mtk_drm_ddp_comp.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  1. /*
  2. * Copyright (c) 2015 MediaTek Inc.
  3. * Authors:
  4. * YT Shen <yt.shen@mediatek.com>
  5. * CK Hu <ck.hu@mediatek.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <linux/clk.h>
  17. #include <linux/iopoll.h>
  18. #include <linux/of.h>
  19. #include <linux/of_address.h>
  20. #include <linux/of_irq.h>
  21. #include <linux/of_platform.h>
  22. #include <linux/platform_device.h>
  23. #include <drm/drmP.h>
  24. #include <linux/soc/mediatek/mtk-cmdq.h>
  25. #include <soc/mediatek/smi.h>
  26. #ifdef CONFIG_MTK_IOMMU_V2
  27. #include "mt_iommu.h"
  28. #include "mtk_iommu_ext.h"
  29. #endif
  30. #include "mtk_drm_drv.h"
  31. #include "mtk_drm_plane.h"
  32. #include "mtk_drm_ddp_comp.h"
  33. #include "mtk_drm_crtc.h"
  34. #include "mtk_drm_gem.h"
  35. #include "mtk_dump.h"
  36. #ifdef CONFIG_MTK_SMI_EXT
  37. #include "smi_public.h"
  38. #endif
  39. #define DISP_OD_EN 0x0000
  40. #define DISP_OD_INTEN 0x0008
  41. #define DISP_OD_INTSTA 0x000c
  42. #define DISP_OD_CFG 0x0020
  43. #define DISP_OD_SIZE 0x0030
  44. #define DISP_DITHER_5 0x0114
  45. #define DISP_DITHER_7 0x011c
  46. #define DISP_DITHER_15 0x013c
  47. #define DISP_DITHER_16 0x0140
  48. #define DISP_REG_SPLIT_START 0x0000
  49. #define DISP_REG_UFO_START 0x0000
  50. #define DISP_REG_UFO_WIDTH 0x0050
  51. #define DISP_REG_UFO_HEIGHT 0x0054
  52. #define OD_RELAYMODE BIT(0)
  53. #define UFO_BYPASS BIT(2)
  54. #define UFO_LR (BIT(3) | BIT(0))
  55. #define DISP_DITHERING BIT(2)
  56. #define DITHER_LSB_ERR_SHIFT_R(x) (((x)&0x7) << 28)
  57. #define DITHER_OVFLW_BIT_R(x) (((x)&0x7) << 24)
  58. #define DITHER_ADD_LSHIFT_R(x) (((x)&0x7) << 20)
  59. #define DITHER_ADD_RSHIFT_R(x) (((x)&0x7) << 16)
  60. #define DITHER_NEW_BIT_MODE BIT(0)
  61. #define DITHER_LSB_ERR_SHIFT_B(x) (((x)&0x7) << 28)
  62. #define DITHER_OVFLW_BIT_B(x) (((x)&0x7) << 24)
  63. #define DITHER_ADD_LSHIFT_B(x) (((x)&0x7) << 20)
  64. #define DITHER_ADD_RSHIFT_B(x) (((x)&0x7) << 16)
  65. #define DITHER_LSB_ERR_SHIFT_G(x) (((x)&0x7) << 12)
  66. #define DITHER_OVFLW_BIT_G(x) (((x)&0x7) << 8)
  67. #define DITHER_ADD_LSHIFT_G(x) (((x)&0x7) << 4)
  68. #define DITHER_ADD_RSHIFT_G(x) (((x)&0x7) << 0)
  69. #define MMSYS_SODI_REQ_MASK 0xF4
  70. #define SODI_REQ_SEL_ALL REG_FLD_MSB_LSB(11, 8)
  71. #define MT6873_SODI_REQ_SEL_ALL REG_FLD_MSB_LSB(9, 8)
  72. #define SODI_REQ_SEL_RDMA0_PD_MODE REG_FLD_MSB_LSB(8, 8)
  73. #define SODI_REQ_SEL_RDMA0_CG_MODE REG_FLD_MSB_LSB(9, 9)
  74. #define SODI_REQ_SEL_RDMA1_PD_MODE REG_FLD_MSB_LSB(10, 10)
  75. #define SODI_REQ_SEL_RDMA1_CG_MODE REG_FLD_MSB_LSB(11, 11)
  76. #define SODI_REQ_VAL_ALL REG_FLD_MSB_LSB(15, 12)
  77. #define MT6873_SODI_REQ_VAL_ALL REG_FLD_MSB_LSB(13, 12)
  78. #define SODI_REQ_VAL_RDMA0_PD_MODE REG_FLD_MSB_LSB(12, 12)
  79. #define SODI_REQ_VAL_RDMA0_CG_MODE REG_FLD_MSB_LSB(13, 13)
  80. #define SODI_REQ_VAL_RDMA1_PD_MODE REG_FLD_MSB_LSB(14, 14)
  81. #define SODI_REQ_VAL_RDMA1_CG_MODE REG_FLD_MSB_LSB(15, 15)
  82. #define MMSYS_EMI_REQ_CTL 0xF8
  83. #define HRT_URGENT_CTL_SEL_ALL REG_FLD_MSB_LSB(7, 0)
  84. #define HRT_URGENT_CTL_SEL_RDMA0 REG_FLD_MSB_LSB(0, 0)
  85. #define HRT_URGENT_CTL_SEL_WDMA0 REG_FLD_MSB_LSB(1, 1)
  86. #define HRT_URGENT_CTL_SEL_RDMA1 REG_FLD_MSB_LSB(2, 2)
  87. #define HRT_URGENT_CTL_SEL_WDMA1 REG_FLD_MSB_LSB(3, 3)
  88. #define HRT_URGENT_CTL_SEL_RDMA4 REG_FLD_MSB_LSB(4, 4)
  89. #define HRT_URGENT_CTL_SEL_RDMA5 REG_FLD_MSB_LSB(5, 5)
  90. #define HRT_URGENT_CTL_SEL_MDP_RDMA4 REG_FLD_MSB_LSB(6, 6)
  91. #define HRT_URGENT_CTL_VAL_ALL REG_FLD_MSB_LSB(16, 9)
  92. #define HRT_URGENT_CTL_VAL_RDMA0 REG_FLD_MSB_LSB(9, 9)
  93. #define HRT_URGENT_CTL_VAL_WDMA0 REG_FLD_MSB_LSB(10, 10)
  94. #define HRT_URGENT_CTL_VAL_RDMA4 REG_FLD_MSB_LSB(13, 13)
  95. #define HRT_URGENT_CTL_VAL_MDP_RDMA4 REG_FLD_MSB_LSB(15, 15)
  96. #define DVFS_HALT_MASK_SEL_ALL REG_FLD_MSB_LSB(23, 18)
  97. #define DVFS_HALT_MASK_SEL_RDMA0 REG_FLD_MSB_LSB(18, 18)
  98. #define DVFS_HALT_MASK_SEL_RDMA1 REG_FLD_MSB_LSB(19, 19)
  99. #define DVFS_HALT_MASK_SEL_RDMA4 REG_FLD_MSB_LSB(20, 20)
  100. #define DVFS_HALT_MASK_SEL_RDMA5 REG_FLD_MSB_LSB(21, 21)
  101. #define DVFS_HALT_MASK_SEL_WDMA0 REG_FLD_MSB_LSB(22, 22)
  102. #define DVFS_HALT_MASK_SEL_WDMA1 REG_FLD_MSB_LSB(23, 23)
  103. #define MT6833_INFRA_DISP_DDR_CTL 0x2C
  104. #define MT6833_INFRA_FLD_DDR_MASK REG_FLD_MSB_LSB(7, 4)
  105. #define SMI_LARB_NON_SEC_CON 0x0380
  106. #define MTK_DDP_COMP_USER "DISP"
  107. void mtk_ddp_write(struct mtk_ddp_comp *comp, unsigned int value,
  108. unsigned int offset, void *handle)
  109. {
  110. #ifdef CONFIG_MTK_DISPLAY_CMDQ
  111. cmdq_pkt_write((struct cmdq_pkt *)handle, comp->cmdq_base,
  112. comp->regs_pa + offset, value, ~0);
  113. #else
  114. writel(value, comp->regs + offset);
  115. #endif
  116. }
  117. void mtk_ddp_write_relaxed(struct mtk_ddp_comp *comp, unsigned int value,
  118. unsigned int offset, void *handle)
  119. {
  120. #ifdef CONFIG_MTK_DISPLAY_CMDQ
  121. cmdq_pkt_write((struct cmdq_pkt *)handle, comp->cmdq_base,
  122. comp->regs_pa + offset, value, ~0);
  123. #else
  124. writel_relaxed(value, comp->regs + offset);
  125. #endif
  126. }
  127. void mtk_ddp_write_mask(struct mtk_ddp_comp *comp, unsigned int value,
  128. unsigned int offset, unsigned int mask, void *handle)
  129. {
  130. #ifdef CONFIG_MTK_DISPLAY_CMDQ
  131. cmdq_pkt_write((struct cmdq_pkt *)handle, comp->cmdq_base,
  132. comp->regs_pa + offset, value, mask);
  133. #else
  134. unsigned int tmp = readl(comp->regs + offset);
  135. tmp = (tmp & ~mask) | (value & mask);
  136. writel(tmp, comp->regs + offset);
  137. #endif
  138. }
  139. void mtk_ddp_write_mask_cpu(struct mtk_ddp_comp *comp,
  140. unsigned int value, unsigned int offset, unsigned int mask)
  141. {
  142. unsigned int tmp = readl(comp->regs + offset);
  143. tmp = (tmp & ~mask) | (value & mask);
  144. writel(tmp, comp->regs + offset);
  145. }
  146. void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
  147. unsigned int CFG, struct cmdq_pkt *handle)
  148. {
  149. /* If bpc equal to 0, the dithering function didn't be enabled */
  150. if (bpc == 0)
  151. return;
  152. if (bpc >= MTK_MIN_BPC) {
  153. cmdq_pkt_write(handle, comp->cmdq_base,
  154. comp->regs_pa + DISP_DITHER_5, 0, ~0);
  155. cmdq_pkt_write(handle, comp->cmdq_base,
  156. comp->regs_pa + DISP_DITHER_7, 0, ~0);
  157. cmdq_pkt_write(handle, comp->cmdq_base,
  158. comp->regs_pa + DISP_DITHER_15,
  159. DITHER_LSB_ERR_SHIFT_R(MTK_MAX_BPC - bpc) |
  160. DITHER_ADD_LSHIFT_R(MTK_MAX_BPC - bpc) |
  161. DITHER_NEW_BIT_MODE,
  162. ~0);
  163. cmdq_pkt_write(
  164. handle, comp->cmdq_base, comp->regs_pa + DISP_DITHER_16,
  165. DITHER_LSB_ERR_SHIFT_B(MTK_MAX_BPC - bpc) |
  166. DITHER_ADD_LSHIFT_B(MTK_MAX_BPC - bpc) |
  167. DITHER_LSB_ERR_SHIFT_G(MTK_MAX_BPC - bpc) |
  168. DITHER_ADD_LSHIFT_G(MTK_MAX_BPC - bpc),
  169. ~0);
  170. cmdq_pkt_write(handle, comp->cmdq_base, comp->regs_pa + CFG,
  171. DISP_DITHERING, ~0);
  172. }
  173. }
  174. static void mtk_od_config(struct mtk_ddp_comp *comp, struct mtk_ddp_config *cfg,
  175. struct cmdq_pkt *handle)
  176. {
  177. cmdq_pkt_write(handle, comp->cmdq_base, comp->regs_pa + DISP_OD_SIZE,
  178. cfg->w << 16 | cfg->h, ~0);
  179. cmdq_pkt_write(handle, comp->cmdq_base, comp->regs_pa + DISP_OD_CFG,
  180. OD_RELAYMODE, ~0);
  181. mtk_dither_set(comp, cfg->bpc, DISP_OD_CFG, handle);
  182. }
  183. static void mtk_od_start(struct mtk_ddp_comp *comp, struct cmdq_pkt *handle)
  184. {
  185. cmdq_pkt_write(handle, comp->cmdq_base, comp->regs_pa + DISP_OD_EN, 1,
  186. ~0);
  187. }
  188. static void mtk_ufoe_config(struct mtk_ddp_comp *comp,
  189. struct mtk_ddp_config *cfg, struct cmdq_pkt *handle)
  190. {
  191. cmdq_pkt_write(handle, comp->cmdq_base,
  192. comp->regs_pa + DISP_REG_UFO_WIDTH, cfg->w, ~0);
  193. cmdq_pkt_write(handle, comp->cmdq_base,
  194. comp->regs_pa + DISP_REG_UFO_HEIGHT, cfg->h, ~0);
  195. }
  196. static void mtk_ufoe_start(struct mtk_ddp_comp *comp, struct cmdq_pkt *handle)
  197. {
  198. cmdq_pkt_write(handle, comp->cmdq_base,
  199. comp->regs_pa + DISP_REG_UFO_START, UFO_BYPASS, ~0);
  200. }
  201. static void mtk_split_start(struct mtk_ddp_comp *comp, struct cmdq_pkt *handle)
  202. {
  203. cmdq_pkt_write(handle, comp->cmdq_base,
  204. comp->regs_pa + DISP_REG_SPLIT_START, 1, ~0);
  205. }
  206. static const struct mtk_ddp_comp_funcs ddp_od = {
  207. .config = mtk_od_config, .start = mtk_od_start,
  208. };
  209. static const struct mtk_ddp_comp_funcs ddp_ufoe = {
  210. .start = mtk_ufoe_start, .config = mtk_ufoe_config,
  211. };
  212. static const struct mtk_ddp_comp_funcs ddp_split = {
  213. .start = mtk_split_start,
  214. };
  215. static const char *const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
  216. [MTK_DISP_OVL] = "ovl",
  217. [MTK_DISP_RDMA] = "rdma",
  218. [MTK_DISP_WDMA] = "wdma",
  219. [MTK_DISP_COLOR] = "color",
  220. [MTK_DISP_CCORR] = "ccorr",
  221. [MTK_DISP_AAL] = "aal",
  222. [MTK_DISP_GAMMA] = "gamma",
  223. [MTK_DISP_DITHER] = "dither",
  224. [MTK_DISP_UFOE] = "ufoe",
  225. [MTK_DSI] = "dsi",
  226. [MTK_DP_INTF] = "dp_intf",
  227. [MTK_DPI] = "dpi",
  228. [MTK_DISP_PWM] = "pwm",
  229. [MTK_DISP_MUTEX] = "mutex",
  230. [MTK_DISP_OD] = "od",
  231. [MTK_DISP_BLS] = "bls",
  232. [MTK_DISP_RSZ] = "rsz",
  233. [MTK_DISP_POSTMASK] = "postmask",
  234. [MTK_DMDP_RDMA] = "mrdma",
  235. [MTK_DMDP_HDR] = "mhdr",
  236. [MTK_DMDP_AAL] = "maal",
  237. [MTK_DMDP_RSZ] = "mrsz",
  238. [MTK_DMDP_TDSHP] = "mtdshp",
  239. [MTK_DISP_DSC] = "dsc",
  240. [MTK_DISP_MERGE] = "merge",
  241. [MTK_DISP_DPTX] = "dptx",
  242. [MTK_DISP_VIRTUAL] = "virtual",
  243. };
  244. struct mtk_ddp_comp_match {
  245. enum mtk_ddp_comp_id index;
  246. enum mtk_ddp_comp_type type;
  247. int alias_id;
  248. const struct mtk_ddp_comp_funcs *funcs;
  249. bool is_output;
  250. };
  251. static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
  252. {DDP_COMPONENT_AAL0, MTK_DISP_AAL, 0, NULL, 0},
  253. {DDP_COMPONENT_AAL1, MTK_DISP_AAL, 1, NULL, 0},
  254. {DDP_COMPONENT_BLS, MTK_DISP_BLS, 0, NULL, 0},
  255. {DDP_COMPONENT_CCORR0, MTK_DISP_CCORR, 0, NULL, 0},
  256. {DDP_COMPONENT_CCORR1, MTK_DISP_CCORR, 1, NULL, 0},
  257. {DDP_COMPONENT_COLOR0, MTK_DISP_COLOR, 0, NULL, 0},
  258. {DDP_COMPONENT_COLOR1, MTK_DISP_COLOR, 1, NULL, 0},
  259. {DDP_COMPONENT_COLOR2, MTK_DISP_COLOR, 2, NULL, 0},
  260. {DDP_COMPONENT_DITHER0, MTK_DISP_DITHER, 0, NULL, 0},
  261. {DDP_COMPONENT_DITHER1, MTK_DISP_DITHER, 1, NULL, 0},
  262. {DDP_COMPONENT_DPI0, MTK_DPI, 0, NULL, 1},
  263. {DDP_COMPONENT_DPI1, MTK_DPI, 1, NULL, 1},
  264. {DDP_COMPONENT_DSI0, MTK_DSI, 0, NULL, 1},
  265. {DDP_COMPONENT_DSI1, MTK_DSI, 1, NULL, 1},
  266. {DDP_COMPONENT_GAMMA0, MTK_DISP_GAMMA, 0, NULL, 0},
  267. {DDP_COMPONENT_GAMMA1, MTK_DISP_GAMMA, 0, NULL, 0},
  268. {DDP_COMPONENT_OD, MTK_DISP_OD, 0, &ddp_od, 0},
  269. {DDP_COMPONENT_OD1, MTK_DISP_OD, 1, &ddp_od, 0},
  270. {DDP_COMPONENT_OVL0, MTK_DISP_OVL, 0, NULL, 0},
  271. {DDP_COMPONENT_OVL1, MTK_DISP_OVL, 1, NULL, 0},
  272. {DDP_COMPONENT_OVL2, MTK_DISP_OVL, 2, NULL, 0},
  273. {DDP_COMPONENT_OVL0_2L, MTK_DISP_OVL, 3, NULL, 0},
  274. {DDP_COMPONENT_OVL1_2L, MTK_DISP_OVL, 4, NULL, 0},
  275. {DDP_COMPONENT_OVL2_2L, MTK_DISP_OVL, 5, NULL, 0},
  276. {DDP_COMPONENT_OVL3_2L, MTK_DISP_OVL, 6, NULL, 0},
  277. {DDP_COMPONENT_OVL0_2L_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  278. {DDP_COMPONENT_OVL1_2L_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  279. {DDP_COMPONENT_OVL0_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  280. {DDP_COMPONENT_OVL1_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  281. {DDP_COMPONENT_OVL0_OVL0_2L_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  282. {DDP_COMPONENT_PWM0, MTK_DISP_PWM, 0, NULL, 0},
  283. {DDP_COMPONENT_PWM1, MTK_DISP_PWM, 1, NULL, 0},
  284. {DDP_COMPONENT_PWM2, MTK_DISP_PWM, 2, NULL, 0},
  285. {DDP_COMPONENT_RDMA0, MTK_DISP_RDMA, 0, NULL, 0},
  286. {DDP_COMPONENT_RDMA1, MTK_DISP_RDMA, 1, NULL, 0},
  287. {DDP_COMPONENT_RDMA2, MTK_DISP_RDMA, 2, NULL, 0},
  288. {DDP_COMPONENT_RDMA3, MTK_DISP_RDMA, 3, NULL, 0},
  289. {DDP_COMPONENT_RDMA4, MTK_DISP_RDMA, 4, NULL, 0},
  290. {DDP_COMPONENT_RDMA5, MTK_DISP_RDMA, 5, NULL, 0},
  291. {DDP_COMPONENT_RDMA0_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  292. {DDP_COMPONENT_RDMA1_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  293. {DDP_COMPONENT_RDMA2_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  294. {DDP_COMPONENT_RSZ0, MTK_DISP_RSZ, 0, NULL, 0},
  295. {DDP_COMPONENT_RSZ1, MTK_DISP_RSZ, 1, NULL, 0},
  296. {DDP_COMPONENT_UFOE, MTK_DISP_UFOE, 0, &ddp_ufoe, 0},
  297. {DDP_COMPONENT_WDMA0, MTK_DISP_WDMA, 0, NULL, 1},
  298. {DDP_COMPONENT_WDMA1, MTK_DISP_WDMA, 1, NULL, 1},
  299. {DDP_COMPONENT_UFBC_WDMA0, MTK_DISP_WDMA, 2, NULL, 1},
  300. {DDP_COMPONENT_WDMA_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  301. {DDP_COMPONENT_WDMA_VIRTUAL1, MTK_DISP_VIRTUAL, -1, NULL, 0},
  302. {DDP_COMPONENT_POSTMASK0, MTK_DISP_POSTMASK, 0, NULL, 0},
  303. {DDP_COMPONENT_POSTMASK1, MTK_DISP_POSTMASK, 1, NULL, 0},
  304. {DDP_COMPONENT_DMDP_RDMA0, MTK_DMDP_RDMA, 0, NULL, 0},
  305. {DDP_COMPONENT_DMDP_HDR0, MTK_DMDP_HDR, 0, NULL, 0},
  306. {DDP_COMPONENT_DMDP_AAL0, MTK_DMDP_AAL, 0, NULL, 0},
  307. {DDP_COMPONENT_DMDP_RSZ0, MTK_DMDP_RSZ, 0, NULL, 0},
  308. {DDP_COMPONENT_DMDP_TDSHP0, MTK_DMDP_TDSHP, 0, NULL, 0},
  309. {DDP_COMPONENT_DSC0, MTK_DISP_DSC, 0, NULL, 0},
  310. {DDP_COMPONENT_MERGE0, MTK_DISP_MERGE, 0, NULL, 0},
  311. {DDP_COMPONENT_DPTX, MTK_DISP_DPTX, 0, NULL, 1},
  312. {DDP_COMPONENT_DP_INTF0, MTK_DP_INTF, 0, NULL, 1},
  313. {DDP_COMPONENT_RDMA4_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  314. {DDP_COMPONENT_RDMA5_VIRTUAL0, MTK_DISP_VIRTUAL, -1, NULL, 0},
  315. {DDP_COMPONENT_MERGE1, MTK_DISP_MERGE, 1, NULL, 0},
  316. {DDP_COMPONENT_SPR0_VIRTUAL, MTK_DISP_VIRTUAL, -1, NULL, 0},
  317. };
  318. bool mtk_ddp_comp_is_output(struct mtk_ddp_comp *comp)
  319. {
  320. if (comp->id < 0 || comp->id >= DDP_COMPONENT_ID_MAX)
  321. return false;
  322. return mtk_ddp_matches[comp->id].is_output;
  323. }
  324. void mtk_ddp_comp_get_name(struct mtk_ddp_comp *comp, char *buf, int buf_len)
  325. {
  326. int r;
  327. if (comp->id < 0 || comp->id >= DDP_COMPONENT_ID_MAX) {
  328. DDPPR_ERR("%s(), invalid id %d, set buf to 0\n",
  329. __func__, comp->id);
  330. memset(buf, 0, buf_len);
  331. return;
  332. }
  333. if (buf_len > sizeof(buf))
  334. buf_len = sizeof(buf);
  335. r = snprintf(buf, buf_len, "%s%d",
  336. mtk_ddp_comp_stem[mtk_ddp_matches[comp->id].type],
  337. mtk_ddp_matches[comp->id].alias_id);
  338. if (r < 0) {
  339. /* Handle snprintf() error */
  340. DDPPR_ERR("snprintf error\n");
  341. }
  342. }
  343. int mtk_ddp_comp_get_type(enum mtk_ddp_comp_id comp_id)
  344. {
  345. if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
  346. return -EINVAL;
  347. return mtk_ddp_matches[comp_id].type;
  348. }
  349. static bool mtk_drm_find_comp_in_ddp(struct mtk_ddp_comp ddp_comp,
  350. const struct mtk_crtc_path_data *path_data)
  351. {
  352. unsigned int i, j, ddp_mode;
  353. const enum mtk_ddp_comp_id *path = NULL;
  354. if (path_data == NULL)
  355. return false;
  356. for (ddp_mode = 0U; ddp_mode < DDP_MODE_NR; ddp_mode++)
  357. for (i = 0U; i < DDP_PATH_NR; i++) {
  358. path = path_data->path[ddp_mode][i];
  359. for (j = 0U; j < path_data->path_len[ddp_mode][i]; j++)
  360. if (ddp_comp.id == path[j])
  361. return true;
  362. }
  363. return false;
  364. }
  365. enum mtk_ddp_comp_id mtk_ddp_comp_get_id(struct device_node *node,
  366. enum mtk_ddp_comp_type comp_type)
  367. {
  368. int id;
  369. int i;
  370. if (comp_type < 0)
  371. return -EINVAL;
  372. id = of_alias_get_id(node, mtk_ddp_comp_stem[comp_type]);
  373. DDPINFO("id:%d, comp_type:%d\n", id, comp_type);
  374. for (i = 0; i < ARRAY_SIZE(mtk_ddp_matches); i++) {
  375. if (comp_type == mtk_ddp_matches[i].type &&
  376. (id < 0 || id == mtk_ddp_matches[i].alias_id))
  377. return mtk_ddp_matches[i].index;
  378. }
  379. return -EINVAL;
  380. }
  381. struct mtk_ddp_comp *mtk_ddp_comp_find_by_id(struct drm_crtc *crtc,
  382. enum mtk_ddp_comp_id comp_id)
  383. {
  384. unsigned int i = 0, j = 0, ddp_mode = 0;
  385. struct mtk_drm_crtc *mtk_crtc =
  386. container_of(crtc, struct mtk_drm_crtc, base);
  387. struct mtk_ddp_comp *comp;
  388. for_each_comp_in_all_crtc_mode(comp, mtk_crtc, i, j,
  389. ddp_mode)
  390. if (comp_id == comp->id)
  391. return comp;
  392. return NULL;
  393. }
  394. static void mtk_ddp_comp_set_larb(struct device *dev, struct device_node *node,
  395. struct mtk_ddp_comp *comp)
  396. {
  397. int ret;
  398. struct device_node *larb_node = NULL;
  399. struct platform_device *larb_pdev = NULL;
  400. enum mtk_ddp_comp_type type = mtk_ddp_comp_get_type(comp->id);
  401. unsigned int larb_id;
  402. comp->larb_dev = NULL;
  403. larb_node = of_parse_phandle(node, "mediatek,larb", 0);
  404. if (larb_node) {
  405. larb_pdev = of_find_device_by_node(larb_node);
  406. if (larb_pdev)
  407. comp->larb_dev = &larb_pdev->dev;
  408. of_node_put(larb_node);
  409. }
  410. if (!comp->larb_dev)
  411. return;
  412. ret = of_property_read_u32(node,
  413. "mediatek,smi-id", &larb_id);
  414. if (ret) {
  415. dev_err(comp->larb_dev,
  416. "read smi-id failed:%d\n", ret);
  417. return;
  418. }
  419. comp->larb_id = larb_id;
  420. /* check if this module need larb_dev */
  421. if (type == MTK_DISP_OVL || type == MTK_DISP_RDMA ||
  422. type == MTK_DISP_WDMA || type == MTK_DISP_POSTMASK) {
  423. dev_warn(dev, "%s: %s need larb device\n", __func__,
  424. mtk_dump_comp_str(comp));
  425. DDPPR_ERR("%s: smi-id:%d\n", mtk_dump_comp_str(comp),
  426. comp->larb_id);
  427. }
  428. }
  429. unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
  430. struct mtk_ddp_comp ddp_comp)
  431. {
  432. struct mtk_drm_private *private = drm->dev_private;
  433. unsigned int ret;
  434. if (mtk_drm_find_comp_in_ddp(ddp_comp, private->data->main_path_data) ==
  435. true) {
  436. ret = BIT(0);
  437. } else if (mtk_drm_find_comp_in_ddp(
  438. ddp_comp, private->data->ext_path_data) == true) {
  439. ret = BIT(1);
  440. } else if (mtk_drm_find_comp_in_ddp(
  441. ddp_comp, private->data->third_path_data) == true) {
  442. ret = BIT(2);
  443. } else {
  444. DRM_INFO("Failed to find comp in ddp table\n");
  445. ret = 0;
  446. }
  447. return ret;
  448. }
  449. int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
  450. struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id,
  451. const struct mtk_ddp_comp_funcs *funcs)
  452. {
  453. enum mtk_ddp_comp_type type;
  454. struct platform_device *comp_pdev = NULL;
  455. struct resource res;
  456. DDPINFO("%s+\n", __func__);
  457. if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
  458. return -EINVAL;
  459. type = mtk_ddp_matches[comp_id].type;
  460. comp->id = comp_id;
  461. comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;
  462. comp->dev = dev;
  463. /* get the first clk in the device node */
  464. comp->clk = of_clk_get(node, 0);
  465. if (IS_ERR(comp->clk)) {
  466. comp->clk = NULL;
  467. DDPPR_ERR("comp:%d get clock fail!\n", comp_id);
  468. }
  469. if (comp_id == DDP_COMPONENT_BLS || comp_id == DDP_COMPONENT_PWM0) {
  470. comp->regs_pa = 0;
  471. comp->regs = NULL;
  472. comp->irq = 0;
  473. return 0;
  474. }
  475. if (of_address_to_resource(node, 0, &res) != 0) {
  476. dev_err(dev, "Missing reg in %s node\n", node->full_name);
  477. return -EINVAL;
  478. }
  479. comp->regs_pa = res.start;
  480. if (comp_id == DDP_COMPONENT_DPI0 || comp_id == DDP_COMPONENT_DPI1 ||
  481. comp_id == DDP_COMPONENT_DSI0 || comp_id == DDP_COMPONENT_DSI1)
  482. comp->irq = 0;
  483. else
  484. comp->irq = of_irq_get(node, 0);
  485. comp->regs = of_iomap(node, 0);
  486. DDPINFO("[DRM]regs_pa:0x%lx, regs:0x%p, node:%s\n",
  487. (unsigned long)comp->regs_pa, comp->regs, node->full_name);
  488. /* handle cmdq related resources */
  489. comp_pdev = of_find_device_by_node(node);
  490. if (!comp_pdev) {
  491. dev_warn(dev, "Waiting for comp device %s\n", node->full_name);
  492. return -EPROBE_DEFER;
  493. }
  494. comp->cmdq_base = cmdq_register_device(&comp_pdev->dev);
  495. #if 0
  496. /* TODO: if no subsys id, use 99 instead. CMDQ owner would define 99 in
  497. * DTS afterward.
  498. */
  499. if (of_property_read_u8(node, "my_subsys_id", &comp->cmdq_subsys))
  500. comp->cmdq_subsys = 99;
  501. #endif
  502. /* handle larb resources */
  503. mtk_ddp_comp_set_larb(dev, node, comp);
  504. DDPINFO("%s-\n", __func__);
  505. return 0;
  506. }
  507. int mtk_ddp_comp_register(struct drm_device *drm, struct mtk_ddp_comp *comp)
  508. {
  509. struct mtk_drm_private *private = drm->dev_private;
  510. if (private->ddp_comp[comp->id])
  511. return -EBUSY;
  512. if (comp->id < 0)
  513. return -EINVAL;
  514. private->ddp_comp[comp->id] = comp;
  515. return 0;
  516. }
  517. void mtk_ddp_comp_unregister(struct drm_device *drm, struct mtk_ddp_comp *comp)
  518. {
  519. struct mtk_drm_private *private = drm->dev_private;
  520. private->ddp_comp[comp->id] = NULL;
  521. }
  522. void mtk_ddp_comp_clk_prepare(struct mtk_ddp_comp *comp)
  523. {
  524. int ret;
  525. if (comp == NULL)
  526. return;
  527. #ifdef CONFIG_MTK_SMI_EXT
  528. if (comp->larb_dev)
  529. smi_bus_prepare_enable(comp->larb_id, MTK_DDP_COMP_USER);
  530. #endif
  531. if (comp->clk) {
  532. ret = clk_prepare_enable(comp->clk);
  533. if (ret)
  534. DDPPR_ERR("clk prepare enable failed:%s\n",
  535. mtk_dump_comp_str(comp));
  536. }
  537. }
  538. void mtk_ddp_comp_clk_unprepare(struct mtk_ddp_comp *comp)
  539. {
  540. if (comp == NULL)
  541. return;
  542. if (comp->clk)
  543. clk_disable_unprepare(comp->clk);
  544. #ifdef CONFIG_MTK_SMI_EXT
  545. if (comp->larb_dev)
  546. smi_bus_disable_unprepare(comp->larb_id, MTK_DDP_COMP_USER);
  547. #endif
  548. }
  549. #ifdef CONFIG_MTK_IOMMU_V2
  550. static enum mtk_iommu_callback_ret_t
  551. mtk_ddp_m4u_callback(int port, unsigned long mva,
  552. void *data)
  553. {
  554. struct mtk_ddp_comp *comp = (struct mtk_ddp_comp *)data;
  555. DDPPR_ERR("fault call port=%d, mva=0x%lx, data=0x%p\n", port, mva,
  556. data);
  557. if (comp) {
  558. mtk_dump_analysis(comp);
  559. mtk_dump_reg(comp);
  560. }
  561. return MTK_IOMMU_CALLBACK_HANDLED;
  562. }
  563. #endif
  564. #define GET_M4U_PORT 0x1F
  565. void mtk_ddp_comp_iommu_enable(struct mtk_ddp_comp *comp,
  566. struct cmdq_pkt *handle)
  567. {
  568. int port, index, ret;
  569. struct resource res;
  570. if (!comp->dev || !comp->larb_dev)
  571. return;
  572. index = 0;
  573. while (1) {
  574. ret = of_property_read_u32_index(comp->dev->of_node,
  575. "iommus", index * 2 + 1, &port);
  576. if (ret < 0)
  577. break;
  578. #ifdef CONFIG_MTK_IOMMU_V2
  579. mtk_iommu_register_fault_callback(
  580. port, (mtk_iommu_fault_callback_t)mtk_ddp_m4u_callback,
  581. (void *)comp);
  582. #endif
  583. port &= (unsigned int)GET_M4U_PORT;
  584. if (of_address_to_resource(comp->larb_dev->of_node, 0, &res) !=
  585. 0) {
  586. dev_err(comp->dev, "Missing reg in %s node\n",
  587. comp->larb_dev->of_node->full_name);
  588. return;
  589. }
  590. cmdq_pkt_write(handle, NULL,
  591. res.start + SMI_LARB_NON_SEC_CON + port * 4, 0x1,
  592. 0x1);
  593. index++;
  594. }
  595. }
  596. void mt6779_mtk_sodi_config(struct drm_device *drm, enum mtk_ddp_comp_id id,
  597. struct cmdq_pkt *handle, void *data)
  598. {
  599. struct mtk_drm_private *priv = drm->dev_private;
  600. unsigned int val = 0, mask = 0;
  601. bool en = *((bool *)data);
  602. if (id == DDP_COMPONENT_ID_MAX) { /* config when top clk on */
  603. if (!en)
  604. return;
  605. val = 0x0F005506;
  606. mask = 0xFFFFFFFF;
  607. } else if (id == DDP_COMPONENT_RDMA0) {
  608. mask |= (BIT(9) + BIT(16));
  609. val |= (((!(unsigned int)en) << 9) + ((en) << 16));
  610. } else if (id == DDP_COMPONENT_RDMA1) {
  611. mask |= (BIT(11) + BIT(17));
  612. val |= (((!(unsigned int)en) << 11) + ((en) << 17));
  613. } else if (id == DDP_COMPONENT_WDMA0) {
  614. mask |= BIT(18);
  615. val |= ((en) << 18);
  616. } else
  617. return;
  618. if (handle == NULL) {
  619. unsigned int v = (readl(priv->config_regs + 0xF8) & (~mask));
  620. v += (val & mask);
  621. writel_relaxed(v, priv->config_regs + 0xF8);
  622. } else
  623. cmdq_pkt_write(handle, NULL, priv->config_regs_pa + 0xF8, val,
  624. mask);
  625. }
  626. void mt6853_mtk_sodi_config(struct drm_device *drm, enum mtk_ddp_comp_id id,
  627. struct cmdq_pkt *handle, void *data)
  628. {
  629. struct mtk_drm_private *priv = drm->dev_private;
  630. unsigned int sodi_req_val = 0, sodi_req_mask = 0;
  631. unsigned int emi_req_val = 0, emi_req_mask = 0;
  632. bool en = *((bool *)data);
  633. if (id == DDP_COMPONENT_ID_MAX) { /* config when top clk on */
  634. if (!en)
  635. return;
  636. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  637. 0, MT6873_SODI_REQ_SEL_ALL);
  638. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  639. 0, MT6873_SODI_REQ_VAL_ALL);
  640. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  641. 1, SODI_REQ_SEL_RDMA0_PD_MODE);
  642. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  643. 1, SODI_REQ_VAL_RDMA0_PD_MODE);
  644. SET_VAL_MASK(emi_req_val, emi_req_mask,
  645. 0x1, HRT_URGENT_CTL_SEL_RDMA0);
  646. SET_VAL_MASK(emi_req_val, emi_req_mask,
  647. 0x1, HRT_URGENT_CTL_SEL_WDMA0);
  648. SET_VAL_MASK(emi_req_val, emi_req_mask,
  649. 0, HRT_URGENT_CTL_VAL_RDMA0);
  650. SET_VAL_MASK(emi_req_val, emi_req_mask,
  651. 0, HRT_URGENT_CTL_VAL_WDMA0);
  652. SET_VAL_MASK(emi_req_val, emi_req_mask,
  653. 0, HRT_URGENT_CTL_VAL_RDMA4);
  654. SET_VAL_MASK(emi_req_val, emi_req_mask,
  655. 0, HRT_URGENT_CTL_VAL_MDP_RDMA4);
  656. SET_VAL_MASK(emi_req_val, emi_req_mask,
  657. 0, DVFS_HALT_MASK_SEL_RDMA0);
  658. SET_VAL_MASK(emi_req_val, emi_req_mask,
  659. 0, DVFS_HALT_MASK_SEL_RDMA4);
  660. SET_VAL_MASK(emi_req_val, emi_req_mask,
  661. 0, DVFS_HALT_MASK_SEL_WDMA0);
  662. } else if (id == DDP_COMPONENT_RDMA0) {
  663. SET_VAL_MASK(sodi_req_val, sodi_req_mask, (!en),
  664. SODI_REQ_SEL_RDMA0_CG_MODE);
  665. SET_VAL_MASK(emi_req_val, emi_req_mask, (!en),
  666. HRT_URGENT_CTL_SEL_RDMA0);
  667. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  668. DVFS_HALT_MASK_SEL_RDMA0);
  669. } else if (id == DDP_COMPONENT_WDMA0) {
  670. SET_VAL_MASK(emi_req_val, emi_req_mask, (!en),
  671. HRT_URGENT_CTL_SEL_WDMA0);
  672. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  673. DVFS_HALT_MASK_SEL_WDMA0);
  674. } else
  675. return;
  676. if (handle == NULL) {
  677. unsigned int v;
  678. v = (readl(priv->config_regs + MMSYS_SODI_REQ_MASK)
  679. & (~sodi_req_mask));
  680. v += (sodi_req_val & sodi_req_mask);
  681. writel_relaxed(v, priv->config_regs + MMSYS_SODI_REQ_MASK);
  682. v = (readl(priv->config_regs + MMSYS_EMI_REQ_CTL)
  683. & (~emi_req_mask));
  684. v += (emi_req_val & emi_req_mask);
  685. writel_relaxed(v, priv->config_regs + MMSYS_EMI_REQ_CTL);
  686. } else {
  687. cmdq_pkt_write(handle, NULL, priv->config_regs_pa +
  688. MMSYS_SODI_REQ_MASK, sodi_req_val, sodi_req_mask);
  689. cmdq_pkt_write(handle, NULL, priv->config_regs_pa +
  690. MMSYS_EMI_REQ_CTL, emi_req_val, emi_req_mask);
  691. }
  692. }
  693. void mt6833_mtk_sodi_config(struct drm_device *drm, enum mtk_ddp_comp_id id,
  694. struct cmdq_pkt *handle, void *data)
  695. {
  696. struct mtk_drm_private *priv = drm->dev_private;
  697. unsigned int sodi_req_val = 0, sodi_req_mask = 0;
  698. unsigned int emi_req_val = 0, emi_req_mask = 0;
  699. unsigned int infra_req_val = 0, infra_req_mask = 0;
  700. bool en = *((bool *)data);
  701. if (id == DDP_COMPONENT_ID_MAX) { /* config when top clk on */
  702. if (!en)
  703. return;
  704. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  705. 0, MT6873_SODI_REQ_SEL_ALL);
  706. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  707. 0, MT6873_SODI_REQ_VAL_ALL);
  708. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  709. 1, SODI_REQ_SEL_RDMA0_PD_MODE);
  710. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  711. 1, SODI_REQ_VAL_RDMA0_PD_MODE);
  712. SET_VAL_MASK(emi_req_val, emi_req_mask,
  713. 0x1, HRT_URGENT_CTL_SEL_RDMA0);
  714. SET_VAL_MASK(emi_req_val, emi_req_mask,
  715. 0x1, HRT_URGENT_CTL_SEL_WDMA0);
  716. SET_VAL_MASK(emi_req_val, emi_req_mask,
  717. 0, HRT_URGENT_CTL_VAL_RDMA0);
  718. SET_VAL_MASK(emi_req_val, emi_req_mask,
  719. 0, HRT_URGENT_CTL_VAL_WDMA0);
  720. SET_VAL_MASK(emi_req_val, emi_req_mask,
  721. 0, HRT_URGENT_CTL_VAL_RDMA4);
  722. SET_VAL_MASK(emi_req_val, emi_req_mask,
  723. 0, HRT_URGENT_CTL_VAL_MDP_RDMA4);
  724. SET_VAL_MASK(emi_req_val, emi_req_mask,
  725. 0, DVFS_HALT_MASK_SEL_RDMA0);
  726. SET_VAL_MASK(emi_req_val, emi_req_mask,
  727. 0, DVFS_HALT_MASK_SEL_RDMA4);
  728. SET_VAL_MASK(emi_req_val, emi_req_mask,
  729. 0, DVFS_HALT_MASK_SEL_WDMA0);
  730. } else if (id == DDP_COMPONENT_RDMA0) {
  731. SET_VAL_MASK(sodi_req_val, sodi_req_mask, (!en),
  732. SODI_REQ_SEL_RDMA0_CG_MODE);
  733. SET_VAL_MASK(emi_req_val, emi_req_mask, (!en),
  734. HRT_URGENT_CTL_SEL_RDMA0);
  735. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  736. DVFS_HALT_MASK_SEL_RDMA0);
  737. } else if (id == DDP_COMPONENT_WDMA0) {
  738. SET_VAL_MASK(emi_req_val, emi_req_mask, (!en),
  739. HRT_URGENT_CTL_SEL_WDMA0);
  740. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  741. DVFS_HALT_MASK_SEL_WDMA0);
  742. } else
  743. return;
  744. if (priv->data->bypass_infra_ddr_control)
  745. SET_VAL_MASK(infra_req_val, infra_req_mask,
  746. 0xf, MT6833_INFRA_FLD_DDR_MASK);
  747. if (handle == NULL) {
  748. unsigned int v;
  749. v = (readl(priv->config_regs + MMSYS_SODI_REQ_MASK)
  750. & (~sodi_req_mask));
  751. v += (sodi_req_val & sodi_req_mask);
  752. writel_relaxed(v, priv->config_regs + MMSYS_SODI_REQ_MASK);
  753. v = (readl(priv->config_regs + MMSYS_EMI_REQ_CTL)
  754. & (~emi_req_mask));
  755. v += (emi_req_val & emi_req_mask);
  756. writel_relaxed(v, priv->config_regs + MMSYS_EMI_REQ_CTL);
  757. if (priv->data->bypass_infra_ddr_control) {
  758. if (!IS_ERR(priv->infra_regs)) {
  759. v = (readl(priv->infra_regs + MT6833_INFRA_DISP_DDR_CTL)
  760. | MT6833_INFRA_FLD_DDR_MASK);
  761. writel_relaxed(v, priv->infra_regs + MT6833_INFRA_DISP_DDR_CTL);
  762. } else
  763. DDPINFO("%s: failed to disable infra ddr control\n", __func__);
  764. }
  765. } else {
  766. cmdq_pkt_write(handle, NULL, priv->config_regs_pa +
  767. MMSYS_SODI_REQ_MASK, sodi_req_val, sodi_req_mask);
  768. cmdq_pkt_write(handle, NULL, priv->config_regs_pa +
  769. MMSYS_EMI_REQ_CTL, emi_req_val, emi_req_mask);
  770. if (priv->data->bypass_infra_ddr_control) {
  771. if (priv->infra_regs_pa) {
  772. cmdq_pkt_write(handle, NULL, priv->infra_regs_pa +
  773. MT6833_INFRA_DISP_DDR_CTL,
  774. infra_req_val, infra_req_mask);
  775. } else
  776. DDPINFO("%s: failed to disable infra ddr control\n", __func__);
  777. }
  778. }
  779. }
  780. void mt6873_mtk_sodi_config(struct drm_device *drm, enum mtk_ddp_comp_id id,
  781. struct cmdq_pkt *handle, void *data)
  782. {
  783. struct mtk_drm_private *priv = drm->dev_private;
  784. unsigned int sodi_req_val = 0, sodi_req_mask = 0;
  785. unsigned int emi_req_val = 0, emi_req_mask = 0;
  786. bool en = *((bool *)data);
  787. if (id == DDP_COMPONENT_ID_MAX) { /* config when top clk on */
  788. if (!en)
  789. return;
  790. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  791. 0, MT6873_SODI_REQ_SEL_ALL);
  792. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  793. 0, MT6873_SODI_REQ_VAL_ALL);
  794. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  795. 1, SODI_REQ_SEL_RDMA0_PD_MODE);
  796. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  797. 1, SODI_REQ_VAL_RDMA0_PD_MODE);
  798. SET_VAL_MASK(emi_req_val, emi_req_mask,
  799. 0x1, HRT_URGENT_CTL_SEL_RDMA0);
  800. SET_VAL_MASK(emi_req_val, emi_req_mask,
  801. 0x1, HRT_URGENT_CTL_SEL_WDMA0);
  802. SET_VAL_MASK(emi_req_val, emi_req_mask,
  803. 0x1, HRT_URGENT_CTL_SEL_RDMA4);
  804. SET_VAL_MASK(emi_req_val, emi_req_mask,
  805. 0x1, HRT_URGENT_CTL_SEL_MDP_RDMA4);
  806. SET_VAL_MASK(emi_req_val, emi_req_mask,
  807. 0, HRT_URGENT_CTL_VAL_RDMA0);
  808. SET_VAL_MASK(emi_req_val, emi_req_mask,
  809. 0, HRT_URGENT_CTL_VAL_WDMA0);
  810. SET_VAL_MASK(emi_req_val, emi_req_mask,
  811. 0, HRT_URGENT_CTL_VAL_RDMA4);
  812. SET_VAL_MASK(emi_req_val, emi_req_mask,
  813. 0, HRT_URGENT_CTL_VAL_MDP_RDMA4);
  814. SET_VAL_MASK(emi_req_val, emi_req_mask,
  815. 0, DVFS_HALT_MASK_SEL_RDMA0);
  816. SET_VAL_MASK(emi_req_val, emi_req_mask,
  817. 0, DVFS_HALT_MASK_SEL_RDMA4);
  818. SET_VAL_MASK(emi_req_val, emi_req_mask,
  819. 0, DVFS_HALT_MASK_SEL_WDMA0);
  820. } else if (id == DDP_COMPONENT_RDMA0) {
  821. SET_VAL_MASK(sodi_req_val, sodi_req_mask, (!(unsigned int)en),
  822. SODI_REQ_SEL_RDMA0_CG_MODE);
  823. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  824. HRT_URGENT_CTL_SEL_RDMA0);
  825. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  826. DVFS_HALT_MASK_SEL_RDMA0);
  827. } else if (id == DDP_COMPONENT_RDMA4) {
  828. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  829. HRT_URGENT_CTL_SEL_RDMA4);
  830. SET_VAL_MASK(emi_req_val, emi_req_mask, (unsigned int)en,
  831. DVFS_HALT_MASK_SEL_RDMA4);
  832. } else if (id == DDP_COMPONENT_WDMA0) {
  833. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  834. HRT_URGENT_CTL_SEL_WDMA0);
  835. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  836. DVFS_HALT_MASK_SEL_WDMA0);
  837. } else
  838. return;
  839. if (handle == NULL) {
  840. unsigned int v;
  841. v = (readl(priv->config_regs + MMSYS_SODI_REQ_MASK)
  842. & (~sodi_req_mask));
  843. v += (sodi_req_val & sodi_req_mask);
  844. writel_relaxed(v, priv->config_regs + MMSYS_SODI_REQ_MASK);
  845. v = (readl(priv->config_regs + MMSYS_EMI_REQ_CTL)
  846. & (~emi_req_mask));
  847. v += (emi_req_val & emi_req_mask);
  848. writel_relaxed(v, priv->config_regs + MMSYS_EMI_REQ_CTL);
  849. } else {
  850. cmdq_pkt_write(handle, NULL, priv->config_regs_pa +
  851. MMSYS_SODI_REQ_MASK, sodi_req_val, sodi_req_mask);
  852. cmdq_pkt_write(handle, NULL, priv->config_regs_pa +
  853. MMSYS_EMI_REQ_CTL, emi_req_val, emi_req_mask);
  854. }
  855. }
  856. void mt6885_mtk_sodi_config(struct drm_device *drm, enum mtk_ddp_comp_id id,
  857. struct cmdq_pkt *handle, void *data)
  858. {
  859. struct mtk_drm_private *priv = drm->dev_private;
  860. unsigned int sodi_req_val = 0, sodi_req_mask = 0;
  861. unsigned int emi_req_val = 0, emi_req_mask = 0;
  862. bool en = *((bool *)data);
  863. if (id == DDP_COMPONENT_ID_MAX) { /* config when top clk on */
  864. if (!en)
  865. return;
  866. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  867. 0, SODI_REQ_SEL_ALL);
  868. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  869. 0, SODI_REQ_VAL_ALL);
  870. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  871. 1, SODI_REQ_SEL_RDMA0_PD_MODE);
  872. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  873. 1, SODI_REQ_VAL_RDMA0_PD_MODE);
  874. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  875. 1, SODI_REQ_SEL_RDMA1_PD_MODE);
  876. SET_VAL_MASK(sodi_req_val, sodi_req_mask,
  877. 1, SODI_REQ_VAL_RDMA1_PD_MODE);
  878. SET_VAL_MASK(emi_req_val, emi_req_mask,
  879. 0xFF, HRT_URGENT_CTL_SEL_ALL);
  880. SET_VAL_MASK(emi_req_val, emi_req_mask,
  881. 0, HRT_URGENT_CTL_VAL_ALL);
  882. SET_VAL_MASK(emi_req_val, emi_req_mask,
  883. 0, DVFS_HALT_MASK_SEL_ALL);
  884. } else if (id == DDP_COMPONENT_RDMA0) {
  885. SET_VAL_MASK(sodi_req_val, sodi_req_mask, (!(unsigned int)en),
  886. SODI_REQ_SEL_RDMA0_CG_MODE);
  887. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  888. HRT_URGENT_CTL_SEL_RDMA0);
  889. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  890. DVFS_HALT_MASK_SEL_RDMA0);
  891. } else if (id == DDP_COMPONENT_RDMA1) {
  892. SET_VAL_MASK(sodi_req_val, sodi_req_mask, (!(unsigned int)en),
  893. SODI_REQ_SEL_RDMA1_CG_MODE);
  894. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  895. HRT_URGENT_CTL_SEL_RDMA1);
  896. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  897. DVFS_HALT_MASK_SEL_RDMA1);
  898. } else if (id == DDP_COMPONENT_RDMA4) {
  899. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  900. HRT_URGENT_CTL_SEL_RDMA4);
  901. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  902. DVFS_HALT_MASK_SEL_RDMA4);
  903. } else if (id == DDP_COMPONENT_RDMA5) {
  904. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  905. HRT_URGENT_CTL_SEL_RDMA5);
  906. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  907. DVFS_HALT_MASK_SEL_RDMA5);
  908. } else if (id == DDP_COMPONENT_WDMA0) {
  909. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  910. HRT_URGENT_CTL_SEL_WDMA0);
  911. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  912. DVFS_HALT_MASK_SEL_WDMA0);
  913. } else if (id == DDP_COMPONENT_WDMA1) {
  914. SET_VAL_MASK(emi_req_val, emi_req_mask, (!(unsigned int)en),
  915. HRT_URGENT_CTL_SEL_WDMA1);
  916. SET_VAL_MASK(emi_req_val, emi_req_mask, en,
  917. DVFS_HALT_MASK_SEL_WDMA1);
  918. } else
  919. return;
  920. if (handle == NULL) {
  921. unsigned int v;
  922. v = (readl(priv->config_regs + MMSYS_SODI_REQ_MASK)
  923. & (~sodi_req_mask));
  924. v += (sodi_req_val & sodi_req_mask);
  925. writel_relaxed(v, priv->config_regs + MMSYS_SODI_REQ_MASK);
  926. v = (readl(priv->config_regs + MMSYS_EMI_REQ_CTL)
  927. & (~emi_req_mask));
  928. v += (emi_req_val & emi_req_mask);
  929. writel_relaxed(v, priv->config_regs + MMSYS_EMI_REQ_CTL);
  930. } else {
  931. cmdq_pkt_write(handle, NULL, priv->config_regs_pa +
  932. MMSYS_SODI_REQ_MASK, sodi_req_val, sodi_req_mask);
  933. cmdq_pkt_write(handle, NULL, priv->config_regs_pa +
  934. MMSYS_EMI_REQ_CTL, emi_req_val, emi_req_mask);
  935. }
  936. }
  937. int mtk_ddp_comp_helper_get_opt(struct mtk_ddp_comp *comp,
  938. enum MTK_DRM_HELPER_OPT option)
  939. {
  940. struct mtk_drm_crtc *mtk_crtc = comp->mtk_crtc;
  941. struct mtk_drm_private *priv = NULL;
  942. struct mtk_drm_helper *helper_opt = NULL;
  943. if (!mtk_crtc) {
  944. DDPINFO("%s: crtc is empty\n", __func__);
  945. return -EINVAL;
  946. }
  947. priv = mtk_crtc->base.dev->dev_private;
  948. helper_opt = priv->helper_opt;
  949. return mtk_drm_helper_get_opt(helper_opt, option);
  950. }