mirror of
https://github.com/torvalds/linux.git
synced 2024-11-14 16:12:02 +00:00
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:
commit
986c34b495
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user