xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/rohm/rohm-bu18tl82.c (revision d1fd9c74759fc742c95117ea6373caa27c260a8c)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * rohm-bu18tl82.c  --  I2C register interface access for bu18tl82 serdes chip
4  *
5  * Copyright (c) 2023 Rockchip Electronics Co. Ltd.
6  *
7  * Author: luowei <lw@rock-chips.com>
8  */
9 
10 #include "../core.h"
11 #include "rohm-bu18tl82.h"
12 
13 #define PINCTRL_GROUP(a, b, c) { .name = a, .pins = b, .num_pins = c}
14 
15 static int BU18TL82_GPIO0_pins[] = {0};
16 static int BU18TL82_GPIO1_pins[] = {1};
17 static int BU18TL82_GPIO2_pins[] = {2};
18 static int BU18TL82_GPIO3_pins[] = {3};
19 static int BU18TL82_GPIO4_pins[] = {4};
20 static int BU18TL82_GPIO5_pins[] = {5};
21 static int BU18TL82_GPIO6_pins[] = {6};
22 static int BU18TL82_GPIO7_pins[] = {7};
23 
24 #define GROUP_DESC(nm) \
25 { \
26 	.name = #nm, \
27 	.pins = nm ## _pins, \
28 	.num_pins = ARRAY_SIZE(nm ## _pins), \
29 }
30 
31 struct serdes_function_data {
32 	u8 gpio_rx_en:1;
33 	u16 gpio_id;
34 };
35 
36 static const char *serdes_gpio_groups[] = {
37 	"BU18TL82_GPIO0", "BU18TL82_GPIO1", "BU18TL82_GPIO2", "BU18TL82_GPIO3",
38 	"BU18TL82_GPIO4", "BU18TL82_GPIO5", "BU18TL82_GPIO6", "BU18TL82_GPIO7",
39 };
40 
41 /*des -> ser -> soc*/
42 #define FUNCTION_DESC_GPIO_INPUT(id) \
43 { \
44 	.name = "DES_GPIO"#id"_TO_SER", \
45 	.group_names = serdes_gpio_groups, \
46 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
47 	.data = (void *)(const struct serdes_function_data []) { \
48 		{ .gpio_rx_en = 0, .gpio_id = (id < 8) ? (id + 2) : (id + 3) } \
49 	}, \
50 } \
51 
52 /*soc -> ser -> des*/
53 #define FUNCTION_DESC_GPIO_OUTPUT(id) \
54 { \
55 	.name = "SER_TO_DES_GPIO"#id, \
56 	.group_names = serdes_gpio_groups, \
57 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
58 	.data = (void *)(const struct serdes_function_data []) { \
59 		{ .gpio_rx_en = 1, .gpio_id = (id < 8) ? (id + 2) : (id + 3) } \
60 	}, \
61 } \
62 
63 static struct pinctrl_pin_desc bu18tl82_pins_desc[] = {
64 	PINCTRL_PIN(ROHM_BU18TL82_GPIO0, "BU18TL82_GPIO0"),
65 	PINCTRL_PIN(ROHM_BU18TL82_GPIO1, "BU18TL82_GPIO1"),
66 	PINCTRL_PIN(ROHM_BU18TL82_GPIO2, "BU18TL82_GPIO2"),
67 	PINCTRL_PIN(ROHM_BU18TL82_GPIO3, "BU18TL82_GPIO3"),
68 	PINCTRL_PIN(ROHM_BU18TL82_GPIO4, "BU18TL82_GPIO4"),
69 	PINCTRL_PIN(ROHM_BU18TL82_GPIO5, "BU18TL82_GPIO5"),
70 	PINCTRL_PIN(ROHM_BU18TL82_GPIO6, "BU18TL82_GPIO6"),
71 	PINCTRL_PIN(ROHM_BU18TL82_GPIO7, "BU18TL82_GPIO7"),
72 };
73 
74 static struct group_desc bu18tl82_groups_desc[] = {
75 	GROUP_DESC(BU18TL82_GPIO0),
76 	GROUP_DESC(BU18TL82_GPIO1),
77 	GROUP_DESC(BU18TL82_GPIO2),
78 	GROUP_DESC(BU18TL82_GPIO3),
79 	GROUP_DESC(BU18TL82_GPIO4),
80 	GROUP_DESC(BU18TL82_GPIO5),
81 	GROUP_DESC(BU18TL82_GPIO6),
82 	GROUP_DESC(BU18TL82_GPIO7),
83 };
84 
85 static struct function_desc bu18tl82_functions_desc[] = {
86 	FUNCTION_DESC_GPIO_INPUT(0),
87 	FUNCTION_DESC_GPIO_INPUT(1),
88 	FUNCTION_DESC_GPIO_INPUT(2),
89 	FUNCTION_DESC_GPIO_INPUT(3),
90 	FUNCTION_DESC_GPIO_INPUT(4),
91 	FUNCTION_DESC_GPIO_INPUT(5),
92 	FUNCTION_DESC_GPIO_INPUT(6),
93 	FUNCTION_DESC_GPIO_INPUT(7),
94 	FUNCTION_DESC_GPIO_INPUT(8),
95 	FUNCTION_DESC_GPIO_INPUT(9),
96 	FUNCTION_DESC_GPIO_INPUT(10),
97 	FUNCTION_DESC_GPIO_INPUT(11),
98 	FUNCTION_DESC_GPIO_INPUT(12),
99 	FUNCTION_DESC_GPIO_INPUT(13),
100 	FUNCTION_DESC_GPIO_INPUT(14),
101 	FUNCTION_DESC_GPIO_INPUT(15),
102 
103 	FUNCTION_DESC_GPIO_OUTPUT(0),
104 	FUNCTION_DESC_GPIO_OUTPUT(1),
105 	FUNCTION_DESC_GPIO_OUTPUT(2),
106 	FUNCTION_DESC_GPIO_OUTPUT(3),
107 	FUNCTION_DESC_GPIO_OUTPUT(4),
108 	FUNCTION_DESC_GPIO_OUTPUT(5),
109 	FUNCTION_DESC_GPIO_OUTPUT(6),
110 	FUNCTION_DESC_GPIO_OUTPUT(7),
111 	FUNCTION_DESC_GPIO_OUTPUT(8),
112 	FUNCTION_DESC_GPIO_OUTPUT(9),
113 	FUNCTION_DESC_GPIO_OUTPUT(10),
114 	FUNCTION_DESC_GPIO_OUTPUT(11),
115 	FUNCTION_DESC_GPIO_OUTPUT(12),
116 	FUNCTION_DESC_GPIO_OUTPUT(13),
117 	FUNCTION_DESC_GPIO_OUTPUT(14),
118 	FUNCTION_DESC_GPIO_OUTPUT(15),
119 };
120 
121 static struct serdes_chip_pinctrl_info bu18tl82_pinctrl_info = {
122 	.pins = bu18tl82_pins_desc,
123 	.num_pins = ARRAY_SIZE(bu18tl82_pins_desc),
124 	.groups = bu18tl82_groups_desc,
125 	.num_groups = ARRAY_SIZE(bu18tl82_groups_desc),
126 	.functions = bu18tl82_functions_desc,
127 	.num_functions = ARRAY_SIZE(bu18tl82_functions_desc),
128 };
129 
bu18tl82_bridge_swrst(struct serdes * serdes)130 void bu18tl82_bridge_swrst(struct serdes *serdes)
131 {
132 	int ret;
133 
134 	ret = serdes_reg_write(serdes, BU18TL82_REG_SWRST_INTERNAL, 0x00ef);
135 	if (ret < 0)
136 		dev_err(serdes->dev,
137 			"%s: failed to reset serdes 0x11 ret=%d\n",
138 			__func__, ret);
139 
140 	ret = serdes_reg_write(serdes, BU18TL82_REG_SWRST_MIPIRX, 0x0003);
141 	if (ret < 0)
142 		dev_err(serdes->dev,
143 			"%s: failed to reset serdes 0x12 ret=%d\n",
144 			__func__, ret);
145 
146 	mdelay(20);
147 
148 	SERDES_DBG_CHIP("%s: %s ret=%d\n",
149 			__func__, serdes->dev->name, ret);
150 }
151 
bu18tl82_enable_hwint(struct serdes * serdes,int enable)152 void bu18tl82_enable_hwint(struct serdes *serdes, int enable)
153 {
154 	int i, ret;
155 
156 	for (i = 0; i < ARRAY_SIZE(bu18tl82_reg_ien); i++) {
157 		if (enable) {
158 			ret = serdes_reg_write(serdes, bu18tl82_reg_ien[i].reg,
159 					       bu18tl82_reg_ien[i].ien);
160 			if (ret)
161 				printf("%s %s reg 0x%04x write error\n",
162 				       __func__,
163 				       serdes->dev->name, bu18tl82_reg_ien[i].reg);
164 		} else {
165 			ret = serdes_reg_write(serdes, bu18tl82_reg_ien[i].reg, 0);
166 			if (ret)
167 				printf("%s %s reg 0x%04x write error\n",
168 				       __func__,
169 				       serdes->dev->name, bu18tl82_reg_ien[i].reg);
170 		}
171 	}
172 
173 	SERDES_DBG_CHIP("%s: %s enable=%d\n", __func__,
174 			serdes->dev->name, enable);
175 }
176 
bu18tl82_bridge_init(struct serdes * serdes)177 int bu18tl82_bridge_init(struct serdes *serdes)
178 {
179 	if (!dm_gpio_is_valid(&serdes->reset_gpio))
180 		bu18tl82_bridge_swrst(serdes);
181 
182 	SERDES_DBG_CHIP("%s: %s\n", __func__,
183 			serdes->dev->name);
184 
185 	return 0;
186 }
187 
bu18tl82_bridge_enable(struct serdes * serdes)188 int bu18tl82_bridge_enable(struct serdes *serdes)
189 {
190 	return 0;
191 }
192 
bu18tl82_bridge_disable(struct serdes * serdes)193 int bu18tl82_bridge_disable(struct serdes *serdes)
194 {
195 	return 0;
196 }
197 
bu18tl82_bridge_get_modes(struct serdes * serdes)198 int bu18tl82_bridge_get_modes(struct serdes *serdes)
199 {
200 	return 0;
201 }
202 
bu18tl82_bridge_pre_enable(struct serdes * serdes)203 int bu18tl82_bridge_pre_enable(struct serdes *serdes)
204 {
205 	int ret = 0;
206 
207 	/* 1:enable 0:dsiable*/
208 	bu18tl82_enable_hwint(serdes, 0);
209 
210 	mdelay(160);
211 
212 	SERDES_DBG_CHIP("%s: %s ret=%d\n", __func__,
213 			serdes->dev->name, ret);
214 
215 	return ret;
216 }
217 
bu18tl82_bridge_detect(struct serdes * serdes,int link)218 bool bu18tl82_bridge_detect(struct serdes *serdes, int link)
219 {
220 	return true;
221 }
222 
223 static struct serdes_chip_bridge_ops bu18tl82_bridge_ops = {
224 	.init = bu18tl82_bridge_init,
225 	.get_modes = bu18tl82_bridge_get_modes,
226 	.pre_enable = bu18tl82_bridge_pre_enable,
227 	.enable = bu18tl82_bridge_enable,
228 	.disable = bu18tl82_bridge_disable,
229 	.detect = bu18tl82_bridge_detect,
230 };
231 
bu18tl82_pinctrl_config_set(struct serdes * serdes,unsigned int pin_selector,unsigned int param,unsigned int argument)232 static int bu18tl82_pinctrl_config_set(struct serdes *serdes,
233 				       unsigned int pin_selector,
234 				       unsigned int param, unsigned int argument)
235 {
236 	switch (param) {
237 	case PIN_CONFIG_DRIVE_STRENGTH:
238 		serdes_set_bits(serdes, bu18tl82_gpio_sw[pin_selector].reg,
239 				bu18tl82_gpio_sw[pin_selector].mask,
240 				FIELD_PREP(BIT(2) | BIT(1), argument));
241 		SERDES_DBG_CHIP("%s: serdes %s pin=%d drv arg=0x%x\n",
242 				 __func__,
243 				 serdes->dev->name, pin_selector, argument);
244 		break;
245 	case PIN_CONFIG_BIAS_PULL_DOWN:
246 		serdes_set_bits(serdes, bu18tl82_gpio_pden[pin_selector].reg,
247 				bu18tl82_gpio_pden[pin_selector].mask,
248 				FIELD_PREP(BIT(4), argument));
249 		SERDES_DBG_CHIP("%s: serdes %s pin=%d pull-down arg=0x%x\n",
250 				 __func__,
251 				 serdes->dev->name, pin_selector, argument);
252 		break;
253 
254 	case PIN_CONFIG_OUTPUT:
255 		serdes_set_bits(serdes, bu18tl82_gpio_oen[pin_selector].reg,
256 				bu18tl82_gpio_oen[pin_selector].mask,
257 				FIELD_PREP(BIT(3), argument));
258 		SERDES_DBG_CHIP("%s: serdes %s pin=%d output arg=0x%x\n",
259 				 __func__,
260 				 serdes->dev->name, pin_selector, argument);
261 		break;
262 	default:
263 		return -EOPNOTSUPP;
264 	}
265 
266 	return 0;
267 }
268 
bu18tl82_pinctrl_set_pin_mux(struct serdes * serdes,unsigned int pin_selector,unsigned int func_selector)269 static int bu18tl82_pinctrl_set_pin_mux(struct serdes *serdes,
270 					unsigned int pin_selector,
271 					unsigned int func_selector)
272 {
273 	struct function_desc *func;
274 	struct pinctrl_pin_desc *pin;
275 	int offset;
276 
277 	func = &serdes->chip_data->pinctrl_info->functions[func_selector];
278 	if (!func) {
279 		printf("%s: func is null\n", __func__);
280 		return -EINVAL;
281 	}
282 
283 	pin = &serdes->chip_data->pinctrl_info->pins[pin_selector];
284 	if (!pin) {
285 		printf("%s: pin is null\n", __func__);
286 		return -EINVAL;
287 	}
288 
289 	SERDES_DBG_CHIP("%s: serdes %s func=%s data=%p pin=%s num=%d\n",
290 			__func__, serdes->dev->name,
291 			func->name, func->data,
292 			pin->name, pin->number);
293 
294 	if (func->data) {
295 		struct serdes_function_data *fdata = func->data;
296 
297 		offset = pin->number;
298 		if (offset > 7)
299 			dev_err(serdes->dev, "%s gpio offset=%d > 7\n",
300 				serdes->dev->name, offset);
301 		else
302 			SERDES_DBG_CHIP("%s: serdes %s gpio=0x%x, off=%d\n",
303 					__func__, serdes->dev->name,
304 					fdata->gpio_id, offset);
305 		serdes_set_bits(serdes, bu18tl82_gpio_oen[offset].reg,
306 				bu18tl82_gpio_oen[offset].mask,
307 				FIELD_PREP(BIT(3), fdata->gpio_rx_en));
308 		serdes_set_bits(serdes, bu18tl82_gpio_id_low[offset].reg,
309 				bu18tl82_gpio_id_low[offset].mask,
310 				FIELD_PREP(GENMASK(7, 0),
311 				(fdata->gpio_id & 0xff)));
312 		serdes_set_bits(serdes, bu18tl82_gpio_id_high[offset].reg,
313 				bu18tl82_gpio_id_high[offset].mask,
314 				FIELD_PREP(GENMASK(2, 0),
315 				((fdata->gpio_id >> 8) & 0x7)));
316 		serdes_set_bits(serdes, bu18tl82_gpio_pden[offset].reg,
317 				bu18tl82_gpio_pden[offset].mask,
318 				FIELD_PREP(BIT(4), 0));
319 	}
320 
321 	return 0;
322 }
323 
bu18tl82_pinctrl_set_grp_mux(struct serdes * serdes,unsigned int group_selector,unsigned int func_selector)324 static int bu18tl82_pinctrl_set_grp_mux(struct serdes *serdes,
325 					unsigned int group_selector,
326 					unsigned int func_selector)
327 {
328 	struct serdes_pinctrl *pinctrl = serdes->serdes_pinctrl;
329 	struct function_desc *func;
330 	struct group_desc *grp;
331 	int i, offset;
332 
333 	func = &serdes->chip_data->pinctrl_info->functions[func_selector];
334 	if (!func) {
335 		printf("%s: func is null\n", __func__);
336 		return -EINVAL;
337 	}
338 
339 	grp = &serdes->chip_data->pinctrl_info->groups[group_selector];
340 	if (!grp) {
341 		printf("%s: grp is null\n", __func__);
342 		return -EINVAL;
343 	}
344 
345 	SERDES_DBG_CHIP("%s: serdes %s func=%s data=%p grp=%s data=%p, num=%d\n",
346 			__func__, serdes->dev->name,
347 			func->name, func->data,
348 			grp->name, grp->data, grp->num_pins);
349 
350 	if (func->data) {
351 		struct serdes_function_data *fdata = func->data;
352 
353 		for (i = 0; i < grp->num_pins; i++) {
354 			offset = grp->pins[i] - pinctrl->pin_base;
355 			if (offset > 7)
356 				dev_err(serdes->dev, "%s gpio offset=%d > 7\n",
357 					serdes->dev->name, offset);
358 			else
359 				SERDES_DBG_CHIP("%s serdes %s io=0x%x off=%d\n",
360 						__func__, serdes->dev->name,
361 						fdata->gpio_id, offset);
362 			serdes_set_bits(serdes, bu18tl82_gpio_oen[offset].reg,
363 					bu18tl82_gpio_oen[offset].mask,
364 					FIELD_PREP(BIT(3), fdata->gpio_rx_en));
365 			serdes_set_bits(serdes, bu18tl82_gpio_id_low[offset].reg,
366 					bu18tl82_gpio_id_low[offset].mask,
367 					FIELD_PREP(GENMASK(7, 0),
368 					(fdata->gpio_id & 0xff)));
369 			serdes_set_bits(serdes, bu18tl82_gpio_id_high[offset].reg,
370 					bu18tl82_gpio_id_high[offset].mask,
371 					FIELD_PREP(GENMASK(2, 0),
372 					((fdata->gpio_id >> 8) & 0x7)));
373 			serdes_set_bits(serdes, bu18tl82_gpio_pden[offset].reg,
374 					bu18tl82_gpio_pden[offset].mask,
375 					FIELD_PREP(BIT(4), 0));
376 		}
377 	}
378 
379 	return 0;
380 }
381 
382 static struct serdes_chip_pinctrl_ops bu18tl82_pinctrl_ops = {
383 	.pinconf_set = bu18tl82_pinctrl_config_set,
384 	.pinmux_set = bu18tl82_pinctrl_set_pin_mux,
385 	.pinmux_group_set = bu18tl82_pinctrl_set_grp_mux,
386 };
387 
bu18tl82_gpio_direction_input(struct serdes * serdes,int gpio)388 static int bu18tl82_gpio_direction_input(struct serdes *serdes, int gpio)
389 {
390 	return 0;
391 }
392 
bu18tl82_gpio_direction_output(struct serdes * serdes,int gpio,int value)393 static int bu18tl82_gpio_direction_output(struct serdes *serdes,
394 					  int gpio, int value)
395 {
396 	return 0;
397 }
398 
bu18tl82_gpio_get_level(struct serdes * serdes,int gpio)399 static int bu18tl82_gpio_get_level(struct serdes *serdes, int gpio)
400 {
401 	return 0;
402 }
403 
bu18tl82_gpio_set_level(struct serdes * serdes,int gpio,int value)404 static int bu18tl82_gpio_set_level(struct serdes *serdes,
405 				   int gpio, int value)
406 {
407 	return 0;
408 }
409 
bu18tl82_gpio_set_config(struct serdes * serdes,int gpio,unsigned long config)410 static int bu18tl82_gpio_set_config(struct serdes *serdes,
411 				    int gpio, unsigned long config)
412 {
413 	return 0;
414 }
415 
bu18tl82_gpio_to_irq(struct serdes * serdes,int gpio)416 static int bu18tl82_gpio_to_irq(struct serdes *serdes, int gpio)
417 {
418 	return 0;
419 }
420 
421 static struct serdes_chip_gpio_ops bu18tl82_gpio_ops = {
422 	.direction_input = bu18tl82_gpio_direction_input,
423 	.direction_output = bu18tl82_gpio_direction_output,
424 	.get_level = bu18tl82_gpio_get_level,
425 	.set_level = bu18tl82_gpio_set_level,
426 	.set_config = bu18tl82_gpio_set_config,
427 	.to_irq = bu18tl82_gpio_to_irq,
428 };
429 
430 struct serdes_chip_data serdes_bu18tl82_data = {
431 	.name		= "bu18tl82",
432 	.serdes_type	= TYPE_SER,
433 	.serdes_id	= ROHM_ID_BU18TL82,
434 	.pinctrl_info	= &bu18tl82_pinctrl_info,
435 	.bridge_ops	= &bu18tl82_bridge_ops,
436 	.pinctrl_ops	= &bu18tl82_pinctrl_ops,
437 	.gpio_ops	= &bu18tl82_gpio_ops,
438 };
439 EXPORT_SYMBOL_GPL(serdes_bu18tl82_data);
440 
441 MODULE_LICENSE("GPL");
442