@@ -3,7 +3,7 @@
#
# Common support
-obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o
+obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o dma.o
obj-y += clock.o clock_data.o opp_data.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
@@ -35,6 +35,81 @@
#include <plat/tc.h>
#define OMAP1_DMA_BASE (0xfffed800)
+#define OMAP1_LOGICAL_DMA_CH_COUNT 17
+
+static u32 errata;
+static u32 enable_1510_mode;
+
+enum {
+ GCR1 = 0, GSCR, GRST, HW_ID,
+ PCH2_ID, PCH0_ID, PCH1_ID, PCHG_ID,
+ PCHD_ID, CAPS_0_U, CAPS_0_L, CAPS_1_U,
+ CAPS_1_L, CAPS_2, CAPS_3, CAPS_4,
+ PCH2_SR, PCH0_SR, PCH1_SR, PCHD_SR,
+
+ CH_COMMON_START,
+
+ /* Common Registers */
+ CSDP1, CCR1, CICR1, CSR1,
+ CEN1, CFN1, CSFI1, CSEI1,
+ CPC, CSAC1, CDAC1, CDEI1,
+ CDFI1, CLNK_CTRL1,
+
+ /* Channel specific register offsets */
+ CSSA_L, CSSA_U, CDSA_L, CDSA_U,
+ COLOR_L, COLOR_U, CCR1_2, LCH_CTRL,
+
+ CH_COMMON_END,
+};
+
+static u16 reg_map[] = {
+ [GCR1] = 0x400,
+ [GSCR] = 0x404,
+ [GRST] = 0x408,
+ [HW_ID] = 0x442,
+ [PCH2_ID] = 0x444,
+ [PCH0_ID] = 0x446,
+ [PCH1_ID] = 0x448,
+ [PCHG_ID] = 0x44a,
+ [PCHD_ID] = 0x44c,
+ [CAPS_0_U] = 0x44e,
+ [CAPS_0_L] = 0x450,
+ [CAPS_1_U] = 0x452,
+ [CAPS_1_L] = 0x454,
+ [CAPS_2] = 0x456,
+ [CAPS_3] = 0x458,
+ [CAPS_4] = 0x45a,
+ [PCH2_SR] = 0x460,
+ [PCH0_SR] = 0x480,
+ [PCH1_SR] = 0x482,
+ [PCHD_SR] = 0x4c0,
+
+ /* Common Registers */
+ [CSDP1] = 0x00,
+ [CCR1] = 0x02,
+ [CICR1] = 0x04,
+ [CSR1] = 0x06,
+ [CEN1] = 0x10,
+ [CFN1] = 0x12,
+ [CSFI1] = 0x14,
+ [CSEI1] = 0x16,
+ [CPC] = 0x18, /* 15xx only */
+ [CSAC1] = 0x18,
+ [CDAC1] = 0x1a,
+ [CDEI1] = 0x1c,
+ [CDFI1] = 0x1e,
+ [CLNK_CTRL1] = 0x28,
+
+ /* Channel specific register offsets */
+ [CSSA_L] = 0x08,
+ [CSSA_U] = 0x0a,
+ [CDSA_L] = 0x0c,
+ [CDSA_U] = 0x0e,
+ [COLOR_L] = 0x20,
+ [COLOR_U] = 0x22,
+ [CCR1_2] = 0x24,
+ [LCH_CTRL] = 0x2a,
+};
static struct resource res[] __initdata = {
[0] = {
@@ -130,9 +205,64 @@ static struct resource res[] __initdata = {
},
};
+static void __iomem *dma_base;
+static inline void dma_write(u16 val, int reg, int lch)
+{
+ if (reg > CH_COMMON_START)
+ __raw_writew(val, dma_base + (reg_map[reg] + 0x40 * lch));
+ else
+ __raw_writew(val, dma_base + reg_map[reg]);
+}
+
+static inline u16 dma_read(int reg, int lch)
+{
+ if (reg > CH_COMMON_START)
+ return __raw_readw(dma_base + (reg_map[reg] + 0x40 * lch));
+ else
+ return __raw_readw(dma_base + reg_map[reg]);
+}
+
+static void omap1_show_dma_caps(void)
+{
+ if (enable_1510_mode) {
+ printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
+ } else {
+ u16 w;
+ printk(KERN_INFO "OMAP DMA hardware version %d\n",
+ dma_read(HW_ID, 0));
+ printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
+ (dma_read(CAPS_0_U, 0) << 16) |
+ dma_read(CAPS_0_L, 0),
+ (dma_read(CAPS_1_U, 0) << 16) |
+ dma_read(CAPS_1_L, 0),
+ dma_read(CAPS_2, 0), dma_read(CAPS_3, 0),
+ dma_read(CAPS_4, 0));
+
+ /* Disable OMAP 3.0/3.1 compatibility mode. */
+ w = dma_read(GSCR, 0);
+ w |= 1 << 3;
+ dma_write(w, GSCR, 0);
+ }
+ return;
+}
+
+static u32 configure_dma_errata(void)
+{
+
+ /*
+ * Errata 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ if (!cpu_is_omap15xx())
+ SET_DMA_ERRATA(DMA_ERRATA_3_3);
+
+ return errata;
+}
+
static int __init omap1_system_dma_init(void)
{
struct omap_system_dma_plat_info *p;
+ struct omap_dma_dev_attr *d;
struct platform_device *pdev;
int ret;
@@ -158,20 +288,68 @@ static int __init omap1_system_dma_init(void)
goto exit_device_put;
}
+ d = p->dma_attr;
+ d->chan = kzalloc(sizeof(struct omap_dma_lch) *
+ (d->lch_count), GFP_KERNEL);
+ if (!d->chan) {
+ dev_err(&pdev->dev, "%s: Memory allocation failed"
+ "for d->chan!!!\n", __func__);
+ goto exit_release_p;
+ }
+
+ /* Valid attributes for omap1 plus processors */
+ if (cpu_is_omap15xx())
+ d->dev_caps = ENABLE_1510_MODE;
+ enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
+
+ d->dev_caps |= SRC_PORT;
+ d->dev_caps |= DST_PORT;
+ d->dev_caps |= SRC_INDEX;
+ d->dev_caps |= DST_INDEX;
+ d->dev_caps |= IS_BURST_ONLY4;
+ d->dev_caps |= CLEAR_CSR_ON_READ;
+ d->dev_caps |= IS_WORD_16;
+
+ d->lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
+
+ if (cpu_is_omap15xx())
+ d->chan_count = 9;
+ else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
+ if (!(d->dev_caps & ENABLE_1510_MODE))
+ d->chan_count = 16;
+ else
+ d->chan_count = 9;
+ }
+
+ p->omap_dma_base = (void __iomem *)res[0].start;
+ dma_base = p->omap_dma_base;
+
+ p->show_dma_caps = omap1_show_dma_caps;
+ p->dma_write = dma_write;
+ p->dma_read = dma_read;
+ p->disable_irq_lch = NULL;
+
+ /* Configure errata handling for all omap1+ */
+ p->errata = configure_dma_errata();
+
ret = platform_device_add_data(pdev, p, sizeof(*p));
if (ret) {
dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
__func__, pdev->name, pdev->id);
- goto exit_device_put;
+ goto exit_release_chan;
}
ret = platform_device_add(pdev);
if (ret) {
dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
__func__, pdev->name, pdev->id);
- goto exit_device_put;
+ goto exit_release_chan;
}
return ret;
+exit_release_chan:
+ kfree(d->chan);
+exit_release_p:
+ kfree(p);
exit_device_put:
platform_device_put(pdev);
exit_device_del:
@@ -4,7 +4,7 @@
# Common support
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \
- common.o
+ common.o dma.o
omap-2-3-common = irq.o sdrc.o prm2xxx_3xxx.o
hwmod-common = omap_hwmod.o \
@@ -39,6 +39,79 @@
#include <plat/omap_device.h>
#include <plat/dma.h>
+static u32 errata;
+static struct omap_dma_dev_attr *d;
+
+enum {
+ REVISION = 0, GCR2, IRQSTATUS_L0, IRQSTATUS_L1,
+ IRQSTATUS_L2, IRQSTATUS_L3, IRQENABLE_L0, IRQENABLE_L1,
+ IRQENABLE_L2, IRQENABLE_L3, SYSSTATUS, OCP_SYSCONFIG,
+ CAPS_0, CAPS_2, CAPS_3, CAPS_4,
+
+ CH_COMMON_START,
+
+ /* Common register offsets */
+ CCR2, CLNK_CTRL2, CICR2, CSR2,
+ CSDP2, CEN2, CFN2, CSEI2,
+ CSFI2, CDEI2, CDFI2, CSAC2,
+ CDAC2,
+
+ /* Channel specific register offsets */
+ CSSA, CDSA, CCEN, CCFN,
+ COLOR,
+
+ /* OMAP4 specific registers */
+ CDP, CNDP, CCDN,
+
+ CH_COMMON_END,
+};
+
+static u16 reg_map[] = {
+ [REVISION] = 0x00,
+ [GCR2] = 0x78,
+ [IRQSTATUS_L0] = 0x08,
+ [IRQSTATUS_L1] = 0x0c,
+ [IRQSTATUS_L2] = 0x10,
+ [IRQSTATUS_L3] = 0x14,
+ [IRQENABLE_L0] = 0x18,
+ [IRQENABLE_L1] = 0x1c,
+ [IRQENABLE_L2] = 0x20,
+ [IRQENABLE_L3] = 0x24,
+ [SYSSTATUS] = 0x28,
+ [OCP_SYSCONFIG] = 0x2c,
+ [CAPS_0] = 0x64,
+ [CAPS_2] = 0x6c,
+ [CAPS_3] = 0x70,
+ [CAPS_4] = 0x74,
+
+ /* Common register offsets */
+ [CCR2] = 0x80,
+ [CLNK_CTRL2] = 0x84,
+ [CICR2] = 0x88,
+ [CSR2] = 0x8c,
+ [CSDP2] = 0x90,
+ [CEN2] = 0x94,
+ [CFN2] = 0x98,
+ [CSEI2] = 0xa4,
+ [CSFI2] = 0xa8,
+ [CDEI2] = 0xac,
+ [CDFI2] = 0xb0,
+ [CSAC2] = 0xb4,
+ [CDAC2] = 0xb8,
+
+ /* Channel specific register offsets */
+ [CSSA] = 0x9c,
+ [CDSA] = 0xa0,
+ [CCEN] = 0xbc,
+ [CCFN] = 0xc0,
+ [COLOR] = 0xc4,
+
+ /* OMAP4 specific registers */
+ [CDP] = 0xd0,
+ [CNDP] = 0xd4,
+ [CCDN] = 0xd8,
+};
+
static struct omap_device_pm_latency omap2_dma_latency[] = {
{
.deactivate_func = omap_device_idle_hwmods,
@@ -47,12 +120,118 @@ static struct omap_device_pm_latency omap2_dma_latency[] = {
},
};
+static void __iomem *dma_base;
+static inline void dma_write(u32 val, int reg, int lch)
+{
+ if (reg > CH_COMMON_START)
+ __raw_writel(val, dma_base + (reg_map[reg] + 0x60 * lch));
+ else
+ __raw_writel(val, dma_base + reg_map[reg]);
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+ if (reg > CH_COMMON_START)
+ return __raw_readl(dma_base + (reg_map[reg] + 0x60 * lch));
+ else
+ return __raw_readl(dma_base + reg_map[reg]);
+}
+
+static inline void disable_irq_lch(int lch)
+{
+ u32 val;
+
+ val = dma_read(IRQENABLE_L0, lch);
+ val &= ~(1 << lch);
+ dma_write(val, IRQENABLE_L0, lch);
+}
+
+static void omap2_show_dma_caps(void)
+{
+ u8 revision = dma_read(REVISION, 0) & 0xff;
+ printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
+ revision >> 4, revision & 0xf);
+ return;
+}
+
+static u32 configure_dma_errata(void)
+{
+
+ /*
+ * Erratas applicable for OMAP2430ES1.0 and all omap2420
+ *
+ * I.
+ * Errata ID: XX Inter Frame DMA buffering issue DMA will wrongly
+ * buffer elements if packing and bursting is enabled. This might
+ * result in data gets stalled in FIFO at the end of the block.
+ * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
+ * guarantee no data will stay in the DMA FIFO in case inter frame
+ * buffering occurs
+ *
+ * II.
+ * Errata ID: XX DMA may hang when several channels are used in parallel
+ * In the following configuration, DMA channel hanging can occur:
+ * a. Channel i, hardware synchronized, is enabled
+ * b. Another channel (Channel x), software synchronized, is enabled.
+ * c. Channel i is disabled before end of transfer
+ * d. Channel i is reenabled.
+ * e. Steps 1 to 4 are repeated a certain number of times.
+ * f. A third channel (Channel y), software synchronized, is enabled.
+ * Channel x and Channel y may hang immediately after step 'f'.
+ * Workaround:
+ * For any channel used - make sure NextLCH_ID is set to the value j.
+ */
+ if (cpu_is_omap2420() || (cpu_is_omap2430() &&
+ (omap_type() == OMAP2430_REV_ES1_0))) {
+
+ SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
+ SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
+ }
+
+ /*
+ * Errata ID: i378: OMAP2plus: sDMA Channel is not disabled
+ * after a transaction error.
+ * Workaround: SW should explicitely disable the channel.
+ */
+ if (cpu_class_is_omap2())
+ SET_DMA_ERRATA(DMA_ERRATA_i378);
+
+ /*
+ * Errata ID: i541: sDMA FIFO draining does not finish
+ * If sDMA channel is disabled on the fly, sDMA enters standby even
+ * through FIFO Drain is still in progress
+ * Workaround: Put sDMA in NoStandby more before a logical channel is
+ * disabled, then put it back to SmartStandby right after the channel
+ * finishes FIFO draining.
+ */
+ if (cpu_is_omap34xx())
+ SET_DMA_ERRATA(DMA_ERRATA_i541);
+
+ /*
+ * Errata ID: i88 : Special programming model needed to disable DMA
+ * before end of block.
+ * Workaround: software must ensure that the DMA is configured in No
+ * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
+ */
+ if (omap_type() == OMAP3430_REV_ES1_0)
+ SET_DMA_ERRATA(DMA_ERRATA_i88);
+
+ /*
+ * Errata 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ SET_DMA_ERRATA(DMA_ERRATA_3_3);
+
+ return errata;
+}
+
/* One time initializations */
static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
{
struct omap_device *od;
struct omap_system_dma_plat_info *p;
- char *name = "omap_system_dma";
+ struct resource *mem;
+ char *name = "omap_dma_system";
p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
if (!p) {
@@ -60,6 +239,16 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
__func__, name, oh->name);
return -ENOMEM;
}
+ p->regs = reg_map;
+ p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
+ p->disable_irq_lch = disable_irq_lch;
+ p->show_dma_caps = omap2_show_dma_caps;
+ p->dma_write = dma_write;
+ p->dma_read = dma_read;
+
+ /* Configure errata handling for all omap2+'s */
+ p->errata = configure_dma_errata();
+
od = omap_device_build(name, 0, oh, p, sizeof(*p),
omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0);
@@ -71,6 +260,26 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
}
kfree(p);
+ mem = platform_get_resource(&od->pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&od->pdev.dev, "%s: no mem resource\n", __func__);
+ return -EINVAL;
+ }
+
+ dma_base = ioremap(mem->start, resource_size(mem));
+ if (!dma_base) {
+ dev_err(&od->pdev.dev, "%s: ioremap fail\n", __func__);
+ return -ENOMEM;
+ }
+
+ d = oh->dev_attr;
+ d->chan = kzalloc(sizeof(struct omap_dma_lch) *
+ (d->lch_count), GFP_KERNEL);
+
+ if (!d->chan) {
+ dev_err(&od->pdev.dev, "%s: kzalloc fail\n", __func__);
+ return -ENOMEM;
+ }
return 0;
}
@@ -29,4 +29,7 @@
#ifndef __ASM_ARCH_OMAP2_DMA_H
#define __ASM_ARCH_OMAP2_DMA_H
+/* Should be part of hwmod data base ? */
+#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
+
#endif /* __ASM_ARCH_OMAP2_DMA_H */
@@ -15,6 +15,10 @@
*
* Support functions for the OMAP internal DMA channels.
*
+ * Copyright (C) 2010 Texas Instruments
+ * Converted DMA library into DMA platform driver.
+ * - G, Manjunath Kondaiah <manjugk@ti.com>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -194,6 +198,9 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
+static struct omap_system_dma_plat_info *p;
+static struct omap_dma_dev_attr *d;
+static u16 *reg_map;
static int enable_1510_mode;
static u32 errata;
@@ -203,27 +210,6 @@ static struct omap_dma_global_context_registers {
u32 dma_gcr;
} omap_dma_global_context;
-struct omap_dma_lch {
- int next_lch;
- int dev_id;
- u16 saved_csr;
- u16 enabled_irqs;
- const char *dev_name;
- void (*callback)(int lch, u16 ch_status, void *data);
- void *data;
-
-#ifndef CONFIG_ARCH_OMAP1
- /* required for Dynamic chaining */
- int prev_linked_ch;
- int next_linked_ch;
- int state;
- int chain_id;
-
- int status;
-#endif
- long flags;
-};
-
struct dma_link_info {
int *linked_dmach_q;
int no_of_lchs_linked;
@@ -280,15 +266,6 @@ static int omap_dma_reserve_channels;
static spinlock_t dma_chan_lock;
static struct omap_dma_lch *dma_chan;
static void __iomem *dma_base;
-
-static const u8 omap1_dma_irq[OMAP1_LOGICAL_DMA_CH_COUNT] = {
- INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
- INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
- INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
- INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
- INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
-};
-
static inline void disable_lnk(int lch);
static void omap_disable_channel_irq(int lch);
static inline void omap_enable_channel_irq(int lch);
@@ -296,43 +273,6 @@ static inline void omap_enable_channel_irq(int lch);
#define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \
__func__);
-static inline void dma_write(u32 val, int reg, int lch)
-{
- if (cpu_class_is_omap1()) {
- if (reg > OMAP1_CH_COMMON_START)
- __raw_writew(val, dma_base +
- (reg_map_omap1[reg] + 0x40 * lch));
- else
- __raw_writew(val, dma_base + reg_map_omap1[reg]);
- } else {
- if (reg > OMAP2_CH_COMMON_START)
- __raw_writel(val, dma_base +
- (reg_map_omap2[reg] + 0x60 * lch));
- else
- __raw_writel(val, dma_base + reg_map_omap2[reg]);
- }
-}
-
-static inline u32 dma_read(int reg, int lch)
-{
- u32 val;
-
- if (cpu_class_is_omap1()) {
- if (reg > OMAP1_CH_COMMON_START)
- val = __raw_readw(dma_base +
- (reg_map_omap1[reg] + 0x40 * lch));
- else
- val = __raw_readw(dma_base + reg_map_omap1[reg]);
- } else {
- if (reg > OMAP2_CH_COMMON_START)
- val = __raw_readl(dma_base +
- (reg_map_omap2[reg] + 0x60 * lch));
- else
- val = __raw_readl(dma_base + reg_map_omap2[reg]);
- }
- return val;
-}
-
#ifdef CONFIG_ARCH_OMAP15XX
/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
int omap_dma_in_1510_mode(void)
@@ -373,7 +313,7 @@ static void clear_lch_regs(int lch)
int i = OMAP1_CH_COMMON_START;
for (; i <= OMAP1_CH_COMMON_END; i += 1)
- dma_write(0, i, lch);
+ p->dma_write(0, i, lch);
}
void omap_set_dma_priority(int lch, int dst_port, int priority)
@@ -408,12 +348,12 @@ void omap_set_dma_priority(int lch, int dst_port, int priority)
if (cpu_class_is_omap2()) {
u32 ccr;
- ccr = dma_read(CCR2, lch);
+ ccr = p->dma_read(CCR2, lch);
if (priority)
ccr |= (1 << 6);
else
ccr &= ~(1 << 6);
- dma_write(ccr, CCR2, lch);
+ p->dma_write(ccr, CCR2, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_priority);
@@ -427,33 +367,33 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
if (cpu_class_is_omap1()) {
u16 ccr;
- l = dma_read(CSDP1, lch);
+ l = p->dma_read(CSDP1, lch);
l &= ~0x03;
l |= data_type;
- dma_write(l, CSDP1, lch);
+ p->dma_write(l, CSDP1, lch);
- ccr = dma_read(CCR1, lch);
+ ccr = p->dma_read(CCR1, lch);
ccr &= ~(1 << 5);
if (sync_mode == OMAP_DMA_SYNC_FRAME)
ccr |= 1 << 5;
- dma_write(ccr, CCR1, lch);
+ p->dma_write(ccr, CCR1, lch);
- ccr = dma_read(CCR1_2, lch);
+ ccr = p->dma_read(CCR1_2, lch);
ccr &= ~(1 << 2);
if (sync_mode == OMAP_DMA_SYNC_BLOCK)
ccr |= 1 << 2;
- dma_write(ccr, CCR1_2, lch);
+ p->dma_write(ccr, CCR1_2, lch);
}
if (cpu_class_is_omap2() && dma_trigger) {
u32 val;
- l = dma_read(CSDP2, lch);
+ l = p->dma_read(CSDP2, lch);
l &= ~0x03;
l |= data_type;
- dma_write(l, CSDP2, lch);
+ p->dma_write(l, CSDP2, lch);
- val = dma_read(CCR2, lch);
+ val = p->dma_read(CCR2, lch);
/* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
val &= ~((1 << 23) | (3 << 19) | 0x1f);
@@ -478,14 +418,14 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
} else {
val &= ~(1 << 24); /* dest synch */
}
- dma_write(val, CCR2, lch);
+ p->dma_write(val, CCR2, lch);
}
if (cpu_class_is_omap1()) {
- dma_write(elem_count, CEN1, lch);
- dma_write(frame_count, CFN1, lch);
+ p->dma_write(elem_count, CEN1, lch);
+ p->dma_write(frame_count, CFN1, lch);
} else {
- dma_write(elem_count, CEN2, lch);
- dma_write(frame_count, CFN2, lch);
+ p->dma_write(elem_count, CEN2, lch);
+ p->dma_write(frame_count, CFN2, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_transfer_params);
@@ -497,7 +437,7 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
if (cpu_class_is_omap1()) {
u16 w;
- w = dma_read(CCR1_2, lch);
+ w = p->dma_read(CCR1_2, lch);
w &= ~0x03;
switch (mode) {
@@ -512,23 +452,23 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG();
}
- dma_write(w, CCR1_2, lch);
+ p->dma_write(w, CCR1_2, lch);
- w = dma_read(LCH_CTRL, lch);
+ w = p->dma_read(LCH_CTRL, lch);
w &= ~0x0f;
/* Default is channel type 2D */
if (mode) {
- dma_write((u16)color, COLOR_L, lch);
- dma_write((u16)(color >> 16), COLOR_U, lch);
+ p->dma_write((u16)color, COLOR_L, lch);
+ p->dma_write((u16)(color >> 16), COLOR_U, lch);
w |= 1; /* Channel type G */
}
- dma_write(w, LCH_CTRL, lch);
+ p->dma_write(w, LCH_CTRL, lch);
}
if (cpu_class_is_omap2()) {
u32 val;
- val = dma_read(CCR2, lch);
+ val = p->dma_read(CCR2, lch);
val &= ~((1 << 17) | (1 << 16));
switch (mode) {
@@ -543,10 +483,10 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
default:
BUG();
}
- dma_write(val, CCR2, lch);
+ p->dma_write(val, CCR2, lch);
color &= 0xffffff;
- dma_write(color, COLOR, lch);
+ p->dma_write(color, COLOR, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_color_mode);
@@ -556,10 +496,10 @@ void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
if (cpu_class_is_omap2()) {
u32 csdp;
- csdp = dma_read(CSDP2, lch);
+ csdp = p->dma_read(CSDP2, lch);
csdp &= ~(0x3 << 16);
csdp |= (mode << 16);
- dma_write(csdp, CSDP2, lch);
+ p->dma_write(csdp, CSDP2, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_write_mode);
@@ -569,10 +509,10 @@ void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
u32 l;
- l = dma_read(LCH_CTRL, lch);
+ l = p->dma_read(LCH_CTRL, lch);
l &= ~0x7;
l |= mode;
- dma_write(l, LCH_CTRL, lch);
+ p->dma_write(l, LCH_CTRL, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_channel_mode);
@@ -587,37 +527,37 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
if (cpu_class_is_omap1()) {
u16 w;
- w = dma_read(CSDP1, lch);
+ w = p->dma_read(CSDP1, lch);
w &= ~(0x1f << 2);
w |= src_port << 2;
- dma_write(w, CSDP1, lch);
+ p->dma_write(w, CSDP1, lch);
- l = dma_read(CCR1, lch);
+ l = p->dma_read(CCR1, lch);
} else
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
l &= ~(0x03 << 12);
l |= src_amode << 12;
if (cpu_class_is_omap1())
- dma_write(l, CCR1, lch);
+ p->dma_write(l, CCR1, lch);
else
- dma_write(l, CCR2, lch);
+ p->dma_write(l, CCR2, lch);
if (cpu_class_is_omap1()) {
- dma_write(src_start >> 16, CSSA_U, lch);
- dma_write((u16)src_start, CSSA_L, lch);
+ p->dma_write(src_start >> 16, CSSA_U, lch);
+ p->dma_write((u16)src_start, CSSA_L, lch);
}
if (cpu_class_is_omap2())
- dma_write(src_start, CSSA, lch);
+ p->dma_write(src_start, CSSA, lch);
if (cpu_class_is_omap1()) {
- dma_write(src_ei, CSEI1, lch);
- dma_write(src_fi, CSFI1, lch);
+ p->dma_write(src_ei, CSEI1, lch);
+ p->dma_write(src_fi, CSFI1, lch);
} else {
- dma_write(src_ei, CSEI2, lch);
- dma_write(src_fi, CSFI2, lch);
+ p->dma_write(src_ei, CSEI2, lch);
+ p->dma_write(src_fi, CSFI2, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_src_params);
@@ -646,8 +586,8 @@ void omap_set_dma_src_index(int lch, int eidx, int fidx)
if (cpu_class_is_omap2())
return;
- dma_write(eidx, CSEI1, lch);
- dma_write(fidx, CSFI1, lch);
+ p->dma_write(eidx, CSEI1, lch);
+ p->dma_write(fidx, CSFI1, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_index);
@@ -656,18 +596,18 @@ void omap_set_dma_src_data_pack(int lch, int enable)
u32 l;
if (cpu_class_is_omap1())
- l = dma_read(CSDP1, lch);
+ l = p->dma_read(CSDP1, lch);
else
- l = dma_read(CSDP2, lch);
+ l = p->dma_read(CSDP2, lch);
l &= ~(1 << 6);
if (enable)
l |= (1 << 6);
if (cpu_class_is_omap1())
- dma_write(l, CSDP1, lch);
+ p->dma_write(l, CSDP1, lch);
else
- dma_write(l, CSDP2, lch);
+ p->dma_write(l, CSDP2, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_data_pack);
@@ -677,9 +617,9 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
u32 l;
if (cpu_class_is_omap2())
- l = dma_read(CSDP2, lch);
+ l = p->dma_read(CSDP2, lch);
else
- l = dma_read(CSDP1, lch);
+ l = p->dma_read(CSDP1, lch);
l &= ~(0x03 << 7);
@@ -718,9 +658,9 @@ void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
l |= (burst << 7);
if (cpu_class_is_omap2())
- dma_write(l, CSDP2, lch);
+ p->dma_write(l, CSDP2, lch);
else
- dma_write(l, CSDP1, lch);
+ p->dma_write(l, CSDP1, lch);
}
EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
@@ -732,37 +672,37 @@ void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
u32 l;
if (cpu_class_is_omap1()) {
- l = dma_read(CSDP1, lch);
+ l = p->dma_read(CSDP1, lch);
l &= ~(0x1f << 9);
l |= dest_port << 9;
- dma_write(l, CSDP1, lch);
+ p->dma_write(l, CSDP1, lch);
- l = dma_read(CCR1, lch);
+ l = p->dma_read(CCR1, lch);
} else
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
l &= ~(0x03 << 14);
l |= dest_amode << 14;
if (cpu_class_is_omap1())
- dma_write(l, CCR1, lch);
+ p->dma_write(l, CCR1, lch);
else
- dma_write(l, CCR2, lch);
+ p->dma_write(l, CCR2, lch);
if (cpu_class_is_omap1()) {
- dma_write(dest_start >> 16, CDSA_U, lch);
- dma_write(dest_start, CDSA_L, lch);
+ p->dma_write(dest_start >> 16, CDSA_U, lch);
+ p->dma_write(dest_start, CDSA_L, lch);
}
if (cpu_class_is_omap2())
- dma_write(dest_start, CDSA, lch);
+ p->dma_write(dest_start, CDSA, lch);
if (cpu_class_is_omap1()) {
- dma_write(dst_ei, CDEI1, lch);
- dma_write(dst_fi, CDFI1, lch);
+ p->dma_write(dst_ei, CDEI1, lch);
+ p->dma_write(dst_fi, CDFI1, lch);
} else {
- dma_write(dst_ei, CDEI2, lch);
- dma_write(dst_fi, CDFI2, lch);
+ p->dma_write(dst_ei, CDEI2, lch);
+ p->dma_write(dst_fi, CDFI2, lch);
}
}
EXPORT_SYMBOL(omap_set_dma_dest_params);
@@ -772,8 +712,8 @@ void omap_set_dma_dest_index(int lch, int eidx, int fidx)
if (cpu_class_is_omap2())
return;
- dma_write(eidx, CDEI1, lch);
- dma_write(fidx, CDFI1, lch);
+ p->dma_write(eidx, CDEI1, lch);
+ p->dma_write(fidx, CDFI1, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_index);
@@ -782,18 +722,18 @@ void omap_set_dma_dest_data_pack(int lch, int enable)
u32 l;
if (cpu_class_is_omap2())
- l = dma_read(CSDP2, lch);
+ l = p->dma_read(CSDP2, lch);
else
- l = dma_read(CSDP1, lch);
+ l = p->dma_read(CSDP1, lch);
l &= ~(1 << 13);
if (enable)
l |= 1 << 13;
if (cpu_class_is_omap2())
- dma_write(l, CSDP2, lch);
+ p->dma_write(l, CSDP2, lch);
else
- dma_write(l, CSDP1, lch);
+ p->dma_write(l, CSDP1, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
@@ -802,9 +742,9 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
unsigned int burst = 0;
u32 l;
if (cpu_class_is_omap2())
- l = dma_read(CSDP2, lch);
+ l = p->dma_read(CSDP2, lch);
else
- l = dma_read(CSDP1, lch);
+ l = p->dma_read(CSDP1, lch);
l &= ~(0x03 << 14);
@@ -841,9 +781,9 @@ void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
l |= (burst << 14);
if (cpu_class_is_omap2())
- dma_write(l, CSDP2, lch);
+ p->dma_write(l, CSDP2, lch);
else
- dma_write(l, CSDP1, lch);
+ p->dma_write(l, CSDP1, lch);
}
EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
@@ -853,20 +793,20 @@ static inline void omap_enable_channel_irq(int lch)
/* Clear CSR */
if (cpu_class_is_omap1()) {
- status = dma_read(CSR1, lch);
- dma_write(dma_chan[lch].enabled_irqs, CICR1, lch);
+ status = p->dma_read(CSR1, lch);
+ p->dma_write(dma_chan[lch].enabled_irqs, CICR1, lch);
} else if (cpu_class_is_omap2()) {
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
- dma_write(dma_chan[lch].enabled_irqs, CICR2, lch);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
+ p->dma_write(dma_chan[lch].enabled_irqs, CICR2, lch);
}
}
static void omap_disable_channel_irq(int lch)
{
if (cpu_class_is_omap2())
- dma_write(0, CICR2, lch);
+ p->dma_write(0, CICR2, lch);
else
- dma_write(0, CICR1, lch);
+ p->dma_write(0, CICR1, lch);
}
void omap_enable_dma_irq(int lch, u16 bits)
@@ -886,10 +826,10 @@ static inline void enable_lnk(int lch)
u32 l;
if (cpu_class_is_omap1()) {
- l = dma_read(CLNK_CTRL1, lch);
+ l = p->dma_read(CLNK_CTRL1, lch);
l &= ~(1 << 14);
} else
- l = dma_read(CLNK_CTRL2, lch);
+ l = p->dma_read(CLNK_CTRL2, lch);
/* Set the ENABLE_LNK bits */
if (dma_chan[lch].next_lch != -1)
@@ -898,9 +838,9 @@ static inline void enable_lnk(int lch)
if (cpu_class_is_omap2()) {
if (dma_chan[lch].next_linked_ch != -1)
l = dma_chan[lch].next_linked_ch | (1 << 15);
- dma_write(l, CLNK_CTRL2, lch);
+ p->dma_write(l, CLNK_CTRL2, lch);
} else
- dma_write(l, CLNK_CTRL1, lch);
+ p->dma_write(l, CLNK_CTRL1, lch);
}
static inline void disable_lnk(int lch)
@@ -909,19 +849,19 @@ static inline void disable_lnk(int lch)
/* Disable interrupts */
if (cpu_class_is_omap1()) {
- l = dma_read(CLNK_CTRL1, lch);
- dma_write(0, CICR1, lch);
+ l = p->dma_read(CLNK_CTRL1, lch);
+ p->dma_write(0, CICR1, lch);
/* Set the STOP_LNK bit */
l |= 1 << 14;
- dma_write(l, CLNK_CTRL1, lch);
+ p->dma_write(l, CLNK_CTRL1, lch);
}
if (cpu_class_is_omap2()) {
- l = dma_read(CLNK_CTRL2, lch);
+ l = p->dma_read(CLNK_CTRL2, lch);
omap_disable_channel_irq(lch);
/* Clear the ENABLE_LNK bit */
l &= ~(1 << 15);
- dma_write(l, CLNK_CTRL2, lch);
+ p->dma_write(l, CLNK_CTRL2, lch);
}
dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
}
@@ -935,9 +875,9 @@ static inline void omap2_enable_irq_lch(int lch)
return;
spin_lock_irqsave(&dma_chan_lock, flags);
- val = dma_read(IRQENABLE_L0, 0);
+ val = p->dma_read(IRQENABLE_L0, 0);
val |= 1 << lch;
- dma_write(val, IRQENABLE_L0, 0);
+ p->dma_write(val, IRQENABLE_L0, 0);
spin_unlock_irqrestore(&dma_chan_lock, flags);
}
@@ -950,9 +890,9 @@ static inline void omap2_disable_irq_lch(int lch)
return;
spin_lock_irqsave(&dma_chan_lock, flags);
- val = dma_read(IRQENABLE_L0, 0);
+ val = p->dma_read(IRQENABLE_L0, 0);
val &= ~(1 << lch);
- dma_write(val, IRQENABLE_L0, 0);
+ p->dma_write(val, IRQENABLE_L0, 0);
spin_unlock_irqrestore(&dma_chan_lock, flags);
}
@@ -1017,17 +957,17 @@ int omap_request_dma(int dev_id, const char *dev_name,
* Disable the 1510 compatibility mode and set the sync device
* id.
*/
- dma_write(dev_id | (1 << 10), CCR1, free_ch);
+ p->dma_write(dev_id | (1 << 10), CCR1, free_ch);
} else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
- dma_write(dev_id, CCR1, free_ch);
+ p->dma_write(dev_id, CCR1, free_ch);
}
if (cpu_class_is_omap2()) {
omap2_enable_irq_lch(free_ch);
omap_enable_channel_irq(free_ch);
/* Clear the CSR register and IRQ status register */
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, free_ch);
- dma_write(1 << free_ch, IRQSTATUS_L0, 0);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, free_ch);
+ p->dma_write(1 << free_ch, IRQSTATUS_L0, 0);
}
*dma_ch_out = free_ch;
@@ -1048,23 +988,23 @@ void omap_free_dma(int lch)
if (cpu_class_is_omap1()) {
/* Disable all DMA interrupts for the channel. */
- dma_write(0, CICR1, lch);
+ p->dma_write(0, CICR1, lch);
/* Make sure the DMA transfer is stopped. */
- dma_write(0, CCR1, lch);
+ p->dma_write(0, CCR1, lch);
}
if (cpu_class_is_omap2()) {
omap2_disable_irq_lch(lch);
/* Clear the CSR register and IRQ status register */
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
- dma_write(1 << lch, IRQSTATUS_L0, 0);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, lch);
+ p->dma_write(1 << lch, IRQSTATUS_L0, 0);
/* Disable all DMA interrupts for the channel. */
- dma_write(0, CICR2, lch);
+ p->dma_write(0, CICR2, lch);
/* Make sure the DMA transfer is stopped. */
- dma_write(0, CCR2, lch);
+ p->dma_write(0, CCR2, lch);
omap_clear_dma(lch);
}
@@ -1105,7 +1045,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
reg |= (0x3 & tparams) << 12;
reg |= (arb_rate & 0xff) << 16;
- dma_write(reg, GCR2, 0);
+ p->dma_write(reg, GCR2, 0);
}
EXPORT_SYMBOL(omap_dma_set_global_params);
@@ -1130,15 +1070,15 @@ omap_dma_set_prio_lch(int lch, unsigned char read_prio,
}
if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
l &= ~((1 << 6) | (1 << 26));
l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
- dma_write(l, CCR2, lch);
+ p->dma_write(l, CCR2, lch);
} else {
- l = dma_read(CCR1, lch);
+ l = p->dma_read(CCR1, lch);
l &= ~((1 << 6) | (1 << 26));
l |= ((read_prio & 0x1) << 6);
- dma_write(l, CCR1, lch);
+ p->dma_write(l, CCR1, lch);
}
return 0;
@@ -1158,19 +1098,19 @@ void omap_clear_dma(int lch)
if (cpu_class_is_omap1()) {
u32 l;
- l = dma_read(CCR1, lch);
+ l = p->dma_read(CCR1, lch);
l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR1, lch);
+ p->dma_write(l, CCR1, lch);
/* Clear pending interrupts */
- l = dma_read(CSR1, lch);
+ l = p->dma_read(CSR1, lch);
}
if (cpu_class_is_omap2()) {
int i = OMAP2_CH_COMMON_START;
for (; i <= OMAP2_CH_COMMON_END; i++)
- dma_write(0, i, lch);
+ p->dma_write(0, i, lch);
}
local_irq_restore(flags);
@@ -1186,16 +1126,16 @@ void omap_start_dma(int lch)
* before starting dma transfer.
*/
if (cpu_is_omap15xx())
- dma_write(0, CPC, lch);
+ p->dma_write(0, CPC, lch);
else if (cpu_class_is_omap1())
- dma_write(0, CDAC1, lch);
+ p->dma_write(0, CDAC1, lch);
else
- dma_write(0, CDAC2, lch);
+ p->dma_write(0, CDAC2, lch);
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch;
- char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
+ char dma_chan_link_map[dma_chan_count];
dma_chan_link_map[lch] = 1;
/* Set the link register of the first channel */
@@ -1218,22 +1158,22 @@ void omap_start_dma(int lch)
cur_lch = next_lch;
} while (next_lch != -1);
} else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
- dma_write(lch, CLNK_CTRL2, lch);
+ p->dma_write(lch, CLNK_CTRL2, lch);
omap_enable_channel_irq(lch);
if (cpu_class_is_omap1()) {
- l = dma_read(CCR1, lch);
+ l = p->dma_read(CCR1, lch);
l |= OMAP_DMA_CCR_EN;
- dma_write(l, CCR1, lch);
+ p->dma_write(l, CCR1, lch);
} else {
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
l |= OMAP_DMA_CCR_EN;
- dma_write(l, CCR2, lch);
+ p->dma_write(l, CCR2, lch);
}
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
@@ -1245,7 +1185,7 @@ void omap_stop_dma(int lch)
/* Disable all interrupts on the channel */
if (cpu_class_is_omap1())
- dma_write(0, CICR1, lch);
+ p->dma_write(0, CICR1, lch);
if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
(l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
@@ -1253,42 +1193,42 @@ void omap_stop_dma(int lch)
u32 sys_cf;
/* Configure No-Standby */
- l = dma_read(OCP_SYSCONFIG, 0);
+ l = p->dma_read(OCP_SYSCONFIG, 0);
sys_cf = l;
l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
- dma_write(l , OCP_SYSCONFIG, 0);
+ p->dma_write(l , OCP_SYSCONFIG, 0);
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR2, lch);
+ p->dma_write(l, CCR2, lch);
/* Wait for sDMA FIFO drain */
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
OMAP_DMA_CCR_WR_ACTIVE))) {
udelay(5);
i++;
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
}
if (i >= 100)
printk(KERN_ERR "DMA drain did not complete on "
"lch %d\n", lch);
/* Restore OCP_SYSCONFIG */
- dma_write(sys_cf, OCP_SYSCONFIG, 0);
+ p->dma_write(sys_cf, OCP_SYSCONFIG, 0);
} else if (cpu_class_is_omap1()) {
- l = dma_read(CCR1, lch);
+ l = p->dma_read(CCR1, lch);
l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR1, lch);
+ p->dma_write(l, CCR1, lch);
} else {
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
l &= ~OMAP_DMA_CCR_EN;
- dma_write(l, CCR2, lch);
+ p->dma_write(l, CCR2, lch);
}
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
int next_lch, cur_lch = lch;
- char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
+ char dma_chan_link_map[dma_chan_count];
memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
do {
@@ -1349,21 +1289,21 @@ dma_addr_t omap_get_dma_src_pos(int lch)
dma_addr_t offset = 0;
if (cpu_is_omap15xx())
- offset = dma_read(CPC, lch);
+ offset = p->dma_read(CPC, lch);
else if (cpu_class_is_omap1())
- offset = dma_read(CSAC1, lch);
+ offset = p->dma_read(CSAC1, lch);
else
- offset = dma_read(CSAC2, lch);
+ offset = p->dma_read(CSAC2, lch);
if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0) {
if (cpu_class_is_omap1())
- offset = dma_read(CSAC1, lch);
+ offset = p->dma_read(CSAC1, lch);
else
- offset = dma_read(CSAC2, lch);
+ offset = p->dma_read(CSAC2, lch);
}
if (cpu_class_is_omap1())
- offset |= (dma_read(CSSA_U, lch) << 16);
+ offset |= (p->dma_read(CSSA_U, lch) << 16);
return offset;
}
@@ -1382,11 +1322,11 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
dma_addr_t offset = 0;
if (cpu_is_omap15xx())
- offset = dma_read(CPC, lch);
+ offset = p->dma_read(CPC, lch);
else if (cpu_class_is_omap1())
- offset = dma_read(CDAC1, lch);
+ offset = p->dma_read(CDAC1, lch);
else
- offset = dma_read(CDAC2, lch);
+ offset = p->dma_read(CDAC2, lch);
/*
* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
@@ -1394,13 +1334,13 @@ dma_addr_t omap_get_dma_dst_pos(int lch)
*/
if (!cpu_is_omap15xx() && offset == 0) {
if (cpu_class_is_omap1())
- offset = dma_read(CDAC1, lch);
+ offset = p->dma_read(CDAC1, lch);
else
- offset = dma_read(CDAC2, lch);
+ offset = p->dma_read(CDAC2, lch);
}
if (cpu_class_is_omap1())
- offset |= (dma_read(CDSA_U, lch) << 16);
+ offset |= (p->dma_read(CDSA_U, lch) << 16);
return offset;
}
@@ -1409,9 +1349,9 @@ EXPORT_SYMBOL(omap_get_dma_dst_pos);
int omap_get_dma_active_status(int lch)
{
if (cpu_class_is_omap1())
- return (dma_read(CCR1, lch) & OMAP_DMA_CCR_EN) != 0;
+ return (p->dma_read(CCR1, lch) & OMAP_DMA_CCR_EN) != 0;
else
- return (dma_read(CCR2, lch) & OMAP_DMA_CCR_EN) != 0;
+ return (p->dma_read(CCR2, lch) & OMAP_DMA_CCR_EN) != 0;
}
EXPORT_SYMBOL(omap_get_dma_active_status);
@@ -1421,10 +1361,10 @@ int omap_dma_running(void)
for (lch = 0; lch < dma_chan_count; lch++) {
if (cpu_class_is_omap1()) {
- if (dma_read(CCR1, lch) & OMAP_DMA_CCR_EN)
+ if (p->dma_read(CCR1, lch) & OMAP_DMA_CCR_EN)
return 1;
} else {
- if (dma_read(CCR2, lch) & OMAP_DMA_CCR_EN)
+ if (p->dma_read(CCR2, lch) & OMAP_DMA_CCR_EN)
return 1;
}
}
@@ -1440,7 +1380,7 @@ void omap_dma_link_lch(int lch_head, int lch_queue)
{
if (omap_dma_in_1510_mode()) {
if (lch_head == lch_queue) {
- dma_write(dma_read(CCR1, lch_head) | (3 << 8),
+ p->dma_write(p->dma_read(CCR1, lch_head) | (3 << 8),
CCR1, lch_head);
return;
}
@@ -1467,7 +1407,7 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
{
if (omap_dma_in_1510_mode()) {
if (lch_head == lch_queue) {
- dma_write(dma_read(CCR1, lch_head) & ~(3 << 8),
+ p->dma_write(p->dma_read(CCR1, lch_head) & ~(3 << 8),
CCR1, lch_head);
return;
}
@@ -1494,8 +1434,6 @@ void omap_dma_unlink_lch(int lch_head, int lch_queue)
}
EXPORT_SYMBOL(omap_dma_unlink_lch);
-/*----------------------------------------------------------------------------*/
-
#ifndef CONFIG_ARCH_OMAP1
/* Create chain of DMA channesls */
static void create_dma_lch_chain(int lch_head, int lch_queue)
@@ -1520,15 +1458,15 @@ static void create_dma_lch_chain(int lch_head, int lch_queue)
lch_queue;
}
- l = dma_read(CLNK_CTRL2, lch_head);
+ l = p->dma_read(CLNK_CTRL2, lch_head);
l &= ~(0x1f);
l |= lch_queue;
- dma_write(l, CLNK_CTRL2, lch_head);
+ p->dma_write(l, CLNK_CTRL2, lch_head);
- l = dma_read(CLNK_CTRL2, lch_queue);
+ l = p->dma_read(CLNK_CTRL2, lch_queue);
l &= ~(0x1f);
l |= (dma_chan[lch_queue].next_linked_ch);
- dma_write(l, CLNK_CTRL2, lch_queue);
+ p->dma_write(l, CLNK_CTRL2, lch_queue);
}
/**
@@ -1804,13 +1742,13 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
/* Set the params to the free channel */
if (src_start != 0)
- dma_write(src_start, CSSA, lch);
+ p->dma_write(src_start, CSSA, lch);
if (dest_start != 0)
- dma_write(dest_start, CDSA, lch);
+ p->dma_write(dest_start, CDSA, lch);
/* Write the buffer size */
- dma_write(elem_count, CEN2, lch);
- dma_write(frame_count, CFN2, lch);
+ p->dma_write(elem_count, CEN2, lch);
+ p->dma_write(frame_count, CFN2, lch);
/*
* If the chain is dynamically linked,
@@ -1843,7 +1781,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
enable_lnk(dma_chan[lch].prev_linked_ch);
dma_chan[lch].state = DMA_CH_QUEUED;
start_dma = 0;
- if (0 == ((1 << 7) & dma_read(
+ if (0 == ((1 << 7) & p->dma_read(
CCR2, dma_chan[lch].prev_linked_ch))) {
disable_lnk(dma_chan[lch].
prev_linked_ch);
@@ -1860,7 +1798,7 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
}
omap_enable_channel_irq(lch);
- l = dma_read(CCR2, lch);
+ l = p->dma_read(CCR2, lch);
if ((0 == (l & (1 << 24))))
l &= ~(1 << 25);
@@ -1871,12 +1809,12 @@ int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
l |= (1 << 7);
dma_chan[lch].state = DMA_CH_STARTED;
pr_debug("starting %d\n", lch);
- dma_write(l, CCR2, lch);
+ p->dma_write(l, CCR2, lch);
} else
start_dma = 0;
} else {
if (0 == (l & (1 << 7)))
- dma_write(l, CCR2, lch);
+ p->dma_write(l, CCR2, lch);
}
dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
}
@@ -1921,7 +1859,7 @@ int omap_start_dma_chain_transfers(int chain_id)
omap_enable_channel_irq(channels[0]);
}
- l = dma_read(CCR2, channels[0]);
+ l = p->dma_read(CCR2, channels[0]);
l |= (1 << 7);
dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
dma_chan[channels[0]].state = DMA_CH_STARTED;
@@ -1930,7 +1868,7 @@ int omap_start_dma_chain_transfers(int chain_id)
l &= ~(1 << 25);
else
l |= (1 << 25);
- dma_write(l, CCR2, channels[0]);
+ p->dma_write(l, CCR2, channels[0]);
dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
@@ -1966,19 +1904,19 @@ int omap_stop_dma_chain_transfers(int chain_id)
channels = dma_linked_lch[chain_id].linked_dmach_q;
if (IS_DMA_ERRATA(DMA_ERRATA_i88)) {
- sys_cf = dma_read(OCP_SYSCONFIG, 0);
+ sys_cf = p->dma_read(OCP_SYSCONFIG, 0);
l = sys_cf;
/* Middle mode reg set no Standby */
l &= ~((1 << 12)|(1 << 13));
- dma_write(l, OCP_SYSCONFIG, 0);
+ p->dma_write(l, OCP_SYSCONFIG, 0);
}
for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
/* Stop the Channel transmission */
- l = dma_read(CCR2, channels[i]);
+ l = p->dma_read(CCR2, channels[i]);
l &= ~(1 << 7);
- dma_write(l, CCR2, channels[i]);
+ p->dma_write(l, CCR2, channels[i]);
/* Disable the link in all the channels */
disable_lnk(channels[i]);
@@ -1991,7 +1929,7 @@ int omap_stop_dma_chain_transfers(int chain_id)
OMAP_DMA_CHAIN_QINIT(chain_id);
if (IS_DMA_ERRATA(DMA_ERRATA_i88))
- dma_write(sys_cf, OCP_SYSCONFIG, 0);
+ p->dma_write(sys_cf, OCP_SYSCONFIG, 0);
return 0;
}
@@ -2033,8 +1971,8 @@ int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- *ei = dma_read(CCEN, lch);
- *fi = dma_read(CCFN, lch);
+ *ei = p->dma_read(CCEN, lch);
+ *fi = p->dma_read(CCFN, lch);
return 0;
}
@@ -2071,7 +2009,7 @@ int omap_get_dma_chain_dst_pos(int chain_id)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- return dma_read(CDAC2, lch);
+ return p->dma_read(CDAC2, lch);
}
EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
@@ -2105,7 +2043,7 @@ int omap_get_dma_chain_src_pos(int chain_id)
/* Get the current channel */
lch = channels[dma_linked_lch[chain_id].q_head];
- return dma_read(CSAC2, lch);
+ return p->dma_read(CSAC2, lch);
}
EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
#endif /* ifndef CONFIG_ARCH_OMAP1 */
@@ -2122,7 +2060,7 @@ static int omap1_dma_handle_ch(int ch)
csr = dma_chan[ch].saved_csr;
dma_chan[ch].saved_csr = 0;
} else
- csr = dma_read(CSR1, ch);
+ csr = p->dma_read(CSR1, ch);
if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
dma_chan[ch + 6].saved_csr = csr >> 7;
csr &= 0x7f;
@@ -2175,13 +2113,13 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
static int omap2_dma_handle_ch(int ch)
{
- u32 status = dma_read(CSR2, ch);
+ u32 status = p->dma_read(CSR2, ch);
if (!status) {
if (printk_ratelimit())
printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n",
ch);
- dma_write(1 << ch, IRQSTATUS_L0, 0);
+ p->dma_write(1 << ch, IRQSTATUS_L0, 0);
return 0;
}
if (unlikely(dma_chan[ch].dev_id == -1)) {
@@ -2200,9 +2138,9 @@ static int omap2_dma_handle_ch(int ch)
if (IS_DMA_ERRATA(DMA_ERRATA_i378)) {
u32 ccr;
- ccr = dma_read(CCR2, ch);
+ ccr = p->dma_read(CCR2, ch);
ccr &= ~OMAP_DMA_CCR_EN;
- dma_write(ccr, CCR2, ch);
+ p->dma_write(ccr, CCR2, ch);
dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
}
}
@@ -2213,16 +2151,16 @@ static int omap2_dma_handle_ch(int ch)
printk(KERN_INFO "DMA misaligned error with device %d\n",
dma_chan[ch].dev_id);
- dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, ch);
- dma_write(1 << ch, IRQSTATUS_L0, ch);
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR2, ch);
+ p->dma_write(1 << ch, IRQSTATUS_L0, ch);
/* read back the register to flush the write */
- dma_read(IRQSTATUS_L0, ch);
+ p->dma_read(IRQSTATUS_L0, ch);
/* If the ch is not chained then chain_id will be -1 */
if (dma_chan[ch].chain_id != -1) {
int chain_id = dma_chan[ch].chain_id;
dma_chan[ch].state = DMA_CH_NOTSTARTED;
- if (dma_read(CLNK_CTRL2, ch) & (1 << 15))
+ if (p->dma_read(CLNK_CTRL2, ch) & (1 << 15))
dma_chan[dma_chan[ch].next_linked_ch].state =
DMA_CH_STARTED;
if (dma_linked_lch[chain_id].chain_mode ==
@@ -2232,10 +2170,10 @@ static int omap2_dma_handle_ch(int ch)
if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
OMAP_DMA_CHAIN_INCQHEAD(chain_id);
- status = dma_read(CSR2, ch);
+ status = p->dma_read(CSR2, ch);
}
- dma_write(status, CSR2, ch);
+ p->dma_write(status, CSR2, ch);
if (likely(dma_chan[ch].callback != NULL))
dma_chan[ch].callback(ch, status, dma_chan[ch].data);
@@ -2249,13 +2187,13 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
u32 val, enable_reg;
int i;
- val = dma_read(IRQSTATUS_L0, 0);
+ val = p->dma_read(IRQSTATUS_L0, 0);
if (val == 0) {
if (printk_ratelimit())
printk(KERN_WARNING "Spurious DMA IRQ\n");
return IRQ_HANDLED;
}
- enable_reg = dma_read(IRQENABLE_L0, 0);
+ enable_reg = p->dma_read(IRQENABLE_L0, 0);
val &= enable_reg; /* Dispatch only relevant interrupts */
for (i = 0; i < dma_lch_count && val != 0; i++) {
if (val & 1)
@@ -2281,20 +2219,20 @@ static struct irqaction omap24xx_dma_irq;
void omap_dma_global_context_save(void)
{
omap_dma_global_context.dma_irqenable_l0 =
- dma_read(IRQENABLE_L0, 0);
+ p->dma_read(IRQENABLE_L0, 0);
omap_dma_global_context.dma_ocp_sysconfig =
- dma_read(OCP_SYSCONFIG, 0);
- omap_dma_global_context.dma_gcr = dma_read(GCR2, 0);
+ p->dma_read(OCP_SYSCONFIG, 0);
+ omap_dma_global_context.dma_gcr = p->dma_read(GCR2, 0);
}
void omap_dma_global_context_restore(void)
{
int ch;
- dma_write(omap_dma_global_context.dma_gcr, GCR2, 0);
- dma_write(omap_dma_global_context.dma_ocp_sysconfig,
+ p->dma_write(omap_dma_global_context.dma_gcr, GCR2, 0);
+ p->dma_write(omap_dma_global_context.dma_ocp_sysconfig,
OCP_SYSCONFIG, 0);
- dma_write(omap_dma_global_context.dma_irqenable_l0,
+ p->dma_write(omap_dma_global_context.dma_irqenable_l0,
IRQENABLE_L0, 0);
/*
@@ -2304,166 +2242,66 @@ void omap_dma_global_context_restore(void)
* affects only secure devices.
*/
if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
- dma_write(0x3 , IRQSTATUS_L0, 0);
+ p->dma_write(0x3 , IRQSTATUS_L0, 0);
for (ch = 0; ch < dma_chan_count; ch++)
if (dma_chan[ch].dev_id != -1)
omap_clear_dma(ch);
}
-static void configure_dma_errata(void)
+static int __devinit omap_system_dma_probe(struct platform_device *pdev)
{
-
- /*
- * Erratas applicable for OMAP2430ES1.0 and all omap2420
- *
- * I.
- * Errata ID: XX Inter Frame DMA buffering issue DMA will wrongly
- * buffer elements if packing and bursting is enabled. This might
- * result in data gets stalled in FIFO at the end of the block.
- * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
- * guarantee no data will stay in the DMA FIFO in case inter frame
- * buffering occurs
- *
- * II.
- * Errata ID: XX DMA may hang when several channels are used in parallel
- * In the following configuration, DMA channel hanging can occur:
- * a. Channel i, hardware synchronized, is enabled
- * b. Another channel (Channel x), software synchronized, is enabled.
- * c. Channel i is disabled before end of transfer
- * d. Channel i is reenabled.
- * e. Steps 1 to 4 are repeated a certain number of times.
- * f. A third channel (Channel y), software synchronized, is enabled.
- * Channel x and Channel y may hang immediately after step 'f'.
- * Workaround:
- * For any channel used - make sure NextLCH_ID is set to the value j.
- */
- if (cpu_is_omap2420() || (cpu_is_omap2430() &&
- (omap_type() == OMAP2430_REV_ES1_0))) {
-
- SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
- SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
+ struct omap_system_dma_plat_info *pdata = pdev->dev.platform_data;
+ struct resource *mem;
+ int ch, ret = 0;
+ int dma_irq;
+ char irq_name[4];
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: System DMA initialized without"
+ "platform data\n", __func__);
+ return -EINVAL;
}
- /*
- * Errata ID: i378: OMAP2plus: sDMA Channel is not disabled
- * after a transaction error.
- * Workaround: SW should explicitely disable the channel.
- */
- if (cpu_class_is_omap2())
- SET_DMA_ERRATA(DMA_ERRATA_i378);
-
- /*
- * Errata ID: i541: sDMA FIFO draining does not finish
- * If sDMA channel is disabled on the fly, sDMA enters standby even
- * through FIFO Drain is still in progress
- * Workaround: Put sDMA in NoStandby more before a logical channel is
- * disabled, then put it back to SmartStandby right after the channel
- * finishes FIFO draining.
- */
- if (cpu_is_omap34xx())
- SET_DMA_ERRATA(DMA_ERRATA_i541);
+ p = pdata;
+ d = p->dma_attr;
+ reg_map = pdata->regs;
+ errata = p->errata;
- /*
- * Errata ID: i88 : Special programming model needed to disable DMA
- * before end of block.
- * Workaround: software must ensure that the DMA is configured in No
- * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
- */
- if (omap_type() == OMAP3430_REV_ES1_0)
- SET_DMA_ERRATA(DMA_ERRATA_i88);
-
- /*
- * Errata 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
- * read before the DMA controller finished disabling the channel.
- */
- if (!cpu_is_omap15xx())
- SET_DMA_ERRATA(DMA_ERRATA_3_3);
-}
-
-/*----------------------------------------------------------------------------*/
-
-static int __init omap_init_dma(void)
-{
- unsigned long base;
- int ch, r;
-
- if (cpu_class_is_omap1()) {
- base = OMAP1_DMA_BASE;
- dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap24xx()) {
- base = OMAP24XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap34xx()) {
- base = OMAP34XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else if (cpu_is_omap44xx()) {
- base = OMAP44XX_DMA4_BASE;
- dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
- } else {
- pr_err("DMA init failed for unsupported omap\n");
- return -ENODEV;
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
+ return -EINVAL;
}
- dma_base = ioremap(base, SZ_4K);
- BUG_ON(!dma_base);
+ dma_base = ioremap(mem->start, resource_size(mem));
+ if (!dma_base) {
+ dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
+ ret = -ENOMEM;
+ goto exit_release_region;
+ }
if (cpu_class_is_omap2() && omap_dma_reserve_channels
&& (omap_dma_reserve_channels <= dma_lch_count))
- dma_lch_count = omap_dma_reserve_channels;
+ d->lch_count = omap_dma_reserve_channels;
- dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
- GFP_KERNEL);
- if (!dma_chan) {
- r = -ENOMEM;
- goto out_unmap;
- }
+ dma_lch_count = d->lch_count;
+ dma_chan_count = dma_lch_count;
+ dma_chan = d->chan;
if (cpu_class_is_omap2()) {
dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
dma_lch_count, GFP_KERNEL);
if (!dma_linked_lch) {
- r = -ENOMEM;
- goto out_free;
+ ret = -ENOMEM;
+ goto exit_dma_chan;
}
}
+ enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
- if (cpu_is_omap15xx()) {
- printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
- dma_chan_count = 9;
- enable_1510_mode = 1;
- } else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
- printk(KERN_INFO "OMAP DMA hardware version %d\n",
- dma_read(HW_ID, 0));
- printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
- (dma_read(CAPS1_0_U, 0) << 16) |
- dma_read(CAPS1_0_L, 0),
- (dma_read(CAPS1_1_U, 0) << 16) |
- dma_read(CAPS1_1_L, 0),
- dma_read(CAPS1_2, 0), dma_read(CAPS1_3, 0),
- dma_read(CAPS1_4, 0));
- if (!enable_1510_mode) {
- u16 w;
-
- /* Disable OMAP 3.0/3.1 compatibility mode. */
- w = dma_read(GSCR, 0);
- w |= 1 << 3;
- dma_write(w, GSCR, 0);
- dma_chan_count = 16;
- } else
- dma_chan_count = 9;
- } else if (cpu_class_is_omap2()) {
- u8 revision = dma_read(REVISION, 0) & 0xff;
- printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
- revision >> 4, revision & 0xf);
- dma_chan_count = dma_lch_count;
- } else {
- dma_chan_count = 0;
- return 0;
- }
+ p->show_dma_caps();
spin_lock_init(&dma_chan_lock);
-
for (ch = 0; ch < dma_chan_count; ch++) {
omap_clear_dma(ch);
if (cpu_class_is_omap2())
@@ -2480,19 +2318,30 @@ static int __init omap_init_dma(void)
* request_irq() doesn't like dev_id (ie. ch) being
* zero, so we have to kludge around this.
*/
- r = request_irq(omap1_dma_irq[ch],
+ sprintf(&irq_name[0], "%d", ch);
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+
+ if (dma_irq < 0) {
+ dev_err(&pdev->dev, "%s:unable to get irq\n",
+ __func__);
+ ret = dma_irq;
+ goto exit_unmap;
+ }
+ ret = request_irq(dma_irq,
omap1_dma_irq_handler, 0, "DMA",
(void *) (ch + 1));
- if (r != 0) {
- int i;
-
- printk(KERN_ERR "unable to request IRQ %d "
- "for DMA (error %d)\n",
- omap1_dma_irq[ch], r);
- for (i = 0; i < ch; i++)
- free_irq(omap1_dma_irq[i],
- (void *) (i + 1));
- goto out_free;
+ if (ret != 0) {
+ int irq_rel;
+ dev_err(&pdev->dev, "unable to request IRQ %d"
+ "for DMA (error %d)\n", dma_irq, ret);
+ for (irq_rel = 0; irq_rel < ch;
+ irq_rel++) {
+ dma_irq = platform_get_irq(pdev,
+ irq_rel);
+ free_irq(dma_irq, (void *)
+ (irq_rel + 1));
+ goto exit_dma_chan;
+ }
}
}
}
@@ -2502,49 +2351,62 @@ static int __init omap_init_dma(void)
DMA_DEFAULT_FIFO_DEPTH, 0);
if (cpu_class_is_omap2()) {
- int irq;
- if (cpu_is_omap44xx())
- irq = OMAP44XX_IRQ_SDMA_0;
- else
- irq = INT_24XX_SDMA_IRQ0;
- setup_irq(irq, &omap24xx_dma_irq);
- }
-
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- /* Enable smartidle idlemodes and autoidle */
- u32 v = dma_read(OCP_SYSCONFIG, 0);
- v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
- DMA_SYSCONFIG_SIDLEMODE_MASK |
- DMA_SYSCONFIG_AUTOIDLE);
- v |= (DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
- DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
- DMA_SYSCONFIG_AUTOIDLE);
- dma_write(v , OCP_SYSCONFIG, 0);
- /* reserve dma channels 0 and 1 in high security devices */
- if (cpu_is_omap34xx() &&
- (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
- printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
- "HS ROM code\n");
- dma_chan[0].dev_id = 0;
- dma_chan[1].dev_id = 1;
- }
+ strcpy(irq_name, "0");
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+ setup_irq(dma_irq, &omap24xx_dma_irq);
}
- /* Configure errata handling for all omap's */
- configure_dma_errata();
-
+ /* reserve dma channels 0 and 1 in high security devices */
+ if (cpu_is_omap34xx() &&
+ (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
+ printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
+ "HS ROM code\n");
+ dma_chan[0].dev_id = 0;
+ dma_chan[1].dev_id = 1;
+ }
return 0;
-out_free:
+exit_dma_chan:
kfree(dma_chan);
+exit_unmap:
+ iounmap(dma_base);
+exit_release_region:
+ release_mem_region(mem->start, resource_size(mem));
+ return ret;
+}
-out_unmap:
+static int __devexit omap_system_dma_remove(struct platform_device *pdev)
+{
+ struct resource *mem;
iounmap(dma_base);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+ return 0;
+}
+
+static struct platform_driver omap_system_dma_driver = {
+ .probe = omap_system_dma_probe,
+ .remove = omap_system_dma_remove,
+ .driver = {
+ .name = "omap_dma_system"
+ },
+};
- return r;
+static int __init omap_system_dma_init(void)
+{
+ return platform_driver_register(&omap_system_dma_driver);
+}
+arch_initcall(omap_system_dma_init);
+
+static void __exit omap_system_dma_exit(void)
+{
+ platform_driver_unregister(&omap_system_dma_driver);
}
-arch_initcall(omap_init_dma);
+MODULE_DESCRIPTION("OMAP SYSTEM DMA DRIVER");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
/*
* Reserve the omap SDMA channels using cmdline bootarg
@@ -21,21 +21,15 @@
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
-/* Move omap4 specific defines to dma-44xx.h */
-#include "dma-44xx.h"
-
-/* Hardware registers for omap1 */
-#define OMAP1_DMA_BASE (0xfffed800)
-
-/* Hardware registers for omap2 and omap3 */
-#define OMAP24XX_DMA4_BASE (L4_24XX_BASE + 0x56000)
-#define OMAP34XX_DMA4_BASE (L4_34XX_BASE + 0x56000)
-#define OMAP44XX_DMA4_BASE (L4_44XX_BASE + 0x56000)
+#include <linux/platform_device.h>
-#define OMAP1_LOGICAL_DMA_CH_COUNT 17
-#define OMAP_DMA4_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */
+/*
+ * TODO: These dma channel defines should go away once all
+ * the omap drivers hwmod adapted.
+ */
-/*----------------------------------------------------------------------------*/
+/* Move omap4 specific defines to dma-44xx.h */
+#include "dma-44xx.h"
/* DMA channels for omap1 */
#define OMAP_DMA_NO_DEVICE 0
@@ -377,9 +371,41 @@ struct omap_dma_channel_params {
#endif
};
+#include <mach/dma.h>
+struct omap_dma_lch {
+ int next_lch;
+ int dev_id;
+ u16 saved_csr;
+ u16 enabled_irqs;
+ const char *dev_name;
+ void (*callback)(int lch, u16 ch_status, void *data);
+ void *data;
+ long flags;
+ /* required for Dynamic chaining */
+ int prev_linked_ch;
+ int next_linked_ch;
+ int state;
+ int chain_id;
+ int status;
+};
+
struct omap_dma_dev_attr {
u32 dev_caps;
u16 lch_count;
+ u16 chan_count;
+ struct omap_dma_lch *chan;
+};
+
+/* System DMA platform data structure */
+struct omap_system_dma_plat_info {
+ struct omap_dma_dev_attr *dma_attr;
+ void __iomem *omap_dma_base;
+ u32 errata;
+ u16 *regs;
+ void (*disable_irq_lch)(int lch);
+ void (*show_dma_caps)(void);
+ void (*dma_write)(u32 val, int reg, int lch);
+ u32 (*dma_read)(int reg, int lch);
};
extern void omap_set_dma_priority(int lch, int dst_port, int priority);