Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dev-sysmmu.c
Go to the documentation of this file.
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);
42 SYSMMU_PLATFORM_DEVICE(jpeg, 3);
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);
53 SYSMMU_PLATFORM_DEVICE(fimd0, 10);
54 SYSMMU_PLATFORM_DEVICE(fimd1, 11);
55 SYSMMU_PLATFORM_DEVICE(camif0, 12);
56 SYSMMU_PLATFORM_DEVICE(camif1, 13);
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 
75  struct resource *res;
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),
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 
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);