diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 115 |
1 files changed, 90 insertions, 25 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 b16c658074d2..df08ea172595 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -67,7 +67,7 @@ #include <drm/drm_vblank.h> #if defined(CONFIG_DRM_AMD_DC_DCN1_0) -#include "ivsrcid/irqsrcs_dcn_1_0.h" +#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h" #include "dcn/dcn_1_0_offset.h" #include "dcn/dcn_1_0_sh_mask.h" @@ -560,6 +560,10 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) init_data.flags.power_down_display_on_boot = true; +#ifdef CONFIG_DRM_AMD_DC_DCN2_0 + init_data.soc_bounding_box = adev->dm.soc_bounding_box; +#endif + /* Display Core create. */ adev->dm.dc = dc_create(&init_data); @@ -665,6 +669,7 @@ static int load_dmcu_fw(struct amdgpu_device *adev) case CHIP_VEGA10: case CHIP_VEGA12: case CHIP_VEGA20: + case CHIP_NAVI10: return 0; case CHIP_RAVEN: if (ASICREV_IS_PICASSO(adev->external_rev_id)) @@ -779,7 +784,7 @@ static int dm_late_init(void *handle) unsigned int linear_lut[16]; int i; struct dmcu *dmcu = adev->dm.dc->res_pool->dmcu; - bool ret; + bool ret = false; for (i = 0; i < 16; i++) linear_lut[i] = 0xFFFF * i / 15; @@ -790,10 +795,13 @@ static int dm_late_init(void *handle) params.backlight_lut_array_size = 16; params.backlight_lut_array = linear_lut; - ret = dmcu_load_iram(dmcu, params); + /* todo will enable for navi10 */ + if (adev->asic_type <= CHIP_RAVEN) { + ret = dmcu_load_iram(dmcu, params); - if (!ret) - return -EINVAL; + if (!ret) + return -EINVAL; + } return detect_mst_link_for_all_connectors(adev->ddev); } @@ -2209,6 +2217,9 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) break; #if defined(CONFIG_DRM_AMD_DC_DCN1_0) case CHIP_RAVEN: +#if defined(CONFIG_DRM_AMD_DC_DCN2_0) + case CHIP_NAVI10: +#endif if (dcn10_register_irq_handlers(dm->adev)) { DRM_ERROR("DM: Failed to initialize IRQ\n"); goto fail; @@ -2362,6 +2373,13 @@ static int dm_early_init(void *handle) adev->mode_info.num_dig = 4; break; #endif +#if defined(CONFIG_DRM_AMD_DC_DCN2_0) + case CHIP_NAVI10: + adev->mode_info.num_crtc = 6; + adev->mode_info.num_hpd = 6; + adev->mode_info.num_dig = 6; + break; +#endif default: DRM_ERROR("Unsupported ASIC type: 0x%X\n", adev->asic_type); return -EINVAL; @@ -2654,6 +2672,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, if (adev->asic_type == CHIP_VEGA10 || adev->asic_type == CHIP_VEGA12 || adev->asic_type == CHIP_VEGA20 || +#if defined(CONFIG_DRM_AMD_DC_DCN2_0) + adev->asic_type == CHIP_NAVI10 || +#endif adev->asic_type == CHIP_RAVEN) { /* Fill GFX9 params */ tiling_info->gfx9.num_pipes = @@ -2859,6 +2880,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, struct drm_plane_state *plane_state, struct drm_crtc_state *crtc_state) { + struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state); const struct amdgpu_framebuffer *amdgpu_fb = to_amdgpu_framebuffer(plane_state->fb); struct dc_scaling_info scaling_info; @@ -2903,13 +2925,11 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, * Always set input transfer function, since plane state is refreshed * every time. */ - ret = amdgpu_dm_set_degamma_lut(crtc_state, dc_plane_state); - if (ret) { - dc_transfer_func_release(dc_plane_state->in_transfer_func); - dc_plane_state->in_transfer_func = NULL; - } + ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, dc_plane_state); + if (ret) + return ret; - return ret; + return 0; } static void update_stream_scaling_settings(const struct drm_display_mode *mode, @@ -2973,6 +2993,9 @@ convert_color_depth_from_display_info(const struct drm_connector *connector, { uint32_t bpc = connector->display_info.bpc; + if (!state) + state = connector->state; + if (state) { bpc = state->max_bpc; /* Round down to the nearest even number. */ @@ -3399,6 +3422,20 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector, fill_stream_properties_from_drm_display_mode(stream, &mode, &aconnector->base, con_state, old_stream); +#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT + /* stream->timing.flags.DSC = 0; */ + /* */ + /* if (aconnector->dc_link && */ + /* aconnector->dc_link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT #<{(|&& */ + /* aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.is_dsc_supported|)}>#) */ + /* if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc, */ + /* &aconnector->dc_link->dpcd_caps.dsc_caps, */ + /* dc_link_bandwidth_kbps(aconnector->dc_link, dc_link_get_link_cap(aconnector->dc_link)), */ + /* &stream->timing, */ + /* &stream->timing.dsc_cfg)) */ + /* stream->timing.flags.DSC = 1; */ +#endif + update_stream_scaling_settings(&mode, dm_state, stream); fill_audio_info( @@ -3481,6 +3518,8 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc) state->vrr_supported = cur->vrr_supported; state->freesync_config = cur->freesync_config; state->crc_enabled = cur->crc_enabled; + state->cm_has_degamma = cur->cm_has_degamma; + state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb; /* TODO Duplicate dc_stream after objects are stream object is flattened */ @@ -3735,6 +3774,10 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector) state->underscan_enable = false; state->underscan_hborder = 0; state->underscan_vborder = 0; + state->base.max_requested_bpc = 8; + + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) + state->abm_level = amdgpu_dm_abm_level; __drm_atomic_helper_connector_reset(connector, &state->base); } @@ -4780,6 +4823,13 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm, { struct amdgpu_device *adev = dm->ddev->dev_private; + /* + * Some of the properties below require access to state, like bpc. + * Allocate some default initial connector state with our reset helper. + */ + if (aconnector->base.funcs->reset) + aconnector->base.funcs->reset(&aconnector->base); + aconnector->connector_id = link_index; aconnector->dc_link = link; aconnector->base.interlace_allowed = false; @@ -4969,9 +5019,6 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, &aconnector->base, &amdgpu_dm_connector_helper_funcs); - if (aconnector->base.funcs->reset) - aconnector->base.funcs->reset(&aconnector->base); - amdgpu_dm_connector_init_helper( dm, aconnector, @@ -4984,11 +5031,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm, drm_connector_register(&aconnector->base); #if defined(CONFIG_DEBUG_FS) - res = connector_debugfs_init(aconnector); - if (res) { - DRM_ERROR("Failed to create debugfs for connector"); - goto out_free; - } + connector_debugfs_init(aconnector); aconnector->debugfs_dpcd_address = 0; aconnector->debugfs_dpcd_size = 0; #endif @@ -5628,14 +5671,25 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, } /* Update the planes if changed or disable if we don't have any. */ - if (planes_count || acrtc_state->active_planes == 0) { + if ((planes_count || acrtc_state->active_planes == 0) && + acrtc_state->stream) { if (new_pcrtc_state->mode_changed) { bundle->stream_update.src = acrtc_state->stream->src; bundle->stream_update.dst = acrtc_state->stream->dst; } - if (new_pcrtc_state->color_mgmt_changed) - bundle->stream_update.out_transfer_func = acrtc_state->stream->out_transfer_func; + if (new_pcrtc_state->color_mgmt_changed) { + /* + * TODO: This isn't fully correct since we've actually + * already modified the stream in place. + */ + bundle->stream_update.gamut_remap = + &acrtc_state->stream->gamut_remap_matrix; + bundle->stream_update.output_csc_transform = + &acrtc_state->stream->csc_color_matrix; + bundle->stream_update.out_transfer_func = + acrtc_state->stream->out_transfer_func; + } acrtc_state->stream->abm_level = acrtc_state->abm_level; if (acrtc_state->abm_level != dm_old_crtc_state->abm_level) @@ -6346,7 +6400,17 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, if (ret) goto fail; - if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && + /* + * If we already removed the old stream from the context + * (and set the new stream to NULL) then we can't reuse + * the old stream even if the stream and scaling are unchanged. + * We'll hit the BUG_ON and black screen. + * + * TODO: Refactor this function to allow this check to work + * in all conditions. + */ + if (dm_new_crtc_state->stream && + dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) { new_crtc_state->mode_changed = false; DRM_DEBUG_DRIVER("Mode change not required, setting mode_changed to %d", @@ -6475,10 +6539,9 @@ skip_modeset: */ if (dm_new_crtc_state->base.color_mgmt_changed || drm_atomic_crtc_needs_modeset(new_crtc_state)) { - ret = amdgpu_dm_set_regamma_lut(dm_new_crtc_state); + ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state); if (ret) goto fail; - amdgpu_dm_set_ctm(dm_new_crtc_state); } /* Update Freesync settings. */ @@ -6781,6 +6844,8 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, new_dm_plane_state->dc_state->in_transfer_func; stream_update.gamut_remap = &new_dm_crtc_state->stream->gamut_remap_matrix; + stream_update.output_csc_transform = + &new_dm_crtc_state->stream->csc_color_matrix; stream_update.out_transfer_func = new_dm_crtc_state->stream->out_transfer_func; } |
