phy: phy-rockchip-inno-usb2: add reset support

Add reset handling support, which is needed for proper
operation with RK3588.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://lore.kernel.org/r/20230522170324.61349-4-sebastian.reichel@collabora.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Sebastian Reichel 2023-05-22 19:03:20 +02:00 committed by Vinod Koul
parent 3a7db8e9ed
commit 76d58ee8b8

View File

@ -24,6 +24,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/power_supply.h> #include <linux/power_supply.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/mfd/syscon.h> #include <linux/mfd/syscon.h>
#include <linux/usb/of.h> #include <linux/usb/of.h>
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
@ -223,6 +224,7 @@ struct rockchip_usb2phy_port {
* @clk: clock struct of phy input clk. * @clk: clock struct of phy input clk.
* @clk480m: clock struct of phy output clk. * @clk480m: clock struct of phy output clk.
* @clk480m_hw: clock struct of phy output clk management. * @clk480m_hw: clock struct of phy output clk management.
* @phy_reset: phy reset control.
* @chg_state: states involved in USB charger detection. * @chg_state: states involved in USB charger detection.
* @chg_type: USB charger types. * @chg_type: USB charger types.
* @dcd_retries: The retry count used to track Data contact * @dcd_retries: The retry count used to track Data contact
@ -239,6 +241,7 @@ struct rockchip_usb2phy {
struct clk *clk; struct clk *clk;
struct clk *clk480m; struct clk *clk480m;
struct clk_hw clk480m_hw; struct clk_hw clk480m_hw;
struct reset_control *phy_reset;
enum usb_chg_state chg_state; enum usb_chg_state chg_state;
enum power_supply_type chg_type; enum power_supply_type chg_type;
u8 dcd_retries; u8 dcd_retries;
@ -280,6 +283,25 @@ static inline bool property_enabled(struct regmap *base,
return tmp != reg->disable; return tmp != reg->disable;
} }
static int rockchip_usb2phy_reset(struct rockchip_usb2phy *rphy)
{
int ret;
ret = reset_control_assert(rphy->phy_reset);
if (ret)
return ret;
udelay(10);
ret = reset_control_deassert(rphy->phy_reset);
if (ret)
return ret;
usleep_range(100, 200);
return 0;
}
static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw) static int rockchip_usb2phy_clk480m_prepare(struct clk_hw *hw)
{ {
struct rockchip_usb2phy *rphy = struct rockchip_usb2phy *rphy =
@ -534,6 +556,18 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
return ret; return ret;
} }
/*
* For rk3588, it needs to reset phy when exit from
* suspend mode with common_on_n 1'b1(aka REFCLK_LOGIC,
* Bias, and PLL blocks are powered down) for lower
* power consumption. If you don't want to reset phy,
* please keep the common_on_n 1'b0 to set these blocks
* remain powered.
*/
ret = rockchip_usb2phy_reset(rphy);
if (ret)
return ret;
/* waiting for the utmi_clk to become stable */ /* waiting for the utmi_clk to become stable */
usleep_range(1500, 2000); usleep_range(1500, 2000);
@ -1348,6 +1382,10 @@ static int rockchip_usb2phy_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
rphy->phy_reset = devm_reset_control_get_optional(dev, "phy");
if (IS_ERR(rphy->phy_reset))
return PTR_ERR(rphy->phy_reset);
rphy->clk = of_clk_get_by_name(np, "phyclk"); rphy->clk = of_clk_get_by_name(np, "phyclk");
if (!IS_ERR(rphy->clk)) { if (!IS_ERR(rphy->clk)) {
clk_prepare_enable(rphy->clk); clk_prepare_enable(rphy->clk);