On Fri, May 05, 2017 at 03:01:41PM -0300, Fabio Estevam wrote:
> According to the eLCDIF initialization steps listed in the MX6SX
> Reference Manual the eLCDIF block reset is mandatory. 
> 
> Without performing the eLCDIF reset the display shows garbage content
> when the kernel boots.
> 
> In earlier tests this issue has not been observed because the bootloader
> was previously showing a splash screen and the bootloader display driver
> does properly implement the eLCDIF reset.
> 
> Add the eLCDIF reset to the driver, so that it can operate correctly
> independently of the bootloader.
> 
> Tested on a imx6sx-sdb board.
> 
> Cc: <sta...@vger.kernel.org>
> Signed-off-by: Fabio Estevam <fabio.este...@nxp.com>

Per Marek's request, this has been applied to drm-misc-next

Thanks,

Sean

> ---
> Changes since v2:
> 
> - Remove unneeded udelay(1) - Marek
> 
>  drivers/gpu/drm/mxsfb/mxsfb_crtc.c | 42 
> ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c 
> b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> index 1144e0c..0abe776 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c
> @@ -35,6 +35,13 @@
>  #include "mxsfb_drv.h"
>  #include "mxsfb_regs.h"
>  
> +#define MXS_SET_ADDR         0x4
> +#define MXS_CLR_ADDR         0x8
> +#define MODULE_CLKGATE               BIT(30)
> +#define MODULE_SFTRST                BIT(31)
> +/* 1 second delay should be plenty of time for block reset */
> +#define RESET_TIMEOUT                1000000
> +
>  static u32 set_hsync_pulse_width(struct mxsfb_drm_private *mxsfb, u32 val)
>  {
>       return (val & mxsfb->devdata->hs_wdth_mask) <<
> @@ -159,6 +166,36 @@ static void mxsfb_disable_controller(struct 
> mxsfb_drm_private *mxsfb)
>               clk_disable_unprepare(mxsfb->clk_disp_axi);
>  }
>  
> +/*
> + * Clear the bit and poll it cleared.  This is usually called with
> + * a reset address and mask being either SFTRST(bit 31) or CLKGATE
> + * (bit 30).
> + */
> +static int clear_poll_bit(void __iomem *addr, u32 mask)
> +{
> +     u32 reg;
> +
> +     writel(mask, addr + MXS_CLR_ADDR);
> +     return readl_poll_timeout(addr, reg, !(reg & mask), 0, RESET_TIMEOUT);
> +}
> +
> +static int mxsfb_reset_block(void __iomem *reset_addr)
> +{
> +     int ret;
> +
> +     ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
> +     if (ret)
> +             return ret;
> +
> +     writel(MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
> +
> +     ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
> +     if (ret)
> +             return ret;
> +
> +     return clear_poll_bit(reset_addr, MODULE_CLKGATE);
> +}
> +
>  static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
>  {
>       struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode;
> @@ -173,6 +210,11 @@ static void mxsfb_crtc_mode_set_nofb(struct 
> mxsfb_drm_private *mxsfb)
>        */
>       mxsfb_enable_axi_clk(mxsfb);
>  
> +     /* Mandatory eLCDIF reset as per the Reference Manual */
> +     err = mxsfb_reset_block(mxsfb->base);
> +     if (err)
> +             return;
> +
>       /* Clear the FIFOs */
>       writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_SET);
>  
> -- 
> 2.7.4
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to