diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm')
5 files changed, 129 insertions, 3 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 ae519f929c57..6fda0dfb78f8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -109,6 +109,10 @@ MODULE_FIRMWARE(FIRMWARE_VANGOGH_DMUB); MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH_DMUB); #define FIRMWARE_BEIGE_GOBY_DMUB "amdgpu/beige_goby_dmcub.bin" MODULE_FIRMWARE(FIRMWARE_BEIGE_GOBY_DMUB); +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) +#define FIRMWARE_YELLOW_CARP_DMUB "amdgpu/yellow_carp_dmcub.bin" +MODULE_FIRMWARE(FIRMWARE_YELLOW_CARP_DMUB); +#endif #define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin" MODULE_FIRMWARE(FIRMWARE_RAVEN_DMCU); @@ -1151,6 +1155,11 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) init_data.flags.gpu_vm_support = true; break; #endif +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + case CHIP_YELLOW_CARP: + init_data.flags.gpu_vm_support = true; + break; +#endif default: break; } @@ -1407,6 +1416,9 @@ static int load_dmcu_fw(struct amdgpu_device *adev) case CHIP_DIMGREY_CAVEFISH: case CHIP_BEIGE_GOBY: case CHIP_VANGOGH: +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + case CHIP_YELLOW_CARP: +#endif return 0; case CHIP_NAVI12: fw_name_dmcu = FIRMWARE_NAVI12_DMCU; @@ -1525,6 +1537,12 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) dmub_asic = DMUB_ASIC_DCN303; fw_name_dmub = FIRMWARE_BEIGE_GOBY_DMUB; break; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + case CHIP_YELLOW_CARP: + dmub_asic = DMUB_ASIC_DCN31; + fw_name_dmub = FIRMWARE_YELLOW_CARP_DMUB; + break; +#endif default: /* ASIC doesn't support DMUB. */ @@ -2219,6 +2237,15 @@ static int dm_resume(void *handle) = 0xffffffff; } } +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + /* + * Resource allocation happens for link encoders for newer ASIC in + * dc_validate_global_state, so we need to revalidate it. + * + * This shouldn't fail (it passed once before), so warn if it does. + */ + WARN_ON(dc_validate_global_state(dm->dc, dc_state, false) != DC_OK); +#endif WARN_ON(!dc_commit_state(dm->dc, dc_state)); @@ -3764,6 +3791,9 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) switch (adev->asic_type) { case CHIP_SIENNA_CICHLID: case CHIP_NAVY_FLOUNDER: +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + case CHIP_YELLOW_CARP: +#endif case CHIP_RENOIR: if (register_outbox_irq_handlers(dm->adev)) { DRM_ERROR("DM: Failed to initialize IRQ\n"); @@ -3868,6 +3898,9 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) case CHIP_DIMGREY_CAVEFISH: case CHIP_BEIGE_GOBY: case CHIP_VANGOGH: +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + case CHIP_YELLOW_CARP: +#endif if (dcn10_register_irq_handlers(dm->adev)) { DRM_ERROR("DM: Failed to initialize IRQ\n"); goto fail; @@ -4039,6 +4072,13 @@ static int dm_early_init(void *handle) adev->mode_info.num_hpd = 6; adev->mode_info.num_dig = 6; break; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + case CHIP_YELLOW_CARP: + adev->mode_info.num_crtc = 4; + adev->mode_info.num_hpd = 4; + adev->mode_info.num_dig = 4; + break; +#endif case CHIP_NAVI14: case CHIP_DIMGREY_CAVEFISH: adev->mode_info.num_crtc = 5; @@ -4276,6 +4316,9 @@ fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev, adev->asic_type == CHIP_NAVY_FLOUNDER || adev->asic_type == CHIP_DIMGREY_CAVEFISH || adev->asic_type == CHIP_BEIGE_GOBY || +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + adev->asic_type == CHIP_YELLOW_CARP || +#endif adev->asic_type == CHIP_VANGOGH) tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs; } @@ -4695,6 +4738,7 @@ get_plane_modifiers(const struct amdgpu_device *adev, unsigned int plane_type, u break; case AMDGPU_FAMILY_NV: case AMDGPU_FAMILY_VGH: + case AMDGPU_FAMILY_YC: if (adev->asic_type >= CHIP_SIENNA_CICHLID) add_gfx10_3_modifiers(adev, mods, &size, &capacity); else @@ -9633,7 +9677,8 @@ skip_modeset: BUG_ON(dm_new_crtc_state->stream == NULL); /* Scaling or underscan settings */ - if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state)) + if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state) || + drm_atomic_crtc_needs_modeset(new_crtc_state)) update_stream_scaling_settings( &new_crtc_state->mode, dm_new_conn_state, dm_new_crtc_state->stream); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 721c8b49730c..22730e554209 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -456,6 +456,7 @@ struct dsc_preferred_settings { uint32_t dsc_num_slices_v; uint32_t dsc_num_slices_h; uint32_t dsc_bits_per_pixel; + bool dsc_force_disable_passthrough; }; struct amdgpu_dm_connector { diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index 9fbbd0159119..f1145086a468 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -887,6 +887,47 @@ unlock: return res; } +/* + * Example usage: + * Disable dsc passthrough, i.e.,: have dsc decoding at converver, not external RX + * echo 1 /sys/kernel/debug/dri/0/DP-1/dsc_disable_passthrough + * Enable dsc passthrough, i.e.,: have dsc passthrough to external RX + * echo 0 /sys/kernel/debug/dri/0/DP-1/dsc_disable_passthrough + */ +static ssize_t dp_dsc_passthrough_set(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + struct amdgpu_dm_connector *aconnector = file_inode(f)->i_private; + char *wr_buf = NULL; + uint32_t wr_buf_size = 42; + int max_param_num = 1; + long param; + uint8_t param_nums = 0; + + if (size == 0) + return -EINVAL; + + wr_buf = kcalloc(wr_buf_size, sizeof(char), GFP_KERNEL); + + if (!wr_buf) { + DRM_DEBUG_DRIVER("no memory to allocate write buffer\n"); + return -ENOSPC; + } + + if (parse_write_buffer_into_params(wr_buf, size, + ¶m, buf, + max_param_num, + ¶m_nums)) { + kfree(wr_buf); + return -EINVAL; + } + + aconnector->dsc_settings.dsc_force_disable_passthrough = param; + + kfree(wr_buf); + return 0; +} + #ifdef CONFIG_DRM_AMD_DC_HDCP /* * Returns the HDCP capability of the Display (1.4 for now). @@ -2535,6 +2576,12 @@ static const struct file_operations dp_max_bpc_debugfs_fops = { .llseek = default_llseek }; +static const struct file_operations dp_dsc_disable_passthrough_debugfs_fops = { + .owner = THIS_MODULE, + .write = dp_dsc_passthrough_set, + .llseek = default_llseek +}; + static const struct { char *name; const struct file_operations *fops; @@ -2559,7 +2606,8 @@ static const struct { {"dsc_chunk_size", &dp_dsc_chunk_size_debugfs_fops}, {"dsc_slice_bpg", &dp_dsc_slice_bpg_offset_debugfs_fops}, {"dp_dsc_fec_support", &dp_dsc_fec_support_fops}, - {"max_bpc", &dp_max_bpc_debugfs_fops} + {"max_bpc", &dp_max_bpc_debugfs_fops}, + {"dsc_disable_passthrough", &dp_dsc_disable_passthrough_debugfs_fops}, }; #ifdef CONFIG_DRM_AMD_DC_HDCP diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index 666796a0067c..64c6ed50990d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -222,10 +222,23 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work, struct amdgpu_dm_connector *aconnector) { struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index]; + struct drm_connector_state *conn_state = aconnector->base.state; mutex_lock(&hdcp_w->mutex); hdcp_w->aconnector = aconnector; + /* the removal of display will invoke auth reset -> hdcp destroy and + * we'd expect the Content Protection (CP) property changed back to + * DESIRED if at the time ENABLED. CP property change should occur + * before the element removed from linked list. + */ + if (conn_state && conn_state->content_protection == DRM_MODE_CONTENT_PROTECTION_ENABLED) { + conn_state->content_protection = DRM_MODE_CONTENT_PROTECTION_DESIRED; + + DRM_DEBUG_DRIVER("[HDCP_DM] display %d, CP 2 -> 1, type %u, DPMS %u\n", + aconnector->base.index, conn_state->hdcp_content_type, aconnector->base.dpms); + } + mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output); process_output(hdcp_w); @@ -454,6 +467,13 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) display->dig_fe = config->dig_fe; link->dig_be = config->dig_be; link->ddc_line = aconnector->dc_link->ddc_hw_inst + 1; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + display->stream_enc_idx = config->stream_enc_idx; + link->link_enc_idx = config->link_enc_idx; + link->phy_idx = config->phy_idx; + link->hdcp_supported_informational = dc_link_is_hdcp14(aconnector->dc_link, + aconnector->dc_sink->sink_signal) ? 1 : 0; +#endif link->dp.rev = aconnector->dc_link->dpcd_caps.dpcd_rev.raw; link->dp.assr_enabled = config->assr_enabled; link->dp.mst_enabled = config->mst_enabled; @@ -462,7 +482,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config) link->adjust.hdcp1.disable = 0; conn_state = aconnector->base.state; - pr_debug("[HDCP_DM] display %d, CP %d, type %d\n", aconnector->base.index, + DRM_DEBUG_DRIVER("[HDCP_DM] display %d, CP %d, type %d\n", aconnector->base.index, (!!aconnector->base.state) ? aconnector->base.state->content_protection : -1, (!!aconnector->base.state) ? aconnector->base.state->hdcp_content_type : -1); @@ -637,6 +657,12 @@ struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, struct INIT_DELAYED_WORK(&hdcp_work[i].property_validate_dwork, event_property_validate); hdcp_work[i].hdcp.config.psp.handle = &adev->psp; +#if defined(CONFIG_DRM_AMD_DC_DCN3_1) + if (dc->ctx->dce_version == DCN_VERSION_3_1) { + hdcp_work[i].hdcp.config.psp.caps.dtm_v3_supported = 1; + hdcp_work[i].hdcp.config.psp.caps.opm_state_query_supported = false; + } +#endif hdcp_work[i].hdcp.config.ddc.handle = dc_get_link_at_index(dc, i); hdcp_work[i].hdcp.config.ddc.funcs.write_i2c = lp_write_i2c; hdcp_work[i].hdcp.config.ddc.funcs.read_i2c = lp_read_i2c; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 4646b0d02939..6fee12c91ef5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -655,6 +655,12 @@ void dm_set_dcn_clocks(struct dc_context *ctx, struct dc_clocks *clks) /* TODO: something */ } +void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigned int param, unsigned int timeout_us) +{ + // TODO: + //amdgpu_device_gpu_recover(dc_context->driver-context, NULL); +} + void *dm_helpers_allocate_gpu_mem( struct dc_context *ctx, enum dc_gpu_mem_alloc_type type, |
