1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2016 Linaro Ltd.
4 * Copyright 2016 ZTE Corporation.
8 #include <linux/component.h>
9 #include <linux/of_address.h>
10 #include <video/videomode.h>
12 #include <drm/drm_atomic_helper.h>
13 #include <drm/drm_crtc.h>
14 #include <drm/drm_fb_cma_helper.h>
15 #include <drm/drm_fb_helper.h>
16 #include <drm/drm_gem_cma_helper.h>
17 #include <drm/drm_of.h>
18 #include <drm/drm_plane_helper.h>
19 #include <drm/drm_probe_helper.h>
22 #include "zx_common_regs.h"
23 #include "zx_drm_drv.h"
26 #include "zx_vou_regs.h"
45 static const struct zx_crtc_regs main_crtc_regs
= {
46 .fir_active
= FIR_MAIN_ACTIVE
,
47 .fir_htiming
= FIR_MAIN_H_TIMING
,
48 .fir_vtiming
= FIR_MAIN_V_TIMING
,
49 .sec_vtiming
= SEC_MAIN_V_TIMING
,
50 .timing_shift
= TIMING_MAIN_SHIFT
,
51 .timing_pi_shift
= TIMING_MAIN_PI_SHIFT
,
54 static const struct zx_crtc_regs aux_crtc_regs
= {
55 .fir_active
= FIR_AUX_ACTIVE
,
56 .fir_htiming
= FIR_AUX_H_TIMING
,
57 .fir_vtiming
= FIR_AUX_V_TIMING
,
58 .sec_vtiming
= SEC_AUX_V_TIMING
,
59 .timing_shift
= TIMING_AUX_SHIFT
,
60 .timing_pi_shift
= TIMING_AUX_PI_SHIFT
,
68 u32 sec_vactive_shift
;
75 u32 div_hdmi_pnx_shift
;
81 static const struct zx_crtc_bits main_crtc_bits
= {
82 .polarity_mask
= MAIN_POL_MASK
,
83 .polarity_shift
= MAIN_POL_SHIFT
,
84 .int_frame_mask
= TIMING_INT_MAIN_FRAME
,
85 .tc_enable
= MAIN_TC_EN
,
86 .sec_vactive_shift
= SEC_VACT_MAIN_SHIFT
,
87 .sec_vactive_mask
= SEC_VACT_MAIN_MASK
,
88 .interlace_select
= MAIN_INTERLACE_SEL
,
89 .pi_enable
= MAIN_PI_EN
,
90 .div_vga_shift
= VGA_MAIN_DIV_SHIFT
,
91 .div_pic_shift
= PIC_MAIN_DIV_SHIFT
,
92 .div_tvenc_shift
= TVENC_MAIN_DIV_SHIFT
,
93 .div_hdmi_pnx_shift
= HDMI_MAIN_PNX_DIV_SHIFT
,
94 .div_hdmi_shift
= HDMI_MAIN_DIV_SHIFT
,
95 .div_inf_shift
= INF_MAIN_DIV_SHIFT
,
96 .div_layer_shift
= LAYER_MAIN_DIV_SHIFT
,
99 static const struct zx_crtc_bits aux_crtc_bits
= {
100 .polarity_mask
= AUX_POL_MASK
,
101 .polarity_shift
= AUX_POL_SHIFT
,
102 .int_frame_mask
= TIMING_INT_AUX_FRAME
,
103 .tc_enable
= AUX_TC_EN
,
104 .sec_vactive_shift
= SEC_VACT_AUX_SHIFT
,
105 .sec_vactive_mask
= SEC_VACT_AUX_MASK
,
106 .interlace_select
= AUX_INTERLACE_SEL
,
107 .pi_enable
= AUX_PI_EN
,
108 .div_vga_shift
= VGA_AUX_DIV_SHIFT
,
109 .div_pic_shift
= PIC_AUX_DIV_SHIFT
,
110 .div_tvenc_shift
= TVENC_AUX_DIV_SHIFT
,
111 .div_hdmi_pnx_shift
= HDMI_AUX_PNX_DIV_SHIFT
,
112 .div_hdmi_shift
= HDMI_AUX_DIV_SHIFT
,
113 .div_inf_shift
= INF_AUX_DIV_SHIFT
,
114 .div_layer_shift
= LAYER_AUX_DIV_SHIFT
,
118 struct drm_crtc crtc
;
119 struct drm_plane
*primary
;
120 struct zx_vou_hw
*vou
;
121 void __iomem
*chnreg
;
122 void __iomem
*chncsc
;
123 void __iomem
*dither
;
124 const struct zx_crtc_regs
*regs
;
125 const struct zx_crtc_bits
*bits
;
126 enum vou_chn_type chn_type
;
130 #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
132 struct vou_layer_bits
{
138 static const struct vou_layer_bits zx_gl_bits
[GL_NUM
] = {
140 .enable
= OSD_CTRL0_GL0_EN
,
141 .chnsel
= OSD_CTRL0_GL0_SEL
,
142 .clksel
= VOU_CLK_GL0_SEL
,
144 .enable
= OSD_CTRL0_GL1_EN
,
145 .chnsel
= OSD_CTRL0_GL1_SEL
,
146 .clksel
= VOU_CLK_GL1_SEL
,
150 static const struct vou_layer_bits zx_vl_bits
[VL_NUM
] = {
152 .enable
= OSD_CTRL0_VL0_EN
,
153 .chnsel
= OSD_CTRL0_VL0_SEL
,
154 .clksel
= VOU_CLK_VL0_SEL
,
156 .enable
= OSD_CTRL0_VL1_EN
,
157 .chnsel
= OSD_CTRL0_VL1_SEL
,
158 .clksel
= VOU_CLK_VL1_SEL
,
160 .enable
= OSD_CTRL0_VL2_EN
,
161 .chnsel
= OSD_CTRL0_VL2_SEL
,
162 .clksel
= VOU_CLK_VL2_SEL
,
169 void __iomem
*timing
;
170 void __iomem
*vouctl
;
171 void __iomem
*otfppu
;
175 struct clk
*main_clk
;
177 struct zx_crtc
*main_crtc
;
178 struct zx_crtc
*aux_crtc
;
181 enum vou_inf_data_sel
{
190 enum vou_inf_data_sel data_sel
;
195 static struct vou_inf vou_infs
[] = {
197 .data_sel
= VOU_YUV444
,
198 .clocks_en_bits
= BIT(24) | BIT(18) | BIT(6),
199 .clocks_sel_bits
= BIT(13) | BIT(2),
202 .data_sel
= VOU_YUV444
,
203 .clocks_en_bits
= BIT(15),
204 .clocks_sel_bits
= BIT(11) | BIT(0),
207 .data_sel
= VOU_RGB_888
,
208 .clocks_en_bits
= BIT(1),
209 .clocks_sel_bits
= BIT(10),
213 static inline struct zx_vou_hw
*crtc_to_vou(struct drm_crtc
*crtc
)
215 struct zx_crtc
*zcrtc
= to_zx_crtc(crtc
);
220 void vou_inf_hdmi_audio_sel(struct drm_crtc
*crtc
,
221 enum vou_inf_hdmi_audio aud
)
223 struct zx_crtc
*zcrtc
= to_zx_crtc(crtc
);
224 struct zx_vou_hw
*vou
= zcrtc
->vou
;
226 zx_writel_mask(vou
->vouctl
+ VOU_INF_HDMI_CTRL
, VOU_HDMI_AUD_MASK
, aud
);
229 void vou_inf_enable(enum vou_inf_id id
, struct drm_crtc
*crtc
)
231 struct zx_crtc
*zcrtc
= to_zx_crtc(crtc
);
232 struct zx_vou_hw
*vou
= zcrtc
->vou
;
233 struct vou_inf
*inf
= &vou_infs
[id
];
234 void __iomem
*dither
= zcrtc
->dither
;
235 void __iomem
*csc
= zcrtc
->chncsc
;
236 bool is_main
= zcrtc
->chn_type
== VOU_CHN_MAIN
;
237 u32 data_sel_shift
= id
<< 1;
239 if (inf
->data_sel
!= VOU_YUV444
) {
240 /* Enable channel CSC for RGB output */
241 zx_writel_mask(csc
+ CSC_CTRL0
, CSC_COV_MODE_MASK
,
242 CSC_BT709_IMAGE_YCBCR2RGB
<< CSC_COV_MODE_SHIFT
);
243 zx_writel_mask(csc
+ CSC_CTRL0
, CSC_WORK_ENABLE
,
246 /* Bypass Dither block for RGB output */
247 zx_writel_mask(dither
+ OSD_DITHER_CTRL0
, DITHER_BYSPASS
,
250 zx_writel_mask(csc
+ CSC_CTRL0
, CSC_WORK_ENABLE
, 0);
251 zx_writel_mask(dither
+ OSD_DITHER_CTRL0
, DITHER_BYSPASS
, 0);
254 /* Select data format */
255 zx_writel_mask(vou
->vouctl
+ VOU_INF_DATA_SEL
, 0x3 << data_sel_shift
,
256 inf
->data_sel
<< data_sel_shift
);
259 zx_writel_mask(vou
->vouctl
+ VOU_INF_CH_SEL
, 0x1 << id
,
260 zcrtc
->chn_type
<< id
);
262 /* Select interface clocks */
263 zx_writel_mask(vou
->vouctl
+ VOU_CLK_SEL
, inf
->clocks_sel_bits
,
264 is_main
? 0 : inf
->clocks_sel_bits
);
266 /* Enable interface clocks */
267 zx_writel_mask(vou
->vouctl
+ VOU_CLK_EN
, inf
->clocks_en_bits
,
268 inf
->clocks_en_bits
);
270 /* Enable the device */
271 zx_writel_mask(vou
->vouctl
+ VOU_INF_EN
, 1 << id
, 1 << id
);
274 void vou_inf_disable(enum vou_inf_id id
, struct drm_crtc
*crtc
)
276 struct zx_vou_hw
*vou
= crtc_to_vou(crtc
);
277 struct vou_inf
*inf
= &vou_infs
[id
];
279 /* Disable the device */
280 zx_writel_mask(vou
->vouctl
+ VOU_INF_EN
, 1 << id
, 0);
282 /* Disable interface clocks */
283 zx_writel_mask(vou
->vouctl
+ VOU_CLK_EN
, inf
->clocks_en_bits
, 0);
286 void zx_vou_config_dividers(struct drm_crtc
*crtc
,
287 struct vou_div_config
*configs
, int num
)
289 struct zx_crtc
*zcrtc
= to_zx_crtc(crtc
);
290 struct zx_vou_hw
*vou
= zcrtc
->vou
;
291 const struct zx_crtc_bits
*bits
= zcrtc
->bits
;
294 /* Clear update flag bit */
295 zx_writel_mask(vou
->vouctl
+ VOU_DIV_PARA
, DIV_PARA_UPDATE
, 0);
297 for (i
= 0; i
< num
; i
++) {
298 struct vou_div_config
*cfg
= configs
+ i
;
304 shift
= bits
->div_vga_shift
;
308 shift
= bits
->div_pic_shift
;
312 shift
= bits
->div_tvenc_shift
;
314 case VOU_DIV_HDMI_PNX
:
316 shift
= bits
->div_hdmi_pnx_shift
;
320 shift
= bits
->div_hdmi_shift
;
324 shift
= bits
->div_inf_shift
;
328 shift
= bits
->div_layer_shift
;
334 /* Each divider occupies 3 bits */
335 zx_writel_mask(vou
->vouctl
+ reg
, 0x7 << shift
,
339 /* Set update flag bit to get dividers effected */
340 zx_writel_mask(vou
->vouctl
+ VOU_DIV_PARA
, DIV_PARA_UPDATE
,
344 static inline void vou_chn_set_update(struct zx_crtc
*zcrtc
)
346 zx_writel(zcrtc
->chnreg
+ CHN_UPDATE
, 1);
349 static void zx_crtc_atomic_enable(struct drm_crtc
*crtc
,
350 struct drm_crtc_state
*old_state
)
352 struct drm_display_mode
*mode
= &crtc
->state
->adjusted_mode
;
353 bool interlaced
= mode
->flags
& DRM_MODE_FLAG_INTERLACE
;
354 struct zx_crtc
*zcrtc
= to_zx_crtc(crtc
);
355 struct zx_vou_hw
*vou
= zcrtc
->vou
;
356 const struct zx_crtc_regs
*regs
= zcrtc
->regs
;
357 const struct zx_crtc_bits
*bits
= zcrtc
->bits
;
364 drm_display_mode_to_videomode(mode
, &vm
);
366 /* Set up timing parameters */
367 val
= V_ACTIVE((interlaced
? vm
.vactive
/ 2 : vm
.vactive
) - 1);
368 val
|= H_ACTIVE(vm
.hactive
- 1);
369 zx_writel(vou
->timing
+ regs
->fir_active
, val
);
371 val
= SYNC_WIDE(vm
.hsync_len
- 1);
372 val
|= BACK_PORCH(vm
.hback_porch
- 1);
373 val
|= FRONT_PORCH(vm
.hfront_porch
- 1);
374 zx_writel(vou
->timing
+ regs
->fir_htiming
, val
);
376 val
= SYNC_WIDE(vm
.vsync_len
- 1);
377 val
|= BACK_PORCH(vm
.vback_porch
- 1);
378 val
|= FRONT_PORCH(vm
.vfront_porch
- 1);
379 zx_writel(vou
->timing
+ regs
->fir_vtiming
, val
);
382 u32 shift
= bits
->sec_vactive_shift
;
383 u32 mask
= bits
->sec_vactive_mask
;
385 val
= zx_readl(vou
->timing
+ SEC_V_ACTIVE
);
387 val
|= ((vm
.vactive
/ 2 - 1) << shift
) & mask
;
388 zx_writel(vou
->timing
+ SEC_V_ACTIVE
, val
);
390 val
= SYNC_WIDE(vm
.vsync_len
- 1);
392 * The vback_porch for the second field needs to shift one on
393 * the value for the first field.
395 val
|= BACK_PORCH(vm
.vback_porch
);
396 val
|= FRONT_PORCH(vm
.vfront_porch
- 1);
397 zx_writel(vou
->timing
+ regs
->sec_vtiming
, val
);
400 /* Set up polarities */
401 if (vm
.flags
& DISPLAY_FLAGS_VSYNC_LOW
)
402 pol
|= 1 << POL_VSYNC_SHIFT
;
403 if (vm
.flags
& DISPLAY_FLAGS_HSYNC_LOW
)
404 pol
|= 1 << POL_HSYNC_SHIFT
;
406 zx_writel_mask(vou
->timing
+ TIMING_CTRL
, bits
->polarity_mask
,
407 pol
<< bits
->polarity_shift
);
409 /* Setup SHIFT register by following what ZTE BSP does */
412 val
|= V_SHIFT_VAL
<< 16;
413 zx_writel(vou
->timing
+ regs
->timing_shift
, val
);
414 zx_writel(vou
->timing
+ regs
->timing_pi_shift
, H_PI_SHIFT_VAL
);
416 /* Progressive or interlace scan select */
417 scan_mask
= bits
->interlace_select
| bits
->pi_enable
;
418 zx_writel_mask(vou
->timing
+ SCAN_CTRL
, scan_mask
,
419 interlaced
? scan_mask
: 0);
421 /* Enable TIMING_CTRL */
422 zx_writel_mask(vou
->timing
+ TIMING_TC_ENABLE
, bits
->tc_enable
,
425 /* Configure channel screen size */
426 zx_writel_mask(zcrtc
->chnreg
+ CHN_CTRL1
, CHN_SCREEN_W_MASK
,
427 vm
.hactive
<< CHN_SCREEN_W_SHIFT
);
428 zx_writel_mask(zcrtc
->chnreg
+ CHN_CTRL1
, CHN_SCREEN_H_MASK
,
429 vm
.vactive
<< CHN_SCREEN_H_SHIFT
);
431 /* Configure channel interlace buffer control */
432 zx_writel_mask(zcrtc
->chnreg
+ CHN_INTERLACE_BUF_CTRL
, CHN_INTERLACE_EN
,
433 interlaced
? CHN_INTERLACE_EN
: 0);
436 vou_chn_set_update(zcrtc
);
439 zx_writel_mask(zcrtc
->chnreg
+ CHN_CTRL0
, CHN_ENABLE
, CHN_ENABLE
);
441 drm_crtc_vblank_on(crtc
);
443 ret
= clk_set_rate(zcrtc
->pixclk
, mode
->clock
* 1000);
445 DRM_DEV_ERROR(vou
->dev
, "failed to set pixclk rate: %d\n", ret
);
449 ret
= clk_prepare_enable(zcrtc
->pixclk
);
451 DRM_DEV_ERROR(vou
->dev
, "failed to enable pixclk: %d\n", ret
);
454 static void zx_crtc_atomic_disable(struct drm_crtc
*crtc
,
455 struct drm_crtc_state
*old_state
)
457 struct zx_crtc
*zcrtc
= to_zx_crtc(crtc
);
458 const struct zx_crtc_bits
*bits
= zcrtc
->bits
;
459 struct zx_vou_hw
*vou
= zcrtc
->vou
;
461 clk_disable_unprepare(zcrtc
->pixclk
);
463 drm_crtc_vblank_off(crtc
);
465 /* Disable channel */
466 zx_writel_mask(zcrtc
->chnreg
+ CHN_CTRL0
, CHN_ENABLE
, 0);
468 /* Disable TIMING_CTRL */
469 zx_writel_mask(vou
->timing
+ TIMING_TC_ENABLE
, bits
->tc_enable
, 0);
472 static void zx_crtc_atomic_flush(struct drm_crtc
*crtc
,
473 struct drm_crtc_state
*old_state
)
475 struct drm_pending_vblank_event
*event
= crtc
->state
->event
;
480 crtc
->state
->event
= NULL
;
482 spin_lock_irq(&crtc
->dev
->event_lock
);
483 if (drm_crtc_vblank_get(crtc
) == 0)
484 drm_crtc_arm_vblank_event(crtc
, event
);
486 drm_crtc_send_vblank_event(crtc
, event
);
487 spin_unlock_irq(&crtc
->dev
->event_lock
);
490 static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs
= {
491 .atomic_flush
= zx_crtc_atomic_flush
,
492 .atomic_enable
= zx_crtc_atomic_enable
,
493 .atomic_disable
= zx_crtc_atomic_disable
,
496 static int zx_vou_enable_vblank(struct drm_crtc
*crtc
)
498 struct zx_crtc
*zcrtc
= to_zx_crtc(crtc
);
499 struct zx_vou_hw
*vou
= crtc_to_vou(crtc
);
500 u32 int_frame_mask
= zcrtc
->bits
->int_frame_mask
;
502 zx_writel_mask(vou
->timing
+ TIMING_INT_CTRL
, int_frame_mask
,
508 static void zx_vou_disable_vblank(struct drm_crtc
*crtc
)
510 struct zx_crtc
*zcrtc
= to_zx_crtc(crtc
);
511 struct zx_vou_hw
*vou
= crtc_to_vou(crtc
);
513 zx_writel_mask(vou
->timing
+ TIMING_INT_CTRL
,
514 zcrtc
->bits
->int_frame_mask
, 0);
517 static const struct drm_crtc_funcs zx_crtc_funcs
= {
518 .destroy
= drm_crtc_cleanup
,
519 .set_config
= drm_atomic_helper_set_config
,
520 .page_flip
= drm_atomic_helper_page_flip
,
521 .reset
= drm_atomic_helper_crtc_reset
,
522 .atomic_duplicate_state
= drm_atomic_helper_crtc_duplicate_state
,
523 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
524 .enable_vblank
= zx_vou_enable_vblank
,
525 .disable_vblank
= zx_vou_disable_vblank
,
528 static int zx_crtc_init(struct drm_device
*drm
, struct zx_vou_hw
*vou
,
529 enum vou_chn_type chn_type
)
531 struct device
*dev
= vou
->dev
;
532 struct zx_plane
*zplane
;
533 struct zx_crtc
*zcrtc
;
536 zcrtc
= devm_kzalloc(dev
, sizeof(*zcrtc
), GFP_KERNEL
);
541 zcrtc
->chn_type
= chn_type
;
543 zplane
= devm_kzalloc(dev
, sizeof(*zplane
), GFP_KERNEL
);
549 if (chn_type
== VOU_CHN_MAIN
) {
550 zplane
->layer
= vou
->osd
+ MAIN_GL_OFFSET
;
551 zplane
->csc
= vou
->osd
+ MAIN_GL_CSC_OFFSET
;
552 zplane
->hbsc
= vou
->osd
+ MAIN_HBSC_OFFSET
;
553 zplane
->rsz
= vou
->otfppu
+ MAIN_RSZ_OFFSET
;
554 zplane
->bits
= &zx_gl_bits
[0];
555 zcrtc
->chnreg
= vou
->osd
+ OSD_MAIN_CHN
;
556 zcrtc
->chncsc
= vou
->osd
+ MAIN_CHN_CSC_OFFSET
;
557 zcrtc
->dither
= vou
->osd
+ MAIN_DITHER_OFFSET
;
558 zcrtc
->regs
= &main_crtc_regs
;
559 zcrtc
->bits
= &main_crtc_bits
;
561 zplane
->layer
= vou
->osd
+ AUX_GL_OFFSET
;
562 zplane
->csc
= vou
->osd
+ AUX_GL_CSC_OFFSET
;
563 zplane
->hbsc
= vou
->osd
+ AUX_HBSC_OFFSET
;
564 zplane
->rsz
= vou
->otfppu
+ AUX_RSZ_OFFSET
;
565 zplane
->bits
= &zx_gl_bits
[1];
566 zcrtc
->chnreg
= vou
->osd
+ OSD_AUX_CHN
;
567 zcrtc
->chncsc
= vou
->osd
+ AUX_CHN_CSC_OFFSET
;
568 zcrtc
->dither
= vou
->osd
+ AUX_DITHER_OFFSET
;
569 zcrtc
->regs
= &aux_crtc_regs
;
570 zcrtc
->bits
= &aux_crtc_bits
;
573 zcrtc
->pixclk
= devm_clk_get(dev
, (chn_type
== VOU_CHN_MAIN
) ?
574 "main_wclk" : "aux_wclk");
575 if (IS_ERR(zcrtc
->pixclk
)) {
576 ret
= PTR_ERR(zcrtc
->pixclk
);
577 DRM_DEV_ERROR(dev
, "failed to get pix clk: %d\n", ret
);
581 ret
= zx_plane_init(drm
, zplane
, DRM_PLANE_TYPE_PRIMARY
);
583 DRM_DEV_ERROR(dev
, "failed to init primary plane: %d\n", ret
);
587 zcrtc
->primary
= &zplane
->plane
;
589 ret
= drm_crtc_init_with_planes(drm
, &zcrtc
->crtc
, zcrtc
->primary
, NULL
,
590 &zx_crtc_funcs
, NULL
);
592 DRM_DEV_ERROR(dev
, "failed to init drm crtc: %d\n", ret
);
596 drm_crtc_helper_add(&zcrtc
->crtc
, &zx_crtc_helper_funcs
);
598 if (chn_type
== VOU_CHN_MAIN
)
599 vou
->main_crtc
= zcrtc
;
601 vou
->aux_crtc
= zcrtc
;
606 void zx_vou_layer_enable(struct drm_plane
*plane
)
608 struct zx_crtc
*zcrtc
= to_zx_crtc(plane
->state
->crtc
);
609 struct zx_vou_hw
*vou
= zcrtc
->vou
;
610 struct zx_plane
*zplane
= to_zx_plane(plane
);
611 const struct vou_layer_bits
*bits
= zplane
->bits
;
613 if (zcrtc
->chn_type
== VOU_CHN_MAIN
) {
614 zx_writel_mask(vou
->osd
+ OSD_CTRL0
, bits
->chnsel
, 0);
615 zx_writel_mask(vou
->vouctl
+ VOU_CLK_SEL
, bits
->clksel
, 0);
617 zx_writel_mask(vou
->osd
+ OSD_CTRL0
, bits
->chnsel
,
619 zx_writel_mask(vou
->vouctl
+ VOU_CLK_SEL
, bits
->clksel
,
623 zx_writel_mask(vou
->osd
+ OSD_CTRL0
, bits
->enable
, bits
->enable
);
626 void zx_vou_layer_disable(struct drm_plane
*plane
,
627 struct drm_plane_state
*old_state
)
629 struct zx_crtc
*zcrtc
= to_zx_crtc(old_state
->crtc
);
630 struct zx_vou_hw
*vou
= zcrtc
->vou
;
631 struct zx_plane
*zplane
= to_zx_plane(plane
);
632 const struct vou_layer_bits
*bits
= zplane
->bits
;
634 zx_writel_mask(vou
->osd
+ OSD_CTRL0
, bits
->enable
, 0);
637 static void zx_overlay_init(struct drm_device
*drm
, struct zx_vou_hw
*vou
)
639 struct device
*dev
= vou
->dev
;
640 struct zx_plane
*zplane
;
645 * VL0 has some quirks on scaling support which need special handling.
646 * Let's leave it out for now.
648 for (i
= 1; i
< VL_NUM
; i
++) {
649 zplane
= devm_kzalloc(dev
, sizeof(*zplane
), GFP_KERNEL
);
651 DRM_DEV_ERROR(dev
, "failed to allocate zplane %d\n", i
);
655 zplane
->layer
= vou
->osd
+ OSD_VL_OFFSET(i
);
656 zplane
->hbsc
= vou
->osd
+ HBSC_VL_OFFSET(i
);
657 zplane
->rsz
= vou
->otfppu
+ RSZ_VL_OFFSET(i
);
658 zplane
->bits
= &zx_vl_bits
[i
];
660 ret
= zx_plane_init(drm
, zplane
, DRM_PLANE_TYPE_OVERLAY
);
662 DRM_DEV_ERROR(dev
, "failed to init overlay %d\n", i
);
668 static inline void zx_osd_int_update(struct zx_crtc
*zcrtc
)
670 struct drm_crtc
*crtc
= &zcrtc
->crtc
;
671 struct drm_plane
*plane
;
673 vou_chn_set_update(zcrtc
);
675 drm_for_each_plane_mask(plane
, crtc
->dev
, crtc
->state
->plane_mask
)
676 zx_plane_set_update(plane
);
679 static irqreturn_t
vou_irq_handler(int irq
, void *dev_id
)
681 struct zx_vou_hw
*vou
= dev_id
;
684 /* Handle TIMING_CTRL frame interrupts */
685 state
= zx_readl(vou
->timing
+ TIMING_INT_STATE
);
686 zx_writel(vou
->timing
+ TIMING_INT_STATE
, state
);
688 if (state
& TIMING_INT_MAIN_FRAME
)
689 drm_crtc_handle_vblank(&vou
->main_crtc
->crtc
);
691 if (state
& TIMING_INT_AUX_FRAME
)
692 drm_crtc_handle_vblank(&vou
->aux_crtc
->crtc
);
694 /* Handle OSD interrupts */
695 state
= zx_readl(vou
->osd
+ OSD_INT_STA
);
696 zx_writel(vou
->osd
+ OSD_INT_CLRSTA
, state
);
698 if (state
& OSD_INT_MAIN_UPT
)
699 zx_osd_int_update(vou
->main_crtc
);
701 if (state
& OSD_INT_AUX_UPT
)
702 zx_osd_int_update(vou
->aux_crtc
);
704 if (state
& OSD_INT_ERROR
)
705 DRM_DEV_ERROR(vou
->dev
, "OSD ERROR: 0x%08x!\n", state
);
710 static void vou_dtrc_init(struct zx_vou_hw
*vou
)
712 /* Clear bit for bypass by ID */
713 zx_writel_mask(vou
->dtrc
+ DTRC_DETILE_CTRL
,
714 TILE2RASTESCAN_BYPASS_MODE
, 0);
716 /* Select ARIDR mode */
717 zx_writel_mask(vou
->dtrc
+ DTRC_DETILE_CTRL
, DETILE_ARIDR_MODE_MASK
,
718 DETILE_ARID_IN_ARIDR
);
720 /* Bypass decompression for both frames */
721 zx_writel_mask(vou
->dtrc
+ DTRC_F0_CTRL
, DTRC_DECOMPRESS_BYPASS
,
722 DTRC_DECOMPRESS_BYPASS
);
723 zx_writel_mask(vou
->dtrc
+ DTRC_F1_CTRL
, DTRC_DECOMPRESS_BYPASS
,
724 DTRC_DECOMPRESS_BYPASS
);
726 /* Set up ARID register */
727 zx_writel(vou
->dtrc
+ DTRC_ARID
, DTRC_ARID3(0xf) | DTRC_ARID2(0xe) |
728 DTRC_ARID1(0xf) | DTRC_ARID0(0xe));
731 static void vou_hw_init(struct zx_vou_hw
*vou
)
733 /* Release reset for all VOU modules */
734 zx_writel(vou
->vouctl
+ VOU_SOFT_RST
, ~0);
736 /* Enable all VOU module clocks */
737 zx_writel(vou
->vouctl
+ VOU_CLK_EN
, ~0);
739 /* Clear both OSD and TIMING_CTRL interrupt state */
740 zx_writel(vou
->osd
+ OSD_INT_CLRSTA
, ~0);
741 zx_writel(vou
->timing
+ TIMING_INT_STATE
, ~0);
743 /* Enable OSD and TIMING_CTRL interrrupts */
744 zx_writel(vou
->osd
+ OSD_INT_MSK
, OSD_INT_ENABLE
);
745 zx_writel(vou
->timing
+ TIMING_INT_CTRL
, TIMING_INT_ENABLE
);
747 /* Select GPC as input to gl/vl scaler as a sane default setting */
748 zx_writel(vou
->otfppu
+ OTFPPU_RSZ_DATA_SOURCE
, 0x2a);
751 * Needs to reset channel and layer logic per frame when frame starts
752 * to get VOU work properly.
754 zx_writel_mask(vou
->osd
+ OSD_RST_CLR
, RST_PER_FRAME
, RST_PER_FRAME
);
759 static int zx_crtc_bind(struct device
*dev
, struct device
*master
, void *data
)
761 struct platform_device
*pdev
= to_platform_device(dev
);
762 struct drm_device
*drm
= data
;
763 struct zx_vou_hw
*vou
;
764 struct resource
*res
;
768 vou
= devm_kzalloc(dev
, sizeof(*vou
), GFP_KERNEL
);
772 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "osd");
773 vou
->osd
= devm_ioremap_resource(dev
, res
);
774 if (IS_ERR(vou
->osd
)) {
775 ret
= PTR_ERR(vou
->osd
);
776 DRM_DEV_ERROR(dev
, "failed to remap osd region: %d\n", ret
);
780 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "timing_ctrl");
781 vou
->timing
= devm_ioremap_resource(dev
, res
);
782 if (IS_ERR(vou
->timing
)) {
783 ret
= PTR_ERR(vou
->timing
);
784 DRM_DEV_ERROR(dev
, "failed to remap timing_ctrl region: %d\n",
789 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "dtrc");
790 vou
->dtrc
= devm_ioremap_resource(dev
, res
);
791 if (IS_ERR(vou
->dtrc
)) {
792 ret
= PTR_ERR(vou
->dtrc
);
793 DRM_DEV_ERROR(dev
, "failed to remap dtrc region: %d\n", ret
);
797 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "vou_ctrl");
798 vou
->vouctl
= devm_ioremap_resource(dev
, res
);
799 if (IS_ERR(vou
->vouctl
)) {
800 ret
= PTR_ERR(vou
->vouctl
);
801 DRM_DEV_ERROR(dev
, "failed to remap vou_ctrl region: %d\n",
806 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "otfppu");
807 vou
->otfppu
= devm_ioremap_resource(dev
, res
);
808 if (IS_ERR(vou
->otfppu
)) {
809 ret
= PTR_ERR(vou
->otfppu
);
810 DRM_DEV_ERROR(dev
, "failed to remap otfppu region: %d\n", ret
);
814 irq
= platform_get_irq(pdev
, 0);
818 vou
->axi_clk
= devm_clk_get(dev
, "aclk");
819 if (IS_ERR(vou
->axi_clk
)) {
820 ret
= PTR_ERR(vou
->axi_clk
);
821 DRM_DEV_ERROR(dev
, "failed to get axi_clk: %d\n", ret
);
825 vou
->ppu_clk
= devm_clk_get(dev
, "ppu_wclk");
826 if (IS_ERR(vou
->ppu_clk
)) {
827 ret
= PTR_ERR(vou
->ppu_clk
);
828 DRM_DEV_ERROR(dev
, "failed to get ppu_clk: %d\n", ret
);
832 ret
= clk_prepare_enable(vou
->axi_clk
);
834 DRM_DEV_ERROR(dev
, "failed to enable axi_clk: %d\n", ret
);
838 clk_prepare_enable(vou
->ppu_clk
);
840 DRM_DEV_ERROR(dev
, "failed to enable ppu_clk: %d\n", ret
);
841 goto disable_axi_clk
;
845 dev_set_drvdata(dev
, vou
);
849 ret
= devm_request_irq(dev
, irq
, vou_irq_handler
, 0, "zx_vou", vou
);
851 DRM_DEV_ERROR(dev
, "failed to request vou irq: %d\n", ret
);
852 goto disable_ppu_clk
;
855 ret
= zx_crtc_init(drm
, vou
, VOU_CHN_MAIN
);
857 DRM_DEV_ERROR(dev
, "failed to init main channel crtc: %d\n",
859 goto disable_ppu_clk
;
862 ret
= zx_crtc_init(drm
, vou
, VOU_CHN_AUX
);
864 DRM_DEV_ERROR(dev
, "failed to init aux channel crtc: %d\n",
866 goto disable_ppu_clk
;
869 zx_overlay_init(drm
, vou
);
874 clk_disable_unprepare(vou
->ppu_clk
);
876 clk_disable_unprepare(vou
->axi_clk
);
880 static void zx_crtc_unbind(struct device
*dev
, struct device
*master
,
883 struct zx_vou_hw
*vou
= dev_get_drvdata(dev
);
885 clk_disable_unprepare(vou
->axi_clk
);
886 clk_disable_unprepare(vou
->ppu_clk
);
889 static const struct component_ops zx_crtc_component_ops
= {
890 .bind
= zx_crtc_bind
,
891 .unbind
= zx_crtc_unbind
,
894 static int zx_crtc_probe(struct platform_device
*pdev
)
896 return component_add(&pdev
->dev
, &zx_crtc_component_ops
);
899 static int zx_crtc_remove(struct platform_device
*pdev
)
901 component_del(&pdev
->dev
, &zx_crtc_component_ops
);
905 static const struct of_device_id zx_crtc_of_match
[] = {
906 { .compatible
= "zte,zx296718-dpc", },
909 MODULE_DEVICE_TABLE(of
, zx_crtc_of_match
);
911 struct platform_driver zx_crtc_driver
= {
912 .probe
= zx_crtc_probe
,
913 .remove
= zx_crtc_remove
,
916 .of_match_table
= zx_crtc_of_match
,