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