ARM: KVM: vgic: take distributor lock on sync_hwstate path
[firefly-linux-kernel-4.4.55.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);