| From 23143c3fa488cc3f2645e75e1c0610a6623a1a5b Mon Sep 17 00:00:00 2001 |
| From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| Date: Mon, 17 Jun 2013 03:20:08 +0200 |
| Subject: drm/rcar-du: Configure RGB output routing to DPAD0 |
| |
| The R8A7790 DU variant has a single RGB output called DPAD0 that can be |
| fed with the output of DU0, DU1 or DU2. Making the routing configurable. |
| |
| Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> |
| (cherry picked from commit 7cbc05cb518304b746bea00bc7c0b005217bcaf7) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 5 ++++ |
| drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 ++ |
| drivers/gpu/drm/rcar-du/rcar_du_group.c | 45 ++++++++++++++++++++++++++++++--- |
| drivers/gpu/drm/rcar-du/rcar_du_group.h | 2 +- |
| 4 files changed, 50 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c |
| index 680606ef11d8..245800ddd1a8 100644 |
| --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c |
| +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c |
| @@ -139,6 +139,11 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc, |
| * configured when starting the CRTC. |
| */ |
| rcrtc->outputs |= BIT(output); |
| + |
| + /* Store RGB routing to DPAD0 for R8A7790. */ |
| + if (rcar_du_has(rcdu, RCAR_DU_FEATURE_DEFR8) && |
| + output == RCAR_DU_OUTPUT_DPAD0) |
| + rcdu->dpad0_source = rcrtc->index; |
| } |
| |
| void rcar_du_crtc_update_planes(struct drm_crtc *crtc) |
| diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h |
| index d5243f493903..924f5e08f060 100644 |
| --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h |
| +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h |
| @@ -68,6 +68,8 @@ struct rcar_du_device { |
| unsigned int num_crtcs; |
| |
| struct rcar_du_group groups[2]; |
| + |
| + unsigned int dpad0_source; |
| }; |
| |
| static inline bool rcar_du_has(struct rcar_du_device *rcdu, |
| diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c |
| index 9df6fb635c96..eb53cd97e8c6 100644 |
| --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c |
| +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c |
| @@ -27,6 +27,7 @@ |
| * counterpart in the DU documentation, that models those semi-global resources. |
| */ |
| |
| +#include <linux/clk.h> |
| #include <linux/io.h> |
| |
| #include "rcar_du_drv.h" |
| @@ -43,6 +44,22 @@ void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data) |
| rcar_du_write(rgrp->dev, rgrp->mmio_offset + reg, data); |
| } |
| |
| +static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp) |
| +{ |
| + u32 defr8 = DEFR8_CODE | DEFR8_DEFE8; |
| + |
| + if (!rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_DEFR8)) |
| + return; |
| + |
| + /* The DEFR8 register for the first group also controls RGB output |
| + * routing to DPAD0 |
| + */ |
| + if (rgrp->index == 0) |
| + defr8 |= DEFR8_DRGBS_DU(rgrp->dev->dpad0_source); |
| + |
| + rcar_du_group_write(rgrp, DEFR8, defr8); |
| +} |
| + |
| static void rcar_du_group_setup(struct rcar_du_group *rgrp) |
| { |
| /* Enable extended features */ |
| @@ -51,8 +68,8 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp) |
| rcar_du_group_write(rgrp, DEFR3, DEFR3_CODE | DEFR3_DEFE3); |
| rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE); |
| rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5); |
| - if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_DEFR8)) |
| - rcar_du_group_write(rgrp, DEFR8, DEFR8_CODE | DEFR8_DEFE8); |
| + |
| + rcar_du_group_setup_defr8(rgrp); |
| |
| /* Use DS1PR and DS2PR to configure planes priorities and connects the |
| * superposition 0 to DU0 pins. DU1 pins will be configured dynamically. |
| @@ -128,7 +145,27 @@ void rcar_du_group_restart(struct rcar_du_group *rgrp) |
| __rcar_du_group_start_stop(rgrp, true); |
| } |
| |
| -void rcar_du_group_set_routing(struct rcar_du_group *rgrp) |
| +static int rcar_du_set_dpad0_routing(struct rcar_du_device *rcdu) |
| +{ |
| + int ret; |
| + |
| + /* RGB output routing to DPAD0 is configured in the DEFR8 register of |
| + * the first group. As this function can be called with the DU0 and DU1 |
| + * CRTCs disabled, we need to enable the first group clock before |
| + * accessing the register. |
| + */ |
| + ret = clk_prepare_enable(rcdu->crtcs[0].clock); |
| + if (ret < 0) |
| + return ret; |
| + |
| + rcar_du_group_setup_defr8(&rcdu->groups[0]); |
| + |
| + clk_disable_unprepare(rcdu->crtcs[0].clock); |
| + |
| + return 0; |
| +} |
| + |
| +int rcar_du_group_set_routing(struct rcar_du_group *rgrp) |
| { |
| struct rcar_du_crtc *crtc0 = &rgrp->dev->crtcs[rgrp->index * 2]; |
| u32 dorcr = rcar_du_group_read(rgrp, DORCR); |
| @@ -145,4 +182,6 @@ void rcar_du_group_set_routing(struct rcar_du_group *rgrp) |
| dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2; |
| |
| rcar_du_group_write(rgrp, DORCR, dorcr); |
| + |
| + return rcar_du_set_dpad0_routing(rgrp->dev); |
| } |
| diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h b/drivers/gpu/drm/rcar-du/rcar_du_group.h |
| index 4487e83fb2c1..5025930972ec 100644 |
| --- a/drivers/gpu/drm/rcar-du/rcar_du_group.h |
| +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.h |
| @@ -45,6 +45,6 @@ int rcar_du_group_get(struct rcar_du_group *rgrp); |
| void rcar_du_group_put(struct rcar_du_group *rgrp); |
| void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start); |
| void rcar_du_group_restart(struct rcar_du_group *rgrp); |
| -void rcar_du_group_set_routing(struct rcar_du_group *rgrp); |
| +int rcar_du_group_set_routing(struct rcar_du_group *rgrp); |
| |
| #endif /* __RCAR_DU_GROUP_H__ */ |
| -- |
| 1.8.5.rc3 |
| |