xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/rohm/rohm-bu18rl82.c (revision fb0c3269ba4cd093780cb50afda01fe0d30baa4b)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * rohm-bu18rl82.c  --  I2C register interface access for bu18rl82 serdes chip
4  *
5  * Copyright (c) 2023-2028 Rockchip Electronics Co. Ltd.
6  *
7  * Author: luowei <lw@rock-chips.com>
8  */
9 
10 #include "../core.h"
11 #include "rohm-bu18rl82.h"
12 
13 static int BU18RL82_GPIO0_pins[] = {0};
14 static int BU18RL82_GPIO1_pins[] = {1};
15 static int BU18RL82_GPIO2_pins[] = {2};
16 static int BU18RL82_GPIO3_pins[] = {3};
17 static int BU18RL82_GPIO4_pins[] = {4};
18 static int BU18RL82_GPIO5_pins[] = {5};
19 static int BU18RL82_GPIO6_pins[] = {6};
20 static int BU18RL82_GPIO7_pins[] = {7};
21 
22 #define GROUP_DESC(nm) \
23 { \
24 	.name = #nm, \
25 	.pins = nm ## _pins, \
26 	.num_pins = ARRAY_SIZE(nm ## _pins), \
27 }
28 
29 struct serdes_function_data {
30 	u8 gpio_rx_en:1;
31 	u16 gpio_id;
32 	u16 mdelay;
33 };
34 
35 static const char *serdes_gpio_groups[] = {
36 	"BU18RL82_GPIO0", "BU18RL82_GPIO1", "BU18RL82_GPIO2", "BU18RL82_GPIO3",
37 	"BU18RL82_GPIO4", "BU18RL82_GPIO5", "BU18RL82_GPIO6", "BU18RL82_GPIO7",
38 };
39 
40 /*des -> ser -> soc*/
41 #define FUNCTION_DESC_GPIO_INPUT(id) \
42 { \
43 	.name = "DES_TO_SER_GPIO"#id, \
44 	.group_names = serdes_gpio_groups, \
45 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
46 	.data = (void *)(const struct serdes_function_data []) { \
47 		{ .gpio_rx_en = 1, .gpio_id = id + 2 } \
48 	}, \
49 } \
50 
51 /*soc -> ser -> des*/
52 #define FUNCTION_DESC_GPIO_OUTPUT(id) \
53 { \
54 	.name = "SER_GPIO"#id"_TO_DES", \
55 	.group_names = serdes_gpio_groups, \
56 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
57 	.data = (void *)(const struct serdes_function_data []) { \
58 		{ .gpio_rx_en = 0, .gpio_id = id + 2 } \
59 	}, \
60 } \
61 
62 #define FUNCTION_DES_DELAY_MS(ms) \
63 { \
64 	.name = "DELAY_"#ms"MS", \
65 	.group_names = serdes_gpio_groups, \
66 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
67 	.data = (void *)(const struct serdes_function_data []) { \
68 		{ .mdelay = ms, } \
69 	}, \
70 } \
71 
72 /*des -> device*/
73 #define FUNCTION_DESC_GPIO_OUTPUT_HIGH() \
74 { \
75 	.name = "DES_GPIO_OUTPUT_HIGH", \
76 	.group_names = serdes_gpio_groups, \
77 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
78 	.data = (void *)(const struct serdes_function_data []) { \
79 		{ .gpio_rx_en = 0, .gpio_id = 1 } \
80 	}, \
81 } \
82 
83 #define FUNCTION_DESC_GPIO_OUTPUT_LOW() \
84 { \
85 	.name = "DES_GPIO_OUTPUT_LOW", \
86 	.group_names = serdes_gpio_groups, \
87 	.num_group_names = ARRAY_SIZE(serdes_gpio_groups), \
88 	.data = (void *)(const struct serdes_function_data []) { \
89 		{ .gpio_rx_en = 0, .gpio_id = 0 } \
90 	}, \
91 } \
92 
93 static struct pinctrl_pin_desc bu18rl82_pins_desc[] = {
94 	PINCTRL_PIN(ROHM_BU18RL82_GPIO0, "BU18RL82_GPIO0"),
95 	PINCTRL_PIN(ROHM_BU18RL82_GPIO1, "BU18RL82_GPIO1"),
96 	PINCTRL_PIN(ROHM_BU18RL82_GPIO2, "BU18RL82_GPIO2"),
97 	PINCTRL_PIN(ROHM_BU18RL82_GPIO3, "BU18RL82_GPIO3"),
98 	PINCTRL_PIN(ROHM_BU18RL82_GPIO4, "BU18RL82_GPIO4"),
99 	PINCTRL_PIN(ROHM_BU18RL82_GPIO5, "BU18RL82_GPIO5"),
100 	PINCTRL_PIN(ROHM_BU18RL82_GPIO6, "BU18RL82_GPIO6"),
101 	PINCTRL_PIN(ROHM_BU18RL82_GPIO7, "BU18RL82_GPIO7"),
102 };
103 
104 static struct group_desc bu18rl82_groups_desc[] = {
105 	GROUP_DESC(BU18RL82_GPIO0),
106 	GROUP_DESC(BU18RL82_GPIO1),
107 	GROUP_DESC(BU18RL82_GPIO2),
108 	GROUP_DESC(BU18RL82_GPIO3),
109 	GROUP_DESC(BU18RL82_GPIO4),
110 	GROUP_DESC(BU18RL82_GPIO5),
111 	GROUP_DESC(BU18RL82_GPIO6),
112 	GROUP_DESC(BU18RL82_GPIO7),
113 };
114 
115 static struct function_desc bu18rl82_functions_desc[] = {
116 	FUNCTION_DESC_GPIO_INPUT(0),
117 	FUNCTION_DESC_GPIO_INPUT(1),
118 	FUNCTION_DESC_GPIO_INPUT(2),
119 	FUNCTION_DESC_GPIO_INPUT(3),
120 	FUNCTION_DESC_GPIO_INPUT(4),
121 	FUNCTION_DESC_GPIO_INPUT(5),
122 	FUNCTION_DESC_GPIO_INPUT(6),
123 	FUNCTION_DESC_GPIO_INPUT(7),
124 	FUNCTION_DESC_GPIO_INPUT(8),
125 	FUNCTION_DESC_GPIO_INPUT(9),
126 	FUNCTION_DESC_GPIO_INPUT(10),
127 	FUNCTION_DESC_GPIO_INPUT(11),
128 	FUNCTION_DESC_GPIO_INPUT(12),
129 	FUNCTION_DESC_GPIO_INPUT(13),
130 	FUNCTION_DESC_GPIO_INPUT(14),
131 	FUNCTION_DESC_GPIO_INPUT(15),
132 
133 	FUNCTION_DESC_GPIO_OUTPUT(0),
134 	FUNCTION_DESC_GPIO_OUTPUT(1),
135 	FUNCTION_DESC_GPIO_OUTPUT(2),
136 	FUNCTION_DESC_GPIO_OUTPUT(3),
137 	FUNCTION_DESC_GPIO_OUTPUT(4),
138 	FUNCTION_DESC_GPIO_OUTPUT(5),
139 	FUNCTION_DESC_GPIO_OUTPUT(6),
140 	FUNCTION_DESC_GPIO_OUTPUT(7),
141 	FUNCTION_DESC_GPIO_OUTPUT(8),
142 	FUNCTION_DESC_GPIO_OUTPUT(9),
143 	FUNCTION_DESC_GPIO_OUTPUT(10),
144 	FUNCTION_DESC_GPIO_OUTPUT(11),
145 	FUNCTION_DESC_GPIO_OUTPUT(12),
146 	FUNCTION_DESC_GPIO_OUTPUT(13),
147 	FUNCTION_DESC_GPIO_OUTPUT(14),
148 	FUNCTION_DESC_GPIO_OUTPUT(15),
149 
150 	FUNCTION_DESC_GPIO_OUTPUT_HIGH(),
151 	FUNCTION_DESC_GPIO_OUTPUT_LOW(),
152 
153 	FUNCTION_DES_DELAY_MS(10),
154 	FUNCTION_DES_DELAY_MS(50),
155 	FUNCTION_DES_DELAY_MS(100),
156 	FUNCTION_DES_DELAY_MS(200),
157 	FUNCTION_DES_DELAY_MS(500),
158 };
159 
160 static struct serdes_chip_pinctrl_info bu18rl82_pinctrl_info = {
161 	.pins = bu18rl82_pins_desc,
162 	.num_pins = ARRAY_SIZE(bu18rl82_pins_desc),
163 	.groups = bu18rl82_groups_desc,
164 	.num_groups = ARRAY_SIZE(bu18rl82_groups_desc),
165 	.functions = bu18rl82_functions_desc,
166 	.num_functions = ARRAY_SIZE(bu18rl82_functions_desc),
167 };
168 
bu18rl82_bridge_swrst(struct serdes * serdes)169 void bu18rl82_bridge_swrst(struct serdes *serdes)
170 {
171 	int ret;
172 
173 	ret = serdes_reg_write(serdes, BU18RL82_REG_RESET,
174 			       BIT(0) | BIT(1) | BIT(7));
175 	if (ret < 0)
176 		printf("%s: failed to reset bu18rl82 0x11 ret=%d\n",
177 		       __func__, ret);
178 
179 	mdelay(20);
180 
181 	SERDES_DBG_CHIP("%s: serdes %s ret=%d\n",
182 			__func__, serdes->dev->name, ret);
183 }
184 
bu18rl82_enable_hwint(struct serdes * serdes,int enable)185 void bu18rl82_enable_hwint(struct serdes *serdes, int enable)
186 {
187 	int i, ret;
188 
189 	for (i = 0; i < ARRAY_SIZE(bu18rl82_reg_ien); i++) {
190 		if (enable) {
191 			ret = serdes_reg_write(serdes, bu18rl82_reg_ien[i].reg,
192 					       bu18rl82_reg_ien[i].ien);
193 			if (ret)
194 				printf("reg 0x%04x write error\n",
195 				       bu18rl82_reg_ien[i].reg);
196 		} else {
197 			ret = serdes_reg_write(serdes, bu18rl82_reg_ien[i].reg, 0);
198 			if (ret)
199 				printf("reg 0x%04x write error\n",
200 				       bu18rl82_reg_ien[i].reg);
201 		}
202 	}
203 
204 	SERDES_DBG_CHIP("%s: serdes %s ret=%d\n",
205 			__func__,
206 			serdes->dev->name, enable);
207 }
208 
bu18rl82_bridge_init(struct serdes * serdes)209 int bu18rl82_bridge_init(struct serdes *serdes)
210 {
211 	if (!dm_gpio_is_valid(&serdes->reset_gpio)) {
212 		bu18rl82_bridge_swrst(serdes);
213 		SERDES_DBG_CHIP("%s: serdes %s\n", __func__,
214 				serdes->dev->name);
215 	}
216 
217 	return 0;
218 }
219 
bu18rl82_bridge_enable(struct serdes * serdes)220 int bu18rl82_bridge_enable(struct serdes *serdes)
221 {
222 	int ret = 0;
223 
224 	/* 1:enable 0:dsiable*/
225 	bu18rl82_enable_hwint(serdes, 0);
226 
227 	SERDES_DBG_CHIP("%s: serdes %s ret=%d\n", __func__,
228 			serdes->dev->name, ret);
229 	return ret;
230 }
231 
bu18rl82_bridge_disable(struct serdes * serdes)232 int bu18rl82_bridge_disable(struct serdes *serdes)
233 {
234 	return 0;
235 }
236 
237 static struct serdes_chip_bridge_ops bu18rl82_bridge_ops = {
238 	.init = bu18rl82_bridge_init,
239 	.enable = bu18rl82_bridge_enable,
240 	.disable = bu18rl82_bridge_disable,
241 };
242 
bu18rl82_pinctrl_config_set(struct serdes * serdes,unsigned int pin_selector,unsigned int param,unsigned int argument)243 static int bu18rl82_pinctrl_config_set(struct serdes *serdes,
244 				       unsigned int pin_selector,
245 				       unsigned int param, unsigned int argument)
246 {
247 	switch (param) {
248 	case PIN_CONFIG_DRIVE_STRENGTH:
249 		serdes_set_bits(serdes, bu18rl82_gpio_sw[pin_selector].reg,
250 				bu18rl82_gpio_sw[pin_selector].mask,
251 				FIELD_PREP(BIT(2) | BIT(1), argument));
252 		SERDES_DBG_CHIP("%s: serdes %s pin=%d drive arg=0x%x\n",
253 				__func__,
254 				serdes->dev->name, pin_selector, argument);
255 		break;
256 	case PIN_CONFIG_BIAS_PULL_DOWN:
257 		serdes_set_bits(serdes, bu18rl82_gpio_pden[pin_selector].reg,
258 				bu18rl82_gpio_pden[pin_selector].mask,
259 				FIELD_PREP(BIT(4), argument));
260 		SERDES_DBG_CHIP("%s: serdes %s pin=%d pull-down arg=0x%x\n",
261 				__func__,
262 				serdes->dev->name, pin_selector, argument);
263 		break;
264 	case PIN_CONFIG_OUTPUT:
265 		serdes_set_bits(serdes, bu18rl82_gpio_oen[pin_selector].reg,
266 				bu18rl82_gpio_oen[pin_selector].mask,
267 				FIELD_PREP(BIT(3), argument));
268 		SERDES_DBG_CHIP("%s: serdes %s pin=%d output arg=0x%x\n",
269 				__func__,
270 				serdes->dev->name, pin_selector, argument);
271 		break;
272 	default:
273 		return -EOPNOTSUPP;
274 	}
275 
276 	return 0;
277 }
278 
bu18rl82_pinctrl_set_pin_mux(struct serdes * serdes,unsigned int pin_selector,unsigned int func_selector)279 static int bu18rl82_pinctrl_set_pin_mux(struct serdes *serdes,
280 					unsigned int pin_selector,
281 					unsigned int func_selector)
282 {
283 	struct function_desc *func;
284 	struct pinctrl_pin_desc *pin;
285 	int offset;
286 	u16 ms;
287 
288 	func = &serdes->chip_data->pinctrl_info->functions[func_selector];
289 	if (!func) {
290 		printf("%s: func is null\n", __func__);
291 		return -EINVAL;
292 	}
293 
294 	pin = &serdes->chip_data->pinctrl_info->pins[pin_selector];
295 	if (!pin) {
296 		printf("%s: pin is null\n", __func__);
297 		return -EINVAL;
298 	}
299 
300 	SERDES_DBG_CHIP("%s: serdes %s func=%s data=%p pin=%s num=%d\n",
301 			__func__, serdes->dev->name,
302 			func->name, func->data,
303 			pin->name, pin->number);
304 
305 	if (func->data) {
306 		struct serdes_function_data *fdata = func->data;
307 		ms = fdata->mdelay;
308 
309 		offset = pin->number;
310 		if (offset > 7)
311 			dev_err(serdes->dev, "%s offset=%d > 7\n",
312 				serdes->dev->name, offset);
313 		else
314 			SERDES_DBG_CHIP("%s: serdes %s id=0x%x off=%d\n",
315 					__func__, serdes->dev->name,
316 					fdata->gpio_id, offset);
317 		if (!ms) {
318 			serdes_set_bits(serdes, bu18rl82_gpio_oen[offset].reg,
319 					bu18rl82_gpio_oen[offset].mask,
320 					FIELD_PREP(BIT(3), fdata->gpio_rx_en));
321 			serdes_set_bits(serdes, bu18rl82_gpio_id_low[offset].reg,
322 					bu18rl82_gpio_id_low[offset].mask,
323 					FIELD_PREP(GENMASK(7, 0),
324 					(fdata->gpio_id & 0xff)));
325 			serdes_set_bits(serdes, bu18rl82_gpio_id_high[offset].reg,
326 					bu18rl82_gpio_id_high[offset].mask,
327 					FIELD_PREP(GENMASK(2, 0),
328 					((fdata->gpio_id >> 8) & 0x7)));
329 			serdes_set_bits(serdes, bu18rl82_gpio_pden[offset].reg,
330 					bu18rl82_gpio_pden[offset].mask,
331 					FIELD_PREP(BIT(4), 0));
332 		} else {
333 			mdelay(ms);
334 			SERDES_DBG_CHIP("%s: delay %dms\n", __func__, ms);
335 		}
336 	}
337 
338 	return 0;
339 }
340 
bu18rl82_pinctrl_set_grp_mux(struct serdes * serdes,unsigned int group_selector,unsigned int func_selector)341 static int bu18rl82_pinctrl_set_grp_mux(struct serdes *serdes,
342 					unsigned int group_selector,
343 					unsigned int func_selector)
344 {
345 	struct serdes_pinctrl *pinctrl = serdes->serdes_pinctrl;
346 	struct function_desc *func;
347 	struct group_desc *grp;
348 	int i, offset;
349 
350 	func = &serdes->chip_data->pinctrl_info->functions[func_selector];
351 	if (!func) {
352 		printf("%s: func is null\n", __func__);
353 		return -EINVAL;
354 	}
355 
356 	grp = &serdes->chip_data->pinctrl_info->groups[group_selector];
357 	if (!grp) {
358 		printf("%s: grp is null\n", __func__);
359 		return -EINVAL;
360 	}
361 
362 	SERDES_DBG_CHIP("%s: serdes %s func=%s data=%p grp=%s data=%p, num=%d\n",
363 			__func__, serdes->chip_data->name, func->name,
364 			func->data, grp->name, grp->data, grp->num_pins);
365 
366 	if (func->data) {
367 		struct serdes_function_data *fdata = func->data;
368 
369 		for (i = 0; i < grp->num_pins; i++) {
370 			offset = grp->pins[i] - pinctrl->pin_base;
371 			if (offset > 7)
372 				dev_err(serdes->dev, "%s offset=%d > 7\n",
373 					serdes->dev->name, offset);
374 			else
375 				SERDES_DBG_CHIP("%s: serdes %s id=0x%x, offset=%d\n",
376 						__func__,
377 						serdes->dev->name, fdata->gpio_id, offset);
378 			serdes_set_bits(serdes, bu18rl82_gpio_oen[offset].reg,
379 					bu18rl82_gpio_oen[offset].mask,
380 					FIELD_PREP(BIT(3), fdata->gpio_rx_en));
381 			serdes_set_bits(serdes, bu18rl82_gpio_id_low[offset].reg,
382 					bu18rl82_gpio_id_low[offset].mask,
383 					FIELD_PREP(GENMASK(7, 0),
384 					(fdata->gpio_id & 0xff)));
385 			serdes_set_bits(serdes, bu18rl82_gpio_id_high[offset].reg,
386 					bu18rl82_gpio_id_high[offset].mask,
387 					FIELD_PREP(GENMASK(2, 0),
388 					((fdata->gpio_id >> 8) & 0x7)));
389 			serdes_set_bits(serdes, bu18rl82_gpio_pden[offset].reg,
390 					bu18rl82_gpio_pden[offset].mask,
391 					FIELD_PREP(BIT(4), 0));
392 		}
393 	}
394 
395 	return 0;
396 }
397 
398 static struct serdes_chip_pinctrl_ops bu18rl82_pinctrl_ops = {
399 	.pinconf_set = bu18rl82_pinctrl_config_set,
400 	.pinmux_set = bu18rl82_pinctrl_set_pin_mux,
401 	.pinmux_group_set = bu18rl82_pinctrl_set_grp_mux,
402 };
403 
bu18rl82_gpio_direction_input(struct serdes * serdes,int gpio)404 static int bu18rl82_gpio_direction_input(struct serdes *serdes,
405 					 int gpio)
406 {
407 	return 0;
408 }
409 
bu18rl82_gpio_direction_output(struct serdes * serdes,int gpio,int value)410 static int bu18rl82_gpio_direction_output(struct serdes *serdes,
411 					  int gpio, int value)
412 {
413 	return 0;
414 }
415 
bu18rl82_gpio_get_level(struct serdes * serdes,int gpio)416 static int bu18rl82_gpio_get_level(struct serdes *serdes, int gpio)
417 {
418 	return 0;
419 }
420 
bu18rl82_gpio_set_level(struct serdes * serdes,int gpio,int value)421 int bu18rl82_gpio_set_level(struct serdes *serdes,
422 			    int gpio, int value)
423 {
424 	return 0;
425 }
426 
bu18rl82_gpio_set_config(struct serdes * serdes,int gpio,unsigned long config)427 static int bu18rl82_gpio_set_config(struct serdes *serdes,
428 				    int gpio, unsigned long config)
429 {
430 	return 0;
431 }
432 
bu18rl82_gpio_to_irq(struct serdes * serdes,int gpio)433 static int bu18rl82_gpio_to_irq(struct serdes *serdes, int gpio)
434 {
435 	return 0;
436 }
437 
438 static struct serdes_chip_gpio_ops bu18rl82_gpio_ops = {
439 	.direction_input = bu18rl82_gpio_direction_input,
440 	.direction_output = bu18rl82_gpio_direction_output,
441 	.get_level = bu18rl82_gpio_get_level,
442 	.set_level = bu18rl82_gpio_set_level,
443 	.set_config = bu18rl82_gpio_set_config,
444 	.to_irq = bu18rl82_gpio_to_irq,
445 };
446 
447 struct serdes_chip_data serdes_bu18rl82_data = {
448 	.name		= "bu18rl82",
449 	.serdes_type	= TYPE_DES,
450 	.serdes_id	= ROHM_ID_BU18RL82,
451 	.pinctrl_info	= &bu18rl82_pinctrl_info,
452 	.pinctrl_ops	= &bu18rl82_pinctrl_ops,
453 	.gpio_ops	= &bu18rl82_gpio_ops,
454 	.bridge_ops	= &bu18rl82_bridge_ops,
455 };
456 EXPORT_SYMBOL_GPL(serdes_bu18rl82_data);
457 
458 MODULE_LICENSE("GPL");
459