From mboxrd@z Thu Jan 1 00:00:00 1970 From: Robert Chiras Subject: [PATCH 08/10] drm/mxsfb: Update mxsfb to support LCD reset Date: Wed, 9 Jan 2019 14:13:48 +0000 Message-ID: <1547043209-8283-9-git-send-email-robert.chiras@nxp.com> References: <1547043209-8283-1-git-send-email-robert.chiras@nxp.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: In-Reply-To: <1547043209-8283-1-git-send-email-robert.chiras@nxp.com> Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org To: Daniel Vetter , Philipp Zabel , Marek Vasut Cc: Robert Chiras , Stefan Agner , Shawn Guo , Fabio Estevam , David Airlie , Anson Huang , "dri-devel@lists.freedesktop.org" , dl-linux-imx , "kernel@pengutronix.de" , "linux-kernel@vger.kernel.org" List-Id: dri-devel@lists.freedesktop.org The eLCDIF controller has control pin for the external LCD reset pin. Add support for it and assert this pin in enable and de-assert it in disable. Also, correct the pm_runtime_enable call, since it was made too early in the probe, causing issues to DRM enable routines. Signed-off-by: Robert Chiras --- drivers/gpu/drm/mxsfb/mxsfb_crtc.c | 12 ++++++++++-- drivers/gpu/drm/mxsfb/mxsfb_drv.c | 20 ++++++++------------ drivers/gpu/drm/mxsfb/mxsfb_regs.h | 1 + 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxs= fb_crtc.c index b62b607..8d1b6a6 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c @@ -230,9 +230,12 @@ static void mxsfb_enable_controller(struct mxsfb_drm_p= rivate *mxsfb) clk_prepare_enable(mxsfb->clk_disp_axi); clk_prepare_enable(mxsfb->clk); =20 - if (mxsfb->devdata->ipversion >=3D 4) + if (mxsfb->devdata->ipversion >=3D 4) { writel(CTRL2_OUTSTANDING_REQS(REQ_16), mxsfb->base + LCDC_V4_CTRL2 + REG_SET); + /* Assert LCD Reset bit */ + writel(CTRL2_LCD_RESET, mxsfb->base + LCDC_V4_CTRL2 + REG_SET); + } =20 /* If it was disabled, re-enable the mode again */ writel(CTRL_DOTCLK_MODE, mxsfb->base + LCDC_CTRL + REG_SET); @@ -250,9 +253,12 @@ static void mxsfb_disable_controller(struct mxsfb_drm_= private *mxsfb) { u32 reg; =20 - if (mxsfb->devdata->ipversion >=3D 4) + if (mxsfb->devdata->ipversion >=3D 4) { writel(CTRL2_OUTSTANDING_REQS(0x7), mxsfb->base + LCDC_V4_CTRL2 + REG_CLR); + /* De-assert LCD Reset bit */ + writel(CTRL2_LCD_RESET, mxsfb->base + LCDC_V4_CTRL2 + REG_CLR); + } =20 writel(CTRL_RUN, mxsfb->base + LCDC_CTRL + REG_CLR); =20 @@ -346,6 +352,8 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_p= rivate *mxsfb) return; =20 clk_set_rate(mxsfb->clk, m->crtc_clock * 1000); + DRM_DEV_DEBUG_DRIVER(drm->dev, "Pixel clock: %dkHz (actual: %dkHz)\n", + m->crtc_clock, (int)(clk_get_rate(mxsfb->clk) / 1000)); =20 DRM_DEV_DEBUG_DRIVER(drm->dev, "Connector bus_flags: 0x%08X\n", bus_flags); diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsf= b_drv.c index f528a37..135b8e1 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -287,7 +287,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned = long flags) if (IS_ERR(mxsfb->base)) return PTR_ERR(mxsfb->base); =20 - mxsfb->clk =3D devm_clk_get(drm->dev, NULL); + mxsfb->clk =3D devm_clk_get(drm->dev, "pix"); if (IS_ERR(mxsfb->clk)) return PTR_ERR(mxsfb->clk); =20 @@ -303,12 +303,10 @@ static int mxsfb_load(struct drm_device *drm, unsigne= d long flags) if (ret) return ret; =20 - pm_runtime_enable(drm->dev); - ret =3D drm_vblank_init(drm, MAX_CRTCS); if (ret < 0) { dev_err(drm->dev, "Failed to initialise vblank\n"); - goto err_vblank; + return ret; } =20 /* Modeset init */ @@ -317,7 +315,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned = long flags) ret =3D mxsfb_create_output(drm); if (ret < 0) { dev_err(drm->dev, "Failed to create outputs\n"); - goto err_vblank; + return ret; } =20 ret =3D drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs, @@ -325,7 +323,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned = long flags) mxsfb->connector); if (ret < 0) { dev_err(drm->dev, "Cannot setup simple display pipe\n"); - goto err_vblank; + return ret; } =20 drm_crtc_vblank_off(&mxsfb->pipe.crtc); @@ -342,14 +340,14 @@ static int mxsfb_load(struct drm_device *drm, unsigne= d long flags) ret =3D drm_panel_attach(mxsfb->panel, mxsfb->connector); if (ret) { dev_err(drm->dev, "Cannot connect panel\n"); - goto err_vblank; + return ret; } } else if (mxsfb->bridge) { ret =3D drm_simple_display_pipe_attach_bridge(&mxsfb->pipe, mxsfb->bridge); if (ret) { dev_err(drm->dev, "Cannot connect bridge\n"); - goto err_vblank; + return ret; } } =20 @@ -369,9 +367,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned = long flags) =20 drm_mode_config_reset(drm); =20 - pm_runtime_get_sync(drm->dev); ret =3D drm_irq_install(drm, platform_get_irq(pdev, 0)); - pm_runtime_put_sync(drm->dev); =20 if (ret < 0) { dev_err(drm->dev, "Failed to install IRQ handler\n"); @@ -393,14 +389,14 @@ static int mxsfb_load(struct drm_device *drm, unsigne= d long flags) =20 drm_helper_hpd_irq_event(drm); =20 + pm_runtime_enable(drm->dev); + return 0; =20 err_cma: drm_irq_uninstall(drm); err_irq: drm_panel_detach(mxsfb->panel); -err_vblank: - pm_runtime_disable(drm->dev); =20 return ret; } diff --git a/drivers/gpu/drm/mxsfb/mxsfb_regs.h b/drivers/gpu/drm/mxsfb/mxs= fb_regs.h index 4904fdd..1d85750 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_regs.h +++ b/drivers/gpu/drm/mxsfb/mxsfb_regs.h @@ -95,6 +95,7 @@ #define CTRL2_OUTSTANDING_REQS(x) REG_PUT((x), 23, 21) #define CTRL2_ODD_LINE_PATTERN(x) REG_PUT((x), 18, 16) #define CTRL2_EVEN_LINE_PATTERN(x) REG_PUT((x), 14, 12) +#define CTRL2_LCD_RESET BIT(0) =20 #define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16) #define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff) --=20 2.7.4