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