0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "dce_hwseq.h"
0027 #include "reg_helper.h"
0028 #include "hw_sequencer_private.h"
0029 #include "core_types.h"
0030
0031 #define CTX \
0032 hws->ctx
0033 #define REG(reg)\
0034 hws->regs->reg
0035
0036 #undef FN
0037 #define FN(reg_name, field_name) \
0038 hws->shifts->field_name, hws->masks->field_name
0039
0040 void dce_enable_fe_clock(struct dce_hwseq *hws,
0041 unsigned int fe_inst, bool enable)
0042 {
0043 REG_UPDATE(DCFE_CLOCK_CONTROL[fe_inst],
0044 DCFE_CLOCK_ENABLE, enable);
0045 }
0046
0047 void dce_pipe_control_lock(struct dc *dc,
0048 struct pipe_ctx *pipe,
0049 bool lock)
0050 {
0051 uint32_t lock_val = lock ? 1 : 0;
0052 uint32_t dcp_grph, scl, blnd, update_lock_mode, val;
0053 struct dce_hwseq *hws = dc->hwseq;
0054
0055
0056 if (lock && pipe->stream_res.tg->funcs->is_blanked &&
0057 pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg))
0058 return;
0059
0060 val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst],
0061 BLND_DCP_GRPH_V_UPDATE_LOCK, &dcp_grph,
0062 BLND_SCL_V_UPDATE_LOCK, &scl,
0063 BLND_BLND_V_UPDATE_LOCK, &blnd,
0064 BLND_V_UPDATE_LOCK_MODE, &update_lock_mode);
0065
0066 dcp_grph = lock_val;
0067 scl = lock_val;
0068 blnd = lock_val;
0069 update_lock_mode = lock_val;
0070
0071 REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
0072 BLND_DCP_GRPH_V_UPDATE_LOCK, dcp_grph,
0073 BLND_SCL_V_UPDATE_LOCK, scl);
0074
0075 if (hws->masks->BLND_BLND_V_UPDATE_LOCK != 0)
0076 REG_SET_2(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], val,
0077 BLND_BLND_V_UPDATE_LOCK, blnd,
0078 BLND_V_UPDATE_LOCK_MODE, update_lock_mode);
0079
0080 if (hws->wa.blnd_crtc_trigger) {
0081 if (!lock) {
0082 uint32_t value = REG_READ(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst]);
0083 REG_WRITE(CRTC_H_BLANK_START_END[pipe->stream_res.tg->inst], value);
0084 }
0085 }
0086 }
0087
0088 #if defined(CONFIG_DRM_AMD_DC_SI)
0089 void dce60_pipe_control_lock(struct dc *dc,
0090 struct pipe_ctx *pipe,
0091 bool lock)
0092 {
0093
0094 }
0095 #endif
0096
0097 void dce_set_blender_mode(struct dce_hwseq *hws,
0098 unsigned int blnd_inst,
0099 enum blnd_mode mode)
0100 {
0101 uint32_t feedthrough = 1;
0102 uint32_t blnd_mode = 0;
0103 uint32_t multiplied_mode = 0;
0104 uint32_t alpha_mode = 2;
0105
0106 switch (mode) {
0107 case BLND_MODE_OTHER_PIPE:
0108 feedthrough = 0;
0109 blnd_mode = 1;
0110 alpha_mode = 0;
0111 break;
0112 case BLND_MODE_BLENDING:
0113 feedthrough = 0;
0114 blnd_mode = 2;
0115 alpha_mode = 0;
0116 multiplied_mode = 1;
0117 break;
0118 case BLND_MODE_CURRENT_PIPE:
0119 default:
0120 if (REG(BLND_CONTROL[blnd_inst]) == REG(BLNDV_CONTROL) ||
0121 blnd_inst == 0)
0122 feedthrough = 0;
0123 break;
0124 }
0125
0126 REG_UPDATE(BLND_CONTROL[blnd_inst],
0127 BLND_MODE, blnd_mode);
0128
0129 if (hws->masks->BLND_ALPHA_MODE != 0) {
0130 REG_UPDATE_3(BLND_CONTROL[blnd_inst],
0131 BLND_FEEDTHROUGH_EN, feedthrough,
0132 BLND_ALPHA_MODE, alpha_mode,
0133 BLND_MULTIPLIED_MODE, multiplied_mode);
0134 }
0135 }
0136
0137
0138 static void dce_disable_sram_shut_down(struct dce_hwseq *hws)
0139 {
0140 if (REG(DC_MEM_GLOBAL_PWR_REQ_CNTL))
0141 REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL,
0142 DC_MEM_GLOBAL_PWR_REQ_DIS, 1);
0143 }
0144
0145 static void dce_underlay_clock_enable(struct dce_hwseq *hws)
0146 {
0147
0148 if (REG(DCFEV_CLOCK_CONTROL))
0149 REG_UPDATE(DCFEV_CLOCK_CONTROL,
0150 DCFEV_CLOCK_ENABLE, 1);
0151 }
0152
0153 static void enable_hw_base_light_sleep(void)
0154 {
0155
0156 }
0157
0158 static void disable_sw_manual_control_light_sleep(void)
0159 {
0160
0161 }
0162
0163 void dce_clock_gating_power_up(struct dce_hwseq *hws,
0164 bool enable)
0165 {
0166 if (enable) {
0167 enable_hw_base_light_sleep();
0168 disable_sw_manual_control_light_sleep();
0169 } else {
0170 dce_disable_sram_shut_down(hws);
0171 dce_underlay_clock_enable(hws);
0172 }
0173 }
0174
0175 void dce_crtc_switch_to_clk_src(struct dce_hwseq *hws,
0176 struct clock_source *clk_src,
0177 unsigned int tg_inst)
0178 {
0179 if (clk_src->id == CLOCK_SOURCE_ID_DP_DTO || clk_src->dp_clk_src) {
0180 REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
0181 DP_DTO0_ENABLE, 1);
0182
0183 } else if (clk_src->id >= CLOCK_SOURCE_COMBO_PHY_PLL0) {
0184 uint32_t rate_source = clk_src->id - CLOCK_SOURCE_COMBO_PHY_PLL0;
0185
0186 REG_UPDATE_2(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
0187 PHYPLL_PIXEL_RATE_SOURCE, rate_source,
0188 PIXEL_RATE_PLL_SOURCE, 0);
0189
0190 REG_UPDATE(PIXEL_RATE_CNTL[tg_inst],
0191 DP_DTO0_ENABLE, 0);
0192
0193 } else if (clk_src->id <= CLOCK_SOURCE_ID_PLL2) {
0194 uint32_t rate_source = clk_src->id - CLOCK_SOURCE_ID_PLL0;
0195
0196 REG_UPDATE_2(PIXEL_RATE_CNTL[tg_inst],
0197 PIXEL_RATE_SOURCE, rate_source,
0198 DP_DTO0_ENABLE, 0);
0199
0200 if (REG(PHYPLL_PIXEL_RATE_CNTL[tg_inst]))
0201 REG_UPDATE(PHYPLL_PIXEL_RATE_CNTL[tg_inst],
0202 PIXEL_RATE_PLL_SOURCE, 1);
0203 } else {
0204 DC_ERR("Unknown clock source. clk_src id: %d, TG_inst: %d",
0205 clk_src->id, tg_inst);
0206 }
0207 }
0208
0209
0210 bool dce_use_lut(enum surface_pixel_format format)
0211 {
0212 switch (format) {
0213 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
0214 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
0215 return true;
0216 default:
0217 return false;
0218 }
0219 }