1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: #include "hw.h"
22: #include "arm-misc.h"
23: #include "omap.h"
24: #include "sysemu.h"
25: #include "qemu-timer.h"
26:
27: #include "pc.h"
28:
29:
30: uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
31: {
32: uint8_t ret;
33:
34: OMAP_8B_REG(addr);
35: cpu_physical_memory_read(addr, (void *) &ret, 1);
36: return ret;
37: }
38:
39: void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
40: uint32_t value)
41: {
42: uint8_t val8 = value;
43:
44: OMAP_8B_REG(addr);
45: cpu_physical_memory_write(addr, (void *) &val8, 1);
46: }
47:
48: uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
49: {
50: uint16_t ret;
51:
52: OMAP_16B_REG(addr);
53: cpu_physical_memory_read(addr, (void *) &ret, 2);
54: return ret;
55: }
56:
57: void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
58: uint32_t value)
59: {
60: uint16_t val16 = value;
61:
62: OMAP_16B_REG(addr);
63: cpu_physical_memory_write(addr, (void *) &val16, 2);
64: }
65:
66: uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
67: {
68: uint32_t ret;
69:
70: OMAP_32B_REG(addr);
71: cpu_physical_memory_read(addr, (void *) &ret, 4);
72: return ret;
73: }
74:
75: void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
76: uint32_t value)
77: {
78: OMAP_32B_REG(addr);
79: cpu_physical_memory_write(addr, (void *) &value, 4);
80: }
81:
82:
83: struct omap_intr_handler_bank_s {
84: uint32_t irqs;
85: uint32_t inputs;
86: uint32_t mask;
87: uint32_t fiq;
88: uint32_t sens_edge;
89: unsigned char priority[32];
90: };
91:
92: struct omap_intr_handler_s {
93: qemu_irq *pins;
94: qemu_irq parent_intr[2];
95: target_phys_addr_t base;
96: unsigned char nbanks;
97:
98:
99: uint32_t new_agr[2];
100: int sir_intr[2];
101: struct omap_intr_handler_bank_s banks[];
102: };
103:
104: static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
105: {
106: int i, j, sir_intr, p_intr, p, f;
107: uint32_t level;
108: sir_intr = 0;
109: p_intr = 255;
110:
111:
112:
113:
114:
115: for (j = 0; j < s->nbanks; ++j) {
116: level = s->banks[j].irqs & ~s->banks[j].mask &
117: (is_fiq ? s->banks[j].fiq : ~s->banks[j].fiq);
118: for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,
119: level >>= f) {
120: p = s->banks[j].priority[i];
121: if (p <= p_intr) {
122: p_intr = p;
123: sir_intr = 32 * j + i;
124: }
125: f = ffs(level >> 1);
126: }
127: }
128: s->sir_intr[is_fiq] = sir_intr;
129: }
130:
131: static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
132: {
133: int i;
134: uint32_t has_intr = 0;
135:
136: for (i = 0; i < s->nbanks; ++i)
137: has_intr |= s->banks[i].irqs & ~s->banks[i].mask &
138: (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq);
139:
140: if (s->new_agr[is_fiq] && has_intr) {
141: s->new_agr[is_fiq] = 0;
142: omap_inth_sir_update(s, is_fiq);
143: qemu_set_irq(s->parent_intr[is_fiq], 1);
144: }
145: }
146:
147: #define INT_FALLING_EDGE 0
148: #define INT_LOW_LEVEL 1
149:
150: static void omap_set_intr(void *opaque, int irq, int req)
151: {
152: struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
153: uint32_t rise;
154:
155: struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5];
156: int n = irq & 31;
157:
158: if (req) {
159: rise = ~bank->irqs & (1 << n);
160: if (~bank->sens_edge & (1 << n))
161: rise &= ~bank->inputs & (1 << n);
162:
163: bank->inputs |= (1 << n);
164: if (rise) {
165: bank->irqs |= rise;
166: omap_inth_update(ih, 0);
167: omap_inth_update(ih, 1);
168: }
169: } else {
170: rise = bank->sens_edge & bank->irqs & (1 << n);
171: bank->irqs &= ~rise;
172: bank->inputs &= ~(1 << n);
173: }
174: }
175:
176: static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
177: {
178: struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
179: int i, offset = addr - s->base;
180: int bank_no = offset >> 8;
181: int line_no;
182: struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
183: offset &= 0xff;
184:
185: switch (offset) {
186: case 0x00:
187: return bank->irqs;
188:
189: case 0x04:
190: return bank->mask;
191:
192: case 0x10:
193: case 0x14:
194: if (bank_no != 0)
195: break;
196: line_no = s->sir_intr[(offset - 0x10) >> 2];
197: bank = &s->banks[line_no >> 5];
198: i = line_no & 31;
199: if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
200: bank->irqs &= ~(1 << i);
201: return line_no;
202:
203: case 0x18:
204: if (bank_no != 0)
205: break;
206: return 0;
207:
208: case 0x1c:
209: case 0x20:
210: case 0x24:
211: case 0x28:
212: case 0x2c:
213: case 0x30:
214: case 0x34:
215: case 0x38:
216: case 0x3c:
217: case 0x40:
218: case 0x44:
219: case 0x48:
220: case 0x4c:
221: case 0x50:
222: case 0x54:
223: case 0x58:
224: case 0x5c:
225: case 0x60:
226: case 0x64:
227: case 0x68:
228: case 0x6c:
229: case 0x70:
230: case 0x74:
231: case 0x78:
232: case 0x7c:
233: case 0x80:
234: case 0x84:
235: case 0x88:
236: case 0x8c:
237: case 0x90:
238: case 0x94:
239: case 0x98:
240: i = (offset - 0x1c) >> 2;
241: return (bank->priority[i] << 2) |
242: (((bank->sens_edge >> i) & 1) << 1) |
243: ((bank->fiq >> i) & 1);
244:
245: case 0x9c:
246: return 0x00000000;
247:
248: }
249: OMAP_BAD_REG(addr);
250: return 0;
251: }
252:
253: static void omap_inth_write(void *opaque, target_phys_addr_t addr,
254: uint32_t value)
255: {
256: struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
257: int i, offset = addr - s->base;
258: int bank_no = offset >> 8;
259: struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
260: offset &= 0xff;
261:
262: switch (offset) {
263: case 0x00:
264:
265:
266: bank->irqs &= value | (bank->inputs & bank->sens_edge);
267: return;
268:
269: case 0x04:
270: bank->mask = value;
271: omap_inth_update(s, 0);
272: omap_inth_update(s, 1);
273: return;
274:
275: case 0x10:
276: case 0x14:
277: OMAP_RO_REG(addr);
278: break;
279:
280: case 0x18:
281: if (bank_no != 0)
282: break;
283: if (value & 2) {
284: qemu_set_irq(s->parent_intr[1], 0);
285: s->new_agr[1] = ~0;
286: omap_inth_update(s, 1);
287: }
288: if (value & 1) {
289: qemu_set_irq(s->parent_intr[0], 0);
290: s->new_agr[0] = ~0;
291: omap_inth_update(s, 0);
292: }
293: return;
294:
295: case 0x1c:
296: case 0x20:
297: case 0x24:
298: case 0x28:
299: case 0x2c:
300: case 0x30:
301: case 0x34:
302: case 0x38:
303: case 0x3c:
304: case 0x40:
305: case 0x44:
306: case 0x48:
307: case 0x4c:
308: case 0x50:
309: case 0x54:
310: case 0x58:
311: case 0x5c:
312: case 0x60:
313: case 0x64:
314: case 0x68:
315: case 0x6c:
316: case 0x70:
317: case 0x74:
318: case 0x78:
319: case 0x7c:
320: case 0x80:
321: case 0x84:
322: case 0x88:
323: case 0x8c:
324: case 0x90:
325: case 0x94:
326: case 0x98:
327: i = (offset - 0x1c) >> 2;
328: bank->priority[i] = (value >> 2) & 0x1f;
329: bank->sens_edge &= ~(1 << i);
330: bank->sens_edge |= ((value >> 1) & 1) << i;
331: bank->fiq &= ~(1 << i);
332: bank->fiq |= (value & 1) << i;
333: return;
334:
335: case 0x9c:
336: for (i = 0; i < 32; i ++)
337: if (value & (1 << i)) {
338: omap_set_intr(s, 32 * bank_no + i, 1);
339: return;
340: }
341: return;
342: }
343: OMAP_BAD_REG(addr);
344: }
345:
346: static CPUReadMemoryFunc *omap_inth_readfn[] = {
347: omap_badwidth_read32,
348: omap_badwidth_read32,
349: omap_inth_read,
350: };
351:
352: static CPUWriteMemoryFunc *omap_inth_writefn[] = {
353: omap_inth_write,
354: omap_inth_write,
355: omap_inth_write,
356: };
357:
358: void omap_inth_reset(struct omap_intr_handler_s *s)
359: {
360: int i;
361:
362: for (i = 0; i < s->nbanks; ++i){
363: s->banks[i].irqs = 0x00000000;
364: s->banks[i].mask = 0xffffffff;
365: s->banks[i].sens_edge = 0x00000000;
366: s->banks[i].fiq = 0x00000000;
367: s->banks[i].inputs = 0x00000000;
368: memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority));
369: }
370:
371: s->new_agr[0] = ~0;
372: s->new_agr[1] = ~0;
373: s->sir_intr[0] = 0;
374: s->sir_intr[1] = 0;
375:
376: qemu_set_irq(s->parent_intr[0], 0);
377: qemu_set_irq(s->parent_intr[1], 0);
378: }
379:
380: struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
381: unsigned long size, unsigned char nbanks,
382: qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk)
383: {
384: int iomemtype;
385: struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
386: qemu_mallocz(sizeof(struct omap_intr_handler_s) +
387: sizeof(struct omap_intr_handler_bank_s) * nbanks);
388:
389: s->parent_intr[0] = parent_irq;
390: s->parent_intr[1] = parent_fiq;
391: s->base = base;
392: s->nbanks = nbanks;
393: s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
394:
395: omap_inth_reset(s);
396:
397: iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
398: omap_inth_writefn, s);
399: cpu_register_physical_memory(s->base, size, iomemtype);
400:
401: return s;
402: }
403:
404:
405: struct omap_dma_channel_s {
406:
407: int burst[2];
408: int pack[2];
409: enum omap_dma_port port[2];
410: target_phys_addr_t addr[2];
411: omap_dma_addressing_t mode[2];
412: uint16_t elements;
413: uint16_t frames;
414: int16_t frame_index[2];
415: int16_t element_index[2];
416: int data_type;
417:
418:
419: int transparent_copy;
420: int constant_fill;
421: uint32_t color;
422:
423:
424: int end_prog;
425: int repeat;
426: int auto_init;
427: int link_enabled;
428: int link_next_ch;
429:
430:
431: int interrupts;
432: int status;
433:
434:
435: int active;
436: int enable;
437: int sync;
438: int pending_request;
439: int waiting_end_prog;
440: uint16_t cpc;
441:
442:
443: int fs;
444: int bs;
445:
446:
447: int omap_3_1_compatible_disable;
448:
449: qemu_irq irq;
450: struct omap_dma_channel_s *sibling;
451:
452: struct omap_dma_reg_set_s {
453: target_phys_addr_t src, dest;
454: int frame;
455: int element;
456: int frame_delta[2];
457: int elem_delta[2];
458: int frames;
459: int elements;
460: } active_set;
461:
462:
463: int priority;
464: int interleave_disabled;
465: int type;
466: };
467:
468: struct omap_dma_s {
469: QEMUTimer *tm;
470: struct omap_mpu_state_s *mpu;
471: target_phys_addr_t base;
472: omap_clk clk;
473: int64_t delay;
474: uint32_t drq;
475: enum omap_dma_model model;
476: int omap_3_1_mapping_disabled;
477:
478: uint16_t gcr;
479: int run_count;
480:
481: int chans;
482: struct omap_dma_channel_s ch[16];
483: struct omap_dma_lcd_channel_s lcd_ch;
484: };
485:
486:
487: #define TIMEOUT_INTR (1 << 0)
488: #define EVENT_DROP_INTR (1 << 1)
489: #define HALF_FRAME_INTR (1 << 2)
490: #define END_FRAME_INTR (1 << 3)
491: #define LAST_FRAME_INTR (1 << 4)
492: #define END_BLOCK_INTR (1 << 5)
493: #define SYNC (1 << 6)
494:
495: static void omap_dma_interrupts_update(struct omap_dma_s *s)
496: {
497: struct omap_dma_channel_s *ch = s->ch;
498: int i;
499:
500: if (s->omap_3_1_mapping_disabled) {
501: for (i = 0; i < s->chans; i ++, ch ++)
502: if (ch->status)
503: qemu_irq_raise(ch->irq);
504: } else {
505:
506: for (i = 0; i < 6; i ++, ch ++) {
507: if (ch->status || (ch->sibling && ch->sibling->status))
508: qemu_irq_raise(ch->irq);
509: }
510: }
511: }
512:
513: static void omap_dma_channel_load(struct omap_dma_s *s,
514: struct omap_dma_channel_s *ch)
515: {
516: struct omap_dma_reg_set_s *a = &ch->active_set;
517: int i;
518: int omap_3_1 = !ch->omap_3_1_compatible_disable;
519:
520:
521:
522:
523:
524:
525: a->src = ch->addr[0];
526: a->dest = ch->addr[1];
527: a->frames = ch->frames;
528: a->elements = ch->elements;
529: a->frame = 0;
530: a->element = 0;
531:
532: if (unlikely(!ch->elements || !ch->frames)) {
533: printf("%s: bad DMA request\n", __FUNCTION__);
534: return;
535: }
536:
537: for (i = 0; i < 2; i ++)
538: switch (ch->mode[i]) {
539: case constant:
540: a->elem_delta[i] = 0;
541: a->frame_delta[i] = 0;
542: break;
543: case post_incremented:
544: a->elem_delta[i] = ch->data_type;
545: a->frame_delta[i] = 0;
546: break;
547: case single_index:
548: a->elem_delta[i] = ch->data_type +
549: ch->element_index[omap_3_1 ? 0 : i] - 1;
550: a->frame_delta[i] = 0;
551: break;
552: case double_index:
553: a->elem_delta[i] = ch->data_type +
554: ch->element_index[omap_3_1 ? 0 : i] - 1;
555: a->frame_delta[i] = ch->frame_index[omap_3_1 ? 0 : i] -
556: ch->element_index[omap_3_1 ? 0 : i];
557: break;
558: default:
559: break;
560: }
561: }
562:
563: static void omap_dma_activate_channel(struct omap_dma_s *s,
564: struct omap_dma_channel_s *ch)
565: {
566: if (!ch->active) {
567: ch->active = 1;
568: if (ch->sync)
569: ch->status |= SYNC;
570: s->run_count ++;
571: }
572:
573: if (s->delay && !qemu_timer_pending(s->tm))
574: qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
575: }
576:
577: static void omap_dma_deactivate_channel(struct omap_dma_s *s,
578: struct omap_dma_channel_s *ch)