Message ID | 20170227112824.24501-3-p.zabel@pengutronix.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Am Montag, den 27.02.2017, 12:28 +0100 schrieb Philipp Zabel: > When disabling the foreground DP channel during a modeset, the DC is > already disabled without waiting for end of frame. There is no reason > to wait for a frame boundary before updating the DP registers in that > case. > Add support to apply updates immediately. No functional changes, yet. > > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> > --- > drivers/gpu/drm/imx/ipuv3-plane.c | 2 +- > drivers/gpu/ipu-v3/ipu-common.c | 8 +++++--- > drivers/gpu/ipu-v3/ipu-dp.c | 12 ++++++------ > drivers/gpu/ipu-v3/ipu-prv.h | 7 ++++++- > include/video/imx-ipu-v3.h | 2 +- > 5 files changed, 19 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c > index 24819c9c36400..55991d46ced50 100644 > --- a/drivers/gpu/drm/imx/ipuv3-plane.c > +++ b/drivers/gpu/drm/imx/ipuv3-plane.c > @@ -181,7 +181,7 @@ static int ipu_disable_plane(struct drm_plane *plane) > ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50); > > if (ipu_plane->dp) > - ipu_dp_disable_channel(ipu_plane->dp); > + ipu_dp_disable_channel(ipu_plane->dp, true); > ipu_idmac_disable_channel(ipu_plane->ipu_ch); > ipu_dmfc_disable_channel(ipu_plane->dmfc); > if (ipu_plane->dp) > diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c > index 8368e6f766ee5..86b87d620150c 100644 > --- a/drivers/gpu/ipu-v3/ipu-common.c > +++ b/drivers/gpu/ipu-v3/ipu-common.c > @@ -51,15 +51,17 @@ int ipu_get_num(struct ipu_soc *ipu) > } > EXPORT_SYMBOL_GPL(ipu_get_num); > > -void ipu_srm_dp_sync_update(struct ipu_soc *ipu) > +void ipu_srm_dp_update(struct ipu_soc *ipu, bool sync) > { > u32 val; > > val = ipu_cm_read(ipu, IPU_SRM_PRI2); > - val |= 0x8; > + val &= DP_S_SRM_MODE_MASK; Should probably be ~DP_S_SRM_MODE_MASK. > + val |= sync ? DP_S_SRM_MODE_NEXT_FRAME : > + DP_S_SRM_MODE_NOW; > ipu_cm_write(ipu, val, IPU_SRM_PRI2); > } > -EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update); > +EXPORT_SYMBOL_GPL(ipu_srm_dp_update); > > enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc) > { > diff --git a/drivers/gpu/ipu-v3/ipu-dp.c b/drivers/gpu/ipu-v3/ipu-dp.c > index 98686edbcdbb0..0e09c98248a0d 100644 > --- a/drivers/gpu/ipu-v3/ipu-dp.c > +++ b/drivers/gpu/ipu-v3/ipu-dp.c > @@ -112,7 +112,7 @@ int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, > writel(reg & ~DP_COM_CONF_GWAM, flow->base + DP_COM_CONF); > } > > - ipu_srm_dp_sync_update(priv->ipu); > + ipu_srm_dp_update(priv->ipu, true); > > mutex_unlock(&priv->mutex); > > @@ -127,7 +127,7 @@ int ipu_dp_set_window_pos(struct ipu_dp *dp, u16 x_pos, u16 y_pos) > > writel((x_pos << 16) | y_pos, flow->base + DP_FG_POS); > > - ipu_srm_dp_sync_update(priv->ipu); > + ipu_srm_dp_update(priv->ipu, true); > > return 0; > } > @@ -207,7 +207,7 @@ int ipu_dp_setup_channel(struct ipu_dp *dp, > flow->out_cs, DP_COM_CONF_CSC_DEF_FG); > } > > - ipu_srm_dp_sync_update(priv->ipu); > + ipu_srm_dp_update(priv->ipu, true); > > mutex_unlock(&priv->mutex); > > @@ -247,7 +247,7 @@ int ipu_dp_enable_channel(struct ipu_dp *dp) > reg |= DP_COM_CONF_FG_EN; > writel(reg, flow->base + DP_COM_CONF); > > - ipu_srm_dp_sync_update(priv->ipu); > + ipu_srm_dp_update(priv->ipu, true); > > mutex_unlock(&priv->mutex); > > @@ -255,7 +255,7 @@ int ipu_dp_enable_channel(struct ipu_dp *dp) > } > EXPORT_SYMBOL_GPL(ipu_dp_enable_channel); > > -void ipu_dp_disable_channel(struct ipu_dp *dp) > +void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync) > { > struct ipu_flow *flow = to_flow(dp); > struct ipu_dp_priv *priv = flow->priv; > @@ -275,7 +275,7 @@ void ipu_dp_disable_channel(struct ipu_dp *dp) > writel(reg, flow->base + DP_COM_CONF); > > writel(0, flow->base + DP_FG_POS); > - ipu_srm_dp_sync_update(priv->ipu); > + ipu_srm_dp_update(priv->ipu, sync); > > if (ipu_idmac_channel_busy(priv->ipu, IPUV3_CHANNEL_MEM_BG_SYNC)) > ipu_wait_interrupt(priv->ipu, IPU_IRQ_DP_SF_END, 50); > diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h > index 22e47b68b14a2..285595702ee0f 100644 > --- a/drivers/gpu/ipu-v3/ipu-prv.h > +++ b/drivers/gpu/ipu-v3/ipu-prv.h > @@ -75,6 +75,11 @@ struct ipu_soc; > #define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * (n)) > #define IPU_INT_STAT(n) IPU_CM_REG(0x0200 + 4 * (n)) > > +/* SRM_PRI2 */ > +#define DP_S_SRM_MODE_MASK (0x3 << 3) > +#define DP_S_SRM_MODE_NOW (0x3 << 3) > +#define DP_S_SRM_MODE_NEXT_FRAME (0x1 << 3) > + > /* FS_PROC_FLOW1 */ > #define FS_PRPENC_ROT_SRC_SEL_MASK (0xf << 0) > #define FS_PRPENC_ROT_SRC_SEL_ENC (0x7 << 0) > @@ -215,7 +220,7 @@ static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value, > writel(value, ipu->idmac_reg + offset); > } > > -void ipu_srm_dp_sync_update(struct ipu_soc *ipu); > +void ipu_srm_dp_update(struct ipu_soc *ipu, bool sync); > > int ipu_module_enable(struct ipu_soc *ipu, u32 mask); > int ipu_module_disable(struct ipu_soc *ipu, u32 mask); > diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h > index 53cd07ccaa4ce..899d2b00ad6d4 100644 > --- a/include/video/imx-ipu-v3.h > +++ b/include/video/imx-ipu-v3.h > @@ -300,7 +300,7 @@ struct ipu_dp *ipu_dp_get(struct ipu_soc *ipu, unsigned int flow); > void ipu_dp_put(struct ipu_dp *); > int ipu_dp_enable(struct ipu_soc *ipu); > int ipu_dp_enable_channel(struct ipu_dp *dp); > -void ipu_dp_disable_channel(struct ipu_dp *dp); > +void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync); > void ipu_dp_disable(struct ipu_soc *ipu); > int ipu_dp_setup_channel(struct ipu_dp *dp, > enum ipu_color_space in, enum ipu_color_space out);
On Mon, 2017-02-27 at 12:33 +0100, Lucas Stach wrote: > Am Montag, den 27.02.2017, 12:28 +0100 schrieb Philipp Zabel: > > When disabling the foreground DP channel during a modeset, the DC is > > already disabled without waiting for end of frame. There is no reason > > to wait for a frame boundary before updating the DP registers in that > > case. > > Add support to apply updates immediately. No functional changes, yet. > > > > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> > > --- > > drivers/gpu/drm/imx/ipuv3-plane.c | 2 +- > > drivers/gpu/ipu-v3/ipu-common.c | 8 +++++--- > > drivers/gpu/ipu-v3/ipu-dp.c | 12 ++++++------ > > drivers/gpu/ipu-v3/ipu-prv.h | 7 ++++++- > > include/video/imx-ipu-v3.h | 2 +- > > 5 files changed, 19 insertions(+), 12 deletions(-) > > > > diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c > > index 24819c9c36400..55991d46ced50 100644 > > --- a/drivers/gpu/drm/imx/ipuv3-plane.c > > +++ b/drivers/gpu/drm/imx/ipuv3-plane.c > > @@ -181,7 +181,7 @@ static int ipu_disable_plane(struct drm_plane *plane) > > ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50); > > > > if (ipu_plane->dp) > > - ipu_dp_disable_channel(ipu_plane->dp); > > + ipu_dp_disable_channel(ipu_plane->dp, true); > > ipu_idmac_disable_channel(ipu_plane->ipu_ch); > > ipu_dmfc_disable_channel(ipu_plane->dmfc); > > if (ipu_plane->dp) > > diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c > > index 8368e6f766ee5..86b87d620150c 100644 > > --- a/drivers/gpu/ipu-v3/ipu-common.c > > +++ b/drivers/gpu/ipu-v3/ipu-common.c > > @@ -51,15 +51,17 @@ int ipu_get_num(struct ipu_soc *ipu) > > } > > EXPORT_SYMBOL_GPL(ipu_get_num); > > > > -void ipu_srm_dp_sync_update(struct ipu_soc *ipu) > > +void ipu_srm_dp_update(struct ipu_soc *ipu, bool sync) > > { > > u32 val; > > > > val = ipu_cm_read(ipu, IPU_SRM_PRI2); > > - val |= 0x8; > > + val &= DP_S_SRM_MODE_MASK; > > Should probably be ~DP_S_SRM_MODE_MASK. Indeed, thanks for catching this. This had no effect since the IPU auto-clears the DP_S_SRM_MODE field, and all other non-zero fields in this register are only SRM update priorities for modules that don't use the SRM for register updates. regards Philipp
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 24819c9c36400..55991d46ced50 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -181,7 +181,7 @@ static int ipu_disable_plane(struct drm_plane *plane) ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50); if (ipu_plane->dp) - ipu_dp_disable_channel(ipu_plane->dp); + ipu_dp_disable_channel(ipu_plane->dp, true); ipu_idmac_disable_channel(ipu_plane->ipu_ch); ipu_dmfc_disable_channel(ipu_plane->dmfc); if (ipu_plane->dp) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 8368e6f766ee5..86b87d620150c 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -51,15 +51,17 @@ int ipu_get_num(struct ipu_soc *ipu) } EXPORT_SYMBOL_GPL(ipu_get_num); -void ipu_srm_dp_sync_update(struct ipu_soc *ipu) +void ipu_srm_dp_update(struct ipu_soc *ipu, bool sync) { u32 val; val = ipu_cm_read(ipu, IPU_SRM_PRI2); - val |= 0x8; + val &= DP_S_SRM_MODE_MASK; + val |= sync ? DP_S_SRM_MODE_NEXT_FRAME : + DP_S_SRM_MODE_NOW; ipu_cm_write(ipu, val, IPU_SRM_PRI2); } -EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update); +EXPORT_SYMBOL_GPL(ipu_srm_dp_update); enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc) { diff --git a/drivers/gpu/ipu-v3/ipu-dp.c b/drivers/gpu/ipu-v3/ipu-dp.c index 98686edbcdbb0..0e09c98248a0d 100644 --- a/drivers/gpu/ipu-v3/ipu-dp.c +++ b/drivers/gpu/ipu-v3/ipu-dp.c @@ -112,7 +112,7 @@ int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, writel(reg & ~DP_COM_CONF_GWAM, flow->base + DP_COM_CONF); } - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, true); mutex_unlock(&priv->mutex); @@ -127,7 +127,7 @@ int ipu_dp_set_window_pos(struct ipu_dp *dp, u16 x_pos, u16 y_pos) writel((x_pos << 16) | y_pos, flow->base + DP_FG_POS); - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, true); return 0; } @@ -207,7 +207,7 @@ int ipu_dp_setup_channel(struct ipu_dp *dp, flow->out_cs, DP_COM_CONF_CSC_DEF_FG); } - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, true); mutex_unlock(&priv->mutex); @@ -247,7 +247,7 @@ int ipu_dp_enable_channel(struct ipu_dp *dp) reg |= DP_COM_CONF_FG_EN; writel(reg, flow->base + DP_COM_CONF); - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, true); mutex_unlock(&priv->mutex); @@ -255,7 +255,7 @@ int ipu_dp_enable_channel(struct ipu_dp *dp) } EXPORT_SYMBOL_GPL(ipu_dp_enable_channel); -void ipu_dp_disable_channel(struct ipu_dp *dp) +void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync) { struct ipu_flow *flow = to_flow(dp); struct ipu_dp_priv *priv = flow->priv; @@ -275,7 +275,7 @@ void ipu_dp_disable_channel(struct ipu_dp *dp) writel(reg, flow->base + DP_COM_CONF); writel(0, flow->base + DP_FG_POS); - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, sync); if (ipu_idmac_channel_busy(priv->ipu, IPUV3_CHANNEL_MEM_BG_SYNC)) ipu_wait_interrupt(priv->ipu, IPU_IRQ_DP_SF_END, 50); diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index 22e47b68b14a2..285595702ee0f 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -75,6 +75,11 @@ struct ipu_soc; #define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * (n)) #define IPU_INT_STAT(n) IPU_CM_REG(0x0200 + 4 * (n)) +/* SRM_PRI2 */ +#define DP_S_SRM_MODE_MASK (0x3 << 3) +#define DP_S_SRM_MODE_NOW (0x3 << 3) +#define DP_S_SRM_MODE_NEXT_FRAME (0x1 << 3) + /* FS_PROC_FLOW1 */ #define FS_PRPENC_ROT_SRC_SEL_MASK (0xf << 0) #define FS_PRPENC_ROT_SRC_SEL_ENC (0x7 << 0) @@ -215,7 +220,7 @@ static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value, writel(value, ipu->idmac_reg + offset); } -void ipu_srm_dp_sync_update(struct ipu_soc *ipu); +void ipu_srm_dp_update(struct ipu_soc *ipu, bool sync); int ipu_module_enable(struct ipu_soc *ipu, u32 mask); int ipu_module_disable(struct ipu_soc *ipu, u32 mask); diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index 53cd07ccaa4ce..899d2b00ad6d4 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -300,7 +300,7 @@ struct ipu_dp *ipu_dp_get(struct ipu_soc *ipu, unsigned int flow); void ipu_dp_put(struct ipu_dp *); int ipu_dp_enable(struct ipu_soc *ipu); int ipu_dp_enable_channel(struct ipu_dp *dp); -void ipu_dp_disable_channel(struct ipu_dp *dp); +void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync); void ipu_dp_disable(struct ipu_soc *ipu); int ipu_dp_setup_channel(struct ipu_dp *dp, enum ipu_color_space in, enum ipu_color_space out);
When disabling the foreground DP channel during a modeset, the DC is already disabled without waiting for end of frame. There is no reason to wait for a frame boundary before updating the DP registers in that case. Add support to apply updates immediately. No functional changes, yet. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> --- drivers/gpu/drm/imx/ipuv3-plane.c | 2 +- drivers/gpu/ipu-v3/ipu-common.c | 8 +++++--- drivers/gpu/ipu-v3/ipu-dp.c | 12 ++++++------ drivers/gpu/ipu-v3/ipu-prv.h | 7 ++++++- include/video/imx-ipu-v3.h | 2 +- 5 files changed, 19 insertions(+), 12 deletions(-)