1 /*
2 * Copyright (C) 2010 Pengutronix
3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 */
9 #include <linux/compiler.h>
10 #include <linux/err.h>
11 #include <linux/init.h>
12
13 #include <mach/hardware.h>
14 #include <mach/devices-common.h>
15 #include <mach/sdma.h>
16
17 struct imx_imx_sdma_data {
18 resource_size_t iobase;
19 resource_size_t irq;
20 struct sdma_platform_data pdata;
21 };
22
23 #define imx_imx_sdma_data_entry_single(soc, _sdma_version, _cpu_name, _to_version)\
24 { \
25 .iobase = soc ## _SDMA ## _BASE_ADDR, \
26 .irq = soc ## _INT_SDMA, \
27 .pdata = { \
28 .sdma_version = _sdma_version, \
29 .cpu_name = _cpu_name, \
30 .to_version = _to_version, \
31 }, \
32 }
33
34 #ifdef CONFIG_SOC_IMX25
35 struct imx_imx_sdma_data imx25_imx_sdma_data __initconst =
36 imx_imx_sdma_data_entry_single(MX25, 1, "imx25", 0);
37 #endif /* ifdef CONFIG_SOC_IMX25 */
38
39 #ifdef CONFIG_SOC_IMX31
40 struct imx_imx_sdma_data imx31_imx_sdma_data __initdata =
41 imx_imx_sdma_data_entry_single(MX31, 1, "imx31", 0);
42 #endif /* ifdef CONFIG_SOC_IMX31 */
43
44 #ifdef CONFIG_SOC_IMX35
45 struct imx_imx_sdma_data imx35_imx_sdma_data __initdata =
46 imx_imx_sdma_data_entry_single(MX35, 2, "imx35", 0);
47 #endif /* ifdef CONFIG_SOC_IMX35 */
48
49 #ifdef CONFIG_SOC_IMX51
50 struct imx_imx_sdma_data imx51_imx_sdma_data __initconst =
51 imx_imx_sdma_data_entry_single(MX51, 2, "imx51", 0);
52 #endif /* ifdef CONFIG_SOC_IMX51 */
53
imx_add_imx_sdma(const struct imx_imx_sdma_data * data)54 static struct platform_device __init __maybe_unused *imx_add_imx_sdma(
55 const struct imx_imx_sdma_data *data)
56 {
57 struct resource res[] = {
58 {
59 .start = data->iobase,
60 .end = data->iobase + SZ_4K - 1,
61 .flags = IORESOURCE_MEM,
62 }, {
63 .start = data->irq,
64 .end = data->irq,
65 .flags = IORESOURCE_IRQ,
66 },
67 };
68
69 return imx_add_platform_device("imx-sdma", -1,
70 res, ARRAY_SIZE(res),
71 &data->pdata, sizeof(data->pdata));
72 }
73
imx_add_imx_dma(void)74 static struct platform_device __init __maybe_unused *imx_add_imx_dma(void)
75 {
76 return imx_add_platform_device("imx-dma", -1, NULL, 0, NULL, 0);
77 }
78
79 #ifdef CONFIG_ARCH_MX25
80 static struct sdma_script_start_addrs addr_imx25_to1 = {
81 .ap_2_ap_addr = 729,
82 .uart_2_mcu_addr = 904,
83 .per_2_app_addr = 1255,
84 .mcu_2_app_addr = 834,
85 .uartsh_2_mcu_addr = 1120,
86 .per_2_shp_addr = 1329,
87 .mcu_2_shp_addr = 1048,
88 .ata_2_mcu_addr = 1560,
89 .mcu_2_ata_addr = 1479,
90 .app_2_per_addr = 1189,
91 .app_2_mcu_addr = 770,
92 .shp_2_per_addr = 1407,
93 .shp_2_mcu_addr = 979,
94 };
95 #endif
96
97 #ifdef CONFIG_SOC_IMX31
98 static struct sdma_script_start_addrs addr_imx31_to1 = {
99 .per_2_per_addr = 1677,
100 };
101
102 static struct sdma_script_start_addrs addr_imx31_to2 = {
103 .ap_2_ap_addr = 423,
104 .ap_2_bp_addr = 829,
105 .bp_2_ap_addr = 1029,
106 };
107 #endif
108
109 #ifdef CONFIG_SOC_IMX35
110 static struct sdma_script_start_addrs addr_imx35_to1 = {
111 .ap_2_ap_addr = 642,
112 .uart_2_mcu_addr = 817,
113 .mcu_2_app_addr = 747,
114 .uartsh_2_mcu_addr = 1183,
115 .per_2_shp_addr = 1033,
116 .mcu_2_shp_addr = 961,
117 .ata_2_mcu_addr = 1333,
118 .mcu_2_ata_addr = 1252,
119 .app_2_mcu_addr = 683,
120 .shp_2_per_addr = 1111,
121 .shp_2_mcu_addr = 892,
122 };
123
124 static struct sdma_script_start_addrs addr_imx35_to2 = {
125 .ap_2_ap_addr = 729,
126 .uart_2_mcu_addr = 904,
127 .per_2_app_addr = 1597,
128 .mcu_2_app_addr = 834,
129 .uartsh_2_mcu_addr = 1270,
130 .per_2_shp_addr = 1120,
131 .mcu_2_shp_addr = 1048,
132 .ata_2_mcu_addr = 1429,
133 .mcu_2_ata_addr = 1339,
134 .app_2_per_addr = 1531,
135 .app_2_mcu_addr = 770,
136 .shp_2_per_addr = 1198,
137 .shp_2_mcu_addr = 979,
138 };
139 #endif
140
141 #ifdef CONFIG_SOC_IMX51
142 static struct sdma_script_start_addrs addr_imx51_to1 = {
143 .ap_2_ap_addr = 642,
144 .uart_2_mcu_addr = 817,
145 .mcu_2_app_addr = 747,
146 .mcu_2_shp_addr = 961,
147 .ata_2_mcu_addr = 1473,
148 .mcu_2_ata_addr = 1392,
149 .app_2_per_addr = 1033,
150 .app_2_mcu_addr = 683,
151 .shp_2_per_addr = 1251,
152 .shp_2_mcu_addr = 892,
153 };
154 #endif
155
imxXX_add_imx_dma(void)156 static int __init imxXX_add_imx_dma(void)
157 {
158 struct platform_device *ret;
159
160 #if defined(CONFIG_SOC_IMX21) || defined(CONFIG_SOC_IMX27)
161 if (cpu_is_mx21() || cpu_is_mx27())
162 ret = imx_add_imx_dma();
163 else
164 #endif
165
166 #if defined(CONFIG_SOC_IMX25)
167 if (cpu_is_mx25()) {
168 imx25_imx_sdma_data.pdata.script_addrs = &addr_imx25_to1;
169 ret = imx_add_imx_sdma(&imx25_imx_sdma_data);
170 } else
171 #endif
172
173 #if defined(CONFIG_SOC_IMX31)
174 if (cpu_is_mx31()) {
175 int to_version = mx31_revision() >> 4;
176 imx31_imx_sdma_data.pdata.to_version = to_version;
177 if (to_version == 1)
178 imx31_imx_sdma_data.pdata.script_addrs = &addr_imx31_to1;
179 else
180 imx31_imx_sdma_data.pdata.script_addrs = &addr_imx31_to2;
181 ret = imx_add_imx_sdma(&imx31_imx_sdma_data);
182 } else
183 #endif
184
185 #if defined(CONFIG_SOC_IMX35)
186 if (cpu_is_mx35()) {
187 int to_version = mx35_revision() >> 4;
188 imx35_imx_sdma_data.pdata.to_version = to_version;
189 if (to_version == 1)
190 imx35_imx_sdma_data.pdata.script_addrs = &addr_imx35_to1;
191 else
192 imx35_imx_sdma_data.pdata.script_addrs = &addr_imx35_to2;
193 ret = imx_add_imx_sdma(&imx35_imx_sdma_data);
194 } else
195 #endif
196
197 #if defined(CONFIG_SOC_IMX51)
198 if (cpu_is_mx51()) {
199 imx51_imx_sdma_data.pdata.script_addrs = &addr_imx51_to1;
200 ret = imx_add_imx_sdma(&imx51_imx_sdma_data);
201 } else
202 #endif
203 ret = ERR_PTR(-ENODEV);
204
205 if (IS_ERR(ret))
206 return PTR_ERR(ret);
207
208 return 0;
209 }
210 arch_initcall(imxXX_add_imx_dma);
211