mtk_drm_drv.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  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/drm_atomic.h>
  14. #include <drm/drm_atomic_helper.h>
  15. #include <drm/drm_drv.h>
  16. #include <drm/drm_fbdev_dma.h>
  17. #include <drm/drm_fourcc.h>
  18. #include <drm/drm_gem.h>
  19. #include <drm/drm_gem_framebuffer_helper.h>
  20. #include <drm/drm_ioctl.h>
  21. #include <drm/drm_of.h>
  22. #include <drm/drm_probe_helper.h>
  23. #include <drm/drm_vblank.h>
  24. #include "mtk_crtc.h"
  25. #include "mtk_ddp_comp.h"
  26. #include "mtk_drm_drv.h"
  27. #include "mtk_gem.h"
  28. #define DRIVER_NAME "mediatek"
  29. #define DRIVER_DESC "Mediatek SoC DRM"
  30. #define DRIVER_DATE "20150513"
  31. #define DRIVER_MAJOR 1
  32. #define DRIVER_MINOR 0
  33. static const struct drm_mode_config_helper_funcs mtk_drm_mode_config_helpers = {
  34. .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
  35. };
  36. static struct drm_framebuffer *
  37. mtk_drm_mode_fb_create(struct drm_device *dev,
  38. struct drm_file *file,
  39. const struct drm_mode_fb_cmd2 *cmd)
  40. {
  41. const struct drm_format_info *info = drm_get_format_info(dev, cmd);
  42. if (info->num_planes != 1)
  43. return ERR_PTR(-EINVAL);
  44. return drm_gem_fb_create(dev, file, cmd);
  45. }
  46. static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = {
  47. .fb_create = mtk_drm_mode_fb_create,
  48. .atomic_check = drm_atomic_helper_check,
  49. .atomic_commit = drm_atomic_helper_commit,
  50. };
  51. static const unsigned int mt2701_mtk_ddp_main[] = {
  52. DDP_COMPONENT_OVL0,
  53. DDP_COMPONENT_RDMA0,
  54. DDP_COMPONENT_COLOR0,
  55. DDP_COMPONENT_BLS,
  56. DDP_COMPONENT_DSI0,
  57. };
  58. static const unsigned int mt2701_mtk_ddp_ext[] = {
  59. DDP_COMPONENT_RDMA1,
  60. DDP_COMPONENT_DPI0,
  61. };
  62. static const unsigned int mt7623_mtk_ddp_main[] = {
  63. DDP_COMPONENT_OVL0,
  64. DDP_COMPONENT_RDMA0,
  65. DDP_COMPONENT_COLOR0,
  66. DDP_COMPONENT_BLS,
  67. DDP_COMPONENT_DPI0,
  68. };
  69. static const unsigned int mt7623_mtk_ddp_ext[] = {
  70. DDP_COMPONENT_RDMA1,
  71. DDP_COMPONENT_DSI0,
  72. };
  73. static const unsigned int mt2712_mtk_ddp_main[] = {
  74. DDP_COMPONENT_OVL0,
  75. DDP_COMPONENT_COLOR0,
  76. DDP_COMPONENT_AAL0,
  77. DDP_COMPONENT_OD0,
  78. DDP_COMPONENT_RDMA0,
  79. DDP_COMPONENT_DPI0,
  80. DDP_COMPONENT_PWM0,
  81. };
  82. static const unsigned int mt2712_mtk_ddp_ext[] = {
  83. DDP_COMPONENT_OVL1,
  84. DDP_COMPONENT_COLOR1,
  85. DDP_COMPONENT_AAL1,
  86. DDP_COMPONENT_OD1,
  87. DDP_COMPONENT_RDMA1,
  88. DDP_COMPONENT_DPI1,
  89. DDP_COMPONENT_PWM1,
  90. };
  91. static const unsigned int mt2712_mtk_ddp_third[] = {
  92. DDP_COMPONENT_RDMA2,
  93. DDP_COMPONENT_DSI3,
  94. DDP_COMPONENT_PWM2,
  95. };
  96. static unsigned int mt8167_mtk_ddp_main[] = {
  97. DDP_COMPONENT_OVL0,
  98. DDP_COMPONENT_COLOR0,
  99. DDP_COMPONENT_CCORR,
  100. DDP_COMPONENT_AAL0,
  101. DDP_COMPONENT_GAMMA,
  102. DDP_COMPONENT_DITHER0,
  103. DDP_COMPONENT_RDMA0,
  104. DDP_COMPONENT_DSI0,
  105. };
  106. static const unsigned int mt8173_mtk_ddp_main[] = {
  107. DDP_COMPONENT_OVL0,
  108. DDP_COMPONENT_COLOR0,
  109. DDP_COMPONENT_AAL0,
  110. DDP_COMPONENT_OD0,
  111. DDP_COMPONENT_RDMA0,
  112. DDP_COMPONENT_UFOE,
  113. DDP_COMPONENT_DSI0,
  114. DDP_COMPONENT_PWM0,
  115. };
  116. static const unsigned int mt8173_mtk_ddp_ext[] = {
  117. DDP_COMPONENT_OVL1,
  118. DDP_COMPONENT_COLOR1,
  119. DDP_COMPONENT_GAMMA,
  120. DDP_COMPONENT_RDMA1,
  121. DDP_COMPONENT_DPI0,
  122. };
  123. static const unsigned int mt8183_mtk_ddp_main[] = {
  124. DDP_COMPONENT_OVL0,
  125. DDP_COMPONENT_OVL_2L0,
  126. DDP_COMPONENT_RDMA0,
  127. DDP_COMPONENT_COLOR0,
  128. DDP_COMPONENT_CCORR,
  129. DDP_COMPONENT_AAL0,
  130. DDP_COMPONENT_GAMMA,
  131. DDP_COMPONENT_DITHER0,
  132. DDP_COMPONENT_DSI0,
  133. };
  134. static const unsigned int mt8183_mtk_ddp_ext[] = {
  135. DDP_COMPONENT_OVL_2L1,
  136. DDP_COMPONENT_RDMA1,
  137. DDP_COMPONENT_DPI0,
  138. };
  139. static const unsigned int mt8186_mtk_ddp_main[] = {
  140. DDP_COMPONENT_OVL0,
  141. DDP_COMPONENT_RDMA0,
  142. DDP_COMPONENT_COLOR0,
  143. DDP_COMPONENT_CCORR,
  144. DDP_COMPONENT_AAL0,
  145. DDP_COMPONENT_GAMMA,
  146. DDP_COMPONENT_POSTMASK0,
  147. DDP_COMPONENT_DITHER0,
  148. DDP_COMPONENT_DSI0,
  149. };
  150. static const unsigned int mt8186_mtk_ddp_ext[] = {
  151. DDP_COMPONENT_OVL_2L0,
  152. DDP_COMPONENT_RDMA1,
  153. DDP_COMPONENT_DPI0,
  154. };
  155. static const unsigned int mt8188_mtk_ddp_main[] = {
  156. DDP_COMPONENT_OVL0,
  157. DDP_COMPONENT_RDMA0,
  158. DDP_COMPONENT_COLOR0,
  159. DDP_COMPONENT_CCORR,
  160. DDP_COMPONENT_AAL0,
  161. DDP_COMPONENT_GAMMA,
  162. DDP_COMPONENT_POSTMASK0,
  163. DDP_COMPONENT_DITHER0,
  164. };
  165. static const struct mtk_drm_route mt8188_mtk_ddp_main_routes[] = {
  166. {0, DDP_COMPONENT_DP_INTF0},
  167. {0, DDP_COMPONENT_DSI0},
  168. };
  169. static const unsigned int mt8192_mtk_ddp_main[] = {
  170. DDP_COMPONENT_OVL0,
  171. DDP_COMPONENT_OVL_2L0,
  172. DDP_COMPONENT_RDMA0,
  173. DDP_COMPONENT_COLOR0,
  174. DDP_COMPONENT_CCORR,
  175. DDP_COMPONENT_AAL0,
  176. DDP_COMPONENT_GAMMA,
  177. DDP_COMPONENT_POSTMASK0,
  178. DDP_COMPONENT_DITHER0,
  179. DDP_COMPONENT_DSI0,
  180. };
  181. static const unsigned int mt8192_mtk_ddp_ext[] = {
  182. DDP_COMPONENT_OVL_2L2,
  183. DDP_COMPONENT_RDMA4,
  184. DDP_COMPONENT_DPI0,
  185. };
  186. static const unsigned int mt8195_mtk_ddp_main[] = {
  187. DDP_COMPONENT_OVL0,
  188. DDP_COMPONENT_RDMA0,
  189. DDP_COMPONENT_COLOR0,
  190. DDP_COMPONENT_CCORR,
  191. DDP_COMPONENT_AAL0,
  192. DDP_COMPONENT_GAMMA,
  193. DDP_COMPONENT_DITHER0,
  194. DDP_COMPONENT_DSC0,
  195. DDP_COMPONENT_MERGE0,
  196. DDP_COMPONENT_DP_INTF0,
  197. };
  198. static const unsigned int mt8195_mtk_ddp_ext[] = {
  199. DDP_COMPONENT_DRM_OVL_ADAPTOR,
  200. DDP_COMPONENT_MERGE5,
  201. DDP_COMPONENT_DP_INTF1,
  202. };
  203. static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
  204. .main_path = mt2701_mtk_ddp_main,
  205. .main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
  206. .ext_path = mt2701_mtk_ddp_ext,
  207. .ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
  208. .shadow_register = true,
  209. .mmsys_dev_num = 1,
  210. };
  211. static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
  212. .main_path = mt7623_mtk_ddp_main,
  213. .main_len = ARRAY_SIZE(mt7623_mtk_ddp_main),
  214. .ext_path = mt7623_mtk_ddp_ext,
  215. .ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
  216. .shadow_register = true,
  217. .mmsys_dev_num = 1,
  218. };
  219. static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
  220. .main_path = mt2712_mtk_ddp_main,
  221. .main_len = ARRAY_SIZE(mt2712_mtk_ddp_main),
  222. .ext_path = mt2712_mtk_ddp_ext,
  223. .ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
  224. .third_path = mt2712_mtk_ddp_third,
  225. .third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
  226. .mmsys_dev_num = 1,
  227. };
  228. static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
  229. .main_path = mt8167_mtk_ddp_main,
  230. .main_len = ARRAY_SIZE(mt8167_mtk_ddp_main),
  231. .mmsys_dev_num = 1,
  232. };
  233. static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
  234. .main_path = mt8173_mtk_ddp_main,
  235. .main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
  236. .ext_path = mt8173_mtk_ddp_ext,
  237. .ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
  238. .mmsys_dev_num = 1,
  239. };
  240. static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
  241. .main_path = mt8183_mtk_ddp_main,
  242. .main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
  243. .ext_path = mt8183_mtk_ddp_ext,
  244. .ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
  245. .mmsys_dev_num = 1,
  246. };
  247. static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
  248. .main_path = mt8186_mtk_ddp_main,
  249. .main_len = ARRAY_SIZE(mt8186_mtk_ddp_main),
  250. .ext_path = mt8186_mtk_ddp_ext,
  251. .ext_len = ARRAY_SIZE(mt8186_mtk_ddp_ext),
  252. .mmsys_dev_num = 1,
  253. };
  254. static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = {
  255. .main_path = mt8188_mtk_ddp_main,
  256. .main_len = ARRAY_SIZE(mt8188_mtk_ddp_main),
  257. .conn_routes = mt8188_mtk_ddp_main_routes,
  258. .num_conn_routes = ARRAY_SIZE(mt8188_mtk_ddp_main_routes),
  259. .mmsys_dev_num = 2,
  260. .max_width = 8191,
  261. .min_width = 1,
  262. .min_height = 1,
  263. };
  264. static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
  265. .main_path = mt8192_mtk_ddp_main,
  266. .main_len = ARRAY_SIZE(mt8192_mtk_ddp_main),
  267. .ext_path = mt8192_mtk_ddp_ext,
  268. .ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
  269. .mmsys_dev_num = 1,
  270. };
  271. static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
  272. .main_path = mt8195_mtk_ddp_main,
  273. .main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
  274. .mmsys_dev_num = 2,
  275. .max_width = 8191,
  276. .min_width = 1,
  277. .min_height = 1,
  278. };
  279. static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
  280. .ext_path = mt8195_mtk_ddp_ext,
  281. .ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
  282. .mmsys_id = 1,
  283. .mmsys_dev_num = 2,
  284. .max_width = 8191,
  285. .min_width = 2, /* 2-pixel align when ethdr is bypassed */
  286. .min_height = 1,
  287. };
  288. static const struct of_device_id mtk_drm_of_ids[] = {
  289. { .compatible = "mediatek,mt2701-mmsys",
  290. .data = &mt2701_mmsys_driver_data},
  291. { .compatible = "mediatek,mt7623-mmsys",
  292. .data = &mt7623_mmsys_driver_data},
  293. { .compatible = "mediatek,mt2712-mmsys",
  294. .data = &mt2712_mmsys_driver_data},
  295. { .compatible = "mediatek,mt8167-mmsys",
  296. .data = &mt8167_mmsys_driver_data},
  297. { .compatible = "mediatek,mt8173-mmsys",
  298. .data = &mt8173_mmsys_driver_data},
  299. { .compatible = "mediatek,mt8183-mmsys",
  300. .data = &mt8183_mmsys_driver_data},
  301. { .compatible = "mediatek,mt8186-mmsys",
  302. .data = &mt8186_mmsys_driver_data},
  303. { .compatible = "mediatek,mt8188-vdosys0",
  304. .data = &mt8188_vdosys0_driver_data},
  305. { .compatible = "mediatek,mt8188-vdosys1",
  306. .data = &mt8195_vdosys1_driver_data},
  307. { .compatible = "mediatek,mt8192-mmsys",
  308. .data = &mt8192_mmsys_driver_data},
  309. { .compatible = "mediatek,mt8195-mmsys",
  310. .data = &mt8195_vdosys0_driver_data},
  311. { .compatible = "mediatek,mt8195-vdosys0",
  312. .data = &mt8195_vdosys0_driver_data},
  313. { .compatible = "mediatek,mt8195-vdosys1",
  314. .data = &mt8195_vdosys1_driver_data},
  315. { }
  316. };
  317. MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
  318. static int mtk_drm_match(struct device *dev, void *data)
  319. {
  320. if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
  321. return true;
  322. return false;
  323. }
  324. static bool mtk_drm_get_all_drm_priv(struct device *dev)
  325. {
  326. struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
  327. struct mtk_drm_private *all_drm_priv[MAX_CRTC];
  328. struct mtk_drm_private *temp_drm_priv;
  329. struct device_node *phandle = dev->parent->of_node;
  330. const struct of_device_id *of_id;
  331. struct device_node *node;
  332. struct device *drm_dev;
  333. unsigned int cnt = 0;
  334. int i, j;
  335. for_each_child_of_node(phandle->parent, node) {
  336. struct platform_device *pdev;
  337. of_id = of_match_node(mtk_drm_of_ids, node);
  338. if (!of_id)
  339. continue;
  340. pdev = of_find_device_by_node(node);
  341. if (!pdev)
  342. continue;
  343. drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
  344. if (!drm_dev)
  345. goto next_put_device_pdev_dev;
  346. temp_drm_priv = dev_get_drvdata(drm_dev);
  347. if (!temp_drm_priv)
  348. goto next_put_device_drm_dev;
  349. if (temp_drm_priv->data->main_len)
  350. all_drm_priv[CRTC_MAIN] = temp_drm_priv;
  351. else if (temp_drm_priv->data->ext_len)
  352. all_drm_priv[CRTC_EXT] = temp_drm_priv;
  353. else if (temp_drm_priv->data->third_len)
  354. all_drm_priv[CRTC_THIRD] = temp_drm_priv;
  355. if (temp_drm_priv->mtk_drm_bound)
  356. cnt++;
  357. next_put_device_drm_dev:
  358. put_device(drm_dev);
  359. next_put_device_pdev_dev:
  360. put_device(&pdev->dev);
  361. if (cnt == MAX_CRTC) {
  362. of_node_put(node);
  363. break;
  364. }
  365. }
  366. if (drm_priv->data->mmsys_dev_num == cnt) {
  367. for (i = 0; i < cnt; i++)
  368. for (j = 0; j < cnt; j++)
  369. all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
  370. return true;
  371. }
  372. return false;
  373. }
  374. static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
  375. {
  376. const struct mtk_mmsys_driver_data *drv_data = private->data;
  377. int i;
  378. if (drv_data->main_path)
  379. for (i = 0; i < drv_data->main_len; i++)
  380. if (drv_data->main_path[i] == comp_id)
  381. return true;
  382. if (drv_data->ext_path)
  383. for (i = 0; i < drv_data->ext_len; i++)
  384. if (drv_data->ext_path[i] == comp_id)
  385. return true;
  386. if (drv_data->third_path)
  387. for (i = 0; i < drv_data->third_len; i++)
  388. if (drv_data->third_path[i] == comp_id)
  389. return true;
  390. if (drv_data->num_conn_routes)
  391. for (i = 0; i < drv_data->num_conn_routes; i++)
  392. if (drv_data->conn_routes[i].route_ddp == comp_id)
  393. return true;
  394. return false;
  395. }
  396. static int mtk_drm_kms_init(struct drm_device *drm)
  397. {
  398. struct mtk_drm_private *private = drm->dev_private;
  399. struct mtk_drm_private *priv_n;
  400. struct device *dma_dev = NULL;
  401. struct drm_crtc *crtc;
  402. int ret, i, j;
  403. if (drm_firmware_drivers_only())
  404. return -ENODEV;
  405. ret = drmm_mode_config_init(drm);
  406. if (ret)
  407. return ret;
  408. drm->mode_config.min_width = 64;
  409. drm->mode_config.min_height = 64;
  410. /*
  411. * set max width and height as default value(4096x4096).
  412. * this value would be used to check framebuffer size limitation
  413. * at drm_mode_addfb().
  414. */
  415. drm->mode_config.max_width = 4096;
  416. drm->mode_config.max_height = 4096;
  417. drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
  418. drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
  419. for (i = 0; i < private->data->mmsys_dev_num; i++) {
  420. drm->dev_private = private->all_drm_private[i];
  421. ret = component_bind_all(private->all_drm_private[i]->dev, drm);
  422. if (ret) {
  423. while (--i >= 0)
  424. component_unbind_all(private->all_drm_private[i]->dev, drm);
  425. return ret;
  426. }
  427. }
  428. /*
  429. * Ensure internal panels are at the top of the connector list before
  430. * crtc creation.
  431. */
  432. drm_helper_move_panel_connectors_to_head(drm);
  433. /*
  434. * 1. We currently support two fixed data streams, each optional,
  435. * and each statically assigned to a crtc:
  436. * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
  437. * 2. For multi mmsys architecture, crtc path data are located in
  438. * different drm private data structures. Loop through crtc index to
  439. * create crtc from the main path and then ext_path and finally the
  440. * third path.
  441. */
  442. for (i = 0; i < MAX_CRTC; i++) {
  443. for (j = 0; j < private->data->mmsys_dev_num; j++) {
  444. priv_n = private->all_drm_private[j];
  445. if (priv_n->data->max_width)
  446. drm->mode_config.max_width = priv_n->data->max_width;
  447. if (priv_n->data->min_width)
  448. drm->mode_config.min_width = priv_n->data->min_width;
  449. if (priv_n->data->min_height)
  450. drm->mode_config.min_height = priv_n->data->min_height;
  451. if (i == CRTC_MAIN && priv_n->data->main_len) {
  452. ret = mtk_crtc_create(drm, priv_n->data->main_path,
  453. priv_n->data->main_len, j,
  454. priv_n->data->conn_routes,
  455. priv_n->data->num_conn_routes);
  456. if (ret)
  457. goto err_component_unbind;
  458. continue;
  459. } else if (i == CRTC_EXT && priv_n->data->ext_len) {
  460. ret = mtk_crtc_create(drm, priv_n->data->ext_path,
  461. priv_n->data->ext_len, j, NULL, 0);
  462. if (ret)
  463. goto err_component_unbind;
  464. continue;
  465. } else if (i == CRTC_THIRD && priv_n->data->third_len) {
  466. ret = mtk_crtc_create(drm, priv_n->data->third_path,
  467. priv_n->data->third_len, j, NULL, 0);
  468. if (ret)
  469. goto err_component_unbind;
  470. continue;
  471. }
  472. }
  473. }
  474. /* IGT will check if the cursor size is configured */
  475. drm->mode_config.cursor_width = 512;
  476. drm->mode_config.cursor_height = 512;
  477. /* Use OVL device for all DMA memory allocations */
  478. crtc = drm_crtc_from_index(drm, 0);
  479. if (crtc)
  480. dma_dev = mtk_crtc_dma_dev_get(crtc);
  481. if (!dma_dev) {
  482. ret = -ENODEV;
  483. dev_err(drm->dev, "Need at least one OVL device\n");
  484. goto err_component_unbind;
  485. }
  486. for (i = 0; i < private->data->mmsys_dev_num; i++)
  487. private->all_drm_private[i]->dma_dev = dma_dev;
  488. /*
  489. * Configure the DMA segment size to make sure we get contiguous IOVA
  490. * when importing PRIME buffers.
  491. */
  492. dma_set_max_seg_size(dma_dev, UINT_MAX);
  493. ret = drm_vblank_init(drm, MAX_CRTC);
  494. if (ret < 0)
  495. goto err_component_unbind;
  496. drm_kms_helper_poll_init(drm);
  497. drm_mode_config_reset(drm);
  498. return 0;
  499. err_component_unbind:
  500. for (i = 0; i < private->data->mmsys_dev_num; i++)
  501. component_unbind_all(private->all_drm_private[i]->dev, drm);
  502. return ret;
  503. }
  504. static void mtk_drm_kms_deinit(struct drm_device *drm)
  505. {
  506. drm_kms_helper_poll_fini(drm);
  507. drm_atomic_helper_shutdown(drm);
  508. component_unbind_all(drm->dev, drm);
  509. }
  510. DEFINE_DRM_GEM_FOPS(mtk_drm_fops);
  511. /*
  512. * We need to override this because the device used to import the memory is
  513. * not dev->dev, as drm_gem_prime_import() expects.
  514. */
  515. static struct drm_gem_object *mtk_gem_prime_import(struct drm_device *dev,
  516. struct dma_buf *dma_buf)
  517. {
  518. struct mtk_drm_private *private = dev->dev_private;
  519. return drm_gem_prime_import_dev(dev, dma_buf, private->dma_dev);
  520. }
  521. static const struct drm_driver mtk_drm_driver = {
  522. .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
  523. .dumb_create = mtk_gem_dumb_create,
  524. .gem_prime_import = mtk_gem_prime_import,
  525. .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
  526. .fops = &mtk_drm_fops,
  527. .name = DRIVER_NAME,
  528. .desc = DRIVER_DESC,
  529. .date = DRIVER_DATE,
  530. .major = DRIVER_MAJOR,
  531. .minor = DRIVER_MINOR,
  532. };
  533. static int compare_dev(struct device *dev, void *data)
  534. {
  535. return dev == (struct device *)data;
  536. }
  537. static int mtk_drm_bind(struct device *dev)
  538. {
  539. struct mtk_drm_private *private = dev_get_drvdata(dev);
  540. struct platform_device *pdev;
  541. struct drm_device *drm;
  542. int ret, i;
  543. pdev = of_find_device_by_node(private->mutex_node);
  544. if (!pdev) {
  545. dev_err(dev, "Waiting for disp-mutex device %pOF\n",
  546. private->mutex_node);
  547. of_node_put(private->mutex_node);
  548. return -EPROBE_DEFER;
  549. }
  550. private->mutex_dev = &pdev->dev;
  551. private->mtk_drm_bound = true;
  552. private->dev = dev;
  553. if (!mtk_drm_get_all_drm_priv(dev))
  554. return 0;
  555. drm = drm_dev_alloc(&mtk_drm_driver, dev);
  556. if (IS_ERR(drm)) {
  557. ret = PTR_ERR(drm);
  558. goto err_put_dev;
  559. }
  560. private->drm_master = true;
  561. drm->dev_private = private;
  562. for (i = 0; i < private->data->mmsys_dev_num; i++)
  563. private->all_drm_private[i]->drm = drm;
  564. ret = mtk_drm_kms_init(drm);
  565. if (ret < 0)
  566. goto err_free;
  567. ret = drm_dev_register(drm, 0);
  568. if (ret < 0)
  569. goto err_deinit;
  570. drm_fbdev_dma_setup(drm, 32);
  571. return 0;
  572. err_deinit:
  573. mtk_drm_kms_deinit(drm);
  574. err_free:
  575. private->drm = NULL;
  576. drm_dev_put(drm);
  577. for (i = 0; i < private->data->mmsys_dev_num; i++)
  578. private->all_drm_private[i]->drm = NULL;
  579. err_put_dev:
  580. for (i = 0; i < private->data->mmsys_dev_num; i++) {
  581. /* For device_find_child in mtk_drm_get_all_priv() */
  582. put_device(private->all_drm_private[i]->dev);
  583. }
  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. int i;
  591. /* for multi mmsys dev, unregister drm dev in mmsys master */
  592. if (private->drm_master) {
  593. drm_dev_unregister(private->drm);
  594. mtk_drm_kms_deinit(private->drm);
  595. drm_dev_put(private->drm);
  596. for (i = 0; i < private->data->mmsys_dev_num; i++) {
  597. /* For device_find_child in mtk_drm_get_all_priv() */
  598. put_device(private->all_drm_private[i]->dev);
  599. }
  600. put_device(private->mutex_dev);
  601. }
  602. private->mtk_drm_bound = false;
  603. private->drm_master = false;
  604. private->drm = NULL;
  605. }
  606. static const struct component_master_ops mtk_drm_ops = {
  607. .bind = mtk_drm_bind,
  608. .unbind = mtk_drm_unbind,
  609. };
  610. static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
  611. { .compatible = "mediatek,mt8167-disp-aal",
  612. .data = (void *)MTK_DISP_AAL},
  613. { .compatible = "mediatek,mt8173-disp-aal",
  614. .data = (void *)MTK_DISP_AAL},
  615. { .compatible = "mediatek,mt8183-disp-aal",
  616. .data = (void *)MTK_DISP_AAL},
  617. { .compatible = "mediatek,mt8192-disp-aal",
  618. .data = (void *)MTK_DISP_AAL},
  619. { .compatible = "mediatek,mt8167-disp-ccorr",
  620. .data = (void *)MTK_DISP_CCORR },
  621. { .compatible = "mediatek,mt8183-disp-ccorr",
  622. .data = (void *)MTK_DISP_CCORR },
  623. { .compatible = "mediatek,mt8192-disp-ccorr",
  624. .data = (void *)MTK_DISP_CCORR },
  625. { .compatible = "mediatek,mt2701-disp-color",
  626. .data = (void *)MTK_DISP_COLOR },
  627. { .compatible = "mediatek,mt8167-disp-color",
  628. .data = (void *)MTK_DISP_COLOR },
  629. { .compatible = "mediatek,mt8173-disp-color",
  630. .data = (void *)MTK_DISP_COLOR },
  631. { .compatible = "mediatek,mt8167-disp-dither",
  632. .data = (void *)MTK_DISP_DITHER },
  633. { .compatible = "mediatek,mt8183-disp-dither",
  634. .data = (void *)MTK_DISP_DITHER },
  635. { .compatible = "mediatek,mt8195-disp-dsc",
  636. .data = (void *)MTK_DISP_DSC },
  637. { .compatible = "mediatek,mt8167-disp-gamma",
  638. .data = (void *)MTK_DISP_GAMMA, },
  639. { .compatible = "mediatek,mt8173-disp-gamma",
  640. .data = (void *)MTK_DISP_GAMMA, },
  641. { .compatible = "mediatek,mt8183-disp-gamma",
  642. .data = (void *)MTK_DISP_GAMMA, },
  643. { .compatible = "mediatek,mt8195-disp-gamma",
  644. .data = (void *)MTK_DISP_GAMMA, },
  645. { .compatible = "mediatek,mt8195-disp-merge",
  646. .data = (void *)MTK_DISP_MERGE },
  647. { .compatible = "mediatek,mt2701-disp-mutex",
  648. .data = (void *)MTK_DISP_MUTEX },
  649. { .compatible = "mediatek,mt2712-disp-mutex",
  650. .data = (void *)MTK_DISP_MUTEX },
  651. { .compatible = "mediatek,mt8167-disp-mutex",
  652. .data = (void *)MTK_DISP_MUTEX },
  653. { .compatible = "mediatek,mt8173-disp-mutex",
  654. .data = (void *)MTK_DISP_MUTEX },
  655. { .compatible = "mediatek,mt8183-disp-mutex",
  656. .data = (void *)MTK_DISP_MUTEX },
  657. { .compatible = "mediatek,mt8186-disp-mutex",
  658. .data = (void *)MTK_DISP_MUTEX },
  659. { .compatible = "mediatek,mt8188-disp-mutex",
  660. .data = (void *)MTK_DISP_MUTEX },
  661. { .compatible = "mediatek,mt8192-disp-mutex",
  662. .data = (void *)MTK_DISP_MUTEX },
  663. { .compatible = "mediatek,mt8195-disp-mutex",
  664. .data = (void *)MTK_DISP_MUTEX },
  665. { .compatible = "mediatek,mt8173-disp-od",
  666. .data = (void *)MTK_DISP_OD },
  667. { .compatible = "mediatek,mt2701-disp-ovl",
  668. .data = (void *)MTK_DISP_OVL },
  669. { .compatible = "mediatek,mt8167-disp-ovl",
  670. .data = (void *)MTK_DISP_OVL },
  671. { .compatible = "mediatek,mt8173-disp-ovl",
  672. .data = (void *)MTK_DISP_OVL },
  673. { .compatible = "mediatek,mt8183-disp-ovl",
  674. .data = (void *)MTK_DISP_OVL },
  675. { .compatible = "mediatek,mt8192-disp-ovl",
  676. .data = (void *)MTK_DISP_OVL },
  677. { .compatible = "mediatek,mt8195-disp-ovl",
  678. .data = (void *)MTK_DISP_OVL },
  679. { .compatible = "mediatek,mt8183-disp-ovl-2l",
  680. .data = (void *)MTK_DISP_OVL_2L },
  681. { .compatible = "mediatek,mt8192-disp-ovl-2l",
  682. .data = (void *)MTK_DISP_OVL_2L },
  683. { .compatible = "mediatek,mt8192-disp-postmask",
  684. .data = (void *)MTK_DISP_POSTMASK },
  685. { .compatible = "mediatek,mt2701-disp-pwm",
  686. .data = (void *)MTK_DISP_BLS },
  687. { .compatible = "mediatek,mt8167-disp-pwm",
  688. .data = (void *)MTK_DISP_PWM },
  689. { .compatible = "mediatek,mt8173-disp-pwm",
  690. .data = (void *)MTK_DISP_PWM },
  691. { .compatible = "mediatek,mt2701-disp-rdma",
  692. .data = (void *)MTK_DISP_RDMA },
  693. { .compatible = "mediatek,mt8167-disp-rdma",
  694. .data = (void *)MTK_DISP_RDMA },
  695. { .compatible = "mediatek,mt8173-disp-rdma",
  696. .data = (void *)MTK_DISP_RDMA },
  697. { .compatible = "mediatek,mt8183-disp-rdma",
  698. .data = (void *)MTK_DISP_RDMA },
  699. { .compatible = "mediatek,mt8195-disp-rdma",
  700. .data = (void *)MTK_DISP_RDMA },
  701. { .compatible = "mediatek,mt8173-disp-ufoe",
  702. .data = (void *)MTK_DISP_UFOE },
  703. { .compatible = "mediatek,mt8173-disp-wdma",
  704. .data = (void *)MTK_DISP_WDMA },
  705. { .compatible = "mediatek,mt2701-dpi",
  706. .data = (void *)MTK_DPI },
  707. { .compatible = "mediatek,mt8167-dsi",
  708. .data = (void *)MTK_DSI },
  709. { .compatible = "mediatek,mt8173-dpi",
  710. .data = (void *)MTK_DPI },
  711. { .compatible = "mediatek,mt8183-dpi",
  712. .data = (void *)MTK_DPI },
  713. { .compatible = "mediatek,mt8186-dpi",
  714. .data = (void *)MTK_DPI },
  715. { .compatible = "mediatek,mt8188-dp-intf",
  716. .data = (void *)MTK_DP_INTF },
  717. { .compatible = "mediatek,mt8192-dpi",
  718. .data = (void *)MTK_DPI },
  719. { .compatible = "mediatek,mt8195-dp-intf",
  720. .data = (void *)MTK_DP_INTF },
  721. { .compatible = "mediatek,mt2701-dsi",
  722. .data = (void *)MTK_DSI },
  723. { .compatible = "mediatek,mt8173-dsi",
  724. .data = (void *)MTK_DSI },
  725. { .compatible = "mediatek,mt8183-dsi",
  726. .data = (void *)MTK_DSI },
  727. { .compatible = "mediatek,mt8186-dsi",
  728. .data = (void *)MTK_DSI },
  729. { .compatible = "mediatek,mt8188-dsi",
  730. .data = (void *)MTK_DSI },
  731. { }
  732. };
  733. static int mtk_drm_probe(struct platform_device *pdev)
  734. {
  735. struct device *dev = &pdev->dev;
  736. struct device_node *phandle = dev->parent->of_node;
  737. const struct of_device_id *of_id;
  738. struct mtk_drm_private *private;
  739. struct device_node *node;
  740. struct component_match *match = NULL;
  741. struct platform_device *ovl_adaptor;
  742. int ret;
  743. int i;
  744. private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
  745. if (!private)
  746. return -ENOMEM;
  747. private->mmsys_dev = dev->parent;
  748. if (!private->mmsys_dev) {
  749. dev_err(dev, "Failed to get MMSYS device\n");
  750. return -ENODEV;
  751. }
  752. of_id = of_match_node(mtk_drm_of_ids, phandle);
  753. if (!of_id)
  754. return -ENODEV;
  755. private->data = of_id->data;
  756. private->all_drm_private = devm_kmalloc_array(dev, private->data->mmsys_dev_num,
  757. sizeof(*private->all_drm_private),
  758. GFP_KERNEL);
  759. if (!private->all_drm_private)
  760. return -ENOMEM;
  761. /* Bringup ovl_adaptor */
  762. if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVL_ADAPTOR)) {
  763. ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovl-adaptor",
  764. PLATFORM_DEVID_AUTO,
  765. (void *)private->mmsys_dev,
  766. sizeof(*private->mmsys_dev));
  767. private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR].dev = &ovl_adaptor->dev;
  768. mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR],
  769. DDP_COMPONENT_DRM_OVL_ADAPTOR);
  770. component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
  771. }
  772. /* Iterate over sibling DISP function blocks */
  773. for_each_child_of_node(phandle->parent, node) {
  774. const struct of_device_id *of_id;
  775. enum mtk_ddp_comp_type comp_type;
  776. int comp_id;
  777. of_id = of_match_node(mtk_ddp_comp_dt_ids, node);
  778. if (!of_id)
  779. continue;
  780. if (!of_device_is_available(node)) {
  781. dev_dbg(dev, "Skipping disabled component %pOF\n",
  782. node);
  783. continue;
  784. }
  785. comp_type = (enum mtk_ddp_comp_type)(uintptr_t)of_id->data;
  786. if (comp_type == MTK_DISP_MUTEX) {
  787. int id;
  788. id = of_alias_get_id(node, "mutex");
  789. if (id < 0 || id == private->data->mmsys_id) {
  790. private->mutex_node = of_node_get(node);
  791. dev_dbg(dev, "get mutex for mmsys %d", private->data->mmsys_id);
  792. }
  793. continue;
  794. }
  795. comp_id = mtk_ddp_comp_get_id(node, comp_type);
  796. if (comp_id < 0) {
  797. dev_warn(dev, "Skipping unknown component %pOF\n",
  798. node);
  799. continue;
  800. }
  801. if (!mtk_drm_find_mmsys_comp(private, comp_id))
  802. continue;
  803. private->comp_node[comp_id] = of_node_get(node);
  804. /*
  805. * Currently only the AAL, CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
  806. * blocks have separate component platform drivers and initialize their own
  807. * DDP component structure. The others are initialized here.
  808. */
  809. if (comp_type == MTK_DISP_AAL ||
  810. comp_type == MTK_DISP_CCORR ||
  811. comp_type == MTK_DISP_COLOR ||
  812. comp_type == MTK_DISP_GAMMA ||
  813. comp_type == MTK_DISP_MERGE ||
  814. comp_type == MTK_DISP_OVL ||
  815. comp_type == MTK_DISP_OVL_2L ||
  816. comp_type == MTK_DISP_OVL_ADAPTOR ||
  817. comp_type == MTK_DISP_RDMA ||
  818. comp_type == MTK_DP_INTF ||
  819. comp_type == MTK_DPI ||
  820. comp_type == MTK_DSI) {
  821. dev_info(dev, "Adding component match for %pOF\n",
  822. node);
  823. drm_of_component_match_add(dev, &match, component_compare_of,
  824. node);
  825. }
  826. ret = mtk_ddp_comp_init(node, &private->ddp_comp[comp_id], comp_id);
  827. if (ret) {
  828. of_node_put(node);
  829. goto err_node;
  830. }
  831. }
  832. if (!private->mutex_node) {
  833. dev_err(dev, "Failed to find disp-mutex node\n");
  834. ret = -ENODEV;
  835. goto err_node;
  836. }
  837. pm_runtime_enable(dev);
  838. platform_set_drvdata(pdev, private);
  839. ret = component_master_add_with_match(dev, &mtk_drm_ops, match);
  840. if (ret)
  841. goto err_pm;
  842. return 0;
  843. err_pm:
  844. pm_runtime_disable(dev);
  845. err_node:
  846. of_node_put(private->mutex_node);
  847. for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
  848. of_node_put(private->comp_node[i]);
  849. return ret;
  850. }
  851. static void mtk_drm_remove(struct platform_device *pdev)
  852. {
  853. struct mtk_drm_private *private = platform_get_drvdata(pdev);
  854. int i;
  855. component_master_del(&pdev->dev, &mtk_drm_ops);
  856. pm_runtime_disable(&pdev->dev);
  857. of_node_put(private->mutex_node);
  858. for (i = 0; i < DDP_COMPONENT_DRM_ID_MAX; i++)
  859. of_node_put(private->comp_node[i]);
  860. }
  861. static void mtk_drm_shutdown(struct platform_device *pdev)
  862. {
  863. struct mtk_drm_private *private = platform_get_drvdata(pdev);
  864. drm_atomic_helper_shutdown(private->drm);
  865. }
  866. static int mtk_drm_sys_prepare(struct device *dev)
  867. {
  868. struct mtk_drm_private *private = dev_get_drvdata(dev);
  869. struct drm_device *drm = private->drm;
  870. if (private->drm_master)
  871. return drm_mode_config_helper_suspend(drm);
  872. else
  873. return 0;
  874. }
  875. static void mtk_drm_sys_complete(struct device *dev)
  876. {
  877. struct mtk_drm_private *private = dev_get_drvdata(dev);
  878. struct drm_device *drm = private->drm;
  879. int ret = 0;
  880. if (private->drm_master)
  881. ret = drm_mode_config_helper_resume(drm);
  882. if (ret)
  883. dev_err(dev, "Failed to resume\n");
  884. }
  885. static const struct dev_pm_ops mtk_drm_pm_ops = {
  886. .prepare = mtk_drm_sys_prepare,
  887. .complete = mtk_drm_sys_complete,
  888. };
  889. static struct platform_driver mtk_drm_platform_driver = {
  890. .probe = mtk_drm_probe,
  891. .remove_new = mtk_drm_remove,
  892. .shutdown = mtk_drm_shutdown,
  893. .driver = {
  894. .name = "mediatek-drm",
  895. .pm = &mtk_drm_pm_ops,
  896. },
  897. };
  898. static struct platform_driver * const mtk_drm_drivers[] = {
  899. &mtk_disp_aal_driver,
  900. &mtk_disp_ccorr_driver,
  901. &mtk_disp_color_driver,
  902. &mtk_disp_gamma_driver,
  903. &mtk_disp_merge_driver,
  904. &mtk_disp_ovl_adaptor_driver,
  905. &mtk_disp_ovl_driver,
  906. &mtk_disp_rdma_driver,
  907. &mtk_dpi_driver,
  908. &mtk_drm_platform_driver,
  909. &mtk_dsi_driver,
  910. &mtk_ethdr_driver,
  911. &mtk_mdp_rdma_driver,
  912. &mtk_padding_driver,
  913. };
  914. static int __init mtk_drm_init(void)
  915. {
  916. return platform_register_drivers(mtk_drm_drivers,
  917. ARRAY_SIZE(mtk_drm_drivers));
  918. }
  919. static void __exit mtk_drm_exit(void)
  920. {
  921. platform_unregister_drivers(mtk_drm_drivers,
  922. ARRAY_SIZE(mtk_drm_drivers));
  923. }
  924. module_init(mtk_drm_init);
  925. module_exit(mtk_drm_exit);
  926. MODULE_AUTHOR("YT SHEN <yt.shen@mediatek.com>");
  927. MODULE_DESCRIPTION("Mediatek SoC DRM driver");
  928. MODULE_LICENSE("GPL v2");