0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/clk.h>
0010 #include <linux/clk-provider.h>
0011 #include <linux/io.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/mutex.h>
0015 #include <linux/of.h>
0016 #include <linux/of_address.h>
0017 #include <linux/of_platform.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/regmap.h>
0023 #include <linux/mfd/syscon.h>
0024 #include <linux/delay.h>
0025
0026 static int enable_usb_uart;
0027
0028 #define HIWORD_UPDATE(val, mask) \
0029 ((val) | (mask) << 16)
0030
0031 #define UOC_CON0 0x00
0032 #define UOC_CON0_SIDDQ BIT(13)
0033 #define UOC_CON0_DISABLE BIT(4)
0034 #define UOC_CON0_COMMON_ON_N BIT(0)
0035
0036 #define UOC_CON2 0x08
0037 #define UOC_CON2_SOFT_CON_SEL BIT(2)
0038
0039 #define UOC_CON3 0x0c
0040
0041 #define UOC_CON3_UTMI_TERMSEL_FULLSPEED BIT(5)
0042 #define UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC (1 << 3)
0043 #define UOC_CON3_UTMI_XCVRSEELCT_MASK (3 << 3)
0044 #define UOC_CON3_UTMI_OPMODE_NODRIVING (1 << 1)
0045 #define UOC_CON3_UTMI_OPMODE_MASK (3 << 1)
0046 #define UOC_CON3_UTMI_SUSPENDN BIT(0)
0047
0048 struct rockchip_usb_phys {
0049 int reg;
0050 const char *pll_name;
0051 };
0052
0053 struct rockchip_usb_phy_base;
0054 struct rockchip_usb_phy_pdata {
0055 struct rockchip_usb_phys *phys;
0056 int (*init_usb_uart)(struct regmap *grf,
0057 const struct rockchip_usb_phy_pdata *pdata);
0058 int usb_uart_phy;
0059 };
0060
0061 struct rockchip_usb_phy_base {
0062 struct device *dev;
0063 struct regmap *reg_base;
0064 const struct rockchip_usb_phy_pdata *pdata;
0065 };
0066
0067 struct rockchip_usb_phy {
0068 struct rockchip_usb_phy_base *base;
0069 struct device_node *np;
0070 unsigned int reg_offset;
0071 struct clk *clk;
0072 struct clk *clk480m;
0073 struct clk_hw clk480m_hw;
0074 struct phy *phy;
0075 bool uart_enabled;
0076 struct reset_control *reset;
0077 struct regulator *vbus;
0078 };
0079
0080 static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
0081 bool siddq)
0082 {
0083 u32 val = HIWORD_UPDATE(siddq ? UOC_CON0_SIDDQ : 0, UOC_CON0_SIDDQ);
0084
0085 return regmap_write(phy->base->reg_base, phy->reg_offset, val);
0086 }
0087
0088 static unsigned long rockchip_usb_phy480m_recalc_rate(struct clk_hw *hw,
0089 unsigned long parent_rate)
0090 {
0091 return 480000000;
0092 }
0093
0094 static void rockchip_usb_phy480m_disable(struct clk_hw *hw)
0095 {
0096 struct rockchip_usb_phy *phy = container_of(hw,
0097 struct rockchip_usb_phy,
0098 clk480m_hw);
0099
0100 if (phy->vbus)
0101 regulator_disable(phy->vbus);
0102
0103
0104 rockchip_usb_phy_power(phy, 1);
0105 }
0106
0107 static int rockchip_usb_phy480m_enable(struct clk_hw *hw)
0108 {
0109 struct rockchip_usb_phy *phy = container_of(hw,
0110 struct rockchip_usb_phy,
0111 clk480m_hw);
0112
0113
0114 return rockchip_usb_phy_power(phy, 0);
0115 }
0116
0117 static int rockchip_usb_phy480m_is_enabled(struct clk_hw *hw)
0118 {
0119 struct rockchip_usb_phy *phy = container_of(hw,
0120 struct rockchip_usb_phy,
0121 clk480m_hw);
0122 int ret;
0123 u32 val;
0124
0125 ret = regmap_read(phy->base->reg_base, phy->reg_offset, &val);
0126 if (ret < 0)
0127 return ret;
0128
0129 return (val & UOC_CON0_SIDDQ) ? 0 : 1;
0130 }
0131
0132 static const struct clk_ops rockchip_usb_phy480m_ops = {
0133 .enable = rockchip_usb_phy480m_enable,
0134 .disable = rockchip_usb_phy480m_disable,
0135 .is_enabled = rockchip_usb_phy480m_is_enabled,
0136 .recalc_rate = rockchip_usb_phy480m_recalc_rate,
0137 };
0138
0139 static int rockchip_usb_phy_power_off(struct phy *_phy)
0140 {
0141 struct rockchip_usb_phy *phy = phy_get_drvdata(_phy);
0142
0143 if (phy->uart_enabled)
0144 return -EBUSY;
0145
0146 clk_disable_unprepare(phy->clk480m);
0147
0148 return 0;
0149 }
0150
0151 static int rockchip_usb_phy_power_on(struct phy *_phy)
0152 {
0153 struct rockchip_usb_phy *phy = phy_get_drvdata(_phy);
0154
0155 if (phy->uart_enabled)
0156 return -EBUSY;
0157
0158 if (phy->vbus) {
0159 int ret;
0160
0161 ret = regulator_enable(phy->vbus);
0162 if (ret)
0163 return ret;
0164 }
0165
0166 return clk_prepare_enable(phy->clk480m);
0167 }
0168
0169 static int rockchip_usb_phy_reset(struct phy *_phy)
0170 {
0171 struct rockchip_usb_phy *phy = phy_get_drvdata(_phy);
0172
0173 if (phy->reset) {
0174 reset_control_assert(phy->reset);
0175 udelay(10);
0176 reset_control_deassert(phy->reset);
0177 }
0178
0179 return 0;
0180 }
0181
0182 static const struct phy_ops ops = {
0183 .power_on = rockchip_usb_phy_power_on,
0184 .power_off = rockchip_usb_phy_power_off,
0185 .reset = rockchip_usb_phy_reset,
0186 .owner = THIS_MODULE,
0187 };
0188
0189 static void rockchip_usb_phy_action(void *data)
0190 {
0191 struct rockchip_usb_phy *rk_phy = data;
0192
0193 if (!rk_phy->uart_enabled) {
0194 of_clk_del_provider(rk_phy->np);
0195 clk_unregister(rk_phy->clk480m);
0196 }
0197
0198 if (rk_phy->clk)
0199 clk_put(rk_phy->clk);
0200 }
0201
0202 static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
0203 struct device_node *child)
0204 {
0205 struct rockchip_usb_phy *rk_phy;
0206 unsigned int reg_offset;
0207 const char *clk_name;
0208 struct clk_init_data init;
0209 int err, i;
0210
0211 rk_phy = devm_kzalloc(base->dev, sizeof(*rk_phy), GFP_KERNEL);
0212 if (!rk_phy)
0213 return -ENOMEM;
0214
0215 rk_phy->base = base;
0216 rk_phy->np = child;
0217
0218 if (of_property_read_u32(child, "reg", ®_offset)) {
0219 dev_err(base->dev, "missing reg property in node %pOFn\n",
0220 child);
0221 return -EINVAL;
0222 }
0223
0224 rk_phy->reset = of_reset_control_get(child, "phy-reset");
0225 if (IS_ERR(rk_phy->reset))
0226 rk_phy->reset = NULL;
0227
0228 rk_phy->reg_offset = reg_offset;
0229
0230 rk_phy->clk = of_clk_get_by_name(child, "phyclk");
0231 if (IS_ERR(rk_phy->clk))
0232 rk_phy->clk = NULL;
0233
0234 i = 0;
0235 init.name = NULL;
0236 while (base->pdata->phys[i].reg) {
0237 if (base->pdata->phys[i].reg == reg_offset) {
0238 init.name = base->pdata->phys[i].pll_name;
0239 break;
0240 }
0241 i++;
0242 }
0243
0244 if (!init.name) {
0245 dev_err(base->dev, "phy data not found\n");
0246 return -EINVAL;
0247 }
0248
0249 if (enable_usb_uart && base->pdata->usb_uart_phy == i) {
0250 dev_dbg(base->dev, "phy%d used as uart output\n", i);
0251 rk_phy->uart_enabled = true;
0252 } else {
0253 if (rk_phy->clk) {
0254 clk_name = __clk_get_name(rk_phy->clk);
0255 init.flags = 0;
0256 init.parent_names = &clk_name;
0257 init.num_parents = 1;
0258 } else {
0259 init.flags = 0;
0260 init.parent_names = NULL;
0261 init.num_parents = 0;
0262 }
0263
0264 init.ops = &rockchip_usb_phy480m_ops;
0265 rk_phy->clk480m_hw.init = &init;
0266
0267 rk_phy->clk480m = clk_register(base->dev, &rk_phy->clk480m_hw);
0268 if (IS_ERR(rk_phy->clk480m)) {
0269 err = PTR_ERR(rk_phy->clk480m);
0270 goto err_clk;
0271 }
0272
0273 err = of_clk_add_provider(child, of_clk_src_simple_get,
0274 rk_phy->clk480m);
0275 if (err < 0)
0276 goto err_clk_prov;
0277 }
0278
0279 err = devm_add_action_or_reset(base->dev, rockchip_usb_phy_action,
0280 rk_phy);
0281 if (err)
0282 return err;
0283
0284 rk_phy->phy = devm_phy_create(base->dev, child, &ops);
0285 if (IS_ERR(rk_phy->phy)) {
0286 dev_err(base->dev, "failed to create PHY\n");
0287 return PTR_ERR(rk_phy->phy);
0288 }
0289 phy_set_drvdata(rk_phy->phy, rk_phy);
0290
0291 rk_phy->vbus = devm_regulator_get_optional(&rk_phy->phy->dev, "vbus");
0292 if (IS_ERR(rk_phy->vbus)) {
0293 if (PTR_ERR(rk_phy->vbus) == -EPROBE_DEFER)
0294 return PTR_ERR(rk_phy->vbus);
0295 rk_phy->vbus = NULL;
0296 }
0297
0298
0299
0300
0301
0302 if (rk_phy->uart_enabled)
0303 return clk_prepare_enable(rk_phy->clk);
0304 else
0305 return rockchip_usb_phy_power(rk_phy, 1);
0306
0307 err_clk_prov:
0308 if (!rk_phy->uart_enabled)
0309 clk_unregister(rk_phy->clk480m);
0310 err_clk:
0311 if (rk_phy->clk)
0312 clk_put(rk_phy->clk);
0313 return err;
0314 }
0315
0316 static const struct rockchip_usb_phy_pdata rk3066a_pdata = {
0317 .phys = (struct rockchip_usb_phys[]){
0318 { .reg = 0x17c, .pll_name = "sclk_otgphy0_480m" },
0319 { .reg = 0x188, .pll_name = "sclk_otgphy1_480m" },
0320 { }
0321 },
0322 };
0323
0324 static int __init rockchip_init_usb_uart_common(struct regmap *grf,
0325 const struct rockchip_usb_phy_pdata *pdata)
0326 {
0327 int regoffs = pdata->phys[pdata->usb_uart_phy].reg;
0328 int ret;
0329 u32 val;
0330
0331
0332
0333
0334
0335
0336 val = HIWORD_UPDATE(UOC_CON0_COMMON_ON_N
0337 | UOC_CON0_DISABLE
0338 | UOC_CON0_SIDDQ,
0339 UOC_CON0_COMMON_ON_N
0340 | UOC_CON0_DISABLE
0341 | UOC_CON0_SIDDQ);
0342 ret = regmap_write(grf, regoffs + UOC_CON0, val);
0343 if (ret)
0344 return ret;
0345
0346 val = HIWORD_UPDATE(UOC_CON2_SOFT_CON_SEL,
0347 UOC_CON2_SOFT_CON_SEL);
0348 ret = regmap_write(grf, regoffs + UOC_CON2, val);
0349 if (ret)
0350 return ret;
0351
0352 val = HIWORD_UPDATE(UOC_CON3_UTMI_OPMODE_NODRIVING
0353 | UOC_CON3_UTMI_XCVRSEELCT_FSTRANSC
0354 | UOC_CON3_UTMI_TERMSEL_FULLSPEED,
0355 UOC_CON3_UTMI_SUSPENDN
0356 | UOC_CON3_UTMI_OPMODE_MASK
0357 | UOC_CON3_UTMI_XCVRSEELCT_MASK
0358 | UOC_CON3_UTMI_TERMSEL_FULLSPEED);
0359 ret = regmap_write(grf, UOC_CON3, val);
0360 if (ret)
0361 return ret;
0362
0363 return 0;
0364 }
0365
0366 #define RK3188_UOC0_CON0 0x10c
0367 #define RK3188_UOC0_CON0_BYPASSSEL BIT(9)
0368 #define RK3188_UOC0_CON0_BYPASSDMEN BIT(8)
0369
0370
0371
0372
0373
0374 static int __init rk3188_init_usb_uart(struct regmap *grf,
0375 const struct rockchip_usb_phy_pdata *pdata)
0376 {
0377 u32 val;
0378 int ret;
0379
0380 ret = rockchip_init_usb_uart_common(grf, pdata);
0381 if (ret)
0382 return ret;
0383
0384 val = HIWORD_UPDATE(RK3188_UOC0_CON0_BYPASSSEL
0385 | RK3188_UOC0_CON0_BYPASSDMEN,
0386 RK3188_UOC0_CON0_BYPASSSEL
0387 | RK3188_UOC0_CON0_BYPASSDMEN);
0388 ret = regmap_write(grf, RK3188_UOC0_CON0, val);
0389 if (ret)
0390 return ret;
0391
0392 return 0;
0393 }
0394
0395 static const struct rockchip_usb_phy_pdata rk3188_pdata = {
0396 .phys = (struct rockchip_usb_phys[]){
0397 { .reg = 0x10c, .pll_name = "sclk_otgphy0_480m" },
0398 { .reg = 0x11c, .pll_name = "sclk_otgphy1_480m" },
0399 { }
0400 },
0401 .init_usb_uart = rk3188_init_usb_uart,
0402 .usb_uart_phy = 0,
0403 };
0404
0405 #define RK3288_UOC0_CON3 0x32c
0406 #define RK3288_UOC0_CON3_BYPASSDMEN BIT(6)
0407 #define RK3288_UOC0_CON3_BYPASSSEL BIT(7)
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424 static int __init rk3288_init_usb_uart(struct regmap *grf,
0425 const struct rockchip_usb_phy_pdata *pdata)
0426 {
0427 u32 val;
0428 int ret;
0429
0430 ret = rockchip_init_usb_uart_common(grf, pdata);
0431 if (ret)
0432 return ret;
0433
0434 val = HIWORD_UPDATE(RK3288_UOC0_CON3_BYPASSSEL
0435 | RK3288_UOC0_CON3_BYPASSDMEN,
0436 RK3288_UOC0_CON3_BYPASSSEL
0437 | RK3288_UOC0_CON3_BYPASSDMEN);
0438 ret = regmap_write(grf, RK3288_UOC0_CON3, val);
0439 if (ret)
0440 return ret;
0441
0442 return 0;
0443 }
0444
0445 static const struct rockchip_usb_phy_pdata rk3288_pdata = {
0446 .phys = (struct rockchip_usb_phys[]){
0447 { .reg = 0x320, .pll_name = "sclk_otgphy0_480m" },
0448 { .reg = 0x334, .pll_name = "sclk_otgphy1_480m" },
0449 { .reg = 0x348, .pll_name = "sclk_otgphy2_480m" },
0450 { }
0451 },
0452 .init_usb_uart = rk3288_init_usb_uart,
0453 .usb_uart_phy = 0,
0454 };
0455
0456 static int rockchip_usb_phy_probe(struct platform_device *pdev)
0457 {
0458 struct device *dev = &pdev->dev;
0459 struct rockchip_usb_phy_base *phy_base;
0460 struct phy_provider *phy_provider;
0461 const struct of_device_id *match;
0462 struct device_node *child;
0463 int err;
0464
0465 phy_base = devm_kzalloc(dev, sizeof(*phy_base), GFP_KERNEL);
0466 if (!phy_base)
0467 return -ENOMEM;
0468
0469 match = of_match_device(dev->driver->of_match_table, dev);
0470 if (!match || !match->data) {
0471 dev_err(dev, "missing phy data\n");
0472 return -EINVAL;
0473 }
0474
0475 phy_base->pdata = match->data;
0476
0477 phy_base->dev = dev;
0478 phy_base->reg_base = ERR_PTR(-ENODEV);
0479 if (dev->parent && dev->parent->of_node)
0480 phy_base->reg_base = syscon_node_to_regmap(
0481 dev->parent->of_node);
0482 if (IS_ERR(phy_base->reg_base))
0483 phy_base->reg_base = syscon_regmap_lookup_by_phandle(
0484 dev->of_node, "rockchip,grf");
0485 if (IS_ERR(phy_base->reg_base)) {
0486 dev_err(&pdev->dev, "Missing rockchip,grf property\n");
0487 return PTR_ERR(phy_base->reg_base);
0488 }
0489
0490 for_each_available_child_of_node(dev->of_node, child) {
0491 err = rockchip_usb_phy_init(phy_base, child);
0492 if (err) {
0493 of_node_put(child);
0494 return err;
0495 }
0496 }
0497
0498 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0499 return PTR_ERR_OR_ZERO(phy_provider);
0500 }
0501
0502 static const struct of_device_id rockchip_usb_phy_dt_ids[] = {
0503 { .compatible = "rockchip,rk3066a-usb-phy", .data = &rk3066a_pdata },
0504 { .compatible = "rockchip,rk3188-usb-phy", .data = &rk3188_pdata },
0505 { .compatible = "rockchip,rk3288-usb-phy", .data = &rk3288_pdata },
0506 {}
0507 };
0508
0509 MODULE_DEVICE_TABLE(of, rockchip_usb_phy_dt_ids);
0510
0511 static struct platform_driver rockchip_usb_driver = {
0512 .probe = rockchip_usb_phy_probe,
0513 .driver = {
0514 .name = "rockchip-usb-phy",
0515 .of_match_table = rockchip_usb_phy_dt_ids,
0516 },
0517 };
0518
0519 module_platform_driver(rockchip_usb_driver);
0520
0521 #ifndef MODULE
0522 static int __init rockchip_init_usb_uart(void)
0523 {
0524 const struct of_device_id *match;
0525 const struct rockchip_usb_phy_pdata *data;
0526 struct device_node *np;
0527 struct regmap *grf;
0528 int ret;
0529
0530 if (!enable_usb_uart)
0531 return 0;
0532
0533 np = of_find_matching_node_and_match(NULL, rockchip_usb_phy_dt_ids,
0534 &match);
0535 if (!np) {
0536 pr_err("%s: failed to find usbphy node\n", __func__);
0537 return -ENOTSUPP;
0538 }
0539
0540 pr_debug("%s: using settings for %s\n", __func__, match->compatible);
0541 data = match->data;
0542
0543 if (!data->init_usb_uart) {
0544 pr_err("%s: usb-uart not available on %s\n",
0545 __func__, match->compatible);
0546 return -ENOTSUPP;
0547 }
0548
0549 grf = ERR_PTR(-ENODEV);
0550 if (np->parent)
0551 grf = syscon_node_to_regmap(np->parent);
0552 if (IS_ERR(grf))
0553 grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
0554 if (IS_ERR(grf)) {
0555 pr_err("%s: Missing rockchip,grf property, %lu\n",
0556 __func__, PTR_ERR(grf));
0557 return PTR_ERR(grf);
0558 }
0559
0560 ret = data->init_usb_uart(grf, data);
0561 if (ret) {
0562 pr_err("%s: could not init usb_uart, %d\n", __func__, ret);
0563 enable_usb_uart = 0;
0564 return ret;
0565 }
0566
0567 return 0;
0568 }
0569 early_initcall(rockchip_init_usb_uart);
0570
0571 static int __init rockchip_usb_uart(char *buf)
0572 {
0573 enable_usb_uart = true;
0574 return 0;
0575 }
0576 early_param("rockchip.usb_uart", rockchip_usb_uart);
0577 #endif
0578
0579 MODULE_AUTHOR("Yunzhi Li <lyz@rock-chips.com>");
0580 MODULE_DESCRIPTION("Rockchip USB 2.0 PHY driver");
0581 MODULE_LICENSE("GPL v2");