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