1 /* 2 * Copyright 2015 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 26 #include "dm_services.h" 27 #include "dc.h" 28 #include "core_types.h" 29 #include "dce120_hw_sequencer.h" 30 #include "dce/dce_hwseq.h" 31 32 #include "dce110/dce110_hw_sequencer.h" 33 34 #include "vega10/DC/dce_12_0_offset.h" 35 #include "vega10/DC/dce_12_0_sh_mask.h" 36 #include "vega10/soc15ip.h" 37 #include "reg_helper.h" 38 39 #define CTX \ 40 hws->ctx 41 #define REG(reg)\ 42 hws->regs->reg 43 44 #undef FN 45 #define FN(reg_name, field_name) \ 46 hws->shifts->field_name, hws->masks->field_name 47 48 struct dce120_hw_seq_reg_offsets { 49 uint32_t crtc; 50 }; 51 52 static const struct dce120_hw_seq_reg_offsets reg_offsets[] = { 53 { 54 .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL), 55 }, 56 { 57 .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL), 58 }, 59 { 60 .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL), 61 }, 62 { 63 .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL), 64 }, 65 { 66 .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL), 67 }, 68 { 69 .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL), 70 } 71 }; 72 73 #define HW_REG_CRTC(reg, id)\ 74 (reg + reg_offsets[id].crtc) 75 76 #define CNTL_ID(controller_id)\ 77 controller_id 78 /******************************************************************************* 79 * Private definitions 80 ******************************************************************************/ 81 #if 0 82 static void dce120_init_pte(struct dc_context *ctx, uint8_t controller_id) 83 { 84 uint32_t addr; 85 uint32_t value = 0; 86 uint32_t chunk_int = 0; 87 uint32_t chunk_mul = 0; 88 /* 89 addr = mmDCP0_DVMM_PTE_CONTROL + controller_id * 90 (mmDCP1_DVMM_PTE_CONTROL- mmDCP0_DVMM_PTE_CONTROL); 91 92 value = dm_read_reg(ctx, addr); 93 94 set_reg_field_value( 95 value, 0, DCP, controller_id, 96 DVMM_PTE_CONTROL, 97 DVMM_USE_SINGLE_PTE); 98 99 set_reg_field_value_soc15( 100 value, 1, DCP, controller_id, 101 DVMM_PTE_CONTROL, 102 DVMM_PTE_BUFFER_MODE0); 103 104 set_reg_field_value_soc15( 105 value, 1, DCP, controller_id, 106 DVMM_PTE_CONTROL, 107 DVMM_PTE_BUFFER_MODE1); 108 109 dm_write_reg(ctx, addr, value);*/ 110 111 addr = mmDVMM_PTE_REQ; 112 value = dm_read_reg(ctx, addr); 113 114 chunk_int = get_reg_field_value( 115 value, 116 DVMM_PTE_REQ, 117 HFLIP_PTEREQ_PER_CHUNK_INT); 118 119 chunk_mul = get_reg_field_value( 120 value, 121 DVMM_PTE_REQ, 122 HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 123 124 if (chunk_int != 0x4 || chunk_mul != 0x4) { 125 126 set_reg_field_value( 127 value, 128 255, 129 DVMM_PTE_REQ, 130 MAX_PTEREQ_TO_ISSUE); 131 132 set_reg_field_value( 133 value, 134 4, 135 DVMM_PTE_REQ, 136 HFLIP_PTEREQ_PER_CHUNK_INT); 137 138 set_reg_field_value( 139 value, 140 4, 141 DVMM_PTE_REQ, 142 HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 143 144 dm_write_reg(ctx, addr, value); 145 } 146 } 147 #endif 148 149 static bool dce120_enable_display_power_gating( 150 struct dc *dc, 151 uint8_t controller_id, 152 struct dc_bios *dcb, 153 enum pipe_gating_control power_gating) 154 { 155 /* disable for bringup */ 156 #if 0 157 enum bp_result bp_result = BP_RESULT_OK; 158 enum bp_pipe_control_action cntl; 159 struct dc_context *ctx = dc->ctx; 160 161 if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment)) 162 return true; 163 164 if (power_gating == PIPE_GATING_CONTROL_INIT) 165 cntl = ASIC_PIPE_INIT; 166 else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 167 cntl = ASIC_PIPE_ENABLE; 168 else 169 cntl = ASIC_PIPE_DISABLE; 170 171 if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) { 172 173 bp_result = dcb->funcs->enable_disp_power_gating( 174 dcb, controller_id + 1, cntl); 175 176 /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 177 * by default when command table is called 178 */ 179 dm_write_reg(ctx, 180 HW_REG_CRTC(mmCRTC0_CRTC_MASTER_UPDATE_MODE, controller_id), 181 0); 182 } 183 184 if (power_gating != PIPE_GATING_CONTROL_ENABLE) 185 dce120_init_pte(ctx, controller_id); 186 187 if (bp_result == BP_RESULT_OK) 188 return true; 189 else 190 return false; 191 #endif 192 return false; 193 } 194 195 static void dce120_update_dchub( 196 struct dce_hwseq *hws, 197 struct dchub_init_data *dh_data) 198 { 199 /* TODO: port code from dal2 */ 200 switch (dh_data->fb_mode) { 201 case FRAME_BUFFER_MODE_ZFB_ONLY: 202 /*For ZFB case need to put DCHUB FB BASE and TOP upside down to indicate ZFB mode*/ 203 REG_UPDATE_2(DCHUB_FB_LOCATION, 204 FB_TOP, 0, 205 FB_BASE, 0x0FFFF); 206 207 REG_UPDATE(DCHUB_AGP_BASE, 208 AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 209 210 REG_UPDATE(DCHUB_AGP_BOT, 211 AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 212 213 REG_UPDATE(DCHUB_AGP_TOP, 214 AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22); 215 break; 216 case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL: 217 /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 218 REG_UPDATE(DCHUB_AGP_BASE, 219 AGP_BASE, dh_data->zfb_phys_addr_base >> 22); 220 221 REG_UPDATE(DCHUB_AGP_BOT, 222 AGP_BOT, dh_data->zfb_mc_base_addr >> 22); 223 224 REG_UPDATE(DCHUB_AGP_TOP, 225 AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22); 226 break; 227 case FRAME_BUFFER_MODE_LOCAL_ONLY: 228 /*Should not touch FB LOCATION (done by VBIOS on AsicInit table)*/ 229 REG_UPDATE(DCHUB_AGP_BASE, 230 AGP_BASE, 0); 231 232 REG_UPDATE(DCHUB_AGP_BOT, 233 AGP_BOT, 0x03FFFF); 234 235 REG_UPDATE(DCHUB_AGP_TOP, 236 AGP_TOP, 0); 237 break; 238 default: 239 break; 240 } 241 242 dh_data->dchub_initialzied = true; 243 dh_data->dchub_info_valid = false; 244 } 245 246 247 248 bool dce120_hw_sequencer_construct(struct dc *dc) 249 { 250 /* All registers used by dce11.2 match those in dce11 in offset and 251 * structure 252 */ 253 dce110_hw_sequencer_construct(dc); 254 dc->hwss.enable_display_power_gating = dce120_enable_display_power_gating; 255 dc->hwss.update_dchub = dce120_update_dchub; 256 257 return true; 258 } 259 260