dce_hwseq.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright 2016 Advanced Micro Devices, Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Authors: AMD
  23. *
  24. */
  25. #include "dce_hwseq.h"
  26. #include "reg_helper.h"
  27. #include "hw_sequencer.h"
  28. #include "core_types.h"
  29. #define CTX \
  30. hws->ctx
  31. #define REG(reg)\
  32. hws->regs->reg
  33. #undef FN
  34. #define FN(reg_name, field_name) \
  35. hws->shifts->field_name, hws->masks->field_name
  36. void dce_enable_fe_clock(struct dce_hwseq *hws,
  37. unsigned int fe_inst, bool enable)
  38. {
  39. REG_UPDATE(DCFE_CLOCK_CONTROL[fe_inst],
  40. DCFE_CLOCK_ENABLE, enable);
  41. }
  42. void dce_pipe_control_lock(struct dc *dc,
  43. struct pipe_ctx *pipe,
  44. bool lock)
  45. {
  46. uint32_t lock_val = lock ? 1 : 0;
  47. uint32_t dcp_grph, scl, blnd, update_lock_mode, val;
  48. struct dce_hwseq *hws = dc->hwseq;
  49. /* Not lock pipe when blank */
  50. if (lock && pipe->stream_res.tg->funcs->is_blanked &&
  51. pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg))
  52. return;
  53. val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst],
  54. BLND_DCP_GRPH_V_UPDATE_LOCK, &dcp_grph,
  55. BLND_SCL_V_UPDATE_LOCK, &scl,
  56. BLND_BLND_V_UPDATE_LOCK, &blnd,
  57. BLND_V_UPDATE_LOCK_MODE, &update_lock_mode);
  58. dcp_grph = lock_val;
  59. scl = lock_val;
  60. blnd = lock_val;
  61. update_lock_mode = lock_val;
  62. REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
  63. BLND_DCP_GRPH_V_UPDATE_LOCK, dcp_grph,
  64. BLND_SCL_V_UPDATE_LOCK, scl);
  65. if (hws->masks->BLND_BLND_V_UPDATE_LOCK != 0)
  66. REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
  67. BLND_BLND_V_UPDATE_LOCK, blnd,
  68. BLND_V_UPDATE_LOCK_MODE, update_lock_mode);
  69. if (hws->wa.blnd_crtc_trigger) {
  70. if (!lock) {
  71. uint32_t value = REG_READ(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst]);
  72. REG_WRITE(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst], value);
  73. }
  74. }
  75. }
  76. void dce_set_blender_mode(struct dce_hwseq *hws,
  77. unsigned int blnd_inst,
  78. enum blnd_mode mode)
  79. {
  80. uint32_t feedthrough = 1;
  81. uint32_t blnd_mode = 0;
  82. uint32_t multiplied_mode = 0;
  83. uint32_t alpha_mode = 2;
  84. switch (mode) {
  85. case BLND_MODE_OTHER_PIPE:
  86. feedthrough = 0;
  87. blnd_mode = 1;
  88. alpha_mode = 0;
  89. break;
  90. case BLND_MODE_BLENDING:
  91. feedthrough = 0;
  92. blnd_mode = 2;
  93. alpha_mode = 0;
  94. multiplied_mode = 1;
  95. break;
  96. case BLND_MODE_CURRENT_PIPE:
  97. default:
  98. if (REG(BLND_CONTROL[blnd_inst]) == REG(BLNDV_CONTROL) ||
  99. blnd_inst == 0)
  100. feedthrough = 0;
  101. break;
  102. }
  103. REG_UPDATE(BLND_CONTROL[blnd_inst],
  104. BLND_MODE, blnd_mode);
  105. if (hws->masks->BLND_ALPHA_MODE != 0) {
  106. REG_UPDATE_3(BLND_CONTROL[blnd_inst],
  107. BLND_FEEDTHROUGH_EN, feedthrough,
  108. BLND_ALPHA_MODE, alpha_mode,
  109. BLND_MULTIPLIED_MODE, multiplied_mode);
  110. }
  111. }
  112. static void dce_disable_sram_shut_down(struct dce_hwseq *hws)
  113. {
  114. if (REG(DC_MEM_GLOBAL_PWR_REQ_CNTL))
  115. REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL,
  116. DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
  117. }
  118. static void dce_underlay_clock_enable(struct dce_hwseq *hws)
  119. {
  120. /* todo: why do we need this at boot? is dce_enable_fe_clock enough? */
  121. if (REG(DCFEV_CLOCK_CONTROL))
  122. REG_UPDATE(DCFEV_CLOCK_CONTROL,
  123. DCFEV_CLOCK_ENABLE, 1);
  124. }
  125. static void enable_hw_base_light_sleep(void)
  126. {
  127. /* TODO: implement */
  128. }
  129. static void disable_sw_manual_control_light_sleep(void)
  130. {
  131. /* TODO: implement */
  132. }
  133. void dce_clock_gating_power_up(struct dce_hwseq *hws,
  134. bool enable)
  135. {
  136. if (enable) {
  137. enable_hw_base_light_sleep();
  138. disable_sw_manual_control_light_sleep();
  139. } else {
  140. dce_disable_sram_shut_down(hws);
  141. dce_underlay_clock_enable(hws);
  142. }
  143. }
  144. void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
  145. struct clock_source *clk_src,
  146. unsigned int tg_inst)
  147. {
  148. if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO || clk_src->dp_clk_src) {
  149. REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
  150. DP_DTO0_ENABLE, 1);
  151. } else if (clk_src->id >= CLOCK_SOURCE_COMBO_PHY_PLL0) {
  152. uint32_t rate_source = clk_src->id - CLOCK_SOURCE_COMBO_PHY_PLL0;
  153. REG_UPDATE_2(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
  154. PHYPLL_PIXEL_RATE_SOURCE, rate_source,
  155. PIXEL_RATE_PLL_SOURCE, 0);
  156. REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
  157. DP_DTO0_ENABLE, 0);
  158. } else if (clk_src->id <= CLOCK_SOURCE_ID_PLL2) {
  159. uint32_t rate_source = clk_src->id - CLOCK_SOURCE_ID_PLL0;
  160. REG_UPDATE_2(PIXEL_RATE_CNTL[tg_inst],
  161. PIXEL_RATE_SOURCE, rate_source,
  162. DP_DTO0_ENABLE, 0);
  163. if (REG(PHYPLL_PIXEL_RATE_CNTL[tg_inst]))
  164. REG_UPDATE(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
  165. PIXEL_RATE_PLL_SOURCE, 1);
  166. } else {
  167. DC_ERR("Unknown clock source. clk_src id: %d, TG_inst: %d",
  168. clk_src->id, tg_inst);
  169. }
  170. }
  171. /* Only use LUT for 8 bit formats */
  172. bool dce_use_lut(enum surface_pixel_format format)
  173. {
  174. switch (format) {
  175. case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
  176. case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
  177. return true;
  178. default:
  179. return false;
  180. }
  181. }