mtk_drm_drv.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015 MediaTek Inc.
  4. * Author: YT SHEN <yt.shen@mediatek.com>
  5. */
  6. #include <linux/component.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/of_platform.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/pm_runtime.h>
  12. #include <linux/dma-mapping.h>
  13. #include <drm/clients/drm_client_setup.h>
  14. #include <drm/drm_atomic.h>
  15. #include <drm/drm_atomic_helper.h>
  16. #include <drm/drm_drv.h>
  17. #include <drm/drm_fbdev_dma.h>
  18. #include <drm/drm_fourcc.h>
  19. #include <drm/drm_gem.h>
  20. #include <drm/drm_gem_framebuffer_helper.h>
  21. #include <drm/drm_ioctl.h>
  22. #include <drm/drm_of.h>
  23. #include <drm/drm_probe_helper.h>
  24. #include <drm/drm_vblank.h>
  25. #include "mtk_crtc.h"
  26. #include "mtk_ddp_comp.h"
  27. #include "mtk_disp_drv.h"
  28. #include "mtk_drm_drv.h"
  29. #include "mtk_gem.h"
  30. #define DRIVER_NAME "mediatek"
  31. #define DRIVER_DESC "Mediatek SoC DRM"
  32. #define DRIVER_MAJOR 1
  33. #define DRIVER_MINOR 0
  34. static const struct drm_mode_config_helper_funcs mtk_drm_mode_config_helpers = {
  35. .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
  36. };
  37. static struct drm_framebuffer *
  38. mtk_drm_mode_fb_create(struct drm_device *dev,
  39. struct drm_file *file,
  40. const struct drm_format_info *info,
  41. const struct drm_mode_fb_cmd2 *cmd)
  42. {
  43. if (info->num_planes != 1)
  44. return ERR_PTR(-EINVAL);
  45. return drm_gem_fb_create(dev, file, info, cmd);
  46. }
  47. static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = {
  48. .fb_create = mtk_drm_mode_fb_create,
  49. .atomic_check = drm_atomic_helper_check,
  50. .atomic_commit = drm_atomic_helper_commit,
  51. };
  52. static const unsigned int mt2701_mtk_ddp_main[] = {
  53. DDP_COMPONENT_OVL0,
  54. DDP_COMPONENT_RDMA0,
  55. DDP_COMPONENT_COLOR0,
  56. DDP_COMPONENT_BLS,
  57. DDP_COMPONENT_DSI0,
  58. };
  59. static const unsigned int mt2701_mtk_ddp_ext[] = {
  60. DDP_COMPONENT_RDMA1,
  61. DDP_COMPONENT_DPI0,
  62. };
  63. static const unsigned int mt7623_mtk_ddp_main[] = {
  64. DDP_COMPONENT_OVL0,
  65. DDP_COMPONENT_RDMA0,
  66. DDP_COMPONENT_COLOR0,
  67. DDP_COMPONENT_BLS,
  68. DDP_COMPONENT_DPI0,
  69. };
  70. static const unsigned int mt7623_mtk_ddp_ext[] = {
  71. DDP_COMPONENT_RDMA1,
  72. DDP_COMPONENT_DSI0,
  73. };
  74. static const unsigned int mt2712_mtk_ddp_main[] = {
  75. DDP_COMPONENT_OVL0,
  76. DDP_COMPONENT_COLOR0,
  77. DDP_COMPONENT_AAL0,
  78. DDP_COMPONENT_OD0,
  79. DDP_COMPONENT_RDMA0,
  80. DDP_COMPONENT_DPI0,
  81. DDP_COMPONENT_PWM0,
  82. };
  83. static const unsigned int mt2712_mtk_ddp_ext[] = {
  84. DDP_COMPONENT_OVL1,
  85. DDP_COMPONENT_COLOR1,
  86. DDP_COMPONENT_AAL1,
  87. DDP_COMPONENT_OD1,
  88. DDP_COMPONENT_RDMA1,
  89. DDP_COMPONENT_DPI1,
  90. DDP_COMPONENT_PWM1,
  91. };
  92. static const unsigned int mt2712_mtk_ddp_third[] = {
  93. DDP_COMPONENT_RDMA2,
  94. DDP_COMPONENT_DSI3,
  95. DDP_COMPONENT_PWM2,
  96. };
  97. static unsigned int mt8167_mtk_ddp_main[] = {
  98. DDP_COMPONENT_OVL0,
  99. DDP_COMPONENT_COLOR0,
  100. DDP_COMPONENT_CCORR,
  101. DDP_COMPONENT_AAL0,
  102. DDP_COMPONENT_GAMMA,
  103. DDP_COMPONENT_DITHER0,
  104. DDP_COMPONENT_RDMA0,
  105. DDP_COMPONENT_DSI0,
  106. };
  107. static const unsigned int mt8173_mtk_ddp_main[] = {
  108. DDP_COMPONENT_OVL0,
  109. DDP_COMPONENT_COLOR0,
  110. DDP_COMPONENT_AAL0,
  111. DDP_COMPONENT_OD0,
  112. DDP_COMPONENT_RDMA0,
  113. DDP_COMPONENT_UFOE,
  114. DDP_COMPONENT_DSI0,
  115. DDP_COMPONENT_PWM0,
  116. };
  117. static const unsigned int mt8173_mtk_ddp_ext[] = {
  118. DDP_COMPONENT_OVL1,
  119. DDP_COMPONENT_COLOR1,
  120. DDP_COMPONENT_GAMMA,
  121. DDP_COMPONENT_RDMA1,
  122. DDP_COMPONENT_DPI0,
  123. };
  124. static const unsigned int mt8183_mtk_ddp_main[] = {
  125. DDP_COMPONENT_OVL0,
  126. DDP_COMPONENT_OVL_2L0,
  127. DDP_COMPONENT_RDMA0,
  128. DDP_COMPONENT_COLOR0,
  129. DDP_COMPONENT_CCORR,
  130. DDP_COMPONENT_AAL0,
  131. DDP_COMPONENT_GAMMA,
  132. DDP_COMPONENT_DITHER0,
  133. DDP_COMPONENT_DSI0,
  134. };
  135. static const unsigned int mt8183_mtk_ddp_ext[] = {
  136. DDP_COMPONENT_OVL_2L1,
  137. DDP_COMPONENT_RDMA1,
  138. DDP_COMPONENT_DPI0,
  139. };
  140. static const unsigned int mt8186_mtk_ddp_main[] = {
  141. DDP_COMPONENT_OVL0,
  142. DDP_COMPONENT_RDMA0,
  143. DDP_COMPONENT_COLOR0,
  144. DDP_COMPONENT_CCORR,
  145. DDP_COMPONENT_AAL0,
  146. DDP_COMPONENT_GAMMA,
  147. DDP_COMPONENT_POSTMASK0,
  148. DDP_COMPONENT_DITHER0,
  149. DDP_COMPONENT_DSI0,
  150. };
  151. static const unsigned int mt8186_mtk_ddp_ext[] = {
  152. DDP_COMPONENT_OVL_2L0,
  153. DDP_COMPONENT_RDMA1,
  154. DDP_COMPONENT_DPI0,
  155. };
  156. static const unsigned int mt8188_mtk_ddp_main[] = {
  157. DDP_COMPONENT_OVL0,
  158. DDP_COMPONENT_RDMA0,
  159. DDP_COMPONENT_COLOR0,
  160. DDP_COMPONENT_CCORR,
  161. DDP_COMPONENT_AAL0,
  162. DDP_COMPONENT_GAMMA,
  163. DDP_COMPONENT_POSTMASK0,
  164. DDP_COMPONENT_DITHER0,
  165. };
  166. static const struct mtk_drm_route mt8188_mtk_ddp_main_routes[] = {
  167. {0, DDP_COMPONENT_DP_INTF0},
  168. {0, DDP_COMPONENT_DSI0},
  169. };
  170. static const unsigned int mt8192_mtk_ddp_main[] = {
  171. DDP_COMPONENT_OVL0,
  172. DDP_COMPONENT_OVL_2L0,
  173. DDP_COMPONENT_RDMA0,
  174. DDP_COMPONENT_COLOR0,
  175. DDP_COMPONENT_CCORR,
  176. DDP_COMPONENT_AAL0,
  177. DDP_COMPONENT_GAMMA,
  178. DDP_COMPONENT_POSTMASK0,
  179. DDP_COMPONENT_DITHER0,
  180. DDP_COMPONENT_DSI0,
  181. };
  182. static const unsigned int mt8192_mtk_ddp_ext[] = {
  183. DDP_COMPONENT_OVL_2L2,
  184. DDP_COMPONENT_RDMA4,
  185. DDP_COMPONENT_DPI0,
  186. };
  187. static const unsigned int mt8195_mtk_ddp_main[] = {
  188. DDP_COMPONENT_OVL0,
  189. DDP_COMPONENT_RDMA0,
  190. DDP_COMPONENT_COLOR0,
  191. DDP_COMPONENT_CCORR,
  192. DDP_COMPONENT_AAL0,
  193. DDP_COMPONENT_GAMMA,
  194. DDP_COMPONENT_DITHER0,
  195. DDP_COMPONENT_DSC0,
  196. DDP_COMPONENT_MERGE0,
  197. DDP_COMPONENT_DP_INTF0,
  198. };
  199. static const unsigned int mt8195_mtk_ddp_ext[] = {
  200. DDP_COMPONENT_DRM_OVL_ADAPTOR,
  201. DDP_COMPONENT_MERGE5,
  202. DDP_COMPONENT_DP_INTF1,
  203. };
  204. static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
  205. .main_path = mt2701_mtk_ddp_main,
  206. .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
  207. .ext_path = mt2701_mtk_ddp_ext,
  208. .ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
  209. .shadow_register = true,
  210. .mmsys_dev_num = 1,
  211. };
  212. static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
  213. .main_path = mt7623_mtk_ddp_main,
  214. .main_len = ARRAY_SIZE(mt7623_mtk_ddp_main),
  215. .ext_path = mt7623_mtk_ddp_ext,
  216. .ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
  217. .shadow_register = true,
  218. .mmsys_dev_num = 1,
  219. };
  220. static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
  221. .main_path = mt2712_mtk_ddp_main,
  222. .main_len = ARRAY_SIZE(mt2712_mtk_ddp_main),
  223. .ext_path = mt2712_mtk_ddp_ext,
  224. .ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
  225. .third_path = mt2712_mtk_ddp_third,
  226. .third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
  227. .mmsys_dev_num = 1,
  228. };
  229. static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
  230. .main_path = mt8167_mtk_ddp_main,
  231. .main_len = ARRAY_SIZE(mt8167_mtk_ddp_main),
  232. .mmsys_dev_num = 1,
  233. };
  234. static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
  235. .main_path = mt8173_mtk_ddp_main,
  236. .main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
  237. .ext_path = mt8173_mtk_ddp_ext,
  238. .ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
  239. .mmsys_dev_num = 1,
  240. };
  241. static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
  242. .main_path = mt8183_mtk_ddp_main,
  243. .main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
  244. .ext_path = mt8183_mtk_ddp_ext,
  245. .ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
  246. .mmsys_dev_num = 1,
  247. };
  248. static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
  249. .main_path = mt8186_mtk_ddp_main,
  250. .main_len = ARRAY_SIZE(mt8186_mtk_ddp_main),
  251. .ext_path = mt8186_mtk_ddp_ext,
  252. .ext_len = ARRAY_SIZE(mt8186_mtk_ddp_ext),
  253. .mmsys_dev_num = 1,
  254. };
  255. static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = {
  256. .main_path = mt8188_mtk_ddp_main,
  257. .main_len = ARRAY_SIZE(mt8188_mtk_ddp_main),
  258. .conn_routes = mt8188_mtk_ddp_main_routes,
  259. .num_conn_routes = ARRAY_SIZE(mt8188_mtk_ddp_main_routes),
  260. .mmsys_dev_num = 2,
  261. .max_width = 8191,
  262. .min_width = 1,
  263. .min_height = 1,
  264. };
  265. static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
  266. .main_path = mt8192_mtk_ddp_main,
  267. .main_len = ARRAY_SIZE(mt8192_mtk_ddp_main),
  268. .ext_path = mt8192_mtk_ddp_ext,
  269. .ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
  270. .mmsys_dev_num = 1,
  271. };
  272. static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
  273. .main_path = mt8195_mtk_ddp_main,
  274. .main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
  275. .mmsys_dev_num = 2,
  276. .max_width = 8191,
  277. .min_width = 1,
  278. .min_height = 1,
  279. };
  280. static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
  281. .ext_path = mt8195_mtk_ddp_ext,
  282. .ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
  283. .mmsys_id = 1,
  284. .mmsys_dev_num = 2,
  285. .max_width = 8191,
  286. .min_width = 2, /* 2-pixel align when ethdr is bypassed */
  287. .min_height = 1,
  288. };
  289. static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
  290. .mmsys_dev_num = 1,
  291. };
  292. static const struct of_device_id mtk_drm_of_ids[] = {
  293. { .compatible = "mediatek,mt2701-mmsys",
  294. .data = &mt2701_mmsys_driver_data},
  295. { .compatible = "mediatek,mt7623-mmsys",
  296. .data = &mt7623_mmsys_driver_data},
  297. { .compatible = "mediatek,mt2712-mmsys",
  298. .data = &mt2712_mmsys_driver_data},
  299. { .compatible = "mediatek,mt8167-mmsys",
  300. .data = &mt8167_mmsys_driver_data},
  301. { .compatible = "mediatek,mt8173-mmsys",
  302. .data = &mt8173_mmsys_driver_data},
  303. { .compatible = "mediatek,mt8183-mmsys",
  304. .data = &mt8183_mmsys_driver_data},
  305. { .compatible = "mediatek,mt8186-mmsys",
  306. .data = &mt8186_mmsys_driver_data},
  307. { .compatible = "mediatek,mt8188-vdosys0",
  308. .data = &mt8188_vdosys0_driver_data},
  309. { .compatible = "mediatek,mt8188-vdosys1",
  310. .data = &mt8195_vdosys1_driver_data},
  311. { .compatible = "mediatek,mt8192-mmsys",
  312. .data = &mt8192_mmsys_driver_data},
  313. { .compatible = "mediatek,mt8195-mmsys",
  314. .data = &mt8195_vdosys0_driver_data},
  315. { .compatible = "mediatek,mt8195-vdosys0",
  316. .data = &mt8195_vdosys0_driver_data},
  317. { .compatible = "mediatek,mt8195-vdosys1",
  318. .data = &mt8195_vdosys1_driver_data},
  319. { .compatible = "mediatek,mt8365-mmsys",
  320. .data = &mt8365_mmsys_driver_data},
  321. { }
  322. };
  323. MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
  324. static int mtk_drm_match(struct device *dev, const void *data)
  325. {
  326. if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
  327. return true;
  328. return false;
  329. }
  330. static bool mtk_drm_get_all_drm_priv(struct device *dev)
  331. {
  332. struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
  333. struct mtk_drm_private *all_drm_priv[MAX_CRTC];
  334. struct mtk_drm_private *temp_drm_priv;
  335. struct device_node *phandle = dev->parent->of_node;
  336. const struct of_device_id *of_id;
  337. struct device_node *node;
  338. struct device *drm_dev;
  339. unsigned int cnt = 0;
  340. int i, j;
  341. for_each_child_of_node(phandle->parent, node) {
  342. struct platform_device *pdev;
  343. of_id = of_match_node(mtk_drm_of_ids, node);
  344. if (!of_id)
  345. continue;
  346. pdev = of_find_device_by_node(node);
  347. if (!pdev)
  348. continue;
  349. drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
  350. put_device(&pdev->dev);
  351. if (!drm_dev)
  352. continue;
  353. temp_drm_priv = dev_get_drvdata(drm_dev);
  354. put_device(drm_dev);
  355. if (!temp_drm_priv)
  356. continue;
  357. if (temp_drm_priv->data->main_len)
  358. all_drm_priv[CRTC_MAIN] = temp_drm_priv;
  359. else if (temp_drm_priv->data->ext_len)
  360. all_drm_priv[CRTC_EXT] = temp_drm_priv;
  361. else if (temp_drm_priv->data->third_len)
  362. all_drm_priv[CRTC_THIRD] = temp_drm_priv;
  363. if (temp_drm_priv->mtk_drm_bound)
  364. cnt++;
  365. if (cnt == MAX_CRTC) {
  366. of_node_put(node);
  367. break;
  368. }
  369. }
  370. if (drm_priv->data->mmsys_dev_num == cnt) {
  371. for (i = 0; i < cnt; i++)
  372. for (j = 0; j < cnt; j++)
  373. all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
  374. return true;
  375. }
  376. return false;
  377. }
  378. static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
  379. {
  380. const struct mtk_mmsys_driver_data *drv_data = private->data;
  381. int i;
  382. if (drv_data->main_path)
  383. for (i = 0; i < drv_data->main_len; i++)
  384. if (drv_data->main_path[i] == comp_id)
  385. return true;
  386. if (drv_data->ext_path)
  387. for (i = 0; i < drv_data->ext_len; i++)
  388. if (drv_data->ext_path[i] == comp_id)
  389. return true;
  390. if (drv_data->third_path)
  391. for (i = 0; i < drv_data->third_len; i++)
  392. if (drv_data->third_path[i] == comp_id)
  393. return true;
  394. if (drv_data->num_conn_routes)
  395. for (i = 0; i < drv_data->num_conn_routes; i++)
  396. if (drv_data->conn_routes[i].route_ddp == comp_id)
  397. return true;
  398. return false;
  399. }
  400. static int mtk_drm_kms_init(struct drm_device *drm)
  401. {
  402. struct mtk_drm_private *private = drm->dev_private;
  403. struct mtk_drm_private *priv_n;
  404. struct device *dma_dev = NULL;
  405. struct drm_crtc *crtc;
  406. int ret, i, j;
  407. if (drm_firmware_drivers_only())
  408. return -ENODEV;
  409. ret = drmm_mode_config_init(drm);
  410. if (ret)
  411. return ret;
  412. drm->mode_config.min_width = 64;
  413. drm->mode_config.min_height = 64;
  414. /*
  415. * set max width and height as default value(4096x4096).
  416. * this value would be used to check framebuffer size limitation
  417. * at drm_mode_addfb().
  418. */
  419. drm->mode_config.max_width = 4096;
  420. drm->mode_config.max_height = 4096;
  421. drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
  422. drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
  423. for (i = 0; i < private->data->mmsys_dev_num; i++) {
  424. drm->dev_private = private->all_drm_private[i];
  425. ret = component_bind_all(private->all_drm_private[i]->dev, drm);
  426. if (ret) {
  427. while (--i >= 0)
  428. component_unbind_all(private->all_drm_private[i]->dev, drm);
  429. return ret;
  430. }
  431. }
  432. /*
  433. * Ensure internal panels are at the top of the connector list before
  434. * crtc creation.
  435. */
  436. drm_helper_move_panel_connectors_to_head(drm);
  437. /*
  438. * 1. We currently support two fixed data streams, each optional,
  439. * and each statically assigned to a crtc:
  440. * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
  441. * 2. For multi mmsys architecture, crtc path data are located in
  442. * different drm private data structures. Loop through crtc index to
  443. * create crtc from the main path and then ext_path and finally the
  444. * third path.
  445. */
  446. for (i = 0; i < MAX_CRTC; i++) {
  447. for (j = 0; j < private->data->mmsys_dev_num; j++) {
  448. priv_n = private->all_drm_private[j];
  449. if (priv_n->data->max_width)
  450. drm->mode_config.max_width = priv_n->data->max_width;
  451. if (priv_n->data->min_width)
  452. drm->mode_config.min_width = priv_n->data->min_width;
  453. if (priv_n->data->min_height)
  454. drm->mode_config.min_height = priv_n->data->min_height;
  455. if (i == CRTC_MAIN && priv_n->data->main_len) {
  456. ret = mtk_crtc_create(drm, priv_n->data->main_path,
  457. priv_n->data->main_len, j,
  458. priv_n->data->conn_routes,
  459. priv_n->data->num_conn_routes);
  460. if (ret)
  461. goto err_component_unbind;
  462. continue;
  463. } else if (i == CRTC_EXT && priv_n->data->ext_len) {
  464. ret = mtk_crtc_create(drm, priv_n->data->ext_path,
  465. priv_n->data->ext_len, j, NULL, 0);
  466. if (ret)
  467. goto err_component_unbind;
  468. continue;
  469. } else if (i == CRTC_THIRD && priv_n->data->third_len) {
  470. ret = mtk_crtc_create(drm, priv_n->data->third_path,
  471. priv_n->data->third_len, j, NULL, 0);
  472. if (ret)
  473. goto err_component_unbind;
  474. continue;
  475. }
  476. }
  477. }
  478. /* IGT will check if the cursor size is configured */
  479. drm->mode_config.cursor_width = 512;
  480. drm->mode_config.cursor_height = 512;
  481. /* Use OVL device for all DMA memory allocations */
  482. crtc = drm_crtc_from_index(drm, 0);
  483. if (crtc)
  484. dma_dev = mtk_crtc_dma_dev_get(crtc);
  485. if (!dma_dev) {
  486. ret = -ENODEV;
  487. dev_err(drm->dev, "Need at least one OVL device\n");
  488. goto err_component_unbind;
  489. }
  490. for (i = 0; i < private->data->mmsys_dev_num; i++)
  491. private->all_drm_private[i]->dma_dev = dma_dev;
  492. /*
  493. * Configure the DMA segment size to make sure we get contiguous IOVA
  494. * when importing PRIME buffers.
  495. */
  496. dma_set_max_seg_size(dma_dev, UINT_MAX);
  497. ret = drm_vblank_init(drm, MAX_CRTC);
  498. if (ret < 0)
  499. goto err_component_unbind;
  500. drm_kms_helper_poll_init(drm);
  501. drm_mode_config_reset(drm);
  502. return 0;
  503. err_component_unbind:
  504. for (i = 0; i < private->data->mmsys_dev_num; i++)
  505. component_unbind_all(private->all_drm_private[i]->dev, drm);
  506. return ret;
  507. }
  508. static void mtk_drm_kms_deinit(struct drm_device *drm)
  509. {
  510. drm_kms_helper_poll_fini(drm);
  511. drm_atomic_helper_shutdown(drm);
  512. component_unbind_all(drm->dev, drm);
  513. }
  514. DEFINE_DRM_GEM_FOPS(mtk_drm_fops);
  515. /*
  516. * We need to override this because the device used to import the memory is
  517. * not dev->dev, as drm_gem_prime_import() expects.
  518. */
  519. static struct drm_gem_object *mtk_gem_prime_import(struct drm_device *dev,
  520. struct dma_buf *dma_buf)
  521. {
  522. struct mtk_drm_private *private = dev->dev_private;
  523. return drm_gem_prime_import_dev(dev, dma_buf, private->dma_dev);
  524. }
  525. static const struct drm_driver mtk_drm_driver = {
  526. .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
  527. .dumb_create = mtk_gem_dumb_create,
  528. DRM_FBDEV_DMA_DRIVER_OPS,
  529. .gem_prime_import = mtk_gem_prime_import,
  530. .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
  531. .fops = &mtk_drm_fops,
  532. .name = DRIVER_NAME,
  533. .desc = DRIVER_DESC,
  534. .major = DRIVER_MAJOR,
  535. .minor = DRIVER_MINOR,
  536. };
  537. static int compare_dev(struct device *dev, void *data)
  538. {
  539. return dev == (struct device *)data;
  540. }
  541. static int mtk_drm_bind(struct device *dev)
  542. {
  543. struct mtk_drm_private *private = dev_get_drvdata(dev);
  544. struct platform_device *pdev;
  545. struct drm_device *drm;
  546. int ret, i;
  547. pdev = of_find_device_by_node(private->mutex_node);
  548. if (!pdev) {
  549. dev_err(dev, "Waiting for disp-mutex device %pOF\n",
  550. private->mutex_node);
  551. of_node_put(private->mutex_node);
  552. return -EPROBE_DEFER;
  553. }
  554. private->mutex_dev = &pdev->dev;
  555. private->mtk_drm_bound = true;
  556. private->dev = dev;
  557. if (!mtk_drm_get_all_drm_priv(dev))
  558. return 0;
  559. drm = drm_dev_alloc(&mtk_drm_driver, dev);
  560. if (IS_ERR(drm)) {
  561. ret = PTR_ERR(drm);
  562. goto err_put_dev;
  563. }
  564. private->drm_master = true;
  565. drm->dev_private = private;
  566. for (i = 0; i < private->data->mmsys_dev_num; i++)
  567. private->all_drm_private[i]->drm = drm;
  568. ret = mtk_drm_kms_init(drm);
  569. if (ret < 0)
  570. goto err_free;
  571. ret = drm_dev_register(drm, 0);
  572. if (ret < 0)
  573. goto err_deinit;
  574. drm_client_setup(drm, NULL);
  575. return 0;
  576. err_deinit:
  577. mtk_drm_kms_deinit(drm);
  578. err_free:
  579. private->drm = NULL;
  580. drm_dev_put(drm);
  581. for (i = 0; i < private->data->mmsys_dev_num; i++)
  582. private->all_drm_private[i]->drm = NULL;
  583. err_put_dev:
  584. put_device(private->mutex_dev);
  585. return ret;
  586. }
  587. static void mtk_drm_unbind(struct device *dev)
  588. {
  589. struct mtk_drm_private *private = dev_get_drvdata(dev);
  590. /* for multi mmsys dev, unregister drm dev in mmsys master */
  591. if (private->drm_master) {
  592. drm_dev_unregister(private->drm);
  593. mtk_drm_kms_deinit(private->drm);
  594. drm_dev_put(private->drm);
  595. put_device(private->mutex_dev);
  596. }
  597. private->mtk_drm_bound = false;
  598. private->drm_master = false;
  599. private->drm = NULL;
  600. }
  601. static const struct component_master_ops mtk_drm_ops = {
  602. .bind = mtk_drm_bind,
  603. .unbind = mtk_drm_unbind,
  604. };
  605. static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
  606. { .compatible = "mediatek,mt8167-disp-aal",
  607. .data = (void *)MTK_DISP_AAL},
  608. { .compatible = "mediatek,mt8173-disp-aal",
  609. .data = (void *)MTK_DISP_AAL},
  610. { .compatible = "mediatek,mt8183-disp-aal",
  611. .data = (void *)MTK_DISP_AAL},
  612. { .compatible = "mediatek,mt8192-disp-aal",
  613. .data = (void *)MTK_DISP_AAL},
  614. { .compatible = "mediatek,mt8167-disp-ccorr",
  615. .data = (void *)MTK_DISP_CCORR },
  616. { .compatible = "mediatek,mt8183-disp-ccorr",
  617. .data = (void *)MTK_DISP_CCORR },
  618. { .compatible = "mediatek,mt8192-disp-ccorr",
  619. .data = (void *)MTK_DISP_CCORR },
  620. { .compatible = "mediatek,mt2701-disp-color",
  621. .data = (void *)MTK_DISP_COLOR },
  622. { .compatible = "mediatek,mt8167-disp-color",
  623. .data = (void *)MTK_DISP_COLOR },
  624. { .compatible = "mediatek,mt8173-disp-color",
  625. .data = (void *)MTK_DISP_COLOR },
  626. { .compatible = "mediatek,mt8167-disp-dither",
  627. .data = (void *)MTK_DISP_DITHER },
  628. { .compatible = "mediatek,mt8183-disp-dither",
  629. .data = (void *)MTK_DISP_DITHER },
  630. { .compatible = "mediatek,mt8195-disp-dsc",
  631. .data = (void *)MTK_DISP_DSC },
  632. { .compatible = "mediatek,mt8167-disp-gamma",
  633. .data = (void *)MTK_DISP_GAMMA, },
  634. { .compatible = "mediatek,mt8173-disp-gamma",
  635. .data = (void *)MTK_DISP_GAMMA, },
  636. { .compatible = "mediatek,mt8183-disp-gamma",
  637. .data = (void *)MTK_DISP_GAMMA, },
  638. { .compatible = "mediatek,mt8195-disp-gamma",
  639. .data = (void *)MTK_DISP_GAMMA, },
  640. { .compatible = "mediatek,mt8195-disp-merge",
  641. .data = (void *)MTK_DISP_MERGE },
  642. { .compatible = "mediatek,mt2701-disp-mutex",
  643. .data = (void *)MTK_DISP_MUTEX },
  644. { .compatible = "mediatek,mt2712-disp-mutex",
  645. .data = (void *)MTK_DISP_MUTEX },
  646. { .compatible = "mediatek,mt8167-disp-mutex",
  647. .data = (void *)MTK_DISP_MUTEX },
  648. { .compatible = "mediatek,mt8173-disp-mutex",
  649. .data = (void *)MTK_DISP_MUTEX },
  650. { .compatible = "mediatek,mt8183-disp-mutex",
  651. .data = (void *)MTK_DISP_MUTEX },
  652. { .compatible = "mediatek,mt8186-disp-mutex",
  653. .data = (void *)MTK_DISP_MUTEX },
  654. { .compatible = "mediatek,mt8188-disp-mutex",
  655. .data = (void *)MTK_DISP_MUTEX },
  656. { .compatible = "mediatek,mt8192-disp-mutex",
  657. .data = (void *)MTK_DISP_MUTEX },
  658. { .compatible = "mediatek,mt8195-disp-mutex",
  659. .data = (void *)MTK_DISP_MUTEX },
  660. { .compatible = "mediatek,mt8365-disp-mutex",
  661. .data = (void *)MTK_DISP_MUTEX },
  662. { .compatible = "mediatek,mt8173-disp-od",
  663. .data = (void *)MTK_DISP_OD },
  664. { .compatible = "mediatek,mt2701-disp-ovl",
  665. .data = (void *)MTK_DISP_OVL },
  666. { .compatible = "mediatek,mt8167-disp-ovl",
  667. .data = (void *)MTK_DISP_OVL },
  668. { .compatible = "mediatek,mt8173-disp-ovl",
  669. .data = (void *)MTK_DISP_OVL },
  670. { .compatible = "mediatek,mt8183-disp-ovl",
  671. .data = (void *)MTK_DISP_OVL },
  672. { .compatible = "mediatek,mt8192-disp-ovl",
  673. .data = (void *)MTK_DISP_OVL },
  674. { .compatible = "mediatek,mt8195-disp-ovl",
  675. .data = (void *)MTK_DISP_OVL },
  676. { .compatible = "mediatek,mt8183-disp-ovl-2l",
  677. .data = (void *)MTK_DISP_OVL_2L },
  678. { .compatible = "mediatek,mt8192-disp-ovl-2l",
  679. .data = (void *)MTK_DISP_OVL_2L },
  680. { .compatible = "mediatek,mt8192-disp-postmask",
  681. .data = (void *)MTK_DISP_POSTMASK },
  682. { .compatible = "mediatek,mt2701-disp-pwm",
  683. .data = (void *)MTK_DISP_BLS },
  684. { .compatible = "mediatek,mt8167-disp-pwm",
  685. .data = (void *)MTK_DISP_PWM },
  686. { .compatible = "mediatek,mt8173-disp-pwm",
  687. .data = (void *)MTK_DISP_PWM },
  688. { .compatible = "mediatek,mt2701-disp-rdma",
  689. .data = (void *)MTK_DISP_RDMA },
  690. { .compatible = "mediatek,mt8167-disp-rdma",
  691. .data = (void *)MTK_DISP_RDMA },
  692. { .compatible = "mediatek,mt8173-disp-rdma",
  693. .data = (void *)MTK_DISP_RDMA },
  694. { .compatible = "mediatek,mt8183-disp-rdma",
  695. .data = (void *)MTK_DISP_RDMA },
  696. { .compatible = "mediatek,mt8195-disp-rdma",
  697. .data = (void *)MTK_DISP_RDMA },
  698. { .compatible = "mediatek,mt8173-disp-ufoe",
  699. .data = (void *)MTK_DISP_UFOE },
  700. { .compatible = "mediatek,mt8173-disp-wdma",
  701. .data = (void *)MTK_DISP_WDMA },
  702. { .compatible = "mediatek,mt2701-dpi",
  703. .data = (void *)MTK_DPI },
  704. { .compatible = "mediatek,mt8167-dsi",
  705. .data = (void *)MTK_DSI },
  706. { .compatible = "mediatek,mt8173-dpi",
  707. .data = (void *)MTK_DPI },
  708. { .compatible = "mediatek,mt8183-dpi",
  709. .data = (void *)MTK_DPI },
  710. { .compatible = "mediatek,mt8186-dpi",
  711. .data = (void *)MTK_DPI },
  712. { .compatible = "mediatek,mt8188-dp-intf",
  713. .data = (void *)MTK_DP_INTF },
  714. { .compatible = "mediatek,mt8192-dpi",
  715. .data = (void *)MTK_DPI },
  716. { .compatible = "mediatek,mt8195-dp-intf",
  717. .data = (void *)MTK_DP_INTF },
  718. { .compatible = "mediatek,mt8195-dpi",
  719. .data = (void *)MTK_DPI },
  720. { .compatible = "mediatek,mt2701-dsi",
  721. .data = (void *)MTK_DSI },
  722. { .compatible = "mediatek,mt8173-dsi",
  723. .data = (void *)MTK_DSI },
  724. { .compatible = "mediatek,mt8183-dsi",
  725. .data = (void *)MTK_DSI },
  726. { .compatible = "mediatek,mt8186-dsi",
  727. .data = (void *)MTK_DSI },
  728. { .compatible = "mediatek,mt8188-dsi",
  729. .data = (void *)MTK_DSI },
  730. { }
  731. };
  732. static int mtk_drm_of_get_ddp_comp_type(struct device_node *node, enum mtk_ddp_comp_type *ctype)
  733. {
  734. const struct of_device_id *of_id = of_match_node(mtk_ddp_comp_dt_ids, node);
  735. if (!of_id)
  736. return -EINVAL;
  737. *ctype = (enum mtk_ddp_comp_type)((uintptr_t)of_id->data);
  738. return 0;
  739. }
  740. static int mtk_drm_of_get_ddp_ep_cid(struct device_node *node,
  741. int output_port, enum mtk_crtc_path crtc_path,
  742. struct device_node **next, unsigned int *cid)
  743. {
  744. struct device_node *ep_dev_node, *ep_out;
  745. enum mtk_ddp_comp_type comp_type;
  746. int ret;
  747. ep_out = of_graph_get_endpoint_by_regs(node, output_port, crtc_path);
  748. if (!ep_out)
  749. return -ENOENT;
  750. ep_dev_node = of_graph_get_remote_port_parent(ep_out);
  751. of_node_put(ep_out);
  752. if (!ep_dev_node)
  753. return -EINVAL;
  754. /*
  755. * Pass the next node pointer regardless of failures in the later code
  756. * so that if this function is called in a loop it will walk through all
  757. * of the subsequent endpoints anyway.
  758. */
  759. *next = ep_dev_node;
  760. if (!of_device_is_available(ep_dev_node))
  761. return -ENODEV;
  762. ret = mtk_drm_of_get_ddp_comp_type(ep_dev_node, &comp_type);
  763. if (ret) {
  764. if (mtk_ovl_adaptor_is_comp_present(ep_dev_node)) {
  765. *cid = (unsigned int)DDP_COMPONENT_DRM_OVL_ADAPTOR;
  766. return 0;
  767. }
  768. return ret;
  769. }
  770. ret = mtk_ddp_comp_get_id(ep_dev_node, comp_type);
  771. if (ret < 0)
  772. return ret;
  773. /* All ok! Pass the Component ID to the caller. */
  774. *cid = (unsigned int)ret;
  775. return 0;
  776. }
  777. /**
  778. * mtk_drm_of_ddp_path_build_one - Build a Display HW Pipeline for a CRTC Path
  779. * @dev: The mediatek-drm device
  780. * @cpath: CRTC Path relative to a VDO or MMSYS
  781. * @out_path: Pointer to an array that will contain the new pipeline
  782. * @out_path_len: Number of entries in the pipeline array
  783. *
  784. * MediaTek SoCs can use different DDP hardware pipelines (or paths) depending
  785. * on the board-specific desired display configuration; this function walks
  786. * through all of the output endpoints starting from a VDO or MMSYS hardware
  787. * instance and builds the right pipeline as specified in device trees.
  788. *
  789. * Return:
  790. * * %0 - Display HW Pipeline successfully built and validated
  791. * * %-ENOENT - Display pipeline was not specified in device tree
  792. * * %-EINVAL - Display pipeline built but validation failed
  793. * * %-ENOMEM - Failure to allocate pipeline array to pass to the caller
  794. */
  795. static int mtk_drm_of_ddp_path_build_one(struct device *dev, enum mtk_crtc_path cpath,
  796. const unsigned int **out_path,
  797. unsigned int *out_path_len)
  798. {
  799. struct device_node *next = NULL, *prev, *vdo = dev->parent->of_node;
  800. unsigned int temp_path[DDP_COMPONENT_DRM_ID_MAX] = { 0 };
  801. unsigned int *final_ddp_path;
  802. unsigned short int idx = 0;
  803. bool ovl_adaptor_comp_added = false;
  804. int ret;
  805. /* Get the first entry for the temp_path array */
  806. ret = mtk_drm_of_get_ddp_ep_cid(vdo, 0, cpath, &next, &temp_path[idx]);
  807. if (ret) {
  808. if (next && temp_path[idx] == DDP_COMPONENT_DRM_OVL_ADAPTOR) {
  809. dev_dbg(dev, "Adding OVL Adaptor for %pOF\n", next);
  810. ovl_adaptor_comp_added = true;
  811. } else {
  812. if (next)
  813. dev_err(dev, "Invalid component %pOF\n", next);
  814. else
  815. dev_err(dev, "Cannot find first endpoint for path %d\n", cpath);
  816. return ret;
  817. }
  818. }
  819. idx++;
  820. /*
  821. * Walk through port outputs until we reach the last valid mediatek-drm component.
  822. * To be valid, this must end with an "invalid" component that is a display node.
  823. */
  824. do {
  825. prev = next;
  826. ret = mtk_drm_of_get_ddp_ep_cid(next, 1, cpath, &next, &temp_path[idx]);
  827. of_node_put(prev);
  828. if (ret) {
  829. of_node_put(next);
  830. break;
  831. }
  832. /*
  833. * If this is an OVL adaptor exclusive component and one of those
  834. * was already added, don't add another instance of the generic
  835. * DDP_COMPONENT_OVL_ADAPTOR, as this is used only to decide whether
  836. * to probe that component master driver of which only one instance
  837. * is needed and possible.
  838. */
  839. if (temp_path[idx] == DDP_COMPONENT_DRM_OVL_ADAPTOR) {
  840. if (!ovl_adaptor_comp_added)
  841. ovl_adaptor_comp_added = true;
  842. else
  843. idx--;
  844. }
  845. } while (++idx < DDP_COMPONENT_DRM_ID_MAX);
  846. /*
  847. * The device component might not be enabled: in that case, don't
  848. * check the last entry and just report that the device is missing.
  849. */
  850. if (ret == -ENODEV)
  851. return ret;
  852. /* If the last entry is not a final display output, the configuration is wrong */
  853. switch (temp_path[idx - 1]) {
  854. case DDP_COMPONENT_DP_INTF0:
  855. case DDP_COMPONENT_DP_INTF1:
  856. case DDP_COMPONENT_DPI0:
  857. case DDP_COMPONENT_DPI1:
  858. case DDP_COMPONENT_DSI0:
  859. case DDP_COMPONENT_DSI1:
  860. case DDP_COMPONENT_DSI2:
  861. case DDP_COMPONENT_DSI3:
  862. break;
  863. default:
  864. dev_err(dev, "Invalid display hw pipeline. Last component: %d (ret=%d)\n",
  865. temp_path[idx - 1], ret);
  866. return -EINVAL;
  867. }
  868. final_ddp_path = devm_kmemdup(dev, temp_path, idx * sizeof(temp_path[0]), GFP_KERNEL);
  869. if (!final_ddp_path)
  870. return -ENOMEM;
  871. dev_dbg(dev, "Display HW Pipeline built with %d components.\n", idx);
  872. /* Pipeline built! */
  873. *out_path = final_ddp_path;
  874. *out_path_len = idx;
  875. return 0;
  876. }
  877. static int mtk_drm_of_ddp_path_build(struct device *dev, struct device_node *node,
  878. struct mtk_mmsys_driver_data *data)
  879. {
  880. struct device_node *ep_node;
  881. struct of_endpoint of_ep;
  882. bool output_present[MAX_CRTC] = { false };
  883. int ret;
  884. for_each_endpoint_of_node(node, ep_node) {
  885. ret = of_graph_parse_endpoint(ep_node, &of_ep);
  886. if (ret) {
  887. dev_err_probe(dev, ret, "Cannot parse endpoint\n");
  888. break;
  889. }
  890. if (of_ep.id >= MAX_CRTC) {
  891. ret = dev_err_probe(dev, -EINVAL,
  892. "Invalid endpoint%u number\n", of_ep.port);
  893. break;
  894. }
  895. output_present[of_ep.id] = true;
  896. }
  897. if (ret) {
  898. of_node_put(ep_node);
  899. return ret;
  900. }
  901. if (output_present[CRTC_MAIN]) {
  902. ret = mtk_drm_of_ddp_path_build_one(dev, CRTC_MAIN,
  903. &data->main_path, &data->main_len);
  904. if (ret && ret != -ENODEV)
  905. return ret;
  906. }
  907. if (output_present[CRTC_EXT]) {
  908. ret = mtk_drm_of_ddp_path_build_one(dev, CRTC_EXT,
  909. &data->ext_path, &data->ext_len);
  910. if (ret && ret != -ENODEV)
  911. return ret;
  912. }
  913. if (output_present[CRTC_THIRD]) {
  914. ret = mtk_drm_of_ddp_path_build_one(dev, CRTC_THIRD,
  915. &data->third_path, &data->third_len);
  916. if (ret && ret != -ENODEV)
  917. return ret;
  918. }
  919. return 0;
  920. }
  921. static int mtk_drm_probe(struct platform_device *pdev)
  922. {
  923. struct device *dev = &pdev->dev;
  924. struct device_node *phandle = dev->parent->of_node;
  925. const struct of_device_id *of_id;
  926. struct mtk_drm_private *private;
  927. struct mtk_mmsys_driver_data *mtk_drm_data;
  928. struct device_node *node;
  929. struct component_match *match = NULL;
  930. struct platform_device *ovl_adaptor;
  931. int ret;
  932. int i;
  933. private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
  934. if (!private)
  935. return -ENOMEM;
  936. private->mmsys_dev = dev->parent;
  937. if (!private->mmsys_dev) {
  938. dev_err(dev, "Failed to get MMSYS device\n");
  939. return -ENODEV;
  940. }
  941. of_id = of_match_node(mtk_drm_of_ids, phandle);
  942. if (!of_id)
  943. return -ENODEV;
  944. mtk_drm_data = (struct mtk_mmsys_driver_data *)of_id->data;
  945. if (!mtk_drm_data)
  946. return -EINVAL;
  947. /* Try to build the display pipeline from devicetree graphs */
  948. if (of_graph_is_present(phandle)) {
  949. dev_dbg(dev, "Building display pipeline for MMSYS %u\n",
  950. mtk_drm_data->mmsys_id);
  951. private->data = devm_kmemdup(dev, mtk_drm_data,
  952. sizeof(*mtk_drm_data), GFP_KERNEL);
  953. if (!private->data)
  954. return -ENOMEM;
  955. ret = mtk_drm_of_ddp_path_build(dev, phandle, private->data);
  956. if (ret)
  957. return ret;
  958. } else {
  959. /* No devicetree graphs support: go with hardcoded paths if present */
  960. dev_dbg(dev, "Using hardcoded paths for MMSYS %u\n", mtk_drm_data->mmsys_id);
  961. private->data = mtk_drm_data;
  962. }
  963. private->all_drm_private = devm_kmalloc_array(dev, private->data->mmsys_dev_num,
  964. sizeof(*private->all_drm_private),
  965. GFP_KERNEL);
  966. if (!private->all_drm_private)
  967. return -ENOMEM;
  968. /* Bringup ovl_adaptor */
  969. if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVL_ADAPTOR)) {
  970. ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovl-adaptor",
  971. PLATFORM_DEVID_AUTO,
  972. (void *)private->mmsys_dev,
  973. sizeof(*private->mmsys_dev));
  974. private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR].dev = &ovl_adaptor->dev;
  975. mtk_ddp_comp_init(dev, NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR],
  976. DDP_COMPONENT_DRM_OVL_ADAPTOR);
  977. component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
  978. }
  979. /* Iterate over sibling DISP function blocks */
  980. for_each_child_of_node(phandle->parent, node) {
  981. enum mtk_ddp_comp_type comp_type;
  982. int comp_id;
  983. ret = mtk_drm_of_get_ddp_comp_type(node, &comp_type);
  984. if (ret)
  985. continue;
  986. if (!of_device_is_available(node)) {
  987. dev_dbg(dev, "Skipping disabled component %pOF\n",
  988. node);
  989. continue;
  990. }
  991. if (comp_type == MTK_DISP_MUTEX) {
  992. int id;
  993. id = of_alias_get_id(node, "mutex");
  994. if (id < 0 || id == private->data->mmsys_id) {
  995. private->mutex_node = of_node_get(node);
  996. dev_dbg(dev, "get mutex for mmsys %d", private->data->mmsys_id);
  997. }
  998. continue;
  999. }
  1000. comp_id = mtk_ddp_comp_get_id(node, comp_type);
  1001. if (comp_id < 0) {
  1002. dev_warn(dev, "Skipping unknown component %pOF\n",
  1003. node);
  1004. continue;
  1005. }
  1006. if (!mtk_drm_find_mmsys_comp(private, comp_id))
  1007. continue;
  1008. private->comp_node[comp_id] = of_node_get(node);
  1009. /*
  1010. * Currently only the AAL, CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
  1011. * blocks have separate component platform drivers and initialize their own
  1012. * DDP component structure. The others are initialized here.
  1013. */
  1014. if (comp_type == MTK_DISP_AAL ||
  1015. comp_type == MTK_DISP_CCORR ||
  1016. comp_type == MTK_DISP_COLOR ||
  1017. comp_type == MTK_DISP_GAMMA ||
  1018. comp_type == MTK_DISP_MERGE ||
  1019. comp_type == MTK_DISP_OVL ||
  1020. comp_type == MTK_DISP_OVL_2L ||
  1021. comp_type == MTK_DISP_OVL_ADAPTOR ||
  1022. comp_type == MTK_DISP_RDMA ||
  1023. comp_type == MTK_DP_INTF ||
  1024. comp_type == MTK_DPI ||
  1025. comp_type == MTK_DSI) {
  1026. dev_info(dev, "Adding component match for %pOF\n",
  1027. node);
  1028. drm_of_component_match_add(dev, &match, component_compare_of,
  1029. node);
  1030. }
  1031. ret = mtk_ddp_comp_init(dev, node, &private->ddp_comp[comp_id], comp_id);
  1032. if (ret) {
  1033. of_node_put(node);
  1034. goto err_node;
  1035. }
  1036. }
  1037. if (!private->mutex_node) {
  1038. dev_err(dev, "Failed to find disp-mutex node\n");
  1039. ret = -ENODEV;
  1040. goto err_node;
  1041. }
  1042. pm_runtime_enable(dev);
  1043. platform_set_drvdata(pdev, private);
  1044. ret = component_master_add_with_match(dev, &mtk_drm_ops, match);
  1045. if (ret)
  1046. goto err_pm;
  1047. return 0;
  1048. err_pm:
  1049. pm_runtime_disable(dev);
  1050. err_node:
  1051. of_node_put(private->mutex_node);
  1052. for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
  1053. of_node_put(private->comp_node[i]);
  1054. return ret;
  1055. }
  1056. static void mtk_drm_remove(struct platform_device *pdev)
  1057. {
  1058. struct mtk_drm_private *private = platform_get_drvdata(pdev);
  1059. int i;
  1060. component_master_del(&pdev->dev, &mtk_drm_ops);
  1061. pm_runtime_disable(&pdev->dev);
  1062. of_node_put(private->mutex_node);
  1063. for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
  1064. of_node_put(private->comp_node[i]);
  1065. }
  1066. static void mtk_drm_shutdown(struct platform_device *pdev)
  1067. {
  1068. struct mtk_drm_private *private = platform_get_drvdata(pdev);
  1069. drm_atomic_helper_shutdown(private->drm);
  1070. }
  1071. static int mtk_drm_sys_prepare(struct device *dev)
  1072. {
  1073. struct mtk_drm_private *private = dev_get_drvdata(dev);
  1074. struct drm_device *drm = private->drm;
  1075. if (private->drm_master)
  1076. return drm_mode_config_helper_suspend(drm);
  1077. else
  1078. return 0;
  1079. }
  1080. static void mtk_drm_sys_complete(struct device *dev)
  1081. {
  1082. struct mtk_drm_private *private = dev_get_drvdata(dev);
  1083. struct drm_device *drm = private->drm;
  1084. int ret = 0;
  1085. if (private->drm_master)
  1086. ret = drm_mode_config_helper_resume(drm);
  1087. if (ret)
  1088. dev_err(dev, "Failed to resume\n");
  1089. }
  1090. static const struct dev_pm_ops mtk_drm_pm_ops = {
  1091. .prepare = mtk_drm_sys_prepare,
  1092. .complete = mtk_drm_sys_complete,
  1093. };
  1094. static struct platform_driver mtk_drm_platform_driver = {
  1095. .probe = mtk_drm_probe,
  1096. .remove = mtk_drm_remove,
  1097. .shutdown = mtk_drm_shutdown,
  1098. .driver = {
  1099. .name = "mediatek-drm",
  1100. .pm = &mtk_drm_pm_ops,
  1101. },
  1102. };
  1103. static struct platform_driver * const mtk_drm_drivers[] = {
  1104. &mtk_disp_aal_driver,
  1105. &mtk_disp_ccorr_driver,
  1106. &mtk_disp_color_driver,
  1107. &mtk_disp_gamma_driver,
  1108. &mtk_disp_merge_driver,
  1109. &mtk_disp_ovl_adaptor_driver,
  1110. &mtk_disp_ovl_driver,
  1111. &mtk_disp_rdma_driver,
  1112. &mtk_dpi_driver,
  1113. &mtk_drm_platform_driver,
  1114. &mtk_dsi_driver,
  1115. &mtk_ethdr_driver,
  1116. &mtk_mdp_rdma_driver,
  1117. &mtk_padding_driver,
  1118. };
  1119. static int __init mtk_drm_init(void)
  1120. {
  1121. return platform_register_drivers(mtk_drm_drivers,
  1122. ARRAY_SIZE(mtk_drm_drivers));
  1123. }
  1124. static void __exit mtk_drm_exit(void)
  1125. {
  1126. platform_unregister_drivers(mtk_drm_drivers,
  1127. ARRAY_SIZE(mtk_drm_drivers));
  1128. }
  1129. module_init(mtk_drm_init);
  1130. module_exit(mtk_drm_exit);
  1131. MODULE_AUTHOR("YT SHEN <yt.shen@mediatek.com>");
  1132. MODULE_DESCRIPTION("Mediatek SoC DRM driver");
  1133. MODULE_LICENSE("GPL v2");