Merge tag 'drm-msm-fixes-2023-06-08' of https://gitlab.freedesktop.org/drm/msm into drm-fixes

A few more late fixes for v6.4-rc6

+ Fix max segment size to address splat on newer a6xx
+ Disable PSR by default w/ modparam to re-enable, since there
  still seems to be a lingering issue
+ Fix HPD issue
+ Fix issue with unitialized GMU mutex

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGufjVZRNT6YfQ7YUXFC7Cz95wdLF7QHAYkiGfp+3Xc3DQ@mail.gmail.com
This commit is contained in:
Dave Airlie 2023-06-09 11:20:22 +10:00
commit 986c34b495
6 changed files with 44 additions and 59 deletions

View File

@ -1526,8 +1526,6 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
if (!pdev) if (!pdev)
return -ENODEV; return -ENODEV;
mutex_init(&gmu->lock);
gmu->dev = &pdev->dev; gmu->dev = &pdev->dev;
of_dma_configure(gmu->dev, node, true); of_dma_configure(gmu->dev, node, true);

View File

@ -1981,6 +1981,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
adreno_gpu = &a6xx_gpu->base; adreno_gpu = &a6xx_gpu->base;
gpu = &adreno_gpu->base; gpu = &adreno_gpu->base;
mutex_init(&a6xx_gpu->gmu.lock);
adreno_gpu->registers = NULL; adreno_gpu->registers = NULL;
/* /*

View File

@ -620,7 +620,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog,
config & DP_DP_HPD_INT_MASK); config & DP_DP_HPD_INT_MASK);
} }
void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog)
{ {
struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog); struct dp_catalog_private, dp_catalog);
@ -635,6 +635,19 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog)
dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
} }
void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog)
{
struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog);
u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE;
dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0);
}
static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog) static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog)
{ {
/* trigger sdp */ /* trigger sdp */

View File

@ -104,7 +104,8 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable);
void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog, void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog,
u32 intr_mask, bool en); u32 intr_mask, bool en);
void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog); void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog);
void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter); void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter);
u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog); u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog);

View File

@ -28,6 +28,10 @@
#include "dp_audio.h" #include "dp_audio.h"
#include "dp_debug.h" #include "dp_debug.h"
static bool psr_enabled = false;
module_param(psr_enabled, bool, 0);
MODULE_PARM_DESC(psr_enabled, "enable PSR for eDP and DP displays");
#define HPD_STRING_SIZE 30 #define HPD_STRING_SIZE 30
enum { enum {
@ -407,7 +411,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
edid = dp->panel->edid; edid = dp->panel->edid;
dp->dp_display.psr_supported = dp->panel->psr_cap.version; dp->dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
dp->audio_supported = drm_detect_monitor_audio(edid); dp->audio_supported = drm_detect_monitor_audio(edid);
dp_panel_handle_sink_request(dp->panel); dp_panel_handle_sink_request(dp->panel);
@ -616,12 +620,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
dp->hpd_state = ST_MAINLINK_READY; dp->hpd_state = ST_MAINLINK_READY;
} }
/* enable HDP irq_hpd/replug interrupt */
if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog,
DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
true);
drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
dp->dp_display.connector_type, state); dp->dp_display.connector_type, state);
mutex_unlock(&dp->event_mutex); mutex_unlock(&dp->event_mutex);
@ -659,12 +657,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n", drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
dp->dp_display.connector_type, state); dp->dp_display.connector_type, state);
/* disable irq_hpd/replug interrupts */
if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog,
DP_DP_IRQ_HPD_INT_MASK | DP_DP_HPD_REPLUG_INT_MASK,
false);
/* unplugged, no more irq_hpd handle */ /* unplugged, no more irq_hpd handle */
dp_del_event(dp, EV_IRQ_HPD_INT); dp_del_event(dp, EV_IRQ_HPD_INT);
@ -688,10 +680,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
return 0; return 0;
} }
/* disable HPD plug interrupts */
if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, false);
/* /*
* We don't need separate work for disconnect as * We don't need separate work for disconnect as
* connect/attention interrupts are disabled * connect/attention interrupts are disabled
@ -707,10 +695,6 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
/* signal the disconnect event early to ensure proper teardown */ /* signal the disconnect event early to ensure proper teardown */
dp_display_handle_plugged_change(&dp->dp_display, false); dp_display_handle_plugged_change(&dp->dp_display, false);
/* enable HDP plug interrupt to prepare for next plugin */
if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true);
drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n", drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
dp->dp_display.connector_type, state); dp->dp_display.connector_type, state);
@ -1083,26 +1067,6 @@ void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp)
mutex_unlock(&dp_display->event_mutex); mutex_unlock(&dp_display->event_mutex);
} }
static void dp_display_config_hpd(struct dp_display_private *dp)
{
dp_display_host_init(dp);
dp_catalog_ctrl_hpd_config(dp->catalog);
/* Enable plug and unplug interrupts only if requested */
if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog,
DP_DP_HPD_PLUG_INT_MASK |
DP_DP_HPD_UNPLUG_INT_MASK,
true);
/* Enable interrupt first time
* we are leaving dp clocks on during disconnect
* and never disable interrupt
*/
enable_irq(dp->irq);
}
void dp_display_set_psr(struct msm_dp *dp_display, bool enter) void dp_display_set_psr(struct msm_dp *dp_display, bool enter)
{ {
struct dp_display_private *dp; struct dp_display_private *dp;
@ -1177,7 +1141,7 @@ static int hpd_event_thread(void *data)
switch (todo->event_id) { switch (todo->event_id) {
case EV_HPD_INIT_SETUP: case EV_HPD_INIT_SETUP:
dp_display_config_hpd(dp_priv); dp_display_host_init(dp_priv);
break; break;
case EV_HPD_PLUG_INT: case EV_HPD_PLUG_INT:
dp_hpd_plug_handle(dp_priv, todo->data); dp_hpd_plug_handle(dp_priv, todo->data);
@ -1283,7 +1247,6 @@ int dp_display_request_irq(struct msm_dp *dp_display)
dp->irq, rc); dp->irq, rc);
return rc; return rc;
} }
disable_irq(dp->irq);
return 0; return 0;
} }
@ -1395,13 +1358,8 @@ static int dp_pm_resume(struct device *dev)
/* turn on dp ctrl/phy */ /* turn on dp ctrl/phy */
dp_display_host_init(dp); dp_display_host_init(dp);
dp_catalog_ctrl_hpd_config(dp->catalog); if (dp_display->is_edp)
dp_catalog_ctrl_hpd_enable(dp->catalog);
if (dp->dp_display.internal_hpd)
dp_catalog_hpd_config_intr(dp->catalog,
DP_DP_HPD_PLUG_INT_MASK |
DP_DP_HPD_UNPLUG_INT_MASK,
true);
if (dp_catalog_link_is_connected(dp->catalog)) { if (dp_catalog_link_is_connected(dp->catalog)) {
/* /*
@ -1569,9 +1527,8 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
if (aux_bus && dp->is_edp) { if (aux_bus && dp->is_edp) {
dp_display_host_init(dp_priv); dp_display_host_init(dp_priv);
dp_catalog_ctrl_hpd_config(dp_priv->catalog); dp_catalog_ctrl_hpd_enable(dp_priv->catalog);
dp_display_host_phy_init(dp_priv); dp_display_host_phy_init(dp_priv);
enable_irq(dp_priv->irq);
/* /*
* The code below assumes that the panel will finish probing * The code below assumes that the panel will finish probing
@ -1613,7 +1570,6 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
error: error:
if (dp->is_edp) { if (dp->is_edp) {
disable_irq(dp_priv->irq);
dp_display_host_phy_exit(dp_priv); dp_display_host_phy_exit(dp_priv);
dp_display_host_deinit(dp_priv); dp_display_host_deinit(dp_priv);
} }
@ -1802,16 +1758,31 @@ void dp_bridge_hpd_enable(struct drm_bridge *bridge)
{ {
struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge); struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
struct msm_dp *dp_display = dp_bridge->dp_display; struct msm_dp *dp_display = dp_bridge->dp_display;
struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
mutex_lock(&dp->event_mutex);
dp_catalog_ctrl_hpd_enable(dp->catalog);
/* enable HDP interrupts */
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, true);
dp_display->internal_hpd = true; dp_display->internal_hpd = true;
mutex_unlock(&dp->event_mutex);
} }
void dp_bridge_hpd_disable(struct drm_bridge *bridge) void dp_bridge_hpd_disable(struct drm_bridge *bridge)
{ {
struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge); struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
struct msm_dp *dp_display = dp_bridge->dp_display; struct msm_dp *dp_display = dp_bridge->dp_display;
struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
mutex_lock(&dp->event_mutex);
/* disable HDP interrupts */
dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
dp_catalog_ctrl_hpd_disable(dp->catalog);
dp_display->internal_hpd = false; dp_display->internal_hpd = false;
mutex_unlock(&dp->event_mutex);
} }
void dp_bridge_hpd_notify(struct drm_bridge *bridge, void dp_bridge_hpd_notify(struct drm_bridge *bridge,

View File

@ -449,6 +449,8 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
if (ret) if (ret)
goto err_cleanup_mode_config; goto err_cleanup_mode_config;
dma_set_max_seg_size(dev, UINT_MAX);
/* Bind all our sub-components: */ /* Bind all our sub-components: */
ret = component_bind_all(dev, ddev); ret = component_bind_all(dev, ddev);
if (ret) if (ret)
@ -459,8 +461,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
if (ret) if (ret)
goto err_msm_uninit; goto err_msm_uninit;
dma_set_max_seg_size(dev, UINT_MAX);
msm_gem_shrinker_init(ddev); msm_gem_shrinker_init(ddev);
if (priv->kms_init) { if (priv->kms_init) {