linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage
@ 2013-01-10  8:35 Peter Chen
  2013-01-10  8:35 ` [PATCH 2/4] usb: " Peter Chen
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Peter Chen @ 2013-01-10  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

For mxs-phy user i.mx6q, the PHY's clock is controlled by
hardware automatically, the software only needs to enable it
at probe, this clock should be used like below:

- Enable at mxs-phy's probe, and disable at mxs-phy's remove, so
The clk framework doesn't need to know it. But other mxs-phy user
mx28/mx23 may need it, so we give mxs-phy a dummy clock for imx6q.
- During the runtime, we don't need to control it.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 .../devicetree/bindings/clock/imx6q-clock.txt      |    2 --
 Documentation/devicetree/bindings/usb/mxs-phy.txt  |    2 ++
 arch/arm/boot/dts/imx6q.dtsi                       |   10 +++++++---
 arch/arm/mach-imx/clk-imx6q.c                      |    5 +----
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt
index d77b4e6..5666486 100644
--- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt
+++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt
@@ -194,8 +194,6 @@ clocks and IDs.
 	ssi2_ipg		179
 	ssi3_ipg		180
 	rom			181
-	usbphy1			182
-	usbphy2			183
 	ldb_di0_div_3_5		184
 	ldb_di1_div_3_5		185
 	sata_ref		186
diff --git a/Documentation/devicetree/bindings/usb/mxs-phy.txt b/Documentation/devicetree/bindings/usb/mxs-phy.txt
index 5835b27..384e700 100644
--- a/Documentation/devicetree/bindings/usb/mxs-phy.txt
+++ b/Documentation/devicetree/bindings/usb/mxs-phy.txt
@@ -4,10 +4,12 @@ Required properties:
 - compatible: Should be "fsl,imx23-usbphy"
 - reg: Should contain registers location and length
 - interrupts: Should contain phy interrupt
+- The reg offset for PHY clock at anatop
 
 Example:
 usbphy1: usbphy at 020c9000 {
 	compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
 	reg = <0x020c9000 0x1000>;
 	interrupts = <0 44 0x04>;
+	anatop-phy-reg-offset = <0x10>;
 };
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index d6265ca..d958c49 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -518,14 +518,18 @@
 				compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
 				reg = <0x020c9000 0x1000>;
 				interrupts = <0 44 0x04>;
-				clocks = <&clks 182>;
-			};
+				anatop-phy-reg-offset = <0x10>;
+				/* the clk is controllered by hardware */
+				clocks = <&clks 0>;
+	 		};
 
 			usbphy2: usbphy at 020ca000 {
 				compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
 				reg = <0x020ca000 0x1000>;
 				interrupts = <0 45 0x04>;
-				clocks = <&clks 183>;
+				anatop-phy-reg-offset = <0x20>;
+				/* the clk is controllered by hardware */
+				clocks = <&clks 0>;
 			};
 
 			snvs at 020cc000 {
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 7f2c10c..fa62bc9 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -153,7 +153,7 @@ enum mx6q_clks {
 	ssi2, ssi3, uart_ipg, uart_serial, usboh3, usdhc1, usdhc2, usdhc3,
 	usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,
 	pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
-	ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
+	ssi2_ipg, ssi3_ipg, rom, ldb_di0_div_3_5, ldb_di1_div_3_5,
 	sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref,
 	clk_max
 };
@@ -208,9 +208,6 @@ int __init mx6q_clocks_init(void)
 	clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB,	"pll7_usb_host","osc", base + 0x20, 0x3);
 	clk[pll8_mlb]      = imx_clk_pllv3(IMX_PLLV3_MLB,	"pll8_mlb",	"osc", base + 0xd0, 0x0);
 
-	clk[usbphy1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 6);
-	clk[usbphy2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 6);
-
 	clk[sata_ref] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5);
 	clk[pcie_ref] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4);
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] usb: mxs-phy: Change mxs phy clock usage
  2013-01-10  8:35 [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Peter Chen
@ 2013-01-10  8:35 ` Peter Chen
  2013-01-10  8:35 ` [PATCH 3/4] usb: mxs-phy: add set_suspend API Peter Chen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Peter Chen @ 2013-01-10  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

As we mark mxs-phy as dummy clock for i.mx6q, we only need to
enable it at probe, this clock doesn't need to be managed
by clock framework.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/otg/mxs-phy.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c
index 7630272..7dca384 100644
--- a/drivers/usb/otg/mxs-phy.c
+++ b/drivers/usb/otg/mxs-phy.c
@@ -20,6 +20,9 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
 
 #define DRIVER_NAME "mxs_phy"
 
@@ -108,6 +111,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
 	void __iomem *base;
 	struct clk *clk;
 	struct mxs_phy *mxs_phy;
+	struct regmap *anatop;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
@@ -146,6 +150,46 @@ static int mxs_phy_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, &mxs_phy->phy);
 
+	/*
+	 * At mx6x, USB PHY PLL and its output gate is controlled by hardware.
+	 * It just needs to open at init, if the usb device is
+	 * in suspend, it will close related PLL automatically.
+	 */
+
+	anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
+
+#define CTRL_SET				0x4
+#define CTRL_CLR				0x8
+
+#define BM_ANADIG_USB_PLL_480_CTRL_BYPASS		(1 << 16)
+#define BM_ANADIG_USB_PLL_480_CTRL_ENABLE		(1 << 13)
+#define BM_ANADIG_USB_PLL_480_CTRL_POWER		(1 << 12)
+#define BM_ANADIG_USB_PLL_480_CTRL_EN_USB_CLKS		(1 << 6)
+
+	if (!IS_ERR(anatop)) {
+		struct device *dev = &pdev->dev;
+		struct device_node *np = dev->of_node;
+		u32 phy_reg_offset;
+		int ret;
+
+		ret = of_property_read_u32(np, "anatop-phy-reg-offset",
+					   &phy_reg_offset);
+		if (ret) {
+			dev_err(dev, "no anatop-phy-reg-offset property set\n");
+			return -EINVAL;
+		}
+
+		regmap_write(anatop, phy_reg_offset + 0x8,
+				BM_ANADIG_USB_PLL_480_CTRL_BYPASS);
+		regmap_write(anatop, phy_reg_offset + 0x4,
+				BM_ANADIG_USB_PLL_480_CTRL_ENABLE
+				| BM_ANADIG_USB_PLL_480_CTRL_POWER
+				| BM_ANADIG_USB_PLL_480_CTRL_EN_USB_CLKS);
+
+	} else {
+		pr_warn("failed to find fsl,imx6q-anatop regmap\n");
+	}
+
 	return 0;
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] usb: mxs-phy: add set_suspend API
  2013-01-10  8:35 [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Peter Chen
  2013-01-10  8:35 ` [PATCH 2/4] usb: " Peter Chen
@ 2013-01-10  8:35 ` Peter Chen
  2013-01-10  8:35 ` [PATCH 4/4] usb: chipidea: imx: Add system suspend/resume API Peter Chen
  2013-01-11  2:25 ` [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Shawn Guo
  3 siblings, 0 replies; 6+ messages in thread
From: Peter Chen @ 2013-01-10  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

It needs to call set_suspend during USB suspend/resume

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/otg/mxs-phy.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c
index 7dca384..40643c9 100644
--- a/drivers/usb/otg/mxs-phy.c
+++ b/drivers/usb/otg/mxs-phy.c
@@ -79,6 +79,25 @@ static void mxs_phy_shutdown(struct usb_phy *phy)
 	clk_disable_unprepare(mxs_phy->clk);
 }
 
+static int mxs_phy_suspend(struct usb_phy *x, int suspend)
+{
+	struct mxs_phy *mxs_phy = to_mxs_phy(x);
+
+	if (suspend) {
+		writel_relaxed(0xffffffff, x->io_priv + HW_USBPHY_PWD);
+		writel_relaxed(BM_USBPHY_CTRL_CLKGATE,
+			x->io_priv + HW_USBPHY_CTRL_SET);
+		clk_disable_unprepare(mxs_phy->clk);
+	} else {
+		clk_prepare_enable(mxs_phy->clk);
+		writel_relaxed(BM_USBPHY_CTRL_CLKGATE,
+			x->io_priv + HW_USBPHY_CTRL_CLR);
+		writel_relaxed(0, x->io_priv + HW_USBPHY_PWD);
+	}
+
+	return 0;
+}
+
 static int mxs_phy_on_connect(struct usb_phy *phy,
 		enum usb_device_speed speed)
 {
@@ -141,6 +160,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
 	mxs_phy->phy.label		= DRIVER_NAME;
 	mxs_phy->phy.init		= mxs_phy_init;
 	mxs_phy->phy.shutdown		= mxs_phy_shutdown;
+	mxs_phy->phy.set_suspend	= mxs_phy_suspend;
 	mxs_phy->phy.notify_connect	= mxs_phy_on_connect;
 	mxs_phy->phy.notify_disconnect	= mxs_phy_on_disconnect;
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] usb: chipidea: imx: Add system suspend/resume API
  2013-01-10  8:35 [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Peter Chen
  2013-01-10  8:35 ` [PATCH 2/4] usb: " Peter Chen
  2013-01-10  8:35 ` [PATCH 3/4] usb: mxs-phy: add set_suspend API Peter Chen
@ 2013-01-10  8:35 ` Peter Chen
  2013-01-11  2:25 ` [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Shawn Guo
  3 siblings, 0 replies; 6+ messages in thread
From: Peter Chen @ 2013-01-10  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

During the system suspend/resume procedure, the USB also
needs to go suspend/resume procedure, this patch adds
related APIs. It is tested at i.mx6q sabrelite. Meanwhile,
it fixes the bug that the USB will out of work after
system suspend/resume.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
---
 drivers/usb/chipidea/bits.h        |    1 +
 drivers/usb/chipidea/ci13xxx_imx.c |   61 ++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index ba9c6ef..d1467bb 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -47,6 +47,7 @@
 #define PORTSC_FPR            BIT(6)
 #define PORTSC_SUSP           BIT(7)
 #define PORTSC_HSP            BIT(9)
+#define PORTSC_PHCD           BIT(23) /* phy suspend mode */
 #define PORTSC_PTC            (0x0FUL << 16)
 
 /* DEVLC */
diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c
index 342eab0..dd257b1 100644
--- a/drivers/usb/chipidea/ci13xxx_imx.c
+++ b/drivers/usb/chipidea/ci13xxx_imx.c
@@ -25,6 +25,7 @@
 #include <linux/mfd/syscon.h>
 
 #include "ci.h"
+#include "bits.h"
 #include "ci13xxx_imx.h"
 
 #define pdev_to_phy(pdev) \
@@ -321,6 +322,63 @@ static int ci13xxx_imx_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int ci13xxx_imx_suspend(struct device *dev)
+{
+	struct ci13xxx_imx_data *data =
+		platform_get_drvdata(to_platform_device(dev));
+	struct platform_device *plat_ci;
+	struct ci13xxx	*ci;
+
+	plat_ci = data->ci_pdev;
+	ci = platform_get_drvdata(plat_ci);
+
+	hw_write(ci, OP_PORTSC, PORTSC_PHCD, 1);
+
+	if (data->phy)
+		usb_phy_set_suspend(data->phy, 1);
+
+	clk_disable_unprepare(data->clk);
+
+	return 0;
+}
+
+static int ci13xxx_imx_resume(struct device *dev)
+{
+	int ret;
+	struct ci13xxx_imx_data *data =
+		platform_get_drvdata(to_platform_device(dev));
+	struct platform_device *plat_ci;
+	struct ci13xxx	*ci;
+
+	plat_ci = data->ci_pdev;
+	ci = platform_get_drvdata(plat_ci);
+
+	ret = clk_prepare_enable(data->clk);
+	if (ret) {
+		dev_err(dev,
+			"Failed to prepare or enable clock, err=%d\n", ret);
+		return ret;
+	}
+
+	if (hw_read(ci, OP_PORTSC, PORTSC_PHCD)) {
+		hw_write(ci, OP_PORTSC, PORTSC_PHCD, 0);
+		/* Some clks sync between Controller and USB PHY */
+		mdelay(1);
+	}
+
+	if (data->phy)
+		usb_phy_set_suspend(data->phy, 0);
+
+	return ret;
+}
+
+static const struct dev_pm_ops ci13xxx_imx_pm_ops = {
+	.suspend	= ci13xxx_imx_suspend,
+	.resume		= ci13xxx_imx_resume,
+};
+#endif
+
 static const struct of_device_id ci13xxx_imx_dt_ids[] = {
 	{ .compatible = "fsl,imx27-usb", },
 	{ /* sentinel */ }
@@ -334,6 +392,9 @@ static struct platform_driver ci13xxx_imx_driver = {
 		.name = "imx_usb",
 		.owner = THIS_MODULE,
 		.of_match_table = ci13xxx_imx_dt_ids,
+#ifdef CONFIG_PM
+		.pm	= &ci13xxx_imx_pm_ops,
+#endif
 	 },
 };
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage
  2013-01-10  8:35 [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Peter Chen
                   ` (2 preceding siblings ...)
  2013-01-10  8:35 ` [PATCH 4/4] usb: chipidea: imx: Add system suspend/resume API Peter Chen
@ 2013-01-11  2:25 ` Shawn Guo
  2013-01-11  3:06   ` Chen Peter-B29397
  3 siblings, 1 reply; 6+ messages in thread
From: Shawn Guo @ 2013-01-11  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jan 10, 2013 at 04:35:51PM +0800, Peter Chen wrote:
> For mxs-phy user i.mx6q, the PHY's clock is controlled by
> hardware automatically, the software only needs to enable it
> at probe, this clock should be used like below:
> 
> - Enable at mxs-phy's probe, and disable at mxs-phy's remove, so
> The clk framework doesn't need to know it. But other mxs-phy user
> mx28/mx23 may need it, so we give mxs-phy a dummy clock for imx6q.
> - During the runtime, we don't need to control it.
> 
Turning it into a dummy clock, you will have no way to maintain the
use count.  It could possibly cause parent clock be turned off while
usbphy is in use.

Let's try to find some other way.

Shawn

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage
  2013-01-11  2:25 ` [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Shawn Guo
@ 2013-01-11  3:06   ` Chen Peter-B29397
  0 siblings, 0 replies; 6+ messages in thread
From: Chen Peter-B29397 @ 2013-01-11  3:06 UTC (permalink / raw)
  To: linux-arm-kernel

 
> On Thu, Jan 10, 2013 at 04:35:51PM +0800, Peter Chen wrote:
> > For mxs-phy user i.mx6q, the PHY's clock is controlled by
> > hardware automatically, the software only needs to enable it
> > at probe, this clock should be used like below:
> >
> > - Enable at mxs-phy's probe, and disable at mxs-phy's remove, so
> > The clk framework doesn't need to know it. But other mxs-phy user
> > mx28/mx23 may need it, so we give mxs-phy a dummy clock for imx6q.
> > - During the runtime, we don't need to control it.
> >
> Turning it into a dummy clock, you will have no way to maintain the
> use count.  It could possibly cause parent clock be turned off while
> usbphy is in use.
> 
> Let's try to find some other way.
> 
I will keep the phyclk unchanged, but just let it control a reserved bit
In that case, the clk framework will know USB is using PLL.

Meanwhile, the real USB PHY clk gate will only be open one time at
phy driver's probe.

> Shawn

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-01-11  3:06 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-10  8:35 [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Peter Chen
2013-01-10  8:35 ` [PATCH 2/4] usb: " Peter Chen
2013-01-10  8:35 ` [PATCH 3/4] usb: mxs-phy: add set_suspend API Peter Chen
2013-01-10  8:35 ` [PATCH 4/4] usb: chipidea: imx: Add system suspend/resume API Peter Chen
2013-01-11  2:25 ` [PATCH 1/4] ARM: dts: mxs-phy: Change mxs phy clock usage Shawn Guo
2013-01-11  3:06   ` Chen Peter-B29397

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).