]> git.proxmox.com Git - qemu.git/blobdiff - hw/omap_dma.c
misc: move include files to include/qemu/
[qemu.git] / hw / omap_dma.c
index ba980df5e17d71ecaced7f8bb290495427c97a01..aec58743114278c12109a63c2845430cbda8bac8 100644 (file)
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "qemu-common.h"
-#include "qemu-timer.h"
+#include "qemu/timer.h"
 #include "omap.h"
 #include "irq.h"
 #include "soc_dma.h"
@@ -33,7 +31,7 @@ struct omap_dma_channel_s {
     int endian_lock[2];
     int translate[2];
     enum omap_dma_port port[2];
-    target_phys_addr_t addr[2];
+    hwaddr addr[2];
     omap_dma_addressing_t mode[2];
     uint32_t elements;
     uint16_t frames;
@@ -80,7 +78,7 @@ struct omap_dma_channel_s {
     struct omap_dma_channel_s *sibling;
 
     struct omap_dma_reg_set_s {
-        target_phys_addr_t src, dest;
+        hwaddr src, dest;
         int frame;
         int element;
         int pck_element;
@@ -104,9 +102,9 @@ struct omap_dma_channel_s {
 
 struct omap_dma_s {
     struct soc_dma_s *dma;
+    MemoryRegion iomem;
 
     struct omap_mpu_state_s *mpu;
-    target_phys_addr_t base;
     omap_clk clk;
     qemu_irq irq[4];
     void (*intr_update)(struct omap_dma_s *s);
@@ -594,84 +592,88 @@ static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma)
     if (dma->update) {
 #endif
 
-    /* If the channel is element synchronized, deactivate it */
-    if (min_elems == elements[omap_dma_intr_element_sync])
-        omap_dma_deactivate_channel(s, ch);
+        /* If the channel is element synchronized, deactivate it */
+        if (min_elems == elements[omap_dma_intr_element_sync])
+            omap_dma_deactivate_channel(s, ch);
 
-    /* If it is the last frame, set the LAST_FRAME interrupt */
-    if (min_elems == elements[omap_dma_intr_last_frame])
-        ch->status |= LAST_FRAME_INTR;
+        /* If it is the last frame, set the LAST_FRAME interrupt */
+        if (min_elems == elements[omap_dma_intr_last_frame])
+            ch->status |= LAST_FRAME_INTR;
 
-    /* If exactly half of the frame was reached, set the HALF_FRAME
-       interrupt */
-    if (min_elems == elements[omap_dma_intr_half_frame])
-        ch->status |= HALF_FRAME_INTR;
+        /* If exactly half of the frame was reached, set the HALF_FRAME
+           interrupt */
+        if (min_elems == elements[omap_dma_intr_half_frame])
+            ch->status |= HALF_FRAME_INTR;
 
-    /* If a full packet has been transferred, set the END_PKT interrupt */
-    if (min_elems == elements[omap_dma_intr_packet])
-        ch->status |= END_PKT_INTR;
+        /* If a full packet has been transferred, set the END_PKT interrupt */
+        if (min_elems == elements[omap_dma_intr_packet])
+            ch->status |= END_PKT_INTR;
 
-    /* If the channel is packet-synchronized, deactivate it */
-    if (min_elems == elements[omap_dma_intr_packet_sync])
-        omap_dma_deactivate_channel(s, ch);
+        /* If the channel is packet-synchronized, deactivate it */
+        if (min_elems == elements[omap_dma_intr_packet_sync])
+            omap_dma_deactivate_channel(s, ch);
 
-    /* If the channel is frame synchronized, deactivate it */
-    if (min_elems == elements[omap_dma_intr_frame_sync])
-        omap_dma_deactivate_channel(s, ch);
+        /* If the channel is frame synchronized, deactivate it */
+        if (min_elems == elements[omap_dma_intr_frame_sync])
+            omap_dma_deactivate_channel(s, ch);
 
-    /* Set the END_FRAME interrupt */
-    if (min_elems == elements[omap_dma_intr_frame])
-        ch->status |= END_FRAME_INTR;
+        /* Set the END_FRAME interrupt */
+        if (min_elems == elements[omap_dma_intr_frame])
+            ch->status |= END_FRAME_INTR;
 
-    if (min_elems == elements[omap_dma_intr_block]) {
-        /* End of Block */
-        /* Disable the channel */
+        if (min_elems == elements[omap_dma_intr_block]) {
+            /* End of Block */
+            /* Disable the channel */
 
-        if (ch->omap_3_1_compatible_disable) {
-            omap_dma_disable_channel(s, ch);
-            if (ch->link_enabled)
-                omap_dma_enable_channel(s, &s->ch[ch->link_next_ch]);
-        } else {
-            if (!ch->auto_init)
+            if (ch->omap_3_1_compatible_disable) {
                 omap_dma_disable_channel(s, ch);
-            else if (ch->repeat || ch->end_prog)
-                omap_dma_channel_load(ch);
-            else {
-                ch->waiting_end_prog = 1;
-                omap_dma_deactivate_channel(s, ch);
+                if (ch->link_enabled)
+                    omap_dma_enable_channel(s, &s->ch[ch->link_next_ch]);
+            } else {
+                if (!ch->auto_init)
+                    omap_dma_disable_channel(s, ch);
+                else if (ch->repeat || ch->end_prog)
+                    omap_dma_channel_load(ch);
+                else {
+                    ch->waiting_end_prog = 1;
+                    omap_dma_deactivate_channel(s, ch);
+                }
             }
-        }
 
-        if (ch->interrupts & END_BLOCK_INTR)
-            ch->status |= END_BLOCK_INTR;
-    }
+            if (ch->interrupts & END_BLOCK_INTR)
+                ch->status |= END_BLOCK_INTR;
+        }
 
-    /* Update packet number */
-    if (ch->fs && ch->bs) {
-        a->pck_element += min_elems;
-        a->pck_element %= a->pck_elements;
-    }
+        /* Update packet number */
+        if (ch->fs && ch->bs) {
+            a->pck_element += min_elems;
+            a->pck_element %= a->pck_elements;
+        }
 
-    /* TODO: check if we really need to update anything here or perhaps we
-     * can skip part of this.  */
+        /* TODO: check if we really need to update anything here or perhaps we
+         * can skip part of this.  */
 #ifndef MULTI_REQ
-    if (dma->update) {
+        if (dma->update) {
 #endif
-        a->element += min_elems;
+            a->element += min_elems;
 
-        frames     = a->element / a->elements;
-        a->element = a->element % a->elements;
-        a->frame  += frames;
-        a->src    += min_elems * a->elem_delta[0] + frames * a->frame_delta[0];
-        a->dest   += min_elems * a->elem_delta[1] + frames * a->frame_delta[1];
+            frames = a->element / a->elements;
+            a->element = a->element % a->elements;
+            a->frame += frames;
+            a->src += min_elems * a->elem_delta[0] + frames * a->frame_delta[0];
+            a->dest += min_elems * a->elem_delta[1] + frames * a->frame_delta[1];
 
-        /* If the channel is async, update cpc */
-        if (!ch->sync && frames)
-            ch->cpc = a->dest & 0xffff;
+            /* If the channel is async, update cpc */
+            if (!ch->sync && frames)
+                ch->cpc = a->dest & 0xffff;
 
-        /* TODO: if the destination port is IMIF or EMIFF, set the dirty
-         * bits on it.  */
+            /* TODO: if the destination port is IMIF or EMIFF, set the dirty
+             * bits on it.  */
+#ifndef MULTI_REQ
+        }
+#else
     }
+#endif
 
     omap_dma_interrupts_update(s);
 }
@@ -912,7 +914,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
         break;
 
     case 0x06: /* SYS_DMA_CSR_CH0 */
-        OMAP_RO_REG((target_phys_addr_t) reg);
+        OMAP_RO_REG((hwaddr) reg);
         break;
 
     case 0x08: /* SYS_DMA_CSSA_L_CH0 */
@@ -952,7 +954,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
         break;
 
     case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */
-        OMAP_RO_REG((target_phys_addr_t) reg);
+        OMAP_RO_REG((hwaddr) reg);
         break;
 
     case 0x1c: /* DMA_CDEI */
@@ -1444,23 +1446,28 @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
     return 0;
 }
 
-static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_dma_read(void *opaque, hwaddr addr,
+                              unsigned size)
 {
     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
-    int reg, ch, offset = addr - s->base;
+    int reg, ch;
     uint16_t ret;
 
-    switch (offset) {
+    if (size != 2) {
+        return omap_badwidth_read16(opaque, addr);
+    }
+
+    switch (addr) {
     case 0x300 ... 0x3fe:
         if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
-            if (omap_dma_3_1_lcd_read(&s->lcd_ch, offset, &ret))
+            if (omap_dma_3_1_lcd_read(&s->lcd_ch, addr, &ret))
                 break;
             return ret;
         }
         /* Fall through. */
     case 0x000 ... 0x2fe:
-        reg = offset & 0x3f;
-        ch = (offset >> 6) & 0x0f;
+        reg = addr & 0x3f;
+        ch = (addr >> 6) & 0x0f;
         if (omap_dma_ch_reg_read(s, &s->ch[ch], reg, &ret))
             break;
         return ret;
@@ -1470,13 +1477,13 @@ static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
             break;
         /* Fall through. */
     case 0x400:
-        if (omap_dma_sys_read(s, offset, &ret))
+        if (omap_dma_sys_read(s, addr, &ret))
             break;
         return ret;
 
     case 0xb00 ... 0xbfe:
         if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
-            if (omap_dma_3_2_lcd_read(&s->lcd_ch, offset, &ret))
+            if (omap_dma_3_2_lcd_read(&s->lcd_ch, addr, &ret))
                 break;
             return ret;
         }
@@ -1487,23 +1494,27 @@ static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
     return 0;
 }
 
-static void omap_dma_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+static void omap_dma_write(void *opaque, hwaddr addr,
+                           uint64_t value, unsigned size)
 {
     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
-    int reg, ch, offset = addr - s->base;
+    int reg, ch;
 
-    switch (offset) {
+    if (size != 2) {
+        return omap_badwidth_write16(opaque, addr, value);
+    }
+
+    switch (addr) {
     case 0x300 ... 0x3fe:
         if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
-            if (omap_dma_3_1_lcd_write(&s->lcd_ch, offset, value))
+            if (omap_dma_3_1_lcd_write(&s->lcd_ch, addr, value))
                 break;
             return;
         }
         /* Fall through.  */
     case 0x000 ... 0x2fe:
-        reg = offset & 0x3f;
-        ch = (offset >> 6) & 0x0f;
+        reg = addr & 0x3f;
+        ch = (addr >> 6) & 0x0f;
         if (omap_dma_ch_reg_write(s, &s->ch[ch], reg, value))
             break;
         return;
@@ -1513,13 +1524,13 @@ static void omap_dma_write(void *opaque, target_phys_addr_t addr,
             break;
     case 0x400:
         /* Fall through. */
-        if (omap_dma_sys_write(s, offset, value))
+        if (omap_dma_sys_write(s, addr, value))
             break;
         return;
 
     case 0xb00 ... 0xbfe:
         if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
-            if (omap_dma_3_2_lcd_write(&s->lcd_ch, offset, value))
+            if (omap_dma_3_2_lcd_write(&s->lcd_ch, addr, value))
                 break;
             return;
         }
@@ -1529,16 +1540,10 @@ static void omap_dma_write(void *opaque, target_phys_addr_t addr,
     OMAP_BAD_REG(addr);
 }
 
-static CPUReadMemoryFunc *omap_dma_readfn[] = {
-    omap_badwidth_read16,
-    omap_dma_read,
-    omap_badwidth_read16,
-};
-
-static CPUWriteMemoryFunc *omap_dma_writefn[] = {
-    omap_badwidth_write16,
-    omap_dma_write,
-    omap_badwidth_write16,
+static const MemoryRegionOps omap_dma_ops = {
+    .read = omap_dma_read,
+    .write = omap_dma_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void omap_dma_request(void *opaque, int drq, int req)
@@ -1613,13 +1618,14 @@ static void omap_dma_setcaps(struct omap_dma_s *s)
     }
 }
 
-struct soc_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
+struct soc_dma_s *omap_dma_init(hwaddr base, qemu_irq *irqs,
+                MemoryRegion *sysmem,
                 qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
                 enum omap_dma_model model)
 {
-    int iomemtype, num_irqs, memsize, i;
+    int num_irqs, memsize, i;
     struct omap_dma_s *s = (struct omap_dma_s *)
-            qemu_mallocz(sizeof(struct omap_dma_s));
+            g_malloc0(sizeof(struct omap_dma_s));
 
     if (model <= omap_dma_3_1) {
         num_irqs = 6;
@@ -1628,7 +1634,6 @@ struct soc_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
         num_irqs = 16;
         memsize = 0xc00;
     }
-    s->base = base;
     s->model = model;
     s->mpu = mpu;
     s->clk = clk;
@@ -1658,9 +1663,8 @@ struct soc_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
     omap_dma_reset(s->dma);
     omap_dma_clk_update(s, 0, 1);
 
-    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
-                    omap_dma_writefn, s);
-    cpu_register_physical_memory(s->base, memsize, iomemtype);
+    memory_region_init_io(&s->iomem, &omap_dma_ops, s, "omap.dma", memsize);
+    memory_region_add_subregion(sysmem, base, &s->iomem);
 
     mpu->drq = s->dma->drq;
 
@@ -1688,13 +1692,18 @@ static void omap_dma_interrupts_4_update(struct omap_dma_s *s)
         qemu_irq_raise(s->irq[3]);
 }
 
-static uint32_t omap_dma4_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_dma4_read(void *opaque, hwaddr addr,
+                               unsigned size)
 {
     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
-    int irqn = 0, chnum, offset = addr - s->base;
+    int irqn = 0, chnum;
     struct omap_dma_channel_s *ch;
 
-    switch (offset) {
+    if (size == 1) {
+        return omap_badwidth_read16(opaque, addr);
+    }
+
+    switch (addr) {
     case 0x00: /* DMA4_REVISION */
         return 0x40;
 
@@ -1735,10 +1744,10 @@ static uint32_t omap_dma4_read(void *opaque, target_phys_addr_t addr)
         return s->gcr;
 
     case 0x80 ... 0xfff:
-        offset -= 0x80;
-        chnum = offset / 0x60;
+        addr -= 0x80;
+        chnum = addr / 0x60;
         ch = s->ch + chnum;
-        offset -= chnum * 0x60;
+        addr -= chnum * 0x60;
         break;
 
     default:
@@ -1747,7 +1756,7 @@ static uint32_t omap_dma4_read(void *opaque, target_phys_addr_t addr)
     }
 
     /* Per-channel registers */
-    switch (offset) {
+    switch (addr) {
     case 0x00: /* DMA4_CCR */
         return (ch->buf_disable << 25) |
                 (ch->src_sync << 24) |
@@ -1833,14 +1842,18 @@ static uint32_t omap_dma4_read(void *opaque, target_phys_addr_t addr)
     }
 }
 
-static void omap_dma4_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+static void omap_dma4_write(void *opaque, hwaddr addr,
+                            uint64_t value, unsigned size)
 {
     struct omap_dma_s *s = (struct omap_dma_s *) opaque;
-    int chnum, irqn = 0, offset = addr - s->base;
+    int chnum, irqn = 0;
     struct omap_dma_channel_s *ch;
 
-    switch (offset) {
+    if (size == 1) {
+        return omap_badwidth_write16(opaque, addr, value);
+    }
+
+    switch (addr) {
     case 0x14: /* DMA4_IRQSTATUS_L3 */
         irqn ++;
     case 0x10: /* DMA4_IRQSTATUS_L2 */
@@ -1878,10 +1891,10 @@ static void omap_dma4_write(void *opaque, target_phys_addr_t addr,
         return;
 
     case 0x80 ... 0xfff:
-        offset -= 0x80;
-        chnum = offset / 0x60;
+        addr -= 0x80;
+        chnum = addr / 0x60;
         ch = s->ch + chnum;
-        offset -= chnum * 0x60;
+        addr -= chnum * 0x60;
         break;
 
     case 0x00: /* DMA4_REVISION */
@@ -1899,7 +1912,7 @@ static void omap_dma4_write(void *opaque, target_phys_addr_t addr,
     }
 
     /* Per-channel registers */
-    switch (offset) {
+    switch (addr) {
     case 0x00: /* DMA4_CCR */
         ch->buf_disable = (value >> 25) & 1;
         ch->src_sync = (value >> 24) & 1;      /* XXX For CamDMA must be 1 */
@@ -1975,12 +1988,12 @@ static void omap_dma4_write(void *opaque, target_phys_addr_t addr,
         break;
 
     case 0x1c: /* DMA4_CSSA */
-        ch->addr[0] = (target_phys_addr_t) (uint32_t) value;
+        ch->addr[0] = (hwaddr) (uint32_t) value;
         ch->set_update = 1;
         break;
 
     case 0x20: /* DMA4_CDSA */
-        ch->addr[1] = (target_phys_addr_t) (uint32_t) value;
+        ch->addr[1] = (hwaddr) (uint32_t) value;
         ch->set_update = 1;
         break;
 
@@ -2021,27 +2034,21 @@ static void omap_dma4_write(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static CPUReadMemoryFunc *omap_dma4_readfn[] = {
-    omap_badwidth_read16,
-    omap_dma4_read,
-    omap_dma4_read,
+static const MemoryRegionOps omap_dma4_ops = {
+    .read = omap_dma4_read,
+    .write = omap_dma4_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc *omap_dma4_writefn[] = {
-    omap_badwidth_write16,
-    omap_dma4_write,
-    omap_dma4_write,
-};
-
-struct soc_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs,
+struct soc_dma_s *omap_dma4_init(hwaddr base, qemu_irq *irqs,
+                MemoryRegion *sysmem,
                 struct omap_mpu_state_s *mpu, int fifo,
                 int chans, omap_clk iclk, omap_clk fclk)
 {
-    int iomemtype, i;
+    int i;
     struct omap_dma_s *s = (struct omap_dma_s *)
-            qemu_mallocz(sizeof(struct omap_dma_s));
+            g_malloc0(sizeof(struct omap_dma_s));
 
-    s->base = base;
     s->model = omap_dma_4;
     s->chans = chans;
     s->mpu = mpu;
@@ -2066,9 +2073,8 @@ struct soc_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs,
     omap_dma_reset(s->dma);
     omap_dma_clk_update(s, 0, !!s->dma->freq);
 
-    iomemtype = cpu_register_io_memory(0, omap_dma4_readfn,
-                    omap_dma4_writefn, s);
-    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
+    memory_region_init_io(&s->iomem, &omap_dma4_ops, s, "omap.dma4", 0x1000);
+    memory_region_add_subregion(sysmem, base, &s->iomem);
 
     mpu->drq = s->dma->drq;