2014-12-03 13:47:26

by Yunzhi Li

[permalink] [raw]
Subject: [PATCH] add a PHY driver Rockchip RK3288 USB2 PHY

From: lyz <[email protected]>

This patche to add a generic PHY driver for ROCKCHIP usb PHYs,
currently this driver can support RK3288. The RK3288 SoC have
three independent USB PHY IPs which are all configured through a
set of registers located in the GRF (general register files)
module. This driver powered off these USB PHYs and gating
their clocks when system suspend for saving power.

lyz (1):
phy: add Rockchip RK3288 USB2 PHY driver.

.../devicetree/bindings/phy/rockchip-usb-phy.txt | 17 ++
drivers/phy/Kconfig | 7 +
drivers/phy/Makefile | 1 +
drivers/phy/phy-rockchip-usb.c | 179 +++++++++++++++++++++
4 files changed, 204 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
create mode 100644 drivers/phy/phy-rockchip-usb.c

--
2.0.0


2014-12-03 13:47:27

by Yunzhi Li

[permalink] [raw]
Subject: [PATCH] phy: add Rockchip RK3288 USB2 PHY driver.

From: lyz <[email protected]>

Add a driver for the Rockchip SoC internal USB2.0 PHY.
This driver currently support RK3288.

Signed-off-by: lyz <[email protected]>
---
.../devicetree/bindings/phy/rockchip-usb-phy.txt | 17 ++
drivers/phy/Kconfig | 7 +
drivers/phy/Makefile | 1 +
drivers/phy/phy-rockchip-usb.c | 179 +++++++++++++++++++++
4 files changed, 204 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
create mode 100644 drivers/phy/phy-rockchip-usb.c

diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
new file mode 100644
index 0000000..18ccc2f
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
@@ -0,0 +1,17 @@
+ROCKCHIP USB2 PHY
+
+Required properties:
+ - compatible: rockchip,rk3288-usb-phy
+ - rockchip,grf : phandle to the syscon managing the "general
+ register files"
+ - #phy-cells: must be 1
+Refer to phy/phy-bindings.txt for the generic PHY binding
+properties
+
+Example:
+
+ usbphy: phy {
+ #phy-cells = <1>;
+ compatible = "rockchip,rk3288-usb-phy";
+ rockchip,grf = <&grf>;
+ };
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 2a436e6..54ab088 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -218,6 +218,13 @@ config PHY_QCOM_IPQ806X_SATA
depends on OF
select GENERIC_PHY

+config PHY_ROCKCHIP_RK3288_USB2
+ tristate "Rockchip USB2 RK3288 PHY Driver"
+ depends on ARCH_ROCKCHIP && OF
+ select GENERIC_PHY
+ help
+ Enable this to support the Rockchip USB 2.0 PHY.
+
config PHY_ST_SPEAR1310_MIPHY
tristate "ST SPEAR1310-MIPHY driver"
select GENERIC_PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index c4590fc..f4f2f79 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -25,6 +25,7 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
+obj-$(CONFIG_PHY_ROCKCHIP_RK3288_USB2) += phy-rockchip-usb.o
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c
new file mode 100644
index 0000000..2586b76
--- /dev/null
+++ b/drivers/phy/phy-rockchip-usb.c
@@ -0,0 +1,179 @@
+/*
+ * Rockchip usb PHY driver
+ *
+ * Copyright (C) 2014 Roy Li <[email protected]>
+ * Copyright (C) 2014 ROCKCHIP, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#define ROCKCHIP_RK3288_UOC(n) (0x320 + n * 0x14)
+
+#define SIDDQ_MSK (1 << (13 + 16))
+#define SIDDQ_ON (1 << 13)
+#define SIDDQ_OFF (0 << 13)
+
+enum rk3288_phy_id {
+ RK3288_OTG,
+ RK3288_HOST0,
+ RK3288_HOST1,
+ RK3288_NUM_PHYS,
+};
+
+struct rockchip_usb_phy {
+ struct regmap *reg_base;
+ unsigned int reg_offset;
+ struct clk *clk;
+ struct phy *phy;
+};
+
+static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
+ bool siddq)
+{
+ return regmap_write(phy->reg_base, phy->reg_offset,
+ SIDDQ_MSK | (siddq ? SIDDQ_ON : SIDDQ_OFF));
+}
+
+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);
+ if (ret)
+ return ret;
+
+ clk_disable_unprepare(phy->clk);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int rockchip_usb_phy_power_on(struct phy *_phy)
+{
+ struct rockchip_usb_phy *phy = phy_get_drvdata(_phy);
+ int ret = 0;
+
+ ret = clk_prepare_enable(phy->clk);
+ if (ret)
+ return ret;
+
+ /* Power up usb phy analog blocks by set siddq 0*/
+ ret = rockchip_usb_phy_power(phy, 0);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static struct phy *rockchip_usb_phy_xlate(struct device *dev,
+ struct of_phandle_args *args)
+{
+ struct rockchip_usb_phy *phy_array = dev_get_drvdata(dev);
+
+ if (WARN_ON(args->args[0] == 0 || args->args[0] >= RK3288_NUM_PHYS))
+ return ERR_PTR(-ENODEV);
+
+ return (phy_array + args->args[0])->phy;
+}
+
+static struct phy_ops ops = {
+ .power_on = rockchip_usb_phy_power_on,
+ .power_off = rockchip_usb_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static int rockchip_usb_phy_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rockchip_usb_phy *rk_phy;
+ struct rockchip_usb_phy *phy_array;
+ struct phy_provider *phy_provider;
+ struct regmap *grf;
+ char clk_name[16];
+ int i;
+
+ grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
+ if (IS_ERR(grf)) {
+ dev_err(&pdev->dev, "Missing rockchip,grf property\n");
+ return PTR_ERR(grf);
+ }
+
+ phy_array = devm_kzalloc(dev, RK3288_NUM_PHYS * sizeof(*rk_phy),
+ GFP_KERNEL);
+ if (!phy_array)
+ return -ENOMEM;
+
+ for (i = 0; i < RK3288_NUM_PHYS; i++) {
+ rk_phy = &phy_array[i];
+
+ rk_phy->reg_base = grf;
+
+ rk_phy->reg_offset = ROCKCHIP_RK3288_UOC(i);
+
+ snprintf(clk_name, sizeof(clk_name), "usbphy%d", i);
+ rk_phy->clk = devm_clk_get(dev, clk_name);
+ if (IS_ERR(rk_phy->clk)) {
+ dev_warn(dev, "failed to get clock %s\n", clk_name);
+ rk_phy->clk = NULL;
+ }
+
+ rk_phy->phy = devm_phy_create(dev, NULL, &ops, NULL);
+ if (IS_ERR(rk_phy->phy)) {
+ dev_err(dev, "failed to create PHY %d\n", i);
+ return PTR_ERR(rk_phy->phy);
+ }
+ phy_set_drvdata(rk_phy->phy, rk_phy);
+ }
+
+ platform_set_drvdata(pdev, phy_array);
+
+ phy_provider = devm_of_phy_provider_register(dev,
+ rockchip_usb_phy_xlate);
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+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 = {
+ .probe = rockchip_usb_phy_probe,
+ .driver = {
+ .name = "rockchip-usb-phy",
+ .owner = THIS_MODULE,
+ .of_match_table = rockchip_usb_phy_dt_ids,
+ },
+};
+
+module_platform_driver(rockchip_usb_driver);
+
+MODULE_AUTHOR("Roy Li <[email protected]>");
+MODULE_DESCRIPTION("Rockchip USB 2.0 PHY driver");
+MODULE_LICENSE("GPL v2");
--
2.0.0

2014-12-03 16:07:11

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] phy: add Rockchip RK3288 USB2 PHY driver.

On Wed, Dec 03, 2014 at 09:46:50PM +0800, LiYunzhi wrote:
> From: lyz <[email protected]>
>
> Add a driver for the Rockchip SoC internal USB2.0 PHY.
> This driver currently support RK3288.
>
> Signed-off-by: lyz <[email protected]>

Is this the name you use to sign legal documents? That is what you need
to put in your Signed-off-by: and "From:" lines.

thanks,

greg k-h

2014-12-04 01:00:51

by Kever Yang

[permalink] [raw]
Subject: Re: [PATCH] phy: add Rockchip RK3288 USB2 PHY driver.

Hi Roy,

Why you send two patches with different commit message but the same
change,
you should use V2 for a new patch.

On 12/03/2014 09:46 PM, LiYunzhi wrote:
> From: lyz <[email protected]>
You don't need the From for the patches from yourself.
>
> Add a driver for the Rockchip SoC internal USB2.0 PHY.
> This driver currently support RK3288.
>
> Signed-off-by: lyz <[email protected]>
Remember to use you Full name here for From/Signed-off-by
or all the kind of signature.
> ---
> .../devicetree/bindings/phy/rockchip-usb-phy.txt | 17 ++
The document should be in a separate patch, so please split this into
two patches.
> drivers/phy/Kconfig | 7 +
> drivers/phy/Makefile | 1 +
> drivers/phy/phy-rockchip-usb.c | 179 +++++++++++++++++++++
> 4 files changed, 204 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
> create mode 100644 drivers/phy/phy-rockchip-usb.c
>
> diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
> new file mode 100644
> index 0000000..18ccc2f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
> @@ -0,0 +1,17 @@
> +ROCKCHIP USB2 PHY
> +
> +Required properties:
> + - compatible: rockchip,rk3288-usb-phy
> + - rockchip,grf : phandle to the syscon managing the "general
> + register files"
> + - #phy-cells: must be 1
> +Refer to phy/phy-bindings.txt for the generic PHY binding
> +properties
> +
> +Example:
> +
> + usbphy: phy {
> + #phy-cells = <1>;
> + compatible = "rockchip,rk3288-usb-phy";
> + rockchip,grf = <&grf>;
> + };
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 2a436e6..54ab088 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -218,6 +218,13 @@ config PHY_QCOM_IPQ806X_SATA
> depends on OF
> select GENERIC_PHY
>
> +config PHY_ROCKCHIP_RK3288_USB2
> + tristate "Rockchip USB2 RK3288 PHY Driver"
> + depends on ARCH_ROCKCHIP && OF
> + select GENERIC_PHY
> + help
> + Enable this to support the Rockchip USB 2.0 PHY.
> +
> config PHY_ST_SPEAR1310_MIPHY
> tristate "ST SPEAR1310-MIPHY driver"
> select GENERIC_PHY
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index c4590fc..f4f2f79 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -25,6 +25,7 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
> phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
> obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
> obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
> +obj-$(CONFIG_PHY_ROCKCHIP_RK3288_USB2) += phy-rockchip-usb.o
Add this after 'CONFIG_PHY_QCOM_IPQ806X_SATA'.
> obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
> obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
> obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
> diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c
> new file mode 100644
> index 0000000..2586b76
> --- /dev/null
> +++ b/drivers/phy/phy-rockchip-usb.c
> @@ -0,0 +1,179 @@
> +/*
> + * Rockchip usb PHY driver
> + *
> + * Copyright (C) 2014 Roy Li <[email protected]>
> + * Copyright (C) 2014 ROCKCHIP, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +
> +#define ROCKCHIP_RK3288_UOC(n) (0x320 + n * 0x14)
> +
> +#define SIDDQ_MSK (1 << (13 + 16))
> +#define SIDDQ_ON (1 << 13)
> +#define SIDDQ_OFF (0 << 13)
> +
> +enum rk3288_phy_id {
> + RK3288_OTG,
> + RK3288_HOST0,
> + RK3288_HOST1,
> + RK3288_NUM_PHYS,
> +};
> +
> +struct rockchip_usb_phy {
> + struct regmap *reg_base;
> + unsigned int reg_offset;
> + struct clk *clk;
> + struct phy *phy;
> +};
> +
> +static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
> + bool siddq)
> +{
> + return regmap_write(phy->reg_base, phy->reg_offset,
> + SIDDQ_MSK | (siddq ? SIDDQ_ON : SIDDQ_OFF));
> +}
> +
> +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);
Use a MACRO like ON/OFF instead of 1/0?
and then we don't need the comment anymore.
> + if (ret)
> + return ret;
> +
> + clk_disable_unprepare(phy->clk);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int rockchip_usb_phy_power_on(struct phy *_phy)
> +{
> + struct rockchip_usb_phy *phy = phy_get_drvdata(_phy);
> + int ret = 0;
> +
> + ret = clk_prepare_enable(phy->clk);
> + if (ret)
> + return ret;
> +
> + /* Power up usb phy analog blocks by set siddq 0*/
> + ret = rockchip_usb_phy_power(phy, 0);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static struct phy *rockchip_usb_phy_xlate(struct device *dev,
> + struct of_phandle_args *args)
> +{
> + struct rockchip_usb_phy *phy_array = dev_get_drvdata(dev);
> +
> + if (WARN_ON(args->args[0] == 0 || args->args[0] >= RK3288_NUM_PHYS))
> + return ERR_PTR(-ENODEV);
> +
> + return (phy_array + args->args[0])->phy;
> +}
> +
> +static struct phy_ops ops = {
> + .power_on = rockchip_usb_phy_power_on,
> + .power_off = rockchip_usb_phy_power_off,
> + .owner = THIS_MODULE,
> +};
> +
> +static int rockchip_usb_phy_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct rockchip_usb_phy *rk_phy;
> + struct rockchip_usb_phy *phy_array;
> + struct phy_provider *phy_provider;
> + struct regmap *grf;
> + char clk_name[16];
> + int i;
> +
> + grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
> + if (IS_ERR(grf)) {
> + dev_err(&pdev->dev, "Missing rockchip,grf property\n");
> + return PTR_ERR(grf);
> + }
> +
> + phy_array = devm_kzalloc(dev, RK3288_NUM_PHYS * sizeof(*rk_phy),
> + GFP_KERNEL);
> + if (!phy_array)
> + return -ENOMEM;
> +
> + for (i = 0; i < RK3288_NUM_PHYS; i++) {
> + rk_phy = &phy_array[i];
> +
> + rk_phy->reg_base = grf;
> +
> + rk_phy->reg_offset = ROCKCHIP_RK3288_UOC(i);
> +
> + snprintf(clk_name, sizeof(clk_name), "usbphy%d", i);
> + rk_phy->clk = devm_clk_get(dev, clk_name);
> + if (IS_ERR(rk_phy->clk)) {
> + dev_warn(dev, "failed to get clock %s\n", clk_name);
> + rk_phy->clk = NULL;
> + }
> +
> + rk_phy->phy = devm_phy_create(dev, NULL, &ops, NULL);
> + if (IS_ERR(rk_phy->phy)) {
> + dev_err(dev, "failed to create PHY %d\n", i);
> + return PTR_ERR(rk_phy->phy);
> + }
> + phy_set_drvdata(rk_phy->phy, rk_phy);
> + }
> +
> + platform_set_drvdata(pdev, phy_array);
> +
> + phy_provider = devm_of_phy_provider_register(dev,
> + rockchip_usb_phy_xlate);
> + return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +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 = {
Maybe use rockchip_usb_phy_driver is better?
> + .probe = rockchip_usb_phy_probe,
> + .driver = {
> + .name = "rockchip-usb-phy",
> + .owner = THIS_MODULE,
> + .of_match_table = rockchip_usb_phy_dt_ids,
> + },
> +};
> +
> +module_platform_driver(rockchip_usb_driver);
> +
> +MODULE_AUTHOR("Roy Li <[email protected]>");
> +MODULE_DESCRIPTION("Rockchip USB 2.0 PHY driver");
> +MODULE_LICENSE("GPL v2");

2014-12-04 14:45:24

by Heiko Stübner

[permalink] [raw]
Subject: Re: [PATCH] phy: add Rockchip RK3288 USB2 PHY driver.

Hi Roy,

Am Mittwoch, 3. Dezember 2014, 21:46:50 schrieb LiYunzhi:
> From: lyz <[email protected]>
>
> Add a driver for the Rockchip SoC internal USB2.0 PHY.
> This driver currently support RK3288.
>
> Signed-off-by: lyz <[email protected]>
> ---

[...]

> diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c
> new file mode 100644
> index 0000000..2586b76
> --- /dev/null
> +++ b/drivers/phy/phy-rockchip-usb.c
> @@ -0,0 +1,179 @@
> +/*
> + * Rockchip usb PHY driver
> + *
> + * Copyright (C) 2014 Roy Li <[email protected]>
> + * Copyright (C) 2014 ROCKCHIP, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +
> +#define ROCKCHIP_RK3288_UOC(n) (0x320 + n * 0x14)
> +
> +#define SIDDQ_MSK (1 << (13 + 16))
> +#define SIDDQ_ON (1 << 13)
> +#define SIDDQ_OFF (0 << 13)

In the rockchip clock driver [in drivers/clk/rockchip/clk.h] exist a macro
HIWORD_UPDATE that removes the need to declare the write-enable bits
separately.


> +
> +enum rk3288_phy_id {
> + RK3288_OTG,
> + RK3288_HOST0,
> + RK3288_HOST1,
> + RK3288_NUM_PHYS,
> +};
> +
> +struct rockchip_usb_phy {
> + struct regmap *reg_base;
> + unsigned int reg_offset;
> + struct clk *clk;
> + struct phy *phy;
> +};
> +
> +static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
> + bool siddq)
> +{
> + return regmap_write(phy->reg_base, phy->reg_offset,
> + SIDDQ_MSK | (siddq ? SIDDQ_ON : SIDDQ_OFF));

just for my understanding:

You're using the SIDDQ bit, which supposedly "powers down all analog blocks"
for IDDQ testing to control the phy power.

What is the difference to usbotg_disable (bit 4 of uoc_con0) that is supposed
to "power down the USB OTG/HOST block"?

Similarly, where is the difference to usbotg_sleepm [uoc_con2 bit 10] combined
with usbotg_common_on_n [uoc_con0 bit 0]?


Thanks
Heiko

2014-12-05 03:55:07

by Yunzhi Li

[permalink] [raw]
Subject: Re: Re: [PATCH] phy: add Rockchip RK3288 USB2 PHY driver.


Hi Heiko

> Am Mittwoch, 3. Dezember 2014, 21:46:50 schrieb LiYunzhi:
>> +
>> +};
>> +
>> +static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
>> + bool siddq)
>> +{
>> + return regmap_write(phy->reg_base, phy->reg_offset,
>> + SIDDQ_MSK | (siddq ? SIDDQ_ON : SIDDQ_OFF));
> just for my understanding:
>
> You're using the SIDDQ bit, which supposedly "powers down all analog blocks"
> for IDDQ testing to control the phy power.
>
> What is the difference to usbotg_disable (bit 4 of uoc_con0) that is supposed
> to "power down the USB OTG/HOST block"?
>
> Similarly, where is the difference to usbotg_sleepm [uoc_con2 bit 10] combined
> with usbotg_common_on_n [uoc_con0 bit 0]?

SIDDQ: is used to power down the USB block analog function.
usbotg_disable: is used to diable USB digital interface, and USB analog
part is still alive.
The power consuming is total different. Power(SIDDQ) <
Power(usbotg_disable).

usbotg_sleepm is defined in USB Low power mode - L1, this signal could
be used for USB 2.0 Link Power Management (LPM) addendum to the USB 2.0
specification, but our controller doesn't support. So we do not use
sleepm, this bit here just for debug force the transmitter enter the LPM
specific sleep mode.

usbotg_common_on_n: is used to control USB PHY internal PLL. When active
Low, the PLL is still alive in suspend mode, which could output 480M
clock for other IP use.

--------
Roy Li @ Rockchip