xref: /rk3399_rockchip-uboot/drivers/video/drm/rockchip_rgb.c (revision 9f3137bcc9ed4e72e95cdc680f8d3cd6aa636ee0)
19e02a86eSWyon Bi /*
29e02a86eSWyon Bi  * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd
39e02a86eSWyon Bi  *
49e02a86eSWyon Bi  * SPDX-License-Identifier:	GPL-2.0+
59e02a86eSWyon Bi  */
69e02a86eSWyon Bi 
79e02a86eSWyon Bi #include <common.h>
8cb17ca6cSSandy Huang #include <dm/of_access.h>
99e02a86eSWyon Bi #include <errno.h>
109e02a86eSWyon Bi #include <syscon.h>
119e02a86eSWyon Bi #include <regmap.h>
129e02a86eSWyon Bi #include <dm/device.h>
139e02a86eSWyon Bi #include <dm/read.h>
14350f6a18SWyon Bi #include <dm/pinctrl.h>
156b93bf2bSWyon Bi #include <linux/media-bus-format.h>
16b5dbb15aSDamon Ding #include <asm/gpio.h>
17b5dbb15aSDamon Ding #include <backlight.h>
189e02a86eSWyon Bi 
199e02a86eSWyon Bi #include "rockchip_display.h"
209e02a86eSWyon Bi #include "rockchip_crtc.h"
219e02a86eSWyon Bi #include "rockchip_connector.h"
2249627130SWyon Bi #include "rockchip_phy.h"
23b5dbb15aSDamon Ding #include "rockchip_panel.h"
249e02a86eSWyon Bi 
251953e619SWyon Bi #define HIWORD_UPDATE(v, h, l)		(((v) << (l)) | (GENMASK(h, l) << 16))
261953e619SWyon Bi 
279e02a86eSWyon Bi #define PX30_GRF_PD_VO_CON1		0x0438
286b9c0415SSandy Huang #define PX30_RGB_DATA_SYNC_BYPASS(v)	HIWORD_UPDATE(v, 3, 3)
299e02a86eSWyon Bi #define PX30_RGB_VOP_SEL(v)		HIWORD_UPDATE(v, 2, 2)
309e02a86eSWyon Bi 
316b9c0415SSandy Huang #define RK1808_GRF_PD_VO_CON1		0x0444
326b9c0415SSandy Huang #define RK1808_RGB_DATA_SYNC_BYPASS(v)	HIWORD_UPDATE(v, 3, 3)
336b9c0415SSandy Huang 
34e8dd2b64SDamon Ding #define RV1106_VENC_GRF_VOP_IO_WRAPPER	0x1000c
35e8dd2b64SDamon Ding #define RV1106_IO_BYPASS_SEL(v)		HIWORD_UPDATE(v, 0, 1)
36e8dd2b64SDamon Ding #define RV1106_VOGRF_VOP_PIPE_BYPASS	0x60034
37e8dd2b64SDamon Ding #define RV1106_VOP_PIPE_BYPASS(v)	HIWORD_UPDATE(v, 0, 1)
38e8dd2b64SDamon Ding 
39406bb09aSAndy Yan #define RV1126_GRF_IOFUNC_CON3          0x1026c
40406bb09aSAndy Yan #define RV1126_LCDC_IO_BYPASS(v)        HIWORD_UPDATE(v, 0, 0)
41406bb09aSAndy Yan 
4249627130SWyon Bi #define RK3288_GRF_SOC_CON6		0x025c
4349627130SWyon Bi #define RK3288_LVDS_LCDC_SEL(v)		HIWORD_UPDATE(v,  3,  3)
4449627130SWyon Bi #define RK3288_GRF_SOC_CON7		0x0260
4549627130SWyon Bi #define RK3288_LVDS_PWRDWN(v)		HIWORD_UPDATE(v, 15, 15)
4649627130SWyon Bi #define RK3288_LVDS_CON_ENABLE_2(v)	HIWORD_UPDATE(v, 12, 12)
4749627130SWyon Bi #define RK3288_LVDS_CON_ENABLE_1(v)	HIWORD_UPDATE(v, 11, 11)
4849627130SWyon Bi #define RK3288_LVDS_CON_CLKINV(v)	HIWORD_UPDATE(v,  8,  8)
4949627130SWyon Bi #define RK3288_LVDS_CON_TTL_EN(v)	HIWORD_UPDATE(v,  6,  6)
5049627130SWyon Bi 
516383df2bSSandy Huang #define RK3368_GRF_SOC_CON15		0x043c
526383df2bSSandy Huang #define RK3368_FORCE_JETAG(v)		HIWORD_UPDATE(v,  13,  13)
536383df2bSSandy Huang 
54078f1c2cSDamon Ding #define RK3562_GRF_IOC_VO_IO_CON	0x10500
55078f1c2cSDamon Ding #define RK3562_RGB_DATA_BYPASS(v)	HIWORD_UPDATE(v, 6, 6)
56078f1c2cSDamon Ding 
57c55d261eSSandy Huang #define RK3568_GRF_VO_CON1		0X0364
58c55d261eSSandy Huang #define RK3568_RGB_DATA_BYPASS(v)	HIWORD_UPDATE(v, 6, 6)
59c55d261eSSandy Huang 
606b9c0415SSandy Huang struct rockchip_rgb;
616b9c0415SSandy Huang 
626b9c0415SSandy Huang struct rockchip_rgb_funcs {
634ec7b4d4SSandy Huang 	void (*prepare)(struct rockchip_rgb *rgb, int pipe);
644ec7b4d4SSandy Huang 	void (*unprepare)(struct rockchip_rgb *rgb);
659e02a86eSWyon Bi };
669e02a86eSWyon Bi 
676b9c0415SSandy Huang struct rockchip_rgb {
680594ce39SZhang Yubing 	struct rockchip_connector connector;
69cb17ca6cSSandy Huang 	int id;
7049627130SWyon Bi 	struct udevice *dev;
716b9c0415SSandy Huang 	struct regmap *grf;
72406bb09aSAndy Yan 	bool data_sync_bypass;
7349627130SWyon Bi 	struct rockchip_phy *phy;
746b9c0415SSandy Huang 	const struct rockchip_rgb_funcs *funcs;
756b9c0415SSandy Huang };
766b9c0415SSandy Huang 
77b5dbb15aSDamon Ding struct mcu_cmd_header {
78b5dbb15aSDamon Ding 	u8 data_type;
79b5dbb15aSDamon Ding 	u8 delay;
80b5dbb15aSDamon Ding 	u8 payload_length;
81b5dbb15aSDamon Ding } __packed;
82b5dbb15aSDamon Ding 
83b5dbb15aSDamon Ding struct mcu_cmd_desc {
84b5dbb15aSDamon Ding 	struct mcu_cmd_header header;
85b5dbb15aSDamon Ding 	const u8 *payload;
86b5dbb15aSDamon Ding };
87b5dbb15aSDamon Ding 
88b5dbb15aSDamon Ding struct mcu_cmd_seq {
89b5dbb15aSDamon Ding 	struct mcu_cmd_desc *cmds;
90b5dbb15aSDamon Ding 	unsigned int cmd_cnt;
91b5dbb15aSDamon Ding };
92b5dbb15aSDamon Ding 
93b5dbb15aSDamon Ding struct rockchip_mcu_panel_desc {
94b5dbb15aSDamon Ding 	struct mcu_cmd_seq *init_seq;
95b5dbb15aSDamon Ding 	struct mcu_cmd_seq *exit_seq;
96b5dbb15aSDamon Ding 
97b5dbb15aSDamon Ding 	struct {
98b5dbb15aSDamon Ding 		unsigned int width;
99b5dbb15aSDamon Ding 		unsigned int height;
100b5dbb15aSDamon Ding 	} size;
101b5dbb15aSDamon Ding 
102b5dbb15aSDamon Ding 	struct {
103b5dbb15aSDamon Ding 		unsigned int prepare;
104b5dbb15aSDamon Ding 		unsigned int enable;
105b5dbb15aSDamon Ding 		unsigned int disable;
106b5dbb15aSDamon Ding 		unsigned int unprepare;
107b5dbb15aSDamon Ding 		unsigned int reset;
108b5dbb15aSDamon Ding 		unsigned int init;
109b5dbb15aSDamon Ding 	} delay;
110b5dbb15aSDamon Ding 
111b5dbb15aSDamon Ding 	unsigned int bpc;
112b5dbb15aSDamon Ding 	u32 bus_format;
113b5dbb15aSDamon Ding 	u32 bus_flags;
114b5dbb15aSDamon Ding 	bool power_invert;
115b5dbb15aSDamon Ding };
116b5dbb15aSDamon Ding 
117b5dbb15aSDamon Ding struct rockchip_mcu_panel {
118b5dbb15aSDamon Ding 	struct rockchip_panel base;
119b5dbb15aSDamon Ding 	struct rockchip_mcu_panel_desc *desc;
120b5dbb15aSDamon Ding 	struct udevice *power_supply;
121b5dbb15aSDamon Ding 	struct udevice *backlight;
122b5dbb15aSDamon Ding 
123b5dbb15aSDamon Ding 	struct gpio_desc enable_gpio;
124b5dbb15aSDamon Ding 	struct gpio_desc reset_gpio;
125b5dbb15aSDamon Ding 
126b5dbb15aSDamon Ding 	bool prepared;
127b5dbb15aSDamon Ding 	bool enabled;
128b5dbb15aSDamon Ding };
129b5dbb15aSDamon Ding 
130b5dbb15aSDamon Ding static inline struct rockchip_mcu_panel *to_rockchip_mcu_panel(struct rockchip_panel *panel)
131b5dbb15aSDamon Ding {
132b5dbb15aSDamon Ding 	return container_of(panel, struct rockchip_mcu_panel, base);
133b5dbb15aSDamon Ding }
134b5dbb15aSDamon Ding 
1350594ce39SZhang Yubing static int rockchip_rgb_connector_prepare(struct rockchip_connector *conn,
1360594ce39SZhang Yubing 					  struct display_state *state)
1379e02a86eSWyon Bi {
1380594ce39SZhang Yubing 	struct rockchip_rgb *rgb = dev_get_priv(conn->dev);
1399e02a86eSWyon Bi 	struct crtc_state *crtc_state = &state->crtc_state;
1409e02a86eSWyon Bi 	int pipe = crtc_state->crtc_id;
1419e3ffb10SGuochun Huang 	int ret;
1429e02a86eSWyon Bi 
143350f6a18SWyon Bi 	pinctrl_select_state(rgb->dev, "default");
144350f6a18SWyon Bi 
1454ec7b4d4SSandy Huang 	if (rgb->funcs && rgb->funcs->prepare)
1464ec7b4d4SSandy Huang 		rgb->funcs->prepare(rgb, pipe);
1479e02a86eSWyon Bi 
1489e3ffb10SGuochun Huang 	if (rgb->phy) {
1499e3ffb10SGuochun Huang 		ret = rockchip_phy_set_mode(rgb->phy, PHY_MODE_VIDEO_TTL);
1509e3ffb10SGuochun Huang 		if (ret) {
1519e3ffb10SGuochun Huang 			dev_err(rgb->dev, "failed to set phy mode: %d\n", ret);
1529e3ffb10SGuochun Huang 			return ret;
1539e3ffb10SGuochun Huang 		}
1545a7ad828SGuochun Huang 
1559e3ffb10SGuochun Huang 		rockchip_phy_power_on(rgb->phy);
1569e3ffb10SGuochun Huang 	}
15749627130SWyon Bi 
1589e02a86eSWyon Bi 	return 0;
1599e02a86eSWyon Bi }
1609e02a86eSWyon Bi 
1610594ce39SZhang Yubing static void rockchip_rgb_connector_unprepare(struct rockchip_connector *conn,
1620594ce39SZhang Yubing 					     struct display_state *state)
1639e02a86eSWyon Bi {
1640594ce39SZhang Yubing 	struct rockchip_rgb *rgb = dev_get_priv(conn->dev);
1656b9c0415SSandy Huang 
16649627130SWyon Bi 	if (rgb->phy)
16749627130SWyon Bi 		rockchip_phy_power_off(rgb->phy);
16849627130SWyon Bi 
1694ec7b4d4SSandy Huang 	if (rgb->funcs && rgb->funcs->unprepare)
1704ec7b4d4SSandy Huang 		rgb->funcs->unprepare(rgb);
1716b9c0415SSandy Huang 
172350f6a18SWyon Bi 	pinctrl_select_state(rgb->dev, "sleep");
1739e02a86eSWyon Bi }
1749e02a86eSWyon Bi 
1750594ce39SZhang Yubing static int rockchip_rgb_connector_init(struct rockchip_connector *conn, struct display_state *state)
17658c17f51SSandy Huang {
1770594ce39SZhang Yubing 	struct rockchip_rgb *rgb = dev_get_priv(conn->dev);
17858c17f51SSandy Huang 	struct connector_state *conn_state = &state->conn_state;
17958c17f51SSandy Huang 
1800594ce39SZhang Yubing 	rgb->phy = conn->phy;
18149627130SWyon Bi 
1829e02a86eSWyon Bi 	conn_state->color_space = V4L2_COLORSPACE_DEFAULT;
183cb17ca6cSSandy Huang 	conn_state->disp_info  = rockchip_get_disp_info(conn_state->type, rgb->id);
1849e02a86eSWyon Bi 
1856b93bf2bSWyon Bi 	switch (conn_state->bus_format) {
1866b93bf2bSWyon Bi 	case MEDIA_BUS_FMT_RGB666_1X18:
1876b93bf2bSWyon Bi 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P666;
188c55d261eSSandy Huang 		conn_state->output_if = VOP_OUTPUT_IF_RGB;
1896b93bf2bSWyon Bi 		break;
1906b93bf2bSWyon Bi 	case MEDIA_BUS_FMT_RGB565_1X16:
1916b93bf2bSWyon Bi 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P565;
192c55d261eSSandy Huang 		conn_state->output_if = VOP_OUTPUT_IF_RGB;
1936b93bf2bSWyon Bi 		break;
194b7b383ebSDamon Ding 	case MEDIA_BUS_FMT_RGB888_3X8:
195b7b383ebSDamon Ding 	case MEDIA_BUS_FMT_BGR888_3X8:
196b754d470SYu YongZhen 		conn_state->output_mode = ROCKCHIP_OUT_MODE_S888;
197c55d261eSSandy Huang 		conn_state->output_if = VOP_OUTPUT_IF_RGB;
198b754d470SYu YongZhen 		break;
199b7b383ebSDamon Ding 	case MEDIA_BUS_FMT_RGB888_DUMMY_4X8:
200b7b383ebSDamon Ding 	case MEDIA_BUS_FMT_BGR888_DUMMY_4X8:
2014ec7b4d4SSandy Huang 		conn_state->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY;
202c55d261eSSandy Huang 		conn_state->output_if = VOP_OUTPUT_IF_RGB;
2034ec7b4d4SSandy Huang 		break;
204c55d261eSSandy Huang 	case MEDIA_BUS_FMT_YUYV8_2X8:
205c55d261eSSandy Huang 	case MEDIA_BUS_FMT_YVYU8_2X8:
206c55d261eSSandy Huang 	case MEDIA_BUS_FMT_UYVY8_2X8:
207c55d261eSSandy Huang 	case MEDIA_BUS_FMT_VYUY8_2X8:
208c55d261eSSandy Huang 		conn_state->output_mode = ROCKCHIP_OUT_MODE_BT656;
209c55d261eSSandy Huang 		conn_state->output_if = VOP_OUTPUT_IF_BT656;
210c55d261eSSandy Huang 		break;
211c55d261eSSandy Huang 	case MEDIA_BUS_FMT_YUYV8_1X16:
212c55d261eSSandy Huang 	case MEDIA_BUS_FMT_YVYU8_1X16:
213c55d261eSSandy Huang 	case MEDIA_BUS_FMT_UYVY8_1X16:
214c55d261eSSandy Huang 	case MEDIA_BUS_FMT_VYUY8_1X16:
215c55d261eSSandy Huang 		conn_state->output_mode = ROCKCHIP_OUT_MODE_BT1120;
216c55d261eSSandy Huang 		conn_state->output_if = VOP_OUTPUT_IF_BT1120;
217d30e58a8SDamon Ding 		break;
2186b93bf2bSWyon Bi 	case MEDIA_BUS_FMT_RGB888_1X24:
2196b93bf2bSWyon Bi 	case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
2206b93bf2bSWyon Bi 	default:
2219e02a86eSWyon Bi 		conn_state->output_mode = ROCKCHIP_OUT_MODE_P888;
222c55d261eSSandy Huang 		conn_state->output_if = VOP_OUTPUT_IF_RGB;
2236b93bf2bSWyon Bi 		break;
2246b93bf2bSWyon Bi 	}
2259e02a86eSWyon Bi 
2269e02a86eSWyon Bi 	return 0;
2279e02a86eSWyon Bi }
2289e02a86eSWyon Bi 
2296b9c0415SSandy Huang static const struct rockchip_connector_funcs rockchip_rgb_connector_funcs = {
2306b9c0415SSandy Huang 	.init = rockchip_rgb_connector_init,
2314ec7b4d4SSandy Huang 	.prepare = rockchip_rgb_connector_prepare,
2324ec7b4d4SSandy Huang 	.unprepare = rockchip_rgb_connector_unprepare,
2339e02a86eSWyon Bi };
2349e02a86eSWyon Bi 
235b5dbb15aSDamon Ding static int rockchip_mcu_panel_send_cmds(struct display_state *state,
236b5dbb15aSDamon Ding 					struct mcu_cmd_seq *cmds)
237b5dbb15aSDamon Ding {
238b5dbb15aSDamon Ding 	int i;
239b5dbb15aSDamon Ding 
240b5dbb15aSDamon Ding 	if (!cmds)
241b5dbb15aSDamon Ding 		return -EINVAL;
242b5dbb15aSDamon Ding 
243b5dbb15aSDamon Ding 	display_send_mcu_cmd(state, MCU_SETBYPASS, 1);
244b5dbb15aSDamon Ding 	for (i = 0; i < cmds->cmd_cnt; i++) {
245b5dbb15aSDamon Ding 		struct mcu_cmd_desc *desc = &cmds->cmds[i];
246b5dbb15aSDamon Ding 		int value = 0;
247b5dbb15aSDamon Ding 
248b5dbb15aSDamon Ding 		value = desc->payload[0];
249b5dbb15aSDamon Ding 		display_send_mcu_cmd(state, desc->header.data_type, value);
250b5dbb15aSDamon Ding 
251b5dbb15aSDamon Ding 		if (desc->header.delay)
252b5dbb15aSDamon Ding 			mdelay(desc->header.delay);
253b5dbb15aSDamon Ding 	}
254b5dbb15aSDamon Ding 	display_send_mcu_cmd(state, MCU_SETBYPASS, 0);
255b5dbb15aSDamon Ding 
256b5dbb15aSDamon Ding 	return 0;
257b5dbb15aSDamon Ding }
258b5dbb15aSDamon Ding 
259b5dbb15aSDamon Ding static void rockchip_mcu_panel_prepare(struct rockchip_panel *panel)
260b5dbb15aSDamon Ding {
261b5dbb15aSDamon Ding 	struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
262b5dbb15aSDamon Ding 	int ret;
263b5dbb15aSDamon Ding 
264b5dbb15aSDamon Ding 	if (mcu_panel->prepared)
265b5dbb15aSDamon Ding 		return;
266b5dbb15aSDamon Ding 
267b5dbb15aSDamon Ding 	if (dm_gpio_is_valid(&mcu_panel->enable_gpio))
268b5dbb15aSDamon Ding 		dm_gpio_set_value(&mcu_panel->enable_gpio, 1);
269b5dbb15aSDamon Ding 
270b5dbb15aSDamon Ding 	if (mcu_panel->desc->delay.prepare)
271b5dbb15aSDamon Ding 		mdelay(mcu_panel->desc->delay.prepare);
272b5dbb15aSDamon Ding 
273b5dbb15aSDamon Ding 	if (dm_gpio_is_valid(&mcu_panel->reset_gpio))
274b5dbb15aSDamon Ding 		dm_gpio_set_value(&mcu_panel->reset_gpio, 1);
275b5dbb15aSDamon Ding 
276b5dbb15aSDamon Ding 	if (mcu_panel->desc->delay.reset)
277b5dbb15aSDamon Ding 		mdelay(mcu_panel->desc->delay.reset);
278b5dbb15aSDamon Ding 
279b5dbb15aSDamon Ding 	if (dm_gpio_is_valid(&mcu_panel->reset_gpio))
280b5dbb15aSDamon Ding 		dm_gpio_set_value(&mcu_panel->reset_gpio, 0);
281b5dbb15aSDamon Ding 
282b5dbb15aSDamon Ding 	if (mcu_panel->desc->delay.init)
283b5dbb15aSDamon Ding 		mdelay(mcu_panel->desc->delay.init);
284b5dbb15aSDamon Ding 
285b5dbb15aSDamon Ding 	if (mcu_panel->desc->init_seq) {
286b5dbb15aSDamon Ding 		ret = rockchip_mcu_panel_send_cmds(panel->state, mcu_panel->desc->init_seq);
287b5dbb15aSDamon Ding 		if (ret)
288b5dbb15aSDamon Ding 			printf("failed to send mcu panel init cmds: %d\n", ret);
289b5dbb15aSDamon Ding 	}
290b5dbb15aSDamon Ding 
291b5dbb15aSDamon Ding 	mcu_panel->prepared = true;
292b5dbb15aSDamon Ding }
293b5dbb15aSDamon Ding 
294b5dbb15aSDamon Ding static void rockchip_mcu_panel_unprepare(struct rockchip_panel *panel)
295b5dbb15aSDamon Ding {
296b5dbb15aSDamon Ding 	struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
297b5dbb15aSDamon Ding 	int ret;
298b5dbb15aSDamon Ding 
299b5dbb15aSDamon Ding 	if (!mcu_panel->prepared)
300b5dbb15aSDamon Ding 		return;
301b5dbb15aSDamon Ding 
302b5dbb15aSDamon Ding 	if (mcu_panel->desc->exit_seq) {
303b5dbb15aSDamon Ding 		ret = rockchip_mcu_panel_send_cmds(panel->state, mcu_panel->desc->exit_seq);
304b5dbb15aSDamon Ding 		if (ret)
305b5dbb15aSDamon Ding 			printf("failed to send mcu panel exit cmds: %d\n", ret);
306b5dbb15aSDamon Ding 	}
307b5dbb15aSDamon Ding 
308b5dbb15aSDamon Ding 	if (dm_gpio_is_valid(&mcu_panel->reset_gpio))
309b5dbb15aSDamon Ding 		dm_gpio_set_value(&mcu_panel->reset_gpio, 1);
310b5dbb15aSDamon Ding 
311b5dbb15aSDamon Ding 	if (dm_gpio_is_valid(&mcu_panel->enable_gpio))
312b5dbb15aSDamon Ding 		dm_gpio_set_value(&mcu_panel->enable_gpio, 0);
313b5dbb15aSDamon Ding 
314b5dbb15aSDamon Ding 	if (mcu_panel->desc->delay.unprepare)
315b5dbb15aSDamon Ding 		mdelay(mcu_panel->desc->delay.unprepare);
316b5dbb15aSDamon Ding 
317b5dbb15aSDamon Ding 	mcu_panel->prepared = false;
318b5dbb15aSDamon Ding }
319b5dbb15aSDamon Ding 
320b5dbb15aSDamon Ding static void rockchip_mcu_panel_enable(struct rockchip_panel *panel)
321b5dbb15aSDamon Ding {
322b5dbb15aSDamon Ding 	struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
323b5dbb15aSDamon Ding 
324b5dbb15aSDamon Ding 	if (mcu_panel->enabled)
325b5dbb15aSDamon Ding 		return;
326b5dbb15aSDamon Ding 
327b5dbb15aSDamon Ding 	if (mcu_panel->desc->delay.enable)
328b5dbb15aSDamon Ding 		mdelay(mcu_panel->desc->delay.enable);
329b5dbb15aSDamon Ding 
330b5dbb15aSDamon Ding 	if (mcu_panel->backlight)
331b5dbb15aSDamon Ding 		backlight_enable(mcu_panel->backlight);
332b5dbb15aSDamon Ding 
333b5dbb15aSDamon Ding 	mcu_panel->enabled = true;
334b5dbb15aSDamon Ding }
335b5dbb15aSDamon Ding 
336b5dbb15aSDamon Ding static void rockchip_mcu_panel_disable(struct rockchip_panel *panel)
337b5dbb15aSDamon Ding {
338b5dbb15aSDamon Ding 	struct rockchip_mcu_panel *mcu_panel = to_rockchip_mcu_panel(panel);
339b5dbb15aSDamon Ding 
340b5dbb15aSDamon Ding 	if (!mcu_panel->enabled)
341b5dbb15aSDamon Ding 		return;
342b5dbb15aSDamon Ding 
343b5dbb15aSDamon Ding 	if (mcu_panel->backlight)
344b5dbb15aSDamon Ding 		backlight_disable(mcu_panel->backlight);
345b5dbb15aSDamon Ding 
346b5dbb15aSDamon Ding 	if (mcu_panel->desc->delay.disable)
347b5dbb15aSDamon Ding 		mdelay(mcu_panel->desc->delay.disable);
348b5dbb15aSDamon Ding 
349b5dbb15aSDamon Ding 	mcu_panel->enabled = false;
350b5dbb15aSDamon Ding }
351b5dbb15aSDamon Ding 
352b5dbb15aSDamon Ding static const struct rockchip_panel_funcs rockchip_mcu_panel_funcs = {
353b5dbb15aSDamon Ding 	.prepare = rockchip_mcu_panel_prepare,
354b5dbb15aSDamon Ding 	.unprepare = rockchip_mcu_panel_unprepare,
355b5dbb15aSDamon Ding 	.enable = rockchip_mcu_panel_enable,
356b5dbb15aSDamon Ding 	.disable = rockchip_mcu_panel_disable,
357b5dbb15aSDamon Ding };
358b5dbb15aSDamon Ding 
359b5dbb15aSDamon Ding static int rockchip_mcu_panel_parse_cmds(const u8 *data, int length,
360b5dbb15aSDamon Ding 					 struct mcu_cmd_seq *pcmds)
361b5dbb15aSDamon Ding {
362b5dbb15aSDamon Ding 	int len;
363b5dbb15aSDamon Ding 	const u8 *buf;
364b5dbb15aSDamon Ding 	const struct mcu_cmd_header *header;
365b5dbb15aSDamon Ding 	int i, cnt = 0;
366b5dbb15aSDamon Ding 
367b5dbb15aSDamon Ding 	/* scan commands */
368b5dbb15aSDamon Ding 	cnt = 0;
369b5dbb15aSDamon Ding 	buf = data;
370b5dbb15aSDamon Ding 	len = length;
371b5dbb15aSDamon Ding 	while (len > sizeof(*header)) {
372b5dbb15aSDamon Ding 		header = (const struct mcu_cmd_header *)buf;
373b5dbb15aSDamon Ding 		buf += sizeof(*header) + header->payload_length;
374b5dbb15aSDamon Ding 		len -= sizeof(*header) + header->payload_length;
375b5dbb15aSDamon Ding 		cnt++;
376b5dbb15aSDamon Ding 	}
377b5dbb15aSDamon Ding 
378b5dbb15aSDamon Ding 	pcmds->cmds = calloc(cnt, sizeof(struct mcu_cmd_desc));
379b5dbb15aSDamon Ding 	if (!pcmds->cmds)
380b5dbb15aSDamon Ding 		return -ENOMEM;
381b5dbb15aSDamon Ding 
382b5dbb15aSDamon Ding 	pcmds->cmd_cnt = cnt;
383b5dbb15aSDamon Ding 
384b5dbb15aSDamon Ding 	buf = data;
385b5dbb15aSDamon Ding 	len = length;
386b5dbb15aSDamon Ding 	for (i = 0; i < cnt; i++) {
387b5dbb15aSDamon Ding 		struct mcu_cmd_desc *desc = &pcmds->cmds[i];
388b5dbb15aSDamon Ding 
389b5dbb15aSDamon Ding 		header = (const struct mcu_cmd_header *)buf;
390b5dbb15aSDamon Ding 		length -= sizeof(*header);
391b5dbb15aSDamon Ding 		buf += sizeof(*header);
392b5dbb15aSDamon Ding 		desc->header.data_type = header->data_type;
393b5dbb15aSDamon Ding 		desc->header.delay = header->delay;
394b5dbb15aSDamon Ding 		desc->header.payload_length = header->payload_length;
395b5dbb15aSDamon Ding 		desc->payload = buf;
396b5dbb15aSDamon Ding 		buf += header->payload_length;
397b5dbb15aSDamon Ding 		length -= header->payload_length;
398b5dbb15aSDamon Ding 	}
399b5dbb15aSDamon Ding 
400b5dbb15aSDamon Ding 	return 0;
401b5dbb15aSDamon Ding }
402b5dbb15aSDamon Ding 
403b5dbb15aSDamon Ding static int rockchip_mcu_panel_init(struct rockchip_mcu_panel *mcu_panel, ofnode mcu_panel_node)
404b5dbb15aSDamon Ding {
405b5dbb15aSDamon Ding 	const void *data;
406b5dbb15aSDamon Ding 	int len;
407b5dbb15aSDamon Ding 	int ret;
408b5dbb15aSDamon Ding 
409b5dbb15aSDamon Ding 	ret = gpio_request_by_name_nodev(mcu_panel_node, "enable-gpios", 0,
410b5dbb15aSDamon Ding 					 &mcu_panel->enable_gpio, GPIOD_IS_OUT);
411b5dbb15aSDamon Ding 	if (ret && ret != -ENOENT) {
412b5dbb15aSDamon Ding 		printf("%s: Cannot get mcu panel enable GPIO: %d\n", __func__, ret);
413b5dbb15aSDamon Ding 		return ret;
414b5dbb15aSDamon Ding 	}
415b5dbb15aSDamon Ding 
416b5dbb15aSDamon Ding 	ret = gpio_request_by_name_nodev(mcu_panel_node, "reset-gpios", 0,
417b5dbb15aSDamon Ding 					 &mcu_panel->reset_gpio, GPIOD_IS_OUT);
418b5dbb15aSDamon Ding 	if (ret && ret != -ENOENT) {
419b5dbb15aSDamon Ding 		printf("%s: Cannot get mcu panel reset GPIO: %d\n", __func__, ret);
420b5dbb15aSDamon Ding 		return ret;
421b5dbb15aSDamon Ding 	}
422b5dbb15aSDamon Ding 
423b5dbb15aSDamon Ding 	mcu_panel->desc = malloc(sizeof(struct rockchip_mcu_panel_desc));
424b5dbb15aSDamon Ding 	if (!mcu_panel->desc)
425b5dbb15aSDamon Ding 		return -ENOMEM;
426b5dbb15aSDamon Ding 
427b5dbb15aSDamon Ding 	mcu_panel->desc->power_invert = ofnode_read_bool(mcu_panel_node, "power-invert");
428b5dbb15aSDamon Ding 
429b5dbb15aSDamon Ding 	mcu_panel->desc->delay.prepare = ofnode_read_u32_default(mcu_panel_node, "prepare-delay-ms", 0);
430b5dbb15aSDamon Ding 	mcu_panel->desc->delay.unprepare = ofnode_read_u32_default(mcu_panel_node, "unprepare-delay-ms", 0);
431b5dbb15aSDamon Ding 	mcu_panel->desc->delay.enable = ofnode_read_u32_default(mcu_panel_node, "enable-delay-ms", 0);
432b5dbb15aSDamon Ding 	mcu_panel->desc->delay.disable = ofnode_read_u32_default(mcu_panel_node, "disable-delay-ms", 0);
433b5dbb15aSDamon Ding 	mcu_panel->desc->delay.init = ofnode_read_u32_default(mcu_panel_node, "init-delay-ms", 0);
434b5dbb15aSDamon Ding 	mcu_panel->desc->delay.reset = ofnode_read_u32_default(mcu_panel_node, "reset-delay-ms", 0);
435b5dbb15aSDamon Ding 
436b5dbb15aSDamon Ding 	mcu_panel->desc->bus_format = ofnode_read_u32_default(mcu_panel_node, "bus-format",
437b5dbb15aSDamon Ding 							      MEDIA_BUS_FMT_RBG888_1X24);
438b5dbb15aSDamon Ding 	mcu_panel->desc->bpc = ofnode_read_u32_default(mcu_panel_node, "bpc", 8);
439b5dbb15aSDamon Ding 
440b5dbb15aSDamon Ding 	data = ofnode_get_property(mcu_panel_node, "panel-init-sequence", &len);
441b5dbb15aSDamon Ding 	if (data) {
442b5dbb15aSDamon Ding 		mcu_panel->desc->init_seq = calloc(1, sizeof(*mcu_panel->desc->init_seq));
443b5dbb15aSDamon Ding 		if (!mcu_panel->desc->init_seq)
444b5dbb15aSDamon Ding 			return -ENOMEM;
445b5dbb15aSDamon Ding 
446b5dbb15aSDamon Ding 		ret = rockchip_mcu_panel_parse_cmds(data, len, mcu_panel->desc->init_seq);
447b5dbb15aSDamon Ding 		if (ret) {
448b5dbb15aSDamon Ding 			printf("failed to parse panel init sequence\n");
449b5dbb15aSDamon Ding 			goto free_on_cmds;
450b5dbb15aSDamon Ding 		}
451b5dbb15aSDamon Ding 	}
452b5dbb15aSDamon Ding 
453b5dbb15aSDamon Ding 	data = ofnode_get_property(mcu_panel_node, "panel-exit-sequence", &len);
454b5dbb15aSDamon Ding 	if (data) {
455b5dbb15aSDamon Ding 		mcu_panel->desc->exit_seq = calloc(1, sizeof(*mcu_panel->desc->exit_seq));
456b5dbb15aSDamon Ding 		if (!mcu_panel->desc->exit_seq) {
457b5dbb15aSDamon Ding 			ret = -ENOMEM;
458b5dbb15aSDamon Ding 			goto free_on_cmds;
459b5dbb15aSDamon Ding 		}
460b5dbb15aSDamon Ding 
461b5dbb15aSDamon Ding 		ret = rockchip_mcu_panel_parse_cmds(data, len, mcu_panel->desc->exit_seq);
462b5dbb15aSDamon Ding 		if (ret) {
463b5dbb15aSDamon Ding 			printf("failed to parse panel exit sequence\n");
464b5dbb15aSDamon Ding 			goto free_cmds;
465b5dbb15aSDamon Ding 		}
466b5dbb15aSDamon Ding 	}
467b5dbb15aSDamon Ding 
468b5dbb15aSDamon Ding 	return 0;
469b5dbb15aSDamon Ding 
470b5dbb15aSDamon Ding free_cmds:
471b5dbb15aSDamon Ding 	free(mcu_panel->desc->exit_seq);
472b5dbb15aSDamon Ding free_on_cmds:
473b5dbb15aSDamon Ding 	free(mcu_panel->desc->init_seq);
474b5dbb15aSDamon Ding 	return ret;
475b5dbb15aSDamon Ding }
476b5dbb15aSDamon Ding 
4779e02a86eSWyon Bi static int rockchip_rgb_probe(struct udevice *dev)
4789e02a86eSWyon Bi {
4796b9c0415SSandy Huang 	struct rockchip_rgb *rgb = dev_get_priv(dev);
480b5dbb15aSDamon Ding 	ofnode mcu_panel_node;
481b5dbb15aSDamon Ding 	int phandle;
482b5dbb15aSDamon Ding 	int ret;
4839e02a86eSWyon Bi 
48449627130SWyon Bi 	rgb->dev = dev;
4850594ce39SZhang Yubing 	rgb->funcs = (const struct rockchip_rgb_funcs *)dev_get_driver_data(dev);
4866b9c0415SSandy Huang 	rgb->grf = syscon_get_regmap(dev_get_parent(dev));
487406bb09aSAndy Yan 	rgb->data_sync_bypass = dev_read_bool(dev, "rockchip,data-sync-bypass");
488cb17ca6cSSandy Huang 	rgb->id = of_alias_get_id(ofnode_to_np(dev->node), "rgb");
489cb17ca6cSSandy Huang 	if (rgb->id < 0)
490cb17ca6cSSandy Huang 		rgb->id = 0;
4919e02a86eSWyon Bi 
492b5dbb15aSDamon Ding 	mcu_panel_node = dev_read_subnode(dev, "mcu-panel");
493b5dbb15aSDamon Ding 	if (ofnode_valid(mcu_panel_node) && ofnode_is_available(mcu_panel_node)) {
494b5dbb15aSDamon Ding 		struct rockchip_mcu_panel *mcu_panel;
495b5dbb15aSDamon Ding 
496b5dbb15aSDamon Ding 		mcu_panel = malloc(sizeof(struct rockchip_mcu_panel));
497b5dbb15aSDamon Ding 		if (!mcu_panel) {
498b5dbb15aSDamon Ding 			printf("failed to alloc mcu_panel data\n");
499b5dbb15aSDamon Ding 			return -ENOMEM;
500b5dbb15aSDamon Ding 		}
501b5dbb15aSDamon Ding 
502b5dbb15aSDamon Ding 		ret = rockchip_mcu_panel_init(mcu_panel, mcu_panel_node);
503b5dbb15aSDamon Ding 		if (ret < 0) {
504b5dbb15aSDamon Ding 			printf("failed to init mcu_panel: %d\n", ret);
505b5dbb15aSDamon Ding 			return ret;
506b5dbb15aSDamon Ding 		}
507b5dbb15aSDamon Ding 
508b5dbb15aSDamon Ding 		phandle = ofnode_read_u32_default(mcu_panel_node, "backlight", -1);
509b5dbb15aSDamon Ding 		if (phandle < 0) {
510b5dbb15aSDamon Ding 			printf("failed to find backlight phandle\n");
511b5dbb15aSDamon Ding 			return -EINVAL;
512b5dbb15aSDamon Ding 		}
513b5dbb15aSDamon Ding 
514b5dbb15aSDamon Ding 		ret = uclass_get_device_by_phandle_id(UCLASS_PANEL_BACKLIGHT, phandle,
515b5dbb15aSDamon Ding 						      &mcu_panel->backlight);
516b5dbb15aSDamon Ding 		if (ret && ret != -ENOENT) {
517b5dbb15aSDamon Ding 			printf("%s: failed to get backlight device: %d\n", __func__, ret);
518b5dbb15aSDamon Ding 			return ret;
519b5dbb15aSDamon Ding 		}
520b5dbb15aSDamon Ding 
521b5dbb15aSDamon Ding 		mcu_panel->base.dev = dev;
522b5dbb15aSDamon Ding 		mcu_panel->base.bus_format = mcu_panel->desc->bus_format;
523b5dbb15aSDamon Ding 		mcu_panel->base.bpc = mcu_panel->desc->bpc;
524b5dbb15aSDamon Ding 		mcu_panel->base.funcs = &rockchip_mcu_panel_funcs;
525a42af2e5SDamon Ding 		mcu_panel->enabled = false;
526a42af2e5SDamon Ding 		mcu_panel->prepared = false;
527b5dbb15aSDamon Ding 
528b5dbb15aSDamon Ding 		rgb->connector.panel = &mcu_panel->base;
529b5dbb15aSDamon Ding 	}
530b5dbb15aSDamon Ding 
5310594ce39SZhang Yubing 	rockchip_connector_bind(&rgb->connector, dev, rgb->id, &rockchip_rgb_connector_funcs,
5320594ce39SZhang Yubing 				NULL, DRM_MODE_CONNECTOR_LVDS);
5330594ce39SZhang Yubing 
5349e02a86eSWyon Bi 	return 0;
5359e02a86eSWyon Bi }
5369e02a86eSWyon Bi 
537e8dd2b64SDamon Ding static void rv1106_rgb_prepare(struct rockchip_rgb *rgb, int pipe)
538e8dd2b64SDamon Ding {
539e8dd2b64SDamon Ding 	regmap_write(rgb->grf, RV1106_VENC_GRF_VOP_IO_WRAPPER,
540e8dd2b64SDamon Ding 		     RV1106_IO_BYPASS_SEL(rgb->data_sync_bypass ? 0x3 : 0x0));
541e8dd2b64SDamon Ding 	regmap_write(rgb->grf, RV1106_VOGRF_VOP_PIPE_BYPASS,
542e8dd2b64SDamon Ding 		     RV1106_VOP_PIPE_BYPASS(rgb->data_sync_bypass ? 0x3 : 0x0));
543e8dd2b64SDamon Ding }
544e8dd2b64SDamon Ding 
545e8dd2b64SDamon Ding static const struct rockchip_rgb_funcs rv1106_rgb_funcs = {
546e8dd2b64SDamon Ding 	.prepare = rv1106_rgb_prepare,
547e8dd2b64SDamon Ding };
548e8dd2b64SDamon Ding 
549406bb09aSAndy Yan static void rv1126_rgb_prepare(struct rockchip_rgb *rgb, int pipe)
550406bb09aSAndy Yan {
551406bb09aSAndy Yan 	regmap_write(rgb->grf, RV1126_GRF_IOFUNC_CON3,
552406bb09aSAndy Yan 		     RV1126_LCDC_IO_BYPASS(rgb->data_sync_bypass));
553406bb09aSAndy Yan }
554406bb09aSAndy Yan 
555406bb09aSAndy Yan static const struct rockchip_rgb_funcs rv1126_rgb_funcs = {
556406bb09aSAndy Yan 	.prepare = rv1126_rgb_prepare,
557406bb09aSAndy Yan };
558406bb09aSAndy Yan 
5594ec7b4d4SSandy Huang static void px30_rgb_prepare(struct rockchip_rgb *rgb, int pipe)
5606b9c0415SSandy Huang {
561a4878ddaSWyon Bi 	regmap_write(rgb->grf, PX30_GRF_PD_VO_CON1, PX30_RGB_VOP_SEL(pipe) |
562406bb09aSAndy Yan 		     PX30_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass));
5636b9c0415SSandy Huang }
5646b9c0415SSandy Huang 
5656b9c0415SSandy Huang static const struct rockchip_rgb_funcs px30_rgb_funcs = {
5664ec7b4d4SSandy Huang 	.prepare = px30_rgb_prepare,
5676b9c0415SSandy Huang };
5686b9c0415SSandy Huang 
5694ec7b4d4SSandy Huang static void rk1808_rgb_prepare(struct rockchip_rgb *rgb, int pipe)
5706b9c0415SSandy Huang {
5716b9c0415SSandy Huang 	regmap_write(rgb->grf, RK1808_GRF_PD_VO_CON1,
572406bb09aSAndy Yan 		     RK1808_RGB_DATA_SYNC_BYPASS(rgb->data_sync_bypass));
5736b9c0415SSandy Huang }
5746b9c0415SSandy Huang 
5756b9c0415SSandy Huang static const struct rockchip_rgb_funcs rk1808_rgb_funcs = {
5764ec7b4d4SSandy Huang 	.prepare = rk1808_rgb_prepare,
5776b9c0415SSandy Huang };
5786b9c0415SSandy Huang 
5794ec7b4d4SSandy Huang static void rk3288_rgb_prepare(struct rockchip_rgb *rgb, int pipe)
58049627130SWyon Bi {
58149627130SWyon Bi 	regmap_write(rgb->grf, RK3288_GRF_SOC_CON6, RK3288_LVDS_LCDC_SEL(pipe));
58249627130SWyon Bi 	regmap_write(rgb->grf, RK3288_GRF_SOC_CON7,
58349627130SWyon Bi 		     RK3288_LVDS_PWRDWN(0) | RK3288_LVDS_CON_ENABLE_2(1) |
58449627130SWyon Bi 		     RK3288_LVDS_CON_ENABLE_1(1) | RK3288_LVDS_CON_CLKINV(0) |
58549627130SWyon Bi 		     RK3288_LVDS_CON_TTL_EN(1));
58649627130SWyon Bi }
58749627130SWyon Bi 
5884ec7b4d4SSandy Huang static void rk3288_rgb_unprepare(struct rockchip_rgb *rgb)
58949627130SWyon Bi {
59049627130SWyon Bi 	regmap_write(rgb->grf, RK3288_GRF_SOC_CON7,
59149627130SWyon Bi 		     RK3288_LVDS_PWRDWN(1) | RK3288_LVDS_CON_ENABLE_2(0) |
59249627130SWyon Bi 		     RK3288_LVDS_CON_ENABLE_1(0) | RK3288_LVDS_CON_TTL_EN(0));
59349627130SWyon Bi }
59449627130SWyon Bi 
59549627130SWyon Bi static const struct rockchip_rgb_funcs rk3288_rgb_funcs = {
5964ec7b4d4SSandy Huang 	.prepare = rk3288_rgb_prepare,
5974ec7b4d4SSandy Huang 	.unprepare = rk3288_rgb_unprepare,
59849627130SWyon Bi };
59949627130SWyon Bi 
6004ec7b4d4SSandy Huang static void rk3368_rgb_prepare(struct rockchip_rgb *rgb, int pipe)
6016383df2bSSandy Huang {
6026383df2bSSandy Huang 	regmap_write(rgb->grf, RK3368_GRF_SOC_CON15, RK3368_FORCE_JETAG(0));
6036383df2bSSandy Huang }
6046383df2bSSandy Huang 
6056383df2bSSandy Huang static const struct rockchip_rgb_funcs rk3368_rgb_funcs = {
6064ec7b4d4SSandy Huang 	.prepare = rk3368_rgb_prepare,
6076383df2bSSandy Huang };
6086383df2bSSandy Huang 
609078f1c2cSDamon Ding static void rk3562_rgb_prepare(struct rockchip_rgb *rgb, int pipe)
610078f1c2cSDamon Ding {
611078f1c2cSDamon Ding 	regmap_write(rgb->grf, RK3562_GRF_IOC_VO_IO_CON,
612078f1c2cSDamon Ding 		     RK3562_RGB_DATA_BYPASS(rgb->data_sync_bypass));
613078f1c2cSDamon Ding }
614078f1c2cSDamon Ding 
615078f1c2cSDamon Ding static const struct rockchip_rgb_funcs rk3562_rgb_funcs = {
616078f1c2cSDamon Ding 	.prepare = rk3562_rgb_prepare,
617078f1c2cSDamon Ding };
618078f1c2cSDamon Ding 
619c55d261eSSandy Huang static void rk3568_rgb_prepare(struct rockchip_rgb *rgb, int pipe)
620c55d261eSSandy Huang {
621963b371cSSandy Huang 	regmap_write(rgb->grf, RK3568_GRF_VO_CON1, RK3568_RGB_DATA_BYPASS(rgb->data_sync_bypass));
622c55d261eSSandy Huang }
623c55d261eSSandy Huang 
624c55d261eSSandy Huang static const struct rockchip_rgb_funcs rk3568_rgb_funcs = {
625c55d261eSSandy Huang 	.prepare = rk3568_rgb_prepare,
626c55d261eSSandy Huang };
627c55d261eSSandy Huang 
6289e02a86eSWyon Bi static const struct udevice_id rockchip_rgb_ids[] = {
6299e02a86eSWyon Bi 	{
6309e02a86eSWyon Bi 		.compatible = "rockchip,px30-rgb",
6310594ce39SZhang Yubing 		.data = (ulong)&px30_rgb_funcs,
6326b9c0415SSandy Huang 	},
6336b9c0415SSandy Huang 	{
6346b9c0415SSandy Huang 		.compatible = "rockchip,rk1808-rgb",
6350594ce39SZhang Yubing 		.data = (ulong)&rk1808_rgb_funcs,
6369e02a86eSWyon Bi 	},
6379e02a86eSWyon Bi 	{
6389e02a86eSWyon Bi 		.compatible = "rockchip,rk3066-rgb",
6399e02a86eSWyon Bi 	},
6409e02a86eSWyon Bi 	{
64149627130SWyon Bi 		.compatible = "rockchip,rk3128-rgb",
64249627130SWyon Bi 	},
64349627130SWyon Bi 	{
64449627130SWyon Bi 		.compatible = "rockchip,rk3288-rgb",
6450594ce39SZhang Yubing 		.data = (ulong)&rk3288_rgb_funcs,
64649627130SWyon Bi 	},
64749627130SWyon Bi 	{
6489e02a86eSWyon Bi 		.compatible = "rockchip,rk3308-rgb",
6499e02a86eSWyon Bi 	},
6509e02a86eSWyon Bi 	{
65149627130SWyon Bi 		.compatible = "rockchip,rk3368-rgb",
6520594ce39SZhang Yubing 		.data = (ulong)&rk3368_rgb_funcs,
65349627130SWyon Bi 	},
65449627130SWyon Bi 	{
655078f1c2cSDamon Ding 		.compatible = "rockchip,rk3562-rgb",
656078f1c2cSDamon Ding 		.data = (ulong)&rk3562_rgb_funcs,
657078f1c2cSDamon Ding 	},
658078f1c2cSDamon Ding 	{
659c55d261eSSandy Huang 		.compatible = "rockchip,rk3568-rgb",
6600594ce39SZhang Yubing 		.data = (ulong)&rk3568_rgb_funcs,
661c55d261eSSandy Huang 	},
662c55d261eSSandy Huang 	{
663*9f3137bcSDamon Ding 		.compatible = "rockchip,rk3588-rgb",
664*9f3137bcSDamon Ding 	},
665*9f3137bcSDamon Ding 	{
666e8dd2b64SDamon Ding 		.compatible = "rockchip,rv1106-rgb",
667e8dd2b64SDamon Ding 		.data = (ulong)&rv1106_rgb_funcs,
668e8dd2b64SDamon Ding 	},
669e8dd2b64SDamon Ding 	{
6709e02a86eSWyon Bi 		.compatible = "rockchip,rv1108-rgb",
6719e02a86eSWyon Bi 	},
672406bb09aSAndy Yan 	{
673406bb09aSAndy Yan 		.compatible = "rockchip,rv1126-rgb",
6740594ce39SZhang Yubing 		.data = (ulong)&rv1126_rgb_funcs,
675406bb09aSAndy Yan 	},
6769e02a86eSWyon Bi 	{}
6779e02a86eSWyon Bi };
6789e02a86eSWyon Bi 
6799e02a86eSWyon Bi U_BOOT_DRIVER(rockchip_rgb) = {
6809e02a86eSWyon Bi 	.name = "rockchip_rgb",
6819e02a86eSWyon Bi 	.id = UCLASS_DISPLAY,
6829e02a86eSWyon Bi 	.of_match = rockchip_rgb_ids,
6839e02a86eSWyon Bi 	.probe = rockchip_rgb_probe,
6846b9c0415SSandy Huang 	.priv_auto_alloc_size = sizeof(struct rockchip_rgb),
6859e02a86eSWyon Bi };
686