1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2014 MediaTek Inc.
4 * Author: Jie Qiu <jie.qiu@mediatek.com>
5 */
6
7#include <linux/clk.h>
8#include <linux/component.h>
9#include <linux/interrupt.h>
10#include <linux/kernel.h>
11#include <linux/media-bus-format.h>
12#include <linux/of.h>
13#include <linux/of_graph.h>
14#include <linux/pinctrl/consumer.h>
15#include <linux/platform_device.h>
16#include <linux/soc/mediatek/mtk-mmsys.h>
17#include <linux/types.h>
18
19#include <video/videomode.h>
20
21#include <drm/drm_atomic_helper.h>
22#include <drm/drm_bridge.h>
23#include <drm/drm_bridge_connector.h>
24#include <drm/drm_crtc.h>
25#include <drm/drm_edid.h>
26#include <drm/drm_of.h>
27#include <drm/drm_simple_kms_helper.h>
28
29#include "mtk_disp_drv.h"
30#include "mtk_dpi_regs.h"
31#include "mtk_drm_ddp_comp.h"
32#include "mtk_drm_drv.h"
33
34enum mtk_dpi_out_bit_num {
35	MTK_DPI_OUT_BIT_NUM_8BITS,
36	MTK_DPI_OUT_BIT_NUM_10BITS,
37	MTK_DPI_OUT_BIT_NUM_12BITS,
38	MTK_DPI_OUT_BIT_NUM_16BITS
39};
40
41enum mtk_dpi_out_yc_map {
42	MTK_DPI_OUT_YC_MAP_RGB,
43	MTK_DPI_OUT_YC_MAP_CYCY,
44	MTK_DPI_OUT_YC_MAP_YCYC,
45	MTK_DPI_OUT_YC_MAP_CY,
46	MTK_DPI_OUT_YC_MAP_YC
47};
48
49enum mtk_dpi_out_channel_swap {
50	MTK_DPI_OUT_CHANNEL_SWAP_RGB,
51	MTK_DPI_OUT_CHANNEL_SWAP_GBR,
52	MTK_DPI_OUT_CHANNEL_SWAP_BRG,
53	MTK_DPI_OUT_CHANNEL_SWAP_RBG,
54	MTK_DPI_OUT_CHANNEL_SWAP_GRB,
55	MTK_DPI_OUT_CHANNEL_SWAP_BGR
56};
57
58enum mtk_dpi_out_color_format {
59	MTK_DPI_COLOR_FORMAT_RGB,
60	MTK_DPI_COLOR_FORMAT_YCBCR_422
61};
62
63struct mtk_dpi {
64	struct drm_encoder encoder;
65	struct drm_bridge bridge;
66	struct drm_bridge *next_bridge;
67	struct drm_connector *connector;
68	void __iomem *regs;
69	struct device *dev;
70	struct device *mmsys_dev;
71	struct clk *engine_clk;
72	struct clk *pixel_clk;
73	struct clk *tvd_clk;
74	int irq;
75	struct drm_display_mode mode;
76	const struct mtk_dpi_conf *conf;
77	enum mtk_dpi_out_color_format color_format;
78	enum mtk_dpi_out_yc_map yc_map;
79	enum mtk_dpi_out_bit_num bit_num;
80	enum mtk_dpi_out_channel_swap channel_swap;
81	struct pinctrl *pinctrl;
82	struct pinctrl_state *pins_gpio;
83	struct pinctrl_state *pins_dpi;
84	u32 output_fmt;
85	int refcount;
86};
87
88static inline struct mtk_dpi *bridge_to_dpi(struct drm_bridge *b)
89{
90	return container_of(b, struct mtk_dpi, bridge);
91}
92
93enum mtk_dpi_polarity {
94	MTK_DPI_POLARITY_RISING,
95	MTK_DPI_POLARITY_FALLING,
96};
97
98struct mtk_dpi_polarities {
99	enum mtk_dpi_polarity de_pol;
100	enum mtk_dpi_polarity ck_pol;
101	enum mtk_dpi_polarity hsync_pol;
102	enum mtk_dpi_polarity vsync_pol;
103};
104
105struct mtk_dpi_sync_param {
106	u32 sync_width;
107	u32 front_porch;
108	u32 back_porch;
109	bool shift_half_line;
110};
111
112struct mtk_dpi_yc_limit {
113	u16 y_top;
114	u16 y_bottom;
115	u16 c_top;
116	u16 c_bottom;
117};
118
119/**
120 * struct mtk_dpi_conf - Configuration of mediatek dpi.
121 * @cal_factor: Callback function to calculate factor value.
122 * @reg_h_fre_con: Register address of frequency control.
123 * @max_clock_khz: Max clock frequency supported for this SoCs in khz units.
124 * @edge_sel_en: Enable of edge selection.
125 * @output_fmts: Array of supported output formats.
126 * @num_output_fmts: Quantity of supported output formats.
127 * @is_ck_de_pol: Support CK/DE polarity.
128 * @swap_input_support: Support input swap function.
129 * @support_direct_pin: IP supports direct connection to dpi panels.
130 * @input_2pixel: Input pixel of dp_intf is 2 pixel per round, so enable this
131 *		  config to enable this feature.
132 * @dimension_mask: Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH
133 *		    (no shift).
134 * @hvsize_mask: Mask of HSIZE and VSIZE mask (no shift).
135 * @channel_swap_shift: Shift value of channel swap.
136 * @yuv422_en_bit: Enable bit of yuv422.
137 * @csc_enable_bit: Enable bit of CSC.
138 * @pixels_per_iter: Quantity of transferred pixels per iteration.
139 * @edge_cfg_in_mmsys: If the edge configuration for DPI's output needs to be set in MMSYS.
140 */
141struct mtk_dpi_conf {
142	unsigned int (*cal_factor)(int clock);
143	u32 reg_h_fre_con;
144	u32 max_clock_khz;
145	bool edge_sel_en;
146	const u32 *output_fmts;
147	u32 num_output_fmts;
148	bool is_ck_de_pol;
149	bool swap_input_support;
150	bool support_direct_pin;
151	bool input_2pixel;
152	u32 dimension_mask;
153	u32 hvsize_mask;
154	u32 channel_swap_shift;
155	u32 yuv422_en_bit;
156	u32 csc_enable_bit;
157	u32 pixels_per_iter;
158	bool edge_cfg_in_mmsys;
159};
160
161static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
162{
163	u32 tmp = readl(dpi->regs + offset) & ~mask;
164
165	tmp |= (val & mask);
166	writel(tmp, dpi->regs + offset);
167}
168
169static void mtk_dpi_sw_reset(struct mtk_dpi *dpi, bool reset)
170{
171	mtk_dpi_mask(dpi, DPI_RET, reset ? RST : 0, RST);
172}
173
174static void mtk_dpi_enable(struct mtk_dpi *dpi)
175{
176	mtk_dpi_mask(dpi, DPI_EN, EN, EN);
177}
178
179static void mtk_dpi_disable(struct mtk_dpi *dpi)
180{
181	mtk_dpi_mask(dpi, DPI_EN, 0, EN);
182}
183
184static void mtk_dpi_config_hsync(struct mtk_dpi *dpi,
185				 struct mtk_dpi_sync_param *sync)
186{
187	mtk_dpi_mask(dpi, DPI_TGEN_HWIDTH, sync->sync_width << HPW,
188		     dpi->conf->dimension_mask << HPW);
189	mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->back_porch << HBP,
190		     dpi->conf->dimension_mask << HBP);
191	mtk_dpi_mask(dpi, DPI_TGEN_HPORCH, sync->front_porch << HFP,
192		     dpi->conf->dimension_mask << HFP);
193}
194
195static void mtk_dpi_config_vsync(struct mtk_dpi *dpi,
196				 struct mtk_dpi_sync_param *sync,
197				 u32 width_addr, u32 porch_addr)
198{
199	mtk_dpi_mask(dpi, width_addr,
200		     sync->shift_half_line << VSYNC_HALF_LINE_SHIFT,
201		     VSYNC_HALF_LINE_MASK);
202	mtk_dpi_mask(dpi, width_addr,
203		     sync->sync_width << VSYNC_WIDTH_SHIFT,
204		     dpi->conf->dimension_mask << VSYNC_WIDTH_SHIFT);
205	mtk_dpi_mask(dpi, porch_addr,
206		     sync->back_porch << VSYNC_BACK_PORCH_SHIFT,
207		     dpi->conf->dimension_mask << VSYNC_BACK_PORCH_SHIFT);
208	mtk_dpi_mask(dpi, porch_addr,
209		     sync->front_porch << VSYNC_FRONT_PORCH_SHIFT,
210		     dpi->conf->dimension_mask << VSYNC_FRONT_PORCH_SHIFT);
211}
212
213static void mtk_dpi_config_vsync_lodd(struct mtk_dpi *dpi,
214				      struct mtk_dpi_sync_param *sync)
215{
216	mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH, DPI_TGEN_VPORCH);
217}
218
219static void mtk_dpi_config_vsync_leven(struct mtk_dpi *dpi,
220				       struct mtk_dpi_sync_param *sync)
221{
222	mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_LEVEN,
223			     DPI_TGEN_VPORCH_LEVEN);
224}
225
226static void mtk_dpi_config_vsync_rodd(struct mtk_dpi *dpi,
227				      struct mtk_dpi_sync_param *sync)
228{
229	mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_RODD,
230			     DPI_TGEN_VPORCH_RODD);
231}
232
233static void mtk_dpi_config_vsync_reven(struct mtk_dpi *dpi,
234				       struct mtk_dpi_sync_param *sync)
235{
236	mtk_dpi_config_vsync(dpi, sync, DPI_TGEN_VWIDTH_REVEN,
237			     DPI_TGEN_VPORCH_REVEN);
238}
239
240static void mtk_dpi_config_pol(struct mtk_dpi *dpi,
241			       struct mtk_dpi_polarities *dpi_pol)
242{
243	unsigned int pol;
244	unsigned int mask;
245
246	mask = HSYNC_POL | VSYNC_POL;
247	pol = (dpi_pol->hsync_pol == MTK_DPI_POLARITY_RISING ? 0 : HSYNC_POL) |
248	      (dpi_pol->vsync_pol == MTK_DPI_POLARITY_RISING ? 0 : VSYNC_POL);
249	if (dpi->conf->is_ck_de_pol) {
250		mask |= CK_POL | DE_POL;
251		pol |= (dpi_pol->ck_pol == MTK_DPI_POLARITY_RISING ?
252			0 : CK_POL) |
253		       (dpi_pol->de_pol == MTK_DPI_POLARITY_RISING ?
254			0 : DE_POL);
255	}
256
257	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, pol, mask);
258}
259
260static void mtk_dpi_config_3d(struct mtk_dpi *dpi, bool en_3d)
261{
262	mtk_dpi_mask(dpi, DPI_CON, en_3d ? TDFP_EN : 0, TDFP_EN);
263}
264
265static void mtk_dpi_config_interface(struct mtk_dpi *dpi, bool inter)
266{
267	mtk_dpi_mask(dpi, DPI_CON, inter ? INTL_EN : 0, INTL_EN);
268}
269
270static void mtk_dpi_config_fb_size(struct mtk_dpi *dpi, u32 width, u32 height)
271{
272	mtk_dpi_mask(dpi, DPI_SIZE, width << HSIZE,
273		     dpi->conf->hvsize_mask << HSIZE);
274	mtk_dpi_mask(dpi, DPI_SIZE, height << VSIZE,
275		     dpi->conf->hvsize_mask << VSIZE);
276}
277
278static void mtk_dpi_config_channel_limit(struct mtk_dpi *dpi)
279{
280	struct mtk_dpi_yc_limit limit;
281
282	if (drm_default_rgb_quant_range(&dpi->mode) ==
283	    HDMI_QUANTIZATION_RANGE_LIMITED) {
284		limit.y_bottom = 0x10;
285		limit.y_top = 0xfe0;
286		limit.c_bottom = 0x10;
287		limit.c_top = 0xfe0;
288	} else {
289		limit.y_bottom = 0;
290		limit.y_top = 0xfff;
291		limit.c_bottom = 0;
292		limit.c_top = 0xfff;
293	}
294
295	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit.y_bottom << Y_LIMINT_BOT,
296		     Y_LIMINT_BOT_MASK);
297	mtk_dpi_mask(dpi, DPI_Y_LIMIT, limit.y_top << Y_LIMINT_TOP,
298		     Y_LIMINT_TOP_MASK);
299	mtk_dpi_mask(dpi, DPI_C_LIMIT, limit.c_bottom << C_LIMIT_BOT,
300		     C_LIMIT_BOT_MASK);
301	mtk_dpi_mask(dpi, DPI_C_LIMIT, limit.c_top << C_LIMIT_TOP,
302		     C_LIMIT_TOP_MASK);
303}
304
305static void mtk_dpi_config_bit_num(struct mtk_dpi *dpi,
306				   enum mtk_dpi_out_bit_num num)
307{
308	u32 val;
309
310	switch (num) {
311	case MTK_DPI_OUT_BIT_NUM_8BITS:
312		val = OUT_BIT_8;
313		break;
314	case MTK_DPI_OUT_BIT_NUM_10BITS:
315		val = OUT_BIT_10;
316		break;
317	case MTK_DPI_OUT_BIT_NUM_12BITS:
318		val = OUT_BIT_12;
319		break;
320	case MTK_DPI_OUT_BIT_NUM_16BITS:
321		val = OUT_BIT_16;
322		break;
323	default:
324		val = OUT_BIT_8;
325		break;
326	}
327	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << OUT_BIT,
328		     OUT_BIT_MASK);
329}
330
331static void mtk_dpi_config_yc_map(struct mtk_dpi *dpi,
332				  enum mtk_dpi_out_yc_map map)
333{
334	u32 val;
335
336	switch (map) {
337	case MTK_DPI_OUT_YC_MAP_RGB:
338		val = YC_MAP_RGB;
339		break;
340	case MTK_DPI_OUT_YC_MAP_CYCY:
341		val = YC_MAP_CYCY;
342		break;
343	case MTK_DPI_OUT_YC_MAP_YCYC:
344		val = YC_MAP_YCYC;
345		break;
346	case MTK_DPI_OUT_YC_MAP_CY:
347		val = YC_MAP_CY;
348		break;
349	case MTK_DPI_OUT_YC_MAP_YC:
350		val = YC_MAP_YC;
351		break;
352	default:
353		val = YC_MAP_RGB;
354		break;
355	}
356
357	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, val << YC_MAP, YC_MAP_MASK);
358}
359
360static void mtk_dpi_config_channel_swap(struct mtk_dpi *dpi,
361					enum mtk_dpi_out_channel_swap swap)
362{
363	u32 val;
364
365	switch (swap) {
366	case MTK_DPI_OUT_CHANNEL_SWAP_RGB:
367		val = SWAP_RGB;
368		break;
369	case MTK_DPI_OUT_CHANNEL_SWAP_GBR:
370		val = SWAP_GBR;
371		break;
372	case MTK_DPI_OUT_CHANNEL_SWAP_BRG:
373		val = SWAP_BRG;
374		break;
375	case MTK_DPI_OUT_CHANNEL_SWAP_RBG:
376		val = SWAP_RBG;
377		break;
378	case MTK_DPI_OUT_CHANNEL_SWAP_GRB:
379		val = SWAP_GRB;
380		break;
381	case MTK_DPI_OUT_CHANNEL_SWAP_BGR:
382		val = SWAP_BGR;
383		break;
384	default:
385		val = SWAP_RGB;
386		break;
387	}
388
389	mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
390		     val << dpi->conf->channel_swap_shift,
391		     CH_SWAP_MASK << dpi->conf->channel_swap_shift);
392}
393
394static void mtk_dpi_config_yuv422_enable(struct mtk_dpi *dpi, bool enable)
395{
396	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->yuv422_en_bit : 0,
397		     dpi->conf->yuv422_en_bit);
398}
399
400static void mtk_dpi_config_csc_enable(struct mtk_dpi *dpi, bool enable)
401{
402	mtk_dpi_mask(dpi, DPI_CON, enable ? dpi->conf->csc_enable_bit : 0,
403		     dpi->conf->csc_enable_bit);
404}
405
406static void mtk_dpi_config_swap_input(struct mtk_dpi *dpi, bool enable)
407{
408	mtk_dpi_mask(dpi, DPI_CON, enable ? IN_RB_SWAP : 0, IN_RB_SWAP);
409}
410
411static void mtk_dpi_config_2n_h_fre(struct mtk_dpi *dpi)
412{
413	mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, H_FRE_2N, H_FRE_2N);
414}
415
416static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
417{
418	if (dpi->conf->edge_sel_en)
419		mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
420}
421
422static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
423					enum mtk_dpi_out_color_format format)
424{
425	mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
426
427	if (format == MTK_DPI_COLOR_FORMAT_YCBCR_422) {
428		mtk_dpi_config_yuv422_enable(dpi, true);
429		mtk_dpi_config_csc_enable(dpi, true);
430
431		/*
432		 * If height is smaller than 720, we need to use RGB_TO_BT601
433		 * to transfer to yuv422. Otherwise, we use RGB_TO_JPEG.
434		 */
435		mtk_dpi_mask(dpi, DPI_MATRIX_SET, dpi->mode.hdisplay <= 720 ?
436			     MATRIX_SEL_RGB_TO_BT601 : MATRIX_SEL_RGB_TO_JPEG,
437			     INT_MATRIX_SEL_MASK);
438	} else {
439		mtk_dpi_config_yuv422_enable(dpi, false);
440		mtk_dpi_config_csc_enable(dpi, false);
441		if (dpi->conf->swap_input_support)
442			mtk_dpi_config_swap_input(dpi, false);
443	}
444}
445
446static void mtk_dpi_dual_edge(struct mtk_dpi *dpi)
447{
448	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
449	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE)) {
450		mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE,
451			     DDR_EN | DDR_4PHASE);
452		mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING,
453			     dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE ?
454			     EDGE_SEL : 0, EDGE_SEL);
455		if (dpi->conf->edge_cfg_in_mmsys)
456			mtk_mmsys_ddp_dpi_fmt_config(dpi->mmsys_dev, MTK_DPI_RGB888_DDR_CON);
457	} else {
458		mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE, 0);
459		if (dpi->conf->edge_cfg_in_mmsys)
460			mtk_mmsys_ddp_dpi_fmt_config(dpi->mmsys_dev, MTK_DPI_RGB888_SDR_CON);
461	}
462}
463
464static void mtk_dpi_power_off(struct mtk_dpi *dpi)
465{
466	if (WARN_ON(dpi->refcount == 0))
467		return;
468
469	if (--dpi->refcount != 0)
470		return;
471
472	mtk_dpi_disable(dpi);
473	clk_disable_unprepare(dpi->pixel_clk);
474	clk_disable_unprepare(dpi->engine_clk);
475}
476
477static int mtk_dpi_power_on(struct mtk_dpi *dpi)
478{
479	int ret;
480
481	if (++dpi->refcount != 1)
482		return 0;
483
484	ret = clk_prepare_enable(dpi->engine_clk);
485	if (ret) {
486		dev_err(dpi->dev, "Failed to enable engine clock: %d\n", ret);
487		goto err_refcount;
488	}
489
490	ret = clk_prepare_enable(dpi->pixel_clk);
491	if (ret) {
492		dev_err(dpi->dev, "Failed to enable pixel clock: %d\n", ret);
493		goto err_pixel;
494	}
495
496	return 0;
497
498err_pixel:
499	clk_disable_unprepare(dpi->engine_clk);
500err_refcount:
501	dpi->refcount--;
502	return ret;
503}
504
505static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
506				    struct drm_display_mode *mode)
507{
508	struct mtk_dpi_polarities dpi_pol;
509	struct mtk_dpi_sync_param hsync;
510	struct mtk_dpi_sync_param vsync_lodd = { 0 };
511	struct mtk_dpi_sync_param vsync_leven = { 0 };
512	struct mtk_dpi_sync_param vsync_rodd = { 0 };
513	struct mtk_dpi_sync_param vsync_reven = { 0 };
514	struct videomode vm = { 0 };
515	unsigned long pll_rate;
516	unsigned int factor;
517
518	/* let pll_rate can fix the valid range of tvdpll (1G~2GHz) */
519	factor = dpi->conf->cal_factor(mode->clock);
520	drm_display_mode_to_videomode(mode, &vm);
521	pll_rate = vm.pixelclock * factor;
522
523	dev_dbg(dpi->dev, "Want PLL %lu Hz, pixel clock %lu Hz\n",
524		pll_rate, vm.pixelclock);
525
526	clk_set_rate(dpi->tvd_clk, pll_rate);
527	pll_rate = clk_get_rate(dpi->tvd_clk);
528
529	/*
530	 * Depending on the IP version, we may output a different amount of
531	 * pixels for each iteration: divide the clock by this number and
532	 * adjust the display porches accordingly.
533	 */
534	vm.pixelclock = pll_rate / factor;
535	vm.pixelclock /= dpi->conf->pixels_per_iter;
536
537	if ((dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_LE) ||
538	    (dpi->output_fmt == MEDIA_BUS_FMT_RGB888_2X12_BE))
539		clk_set_rate(dpi->pixel_clk, vm.pixelclock * 2);
540	else
541		clk_set_rate(dpi->pixel_clk, vm.pixelclock);
542
543
544	vm.pixelclock = clk_get_rate(dpi->pixel_clk);
545
546	dev_dbg(dpi->dev, "Got  PLL %lu Hz, pixel clock %lu Hz\n",
547		pll_rate, vm.pixelclock);
548
549	dpi_pol.ck_pol = MTK_DPI_POLARITY_FALLING;
550	dpi_pol.de_pol = MTK_DPI_POLARITY_RISING;
551	dpi_pol.hsync_pol = vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ?
552			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
553	dpi_pol.vsync_pol = vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ?
554			    MTK_DPI_POLARITY_FALLING : MTK_DPI_POLARITY_RISING;
555
556	/*
557	 * Depending on the IP version, we may output a different amount of
558	 * pixels for each iteration: divide the clock by this number and
559	 * adjust the display porches accordingly.
560	 */
561	hsync.sync_width = vm.hsync_len / dpi->conf->pixels_per_iter;
562	hsync.back_porch = vm.hback_porch / dpi->conf->pixels_per_iter;
563	hsync.front_porch = vm.hfront_porch / dpi->conf->pixels_per_iter;
564
565	hsync.shift_half_line = false;
566	vsync_lodd.sync_width = vm.vsync_len;
567	vsync_lodd.back_porch = vm.vback_porch;
568	vsync_lodd.front_porch = vm.vfront_porch;
569	vsync_lodd.shift_half_line = false;
570
571	if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
572	    mode->flags & DRM_MODE_FLAG_3D_MASK) {
573		vsync_leven = vsync_lodd;
574		vsync_rodd = vsync_lodd;
575		vsync_reven = vsync_lodd;
576		vsync_leven.shift_half_line = true;
577		vsync_reven.shift_half_line = true;
578	} else if (vm.flags & DISPLAY_FLAGS_INTERLACED &&
579		   !(mode->flags & DRM_MODE_FLAG_3D_MASK)) {
580		vsync_leven = vsync_lodd;
581		vsync_leven.shift_half_line = true;
582	} else if (!(vm.flags & DISPLAY_FLAGS_INTERLACED) &&
583		   mode->flags & DRM_MODE_FLAG_3D_MASK) {
584		vsync_rodd = vsync_lodd;
585	}
586	mtk_dpi_sw_reset(dpi, true);
587	mtk_dpi_config_pol(dpi, &dpi_pol);
588
589	mtk_dpi_config_hsync(dpi, &hsync);
590	mtk_dpi_config_vsync_lodd(dpi, &vsync_lodd);
591	mtk_dpi_config_vsync_rodd(dpi, &vsync_rodd);
592	mtk_dpi_config_vsync_leven(dpi, &vsync_leven);
593	mtk_dpi_config_vsync_reven(dpi, &vsync_reven);
594
595	mtk_dpi_config_3d(dpi, !!(mode->flags & DRM_MODE_FLAG_3D_MASK));
596	mtk_dpi_config_interface(dpi, !!(vm.flags &
597					 DISPLAY_FLAGS_INTERLACED));
598	if (vm.flags & DISPLAY_FLAGS_INTERLACED)
599		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive >> 1);
600	else
601		mtk_dpi_config_fb_size(dpi, vm.hactive, vm.vactive);
602
603	mtk_dpi_config_channel_limit(dpi);
604	mtk_dpi_config_bit_num(dpi, dpi->bit_num);
605	mtk_dpi_config_channel_swap(dpi, dpi->channel_swap);
606	mtk_dpi_config_color_format(dpi, dpi->color_format);
607	if (dpi->conf->support_direct_pin) {
608		mtk_dpi_config_yc_map(dpi, dpi->yc_map);
609		mtk_dpi_config_2n_h_fre(dpi);
610		mtk_dpi_dual_edge(dpi);
611		mtk_dpi_config_disable_edge(dpi);
612	}
613	if (dpi->conf->input_2pixel) {
614		mtk_dpi_mask(dpi, DPI_CON, DPINTF_INPUT_2P_EN,
615			     DPINTF_INPUT_2P_EN);
616	}
617	mtk_dpi_sw_reset(dpi, false);
618
619	return 0;
620}
621
622static u32 *mtk_dpi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
623						      struct drm_bridge_state *bridge_state,
624						      struct drm_crtc_state *crtc_state,
625						      struct drm_connector_state *conn_state,
626						      unsigned int *num_output_fmts)
627{
628	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
629	u32 *output_fmts;
630
631	*num_output_fmts = 0;
632
633	if (!dpi->conf->output_fmts) {
634		dev_err(dpi->dev, "output_fmts should not be null\n");
635		return NULL;
636	}
637
638	output_fmts = kcalloc(dpi->conf->num_output_fmts, sizeof(*output_fmts),
639			     GFP_KERNEL);
640	if (!output_fmts)
641		return NULL;
642
643	*num_output_fmts = dpi->conf->num_output_fmts;
644
645	memcpy(output_fmts, dpi->conf->output_fmts,
646	       sizeof(*output_fmts) * dpi->conf->num_output_fmts);
647
648	return output_fmts;
649}
650
651static u32 *mtk_dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
652						     struct drm_bridge_state *bridge_state,
653						     struct drm_crtc_state *crtc_state,
654						     struct drm_connector_state *conn_state,
655						     u32 output_fmt,
656						     unsigned int *num_input_fmts)
657{
658	u32 *input_fmts;
659
660	*num_input_fmts = 0;
661
662	input_fmts = kcalloc(1, sizeof(*input_fmts),
663			     GFP_KERNEL);
664	if (!input_fmts)
665		return NULL;
666
667	*num_input_fmts = 1;
668	input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
669
670	return input_fmts;
671}
672
673static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
674				       struct drm_bridge_state *bridge_state,
675				       struct drm_crtc_state *crtc_state,
676				       struct drm_connector_state *conn_state)
677{
678	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
679	unsigned int out_bus_format;
680
681	out_bus_format = bridge_state->output_bus_cfg.format;
682
683	if (out_bus_format == MEDIA_BUS_FMT_FIXED)
684		if (dpi->conf->num_output_fmts)
685			out_bus_format = dpi->conf->output_fmts[0];
686
687	dev_dbg(dpi->dev, "input format 0x%04x, output format 0x%04x\n",
688		bridge_state->input_bus_cfg.format,
689		bridge_state->output_bus_cfg.format);
690
691	dpi->output_fmt = out_bus_format;
692	dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
693	dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
694	dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
695	if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
696		dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422;
697	else
698		dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
699
700	return 0;
701}
702
703static int mtk_dpi_bridge_attach(struct drm_bridge *bridge,
704				 enum drm_bridge_attach_flags flags)
705{
706	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
707
708	return drm_bridge_attach(bridge->encoder, dpi->next_bridge,
709				 &dpi->bridge, flags);
710}
711
712static void mtk_dpi_bridge_mode_set(struct drm_bridge *bridge,
713				const struct drm_display_mode *mode,
714				const struct drm_display_mode *adjusted_mode)
715{
716	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
717
718	drm_mode_copy(&dpi->mode, adjusted_mode);
719}
720
721static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
722{
723	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
724
725	mtk_dpi_power_off(dpi);
726
727	if (dpi->pinctrl && dpi->pins_gpio)
728		pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
729}
730
731static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
732{
733	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
734
735	if (dpi->pinctrl && dpi->pins_dpi)
736		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
737
738	mtk_dpi_power_on(dpi);
739	mtk_dpi_set_display_mode(dpi, &dpi->mode);
740	mtk_dpi_enable(dpi);
741}
742
743static enum drm_mode_status
744mtk_dpi_bridge_mode_valid(struct drm_bridge *bridge,
745			  const struct drm_display_info *info,
746			  const struct drm_display_mode *mode)
747{
748	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
749
750	if (mode->clock > dpi->conf->max_clock_khz)
751		return MODE_CLOCK_HIGH;
752
753	return MODE_OK;
754}
755
756static const struct drm_bridge_funcs mtk_dpi_bridge_funcs = {
757	.attach = mtk_dpi_bridge_attach,
758	.mode_set = mtk_dpi_bridge_mode_set,
759	.mode_valid = mtk_dpi_bridge_mode_valid,
760	.disable = mtk_dpi_bridge_disable,
761	.enable = mtk_dpi_bridge_enable,
762	.atomic_check = mtk_dpi_bridge_atomic_check,
763	.atomic_get_output_bus_fmts = mtk_dpi_bridge_atomic_get_output_bus_fmts,
764	.atomic_get_input_bus_fmts = mtk_dpi_bridge_atomic_get_input_bus_fmts,
765	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
766	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
767	.atomic_reset = drm_atomic_helper_bridge_reset,
768};
769
770void mtk_dpi_start(struct device *dev)
771{
772	struct mtk_dpi *dpi = dev_get_drvdata(dev);
773
774	mtk_dpi_power_on(dpi);
775}
776
777void mtk_dpi_stop(struct device *dev)
778{
779	struct mtk_dpi *dpi = dev_get_drvdata(dev);
780
781	mtk_dpi_power_off(dpi);
782}
783
784static int mtk_dpi_bind(struct device *dev, struct device *master, void *data)
785{
786	struct mtk_dpi *dpi = dev_get_drvdata(dev);
787	struct drm_device *drm_dev = data;
788	struct mtk_drm_private *priv = drm_dev->dev_private;
789	int ret;
790
791	dpi->mmsys_dev = priv->mmsys_dev;
792	ret = drm_simple_encoder_init(drm_dev, &dpi->encoder,
793				      DRM_MODE_ENCODER_TMDS);
794	if (ret) {
795		dev_err(dev, "Failed to initialize decoder: %d\n", ret);
796		return ret;
797	}
798
799	dpi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm_dev, dpi->dev);
800
801	ret = drm_bridge_attach(&dpi->encoder, &dpi->bridge, NULL,
802				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
803	if (ret)
804		goto err_cleanup;
805
806	dpi->connector = drm_bridge_connector_init(drm_dev, &dpi->encoder);
807	if (IS_ERR(dpi->connector)) {
808		dev_err(dev, "Unable to create bridge connector\n");
809		ret = PTR_ERR(dpi->connector);
810		goto err_cleanup;
811	}
812	drm_connector_attach_encoder(dpi->connector, &dpi->encoder);
813
814	return 0;
815
816err_cleanup:
817	drm_encoder_cleanup(&dpi->encoder);
818	return ret;
819}
820
821static void mtk_dpi_unbind(struct device *dev, struct device *master,
822			   void *data)
823{
824	struct mtk_dpi *dpi = dev_get_drvdata(dev);
825
826	drm_encoder_cleanup(&dpi->encoder);
827}
828
829static const struct component_ops mtk_dpi_component_ops = {
830	.bind = mtk_dpi_bind,
831	.unbind = mtk_dpi_unbind,
832};
833
834static unsigned int mt8173_calculate_factor(int clock)
835{
836	if (clock <= 27000)
837		return 3 << 4;
838	else if (clock <= 84000)
839		return 3 << 3;
840	else if (clock <= 167000)
841		return 3 << 2;
842	else
843		return 3 << 1;
844}
845
846static unsigned int mt2701_calculate_factor(int clock)
847{
848	if (clock <= 64000)
849		return 4;
850	else if (clock <= 128000)
851		return 2;
852	else
853		return 1;
854}
855
856static unsigned int mt8183_calculate_factor(int clock)
857{
858	if (clock <= 27000)
859		return 8;
860	else if (clock <= 167000)
861		return 4;
862	else
863		return 2;
864}
865
866static unsigned int mt8195_dpintf_calculate_factor(int clock)
867{
868	if (clock < 70000)
869		return 4;
870	else if (clock < 200000)
871		return 2;
872	else
873		return 1;
874}
875
876static const u32 mt8173_output_fmts[] = {
877	MEDIA_BUS_FMT_RGB888_1X24,
878};
879
880static const u32 mt8183_output_fmts[] = {
881	MEDIA_BUS_FMT_RGB888_2X12_LE,
882	MEDIA_BUS_FMT_RGB888_2X12_BE,
883};
884
885static const u32 mt8195_output_fmts[] = {
886	MEDIA_BUS_FMT_RGB888_1X24,
887	MEDIA_BUS_FMT_YUYV8_1X16,
888};
889
890static const struct mtk_dpi_conf mt8173_conf = {
891	.cal_factor = mt8173_calculate_factor,
892	.reg_h_fre_con = 0xe0,
893	.max_clock_khz = 300000,
894	.output_fmts = mt8173_output_fmts,
895	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
896	.pixels_per_iter = 1,
897	.is_ck_de_pol = true,
898	.swap_input_support = true,
899	.support_direct_pin = true,
900	.dimension_mask = HPW_MASK,
901	.hvsize_mask = HSIZE_MASK,
902	.channel_swap_shift = CH_SWAP,
903	.yuv422_en_bit = YUV422_EN,
904	.csc_enable_bit = CSC_ENABLE,
905};
906
907static const struct mtk_dpi_conf mt2701_conf = {
908	.cal_factor = mt2701_calculate_factor,
909	.reg_h_fre_con = 0xb0,
910	.edge_sel_en = true,
911	.max_clock_khz = 150000,
912	.output_fmts = mt8173_output_fmts,
913	.num_output_fmts = ARRAY_SIZE(mt8173_output_fmts),
914	.pixels_per_iter = 1,
915	.is_ck_de_pol = true,
916	.swap_input_support = true,
917	.support_direct_pin = true,
918	.dimension_mask = HPW_MASK,
919	.hvsize_mask = HSIZE_MASK,
920	.channel_swap_shift = CH_SWAP,
921	.yuv422_en_bit = YUV422_EN,
922	.csc_enable_bit = CSC_ENABLE,
923};
924
925static const struct mtk_dpi_conf mt8183_conf = {
926	.cal_factor = mt8183_calculate_factor,
927	.reg_h_fre_con = 0xe0,
928	.max_clock_khz = 100000,
929	.output_fmts = mt8183_output_fmts,
930	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
931	.pixels_per_iter = 1,
932	.is_ck_de_pol = true,
933	.swap_input_support = true,
934	.support_direct_pin = true,
935	.dimension_mask = HPW_MASK,
936	.hvsize_mask = HSIZE_MASK,
937	.channel_swap_shift = CH_SWAP,
938	.yuv422_en_bit = YUV422_EN,
939	.csc_enable_bit = CSC_ENABLE,
940};
941
942static const struct mtk_dpi_conf mt8186_conf = {
943	.cal_factor = mt8183_calculate_factor,
944	.reg_h_fre_con = 0xe0,
945	.max_clock_khz = 150000,
946	.output_fmts = mt8183_output_fmts,
947	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
948	.edge_cfg_in_mmsys = true,
949	.pixels_per_iter = 1,
950	.is_ck_de_pol = true,
951	.swap_input_support = true,
952	.support_direct_pin = true,
953	.dimension_mask = HPW_MASK,
954	.hvsize_mask = HSIZE_MASK,
955	.channel_swap_shift = CH_SWAP,
956	.yuv422_en_bit = YUV422_EN,
957	.csc_enable_bit = CSC_ENABLE,
958};
959
960static const struct mtk_dpi_conf mt8192_conf = {
961	.cal_factor = mt8183_calculate_factor,
962	.reg_h_fre_con = 0xe0,
963	.max_clock_khz = 150000,
964	.output_fmts = mt8183_output_fmts,
965	.num_output_fmts = ARRAY_SIZE(mt8183_output_fmts),
966	.pixels_per_iter = 1,
967	.is_ck_de_pol = true,
968	.swap_input_support = true,
969	.support_direct_pin = true,
970	.dimension_mask = HPW_MASK,
971	.hvsize_mask = HSIZE_MASK,
972	.channel_swap_shift = CH_SWAP,
973	.yuv422_en_bit = YUV422_EN,
974	.csc_enable_bit = CSC_ENABLE,
975};
976
977static const struct mtk_dpi_conf mt8195_dpintf_conf = {
978	.cal_factor = mt8195_dpintf_calculate_factor,
979	.max_clock_khz = 600000,
980	.output_fmts = mt8195_output_fmts,
981	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
982	.pixels_per_iter = 4,
983	.input_2pixel = true,
984	.dimension_mask = DPINTF_HPW_MASK,
985	.hvsize_mask = DPINTF_HSIZE_MASK,
986	.channel_swap_shift = DPINTF_CH_SWAP,
987	.yuv422_en_bit = DPINTF_YUV422_EN,
988	.csc_enable_bit = DPINTF_CSC_ENABLE,
989};
990
991static int mtk_dpi_probe(struct platform_device *pdev)
992{
993	struct device *dev = &pdev->dev;
994	struct mtk_dpi *dpi;
995	int ret;
996
997	dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
998	if (!dpi)
999		return -ENOMEM;
1000
1001	dpi->dev = dev;
1002	dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev);
1003	dpi->output_fmt = MEDIA_BUS_FMT_RGB888_1X24;
1004
1005	dpi->pinctrl = devm_pinctrl_get(&pdev->dev);
1006	if (IS_ERR(dpi->pinctrl)) {
1007		dpi->pinctrl = NULL;
1008		dev_dbg(&pdev->dev, "Cannot find pinctrl!\n");
1009	}
1010	if (dpi->pinctrl) {
1011		dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "sleep");
1012		if (IS_ERR(dpi->pins_gpio)) {
1013			dpi->pins_gpio = NULL;
1014			dev_dbg(&pdev->dev, "Cannot find pinctrl idle!\n");
1015		}
1016		if (dpi->pins_gpio)
1017			pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
1018
1019		dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "default");
1020		if (IS_ERR(dpi->pins_dpi)) {
1021			dpi->pins_dpi = NULL;
1022			dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n");
1023		}
1024	}
1025	dpi->regs = devm_platform_ioremap_resource(pdev, 0);
1026	if (IS_ERR(dpi->regs))
1027		return dev_err_probe(dev, PTR_ERR(dpi->regs),
1028				     "Failed to ioremap mem resource\n");
1029
1030	dpi->engine_clk = devm_clk_get(dev, "engine");
1031	if (IS_ERR(dpi->engine_clk))
1032		return dev_err_probe(dev, PTR_ERR(dpi->engine_clk),
1033				     "Failed to get engine clock\n");
1034
1035	dpi->pixel_clk = devm_clk_get(dev, "pixel");
1036	if (IS_ERR(dpi->pixel_clk))
1037		return dev_err_probe(dev, PTR_ERR(dpi->pixel_clk),
1038				     "Failed to get pixel clock\n");
1039
1040	dpi->tvd_clk = devm_clk_get(dev, "pll");
1041	if (IS_ERR(dpi->tvd_clk))
1042		return dev_err_probe(dev, PTR_ERR(dpi->tvd_clk),
1043				     "Failed to get tvdpll clock\n");
1044
1045	dpi->irq = platform_get_irq(pdev, 0);
1046	if (dpi->irq < 0)
1047		return dpi->irq;
1048
1049	dpi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
1050	if (IS_ERR(dpi->next_bridge))
1051		return dev_err_probe(dev, PTR_ERR(dpi->next_bridge),
1052				     "Failed to get bridge\n");
1053
1054	dev_info(dev, "Found bridge node: %pOF\n", dpi->next_bridge->of_node);
1055
1056	platform_set_drvdata(pdev, dpi);
1057
1058	dpi->bridge.funcs = &mtk_dpi_bridge_funcs;
1059	dpi->bridge.of_node = dev->of_node;
1060	dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
1061
1062	ret = devm_drm_bridge_add(dev, &dpi->bridge);
1063	if (ret)
1064		return ret;
1065
1066	ret = component_add(dev, &mtk_dpi_component_ops);
1067	if (ret)
1068		return dev_err_probe(dev, ret, "Failed to add component.\n");
1069
1070	return 0;
1071}
1072
1073static void mtk_dpi_remove(struct platform_device *pdev)
1074{
1075	component_del(&pdev->dev, &mtk_dpi_component_ops);
1076}
1077
1078static const struct of_device_id mtk_dpi_of_ids[] = {
1079	{ .compatible = "mediatek,mt2701-dpi", .data = &mt2701_conf },
1080	{ .compatible = "mediatek,mt8173-dpi", .data = &mt8173_conf },
1081	{ .compatible = "mediatek,mt8183-dpi", .data = &mt8183_conf },
1082	{ .compatible = "mediatek,mt8186-dpi", .data = &mt8186_conf },
1083	{ .compatible = "mediatek,mt8188-dp-intf", .data = &mt8195_dpintf_conf },
1084	{ .compatible = "mediatek,mt8192-dpi", .data = &mt8192_conf },
1085	{ .compatible = "mediatek,mt8195-dp-intf", .data = &mt8195_dpintf_conf },
1086	{ /* sentinel */ },
1087};
1088MODULE_DEVICE_TABLE(of, mtk_dpi_of_ids);
1089
1090struct platform_driver mtk_dpi_driver = {
1091	.probe = mtk_dpi_probe,
1092	.remove_new = mtk_dpi_remove,
1093	.driver = {
1094		.name = "mediatek-dpi",
1095		.of_match_table = mtk_dpi_of_ids,
1096	},
1097};
1098