diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display')
42 files changed, 372 insertions, 213 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 467796d97313..47338a8200ed 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1939,17 +1939,15 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) adev->dm.hdcp_workqueue = NULL; } - if (adev->dm.dc) + if (adev->dm.dc) { dc_deinit_callbacks(adev->dm.dc); - - if (adev->dm.dc) dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv); - - if (dc_enable_dmub_notifications(adev->dm.dc)) { - kfree(adev->dm.dmub_notify); - adev->dm.dmub_notify = NULL; - destroy_workqueue(adev->dm.delayed_hpd_wq); - adev->dm.delayed_hpd_wq = NULL; + if (dc_enable_dmub_notifications(adev->dm.dc)) { + kfree(adev->dm.dmub_notify); + adev->dm.dmub_notify = NULL; + destroy_workqueue(adev->dm.delayed_hpd_wq); + adev->dm.delayed_hpd_wq = NULL; + } } if (adev->dm.dmub_bo) @@ -1957,7 +1955,7 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) &adev->dm.dmub_bo_gpu_addr, &adev->dm.dmub_bo_cpu_addr); - if (adev->dm.hpd_rx_offload_wq) { + if (adev->dm.hpd_rx_offload_wq && adev->dm.dc) { for (i = 0; i < adev->dm.dc->caps.max_links; i++) { if (adev->dm.hpd_rx_offload_wq[i].wq) { destroy_workqueue(adev->dm.hpd_rx_offload_wq[i].wq); @@ -2130,7 +2128,8 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_4_MAILBOX DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_5_TRACEBUFF DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_6_FW_STATE - DMUB_WINDOW_MEMORY_TYPE_FB //DMUB_WINDOW_7_SCRATCH_MEM + DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_7_SCRATCH_MEM + DMUB_WINDOW_MEMORY_TYPE_FB, //DMUB_WINDOW_SHARED_STATE }; int r; @@ -5254,6 +5253,7 @@ static void fill_dc_dirty_rects(struct drm_plane *plane, struct drm_plane_state *new_plane_state, struct drm_crtc_state *crtc_state, struct dc_flip_addrs *flip_addrs, + bool is_psr_su, bool *dirty_regions_changed) { struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); @@ -5278,6 +5278,10 @@ static void fill_dc_dirty_rects(struct drm_plane *plane, num_clips = drm_plane_get_damage_clips_count(new_plane_state); clips = drm_plane_get_damage_clips(new_plane_state); + if (num_clips && (!amdgpu_damage_clips || (amdgpu_damage_clips < 0 && + is_psr_su))) + goto ffu; + if (!dm_crtc_state->mpo_requested) { if (!num_clips || num_clips > DC_MAX_DIRTY_RECTS) goto ffu; @@ -6229,7 +6233,9 @@ create_stream_for_sink(struct drm_connector *connector, if (recalculate_timing) { freesync_mode = get_highest_refresh_rate_mode(aconnector, false); drm_mode_copy(&saved_mode, &mode); + saved_mode.picture_aspect_ratio = mode.picture_aspect_ratio; drm_mode_copy(&mode, freesync_mode); + mode.picture_aspect_ratio = saved_mode.picture_aspect_ratio; } else { decide_crtc_timing_for_drm_display_mode( &mode, preferred_mode, scale); @@ -6509,7 +6515,8 @@ static void amdgpu_dm_connector_unregister(struct drm_connector *connector) { struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && + amdgpu_dm_abm_level < 0) sysfs_remove_group(&connector->kdev->kobj, &amdgpu_group); drm_dp_aux_unregister(&amdgpu_dm_connector->dm_dp_aux.aux); @@ -6573,9 +6580,12 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector) state->vcpi_slots = 0; state->pbn = 0; - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) - state->abm_level = amdgpu_dm_abm_level ?: - ABM_LEVEL_IMMEDIATE_DISABLE; + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + if (amdgpu_dm_abm_level <= 0) + state->abm_level = ABM_LEVEL_IMMEDIATE_DISABLE; + else + state->abm_level = amdgpu_dm_abm_level; + } __drm_atomic_helper_connector_reset(connector, &state->base); } @@ -6613,7 +6623,8 @@ amdgpu_dm_connector_late_register(struct drm_connector *connector) to_amdgpu_dm_connector(connector); int r; - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP && + amdgpu_dm_abm_level < 0) { r = sysfs_create_group(&connector->kdev->kobj, &amdgpu_group); if (r) @@ -7643,7 +7654,8 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc; if (connector_type == DRM_MODE_CONNECTOR_eDP && - (dc_is_dmcu_initialized(adev->dm.dc) || adev->dm.dc->ctx->dmub_srv)) { + (dc_is_dmcu_initialized(adev->dm.dc) || + adev->dm.dc->ctx->dmub_srv) && amdgpu_dm_abm_level < 0) { drm_object_attach_property(&aconnector->base.base, adev->mode_info.abm_level_property, 0); } @@ -8411,6 +8423,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, fill_dc_dirty_rects(plane, old_plane_state, new_plane_state, new_crtc_state, &bundle->flip_addrs[planes_count], + acrtc_state->stream->link->psr_settings.psr_version == + DC_PSR_VERSION_SU_1, &dirty_rects_changed); /* diff --git a/drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c index f2dfa96f9ef5..39530b2ea495 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c @@ -94,7 +94,7 @@ static void calculate_bandwidth( const uint32_t s_high = 7; const uint32_t dmif_chunk_buff_margin = 1; - uint32_t max_chunks_fbc_mode; + uint32_t max_chunks_fbc_mode = 0; int32_t num_cursor_lines; int32_t i, j, k; diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 960c4b4f6ddf..05f392501c0a 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -1850,19 +1850,21 @@ static enum bp_result get_firmware_info_v3_2( /* Vega12 */ smu_info_v3_2 = GET_IMAGE(struct atom_smu_info_v3_2, DATA_TABLES(smu_info)); - DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_2->gpuclk_ss_percentage); if (!smu_info_v3_2) return BP_RESULT_BADBIOSTABLE; + DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_2->gpuclk_ss_percentage); + info->default_engine_clk = smu_info_v3_2->bootup_dcefclk_10khz * 10; } else if (revision.minor == 3) { /* Vega20 */ smu_info_v3_3 = GET_IMAGE(struct atom_smu_info_v3_3, DATA_TABLES(smu_info)); - DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_3->gpuclk_ss_percentage); if (!smu_info_v3_3) return BP_RESULT_BADBIOSTABLE; + DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", smu_info_v3_3->gpuclk_ss_percentage); + info->default_engine_clk = smu_info_v3_3->bootup_dcefclk_10khz * 10; } @@ -2422,10 +2424,11 @@ static enum bp_result get_integrated_info_v11( info_v11 = GET_IMAGE(struct atom_integrated_system_info_v1_11, DATA_TABLES(integratedsysteminfo)); - DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v11->gpuclk_ss_percentage); if (info_v11 == NULL) return BP_RESULT_BADBIOSTABLE; + DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v11->gpuclk_ss_percentage); + info->gpu_cap_info = le32_to_cpu(info_v11->gpucapinfo); /* @@ -2637,11 +2640,12 @@ static enum bp_result get_integrated_info_v2_1( info_v2_1 = GET_IMAGE(struct atom_integrated_system_info_v2_1, DATA_TABLES(integratedsysteminfo)); - DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v2_1->gpuclk_ss_percentage); if (info_v2_1 == NULL) return BP_RESULT_BADBIOSTABLE; + DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v2_1->gpuclk_ss_percentage); + info->gpu_cap_info = le32_to_cpu(info_v2_1->gpucapinfo); /* @@ -2799,11 +2803,11 @@ static enum bp_result get_integrated_info_v2_2( info_v2_2 = GET_IMAGE(struct atom_integrated_system_info_v2_2, DATA_TABLES(integratedsysteminfo)); - DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v2_2->gpuclk_ss_percentage); - if (info_v2_2 == NULL) return BP_RESULT_BADBIOSTABLE; + DC_LOG_BIOS("gpuclk_ss_percentage (unit of 0.001 percent): %d\n", info_v2_2->gpuclk_ss_percentage); + info->gpu_cap_info = le32_to_cpu(info_v2_2->gpucapinfo); /* diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index 28a2a837d2f0..86ee4fe4f5e3 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -340,7 +340,6 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p dcn32_clk_mgr_construct(ctx, clk_mgr, pp_smu, dccg); return &clk_mgr->base; - break; } case AMDGPU_FAMILY_GC_11_0_1: { diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c index a5489fe6875f..aa9fd1dc550a 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c @@ -546,6 +546,8 @@ static unsigned int find_dcfclk_for_voltage(const struct vg_dpm_clocks *clock_ta int i; for (i = 0; i < VG_NUM_SOC_VOLTAGE_LEVELS; i++) { + if (i >= VG_NUM_DCFCLK_DPM_LEVELS) + break; if (clock_table->SocVoltage[i] == voltage) return clock_table->DcfClocks[i]; } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c index 06edca50a8fa..c378b879c76d 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c @@ -414,7 +414,6 @@ static void init_clk_states(struct clk_mgr *clk_mgr) uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz; memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks)); - clk_mgr->clks.dtbclk_en = true; clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk; // restore ref_dtbclk clk_mgr->clks.p_state_change_support = true; clk_mgr->clks.prev_p_state_change_support = true; @@ -659,10 +658,13 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1]; uint32_t max_fclk = 0, min_pstate = 0, max_dispclk = 0, max_dppclk = 0; uint32_t max_pstate = 0, max_dram_speed_mts = 0, min_dram_speed_mts = 0; + uint32_t num_memps, num_fclk, num_dcfclk; int i; /* Determine min/max p-state values. */ - for (i = 0; i < clock_table->NumMemPstatesEnabled; i++) { + num_memps = (clock_table->NumMemPstatesEnabled > NUM_MEM_PSTATE_LEVELS) ? NUM_MEM_PSTATE_LEVELS : + clock_table->NumMemPstatesEnabled; + for (i = 0; i < num_memps; i++) { uint32_t dram_speed_mts = calc_dram_speed_mts(&clock_table->MemPstateTable[i]); if (is_valid_clock_value(dram_speed_mts) && dram_speed_mts > max_dram_speed_mts) { @@ -674,7 +676,7 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk min_dram_speed_mts = max_dram_speed_mts; min_pstate = max_pstate; - for (i = 0; i < clock_table->NumMemPstatesEnabled; i++) { + for (i = 0; i < num_memps; i++) { uint32_t dram_speed_mts = calc_dram_speed_mts(&clock_table->MemPstateTable[i]); if (is_valid_clock_value(dram_speed_mts) && dram_speed_mts < min_dram_speed_mts) { @@ -703,9 +705,13 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk /* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */ ASSERT(clock_table->NumDcfClkLevelsEnabled > 0); - max_fclk = find_max_clk_value(clock_table->FclkClocks_Freq, clock_table->NumFclkLevelsEnabled); + num_fclk = (clock_table->NumFclkLevelsEnabled > NUM_FCLK_DPM_LEVELS) ? NUM_FCLK_DPM_LEVELS : + clock_table->NumFclkLevelsEnabled; + max_fclk = find_max_clk_value(clock_table->FclkClocks_Freq, num_fclk); - for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) { + num_dcfclk = (clock_table->NumFclkLevelsEnabled > NUM_DCFCLK_DPM_LEVELS) ? NUM_DCFCLK_DPM_LEVELS : + clock_table->NumDcfClkLevelsEnabled; + for (i = 0; i < num_dcfclk; i++) { int j; /* First search defaults for the clocks we don't read using closest lower or equal default dcfclk */ diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c index a07f7e685d28..9e588c56c570 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_smu.c @@ -361,32 +361,32 @@ void dcn35_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zst case DCN_ZSTATE_SUPPORT_ALLOW: msg_id = VBIOSSMC_MSG_AllowZstatesEntry; param = (1 << 10) | (1 << 9) | (1 << 8); - smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW, param = %d\n", __func__, param); + smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW, param = 0x%x\n", __func__, param); break; case DCN_ZSTATE_SUPPORT_DISALLOW: msg_id = VBIOSSMC_MSG_AllowZstatesEntry; param = 0; - smu_print("%s: SMC_MSG_AllowZstatesEntry msg_id = DISALLOW, param = %d\n", __func__, param); + smu_print("%s: SMC_MSG_AllowZstatesEntry msg_id = DISALLOW, param = 0x%x\n", __func__, param); break; case DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY: msg_id = VBIOSSMC_MSG_AllowZstatesEntry; param = (1 << 10); - smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z10_ONLY, param = %d\n", __func__, param); + smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z10_ONLY, param = 0x%x\n", __func__, param); break; case DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY: msg_id = VBIOSSMC_MSG_AllowZstatesEntry; param = (1 << 10) | (1 << 8); - smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z8_Z10_ONLY, param = %d\n", __func__, param); + smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z8_Z10_ONLY, param = 0x%x\n", __func__, param); break; case DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY: msg_id = VBIOSSMC_MSG_AllowZstatesEntry; param = (1 << 8); - smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z8_ONLY, param = %d\n", __func__, param); + smu_print("%s: SMC_MSG_AllowZstatesEntry msg = ALLOW_Z8_ONLY, param = 0x%x\n", __func__, param); break; default: //DCN_ZSTATE_SUPPORT_UNKNOWN @@ -400,7 +400,7 @@ void dcn35_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zst clk_mgr, msg_id, param); - smu_print("%s: msg_id = %d, param = 0x%x, return = %d\n", __func__, msg_id, param, retv); + smu_print("%s: msg_id = %d, param = 0x%x, return = 0x%x\n", __func__, msg_id, param, retv); } int dcn35_smu_get_dprefclk(struct clk_mgr_internal *clk_mgr) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 72512903f88f..4d5194293dbd 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2454,6 +2454,10 @@ static enum surface_update_type get_scaling_info_update_type( /* Changing clip size of a large surface may result in MPC slice count change */ update_flags->bits.bandwidth_change = 1; + if (u->scaling_info->clip_rect.width != u->surface->clip_rect.width || + u->scaling_info->clip_rect.height != u->surface->clip_rect.height) + update_flags->bits.clip_size_change = 1; + if (u->scaling_info->src_rect.x != u->surface->src_rect.x || u->scaling_info->src_rect.y != u->surface->src_rect.y || u->scaling_info->clip_rect.x != u->surface->clip_rect.x @@ -2467,7 +2471,8 @@ static enum surface_update_type get_scaling_info_update_type( || update_flags->bits.scaling_change) return UPDATE_TYPE_FULL; - if (update_flags->bits.position_change) + if (update_flags->bits.position_change || + update_flags->bits.clip_size_change) return UPDATE_TYPE_MED; return UPDATE_TYPE_FAST; @@ -3093,10 +3098,6 @@ static bool update_planes_and_stream_state(struct dc *dc, if (otg_master && otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) resource_build_test_pattern_params(&context->res_ctx, otg_master); - - if (otg_master && (otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422 || - otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)) - resource_build_subsampling_params(&context->res_ctx, otg_master); } } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 96ea283bd169..1b7765bc5e5e 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -822,16 +822,6 @@ static struct rect calculate_odm_slice_in_timing_active(struct pipe_ctx *pipe_ct stream->timing.v_border_bottom + stream->timing.v_border_top; - /* Recout for ODM slices after the first slice need one extra left edge pixel - * for 3-tap chroma subsampling. - */ - if (odm_slice_idx > 0 && - (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422 || - pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)) { - odm_rec.x -= 1; - odm_rec.width += 1; - } - return odm_rec; } @@ -1448,7 +1438,6 @@ void resource_build_test_pattern_params(struct resource_context *res_ctx, enum controller_dp_test_pattern controller_test_pattern; enum controller_dp_color_space controller_color_space; enum dc_color_depth color_depth = otg_master->stream->timing.display_color_depth; - enum dc_pixel_encoding pixel_encoding = otg_master->stream->timing.pixel_encoding; int h_active = otg_master->stream->timing.h_addressable + otg_master->stream->timing.h_border_left + otg_master->stream->timing.h_border_right; @@ -1480,36 +1469,10 @@ void resource_build_test_pattern_params(struct resource_context *res_ctx, else params->width = last_odm_slice_width; - /* Extra left edge pixel is required for 3-tap chroma subsampling. */ - if (i != 0 && (pixel_encoding == PIXEL_ENCODING_YCBCR422 || - pixel_encoding == PIXEL_ENCODING_YCBCR420)) { - params->offset -= 1; - params->width += 1; - } - offset += odm_slice_width; } } -void resource_build_subsampling_params(struct resource_context *res_ctx, - struct pipe_ctx *otg_master) -{ - struct pipe_ctx *opp_heads[MAX_PIPES]; - int odm_cnt = 1; - int i; - - odm_cnt = resource_get_opp_heads_for_otg_master(otg_master, res_ctx, opp_heads); - - /* For ODM slices after the first slice, extra left edge pixel is required - * for 3-tap chroma subsampling. - */ - if (otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR422 || - otg_master->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) { - for (i = 0; i < odm_cnt; i++) - opp_heads[i]->stream_res.left_edge_extra_pixel = (i == 0) ? false : true; - } -} - bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx) { const struct dc_plane_state *plane_state = pipe_ctx->plane_state; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index c789cc2e216d..9b42f6fc8c69 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -51,7 +51,7 @@ struct aux_payload; struct set_config_cmd_payload; struct dmub_notification; -#define DC_VER "3.2.271" +#define DC_VER "3.2.272" #define MAX_SURFACES 3 #define MAX_PLANES 6 @@ -1252,6 +1252,7 @@ union surface_update_flags { uint32_t rotation_change:1; uint32_t swizzle_change:1; uint32_t scaling_change:1; + uint32_t clip_size_change: 1; uint32_t position_change:1; uint32_t in_transfer_func_change:1; uint32_t input_csc_change:1; @@ -1571,7 +1572,19 @@ struct dc_link { enum engine_id dpia_preferred_eng_id; bool test_pattern_enabled; + /* Pending/Current test pattern are only used to perform and track + * FIXED_VS retimer test pattern/lane adjustment override state. + * Pending allows link HWSS to differentiate PHY vs non-PHY pattern, + * to perform specific lane adjust overrides before setting certain + * PHY test patterns. In cases when lane adjust and set test pattern + * calls are not performed atomically (i.e. performing link training), + * pending_test_pattern will be invalid or contain a non-PHY test pattern + * and current_test_pattern will contain required context for any future + * set pattern/set lane adjust to transition between override state(s). + * */ enum dp_test_pattern current_test_pattern; + enum dp_test_pattern pending_test_pattern; + union compliance_test_state compliance_test_state; void *priv; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index a1477906fe4f..0bc32537e2eb 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -1198,6 +1198,7 @@ bool dc_dmub_srv_is_hw_pwr_up(struct dc_dmub_srv *dc_dmub_srv, bool wait) static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) { + struct dc_dmub_srv *dc_dmub_srv; union dmub_rb_cmd cmd = {0}; if (dc->debug.dmcub_emulation) @@ -1206,6 +1207,8 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) if (!dc->ctx->dmub_srv || !dc->ctx->dmub_srv->dmub) return; + dc_dmub_srv = dc->ctx->dmub_srv; + memset(&cmd, 0, sizeof(cmd)); cmd.idle_opt_notify_idle.header.type = DMUB_CMD__IDLE_OPT; cmd.idle_opt_notify_idle.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_NOTIFY_IDLE; @@ -1216,10 +1219,32 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) cmd.idle_opt_notify_idle.cntl_data.driver_idle = allow_idle; if (allow_idle) { + volatile struct dmub_shared_state_ips_driver *ips_driver = + &dc_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_DRIVER].data.ips_driver; + union dmub_shared_state_ips_driver_signals new_signals; + dc_dmub_srv_wait_idle(dc->ctx->dmub_srv); - if (dc->hwss.set_idle_state) - dc->hwss.set_idle_state(dc, true); + memset(&new_signals, 0, sizeof(new_signals)); + + if (dc->config.disable_ips == DMUB_IPS_ENABLE || + dc->config.disable_ips == DMUB_IPS_DISABLE_DYNAMIC) { + new_signals.bits.allow_pg = 1; + new_signals.bits.allow_ips1 = 1; + new_signals.bits.allow_ips2 = 1; + new_signals.bits.allow_z10 = 1; + } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS1) { + new_signals.bits.allow_ips1 = 1; + } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2) { + new_signals.bits.allow_pg = 1; + new_signals.bits.allow_ips1 = 1; + } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2_Z10) { + new_signals.bits.allow_pg = 1; + new_signals.bits.allow_ips1 = 1; + new_signals.bits.allow_ips2 = 1; + } + + ips_driver->signals = new_signals; } /* NOTE: This does not use the "wake" interface since this is part of the wake path. */ @@ -1229,8 +1254,7 @@ static void dc_dmub_srv_notify_idle(const struct dc *dc, bool allow_idle) static void dc_dmub_srv_exit_low_power_state(const struct dc *dc) { - uint32_t allow_state = 0; - uint32_t commit_state = 0; + struct dc_dmub_srv *dc_dmub_srv; if (dc->debug.dmcub_emulation) return; @@ -1238,61 +1262,44 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc) if (!dc->ctx->dmub_srv || !dc->ctx->dmub_srv->dmub) return; - if (dc->hwss.get_idle_state && - dc->hwss.set_idle_state && - dc->clk_mgr->funcs->exit_low_power_state) { + dc_dmub_srv = dc->ctx->dmub_srv; - allow_state = dc->hwss.get_idle_state(dc); - dc->hwss.set_idle_state(dc, false); + if (dc->clk_mgr->funcs->exit_low_power_state) { + volatile const struct dmub_shared_state_ips_fw *ips_fw = + &dc_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_FW].data.ips_fw; + volatile struct dmub_shared_state_ips_driver *ips_driver = + &dc_dmub_srv->dmub->shared_state[DMUB_SHARED_SHARE_FEATURE__IPS_DRIVER].data.ips_driver; + union dmub_shared_state_ips_driver_signals prev_driver_signals = ips_driver->signals; - if (!(allow_state & DMUB_IPS2_ALLOW_MASK)) { - // Wait for evaluation time - for (;;) { - udelay(dc->debug.ips2_eval_delay_us); - commit_state = dc->hwss.get_idle_state(dc); - if (commit_state & DMUB_IPS2_ALLOW_MASK) - break; + ips_driver->signals.all = 0; - /* allow was still set, retry eval delay */ - dc->hwss.set_idle_state(dc, false); - } + if (prev_driver_signals.bits.allow_ips2) { + udelay(dc->debug.ips2_eval_delay_us); - if (!(commit_state & DMUB_IPS2_COMMIT_MASK)) { + if (ips_fw->signals.bits.ips2_commit) { // Tell PMFW to exit low power state dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr); // Wait for IPS2 entry upper bound udelay(dc->debug.ips2_entry_delay_us); - dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr); - for (;;) { - commit_state = dc->hwss.get_idle_state(dc); - if (commit_state & DMUB_IPS2_COMMIT_MASK) - break; + dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr); + while (ips_fw->signals.bits.ips2_commit) udelay(1); - } if (!dc_dmub_srv_is_hw_pwr_up(dc->ctx->dmub_srv, true)) ASSERT(0); - /* TODO: See if we can return early here - IPS2 should go - * back directly to IPS0 and clear the flags, but it will - * be safer to directly notify DMCUB of this. - */ - allow_state = dc->hwss.get_idle_state(dc); + dmub_srv_sync_inbox1(dc->ctx->dmub_srv->dmub); } } dc_dmub_srv_notify_idle(dc, false); - if (!(allow_state & DMUB_IPS1_ALLOW_MASK)) { - for (;;) { - commit_state = dc->hwss.get_idle_state(dc); - if (commit_state & DMUB_IPS1_COMMIT_MASK) - break; - + if (prev_driver_signals.bits.allow_ips1) { + while (ips_fw->signals.bits.ips1_commit) udelay(1); - } + } } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c index ba1fec3016d5..bf636b28e3e1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c @@ -65,5 +65,9 @@ bool should_use_dmub_lock(struct dc_link *link) { if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) return true; + + if (link->replay_settings.replay_feature_enabled) + return true; + return false; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c index 54ec144f7b81..2f5b3fbd3507 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c @@ -56,16 +56,13 @@ static void dpp3_enable_cm_block( static enum dc_lut_mode dpp30_get_gamcor_current(struct dpp *dpp_base) { - enum dc_lut_mode mode; + enum dc_lut_mode mode = LUT_BYPASS; uint32_t state_mode; uint32_t lut_mode; struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &state_mode); - if (state_mode == 0) - mode = LUT_BYPASS; - if (state_mode == 2) {//Programmable RAM LUT REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_SELECT_CURRENT, &lut_mode); if (lut_mode == 0) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index ba76dd4a2ce2..a0a65e099104 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -2760,7 +2760,7 @@ static int build_synthetic_soc_states(bool disable_dc_mode_overwrite, struct clk struct _vcs_dpi_voltage_scaling_st entry = {0}; struct clk_limit_table_entry max_clk_data = {0}; - unsigned int min_dcfclk_mhz = 399, min_fclk_mhz = 599; + unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299; static const unsigned int num_dcfclk_stas = 5; unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 1324, 1564}; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c index 912256006d75..80bebfc268db 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c @@ -588,7 +588,9 @@ void dcn35_decide_zstate_support(struct dc *dc, struct dc_state *context) } else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { struct dc_link *link = context->streams[0]->sink->link; bool is_pwrseq0 = link && link->link_index == 0; - bool is_psr1 = link && link->psr_settings.psr_version == DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr; + bool is_psr = (link && (link->psr_settings.psr_version == DC_PSR_VERSION_1 || + link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) && !link->panel_config.psr.disable_psr); + bool is_replay = link && link->replay_settings.replay_feature_enabled; int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000; bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency; @@ -596,12 +598,14 @@ void dcn35_decide_zstate_support(struct dc *dc, struct dc_state *context) dc->debug.minimum_z10_residency_time > 0 ? dc->debug.minimum_z10_residency_time : 5000; bool allow_z10 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z10_residency; + /*for psr1/psr-su, we allow z8 and z10 based on latency, for replay with IPS enabled, it will enter ips2*/ if (is_pwrseq0 && allow_z10) support = DCN_ZSTATE_SUPPORT_ALLOW; - else if (is_pwrseq0 && is_psr1) + else if (is_pwrseq0 && (is_psr || is_replay)) support = allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY : DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY; else if (allow_z8) support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY; + } context->bw_ctx.bw.dcn.clk.zstate_support = support; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index bc0a21957e33..c55d5155ecb9 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -1573,8 +1573,7 @@ static void dcn20_detect_pipe_changes(struct dc_state *old_state, * makes this assumption at the moment with how hubp reset is matched to * same index mpcc reset. */ - if (old_pipe->stream_res.opp != new_pipe->stream_res.opp || - old_pipe->stream_res.left_edge_extra_pixel != new_pipe->stream_res.left_edge_extra_pixel) + if (old_pipe->stream_res.opp != new_pipe->stream_res.opp) new_pipe->update_flags.bits.opp_changed = 1; if (old_pipe->stream_res.tg != new_pipe->stream_res.tg) new_pipe->update_flags.bits.tg_changed = 1; @@ -1740,6 +1739,7 @@ static void dcn20_update_dchubp_dpp( if (pipe_ctx->update_flags.bits.scaler || plane_state->update_flags.bits.scaling_change || plane_state->update_flags.bits.position_change || + plane_state->update_flags.bits.clip_size_change || plane_state->update_flags.bits.per_pixel_alpha_change || pipe_ctx->stream->update_flags.bits.scaling) { pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->plane_state->per_pixel_alpha; @@ -1752,6 +1752,7 @@ static void dcn20_update_dchubp_dpp( if (pipe_ctx->update_flags.bits.viewport || (context == dc->current_state && plane_state->update_flags.bits.position_change) || (context == dc->current_state && plane_state->update_flags.bits.scaling_change) || + (context == dc->current_state && plane_state->update_flags.bits.clip_size_change) || (context == dc->current_state && pipe_ctx->stream->update_flags.bits.scaling)) { hubp->funcs->mem_program_viewport( @@ -1960,10 +1961,6 @@ static void dcn20_program_pipe( pipe_ctx->stream_res.opp, &pipe_ctx->stream->bit_depth_params, &pipe_ctx->stream->clamping); - - pipe_ctx->stream_res.opp->funcs->opp_program_left_edge_extra_pixel( - pipe_ctx->stream_res.opp, - pipe_ctx->stream_res.left_edge_extra_pixel); } /* Set ABM pipe after other pipe configurations done */ diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c index 5c7f380a84f9..7252f5f781f0 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c @@ -211,7 +211,7 @@ void dcn21_set_pipe(struct pipe_ctx *pipe_ctx) struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu; uint32_t otg_inst; - if (!abm && !tg && !panel_cntl) + if (!abm || !tg || !panel_cntl) return; otg_inst = tg->inst; @@ -245,7 +245,7 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx, struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; uint32_t otg_inst; - if (!abm && !tg && !panel_cntl) + if (!abm || !tg || !panel_cntl) return false; otg_inst = tg->inst; diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index ebb659c327e0..3a6bf77a6873 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -333,8 +333,6 @@ struct stream_resource { uint8_t gsl_group; struct test_pattern_params test_pattern_params; - - bool left_edge_extra_pixel; }; struct plane_resource { diff --git a/drivers/gpu/drm/amd/display/dc/inc/resource.h b/drivers/gpu/drm/amd/display/dc/inc/resource.h index b14d52e52fa2..77a60aa9f27b 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/resource.h +++ b/drivers/gpu/drm/amd/display/dc/inc/resource.h @@ -107,10 +107,6 @@ void resource_build_test_pattern_params( struct resource_context *res_ctx, struct pipe_ctx *pipe_ctx); -void resource_build_subsampling_params( - struct resource_context *res_ctx, - struct pipe_ctx *pipe_ctx); - bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx); enum dc_status resource_build_scaling_params_for_context( diff --git a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c index 2d152b68a501..22b24749c9d2 100644 --- a/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c +++ b/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c @@ -61,22 +61,6 @@ static enum dc_link_rate get_link_rate_from_test_link_rate(uint8_t test_rate) } } -static bool is_dp_phy_sqaure_pattern(enum dp_test_pattern test_pattern) -{ - return (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern && - test_pattern <= DP_TEST_PATTERN_SQUARE_END); -} - -static bool is_dp_phy_pattern(enum dp_test_pattern test_pattern) -{ - if ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern && - test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) || - test_pattern == DP_TEST_PATTERN_VIDEO_MODE) - return true; - else - return false; -} - static void dp_retrain_link_dp_test(struct dc_link *link, struct dc_link_settings *link_setting, bool skip_video_pattern) @@ -361,7 +345,7 @@ static void dp_test_send_phy_test_pattern(struct dc_link *link) test_pattern_size); } - if (is_dp_phy_sqaure_pattern(test_pattern)) { + if (IS_DP_PHY_SQUARE_PATTERN(test_pattern)) { test_pattern_size = 1; // Square pattern data is 1 byte (DP spec) core_link_read_dpcd( link, @@ -623,6 +607,8 @@ bool dp_set_test_pattern( if (pipe_ctx == NULL) return false; + link->pending_test_pattern = test_pattern; + /* Reset CRTC Test Pattern if it is currently running and request is VideoMode */ if (link->test_pattern_enabled && test_pattern == DP_TEST_PATTERN_VIDEO_MODE) { @@ -643,12 +629,13 @@ bool dp_set_test_pattern( /* Reset Test Pattern state */ link->test_pattern_enabled = false; link->current_test_pattern = test_pattern; + link->pending_test_pattern = DP_TEST_PATTERN_UNSUPPORTED; return true; } /* Check for PHY Test Patterns */ - if (is_dp_phy_pattern(test_pattern)) { + if (IS_DP_PHY_PATTERN(test_pattern)) { /* Set DPCD Lane Settings before running test pattern */ if (p_link_settings != NULL) { if ((link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && @@ -681,6 +668,7 @@ bool dp_set_test_pattern( /* Set Test Pattern state */ link->test_pattern_enabled = true; link->current_test_pattern = test_pattern; + link->pending_test_pattern = DP_TEST_PATTERN_UNSUPPORTED; if (p_link_settings != NULL) dpcd_set_link_settings(link, p_link_settings); @@ -756,7 +744,7 @@ bool dp_set_test_pattern( return false; if (link->dpcd_caps.dpcd_rev.raw >= DPCD_REV_12) { - if (is_dp_phy_sqaure_pattern(test_pattern)) + if (IS_DP_PHY_SQUARE_PATTERN(test_pattern)) core_link_write_dpcd(link, DP_LINK_SQUARE_PATTERN, p_custom_pattern, @@ -884,6 +872,7 @@ bool dp_set_test_pattern( /* Set Test Pattern state */ link->test_pattern_enabled = true; link->current_test_pattern = test_pattern; + link->pending_test_pattern = DP_TEST_PATTERN_UNSUPPORTED; } return true; diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c index b659baa23147..348ea4cb832d 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio_fixed_vs_pe_retimer.c @@ -80,21 +80,23 @@ static bool set_dio_fixed_vs_pe_retimer_dp_link_test_pattern_override(struct dc_ const uint8_t vendor_lttpr_write_data_pg0[4] = {0x1, 0x11, 0x0, 0x0}; const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 0x0, 0x06}; + if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED) + return false; if (tp_params == NULL) return false; - if (link->current_test_pattern >= DP_TEST_PATTERN_SQUARE_BEGIN && - link->current_test_pattern <= DP_TEST_PATTERN_SQUARE_END) { + if (IS_DP_PHY_SQUARE_PATTERN(link->current_test_pattern)) // Deprogram overrides from previous test pattern dp_dio_fixed_vs_pe_retimer_exit_manual_automation(link); - } switch (tp_params->dp_phy_pattern) { case DP_TEST_PATTERN_80BIT_CUSTOM: if (tp_params->custom_pattern_size == 0 || memcmp(tp_params->custom_pattern, pltpat_custom, tp_params->custom_pattern_size) != 0) return false; + hw_tp_params.custom_pattern = tp_params->custom_pattern; + hw_tp_params.custom_pattern_size = tp_params->custom_pattern_size; break; case DP_TEST_PATTERN_D102: break; @@ -185,13 +187,7 @@ static const struct link_hwss dio_fixed_vs_pe_retimer_link_hwss = { bool requires_fixed_vs_pe_retimer_dio_link_hwss(const struct dc_link *link) { - if (!(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)) - return false; - - if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED) - return false; - - return true; + return (link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN); } const struct link_hwss *get_dio_fixed_vs_pe_retimer_link_hwss(void) diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c index b621b97711b6..3e6c7be7e278 100644 --- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c @@ -74,13 +74,16 @@ static void dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(struct dc_link *link, static void dp_hpo_fixed_vs_pe_retimer_program_override_test_pattern(struct dc_link *link, struct encoder_set_dp_phy_pattern_param *tp_params) { + uint8_t clk_src = 0x4C; + uint8_t pattern = 0x4F; /* SQ128 */ + const uint8_t vendor_lttpr_write_data_pg0[4] = {0x1, 0x11, 0x0, 0x0}; - const uint8_t vendor_lttpr_write_data_pg1[4] = {0x1, 0x50, 0x50, 0x0}; - const uint8_t vendor_lttpr_write_data_pg2[4] = {0x1, 0x51, 0x50, 0x0}; + const uint8_t vendor_lttpr_write_data_pg1[4] = {0x1, 0x50, 0x50, clk_src}; + const uint8_t vendor_lttpr_write_data_pg2[4] = {0x1, 0x51, 0x50, clk_src}; const uint8_t vendor_lttpr_write_data_pg3[4] = {0x1, 0x10, 0x58, 0x21}; const uint8_t vendor_lttpr_write_data_pg4[4] = {0x1, 0x10, 0x59, 0x21}; - const uint8_t vendor_lttpr_write_data_pg5[4] = {0x1, 0x1C, 0x58, 0x4F}; - const uint8_t vendor_lttpr_write_data_pg6[4] = {0x1, 0x1C, 0x59, 0x4F}; + const uint8_t vendor_lttpr_write_data_pg5[4] = {0x1, 0x1C, 0x58, pattern}; + const uint8_t vendor_lttpr_write_data_pg6[4] = {0x1, 0x1C, 0x59, pattern}; const uint8_t vendor_lttpr_write_data_pg7[4] = {0x1, 0x30, 0x51, 0x20}; const uint8_t vendor_lttpr_write_data_pg8[4] = {0x1, 0x30, 0x52, 0x20}; const uint8_t vendor_lttpr_write_data_pg9[4] = {0x1, 0x30, 0x54, 0x20}; @@ -123,18 +126,20 @@ static bool dp_hpo_fixed_vs_pe_retimer_set_override_test_pattern(struct dc_link struct encoder_set_dp_phy_pattern_param hw_tp_params = { 0 }; const uint8_t vendor_lttpr_exit_manual_automation_0[4] = {0x1, 0x11, 0x0, 0x06}; + if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED) + return false; + if (tp_params == NULL) return false; - if (tp_params->dp_phy_pattern < DP_TEST_PATTERN_SQUARE_BEGIN || - tp_params->dp_phy_pattern > DP_TEST_PATTERN_SQUARE_END) { + if (!IS_DP_PHY_SQUARE_PATTERN(tp_params->dp_phy_pattern)) { // Deprogram overrides from previously set square wave override if (link->current_test_pattern == DP_TEST_PATTERN_80BIT_CUSTOM || link->current_test_pattern == DP_TEST_PATTERN_D102) link->dc->link_srv->configure_fixed_vs_pe_retimer(link->ddc, &vendor_lttpr_exit_manual_automation_0[0], sizeof(vendor_lttpr_exit_manual_automation_0)); - else + else if (IS_DP_PHY_SQUARE_PATTERN(link->current_test_pattern)) dp_dio_fixed_vs_pe_retimer_exit_manual_automation(link); return false; @@ -148,8 +153,6 @@ static bool dp_hpo_fixed_vs_pe_retimer_set_override_test_pattern(struct dc_link dp_hpo_fixed_vs_pe_retimer_program_override_test_pattern(link, tp_params); - dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(link, &link->cur_lane_setting[0]); - return true; } @@ -170,16 +173,18 @@ static void set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link, const struct dc_link_settings *link_settings, const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX]) { - link_res->hpo_dp_link_enc->funcs->set_ffe( - link_res->hpo_dp_link_enc, - link_settings, - lane_settings[0].FFE_PRESET.raw); - - // FFE is programmed when retimer is programmed for SQ128, but explicit - // programming needed here as well in case FFE-only update is requested - if (link->current_test_pattern >= DP_TEST_PATTERN_SQUARE_BEGIN && - link->current_test_pattern <= DP_TEST_PATTERN_SQUARE_END) - dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(link, &lane_settings[0]); + // Don't update our HW FFE when outputting phy test patterns + if (IS_DP_PHY_PATTERN(link->pending_test_pattern)) { + // Directly program FIXED_VS retimer FFE for SQ128 override + if (IS_DP_PHY_SQUARE_PATTERN(link->pending_test_pattern)) { + dp_hpo_fixed_vs_pe_retimer_set_tx_ffe(link, &lane_settings[0]); + } + } else { + link_res->hpo_dp_link_enc->funcs->set_ffe( + link_res->hpo_dp_link_enc, + link_settings, + lane_settings[0].FFE_PRESET.raw); + } } static void enable_hpo_fixed_vs_pe_retimer_dp_link_output(struct dc_link *link, @@ -214,13 +219,7 @@ static const struct link_hwss hpo_fixed_vs_pe_retimer_dp_link_hwss = { bool requires_fixed_vs_pe_retimer_hpo_link_hwss(const struct dc_link *link) { - if (!(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN)) - return false; - - if (!link->dpcd_caps.lttpr_caps.main_link_channel_coding.bits.DP_128b_132b_SUPPORTED) - return false; - - return true; + return requires_fixed_vs_pe_retimer_dio_link_hwss(link); } const struct link_hwss *get_hpo_fixed_vs_pe_retimer_dp_link_hwss(void) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_validation.c b/drivers/gpu/drm/amd/display/dc/link/link_validation.c index 1c038e2a527b..1aed55b0ab6a 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_validation.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_validation.c @@ -359,7 +359,7 @@ bool link_validate_dpia_bandwidth(const struct dc_stream_state *stream, const un struct dc_link *dpia_link[MAX_DPIA_NUM] = {0}; int num_dpias = 0; - for (uint8_t i = 0; i < num_streams; ++i) { + for (unsigned int i = 0; i < num_streams; ++i) { if (stream[i].signal == SIGNAL_TYPE_DISPLAY_PORT) { /* new dpia sst stream, check whether it exceeds max dpia */ if (num_dpias >= MAX_DPIA_NUM) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c index 0050e0a06cbc..2fa4e64e2430 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c @@ -37,6 +37,7 @@ #include "clk_mgr.h" #include "resource.h" #include "link_enc_cfg.h" +#include "atomfirmware.h" #define DC_LOGGER \ link->ctx->logger @@ -100,8 +101,11 @@ void dp_set_hw_lane_settings( { const struct link_hwss *link_hwss = get_link_hwss(link, link_res); + // Don't return here if using FIXED_VS link HWSS and encoding is 128b/132b if ((link_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) && - !is_immediate_downstream(link, offset)) + !is_immediate_downstream(link, offset) && + (!(link->chip_caps & EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) || + link_dp_get_encoding_format(&link_settings->link_settings) == DP_8b_10b_ENCODING)) return; if (link_hwss->ext.set_dp_lane_settings) diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index e06d3c2d8910..e538c67d3ed9 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -517,6 +517,7 @@ enum link_training_result dp_check_link_loss_status( { enum link_training_result status = LINK_TRAINING_SUCCESS; union lane_status lane_status; + union lane_align_status_updated dpcd_lane_status_updated; uint8_t dpcd_buf[6] = {0}; uint32_t lane; @@ -532,10 +533,12 @@ enum link_training_result dp_check_link_loss_status( * check lanes status */ lane_status.raw = dp_get_nibble_at_index(&dpcd_buf[2], lane); + dpcd_lane_status_updated.raw = dpcd_buf[4]; if (!lane_status.bits.CHANNEL_EQ_DONE_0 || !lane_status.bits.CR_DONE_0 || - !lane_status.bits.SYMBOL_LOCKED_0) { + !lane_status.bits.SYMBOL_LOCKED_0 || + !dp_is_interlane_aligned(dpcd_lane_status_updated)) { /* if one of the channel equalization, clock * recovery or symbol lock is dropped * consider it as (link has been diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c index e8dda44b23cb..5d36bab0029c 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_dpia.c @@ -619,7 +619,7 @@ static enum link_training_result dpia_training_eq_non_transparent( uint32_t retries_eq = 0; enum dc_status status; enum dc_dp_training_pattern tr_pattern; - uint32_t wait_time_microsec; + uint32_t wait_time_microsec = 0; enum dc_lane_count lane_count = lt_settings->link_settings.lane_count; union lane_align_status_updated dpcd_lane_status_updated = {0}; union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX] = {0}; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c index 443215b96308..acfbbc638cc6 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c @@ -892,7 +892,8 @@ bool edp_set_replay_allow_active(struct dc_link *link, const bool *allow_active, /* Set power optimization flag */ if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts) { - if (link->replay_settings.replay_feature_enabled && replay->funcs->replay_set_power_opt) { + if (replay != NULL && link->replay_settings.replay_feature_enabled && + replay->funcs->replay_set_power_opt) { replay->funcs->replay_set_power_opt(replay, *power_opts, panel_inst); link->replay_settings.replay_power_opt_active = *power_opts; } diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c index e534e87cc85b..5d52853cac96 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -781,7 +781,7 @@ static const struct dc_debug_options debug_defaults_drv = { .disable_z10 = false, .ignore_pg = true, .psp_disabled_wa = true, - .ips2_eval_delay_us = 1650, + .ips2_eval_delay_us = 2000, .ips2_entry_delay_us = 800, .disable_dmub_reallow_idle = true, .static_screen_wait_frames = 2, @@ -1907,7 +1907,8 @@ static bool dcn35_resource_construct( if (dc->ctx->dce_environment == DCE_ENV_PRODUCTION_DRV) dc->debug = debug_defaults_drv; - + /*HW default is to have all the FGCG enabled, SW no need to program them*/ + dc->debug.enable_fine_grain_clock_gating.u32All = 0xFFFF; // Init the vm_helper if (dc->vm_helper) vm_helper_init(dc->vm_helper, 16); diff --git a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h index ae30fe2b6d0d..ff2a65e67bd4 100644 --- a/drivers/gpu/drm/amd/display/dmub/dmub_srv.h +++ b/drivers/gpu/drm/amd/display/dmub/dmub_srv.h @@ -125,6 +125,7 @@ enum dmub_window_id { DMUB_WINDOW_5_TRACEBUFF, DMUB_WINDOW_6_FW_STATE, DMUB_WINDOW_7_SCRATCH_MEM, + DMUB_WINDOW_SHARED_STATE, DMUB_WINDOW_TOTAL, }; @@ -368,7 +369,8 @@ struct dmub_srv_hw_funcs { const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void (*setup_mailbox)(struct dmub_srv *dmub, const struct dmub_region *inbox1); @@ -461,6 +463,7 @@ struct dmub_srv_create_params { * @user_ctx: user provided context for the dmub_srv * @fw_version: the current firmware version, if any * @is_virtual: false if hardware support only + * @shared_state: dmub shared state between firmware and driver * @fw_state: dmub firmware state pointer */ struct dmub_srv { @@ -469,6 +472,7 @@ struct dmub_srv { uint32_t fw_version; bool is_virtual; struct dmub_fb scratch_mem_fb; + volatile struct dmub_shared_state_feature_block *shared_state; volatile const struct dmub_fw_state *fw_state; /* private: internal use only */ diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 59b96136871e..a529e369b2ac 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -508,6 +508,8 @@ struct dmub_visual_confirm_color { * @trace_buffer_size: size of the tracebuffer region * @fw_version: the firmware version information * @dal_fw: 1 if the firmware is DAL + * @shared_state_size: size of the shared state region in bytes + * @shared_state_features: number of shared state features */ struct dmub_fw_meta_info { uint32_t magic_value; /**< magic value identifying DMUB firmware meta info */ @@ -516,6 +518,9 @@ struct dmub_fw_meta_info { uint32_t fw_version; /**< the firmware version information */ uint8_t dal_fw; /**< 1 if the firmware is DAL */ uint8_t reserved[3]; /**< padding bits */ + uint32_t shared_state_size; /**< size of the shared state region in bytes */ + uint16_t shared_state_features; /**< number of shared state features */ + uint16_t reserved2; /**< padding bytes */ }; /** @@ -660,6 +665,116 @@ enum dmub_fw_boot_options_bit { }; //============================================================================== +//< DMUB_SHARED_STATE>========================================================== +//============================================================================== + +/** + * Shared firmware state between driver and firmware for lockless communication + * in situations where the inbox/outbox may be unavailable. + * + * Each structure *must* be at most 256-bytes in size. The layout allocation is + * described below: + * + * [Header (256 Bytes)][Feature 1 (256 Bytes)][Feature 2 (256 Bytes)]... + */ + +/** + * enum dmub_shared_state_feature_id - List of shared state features. + */ +enum dmub_shared_state_feature_id { + DMUB_SHARED_SHARE_FEATURE__INVALID = 0, + DMUB_SHARED_SHARE_FEATURE__IPS_FW = 1, + DMUB_SHARED_SHARE_FEATURE__IPS_DRIVER = 2, + DMUB_SHARED_STATE_FEATURE__LAST, /* Total number of features. */ +}; + +/** + * struct dmub_shared_state_ips_fw - Firmware signals for IPS. + */ +union dmub_shared_state_ips_fw_signals { + struct { + uint32_t ips1_commit : 1; /**< 1 if in IPS1 */ + uint32_t ips2_commit : 1; /**< 1 if in IPS2 */ + uint32_t reserved_bits : 30; /**< Reversed */ + } bits; + uint32_t all; +}; + +/** + * struct dmub_shared_state_ips_signals - Firmware signals for IPS. + */ +union dmub_shared_state_ips_driver_signals { + struct { + uint32_t allow_pg : 1; /**< 1 if PG is allowed */ + uint32_t allow_ips1 : 1; /**< 1 is IPS1 is allowed */ + uint32_t allow_ips2 : 1; /**< 1 is IPS1 is allowed */ + uint32_t allow_z10 : 1; /**< 1 if Z10 is allowed */ + uint32_t reserved_bits : 28; /**< Reversed bits */ + } bits; + uint32_t all; +}; + +/** + * IPS FW Version + */ +#define DMUB_SHARED_STATE__IPS_FW_VERSION 1 + +/** + * struct dmub_shared_state_ips_fw - Firmware state for IPS. + */ +struct dmub_shared_state_ips_fw { + union dmub_shared_state_ips_fw_signals signals; /**< 4 bytes, IPS signal bits */ + uint32_t reserved[61]; /**< Reversed, to be updated when adding new fields. */ +}; /* 248-bytes, fixed */ + +/** + * IPS Driver Version + */ +#define DMUB_SHARED_STATE__IPS_DRIVER_VERSION 1 + +/** + * struct dmub_shared_state_ips_driver - Driver state for IPS. + */ +struct dmub_shared_state_ips_driver { + union dmub_shared_state_ips_driver_signals signals; /**< 4 bytes, IPS signal bits */ + uint32_t reserved[61]; /**< Reversed, to be updated when adding new fields. */ +}; /* 248-bytes, fixed */ + +/** + * enum dmub_shared_state_feature_common - Generic payload. + */ +struct dmub_shared_state_feature_common { + uint32_t padding[62]; +}; /* 248-bytes, fixed */ + +/** + * enum dmub_shared_state_feature_header - Feature description. + */ +struct dmub_shared_state_feature_header { + uint16_t id; /**< Feature ID */ + uint16_t version; /**< Feature version */ + uint32_t reserved; /**< Reserved bytes. */ +}; /* 8 bytes, fixed */ + +/** + * struct dmub_shared_state_feature_block - Feature block. + */ +struct dmub_shared_state_feature_block { + struct dmub_shared_state_feature_header header; /**< Shared state header. */ + union dmub_shared_feature_state_union { + struct dmub_shared_state_feature_common common; /**< Generic data */ + struct dmub_shared_state_ips_fw ips_fw; /**< IPS firmware state */ + struct dmub_shared_state_ips_driver ips_driver; /**< IPS driver state */ + } data; /**< Shared state data. */ +}; /* 256-bytes, fixed */ + +/** + * Shared state size in bytes. + */ +#define DMUB_FW_HEADER_SHARED_STATE_SIZE \ + ((DMUB_SHARED_STATE_FEATURE__LAST + 1) * sizeof(struct dmub_shared_state_feature_block)) + +//============================================================================== //</DMUB_STATUS>================================================================ //============================================================================== //< DMUB_VBIOS>================================================================= diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c index 98dad0d47e72..cae96fba6349 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c @@ -191,7 +191,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; uint64_t fb_base, fb_offset; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h index 1df128e57ed3..de287b101848 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h @@ -197,7 +197,8 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub, const struct dmub_region *inbox1); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c index 81dae75e9ff8..a4abe951c838 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.c @@ -124,7 +124,8 @@ void dmub_dcn30_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h index 9a3afffd9b0f..066f35a50094 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn30.h @@ -43,7 +43,8 @@ void dmub_dcn30_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); #endif /* _DMUB_DCN30_H_ */ diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c index 094e9f864557..2bcf5fb87dd9 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.c @@ -187,7 +187,8 @@ void dmub_dcn31_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h index 4d520a893c7b..eccdab4986ce 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn31.h @@ -199,7 +199,8 @@ void dmub_dcn31_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void dmub_dcn31_setup_mailbox(struct dmub_srv *dmub, const struct dmub_region *inbox1); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c index 305463b8f110..0d521eeda050 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.c @@ -216,7 +216,8 @@ void dmub_dcn32_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h index b0cd8d29402f..29c1132951af 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn32.h @@ -206,7 +206,8 @@ void dmub_dcn32_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void dmub_dcn32_setup_mailbox(struct dmub_srv *dmub, const struct dmub_region *inbox1); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c index 6d1fbea0f6ba..60223efc6fc8 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c @@ -229,7 +229,8 @@ void dmub_dcn35_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6) + const struct dmub_window *cw6, + const struct dmub_window *region6) { union dmub_addr offset; @@ -275,6 +276,15 @@ void dmub_dcn35_setup_windows(struct dmub_srv *dmub, REG_SET_2(DMCUB_REGION3_CW6_TOP_ADDRESS, 0, DMCUB_REGION3_CW6_TOP_ADDRESS, cw6->region.top, DMCUB_REGION3_CW6_ENABLE, 1); + + offset = region6->offset; + + REG_WRITE(DMCUB_REGION6_OFFSET, offset.u.low_part); + REG_WRITE(DMCUB_REGION6_OFFSET_HIGH, offset.u.high_part); + REG_SET_2(DMCUB_REGION6_TOP_ADDRESS, 0, + DMCUB_REGION6_TOP_ADDRESS, + region6->region.top - region6->region.base - 1, + DMCUB_REGION6_ENABLE, 1); } void dmub_dcn35_setup_mailbox(struct dmub_srv *dmub, diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h index 129a7031d2ae..686e97c00ccc 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.h @@ -89,6 +89,9 @@ struct dmub_srv; DMUB_SR(DMCUB_REGION5_OFFSET) \ DMUB_SR(DMCUB_REGION5_OFFSET_HIGH) \ DMUB_SR(DMCUB_REGION5_TOP_ADDRESS) \ + DMUB_SR(DMCUB_REGION6_OFFSET) \ + DMUB_SR(DMCUB_REGION6_OFFSET_HIGH) \ + DMUB_SR(DMCUB_REGION6_TOP_ADDRESS) \ DMUB_SR(DMCUB_SCRATCH0) \ DMUB_SR(DMCUB_SCRATCH1) \ DMUB_SR(DMCUB_SCRATCH2) \ @@ -154,6 +157,8 @@ struct dmub_srv; DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_ENABLE) \ DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_TOP_ADDRESS) \ DMUB_SF(DMCUB_REGION5_TOP_ADDRESS, DMCUB_REGION5_ENABLE) \ + DMUB_SF(DMCUB_REGION6_TOP_ADDRESS, DMCUB_REGION6_TOP_ADDRESS) \ + DMUB_SF(DMCUB_REGION6_TOP_ADDRESS, DMCUB_REGION6_ENABLE) \ DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) \ DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET) \ DMUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE) \ @@ -214,7 +219,8 @@ void dmub_dcn35_setup_windows(struct dmub_srv *dmub, const struct dmub_window *cw3, const struct dmub_window *cw4, const struct dmub_window *cw5, - const struct dmub_window *cw6); + const struct dmub_window *cw6, + const struct dmub_window *region6); void dmub_dcn35_setup_mailbox(struct dmub_srv *dmub, const struct dmub_region *inbox1); diff --git a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c index 569c2a27a042..fb66832dc996 100644 --- a/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c @@ -78,6 +78,7 @@ #define DMUB_CW6_BASE (0x66000000) #define DMUB_REGION5_BASE (0xA0000000) +#define DMUB_REGION6_BASE (0xC0000000) static struct dmub_srv_dcn32_regs dmub_srv_dcn32_regs; static struct dmub_srv_dcn35_regs dmub_srv_dcn35_regs; @@ -480,6 +481,7 @@ enum dmub_status window_sizes[DMUB_WINDOW_5_TRACEBUFF] = trace_buffer_size; window_sizes[DMUB_WINDOW_6_FW_STATE] = fw_state_size; window_sizes[DMUB_WINDOW_7_SCRATCH_MEM] = DMUB_SCRATCH_MEM_SIZE; + window_sizes[DMUB_WINDOW_SHARED_STATE] = DMUB_FW_HEADER_SHARED_STATE_SIZE; out->fb_size = dmub_srv_calc_regions_for_memory_type(params, out, window_sizes, DMUB_WINDOW_MEMORY_TYPE_FB); @@ -565,9 +567,10 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, struct dmub_fb *tracebuff_fb = params->fb[DMUB_WINDOW_5_TRACEBUFF]; struct dmub_fb *fw_state_fb = params->fb[DMUB_WINDOW_6_FW_STATE]; struct dmub_fb *scratch_mem_fb = params->fb[DMUB_WINDOW_7_SCRATCH_MEM]; + struct dmub_fb *shared_state_fb = params->fb[DMUB_WINDOW_SHARED_STATE]; struct dmub_rb_init_params rb_params, outbox0_rb_params; - struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5, cw6; + struct dmub_window cw0, cw1, cw2, cw3, cw4, cw5, cw6, region6; struct dmub_region inbox1, outbox1, outbox0; if (!dmub->sw_init) @@ -652,10 +655,16 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, dmub->fw_state = fw_state_fb->cpu_addr; + region6.offset.quad_part = shared_state_fb->gpu_addr; + region6.region.base = DMUB_CW6_BASE; + region6.region.top = region6.region.base + shared_state_fb->size; + + dmub->shared_state = shared_state_fb->cpu_addr; + dmub->scratch_mem_fb = *scratch_mem_fb; if (dmub->hw_funcs.setup_windows) - dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, &cw5, &cw6); + dmub->hw_funcs.setup_windows(dmub, &cw2, &cw3, &cw4, &cw5, &cw6, ®ion6); if (dmub->hw_funcs.setup_outbox0) dmub->hw_funcs.setup_outbox0(dmub, &outbox0); diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h index 1b8ab20f1715..92dbff22a7c6 100644 --- a/drivers/gpu/drm/amd/display/include/link_service_types.h +++ b/drivers/gpu/drm/amd/display/include/link_service_types.h @@ -169,6 +169,15 @@ enum dp_test_pattern { DP_TEST_PATTERN_UNSUPPORTED }; +#define IS_DP_PHY_SQUARE_PATTERN(test_pattern)\ + (DP_TEST_PATTERN_SQUARE_BEGIN <= test_pattern &&\ + test_pattern <= DP_TEST_PATTERN_SQUARE_END) + +#define IS_DP_PHY_PATTERN(test_pattern)\ + ((DP_TEST_PATTERN_PHY_PATTERN_BEGIN <= test_pattern &&\ + test_pattern <= DP_TEST_PATTERN_PHY_PATTERN_END) ||\ + test_pattern == DP_TEST_PATTERN_VIDEO_MODE) + enum dp_test_pattern_color_space { DP_TEST_PATTERN_COLOR_SPACE_RGB, DP_TEST_PATTERN_COLOR_SPACE_YCBCR601, |