Merge branch 'for-3.5/drivers' of git://git.kernel.dk/linux-block
[deliverable/linux.git] / arch / arm / mach-exynos / dev-sysmmu.c
1 /* linux/arch/arm/mach-exynos/dev-sysmmu.c
2 *
3 * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS - System MMU support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13 #include <linux/platform_device.h>
14 #include <linux/dma-mapping.h>
15
16 #include <plat/cpu.h>
17
18 #include <mach/map.h>
19 #include <mach/irqs.h>
20 #include <mach/sysmmu.h>
21
22 static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
23
24 #define SYSMMU_PLATFORM_DEVICE(ipname, devid) \
25 static struct sysmmu_platform_data platdata_##ipname = { \
26 .dbgname = #ipname, \
27 }; \
28 struct platform_device SYSMMU_PLATDEV(ipname) = \
29 { \
30 .name = SYSMMU_DEVNAME_BASE, \
31 .id = devid, \
32 .dev = { \
33 .dma_mask = &exynos_sysmmu_dma_mask, \
34 .coherent_dma_mask = DMA_BIT_MASK(32), \
35 .platform_data = &platdata_##ipname, \
36 }, \
37 }
38
39 SYSMMU_PLATFORM_DEVICE(mfc_l, 0);
40 SYSMMU_PLATFORM_DEVICE(mfc_r, 1);
41 SYSMMU_PLATFORM_DEVICE(tv, 2);
42 SYSMMU_PLATFORM_DEVICE(jpeg, 3);
43 SYSMMU_PLATFORM_DEVICE(rot, 4);
44 SYSMMU_PLATFORM_DEVICE(fimc0, 5); /* fimc* and gsc* exist exclusively */
45 SYSMMU_PLATFORM_DEVICE(fimc1, 6);
46 SYSMMU_PLATFORM_DEVICE(fimc2, 7);
47 SYSMMU_PLATFORM_DEVICE(fimc3, 8);
48 SYSMMU_PLATFORM_DEVICE(gsc0, 5);
49 SYSMMU_PLATFORM_DEVICE(gsc1, 6);
50 SYSMMU_PLATFORM_DEVICE(gsc2, 7);
51 SYSMMU_PLATFORM_DEVICE(gsc3, 8);
52 SYSMMU_PLATFORM_DEVICE(isp, 9);
53 SYSMMU_PLATFORM_DEVICE(fimd0, 10);
54 SYSMMU_PLATFORM_DEVICE(fimd1, 11);
55 SYSMMU_PLATFORM_DEVICE(camif0, 12);
56 SYSMMU_PLATFORM_DEVICE(camif1, 13);
57 SYSMMU_PLATFORM_DEVICE(2d, 14);
58
59 #define SYSMMU_RESOURCE_NAME(core, ipname) sysmmures_##core##_##ipname
60
61 #define SYSMMU_RESOURCE(core, ipname) \
62 static struct resource SYSMMU_RESOURCE_NAME(core, ipname)[] __initdata =
63
64 #define DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
65 DEFINE_RES_MEM_NAMED(core##_PA_SYSMMU_##mem, SZ_4K, #mem), \
66 DEFINE_RES_IRQ_NAMED(core##_IRQ_SYSMMU_##irq##_0, #mem)
67
68 #define SYSMMU_RESOURCE_DEFINE(core, ipname, mem, irq) \
69 SYSMMU_RESOURCE(core, ipname) { \
70 DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
71 }
72
73 struct sysmmu_resource_map {
74 struct platform_device *pdev;
75 struct resource *res;
76 u32 rnum;
77 struct device *pdd;
78 char *clocknames;
79 };
80
81 #define SYSMMU_RESOURCE_MAPPING(core, ipname, resname) { \
82 .pdev = &SYSMMU_PLATDEV(ipname), \
83 .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
84 .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
85 .clocknames = SYSMMU_CLOCK_NAME, \
86 }
87
88 #define SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata) { \
89 .pdev = &SYSMMU_PLATDEV(ipname), \
90 .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
91 .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
92 .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
93 }
94
95 #ifdef CONFIG_EXYNOS_DEV_PD
96 #define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) { \
97 .pdev = &SYSMMU_PLATDEV(ipname), \
98 .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
99 .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
100 .clocknames = SYSMMU_CLOCK_NAME, \
101 .pdd = &exynos##core##_device_pd[pd].dev, \
102 }
103
104 #define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) {\
105 .pdev = &SYSMMU_PLATDEV(ipname), \
106 .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
107 .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
108 .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
109 .pdd = &exynos##core##_device_pd[pd].dev, \
110 }
111 #else
112 #define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) \
113 SYSMMU_RESOURCE_MAPPING(core, ipname, resname)
114 #define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) \
115 SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata)
116
117 #endif /* CONFIG_EXYNOS_DEV_PD */
118
119 #ifdef CONFIG_ARCH_EXYNOS4
120 SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc0, FIMC0, FIMC0);
121 SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc1, FIMC1, FIMC1);
122 SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc2, FIMC2, FIMC2);
123 SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc3, FIMC3, FIMC3);
124 SYSMMU_RESOURCE_DEFINE(EXYNOS4, jpeg, JPEG, JPEG);
125 SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d, G2D, 2D);
126 SYSMMU_RESOURCE_DEFINE(EXYNOS4, tv, TV, TV_M0);
127 SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d_acp, 2D_ACP, 2D);
128 SYSMMU_RESOURCE_DEFINE(EXYNOS4, rot, ROTATOR, ROTATOR);
129 SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd0, FIMD0, LCD0_M0);
130 SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd1, FIMD1, LCD1_M1);
131 SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite0, FIMC_LITE0, FIMC_LITE0);
132 SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite1, FIMC_LITE1, FIMC_LITE1);
133 SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_r, MFC_R, MFC_M0);
134 SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_l, MFC_L, MFC_M1);
135 SYSMMU_RESOURCE(EXYNOS4, isp) {
136 DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_ISP, FIMC_ISP),
137 DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_DRC, FIMC_DRC),
138 DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_FD, FIMC_FD),
139 DEFINE_SYSMMU_RESOURCE(EXYNOS4, ISPCPU, FIMC_CX),
140 };
141
142 static struct sysmmu_resource_map sysmmu_resmap4[] __initdata = {
143 SYSMMU_RESOURCE_MAPPING_PD(4, fimc0, fimc0, PD_CAM),
144 SYSMMU_RESOURCE_MAPPING_PD(4, fimc1, fimc1, PD_CAM),
145 SYSMMU_RESOURCE_MAPPING_PD(4, fimc2, fimc2, PD_CAM),
146 SYSMMU_RESOURCE_MAPPING_PD(4, fimc3, fimc3, PD_CAM),
147 SYSMMU_RESOURCE_MAPPING_PD(4, tv, tv, PD_TV),
148 SYSMMU_RESOURCE_MAPPING_PD(4, mfc_r, mfc_r, PD_MFC),
149 SYSMMU_RESOURCE_MAPPING_PD(4, mfc_l, mfc_l, PD_MFC),
150 SYSMMU_RESOURCE_MAPPING_PD(4, rot, rot, PD_LCD0),
151 SYSMMU_RESOURCE_MAPPING_PD(4, jpeg, jpeg, PD_CAM),
152 SYSMMU_RESOURCE_MAPPING_PD(4, fimd0, fimd0, PD_LCD0),
153 };
154
155 static struct sysmmu_resource_map sysmmu_resmap4210[] __initdata = {
156 SYSMMU_RESOURCE_MAPPING_PD(4, 2d, 2d, PD_LCD0),
157 SYSMMU_RESOURCE_MAPPING_PD(4, fimd1, fimd1, PD_LCD1),
158 };
159
160 static struct sysmmu_resource_map sysmmu_resmap4212[] __initdata = {
161 SYSMMU_RESOURCE_MAPPING(4, 2d, 2d_acp),
162 SYSMMU_RESOURCE_MAPPING_PD(4, camif0, flite0, PD_ISP),
163 SYSMMU_RESOURCE_MAPPING_PD(4, camif1, flite1, PD_ISP),
164 SYSMMU_RESOURCE_MAPPING_PD(4, isp, isp, PD_ISP),
165 };
166 #endif /* CONFIG_ARCH_EXYNOS4 */
167
168 #ifdef CONFIG_ARCH_EXYNOS5
169 SYSMMU_RESOURCE_DEFINE(EXYNOS5, jpeg, JPEG, JPEG);
170 SYSMMU_RESOURCE_DEFINE(EXYNOS5, fimd1, FIMD1, FIMD1);
171 SYSMMU_RESOURCE_DEFINE(EXYNOS5, 2d, 2D, 2D);
172 SYSMMU_RESOURCE_DEFINE(EXYNOS5, rot, ROTATOR, ROTATOR);
173 SYSMMU_RESOURCE_DEFINE(EXYNOS5, tv, TV, TV);
174 SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite0, LITE0, LITE0);
175 SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite1, LITE1, LITE1);
176 SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc0, GSC0, GSC0);
177 SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc1, GSC1, GSC1);
178 SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc2, GSC2, GSC2);
179 SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc3, GSC3, GSC3);
180 SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_r, MFC_R, MFC_R);
181 SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_l, MFC_L, MFC_L);
182 SYSMMU_RESOURCE(EXYNOS5, isp) {
183 DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISP, ISP),
184 DEFINE_SYSMMU_RESOURCE(EXYNOS5, DRC, DRC),
185 DEFINE_SYSMMU_RESOURCE(EXYNOS5, FD, FD),
186 DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISPCPU, MCUISP),
187 DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERC, SCALERCISP),
188 DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERP, SCALERPISP),
189 DEFINE_SYSMMU_RESOURCE(EXYNOS5, ODC, ODC),
190 DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS0, DIS0),
191 DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS1, DIS1),
192 DEFINE_SYSMMU_RESOURCE(EXYNOS5, 3DNR, 3DNR),
193 };
194
195 static struct sysmmu_resource_map sysmmu_resmap5[] __initdata = {
196 SYSMMU_RESOURCE_MAPPING(5, jpeg, jpeg),
197 SYSMMU_RESOURCE_MAPPING(5, fimd1, fimd1),
198 SYSMMU_RESOURCE_MAPPING(5, 2d, 2d),
199 SYSMMU_RESOURCE_MAPPING(5, rot, rot),
200 SYSMMU_RESOURCE_MAPPING_PD(5, tv, tv, PD_DISP1),
201 SYSMMU_RESOURCE_MAPPING_PD(5, camif0, flite0, PD_GSCL),
202 SYSMMU_RESOURCE_MAPPING_PD(5, camif1, flite1, PD_GSCL),
203 SYSMMU_RESOURCE_MAPPING_PD(5, gsc0, gsc0, PD_GSCL),
204 SYSMMU_RESOURCE_MAPPING_PD(5, gsc1, gsc1, PD_GSCL),
205 SYSMMU_RESOURCE_MAPPING_PD(5, gsc2, gsc2, PD_GSCL),
206 SYSMMU_RESOURCE_MAPPING_PD(5, gsc3, gsc3, PD_GSCL),
207 SYSMMU_RESOURCE_MAPPING_PD(5, mfc_r, mfc_r, PD_MFC),
208 SYSMMU_RESOURCE_MAPPING_PD(5, mfc_l, mfc_l, PD_MFC),
209 SYSMMU_RESOURCE_MAPPING_MCPD(5, isp, isp, PD_ISP, mc_platdata),
210 };
211 #endif /* CONFIG_ARCH_EXYNOS5 */
212
213 static int __init init_sysmmu_platform_device(void)
214 {
215 int i, j;
216 struct sysmmu_resource_map *resmap[2] = {NULL, NULL};
217 int nmap[2] = {0, 0};
218
219 #ifdef CONFIG_ARCH_EXYNOS5
220 if (soc_is_exynos5250()) {
221 resmap[0] = sysmmu_resmap5;
222 nmap[0] = ARRAY_SIZE(sysmmu_resmap5);
223 nmap[1] = 0;
224 }
225 #endif
226
227 #ifdef CONFIG_ARCH_EXYNOS4
228 if (resmap[0] == NULL) {
229 resmap[0] = sysmmu_resmap4;
230 nmap[0] = ARRAY_SIZE(sysmmu_resmap4);
231 }
232
233 if (soc_is_exynos4210()) {
234 resmap[1] = sysmmu_resmap4210;
235 nmap[1] = ARRAY_SIZE(sysmmu_resmap4210);
236 }
237
238 if (soc_is_exynos4412() || soc_is_exynos4212()) {
239 resmap[1] = sysmmu_resmap4212;
240 nmap[1] = ARRAY_SIZE(sysmmu_resmap4212);
241 }
242 #endif
243
244 for (j = 0; j < 2; j++) {
245 for (i = 0; i < nmap[j]; i++) {
246 struct sysmmu_resource_map *map;
247 struct sysmmu_platform_data *platdata;
248
249 map = &resmap[j][i];
250
251 map->pdev->dev.parent = map->pdd;
252
253 platdata = map->pdev->dev.platform_data;
254 platdata->clockname = map->clocknames;
255
256 if (platform_device_add_resources(map->pdev, map->res,
257 map->rnum)) {
258 pr_err("%s: Failed to add device resources for "
259 "%s.%d\n", __func__,
260 map->pdev->name, map->pdev->id);
261 continue;
262 }
263
264 if (platform_device_register(map->pdev)) {
265 pr_err("%s: Failed to register %s.%d\n",
266 __func__, map->pdev->name,
267 map->pdev->id);
268 }
269 }
270 }
271
272 return 0;
273 }
274 arch_initcall(init_sysmmu_platform_device);
This page took 0.037503 seconds and 6 git commands to generate.