dsi_ctrl_hw_2_2.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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 &= ~(0xF);
  214. reg |= (trigger_map[cfg->dma_cmd_trigger] & 0xF);
  215. DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
  216. DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL2, 0x0);
  217. DSI_W32(ctrl, DSI_DMA_SCHEDULE_CTRL, 0x0);
  218. ctrl->reset_trig_ctrl = false;
  219. }
  220. /**
  221. * dsi_ctrl_hw_22_log_line_count() - reads the MDP interface line count
  222. * registers.
  223. * @ctrl: Pointer to the controller host hardware.
  224. * @cmd_mode: Boolean to indicate command mode operation.
  225. *
  226. * Return: INTF register value.
  227. */
  228. u32 dsi_ctrl_hw_22_log_line_count(struct dsi_ctrl_hw *ctrl, bool cmd_mode)
  229. {
  230. u32 reg = 0;
  231. if (IS_ERR_OR_NULL(ctrl->mdp_intf_base))
  232. return reg;
  233. if (cmd_mode)
  234. reg = DSI_MDP_INTF_R32(ctrl, MDP_INTF_TEAR_OFFSET
  235. + MDP_INTF_TEAR_LINE_COUNT_OFFSET);
  236. else
  237. reg = DSI_MDP_INTF_R32(ctrl, MDP_INTF_LINE_COUNT_OFFSET);
  238. return reg;
  239. }
  240. void dsi_ctrl_hw_22_configure_splitlink(struct dsi_ctrl_hw *ctrl,
  241. struct dsi_host_common_cfg *common_cfg, u32 flags)
  242. {
  243. u32 reg = 0;
  244. reg = DSI_R32(ctrl, DSI_SPLIT_LINK);
  245. /* DMA_LINK_SEL */
  246. reg &= ~(0x7 << 12);
  247. /* Send command to both sublinks unless specified */
  248. if (flags & DSI_CTRL_CMD_SUBLINK0)
  249. reg |= BIT(12);
  250. else if (flags & DSI_CTRL_CMD_SUBLINK1)
  251. reg |= BIT(13);
  252. else
  253. reg |= (BIT(12) | BIT(13));
  254. /**
  255. * Avoid dma trigger on sublink1 for read commands. This can be
  256. * enabled in future if panel supports sending read command on sublink1.
  257. */
  258. if (flags & DSI_CTRL_CMD_READ) {
  259. reg = reg & ~BIT(13);
  260. }
  261. DSI_W32(ctrl, DSI_SPLIT_LINK, reg);
  262. /* Make sure the split link config is updated */
  263. wmb();
  264. }
  265. void dsi_ctrl_hw_22_setup_misr(struct dsi_ctrl_hw *ctrl, enum dsi_op_mode panel_mode,
  266. bool enable, u32 frame_count)
  267. {
  268. u32 config = 0;
  269. DSI_W32(ctrl, DSI_MDP_MISR_CTRL, config);
  270. wmb(); /* clear misr data */
  271. if (enable) {
  272. config = (frame_count & 0xffff);
  273. config |= BIT(8) | BIT(24) | BIT(31); /* enable, panel data-only, free run mode */
  274. }
  275. DSI_CTRL_HW_DBG(ctrl, "MISR enable:%d, frame_count:%d, config:0x%x\n",
  276. enable, frame_count, config);
  277. DSI_W32(ctrl, DSI_MDP_MISR_CTRL, config);
  278. wmb(); /* make sure MISR is configured */
  279. }
  280. u32 dsi_ctrl_hw_22_collect_misr(struct dsi_ctrl_hw *ctrl, enum dsi_op_mode panel_mode)
  281. {
  282. u32 enabled;
  283. u32 misr = 0;
  284. enabled = DSI_R32(ctrl, DSI_MDP_MISR_CTRL) & BIT(8);
  285. if (enabled)
  286. misr = DSI_R32(ctrl, DSI_MDP_MISR_SIGNATURE);
  287. DSI_CTRL_HW_DBG(ctrl, "MISR enabled:%d value:0x%x\n", enabled, misr);
  288. return misr;
  289. }