Lines Matching +full:dma +full:- +full:requests

2  * Arm PrimeCell PL080/PL081 DMA controller
15 #include "hw/dma/pl080.h"
18 #include "hw/qdev-properties.h"
83 bool tclevel = (s->tc_int & s->tc_mask); in pl080_update()
84 bool errlevel = (s->err_int & s->err_mask); in pl080_update()
86 qemu_set_irq(s->interr, errlevel); in pl080_update()
87 qemu_set_irq(s->inttc, tclevel); in pl080_update()
88 qemu_set_irq(s->irq, errlevel || tclevel); in pl080_update()
106 s->tc_mask = 0; in pl080_run()
107 for (c = 0; c < s->nchannels; c++) { in pl080_run()
108 if (s->chan[c].conf & PL080_CCONF_ITC) in pl080_run()
109 s->tc_mask |= 1 << c; in pl080_run()
110 if (s->chan[c].conf & PL080_CCONF_IE) in pl080_run()
111 s->err_mask |= 1 << c; in pl080_run()
114 if ((s->conf & PL080_CONF_E) == 0) in pl080_run()
117 /* If we are already in the middle of a DMA operation then indicate that in pl080_run()
118 there may be new DMA requests and return immediately. */ in pl080_run()
119 if (s->running) { in pl080_run()
120 s->running++; in pl080_run()
123 s->running = 1; in pl080_run()
124 while (s->running) { in pl080_run()
125 for (c = 0; c < s->nchannels; c++) { in pl080_run()
126 ch = &s->chan[c]; in pl080_run()
128 /* Test if thiws channel has any pending DMA requests. */ in pl080_run()
129 if ((ch->conf & (PL080_CCONF_H | PL080_CCONF_E)) in pl080_run()
132 flow = (ch->conf >> 11) & 7; in pl080_run()
137 src_id = (ch->conf >> 1) & 0x1f; in pl080_run()
138 dest_id = (ch->conf >> 6) & 0x1f; in pl080_run()
139 size = ch->ctrl & 0xfff; in pl080_run()
140 req = s->req_single | s->req_burst; in pl080_run()
165 swidth = 1 << ((ch->ctrl >> 18) & 7); in pl080_run()
166 dwidth = 1 << ((ch->ctrl >> 21) & 7); in pl080_run()
168 address_space_read(&s->downstream_as, ch->src, in pl080_run()
170 if (ch->ctrl & PL080_CCTRL_SI) in pl080_run()
171 ch->src += swidth; in pl080_run()
176 address_space_write(&s->downstream_as, ch->dest + n, in pl080_run()
178 if (ch->ctrl & PL080_CCTRL_DI) in pl080_run()
179 ch->dest += swidth; in pl080_run()
182 size--; in pl080_run()
183 ch->ctrl = (ch->ctrl & 0xfffff000) | size; in pl080_run()
186 if (ch->lli) { in pl080_run()
187 ch->src = address_space_ldl_le(&s->downstream_as, in pl080_run()
188 ch->lli, in pl080_run()
191 ch->dest = address_space_ldl_le(&s->downstream_as, in pl080_run()
192 ch->lli + 4, in pl080_run()
195 ch->ctrl = address_space_ldl_le(&s->downstream_as, in pl080_run()
196 ch->lli + 12, in pl080_run()
199 ch->lli = address_space_ldl_le(&s->downstream_as, in pl080_run()
200 ch->lli + 8, in pl080_run()
204 ch->conf &= ~PL080_CCONF_E; in pl080_run()
206 if (ch->ctrl & PL080_CCTRL_I) { in pl080_run()
207 s->tc_int |= 1 << c; in pl080_run()
212 if (--s->running) in pl080_run()
213 s->running = 1; in pl080_run()
225 if (s->nchannels == 8) { in pl080_read()
226 return pl080_id[(offset - 0xfe0) >> 2]; in pl080_read()
228 return pl081_id[(offset - 0xfe0) >> 2]; in pl080_read()
233 if (i >= s->nchannels) in pl080_read()
237 return s->chan[i].src; in pl080_read()
239 return s->chan[i].dest; in pl080_read()
241 return s->chan[i].lli; in pl080_read()
243 return s->chan[i].ctrl; in pl080_read()
245 return s->chan[i].conf; in pl080_read()
252 return (s->tc_int & s->tc_mask) | (s->err_int & s->err_mask); in pl080_read()
254 return (s->tc_int & s->tc_mask); in pl080_read()
256 return (s->err_int & s->err_mask); in pl080_read()
258 return s->tc_int; in pl080_read()
260 return s->err_int; in pl080_read()
263 for (i = 0; i < s->nchannels; i++) { in pl080_read()
264 if (s->chan[i].conf & PL080_CCONF_E) in pl080_read()
275 return s->conf; in pl080_read()
277 return s->sync; in pl080_read()
294 if (i >= s->nchannels) in pl080_write()
298 s->chan[i].src = value; in pl080_write()
301 s->chan[i].dest = value; in pl080_write()
304 s->chan[i].lli = value; in pl080_write()
307 s->chan[i].ctrl = value; in pl080_write()
310 s->chan[i].conf = value; in pl080_write()
318 s->tc_int &= ~value; in pl080_write()
321 s->err_int &= ~value; in pl080_write()
328 qemu_log_mask(LOG_UNIMP, "pl080_write: Soft DMA not implemented\n"); in pl080_write()
331 s->conf = value; in pl080_write()
332 if (s->conf & (PL080_CONF_M1 | PL080_CONF_M2)) { in pl080_write()
334 "pl080_write: Big-endian DMA not implemented\n"); in pl080_write()
339 s->sync = value; in pl080_write()
360 s->tc_int = 0; in pl080_reset()
361 s->tc_mask = 0; in pl080_reset()
362 s->err_int = 0; in pl080_reset()
363 s->err_mask = 0; in pl080_reset()
364 s->conf = 0; in pl080_reset()
365 s->sync = 0; in pl080_reset()
366 s->req_single = 0; in pl080_reset()
367 s->req_burst = 0; in pl080_reset()
368 s->running = 0; in pl080_reset()
370 for (i = 0; i < s->nchannels; i++) { in pl080_reset()
371 s->chan[i].src = 0; in pl080_reset()
372 s->chan[i].dest = 0; in pl080_reset()
373 s->chan[i].lli = 0; in pl080_reset()
374 s->chan[i].ctrl = 0; in pl080_reset()
375 s->chan[i].conf = 0; in pl080_reset()
384 memory_region_init_io(&s->iomem, OBJECT(s), &pl080_ops, s, "pl080", 0x1000); in pl080_init()
385 sysbus_init_mmio(sbd, &s->iomem); in pl080_init()
386 sysbus_init_irq(sbd, &s->irq); in pl080_init()
387 sysbus_init_irq(sbd, &s->interr); in pl080_init()
388 sysbus_init_irq(sbd, &s->inttc); in pl080_init()
389 s->nchannels = 8; in pl080_init()
396 if (!s->downstream) { in pl080_realize()
401 address_space_init(&s->downstream_as, s->downstream, "pl080-downstream"); in pl080_realize()
408 s->nchannels = 2; in pl081_init()
420 dc->vmsd = &vmstate_pl080; in pl080_class_init()
421 dc->realize = pl080_realize; in pl080_class_init()