Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  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
 22static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
 23
 24#define SYSMMU_PLATFORM_DEVICE(ipname, devid)				\
 25static struct sysmmu_platform_data platdata_##ipname = {		\
 26	.dbgname = #ipname,						\
 27};									\
 28struct 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
 39SYSMMU_PLATFORM_DEVICE(mfc_l,	0);
 40SYSMMU_PLATFORM_DEVICE(mfc_r,	1);
 41SYSMMU_PLATFORM_DEVICE(tv,	2);
 42SYSMMU_PLATFORM_DEVICE(jpeg,	3);
 43SYSMMU_PLATFORM_DEVICE(rot,	4);
 44SYSMMU_PLATFORM_DEVICE(fimc0,	5); /* fimc* and gsc* exist exclusively */
 45SYSMMU_PLATFORM_DEVICE(fimc1,	6);
 46SYSMMU_PLATFORM_DEVICE(fimc2,	7);
 47SYSMMU_PLATFORM_DEVICE(fimc3,	8);
 48SYSMMU_PLATFORM_DEVICE(gsc0,	5);
 49SYSMMU_PLATFORM_DEVICE(gsc1,	6);
 50SYSMMU_PLATFORM_DEVICE(gsc2,	7);
 51SYSMMU_PLATFORM_DEVICE(gsc3,	8);
 52SYSMMU_PLATFORM_DEVICE(isp,	9);
 53SYSMMU_PLATFORM_DEVICE(fimd0,	10);
 54SYSMMU_PLATFORM_DEVICE(fimd1,	11);
 55SYSMMU_PLATFORM_DEVICE(camif0,	12);
 56SYSMMU_PLATFORM_DEVICE(camif1,	13);
 57SYSMMU_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
 73struct 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
120SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc0,	FIMC0,	FIMC0);
121SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc1,	FIMC1,	FIMC1);
122SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc2,	FIMC2,	FIMC2);
123SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc3,	FIMC3,	FIMC3);
124SYSMMU_RESOURCE_DEFINE(EXYNOS4, jpeg,	JPEG,	JPEG);
125SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d,	G2D,	2D);
126SYSMMU_RESOURCE_DEFINE(EXYNOS4, tv,	TV,	TV_M0);
127SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d_acp,	2D_ACP,	2D);
128SYSMMU_RESOURCE_DEFINE(EXYNOS4, rot,	ROTATOR, ROTATOR);
129SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd0,	FIMD0,	LCD0_M0);
130SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd1,	FIMD1,	LCD1_M1);
131SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite0,	FIMC_LITE0, FIMC_LITE0);
132SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite1,	FIMC_LITE1, FIMC_LITE1);
133SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_r,	MFC_R,	MFC_M0);
134SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_l,	MFC_L,	MFC_M1);
135SYSMMU_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
142static 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
155static 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
160static 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
169SYSMMU_RESOURCE_DEFINE(EXYNOS5, jpeg,	JPEG,	JPEG);
170SYSMMU_RESOURCE_DEFINE(EXYNOS5, fimd1,	FIMD1,	FIMD1);
171SYSMMU_RESOURCE_DEFINE(EXYNOS5, 2d,	2D,	2D);
172SYSMMU_RESOURCE_DEFINE(EXYNOS5, rot,	ROTATOR, ROTATOR);
173SYSMMU_RESOURCE_DEFINE(EXYNOS5, tv,	TV,	TV);
174SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite0,	LITE0,	LITE0);
175SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite1,	LITE1,	LITE1);
176SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc0,	GSC0,	GSC0);
177SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc1,	GSC1,	GSC1);
178SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc2,	GSC2,	GSC2);
179SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc3,	GSC3,	GSC3);
180SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_r,	MFC_R,	MFC_R);
181SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_l,	MFC_L,	MFC_L);
182SYSMMU_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
195static 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
213static 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}
274arch_initcall(init_sysmmu_platform_device);