• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2016 Linaro Ltd.
4  * Copyright 2016 ZTE Corporation.
5  */
6 
7 #include <linux/clk.h>
8 #include <linux/component.h>
9 #include <linux/module.h>
10 #include <linux/of_address.h>
11 #include <linux/platform_device.h>
12 
13 #include <video/videomode.h>
14 
15 #include <drm/drm_atomic_helper.h>
16 #include <drm/drm_crtc.h>
17 #include <drm/drm_fb_cma_helper.h>
18 #include <drm/drm_fb_helper.h>
19 #include <drm/drm_gem_cma_helper.h>
20 #include <drm/drm_of.h>
21 #include <drm/drm_plane_helper.h>
22 #include <drm/drm_probe_helper.h>
23 #include <drm/drm_vblank.h>
24 
25 #include "zx_common_regs.h"
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 	void __iomem *chncsc;
126 	void __iomem *dither;
127 	const struct zx_crtc_regs *regs;
128 	const struct zx_crtc_bits *bits;
129 	enum vou_chn_type chn_type;
130 	struct clk *pixclk;
131 };
132 
133 #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
134 
135 struct vou_layer_bits {
136 	u32 enable;
137 	u32 chnsel;
138 	u32 clksel;
139 };
140 
141 static const struct vou_layer_bits zx_gl_bits[GL_NUM] = {
142 	{
143 		.enable = OSD_CTRL0_GL0_EN,
144 		.chnsel = OSD_CTRL0_GL0_SEL,
145 		.clksel = VOU_CLK_GL0_SEL,
146 	}, {
147 		.enable = OSD_CTRL0_GL1_EN,
148 		.chnsel = OSD_CTRL0_GL1_SEL,
149 		.clksel = VOU_CLK_GL1_SEL,
150 	},
151 };
152 
153 static const struct vou_layer_bits zx_vl_bits[VL_NUM] = {
154 	{
155 		.enable = OSD_CTRL0_VL0_EN,
156 		.chnsel = OSD_CTRL0_VL0_SEL,
157 		.clksel = VOU_CLK_VL0_SEL,
158 	}, {
159 		.enable = OSD_CTRL0_VL1_EN,
160 		.chnsel = OSD_CTRL0_VL1_SEL,
161 		.clksel = VOU_CLK_VL1_SEL,
162 	}, {
163 		.enable = OSD_CTRL0_VL2_EN,
164 		.chnsel = OSD_CTRL0_VL2_SEL,
165 		.clksel = VOU_CLK_VL2_SEL,
166 	},
167 };
168 
169 struct zx_vou_hw {
170 	struct device *dev;
171 	void __iomem *osd;
172 	void __iomem *timing;
173 	void __iomem *vouctl;
174 	void __iomem *otfppu;
175 	void __iomem *dtrc;
176 	struct clk *axi_clk;
177 	struct clk *ppu_clk;
178 	struct clk *main_clk;
179 	struct clk *aux_clk;
180 	struct zx_crtc *main_crtc;
181 	struct zx_crtc *aux_crtc;
182 };
183 
184 enum vou_inf_data_sel {
185 	VOU_YUV444	= 0,
186 	VOU_RGB_101010	= 1,
187 	VOU_RGB_888	= 2,
188 	VOU_RGB_666	= 3,
189 };
190 
191 struct vou_inf {
192 	enum vou_inf_id id;
193 	enum vou_inf_data_sel data_sel;
194 	u32 clocks_en_bits;
195 	u32 clocks_sel_bits;
196 };
197 
198 static struct vou_inf vou_infs[] = {
199 	[VOU_HDMI] = {
200 		.data_sel = VOU_YUV444,
201 		.clocks_en_bits = BIT(24) | BIT(18) | BIT(6),
202 		.clocks_sel_bits = BIT(13) | BIT(2),
203 	},
204 	[VOU_TV_ENC] = {
205 		.data_sel = VOU_YUV444,
206 		.clocks_en_bits = BIT(15),
207 		.clocks_sel_bits = BIT(11) | BIT(0),
208 	},
209 	[VOU_VGA] = {
210 		.data_sel = VOU_RGB_888,
211 		.clocks_en_bits = BIT(1),
212 		.clocks_sel_bits = BIT(10),
213 	},
214 };
215 
crtc_to_vou(struct drm_crtc * crtc)216 static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
217 {
218 	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
219 
220 	return zcrtc->vou;
221 }
222 
vou_inf_hdmi_audio_sel(struct drm_crtc * crtc,enum vou_inf_hdmi_audio aud)223 void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc,
224 			    enum vou_inf_hdmi_audio aud)
225 {
226 	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
227 	struct zx_vou_hw *vou = zcrtc->vou;
228 
229 	zx_writel_mask(vou->vouctl + VOU_INF_HDMI_CTRL, VOU_HDMI_AUD_MASK, aud);
230 }
231 
vou_inf_enable(enum vou_inf_id id,struct drm_crtc * crtc)232 void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc)
233 {
234 	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
235 	struct zx_vou_hw *vou = zcrtc->vou;
236 	struct vou_inf *inf = &vou_infs[id];
237 	void __iomem *dither = zcrtc->dither;
238 	void __iomem *csc = zcrtc->chncsc;
239 	bool is_main = zcrtc->chn_type == VOU_CHN_MAIN;
240 	u32 data_sel_shift = id << 1;
241 
242 	if (inf->data_sel != VOU_YUV444) {
243 		/* Enable channel CSC for RGB output */
244 		zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK,
245 			       CSC_BT709_IMAGE_YCBCR2RGB << CSC_COV_MODE_SHIFT);
246 		zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE,
247 			       CSC_WORK_ENABLE);
248 
249 		/* Bypass Dither block for RGB output */
250 		zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS,
251 			       DITHER_BYSPASS);
252 	} else {
253 		zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 0);
254 		zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 0);
255 	}
256 
257 	/* Select data format */
258 	zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift,
259 		       inf->data_sel << data_sel_shift);
260 
261 	/* Select channel */
262 	zx_writel_mask(vou->vouctl + VOU_INF_CH_SEL, 0x1 << id,
263 		       zcrtc->chn_type << id);
264 
265 	/* Select interface clocks */
266 	zx_writel_mask(vou->vouctl + VOU_CLK_SEL, inf->clocks_sel_bits,
267 		       is_main ? 0 : inf->clocks_sel_bits);
268 
269 	/* Enable interface clocks */
270 	zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits,
271 		       inf->clocks_en_bits);
272 
273 	/* Enable the device */
274 	zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 1 << id);
275 }
276 
vou_inf_disable(enum vou_inf_id id,struct drm_crtc * crtc)277 void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc)
278 {
279 	struct zx_vou_hw *vou = crtc_to_vou(crtc);
280 	struct vou_inf *inf = &vou_infs[id];
281 
282 	/* Disable the device */
283 	zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 0);
284 
285 	/* Disable interface clocks */
286 	zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0);
287 }
288 
zx_vou_config_dividers(struct drm_crtc * crtc,struct vou_div_config * configs,int num)289 void zx_vou_config_dividers(struct drm_crtc *crtc,
290 			    struct vou_div_config *configs, int num)
291 {
292 	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
293 	struct zx_vou_hw *vou = zcrtc->vou;
294 	const struct zx_crtc_bits *bits = zcrtc->bits;
295 	int i;
296 
297 	/* Clear update flag bit */
298 	zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0);
299 
300 	for (i = 0; i < num; i++) {
301 		struct vou_div_config *cfg = configs + i;
302 		u32 reg, shift;
303 
304 		switch (cfg->id) {
305 		case VOU_DIV_VGA:
306 			reg = VOU_CLK_SEL;
307 			shift = bits->div_vga_shift;
308 			break;
309 		case VOU_DIV_PIC:
310 			reg = VOU_CLK_SEL;
311 			shift = bits->div_pic_shift;
312 			break;
313 		case VOU_DIV_TVENC:
314 			reg = VOU_DIV_PARA;
315 			shift = bits->div_tvenc_shift;
316 			break;
317 		case VOU_DIV_HDMI_PNX:
318 			reg = VOU_DIV_PARA;
319 			shift = bits->div_hdmi_pnx_shift;
320 			break;
321 		case VOU_DIV_HDMI:
322 			reg = VOU_DIV_PARA;
323 			shift = bits->div_hdmi_shift;
324 			break;
325 		case VOU_DIV_INF:
326 			reg = VOU_DIV_PARA;
327 			shift = bits->div_inf_shift;
328 			break;
329 		case VOU_DIV_LAYER:
330 			reg = VOU_DIV_PARA;
331 			shift = bits->div_layer_shift;
332 			break;
333 		default:
334 			continue;
335 		}
336 
337 		/* Each divider occupies 3 bits */
338 		zx_writel_mask(vou->vouctl + reg, 0x7 << shift,
339 			       cfg->val << shift);
340 	}
341 
342 	/* Set update flag bit to get dividers effected */
343 	zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE,
344 		       DIV_PARA_UPDATE);
345 }
346 
vou_chn_set_update(struct zx_crtc * zcrtc)347 static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
348 {
349 	zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
350 }
351 
zx_crtc_atomic_enable(struct drm_crtc * crtc,struct drm_crtc_state * old_state)352 static void zx_crtc_atomic_enable(struct drm_crtc *crtc,
353 				  struct drm_crtc_state *old_state)
354 {
355 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
356 	bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
357 	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
358 	struct zx_vou_hw *vou = zcrtc->vou;
359 	const struct zx_crtc_regs *regs = zcrtc->regs;
360 	const struct zx_crtc_bits *bits = zcrtc->bits;
361 	struct videomode vm;
362 	u32 scan_mask;
363 	u32 pol = 0;
364 	u32 val;
365 	int ret;
366 
367 	drm_display_mode_to_videomode(mode, &vm);
368 
369 	/* Set up timing parameters */
370 	val = V_ACTIVE((interlaced ? vm.vactive / 2 : vm.vactive) - 1);
371 	val |= H_ACTIVE(vm.hactive - 1);
372 	zx_writel(vou->timing + regs->fir_active, val);
373 
374 	val = SYNC_WIDE(vm.hsync_len - 1);
375 	val |= BACK_PORCH(vm.hback_porch - 1);
376 	val |= FRONT_PORCH(vm.hfront_porch - 1);
377 	zx_writel(vou->timing + regs->fir_htiming, val);
378 
379 	val = SYNC_WIDE(vm.vsync_len - 1);
380 	val |= BACK_PORCH(vm.vback_porch - 1);
381 	val |= FRONT_PORCH(vm.vfront_porch - 1);
382 	zx_writel(vou->timing + regs->fir_vtiming, val);
383 
384 	if (interlaced) {
385 		u32 shift = bits->sec_vactive_shift;
386 		u32 mask = bits->sec_vactive_mask;
387 
388 		val = zx_readl(vou->timing + SEC_V_ACTIVE);
389 		val &= ~mask;
390 		val |= ((vm.vactive / 2 - 1) << shift) & mask;
391 		zx_writel(vou->timing + SEC_V_ACTIVE, val);
392 
393 		val = SYNC_WIDE(vm.vsync_len - 1);
394 		/*
395 		 * The vback_porch for the second field needs to shift one on
396 		 * the value for the first field.
397 		 */
398 		val |= BACK_PORCH(vm.vback_porch);
399 		val |= FRONT_PORCH(vm.vfront_porch - 1);
400 		zx_writel(vou->timing + regs->sec_vtiming, val);
401 	}
402 
403 	/* Set up polarities */
404 	if (vm.flags & DISPLAY_FLAGS_VSYNC_LOW)
405 		pol |= 1 << POL_VSYNC_SHIFT;
406 	if (vm.flags & DISPLAY_FLAGS_HSYNC_LOW)
407 		pol |= 1 << POL_HSYNC_SHIFT;
408 
409 	zx_writel_mask(vou->timing + TIMING_CTRL, bits->polarity_mask,
410 		       pol << bits->polarity_shift);
411 
412 	/* Setup SHIFT register by following what ZTE BSP does */
413 	val = H_SHIFT_VAL;
414 	if (interlaced)
415 		val |= V_SHIFT_VAL << 16;
416 	zx_writel(vou->timing + regs->timing_shift, val);
417 	zx_writel(vou->timing + regs->timing_pi_shift, H_PI_SHIFT_VAL);
418 
419 	/* Progressive or interlace scan select */
420 	scan_mask = bits->interlace_select | bits->pi_enable;
421 	zx_writel_mask(vou->timing + SCAN_CTRL, scan_mask,
422 		       interlaced ? scan_mask : 0);
423 
424 	/* Enable TIMING_CTRL */
425 	zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable,
426 		       bits->tc_enable);
427 
428 	/* Configure channel screen size */
429 	zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_W_MASK,
430 		       vm.hactive << CHN_SCREEN_W_SHIFT);
431 	zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_H_MASK,
432 		       vm.vactive << CHN_SCREEN_H_SHIFT);
433 
434 	/* Configure channel interlace buffer control */
435 	zx_writel_mask(zcrtc->chnreg + CHN_INTERLACE_BUF_CTRL, CHN_INTERLACE_EN,
436 		       interlaced ? CHN_INTERLACE_EN : 0);
437 
438 	/* Update channel */
439 	vou_chn_set_update(zcrtc);
440 
441 	/* Enable channel */
442 	zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE);
443 
444 	drm_crtc_vblank_on(crtc);
445 
446 	ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000);
447 	if (ret) {
448 		DRM_DEV_ERROR(vou->dev, "failed to set pixclk rate: %d\n", ret);
449 		return;
450 	}
451 
452 	ret = clk_prepare_enable(zcrtc->pixclk);
453 	if (ret)
454 		DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret);
455 }
456 
zx_crtc_atomic_disable(struct drm_crtc * crtc,struct drm_crtc_state * old_state)457 static void zx_crtc_atomic_disable(struct drm_crtc *crtc,
458 				   struct drm_crtc_state *old_state)
459 {
460 	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
461 	const struct zx_crtc_bits *bits = zcrtc->bits;
462 	struct zx_vou_hw *vou = zcrtc->vou;
463 
464 	clk_disable_unprepare(zcrtc->pixclk);
465 
466 	drm_crtc_vblank_off(crtc);
467 
468 	/* Disable channel */
469 	zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0);
470 
471 	/* Disable TIMING_CTRL */
472 	zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 0);
473 }
474 
zx_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_crtc_state * old_state)475 static void zx_crtc_atomic_flush(struct drm_crtc *crtc,
476 				  struct drm_crtc_state *old_state)
477 {
478 	struct drm_pending_vblank_event *event = crtc->state->event;
479 
480 	if (!event)
481 		return;
482 
483 	crtc->state->event = NULL;
484 
485 	spin_lock_irq(&crtc->dev->event_lock);
486 	if (drm_crtc_vblank_get(crtc) == 0)
487 		drm_crtc_arm_vblank_event(crtc, event);
488 	else
489 		drm_crtc_send_vblank_event(crtc, event);
490 	spin_unlock_irq(&crtc->dev->event_lock);
491 }
492 
493 static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = {
494 	.atomic_flush = zx_crtc_atomic_flush,
495 	.atomic_enable = zx_crtc_atomic_enable,
496 	.atomic_disable = zx_crtc_atomic_disable,
497 };
498 
zx_vou_enable_vblank(struct drm_crtc * crtc)499 static int zx_vou_enable_vblank(struct drm_crtc *crtc)
500 {
501 	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
502 	struct zx_vou_hw *vou = crtc_to_vou(crtc);
503 	u32 int_frame_mask = zcrtc->bits->int_frame_mask;
504 
505 	zx_writel_mask(vou->timing + TIMING_INT_CTRL, int_frame_mask,
506 		       int_frame_mask);
507 
508 	return 0;
509 }
510 
zx_vou_disable_vblank(struct drm_crtc * crtc)511 static void zx_vou_disable_vblank(struct drm_crtc *crtc)
512 {
513 	struct zx_crtc *zcrtc = to_zx_crtc(crtc);
514 	struct zx_vou_hw *vou = crtc_to_vou(crtc);
515 
516 	zx_writel_mask(vou->timing + TIMING_INT_CTRL,
517 		       zcrtc->bits->int_frame_mask, 0);
518 }
519 
520 static const struct drm_crtc_funcs zx_crtc_funcs = {
521 	.destroy = drm_crtc_cleanup,
522 	.set_config = drm_atomic_helper_set_config,
523 	.page_flip = drm_atomic_helper_page_flip,
524 	.reset = drm_atomic_helper_crtc_reset,
525 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
526 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
527 	.enable_vblank = zx_vou_enable_vblank,
528 	.disable_vblank = zx_vou_disable_vblank,
529 };
530 
zx_crtc_init(struct drm_device * drm,struct zx_vou_hw * vou,enum vou_chn_type chn_type)531 static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
532 			enum vou_chn_type chn_type)
533 {
534 	struct device *dev = vou->dev;
535 	struct zx_plane *zplane;
536 	struct zx_crtc *zcrtc;
537 	int ret;
538 
539 	zcrtc = devm_kzalloc(dev, sizeof(*zcrtc), GFP_KERNEL);
540 	if (!zcrtc)
541 		return -ENOMEM;
542 
543 	zcrtc->vou = vou;
544 	zcrtc->chn_type = chn_type;
545 
546 	zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
547 	if (!zplane)
548 		return -ENOMEM;
549 
550 	zplane->dev = dev;
551 
552 	if (chn_type == VOU_CHN_MAIN) {
553 		zplane->layer = vou->osd + MAIN_GL_OFFSET;
554 		zplane->csc = vou->osd + MAIN_GL_CSC_OFFSET;
555 		zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
556 		zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
557 		zplane->bits = &zx_gl_bits[0];
558 		zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
559 		zcrtc->chncsc = vou->osd + MAIN_CHN_CSC_OFFSET;
560 		zcrtc->dither = vou->osd + MAIN_DITHER_OFFSET;
561 		zcrtc->regs = &main_crtc_regs;
562 		zcrtc->bits = &main_crtc_bits;
563 	} else {
564 		zplane->layer = vou->osd + AUX_GL_OFFSET;
565 		zplane->csc = vou->osd + AUX_GL_CSC_OFFSET;
566 		zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
567 		zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
568 		zplane->bits = &zx_gl_bits[1];
569 		zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
570 		zcrtc->chncsc = vou->osd + AUX_CHN_CSC_OFFSET;
571 		zcrtc->dither = vou->osd + AUX_DITHER_OFFSET;
572 		zcrtc->regs = &aux_crtc_regs;
573 		zcrtc->bits = &aux_crtc_bits;
574 	}
575 
576 	zcrtc->pixclk = devm_clk_get(dev, (chn_type == VOU_CHN_MAIN) ?
577 					  "main_wclk" : "aux_wclk");
578 	if (IS_ERR(zcrtc->pixclk)) {
579 		ret = PTR_ERR(zcrtc->pixclk);
580 		DRM_DEV_ERROR(dev, "failed to get pix clk: %d\n", ret);
581 		return ret;
582 	}
583 
584 	ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_PRIMARY);
585 	if (ret) {
586 		DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret);
587 		return ret;
588 	}
589 
590 	zcrtc->primary = &zplane->plane;
591 
592 	ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL,
593 					&zx_crtc_funcs, NULL);
594 	if (ret) {
595 		DRM_DEV_ERROR(dev, "failed to init drm crtc: %d\n", ret);
596 		return ret;
597 	}
598 
599 	drm_crtc_helper_add(&zcrtc->crtc, &zx_crtc_helper_funcs);
600 
601 	if (chn_type == VOU_CHN_MAIN)
602 		vou->main_crtc = zcrtc;
603 	else
604 		vou->aux_crtc = zcrtc;
605 
606 	return 0;
607 }
608 
zx_vou_layer_enable(struct drm_plane * plane)609 void zx_vou_layer_enable(struct drm_plane *plane)
610 {
611 	struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc);
612 	struct zx_vou_hw *vou = zcrtc->vou;
613 	struct zx_plane *zplane = to_zx_plane(plane);
614 	const struct vou_layer_bits *bits = zplane->bits;
615 
616 	if (zcrtc->chn_type == VOU_CHN_MAIN) {
617 		zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0);
618 		zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0);
619 	} else {
620 		zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel,
621 			       bits->chnsel);
622 		zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel,
623 			       bits->clksel);
624 	}
625 
626 	zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
627 }
628 
zx_vou_layer_disable(struct drm_plane * plane,struct drm_plane_state * old_state)629 void zx_vou_layer_disable(struct drm_plane *plane,
630 			  struct drm_plane_state *old_state)
631 {
632 	struct zx_crtc *zcrtc = to_zx_crtc(old_state->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 
zx_overlay_init(struct drm_device * drm,struct zx_vou_hw * vou)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 
zx_osd_int_update(struct zx_crtc * zcrtc)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 
vou_irq_handler(int irq,void * dev_id)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 
vou_dtrc_init(struct zx_vou_hw * vou)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 
vou_hw_init(struct zx_vou_hw * vou)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 
zx_crtc_bind(struct device * dev,struct device * master,void * data)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 
zx_crtc_unbind(struct device * dev,struct device * master,void * data)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 
zx_crtc_probe(struct platform_device * pdev)897 static int zx_crtc_probe(struct platform_device *pdev)
898 {
899 	return component_add(&pdev->dev, &zx_crtc_component_ops);
900 }
901 
zx_crtc_remove(struct platform_device * pdev)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 };
922