diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-04-14 10:44:42 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-04-14 10:44:42 -0400 |
commit | 740c699a8d316c8bf8593f19e2ca47795e690622 (patch) | |
tree | a78886955770a477945c5d84e06b2e7678733b54 /arch/arm/mach-omap2/dma.c | |
parent | e69af4657e7764d03ad555f0b583d9c4217bcefa (diff) | |
parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff) |
Merge tag 'v3.15-rc1' into perf/urgent
Pick up the latest fixes.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/arm/mach-omap2/dma.c')
-rw-r--r-- | arch/arm/mach-omap2/dma.c | 183 |
1 files changed, 78 insertions, 105 deletions
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 49fd0d501c9b..5689c88d986d 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c | |||
@@ -35,97 +35,80 @@ | |||
35 | #include "omap_hwmod.h" | 35 | #include "omap_hwmod.h" |
36 | #include "omap_device.h" | 36 | #include "omap_device.h" |
37 | 37 | ||
38 | #define OMAP2_DMA_STRIDE 0x60 | 38 | static enum omap_reg_offsets dma_common_ch_end; |
39 | 39 | ||
40 | static u32 errata; | 40 | static const struct omap_dma_reg reg_map[] = { |
41 | static u8 dma_stride; | 41 | [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT }, |
42 | 42 | [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT }, | |
43 | static struct omap_dma_dev_attr *d; | 43 | [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT }, |
44 | 44 | [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT }, | |
45 | static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end; | 45 | [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT }, |
46 | 46 | [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT }, | |
47 | static u16 reg_map[] = { | 47 | [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT }, |
48 | [REVISION] = 0x00, | 48 | [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT }, |
49 | [GCR] = 0x78, | 49 | [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT }, |
50 | [IRQSTATUS_L0] = 0x08, | 50 | [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT }, |
51 | [IRQSTATUS_L1] = 0x0c, | 51 | [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT }, |
52 | [IRQSTATUS_L2] = 0x10, | 52 | [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT }, |
53 | [IRQSTATUS_L3] = 0x14, | 53 | [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT }, |
54 | [IRQENABLE_L0] = 0x18, | 54 | [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT }, |
55 | [IRQENABLE_L1] = 0x1c, | 55 | [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT }, |
56 | [IRQENABLE_L2] = 0x20, | 56 | [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT }, |
57 | [IRQENABLE_L3] = 0x24, | ||
58 | [SYSSTATUS] = 0x28, | ||
59 | [OCP_SYSCONFIG] = 0x2c, | ||
60 | [CAPS_0] = 0x64, | ||
61 | [CAPS_2] = 0x6c, | ||
62 | [CAPS_3] = 0x70, | ||
63 | [CAPS_4] = 0x74, | ||
64 | 57 | ||
65 | /* Common register offsets */ | 58 | /* Common register offsets */ |
66 | [CCR] = 0x80, | 59 | [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT }, |
67 | [CLNK_CTRL] = 0x84, | 60 | [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT }, |
68 | [CICR] = 0x88, | 61 | [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT }, |
69 | [CSR] = 0x8c, | 62 | [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT }, |
70 | [CSDP] = 0x90, | 63 | [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT }, |
71 | [CEN] = 0x94, | 64 | [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT }, |
72 | [CFN] = 0x98, | 65 | [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT }, |
73 | [CSEI] = 0xa4, | 66 | [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT }, |
74 | [CSFI] = 0xa8, | 67 | [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT }, |
75 | [CDEI] = 0xac, | 68 | [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT }, |
76 | [CDFI] = 0xb0, | 69 | [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT }, |
77 | [CSAC] = 0xb4, | 70 | [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT }, |
78 | [CDAC] = 0xb8, | 71 | [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT }, |
79 | 72 | ||
80 | /* Channel specific register offsets */ | 73 | /* Channel specific register offsets */ |
81 | [CSSA] = 0x9c, | 74 | [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT }, |
82 | [CDSA] = 0xa0, | 75 | [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT }, |
83 | [CCEN] = 0xbc, | 76 | [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT }, |
84 | [CCFN] = 0xc0, | 77 | [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT }, |
85 | [COLOR] = 0xc4, | 78 | [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT }, |
86 | 79 | ||
87 | /* OMAP4 specific registers */ | 80 | /* OMAP4 specific registers */ |
88 | [CDP] = 0xd0, | 81 | [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT }, |
89 | [CNDP] = 0xd4, | 82 | [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT }, |
90 | [CCDN] = 0xd8, | 83 | [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT }, |
91 | }; | 84 | }; |
92 | 85 | ||
93 | static void __iomem *dma_base; | 86 | static void __iomem *dma_base; |
94 | static inline void dma_write(u32 val, int reg, int lch) | 87 | static inline void dma_write(u32 val, int reg, int lch) |
95 | { | 88 | { |
96 | u8 stride; | 89 | void __iomem *addr = dma_base; |
97 | u32 offset; | ||
98 | 90 | ||
99 | stride = (reg >= dma_common_ch_start) ? dma_stride : 0; | 91 | addr += reg_map[reg].offset; |
100 | offset = reg_map[reg] + (stride * lch); | 92 | addr += reg_map[reg].stride * lch; |
101 | __raw_writel(val, dma_base + offset); | 93 | |
94 | __raw_writel(val, addr); | ||
102 | } | 95 | } |
103 | 96 | ||
104 | static inline u32 dma_read(int reg, int lch) | 97 | static inline u32 dma_read(int reg, int lch) |
105 | { | 98 | { |
106 | u8 stride; | 99 | void __iomem *addr = dma_base; |
107 | u32 offset, val; | ||
108 | |||
109 | stride = (reg >= dma_common_ch_start) ? dma_stride : 0; | ||
110 | offset = reg_map[reg] + (stride * lch); | ||
111 | val = __raw_readl(dma_base + offset); | ||
112 | return val; | ||
113 | } | ||
114 | 100 | ||
115 | static inline void omap2_disable_irq_lch(int lch) | 101 | addr += reg_map[reg].offset; |
116 | { | 102 | addr += reg_map[reg].stride * lch; |
117 | u32 val; | ||
118 | 103 | ||
119 | val = dma_read(IRQENABLE_L0, lch); | 104 | return __raw_readl(addr); |
120 | val &= ~(1 << lch); | ||
121 | dma_write(val, IRQENABLE_L0, lch); | ||
122 | } | 105 | } |
123 | 106 | ||
124 | static void omap2_clear_dma(int lch) | 107 | static void omap2_clear_dma(int lch) |
125 | { | 108 | { |
126 | int i = dma_common_ch_start; | 109 | int i; |
127 | 110 | ||
128 | for (; i <= dma_common_ch_end; i += 1) | 111 | for (i = CSDP; i <= dma_common_ch_end; i += 1) |
129 | dma_write(0, i, lch); | 112 | dma_write(0, i, lch); |
130 | } | 113 | } |
131 | 114 | ||
@@ -137,8 +120,9 @@ static void omap2_show_dma_caps(void) | |||
137 | return; | 120 | return; |
138 | } | 121 | } |
139 | 122 | ||
140 | static u32 configure_dma_errata(void) | 123 | static unsigned configure_dma_errata(void) |
141 | { | 124 | { |
125 | unsigned errata = 0; | ||
142 | 126 | ||
143 | /* | 127 | /* |
144 | * Errata applicable for OMAP2430ES1.0 and all omap2420 | 128 | * Errata applicable for OMAP2430ES1.0 and all omap2420 |
@@ -220,48 +204,50 @@ static u32 configure_dma_errata(void) | |||
220 | return errata; | 204 | return errata; |
221 | } | 205 | } |
222 | 206 | ||
207 | static struct omap_system_dma_plat_info dma_plat_info __initdata = { | ||
208 | .reg_map = reg_map, | ||
209 | .channel_stride = 0x60, | ||
210 | .show_dma_caps = omap2_show_dma_caps, | ||
211 | .clear_dma = omap2_clear_dma, | ||
212 | .dma_write = dma_write, | ||
213 | .dma_read = dma_read, | ||
214 | }; | ||
215 | |||
216 | static struct platform_device_info omap_dma_dev_info = { | ||
217 | .name = "omap-dma-engine", | ||
218 | .id = -1, | ||
219 | .dma_mask = DMA_BIT_MASK(32), | ||
220 | }; | ||
221 | |||
223 | /* One time initializations */ | 222 | /* One time initializations */ |
224 | static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) | 223 | static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) |
225 | { | 224 | { |
226 | struct platform_device *pdev; | 225 | struct platform_device *pdev; |
227 | struct omap_system_dma_plat_info *p; | 226 | struct omap_system_dma_plat_info p; |
227 | struct omap_dma_dev_attr *d; | ||
228 | struct resource *mem; | 228 | struct resource *mem; |
229 | char *name = "omap_dma_system"; | 229 | char *name = "omap_dma_system"; |
230 | 230 | ||
231 | dma_stride = OMAP2_DMA_STRIDE; | 231 | p = dma_plat_info; |
232 | dma_common_ch_start = CSDP; | 232 | p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; |
233 | 233 | p.errata = configure_dma_errata(); | |
234 | p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL); | ||
235 | if (!p) { | ||
236 | pr_err("%s: Unable to allocate pdata for %s:%s\n", | ||
237 | __func__, name, oh->name); | ||
238 | return -ENOMEM; | ||
239 | } | ||
240 | |||
241 | p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; | ||
242 | p->disable_irq_lch = omap2_disable_irq_lch; | ||
243 | p->show_dma_caps = omap2_show_dma_caps; | ||
244 | p->clear_dma = omap2_clear_dma; | ||
245 | p->dma_write = dma_write; | ||
246 | p->dma_read = dma_read; | ||
247 | |||
248 | p->clear_lch_regs = NULL; | ||
249 | |||
250 | p->errata = configure_dma_errata(); | ||
251 | 234 | ||
252 | pdev = omap_device_build(name, 0, oh, p, sizeof(*p)); | 235 | pdev = omap_device_build(name, 0, oh, &p, sizeof(p)); |
253 | kfree(p); | ||
254 | if (IS_ERR(pdev)) { | 236 | if (IS_ERR(pdev)) { |
255 | pr_err("%s: Can't build omap_device for %s:%s.\n", | 237 | pr_err("%s: Can't build omap_device for %s:%s.\n", |
256 | __func__, name, oh->name); | 238 | __func__, name, oh->name); |
257 | return PTR_ERR(pdev); | 239 | return PTR_ERR(pdev); |
258 | } | 240 | } |
259 | 241 | ||
242 | omap_dma_dev_info.res = pdev->resource; | ||
243 | omap_dma_dev_info.num_res = pdev->num_resources; | ||
244 | |||
260 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 245 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
261 | if (!mem) { | 246 | if (!mem) { |
262 | dev_err(&pdev->dev, "%s: no mem resource\n", __func__); | 247 | dev_err(&pdev->dev, "%s: no mem resource\n", __func__); |
263 | return -EINVAL; | 248 | return -EINVAL; |
264 | } | 249 | } |
250 | |||
265 | dma_base = ioremap(mem->start, resource_size(mem)); | 251 | dma_base = ioremap(mem->start, resource_size(mem)); |
266 | if (!dma_base) { | 252 | if (!dma_base) { |
267 | dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); | 253 | dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); |
@@ -269,13 +255,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) | |||
269 | } | 255 | } |
270 | 256 | ||
271 | d = oh->dev_attr; | 257 | d = oh->dev_attr; |
272 | d->chan = kzalloc(sizeof(struct omap_dma_lch) * | ||
273 | (d->lch_count), GFP_KERNEL); | ||
274 | |||
275 | if (!d->chan) { | ||
276 | dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__); | ||
277 | return -ENOMEM; | ||
278 | } | ||
279 | 258 | ||
280 | if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) | 259 | if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) |
281 | d->dev_caps |= HS_CHANNELS_RESERVED; | 260 | d->dev_caps |= HS_CHANNELS_RESERVED; |
@@ -289,12 +268,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) | |||
289 | return 0; | 268 | return 0; |
290 | } | 269 | } |
291 | 270 | ||
292 | static const struct platform_device_info omap_dma_dev_info = { | ||
293 | .name = "omap-dma-engine", | ||
294 | .id = -1, | ||
295 | .dma_mask = DMA_BIT_MASK(32), | ||
296 | }; | ||
297 | |||
298 | static int __init omap2_system_dma_init(void) | 271 | static int __init omap2_system_dma_init(void) |
299 | { | 272 | { |
300 | struct platform_device *pdev; | 273 | struct platform_device *pdev; |