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