0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <dt-bindings/phy/phy.h>
0011 #include <linux/clk.h>
0012 #include <linux/delay.h>
0013 #include <linux/iopoll.h>
0014 #include <linux/module.h>
0015 #include <linux/of_address.h>
0016 #include <linux/phy/phy.h>
0017 #include <linux/platform_device.h>
0018
0019 #include "phy-mtk-io.h"
0020
0021
0022 #define SSUSB_SIFSLV_MISC 0x000
0023 #define SSUSB_SIFSLV_U2FREQ 0x100
0024 #define SSUSB_SIFSLV_U2PHY_COM 0x300
0025
0026
0027 #define SSPXTP_SIFSLV_DIG_GLB 0x000
0028 #define SSPXTP_SIFSLV_PHYA_GLB 0x100
0029
0030
0031 #define SSPXTP_SIFSLV_DIG_LN_TOP 0x000
0032 #define SSPXTP_SIFSLV_DIG_LN_TX0 0x100
0033 #define SSPXTP_SIFSLV_DIG_LN_RX0 0x200
0034 #define SSPXTP_SIFSLV_DIG_LN_DAIF 0x300
0035 #define SSPXTP_SIFSLV_PHYA_LN 0x400
0036
0037 #define XSP_U2FREQ_FMCR0 ((SSUSB_SIFSLV_U2FREQ) + 0x00)
0038 #define P2F_RG_FREQDET_EN BIT(24)
0039 #define P2F_RG_CYCLECNT GENMASK(23, 0)
0040 #define P2F_RG_CYCLECNT_VAL(x) ((P2F_RG_CYCLECNT) & (x))
0041
0042 #define XSP_U2FREQ_MMONR0 ((SSUSB_SIFSLV_U2FREQ) + 0x0c)
0043
0044 #define XSP_U2FREQ_FMMONR1 ((SSUSB_SIFSLV_U2FREQ) + 0x10)
0045 #define P2F_RG_FRCK_EN BIT(8)
0046 #define P2F_USB_FM_VALID BIT(0)
0047
0048 #define XSP_USBPHYACR0 ((SSUSB_SIFSLV_U2PHY_COM) + 0x00)
0049 #define P2A0_RG_INTR_EN BIT(5)
0050
0051 #define XSP_USBPHYACR1 ((SSUSB_SIFSLV_U2PHY_COM) + 0x04)
0052 #define P2A1_RG_INTR_CAL GENMASK(23, 19)
0053 #define P2A1_RG_INTR_CAL_VAL(x) ((0x1f & (x)) << 19)
0054 #define P2A1_RG_VRT_SEL GENMASK(14, 12)
0055 #define P2A1_RG_VRT_SEL_VAL(x) ((0x7 & (x)) << 12)
0056 #define P2A1_RG_TERM_SEL GENMASK(10, 8)
0057 #define P2A1_RG_TERM_SEL_VAL(x) ((0x7 & (x)) << 8)
0058
0059 #define XSP_USBPHYACR5 ((SSUSB_SIFSLV_U2PHY_COM) + 0x014)
0060 #define P2A5_RG_HSTX_SRCAL_EN BIT(15)
0061 #define P2A5_RG_HSTX_SRCTRL GENMASK(14, 12)
0062 #define P2A5_RG_HSTX_SRCTRL_VAL(x) ((0x7 & (x)) << 12)
0063
0064 #define XSP_USBPHYACR6 ((SSUSB_SIFSLV_U2PHY_COM) + 0x018)
0065 #define P2A6_RG_BC11_SW_EN BIT(23)
0066 #define P2A6_RG_OTG_VBUSCMP_EN BIT(20)
0067
0068 #define XSP_U2PHYDTM1 ((SSUSB_SIFSLV_U2PHY_COM) + 0x06C)
0069 #define P2D_FORCE_IDDIG BIT(9)
0070 #define P2D_RG_VBUSVALID BIT(5)
0071 #define P2D_RG_SESSEND BIT(4)
0072 #define P2D_RG_AVALID BIT(2)
0073 #define P2D_RG_IDDIG BIT(1)
0074
0075 #define SSPXTP_PHYA_GLB_00 ((SSPXTP_SIFSLV_PHYA_GLB) + 0x00)
0076 #define RG_XTP_GLB_BIAS_INTR_CTRL GENMASK(21, 16)
0077 #define RG_XTP_GLB_BIAS_INTR_CTRL_VAL(x) ((0x3f & (x)) << 16)
0078
0079 #define SSPXTP_PHYA_LN_04 ((SSPXTP_SIFSLV_PHYA_LN) + 0x04)
0080 #define RG_XTP_LN0_TX_IMPSEL GENMASK(4, 0)
0081 #define RG_XTP_LN0_TX_IMPSEL_VAL(x) (0x1f & (x))
0082
0083 #define SSPXTP_PHYA_LN_14 ((SSPXTP_SIFSLV_PHYA_LN) + 0x014)
0084 #define RG_XTP_LN0_RX_IMPSEL GENMASK(4, 0)
0085 #define RG_XTP_LN0_RX_IMPSEL_VAL(x) (0x1f & (x))
0086
0087 #define XSP_REF_CLK 26
0088 #define XSP_SLEW_RATE_COEF 17
0089 #define XSP_SR_COEF_DIVISOR 1000
0090 #define XSP_FM_DET_CYCLE_CNT 1024
0091
0092 struct xsphy_instance {
0093 struct phy *phy;
0094 void __iomem *port_base;
0095 struct clk *ref_clk;
0096 u32 index;
0097 u32 type;
0098
0099 int efuse_intr;
0100 int efuse_tx_imp;
0101 int efuse_rx_imp;
0102
0103 int eye_src;
0104 int eye_vrt;
0105 int eye_term;
0106 };
0107
0108 struct mtk_xsphy {
0109 struct device *dev;
0110 void __iomem *glb_base;
0111 struct xsphy_instance **phys;
0112 int nphys;
0113 int src_ref_clk;
0114 int src_coef;
0115 };
0116
0117 static void u2_phy_slew_rate_calibrate(struct mtk_xsphy *xsphy,
0118 struct xsphy_instance *inst)
0119 {
0120 void __iomem *pbase = inst->port_base;
0121 int calib_val;
0122 int fm_out;
0123 u32 tmp;
0124
0125
0126 if (inst->eye_src)
0127 return;
0128
0129
0130 mtk_phy_set_bits(pbase + XSP_USBPHYACR5, P2A5_RG_HSTX_SRCAL_EN);
0131 udelay(1);
0132
0133
0134 mtk_phy_set_bits(pbase + XSP_U2FREQ_FMMONR1, P2F_RG_FRCK_EN);
0135
0136
0137 mtk_phy_update_bits(pbase + XSP_U2FREQ_FMCR0, P2F_RG_CYCLECNT,
0138 P2F_RG_CYCLECNT_VAL(XSP_FM_DET_CYCLE_CNT));
0139
0140
0141 mtk_phy_set_bits(pbase + XSP_U2FREQ_FMCR0, P2F_RG_FREQDET_EN);
0142
0143
0144 readl_poll_timeout(pbase + XSP_U2FREQ_FMMONR1, tmp,
0145 (tmp & P2F_USB_FM_VALID), 10, 200);
0146
0147 fm_out = readl(pbase + XSP_U2FREQ_MMONR0);
0148
0149
0150 mtk_phy_clear_bits(pbase + XSP_U2FREQ_FMCR0, P2F_RG_FREQDET_EN);
0151
0152
0153 mtk_phy_clear_bits(pbase + XSP_U2FREQ_FMMONR1, P2F_RG_FRCK_EN);
0154
0155 if (fm_out) {
0156
0157 tmp = xsphy->src_ref_clk * xsphy->src_coef;
0158 tmp = (tmp * XSP_FM_DET_CYCLE_CNT) / fm_out;
0159 calib_val = DIV_ROUND_CLOSEST(tmp, XSP_SR_COEF_DIVISOR);
0160 } else {
0161
0162 calib_val = 3;
0163 }
0164 dev_dbg(xsphy->dev, "phy.%d, fm_out:%d, calib:%d (clk:%d, coef:%d)\n",
0165 inst->index, fm_out, calib_val,
0166 xsphy->src_ref_clk, xsphy->src_coef);
0167
0168
0169 mtk_phy_update_bits(pbase + XSP_USBPHYACR5, P2A5_RG_HSTX_SRCTRL,
0170 P2A5_RG_HSTX_SRCTRL_VAL(calib_val));
0171
0172
0173 mtk_phy_clear_bits(pbase + XSP_USBPHYACR5, P2A5_RG_HSTX_SRCAL_EN);
0174 }
0175
0176 static void u2_phy_instance_init(struct mtk_xsphy *xsphy,
0177 struct xsphy_instance *inst)
0178 {
0179 void __iomem *pbase = inst->port_base;
0180
0181
0182 mtk_phy_clear_bits(pbase + XSP_USBPHYACR6, P2A6_RG_BC11_SW_EN);
0183
0184 mtk_phy_set_bits(pbase + XSP_USBPHYACR0, P2A0_RG_INTR_EN);
0185 }
0186
0187 static void u2_phy_instance_power_on(struct mtk_xsphy *xsphy,
0188 struct xsphy_instance *inst)
0189 {
0190 void __iomem *pbase = inst->port_base;
0191 u32 index = inst->index;
0192
0193 mtk_phy_set_bits(pbase + XSP_USBPHYACR6, P2A6_RG_OTG_VBUSCMP_EN);
0194
0195 mtk_phy_update_bits(pbase + XSP_U2PHYDTM1,
0196 P2D_RG_VBUSVALID | P2D_RG_AVALID | P2D_RG_SESSEND,
0197 P2D_RG_VBUSVALID | P2D_RG_AVALID);
0198
0199 dev_dbg(xsphy->dev, "%s(%d)\n", __func__, index);
0200 }
0201
0202 static void u2_phy_instance_power_off(struct mtk_xsphy *xsphy,
0203 struct xsphy_instance *inst)
0204 {
0205 void __iomem *pbase = inst->port_base;
0206 u32 index = inst->index;
0207
0208 mtk_phy_clear_bits(pbase + XSP_USBPHYACR6, P2A6_RG_OTG_VBUSCMP_EN);
0209
0210 mtk_phy_update_bits(pbase + XSP_U2PHYDTM1,
0211 P2D_RG_VBUSVALID | P2D_RG_AVALID | P2D_RG_SESSEND,
0212 P2D_RG_SESSEND);
0213
0214 dev_dbg(xsphy->dev, "%s(%d)\n", __func__, index);
0215 }
0216
0217 static void u2_phy_instance_set_mode(struct mtk_xsphy *xsphy,
0218 struct xsphy_instance *inst,
0219 enum phy_mode mode)
0220 {
0221 u32 tmp;
0222
0223 tmp = readl(inst->port_base + XSP_U2PHYDTM1);
0224 switch (mode) {
0225 case PHY_MODE_USB_DEVICE:
0226 tmp |= P2D_FORCE_IDDIG | P2D_RG_IDDIG;
0227 break;
0228 case PHY_MODE_USB_HOST:
0229 tmp |= P2D_FORCE_IDDIG;
0230 tmp &= ~P2D_RG_IDDIG;
0231 break;
0232 case PHY_MODE_USB_OTG:
0233 tmp &= ~(P2D_FORCE_IDDIG | P2D_RG_IDDIG);
0234 break;
0235 default:
0236 return;
0237 }
0238 writel(tmp, inst->port_base + XSP_U2PHYDTM1);
0239 }
0240
0241 static void phy_parse_property(struct mtk_xsphy *xsphy,
0242 struct xsphy_instance *inst)
0243 {
0244 struct device *dev = &inst->phy->dev;
0245
0246 switch (inst->type) {
0247 case PHY_TYPE_USB2:
0248 device_property_read_u32(dev, "mediatek,efuse-intr",
0249 &inst->efuse_intr);
0250 device_property_read_u32(dev, "mediatek,eye-src",
0251 &inst->eye_src);
0252 device_property_read_u32(dev, "mediatek,eye-vrt",
0253 &inst->eye_vrt);
0254 device_property_read_u32(dev, "mediatek,eye-term",
0255 &inst->eye_term);
0256 dev_dbg(dev, "intr:%d, src:%d, vrt:%d, term:%d\n",
0257 inst->efuse_intr, inst->eye_src,
0258 inst->eye_vrt, inst->eye_term);
0259 break;
0260 case PHY_TYPE_USB3:
0261 device_property_read_u32(dev, "mediatek,efuse-intr",
0262 &inst->efuse_intr);
0263 device_property_read_u32(dev, "mediatek,efuse-tx-imp",
0264 &inst->efuse_tx_imp);
0265 device_property_read_u32(dev, "mediatek,efuse-rx-imp",
0266 &inst->efuse_rx_imp);
0267 dev_dbg(dev, "intr:%d, tx-imp:%d, rx-imp:%d\n",
0268 inst->efuse_intr, inst->efuse_tx_imp,
0269 inst->efuse_rx_imp);
0270 break;
0271 default:
0272 dev_err(xsphy->dev, "incompatible phy type\n");
0273 return;
0274 }
0275 }
0276
0277 static void u2_phy_props_set(struct mtk_xsphy *xsphy,
0278 struct xsphy_instance *inst)
0279 {
0280 void __iomem *pbase = inst->port_base;
0281
0282 if (inst->efuse_intr)
0283 mtk_phy_update_bits(pbase + XSP_USBPHYACR1, P2A1_RG_INTR_CAL,
0284 P2A1_RG_INTR_CAL_VAL(inst->efuse_intr));
0285
0286 if (inst->eye_src)
0287 mtk_phy_update_bits(pbase + XSP_USBPHYACR5, P2A5_RG_HSTX_SRCTRL,
0288 P2A5_RG_HSTX_SRCTRL_VAL(inst->eye_src));
0289
0290 if (inst->eye_vrt)
0291 mtk_phy_update_bits(pbase + XSP_USBPHYACR1, P2A1_RG_VRT_SEL,
0292 P2A1_RG_VRT_SEL_VAL(inst->eye_vrt));
0293
0294 if (inst->eye_term)
0295 mtk_phy_update_bits(pbase + XSP_USBPHYACR1, P2A1_RG_TERM_SEL,
0296 P2A1_RG_TERM_SEL_VAL(inst->eye_term));
0297 }
0298
0299 static void u3_phy_props_set(struct mtk_xsphy *xsphy,
0300 struct xsphy_instance *inst)
0301 {
0302 void __iomem *pbase = inst->port_base;
0303
0304 if (inst->efuse_intr)
0305 mtk_phy_update_bits(xsphy->glb_base + SSPXTP_PHYA_GLB_00,
0306 RG_XTP_GLB_BIAS_INTR_CTRL,
0307 RG_XTP_GLB_BIAS_INTR_CTRL_VAL(inst->efuse_intr));
0308
0309 if (inst->efuse_tx_imp)
0310 mtk_phy_update_bits(pbase + SSPXTP_PHYA_LN_04,
0311 RG_XTP_LN0_TX_IMPSEL,
0312 RG_XTP_LN0_TX_IMPSEL_VAL(inst->efuse_tx_imp));
0313
0314 if (inst->efuse_rx_imp)
0315 mtk_phy_update_bits(pbase + SSPXTP_PHYA_LN_14,
0316 RG_XTP_LN0_RX_IMPSEL,
0317 RG_XTP_LN0_RX_IMPSEL_VAL(inst->efuse_rx_imp));
0318 }
0319
0320 static int mtk_phy_init(struct phy *phy)
0321 {
0322 struct xsphy_instance *inst = phy_get_drvdata(phy);
0323 struct mtk_xsphy *xsphy = dev_get_drvdata(phy->dev.parent);
0324 int ret;
0325
0326 ret = clk_prepare_enable(inst->ref_clk);
0327 if (ret) {
0328 dev_err(xsphy->dev, "failed to enable ref_clk\n");
0329 return ret;
0330 }
0331
0332 switch (inst->type) {
0333 case PHY_TYPE_USB2:
0334 u2_phy_instance_init(xsphy, inst);
0335 u2_phy_props_set(xsphy, inst);
0336 break;
0337 case PHY_TYPE_USB3:
0338 u3_phy_props_set(xsphy, inst);
0339 break;
0340 default:
0341 dev_err(xsphy->dev, "incompatible phy type\n");
0342 clk_disable_unprepare(inst->ref_clk);
0343 return -EINVAL;
0344 }
0345
0346 return 0;
0347 }
0348
0349 static int mtk_phy_power_on(struct phy *phy)
0350 {
0351 struct xsphy_instance *inst = phy_get_drvdata(phy);
0352 struct mtk_xsphy *xsphy = dev_get_drvdata(phy->dev.parent);
0353
0354 if (inst->type == PHY_TYPE_USB2) {
0355 u2_phy_instance_power_on(xsphy, inst);
0356 u2_phy_slew_rate_calibrate(xsphy, inst);
0357 }
0358
0359 return 0;
0360 }
0361
0362 static int mtk_phy_power_off(struct phy *phy)
0363 {
0364 struct xsphy_instance *inst = phy_get_drvdata(phy);
0365 struct mtk_xsphy *xsphy = dev_get_drvdata(phy->dev.parent);
0366
0367 if (inst->type == PHY_TYPE_USB2)
0368 u2_phy_instance_power_off(xsphy, inst);
0369
0370 return 0;
0371 }
0372
0373 static int mtk_phy_exit(struct phy *phy)
0374 {
0375 struct xsphy_instance *inst = phy_get_drvdata(phy);
0376
0377 clk_disable_unprepare(inst->ref_clk);
0378 return 0;
0379 }
0380
0381 static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
0382 {
0383 struct xsphy_instance *inst = phy_get_drvdata(phy);
0384 struct mtk_xsphy *xsphy = dev_get_drvdata(phy->dev.parent);
0385
0386 if (inst->type == PHY_TYPE_USB2)
0387 u2_phy_instance_set_mode(xsphy, inst, mode);
0388
0389 return 0;
0390 }
0391
0392 static struct phy *mtk_phy_xlate(struct device *dev,
0393 struct of_phandle_args *args)
0394 {
0395 struct mtk_xsphy *xsphy = dev_get_drvdata(dev);
0396 struct xsphy_instance *inst = NULL;
0397 struct device_node *phy_np = args->np;
0398 int index;
0399
0400 if (args->args_count != 1) {
0401 dev_err(dev, "invalid number of cells in 'phy' property\n");
0402 return ERR_PTR(-EINVAL);
0403 }
0404
0405 for (index = 0; index < xsphy->nphys; index++)
0406 if (phy_np == xsphy->phys[index]->phy->dev.of_node) {
0407 inst = xsphy->phys[index];
0408 break;
0409 }
0410
0411 if (!inst) {
0412 dev_err(dev, "failed to find appropriate phy\n");
0413 return ERR_PTR(-EINVAL);
0414 }
0415
0416 inst->type = args->args[0];
0417 if (!(inst->type == PHY_TYPE_USB2 ||
0418 inst->type == PHY_TYPE_USB3)) {
0419 dev_err(dev, "unsupported phy type: %d\n", inst->type);
0420 return ERR_PTR(-EINVAL);
0421 }
0422
0423 phy_parse_property(xsphy, inst);
0424
0425 return inst->phy;
0426 }
0427
0428 static const struct phy_ops mtk_xsphy_ops = {
0429 .init = mtk_phy_init,
0430 .exit = mtk_phy_exit,
0431 .power_on = mtk_phy_power_on,
0432 .power_off = mtk_phy_power_off,
0433 .set_mode = mtk_phy_set_mode,
0434 .owner = THIS_MODULE,
0435 };
0436
0437 static const struct of_device_id mtk_xsphy_id_table[] = {
0438 { .compatible = "mediatek,xsphy", },
0439 { },
0440 };
0441 MODULE_DEVICE_TABLE(of, mtk_xsphy_id_table);
0442
0443 static int mtk_xsphy_probe(struct platform_device *pdev)
0444 {
0445 struct device *dev = &pdev->dev;
0446 struct device_node *np = dev->of_node;
0447 struct device_node *child_np;
0448 struct phy_provider *provider;
0449 struct resource *glb_res;
0450 struct mtk_xsphy *xsphy;
0451 struct resource res;
0452 int port, retval;
0453
0454 xsphy = devm_kzalloc(dev, sizeof(*xsphy), GFP_KERNEL);
0455 if (!xsphy)
0456 return -ENOMEM;
0457
0458 xsphy->nphys = of_get_child_count(np);
0459 xsphy->phys = devm_kcalloc(dev, xsphy->nphys,
0460 sizeof(*xsphy->phys), GFP_KERNEL);
0461 if (!xsphy->phys)
0462 return -ENOMEM;
0463
0464 xsphy->dev = dev;
0465 platform_set_drvdata(pdev, xsphy);
0466
0467 glb_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0468
0469 if (glb_res) {
0470
0471 xsphy->glb_base = devm_ioremap_resource(dev, glb_res);
0472 if (IS_ERR(xsphy->glb_base)) {
0473 dev_err(dev, "failed to remap glb regs\n");
0474 return PTR_ERR(xsphy->glb_base);
0475 }
0476 }
0477
0478 xsphy->src_ref_clk = XSP_REF_CLK;
0479 xsphy->src_coef = XSP_SLEW_RATE_COEF;
0480
0481 device_property_read_u32(dev, "mediatek,src-ref-clk-mhz",
0482 &xsphy->src_ref_clk);
0483 device_property_read_u32(dev, "mediatek,src-coef", &xsphy->src_coef);
0484
0485 port = 0;
0486 for_each_child_of_node(np, child_np) {
0487 struct xsphy_instance *inst;
0488 struct phy *phy;
0489
0490 inst = devm_kzalloc(dev, sizeof(*inst), GFP_KERNEL);
0491 if (!inst) {
0492 retval = -ENOMEM;
0493 goto put_child;
0494 }
0495
0496 xsphy->phys[port] = inst;
0497
0498 phy = devm_phy_create(dev, child_np, &mtk_xsphy_ops);
0499 if (IS_ERR(phy)) {
0500 dev_err(dev, "failed to create phy\n");
0501 retval = PTR_ERR(phy);
0502 goto put_child;
0503 }
0504
0505 retval = of_address_to_resource(child_np, 0, &res);
0506 if (retval) {
0507 dev_err(dev, "failed to get address resource(id-%d)\n",
0508 port);
0509 goto put_child;
0510 }
0511
0512 inst->port_base = devm_ioremap_resource(&phy->dev, &res);
0513 if (IS_ERR(inst->port_base)) {
0514 dev_err(dev, "failed to remap phy regs\n");
0515 retval = PTR_ERR(inst->port_base);
0516 goto put_child;
0517 }
0518
0519 inst->phy = phy;
0520 inst->index = port;
0521 phy_set_drvdata(phy, inst);
0522 port++;
0523
0524 inst->ref_clk = devm_clk_get(&phy->dev, "ref");
0525 if (IS_ERR(inst->ref_clk)) {
0526 dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
0527 retval = PTR_ERR(inst->ref_clk);
0528 goto put_child;
0529 }
0530 }
0531
0532 provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
0533 return PTR_ERR_OR_ZERO(provider);
0534
0535 put_child:
0536 of_node_put(child_np);
0537 return retval;
0538 }
0539
0540 static struct platform_driver mtk_xsphy_driver = {
0541 .probe = mtk_xsphy_probe,
0542 .driver = {
0543 .name = "mtk-xsphy",
0544 .of_match_table = mtk_xsphy_id_table,
0545 },
0546 };
0547
0548 module_platform_driver(mtk_xsphy_driver);
0549
0550 MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
0551 MODULE_DESCRIPTION("MediaTek USB XS-PHY driver");
0552 MODULE_LICENSE("GPL v2");