dsi_ctrl_hw_2_2.c 9.5 KB

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