phy-qcom-edp.c (19483B)
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/of_device.h> 17#include <linux/of_address.h> 18#include <linux/phy/phy.h> 19#include <linux/platform_device.h> 20#include <linux/regulator/consumer.h> 21#include <linux/reset.h> 22#include <linux/slab.h> 23 24#include <dt-bindings/phy/phy.h> 25 26#include "phy-qcom-qmp.h" 27 28/* EDP_PHY registers */ 29#define DP_PHY_CFG 0x0010 30#define DP_PHY_CFG_1 0x0014 31#define DP_PHY_PD_CTL 0x001c 32#define DP_PHY_MODE 0x0020 33 34#define DP_PHY_AUX_CFG0 0x0024 35#define DP_PHY_AUX_CFG1 0x0028 36#define DP_PHY_AUX_CFG2 0x002C 37#define DP_PHY_AUX_CFG3 0x0030 38#define DP_PHY_AUX_CFG4 0x0034 39#define DP_PHY_AUX_CFG5 0x0038 40#define DP_PHY_AUX_CFG6 0x003C 41#define DP_PHY_AUX_CFG7 0x0040 42#define DP_PHY_AUX_CFG8 0x0044 43#define DP_PHY_AUX_CFG9 0x0048 44 45#define DP_PHY_AUX_INTERRUPT_MASK 0x0058 46 47#define DP_PHY_VCO_DIV 0x0074 48#define DP_PHY_TX0_TX1_LANE_CTL 0x007c 49#define DP_PHY_TX2_TX3_LANE_CTL 0x00a0 50 51#define DP_PHY_STATUS 0x00e0 52 53/* LANE_TXn registers */ 54#define TXn_CLKBUF_ENABLE 0x0000 55#define TXn_TX_EMP_POST1_LVL 0x0004 56 57#define TXn_TX_DRV_LVL 0x0014 58#define TXn_TX_DRV_LVL_OFFSET 0x0018 59#define TXn_RESET_TSYNC_EN 0x001c 60#define TXn_LDO_CONFIG 0x0084 61#define TXn_TX_BAND 0x0028 62 63#define TXn_RES_CODE_LANE_OFFSET_TX0 0x0044 64#define TXn_RES_CODE_LANE_OFFSET_TX1 0x0048 65 66#define TXn_TRANSCEIVER_BIAS_EN 0x0054 67#define TXn_HIGHZ_DRVR_EN 0x0058 68#define TXn_TX_POL_INV 0x005c 69#define TXn_LANE_MODE_1 0x0064 70 71#define TXn_TRAN_DRVR_EMP_EN 0x0078 72 73struct qcom_edp { 74 struct device *dev; 75 76 struct phy *phy; 77 78 void __iomem *edp; 79 void __iomem *tx0; 80 void __iomem *tx1; 81 void __iomem *pll; 82 83 struct clk_hw dp_link_hw; 84 struct clk_hw dp_pixel_hw; 85 86 struct phy_configure_opts_dp dp_opts; 87 88 struct clk_bulk_data clks[2]; 89 struct regulator_bulk_data supplies[2]; 90}; 91 92static int qcom_edp_phy_init(struct phy *phy) 93{ 94 struct qcom_edp *edp = phy_get_drvdata(phy); 95 int ret; 96 97 ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies); 98 if (ret) 99 return ret; 100 101 ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks); 102 if (ret) 103 goto out_disable_supplies; 104 105 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 106 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 107 edp->edp + DP_PHY_PD_CTL); 108 109 /* Turn on BIAS current for PHY/PLL */ 110 writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN); 111 112 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL); 113 msleep(20); 114 115 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 116 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 117 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 118 edp->edp + DP_PHY_PD_CTL); 119 120 writel(0x00, edp->edp + DP_PHY_AUX_CFG0); 121 writel(0x13, edp->edp + DP_PHY_AUX_CFG1); 122 writel(0x24, edp->edp + DP_PHY_AUX_CFG2); 123 writel(0x00, edp->edp + DP_PHY_AUX_CFG3); 124 writel(0x0a, edp->edp + DP_PHY_AUX_CFG4); 125 writel(0x26, edp->edp + DP_PHY_AUX_CFG5); 126 writel(0x0a, edp->edp + DP_PHY_AUX_CFG6); 127 writel(0x03, edp->edp + DP_PHY_AUX_CFG7); 128 writel(0x37, edp->edp + DP_PHY_AUX_CFG8); 129 writel(0x03, edp->edp + DP_PHY_AUX_CFG9); 130 131 writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | 132 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | 133 PHY_AUX_REQ_ERR_MASK, edp->edp + DP_PHY_AUX_INTERRUPT_MASK); 134 135 msleep(20); 136 137 return 0; 138 139out_disable_supplies: 140 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); 141 142 return ret; 143} 144 145static int qcom_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts) 146{ 147 const struct phy_configure_opts_dp *dp_opts = &opts->dp; 148 struct qcom_edp *edp = phy_get_drvdata(phy); 149 150 memcpy(&edp->dp_opts, dp_opts, sizeof(*dp_opts)); 151 152 return 0; 153} 154 155static int qcom_edp_configure_ssc(const struct qcom_edp *edp) 156{ 157 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 158 u32 step1; 159 u32 step2; 160 161 switch (dp_opts->link_rate) { 162 case 1620: 163 case 2700: 164 case 8100: 165 step1 = 0x45; 166 step2 = 0x06; 167 break; 168 169 case 5400: 170 step1 = 0x5c; 171 step2 = 0x08; 172 break; 173 174 default: 175 /* Other link rates aren't supported */ 176 return -EINVAL; 177 } 178 179 writel(0x01, edp->pll + QSERDES_V4_COM_SSC_EN_CENTER); 180 writel(0x00, edp->pll + QSERDES_V4_COM_SSC_ADJ_PER1); 181 writel(0x36, edp->pll + QSERDES_V4_COM_SSC_PER1); 182 writel(0x01, edp->pll + QSERDES_V4_COM_SSC_PER2); 183 writel(step1, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0); 184 writel(step2, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0); 185 186 return 0; 187} 188 189static int qcom_edp_configure_pll(const struct qcom_edp *edp) 190{ 191 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 192 u32 div_frac_start2_mode0; 193 u32 div_frac_start3_mode0; 194 u32 dec_start_mode0; 195 u32 lock_cmp1_mode0; 196 u32 lock_cmp2_mode0; 197 u32 hsclk_sel; 198 199 switch (dp_opts->link_rate) { 200 case 1620: 201 hsclk_sel = 0x5; 202 dec_start_mode0 = 0x69; 203 div_frac_start2_mode0 = 0x80; 204 div_frac_start3_mode0 = 0x07; 205 lock_cmp1_mode0 = 0x6f; 206 lock_cmp2_mode0 = 0x08; 207 break; 208 209 case 2700: 210 hsclk_sel = 0x3; 211 dec_start_mode0 = 0x69; 212 div_frac_start2_mode0 = 0x80; 213 div_frac_start3_mode0 = 0x07; 214 lock_cmp1_mode0 = 0x0f; 215 lock_cmp2_mode0 = 0x0e; 216 break; 217 218 case 5400: 219 hsclk_sel = 0x1; 220 dec_start_mode0 = 0x8c; 221 div_frac_start2_mode0 = 0x00; 222 div_frac_start3_mode0 = 0x0a; 223 lock_cmp1_mode0 = 0x1f; 224 lock_cmp2_mode0 = 0x1c; 225 break; 226 227 case 8100: 228 hsclk_sel = 0x0; 229 dec_start_mode0 = 0x69; 230 div_frac_start2_mode0 = 0x80; 231 div_frac_start3_mode0 = 0x07; 232 lock_cmp1_mode0 = 0x2f; 233 lock_cmp2_mode0 = 0x2a; 234 break; 235 236 default: 237 /* Other link rates aren't supported */ 238 return -EINVAL; 239 } 240 241 writel(0x01, edp->pll + QSERDES_V4_COM_SVS_MODE_CLK_SEL); 242 writel(0x0b, edp->pll + QSERDES_V4_COM_SYSCLK_EN_SEL); 243 writel(0x02, edp->pll + QSERDES_V4_COM_SYS_CLK_CTRL); 244 writel(0x0c, edp->pll + QSERDES_V4_COM_CLK_ENABLE1); 245 writel(0x06, edp->pll + QSERDES_V4_COM_SYSCLK_BUF_ENABLE); 246 writel(0x30, edp->pll + QSERDES_V4_COM_CLK_SELECT); 247 writel(hsclk_sel, edp->pll + QSERDES_V4_COM_HSCLK_SEL); 248 writel(0x0f, edp->pll + QSERDES_V4_COM_PLL_IVCO); 249 writel(0x08, edp->pll + QSERDES_V4_COM_LOCK_CMP_EN); 250 writel(0x36, edp->pll + QSERDES_V4_COM_PLL_CCTRL_MODE0); 251 writel(0x16, edp->pll + QSERDES_V4_COM_PLL_RCTRL_MODE0); 252 writel(0x06, edp->pll + QSERDES_V4_COM_CP_CTRL_MODE0); 253 writel(dec_start_mode0, edp->pll + QSERDES_V4_COM_DEC_START_MODE0); 254 writel(0x00, edp->pll + QSERDES_V4_COM_DIV_FRAC_START1_MODE0); 255 writel(div_frac_start2_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START2_MODE0); 256 writel(div_frac_start3_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START3_MODE0); 257 writel(0x02, edp->pll + QSERDES_V4_COM_CMN_CONFIG); 258 writel(0x3f, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0); 259 writel(0x00, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0); 260 writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_MAP); 261 writel(lock_cmp1_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP1_MODE0); 262 writel(lock_cmp2_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP2_MODE0); 263 264 writel(0x0a, edp->pll + QSERDES_V4_COM_BG_TIMER); 265 writel(0x14, edp->pll + QSERDES_V4_COM_CORECLK_DIV_MODE0); 266 writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_CTRL); 267 writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN); 268 writel(0x0f, edp->pll + QSERDES_V4_COM_CORE_CLK_EN); 269 writel(0xa0, edp->pll + QSERDES_V4_COM_VCO_TUNE1_MODE0); 270 writel(0x03, edp->pll + QSERDES_V4_COM_VCO_TUNE2_MODE0); 271 272 return 0; 273} 274 275static int qcom_edp_set_vco_div(const struct qcom_edp *edp) 276{ 277 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 278 unsigned long pixel_freq; 279 u32 vco_div; 280 281 switch (dp_opts->link_rate) { 282 case 1620: 283 vco_div = 0x1; 284 pixel_freq = 1620000000UL / 2; 285 break; 286 287 case 2700: 288 vco_div = 0x1; 289 pixel_freq = 2700000000UL / 2; 290 break; 291 292 case 5400: 293 vco_div = 0x2; 294 pixel_freq = 5400000000UL / 4; 295 break; 296 297 case 8100: 298 vco_div = 0x0; 299 pixel_freq = 8100000000UL / 6; 300 break; 301 302 default: 303 /* Other link rates aren't supported */ 304 return -EINVAL; 305 } 306 307 writel(vco_div, edp->edp + DP_PHY_VCO_DIV); 308 309 clk_set_rate(edp->dp_link_hw.clk, dp_opts->link_rate * 100000); 310 clk_set_rate(edp->dp_pixel_hw.clk, pixel_freq); 311 312 return 0; 313} 314 315static int qcom_edp_phy_power_on(struct phy *phy) 316{ 317 const struct qcom_edp *edp = phy_get_drvdata(phy); 318 int timeout; 319 int ret; 320 u32 val; 321 322 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | 323 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | 324 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, 325 edp->edp + DP_PHY_PD_CTL); 326 writel(0xfc, edp->edp + DP_PHY_MODE); 327 328 timeout = readl_poll_timeout(edp->pll + QSERDES_V4_COM_CMN_STATUS, 329 val, val & BIT(7), 5, 200); 330 if (timeout) 331 return timeout; 332 333 writel(0x01, edp->tx0 + TXn_LDO_CONFIG); 334 writel(0x01, edp->tx1 + TXn_LDO_CONFIG); 335 writel(0x00, edp->tx0 + TXn_LANE_MODE_1); 336 writel(0x00, edp->tx1 + TXn_LANE_MODE_1); 337 338 if (edp->dp_opts.ssc) { 339 ret = qcom_edp_configure_ssc(edp); 340 if (ret) 341 return ret; 342 } 343 344 ret = qcom_edp_configure_pll(edp); 345 if (ret) 346 return ret; 347 348 /* TX Lane configuration */ 349 writel(0x05, edp->edp + DP_PHY_TX0_TX1_LANE_CTL); 350 writel(0x05, edp->edp + DP_PHY_TX2_TX3_LANE_CTL); 351 352 /* TX-0 register configuration */ 353 writel(0x03, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN); 354 writel(0x0f, edp->tx0 + TXn_CLKBUF_ENABLE); 355 writel(0x03, edp->tx0 + TXn_RESET_TSYNC_EN); 356 writel(0x01, edp->tx0 + TXn_TRAN_DRVR_EMP_EN); 357 writel(0x04, edp->tx0 + TXn_TX_BAND); 358 359 /* TX-1 register configuration */ 360 writel(0x03, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN); 361 writel(0x0f, edp->tx1 + TXn_CLKBUF_ENABLE); 362 writel(0x03, edp->tx1 + TXn_RESET_TSYNC_EN); 363 writel(0x01, edp->tx1 + TXn_TRAN_DRVR_EMP_EN); 364 writel(0x04, edp->tx1 + TXn_TX_BAND); 365 366 ret = qcom_edp_set_vco_div(edp); 367 if (ret) 368 return ret; 369 370 writel(0x01, edp->edp + DP_PHY_CFG); 371 writel(0x05, edp->edp + DP_PHY_CFG); 372 writel(0x01, edp->edp + DP_PHY_CFG); 373 writel(0x09, edp->edp + DP_PHY_CFG); 374 375 writel(0x20, edp->pll + QSERDES_V4_COM_RESETSM_CNTRL); 376 377 timeout = readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS, 378 val, val & BIT(0), 500, 10000); 379 if (timeout) 380 return timeout; 381 382 writel(0x19, edp->edp + DP_PHY_CFG); 383 writel(0x1f, edp->tx0 + TXn_HIGHZ_DRVR_EN); 384 writel(0x04, edp->tx0 + TXn_HIGHZ_DRVR_EN); 385 writel(0x00, edp->tx0 + TXn_TX_POL_INV); 386 writel(0x1f, edp->tx1 + TXn_HIGHZ_DRVR_EN); 387 writel(0x04, edp->tx1 + TXn_HIGHZ_DRVR_EN); 388 writel(0x00, edp->tx1 + TXn_TX_POL_INV); 389 writel(0x10, edp->tx0 + TXn_TX_DRV_LVL_OFFSET); 390 writel(0x10, edp->tx1 + TXn_TX_DRV_LVL_OFFSET); 391 writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX0); 392 writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX1); 393 writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX0); 394 writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX1); 395 396 writel(0x10, edp->tx0 + TXn_TX_EMP_POST1_LVL); 397 writel(0x10, edp->tx1 + TXn_TX_EMP_POST1_LVL); 398 writel(0x1f, edp->tx0 + TXn_TX_DRV_LVL); 399 writel(0x1f, edp->tx1 + TXn_TX_DRV_LVL); 400 401 writel(0x4, edp->tx0 + TXn_HIGHZ_DRVR_EN); 402 writel(0x3, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN); 403 writel(0x4, edp->tx1 + TXn_HIGHZ_DRVR_EN); 404 writel(0x0, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN); 405 writel(0x3, edp->edp + DP_PHY_CFG_1); 406 407 writel(0x18, edp->edp + DP_PHY_CFG); 408 usleep_range(100, 1000); 409 410 writel(0x19, edp->edp + DP_PHY_CFG); 411 412 return readl_poll_timeout(edp->edp + DP_PHY_STATUS, 413 val, val & BIT(1), 500, 10000); 414} 415 416static int qcom_edp_phy_power_off(struct phy *phy) 417{ 418 const struct qcom_edp *edp = phy_get_drvdata(phy); 419 420 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL); 421 422 return 0; 423} 424 425static int qcom_edp_phy_exit(struct phy *phy) 426{ 427 struct qcom_edp *edp = phy_get_drvdata(phy); 428 429 clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks); 430 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); 431 432 return 0; 433} 434 435static const struct phy_ops qcom_edp_ops = { 436 .init = qcom_edp_phy_init, 437 .configure = qcom_edp_phy_configure, 438 .power_on = qcom_edp_phy_power_on, 439 .power_off = qcom_edp_phy_power_off, 440 .exit = qcom_edp_phy_exit, 441 .owner = THIS_MODULE, 442}; 443 444/* 445 * Embedded Display Port PLL driver block diagram for branch clocks 446 * 447 * +------------------------------+ 448 * | EDP_VCO_CLK | 449 * | | 450 * | +-------------------+ | 451 * | | (EDP PLL/VCO) | | 452 * | +---------+---------+ | 453 * | v | 454 * | +----------+-----------+ | 455 * | | hsclk_divsel_clk_src | | 456 * | +----------+-----------+ | 457 * +------------------------------+ 458 * | 459 * +---------<---------v------------>----------+ 460 * | | 461 * +--------v----------------+ | 462 * | edp_phy_pll_link_clk | | 463 * | link_clk | | 464 * +--------+----------------+ | 465 * | | 466 * | | 467 * v v 468 * Input to DISPCC block | 469 * for link clk, crypto clk | 470 * and interface clock | 471 * | 472 * | 473 * +--------<------------+-----------------+---<---+ 474 * | | | 475 * +----v---------+ +--------v-----+ +--------v------+ 476 * | vco_divided | | vco_divided | | vco_divided | 477 * | _clk_src | | _clk_src | | _clk_src | 478 * | | | | | | 479 * |divsel_six | | divsel_two | | divsel_four | 480 * +-------+------+ +-----+--------+ +--------+------+ 481 * | | | 482 * v---->----------v-------------<------v 483 * | 484 * +----------+-----------------+ 485 * | edp_phy_pll_vco_div_clk | 486 * +---------+------------------+ 487 * | 488 * v 489 * Input to DISPCC block 490 * for EDP pixel clock 491 * 492 */ 493static int qcom_edp_dp_pixel_clk_determine_rate(struct clk_hw *hw, 494 struct clk_rate_request *req) 495{ 496 switch (req->rate) { 497 case 1620000000UL / 2: 498 case 2700000000UL / 2: 499 /* 5.4 and 8.1 GHz are same link rate as 2.7GHz, i.e. div 4 and div 6 */ 500 return 0; 501 502 default: 503 return -EINVAL; 504 } 505} 506 507static unsigned long 508qcom_edp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 509{ 510 const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_pixel_hw); 511 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 512 513 switch (dp_opts->link_rate) { 514 case 1620: 515 return 1620000000UL / 2; 516 case 2700: 517 return 2700000000UL / 2; 518 case 5400: 519 return 5400000000UL / 4; 520 case 8100: 521 return 8100000000UL / 6; 522 default: 523 return 0; 524 } 525} 526 527static const struct clk_ops qcom_edp_dp_pixel_clk_ops = { 528 .determine_rate = qcom_edp_dp_pixel_clk_determine_rate, 529 .recalc_rate = qcom_edp_dp_pixel_clk_recalc_rate, 530}; 531 532static int qcom_edp_dp_link_clk_determine_rate(struct clk_hw *hw, 533 struct clk_rate_request *req) 534{ 535 switch (req->rate) { 536 case 162000000: 537 case 270000000: 538 case 540000000: 539 case 810000000: 540 return 0; 541 542 default: 543 return -EINVAL; 544 } 545} 546 547static unsigned long 548qcom_edp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 549{ 550 const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_link_hw); 551 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; 552 553 switch (dp_opts->link_rate) { 554 case 1620: 555 case 2700: 556 case 5400: 557 case 8100: 558 return dp_opts->link_rate * 100000; 559 560 default: 561 return 0; 562 } 563} 564 565static const struct clk_ops qcom_edp_dp_link_clk_ops = { 566 .determine_rate = qcom_edp_dp_link_clk_determine_rate, 567 .recalc_rate = qcom_edp_dp_link_clk_recalc_rate, 568}; 569 570static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np) 571{ 572 struct clk_hw_onecell_data *data; 573 struct clk_init_data init = { }; 574 int ret; 575 576 data = devm_kzalloc(edp->dev, struct_size(data, hws, 2), GFP_KERNEL); 577 if (!data) 578 return -ENOMEM; 579 580 init.ops = &qcom_edp_dp_link_clk_ops; 581 init.name = "edp_phy_pll_link_clk"; 582 edp->dp_link_hw.init = &init; 583 ret = devm_clk_hw_register(edp->dev, &edp->dp_link_hw); 584 if (ret) 585 return ret; 586 587 init.ops = &qcom_edp_dp_pixel_clk_ops; 588 init.name = "edp_phy_pll_vco_div_clk"; 589 edp->dp_pixel_hw.init = &init; 590 ret = devm_clk_hw_register(edp->dev, &edp->dp_pixel_hw); 591 if (ret) 592 return ret; 593 594 data->hws[0] = &edp->dp_link_hw; 595 data->hws[1] = &edp->dp_pixel_hw; 596 data->num = 2; 597 598 return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data); 599} 600 601static int qcom_edp_phy_probe(struct platform_device *pdev) 602{ 603 struct phy_provider *phy_provider; 604 struct device *dev = &pdev->dev; 605 struct qcom_edp *edp; 606 int ret; 607 608 edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL); 609 if (!edp) 610 return -ENOMEM; 611 612 edp->dev = dev; 613 614 edp->edp = devm_platform_ioremap_resource(pdev, 0); 615 if (IS_ERR(edp->edp)) 616 return PTR_ERR(edp->edp); 617 618 edp->tx0 = devm_platform_ioremap_resource(pdev, 1); 619 if (IS_ERR(edp->tx0)) 620 return PTR_ERR(edp->tx0); 621 622 edp->tx1 = devm_platform_ioremap_resource(pdev, 2); 623 if (IS_ERR(edp->tx1)) 624 return PTR_ERR(edp->tx1); 625 626 edp->pll = devm_platform_ioremap_resource(pdev, 3); 627 if (IS_ERR(edp->pll)) 628 return PTR_ERR(edp->pll); 629 630 edp->clks[0].id = "aux"; 631 edp->clks[1].id = "cfg_ahb"; 632 ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks); 633 if (ret) 634 return ret; 635 636 edp->supplies[0].supply = "vdda-phy"; 637 edp->supplies[1].supply = "vdda-pll"; 638 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies), edp->supplies); 639 if (ret) 640 return ret; 641 642 ret = qcom_edp_clks_register(edp, pdev->dev.of_node); 643 if (ret) 644 return ret; 645 646 edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops); 647 if (IS_ERR(edp->phy)) { 648 dev_err(dev, "failed to register phy\n"); 649 return PTR_ERR(edp->phy); 650 } 651 652 phy_set_drvdata(edp->phy, edp); 653 654 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 655 return PTR_ERR_OR_ZERO(phy_provider); 656} 657 658static const struct of_device_id qcom_edp_phy_match_table[] = { 659 { .compatible = "qcom,sc7280-edp-phy" }, 660 { .compatible = "qcom,sc8180x-edp-phy" }, 661 { } 662}; 663MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table); 664 665static struct platform_driver qcom_edp_phy_driver = { 666 .probe = qcom_edp_phy_probe, 667 .driver = { 668 .name = "qcom-edp-phy", 669 .of_match_table = qcom_edp_phy_match_table, 670 }, 671}; 672 673module_platform_driver(qcom_edp_phy_driver); 674 675MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@linaro.org>"); 676MODULE_DESCRIPTION("Qualcomm eDP QMP PHY driver"); 677MODULE_LICENSE("GPL v2");