xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/serdes-bridge-split.c (revision fb0c3269ba4cd093780cb50afda01fe0d30baa4b)
1*fb0c3269SLuo Wei // SPDX-License-Identifier: GPL-2.0-or-later
2*fb0c3269SLuo Wei /*
3*fb0c3269SLuo Wei  * serdes-bridge_split.c  --  display bridge_split for different serdes chips
4*fb0c3269SLuo Wei  *
5*fb0c3269SLuo Wei  * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
6*fb0c3269SLuo Wei  *
7*fb0c3269SLuo Wei  * Author: luowei <lw@rock-chips.com>
8*fb0c3269SLuo Wei  */
9*fb0c3269SLuo Wei 
10*fb0c3269SLuo Wei #include "core.h"
11*fb0c3269SLuo Wei 
12*fb0c3269SLuo Wei static void serdes_bridge_split_init(struct serdes *serdes)
13*fb0c3269SLuo Wei {
14*fb0c3269SLuo Wei 	if (serdes->vpower_supply)
15*fb0c3269SLuo Wei 		regulator_set_enable(serdes->vpower_supply, true);
16*fb0c3269SLuo Wei 
17*fb0c3269SLuo Wei 	if (dm_gpio_is_valid(&serdes->enable_gpio))
18*fb0c3269SLuo Wei 		dm_gpio_set_value(&serdes->enable_gpio, 1);
19*fb0c3269SLuo Wei 
20*fb0c3269SLuo Wei 	mdelay(5);
21*fb0c3269SLuo Wei 
22*fb0c3269SLuo Wei 	//video_bridge_set_active(serdes->dev, true);
23*fb0c3269SLuo Wei 
24*fb0c3269SLuo Wei 	if (serdes->chip_data->bridge_ops->init)
25*fb0c3269SLuo Wei 		serdes->chip_data->bridge_ops->init(serdes);
26*fb0c3269SLuo Wei 
27*fb0c3269SLuo Wei 	serdes_i2c_set_sequence(serdes);
28*fb0c3269SLuo Wei 
29*fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
30*fb0c3269SLuo Wei 		       serdes->dev->name,
31*fb0c3269SLuo Wei 		       serdes->chip_data->name);
32*fb0c3269SLuo Wei }
33*fb0c3269SLuo Wei 
34*fb0c3269SLuo Wei static void serdes_bridge_split_pre_enable(struct rockchip_bridge *bridge)
35*fb0c3269SLuo Wei {
36*fb0c3269SLuo Wei 	struct udevice *dev = bridge->dev;
37*fb0c3269SLuo Wei 	struct serdes *serdes = dev_get_priv(dev->parent);
38*fb0c3269SLuo Wei 
39*fb0c3269SLuo Wei 	//serdes_bridge_split_split_init(serdes);
40*fb0c3269SLuo Wei 
41*fb0c3269SLuo Wei 	if (serdes->chip_data->bridge_ops->pre_enable)
42*fb0c3269SLuo Wei 		serdes->chip_data->bridge_ops->pre_enable(serdes);
43*fb0c3269SLuo Wei 
44*fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
45*fb0c3269SLuo Wei 		       serdes->dev->name,
46*fb0c3269SLuo Wei 		       serdes->chip_data->name);
47*fb0c3269SLuo Wei }
48*fb0c3269SLuo Wei 
49*fb0c3269SLuo Wei static void serdes_bridge_split_post_disable(struct rockchip_bridge *bridge)
50*fb0c3269SLuo Wei {
51*fb0c3269SLuo Wei 	struct udevice *dev = bridge->dev;
52*fb0c3269SLuo Wei 	struct serdes *serdes = dev_get_priv(dev->parent);
53*fb0c3269SLuo Wei 
54*fb0c3269SLuo Wei 	if (serdes->chip_data->bridge_ops->post_disable)
55*fb0c3269SLuo Wei 		serdes->chip_data->bridge_ops->post_disable(serdes);
56*fb0c3269SLuo Wei 
57*fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
58*fb0c3269SLuo Wei 		       serdes->dev->name,
59*fb0c3269SLuo Wei 		       serdes->chip_data->name);
60*fb0c3269SLuo Wei }
61*fb0c3269SLuo Wei 
62*fb0c3269SLuo Wei static void serdes_bridge_split_enable(struct rockchip_bridge *bridge)
63*fb0c3269SLuo Wei {
64*fb0c3269SLuo Wei 	struct udevice *dev = bridge->dev;
65*fb0c3269SLuo Wei 	struct serdes *serdes = dev_get_priv(dev->parent);
66*fb0c3269SLuo Wei 
67*fb0c3269SLuo Wei 	if (serdes->chip_data->serdes_type == TYPE_DES)
68*fb0c3269SLuo Wei 		serdes_bridge_split_init(serdes);
69*fb0c3269SLuo Wei 
70*fb0c3269SLuo Wei 	if (serdes->chip_data->bridge_ops->enable)
71*fb0c3269SLuo Wei 		serdes->chip_data->bridge_ops->enable(serdes);
72*fb0c3269SLuo Wei 
73*fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
74*fb0c3269SLuo Wei 		       serdes->dev->name,
75*fb0c3269SLuo Wei 		       serdes->chip_data->name);
76*fb0c3269SLuo Wei }
77*fb0c3269SLuo Wei 
78*fb0c3269SLuo Wei static void serdes_bridge_split_disable(struct rockchip_bridge *bridge)
79*fb0c3269SLuo Wei {
80*fb0c3269SLuo Wei 	struct udevice *dev = bridge->dev;
81*fb0c3269SLuo Wei 	struct serdes *serdes = dev_get_priv(dev->parent);
82*fb0c3269SLuo Wei 
83*fb0c3269SLuo Wei 	if (serdes->chip_data->bridge_ops->disable)
84*fb0c3269SLuo Wei 		serdes->chip_data->bridge_ops->disable(serdes);
85*fb0c3269SLuo Wei 
86*fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
87*fb0c3269SLuo Wei 		       serdes->chip_data->name);
88*fb0c3269SLuo Wei }
89*fb0c3269SLuo Wei 
90*fb0c3269SLuo Wei static void serdes_bridge_split_mode_set(struct rockchip_bridge *bridge,
91*fb0c3269SLuo Wei 					 const struct drm_display_mode *mode)
92*fb0c3269SLuo Wei {
93*fb0c3269SLuo Wei 	struct udevice *dev = bridge->dev;
94*fb0c3269SLuo Wei 	struct serdes *serdes = dev_get_priv(dev->parent);
95*fb0c3269SLuo Wei 
96*fb0c3269SLuo Wei 	memcpy(&serdes->serdes_bridge_split->mode, mode,
97*fb0c3269SLuo Wei 	       sizeof(struct drm_display_mode));
98*fb0c3269SLuo Wei 
99*fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
100*fb0c3269SLuo Wei 		       serdes->chip_data->name);
101*fb0c3269SLuo Wei }
102*fb0c3269SLuo Wei 
103*fb0c3269SLuo Wei static bool serdes_bridge_split_detect(struct rockchip_bridge *bridge)
104*fb0c3269SLuo Wei {
105*fb0c3269SLuo Wei 	bool ret = true;
106*fb0c3269SLuo Wei 	struct udevice *dev = bridge->dev;
107*fb0c3269SLuo Wei 	struct serdes *serdes = dev_get_priv(dev->parent);
108*fb0c3269SLuo Wei 
109*fb0c3269SLuo Wei 	if (serdes->chip_data->bridge_ops->detect)
110*fb0c3269SLuo Wei 		ret = serdes->chip_data->bridge_ops->detect(serdes);
111*fb0c3269SLuo Wei 
112*fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s %s\n", __func__, serdes->dev->name,
113*fb0c3269SLuo Wei 		       serdes->chip_data->name, ret ? "detected" : "no detected");
114*fb0c3269SLuo Wei 
115*fb0c3269SLuo Wei 	return ret;
116*fb0c3269SLuo Wei }
117*fb0c3269SLuo Wei 
118*fb0c3269SLuo Wei struct rockchip_bridge_funcs serdes_bridge_split_ops = {
119*fb0c3269SLuo Wei 	.pre_enable = serdes_bridge_split_pre_enable,
120*fb0c3269SLuo Wei 	.post_disable = serdes_bridge_split_post_disable,
121*fb0c3269SLuo Wei 	.enable = serdes_bridge_split_enable,
122*fb0c3269SLuo Wei 	.disable = serdes_bridge_split_disable,
123*fb0c3269SLuo Wei 	.mode_set = serdes_bridge_split_mode_set,
124*fb0c3269SLuo Wei 	.detect = serdes_bridge_split_detect,
125*fb0c3269SLuo Wei };
126*fb0c3269SLuo Wei 
127*fb0c3269SLuo Wei static int serdes_bridge_split_probe(struct udevice *dev)
128*fb0c3269SLuo Wei {
129*fb0c3269SLuo Wei 	struct rockchip_bridge *bridge;
130*fb0c3269SLuo Wei 	struct serdes *serdes = dev_get_priv(dev->parent);
131*fb0c3269SLuo Wei 	struct mipi_dsi_device *device = dev_get_platdata(dev);
132*fb0c3269SLuo Wei 
133*fb0c3269SLuo Wei 	serdes->sel_mipi = dev_read_bool(dev->parent, "sel-mipi");
134*fb0c3269SLuo Wei 	if (serdes->sel_mipi) {
135*fb0c3269SLuo Wei 		device->dev = dev;
136*fb0c3269SLuo Wei 		device->lanes = dev_read_u32_default(dev->parent, "dsi,lanes", 4);
137*fb0c3269SLuo Wei 		device->format = dev_read_u32_default(dev->parent, "dsi,format",
138*fb0c3269SLuo Wei 						      MIPI_DSI_FMT_RGB888);
139*fb0c3269SLuo Wei 		device->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
140*fb0c3269SLuo Wei 		device->channel = dev_read_u32_default(dev->parent, "reg", 0);
141*fb0c3269SLuo Wei 	}
142*fb0c3269SLuo Wei 
143*fb0c3269SLuo Wei 	bridge = calloc(1, sizeof(*bridge));
144*fb0c3269SLuo Wei 	if (!bridge)
145*fb0c3269SLuo Wei 		return -ENOMEM;
146*fb0c3269SLuo Wei 
147*fb0c3269SLuo Wei 	dev->driver_data = (ulong)bridge;
148*fb0c3269SLuo Wei 	bridge->dev = dev;
149*fb0c3269SLuo Wei 	bridge->funcs = &serdes_bridge_split_ops;
150*fb0c3269SLuo Wei 
151*fb0c3269SLuo Wei 	serdes->serdes_bridge_split->bridge = bridge;
152*fb0c3269SLuo Wei 
153*fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s bridge=%p name=%s device=%p\n",
154*fb0c3269SLuo Wei 		       __func__, serdes->dev->name,
155*fb0c3269SLuo Wei 		       serdes->chip_data->name,
156*fb0c3269SLuo Wei 		       bridge, bridge->dev->name, device);
157*fb0c3269SLuo Wei 
158*fb0c3269SLuo Wei 	return 0;
159*fb0c3269SLuo Wei }
160*fb0c3269SLuo Wei 
161*fb0c3269SLuo Wei static const struct udevice_id serdes_of_match[] = {
162*fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96745)
163*fb0c3269SLuo Wei 	{ .compatible = "maxim,max96745-bridge-split", },
164*fb0c3269SLuo Wei #endif
165*fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96755)
166*fb0c3269SLuo Wei 	{ .compatible = "maxim,max96755-bridge-split", },
167*fb0c3269SLuo Wei #endif
168*fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96789)
169*fb0c3269SLuo Wei 	{ .compatible = "maxim,max96789-bridge-split", },
170*fb0c3269SLuo Wei #endif
171*fb0c3269SLuo Wei 	{ }
172*fb0c3269SLuo Wei };
173*fb0c3269SLuo Wei 
174*fb0c3269SLuo Wei U_BOOT_DRIVER(serdes_bridge_split) = {
175*fb0c3269SLuo Wei 	.name = "serdes-bridge-split",
176*fb0c3269SLuo Wei 	.id = UCLASS_VIDEO_BRIDGE,
177*fb0c3269SLuo Wei 	.of_match = serdes_of_match,
178*fb0c3269SLuo Wei 	.probe = serdes_bridge_split_probe,
179*fb0c3269SLuo Wei 	.priv_auto_alloc_size = sizeof(struct serdes_bridge_split),
180*fb0c3269SLuo Wei 	.platdata_auto_alloc_size = sizeof(struct mipi_dsi_device),
181*fb0c3269SLuo Wei };
182