1 /* linux/arch/arm/mach-exynos4/dev-sysmmu.c
2  *
3  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4  *		http://www.samsung.com
5  *
6  * EXYNOS4 - 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 #include <linux/export.h>
16 
17 #include <mach/map.h>
18 #include <mach/irqs.h>
19 #include <mach/sysmmu.h>
20 #include <plat/s5p-clock.h>
21 
22 /* These names must be equal to the clock names in mach-exynos4/clock.c */
23 const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM] = {
24 	"SYSMMU_MDMA"	,
25 	"SYSMMU_SSS"	,
26 	"SYSMMU_FIMC0"	,
27 	"SYSMMU_FIMC1"	,
28 	"SYSMMU_FIMC2"	,
29 	"SYSMMU_FIMC3"	,
30 	"SYSMMU_JPEG"	,
31 	"SYSMMU_FIMD0"	,
32 	"SYSMMU_FIMD1"	,
33 	"SYSMMU_PCIe"	,
34 	"SYSMMU_G2D"	,
35 	"SYSMMU_ROTATOR",
36 	"SYSMMU_MDMA2"	,
37 	"SYSMMU_TV"	,
38 	"SYSMMU_MFC_L"	,
39 	"SYSMMU_MFC_R"	,
40 };
41 
42 static struct resource exynos4_sysmmu_resource[] = {
43 	[0] = {
44 		.start	= EXYNOS4_PA_SYSMMU_MDMA,
45 		.end	= EXYNOS4_PA_SYSMMU_MDMA + SZ_64K - 1,
46 		.flags	= IORESOURCE_MEM,
47 	},
48 	[1] = {
49 		.start	= IRQ_SYSMMU_MDMA0_0,
50 		.end	= IRQ_SYSMMU_MDMA0_0,
51 		.flags	= IORESOURCE_IRQ,
52 	},
53 	[2] = {
54 		.start	= EXYNOS4_PA_SYSMMU_SSS,
55 		.end	= EXYNOS4_PA_SYSMMU_SSS + SZ_64K - 1,
56 		.flags	= IORESOURCE_MEM,
57 	},
58 	[3] = {
59 		.start	= IRQ_SYSMMU_SSS_0,
60 		.end	= IRQ_SYSMMU_SSS_0,
61 		.flags	= IORESOURCE_IRQ,
62 	},
63 	[4] = {
64 		.start	= EXYNOS4_PA_SYSMMU_FIMC0,
65 		.end	= EXYNOS4_PA_SYSMMU_FIMC0 + SZ_64K - 1,
66 		.flags	= IORESOURCE_MEM,
67 	},
68 	[5] = {
69 		.start	= IRQ_SYSMMU_FIMC0_0,
70 		.end	= IRQ_SYSMMU_FIMC0_0,
71 		.flags	= IORESOURCE_IRQ,
72 	},
73 	[6] = {
74 		.start	= EXYNOS4_PA_SYSMMU_FIMC1,
75 		.end	= EXYNOS4_PA_SYSMMU_FIMC1 + SZ_64K - 1,
76 		.flags	= IORESOURCE_MEM,
77 	},
78 	[7] = {
79 		.start	= IRQ_SYSMMU_FIMC1_0,
80 		.end	= IRQ_SYSMMU_FIMC1_0,
81 		.flags	= IORESOURCE_IRQ,
82 	},
83 	[8] = {
84 		.start	= EXYNOS4_PA_SYSMMU_FIMC2,
85 		.end	= EXYNOS4_PA_SYSMMU_FIMC2 + SZ_64K - 1,
86 		.flags	= IORESOURCE_MEM,
87 	},
88 	[9] = {
89 		.start	= IRQ_SYSMMU_FIMC2_0,
90 		.end	= IRQ_SYSMMU_FIMC2_0,
91 		.flags	= IORESOURCE_IRQ,
92 	},
93 	[10] = {
94 		.start	= EXYNOS4_PA_SYSMMU_FIMC3,
95 		.end	= EXYNOS4_PA_SYSMMU_FIMC3 + SZ_64K - 1,
96 		.flags	= IORESOURCE_MEM,
97 	},
98 	[11] = {
99 		.start	= IRQ_SYSMMU_FIMC3_0,
100 		.end	= IRQ_SYSMMU_FIMC3_0,
101 		.flags	= IORESOURCE_IRQ,
102 	},
103 	[12] = {
104 		.start	= EXYNOS4_PA_SYSMMU_JPEG,
105 		.end	= EXYNOS4_PA_SYSMMU_JPEG + SZ_64K - 1,
106 		.flags	= IORESOURCE_MEM,
107 	},
108 	[13] = {
109 		.start	= IRQ_SYSMMU_JPEG_0,
110 		.end	= IRQ_SYSMMU_JPEG_0,
111 		.flags	= IORESOURCE_IRQ,
112 	},
113 	[14] = {
114 		.start	= EXYNOS4_PA_SYSMMU_FIMD0,
115 		.end	= EXYNOS4_PA_SYSMMU_FIMD0 + SZ_64K - 1,
116 		.flags	= IORESOURCE_MEM,
117 	},
118 	[15] = {
119 		.start	= IRQ_SYSMMU_LCD0_M0_0,
120 		.end	= IRQ_SYSMMU_LCD0_M0_0,
121 		.flags	= IORESOURCE_IRQ,
122 	},
123 	[16] = {
124 		.start	= EXYNOS4_PA_SYSMMU_FIMD1,
125 		.end	= EXYNOS4_PA_SYSMMU_FIMD1 + SZ_64K - 1,
126 		.flags	= IORESOURCE_MEM,
127 	},
128 	[17] = {
129 		.start	= IRQ_SYSMMU_LCD1_M1_0,
130 		.end	= IRQ_SYSMMU_LCD1_M1_0,
131 		.flags	= IORESOURCE_IRQ,
132 	},
133 	[18] = {
134 		.start	= EXYNOS4_PA_SYSMMU_PCIe,
135 		.end	= EXYNOS4_PA_SYSMMU_PCIe + SZ_64K - 1,
136 		.flags	= IORESOURCE_MEM,
137 	},
138 	[19] = {
139 		.start	= IRQ_SYSMMU_PCIE_0,
140 		.end	= IRQ_SYSMMU_PCIE_0,
141 		.flags	= IORESOURCE_IRQ,
142 	},
143 	[20] = {
144 		.start	= EXYNOS4_PA_SYSMMU_G2D,
145 		.end	= EXYNOS4_PA_SYSMMU_G2D + SZ_64K - 1,
146 		.flags	= IORESOURCE_MEM,
147 	},
148 	[21] = {
149 		.start	= IRQ_SYSMMU_2D_0,
150 		.end	= IRQ_SYSMMU_2D_0,
151 		.flags	= IORESOURCE_IRQ,
152 	},
153 	[22] = {
154 		.start	= EXYNOS4_PA_SYSMMU_ROTATOR,
155 		.end	= EXYNOS4_PA_SYSMMU_ROTATOR + SZ_64K - 1,
156 		.flags	= IORESOURCE_MEM,
157 	},
158 	[23] = {
159 		.start	= IRQ_SYSMMU_ROTATOR_0,
160 		.end	= IRQ_SYSMMU_ROTATOR_0,
161 		.flags	= IORESOURCE_IRQ,
162 	},
163 	[24] = {
164 		.start	= EXYNOS4_PA_SYSMMU_MDMA2,
165 		.end	= EXYNOS4_PA_SYSMMU_MDMA2 + SZ_64K - 1,
166 		.flags	= IORESOURCE_MEM,
167 	},
168 	[25] = {
169 		.start	= IRQ_SYSMMU_MDMA1_0,
170 		.end	= IRQ_SYSMMU_MDMA1_0,
171 		.flags	= IORESOURCE_IRQ,
172 	},
173 	[26] = {
174 		.start	= EXYNOS4_PA_SYSMMU_TV,
175 		.end	= EXYNOS4_PA_SYSMMU_TV + SZ_64K - 1,
176 		.flags	= IORESOURCE_MEM,
177 	},
178 	[27] = {
179 		.start	= IRQ_SYSMMU_TV_M0_0,
180 		.end	= IRQ_SYSMMU_TV_M0_0,
181 		.flags	= IORESOURCE_IRQ,
182 	},
183 	[28] = {
184 		.start	= EXYNOS4_PA_SYSMMU_MFC_L,
185 		.end	= EXYNOS4_PA_SYSMMU_MFC_L + SZ_64K - 1,
186 		.flags	= IORESOURCE_MEM,
187 	},
188 	[29] = {
189 		.start	= IRQ_SYSMMU_MFC_M0_0,
190 		.end	= IRQ_SYSMMU_MFC_M0_0,
191 		.flags	= IORESOURCE_IRQ,
192 	},
193 	[30] = {
194 		.start	= EXYNOS4_PA_SYSMMU_MFC_R,
195 		.end	= EXYNOS4_PA_SYSMMU_MFC_R + SZ_64K - 1,
196 		.flags	= IORESOURCE_MEM,
197 	},
198 	[31] = {
199 		.start	= IRQ_SYSMMU_MFC_M1_0,
200 		.end	= IRQ_SYSMMU_MFC_M1_0,
201 		.flags	= IORESOURCE_IRQ,
202 	},
203 };
204 
205 struct platform_device exynos4_device_sysmmu = {
206 	.name		= "s5p-sysmmu",
207 	.id		= 32,
208 	.num_resources	= ARRAY_SIZE(exynos4_sysmmu_resource),
209 	.resource	= exynos4_sysmmu_resource,
210 };
211 EXPORT_SYMBOL(exynos4_device_sysmmu);
212 
213 static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM];
sysmmu_clk_init(struct device * dev,sysmmu_ips ips)214 void sysmmu_clk_init(struct device *dev, sysmmu_ips ips)
215 {
216 	sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]);
217 	if (IS_ERR(sysmmu_clk[ips]))
218 		sysmmu_clk[ips] = NULL;
219 	else
220 		clk_put(sysmmu_clk[ips]);
221 }
222 
sysmmu_clk_enable(sysmmu_ips ips)223 void sysmmu_clk_enable(sysmmu_ips ips)
224 {
225 	if (sysmmu_clk[ips])
226 		clk_enable(sysmmu_clk[ips]);
227 }
228 
sysmmu_clk_disable(sysmmu_ips ips)229 void sysmmu_clk_disable(sysmmu_ips ips)
230 {
231 	if (sysmmu_clk[ips])
232 		clk_disable(sysmmu_clk[ips]);
233 }
234