aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
diff options
context:
space:
mode:
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.c335
1 files changed, 174 insertions, 161 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 075429bea427..9dd2e0601ea8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -48,7 +48,7 @@
#include "amdgpu_dm.h"
#ifdef CONFIG_DRM_AMD_DC_HDCP
#include "amdgpu_dm_hdcp.h"
-#include <drm/drm_hdcp.h>
+#include <drm/display/drm_hdcp_helper.h>
#endif
#include "amdgpu_pm.h"
#include "amdgpu_atombios.h"
@@ -73,17 +73,17 @@
#include <linux/firmware.h>
#include <linux/component.h>
+#include <drm/display/drm_dp_mst_helper.h>
+#include <drm/display/drm_hdmi_helper.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_atomic_helper.h>
-#include <drm/drm_dp_mst_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_edid.h>
#include <drm/drm_vblank.h>
#include <drm/drm_audio_component.h>
-#if defined(CONFIG_DRM_AMD_DC_DCN)
#include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
#include "dcn/dcn_1_0_offset.h"
@@ -92,7 +92,6 @@
#include "vega10_ip_offset.h"
#include "soc15_common.h"
-#endif
#include "modules/inc/mod_freesync.h"
#include "modules/power/power_helpers.h"
@@ -114,6 +113,10 @@ MODULE_FIRMWARE(FIRMWARE_DIMGREY_CAVEFISH_DMUB);
MODULE_FIRMWARE(FIRMWARE_BEIGE_GOBY_DMUB);
#define FIRMWARE_YELLOW_CARP_DMUB "amdgpu/yellow_carp_dmcub.bin"
MODULE_FIRMWARE(FIRMWARE_YELLOW_CARP_DMUB);
+#define FIRMWARE_DCN_315_DMUB "amdgpu/dcn_3_1_5_dmcub.bin"
+MODULE_FIRMWARE(FIRMWARE_DCN_315_DMUB);
+#define FIRMWARE_DCN316_DMUB "amdgpu/dcn_3_1_6_dmcub.bin"
+MODULE_FIRMWARE(FIRMWARE_DCN316_DMUB);
#define FIRMWARE_RAVEN_DMCU "amdgpu/raven_dmcu.bin"
MODULE_FIRMWARE(FIRMWARE_RAVEN_DMCU);
@@ -599,7 +602,6 @@ static void dm_crtc_high_irq(void *interrupt_params)
spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
/**
* dm_dcn_vertical_interrupt0_high_irq() - Handles OTG Vertical interrupt0 for
@@ -767,7 +769,7 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
do {
dc_stat_get_dmub_notification(adev->dm.dc, &notify);
- if (notify.type > ARRAY_SIZE(dm->dmub_thread_offload)) {
+ if (notify.type >= ARRAY_SIZE(dm->dmub_thread_offload)) {
DRM_ERROR("DM: notify type %d invalid!", notify.type);
continue;
}
@@ -823,7 +825,6 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params)
if (count > DMUB_TRACE_MAX_READ)
DRM_DEBUG_DRIVER("Warning : count > DMUB_TRACE_MAX_READ");
}
-#endif /* CONFIG_DRM_AMD_DC_DCN */
static int dm_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
@@ -1027,7 +1028,6 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
const unsigned char *fw_inst_const, *fw_bss_data;
uint32_t i, fw_inst_const_size, fw_bss_data_size;
bool has_hw_support;
- struct dc *dc = adev->dm.dc;
if (!dmub_srv)
/* DMUB isn't supported on the ASIC. */
@@ -1119,14 +1119,10 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
for (i = 0; i < fb_info->num_fb; ++i)
hw_params.fb[i] = &fb_info->fb[i];
- switch (adev->asic_type) {
- case CHIP_YELLOW_CARP:
- if (dc->ctx->asic_id.hw_internal_rev != YELLOW_CARP_A0) {
- hw_params.dpia_supported = true;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- hw_params.disable_dpia = dc->debug.dpia_debug.bits.disable_dpia;
-#endif
- }
+ switch (adev->ip_versions[DCE_HWIP][0]) {
+ case IP_VERSION(3, 1, 3): /* Only for this asic hw internal rev B0 */
+ hw_params.dpia_supported = true;
+ hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia;
break;
default:
break;
@@ -1188,7 +1184,6 @@ static void dm_dmub_hw_resume(struct amdgpu_device *adev)
}
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_addr_space_config *pa_config)
{
uint64_t pt_base;
@@ -1243,8 +1238,7 @@ static void mmhub_read_system_context(struct amdgpu_device *adev, struct dc_phy_
pa_config->is_hvm_enabled = 0;
}
-#endif
-#if defined(CONFIG_DRM_AMD_DC_DCN)
+
static void vblank_control_worker(struct work_struct *work)
{
struct vblank_control_work *vblank_work =
@@ -1281,8 +1275,6 @@ static void vblank_control_worker(struct work_struct *work)
kfree(vblank_work);
}
-#endif
-
static void dm_handle_hpd_rx_offload_work(struct work_struct *work)
{
struct hpd_rx_irq_offload_work *offload_work;
@@ -1409,9 +1401,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
mutex_init(&adev->dm.dc_lock);
mutex_init(&adev->dm.audio_lock);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
spin_lock_init(&adev->dm.vblank_lock);
-#endif
if(amdgpu_dm_irq_init(adev)) {
DRM_ERROR("amdgpu: failed to initialize DM IRQ support.\n");
@@ -1442,6 +1432,25 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
init_data.dce_environment = DCE_ENV_PRODUCTION_DRV;
+ switch (adev->ip_versions[DCE_HWIP][0]) {
+ case IP_VERSION(2, 1, 0):
+ switch (adev->dm.dmcub_fw_version) {
+ case 0: /* development */
+ case 0x1: /* linux-firmware.git hash 6d9f399 */
+ case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */
+ init_data.flags.disable_dmcu = false;
+ break;
+ default:
+ init_data.flags.disable_dmcu = true;
+ }
+ break;
+ case IP_VERSION(2, 0, 3):
+ init_data.flags.disable_dmcu = true;
+ break;
+ default:
+ break;
+ }
+
switch (adev->asic_type) {
case CHIP_CARRIZO:
case CHIP_STONEY:
@@ -1449,34 +1458,30 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
break;
default:
switch (adev->ip_versions[DCE_HWIP][0]) {
- case IP_VERSION(2, 1, 0):
- init_data.flags.gpu_vm_support = true;
- switch (adev->dm.dmcub_fw_version) {
- case 0: /* development */
- case 0x1: /* linux-firmware.git hash 6d9f399 */
- case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */
- init_data.flags.disable_dmcu = false;
- break;
- default:
- init_data.flags.disable_dmcu = true;
- }
- break;
case IP_VERSION(1, 0, 0):
case IP_VERSION(1, 0, 1):
+ /* enable S/G on PCO and RV2 */
+ if ((adev->apu_flags & AMD_APU_IS_RAVEN2) ||
+ (adev->apu_flags & AMD_APU_IS_PICASSO))
+ init_data.flags.gpu_vm_support = true;
+ break;
+ case IP_VERSION(2, 1, 0):
case IP_VERSION(3, 0, 1):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
init_data.flags.gpu_vm_support = true;
break;
- case IP_VERSION(2, 0, 3):
- init_data.flags.disable_dmcu = true;
- break;
default:
break;
}
break;
}
+ if (init_data.flags.gpu_vm_support)
+ adev->mode_info.gpu_vm_support = true;
+
if (amdgpu_dc_feature_mask & DC_FBC_MASK)
init_data.flags.fbc_support = true;
@@ -1489,17 +1494,15 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
if (amdgpu_dc_feature_mask & DC_EDP_NO_POWER_SEQUENCING)
init_data.flags.edp_no_power_sequencing = true;
-#ifdef CONFIG_DRM_AMD_DC_DCN
if (amdgpu_dc_feature_mask & DC_DISABLE_LTTPR_DP1_4A)
init_data.flags.allow_lttpr_non_transparent_mode.bits.DP1_4A = true;
if (amdgpu_dc_feature_mask & DC_DISABLE_LTTPR_DP2_0)
init_data.flags.allow_lttpr_non_transparent_mode.bits.DP2_0 = true;
-#endif
- init_data.flags.power_down_display_on_boot = true;
+ init_data.flags.seamless_boot_edp_requested = false;
if (check_seamless_boot_capability(adev)) {
- init_data.flags.power_down_display_on_boot = false;
+ init_data.flags.seamless_boot_edp_requested = true;
init_data.flags.allow_seamless_boot_optimization = true;
DRM_INFO("Seamless boot condition check passed\n");
}
@@ -1550,7 +1553,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
goto error;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if ((adev->flags & AMD_IS_APU) && (adev->asic_type >= CHIP_CARRIZO)) {
struct dc_phy_addr_space_config pa_config;
@@ -1559,7 +1561,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
// Call the DC init_memory func
dc_setup_system_context(adev->dm.dc, &pa_config);
}
-#endif
adev->dm.freesync_module = mod_freesync_create(adev->dm.dc);
if (!adev->dm.freesync_module) {
@@ -1571,14 +1572,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
amdgpu_dm_init_color_mod();
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (adev->dm.dc->caps.max_links > 0) {
adev->dm.vblank_control_workqueue =
create_singlethread_workqueue("dm_vblank_control_workqueue");
if (!adev->dm.vblank_control_workqueue)
DRM_ERROR("amdgpu: failed to initialize vblank_workqueue.\n");
}
-#endif
#ifdef CONFIG_DRM_AMD_DC_HDCP
if (adev->dm.dc->caps.max_links > 0 && adev->family >= AMDGPU_FAMILY_RV) {
@@ -1610,7 +1609,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
}
amdgpu_dm_outbox_init(adev);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (!register_dmub_notify_callback(adev, DMUB_NOTIFICATION_AUX_REPLY,
dmub_aux_setconfig_callback, false)) {
DRM_ERROR("amdgpu: fail to register dmub aux callback");
@@ -1624,7 +1622,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
DRM_ERROR("amdgpu: fail to register dmub hpd callback");
goto error;
}
-#endif /* CONFIG_DRM_AMD_DC_DCN */
}
if (amdgpu_dm_initialize_drm_device(adev)) {
@@ -1671,12 +1668,10 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev)
{
int i;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (adev->dm.vblank_control_workqueue) {
destroy_workqueue(adev->dm.vblank_control_workqueue);
adev->dm.vblank_control_workqueue = NULL;
}
-#endif
for (i = 0; i < adev->dm.display_indexes_num; i++) {
drm_encoder_cleanup(&adev->dm.mst_encoders[i].base);
@@ -1804,6 +1799,8 @@ static int load_dmcu_fw(struct amdgpu_device *adev)
case IP_VERSION(3, 0, 1):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
return 0;
default:
break;
@@ -1919,7 +1916,14 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev)
dmub_asic = (adev->external_rev_id == YELLOW_CARP_B0) ? DMUB_ASIC_DCN31B : DMUB_ASIC_DCN31;
fw_name_dmub = FIRMWARE_YELLOW_CARP_DMUB;
break;
-
+ case IP_VERSION(3, 1, 5):
+ dmub_asic = DMUB_ASIC_DCN315;
+ fw_name_dmub = FIRMWARE_DCN_315_DMUB;
+ break;
+ case IP_VERSION(3, 1, 6):
+ dmub_asic = DMUB_ASIC_DCN316;
+ fw_name_dmub = FIRMWARE_DCN316_DMUB;
+ break;
default:
/* ASIC doesn't support DMUB. */
return 0;
@@ -2179,12 +2183,8 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend)
static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
{
- struct smu_context *smu = &adev->smu;
int ret = 0;
- if (!is_support_sw_smu(adev))
- return 0;
-
/* This interface is for dGPU Navi1x.Linux dc-pplib interface depends
* on window driver dc implementation.
* For Navi1x, clock settings of dcn watermarks are fixed. the settings
@@ -2223,7 +2223,7 @@ static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev)
return 0;
}
- ret = smu_write_watermarks_table(smu);
+ ret = amdgpu_dpm_write_watermarks_table(adev);
if (ret) {
DRM_ERROR("Failed to update WMTABLE!\n");
return ret;
@@ -2382,9 +2382,7 @@ static int dm_suspend(void *handle)
if (amdgpu_in_reset(adev)) {
mutex_lock(&dm->dc_lock);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
dc_allow_idle_optimizations(adev->dm.dc, false);
-#endif
dm->cached_dc_state = dc_copy_state(dm->dc->current_state);
@@ -2413,7 +2411,7 @@ static int dm_suspend(void *handle)
return 0;
}
-static struct amdgpu_dm_connector *
+struct amdgpu_dm_connector *
amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
struct drm_crtc *crtc)
{
@@ -2613,10 +2611,13 @@ static int dm_resume(void *handle)
* before the 0 streams commit.
*
* DC expects that link encoder assignments are *not* valid
- * when committing a state, so as a workaround it needs to be
- * cleared here.
+ * when committing a state, so as a workaround we can copy
+ * off of the current state.
+ *
+ * We lose the previous assignments, but we had already
+ * commit 0 streams anyway.
*/
- link_enc_cfg_init(dm->dc, dc_state);
+ link_enc_cfg_copy(adev->dm.dc->current_state, dc_state);
if (dc_enable_dmub_notifications(adev->dm.dc))
amdgpu_dm_outbox_init(adev);
@@ -2690,7 +2691,8 @@ static int dm_resume(void *handle)
* this is the case when traversing through already created
* MST connectors, should be skipped
*/
- if (aconnector->mst_port)
+ if (aconnector->dc_link &&
+ aconnector->dc_link->type == dc_connection_mst_branch)
continue;
mutex_lock(&aconnector->hpd_lock);
@@ -2810,7 +2812,7 @@ static struct drm_mode_config_helper_funcs amdgpu_dm_mode_config_helperfuncs = {
static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
{
- u32 max_cll, min_cll, max, min, q, r;
+ u32 max_avg, min_cll, max, min, q, r;
struct amdgpu_dm_backlight_caps *caps;
struct amdgpu_display_manager *dm;
struct drm_connector *conn_base;
@@ -2840,7 +2842,7 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
caps = &dm->backlight_caps[i];
caps->ext_caps = &aconnector->dc_link->dpcd_sink_ext_caps;
caps->aux_support = false;
- max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll;
+ max_avg = conn_base->hdr_sink_metadata.hdmi_type1.max_fall;
min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll;
if (caps->ext_caps->bits.oled == 1 /*||
@@ -2868,8 +2870,8 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
* The results of the above expressions can be verified at
* pre_computed_values.
*/
- q = max_cll >> 5;
- r = max_cll % 32;
+ q = max_avg >> 5;
+ r = max_avg % 32;
max = (1 << q) * pre_computed_values[r];
// min luminance: maxLum * (CV/255)^2 / 100
@@ -3533,7 +3535,6 @@ static int dce110_register_irq_handlers(struct amdgpu_device *adev)
return 0;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* Register IRQ sources and initialize IRQ callbacks */
static int dcn10_register_irq_handlers(struct amdgpu_device *adev)
{
@@ -3722,7 +3723,6 @@ static int register_outbox_irq_handlers(struct amdgpu_device *adev)
return 0;
}
-#endif
/*
* Acquires the lock for the atomic state object and returns
@@ -3730,8 +3730,8 @@ static int register_outbox_irq_handlers(struct amdgpu_device *adev)
*
* This should only be called during atomic check.
*/
-static int dm_atomic_get_state(struct drm_atomic_state *state,
- struct dm_atomic_state **dm_state)
+int dm_atomic_get_state(struct drm_atomic_state *state,
+ struct dm_atomic_state **dm_state)
{
struct drm_device *dev = state->dev;
struct amdgpu_device *adev = drm_to_adev(dev);
@@ -3948,7 +3948,7 @@ static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *cap
max - min);
}
-static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
+static void amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
int bl_idx,
u32 user_brightness)
{
@@ -3979,7 +3979,8 @@ static int amdgpu_dm_backlight_set_level(struct amdgpu_display_manager *dm,
DRM_DEBUG("DM: Failed to update backlight on eDP[%d]\n", bl_idx);
}
- return rc ? 0 : 1;
+ if (rc)
+ dm->actual_brightness[bl_idx] = user_brightness;
}
static int amdgpu_dm_backlight_update_status(struct backlight_device *bd)
@@ -4225,12 +4226,13 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
goto fail;
}
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/* Use Outbox interrupt */
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(3, 0, 0):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
case IP_VERSION(2, 1, 0):
if (register_outbox_irq_handlers(dm->adev)) {
DRM_ERROR("DM: Failed to initialize IRQ\n");
@@ -4247,6 +4249,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
psr_feature_enabled = true;
break;
default:
@@ -4254,10 +4258,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
break;
}
}
-#endif
-
- /* Disable vblank IRQs aggressively for power-saving. */
- adev_to_drm(adev)->vblank_disable_immediate = true;
/* loops over all connectors on the board */
for (i = 0; i < link_cnt; i++) {
@@ -4350,7 +4350,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
}
break;
default:
-#if defined(CONFIG_DRM_AMD_DC_DCN)
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(1, 0, 0):
case IP_VERSION(1, 0, 1):
@@ -4364,6 +4363,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
case IP_VERSION(3, 0, 1):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
if (dcn10_register_irq_handlers(dm->adev)) {
DRM_ERROR("DM: Failed to initialize IRQ\n");
goto fail;
@@ -4374,7 +4375,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
adev->ip_versions[DCE_HWIP][0]);
goto fail;
}
-#endif
break;
}
@@ -4523,7 +4523,7 @@ static int dm_early_init(void *handle)
adev->mode_info.num_dig = 6;
break;
default:
-#if defined(CONFIG_DRM_AMD_DC_DCN)
+
switch (adev->ip_versions[DCE_HWIP][0]) {
case IP_VERSION(2, 0, 2):
case IP_VERSION(3, 0, 0):
@@ -4549,6 +4549,8 @@ static int dm_early_init(void *handle)
case IP_VERSION(2, 1, 0):
case IP_VERSION(3, 1, 2):
case IP_VERSION(3, 1, 3):
+ case IP_VERSION(3, 1, 5):
+ case IP_VERSION(3, 1, 6):
adev->mode_info.num_crtc = 4;
adev->mode_info.num_hpd = 4;
adev->mode_info.num_dig = 4;
@@ -4558,7 +4560,6 @@ static int dm_early_init(void *handle)
adev->ip_versions[DCE_HWIP][0]);
return -EINVAL;
}
-#endif
break;
}
@@ -5221,6 +5222,8 @@ get_plane_modifiers(const struct amdgpu_device *adev, unsigned int plane_type, u
case AMDGPU_FAMILY_NV:
case AMDGPU_FAMILY_VGH:
case AMDGPU_FAMILY_YC:
+ case AMDGPU_FAMILY_GC_10_3_6:
+ case AMDGPU_FAMILY_GC_10_3_7:
if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
add_gfx10_3_modifiers(adev, mods, &size, &capacity);
else
@@ -5375,17 +5378,19 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
static void
fill_blending_from_plane_state(const struct drm_plane_state *plane_state,
- bool *per_pixel_alpha, bool *global_alpha,
- int *global_alpha_value)
+ bool *per_pixel_alpha, bool *pre_multiplied_alpha,
+ bool *global_alpha, int *global_alpha_value)
{
*per_pixel_alpha = false;
+ *pre_multiplied_alpha = true;
*global_alpha = false;
*global_alpha_value = 0xff;
if (plane_state->plane->type != DRM_PLANE_TYPE_OVERLAY)
return;
- if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) {
+ if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI ||
+ plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) {
static const uint32_t alpha_formats[] = {
DRM_FORMAT_ARGB8888,
DRM_FORMAT_RGBA8888,
@@ -5400,6 +5405,9 @@ fill_blending_from_plane_state(const struct drm_plane_state *plane_state,
break;
}
}
+
+ if (per_pixel_alpha && plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE)
+ *pre_multiplied_alpha = false;
}
if (plane_state->alpha < 0xffff) {
@@ -5562,7 +5570,7 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
return ret;
fill_blending_from_plane_state(
- plane_state, &plane_info->per_pixel_alpha,
+ plane_state, &plane_info->per_pixel_alpha, &plane_info->pre_multiplied_alpha,
&plane_info->global_alpha, &plane_info->global_alpha_value);
return 0;
@@ -5609,6 +5617,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
dc_plane_state->tiling_info = plane_info.tiling_info;
dc_plane_state->visible = plane_info.visible;
dc_plane_state->per_pixel_alpha = plane_info.per_pixel_alpha;
+ dc_plane_state->pre_multiplied_alpha = plane_info.pre_multiplied_alpha;
dc_plane_state->global_alpha = plane_info.global_alpha;
dc_plane_state->global_alpha_value = plane_info.global_alpha_value;
dc_plane_state->dcc = plane_info.dcc;
@@ -5857,7 +5866,7 @@ static void fill_stream_properties_from_drm_display_mode(
else if (drm_mode_is_420_also(info, mode_in)
&& aconnector->force_yuv420_output)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
- else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444)
+ else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
else
@@ -6187,7 +6196,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
if (stream->link && stream->link->local_sink)
max_dsc_target_bpp_limit_override =
stream->link->local_sink->edid_caps.panel_patch.max_dsc_target_bpp_limit;
-
+
/* Set DSC policy according to dsc_clock_en */
dc_dsc_policy_set_enable_dsc_when_not_needed(
aconnector->dsc_settings.dsc_force_enable == DSC_CLK_FORCE_ENABLE);
@@ -6326,7 +6335,7 @@ get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector,
}
}
- aconnector->freesync_vid_base = *m_pref;
+ drm_mode_copy(&aconnector->freesync_vid_base, m_pref);
return m_pref;
}
@@ -6436,12 +6445,11 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
*/
DRM_DEBUG_DRIVER("No preferred mode found\n");
} else {
- recalculate_timing = amdgpu_freesync_vid_mode &&
- is_freesync_video_mode(&mode, aconnector);
+ recalculate_timing = is_freesync_video_mode(&mode, aconnector);
if (recalculate_timing) {
freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
- saved_mode = mode;
- mode = *freesync_mode;
+ drm_mode_copy(&saved_mode, &mode);
+ drm_mode_copy(&mode, freesync_mode);
} else {
decide_crtc_timing_for_drm_display_mode(
&mode, preferred_mode, scale);
@@ -6500,7 +6508,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
if (stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED)
stream->use_vsc_sdp_for_colorimetry = true;
}
- mod_build_vsc_infopacket(stream, &stream->vsc_infopacket);
+ mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space);
aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
}
@@ -6611,10 +6619,8 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
struct amdgpu_device *adev = drm_to_adev(crtc->dev);
struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
-#if defined(CONFIG_DRM_AMD_DC_DCN)
struct amdgpu_display_manager *dm = &adev->dm;
struct vblank_control_work *work;
-#endif
int rc = 0;
if (enable) {
@@ -6637,7 +6643,6 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
if (amdgpu_in_reset(adev))
return 0;
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dm->vblank_control_workqueue) {
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (!work)
@@ -6655,7 +6660,6 @@ static inline int dm_set_vblank(struct drm_crtc *crtc, bool enable)
queue_work(dm->vblank_control_workqueue, &work->work);
}
-#endif
return 0;
}
@@ -7011,7 +7015,7 @@ static void handle_edid_mgmt(struct amdgpu_dm_connector *aconnector)
create_eml_sink(aconnector);
}
-static struct dc_stream_state *
+struct dc_stream_state *
create_validate_stream_for_sink(struct amdgpu_dm_connector *aconnector,
const struct drm_display_mode *drm_mode,
const struct dm_connector_state *dm_state,
@@ -7548,9 +7552,6 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
struct amdgpu_device *adev;
struct amdgpu_bo *rbo;
struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
- struct list_head list;
- struct ttm_validate_buffer tv;
- struct ww_acquire_ctx ticket;
uint32_t domain;
int r;
@@ -7563,18 +7564,19 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
obj = new_state->fb->obj[0];
rbo = gem_to_amdgpu_bo(obj);
adev = amdgpu_ttm_adev(rbo->tbo.bdev);
- INIT_LIST_HEAD(&list);
-
- tv.bo = &rbo->tbo;
- tv.num_shared = 1;
- list_add(&tv.head, &list);
- r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
+ r = amdgpu_bo_reserve(rbo, true);
if (r) {
dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
return r;
}
+ r = dma_resv_reserve_fences(rbo->tbo.base.resv, 1);
+ if (r) {
+ dev_err(adev->dev, "reserving fence slot failed (%d)\n", r);
+ goto error_unlock;
+ }
+
if (plane->type != DRM_PLANE_TYPE_CURSOR)
domain = amdgpu_display_supported_domains(adev, rbo->flags);
else
@@ -7584,19 +7586,16 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
if (unlikely(r != 0)) {
if (r != -ERESTARTSYS)
DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
- ttm_eu_backoff_reservation(&ticket, &list);
- return r;
+ goto error_unlock;
}
r = amdgpu_ttm_alloc_gart(&rbo->tbo);
if (unlikely(r != 0)) {
- amdgpu_bo_unpin(rbo);
- ttm_eu_backoff_reservation(&ticket, &list);
DRM_ERROR("%p bind failed\n", rbo);
- return r;
+ goto error_unpin;
}
- ttm_eu_backoff_reservation(&ticket, &list);
+ amdgpu_bo_unreserve(rbo);
afb->address = amdgpu_bo_gpu_offset(rbo);
@@ -7628,6 +7627,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
}
return 0;
+
+error_unpin:
+ amdgpu_bo_unpin(rbo);
+
+error_unlock:
+ amdgpu_bo_unreserve(rbo);
+ return r;
}
static void dm_plane_helper_cleanup_fb(struct drm_plane *plane,
@@ -7895,6 +7901,9 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
if (res)
return res;
+ if (modifiers == NULL)
+ adev_to_drm(dm->adev)->mode_config.fb_modifiers_not_supported = true;
+
res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs,
&dm_plane_funcs, formats, num_formats,
modifiers, plane->type, NULL);
@@ -7905,7 +7914,8 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
if (plane->type == DRM_PLANE_TYPE_OVERLAY &&
plane_cap && plane_cap->per_pixel_alpha) {
unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
- BIT(DRM_MODE_BLEND_PREMULTI);
+ BIT(DRM_MODE_BLEND_PREMULTI) |
+ BIT(DRM_MODE_BLEND_COVERAGE);
drm_plane_create_alpha_property(plane);
drm_plane_create_blend_mode_property(plane, blend_caps);
@@ -8144,6 +8154,9 @@ static void amdgpu_dm_connector_add_common_modes(struct drm_encoder *encoder,
mode = amdgpu_dm_create_common_mode(encoder,
common_modes[i].name, common_modes[i].w,
common_modes[i].h);
+ if (!mode)
+ continue;
+
drm_mode_probed_add(connector, mode);
amdgpu_dm_connector->num_modes++;
}
@@ -8305,7 +8318,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect
struct amdgpu_dm_connector *amdgpu_dm_connector =
to_amdgpu_dm_connector(connector);
- if (!(amdgpu_freesync_vid_mode && edid))
+ if (!edid)
return;
if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
@@ -8372,7 +8385,7 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
break;
case DRM_MODE_CONNECTOR_DisplayPort:
aconnector->base.polled = DRM_CONNECTOR_POLL_HPD;
- link->link_enc = dp_get_link_enc(link);
+ link->link_enc = link_enc_cfg_get_link_enc(link);
ASSERT(link->link_enc);
if (link->link_enc)
aconnector->base.ycbcr_420_allowed =
@@ -9197,7 +9210,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
* deadlock during GPU reset when this fence will not signal
* but we hold reservation lock for the BO.
*/
- r = dma_resv_wait_timeout(abo->tbo.base.resv, true, false,
+ r = dma_resv_wait_timeout(abo->tbo.base.resv,
+ DMA_RESV_USAGE_WRITE, false,
msecs_to_jiffies(5000));
if (unlikely(r <= 0))
DRM_ERROR("Waiting for fences timed out!");
@@ -9209,7 +9223,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
&bundle->flip_addrs[planes_count].address,
afb->tmz_surface, false);
- DRM_DEBUG_ATOMIC("plane: id=%d dcc_en=%d\n",
+ drm_dbg_state(state->dev, "plane: id=%d dcc_en=%d\n",
new_plane_state->plane->index,
bundle->plane_infos[planes_count].dcc.enable);
@@ -9243,7 +9257,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
dc_plane,
bundle->flip_addrs[planes_count].flip_timestamp_in_us);
- DRM_DEBUG_ATOMIC("%s Flipping to hi: 0x%x, low: 0x%x\n",
+ drm_dbg_state(state->dev, "%s Flipping to hi: 0x%x, low: 0x%x\n",
__func__,
bundle->flip_addrs[planes_count].address.grph.addr.high_part,
bundle->flip_addrs[planes_count].address.grph.addr.low_part);
@@ -9324,14 +9338,12 @@ 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) &&
acrtc_state->stream) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
/*
* If PSR or idle optimizations are enabled then flush out
* any pending work before hardware programming.
*/
if (dm->vblank_control_workqueue)
flush_workqueue(dm->vblank_control_workqueue);
-#endif
bundle->stream_update.stream = acrtc_state->stream;
if (new_pcrtc_state->mode_changed) {
@@ -9585,7 +9597,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
- DRM_DEBUG_ATOMIC(
+ drm_dbg_state(state->dev,
"amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, "
"planes_changed:%d, mode_changed:%d,active_changed:%d,"
"connectors_changed:%d\n",
@@ -9664,21 +9676,19 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
if (dc_state) {
/* if there mode set or reset, disable eDP PSR */
if (mode_set_reset_required) {
-#if defined(CONFIG_DRM_AMD_DC_DCN)
if (dm->vblank_control_workqueue)
flush_workqueue(dm->vblank_control_workqueue);
-#endif
+
amdgpu_dm_psr_disable_all(dm);
}
dm_enable_per_frame_crtc_master_sync(dc_state);
mutex_lock(&dm->dc_lock);
WARN_ON(!dc_commit_state(dm->dc, dc_state));
-#if defined(CONFIG_DRM_AMD_DC_DCN)
- /* Allow idle optimization when vblank count is 0 for display off */
- if (dm->active_vblank_irq_count == 0)
- dc_allow_idle_optimizations(dm->dc,true);
-#endif
+
+ /* Allow idle optimization when vblank count is 0 for display off */
+ if (dm->active_vblank_irq_count == 0)
+ dc_allow_idle_optimizations(dm->dc, true);
mutex_unlock(&dm->dc_lock);
}
@@ -9908,7 +9918,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
/* restore the backlight level */
for (i = 0; i < dm->num_of_edps; i++) {
if (dm->backlight_dev[i] &&
- (amdgpu_dm_backlight_get_level(dm, i) != dm->brightness[i]))
+ (dm->actual_brightness[i] != dm->brightness[i]))
amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
}
#endif
@@ -10142,27 +10152,27 @@ static bool
is_timing_unchanged_for_freesync(struct drm_crtc_state *old_crtc_state,
struct drm_crtc_state *new_crtc_state)
{
- struct drm_display_mode old_mode, new_mode;
+ const struct drm_display_mode *old_mode, *new_mode;
if (!old_crtc_state || !new_crtc_state)
return false;
- old_mode = old_crtc_state->mode;
- new_mode = new_crtc_state->mode;
-
- if (old_mode.clock == new_mode.clock &&
- old_mode.hdisplay == new_mode.hdisplay &&
- old_mode.vdisplay == new_mode.vdisplay &&
- old_mode.htotal == new_mode.htotal &&
- old_mode.vtotal != new_mode.vtotal &&
- old_mode.hsync_start == new_mode.hsync_start &&
- old_mode.vsync_start != new_mode.vsync_start &&
- old_mode.hsync_end == new_mode.hsync_end &&
- old_mode.vsync_end != new_mode.vsync_end &&
- old_mode.hskew == new_mode.hskew &&
- old_mode.vscan == new_mode.vscan &&
- (old_mode.vsync_end - old_mode.vsync_start) ==
- (new_mode.vsync_end - new_mode.vsync_start))
+ old_mode = &old_crtc_state->mode;
+ new_mode = &new_crtc_state->mode;
+
+ if (old_mode->clock == new_mode->clock &&
+ old_mode->hdisplay == new_mode->hdisplay &&
+ old_mode->vdisplay == new_mode->vdisplay &&
+ old_mode->htotal == new_mode->htotal &&
+ old_mode->vtotal != new_mode->vtotal &&
+ old_mode->hsync_start == new_mode->hsync_start &&
+ old_mode->vsync_start != new_mode->vsync_start &&
+ old_mode->hsync_end == new_mode->hsync_end &&
+ old_mode->vsync_end != new_mode->vsync_end &&
+ old_mode->hskew == new_mode->hskew &&
+ old_mode->vscan == new_mode->vscan &&
+ (old_mode->vsync_end - old_mode->vsync_start) ==
+ (new_mode->vsync_end - new_mode->vsync_start))
return true;
return false;
@@ -10183,12 +10193,12 @@ static void set_freesync_fixed_config(struct dm_crtc_state *dm_new_crtc_state) {
}
static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
- struct drm_atomic_state *state,
- struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state,
- struct drm_crtc_state *new_crtc_state,
- bool enable,
- bool *lock_and_validation_needed)
+ struct drm_atomic_state *state,
+ struct drm_crtc *crtc,
+ struct drm_crtc_state *old_crtc_state,
+ struct drm_crtc_state *new_crtc_state,
+ bool enable,
+ bool *lock_and_validation_needed)
{
struct dm_atomic_state *dm_state = NULL;
struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
@@ -10272,8 +10282,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
* TODO: Refactor this function to allow this check to work
* in all conditions.
*/
- if (amdgpu_freesync_vid_mode &&
- dm_new_crtc_state->stream &&
+ if (dm_new_crtc_state->stream &&
is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state))
goto skip_modeset;
@@ -10290,7 +10299,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
goto skip_modeset;
- DRM_DEBUG_ATOMIC(
+ drm_dbg_state(state->dev,
"amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, "
"planes_changed:%d, mode_changed:%d,active_changed:%d,"
"connectors_changed:%d\n",
@@ -10308,7 +10317,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
if (!dm_old_crtc_state->stream)
goto skip_modeset;
- if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream &&
+ if (dm_new_crtc_state->stream &&
is_timing_unchanged_for_freesync(new_crtc_state,
old_crtc_state)) {
new_crtc_state->mode_changed = false;
@@ -10320,7 +10329,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
set_freesync_fixed_config(dm_new_crtc_state);
goto skip_modeset;
- } else if (amdgpu_freesync_vid_mode && aconnector &&
+ } else if (aconnector &&
is_freesync_video_mode(&new_crtc_state->mode,
aconnector)) {
struct drm_display_mode *high_mode;
@@ -10858,10 +10867,13 @@ static int dm_check_crtc_cursor(struct drm_atomic_state *state,
static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm_crtc *crtc)
{
struct drm_connector *connector;
- struct drm_connector_state *conn_state;
+ struct drm_connector_state *conn_state, *old_conn_state;
struct amdgpu_dm_connector *aconnector = NULL;
int i;
- for_each_new_connector_in_state(state, connector, conn_state, i) {
+ for_each_oldnew_connector_in_state(state, connector, old_conn_state, conn_state, i) {
+ if (!conn_state->crtc)
+ conn_state = old_conn_state;
+
if (conn_state->crtc != crtc)
continue;
@@ -10968,6 +10980,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
}
}
}
+ pre_validate_dsc(state, &dm_state, vars);
}
#endif
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {