0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/clk.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/delay.h>
0011 #include <linux/extcon-provider.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/gpio/consumer.h>
0015 #include <linux/jiffies.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/mutex.h>
0019 #include <linux/of.h>
0020 #include <linux/of_address.h>
0021 #include <linux/of_irq.h>
0022 #include <linux/of_platform.h>
0023 #include <linux/phy/phy.h>
0024 #include <linux/platform_device.h>
0025 #include <linux/power_supply.h>
0026 #include <linux/regmap.h>
0027 #include <linux/mfd/syscon.h>
0028 #include <linux/usb/of.h>
0029 #include <linux/usb/otg.h>
0030
0031 #define BIT_WRITEABLE_SHIFT 16
0032 #define SCHEDULE_DELAY (60 * HZ)
0033 #define OTG_SCHEDULE_DELAY (2 * HZ)
0034
0035 enum rockchip_usb2phy_port_id {
0036 USB2PHY_PORT_OTG,
0037 USB2PHY_PORT_HOST,
0038 USB2PHY_NUM_PORTS,
0039 };
0040
0041 enum rockchip_usb2phy_host_state {
0042 PHY_STATE_HS_ONLINE = 0,
0043 PHY_STATE_DISCONNECT = 1,
0044 PHY_STATE_CONNECT = 2,
0045 PHY_STATE_FS_LS_ONLINE = 4,
0046 };
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 enum usb_chg_state {
0061 USB_CHG_STATE_UNDEFINED = 0,
0062 USB_CHG_STATE_WAIT_FOR_DCD,
0063 USB_CHG_STATE_DCD_DONE,
0064 USB_CHG_STATE_PRIMARY_DONE,
0065 USB_CHG_STATE_SECONDARY_DONE,
0066 USB_CHG_STATE_DETECTED,
0067 };
0068
0069 static const unsigned int rockchip_usb2phy_extcon_cable[] = {
0070 EXTCON_USB,
0071 EXTCON_USB_HOST,
0072 EXTCON_CHG_USB_SDP,
0073 EXTCON_CHG_USB_CDP,
0074 EXTCON_CHG_USB_DCP,
0075 EXTCON_CHG_USB_SLOW,
0076 EXTCON_NONE,
0077 };
0078
0079 struct usb2phy_reg {
0080 unsigned int offset;
0081 unsigned int bitend;
0082 unsigned int bitstart;
0083 unsigned int disable;
0084 unsigned int enable;
0085 };
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 struct rockchip_chg_det_reg {
0101 struct usb2phy_reg cp_det;
0102 struct usb2phy_reg dcp_det;
0103 struct usb2phy_reg dp_det;
0104 struct usb2phy_reg idm_sink_en;
0105 struct usb2phy_reg idp_sink_en;
0106 struct usb2phy_reg idp_src_en;
0107 struct usb2phy_reg rdm_pdwn_en;
0108 struct usb2phy_reg vdm_src_en;
0109 struct usb2phy_reg vdp_src_en;
0110 struct usb2phy_reg opmode;
0111 };
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 struct rockchip_usb2phy_port_cfg {
0132 struct usb2phy_reg phy_sus;
0133 struct usb2phy_reg bvalid_det_en;
0134 struct usb2phy_reg bvalid_det_st;
0135 struct usb2phy_reg bvalid_det_clr;
0136 struct usb2phy_reg id_det_en;
0137 struct usb2phy_reg id_det_st;
0138 struct usb2phy_reg id_det_clr;
0139 struct usb2phy_reg ls_det_en;
0140 struct usb2phy_reg ls_det_st;
0141 struct usb2phy_reg ls_det_clr;
0142 struct usb2phy_reg utmi_avalid;
0143 struct usb2phy_reg utmi_bvalid;
0144 struct usb2phy_reg utmi_id;
0145 struct usb2phy_reg utmi_ls;
0146 struct usb2phy_reg utmi_hstdet;
0147 };
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 struct rockchip_usb2phy_cfg {
0158 unsigned int reg;
0159 unsigned int num_ports;
0160 struct usb2phy_reg clkout_ctl;
0161 const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS];
0162 const struct rockchip_chg_det_reg chg_det;
0163 };
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 struct rockchip_usb2phy_port {
0186 struct phy *phy;
0187 unsigned int port_id;
0188 bool suspended;
0189 bool vbus_attached;
0190 int bvalid_irq;
0191 int id_irq;
0192 int ls_irq;
0193 int otg_mux_irq;
0194 struct mutex mutex;
0195 struct delayed_work chg_work;
0196 struct delayed_work otg_sm_work;
0197 struct delayed_work sm_work;
0198 const struct rockchip_usb2phy_port_cfg *port_cfg;
0199 struct notifier_block event_nb;
0200 enum usb_otg_state state;
0201 enum usb_dr_mode mode;
0202 };
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221 struct rockchip_usb2phy {
0222 struct device *dev;
0223 struct regmap *grf;
0224 struct regmap *usbgrf;
0225 struct clk *clk;
0226 struct clk *clk480m;
0227 struct clk_hw clk480m_hw;
0228 enum usb_chg_state chg_state;
0229 enum power_supply_type chg_type;
0230 u8 dcd_retries;
0231 struct extcon_dev *edev;
0232 int irq;
0233 const struct rockchip_usb2phy_cfg *phy_cfg;
0234 struct rockchip_usb2phy_port ports[USB2PHY_NUM_PORTS];
0235 };
0236
0237 static inline struct regmap *get_reg_base(struct rockchip_usb2phy *rphy)
0238 {
0239 return rphy->usbgrf == NULL ? rphy->grf : rphy->usbgrf;
0240 }
0241
0242 static inline int property_enable(struct regmap *base,
0243 const struct usb2phy_reg *reg, bool en)
0244 {
0245 unsigned int val, mask, tmp;
0246
0247 tmp = en ? reg->enable : reg->disable;
0248 mask = GENMASK(reg->bitend, reg->bitstart);
0249 val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
0250
0251 return regmap_write(base, reg->offset, val);
0252 }
0253
0254 static inline bool property_enabled(struct regmap *base,
0255 const struct usb2phy_reg *reg)
0256 {
0257 int ret;
0258 unsigned int tmp, orig;
0259 unsigned int mask = GENMASK(reg->bitend, reg->bitstart);
0260
0261 ret = regmap_read(base, reg->offset, &orig);
0262 if (ret)
0263 return false;
0264
0265 tmp = (orig & mask) >> reg->bitstart;
0266 return tmp != reg->disable;
0267 }
0268
0269 static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
0270 {
0271 struct rockchip_usb2phy *rphy =
0272 container_of(hw, struct rockchip_usb2phy, clk480m_hw);
0273 struct regmap *base = get_reg_base(rphy);
0274 int ret;
0275
0276
0277 if (!property_enabled(base, &rphy->phy_cfg->clkout_ctl)) {
0278 ret = property_enable(base, &rphy->phy_cfg->clkout_ctl, true);
0279 if (ret)
0280 return ret;
0281
0282
0283 usleep_range(1200, 1300);
0284 }
0285
0286 return 0;
0287 }
0288
0289 static void rockchip_usb2phy_clk480m_unprepare(struct clk_hw *hw)
0290 {
0291 struct rockchip_usb2phy *rphy =
0292 container_of(hw, struct rockchip_usb2phy, clk480m_hw);
0293 struct regmap *base = get_reg_base(rphy);
0294
0295
0296 property_enable(base, &rphy->phy_cfg->clkout_ctl, false);
0297 }
0298
0299 static int rockchip_usb2phy_clk480m_prepared(struct clk_hw *hw)
0300 {
0301 struct rockchip_usb2phy *rphy =
0302 container_of(hw, struct rockchip_usb2phy, clk480m_hw);
0303 struct regmap *base = get_reg_base(rphy);
0304
0305 return property_enabled(base, &rphy->phy_cfg->clkout_ctl);
0306 }
0307
0308 static unsigned long
0309 rockchip_usb2phy_clk480m_recalc_rate(struct clk_hw *hw,
0310 unsigned long parent_rate)
0311 {
0312 return 480000000;
0313 }
0314
0315 static const struct clk_ops rockchip_usb2phy_clkout_ops = {
0316 .prepare = rockchip_usb2phy_clk480m_prepare,
0317 .unprepare = rockchip_usb2phy_clk480m_unprepare,
0318 .is_prepared = rockchip_usb2phy_clk480m_prepared,
0319 .recalc_rate = rockchip_usb2phy_clk480m_recalc_rate,
0320 };
0321
0322 static void rockchip_usb2phy_clk480m_unregister(void *data)
0323 {
0324 struct rockchip_usb2phy *rphy = data;
0325
0326 of_clk_del_provider(rphy->dev->of_node);
0327 clk_unregister(rphy->clk480m);
0328 }
0329
0330 static int
0331 rockchip_usb2phy_clk480m_register(struct rockchip_usb2phy *rphy)
0332 {
0333 struct device_node *node = rphy->dev->of_node;
0334 struct clk_init_data init;
0335 const char *clk_name;
0336 int ret = 0;
0337
0338 init.flags = 0;
0339 init.name = "clk_usbphy_480m";
0340 init.ops = &rockchip_usb2phy_clkout_ops;
0341
0342
0343 of_property_read_string(node, "clock-output-names", &init.name);
0344
0345 if (rphy->clk) {
0346 clk_name = __clk_get_name(rphy->clk);
0347 init.parent_names = &clk_name;
0348 init.num_parents = 1;
0349 } else {
0350 init.parent_names = NULL;
0351 init.num_parents = 0;
0352 }
0353
0354 rphy->clk480m_hw.init = &init;
0355
0356
0357 rphy->clk480m = clk_register(rphy->dev, &rphy->clk480m_hw);
0358 if (IS_ERR(rphy->clk480m)) {
0359 ret = PTR_ERR(rphy->clk480m);
0360 goto err_ret;
0361 }
0362
0363 ret = of_clk_add_provider(node, of_clk_src_simple_get, rphy->clk480m);
0364 if (ret < 0)
0365 goto err_clk_provider;
0366
0367 return devm_add_action_or_reset(rphy->dev, rockchip_usb2phy_clk480m_unregister, rphy);
0368
0369 err_clk_provider:
0370 clk_unregister(rphy->clk480m);
0371 err_ret:
0372 return ret;
0373 }
0374
0375 static int rockchip_usb2phy_extcon_register(struct rockchip_usb2phy *rphy)
0376 {
0377 int ret;
0378 struct device_node *node = rphy->dev->of_node;
0379 struct extcon_dev *edev;
0380
0381 if (of_property_read_bool(node, "extcon")) {
0382 edev = extcon_get_edev_by_phandle(rphy->dev, 0);
0383 if (IS_ERR(edev)) {
0384 if (PTR_ERR(edev) != -EPROBE_DEFER)
0385 dev_err(rphy->dev, "Invalid or missing extcon\n");
0386 return PTR_ERR(edev);
0387 }
0388 } else {
0389
0390 edev = devm_extcon_dev_allocate(rphy->dev,
0391 rockchip_usb2phy_extcon_cable);
0392
0393 if (IS_ERR(edev))
0394 return -ENOMEM;
0395
0396 ret = devm_extcon_dev_register(rphy->dev, edev);
0397 if (ret) {
0398 dev_err(rphy->dev, "failed to register extcon device\n");
0399 return ret;
0400 }
0401 }
0402
0403 rphy->edev = edev;
0404
0405 return 0;
0406 }
0407
0408 static int rockchip_usb2phy_init(struct phy *phy)
0409 {
0410 struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
0411 struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
0412 int ret = 0;
0413
0414 mutex_lock(&rport->mutex);
0415
0416 if (rport->port_id == USB2PHY_PORT_OTG) {
0417 if (rport->mode != USB_DR_MODE_HOST &&
0418 rport->mode != USB_DR_MODE_UNKNOWN) {
0419
0420 ret = property_enable(rphy->grf,
0421 &rport->port_cfg->bvalid_det_clr,
0422 true);
0423 if (ret)
0424 goto out;
0425
0426 ret = property_enable(rphy->grf,
0427 &rport->port_cfg->bvalid_det_en,
0428 true);
0429 if (ret)
0430 goto out;
0431
0432
0433 ret = property_enable(rphy->grf,
0434 &rport->port_cfg->id_det_clr,
0435 true);
0436 if (ret)
0437 goto out;
0438
0439 ret = property_enable(rphy->grf,
0440 &rport->port_cfg->id_det_en,
0441 true);
0442 if (ret)
0443 goto out;
0444
0445 schedule_delayed_work(&rport->otg_sm_work,
0446 OTG_SCHEDULE_DELAY * 3);
0447 } else {
0448
0449 dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
0450 }
0451 } else if (rport->port_id == USB2PHY_PORT_HOST) {
0452
0453 ret = property_enable(rphy->grf,
0454 &rport->port_cfg->ls_det_clr, true);
0455 if (ret)
0456 goto out;
0457
0458 ret = property_enable(rphy->grf,
0459 &rport->port_cfg->ls_det_en, true);
0460 if (ret)
0461 goto out;
0462
0463 schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
0464 }
0465
0466 out:
0467 mutex_unlock(&rport->mutex);
0468 return ret;
0469 }
0470
0471 static int rockchip_usb2phy_power_on(struct phy *phy)
0472 {
0473 struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
0474 struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
0475 struct regmap *base = get_reg_base(rphy);
0476 int ret;
0477
0478 dev_dbg(&rport->phy->dev, "port power on\n");
0479
0480 if (!rport->suspended)
0481 return 0;
0482
0483 ret = clk_prepare_enable(rphy->clk480m);
0484 if (ret)
0485 return ret;
0486
0487 ret = property_enable(base, &rport->port_cfg->phy_sus, false);
0488 if (ret)
0489 return ret;
0490
0491
0492 usleep_range(1500, 2000);
0493
0494 rport->suspended = false;
0495 return 0;
0496 }
0497
0498 static int rockchip_usb2phy_power_off(struct phy *phy)
0499 {
0500 struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
0501 struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent);
0502 struct regmap *base = get_reg_base(rphy);
0503 int ret;
0504
0505 dev_dbg(&rport->phy->dev, "port power off\n");
0506
0507 if (rport->suspended)
0508 return 0;
0509
0510 ret = property_enable(base, &rport->port_cfg->phy_sus, true);
0511 if (ret)
0512 return ret;
0513
0514 rport->suspended = true;
0515 clk_disable_unprepare(rphy->clk480m);
0516
0517 return 0;
0518 }
0519
0520 static int rockchip_usb2phy_exit(struct phy *phy)
0521 {
0522 struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
0523
0524 if (rport->port_id == USB2PHY_PORT_OTG &&
0525 rport->mode != USB_DR_MODE_HOST &&
0526 rport->mode != USB_DR_MODE_UNKNOWN) {
0527 cancel_delayed_work_sync(&rport->otg_sm_work);
0528 cancel_delayed_work_sync(&rport->chg_work);
0529 } else if (rport->port_id == USB2PHY_PORT_HOST)
0530 cancel_delayed_work_sync(&rport->sm_work);
0531
0532 return 0;
0533 }
0534
0535 static const struct phy_ops rockchip_usb2phy_ops = {
0536 .init = rockchip_usb2phy_init,
0537 .exit = rockchip_usb2phy_exit,
0538 .power_on = rockchip_usb2phy_power_on,
0539 .power_off = rockchip_usb2phy_power_off,
0540 .owner = THIS_MODULE,
0541 };
0542
0543 static void rockchip_usb2phy_otg_sm_work(struct work_struct *work)
0544 {
0545 struct rockchip_usb2phy_port *rport =
0546 container_of(work, struct rockchip_usb2phy_port,
0547 otg_sm_work.work);
0548 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0549 static unsigned int cable;
0550 unsigned long delay;
0551 bool vbus_attach, sch_work, notify_charger;
0552
0553 vbus_attach = property_enabled(rphy->grf,
0554 &rport->port_cfg->utmi_bvalid);
0555
0556 sch_work = false;
0557 notify_charger = false;
0558 delay = OTG_SCHEDULE_DELAY;
0559 dev_dbg(&rport->phy->dev, "%s otg sm work\n",
0560 usb_otg_state_string(rport->state));
0561
0562 switch (rport->state) {
0563 case OTG_STATE_UNDEFINED:
0564 rport->state = OTG_STATE_B_IDLE;
0565 if (!vbus_attach)
0566 rockchip_usb2phy_power_off(rport->phy);
0567 fallthrough;
0568 case OTG_STATE_B_IDLE:
0569 if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0) {
0570 dev_dbg(&rport->phy->dev, "usb otg host connect\n");
0571 rport->state = OTG_STATE_A_HOST;
0572 rockchip_usb2phy_power_on(rport->phy);
0573 return;
0574 } else if (vbus_attach) {
0575 dev_dbg(&rport->phy->dev, "vbus_attach\n");
0576 switch (rphy->chg_state) {
0577 case USB_CHG_STATE_UNDEFINED:
0578 schedule_delayed_work(&rport->chg_work, 0);
0579 return;
0580 case USB_CHG_STATE_DETECTED:
0581 switch (rphy->chg_type) {
0582 case POWER_SUPPLY_TYPE_USB:
0583 dev_dbg(&rport->phy->dev, "sdp cable is connected\n");
0584 rockchip_usb2phy_power_on(rport->phy);
0585 rport->state = OTG_STATE_B_PERIPHERAL;
0586 notify_charger = true;
0587 sch_work = true;
0588 cable = EXTCON_CHG_USB_SDP;
0589 break;
0590 case POWER_SUPPLY_TYPE_USB_DCP:
0591 dev_dbg(&rport->phy->dev, "dcp cable is connected\n");
0592 rockchip_usb2phy_power_off(rport->phy);
0593 notify_charger = true;
0594 sch_work = true;
0595 cable = EXTCON_CHG_USB_DCP;
0596 break;
0597 case POWER_SUPPLY_TYPE_USB_CDP:
0598 dev_dbg(&rport->phy->dev, "cdp cable is connected\n");
0599 rockchip_usb2phy_power_on(rport->phy);
0600 rport->state = OTG_STATE_B_PERIPHERAL;
0601 notify_charger = true;
0602 sch_work = true;
0603 cable = EXTCON_CHG_USB_CDP;
0604 break;
0605 default:
0606 break;
0607 }
0608 break;
0609 default:
0610 break;
0611 }
0612 } else {
0613 notify_charger = true;
0614 rphy->chg_state = USB_CHG_STATE_UNDEFINED;
0615 rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
0616 }
0617
0618 if (rport->vbus_attached != vbus_attach) {
0619 rport->vbus_attached = vbus_attach;
0620
0621 if (notify_charger && rphy->edev) {
0622 extcon_set_state_sync(rphy->edev,
0623 cable, vbus_attach);
0624 if (cable == EXTCON_CHG_USB_SDP)
0625 extcon_set_state_sync(rphy->edev,
0626 EXTCON_USB,
0627 vbus_attach);
0628 }
0629 }
0630 break;
0631 case OTG_STATE_B_PERIPHERAL:
0632 if (!vbus_attach) {
0633 dev_dbg(&rport->phy->dev, "usb disconnect\n");
0634 rphy->chg_state = USB_CHG_STATE_UNDEFINED;
0635 rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
0636 rport->state = OTG_STATE_B_IDLE;
0637 delay = 0;
0638 rockchip_usb2phy_power_off(rport->phy);
0639 }
0640 sch_work = true;
0641 break;
0642 case OTG_STATE_A_HOST:
0643 if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) == 0) {
0644 dev_dbg(&rport->phy->dev, "usb otg host disconnect\n");
0645 rport->state = OTG_STATE_B_IDLE;
0646 rockchip_usb2phy_power_off(rport->phy);
0647 }
0648 break;
0649 default:
0650 break;
0651 }
0652
0653 if (sch_work)
0654 schedule_delayed_work(&rport->otg_sm_work, delay);
0655 }
0656
0657 static const char *chg_to_string(enum power_supply_type chg_type)
0658 {
0659 switch (chg_type) {
0660 case POWER_SUPPLY_TYPE_USB:
0661 return "USB_SDP_CHARGER";
0662 case POWER_SUPPLY_TYPE_USB_DCP:
0663 return "USB_DCP_CHARGER";
0664 case POWER_SUPPLY_TYPE_USB_CDP:
0665 return "USB_CDP_CHARGER";
0666 default:
0667 return "INVALID_CHARGER";
0668 }
0669 }
0670
0671 static void rockchip_chg_enable_dcd(struct rockchip_usb2phy *rphy,
0672 bool en)
0673 {
0674 struct regmap *base = get_reg_base(rphy);
0675
0676 property_enable(base, &rphy->phy_cfg->chg_det.rdm_pdwn_en, en);
0677 property_enable(base, &rphy->phy_cfg->chg_det.idp_src_en, en);
0678 }
0679
0680 static void rockchip_chg_enable_primary_det(struct rockchip_usb2phy *rphy,
0681 bool en)
0682 {
0683 struct regmap *base = get_reg_base(rphy);
0684
0685 property_enable(base, &rphy->phy_cfg->chg_det.vdp_src_en, en);
0686 property_enable(base, &rphy->phy_cfg->chg_det.idm_sink_en, en);
0687 }
0688
0689 static void rockchip_chg_enable_secondary_det(struct rockchip_usb2phy *rphy,
0690 bool en)
0691 {
0692 struct regmap *base = get_reg_base(rphy);
0693
0694 property_enable(base, &rphy->phy_cfg->chg_det.vdm_src_en, en);
0695 property_enable(base, &rphy->phy_cfg->chg_det.idp_sink_en, en);
0696 }
0697
0698 #define CHG_DCD_POLL_TIME (100 * HZ / 1000)
0699 #define CHG_DCD_MAX_RETRIES 6
0700 #define CHG_PRIMARY_DET_TIME (40 * HZ / 1000)
0701 #define CHG_SECONDARY_DET_TIME (40 * HZ / 1000)
0702 static void rockchip_chg_detect_work(struct work_struct *work)
0703 {
0704 struct rockchip_usb2phy_port *rport =
0705 container_of(work, struct rockchip_usb2phy_port, chg_work.work);
0706 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0707 struct regmap *base = get_reg_base(rphy);
0708 bool is_dcd, tmout, vout;
0709 unsigned long delay;
0710
0711 dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
0712 rphy->chg_state);
0713 switch (rphy->chg_state) {
0714 case USB_CHG_STATE_UNDEFINED:
0715 if (!rport->suspended)
0716 rockchip_usb2phy_power_off(rport->phy);
0717
0718 property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
0719
0720 rockchip_chg_enable_dcd(rphy, true);
0721 rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
0722 rphy->dcd_retries = 0;
0723 delay = CHG_DCD_POLL_TIME;
0724 break;
0725 case USB_CHG_STATE_WAIT_FOR_DCD:
0726
0727 is_dcd = property_enabled(rphy->grf,
0728 &rphy->phy_cfg->chg_det.dp_det);
0729 tmout = ++rphy->dcd_retries == CHG_DCD_MAX_RETRIES;
0730
0731 if (is_dcd || tmout) {
0732
0733
0734 rockchip_chg_enable_dcd(rphy, false);
0735
0736 rockchip_chg_enable_primary_det(rphy, true);
0737 delay = CHG_PRIMARY_DET_TIME;
0738 rphy->chg_state = USB_CHG_STATE_DCD_DONE;
0739 } else {
0740
0741 delay = CHG_DCD_POLL_TIME;
0742 }
0743 break;
0744 case USB_CHG_STATE_DCD_DONE:
0745 vout = property_enabled(rphy->grf,
0746 &rphy->phy_cfg->chg_det.cp_det);
0747 rockchip_chg_enable_primary_det(rphy, false);
0748 if (vout) {
0749
0750 rockchip_chg_enable_secondary_det(rphy, true);
0751 delay = CHG_SECONDARY_DET_TIME;
0752 rphy->chg_state = USB_CHG_STATE_PRIMARY_DONE;
0753 } else {
0754 if (rphy->dcd_retries == CHG_DCD_MAX_RETRIES) {
0755
0756 rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
0757 rphy->chg_state = USB_CHG_STATE_DETECTED;
0758 delay = 0;
0759 } else {
0760 rphy->chg_type = POWER_SUPPLY_TYPE_USB;
0761 rphy->chg_state = USB_CHG_STATE_DETECTED;
0762 delay = 0;
0763 }
0764 }
0765 break;
0766 case USB_CHG_STATE_PRIMARY_DONE:
0767 vout = property_enabled(rphy->grf,
0768 &rphy->phy_cfg->chg_det.dcp_det);
0769
0770 rockchip_chg_enable_secondary_det(rphy, false);
0771 if (vout)
0772 rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP;
0773 else
0774 rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP;
0775 fallthrough;
0776 case USB_CHG_STATE_SECONDARY_DONE:
0777 rphy->chg_state = USB_CHG_STATE_DETECTED;
0778 fallthrough;
0779 case USB_CHG_STATE_DETECTED:
0780
0781 property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
0782 rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
0783 dev_dbg(&rport->phy->dev, "charger = %s\n",
0784 chg_to_string(rphy->chg_type));
0785 return;
0786 default:
0787 return;
0788 }
0789
0790 schedule_delayed_work(&rport->chg_work, delay);
0791 }
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806 static void rockchip_usb2phy_sm_work(struct work_struct *work)
0807 {
0808 struct rockchip_usb2phy_port *rport =
0809 container_of(work, struct rockchip_usb2phy_port, sm_work.work);
0810 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0811 unsigned int sh = rport->port_cfg->utmi_hstdet.bitend -
0812 rport->port_cfg->utmi_hstdet.bitstart + 1;
0813 unsigned int ul, uhd, state;
0814 unsigned int ul_mask, uhd_mask;
0815 int ret;
0816
0817 mutex_lock(&rport->mutex);
0818
0819 ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul);
0820 if (ret < 0)
0821 goto next_schedule;
0822
0823 ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd);
0824 if (ret < 0)
0825 goto next_schedule;
0826
0827 uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend,
0828 rport->port_cfg->utmi_hstdet.bitstart);
0829 ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend,
0830 rport->port_cfg->utmi_ls.bitstart);
0831
0832
0833 state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) |
0834 (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh);
0835
0836 switch (state) {
0837 case PHY_STATE_HS_ONLINE:
0838 dev_dbg(&rport->phy->dev, "HS online\n");
0839 break;
0840 case PHY_STATE_FS_LS_ONLINE:
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850 if (!rport->suspended) {
0851
0852 dev_dbg(&rport->phy->dev, "FS/LS online\n");
0853 break;
0854 }
0855 fallthrough;
0856 case PHY_STATE_CONNECT:
0857 if (rport->suspended) {
0858 dev_dbg(&rport->phy->dev, "Connected\n");
0859 rockchip_usb2phy_power_on(rport->phy);
0860 rport->suspended = false;
0861 } else {
0862
0863 dev_dbg(&rport->phy->dev, "FS/LS online\n");
0864 }
0865 break;
0866 case PHY_STATE_DISCONNECT:
0867 if (!rport->suspended) {
0868 dev_dbg(&rport->phy->dev, "Disconnected\n");
0869 rockchip_usb2phy_power_off(rport->phy);
0870 rport->suspended = true;
0871 }
0872
0873
0874
0875
0876
0877 property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
0878 property_enable(rphy->grf, &rport->port_cfg->ls_det_en, true);
0879
0880
0881
0882
0883
0884 mutex_unlock(&rport->mutex);
0885 return;
0886 default:
0887 dev_dbg(&rport->phy->dev, "unknown phy state\n");
0888 break;
0889 }
0890
0891 next_schedule:
0892 mutex_unlock(&rport->mutex);
0893 schedule_delayed_work(&rport->sm_work, SCHEDULE_DELAY);
0894 }
0895
0896 static irqreturn_t rockchip_usb2phy_linestate_irq(int irq, void *data)
0897 {
0898 struct rockchip_usb2phy_port *rport = data;
0899 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0900
0901 if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st))
0902 return IRQ_NONE;
0903
0904 mutex_lock(&rport->mutex);
0905
0906
0907 property_enable(rphy->grf, &rport->port_cfg->ls_det_en, false);
0908 property_enable(rphy->grf, &rport->port_cfg->ls_det_clr, true);
0909
0910 mutex_unlock(&rport->mutex);
0911
0912
0913
0914
0915
0916
0917 if (rport->suspended && rport->port_id == USB2PHY_PORT_HOST)
0918 rockchip_usb2phy_sm_work(&rport->sm_work.work);
0919
0920 return IRQ_HANDLED;
0921 }
0922
0923 static irqreturn_t rockchip_usb2phy_bvalid_irq(int irq, void *data)
0924 {
0925 struct rockchip_usb2phy_port *rport = data;
0926 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0927
0928 if (!property_enabled(rphy->grf, &rport->port_cfg->bvalid_det_st))
0929 return IRQ_NONE;
0930
0931
0932 property_enable(rphy->grf, &rport->port_cfg->bvalid_det_clr, true);
0933
0934 rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
0935
0936 return IRQ_HANDLED;
0937 }
0938
0939 static irqreturn_t rockchip_usb2phy_id_irq(int irq, void *data)
0940 {
0941 struct rockchip_usb2phy_port *rport = data;
0942 struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
0943 bool id;
0944
0945 if (!property_enabled(rphy->grf, &rport->port_cfg->id_det_st))
0946 return IRQ_NONE;
0947
0948
0949 property_enable(rphy->grf, &rport->port_cfg->id_det_clr, true);
0950
0951 id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
0952 extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
0953
0954 return IRQ_HANDLED;
0955 }
0956
0957 static irqreturn_t rockchip_usb2phy_otg_mux_irq(int irq, void *data)
0958 {
0959 irqreturn_t ret = IRQ_NONE;
0960
0961 ret |= rockchip_usb2phy_bvalid_irq(irq, data);
0962 ret |= rockchip_usb2phy_id_irq(irq, data);
0963
0964 return ret;
0965 }
0966
0967 static irqreturn_t rockchip_usb2phy_irq(int irq, void *data)
0968 {
0969 struct rockchip_usb2phy *rphy = data;
0970 struct rockchip_usb2phy_port *rport;
0971 irqreturn_t ret = IRQ_NONE;
0972 unsigned int index;
0973
0974 for (index = 0; index < rphy->phy_cfg->num_ports; index++) {
0975 rport = &rphy->ports[index];
0976 if (!rport->phy)
0977 continue;
0978
0979 switch (rport->port_id) {
0980 case USB2PHY_PORT_OTG:
0981 if (rport->mode != USB_DR_MODE_HOST &&
0982 rport->mode != USB_DR_MODE_UNKNOWN)
0983 ret |= rockchip_usb2phy_otg_mux_irq(irq, rport);
0984 break;
0985 case USB2PHY_PORT_HOST:
0986 ret |= rockchip_usb2phy_linestate_irq(irq, rport);
0987 break;
0988 }
0989 }
0990
0991 return ret;
0992 }
0993
0994 static int rockchip_usb2phy_port_irq_init(struct rockchip_usb2phy *rphy,
0995 struct rockchip_usb2phy_port *rport,
0996 struct device_node *child_np)
0997 {
0998 int ret;
0999
1000
1001
1002
1003
1004 if (rphy->irq > 0)
1005 return 0;
1006
1007 switch (rport->port_id) {
1008 case USB2PHY_PORT_HOST:
1009 rport->ls_irq = of_irq_get_byname(child_np, "linestate");
1010 if (rport->ls_irq < 0) {
1011 dev_err(rphy->dev, "no linestate irq provided\n");
1012 return rport->ls_irq;
1013 }
1014
1015 ret = devm_request_threaded_irq(rphy->dev, rport->ls_irq, NULL,
1016 rockchip_usb2phy_linestate_irq,
1017 IRQF_ONESHOT,
1018 "rockchip_usb2phy", rport);
1019 if (ret) {
1020 dev_err(rphy->dev, "failed to request linestate irq handle\n");
1021 return ret;
1022 }
1023 break;
1024 case USB2PHY_PORT_OTG:
1025
1026
1027
1028
1029
1030 rport->otg_mux_irq = of_irq_get_byname(child_np, "otg-mux");
1031 if (rport->otg_mux_irq > 0) {
1032 ret = devm_request_threaded_irq(rphy->dev, rport->otg_mux_irq,
1033 NULL,
1034 rockchip_usb2phy_otg_mux_irq,
1035 IRQF_ONESHOT,
1036 "rockchip_usb2phy_otg",
1037 rport);
1038 if (ret) {
1039 dev_err(rphy->dev,
1040 "failed to request otg-mux irq handle\n");
1041 return ret;
1042 }
1043 } else {
1044 rport->bvalid_irq = of_irq_get_byname(child_np, "otg-bvalid");
1045 if (rport->bvalid_irq < 0) {
1046 dev_err(rphy->dev, "no vbus valid irq provided\n");
1047 ret = rport->bvalid_irq;
1048 return ret;
1049 }
1050
1051 ret = devm_request_threaded_irq(rphy->dev, rport->bvalid_irq,
1052 NULL,
1053 rockchip_usb2phy_bvalid_irq,
1054 IRQF_ONESHOT,
1055 "rockchip_usb2phy_bvalid",
1056 rport);
1057 if (ret) {
1058 dev_err(rphy->dev,
1059 "failed to request otg-bvalid irq handle\n");
1060 return ret;
1061 }
1062
1063 rport->id_irq = of_irq_get_byname(child_np, "otg-id");
1064 if (rport->id_irq < 0) {
1065 dev_err(rphy->dev, "no otg-id irq provided\n");
1066 ret = rport->id_irq;
1067 return ret;
1068 }
1069
1070 ret = devm_request_threaded_irq(rphy->dev, rport->id_irq,
1071 NULL,
1072 rockchip_usb2phy_id_irq,
1073 IRQF_ONESHOT,
1074 "rockchip_usb2phy_id",
1075 rport);
1076 if (ret) {
1077 dev_err(rphy->dev,
1078 "failed to request otg-id irq handle\n");
1079 return ret;
1080 }
1081 }
1082 break;
1083 default:
1084 return -EINVAL;
1085 }
1086
1087 return 0;
1088 }
1089
1090 static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy,
1091 struct rockchip_usb2phy_port *rport,
1092 struct device_node *child_np)
1093 {
1094 int ret;
1095
1096 rport->port_id = USB2PHY_PORT_HOST;
1097 rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_HOST];
1098 rport->suspended = true;
1099
1100 mutex_init(&rport->mutex);
1101 INIT_DELAYED_WORK(&rport->sm_work, rockchip_usb2phy_sm_work);
1102
1103 ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
1104 if (ret) {
1105 dev_err(rphy->dev, "failed to setup host irq\n");
1106 return ret;
1107 }
1108
1109 return 0;
1110 }
1111
1112 static int rockchip_otg_event(struct notifier_block *nb,
1113 unsigned long event, void *ptr)
1114 {
1115 struct rockchip_usb2phy_port *rport =
1116 container_of(nb, struct rockchip_usb2phy_port, event_nb);
1117
1118 schedule_delayed_work(&rport->otg_sm_work, OTG_SCHEDULE_DELAY);
1119
1120 return NOTIFY_DONE;
1121 }
1122
1123 static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
1124 struct rockchip_usb2phy_port *rport,
1125 struct device_node *child_np)
1126 {
1127 int ret;
1128
1129 rport->port_id = USB2PHY_PORT_OTG;
1130 rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
1131 rport->state = OTG_STATE_UNDEFINED;
1132
1133
1134
1135
1136
1137
1138
1139 rport->suspended = true;
1140 rport->vbus_attached = false;
1141
1142 mutex_init(&rport->mutex);
1143
1144 rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
1145 if (rport->mode == USB_DR_MODE_HOST ||
1146 rport->mode == USB_DR_MODE_UNKNOWN) {
1147 ret = 0;
1148 goto out;
1149 }
1150
1151 INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work);
1152 INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work);
1153
1154 ret = rockchip_usb2phy_port_irq_init(rphy, rport, child_np);
1155 if (ret) {
1156 dev_err(rphy->dev, "failed to init irq for host port\n");
1157 goto out;
1158 }
1159
1160 if (!IS_ERR(rphy->edev)) {
1161 rport->event_nb.notifier_call = rockchip_otg_event;
1162
1163 ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
1164 EXTCON_USB_HOST, &rport->event_nb);
1165 if (ret)
1166 dev_err(rphy->dev, "register USB HOST notifier failed\n");
1167
1168 if (!of_property_read_bool(rphy->dev->of_node, "extcon")) {
1169
1170 ret = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
1171 extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !ret);
1172 }
1173 }
1174
1175 out:
1176 return ret;
1177 }
1178
1179 static int rockchip_usb2phy_probe(struct platform_device *pdev)
1180 {
1181 struct device *dev = &pdev->dev;
1182 struct device_node *np = dev->of_node;
1183 struct device_node *child_np;
1184 struct phy_provider *provider;
1185 struct rockchip_usb2phy *rphy;
1186 const struct rockchip_usb2phy_cfg *phy_cfgs;
1187 const struct of_device_id *match;
1188 unsigned int reg;
1189 int index, ret;
1190
1191 rphy = devm_kzalloc(dev, sizeof(*rphy), GFP_KERNEL);
1192 if (!rphy)
1193 return -ENOMEM;
1194
1195 match = of_match_device(dev->driver->of_match_table, dev);
1196 if (!match || !match->data) {
1197 dev_err(dev, "phy configs are not assigned!\n");
1198 return -EINVAL;
1199 }
1200
1201 if (!dev->parent || !dev->parent->of_node) {
1202 rphy->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,usbgrf");
1203 if (IS_ERR(rphy->grf)) {
1204 dev_err(dev, "failed to locate usbgrf\n");
1205 return PTR_ERR(rphy->grf);
1206 }
1207 }
1208
1209 else {
1210 rphy->grf = syscon_node_to_regmap(dev->parent->of_node);
1211 if (IS_ERR(rphy->grf))
1212 return PTR_ERR(rphy->grf);
1213 }
1214
1215 if (of_device_is_compatible(np, "rockchip,rv1108-usb2phy")) {
1216 rphy->usbgrf =
1217 syscon_regmap_lookup_by_phandle(dev->of_node,
1218 "rockchip,usbgrf");
1219 if (IS_ERR(rphy->usbgrf))
1220 return PTR_ERR(rphy->usbgrf);
1221 } else {
1222 rphy->usbgrf = NULL;
1223 }
1224
1225 if (of_property_read_u32_index(np, "reg", 0, ®)) {
1226 dev_err(dev, "the reg property is not assigned in %pOFn node\n",
1227 np);
1228 return -EINVAL;
1229 }
1230
1231
1232 if (reg == 0) {
1233 if (of_property_read_u32_index(np, "reg", 1, ®)) {
1234 dev_err(dev, "the reg property is not assigned in %pOFn node\n",
1235 np);
1236 return -EINVAL;
1237 }
1238 }
1239
1240 rphy->dev = dev;
1241 phy_cfgs = match->data;
1242 rphy->chg_state = USB_CHG_STATE_UNDEFINED;
1243 rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN;
1244 rphy->irq = platform_get_irq_optional(pdev, 0);
1245 platform_set_drvdata(pdev, rphy);
1246
1247 ret = rockchip_usb2phy_extcon_register(rphy);
1248 if (ret)
1249 return ret;
1250
1251
1252 index = 0;
1253 while (phy_cfgs[index].reg) {
1254 if (phy_cfgs[index].reg == reg) {
1255 rphy->phy_cfg = &phy_cfgs[index];
1256 break;
1257 }
1258
1259 ++index;
1260 }
1261
1262 if (!rphy->phy_cfg) {
1263 dev_err(dev, "no phy-config can be matched with %pOFn node\n",
1264 np);
1265 return -EINVAL;
1266 }
1267
1268 rphy->clk = of_clk_get_by_name(np, "phyclk");
1269 if (!IS_ERR(rphy->clk)) {
1270 clk_prepare_enable(rphy->clk);
1271 } else {
1272 dev_info(&pdev->dev, "no phyclk specified\n");
1273 rphy->clk = NULL;
1274 }
1275
1276 ret = rockchip_usb2phy_clk480m_register(rphy);
1277 if (ret) {
1278 dev_err(dev, "failed to register 480m output clock\n");
1279 goto disable_clks;
1280 }
1281
1282 index = 0;
1283 for_each_available_child_of_node(np, child_np) {
1284 struct rockchip_usb2phy_port *rport = &rphy->ports[index];
1285 struct phy *phy;
1286
1287
1288 if (!of_node_name_eq(child_np, "host-port") &&
1289 !of_node_name_eq(child_np, "otg-port"))
1290 goto next_child;
1291
1292 phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops);
1293 if (IS_ERR(phy)) {
1294 dev_err_probe(dev, PTR_ERR(phy), "failed to create phy\n");
1295 ret = PTR_ERR(phy);
1296 goto put_child;
1297 }
1298
1299 rport->phy = phy;
1300 phy_set_drvdata(rport->phy, rport);
1301
1302
1303 if (of_node_name_eq(child_np, "host-port")) {
1304 ret = rockchip_usb2phy_host_port_init(rphy, rport,
1305 child_np);
1306 if (ret)
1307 goto put_child;
1308 } else {
1309 ret = rockchip_usb2phy_otg_port_init(rphy, rport,
1310 child_np);
1311 if (ret)
1312 goto put_child;
1313 }
1314
1315 next_child:
1316
1317 if (++index >= rphy->phy_cfg->num_ports) {
1318 of_node_put(child_np);
1319 break;
1320 }
1321 }
1322
1323 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1324
1325 if (rphy->irq > 0) {
1326 ret = devm_request_threaded_irq(rphy->dev, rphy->irq, NULL,
1327 rockchip_usb2phy_irq,
1328 IRQF_ONESHOT,
1329 "rockchip_usb2phy",
1330 rphy);
1331 if (ret) {
1332 dev_err(rphy->dev,
1333 "failed to request usb2phy irq handle\n");
1334 goto put_child;
1335 }
1336 }
1337
1338 return PTR_ERR_OR_ZERO(provider);
1339
1340 put_child:
1341 of_node_put(child_np);
1342 disable_clks:
1343 if (rphy->clk) {
1344 clk_disable_unprepare(rphy->clk);
1345 clk_put(rphy->clk);
1346 }
1347 return ret;
1348 }
1349
1350 static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
1351 {
1352 .reg = 0x760,
1353 .num_ports = 2,
1354 .clkout_ctl = { 0x0768, 4, 4, 1, 0 },
1355 .port_cfgs = {
1356 [USB2PHY_PORT_OTG] = {
1357 .phy_sus = { 0x0760, 15, 0, 0, 0x1d1 },
1358 .bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
1359 .bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
1360 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
1361 .id_det_en = { 0x0680, 6, 5, 0, 3 },
1362 .id_det_st = { 0x0690, 6, 5, 0, 3 },
1363 .id_det_clr = { 0x06a0, 6, 5, 0, 3 },
1364 .ls_det_en = { 0x0680, 2, 2, 0, 1 },
1365 .ls_det_st = { 0x0690, 2, 2, 0, 1 },
1366 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
1367 .utmi_bvalid = { 0x0480, 4, 4, 0, 1 },
1368 .utmi_id = { 0x0480, 1, 1, 0, 1 },
1369 .utmi_ls = { 0x0480, 3, 2, 0, 1 },
1370 },
1371 [USB2PHY_PORT_HOST] = {
1372 .phy_sus = { 0x0764, 15, 0, 0, 0x1d1 },
1373 .ls_det_en = { 0x0680, 4, 4, 0, 1 },
1374 .ls_det_st = { 0x0690, 4, 4, 0, 1 },
1375 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 }
1376 }
1377 },
1378 .chg_det = {
1379 .opmode = { 0x0760, 3, 0, 5, 1 },
1380 .cp_det = { 0x0884, 4, 4, 0, 1 },
1381 .dcp_det = { 0x0884, 3, 3, 0, 1 },
1382 .dp_det = { 0x0884, 5, 5, 0, 1 },
1383 .idm_sink_en = { 0x0768, 8, 8, 0, 1 },
1384 .idp_sink_en = { 0x0768, 7, 7, 0, 1 },
1385 .idp_src_en = { 0x0768, 9, 9, 0, 1 },
1386 .rdm_pdwn_en = { 0x0768, 10, 10, 0, 1 },
1387 .vdm_src_en = { 0x0768, 12, 12, 0, 1 },
1388 .vdp_src_en = { 0x0768, 11, 11, 0, 1 },
1389 },
1390 },
1391 {
1392 .reg = 0x800,
1393 .num_ports = 2,
1394 .clkout_ctl = { 0x0808, 4, 4, 1, 0 },
1395 .port_cfgs = {
1396 [USB2PHY_PORT_OTG] = {
1397 .phy_sus = { 0x800, 15, 0, 0, 0x1d1 },
1398 .ls_det_en = { 0x0684, 0, 0, 0, 1 },
1399 .ls_det_st = { 0x0694, 0, 0, 0, 1 },
1400 .ls_det_clr = { 0x06a4, 0, 0, 0, 1 }
1401 },
1402 [USB2PHY_PORT_HOST] = {
1403 .phy_sus = { 0x804, 15, 0, 0, 0x1d1 },
1404 .ls_det_en = { 0x0684, 1, 1, 0, 1 },
1405 .ls_det_st = { 0x0694, 1, 1, 0, 1 },
1406 .ls_det_clr = { 0x06a4, 1, 1, 0, 1 }
1407 }
1408 },
1409 },
1410 { }
1411 };
1412
1413 static const struct rockchip_usb2phy_cfg rk3308_phy_cfgs[] = {
1414 {
1415 .reg = 0x100,
1416 .num_ports = 2,
1417 .clkout_ctl = { 0x108, 4, 4, 1, 0 },
1418 .port_cfgs = {
1419 [USB2PHY_PORT_OTG] = {
1420 .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 },
1421 .bvalid_det_en = { 0x3020, 3, 2, 0, 3 },
1422 .bvalid_det_st = { 0x3024, 3, 2, 0, 3 },
1423 .bvalid_det_clr = { 0x3028, 3, 2, 0, 3 },
1424 .id_det_en = { 0x3020, 5, 4, 0, 3 },
1425 .id_det_st = { 0x3024, 5, 4, 0, 3 },
1426 .id_det_clr = { 0x3028, 5, 4, 0, 3 },
1427 .ls_det_en = { 0x3020, 0, 0, 0, 1 },
1428 .ls_det_st = { 0x3024, 0, 0, 0, 1 },
1429 .ls_det_clr = { 0x3028, 0, 0, 0, 1 },
1430 .utmi_avalid = { 0x0120, 10, 10, 0, 1 },
1431 .utmi_bvalid = { 0x0120, 9, 9, 0, 1 },
1432 .utmi_id = { 0x0120, 6, 6, 0, 1 },
1433 .utmi_ls = { 0x0120, 5, 4, 0, 1 },
1434 },
1435 [USB2PHY_PORT_HOST] = {
1436 .phy_sus = { 0x0104, 8, 0, 0, 0x1d1 },
1437 .ls_det_en = { 0x3020, 1, 1, 0, 1 },
1438 .ls_det_st = { 0x3024, 1, 1, 0, 1 },
1439 .ls_det_clr = { 0x3028, 1, 1, 0, 1 },
1440 .utmi_ls = { 0x0120, 17, 16, 0, 1 },
1441 .utmi_hstdet = { 0x0120, 19, 19, 0, 1 }
1442 }
1443 },
1444 .chg_det = {
1445 .opmode = { 0x0100, 3, 0, 5, 1 },
1446 .cp_det = { 0x0120, 24, 24, 0, 1 },
1447 .dcp_det = { 0x0120, 23, 23, 0, 1 },
1448 .dp_det = { 0x0120, 25, 25, 0, 1 },
1449 .idm_sink_en = { 0x0108, 8, 8, 0, 1 },
1450 .idp_sink_en = { 0x0108, 7, 7, 0, 1 },
1451 .idp_src_en = { 0x0108, 9, 9, 0, 1 },
1452 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
1453 .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
1454 .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
1455 },
1456 },
1457 { }
1458 };
1459
1460 static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
1461 {
1462 .reg = 0x100,
1463 .num_ports = 2,
1464 .clkout_ctl = { 0x108, 4, 4, 1, 0 },
1465 .port_cfgs = {
1466 [USB2PHY_PORT_OTG] = {
1467 .phy_sus = { 0x0100, 15, 0, 0, 0x1d1 },
1468 .bvalid_det_en = { 0x0110, 3, 2, 0, 3 },
1469 .bvalid_det_st = { 0x0114, 3, 2, 0, 3 },
1470 .bvalid_det_clr = { 0x0118, 3, 2, 0, 3 },
1471 .id_det_en = { 0x0110, 5, 4, 0, 3 },
1472 .id_det_st = { 0x0114, 5, 4, 0, 3 },
1473 .id_det_clr = { 0x0118, 5, 4, 0, 3 },
1474 .ls_det_en = { 0x0110, 0, 0, 0, 1 },
1475 .ls_det_st = { 0x0114, 0, 0, 0, 1 },
1476 .ls_det_clr = { 0x0118, 0, 0, 0, 1 },
1477 .utmi_avalid = { 0x0120, 10, 10, 0, 1 },
1478 .utmi_bvalid = { 0x0120, 9, 9, 0, 1 },
1479 .utmi_id = { 0x0120, 6, 6, 0, 1 },
1480 .utmi_ls = { 0x0120, 5, 4, 0, 1 },
1481 },
1482 [USB2PHY_PORT_HOST] = {
1483 .phy_sus = { 0x104, 15, 0, 0, 0x1d1 },
1484 .ls_det_en = { 0x110, 1, 1, 0, 1 },
1485 .ls_det_st = { 0x114, 1, 1, 0, 1 },
1486 .ls_det_clr = { 0x118, 1, 1, 0, 1 },
1487 .utmi_ls = { 0x120, 17, 16, 0, 1 },
1488 .utmi_hstdet = { 0x120, 19, 19, 0, 1 }
1489 }
1490 },
1491 .chg_det = {
1492 .opmode = { 0x0100, 3, 0, 5, 1 },
1493 .cp_det = { 0x0120, 24, 24, 0, 1 },
1494 .dcp_det = { 0x0120, 23, 23, 0, 1 },
1495 .dp_det = { 0x0120, 25, 25, 0, 1 },
1496 .idm_sink_en = { 0x0108, 8, 8, 0, 1 },
1497 .idp_sink_en = { 0x0108, 7, 7, 0, 1 },
1498 .idp_src_en = { 0x0108, 9, 9, 0, 1 },
1499 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
1500 .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
1501 .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
1502 },
1503 },
1504 { }
1505 };
1506
1507 static const struct rockchip_usb2phy_cfg rk3366_phy_cfgs[] = {
1508 {
1509 .reg = 0x700,
1510 .num_ports = 2,
1511 .clkout_ctl = { 0x0724, 15, 15, 1, 0 },
1512 .port_cfgs = {
1513 [USB2PHY_PORT_HOST] = {
1514 .phy_sus = { 0x0728, 15, 0, 0, 0x1d1 },
1515 .ls_det_en = { 0x0680, 4, 4, 0, 1 },
1516 .ls_det_st = { 0x0690, 4, 4, 0, 1 },
1517 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 },
1518 .utmi_ls = { 0x049c, 14, 13, 0, 1 },
1519 .utmi_hstdet = { 0x049c, 12, 12, 0, 1 }
1520 }
1521 },
1522 },
1523 { }
1524 };
1525
1526 static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
1527 {
1528 .reg = 0xe450,
1529 .num_ports = 2,
1530 .clkout_ctl = { 0xe450, 4, 4, 1, 0 },
1531 .port_cfgs = {
1532 [USB2PHY_PORT_OTG] = {
1533 .phy_sus = { 0xe454, 1, 0, 2, 1 },
1534 .bvalid_det_en = { 0xe3c0, 3, 3, 0, 1 },
1535 .bvalid_det_st = { 0xe3e0, 3, 3, 0, 1 },
1536 .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 },
1537 .id_det_en = { 0xe3c0, 5, 4, 0, 3 },
1538 .id_det_st = { 0xe3e0, 5, 4, 0, 3 },
1539 .id_det_clr = { 0xe3d0, 5, 4, 0, 3 },
1540 .utmi_avalid = { 0xe2ac, 7, 7, 0, 1 },
1541 .utmi_bvalid = { 0xe2ac, 12, 12, 0, 1 },
1542 .utmi_id = { 0xe2ac, 8, 8, 0, 1 },
1543 },
1544 [USB2PHY_PORT_HOST] = {
1545 .phy_sus = { 0xe458, 1, 0, 0x2, 0x1 },
1546 .ls_det_en = { 0xe3c0, 6, 6, 0, 1 },
1547 .ls_det_st = { 0xe3e0, 6, 6, 0, 1 },
1548 .ls_det_clr = { 0xe3d0, 6, 6, 0, 1 },
1549 .utmi_ls = { 0xe2ac, 22, 21, 0, 1 },
1550 .utmi_hstdet = { 0xe2ac, 23, 23, 0, 1 }
1551 }
1552 },
1553 .chg_det = {
1554 .opmode = { 0xe454, 3, 0, 5, 1 },
1555 .cp_det = { 0xe2ac, 2, 2, 0, 1 },
1556 .dcp_det = { 0xe2ac, 1, 1, 0, 1 },
1557 .dp_det = { 0xe2ac, 0, 0, 0, 1 },
1558 .idm_sink_en = { 0xe450, 8, 8, 0, 1 },
1559 .idp_sink_en = { 0xe450, 7, 7, 0, 1 },
1560 .idp_src_en = { 0xe450, 9, 9, 0, 1 },
1561 .rdm_pdwn_en = { 0xe450, 10, 10, 0, 1 },
1562 .vdm_src_en = { 0xe450, 12, 12, 0, 1 },
1563 .vdp_src_en = { 0xe450, 11, 11, 0, 1 },
1564 },
1565 },
1566 {
1567 .reg = 0xe460,
1568 .num_ports = 2,
1569 .clkout_ctl = { 0xe460, 4, 4, 1, 0 },
1570 .port_cfgs = {
1571 [USB2PHY_PORT_OTG] = {
1572 .phy_sus = { 0xe464, 1, 0, 2, 1 },
1573 .bvalid_det_en = { 0xe3c0, 8, 8, 0, 1 },
1574 .bvalid_det_st = { 0xe3e0, 8, 8, 0, 1 },
1575 .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
1576 .id_det_en = { 0xe3c0, 10, 9, 0, 3 },
1577 .id_det_st = { 0xe3e0, 10, 9, 0, 3 },
1578 .id_det_clr = { 0xe3d0, 10, 9, 0, 3 },
1579 .utmi_avalid = { 0xe2ac, 10, 10, 0, 1 },
1580 .utmi_bvalid = { 0xe2ac, 16, 16, 0, 1 },
1581 .utmi_id = { 0xe2ac, 11, 11, 0, 1 },
1582 },
1583 [USB2PHY_PORT_HOST] = {
1584 .phy_sus = { 0xe468, 1, 0, 0x2, 0x1 },
1585 .ls_det_en = { 0xe3c0, 11, 11, 0, 1 },
1586 .ls_det_st = { 0xe3e0, 11, 11, 0, 1 },
1587 .ls_det_clr = { 0xe3d0, 11, 11, 0, 1 },
1588 .utmi_ls = { 0xe2ac, 26, 25, 0, 1 },
1589 .utmi_hstdet = { 0xe2ac, 27, 27, 0, 1 }
1590 }
1591 },
1592 },
1593 { }
1594 };
1595
1596 static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = {
1597 {
1598 .reg = 0xfe8a0000,
1599 .num_ports = 2,
1600 .clkout_ctl = { 0x0008, 4, 4, 1, 0 },
1601 .port_cfgs = {
1602 [USB2PHY_PORT_OTG] = {
1603 .phy_sus = { 0x0000, 8, 0, 0, 0x1d1 },
1604 .bvalid_det_en = { 0x0080, 3, 2, 0, 3 },
1605 .bvalid_det_st = { 0x0084, 3, 2, 0, 3 },
1606 .bvalid_det_clr = { 0x0088, 3, 2, 0, 3 },
1607 .id_det_en = { 0x0080, 5, 4, 0, 3 },
1608 .id_det_st = { 0x0084, 5, 4, 0, 3 },
1609 .id_det_clr = { 0x0088, 5, 4, 0, 3 },
1610 .utmi_avalid = { 0x00c0, 10, 10, 0, 1 },
1611 .utmi_bvalid = { 0x00c0, 9, 9, 0, 1 },
1612 .utmi_id = { 0x00c0, 6, 6, 0, 1 },
1613 },
1614 [USB2PHY_PORT_HOST] = {
1615
1616 .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d2 },
1617 .ls_det_en = { 0x0080, 1, 1, 0, 1 },
1618 .ls_det_st = { 0x0084, 1, 1, 0, 1 },
1619 .ls_det_clr = { 0x0088, 1, 1, 0, 1 },
1620 .utmi_ls = { 0x00c0, 17, 16, 0, 1 },
1621 .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 }
1622 }
1623 },
1624 .chg_det = {
1625 .opmode = { 0x0000, 3, 0, 5, 1 },
1626 .cp_det = { 0x00c0, 24, 24, 0, 1 },
1627 .dcp_det = { 0x00c0, 23, 23, 0, 1 },
1628 .dp_det = { 0x00c0, 25, 25, 0, 1 },
1629 .idm_sink_en = { 0x0008, 8, 8, 0, 1 },
1630 .idp_sink_en = { 0x0008, 7, 7, 0, 1 },
1631 .idp_src_en = { 0x0008, 9, 9, 0, 1 },
1632 .rdm_pdwn_en = { 0x0008, 10, 10, 0, 1 },
1633 .vdm_src_en = { 0x0008, 12, 12, 0, 1 },
1634 .vdp_src_en = { 0x0008, 11, 11, 0, 1 },
1635 },
1636 },
1637 {
1638 .reg = 0xfe8b0000,
1639 .num_ports = 2,
1640 .clkout_ctl = { 0x0008, 4, 4, 1, 0 },
1641 .port_cfgs = {
1642 [USB2PHY_PORT_OTG] = {
1643 .phy_sus = { 0x0000, 8, 0, 0x1d2, 0x1d1 },
1644 .ls_det_en = { 0x0080, 0, 0, 0, 1 },
1645 .ls_det_st = { 0x0084, 0, 0, 0, 1 },
1646 .ls_det_clr = { 0x0088, 0, 0, 0, 1 },
1647 .utmi_ls = { 0x00c0, 5, 4, 0, 1 },
1648 .utmi_hstdet = { 0x00c0, 7, 7, 0, 1 }
1649 },
1650 [USB2PHY_PORT_HOST] = {
1651 .phy_sus = { 0x0004, 8, 0, 0x1d2, 0x1d1 },
1652 .ls_det_en = { 0x0080, 1, 1, 0, 1 },
1653 .ls_det_st = { 0x0084, 1, 1, 0, 1 },
1654 .ls_det_clr = { 0x0088, 1, 1, 0, 1 },
1655 .utmi_ls = { 0x00c0, 17, 16, 0, 1 },
1656 .utmi_hstdet = { 0x00c0, 19, 19, 0, 1 }
1657 }
1658 },
1659 },
1660 { }
1661 };
1662
1663 static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = {
1664 {
1665 .reg = 0x100,
1666 .num_ports = 2,
1667 .clkout_ctl = { 0x108, 4, 4, 1, 0 },
1668 .port_cfgs = {
1669 [USB2PHY_PORT_OTG] = {
1670 .phy_sus = { 0x0100, 15, 0, 0, 0x1d1 },
1671 .bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
1672 .bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
1673 .bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
1674 .ls_det_en = { 0x0680, 2, 2, 0, 1 },
1675 .ls_det_st = { 0x0690, 2, 2, 0, 1 },
1676 .ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
1677 .utmi_bvalid = { 0x0804, 10, 10, 0, 1 },
1678 .utmi_ls = { 0x0804, 13, 12, 0, 1 },
1679 },
1680 [USB2PHY_PORT_HOST] = {
1681 .phy_sus = { 0x0104, 15, 0, 0, 0x1d1 },
1682 .ls_det_en = { 0x0680, 4, 4, 0, 1 },
1683 .ls_det_st = { 0x0690, 4, 4, 0, 1 },
1684 .ls_det_clr = { 0x06a0, 4, 4, 0, 1 },
1685 .utmi_ls = { 0x0804, 9, 8, 0, 1 },
1686 .utmi_hstdet = { 0x0804, 7, 7, 0, 1 }
1687 }
1688 },
1689 .chg_det = {
1690 .opmode = { 0x0100, 3, 0, 5, 1 },
1691 .cp_det = { 0x0804, 1, 1, 0, 1 },
1692 .dcp_det = { 0x0804, 0, 0, 0, 1 },
1693 .dp_det = { 0x0804, 2, 2, 0, 1 },
1694 .idm_sink_en = { 0x0108, 8, 8, 0, 1 },
1695 .idp_sink_en = { 0x0108, 7, 7, 0, 1 },
1696 .idp_src_en = { 0x0108, 9, 9, 0, 1 },
1697 .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 },
1698 .vdm_src_en = { 0x0108, 12, 12, 0, 1 },
1699 .vdp_src_en = { 0x0108, 11, 11, 0, 1 },
1700 },
1701 },
1702 { }
1703 };
1704
1705 static const struct of_device_id rockchip_usb2phy_dt_match[] = {
1706 { .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs },
1707 { .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
1708 { .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs },
1709 { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
1710 { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
1711 { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
1712 { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs },
1713 { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs },
1714 {}
1715 };
1716 MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match);
1717
1718 static struct platform_driver rockchip_usb2phy_driver = {
1719 .probe = rockchip_usb2phy_probe,
1720 .driver = {
1721 .name = "rockchip-usb2phy",
1722 .of_match_table = rockchip_usb2phy_dt_match,
1723 },
1724 };
1725 module_platform_driver(rockchip_usb2phy_driver);
1726
1727 MODULE_AUTHOR("Frank Wang <frank.wang@rock-chips.com>");
1728 MODULE_DESCRIPTION("Rockchip USB2.0 PHY driver");
1729 MODULE_LICENSE("GPL v2");