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 "dm_services.h"
0027 #include "dc.h"
0028 #include "core_types.h"
0029 #include "dce120_hw_sequencer.h"
0030 #include "dce/dce_hwseq.h"
0031
0032 #include "dce110/dce110_hw_sequencer.h"
0033
0034 #include "dce/dce_12_0_offset.h"
0035 #include "dce/dce_12_0_sh_mask.h"
0036 #include "soc15_hw_ip.h"
0037 #include "vega10_ip_offset.h"
0038 #include "reg_helper.h"
0039
0040 #define CTX \
0041 hws->ctx
0042 #define REG(reg)\
0043 hws->regs->reg
0044
0045 #undef FN
0046 #define FN(reg_name, field_name) \
0047 hws->shifts->field_name, hws->masks->field_name
0048
0049 struct dce120_hw_seq_reg_offsets {
0050 uint32_t crtc;
0051 };
0052
0053 #if 0
0054 static const struct dce120_hw_seq_reg_offsets reg_offsets[] = {
0055 {
0056 .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
0057 },
0058 {
0059 .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
0060 },
0061 {
0062 .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
0063 },
0064 {
0065 .crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
0066 },
0067 {
0068 .crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
0069 },
0070 {
0071 .crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
0072 }
0073 };
0074
0075 #define HW_REG_CRTC(reg, id)\
0076 (reg + reg_offsets[id].crtc)
0077
0078 #define CNTL_ID(controller_id)\
0079 controller_id
0080
0081
0082
0083 static void dce120_init_pte(struct dc_context *ctx, uint8_t controller_id)
0084 {
0085 uint32_t addr;
0086 uint32_t value = 0;
0087 uint32_t chunk_int = 0;
0088 uint32_t chunk_mul = 0;
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 addr = mmDVMM_PTE_REQ;
0113 value = dm_read_reg(ctx, addr);
0114
0115 chunk_int = get_reg_field_value(
0116 value,
0117 DVMM_PTE_REQ,
0118 HFLIP_PTEREQ_PER_CHUNK_INT);
0119
0120 chunk_mul = get_reg_field_value(
0121 value,
0122 DVMM_PTE_REQ,
0123 HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
0124
0125 if (chunk_int != 0x4 || chunk_mul != 0x4) {
0126
0127 set_reg_field_value(
0128 value,
0129 255,
0130 DVMM_PTE_REQ,
0131 MAX_PTEREQ_TO_ISSUE);
0132
0133 set_reg_field_value(
0134 value,
0135 4,
0136 DVMM_PTE_REQ,
0137 HFLIP_PTEREQ_PER_CHUNK_INT);
0138
0139 set_reg_field_value(
0140 value,
0141 4,
0142 DVMM_PTE_REQ,
0143 HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);
0144
0145 dm_write_reg(ctx, addr, value);
0146 }
0147 }
0148 #endif
0149
0150 static bool dce120_enable_display_power_gating(
0151 struct dc *dc,
0152 uint8_t controller_id,
0153 struct dc_bios *dcb,
0154 enum pipe_gating_control power_gating)
0155 {
0156
0157 #if 0
0158 enum bp_result bp_result = BP_RESULT_OK;
0159 enum bp_pipe_control_action cntl;
0160 struct dc_context *ctx = dc->ctx;
0161
0162 if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
0163 return true;
0164
0165 if (power_gating == PIPE_GATING_CONTROL_INIT)
0166 cntl = ASIC_PIPE_INIT;
0167 else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
0168 cntl = ASIC_PIPE_ENABLE;
0169 else
0170 cntl = ASIC_PIPE_DISABLE;
0171
0172 if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {
0173
0174 bp_result = dcb->funcs->enable_disp_power_gating(
0175 dcb, controller_id + 1, cntl);
0176
0177
0178
0179
0180 dm_write_reg(ctx,
0181 HW_REG_CRTC(mmCRTC0_CRTC_MASTER_UPDATE_MODE, controller_id),
0182 0);
0183 }
0184
0185 if (power_gating != PIPE_GATING_CONTROL_ENABLE)
0186 dce120_init_pte(ctx, controller_id);
0187
0188 if (bp_result == BP_RESULT_OK)
0189 return true;
0190 else
0191 return false;
0192 #endif
0193 return false;
0194 }
0195
0196 static void dce120_update_dchub(
0197 struct dce_hwseq *hws,
0198 struct dchub_init_data *dh_data)
0199 {
0200
0201 switch (dh_data->fb_mode) {
0202 case FRAME_BUFFER_MODE_ZFB_ONLY:
0203
0204 REG_UPDATE_2(DCHUB_FB_LOCATION,
0205 FB_TOP, 0,
0206 FB_BASE, 0x0FFFF);
0207
0208 REG_UPDATE(DCHUB_AGP_BASE,
0209 AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
0210
0211 REG_UPDATE(DCHUB_AGP_BOT,
0212 AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
0213
0214 REG_UPDATE(DCHUB_AGP_TOP,
0215 AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
0216 break;
0217 case FRAME_BUFFER_MODE_MIXED_ZFB_AND_LOCAL:
0218
0219 REG_UPDATE(DCHUB_AGP_BASE,
0220 AGP_BASE, dh_data->zfb_phys_addr_base >> 22);
0221
0222 REG_UPDATE(DCHUB_AGP_BOT,
0223 AGP_BOT, dh_data->zfb_mc_base_addr >> 22);
0224
0225 REG_UPDATE(DCHUB_AGP_TOP,
0226 AGP_TOP, (dh_data->zfb_mc_base_addr + dh_data->zfb_size_in_byte - 1) >> 22);
0227 break;
0228 case FRAME_BUFFER_MODE_LOCAL_ONLY:
0229
0230 REG_UPDATE(DCHUB_AGP_BASE,
0231 AGP_BASE, 0);
0232
0233 REG_UPDATE(DCHUB_AGP_BOT,
0234 AGP_BOT, 0x03FFFF);
0235
0236 REG_UPDATE(DCHUB_AGP_TOP,
0237 AGP_TOP, 0);
0238 break;
0239 default:
0240 break;
0241 }
0242
0243 dh_data->dchub_initialzied = true;
0244 dh_data->dchub_info_valid = false;
0245 }
0246
0247
0248
0249
0250
0251
0252
0253 bool dce121_xgmi_enabled(struct dce_hwseq *hws)
0254 {
0255 uint32_t pf_max_region;
0256
0257 REG_GET(MC_VM_XGMI_LFB_CNTL, PF_MAX_REGION, &pf_max_region);
0258
0259 return !!pf_max_region;
0260 }
0261
0262 void dce120_hw_sequencer_construct(struct dc *dc)
0263 {
0264
0265
0266
0267 dce110_hw_sequencer_construct(dc);
0268 dc->hwseq->funcs.enable_display_power_gating = dce120_enable_display_power_gating;
0269 dc->hwss.update_dchub = dce120_update_dchub;
0270 }
0271