Revision 3387bf55
b/hw/omap_gpmc.c | ||
---|---|---|
54 | 54 |
qemu_set_irq(s->irq, s->irqen & s->irqst); |
55 | 55 |
} |
56 | 56 |
|
57 |
static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
|
|
57 |
static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
|
|
58 | 58 |
{ |
59 |
struct omap_gpmc_cs_file_s *f = &s->cs_file[cs]; |
|
60 |
uint32_t mask = (f->config[6] >> 8) & 0xf; |
|
61 |
uint32_t base = f->config[6] & 0x3f; |
|
59 | 62 |
uint32_t size; |
60 | 63 |
|
61 | 64 |
if (!f->iomem) { |
62 | 65 |
return; |
63 | 66 |
} |
64 | 67 |
|
68 |
if (!(f->config[6] & (1 << 6))) { |
|
69 |
/* Do nothing unless CSVALID */ |
|
70 |
return; |
|
71 |
} |
|
72 |
|
|
65 | 73 |
/* TODO: check for overlapping regions and report access errors */ |
66 | 74 |
if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) || |
67 |
(base < 0 || base >= 0x40) || |
|
68 |
(base & 0x0f & ~mask)) { |
|
75 |
(base & 0x0f & ~mask)) { |
|
69 | 76 |
fprintf(stderr, "%s: wrong cs address mapping/decoding!\n", |
70 | 77 |
__FUNCTION__); |
71 | 78 |
return; |
... | ... | |
83 | 90 |
&f->container); |
84 | 91 |
} |
85 | 92 |
|
86 |
static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
|
|
93 |
static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
|
|
87 | 94 |
{ |
95 |
struct omap_gpmc_cs_file_s *f = &s->cs_file[cs]; |
|
96 |
if (!(f->config[6] & (1 << 6))) { |
|
97 |
/* Do nothing unless CSVALID */ |
|
98 |
return; |
|
99 |
} |
|
88 | 100 |
if (!f->iomem) { |
89 | 101 |
return; |
90 | 102 |
} |
... | ... | |
110 | 122 |
s->preffifo = 0; |
111 | 123 |
s->prefcount = 0; |
112 | 124 |
for (i = 0; i < 8; i ++) { |
113 |
if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */ |
|
114 |
omap_gpmc_cs_unmap(s->cs_file + i); |
|
115 |
s->cs_file[i].config[0] = i ? 1 << 12 : 0; |
|
125 |
omap_gpmc_cs_unmap(s, i); |
|
116 | 126 |
s->cs_file[i].config[1] = 0x101001; |
117 | 127 |
s->cs_file[i].config[2] = 0x020201; |
118 | 128 |
s->cs_file[i].config[3] = 0x10031003; |
119 | 129 |
s->cs_file[i].config[4] = 0x10f1111; |
120 | 130 |
s->cs_file[i].config[5] = 0; |
121 | 131 |
s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6); |
122 |
if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */ |
|
123 |
omap_gpmc_cs_map(&s->cs_file[i], |
|
124 |
s->cs_file[i].config[6] & 0x1f, /* MASKADDR */ |
|
125 |
(s->cs_file[i].config[6] >> 8 & 0xf)); /* BASEADDR */ |
|
132 |
|
|
133 |
s->cs_file[i].config[6] = 0xf00; |
|
134 |
/* In theory we could probe attached devices for some CFG1 |
|
135 |
* bits here, but we just retain them across resets as they |
|
136 |
* were set initially by omap_gpmc_attach(). |
|
137 |
*/ |
|
138 |
if (i == 0) { |
|
139 |
s->cs_file[i].config[0] &= 0x00433e00; |
|
140 |
s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */ |
|
141 |
omap_gpmc_cs_map(s, i); |
|
142 |
} else { |
|
143 |
s->cs_file[i].config[0] &= 0x00403c00; |
|
144 |
} |
|
126 | 145 |
} |
127 | 146 |
s->ecc_cs = 0; |
128 | 147 |
s->ecc_ptr = 0; |
... | ... | |
311 | 330 |
break; |
312 | 331 |
case 0x78: /* GPMC_CONFIG7 */ |
313 | 332 |
if ((f->config[6] ^ value) & 0xf7f) { |
314 |
if (f->config[6] & (1 << 6)) /* CSVALID */ |
|
315 |
omap_gpmc_cs_unmap(f); |
|
316 |
if (value & (1 << 6)) /* CSVALID */ |
|
317 |
omap_gpmc_cs_map(f, value & 0x1f, /* MASKADDR */ |
|
318 |
(value >> 8 & 0xf)); /* BASEADDR */ |
|
333 |
omap_gpmc_cs_unmap(s, cs); |
|
334 |
f->config[6] = value & 0x00000f7f; |
|
335 |
omap_gpmc_cs_map(s, cs); |
|
319 | 336 |
} |
320 |
f->config[6] = value & 0x00000f7f; |
|
321 | 337 |
break; |
322 | 338 |
case 0x7c: /* GPMC_NAND_COMMAND */ |
323 | 339 |
case 0x80: /* GPMC_NAND_ADDRESS */ |
... | ... | |
407 | 423 |
} |
408 | 424 |
f = &s->cs_file[cs]; |
409 | 425 |
|
426 |
omap_gpmc_cs_unmap(s, cs); |
|
410 | 427 |
f->iomem = iomem; |
411 |
|
|
412 |
if (f->config[6] & (1 << 6)) /* CSVALID */ |
|
413 |
omap_gpmc_cs_map(f, f->config[6] & 0x1f, /* MASKADDR */ |
|
414 |
(f->config[6] >> 8 & 0xf)); /* BASEADDR */ |
|
428 |
omap_gpmc_cs_map(s, cs); |
|
415 | 429 |
} |
Also available in: Unified diff