1 /* linux/arch/arm/mach-exynos/dev-sysmmu.c
3 * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * EXYNOS - System MMU support
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.
13 #include <linux/platform_device.h>
14 #include <linux/dma-mapping.h>
19 #include <mach/irqs.h>
20 #include <mach/sysmmu.h>
22 static u64 exynos_sysmmu_dma_mask
= DMA_BIT_MASK(32);
24 #define SYSMMU_PLATFORM_DEVICE(ipname, devid) \
25 static struct sysmmu_platform_data platdata_##ipname = { \
28 struct platform_device SYSMMU_PLATDEV(ipname) = \
30 .name = SYSMMU_DEVNAME_BASE, \
33 .dma_mask = &exynos_sysmmu_dma_mask, \
34 .coherent_dma_mask = DMA_BIT_MASK(32), \
35 .platform_data = &platdata_##ipname, \
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);
59 #define SYSMMU_RESOURCE_NAME(core, ipname) sysmmures_##core##_##ipname
61 #define SYSMMU_RESOURCE(core, ipname) \
62 static struct resource SYSMMU_RESOURCE_NAME(core, ipname)[] __initdata =
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)
68 #define SYSMMU_RESOURCE_DEFINE(core, ipname, mem, irq) \
69 SYSMMU_RESOURCE(core, ipname) { \
70 DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
73 struct sysmmu_resource_map
{
74 struct platform_device
*pdev
;
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, \
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, \
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, \
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, \
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)
117 #endif /* CONFIG_EXYNOS_DEV_PD */
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
),
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
),
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
),
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
),
166 #endif /* CONFIG_ARCH_EXYNOS4 */
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
),
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
),
211 #endif /* CONFIG_ARCH_EXYNOS5 */
213 static int __init
init_sysmmu_platform_device(void)
216 struct sysmmu_resource_map
*resmap
[2] = {NULL
, NULL
};
217 int nmap
[2] = {0, 0};
219 #ifdef CONFIG_ARCH_EXYNOS5
220 if (soc_is_exynos5250()) {
221 resmap
[0] = sysmmu_resmap5
;
222 nmap
[0] = ARRAY_SIZE(sysmmu_resmap5
);
227 #ifdef CONFIG_ARCH_EXYNOS4
228 if (resmap
[0] == NULL
) {
229 resmap
[0] = sysmmu_resmap4
;
230 nmap
[0] = ARRAY_SIZE(sysmmu_resmap4
);
233 if (soc_is_exynos4210()) {
234 resmap
[1] = sysmmu_resmap4210
;
235 nmap
[1] = ARRAY_SIZE(sysmmu_resmap4210
);
238 if (soc_is_exynos4412() || soc_is_exynos4212()) {
239 resmap
[1] = sysmmu_resmap4212
;
240 nmap
[1] = ARRAY_SIZE(sysmmu_resmap4212
);
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
;
251 map
->pdev
->dev
.parent
= map
->pdd
;
253 platdata
= map
->pdev
->dev
.platform_data
;
254 platdata
->clockname
= map
->clocknames
;
256 if (platform_device_add_resources(map
->pdev
, map
->res
,
258 pr_err("%s: Failed to add device resources for "
260 map
->pdev
->name
, map
->pdev
->id
);
264 if (platform_device_register(map
->pdev
)) {
265 pr_err("%s: Failed to register %s.%d\n",
266 __func__
, map
->pdev
->name
,
274 arch_initcall(init_sysmmu_platform_device
);