xref: /rk3399_rockchip-uboot/drivers/video/drm/display-serdes/serdes-i2c.c (revision b77c257eaed4fb83d4f17aeb4ad71b3a8a7e38e6)
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 <serdes-display-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 %s Write Reg%04x %04x)\n",
117 		       __func__, serdes->dev->name,
118 		       serdes->dev->name, reg, val);
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_set_bits: Set the value of a bitfield in a serdes register
135  *
136  * @serdes: Device to write to.
137  * @reg: Register to write to.
138  * @mask: Mask of bits to set.
139  * @val: Value to set (unshifted)
140  */
141 int serdes_set_bits(struct serdes *serdes, unsigned int reg,
142 		    unsigned int mask, unsigned int val)
143 {
144 	int ret = 0;
145 
146 	SERDES_DBG_I2C("%s %s %s Write Reg%04x %04x) mask=%04x\n",
147 		       __func__,
148 		       serdes->dev->name,
149 		       serdes->dev->name, reg, val, mask);
150 
151 	if (serdes->chip_data->reg_val_type == REG_8BIT_VAL_8IT)
152 		ret = dm_i2c_reg_clrset_u8(serdes->dev, reg, mask, val);
153 	else
154 		ret = dm_i2c_reg_clrset(serdes->dev, reg, mask, val);
155 
156 	return ret;
157 }
158 EXPORT_SYMBOL_GPL(serdes_set_bits);
159 
160 int serdes_i2c_set_sequence(struct serdes *serdes)
161 {
162 	int i, ret = 0;
163 	unsigned int def = 0;
164 
165 	for (i = 0; i < serdes->serdes_init_seq->reg_seq_cnt; i++) {
166 		if (serdes->serdes_init_seq->reg_sequence[i].reg == 0xffff) {
167 			SERDES_DBG_MFD("%s: delay 0x%04x us\n", __func__,
168 				       serdes->serdes_init_seq->reg_sequence[i].def);
169 			udelay(serdes->serdes_init_seq->reg_sequence[i].def);
170 			continue;
171 		}
172 
173 		ret = serdes_reg_write(serdes,
174 				       serdes->serdes_init_seq->reg_sequence[i].reg,
175 				       serdes->serdes_init_seq->reg_sequence[i].def);
176 
177 		if (ret < 0) {
178 			SERDES_DBG_MFD("failed to write reg %04x, ret %d, again\n",
179 				       serdes->serdes_init_seq->reg_sequence[i].reg, ret);
180 			ret = serdes_reg_write(serdes,
181 					       serdes->serdes_init_seq->reg_sequence[i].reg,
182 					       serdes->serdes_init_seq->reg_sequence[i].def);
183 		}
184 		serdes_reg_read(serdes, serdes->serdes_init_seq->reg_sequence[i].reg, &def);
185 		if ((def != serdes->serdes_init_seq->reg_sequence[i].def) || (ret < 0)) {
186 			/*if read value != write value then write again*/
187 			printf("%s read %04x %04x != %04x\n", serdes->dev->name,
188 			       serdes->serdes_init_seq->reg_sequence[i].reg,
189 			       def, serdes->serdes_init_seq->reg_sequence[i].def);
190 			ret = serdes_reg_write(serdes,
191 					       serdes->serdes_init_seq->reg_sequence[i].reg,
192 					       serdes->serdes_init_seq->reg_sequence[i].def);
193 		}
194 	}
195 
196 	SERDES_DBG_MFD("serdes %s sequence_init\n", serdes->dev->name);
197 
198 	return ret;
199 }
200 EXPORT_SYMBOL_GPL(serdes_i2c_set_sequence);
201 
202 int serdes_parse_init_seq(struct udevice *dev, const u16 *data,
203 			  int length, struct serdes_init_seq *seq)
204 {
205 	struct reg_sequence *reg_sequence;
206 	u16 *buf, *d;
207 	unsigned int i, cnt;
208 	int ret;
209 
210 	if (!seq)
211 		return -EINVAL;
212 
213 	buf = calloc(1, length);
214 	if (!buf)
215 		return -ENOMEM;
216 
217 	memcpy(buf, data, length);
218 
219 	d = buf;
220 	cnt = length / 4;
221 	seq->reg_seq_cnt = cnt;
222 
223 	seq->reg_sequence = calloc(cnt, sizeof(struct reg_sequence));
224 	if (!seq->reg_sequence) {
225 		ret = -ENOMEM;
226 		goto free_buf;
227 	}
228 
229 	for (i = 0; i < cnt; i++) {
230 		reg_sequence = &seq->reg_sequence[i];
231 		reg_sequence->reg = get_unaligned_be16(&d[0]);
232 		reg_sequence->def = get_unaligned_be16(&d[1]);
233 		d += 2;
234 	}
235 
236 	return 0;
237 
238 free_buf:
239 	free(buf);
240 
241 	return ret;
242 }
243 EXPORT_SYMBOL_GPL(serdes_parse_init_seq);
244 
245 int serdes_get_init_seq(struct serdes *serdes)
246 {
247 	const void *data = NULL;
248 	int len, err;
249 
250 	data = dev_read_prop(serdes->dev, "serdes-init-sequence", &len);
251 	if (!data) {
252 		printf("failed to get serdes-init-sequence\n");
253 		return -EINVAL;
254 	}
255 
256 	serdes->serdes_init_seq = calloc(1, sizeof(*serdes->serdes_init_seq));
257 	if (!serdes->serdes_init_seq)
258 		return -ENOMEM;
259 
260 	err = serdes_parse_init_seq(serdes->dev,
261 				    data, len, serdes->serdes_init_seq);
262 	if (err) {
263 		printf("failed to parse serdes-init-sequence\n");
264 		goto free_init_seq;
265 	}
266 
267 	return 0;
268 
269 free_init_seq:
270 	free(serdes->serdes_init_seq);
271 
272 	return err;
273 }
274 EXPORT_SYMBOL_GPL(serdes_get_init_seq);
275 
276 int serdes_gpio_register(struct udevice *dev,
277 			 struct serdes *serdes)
278 {
279 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
280 	struct uclass_driver *drv;
281 	int ret = -ENODEV;
282 	const char *name;
283 	ofnode subnode;
284 	struct udevice *subdev;
285 	struct udevice *gpio_dev;
286 
287 	SERDES_DBG_MFD("%s node=%s\n",
288 		       __func__, ofnode_get_name(dev->node));
289 
290 	/* Lookup GPIO driver */
291 	drv = lists_uclass_lookup(UCLASS_GPIO);
292 	if (!drv) {
293 		printf("Cannot find GPIO driver\n");
294 		return -ENOENT;
295 	}
296 
297 	dev_for_each_subnode(subnode, dev) {
298 		if (pre_reloc_only &&
299 		    !ofnode_pre_reloc(subnode))
300 			continue;
301 
302 		name = ofnode_get_name(subnode);
303 		if (!name)
304 			continue;
305 
306 		if (strstr(name, "gpio")) {
307 			ret = device_bind_driver_to_node(dev,
308 							 "serdes-gpio", name,
309 							 subnode, &subdev);
310 			if (ret)
311 				return ret;
312 
313 			ret = uclass_get_device_by_ofnode(UCLASS_GPIO,
314 							  subnode,
315 							  &gpio_dev);
316 			if (ret) {
317 				printf("%s failed to get gpio dev\n", __func__);
318 				return ret;
319 			}
320 
321 			SERDES_DBG_MFD("%s select %s gpio_dev=%s\n",
322 				       __func__, name, gpio_dev->name);
323 			return 0;
324 		}
325 	}
326 
327 	return ret;
328 }
329 EXPORT_SYMBOL_GPL(serdes_gpio_register);
330 
331 int serdes_pinctrl_register(struct udevice *dev,
332 			    struct serdes *serdes)
333 {
334 	bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
335 	struct uclass_driver *drv;
336 	int ret = -ENODEV;
337 	const char *name;
338 	ofnode subnode;
339 	struct udevice *subdev;
340 	struct udevice *pinctrl_dev;
341 
342 	SERDES_DBG_MFD("%s node=%s\n",
343 		       __func__, ofnode_get_name(dev->node));
344 
345 	/* Lookup PINCTRL driver */
346 	drv = lists_uclass_lookup(UCLASS_PINCTRL);
347 	if (!drv) {
348 		printf("Cannot find PINCTRL driver\n");
349 		return -ENOENT;
350 	}
351 
352 	dev_for_each_subnode(subnode, dev) {
353 		if (pre_reloc_only &&
354 		    !ofnode_pre_reloc(subnode))
355 			continue;
356 
357 		name = ofnode_get_name(subnode);
358 		if (!name)
359 			continue;
360 
361 		if (strstr(name, "pinctrl")) {
362 			ret = device_bind_driver_to_node(dev,
363 							 "serdes-pinctrl", name,
364 							 subnode, &subdev);
365 			if (ret)
366 				return ret;
367 
368 			ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL,
369 							  subnode,
370 							  &pinctrl_dev);
371 			if (ret) {
372 				printf("%s failed to get pinctrl\n", __func__);
373 				return ret;
374 			}
375 
376 			SERDES_DBG_MFD("%s select %s pinctrl_dev=%s\n",
377 				       __func__, name, pinctrl_dev->name);
378 			return 0;
379 		}
380 	}
381 
382 	return ret;
383 }
384 EXPORT_SYMBOL_GPL(serdes_pinctrl_register);
385 
386 static int serdes_i2c_init(struct serdes *serdes)
387 {
388 	int ret = 0;
389 	int i = 0;
390 
391 	if (serdes->vpower_supply)
392 		regulator_set_enable(serdes->vpower_supply, true);
393 
394 	if (dm_gpio_is_valid(&serdes->enable_gpio))
395 		dm_gpio_set_value(&serdes->enable_gpio, 1);
396 
397 	mdelay(5);
398 
399 	for (i = 0; i < 5; i++) {
400 		ret = serdes_i2c_set_sequence(serdes);
401 		if (!ret)
402 			break;
403 		else
404 			mdelay(20);
405 	}
406 
407 	SERDES_DBG_MFD("%s: %s %s\n", __func__, serdes->dev->name,
408 		       serdes->chip_data->name);
409 
410 	return ret;
411 }
412 
413 static int serdes_i2c_probe(struct udevice *dev)
414 {
415 	struct serdes *serdes = dev_get_priv(dev);
416 	int ret;
417 
418 	ret = i2c_set_chip_offset_len(dev, 2);
419 	if (ret)
420 		return ret;
421 
422 	serdes->dev = dev;
423 	serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev);
424 	serdes->type = serdes->chip_data->serdes_type;
425 
426 	SERDES_DBG_MFD("serdes %s %s probe start\n",
427 		       serdes->dev->name, serdes->chip_data->name);
428 
429 	ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
430 					   "vpower-supply",
431 					   &serdes->vpower_supply);
432 	if (ret && ret != -ENOENT)
433 		SERDES_DBG_MFD("%s: Cannot get power supply: %d\n",
434 			       __func__, ret);
435 
436 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
437 				   &serdes->enable_gpio, GPIOD_IS_OUT);
438 	if (ret)
439 		SERDES_DBG_MFD("%s: failed to get enable gpio: %d\n",
440 			       __func__, ret);
441 
442 	ret = gpio_request_by_name(dev, "lock-gpios", 0,
443 				   &serdes->lock_gpio,
444 				   GPIOD_IS_IN);
445 	if (ret)
446 		SERDES_DBG_MFD("%s: failed to get lock gpio: %d\n",
447 			       __func__, ret);
448 
449 	ret = gpio_request_by_name(dev, "err-gpios", 0,
450 				   &serdes->err_gpio,
451 				   GPIOD_IS_IN);
452 	if (ret)
453 		SERDES_DBG_MFD("%s: failed to err gpio: %d\n",
454 			       __func__, ret);
455 
456 	ret = serdes_get_init_seq(serdes);
457 	if (ret)
458 		return ret;
459 
460 	serdes_i2c_init(serdes);
461 
462 	printf("%s %s successful, version %s\n",
463 	       __func__,
464 	       serdes->dev->name,
465 	       SERDES_UBOOT_DISPLAY_VERSION);
466 
467 	return 0;
468 }
469 
470 static const struct udevice_id serdes_of_match[] = {
471 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_NOVO_NCA9539)
472 	{ .compatible = "novo,nca9539", .data = (ulong)&serdes_nca9539_data },
473 #endif
474 	{ }
475 };
476 
477 U_BOOT_DRIVER(serdes_misc) = {
478 	.name = "serdes-misc",
479 	.id = UCLASS_MISC,
480 	.of_match = serdes_of_match,
481 	.probe = serdes_i2c_probe,
482 	.priv_auto_alloc_size = sizeof(struct serdes),
483 };
484 
485 int serdes_power_init(void)
486 {
487 	struct udevice *dev;
488 	int ret = 0;
489 
490 	ret = uclass_get_device_by_driver(UCLASS_MISC,
491 					  DM_GET_DRIVER(serdes_misc),
492 					  &dev);
493 	if (ret)
494 		printf("%s failed to get serdes misc device\n", __func__);
495 
496 	return ret;
497 }
498 
499