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); |