xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/serdes-core.c (revision cf55f2e8d05973d6046c8006d83cc6dcf08c7b5d)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * serdes-i2c.c  --  display i2c 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 "core.h"
11 
12 static int dm_i2c_reg_write_u8(struct udevice *dev, u8 reg, u8 val)
13 {
14 	int ret;
15 	u8 buf[2];
16 	struct i2c_msg msg;
17 	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
18 
19 	buf[0] = reg;
20 	buf[1] = val;
21 	msg.addr = chip->chip_addr;
22 	msg.flags = 0;
23 	msg.len = 2;
24 	msg.buf = buf;
25 
26 	ret = dm_i2c_xfer(dev, &msg, 1);
27 	if (ret) {
28 		printf("dm i2c write failed: %d\n", ret);
29 		return ret;
30 	}
31 
32 	return 0;
33 }
34 
35 static uint8_t dm_i2c_reg_read_u8(struct udevice *dev, u8 reg)
36 {
37 	int ret;
38 	u8 data;
39 	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
40 	struct i2c_msg msg[] = {
41 		{
42 			.addr = chip->chip_addr,
43 			.flags = 0,
44 			.buf = (u8 *)&reg,
45 			.len = 1,
46 		}, {
47 			.addr = chip->chip_addr,
48 			.flags = I2C_M_RD,
49 			.buf = (u8 *)&data,
50 			.len = 1,
51 		}
52 	};
53 
54 	ret = dm_i2c_xfer(dev, msg, 2);
55 	if (ret) {
56 		printf("dm i2c read failed: %d\n", ret);
57 		return ret;
58 	}
59 
60 	return data;
61 }
62 
63 static int dm_i2c_reg_clrset_u8(struct udevice *dev,
64 				u8 offset,
65 				u8 clr, u8 set)
66 {
67 	u8 val;
68 
69 	val = dm_i2c_reg_read_u8(dev, offset);
70 	if (val < 0)
71 		return val;
72 
73 	val &= ~clr;
74 	val |= set;
75 
76 	return dm_i2c_reg_write_u8(dev, offset, val);
77 }
78 
79 /**
80  * serdes_reg_read: Read a single serdes register.
81  *
82  * @serdes: Device to read from.
83  * @reg: Register to read.
84  * @val: Date read from register.
85  */
86 int serdes_reg_read(struct serdes *serdes,
87 		    unsigned int reg, unsigned int *val)
88 {
89 	unsigned int value;
90 
91 	if (serdes->chip_data->reg_val_type == REG_8BIT_VAL_8IT)
92 		value = dm_i2c_reg_read_u8(serdes->dev, reg);
93 	else
94 		value = dm_i2c_reg_read(serdes->dev, reg);
95 
96 	*val = value;
97 	SERDES_DBG_I2C("%s %s %s Read Reg%04x %04x\n",
98 		       __func__, serdes->dev->name,
99 		       serdes->dev->name, reg, *val);
100 	return 0;
101 }
102 EXPORT_SYMBOL_GPL(serdes_reg_read);
103 
104 /**
105  * serdes_reg_write: Write a single serdes register.
106  *
107  * @serdes: Device to write to.
108  * @reg: Register to write to.
109  * @val: Value to write.
110  */
111 int serdes_reg_write(struct serdes *serdes, unsigned int reg,
112 		     unsigned int val)
113 {
114 	int ret = 0;
115 
116 	SERDES_DBG_I2C("%s %s Write Reg%04x %04x) type=%d\n",
117 		       __func__, serdes->dev->name,
118 		       reg, val, serdes->chip_data->reg_val_type);
119 	if (serdes->chip_data->reg_val_type == REG_8BIT_VAL_8IT) {
120 		ret = dm_i2c_reg_write_u8(serdes->dev, reg, val);
121 		if (ret != 0)
122 			return ret;
123 	} else {
124 		ret = dm_i2c_reg_write(serdes->dev, reg, val);
125 		if (ret != 0)
126 			return ret;
127 	}
128 
129 	return ret;
130 }
131 EXPORT_SYMBOL_GPL(serdes_reg_write);
132 
133 /**
134  * serdes_multi_reg_write: Write many serdes register.
135  *
136  * @serdes: Device to write to.
137  * @regs: Registers to write to.
138  * @num_regs: Number of registers to write.
139  */
140 int serdes_multi_reg_write(struct serdes *serdes,
141 			   const struct reg_sequence *regs,
142 			   int num_regs)
143 {
144 	int i, ret = 0;
145 
146 	SERDES_DBG_I2C("%s %s %s num=%d\n", __func__, serdes->dev->name,
147 		       serdes->chip_data->name, num_regs);
148 
149 	for (i = 0; i < num_regs; i++) {
150 		ret = serdes_reg_write(serdes, regs[i].reg, regs[i].def);
151 		SERDES_DBG_I2C("serdes %s Write Reg%04x %04x ret=%d\n",
152 			       serdes->chip_data->name,
153 			       regs[i].reg, regs[i].def, ret);
154 	}
155 
156 	return ret;
157 }
158 EXPORT_SYMBOL_GPL(serdes_multi_reg_write);
159 
160 /**
161  * serdes_set_bits: Set the value of a bitfield in a serdes register
162  *
163  * @serdes: Device to write to.
164  * @reg: Register to write to.
165  * @mask: Mask of bits to set.
166  * @val: Value to set (unshifted)
167  */
168 int serdes_set_bits(struct serdes *serdes, unsigned int reg,
169 		    unsigned int mask, unsigned int val)
170 {
171 	int ret = 0;
172 
173 	SERDES_DBG_I2C("%s %s %s Write Reg%04x %04x) mask=%04x\n",
174 		       __func__,
175 		       serdes->dev->name,
176 		       serdes->dev->name, reg, val, mask);
177 
178 	if (serdes->chip_data->reg_val_type == REG_8BIT_VAL_8IT)
179 		ret = dm_i2c_reg_clrset_u8(serdes->dev, reg, mask, val);
180 	else
181 		ret = dm_i2c_reg_clrset(serdes->dev, reg, mask, val);
182 
183 	return ret;
184 }
185 EXPORT_SYMBOL_GPL(serdes_set_bits);
186 
187 int serdes_i2c_set_sequence(struct serdes *serdes)
188 {
189 	int i, ret = 0;
190 	unsigned int def = 0;
191 
192 	if(serdes->mcu_enable) {
193 		printf("serdes %s i2c set sequence in MCU\n", serdes->dev->name);
194 		return 0;
195 	}
196 
197 	for (i = 0; i < serdes->serdes_init_seq->reg_seq_cnt; i++) {
198 		if (serdes->serdes_init_seq->reg_sequence[i].reg == 0xffff) {
199 			SERDES_DBG_MFD("%s: delay 0x%04x us\n", __func__,
200 				       serdes->serdes_init_seq->reg_sequence[i].def);
201 			udelay(serdes->serdes_init_seq->reg_sequence[i].def);
202 			continue;
203 		}
204 
205 		ret = serdes_reg_write(serdes,
206 				       serdes->serdes_init_seq->reg_sequence[i].reg,
207 				       serdes->serdes_init_seq->reg_sequence[i].def);
208 
209 		if (ret < 0) {
210 			SERDES_DBG_MFD("failed to write reg %04x, ret %d\n",
211 				       serdes->serdes_init_seq->reg_sequence[i].reg, ret);
212 			ret = serdes_reg_write(serdes,
213 					       serdes->serdes_init_seq->reg_sequence[i].reg,
214 					       serdes->serdes_init_seq->reg_sequence[i].def);
215 		}
216 		serdes_reg_read(serdes, serdes->serdes_init_seq->reg_sequence[i].reg, &def);
217 		if ((def != serdes->serdes_init_seq->reg_sequence[i].def) || (ret < 0)) {
218 			/*if read value != write value then write again*/
219 			printf("%s read %04x %04x != %04x\n", serdes->dev->name,
220 			       serdes->serdes_init_seq->reg_sequence[i].reg,
221 			       def, serdes->serdes_init_seq->reg_sequence[i].def);
222 			ret = serdes_reg_write(serdes,
223 					       serdes->serdes_init_seq->reg_sequence[i].reg,
224 					       serdes->serdes_init_seq->reg_sequence[i].def);
225 		}
226 	}
227 
228 	/* workaround */
229 	if (serdes->chip_data->serdes_id == MAXIM_ID_MAX96752) {
230 		ret = serdes_reg_write(serdes, 0x10, 0x21);
231 		mdelay(10);
232 		printf("%s reset oneshot max96752\n", serdes->dev->name);
233 	}
234 
235 	SERDES_DBG_MFD("serdes %s sequence_init\n", serdes->dev->name);
236 
237 	return ret;
238 }
239 EXPORT_SYMBOL_GPL(serdes_i2c_set_sequence);
240 
241 int serdes_parse_init_seq(struct udevice *dev, const u16 *data,
242 			  int length, struct serdes_init_seq *seq)
243 {
244 	struct reg_sequence *reg_sequence;
245 	u16 *buf, *d;
246 	unsigned int i, cnt;
247 	int ret;
248 
249 	if (!seq)
250 		return -EINVAL;
251 
252 	buf = calloc(1, length);
253 	if (!buf)
254 		return -ENOMEM;
255 
256 	memcpy(buf, data, length);
257 
258 	d = buf;
259 	cnt = length / 4;
260 	seq->reg_seq_cnt = cnt;
261 
262 	seq->reg_sequence = calloc(cnt, sizeof(struct reg_sequence));
263 	if (!seq->reg_sequence) {
264 		ret = -ENOMEM;
265 		goto free_buf;
266 	}
267 
268 	for (i = 0; i < cnt; i++) {
269 		reg_sequence = &seq->reg_sequence[i];
270 		reg_sequence->reg = get_unaligned_be16(&d[0]);
271 		reg_sequence->def = get_unaligned_be16(&d[1]);
272 		d += 2;
273 	}
274 
275 	return 0;
276 
277 free_buf:
278 	free(buf);
279 
280 	return ret;
281 }
282 EXPORT_SYMBOL_GPL(serdes_parse_init_seq);
283 
284 int serdes_get_init_seq(struct serdes *serdes)
285 {
286 	const void *data = NULL;
287 	int len, err;
288 
289 	data = dev_read_prop(serdes->dev, "serdes-init-sequence", &len);
290 	if (!data) {
291 		printf("failed to get serdes-init-sequence\n");
292 		return -EINVAL;
293 	}
294 
295 	serdes->serdes_init_seq = calloc(1, sizeof(*serdes->serdes_init_seq));
296 	if (!serdes->serdes_init_seq)
297 		return -ENOMEM;
298 
299 	err = serdes_parse_init_seq(serdes->dev,
300 				    data, len, serdes->serdes_init_seq);
301 	if (err) {
302 		printf("failed to parse serdes-init-sequence\n");
303 		goto free_init_seq;
304 	}
305 
306 	return 0;
307 
308 free_init_seq:
309 	free(serdes->serdes_init_seq);
310 
311 	return err;
312 }
313 EXPORT_SYMBOL_GPL(serdes_get_init_seq);
314 
315 int serdes_gpio_register(struct udevice *dev,
316 			 struct serdes *serdes)
317 {
318 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
319 	struct uclass_driver *drv;
320 	int ret = -ENODEV;
321 	const char *name;
322 	ofnode subnode;
323 	struct udevice *subdev;
324 	struct udevice *gpio_dev;
325 
326 	SERDES_DBG_MFD("%s node=%s\n",
327 		       __func__, ofnode_get_name(dev->node));
328 
329 	/* Lookup GPIO driver */
330 	drv = lists_uclass_lookup(UCLASS_GPIO);
331 	if (!drv) {
332 		printf("Cannot find GPIO driver\n");
333 		return -ENOENT;
334 	}
335 
336 	dev_for_each_subnode(subnode, dev) {
337 		if (pre_reloc_only &&
338 		    !ofnode_pre_reloc(subnode))
339 			continue;
340 
341 		name = ofnode_get_name(subnode);
342 		if (!name)
343 			continue;
344 
345 		if (strstr(name, "gpio")) {
346 			ret = device_bind_driver_to_node(dev,
347 							 "serdes-gpio", name,
348 							 subnode, &subdev);
349 			if (ret)
350 				return ret;
351 
352 			ret = uclass_get_device_by_ofnode(UCLASS_GPIO,
353 							  subnode,
354 							  &gpio_dev);
355 			if (ret) {
356 				printf("%s failed to get gpio dev\n", __func__);
357 				return ret;
358 			}
359 
360 			SERDES_DBG_MFD("%s select %s gpio_dev=%s\n",
361 				       __func__, name, gpio_dev->name);
362 			return 0;
363 		}
364 	}
365 
366 	return ret;
367 }
368 EXPORT_SYMBOL_GPL(serdes_gpio_register);
369 
370 int serdes_pinctrl_register(struct udevice *dev,
371 			    struct serdes *serdes)
372 {
373 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
374 	struct uclass_driver *drv;
375 	int ret = -ENODEV;
376 	const char *name;
377 	ofnode subnode;
378 	struct udevice *subdev;
379 	struct udevice *pinctrl_dev;
380 
381 	SERDES_DBG_MFD("%s node=%s\n",
382 		       __func__, ofnode_get_name(dev->node));
383 
384 	/* Lookup PINCTRL driver */
385 	drv = lists_uclass_lookup(UCLASS_PINCTRL);
386 	if (!drv) {
387 		printf("Cannot find PINCTRL driver\n");
388 		return -ENOENT;
389 	}
390 
391 	dev_for_each_subnode(subnode, dev) {
392 		if (pre_reloc_only &&
393 		    !ofnode_pre_reloc(subnode))
394 			continue;
395 
396 		name = ofnode_get_name(subnode);
397 		if (!name)
398 			continue;
399 
400 		if (strstr(name, "pinctrl")) {
401 			ret = device_bind_driver_to_node(dev,
402 							 "serdes-pinctrl", name,
403 							 subnode, &subdev);
404 			if (ret)
405 				return ret;
406 
407 			ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL,
408 							  subnode,
409 							  &pinctrl_dev);
410 			if (ret) {
411 				printf("%s failed to get pinctrl\n", __func__);
412 				return ret;
413 			}
414 
415 			SERDES_DBG_MFD("%s select %s pinctrl_dev=%s\n",
416 				       __func__, name, pinctrl_dev->name);
417 			return 0;
418 		}
419 	}
420 
421 	return ret;
422 }
423 EXPORT_SYMBOL_GPL(serdes_pinctrl_register);
424 
425 static int serdes_i2c_init(struct serdes *serdes)
426 {
427 	int ret = 0;
428 	int i = 0;
429 
430 	if (serdes->vpower_supply)
431 		regulator_set_enable(serdes->vpower_supply, true);
432 
433 	if (dm_gpio_is_valid(&serdes->enable_gpio))
434 		dm_gpio_set_value(&serdes->enable_gpio, 1);
435 
436 	mdelay(5);
437 
438 	for (i = 0; i < 3; i++) {
439 		ret = serdes_i2c_set_sequence(serdes);
440 		if (!ret)
441 			break;
442 		mdelay(20);
443 	}
444 
445 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
446 		       serdes->chip_data->name);
447 
448 	return ret;
449 }
450 
451 static int serdes_i2c_probe(struct udevice *dev)
452 {
453 	struct serdes *serdes = dev_get_priv(dev);
454 	int ret;
455 
456 	ret = i2c_set_chip_offset_len(dev, 2);
457 	if (ret)
458 		return ret;
459 
460 	serdes->dev = dev;
461 	serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev);
462 	serdes->type = serdes->chip_data->serdes_type;
463 
464 	SERDES_DBG_MFD("serdes %s %s probe start\n",
465 		       serdes->dev->name, serdes->chip_data->name);
466 
467 	ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
468 					   "vpower-supply",
469 					   &serdes->vpower_supply);
470 	if (ret && ret != -ENOENT)
471 		SERDES_DBG_MFD("%s: Cannot get power supply: %d\n",
472 			       __func__, ret);
473 
474 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
475 				   &serdes->enable_gpio, GPIOD_IS_OUT);
476 	if (ret)
477 		SERDES_DBG_MFD("%s: failed to get enable gpio: %d\n",
478 			       __func__, ret);
479 
480 	ret = gpio_request_by_name(dev, "lock-gpios", 0,
481 				   &serdes->lock_gpio,
482 				   GPIOD_IS_IN);
483 	if (ret)
484 		SERDES_DBG_MFD("%s: failed to get lock gpio: %d\n",
485 			       __func__, ret);
486 
487 	ret = gpio_request_by_name(dev, "err-gpios", 0,
488 				   &serdes->err_gpio,
489 				   GPIOD_IS_IN);
490 	if (ret)
491 		SERDES_DBG_MFD("%s: failed to err gpio: %d\n",
492 			       __func__, ret);
493 
494 	ret = serdes_get_init_seq(serdes);
495 	if (ret)
496 		return ret;
497 
498 	serdes_i2c_init(serdes);
499 
500 	printf("%s %s successful, version %s\n",
501 	       __func__,
502 	       serdes->dev->name,
503 	       SERDES_UBOOT_DISPLAY_VERSION);
504 
505 	return 0;
506 }
507 
508 static const struct udevice_id serdes_of_match[] = {
509 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_NOVO_NCA9539)
510 	{ .compatible = "novo,nca9539", .data = (ulong)&serdes_nca9539_data },
511 #endif
512 	{ }
513 };
514 
515 U_BOOT_DRIVER(serdes_misc) = {
516 	.name = "serdes-misc",
517 	.id = UCLASS_MISC,
518 	.of_match = serdes_of_match,
519 	.probe = serdes_i2c_probe,
520 	.priv_auto_alloc_size = sizeof(struct serdes),
521 };
522 
523 int serdes_power_init(void)
524 {
525 	struct udevice *dev;
526 	int ret = 0;
527 
528 	ret = uclass_get_device_by_driver(UCLASS_MISC,
529 					  DM_GET_DRIVER(serdes_misc),
530 					  &dev);
531 	if (ret)
532 		printf("%s failed to get misc device ret=%d\n", __func__, ret);
533 
534 	return ret;
535 }
536