Commit 6f5a5e86 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'amd-drm-fixes-6.4-2023-04-26' of...

Merge tag 'amd-drm-fixes-6.4-2023-04-26' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-fixes-6.4-2023-04-26:

amdgpu:
- SR-IOV fixes
- DCN 3.2 fixes
- DC mclk handling fixes
- eDP fixes
- SubVP fixes
- HDCP regression fix
- DSC fixes
- DC FP fixes
- DCN 3.x fixes
- Display flickering fix when switching between vram and gtt
- Z8 power saving fix
- Fix hang when skipping modeset
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230427033012.7668-1-alexander.deucher@amd.com
parents cf03e295 d893f393
......@@ -2539,8 +2539,6 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
amdgpu_fru_get_product_info(adev);
init_failed:
if (amdgpu_sriov_vf(adev))
amdgpu_virt_release_full_gpu(adev, true);
return r;
}
......@@ -3859,18 +3857,6 @@ int amdgpu_device_init(struct amdgpu_device *adev,
r = amdgpu_device_ip_init(adev);
if (r) {
/* failed in exclusive mode due to timeout */
if (amdgpu_sriov_vf(adev) &&
!amdgpu_sriov_runtime(adev) &&
amdgpu_virt_mmio_blocked(adev) &&
!amdgpu_virt_wait_reset(adev)) {
dev_err(adev->dev, "VF exclusive mode timeout\n");
/* Don't send request since VF is inactive. */
adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME;
adev->virt.ops = NULL;
r = -EAGAIN;
goto release_ras_con;
}
dev_err(adev->dev, "amdgpu_device_ip_init failed\n");
amdgpu_vf_error_put(adev, AMDGIM_ERROR_VF_AMDGPU_INIT_FAIL, 0, 0);
goto release_ras_con;
......@@ -3939,8 +3925,10 @@ int amdgpu_device_init(struct amdgpu_device *adev,
msecs_to_jiffies(AMDGPU_RESUME_MS));
}
if (amdgpu_sriov_vf(adev))
if (amdgpu_sriov_vf(adev)) {
amdgpu_virt_release_full_gpu(adev, true);
flush_delayed_work(&adev->delayed_init_work);
}
r = sysfs_create_files(&adev->dev->kobj, amdgpu_dev_attributes);
if (r)
......@@ -3980,6 +3968,20 @@ int amdgpu_device_init(struct amdgpu_device *adev,
return 0;
release_ras_con:
if (amdgpu_sriov_vf(adev))
amdgpu_virt_release_full_gpu(adev, true);
/* failed in exclusive mode due to timeout */
if (amdgpu_sriov_vf(adev) &&
!amdgpu_sriov_runtime(adev) &&
amdgpu_virt_mmio_blocked(adev) &&
!amdgpu_virt_wait_reset(adev)) {
dev_err(adev->dev, "VF exclusive mode timeout\n");
/* Don't send request since VF is inactive. */
adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME;
adev->virt.ops = NULL;
r = -EAGAIN;
}
amdgpu_release_ras_context(adev);
failed:
......
......@@ -430,7 +430,7 @@ static int jpeg_v4_0_start_sriov(struct amdgpu_device *adev)
MMSCH_COMMAND__END;
header.version = MMSCH_VERSION;
header.total_size = sizeof(struct mmsch_v4_0_init_header) >> 2;
header.total_size = RREG32_SOC15(VCN, 0, regMMSCH_VF_CTX_SIZE);
header.jpegdec.init_status = 0;
header.jpegdec.table_offset = 0;
......
......@@ -3128,9 +3128,12 @@ void amdgpu_dm_update_connector_after_detect(
aconnector->edid);
}
aconnector->timing_requested = kzalloc(sizeof(struct dc_crtc_timing), GFP_KERNEL);
if (!aconnector->timing_requested)
dm_error("%s: failed to create aconnector->requested_timing\n", __func__);
if (!aconnector->timing_requested) {
aconnector->timing_requested =
kzalloc(sizeof(struct dc_crtc_timing), GFP_KERNEL);
if (!aconnector->timing_requested)
dm_error("failed to create aconnector->requested_timing\n");
}
drm_connector_update_edid_property(connector, aconnector->edid);
amdgpu_dm_update_freesync_caps(connector, aconnector->edid);
......@@ -7898,6 +7901,13 @@ static void amdgpu_dm_commit_cursors(struct drm_atomic_state *state)
amdgpu_dm_plane_handle_cursor_update(plane, old_plane_state);
}
static inline uint32_t get_mem_type(struct drm_framebuffer *fb)
{
struct amdgpu_bo *abo = gem_to_amdgpu_bo(fb->obj[0]);
return abo->tbo.resource ? abo->tbo.resource->mem_type : 0;
}
static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
struct dc_state *dc_state,
struct drm_device *dev,
......@@ -7972,6 +7982,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
continue;
dc_plane = dm_new_plane_state->dc_state;
if (!dc_plane)
continue;
bundle->surface_updates[planes_count].surface = dc_plane;
if (new_pcrtc_state->color_mgmt_changed) {
......@@ -8038,11 +8050,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
/*
* Only allow immediate flips for fast updates that don't
* change FB pitch, DCC state, rotation or mirroing.
* change memory domain, FB pitch, DCC state, rotation or
* mirroring.
*/
bundle->flip_addrs[planes_count].flip_immediate =
crtc->state->async_flip &&
acrtc_state->update_type == UPDATE_TYPE_FAST;
acrtc_state->update_type == UPDATE_TYPE_FAST &&
get_mem_type(old_plane_state->fb) == get_mem_type(fb);
timestamp_ns = ktime_get_ns();
bundle->flip_addrs[planes_count].flip_timestamp_in_us = div_u64(timestamp_ns, 1000);
......@@ -8554,6 +8568,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
if (!adev->dm.hdcp_workqueue)
continue;
pr_debug("[HDCP_DM] -------------- i : %x ----------\n", i);
if (!connector)
......@@ -8602,6 +8619,9 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(dm_new_con_state->base.crtc);
struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
if (!adev->dm.hdcp_workqueue)
continue;
new_crtc_state = NULL;
old_crtc_state = NULL;
......@@ -9620,8 +9640,9 @@ static int dm_update_plane_state(struct dc *dc,
return -EINVAL;
}
if (dm_old_plane_state->dc_state)
dc_plane_state_release(dm_old_plane_state->dc_state);
dc_plane_state_release(dm_old_plane_state->dc_state);
dm_new_plane_state->dc_state = NULL;
*lock_and_validation_needed = true;
......@@ -10158,6 +10179,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars);
if (ret) {
DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n");
ret = -EINVAL;
goto fail;
}
......
......@@ -687,7 +687,6 @@ static void apply_synaptics_fifo_reset_wa(struct drm_dp_aux *aux)
return;
data[0] |= (1 << 1); // set bit 1 to 1
return;
if (!execute_synaptics_rc_command(aux, false, 0x31, 4, 0x221198, data))
return;
......
......@@ -379,13 +379,17 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
if (aconnector->dc_sink && connector->state) {
struct drm_device *dev = connector->dev;
struct amdgpu_device *adev = drm_to_adev(dev);
struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
struct hdcp_workqueue *hdcp_w = &hdcp_work[aconnector->dc_link->link_index];
connector->state->hdcp_content_type =
hdcp_w->hdcp_content_type[connector->index];
connector->state->content_protection =
hdcp_w->content_protection[connector->index];
if (adev->dm.hdcp_workqueue) {
struct hdcp_workqueue *hdcp_work = adev->dm.hdcp_workqueue;
struct hdcp_workqueue *hdcp_w =
&hdcp_work[aconnector->dc_link->link_index];
connector->state->hdcp_content_type =
hdcp_w->hdcp_content_type[connector->index];
connector->state->content_protection =
hdcp_w->content_protection[connector->index];
}
}
if (aconnector->dc_sink) {
......@@ -1406,6 +1410,7 @@ int pre_validate_dsc(struct drm_atomic_state *state,
ret = pre_compute_mst_dsc_configs_for_state(state, local_dc_state, vars);
if (ret != 0) {
DRM_INFO_ONCE("pre_compute_mst_dsc_configs_for_state() failed\n");
ret = -EINVAL;
goto clean_exit;
}
......
......@@ -89,6 +89,7 @@ void dc_fpu_begin(const char *function_name, const int line)
if (*pcpu == 1) {
#if defined(CONFIG_X86)
migrate_disable();
kernel_fpu_begin();
#elif defined(CONFIG_PPC64)
if (cpu_has_feature(CPU_FTR_VSX_COMP)) {
......@@ -129,6 +130,7 @@ void dc_fpu_end(const char *function_name, const int line)
if (*pcpu <= 0) {
#if defined(CONFIG_X86)
kernel_fpu_end();
migrate_enable();
#elif defined(CONFIG_PPC64)
if (cpu_has_feature(CPU_FTR_VSX_COMP)) {
disable_kernel_vsx();
......
......@@ -878,6 +878,8 @@ void dcn32_clk_mgr_construct(
struct pp_smu_funcs *pp_smu,
struct dccg *dccg)
{
struct clk_log_info log_info = {0};
clk_mgr->base.ctx = ctx;
clk_mgr->base.funcs = &dcn32_funcs;
if (ASICREV_IS_GC_11_0_2(clk_mgr->base.ctx->asic_id.hw_internal_rev)) {
......@@ -911,6 +913,7 @@ void dcn32_clk_mgr_construct(
clk_mgr->base.clks.ref_dtbclk_khz = 268750;
}
/* integer part is now VCO frequency in kHz */
clk_mgr->base.dentist_vco_freq_khz = dcn32_get_vco_frequency_from_reg(clk_mgr);
......@@ -918,6 +921,8 @@ void dcn32_clk_mgr_construct(
if (clk_mgr->base.dentist_vco_freq_khz == 0)
clk_mgr->base.dentist_vco_freq_khz = 4300000; /* Updated as per HW docs */
dcn32_dump_clk_registers(&clk_mgr->base.boot_snapshot, &clk_mgr->base, &log_info);
if (ctx->dc->debug.disable_dtb_ref_clk_switch &&
clk_mgr->base.clks.ref_dtbclk_khz != clk_mgr->base.boot_snapshot.dtbclk) {
clk_mgr->base.clks.ref_dtbclk_khz = clk_mgr->base.boot_snapshot.dtbclk;
......
......@@ -1707,6 +1707,9 @@ bool dc_remove_plane_from_context(
struct dc_stream_status *stream_status = NULL;
struct resource_pool *pool = dc->res_pool;
if (!plane_state)
return true;
for (i = 0; i < context->stream_count; i++)
if (context->streams[i] == stream) {
stream_status = &context->stream_status[i];
......
......@@ -1454,6 +1454,7 @@ struct dc_link {
struct ddc_service *ddc;
enum dp_panel_mode panel_mode;
bool aux_mode;
/* Private to DC core */
......
......@@ -144,7 +144,7 @@ struct test_pattern {
unsigned int cust_pattern_size;
};
#define SUBVP_DRR_MARGIN_US 600 // 600us for DRR margin (SubVP + DRR)
#define SUBVP_DRR_MARGIN_US 100 // 100us for DRR margin (SubVP + DRR)
enum mall_stream_type {
SUBVP_NONE, // subvp not in use
......
......@@ -3031,10 +3031,12 @@ void dce110_enable_dp_link_output(
const struct link_hwss *link_hwss = get_link_hwss(link, link_res);
unsigned int i;
/*
* Add the logic to extract BOTH power up and power down sequences
* from enable/disable link output and only call edp panel control
* in enable_link_dp and disable_link_dp once.
*/
if (link->connector_signal == SIGNAL_TYPE_EDP) {
if (!link->dc->config.edp_no_power_sequencing)
link->dc->hwss.edp_power_control(link, true);
link->dc->hwss.edp_wait_for_hpd_ready(link, true);
}
......@@ -3096,11 +3098,12 @@ void dce110_disable_link_output(struct dc_link *link,
link_hwss->disable_link_output(link, link_res, signal);
link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF;
if (signal == SIGNAL_TYPE_EDP &&
link->dc->hwss.edp_backlight_control)
link->dc->hwss.edp_power_control(link, false);
else if (dmcu != NULL && dmcu->funcs->lock_phy)
/*
* Add the logic to extract BOTH power up and power down sequences
* from enable/disable link output and only call edp panel control
* in enable_link_dp and disable_link_dp once.
*/
if (dmcu != NULL && dmcu->funcs->lock_phy)
dmcu->funcs->unlock_phy(dmcu);
dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
}
......
......@@ -2113,6 +2113,15 @@ void dcn20_optimize_bandwidth(
if (hubbub->funcs->program_compbuf_size)
hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true);
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
dc_dmub_srv_p_state_delegate(dc,
true, context);
context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
dc->clk_mgr->clks.fw_based_mclk_switching = true;
} else {
dc->clk_mgr->clks.fw_based_mclk_switching = false;
}
dc->clk_mgr->funcs->update_clocks(
dc->clk_mgr,
context,
......
......@@ -983,13 +983,36 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,
}
void dcn30_prepare_bandwidth(struct dc *dc,
struct dc_state *context)
struct dc_state *context)
{
bool p_state_change_support = context->bw_ctx.bw.dcn.clk.p_state_change_support;
/* Any transition into an FPO config should disable MCLK switching first to avoid
* driver and FW P-State synchronization issues.
*/
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
dc->optimized_required = true;
context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
}
if (dc->clk_mgr->dc_mode_softmax_enabled)
if (dc->clk_mgr->clks.dramclk_khz <= dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000 &&
context->bw_ctx.bw.dcn.clk.dramclk_khz > dc->clk_mgr->bw_params->dc_mode_softmax_memclk * 1000)
dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz);
dcn20_prepare_bandwidth(dc, context);
/*
* enabled -> enabled: do not disable
* enabled -> disabled: disable
* disabled -> enabled: don't care
* disabled -> disabled: don't care
*/
if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
dc_dmub_srv_p_state_delegate(dc, false, context);
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dc->clk_mgr->clks.fw_based_mclk_switching) {
/* After disabling P-State, restore the original value to ensure we get the correct P-State
* on the next optimize. */
context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support;
}
}
......@@ -701,7 +701,9 @@ static const struct dc_plane_cap plane_cap = {
.argb8888 = 167,
.nv12 = 167,
.fp16 = 167
}
},
16,
16
};
static const struct dc_debug_options debug_defaults_drv = {
......
......@@ -295,6 +295,10 @@ void dcn31_init_hw(struct dc *dc)
if (dc->res_pool->hubbub->funcs->init_crb)
dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
#endif
// Get DMCUB capabilities
dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub);
dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
}
void dcn31_dsc_pg_control(
......
......@@ -274,7 +274,7 @@ static void dccg314_set_dpstreamclk(
}
}
void dccg314_init(struct dccg *dccg)
static void dccg314_init(struct dccg *dccg)
{
int otg_inst;
......
......@@ -885,7 +885,7 @@ static const struct dc_plane_cap plane_cap = {
static const struct dc_debug_options debug_defaults_drv = {
.disable_z10 = false,
.enable_z9_disable_interface = true,
.minimum_z8_residency_time = 3080,
.minimum_z8_residency_time = 2000,
.psr_skip_crtc_disable = true,
.disable_dmcu = true,
.force_abm_enable = false,
......
......@@ -948,6 +948,7 @@ void dcn32_init_hw(struct dc *dc)
if (dc->ctx->dmub_srv) {
dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub);
dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch;
}
}
......
......@@ -324,7 +324,6 @@ static const struct dcn10_link_enc_shift le_shift = {
static const struct dcn10_link_enc_mask le_mask = {
LINK_ENCODER_MASK_SH_LIST_DCN31(_MASK), \
//DPCS_DCN31_MASK_SH_LIST(_MASK)
};
......@@ -2024,7 +2023,7 @@ int dcn32_populate_dml_pipes_from_context(
// In general cases we want to keep the dram clock change requirement
// (prefer configs that support MCLK switch). Only override to false
// for SubVP
if (subvp_in_use)
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || subvp_in_use)
context->bw_ctx.dml.soc.dram_clock_change_requirement_final = false;
else
context->bw_ctx.dml.soc.dram_clock_change_requirement_final = true;
......@@ -2093,27 +2092,28 @@ static bool dcn32_resource_construct(
uint32_t pipe_fuses = 0;
uint32_t num_pipes = 4;
#undef REG_STRUCT
#define REG_STRUCT bios_regs
bios_regs_init();
#undef REG_STRUCT
#define REG_STRUCT clk_src_regs
clk_src_regs_init(0, A),
clk_src_regs_init(1, B),
clk_src_regs_init(2, C),
clk_src_regs_init(3, D),
clk_src_regs_init(4, E);
#undef REG_STRUCT
#define REG_STRUCT abm_regs
abm_regs_init(0),
abm_regs_init(1),
abm_regs_init(2),
abm_regs_init(3);
#undef REG_STRUCT
#define REG_STRUCT dccg_regs
dccg_regs_init();
#undef REG_STRUCT
#define REG_STRUCT bios_regs
bios_regs_init();
#undef REG_STRUCT
#define REG_STRUCT clk_src_regs
clk_src_regs_init(0, A),
clk_src_regs_init(1, B),
clk_src_regs_init(2, C),
clk_src_regs_init(3, D),
clk_src_regs_init(4, E);
#undef REG_STRUCT
#define REG_STRUCT abm_regs
abm_regs_init(0),
abm_regs_init(1),
abm_regs_init(2),
abm_regs_init(3);
#undef REG_STRUCT
#define REG_STRUCT dccg_regs
dccg_regs_init();
DC_FP_START();
......
......@@ -368,7 +368,9 @@ void dcn30_fpu_update_soc_for_wm_a(struct dc *dc, struct dc_state *context)
dc_assert_fp_enabled();
if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].valid) {
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching ||
context->bw_ctx.dml.soc.dram_clock_change_latency_us == 0)
context->bw_ctx.dml.soc.dram_clock_change_latency_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us;
context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us;
}
......@@ -563,6 +565,20 @@ void dcn30_fpu_calculate_wm_and_dlg(
pipe_idx++;
}
// WA: restrict FPO to use first non-strobe mode (NV24 BW issue)
if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching &&
dc->dml.soc.num_chans <= 4 &&
context->bw_ctx.dml.vba.DRAMSpeed <= 1700 &&
context->bw_ctx.dml.vba.DRAMSpeed >= 1500) {
for (i = 0; i < dc->dml.soc.num_states; i++) {
if (dc->dml.soc.clock_limits[i].dram_speed_mts > 1700) {
context->bw_ctx.dml.vba.DRAMSpeed = dc->dml.soc.clock_limits[i].dram_speed_mts;
break;
}
}
}
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
if (!pstate_en)
......
......@@ -109,7 +109,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
{
.state = 0,
.dcfclk_mhz = 1564.0,
.fabricclk_mhz = 400.0,
.fabricclk_mhz = 2500.0,
.dispclk_mhz = 2150.0,
.dppclk_mhz = 2150.0,
.phyclk_mhz = 810.0,
......@@ -117,7 +117,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
.phyclk_d32_mhz = 625.0,
.socclk_mhz = 1200.0,
.dscclk_mhz = 716.667,
.dram_speed_mts = 16000.0,
.dram_speed_mts = 18000.0,
.dtbclk_mhz = 1564.0,
},
},
......@@ -148,7 +148,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
.max_avg_fabric_bw_use_normal_percent = 60.0,
.max_avg_dram_bw_use_normal_strobe_percent = 50.0,
.max_avg_dram_bw_use_normal_percent = 15.0,
.num_chans = 8,
.num_chans = 24,
.dram_channel_width_bytes = 2,
.fabric_datapath_to_dcn_data_return_bytes = 64,
.return_bus_width_bytes = 64,
......@@ -1331,6 +1331,11 @@ static void dcn32_calculate_dlg_params(struct dc *dc, struct dc_state *context,
context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb]
!= dm_dram_clock_change_unsupported;
/* Pstate change might not be supported by hardware, but it might be
* possible with firmware driven vertical blank stretching.
*/
context->bw_ctx.bw.dcn.clk.p_state_change_support |= context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching;
context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
context->bw_ctx.bw.dcn.clk.dtbclk_en = is_dtbclk_required(dc, context);
context->bw_ctx.bw.dcn.clk.ref_dtbclk_khz = context->bw_ctx.dml.vba.DTBCLKPerState[vlevel] * 1000;
......@@ -2871,3 +2876,9 @@ bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint
}
return vactive_found;
}
void dcn32_set_clock_limits(const struct _vcs_dpi_soc_bounding_box_st *soc_bb)
{
dc_assert_fp_enabled();
dcn3_2_soc.clock_limits[0].dcfclk_mhz = 1200.0;
}
......@@ -80,4 +80,6 @@ void dcn32_assign_fpo_vactive_candidate(struct dc *dc, const struct dc_state *co
bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint32_t vactive_margin_req);
void dcn32_set_clock_limits(const struct _vcs_dpi_soc_bounding_box_st *soc_bb);
#endif
......@@ -106,16 +106,16 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
.clock_limits = {
{
.state = 0,
.dcfclk_mhz = 1564.0,
.fabricclk_mhz = 400.0,
.dispclk_mhz = 2150.0,
.dppclk_mhz = 2150.0,
.dcfclk_mhz = 1434.0,
.fabricclk_mhz = 2250.0,
.dispclk_mhz = 1720.0,
.dppclk_mhz = 1720.0,
.phyclk_mhz = 810.0,
.phyclk_d18_mhz = 667.0,
.phyclk_d32_mhz = 625.0,
.phyclk_d32_mhz = 313.0,
.socclk_mhz = 1200.0,
.dscclk_mhz = 716.667,
.dram_speed_mts = 1600.0,
.dscclk_mhz = 573.333,
.dram_speed_mts = 16000.0,
.dtbclk_mhz = 1564.0,
},
},
......@@ -125,14 +125,14 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
.sr_exit_z8_time_us = 285.0,
.sr_enter_plus_exit_z8_time_us = 320,
.writeback_latency_us = 12.0,
.round_trip_ping_latency_dcfclk_cycles = 263,
.round_trip_ping_latency_dcfclk_cycles = 207,
.urgent_latency_pixel_data_only_us = 4,
.urgent_latency_pixel_mixed_with_vm_data_us = 4,
.urgent_latency_vm_data_only_us = 4,
.fclk_change_latency_us = 20,
.usr_retraining_latency_us = 2,
.smn_latency_us = 2,
.mall_allocated_for_dcn_mbytes = 64,
.fclk_change_latency_us = 7,
.usr_retraining_latency_us = 0,
.smn_latency_us = 0,
.mall_allocated_for_dcn_mbytes = 32,
.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
......
......@@ -1927,6 +1927,11 @@ static void disable_link_dp(struct dc_link *link,
dp_disable_link_phy(link, link_res, signal);
if (link->connector_signal == SIGNAL_TYPE_EDP) {
if (!link->dc->config.edp_no_power_sequencing)
link->dc->hwss.edp_power_control(link, false);
}
if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
/* set the sink to SST mode after disabling the link */
enable_mst_on_sink(link, false);
......
......@@ -1596,7 +1596,10 @@ bool perform_link_training_with_retries(
* Report and continue with eDP panel mode to
* perform eDP link training with right settings
*/
cp_psp->funcs.enable_assr(cp_psp->handle, link);
bool result;
result = cp_psp->funcs.enable_assr(cp_psp->handle, link);
if (!result && link->panel_mode != DP_PANEL_MODE_EDP)
panel_mode = DP_PANEL_MODE_DEFAULT;
}
}
......
......@@ -83,6 +83,7 @@ void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
ASSERT(result == DC_OK);
}
}
link->panel_mode = panel_mode;
DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
"eDP panel mode enabled: %d \n",
link->link_index,
......
......@@ -130,12 +130,13 @@ void dmub_dcn32_reset(struct dmub_srv *dmub)
REG_WRITE(DMCUB_INBOX1_WPTR, 0);
REG_WRITE(DMCUB_OUTBOX1_RPTR, 0);
REG_WRITE(DMCUB_OUTBOX1_WPTR, 0);
REG_WRITE(DMCUB_OUTBOX0_RPTR, 0);
REG_WRITE(DMCUB_OUTBOX0_WPTR, 0);
REG_WRITE(DMCUB_SCRATCH0, 0);
}
void dmub_dcn32_reset_release(struct dmub_srv *dmub)
{
REG_WRITE(DMCUB_GPINT_DATAIN1, 0);
REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 0);
REG_WRITE(DMCUB_SCRATCH15, dmub->psp_version & 0x001100FF);
REG_UPDATE_2(DMCUB_CNTL, DMCUB_ENABLE, 1, DMCUB_TRACEPORT_EN, 1);
......
......@@ -104,6 +104,7 @@ static inline bool dc_is_audio_capable_signal(enum signal_type signal)
{
return (signal == SIGNAL_TYPE_DISPLAY_PORT ||
signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
signal == SIGNAL_TYPE_VIRTUAL ||
dc_is_hdmi_signal(signal));
}
......
......@@ -62,8 +62,8 @@
#define CTF_OFFSET_HOTSPOT 5
#define CTF_OFFSET_MEM 5
static const int pmfw_decoded_link_speed[5] = {1, 2, 3, 4, 5};
static const int pmfw_decoded_link_width[7] = {0, 1, 2, 4, 8, 12, 16};
extern const int pmfw_decoded_link_speed[5];
extern const int pmfw_decoded_link_width[7];
#define DECODE_GEN_SPEED(gen_speed_idx) (pmfw_decoded_link_speed[gen_speed_idx])
#define DECODE_LANE_WIDTH(lane_width_idx) (pmfw_decoded_link_width[lane_width_idx])
......
......@@ -85,6 +85,9 @@ MODULE_FIRMWARE("amdgpu/smu_13_0_10.bin");
static const int link_width[] = {0, 1, 2, 4, 8, 12, 16};
static const int link_speed[] = {25, 50, 80, 160};
const int pmfw_decoded_link_speed[5] = {1, 2, 3, 4, 5};
const int pmfw_decoded_link_width[7] = {0, 1, 2, 4, 8, 12, 16};
int smu_v13_0_init_microcode(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment