aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2016-12-28 19:03:03 -0500
committerShawn Guo <shawn.guo@linaro.org>2017-01-27 21:17:40 -0500
commit7254b1f91ebc221ef71f7b23129a2ec0558e50cb (patch)
treef362a64318e12f572d9cae3122e5857eeb372660
parent98ae9869d187ab737b5b231e7879d15e1e9a763d (diff)
drm: zte: add .atomic_disable hook to disable graphic layer
There are a few hardware bits for each graphic layer to control main/aux channel and clock selection, as well as the layer enabling. These bits sit outside the layer block itself, but in VOU control glue block. We currently set these bits up at CRTC initialization for once, and do not support disabling the layer. This patch creates a pair of functions zx_vou_layer_enable[disable] to be invoked from plane hooks .atomic_update and .atomic_disable to set up and tear down the layer. This is generic for both graphic and video layers, so it will make the overlay plane support to be added later much easier. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Reviewed-by: Sean Paul <seanpaul@chromium.org>
-rw-r--r--drivers/gpu/drm/zte/zx_plane.c15
-rw-r--r--drivers/gpu/drm/zte/zx_plane.h1
-rw-r--r--drivers/gpu/drm/zte/zx_vou.c70
-rw-r--r--drivers/gpu/drm/zte/zx_vou.h3
4 files changed, 69 insertions, 20 deletions
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 78d29b1db91c..5445eebf830f 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -197,12 +197,27 @@ static void zx_gl_plane_atomic_update(struct drm_plane *plane,
197 /* Enable HBSC block */ 197 /* Enable HBSC block */
198 zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN); 198 zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN);
199 199
200 zx_vou_layer_enable(plane);
201
200 zx_gl_set_update(zplane); 202 zx_gl_set_update(zplane);
201} 203}
202 204
205static void zx_plane_atomic_disable(struct drm_plane *plane,
206 struct drm_plane_state *old_state)
207{
208 struct zx_plane *zplane = to_zx_plane(plane);
209 void __iomem *hbsc = zplane->hbsc;
210
211 zx_vou_layer_disable(plane);
212
213 /* Disable HBSC block */
214 zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, 0);
215}
216
203static const struct drm_plane_helper_funcs zx_gl_plane_helper_funcs = { 217static const struct drm_plane_helper_funcs zx_gl_plane_helper_funcs = {
204 .atomic_check = zx_gl_plane_atomic_check, 218 .atomic_check = zx_gl_plane_atomic_check,
205 .atomic_update = zx_gl_plane_atomic_update, 219 .atomic_update = zx_gl_plane_atomic_update,
220 .atomic_disable = zx_plane_atomic_disable,
206}; 221};
207 222
208static void zx_plane_destroy(struct drm_plane *plane) 223static void zx_plane_destroy(struct drm_plane *plane)
diff --git a/drivers/gpu/drm/zte/zx_plane.h b/drivers/gpu/drm/zte/zx_plane.h
index 264a92e0b532..933611ddffd0 100644
--- a/drivers/gpu/drm/zte/zx_plane.h
+++ b/drivers/gpu/drm/zte/zx_plane.h
@@ -18,6 +18,7 @@ struct zx_plane {
18 void __iomem *csc; 18 void __iomem *csc;
19 void __iomem *hbsc; 19 void __iomem *hbsc;
20 void __iomem *rsz; 20 void __iomem *rsz;
21 const struct vou_layer_bits *bits;
21}; 22};
22 23
23#define to_zx_plane(plane) container_of(plane, struct zx_plane, plane) 24#define to_zx_plane(plane) container_of(plane, struct zx_plane, plane)
diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c
index 1bc8f8762956..d299a3528282 100644
--- a/drivers/gpu/drm/zte/zx_vou.c
+++ b/drivers/gpu/drm/zte/zx_vou.c
@@ -65,7 +65,6 @@ struct zx_crtc_bits {
65 u32 polarity_shift; 65 u32 polarity_shift;
66 u32 int_frame_mask; 66 u32 int_frame_mask;
67 u32 tc_enable; 67 u32 tc_enable;
68 u32 gl_enable;
69}; 68};
70 69
71static const struct zx_crtc_bits main_crtc_bits = { 70static const struct zx_crtc_bits main_crtc_bits = {
@@ -73,7 +72,6 @@ static const struct zx_crtc_bits main_crtc_bits = {
73 .polarity_shift = MAIN_POL_SHIFT, 72 .polarity_shift = MAIN_POL_SHIFT,
74 .int_frame_mask = TIMING_INT_MAIN_FRAME, 73 .int_frame_mask = TIMING_INT_MAIN_FRAME,
75 .tc_enable = MAIN_TC_EN, 74 .tc_enable = MAIN_TC_EN,
76 .gl_enable = OSD_CTRL0_GL0_EN,
77}; 75};
78 76
79static const struct zx_crtc_bits aux_crtc_bits = { 77static const struct zx_crtc_bits aux_crtc_bits = {
@@ -81,7 +79,6 @@ static const struct zx_crtc_bits aux_crtc_bits = {
81 .polarity_shift = AUX_POL_SHIFT, 79 .polarity_shift = AUX_POL_SHIFT,
82 .int_frame_mask = TIMING_INT_AUX_FRAME, 80 .int_frame_mask = TIMING_INT_AUX_FRAME,
83 .tc_enable = AUX_TC_EN, 81 .tc_enable = AUX_TC_EN,
84 .gl_enable = OSD_CTRL0_GL1_EN,
85}; 82};
86 83
87struct zx_crtc { 84struct zx_crtc {
@@ -97,6 +94,24 @@ struct zx_crtc {
97 94
98#define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc) 95#define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
99 96
97struct vou_layer_bits {
98 u32 enable;
99 u32 chnsel;
100 u32 clksel;
101};
102
103static const struct vou_layer_bits zx_gl_bits[GL_NUM] = {
104 {
105 .enable = OSD_CTRL0_GL0_EN,
106 .chnsel = OSD_CTRL0_GL0_SEL,
107 .clksel = VOU_CLK_GL0_SEL,
108 }, {
109 .enable = OSD_CTRL0_GL1_EN,
110 .chnsel = OSD_CTRL0_GL1_SEL,
111 .clksel = VOU_CLK_GL1_SEL,
112 },
113};
114
100struct zx_vou_hw { 115struct zx_vou_hw {
101 struct device *dev; 116 struct device *dev;
102 void __iomem *osd; 117 void __iomem *osd;
@@ -229,10 +244,6 @@ static void zx_crtc_enable(struct drm_crtc *crtc)
229 /* Enable channel */ 244 /* Enable channel */
230 zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE); 245 zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE);
231 246
232 /* Enable Graphic Layer */
233 zx_writel_mask(vou->osd + OSD_CTRL0, bits->gl_enable,
234 bits->gl_enable);
235
236 drm_crtc_vblank_on(crtc); 247 drm_crtc_vblank_on(crtc);
237 248
238 ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000); 249 ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000);
@@ -256,9 +267,6 @@ static void zx_crtc_disable(struct drm_crtc *crtc)
256 267
257 drm_crtc_vblank_off(crtc); 268 drm_crtc_vblank_off(crtc);
258 269
259 /* Disable Graphic Layer */
260 zx_writel_mask(vou->osd + OSD_CTRL0, bits->gl_enable, 0);
261
262 /* Disable channel */ 270 /* Disable channel */
263 zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0); 271 zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0);
264 272
@@ -325,6 +333,7 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
325 zplane->csc = vou->osd + MAIN_CSC_OFFSET; 333 zplane->csc = vou->osd + MAIN_CSC_OFFSET;
326 zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET; 334 zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
327 zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET; 335 zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
336 zplane->bits = &zx_gl_bits[0];
328 zcrtc->chnreg = vou->osd + OSD_MAIN_CHN; 337 zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
329 zcrtc->regs = &main_crtc_regs; 338 zcrtc->regs = &main_crtc_regs;
330 zcrtc->bits = &main_crtc_bits; 339 zcrtc->bits = &main_crtc_bits;
@@ -333,6 +342,7 @@ static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
333 zplane->csc = vou->osd + AUX_CSC_OFFSET; 342 zplane->csc = vou->osd + AUX_CSC_OFFSET;
334 zplane->hbsc = vou->osd + AUX_HBSC_OFFSET; 343 zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
335 zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET; 344 zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
345 zplane->bits = &zx_gl_bits[1];
336 zcrtc->chnreg = vou->osd + OSD_AUX_CHN; 346 zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
337 zcrtc->regs = &aux_crtc_regs; 347 zcrtc->regs = &aux_crtc_regs;
338 zcrtc->bits = &aux_crtc_bits; 348 zcrtc->bits = &aux_crtc_bits;
@@ -420,6 +430,36 @@ void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe)
420 zcrtc->bits->int_frame_mask, 0); 430 zcrtc->bits->int_frame_mask, 0);
421} 431}
422 432
433void zx_vou_layer_enable(struct drm_plane *plane)
434{
435 struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc);
436 struct zx_vou_hw *vou = zcrtc->vou;
437 struct zx_plane *zplane = to_zx_plane(plane);
438 const struct vou_layer_bits *bits = zplane->bits;
439
440 if (zcrtc->chn_type == VOU_CHN_MAIN) {
441 zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0);
442 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0);
443 } else {
444 zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel,
445 bits->chnsel);
446 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel,
447 bits->clksel);
448 }
449
450 zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
451}
452
453void zx_vou_layer_disable(struct drm_plane *plane)
454{
455 struct zx_crtc *zcrtc = to_zx_crtc(plane->crtc);
456 struct zx_vou_hw *vou = zcrtc->vou;
457 struct zx_plane *zplane = to_zx_plane(plane);
458 const struct vou_layer_bits *bits = zplane->bits;
459
460 zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
461}
462
423static irqreturn_t vou_irq_handler(int irq, void *dev_id) 463static irqreturn_t vou_irq_handler(int irq, void *dev_id)
424{ 464{
425 struct zx_vou_hw *vou = dev_id; 465 struct zx_vou_hw *vou = dev_id;
@@ -478,19 +518,9 @@ static void vou_dtrc_init(struct zx_vou_hw *vou)
478 518
479static void vou_hw_init(struct zx_vou_hw *vou) 519static void vou_hw_init(struct zx_vou_hw *vou)
480{ 520{
481 /* Set GL0 to main channel and GL1 to aux channel */
482 zx_writel_mask(vou->osd + OSD_CTRL0, OSD_CTRL0_GL0_SEL, 0);
483 zx_writel_mask(vou->osd + OSD_CTRL0, OSD_CTRL0_GL1_SEL,
484 OSD_CTRL0_GL1_SEL);
485
486 /* Release reset for all VOU modules */ 521 /* Release reset for all VOU modules */
487 zx_writel(vou->vouctl + VOU_SOFT_RST, ~0); 522 zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
488 523
489 /* Select main clock for GL0 and aux clock for GL1 module */
490 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, VOU_CLK_GL0_SEL, 0);
491 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, VOU_CLK_GL1_SEL,
492 VOU_CLK_GL1_SEL);
493
494 /* Enable clock auto-gating for all VOU modules */ 524 /* Enable clock auto-gating for all VOU modules */
495 zx_writel(vou->vouctl + VOU_CLK_REQEN, ~0); 525 zx_writel(vou->vouctl + VOU_CLK_REQEN, ~0);
496 526
diff --git a/drivers/gpu/drm/zte/zx_vou.h b/drivers/gpu/drm/zte/zx_vou.h
index e571b888a3ca..ace00ce318e5 100644
--- a/drivers/gpu/drm/zte/zx_vou.h
+++ b/drivers/gpu/drm/zte/zx_vou.h
@@ -53,4 +53,7 @@ void vou_inf_disable(const struct vou_inf *inf, struct drm_crtc *crtc);
53int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe); 53int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe);
54void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe); 54void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe);
55 55
56void zx_vou_layer_enable(struct drm_plane *plane);
57void zx_vou_layer_disable(struct drm_plane *plane);
58
56#endif /* __ZX_VOU_H__ */ 59#endif /* __ZX_VOU_H__ */