FILE
phy-qcom-edp.c
File preview with syntax highlighting.
linux-6.19.14/drivers/phy/qualcomm/phy-qcom-edp.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021, Linaro Ltd. 5 */ 6 7#include <linux/clk.h> 8#include <linux/clk-provider.h> 9#include <linux/delay.h> 10#include <linux/err.h> 11#include <linux/io.h> 12#include <linux/iopoll.h> 13#include <linux/kernel.h> 14#include <linux/module.h> 15#include <linux/of.h> 16#include <linux/phy/phy.h> 17#include <linux/phy/phy-dp.h> 18#include <linux/platform_device.h> 19#include <linux/regulator/consumer.h> 20#include <linux/reset.h> 21#include <linux/slab.h> 22 23#include <dt-bindings/phy/phy.h> 24 25#include "phy-qcom-qmp-dp-phy.h" 26#include "phy-qcom-qmp-qserdes-com-v4.h" 27#include "phy-qcom-qmp-qserdes-com-v6.h" 28 29/* EDP_PHY registers */ 30#define DP_PHY_CFG 0x0010 31#define DP_PHY_CFG_1 0x0014 32#define DP_PHY_PD_CTL 0x001c 33#define DP_PHY_MODE 0x0020 34 35#define DP_AUX_CFG_SIZE 10 36#define DP_PHY_AUX_CFG(n) (0x24 + (0x04 * (n))) 37 38#define DP_PHY_AUX_INTERRUPT_MASK 0x0058 39 40#define DP_PHY_VCO_DIV 0x0074 41#define DP_PHY_TX0_TX1_LANE_CTL 0x007c 42#define DP_PHY_TX2_TX3_LANE_CTL 0x00a0 43 44#define DP_PHY_STATUS 0x00e0 45 46/* LANE_TXn registers */ 47#define TXn_CLKBUF_ENABLE 0x0000 48#define TXn_TX_EMP_POST1_LVL 0x0004 49 50#define TXn_TX_DRV_LVL 0x0014 51#define TXn_TX_DRV_LVL_OFFSET 0x0018 52#define TXn_RESET_TSYNC_EN 0x001c 53#define TXn_LDO_CONFIG 0x0084 54#define TXn_TX_BAND 0x0028 55 56#define TXn_RES_CODE_LANE_OFFSET_TX0 0x0044 57#define TXn_RES_CODE_LANE_OFFSET_TX1 0x0048 58 59#define TXn_TRANSCEIVER_BIAS_EN 0x0054 60#define TXn_HIGHZ_DRVR_EN 0x0058 61#define TXn_TX_POL_INV 0x005c 62#define TXn_LANE_MODE_1 0x0064 63 64#define TXn_TRAN_DRVR_EMP_EN 0x0078 65 66struct qcom_edp_swing_pre_emph_cfg { 67 const u8 (*swing_hbr_rbr)[4][4]; 68 const u8 (*swing_hbr3_hbr2)[4][4]; 69 const u8 (*pre_emphasis_hbr_rbr)[4][4]; 70 const u8 (*pre_emphasis_hbr3_hbr2)[4][4]; 71}; 72 73struct qcom_edp; 74 75struct phy_ver_ops { 76 int (*com_power_on)(const struct qcom_edp *edp); 77 int (*com_resetsm_cntrl)(const struct qcom_edp *edp); 78 int (*com_bias_en_clkbuflr)(const struct qcom_edp *edp); 79 int (*com_configure_pll)(const struct qcom_edp *edp); 80 int (*com_configure_ssc)(const struct qcom_edp *edp); 81}; 82 83struct qcom_edp_phy_cfg { 84 bool is_edp; 85 const u8 *aux_cfg; 86 const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg; 87 const struct phy_ver_ops *ver_ops; 88}; 89 90struct qcom_edp { 91 struct device *dev; 92 const struct qcom_edp_phy_cfg *cfg; 93 94 struct phy *phy; 95 96 void __iomem *edp; 97 void __iomem *tx0; 98 void __iomem *tx1; 99 void __iomem *pll; 100 101 struct clk_hw dp_link_hw; 102 struct clk_hw dp_pixel_hw; 103 104 struct phy_configure_opts_dp dp_opts; 105 106 struct clk_bulk_data *clks; 107 int num_clks; 108 109 struct regulator_bulk_data supplies[2]; 110 111 bool is_edp; 112}; 113 114static const u8 dp_swing_hbr_rbr[4][4] = { 115 { 0x08, 0x0f, 0x16, 0x1f }, 116 { 0x11, 0x1e, 0x1f, 0xff }, 117 { 0x16, 0x1f, 0xff, 0xff }, 118 { 0x1f, 0xff, 0xff, 0xff } 119}; 120 121static const u8 dp_pre_emp_hbr_rbr[4][4] = { 122 { 0x00, 0x0d, 0x14, 0x1a }, 123 { 0x00, 0x0e, 0x15, 0xff }, 124 { 0x00, 0x0e, 0xff, 0xff }, 125 { 0x03, 0xff, 0xff, 0xff } 126}; 127 128static const u8 dp_swing_hbr2_hbr3[4][4] = { 129 { 0x02, 0x12, 0x16, 0x1a }, 130 { 0x09, 0x19, 0x1f, 0xff }, 131 { 0x10, 0x1f, 0xff, 0xff }, 132 { 0x1f, 0xff, 0xff, 0xff } 133}; 134 135static const u8 dp_pre_emp_hbr2_hbr3[4][4] = { 136 { 0x00, 0x0c, 0x15, 0x1b }, 137 { 0x02, 0x0e, 0x16, 0xff }, 138 { 0x02, 0x11, 0xff, 0xff }, 139 { 0x04, 0xff, 0xff, 0xff } 140}; 141 142static const struct qcom_edp_swing_pre_emph_cfg dp_phy_swing_pre_emph_cfg = { 143 .swing_hbr_rbr = &dp_swing_hbr_rbr, 144 .swing_hbr3_hbr2 = &dp_swing_hbr2_hbr3, 145 .pre_emphasis_hbr_rbr = &dp_pre_emp_hbr_rbr, 146 .pre_emphasis_hbr3_hbr2 = &dp_pre_emp_hbr2_hbr3, 147}; 148 149static const u8 edp_swing_hbr_rbr[4][4] = { 150 { 0x07, 0x0f, 0x16, 0x1f }, 151 { 0x0d, 0x16, 0x1e, 0xff }, 152 { 0x11, 0x1b, 0xff, 0xff }, 153 { 0x16, 0xff, 0xff, 0xff } 154}; 155 156static const u8 edp_pre_emp_hbr_rbr[4][4] = { 157 { 0x05, 0x12, 0x17, 0x1d }, 158 { 0x05, 0x11, 0x18, 0xff }, 159 { 0x06, 0x11, 0xff, 0xff }, 160 { 0x00, 0xff, 0xff, 0xff } 161}; 162 163static const u8 edp_swing_hbr2_hbr3[4][4] = { 164 { 0x0b, 0x11, 0x17, 0x1c }, 165 { 0x10, 0x19, 0x1f, 0xff }, 166 { 0x19, 0x1f, 0xff, 0xff }, 167 { 0x1f, 0xff, 0xff, 0xff } 168}; 169 170static const u8 edp_pre_emp_hbr2_hbr3[4][4] = { 171 { 0x08, 0x11, 0x17, 0x1b }, 172 { 0x00, 0x0c, 0x13, 0xff }, 173 { 0x05, 0x10, 0xff, 0xff }, 174 { 0x00, 0xff, 0xff, 0xff } 175}; 176 177static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = { 178 .swing_hbr_rbr = &edp_swing_hbr_rbr, 179 .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3, 180 .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr, 181 .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3, 182}; 183 184static const u8 edp_phy_aux_cfg_v4[10] = { 185 0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03 186}; 187 188static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = { 189 { 0x05, 0x11, 0x17, 0x1d }, 190 { 0x05, 0x11, 0x18, 0xff }, 191 { 0x06, 0x11, 0xff, 0xff }, 192 { 0x00, 0xff, 0xff, 0xff } 193}; 194 195static const u8 edp_pre_emp_hbr2_hbr3_v5[4][4] = { 196 { 0x0c, 0x15, 0x19, 0x1e }, 197 { 0x0b, 0x15, 0x19, 0xff }, 198 { 0x0e, 0x14, 0xff, 0xff }, 199 { 0x0d, 0xff, 0xff, 0xff } 200}; 201 202static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = { 203 .swing_hbr_rbr = &edp_swing_hbr_rbr, 204 .swing_hbr3_hbr2 = &edp_swing_hbr2_hbr3, 205 .pre_emphasis_hbr_rbr = &edp_pre_emp_hbr_rbr_v5, 206 .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5, 207}; 208 209static const u8 edp_phy_aux_cfg_v5[10] = { 210 0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03 211}; 212 213static int qcom_edp_phy_init(struct phy *phy) 214{ 215 struct qcom_edp *edp = phy_get_drvdata(phy); 216 u8 aux_cfg[DP_AUX_CFG_SIZE]; 217 int ret; 218 219 ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies); 220 if (ret) 221 return ret; 222 223 ret = clk_bulk_prepare_enable(edp->num_clks, edp->clks); 224 if (ret) 225 goto out_disable_supplies; 226 227 memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg)); 228 229 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 230 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 231 edp->edp + DP_PHY_PD_CTL); 232 233 ret = edp->cfg->ver_ops->com_bias_en_clkbuflr(edp); 234 if (ret) 235 return ret; 236 237 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL); 238 msleep(20); 239 240 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 241 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 242 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 243 edp->edp + DP_PHY_PD_CTL); 244 245 /* 246 * TODO: Re-work the conditions around setting the cfg8 value 247 * when more information becomes available about why this is 248 * even needed. 249 */ 250 if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp) 251 aux_cfg[8] = 0xb7; 252 253 writel(0xfc, edp->edp + DP_PHY_MODE); 254 255 for (int i = 0; i < DP_AUX_CFG_SIZE; i++) 256 writel(aux_cfg[i], edp->edp + DP_PHY_AUX_CFG(i)); 257 258 writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | 259 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | 260 PHY_AUX_REQ_ERR_MASK, edp->edp + DP_PHY_AUX_INTERRUPT_MASK); 261 262 msleep(20); 263 264 return 0; 265 266out_disable_supplies: 267 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); 268 269 return ret; 270} 271 272static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configure_opts_dp *dp_opts) 273{ 274 const struct qcom_edp_swing_pre_emph_cfg *cfg = edp->cfg->swing_pre_emph_cfg; 275 unsigned int v_level = 0; 276 unsigned int p_level = 0; 277 u8 ldo_config; 278 u8 swing; 279 u8 emph; 280 int i; 281 282 if (!cfg) 283 return 0; 284 285 if (edp->is_edp) 286 cfg = &edp_phy_swing_pre_emph_cfg; 287 288 for (i = 0; i < dp_opts->lanes; i++) { 289 v_level = max(v_level, dp_opts->voltage[i]); 290 p_level = max(p_level, dp_opts->pre[i]); 291 } 292 293 if (dp_opts->link_rate <= 2700) { 294 swing = (*cfg->swing_hbr_rbr)[v_level][p_level]; 295 emph = (*cfg->pre_emphasis_hbr_rbr)[v_level][p_level]; 296 } else { 297 swing = (*cfg->swing_hbr3_hbr2)[v_level][p_level]; 298 emph = (*cfg->pre_emphasis_hbr3_hbr2)[v_level][p_level]; 299 } 300 301 if (swing == 0xff || emph == 0xff) 302 return -EINVAL; 303 304 ldo_config = edp->is_edp ? 0x0 : 0x1; 305 306 writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG); 307 writel(swing, edp->tx0 + TXn_TX_DRV_LVL); 308 writel(emph, edp->tx0 + TXn_TX_EMP_POST1_LVL); 309 310 writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG); 311 writel(swing, edp->tx1 + TXn_TX_DRV_LVL); 312 writel(emph, edp->tx1 + TXn_TX_EMP_POST1_LVL); 313 314 return 0; 315} 316 317static int qcom_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts) 318{ 319 const struct phy_configure_opts_dp *dp_opts = &opts->dp; 320 struct qcom_edp *edp = phy_get_drvdata(phy); 321 int ret = 0; 322 323 memcpy(&edp->dp_opts, dp_opts, sizeof(*dp_opts)); 324 325 if (dp_opts->set_voltages) 326 ret = qcom_edp_set_voltages(edp, dp_opts); 327 328 return ret; 329} 330 331static int qcom_edp_configure_ssc(const struct qcom_edp *edp) 332{ 333 return edp->cfg->ver_ops->com_configure_ssc(edp); 334} 335 336static int qcom_edp_configure_pll(const struct qcom_edp *edp) 337{ 338 return edp->cfg->ver_ops->com_configure_pll(edp); 339} 340 341static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel_freq) 342{ 343 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 344 u32 vco_div; 345 346 switch (dp_opts->link_rate) { 347 case 1620: 348 vco_div = 0x1; 349 *pixel_freq = 1620000000UL / 2; 350 break; 351 352 case 2700: 353 vco_div = 0x1; 354 *pixel_freq = 2700000000UL / 2; 355 break; 356 357 case 5400: 358 vco_div = 0x2; 359 *pixel_freq = 5400000000UL / 4; 360 break; 361 362 case 8100: 363 vco_div = 0x0; 364 *pixel_freq = 8100000000UL / 6; 365 break; 366 367 default: 368 /* Other link rates aren't supported */ 369 return -EINVAL; 370 } 371 372 writel(vco_div, edp->edp + DP_PHY_VCO_DIV); 373 374 return 0; 375} 376 377static int qcom_edp_phy_power_on_v4(const struct qcom_edp *edp) 378{ 379 u32 val; 380 381 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 382 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 383 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 384 edp->edp + DP_PHY_PD_CTL); 385 writel(0xfc, edp->edp + DP_PHY_MODE); 386 387 return readl_poll_timeout(edp->pll + QSERDES_V4_COM_CMN_STATUS, 388 val, val & BIT(7), 5, 200); 389} 390 391static int qcom_edp_phy_com_resetsm_cntrl_v4(const struct qcom_edp *edp) 392{ 393 u32 val; 394 395 writel(0x20, edp->pll + QSERDES_V4_COM_RESETSM_CNTRL); 396 397 return readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS, 398 val, val & BIT(0), 500, 10000); 399} 400 401static int qcom_edp_com_bias_en_clkbuflr_v4(const struct qcom_edp *edp) 402{ 403 /* Turn on BIAS current for PHY/PLL */ 404 writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN); 405 406 return 0; 407} 408 409static int qcom_edp_com_configure_ssc_v4(const struct qcom_edp *edp) 410{ 411 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 412 u32 step1; 413 u32 step2; 414 415 switch (dp_opts->link_rate) { 416 case 1620: 417 case 2700: 418 case 8100: 419 step1 = 0x45; 420 step2 = 0x06; 421 break; 422 423 case 5400: 424 step1 = 0x5c; 425 step2 = 0x08; 426 break; 427 428 default: 429 /* Other link rates aren't supported */ 430 return -EINVAL; 431 } 432 433 writel(0x01, edp->pll + QSERDES_V4_COM_SSC_EN_CENTER); 434 writel(0x00, edp->pll + QSERDES_V4_COM_SSC_ADJ_PER1); 435 writel(0x36, edp->pll + QSERDES_V4_COM_SSC_PER1); 436 writel(0x01, edp->pll + QSERDES_V4_COM_SSC_PER2); 437 writel(step1, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0); 438 writel(step2, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0); 439 440 return 0; 441} 442 443static int qcom_edp_com_configure_pll_v4(const struct qcom_edp *edp) 444{ 445 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 446 u32 div_frac_start2_mode0; 447 u32 div_frac_start3_mode0; 448 u32 dec_start_mode0; 449 u32 lock_cmp1_mode0; 450 u32 lock_cmp2_mode0; 451 u32 hsclk_sel; 452 453 switch (dp_opts->link_rate) { 454 case 1620: 455 hsclk_sel = 0x5; 456 dec_start_mode0 = 0x69; 457 div_frac_start2_mode0 = 0x80; 458 div_frac_start3_mode0 = 0x07; 459 lock_cmp1_mode0 = 0x6f; 460 lock_cmp2_mode0 = 0x08; 461 break; 462 463 case 2700: 464 hsclk_sel = 0x3; 465 dec_start_mode0 = 0x69; 466 div_frac_start2_mode0 = 0x80; 467 div_frac_start3_mode0 = 0x07; 468 lock_cmp1_mode0 = 0x0f; 469 lock_cmp2_mode0 = 0x0e; 470 break; 471 472 case 5400: 473 hsclk_sel = 0x1; 474 dec_start_mode0 = 0x8c; 475 div_frac_start2_mode0 = 0x00; 476 div_frac_start3_mode0 = 0x0a; 477 lock_cmp1_mode0 = 0x1f; 478 lock_cmp2_mode0 = 0x1c; 479 break; 480 481 case 8100: 482 hsclk_sel = 0x0; 483 dec_start_mode0 = 0x69; 484 div_frac_start2_mode0 = 0x80; 485 div_frac_start3_mode0 = 0x07; 486 lock_cmp1_mode0 = 0x2f; 487 lock_cmp2_mode0 = 0x2a; 488 break; 489 490 default: 491 /* Other link rates aren't supported */ 492 return -EINVAL; 493 } 494 495 writel(0x01, edp->pll + QSERDES_V4_COM_SVS_MODE_CLK_SEL); 496 writel(0x0b, edp->pll + QSERDES_V4_COM_SYSCLK_EN_SEL); 497 writel(0x02, edp->pll + QSERDES_V4_COM_SYS_CLK_CTRL); 498 writel(0x0c, edp->pll + QSERDES_V4_COM_CLK_ENABLE1); 499 writel(0x06, edp->pll + QSERDES_V4_COM_SYSCLK_BUF_ENABLE); 500 writel(0x30, edp->pll + QSERDES_V4_COM_CLK_SELECT); 501 writel(hsclk_sel, edp->pll + QSERDES_V4_COM_HSCLK_SEL); 502 writel(0x0f, edp->pll + QSERDES_V4_COM_PLL_IVCO); 503 writel(0x08, edp->pll + QSERDES_V4_COM_LOCK_CMP_EN); 504 writel(0x36, edp->pll + QSERDES_V4_COM_PLL_CCTRL_MODE0); 505 writel(0x16, edp->pll + QSERDES_V4_COM_PLL_RCTRL_MODE0); 506 writel(0x06, edp->pll + QSERDES_V4_COM_CP_CTRL_MODE0); 507 writel(dec_start_mode0, edp->pll + QSERDES_V4_COM_DEC_START_MODE0); 508 writel(0x00, edp->pll + QSERDES_V4_COM_DIV_FRAC_START1_MODE0); 509 writel(div_frac_start2_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START2_MODE0); 510 writel(div_frac_start3_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START3_MODE0); 511 writel(0x02, edp->pll + QSERDES_V4_COM_CMN_CONFIG); 512 writel(0x3f, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0); 513 writel(0x00, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0); 514 writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_MAP); 515 writel(lock_cmp1_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP1_MODE0); 516 writel(lock_cmp2_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP2_MODE0); 517 518 writel(0x0a, edp->pll + QSERDES_V4_COM_BG_TIMER); 519 writel(0x14, edp->pll + QSERDES_V4_COM_CORECLK_DIV_MODE0); 520 writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_CTRL); 521 writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN); 522 writel(0x0f, edp->pll + QSERDES_V4_COM_CORE_CLK_EN); 523 writel(0xa0, edp->pll + QSERDES_V4_COM_VCO_TUNE1_MODE0); 524 writel(0x03, edp->pll + QSERDES_V4_COM_VCO_TUNE2_MODE0); 525 526 return 0; 527} 528 529static const struct phy_ver_ops qcom_edp_phy_ops_v4 = { 530 .com_power_on = qcom_edp_phy_power_on_v4, 531 .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4, 532 .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v4, 533 .com_configure_pll = qcom_edp_com_configure_pll_v4, 534 .com_configure_ssc = qcom_edp_com_configure_ssc_v4, 535}; 536 537static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = { 538 .is_edp = false, 539 .aux_cfg = edp_phy_aux_cfg_v5, 540 .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5, 541 .ver_ops = &qcom_edp_phy_ops_v4, 542}; 543 544static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = { 545 .aux_cfg = edp_phy_aux_cfg_v4, 546 .ver_ops = &qcom_edp_phy_ops_v4, 547}; 548 549static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = { 550 .aux_cfg = edp_phy_aux_cfg_v4, 551 .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 552 .ver_ops = &qcom_edp_phy_ops_v4, 553}; 554 555static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = { 556 .is_edp = true, 557 .aux_cfg = edp_phy_aux_cfg_v4, 558 .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, 559 .ver_ops = &qcom_edp_phy_ops_v4, 560}; 561 562static int qcom_edp_phy_power_on_v6(const struct qcom_edp *edp) 563{ 564 u32 val; 565 566 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 567 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 568 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 569 edp->edp + DP_PHY_PD_CTL); 570 writel(0xfc, edp->edp + DP_PHY_MODE); 571 572 return readl_poll_timeout(edp->pll + QSERDES_V6_COM_CMN_STATUS, 573 val, val & BIT(7), 5, 200); 574} 575 576static int qcom_edp_phy_com_resetsm_cntrl_v6(const struct qcom_edp *edp) 577{ 578 u32 val; 579 580 writel(0x20, edp->pll + QSERDES_V6_COM_RESETSM_CNTRL); 581 582 return readl_poll_timeout(edp->pll + QSERDES_V6_COM_C_READY_STATUS, 583 val, val & BIT(0), 500, 10000); 584} 585 586static int qcom_edp_com_bias_en_clkbuflr_v6(const struct qcom_edp *edp) 587{ 588 /* Turn on BIAS current for PHY/PLL */ 589 writel(0x1f, edp->pll + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN); 590 591 return 0; 592} 593 594static int qcom_edp_com_configure_ssc_v6(const struct qcom_edp *edp) 595{ 596 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 597 u32 step1; 598 u32 step2; 599 600 switch (dp_opts->link_rate) { 601 case 1620: 602 case 2700: 603 case 8100: 604 step1 = 0x92; 605 step2 = 0x01; 606 break; 607 608 case 5400: 609 step1 = 0x18; 610 step2 = 0x02; 611 break; 612 613 default: 614 /* Other link rates aren't supported */ 615 return -EINVAL; 616 } 617 618 writel(0x01, edp->pll + QSERDES_V6_COM_SSC_EN_CENTER); 619 writel(0x00, edp->pll + QSERDES_V6_COM_SSC_ADJ_PER1); 620 writel(0x36, edp->pll + QSERDES_V6_COM_SSC_PER1); 621 writel(0x01, edp->pll + QSERDES_V6_COM_SSC_PER2); 622 writel(step1, edp->pll + QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0); 623 writel(step2, edp->pll + QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0); 624 625 return 0; 626} 627 628static int qcom_edp_com_configure_pll_v6(const struct qcom_edp *edp) 629{ 630 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 631 u32 div_frac_start2_mode0; 632 u32 div_frac_start3_mode0; 633 u32 dec_start_mode0; 634 u32 lock_cmp1_mode0; 635 u32 lock_cmp2_mode0; 636 u32 code1_mode0; 637 u32 code2_mode0; 638 u32 hsclk_sel; 639 640 switch (dp_opts->link_rate) { 641 case 1620: 642 hsclk_sel = 0x5; 643 dec_start_mode0 = 0x34; 644 div_frac_start2_mode0 = 0xc0; 645 div_frac_start3_mode0 = 0x0b; 646 lock_cmp1_mode0 = 0x37; 647 lock_cmp2_mode0 = 0x04; 648 code1_mode0 = 0x71; 649 code2_mode0 = 0x0c; 650 break; 651 652 case 2700: 653 hsclk_sel = 0x3; 654 dec_start_mode0 = 0x34; 655 div_frac_start2_mode0 = 0xc0; 656 div_frac_start3_mode0 = 0x0b; 657 lock_cmp1_mode0 = 0x07; 658 lock_cmp2_mode0 = 0x07; 659 code1_mode0 = 0x71; 660 code2_mode0 = 0x0c; 661 break; 662 663 case 5400: 664 hsclk_sel = 0x1; 665 dec_start_mode0 = 0x46; 666 div_frac_start2_mode0 = 0x00; 667 div_frac_start3_mode0 = 0x05; 668 lock_cmp1_mode0 = 0x0f; 669 lock_cmp2_mode0 = 0x0e; 670 code1_mode0 = 0x97; 671 code2_mode0 = 0x10; 672 break; 673 674 case 8100: 675 hsclk_sel = 0x0; 676 dec_start_mode0 = 0x34; 677 div_frac_start2_mode0 = 0xc0; 678 div_frac_start3_mode0 = 0x0b; 679 lock_cmp1_mode0 = 0x17; 680 lock_cmp2_mode0 = 0x15; 681 code1_mode0 = 0x71; 682 code2_mode0 = 0x0c; 683 break; 684 685 default: 686 /* Other link rates aren't supported */ 687 return -EINVAL; 688 } 689 690 writel(0x01, edp->pll + QSERDES_V6_COM_SVS_MODE_CLK_SEL); 691 writel(0x0b, edp->pll + QSERDES_V6_COM_SYSCLK_EN_SEL); 692 writel(0x02, edp->pll + QSERDES_V6_COM_SYS_CLK_CTRL); 693 writel(0x0c, edp->pll + QSERDES_V6_COM_CLK_ENABLE1); 694 writel(0x06, edp->pll + QSERDES_V6_COM_SYSCLK_BUF_ENABLE); 695 writel(0x30, edp->pll + QSERDES_V6_COM_CLK_SELECT); 696 writel(hsclk_sel, edp->pll + QSERDES_V6_COM_HSCLK_SEL_1); 697 writel(0x07, edp->pll + QSERDES_V6_COM_PLL_IVCO); 698 writel(0x08, edp->pll + QSERDES_V6_COM_LOCK_CMP_EN); 699 writel(0x36, edp->pll + QSERDES_V6_COM_PLL_CCTRL_MODE0); 700 writel(0x16, edp->pll + QSERDES_V6_COM_PLL_RCTRL_MODE0); 701 writel(0x06, edp->pll + QSERDES_V6_COM_CP_CTRL_MODE0); 702 writel(dec_start_mode0, edp->pll + QSERDES_V6_COM_DEC_START_MODE0); 703 writel(0x00, edp->pll + QSERDES_V6_COM_DIV_FRAC_START1_MODE0); 704 writel(div_frac_start2_mode0, edp->pll + QSERDES_V6_COM_DIV_FRAC_START2_MODE0); 705 writel(div_frac_start3_mode0, edp->pll + QSERDES_V6_COM_DIV_FRAC_START3_MODE0); 706 writel(0x12, edp->pll + QSERDES_V6_COM_CMN_CONFIG_1); 707 writel(0x3f, edp->pll + QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0); 708 writel(0x00, edp->pll + QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0); 709 writel(0x00, edp->pll + QSERDES_V6_COM_VCO_TUNE_MAP); 710 writel(lock_cmp1_mode0, edp->pll + QSERDES_V6_COM_LOCK_CMP1_MODE0); 711 writel(lock_cmp2_mode0, edp->pll + QSERDES_V6_COM_LOCK_CMP2_MODE0); 712 713 writel(0x0a, edp->pll + QSERDES_V6_COM_BG_TIMER); 714 writel(0x14, edp->pll + QSERDES_V6_COM_PLL_CORE_CLK_DIV_MODE0); 715 writel(0x00, edp->pll + QSERDES_V6_COM_VCO_TUNE_CTRL); 716 writel(0x1f, edp->pll + QSERDES_V6_COM_PLL_BIAS_EN_CLK_BUFLR_EN); 717 writel(0x0f, edp->pll + QSERDES_V6_COM_CORE_CLK_EN); 718 writel(0xa0, edp->pll + QSERDES_V6_COM_VCO_TUNE1_MODE0); 719 writel(0x03, edp->pll + QSERDES_V6_COM_VCO_TUNE2_MODE0); 720 721 writel(code1_mode0, edp->pll + QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0); 722 writel(code2_mode0, edp->pll + QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0); 723 724 return 0; 725} 726 727static const struct phy_ver_ops qcom_edp_phy_ops_v6 = { 728 .com_power_on = qcom_edp_phy_power_on_v6, 729 .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6, 730 .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6, 731 .com_configure_pll = qcom_edp_com_configure_pll_v6, 732 .com_configure_ssc = qcom_edp_com_configure_ssc_v6, 733}; 734 735static struct qcom_edp_phy_cfg x1e80100_phy_cfg = { 736 .aux_cfg = edp_phy_aux_cfg_v4, 737 .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, 738 .ver_ops = &qcom_edp_phy_ops_v6, 739}; 740 741static int qcom_edp_phy_power_on(struct phy *phy) 742{ 743 const struct qcom_edp *edp = phy_get_drvdata(phy); 744 u32 bias0_en, drvr0_en, bias1_en, drvr1_en; 745 unsigned long pixel_freq; 746 u8 ldo_config = 0x0; 747 int ret; 748 u32 val; 749 u8 cfg1; 750 751 ret = edp->cfg->ver_ops->com_power_on(edp); 752 if (ret) 753 return ret; 754 755 if (edp->cfg->swing_pre_emph_cfg && !edp->is_edp) 756 ldo_config = 0x1; 757 758 writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG); 759 writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG); 760 writel(0x00, edp->tx0 + TXn_LANE_MODE_1); 761 writel(0x00, edp->tx1 + TXn_LANE_MODE_1); 762 763 if (edp->dp_opts.ssc) { 764 ret = qcom_edp_configure_ssc(edp); 765 if (ret) 766 return ret; 767 } 768 769 ret = qcom_edp_configure_pll(edp); 770 if (ret) 771 return ret; 772 773 /* TX Lane configuration */ 774 writel(0x05, edp->edp + DP_PHY_TX0_TX1_LANE_CTL); 775 writel(0x05, edp->edp + DP_PHY_TX2_TX3_LANE_CTL); 776 777 /* TX-0 register configuration */ 778 writel(0x03, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN); 779 writel(0x0f, edp->tx0 + TXn_CLKBUF_ENABLE); 780 writel(0x03, edp->tx0 + TXn_RESET_TSYNC_EN); 781 writel(0x01, edp->tx0 + TXn_TRAN_DRVR_EMP_EN); 782 writel(0x04, edp->tx0 + TXn_TX_BAND); 783 784 /* TX-1 register configuration */ 785 writel(0x03, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN); 786 writel(0x0f, edp->tx1 + TXn_CLKBUF_ENABLE); 787 writel(0x03, edp->tx1 + TXn_RESET_TSYNC_EN); 788 writel(0x01, edp->tx1 + TXn_TRAN_DRVR_EMP_EN); 789 writel(0x04, edp->tx1 + TXn_TX_BAND); 790 791 ret = qcom_edp_set_vco_div(edp, &pixel_freq); 792 if (ret) 793 return ret; 794 795 writel(0x01, edp->edp + DP_PHY_CFG); 796 writel(0x05, edp->edp + DP_PHY_CFG); 797 writel(0x01, edp->edp + DP_PHY_CFG); 798 writel(0x09, edp->edp + DP_PHY_CFG); 799 800 ret = edp->cfg->ver_ops->com_resetsm_cntrl(edp); 801 if (ret) 802 return ret; 803 804 writel(0x19, edp->edp + DP_PHY_CFG); 805 writel(0x1f, edp->tx0 + TXn_HIGHZ_DRVR_EN); 806 writel(0x04, edp->tx0 + TXn_HIGHZ_DRVR_EN); 807 writel(0x00, edp->tx0 + TXn_TX_POL_INV); 808 writel(0x1f, edp->tx1 + TXn_HIGHZ_DRVR_EN); 809 writel(0x04, edp->tx1 + TXn_HIGHZ_DRVR_EN); 810 writel(0x00, edp->tx1 + TXn_TX_POL_INV); 811 writel(0x10, edp->tx0 + TXn_TX_DRV_LVL_OFFSET); 812 writel(0x10, edp->tx1 + TXn_TX_DRV_LVL_OFFSET); 813 writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX0); 814 writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX1); 815 writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX0); 816 writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX1); 817 818 writel(0x10, edp->tx0 + TXn_TX_EMP_POST1_LVL); 819 writel(0x10, edp->tx1 + TXn_TX_EMP_POST1_LVL); 820 writel(0x1f, edp->tx0 + TXn_TX_DRV_LVL); 821 writel(0x1f, edp->tx1 + TXn_TX_DRV_LVL); 822 823 if (edp->dp_opts.lanes == 1) { 824 bias0_en = 0x01; 825 bias1_en = 0x00; 826 drvr0_en = 0x06; 827 drvr1_en = 0x07; 828 cfg1 = 0x1; 829 } else if (edp->dp_opts.lanes == 2) { 830 bias0_en = 0x03; 831 bias1_en = 0x00; 832 drvr0_en = 0x04; 833 drvr1_en = 0x07; 834 cfg1 = 0x3; 835 } else { 836 bias0_en = 0x03; 837 bias1_en = 0x03; 838 drvr0_en = 0x04; 839 drvr1_en = 0x04; 840 cfg1 = 0xf; 841 } 842 843 writel(drvr0_en, edp->tx0 + TXn_HIGHZ_DRVR_EN); 844 writel(bias0_en, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN); 845 writel(drvr1_en, edp->tx1 + TXn_HIGHZ_DRVR_EN); 846 writel(bias1_en, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN); 847 writel(cfg1, edp->edp + DP_PHY_CFG_1); 848 849 writel(0x18, edp->edp + DP_PHY_CFG); 850 usleep_range(100, 1000); 851 852 writel(0x19, edp->edp + DP_PHY_CFG); 853 854 ret = readl_poll_timeout(edp->edp + DP_PHY_STATUS, 855 val, val & BIT(1), 500, 10000); 856 if (ret) 857 return ret; 858 859 clk_set_rate(edp->dp_link_hw.clk, edp->dp_opts.link_rate * 100000); 860 clk_set_rate(edp->dp_pixel_hw.clk, pixel_freq); 861 862 return 0; 863} 864 865static int qcom_edp_phy_power_off(struct phy *phy) 866{ 867 const struct qcom_edp *edp = phy_get_drvdata(phy); 868 869 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL); 870 871 return 0; 872} 873 874static int qcom_edp_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) 875{ 876 struct qcom_edp *edp = phy_get_drvdata(phy); 877 878 if (mode != PHY_MODE_DP) 879 return -EINVAL; 880 881 edp->is_edp = submode == PHY_SUBMODE_EDP; 882 883 return 0; 884} 885 886static int qcom_edp_phy_exit(struct phy *phy) 887{ 888 struct qcom_edp *edp = phy_get_drvdata(phy); 889 890 clk_bulk_disable_unprepare(edp->num_clks, edp->clks); 891 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); 892 893 return 0; 894} 895 896static const struct phy_ops qcom_edp_ops = { 897 .init = qcom_edp_phy_init, 898 .configure = qcom_edp_phy_configure, 899 .power_on = qcom_edp_phy_power_on, 900 .power_off = qcom_edp_phy_power_off, 901 .set_mode = qcom_edp_phy_set_mode, 902 .exit = qcom_edp_phy_exit, 903 .owner = THIS_MODULE, 904}; 905 906/* 907 * Embedded Display Port PLL driver block diagram for branch clocks 908 * 909 * +------------------------------+ 910 * | EDP_VCO_CLK | 911 * | | 912 * | +-------------------+ | 913 * | | (EDP PLL/VCO) | | 914 * | +---------+---------+ | 915 * | v | 916 * | +----------+-----------+ | 917 * | | hsclk_divsel_clk_src | | 918 * | +----------+-----------+ | 919 * +------------------------------+ 920 * | 921 * +---------<---------v------------>----------+ 922 * | | 923 * +--------v----------------+ | 924 * | edp_phy_pll_link_clk | | 925 * | link_clk | | 926 * +--------+----------------+ | 927 * | | 928 * | | 929 * v v 930 * Input to DISPCC block | 931 * for link clk, crypto clk | 932 * and interface clock | 933 * | 934 * | 935 * +--------<------------+-----------------+---<---+ 936 * | | | 937 * +----v---------+ +--------v-----+ +--------v------+ 938 * | vco_divided | | vco_divided | | vco_divided | 939 * | _clk_src | | _clk_src | | _clk_src | 940 * | | | | | | 941 * |divsel_six | | divsel_two | | divsel_four | 942 * +-------+------+ +-----+--------+ +--------+------+ 943 * | | | 944 * v---->----------v-------------<------v 945 * | 946 * +----------+-----------------+ 947 * | edp_phy_pll_vco_div_clk | 948 * +---------+------------------+ 949 * | 950 * v 951 * Input to DISPCC block 952 * for EDP pixel clock 953 * 954 */ 955static int qcom_edp_dp_pixel_clk_determine_rate(struct clk_hw *hw, 956 struct clk_rate_request *req) 957{ 958 switch (req->rate) { 959 case 1620000000UL / 2: 960 case 2700000000UL / 2: 961 /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */ 962 return 0; 963 964 default: 965 return -EINVAL; 966 } 967} 968 969static unsigned long 970qcom_edp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 971{ 972 const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_pixel_hw); 973 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 974 975 switch (dp_opts->link_rate) { 976 case 1620: 977 return 1620000000UL / 2; 978 case 2700: 979 return 2700000000UL / 2; 980 case 5400: 981 return 5400000000UL / 4; 982 case 8100: 983 return 8100000000UL / 6; 984 default: 985 return 0; 986 } 987} 988 989static const struct clk_ops qcom_edp_dp_pixel_clk_ops = { 990 .determine_rate = qcom_edp_dp_pixel_clk_determine_rate, 991 .recalc_rate = qcom_edp_dp_pixel_clk_recalc_rate, 992}; 993 994static int qcom_edp_dp_link_clk_determine_rate(struct clk_hw *hw, 995 struct clk_rate_request *req) 996{ 997 switch (req->rate) { 998 case 162000000: 999 case 270000000: 1000 case 540000000: 1001 case 810000000: 1002 return 0; 1003 1004 default: 1005 return -EINVAL; 1006 } 1007} 1008 1009static unsigned long 1010qcom_edp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 1011{ 1012 const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_link_hw); 1013 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 1014 1015 switch (dp_opts->link_rate) { 1016 case 1620: 1017 case 2700: 1018 case 5400: 1019 case 8100: 1020 return dp_opts->link_rate * 100000; 1021 1022 default: 1023 return 0; 1024 } 1025} 1026 1027static const struct clk_ops qcom_edp_dp_link_clk_ops = { 1028 .determine_rate = qcom_edp_dp_link_clk_determine_rate, 1029 .recalc_rate = qcom_edp_dp_link_clk_recalc_rate, 1030}; 1031 1032static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np) 1033{ 1034 struct clk_hw_onecell_data *data; 1035 struct clk_init_data init = { }; 1036 char name[64]; 1037 int ret; 1038 1039 data = devm_kzalloc(edp->dev, struct_size(data, hws, 2), GFP_KERNEL); 1040 if (!data) 1041 return -ENOMEM; 1042 data->num = 2; 1043 1044 snprintf(name, sizeof(name), "%s::link_clk", dev_name(edp->dev)); 1045 init.ops = &qcom_edp_dp_link_clk_ops; 1046 init.name = name; 1047 edp->dp_link_hw.init = &init; 1048 ret = devm_clk_hw_register(edp->dev, &edp->dp_link_hw); 1049 if (ret) 1050 return ret; 1051 1052 snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(edp->dev)); 1053 init.ops = &qcom_edp_dp_pixel_clk_ops; 1054 init.name = name; 1055 edp->dp_pixel_hw.init = &init; 1056 ret = devm_clk_hw_register(edp->dev, &edp->dp_pixel_hw); 1057 if (ret) 1058 return ret; 1059 1060 data->hws[0] = &edp->dp_link_hw; 1061 data->hws[1] = &edp->dp_pixel_hw; 1062 1063 return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data); 1064} 1065 1066static int qcom_edp_phy_probe(struct platform_device *pdev) 1067{ 1068 struct phy_provider *phy_provider; 1069 struct device *dev = &pdev->dev; 1070 struct qcom_edp *edp; 1071 int ret; 1072 1073 edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL); 1074 if (!edp) 1075 return -ENOMEM; 1076 1077 edp->dev = dev; 1078 edp->cfg = of_device_get_match_data(&pdev->dev); 1079 edp->is_edp = edp->cfg->is_edp; 1080 1081 edp->edp = devm_platform_ioremap_resource(pdev, 0); 1082 if (IS_ERR(edp->edp)) 1083 return PTR_ERR(edp->edp); 1084 1085 edp->tx0 = devm_platform_ioremap_resource(pdev, 1); 1086 if (IS_ERR(edp->tx0)) 1087 return PTR_ERR(edp->tx0); 1088 1089 edp->tx1 = devm_platform_ioremap_resource(pdev, 2); 1090 if (IS_ERR(edp->tx1)) 1091 return PTR_ERR(edp->tx1); 1092 1093 edp->pll = devm_platform_ioremap_resource(pdev, 3); 1094 if (IS_ERR(edp->pll)) 1095 return PTR_ERR(edp->pll); 1096 1097 edp->num_clks = devm_clk_bulk_get_all(dev, &edp->clks); 1098 if (edp->num_clks < 0) 1099 return dev_err_probe(dev, edp->num_clks, "failed to get clocks\n"); 1100 1101 edp->supplies[0].supply = "vdda-phy"; 1102 edp->supplies[1].supply = "vdda-pll"; 1103 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies), edp->supplies); 1104 if (ret) 1105 return ret; 1106 1107 ret = regulator_set_load(edp->supplies[0].consumer, 21800); /* 1.2 V vdda-phy */ 1108 if (ret) { 1109 dev_err(dev, "failed to set load at %s\n", edp->supplies[0].supply); 1110 return ret; 1111 } 1112 1113 ret = regulator_set_load(edp->supplies[1].consumer, 36000); /* 0.9 V vdda-pll */ 1114 if (ret) { 1115 dev_err(dev, "failed to set load at %s\n", edp->supplies[1].supply); 1116 return ret; 1117 } 1118 1119 ret = qcom_edp_clks_register(edp, pdev->dev.of_node); 1120 if (ret) 1121 return ret; 1122 1123 edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops); 1124 if (IS_ERR(edp->phy)) { 1125 dev_err(dev, "failed to register phy\n"); 1126 return PTR_ERR(edp->phy); 1127 } 1128 1129 phy_set_drvdata(edp->phy, edp); 1130 1131 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 1132 return PTR_ERR_OR_ZERO(phy_provider); 1133} 1134 1135static const struct of_device_id qcom_edp_phy_match_table[] = { 1136 { .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, }, 1137 { .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, }, 1138 { .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, }, 1139 { .compatible = "qcom,sc8280xp-dp-phy", .data = &sc8280xp_dp_phy_cfg, }, 1140 { .compatible = "qcom,sc8280xp-edp-phy", .data = &sc8280xp_edp_phy_cfg, }, 1141 { .compatible = "qcom,x1e80100-dp-phy", .data = &x1e80100_phy_cfg, }, 1142 { } 1143}; 1144MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table); 1145 1146static struct platform_driver qcom_edp_phy_driver = { 1147 .probe = qcom_edp_phy_probe, 1148 .driver = { 1149 .name = "qcom-edp-phy", 1150 .of_match_table = qcom_edp_phy_match_table, 1151 }, 1152}; 1153 1154module_platform_driver(qcom_edp_phy_driver); 1155 1156MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@linaro.org>"); 1157MODULE_DESCRIPTION("Qualcomm eDP QMP PHY driver"); 1158MODULE_LICENSE("GPL v2");
~/
Read-only file preview.