xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/serdes-core.c (revision 3f3f40cd59320e8b274fce3e3becf4dd08c2c8a4)
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 	for (i = 0; i < serdes->serdes_init_seq->reg_seq_cnt; i++) {
193 		if (serdes->serdes_init_seq->reg_sequence[i].reg == 0xffff) {
194 			SERDES_DBG_MFD("%s: delay 0x%04x us\n", __func__,
195 				       serdes->serdes_init_seq->reg_sequence[i].def);
196 			udelay(serdes->serdes_init_seq->reg_sequence[i].def);
197 			continue;
198 		}
199 
200 		ret = serdes_reg_write(serdes,
201 				       serdes->serdes_init_seq->reg_sequence[i].reg,
202 				       serdes->serdes_init_seq->reg_sequence[i].def);
203 
204 		if (ret < 0) {
205 			SERDES_DBG_MFD("failed to write reg %04x, ret %d\n",
206 				       serdes->serdes_init_seq->reg_sequence[i].reg, ret);
207 			ret = serdes_reg_write(serdes,
208 					       serdes->serdes_init_seq->reg_sequence[i].reg,
209 					       serdes->serdes_init_seq->reg_sequence[i].def);
210 		}
211 		serdes_reg_read(serdes, serdes->serdes_init_seq->reg_sequence[i].reg, &def);
212 		if ((def != serdes->serdes_init_seq->reg_sequence[i].def) || (ret < 0)) {
213 			/*if read value != write value then write again*/
214 			printf("%s read %04x %04x != %04x\n", serdes->dev->name,
215 			       serdes->serdes_init_seq->reg_sequence[i].reg,
216 			       def, serdes->serdes_init_seq->reg_sequence[i].def);
217 			ret = serdes_reg_write(serdes,
218 					       serdes->serdes_init_seq->reg_sequence[i].reg,
219 					       serdes->serdes_init_seq->reg_sequence[i].def);
220 		}
221 	}
222 
223 	/* workaround */
224 	if (serdes->chip_data->serdes_id == MAXIM_ID_MAX96752) {
225 		ret = serdes_reg_write(serdes, 0x10, 0x21);
226 		mdelay(10);
227 		printf("%s reset oneshot max96752\n", serdes->dev->name);
228 	}
229 
230 	SERDES_DBG_MFD("serdes %s sequence_init\n", serdes->dev->name);
231 
232 	return ret;
233 }
234 EXPORT_SYMBOL_GPL(serdes_i2c_set_sequence);
235 
236 int serdes_parse_init_seq(struct udevice *dev, const u16 *data,
237 			  int length, struct serdes_init_seq *seq)
238 {
239 	struct reg_sequence *reg_sequence;
240 	u16 *buf, *d;
241 	unsigned int i, cnt;
242 	int ret;
243 
244 	if (!seq)
245 		return -EINVAL;
246 
247 	buf = calloc(1, length);
248 	if (!buf)
249 		return -ENOMEM;
250 
251 	memcpy(buf, data, length);
252 
253 	d = buf;
254 	cnt = length / 4;
255 	seq->reg_seq_cnt = cnt;
256 
257 	seq->reg_sequence = calloc(cnt, sizeof(struct reg_sequence));
258 	if (!seq->reg_sequence) {
259 		ret = -ENOMEM;
260 		goto free_buf;
261 	}
262 
263 	for (i = 0; i < cnt; i++) {
264 		reg_sequence = &seq->reg_sequence[i];
265 		reg_sequence->reg = get_unaligned_be16(&d[0]);
266 		reg_sequence->def = get_unaligned_be16(&d[1]);
267 		d += 2;
268 	}
269 
270 	return 0;
271 
272 free_buf:
273 	free(buf);
274 
275 	return ret;
276 }
277 EXPORT_SYMBOL_GPL(serdes_parse_init_seq);
278 
279 int serdes_get_init_seq(struct serdes *serdes)
280 {
281 	const void *data = NULL;
282 	int len, err;
283 
284 	data = dev_read_prop(serdes->dev, "serdes-init-sequence", &len);
285 	if (!data) {
286 		printf("failed to get serdes-init-sequence\n");
287 		return -EINVAL;
288 	}
289 
290 	serdes->serdes_init_seq = calloc(1, sizeof(*serdes->serdes_init_seq));
291 	if (!serdes->serdes_init_seq)
292 		return -ENOMEM;
293 
294 	err = serdes_parse_init_seq(serdes->dev,
295 				    data, len, serdes->serdes_init_seq);
296 	if (err) {
297 		printf("failed to parse serdes-init-sequence\n");
298 		goto free_init_seq;
299 	}
300 
301 	return 0;
302 
303 free_init_seq:
304 	free(serdes->serdes_init_seq);
305 
306 	return err;
307 }
308 EXPORT_SYMBOL_GPL(serdes_get_init_seq);
309 
310 int serdes_gpio_register(struct udevice *dev,
311 			 struct serdes *serdes)
312 {
313 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
314 	struct uclass_driver *drv;
315 	int ret = -ENODEV;
316 	const char *name;
317 	ofnode subnode;
318 	struct udevice *subdev;
319 	struct udevice *gpio_dev;
320 
321 	SERDES_DBG_MFD("%s node=%s\n",
322 		       __func__, ofnode_get_name(dev->node));
323 
324 	/* Lookup GPIO driver */
325 	drv = lists_uclass_lookup(UCLASS_GPIO);
326 	if (!drv) {
327 		printf("Cannot find GPIO driver\n");
328 		return -ENOENT;
329 	}
330 
331 	dev_for_each_subnode(subnode, dev) {
332 		if (pre_reloc_only &&
333 		    !ofnode_pre_reloc(subnode))
334 			continue;
335 
336 		name = ofnode_get_name(subnode);
337 		if (!name)
338 			continue;
339 
340 		if (strstr(name, "gpio")) {
341 			ret = device_bind_driver_to_node(dev,
342 							 "serdes-gpio", name,
343 							 subnode, &subdev);
344 			if (ret)
345 				return ret;
346 
347 			ret = uclass_get_device_by_ofnode(UCLASS_GPIO,
348 							  subnode,
349 							  &gpio_dev);
350 			if (ret) {
351 				printf("%s failed to get gpio dev\n", __func__);
352 				return ret;
353 			}
354 
355 			SERDES_DBG_MFD("%s select %s gpio_dev=%s\n",
356 				       __func__, name, gpio_dev->name);
357 			return 0;
358 		}
359 	}
360 
361 	return ret;
362 }
363 EXPORT_SYMBOL_GPL(serdes_gpio_register);
364 
365 int serdes_pinctrl_register(struct udevice *dev,
366 			    struct serdes *serdes)
367 {
368 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
369 	struct uclass_driver *drv;
370 	int ret = -ENODEV;
371 	const char *name;
372 	ofnode subnode;
373 	struct udevice *subdev;
374 	struct udevice *pinctrl_dev;
375 
376 	SERDES_DBG_MFD("%s node=%s\n",
377 		       __func__, ofnode_get_name(dev->node));
378 
379 	/* Lookup PINCTRL driver */
380 	drv = lists_uclass_lookup(UCLASS_PINCTRL);
381 	if (!drv) {
382 		printf("Cannot find PINCTRL driver\n");
383 		return -ENOENT;
384 	}
385 
386 	dev_for_each_subnode(subnode, dev) {
387 		if (pre_reloc_only &&
388 		    !ofnode_pre_reloc(subnode))
389 			continue;
390 
391 		name = ofnode_get_name(subnode);
392 		if (!name)
393 			continue;
394 
395 		if (strstr(name, "pinctrl")) {
396 			ret = device_bind_driver_to_node(dev,
397 							 "serdes-pinctrl", name,
398 							 subnode, &subdev);
399 			if (ret)
400 				return ret;
401 
402 			ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL,
403 							  subnode,
404 							  &pinctrl_dev);
405 			if (ret) {
406 				printf("%s failed to get pinctrl\n", __func__);
407 				return ret;
408 			}
409 
410 			SERDES_DBG_MFD("%s select %s pinctrl_dev=%s\n",
411 				       __func__, name, pinctrl_dev->name);
412 			return 0;
413 		}
414 	}
415 
416 	return ret;
417 }
418 EXPORT_SYMBOL_GPL(serdes_pinctrl_register);
419 
420 static int serdes_i2c_init(struct serdes *serdes)
421 {
422 	int ret = 0;
423 	int i = 0;
424 
425 	if (serdes->vpower_supply)
426 		regulator_set_enable(serdes->vpower_supply, true);
427 
428 	if (dm_gpio_is_valid(&serdes->enable_gpio))
429 		dm_gpio_set_value(&serdes->enable_gpio, 1);
430 
431 	mdelay(5);
432 
433 	for (i = 0; i < 3; i++) {
434 		ret = serdes_i2c_set_sequence(serdes);
435 		if (!ret)
436 			break;
437 		mdelay(20);
438 	}
439 
440 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
441 		       serdes->chip_data->name);
442 
443 	return ret;
444 }
445 
446 static int serdes_i2c_probe(struct udevice *dev)
447 {
448 	struct serdes *serdes = dev_get_priv(dev);
449 	int ret;
450 
451 	ret = i2c_set_chip_offset_len(dev, 2);
452 	if (ret)
453 		return ret;
454 
455 	serdes->dev = dev;
456 	serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev);
457 	serdes->type = serdes->chip_data->serdes_type;
458 
459 	SERDES_DBG_MFD("serdes %s %s probe start\n",
460 		       serdes->dev->name, serdes->chip_data->name);
461 
462 	ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
463 					   "vpower-supply",
464 					   &serdes->vpower_supply);
465 	if (ret && ret != -ENOENT)
466 		SERDES_DBG_MFD("%s: Cannot get power supply: %d\n",
467 			       __func__, ret);
468 
469 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
470 				   &serdes->enable_gpio, GPIOD_IS_OUT);
471 	if (ret)
472 		SERDES_DBG_MFD("%s: failed to get enable gpio: %d\n",
473 			       __func__, ret);
474 
475 	ret = gpio_request_by_name(dev, "lock-gpios", 0,
476 				   &serdes->lock_gpio,
477 				   GPIOD_IS_IN);
478 	if (ret)
479 		SERDES_DBG_MFD("%s: failed to get lock gpio: %d\n",
480 			       __func__, ret);
481 
482 	ret = gpio_request_by_name(dev, "err-gpios", 0,
483 				   &serdes->err_gpio,
484 				   GPIOD_IS_IN);
485 	if (ret)
486 		SERDES_DBG_MFD("%s: failed to err gpio: %d\n",
487 			       __func__, ret);
488 
489 	ret = serdes_get_init_seq(serdes);
490 	if (ret)
491 		return ret;
492 
493 	serdes_i2c_init(serdes);
494 
495 	printf("%s %s successful, version %s\n",
496 	       __func__,
497 	       serdes->dev->name,
498 	       SERDES_UBOOT_DISPLAY_VERSION);
499 
500 	return 0;
501 }
502 
503 static const struct udevice_id serdes_of_match[] = {
504 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_NOVO_NCA9539)
505 	{ .compatible = "novo,nca9539", .data = (ulong)&serdes_nca9539_data },
506 #endif
507 	{ }
508 };
509 
510 U_BOOT_DRIVER(serdes_misc) = {
511 	.name = "serdes-misc",
512 	.id = UCLASS_MISC,
513 	.of_match = serdes_of_match,
514 	.probe = serdes_i2c_probe,
515 	.priv_auto_alloc_size = sizeof(struct serdes),
516 };
517 
518 int serdes_power_init(void)
519 {
520 	struct udevice *dev;
521 	int ret = 0;
522 
523 	ret = uclass_get_device_by_driver(UCLASS_MISC,
524 					  DM_GET_DRIVER(serdes_misc),
525 					  &dev);
526 	if (ret)
527 		printf("%s failed to get misc device ret=%d\n", __func__, ret);
528 
529 	return ret;
530 }
531