xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/serdes-i2c.c (revision 77c57384925823ac7325dead6d2664651a86d016)
1a00ee452SLuo Wei // SPDX-License-Identifier: GPL-2.0-or-later
2a00ee452SLuo Wei /*
3fb0c3269SLuo 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 
12fb0c3269SLuo Wei static struct serdes *g_serdes_ser_split[MAX_NUM_SERDES_SPLIT];
13fb0c3269SLuo Wei 
serdes_i2c_init(struct serdes * serdes)14fb0c3269SLuo Wei static void serdes_i2c_init(struct serdes *serdes)
15a00ee452SLuo Wei {
16a00ee452SLuo Wei 	if (serdes->vpower_supply)
17a00ee452SLuo Wei 		regulator_set_enable(serdes->vpower_supply, true);
18a00ee452SLuo Wei 
19a00ee452SLuo Wei 	if (dm_gpio_is_valid(&serdes->enable_gpio))
20a00ee452SLuo Wei 		dm_gpio_set_value(&serdes->enable_gpio, 1);
21a00ee452SLuo Wei 
22fb0c3269SLuo Wei 	//mdelay(5);
23a00ee452SLuo Wei 
24fb0c3269SLuo Wei 	//video_bridge_set_active(serdes->dev, true);
25fb0c3269SLuo Wei 
26fb0c3269SLuo Wei 	if (serdes->chip_data->bridge_ops->init)
27fb0c3269SLuo Wei 		serdes->chip_data->bridge_ops->init(serdes);
28fb0c3269SLuo Wei 
29fb0c3269SLuo Wei 	serdes_i2c_set_sequence(serdes);
30fb0c3269SLuo Wei 
31fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s %s\n", __func__,
32fb0c3269SLuo Wei 		       serdes->dev->name,
33fb0c3269SLuo Wei 		       serdes->chip_data->name);
34a00ee452SLuo Wei }
35a00ee452SLuo Wei 
serdes_set_i2c_address(struct serdes * serdes,u32 reg_hw,u32 reg_use,int link)36fb0c3269SLuo Wei static int serdes_set_i2c_address(struct serdes *serdes,
37fb0c3269SLuo Wei 				  u32 reg_hw, u32 reg_use, int link)
38fb0c3269SLuo Wei {
39fb0c3269SLuo Wei 	int ret = 0;
40fb0c3269SLuo Wei 	struct dm_i2c_chip *chip_split;
41fb0c3269SLuo Wei 	struct serdes *serdes_split = serdes->g_serdes_bridge_split;
42fb0c3269SLuo Wei 
43fb0c3269SLuo Wei 	if (!serdes_split) {
44fb0c3269SLuo Wei 		pr_info("%s: serdes_split is null\n", __func__);
45fb0c3269SLuo Wei 		return -1;
46fb0c3269SLuo Wei 	}
47fb0c3269SLuo Wei 
48fb0c3269SLuo Wei 	chip_split = dev_get_parent_platdata(serdes->dev);
49fb0c3269SLuo Wei 	SERDES_DBG_MFD("%s: %s addr=0x%x reg_hw=0x%x, reg_use=0x%x split=0x%p\n",
50fb0c3269SLuo Wei 		       __func__, serdes_split->dev->name,
51fb0c3269SLuo Wei 		       chip_split->chip_addr, serdes->reg_hw,
52fb0c3269SLuo Wei 		       serdes->reg_use, serdes_split);
53fb0c3269SLuo Wei 
54fb0c3269SLuo Wei 	chip_split->chip_addr = serdes->reg_hw;
55fb0c3269SLuo Wei 
56fb0c3269SLuo Wei 	if (serdes_split && serdes_split->chip_data->split_ops &&
57fb0c3269SLuo Wei 	    serdes_split->chip_data->split_ops->select)
58fb0c3269SLuo Wei 		ret = serdes_split->chip_data->split_ops->select(serdes_split, link);
59fb0c3269SLuo Wei 
60fb0c3269SLuo Wei 	if (serdes->chip_data->split_ops &&
61fb0c3269SLuo Wei 	    serdes->chip_data->split_ops->set_i2c_addr)
62fb0c3269SLuo Wei 		serdes->chip_data->split_ops->set_i2c_addr(serdes,
63fb0c3269SLuo Wei 							   reg_use, link);
64fb0c3269SLuo Wei 
65fb0c3269SLuo Wei 	if (serdes_split && serdes_split->chip_data->split_ops &&
66fb0c3269SLuo Wei 	    serdes_split->chip_data->split_ops->select)
67fb0c3269SLuo Wei 		ret = serdes_split->chip_data->split_ops->select(serdes_split,
68fb0c3269SLuo Wei 								 SER_SPLITTER_MODE);
69fb0c3269SLuo Wei 
70fb0c3269SLuo Wei 	chip_split->chip_addr = serdes->reg_use;
71fb0c3269SLuo Wei 
72fb0c3269SLuo Wei 	serdes_i2c_set_sequence(serdes);
73a00ee452SLuo Wei 
74a00ee452SLuo Wei 	return ret;
75a00ee452SLuo Wei }
76a00ee452SLuo Wei 
serdes_i2c_probe(struct udevice * dev)77a00ee452SLuo Wei static int serdes_i2c_probe(struct udevice *dev)
78a00ee452SLuo Wei {
79a00ee452SLuo Wei 	struct serdes *serdes = dev_get_priv(dev);
80fb0c3269SLuo Wei 	struct serdes_bridge *serdes_bridge = NULL;
81fb0c3269SLuo Wei 	struct serdes_bridge_split *serdes_bridge_split = NULL;
82*77c57384SZitong Cai 
83a00ee452SLuo Wei 	int ret;
84a00ee452SLuo Wei 
85a00ee452SLuo Wei 	ret = i2c_set_chip_offset_len(dev, 2);
86a00ee452SLuo Wei 	if (ret)
87a00ee452SLuo Wei 		return ret;
88a00ee452SLuo Wei 
89a00ee452SLuo Wei 	serdes->dev = dev;
90a00ee452SLuo Wei 	serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev);
91a00ee452SLuo Wei 	serdes->type = serdes->chip_data->serdes_type;
92a00ee452SLuo Wei 
93fb0c3269SLuo Wei 	SERDES_DBG_MFD("serdes %s %s probe start serdes=%p\n",
94fb0c3269SLuo Wei 		       serdes->dev->name, serdes->chip_data->name, serdes);
95a00ee452SLuo Wei 
96a00ee452SLuo Wei 	ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
97a00ee452SLuo Wei 					   "vpower-supply",
98a00ee452SLuo Wei 					   &serdes->vpower_supply);
99a00ee452SLuo Wei 	if (ret && ret != -ENOENT)
100a00ee452SLuo Wei 		SERDES_DBG_MFD("%s: Cannot get power supply: %d\n",
101a00ee452SLuo Wei 			       __func__, ret);
102a00ee452SLuo Wei 
103a00ee452SLuo Wei 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
104a00ee452SLuo Wei 				   &serdes->enable_gpio, GPIOD_IS_OUT);
105a00ee452SLuo Wei 	if (ret)
106a00ee452SLuo Wei 		SERDES_DBG_MFD("%s: failed to get enable gpio: %d\n",
107a00ee452SLuo Wei 			       __func__, ret);
108a00ee452SLuo Wei 
109fb0c3269SLuo Wei 	ret = gpio_request_by_name(dev, "lock-gpios", 0, &serdes->lock_gpio,
110a00ee452SLuo Wei 				   GPIOD_IS_IN);
111a00ee452SLuo Wei 	if (ret)
112a00ee452SLuo Wei 		SERDES_DBG_MFD("%s: failed to get lock gpio: %d\n",
113a00ee452SLuo Wei 			       __func__, ret);
114a00ee452SLuo Wei 
115fb0c3269SLuo Wei 	ret = gpio_request_by_name(dev, "err-gpios", 0, &serdes->err_gpio,
116a00ee452SLuo Wei 				   GPIOD_IS_IN);
117a00ee452SLuo Wei 	if (ret)
118a00ee452SLuo Wei 		SERDES_DBG_MFD("%s: failed to err gpio: %d\n",
119a00ee452SLuo Wei 			       __func__, ret);
120a00ee452SLuo Wei 
1213fc0646aSZitong Cai 	serdes->mcu_enable = dev_read_bool(dev, "mcu-enable");
1223fc0646aSZitong Cai 
123fb0c3269SLuo Wei 	if (serdes->chip_data->serdes_type == TYPE_OTHER) {
124fb0c3269SLuo Wei 		SERDES_DBG_MFD("TYPE_OTHER just need only init i2c\n");
125fb0c3269SLuo Wei 		serdes_i2c_init(serdes);
126fb0c3269SLuo Wei 		return 0;
127fb0c3269SLuo Wei 	}
128fb0c3269SLuo Wei 
129a00ee452SLuo Wei 	ret = serdes_get_init_seq(serdes);
130a00ee452SLuo Wei 	if (ret)
131a00ee452SLuo Wei 		return ret;
132a00ee452SLuo Wei 
133fb0c3269SLuo Wei 	if (serdes->chip_data->serdes_type == TYPE_SER)
134a00ee452SLuo Wei 		serdes_i2c_init(serdes);
135a00ee452SLuo Wei 
136fb0c3269SLuo Wei 	if (serdes->chip_data->bridge_ops) {
137fb0c3269SLuo Wei 		serdes_bridge = calloc(1, sizeof(*serdes_bridge));
138fb0c3269SLuo Wei 		if (!serdes_bridge)
139fb0c3269SLuo Wei 			return -ENOMEM;
140fb0c3269SLuo Wei 		serdes->serdes_bridge = serdes_bridge;
141fb0c3269SLuo Wei 
142fb0c3269SLuo Wei 		serdes_bridge_split = calloc(1, sizeof(*serdes_bridge_split));
143fb0c3269SLuo Wei 		if (!serdes_bridge_split)
144fb0c3269SLuo Wei 			return -ENOMEM;
145fb0c3269SLuo Wei 		serdes->serdes_bridge_split = serdes_bridge_split;
146fb0c3269SLuo Wei 	}
147fb0c3269SLuo Wei 
148*77c57384SZitong Cai 	ret = serdes_pinctrl_register(dev);
149fb0c3269SLuo Wei 	if (ret)
150fb0c3269SLuo Wei 		return ret;
151fb0c3269SLuo Wei 
152fb0c3269SLuo Wei 	serdes->id_serdes_bridge_split = dev_read_u32_default(dev, "id-serdes-bridge-split", 0);
153fb0c3269SLuo Wei 	if ((serdes->id_serdes_bridge_split < MAX_NUM_SERDES_SPLIT) && (serdes->type == TYPE_SER)) {
154fb0c3269SLuo Wei 		g_serdes_ser_split[serdes->id_serdes_bridge_split] = serdes;
155fb0c3269SLuo Wei 		SERDES_DBG_MFD("%s: %s-%s g_serdes_split[%d]=0x%p\n", __func__,
156fb0c3269SLuo Wei 			       serdes->dev->name, serdes->chip_data->name,
157fb0c3269SLuo Wei 			       serdes->id_serdes_bridge_split, serdes);
158fb0c3269SLuo Wei 	}
159fb0c3269SLuo Wei 
160fb0c3269SLuo Wei 	serdes->reg_hw = dev_read_u32_default(dev, "reg-hw", 0);
161fb0c3269SLuo Wei 	serdes->reg_use = dev_read_u32_default(dev, "reg", 0);
162fb0c3269SLuo Wei 	serdes->link_use = dev_read_u32_default(dev, "link", 0);
163fb0c3269SLuo Wei 	serdes->id_serdes_panel_split = dev_read_u32_default(dev, "id-serdes-panel-split", 0);
164fb0c3269SLuo Wei 
165fb0c3269SLuo Wei 	if ((serdes->id_serdes_panel_split) && (serdes->type == TYPE_DES)) {
166fb0c3269SLuo Wei 		serdes->g_serdes_bridge_split = g_serdes_ser_split[serdes->id_serdes_panel_split];
167fb0c3269SLuo Wei 		SERDES_DBG_MFD("%s: id=%d p=0x%p\n", __func__,
168fb0c3269SLuo Wei 			       serdes->id_serdes_panel_split,
169fb0c3269SLuo Wei 			       serdes->g_serdes_bridge_split);
170fb0c3269SLuo Wei 	}
171fb0c3269SLuo Wei 
172fb0c3269SLuo Wei 	if (serdes->reg_hw) {
173fb0c3269SLuo Wei 		SERDES_DBG_MFD("%s: %s change i2c addr from 0x%x to 0x%x\n",
174fb0c3269SLuo Wei 			       __func__, dev->name,
175fb0c3269SLuo Wei 			       serdes->reg_hw, serdes->reg_use);
176fb0c3269SLuo Wei 		serdes_set_i2c_address(serdes, serdes->reg_hw,
177fb0c3269SLuo Wei 				       serdes->reg_use, serdes->link_use);
178fb0c3269SLuo Wei 	}
179fb0c3269SLuo Wei 
180fb0c3269SLuo Wei 	printf("%s %s %s successful\n",
181a00ee452SLuo Wei 	       __func__,
182a00ee452SLuo Wei 	       serdes->dev->name,
183fb0c3269SLuo Wei 	       serdes->chip_data->name);
184a00ee452SLuo Wei 
185a00ee452SLuo Wei 	return 0;
186a00ee452SLuo Wei }
187a00ee452SLuo Wei 
188a00ee452SLuo Wei static const struct udevice_id serdes_of_match[] = {
189fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18TL82)
190fb0c3269SLuo Wei 	{ .compatible = "rohm,bu18tl82",
191fb0c3269SLuo Wei 		.data = (ulong)&serdes_bu18tl82_data },
192fb0c3269SLuo Wei #endif
193fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18RL82)
194fb0c3269SLuo Wei 	{ .compatible = "rohm,bu18rl82",
195fb0c3269SLuo Wei 		.data = (ulong)&serdes_bu18rl82_data },
196fb0c3269SLuo Wei #endif
197fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96745)
198fb0c3269SLuo Wei 	{ .compatible = "maxim,max96745",
199fb0c3269SLuo Wei 		.data = (ulong)&serdes_max96745_data },
200fb0c3269SLuo Wei #endif
201fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96755)
202fb0c3269SLuo Wei 	{ .compatible = "maxim,max96755",
203fb0c3269SLuo Wei 		.data = (ulong)&serdes_max96755_data },
204fb0c3269SLuo Wei #endif
205fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96789)
206fb0c3269SLuo Wei 	{ .compatible = "maxim,max96789",
207fb0c3269SLuo Wei 		.data = (ulong)&serdes_max96789_data },
208fb0c3269SLuo Wei #endif
209fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX111)
210fb0c3269SLuo Wei 	{ .compatible = "rockchip,rkx111",
211fb0c3269SLuo Wei 		.data = (ulong)&serdes_rkx111_data },
212fb0c3269SLuo Wei #endif
213fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96752)
214fb0c3269SLuo Wei 	{ .compatible = "maxim,max96752",
215fb0c3269SLuo Wei 		.data = (ulong)&serdes_max96752_data },
216fb0c3269SLuo Wei #endif
217fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96772)
218fb0c3269SLuo Wei 	{ .compatible = "maxim,max96772",
219fb0c3269SLuo Wei 		.data = (ulong)&serdes_max96772_data },
220fb0c3269SLuo Wei #endif
221fb0c3269SLuo Wei #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX121)
222fb0c3269SLuo Wei 	{ .compatible = "rockchip,rkx121",
223fb0c3269SLuo Wei 		.data = (ulong)&serdes_rkx121_data },
224a00ee452SLuo Wei #endif
225a00ee452SLuo Wei 	{ }
226a00ee452SLuo Wei };
227a00ee452SLuo Wei 
228fb0c3269SLuo Wei U_BOOT_DRIVER(serdes_i2c) = {
229fb0c3269SLuo Wei 	.name = "serdes-i2c",
230a00ee452SLuo Wei 	.id = UCLASS_MISC,
231a00ee452SLuo Wei 	.of_match = serdes_of_match,
232a00ee452SLuo Wei 	.probe = serdes_i2c_probe,
233fb0c3269SLuo Wei 	.bind = dm_scan_fdt_dev,
234a00ee452SLuo Wei 	.priv_auto_alloc_size = sizeof(struct serdes),
235a00ee452SLuo Wei };
236