diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-06-16 21:20:08 -0400 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-08-09 17:17:52 -0400 |
commit | 7cbc05cb518304b746bea00bc7c0b005217bcaf7 (patch) | |
tree | 32162ad351e9048403ec95ec3192fa6a8ee02b2b /drivers/gpu/drm/rcar-du | |
parent | ef67a902e946ad1ef51040cf287a45cc4714e2b5 (diff) |
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>
Diffstat (limited to 'drivers/gpu/drm/rcar-du')
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_group.c | 45 | ||||
-rw-r--r-- | 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, | |||
139 | * configured when starting the CRTC. | 139 | * configured when starting the CRTC. |
140 | */ | 140 | */ |
141 | rcrtc->outputs |= BIT(output); | 141 | rcrtc->outputs |= BIT(output); |
142 | |||
143 | /* Store RGB routing to DPAD0 for R8A7790. */ | ||
144 | if (rcar_du_has(rcdu, RCAR_DU_FEATURE_DEFR8) && | ||
145 | output == RCAR_DU_OUTPUT_DPAD0) | ||
146 | rcdu->dpad0_source = rcrtc->index; | ||
142 | } | 147 | } |
143 | 148 | ||
144 | void rcar_du_crtc_update_planes(struct drm_crtc *crtc) | 149 | 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 { | |||
68 | unsigned int num_crtcs; | 68 | unsigned int num_crtcs; |
69 | 69 | ||
70 | struct rcar_du_group groups[2]; | 70 | struct rcar_du_group groups[2]; |
71 | |||
72 | unsigned int dpad0_source; | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | static inline bool rcar_du_has(struct rcar_du_device *rcdu, | 75 | 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 @@ | |||
27 | * counterpart in the DU documentation, that models those semi-global resources. | 27 | * counterpart in the DU documentation, that models those semi-global resources. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/clk.h> | ||
30 | #include <linux/io.h> | 31 | #include <linux/io.h> |
31 | 32 | ||
32 | #include "rcar_du_drv.h" | 33 | #include "rcar_du_drv.h" |
@@ -43,6 +44,22 @@ void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data) | |||
43 | rcar_du_write(rgrp->dev, rgrp->mmio_offset + reg, data); | 44 | rcar_du_write(rgrp->dev, rgrp->mmio_offset + reg, data); |
44 | } | 45 | } |
45 | 46 | ||
47 | static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp) | ||
48 | { | ||
49 | u32 defr8 = DEFR8_CODE | DEFR8_DEFE8; | ||
50 | |||
51 | if (!rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_DEFR8)) | ||
52 | return; | ||
53 | |||
54 | /* The DEFR8 register for the first group also controls RGB output | ||
55 | * routing to DPAD0 | ||
56 | */ | ||
57 | if (rgrp->index == 0) | ||
58 | defr8 |= DEFR8_DRGBS_DU(rgrp->dev->dpad0_source); | ||
59 | |||
60 | rcar_du_group_write(rgrp, DEFR8, defr8); | ||
61 | } | ||
62 | |||
46 | static void rcar_du_group_setup(struct rcar_du_group *rgrp) | 63 | static void rcar_du_group_setup(struct rcar_du_group *rgrp) |
47 | { | 64 | { |
48 | /* Enable extended features */ | 65 | /* Enable extended features */ |
@@ -51,8 +68,8 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp) | |||
51 | rcar_du_group_write(rgrp, DEFR3, DEFR3_CODE | DEFR3_DEFE3); | 68 | rcar_du_group_write(rgrp, DEFR3, DEFR3_CODE | DEFR3_DEFE3); |
52 | rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE); | 69 | rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE); |
53 | rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5); | 70 | rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5); |
54 | if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_DEFR8)) | 71 | |
55 | rcar_du_group_write(rgrp, DEFR8, DEFR8_CODE | DEFR8_DEFE8); | 72 | rcar_du_group_setup_defr8(rgrp); |
56 | 73 | ||
57 | /* Use DS1PR and DS2PR to configure planes priorities and connects the | 74 | /* Use DS1PR and DS2PR to configure planes priorities and connects the |
58 | * superposition 0 to DU0 pins. DU1 pins will be configured dynamically. | 75 | * 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) | |||
128 | __rcar_du_group_start_stop(rgrp, true); | 145 | __rcar_du_group_start_stop(rgrp, true); |
129 | } | 146 | } |
130 | 147 | ||
131 | void rcar_du_group_set_routing(struct rcar_du_group *rgrp) | 148 | static int rcar_du_set_dpad0_routing(struct rcar_du_device *rcdu) |
149 | { | ||
150 | int ret; | ||
151 | |||
152 | /* RGB output routing to DPAD0 is configured in the DEFR8 register of | ||
153 | * the first group. As this function can be called with the DU0 and DU1 | ||
154 | * CRTCs disabled, we need to enable the first group clock before | ||
155 | * accessing the register. | ||
156 | */ | ||
157 | ret = clk_prepare_enable(rcdu->crtcs[0].clock); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | |||
161 | rcar_du_group_setup_defr8(&rcdu->groups[0]); | ||
162 | |||
163 | clk_disable_unprepare(rcdu->crtcs[0].clock); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | int rcar_du_group_set_routing(struct rcar_du_group *rgrp) | ||
132 | { | 169 | { |
133 | struct rcar_du_crtc *crtc0 = &rgrp->dev->crtcs[rgrp->index * 2]; | 170 | struct rcar_du_crtc *crtc0 = &rgrp->dev->crtcs[rgrp->index * 2]; |
134 | u32 dorcr = rcar_du_group_read(rgrp, DORCR); | 171 | u32 dorcr = rcar_du_group_read(rgrp, DORCR); |
@@ -145,4 +182,6 @@ void rcar_du_group_set_routing(struct rcar_du_group *rgrp) | |||
145 | dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2; | 182 | dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2; |
146 | 183 | ||
147 | rcar_du_group_write(rgrp, DORCR, dorcr); | 184 | rcar_du_group_write(rgrp, DORCR, dorcr); |
185 | |||
186 | return rcar_du_set_dpad0_routing(rgrp->dev); | ||
148 | } | 187 | } |
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); | |||
45 | void rcar_du_group_put(struct rcar_du_group *rgrp); | 45 | void rcar_du_group_put(struct rcar_du_group *rgrp); |
46 | void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start); | 46 | void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start); |
47 | void rcar_du_group_restart(struct rcar_du_group *rgrp); | 47 | void rcar_du_group_restart(struct rcar_du_group *rgrp); |
48 | void rcar_du_group_set_routing(struct rcar_du_group *rgrp); | 48 | int rcar_du_group_set_routing(struct rcar_du_group *rgrp); |
49 | 49 | ||
50 | #endif /* __RCAR_DU_GROUP_H__ */ | 50 | #endif /* __RCAR_DU_GROUP_H__ */ |