From: lyz Date: Mon, 4 May 2015 06:06:17 +0000 (+0800) Subject: phy: phy-rockchip-usb: add support of rk33 usb phy X-Git-Tag: firefly_0821_release~4158^2~109 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=commitdiff_plain;h=6d91a06b4e95dfb83a41c9224e853bce579180bc phy: phy-rockchip-usb: add support of rk33 usb phy The usb phy of rk33's ehci usb controller usb genernic phy subsystem to handle suspend and resume Signed-off-by: lyz --- diff --git a/arch/arm64/boot/dts/rk3368.dtsi b/arch/arm64/boot/dts/rk3368.dtsi index 6a00febfbb3f..bfa3c0d094f6 100644 --- a/arch/arm64/boot/dts/rk3368.dtsi +++ b/arch/arm64/boot/dts/rk3368.dtsi @@ -1365,6 +1365,23 @@ }; }; + usbphy: phy { + compatible = "rockchip,rk3368-usb-phy"; + rockchip,grf = <&grf>; + #address-cells = <1>; + #size-cells = <0>; + + usbphy0: usb-phy0 { + #phy-cells = <0>; + reg = <0x700>; + }; + + usbphy1: usb-phy1 { + #phy-cells = <0>; + reg = <0x728>; + }; + }; + usb0: usb@ff580000 { compatible = "rockchip,rk3368_usb20_otg"; reg = <0x0 0xff580000 0x0 0x40000>; @@ -1384,6 +1401,8 @@ interrupts = ; clocks = <&clk_gates8 1>, <&clk_gates20 3>; clock-names = "clk_usbphy0", "hclk_ehci"; + phys = <&usbphy1>; + phy-names = "usb"; //resets = <&reset RK3288_SOFT_RST_USBHOST0_H>, <&reset RK3288_SOFT_RST_USBHOST0PHY>, // <&reset RK3288_SOFT_RST_USBHOST0C>, <&reset RK3288_SOFT_RST_USB_HOST0>; //reset-names = "ehci_ahb", "ehci_phy", "ehci_controller", "ehci"; diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index 6b582f7f7329..9de12477f16c 100644 --- a/arch/arm64/configs/rockchip_defconfig +++ b/arch/arm64/configs/rockchip_defconfig @@ -577,6 +577,8 @@ CONFIG_ROCKCHIP_ADC=y CONFIG_PWM=y CONFIG_PWM_ROCKCHIP=y CONFIG_RESET_CONTROLLER=y +CONFIG_GENERIC_PHY=y +CONFIG_PHY_ROCKCHIP_USB=y CONFIG_RK_HEADSET=y CONFIG_ANDROID_BINDER_IPC=y CONFIG_EXT2_FS=y diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c index c1d94dcc0bab..17ca9d999abf 100644 --- a/drivers/phy/phy-rockchip-usb.c +++ b/drivers/phy/phy-rockchip-usb.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -41,22 +42,34 @@ struct rockchip_usb_phy { struct regmap *reg_base; struct clk *clk; struct phy *phy; + int (*rk_usb_phy_power)(struct rockchip_usb_phy *phy, bool on); }; -static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy, - bool siddq) +static int rk32_usb_phy_power(struct rockchip_usb_phy *phy, + bool on) { + /* Power down usb phy analog blocks by set siddq 1 */ + bool siddq = !on; + return regmap_write(phy->reg_base, phy->reg_offset, SIDDQ_WRITE_ENA | (siddq ? SIDDQ_ON : SIDDQ_OFF)); } +static int rk33_usb_phy_power(struct rockchip_usb_phy *phy, + bool on) +{ + if (on) + return regmap_write(phy->reg_base, phy->reg_offset, 0xffff0000); + else + return regmap_write(phy->reg_base, phy->reg_offset, 0xffff01d5); +} + static int rockchip_usb_phy_power_off(struct phy *_phy) { struct rockchip_usb_phy *phy = phy_get_drvdata(_phy); int ret = 0; - /* Power down usb phy analog blocks by set siddq 1 */ - ret = rockchip_usb_phy_power(phy, 1); + ret = phy->rk_usb_phy_power(phy, 0); if (ret) return ret; @@ -77,7 +90,7 @@ static int rockchip_usb_phy_power_on(struct phy *_phy) return ret; /* Power up usb phy analog blocks by set siddq 0 */ - ret = rockchip_usb_phy_power(phy, 0); + ret = phy->rk_usb_phy_power(phy, 1); if (ret) return ret; @@ -90,6 +103,18 @@ static struct phy_ops ops = { .owner = THIS_MODULE, }; +static const struct of_device_id rockchip_usb_phy_dt_ids[] = { + { + .compatible = "rockchip,rk3288-usb-phy", + .data = (void *)rk32_usb_phy_power + }, + { + .compatible = "rockchip,rk3368-usb-phy", + .data = (void *)rk33_usb_phy_power + }, + {} +}; + static int rockchip_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -97,7 +122,9 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) struct phy_provider *phy_provider; struct device_node *child; struct regmap *grf; + const struct of_device_id *match; unsigned int reg_offset; + int (*rk_usb_phy_power)(struct rockchip_usb_phy *phy, bool siddq); grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); if (IS_ERR(grf)) { @@ -105,6 +132,12 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(grf); } + match = of_match_device(rockchip_usb_phy_dt_ids, &pdev->dev); + if (match && match->data) + rk_usb_phy_power = match->data; + else + return PTR_ERR(match); + for_each_available_child_of_node(dev->of_node, child) { rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL); if (!rk_phy) @@ -116,6 +149,7 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) return -EINVAL; } + rk_phy->rk_usb_phy_power = rk_usb_phy_power; rk_phy->reg_offset = reg_offset; rk_phy->reg_base = grf; @@ -132,17 +166,12 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) } phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - if (PTR_ERR(phy_provider)) + if (IS_ERR(phy_provider)) return (long)phy_provider; else return 0; } -static const struct of_device_id rockchip_usb_phy_dt_ids[] = { - { .compatible = "rockchip,rk3288-usb-phy" }, - {} -}; - MODULE_DEVICE_TABLE(of, rockchip_usb_phy_dt_ids); static struct platform_driver rockchip_usb_driver = {