Commit 6db71bea authored by Dave Airlie's avatar Dave Airlie

Merge tag 'imx-drm-fixes-2019-04-25' of git://git.pengutronix.de/pza/linux into drm-fixes

drm/imx: fix DP CSC handling

- Fix the DP color space conversion matrix setup to avoid bugs where
  disabling the overlay plane while both primary and overlay plane are
  routed via the CSC unit would not reconfigure the CSC routing
  properly, leaving the display in a nonworking state, or the CSC
  setting from a previously set mode would be left behind, causing
  wrong colors when reenabling the display in certain configurations.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Philipp Zabel <p.zabel@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/1556183136.2271.3.camel@pengutronix.de
parents a35d9d6a 7bcde275
...@@ -71,7 +71,7 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc, ...@@ -71,7 +71,7 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc,
if (disable_partial) if (disable_partial)
ipu_plane_disable(ipu_crtc->plane[1], true); ipu_plane_disable(ipu_crtc->plane[1], true);
if (disable_full) if (disable_full)
ipu_plane_disable(ipu_crtc->plane[0], false); ipu_plane_disable(ipu_crtc->plane[0], true);
} }
static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, static void ipu_crtc_atomic_disable(struct drm_crtc *crtc,
......
...@@ -195,7 +195,8 @@ int ipu_dp_setup_channel(struct ipu_dp *dp, ...@@ -195,7 +195,8 @@ int ipu_dp_setup_channel(struct ipu_dp *dp,
ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs, ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs,
DP_COM_CONF_CSC_DEF_BOTH); DP_COM_CONF_CSC_DEF_BOTH);
} else { } else {
if (flow->foreground.in_cs == flow->out_cs) if (flow->foreground.in_cs == IPUV3_COLORSPACE_UNKNOWN ||
flow->foreground.in_cs == flow->out_cs)
/* /*
* foreground identical to output, apply color * foreground identical to output, apply color
* conversion on background * conversion on background
...@@ -261,6 +262,8 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync) ...@@ -261,6 +262,8 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync)
struct ipu_dp_priv *priv = flow->priv; struct ipu_dp_priv *priv = flow->priv;
u32 reg, csc; u32 reg, csc;
dp->in_cs = IPUV3_COLORSPACE_UNKNOWN;
if (!dp->foreground) if (!dp->foreground)
return; return;
...@@ -268,8 +271,9 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync) ...@@ -268,8 +271,9 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync)
reg = readl(flow->base + DP_COM_CONF); reg = readl(flow->base + DP_COM_CONF);
csc = reg & DP_COM_CONF_CSC_DEF_MASK; csc = reg & DP_COM_CONF_CSC_DEF_MASK;
if (csc == DP_COM_CONF_CSC_DEF_FG)
reg &= ~DP_COM_CONF_CSC_DEF_MASK; reg &= ~DP_COM_CONF_CSC_DEF_MASK;
if (csc == DP_COM_CONF_CSC_DEF_BOTH || csc == DP_COM_CONF_CSC_DEF_BG)
reg |= DP_COM_CONF_CSC_DEF_BG;
reg &= ~DP_COM_CONF_FG_EN; reg &= ~DP_COM_CONF_FG_EN;
writel(reg, flow->base + DP_COM_CONF); writel(reg, flow->base + DP_COM_CONF);
...@@ -347,6 +351,8 @@ int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base) ...@@ -347,6 +351,8 @@ int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
mutex_init(&priv->mutex); mutex_init(&priv->mutex);
for (i = 0; i < IPUV3_NUM_FLOWS; i++) { for (i = 0; i < IPUV3_NUM_FLOWS; i++) {
priv->flow[i].background.in_cs = IPUV3_COLORSPACE_UNKNOWN;
priv->flow[i].foreground.in_cs = IPUV3_COLORSPACE_UNKNOWN;
priv->flow[i].foreground.foreground = true; priv->flow[i].foreground.foreground = true;
priv->flow[i].base = priv->base + ipu_dp_flow_base[i]; priv->flow[i].base = priv->base + ipu_dp_flow_base[i];
priv->flow[i].priv = priv; priv->flow[i].priv = priv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment