mtk_disp_postmask.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*
  2. * Copyright (c) 2019 MediaTek Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <drm/drmP.h>
  14. #include <linux/clk.h>
  15. #include <linux/component.h>
  16. #include <linux/of_device.h>
  17. #include <linux/of_irq.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/pm_runtime.h>
  20. #include <linux/soc/mediatek/mtk-cmdq.h>
  21. #include "mtk_drm_crtc.h"
  22. #include "mtk_drm_ddp_comp.h"
  23. #include "mtk_drm_drv.h"
  24. #include "mtk_log.h"
  25. #include "mtk_dump.h"
  26. #include "mtk_drm_mmp.h"
  27. #include "mtk_drm_gem.h"
  28. #define POSTMASK_MASK_MAX_NUM 96
  29. #define POSTMASK_GRAD_MAX_NUM 192
  30. #define POSTMASK_DRAM_MODE
  31. #define DISP_POSTMASK_EN 0x0
  32. #define DISP_POSTMASK_INTEN 0x8
  33. #define INTEN_FLD_PM_IF_FME_END_INTEN REG_FLD_MSB_LSB(0, 0)
  34. #define INTEN_FLD_PM_FME_CPL_INTEN REG_FLD_MSB_LSB(1, 1)
  35. #define INTEN_FLD_PM_START_INTEN REG_FLD_MSB_LSB(2, 2)
  36. #define INTEN_FLD_PM_ABNORMAL_SOF_INTEN REG_FLD_MSB_LSB(4, 4)
  37. #define INTEN_FLD_RDMA_FME_UND_INTEN REG_FLD_MSB_LSB(8, 8)
  38. #define INTEN_FLD_RDMA_FME_SWRST_DONE_INTEN REG_FLD_MSB_LSB(9, 9)
  39. #define INTEN_FLD_RDMA_FME_HWRST_DONE_INTEN REG_FLD_MSB_LSB(10, 10)
  40. #define INTEN_FLD_RDMA_EOF_ABNORMAL_INTEN REG_FLD_MSB_LSB(11, 11)
  41. #define INTEN_FLD_RDMA_SMI_UNDERFLOW_INTEN REG_FLD_MSB_LSB(12, 12)
  42. #define DISP_POSTMASK_INTSTA 0xC
  43. #define DISP_POSTMASK_CFG 0x20
  44. #define CFG_FLD_STALL_CG_ON REG_FLD_MSB_LSB(8, 8)
  45. #define CFG_FLD_GCLAST_EN REG_FLD_MSB_LSB(6, 6)
  46. #define CFG_FLD_BGCLR_IN_SEL REG_FLD_MSB_LSB(2, 2)
  47. #define CFG_FLD_DRAM_MODE REG_FLD_MSB_LSB(1, 1)
  48. #define CFG_FLD_RELAY_MODE REG_FLD_MSB_LSB(0, 0)
  49. #define DISP_POSTMASK_SIZE 0x30
  50. #define DISP_POSTMASK_SRAM_CFG 0x40
  51. #define SRAM_CFG_FLD_MASK_NUM_SW_SET REG_FLD_MSB_LSB(11, 4)
  52. #define SRAM_CFG_FLD_MASK_L_TOP_EN REG_FLD_MSB_LSB(3, 3)
  53. #define SRAM_CFG_FLD_MASK_L_BOTTOM_EN REG_FLD_MSB_LSB(2, 2)
  54. #define SRAM_CFG_FLD_MASK_R_TOP_EN REG_FLD_MSB_LSB(1, 1)
  55. #define SRAM_CFG_FLD_MASK_R_BOTTOM_EN REG_FLD_MSB_LSB(0, 0)
  56. #define DISP_POSTMASK_BLEND_CFG 0x50
  57. #define BLEND_CFG_FLD_CONST_BLD REG_FLD_MSB_LSB(2, 2)
  58. #define BLEND_CFG_FLD_PARGB_BLD REG_FLD_MSB_LSB(1, 1)
  59. #define BLEND_CFG_FLD_A_EN REG_FLD_MSB_LSB(0, 0)
  60. #define DISP_POSTMASK_ROI_BGCLR 0x54
  61. #define DISP_POSTMASK_MASK_CLR 0x58
  62. #define DISP_REG_POSTMASK_SODI 0x60
  63. #define PM_MASK_THRESHOLD_LOW_FOR_SODI REG_FLD_MSB_LSB(13, 0)
  64. #define PM_MASK_THRESHOLD_HIGH_FOR_SODI REG_FLD_MSB_LSB(29, 16)
  65. #define DISP_POSTMASK_STATUS 0xA0
  66. #define DISP_POSTMASK_INPUT_COUNT 0xA4
  67. #define DISP_POSTMASK_MEM_ADDR 0x100
  68. #define DISP_POSTMASK_MEM_LENGTH 0x104
  69. #define DISP_POSTMASK_RDMA_FIFO_CTRL 0x108
  70. #define DISP_POSTMASK_MEM_GMC_SETTING2 0x10C
  71. #define MEM_GMC_FLD_FORCE_REQ_TH REG_FLD_MSB_LSB(30, 30)
  72. #define MEM_GMC_FLD_REQ_TH_ULTRA REG_FLD_MSB_LSB(29, 29)
  73. #define MEM_GMC_FLD_REQ_TH_PREULTRA REG_FLD_MSB_LSB(28, 28)
  74. #define MEM_GMC_FLD_ISSUE_REQ_TH_URG REG_FLD_MSB_LSB(27, 16)
  75. #define MEM_GMC_FLD_ISSUE_REQ_TH REG_FLD_MSB_LSB(11, 0)
  76. #define DISP_POSTMASK_PAUSE_REGION 0x110
  77. #define PAUSE_REGION_FLD_RDMA_PAUSE_END REG_FLD_MSB_LSB(27, 16)
  78. #define PAUSE_REGION_FLD_RDMA_PAUSE_START REG_FLD_MSB_LSB(11, 0)
  79. #define DISP_POSTMASK_RDMA_GREQ_NUM 0x130
  80. #define GREQ_FLD_IOBUF_FLUSH_ULTRA REG_FLD_MSB_LSB(31, 31)
  81. #define GREQ_FLD_IOBUF_FLUSH_PREULTRA REG_FLD_MSB_LSB(30, 30)
  82. #define GREQ_FLD_GRP_BRK_STOP REG_FLD_MSB_LSB(29, 29)
  83. #define GREQ_FLD_GRP_END_STOP REG_FLD_MSB_LSB(28, 28)
  84. #define GREQ_FLD_GREQ_STOP_EN REG_FLD_MSB_LSB(27, 27)
  85. #define GREQ_FLD_GREQ_DIS_CNT REG_FLD_MSB_LSB(26, 24)
  86. #define GREQ_FLD_OSTD_GREQ_NUM REG_FLD_MSB_LSB(23, 16)
  87. #define GREQ_FLD_GREQ_NUM_SHT REG_FLD_MSB_LSB(14, 13)
  88. #define GREQ_FLD_GREQ_NUM_SHT_VAL REG_FLD_MSB_LSB(12, 12)
  89. #define GREQ_FLD_GREQ_URG_NUM REG_FLD_MSB_LSB(7, 4)
  90. #define GREQ_FLD_GREQ_NUM REG_FLD_MSB_LSB(3, 0)
  91. #define DISP_POSTMASK_RDMA_GREQ_URG_NUM 0x134
  92. #define GREQ_URG_FLD_ARB_URG_BIAS REG_FLD_MSB_LSB(12, 12)
  93. #define GREQ_URG_FLD_ARB_GREQ_URG_TH REG_FLD_MSB_LSB(11, 0)
  94. #define DISP_POSTMASK_RDMA_ULTRA_SRC 0x140
  95. #define ULTRA_FLD_ULTRA_RDMA_SRC REG_FLD_MSB_LSB(15, 14)
  96. #define ULTRA_FLD_ULTRA_ROI_END_SRC REG_FLD_MSB_LSB(13, 12)
  97. #define ULTRA_FLD_ULTRA_SMI_SRC REG_FLD_MSB_LSB(11, 10)
  98. #define ULTRA_FLD_ULTRA_BUF_SRC REG_FLD_MSB_LSB(9, 8)
  99. #define ULTRA_FLD_PREULTRA_RDMA_SRC REG_FLD_MSB_LSB(7, 6)
  100. #define ULTRA_FLD_PREULTRA_ROI_END_SRC REG_FLD_MSB_LSB(5, 4)
  101. #define ULTRA_FLD_PREULTRA_SMI_SRC REG_FLD_MSB_LSB(3, 2)
  102. #define ULTRA_FLD_PREULTRA_BUF_SRC REG_FLD_MSB_LSB(1, 0)
  103. #define DISP_POSTMASK_RDMA_BUF_LOW_TH 0x144
  104. #define TH_FLD_RDMA_PREULTRA_LOW_TH REG_FLD_MSB_LSB(23, 12)
  105. #define TH_FLD_RDMA_ULTRA_LOW_TH REG_FLD_MSB_LSB(11, 0)
  106. #define DISP_POSTMASK_RDMA_BUF_HIGH_TH 0x148
  107. #define TH_FLD_RDMA_PREULTRA_HIGH_DIS REG_FLD_MSB_LSB(31, 31)
  108. #define TH_FLD_RDMA_PREULTRA_HIGH_TH REG_FLD_MSB_LSB(23, 12)
  109. #define DISP_POSTMASK_NUM_0 0x800
  110. #define DISP_POSTMASK_NUM(n) (DISP_POSTMASK_NUM_0 + (0x4 * (n)))
  111. #define DISP_POSTMASK_GRAD_VAL_0 0xA00
  112. #define DISP_POSTMASK_GRAD_VAL(n) (DISP_POSTMASK_GRAD_VAL_0 + (0x4 * (n)))
  113. struct mtk_disp_postmask_data {
  114. bool support_shadow;
  115. };
  116. struct mtk_disp_postmask {
  117. struct mtk_ddp_comp ddp_comp;
  118. struct drm_crtc *crtc;
  119. const struct mtk_disp_postmask_data *data;
  120. unsigned int underflow_cnt;
  121. unsigned int abnormal_cnt;
  122. };
  123. static irqreturn_t mtk_postmask_irq_handler(int irq, void *dev_id)
  124. {
  125. struct mtk_disp_postmask *priv = dev_id;
  126. struct mtk_ddp_comp *postmask = &priv->ddp_comp;
  127. unsigned int val = 0;
  128. unsigned int ret = 0;
  129. if (mtk_drm_top_clk_isr_get("postmask_irq") == false) {
  130. DDPIRQ("%s, top clk off\n", __func__);
  131. return IRQ_NONE;
  132. }
  133. val = readl(postmask->regs + DISP_POSTMASK_INTSTA);
  134. if (!val) {
  135. ret = IRQ_NONE;
  136. goto out;
  137. }
  138. DRM_MMP_MARK(IRQ, irq, val);
  139. DRM_MMP_MARK(postmask0, val, 0);
  140. if (val & 0x110)
  141. DRM_MMP_MARK(abnormal_irq, val, postmask->id);
  142. DDPIRQ("%s irq, val:0x%x\n", mtk_dump_comp_str(postmask), val);
  143. writel(~val, postmask->regs + DISP_POSTMASK_INTSTA);
  144. if (val & (1 << 0))
  145. DDPIRQ("[IRQ] %s: input frame end!\n",
  146. mtk_dump_comp_str(postmask));
  147. if (val & (1 << 1))
  148. DDPIRQ("[IRQ] %s: output frame end!\n",
  149. mtk_dump_comp_str(postmask));
  150. if (val & (1 << 2))
  151. DDPIRQ("[IRQ] %s: frame start!\n", mtk_dump_comp_str(postmask));
  152. if (val & (1 << 4)) {
  153. DDPPR_ERR("[IRQ] %s: abnormal SOF! cnt=%d\n",
  154. mtk_dump_comp_str(postmask), priv->abnormal_cnt);
  155. priv->abnormal_cnt++;
  156. }
  157. if (val & (1 << 8)) {
  158. DDPPR_ERR("[IRQ] %s: frame underflow! cnt=%d\n",
  159. mtk_dump_comp_str(postmask), priv->underflow_cnt);
  160. priv->underflow_cnt++;
  161. }
  162. ret = IRQ_HANDLED;
  163. out:
  164. mtk_drm_top_clk_isr_put("postmask_irq");
  165. return ret;
  166. }
  167. static void mtk_postmask_config(struct mtk_ddp_comp *comp,
  168. struct mtk_ddp_config *cfg,
  169. struct cmdq_pkt *handle)
  170. {
  171. unsigned int value;
  172. struct mtk_panel_params *panel_ext =
  173. mtk_drm_get_lcm_ext_params(&comp->mtk_crtc->base);
  174. #ifdef CONFIG_MTK_ROUND_CORNER_SUPPORT
  175. #ifndef POSTMASK_DRAM_MODE
  176. unsigned int i = 0;
  177. unsigned int num = 0;
  178. #else
  179. struct mtk_drm_gem_obj *gem;
  180. #endif
  181. #endif
  182. value = (REG_FLD_VAL((BLEND_CFG_FLD_A_EN), 1) |
  183. REG_FLD_VAL((BLEND_CFG_FLD_PARGB_BLD), 0) |
  184. REG_FLD_VAL((BLEND_CFG_FLD_CONST_BLD), 0));
  185. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_BLEND_CFG, handle);
  186. mtk_ddp_write_relaxed(comp, 0xff000000, DISP_POSTMASK_ROI_BGCLR,
  187. handle);
  188. mtk_ddp_write_relaxed(comp, 0xff000000, DISP_POSTMASK_MASK_CLR, handle);
  189. value = (cfg->w << 16) + cfg->h;
  190. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_SIZE, handle);
  191. if (!panel_ext)
  192. DDPPR_ERR("%s:panel_ext not found\n", __func__);
  193. if (panel_ext && panel_ext->round_corner_en) {
  194. #ifdef CONFIG_MTK_ROUND_CORNER_SUPPORT
  195. value = (REG_FLD_VAL((PAUSE_REGION_FLD_RDMA_PAUSE_START),
  196. panel_ext->corner_pattern_height) |
  197. REG_FLD_VAL(
  198. (PAUSE_REGION_FLD_RDMA_PAUSE_END),
  199. cfg->h -
  200. panel_ext->corner_pattern_height_bot));
  201. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_PAUSE_REGION,
  202. handle);
  203. value = (REG_FLD_VAL((MEM_GMC_FLD_ISSUE_REQ_TH), 63) |
  204. REG_FLD_VAL((MEM_GMC_FLD_ISSUE_REQ_TH_URG), 63) |
  205. REG_FLD_VAL((MEM_GMC_FLD_REQ_TH_PREULTRA), 0) |
  206. REG_FLD_VAL((MEM_GMC_FLD_REQ_TH_ULTRA), 1) |
  207. REG_FLD_VAL((MEM_GMC_FLD_FORCE_REQ_TH), 0));
  208. mtk_ddp_write_relaxed(comp, value,
  209. DISP_POSTMASK_MEM_GMC_SETTING2, handle);
  210. value = (REG_FLD_VAL((GREQ_FLD_GREQ_NUM), 7) |
  211. REG_FLD_VAL((GREQ_FLD_GREQ_URG_NUM), 7) |
  212. REG_FLD_VAL((GREQ_FLD_GREQ_NUM_SHT_VAL), 1) |
  213. REG_FLD_VAL((GREQ_FLD_GREQ_NUM_SHT), 0) |
  214. REG_FLD_VAL((GREQ_FLD_OSTD_GREQ_NUM), 0xFF) |
  215. REG_FLD_VAL((GREQ_FLD_GREQ_DIS_CNT), 1) |
  216. REG_FLD_VAL((GREQ_FLD_GREQ_STOP_EN), 0) |
  217. REG_FLD_VAL((GREQ_FLD_GRP_END_STOP), 1) |
  218. REG_FLD_VAL((GREQ_FLD_GRP_BRK_STOP), 1) |
  219. REG_FLD_VAL((GREQ_FLD_IOBUF_FLUSH_PREULTRA), 1) |
  220. REG_FLD_VAL((GREQ_FLD_IOBUF_FLUSH_ULTRA), 1));
  221. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_RDMA_GREQ_NUM,
  222. handle);
  223. value = (REG_FLD_VAL((GREQ_URG_FLD_ARB_GREQ_URG_TH), 0) |
  224. REG_FLD_VAL((GREQ_URG_FLD_ARB_URG_BIAS), 0));
  225. mtk_ddp_write_relaxed(comp, value,
  226. DISP_POSTMASK_RDMA_GREQ_URG_NUM, handle);
  227. value = (REG_FLD_VAL((ULTRA_FLD_PREULTRA_BUF_SRC), 0) |
  228. REG_FLD_VAL((ULTRA_FLD_PREULTRA_SMI_SRC), 1) |
  229. REG_FLD_VAL((ULTRA_FLD_PREULTRA_ROI_END_SRC), 0) |
  230. REG_FLD_VAL((ULTRA_FLD_PREULTRA_RDMA_SRC), 0) |
  231. REG_FLD_VAL((ULTRA_FLD_ULTRA_BUF_SRC), 0) |
  232. REG_FLD_VAL((ULTRA_FLD_ULTRA_SMI_SRC), 1) |
  233. REG_FLD_VAL((ULTRA_FLD_ULTRA_ROI_END_SRC), 0) |
  234. REG_FLD_VAL((ULTRA_FLD_ULTRA_RDMA_SRC), 0));
  235. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_RDMA_ULTRA_SRC,
  236. handle);
  237. value = (REG_FLD_VAL((TH_FLD_RDMA_ULTRA_LOW_TH), 0xFFF) |
  238. REG_FLD_VAL((TH_FLD_RDMA_PREULTRA_LOW_TH), 0xFFF));
  239. mtk_ddp_write_relaxed(comp, value,
  240. DISP_POSTMASK_RDMA_BUF_LOW_TH, handle);
  241. value = (REG_FLD_VAL((TH_FLD_RDMA_PREULTRA_HIGH_TH), 0xFFF) |
  242. REG_FLD_VAL((TH_FLD_RDMA_PREULTRA_HIGH_DIS), 0));
  243. mtk_ddp_write_relaxed(comp, value,
  244. DISP_POSTMASK_RDMA_BUF_HIGH_TH, handle);
  245. #ifdef POSTMASK_DRAM_MODE
  246. value = (REG_FLD_VAL((CFG_FLD_RELAY_MODE), 0) |
  247. REG_FLD_VAL((CFG_FLD_DRAM_MODE), 1) |
  248. REG_FLD_VAL((CFG_FLD_BGCLR_IN_SEL), 1) |
  249. REG_FLD_VAL((CFG_FLD_GCLAST_EN), 1) |
  250. REG_FLD_VAL((CFG_FLD_STALL_CG_ON), 1));
  251. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_CFG, handle);
  252. gem = comp->mtk_crtc->round_corner_gem;
  253. value = (unsigned int)gem->dma_addr;
  254. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_MEM_ADDR,
  255. handle);
  256. mtk_ddp_write_relaxed(comp, panel_ext->corner_pattern_tp_size,
  257. DISP_POSTMASK_MEM_LENGTH, handle);
  258. #else
  259. value = (REG_FLD_VAL((CFG_FLD_RELAY_MODE), 0) |
  260. REG_FLD_VAL((CFG_FLD_DRAM_MODE), 0) |
  261. REG_FLD_VAL((CFG_FLD_BGCLR_IN_SEL), 1) |
  262. REG_FLD_VAL((CFG_FLD_GCLAST_EN), 1) |
  263. REG_FLD_VAL((CFG_FLD_STALL_CG_ON), 1));
  264. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_CFG, handle);
  265. value = (REG_FLD_VAL((SRAM_CFG_FLD_MASK_NUM_SW_SET),
  266. panel_ext->corner_pattern_height) |
  267. REG_FLD_VAL((SRAM_CFG_FLD_MASK_L_TOP_EN), 1) |
  268. REG_FLD_VAL((SRAM_CFG_FLD_MASK_L_BOTTOM_EN), 1) |
  269. REG_FLD_VAL((SRAM_CFG_FLD_MASK_R_TOP_EN), 1) |
  270. REG_FLD_VAL((SRAM_CFG_FLD_MASK_R_BOTTOM_EN), 1));
  271. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_SRAM_CFG,
  272. handle);
  273. num = POSTMASK_MASK_MAX_NUM;
  274. for (i = 0; i < num; i++) {
  275. mtk_ddp_write_relaxed(comp, 0x1F001F00,
  276. DISP_POSTMASK_NUM(i), handle);
  277. }
  278. num = POSTMASK_GRAD_MAX_NUM;
  279. for (i = 0; i < num; i++) {
  280. mtk_ddp_write_relaxed(
  281. comp, 0x0, DISP_POSTMASK_GRAD_VAL(i), handle);
  282. }
  283. #endif
  284. #endif
  285. /* config relay mode */
  286. } else {
  287. value = (REG_FLD_VAL((CFG_FLD_RELAY_MODE), 1) |
  288. REG_FLD_VAL((CFG_FLD_DRAM_MODE), 1) |
  289. REG_FLD_VAL((CFG_FLD_BGCLR_IN_SEL), 1) |
  290. REG_FLD_VAL((CFG_FLD_GCLAST_EN), 1) |
  291. REG_FLD_VAL((CFG_FLD_STALL_CG_ON), 1));
  292. mtk_ddp_write_relaxed(comp, value, DISP_POSTMASK_CFG, handle);
  293. }
  294. }
  295. int mtk_postmask_dump(struct mtk_ddp_comp *comp)
  296. {
  297. void __iomem *baddr = comp->regs;
  298. DDPDUMP("== %s REGS ==\n", mtk_dump_comp_str(comp));
  299. mtk_serial_dump_reg(baddr, 0x0, 4);
  300. mtk_serial_dump_reg(baddr, 0x20, 1);
  301. mtk_serial_dump_reg(baddr, 0x30, 1);
  302. mtk_serial_dump_reg(baddr, 0x40, 3);
  303. mtk_serial_dump_reg(baddr, 0x50, 3);
  304. mtk_serial_dump_reg(baddr, 0xA0, 2);
  305. mtk_serial_dump_reg(baddr, 0xB0, 3);
  306. mtk_serial_dump_reg(baddr, 0x100, 4);
  307. mtk_serial_dump_reg(baddr, 0x110, 1);
  308. mtk_serial_dump_reg(baddr, 0x130, 2);
  309. mtk_serial_dump_reg(baddr, 0x140, 3);
  310. return 0;
  311. }
  312. int mtk_postmask_analysis(struct mtk_ddp_comp *comp)
  313. {
  314. void __iomem *baddr = comp->regs;
  315. DDPDUMP("== %s ANALYSIS ==\n", mtk_dump_comp_str(comp));
  316. DDPDUMP("en=%d,cfg=0x%x,size=(%dx%d)\n",
  317. readl(DISP_POSTMASK_EN + baddr) & 0x1,
  318. readl(DISP_POSTMASK_CFG + baddr),
  319. (readl(DISP_POSTMASK_SIZE + baddr) >> 16) & 0x1fff,
  320. readl(DISP_POSTMASK_SIZE + baddr) & 0x1fff);
  321. DDPDUMP("blend_cfg=0x%x,bg=0x%x,mask=0x%x\n",
  322. readl(DISP_POSTMASK_BLEND_CFG + baddr),
  323. readl(DISP_POSTMASK_ROI_BGCLR + baddr),
  324. readl(DISP_POSTMASK_MASK_CLR + baddr));
  325. DDPDUMP("fifo_cfg=%d,gmc=0x%x,threshold=(0x%x,0x%x)\n",
  326. readl(DISP_POSTMASK_RDMA_FIFO_CTRL + baddr),
  327. readl(DISP_POSTMASK_MEM_GMC_SETTING2 + baddr),
  328. readl(DISP_POSTMASK_RDMA_BUF_LOW_TH + baddr),
  329. readl(DISP_POSTMASK_RDMA_BUF_HIGH_TH + baddr));
  330. DDPDUMP("mem_addr=0x%x,length=0x%x\n",
  331. readl(DISP_POSTMASK_MEM_ADDR + baddr),
  332. readl(DISP_POSTMASK_MEM_LENGTH + baddr));
  333. DDPDUMP("status=0x%x,cur_pos=0x%x\n",
  334. readl(DISP_POSTMASK_STATUS + baddr),
  335. readl(DISP_POSTMASK_INPUT_COUNT + baddr));
  336. return 0;
  337. }
  338. static int mtk_postmask_io_cmd(struct mtk_ddp_comp *comp,
  339. struct cmdq_pkt *handle,
  340. enum mtk_ddp_io_cmd io_cmd, void *params);
  341. static void mtk_postmask_start(struct mtk_ddp_comp *comp,
  342. struct cmdq_pkt *handle)
  343. {
  344. DDPDBG("%s\n", __func__);
  345. mtk_postmask_io_cmd(comp, handle, IRQ_LEVEL_ALL, NULL);
  346. cmdq_pkt_write(handle, comp->cmdq_base,
  347. comp->regs_pa + DISP_POSTMASK_EN, 1, ~0);
  348. }
  349. static void mtk_postmask_stop(struct mtk_ddp_comp *comp,
  350. struct cmdq_pkt *handle)
  351. {
  352. DDPDBG("%s\n", __func__);
  353. cmdq_pkt_write(handle, comp->cmdq_base,
  354. comp->regs_pa + DISP_POSTMASK_INTEN, 0, ~0);
  355. cmdq_pkt_write(handle, comp->cmdq_base,
  356. comp->regs_pa + DISP_POSTMASK_EN, 0, ~0);
  357. cmdq_pkt_write(handle, comp->cmdq_base,
  358. comp->regs_pa + DISP_POSTMASK_INTSTA, 0, ~0);
  359. }
  360. static int mtk_disp_postmask_bind(struct device *dev, struct device *master,
  361. void *data)
  362. {
  363. struct mtk_disp_postmask *priv = dev_get_drvdata(dev);
  364. struct drm_device *drm_dev = data;
  365. int ret;
  366. DDPINFO("%s\n", __func__);
  367. ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
  368. if (ret < 0) {
  369. dev_err(dev, "Failed to register component %s: %d\n",
  370. dev->of_node->full_name, ret);
  371. return ret;
  372. }
  373. return 0;
  374. }
  375. static void mtk_disp_postmask_unbind(struct device *dev, struct device *master,
  376. void *data)
  377. {
  378. struct mtk_disp_postmask *priv = dev_get_drvdata(dev);
  379. struct drm_device *drm_dev = data;
  380. mtk_ddp_comp_unregister(drm_dev, &priv->ddp_comp);
  381. }
  382. static void mtk_postmask_prepare(struct mtk_ddp_comp *comp)
  383. {
  384. mtk_ddp_comp_clk_prepare(comp);
  385. }
  386. static void mtk_postmask_unprepare(struct mtk_ddp_comp *comp)
  387. {
  388. mtk_ddp_comp_clk_unprepare(comp);
  389. }
  390. static int mtk_postmask_io_cmd(struct mtk_ddp_comp *comp,
  391. struct cmdq_pkt *handle,
  392. enum mtk_ddp_io_cmd io_cmd, void *params)
  393. {
  394. switch (io_cmd) {
  395. case IRQ_LEVEL_ALL: {
  396. unsigned int inten;
  397. inten = REG_FLD_VAL(INTEN_FLD_PM_IF_FME_END_INTEN, 1) |
  398. REG_FLD_VAL(INTEN_FLD_PM_FME_CPL_INTEN, 1) |
  399. REG_FLD_VAL(INTEN_FLD_PM_START_INTEN, 1) |
  400. REG_FLD_VAL(INTEN_FLD_PM_ABNORMAL_SOF_INTEN, 1) |
  401. REG_FLD_VAL(INTEN_FLD_RDMA_FME_UND_INTEN, 1) |
  402. REG_FLD_VAL(INTEN_FLD_RDMA_EOF_ABNORMAL_INTEN, 1);
  403. cmdq_pkt_write(handle, comp->cmdq_base,
  404. comp->regs_pa + DISP_POSTMASK_INTEN, inten,
  405. inten);
  406. break;
  407. }
  408. case IRQ_LEVEL_IDLE: {
  409. unsigned int inten;
  410. inten = REG_FLD_VAL(INTEN_FLD_PM_IF_FME_END_INTEN, 1) |
  411. REG_FLD_VAL(INTEN_FLD_PM_FME_CPL_INTEN, 1) |
  412. REG_FLD_VAL(INTEN_FLD_PM_START_INTEN, 1);
  413. cmdq_pkt_write(handle, comp->cmdq_base,
  414. comp->regs_pa + DISP_POSTMASK_INTEN, 0, inten);
  415. break;
  416. }
  417. default:
  418. break;
  419. }
  420. return 0;
  421. }
  422. static const struct mtk_ddp_comp_funcs mtk_disp_postmask_funcs = {
  423. .config = mtk_postmask_config,
  424. .start = mtk_postmask_start,
  425. .stop = mtk_postmask_stop,
  426. .prepare = mtk_postmask_prepare,
  427. .unprepare = mtk_postmask_unprepare,
  428. .io_cmd = mtk_postmask_io_cmd,
  429. };
  430. static const struct component_ops mtk_disp_postmask_component_ops = {
  431. .bind = mtk_disp_postmask_bind, .unbind = mtk_disp_postmask_unbind,
  432. };
  433. static int mtk_disp_postmask_probe(struct platform_device *pdev)
  434. {
  435. struct device *dev = &pdev->dev;
  436. struct mtk_disp_postmask *priv;
  437. enum mtk_ddp_comp_id comp_id;
  438. int irq;
  439. int ret;
  440. DDPINFO("%s+\n", __func__);
  441. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  442. if (priv == NULL)
  443. return -ENOMEM;
  444. irq = platform_get_irq(pdev, 0);
  445. if (irq < 0)
  446. return irq;
  447. comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_POSTMASK);
  448. if ((int)comp_id < 0) {
  449. DDPPR_ERR("Failed to identify by alias: %d\n", comp_id);
  450. return comp_id;
  451. }
  452. ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
  453. &mtk_disp_postmask_funcs);
  454. if (ret != 0) {
  455. DDPPR_ERR("Failed to initialize component: %d\n", ret);
  456. return ret;
  457. }
  458. platform_set_drvdata(pdev, priv);
  459. ret = devm_request_irq(dev, irq, mtk_postmask_irq_handler,
  460. IRQF_TRIGGER_NONE | IRQF_SHARED, dev_name(dev),
  461. priv);
  462. if (ret < 0) {
  463. DDPAEE("%s:%d, failed to request irq:%d ret:%d comp_id:%d\n",
  464. __func__, __LINE__,
  465. irq, ret, comp_id);
  466. return ret;
  467. }
  468. pm_runtime_enable(dev);
  469. ret = component_add(dev, &mtk_disp_postmask_component_ops);
  470. if (ret != 0) {
  471. dev_err(dev, "Failed to add component: %d\n", ret);
  472. pm_runtime_disable(dev);
  473. }
  474. DDPINFO("%s-\n", __func__);
  475. return ret;
  476. }
  477. static int mtk_disp_postmask_remove(struct platform_device *pdev)
  478. {
  479. component_del(&pdev->dev, &mtk_disp_postmask_component_ops);
  480. pm_runtime_disable(&pdev->dev);
  481. return 0;
  482. }
  483. static const struct mtk_disp_postmask_data mt6779_postmask_driver_data = {
  484. .support_shadow = false,
  485. };
  486. static const struct mtk_disp_postmask_data mt6885_postmask_driver_data = {
  487. .support_shadow = false,
  488. };
  489. static const struct mtk_disp_postmask_data mt6873_postmask_driver_data = {
  490. .support_shadow = false,
  491. };
  492. static const struct mtk_disp_postmask_data mt6853_postmask_driver_data = {
  493. .support_shadow = false,
  494. };
  495. static const struct mtk_disp_postmask_data mt6833_postmask_driver_data = {
  496. .support_shadow = false,
  497. };
  498. static const struct of_device_id mtk_disp_postmask_driver_dt_match[] = {
  499. { .compatible = "mediatek,mt6779-disp-postmask",
  500. .data = &mt6779_postmask_driver_data},
  501. { .compatible = "mediatek,mt6885-disp-postmask",
  502. .data = &mt6885_postmask_driver_data},
  503. { .compatible = "mediatek,mt6873-disp-postmask",
  504. .data = &mt6873_postmask_driver_data},
  505. { .compatible = "mediatek,mt6853-disp-postmask",
  506. .data = &mt6853_postmask_driver_data},
  507. { .compatible = "mediatek,mt6833-disp-postmask",
  508. .data = &mt6833_postmask_driver_data},
  509. {},
  510. };
  511. struct platform_driver mtk_disp_postmask_driver = {
  512. .probe = mtk_disp_postmask_probe,
  513. .remove = mtk_disp_postmask_remove,
  514. .driver = {
  515. .name = "mediatek-disp-postmask",
  516. .owner = THIS_MODULE,
  517. .of_match_table = mtk_disp_postmask_driver_dt_match,
  518. },
  519. };