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 
crtc_to_vou(struct drm_crtc * crtc)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 
vou_inf_hdmi_audio_sel(struct drm_crtc * crtc,enum vou_inf_hdmi_audio aud)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 
vou_inf_enable(enum vou_inf_id id,struct drm_crtc * crtc)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 
vou_inf_disable(enum vou_inf_id id,struct drm_crtc * crtc)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 
zx_vou_config_dividers(struct drm_crtc * crtc,struct vou_div_config * configs,int num)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 
vou_chn_set_update(struct zx_crtc * zcrtc)348 static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
349 {
350 	zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
351 }
352 
zx_crtc_atomic_enable(struct drm_crtc * crtc,struct drm_crtc_state * old_state)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 
zx_crtc_atomic_disable(struct drm_crtc * crtc,struct drm_crtc_state * old_state)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 
zx_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_crtc_state * old_state)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 
zx_vou_enable_vblank(struct drm_crtc * crtc)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 
zx_vou_disable_vblank(struct drm_crtc * crtc)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 
zx_crtc_init(struct drm_device * drm,struct zx_vou_hw * vou,enum vou_chn_type chn_type)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 
zx_vou_layer_enable(struct drm_plane * plane)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 
zx_vou_layer_disable(struct drm_plane * plane,struct drm_plane_state * old_state)630 void zx_vou_layer_disable(struct drm_plane *plane,
631 			  struct drm_plane_state *old_state)
632 {
633 	struct zx_crtc *zcrtc = to_zx_crtc(old_state->crtc);
634 	struct zx_vou_hw *vou = zcrtc->vou;
635 	struct zx_plane *zplane = to_zx_plane(plane);
636 	const struct vou_layer_bits *bits = zplane->bits;
637 
638 	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
639 }
640 
zx_overlay_init(struct drm_device * drm,struct zx_vou_hw * vou)641 static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou)
642 {
643 	struct device *dev = vou->dev;
644 	struct zx_plane *zplane;
645 	int i;
646 	int ret;
647 
648 	/*
649 	 * VL0 has some quirks on scaling support which need special handling.
650 	 * Let's leave it out for now.
651 	 */
652 	for (i = 1; i < VL_NUM; i++) {
653 		zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
654 		if (!zplane) {
655 			DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i);
656 			return;
657 		}
658 
659 		zplane->layer = vou->osd + OSD_VL_OFFSET(i);
660 		zplane->hbsc = vou->osd + HBSC_VL_OFFSET(i);
661 		zplane->rsz = vou->otfppu + RSZ_VL_OFFSET(i);
662 		zplane->bits = &zx_vl_bits[i];
663 
664 		ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY);
665 		if (ret) {
666 			DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i);
667 			continue;
668 		}
669 	}
670 }
671 
zx_osd_int_update(struct zx_crtc * zcrtc)672 static inline void zx_osd_int_update(struct zx_crtc *zcrtc)
673 {
674 	struct drm_crtc *crtc = &zcrtc->crtc;
675 	struct drm_plane *plane;
676 
677 	vou_chn_set_update(zcrtc);
678 
679 	drm_for_each_plane_mask(plane, crtc->dev, crtc->state->plane_mask)
680 		zx_plane_set_update(plane);
681 }
682 
vou_irq_handler(int irq,void * dev_id)683 static irqreturn_t vou_irq_handler(int irq, void *dev_id)
684 {
685 	struct zx_vou_hw *vou = dev_id;
686 	u32 state;
687 
688 	/* Handle TIMING_CTRL frame interrupts */
689 	state = zx_readl(vou->timing + TIMING_INT_STATE);
690 	zx_writel(vou->timing + TIMING_INT_STATE, state);
691 
692 	if (state & TIMING_INT_MAIN_FRAME)
693 		drm_crtc_handle_vblank(&vou->main_crtc->crtc);
694 
695 	if (state & TIMING_INT_AUX_FRAME)
696 		drm_crtc_handle_vblank(&vou->aux_crtc->crtc);
697 
698 	/* Handle OSD interrupts */
699 	state = zx_readl(vou->osd + OSD_INT_STA);
700 	zx_writel(vou->osd + OSD_INT_CLRSTA, state);
701 
702 	if (state & OSD_INT_MAIN_UPT)
703 		zx_osd_int_update(vou->main_crtc);
704 
705 	if (state & OSD_INT_AUX_UPT)
706 		zx_osd_int_update(vou->aux_crtc);
707 
708 	if (state & OSD_INT_ERROR)
709 		DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state);
710 
711 	return IRQ_HANDLED;
712 }
713 
vou_dtrc_init(struct zx_vou_hw * vou)714 static void vou_dtrc_init(struct zx_vou_hw *vou)
715 {
716 	/* Clear bit for bypass by ID */
717 	zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL,
718 		       TILE2RASTESCAN_BYPASS_MODE, 0);
719 
720 	/* Select ARIDR mode */
721 	zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, DETILE_ARIDR_MODE_MASK,
722 		       DETILE_ARID_IN_ARIDR);
723 
724 	/* Bypass decompression for both frames */
725 	zx_writel_mask(vou->dtrc + DTRC_F0_CTRL, DTRC_DECOMPRESS_BYPASS,
726 		       DTRC_DECOMPRESS_BYPASS);
727 	zx_writel_mask(vou->dtrc + DTRC_F1_CTRL, DTRC_DECOMPRESS_BYPASS,
728 		       DTRC_DECOMPRESS_BYPASS);
729 
730 	/* Set up ARID register */
731 	zx_writel(vou->dtrc + DTRC_ARID, DTRC_ARID3(0xf) | DTRC_ARID2(0xe) |
732 		  DTRC_ARID1(0xf) | DTRC_ARID0(0xe));
733 }
734 
vou_hw_init(struct zx_vou_hw * vou)735 static void vou_hw_init(struct zx_vou_hw *vou)
736 {
737 	/* Release reset for all VOU modules */
738 	zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
739 
740 	/* Enable all VOU module clocks */
741 	zx_writel(vou->vouctl + VOU_CLK_EN, ~0);
742 
743 	/* Clear both OSD and TIMING_CTRL interrupt state */
744 	zx_writel(vou->osd + OSD_INT_CLRSTA, ~0);
745 	zx_writel(vou->timing + TIMING_INT_STATE, ~0);
746 
747 	/* Enable OSD and TIMING_CTRL interrrupts */
748 	zx_writel(vou->osd + OSD_INT_MSK, OSD_INT_ENABLE);
749 	zx_writel(vou->timing + TIMING_INT_CTRL, TIMING_INT_ENABLE);
750 
751 	/* Select GPC as input to gl/vl scaler as a sane default setting */
752 	zx_writel(vou->otfppu + OTFPPU_RSZ_DATA_SOURCE, 0x2a);
753 
754 	/*
755 	 * Needs to reset channel and layer logic per frame when frame starts
756 	 * to get VOU work properly.
757 	 */
758 	zx_writel_mask(vou->osd + OSD_RST_CLR, RST_PER_FRAME, RST_PER_FRAME);
759 
760 	vou_dtrc_init(vou);
761 }
762 
zx_crtc_bind(struct device * dev,struct device * master,void * data)763 static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
764 {
765 	struct platform_device *pdev = to_platform_device(dev);
766 	struct drm_device *drm = data;
767 	struct zx_vou_hw *vou;
768 	struct resource *res;
769 	int irq;
770 	int ret;
771 
772 	vou = devm_kzalloc(dev, sizeof(*vou), GFP_KERNEL);
773 	if (!vou)
774 		return -ENOMEM;
775 
776 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osd");
777 	vou->osd = devm_ioremap_resource(dev, res);
778 	if (IS_ERR(vou->osd)) {
779 		ret = PTR_ERR(vou->osd);
780 		DRM_DEV_ERROR(dev, "failed to remap osd region: %d\n", ret);
781 		return ret;
782 	}
783 
784 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "timing_ctrl");
785 	vou->timing = devm_ioremap_resource(dev, res);
786 	if (IS_ERR(vou->timing)) {
787 		ret = PTR_ERR(vou->timing);
788 		DRM_DEV_ERROR(dev, "failed to remap timing_ctrl region: %d\n",
789 			      ret);
790 		return ret;
791 	}
792 
793 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dtrc");
794 	vou->dtrc = devm_ioremap_resource(dev, res);
795 	if (IS_ERR(vou->dtrc)) {
796 		ret = PTR_ERR(vou->dtrc);
797 		DRM_DEV_ERROR(dev, "failed to remap dtrc region: %d\n", ret);
798 		return ret;
799 	}
800 
801 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vou_ctrl");
802 	vou->vouctl = devm_ioremap_resource(dev, res);
803 	if (IS_ERR(vou->vouctl)) {
804 		ret = PTR_ERR(vou->vouctl);
805 		DRM_DEV_ERROR(dev, "failed to remap vou_ctrl region: %d\n",
806 			      ret);
807 		return ret;
808 	}
809 
810 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otfppu");
811 	vou->otfppu = devm_ioremap_resource(dev, res);
812 	if (IS_ERR(vou->otfppu)) {
813 		ret = PTR_ERR(vou->otfppu);
814 		DRM_DEV_ERROR(dev, "failed to remap otfppu region: %d\n", ret);
815 		return ret;
816 	}
817 
818 	irq = platform_get_irq(pdev, 0);
819 	if (irq < 0)
820 		return irq;
821 
822 	vou->axi_clk = devm_clk_get(dev, "aclk");
823 	if (IS_ERR(vou->axi_clk)) {
824 		ret = PTR_ERR(vou->axi_clk);
825 		DRM_DEV_ERROR(dev, "failed to get axi_clk: %d\n", ret);
826 		return ret;
827 	}
828 
829 	vou->ppu_clk = devm_clk_get(dev, "ppu_wclk");
830 	if (IS_ERR(vou->ppu_clk)) {
831 		ret = PTR_ERR(vou->ppu_clk);
832 		DRM_DEV_ERROR(dev, "failed to get ppu_clk: %d\n", ret);
833 		return ret;
834 	}
835 
836 	ret = clk_prepare_enable(vou->axi_clk);
837 	if (ret) {
838 		DRM_DEV_ERROR(dev, "failed to enable axi_clk: %d\n", ret);
839 		return ret;
840 	}
841 
842 	clk_prepare_enable(vou->ppu_clk);
843 	if (ret) {
844 		DRM_DEV_ERROR(dev, "failed to enable ppu_clk: %d\n", ret);
845 		goto disable_axi_clk;
846 	}
847 
848 	vou->dev = dev;
849 	dev_set_drvdata(dev, vou);
850 
851 	vou_hw_init(vou);
852 
853 	ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou);
854 	if (ret < 0) {
855 		DRM_DEV_ERROR(dev, "failed to request vou irq: %d\n", ret);
856 		goto disable_ppu_clk;
857 	}
858 
859 	ret = zx_crtc_init(drm, vou, VOU_CHN_MAIN);
860 	if (ret) {
861 		DRM_DEV_ERROR(dev, "failed to init main channel crtc: %d\n",
862 			      ret);
863 		goto disable_ppu_clk;
864 	}
865 
866 	ret = zx_crtc_init(drm, vou, VOU_CHN_AUX);
867 	if (ret) {
868 		DRM_DEV_ERROR(dev, "failed to init aux channel crtc: %d\n",
869 			      ret);
870 		goto disable_ppu_clk;
871 	}
872 
873 	zx_overlay_init(drm, vou);
874 
875 	return 0;
876 
877 disable_ppu_clk:
878 	clk_disable_unprepare(vou->ppu_clk);
879 disable_axi_clk:
880 	clk_disable_unprepare(vou->axi_clk);
881 	return ret;
882 }
883 
zx_crtc_unbind(struct device * dev,struct device * master,void * data)884 static void zx_crtc_unbind(struct device *dev, struct device *master,
885 			   void *data)
886 {
887 	struct zx_vou_hw *vou = dev_get_drvdata(dev);
888 
889 	clk_disable_unprepare(vou->axi_clk);
890 	clk_disable_unprepare(vou->ppu_clk);
891 }
892 
893 static const struct component_ops zx_crtc_component_ops = {
894 	.bind = zx_crtc_bind,
895 	.unbind = zx_crtc_unbind,
896 };
897 
zx_crtc_probe(struct platform_device * pdev)898 static int zx_crtc_probe(struct platform_device *pdev)
899 {
900 	return component_add(&pdev->dev, &zx_crtc_component_ops);
901 }
902 
zx_crtc_remove(struct platform_device * pdev)903 static int zx_crtc_remove(struct platform_device *pdev)
904 {
905 	component_del(&pdev->dev, &zx_crtc_component_ops);
906 	return 0;
907 }
908 
909 static const struct of_device_id zx_crtc_of_match[] = {
910 	{ .compatible = "zte,zx296718-dpc", },
911 	{ /* end */ },
912 };
913 MODULE_DEVICE_TABLE(of, zx_crtc_of_match);
914 
915 struct platform_driver zx_crtc_driver = {
916 	.probe = zx_crtc_probe,
917 	.remove = zx_crtc_remove,
918 	.driver	= {
919 		.name = "zx-crtc",
920 		.of_match_table	= zx_crtc_of_match,
921 	},
922 };
923