dsi_ctrl_hw_2_2.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/iopoll.h>
  7. #include "dsi_ctrl_hw.h"
  8. #include "dsi_ctrl_reg.h"
  9. #include "dsi_hw.h"
  10. #include "dsi_ctrl.h"
  11. #include "dsi_catalog.h"
  12. #define DISP_CC_MISC_CMD_REG_OFF 0x00
  13. /* register to configure DMA scheduling */
  14. #define DSI_DMA_SCHEDULE_CTRL 0x100
  15. #define DSI_DMA_SCHEDULE_CTRL2 0x0104
  16. /* offset addresses of MDP INTF base register, to be mapped for debug feature */
  17. #define MDP_INTF_TEAR_OFFSET 0x280
  18. #define MDP_INTF_TEAR_LINE_COUNT_OFFSET 0x30
  19. #define MDP_INTF_LINE_COUNT_OFFSET 0xB0
  20. #define DSI_MDP_MISR_CTRL 0x364
  21. #define DSI_MDP_MISR_SIGNATURE 0x368
  22. void dsi_ctrl_hw_22_setup_lane_map(struct dsi_ctrl_hw *ctrl,
  23. struct dsi_lane_map *lane_map)
  24. {
  25. u32 reg_value = lane_map->lane_map_v2[DSI_LOGICAL_LANE_0] |
  26. (lane_map->lane_map_v2[DSI_LOGICAL_LANE_1] << 4) |
  27. (lane_map->lane_map_v2[DSI_LOGICAL_LANE_2] << 8) |
  28. (lane_map->lane_map_v2[DSI_LOGICAL_LANE_3] << 12);
  29. DSI_W32(ctrl, DSI_LANE_SWAP_CTRL, reg_value);
  30. DSI_CTRL_HW_DBG(ctrl, "[DSI_%d] Lane swap setup complete\n",
  31. ctrl->index);
  32. }
  33. int dsi_ctrl_hw_22_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl,
  34. u32 lanes)
  35. {
  36. int rc = 0, val = 0;
  37. u32 fifo_empty_mask = 0;
  38. u32 const sleep_us = 10;
  39. u32 const timeout_us = 100;
  40. if (lanes & DSI_DATA_LANE_0)
  41. fifo_empty_mask |= (BIT(12) | BIT(16));
  42. if (lanes & DSI_DATA_LANE_1)
  43. fifo_empty_mask |= BIT(20);
  44. if (lanes & DSI_DATA_LANE_2)
  45. fifo_empty_mask |= BIT(24);
  46. if (lanes & DSI_DATA_LANE_3)
  47. fifo_empty_mask |= BIT(28);
  48. DSI_CTRL_HW_DBG(ctrl, "%s: polling for fifo empty, mask=0x%08x\n",
  49. __func__, fifo_empty_mask);
  50. rc = DSI_READ_POLL_TIMEOUT(ctrl, DSI_FIFO_STATUS, val,
  51. (val & fifo_empty_mask), sleep_us, timeout_us);
  52. if (rc) {
  53. DSI_CTRL_HW_ERR(ctrl,
  54. "%s: fifo not empty, FIFO_STATUS=0x%08x\n",
  55. __func__, val);
  56. goto error;
  57. }
  58. error:
  59. return rc;
  60. }
  61. ssize_t dsi_ctrl_hw_22_reg_dump_to_buffer(struct dsi_ctrl_hw *ctrl,
  62. char *buf,
  63. u32 size)
  64. {
  65. return size;
  66. }
  67. /**
  68. * dsi_ctrl_hw_22_phy_reset_config() - to configure clamp control during ulps
  69. * @ctrl: Pointer to the controller host hardware.
  70. * @enable: boolean to specify enable/disable.
  71. */
  72. void dsi_ctrl_hw_22_phy_reset_config(struct dsi_ctrl_hw *ctrl,
  73. bool enable)
  74. {
  75. u32 reg = 0;
  76. reg = DSI_DISP_CC_R32(ctrl, DISP_CC_MISC_CMD_REG_OFF);
  77. /* Mask/unmask disable PHY reset bit */
  78. if (enable)
  79. reg &= ~BIT(ctrl->index);
  80. else
  81. reg |= BIT(ctrl->index);
  82. DSI_DISP_CC_W32(ctrl, DISP_CC_MISC_CMD_REG_OFF, reg);
  83. }
  84. /**
  85. * dsi_ctrl_hw_22_schedule_dma_cmd() - to schedule DMA command transfer
  86. * @ctrl: Pointer to the controller host hardware.
  87. * @line_no: Line number at which command needs to be sent.
  88. */
  89. void dsi_ctrl_hw_22_schedule_dma_cmd(struct dsi_ctrl_hw *ctrl, int line_no)
  90. {
  91. u32 reg = 0;
  92. reg = DSI_R32(ctrl, DSI_DMA_SCHEDULE_CTRL);
  93. reg |= BIT(28);
  94. reg |= (line_no & 0xffff);
  95. DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL, reg);
  96. ctrl->reset_trig_ctrl = true;
  97. }
  98. /*
  99. * dsi_ctrl_hw_kickoff_non_embedded_mode()-Kickoff cmd in non-embedded mode
  100. * @ctrl: - Pointer to the controller host hardware.
  101. * @dsi_ctrl_cmd_dma_info: - command buffer information.
  102. * @flags: - DSI CTRL Flags.
  103. */
  104. void dsi_ctrl_hw_kickoff_non_embedded_mode(struct dsi_ctrl_hw *ctrl,
  105. struct dsi_ctrl_cmd_dma_info *cmd,
  106. u32 flags)
  107. {
  108. u32 reg = 0;
  109. reg = DSI_R32(ctrl, DSI_COMMAND_MODE_DMA_CTRL);
  110. reg &= ~BIT(31);/* disable broadcast */
  111. reg &= ~BIT(30);
  112. if (cmd->use_lpm)
  113. reg |= BIT(26);
  114. else
  115. reg &= ~BIT(26);
  116. /* Select non EMBEDDED_MODE, pick the packet header from register */
  117. reg &= ~BIT(28);
  118. reg |= BIT(24);/* long packet */
  119. reg |= BIT(29);/* wc_sel = 1 */
  120. reg |= (((cmd->datatype) & 0x03f) << 16);/* data type */
  121. DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
  122. /* Enable WRITE_WATERMARK_DISABLE and READ_WATERMARK_DISABLE bits */
  123. reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL);
  124. reg |= BIT(20);
  125. reg |= BIT(16);
  126. reg |= 0x33;/* Set READ and WRITE watermark levels to maximum */
  127. DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg);
  128. DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
  129. DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, ((cmd->length) & 0xFFFFFF));
  130. /* wait for writes to complete before kick off */
  131. wmb();
  132. if (!(flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER))
  133. DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
  134. }
  135. /*
  136. * dsi_ctrl_hw_22_config_clk_gating() - enable/disable clk gating on DSI PHY
  137. * @ctrl: Pointer to the controller host hardware.
  138. * @enable: bool to notify enable/disable.
  139. * @clk_selection: clock to enable/disable clock gating.
  140. *
  141. */
  142. void dsi_ctrl_hw_22_config_clk_gating(struct dsi_ctrl_hw *ctrl, bool enable,
  143. enum dsi_clk_gate_type clk_selection)
  144. {
  145. u32 reg = 0;
  146. u32 enable_select = 0;
  147. reg = DSI_DISP_CC_R32(ctrl, DISP_CC_MISC_CMD_REG_OFF);
  148. if (clk_selection & PIXEL_CLK)
  149. enable_select |= ctrl->index ? BIT(6) : BIT(5);
  150. if (clk_selection & BYTE_CLK)
  151. enable_select |= ctrl->index ? BIT(8) : BIT(7);
  152. if (clk_selection & DSI_PHY)
  153. enable_select |= ctrl->index ? BIT(10) : BIT(9);
  154. if (enable)
  155. reg |= enable_select;
  156. else
  157. reg &= ~enable_select;
  158. DSI_DISP_CC_W32(ctrl, DISP_CC_MISC_CMD_REG_OFF, reg);
  159. }
  160. /**
  161. * dsi_ctrl_hw_22_configure_cmddma_window() - configure DMA window for CMD TX
  162. * @ctrl: Pointer to the controller host hardware.
  163. * @cmd: Pointer to the DSI DMA command info.
  164. * @line_no: Line number at which the CMD needs to be triggered.
  165. * @window: Width of the DMA CMD window.
  166. */
  167. void dsi_ctrl_hw_22_configure_cmddma_window(struct dsi_ctrl_hw *ctrl,
  168. struct dsi_ctrl_cmd_dma_info *cmd,
  169. u32 line_no, u32 window)
  170. {
  171. u32 reg = 0;
  172. if (cmd->en_broadcast) {
  173. reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
  174. if (cmd->is_master) {
  175. reg &= ~0xF;
  176. reg |= 0xc;
  177. } else {
  178. reg &= ~0xF;
  179. reg |= BIT(16);
  180. }
  181. DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
  182. if (cmd->is_master) {
  183. reg = 0;
  184. reg |= line_no;
  185. reg |= window << 16;
  186. DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL2, reg);
  187. }
  188. } else {
  189. reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
  190. reg &= ~0xF;
  191. reg |= 0xc;
  192. DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
  193. reg = 0;
  194. reg |= line_no;
  195. reg |= window << 16;
  196. DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL2, reg);
  197. }
  198. ctrl->reset_trig_ctrl = true;
  199. }
  200. /**
  201. * dsi_ctrl_hw_22_reset_trigger_controls() - reset dsi trigger configurations
  202. * @ctrl: Pointer to the controller host hardware.
  203. * @cfg: DSI host configuration that is common to both video and
  204. * command modes.
  205. */
  206. void dsi_ctrl_hw_22_reset_trigger_controls(struct dsi_ctrl_hw *ctrl,
  207. struct dsi_host_common_cfg *cfg)
  208. {
  209. u32 reg;
  210. const u8 trigger_map[DSI_TRIGGER_MAX] = {
  211. 0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
  212. reg = DSI_R32(ctrl, DSI_TRIG_CTRL);
  213. reg &= ~BIT(16); /* Reset DMA_TRG_MUX */
  214. reg &= ~(0xF); /* Reset DMA_TRIGGER_SEL */
  215. reg |= (trigger_map[cfg->dma_cmd_trigger] & 0xF);
  216. DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
  217. DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL2, 0x0);
  218. DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL, 0x0);
  219. ctrl->reset_trig_ctrl = false;
  220. }
  221. /**
  222. * dsi_ctrl_hw_22_log_line_count() - reads the MDP interface line count
  223. * registers.
  224. * @ctrl: Pointer to the controller host hardware.
  225. * @cmd_mode: Boolean to indicate command mode operation.
  226. *
  227. * Return: INTF register value.
  228. */
  229. u32 dsi_ctrl_hw_22_log_line_count(struct dsi_ctrl_hw *ctrl, bool cmd_mode)
  230. {
  231. u32 reg = 0;
  232. if (IS_ERR_OR_NULL(ctrl->mdp_intf_base))
  233. return reg;
  234. if (cmd_mode)
  235. reg = DSI_MDP_INTF_R32(ctrl, MDP_INTF_TEAR_OFFSET
  236. + MDP_INTF_TEAR_LINE_COUNT_OFFSET);
  237. else
  238. reg = DSI_MDP_INTF_R32(ctrl, MDP_INTF_LINE_COUNT_OFFSET);
  239. return reg;
  240. }
  241. void dsi_ctrl_hw_22_configure_splitlink(struct dsi_ctrl_hw *ctrl,
  242. struct dsi_host_common_cfg *common_cfg, u32 flags)
  243. {
  244. u32 reg = 0;
  245. reg = DSI_R32(ctrl, DSI_SPLIT_LINK);
  246. /* DMA_LINK_SEL */
  247. reg &= ~(0x7 << 12);
  248. /* Send command to both sublinks unless specified */
  249. if (flags & DSI_CTRL_CMD_SUBLINK0)
  250. reg |= BIT(12);
  251. else if (flags & DSI_CTRL_CMD_SUBLINK1)
  252. reg |= BIT(13);
  253. else
  254. reg |= (BIT(12) | BIT(13));
  255. /**
  256. * Avoid dma trigger on sublink1 for read commands. This can be
  257. * enabled in future if panel supports sending read command on sublink1.
  258. */
  259. if (flags & DSI_CTRL_CMD_READ) {
  260. reg = reg & ~BIT(13);
  261. }
  262. DSI_W32(ctrl, DSI_SPLIT_LINK, reg);
  263. /* Make sure the split link config is updated */
  264. wmb();
  265. }
  266. void dsi_ctrl_hw_22_setup_misr(struct dsi_ctrl_hw *ctrl, enum dsi_op_mode panel_mode,
  267. bool enable, u32 frame_count)
  268. {
  269. u32 config = 0;
  270. DSI_W32(ctrl, DSI_MDP_MISR_CTRL, config);
  271. wmb(); /* clear misr data */
  272. if (enable) {
  273. config = (frame_count & 0xffff);
  274. config |= BIT(8) | BIT(24) | BIT(31); /* enable, panel data-only, free run mode */
  275. }
  276. DSI_CTRL_HW_DBG(ctrl, "MISR enable:%d, frame_count:%d, config:0x%x\n",
  277. enable, frame_count, config);
  278. DSI_W32(ctrl, DSI_MDP_MISR_CTRL, config);
  279. wmb(); /* make sure MISR is configured */
  280. }
  281. u32 dsi_ctrl_hw_22_collect_misr(struct dsi_ctrl_hw *ctrl, enum dsi_op_mode panel_mode)
  282. {
  283. u32 enabled;
  284. u32 misr = 0;
  285. enabled = DSI_R32(ctrl, DSI_MDP_MISR_CTRL) & BIT(8);
  286. if (enabled)
  287. misr = DSI_R32(ctrl, DSI_MDP_MISR_SIGNATURE);
  288. DSI_CTRL_HW_DBG(ctrl, "MISR enabled:%d value:0x%x\n", enabled, misr);
  289. return misr;
  290. }