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 | 411 | endif |
412 | 412 | |
413 | 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 | 415 | obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o |
416 | 416 | obj-arm-y += versatile_pci.o |
417 | 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 | 56 | extern void at91_pdc_write(void *opaque, target_phys_addr_t offset, uint32_t val); |
57 | 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 | 61 | #endif /* !AT91_H */ | ... | ... |
hw/at91_lcdc.c
... | ... | @@ -138,6 +138,18 @@ union pixel8u { |
138 | 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 | 153 | static void at91_lcdc_update_display(void *opaque) |
142 | 154 | { |
143 | 155 | LCDCState *s = opaque; |
... | ... | @@ -149,7 +161,9 @@ static void at91_lcdc_update_display(void *opaque) |
149 | 161 | int q_bpp = (ds_get_bits_per_pixel(s->ds) + 7) >> 3; |
150 | 162 | int bpp; |
151 | 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 | 168 | DPRINTF("update begin\n"); |
155 | 169 | if (!(s->dmacon & DMACON_DMAEN)) |
... | ... | @@ -167,33 +181,49 @@ static void at91_lcdc_update_display(void *opaque) |
167 | 181 | return;//reserved value, unknown pixel size |
168 | 182 | } |
169 | 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 | 186 | return; |
173 | 187 | } |
174 | - int once = 0; | |
188 | + //int once = 0; | |
175 | 189 | for (y = 0; y < height; ++y) { |
176 | 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 | 203 | if (tmp.val != 0 && once == 0) { |
179 | 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 | 209 | switch (ds_get_bits_per_pixel(s->ds)) { |
183 | 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 | 212 | break; |
186 | 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 | 215 | break; |
189 | 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 | 218 | break; |
192 | 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 | 221 | break; |
195 | 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 | 227 | break; |
198 | 228 | default: |
199 | 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 | 352 | //rom |
353 | 353 | cpu_register_physical_memory(0x0, 100 * 1024, |
354 | 354 | sam9->bootrom | IO_MEM_ROMD); |
355 | + at91_nand_register(); | |
355 | 356 | } else { |
356 | 357 | //nor flash |
357 | 358 | ram_addr_t nor_flash_mem = qemu_ram_alloc(NOR_FLASH_SIZE); | ... | ... |