xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/serdes-bridge.c (revision b77c257eaed4fb83d4f17aeb4ad71b3a8a7e38e6)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * serdes-bridge.c  --  display bridge for different serdes chips
4  *
5  * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
6  *
7  * Author: luowei <lw@rock-chips.com>
8  */
9 
10 #include <serdes-display-core.h>
11 
12 static void serdes_bridge_init(struct serdes *serdes)
13 {
14 	if (serdes->vpower_supply)
15 		regulator_set_enable(serdes->vpower_supply, true);
16 
17 	if (dm_gpio_is_valid(&serdes->enable_gpio))
18 		dm_gpio_set_value(&serdes->enable_gpio, 1);
19 
20 	mdelay(5);
21 
22 	video_bridge_set_active(serdes->dev, true);
23 
24 	if (serdes->chip_data->bridge_ops->init)
25 		serdes->chip_data->bridge_ops->init(serdes);
26 
27 	serdes_i2c_set_sequence(serdes);
28 
29 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
30 		       serdes->dev->name,
31 		       serdes->chip_data->name);
32 }
33 
34 static void serdes_bridge_pre_enable(struct rockchip_bridge *bridge)
35 {
36 	struct udevice *dev = bridge->dev;
37 	struct serdes *serdes = dev_get_priv(dev);
38 
39 	//serdes_bridge_init(serdes);
40 
41 	if (serdes->chip_data->bridge_ops->pre_enable)
42 		serdes->chip_data->bridge_ops->pre_enable(serdes);
43 
44 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
45 		       serdes->dev->name,
46 		       serdes->chip_data->name);
47 }
48 
49 static void serdes_bridge_post_disable(struct rockchip_bridge *bridge)
50 {
51 	struct udevice *dev = bridge->dev;
52 	struct serdes *serdes = dev_get_priv(dev);
53 
54 	if (serdes->chip_data->bridge_ops->post_disable)
55 		serdes->chip_data->bridge_ops->post_disable(serdes);
56 
57 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
58 		       serdes->dev->name,
59 		       serdes->chip_data->name);
60 }
61 
62 static void serdes_bridge_enable(struct rockchip_bridge *bridge)
63 {
64 	struct udevice *dev = bridge->dev;
65 	struct serdes *serdes = dev_get_priv(dev);
66 
67 	if (serdes->chip_data->serdes_type == TYPE_DES)
68 		serdes_bridge_init(serdes);
69 
70 	if (serdes->chip_data->bridge_ops->enable)
71 		serdes->chip_data->bridge_ops->enable(serdes);
72 
73 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
74 		       serdes->dev->name,
75 		       serdes->chip_data->name);
76 }
77 
78 static void serdes_bridge_disable(struct rockchip_bridge *bridge)
79 {
80 	struct udevice *dev = bridge->dev;
81 	struct serdes *serdes = dev_get_priv(dev);
82 
83 	if (serdes->chip_data->bridge_ops->disable)
84 		serdes->chip_data->bridge_ops->disable(serdes);
85 
86 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
87 		       serdes->chip_data->name);
88 }
89 
90 static void serdes_bridge_mode_set(struct rockchip_bridge *bridge,
91 				   const struct drm_display_mode *mode)
92 {
93 	struct udevice *dev = bridge->dev;
94 	struct serdes *serdes = dev_get_priv(dev);
95 
96 	memcpy(&serdes->serdes_bridge->mode, mode,
97 	       sizeof(struct drm_display_mode));
98 
99 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
100 		       serdes->chip_data->name);
101 }
102 
103 static bool serdes_bridge_detect(struct rockchip_bridge *bridge)
104 {
105 	bool ret = true;
106 	struct serdes *serdes = dev_get_priv(bridge->dev);
107 
108 	if (serdes->chip_data->bridge_ops->detect)
109 		ret = serdes->chip_data->bridge_ops->detect(serdes);
110 
111 	SERDES_DBG_MFD("%s: %s %s %s\n", __func__, serdes->dev->name,
112 		       serdes->chip_data->name, (ret == true) ? "detected" : "no detected");
113 
114 	return ret;
115 }
116 
117 struct rockchip_bridge_funcs serdes_bridge_ops = {
118 	.pre_enable = serdes_bridge_pre_enable,
119 	.post_disable = serdes_bridge_post_disable,
120 	.enable = serdes_bridge_enable,
121 	.disable = serdes_bridge_disable,
122 	.mode_set = serdes_bridge_mode_set,
123 	.detect = serdes_bridge_detect,
124 };
125 
126 static int serdes_bridge_probe(struct udevice *dev)
127 {
128 	struct serdes *serdes = dev_get_priv(dev);
129 	struct serdes_bridge *serdes_bridge = NULL;
130 	struct serdes_pinctrl *serdes_pinctrl = NULL;
131 	struct rockchip_bridge *bridge = NULL;
132 	int ret;
133 
134 	ret = i2c_set_chip_offset_len(dev, 2);
135 	if (ret)
136 		return ret;
137 
138 	serdes->dev = dev;
139 	serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev);
140 	serdes->type = serdes->chip_data->serdes_type;
141 
142 	SERDES_DBG_MFD("serdes %s %s probe start\n",
143 		       serdes->dev->name, serdes->chip_data->name);
144 
145 	ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
146 					   "vpower-supply", &serdes->vpower_supply);
147 	if (ret && ret != -ENOENT)
148 		SERDES_DBG_MFD("%s: Cannot get power supply: %d\n",
149 			       __func__, ret);
150 
151 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
152 				   &serdes->enable_gpio, GPIOD_IS_OUT);
153 	if (ret)
154 		SERDES_DBG_MFD("%s: failed to get enable gpio: %d\n",
155 			       __func__, ret);
156 
157 	ret = gpio_request_by_name(dev, "lock-gpios", 0, &serdes->lock_gpio,
158 				   GPIOD_IS_IN);
159 	if (ret)
160 		SERDES_DBG_MFD("%s: failed to get lock gpio: %d\n",
161 			       __func__, ret);
162 
163 	ret = gpio_request_by_name(dev, "err-gpios", 0, &serdes->err_gpio,
164 				   GPIOD_IS_IN);
165 	if (ret)
166 		SERDES_DBG_MFD("%s: failed to err gpio: %d\n",
167 			       __func__, ret);
168 
169 	if (serdes->chip_data->serdes_type != TYPE_SER)
170 		SERDES_DBG_MFD("warning: this chip is not ser type\n");
171 
172 	if (serdes->chip_data->serdes_type == TYPE_OTHER) {
173 		SERDES_DBG_MFD("TYPE_OTHER just need only init i2c\n");
174 		serdes_bridge_init(serdes);
175 		return 0;
176 	}
177 
178 	if (!serdes->chip_data->bridge_ops) {
179 		SERDES_DBG_MFD("%s %s no bridge ops\n",
180 			       __func__, serdes->chip_data->name);
181 		return -1;
182 	}
183 
184 	serdes_bridge = calloc(1, sizeof(*serdes_bridge));
185 	if (!serdes_bridge)
186 		return -ENOMEM;
187 
188 	serdes->sel_mipi = dev_read_bool(dev, "sel-mipi");
189 	if (serdes->sel_mipi) {
190 		struct mipi_dsi_device *device = dev_get_platdata(dev);
191 
192 		device->dev = dev;
193 		device->lanes = dev_read_u32_default(dev, "dsi,lanes", 4);
194 		device->format = dev_read_u32_default(dev, "dsi,format",
195 						      MIPI_DSI_FMT_RGB888);
196 		device->mode_flags = MIPI_DSI_MODE_VIDEO |
197 				     MIPI_DSI_MODE_VIDEO_BURST |
198 				     MIPI_DSI_MODE_VIDEO_HBP |
199 				     MIPI_DSI_MODE_LPM |
200 				     MIPI_DSI_MODE_EOT_PACKET;
201 		device->channel = dev_read_u32_default(dev, "reg", 0);
202 	}
203 
204 	bridge = calloc(1, sizeof(*bridge));
205 	if (!bridge)
206 		return -ENOMEM;
207 
208 	dev->driver_data = (ulong)bridge;
209 	bridge->dev = dev;
210 	bridge->funcs = &serdes_bridge_ops;
211 
212 	serdes->serdes_bridge = serdes_bridge;
213 	serdes->serdes_bridge->bridge = bridge;
214 
215 	serdes_pinctrl = calloc(1, sizeof(*serdes_pinctrl));
216 	if (!serdes_pinctrl)
217 		return -ENOMEM;
218 
219 	serdes->serdes_pinctrl = serdes_pinctrl;
220 
221 	ret = serdes_pinctrl_register(dev, serdes);
222 	if (ret)
223 		return ret;
224 
225 	ret = serdes_get_init_seq(serdes);
226 	if (ret)
227 		return ret;
228 
229 	if (serdes->chip_data->serdes_type == TYPE_SER)
230 		serdes_bridge_init(serdes);
231 
232 	printf("%s %s %s successful\n",
233 	       __func__,
234 	       serdes->dev->name,
235 	       serdes->chip_data->name);
236 
237 	return 0;
238 }
239 
240 static const struct udevice_id serdes_of_match[] = {
241 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18TL82)
242 	{ .compatible = "rohm,bu18tl82", .data = (ulong)&serdes_bu18tl82_data },
243 #endif
244 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18RL82)
245 	{ .compatible = "rohm,bu18rl82", .data = (ulong)&serdes_bu18rl82_data },
246 #endif
247 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96745)
248 	{ .compatible = "maxim,max96745", .data = (ulong)&serdes_max96745_data },
249 #endif
250 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96755)
251 	{ .compatible = "maxim,max96755", .data = (ulong)&serdes_max96755_data },
252 #endif
253 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX111)
254 	{ .compatible = "rockchip,rkx111", .data = (ulong)&serdes_rkx111_data },
255 #endif
256 	{ }
257 };
258 
259 U_BOOT_DRIVER(serdes_bridge) = {
260 	.name = "serdes-bridge",
261 	.id = UCLASS_VIDEO_BRIDGE,
262 	.of_match = serdes_of_match,
263 	.probe = serdes_bridge_probe,
264 	.priv_auto_alloc_size = sizeof(struct serdes),
265 	.platdata_auto_alloc_size = sizeof(struct mipi_dsi_device),
266 };
267