]> Git Repo - linux.git/blob - drivers/gpu/drm/zte/zx_vou.c
Merge tag 'spi-fix-v4.10-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/brooni...
[linux.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 timing_shift;
44         u32 timing_pi_shift;
45 };
46
47 static const struct zx_crtc_regs main_crtc_regs = {
48         .fir_active = FIR_MAIN_ACTIVE,
49         .fir_htiming = FIR_MAIN_H_TIMING,
50         .fir_vtiming = FIR_MAIN_V_TIMING,
51         .timing_shift = TIMING_MAIN_SHIFT,
52         .timing_pi_shift = TIMING_MAIN_PI_SHIFT,
53 };
54
55 static const struct zx_crtc_regs aux_crtc_regs = {
56         .fir_active = FIR_AUX_ACTIVE,
57         .fir_htiming = FIR_AUX_H_TIMING,
58         .fir_vtiming = FIR_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 gl_enable;
69 };
70
71 static const struct zx_crtc_bits main_crtc_bits = {
72         .polarity_mask = MAIN_POL_MASK,
73         .polarity_shift = MAIN_POL_SHIFT,
74         .int_frame_mask = TIMING_INT_MAIN_FRAME,
75         .tc_enable = MAIN_TC_EN,
76         .gl_enable = OSD_CTRL0_GL0_EN,
77 };
78
79 static const struct zx_crtc_bits aux_crtc_bits = {
80         .polarity_mask = AUX_POL_MASK,
81         .polarity_shift = AUX_POL_SHIFT,
82         .int_frame_mask = TIMING_INT_AUX_FRAME,
83         .tc_enable = AUX_TC_EN,
84         .gl_enable = OSD_CTRL0_GL1_EN,
85 };
86
87 struct zx_crtc {
88         struct drm_crtc crtc;
89         struct drm_plane *primary;
90         struct zx_vou_hw *vou;
91         void __iomem *chnreg;
92         const struct zx_crtc_regs *regs;
93         const struct zx_crtc_bits *bits;
94         enum vou_chn_type chn_type;
95         struct clk *pixclk;
96 };
97
98 #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
99
100 struct zx_vou_hw {
101         struct device *dev;
102         void __iomem *osd;
103         void __iomem *timing;
104         void __iomem *vouctl;
105         void __iomem *otfppu;
106         void __iomem *dtrc;
107         struct clk *axi_clk;
108         struct clk *ppu_clk;
109         struct clk *main_clk;
110         struct clk *aux_clk;
111         struct zx_crtc *main_crtc;
112         struct zx_crtc *aux_crtc;
113 };
114
115 static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
116 {
117         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
118
119         return zcrtc->vou;
120 }
121
122 void vou_inf_enable(const struct vou_inf *inf, struct drm_crtc *crtc)
123 {
124         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
125         struct zx_vou_hw *vou = zcrtc->vou;
126         bool is_main = zcrtc->chn_type == VOU_CHN_MAIN;
127         u32 data_sel_shift = inf->id << 1;
128
129         /* Select data format */
130         zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift,
131                        inf->data_sel << data_sel_shift);
132
133         /* Select channel */
134         zx_writel_mask(vou->vouctl + VOU_INF_CH_SEL, 0x1 << inf->id,
135                        zcrtc->chn_type << inf->id);
136
137         /* Select interface clocks */
138         zx_writel_mask(vou->vouctl + VOU_CLK_SEL, inf->clocks_sel_bits,
139                        is_main ? 0 : inf->clocks_sel_bits);
140
141         /* Enable interface clocks */
142         zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits,
143                        inf->clocks_en_bits);
144
145         /* Enable the device */
146         zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << inf->id, 1 << inf->id);
147 }
148
149 void vou_inf_disable(const struct vou_inf *inf, struct drm_crtc *crtc)
150 {
151         struct zx_vou_hw *vou = crtc_to_vou(crtc);
152
153         /* Disable the device */
154         zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << inf->id, 0);
155
156         /* Disable interface clocks */
157         zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0);
158 }
159
160 static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
161 {
162         zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
163 }
164
165 static void zx_crtc_enable(struct drm_crtc *crtc)
166 {
167         struct drm_display_mode *mode = &crtc->state->adjusted_mode;
168         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
169         struct zx_vou_hw *vou = zcrtc->vou;
170         const struct zx_crtc_regs *regs = zcrtc->regs;
171         const struct zx_crtc_bits *bits = zcrtc->bits;
172         struct videomode vm;
173         u32 pol = 0;
174         u32 val;
175         int ret;
176
177         drm_display_mode_to_videomode(mode, &vm);
178
179         /* Set up timing parameters */
180         val = V_ACTIVE(vm.vactive - 1);
181         val |= H_ACTIVE(vm.hactive - 1);
182         zx_writel(vou->timing + regs->fir_active, val);
183
184         val = SYNC_WIDE(vm.hsync_len - 1);
185         val |= BACK_PORCH(vm.hback_porch - 1);
186         val |= FRONT_PORCH(vm.hfront_porch - 1);
187         zx_writel(vou->timing + regs->fir_htiming, val);
188
189         val = SYNC_WIDE(vm.vsync_len - 1);
190         val |= BACK_PORCH(vm.vback_porch - 1);
191         val |= FRONT_PORCH(vm.vfront_porch - 1);
192         zx_writel(vou->timing + regs->fir_vtiming, val);
193
194         /* Set up polarities */
195         if (vm.flags & DISPLAY_FLAGS_VSYNC_LOW)
196                 pol |= 1 << POL_VSYNC_SHIFT;
197         if (vm.flags & DISPLAY_FLAGS_HSYNC_LOW)
198                 pol |= 1 << POL_HSYNC_SHIFT;
199
200         zx_writel_mask(vou->timing + TIMING_CTRL, bits->polarity_mask,
201                        pol << bits->polarity_shift);
202
203         /* Setup SHIFT register by following what ZTE BSP does */
204         zx_writel(vou->timing + regs->timing_shift, H_SHIFT_VAL);
205         zx_writel(vou->timing + regs->timing_pi_shift, H_PI_SHIFT_VAL);
206
207         /* Enable TIMING_CTRL */
208         zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable,
209                        bits->tc_enable);
210
211         /* Configure channel screen size */
212         zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_W_MASK,
213                        vm.hactive << CHN_SCREEN_W_SHIFT);
214         zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_H_MASK,
215                        vm.vactive << CHN_SCREEN_H_SHIFT);
216
217         /* Update channel */
218         vou_chn_set_update(zcrtc);
219
220         /* Enable channel */
221         zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE);
222
223         /* Enable Graphic Layer */
224         zx_writel_mask(vou->osd + OSD_CTRL0, bits->gl_enable,
225                        bits->gl_enable);
226
227         drm_crtc_vblank_on(crtc);
228
229         ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000);
230         if (ret) {
231                 DRM_DEV_ERROR(vou->dev, "failed to set pixclk rate: %d\n", ret);
232                 return;
233         }
234
235         ret = clk_prepare_enable(zcrtc->pixclk);
236         if (ret)
237                 DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret);
238 }
239
240 static void zx_crtc_disable(struct drm_crtc *crtc)
241 {
242         struct zx_crtc *zcrtc = to_zx_crtc(crtc);
243         const struct zx_crtc_bits *bits = zcrtc->bits;
244         struct zx_vou_hw *vou = zcrtc->vou;
245
246         clk_disable_unprepare(zcrtc->pixclk);
247
248         drm_crtc_vblank_off(crtc);
249
250         /* Disable Graphic Layer */
251         zx_writel_mask(vou->osd + OSD_CTRL0, bits->gl_enable, 0);
252
253         /* Disable channel */
254         zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0);
255
256         /* Disable TIMING_CTRL */
257         zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 0);
258 }
259
260 static void zx_crtc_atomic_flush(struct drm_crtc *crtc,
261                                   struct drm_crtc_state *old_state)
262 {
263         struct drm_pending_vblank_event *event = crtc->state->event;
264
265         if (!event)
266                 return;
267
268         crtc->state->event = NULL;
269
270         spin_lock_irq(&crtc->dev->event_lock);
271         if (drm_crtc_vblank_get(crtc) == 0)
272                 drm_crtc_arm_vblank_event(crtc, event);
273         else
274                 drm_crtc_send_vblank_event(crtc, event);
275         spin_unlock_irq(&crtc->dev->event_lock);
276 }
277
278 static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = {
279         .enable = zx_crtc_enable,
280         .disable = zx_crtc_disable,
281         .atomic_flush = zx_crtc_atomic_flush,
282 };
283
284 static const struct drm_crtc_funcs zx_crtc_funcs = {
285         .destroy = drm_crtc_cleanup,
286         .set_config = drm_atomic_helper_set_config,
287         .page_flip = drm_atomic_helper_page_flip,
288         .reset = drm_atomic_helper_crtc_reset,
289         .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
290         .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
291 };
292
293 static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
294                         enum vou_chn_type chn_type)
295 {
296         struct device *dev = vou->dev;
297         struct zx_layer_data data;
298         struct zx_crtc *zcrtc;
299         int ret;
300
301         zcrtc = devm_kzalloc(dev, sizeof(*zcrtc), GFP_KERNEL);
302         if (!zcrtc)
303                 return -ENOMEM;
304
305         zcrtc->vou = vou;
306         zcrtc->chn_type = chn_type;
307
308         if (chn_type == VOU_CHN_MAIN) {
309                 data.layer = vou->osd + MAIN_GL_OFFSET;
310                 data.csc = vou->osd + MAIN_CSC_OFFSET;
311                 data.hbsc = vou->osd + MAIN_HBSC_OFFSET;
312                 data.rsz = vou->otfppu + MAIN_RSZ_OFFSET;
313                 zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
314                 zcrtc->regs = &main_crtc_regs;
315                 zcrtc->bits = &main_crtc_bits;
316         } else {
317                 data.layer = vou->osd + AUX_GL_OFFSET;
318                 data.csc = vou->osd + AUX_CSC_OFFSET;
319                 data.hbsc = vou->osd + AUX_HBSC_OFFSET;
320                 data.rsz = vou->otfppu + AUX_RSZ_OFFSET;
321                 zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
322                 zcrtc->regs = &aux_crtc_regs;
323                 zcrtc->bits = &aux_crtc_bits;
324         }
325
326         zcrtc->pixclk = devm_clk_get(dev, (chn_type == VOU_CHN_MAIN) ?
327                                           "main_wclk" : "aux_wclk");
328         if (IS_ERR(zcrtc->pixclk)) {
329                 ret = PTR_ERR(zcrtc->pixclk);
330                 DRM_DEV_ERROR(dev, "failed to get pix clk: %d\n", ret);
331                 return ret;
332         }
333
334         zcrtc->primary = zx_plane_init(drm, dev, &data, DRM_PLANE_TYPE_PRIMARY);
335         if (IS_ERR(zcrtc->primary)) {
336                 ret = PTR_ERR(zcrtc->primary);
337                 DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret);
338                 return ret;
339         }
340
341         ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL,
342                                         &zx_crtc_funcs, NULL);
343         if (ret) {
344                 DRM_DEV_ERROR(dev, "failed to init drm crtc: %d\n", ret);
345                 return ret;
346         }
347
348         drm_crtc_helper_add(&zcrtc->crtc, &zx_crtc_helper_funcs);
349
350         if (chn_type == VOU_CHN_MAIN)
351                 vou->main_crtc = zcrtc;
352         else
353                 vou->aux_crtc = zcrtc;
354
355         return 0;
356 }
357
358 static inline struct drm_crtc *zx_find_crtc(struct drm_device *drm, int pipe)
359 {
360         struct drm_crtc *crtc;
361
362         list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
363                 if (crtc->index == pipe)
364                         return crtc;
365
366         return NULL;
367 }
368
369 int zx_vou_enable_vblank(struct drm_device *drm, unsigned int pipe)
370 {
371         struct drm_crtc *crtc;
372         struct zx_crtc *zcrtc;
373         struct zx_vou_hw *vou;
374         u32 int_frame_mask;
375
376         crtc = zx_find_crtc(drm, pipe);
377         if (!crtc)
378                 return 0;
379
380         vou = crtc_to_vou(crtc);
381         zcrtc = to_zx_crtc(crtc);
382         int_frame_mask = zcrtc->bits->int_frame_mask;
383
384         zx_writel_mask(vou->timing + TIMING_INT_CTRL, int_frame_mask,
385                        int_frame_mask);
386
387         return 0;
388 }
389
390 void zx_vou_disable_vblank(struct drm_device *drm, unsigned int pipe)
391 {
392         struct drm_crtc *crtc;
393         struct zx_crtc *zcrtc;
394         struct zx_vou_hw *vou;
395
396         crtc = zx_find_crtc(drm, pipe);
397         if (!crtc)
398                 return;
399
400         vou = crtc_to_vou(crtc);
401         zcrtc = to_zx_crtc(crtc);
402
403         zx_writel_mask(vou->timing + TIMING_INT_CTRL,
404                        zcrtc->bits->int_frame_mask, 0);
405 }
406
407 static irqreturn_t vou_irq_handler(int irq, void *dev_id)
408 {
409         struct zx_vou_hw *vou = dev_id;
410         u32 state;
411
412         /* Handle TIMING_CTRL frame interrupts */
413         state = zx_readl(vou->timing + TIMING_INT_STATE);
414         zx_writel(vou->timing + TIMING_INT_STATE, state);
415
416         if (state & TIMING_INT_MAIN_FRAME)
417                 drm_crtc_handle_vblank(&vou->main_crtc->crtc);
418
419         if (state & TIMING_INT_AUX_FRAME)
420                 drm_crtc_handle_vblank(&vou->aux_crtc->crtc);
421
422         /* Handle OSD interrupts */
423         state = zx_readl(vou->osd + OSD_INT_STA);
424         zx_writel(vou->osd + OSD_INT_CLRSTA, state);
425
426         if (state & OSD_INT_MAIN_UPT) {
427                 vou_chn_set_update(vou->main_crtc);
428                 zx_plane_set_update(vou->main_crtc->primary);
429         }
430
431         if (state & OSD_INT_AUX_UPT) {
432                 vou_chn_set_update(vou->aux_crtc);
433                 zx_plane_set_update(vou->aux_crtc->primary);
434         }
435
436         if (state & OSD_INT_ERROR)
437                 DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state);
438
439         return IRQ_HANDLED;
440 }
441
442 static void vou_dtrc_init(struct zx_vou_hw *vou)
443 {
444         /* Clear bit for bypass by ID */
445         zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL,
446                        TILE2RASTESCAN_BYPASS_MODE, 0);
447
448         /* Select ARIDR mode */
449         zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, DETILE_ARIDR_MODE_MASK,
450                        DETILE_ARID_IN_ARIDR);
451
452         /* Bypass decompression for both frames */
453         zx_writel_mask(vou->dtrc + DTRC_F0_CTRL, DTRC_DECOMPRESS_BYPASS,
454                        DTRC_DECOMPRESS_BYPASS);
455         zx_writel_mask(vou->dtrc + DTRC_F1_CTRL, DTRC_DECOMPRESS_BYPASS,
456                        DTRC_DECOMPRESS_BYPASS);
457
458         /* Set up ARID register */
459         zx_writel(vou->dtrc + DTRC_ARID, DTRC_ARID3(0xf) | DTRC_ARID2(0xe) |
460                   DTRC_ARID1(0xf) | DTRC_ARID0(0xe));
461 }
462
463 static void vou_hw_init(struct zx_vou_hw *vou)
464 {
465         /* Set GL0 to main channel and GL1 to aux channel */
466         zx_writel_mask(vou->osd + OSD_CTRL0, OSD_CTRL0_GL0_SEL, 0);
467         zx_writel_mask(vou->osd + OSD_CTRL0, OSD_CTRL0_GL1_SEL,
468                        OSD_CTRL0_GL1_SEL);
469
470         /* Release reset for all VOU modules */
471         zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
472
473         /* Select main clock for GL0 and aux clock for GL1 module */
474         zx_writel_mask(vou->vouctl + VOU_CLK_SEL, VOU_CLK_GL0_SEL, 0);
475         zx_writel_mask(vou->vouctl + VOU_CLK_SEL, VOU_CLK_GL1_SEL,
476                        VOU_CLK_GL1_SEL);
477
478         /* Enable clock auto-gating for all VOU modules */
479         zx_writel(vou->vouctl + VOU_CLK_REQEN, ~0);
480
481         /* Enable all VOU module clocks */
482         zx_writel(vou->vouctl + VOU_CLK_EN, ~0);
483
484         /* Clear both OSD and TIMING_CTRL interrupt state */
485         zx_writel(vou->osd + OSD_INT_CLRSTA, ~0);
486         zx_writel(vou->timing + TIMING_INT_STATE, ~0);
487
488         /* Enable OSD and TIMING_CTRL interrrupts */
489         zx_writel(vou->osd + OSD_INT_MSK, OSD_INT_ENABLE);
490         zx_writel(vou->timing + TIMING_INT_CTRL, TIMING_INT_ENABLE);
491
492         /* Select GPC as input to gl/vl scaler as a sane default setting */
493         zx_writel(vou->otfppu + OTFPPU_RSZ_DATA_SOURCE, 0x2a);
494
495         /*
496          * Needs to reset channel and layer logic per frame when frame starts
497          * to get VOU work properly.
498          */
499         zx_writel_mask(vou->osd + OSD_RST_CLR, RST_PER_FRAME, RST_PER_FRAME);
500
501         vou_dtrc_init(vou);
502 }
503
504 static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
505 {
506         struct platform_device *pdev = to_platform_device(dev);
507         struct drm_device *drm = data;
508         struct zx_vou_hw *vou;
509         struct resource *res;
510         int irq;
511         int ret;
512
513         vou = devm_kzalloc(dev, sizeof(*vou), GFP_KERNEL);
514         if (!vou)
515                 return -ENOMEM;
516
517         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osd");
518         vou->osd = devm_ioremap_resource(dev, res);
519         if (IS_ERR(vou->osd)) {
520                 ret = PTR_ERR(vou->osd);
521                 DRM_DEV_ERROR(dev, "failed to remap osd region: %d\n", ret);
522                 return ret;
523         }
524
525         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "timing_ctrl");
526         vou->timing = devm_ioremap_resource(dev, res);
527         if (IS_ERR(vou->timing)) {
528                 ret = PTR_ERR(vou->timing);
529                 DRM_DEV_ERROR(dev, "failed to remap timing_ctrl region: %d\n",
530                               ret);
531                 return ret;
532         }
533
534         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dtrc");
535         vou->dtrc = devm_ioremap_resource(dev, res);
536         if (IS_ERR(vou->dtrc)) {
537                 ret = PTR_ERR(vou->dtrc);
538                 DRM_DEV_ERROR(dev, "failed to remap dtrc region: %d\n", ret);
539                 return ret;
540         }
541
542         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vou_ctrl");
543         vou->vouctl = devm_ioremap_resource(dev, res);
544         if (IS_ERR(vou->vouctl)) {
545                 ret = PTR_ERR(vou->vouctl);
546                 DRM_DEV_ERROR(dev, "failed to remap vou_ctrl region: %d\n",
547                               ret);
548                 return ret;
549         }
550
551         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otfppu");
552         vou->otfppu = devm_ioremap_resource(dev, res);
553         if (IS_ERR(vou->otfppu)) {
554                 ret = PTR_ERR(vou->otfppu);
555                 DRM_DEV_ERROR(dev, "failed to remap otfppu region: %d\n", ret);
556                 return ret;
557         }
558
559         irq = platform_get_irq(pdev, 0);
560         if (irq < 0)
561                 return irq;
562
563         vou->axi_clk = devm_clk_get(dev, "aclk");
564         if (IS_ERR(vou->axi_clk)) {
565                 ret = PTR_ERR(vou->axi_clk);
566                 DRM_DEV_ERROR(dev, "failed to get axi_clk: %d\n", ret);
567                 return ret;
568         }
569
570         vou->ppu_clk = devm_clk_get(dev, "ppu_wclk");
571         if (IS_ERR(vou->ppu_clk)) {
572                 ret = PTR_ERR(vou->ppu_clk);
573                 DRM_DEV_ERROR(dev, "failed to get ppu_clk: %d\n", ret);
574                 return ret;
575         }
576
577         ret = clk_prepare_enable(vou->axi_clk);
578         if (ret) {
579                 DRM_DEV_ERROR(dev, "failed to enable axi_clk: %d\n", ret);
580                 return ret;
581         }
582
583         clk_prepare_enable(vou->ppu_clk);
584         if (ret) {
585                 DRM_DEV_ERROR(dev, "failed to enable ppu_clk: %d\n", ret);
586                 goto disable_axi_clk;
587         }
588
589         vou->dev = dev;
590         dev_set_drvdata(dev, vou);
591
592         vou_hw_init(vou);
593
594         ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou);
595         if (ret < 0) {
596                 DRM_DEV_ERROR(dev, "failed to request vou irq: %d\n", ret);
597                 goto disable_ppu_clk;
598         }
599
600         ret = zx_crtc_init(drm, vou, VOU_CHN_MAIN);
601         if (ret) {
602                 DRM_DEV_ERROR(dev, "failed to init main channel crtc: %d\n",
603                               ret);
604                 goto disable_ppu_clk;
605         }
606
607         ret = zx_crtc_init(drm, vou, VOU_CHN_AUX);
608         if (ret) {
609                 DRM_DEV_ERROR(dev, "failed to init aux channel crtc: %d\n",
610                               ret);
611                 goto disable_ppu_clk;
612         }
613
614         return 0;
615
616 disable_ppu_clk:
617         clk_disable_unprepare(vou->ppu_clk);
618 disable_axi_clk:
619         clk_disable_unprepare(vou->axi_clk);
620         return ret;
621 }
622
623 static void zx_crtc_unbind(struct device *dev, struct device *master,
624                            void *data)
625 {
626         struct zx_vou_hw *vou = dev_get_drvdata(dev);
627
628         clk_disable_unprepare(vou->axi_clk);
629         clk_disable_unprepare(vou->ppu_clk);
630 }
631
632 static const struct component_ops zx_crtc_component_ops = {
633         .bind = zx_crtc_bind,
634         .unbind = zx_crtc_unbind,
635 };
636
637 static int zx_crtc_probe(struct platform_device *pdev)
638 {
639         return component_add(&pdev->dev, &zx_crtc_component_ops);
640 }
641
642 static int zx_crtc_remove(struct platform_device *pdev)
643 {
644         component_del(&pdev->dev, &zx_crtc_component_ops);
645         return 0;
646 }
647
648 static const struct of_device_id zx_crtc_of_match[] = {
649         { .compatible = "zte,zx296718-dpc", },
650         { /* end */ },
651 };
652 MODULE_DEVICE_TABLE(of, zx_crtc_of_match);
653
654 struct platform_driver zx_crtc_driver = {
655         .probe = zx_crtc_probe,
656         .remove = zx_crtc_remove,
657         .driver = {
658                 .name = "zx-crtc",
659                 .of_match_table = zx_crtc_of_match,
660         },
661 };
This page took 0.07317 seconds and 4 git commands to generate.