.. | .. |
---|
109 | 109 | * @ls_det_en: linestate detection enable register. |
---|
110 | 110 | * @ls_det_st: linestate detection state register. |
---|
111 | 111 | * @ls_det_clr: linestate detection clear register. |
---|
112 | | - * @phy_chg_mode: set phy in charge detection mode. |
---|
113 | 112 | * @phy_sus: phy suspend register. |
---|
114 | 113 | * @utmi_bvalid: utmi vbus bvalid status register. |
---|
115 | 114 | * @utmi_iddig: otg port id pin status register. |
---|
.. | .. |
---|
141 | 140 | struct usb2phy_reg ls_det_en; |
---|
142 | 141 | struct usb2phy_reg ls_det_st; |
---|
143 | 142 | struct usb2phy_reg ls_det_clr; |
---|
144 | | - struct usb2phy_reg phy_chg_mode; |
---|
145 | 143 | struct usb2phy_reg phy_sus; |
---|
146 | 144 | struct usb2phy_reg utmi_bvalid; |
---|
147 | 145 | struct usb2phy_reg utmi_iddig; |
---|
.. | .. |
---|
221 | 219 | * @dev: pointer to our struct device. |
---|
222 | 220 | * @grf: General Register Files regmap. |
---|
223 | 221 | * @base: the base address of APB interface. |
---|
224 | | - * @apb_reset: apb reset signal for phy. |
---|
225 | 222 | * @reset: power reset signal for phy. |
---|
226 | 223 | * @clks: array of input clocks. |
---|
227 | 224 | * @num_clks: number of input clocks. |
---|
.. | .. |
---|
240 | 237 | struct device *dev; |
---|
241 | 238 | struct regmap *grf; |
---|
242 | 239 | void __iomem *base; |
---|
243 | | - struct reset_control *apb_reset; |
---|
244 | 240 | struct reset_control *reset; |
---|
245 | 241 | struct clk_bulk_data *clks; |
---|
246 | 242 | int num_clks; |
---|
.. | .. |
---|
358 | 354 | /* optional override of the clockname */ |
---|
359 | 355 | of_property_read_string(node, "clock-output-names", &init.name); |
---|
360 | 356 | |
---|
361 | | - if (refclk) { |
---|
| 357 | + if (!IS_ERR(refclk)) { |
---|
362 | 358 | clk_name = __clk_get_name(refclk); |
---|
363 | 359 | init.parent_names = &clk_name; |
---|
364 | 360 | init.num_parents = 1; |
---|
.. | .. |
---|
663 | 659 | return ret; |
---|
664 | 660 | } |
---|
665 | 661 | |
---|
666 | | -static int rockchip_usb2phy_set_mode(struct phy *phy, enum phy_mode mode) |
---|
| 662 | +static int rockchip_usb2phy_set_mode(struct phy *phy, |
---|
| 663 | + enum phy_mode mode, int submode) |
---|
667 | 664 | { |
---|
668 | 665 | struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); |
---|
669 | 666 | struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); |
---|
.. | .. |
---|
800 | 797 | struct rockchip_usb2phy_port *rport) |
---|
801 | 798 | { |
---|
802 | 799 | bool chg_valid, phy_connect; |
---|
803 | | - const struct usb2phy_reg *phy_sus_reg; |
---|
804 | | - unsigned int phy_sus_cfg, mask; |
---|
805 | | - int result, cnt, ret; |
---|
| 800 | + int result; |
---|
| 801 | + int cnt; |
---|
806 | 802 | |
---|
807 | 803 | mutex_lock(&rport->mutex); |
---|
808 | 804 | |
---|
809 | | - /* |
---|
810 | | - * We are violating what the phy specification says about |
---|
811 | | - * the charge detection process. Ideally we need to hold |
---|
812 | | - * the phy in the reset state during the charge detection |
---|
813 | | - * process, but that's causing trouble synchronizing between |
---|
814 | | - * the phy and usb controller because CLK60_30 is disabled |
---|
815 | | - * while phy in reset. |
---|
816 | | - * |
---|
817 | | - * We have discussed this with the phy IP Provider, and |
---|
818 | | - * it was suggested to keep the CLK60_30 while do charging |
---|
819 | | - * detection. |
---|
820 | | - * |
---|
821 | | - * Set the phy in charge mode (keep the CLK60_30): |
---|
822 | | - * Enable the DP/DM pulldown resistor; |
---|
823 | | - * Set the opmode to non-driving mode; |
---|
824 | | - * Set the phy controlled by GRF utmi interface, and set |
---|
825 | | - * the utmi in normal mode to keep the CLK60_30. |
---|
826 | | - */ |
---|
827 | | - phy_sus_reg = &rport->port_cfg->phy_sus; |
---|
828 | | - ret = regmap_read(rphy->grf, phy_sus_reg->offset, &phy_sus_cfg); |
---|
829 | | - if (ret) { |
---|
830 | | - dev_err(&rport->phy->dev, |
---|
831 | | - "Fail to read phy_sus reg offset 0x%x, ret %d\n", |
---|
832 | | - phy_sus_reg->offset, ret); |
---|
833 | | - goto unlock; |
---|
834 | | - } |
---|
835 | | - |
---|
836 | | - ret = property_enable(rphy->grf, &rport->port_cfg->phy_chg_mode, true); |
---|
837 | | - if (ret) { |
---|
838 | | - dev_err(&rport->phy->dev, |
---|
839 | | - "Fail to set phy_chg_mode reg, ret %d\n", ret); |
---|
840 | | - goto unlock; |
---|
841 | | - } |
---|
| 805 | + reset_control_assert(rphy->reset); |
---|
842 | 806 | |
---|
843 | 807 | /* CHG_RST is set to 1'b0 to start charge detection */ |
---|
844 | 808 | property_enable(rphy->grf, &rphy->phy_cfg->chg_det.chg_en, true); |
---|
.. | .. |
---|
878 | 842 | dev_info(&rport->phy->dev, "charger = %s\n", |
---|
879 | 843 | chg_to_string(rphy->chg_type)); |
---|
880 | 844 | |
---|
| 845 | + usleep_range(1000, 1100); |
---|
| 846 | + reset_control_deassert(rphy->reset); |
---|
| 847 | + /* waiting for the utmi_clk to become stable */ |
---|
| 848 | + usleep_range(2500, 3000); |
---|
| 849 | + |
---|
881 | 850 | /* disable the chg detection module */ |
---|
882 | 851 | property_enable(rphy->grf, &rphy->phy_cfg->chg_det.chg_rst, true); |
---|
883 | 852 | property_enable(rphy->grf, &rphy->phy_cfg->chg_det.chg_en, false); |
---|
884 | 853 | |
---|
885 | | - mask = GENMASK(phy_sus_reg->bitend, phy_sus_reg->bitstart); |
---|
886 | | - /* Restore the phy suspend configuration */ |
---|
887 | | - ret = regmap_write(rphy->grf, phy_sus_reg->offset, |
---|
888 | | - ((phy_sus_cfg << phy_sus_reg->bitstart) | |
---|
889 | | - (mask << BIT_WRITEABLE_SHIFT))); |
---|
890 | | - if (ret) |
---|
891 | | - dev_err(&rport->phy->dev, |
---|
892 | | - "Fail to set phy_sus reg offset 0x%x, ret %d\n", |
---|
893 | | - phy_sus_reg->offset, ret); |
---|
894 | | - |
---|
895 | | -unlock: |
---|
896 | 854 | mutex_unlock(&rport->mutex); |
---|
897 | 855 | } |
---|
898 | 856 | |
---|
.. | .. |
---|
1120 | 1078 | extcon_set_state(rphy->edev, EXTCON_USB_HOST, true); |
---|
1121 | 1079 | extcon_sync(rphy->edev, EXTCON_USB); |
---|
1122 | 1080 | extcon_sync(rphy->edev, EXTCON_USB_HOST); |
---|
1123 | | - rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST); |
---|
| 1081 | + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST, 0); |
---|
1124 | 1082 | property_enable(rphy->grf, &rport->port_cfg->idpullup, |
---|
1125 | 1083 | false); |
---|
1126 | 1084 | property_enable(rphy->grf, &rport->port_cfg->iddig_output, |
---|
.. | .. |
---|
1129 | 1087 | true); |
---|
1130 | 1088 | break; |
---|
1131 | 1089 | case USB_DR_MODE_PERIPHERAL: |
---|
1132 | | - rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_DEVICE); |
---|
| 1090 | + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_DEVICE, 0); |
---|
1133 | 1091 | property_enable(rphy->grf, &rport->port_cfg->idpullup, |
---|
1134 | 1092 | true); |
---|
1135 | 1093 | property_enable(rphy->grf, &rport->port_cfg->iddig_output, |
---|
.. | .. |
---|
1138 | 1096 | true); |
---|
1139 | 1097 | break; |
---|
1140 | 1098 | case USB_DR_MODE_OTG: |
---|
1141 | | - rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_OTG); |
---|
| 1099 | + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_OTG, 0); |
---|
1142 | 1100 | property_enable(rphy->grf, &rport->port_cfg->iddig_output, |
---|
1143 | 1101 | false); |
---|
1144 | 1102 | property_enable(rphy->grf, &rport->port_cfg->iddig_en, |
---|
.. | .. |
---|
1309 | 1267 | extcon_set_state(rphy->edev, EXTCON_USB, false); |
---|
1310 | 1268 | extcon_set_state(rphy->edev, EXTCON_USB_HOST, true); |
---|
1311 | 1269 | } |
---|
1312 | | - rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST); |
---|
| 1270 | + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST, 0); |
---|
1313 | 1271 | /* |
---|
1314 | 1272 | * Here set iddig to 0 by disable idpullup, the otg_suspendm |
---|
1315 | 1273 | * will be set to 1 to enable the disconnect detection module, |
---|
.. | .. |
---|
1509 | 1467 | if (IS_ERR(rphy->reset)) |
---|
1510 | 1468 | return PTR_ERR(rphy->reset); |
---|
1511 | 1469 | |
---|
1512 | | - rphy->apb_reset = devm_reset_control_get(dev, "u2phy-apb"); |
---|
1513 | | - if (IS_ERR(rphy->apb_reset)) |
---|
1514 | | - return PTR_ERR(rphy->apb_reset); |
---|
1515 | | - |
---|
1516 | 1470 | rphy->vup_gpio = devm_gpiod_get_optional(dev, "vup", GPIOD_OUT_LOW); |
---|
1517 | 1471 | if (IS_ERR(rphy->vup_gpio)) { |
---|
1518 | 1472 | ret = PTR_ERR(rphy->vup_gpio); |
---|
.. | .. |
---|
1520 | 1474 | return ret; |
---|
1521 | 1475 | } |
---|
1522 | 1476 | |
---|
1523 | | - reset_control_assert(rphy->apb_reset); |
---|
1524 | 1477 | reset_control_assert(rphy->reset); |
---|
1525 | 1478 | udelay(1); |
---|
1526 | 1479 | reset_control_deassert(rphy->reset); |
---|
1527 | | - reset_control_deassert(rphy->apb_reset); |
---|
1528 | 1480 | |
---|
1529 | 1481 | match = of_match_device(dev->driver->of_match_table, dev); |
---|
1530 | 1482 | if (!match || !match->data) { |
---|
.. | .. |
---|
1914 | 1866 | .ls_det_en = { 0x10300, 0, 0, 0, 1 }, |
---|
1915 | 1867 | .ls_det_st = { 0x10304, 0, 0, 0, 1 }, |
---|
1916 | 1868 | .ls_det_clr = { 0x10308, 0, 0, 0, 1 }, |
---|
1917 | | - .phy_chg_mode = { 0x10230, 8, 0, 0x052, 0x1d7 }, |
---|
1918 | 1869 | .phy_sus = { 0x10230, 8, 0, 0x052, 0x1d5 }, |
---|
1919 | 1870 | .utmi_bvalid = { 0x10248, 9, 9, 0, 1 }, |
---|
1920 | 1871 | .utmi_iddig = { 0x10248, 6, 6, 0, 1 }, |
---|