Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+69 -20
+15
drivers/gpu/drm/zte/zx_plane.c
··· 197 197 /* Enable HBSC block */ 198 198 zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN); 199 199 200 + zx_vou_layer_enable(plane); 201 + 200 202 zx_gl_set_update(zplane); 203 + } 204 + 205 + static 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); 201 215 } 202 216 203 217 static const struct drm_plane_helper_funcs zx_gl_plane_helper_funcs = { 204 218 .atomic_check = zx_gl_plane_atomic_check, 205 219 .atomic_update = zx_gl_plane_atomic_update, 220 + .atomic_disable = zx_plane_atomic_disable, 206 221 }; 207 222 208 223 static void zx_plane_destroy(struct drm_plane *plane)
+1
drivers/gpu/drm/zte/zx_plane.h
··· 18 18 void __iomem *csc; 19 19 void __iomem *hbsc; 20 20 void __iomem *rsz; 21 + const struct vou_layer_bits *bits; 21 22 }; 22 23 23 24 #define to_zx_plane(plane) container_of(plane, struct zx_plane, plane)
+50 -20
drivers/gpu/drm/zte/zx_vou.c
··· 65 65 u32 polarity_shift; 66 66 u32 int_frame_mask; 67 67 u32 tc_enable; 68 - u32 gl_enable; 69 68 }; 70 69 71 70 static const struct zx_crtc_bits main_crtc_bits = { ··· 72 73 .polarity_shift = MAIN_POL_SHIFT, 73 74 .int_frame_mask = TIMING_INT_MAIN_FRAME, 74 75 .tc_enable = MAIN_TC_EN, 75 - .gl_enable = OSD_CTRL0_GL0_EN, 76 76 }; 77 77 78 78 static const struct zx_crtc_bits aux_crtc_bits = { ··· 79 81 .polarity_shift = AUX_POL_SHIFT, 80 82 .int_frame_mask = TIMING_INT_AUX_FRAME, 81 83 .tc_enable = AUX_TC_EN, 82 - .gl_enable = OSD_CTRL0_GL1_EN, 83 84 }; 84 85 85 86 struct zx_crtc { ··· 93 96 }; 94 97 95 98 #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc) 99 + 100 + struct vou_layer_bits { 101 + u32 enable; 102 + u32 chnsel; 103 + u32 clksel; 104 + }; 105 + 106 + static const struct vou_layer_bits zx_gl_bits[GL_NUM] = { 107 + { 108 + .enable = OSD_CTRL0_GL0_EN, 109 + .chnsel = OSD_CTRL0_GL0_SEL, 110 + .clksel = VOU_CLK_GL0_SEL, 111 + }, { 112 + .enable = OSD_CTRL0_GL1_EN, 113 + .chnsel = OSD_CTRL0_GL1_SEL, 114 + .clksel = VOU_CLK_GL1_SEL, 115 + }, 116 + }; 96 117 97 118 struct zx_vou_hw { 98 119 struct device *dev; ··· 244 229 /* Enable channel */ 245 230 zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE); 246 231 247 - /* Enable Graphic Layer */ 248 - zx_writel_mask(vou->osd + OSD_CTRL0, bits->gl_enable, 249 - bits->gl_enable); 250 - 251 232 drm_crtc_vblank_on(crtc); 252 233 253 234 ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000); ··· 266 255 clk_disable_unprepare(zcrtc->pixclk); 267 256 268 257 drm_crtc_vblank_off(crtc); 269 - 270 - /* Disable Graphic Layer */ 271 - zx_writel_mask(vou->osd + OSD_CTRL0, bits->gl_enable, 0); 272 258 273 259 /* Disable channel */ 274 260 zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0); ··· 333 325 zplane->csc = vou->osd + MAIN_CSC_OFFSET; 334 326 zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET; 335 327 zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET; 328 + zplane->bits = &zx_gl_bits[0]; 336 329 zcrtc->chnreg = vou->osd + OSD_MAIN_CHN; 337 330 zcrtc->regs = &main_crtc_regs; 338 331 zcrtc->bits = &main_crtc_bits; ··· 342 333 zplane->csc = vou->osd + AUX_CSC_OFFSET; 343 334 zplane->hbsc = vou->osd + AUX_HBSC_OFFSET; 344 335 zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET; 336 + zplane->bits = &zx_gl_bits[1]; 345 337 zcrtc->chnreg = vou->osd + OSD_AUX_CHN; 346 338 zcrtc->regs = &aux_crtc_regs; 347 339 zcrtc->bits = &aux_crtc_bits; ··· 430 420 zcrtc->bits->int_frame_mask, 0); 431 421 } 432 422 423 + void zx_vou_layer_enable(struct drm_plane *plane) 424 + { 425 + struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc); 426 + struct zx_vou_hw *vou = zcrtc->vou; 427 + struct zx_plane *zplane = to_zx_plane(plane); 428 + const struct vou_layer_bits *bits = zplane->bits; 429 + 430 + if (zcrtc->chn_type == VOU_CHN_MAIN) { 431 + zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0); 432 + zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0); 433 + } else { 434 + zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 435 + bits->chnsel); 436 + zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 437 + bits->clksel); 438 + } 439 + 440 + zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable); 441 + } 442 + 443 + void zx_vou_layer_disable(struct drm_plane *plane) 444 + { 445 + struct zx_crtc *zcrtc = to_zx_crtc(plane->crtc); 446 + struct zx_vou_hw *vou = zcrtc->vou; 447 + struct zx_plane *zplane = to_zx_plane(plane); 448 + const struct vou_layer_bits *bits = zplane->bits; 449 + 450 + zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0); 451 + } 452 + 433 453 static irqreturn_t vou_irq_handler(int irq, void *dev_id) 434 454 { 435 455 struct zx_vou_hw *vou = dev_id; ··· 518 478 519 479 static void vou_hw_init(struct zx_vou_hw *vou) 520 480 { 521 - /* Set GL0 to main channel and GL1 to aux channel */ 522 - zx_writel_mask(vou->osd + OSD_CTRL0, OSD_CTRL0_GL0_SEL, 0); 523 - zx_writel_mask(vou->osd + OSD_CTRL0, OSD_CTRL0_GL1_SEL, 524 - OSD_CTRL0_GL1_SEL); 525 - 526 481 /* Release reset for all VOU modules */ 527 482 zx_writel(vou->vouctl + VOU_SOFT_RST, ~0); 528 - 529 - /* Select main clock for GL0 and aux clock for GL1 module */ 530 - zx_writel_mask(vou->vouctl + VOU_CLK_SEL, VOU_CLK_GL0_SEL, 0); 531 - zx_writel_mask(vou->vouctl + VOU_CLK_SEL, VOU_CLK_GL1_SEL, 532 - VOU_CLK_GL1_SEL); 533 483 534 484 /* Enable clock auto-gating for all VOU modules */ 535 485 zx_writel(vou->vouctl + VOU_CLK_REQEN, ~0);
+3
drivers/gpu/drm/zte/zx_vou.h
··· 53 53 int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe); 54 54 void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe); 55 55 56 + void zx_vou_layer_enable(struct drm_plane *plane); 57 + void zx_vou_layer_disable(struct drm_plane *plane); 58 + 56 59 #endif /* __ZX_VOU_H__ */