Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / gpu / drm / zte / zx_vou.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2016 Linaro Ltd.
4  * Copyright 2016 ZTE Corporation.
5  */
6
7 #include <linux/clk.h>
8 #include <linux/component.h>
9 #include <linux/of_address.h>
10 #include <video/videomode.h>
11
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>
20 #include <drm/drmP.h>
21
22 #include "zx_common_regs.h"
23 #include "zx_drm_drv.h"
24 #include "zx_plane.h"
25 #include "zx_vou.h"
26 #include "zx_vou_regs.h"
27
28 #define GL_NUM  2
29 #define VL_NUM  3
30
31 enum vou_chn_type {
32         VOU_CHN_MAIN,
33         VOU_CHN_AUX,
34 };
35
36 struct zx_crtc_regs {
37         u32 fir_active;
38         u32 fir_htiming;
39         u32 fir_vtiming;
40         u32 sec_vtiming;
41         u32 timing_shift;
42         u32 timing_pi_shift;
43 };
44
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,
52 };
53
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,
61 };
62
63 struct zx_crtc_bits {
64         u32 polarity_mask;
65         u32 polarity_shift;
66         u32 int_frame_mask;
67         u32 tc_enable;
68         u32 sec_vactive_shift;
69         u32 sec_vactive_mask;
70         u32 interlace_select;
71         u32 pi_enable;
72         u32 div_vga_shift;
73         u32 div_pic_shift;
74         u32 div_tvenc_shift;
75         u32 div_hdmi_pnx_shift;
76         u32 div_hdmi_shift;
77         u32 div_inf_shift;
78         u32 div_layer_shift;
79 };
80
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,
97 };
98
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,
115 };
116
117 struct zx_crtc {
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;
127         struct clk *pixclk;
128 };
129
130 #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
131
132 struct vou_layer_bits {
133         u32 enable;
134         u32 chnsel;
135         u32 clksel;
136 };
137
138 static const struct vou_layer_bits zx_gl_bits[GL_NUM] = {
139         {
140                 .enable = OSD_CTRL0_GL0_EN,
141                 .chnsel = OSD_CTRL0_GL0_SEL,
142                 .clksel = VOU_CLK_GL0_SEL,
143         }, {
144                 .enable = OSD_CTRL0_GL1_EN,
145                 .chnsel = OSD_CTRL0_GL1_SEL,
146                 .clksel = VOU_CLK_GL1_SEL,
147         },
148 };
149
150 static const struct vou_layer_bits zx_vl_bits[VL_NUM] = {
151         {
152                 .enable = OSD_CTRL0_VL0_EN,
153                 .chnsel = OSD_CTRL0_VL0_SEL,
154                 .clksel = VOU_CLK_VL0_SEL,
155         }, {
156                 .enable = OSD_CTRL0_VL1_EN,
157                 .chnsel = OSD_CTRL0_VL1_SEL,
158                 .clksel = VOU_CLK_VL1_SEL,
159         }, {
160                 .enable = OSD_CTRL0_VL2_EN,
161                 .chnsel = OSD_CTRL0_VL2_SEL,
162                 .clksel = VOU_CLK_VL2_SEL,
163         },
164 };
165
166 struct zx_vou_hw {
167         struct device *dev;
168         void __iomem *osd;
169         void __iomem *timing;
170         void __iomem *vouctl;
171         void __iomem *otfppu;
172         void __iomem *dtrc;
173         struct clk *axi_clk;
174         struct clk *ppu_clk;
175         struct clk *main_clk;
176         struct clk *aux_clk;
177         struct zx_crtc *main_crtc;
178         struct zx_crtc *aux_crtc;
179 };
180
181 enum vou_inf_data_sel {
182         VOU_YUV444      = 0,
183         VOU_RGB_101010  = 1,
184         VOU_RGB_888     = 2,
185         VOU_RGB_666     = 3,
186 };
187
188 struct vou_inf {
189         enum vou_inf_id id;
190         enum vou_inf_data_sel data_sel;
191         u32 clocks_en_bits;
192         u32 clocks_sel_bits;
193 };
194
195 static struct vou_inf vou_infs[] = {
196         [VOU_HDMI] = {
197                 .data_sel = VOU_YUV444,
198                 .clocks_en_bits = BIT(24) | BIT(18) | BIT(6),
199                 .clocks_sel_bits = BIT(13) | BIT(2),
200         },
201         [VOU_TV_ENC] = {
202                 .data_sel = VOU_YUV444,
203                 .clocks_en_bits = BIT(15),
204                 .clocks_sel_bits = BIT(11) | BIT(0),
205         },
206         [VOU_VGA] = {
207                 .data_sel = VOU_RGB_888,
208                 .clocks_en_bits = BIT(1),
209                 .clocks_sel_bits = BIT(10),
210         },
211 };
212
213 static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
214 {
215         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
216
217         return zcrtc->vou;
218 }
219
220 void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc,
221                             enum vou_inf_hdmi_audio aud)
222 {
223         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
224         struct zx_vou_hw *vou = zcrtc->vou;
225
226         zx_writel_mask(vou->vouctl + VOU_INF_HDMI_CTRL, VOU_HDMI_AUD_MASK, aud);
227 }
228
229 void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc)
230 {
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;
238
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,
244                                CSC_WORK_ENABLE);
245
246                 /* Bypass Dither block for RGB output */
247                 zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS,
248                                DITHER_BYSPASS);
249         } else {
250                 zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 0);
251                 zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 0);
252         }
253
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);
257
258         /* Select channel */
259         zx_writel_mask(vou->vouctl + VOU_INF_CH_SEL, 0x1 << id,
260                        zcrtc->chn_type << id);
261
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);
265
266         /* Enable interface clocks */
267         zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits,
268                        inf->clocks_en_bits);
269
270         /* Enable the device */
271         zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 1 << id);
272 }
273
274 void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc)
275 {
276         struct zx_vou_hw *vou = crtc_to_vou(crtc);
277         struct vou_inf *inf = &vou_infs[id];
278
279         /* Disable the device */
280         zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 0);
281
282         /* Disable interface clocks */
283         zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0);
284 }
285
286 void zx_vou_config_dividers(struct drm_crtc *crtc,
287                             struct vou_div_config *configs, int num)
288 {
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;
292         int i;
293
294         /* Clear update flag bit */
295         zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0);
296
297         for (i = 0; i < num; i++) {
298                 struct vou_div_config *cfg = configs + i;
299                 u32 reg, shift;
300
301                 switch (cfg->id) {
302                 case VOU_DIV_VGA:
303                         reg = VOU_CLK_SEL;
304                         shift = bits->div_vga_shift;
305                         break;
306                 case VOU_DIV_PIC:
307                         reg = VOU_CLK_SEL;
308                         shift = bits->div_pic_shift;
309                         break;
310                 case VOU_DIV_TVENC:
311                         reg = VOU_DIV_PARA;
312                         shift = bits->div_tvenc_shift;
313                         break;
314                 case VOU_DIV_HDMI_PNX:
315                         reg = VOU_DIV_PARA;
316                         shift = bits->div_hdmi_pnx_shift;
317                         break;
318                 case VOU_DIV_HDMI:
319                         reg = VOU_DIV_PARA;
320                         shift = bits->div_hdmi_shift;
321                         break;
322                 case VOU_DIV_INF:
323                         reg = VOU_DIV_PARA;
324                         shift = bits->div_inf_shift;
325                         break;
326                 case VOU_DIV_LAYER:
327                         reg = VOU_DIV_PARA;
328                         shift = bits->div_layer_shift;
329                         break;
330                 default:
331                         continue;
332                 }
333
334                 /* Each divider occupies 3 bits */
335                 zx_writel_mask(vou->vouctl + reg, 0x7 << shift,
336                                cfg->val << shift);
337         }
338
339         /* Set update flag bit to get dividers effected */
340         zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE,
341                        DIV_PARA_UPDATE);
342 }
343
344 static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
345 {
346         zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
347 }
348
349 static void zx_crtc_atomic_enable(struct drm_crtc *crtc,
350                                   struct drm_crtc_state *old_state)
351 {
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;
358         struct videomode vm;
359         u32 scan_mask;
360         u32 pol = 0;
361         u32 val;
362         int ret;
363
364         drm_display_mode_to_videomode(mode, &vm);
365
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);
370
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);
375
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);
380
381         if (interlaced) {
382                 u32 shift = bits->sec_vactive_shift;
383                 u32 mask = bits->sec_vactive_mask;
384
385                 val = zx_readl(vou->timing + SEC_V_ACTIVE);
386                 val &= ~mask;
387                 val |= ((vm.vactive / 2 - 1) << shift) & mask;
388                 zx_writel(vou->timing + SEC_V_ACTIVE, val);
389
390                 val = SYNC_WIDE(vm.vsync_len - 1);
391                 /*
392                  * The vback_porch for the second field needs to shift one on
393                  * the value for the first field.
394                  */
395                 val |= BACK_PORCH(vm.vback_porch);
396                 val |= FRONT_PORCH(vm.vfront_porch - 1);
397                 zx_writel(vou->timing + regs->sec_vtiming, val);
398         }
399
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;
405
406         zx_writel_mask(vou->timing + TIMING_CTRL, bits->polarity_mask,
407                        pol << bits->polarity_shift);
408
409         /* Setup SHIFT register by following what ZTE BSP does */
410         val = H_SHIFT_VAL;
411         if (interlaced)
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);
415
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);
420
421         /* Enable TIMING_CTRL */
422         zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable,
423                        bits->tc_enable);
424
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);
430
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);
434
435         /* Update channel */
436         vou_chn_set_update(zcrtc);
437
438         /* Enable channel */
439         zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE);
440
441         drm_crtc_vblank_on(crtc);
442
443         ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000);
444         if (ret) {
445                 DRM_DEV_ERROR(vou->dev, "failed to set pixclk rate: %d\n", ret);
446                 return;
447         }
448
449         ret = clk_prepare_enable(zcrtc->pixclk);
450         if (ret)
451                 DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret);
452 }
453
454 static void zx_crtc_atomic_disable(struct drm_crtc *crtc,
455                                    struct drm_crtc_state *old_state)
456 {
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;
460
461         clk_disable_unprepare(zcrtc->pixclk);
462
463         drm_crtc_vblank_off(crtc);
464
465         /* Disable channel */
466         zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0);
467
468         /* Disable TIMING_CTRL */
469         zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 0);
470 }
471
472 static void zx_crtc_atomic_flush(struct drm_crtc *crtc,
473                                   struct drm_crtc_state *old_state)
474 {
475         struct drm_pending_vblank_event *event = crtc->state->event;
476
477         if (!event)
478                 return;
479
480         crtc->state->event = NULL;
481
482         spin_lock_irq(&crtc->dev->event_lock);
483         if (drm_crtc_vblank_get(crtc) == 0)
484                 drm_crtc_arm_vblank_event(crtc, event);
485         else
486                 drm_crtc_send_vblank_event(crtc, event);
487         spin_unlock_irq(&crtc->dev->event_lock);
488 }
489
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,
494 };
495
496 static int zx_vou_enable_vblank(struct drm_crtc *crtc)
497 {
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;
501
502         zx_writel_mask(vou->timing + TIMING_INT_CTRL, int_frame_mask,
503                        int_frame_mask);
504
505         return 0;
506 }
507
508 static void zx_vou_disable_vblank(struct drm_crtc *crtc)
509 {
510         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
511         struct zx_vou_hw *vou = crtc_to_vou(crtc);
512
513         zx_writel_mask(vou->timing + TIMING_INT_CTRL,
514                        zcrtc->bits->int_frame_mask, 0);
515 }
516
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,
526 };
527
528 static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
529                         enum vou_chn_type chn_type)
530 {
531         struct device *dev = vou->dev;
532         struct zx_plane *zplane;
533         struct zx_crtc *zcrtc;
534         int ret;
535
536         zcrtc = devm_kzalloc(dev, sizeof(*zcrtc), GFP_KERNEL);
537         if (!zcrtc)
538                 return -ENOMEM;
539
540         zcrtc->vou = vou;
541         zcrtc->chn_type = chn_type;
542
543         zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
544         if (!zplane)
545                 return -ENOMEM;
546
547         zplane->dev = dev;
548
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;
560         } else {
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;
571         }
572
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);
578                 return ret;
579         }
580
581         ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_PRIMARY);
582         if (ret) {
583                 DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret);
584                 return ret;
585         }
586
587         zcrtc->primary = &zplane->plane;
588
589         ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL,
590                                         &zx_crtc_funcs, NULL);
591         if (ret) {
592                 DRM_DEV_ERROR(dev, "failed to init drm crtc: %d\n", ret);
593                 return ret;
594         }
595
596         drm_crtc_helper_add(&zcrtc->crtc, &zx_crtc_helper_funcs);
597
598         if (chn_type == VOU_CHN_MAIN)
599                 vou->main_crtc = zcrtc;
600         else
601                 vou->aux_crtc = zcrtc;
602
603         return 0;
604 }
605
606 void zx_vou_layer_enable(struct drm_plane *plane)
607 {
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;
612
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);
616         } else {
617                 zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel,
618                                bits->chnsel);
619                 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel,
620                                bits->clksel);
621         }
622
623         zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
624 }
625
626 void zx_vou_layer_disable(struct drm_plane *plane,
627                           struct drm_plane_state *old_state)
628 {
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;
633
634         zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
635 }
636
637 static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou)
638 {
639         struct device *dev = vou->dev;
640         struct zx_plane *zplane;
641         int i;
642         int ret;
643
644         /*
645          * VL0 has some quirks on scaling support which need special handling.
646          * Let's leave it out for now.
647          */
648         for (i = 1; i < VL_NUM; i++) {
649                 zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
650                 if (!zplane) {
651                         DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i);
652                         return;
653                 }
654
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];
659
660                 ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY);
661                 if (ret) {
662                         DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i);
663                         continue;
664                 }
665         }
666 }
667
668 static inline void zx_osd_int_update(struct zx_crtc *zcrtc)
669 {
670         struct drm_crtc *crtc = &zcrtc->crtc;
671         struct drm_plane *plane;
672
673         vou_chn_set_update(zcrtc);
674
675         drm_for_each_plane_mask(plane, crtc->dev, crtc->state->plane_mask)
676                 zx_plane_set_update(plane);
677 }
678
679 static irqreturn_t vou_irq_handler(int irq, void *dev_id)
680 {
681         struct zx_vou_hw *vou = dev_id;
682         u32 state;
683
684         /* Handle TIMING_CTRL frame interrupts */
685         state = zx_readl(vou->timing + TIMING_INT_STATE);
686         zx_writel(vou->timing + TIMING_INT_STATE, state);
687
688         if (state & TIMING_INT_MAIN_FRAME)
689                 drm_crtc_handle_vblank(&vou->main_crtc->crtc);
690
691         if (state & TIMING_INT_AUX_FRAME)
692                 drm_crtc_handle_vblank(&vou->aux_crtc->crtc);
693
694         /* Handle OSD interrupts */
695         state = zx_readl(vou->osd + OSD_INT_STA);
696         zx_writel(vou->osd + OSD_INT_CLRSTA, state);
697
698         if (state & OSD_INT_MAIN_UPT)
699                 zx_osd_int_update(vou->main_crtc);
700
701         if (state & OSD_INT_AUX_UPT)
702                 zx_osd_int_update(vou->aux_crtc);
703
704         if (state & OSD_INT_ERROR)
705                 DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state);
706
707         return IRQ_HANDLED;
708 }
709
710 static void vou_dtrc_init(struct zx_vou_hw *vou)
711 {
712         /* Clear bit for bypass by ID */
713         zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL,
714                        TILE2RASTESCAN_BYPASS_MODE, 0);
715
716         /* Select ARIDR mode */
717         zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, DETILE_ARIDR_MODE_MASK,
718                        DETILE_ARID_IN_ARIDR);
719
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);
725
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));
729 }
730
731 static void vou_hw_init(struct zx_vou_hw *vou)
732 {
733         /* Release reset for all VOU modules */
734         zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
735
736         /* Enable all VOU module clocks */
737         zx_writel(vou->vouctl + VOU_CLK_EN, ~0);
738
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);
742
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);
746
747         /* Select GPC as input to gl/vl scaler as a sane default setting */
748         zx_writel(vou->otfppu + OTFPPU_RSZ_DATA_SOURCE, 0x2a);
749
750         /*
751          * Needs to reset channel and layer logic per frame when frame starts
752          * to get VOU work properly.
753          */
754         zx_writel_mask(vou->osd + OSD_RST_CLR, RST_PER_FRAME, RST_PER_FRAME);
755
756         vou_dtrc_init(vou);
757 }
758
759 static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
760 {
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;
765         int irq;
766         int ret;
767
768         vou = devm_kzalloc(dev, sizeof(*vou), GFP_KERNEL);
769         if (!vou)
770                 return -ENOMEM;
771
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);
777                 return ret;
778         }
779
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",
785                               ret);
786                 return ret;
787         }
788
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);
794                 return ret;
795         }
796
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",
802                               ret);
803                 return ret;
804         }
805
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);
811                 return ret;
812         }
813
814         irq = platform_get_irq(pdev, 0);
815         if (irq < 0)
816                 return irq;
817
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);
822                 return ret;
823         }
824
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);
829                 return ret;
830         }
831
832         ret = clk_prepare_enable(vou->axi_clk);
833         if (ret) {
834                 DRM_DEV_ERROR(dev, "failed to enable axi_clk: %d\n", ret);
835                 return ret;
836         }
837
838         clk_prepare_enable(vou->ppu_clk);
839         if (ret) {
840                 DRM_DEV_ERROR(dev, "failed to enable ppu_clk: %d\n", ret);
841                 goto disable_axi_clk;
842         }
843
844         vou->dev = dev;
845         dev_set_drvdata(dev, vou);
846
847         vou_hw_init(vou);
848
849         ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou);
850         if (ret < 0) {
851                 DRM_DEV_ERROR(dev, "failed to request vou irq: %d\n", ret);
852                 goto disable_ppu_clk;
853         }
854
855         ret = zx_crtc_init(drm, vou, VOU_CHN_MAIN);
856         if (ret) {
857                 DRM_DEV_ERROR(dev, "failed to init main channel crtc: %d\n",
858                               ret);
859                 goto disable_ppu_clk;
860         }
861
862         ret = zx_crtc_init(drm, vou, VOU_CHN_AUX);
863         if (ret) {
864                 DRM_DEV_ERROR(dev, "failed to init aux channel crtc: %d\n",
865                               ret);
866                 goto disable_ppu_clk;
867         }
868
869         zx_overlay_init(drm, vou);
870
871         return 0;
872
873 disable_ppu_clk:
874         clk_disable_unprepare(vou->ppu_clk);
875 disable_axi_clk:
876         clk_disable_unprepare(vou->axi_clk);
877         return ret;
878 }
879
880 static void zx_crtc_unbind(struct device *dev, struct device *master,
881                            void *data)
882 {
883         struct zx_vou_hw *vou = dev_get_drvdata(dev);
884
885         clk_disable_unprepare(vou->axi_clk);
886         clk_disable_unprepare(vou->ppu_clk);
887 }
888
889 static const struct component_ops zx_crtc_component_ops = {
890         .bind = zx_crtc_bind,
891         .unbind = zx_crtc_unbind,
892 };
893
894 static int zx_crtc_probe(struct platform_device *pdev)
895 {
896         return component_add(&pdev->dev, &zx_crtc_component_ops);
897 }
898
899 static int zx_crtc_remove(struct platform_device *pdev)
900 {
901         component_del(&pdev->dev, &zx_crtc_component_ops);
902         return 0;
903 }
904
905 static const struct of_device_id zx_crtc_of_match[] = {
906         { .compatible = "zte,zx296718-dpc", },
907         { /* end */ },
908 };
909 MODULE_DEVICE_TABLE(of, zx_crtc_of_match);
910
911 struct platform_driver zx_crtc_driver = {
912         .probe = zx_crtc_probe,
913         .remove = zx_crtc_remove,
914         .driver = {
915                 .name = "zx-crtc",
916                 .of_match_table = zx_crtc_of_match,
917         },
918 };