1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * serdes-bridge.c -- display bridge 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 struct serdes *g_serdes_ser_split[MAX_NUM_SERDES_SPLIT]; 13 14 static void serdes_i2c_init(struct serdes *serdes) 15 { 16 if (serdes->vpower_supply) 17 regulator_set_enable(serdes->vpower_supply, true); 18 19 if (dm_gpio_is_valid(&serdes->enable_gpio)) 20 dm_gpio_set_value(&serdes->enable_gpio, 1); 21 22 //mdelay(5); 23 24 //video_bridge_set_active(serdes->dev, true); 25 26 if (serdes->chip_data->bridge_ops->init) 27 serdes->chip_data->bridge_ops->init(serdes); 28 29 serdes_i2c_set_sequence(serdes); 30 31 SERDES_DBG_MFD("%s: %s %s\n", __func__, 32 serdes->dev->name, 33 serdes->chip_data->name); 34 } 35 36 static int serdes_set_i2c_address(struct serdes *serdes, 37 u32 reg_hw, u32 reg_use, int link) 38 { 39 int ret = 0; 40 struct dm_i2c_chip *chip_split; 41 struct serdes *serdes_split = serdes->g_serdes_bridge_split; 42 43 if (!serdes_split) { 44 pr_info("%s: serdes_split is null\n", __func__); 45 return -1; 46 } 47 48 chip_split = dev_get_parent_platdata(serdes->dev); 49 SERDES_DBG_MFD("%s: %s addr=0x%x reg_hw=0x%x, reg_use=0x%x split=0x%p\n", 50 __func__, serdes_split->dev->name, 51 chip_split->chip_addr, serdes->reg_hw, 52 serdes->reg_use, serdes_split); 53 54 chip_split->chip_addr = serdes->reg_hw; 55 56 if (serdes_split && serdes_split->chip_data->split_ops && 57 serdes_split->chip_data->split_ops->select) 58 ret = serdes_split->chip_data->split_ops->select(serdes_split, link); 59 60 if (serdes->chip_data->split_ops && 61 serdes->chip_data->split_ops->set_i2c_addr) 62 serdes->chip_data->split_ops->set_i2c_addr(serdes, 63 reg_use, link); 64 65 if (serdes_split && serdes_split->chip_data->split_ops && 66 serdes_split->chip_data->split_ops->select) 67 ret = serdes_split->chip_data->split_ops->select(serdes_split, 68 SER_SPLITTER_MODE); 69 70 chip_split->chip_addr = serdes->reg_use; 71 72 serdes_i2c_set_sequence(serdes); 73 74 return ret; 75 } 76 77 static int serdes_i2c_probe(struct udevice *dev) 78 { 79 struct serdes *serdes = dev_get_priv(dev); 80 struct serdes_bridge *serdes_bridge = NULL; 81 struct serdes_bridge_split *serdes_bridge_split = NULL; 82 83 int ret; 84 85 ret = i2c_set_chip_offset_len(dev, 2); 86 if (ret) 87 return ret; 88 89 serdes->dev = dev; 90 serdes->chip_data = (struct serdes_chip_data *)dev_get_driver_data(dev); 91 serdes->type = serdes->chip_data->serdes_type; 92 93 SERDES_DBG_MFD("serdes %s %s probe start serdes=%p\n", 94 serdes->dev->name, serdes->chip_data->name, serdes); 95 96 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, 97 "vpower-supply", 98 &serdes->vpower_supply); 99 if (ret && ret != -ENOENT) 100 SERDES_DBG_MFD("%s: Cannot get power supply: %d\n", 101 __func__, ret); 102 103 ret = gpio_request_by_name(dev, "enable-gpios", 0, 104 &serdes->enable_gpio, GPIOD_IS_OUT); 105 if (ret) 106 SERDES_DBG_MFD("%s: failed to get enable gpio: %d\n", 107 __func__, ret); 108 109 ret = gpio_request_by_name(dev, "lock-gpios", 0, &serdes->lock_gpio, 110 GPIOD_IS_IN); 111 if (ret) 112 SERDES_DBG_MFD("%s: failed to get lock gpio: %d\n", 113 __func__, ret); 114 115 ret = gpio_request_by_name(dev, "err-gpios", 0, &serdes->err_gpio, 116 GPIOD_IS_IN); 117 if (ret) 118 SERDES_DBG_MFD("%s: failed to err gpio: %d\n", 119 __func__, ret); 120 121 serdes->mcu_enable = dev_read_bool(dev, "mcu-enable"); 122 123 if (serdes->chip_data->serdes_type == TYPE_OTHER) { 124 SERDES_DBG_MFD("TYPE_OTHER just need only init i2c\n"); 125 serdes_i2c_init(serdes); 126 return 0; 127 } 128 129 ret = serdes_get_init_seq(serdes); 130 if (ret) 131 return ret; 132 133 if (serdes->chip_data->serdes_type == TYPE_SER) 134 serdes_i2c_init(serdes); 135 136 if (serdes->chip_data->bridge_ops) { 137 serdes_bridge = calloc(1, sizeof(*serdes_bridge)); 138 if (!serdes_bridge) 139 return -ENOMEM; 140 serdes->serdes_bridge = serdes_bridge; 141 142 serdes_bridge_split = calloc(1, sizeof(*serdes_bridge_split)); 143 if (!serdes_bridge_split) 144 return -ENOMEM; 145 serdes->serdes_bridge_split = serdes_bridge_split; 146 } 147 148 ret = serdes_pinctrl_register(dev); 149 if (ret) 150 return ret; 151 152 serdes->id_serdes_bridge_split = dev_read_u32_default(dev, "id-serdes-bridge-split", 0); 153 if ((serdes->id_serdes_bridge_split < MAX_NUM_SERDES_SPLIT) && (serdes->type == TYPE_SER)) { 154 g_serdes_ser_split[serdes->id_serdes_bridge_split] = serdes; 155 SERDES_DBG_MFD("%s: %s-%s g_serdes_split[%d]=0x%p\n", __func__, 156 serdes->dev->name, serdes->chip_data->name, 157 serdes->id_serdes_bridge_split, serdes); 158 } 159 160 serdes->reg_hw = dev_read_u32_default(dev, "reg-hw", 0); 161 serdes->reg_use = dev_read_u32_default(dev, "reg", 0); 162 serdes->link_use = dev_read_u32_default(dev, "link", 0); 163 serdes->id_serdes_panel_split = dev_read_u32_default(dev, "id-serdes-panel-split", 0); 164 165 if ((serdes->id_serdes_panel_split) && (serdes->type == TYPE_DES)) { 166 serdes->g_serdes_bridge_split = g_serdes_ser_split[serdes->id_serdes_panel_split]; 167 SERDES_DBG_MFD("%s: id=%d p=0x%p\n", __func__, 168 serdes->id_serdes_panel_split, 169 serdes->g_serdes_bridge_split); 170 } 171 172 if (serdes->reg_hw) { 173 SERDES_DBG_MFD("%s: %s change i2c addr from 0x%x to 0x%x\n", 174 __func__, dev->name, 175 serdes->reg_hw, serdes->reg_use); 176 serdes_set_i2c_address(serdes, serdes->reg_hw, 177 serdes->reg_use, serdes->link_use); 178 } 179 180 printf("%s %s %s successful\n", 181 __func__, 182 serdes->dev->name, 183 serdes->chip_data->name); 184 185 return 0; 186 } 187 188 static const struct udevice_id serdes_of_match[] = { 189 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18TL82) 190 { .compatible = "rohm,bu18tl82", 191 .data = (ulong)&serdes_bu18tl82_data }, 192 #endif 193 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROHM_BU18RL82) 194 { .compatible = "rohm,bu18rl82", 195 .data = (ulong)&serdes_bu18rl82_data }, 196 #endif 197 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96745) 198 { .compatible = "maxim,max96745", 199 .data = (ulong)&serdes_max96745_data }, 200 #endif 201 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96755) 202 { .compatible = "maxim,max96755", 203 .data = (ulong)&serdes_max96755_data }, 204 #endif 205 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96789) 206 { .compatible = "maxim,max96789", 207 .data = (ulong)&serdes_max96789_data }, 208 #endif 209 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX111) 210 { .compatible = "rockchip,rkx111", 211 .data = (ulong)&serdes_rkx111_data }, 212 #endif 213 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96752) 214 { .compatible = "maxim,max96752", 215 .data = (ulong)&serdes_max96752_data }, 216 #endif 217 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_MAXIM_MAX96772) 218 { .compatible = "maxim,max96772", 219 .data = (ulong)&serdes_max96772_data }, 220 #endif 221 #if IS_ENABLED(CONFIG_SERDES_DISPLAY_CHIP_ROCKCHIP_RKX121) 222 { .compatible = "rockchip,rkx121", 223 .data = (ulong)&serdes_rkx121_data }, 224 #endif 225 { } 226 }; 227 228 U_BOOT_DRIVER(serdes_i2c) = { 229 .name = "serdes-i2c", 230 .id = UCLASS_MISC, 231 .of_match = serdes_of_match, 232 .probe = serdes_i2c_probe, 233 .bind = dm_scan_fdt_dev, 234 .priv_auto_alloc_size = sizeof(struct serdes), 235 }; 236