0001
0002
0003 #include <linux/clk.h>
0004 #include <linux/err.h>
0005 #include <linux/io.h>
0006 #include <linux/module.h>
0007 #include <linux/of_device.h>
0008 #include <linux/phy/phy.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/delay.h>
0011 #include <linux/regmap.h>
0012 #include <linux/mfd/syscon.h>
0013 #include <linux/bitfield.h>
0014
0015
0016 #define QSCRATCH_GENERAL_CFG (0x08)
0017 #define HSUSB_PHY_CTRL_REG (0x10)
0018
0019
0020 #define HSUSB_CTRL_DMSEHV_CLAMP BIT(24)
0021 #define HSUSB_CTRL_USB2_SUSPEND BIT(23)
0022 #define HSUSB_CTRL_UTMI_CLK_EN BIT(21)
0023 #define HSUSB_CTRL_UTMI_OTG_VBUS_VALID BIT(20)
0024 #define HSUSB_CTRL_USE_CLKCORE BIT(18)
0025 #define HSUSB_CTRL_DPSEHV_CLAMP BIT(17)
0026 #define HSUSB_CTRL_COMMONONN BIT(11)
0027 #define HSUSB_CTRL_ID_HV_CLAMP BIT(9)
0028 #define HSUSB_CTRL_OTGSESSVLD_CLAMP BIT(8)
0029 #define HSUSB_CTRL_CLAMP_EN BIT(7)
0030 #define HSUSB_CTRL_RETENABLEN BIT(1)
0031 #define HSUSB_CTRL_POR BIT(0)
0032
0033
0034 #define HSUSB_GCFG_XHCI_REV BIT(2)
0035
0036
0037 #define SSUSB_PHY_CTRL_REG (0x00)
0038 #define SSUSB_PHY_PARAM_CTRL_1 (0x04)
0039 #define SSUSB_PHY_PARAM_CTRL_2 (0x08)
0040 #define CR_PROTOCOL_DATA_IN_REG (0x0c)
0041 #define CR_PROTOCOL_DATA_OUT_REG (0x10)
0042 #define CR_PROTOCOL_CAP_ADDR_REG (0x14)
0043 #define CR_PROTOCOL_CAP_DATA_REG (0x18)
0044 #define CR_PROTOCOL_READ_REG (0x1c)
0045 #define CR_PROTOCOL_WRITE_REG (0x20)
0046
0047
0048 #define SSUSB_CTRL_REF_USE_PAD BIT(28)
0049 #define SSUSB_CTRL_TEST_POWERDOWN BIT(27)
0050 #define SSUSB_CTRL_LANE0_PWR_PRESENT BIT(24)
0051 #define SSUSB_CTRL_SS_PHY_EN BIT(8)
0052 #define SSUSB_CTRL_SS_PHY_RESET BIT(7)
0053
0054
0055 #define SSPHY_CTRL_RX_OVRD_IN_HI(lane) (0x1006 + 0x100 * (lane))
0056 #define SSPHY_CTRL_TX_OVRD_DRV_LO(lane) (0x1002 + 0x100 * (lane))
0057
0058
0059 #define SSPHY_RX_EQ_VALUE 4
0060
0061 #define SSPHY_TX_DEEMPH_3_5DB 23
0062
0063 #define SSPHY_MPLL_VALUE 0
0064
0065
0066 #define PHY_PARAM_CTRL1_TX_FULL_SWING_MASK GENMASK(26, 19)
0067 #define PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK GENMASK(19, 13)
0068 #define PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK GENMASK(13, 7)
0069 #define PHY_PARAM_CTRL1_LOS_BIAS_MASK GENMASK(7, 2)
0070
0071 #define PHY_PARAM_CTRL1_MASK \
0072 (PHY_PARAM_CTRL1_TX_FULL_SWING_MASK | \
0073 PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK | \
0074 PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK | \
0075 PHY_PARAM_CTRL1_LOS_BIAS_MASK)
0076
0077 #define PHY_PARAM_CTRL1_TX_FULL_SWING(x) \
0078 FIELD_PREP(PHY_PARAM_CTRL1_TX_FULL_SWING_MASK, (x))
0079 #define PHY_PARAM_CTRL1_TX_DEEMPH_6DB(x) \
0080 FIELD_PREP(PHY_PARAM_CTRL1_TX_DEEMPH_6DB_MASK, (x))
0081 #define PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB(x) \
0082 FIELD_PREP(PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB_MASK, x)
0083 #define PHY_PARAM_CTRL1_LOS_BIAS(x) \
0084 FIELD_PREP(PHY_PARAM_CTRL1_LOS_BIAS_MASK, (x))
0085
0086
0087 #define RX_OVRD_IN_HI_RX_RESET_OVRD BIT(13)
0088 #define RX_OVRD_IN_HI_RX_RX_RESET BIT(12)
0089 #define RX_OVRD_IN_HI_RX_EQ_OVRD BIT(11)
0090 #define RX_OVRD_IN_HI_RX_EQ_MASK GENMASK(10, 7)
0091 #define RX_OVRD_IN_HI_RX_EQ(x) FIELD_PREP(RX_OVRD_IN_HI_RX_EQ_MASK, (x))
0092 #define RX_OVRD_IN_HI_RX_EQ_EN_OVRD BIT(7)
0093 #define RX_OVRD_IN_HI_RX_EQ_EN BIT(6)
0094 #define RX_OVRD_IN_HI_RX_LOS_FILTER_OVRD BIT(5)
0095 #define RX_OVRD_IN_HI_RX_LOS_FILTER_MASK GENMASK(4, 2)
0096 #define RX_OVRD_IN_HI_RX_RATE_OVRD BIT(2)
0097 #define RX_OVRD_IN_HI_RX_RATE_MASK GENMASK(2, 0)
0098
0099
0100 #define TX_OVRD_DRV_LO_AMPLITUDE_MASK GENMASK(6, 0)
0101 #define TX_OVRD_DRV_LO_PREEMPH_MASK GENMASK(13, 6)
0102 #define TX_OVRD_DRV_LO_PREEMPH(x) ((x) << 7)
0103 #define TX_OVRD_DRV_LO_EN BIT(14)
0104
0105
0106 #define SSPHY_MPLL_MASK GENMASK(8, 5)
0107 #define SSPHY_MPLL(x) ((x) << 5)
0108
0109
0110 #define SS_CR_CAP_ADDR_REG BIT(0)
0111 #define SS_CR_CAP_DATA_REG BIT(0)
0112 #define SS_CR_READ_REG BIT(0)
0113 #define SS_CR_WRITE_REG BIT(0)
0114
0115 #define LATCH_SLEEP 40
0116 #define LATCH_TIMEOUT 100
0117
0118 struct usb_phy {
0119 void __iomem *base;
0120 struct device *dev;
0121 struct clk *xo_clk;
0122 struct clk *ref_clk;
0123 u32 rx_eq;
0124 u32 tx_deamp_3_5db;
0125 u32 mpll;
0126 };
0127
0128 struct phy_drvdata {
0129 struct phy_ops ops;
0130 u32 clk_rate;
0131 };
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 static inline void usb_phy_write_readback(struct usb_phy *phy_dwc3,
0143 u32 offset,
0144 const u32 mask, u32 val)
0145 {
0146 u32 write_val, tmp = readl(phy_dwc3->base + offset);
0147
0148 tmp &= ~mask;
0149 write_val = tmp | val;
0150
0151 writel(write_val, phy_dwc3->base + offset);
0152
0153
0154 tmp = readl(phy_dwc3->base + offset);
0155 tmp &= mask;
0156
0157 if (tmp != val)
0158 dev_err(phy_dwc3->dev, "write: %x to QSCRATCH: %x FAILED\n", val, offset);
0159 }
0160
0161 static int wait_for_latch(void __iomem *addr)
0162 {
0163 u32 val;
0164
0165 return readl_poll_timeout(addr, val, !val, LATCH_SLEEP, LATCH_TIMEOUT);
0166 }
0167
0168
0169
0170
0171
0172
0173
0174
0175 static int usb_ss_write_phycreg(struct usb_phy *phy_dwc3,
0176 u32 addr, u32 val)
0177 {
0178 int ret;
0179
0180 writel(addr, phy_dwc3->base + CR_PROTOCOL_DATA_IN_REG);
0181 writel(SS_CR_CAP_ADDR_REG,
0182 phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG);
0183
0184 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG);
0185 if (ret)
0186 goto err_wait;
0187
0188 writel(val, phy_dwc3->base + CR_PROTOCOL_DATA_IN_REG);
0189 writel(SS_CR_CAP_DATA_REG,
0190 phy_dwc3->base + CR_PROTOCOL_CAP_DATA_REG);
0191
0192 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_CAP_DATA_REG);
0193 if (ret)
0194 goto err_wait;
0195
0196 writel(SS_CR_WRITE_REG, phy_dwc3->base + CR_PROTOCOL_WRITE_REG);
0197
0198 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_WRITE_REG);
0199
0200 err_wait:
0201 if (ret)
0202 dev_err(phy_dwc3->dev, "timeout waiting for latch\n");
0203 return ret;
0204 }
0205
0206
0207
0208
0209
0210
0211
0212
0213 static int usb_ss_read_phycreg(struct usb_phy *phy_dwc3,
0214 u32 addr, u32 *val)
0215 {
0216 int ret;
0217
0218 writel(addr, phy_dwc3->base + CR_PROTOCOL_DATA_IN_REG);
0219 writel(SS_CR_CAP_ADDR_REG,
0220 phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG);
0221
0222 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_CAP_ADDR_REG);
0223 if (ret)
0224 goto err_wait;
0225
0226
0227
0228
0229
0230
0231 writel(SS_CR_READ_REG, phy_dwc3->base + CR_PROTOCOL_READ_REG);
0232
0233 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_READ_REG);
0234 if (ret)
0235 goto err_wait;
0236
0237
0238 readl(phy_dwc3->base + CR_PROTOCOL_DATA_OUT_REG);
0239
0240 writel(SS_CR_READ_REG, phy_dwc3->base + CR_PROTOCOL_READ_REG);
0241
0242 ret = wait_for_latch(phy_dwc3->base + CR_PROTOCOL_READ_REG);
0243 if (ret)
0244 goto err_wait;
0245
0246 *val = readl(phy_dwc3->base + CR_PROTOCOL_DATA_OUT_REG);
0247
0248 err_wait:
0249 return ret;
0250 }
0251
0252 static int qcom_ipq806x_usb_hs_phy_init(struct phy *phy)
0253 {
0254 struct usb_phy *phy_dwc3 = phy_get_drvdata(phy);
0255 int ret;
0256 u32 val;
0257
0258 ret = clk_prepare_enable(phy_dwc3->xo_clk);
0259 if (ret)
0260 return ret;
0261
0262 ret = clk_prepare_enable(phy_dwc3->ref_clk);
0263 if (ret) {
0264 clk_disable_unprepare(phy_dwc3->xo_clk);
0265 return ret;
0266 }
0267
0268
0269
0270
0271
0272 val = HSUSB_CTRL_DPSEHV_CLAMP | HSUSB_CTRL_DMSEHV_CLAMP |
0273 HSUSB_CTRL_RETENABLEN | HSUSB_CTRL_COMMONONN |
0274 HSUSB_CTRL_OTGSESSVLD_CLAMP | HSUSB_CTRL_ID_HV_CLAMP |
0275 HSUSB_CTRL_UTMI_OTG_VBUS_VALID | HSUSB_CTRL_UTMI_CLK_EN |
0276 HSUSB_CTRL_CLAMP_EN | 0x70;
0277
0278
0279 if (!phy_dwc3->xo_clk)
0280 val |= HSUSB_CTRL_USE_CLKCORE;
0281
0282 writel(val, phy_dwc3->base + HSUSB_PHY_CTRL_REG);
0283 usleep_range(2000, 2200);
0284
0285
0286 writel(HSUSB_GCFG_XHCI_REV, phy_dwc3->base + QSCRATCH_GENERAL_CFG);
0287
0288 return 0;
0289 }
0290
0291 static int qcom_ipq806x_usb_hs_phy_exit(struct phy *phy)
0292 {
0293 struct usb_phy *phy_dwc3 = phy_get_drvdata(phy);
0294
0295 clk_disable_unprepare(phy_dwc3->ref_clk);
0296 clk_disable_unprepare(phy_dwc3->xo_clk);
0297
0298 return 0;
0299 }
0300
0301 static int qcom_ipq806x_usb_ss_phy_init(struct phy *phy)
0302 {
0303 struct usb_phy *phy_dwc3 = phy_get_drvdata(phy);
0304 int ret;
0305 u32 data;
0306
0307 ret = clk_prepare_enable(phy_dwc3->xo_clk);
0308 if (ret)
0309 return ret;
0310
0311 ret = clk_prepare_enable(phy_dwc3->ref_clk);
0312 if (ret) {
0313 clk_disable_unprepare(phy_dwc3->xo_clk);
0314 return ret;
0315 }
0316
0317
0318 data = readl(phy_dwc3->base + SSUSB_PHY_CTRL_REG);
0319 writel(data | SSUSB_CTRL_SS_PHY_RESET,
0320 phy_dwc3->base + SSUSB_PHY_CTRL_REG);
0321 usleep_range(2000, 2200);
0322 writel(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG);
0323
0324
0325 if (!phy_dwc3->xo_clk)
0326 data &= ~SSUSB_CTRL_REF_USE_PAD;
0327 else
0328 data |= SSUSB_CTRL_REF_USE_PAD;
0329
0330 writel(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG);
0331
0332
0333 msleep(30);
0334
0335 data |= SSUSB_CTRL_SS_PHY_EN | SSUSB_CTRL_LANE0_PWR_PRESENT;
0336 writel(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG);
0337
0338
0339
0340
0341
0342
0343 ret = usb_ss_read_phycreg(phy_dwc3, 0x102D, &data);
0344 if (ret)
0345 goto err_phy_trans;
0346
0347 data |= (1 << 7);
0348 ret = usb_ss_write_phycreg(phy_dwc3, 0x102D, data);
0349 if (ret)
0350 goto err_phy_trans;
0351
0352 ret = usb_ss_read_phycreg(phy_dwc3, 0x1010, &data);
0353 if (ret)
0354 goto err_phy_trans;
0355
0356 data &= ~0xff0;
0357 data |= 0x20;
0358 ret = usb_ss_write_phycreg(phy_dwc3, 0x1010, data);
0359 if (ret)
0360 goto err_phy_trans;
0361
0362
0363
0364
0365
0366
0367
0368
0369 ret = usb_ss_read_phycreg(phy_dwc3, SSPHY_CTRL_RX_OVRD_IN_HI(0), &data);
0370 if (ret)
0371 goto err_phy_trans;
0372
0373 data &= ~RX_OVRD_IN_HI_RX_EQ_EN;
0374 data |= RX_OVRD_IN_HI_RX_EQ_EN_OVRD;
0375 data &= ~RX_OVRD_IN_HI_RX_EQ_MASK;
0376 data |= RX_OVRD_IN_HI_RX_EQ(phy_dwc3->rx_eq);
0377 data |= RX_OVRD_IN_HI_RX_EQ_OVRD;
0378 ret = usb_ss_write_phycreg(phy_dwc3,
0379 SSPHY_CTRL_RX_OVRD_IN_HI(0), data);
0380 if (ret)
0381 goto err_phy_trans;
0382
0383
0384
0385
0386
0387
0388
0389 ret = usb_ss_read_phycreg(phy_dwc3,
0390 SSPHY_CTRL_TX_OVRD_DRV_LO(0), &data);
0391 if (ret)
0392 goto err_phy_trans;
0393
0394 data &= ~TX_OVRD_DRV_LO_PREEMPH_MASK;
0395 data |= TX_OVRD_DRV_LO_PREEMPH(phy_dwc3->tx_deamp_3_5db);
0396 data &= ~TX_OVRD_DRV_LO_AMPLITUDE_MASK;
0397 data |= 0x6E;
0398 data |= TX_OVRD_DRV_LO_EN;
0399 ret = usb_ss_write_phycreg(phy_dwc3,
0400 SSPHY_CTRL_TX_OVRD_DRV_LO(0), data);
0401 if (ret)
0402 goto err_phy_trans;
0403
0404 data = 0;
0405 data &= ~SSPHY_MPLL_MASK;
0406 data |= SSPHY_MPLL(phy_dwc3->mpll);
0407 usb_ss_write_phycreg(phy_dwc3, 0x30, data);
0408
0409
0410
0411
0412
0413
0414
0415
0416 data = readl(phy_dwc3->base + SSUSB_PHY_PARAM_CTRL_1);
0417
0418 data &= ~PHY_PARAM_CTRL1_MASK;
0419
0420 data |= PHY_PARAM_CTRL1_TX_FULL_SWING(0x6e) |
0421 PHY_PARAM_CTRL1_TX_DEEMPH_6DB(0x20) |
0422 PHY_PARAM_CTRL1_TX_DEEMPH_3_5DB(phy_dwc3->tx_deamp_3_5db) |
0423 PHY_PARAM_CTRL1_LOS_BIAS(0x9);
0424
0425 usb_phy_write_readback(phy_dwc3, SSUSB_PHY_PARAM_CTRL_1,
0426 PHY_PARAM_CTRL1_MASK, data);
0427
0428 err_phy_trans:
0429 return ret;
0430 }
0431
0432 static int qcom_ipq806x_usb_ss_phy_exit(struct phy *phy)
0433 {
0434 struct usb_phy *phy_dwc3 = phy_get_drvdata(phy);
0435
0436
0437
0438
0439
0440
0441 usb_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG,
0442 SSUSB_CTRL_SS_PHY_EN, 0x0);
0443 usb_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG,
0444 SSUSB_CTRL_REF_USE_PAD, 0x0);
0445 usb_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG,
0446 SSUSB_CTRL_TEST_POWERDOWN, 0x0);
0447
0448 clk_disable_unprepare(phy_dwc3->ref_clk);
0449 clk_disable_unprepare(phy_dwc3->xo_clk);
0450
0451 return 0;
0452 }
0453
0454 static const struct phy_drvdata qcom_ipq806x_usb_hs_drvdata = {
0455 .ops = {
0456 .init = qcom_ipq806x_usb_hs_phy_init,
0457 .exit = qcom_ipq806x_usb_hs_phy_exit,
0458 .owner = THIS_MODULE,
0459 },
0460 .clk_rate = 60000000,
0461 };
0462
0463 static const struct phy_drvdata qcom_ipq806x_usb_ss_drvdata = {
0464 .ops = {
0465 .init = qcom_ipq806x_usb_ss_phy_init,
0466 .exit = qcom_ipq806x_usb_ss_phy_exit,
0467 .owner = THIS_MODULE,
0468 },
0469 .clk_rate = 125000000,
0470 };
0471
0472 static const struct of_device_id qcom_ipq806x_usb_phy_table[] = {
0473 { .compatible = "qcom,ipq806x-usb-phy-hs",
0474 .data = &qcom_ipq806x_usb_hs_drvdata },
0475 { .compatible = "qcom,ipq806x-usb-phy-ss",
0476 .data = &qcom_ipq806x_usb_ss_drvdata },
0477 { }
0478 };
0479 MODULE_DEVICE_TABLE(of, qcom_ipq806x_usb_phy_table);
0480
0481 static int qcom_ipq806x_usb_phy_probe(struct platform_device *pdev)
0482 {
0483 struct resource *res;
0484 resource_size_t size;
0485 struct phy *generic_phy;
0486 struct usb_phy *phy_dwc3;
0487 const struct phy_drvdata *data;
0488 struct phy_provider *phy_provider;
0489
0490 phy_dwc3 = devm_kzalloc(&pdev->dev, sizeof(*phy_dwc3), GFP_KERNEL);
0491 if (!phy_dwc3)
0492 return -ENOMEM;
0493
0494 data = of_device_get_match_data(&pdev->dev);
0495
0496 phy_dwc3->dev = &pdev->dev;
0497
0498 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0499 if (!res)
0500 return -EINVAL;
0501 size = resource_size(res);
0502 phy_dwc3->base = devm_ioremap(phy_dwc3->dev, res->start, size);
0503
0504 if (!phy_dwc3->base) {
0505 dev_err(phy_dwc3->dev, "failed to map reg\n");
0506 return -ENOMEM;
0507 }
0508
0509 phy_dwc3->ref_clk = devm_clk_get(phy_dwc3->dev, "ref");
0510 if (IS_ERR(phy_dwc3->ref_clk)) {
0511 dev_dbg(phy_dwc3->dev, "cannot get reference clock\n");
0512 return PTR_ERR(phy_dwc3->ref_clk);
0513 }
0514
0515 clk_set_rate(phy_dwc3->ref_clk, data->clk_rate);
0516
0517 phy_dwc3->xo_clk = devm_clk_get(phy_dwc3->dev, "xo");
0518 if (IS_ERR(phy_dwc3->xo_clk)) {
0519 dev_dbg(phy_dwc3->dev, "cannot get TCXO clock\n");
0520 phy_dwc3->xo_clk = NULL;
0521 }
0522
0523
0524 if (device_property_read_u32(&pdev->dev, "qcom,rx-eq",
0525 &phy_dwc3->rx_eq))
0526 phy_dwc3->rx_eq = SSPHY_RX_EQ_VALUE;
0527
0528 if (device_property_read_u32(&pdev->dev, "qcom,tx-deamp_3_5db",
0529 &phy_dwc3->tx_deamp_3_5db))
0530 phy_dwc3->tx_deamp_3_5db = SSPHY_TX_DEEMPH_3_5DB;
0531
0532 if (device_property_read_u32(&pdev->dev, "qcom,mpll", &phy_dwc3->mpll))
0533 phy_dwc3->mpll = SSPHY_MPLL_VALUE;
0534
0535 generic_phy = devm_phy_create(phy_dwc3->dev, pdev->dev.of_node, &data->ops);
0536
0537 if (IS_ERR(generic_phy))
0538 return PTR_ERR(generic_phy);
0539
0540 phy_set_drvdata(generic_phy, phy_dwc3);
0541 platform_set_drvdata(pdev, phy_dwc3);
0542
0543 phy_provider = devm_of_phy_provider_register(phy_dwc3->dev,
0544 of_phy_simple_xlate);
0545
0546 if (IS_ERR(phy_provider))
0547 return PTR_ERR(phy_provider);
0548
0549 return 0;
0550 }
0551
0552 static struct platform_driver qcom_ipq806x_usb_phy_driver = {
0553 .probe = qcom_ipq806x_usb_phy_probe,
0554 .driver = {
0555 .name = "qcom-ipq806x-usb-phy",
0556 .of_match_table = qcom_ipq806x_usb_phy_table,
0557 },
0558 };
0559
0560 module_platform_driver(qcom_ipq806x_usb_phy_driver);
0561
0562 MODULE_ALIAS("platform:phy-qcom-ipq806x-usb");
0563 MODULE_LICENSE("GPL v2");
0564 MODULE_AUTHOR("Andy Gross <agross@codeaurora.org>");
0565 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
0566 MODULE_DESCRIPTION("DesignWare USB3 QCOM PHY driver");