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