0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/err.h>
0022 #include <linux/io.h>
0023 #include <linux/slab.h>
0024 #include <linux/module.h>
0025 #include <linux/init.h>
0026 #include <linux/device.h>
0027 #include <linux/dma-mapping.h>
0028 #include <linux/dmaengine.h>
0029 #include <linux/of.h>
0030 #include <linux/omap-dma.h>
0031
0032 #include "soc.h"
0033 #include "common.h"
0034
0035 static const struct omap_dma_reg reg_map[] = {
0036 [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT },
0037 [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT },
0038 [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT },
0039 [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT },
0040 [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT },
0041 [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT },
0042 [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT },
0043 [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT },
0044 [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT },
0045 [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT },
0046 [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT },
0047 [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT },
0048 [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT },
0049 [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT },
0050 [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT },
0051 [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT },
0052
0053
0054 [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT },
0055 [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT },
0056 [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT },
0057 [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT },
0058 [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT },
0059 [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT },
0060 [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT },
0061 [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT },
0062 [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT },
0063 [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT },
0064 [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT },
0065 [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT },
0066 [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT },
0067
0068
0069 [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT },
0070 [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT },
0071 [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT },
0072 [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT },
0073 [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT },
0074
0075
0076 [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT },
0077 [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT },
0078 [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT },
0079 };
0080
0081 static unsigned configure_dma_errata(void)
0082 {
0083 unsigned errata = 0;
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 if (cpu_is_omap2420() || (cpu_is_omap2430() &&
0112 (omap_type() == OMAP2430_REV_ES1_0))) {
0113
0114 SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
0115 SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
0116 }
0117
0118
0119
0120
0121
0122
0123 if (cpu_class_is_omap2())
0124 SET_DMA_ERRATA(DMA_ERRATA_i378);
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 if (cpu_is_omap34xx())
0135 SET_DMA_ERRATA(DMA_ERRATA_i541);
0136
0137
0138
0139
0140
0141
0142
0143 if (omap_type() == OMAP3430_REV_ES1_0)
0144 SET_DMA_ERRATA(DMA_ERRATA_i88);
0145
0146
0147
0148
0149
0150 SET_DMA_ERRATA(DMA_ERRATA_3_3);
0151
0152
0153
0154
0155
0156
0157
0158
0159 if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
0160 SET_DMA_ERRATA(DMA_ROMCODE_BUG);
0161
0162 return errata;
0163 }
0164
0165 static const struct dma_slave_map omap24xx_sdma_dt_map[] = {
0166
0167 { "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) },
0168 { "musb-hdrc.1.auto", "dmareq1", SDMA_FILTER_PARAM(3) },
0169 { "musb-hdrc.1.auto", "dmareq2", SDMA_FILTER_PARAM(14) },
0170 { "musb-hdrc.1.auto", "dmareq3", SDMA_FILTER_PARAM(15) },
0171 { "musb-hdrc.1.auto", "dmareq4", SDMA_FILTER_PARAM(16) },
0172 { "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) },
0173 };
0174
0175 static struct omap_dma_dev_attr dma_attr = {
0176 .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
0177 IS_CSSA_32 | IS_CDSA_32,
0178 .lch_count = 32,
0179 };
0180
0181 struct omap_system_dma_plat_info dma_plat_info = {
0182 .reg_map = reg_map,
0183 .channel_stride = 0x60,
0184 .dma_attr = &dma_attr,
0185 };
0186
0187
0188 static int __init omap2_system_dma_init(void)
0189 {
0190 dma_plat_info.errata = configure_dma_errata();
0191
0192 if (soc_is_omap24xx()) {
0193
0194 dma_plat_info.slave_map = omap24xx_sdma_dt_map;
0195 dma_plat_info.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map);
0196 }
0197
0198 if (!soc_is_omap242x())
0199 dma_attr.dev_caps |= IS_RW_PRIORITY;
0200
0201 if (soc_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
0202 dma_attr.dev_caps |= HS_CHANNELS_RESERVED;
0203
0204 return 0;
0205 }
0206 omap_arch_initcall(omap2_system_dma_init);