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