GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / gpu / drm / zte / zx_vou.c
1 /*
2  * Copyright 2016 Linaro Ltd.
3  * Copyright 2016 ZTE Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  */
10
11 #include <linux/clk.h>
12 #include <linux/component.h>
13 #include <linux/of_address.h>
14 #include <video/videomode.h>
15
16 #include <drm/drm_atomic_helper.h>
17 #include <drm/drm_crtc.h>
18 #include <drm/drm_crtc_helper.h>
19 #include <drm/drm_fb_cma_helper.h>
20 #include <drm/drm_fb_helper.h>
21 #include <drm/drm_gem_cma_helper.h>
22 #include <drm/drm_of.h>
23 #include <drm/drm_plane_helper.h>
24 #include <drm/drmP.h>
25
26 #include "zx_common_regs.h"
27 #include "zx_drm_drv.h"
28 #include "zx_plane.h"
29 #include "zx_vou.h"
30 #include "zx_vou_regs.h"
31
32 #define GL_NUM  2
33 #define VL_NUM  3
34
35 enum vou_chn_type {
36         VOU_CHN_MAIN,
37         VOU_CHN_AUX,
38 };
39
40 struct zx_crtc_regs {
41         u32 fir_active;
42         u32 fir_htiming;
43         u32 fir_vtiming;
44         u32 sec_vtiming;
45         u32 timing_shift;
46         u32 timing_pi_shift;
47 };
48
49 static const struct zx_crtc_regs main_crtc_regs = {
50         .fir_active = FIR_MAIN_ACTIVE,
51         .fir_htiming = FIR_MAIN_H_TIMING,
52         .fir_vtiming = FIR_MAIN_V_TIMING,
53         .sec_vtiming = SEC_MAIN_V_TIMING,
54         .timing_shift = TIMING_MAIN_SHIFT,
55         .timing_pi_shift = TIMING_MAIN_PI_SHIFT,
56 };
57
58 static const struct zx_crtc_regs aux_crtc_regs = {
59         .fir_active = FIR_AUX_ACTIVE,
60         .fir_htiming = FIR_AUX_H_TIMING,
61         .fir_vtiming = FIR_AUX_V_TIMING,
62         .sec_vtiming = SEC_AUX_V_TIMING,
63         .timing_shift = TIMING_AUX_SHIFT,
64         .timing_pi_shift = TIMING_AUX_PI_SHIFT,
65 };
66
67 struct zx_crtc_bits {
68         u32 polarity_mask;
69         u32 polarity_shift;
70         u32 int_frame_mask;
71         u32 tc_enable;
72         u32 sec_vactive_shift;
73         u32 sec_vactive_mask;
74         u32 interlace_select;
75         u32 pi_enable;
76         u32 div_vga_shift;
77         u32 div_pic_shift;
78         u32 div_tvenc_shift;
79         u32 div_hdmi_pnx_shift;
80         u32 div_hdmi_shift;
81         u32 div_inf_shift;
82         u32 div_layer_shift;
83 };
84
85 static const struct zx_crtc_bits main_crtc_bits = {
86         .polarity_mask = MAIN_POL_MASK,
87         .polarity_shift = MAIN_POL_SHIFT,
88         .int_frame_mask = TIMING_INT_MAIN_FRAME,
89         .tc_enable = MAIN_TC_EN,
90         .sec_vactive_shift = SEC_VACT_MAIN_SHIFT,
91         .sec_vactive_mask = SEC_VACT_MAIN_MASK,
92         .interlace_select = MAIN_INTERLACE_SEL,
93         .pi_enable = MAIN_PI_EN,
94         .div_vga_shift = VGA_MAIN_DIV_SHIFT,
95         .div_pic_shift = PIC_MAIN_DIV_SHIFT,
96         .div_tvenc_shift = TVENC_MAIN_DIV_SHIFT,
97         .div_hdmi_pnx_shift = HDMI_MAIN_PNX_DIV_SHIFT,
98         .div_hdmi_shift = HDMI_MAIN_DIV_SHIFT,
99         .div_inf_shift = INF_MAIN_DIV_SHIFT,
100         .div_layer_shift = LAYER_MAIN_DIV_SHIFT,
101 };
102
103 static const struct zx_crtc_bits aux_crtc_bits = {
104         .polarity_mask = AUX_POL_MASK,
105         .polarity_shift = AUX_POL_SHIFT,
106         .int_frame_mask = TIMING_INT_AUX_FRAME,
107         .tc_enable = AUX_TC_EN,
108         .sec_vactive_shift = SEC_VACT_AUX_SHIFT,
109         .sec_vactive_mask = SEC_VACT_AUX_MASK,
110         .interlace_select = AUX_INTERLACE_SEL,
111         .pi_enable = AUX_PI_EN,
112         .div_vga_shift = VGA_AUX_DIV_SHIFT,
113         .div_pic_shift = PIC_AUX_DIV_SHIFT,
114         .div_tvenc_shift = TVENC_AUX_DIV_SHIFT,
115         .div_hdmi_pnx_shift = HDMI_AUX_PNX_DIV_SHIFT,
116         .div_hdmi_shift = HDMI_AUX_DIV_SHIFT,
117         .div_inf_shift = INF_AUX_DIV_SHIFT,
118         .div_layer_shift = LAYER_AUX_DIV_SHIFT,
119 };
120
121 struct zx_crtc {
122         struct drm_crtc crtc;
123         struct drm_plane *primary;
124         struct zx_vou_hw *vou;
125         void __iomem *chnreg;
126         void __iomem *chncsc;
127         void __iomem *dither;
128         const struct zx_crtc_regs *regs;
129         const struct zx_crtc_bits *bits;
130         enum vou_chn_type chn_type;
131         struct clk *pixclk;
132 };
133
134 #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
135
136 struct vou_layer_bits {
137         u32 enable;
138         u32 chnsel;
139         u32 clksel;
140 };
141
142 static const struct vou_layer_bits zx_gl_bits[GL_NUM] = {
143         {
144                 .enable = OSD_CTRL0_GL0_EN,
145                 .chnsel = OSD_CTRL0_GL0_SEL,
146                 .clksel = VOU_CLK_GL0_SEL,
147         }, {
148                 .enable = OSD_CTRL0_GL1_EN,
149                 .chnsel = OSD_CTRL0_GL1_SEL,
150                 .clksel = VOU_CLK_GL1_SEL,
151         },
152 };
153
154 static const struct vou_layer_bits zx_vl_bits[VL_NUM] = {
155         {
156                 .enable = OSD_CTRL0_VL0_EN,
157                 .chnsel = OSD_CTRL0_VL0_SEL,
158                 .clksel = VOU_CLK_VL0_SEL,
159         }, {
160                 .enable = OSD_CTRL0_VL1_EN,
161                 .chnsel = OSD_CTRL0_VL1_SEL,
162                 .clksel = VOU_CLK_VL1_SEL,
163         }, {
164                 .enable = OSD_CTRL0_VL2_EN,
165                 .chnsel = OSD_CTRL0_VL2_SEL,
166                 .clksel = VOU_CLK_VL2_SEL,
167         },
168 };
169
170 struct zx_vou_hw {
171         struct device *dev;
172         void __iomem *osd;
173         void __iomem *timing;
174         void __iomem *vouctl;
175         void __iomem *otfppu;
176         void __iomem *dtrc;
177         struct clk *axi_clk;
178         struct clk *ppu_clk;
179         struct clk *main_clk;
180         struct clk *aux_clk;
181         struct zx_crtc *main_crtc;
182         struct zx_crtc *aux_crtc;
183 };
184
185 enum vou_inf_data_sel {
186         VOU_YUV444      = 0,
187         VOU_RGB_101010  = 1,
188         VOU_RGB_888     = 2,
189         VOU_RGB_666     = 3,
190 };
191
192 struct vou_inf {
193         enum vou_inf_id id;
194         enum vou_inf_data_sel data_sel;
195         u32 clocks_en_bits;
196         u32 clocks_sel_bits;
197 };
198
199 static struct vou_inf vou_infs[] = {
200         [VOU_HDMI] = {
201                 .data_sel = VOU_YUV444,
202                 .clocks_en_bits = BIT(24) | BIT(18) | BIT(6),
203                 .clocks_sel_bits = BIT(13) | BIT(2),
204         },
205         [VOU_TV_ENC] = {
206                 .data_sel = VOU_YUV444,
207                 .clocks_en_bits = BIT(15),
208                 .clocks_sel_bits = BIT(11) | BIT(0),
209         },
210         [VOU_VGA] = {
211                 .data_sel = VOU_RGB_888,
212                 .clocks_en_bits = BIT(1),
213                 .clocks_sel_bits = BIT(10),
214         },
215 };
216
217 static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
218 {
219         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
220
221         return zcrtc->vou;
222 }
223
224 void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc,
225                             enum vou_inf_hdmi_audio aud)
226 {
227         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
228         struct zx_vou_hw *vou = zcrtc->vou;
229
230         zx_writel_mask(vou->vouctl + VOU_INF_HDMI_CTRL, VOU_HDMI_AUD_MASK, aud);
231 }
232
233 void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc)
234 {
235         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
236         struct zx_vou_hw *vou = zcrtc->vou;
237         struct vou_inf *inf = &vou_infs[id];
238         void __iomem *dither = zcrtc->dither;
239         void __iomem *csc = zcrtc->chncsc;
240         bool is_main = zcrtc->chn_type == VOU_CHN_MAIN;
241         u32 data_sel_shift = id << 1;
242
243         if (inf->data_sel != VOU_YUV444) {
244                 /* Enable channel CSC for RGB output */
245                 zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK,
246                                CSC_BT709_IMAGE_YCBCR2RGB << CSC_COV_MODE_SHIFT);
247                 zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE,
248                                CSC_WORK_ENABLE);
249
250                 /* Bypass Dither block for RGB output */
251                 zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS,
252                                DITHER_BYSPASS);
253         } else {
254                 zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 0);
255                 zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 0);
256         }
257
258         /* Select data format */
259         zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift,
260                        inf->data_sel << data_sel_shift);
261
262         /* Select channel */
263         zx_writel_mask(vou->vouctl + VOU_INF_CH_SEL, 0x1 << id,
264                        zcrtc->chn_type << id);
265
266         /* Select interface clocks */
267         zx_writel_mask(vou->vouctl + VOU_CLK_SEL, inf->clocks_sel_bits,
268                        is_main ? 0 : inf->clocks_sel_bits);
269
270         /* Enable interface clocks */
271         zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits,
272                        inf->clocks_en_bits);
273
274         /* Enable the device */
275         zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 1 << id);
276 }
277
278 void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc)
279 {
280         struct zx_vou_hw *vou = crtc_to_vou(crtc);
281         struct vou_inf *inf = &vou_infs[id];
282
283         /* Disable the device */
284         zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 0);
285
286         /* Disable interface clocks */
287         zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0);
288 }
289
290 void zx_vou_config_dividers(struct drm_crtc *crtc,
291                             struct vou_div_config *configs, int num)
292 {
293         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
294         struct zx_vou_hw *vou = zcrtc->vou;
295         const struct zx_crtc_bits *bits = zcrtc->bits;
296         int i;
297
298         /* Clear update flag bit */
299         zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0);
300
301         for (i = 0; i < num; i++) {
302                 struct vou_div_config *cfg = configs + i;
303                 u32 reg, shift;
304
305                 switch (cfg->id) {
306                 case VOU_DIV_VGA:
307                         reg = VOU_CLK_SEL;
308                         shift = bits->div_vga_shift;
309                         break;
310                 case VOU_DIV_PIC:
311                         reg = VOU_CLK_SEL;
312                         shift = bits->div_pic_shift;
313                         break;
314                 case VOU_DIV_TVENC:
315                         reg = VOU_DIV_PARA;
316                         shift = bits->div_tvenc_shift;
317                         break;
318                 case VOU_DIV_HDMI_PNX:
319                         reg = VOU_DIV_PARA;
320                         shift = bits->div_hdmi_pnx_shift;
321                         break;
322                 case VOU_DIV_HDMI:
323                         reg = VOU_DIV_PARA;
324                         shift = bits->div_hdmi_shift;
325                         break;
326                 case VOU_DIV_INF:
327                         reg = VOU_DIV_PARA;
328                         shift = bits->div_inf_shift;
329                         break;
330                 case VOU_DIV_LAYER:
331                         reg = VOU_DIV_PARA;
332                         shift = bits->div_layer_shift;
333                         break;
334                 default:
335                         continue;
336                 }
337
338                 /* Each divider occupies 3 bits */
339                 zx_writel_mask(vou->vouctl + reg, 0x7 << shift,
340                                cfg->val << shift);
341         }
342
343         /* Set update flag bit to get dividers effected */
344         zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE,
345                        DIV_PARA_UPDATE);
346 }
347
348 static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
349 {
350         zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
351 }
352
353 static void zx_crtc_atomic_enable(struct drm_crtc *crtc,
354                                   struct drm_crtc_state *old_state)
355 {
356         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
357         bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
358         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
359         struct zx_vou_hw *vou = zcrtc->vou;
360         const struct zx_crtc_regs *regs = zcrtc->regs;
361         const struct zx_crtc_bits *bits = zcrtc->bits;
362         struct videomode vm;
363         u32 scan_mask;
364         u32 pol = 0;
365         u32 val;
366         int ret;
367
368         drm_display_mode_to_videomode(mode, &vm);
369
370         /* Set up timing parameters */
371         val = V_ACTIVE((interlaced ? vm.vactive / 2 : vm.vactive) - 1);
372         val |= H_ACTIVE(vm.hactive - 1);
373         zx_writel(vou->timing + regs->fir_active, val);
374
375         val = SYNC_WIDE(vm.hsync_len - 1);
376         val |= BACK_PORCH(vm.hback_porch - 1);
377         val |= FRONT_PORCH(vm.hfront_porch - 1);
378         zx_writel(vou->timing + regs->fir_htiming, val);
379
380         val = SYNC_WIDE(vm.vsync_len - 1);
381         val |= BACK_PORCH(vm.vback_porch - 1);
382         val |= FRONT_PORCH(vm.vfront_porch - 1);
383         zx_writel(vou->timing + regs->fir_vtiming, val);
384
385         if (interlaced) {
386                 u32 shift = bits->sec_vactive_shift;
387                 u32 mask = bits->sec_vactive_mask;
388
389                 val = zx_readl(vou->timing + SEC_V_ACTIVE);
390                 val &= ~mask;
391                 val |= ((vm.vactive / 2 - 1) << shift) & mask;
392                 zx_writel(vou->timing + SEC_V_ACTIVE, val);
393
394                 val = SYNC_WIDE(vm.vsync_len - 1);
395                 /*
396                  * The vback_porch for the second field needs to shift one on
397                  * the value for the first field.
398                  */
399                 val |= BACK_PORCH(vm.vback_porch);
400                 val |= FRONT_PORCH(vm.vfront_porch - 1);
401                 zx_writel(vou->timing + regs->sec_vtiming, val);
402         }
403
404         /* Set up polarities */
405         if (vm.flags & DISPLAY_FLAGS_VSYNC_LOW)
406                 pol |= 1 << POL_VSYNC_SHIFT;
407         if (vm.flags & DISPLAY_FLAGS_HSYNC_LOW)
408                 pol |= 1 << POL_HSYNC_SHIFT;
409
410         zx_writel_mask(vou->timing + TIMING_CTRL, bits->polarity_mask,
411                        pol << bits->polarity_shift);
412
413         /* Setup SHIFT register by following what ZTE BSP does */
414         val = H_SHIFT_VAL;
415         if (interlaced)
416                 val |= V_SHIFT_VAL << 16;
417         zx_writel(vou->timing + regs->timing_shift, val);
418         zx_writel(vou->timing + regs->timing_pi_shift, H_PI_SHIFT_VAL);
419
420         /* Progressive or interlace scan select */
421         scan_mask = bits->interlace_select | bits->pi_enable;
422         zx_writel_mask(vou->timing + SCAN_CTRL, scan_mask,
423                        interlaced ? scan_mask : 0);
424
425         /* Enable TIMING_CTRL */
426         zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable,
427                        bits->tc_enable);
428
429         /* Configure channel screen size */
430         zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_W_MASK,
431                        vm.hactive << CHN_SCREEN_W_SHIFT);
432         zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_H_MASK,
433                        vm.vactive << CHN_SCREEN_H_SHIFT);
434
435         /* Configure channel interlace buffer control */
436         zx_writel_mask(zcrtc->chnreg + CHN_INTERLACE_BUF_CTRL, CHN_INTERLACE_EN,
437                        interlaced ? CHN_INTERLACE_EN : 0);
438
439         /* Update channel */
440         vou_chn_set_update(zcrtc);
441
442         /* Enable channel */
443         zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE);
444
445         drm_crtc_vblank_on(crtc);
446
447         ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000);
448         if (ret) {
449                 DRM_DEV_ERROR(vou->dev, "failed to set pixclk rate: %d\n", ret);
450                 return;
451         }
452
453         ret = clk_prepare_enable(zcrtc->pixclk);
454         if (ret)
455                 DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret);
456 }
457
458 static void zx_crtc_atomic_disable(struct drm_crtc *crtc,
459                                    struct drm_crtc_state *old_state)
460 {
461         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
462         const struct zx_crtc_bits *bits = zcrtc->bits;
463         struct zx_vou_hw *vou = zcrtc->vou;
464
465         clk_disable_unprepare(zcrtc->pixclk);
466
467         drm_crtc_vblank_off(crtc);
468
469         /* Disable channel */
470         zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0);
471
472         /* Disable TIMING_CTRL */
473         zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 0);
474 }
475
476 static void zx_crtc_atomic_flush(struct drm_crtc *crtc,
477                                   struct drm_crtc_state *old_state)
478 {
479         struct drm_pending_vblank_event *event = crtc->state->event;
480
481         if (!event)
482                 return;
483
484         crtc->state->event = NULL;
485
486         spin_lock_irq(&crtc->dev->event_lock);
487         if (drm_crtc_vblank_get(crtc) == 0)
488                 drm_crtc_arm_vblank_event(crtc, event);
489         else
490                 drm_crtc_send_vblank_event(crtc, event);
491         spin_unlock_irq(&crtc->dev->event_lock);
492 }
493
494 static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = {
495         .atomic_flush = zx_crtc_atomic_flush,
496         .atomic_enable = zx_crtc_atomic_enable,
497         .atomic_disable = zx_crtc_atomic_disable,
498 };
499
500 static int zx_vou_enable_vblank(struct drm_crtc *crtc)
501 {
502         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
503         struct zx_vou_hw *vou = crtc_to_vou(crtc);
504         u32 int_frame_mask = zcrtc->bits->int_frame_mask;
505
506         zx_writel_mask(vou->timing + TIMING_INT_CTRL, int_frame_mask,
507                        int_frame_mask);
508
509         return 0;
510 }
511
512 static void zx_vou_disable_vblank(struct drm_crtc *crtc)
513 {
514         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
515         struct zx_vou_hw *vou = crtc_to_vou(crtc);
516
517         zx_writel_mask(vou->timing + TIMING_INT_CTRL,
518                        zcrtc->bits->int_frame_mask, 0);
519 }
520
521 static const struct drm_crtc_funcs zx_crtc_funcs = {
522         .destroy = drm_crtc_cleanup,
523         .set_config = drm_atomic_helper_set_config,
524         .page_flip = drm_atomic_helper_page_flip,
525         .reset = drm_atomic_helper_crtc_reset,
526         .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
527         .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
528         .enable_vblank = zx_vou_enable_vblank,
529         .disable_vblank = zx_vou_disable_vblank,
530 };
531
532 static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
533                         enum vou_chn_type chn_type)
534 {
535         struct device *dev = vou->dev;
536         struct zx_plane *zplane;
537         struct zx_crtc *zcrtc;
538         int ret;
539
540         zcrtc = devm_kzalloc(dev, sizeof(*zcrtc), GFP_KERNEL);
541         if (!zcrtc)
542                 return -ENOMEM;
543
544         zcrtc->vou = vou;
545         zcrtc->chn_type = chn_type;
546
547         zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
548         if (!zplane)
549                 return -ENOMEM;
550
551         zplane->dev = dev;
552
553         if (chn_type == VOU_CHN_MAIN) {
554                 zplane->layer = vou->osd + MAIN_GL_OFFSET;
555                 zplane->csc = vou->osd + MAIN_GL_CSC_OFFSET;
556                 zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
557                 zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
558                 zplane->bits = &zx_gl_bits[0];
559                 zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
560                 zcrtc->chncsc = vou->osd + MAIN_CHN_CSC_OFFSET;
561                 zcrtc->dither = vou->osd + MAIN_DITHER_OFFSET;
562                 zcrtc->regs = &main_crtc_regs;
563                 zcrtc->bits = &main_crtc_bits;
564         } else {
565                 zplane->layer = vou->osd + AUX_GL_OFFSET;
566                 zplane->csc = vou->osd + AUX_GL_CSC_OFFSET;
567                 zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
568                 zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
569                 zplane->bits = &zx_gl_bits[1];
570                 zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
571                 zcrtc->chncsc = vou->osd + AUX_CHN_CSC_OFFSET;
572                 zcrtc->dither = vou->osd + AUX_DITHER_OFFSET;
573                 zcrtc->regs = &aux_crtc_regs;
574                 zcrtc->bits = &aux_crtc_bits;
575         }
576
577         zcrtc->pixclk = devm_clk_get(dev, (chn_type == VOU_CHN_MAIN) ?
578                                           "main_wclk" : "aux_wclk");
579         if (IS_ERR(zcrtc->pixclk)) {
580                 ret = PTR_ERR(zcrtc->pixclk);
581                 DRM_DEV_ERROR(dev, "failed to get pix clk: %d\n", ret);
582                 return ret;
583         }
584
585         ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_PRIMARY);
586         if (ret) {
587                 DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret);
588                 return ret;
589         }
590
591         zcrtc->primary = &zplane->plane;
592
593         ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL,
594                                         &zx_crtc_funcs, NULL);
595         if (ret) {
596                 DRM_DEV_ERROR(dev, "failed to init drm crtc: %d\n", ret);
597                 return ret;
598         }
599
600         drm_crtc_helper_add(&zcrtc->crtc, &zx_crtc_helper_funcs);
601
602         if (chn_type == VOU_CHN_MAIN)
603                 vou->main_crtc = zcrtc;
604         else
605                 vou->aux_crtc = zcrtc;
606
607         return 0;
608 }
609
610 void zx_vou_layer_enable(struct drm_plane *plane)
611 {
612         struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc);
613         struct zx_vou_hw *vou = zcrtc->vou;
614         struct zx_plane *zplane = to_zx_plane(plane);
615         const struct vou_layer_bits *bits = zplane->bits;
616
617         if (zcrtc->chn_type == VOU_CHN_MAIN) {
618                 zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0);
619                 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0);
620         } else {
621                 zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel,
622                                bits->chnsel);
623                 zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel,
624                                bits->clksel);
625         }
626
627         zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
628 }
629
630 void zx_vou_layer_disable(struct drm_plane *plane)
631 {
632         struct zx_crtc *zcrtc = to_zx_crtc(plane->crtc);
633         struct zx_vou_hw *vou = zcrtc->vou;
634         struct zx_plane *zplane = to_zx_plane(plane);
635         const struct vou_layer_bits *bits = zplane->bits;
636
637         zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
638 }
639
640 static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou)
641 {
642         struct device *dev = vou->dev;
643         struct zx_plane *zplane;
644         int i;
645         int ret;
646
647         /*
648          * VL0 has some quirks on scaling support which need special handling.
649          * Let's leave it out for now.
650          */
651         for (i = 1; i < VL_NUM; i++) {
652                 zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
653                 if (!zplane) {
654                         DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i);
655                         return;
656                 }
657
658                 zplane->layer = vou->osd + OSD_VL_OFFSET(i);
659                 zplane->hbsc = vou->osd + HBSC_VL_OFFSET(i);
660                 zplane->rsz = vou->otfppu + RSZ_VL_OFFSET(i);
661                 zplane->bits = &zx_vl_bits[i];
662
663                 ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY);
664                 if (ret) {
665                         DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i);
666                         continue;
667                 }
668         }
669 }
670
671 static inline void zx_osd_int_update(struct zx_crtc *zcrtc)
672 {
673         struct drm_crtc *crtc = &zcrtc->crtc;
674         struct drm_plane *plane;
675
676         vou_chn_set_update(zcrtc);
677
678         drm_for_each_plane_mask(plane, crtc->dev, crtc->state->plane_mask)
679                 zx_plane_set_update(plane);
680 }
681
682 static irqreturn_t vou_irq_handler(int irq, void *dev_id)
683 {
684         struct zx_vou_hw *vou = dev_id;
685         u32 state;
686
687         /* Handle TIMING_CTRL frame interrupts */
688         state = zx_readl(vou->timing + TIMING_INT_STATE);
689         zx_writel(vou->timing + TIMING_INT_STATE, state);
690
691         if (state & TIMING_INT_MAIN_FRAME)
692                 drm_crtc_handle_vblank(&vou->main_crtc->crtc);
693
694         if (state & TIMING_INT_AUX_FRAME)
695                 drm_crtc_handle_vblank(&vou->aux_crtc->crtc);
696
697         /* Handle OSD interrupts */
698         state = zx_readl(vou->osd + OSD_INT_STA);
699         zx_writel(vou->osd + OSD_INT_CLRSTA, state);
700
701         if (state & OSD_INT_MAIN_UPT)
702                 zx_osd_int_update(vou->main_crtc);
703
704         if (state & OSD_INT_AUX_UPT)
705                 zx_osd_int_update(vou->aux_crtc);
706
707         if (state & OSD_INT_ERROR)
708                 DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state);
709
710         return IRQ_HANDLED;
711 }
712
713 static void vou_dtrc_init(struct zx_vou_hw *vou)
714 {
715         /* Clear bit for bypass by ID */
716         zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL,
717                        TILE2RASTESCAN_BYPASS_MODE, 0);
718
719         /* Select ARIDR mode */
720         zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, DETILE_ARIDR_MODE_MASK,
721                        DETILE_ARID_IN_ARIDR);
722
723         /* Bypass decompression for both frames */
724         zx_writel_mask(vou->dtrc + DTRC_F0_CTRL, DTRC_DECOMPRESS_BYPASS,
725                        DTRC_DECOMPRESS_BYPASS);
726         zx_writel_mask(vou->dtrc + DTRC_F1_CTRL, DTRC_DECOMPRESS_BYPASS,
727                        DTRC_DECOMPRESS_BYPASS);
728
729         /* Set up ARID register */
730         zx_writel(vou->dtrc + DTRC_ARID, DTRC_ARID3(0xf) | DTRC_ARID2(0xe) |
731                   DTRC_ARID1(0xf) | DTRC_ARID0(0xe));
732 }
733
734 static void vou_hw_init(struct zx_vou_hw *vou)
735 {
736         /* Release reset for all VOU modules */
737         zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
738
739         /* Enable all VOU module clocks */
740         zx_writel(vou->vouctl + VOU_CLK_EN, ~0);
741
742         /* Clear both OSD and TIMING_CTRL interrupt state */
743         zx_writel(vou->osd + OSD_INT_CLRSTA, ~0);
744         zx_writel(vou->timing + TIMING_INT_STATE, ~0);
745
746         /* Enable OSD and TIMING_CTRL interrrupts */
747         zx_writel(vou->osd + OSD_INT_MSK, OSD_INT_ENABLE);
748         zx_writel(vou->timing + TIMING_INT_CTRL, TIMING_INT_ENABLE);
749
750         /* Select GPC as input to gl/vl scaler as a sane default setting */
751         zx_writel(vou->otfppu + OTFPPU_RSZ_DATA_SOURCE, 0x2a);
752
753         /*
754          * Needs to reset channel and layer logic per frame when frame starts
755          * to get VOU work properly.
756          */
757         zx_writel_mask(vou->osd + OSD_RST_CLR, RST_PER_FRAME, RST_PER_FRAME);
758
759         vou_dtrc_init(vou);
760 }
761
762 static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
763 {
764         struct platform_device *pdev = to_platform_device(dev);
765         struct drm_device *drm = data;
766         struct zx_vou_hw *vou;
767         struct resource *res;
768         int irq;
769         int ret;
770
771         vou = devm_kzalloc(dev, sizeof(*vou), GFP_KERNEL);
772         if (!vou)
773                 return -ENOMEM;
774
775         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osd");
776         vou->osd = devm_ioremap_resource(dev, res);
777         if (IS_ERR(vou->osd)) {
778                 ret = PTR_ERR(vou->osd);
779                 DRM_DEV_ERROR(dev, "failed to remap osd region: %d\n", ret);
780                 return ret;
781         }
782
783         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "timing_ctrl");
784         vou->timing = devm_ioremap_resource(dev, res);
785         if (IS_ERR(vou->timing)) {
786                 ret = PTR_ERR(vou->timing);
787                 DRM_DEV_ERROR(dev, "failed to remap timing_ctrl region: %d\n",
788                               ret);
789                 return ret;
790         }
791
792         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dtrc");
793         vou->dtrc = devm_ioremap_resource(dev, res);
794         if (IS_ERR(vou->dtrc)) {
795                 ret = PTR_ERR(vou->dtrc);
796                 DRM_DEV_ERROR(dev, "failed to remap dtrc region: %d\n", ret);
797                 return ret;
798         }
799
800         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vou_ctrl");
801         vou->vouctl = devm_ioremap_resource(dev, res);
802         if (IS_ERR(vou->vouctl)) {
803                 ret = PTR_ERR(vou->vouctl);
804                 DRM_DEV_ERROR(dev, "failed to remap vou_ctrl region: %d\n",
805                               ret);
806                 return ret;
807         }
808
809         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otfppu");
810         vou->otfppu = devm_ioremap_resource(dev, res);
811         if (IS_ERR(vou->otfppu)) {
812                 ret = PTR_ERR(vou->otfppu);
813                 DRM_DEV_ERROR(dev, "failed to remap otfppu region: %d\n", ret);
814                 return ret;
815         }
816
817         irq = platform_get_irq(pdev, 0);
818         if (irq < 0)
819                 return irq;
820
821         vou->axi_clk = devm_clk_get(dev, "aclk");
822         if (IS_ERR(vou->axi_clk)) {
823                 ret = PTR_ERR(vou->axi_clk);
824                 DRM_DEV_ERROR(dev, "failed to get axi_clk: %d\n", ret);
825                 return ret;
826         }
827
828         vou->ppu_clk = devm_clk_get(dev, "ppu_wclk");
829         if (IS_ERR(vou->ppu_clk)) {
830                 ret = PTR_ERR(vou->ppu_clk);
831                 DRM_DEV_ERROR(dev, "failed to get ppu_clk: %d\n", ret);
832                 return ret;
833         }
834
835         ret = clk_prepare_enable(vou->axi_clk);
836         if (ret) {
837                 DRM_DEV_ERROR(dev, "failed to enable axi_clk: %d\n", ret);
838                 return ret;
839         }
840
841         clk_prepare_enable(vou->ppu_clk);
842         if (ret) {
843                 DRM_DEV_ERROR(dev, "failed to enable ppu_clk: %d\n", ret);
844                 goto disable_axi_clk;
845         }
846
847         vou->dev = dev;
848         dev_set_drvdata(dev, vou);
849
850         vou_hw_init(vou);
851
852         ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou);
853         if (ret < 0) {
854                 DRM_DEV_ERROR(dev, "failed to request vou irq: %d\n", ret);
855                 goto disable_ppu_clk;
856         }
857
858         ret = zx_crtc_init(drm, vou, VOU_CHN_MAIN);
859         if (ret) {
860                 DRM_DEV_ERROR(dev, "failed to init main channel crtc: %d\n",
861                               ret);
862                 goto disable_ppu_clk;
863         }
864
865         ret = zx_crtc_init(drm, vou, VOU_CHN_AUX);
866         if (ret) {
867                 DRM_DEV_ERROR(dev, "failed to init aux channel crtc: %d\n",
868                               ret);
869                 goto disable_ppu_clk;
870         }
871
872         zx_overlay_init(drm, vou);
873
874         return 0;
875
876 disable_ppu_clk:
877         clk_disable_unprepare(vou->ppu_clk);
878 disable_axi_clk:
879         clk_disable_unprepare(vou->axi_clk);
880         return ret;
881 }
882
883 static void zx_crtc_unbind(struct device *dev, struct device *master,
884                            void *data)
885 {
886         struct zx_vou_hw *vou = dev_get_drvdata(dev);
887
888         clk_disable_unprepare(vou->axi_clk);
889         clk_disable_unprepare(vou->ppu_clk);
890 }
891
892 static const struct component_ops zx_crtc_component_ops = {
893         .bind = zx_crtc_bind,
894         .unbind = zx_crtc_unbind,
895 };
896
897 static int zx_crtc_probe(struct platform_device *pdev)
898 {
899         return component_add(&pdev->dev, &zx_crtc_component_ops);
900 }
901
902 static int zx_crtc_remove(struct platform_device *pdev)
903 {
904         component_del(&pdev->dev, &zx_crtc_component_ops);
905         return 0;
906 }
907
908 static const struct of_device_id zx_crtc_of_match[] = {
909         { .compatible = "zte,zx296718-dpc", },
910         { /* end */ },
911 };
912 MODULE_DEVICE_TABLE(of, zx_crtc_of_match);
913
914 struct platform_driver zx_crtc_driver = {
915         .probe = zx_crtc_probe,
916         .remove = zx_crtc_remove,
917         .driver = {
918                 .name = "zx-crtc",
919                 .of_match_table = zx_crtc_of_match,
920         },
921 };