0001
0002
0003
0004
0005
0006
0007 #include <linux/clk.h>
0008 #include <linux/clk-provider.h>
0009 #include <linux/delay.h>
0010 #include <linux/err.h>
0011 #include <linux/io.h>
0012 #include <linux/iopoll.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/of_device.h>
0017 #include <linux/of_address.h>
0018 #include <linux/phy/phy.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/regulator/consumer.h>
0021 #include <linux/reset.h>
0022 #include <linux/slab.h>
0023
0024 #include <dt-bindings/phy/phy.h>
0025
0026 #include "phy-qcom-qmp.h"
0027
0028
0029 #define DP_PHY_CFG 0x0010
0030 #define DP_PHY_CFG_1 0x0014
0031 #define DP_PHY_PD_CTL 0x001c
0032 #define DP_PHY_MODE 0x0020
0033
0034 #define DP_PHY_AUX_CFG0 0x0024
0035 #define DP_PHY_AUX_CFG1 0x0028
0036 #define DP_PHY_AUX_CFG2 0x002C
0037 #define DP_PHY_AUX_CFG3 0x0030
0038 #define DP_PHY_AUX_CFG4 0x0034
0039 #define DP_PHY_AUX_CFG5 0x0038
0040 #define DP_PHY_AUX_CFG6 0x003C
0041 #define DP_PHY_AUX_CFG7 0x0040
0042 #define DP_PHY_AUX_CFG8 0x0044
0043 #define DP_PHY_AUX_CFG9 0x0048
0044
0045 #define DP_PHY_AUX_INTERRUPT_MASK 0x0058
0046
0047 #define DP_PHY_VCO_DIV 0x0074
0048 #define DP_PHY_TX0_TX1_LANE_CTL 0x007c
0049 #define DP_PHY_TX2_TX3_LANE_CTL 0x00a0
0050
0051 #define DP_PHY_STATUS 0x00e0
0052
0053
0054 #define TXn_CLKBUF_ENABLE 0x0000
0055 #define TXn_TX_EMP_POST1_LVL 0x0004
0056
0057 #define TXn_TX_DRV_LVL 0x0014
0058 #define TXn_TX_DRV_LVL_OFFSET 0x0018
0059 #define TXn_RESET_TSYNC_EN 0x001c
0060 #define TXn_LDO_CONFIG 0x0084
0061 #define TXn_TX_BAND 0x0028
0062
0063 #define TXn_RES_CODE_LANE_OFFSET_TX0 0x0044
0064 #define TXn_RES_CODE_LANE_OFFSET_TX1 0x0048
0065
0066 #define TXn_TRANSCEIVER_BIAS_EN 0x0054
0067 #define TXn_HIGHZ_DRVR_EN 0x0058
0068 #define TXn_TX_POL_INV 0x005c
0069 #define TXn_LANE_MODE_1 0x0064
0070
0071 #define TXn_TRAN_DRVR_EMP_EN 0x0078
0072
0073 struct qcom_edp {
0074 struct device *dev;
0075
0076 struct phy *phy;
0077
0078 void __iomem *edp;
0079 void __iomem *tx0;
0080 void __iomem *tx1;
0081 void __iomem *pll;
0082
0083 struct clk_hw dp_link_hw;
0084 struct clk_hw dp_pixel_hw;
0085
0086 struct phy_configure_opts_dp dp_opts;
0087
0088 struct clk_bulk_data clks[2];
0089 struct regulator_bulk_data supplies[2];
0090 };
0091
0092 static int qcom_edp_phy_init(struct phy *phy)
0093 {
0094 struct qcom_edp *edp = phy_get_drvdata(phy);
0095 int ret;
0096
0097 ret = regulator_bulk_enable(ARRAY_SIZE(edp->supplies), edp->supplies);
0098 if (ret)
0099 return ret;
0100
0101 ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks);
0102 if (ret)
0103 goto out_disable_supplies;
0104
0105 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
0106 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
0107 edp->edp + DP_PHY_PD_CTL);
0108
0109
0110 writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
0111
0112 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
0113 msleep(20);
0114
0115 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
0116 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
0117 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
0118 edp->edp + DP_PHY_PD_CTL);
0119
0120 writel(0x00, edp->edp + DP_PHY_AUX_CFG0);
0121 writel(0x13, edp->edp + DP_PHY_AUX_CFG1);
0122 writel(0x24, edp->edp + DP_PHY_AUX_CFG2);
0123 writel(0x00, edp->edp + DP_PHY_AUX_CFG3);
0124 writel(0x0a, edp->edp + DP_PHY_AUX_CFG4);
0125 writel(0x26, edp->edp + DP_PHY_AUX_CFG5);
0126 writel(0x0a, edp->edp + DP_PHY_AUX_CFG6);
0127 writel(0x03, edp->edp + DP_PHY_AUX_CFG7);
0128 writel(0x37, edp->edp + DP_PHY_AUX_CFG8);
0129 writel(0x03, edp->edp + DP_PHY_AUX_CFG9);
0130
0131 writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
0132 PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
0133 PHY_AUX_REQ_ERR_MASK, edp->edp + DP_PHY_AUX_INTERRUPT_MASK);
0134
0135 msleep(20);
0136
0137 return 0;
0138
0139 out_disable_supplies:
0140 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
0141
0142 return ret;
0143 }
0144
0145 static int qcom_edp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
0146 {
0147 const struct phy_configure_opts_dp *dp_opts = &opts->dp;
0148 struct qcom_edp *edp = phy_get_drvdata(phy);
0149
0150 memcpy(&edp->dp_opts, dp_opts, sizeof(*dp_opts));
0151
0152 return 0;
0153 }
0154
0155 static int qcom_edp_configure_ssc(const struct qcom_edp *edp)
0156 {
0157 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
0158 u32 step1;
0159 u32 step2;
0160
0161 switch (dp_opts->link_rate) {
0162 case 1620:
0163 case 2700:
0164 case 8100:
0165 step1 = 0x45;
0166 step2 = 0x06;
0167 break;
0168
0169 case 5400:
0170 step1 = 0x5c;
0171 step2 = 0x08;
0172 break;
0173
0174 default:
0175
0176 return -EINVAL;
0177 }
0178
0179 writel(0x01, edp->pll + QSERDES_V4_COM_SSC_EN_CENTER);
0180 writel(0x00, edp->pll + QSERDES_V4_COM_SSC_ADJ_PER1);
0181 writel(0x36, edp->pll + QSERDES_V4_COM_SSC_PER1);
0182 writel(0x01, edp->pll + QSERDES_V4_COM_SSC_PER2);
0183 writel(step1, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0);
0184 writel(step2, edp->pll + QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0);
0185
0186 return 0;
0187 }
0188
0189 static int qcom_edp_configure_pll(const struct qcom_edp *edp)
0190 {
0191 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
0192 u32 div_frac_start2_mode0;
0193 u32 div_frac_start3_mode0;
0194 u32 dec_start_mode0;
0195 u32 lock_cmp1_mode0;
0196 u32 lock_cmp2_mode0;
0197 u32 hsclk_sel;
0198
0199 switch (dp_opts->link_rate) {
0200 case 1620:
0201 hsclk_sel = 0x5;
0202 dec_start_mode0 = 0x69;
0203 div_frac_start2_mode0 = 0x80;
0204 div_frac_start3_mode0 = 0x07;
0205 lock_cmp1_mode0 = 0x6f;
0206 lock_cmp2_mode0 = 0x08;
0207 break;
0208
0209 case 2700:
0210 hsclk_sel = 0x3;
0211 dec_start_mode0 = 0x69;
0212 div_frac_start2_mode0 = 0x80;
0213 div_frac_start3_mode0 = 0x07;
0214 lock_cmp1_mode0 = 0x0f;
0215 lock_cmp2_mode0 = 0x0e;
0216 break;
0217
0218 case 5400:
0219 hsclk_sel = 0x1;
0220 dec_start_mode0 = 0x8c;
0221 div_frac_start2_mode0 = 0x00;
0222 div_frac_start3_mode0 = 0x0a;
0223 lock_cmp1_mode0 = 0x1f;
0224 lock_cmp2_mode0 = 0x1c;
0225 break;
0226
0227 case 8100:
0228 hsclk_sel = 0x0;
0229 dec_start_mode0 = 0x69;
0230 div_frac_start2_mode0 = 0x80;
0231 div_frac_start3_mode0 = 0x07;
0232 lock_cmp1_mode0 = 0x2f;
0233 lock_cmp2_mode0 = 0x2a;
0234 break;
0235
0236 default:
0237
0238 return -EINVAL;
0239 }
0240
0241 writel(0x01, edp->pll + QSERDES_V4_COM_SVS_MODE_CLK_SEL);
0242 writel(0x0b, edp->pll + QSERDES_V4_COM_SYSCLK_EN_SEL);
0243 writel(0x02, edp->pll + QSERDES_V4_COM_SYS_CLK_CTRL);
0244 writel(0x0c, edp->pll + QSERDES_V4_COM_CLK_ENABLE1);
0245 writel(0x06, edp->pll + QSERDES_V4_COM_SYSCLK_BUF_ENABLE);
0246 writel(0x30, edp->pll + QSERDES_V4_COM_CLK_SELECT);
0247 writel(hsclk_sel, edp->pll + QSERDES_V4_COM_HSCLK_SEL);
0248 writel(0x0f, edp->pll + QSERDES_V4_COM_PLL_IVCO);
0249 writel(0x08, edp->pll + QSERDES_V4_COM_LOCK_CMP_EN);
0250 writel(0x36, edp->pll + QSERDES_V4_COM_PLL_CCTRL_MODE0);
0251 writel(0x16, edp->pll + QSERDES_V4_COM_PLL_RCTRL_MODE0);
0252 writel(0x06, edp->pll + QSERDES_V4_COM_CP_CTRL_MODE0);
0253 writel(dec_start_mode0, edp->pll + QSERDES_V4_COM_DEC_START_MODE0);
0254 writel(0x00, edp->pll + QSERDES_V4_COM_DIV_FRAC_START1_MODE0);
0255 writel(div_frac_start2_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START2_MODE0);
0256 writel(div_frac_start3_mode0, edp->pll + QSERDES_V4_COM_DIV_FRAC_START3_MODE0);
0257 writel(0x02, edp->pll + QSERDES_V4_COM_CMN_CONFIG);
0258 writel(0x3f, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE0);
0259 writel(0x00, edp->pll + QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0);
0260 writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_MAP);
0261 writel(lock_cmp1_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP1_MODE0);
0262 writel(lock_cmp2_mode0, edp->pll + QSERDES_V4_COM_LOCK_CMP2_MODE0);
0263
0264 writel(0x0a, edp->pll + QSERDES_V4_COM_BG_TIMER);
0265 writel(0x14, edp->pll + QSERDES_V4_COM_CORECLK_DIV_MODE0);
0266 writel(0x00, edp->pll + QSERDES_V4_COM_VCO_TUNE_CTRL);
0267 writel(0x17, edp->pll + QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN);
0268 writel(0x0f, edp->pll + QSERDES_V4_COM_CORE_CLK_EN);
0269 writel(0xa0, edp->pll + QSERDES_V4_COM_VCO_TUNE1_MODE0);
0270 writel(0x03, edp->pll + QSERDES_V4_COM_VCO_TUNE2_MODE0);
0271
0272 return 0;
0273 }
0274
0275 static int qcom_edp_set_vco_div(const struct qcom_edp *edp)
0276 {
0277 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
0278 unsigned long pixel_freq;
0279 u32 vco_div;
0280
0281 switch (dp_opts->link_rate) {
0282 case 1620:
0283 vco_div = 0x1;
0284 pixel_freq = 1620000000UL / 2;
0285 break;
0286
0287 case 2700:
0288 vco_div = 0x1;
0289 pixel_freq = 2700000000UL / 2;
0290 break;
0291
0292 case 5400:
0293 vco_div = 0x2;
0294 pixel_freq = 5400000000UL / 4;
0295 break;
0296
0297 case 8100:
0298 vco_div = 0x0;
0299 pixel_freq = 8100000000UL / 6;
0300 break;
0301
0302 default:
0303
0304 return -EINVAL;
0305 }
0306
0307 writel(vco_div, edp->edp + DP_PHY_VCO_DIV);
0308
0309 clk_set_rate(edp->dp_link_hw.clk, dp_opts->link_rate * 100000);
0310 clk_set_rate(edp->dp_pixel_hw.clk, pixel_freq);
0311
0312 return 0;
0313 }
0314
0315 static int qcom_edp_phy_power_on(struct phy *phy)
0316 {
0317 const struct qcom_edp *edp = phy_get_drvdata(phy);
0318 int timeout;
0319 int ret;
0320 u32 val;
0321
0322 writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
0323 DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN |
0324 DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
0325 edp->edp + DP_PHY_PD_CTL);
0326 writel(0xfc, edp->edp + DP_PHY_MODE);
0327
0328 timeout = readl_poll_timeout(edp->pll + QSERDES_V4_COM_CMN_STATUS,
0329 val, val & BIT(7), 5, 200);
0330 if (timeout)
0331 return timeout;
0332
0333 writel(0x01, edp->tx0 + TXn_LDO_CONFIG);
0334 writel(0x01, edp->tx1 + TXn_LDO_CONFIG);
0335 writel(0x00, edp->tx0 + TXn_LANE_MODE_1);
0336 writel(0x00, edp->tx1 + TXn_LANE_MODE_1);
0337
0338 if (edp->dp_opts.ssc) {
0339 ret = qcom_edp_configure_ssc(edp);
0340 if (ret)
0341 return ret;
0342 }
0343
0344 ret = qcom_edp_configure_pll(edp);
0345 if (ret)
0346 return ret;
0347
0348
0349 writel(0x05, edp->edp + DP_PHY_TX0_TX1_LANE_CTL);
0350 writel(0x05, edp->edp + DP_PHY_TX2_TX3_LANE_CTL);
0351
0352
0353 writel(0x03, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN);
0354 writel(0x0f, edp->tx0 + TXn_CLKBUF_ENABLE);
0355 writel(0x03, edp->tx0 + TXn_RESET_TSYNC_EN);
0356 writel(0x01, edp->tx0 + TXn_TRAN_DRVR_EMP_EN);
0357 writel(0x04, edp->tx0 + TXn_TX_BAND);
0358
0359
0360 writel(0x03, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN);
0361 writel(0x0f, edp->tx1 + TXn_CLKBUF_ENABLE);
0362 writel(0x03, edp->tx1 + TXn_RESET_TSYNC_EN);
0363 writel(0x01, edp->tx1 + TXn_TRAN_DRVR_EMP_EN);
0364 writel(0x04, edp->tx1 + TXn_TX_BAND);
0365
0366 ret = qcom_edp_set_vco_div(edp);
0367 if (ret)
0368 return ret;
0369
0370 writel(0x01, edp->edp + DP_PHY_CFG);
0371 writel(0x05, edp->edp + DP_PHY_CFG);
0372 writel(0x01, edp->edp + DP_PHY_CFG);
0373 writel(0x09, edp->edp + DP_PHY_CFG);
0374
0375 writel(0x20, edp->pll + QSERDES_V4_COM_RESETSM_CNTRL);
0376
0377 timeout = readl_poll_timeout(edp->pll + QSERDES_V4_COM_C_READY_STATUS,
0378 val, val & BIT(0), 500, 10000);
0379 if (timeout)
0380 return timeout;
0381
0382 writel(0x19, edp->edp + DP_PHY_CFG);
0383 writel(0x1f, edp->tx0 + TXn_HIGHZ_DRVR_EN);
0384 writel(0x04, edp->tx0 + TXn_HIGHZ_DRVR_EN);
0385 writel(0x00, edp->tx0 + TXn_TX_POL_INV);
0386 writel(0x1f, edp->tx1 + TXn_HIGHZ_DRVR_EN);
0387 writel(0x04, edp->tx1 + TXn_HIGHZ_DRVR_EN);
0388 writel(0x00, edp->tx1 + TXn_TX_POL_INV);
0389 writel(0x10, edp->tx0 + TXn_TX_DRV_LVL_OFFSET);
0390 writel(0x10, edp->tx1 + TXn_TX_DRV_LVL_OFFSET);
0391 writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX0);
0392 writel(0x11, edp->tx0 + TXn_RES_CODE_LANE_OFFSET_TX1);
0393 writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX0);
0394 writel(0x11, edp->tx1 + TXn_RES_CODE_LANE_OFFSET_TX1);
0395
0396 writel(0x10, edp->tx0 + TXn_TX_EMP_POST1_LVL);
0397 writel(0x10, edp->tx1 + TXn_TX_EMP_POST1_LVL);
0398 writel(0x1f, edp->tx0 + TXn_TX_DRV_LVL);
0399 writel(0x1f, edp->tx1 + TXn_TX_DRV_LVL);
0400
0401 writel(0x4, edp->tx0 + TXn_HIGHZ_DRVR_EN);
0402 writel(0x3, edp->tx0 + TXn_TRANSCEIVER_BIAS_EN);
0403 writel(0x4, edp->tx1 + TXn_HIGHZ_DRVR_EN);
0404 writel(0x0, edp->tx1 + TXn_TRANSCEIVER_BIAS_EN);
0405 writel(0x3, edp->edp + DP_PHY_CFG_1);
0406
0407 writel(0x18, edp->edp + DP_PHY_CFG);
0408 usleep_range(100, 1000);
0409
0410 writel(0x19, edp->edp + DP_PHY_CFG);
0411
0412 return readl_poll_timeout(edp->edp + DP_PHY_STATUS,
0413 val, val & BIT(1), 500, 10000);
0414 }
0415
0416 static int qcom_edp_phy_power_off(struct phy *phy)
0417 {
0418 const struct qcom_edp *edp = phy_get_drvdata(phy);
0419
0420 writel(DP_PHY_PD_CTL_PSR_PWRDN, edp->edp + DP_PHY_PD_CTL);
0421
0422 return 0;
0423 }
0424
0425 static int qcom_edp_phy_exit(struct phy *phy)
0426 {
0427 struct qcom_edp *edp = phy_get_drvdata(phy);
0428
0429 clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks);
0430 regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies);
0431
0432 return 0;
0433 }
0434
0435 static const struct phy_ops qcom_edp_ops = {
0436 .init = qcom_edp_phy_init,
0437 .configure = qcom_edp_phy_configure,
0438 .power_on = qcom_edp_phy_power_on,
0439 .power_off = qcom_edp_phy_power_off,
0440 .exit = qcom_edp_phy_exit,
0441 .owner = THIS_MODULE,
0442 };
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493 static int qcom_edp_dp_pixel_clk_determine_rate(struct clk_hw *hw,
0494 struct clk_rate_request *req)
0495 {
0496 switch (req->rate) {
0497 case 1620000000UL / 2:
0498 case 2700000000UL / 2:
0499
0500 return 0;
0501
0502 default:
0503 return -EINVAL;
0504 }
0505 }
0506
0507 static unsigned long
0508 qcom_edp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
0509 {
0510 const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_pixel_hw);
0511 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
0512
0513 switch (dp_opts->link_rate) {
0514 case 1620:
0515 return 1620000000UL / 2;
0516 case 2700:
0517 return 2700000000UL / 2;
0518 case 5400:
0519 return 5400000000UL / 4;
0520 case 8100:
0521 return 8100000000UL / 6;
0522 default:
0523 return 0;
0524 }
0525 }
0526
0527 static const struct clk_ops qcom_edp_dp_pixel_clk_ops = {
0528 .determine_rate = qcom_edp_dp_pixel_clk_determine_rate,
0529 .recalc_rate = qcom_edp_dp_pixel_clk_recalc_rate,
0530 };
0531
0532 static int qcom_edp_dp_link_clk_determine_rate(struct clk_hw *hw,
0533 struct clk_rate_request *req)
0534 {
0535 switch (req->rate) {
0536 case 162000000:
0537 case 270000000:
0538 case 540000000:
0539 case 810000000:
0540 return 0;
0541
0542 default:
0543 return -EINVAL;
0544 }
0545 }
0546
0547 static unsigned long
0548 qcom_edp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
0549 {
0550 const struct qcom_edp *edp = container_of(hw, struct qcom_edp, dp_link_hw);
0551 const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
0552
0553 switch (dp_opts->link_rate) {
0554 case 1620:
0555 case 2700:
0556 case 5400:
0557 case 8100:
0558 return dp_opts->link_rate * 100000;
0559
0560 default:
0561 return 0;
0562 }
0563 }
0564
0565 static const struct clk_ops qcom_edp_dp_link_clk_ops = {
0566 .determine_rate = qcom_edp_dp_link_clk_determine_rate,
0567 .recalc_rate = qcom_edp_dp_link_clk_recalc_rate,
0568 };
0569
0570 static int qcom_edp_clks_register(struct qcom_edp *edp, struct device_node *np)
0571 {
0572 struct clk_hw_onecell_data *data;
0573 struct clk_init_data init = { };
0574 int ret;
0575
0576 data = devm_kzalloc(edp->dev, struct_size(data, hws, 2), GFP_KERNEL);
0577 if (!data)
0578 return -ENOMEM;
0579
0580 init.ops = &qcom_edp_dp_link_clk_ops;
0581 init.name = "edp_phy_pll_link_clk";
0582 edp->dp_link_hw.init = &init;
0583 ret = devm_clk_hw_register(edp->dev, &edp->dp_link_hw);
0584 if (ret)
0585 return ret;
0586
0587 init.ops = &qcom_edp_dp_pixel_clk_ops;
0588 init.name = "edp_phy_pll_vco_div_clk";
0589 edp->dp_pixel_hw.init = &init;
0590 ret = devm_clk_hw_register(edp->dev, &edp->dp_pixel_hw);
0591 if (ret)
0592 return ret;
0593
0594 data->hws[0] = &edp->dp_link_hw;
0595 data->hws[1] = &edp->dp_pixel_hw;
0596 data->num = 2;
0597
0598 return devm_of_clk_add_hw_provider(edp->dev, of_clk_hw_onecell_get, data);
0599 }
0600
0601 static int qcom_edp_phy_probe(struct platform_device *pdev)
0602 {
0603 struct phy_provider *phy_provider;
0604 struct device *dev = &pdev->dev;
0605 struct qcom_edp *edp;
0606 int ret;
0607
0608 edp = devm_kzalloc(dev, sizeof(*edp), GFP_KERNEL);
0609 if (!edp)
0610 return -ENOMEM;
0611
0612 edp->dev = dev;
0613
0614 edp->edp = devm_platform_ioremap_resource(pdev, 0);
0615 if (IS_ERR(edp->edp))
0616 return PTR_ERR(edp->edp);
0617
0618 edp->tx0 = devm_platform_ioremap_resource(pdev, 1);
0619 if (IS_ERR(edp->tx0))
0620 return PTR_ERR(edp->tx0);
0621
0622 edp->tx1 = devm_platform_ioremap_resource(pdev, 2);
0623 if (IS_ERR(edp->tx1))
0624 return PTR_ERR(edp->tx1);
0625
0626 edp->pll = devm_platform_ioremap_resource(pdev, 3);
0627 if (IS_ERR(edp->pll))
0628 return PTR_ERR(edp->pll);
0629
0630 edp->clks[0].id = "aux";
0631 edp->clks[1].id = "cfg_ahb";
0632 ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks);
0633 if (ret)
0634 return ret;
0635
0636 edp->supplies[0].supply = "vdda-phy";
0637 edp->supplies[1].supply = "vdda-pll";
0638 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(edp->supplies), edp->supplies);
0639 if (ret)
0640 return ret;
0641
0642 ret = regulator_set_load(edp->supplies[0].consumer, 21800);
0643 if (ret) {
0644 dev_err(dev, "failed to set load at %s\n", edp->supplies[0].supply);
0645 return ret;
0646 }
0647
0648 ret = regulator_set_load(edp->supplies[1].consumer, 36000);
0649 if (ret) {
0650 dev_err(dev, "failed to set load at %s\n", edp->supplies[1].supply);
0651 return ret;
0652 }
0653
0654 ret = qcom_edp_clks_register(edp, pdev->dev.of_node);
0655 if (ret)
0656 return ret;
0657
0658 edp->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_edp_ops);
0659 if (IS_ERR(edp->phy)) {
0660 dev_err(dev, "failed to register phy\n");
0661 return PTR_ERR(edp->phy);
0662 }
0663
0664 phy_set_drvdata(edp->phy, edp);
0665
0666 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0667 return PTR_ERR_OR_ZERO(phy_provider);
0668 }
0669
0670 static const struct of_device_id qcom_edp_phy_match_table[] = {
0671 { .compatible = "qcom,sc7280-edp-phy" },
0672 { .compatible = "qcom,sc8180x-edp-phy" },
0673 { }
0674 };
0675 MODULE_DEVICE_TABLE(of, qcom_edp_phy_match_table);
0676
0677 static struct platform_driver qcom_edp_phy_driver = {
0678 .probe = qcom_edp_phy_probe,
0679 .driver = {
0680 .name = "qcom-edp-phy",
0681 .of_match_table = qcom_edp_phy_match_table,
0682 },
0683 };
0684
0685 module_platform_driver(qcom_edp_phy_driver);
0686
0687 MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@linaro.org>");
0688 MODULE_DESCRIPTION("Qualcomm eDP QMP PHY driver");
0689 MODULE_LICENSE("GPL v2");