Commit 66cbdd2fe1390f311068687c1f9224d1fa478ff6

Authored by Evgeniy Dushistov
1 parent f938f6b6

at91: add initial support for nand IP block

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