Commit 66cbdd2fe1390f311068687c1f9224d1fa478ff6
1 parent
f938f6b6
at91: add initial support for nand IP block
Showing
5 changed files
with
112 additions
and
12 deletions
Makefile.target
| @@ -411,7 +411,7 @@ obj-sparc-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o | @@ -411,7 +411,7 @@ obj-sparc-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o | ||
| 411 | endif | 411 | endif |
| 412 | 412 | ||
| 413 | obj-arm-y = integratorcp.o versatilepb.o smc91c111.o arm_pic.o arm_timer.o | 413 | obj-arm-y = integratorcp.o versatilepb.o smc91c111.o arm_pic.o arm_timer.o |
| 414 | -obj-arm-y += pflash_atmel.o at91sam9.o spi_flash.o at91_lcdc.o | 414 | +obj-arm-y += pflash_atmel.o at91sam9.o spi_flash.o at91_lcdc.o at91_nand.o |
| 415 | obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o | 415 | obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o |
| 416 | obj-arm-y += versatile_pci.o | 416 | obj-arm-y += versatile_pci.o |
| 417 | obj-arm-y += realview_gic.o realview.o arm_sysctl.o mpcore.o | 417 | obj-arm-y += realview_gic.o realview.o arm_sysctl.o mpcore.o |
hw/at91.h
| @@ -56,4 +56,6 @@ extern void at91_pdc_reset(PDCState *s); | @@ -56,4 +56,6 @@ extern void at91_pdc_reset(PDCState *s); | ||
| 56 | extern void at91_pdc_write(void *opaque, target_phys_addr_t offset, uint32_t val); | 56 | extern void at91_pdc_write(void *opaque, target_phys_addr_t offset, uint32_t val); |
| 57 | extern uint32_t at91_pdc_read(void *opaque, target_phys_addr_t offset); | 57 | extern uint32_t at91_pdc_read(void *opaque, target_phys_addr_t offset); |
| 58 | 58 | ||
| 59 | +extern void at91_nand_register(void); | ||
| 60 | + | ||
| 59 | #endif /* !AT91_H */ | 61 | #endif /* !AT91_H */ |
hw/at91_lcdc.c
| @@ -138,6 +138,18 @@ union pixel8u { | @@ -138,6 +138,18 @@ union pixel8u { | ||
| 138 | uint8_t val; | 138 | uint8_t val; |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | +struct pixel16 { | ||
| 142 | + unsigned b : 5; | ||
| 143 | + unsigned g : 5; | ||
| 144 | + unsigned r : 5; | ||
| 145 | +}; | ||
| 146 | + | ||
| 147 | +union pixel16u { | ||
| 148 | + struct pixel16 p; | ||
| 149 | + uint8_t val[0]; | ||
| 150 | +}; | ||
| 151 | + | ||
| 152 | + | ||
| 141 | static void at91_lcdc_update_display(void *opaque) | 153 | static void at91_lcdc_update_display(void *opaque) |
| 142 | { | 154 | { |
| 143 | LCDCState *s = opaque; | 155 | LCDCState *s = opaque; |
| @@ -149,7 +161,9 @@ static void at91_lcdc_update_display(void *opaque) | @@ -149,7 +161,9 @@ static void at91_lcdc_update_display(void *opaque) | ||
| 149 | int q_bpp = (ds_get_bits_per_pixel(s->ds) + 7) >> 3; | 161 | int q_bpp = (ds_get_bits_per_pixel(s->ds) + 7) >> 3; |
| 150 | int bpp; | 162 | int bpp; |
| 151 | int bpp_idx = (s->lcdcon2 >> 5) & 7; | 163 | int bpp_idx = (s->lcdcon2 >> 5) & 7; |
| 152 | - union pixel8u tmp; | 164 | + union pixel8u tmp8; |
| 165 | + union pixel16u tmp16; | ||
| 166 | + unsigned int r, g, b; | ||
| 153 | 167 | ||
| 154 | DPRINTF("update begin\n"); | 168 | DPRINTF("update begin\n"); |
| 155 | if (!(s->dmacon & DMACON_DMAEN)) | 169 | if (!(s->dmacon & DMACON_DMAEN)) |
| @@ -167,33 +181,49 @@ static void at91_lcdc_update_display(void *opaque) | @@ -167,33 +181,49 @@ static void at91_lcdc_update_display(void *opaque) | ||
| 167 | return;//reserved value, unknown pixel size | 181 | return;//reserved value, unknown pixel size |
| 168 | } | 182 | } |
| 169 | /*TODO: fix this restriction*/ | 183 | /*TODO: fix this restriction*/ |
| 170 | - if (bpp != 8) { | ||
| 171 | - fprintf(stderr, "Unsupported pixel size\n"); | 184 | + if (bpp != 8 && bpp != 16) { |
| 185 | + fprintf(stderr, "Unsupported pixel size: %d\n", bpp); | ||
| 172 | return; | 186 | return; |
| 173 | } | 187 | } |
| 174 | - int once = 0; | 188 | + //int once = 0; |
| 175 | for (y = 0; y < height; ++y) { | 189 | for (y = 0; y < height; ++y) { |
| 176 | for (x = 0; x < width; ++x) { | 190 | for (x = 0; x < width; ++x) { |
| 177 | - cpu_physical_memory_read(s->dmabaddr1 + width * y + x, &tmp.val, 1); | 191 | + if (bpp == 8) { |
| 192 | + cpu_physical_memory_read(s->dmabaddr1 + width * y + x, &tmp8.val, 1); | ||
| 193 | + r = tmp8.p.r; | ||
| 194 | + g = tmp8.p.g; | ||
| 195 | + b = tmp8.p.b; | ||
| 196 | + } else { | ||
| 197 | + cpu_physical_memory_read(s->dmabaddr1 + width * y + x, &tmp16.val[0], 2); | ||
| 198 | + r = tmp16.p.r; | ||
| 199 | + g = tmp16.p.g; | ||
| 200 | + b = tmp16.p.b; | ||
| 201 | + } | ||
| 202 | +#if 0 | ||
| 178 | if (tmp.val != 0 && once == 0) { | 203 | if (tmp.val != 0 && once == 0) { |
| 179 | once = 1; | 204 | once = 1; |
| 180 | - DPRINTF("not null %X, %X, %X, bpp %d\n", (unsigned)tmp.p.r << 5, (unsigned)tmp.p.g << 5, (unsigned)tmp.p.b << 6, ds_get_bits_per_pixel(s->ds)); | 205 | + DPRINTF("not null %X, %X, %X, bpp %d\n", (unsigned)r << 5, (unsigned)g << 5, (unsigned)b << 6, |
| 206 | + ds_get_bits_per_pixel(s->ds)); | ||
| 181 | } | 207 | } |
| 208 | +#endif | ||
| 182 | switch (ds_get_bits_per_pixel(s->ds)) { | 209 | switch (ds_get_bits_per_pixel(s->ds)) { |
| 183 | case 8: | 210 | case 8: |
| 184 | - color = rgb_to_pixel8(tmp.p.r, tmp.p.g, tmp.p.b); | 211 | + color = rgb_to_pixel8(r, g, b); |
| 185 | break; | 212 | break; |
| 186 | case 15: | 213 | case 15: |
| 187 | - color = rgb_to_pixel15(tmp.p.r, tmp.p.g, tmp.p.b); | 214 | + color = rgb_to_pixel15(r, g, b); |
| 188 | break; | 215 | break; |
| 189 | case 16: | 216 | case 16: |
| 190 | - color = rgb_to_pixel16(tmp.p.r, tmp.p.g, tmp.p.b); | 217 | + color = rgb_to_pixel16(r, g, b); |
| 191 | break; | 218 | break; |
| 192 | case 24: | 219 | case 24: |
| 193 | - color = rgb_to_pixel24(tmp.p.r, tmp.p.g, tmp.p.b); | 220 | + color = rgb_to_pixel24(r, g, b); |
| 194 | break; | 221 | break; |
| 195 | case 32: | 222 | case 32: |
| 196 | - color = rgb_to_pixel32((unsigned)tmp.p.r << 5, (unsigned)tmp.p.g << 5, (unsigned)tmp.p.b << 6); | 223 | + if (bpp == 8) |
| 224 | + color = rgb_to_pixel32((unsigned)r << 5, (unsigned)g << 5, (unsigned)b << 6); | ||
| 225 | + else | ||
| 226 | + color = rgb_to_pixel32((unsigned)r << 3, (unsigned)g << 3, (unsigned)b << 3); | ||
| 197 | break; | 227 | break; |
| 198 | default: | 228 | default: |
| 199 | return; | 229 | return; |
hw/at91_nand.c
0 → 100644
| 1 | +#include <stdio.h> | ||
| 2 | + | ||
| 3 | +#include "hw.h" | ||
| 4 | +#include "at91.h" | ||
| 5 | + | ||
| 6 | +typedef struct NandState { | ||
| 7 | + unsigned int cmd; | ||
| 8 | +} NandState; | ||
| 9 | + | ||
| 10 | +#define AT91_NAND_DEBUG | ||
| 11 | +#ifdef AT91_NAND_DEBUG | ||
| 12 | +#define DPRINTF(fmt, ...) \ | ||
| 13 | + do { \ | ||
| 14 | + printf("AT91NAND: " fmt , ## __VA_ARGS__); \ | ||
| 15 | + } while (0) | ||
| 16 | +#else | ||
| 17 | +#define DPRINTF(fmt, ...) do { } while (0) | ||
| 18 | +#endif | ||
| 19 | + | ||
| 20 | +extern CPUState *g_env; | ||
| 21 | + | ||
| 22 | +static uint32_t at91_nand_mem_read(void *opaque, target_phys_addr_t offset) | ||
| 23 | +{ | ||
| 24 | + NandState *s = opaque; | ||
| 25 | + | ||
| 26 | + DPRINTF("(IP %X) read from %X\n", g_env->regs[15], offset); | ||
| 27 | + switch (s->cmd) { | ||
| 28 | + case 0x70: | ||
| 29 | + s->cmd = 0; | ||
| 30 | + return 0x40; | ||
| 31 | + default: | ||
| 32 | + return 0x0; | ||
| 33 | + } | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +static void at91_nand_mem_write(void *opaque, target_phys_addr_t offset, | ||
| 37 | + uint32_t value) | ||
| 38 | +{ | ||
| 39 | + NandState *s = opaque; | ||
| 40 | + | ||
| 41 | + DPRINTF("(IP %X) write to %X %X\n", g_env->regs[15], offset, value); | ||
| 42 | + s->cmd = value; | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +static CPUReadMemoryFunc *at91_nand_readfn[] = { | ||
| 46 | + at91_nand_mem_read, | ||
| 47 | + at91_nand_mem_read, | ||
| 48 | + at91_nand_mem_read, | ||
| 49 | +}; | ||
| 50 | + | ||
| 51 | +static CPUWriteMemoryFunc *at91_nand_writefn[] = { | ||
| 52 | + at91_nand_mem_write, | ||
| 53 | + at91_nand_mem_write, | ||
| 54 | + at91_nand_mem_write, | ||
| 55 | +}; | ||
| 56 | + | ||
| 57 | +void at91_nand_register(void) | ||
| 58 | +{ | ||
| 59 | + NandState *s; | ||
| 60 | + int iomemtype; | ||
| 61 | + | ||
| 62 | + s = qemu_mallocz(sizeof(*s)); | ||
| 63 | + iomemtype = cpu_register_io_memory(at91_nand_readfn, at91_nand_writefn, s); | ||
| 64 | + cpu_register_physical_memory(0x40000000, 0x10000000, iomemtype); | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | + |
hw/at91sam9.c
| @@ -352,6 +352,7 @@ static void at91sam9_init(ram_addr_t ram_size, | @@ -352,6 +352,7 @@ static void at91sam9_init(ram_addr_t ram_size, | ||
| 352 | //rom | 352 | //rom |
| 353 | cpu_register_physical_memory(0x0, 100 * 1024, | 353 | cpu_register_physical_memory(0x0, 100 * 1024, |
| 354 | sam9->bootrom | IO_MEM_ROMD); | 354 | sam9->bootrom | IO_MEM_ROMD); |
| 355 | + at91_nand_register(); | ||
| 355 | } else { | 356 | } else { |
| 356 | //nor flash | 357 | //nor flash |
| 357 | ram_addr_t nor_flash_mem = qemu_ram_alloc(NOR_FLASH_SIZE); | 358 | ram_addr_t nor_flash_mem = qemu_ram_alloc(NOR_FLASH_SIZE); |