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 *)®, 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