.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Rockchip USB2.0 PHY with Innosilicon IP block driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify |
---|
7 | | - * it under the terms of the GNU General Public License as published by |
---|
8 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
9 | | - * (at your option) any later version. |
---|
10 | | - * |
---|
11 | | - * This program is distributed in the hope that it will be useful, |
---|
12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | | - * GNU General Public License for more details. |
---|
15 | 6 | */ |
---|
16 | 7 | |
---|
17 | 8 | #include <linux/clk.h> |
---|
.. | .. |
---|
34 | 25 | #include <linux/pm_runtime.h> |
---|
35 | 26 | #include <linux/power_supply.h> |
---|
36 | 27 | #include <linux/regmap.h> |
---|
| 28 | +#include <linux/reset.h> |
---|
37 | 29 | #include <linux/rockchip/cpu.h> |
---|
38 | 30 | #include <linux/mfd/syscon.h> |
---|
39 | 31 | #include <linux/usb/of.h> |
---|
40 | 32 | #include <linux/usb/otg.h> |
---|
| 33 | +#include <linux/usb/role.h> |
---|
| 34 | +#include <linux/usb/typec_mux.h> |
---|
41 | 35 | #include <linux/wakelock.h> |
---|
42 | 36 | |
---|
43 | 37 | #define BIT_WRITEABLE_SHIFT 16 |
---|
.. | .. |
---|
63 | 57 | }; |
---|
64 | 58 | |
---|
65 | 59 | /** |
---|
66 | | - * Different states involved in USB charger detection. |
---|
67 | | - * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection |
---|
| 60 | + * enum usb_chg_state - Different states involved in USB charger detection. |
---|
| 61 | + * @USB_CHG_STATE_UNDEFINED: USB charger is not connected or detection |
---|
68 | 62 | * process is not yet started. |
---|
69 | | - * USB_CHG_STATE_WAIT_FOR_DCD Waiting for Data pins contact. |
---|
70 | | - * USB_CHG_STATE_DCD_DONE Data pin contact is detected. |
---|
71 | | - * USB_CHG_STATE_PRIMARY_DONE Primary detection is completed (Detects |
---|
| 63 | + * @USB_CHG_STATE_WAIT_FOR_DCD: Waiting for Data pins contact. |
---|
| 64 | + * @USB_CHG_STATE_DCD_DONE: Data pin contact is detected. |
---|
| 65 | + * @USB_CHG_STATE_PRIMARY_DONE: Primary detection is completed (Detects |
---|
72 | 66 | * between SDP and DCP/CDP). |
---|
73 | | - * USB_CHG_STATE_SECONDARY_DONE Secondary detection is completed (Detects |
---|
74 | | - * between DCP and CDP). |
---|
75 | | - * USB_CHG_STATE_DETECTED USB charger type is determined. |
---|
| 67 | + * @USB_CHG_STATE_SECONDARY_DONE: Secondary detection is completed (Detects |
---|
| 68 | + * between DCP and CDP). |
---|
| 69 | + * @USB_CHG_STATE_DETECTED: USB charger type is determined. |
---|
76 | 70 | */ |
---|
77 | 71 | enum usb_chg_state { |
---|
78 | 72 | USB_CHG_STATE_UNDEFINED = 0, |
---|
.. | .. |
---|
103 | 97 | }; |
---|
104 | 98 | |
---|
105 | 99 | /** |
---|
106 | | - * struct rockchip_chg_det_reg: usb charger detect registers |
---|
| 100 | + * struct rockchip_chg_det_reg - usb charger detect registers |
---|
107 | 101 | * @cp_det: charging port detected successfully. |
---|
108 | 102 | * @dcp_det: dedicated charging port detected successfully. |
---|
109 | 103 | * @dp_det: assert data pin connect successfully. |
---|
.. | .. |
---|
129 | 123 | }; |
---|
130 | 124 | |
---|
131 | 125 | /** |
---|
132 | | - * struct rockchip_usb2phy_port_cfg: usb-phy port configuration. |
---|
| 126 | + * struct rockchip_usb2phy_port_cfg - usb-phy port configuration. |
---|
133 | 127 | * @phy_sus: phy suspend register. |
---|
| 128 | + * @pipe_phystatus: select pipe phystatus from grf or phy. |
---|
134 | 129 | * @bvalid_det_en: vbus valid rise detection enable register. |
---|
135 | 130 | * @bvalid_det_st: vbus valid rise detection status register. |
---|
136 | 131 | * @bvalid_det_clr: vbus valid rise detection clear register. |
---|
137 | | - * @bvalid_set: bvalid select and set to usb controller. |
---|
| 132 | + * @bvalid_grf_con: vbus valid software control. |
---|
| 133 | + * @bvalid_grf_sel: vbus valid software control select. |
---|
| 134 | + * @bvalid_phy_con: vbus valid external select and enable. |
---|
138 | 135 | * @bypass_dm_en: usb bypass uart DM enable register. |
---|
139 | 136 | * @bypass_sel: usb bypass uart select register. |
---|
140 | 137 | * @bypass_iomux: usb bypass uart GRF iomux register. |
---|
141 | 138 | * @bypass_bc: bypass battery charging module. |
---|
142 | 139 | * @bypass_otg: bypass otg module. |
---|
143 | 140 | * @bypass_host: bypass host module. |
---|
| 141 | + * @disfall_en: host disconnect fall edge detection enable. |
---|
| 142 | + * @disfall_st: host disconnect fall edge detection state. |
---|
| 143 | + * @disfall_clr: host disconnect fall edge detection clear. |
---|
| 144 | + * @disrise_en: host disconnect rise edge detection enable. |
---|
| 145 | + * @disrise_st: host disconnect rise edge detection state. |
---|
| 146 | + * @disrise_clr: host disconnect rise edge detection clear. |
---|
144 | 147 | * @ls_det_en: linestate detection enable register. |
---|
145 | 148 | * @ls_det_st: linestate detection state register. |
---|
146 | 149 | * @ls_det_clr: linestate detection clear register. |
---|
.. | .. |
---|
163 | 166 | */ |
---|
164 | 167 | struct rockchip_usb2phy_port_cfg { |
---|
165 | 168 | struct usb2phy_reg phy_sus; |
---|
| 169 | + struct usb2phy_reg pipe_phystatus; |
---|
166 | 170 | struct usb2phy_reg bvalid_det_en; |
---|
167 | 171 | struct usb2phy_reg bvalid_det_st; |
---|
168 | 172 | struct usb2phy_reg bvalid_det_clr; |
---|
169 | | - struct usb2phy_reg bvalid_set; |
---|
| 173 | + struct usb2phy_reg bvalid_grf_con; |
---|
| 174 | + struct usb2phy_reg bvalid_grf_sel; |
---|
| 175 | + struct usb2phy_reg bvalid_phy_con; |
---|
170 | 176 | struct usb2phy_reg bypass_dm_en; |
---|
171 | 177 | struct usb2phy_reg bypass_sel; |
---|
172 | 178 | struct usb2phy_reg bypass_iomux; |
---|
173 | 179 | struct usb2phy_reg bypass_bc; |
---|
174 | 180 | struct usb2phy_reg bypass_otg; |
---|
175 | 181 | struct usb2phy_reg bypass_host; |
---|
| 182 | + struct usb2phy_reg disfall_en; |
---|
| 183 | + struct usb2phy_reg disfall_st; |
---|
| 184 | + struct usb2phy_reg disfall_clr; |
---|
| 185 | + struct usb2phy_reg disrise_en; |
---|
| 186 | + struct usb2phy_reg disrise_st; |
---|
| 187 | + struct usb2phy_reg disrise_clr; |
---|
176 | 188 | struct usb2phy_reg ls_det_en; |
---|
177 | 189 | struct usb2phy_reg ls_det_st; |
---|
178 | 190 | struct usb2phy_reg ls_det_clr; |
---|
.. | .. |
---|
194 | 206 | }; |
---|
195 | 207 | |
---|
196 | 208 | /** |
---|
197 | | - * struct rockchip_usb2phy_cfg: usb-phy configuration. |
---|
| 209 | + * struct rockchip_usb2phy_cfg - usb-phy configuration. |
---|
198 | 210 | * @reg: the address offset of grf for usb-phy config. |
---|
199 | 211 | * @num_ports: specify how many ports that the phy has. |
---|
200 | | - * @phy_tuning: phy default parameters tunning. |
---|
| 212 | + * @phy_tuning: phy default parameters tuning. |
---|
201 | 213 | * @vbus_detect: vbus voltage level detection function. |
---|
202 | 214 | * @clkout_ctl: keep on/turn off output clk of phy via commonon bit. |
---|
203 | 215 | * @clkout_ctl_phy: keep on/turn off output clk of phy via phy inner |
---|
204 | 216 | * debug register. |
---|
| 217 | + * @ls_filter_con: set linestate filter time. |
---|
| 218 | + * @port_cfgs: usb-phy port configurations. |
---|
205 | 219 | * @ls_filter_con: set linestate filter time. |
---|
206 | 220 | * @chg_det: charger detection registers. |
---|
207 | 221 | */ |
---|
208 | 222 | struct rockchip_usb2phy_cfg { |
---|
209 | 223 | unsigned int reg; |
---|
210 | 224 | unsigned int num_ports; |
---|
211 | | - int (*phy_tuning)(struct rockchip_usb2phy *); |
---|
| 225 | + int (*phy_tuning)(struct rockchip_usb2phy *rphy); |
---|
212 | 226 | int (*vbus_detect)(struct rockchip_usb2phy *rphy, |
---|
213 | 227 | const struct usb2phy_reg *vbus_det_en, |
---|
214 | 228 | bool en); |
---|
.. | .. |
---|
220 | 234 | }; |
---|
221 | 235 | |
---|
222 | 236 | /** |
---|
223 | | - * struct rockchip_usb2phy_port: usb-phy port data. |
---|
| 237 | + * struct rockchip_usb2phy_port - usb-phy port data. |
---|
| 238 | + * @phy: generic phy. |
---|
224 | 239 | * @port_id: flag for otg port or host port. |
---|
225 | 240 | * @low_power_en: enable enter low power when suspend. |
---|
226 | 241 | * @perip_connected: flag for periphyeral connect status. |
---|
227 | 242 | * @prev_iddig: previous otg port id pin status. |
---|
| 243 | + * @sel_pipe_phystatus: select pipe phystatus from grf. |
---|
228 | 244 | * @suspended: phy suspended flag. |
---|
| 245 | + * @typec_vbus_det: Type-C otg vbus detect. |
---|
229 | 246 | * @utmi_avalid: utmi avalid status usage flag. |
---|
230 | 247 | * true - use avalid to get vbus status |
---|
231 | | - * flase - use bvalid to get vbus status |
---|
| 248 | + * false - use bvalid to get vbus status |
---|
232 | 249 | * @vbus_attached: otg device vbus status. |
---|
233 | 250 | * @vbus_always_on: otg vbus is always powered on. |
---|
234 | 251 | * @vbus_enabled: vbus regulator status. |
---|
235 | 252 | * @bypass_uart_en: usb bypass uart enable, passed from DT. |
---|
| 253 | + * @host_disconnect: usb host disconnect status. |
---|
| 254 | + * @dis_u2_susphy: disable usb2 phy suspend. |
---|
236 | 255 | * @bvalid_irq: IRQ number assigned for vbus valid rise detection. |
---|
237 | 256 | * @ls_irq: IRQ number assigned for linestate detection. |
---|
238 | 257 | * @id_irq: IRQ number assigned for id fall or rise detection. |
---|
.. | .. |
---|
244 | 263 | * @otg_sm_work: OTG state machine work. |
---|
245 | 264 | * @sm_work: HOST state machine work. |
---|
246 | 265 | * @vbus: vbus regulator supply on few rockchip boards. |
---|
247 | | - * @phy_cfg: port register configuration, assigned by driver data. |
---|
| 266 | + * @sw: orientation switch, communicate with TCPM (Type-C Port Manager). |
---|
| 267 | + * @port_cfg: port register configuration, assigned by driver data. |
---|
248 | 268 | * @event_nb: hold event notification callback. |
---|
249 | 269 | * @state: define OTG enumeration states before device reset. |
---|
250 | 270 | * @mode: the dr_mode of the controller. |
---|
.. | .. |
---|
255 | 275 | bool low_power_en; |
---|
256 | 276 | bool perip_connected; |
---|
257 | 277 | bool prev_iddig; |
---|
| 278 | + bool sel_pipe_phystatus; |
---|
258 | 279 | bool suspended; |
---|
| 280 | + bool typec_vbus_det; |
---|
259 | 281 | bool utmi_avalid; |
---|
260 | 282 | bool vbus_attached; |
---|
261 | 283 | bool vbus_always_on; |
---|
262 | 284 | bool vbus_enabled; |
---|
263 | 285 | bool bypass_uart_en; |
---|
| 286 | + bool host_disconnect; |
---|
264 | 287 | bool dis_u2_susphy; |
---|
265 | 288 | int bvalid_irq; |
---|
266 | 289 | int ls_irq; |
---|
.. | .. |
---|
272 | 295 | struct delayed_work otg_sm_work; |
---|
273 | 296 | struct delayed_work sm_work; |
---|
274 | 297 | struct regulator *vbus; |
---|
| 298 | + struct typec_switch *sw; |
---|
275 | 299 | const struct rockchip_usb2phy_port_cfg *port_cfg; |
---|
276 | 300 | struct notifier_block event_nb; |
---|
277 | 301 | struct wake_lock wakelock; |
---|
.. | .. |
---|
280 | 304 | }; |
---|
281 | 305 | |
---|
282 | 306 | /** |
---|
283 | | - * struct rockchip_usb2phy: usb2.0 phy driver data. |
---|
| 307 | + * struct rockchip_usb2phy - usb2.0 phy driver data. |
---|
| 308 | + * @dev: pointer to device. |
---|
284 | 309 | * @grf: General Register Files regmap. |
---|
285 | 310 | * @usbgrf: USB General Register Files regmap. |
---|
| 311 | + * @usbctrl_grf: USB Controller General Register Files regmap. |
---|
286 | 312 | * *phy_base: the base address of USB PHY. |
---|
| 313 | + * @phy_reset: phy reset control. |
---|
287 | 314 | * @clks: array of phy input clocks. |
---|
288 | 315 | * @clk480m: clock struct of phy output clk. |
---|
289 | | - * @clk_hw: clock struct of phy output clk management. |
---|
| 316 | + * @clk480m_hw: clock struct of phy output clk management. |
---|
290 | 317 | * @num_clks: number of phy input clocks. |
---|
291 | 318 | * @chg_state: states involved in USB charger detection. |
---|
292 | 319 | * @chg_type: USB charger types. |
---|
.. | .. |
---|
306 | 333 | struct device *dev; |
---|
307 | 334 | struct regmap *grf; |
---|
308 | 335 | struct regmap *usbgrf; |
---|
| 336 | + struct regmap *usbctrl_grf; |
---|
309 | 337 | void __iomem *phy_base; |
---|
| 338 | + struct reset_control *phy_reset; |
---|
310 | 339 | struct clk_bulk_data *clks; |
---|
311 | 340 | struct clk *clk480m; |
---|
312 | 341 | struct clk_hw clk480m_hw; |
---|
.. | .. |
---|
376 | 405 | orig = readl(base + reg->offset); |
---|
377 | 406 | tmp = (orig & mask) >> reg->bitstart; |
---|
378 | 407 | return tmp == reg->enable; |
---|
| 408 | +} |
---|
| 409 | + |
---|
| 410 | +static inline void phy_clear_bits(void __iomem *reg, u32 bits) |
---|
| 411 | +{ |
---|
| 412 | + u32 tmp = readl(reg); |
---|
| 413 | + |
---|
| 414 | + tmp &= ~bits; |
---|
| 415 | + writel(tmp, reg); |
---|
| 416 | +} |
---|
| 417 | + |
---|
| 418 | +static inline void phy_set_bits(void __iomem *reg, u32 bits) |
---|
| 419 | +{ |
---|
| 420 | + u32 tmp = readl(reg); |
---|
| 421 | + |
---|
| 422 | + tmp |= bits; |
---|
| 423 | + writel(tmp, reg); |
---|
| 424 | +} |
---|
| 425 | + |
---|
| 426 | +static inline void phy_update_bits(void __iomem *reg, u32 mask, u32 val) |
---|
| 427 | +{ |
---|
| 428 | + u32 tmp = readl(reg); |
---|
| 429 | + |
---|
| 430 | + tmp &= ~mask; |
---|
| 431 | + tmp |= val & mask; |
---|
| 432 | + writel(tmp, reg); |
---|
| 433 | +} |
---|
| 434 | + |
---|
| 435 | +static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy) |
---|
| 436 | +{ |
---|
| 437 | + int ret; |
---|
| 438 | + |
---|
| 439 | + if (!rphy->phy_reset) |
---|
| 440 | + return 0; |
---|
| 441 | + |
---|
| 442 | + ret = reset_control_assert(rphy->phy_reset); |
---|
| 443 | + if (ret) |
---|
| 444 | + return ret; |
---|
| 445 | + |
---|
| 446 | + udelay(10); |
---|
| 447 | + |
---|
| 448 | + ret = reset_control_deassert(rphy->phy_reset); |
---|
| 449 | + if (ret) |
---|
| 450 | + return ret; |
---|
| 451 | + |
---|
| 452 | + usleep_range(100, 200); |
---|
| 453 | + |
---|
| 454 | + return 0; |
---|
379 | 455 | } |
---|
380 | 456 | |
---|
381 | 457 | static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) |
---|
.. | .. |
---|
595 | 671 | return ret; |
---|
596 | 672 | } |
---|
597 | 673 | |
---|
| 674 | +static int rockchip_usb2phy_enable_host_disc_irq(struct rockchip_usb2phy *rphy, |
---|
| 675 | + struct rockchip_usb2phy_port *rport, |
---|
| 676 | + bool en) |
---|
| 677 | +{ |
---|
| 678 | + int ret; |
---|
| 679 | + |
---|
| 680 | + ret = property_enable(rphy->grf, &rport->port_cfg->disfall_clr, true); |
---|
| 681 | + if (ret) |
---|
| 682 | + goto out; |
---|
| 683 | + |
---|
| 684 | + ret = property_enable(rphy->grf, &rport->port_cfg->disfall_en, en); |
---|
| 685 | + if (ret) |
---|
| 686 | + goto out; |
---|
| 687 | + |
---|
| 688 | + ret = property_enable(rphy->grf, &rport->port_cfg->disrise_clr, true); |
---|
| 689 | + if (ret) |
---|
| 690 | + goto out; |
---|
| 691 | + |
---|
| 692 | + ret = property_enable(rphy->grf, &rport->port_cfg->disrise_en, en); |
---|
| 693 | +out: |
---|
| 694 | + return ret; |
---|
| 695 | +} |
---|
| 696 | + |
---|
598 | 697 | static int rockchip_usb_bypass_uart(struct rockchip_usb2phy_port *rport, |
---|
599 | 698 | bool en) |
---|
600 | 699 | { |
---|
.. | .. |
---|
693 | 792 | struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); |
---|
694 | 793 | struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); |
---|
695 | 794 | int ret = 0; |
---|
| 795 | + unsigned int ul, ul_mask; |
---|
696 | 796 | |
---|
697 | 797 | mutex_lock(&rport->mutex); |
---|
| 798 | + |
---|
| 799 | + if (rport->sel_pipe_phystatus) |
---|
| 800 | + property_enable(rphy->usbctrl_grf, |
---|
| 801 | + &rport->port_cfg->pipe_phystatus, true); |
---|
698 | 802 | |
---|
699 | 803 | if (rport->port_id == USB2PHY_PORT_OTG && |
---|
700 | 804 | (rport->mode == USB_DR_MODE_PERIPHERAL || |
---|
.. | .. |
---|
721 | 825 | "failed to enable bvalid irq\n"); |
---|
722 | 826 | goto out; |
---|
723 | 827 | } |
---|
724 | | - |
---|
725 | 828 | schedule_delayed_work(&rport->otg_sm_work, |
---|
726 | | - OTG_SCHEDULE_DELAY); |
---|
| 829 | + rport->typec_vbus_det ? 0 : OTG_SCHEDULE_DELAY); |
---|
727 | 830 | } |
---|
728 | 831 | } else if (rport->port_id == USB2PHY_PORT_HOST) { |
---|
| 832 | + if (rport->port_cfg->disfall_en.offset) { |
---|
| 833 | + ret = regmap_read(rphy->grf, rport->port_cfg->utmi_ls.offset, &ul); |
---|
| 834 | + if (ret < 0) |
---|
| 835 | + goto out; |
---|
| 836 | + ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend, |
---|
| 837 | + rport->port_cfg->utmi_ls.bitstart); |
---|
| 838 | + rport->host_disconnect = (ul & ul_mask) == 0 ? true : false; |
---|
| 839 | + ret = rockchip_usb2phy_enable_host_disc_irq(rphy, rport, true); |
---|
| 840 | + if (ret) { |
---|
| 841 | + dev_err(rphy->dev, "failed to enable disconnect irq\n"); |
---|
| 842 | + goto out; |
---|
| 843 | + } |
---|
| 844 | + } |
---|
| 845 | + |
---|
729 | 846 | /* clear linestate and enable linestate detect irq */ |
---|
730 | 847 | ret = rockchip_usb2phy_enable_line_irq(rphy, rport, true); |
---|
731 | 848 | if (ret) { |
---|
.. | .. |
---|
773 | 890 | ret = property_enable(base, &rport->port_cfg->phy_sus, false); |
---|
774 | 891 | if (ret) |
---|
775 | 892 | goto unlock; |
---|
| 893 | + |
---|
| 894 | + /* |
---|
| 895 | + * For rk3588, it needs to reset phy when exit from |
---|
| 896 | + * suspend mode with common_on_n 1'b1(aka REFCLK_LOGIC, |
---|
| 897 | + * Bias, and PLL blocks are powered down) for lower |
---|
| 898 | + * power consumption. If you don't want to reset phy, |
---|
| 899 | + * please keep the common_on_n 1'b0 to set these blocks |
---|
| 900 | + * remain powered. |
---|
| 901 | + */ |
---|
| 902 | + if (rport->port_id == USB2PHY_PORT_OTG && |
---|
| 903 | + of_device_is_compatible(rphy->dev->of_node, "rockchip,rk3588-usb2phy")) { |
---|
| 904 | + ret = rockchip_usb2phy_reset(rphy); |
---|
| 905 | + if (ret) |
---|
| 906 | + goto unlock; |
---|
| 907 | + } |
---|
776 | 908 | |
---|
777 | 909 | /* waiting for the utmi_clk to become stable */ |
---|
778 | 910 | usleep_range(1500, 2000); |
---|
.. | .. |
---|
830 | 962 | if (rport->port_id == USB2PHY_PORT_HOST) |
---|
831 | 963 | cancel_delayed_work_sync(&rport->sm_work); |
---|
832 | 964 | else if (rport->port_id == USB2PHY_PORT_OTG && |
---|
833 | | - rport->bvalid_irq > 0) |
---|
| 965 | + rport->otg_sm_work.work.func) |
---|
834 | 966 | flush_delayed_work(&rport->otg_sm_work); |
---|
835 | 967 | |
---|
836 | 968 | return 0; |
---|
.. | .. |
---|
859 | 991 | return ret; |
---|
860 | 992 | } |
---|
861 | 993 | |
---|
862 | | -static int rockchip_usb2phy_set_mode(struct phy *phy, enum phy_mode mode) |
---|
| 994 | +static int rockchip_usb2phy_set_mode(struct phy *phy, |
---|
| 995 | + enum phy_mode mode, int submode) |
---|
863 | 996 | { |
---|
864 | 997 | struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy); |
---|
865 | 998 | struct rockchip_usb2phy *rphy = dev_get_drvdata(phy->dev.parent); |
---|
.. | .. |
---|
871 | 1004 | |
---|
872 | 1005 | switch (mode) { |
---|
873 | 1006 | case PHY_MODE_USB_OTG: |
---|
| 1007 | + if (rphy->edev_self && submode) { |
---|
| 1008 | + if (submode == USB_ROLE_HOST) { |
---|
| 1009 | + extcon_set_state(rphy->edev, EXTCON_USB_HOST, true); |
---|
| 1010 | + extcon_set_state(rphy->edev, EXTCON_USB, false); |
---|
| 1011 | + } else if (submode == USB_ROLE_DEVICE) { |
---|
| 1012 | + extcon_set_state(rphy->edev, EXTCON_USB_HOST, false); |
---|
| 1013 | + extcon_set_state(rphy->edev, EXTCON_USB, true); |
---|
| 1014 | + } |
---|
| 1015 | + |
---|
| 1016 | + return ret; |
---|
| 1017 | + } |
---|
| 1018 | + |
---|
874 | 1019 | /* |
---|
875 | 1020 | * In case of using vbus to detect connect state by u2phy, |
---|
876 | 1021 | * enable vbus detect on otg mode. |
---|
877 | | - * |
---|
878 | | - * fallthrough |
---|
879 | 1022 | */ |
---|
| 1023 | + fallthrough; |
---|
880 | 1024 | case PHY_MODE_USB_DEVICE: |
---|
881 | 1025 | /* Disable VBUS supply */ |
---|
882 | 1026 | rockchip_set_vbus_power(rport, false); |
---|
883 | 1027 | extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, false); |
---|
| 1028 | + /* For vbus always on, set EXTCON_USB to true. */ |
---|
| 1029 | + if (rport->vbus_always_on) |
---|
| 1030 | + extcon_set_state(rphy->edev, EXTCON_USB, true); |
---|
| 1031 | + rport->perip_connected = true; |
---|
884 | 1032 | vbus_det_en = true; |
---|
885 | 1033 | break; |
---|
886 | 1034 | case PHY_MODE_USB_HOST: |
---|
.. | .. |
---|
893 | 1041 | } |
---|
894 | 1042 | |
---|
895 | 1043 | extcon_set_state_sync(rphy->edev, EXTCON_USB_VBUS_EN, true); |
---|
896 | | - /* fallthrough */ |
---|
| 1044 | + /* For vbus always on, deinit EXTCON_USB to false. */ |
---|
| 1045 | + if (rport->vbus_always_on) |
---|
| 1046 | + extcon_set_state(rphy->edev, EXTCON_USB, false); |
---|
| 1047 | + rport->perip_connected = false; |
---|
| 1048 | + fallthrough; |
---|
897 | 1049 | case PHY_MODE_INVALID: |
---|
898 | 1050 | vbus_det_en = false; |
---|
899 | 1051 | break; |
---|
.. | .. |
---|
953 | 1105 | return sprintf(buf, "otg\n"); |
---|
954 | 1106 | case USB_DR_MODE_UNKNOWN: |
---|
955 | 1107 | return sprintf(buf, "UNKNOWN\n"); |
---|
956 | | - default: |
---|
957 | | - break; |
---|
958 | 1108 | } |
---|
959 | 1109 | |
---|
960 | 1110 | return -EINVAL; |
---|
.. | .. |
---|
1011 | 1161 | |
---|
1012 | 1162 | switch (rport->mode) { |
---|
1013 | 1163 | case USB_DR_MODE_HOST: |
---|
1014 | | - rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST); |
---|
| 1164 | + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_HOST, 0); |
---|
1015 | 1165 | property_enable(base, &rport->port_cfg->iddig_output, false); |
---|
1016 | 1166 | property_enable(base, &rport->port_cfg->iddig_en, true); |
---|
1017 | 1167 | break; |
---|
1018 | 1168 | case USB_DR_MODE_PERIPHERAL: |
---|
1019 | | - rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_DEVICE); |
---|
| 1169 | + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_DEVICE, 0); |
---|
1020 | 1170 | property_enable(base, &rport->port_cfg->iddig_output, true); |
---|
1021 | 1171 | property_enable(base, &rport->port_cfg->iddig_en, true); |
---|
1022 | 1172 | break; |
---|
1023 | 1173 | case USB_DR_MODE_OTG: |
---|
1024 | | - rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_OTG); |
---|
| 1174 | + rockchip_usb2phy_set_mode(rport->phy, PHY_MODE_USB_OTG, 0); |
---|
1025 | 1175 | property_enable(base, &rport->port_cfg->iddig_output, false); |
---|
1026 | 1176 | property_enable(base, &rport->port_cfg->iddig_en, false); |
---|
1027 | 1177 | break; |
---|
.. | .. |
---|
1060 | 1210 | |
---|
1061 | 1211 | mutex_lock(&rport->mutex); |
---|
1062 | 1212 | |
---|
1063 | | - if (rport->utmi_avalid) |
---|
| 1213 | + if (rport->port_cfg->bvalid_grf_con.enable && rport->typec_vbus_det) |
---|
| 1214 | + rport->vbus_attached = |
---|
| 1215 | + property_enabled(rphy->grf, &rport->port_cfg->bvalid_grf_con); |
---|
| 1216 | + else if (rport->utmi_avalid) |
---|
1064 | 1217 | rport->vbus_attached = |
---|
1065 | 1218 | property_enabled(rphy->grf, &rport->port_cfg->utmi_avalid); |
---|
1066 | 1219 | else |
---|
.. | .. |
---|
1082 | 1235 | rockchip_usb2phy_power_off(rport->phy); |
---|
1083 | 1236 | mutex_lock(&rport->mutex); |
---|
1084 | 1237 | } |
---|
1085 | | - /* fall through */ |
---|
| 1238 | + fallthrough; |
---|
1086 | 1239 | case OTG_STATE_B_IDLE: |
---|
1087 | 1240 | if (extcon_get_state(rphy->edev, EXTCON_USB_HOST) > 0 || |
---|
1088 | | - extcon_get_state(rphy->edev, EXTCON_USB_VBUS_EN) > 0 ) { |
---|
| 1241 | + extcon_get_state(rphy->edev, EXTCON_USB_VBUS_EN) > 0) { |
---|
1089 | 1242 | dev_dbg(&rport->phy->dev, "usb otg host connect\n"); |
---|
1090 | 1243 | rport->state = OTG_STATE_A_HOST; |
---|
1091 | 1244 | rphy->chg_state = USB_CHG_STATE_UNDEFINED; |
---|
.. | .. |
---|
1139 | 1292 | } else { |
---|
1140 | 1293 | rphy->chg_state = USB_CHG_STATE_UNDEFINED; |
---|
1141 | 1294 | rphy->chg_type = POWER_SUPPLY_TYPE_UNKNOWN; |
---|
| 1295 | + rport->perip_connected = false; |
---|
1142 | 1296 | mutex_unlock(&rport->mutex); |
---|
1143 | 1297 | if (!rport->dis_u2_susphy) |
---|
1144 | 1298 | rockchip_usb2phy_power_off(rport->phy); |
---|
.. | .. |
---|
1370 | 1524 | rphy->chg_type = POWER_SUPPLY_TYPE_USB_DCP; |
---|
1371 | 1525 | else |
---|
1372 | 1526 | rphy->chg_type = POWER_SUPPLY_TYPE_USB_CDP; |
---|
1373 | | - /* fall through */ |
---|
| 1527 | + fallthrough; |
---|
1374 | 1528 | case USB_CHG_STATE_SECONDARY_DONE: |
---|
1375 | 1529 | rphy->chg_state = USB_CHG_STATE_DETECTED; |
---|
1376 | | - /* fall through */ |
---|
| 1530 | + fallthrough; |
---|
1377 | 1531 | case USB_CHG_STATE_DETECTED: |
---|
| 1532 | + if (rphy->phy_cfg->chg_det.chg_mode.offset != |
---|
| 1533 | + rport->port_cfg->phy_sus.offset) |
---|
| 1534 | + property_enable(base, &rphy->phy_cfg->chg_det.chg_mode, false); |
---|
| 1535 | + |
---|
1378 | 1536 | /* Restore the PHY suspend configuration */ |
---|
1379 | 1537 | phy_sus_reg = &rport->port_cfg->phy_sus; |
---|
1380 | 1538 | mask = GENMASK(phy_sus_reg->bitend, phy_sus_reg->bitstart); |
---|
1381 | 1539 | ret = regmap_write(base, phy_sus_reg->offset, |
---|
1382 | | - ((rphy->phy_sus_cfg << |
---|
1383 | | - phy_sus_reg->bitstart) | |
---|
1384 | | - (mask << BIT_WRITEABLE_SHIFT))); |
---|
| 1540 | + (rphy->phy_sus_cfg | (mask << BIT_WRITEABLE_SHIFT))); |
---|
1385 | 1541 | if (ret) |
---|
1386 | 1542 | dev_err(&rport->phy->dev, |
---|
1387 | 1543 | "Fail to set phy_sus reg offset 0x%x, ret %d\n", |
---|
1388 | 1544 | phy_sus_reg->offset, ret); |
---|
1389 | 1545 | mutex_unlock(&rport->mutex); |
---|
1390 | 1546 | rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); |
---|
1391 | | - dev_info(&rport->phy->dev, "charger = %s\n", |
---|
| 1547 | + dev_dbg(&rport->phy->dev, "charger = %s\n", |
---|
1392 | 1548 | chg_to_string(rphy->chg_type)); |
---|
1393 | 1549 | return; |
---|
1394 | 1550 | default: |
---|
.. | .. |
---|
1422 | 1578 | struct rockchip_usb2phy_port *rport = |
---|
1423 | 1579 | container_of(work, struct rockchip_usb2phy_port, sm_work.work); |
---|
1424 | 1580 | struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); |
---|
1425 | | - unsigned int sh = rport->port_cfg->utmi_hstdet.bitend - |
---|
1426 | | - rport->port_cfg->utmi_hstdet.bitstart + 1; |
---|
1427 | | - unsigned int ul, uhd, state; |
---|
| 1581 | + unsigned int sh, ul, uhd, state; |
---|
1428 | 1582 | unsigned int ul_mask, uhd_mask; |
---|
1429 | 1583 | int ret; |
---|
1430 | 1584 | |
---|
1431 | 1585 | if (!rport->port_cfg->utmi_ls.offset || |
---|
1432 | | - !rport->port_cfg->utmi_hstdet.offset) { |
---|
| 1586 | + (!rport->port_cfg->utmi_hstdet.offset && |
---|
| 1587 | + !rport->port_cfg->disfall_en.offset)) { |
---|
1433 | 1588 | dev_dbg(&rport->phy->dev, "some property may not be specified\n"); |
---|
1434 | 1589 | return; |
---|
1435 | 1590 | } |
---|
.. | .. |
---|
1440 | 1595 | if (ret < 0) |
---|
1441 | 1596 | goto next_schedule; |
---|
1442 | 1597 | |
---|
1443 | | - ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd); |
---|
1444 | | - if (ret < 0) |
---|
1445 | | - goto next_schedule; |
---|
1446 | | - |
---|
1447 | | - uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend, |
---|
1448 | | - rport->port_cfg->utmi_hstdet.bitstart); |
---|
1449 | 1598 | ul_mask = GENMASK(rport->port_cfg->utmi_ls.bitend, |
---|
1450 | 1599 | rport->port_cfg->utmi_ls.bitstart); |
---|
1451 | 1600 | |
---|
1452 | | - /* stitch on utmi_ls and utmi_hstdet as phy state */ |
---|
1453 | | - state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) | |
---|
1454 | | - (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh); |
---|
| 1601 | + if (rport->port_cfg->utmi_hstdet.offset) { |
---|
| 1602 | + ret = regmap_read(rphy->grf, rport->port_cfg->utmi_hstdet.offset, &uhd); |
---|
| 1603 | + if (ret < 0) |
---|
| 1604 | + goto next_schedule; |
---|
| 1605 | + |
---|
| 1606 | + uhd_mask = GENMASK(rport->port_cfg->utmi_hstdet.bitend, |
---|
| 1607 | + rport->port_cfg->utmi_hstdet.bitstart); |
---|
| 1608 | + |
---|
| 1609 | + sh = rport->port_cfg->utmi_hstdet.bitend - |
---|
| 1610 | + rport->port_cfg->utmi_hstdet.bitstart + 1; |
---|
| 1611 | + /* stitch on utmi_ls and utmi_hstdet as phy state */ |
---|
| 1612 | + state = ((uhd & uhd_mask) >> rport->port_cfg->utmi_hstdet.bitstart) | |
---|
| 1613 | + (((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << sh); |
---|
| 1614 | + } else { |
---|
| 1615 | + state = ((ul & ul_mask) >> rport->port_cfg->utmi_ls.bitstart) << 1 | |
---|
| 1616 | + rport->host_disconnect; |
---|
| 1617 | + } |
---|
1455 | 1618 | |
---|
1456 | 1619 | switch (state) { |
---|
1457 | 1620 | case PHY_STATE_HS_ONLINE: |
---|
.. | .. |
---|
1472 | 1635 | dev_dbg(&rport->phy->dev, "FS/LS online\n"); |
---|
1473 | 1636 | break; |
---|
1474 | 1637 | } |
---|
1475 | | - /* fall through */ |
---|
| 1638 | + fallthrough; |
---|
1476 | 1639 | case PHY_STATE_CONNECT: |
---|
1477 | 1640 | if (rport->suspended) { |
---|
1478 | 1641 | dev_dbg(&rport->phy->dev, "Connected\n"); |
---|
.. | .. |
---|
1516 | 1679 | mutex_unlock(&rport->mutex); |
---|
1517 | 1680 | return; |
---|
1518 | 1681 | default: |
---|
1519 | | - dev_dbg(&rport->phy->dev, "unknown phy state\n"); |
---|
| 1682 | + dev_dbg(&rport->phy->dev, "unknown phy state %d\n", state); |
---|
1520 | 1683 | break; |
---|
1521 | 1684 | } |
---|
1522 | 1685 | |
---|
.. | .. |
---|
1530 | 1693 | struct rockchip_usb2phy_port *rport = data; |
---|
1531 | 1694 | struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); |
---|
1532 | 1695 | |
---|
1533 | | - if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st)) |
---|
| 1696 | + if (!property_enabled(rphy->grf, &rport->port_cfg->ls_det_st) || |
---|
| 1697 | + !property_enabled(rphy->grf, &rport->port_cfg->ls_det_en)) |
---|
1534 | 1698 | return IRQ_NONE; |
---|
1535 | 1699 | |
---|
1536 | 1700 | dev_dbg(&rport->phy->dev, "linestate interrupt\n"); |
---|
.. | .. |
---|
1539 | 1703 | |
---|
1540 | 1704 | /* disable linestate detect irq and clear its status */ |
---|
1541 | 1705 | rockchip_usb2phy_enable_line_irq(rphy, rport, false); |
---|
| 1706 | + |
---|
| 1707 | + /* |
---|
| 1708 | + * For host port, it may miss disc irq when device is connected, |
---|
| 1709 | + * in this case, we can clear host_disconnect state depend on |
---|
| 1710 | + * the linestate irq. |
---|
| 1711 | + */ |
---|
| 1712 | + if (rport->port_id == USB2PHY_PORT_HOST && rport->port_cfg->disfall_en.offset) |
---|
| 1713 | + rport->host_disconnect = false; |
---|
1542 | 1714 | |
---|
1543 | 1715 | mutex_unlock(&rport->mutex); |
---|
1544 | 1716 | |
---|
.. | .. |
---|
1571 | 1743 | if (rport->bypass_uart_en) |
---|
1572 | 1744 | rockchip_usb_bypass_uart(rport, false); |
---|
1573 | 1745 | |
---|
1574 | | - cancel_delayed_work_sync(&rport->otg_sm_work); |
---|
1575 | | - rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); |
---|
| 1746 | + if (rport->otg_sm_work.work.func) { |
---|
| 1747 | + cancel_delayed_work_sync(&rport->otg_sm_work); |
---|
| 1748 | + rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work); |
---|
| 1749 | + } |
---|
1576 | 1750 | |
---|
1577 | 1751 | return IRQ_HANDLED; |
---|
1578 | 1752 | } |
---|
.. | .. |
---|
1593 | 1767 | if (property_enabled(rphy->grf, &rport->port_cfg->idfall_det_st)) { |
---|
1594 | 1768 | property_enable(rphy->grf, &rport->port_cfg->idfall_det_clr, |
---|
1595 | 1769 | true); |
---|
1596 | | - cable_vbus_state = true; |
---|
| 1770 | + /* switch to host if id fall det and iddig status is low */ |
---|
| 1771 | + if (!property_enabled(rphy->grf, &rport->port_cfg->utmi_iddig)) |
---|
| 1772 | + cable_vbus_state = true; |
---|
1597 | 1773 | } else if (property_enabled(rphy->grf, &rport->port_cfg->idrise_det_st)) { |
---|
1598 | 1774 | property_enable(rphy->grf, &rport->port_cfg->idrise_det_clr, |
---|
1599 | 1775 | true); |
---|
.. | .. |
---|
1607 | 1783 | extcon_sync(rphy->edev, EXTCON_USB_VBUS_EN); |
---|
1608 | 1784 | |
---|
1609 | 1785 | rockchip_set_vbus_power(rport, cable_vbus_state); |
---|
| 1786 | + |
---|
| 1787 | + mutex_unlock(&rport->mutex); |
---|
| 1788 | + |
---|
| 1789 | + return IRQ_HANDLED; |
---|
| 1790 | +} |
---|
| 1791 | + |
---|
| 1792 | +static irqreturn_t rockchip_usb2phy_host_disc_irq(int irq, void *data) |
---|
| 1793 | +{ |
---|
| 1794 | + struct rockchip_usb2phy_port *rport = data; |
---|
| 1795 | + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); |
---|
| 1796 | + |
---|
| 1797 | + if (!property_enabled(rphy->grf, &rport->port_cfg->disfall_st) && |
---|
| 1798 | + !property_enabled(rphy->grf, &rport->port_cfg->disrise_st)) |
---|
| 1799 | + return IRQ_NONE; |
---|
| 1800 | + |
---|
| 1801 | + mutex_lock(&rport->mutex); |
---|
| 1802 | + |
---|
| 1803 | + /* clear disconnect fall or rise detect irq pending status */ |
---|
| 1804 | + if (property_enabled(rphy->grf, &rport->port_cfg->disfall_st)) { |
---|
| 1805 | + property_enable(rphy->grf, &rport->port_cfg->disfall_clr, |
---|
| 1806 | + true); |
---|
| 1807 | + rport->host_disconnect = false; |
---|
| 1808 | + } else if (property_enabled(rphy->grf, &rport->port_cfg->disrise_st)) { |
---|
| 1809 | + property_enable(rphy->grf, &rport->port_cfg->disrise_clr, |
---|
| 1810 | + true); |
---|
| 1811 | + rport->host_disconnect = true; |
---|
| 1812 | + } |
---|
1610 | 1813 | |
---|
1611 | 1814 | mutex_unlock(&rport->mutex); |
---|
1612 | 1815 | |
---|
.. | .. |
---|
1637 | 1840 | if (!rport->phy) |
---|
1638 | 1841 | continue; |
---|
1639 | 1842 | |
---|
| 1843 | + /* |
---|
| 1844 | + * Handle disc irq before linestate irq to set the disc |
---|
| 1845 | + * state for sm work scheduled in the linestate irq handler. |
---|
| 1846 | + */ |
---|
| 1847 | + if (rport->port_id == USB2PHY_PORT_HOST && |
---|
| 1848 | + rport->port_cfg->disfall_en.offset) |
---|
| 1849 | + ret |= rockchip_usb2phy_host_disc_irq(irq, rport); |
---|
| 1850 | + |
---|
1640 | 1851 | /* Handle linestate irq for both otg port and host port */ |
---|
1641 | | - ret = rockchip_usb2phy_linestate_irq(irq, rport); |
---|
| 1852 | + ret |= rockchip_usb2phy_linestate_irq(irq, rport); |
---|
1642 | 1853 | |
---|
1643 | 1854 | /* |
---|
1644 | 1855 | * Handle bvalid irq and id irq for otg port which |
---|
.. | .. |
---|
1777 | 1988 | return ret; |
---|
1778 | 1989 | } |
---|
1779 | 1990 | |
---|
| 1991 | +static void rockchip_usb2phy_usb_bvalid_enable(struct rockchip_usb2phy_port *rport, |
---|
| 1992 | + u8 enable) |
---|
| 1993 | +{ |
---|
| 1994 | + struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent); |
---|
| 1995 | + const struct rockchip_usb2phy_port_cfg *cfg = rport->port_cfg; |
---|
| 1996 | + |
---|
| 1997 | + if (cfg->bvalid_phy_con.enable) |
---|
| 1998 | + property_enable(rphy->grf, &cfg->bvalid_phy_con, enable); |
---|
| 1999 | + |
---|
| 2000 | + if (cfg->bvalid_grf_con.enable) |
---|
| 2001 | + property_enable(rphy->grf, &cfg->bvalid_grf_con, enable); |
---|
| 2002 | +} |
---|
| 2003 | + |
---|
| 2004 | +static int rockchip_usb2phy_orien_sw_set(struct typec_switch *sw, |
---|
| 2005 | + enum typec_orientation orien) |
---|
| 2006 | +{ |
---|
| 2007 | + struct rockchip_usb2phy_port *rport = typec_switch_get_drvdata(sw); |
---|
| 2008 | + |
---|
| 2009 | + dev_dbg(&rport->phy->dev, "type-c orientation: %d\n", orien); |
---|
| 2010 | + |
---|
| 2011 | + mutex_lock(&rport->mutex); |
---|
| 2012 | + rockchip_usb2phy_usb_bvalid_enable(rport, orien != TYPEC_ORIENTATION_NONE); |
---|
| 2013 | + mutex_unlock(&rport->mutex); |
---|
| 2014 | + |
---|
| 2015 | + return 0; |
---|
| 2016 | +} |
---|
| 2017 | + |
---|
| 2018 | +static int |
---|
| 2019 | +rockchip_usb2phy_setup_orien_switch(struct rockchip_usb2phy *rphy, |
---|
| 2020 | + struct rockchip_usb2phy_port *rport) |
---|
| 2021 | +{ |
---|
| 2022 | + struct typec_switch_desc sw_desc = { }; |
---|
| 2023 | + struct device *dev = rphy->dev; |
---|
| 2024 | + |
---|
| 2025 | + sw_desc.drvdata = rport; |
---|
| 2026 | + sw_desc.fwnode = dev_fwnode(dev); |
---|
| 2027 | + sw_desc.set = rockchip_usb2phy_orien_sw_set; |
---|
| 2028 | + |
---|
| 2029 | + rport->sw = typec_switch_register(dev, &sw_desc); |
---|
| 2030 | + if (IS_ERR(rport->sw)) { |
---|
| 2031 | + dev_err(dev, "Error register typec orientation switch: %ld\n", |
---|
| 2032 | + PTR_ERR(rport->sw)); |
---|
| 2033 | + return PTR_ERR(rport->sw); |
---|
| 2034 | + } |
---|
| 2035 | + |
---|
| 2036 | + return 0; |
---|
| 2037 | +} |
---|
| 2038 | + |
---|
| 2039 | +static void rockchip_usb2phy_orien_switch_unregister(void *data) |
---|
| 2040 | +{ |
---|
| 2041 | + struct rockchip_usb2phy_port *rport = data; |
---|
| 2042 | + |
---|
| 2043 | + typec_switch_unregister(rport->sw); |
---|
| 2044 | +} |
---|
| 2045 | + |
---|
1780 | 2046 | static int rockchip_usb2phy_host_port_init(struct rockchip_usb2phy *rphy, |
---|
1781 | 2047 | struct rockchip_usb2phy_port *rport, |
---|
1782 | 2048 | struct device_node *child_np) |
---|
.. | .. |
---|
1861 | 2127 | rport->low_power_en = |
---|
1862 | 2128 | of_property_read_bool(child_np, "rockchip,low-power-mode"); |
---|
1863 | 2129 | |
---|
| 2130 | + /* For type-c with vbus_det always pull up */ |
---|
| 2131 | + rport->typec_vbus_det = |
---|
| 2132 | + of_property_read_bool(child_np, "rockchip,typec-vbus-det"); |
---|
| 2133 | + |
---|
| 2134 | + rport->sel_pipe_phystatus = |
---|
| 2135 | + of_property_read_bool(child_np, "rockchip,sel-pipe-phystatus"); |
---|
| 2136 | + |
---|
| 2137 | + if (rport->sel_pipe_phystatus) { |
---|
| 2138 | + rphy->usbctrl_grf = |
---|
| 2139 | + syscon_regmap_lookup_by_phandle(rphy->dev->of_node, |
---|
| 2140 | + "rockchip,usbctrl-grf"); |
---|
| 2141 | + if (IS_ERR(rphy->usbctrl_grf)) { |
---|
| 2142 | + dev_err(rphy->dev, "Failed to map usbctrl-grf\n"); |
---|
| 2143 | + return PTR_ERR(rphy->usbctrl_grf); |
---|
| 2144 | + } |
---|
| 2145 | + } |
---|
| 2146 | + |
---|
1864 | 2147 | /* Get Vbus regulators */ |
---|
1865 | 2148 | rport->vbus = devm_regulator_get_optional(&rport->phy->dev, "vbus"); |
---|
1866 | 2149 | if (IS_ERR(rport->vbus)) { |
---|
.. | .. |
---|
1868 | 2151 | if (ret == -EPROBE_DEFER) |
---|
1869 | 2152 | return ret; |
---|
1870 | 2153 | |
---|
1871 | | - dev_warn(&rport->phy->dev, "No vbus specified for otg port\n"); |
---|
| 2154 | + if (rport->mode == USB_DR_MODE_OTG) |
---|
| 2155 | + dev_warn(&rport->phy->dev, "No vbus specified for otg port\n"); |
---|
1872 | 2156 | rport->vbus = NULL; |
---|
1873 | 2157 | } |
---|
1874 | 2158 | |
---|
.. | .. |
---|
1891 | 2175 | return ret; |
---|
1892 | 2176 | } |
---|
1893 | 2177 | |
---|
| 2178 | + if (IS_REACHABLE(CONFIG_TYPEC) && |
---|
| 2179 | + device_property_present(rphy->dev, "orientation-switch")) { |
---|
| 2180 | + ret = rockchip_usb2phy_setup_orien_switch(rphy, rport); |
---|
| 2181 | + if (ret) |
---|
| 2182 | + return ret; |
---|
| 2183 | + |
---|
| 2184 | + ret = devm_add_action_or_reset(rphy->dev, |
---|
| 2185 | + rockchip_usb2phy_orien_switch_unregister, |
---|
| 2186 | + rport); |
---|
| 2187 | + if (ret) |
---|
| 2188 | + return ret; |
---|
| 2189 | + } |
---|
| 2190 | + |
---|
| 2191 | + /* |
---|
| 2192 | + * Set the utmi bvalid come from the usb phy or grf. |
---|
| 2193 | + * For most of Rockchip SoCs, them have VBUSDET pin |
---|
| 2194 | + * for the usb phy to detect the USB VBUS and set |
---|
| 2195 | + * the bvalid signal, so select the bvalid from the |
---|
| 2196 | + * usb phy by default. And for those SoCs which don't |
---|
| 2197 | + * have VBUSDET pin (e.g. RV1103), it needs to select |
---|
| 2198 | + * the bvaid from the grf and set bvalid to be valid |
---|
| 2199 | + * (high) by default. |
---|
| 2200 | + */ |
---|
| 2201 | + if (rport->port_cfg->bvalid_grf_sel.enable != 0) { |
---|
| 2202 | + if (of_machine_is_compatible("rockchip,rv1103")) |
---|
| 2203 | + property_enable(base, &rport->port_cfg->bvalid_grf_sel, true); |
---|
| 2204 | + else |
---|
| 2205 | + property_enable(base, &rport->port_cfg->bvalid_grf_sel, false); |
---|
| 2206 | + } |
---|
| 2207 | + |
---|
| 2208 | + if (rport->vbus_always_on) |
---|
| 2209 | + extcon_set_state(rphy->edev, EXTCON_USB, true); |
---|
| 2210 | + |
---|
1894 | 2211 | if (rport->vbus_always_on || rport->mode == USB_DR_MODE_HOST || |
---|
1895 | 2212 | rport->mode == USB_DR_MODE_UNKNOWN) |
---|
1896 | 2213 | goto out; |
---|
1897 | | - |
---|
1898 | | - /* Select bvalid of usb phy as bvalid of usb controller */ |
---|
1899 | | - if (rport->port_cfg->bvalid_set.enable != 0) |
---|
1900 | | - property_enable(base, &rport->port_cfg->bvalid_set, false); |
---|
1901 | 2214 | |
---|
1902 | 2215 | wake_lock_init(&rport->wakelock, WAKE_LOCK_SUSPEND, "rockchip_otg"); |
---|
1903 | 2216 | ret = devm_add_action_or_reset(rphy->dev, rockchip_otg_wake_lock_destroy, |
---|
.. | .. |
---|
2012 | 2325 | |
---|
2013 | 2326 | /* find out a proper config which can be matched with dt. */ |
---|
2014 | 2327 | index = 0; |
---|
2015 | | - while (phy_cfgs[index].reg) { |
---|
| 2328 | + do { |
---|
2016 | 2329 | if (phy_cfgs[index].reg == reg) { |
---|
2017 | 2330 | rphy->phy_cfg = &phy_cfgs[index]; |
---|
2018 | 2331 | break; |
---|
2019 | 2332 | } |
---|
2020 | 2333 | |
---|
2021 | 2334 | ++index; |
---|
2022 | | - } |
---|
| 2335 | + } while (phy_cfgs[index].reg); |
---|
2023 | 2336 | |
---|
2024 | 2337 | if (!rphy->phy_cfg) { |
---|
2025 | | - dev_err(dev, "no phy-config can be matched with %s node\n", |
---|
2026 | | - np->name); |
---|
| 2338 | + dev_err(dev, "no phy-config can be matched with %pOFn node\n", |
---|
| 2339 | + np); |
---|
2027 | 2340 | return -EINVAL; |
---|
2028 | 2341 | } |
---|
2029 | 2342 | |
---|
2030 | 2343 | pm_runtime_set_active(dev); |
---|
2031 | 2344 | pm_runtime_enable(dev); |
---|
2032 | 2345 | pm_runtime_get_sync(dev); |
---|
| 2346 | + |
---|
| 2347 | + |
---|
| 2348 | + rphy->phy_reset = devm_reset_control_get_optional(dev, "phy"); |
---|
| 2349 | + if (IS_ERR(rphy->phy_reset)) |
---|
| 2350 | + return PTR_ERR(rphy->phy_reset); |
---|
2033 | 2351 | |
---|
2034 | 2352 | ret = devm_clk_bulk_get_all(dev, &rphy->clks); |
---|
2035 | 2353 | if (ret == -EPROBE_DEFER) |
---|
.. | .. |
---|
2057 | 2375 | struct phy *phy; |
---|
2058 | 2376 | |
---|
2059 | 2377 | /* This driver aims to support both otg-port and host-port */ |
---|
2060 | | - if (of_node_cmp(child_np->name, "host-port") && |
---|
2061 | | - of_node_cmp(child_np->name, "otg-port")) |
---|
| 2378 | + if (!of_node_name_eq(child_np, "host-port") && |
---|
| 2379 | + !of_node_name_eq(child_np, "otg-port")) |
---|
2062 | 2380 | goto next_child; |
---|
2063 | 2381 | |
---|
2064 | 2382 | phy = devm_phy_create(dev, child_np, &rockchip_usb2phy_ops); |
---|
.. | .. |
---|
2072 | 2390 | phy_set_drvdata(rport->phy, rport); |
---|
2073 | 2391 | |
---|
2074 | 2392 | /* initialize otg/host port separately */ |
---|
2075 | | - if (!of_node_cmp(child_np->name, "host-port")) { |
---|
| 2393 | + if (of_node_name_eq(child_np, "host-port")) { |
---|
2076 | 2394 | ret = rockchip_usb2phy_host_port_init(rphy, rport, |
---|
2077 | 2395 | child_np); |
---|
2078 | 2396 | if (ret) |
---|
.. | .. |
---|
2136 | 2454 | pm_runtime_put_sync(dev); |
---|
2137 | 2455 | pm_runtime_disable(dev); |
---|
2138 | 2456 | clk_bulk_disable_unprepare(rphy->num_clks, rphy->clks); |
---|
2139 | | - |
---|
2140 | 2457 | return ret; |
---|
2141 | 2458 | } |
---|
2142 | 2459 | |
---|
.. | .. |
---|
2203 | 2520 | { |
---|
2204 | 2521 | int ret; |
---|
2205 | 2522 | |
---|
2206 | | - /* Open pre-emphasize in non-chirp state for otg port */ |
---|
2207 | | - ret = regmap_write(rphy->grf, 0x0, 0x00070004); |
---|
2208 | | - if (ret) |
---|
2209 | | - return ret; |
---|
| 2523 | + if (soc_is_rk3308bs()) { |
---|
| 2524 | + /* Turn off differential receiver in suspend mode */ |
---|
| 2525 | + ret = regmap_update_bits(rphy->grf, 0x30, BIT(2), 0); |
---|
| 2526 | + if (ret) |
---|
| 2527 | + return ret; |
---|
2210 | 2528 | |
---|
2211 | | - /* Open pre-emphasize in non-chirp state for host port */ |
---|
2212 | | - ret = regmap_write(rphy->grf, 0x30, 0x00070004); |
---|
2213 | | - if (ret) |
---|
2214 | | - return ret; |
---|
| 2529 | + /* Enable otg port pre-emphasis during non-chirp phase */ |
---|
| 2530 | + ret = regmap_update_bits(rphy->grf, 0, GENMASK(2, 0), BIT(2)); |
---|
| 2531 | + if (ret) |
---|
| 2532 | + return ret; |
---|
2215 | 2533 | |
---|
2216 | | - /* Turn off differential receiver in suspend mode */ |
---|
2217 | | - ret = regmap_write(rphy->grf, 0x18, 0x00040000); |
---|
2218 | | - if (ret) |
---|
2219 | | - return ret; |
---|
| 2534 | + /* Set otg port squelch trigger point configure to 100mv */ |
---|
| 2535 | + ret = regmap_update_bits(rphy->grf, 0x004, GENMASK(7, 5), 0x40); |
---|
| 2536 | + if (ret) |
---|
| 2537 | + return ret; |
---|
| 2538 | + |
---|
| 2539 | + ret = regmap_update_bits(rphy->grf, 0x008, BIT(0), 0x1); |
---|
| 2540 | + if (ret) |
---|
| 2541 | + return ret; |
---|
| 2542 | + |
---|
| 2543 | + /* Enable host port pre-emphasis during non-chirp phase */ |
---|
| 2544 | + ret = regmap_update_bits(rphy->grf, 0x400, GENMASK(2, 0), BIT(2)); |
---|
| 2545 | + if (ret) |
---|
| 2546 | + return ret; |
---|
| 2547 | + |
---|
| 2548 | + /* Set host port squelch trigger point configure to 100mv */ |
---|
| 2549 | + ret = regmap_update_bits(rphy->grf, 0x404, GENMASK(7, 5), 0x40); |
---|
| 2550 | + if (ret) |
---|
| 2551 | + return ret; |
---|
| 2552 | + |
---|
| 2553 | + ret = regmap_update_bits(rphy->grf, 0x408, BIT(0), 0x1); |
---|
| 2554 | + if (ret) |
---|
| 2555 | + return ret; |
---|
| 2556 | + } else { |
---|
| 2557 | + /* Open pre-emphasize in non-chirp state for otg port */ |
---|
| 2558 | + ret = regmap_write(rphy->grf, 0x0, 0x00070004); |
---|
| 2559 | + if (ret) |
---|
| 2560 | + return ret; |
---|
| 2561 | + |
---|
| 2562 | + /* Open pre-emphasize in non-chirp state for host port */ |
---|
| 2563 | + ret = regmap_write(rphy->grf, 0x30, 0x00070004); |
---|
| 2564 | + if (ret) |
---|
| 2565 | + return ret; |
---|
| 2566 | + |
---|
| 2567 | + /* Turn off differential receiver in suspend mode */ |
---|
| 2568 | + ret = regmap_write(rphy->grf, 0x18, 0x00040000); |
---|
| 2569 | + if (ret) |
---|
| 2570 | + return ret; |
---|
| 2571 | + } |
---|
2220 | 2572 | |
---|
2221 | 2573 | return 0; |
---|
2222 | 2574 | } |
---|
.. | .. |
---|
2379 | 2731 | |
---|
2380 | 2732 | static int rk3528_usb2phy_tuning(struct rockchip_usb2phy *rphy) |
---|
2381 | 2733 | { |
---|
2382 | | - u32 reg; |
---|
2383 | 2734 | int ret = 0; |
---|
2384 | 2735 | |
---|
2385 | 2736 | /* Turn off otg port differential receiver in suspend mode */ |
---|
2386 | | - reg = readl(rphy->phy_base + 0x30); |
---|
2387 | | - writel(reg & ~BIT(2), rphy->phy_base + 0x30); |
---|
| 2737 | + phy_clear_bits(rphy->phy_base + 0x30, BIT(2)); |
---|
2388 | 2738 | |
---|
2389 | 2739 | /* Turn off host port differential receiver in suspend mode */ |
---|
2390 | | - reg = readl(rphy->phy_base + 0x0430); |
---|
2391 | | - writel(reg & ~BIT(2), rphy->phy_base + 0x0430); |
---|
| 2740 | + phy_clear_bits(rphy->phy_base + 0x430, BIT(2)); |
---|
2392 | 2741 | |
---|
2393 | 2742 | /* Set otg port HS eye height to 400mv(default is 450mv) */ |
---|
2394 | | - reg = readl(rphy->phy_base + 0x30); |
---|
2395 | | - reg &= ~GENMASK(6, 4); |
---|
2396 | | - reg |= (0x00 << 4); |
---|
2397 | | - writel(reg, rphy->phy_base + 0x30); |
---|
| 2743 | + phy_update_bits(rphy->phy_base + 0x30, GENMASK(6, 4), (0x00 << 4)); |
---|
2398 | 2744 | |
---|
2399 | 2745 | /* Set host port HS eye height to 400mv(default is 450mv) */ |
---|
2400 | | - reg = readl(rphy->phy_base + 0x430); |
---|
2401 | | - reg &= ~GENMASK(6, 4); |
---|
2402 | | - reg |= (0x00 << 4); |
---|
2403 | | - writel(reg, rphy->phy_base + 0x430); |
---|
| 2746 | + phy_update_bits(rphy->phy_base + 0x430, GENMASK(6, 4), (0x00 << 4)); |
---|
2404 | 2747 | |
---|
2405 | 2748 | /* Choose the Tx fs/ls data as linestate from TX driver for otg port */ |
---|
2406 | | - reg = readl(rphy->phy_base + 0x94); |
---|
2407 | | - reg &= ~GENMASK(6, 3); |
---|
2408 | | - reg |= (0x03 << 3); |
---|
2409 | | - writel(reg, rphy->phy_base + 0x94); |
---|
| 2749 | + phy_update_bits(rphy->phy_base + 0x94, GENMASK(6, 3), (0x03 << 3)); |
---|
2410 | 2750 | |
---|
2411 | 2751 | /* Enable otg and host ports phy irq to pmu wakeup source */ |
---|
2412 | 2752 | ret |= regmap_write(rphy->grf, 0x80004, 0x00030003); |
---|
.. | .. |
---|
2414 | 2754 | return ret; |
---|
2415 | 2755 | } |
---|
2416 | 2756 | |
---|
2417 | | -static int rk3568_usb2phy_tuning(struct rockchip_usb2phy *rphy) |
---|
| 2757 | +static int rk3562_usb2phy_tuning(struct rockchip_usb2phy *rphy) |
---|
2418 | 2758 | { |
---|
2419 | | - u32 reg; |
---|
2420 | 2759 | int ret = 0; |
---|
2421 | 2760 | |
---|
2422 | | - reg = readl(rphy->phy_base + 0x30); |
---|
2423 | | - /* turn off differential reciver in suspend mode */ |
---|
2424 | | - writel(reg & ~BIT(2), rphy->phy_base + 0x30); |
---|
| 2761 | + /* Turn off differential receiver by default to save power */ |
---|
| 2762 | + phy_clear_bits(rphy->phy_base + 0x0030, BIT(2)); |
---|
| 2763 | + phy_clear_bits(rphy->phy_base + 0x0430, BIT(2)); |
---|
2425 | 2764 | |
---|
2426 | | - reg = readl(rphy->phy_base); |
---|
| 2765 | + /* Enable pre-emphasis during non-chirp phase */ |
---|
| 2766 | + phy_update_bits(rphy->phy_base, GENMASK(2, 0), 0x04); |
---|
| 2767 | + phy_update_bits(rphy->phy_base + 0x0400, GENMASK(2, 0), 0x04); |
---|
| 2768 | + |
---|
| 2769 | + /* Set HS eye height to 425mv(default is 400mv) */ |
---|
| 2770 | + phy_update_bits(rphy->phy_base + 0x0030, GENMASK(6, 4), (0x05 << 4)); |
---|
| 2771 | + phy_update_bits(rphy->phy_base + 0x0430, GENMASK(6, 4), (0x05 << 4)); |
---|
| 2772 | + |
---|
| 2773 | + /* Set the bvalid filter time to 10ms based on the u2phy grf pclk 100MHz */ |
---|
| 2774 | + ret |= regmap_write(rphy->grf, 0x0138, FILTER_COUNTER); |
---|
| 2775 | + |
---|
| 2776 | + /* Set the id filter time to 10ms based on the u2phy grf pclk 100MHz */ |
---|
| 2777 | + ret |= regmap_write(rphy->grf, 0x013c, FILTER_COUNTER); |
---|
| 2778 | + |
---|
| 2779 | + /* Enable host port wakeup irq */ |
---|
| 2780 | + ret |= regmap_write(rphy->grf, 0x010c, 0x80008000); |
---|
| 2781 | + |
---|
| 2782 | + return ret; |
---|
| 2783 | +} |
---|
| 2784 | + |
---|
| 2785 | +static int rk3568_usb2phy_tuning(struct rockchip_usb2phy *rphy) |
---|
| 2786 | +{ |
---|
| 2787 | + int ret = 0; |
---|
| 2788 | + |
---|
| 2789 | + /* Turn off differential receiver by default to save power */ |
---|
| 2790 | + phy_clear_bits(rphy->phy_base + 0x30, BIT(2)); |
---|
| 2791 | + |
---|
2427 | 2792 | /* Enable otg port pre-emphasis during non-chirp phase */ |
---|
2428 | | - reg &= ~(0x07 << 0); |
---|
2429 | | - reg |= (0x04 << 0); |
---|
2430 | | - writel(reg, rphy->phy_base); |
---|
| 2793 | + phy_update_bits(rphy->phy_base, GENMASK(2, 0), 0x04); |
---|
2431 | 2794 | |
---|
2432 | | - reg = readl(rphy->phy_base + 0x0400); |
---|
2433 | 2795 | /* Enable host port pre-emphasis during non-chirp phase */ |
---|
2434 | | - reg &= ~(0x07 << 0); |
---|
2435 | | - reg |= (0x04 << 0); |
---|
2436 | | - writel(reg, rphy->phy_base + 0x0400); |
---|
| 2796 | + phy_update_bits(rphy->phy_base + 0x0400, GENMASK(2, 0), 0x04); |
---|
2437 | 2797 | |
---|
2438 | 2798 | if (rphy->phy_cfg->reg == 0xfe8a0000) { |
---|
2439 | 2799 | /* Set otg port HS eye height to 437.5mv(default is 400mv) */ |
---|
2440 | | - reg = readl(rphy->phy_base + 0x30); |
---|
2441 | | - reg &= ~(0x07 << 4); |
---|
2442 | | - reg |= (0x06 << 4); |
---|
2443 | | - writel(reg, rphy->phy_base + 0x30); |
---|
| 2800 | + phy_update_bits(rphy->phy_base + 0x30, GENMASK(6, 4), (0x06 << 4)); |
---|
2444 | 2801 | |
---|
2445 | 2802 | /* |
---|
2446 | 2803 | * Set the bvalid filter time to 10ms |
---|
.. | .. |
---|
2461 | 2818 | return ret; |
---|
2462 | 2819 | } |
---|
2463 | 2820 | |
---|
| 2821 | +static int rv1106_usb2phy_tuning(struct rockchip_usb2phy *rphy) |
---|
| 2822 | +{ |
---|
| 2823 | + /* Always enable pre-emphasis in SOF & EOP & chirp & non-chirp state */ |
---|
| 2824 | + phy_update_bits(rphy->phy_base + 0x30, GENMASK(2, 0), 0x07); |
---|
| 2825 | + |
---|
| 2826 | + if (rockchip_get_cpu_version()) { |
---|
| 2827 | + /* Set Tx HS pre_emphasize strength to 3'b001 */ |
---|
| 2828 | + phy_update_bits(rphy->phy_base + 0x40, GENMASK(5, 3), (0x01 << 3)); |
---|
| 2829 | + } else { |
---|
| 2830 | + /* Set Tx HS pre_emphasize strength to 3'b011 */ |
---|
| 2831 | + phy_update_bits(rphy->phy_base + 0x40, GENMASK(5, 3), (0x03 << 3)); |
---|
| 2832 | + } |
---|
| 2833 | + |
---|
| 2834 | + /* Set RX Squelch trigger point configure to 4'b0000(112.5 mV) */ |
---|
| 2835 | + phy_update_bits(rphy->phy_base + 0x64, GENMASK(6, 3), (0x00 << 3)); |
---|
| 2836 | + |
---|
| 2837 | + /* Turn off differential receiver by default to save power */ |
---|
| 2838 | + phy_clear_bits(rphy->phy_base + 0x100, BIT(6)); |
---|
| 2839 | + |
---|
| 2840 | + /* Set 45ohm HS ODT value to 5'b10111 to increase driver strength */ |
---|
| 2841 | + phy_update_bits(rphy->phy_base + 0x11c, GENMASK(4, 0), 0x17); |
---|
| 2842 | + |
---|
| 2843 | + /* Set Tx HS eye height tuning to 3'b011(462 mV)*/ |
---|
| 2844 | + phy_update_bits(rphy->phy_base + 0x124, GENMASK(4, 2), (0x03 << 2)); |
---|
| 2845 | + |
---|
| 2846 | + /* Bypass Squelch detector calibration */ |
---|
| 2847 | + phy_update_bits(rphy->phy_base + 0x1a4, GENMASK(7, 4), (0x01 << 4)); |
---|
| 2848 | + phy_update_bits(rphy->phy_base + 0x1b4, GENMASK(7, 4), (0x01 << 4)); |
---|
| 2849 | + |
---|
| 2850 | + /* Set HS disconnect detect mode to single ended detect mode */ |
---|
| 2851 | + phy_set_bits(rphy->phy_base + 0x70, BIT(2)); |
---|
| 2852 | + |
---|
| 2853 | + return 0; |
---|
| 2854 | +} |
---|
| 2855 | + |
---|
2464 | 2856 | static int rockchip_usb2phy_vbus_det_control(struct rockchip_usb2phy *rphy, |
---|
2465 | 2857 | const struct usb2phy_reg *vbus_det_en, |
---|
2466 | 2858 | bool en) |
---|
2467 | 2859 | { |
---|
2468 | | - u32 reg; |
---|
2469 | | - |
---|
2470 | 2860 | if (en) { |
---|
2471 | | - reg = readl(rphy->phy_base + vbus_det_en->offset); |
---|
2472 | 2861 | /* Enable vbus voltage level detection function */ |
---|
2473 | | - writel(reg & ~BIT(7), rphy->phy_base + vbus_det_en->offset); |
---|
| 2862 | + phy_clear_bits(rphy->phy_base + vbus_det_en->offset, BIT(7)); |
---|
2474 | 2863 | } else { |
---|
2475 | | - reg = readl(rphy->phy_base + vbus_det_en->offset); |
---|
2476 | 2864 | /* Disable vbus voltage level detection function */ |
---|
2477 | | - writel(reg | BIT(7), rphy->phy_base + vbus_det_en->offset); |
---|
| 2865 | + phy_set_bits(rphy->phy_base + vbus_det_en->offset, BIT(7)); |
---|
2478 | 2866 | } |
---|
2479 | 2867 | |
---|
2480 | 2868 | return 0; |
---|
| 2869 | +} |
---|
| 2870 | + |
---|
| 2871 | +static int rk3588_usb2phy_tuning(struct rockchip_usb2phy *rphy) |
---|
| 2872 | +{ |
---|
| 2873 | + unsigned int reg; |
---|
| 2874 | + int ret = 0; |
---|
| 2875 | + |
---|
| 2876 | + /* Read the SIDDQ control register */ |
---|
| 2877 | + ret = regmap_read(rphy->grf, 0x0008, ®); |
---|
| 2878 | + if (ret) |
---|
| 2879 | + return ret; |
---|
| 2880 | + |
---|
| 2881 | + if (reg & BIT(13)) { |
---|
| 2882 | + /* Deassert SIDDQ to power on analog block */ |
---|
| 2883 | + ret = regmap_write(rphy->grf, 0x0008, |
---|
| 2884 | + GENMASK(29, 29) | 0x0000); |
---|
| 2885 | + if (ret) |
---|
| 2886 | + return ret; |
---|
| 2887 | + |
---|
| 2888 | + /* Do reset after exit IDDQ mode */ |
---|
| 2889 | + ret = rockchip_usb2phy_reset(rphy); |
---|
| 2890 | + if (ret) |
---|
| 2891 | + return ret; |
---|
| 2892 | + } |
---|
| 2893 | + |
---|
| 2894 | + if (rphy->phy_cfg->reg == 0x0000) { |
---|
| 2895 | + /* |
---|
| 2896 | + * Set USB2 PHY0 suspend configuration for USB3_0 |
---|
| 2897 | + * 1. Set utmi_termselect to 1'b1 (en FS terminations) |
---|
| 2898 | + * 2. Set utmi_xcvrselect to 2'b01 (FS transceiver) |
---|
| 2899 | + * 3. Set utmi_opmode to 2'b01 (no-driving) |
---|
| 2900 | + */ |
---|
| 2901 | + ret |= regmap_write(rphy->grf, 0x000c, |
---|
| 2902 | + GENMASK(20, 16) | 0x0015); |
---|
| 2903 | + |
---|
| 2904 | + /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */ |
---|
| 2905 | + ret |= regmap_write(rphy->grf, 0x0004, |
---|
| 2906 | + GENMASK(27, 24) | 0x0900); |
---|
| 2907 | + |
---|
| 2908 | + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */ |
---|
| 2909 | + ret |= regmap_write(rphy->grf, 0x0008, |
---|
| 2910 | + GENMASK(20, 19) | 0x0010); |
---|
| 2911 | + |
---|
| 2912 | + /* Pullup iddig pin for USB3_0 OTG mode */ |
---|
| 2913 | + ret |= regmap_write(rphy->grf, 0x0010, |
---|
| 2914 | + GENMASK(17, 16) | 0x0003); |
---|
| 2915 | + } else if (rphy->phy_cfg->reg == 0x4000) { |
---|
| 2916 | + /* |
---|
| 2917 | + * Set USB2 PHY1 suspend configuration for USB3_1 |
---|
| 2918 | + * 1. Set utmi_termselect to 1'b1 (en FS terminations) |
---|
| 2919 | + * 2. Set utmi_xcvrselect to 2'b01(FS transceiver) |
---|
| 2920 | + * 3. Set utmi_opmode to 2'b01 (no-driving) |
---|
| 2921 | + */ |
---|
| 2922 | + ret |= regmap_write(rphy->grf, 0x000c, |
---|
| 2923 | + GENMASK(20, 16) | 0x0015); |
---|
| 2924 | + |
---|
| 2925 | + /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */ |
---|
| 2926 | + ret |= regmap_write(rphy->grf, 0x0004, |
---|
| 2927 | + GENMASK(27, 24) | 0x0900); |
---|
| 2928 | + |
---|
| 2929 | + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */ |
---|
| 2930 | + ret |= regmap_write(rphy->grf, 0x0008, |
---|
| 2931 | + GENMASK(20, 19) | 0x0010); |
---|
| 2932 | + |
---|
| 2933 | + /* Pullup iddig pin for USB3_1 OTG mode */ |
---|
| 2934 | + ret |= regmap_write(rphy->grf, 0x0010, |
---|
| 2935 | + GENMASK(17, 16) | 0x0003); |
---|
| 2936 | + } else if (rphy->phy_cfg->reg == 0x8000) { |
---|
| 2937 | + /* |
---|
| 2938 | + * Set USB2 PHY2 suspend configuration for USB2_0 |
---|
| 2939 | + * 1. Set utmi_termselect to 1'b1 (en FS terminations) |
---|
| 2940 | + * 2. Set utmi_xcvrselect to 2'b01(FS transceiver) |
---|
| 2941 | + * 3. Set utmi_opmode to 2'b00 (normal) |
---|
| 2942 | + */ |
---|
| 2943 | + ret |= regmap_write(rphy->grf, 0x000c, |
---|
| 2944 | + GENMASK(20, 16) | 0x0014); |
---|
| 2945 | + |
---|
| 2946 | + /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */ |
---|
| 2947 | + ret |= regmap_write(rphy->grf, 0x0004, |
---|
| 2948 | + GENMASK(27, 24) | 0x0900); |
---|
| 2949 | + |
---|
| 2950 | + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */ |
---|
| 2951 | + ret |= regmap_write(rphy->grf, 0x0008, |
---|
| 2952 | + GENMASK(20, 19) | 0x0010); |
---|
| 2953 | + } else if (rphy->phy_cfg->reg == 0xc000) { |
---|
| 2954 | + /* |
---|
| 2955 | + * Set USB2 PHY3 suspend configuration for USB2_1 |
---|
| 2956 | + * 1. Set utmi_termselect to 1'b1 (en FS terminations) |
---|
| 2957 | + * 2. Set utmi_xcvrselect to 2'b01(FS transceiver) |
---|
| 2958 | + * 3. Set utmi_opmode to 2'b00 (normal) |
---|
| 2959 | + */ |
---|
| 2960 | + ret |= regmap_write(rphy->grf, 0x000c, |
---|
| 2961 | + GENMASK(20, 16) | 0x0014); |
---|
| 2962 | + |
---|
| 2963 | + /* HS DC Voltage Level Adjustment 4'b1001 : +5.89% */ |
---|
| 2964 | + ret |= regmap_write(rphy->grf, 0x0004, |
---|
| 2965 | + GENMASK(27, 24) | 0x0900); |
---|
| 2966 | + |
---|
| 2967 | + /* HS Transmitter Pre-Emphasis Current Control 2'b10 : 2x */ |
---|
| 2968 | + ret |= regmap_write(rphy->grf, 0x0008, |
---|
| 2969 | + GENMASK(20, 19) | 0x0010); |
---|
| 2970 | + } |
---|
| 2971 | + |
---|
| 2972 | + return ret; |
---|
2481 | 2973 | } |
---|
2482 | 2974 | |
---|
2483 | 2975 | #ifdef CONFIG_PM_SLEEP |
---|
.. | .. |
---|
2570 | 3062 | |
---|
2571 | 3063 | if (device_may_wakeup(rphy->dev)) |
---|
2572 | 3064 | wakeup_enable = true; |
---|
| 3065 | + |
---|
| 3066 | + /* |
---|
| 3067 | + * PHY lost power in suspend, it needs to reset |
---|
| 3068 | + * PHY to recovery clock to usb controller. |
---|
| 3069 | + */ |
---|
| 3070 | + if (!wakeup_enable) |
---|
| 3071 | + rockchip_usb2phy_reset(rphy); |
---|
2573 | 3072 | |
---|
2574 | 3073 | if (phy_cfg->phy_tuning) |
---|
2575 | 3074 | ret = phy_cfg->phy_tuning(rphy); |
---|
.. | .. |
---|
2987 | 3486 | .vbus_det_en = { 0x079c, 15, 15, 1, 0 }, |
---|
2988 | 3487 | }, |
---|
2989 | 3488 | [USB2PHY_PORT_HOST] = { |
---|
2990 | | - .phy_sus = { 0x0728, 8, 0, 0, 0x1d1 }, |
---|
| 3489 | + .phy_sus = { 0x0728, 15, 0, 0, 0x1d1 }, |
---|
2991 | 3490 | .ls_det_en = { 0x0680, 4, 4, 0, 1 }, |
---|
2992 | 3491 | .ls_det_st = { 0x0690, 4, 4, 0, 1 }, |
---|
2993 | 3492 | .ls_det_clr = { 0x06a0, 4, 4, 0, 1 } |
---|
.. | .. |
---|
3128 | 3627 | .bvalid_det_en = { 0x60074, 2, 2, 0, 1 }, |
---|
3129 | 3628 | .bvalid_det_st = { 0x60078, 2, 2, 0, 1 }, |
---|
3130 | 3629 | .bvalid_det_clr = { 0x6007c, 2, 2, 0, 1 }, |
---|
3131 | | - .bvalid_set = { 0x6004c, 15, 14, 0, 3 }, |
---|
3132 | 3630 | .iddig_output = { 0x6004c, 10, 10, 0, 1 }, |
---|
3133 | 3631 | .iddig_en = { 0x6004c, 9, 9, 0, 1 }, |
---|
3134 | 3632 | .idfall_det_en = { 0x60074, 5, 5, 0, 1 }, |
---|
.. | .. |
---|
3172 | 3670 | } |
---|
3173 | 3671 | }; |
---|
3174 | 3672 | |
---|
| 3673 | +static const struct rockchip_usb2phy_cfg rk3562_phy_cfgs[] = { |
---|
| 3674 | + { |
---|
| 3675 | + .reg = 0xff740000, |
---|
| 3676 | + .num_ports = 2, |
---|
| 3677 | + .phy_tuning = rk3562_usb2phy_tuning, |
---|
| 3678 | + .vbus_detect = rockchip_usb2phy_vbus_det_control, |
---|
| 3679 | + .clkout_ctl = { 0x0108, 4, 4, 1, 0 }, |
---|
| 3680 | + .ls_filter_con = { 0x0130, 19, 0, 0x30100, 0x00020 }, |
---|
| 3681 | + .port_cfgs = { |
---|
| 3682 | + [USB2PHY_PORT_OTG] = { |
---|
| 3683 | + .phy_sus = { 0x0100, 8, 0, 0, 0x1d1 }, |
---|
| 3684 | + .bvalid_det_en = { 0x0110, 2, 2, 0, 1 }, |
---|
| 3685 | + .bvalid_det_st = { 0x0114, 2, 2, 0, 1 }, |
---|
| 3686 | + .bvalid_det_clr = { 0x0118, 2, 2, 0, 1 }, |
---|
| 3687 | + .bvalid_grf_sel = { 0x0108, 15, 14, 0, 3 }, |
---|
| 3688 | + .bypass_dm_en = { 0x0108, 2, 2, 0, 1}, |
---|
| 3689 | + .bypass_sel = { 0x0108, 3, 3, 0, 1}, |
---|
| 3690 | + .iddig_output = { 0x0100, 10, 10, 0, 1 }, |
---|
| 3691 | + .iddig_en = { 0x0100, 9, 9, 0, 1 }, |
---|
| 3692 | + .idfall_det_en = { 0x0110, 5, 5, 0, 1 }, |
---|
| 3693 | + .idfall_det_st = { 0x0114, 5, 5, 0, 1 }, |
---|
| 3694 | + .idfall_det_clr = { 0x0118, 5, 5, 0, 1 }, |
---|
| 3695 | + .idrise_det_en = { 0x0110, 4, 4, 0, 1 }, |
---|
| 3696 | + .idrise_det_st = { 0x0114, 4, 4, 0, 1 }, |
---|
| 3697 | + .idrise_det_clr = { 0x0118, 4, 4, 0, 1 }, |
---|
| 3698 | + .ls_det_en = { 0x0110, 0, 0, 0, 1 }, |
---|
| 3699 | + .ls_det_st = { 0x0114, 0, 0, 0, 1 }, |
---|
| 3700 | + .ls_det_clr = { 0x0118, 0, 0, 0, 1 }, |
---|
| 3701 | + .utmi_avalid = { 0x0120, 10, 10, 0, 1 }, |
---|
| 3702 | + .utmi_bvalid = { 0x0120, 9, 9, 0, 1 }, |
---|
| 3703 | + .utmi_iddig = { 0x0120, 6, 6, 0, 1 }, |
---|
| 3704 | + .utmi_ls = { 0x0120, 5, 4, 0, 1 }, |
---|
| 3705 | + .vbus_det_en = { 0x003c, 7, 7, 0, 1 }, |
---|
| 3706 | + }, |
---|
| 3707 | + [USB2PHY_PORT_HOST] = { |
---|
| 3708 | + .phy_sus = { 0x0104, 8, 0, 0x1d2, 0x1d1 }, |
---|
| 3709 | + .ls_det_en = { 0x0110, 1, 1, 0, 1 }, |
---|
| 3710 | + .ls_det_st = { 0x0114, 1, 1, 0, 1 }, |
---|
| 3711 | + .ls_det_clr = { 0x0118, 1, 1, 0, 1 }, |
---|
| 3712 | + .utmi_ls = { 0x0120, 17, 16, 0, 1 }, |
---|
| 3713 | + .utmi_hstdet = { 0x0120, 19, 19, 0, 1 } |
---|
| 3714 | + } |
---|
| 3715 | + }, |
---|
| 3716 | + .chg_det = { |
---|
| 3717 | + .chg_mode = { 0x0100, 8, 0, 0, 0x1d7 }, |
---|
| 3718 | + .cp_det = { 0x0120, 24, 24, 0, 1 }, |
---|
| 3719 | + .dcp_det = { 0x0120, 23, 23, 0, 1 }, |
---|
| 3720 | + .dp_det = { 0x0120, 25, 25, 0, 1 }, |
---|
| 3721 | + .idm_sink_en = { 0x0108, 8, 8, 0, 1 }, |
---|
| 3722 | + .idp_sink_en = { 0x0108, 7, 7, 0, 1 }, |
---|
| 3723 | + .idp_src_en = { 0x0108, 9, 9, 0, 1 }, |
---|
| 3724 | + .rdm_pdwn_en = { 0x0108, 10, 10, 0, 1 }, |
---|
| 3725 | + .vdm_src_en = { 0x0108, 12, 12, 0, 1 }, |
---|
| 3726 | + .vdp_src_en = { 0x0108, 11, 11, 0, 1 }, |
---|
| 3727 | + }, |
---|
| 3728 | + }, |
---|
| 3729 | + { /* sentinel */ } |
---|
| 3730 | +}; |
---|
| 3731 | + |
---|
3175 | 3732 | static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { |
---|
3176 | 3733 | { |
---|
3177 | 3734 | .reg = 0xfe8a0000, |
---|
.. | .. |
---|
3186 | 3743 | .bvalid_det_en = { 0x0080, 2, 2, 0, 1 }, |
---|
3187 | 3744 | .bvalid_det_st = { 0x0084, 2, 2, 0, 1 }, |
---|
3188 | 3745 | .bvalid_det_clr = { 0x0088, 2, 2, 0, 1 }, |
---|
3189 | | - .bvalid_set = { 0x0008, 15, 14, 0, 3 }, |
---|
| 3746 | + .bvalid_grf_sel = { 0x0008, 15, 14, 0, 3 }, |
---|
3190 | 3747 | .bypass_dm_en = { 0x0008, 2, 2, 0, 1}, |
---|
3191 | 3748 | .bypass_sel = { 0x0008, 3, 3, 0, 1}, |
---|
3192 | 3749 | .iddig_output = { 0x0000, 10, 10, 0, 1 }, |
---|
.. | .. |
---|
3257 | 3814 | { /* sentinel */ } |
---|
3258 | 3815 | }; |
---|
3259 | 3816 | |
---|
| 3817 | +static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = { |
---|
| 3818 | + { |
---|
| 3819 | + .reg = 0x0000, |
---|
| 3820 | + .num_ports = 1, |
---|
| 3821 | + .phy_tuning = rk3588_usb2phy_tuning, |
---|
| 3822 | + .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, |
---|
| 3823 | + .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 }, |
---|
| 3824 | + .port_cfgs = { |
---|
| 3825 | + [USB2PHY_PORT_OTG] = { |
---|
| 3826 | + .phy_sus = { 0x000c, 11, 11, 0, 1 }, |
---|
| 3827 | + .pipe_phystatus = { 0x001c, 3, 2, 0, 2 }, |
---|
| 3828 | + .bvalid_det_en = { 0x0080, 1, 1, 0, 1 }, |
---|
| 3829 | + .bvalid_det_st = { 0x0084, 1, 1, 0, 1 }, |
---|
| 3830 | + .bvalid_det_clr = { 0x0088, 1, 1, 0, 1 }, |
---|
| 3831 | + .bvalid_grf_sel = { 0x0010, 3, 3, 0, 1 }, |
---|
| 3832 | + .bvalid_grf_con = { 0x0010, 3, 2, 2, 3 }, |
---|
| 3833 | + .bvalid_phy_con = { 0x0008, 1, 0, 2, 3 }, |
---|
| 3834 | + .bypass_dm_en = { 0x000c, 5, 5, 0, 1 }, |
---|
| 3835 | + .bypass_sel = { 0x000c, 6, 6, 0, 1 }, |
---|
| 3836 | + .iddig_output = { 0x0010, 0, 0, 0, 1 }, |
---|
| 3837 | + .iddig_en = { 0x0010, 1, 1, 0, 1 }, |
---|
| 3838 | + .idfall_det_en = { 0x0080, 4, 4, 0, 1 }, |
---|
| 3839 | + .idfall_det_st = { 0x0084, 4, 4, 0, 1 }, |
---|
| 3840 | + .idfall_det_clr = { 0x0088, 4, 4, 0, 1 }, |
---|
| 3841 | + .idrise_det_en = { 0x0080, 3, 3, 0, 1 }, |
---|
| 3842 | + .idrise_det_st = { 0x0084, 3, 3, 0, 1 }, |
---|
| 3843 | + .idrise_det_clr = { 0x0088, 3, 3, 0, 1 }, |
---|
| 3844 | + .ls_det_en = { 0x0080, 0, 0, 0, 1 }, |
---|
| 3845 | + .ls_det_st = { 0x0084, 0, 0, 0, 1 }, |
---|
| 3846 | + .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, |
---|
| 3847 | + .disfall_en = { 0x0080, 6, 6, 0, 1 }, |
---|
| 3848 | + .disfall_st = { 0x0084, 6, 6, 0, 1 }, |
---|
| 3849 | + .disfall_clr = { 0x0088, 6, 6, 0, 1 }, |
---|
| 3850 | + .disrise_en = { 0x0080, 5, 5, 0, 1 }, |
---|
| 3851 | + .disrise_st = { 0x0084, 5, 5, 0, 1 }, |
---|
| 3852 | + .disrise_clr = { 0x0088, 5, 5, 0, 1 }, |
---|
| 3853 | + .utmi_avalid = { 0x00c0, 7, 7, 0, 1 }, |
---|
| 3854 | + .utmi_bvalid = { 0x00c0, 6, 6, 0, 1 }, |
---|
| 3855 | + .utmi_iddig = { 0x00c0, 5, 5, 0, 1 }, |
---|
| 3856 | + .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, |
---|
| 3857 | + } |
---|
| 3858 | + }, |
---|
| 3859 | + .chg_det = { |
---|
| 3860 | + .chg_mode = { 0x0008, 2, 2, 0, 1 }, |
---|
| 3861 | + .cp_det = { 0x00c0, 0, 0, 0, 1 }, |
---|
| 3862 | + .dcp_det = { 0x00c0, 0, 0, 0, 1 }, |
---|
| 3863 | + .dp_det = { 0x00c0, 1, 1, 1, 0 }, |
---|
| 3864 | + .idm_sink_en = { 0x0008, 5, 5, 1, 0 }, |
---|
| 3865 | + .idp_sink_en = { 0x0008, 5, 5, 0, 1 }, |
---|
| 3866 | + .idp_src_en = { 0x0008, 14, 14, 0, 1 }, |
---|
| 3867 | + .rdm_pdwn_en = { 0x0008, 14, 14, 0, 1 }, |
---|
| 3868 | + .vdm_src_en = { 0x0008, 7, 6, 0, 3 }, |
---|
| 3869 | + .vdp_src_en = { 0x0008, 7, 6, 0, 3 }, |
---|
| 3870 | + }, |
---|
| 3871 | + }, |
---|
| 3872 | + { |
---|
| 3873 | + .reg = 0x4000, |
---|
| 3874 | + .num_ports = 1, |
---|
| 3875 | + .phy_tuning = rk3588_usb2phy_tuning, |
---|
| 3876 | + .clkout_ctl = { 0x0000, 0, 0, 1, 0 }, |
---|
| 3877 | + .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 }, |
---|
| 3878 | + .port_cfgs = { |
---|
| 3879 | + [USB2PHY_PORT_OTG] = { |
---|
| 3880 | + .phy_sus = { 0x000c, 11, 11, 0, 1 }, |
---|
| 3881 | + .pipe_phystatus = { 0x0034, 3, 2, 0, 2 }, |
---|
| 3882 | + .bvalid_det_en = { 0x0080, 1, 1, 0, 1 }, |
---|
| 3883 | + .bvalid_det_st = { 0x0084, 1, 1, 0, 1 }, |
---|
| 3884 | + .bvalid_det_clr = { 0x0088, 1, 1, 0, 1 }, |
---|
| 3885 | + .bvalid_grf_sel = { 0x0010, 3, 3, 0, 1 }, |
---|
| 3886 | + .bvalid_grf_con = { 0x0010, 3, 2, 2, 3 }, |
---|
| 3887 | + .bvalid_phy_con = { 0x0008, 1, 0, 2, 3 }, |
---|
| 3888 | + .bypass_dm_en = { 0x000c, 5, 5, 0, 1 }, |
---|
| 3889 | + .bypass_sel = { 0x000c, 6, 6, 0, 1 }, |
---|
| 3890 | + .iddig_output = { 0x0010, 0, 0, 0, 1 }, |
---|
| 3891 | + .iddig_en = { 0x0010, 1, 1, 0, 1 }, |
---|
| 3892 | + .idfall_det_en = { 0x0080, 4, 4, 0, 1 }, |
---|
| 3893 | + .idfall_det_st = { 0x0084, 4, 4, 0, 1 }, |
---|
| 3894 | + .idfall_det_clr = { 0x0088, 4, 4, 0, 1 }, |
---|
| 3895 | + .idrise_det_en = { 0x0080, 3, 3, 0, 1 }, |
---|
| 3896 | + .idrise_det_st = { 0x0084, 3, 3, 0, 1 }, |
---|
| 3897 | + .idrise_det_clr = { 0x0088, 3, 3, 0, 1 }, |
---|
| 3898 | + .ls_det_en = { 0x0080, 0, 0, 0, 1 }, |
---|
| 3899 | + .ls_det_st = { 0x0084, 0, 0, 0, 1 }, |
---|
| 3900 | + .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, |
---|
| 3901 | + .disfall_en = { 0x0080, 6, 6, 0, 1 }, |
---|
| 3902 | + .disfall_st = { 0x0084, 6, 6, 0, 1 }, |
---|
| 3903 | + .disfall_clr = { 0x0088, 6, 6, 0, 1 }, |
---|
| 3904 | + .disrise_en = { 0x0080, 5, 5, 0, 1 }, |
---|
| 3905 | + .disrise_st = { 0x0084, 5, 5, 0, 1 }, |
---|
| 3906 | + .disrise_clr = { 0x0088, 5, 5, 0, 1 }, |
---|
| 3907 | + .utmi_avalid = { 0x00c0, 7, 7, 0, 1 }, |
---|
| 3908 | + .utmi_bvalid = { 0x00c0, 6, 6, 0, 1 }, |
---|
| 3909 | + .utmi_iddig = { 0x00c0, 5, 5, 0, 1 }, |
---|
| 3910 | + .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, |
---|
| 3911 | + } |
---|
| 3912 | + }, |
---|
| 3913 | + .chg_det = { |
---|
| 3914 | + .chg_mode = { 0x0008, 2, 2, 0, 1 }, |
---|
| 3915 | + .cp_det = { 0x00c0, 0, 0, 0, 1 }, |
---|
| 3916 | + .dcp_det = { 0x00c0, 0, 0, 0, 1 }, |
---|
| 3917 | + .dp_det = { 0x00c0, 1, 1, 1, 0 }, |
---|
| 3918 | + .idm_sink_en = { 0x0008, 5, 5, 1, 0 }, |
---|
| 3919 | + .idp_sink_en = { 0x0008, 5, 5, 0, 1 }, |
---|
| 3920 | + .idp_src_en = { 0x0008, 14, 14, 0, 1 }, |
---|
| 3921 | + .rdm_pdwn_en = { 0x0008, 14, 14, 0, 1 }, |
---|
| 3922 | + .vdm_src_en = { 0x0008, 7, 6, 0, 3 }, |
---|
| 3923 | + .vdp_src_en = { 0x0008, 7, 6, 0, 3 }, |
---|
| 3924 | + }, |
---|
| 3925 | + }, |
---|
| 3926 | + { |
---|
| 3927 | + .reg = 0x8000, |
---|
| 3928 | + .num_ports = 1, |
---|
| 3929 | + .phy_tuning = rk3588_usb2phy_tuning, |
---|
| 3930 | + .clkout_ctl = { 0x0000, 0, 0, 0, 0 }, |
---|
| 3931 | + .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 }, |
---|
| 3932 | + .port_cfgs = { |
---|
| 3933 | + [USB2PHY_PORT_HOST] = { |
---|
| 3934 | + .phy_sus = { 0x0008, 2, 2, 0, 1 }, |
---|
| 3935 | + .ls_det_en = { 0x0080, 0, 0, 0, 1 }, |
---|
| 3936 | + .ls_det_st = { 0x0084, 0, 0, 0, 1 }, |
---|
| 3937 | + .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, |
---|
| 3938 | + .disfall_en = { 0x0080, 6, 6, 0, 1 }, |
---|
| 3939 | + .disfall_st = { 0x0084, 6, 6, 0, 1 }, |
---|
| 3940 | + .disfall_clr = { 0x0088, 6, 6, 0, 1 }, |
---|
| 3941 | + .disrise_en = { 0x0080, 5, 5, 0, 1 }, |
---|
| 3942 | + .disrise_st = { 0x0084, 5, 5, 0, 1 }, |
---|
| 3943 | + .disrise_clr = { 0x0088, 5, 5, 0, 1 }, |
---|
| 3944 | + .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, |
---|
| 3945 | + } |
---|
| 3946 | + }, |
---|
| 3947 | + }, |
---|
| 3948 | + { |
---|
| 3949 | + .reg = 0xc000, |
---|
| 3950 | + .num_ports = 1, |
---|
| 3951 | + .phy_tuning = rk3588_usb2phy_tuning, |
---|
| 3952 | + .clkout_ctl = { 0x0000, 0, 0, 0, 0 }, |
---|
| 3953 | + .ls_filter_con = { 0x0040, 19, 0, 0x30100, 0x00020 }, |
---|
| 3954 | + .port_cfgs = { |
---|
| 3955 | + [USB2PHY_PORT_HOST] = { |
---|
| 3956 | + .phy_sus = { 0x0008, 2, 2, 0, 1 }, |
---|
| 3957 | + .ls_det_en = { 0x0080, 0, 0, 0, 1 }, |
---|
| 3958 | + .ls_det_st = { 0x0084, 0, 0, 0, 1 }, |
---|
| 3959 | + .ls_det_clr = { 0x0088, 0, 0, 0, 1 }, |
---|
| 3960 | + .disfall_en = { 0x0080, 6, 6, 0, 1 }, |
---|
| 3961 | + .disfall_st = { 0x0084, 6, 6, 0, 1 }, |
---|
| 3962 | + .disfall_clr = { 0x0088, 6, 6, 0, 1 }, |
---|
| 3963 | + .disrise_en = { 0x0080, 5, 5, 0, 1 }, |
---|
| 3964 | + .disrise_st = { 0x0084, 5, 5, 0, 1 }, |
---|
| 3965 | + .disrise_clr = { 0x0088, 5, 5, 0, 1 }, |
---|
| 3966 | + .utmi_ls = { 0x00c0, 10, 9, 0, 1 }, |
---|
| 3967 | + } |
---|
| 3968 | + }, |
---|
| 3969 | + }, |
---|
| 3970 | + { /* sentinel */ } |
---|
| 3971 | +}; |
---|
| 3972 | + |
---|
| 3973 | +static const struct rockchip_usb2phy_cfg rv1106_phy_cfgs[] = { |
---|
| 3974 | + { |
---|
| 3975 | + .reg = 0xff3e0000, |
---|
| 3976 | + .num_ports = 1, |
---|
| 3977 | + .phy_tuning = rv1106_usb2phy_tuning, |
---|
| 3978 | + .clkout_ctl = { 0x0058, 4, 4, 1, 0 }, |
---|
| 3979 | + .port_cfgs = { |
---|
| 3980 | + [USB2PHY_PORT_OTG] = { |
---|
| 3981 | + .phy_sus = { 0x0050, 8, 0, 0, 0x1d1 }, |
---|
| 3982 | + .bvalid_det_en = { 0x0100, 2, 2, 0, 1 }, |
---|
| 3983 | + .bvalid_det_st = { 0x0104, 2, 2, 0, 1 }, |
---|
| 3984 | + .bvalid_det_clr = { 0x0108, 2, 2, 0, 1 }, |
---|
| 3985 | + .bvalid_grf_sel = { 0x0058, 15, 14, 0, 3 }, |
---|
| 3986 | + .iddig_output = { 0x0050, 10, 10, 0, 1 }, |
---|
| 3987 | + .iddig_en = { 0x0050, 9, 9, 0, 1 }, |
---|
| 3988 | + .idfall_det_en = { 0x0100, 5, 5, 0, 1 }, |
---|
| 3989 | + .idfall_det_st = { 0x0104, 5, 5, 0, 1 }, |
---|
| 3990 | + .idfall_det_clr = { 0x0108, 5, 5, 0, 1 }, |
---|
| 3991 | + .idrise_det_en = { 0x0100, 4, 4, 0, 1 }, |
---|
| 3992 | + .idrise_det_st = { 0x0104, 4, 4, 0, 1 }, |
---|
| 3993 | + .idrise_det_clr = { 0x0108, 4, 4, 0, 1 }, |
---|
| 3994 | + .ls_det_en = { 0x0100, 0, 0, 0, 1 }, |
---|
| 3995 | + .ls_det_st = { 0x0104, 0, 0, 0, 1 }, |
---|
| 3996 | + .ls_det_clr = { 0x0108, 0, 0, 0, 1 }, |
---|
| 3997 | + .utmi_avalid = { 0x0060, 10, 10, 0, 1 }, |
---|
| 3998 | + .utmi_bvalid = { 0x0060, 9, 9, 0, 1 }, |
---|
| 3999 | + .utmi_iddig = { 0x0060, 6, 6, 0, 1 }, |
---|
| 4000 | + .utmi_ls = { 0x0060, 5, 4, 0, 1 }, |
---|
| 4001 | + }, |
---|
| 4002 | + }, |
---|
| 4003 | + .chg_det = { |
---|
| 4004 | + .chg_mode = { 0x0050, 8, 0, 0, 0x1d7 }, |
---|
| 4005 | + .cp_det = { 0x0060, 13, 13, 0, 1 }, |
---|
| 4006 | + .dcp_det = { 0x0060, 12, 12, 0, 1 }, |
---|
| 4007 | + .dp_det = { 0x0060, 14, 14, 0, 1 }, |
---|
| 4008 | + .idm_sink_en = { 0x0058, 8, 8, 0, 1 }, |
---|
| 4009 | + .idp_sink_en = { 0x0058, 7, 7, 0, 1 }, |
---|
| 4010 | + .idp_src_en = { 0x0058, 9, 9, 0, 1 }, |
---|
| 4011 | + .rdm_pdwn_en = { 0x0058, 10, 10, 0, 1 }, |
---|
| 4012 | + .vdm_src_en = { 0x0058, 12, 12, 0, 1 }, |
---|
| 4013 | + .vdp_src_en = { 0x0058, 11, 11, 0, 1 }, |
---|
| 4014 | + }, |
---|
| 4015 | + }, |
---|
| 4016 | + { /* sentinel */ } |
---|
| 4017 | +}; |
---|
| 4018 | + |
---|
3260 | 4019 | static const struct rockchip_usb2phy_cfg rv1108_phy_cfgs[] = { |
---|
3261 | 4020 | { |
---|
3262 | 4021 | .reg = 0x100, |
---|
.. | .. |
---|
3300 | 4059 | }; |
---|
3301 | 4060 | |
---|
3302 | 4061 | static const struct of_device_id rockchip_usb2phy_dt_match[] = { |
---|
| 4062 | +#ifdef CONFIG_CPU_PX30 |
---|
| 4063 | + { .compatible = "rockchip,px30-usb2phy", .data = &rk3328_phy_cfgs }, |
---|
| 4064 | +#endif |
---|
| 4065 | +#ifdef CONFIG_CPU_RK1808 |
---|
3303 | 4066 | { .compatible = "rockchip,rk1808-usb2phy", .data = &rk1808_phy_cfgs }, |
---|
| 4067 | +#endif |
---|
| 4068 | +#ifdef CONFIG_CPU_RK312X |
---|
3304 | 4069 | { .compatible = "rockchip,rk3128-usb2phy", .data = &rk312x_phy_cfgs }, |
---|
| 4070 | +#endif |
---|
| 4071 | +#ifdef CONFIG_CPU_RK322X |
---|
3305 | 4072 | { .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs }, |
---|
| 4073 | +#endif |
---|
| 4074 | +#ifdef CONFIG_CPU_RK3308 |
---|
3306 | 4075 | { .compatible = "rockchip,rk3308-usb2phy", .data = &rk3308_phy_cfgs }, |
---|
| 4076 | +#endif |
---|
| 4077 | +#ifdef CONFIG_CPU_RK3328 |
---|
3307 | 4078 | { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, |
---|
| 4079 | +#endif |
---|
| 4080 | +#ifdef CONFIG_CPU_RK3366 |
---|
3308 | 4081 | { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, |
---|
| 4082 | +#endif |
---|
| 4083 | +#ifdef CONFIG_CPU_RK3368 |
---|
3309 | 4084 | { .compatible = "rockchip,rk3368-usb2phy", .data = &rk3368_phy_cfgs }, |
---|
| 4085 | +#endif |
---|
| 4086 | +#ifdef CONFIG_CPU_RK3399 |
---|
3310 | 4087 | { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, |
---|
| 4088 | +#endif |
---|
| 4089 | +#ifdef CONFIG_CPU_RK3528 |
---|
3311 | 4090 | { .compatible = "rockchip,rk3528-usb2phy", .data = &rk3528_phy_cfgs }, |
---|
| 4091 | +#endif |
---|
| 4092 | +#ifdef CONFIG_CPU_RK3562 |
---|
| 4093 | + { .compatible = "rockchip,rk3562-usb2phy", .data = &rk3562_phy_cfgs }, |
---|
| 4094 | +#endif |
---|
| 4095 | +#ifdef CONFIG_CPU_RK3568 |
---|
3312 | 4096 | { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs }, |
---|
| 4097 | +#endif |
---|
| 4098 | +#ifdef CONFIG_CPU_RK3588 |
---|
| 4099 | + { .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs }, |
---|
| 4100 | +#endif |
---|
| 4101 | +#ifdef CONFIG_CPU_RV1106 |
---|
| 4102 | + { .compatible = "rockchip,rv1106-usb2phy", .data = &rv1106_phy_cfgs }, |
---|
| 4103 | +#endif |
---|
| 4104 | +#ifdef CONFIG_CPU_RV1108 |
---|
3313 | 4105 | { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs }, |
---|
| 4106 | +#endif |
---|
3314 | 4107 | {} |
---|
3315 | 4108 | }; |
---|
3316 | 4109 | MODULE_DEVICE_TABLE(of, rockchip_usb2phy_dt_match); |
---|