[PATCH] drm/amd/display: enable/disable PSR feature at run time
[Why] Per current architecture, PSR feature is disabled by default for DCN < 3. This makes it impossible for those pre-flashed device users to try newer (psr capable) panels without altering OS (boot params). Also on Chromebooks its not sustainable to have custom dc_feature_mask. [How] amdgpu_dm_set_psr_caps() in its current form does a decent job to evaluate and discard links that are not capable of PSR feature. If the current implementation has gap, going forward it needs to be addressed either by adding appropriate ways to detect and discard the panels or by iteratively blacklisting the same. Signed-off-by: Shirish S --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 ++- 1 file changed, 2 insertions(+), 21 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 073bf00c6fdc..0fcafe1a071d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4313,7 +4313,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) s32 primary_planes; enum dc_connection_type new_connection_type = dc_connection_none; const struct dc_plane_cap *plane; - bool psr_feature_enabled = false; int max_overlay = dm->dc->caps.max_slave_planes; dm->display_indexes_num = dm->dc->caps.max_streams; @@ -4405,24 +4404,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) adev->ip_versions[DCE_HWIP][0]); } - /* Determine whether to enable PSR support by default. */ - if (!(amdgpu_dc_debug_mask & DC_DISABLE_PSR)) { - switch (adev->ip_versions[DCE_HWIP][0]) { - case IP_VERSION(3, 1, 2): - case IP_VERSION(3, 1, 3): - case IP_VERSION(3, 1, 4): - case IP_VERSION(3, 1, 5): - case IP_VERSION(3, 1, 6): - case IP_VERSION(3, 2, 0): - case IP_VERSION(3, 2, 1): - psr_feature_enabled = true; - break; - default: - psr_feature_enabled = amdgpu_dc_feature_mask & DC_PSR_MASK; - break; - } - } - /* loops over all connectors on the board */ for (i = 0; i < link_cnt; i++) { struct dc_link *link = NULL; @@ -4471,8 +4452,8 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) amdgpu_dm_update_connector_after_detect(aconnector); setup_backlight_device(dm, aconnector); - if (psr_feature_enabled) - amdgpu_dm_set_psr_caps(link); + /* Determine & Set PSR caps*/ + amdgpu_dm_set_psr_caps(link); /* TODO: Fix vblank control helpers to delay PSR entry to allow this when * PSR is also supported. -- 2.17.1
[PATCH] amd/display/debugfs: add sysfs entry to read PSR residency from firmware
[Why] Currently there aren't any methods to determine PSR state residency. [How] create a sysfs entry for reading residency and internally hook it up to existing functionality of reading PSR residency from firmware. Signed-off-by: Shirish S --- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 19 +++ 1 file changed, 19 insertions(+) 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 abf7895d1608..d8a5cde2b06f 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 @@ -35,6 +35,7 @@ #include "resource.h" #include "dsc.h" #include "link_hwss.h" +#include "link.h" #include "dc/dc_dmub_srv.h" #include "link/protocols/link_dp_capability.h" @@ -2793,6 +2794,22 @@ static int psr_get(void *data, u64 *val) return 0; } +/* + * Read PSR state residency + */ +static int psr_read_residency(void *data, u64 *val) +{ + struct amdgpu_dm_connector *connector = data; + struct dc_link *link = connector->dc_link; + u32 residency; + + link_get_psr_residency(link, ); + + *val = (u64)residency; + + return 0; +} + /* * Set dmcub trace event IRQ enable or disable. * Usage to enable dmcub trace event IRQ: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en @@ -2828,6 +2845,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(dmcub_trace_event_state_fops, dmcub_trace_event_state_g dmcub_trace_event_state_set, "%llu\n"); DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(psr_residency_fops, psr_read_residency, NULL, "%llu\n"); DEFINE_SHOW_ATTRIBUTE(current_backlight); DEFINE_SHOW_ATTRIBUTE(target_backlight); @@ -2991,6 +3009,7 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, _capability_fops); debugfs_create_file_unsafe("psr_state", 0444, dir, connector, _fops); + debugfs_create_file_unsafe("psr_residency", 0444, dir, connector, _residency_fops); debugfs_create_file("amdgpu_current_backlight_pwm", 0444, dir, connector, _backlight_fops); debugfs_create_file("amdgpu_target_backlight_pwm", 0444, dir, connector, -- 2.17.1
[PATCH] amd/display/debugfs: add sysfs entry to read PSR residency from firmware
[Why] Currently there aren't any methods to determine PSR state residency. [How] create a sysfs entry for reading residency and internally hook it up to existing functionality of reading PSR residency from firmware. Signed-off-by: Shirish S --- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 18 ++ 1 file changed, 18 insertions(+) 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 abf7895d1608..6dfd4cb42949 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 @@ -2793,6 +2793,22 @@ static int psr_get(void *data, u64 *val) return 0; } +/* + * Read PSR state residency + */ +static int psr_read_residency(void *data, u64 *val) +{ + struct amdgpu_dm_connector *connector = data; + struct dc_link *link = connector->dc_link; + u32 residency; + + dc_link_get_psr_residency(link, ); + + *val = (u64)residency; + + return 0; +} + /* * Set dmcub trace event IRQ enable or disable. * Usage to enable dmcub trace event IRQ: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en @@ -2828,6 +2844,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(dmcub_trace_event_state_fops, dmcub_trace_event_state_g dmcub_trace_event_state_set, "%llu\n"); DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(psr_residency_fops, psr_read_residency, NULL, "%llu\n"); DEFINE_SHOW_ATTRIBUTE(current_backlight); DEFINE_SHOW_ATTRIBUTE(target_backlight); @@ -2991,6 +3008,7 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, _capability_fops); debugfs_create_file_unsafe("psr_state", 0444, dir, connector, _fops); + debugfs_create_file_unsafe("psr_residency", 0444, dir, connector, _residency_fops); debugfs_create_file("amdgpu_current_backlight_pwm", 0444, dir, connector, _backlight_fops); debugfs_create_file("amdgpu_target_backlight_pwm", 0444, dir, connector, -- 2.17.1
[PATCH] amd/display/debugfs: add sysfs entry to read PSR residency from firmware
[Why] Currently there aren't any methods to determine PSR state residency. [How] create a sysfs entry for reading residency and internally hook it up to existing functionality of reading PSR residency from firmware. Signed-off-by: Shirish S --- .../amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 19 +++ 1 file changed, 19 insertions(+) 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 abf7895d1608..8ff2802db5b5 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 @@ -27,6 +27,7 @@ #include #include "dc.h" +#include "dc_link.h" #include "amdgpu.h" #include "amdgpu_dm.h" #include "amdgpu_dm_debugfs.h" @@ -2793,6 +2794,22 @@ static int psr_get(void *data, u64 *val) return 0; } +/* + * Read PSR state residency + */ +static int psr_read_residency(void *data, u64 *val) +{ + struct amdgpu_dm_connector *connector = data; + struct dc_link *link = connector->dc_link; + u32 residency; + + dc_link_get_psr_residency(link, ); + + *val = (u64)residency; + + return 0; +} + /* * Set dmcub trace event IRQ enable or disable. * Usage to enable dmcub trace event IRQ: echo 1 > /sys/kernel/debug/dri/0/amdgpu_dm_dmcub_trace_event_en @@ -2828,6 +2845,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(dmcub_trace_event_state_fops, dmcub_trace_event_state_g dmcub_trace_event_state_set, "%llu\n"); DEFINE_DEBUGFS_ATTRIBUTE(psr_fops, psr_get, NULL, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(psr_residency_fops, psr_read_residency, NULL, "%llu\n"); DEFINE_SHOW_ATTRIBUTE(current_backlight); DEFINE_SHOW_ATTRIBUTE(target_backlight); @@ -2991,6 +3009,7 @@ void connector_debugfs_init(struct amdgpu_dm_connector *connector) if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) { debugfs_create_file_unsafe("psr_capability", 0444, dir, connector, _capability_fops); debugfs_create_file_unsafe("psr_state", 0444, dir, connector, _fops); + debugfs_create_file_unsafe("psr_residency", 0444, dir, connector, _residency_fops); debugfs_create_file("amdgpu_current_backlight_pwm", 0444, dir, connector, _backlight_fops); debugfs_create_file("amdgpu_target_backlight_pwm", 0444, dir, connector, -- 2.17.1
[PATCH] drm/amd/display: explicitly disable psr_feature_enable appropriately
[Why] If psr_feature_enable is set to true by default, it continues to be enabled for non capable links. [How] explicitly disable the feature on links that are not capable of the same. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c index 8ca10ab3dfc1..26291db0a3cf 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c @@ -60,11 +60,15 @@ static bool link_supports_psrsu(struct dc_link *link) */ void amdgpu_dm_set_psr_caps(struct dc_link *link) { - if (!(link->connector_signal & SIGNAL_TYPE_EDP)) + if (!(link->connector_signal & SIGNAL_TYPE_EDP)) { + link->psr_settings.psr_feature_enabled = false; return; + } - if (link->type == dc_connection_none) + if (link->type == dc_connection_none) { + link->psr_settings.psr_feature_enabled = false; return; + } if (link->dpcd_caps.psr_info.psr_version == 0) { link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; -- 2.17.1
[PATCH] drm/amd/display: disable psr whenever applicable
[Why] psr feature continues to be enabled for non capable links. [How] disable the feature on links that are not capable of the same. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c index 8ca10ab3dfc1..f73af028f312 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c @@ -60,11 +60,17 @@ static bool link_supports_psrsu(struct dc_link *link) */ void amdgpu_dm_set_psr_caps(struct dc_link *link) { - if (!(link->connector_signal & SIGNAL_TYPE_EDP)) + if (!(link->connector_signal & SIGNAL_TYPE_EDP)) { + DRM_ERROR("Disabling PSR as connector is not eDP\n") + link->psr_settings.psr_feature_enabled = false; return; + } - if (link->type == dc_connection_none) + if (link->type == dc_connection_none) { + DRM_ERROR("Disabling PSR as eDP connection type is invalid\n") + link->psr_settings.psr_feature_enabled = false; return; + } if (link->dpcd_caps.psr_info.psr_version == 0) { link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; -- 2.17.1
[PATCH] amd/display: set backlight only if required
[Why] comparing pwm bl values (coverted) with user brightness(converted) levels in commit_tail leads to continuous setting of backlight via dmub as they don't to match. This leads overdrive in queuing of commands to DMCU that sometimes lead to depending on load on DMCU fw: "[drm:dc_dmub_srv_wait_idle] *ERROR* Error waiting for DMUB idle: status=3" [How] Store last successfully set backlight value and compare with it instead of pwm reads which is not what we should compare with. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 6 ++ 2 files changed, 10 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 df0980ff9a63..2b8337e47861 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3972,7 +3972,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) { @@ -4003,7 +4003,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) @@ -9944,7 +9945,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 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 372f9adf091a..321279bc877b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -540,6 +540,12 @@ struct amdgpu_display_manager { * cached backlight values. */ u32 brightness[AMDGPU_DM_MAX_NUM_EDP]; + /** +* @actual_brightness: +* +* last successfully applied backlight values. +*/ + u32 actual_brightness[AMDGPU_DM_MAX_NUM_EDP]; }; enum dsc_clock_force_state { -- 2.17.1
[PATCH] amd/display: set backlight only if required
[Why] comparing pwm bl values (coverted) with user brightness(converted) levels in commit_tail leads to continuous setting of backlight via dmub as they don't to match. This leads overdrive in queuing of commands to DMCU that sometimes lead to depending on load on DMCU fw: "[drm:dc_dmub_srv_wait_idle] *ERROR* Error waiting for DMUB idle: status=3" Here status 3 => DMUB_STATUS_QUEUE_FULL [How] Store last successfully set backlight value and compare with it instead of pwm reads which is not what we should compare with. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 6 ++ 2 files changed, 10 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 df0980ff9a63..2b8337e47861 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3972,7 +3972,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) { @@ -4003,7 +4003,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) @@ -9944,7 +9945,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 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 372f9adf091a..321279bc877b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -540,6 +540,12 @@ struct amdgpu_display_manager { * cached backlight values. */ u32 brightness[AMDGPU_DM_MAX_NUM_EDP]; + /** +* @actual_brightness: +* +* last successfully applied backlight values. +*/ + u32 actual_brightness[AMDGPU_DM_MAX_NUM_EDP]; }; enum dsc_clock_force_state { -- 2.17.1
[PATCH] drm/amd/display: log amdgpu_dm_atomic_check() failure cause
update developers with next level of info about unsupported display configuration query that led to atomic check failure. Signed-off-by: Shirish S --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 69 ++- 1 file changed, 51 insertions(+), 18 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 b1d9e89e5ae9..b7044c04a7c5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10755,8 +10755,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, trace_amdgpu_dm_atomic_check_begin(state); ret = drm_atomic_helper_check_modeset(dev, state); - if (ret) + if (ret) { + DRM_DEBUG_DRIVER("drm_atomic_helper_check_modeset() failed\n"); goto fail; + } /* Check connector changes */ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { @@ -10772,6 +10774,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc); if (IS_ERR(new_crtc_state)) { + DRM_DEBUG_DRIVER("drm_atomic_get_crtc_state() failed\n"); ret = PTR_ERR(new_crtc_state); goto fail; } @@ -10786,8 +10789,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { ret = add_affected_mst_dsc_crtcs(state, crtc); - if (ret) + if (ret) { + DRM_DEBUG_DRIVER("add_affected_mst_dsc_crtcs() failed\n"); goto fail; + } } } } @@ -10802,19 +10807,25 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, continue; ret = amdgpu_dm_verify_lut_sizes(new_crtc_state); - if (ret) + if (ret) { + DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n"); goto fail; + } if (!new_crtc_state->enable) continue; ret = drm_atomic_add_affected_connectors(state, crtc); - if (ret) + if (ret) { + DRM_DEBUG_DRIVER("drm_atomic_add_affected_connectors() failed\n"); goto fail; + } ret = drm_atomic_add_affected_planes(state, crtc); - if (ret) + if (ret) { + DRM_DEBUG_DRIVER("drm_atomic_add_affected_planes() failed\n"); goto fail; + } if (dm_old_crtc_state->dsc_force_changed) new_crtc_state->mode_changed = true; @@ -10851,6 +10862,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, if (IS_ERR(new_plane_state)) { ret = PTR_ERR(new_plane_state); + DRM_DEBUG_DRIVER("new_plane_state is BAD\n"); goto fail; } } @@ -10863,8 +10875,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_plane_state, false, _and_validation_needed); - if (ret) + if (ret) { + DRM_DEBUG_DRIVER("dm_update_plane_state() failed\n"); goto fail; + } } /* Disable all crtcs which require disable */ @@ -10874,8 +10888,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state, false, _and_validation_needed); - if (ret) + if (ret) { + DRM_DEBUG_DRIVER("DISABLE: dm_update_crtc_state() failed\n"); goto fail; + } } /* Enable all crtcs which require enable */ @@ -10885,8 +10901,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state, true, _and_validation_needed); - if (
[PATCH] drm/amd/display: reject both non-zero src_x and src_y only for DCN1x
[Why] Video plane gets rejected for non-zero src_y and src_x on DCN2.x. [How] Limit the rejection till DCN1.x and verified MPO, by dragging video playback beyond display's left (0, 0) co-ordinates. Fixes: d89f6048bdcb ("drm/amd/display: Reject non-zero src_y and src_x for video planes") Signed-off-by: Shirish S Reviewed-by: Harry Wentland --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 ++- 1 file changed, 11 insertions(+), 9 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 7a54ccb794f9..00b3ef41b752 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4581,7 +4581,8 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev, } -static int fill_dc_scaling_info(const struct drm_plane_state *state, +static int fill_dc_scaling_info(struct amdgpu_device *adev, + const struct drm_plane_state *state, struct dc_scaling_info *scaling_info) { int scale_w, scale_h, min_downscale, max_upscale; @@ -4595,7 +4596,8 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, /* * For reasons we don't (yet) fully understand a non-zero * src_y coordinate into an NV12 buffer can cause a -* system hang. To avoid hangs (and maybe be overly cautious) +* system hang on DCN1x. +* To avoid hangs (and maybe be overly cautious) * let's reject both non-zero src_x and src_y. * * We currently know of only one use-case to reproduce a @@ -4603,10 +4605,10 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, * is to gesture the YouTube Android app into full screen * on ChromeOS. */ - if (state->fb && - state->fb->format->format == DRM_FORMAT_NV12 && - (scaling_info->src_rect.x != 0 || -scaling_info->src_rect.y != 0)) + if (((adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 0)) || + (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 1))) && + (state->fb && state->fb->format->format == DRM_FORMAT_NV12 && + (scaling_info->src_rect.x != 0 || scaling_info->src_rect.y != 0))) return -EINVAL; scaling_info->src_rect.width = state->src_w >> 16; @@ -5512,7 +5514,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, int ret; bool force_disable_dcc = false; - ret = fill_dc_scaling_info(plane_state, _info); + ret = fill_dc_scaling_info(adev, plane_state, _info); if (ret) return ret; @@ -7575,7 +7577,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane, if (ret) return ret; - ret = fill_dc_scaling_info(new_plane_state, _info); + ret = fill_dc_scaling_info(adev, new_plane_state, _info); if (ret) return ret; @@ -9023,7 +9025,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->surface_updates[planes_count].gamut_remap_matrix = _plane->gamut_remap_matrix; } - fill_dc_scaling_info(new_plane_state, + fill_dc_scaling_info(dm->adev, new_plane_state, >scaling_infos[planes_count]); bundle->surface_updates[planes_count].scaling_info = -- 2.17.1
[PATCH] drm/amd/display: fix exit from amdgpu_dm_atomic_check() abruptly
make action upon failure in "drm_atomic_add_affected_connectors()" consistent with the rest of failures in amdgpu_dm_atomic_check(). Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1e26d9be8993..a27c246143ac 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10801,7 +10801,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, ret = drm_atomic_add_affected_connectors(state, crtc); if (ret) - return ret; + goto fail; ret = drm_atomic_add_affected_planes(state, crtc); if (ret) -- 2.17.1
[PATCH] drm/amd/display: log amdgpu_dm_atomic_check() failure cause
update user with next level of info about which condition led to atomic check failure. Signed-off-by: Shirish S --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 70 ++- 1 file changed, 52 insertions(+), 18 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 1e26d9be8993..37ea8a76fa09 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10746,8 +10746,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, trace_amdgpu_dm_atomic_check_begin(state); ret = drm_atomic_helper_check_modeset(dev, state); - if (ret) + if (ret) { + DRM_DEV_ERROR(adev->dev, "drm_atomic_helper_check_modeset() failed\n"); goto fail; + } /* Check connector changes */ for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { @@ -10763,6 +10765,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc); if (IS_ERR(new_crtc_state)) { + DRM_DEV_ERROR(adev->dev, "drm_atomic_get_crtc_state() failed\n"); ret = PTR_ERR(new_crtc_state); goto fail; } @@ -10777,8 +10780,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { ret = add_affected_mst_dsc_crtcs(state, crtc); - if (ret) + if (ret) { + DRM_DEV_ERROR(adev->dev, "add_affected_mst_dsc_crtcs() failed\n"); goto fail; + } } } } @@ -10793,19 +10798,25 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, continue; ret = amdgpu_dm_verify_lut_sizes(new_crtc_state); - if (ret) + if (ret) { + DRM_DEV_ERROR(adev->dev, "amdgpu_dm_verify_lut_sizes() failed\n"); goto fail; + } if (!new_crtc_state->enable) continue; ret = drm_atomic_add_affected_connectors(state, crtc); - if (ret) - return ret; + if (ret) { + DRM_DEV_ERROR(adev->dev, "drm_atomic_add_affected_connectors() failed\n"); + goto fail; + } ret = drm_atomic_add_affected_planes(state, crtc); - if (ret) + if (ret) { + DRM_DEV_ERROR(adev->dev, "drm_atomic_add_affected_planes() failed\n"); goto fail; + } if (dm_old_crtc_state->dsc_force_changed) new_crtc_state->mode_changed = true; @@ -10842,6 +10853,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, if (IS_ERR(new_plane_state)) { ret = PTR_ERR(new_plane_state); + DRM_DEV_ERROR(adev->dev, "new_plane_state is BAD\n"); goto fail; } } @@ -10854,8 +10866,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_plane_state, false, _and_validation_needed); - if (ret) + if (ret) { + DRM_DEV_ERROR(adev->dev, "dm_update_plane_state() failed\n"); goto fail; + } } /* Disable all crtcs which require disable */ @@ -10865,8 +10879,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state, false, _and_validation_needed); - if (ret) + if (ret) { + DRM_DEV_ERROR(adev->dev, "DISABLE: dm_update_crtc_state() failed\n"); goto fail; + } } /* Enable all crtcs which require enable */ @@ -10876,8 +10892,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, new_crtc_state,
[PATCH] drm/amd/display: reject both non-zero src_x and src_y only for DCN1x
limit the MPO rejection only for DCN1x as its not required on later versions. Fixes: d89f6048bdcb ("drm/amd/display: Reject non-zero src_y and src_x for video planes") Signed-off-by: Shirish S --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 20 ++- 1 file changed, 11 insertions(+), 9 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 1e26d9be8993..26b29d561919 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4572,7 +4572,8 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev, } -static int fill_dc_scaling_info(const struct drm_plane_state *state, +static int fill_dc_scaling_info(struct amdgpu_device *adev, + const struct drm_plane_state *state, struct dc_scaling_info *scaling_info) { int scale_w, scale_h, min_downscale, max_upscale; @@ -4586,7 +4587,8 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, /* * For reasons we don't (yet) fully understand a non-zero * src_y coordinate into an NV12 buffer can cause a -* system hang. To avoid hangs (and maybe be overly cautious) +* system hang on DCN1x. +* To avoid hangs (and maybe be overly cautious) * let's reject both non-zero src_x and src_y. * * We currently know of only one use-case to reproduce a @@ -4594,10 +4596,10 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, * is to gesture the YouTube Android app into full screen * on ChromeOS. */ - if (state->fb && - state->fb->format->format == DRM_FORMAT_NV12 && - (scaling_info->src_rect.x != 0 || -scaling_info->src_rect.y != 0)) + if (((adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 0)) || + (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 1))) && + (state->fb && state->fb->format->format == DRM_FORMAT_NV12 && + (scaling_info->src_rect.x != 0 || scaling_info->src_rect.y != 0))) return -EINVAL; scaling_info->src_rect.width = state->src_w >> 16; @@ -5503,7 +5505,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, int ret; bool force_disable_dcc = false; - ret = fill_dc_scaling_info(plane_state, _info); + ret = fill_dc_scaling_info(adev, plane_state, _info); if (ret) return ret; @@ -7566,7 +7568,7 @@ static int dm_plane_atomic_check(struct drm_plane *plane, if (ret) return ret; - ret = fill_dc_scaling_info(new_plane_state, _info); + ret = fill_dc_scaling_info(adev, new_plane_state, _info); if (ret) return ret; @@ -9014,7 +9016,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->surface_updates[planes_count].gamut_remap_matrix = _plane->gamut_remap_matrix; } - fill_dc_scaling_info(new_plane_state, + fill_dc_scaling_info(dm->adev, new_plane_state, >scaling_infos[planes_count]); bundle->surface_updates[planes_count].scaling_info = -- 2.17.1
[PATCH] drm/amdgpu/display: fix DMUB firmware version info
DMUB firmware info is printed before it gets initialized. Correct this order to ensure true value is conveyed. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7e09b6d26a51..396a2dca2fe0 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1548,6 +1548,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) } hdr = (const struct dmcub_firmware_header_v1_0 *)adev->dm.dmub_fw->data; + adev->dm.dmcub_fw_version = le32_to_cpu(hdr->header.ucode_version); if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { adev->firmware.ucode[AMDGPU_UCODE_ID_DMCUB].ucode_id = @@ -1561,7 +1562,6 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) adev->dm.dmcub_fw_version); } - adev->dm.dmcub_fw_version = le32_to_cpu(hdr->header.ucode_version); adev->dm.dmub_srv = kzalloc(sizeof(*adev->dm.dmub_srv), GFP_KERNEL); dmub_srv = adev->dm.dmub_srv; -- 2.17.1
[PATCH] drm/amdgpu/powerplay/smu10: refactor AMDGPU_PP_SENSOR_GPU_LOAD
refactor AMDGPU_PP_SENSOR_GPU_LOAD to ensure code consistency with other commands Signed-off-by: Shirish S --- .../gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c| 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index f5d59fa3a030..f5fe540cd536 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -1297,19 +1297,18 @@ static int smu10_read_sensor(struct pp_hwmgr *hwmgr, int idx, *size = 4; break; case AMDGPU_PP_SENSOR_GPU_LOAD: - if (has_gfx_busy) { + if (!has_gfx_busy) + ret = -EOPNOTSUPP; + else { ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxBusy, _percent); if (!ret) - activity_percent = activity_percent > 100 ? 100 : activity_percent; + *((uint32_t *)value) = min(activity_percent, (u32)100); else - return -EIO; - *((uint32_t *)value) = activity_percent; - return 0; - } else { - return -EOPNOTSUPP; + ret = -EIO; } + break; default: ret = -EOPNOTSUPP; break; -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] amdgpu/pm: read_sensor() report failure apporpriately
report -ENOTSUPP instead of -EINVAL, so that if userspace fails to read sensor data can figure it out the failure correctly. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/si_dpm.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index 2c90f715ee0a..c932b632ddd4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -1285,7 +1285,7 @@ static int smu10_read_sensor(struct pp_hwmgr *hwmgr, int idx, *size = 4; break; default: - ret = -EINVAL; + ret = -EOPNOTSUPP; break; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index c57dc9ae81f2..a58f92249c53 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -3945,7 +3945,7 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = (uint32_t)convert_to_vddc(val_vid); return 0; default: - return -EINVAL; + return -EOPNOTSUPP; } } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c index ed9b89980184..2cef9c0c6d6f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c @@ -1805,7 +1805,7 @@ static int smu8_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = smu8_thermal_get_temperature(hwmgr); return 0; default: - return -EINVAL; + return -EOPNOTSUPP; } } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index 29c99642d22d..5e875ad8d633 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -3890,7 +3890,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx, *size = 8; break; default: - ret = -EINVAL; + ret = -EOPNOTSUPP; break; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c index c0753029a8e2..a827f2bc7904 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c @@ -1429,7 +1429,7 @@ static int vega12_read_sensor(struct pp_hwmgr *hwmgr, int idx, *size = 8; break; default: - ret = -EINVAL; + ret = -EOPNOTSUPP; break; } return ret; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index 87811b005b85..e8eec2539c17 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -2240,7 +2240,7 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx, *size = 8; break; default: - ret = -EINVAL; + ret = -EOPNOTSUPP; break; } return ret; diff --git a/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c b/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c index 66daabebee35..bcae42cef374 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c +++ b/drivers/gpu/drm/amd/pm/powerplay/kv_dpm.c @@ -3305,7 +3305,7 @@ static int kv_dpm_read_sensor(void *handle, int idx, *size = 4; return 0; default: - return -EINVAL; + return -EOPNOTSUPP; } } diff --git a/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c b/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c index 62291358fb1c..26a5321e621b 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/powerplay/si_dpm.c @@ -8014,7 +8014,7 @@ static int si_dpm_read_sensor(void *handle, int idx, *size = 4; return 0; default: - return -EINVAL; + return -EOPNOTSUPP; } } -- 2.17.1
[PATCH] drm/amd/display: fix crash/reboot while accessing sysfs files
read/writes to aux_dpcd_* sysfs entries leads to system reboot or hang. Hence fix the handling of input data and reporting of errors appropriately to the user space. Signed-off-by: Shirish S --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) 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 004cd8d38214..8cd646eef096 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 @@ -908,7 +908,7 @@ static ssize_t dp_dpcd_address_write(struct file *f, const char __user *buf, struct amdgpu_dm_connector *connector = file_inode(f)->i_private; if (size < sizeof(connector->debugfs_dpcd_address)) - return 0; + return -EINVAL; r = copy_from_user(>debugfs_dpcd_address, buf, sizeof(connector->debugfs_dpcd_address)); @@ -923,7 +923,7 @@ static ssize_t dp_dpcd_size_write(struct file *f, const char __user *buf, struct amdgpu_dm_connector *connector = file_inode(f)->i_private; if (size < sizeof(connector->debugfs_dpcd_size)) - return 0; + return -EINVAL; r = copy_from_user(>debugfs_dpcd_size, buf, sizeof(connector->debugfs_dpcd_size)); @@ -943,8 +943,8 @@ static ssize_t dp_dpcd_data_write(struct file *f, const char __user *buf, struct dc_link *link = connector->dc_link; uint32_t write_size = connector->debugfs_dpcd_size; - if (size < write_size) - return 0; + if (!write_size || size < write_size) + return -EINVAL; data = kzalloc(write_size, GFP_KERNEL); if (!data) @@ -967,7 +967,7 @@ static ssize_t dp_dpcd_data_read(struct file *f, char __user *buf, struct dc_link *link = connector->dc_link; uint32_t read_size = connector->debugfs_dpcd_size; - if (size < read_size) + if (!read_size || size < read_size) return 0; data = kzalloc(read_size, GFP_KERNEL); -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] amdgpu/gmc_v9: Warn if SDPIF_MMIO_CNTRL_0 is not set
With IOMMU enabled, if SDPIF_MMIO_CNTRL_0 is not set appropriately the system hangs without any trace during S3. To ease debug and to ensure that the failure, if any, was caused by a race conditions that disabled write access to SDPIF_MMIO_CNTRL_0 register, warn the user about it. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index d0645ad3446e..fc2d88dbe828 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1546,8 +1546,11 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) */ void gmc_v9_0_restore_registers(struct amdgpu_device *adev) { - if (adev->asic_type == CHIP_RAVEN) + if (adev->asic_type == CHIP_RAVEN) { WREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); + WARN_ON(adev->gmc.sdpif_register != + RREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); + } } /** -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: re-order asic declarations
"1382d6409891 drm/amd/display: Fix RV2 Variant Detection" introduces build error of: "use of undeclared identifier 'RENOIR_A0'" To fix the same, this patch re-orders the ASIC declarations accordingly. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/include/dal_asic_id.h | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/include/dal_asic_id.h b/drivers/gpu/drm/amd/display/include/dal_asic_id.h index 8a87d0ed90ae..2359e88d6029 100644 --- a/drivers/gpu/drm/amd/display/include/dal_asic_id.h +++ b/drivers/gpu/drm/amd/display/include/dal_asic_id.h @@ -136,6 +136,7 @@ #define RAVEN2_A0 0x81 #define RAVEN1_F0 0xF0 #define RAVEN_UNKNOWN 0xFF +#define RENOIR_A0 0x91 #ifndef ASICREV_IS_RAVEN #define ASICREV_IS_RAVEN(eChipRev) ((eChipRev >= RAVEN_A0) && eChipRev < RAVEN_UNKNOWN) #endif @@ -171,8 +172,6 @@ enum { #define ASICREV_IS_NAVI10_P(eChipRev)(eChipRev < NV_NAVI12_P_A0) #define ASICREV_IS_NAVI12_P(eChipRev)((eChipRev >= NV_NAVI12_P_A0) && (eChipRev < NV_NAVI14_M_A0)) #define ASICREV_IS_NAVI14_M(eChipRev)((eChipRev >= NV_NAVI14_M_A0) && (eChipRev < NV_UNKNOWN)) -#define RENOIR_A0 0x91 -#define DEVICE_ID_RENOIR_1636 0x1636 // Renoir #define ASICREV_IS_RENOIR(eChipRev) ((eChipRev >= RENOIR_A0) && (eChipRev < RAVEN1_F0)) /* @@ -183,6 +182,9 @@ enum { #define DEVICE_ID_TEMASH_9839 0x9839 #define DEVICE_ID_TEMASH_983D 0x983D +/* RENOIR */ +#define DEVICE_ID_RENOIR_1636 0x1636 + /* Asic Family IDs for different asic family. */ #define FAMILY_CI 120 /* Sea Islands: Hawaii (P), Bonaire (M) */ #define FAMILY_KV 125 /* Fusion => Kaveri: Spectre, Spooky; Kabini: Kalindi */ -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] amdgpu/gmc_v9: save/restore sdpif regs during S3
fixes S3 issue with IOMMU + S/G enabled @ 64M VRAM. Suggested-by: Alex Deucher Signed-off-by: Shirish S Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h | 1 + drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 37 ++- .../include/asic_reg/dce/dce_12_0_offset.h| 2 + 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index d03beb204091..2bd9423c1dab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -195,6 +195,7 @@ struct amdgpu_gmc { uint32_tsrbm_soft_reset; boolprt_warning; uint64_tstolen_size; + uint32_tsdpif_register; /* apertures */ u64 shared_aperture_start; u64 shared_aperture_end; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 90216abf14a4..cc0c273a86f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -1271,6 +1271,19 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) } } +/** + * gmc_v9_0_restore_registers - restores regs + * + * @adev: amdgpu_device pointer + * + * This restores register values, saved at suspend. + */ +static void gmc_v9_0_restore_registers(struct amdgpu_device *adev) +{ + if (adev->asic_type == CHIP_RAVEN) + WREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); +} + /** * gmc_v9_0_gart_enable - gart enable * @@ -1376,6 +1389,20 @@ static int gmc_v9_0_hw_init(void *handle) return r; } +/** + * gmc_v9_0_save_registers - saves regs + * + * @adev: amdgpu_device pointer + * + * This saves potential register values that should be + * restored upon resume + */ +static void gmc_v9_0_save_registers(struct amdgpu_device *adev) +{ + if (adev->asic_type == CHIP_RAVEN) + adev->gmc.sdpif_register = RREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); +} + /** * gmc_v9_0_gart_disable - gart disable * @@ -1412,9 +1439,16 @@ static int gmc_v9_0_hw_fini(void *handle) static int gmc_v9_0_suspend(void *handle) { + int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - return gmc_v9_0_hw_fini(adev); + r = gmc_v9_0_hw_fini(adev); + if (r) + return r; + + gmc_v9_0_save_registers(adev); + + return 0; } static int gmc_v9_0_resume(void *handle) @@ -1422,6 +1456,7 @@ static int gmc_v9_0_resume(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + gmc_v9_0_restore_registers(adev); r = gmc_v9_0_hw_init(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h index b6f74bf4af02..27bb8c1ab858 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h @@ -7376,6 +7376,8 @@ #define mmCRTC4_CRTC_DRR_CONTROL 0x0f3e #define mmCRTC4_CRTC_DRR_CONTROL_BASE_IDX 2 +#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0 0x395d +#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0_BASE_IDX 2 // addressBlock: dce_dc_fmt4_dispdec // base address: 0x2000 -- 2.17.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: remove the intterupt handling for the KIQ events
[Why] 1. we never submit IBs to the KIQ 2. there seems to be ~500ms delay during amdgpu resume spent in KIQ, hence, KIQ interrupts are not working correctly. [How] remove interrupt handling for KIQ. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 59 --- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 75 --- 2 files changed, 134 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 2aeef2b..dc9d5bf 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -2048,11 +2048,6 @@ static int gfx_v8_0_sw_init(void *handle) adev->gfx.mec.num_pipe_per_mec = 4; adev->gfx.mec.num_queue_per_pipe = 8; - /* KIQ event */ - r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_INT_IB2, >gfx.kiq.irq); - if (r) - return r; - /* EOP Event */ r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_CP_END_OF_PIPE, >gfx.eop_irq); if (r) @@ -7025,52 +7020,6 @@ static int gfx_v8_0_sq_irq(struct amdgpu_device *adev, return 0; } -static int gfx_v8_0_kiq_set_interrupt_state(struct amdgpu_device *adev, - struct amdgpu_irq_src *src, - unsigned int type, - enum amdgpu_interrupt_state state) -{ - struct amdgpu_ring *ring = &(adev->gfx.kiq.ring); - - switch (type) { - case AMDGPU_CP_KIQ_IRQ_DRIVER0: - WREG32_FIELD(CPC_INT_CNTL, GENERIC2_INT_ENABLE, -state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1); - if (ring->me == 1) - WREG32_FIELD_OFFSET(CP_ME1_PIPE0_INT_CNTL, -ring->pipe, -GENERIC2_INT_ENABLE, -state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1); - else - WREG32_FIELD_OFFSET(CP_ME2_PIPE0_INT_CNTL, -ring->pipe, -GENERIC2_INT_ENABLE, -state == AMDGPU_IRQ_STATE_DISABLE ? 0 : 1); - break; - default: - BUG(); /* kiq only support GENERIC2_INT now */ - break; - } - return 0; -} - -static int gfx_v8_0_kiq_irq(struct amdgpu_device *adev, - struct amdgpu_irq_src *source, - struct amdgpu_iv_entry *entry) -{ - u8 me_id, pipe_id, queue_id; - struct amdgpu_ring *ring = &(adev->gfx.kiq.ring); - - me_id = (entry->ring_id & 0x0c) >> 2; - pipe_id = (entry->ring_id & 0x03) >> 0; - queue_id = (entry->ring_id & 0x70) >> 4; - DRM_DEBUG("IH: CPC GENERIC2_INT, me:%d, pipe:%d, queue:%d\n", - me_id, pipe_id, queue_id); - - amdgpu_fence_process(ring); - return 0; -} - static const struct amd_ip_funcs gfx_v8_0_ip_funcs = { .name = "gfx_v8_0", .early_init = gfx_v8_0_early_init, @@ -7221,11 +7170,6 @@ static const struct amdgpu_irq_src_funcs gfx_v8_0_priv_inst_irq_funcs = { .process = gfx_v8_0_priv_inst_irq, }; -static const struct amdgpu_irq_src_funcs gfx_v8_0_kiq_irq_funcs = { - .set = gfx_v8_0_kiq_set_interrupt_state, - .process = gfx_v8_0_kiq_irq, -}; - static const struct amdgpu_irq_src_funcs gfx_v8_0_cp_ecc_error_irq_funcs = { .set = gfx_v8_0_set_cp_ecc_int_state, .process = gfx_v8_0_cp_ecc_error_irq, @@ -7247,9 +7191,6 @@ static void gfx_v8_0_set_irq_funcs(struct amdgpu_device *adev) adev->gfx.priv_inst_irq.num_types = 1; adev->gfx.priv_inst_irq.funcs = _v8_0_priv_inst_irq_funcs; - adev->gfx.kiq.irq.num_types = AMDGPU_CP_KIQ_IRQ_LAST; - adev->gfx.kiq.irq.funcs = _v8_0_kiq_irq_funcs; - adev->gfx.cp_ecc_error_irq.num_types = 1; adev->gfx.cp_ecc_error_irq.funcs = _v8_0_cp_ecc_error_irq_funcs; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 7a6a814..edf23a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1711,11 +1711,6 @@ static int gfx_v9_0_sw_init(void *handle) adev->gfx.mec.num_pipe_per_mec = 4; adev->gfx.mec.num_queue_per_pipe = 8; - /* KIQ event */ - r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, GFX_9_0__SRCID__CP_IB2_INTERRUPT_PKT, >gfx.kiq.irq); - if (r) - return r; - /* EOP Event */ r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_GRBM_CP, GFX_9_0__SRCID__CP_EOP_INTERRUPT, >gfx.eop_irq); if
[PATCH] drm/amdgpu: skip IB tests for KIQ in general
From: Pratik Vishwakarma [Why] 1. We never submit IBs to KIQ. 2. Ring test pass without KIQ's ring also. 3. By skipping we see an improvement of around 500ms in the amdgpu's resume time. [How] skip IB tests for KIQ ring type. Signed-off-by: Shirish S Signed-off-by: Pratik Vishwakarma --- This patch is a follow-up to the suggestion given by Alex, while reviewing the patch: https://patchwork.freedesktop.org/patch/250912/ -Shirish S drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 47817e0..b8963b7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -354,6 +354,14 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev) if (!ring || !ring->ready) continue; + /* skip IB tests for KIQ in general for the below reasons: +* 1. We never submit IBs to the KIQ +* 2. KIQ doesn't use the EOP interrupts, +*we use some other CP interrupt. +*/ + if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ) + continue; + /* MM engine need more time */ if (ring->funcs->type == AMDGPU_RING_TYPE_UVD || ring->funcs->type == AMDGPU_RING_TYPE_VCE || -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: move the nonblocking commit helpers appropriately
[Why] In multi-monitor scenario, if first crtc's flip done event occurs delayed (but within timeout), due to non-blocking design of commit_tail(), there are more than one commit's scheduled by the time the second crtc's wait_for_completion_timeout() is called in drm_atomic_helper_wait_for_flip_done. Due to these in-between additions and deletions in the atomic state, it is found that the system fails while accessing common data structures of the second crtc in drm_atomic_helper_wait_for_flip_done(), leading to crash as below: BUG: unable to handle kernel paging request at 0001001c IP: do_raw_spin_lock+0xf/0x94 PGD 0 P4D 0 Oops: [#1] PREEMPT SMP NOPTI Call Trace: __wait_for_common+0x36/0x60 drm_atomic_helper_wait_for_flip_done+0x47/0x89 amdgpu_dm_atomic_commit_tail+0xf4b/0xf84 ? drm_atomic_helper_wait_for_dependencies+0x1cd/0x217 commit_tail+0x41/0x5f [How] Move drm_atomic_helper_commit_hw_done() post wait_for_flip_done(), which cleans up the atomic state's commit and completes pending hw_done and flip_done works as a result there wont be dangling flip waits on random commits. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +++-- 1 file changed, 7 insertions(+), 2 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 0f10d92..41a1958 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4626,12 +4626,17 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) } spin_unlock_irqrestore(>ddev->event_lock, flags); - /* Signal HW programming completion */ - drm_atomic_helper_commit_hw_done(state); if (wait_for_vblank) drm_atomic_helper_wait_for_flip_done(dev, state); + /* Atomic state pointer gets corrupted in case of frequent +* modesets operations like changing resolutions. +* Hence discard state->commit before signalling to user +* space. +*/ + drm_atomic_helper_commit_hw_done(state); + drm_atomic_helper_cleanup_planes(dev, state); /* -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: add ip_block_mask user option for static builds
This patch extends amdgpu.ip_block_mask to a Kconfig option as well, that can be altered by user at build time for OS' that do not permit passing dyanamic loading of amdgpu driver and also passing command line arguments. Note: This option to be used purely for debugging purposes and amdgpu driver is not productised/tested extensively with any of its blokcs disabled. The default value of this option enables all IP's. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/Kconfig | 7 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig b/drivers/gpu/drm/amd/amdgpu/Kconfig index e8af1f5..3f94ae5 100644 --- a/drivers/gpu/drm/amd/amdgpu/Kconfig +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig @@ -23,6 +23,13 @@ config DRM_AMDGPU_CIK radeon.cik_support=0 amdgpu.cik_support=1 +config DRM_AMDGPU_IP_BLOCK_MASK + hex "AMDGPU IP Block Mask" + depends on DRM_AMDGPU + default "0x" + help + Modify this option to disable any IP block of amdgpu. + config DRM_AMDGPU_USERPTR bool "Always enable userptr write support" depends on DRM_AMDGPU diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 2221f6b..bd0a876 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -93,7 +93,7 @@ int amdgpu_dpm = -1; int amdgpu_fw_load_type = -1; int amdgpu_aspm = -1; int amdgpu_runtime_pm = -1; -uint amdgpu_ip_block_mask = 0x; +uint amdgpu_ip_block_mask = CONFIG_DRM_AMDGPU_IP_BLOCK_MASK; int amdgpu_bapm = -1; int amdgpu_deep_color = 0; int amdgpu_vm_size = -1; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdpu/vce_v3: skip suspend and resume if powergated
This patch adds a mechanism by which the VCE 3.0 block shall check if it was enabled or in use before suspending, if it was powergated while entering suspend then there is no need to repeat it in vce_3_0_suspend(). Similarly, if the block was powergated while entering suspend itself then there is no need to resume it. By this we not only make the suspend and resume sequence more efficient, but also optimize the overall amdgpu suspend and resume time by reducing the ring intialize and tests for unused IP blocks. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 ++ drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 21 + 2 files changed, 23 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 07924d4..aa85063 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1035,6 +1035,8 @@ struct amdgpu_device { /* vce */ struct amdgpu_vce vce; + boolis_vce_pg; + boolis_vce_disabled; /* vcn */ struct amdgpu_vcn vcn; diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index cc6ce6c..822cfd6 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -326,6 +326,7 @@ static int vce_v3_0_start(struct amdgpu_device *adev) WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT); mutex_unlock(>grbm_idx_mutex); + adev->is_vce_pg = false; return 0; } @@ -355,6 +356,7 @@ static int vce_v3_0_stop(struct amdgpu_device *adev) WREG32(mmGRBM_GFX_INDEX, mmGRBM_GFX_INDEX_DEFAULT); mutex_unlock(>grbm_idx_mutex); + adev->is_vce_pg = true; return 0; } @@ -506,6 +508,17 @@ static int vce_v3_0_suspend(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* Proceed with suspend sequence only if VCE is started +* Mark the block as being disabled if its stopped. +*/ + if (adev->is_vce_pg) { + DRM_DEBUG("VCE is already powergated, not suspending\n"); + adev->is_vce_disabled = true; + return 0; + } + + adev->is_vce_disabled = false; + r = vce_v3_0_hw_fini(adev); if (r) return r; @@ -518,6 +531,14 @@ static int vce_v3_0_resume(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* Proceed with resume sequence if VCE was enabled +* while suspending. +*/ + if (adev->is_vce_disabled) { + DRM_DEBUG("VCE is powergated, not resuming the block\n"); + return 0; + } + r = amdgpu_vce_resume(adev); if (r) return r; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: move the amdgpu_fbdev_set_suspend() further up
This patch moves amdgpu_fbdev_set_suspend() to the beginning of suspend sequence. This is to ensure fbcon does not to write to the VRAM after GPU is powerd down. Signed-off-by: Shirish S Reviewed-by: Michel Dänzer --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7a1bec1..745f760 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2702,6 +2702,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) drm_kms_helper_poll_disable(dev); + if (fbcon) + amdgpu_fbdev_set_suspend(adev, 1); + if (!amdgpu_device_has_dc_support(adev)) { /* turn off display hw */ drm_modeset_lock_all(dev); @@ -2767,9 +2770,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) DRM_ERROR("amdgpu asic reset failed\n"); } - if (fbcon) - amdgpu_fbdev_set_suspend(adev, 1); - return 0; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: move the amdgpu_fbdev_set_suspend() further up
This patch moves amdgpu_fbdev_set_suspend() to the beginning of suspend sequence. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 7a1bec1..745f760 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2702,6 +2702,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) drm_kms_helper_poll_disable(dev); + if (fbcon) + amdgpu_fbdev_set_suspend(adev, 1); + if (!amdgpu_device_has_dc_support(adev)) { /* turn off display hw */ drm_modeset_lock_all(dev); @@ -2767,9 +2770,6 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) DRM_ERROR("amdgpu asic reset failed\n"); } - if (fbcon) - amdgpu_fbdev_set_suspend(adev, 1); - return 0; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: use drm_fb helper for console_(un)lock
This patch removes the usage of console_(un)lock by replacing drm_fb_helper_set_suspend() to drm_fb_helper_set_suspend_unlocked() which locks and unlocks the console instead of locking ourselves. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 022c136..a759b74 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2691,11 +2691,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon) DRM_ERROR("amdgpu asic reset failed\n"); } - if (fbcon) { - console_lock(); + if (fbcon) amdgpu_fbdev_set_suspend(adev, 1); - console_unlock(); - } + return 0; } @@ -2784,9 +2782,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) } drm_modeset_unlock_all(dev); } - console_lock(); amdgpu_fbdev_set_suspend(adev, 0); - console_unlock(); } drm_kms_helper_poll_enable(dev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c index d44b764..69c5d22 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -373,8 +373,8 @@ void amdgpu_fbdev_fini(struct amdgpu_device *adev) void amdgpu_fbdev_set_suspend(struct amdgpu_device *adev, int state) { if (adev->mode_info.rfbdev) - drm_fb_helper_set_suspend(>mode_info.rfbdev->helper, - state); + drm_fb_helper_set_suspend_unlocked(>mode_info.rfbdev->helper, + state); } int amdgpu_fbdev_total_size(struct amdgpu_device *adev) -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: lock and unlock console only for amdgpu_fbdev_set_suspend [V5]
[Why] While the console_lock is held, console output will be buffered, till its unlocked it wont be emitted, hence its ideal to unlock sooner to enable debugging/detecting/fixing of any issue in the remaining sequence of events in resume path. The concern here is about consoles other than fbcon on the device, e.g. a serial console [How] This patch restructures the console_lock, console_unlock around amdgpu_fbdev_set_suspend() and moves this new block appropriately. V2: Kept amdgpu_fbdev_set_suspend after pci_set_power_state V3: Updated the commit message to clarify the real concern that this patch addresses. V4: code clean-up. V5: fixed return value Signed-off-by: Shirish S Reviewed-by: Michel Dänzer --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 22 +++--- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 709e4a3..cf9af28 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2720,15 +2720,12 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - if (fbcon) - console_lock(); - if (resume) { pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); r = pci_enable_device(dev->pdev); if (r) - goto unlock; + return r; } /* post card */ @@ -2741,7 +2738,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) r = amdgpu_device_ip_resume(adev); if (r) { DRM_ERROR("amdgpu_device_ip_resume failed (%d).\n", r); - goto unlock; + return r; } amdgpu_fence_driver_resume(adev); @@ -2749,7 +2746,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) r = amdgpu_device_ip_late_init(adev); if (r) - goto unlock; + return r; /* pin cursors */ list_for_each_entry(crtc, >mode_config.crtc_list, head) { @@ -2784,6 +2781,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) } drm_modeset_unlock_all(dev); } + console_lock(); + amdgpu_fbdev_set_suspend(adev, 0); + console_unlock(); } drm_kms_helper_poll_enable(dev); @@ -2807,15 +2807,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) #ifdef CONFIG_PM dev->dev->power.disable_depth--; #endif - - if (fbcon) - amdgpu_fbdev_set_suspend(adev, 0); - -unlock: - if (fbcon) - console_unlock(); - - return r; + return 0; } /** -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: lock and unlock console only for amdgpu_fbdev_set_suspend [V4]
[Why] While the console_lock is held, console output will be buffered, till its unlocked it wont be emitted, hence its ideal to unlock sooner to enable debugging/detecting/fixing of any issue in the remaining sequence of events in resume path. The concern here is about consoles other than fbcon on the device, e.g. a serial console [How] This patch restructures the console_lock, console_unlock around amdgpu_fbdev_set_suspend() and moves this new block appropriately. V2: Kept amdgpu_fbdev_set_suspend after pci_set_power_state V3: Updated the commit message to clarify the real concern that this patch addresses. V4: code clean-up. Signed-off-by: Shirish S Reviewed-by: Michel Dänzer --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 21 ++--- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 709e4a3..096ad09 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2720,15 +2720,12 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - if (fbcon) - console_lock(); - if (resume) { pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); r = pci_enable_device(dev->pdev); if (r) - goto unlock; + return r; } /* post card */ @@ -2741,7 +2738,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) r = amdgpu_device_ip_resume(adev); if (r) { DRM_ERROR("amdgpu_device_ip_resume failed (%d).\n", r); - goto unlock; + return r; } amdgpu_fence_driver_resume(adev); @@ -2749,7 +2746,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) r = amdgpu_device_ip_late_init(adev); if (r) - goto unlock; + return r; /* pin cursors */ list_for_each_entry(crtc, >mode_config.crtc_list, head) { @@ -2784,6 +2781,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) } drm_modeset_unlock_all(dev); } + console_lock(); + amdgpu_fbdev_set_suspend(adev, 0); + console_unlock(); } drm_kms_helper_poll_enable(dev); @@ -2807,15 +2807,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) #ifdef CONFIG_PM dev->dev->power.disable_depth--; #endif - - if (fbcon) - amdgpu_fbdev_set_suspend(adev, 0); - -unlock: - if (fbcon) - console_unlock(); - - return r; } /** -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: lock and unlock console only for amdgpu_fbdev_set_suspend [V3]
[Why] While the console_lock is held, console output will be buffered, till its unlocked it wont be emitted, hence its ideal to unlock sooner to enable debugging/detecting/fixing of any issue in the remaining sequence of events in resume path. The concern here is about consoles other than fbcon on the device, e.g. a serial console [How] This patch restructures the console_lock, console_unlock around amdgpu_fbdev_set_suspend() and moves this new block appropriately. V2: Kept amdgpu_fbdev_set_suspend after pci_set_power_state V3: Updated the commit message to clarify the real concern that this patch addresses. Signed-off-by: Shirish S Reviewed-by: Michel Dänzer --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 709e4a3..c1eed94 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2720,9 +2720,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - if (fbcon) - console_lock(); - if (resume) { pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); @@ -2784,6 +2781,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) } drm_modeset_unlock_all(dev); } + console_lock(); + amdgpu_fbdev_set_suspend(adev, 0); + console_unlock(); } drm_kms_helper_poll_enable(dev); @@ -2808,13 +2808,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) dev->dev->power.disable_depth--; #endif - if (fbcon) - amdgpu_fbdev_set_suspend(adev, 0); - unlock: - if (fbcon) - console_unlock(); - return r; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: lock and unlock console only for amdgpu_fbdev_set_suspend [V2]
[Why] While the console_lock is held, console output will be buffered, till its unlocked it wont be emitted, hence its ideal to unlock sooner to enable debugging/detecting/fixing of any issue in the remaining sequence of events in resume path. [How] This patch restructures the console_lock, console_unlock around amdgpu_fbdev_set_suspend() and moves this new block appropriately. V2: Kept amdgpu_fbdev_set_suspend after pci_set_power_state Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 709e4a3..b0fe727 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2720,9 +2720,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - if (fbcon) - console_lock(); - if (resume) { pci_set_power_state(dev->pdev, PCI_D0); pci_restore_state(dev->pdev); @@ -2746,7 +2743,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) amdgpu_fence_driver_resume(adev); - r = amdgpu_device_ip_late_init(adev); if (r) goto unlock; @@ -2784,6 +2780,9 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) } drm_modeset_unlock_all(dev); } + console_lock(); + amdgpu_fbdev_set_suspend(adev, 0); + console_unlock(); } drm_kms_helper_poll_enable(dev); @@ -2808,13 +2807,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) dev->dev->power.disable_depth--; #endif - if (fbcon) - amdgpu_fbdev_set_suspend(adev, 0); - unlock: - if (fbcon) - console_unlock(); - return r; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: reciprocate amdgpu.._resume sequence to match amdgpu.._suspend
[Why] 1. To ensure that resume path reciprocates the sequence followed during suspend. 2. While the console_lock is held, console output will be buffered, till its unlocked it wont be emitted, hence its ideal to unlock sooner to enable debugging/detecting/fixing of any issue in the remaining sequence of events in resume path. [How] This patch restructures the console_lock, console_unlock around amdgpu_fbdev_set_suspend() and moves this new block to the very beginning of the resume sequence. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 709e4a3..fc4c517 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2720,8 +2720,11 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - if (fbcon) + if (fbcon) { console_lock(); + amdgpu_fbdev_set_suspend(adev, 0); + console_unlock(); + } if (resume) { pci_set_power_state(dev->pdev, PCI_D0); @@ -2746,7 +2749,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) amdgpu_fence_driver_resume(adev); - r = amdgpu_device_ip_late_init(adev); if (r) goto unlock; @@ -2808,13 +2810,7 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) dev->dev->power.disable_depth--; #endif - if (fbcon) - amdgpu_fbdev_set_suspend(adev, 0); - unlock: - if (fbcon) - console_unlock(); - return r; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: execute amdgpu_ring_patch_cond_exec() only for valid job
issue: BUG_ON(ring->ring[offset] != 0x55aa55aa) is hit on resume from S3 state. fix & analysis: fix is to check for valid job, which in continuation to the below patch: 113890e drm/amdgpu: cond_exec only for schedule with a job Since cond_exec is not initialised if there is no job, 0x55aa55aa is not written to ring, as a result in patch_cond_exec callback, BUG_ON is hit where it checks for the same 0x55aa55aa value in register. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 31f8170..3381ada 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -249,7 +249,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, fence_flags | AMDGPU_FENCE_FLAG_64BIT); } - if (patch_offset != ~0 && ring->funcs->patch_cond_exec) + if (job && patch_offset != ~0 && ring->funcs->patch_cond_exec) amdgpu_ring_patch_cond_exec(ring, patch_offset); ring->current_ctx = fence_ctx; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: release spinlock before committing updates to stream
Currently, amdgpu_do_flip() spinlocks crtc->dev->event_lock and releases it only after committing updates to the stream. dc_commit_updates_for_stream() should be moved out of spinlock for the below reasons: 1. event_lock is supposed to protect access to acrct->pflip_status _only_ 2. dc_commit_updates_for_stream() has potential sleep's and also its not appropriate to be in an atomic state for such long sequences of code. Signed-off-by: Shirish S Suggested-by: Andrey Grodzovsky Reviewed-by: Michel Dänzer Reviewed-by: Harry Wentland --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 ++ 1 file changed, 2 insertions(+), 4 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 769ef7c..d399f76 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4002,10 +4002,11 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, if (acrtc->base.state->event) prepare_flip_isr(acrtc); + spin_unlock_irqrestore(>dev->event_lock, flags); + surface_updates->surface = dc_stream_get_status(acrtc_state->stream)->plane_states[0]; surface_updates->flip_addr = - dc_commit_updates_for_stream(adev->dm.dc, surface_updates, 1, @@ -4018,9 +4019,6 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc, __func__, addr.address.grph.addr.high_part, addr.address.grph.addr.low_part); - - - spin_unlock_irqrestore(>dev->event_lock, flags); } /* -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: change gfx8 ib test to use WB
This patch is extends the usage of WB in gfx8's ib test which was originally implemented in the below upstream patch "ed9324a drm/amdgpu: change gfx9 ib test to use WB" For reference below are the reasons for switching to WB: 1)Because when doing IB test we don't want to involve KIQ health status affect, and since SCRATCH register access is go through KIQ that way GFX IB test would failed due to KIQ fail. 2)acccessing SCRATCH register cost much more time than WB method because SCRATCH register access runs through KIQ which at least could begin after GPU world switch back to current Guest VF Signed-off-by: Shirish S Reviewed-by: Chunming Zhou Reviewed-by: Christian König --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 35 +-- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 818874b..61452c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -866,26 +866,32 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) struct amdgpu_device *adev = ring->adev; struct amdgpu_ib ib; struct dma_fence *f = NULL; - uint32_t scratch; - uint32_t tmp = 0; + + unsigned int index; + uint64_t gpu_addr; + uint32_t tmp; long r; - r = amdgpu_gfx_scratch_get(adev, ); + r = amdgpu_device_wb_get(adev, ); if (r) { - DRM_ERROR("amdgpu: failed to get scratch reg (%ld).\n", r); + dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); return r; } - WREG32(scratch, 0xCAFEDEAD); + + gpu_addr = adev->wb.gpu_addr + (index * 4); + adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); memset(, 0, sizeof(ib)); - r = amdgpu_ib_get(adev, NULL, 256, ); + r = amdgpu_ib_get(adev, NULL, 16, ); if (r) { DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); goto err1; } - ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); - ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START)); - ib.ptr[2] = 0xDEADBEEF; - ib.length_dw = 3; + ib.ptr[0] = PACKET3(PACKET3_WRITE_DATA, 3); + ib.ptr[1] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; + ib.ptr[2] = lower_32_bits(gpu_addr); + ib.ptr[3] = upper_32_bits(gpu_addr); + ib.ptr[4] = 0xDEADBEEF; + ib.length_dw = 5; r = amdgpu_ib_schedule(ring, 1, , NULL, ); if (r) @@ -900,20 +906,21 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); goto err2; } - tmp = RREG32(scratch); + + tmp = adev->wb.wb[index]; if (tmp == 0xDEADBEEF) { DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); r = 0; } else { - DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n", - scratch, tmp); + DRM_ERROR("ib test on ring %d failed\n", ring->idx); r = -EINVAL; } + err2: amdgpu_ib_free(adev, , NULL); dma_fence_put(f); err1: - amdgpu_gfx_scratch_free(adev, scratch); + amdgpu_device_wb_free(adev, index); return r; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: change gfx8 ib test to use WB
This patch is extends the usage of WB in gfx8's ib test which was originally implemented in the below upstream patch: "ed9324a drm/amdgpu: change gfx9 ib test to use WB" Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 35 +-- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 818874b..61452c7 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -866,26 +866,32 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) struct amdgpu_device *adev = ring->adev; struct amdgpu_ib ib; struct dma_fence *f = NULL; - uint32_t scratch; - uint32_t tmp = 0; + + unsigned int index; + uint64_t gpu_addr; + uint32_t tmp; long r; - r = amdgpu_gfx_scratch_get(adev, ); + r = amdgpu_device_wb_get(adev, ); if (r) { - DRM_ERROR("amdgpu: failed to get scratch reg (%ld).\n", r); + dev_err(adev->dev, "(%ld) failed to allocate wb slot\n", r); return r; } - WREG32(scratch, 0xCAFEDEAD); + + gpu_addr = adev->wb.gpu_addr + (index * 4); + adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); memset(, 0, sizeof(ib)); - r = amdgpu_ib_get(adev, NULL, 256, ); + r = amdgpu_ib_get(adev, NULL, 16, ); if (r) { DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); goto err1; } - ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); - ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START)); - ib.ptr[2] = 0xDEADBEEF; - ib.length_dw = 3; + ib.ptr[0] = PACKET3(PACKET3_WRITE_DATA, 3); + ib.ptr[1] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM; + ib.ptr[2] = lower_32_bits(gpu_addr); + ib.ptr[3] = upper_32_bits(gpu_addr); + ib.ptr[4] = 0xDEADBEEF; + ib.length_dw = 5; r = amdgpu_ib_schedule(ring, 1, , NULL, ); if (r) @@ -900,20 +906,21 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); goto err2; } - tmp = RREG32(scratch); + + tmp = adev->wb.wb[index]; if (tmp == 0xDEADBEEF) { DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); r = 0; } else { - DRM_ERROR("amdgpu: ib test failed (scratch(0x%04X)=0x%08X)\n", - scratch, tmp); + DRM_ERROR("ib test on ring %d failed\n", ring->idx); r = -EINVAL; } + err2: amdgpu_ib_free(adev, , NULL); dma_fence_put(f); err1: - amdgpu_gfx_scratch_free(adev, scratch); + amdgpu_device_wb_free(adev, index); return r; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu/pp: replace mutex with spin_lock (V3)
This patch replaces usage of mutex with spin_lock to avoid sleep in atomic context. Below is the stack trace: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:** in_atomic(): 1, irqs_disabled(): 1, pid: 5, name: kworker/u4:0 CPU: 1 PID: 5 Comm: kworker/u4:0 Tainted: GW 4.14.43 #9 Workqueue: events_unbound commit_work Call Trace: dump_stack+0x4d/0x63 ___might_sleep+0x11f/0x12e mutex_lock+0x20/0x42 amd_powerplay_display_configuration_change+0x32/0x51 dm_pp_apply_display_requirements+0x10b/0x118 dce110_set_bandwidth+0x1a1/0x1b5 dc_commit_updates_for_stream+0x14c/0x4cf ? amdgpu_get_crtc_scanoutpos+0x82/0x16b amdgpu_dm_do_flip+0x239/0x298 amdgpu_dm_commit_planes.isra.23+0x379/0x54b ? drm_calc_timestamping_constants+0x14b/0x15c amdgpu_dm_atomic_commit_tail+0x4fc/0x5d2 ? wait_for_common+0x5b/0x69 commit_tail+0x42/0x64 process_one_work+0x1b0/0x314 worker_thread+0x1cb/0x2c1 ? create_worker+0x1da/0x1da kthread+0x156/0x15e ? kthread_flush_work+0xea/0xea ret_from_fork+0x22/0x40 V2: Added stack trace in the commit message. V3: Fixed compile time error related to mutex_init() Signed-off-by: Shirish S Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 154 +- drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 +- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index b493369..1d47707 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -50,7 +50,7 @@ static int amd_powerplay_create(struct amdgpu_device *adev) hwmgr->not_vf = !amdgpu_sriov_vf(adev); hwmgr->pm_en = (amdgpu_dpm && hwmgr->not_vf) ? true : false; hwmgr->device = amdgpu_cgs_create_device(adev); - mutex_init(>smu_lock); + spin_lock_init(>smu_lock); hwmgr->chip_family = adev->family; hwmgr->chip_id = adev->asic_type; hwmgr->feature_mask = adev->powerplay.pp_feature; @@ -183,10 +183,10 @@ static int pp_late_init(void *handle) int ret; if (hwmgr && hwmgr->pm_en) { - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr_handle_task(hwmgr, AMD_PP_TASK_COMPLETE_INIT, NULL); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); } if (adev->pm.smu_prv_buffer_size != 0) pp_reserve_vram_for_smu(adev); @@ -375,11 +375,11 @@ static int pp_dpm_force_performance_level(void *handle, if (level == hwmgr->dpm_level) return 0; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); pp_dpm_en_umd_pstate(hwmgr, ); hwmgr->request_dpm_level = level; hwmgr_handle_task(hwmgr, AMD_PP_TASK_READJUST_POWER_STATE, NULL); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return 0; } @@ -393,9 +393,9 @@ static enum amd_dpm_forced_level pp_dpm_get_performance_level( if (!hwmgr || !hwmgr->pm_en) return -EINVAL; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); level = hwmgr->dpm_level; - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return level; } @@ -411,9 +411,9 @@ static uint32_t pp_dpm_get_sclk(void *handle, bool low) pr_info("%s was not implemented.\n", __func__); return 0; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); clk = hwmgr->hwmgr_func->get_sclk(hwmgr, low); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return clk; } @@ -429,9 +429,9 @@ static uint32_t pp_dpm_get_mclk(void *handle, bool low) pr_info("%s was not implemented.\n", __func__); return 0; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); clk = hwmgr->hwmgr_func->get_mclk(hwmgr, low); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return clk; } @@ -446,9 +446,9 @@ static void pp_dpm_powergate_vce(void *handle, bool gate) pr_info("%s was not implemented.\n", __func__); return; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr->hwmgr_func->powergate_vce(hwmgr, gate); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); } static void pp_dpm_powergate_uvd(void *handle, bool gate) @@ -462,9 +462,9 @@ static void pp_dpm_powergate_uvd(void *handle, bool gate) pr_info("%s was not implemented.\n", __func__); return; } - mutex_lock(>smu_lock); + spin_lock(>sm
[PATCH] drm/amdgpu: avoid sleep while executing atombios table (V2)
This patch replaces kzalloc's flag from GFP_KERNEL to GFP_ATOMIC to avoid sleeping in atomic context. Below is the stack trace: BUG: sleeping function called from invalid context at mm/slab.h:*** in_atomic(): 1, irqs_disabled(): 0, pid: 1137, name: DrmThread CPU: 1 PID: 1137 Comm: DrmThread Tainted: GW 4.14.43 #10 Call Trace: dump_stack+0x4d/0x63 ___might_sleep+0x11f/0x12e __kmalloc+0x76/0x126 amdgpu_atom_execute_table_locked+0xfc/0x285 amdgpu_atom_execute_table+0x5d/0x72 transmitter_control_v1_5+0xef/0x11a hwss_edp_backlight_control+0x132/0x151 dce110_disable_stream+0x133/0x16e core_link_disable_stream+0x1c5/0x23b dce110_reset_hw_ctx_wrap+0xb4/0x1aa dce110_apply_ctx_to_hw+0x4e/0x6da ? generic_reg_get+0x1f/0x33 dc_commit_state+0x33f/0x3d2 amdgpu_dm_atomic_commit_tail+0x2cf/0x5d2 ? wait_for_common+0x5b/0x69 commit_tail+0x42/0x64 drm_atomic_helper_commit+0xdc/0xf9 drm_atomic_helper_set_config+0x5c/0x76 __drm_mode_set_config_internal+0x64/0x105 drm_mode_setcrtc+0x474/0x56f ? drm_mode_getcrtc+0x155/0x155 drm_ioctl_kernel+0x6c/0xa8 drm_ioctl+0x267/0x353 ? drm_mode_getcrtc+0x155/0x155 amdgpu_drm_ioctl+0x4f/0x7f vfs_ioctl+0x21/0x2f do_vfs_ioctl+0x4c4/0x4e7 ? security_file_ioctl+0x3b/0x4f SyS_ioctl+0x57/0x79 do_syscall_64+0x64/0x72 entry_SYSCALL_64_after_hwframe+0x3d/0xa2 V2: Added stack trace in commit message. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/atom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index bfd98f0..da4558c 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1221,7 +1221,7 @@ static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, ectx.abort = false; ectx.last_jump = 0; if (ws) - ectx.ws = kzalloc(4 * ws, GFP_KERNEL); + ectx.ws = kzalloc(4 * ws, GFP_ATOMIC); else ectx.ws = NULL; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: replace mutex with spin_lock (V2)
mutex's lead to sleeps which should be avoided in atomic context. Hence this patch replaces it with the spin_locks. Below is the stack trace: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:** in_atomic(): 1, irqs_disabled(): 1, pid: 89, name: kworker/u4:3 CPU: 1 PID: 89 Comm: kworker/u4:3 Tainted: GW 4.14.43 #8 Workqueue: events_unbound commit_work Call Trace: dump_stack+0x4d/0x63 ___might_sleep+0x11f/0x12e mutex_lock+0x20/0x42 amdgpu_atom_execute_table+0x26/0x72 enable_disp_power_gating_v2_1+0x85/0xae dce110_enable_display_power_gating+0x83/0x1b1 dce110_power_down_fe+0x4a/0x6d dc_post_update_surfaces_to_stream+0x59/0x87 amdgpu_dm_do_flip+0x239/0x298 amdgpu_dm_commit_planes.isra.23+0x379/0x54b ? drm_calc_timestamping_constants+0x14b/0x15c amdgpu_dm_atomic_commit_tail+0x4fc/0x5d2 ? wait_for_common+0x5b/0x69 commit_tail+0x42/0x64 process_one_work+0x1b0/0x314 worker_thread+0x1cb/0x2c1 ? create_worker+0x1da/0x1da kthread+0x156/0x15e ? kthread_flush_work+0xea/0xea ret_from_fork+0x22/0x40 V2: Added stack trace in commit message. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 2 +- drivers/gpu/drm/amd/amdgpu/atom.c| 4 ++-- drivers/gpu/drm/amd/amdgpu/atom.h| 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index bf872f6..ba3d4b9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -2033,7 +2033,7 @@ int amdgpu_atombios_init(struct amdgpu_device *adev) return -ENOMEM; } - mutex_init(>mode_info.atom_context->mutex); + spin_lock_init(>mode_info.atom_context->lock); if (adev->is_atom_fw) { amdgpu_atomfirmware_scratch_regs_init(adev); amdgpu_atomfirmware_allocate_fb_scratch(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index 69500a8..bfd98f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1261,7 +1261,7 @@ int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * pa { int r; - mutex_lock(>mutex); + spin_lock(>lock); /* reset data block */ ctx->data_block = 0; /* reset reg block */ @@ -1274,7 +1274,7 @@ int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * pa ctx->divmul[0] = 0; ctx->divmul[1] = 0; r = amdgpu_atom_execute_table_locked(ctx, index, params); - mutex_unlock(>mutex); + spin_unlock(>lock); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h index a391709..54063e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.h +++ b/drivers/gpu/drm/amd/amdgpu/atom.h @@ -26,6 +26,7 @@ #define ATOM_H #include +#include #include #define ATOM_BIOS_MAGIC0xAA55 @@ -125,7 +126,7 @@ struct card_info { struct atom_context { struct card_info *card; - struct mutex mutex; + spinlock_t lock; void *bios; uint32_t cmd_table, data_table; uint16_t *iio; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu/pp: replace mutex with spin_lock (V2)
This patch replaces usage of mutex with spin_lock to avoid sleep in atomic context. Below is the stack trace: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:** in_atomic(): 1, irqs_disabled(): 1, pid: 5, name: kworker/u4:0 CPU: 1 PID: 5 Comm: kworker/u4:0 Tainted: GW 4.14.43 #9 Workqueue: events_unbound commit_work Call Trace: dump_stack+0x4d/0x63 ___might_sleep+0x11f/0x12e mutex_lock+0x20/0x42 amd_powerplay_display_configuration_change+0x32/0x51 dm_pp_apply_display_requirements+0x10b/0x118 dce110_set_bandwidth+0x1a1/0x1b5 dc_commit_updates_for_stream+0x14c/0x4cf ? amdgpu_get_crtc_scanoutpos+0x82/0x16b amdgpu_dm_do_flip+0x239/0x298 amdgpu_dm_commit_planes.isra.23+0x379/0x54b ? drm_calc_timestamping_constants+0x14b/0x15c amdgpu_dm_atomic_commit_tail+0x4fc/0x5d2 ? wait_for_common+0x5b/0x69 commit_tail+0x42/0x64 process_one_work+0x1b0/0x314 worker_thread+0x1cb/0x2c1 ? create_worker+0x1da/0x1da kthread+0x156/0x15e ? kthread_flush_work+0xea/0xea ret_from_fork+0x22/0x40 V2: Added stack trace in the commit message. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 152 +- drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 +- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index b493369..2d9c120 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -183,10 +183,10 @@ static int pp_late_init(void *handle) int ret; if (hwmgr && hwmgr->pm_en) { - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr_handle_task(hwmgr, AMD_PP_TASK_COMPLETE_INIT, NULL); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); } if (adev->pm.smu_prv_buffer_size != 0) pp_reserve_vram_for_smu(adev); @@ -375,11 +375,11 @@ static int pp_dpm_force_performance_level(void *handle, if (level == hwmgr->dpm_level) return 0; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); pp_dpm_en_umd_pstate(hwmgr, ); hwmgr->request_dpm_level = level; hwmgr_handle_task(hwmgr, AMD_PP_TASK_READJUST_POWER_STATE, NULL); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return 0; } @@ -393,9 +393,9 @@ static enum amd_dpm_forced_level pp_dpm_get_performance_level( if (!hwmgr || !hwmgr->pm_en) return -EINVAL; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); level = hwmgr->dpm_level; - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return level; } @@ -411,9 +411,9 @@ static uint32_t pp_dpm_get_sclk(void *handle, bool low) pr_info("%s was not implemented.\n", __func__); return 0; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); clk = hwmgr->hwmgr_func->get_sclk(hwmgr, low); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return clk; } @@ -429,9 +429,9 @@ static uint32_t pp_dpm_get_mclk(void *handle, bool low) pr_info("%s was not implemented.\n", __func__); return 0; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); clk = hwmgr->hwmgr_func->get_mclk(hwmgr, low); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return clk; } @@ -446,9 +446,9 @@ static void pp_dpm_powergate_vce(void *handle, bool gate) pr_info("%s was not implemented.\n", __func__); return; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr->hwmgr_func->powergate_vce(hwmgr, gate); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); } static void pp_dpm_powergate_uvd(void *handle, bool gate) @@ -462,9 +462,9 @@ static void pp_dpm_powergate_uvd(void *handle, bool gate) pr_info("%s was not implemented.\n", __func__); return; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); } static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, @@ -476,9 +476,9 @@ static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, if (!hwmgr || !hwmgr->pm_en) return -EINVAL; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); ret = hwmgr_handle_task(hwmgr, task_id, user_state); - mutex_unlock(>smu_lock); + spin_unlock(>
[PATCH] drm/amdgpu: avoid sleep while executing atombios table (V2)
This patch replaces kzalloc's flag from GFP_KERNEL to GFP_ATOMIC to avoid sleeping in atomic context. Below is the stack trace: BUG: sleeping function called from invalid context at mm/slab.h:*** in_atomic(): 1, irqs_disabled(): 0, pid: 1137, name: DrmThread CPU: 1 PID: 1137 Comm: DrmThread Tainted: GW 4.14.43 #10 Call Trace: dump_stack+0x4d/0x63 ___might_sleep+0x11f/0x12e __kmalloc+0x76/0x126 amdgpu_atom_execute_table_locked+0xfc/0x285 amdgpu_atom_execute_table+0x5d/0x72 transmitter_control_v1_5+0xef/0x11a hwss_edp_backlight_control+0x132/0x151 dce110_disable_stream+0x133/0x16e core_link_disable_stream+0x1c5/0x23b dce110_reset_hw_ctx_wrap+0xb4/0x1aa dce110_apply_ctx_to_hw+0x4e/0x6da ? generic_reg_get+0x1f/0x33 dc_commit_state+0x33f/0x3d2 amdgpu_dm_atomic_commit_tail+0x2cf/0x5d2 ? wait_for_common+0x5b/0x69 commit_tail+0x42/0x64 drm_atomic_helper_commit+0xdc/0xf9 drm_atomic_helper_set_config+0x5c/0x76 __drm_mode_set_config_internal+0x64/0x105 drm_mode_setcrtc+0x474/0x56f ? drm_mode_getcrtc+0x155/0x155 drm_ioctl_kernel+0x6c/0xa8 drm_ioctl+0x267/0x353 ? drm_mode_getcrtc+0x155/0x155 amdgpu_drm_ioctl+0x4f/0x7f vfs_ioctl+0x21/0x2f do_vfs_ioctl+0x4c4/0x4e7 ? security_file_ioctl+0x3b/0x4f SyS_ioctl+0x57/0x79 do_syscall_64+0x64/0x72 entry_SYSCALL_64_after_hwframe+0x3d/0xa2 V2: Added stack trace in commit message. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/atom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index bfd98f0..da4558c 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1221,7 +1221,7 @@ static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, ectx.abort = false; ectx.last_jump = 0; if (ws) - ectx.ws = kzalloc(4 * ws, GFP_KERNEL); + ectx.ws = kzalloc(4 * ws, GFP_ATOMIC); else ectx.ws = NULL; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: avoid sleeping in atomic context while creating new state (V2)
This patch fixes the warning messages that are caused due to calling sleep in atomic context as below: BUG: sleeping function called from invalid context at mm/slab.h:419 in_atomic(): 1, irqs_disabled(): 1, pid: 5, name: kworker/u4:0 CPU: 1 PID: 5 Comm: kworker/u4:0 Tainted: GW 4.14.35 #941 Workqueue: events_unbound commit_work Call Trace: dump_stack+0x4d/0x63 ___might_sleep+0x11f/0x12e kmem_cache_alloc_trace+0x41/0xea dc_create_state+0x1f/0x30 dc_commit_updates_for_stream+0x73/0x4cf ? amdgpu_get_crtc_scanoutpos+0x82/0x16b amdgpu_dm_do_flip+0x239/0x298 amdgpu_dm_commit_planes.isra.23+0x379/0x54b ? dc_commit_state+0x3da/0x404 amdgpu_dm_atomic_commit_tail+0x4fc/0x5d2 ? wait_for_common+0x5b/0x69 commit_tail+0x42/0x64 process_one_work+0x1b0/0x314 worker_thread+0x1cb/0x2c1 ? create_worker+0x1da/0x1da kthread+0x156/0x15e ? kthread_flush_work+0xea/0xea ret_from_fork+0x22/0x40 V2: fix applicable only to dc_create_state() and not dc_create(). Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index c88f661..839e3f6 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -953,7 +953,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) struct dc_state *dc_create_state(void) { struct dc_state *context = kzalloc(sizeof(struct dc_state), - GFP_KERNEL); + GFP_ATOMIC); if (!context) return NULL; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu/pp: replace mutex with spin_lock
This patch replaces usage of mutex with spin_lock to avoid sleep in atomic context. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 152 +- drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 +- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index b493369..2d9c120 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -183,10 +183,10 @@ static int pp_late_init(void *handle) int ret; if (hwmgr && hwmgr->pm_en) { - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr_handle_task(hwmgr, AMD_PP_TASK_COMPLETE_INIT, NULL); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); } if (adev->pm.smu_prv_buffer_size != 0) pp_reserve_vram_for_smu(adev); @@ -375,11 +375,11 @@ static int pp_dpm_force_performance_level(void *handle, if (level == hwmgr->dpm_level) return 0; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); pp_dpm_en_umd_pstate(hwmgr, ); hwmgr->request_dpm_level = level; hwmgr_handle_task(hwmgr, AMD_PP_TASK_READJUST_POWER_STATE, NULL); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return 0; } @@ -393,9 +393,9 @@ static enum amd_dpm_forced_level pp_dpm_get_performance_level( if (!hwmgr || !hwmgr->pm_en) return -EINVAL; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); level = hwmgr->dpm_level; - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return level; } @@ -411,9 +411,9 @@ static uint32_t pp_dpm_get_sclk(void *handle, bool low) pr_info("%s was not implemented.\n", __func__); return 0; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); clk = hwmgr->hwmgr_func->get_sclk(hwmgr, low); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return clk; } @@ -429,9 +429,9 @@ static uint32_t pp_dpm_get_mclk(void *handle, bool low) pr_info("%s was not implemented.\n", __func__); return 0; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); clk = hwmgr->hwmgr_func->get_mclk(hwmgr, low); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return clk; } @@ -446,9 +446,9 @@ static void pp_dpm_powergate_vce(void *handle, bool gate) pr_info("%s was not implemented.\n", __func__); return; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr->hwmgr_func->powergate_vce(hwmgr, gate); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); } static void pp_dpm_powergate_uvd(void *handle, bool gate) @@ -462,9 +462,9 @@ static void pp_dpm_powergate_uvd(void *handle, bool gate) pr_info("%s was not implemented.\n", __func__); return; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); } static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, @@ -476,9 +476,9 @@ static int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_task task_id, if (!hwmgr || !hwmgr->pm_en) return -EINVAL; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); ret = hwmgr_handle_task(hwmgr, task_id, user_state); - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return ret; } @@ -492,7 +492,7 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle) if (!hwmgr || !hwmgr->pm_en || !hwmgr->current_ps) return -EINVAL; - mutex_lock(>smu_lock); + spin_lock(>smu_lock); state = hwmgr->current_ps; @@ -513,7 +513,7 @@ static enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle) pm_type = POWER_STATE_TYPE_DEFAULT; break; } - mutex_unlock(>smu_lock); + spin_unlock(>smu_lock); return pm_type; } @@ -529,9 +529,9 @@ static void pp_dpm_set_fan_control_mode(void *handle, uint32_t mode) pr_info("%s was not implemented.\n", __func__); return; } - mutex_lock(>smu_lock); + spin_lock(>smu_lock); hwmgr->hwmgr_func->set_fan_control_mode(hwmgr, mode); - mutex_unlock(>smu_lock);
[PATCH] drm/amdgpu: replace mutex with spin_lock
mutex's lead to sleeps which should be avoided in atomic context. Hence this patch replaces it with the spin_locks. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 2 +- drivers/gpu/drm/amd/amdgpu/atom.c| 4 ++-- drivers/gpu/drm/amd/amdgpu/atom.h| 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index bf872f6..ba3d4b9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -2033,7 +2033,7 @@ int amdgpu_atombios_init(struct amdgpu_device *adev) return -ENOMEM; } - mutex_init(>mode_info.atom_context->mutex); + spin_lock_init(>mode_info.atom_context->lock); if (adev->is_atom_fw) { amdgpu_atomfirmware_scratch_regs_init(adev); amdgpu_atomfirmware_allocate_fb_scratch(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index 69500a8..bfd98f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1261,7 +1261,7 @@ int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * pa { int r; - mutex_lock(>mutex); + spin_lock(>lock); /* reset data block */ ctx->data_block = 0; /* reset reg block */ @@ -1274,7 +1274,7 @@ int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t * pa ctx->divmul[0] = 0; ctx->divmul[1] = 0; r = amdgpu_atom_execute_table_locked(ctx, index, params); - mutex_unlock(>mutex); + spin_unlock(>lock); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h index a391709..cdfb0d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.h +++ b/drivers/gpu/drm/amd/amdgpu/atom.h @@ -26,6 +26,7 @@ #define ATOM_H #include +#include #include #define ATOM_BIOS_MAGIC0xAA55 @@ -125,7 +126,7 @@ struct card_info { struct atom_context { struct card_info *card; - struct mutex mutex; + spinlock_t lock; void *bios; uint32_t cmd_table, data_table; uint16_t *iio; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: avoid sleep while executing atombios table
This patch replaces kzalloc's flag from GFP_KERNEL to GFP_ATOMIC to avoid sleeping in atomic context. Signed-off-by: Shirish S --- drivers/gpu/drm/amd/amdgpu/atom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index bfd98f0..da4558c 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1221,7 +1221,7 @@ static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, ectx.abort = false; ectx.last_jump = 0; if (ws) - ectx.ws = kzalloc(4 * ws, GFP_KERNEL); + ectx.ws = kzalloc(4 * ws, GFP_ATOMIC); else ectx.ws = NULL; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: avoid sleeping in atomic context while creating new context or state
This patch fixes the warning messages that are caused due to calling sleep in atomic context as below: BUG: sleeping function called from invalid context at mm/slab.h:419 in_atomic(): 1, irqs_disabled(): 1, pid: 5, name: kworker/u4:0 CPU: 1 PID: 5 Comm: kworker/u4:0 Tainted: GW 4.14.35 #941 Workqueue: events_unbound commit_work Call Trace: dump_stack+0x4d/0x63 ___might_sleep+0x11f/0x12e kmem_cache_alloc_trace+0x41/0xea dc_create_state+0x1f/0x30 dc_commit_updates_for_stream+0x73/0x4cf ? amdgpu_get_crtc_scanoutpos+0x82/0x16b amdgpu_dm_do_flip+0x239/0x298 amdgpu_dm_commit_planes.isra.23+0x379/0x54b ? dc_commit_state+0x3da/0x404 amdgpu_dm_atomic_commit_tail+0x4fc/0x5d2 ? wait_for_common+0x5b/0x69 commit_tail+0x42/0x64 process_one_work+0x1b0/0x314 worker_thread+0x1cb/0x2c1 ? create_worker+0x1da/0x1da kthread+0x156/0x15e ? kthread_flush_work+0xea/0xea ret_from_fork+0x22/0x40 Signed-off-by: Shirish S --- drivers/gpu/drm/amd/display/dc/core/dc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 33149ed..d62206f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -588,7 +588,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context) struct dc *dc_create(const struct dc_init_data *init_params) { - struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL); + struct dc *dc = kzalloc(sizeof(*dc), GFP_ATOMIC); unsigned int full_pipe_count; if (NULL == dc) @@ -937,7 +937,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc) struct dc_state *dc_create_state(void) { struct dc_state *context = kzalloc(sizeof(struct dc_state), - GFP_KERNEL); + GFP_ATOMIC); if (!context) return NULL; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: remove need of modeset flag for overlay planes (V2)
This patch is in continuation to the "843e3c7 drm/amd/display: defer modeset check in dm_update_planes_state" where we started to eliminate the dependency on DRM_MODE_ATOMIC_ALLOW_MODESET to be set by the user space, which as such is not mandatory. After deferring, this patch eliminates the dependency on the flag for overlay planes. This has to be done in stages as its a pretty complex and requires thorough testing before we free primary planes as well from dependency on modeset flag. V2: Simplified the plane type check. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +--- 1 file changed, 5 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 1a63c04..045e5df 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4174,7 +4174,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, } spin_unlock_irqrestore(>dev->event_lock, flags); - if (!pflip_needed) { + if (!pflip_needed || plane->type == DRM_PLANE_TYPE_OVERLAY) { WARN_ON(!dm_new_plane_state->dc_state); plane_states_constructed[planes_count] = dm_new_plane_state->dc_state; @@ -4884,7 +4884,8 @@ static int dm_update_planes_state(struct dc *dc, /* Remove any changed/removed planes */ if (!enable) { - if (pflip_needed) + if (pflip_needed && + plane->type != DRM_PLANE_TYPE_OVERLAY) continue; if (!old_plane_crtc) @@ -4931,7 +4932,8 @@ static int dm_update_planes_state(struct dc *dc, if (!dm_new_crtc_state->stream) continue; - if (pflip_needed) + if (pflip_needed && + plane->type != DRM_PLANE_TYPE_OVERLAY) continue; WARN_ON(dm_new_plane_state->dc_state); -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: disable FBC on underlay pipe
FBC is not applicable for the underlay pipe, hence disallow enabling and disabling of the same. This also fixes the BUG hit of calling sleep in atomic context. Signed-off-by: Shirish S <shiris...@amd.com> Reviewed-by: Roman Li <roman...@amd.com> --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 5dbd433..64d0bca 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2765,6 +2765,9 @@ static void dce110_program_front_end_for_pipe( struct dc_plane_state *plane_state = pipe_ctx->plane_state; struct xfm_grph_csc_adjustment adjust; struct out_csc_color_matrix tbl_entry; +#if defined(CONFIG_DRM_AMD_DC_FBC) + unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; +#endif unsigned int i; DC_LOGGER_INIT(); memset(_entry, 0, sizeof(tbl_entry)); @@ -2806,7 +2809,9 @@ static void dce110_program_front_end_for_pipe( program_scaler(dc, pipe_ctx); #if defined(CONFIG_DRM_AMD_DC_FBC) - if (dc->fbc_compressor && old_pipe->stream) { + /* fbc not applicable on Underlay pipe */ + if (dc->fbc_compressor && old_pipe->stream && + pipe_ctx->pipe_idx != underlay_idx) { if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); else -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: disable FBC on underlay pipe
FBC is not applicable for the underlay pipe, hence disallow enabling and disabling of the same. This also fixes the BUG hit of calling sleep in atomic context. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 5dbd433..64d0bca 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2765,6 +2765,9 @@ static void dce110_program_front_end_for_pipe( struct dc_plane_state *plane_state = pipe_ctx->plane_state; struct xfm_grph_csc_adjustment adjust; struct out_csc_color_matrix tbl_entry; +#if defined(CONFIG_DRM_AMD_DC_FBC) + unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; +#endif unsigned int i; DC_LOGGER_INIT(); memset(_entry, 0, sizeof(tbl_entry)); @@ -2806,7 +2809,9 @@ static void dce110_program_front_end_for_pipe( program_scaler(dc, pipe_ctx); #if defined(CONFIG_DRM_AMD_DC_FBC) - if (dc->fbc_compressor && old_pipe->stream) { + /* fbc not applicable on Unerlay pipe */ + if (dc->fbc_compressor && old_pipe->stream && + pipe_ctx->pipe_idx != underlay_idx) { if (plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); else -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: remove need of modeset flag for overlay planes
This patch is in continuation to the "843e3c7 drm/amd/display: defer modeset check in dm_update_planes_state" where we started to eliminate the dependency on DRM_MODE_ATOMIC_ALLOW_MODESET to be set by the user space, which as such is not mandatory. After deferring, this patch eliminates the dependency on the flag for overlay planes. This has to be done in stages as its a pretty complex and requires thorough testing before we free primary planes as well from dependency on modeset flag. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +--- 1 file changed, 5 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 1a63c04..87b661d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4174,7 +4174,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, } spin_unlock_irqrestore(>dev->event_lock, flags); - if (!pflip_needed) { + if (!pflip_needed || plane->type == DRM_PLANE_TYPE_OVERLAY) { WARN_ON(!dm_new_plane_state->dc_state); plane_states_constructed[planes_count] = dm_new_plane_state->dc_state; @@ -4884,7 +4884,8 @@ static int dm_update_planes_state(struct dc *dc, /* Remove any changed/removed planes */ if (!enable) { - if (pflip_needed) + if (pflip_needed && + plane && plane->type != DRM_PLANE_TYPE_OVERLAY) continue; if (!old_plane_crtc) @@ -4931,7 +4932,8 @@ static int dm_update_planes_state(struct dc *dc, if (!dm_new_crtc_state->stream) continue; - if (pflip_needed) + if (pflip_needed && + plane && plane->type != DRM_PLANE_TYPE_OVERLAY) continue; WARN_ON(dm_new_plane_state->dc_state); -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: fix return value of dm_dp_aux_transfer() (V2)
Currently the dm_dp_aux_transfer() does not parse the return value of dal_ddc_service_read_dpcd_data(), which also has a failure case. This patch captures the same and ensures the i2c operation status is sent appropriately to the drm framework. V2: Updated commit message. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 782491e..7ac124d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -115,7 +115,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, msg->address, msg->buffer, msg->size); - return read_bytes; + if (read_bytes != msg->size && + read_bytes >= DDC_RESULT_FAILED_OPERATION) + return -EIO; + else + return read_bytes; case DP_AUX_I2C_WRITE: res = dal_ddc_service_write_dpcd_data( TO_DM_AUX(aux)->ddc_service, -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: introduce quirks for i2c adaptor
The dp aux channel cannot read messages of size greater than 16 bytes, this patch adds quirks feild accordingly at the initialization of the adaptor. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 782491e..f7d6d9a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -464,10 +464,15 @@ static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { .register_connector = dm_dp_mst_register_connector }; +/* I2C adapter quirks, max read len is 16 bytes. */ +static const struct i2c_adapter_quirks dm_dp_aux_quirks = { + .max_read_len = 128, +}; void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, struct amdgpu_dm_connector *aconnector) { aconnector->dm_dp_aux.aux.name = "dmdc"; + aconnector->dm_dp_aux.aux.ddc.quirks = _dp_aux_quirks; aconnector->dm_dp_aux.aux.dev = dm->adev->dev; aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer; aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: fix return value of dm_dp_aux_transfer()
Currently the dm_dp_aux_transfer() does not parse the return value of dal_ddc_service_read_dpcd_data(), which also has a failure case. This patch captures the same and ensures the i2c operation status is sent provided appropriately to the callers to it. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 782491e..7ac124d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -115,7 +115,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, msg->address, msg->buffer, msg->size); - return read_bytes; + if (read_bytes != msg->size && + read_bytes >= DDC_RESULT_FAILED_OPERATION) + return -EIO; + else + return read_bytes; case DP_AUX_I2C_WRITE: res = dal_ddc_service_write_dpcd_data( TO_DM_AUX(aux)->ddc_service, -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: defer test IBs on the rings at boot (V3)
amdgpu_ib_ring_tests() runs test IB's on rings at boot contributes to ~500 ms of amdgpu driver's boot time. This patch defers it and ensures that its executed in amdgpu_info_ioctl() if it wasn't scheduled. V2: Use queue_delayed_work() & flush_delayed_work(). V3: removed usage of separate wq, ensure ib tests is run before enabling clockgating. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 17 ++--- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c| 3 +++ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 1762eb4..f225840 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1656,6 +1656,10 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) if (amdgpu_emu_mode == 1) return 0; + r = amdgpu_ib_ring_tests(adev); + if (r) + DRM_ERROR("ib ring test failed (%d).\n", r); + for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.valid) continue; @@ -1706,8 +1710,8 @@ static int amdgpu_device_ip_late_init(struct amdgpu_device *adev) } } - mod_delayed_work(system_wq, >late_init_work, - msecs_to_jiffies(AMDGPU_RESUME_MS)); + queue_delayed_work(system_wq, >late_init_work, + msecs_to_jiffies(AMDGPU_RESUME_MS)); amdgpu_device_fill_reset_magic(adev); @@ -2374,10 +2378,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, goto failed; } - r = amdgpu_ib_ring_tests(adev); - if (r) - DRM_ERROR("ib ring test failed (%d).\n", r); - if (amdgpu_sriov_vf(adev)) amdgpu_virt_init_data_exchange(adev); @@ -2640,11 +2640,6 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon) amdgpu_fence_driver_resume(adev); - if (resume) { - r = amdgpu_ib_ring_tests(adev); - if (r) - DRM_ERROR("ib ring test failed (%d).\n", r); - } r = amdgpu_device_ip_late_init(adev); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 487d39e..83d7160 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -279,6 +279,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file if (!info->return_size || !info->return_pointer) return -EINVAL; + /* Ensure IB tests are run on ring */ + flush_delayed_work(>late_init_work); + switch (info->query) { case AMDGPU_INFO_ACCEL_WORKING: ui32 = adev->accel_working; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: defer test IBs on the rings at boot (V2)
amdgpu_ib_ring_tests() runs test IB's on rings at boot contributes to ~500 ms of amdgpu driver's boot time. This patch defers it and ensures that its executed in amdgpu_info_ioctl() if it wasn't scheduled. V2: Use queue_delayed_work() & flush_delayed_work(). Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 20 +--- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c| 4 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 5734871..ae8f722 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1611,6 +1611,8 @@ struct amdgpu_device { /* delayed work_func for deferring clockgating during resume */ struct delayed_work late_init_work; + /* delayed work_func to defer testing IB's on rings during boot */ + struct delayed_work late_init_test_ib_work; struct amdgpu_virt virt; /* firmware VRAM reservation */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 1762eb4..ee84058 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -63,6 +63,7 @@ MODULE_FIRMWARE("amdgpu/vega12_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); #define AMDGPU_RESUME_MS 2000 +#define AMDGPU_IB_TEST_SCHED_MS2000 static const char *amdgpu_asic_name[] = { "TAHITI", @@ -2105,6 +2106,16 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) } } +static void amdgpu_device_late_init_test_ib_func_handler(struct work_struct *work) +{ + struct amdgpu_device *adev = + container_of(work, struct amdgpu_device, late_init_test_ib_work.work); + int r = amdgpu_ib_ring_tests(adev); + + if (r) + DRM_ERROR("ib ring test failed (%d).\n", r); +} + /** * amdgpu_device_has_dc_support - check if dc is supported * @@ -2212,6 +2223,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, INIT_LIST_HEAD(>ring_lru_list); spin_lock_init(>ring_lru_list_lock); + INIT_DELAYED_WORK(>late_init_test_ib_work, + amdgpu_device_late_init_test_ib_func_handler); INIT_DELAYED_WORK(>late_init_work, amdgpu_device_ip_late_init_func_handler); @@ -2374,9 +2387,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, goto failed; } - r = amdgpu_ib_ring_tests(adev); - if (r) - DRM_ERROR("ib ring test failed (%d).\n", r); + /* Schedule amdgpu_ib_ring_tests() */ + queue_delayed_work(system_wq, >late_init_test_ib_work, + msecs_to_jiffies(AMDGPU_IB_TEST_SCHED_MS)); if (amdgpu_sriov_vf(adev)) amdgpu_virt_init_data_exchange(adev); @@ -2469,6 +2482,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) } adev->accel_working = false; cancel_delayed_work_sync(>late_init_work); + cancel_delayed_work_sync(>late_init_test_ib_work); /* free i2c buses */ if (!amdgpu_device_has_dc_support(adev)) amdgpu_i2c_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 487d39e..6fa326b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -279,6 +279,10 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file if (!info->return_size || !info->return_pointer) return -EINVAL; + /* Ensure IB tests on ring are executed */ + if (delayed_work_pending(>late_init_test_ib_work)) + flush_delayed_work(>late_init_test_ib_work); + switch (info->query) { case AMDGPU_INFO_ACCEL_WORKING: ui32 = adev->accel_working; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: defer test IBs on the rings at boot
amdgpu_ib_ring_tests() runs test IB's on rings at boot contributes to ~500 ms of amdgpu driver's boot time. This patch defers it and adds a check to report in amdgpu_info_ioctl() if it was scheduled or not. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h| 2 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 20 +--- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c| 3 +++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 5734871..ae8f722 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1611,6 +1611,8 @@ struct amdgpu_device { /* delayed work_func for deferring clockgating during resume */ struct delayed_work late_init_work; + /* delayed work_func to defer testing IB's on rings during boot */ + struct delayed_work late_init_test_ib_work; struct amdgpu_virt virt; /* firmware VRAM reservation */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 1762eb4..e65a5e6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -63,6 +63,7 @@ MODULE_FIRMWARE("amdgpu/vega12_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); #define AMDGPU_RESUME_MS 2000 +#define AMDGPU_IB_TEST_SCHED_MS2000 static const char *amdgpu_asic_name[] = { "TAHITI", @@ -2105,6 +2106,16 @@ bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type) } } +static void amdgpu_device_late_init_test_ib_func_handler(struct work_struct *work) +{ + struct amdgpu_device *adev = + container_of(work, struct amdgpu_device, late_init_test_ib_work.work); + int r = amdgpu_ib_ring_tests(adev); + + if (r) + DRM_ERROR("ib ring test failed (%d).\n", r); +} + /** * amdgpu_device_has_dc_support - check if dc is supported * @@ -2212,6 +2223,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, INIT_LIST_HEAD(>ring_lru_list); spin_lock_init(>ring_lru_list_lock); + INIT_DELAYED_WORK(>late_init_test_ib_work, + amdgpu_device_late_init_test_ib_func_handler); INIT_DELAYED_WORK(>late_init_work, amdgpu_device_ip_late_init_func_handler); @@ -2374,9 +2387,9 @@ int amdgpu_device_init(struct amdgpu_device *adev, goto failed; } - r = amdgpu_ib_ring_tests(adev); - if (r) - DRM_ERROR("ib ring test failed (%d).\n", r); + /* Schedule amdgpu_ib_ring_tests() */ + mod_delayed_work(system_wq, >late_init_test_ib_work, + msecs_to_jiffies(AMDGPU_IB_TEST_SCHED_MS)); if (amdgpu_sriov_vf(adev)) amdgpu_virt_init_data_exchange(adev); @@ -2469,6 +2482,7 @@ void amdgpu_device_fini(struct amdgpu_device *adev) } adev->accel_working = false; cancel_delayed_work_sync(>late_init_work); + cancel_delayed_work_sync(>late_init_test_ib_work); /* free i2c buses */ if (!amdgpu_device_has_dc_support(adev)) amdgpu_i2c_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 487d39e..057bd9a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -279,6 +279,9 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file if (!info->return_size || !info->return_pointer) return -EINVAL; + if (delayed_work_pending(>late_init_test_ib_work)) + DRM_ERROR("IB test on ring not executed\n"); + switch (info->query) { case AMDGPU_INFO_ACCEL_WORKING: ui32 = adev->accel_working; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: defer initing UVD & VCE IP blocks
UVD & VCE blocks take up around 1200 msecs of boot time. This patch adds them to the late init work function so as to reduce boot time. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 28 ++-- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 0e798b3..54f1320 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1589,7 +1589,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.sw) continue; - if (adev->ip_blocks[i].status.hw) + if (adev->ip_blocks[i].status.hw || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_UVD || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_VCE) continue; r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev); if (r) { @@ -1639,17 +1641,18 @@ static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev) } /** - * amdgpu_device_ip_late_set_cg_state - late init for clockgating + * amdgpu_late_init_ip_blocks - late init of some IP blocks and clockgating * * @adev: amdgpu_device pointer * - * Late initialization pass enabling clockgating for hardware IPs. + * Late initialization pass for high time consuming IP blocks like UVD & VCE + * along with enabling clockgating for hardware IPs. * The list of all the hardware IPs that make up the asic is walked and the * set_clockgating_state callbacks are run. This stage is run late * in the init process. * Returns 0 on success, negative error code on failure. */ -static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) +static int amdgpu_late_init_ip_blocks(struct amdgpu_device *adev) { int i = 0, r; @@ -1657,6 +1660,19 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) return 0; for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.hw && + (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_UVD || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_VCE)) { + r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev); + if (r) { + DRM_ERROR("hw_init of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + return r; + } + + adev->ip_blocks[i].status.hw = true; + } + if (!adev->ip_blocks[i].status.valid) continue; /* skip CG for VCE/UVD, it's handled specially */ @@ -1823,7 +1839,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) * * @work: work_struct * - * Work handler for amdgpu_device_ip_late_set_cg_state. We put the + * Work handler for amdgpu_late_init_ip_blocks. We put the * clockgating setup into a worker thread to speed up driver init and * resume from suspend. */ @@ -1831,7 +1847,7 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) { struct amdgpu_device *adev = container_of(work, struct amdgpu_device, late_init_work.work); - amdgpu_device_ip_late_set_cg_state(adev); + amdgpu_late_init_ip_blocks(adev); } /** -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: defer initing UVD & VCE IP blocks
UVD & VCE blocks take up around 1200 msecs of boot time. This patch adds them to the late init work function so as to reduce boot time. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 28 ++-- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 0e798b3..54f1320 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1589,7 +1589,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.sw) continue; - if (adev->ip_blocks[i].status.hw) + if (adev->ip_blocks[i].status.hw || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_UVD || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_VCE) continue; r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev); if (r) { @@ -1639,17 +1641,18 @@ static bool amdgpu_device_check_vram_lost(struct amdgpu_device *adev) } /** - * amdgpu_device_ip_late_set_cg_state - late init for clockgating + * amdgpu_late_init_ip_blocks - late init of some IP blocks and clockgating * * @adev: amdgpu_device pointer * - * Late initialization pass enabling clockgating for hardware IPs. + * Late initialization pass for high time consuming IP blocks like UVD & VCE + * along with enabling clockgating for hardware IPs. * The list of all the hardware IPs that make up the asic is walked and the * set_clockgating_state callbacks are run. This stage is run late * in the init process. * Returns 0 on success, negative error code on failure. */ -static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) +static int amdgpu_late_init_ip_blocks(struct amdgpu_device *adev) { int i = 0, r; @@ -1657,6 +1660,19 @@ static int amdgpu_device_ip_late_set_cg_state(struct amdgpu_device *adev) return 0; for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].status.hw && + (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_UVD || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_VCE)) { + r = adev->ip_blocks[i].version->funcs->hw_init((void *)adev); + if (r) { + DRM_ERROR("hw_init of IP block <%s> failed %d\n", + adev->ip_blocks[i].version->funcs->name, r); + return r; + } + + adev->ip_blocks[i].status.hw = true; + } + if (!adev->ip_blocks[i].status.valid) continue; /* skip CG for VCE/UVD, it's handled specially */ @@ -1823,7 +1839,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) * * @work: work_struct * - * Work handler for amdgpu_device_ip_late_set_cg_state. We put the + * Work handler for amdgpu_late_init_ip_blocks. We put the * clockgating setup into a worker thread to speed up driver init and * resume from suspend. */ @@ -1831,7 +1847,7 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work) { struct amdgpu_device *adev = container_of(work, struct amdgpu_device, late_init_work.work); - amdgpu_device_ip_late_set_cg_state(adev); + amdgpu_late_init_ip_blocks(adev); } /** -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: remove dummy is_blanked() to optimise boot time
is_blanked() hook is a dummy one for underlay pipe, hence when called, it loops for ~300ms at boot. This patch removes this dummy call and adds missing checks. Signed-off-by: Shirish S <shiris...@amd.com> Reviewed-by: Harry Wentland <harry.wentl...@amd.com> --- drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 3 +++ drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c| 3 ++- drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c | 7 --- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index ebc96b7..481f692 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -230,6 +230,9 @@ bool hwss_wait_for_blank_complete( { int counter; + /* Not applicable if the pipe is not primary, save 300ms of boot time */ + if (!tg->funcs->is_blanked) + return true; for (counter = 0; counter < 100; counter++) { if (tg->funcs->is_blanked(tg)) break; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c index 4877243..0275d6d 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_hwseq.c @@ -53,7 +53,8 @@ void dce_pipe_control_lock(struct dc *dc, struct dce_hwseq *hws = dc->hwseq; /* Not lock pipe when blank */ - if (lock && pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg)) + if (lock && pipe->stream_res.tg->funcs->is_blanked && + pipe->stream_res.tg->funcs->is_blanked(pipe->stream_res.tg)) return; val = REG_GET_4(BLND_V_UPDATE_LOCK[pipe->stream_res.tg->inst], diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c index 8ad0481..a3cef60 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_timing_generator_v.c @@ -648,12 +648,6 @@ static void dce110_timing_generator_v_disable_vga( return; } -static bool dce110_tg_v_is_blanked(struct timing_generator *tg) -{ - /* Signal comes from the primary pipe, underlay is never blanked. */ - return false; -} - /** * * DCE11 Timing Generator Constructor / Destructor @@ -670,7 +664,6 @@ static const struct timing_generator_funcs dce110_tg_v_funcs = { .set_early_control = dce110_timing_generator_v_set_early_control, .wait_for_state = dce110_timing_generator_v_wait_for_state, .set_blank = dce110_timing_generator_v_set_blank, - .is_blanked = dce110_tg_v_is_blanked, .set_colors = dce110_timing_generator_v_set_colors, .set_overscan_blank_color = dce110_timing_generator_v_set_overscan_color_black, -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: fix dereferencing possible ERR_PTR()
This patch fixes static checker warning caused by "36cc549d5986: "drm/amd/display: disable CRTCs with NULL FB on their primary plane (V2)" Reported-by: Dan Carpenter <dan.carpen...@oracle.com> Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ 1 file changed, 3 insertions(+) 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 0564676..9e2cdc9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4893,6 +4893,9 @@ static int dm_atomic_check_plane_state_fb(struct drm_atomic_state *state, return -EDEADLK; crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + if (crtc->primary == plane && crtc_state->active) { if (!plane_state->fb) return -EINVAL; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: Check msg->size before starting aux transfer
This patch adds an essential check related to the size of the payload to be transferred via aux channel. Without this check dal_ddc_service_read_dpcd_data() is fed with inappropriate payload size leading to deadlocks. Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 39cfe0f..8291d74 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -85,6 +85,9 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, enum ddc_result res; ssize_t read_bytes; + if (WARN_ON(msg->size > 16)) + return -E2BIG; + switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_READ: read_bytes = dal_ddc_service_read_dpcd_data( -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/display: validate plane format on primary plane
In dce110, the plane configuration is such that plane 0 or the primary plane should be rendered with only RGB data. This patch adds the validation to ensure that no video data is rendered on plane 0. Signed-off-by: Shirish S <shiris...@amd.com> Reviewed-by: Tony Cheng <tony.ch...@amd.com> --- drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 830cbbc..b1f14be 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -879,6 +879,13 @@ static bool dce110_validate_surface_sets( plane->src_rect.height > 1080)) return false; + /* we don't have the logic to support underlay +* only yet so block the use case where we get +* NV12 plane as top layer +*/ + if (j == 0) + return false; + /* irrespective of plane format, * stream should be RGB encoded */ -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/atomic: Add new reverse iterator over all plane state (V2)
Add reverse iterator for_each_oldnew_plane_in_state_reverse to compliment the for_each_oldnew_plane_in_state way or reading plane states. The plane states are required to be read in reverse order for amd drivers, cause the z order convention followed in linux is opposite to how the planes are supposed to be presented to DC engine, which is in common to both windows and linux. V2: fix compile time errors due to -Werror flag. Signed-off-by: Shirish S <shiris...@amd.com> Signed-off-by: Pratik Vishwakarma <pratik.vishwaka...@amd.com> Reviewed-by: Daniel Vetter <daniel.vet...@ffwll.ch> --- include/drm/drm_atomic.h | 22 ++ 1 file changed, 22 insertions(+) diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index cf13842..3fe8dde 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -754,6 +754,28 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (new_plane_state) = (__state)->planes[__i].new_state, 1)) /** + * for_each_oldnew_plane_in_state_reverse - iterate over all planes in an atomic + * update in reverse order + * @__state: drm_atomic_state pointer + * @plane: drm_plane iteration cursor + * @old_plane_state: drm_plane_state iteration cursor for the old state + * @new_plane_state: drm_plane_state iteration cursor for the new state + * @__i: int iteration cursor, for macro-internal use + * + * This iterates over all planes in an atomic update in reverse order, + * tracking both old and new state. This is useful in places where the + * state delta needs to be considered, for example in atomic check functions. + */ +#define for_each_oldnew_plane_in_state_reverse(__state, plane, old_plane_state, new_plane_state, __i) \ + for ((__i) = ((__state)->dev->mode_config.num_total_plane - 1); \ +(__i) >= 0;\ +(__i)--) \ + for_each_if ((__state)->planes[__i].ptr && \ +((plane) = (__state)->planes[__i].ptr, \ + (old_plane_state) = (__state)->planes[__i].old_state,\ + (new_plane_state) = (__state)->planes[__i].new_state, 1)) + +/** * for_each_old_plane_in_state - iterate over all planes in an atomic update * @__state: drm_atomic_state pointer * @plane: drm_plane iteration cursor -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/2] drm/amd/display: update plane functionalities
This patch introduces amdgpu_drm_plane_state structure, which subclasses drm_plane_state and holds data suitable for configuring hardware. It switches reset(), atomic_duplicate_state() & atomic_destroy_state() functions to new internal implementation, earlier they were pointing to drm core functions. TESTS(On Chromium OS on Stoney Only) * Builds without compilation errors. * 'plane_test' passes for XR24 format based Overlay plane. * Chromium OS ui comes up. Signed-off-by: Shirish S <shiris...@amd.com> Reviewed-by: Harry Wentland <harry.wentl...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 13 ++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c| 53 -- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index da3b125..7f2d282 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -56,6 +56,7 @@ struct amdgpu_hpd; #define to_amdgpu_connector(x) container_of(x, struct amdgpu_connector, base) #define to_amdgpu_encoder(x) container_of(x, struct amdgpu_encoder, base) #define to_amdgpu_framebuffer(x) container_of(x, struct amdgpu_framebuffer, base) +#define to_amdgpu_plane(x) container_of(x, struct amdgpu_plane, base) #define AMDGPU_MAX_HPD_PINS 6 #define AMDGPU_MAX_CRTCS 6 @@ -455,6 +456,18 @@ struct amdgpu_crtc { struct drm_pending_vblank_event *event; }; +struct amdgpu_plane_state { + struct drm_plane_state base; + unsigned int h_ratio; + unsigned int v_ratio; +}; + +static inline struct amdgpu_plane_state * +to_amdgpu_plane_state(struct drm_plane_state *state) +{ + return container_of(state, struct amdgpu_plane_state, base); +} + struct amdgpu_plane { struct drm_plane base; enum drm_plane_type plane_type; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c index b35aaae..b694c7b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_types.c @@ -1611,10 +1611,57 @@ const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs = { .atomic_check = dm_encoder_helper_atomic_check }; +static void dm_drm_plane_reset(struct drm_plane *plane) +{ + struct amdgpu_plane_state *amdgpu_state; + + if (plane->state) { + amdgpu_state = to_amdgpu_plane_state(plane->state); + if (amdgpu_state->base.fb) + drm_framebuffer_unreference(amdgpu_state->base.fb); + kfree(amdgpu_state); + plane->state = NULL; + } + + amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL); + if (amdgpu_state) { + plane->state = _state->base; + plane->state->plane = plane; + } +} + +static struct drm_plane_state * +dm_drm_plane_duplicate_state(struct drm_plane *plane) +{ + struct amdgpu_plane_state *amdgpu_state; + struct amdgpu_plane_state *copy; + + amdgpu_state = to_amdgpu_plane_state(plane->state); + copy = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL); + if (!copy) + return NULL; + + __drm_atomic_helper_plane_duplicate_state(plane, >base); + return >base; +} + +static void dm_drm_plane_destroy_state(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct amdgpu_plane_state *old_amdgpu_state = + to_amdgpu_plane_state(old_state); + __drm_atomic_helper_plane_destroy_state(old_state); + kfree(old_amdgpu_state); +} + static const struct drm_plane_funcs dm_plane_funcs = { - .reset = drm_atomic_helper_plane_reset, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy= drm_plane_cleanup, + .set_property = drm_atomic_helper_plane_set_property, + .reset = dm_drm_plane_reset, + .atomic_duplicate_state = dm_drm_plane_duplicate_state, + .atomic_destroy_state = dm_drm_plane_destroy_state, }; static int dm_plane_helper_prepare_fb( -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm: add check for plane functions
On Mon, Mar 20, 2017 at 1:51 PM, Daniel Vetter <dan...@ffwll.ch> wrote: > On Mon, Mar 20, 2017 at 09:58:01AM +0530, Shirish S wrote: >> First of all, thanks for your comments/insights. >> >> On Sat, Mar 18, 2017 at 12:59 AM, Eric Anholt <e...@anholt.net> wrote: >> > Ville Syrjälä <ville.syrj...@linux.intel.com> writes: >> > >> >> On Fri, Mar 17, 2017 at 05:57:52PM +0100, Daniel Vetter wrote: >> >>> On Fri, Mar 17, 2017 at 01:08:43PM +0200, Ville Syrjälä wrote: >> >>> > On Fri, Mar 17, 2017 at 03:46:34PM +0530, Shirish S wrote: >> >>> > > On Fri, Mar 17, 2017 at 3:26 PM, Ville Syrjälä >> >>> > > <ville.syrj...@linux.intel.com> wrote: >> >>> > > > On Fri, Mar 17, 2017 at 01:25:08PM +0530, Shirish S wrote: >> >>> > > >> update_plane() and disable_plane() functions >> >>> > > >> assoiciated with setting plane are called >> >>> > > >> without any check, causing kernel panic. >> >>> > > > >> >>> > > > Why are you registering a plane without the funcs? >> >>> > > > >> >>> > > Basically, enabling planes and making them fully functional is >> >>> > > generally a 2 -step process, >> >>> > > so i suggest for new drivers wanting to implement/re-design planes, >> >>> > > would like to tap >> >>> > > the flow at enabling(listing caps) and later at ensuring it works. >> >>> > >> >>> > I don't think there's much point in exposing something that >> >>> > doesn't work. And even if you do, you could always just use >> >>> > stub functions. >> >>> >> >>> Yes, just wire up stub functions if you want to enable planes with >> >>> multi-step patch series. >> >>> >> >>> > > I noticed that there is a underlying assumption only for >> >>> > > plane->(funcs) are implemented, whereas for >> >>> > > other function for crtc/connector/encoder function calls there is a >> >>> > > sanity check(or WARN_ON) through out the framework. >> >>> > > >> >>> > > I believe this check wont cause any performance/functional impact. >> >>> > > Please let me know if am missing anything. >> >>> > > And further more help developers to focus on enabling planes via >> >>> > > various tests without causing reboots/system hangs. >> >>> > >> >>> > I don't particularly like adding more unconditional runtime checks >> >>> > that just to protect developers from themselves. If you really >> >>> > think there's value in these, then at least add the checks into >> >>> > the plane init codepath so that it's a one time cost. >> >>> > >> All the plane->funcs are guarded before being called , be it: >> late_register() >> early_unregister() >> atomic_destroy_state() etc., >> only update/disable_plane() are called without checking their >> existence, am just extending the protocol. >> >>> > The same approach could be used for all the other non-optional >> >>> > hooks. Otherwise the same WARN_ON()s would have to be sprinkled >> >>> > all over the place, and there's always the risk of missing a few >> >>> > codepaths that call a specific hook. >> >>> >> >>> I think for these here there's negative value - it allows developers to >> >>> create completely broken planes. Stub functions really seem like a much >> >>> better idea. >> >> >> >> I was thinking >> >> >> >> drm_whatever_init() >> >> { >> >> if (WARN_ON(!funcs->mandatory_thing)) >> >> return -EINVAL; >> >> } >> >> >> I think since the motive here is to >> * convey user space that it does not have permissions to >> update/disable available plane due to implementation issues. >> * Keeping system alive/usable after non-permitted call. >> Adding a WARN_ON() trace showing something is missing at boot/insmod >> time, wont solve the purpose. >> >> This development phase here could be setting-up infra for adding a >> plane available on hardware,populate its capabilities >> and to kn
Re: [PATCH] drm: add check for plane functions
First of all, thanks for your comments/insights. On Sat, Mar 18, 2017 at 12:59 AM, Eric Anholt <e...@anholt.net> wrote: > Ville Syrjälä <ville.syrj...@linux.intel.com> writes: > >> On Fri, Mar 17, 2017 at 05:57:52PM +0100, Daniel Vetter wrote: >>> On Fri, Mar 17, 2017 at 01:08:43PM +0200, Ville Syrjälä wrote: >>> > On Fri, Mar 17, 2017 at 03:46:34PM +0530, Shirish S wrote: >>> > > On Fri, Mar 17, 2017 at 3:26 PM, Ville Syrjälä >>> > > <ville.syrj...@linux.intel.com> wrote: >>> > > > On Fri, Mar 17, 2017 at 01:25:08PM +0530, Shirish S wrote: >>> > > >> update_plane() and disable_plane() functions >>> > > >> assoiciated with setting plane are called >>> > > >> without any check, causing kernel panic. >>> > > > >>> > > > Why are you registering a plane without the funcs? >>> > > > >>> > > Basically, enabling planes and making them fully functional is >>> > > generally a 2 -step process, >>> > > so i suggest for new drivers wanting to implement/re-design planes, >>> > > would like to tap >>> > > the flow at enabling(listing caps) and later at ensuring it works. >>> > >>> > I don't think there's much point in exposing something that >>> > doesn't work. And even if you do, you could always just use >>> > stub functions. >>> >>> Yes, just wire up stub functions if you want to enable planes with >>> multi-step patch series. >>> >>> > > I noticed that there is a underlying assumption only for >>> > > plane->(funcs) are implemented, whereas for >>> > > other function for crtc/connector/encoder function calls there is a >>> > > sanity check(or WARN_ON) through out the framework. >>> > > >>> > > I believe this check wont cause any performance/functional impact. >>> > > Please let me know if am missing anything. >>> > > And further more help developers to focus on enabling planes via >>> > > various tests without causing reboots/system hangs. >>> > >>> > I don't particularly like adding more unconditional runtime checks >>> > that just to protect developers from themselves. If you really >>> > think there's value in these, then at least add the checks into >>> > the plane init codepath so that it's a one time cost. >>> > All the plane->funcs are guarded before being called , be it: late_register() early_unregister() atomic_destroy_state() etc., only update/disable_plane() are called without checking their existence, am just extending the protocol. >>> > The same approach could be used for all the other non-optional >>> > hooks. Otherwise the same WARN_ON()s would have to be sprinkled >>> > all over the place, and there's always the risk of missing a few >>> > codepaths that call a specific hook. >>> >>> I think for these here there's negative value - it allows developers to >>> create completely broken planes. Stub functions really seem like a much >>> better idea. >> >> I was thinking >> >> drm_whatever_init() >> { >> if (WARN_ON(!funcs->mandatory_thing)) >> return -EINVAL; >> } >> I think since the motive here is to * convey user space that it does not have permissions to update/disable available plane due to implementation issues. * Keeping system alive/usable after non-permitted call. Adding a WARN_ON() trace showing something is missing at boot/insmod time, wont solve the purpose. This development phase here could be setting-up infra for adding a plane available on hardware,populate its capabilities and to know how user space reads it and tweak it before moving to configuring registers. To add to what @Eric Anholt mentioned, without this patch developer comes to know about the mandatory functions required in a real tough way of panic and system freezes, just because the core framework invokes a NULL function pointer without checking. (Am re-stressing here, that only update/disable planes are exceptions rest all have required checks.) >> rather than putting the WARN_ON()s around each call of >> funcs->mandatory_thing(). >> There are similar checks around every "[crtc/encoder]->funcs->[hooked_up_function specific to vendor]", including plane functions called in drm_plane.c & other places like: drivers/gpu/drm/drm_crtc_helper.c:1074: if (plane->funcs->atomic_duplicate_state)
[PATCH] drm: add check for plane functions
update_plane() and disable_plane() functions assoiciated with setting plane are called without any check, causing kernel panic. This patch adds the required check to avoid it. Change-Id: I0d6792608b33e674c217388aa57c4b7d680d9bc7 Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/drm_plane.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 249c0ae..f675f8b 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -456,6 +456,12 @@ static int __setplane_internal(struct drm_plane *plane, { int ret = 0; + if (plane->funcs->disable_plane == NULL || + plane->funcs->update_plane == NULL) { + DRM_ERROR("plane funcs not implemented\n"); + ret = -EPERM; + goto out; + } /* No fb means shut it down */ if (!fb) { plane->old_fb = plane->fb; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 0/1] Add infrastructure for handling underlay planes
I would like to use this letter to explain what this patche does. (Note its tested on Carrizo & Stoney) * Firstly it decouples the per-plane per-crtc design, as a result, now with the unit test called as 'modetest' we can see 3 planes and 2 crtc's compared to what it was 2 planes for 2 crtc's w/o this patch. * I have introduced new variable of max_surfaces to the public caps structure that can be used for all asic's in future as well. Basic understanding being: max_streams == crtc link_count == connector max_surfaces== plane * The drm device initialization loops now for number of surfaces instead of stream. * Have taken care that it won't break other asic's * Am able to reach __setplane_internal() in drm_plane.c which does the final update to plane, had to put a sanity patch there as we do not have update_plane() and disable_plane() implemented --> also testifies, that now we are able to handle planes with this patch. * The YUV formats supported right now are default, will refine it going further. Shirish S (1): drm/amd/display: decouple per-crtc-plane model drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 8 +++ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 67 ++- .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c| 77 +++--- .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.h| 5 +- drivers/gpu/drm/amd/display/dc/dc.h| 1 + .../drm/amd/display/dc/dce100/dce100_resource.c| 2 + .../drm/amd/display/dc/dce110/dce110_resource.c| 2 + .../drm/amd/display/dc/dce112/dce112_resource.c| 2 + .../drm/amd/display/dc/dce120/dce120_resource.c| 2 + .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 2 + 10 files changed, 127 insertions(+), 41 deletions(-) -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/1] drm/amd/display: decouple per-crtc-plane model
Current design has per-crtc-plane model. As a result, for asic's that support underlay, are unable to expose it to user space for modesetting. To enable this, the drm driver intialisation now runs for number of surfaces instead of stream/crtc. This patch plumbs surface capabilities to drm framework so that it can be effectively used by user space. Tests: (On Chromium OS) * 'modetest -p' now shows additional plane with YUV capabilities in case of CZ and ST. * 'plane_test' reaches __setplane_internal and fails there as update_plane function is not implemented. * Checked multimonitor display works fine Change-Id: Ibc112d1c7f76539b530b4e11862bb57f2e480121 Signed-off-by: Shirish S <shiris...@amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 8 +++ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 67 ++- .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.c| 77 +++--- .../drm/amd/display/amdgpu_dm/amdgpu_dm_types.h| 5 +- drivers/gpu/drm/amd/display/dc/dc.h| 1 + .../drm/amd/display/dc/dce100/dce100_resource.c| 2 + .../drm/amd/display/dc/dce110/dce110_resource.c| 2 + .../drm/amd/display/dc/dce112/dce112_resource.c| 2 + .../drm/amd/display/dc/dce120/dce120_resource.c| 2 + .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 2 + 10 files changed, 127 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 3148412..da3b125 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -59,6 +59,7 @@ struct amdgpu_hpd; #define AMDGPU_MAX_HPD_PINS 6 #define AMDGPU_MAX_CRTCS 6 +#define AMDGPU_MAX_PLANES 6 #define AMDGPU_MAX_AFMT_BLOCKS 9 enum amdgpu_rmx_type { @@ -338,6 +339,7 @@ struct amdgpu_mode_info { struct card_info *atom_card_info; bool mode_config_initialized; struct amdgpu_crtc *crtcs[AMDGPU_MAX_CRTCS]; + struct amdgpu_plane *planes[AMDGPU_MAX_PLANES]; struct amdgpu_afmt *afmt[AMDGPU_MAX_AFMT_BLOCKS]; /* DVI-I properties */ struct drm_property *coherent_mode_property; @@ -371,6 +373,7 @@ struct amdgpu_mode_info { int num_dig; /* number of dig blocks */ int disp_priority; const struct amdgpu_display_funcs *funcs; + enum drm_plane_type *plane_type; }; #define AMDGPU_MAX_BL_LEVEL 0xFF @@ -452,6 +455,11 @@ struct amdgpu_crtc { struct drm_pending_vblank_event *event; }; +struct amdgpu_plane { + struct drm_plane base; + enum drm_plane_type plane_type; +}; + struct amdgpu_encoder_atom_dig { bool linkb; /* atom dig */ 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 59aafba..be9581d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -55,6 +55,28 @@ #include "modules/inc/mod_freesync.h" +static enum drm_plane_type dm_surfaces_type_default[AMDGPU_MAX_PLANES] = { + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_PRIMARY, +}; + +static enum drm_plane_type dm_surfaces_type_carizzo[AMDGPU_MAX_PLANES] = { + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_OVERLAY,/* YUV Capable Underlay */ +}; + +static enum drm_plane_type dm_surfaces_type_stoney[AMDGPU_MAX_PLANES] = { + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_PRIMARY, + DRM_PLANE_TYPE_OVERLAY, /* YUV Capable Underlay */ +}; + /* * dm_vblank_get_counter * @@ -1058,30 +1080,34 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) uint32_t i; struct amdgpu_connector *aconnector; struct amdgpu_encoder *aencoder; - struct amdgpu_crtc *acrtc; + struct amdgpu_mode_info *mode_info = >mode_info; uint32_t link_cnt; link_cnt = dm->dc->caps.max_links; - if (amdgpu_dm_mode_config_init(dm->adev)) { DRM_ERROR("DM: Failed to initialize mode config\n"); - return -1; + goto fail; } - for (i = 0; i < dm->dc->caps.max_streams; i++) { - acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); - if (!acrtc) - goto fail; + for (i = 0; i < dm->dc->caps.max_surfaces; i++) { + mode_info->planes[i] = kzalloc(sizeof(struct amdgpu_plane), +GFP_KERNEL); + if (!mode_info->planes[i]) { + DRM_ERROR("KMS: Failed to allocate surface\n"); + goto