Commit 986c34b4 authored by Dave Airlie's avatar Dave Airlie
Browse files

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: default avatarDave Airlie <airlied@redhat.com>
From: Rob Clark <robdclark@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CAF6AEGufjVZRNT6YfQ7YUXFC7Cz95wdLF7QHAYkiGfp+3Xc3DQ@mail.gmail.com
parents bcd84301 12abd735
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -1526,8 +1526,6 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
	if (!pdev)
		return -ENODEV;

	mutex_init(&gmu->lock);

	gmu->dev = &pdev->dev;

	of_dma_configure(gmu->dev, node, true);
+2 −0
Original line number Diff line number Diff line
@@ -1981,6 +1981,8 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
	adreno_gpu = &a6xx_gpu->base;
	gpu = &adreno_gpu->base;

	mutex_init(&a6xx_gpu->gmu.lock);

	adreno_gpu->registers = NULL;

	/*
+14 −1
Original line number Diff line number Diff line
@@ -620,7 +620,7 @@ void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog,
				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, 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);
}

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)
{
	/* trigger sdp */
+2 −1
Original line number Diff line number Diff line
@@ -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_hpd_config_intr(struct dp_catalog *dp_catalog,
			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_set_psr(struct dp_catalog *dp_catalog, bool enter);
u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog);
+24 −53
Original line number Diff line number Diff line
@@ -28,6 +28,10 @@
#include "dp_audio.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

enum {
@@ -407,7 +411,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)

	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_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;
	}

	/* 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",
			dp->dp_display.connector_type, state);
	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",
			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 */
	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;
	}

	/* 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
	 * 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 */
	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",
			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);
}

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)
{
	struct dp_display_private *dp;
@@ -1177,7 +1141,7 @@ static int hpd_event_thread(void *data)

		switch (todo->event_id) {
		case EV_HPD_INIT_SETUP:
			dp_display_config_hpd(dp_priv);
			dp_display_host_init(dp_priv);
			break;
		case EV_HPD_PLUG_INT:
			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);
		return rc;
	}
	disable_irq(dp->irq);

	return 0;
}
@@ -1395,13 +1358,8 @@ static int dp_pm_resume(struct device *dev)
	/* turn on dp ctrl/phy */
	dp_display_host_init(dp);

	dp_catalog_ctrl_hpd_config(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_display->is_edp)
		dp_catalog_ctrl_hpd_enable(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) {
		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);
		enable_irq(dp_priv->irq);

		/*
		 * 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:
	if (dp->is_edp) {
		disable_irq(dp_priv->irq);
		dp_display_host_phy_exit(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 *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;
	mutex_unlock(&dp->event_mutex);
}

void dp_bridge_hpd_disable(struct drm_bridge *bridge)
{
	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
	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;
	mutex_unlock(&dp->event_mutex);
}

void dp_bridge_hpd_notify(struct drm_bridge *bridge,
Loading