dev-sysmmu.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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. #include <linux/platform_device.h>
  13. #include <linux/dma-mapping.h>
  14. #include <plat/cpu.h>
  15. #include <mach/map.h>
  16. #include <mach/irqs.h>
  17. #include <mach/sysmmu.h>
  18. static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32);
  19. #define SYSMMU_PLATFORM_DEVICE(ipname, devid) \
  20. static struct sysmmu_platform_data platdata_##ipname = { \
  21. .dbgname = #ipname, \
  22. }; \
  23. struct platform_device SYSMMU_PLATDEV(ipname) = \
  24. { \
  25. .name = SYSMMU_DEVNAME_BASE, \
  26. .id = devid, \
  27. .dev = { \
  28. .dma_mask = &exynos_sysmmu_dma_mask, \
  29. .coherent_dma_mask = DMA_BIT_MASK(32), \
  30. .platform_data = &platdata_##ipname, \
  31. }, \
  32. }
  33. SYSMMU_PLATFORM_DEVICE(mfc_l, 0);
  34. SYSMMU_PLATFORM_DEVICE(mfc_r, 1);
  35. SYSMMU_PLATFORM_DEVICE(tv, 2);
  36. SYSMMU_PLATFORM_DEVICE(jpeg, 3);
  37. SYSMMU_PLATFORM_DEVICE(rot, 4);
  38. SYSMMU_PLATFORM_DEVICE(fimc0, 5); /* fimc* and gsc* exist exclusively */
  39. SYSMMU_PLATFORM_DEVICE(fimc1, 6);
  40. SYSMMU_PLATFORM_DEVICE(fimc2, 7);
  41. SYSMMU_PLATFORM_DEVICE(fimc3, 8);
  42. SYSMMU_PLATFORM_DEVICE(gsc0, 5);
  43. SYSMMU_PLATFORM_DEVICE(gsc1, 6);
  44. SYSMMU_PLATFORM_DEVICE(gsc2, 7);
  45. SYSMMU_PLATFORM_DEVICE(gsc3, 8);
  46. SYSMMU_PLATFORM_DEVICE(isp, 9);
  47. SYSMMU_PLATFORM_DEVICE(fimd0, 10);
  48. SYSMMU_PLATFORM_DEVICE(fimd1, 11);
  49. SYSMMU_PLATFORM_DEVICE(camif0, 12);
  50. SYSMMU_PLATFORM_DEVICE(camif1, 13);
  51. SYSMMU_PLATFORM_DEVICE(2d, 14);
  52. #define SYSMMU_RESOURCE_NAME(core, ipname) sysmmures_##core##_##ipname
  53. #define SYSMMU_RESOURCE(core, ipname) \
  54. static struct resource SYSMMU_RESOURCE_NAME(core, ipname)[] __initdata =
  55. #define DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
  56. DEFINE_RES_MEM_NAMED(core##_PA_SYSMMU_##mem, SZ_4K, #mem), \
  57. DEFINE_RES_IRQ_NAMED(core##_IRQ_SYSMMU_##irq##_0, #mem)
  58. #define SYSMMU_RESOURCE_DEFINE(core, ipname, mem, irq) \
  59. SYSMMU_RESOURCE(core, ipname) { \
  60. DEFINE_SYSMMU_RESOURCE(core, mem, irq) \
  61. }
  62. struct sysmmu_resource_map {
  63. struct platform_device *pdev;
  64. struct resource *res;
  65. u32 rnum;
  66. struct device *pdd;
  67. char *clocknames;
  68. };
  69. #define SYSMMU_RESOURCE_MAPPING(core, ipname, resname) { \
  70. .pdev = &SYSMMU_PLATDEV(ipname), \
  71. .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
  72. .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
  73. .clocknames = SYSMMU_CLOCK_NAME, \
  74. }
  75. #define SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata) { \
  76. .pdev = &SYSMMU_PLATDEV(ipname), \
  77. .res = SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
  78. .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
  79. .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
  80. }
  81. #ifdef CONFIG_EXYNOS_DEV_PD
  82. #define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) { \
  83. .pdev = &SYSMMU_PLATDEV(ipname), \
  84. .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
  85. .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
  86. .clocknames = SYSMMU_CLOCK_NAME, \
  87. .pdd = &exynos##core##_device_pd[pd].dev, \
  88. }
  89. #define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) {\
  90. .pdev = &SYSMMU_PLATDEV(ipname), \
  91. .res = &SYSMMU_RESOURCE_NAME(EXYNOS##core, resname), \
  92. .rnum = ARRAY_SIZE(SYSMMU_RESOURCE_NAME(EXYNOS##core, resname)),\
  93. .clocknames = SYSMMU_CLOCK_NAME "," SYSMMU_CLOCK_NAME2, \
  94. .pdd = &exynos##core##_device_pd[pd].dev, \
  95. }
  96. #else
  97. #define SYSMMU_RESOURCE_MAPPING_PD(core, ipname, resname, pd) \
  98. SYSMMU_RESOURCE_MAPPING(core, ipname, resname)
  99. #define SYSMMU_RESOURCE_MAPPING_MCPD(core, ipname, resname, pd, pdata) \
  100. SYSMMU_RESOURCE_MAPPING_MC(core, ipname, resname, pdata)
  101. #endif /* CONFIG_EXYNOS_DEV_PD */
  102. #ifdef CONFIG_ARCH_EXYNOS4
  103. SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc0, FIMC0, FIMC0);
  104. SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc1, FIMC1, FIMC1);
  105. SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc2, FIMC2, FIMC2);
  106. SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimc3, FIMC3, FIMC3);
  107. SYSMMU_RESOURCE_DEFINE(EXYNOS4, jpeg, JPEG, JPEG);
  108. SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d, G2D, 2D);
  109. SYSMMU_RESOURCE_DEFINE(EXYNOS4, tv, TV, TV_M0);
  110. SYSMMU_RESOURCE_DEFINE(EXYNOS4, 2d_acp, 2D_ACP, 2D);
  111. SYSMMU_RESOURCE_DEFINE(EXYNOS4, rot, ROTATOR, ROTATOR);
  112. SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd0, FIMD0, LCD0_M0);
  113. SYSMMU_RESOURCE_DEFINE(EXYNOS4, fimd1, FIMD1, LCD1_M1);
  114. SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite0, FIMC_LITE0, FIMC_LITE0);
  115. SYSMMU_RESOURCE_DEFINE(EXYNOS4, flite1, FIMC_LITE1, FIMC_LITE1);
  116. SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_r, MFC_R, MFC_M0);
  117. SYSMMU_RESOURCE_DEFINE(EXYNOS4, mfc_l, MFC_L, MFC_M1);
  118. SYSMMU_RESOURCE(EXYNOS4, isp) {
  119. DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_ISP, FIMC_ISP),
  120. DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_DRC, FIMC_DRC),
  121. DEFINE_SYSMMU_RESOURCE(EXYNOS4, FIMC_FD, FIMC_FD),
  122. DEFINE_SYSMMU_RESOURCE(EXYNOS4, ISPCPU, FIMC_CX),
  123. };
  124. static struct sysmmu_resource_map sysmmu_resmap4[] __initdata = {
  125. SYSMMU_RESOURCE_MAPPING_PD(4, fimc0, fimc0, PD_CAM),
  126. SYSMMU_RESOURCE_MAPPING_PD(4, fimc1, fimc1, PD_CAM),
  127. SYSMMU_RESOURCE_MAPPING_PD(4, fimc2, fimc2, PD_CAM),
  128. SYSMMU_RESOURCE_MAPPING_PD(4, fimc3, fimc3, PD_CAM),
  129. SYSMMU_RESOURCE_MAPPING_PD(4, tv, tv, PD_TV),
  130. SYSMMU_RESOURCE_MAPPING_PD(4, mfc_r, mfc_r, PD_MFC),
  131. SYSMMU_RESOURCE_MAPPING_PD(4, mfc_l, mfc_l, PD_MFC),
  132. SYSMMU_RESOURCE_MAPPING_PD(4, rot, rot, PD_LCD0),
  133. SYSMMU_RESOURCE_MAPPING_PD(4, jpeg, jpeg, PD_CAM),
  134. SYSMMU_RESOURCE_MAPPING_PD(4, fimd0, fimd0, PD_LCD0),
  135. };
  136. static struct sysmmu_resource_map sysmmu_resmap4210[] __initdata = {
  137. SYSMMU_RESOURCE_MAPPING_PD(4, 2d, 2d, PD_LCD0),
  138. SYSMMU_RESOURCE_MAPPING_PD(4, fimd1, fimd1, PD_LCD1),
  139. };
  140. static struct sysmmu_resource_map sysmmu_resmap4212[] __initdata = {
  141. SYSMMU_RESOURCE_MAPPING(4, 2d, 2d_acp),
  142. SYSMMU_RESOURCE_MAPPING_PD(4, camif0, flite0, PD_ISP),
  143. SYSMMU_RESOURCE_MAPPING_PD(4, camif1, flite1, PD_ISP),
  144. SYSMMU_RESOURCE_MAPPING_PD(4, isp, isp, PD_ISP),
  145. };
  146. #endif /* CONFIG_ARCH_EXYNOS4 */
  147. #ifdef CONFIG_ARCH_EXYNOS5
  148. SYSMMU_RESOURCE_DEFINE(EXYNOS5, jpeg, JPEG, JPEG);
  149. SYSMMU_RESOURCE_DEFINE(EXYNOS5, fimd1, FIMD1, FIMD1);
  150. SYSMMU_RESOURCE_DEFINE(EXYNOS5, 2d, 2D, 2D);
  151. SYSMMU_RESOURCE_DEFINE(EXYNOS5, rot, ROTATOR, ROTATOR);
  152. SYSMMU_RESOURCE_DEFINE(EXYNOS5, tv, TV, TV);
  153. SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite0, LITE0, LITE0);
  154. SYSMMU_RESOURCE_DEFINE(EXYNOS5, flite1, LITE1, LITE1);
  155. SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc0, GSC0, GSC0);
  156. SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc1, GSC1, GSC1);
  157. SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc2, GSC2, GSC2);
  158. SYSMMU_RESOURCE_DEFINE(EXYNOS5, gsc3, GSC3, GSC3);
  159. SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_r, MFC_R, MFC_R);
  160. SYSMMU_RESOURCE_DEFINE(EXYNOS5, mfc_l, MFC_L, MFC_L);
  161. SYSMMU_RESOURCE(EXYNOS5, isp) {
  162. DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISP, ISP),
  163. DEFINE_SYSMMU_RESOURCE(EXYNOS5, DRC, DRC),
  164. DEFINE_SYSMMU_RESOURCE(EXYNOS5, FD, FD),
  165. DEFINE_SYSMMU_RESOURCE(EXYNOS5, ISPCPU, MCUISP),
  166. DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERC, SCALERCISP),
  167. DEFINE_SYSMMU_RESOURCE(EXYNOS5, SCALERP, SCALERPISP),
  168. DEFINE_SYSMMU_RESOURCE(EXYNOS5, ODC, ODC),
  169. DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS0, DIS0),
  170. DEFINE_SYSMMU_RESOURCE(EXYNOS5, DIS1, DIS1),
  171. DEFINE_SYSMMU_RESOURCE(EXYNOS5, 3DNR, 3DNR),
  172. };
  173. static struct sysmmu_resource_map sysmmu_resmap5[] __initdata = {
  174. SYSMMU_RESOURCE_MAPPING(5, jpeg, jpeg),
  175. SYSMMU_RESOURCE_MAPPING(5, fimd1, fimd1),
  176. SYSMMU_RESOURCE_MAPPING(5, 2d, 2d),
  177. SYSMMU_RESOURCE_MAPPING(5, rot, rot),
  178. SYSMMU_RESOURCE_MAPPING_PD(5, tv, tv, PD_DISP1),
  179. SYSMMU_RESOURCE_MAPPING_PD(5, camif0, flite0, PD_GSCL),
  180. SYSMMU_RESOURCE_MAPPING_PD(5, camif1, flite1, PD_GSCL),
  181. SYSMMU_RESOURCE_MAPPING_PD(5, gsc0, gsc0, PD_GSCL),
  182. SYSMMU_RESOURCE_MAPPING_PD(5, gsc1, gsc1, PD_GSCL),
  183. SYSMMU_RESOURCE_MAPPING_PD(5, gsc2, gsc2, PD_GSCL),
  184. SYSMMU_RESOURCE_MAPPING_PD(5, gsc3, gsc3, PD_GSCL),
  185. SYSMMU_RESOURCE_MAPPING_PD(5, mfc_r, mfc_r, PD_MFC),
  186. SYSMMU_RESOURCE_MAPPING_PD(5, mfc_l, mfc_l, PD_MFC),
  187. SYSMMU_RESOURCE_MAPPING_MCPD(5, isp, isp, PD_ISP, mc_platdata),
  188. };
  189. #endif /* CONFIG_ARCH_EXYNOS5 */
  190. static int __init init_sysmmu_platform_device(void)
  191. {
  192. int i, j;
  193. struct sysmmu_resource_map *resmap[2] = {NULL, NULL};
  194. int nmap[2] = {0, 0};
  195. #ifdef CONFIG_ARCH_EXYNOS5
  196. if (soc_is_exynos5250()) {
  197. resmap[0] = sysmmu_resmap5;
  198. nmap[0] = ARRAY_SIZE(sysmmu_resmap5);
  199. nmap[1] = 0;
  200. }
  201. #endif
  202. #ifdef CONFIG_ARCH_EXYNOS4
  203. if (resmap[0] == NULL) {
  204. resmap[0] = sysmmu_resmap4;
  205. nmap[0] = ARRAY_SIZE(sysmmu_resmap4);
  206. }
  207. if (soc_is_exynos4210()) {
  208. resmap[1] = sysmmu_resmap4210;
  209. nmap[1] = ARRAY_SIZE(sysmmu_resmap4210);
  210. }
  211. if (soc_is_exynos4412() || soc_is_exynos4212()) {
  212. resmap[1] = sysmmu_resmap4212;
  213. nmap[1] = ARRAY_SIZE(sysmmu_resmap4212);
  214. }
  215. #endif
  216. for (j = 0; j < 2; j++) {
  217. for (i = 0; i < nmap[j]; i++) {
  218. struct sysmmu_resource_map *map;
  219. struct sysmmu_platform_data *platdata;
  220. map = &resmap[j][i];
  221. map->pdev->dev.parent = map->pdd;
  222. platdata = map->pdev->dev.platform_data;
  223. platdata->clockname = map->clocknames;
  224. if (platform_device_add_resources(map->pdev, map->res,
  225. map->rnum)) {
  226. pr_err("%s: Failed to add device resources for "
  227. "%s.%d\n", __func__,
  228. map->pdev->name, map->pdev->id);
  229. continue;
  230. }
  231. if (platform_device_register(map->pdev)) {
  232. pr_err("%s: Failed to register %s.%d\n",
  233. __func__, map->pdev->name,
  234. map->pdev->id);
  235. }
  236. }
  237. }
  238. return 0;
  239. }
  240. arch_initcall(init_sysmmu_platform_device);