All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250
@ 2012-12-18 14:43 Vivek Gautam
  2012-12-18 14:43 ` [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer Vivek Gautam
                   ` (4 more replies)
  0 siblings, 5 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-18 14:43 UTC (permalink / raw)
  To: linux-usb
  Cc: devicetree-discuss, linux-kernel, linux-samsung-soc, gregkh,
	balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri

Changes from v4:
 - Moved architecture side changes out of this patch-set.
 - Added support for multiple usbphy phandle parsing and
   doing all pmu_isolation() and phy_cfg_sel() related changes
   in samsung-usbphy driver only instead of architecture
   as in v4 patch-set.
 - Removed unnecessary multi line definitions for macros.

Changes from v3:
 - Moved enums S5P_USB_PHY_DEVICE, S5P_USB_PHY_HOST from machine to file
   include/linux/usb/samsung_usb_phy.h as USB_PHY_TYPE_DEVICE and
   USB_PHY_TYPE_HOST to make it more generic. Further resolve its
   dependencies.
 - Introduced a function 'samsung_usbphy_set_type()' which takes
   care of setting up the phy_type: HOST/DEVICE. This function
   can be called by host/otg drivers to setup phy_type prior to
   handling the respective PHYs.
 - Added an error-path for HOST type phy in s5p_usb_phy_pmu_isolation()
   for 'mach-s3c64xx'.
 - Moving to PHY driver as default for ehci-s5p and ohci-exynos, and only
   when failed fall back to plat-data.
 - Added samsung_usbphy_set_type() prior to doing usb_phy_init() or
   usb_phy_shutdown() so that appropriate PHY gets init or shutdown.

Based on patches for samsung-usbphy driver:
 1)http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/134476.html
 2)https://lkml.org/lkml/2012/12/18/187
 
Vivek Gautam (4):
  ARM: EXYNOS: Update & move usb-phy types to generic include layer
  usb: phy: samsung: Add host phy support to samsung-phy driver
  USB: ehci-s5p: Add phy driver support
  USB: ohci-exynos: Add phy driver support

 .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
 drivers/usb/host/ehci-s5p.c                        |   71 +++-
 drivers/usb/host/ohci-exynos.c                     |   71 +++-
 drivers/usb/phy/Kconfig                            |    2 +-
 drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
 include/linux/usb/samsung_usb_phy.h                |   29 ++
 6 files changed, 570 insertions(+), 93 deletions(-)
 create mode 100644 include/linux/usb/samsung_usb_phy.h

-- 
1.7.6.5


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

* [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
  2012-12-18 14:43 [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250 Vivek Gautam
@ 2012-12-18 14:43 ` Vivek Gautam
  2012-12-19  5:38     ` Vivek Gautam
  2012-12-19 21:48     ` Doug Anderson
  2012-12-18 14:43 ` [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver Vivek Gautam
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-18 14:43 UTC (permalink / raw)
  To: linux-usb
  Cc: devicetree-discuss, linux-kernel, linux-samsung-soc, gregkh,
	balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri

Updating the names of usb-phy types to more generic names:
USB_PHY_TYPE_DEIVCE & USB_PHY_TYPE_HOST; and further update
its dependencies.

Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
---
 drivers/usb/host/ehci-s5p.c         |    9 +++++----
 drivers/usb/host/ohci-exynos.c      |    9 +++++----
 include/linux/usb/samsung_usb_phy.h |   16 ++++++++++++++++
 3 files changed, 26 insertions(+), 8 deletions(-)
 create mode 100644 include/linux/usb/samsung_usb_phy.h

diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index 319dcfa..46ca5ef 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/of_gpio.h>
 #include <linux/platform_data/usb-ehci-s5p.h>
+#include <linux/usb/samsung_usb_phy.h>
 #include <plat/usb-phy.h>
 
 #define EHCI_INSNREG00(base)			(base + 0x90)
@@ -164,7 +165,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
 	}
 
 	if (pdata->phy_init)
-		pdata->phy_init(pdev, S5P_USB_PHY_HOST);
+		pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 
 	ehci = hcd_to_ehci(hcd);
 	ehci->caps = hcd->regs;
@@ -198,7 +199,7 @@ static int s5p_ehci_remove(struct platform_device *pdev)
 	usb_remove_hcd(hcd);
 
 	if (pdata && pdata->phy_exit)
-		pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
+		pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 
 	clk_disable_unprepare(s5p_ehci->clk);
 
@@ -229,7 +230,7 @@ static int s5p_ehci_suspend(struct device *dev)
 	rc = ehci_suspend(hcd, do_wakeup);
 
 	if (pdata && pdata->phy_exit)
-		pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
+		pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 
 	clk_disable_unprepare(s5p_ehci->clk);
 
@@ -246,7 +247,7 @@ static int s5p_ehci_resume(struct device *dev)
 	clk_prepare_enable(s5p_ehci->clk);
 
 	if (pdata && pdata->phy_init)
-		pdata->phy_init(pdev, S5P_USB_PHY_HOST);
+		pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 
 	/* DMA burst Enable */
 	writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index aa3b884..804fb62 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-exynos.h>
+#include <linux/usb/samsung_usb_phy.h>
 #include <plat/usb-phy.h>
 
 struct exynos_ohci_hcd {
@@ -153,7 +154,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	}
 
 	if (pdata->phy_init)
-		pdata->phy_init(pdev, S5P_USB_PHY_HOST);
+		pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 
 	ohci = hcd_to_ohci(hcd);
 	ohci_hcd_init(ohci);
@@ -184,7 +185,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
 	usb_remove_hcd(hcd);
 
 	if (pdata && pdata->phy_exit)
-		pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
+		pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -229,7 +230,7 @@ static int exynos_ohci_suspend(struct device *dev)
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	if (pdata && pdata->phy_exit)
-		pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
+		pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -249,7 +250,7 @@ static int exynos_ohci_resume(struct device *dev)
 	clk_prepare_enable(exynos_ohci->clk);
 
 	if (pdata && pdata->phy_init)
-		pdata->phy_init(pdev, S5P_USB_PHY_HOST);
+		pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
 
 	ohci_resume(hcd, false);
 
diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
new file mode 100644
index 0000000..9167826
--- /dev/null
+++ b/include/linux/usb/samsung_usb_phy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ *		http://www.samsung.com/
+ *
+ * Defines phy types for samsung usb phy controllers - HOST or DEIVCE.
+ *
+ * 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, or (at your
+ * option) any later version.
+ */
+
+enum samsung_usb_phy_type {
+	USB_PHY_TYPE_DEVICE,
+	USB_PHY_TYPE_HOST,
+};
-- 
1.7.6.5


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

* [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
  2012-12-18 14:43 [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250 Vivek Gautam
  2012-12-18 14:43 ` [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer Vivek Gautam
@ 2012-12-18 14:43 ` Vivek Gautam
  2012-12-19  5:40     ` Vivek Gautam
  2012-12-19 23:01   ` Doug Anderson
  2012-12-18 14:43 ` [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support Vivek Gautam
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-18 14:43 UTC (permalink / raw)
  To: linux-usb
  Cc: devicetree-discuss, linux-kernel, linux-samsung-soc, gregkh,
	balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri

This patch adds host phy support to samsung-usbphy.c and
further adds support for samsung's exynos5250 usb-phy.

Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
---
 .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
 drivers/usb/phy/Kconfig                            |    2 +-
 drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
 include/linux/usb/samsung_usb_phy.h                |   13 +
 4 files changed, 454 insertions(+), 51 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
index a7b28b2..2ec5400 100644
--- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -1,23 +1,38 @@
 * Samsung's usb phy transceiver
 
-The Samsung's phy transceiver is used for controlling usb otg phy for
-s3c-hsotg usb device controller.
+The Samsung's phy transceiver is used for controlling usb phy for
+s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
+across Samsung SOCs.
 TODO: Adding the PHY binding with controller(s) according to the under
 developement generic PHY driver.
 
 Required properties:
+
+Exynos4210:
 - compatible : should be "samsung,exynos4210-usbphy"
 - reg : base physical address of the phy registers and length of memory mapped
 	region.
 
+Exynos5250:
+- compatible : should be "samsung,exynos5250-usbphy"
+- reg : base physical address of the phy registers and length of memory mapped
+	region.
+
 Optional properties:
 - samsung,usb-phyhandle : should point to usb-phyhandle sub-node which provides
 			binding data to enable/disable device PHY handled by
-			PMU register.
+			PMU register; or to configure usb2.0 phy handled by
+			SYSREG.
 
 			Required properties:
 			- compatible : should be "samsung,usbdev-phyctrl" for
-					DEVICE type phy.
+				       DEVICE type phy; or
+				       should be "samsung,usbhost-phyctrl" for
+				       HOST type phy; or
+				       should be "samsung,usb-phycfg" for
+				       USB2.0 PHY_CFG.
 			- samsung,phyhandle-reg: base physical address of
-						PHY_CONTROL register in PMU.
+						 PHY_CONTROL register in PMU;
+						 or USB2.0 PHY_CFG register
+						 in SYSREG.
 - samsung,enable-mask : should be '1'
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 17ad743..13c0eaf 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -47,7 +47,7 @@ config USB_RCAR_PHY
 
 config SAMSUNG_USBPHY
 	bool "Samsung USB PHY controller Driver"
-	depends on USB_S3C_HSOTG
+	depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
 	select USB_OTG_UTILS
 	help
 	  Enable this to support Samsung USB phy controller for samsung
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
index 4ceabe3..621348a 100644
--- a/drivers/usb/phy/samsung-usbphy.c
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -5,7 +5,8 @@
  *
  * Author: Praveen Paneri <p.paneri@samsung.com>
  *
- * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
+ * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
+ * OHCI-EXYNOS controllers.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -24,7 +25,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <linux/usb/otg.h>
+#include <linux/usb/samsung_usb_phy.h>
 #include <linux/platform_data/samsung-usbphy.h>
 
 /* Register definitions */
@@ -56,6 +57,103 @@
 #define RSTCON_HLINK_SWRST			(0x1 << 1)
 #define RSTCON_SWRST				(0x1 << 0)
 
+/* EXYNOS5 */
+#define EXYNOS5_PHY_HOST_CTRL0			(0x00)
+
+#define HOST_CTRL0_PHYSWRSTALL			(0x1 << 31)
+
+#define HOST_CTRL0_REFCLKSEL_MASK		(0x3)
+#define HOST_CTRL0_REFCLKSEL_XTAL		(0x0 << 19)
+#define HOST_CTRL0_REFCLKSEL_EXTL		(0x1 << 19)
+#define HOST_CTRL0_REFCLKSEL_CLKCORE		(0x2 << 19)
+
+#define HOST_CTRL0_FSEL_MASK			(0x7 << 16)
+#define HOST_CTRL0_FSEL(_x)			((_x) << 16)
+#define HOST_CTRL0_FSEL_CLKSEL_50M		(0x7)
+#define HOST_CTRL0_FSEL_CLKSEL_24M		(0x5)
+#define HOST_CTRL0_FSEL_CLKSEL_20M		(0x4)
+#define HOST_CTRL0_FSEL_CLKSEL_19200K		(0x3)
+#define HOST_CTRL0_FSEL_CLKSEL_12M		(0x2)
+#define HOST_CTRL0_FSEL_CLKSEL_10M		(0x1)
+#define HOST_CTRL0_FSEL_CLKSEL_9600K		(0x0)
+
+#define HOST_CTRL0_TESTBURNIN			(0x1 << 11)
+#define HOST_CTRL0_RETENABLE			(0x1 << 10)
+#define HOST_CTRL0_COMMONON_N			(0x1 << 9)
+#define HOST_CTRL0_SIDDQ			(0x1 << 6)
+#define HOST_CTRL0_FORCESLEEP			(0x1 << 5)
+#define HOST_CTRL0_FORCESUSPEND			(0x1 << 4)
+#define HOST_CTRL0_WORDINTERFACE		(0x1 << 3)
+#define HOST_CTRL0_UTMISWRST			(0x1 << 2)
+#define HOST_CTRL0_LINKSWRST			(0x1 << 1)
+#define HOST_CTRL0_PHYSWRST			(0x1 << 0)
+
+#define EXYNOS5_PHY_HOST_TUNE0			(0x04)
+
+#define EXYNOS5_PHY_HSIC_CTRL1			(0x10)
+
+#define EXYNOS5_PHY_HSIC_TUNE1			(0x14)
+
+#define EXYNOS5_PHY_HSIC_CTRL2			(0x20)
+
+#define EXYNOS5_PHY_HSIC_TUNE2			(0x24)
+
+#define HSIC_CTRL_REFCLKSEL_MASK		(0x3)
+#define HSIC_CTRL_REFCLKSEL			(0x2 << 23)
+
+#define HSIC_CTRL_REFCLKDIV_MASK		(0x7f)
+#define HSIC_CTRL_REFCLKDIV(_x)			((_x) << 16)
+#define HSIC_CTRL_REFCLKDIV_12			(0x24 << 16)
+#define HSIC_CTRL_REFCLKDIV_15			(0x1c << 16)
+#define HSIC_CTRL_REFCLKDIV_16			(0x1a << 16)
+#define HSIC_CTRL_REFCLKDIV_19_2		(0x15 << 16)
+#define HSIC_CTRL_REFCLKDIV_20			(0x14)
+
+#define HSIC_CTRL_SIDDQ				(0x1 << 6)
+#define HSIC_CTRL_FORCESLEEP			(0x1 << 5)
+#define HSIC_CTRL_FORCESUSPEND			(0x1 << 4)
+#define HSIC_CTRL_WORDINTERFACE			(0x1 << 3)
+#define HSIC_CTRL_UTMISWRST			(0x1 << 2)
+#define HSIC_CTRL_PHYSWRST			(0x1 << 0)
+
+#define EXYNOS5_PHY_HOST_EHCICTRL		(0x30)
+
+#define HOST_EHCICTRL_ENAINCRXALIGN		(0x1 << 29)
+#define HOST_EHCICTRL_ENAINCR4			(0x1 << 28)
+#define HOST_EHCICTRL_ENAINCR8			(0x1 << 27)
+#define HOST_EHCICTRL_ENAINCR16			(0x1 << 26)
+
+#define EXYNOS5_PHY_HOST_OHCICTRL		(0x34)
+
+#define HOST_OHCICTRL_SUSPLGCY			(0x1 << 3)
+#define HOST_OHCICTRL_APPSTARTCLK		(0x1 << 2)
+#define HOST_OHCICTRL_CNTSEL			(0x1 << 1)
+#define HOST_OHCICTRL_CLKCKTRST			(0x1 << 0)
+
+#define EXYNOS5_PHY_OTG_SYS			(0x38)
+
+#define OTG_SYS_PHYLINK_SWRESET			(0x1 << 14)
+#define OTG_SYS_LINKSWRST_UOTG			(0x1 << 13)
+#define OTG_SYS_PHY0_SWRST			(0x1 << 12)
+
+#define OTG_SYS_REFCLKSEL_MASK			(0x3 << 9)
+#define OTG_SYS_REFCLKSEL_XTAL			(0x0 << 9)
+#define OTG_SYS_REFCLKSEL_EXTL			(0x1 << 9)
+#define OTG_SYS_REFCLKSEL_CLKCORE		(0x2 << 9)
+
+#define OTG_SYS_IDPULLUP_UOTG			(0x1 << 8)
+#define OTG_SYS_COMMON_ON			(0x1 << 7)
+
+#define OTG_SYS_FSEL_MASK			(0x7 << 4)
+#define OTG_SYS_FSEL(_x)			((_x) << 4)
+
+#define OTG_SYS_FORCESLEEP			(0x1 << 3)
+#define OTG_SYS_OTGDISABLE			(0x1 << 2)
+#define OTG_SYS_SIDDQ_UOTG			(0x1 << 1)
+#define OTG_SYS_FORCESUSPEND			(0x1 << 0)
+
+#define EXYNOS5_PHY_OTG_TUNE			(0x40)
+
 #ifndef MHZ
 #define MHZ (1000*1000)
 #endif
@@ -63,6 +161,7 @@
 enum samsung_cpu_type {
 	TYPE_S3C64XX,
 	TYPE_EXYNOS4210,
+	TYPE_EXYNOS5250,
 };
 
 /*
@@ -73,9 +172,13 @@ enum samsung_cpu_type {
  * @clk: usb phy clock
  * @regs: usb phy register memory base
  * @devctrl_reg: usb device phy-control pmu register memory base
+ * @hostctrl_reg: usb host phy-control pmu register memory base
+ * @phycfg_reg: usb2.0 phy-cfg system register memory base
  * @en_mask: enable mask
  * @ref_clk_freq: reference clock frequency selection
  * @cpu_type: machine identifier
+ * @phy_type: It keeps track of the PHY type.
+ * @host_usage: host_phy usage count.
  */
 struct samsung_usbphy {
 	struct usb_phy	phy;
@@ -84,9 +187,13 @@ struct samsung_usbphy {
 	struct clk	*clk;
 	void __iomem	*regs;
 	void __iomem	*devctrl_reg;
+	void __iomem	*hostctrl_reg;
+	void __iomem	*phycfg_reg;
 	u32		en_mask;
 	int		ref_clk_freq;
 	int		cpu_type;
+	enum samsung_usb_phy_type phy_type;
+	atomic_t	host_usage;
 };
 
 #define phy_to_sphy(x)		container_of((x), struct samsung_usbphy, phy)
@@ -96,26 +203,49 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
 	struct device_node *usb_phyctrl;
 	u32 reg;
 	int lenp;
+	int count = 0;
 
 	if (!sphy->dev->of_node) {
 		sphy->devctrl_reg = NULL;
 		return -ENODEV;
 	}
 
-	if (of_get_property(sphy->dev->of_node, "samsung,usb-phyhandle", &lenp)) {
-		usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
-						"samsung,usb-phyhandle", 0);
-		if (!usb_phyctrl) {
-			dev_warn(sphy->dev, "Can't get usb-phy handle\n");
-			sphy->devctrl_reg = NULL;
-		}
-
-		of_property_read_u32(usb_phyctrl, "samsung,phyhandle-reg", &reg);
+	if (of_get_property(sphy->dev->of_node,
+			"samsung,usb-phyhandle", &lenp)) {
+		do {
+			usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
+							"samsung,usb-phyhandle",
+							count++);
+			if (!usb_phyctrl) {
+				dev_warn(sphy->dev,
+					"Can't get usb-phy handle\n");
+				sphy->devctrl_reg = NULL;
+			}
+
+			of_property_read_u32(usb_phyctrl,
+					"samsung,phyhandle-reg", &reg);
+
+			/*
+			 * Considering here the maximum number of configurable
+			 * register settings: DEVICE_PHY_CONTROL
+			 *		      HOST_PHY_CONTROL
+			 *		      PHY20_CFG
+			 */
+			if (of_device_is_compatible(usb_phyctrl,
+						"samsung,usbdev-phyctrl"))
+				sphy->devctrl_reg = ioremap(reg, SZ_4);
+			else if (of_device_is_compatible(usb_phyctrl,
+						"samsung,usbhost-phyctrl"))
+				sphy->hostctrl_reg = ioremap(reg, SZ_4);
+			else if (of_device_is_compatible(usb_phyctrl,
+						"samsung,usb-phycfg"))
+				sphy->phycfg_reg = ioremap(reg, SZ_4);
+
+			of_property_read_u32(sphy->dev->of_node,
+					"samsung,enable-mask", &sphy->en_mask);
+		} while (of_parse_phandle(sphy->dev->of_node,
+				"samsung,usb-phyhandle", count));
 
-		sphy->devctrl_reg = ioremap(reg, SZ_4);
-
-		of_property_read_u32(sphy->dev->of_node, "samsung,enable-mask",
-							&sphy->en_mask);
 		of_node_put(usb_phyctrl);
 	} else {
 		dev_warn(sphy->dev, "Can't get usb-phy handle\n");
@@ -129,13 +259,18 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
  * Set isolation here for phy.
  * SOCs control this by controlling corresponding PMU registers
  */
-static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
+static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy,
+							int on, int type)
 {
-	void __iomem *usb_phyctrl_reg;
+	void __iomem *usb_phyctrl_reg = NULL;
 	u32 en_mask = sphy->en_mask;
 	u32 reg;
 
-	usb_phyctrl_reg = sphy->devctrl_reg;
+	if (type == USB_PHY_TYPE_DEVICE) {
+		usb_phyctrl_reg = sphy->devctrl_reg;
+	} else if (type == USB_PHY_TYPE_HOST) {
+		usb_phyctrl_reg = sphy->hostctrl_reg;
+	}
 
 	if (!usb_phyctrl_reg) {
 		dev_warn(sphy->dev, "Can't set pmu isolation\n");
@@ -151,6 +286,47 @@ static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
 }
 
 /*
+ * Configure the mode of working og usb-phy here: HOST/DEVICE.
+ * SOCs control this by controlling corresponding system register
+ */
+static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy, int type)
+{
+	void __iomem *usb_phycfg_reg;
+	u32 en_mask = sphy->en_mask;
+	u32 reg;
+
+	usb_phycfg_reg = sphy->phycfg_reg;
+
+	if (!usb_phycfg_reg) {
+		dev_warn(sphy->dev, "Can't select specified phy mode\n");
+		return;
+	}
+
+	reg = readl(usb_phycfg_reg);
+
+	if (type == USB_PHY_TYPE_DEVICE)
+		writel(reg & ~en_mask, usb_phycfg_reg);
+	else if (type == USB_PHY_TYPE_HOST)
+		writel(reg | en_mask, usb_phycfg_reg);
+}
+
+/*
+ * PHYs are different for USB Device and USB Host. Controllers can make
+ * sure that the correct PHY type is selected by calling this function
+ * before any PHY operation.
+ */
+int samsung_usbphy_set_type(struct usb_phy *phy,
+				enum samsung_usb_phy_type phy_type)
+{
+	struct samsung_usbphy *sphy = phy_to_sphy(phy);
+
+	if (sphy->phy_type != phy_type)
+		sphy->phy_type = phy_type;
+
+	return 0;
+}
+
+/*
  * Returns reference clock frequency selection value
  */
 static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
@@ -158,34 +334,178 @@ static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
 	struct clk *ref_clk;
 	int refclk_freq = 0;
 
-	ref_clk = clk_get(sphy->dev, "xusbxti");
+	if (sphy->cpu_type == TYPE_EXYNOS5250)
+		ref_clk = clk_get(sphy->dev, "ext_xtal");
+	else
+		ref_clk = clk_get(sphy->dev, "xusbxti");
 	if (IS_ERR(ref_clk)) {
 		dev_err(sphy->dev, "Failed to get reference clock\n");
 		return PTR_ERR(ref_clk);
 	}
 
-	switch (clk_get_rate(ref_clk)) {
-	case 12 * MHZ:
-		refclk_freq = PHYCLK_CLKSEL_12M;
-		break;
-	case 24 * MHZ:
-		refclk_freq = PHYCLK_CLKSEL_24M;
-		break;
-	case 48 * MHZ:
-		refclk_freq = PHYCLK_CLKSEL_48M;
-		break;
-	default:
-		if (sphy->cpu_type == TYPE_S3C64XX)
-			refclk_freq = PHYCLK_CLKSEL_48M;
-		else
+	if (sphy->cpu_type == TYPE_EXYNOS5250) {
+		/* set clock frequency for PLL */
+		switch (clk_get_rate(ref_clk)) {
+		case 96 * 100000:
+			refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
+			break;
+		case 10 * MHZ:
+			refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_10M;
+			break;
+		case 12 * MHZ:
+			refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_12M;
+			break;
+		case 192 * 100000:
+			refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_19200K;
+			break;
+		case 20 * MHZ:
+			refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_20M;
+			break;
+		case 50 * MHZ:
+			refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_50M;
+			break;
+		case 24 * MHZ:
+		default:
+			/* default reference clock */
+			refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_24M;
+			break;
+		}
+	} else {
+		switch (clk_get_rate(ref_clk)) {
+		case 12 * MHZ:
+			refclk_freq = PHYCLK_CLKSEL_12M;
+			break;
+		case 24 * MHZ:
 			refclk_freq = PHYCLK_CLKSEL_24M;
-		break;
+			break;
+		case 48 * MHZ:
+			refclk_freq = PHYCLK_CLKSEL_48M;
+			break;
+		default:
+			if (sphy->cpu_type == TYPE_S3C64XX)
+				refclk_freq = PHYCLK_CLKSEL_48M;
+			else
+				refclk_freq = PHYCLK_CLKSEL_24M;
+			break;
+		}
 	}
 	clk_put(ref_clk);
 
 	return refclk_freq;
 }
 
+static int exynos5_phyhost_is_on(void *regs)
+{
+	u32 reg;
+
+	reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
+
+	return !(reg & HOST_CTRL0_SIDDQ);
+}
+
+static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phyclk = sphy->ref_clk_freq;
+	u32 phyhost;
+	u32 phyotg;
+	u32 phyhsic;
+	u32 ehcictrl;
+	u32 ohcictrl;
+
+	atomic_inc(&sphy->host_usage);
+
+	if (exynos5_phyhost_is_on(regs)) {
+		dev_info(sphy->dev, "Already power on PHY\n");
+		return;
+	}
+
+	/* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */
+	samsung_usbphy_cfg_sel(sphy, USB_PHY_TYPE_HOST);
+
+	/* Host configuration */
+	phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
+
+	/* phy reference clock configuration */
+	phyhost &= ~HOST_CTRL0_FSEL_MASK;
+	phyhost |= HOST_CTRL0_FSEL(phyclk);
+
+	/* host phy reset */
+	phyhost &= ~(HOST_CTRL0_PHYSWRST |
+			HOST_CTRL0_PHYSWRSTALL |
+			HOST_CTRL0_SIDDQ |
+			/* Enable normal mode of operation */
+			HOST_CTRL0_FORCESUSPEND |
+			HOST_CTRL0_FORCESLEEP);
+
+	/* Link reset */
+	phyhost |= (HOST_CTRL0_LINKSWRST |
+			HOST_CTRL0_UTMISWRST |
+			/* COMMON Block configuration during suspend */
+			HOST_CTRL0_COMMONON_N);
+	writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
+	udelay(10);
+	phyhost &= ~(HOST_CTRL0_LINKSWRST |
+			HOST_CTRL0_UTMISWRST);
+	writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
+
+	/* OTG configuration */
+	phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
+
+	/* phy reference clock configuration */
+	phyotg &= ~OTG_SYS_FSEL_MASK;
+	phyotg |= OTG_SYS_FSEL(phyclk);
+
+	/* Enable normal mode of operation */
+	phyotg &= ~(OTG_SYS_FORCESUSPEND |
+			OTG_SYS_SIDDQ_UOTG |
+			OTG_SYS_FORCESLEEP |
+			OTG_SYS_REFCLKSEL_MASK |
+			/* COMMON Block configuration during suspend */
+			OTG_SYS_COMMON_ON);
+
+	/* OTG phy & link reset */
+	phyotg |= (OTG_SYS_PHY0_SWRST |
+			OTG_SYS_LINKSWRST_UOTG |
+			OTG_SYS_PHYLINK_SWRESET |
+			OTG_SYS_OTGDISABLE |
+			/* Set phy refclk */
+			OTG_SYS_REFCLKSEL_CLKCORE);
+
+	writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
+	udelay(10);
+	phyotg &= ~(OTG_SYS_PHY0_SWRST |
+			OTG_SYS_LINKSWRST_UOTG |
+			OTG_SYS_PHYLINK_SWRESET);
+	writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
+
+	/* HSIC phy configuration */
+	phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
+			HSIC_CTRL_REFCLKSEL |
+			HSIC_CTRL_PHYSWRST);
+	writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
+	writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
+	udelay(10);
+	phyhsic &= ~HSIC_CTRL_PHYSWRST;
+	writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
+	writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
+
+	udelay(80);
+
+	/* enable EHCI DMA burst */
+	ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL);
+	ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN |
+				HOST_EHCICTRL_ENAINCR4 |
+				HOST_EHCICTRL_ENAINCR8 |
+				HOST_EHCICTRL_ENAINCR16);
+	writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL);
+
+	/* set ohci_suspend_on_n */
+	ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL);
+	ohcictrl |= HOST_OHCICTRL_SUSPLGCY;
+	writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL);
+}
+
 static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
 {
 	void __iomem *regs = sphy->regs;
@@ -221,6 +541,41 @@ static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
 	writel(rstcon, regs + SAMSUNG_RSTCON);
 }
 
+static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phyhost;
+	u32 phyotg;
+	u32 phyhsic;
+
+	if (atomic_dec_return(&sphy->host_usage) > 0) {
+		dev_info(sphy->dev, "still being used\n");
+		return;
+	}
+
+	phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
+			HSIC_CTRL_REFCLKSEL |
+			HSIC_CTRL_SIDDQ |
+			HSIC_CTRL_FORCESLEEP |
+			HSIC_CTRL_FORCESUSPEND);
+	writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
+	writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
+
+	phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
+	phyhost |= (HOST_CTRL0_SIDDQ |
+			HOST_CTRL0_FORCESUSPEND |
+			HOST_CTRL0_FORCESLEEP |
+			HOST_CTRL0_PHYSWRST |
+			HOST_CTRL0_PHYSWRSTALL);
+	writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
+
+	phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
+	phyotg |= (OTG_SYS_FORCESUSPEND |
+			OTG_SYS_SIDDQ_UOTG |
+			OTG_SYS_FORCESLEEP);
+	writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
+}
+
 static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
 {
 	void __iomem *regs = sphy->regs;
@@ -263,10 +618,13 @@ static int samsung_usbphy_init(struct usb_phy *phy)
 	if (sphy->plat && sphy->plat->pmu_isolation)
 		sphy->plat->pmu_isolation(false);
 	else
-		samsung_usbphy_set_isolation(sphy, false);
+		samsung_usbphy_set_isolation(sphy, false, sphy->phy_type);
 
 	/* Initialize usb phy registers */
-	samsung_usbphy_enable(sphy);
+	if (sphy->cpu_type == TYPE_EXYNOS5250)
+		samsung_exynos5_usbphy_enable(sphy);
+	else
+		samsung_usbphy_enable(sphy);
 
 	/* Disable the phy clock */
 	clk_disable_unprepare(sphy->clk);
@@ -288,13 +646,16 @@ static void samsung_usbphy_shutdown(struct usb_phy *phy)
 	}
 
 	/* De-initialize usb phy registers */
-	samsung_usbphy_disable(sphy);
+	if (sphy->cpu_type == TYPE_EXYNOS5250)
+		samsung_exynos5_usbphy_disable(sphy);
+	else
+		samsung_usbphy_disable(sphy);
 
 	/* Enable phy isolation */
 	if (sphy->plat && sphy->plat->pmu_isolation)
 		sphy->plat->pmu_isolation(true);
 	else
-		samsung_usbphy_set_isolation(sphy, true);
+		samsung_usbphy_set_isolation(sphy, true, sphy->phy_type);
 
 	clk_disable_unprepare(sphy->clk);
 }
@@ -339,12 +700,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
 	if (!sphy)
 		return -ENOMEM;
 
-	clk = devm_clk_get(dev, "otg");
-	if (IS_ERR(clk)) {
-		dev_err(dev, "Failed to get otg clock\n");
-		return PTR_ERR(clk);
-	}
-
 	sphy->dev = &pdev->dev;
 
 	ret = samsung_usbphy_parse_dt_param(sphy);
@@ -361,7 +716,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
 
 	sphy->plat		= pdata;
 	sphy->regs		= phy_base;
-	sphy->clk		= clk;
 	sphy->phy.dev		= sphy->dev;
 	sphy->phy.label		= "samsung-usbphy";
 	sphy->phy.init		= samsung_usbphy_init;
@@ -371,6 +725,17 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, sphy);
 
+	if (sphy->cpu_type == TYPE_EXYNOS5250)
+		clk = devm_clk_get(dev, "usbhost");
+	else
+		clk = devm_clk_get(dev, "otg");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "Failed to get otg clock\n");
+		return PTR_ERR(clk);
+	}
+
+	sphy->clk = clk;
+
 	return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
 }
 
@@ -382,6 +747,10 @@ static int __exit samsung_usbphy_remove(struct platform_device *pdev)
 
 	if (sphy->devctrl_reg)
 		iounmap(sphy->devctrl_reg);
+	if (sphy->hostctrl_reg)
+		iounmap(sphy->hostctrl_reg);
+	if (sphy->phycfg_reg)
+		iounmap(sphy->phycfg_reg);
 
 	return 0;
 }
@@ -394,6 +763,9 @@ static const struct of_device_id samsung_usbphy_dt_match[] = {
 	}, {
 		.compatible = "samsung,exynos4210-usbphy",
 		.data = (void *)TYPE_EXYNOS4210,
+	}, {
+		.compatible = "samsung,exynos5250-usbphy",
+		.data = (void *)TYPE_EXYNOS5250,
 	},
 	{},
 };
@@ -407,6 +779,9 @@ static struct platform_device_id samsung_usbphy_driver_ids[] = {
 	}, {
 		.name		= "exynos4210-usbphy",
 		.driver_data	= TYPE_EXYNOS4210,
+	}, {
+		.name		= "exynos5250-usbphy",
+		.driver_data	= TYPE_EXYNOS5250,
 	},
 	{},
 };
diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
index 9167826..aecefaf 100644
--- a/include/linux/usb/samsung_usb_phy.h
+++ b/include/linux/usb/samsung_usb_phy.h
@@ -10,7 +10,20 @@
  * option) any later version.
  */
 
+#include <linux/usb/phy.h>
+
 enum samsung_usb_phy_type {
 	USB_PHY_TYPE_DEVICE,
 	USB_PHY_TYPE_HOST,
 };
+
+#ifdef CONFIG_SAMSUNG_USBPHY
+extern int samsung_usbphy_set_type(struct usb_phy *phy,
+				enum samsung_usb_phy_type phy_type);
+#else
+static inline int samsung_usbphy_set_type(struct usb_phy *phy,
+				enum samsung_usb_phy_type phy_type)
+{
+	return 0;
+}
+#endif /* CONFIG_SAMSUNG_USBPHY */
-- 
1.7.6.5


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

* [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support
  2012-12-18 14:43 [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250 Vivek Gautam
  2012-12-18 14:43 ` [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer Vivek Gautam
  2012-12-18 14:43 ` [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver Vivek Gautam
@ 2012-12-18 14:43 ` Vivek Gautam
  2012-12-19  5:41   ` Vivek Gautam
  2012-12-19 23:30   ` Doug Anderson
  2012-12-18 14:43 ` [PATCH v5 4/4] USB: ohci-exynos: " Vivek Gautam
  2012-12-19  5:37   ` Vivek Gautam
  4 siblings, 2 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-18 14:43 UTC (permalink / raw)
  To: linux-usb
  Cc: devicetree-discuss, linux-kernel, linux-samsung-soc, gregkh,
	balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri

Adding the phy driver to ehci-s5p. Keeping the platform data
for continuing the smooth operation for boards which still uses it

Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/usb/host/ehci-s5p.c |   70 ++++++++++++++++++++++++++++++-------------
 1 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index 46ca5ef..50c93af 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -17,6 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/of_gpio.h>
 #include <linux/platform_data/usb-ehci-s5p.h>
+#include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
 #include <plat/usb-phy.h>
 
@@ -33,6 +34,8 @@ struct s5p_ehci_hcd {
 	struct device *dev;
 	struct usb_hcd *hcd;
 	struct clk *clk;
+	struct usb_phy *phy;
+	struct s5p_ehci_platdata *pdata;
 };
 
 static const struct hc_driver s5p_ehci_hc_driver = {
@@ -66,6 +69,30 @@ static const struct hc_driver s5p_ehci_hc_driver = {
 	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
 };
 
+static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci)
+{
+	struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
+
+	if (s5p_ehci->phy) {
+		samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);
+		usb_phy_init(s5p_ehci->phy);
+	} else if (s5p_ehci->pdata->phy_init) {
+		s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+	}
+}
+
+static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci)
+{
+	struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
+
+	if (s5p_ehci->phy) {
+		samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);
+		usb_phy_shutdown(s5p_ehci->phy);
+	} else if (s5p_ehci->pdata->phy_exit) {
+		s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+	}
+}
+
 static void s5p_setup_vbus_gpio(struct platform_device *pdev)
 {
 	int err;
@@ -88,20 +115,15 @@ static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
 
 static int s5p_ehci_probe(struct platform_device *pdev)
 {
-	struct s5p_ehci_platdata *pdata;
+	struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
 	struct s5p_ehci_hcd *s5p_ehci;
 	struct usb_hcd *hcd;
 	struct ehci_hcd *ehci;
 	struct resource *res;
+	struct usb_phy *phy;
 	int irq;
 	int err;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		dev_err(&pdev->dev, "No platform data defined\n");
-		return -EINVAL;
-	}
-
 	/*
 	 * Right now device-tree probed devices don't get dma_mask set.
 	 * Since shared usb code relies on it, set it here for now.
@@ -119,6 +141,19 @@ static int s5p_ehci_probe(struct platform_device *pdev)
 	if (!s5p_ehci)
 		return -ENOMEM;
 
+	phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
+	if (IS_ERR_OR_NULL(phy)) {
+		/* Fallback to pdata */
+		if (!pdata) {
+			dev_err(&pdev->dev, "no platform data or transceiver defined\n");
+			return -EPROBE_DEFER;
+		} else {
+			s5p_ehci->pdata = pdata;
+		}
+	} else {
+		s5p_ehci->phy = phy;
+	}
+
 	s5p_ehci->dev = &pdev->dev;
 
 	hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev,
@@ -164,8 +199,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
 		goto fail_io;
 	}
 
-	if (pdata->phy_init)
-		pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+	s5p_ehci_phy_enable(s5p_ehci);
 
 	ehci = hcd_to_ehci(hcd);
 	ehci->caps = hcd->regs;
@@ -176,13 +210,15 @@ static int s5p_ehci_probe(struct platform_device *pdev)
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
-		goto fail_io;
+		goto fail_add_hcd;
 	}
 
 	platform_set_drvdata(pdev, s5p_ehci);
 
 	return 0;
 
+fail_add_hcd:
+	s5p_ehci_phy_disable(s5p_ehci);
 fail_io:
 	clk_disable_unprepare(s5p_ehci->clk);
 fail_clk:
@@ -192,14 +228,12 @@ fail_clk:
 
 static int s5p_ehci_remove(struct platform_device *pdev)
 {
-	struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
 	struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
 	struct usb_hcd *hcd = s5p_ehci->hcd;
 
 	usb_remove_hcd(hcd);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+	s5p_ehci_phy_disable(s5p_ehci);
 
 	clk_disable_unprepare(s5p_ehci->clk);
 
@@ -223,14 +257,11 @@ static int s5p_ehci_suspend(struct device *dev)
 	struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
 	struct usb_hcd *hcd = s5p_ehci->hcd;
 	bool do_wakeup = device_may_wakeup(dev);
-	struct platform_device *pdev = to_platform_device(dev);
-	struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
 	int rc;
 
 	rc = ehci_suspend(hcd, do_wakeup);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+	s5p_ehci_phy_disable(s5p_ehci);
 
 	clk_disable_unprepare(s5p_ehci->clk);
 
@@ -241,13 +272,10 @@ static int s5p_ehci_resume(struct device *dev)
 {
 	struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
 	struct usb_hcd *hcd = s5p_ehci->hcd;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
 
 	clk_prepare_enable(s5p_ehci->clk);
 
-	if (pdata && pdata->phy_init)
-		pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+	s5p_ehci_phy_enable(s5p_ehci);
 
 	/* DMA burst Enable */
 	writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
-- 
1.7.6.5


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

* [PATCH v5 4/4] USB: ohci-exynos: Add phy driver support
  2012-12-18 14:43 [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250 Vivek Gautam
                   ` (2 preceding siblings ...)
  2012-12-18 14:43 ` [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support Vivek Gautam
@ 2012-12-18 14:43 ` Vivek Gautam
  2012-12-19  5:41     ` Vivek Gautam
  2012-12-19  5:37   ` Vivek Gautam
  4 siblings, 1 reply; 34+ messages in thread
From: Vivek Gautam @ 2012-12-18 14:43 UTC (permalink / raw)
  To: linux-usb
  Cc: devicetree-discuss, linux-kernel, linux-samsung-soc, gregkh,
	balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri

Adding the phy-driver to ohci-exynos. Keeping the platform data
for continuing the smooth operation for boards which still uses it

Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/usb/host/ohci-exynos.c |   70 ++++++++++++++++++++++++++++------------
 1 files changed, 49 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 804fb62..c92ab7b 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -15,6 +15,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/usb-exynos.h>
+#include <linux/usb/phy.h>
 #include <linux/usb/samsung_usb_phy.h>
 #include <plat/usb-phy.h>
 
@@ -22,8 +23,34 @@ struct exynos_ohci_hcd {
 	struct device *dev;
 	struct usb_hcd *hcd;
 	struct clk *clk;
+	struct usb_phy *phy;
+	struct exynos4_ohci_platdata *pdata;
 };
 
+static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+{
+	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+
+	if (exynos_ohci->phy) {
+		samsung_usbphy_set_type(exynos_ohci->phy, USB_PHY_TYPE_HOST);
+		usb_phy_init(exynos_ohci->phy);
+	} else if (exynos_ohci->pdata->phy_init) {
+		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+	}
+}
+
+static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+{
+	struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+
+	if (exynos_ohci->phy) {
+		samsung_usbphy_set_type(exynos_ohci->phy, USB_PHY_TYPE_HOST);
+		usb_phy_shutdown(exynos_ohci->phy);
+	} else if (exynos_ohci->pdata->phy_exit) {
+		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+	}
+}
+
 static int ohci_exynos_reset(struct usb_hcd *hcd)
 {
 	return ohci_init(hcd_to_ohci(hcd));
@@ -79,20 +106,15 @@ static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
 
 static int exynos_ohci_probe(struct platform_device *pdev)
 {
-	struct exynos4_ohci_platdata *pdata;
+	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci;
 	struct usb_hcd *hcd;
 	struct ohci_hcd *ohci;
 	struct resource *res;
+	struct usb_phy *phy;
 	int irq;
 	int err;
 
-	pdata = pdev->dev.platform_data;
-	if (!pdata) {
-		dev_err(&pdev->dev, "No platform data defined\n");
-		return -EINVAL;
-	}
-
 	/*
 	 * Right now device-tree probed devices don't get dma_mask set.
 	 * Since shared usb code relies on it, set it here for now.
@@ -108,6 +130,19 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	if (!exynos_ohci)
 		return -ENOMEM;
 
+	phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
+	if (IS_ERR_OR_NULL(phy)) {
+		/* Fallback to pdata */
+		if (!pdata) {
+			dev_err(&pdev->dev, "no platform data or transceiver defined\n");
+			return -EPROBE_DEFER;
+		} else {
+			exynos_ohci->pdata = pdata;
+		}
+	} else {
+		exynos_ohci->phy = phy;
+	}
+
 	exynos_ohci->dev = &pdev->dev;
 
 	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
@@ -153,8 +188,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 		goto fail_io;
 	}
 
-	if (pdata->phy_init)
-		pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+	exynos_ohci_phy_enable(exynos_ohci);
 
 	ohci = hcd_to_ohci(hcd);
 	ohci_hcd_init(ohci);
@@ -162,13 +196,15 @@ static int exynos_ohci_probe(struct platform_device *pdev)
 	err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 	if (err) {
 		dev_err(&pdev->dev, "Failed to add USB HCD\n");
-		goto fail_io;
+		goto fail_add_hcd;
 	}
 
 	platform_set_drvdata(pdev, exynos_ohci);
 
 	return 0;
 
+fail_add_hcd:
+	exynos_ohci_phy_disable(exynos_ohci);
 fail_io:
 	clk_disable_unprepare(exynos_ohci->clk);
 fail_clk:
@@ -178,14 +214,12 @@ fail_clk:
 
 static int exynos_ohci_remove(struct platform_device *pdev)
 {
-	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
 	struct usb_hcd *hcd = exynos_ohci->hcd;
 
 	usb_remove_hcd(hcd);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+	exynos_ohci_phy_disable(exynos_ohci);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -209,8 +243,6 @@ static int exynos_ohci_suspend(struct device *dev)
 	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
 	struct usb_hcd *hcd = exynos_ohci->hcd;
 	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-	struct platform_device *pdev = to_platform_device(dev);
-	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 	unsigned long flags;
 	int rc = 0;
 
@@ -229,8 +261,7 @@ static int exynos_ohci_suspend(struct device *dev)
 
 	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
-	if (pdata && pdata->phy_exit)
-		pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+	exynos_ohci_phy_disable(exynos_ohci);
 
 	clk_disable_unprepare(exynos_ohci->clk);
 
@@ -244,13 +275,10 @@ static int exynos_ohci_resume(struct device *dev)
 {
 	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
 	struct usb_hcd *hcd = exynos_ohci->hcd;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
 
 	clk_prepare_enable(exynos_ohci->clk);
 
-	if (pdata && pdata->phy_init)
-		pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+	exynos_ohci_phy_enable(exynos_ohci);
 
 	ohci_resume(hcd, false);
 
-- 
1.7.6.5


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

* Re: [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250
@ 2012-12-19  5:37   ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:37 UTC (permalink / raw)
  To: linux-usb
  Cc: dianders, devicetree-discuss, linux-kernel, linux-samsung-soc,
	gregkh, balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri, Vivek Gautam

CC: Doug Anderson


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> Changes from v4:
>  - Moved architecture side changes out of this patch-set.
>  - Added support for multiple usbphy phandle parsing and
>    doing all pmu_isolation() and phy_cfg_sel() related changes
>    in samsung-usbphy driver only instead of architecture
>    as in v4 patch-set.
>  - Removed unnecessary multi line definitions for macros.
>
> Changes from v3:
>  - Moved enums S5P_USB_PHY_DEVICE, S5P_USB_PHY_HOST from machine to file
>    include/linux/usb/samsung_usb_phy.h as USB_PHY_TYPE_DEVICE and
>    USB_PHY_TYPE_HOST to make it more generic. Further resolve its
>    dependencies.
>  - Introduced a function 'samsung_usbphy_set_type()' which takes
>    care of setting up the phy_type: HOST/DEVICE. This function
>    can be called by host/otg drivers to setup phy_type prior to
>    handling the respective PHYs.
>  - Added an error-path for HOST type phy in s5p_usb_phy_pmu_isolation()
>    for 'mach-s3c64xx'.
>  - Moving to PHY driver as default for ehci-s5p and ohci-exynos, and only
>    when failed fall back to plat-data.
>  - Added samsung_usbphy_set_type() prior to doing usb_phy_init() or
>    usb_phy_shutdown() so that appropriate PHY gets init or shutdown.
>
> Based on patches for samsung-usbphy driver:
>  1)http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/134476.html
>  2)https://lkml.org/lkml/2012/12/18/187
>
> Vivek Gautam (4):
>   ARM: EXYNOS: Update & move usb-phy types to generic include layer
>   usb: phy: samsung: Add host phy support to samsung-phy driver
>   USB: ehci-s5p: Add phy driver support
>   USB: ohci-exynos: Add phy driver support
>
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
>  drivers/usb/host/ehci-s5p.c                        |   71 +++-
>  drivers/usb/host/ohci-exynos.c                     |   71 +++-
>  drivers/usb/phy/Kconfig                            |    2 +-
>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
>  include/linux/usb/samsung_usb_phy.h                |   29 ++
>  6 files changed, 570 insertions(+), 93 deletions(-)
>  create mode 100644 include/linux/usb/samsung_usb_phy.h
>
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250
@ 2012-12-19  5:37   ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:37 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	p.paneri-Sze3O3UU22JBDgjK7y7TUQ,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	jg1.han-Sze3O3UU22JBDgjK7y7TUQ, balbi-l0cyMroinI0,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	sylvester.nawrocki-Re5JQEeQqe8AvxtiuMwx3w, kishon-l0cyMroinI0,
	Vivek Gautam

CC: Doug Anderson


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> Changes from v4:
>  - Moved architecture side changes out of this patch-set.
>  - Added support for multiple usbphy phandle parsing and
>    doing all pmu_isolation() and phy_cfg_sel() related changes
>    in samsung-usbphy driver only instead of architecture
>    as in v4 patch-set.
>  - Removed unnecessary multi line definitions for macros.
>
> Changes from v3:
>  - Moved enums S5P_USB_PHY_DEVICE, S5P_USB_PHY_HOST from machine to file
>    include/linux/usb/samsung_usb_phy.h as USB_PHY_TYPE_DEVICE and
>    USB_PHY_TYPE_HOST to make it more generic. Further resolve its
>    dependencies.
>  - Introduced a function 'samsung_usbphy_set_type()' which takes
>    care of setting up the phy_type: HOST/DEVICE. This function
>    can be called by host/otg drivers to setup phy_type prior to
>    handling the respective PHYs.
>  - Added an error-path for HOST type phy in s5p_usb_phy_pmu_isolation()
>    for 'mach-s3c64xx'.
>  - Moving to PHY driver as default for ehci-s5p and ohci-exynos, and only
>    when failed fall back to plat-data.
>  - Added samsung_usbphy_set_type() prior to doing usb_phy_init() or
>    usb_phy_shutdown() so that appropriate PHY gets init or shutdown.
>
> Based on patches for samsung-usbphy driver:
>  1)http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/134476.html
>  2)https://lkml.org/lkml/2012/12/18/187
>
> Vivek Gautam (4):
>   ARM: EXYNOS: Update & move usb-phy types to generic include layer
>   usb: phy: samsung: Add host phy support to samsung-phy driver
>   USB: ehci-s5p: Add phy driver support
>   USB: ohci-exynos: Add phy driver support
>
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
>  drivers/usb/host/ehci-s5p.c                        |   71 +++-
>  drivers/usb/host/ohci-exynos.c                     |   71 +++-
>  drivers/usb/phy/Kconfig                            |    2 +-
>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
>  include/linux/usb/samsung_usb_phy.h                |   29 ++
>  6 files changed, 570 insertions(+), 93 deletions(-)
>  create mode 100644 include/linux/usb/samsung_usb_phy.h
>
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
@ 2012-12-19  5:38     ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:38 UTC (permalink / raw)
  To: linux-usb
  Cc: dianders, devicetree-discuss, linux-kernel, linux-samsung-soc,
	gregkh, balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri, Vivek Gautam

CC: Doug Anderson.


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> Updating the names of usb-phy types to more generic names:
> USB_PHY_TYPE_DEIVCE & USB_PHY_TYPE_HOST; and further update
> its dependencies.
>
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> ---
>  drivers/usb/host/ehci-s5p.c         |    9 +++++----
>  drivers/usb/host/ohci-exynos.c      |    9 +++++----
>  include/linux/usb/samsung_usb_phy.h |   16 ++++++++++++++++
>  3 files changed, 26 insertions(+), 8 deletions(-)
>  create mode 100644 include/linux/usb/samsung_usb_phy.h
>
> diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
> index 319dcfa..46ca5ef 100644
> --- a/drivers/usb/host/ehci-s5p.c
> +++ b/drivers/usb/host/ehci-s5p.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/of_gpio.h>
>  #include <linux/platform_data/usb-ehci-s5p.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
>  #define EHCI_INSNREG00(base)                   (base + 0x90)
> @@ -164,7 +165,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>         }
>
>         if (pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ehci = hcd_to_ehci(hcd);
>         ehci->caps = hcd->regs;
> @@ -198,7 +199,7 @@ static int s5p_ehci_remove(struct platform_device *pdev)
>         usb_remove_hcd(hcd);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -229,7 +230,7 @@ static int s5p_ehci_suspend(struct device *dev)
>         rc = ehci_suspend(hcd, do_wakeup);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -246,7 +247,7 @@ static int s5p_ehci_resume(struct device *dev)
>         clk_prepare_enable(s5p_ehci->clk);
>
>         if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         /* DMA burst Enable */
>         writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
> diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
> index aa3b884..804fb62 100644
> --- a/drivers/usb/host/ohci-exynos.c
> +++ b/drivers/usb/host/ohci-exynos.c
> @@ -15,6 +15,7 @@
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/usb-exynos.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
>  struct exynos_ohci_hcd {
> @@ -153,7 +154,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>         }
>
>         if (pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ohci = hcd_to_ohci(hcd);
>         ohci_hcd_init(ohci);
> @@ -184,7 +185,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
>         usb_remove_hcd(hcd);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -229,7 +230,7 @@ static int exynos_ohci_suspend(struct device *dev)
>         clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -249,7 +250,7 @@ static int exynos_ohci_resume(struct device *dev)
>         clk_prepare_enable(exynos_ohci->clk);
>
>         if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ohci_resume(hcd, false);
>
> diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
> new file mode 100644
> index 0000000..9167826
> --- /dev/null
> +++ b/include/linux/usb/samsung_usb_phy.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + *             http://www.samsung.com/
> + *
> + * Defines phy types for samsung usb phy controllers - HOST or DEIVCE.
> + *
> + * 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, or (at your
> + * option) any later version.
> + */
> +
> +enum samsung_usb_phy_type {
> +       USB_PHY_TYPE_DEVICE,
> +       USB_PHY_TYPE_HOST,
> +};
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
@ 2012-12-19  5:38     ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:38 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	p.paneri-Sze3O3UU22JBDgjK7y7TUQ,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	jg1.han-Sze3O3UU22JBDgjK7y7TUQ, balbi-l0cyMroinI0,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	sylvester.nawrocki-Re5JQEeQqe8AvxtiuMwx3w, kishon-l0cyMroinI0,
	Vivek Gautam

CC: Doug Anderson.


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> Updating the names of usb-phy types to more generic names:
> USB_PHY_TYPE_DEIVCE & USB_PHY_TYPE_HOST; and further update
> its dependencies.
>
> Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/usb/host/ehci-s5p.c         |    9 +++++----
>  drivers/usb/host/ohci-exynos.c      |    9 +++++----
>  include/linux/usb/samsung_usb_phy.h |   16 ++++++++++++++++
>  3 files changed, 26 insertions(+), 8 deletions(-)
>  create mode 100644 include/linux/usb/samsung_usb_phy.h
>
> diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
> index 319dcfa..46ca5ef 100644
> --- a/drivers/usb/host/ehci-s5p.c
> +++ b/drivers/usb/host/ehci-s5p.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/of_gpio.h>
>  #include <linux/platform_data/usb-ehci-s5p.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
>  #define EHCI_INSNREG00(base)                   (base + 0x90)
> @@ -164,7 +165,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>         }
>
>         if (pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ehci = hcd_to_ehci(hcd);
>         ehci->caps = hcd->regs;
> @@ -198,7 +199,7 @@ static int s5p_ehci_remove(struct platform_device *pdev)
>         usb_remove_hcd(hcd);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -229,7 +230,7 @@ static int s5p_ehci_suspend(struct device *dev)
>         rc = ehci_suspend(hcd, do_wakeup);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -246,7 +247,7 @@ static int s5p_ehci_resume(struct device *dev)
>         clk_prepare_enable(s5p_ehci->clk);
>
>         if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         /* DMA burst Enable */
>         writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
> diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
> index aa3b884..804fb62 100644
> --- a/drivers/usb/host/ohci-exynos.c
> +++ b/drivers/usb/host/ohci-exynos.c
> @@ -15,6 +15,7 @@
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/usb-exynos.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
>  struct exynos_ohci_hcd {
> @@ -153,7 +154,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>         }
>
>         if (pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ohci = hcd_to_ohci(hcd);
>         ohci_hcd_init(ohci);
> @@ -184,7 +185,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
>         usb_remove_hcd(hcd);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -229,7 +230,7 @@ static int exynos_ohci_suspend(struct device *dev)
>         clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -249,7 +250,7 @@ static int exynos_ohci_resume(struct device *dev)
>         clk_prepare_enable(exynos_ohci->clk);
>
>         if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ohci_resume(hcd, false);
>
> diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
> new file mode 100644
> index 0000000..9167826
> --- /dev/null
> +++ b/include/linux/usb/samsung_usb_phy.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + *             http://www.samsung.com/
> + *
> + * Defines phy types for samsung usb phy controllers - HOST or DEIVCE.
> + *
> + * 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, or (at your
> + * option) any later version.
> + */
> +
> +enum samsung_usb_phy_type {
> +       USB_PHY_TYPE_DEVICE,
> +       USB_PHY_TYPE_HOST,
> +};
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
@ 2012-12-19  5:40     ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:40 UTC (permalink / raw)
  To: linux-usb
  Cc: dianders, yulgon.kim, linux-samsung-soc, p.paneri, gregkh,
	devicetree-discuss, jg1.han, linux-kernel, balbi, kishon,
	kgene.kim, stern, rob.herring, sylvester.nawrocki, Vivek Gautam

CC: Doug Anderson.


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> This patch adds host phy support to samsung-usbphy.c and
> further adds support for samsung's exynos5250 usb-phy.
>
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> ---
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
>  drivers/usb/phy/Kconfig                            |    2 +-
>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
>  include/linux/usb/samsung_usb_phy.h                |   13 +
>  4 files changed, 454 insertions(+), 51 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> index a7b28b2..2ec5400 100644
> --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -1,23 +1,38 @@
>  * Samsung's usb phy transceiver
>
> -The Samsung's phy transceiver is used for controlling usb otg phy for
> -s3c-hsotg usb device controller.
> +The Samsung's phy transceiver is used for controlling usb phy for
> +s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
> +across Samsung SOCs.
>  TODO: Adding the PHY binding with controller(s) according to the under
>  developement generic PHY driver.
>
>  Required properties:
> +
> +Exynos4210:
>  - compatible : should be "samsung,exynos4210-usbphy"
>  - reg : base physical address of the phy registers and length of memory mapped
>         region.
>
> +Exynos5250:
> +- compatible : should be "samsung,exynos5250-usbphy"
> +- reg : base physical address of the phy registers and length of memory mapped
> +       region.
> +
>  Optional properties:
>  - samsung,usb-phyhandle : should point to usb-phyhandle sub-node which provides
>                         binding data to enable/disable device PHY handled by
> -                       PMU register.
> +                       PMU register; or to configure usb2.0 phy handled by
> +                       SYSREG.
>
>                         Required properties:
>                         - compatible : should be "samsung,usbdev-phyctrl" for
> -                                       DEVICE type phy.
> +                                      DEVICE type phy; or
> +                                      should be "samsung,usbhost-phyctrl" for
> +                                      HOST type phy; or
> +                                      should be "samsung,usb-phycfg" for
> +                                      USB2.0 PHY_CFG.
>                         - samsung,phyhandle-reg: base physical address of
> -                                               PHY_CONTROL register in PMU.
> +                                                PHY_CONTROL register in PMU;
> +                                                or USB2.0 PHY_CFG register
> +                                                in SYSREG.
>  - samsung,enable-mask : should be '1'
> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> index 17ad743..13c0eaf 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -47,7 +47,7 @@ config USB_RCAR_PHY
>
>  config SAMSUNG_USBPHY
>         bool "Samsung USB PHY controller Driver"
> -       depends on USB_S3C_HSOTG
> +       depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
>         select USB_OTG_UTILS
>         help
>           Enable this to support Samsung USB phy controller for samsung
> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
> index 4ceabe3..621348a 100644
> --- a/drivers/usb/phy/samsung-usbphy.c
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -5,7 +5,8 @@
>   *
>   * Author: Praveen Paneri <p.paneri@samsung.com>
>   *
> - * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
> + * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
> + * OHCI-EXYNOS controllers.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -24,7 +25,7 @@
>  #include <linux/err.h>
>  #include <linux/io.h>
>  #include <linux/of.h>
> -#include <linux/usb/otg.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <linux/platform_data/samsung-usbphy.h>
>
>  /* Register definitions */
> @@ -56,6 +57,103 @@
>  #define RSTCON_HLINK_SWRST                     (0x1 << 1)
>  #define RSTCON_SWRST                           (0x1 << 0)
>
> +/* EXYNOS5 */
> +#define EXYNOS5_PHY_HOST_CTRL0                 (0x00)
> +
> +#define HOST_CTRL0_PHYSWRSTALL                 (0x1 << 31)
> +
> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
> +
> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
> +
> +#define HOST_CTRL0_TESTBURNIN                  (0x1 << 11)
> +#define HOST_CTRL0_RETENABLE                   (0x1 << 10)
> +#define HOST_CTRL0_COMMONON_N                  (0x1 << 9)
> +#define HOST_CTRL0_SIDDQ                       (0x1 << 6)
> +#define HOST_CTRL0_FORCESLEEP                  (0x1 << 5)
> +#define HOST_CTRL0_FORCESUSPEND                        (0x1 << 4)
> +#define HOST_CTRL0_WORDINTERFACE               (0x1 << 3)
> +#define HOST_CTRL0_UTMISWRST                   (0x1 << 2)
> +#define HOST_CTRL0_LINKSWRST                   (0x1 << 1)
> +#define HOST_CTRL0_PHYSWRST                    (0x1 << 0)
> +
> +#define EXYNOS5_PHY_HOST_TUNE0                 (0x04)
> +
> +#define EXYNOS5_PHY_HSIC_CTRL1                 (0x10)
> +
> +#define EXYNOS5_PHY_HSIC_TUNE1                 (0x14)
> +
> +#define EXYNOS5_PHY_HSIC_CTRL2                 (0x20)
> +
> +#define EXYNOS5_PHY_HSIC_TUNE2                 (0x24)
> +
> +#define HSIC_CTRL_REFCLKSEL_MASK               (0x3)
> +#define HSIC_CTRL_REFCLKSEL                    (0x2 << 23)
> +
> +#define HSIC_CTRL_REFCLKDIV_MASK               (0x7f)
> +#define HSIC_CTRL_REFCLKDIV(_x)                        ((_x) << 16)
> +#define HSIC_CTRL_REFCLKDIV_12                 (0x24 << 16)
> +#define HSIC_CTRL_REFCLKDIV_15                 (0x1c << 16)
> +#define HSIC_CTRL_REFCLKDIV_16                 (0x1a << 16)
> +#define HSIC_CTRL_REFCLKDIV_19_2               (0x15 << 16)
> +#define HSIC_CTRL_REFCLKDIV_20                 (0x14)
> +
> +#define HSIC_CTRL_SIDDQ                                (0x1 << 6)
> +#define HSIC_CTRL_FORCESLEEP                   (0x1 << 5)
> +#define HSIC_CTRL_FORCESUSPEND                 (0x1 << 4)
> +#define HSIC_CTRL_WORDINTERFACE                        (0x1 << 3)
> +#define HSIC_CTRL_UTMISWRST                    (0x1 << 2)
> +#define HSIC_CTRL_PHYSWRST                     (0x1 << 0)
> +
> +#define EXYNOS5_PHY_HOST_EHCICTRL              (0x30)
> +
> +#define HOST_EHCICTRL_ENAINCRXALIGN            (0x1 << 29)
> +#define HOST_EHCICTRL_ENAINCR4                 (0x1 << 28)
> +#define HOST_EHCICTRL_ENAINCR8                 (0x1 << 27)
> +#define HOST_EHCICTRL_ENAINCR16                        (0x1 << 26)
> +
> +#define EXYNOS5_PHY_HOST_OHCICTRL              (0x34)
> +
> +#define HOST_OHCICTRL_SUSPLGCY                 (0x1 << 3)
> +#define HOST_OHCICTRL_APPSTARTCLK              (0x1 << 2)
> +#define HOST_OHCICTRL_CNTSEL                   (0x1 << 1)
> +#define HOST_OHCICTRL_CLKCKTRST                        (0x1 << 0)
> +
> +#define EXYNOS5_PHY_OTG_SYS                    (0x38)
> +
> +#define OTG_SYS_PHYLINK_SWRESET                        (0x1 << 14)
> +#define OTG_SYS_LINKSWRST_UOTG                 (0x1 << 13)
> +#define OTG_SYS_PHY0_SWRST                     (0x1 << 12)
> +
> +#define OTG_SYS_REFCLKSEL_MASK                 (0x3 << 9)
> +#define OTG_SYS_REFCLKSEL_XTAL                 (0x0 << 9)
> +#define OTG_SYS_REFCLKSEL_EXTL                 (0x1 << 9)
> +#define OTG_SYS_REFCLKSEL_CLKCORE              (0x2 << 9)
> +
> +#define OTG_SYS_IDPULLUP_UOTG                  (0x1 << 8)
> +#define OTG_SYS_COMMON_ON                      (0x1 << 7)
> +
> +#define OTG_SYS_FSEL_MASK                      (0x7 << 4)
> +#define OTG_SYS_FSEL(_x)                       ((_x) << 4)
> +
> +#define OTG_SYS_FORCESLEEP                     (0x1 << 3)
> +#define OTG_SYS_OTGDISABLE                     (0x1 << 2)
> +#define OTG_SYS_SIDDQ_UOTG                     (0x1 << 1)
> +#define OTG_SYS_FORCESUSPEND                   (0x1 << 0)
> +
> +#define EXYNOS5_PHY_OTG_TUNE                   (0x40)
> +
>  #ifndef MHZ
>  #define MHZ (1000*1000)
>  #endif
> @@ -63,6 +161,7 @@
>  enum samsung_cpu_type {
>         TYPE_S3C64XX,
>         TYPE_EXYNOS4210,
> +       TYPE_EXYNOS5250,
>  };
>
>  /*
> @@ -73,9 +172,13 @@ enum samsung_cpu_type {
>   * @clk: usb phy clock
>   * @regs: usb phy register memory base
>   * @devctrl_reg: usb device phy-control pmu register memory base
> + * @hostctrl_reg: usb host phy-control pmu register memory base
> + * @phycfg_reg: usb2.0 phy-cfg system register memory base
>   * @en_mask: enable mask
>   * @ref_clk_freq: reference clock frequency selection
>   * @cpu_type: machine identifier
> + * @phy_type: It keeps track of the PHY type.
> + * @host_usage: host_phy usage count.
>   */
>  struct samsung_usbphy {
>         struct usb_phy  phy;
> @@ -84,9 +187,13 @@ struct samsung_usbphy {
>         struct clk      *clk;
>         void __iomem    *regs;
>         void __iomem    *devctrl_reg;
> +       void __iomem    *hostctrl_reg;
> +       void __iomem    *phycfg_reg;
>         u32             en_mask;
>         int             ref_clk_freq;
>         int             cpu_type;
> +       enum samsung_usb_phy_type phy_type;
> +       atomic_t        host_usage;
>  };
>
>  #define phy_to_sphy(x)         container_of((x), struct samsung_usbphy, phy)
> @@ -96,26 +203,49 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
>         struct device_node *usb_phyctrl;
>         u32 reg;
>         int lenp;
> +       int count = 0;
>
>         if (!sphy->dev->of_node) {
>                 sphy->devctrl_reg = NULL;
>                 return -ENODEV;
>         }
>
> -       if (of_get_property(sphy->dev->of_node, "samsung,usb-phyhandle", &lenp)) {
> -               usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
> -                                               "samsung,usb-phyhandle", 0);
> -               if (!usb_phyctrl) {
> -                       dev_warn(sphy->dev, "Can't get usb-phy handle\n");
> -                       sphy->devctrl_reg = NULL;
> -               }
> -
> -               of_property_read_u32(usb_phyctrl, "samsung,phyhandle-reg", &reg);
> +       if (of_get_property(sphy->dev->of_node,
> +                       "samsung,usb-phyhandle", &lenp)) {
> +               do {
> +                       usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
> +                                                       "samsung,usb-phyhandle",
> +                                                       count++);
> +                       if (!usb_phyctrl) {
> +                               dev_warn(sphy->dev,
> +                                       "Can't get usb-phy handle\n");
> +                               sphy->devctrl_reg = NULL;
> +                       }
> +
> +                       of_property_read_u32(usb_phyctrl,
> +                                       "samsung,phyhandle-reg", &reg);
> +
> +                       /*
> +                        * Considering here the maximum number of configurable
> +                        * register settings: DEVICE_PHY_CONTROL
> +                        *                    HOST_PHY_CONTROL
> +                        *                    PHY20_CFG
> +                        */
> +                       if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usbdev-phyctrl"))
> +                               sphy->devctrl_reg = ioremap(reg, SZ_4);
> +                       else if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usbhost-phyctrl"))
> +                               sphy->hostctrl_reg = ioremap(reg, SZ_4);
> +                       else if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usb-phycfg"))
> +                               sphy->phycfg_reg = ioremap(reg, SZ_4);
> +
> +                       of_property_read_u32(sphy->dev->of_node,
> +                                       "samsung,enable-mask", &sphy->en_mask);
> +               } while (of_parse_phandle(sphy->dev->of_node,
> +                               "samsung,usb-phyhandle", count));
>
> -               sphy->devctrl_reg = ioremap(reg, SZ_4);
> -
> -               of_property_read_u32(sphy->dev->of_node, "samsung,enable-mask",
> -                                                       &sphy->en_mask);
>                 of_node_put(usb_phyctrl);
>         } else {
>                 dev_warn(sphy->dev, "Can't get usb-phy handle\n");
> @@ -129,13 +259,18 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
>   * Set isolation here for phy.
>   * SOCs control this by controlling corresponding PMU registers
>   */
> -static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
> +static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy,
> +                                                       int on, int type)
>  {
> -       void __iomem *usb_phyctrl_reg;
> +       void __iomem *usb_phyctrl_reg = NULL;
>         u32 en_mask = sphy->en_mask;
>         u32 reg;
>
> -       usb_phyctrl_reg = sphy->devctrl_reg;
> +       if (type == USB_PHY_TYPE_DEVICE) {
> +               usb_phyctrl_reg = sphy->devctrl_reg;
> +       } else if (type == USB_PHY_TYPE_HOST) {
> +               usb_phyctrl_reg = sphy->hostctrl_reg;
> +       }
>
>         if (!usb_phyctrl_reg) {
>                 dev_warn(sphy->dev, "Can't set pmu isolation\n");
> @@ -151,6 +286,47 @@ static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
>  }
>
>  /*
> + * Configure the mode of working og usb-phy here: HOST/DEVICE.
> + * SOCs control this by controlling corresponding system register
> + */
> +static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy, int type)
> +{
> +       void __iomem *usb_phycfg_reg;
> +       u32 en_mask = sphy->en_mask;
> +       u32 reg;
> +
> +       usb_phycfg_reg = sphy->phycfg_reg;
> +
> +       if (!usb_phycfg_reg) {
> +               dev_warn(sphy->dev, "Can't select specified phy mode\n");
> +               return;
> +       }
> +
> +       reg = readl(usb_phycfg_reg);
> +
> +       if (type == USB_PHY_TYPE_DEVICE)
> +               writel(reg & ~en_mask, usb_phycfg_reg);
> +       else if (type == USB_PHY_TYPE_HOST)
> +               writel(reg | en_mask, usb_phycfg_reg);
> +}
> +
> +/*
> + * PHYs are different for USB Device and USB Host. Controllers can make
> + * sure that the correct PHY type is selected by calling this function
> + * before any PHY operation.
> + */
> +int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type)
> +{
> +       struct samsung_usbphy *sphy = phy_to_sphy(phy);
> +
> +       if (sphy->phy_type != phy_type)
> +               sphy->phy_type = phy_type;
> +
> +       return 0;
> +}
> +
> +/*
>   * Returns reference clock frequency selection value
>   */
>  static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
> @@ -158,34 +334,178 @@ static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
>         struct clk *ref_clk;
>         int refclk_freq = 0;
>
> -       ref_clk = clk_get(sphy->dev, "xusbxti");
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               ref_clk = clk_get(sphy->dev, "ext_xtal");
> +       else
> +               ref_clk = clk_get(sphy->dev, "xusbxti");
>         if (IS_ERR(ref_clk)) {
>                 dev_err(sphy->dev, "Failed to get reference clock\n");
>                 return PTR_ERR(ref_clk);
>         }
>
> -       switch (clk_get_rate(ref_clk)) {
> -       case 12 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_12M;
> -               break;
> -       case 24 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_24M;
> -               break;
> -       case 48 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_48M;
> -               break;
> -       default:
> -               if (sphy->cpu_type == TYPE_S3C64XX)
> -                       refclk_freq = PHYCLK_CLKSEL_48M;
> -               else
> +       if (sphy->cpu_type == TYPE_EXYNOS5250) {
> +               /* set clock frequency for PLL */
> +               switch (clk_get_rate(ref_clk)) {
> +               case 96 * 100000:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
> +                       break;
> +               case 10 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_10M;
> +                       break;
> +               case 12 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_12M;
> +                       break;
> +               case 192 * 100000:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_19200K;
> +                       break;
> +               case 20 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_20M;
> +                       break;
> +               case 50 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_50M;
> +                       break;
> +               case 24 * MHZ:
> +               default:
> +                       /* default reference clock */
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_24M;
> +                       break;
> +               }
> +       } else {
> +               switch (clk_get_rate(ref_clk)) {
> +               case 12 * MHZ:
> +                       refclk_freq = PHYCLK_CLKSEL_12M;
> +                       break;
> +               case 24 * MHZ:
>                         refclk_freq = PHYCLK_CLKSEL_24M;
> -               break;
> +                       break;
> +               case 48 * MHZ:
> +                       refclk_freq = PHYCLK_CLKSEL_48M;
> +                       break;
> +               default:
> +                       if (sphy->cpu_type == TYPE_S3C64XX)
> +                               refclk_freq = PHYCLK_CLKSEL_48M;
> +                       else
> +                               refclk_freq = PHYCLK_CLKSEL_24M;
> +                       break;
> +               }
>         }
>         clk_put(ref_clk);
>
>         return refclk_freq;
>  }
>
> +static int exynos5_phyhost_is_on(void *regs)
> +{
> +       u32 reg;
> +
> +       reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       return !(reg & HOST_CTRL0_SIDDQ);
> +}
> +
> +static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phyclk = sphy->ref_clk_freq;
> +       u32 phyhost;
> +       u32 phyotg;
> +       u32 phyhsic;
> +       u32 ehcictrl;
> +       u32 ohcictrl;
> +
> +       atomic_inc(&sphy->host_usage);
> +
> +       if (exynos5_phyhost_is_on(regs)) {
> +               dev_info(sphy->dev, "Already power on PHY\n");
> +               return;
> +       }
> +
> +       /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */
> +       samsung_usbphy_cfg_sel(sphy, USB_PHY_TYPE_HOST);
> +
> +       /* Host configuration */
> +       phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       /* phy reference clock configuration */
> +       phyhost &= ~HOST_CTRL0_FSEL_MASK;
> +       phyhost |= HOST_CTRL0_FSEL(phyclk);
> +
> +       /* host phy reset */
> +       phyhost &= ~(HOST_CTRL0_PHYSWRST |
> +                       HOST_CTRL0_PHYSWRSTALL |
> +                       HOST_CTRL0_SIDDQ |
> +                       /* Enable normal mode of operation */
> +                       HOST_CTRL0_FORCESUSPEND |
> +                       HOST_CTRL0_FORCESLEEP);
> +
> +       /* Link reset */
> +       phyhost |= (HOST_CTRL0_LINKSWRST |
> +                       HOST_CTRL0_UTMISWRST |
> +                       /* COMMON Block configuration during suspend */
> +                       HOST_CTRL0_COMMONON_N);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +       udelay(10);
> +       phyhost &= ~(HOST_CTRL0_LINKSWRST |
> +                       HOST_CTRL0_UTMISWRST);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       /* OTG configuration */
> +       phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
> +
> +       /* phy reference clock configuration */
> +       phyotg &= ~OTG_SYS_FSEL_MASK;
> +       phyotg |= OTG_SYS_FSEL(phyclk);
> +
> +       /* Enable normal mode of operation */
> +       phyotg &= ~(OTG_SYS_FORCESUSPEND |
> +                       OTG_SYS_SIDDQ_UOTG |
> +                       OTG_SYS_FORCESLEEP |
> +                       OTG_SYS_REFCLKSEL_MASK |
> +                       /* COMMON Block configuration during suspend */
> +                       OTG_SYS_COMMON_ON);
> +
> +       /* OTG phy & link reset */
> +       phyotg |= (OTG_SYS_PHY0_SWRST |
> +                       OTG_SYS_LINKSWRST_UOTG |
> +                       OTG_SYS_PHYLINK_SWRESET |
> +                       OTG_SYS_OTGDISABLE |
> +                       /* Set phy refclk */
> +                       OTG_SYS_REFCLKSEL_CLKCORE);
> +
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +       udelay(10);
> +       phyotg &= ~(OTG_SYS_PHY0_SWRST |
> +                       OTG_SYS_LINKSWRST_UOTG |
> +                       OTG_SYS_PHYLINK_SWRESET);
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +
> +       /* HSIC phy configuration */
> +       phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
> +                       HSIC_CTRL_REFCLKSEL |
> +                       HSIC_CTRL_PHYSWRST);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +       udelay(10);
> +       phyhsic &= ~HSIC_CTRL_PHYSWRST;
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +
> +       udelay(80);
> +
> +       /* enable EHCI DMA burst */
> +       ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL);
> +       ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN |
> +                               HOST_EHCICTRL_ENAINCR4 |
> +                               HOST_EHCICTRL_ENAINCR8 |
> +                               HOST_EHCICTRL_ENAINCR16);
> +       writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL);
> +
> +       /* set ohci_suspend_on_n */
> +       ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL);
> +       ohcictrl |= HOST_OHCICTRL_SUSPLGCY;
> +       writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL);
> +}
> +
>  static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>  {
>         void __iomem *regs = sphy->regs;
> @@ -221,6 +541,41 @@ static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>         writel(rstcon, regs + SAMSUNG_RSTCON);
>  }
>
> +static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phyhost;
> +       u32 phyotg;
> +       u32 phyhsic;
> +
> +       if (atomic_dec_return(&sphy->host_usage) > 0) {
> +               dev_info(sphy->dev, "still being used\n");
> +               return;
> +       }
> +
> +       phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
> +                       HSIC_CTRL_REFCLKSEL |
> +                       HSIC_CTRL_SIDDQ |
> +                       HSIC_CTRL_FORCESLEEP |
> +                       HSIC_CTRL_FORCESUSPEND);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +
> +       phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +       phyhost |= (HOST_CTRL0_SIDDQ |
> +                       HOST_CTRL0_FORCESUSPEND |
> +                       HOST_CTRL0_FORCESLEEP |
> +                       HOST_CTRL0_PHYSWRST |
> +                       HOST_CTRL0_PHYSWRSTALL);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
> +       phyotg |= (OTG_SYS_FORCESUSPEND |
> +                       OTG_SYS_SIDDQ_UOTG |
> +                       OTG_SYS_FORCESLEEP);
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +}
> +
>  static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
>  {
>         void __iomem *regs = sphy->regs;
> @@ -263,10 +618,13 @@ static int samsung_usbphy_init(struct usb_phy *phy)
>         if (sphy->plat && sphy->plat->pmu_isolation)
>                 sphy->plat->pmu_isolation(false);
>         else
> -               samsung_usbphy_set_isolation(sphy, false);
> +               samsung_usbphy_set_isolation(sphy, false, sphy->phy_type);
>
>         /* Initialize usb phy registers */
> -       samsung_usbphy_enable(sphy);
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               samsung_exynos5_usbphy_enable(sphy);
> +       else
> +               samsung_usbphy_enable(sphy);
>
>         /* Disable the phy clock */
>         clk_disable_unprepare(sphy->clk);
> @@ -288,13 +646,16 @@ static void samsung_usbphy_shutdown(struct usb_phy *phy)
>         }
>
>         /* De-initialize usb phy registers */
> -       samsung_usbphy_disable(sphy);
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               samsung_exynos5_usbphy_disable(sphy);
> +       else
> +               samsung_usbphy_disable(sphy);
>
>         /* Enable phy isolation */
>         if (sphy->plat && sphy->plat->pmu_isolation)
>                 sphy->plat->pmu_isolation(true);
>         else
> -               samsung_usbphy_set_isolation(sphy, true);
> +               samsung_usbphy_set_isolation(sphy, true, sphy->phy_type);
>
>         clk_disable_unprepare(sphy->clk);
>  }
> @@ -339,12 +700,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>         if (!sphy)
>                 return -ENOMEM;
>
> -       clk = devm_clk_get(dev, "otg");
> -       if (IS_ERR(clk)) {
> -               dev_err(dev, "Failed to get otg clock\n");
> -               return PTR_ERR(clk);
> -       }
> -
>         sphy->dev = &pdev->dev;
>
>         ret = samsung_usbphy_parse_dt_param(sphy);
> @@ -361,7 +716,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>
>         sphy->plat              = pdata;
>         sphy->regs              = phy_base;
> -       sphy->clk               = clk;
>         sphy->phy.dev           = sphy->dev;
>         sphy->phy.label         = "samsung-usbphy";
>         sphy->phy.init          = samsung_usbphy_init;
> @@ -371,6 +725,17 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>
>         platform_set_drvdata(pdev, sphy);
>
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               clk = devm_clk_get(dev, "usbhost");
> +       else
> +               clk = devm_clk_get(dev, "otg");
> +       if (IS_ERR(clk)) {
> +               dev_err(dev, "Failed to get otg clock\n");
> +               return PTR_ERR(clk);
> +       }
> +
> +       sphy->clk = clk;
> +
>         return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>  }
>
> @@ -382,6 +747,10 @@ static int __exit samsung_usbphy_remove(struct platform_device *pdev)
>
>         if (sphy->devctrl_reg)
>                 iounmap(sphy->devctrl_reg);
> +       if (sphy->hostctrl_reg)
> +               iounmap(sphy->hostctrl_reg);
> +       if (sphy->phycfg_reg)
> +               iounmap(sphy->phycfg_reg);
>
>         return 0;
>  }
> @@ -394,6 +763,9 @@ static const struct of_device_id samsung_usbphy_dt_match[] = {
>         }, {
>                 .compatible = "samsung,exynos4210-usbphy",
>                 .data = (void *)TYPE_EXYNOS4210,
> +       }, {
> +               .compatible = "samsung,exynos5250-usbphy",
> +               .data = (void *)TYPE_EXYNOS5250,
>         },
>         {},
>  };
> @@ -407,6 +779,9 @@ static struct platform_device_id samsung_usbphy_driver_ids[] = {
>         }, {
>                 .name           = "exynos4210-usbphy",
>                 .driver_data    = TYPE_EXYNOS4210,
> +       }, {
> +               .name           = "exynos5250-usbphy",
> +               .driver_data    = TYPE_EXYNOS5250,
>         },
>         {},
>  };
> diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
> index 9167826..aecefaf 100644
> --- a/include/linux/usb/samsung_usb_phy.h
> +++ b/include/linux/usb/samsung_usb_phy.h
> @@ -10,7 +10,20 @@
>   * option) any later version.
>   */
>
> +#include <linux/usb/phy.h>
> +
>  enum samsung_usb_phy_type {
>         USB_PHY_TYPE_DEVICE,
>         USB_PHY_TYPE_HOST,
>  };
> +
> +#ifdef CONFIG_SAMSUNG_USBPHY
> +extern int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type);
> +#else
> +static inline int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_SAMSUNG_USBPHY */
> --
> 1.7.6.5
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
@ 2012-12-19  5:40     ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:40 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	p.paneri-Sze3O3UU22JBDgjK7y7TUQ,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	jg1.han-Sze3O3UU22JBDgjK7y7TUQ, balbi-l0cyMroinI0,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	sylvester.nawrocki-Re5JQEeQqe8AvxtiuMwx3w, kishon-l0cyMroinI0,
	Vivek Gautam

CC: Doug Anderson.


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> This patch adds host phy support to samsung-usbphy.c and
> further adds support for samsung's exynos5250 usb-phy.
>
> Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
>  drivers/usb/phy/Kconfig                            |    2 +-
>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
>  include/linux/usb/samsung_usb_phy.h                |   13 +
>  4 files changed, 454 insertions(+), 51 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> index a7b28b2..2ec5400 100644
> --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -1,23 +1,38 @@
>  * Samsung's usb phy transceiver
>
> -The Samsung's phy transceiver is used for controlling usb otg phy for
> -s3c-hsotg usb device controller.
> +The Samsung's phy transceiver is used for controlling usb phy for
> +s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
> +across Samsung SOCs.
>  TODO: Adding the PHY binding with controller(s) according to the under
>  developement generic PHY driver.
>
>  Required properties:
> +
> +Exynos4210:
>  - compatible : should be "samsung,exynos4210-usbphy"
>  - reg : base physical address of the phy registers and length of memory mapped
>         region.
>
> +Exynos5250:
> +- compatible : should be "samsung,exynos5250-usbphy"
> +- reg : base physical address of the phy registers and length of memory mapped
> +       region.
> +
>  Optional properties:
>  - samsung,usb-phyhandle : should point to usb-phyhandle sub-node which provides
>                         binding data to enable/disable device PHY handled by
> -                       PMU register.
> +                       PMU register; or to configure usb2.0 phy handled by
> +                       SYSREG.
>
>                         Required properties:
>                         - compatible : should be "samsung,usbdev-phyctrl" for
> -                                       DEVICE type phy.
> +                                      DEVICE type phy; or
> +                                      should be "samsung,usbhost-phyctrl" for
> +                                      HOST type phy; or
> +                                      should be "samsung,usb-phycfg" for
> +                                      USB2.0 PHY_CFG.
>                         - samsung,phyhandle-reg: base physical address of
> -                                               PHY_CONTROL register in PMU.
> +                                                PHY_CONTROL register in PMU;
> +                                                or USB2.0 PHY_CFG register
> +                                                in SYSREG.
>  - samsung,enable-mask : should be '1'
> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> index 17ad743..13c0eaf 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -47,7 +47,7 @@ config USB_RCAR_PHY
>
>  config SAMSUNG_USBPHY
>         bool "Samsung USB PHY controller Driver"
> -       depends on USB_S3C_HSOTG
> +       depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
>         select USB_OTG_UTILS
>         help
>           Enable this to support Samsung USB phy controller for samsung
> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
> index 4ceabe3..621348a 100644
> --- a/drivers/usb/phy/samsung-usbphy.c
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -5,7 +5,8 @@
>   *
>   * Author: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>   *
> - * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
> + * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
> + * OHCI-EXYNOS controllers.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -24,7 +25,7 @@
>  #include <linux/err.h>
>  #include <linux/io.h>
>  #include <linux/of.h>
> -#include <linux/usb/otg.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <linux/platform_data/samsung-usbphy.h>
>
>  /* Register definitions */
> @@ -56,6 +57,103 @@
>  #define RSTCON_HLINK_SWRST                     (0x1 << 1)
>  #define RSTCON_SWRST                           (0x1 << 0)
>
> +/* EXYNOS5 */
> +#define EXYNOS5_PHY_HOST_CTRL0                 (0x00)
> +
> +#define HOST_CTRL0_PHYSWRSTALL                 (0x1 << 31)
> +
> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
> +
> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
> +
> +#define HOST_CTRL0_TESTBURNIN                  (0x1 << 11)
> +#define HOST_CTRL0_RETENABLE                   (0x1 << 10)
> +#define HOST_CTRL0_COMMONON_N                  (0x1 << 9)
> +#define HOST_CTRL0_SIDDQ                       (0x1 << 6)
> +#define HOST_CTRL0_FORCESLEEP                  (0x1 << 5)
> +#define HOST_CTRL0_FORCESUSPEND                        (0x1 << 4)
> +#define HOST_CTRL0_WORDINTERFACE               (0x1 << 3)
> +#define HOST_CTRL0_UTMISWRST                   (0x1 << 2)
> +#define HOST_CTRL0_LINKSWRST                   (0x1 << 1)
> +#define HOST_CTRL0_PHYSWRST                    (0x1 << 0)
> +
> +#define EXYNOS5_PHY_HOST_TUNE0                 (0x04)
> +
> +#define EXYNOS5_PHY_HSIC_CTRL1                 (0x10)
> +
> +#define EXYNOS5_PHY_HSIC_TUNE1                 (0x14)
> +
> +#define EXYNOS5_PHY_HSIC_CTRL2                 (0x20)
> +
> +#define EXYNOS5_PHY_HSIC_TUNE2                 (0x24)
> +
> +#define HSIC_CTRL_REFCLKSEL_MASK               (0x3)
> +#define HSIC_CTRL_REFCLKSEL                    (0x2 << 23)
> +
> +#define HSIC_CTRL_REFCLKDIV_MASK               (0x7f)
> +#define HSIC_CTRL_REFCLKDIV(_x)                        ((_x) << 16)
> +#define HSIC_CTRL_REFCLKDIV_12                 (0x24 << 16)
> +#define HSIC_CTRL_REFCLKDIV_15                 (0x1c << 16)
> +#define HSIC_CTRL_REFCLKDIV_16                 (0x1a << 16)
> +#define HSIC_CTRL_REFCLKDIV_19_2               (0x15 << 16)
> +#define HSIC_CTRL_REFCLKDIV_20                 (0x14)
> +
> +#define HSIC_CTRL_SIDDQ                                (0x1 << 6)
> +#define HSIC_CTRL_FORCESLEEP                   (0x1 << 5)
> +#define HSIC_CTRL_FORCESUSPEND                 (0x1 << 4)
> +#define HSIC_CTRL_WORDINTERFACE                        (0x1 << 3)
> +#define HSIC_CTRL_UTMISWRST                    (0x1 << 2)
> +#define HSIC_CTRL_PHYSWRST                     (0x1 << 0)
> +
> +#define EXYNOS5_PHY_HOST_EHCICTRL              (0x30)
> +
> +#define HOST_EHCICTRL_ENAINCRXALIGN            (0x1 << 29)
> +#define HOST_EHCICTRL_ENAINCR4                 (0x1 << 28)
> +#define HOST_EHCICTRL_ENAINCR8                 (0x1 << 27)
> +#define HOST_EHCICTRL_ENAINCR16                        (0x1 << 26)
> +
> +#define EXYNOS5_PHY_HOST_OHCICTRL              (0x34)
> +
> +#define HOST_OHCICTRL_SUSPLGCY                 (0x1 << 3)
> +#define HOST_OHCICTRL_APPSTARTCLK              (0x1 << 2)
> +#define HOST_OHCICTRL_CNTSEL                   (0x1 << 1)
> +#define HOST_OHCICTRL_CLKCKTRST                        (0x1 << 0)
> +
> +#define EXYNOS5_PHY_OTG_SYS                    (0x38)
> +
> +#define OTG_SYS_PHYLINK_SWRESET                        (0x1 << 14)
> +#define OTG_SYS_LINKSWRST_UOTG                 (0x1 << 13)
> +#define OTG_SYS_PHY0_SWRST                     (0x1 << 12)
> +
> +#define OTG_SYS_REFCLKSEL_MASK                 (0x3 << 9)
> +#define OTG_SYS_REFCLKSEL_XTAL                 (0x0 << 9)
> +#define OTG_SYS_REFCLKSEL_EXTL                 (0x1 << 9)
> +#define OTG_SYS_REFCLKSEL_CLKCORE              (0x2 << 9)
> +
> +#define OTG_SYS_IDPULLUP_UOTG                  (0x1 << 8)
> +#define OTG_SYS_COMMON_ON                      (0x1 << 7)
> +
> +#define OTG_SYS_FSEL_MASK                      (0x7 << 4)
> +#define OTG_SYS_FSEL(_x)                       ((_x) << 4)
> +
> +#define OTG_SYS_FORCESLEEP                     (0x1 << 3)
> +#define OTG_SYS_OTGDISABLE                     (0x1 << 2)
> +#define OTG_SYS_SIDDQ_UOTG                     (0x1 << 1)
> +#define OTG_SYS_FORCESUSPEND                   (0x1 << 0)
> +
> +#define EXYNOS5_PHY_OTG_TUNE                   (0x40)
> +
>  #ifndef MHZ
>  #define MHZ (1000*1000)
>  #endif
> @@ -63,6 +161,7 @@
>  enum samsung_cpu_type {
>         TYPE_S3C64XX,
>         TYPE_EXYNOS4210,
> +       TYPE_EXYNOS5250,
>  };
>
>  /*
> @@ -73,9 +172,13 @@ enum samsung_cpu_type {
>   * @clk: usb phy clock
>   * @regs: usb phy register memory base
>   * @devctrl_reg: usb device phy-control pmu register memory base
> + * @hostctrl_reg: usb host phy-control pmu register memory base
> + * @phycfg_reg: usb2.0 phy-cfg system register memory base
>   * @en_mask: enable mask
>   * @ref_clk_freq: reference clock frequency selection
>   * @cpu_type: machine identifier
> + * @phy_type: It keeps track of the PHY type.
> + * @host_usage: host_phy usage count.
>   */
>  struct samsung_usbphy {
>         struct usb_phy  phy;
> @@ -84,9 +187,13 @@ struct samsung_usbphy {
>         struct clk      *clk;
>         void __iomem    *regs;
>         void __iomem    *devctrl_reg;
> +       void __iomem    *hostctrl_reg;
> +       void __iomem    *phycfg_reg;
>         u32             en_mask;
>         int             ref_clk_freq;
>         int             cpu_type;
> +       enum samsung_usb_phy_type phy_type;
> +       atomic_t        host_usage;
>  };
>
>  #define phy_to_sphy(x)         container_of((x), struct samsung_usbphy, phy)
> @@ -96,26 +203,49 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
>         struct device_node *usb_phyctrl;
>         u32 reg;
>         int lenp;
> +       int count = 0;
>
>         if (!sphy->dev->of_node) {
>                 sphy->devctrl_reg = NULL;
>                 return -ENODEV;
>         }
>
> -       if (of_get_property(sphy->dev->of_node, "samsung,usb-phyhandle", &lenp)) {
> -               usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
> -                                               "samsung,usb-phyhandle", 0);
> -               if (!usb_phyctrl) {
> -                       dev_warn(sphy->dev, "Can't get usb-phy handle\n");
> -                       sphy->devctrl_reg = NULL;
> -               }
> -
> -               of_property_read_u32(usb_phyctrl, "samsung,phyhandle-reg", &reg);
> +       if (of_get_property(sphy->dev->of_node,
> +                       "samsung,usb-phyhandle", &lenp)) {
> +               do {
> +                       usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
> +                                                       "samsung,usb-phyhandle",
> +                                                       count++);
> +                       if (!usb_phyctrl) {
> +                               dev_warn(sphy->dev,
> +                                       "Can't get usb-phy handle\n");
> +                               sphy->devctrl_reg = NULL;
> +                       }
> +
> +                       of_property_read_u32(usb_phyctrl,
> +                                       "samsung,phyhandle-reg", &reg);
> +
> +                       /*
> +                        * Considering here the maximum number of configurable
> +                        * register settings: DEVICE_PHY_CONTROL
> +                        *                    HOST_PHY_CONTROL
> +                        *                    PHY20_CFG
> +                        */
> +                       if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usbdev-phyctrl"))
> +                               sphy->devctrl_reg = ioremap(reg, SZ_4);
> +                       else if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usbhost-phyctrl"))
> +                               sphy->hostctrl_reg = ioremap(reg, SZ_4);
> +                       else if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usb-phycfg"))
> +                               sphy->phycfg_reg = ioremap(reg, SZ_4);
> +
> +                       of_property_read_u32(sphy->dev->of_node,
> +                                       "samsung,enable-mask", &sphy->en_mask);
> +               } while (of_parse_phandle(sphy->dev->of_node,
> +                               "samsung,usb-phyhandle", count));
>
> -               sphy->devctrl_reg = ioremap(reg, SZ_4);
> -
> -               of_property_read_u32(sphy->dev->of_node, "samsung,enable-mask",
> -                                                       &sphy->en_mask);
>                 of_node_put(usb_phyctrl);
>         } else {
>                 dev_warn(sphy->dev, "Can't get usb-phy handle\n");
> @@ -129,13 +259,18 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
>   * Set isolation here for phy.
>   * SOCs control this by controlling corresponding PMU registers
>   */
> -static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
> +static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy,
> +                                                       int on, int type)
>  {
> -       void __iomem *usb_phyctrl_reg;
> +       void __iomem *usb_phyctrl_reg = NULL;
>         u32 en_mask = sphy->en_mask;
>         u32 reg;
>
> -       usb_phyctrl_reg = sphy->devctrl_reg;
> +       if (type == USB_PHY_TYPE_DEVICE) {
> +               usb_phyctrl_reg = sphy->devctrl_reg;
> +       } else if (type == USB_PHY_TYPE_HOST) {
> +               usb_phyctrl_reg = sphy->hostctrl_reg;
> +       }
>
>         if (!usb_phyctrl_reg) {
>                 dev_warn(sphy->dev, "Can't set pmu isolation\n");
> @@ -151,6 +286,47 @@ static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
>  }
>
>  /*
> + * Configure the mode of working og usb-phy here: HOST/DEVICE.
> + * SOCs control this by controlling corresponding system register
> + */
> +static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy, int type)
> +{
> +       void __iomem *usb_phycfg_reg;
> +       u32 en_mask = sphy->en_mask;
> +       u32 reg;
> +
> +       usb_phycfg_reg = sphy->phycfg_reg;
> +
> +       if (!usb_phycfg_reg) {
> +               dev_warn(sphy->dev, "Can't select specified phy mode\n");
> +               return;
> +       }
> +
> +       reg = readl(usb_phycfg_reg);
> +
> +       if (type == USB_PHY_TYPE_DEVICE)
> +               writel(reg & ~en_mask, usb_phycfg_reg);
> +       else if (type == USB_PHY_TYPE_HOST)
> +               writel(reg | en_mask, usb_phycfg_reg);
> +}
> +
> +/*
> + * PHYs are different for USB Device and USB Host. Controllers can make
> + * sure that the correct PHY type is selected by calling this function
> + * before any PHY operation.
> + */
> +int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type)
> +{
> +       struct samsung_usbphy *sphy = phy_to_sphy(phy);
> +
> +       if (sphy->phy_type != phy_type)
> +               sphy->phy_type = phy_type;
> +
> +       return 0;
> +}
> +
> +/*
>   * Returns reference clock frequency selection value
>   */
>  static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
> @@ -158,34 +334,178 @@ static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
>         struct clk *ref_clk;
>         int refclk_freq = 0;
>
> -       ref_clk = clk_get(sphy->dev, "xusbxti");
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               ref_clk = clk_get(sphy->dev, "ext_xtal");
> +       else
> +               ref_clk = clk_get(sphy->dev, "xusbxti");
>         if (IS_ERR(ref_clk)) {
>                 dev_err(sphy->dev, "Failed to get reference clock\n");
>                 return PTR_ERR(ref_clk);
>         }
>
> -       switch (clk_get_rate(ref_clk)) {
> -       case 12 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_12M;
> -               break;
> -       case 24 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_24M;
> -               break;
> -       case 48 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_48M;
> -               break;
> -       default:
> -               if (sphy->cpu_type == TYPE_S3C64XX)
> -                       refclk_freq = PHYCLK_CLKSEL_48M;
> -               else
> +       if (sphy->cpu_type == TYPE_EXYNOS5250) {
> +               /* set clock frequency for PLL */
> +               switch (clk_get_rate(ref_clk)) {
> +               case 96 * 100000:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
> +                       break;
> +               case 10 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_10M;
> +                       break;
> +               case 12 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_12M;
> +                       break;
> +               case 192 * 100000:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_19200K;
> +                       break;
> +               case 20 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_20M;
> +                       break;
> +               case 50 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_50M;
> +                       break;
> +               case 24 * MHZ:
> +               default:
> +                       /* default reference clock */
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_24M;
> +                       break;
> +               }
> +       } else {
> +               switch (clk_get_rate(ref_clk)) {
> +               case 12 * MHZ:
> +                       refclk_freq = PHYCLK_CLKSEL_12M;
> +                       break;
> +               case 24 * MHZ:
>                         refclk_freq = PHYCLK_CLKSEL_24M;
> -               break;
> +                       break;
> +               case 48 * MHZ:
> +                       refclk_freq = PHYCLK_CLKSEL_48M;
> +                       break;
> +               default:
> +                       if (sphy->cpu_type == TYPE_S3C64XX)
> +                               refclk_freq = PHYCLK_CLKSEL_48M;
> +                       else
> +                               refclk_freq = PHYCLK_CLKSEL_24M;
> +                       break;
> +               }
>         }
>         clk_put(ref_clk);
>
>         return refclk_freq;
>  }
>
> +static int exynos5_phyhost_is_on(void *regs)
> +{
> +       u32 reg;
> +
> +       reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       return !(reg & HOST_CTRL0_SIDDQ);
> +}
> +
> +static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phyclk = sphy->ref_clk_freq;
> +       u32 phyhost;
> +       u32 phyotg;
> +       u32 phyhsic;
> +       u32 ehcictrl;
> +       u32 ohcictrl;
> +
> +       atomic_inc(&sphy->host_usage);
> +
> +       if (exynos5_phyhost_is_on(regs)) {
> +               dev_info(sphy->dev, "Already power on PHY\n");
> +               return;
> +       }
> +
> +       /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */
> +       samsung_usbphy_cfg_sel(sphy, USB_PHY_TYPE_HOST);
> +
> +       /* Host configuration */
> +       phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       /* phy reference clock configuration */
> +       phyhost &= ~HOST_CTRL0_FSEL_MASK;
> +       phyhost |= HOST_CTRL0_FSEL(phyclk);
> +
> +       /* host phy reset */
> +       phyhost &= ~(HOST_CTRL0_PHYSWRST |
> +                       HOST_CTRL0_PHYSWRSTALL |
> +                       HOST_CTRL0_SIDDQ |
> +                       /* Enable normal mode of operation */
> +                       HOST_CTRL0_FORCESUSPEND |
> +                       HOST_CTRL0_FORCESLEEP);
> +
> +       /* Link reset */
> +       phyhost |= (HOST_CTRL0_LINKSWRST |
> +                       HOST_CTRL0_UTMISWRST |
> +                       /* COMMON Block configuration during suspend */
> +                       HOST_CTRL0_COMMONON_N);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +       udelay(10);
> +       phyhost &= ~(HOST_CTRL0_LINKSWRST |
> +                       HOST_CTRL0_UTMISWRST);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       /* OTG configuration */
> +       phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
> +
> +       /* phy reference clock configuration */
> +       phyotg &= ~OTG_SYS_FSEL_MASK;
> +       phyotg |= OTG_SYS_FSEL(phyclk);
> +
> +       /* Enable normal mode of operation */
> +       phyotg &= ~(OTG_SYS_FORCESUSPEND |
> +                       OTG_SYS_SIDDQ_UOTG |
> +                       OTG_SYS_FORCESLEEP |
> +                       OTG_SYS_REFCLKSEL_MASK |
> +                       /* COMMON Block configuration during suspend */
> +                       OTG_SYS_COMMON_ON);
> +
> +       /* OTG phy & link reset */
> +       phyotg |= (OTG_SYS_PHY0_SWRST |
> +                       OTG_SYS_LINKSWRST_UOTG |
> +                       OTG_SYS_PHYLINK_SWRESET |
> +                       OTG_SYS_OTGDISABLE |
> +                       /* Set phy refclk */
> +                       OTG_SYS_REFCLKSEL_CLKCORE);
> +
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +       udelay(10);
> +       phyotg &= ~(OTG_SYS_PHY0_SWRST |
> +                       OTG_SYS_LINKSWRST_UOTG |
> +                       OTG_SYS_PHYLINK_SWRESET);
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +
> +       /* HSIC phy configuration */
> +       phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
> +                       HSIC_CTRL_REFCLKSEL |
> +                       HSIC_CTRL_PHYSWRST);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +       udelay(10);
> +       phyhsic &= ~HSIC_CTRL_PHYSWRST;
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +
> +       udelay(80);
> +
> +       /* enable EHCI DMA burst */
> +       ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL);
> +       ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN |
> +                               HOST_EHCICTRL_ENAINCR4 |
> +                               HOST_EHCICTRL_ENAINCR8 |
> +                               HOST_EHCICTRL_ENAINCR16);
> +       writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL);
> +
> +       /* set ohci_suspend_on_n */
> +       ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL);
> +       ohcictrl |= HOST_OHCICTRL_SUSPLGCY;
> +       writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL);
> +}
> +
>  static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>  {
>         void __iomem *regs = sphy->regs;
> @@ -221,6 +541,41 @@ static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>         writel(rstcon, regs + SAMSUNG_RSTCON);
>  }
>
> +static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phyhost;
> +       u32 phyotg;
> +       u32 phyhsic;
> +
> +       if (atomic_dec_return(&sphy->host_usage) > 0) {
> +               dev_info(sphy->dev, "still being used\n");
> +               return;
> +       }
> +
> +       phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
> +                       HSIC_CTRL_REFCLKSEL |
> +                       HSIC_CTRL_SIDDQ |
> +                       HSIC_CTRL_FORCESLEEP |
> +                       HSIC_CTRL_FORCESUSPEND);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +
> +       phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +       phyhost |= (HOST_CTRL0_SIDDQ |
> +                       HOST_CTRL0_FORCESUSPEND |
> +                       HOST_CTRL0_FORCESLEEP |
> +                       HOST_CTRL0_PHYSWRST |
> +                       HOST_CTRL0_PHYSWRSTALL);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
> +       phyotg |= (OTG_SYS_FORCESUSPEND |
> +                       OTG_SYS_SIDDQ_UOTG |
> +                       OTG_SYS_FORCESLEEP);
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +}
> +
>  static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
>  {
>         void __iomem *regs = sphy->regs;
> @@ -263,10 +618,13 @@ static int samsung_usbphy_init(struct usb_phy *phy)
>         if (sphy->plat && sphy->plat->pmu_isolation)
>                 sphy->plat->pmu_isolation(false);
>         else
> -               samsung_usbphy_set_isolation(sphy, false);
> +               samsung_usbphy_set_isolation(sphy, false, sphy->phy_type);
>
>         /* Initialize usb phy registers */
> -       samsung_usbphy_enable(sphy);
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               samsung_exynos5_usbphy_enable(sphy);
> +       else
> +               samsung_usbphy_enable(sphy);
>
>         /* Disable the phy clock */
>         clk_disable_unprepare(sphy->clk);
> @@ -288,13 +646,16 @@ static void samsung_usbphy_shutdown(struct usb_phy *phy)
>         }
>
>         /* De-initialize usb phy registers */
> -       samsung_usbphy_disable(sphy);
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               samsung_exynos5_usbphy_disable(sphy);
> +       else
> +               samsung_usbphy_disable(sphy);
>
>         /* Enable phy isolation */
>         if (sphy->plat && sphy->plat->pmu_isolation)
>                 sphy->plat->pmu_isolation(true);
>         else
> -               samsung_usbphy_set_isolation(sphy, true);
> +               samsung_usbphy_set_isolation(sphy, true, sphy->phy_type);
>
>         clk_disable_unprepare(sphy->clk);
>  }
> @@ -339,12 +700,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>         if (!sphy)
>                 return -ENOMEM;
>
> -       clk = devm_clk_get(dev, "otg");
> -       if (IS_ERR(clk)) {
> -               dev_err(dev, "Failed to get otg clock\n");
> -               return PTR_ERR(clk);
> -       }
> -
>         sphy->dev = &pdev->dev;
>
>         ret = samsung_usbphy_parse_dt_param(sphy);
> @@ -361,7 +716,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>
>         sphy->plat              = pdata;
>         sphy->regs              = phy_base;
> -       sphy->clk               = clk;
>         sphy->phy.dev           = sphy->dev;
>         sphy->phy.label         = "samsung-usbphy";
>         sphy->phy.init          = samsung_usbphy_init;
> @@ -371,6 +725,17 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>
>         platform_set_drvdata(pdev, sphy);
>
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               clk = devm_clk_get(dev, "usbhost");
> +       else
> +               clk = devm_clk_get(dev, "otg");
> +       if (IS_ERR(clk)) {
> +               dev_err(dev, "Failed to get otg clock\n");
> +               return PTR_ERR(clk);
> +       }
> +
> +       sphy->clk = clk;
> +
>         return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>  }
>
> @@ -382,6 +747,10 @@ static int __exit samsung_usbphy_remove(struct platform_device *pdev)
>
>         if (sphy->devctrl_reg)
>                 iounmap(sphy->devctrl_reg);
> +       if (sphy->hostctrl_reg)
> +               iounmap(sphy->hostctrl_reg);
> +       if (sphy->phycfg_reg)
> +               iounmap(sphy->phycfg_reg);
>
>         return 0;
>  }
> @@ -394,6 +763,9 @@ static const struct of_device_id samsung_usbphy_dt_match[] = {
>         }, {
>                 .compatible = "samsung,exynos4210-usbphy",
>                 .data = (void *)TYPE_EXYNOS4210,
> +       }, {
> +               .compatible = "samsung,exynos5250-usbphy",
> +               .data = (void *)TYPE_EXYNOS5250,
>         },
>         {},
>  };
> @@ -407,6 +779,9 @@ static struct platform_device_id samsung_usbphy_driver_ids[] = {
>         }, {
>                 .name           = "exynos4210-usbphy",
>                 .driver_data    = TYPE_EXYNOS4210,
> +       }, {
> +               .name           = "exynos5250-usbphy",
> +               .driver_data    = TYPE_EXYNOS5250,
>         },
>         {},
>  };
> diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
> index 9167826..aecefaf 100644
> --- a/include/linux/usb/samsung_usb_phy.h
> +++ b/include/linux/usb/samsung_usb_phy.h
> @@ -10,7 +10,20 @@
>   * option) any later version.
>   */
>
> +#include <linux/usb/phy.h>
> +
>  enum samsung_usb_phy_type {
>         USB_PHY_TYPE_DEVICE,
>         USB_PHY_TYPE_HOST,
>  };
> +
> +#ifdef CONFIG_SAMSUNG_USBPHY
> +extern int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type);
> +#else
> +static inline int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_SAMSUNG_USBPHY */
> --
> 1.7.6.5
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support
  2012-12-18 14:43 ` [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support Vivek Gautam
@ 2012-12-19  5:41   ` Vivek Gautam
  2012-12-19 23:30   ` Doug Anderson
  1 sibling, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:41 UTC (permalink / raw)
  To: linux-usb
  Cc: dianders, devicetree-discuss, linux-kernel, linux-samsung-soc,
	gregkh, balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri, Vivek Gautam

CC: Doug Anderson.


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> Adding the phy driver to ehci-s5p. Keeping the platform data
> for continuing the smooth operation for boards which still uses it
>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> Acked-by: Jingoo Han <jg1.han@samsung.com>
> ---
>  drivers/usb/host/ehci-s5p.c |   70 ++++++++++++++++++++++++++++++-------------
>  1 files changed, 49 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
> index 46ca5ef..50c93af 100644
> --- a/drivers/usb/host/ehci-s5p.c
> +++ b/drivers/usb/host/ehci-s5p.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/of_gpio.h>
>  #include <linux/platform_data/usb-ehci-s5p.h>
> +#include <linux/usb/phy.h>
>  #include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
> @@ -33,6 +34,8 @@ struct s5p_ehci_hcd {
>         struct device *dev;
>         struct usb_hcd *hcd;
>         struct clk *clk;
> +       struct usb_phy *phy;
> +       struct s5p_ehci_platdata *pdata;
>  };
>
>  static const struct hc_driver s5p_ehci_hc_driver = {
> @@ -66,6 +69,30 @@ static const struct hc_driver s5p_ehci_hc_driver = {
>         .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
>  };
>
> +static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci)
> +{
> +       struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
> +
> +       if (s5p_ehci->phy) {
> +               samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);
> +               usb_phy_init(s5p_ehci->phy);
> +       } else if (s5p_ehci->pdata->phy_init) {
> +               s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       }
> +}
> +
> +static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci)
> +{
> +       struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
> +
> +       if (s5p_ehci->phy) {
> +               samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);
> +               usb_phy_shutdown(s5p_ehci->phy);
> +       } else if (s5p_ehci->pdata->phy_exit) {
> +               s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       }
> +}
> +
>  static void s5p_setup_vbus_gpio(struct platform_device *pdev)
>  {
>         int err;
> @@ -88,20 +115,15 @@ static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
>
>  static int s5p_ehci_probe(struct platform_device *pdev)
>  {
> -       struct s5p_ehci_platdata *pdata;
> +       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>         struct s5p_ehci_hcd *s5p_ehci;
>         struct usb_hcd *hcd;
>         struct ehci_hcd *ehci;
>         struct resource *res;
> +       struct usb_phy *phy;
>         int irq;
>         int err;
>
> -       pdata = pdev->dev.platform_data;
> -       if (!pdata) {
> -               dev_err(&pdev->dev, "No platform data defined\n");
> -               return -EINVAL;
> -       }
> -
>         /*
>          * Right now device-tree probed devices don't get dma_mask set.
>          * Since shared usb code relies on it, set it here for now.
> @@ -119,6 +141,19 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>         if (!s5p_ehci)
>                 return -ENOMEM;
>
> +       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
> +       if (IS_ERR_OR_NULL(phy)) {
> +               /* Fallback to pdata */
> +               if (!pdata) {
> +                       dev_err(&pdev->dev, "no platform data or transceiver defined\n");
> +                       return -EPROBE_DEFER;
> +               } else {
> +                       s5p_ehci->pdata = pdata;
> +               }
> +       } else {
> +               s5p_ehci->phy = phy;
> +       }
> +
>         s5p_ehci->dev = &pdev->dev;
>
>         hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev,
> @@ -164,8 +199,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>                 goto fail_io;
>         }
>
> -       if (pdata->phy_init)
> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       s5p_ehci_phy_enable(s5p_ehci);
>
>         ehci = hcd_to_ehci(hcd);
>         ehci->caps = hcd->regs;
> @@ -176,13 +210,15 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>         err = usb_add_hcd(hcd, irq, IRQF_SHARED);
>         if (err) {
>                 dev_err(&pdev->dev, "Failed to add USB HCD\n");
> -               goto fail_io;
> +               goto fail_add_hcd;
>         }
>
>         platform_set_drvdata(pdev, s5p_ehci);
>
>         return 0;
>
> +fail_add_hcd:
> +       s5p_ehci_phy_disable(s5p_ehci);
>  fail_io:
>         clk_disable_unprepare(s5p_ehci->clk);
>  fail_clk:
> @@ -192,14 +228,12 @@ fail_clk:
>
>  static int s5p_ehci_remove(struct platform_device *pdev)
>  {
> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>         struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
>         struct usb_hcd *hcd = s5p_ehci->hcd;
>
>         usb_remove_hcd(hcd);
>
> -       if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       s5p_ehci_phy_disable(s5p_ehci);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -223,14 +257,11 @@ static int s5p_ehci_suspend(struct device *dev)
>         struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
>         struct usb_hcd *hcd = s5p_ehci->hcd;
>         bool do_wakeup = device_may_wakeup(dev);
> -       struct platform_device *pdev = to_platform_device(dev);
> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>         int rc;
>
>         rc = ehci_suspend(hcd, do_wakeup);
>
> -       if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       s5p_ehci_phy_disable(s5p_ehci);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -241,13 +272,10 @@ static int s5p_ehci_resume(struct device *dev)
>  {
>         struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
>         struct usb_hcd *hcd = s5p_ehci->hcd;
> -       struct platform_device *pdev = to_platform_device(dev);
> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>
>         clk_prepare_enable(s5p_ehci->clk);
>
> -       if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       s5p_ehci_phy_enable(s5p_ehci);
>
>         /* DMA burst Enable */
>         writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 4/4] USB: ohci-exynos: Add phy driver support
@ 2012-12-19  5:41     ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:41 UTC (permalink / raw)
  To: linux-usb
  Cc: dianders, devicetree-discuss, linux-kernel, linux-samsung-soc,
	gregkh, balbi, stern, kgene.kim, thomas.abraham, rob.herring,
	grant.likely, sylvester.nawrocki, jg1.han, yulgon.kim, kishon,
	p.paneri, Vivek Gautam

CC: Doug Anderson.


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> Adding the phy-driver to ohci-exynos. Keeping the platform data
> for continuing the smooth operation for boards which still uses it
>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> Acked-by: Jingoo Han <jg1.han@samsung.com>
> ---
>  drivers/usb/host/ohci-exynos.c |   70 ++++++++++++++++++++++++++++------------
>  1 files changed, 49 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
> index 804fb62..c92ab7b 100644
> --- a/drivers/usb/host/ohci-exynos.c
> +++ b/drivers/usb/host/ohci-exynos.c
> @@ -15,6 +15,7 @@
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/usb-exynos.h>
> +#include <linux/usb/phy.h>
>  #include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
> @@ -22,8 +23,34 @@ struct exynos_ohci_hcd {
>         struct device *dev;
>         struct usb_hcd *hcd;
>         struct clk *clk;
> +       struct usb_phy *phy;
> +       struct exynos4_ohci_platdata *pdata;
>  };
>
> +static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
> +{
> +       struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
> +
> +       if (exynos_ohci->phy) {
> +               samsung_usbphy_set_type(exynos_ohci->phy, USB_PHY_TYPE_HOST);
> +               usb_phy_init(exynos_ohci->phy);
> +       } else if (exynos_ohci->pdata->phy_init) {
> +               exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       }
> +}
> +
> +static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
> +{
> +       struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
> +
> +       if (exynos_ohci->phy) {
> +               samsung_usbphy_set_type(exynos_ohci->phy, USB_PHY_TYPE_HOST);
> +               usb_phy_shutdown(exynos_ohci->phy);
> +       } else if (exynos_ohci->pdata->phy_exit) {
> +               exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       }
> +}
> +
>  static int ohci_exynos_reset(struct usb_hcd *hcd)
>  {
>         return ohci_init(hcd_to_ohci(hcd));
> @@ -79,20 +106,15 @@ static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
>
>  static int exynos_ohci_probe(struct platform_device *pdev)
>  {
> -       struct exynos4_ohci_platdata *pdata;
> +       struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
>         struct exynos_ohci_hcd *exynos_ohci;
>         struct usb_hcd *hcd;
>         struct ohci_hcd *ohci;
>         struct resource *res;
> +       struct usb_phy *phy;
>         int irq;
>         int err;
>
> -       pdata = pdev->dev.platform_data;
> -       if (!pdata) {
> -               dev_err(&pdev->dev, "No platform data defined\n");
> -               return -EINVAL;
> -       }
> -
>         /*
>          * Right now device-tree probed devices don't get dma_mask set.
>          * Since shared usb code relies on it, set it here for now.
> @@ -108,6 +130,19 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>         if (!exynos_ohci)
>                 return -ENOMEM;
>
> +       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
> +       if (IS_ERR_OR_NULL(phy)) {
> +               /* Fallback to pdata */
> +               if (!pdata) {
> +                       dev_err(&pdev->dev, "no platform data or transceiver defined\n");
> +                       return -EPROBE_DEFER;
> +               } else {
> +                       exynos_ohci->pdata = pdata;
> +               }
> +       } else {
> +               exynos_ohci->phy = phy;
> +       }
> +
>         exynos_ohci->dev = &pdev->dev;
>
>         hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
> @@ -153,8 +188,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>                 goto fail_io;
>         }
>
> -       if (pdata->phy_init)
> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       exynos_ohci_phy_enable(exynos_ohci);
>
>         ohci = hcd_to_ohci(hcd);
>         ohci_hcd_init(ohci);
> @@ -162,13 +196,15 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>         err = usb_add_hcd(hcd, irq, IRQF_SHARED);
>         if (err) {
>                 dev_err(&pdev->dev, "Failed to add USB HCD\n");
> -               goto fail_io;
> +               goto fail_add_hcd;
>         }
>
>         platform_set_drvdata(pdev, exynos_ohci);
>
>         return 0;
>
> +fail_add_hcd:
> +       exynos_ohci_phy_disable(exynos_ohci);
>  fail_io:
>         clk_disable_unprepare(exynos_ohci->clk);
>  fail_clk:
> @@ -178,14 +214,12 @@ fail_clk:
>
>  static int exynos_ohci_remove(struct platform_device *pdev)
>  {
> -       struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
>         struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
>         struct usb_hcd *hcd = exynos_ohci->hcd;
>
>         usb_remove_hcd(hcd);
>
> -       if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       exynos_ohci_phy_disable(exynos_ohci);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -209,8 +243,6 @@ static int exynos_ohci_suspend(struct device *dev)
>         struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
>         struct usb_hcd *hcd = exynos_ohci->hcd;
>         struct ohci_hcd *ohci = hcd_to_ohci(hcd);
> -       struct platform_device *pdev = to_platform_device(dev);
> -       struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
>         unsigned long flags;
>         int rc = 0;
>
> @@ -229,8 +261,7 @@ static int exynos_ohci_suspend(struct device *dev)
>
>         clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>
> -       if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       exynos_ohci_phy_disable(exynos_ohci);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -244,13 +275,10 @@ static int exynos_ohci_resume(struct device *dev)
>  {
>         struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
>         struct usb_hcd *hcd = exynos_ohci->hcd;
> -       struct platform_device *pdev = to_platform_device(dev);
> -       struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
>
>         clk_prepare_enable(exynos_ohci->clk);
>
> -       if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       exynos_ohci_phy_enable(exynos_ohci);
>
>         ohci_resume(hcd, false);
>
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 4/4] USB: ohci-exynos: Add phy driver support
@ 2012-12-19  5:41     ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-19  5:41 UTC (permalink / raw)
  To: linux-usb-u79uwXL29TY76Z2rM5mHXA
  Cc: yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	p.paneri-Sze3O3UU22JBDgjK7y7TUQ,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	jg1.han-Sze3O3UU22JBDgjK7y7TUQ, balbi-l0cyMroinI0,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
	stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	sylvester.nawrocki-Re5JQEeQqe8AvxtiuMwx3w, kishon-l0cyMroinI0,
	Vivek Gautam

CC: Doug Anderson.


On Tue, Dec 18, 2012 at 8:13 PM, Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> Adding the phy-driver to ohci-exynos. Keeping the platform data
> for continuing the smooth operation for boards which still uses it
>
> Signed-off-by: Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Acked-by: Jingoo Han <jg1.han-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/usb/host/ohci-exynos.c |   70 ++++++++++++++++++++++++++++------------
>  1 files changed, 49 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
> index 804fb62..c92ab7b 100644
> --- a/drivers/usb/host/ohci-exynos.c
> +++ b/drivers/usb/host/ohci-exynos.c
> @@ -15,6 +15,7 @@
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/usb-exynos.h>
> +#include <linux/usb/phy.h>
>  #include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
> @@ -22,8 +23,34 @@ struct exynos_ohci_hcd {
>         struct device *dev;
>         struct usb_hcd *hcd;
>         struct clk *clk;
> +       struct usb_phy *phy;
> +       struct exynos4_ohci_platdata *pdata;
>  };
>
> +static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
> +{
> +       struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
> +
> +       if (exynos_ohci->phy) {
> +               samsung_usbphy_set_type(exynos_ohci->phy, USB_PHY_TYPE_HOST);
> +               usb_phy_init(exynos_ohci->phy);
> +       } else if (exynos_ohci->pdata->phy_init) {
> +               exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       }
> +}
> +
> +static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
> +{
> +       struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
> +
> +       if (exynos_ohci->phy) {
> +               samsung_usbphy_set_type(exynos_ohci->phy, USB_PHY_TYPE_HOST);
> +               usb_phy_shutdown(exynos_ohci->phy);
> +       } else if (exynos_ohci->pdata->phy_exit) {
> +               exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       }
> +}
> +
>  static int ohci_exynos_reset(struct usb_hcd *hcd)
>  {
>         return ohci_init(hcd_to_ohci(hcd));
> @@ -79,20 +106,15 @@ static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
>
>  static int exynos_ohci_probe(struct platform_device *pdev)
>  {
> -       struct exynos4_ohci_platdata *pdata;
> +       struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
>         struct exynos_ohci_hcd *exynos_ohci;
>         struct usb_hcd *hcd;
>         struct ohci_hcd *ohci;
>         struct resource *res;
> +       struct usb_phy *phy;
>         int irq;
>         int err;
>
> -       pdata = pdev->dev.platform_data;
> -       if (!pdata) {
> -               dev_err(&pdev->dev, "No platform data defined\n");
> -               return -EINVAL;
> -       }
> -
>         /*
>          * Right now device-tree probed devices don't get dma_mask set.
>          * Since shared usb code relies on it, set it here for now.
> @@ -108,6 +130,19 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>         if (!exynos_ohci)
>                 return -ENOMEM;
>
> +       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
> +       if (IS_ERR_OR_NULL(phy)) {
> +               /* Fallback to pdata */
> +               if (!pdata) {
> +                       dev_err(&pdev->dev, "no platform data or transceiver defined\n");
> +                       return -EPROBE_DEFER;
> +               } else {
> +                       exynos_ohci->pdata = pdata;
> +               }
> +       } else {
> +               exynos_ohci->phy = phy;
> +       }
> +
>         exynos_ohci->dev = &pdev->dev;
>
>         hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
> @@ -153,8 +188,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>                 goto fail_io;
>         }
>
> -       if (pdata->phy_init)
> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       exynos_ohci_phy_enable(exynos_ohci);
>
>         ohci = hcd_to_ohci(hcd);
>         ohci_hcd_init(ohci);
> @@ -162,13 +196,15 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>         err = usb_add_hcd(hcd, irq, IRQF_SHARED);
>         if (err) {
>                 dev_err(&pdev->dev, "Failed to add USB HCD\n");
> -               goto fail_io;
> +               goto fail_add_hcd;
>         }
>
>         platform_set_drvdata(pdev, exynos_ohci);
>
>         return 0;
>
> +fail_add_hcd:
> +       exynos_ohci_phy_disable(exynos_ohci);
>  fail_io:
>         clk_disable_unprepare(exynos_ohci->clk);
>  fail_clk:
> @@ -178,14 +214,12 @@ fail_clk:
>
>  static int exynos_ohci_remove(struct platform_device *pdev)
>  {
> -       struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
>         struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
>         struct usb_hcd *hcd = exynos_ohci->hcd;
>
>         usb_remove_hcd(hcd);
>
> -       if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       exynos_ohci_phy_disable(exynos_ohci);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -209,8 +243,6 @@ static int exynos_ohci_suspend(struct device *dev)
>         struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
>         struct usb_hcd *hcd = exynos_ohci->hcd;
>         struct ohci_hcd *ohci = hcd_to_ohci(hcd);
> -       struct platform_device *pdev = to_platform_device(dev);
> -       struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
>         unsigned long flags;
>         int rc = 0;
>
> @@ -229,8 +261,7 @@ static int exynos_ohci_suspend(struct device *dev)
>
>         clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>
> -       if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       exynos_ohci_phy_disable(exynos_ohci);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -244,13 +275,10 @@ static int exynos_ohci_resume(struct device *dev)
>  {
>         struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
>         struct usb_hcd *hcd = exynos_ohci->hcd;
> -       struct platform_device *pdev = to_platform_device(dev);
> -       struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
>
>         clk_prepare_enable(exynos_ohci->clk);
>
> -       if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       exynos_ohci_phy_enable(exynos_ohci);
>
>         ohci_resume(hcd, false);
>
> --
> 1.7.6.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
@ 2012-12-19 21:48     ` Doug Anderson
  0 siblings, 0 replies; 34+ messages in thread
From: Doug Anderson @ 2012-12-19 21:48 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: linux-usb, yulgon.kim, linux-samsung-soc, Praveen Paneri, gregkh,
	devicetree-discuss, jg1.han, linux-kernel, balbi, kishon,
	Kukjin Kim, stern, rob.herring, sylvester.nawrocki

Vivek,

On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> Updating the names of usb-phy types to more generic names:
> USB_PHY_TYPE_DEIVCE & USB_PHY_TYPE_HOST; and further update
> its dependencies.

Since you're changing the name, I would have expected to see a removal
of the old enum type in this patch.  I don't see it.  After applying
all of your patches I find that S5P_USB_PHY_HOST and
S5P_USB_PHY_DEVICE are still defined and used.

$ git grep S5P_USB_PHY_HOST
arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
arch/arm/plat-samsung/include/plat/usb-phy.h:   S5P_USB_PHY_HOST,

I believe that those usages of the old enum should also be switched
over and the old enum removed.

> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> ---
>  drivers/usb/host/ehci-s5p.c         |    9 +++++----
>  drivers/usb/host/ohci-exynos.c      |    9 +++++----
>  include/linux/usb/samsung_usb_phy.h |   16 ++++++++++++++++
>  3 files changed, 26 insertions(+), 8 deletions(-)
>  create mode 100644 include/linux/usb/samsung_usb_phy.h
>
> diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
> index 319dcfa..46ca5ef 100644
> --- a/drivers/usb/host/ehci-s5p.c
> +++ b/drivers/usb/host/ehci-s5p.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/of_gpio.h>
>  #include <linux/platform_data/usb-ehci-s5p.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
>  #define EHCI_INSNREG00(base)                   (base + 0x90)
> @@ -164,7 +165,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>         }
>
>         if (pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ehci = hcd_to_ehci(hcd);
>         ehci->caps = hcd->regs;
> @@ -198,7 +199,7 @@ static int s5p_ehci_remove(struct platform_device *pdev)
>         usb_remove_hcd(hcd);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -229,7 +230,7 @@ static int s5p_ehci_suspend(struct device *dev)
>         rc = ehci_suspend(hcd, do_wakeup);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -246,7 +247,7 @@ static int s5p_ehci_resume(struct device *dev)
>         clk_prepare_enable(s5p_ehci->clk);
>
>         if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         /* DMA burst Enable */
>         writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
> diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
> index aa3b884..804fb62 100644
> --- a/drivers/usb/host/ohci-exynos.c
> +++ b/drivers/usb/host/ohci-exynos.c
> @@ -15,6 +15,7 @@
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/usb-exynos.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
>  struct exynos_ohci_hcd {
> @@ -153,7 +154,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>         }
>
>         if (pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ohci = hcd_to_ohci(hcd);
>         ohci_hcd_init(ohci);
> @@ -184,7 +185,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
>         usb_remove_hcd(hcd);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -229,7 +230,7 @@ static int exynos_ohci_suspend(struct device *dev)
>         clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -249,7 +250,7 @@ static int exynos_ohci_resume(struct device *dev)
>         clk_prepare_enable(exynos_ohci->clk);
>
>         if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ohci_resume(hcd, false);
>
> diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
> new file mode 100644
> index 0000000..9167826
> --- /dev/null
> +++ b/include/linux/usb/samsung_usb_phy.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + *             http://www.samsung.com/
> + *
> + * Defines phy types for samsung usb phy controllers - HOST or DEIVCE.
> + *
> + * 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, or (at your
> + * option) any later version.
> + */
> +
> +enum samsung_usb_phy_type {
> +       USB_PHY_TYPE_DEVICE,
> +       USB_PHY_TYPE_HOST,
> +};
> --
> 1.7.6.5
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* Re: [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
@ 2012-12-19 21:48     ` Doug Anderson
  0 siblings, 0 replies; 34+ messages in thread
From: Doug Anderson @ 2012-12-19 21:48 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: jg1.han-Sze3O3UU22JBDgjK7y7TUQ,
	yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Praveen Paneri,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, balbi-l0cyMroinI0,
	kishon-l0cyMroinI0, Kukjin Kim,
	stern-nwvwT67g6+6dFdvTe/nMLpVzexx5G7lz,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	sylvester.nawrocki-Re5JQEeQqe8AvxtiuMwx3w

Vivek,

On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> Updating the names of usb-phy types to more generic names:
> USB_PHY_TYPE_DEIVCE & USB_PHY_TYPE_HOST; and further update
> its dependencies.

Since you're changing the name, I would have expected to see a removal
of the old enum type in this patch.  I don't see it.  After applying
all of your patches I find that S5P_USB_PHY_HOST and
S5P_USB_PHY_DEVICE are still defined and used.

$ git grep S5P_USB_PHY_HOST
arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
arch/arm/plat-samsung/include/plat/usb-phy.h:   S5P_USB_PHY_HOST,

I believe that those usages of the old enum should also be switched
over and the old enum removed.

> Signed-off-by: Praveen Paneri <p.paneri-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/usb/host/ehci-s5p.c         |    9 +++++----
>  drivers/usb/host/ohci-exynos.c      |    9 +++++----
>  include/linux/usb/samsung_usb_phy.h |   16 ++++++++++++++++
>  3 files changed, 26 insertions(+), 8 deletions(-)
>  create mode 100644 include/linux/usb/samsung_usb_phy.h
>
> diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
> index 319dcfa..46ca5ef 100644
> --- a/drivers/usb/host/ehci-s5p.c
> +++ b/drivers/usb/host/ehci-s5p.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/of_gpio.h>
>  #include <linux/platform_data/usb-ehci-s5p.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
>  #define EHCI_INSNREG00(base)                   (base + 0x90)
> @@ -164,7 +165,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>         }
>
>         if (pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ehci = hcd_to_ehci(hcd);
>         ehci->caps = hcd->regs;
> @@ -198,7 +199,7 @@ static int s5p_ehci_remove(struct platform_device *pdev)
>         usb_remove_hcd(hcd);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -229,7 +230,7 @@ static int s5p_ehci_suspend(struct device *dev)
>         rc = ehci_suspend(hcd, do_wakeup);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -246,7 +247,7 @@ static int s5p_ehci_resume(struct device *dev)
>         clk_prepare_enable(s5p_ehci->clk);
>
>         if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         /* DMA burst Enable */
>         writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
> diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
> index aa3b884..804fb62 100644
> --- a/drivers/usb/host/ohci-exynos.c
> +++ b/drivers/usb/host/ohci-exynos.c
> @@ -15,6 +15,7 @@
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
>  #include <linux/platform_data/usb-exynos.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
>  struct exynos_ohci_hcd {
> @@ -153,7 +154,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>         }
>
>         if (pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ohci = hcd_to_ohci(hcd);
>         ohci_hcd_init(ohci);
> @@ -184,7 +185,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
>         usb_remove_hcd(hcd);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -229,7 +230,7 @@ static int exynos_ohci_suspend(struct device *dev)
>         clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>
>         if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>
>         clk_disable_unprepare(exynos_ohci->clk);
>
> @@ -249,7 +250,7 @@ static int exynos_ohci_resume(struct device *dev)
>         clk_prepare_enable(exynos_ohci->clk);
>
>         if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>
>         ohci_resume(hcd, false);
>
> diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
> new file mode 100644
> index 0000000..9167826
> --- /dev/null
> +++ b/include/linux/usb/samsung_usb_phy.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
> + *             http://www.samsung.com/
> + *
> + * Defines phy types for samsung usb phy controllers - HOST or DEIVCE.
> + *
> + * 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, or (at your
> + * option) any later version.
> + */
> +
> +enum samsung_usb_phy_type {
> +       USB_PHY_TYPE_DEVICE,
> +       USB_PHY_TYPE_HOST,
> +};
> --
> 1.7.6.5
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
  2012-12-18 14:43 ` [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver Vivek Gautam
  2012-12-19  5:40     ` Vivek Gautam
@ 2012-12-19 23:01   ` Doug Anderson
  2013-01-11 12:40     ` Vivek Gautam
  1 sibling, 1 reply; 34+ messages in thread
From: Doug Anderson @ 2012-12-19 23:01 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: linux-usb, yulgon.kim, linux-samsung-soc, Praveen Paneri, gregkh,
	devicetree-discuss, jg1.han, linux-kernel, balbi, kishon,
	Kukjin Kim, stern, rob.herring, sylvester.nawrocki

Vivek,

I don't really have a good 10000 foot view about how all of the USB
bits fit together, but a few detail-oriented comments below.


On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> This patch adds host phy support to samsung-usbphy.c and
> further adds support for samsung's exynos5250 usb-phy.
>
> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> ---
>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
>  drivers/usb/phy/Kconfig                            |    2 +-
>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
>  include/linux/usb/samsung_usb_phy.h                |   13 +
>  4 files changed, 454 insertions(+), 51 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> index a7b28b2..2ec5400 100644
> --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> @@ -1,23 +1,38 @@
>  * Samsung's usb phy transceiver
>
> -The Samsung's phy transceiver is used for controlling usb otg phy for
> -s3c-hsotg usb device controller.
> +The Samsung's phy transceiver is used for controlling usb phy for
> +s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
> +across Samsung SOCs.
>  TODO: Adding the PHY binding with controller(s) according to the under
>  developement generic PHY driver.
>
>  Required properties:
> +
> +Exynos4210:
>  - compatible : should be "samsung,exynos4210-usbphy"
>  - reg : base physical address of the phy registers and length of memory mapped
>         region.
>
> +Exynos5250:
> +- compatible : should be "samsung,exynos5250-usbphy"
> +- reg : base physical address of the phy registers and length of memory mapped
> +       region.
> +
>  Optional properties:
>  - samsung,usb-phyhandle : should point to usb-phyhandle sub-node which provides
>                         binding data to enable/disable device PHY handled by
> -                       PMU register.
> +                       PMU register; or to configure usb2.0 phy handled by
> +                       SYSREG.
>
>                         Required properties:
>                         - compatible : should be "samsung,usbdev-phyctrl" for
> -                                       DEVICE type phy.
> +                                      DEVICE type phy; or
> +                                      should be "samsung,usbhost-phyctrl" for
> +                                      HOST type phy; or
> +                                      should be "samsung,usb-phycfg" for
> +                                      USB2.0 PHY_CFG.
>                         - samsung,phyhandle-reg: base physical address of
> -                                               PHY_CONTROL register in PMU.
> +                                                PHY_CONTROL register in PMU;
> +                                                or USB2.0 PHY_CFG register
> +                                                in SYSREG.
>  - samsung,enable-mask : should be '1'
> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> index 17ad743..13c0eaf 100644
> --- a/drivers/usb/phy/Kconfig
> +++ b/drivers/usb/phy/Kconfig
> @@ -47,7 +47,7 @@ config USB_RCAR_PHY
>
>  config SAMSUNG_USBPHY
>         bool "Samsung USB PHY controller Driver"
> -       depends on USB_S3C_HSOTG
> +       depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
>         select USB_OTG_UTILS
>         help
>           Enable this to support Samsung USB phy controller for samsung
> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
> index 4ceabe3..621348a 100644
> --- a/drivers/usb/phy/samsung-usbphy.c
> +++ b/drivers/usb/phy/samsung-usbphy.c
> @@ -5,7 +5,8 @@
>   *
>   * Author: Praveen Paneri <p.paneri@samsung.com>
>   *
> - * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
> + * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
> + * OHCI-EXYNOS controllers.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -24,7 +25,7 @@
>  #include <linux/err.h>
>  #include <linux/io.h>
>  #include <linux/of.h>
> -#include <linux/usb/otg.h>
> +#include <linux/usb/samsung_usb_phy.h>
>  #include <linux/platform_data/samsung-usbphy.h>
>
>  /* Register definitions */
> @@ -56,6 +57,103 @@
>  #define RSTCON_HLINK_SWRST                     (0x1 << 1)
>  #define RSTCON_SWRST                           (0x1 << 0)
>
> +/* EXYNOS5 */
> +#define EXYNOS5_PHY_HOST_CTRL0                 (0x00)
> +
> +#define HOST_CTRL0_PHYSWRSTALL                 (0x1 << 31)
> +
> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
> +
> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)

Add the shifts to the #defines and remove HOST_CTRL0_FSEL(_x).  That
makes it match the older phy more closely.

> +
> +#define HOST_CTRL0_TESTBURNIN                  (0x1 << 11)
> +#define HOST_CTRL0_RETENABLE                   (0x1 << 10)
> +#define HOST_CTRL0_COMMONON_N                  (0x1 << 9)
> +#define HOST_CTRL0_SIDDQ                       (0x1 << 6)
> +#define HOST_CTRL0_FORCESLEEP                  (0x1 << 5)
> +#define HOST_CTRL0_FORCESUSPEND                        (0x1 << 4)
> +#define HOST_CTRL0_WORDINTERFACE               (0x1 << 3)
> +#define HOST_CTRL0_UTMISWRST                   (0x1 << 2)
> +#define HOST_CTRL0_LINKSWRST                   (0x1 << 1)
> +#define HOST_CTRL0_PHYSWRST                    (0x1 << 0)
> +
> +#define EXYNOS5_PHY_HOST_TUNE0                 (0x04)
> +
> +#define EXYNOS5_PHY_HSIC_CTRL1                 (0x10)
> +
> +#define EXYNOS5_PHY_HSIC_TUNE1                 (0x14)
> +
> +#define EXYNOS5_PHY_HSIC_CTRL2                 (0x20)
> +
> +#define EXYNOS5_PHY_HSIC_TUNE2                 (0x24)
> +
> +#define HSIC_CTRL_REFCLKSEL_MASK               (0x3)
> +#define HSIC_CTRL_REFCLKSEL                    (0x2 << 23)
> +
> +#define HSIC_CTRL_REFCLKDIV_MASK               (0x7f)
> +#define HSIC_CTRL_REFCLKDIV(_x)                        ((_x) << 16)
> +#define HSIC_CTRL_REFCLKDIV_12                 (0x24 << 16)
> +#define HSIC_CTRL_REFCLKDIV_15                 (0x1c << 16)
> +#define HSIC_CTRL_REFCLKDIV_16                 (0x1a << 16)
> +#define HSIC_CTRL_REFCLKDIV_19_2               (0x15 << 16)
> +#define HSIC_CTRL_REFCLKDIV_20                 (0x14)
> +
> +#define HSIC_CTRL_SIDDQ                                (0x1 << 6)
> +#define HSIC_CTRL_FORCESLEEP                   (0x1 << 5)
> +#define HSIC_CTRL_FORCESUSPEND                 (0x1 << 4)
> +#define HSIC_CTRL_WORDINTERFACE                        (0x1 << 3)
> +#define HSIC_CTRL_UTMISWRST                    (0x1 << 2)
> +#define HSIC_CTRL_PHYSWRST                     (0x1 << 0)
> +
> +#define EXYNOS5_PHY_HOST_EHCICTRL              (0x30)
> +
> +#define HOST_EHCICTRL_ENAINCRXALIGN            (0x1 << 29)
> +#define HOST_EHCICTRL_ENAINCR4                 (0x1 << 28)
> +#define HOST_EHCICTRL_ENAINCR8                 (0x1 << 27)
> +#define HOST_EHCICTRL_ENAINCR16                        (0x1 << 26)
> +
> +#define EXYNOS5_PHY_HOST_OHCICTRL              (0x34)
> +
> +#define HOST_OHCICTRL_SUSPLGCY                 (0x1 << 3)
> +#define HOST_OHCICTRL_APPSTARTCLK              (0x1 << 2)
> +#define HOST_OHCICTRL_CNTSEL                   (0x1 << 1)
> +#define HOST_OHCICTRL_CLKCKTRST                        (0x1 << 0)
> +
> +#define EXYNOS5_PHY_OTG_SYS                    (0x38)
> +
> +#define OTG_SYS_PHYLINK_SWRESET                        (0x1 << 14)
> +#define OTG_SYS_LINKSWRST_UOTG                 (0x1 << 13)
> +#define OTG_SYS_PHY0_SWRST                     (0x1 << 12)
> +
> +#define OTG_SYS_REFCLKSEL_MASK                 (0x3 << 9)
> +#define OTG_SYS_REFCLKSEL_XTAL                 (0x0 << 9)
> +#define OTG_SYS_REFCLKSEL_EXTL                 (0x1 << 9)
> +#define OTG_SYS_REFCLKSEL_CLKCORE              (0x2 << 9)
> +
> +#define OTG_SYS_IDPULLUP_UOTG                  (0x1 << 8)
> +#define OTG_SYS_COMMON_ON                      (0x1 << 7)
> +
> +#define OTG_SYS_FSEL_MASK                      (0x7 << 4)
> +#define OTG_SYS_FSEL(_x)                       ((_x) << 4)
> +
> +#define OTG_SYS_FORCESLEEP                     (0x1 << 3)
> +#define OTG_SYS_OTGDISABLE                     (0x1 << 2)
> +#define OTG_SYS_SIDDQ_UOTG                     (0x1 << 1)
> +#define OTG_SYS_FORCESUSPEND                   (0x1 << 0)
> +
> +#define EXYNOS5_PHY_OTG_TUNE                   (0x40)
> +
>  #ifndef MHZ
>  #define MHZ (1000*1000)
>  #endif
> @@ -63,6 +161,7 @@
>  enum samsung_cpu_type {
>         TYPE_S3C64XX,
>         TYPE_EXYNOS4210,
> +       TYPE_EXYNOS5250,
>  };
>
>  /*
> @@ -73,9 +172,13 @@ enum samsung_cpu_type {
>   * @clk: usb phy clock
>   * @regs: usb phy register memory base
>   * @devctrl_reg: usb device phy-control pmu register memory base
> + * @hostctrl_reg: usb host phy-control pmu register memory base
> + * @phycfg_reg: usb2.0 phy-cfg system register memory base
>   * @en_mask: enable mask
>   * @ref_clk_freq: reference clock frequency selection
>   * @cpu_type: machine identifier
> + * @phy_type: It keeps track of the PHY type.
> + * @host_usage: host_phy usage count.
>   */
>  struct samsung_usbphy {
>         struct usb_phy  phy;
> @@ -84,9 +187,13 @@ struct samsung_usbphy {
>         struct clk      *clk;
>         void __iomem    *regs;
>         void __iomem    *devctrl_reg;
> +       void __iomem    *hostctrl_reg;
> +       void __iomem    *phycfg_reg;
>         u32             en_mask;
>         int             ref_clk_freq;
>         int             cpu_type;
> +       enum samsung_usb_phy_type phy_type;
> +       atomic_t        host_usage;
>  };
>
>  #define phy_to_sphy(x)         container_of((x), struct samsung_usbphy, phy)
> @@ -96,26 +203,49 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
>         struct device_node *usb_phyctrl;
>         u32 reg;
>         int lenp;
> +       int count = 0;
>
>         if (!sphy->dev->of_node) {
>                 sphy->devctrl_reg = NULL;

Remove init to NULL here (and in other error cases).
...I was going to suggest instead to add setting of hostctrl_reg and
phycfg_reg to NULL, but then realized that we should just rely on the
fact that the devm_kzalloc() will zero things.

>                 return -ENODEV;
>         }
>
> -       if (of_get_property(sphy->dev->of_node, "samsung,usb-phyhandle", &lenp)) {
> -               usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
> -                                               "samsung,usb-phyhandle", 0);
> -               if (!usb_phyctrl) {
> -                       dev_warn(sphy->dev, "Can't get usb-phy handle\n");
> -                       sphy->devctrl_reg = NULL;
> -               }
> -
> -               of_property_read_u32(usb_phyctrl, "samsung,phyhandle-reg", &reg);
> +       if (of_get_property(sphy->dev->of_node,
> +                       "samsung,usb-phyhandle", &lenp)) {
> +               do {

Indentation gets excessive here.  Can you break this into its own function?

> +                       usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
> +                                                       "samsung,usb-phyhandle",
> +                                                       count++);
> +                       if (!usb_phyctrl) {
> +                               dev_warn(sphy->dev,
> +                                       "Can't get usb-phy handle\n");
> +                               sphy->devctrl_reg = NULL;

This is a confusing way to handle the error.  Essentially you want to
print an error if you get to the end of the function and devctrl_reg,
hostctrl_reg, and phycfg_reg are all NULL, right?  Just check for
that.

> +                       }
> +
> +                       of_property_read_u32(usb_phyctrl,
> +                                       "samsung,phyhandle-reg", &reg);
> +
> +                       /*
> +                        * Considering here the maximum number of configurable
> +                        * register settings: DEVICE_PHY_CONTROL
> +                        *                    HOST_PHY_CONTROL
> +                        *                    PHY20_CFG
> +                        */
> +                       if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usbdev-phyctrl"))
> +                               sphy->devctrl_reg = ioremap(reg, SZ_4);
> +                       else if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usbhost-phyctrl"))
> +                               sphy->hostctrl_reg = ioremap(reg, SZ_4);
> +                       else if (of_device_is_compatible(usb_phyctrl,
> +                                               "samsung,usb-phycfg"))
> +                               sphy->phycfg_reg = ioremap(reg, SZ_4);
> +
> +                       of_property_read_u32(sphy->dev->of_node,
> +                                       "samsung,enable-mask", &sphy->en_mask);
> +               } while (of_parse_phandle(sphy->dev->of_node,
> +                               "samsung,usb-phyhandle", count));

Can't you use (*lenp) to figure out how many times to loop?  Seems
like that would be simpler.

>
> -               sphy->devctrl_reg = ioremap(reg, SZ_4);
> -
> -               of_property_read_u32(sphy->dev->of_node, "samsung,enable-mask",
> -                                                       &sphy->en_mask);
>                 of_node_put(usb_phyctrl);
>         } else {
>                 dev_warn(sphy->dev, "Can't get usb-phy handle\n");
> @@ -129,13 +259,18 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
>   * Set isolation here for phy.
>   * SOCs control this by controlling corresponding PMU registers
>   */
> -static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
> +static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy,
> +                                                       int on, int type)

Why add type to this function.  It's always sphy->type, isn't it?

>  {
> -       void __iomem *usb_phyctrl_reg;
> +       void __iomem *usb_phyctrl_reg = NULL;
>         u32 en_mask = sphy->en_mask;
>         u32 reg;
>
> -       usb_phyctrl_reg = sphy->devctrl_reg;
> +       if (type == USB_PHY_TYPE_DEVICE) {

nit: no braces for single line "if".  Please run checkpatch.

> +               usb_phyctrl_reg = sphy->devctrl_reg;
> +       } else if (type == USB_PHY_TYPE_HOST) {
> +               usb_phyctrl_reg = sphy->hostctrl_reg;
> +       }
>
>         if (!usb_phyctrl_reg) {
>                 dev_warn(sphy->dev, "Can't set pmu isolation\n");
> @@ -151,6 +286,47 @@ static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
>  }
>
>  /*
> + * Configure the mode of working og usb-phy here: HOST/DEVICE.

s/og/otg?

> + * SOCs control this by controlling corresponding system register
> + */
> +static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy, int type)

Why add type to this function.  It's always sphy->type, isn't it?

> +{
> +       void __iomem *usb_phycfg_reg;
> +       u32 en_mask = sphy->en_mask;
> +       u32 reg;
> +
> +       usb_phycfg_reg = sphy->phycfg_reg;
> +
> +       if (!usb_phycfg_reg) {
> +               dev_warn(sphy->dev, "Can't select specified phy mode\n");
> +               return;
> +       }
> +
> +       reg = readl(usb_phycfg_reg);
> +
> +       if (type == USB_PHY_TYPE_DEVICE)

This is really confusing.  You disable for device and enable for host?  Eh?

> +               writel(reg & ~en_mask, usb_phycfg_reg);
> +       else if (type == USB_PHY_TYPE_HOST)
> +               writel(reg | en_mask, usb_phycfg_reg);
> +}
> +
> +/*
> + * PHYs are different for USB Device and USB Host. Controllers can make
> + * sure that the correct PHY type is selected by calling this function
> + * before any PHY operation.
> + */
> +int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type)
> +{
> +       struct samsung_usbphy *sphy = phy_to_sphy(phy);
> +
> +       if (sphy->phy_type != phy_type)
> +               sphy->phy_type = phy_type;

Kill useless "if"

> +
> +       return 0;
> +}
> +
> +/*
>   * Returns reference clock frequency selection value
>   */
>  static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
> @@ -158,34 +334,178 @@ static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
>         struct clk *ref_clk;
>         int refclk_freq = 0;
>
> -       ref_clk = clk_get(sphy->dev, "xusbxti");
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               ref_clk = clk_get(sphy->dev, "ext_xtal");
> +       else
> +               ref_clk = clk_get(sphy->dev, "xusbxti");

Seems strange that this clock has a special different name on 5250.
Maybe that should be fixed rather than hacking it here?
clk_add_alias()?

>         if (IS_ERR(ref_clk)) {
>                 dev_err(sphy->dev, "Failed to get reference clock\n");
>                 return PTR_ERR(ref_clk);
>         }
>
> -       switch (clk_get_rate(ref_clk)) {
> -       case 12 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_12M;
> -               break;
> -       case 24 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_24M;
> -               break;
> -       case 48 * MHZ:
> -               refclk_freq = PHYCLK_CLKSEL_48M;
> -               break;
> -       default:
> -               if (sphy->cpu_type == TYPE_S3C64XX)
> -                       refclk_freq = PHYCLK_CLKSEL_48M;
> -               else
> +       if (sphy->cpu_type == TYPE_EXYNOS5250) {
> +               /* set clock frequency for PLL */
> +               switch (clk_get_rate(ref_clk)) {
> +               case 96 * 100000:

nit: change to 9600 * KHZ to match; below too.

> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;

Why |= with 0?

> +                       break;
> +               case 10 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_10M;
> +                       break;
> +               case 12 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_12M;
> +                       break;
> +               case 192 * 100000:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_19200K;
> +                       break;
> +               case 20 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_20M;
> +                       break;
> +               case 50 * MHZ:
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_50M;
> +                       break;
> +               case 24 * MHZ:
> +               default:
> +                       /* default reference clock */
> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_24M;
> +                       break;
> +               }
> +       } else {
> +               switch (clk_get_rate(ref_clk)) {
> +               case 12 * MHZ:
> +                       refclk_freq = PHYCLK_CLKSEL_12M;
> +                       break;
> +               case 24 * MHZ:
>                         refclk_freq = PHYCLK_CLKSEL_24M;
> -               break;
> +                       break;
> +               case 48 * MHZ:
> +                       refclk_freq = PHYCLK_CLKSEL_48M;
> +                       break;
> +               default:
> +                       if (sphy->cpu_type == TYPE_S3C64XX)
> +                               refclk_freq = PHYCLK_CLKSEL_48M;
> +                       else
> +                               refclk_freq = PHYCLK_CLKSEL_24M;
> +                       break;
> +               }
>         }
>         clk_put(ref_clk);
>
>         return refclk_freq;
>  }
>
> +static int exynos5_phyhost_is_on(void *regs)

return bool?

> +{
> +       u32 reg;
> +
> +       reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       return !(reg & HOST_CTRL0_SIDDQ);
> +}
> +
> +static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phyclk = sphy->ref_clk_freq;
> +       u32 phyhost;
> +       u32 phyotg;
> +       u32 phyhsic;
> +       u32 ehcictrl;
> +       u32 ohcictrl;
> +
> +       atomic_inc(&sphy->host_usage);

Can you explain what situations you expect host_usage to be > 1?  Why
is that special for exynos5?

If you really expect multiple users of this, it seems like you need
better locking.  Without better locking one process could be in the
middle of disabling at the same time another process is enabling,
couldn't it?

> +
> +       if (exynos5_phyhost_is_on(regs)) {
> +               dev_info(sphy->dev, "Already power on PHY\n");
> +               return;
> +       }
> +
> +       /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */
> +       samsung_usbphy_cfg_sel(sphy, USB_PHY_TYPE_HOST);
> +
> +       /* Host configuration */
> +       phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       /* phy reference clock configuration */
> +       phyhost &= ~HOST_CTRL0_FSEL_MASK;
> +       phyhost |= HOST_CTRL0_FSEL(phyclk);
> +
> +       /* host phy reset */
> +       phyhost &= ~(HOST_CTRL0_PHYSWRST |
> +                       HOST_CTRL0_PHYSWRSTALL |
> +                       HOST_CTRL0_SIDDQ |
> +                       /* Enable normal mode of operation */
> +                       HOST_CTRL0_FORCESUSPEND |
> +                       HOST_CTRL0_FORCESLEEP);
> +
> +       /* Link reset */
> +       phyhost |= (HOST_CTRL0_LINKSWRST |
> +                       HOST_CTRL0_UTMISWRST |
> +                       /* COMMON Block configuration during suspend */
> +                       HOST_CTRL0_COMMONON_N);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +       udelay(10);
> +       phyhost &= ~(HOST_CTRL0_LINKSWRST |
> +                       HOST_CTRL0_UTMISWRST);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       /* OTG configuration */
> +       phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
> +
> +       /* phy reference clock configuration */
> +       phyotg &= ~OTG_SYS_FSEL_MASK;
> +       phyotg |= OTG_SYS_FSEL(phyclk);
> +
> +       /* Enable normal mode of operation */
> +       phyotg &= ~(OTG_SYS_FORCESUSPEND |
> +                       OTG_SYS_SIDDQ_UOTG |
> +                       OTG_SYS_FORCESLEEP |
> +                       OTG_SYS_REFCLKSEL_MASK |
> +                       /* COMMON Block configuration during suspend */
> +                       OTG_SYS_COMMON_ON);
> +
> +       /* OTG phy & link reset */
> +       phyotg |= (OTG_SYS_PHY0_SWRST |
> +                       OTG_SYS_LINKSWRST_UOTG |
> +                       OTG_SYS_PHYLINK_SWRESET |
> +                       OTG_SYS_OTGDISABLE |
> +                       /* Set phy refclk */
> +                       OTG_SYS_REFCLKSEL_CLKCORE);
> +
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +       udelay(10);
> +       phyotg &= ~(OTG_SYS_PHY0_SWRST |
> +                       OTG_SYS_LINKSWRST_UOTG |
> +                       OTG_SYS_PHYLINK_SWRESET);
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +
> +       /* HSIC phy configuration */
> +       phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
> +                       HSIC_CTRL_REFCLKSEL |
> +                       HSIC_CTRL_PHYSWRST);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +       udelay(10);
> +       phyhsic &= ~HSIC_CTRL_PHYSWRST;
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +
> +       udelay(80);
> +
> +       /* enable EHCI DMA burst */
> +       ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL);
> +       ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN |
> +                               HOST_EHCICTRL_ENAINCR4 |
> +                               HOST_EHCICTRL_ENAINCR8 |
> +                               HOST_EHCICTRL_ENAINCR16);
> +       writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL);
> +
> +       /* set ohci_suspend_on_n */
> +       ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL);
> +       ohcictrl |= HOST_OHCICTRL_SUSPLGCY;
> +       writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL);
> +}
> +
>  static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>  {
>         void __iomem *regs = sphy->regs;
> @@ -221,6 +541,41 @@ static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>         writel(rstcon, regs + SAMSUNG_RSTCON);
>  }
>
> +static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy)
> +{
> +       void __iomem *regs = sphy->regs;
> +       u32 phyhost;
> +       u32 phyotg;
> +       u32 phyhsic;
> +
> +       if (atomic_dec_return(&sphy->host_usage) > 0) {
> +               dev_info(sphy->dev, "still being used\n");
> +               return;
> +       }
> +
> +       phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
> +                       HSIC_CTRL_REFCLKSEL |
> +                       HSIC_CTRL_SIDDQ |
> +                       HSIC_CTRL_FORCESLEEP |
> +                       HSIC_CTRL_FORCESUSPEND);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
> +
> +       phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
> +       phyhost |= (HOST_CTRL0_SIDDQ |
> +                       HOST_CTRL0_FORCESUSPEND |
> +                       HOST_CTRL0_FORCESLEEP |
> +                       HOST_CTRL0_PHYSWRST |
> +                       HOST_CTRL0_PHYSWRSTALL);
> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
> +
> +       phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
> +       phyotg |= (OTG_SYS_FORCESUSPEND |
> +                       OTG_SYS_SIDDQ_UOTG |
> +                       OTG_SYS_FORCESLEEP);
> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
> +}
> +
>  static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
>  {
>         void __iomem *regs = sphy->regs;
> @@ -263,10 +618,13 @@ static int samsung_usbphy_init(struct usb_phy *phy)
>         if (sphy->plat && sphy->plat->pmu_isolation)
>                 sphy->plat->pmu_isolation(false);
>         else
> -               samsung_usbphy_set_isolation(sphy, false);
> +               samsung_usbphy_set_isolation(sphy, false, sphy->phy_type);
>
>         /* Initialize usb phy registers */
> -       samsung_usbphy_enable(sphy);
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               samsung_exynos5_usbphy_enable(sphy);
> +       else
> +               samsung_usbphy_enable(sphy);
>
>         /* Disable the phy clock */
>         clk_disable_unprepare(sphy->clk);
> @@ -288,13 +646,16 @@ static void samsung_usbphy_shutdown(struct usb_phy *phy)
>         }
>
>         /* De-initialize usb phy registers */
> -       samsung_usbphy_disable(sphy);
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               samsung_exynos5_usbphy_disable(sphy);
> +       else
> +               samsung_usbphy_disable(sphy);
>
>         /* Enable phy isolation */
>         if (sphy->plat && sphy->plat->pmu_isolation)
>                 sphy->plat->pmu_isolation(true);
>         else
> -               samsung_usbphy_set_isolation(sphy, true);
> +               samsung_usbphy_set_isolation(sphy, true, sphy->phy_type);
>
>         clk_disable_unprepare(sphy->clk);
>  }
> @@ -339,12 +700,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>         if (!sphy)
>                 return -ENOMEM;
>
> -       clk = devm_clk_get(dev, "otg");
> -       if (IS_ERR(clk)) {
> -               dev_err(dev, "Failed to get otg clock\n");
> -               return PTR_ERR(clk);
> -       }
> -
>         sphy->dev = &pdev->dev;
>
>         ret = samsung_usbphy_parse_dt_param(sphy);
> @@ -361,7 +716,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>
>         sphy->plat              = pdata;
>         sphy->regs              = phy_base;
> -       sphy->clk               = clk;
>         sphy->phy.dev           = sphy->dev;
>         sphy->phy.label         = "samsung-usbphy";
>         sphy->phy.init          = samsung_usbphy_init;
> @@ -371,6 +725,17 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>
>         platform_set_drvdata(pdev, sphy);
>
> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
> +               clk = devm_clk_get(dev, "usbhost");

Why is 5250 special in that it is always host?  Something doesn't seem
right here.

...also, are you sure you want to move this down to after
platform_set_drvdata()?  I don't think it will hurt anything, but
seems better to leave it where it was and just make call
samsung_usbphy_get_driver_data(pdev) earlier in the function.

> +       else
> +               clk = devm_clk_get(dev, "otg");
> +       if (IS_ERR(clk)) {
> +               dev_err(dev, "Failed to get otg clock\n");
> +               return PTR_ERR(clk);
> +       }
> +
> +       sphy->clk = clk;
> +
>         return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
>  }
>
> @@ -382,6 +747,10 @@ static int __exit samsung_usbphy_remove(struct platform_device *pdev)
>
>         if (sphy->devctrl_reg)
>                 iounmap(sphy->devctrl_reg);
> +       if (sphy->hostctrl_reg)
> +               iounmap(sphy->hostctrl_reg);
> +       if (sphy->phycfg_reg)
> +               iounmap(sphy->phycfg_reg);
>
>         return 0;
>  }
> @@ -394,6 +763,9 @@ static const struct of_device_id samsung_usbphy_dt_match[] = {
>         }, {
>                 .compatible = "samsung,exynos4210-usbphy",
>                 .data = (void *)TYPE_EXYNOS4210,
> +       }, {
> +               .compatible = "samsung,exynos5250-usbphy",
> +               .data = (void *)TYPE_EXYNOS5250,
>         },
>         {},
>  };
> @@ -407,6 +779,9 @@ static struct platform_device_id samsung_usbphy_driver_ids[] = {
>         }, {
>                 .name           = "exynos4210-usbphy",
>                 .driver_data    = TYPE_EXYNOS4210,
> +       }, {
> +               .name           = "exynos5250-usbphy",
> +               .driver_data    = TYPE_EXYNOS5250,
>         },
>         {},
>  };
> diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
> index 9167826..aecefaf 100644
> --- a/include/linux/usb/samsung_usb_phy.h
> +++ b/include/linux/usb/samsung_usb_phy.h
> @@ -10,7 +10,20 @@
>   * option) any later version.
>   */
>
> +#include <linux/usb/phy.h>
> +
>  enum samsung_usb_phy_type {
>         USB_PHY_TYPE_DEVICE,
>         USB_PHY_TYPE_HOST,
>  };
> +
> +#ifdef CONFIG_SAMSUNG_USBPHY
> +extern int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type);
> +#else
> +static inline int samsung_usbphy_set_type(struct usb_phy *phy,
> +                               enum samsung_usb_phy_type phy_type)
> +{
> +       return 0;
> +}
> +#endif /* CONFIG_SAMSUNG_USBPHY */
> --
> 1.7.6.5
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* Re: [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support
  2012-12-18 14:43 ` [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support Vivek Gautam
  2012-12-19  5:41   ` Vivek Gautam
@ 2012-12-19 23:30   ` Doug Anderson
  2012-12-20  6:37     ` Vivek Gautam
  1 sibling, 1 reply; 34+ messages in thread
From: Doug Anderson @ 2012-12-19 23:30 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: linux-usb, yulgon.kim, linux-samsung-soc, Praveen Paneri, gregkh,
	devicetree-discuss, jg1.han, linux-kernel, balbi, kishon,
	Kukjin Kim, Alan Stern, Rob Herring, Sylwester Nawrocki

Vivek,

Again, not a high-level review, but...


On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> Adding the phy driver to ehci-s5p. Keeping the platform data
> for continuing the smooth operation for boards which still uses it
>
> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> Acked-by: Jingoo Han <jg1.han@samsung.com>
> ---
>  drivers/usb/host/ehci-s5p.c |   70 ++++++++++++++++++++++++++++++-------------
>  1 files changed, 49 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
> index 46ca5ef..50c93af 100644
> --- a/drivers/usb/host/ehci-s5p.c
> +++ b/drivers/usb/host/ehci-s5p.c
> @@ -17,6 +17,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/of_gpio.h>
>  #include <linux/platform_data/usb-ehci-s5p.h>
> +#include <linux/usb/phy.h>
>  #include <linux/usb/samsung_usb_phy.h>
>  #include <plat/usb-phy.h>
>
> @@ -33,6 +34,8 @@ struct s5p_ehci_hcd {
>         struct device *dev;
>         struct usb_hcd *hcd;
>         struct clk *clk;
> +       struct usb_phy *phy;
> +       struct s5p_ehci_platdata *pdata;
>  };
>
>  static const struct hc_driver s5p_ehci_hc_driver = {
> @@ -66,6 +69,30 @@ static const struct hc_driver s5p_ehci_hc_driver = {
>         .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
>  };
>
> +static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci)
> +{
> +       struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
> +
> +       if (s5p_ehci->phy) {
> +               samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);

This confuses me.  Why are you setting the type to host here?

> +               usb_phy_init(s5p_ehci->phy);
> +       } else if (s5p_ehci->pdata->phy_init) {
> +               s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       }
> +}
> +
> +static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci)
> +{
> +       struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
> +
> +       if (s5p_ehci->phy) {
> +               samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);

...and why set it to host here?

> +               usb_phy_shutdown(s5p_ehci->phy);
> +       } else if (s5p_ehci->pdata->phy_exit) {
> +               s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       }
> +}
> +
>  static void s5p_setup_vbus_gpio(struct platform_device *pdev)
>  {
>         int err;
> @@ -88,20 +115,15 @@ static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
>
>  static int s5p_ehci_probe(struct platform_device *pdev)
>  {
> -       struct s5p_ehci_platdata *pdata;
> +       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>         struct s5p_ehci_hcd *s5p_ehci;
>         struct usb_hcd *hcd;
>         struct ehci_hcd *ehci;
>         struct resource *res;
> +       struct usb_phy *phy;
>         int irq;
>         int err;
>
> -       pdata = pdev->dev.platform_data;
> -       if (!pdata) {
> -               dev_err(&pdev->dev, "No platform data defined\n");
> -               return -EINVAL;
> -       }
> -
>         /*
>          * Right now device-tree probed devices don't get dma_mask set.
>          * Since shared usb code relies on it, set it here for now.
> @@ -119,6 +141,19 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>         if (!s5p_ehci)
>                 return -ENOMEM;
>
> +       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
> +       if (IS_ERR_OR_NULL(phy)) {
> +               /* Fallback to pdata */
> +               if (!pdata) {
> +                       dev_err(&pdev->dev, "no platform data or transceiver defined\n");
> +                       return -EPROBE_DEFER;

Shouldn't you return -EINVAL like the old code did?

> +               } else {
> +                       s5p_ehci->pdata = pdata;
> +               }
> +       } else {
> +               s5p_ehci->phy = phy;
> +       }
> +
>         s5p_ehci->dev = &pdev->dev;
>
>         hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev,
> @@ -164,8 +199,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>                 goto fail_io;
>         }
>
> -       if (pdata->phy_init)
> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       s5p_ehci_phy_enable(s5p_ehci);
>
>         ehci = hcd_to_ehci(hcd);
>         ehci->caps = hcd->regs;
> @@ -176,13 +210,15 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>         err = usb_add_hcd(hcd, irq, IRQF_SHARED);
>         if (err) {
>                 dev_err(&pdev->dev, "Failed to add USB HCD\n");
> -               goto fail_io;
> +               goto fail_add_hcd;
>         }
>
>         platform_set_drvdata(pdev, s5p_ehci);
>
>         return 0;
>
> +fail_add_hcd:
> +       s5p_ehci_phy_disable(s5p_ehci);
>  fail_io:
>         clk_disable_unprepare(s5p_ehci->clk);
>  fail_clk:
> @@ -192,14 +228,12 @@ fail_clk:
>
>  static int s5p_ehci_remove(struct platform_device *pdev)
>  {
> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>         struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
>         struct usb_hcd *hcd = s5p_ehci->hcd;
>
>         usb_remove_hcd(hcd);
>
> -       if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       s5p_ehci_phy_disable(s5p_ehci);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -223,14 +257,11 @@ static int s5p_ehci_suspend(struct device *dev)
>         struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
>         struct usb_hcd *hcd = s5p_ehci->hcd;
>         bool do_wakeup = device_may_wakeup(dev);
> -       struct platform_device *pdev = to_platform_device(dev);
> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>         int rc;
>
>         rc = ehci_suspend(hcd, do_wakeup);
>
> -       if (pdata && pdata->phy_exit)
> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
> +       s5p_ehci_phy_disable(s5p_ehci);
>
>         clk_disable_unprepare(s5p_ehci->clk);
>
> @@ -241,13 +272,10 @@ static int s5p_ehci_resume(struct device *dev)
>  {
>         struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
>         struct usb_hcd *hcd = s5p_ehci->hcd;
> -       struct platform_device *pdev = to_platform_device(dev);
> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>
>         clk_prepare_enable(s5p_ehci->clk);
>
> -       if (pdata && pdata->phy_init)
> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
> +       s5p_ehci_phy_enable(s5p_ehci);
>
>         /* DMA burst Enable */
>         writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
> --
> 1.7.6.5
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss

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

* Re: [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
  2012-12-19 21:48     ` Doug Anderson
  (?)
@ 2012-12-20  5:51     ` Vivek Gautam
  2012-12-20 16:53       ` Doug Anderson
  -1 siblings, 1 reply; 34+ messages in thread
From: Vivek Gautam @ 2012-12-20  5:51 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Vivek Gautam, jg1.han, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, linux-usb,
	linux-kernel, balbi, kishon, Kukjin Kim, stern, rob.herring,
	sylvester.nawrocki

Hi Doug,


On Thu, Dec 20, 2012 at 3:18 AM, Doug Anderson <dianders@chromium.org> wrote:
> Vivek,
>
> On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
>> Updating the names of usb-phy types to more generic names:
>> USB_PHY_TYPE_DEIVCE & USB_PHY_TYPE_HOST; and further update
>> its dependencies.
>
> Since you're changing the name, I would have expected to see a removal
> of the old enum type in this patch.  I don't see it.  After applying
> all of your patches I find that S5P_USB_PHY_HOST and
> S5P_USB_PHY_DEVICE are still defined and used.
>

True that we should have removed the earlier defined enums, infact i
did the same
in patchset v4 for this series. But since in this patchset i separated
out drivers and
architecture part, i thought it would be easier to remove them in one
shot in a latter commit
which will actually touch upon all architecture related code
(mach-exynos/setup-usb-phy.c,
mach-s5pv210/setup-usb-phy.c, and include/plat/usb-phy.h) once this
approach is accepted.

> $ git grep S5P_USB_PHY_HOST
> arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
> arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
> arch/arm/plat-samsung/include/plat/usb-phy.h:   S5P_USB_PHY_HOST,
>
> I believe that those usages of the old enum should also be switched
> over and the old enum removed.
>
Sure, those enums need to be removed.
If you say i will submit a patch for the same.

>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>> ---
>>  drivers/usb/host/ehci-s5p.c         |    9 +++++----
>>  drivers/usb/host/ohci-exynos.c      |    9 +++++----
>>  include/linux/usb/samsung_usb_phy.h |   16 ++++++++++++++++
>>  3 files changed, 26 insertions(+), 8 deletions(-)
>>  create mode 100644 include/linux/usb/samsung_usb_phy.h
>>
>> diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
>> index 319dcfa..46ca5ef 100644
>> --- a/drivers/usb/host/ehci-s5p.c
>> +++ b/drivers/usb/host/ehci-s5p.c
>> @@ -17,6 +17,7 @@
>>  #include <linux/platform_device.h>
>>  #include <linux/of_gpio.h>
>>  #include <linux/platform_data/usb-ehci-s5p.h>
>> +#include <linux/usb/samsung_usb_phy.h>
>>  #include <plat/usb-phy.h>
>>
>>  #define EHCI_INSNREG00(base)                   (base + 0x90)
>> @@ -164,7 +165,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>>         }
>>
>>         if (pdata->phy_init)
>> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
>> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>>
>>         ehci = hcd_to_ehci(hcd);
>>         ehci->caps = hcd->regs;
>> @@ -198,7 +199,7 @@ static int s5p_ehci_remove(struct platform_device *pdev)
>>         usb_remove_hcd(hcd);
>>
>>         if (pdata && pdata->phy_exit)
>> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
>> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>>
>>         clk_disable_unprepare(s5p_ehci->clk);
>>
>> @@ -229,7 +230,7 @@ static int s5p_ehci_suspend(struct device *dev)
>>         rc = ehci_suspend(hcd, do_wakeup);
>>
>>         if (pdata && pdata->phy_exit)
>> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
>> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>>
>>         clk_disable_unprepare(s5p_ehci->clk);
>>
>> @@ -246,7 +247,7 @@ static int s5p_ehci_resume(struct device *dev)
>>         clk_prepare_enable(s5p_ehci->clk);
>>
>>         if (pdata && pdata->phy_init)
>> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
>> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>>
>>         /* DMA burst Enable */
>>         writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
>> diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
>> index aa3b884..804fb62 100644
>> --- a/drivers/usb/host/ohci-exynos.c
>> +++ b/drivers/usb/host/ohci-exynos.c
>> @@ -15,6 +15,7 @@
>>  #include <linux/of.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/platform_data/usb-exynos.h>
>> +#include <linux/usb/samsung_usb_phy.h>
>>  #include <plat/usb-phy.h>
>>
>>  struct exynos_ohci_hcd {
>> @@ -153,7 +154,7 @@ static int exynos_ohci_probe(struct platform_device *pdev)
>>         }
>>
>>         if (pdata->phy_init)
>> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
>> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>>
>>         ohci = hcd_to_ohci(hcd);
>>         ohci_hcd_init(ohci);
>> @@ -184,7 +185,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)
>>         usb_remove_hcd(hcd);
>>
>>         if (pdata && pdata->phy_exit)
>> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
>> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>>
>>         clk_disable_unprepare(exynos_ohci->clk);
>>
>> @@ -229,7 +230,7 @@ static int exynos_ohci_suspend(struct device *dev)
>>         clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
>>
>>         if (pdata && pdata->phy_exit)
>> -               pdata->phy_exit(pdev, S5P_USB_PHY_HOST);
>> +               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>>
>>         clk_disable_unprepare(exynos_ohci->clk);
>>
>> @@ -249,7 +250,7 @@ static int exynos_ohci_resume(struct device *dev)
>>         clk_prepare_enable(exynos_ohci->clk);
>>
>>         if (pdata && pdata->phy_init)
>> -               pdata->phy_init(pdev, S5P_USB_PHY_HOST);
>> +               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>>
>>         ohci_resume(hcd, false);
>>
>> diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
>> new file mode 100644
>> index 0000000..9167826
>> --- /dev/null
>> +++ b/include/linux/usb/samsung_usb_phy.h
>> @@ -0,0 +1,16 @@
>> +/*
>> + * Copyright (C) 2012 Samsung Electronics Co.Ltd
>> + *             http://www.samsung.com/
>> + *
>> + * Defines phy types for samsung usb phy controllers - HOST or DEIVCE.
>> + *
>> + * 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, or (at your
>> + * option) any later version.
>> + */
>> +
>> +enum samsung_usb_phy_type {
>> +       USB_PHY_TYPE_DEVICE,
>> +       USB_PHY_TYPE_HOST,
>> +};
>> --
>> 1.7.6.5
>>
>> _______________________________________________
>> devicetree-discuss mailing list
>> devicetree-discuss@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/devicetree-discuss
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support
  2012-12-19 23:30   ` Doug Anderson
@ 2012-12-20  6:37     ` Vivek Gautam
  2012-12-20 17:51         ` Doug Anderson
  0 siblings, 1 reply; 34+ messages in thread
From: Vivek Gautam @ 2012-12-20  6:37 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Vivek Gautam, linux-usb, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, jg1.han,
	linux-kernel, balbi, kishon, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

Hi Doug,


On Thu, Dec 20, 2012 at 5:00 AM, Doug Anderson <dianders@chromium.org> wrote:
> Vivek,
>
> Again, not a high-level review, but...
>
Thanks for reviewing. :-)

>
> On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
>> Adding the phy driver to ehci-s5p. Keeping the platform data
>> for continuing the smooth operation for boards which still uses it
>>
>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>> Acked-by: Jingoo Han <jg1.han@samsung.com>
>> ---
>>  drivers/usb/host/ehci-s5p.c |   70 ++++++++++++++++++++++++++++++-------------
>>  1 files changed, 49 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
>> index 46ca5ef..50c93af 100644
>> --- a/drivers/usb/host/ehci-s5p.c
>> +++ b/drivers/usb/host/ehci-s5p.c
>> @@ -17,6 +17,7 @@
>>  #include <linux/platform_device.h>
>>  #include <linux/of_gpio.h>
>>  #include <linux/platform_data/usb-ehci-s5p.h>
>> +#include <linux/usb/phy.h>
>>  #include <linux/usb/samsung_usb_phy.h>
>>  #include <plat/usb-phy.h>
>>
>> @@ -33,6 +34,8 @@ struct s5p_ehci_hcd {
>>         struct device *dev;
>>         struct usb_hcd *hcd;
>>         struct clk *clk;
>> +       struct usb_phy *phy;
>> +       struct s5p_ehci_platdata *pdata;
>>  };
>>
>>  static const struct hc_driver s5p_ehci_hc_driver = {
>> @@ -66,6 +69,30 @@ static const struct hc_driver s5p_ehci_hc_driver = {
>>         .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
>>  };
>>
>> +static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci)
>> +{
>> +       struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
>> +
>> +       if (s5p_ehci->phy) {
>> +               samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);
>
> This confuses me.  Why are you setting the type to host here?
>
Being in host controller, before calling usb_phy_init() we set type to
Host since, with certain SOCs
like 4210, same register has different bit settings for HOST type and
device type. So setting this
to Host type here make the flow of usb_phy_init to go in the direction of Host.

>> +               usb_phy_init(s5p_ehci->phy);
>> +       } else if (s5p_ehci->pdata->phy_init) {
>> +               s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>> +       }
>> +}
>> +
>> +static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci)
>> +{
>> +       struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
>> +
>> +       if (s5p_ehci->phy) {
>> +               samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);
>
> ...and why set it to host here?
>
Same here...

>> +               usb_phy_shutdown(s5p_ehci->phy);
>> +       } else if (s5p_ehci->pdata->phy_exit) {
>> +               s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>> +       }
>> +}
>> +
>>  static void s5p_setup_vbus_gpio(struct platform_device *pdev)
>>  {
>>         int err;
>> @@ -88,20 +115,15 @@ static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
>>
>>  static int s5p_ehci_probe(struct platform_device *pdev)
>>  {
>> -       struct s5p_ehci_platdata *pdata;
>> +       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>>         struct s5p_ehci_hcd *s5p_ehci;
>>         struct usb_hcd *hcd;
>>         struct ehci_hcd *ehci;
>>         struct resource *res;
>> +       struct usb_phy *phy;
>>         int irq;
>>         int err;
>>
>> -       pdata = pdev->dev.platform_data;
>> -       if (!pdata) {
>> -               dev_err(&pdev->dev, "No platform data defined\n");
>> -               return -EINVAL;
>> -       }
>> -
>>         /*
>>          * Right now device-tree probed devices don't get dma_mask set.
>>          * Since shared usb code relies on it, set it here for now.
>> @@ -119,6 +141,19 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>>         if (!s5p_ehci)
>>                 return -ENOMEM;
>>
>> +       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
>> +       if (IS_ERR_OR_NULL(phy)) {
>> +               /* Fallback to pdata */
>> +               if (!pdata) {
>> +                       dev_err(&pdev->dev, "no platform data or transceiver defined\n");
>> +                       return -EPROBE_DEFER;
>
> Shouldn't you return -EINVAL like the old code did?

We are deferring the probe since the usb-phy transceiver may get
probed after ehci/ohci controllers.
And if we return -EINVAL like the previous code, we would end up not
setting the phy.

>
>> +               } else {
>> +                       s5p_ehci->pdata = pdata;
>> +               }
>> +       } else {
>> +               s5p_ehci->phy = phy;
>> +       }
>> +
>>         s5p_ehci->dev = &pdev->dev;
>>
>>         hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev,
>> @@ -164,8 +199,7 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>>                 goto fail_io;
>>         }
>>
>> -       if (pdata->phy_init)
>> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>> +       s5p_ehci_phy_enable(s5p_ehci);
>>
>>         ehci = hcd_to_ehci(hcd);
>>         ehci->caps = hcd->regs;
>> @@ -176,13 +210,15 @@ static int s5p_ehci_probe(struct platform_device *pdev)
>>         err = usb_add_hcd(hcd, irq, IRQF_SHARED);
>>         if (err) {
>>                 dev_err(&pdev->dev, "Failed to add USB HCD\n");
>> -               goto fail_io;
>> +               goto fail_add_hcd;
>>         }
>>
>>         platform_set_drvdata(pdev, s5p_ehci);
>>
>>         return 0;
>>
>> +fail_add_hcd:
>> +       s5p_ehci_phy_disable(s5p_ehci);
>>  fail_io:
>>         clk_disable_unprepare(s5p_ehci->clk);
>>  fail_clk:
>> @@ -192,14 +228,12 @@ fail_clk:
>>
>>  static int s5p_ehci_remove(struct platform_device *pdev)
>>  {
>> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>>         struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
>>         struct usb_hcd *hcd = s5p_ehci->hcd;
>>
>>         usb_remove_hcd(hcd);
>>
>> -       if (pdata && pdata->phy_exit)
>> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>> +       s5p_ehci_phy_disable(s5p_ehci);
>>
>>         clk_disable_unprepare(s5p_ehci->clk);
>>
>> @@ -223,14 +257,11 @@ static int s5p_ehci_suspend(struct device *dev)
>>         struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
>>         struct usb_hcd *hcd = s5p_ehci->hcd;
>>         bool do_wakeup = device_may_wakeup(dev);
>> -       struct platform_device *pdev = to_platform_device(dev);
>> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>>         int rc;
>>
>>         rc = ehci_suspend(hcd, do_wakeup);
>>
>> -       if (pdata && pdata->phy_exit)
>> -               pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
>> +       s5p_ehci_phy_disable(s5p_ehci);
>>
>>         clk_disable_unprepare(s5p_ehci->clk);
>>
>> @@ -241,13 +272,10 @@ static int s5p_ehci_resume(struct device *dev)
>>  {
>>         struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
>>         struct usb_hcd *hcd = s5p_ehci->hcd;
>> -       struct platform_device *pdev = to_platform_device(dev);
>> -       struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
>>
>>         clk_prepare_enable(s5p_ehci->clk);
>>
>> -       if (pdata && pdata->phy_init)
>> -               pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
>> +       s5p_ehci_phy_enable(s5p_ehci);
>>
>>         /* DMA burst Enable */
>>         writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
>> --
>> 1.7.6.5
>>
>> _______________________________________________
>> devicetree-discuss mailing list
>> devicetree-discuss@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/devicetree-discuss
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
  2012-12-20  5:51     ` Vivek Gautam
@ 2012-12-20 16:53       ` Doug Anderson
  2012-12-20 19:03           ` Vivek Gautam
  0 siblings, 1 reply; 34+ messages in thread
From: Doug Anderson @ 2012-12-20 16:53 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Vivek Gautam, jg1.han, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, linux-usb,
	linux-kernel, balbi, kishon, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

Vivek,

On Wed, Dec 19, 2012 at 9:51 PM, Vivek Gautam <gautamvivek1987@gmail.com> wrote:
> Hi Doug,
>
>
> On Thu, Dec 20, 2012 at 3:18 AM, Doug Anderson <dianders@chromium.org> wrote:
>> Vivek,
>>
>> Since you're changing the name, I would have expected to see a removal
>> of the old enum type in this patch.  I don't see it.  After applying
>> all of your patches I find that S5P_USB_PHY_HOST and
>> S5P_USB_PHY_DEVICE are still defined and used.
>>
>
> True that we should have removed the earlier defined enums, infact i
> did the same
> in patchset v4 for this series. But since in this patchset i separated
> out drivers and
> architecture part, i thought it would be easier to remove them in one
> shot in a latter commit
> which will actually touch upon all architecture related code
> (mach-exynos/setup-usb-phy.c,
> mach-s5pv210/setup-usb-phy.c, and include/plat/usb-phy.h) once this
> approach is accepted.
>
>> $ git grep S5P_USB_PHY_HOST
>> arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
>> arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
>> arch/arm/plat-samsung/include/plat/usb-phy.h:   S5P_USB_PHY_HOST,
>>
>> I believe that those usages of the old enum should also be switched
>> over and the old enum removed.
>>
> Sure, those enums need to be removed.
> If you say i will submit a patch for the same.

It would be nice to add it to the patch series in the next version.  Thanks!

-Doug

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

* Re: [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support
@ 2012-12-20 17:51         ` Doug Anderson
  0 siblings, 0 replies; 34+ messages in thread
From: Doug Anderson @ 2012-12-20 17:51 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Vivek Gautam, linux-usb, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, jg1.han,
	linux-kernel, balbi, kishon, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

On Wed, Dec 19, 2012 at 10:37 PM, Vivek Gautam
<gautamvivek1987@gmail.com> wrote:
>
> On Thu, Dec 20, 2012 at 5:00 AM, Doug Anderson <dianders@chromium.org> wrote:
>>
>> On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
>>> +static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci)
>>> +{
>>> +       struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
>>> +
>>> +       if (s5p_ehci->phy) {
>>> +               samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);
>>
>> This confuses me.  Why are you setting the type to host here?
>>
> Being in host controller, before calling usb_phy_init() we set type to
> Host since, with certain SOCs
> like 4210, same register has different bit settings for HOST type and
> device type. So setting this
> to Host type here make the flow of usb_phy_init to go in the direction of Host.

OK.  I think I need to study the code more...

>>>
>>> +       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
>>> +       if (IS_ERR_OR_NULL(phy)) {
>>> +               /* Fallback to pdata */
>>> +               if (!pdata) {
>>> +                       dev_err(&pdev->dev, "no platform data or transceiver defined\n");
>>> +                       return -EPROBE_DEFER;
>>
>> Shouldn't you return -EINVAL like the old code did?
>
> We are deferring the probe since the usb-phy transceiver may get
> probed after ehci/ohci controllers.
> And if we return -EINVAL like the previous code, we would end up not
> setting the phy.

OK.  Something is wrong here then, since this really isn't an error:
* It should be commented about why you're deferring.
* You shouldn't have a dev_err for something that's not fatal.

Ideally we'd want something that would force probing to happen in the
right order.  I spent a little time looking and didn't see anything,
but maybe I'm missing something obvious.  If nothing pops out, the
defer seems OK as long as it is commented well.

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

* Re: [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support
@ 2012-12-20 17:51         ` Doug Anderson
  0 siblings, 0 replies; 34+ messages in thread
From: Doug Anderson @ 2012-12-20 17:51 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Vivek Gautam, linux-usb-u79uwXL29TY76Z2rM5mHXA,
	yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Praveen Paneri,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	jg1.han-Sze3O3UU22JBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, balbi-l0cyMroinI0,
	kishon-l0cyMroinI0, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

On Wed, Dec 19, 2012 at 10:37 PM, Vivek Gautam
<gautamvivek1987-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> On Thu, Dec 20, 2012 at 5:00 AM, Doug Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
>>
>> On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
>>> +static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci)
>>> +{
>>> +       struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
>>> +
>>> +       if (s5p_ehci->phy) {
>>> +               samsung_usbphy_set_type(s5p_ehci->phy, USB_PHY_TYPE_HOST);
>>
>> This confuses me.  Why are you setting the type to host here?
>>
> Being in host controller, before calling usb_phy_init() we set type to
> Host since, with certain SOCs
> like 4210, same register has different bit settings for HOST type and
> device type. So setting this
> to Host type here make the flow of usb_phy_init to go in the direction of Host.

OK.  I think I need to study the code more...

>>>
>>> +       phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
>>> +       if (IS_ERR_OR_NULL(phy)) {
>>> +               /* Fallback to pdata */
>>> +               if (!pdata) {
>>> +                       dev_err(&pdev->dev, "no platform data or transceiver defined\n");
>>> +                       return -EPROBE_DEFER;
>>
>> Shouldn't you return -EINVAL like the old code did?
>
> We are deferring the probe since the usb-phy transceiver may get
> probed after ehci/ohci controllers.
> And if we return -EINVAL like the previous code, we would end up not
> setting the phy.

OK.  Something is wrong here then, since this really isn't an error:
* It should be commented about why you're deferring.
* You shouldn't have a dev_err for something that's not fatal.

Ideally we'd want something that would force probing to happen in the
right order.  I spent a little time looking and didn't see anything,
but maybe I'm missing something obvious.  If nothing pops out, the
defer seems OK as long as it is commented well.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
@ 2012-12-20 19:03           ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-20 19:03 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Vivek Gautam, jg1.han, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, linux-usb,
	linux-kernel, balbi, kishon, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

Hi Doug,

On Thu, Dec 20, 2012 at 10:23 PM, Doug Anderson <dianders@chromium.org> wrote:
> Vivek,
>
> On Wed, Dec 19, 2012 at 9:51 PM, Vivek Gautam <gautamvivek1987@gmail.com> wrote:
>> Hi Doug,
>>
>>
>> On Thu, Dec 20, 2012 at 3:18 AM, Doug Anderson <dianders@chromium.org> wrote:
>>> Vivek,
>>>
>>> Since you're changing the name, I would have expected to see a removal
>>> of the old enum type in this patch.  I don't see it.  After applying
>>> all of your patches I find that S5P_USB_PHY_HOST and
>>> S5P_USB_PHY_DEVICE are still defined and used.
>>>
>>
>> True that we should have removed the earlier defined enums, infact i
>> did the same
>> in patchset v4 for this series. But since in this patchset i separated
>> out drivers and
>> architecture part, i thought it would be easier to remove them in one
>> shot in a latter commit
>> which will actually touch upon all architecture related code
>> (mach-exynos/setup-usb-phy.c,
>> mach-s5pv210/setup-usb-phy.c, and include/plat/usb-phy.h) once this
>> approach is accepted.
>>
>>> $ git grep S5P_USB_PHY_HOST
>>> arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
>>> arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
>>> arch/arm/plat-samsung/include/plat/usb-phy.h:   S5P_USB_PHY_HOST,
>>>
>>> I believe that those usages of the old enum should also be switched
>>> over and the old enum removed.
>>>
>> Sure, those enums need to be removed.
>> If you say i will submit a patch for the same.
>
> It would be nice to add it to the patch series in the next version.  Thanks!
>

Sure i shall add the same to the arch patches in the next version, or
if needed will send a separate patch for this.

> -Doug



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer
@ 2012-12-20 19:03           ` Vivek Gautam
  0 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2012-12-20 19:03 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Vivek Gautam, jg1.han-Sze3O3UU22JBDgjK7y7TUQ,
	yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Praveen Paneri,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, balbi-l0cyMroinI0,
	kishon-l0cyMroinI0, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

Hi Doug,

On Thu, Dec 20, 2012 at 10:23 PM, Doug Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
> Vivek,
>
> On Wed, Dec 19, 2012 at 9:51 PM, Vivek Gautam <gautamvivek1987-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> Hi Doug,
>>
>>
>> On Thu, Dec 20, 2012 at 3:18 AM, Doug Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
>>> Vivek,
>>>
>>> Since you're changing the name, I would have expected to see a removal
>>> of the old enum type in this patch.  I don't see it.  After applying
>>> all of your patches I find that S5P_USB_PHY_HOST and
>>> S5P_USB_PHY_DEVICE are still defined and used.
>>>
>>
>> True that we should have removed the earlier defined enums, infact i
>> did the same
>> in patchset v4 for this series. But since in this patchset i separated
>> out drivers and
>> architecture part, i thought it would be easier to remove them in one
>> shot in a latter commit
>> which will actually touch upon all architecture related code
>> (mach-exynos/setup-usb-phy.c,
>> mach-s5pv210/setup-usb-phy.c, and include/plat/usb-phy.h) once this
>> approach is accepted.
>>
>>> $ git grep S5P_USB_PHY_HOST
>>> arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
>>> arch/arm/mach-exynos/setup-usb-phy.c:   else if (type == S5P_USB_PHY_HOST)
>>> arch/arm/plat-samsung/include/plat/usb-phy.h:   S5P_USB_PHY_HOST,
>>>
>>> I believe that those usages of the old enum should also be switched
>>> over and the old enum removed.
>>>
>> Sure, those enums need to be removed.
>> If you say i will submit a patch for the same.
>
> It would be nice to add it to the patch series in the next version.  Thanks!
>

Sure i shall add the same to the arch patches in the next version, or
if needed will send a separate patch for this.

> -Doug



-- 
Thanks & Regards
Vivek
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
  2012-12-19 23:01   ` Doug Anderson
@ 2013-01-11 12:40     ` Vivek Gautam
  2013-01-11 12:58         ` Felipe Balbi
  2013-01-12  0:50       ` Doug Anderson
  0 siblings, 2 replies; 34+ messages in thread
From: Vivek Gautam @ 2013-01-11 12:40 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Vivek Gautam, linux-usb, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, jg1.han,
	linux-kernel, balbi, kishon, Kukjin Kim, stern, rob.herring,
	sylvester.nawrocki

Hi Doug,

Sorry!!  for the delayed response.


On Thu, Dec 20, 2012 at 4:31 AM, Doug Anderson <dianders@chromium.org> wrote:
> Vivek,
>
> I don't really have a good 10000 foot view about how all of the USB
> bits fit together, but a few detail-oriented comments below.
>
>
> On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
>> This patch adds host phy support to samsung-usbphy.c and
>> further adds support for samsung's exynos5250 usb-phy.
>>
>> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>> ---
>>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
>>  drivers/usb/phy/Kconfig                            |    2 +-
>>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
>>  include/linux/usb/samsung_usb_phy.h                |   13 +
>>  4 files changed, 454 insertions(+), 51 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> index a7b28b2..2ec5400 100644
>> --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> @@ -1,23 +1,38 @@
>>  * Samsung's usb phy transceiver
>>
>> -The Samsung's phy transceiver is used for controlling usb otg phy for
>> -s3c-hsotg usb device controller.
>> +The Samsung's phy transceiver is used for controlling usb phy for
>> +s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
>> +across Samsung SOCs.
>>  TODO: Adding the PHY binding with controller(s) according to the under
>>  developement generic PHY driver.
>>
>>  Required properties:
>> +
>> +Exynos4210:
>>  - compatible : should be "samsung,exynos4210-usbphy"
>>  - reg : base physical address of the phy registers and length of memory mapped
>>         region.
>>
>> +Exynos5250:
>> +- compatible : should be "samsung,exynos5250-usbphy"
>> +- reg : base physical address of the phy registers and length of memory mapped
>> +       region.
>> +
>>  Optional properties:
>>  - samsung,usb-phyhandle : should point to usb-phyhandle sub-node which provides
>>                         binding data to enable/disable device PHY handled by
>> -                       PMU register.
>> +                       PMU register; or to configure usb2.0 phy handled by
>> +                       SYSREG.
>>
>>                         Required properties:
>>                         - compatible : should be "samsung,usbdev-phyctrl" for
>> -                                       DEVICE type phy.
>> +                                      DEVICE type phy; or
>> +                                      should be "samsung,usbhost-phyctrl" for
>> +                                      HOST type phy; or
>> +                                      should be "samsung,usb-phycfg" for
>> +                                      USB2.0 PHY_CFG.
>>                         - samsung,phyhandle-reg: base physical address of
>> -                                               PHY_CONTROL register in PMU.
>> +                                                PHY_CONTROL register in PMU;
>> +                                                or USB2.0 PHY_CFG register
>> +                                                in SYSREG.
>>  - samsung,enable-mask : should be '1'
>> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
>> index 17ad743..13c0eaf 100644
>> --- a/drivers/usb/phy/Kconfig
>> +++ b/drivers/usb/phy/Kconfig
>> @@ -47,7 +47,7 @@ config USB_RCAR_PHY
>>
>>  config SAMSUNG_USBPHY
>>         bool "Samsung USB PHY controller Driver"
>> -       depends on USB_S3C_HSOTG
>> +       depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
>>         select USB_OTG_UTILS
>>         help
>>           Enable this to support Samsung USB phy controller for samsung
>> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
>> index 4ceabe3..621348a 100644
>> --- a/drivers/usb/phy/samsung-usbphy.c
>> +++ b/drivers/usb/phy/samsung-usbphy.c
>> @@ -5,7 +5,8 @@
>>   *
>>   * Author: Praveen Paneri <p.paneri@samsung.com>
>>   *
>> - * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
>> + * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
>> + * OHCI-EXYNOS controllers.
>>   *
>>   * This program is free software; you can redistribute it and/or modify
>>   * it under the terms of the GNU General Public License version 2 as
>> @@ -24,7 +25,7 @@
>>  #include <linux/err.h>
>>  #include <linux/io.h>
>>  #include <linux/of.h>
>> -#include <linux/usb/otg.h>
>> +#include <linux/usb/samsung_usb_phy.h>
>>  #include <linux/platform_data/samsung-usbphy.h>
>>
>>  /* Register definitions */
>> @@ -56,6 +57,103 @@
>>  #define RSTCON_HLINK_SWRST                     (0x1 << 1)
>>  #define RSTCON_SWRST                           (0x1 << 0)
>>
>> +/* EXYNOS5 */
>> +#define EXYNOS5_PHY_HOST_CTRL0                 (0x00)
>> +
>> +#define HOST_CTRL0_PHYSWRSTALL                 (0x1 << 31)
>> +
>> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
>> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
>> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
>> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
>> +
>> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
>> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
>> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
>> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
>> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
>> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
>> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
>> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
>> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
>
> Add the shifts to the #defines and remove HOST_CTRL0_FSEL(_x).  That
> makes it match the older phy more closely.
>
Wouldn't it hamper the readability when shifts are used ??
I mean if we have something like this -

phyhost |= HOST_CTRL0_FSEL(phyclk)

so, if we are using the shifts then
phyhost |= (HOST_CTRL0_FSEL_CLKSEL_24M << HOST_CTRL0_FSEL_SHIFT)

If you say i will add the shifts here.

>> +
>> +#define HOST_CTRL0_TESTBURNIN                  (0x1 << 11)
>> +#define HOST_CTRL0_RETENABLE                   (0x1 << 10)
>> +#define HOST_CTRL0_COMMONON_N                  (0x1 << 9)
>> +#define HOST_CTRL0_SIDDQ                       (0x1 << 6)
>> +#define HOST_CTRL0_FORCESLEEP                  (0x1 << 5)
>> +#define HOST_CTRL0_FORCESUSPEND                        (0x1 << 4)
>> +#define HOST_CTRL0_WORDINTERFACE               (0x1 << 3)
>> +#define HOST_CTRL0_UTMISWRST                   (0x1 << 2)
>> +#define HOST_CTRL0_LINKSWRST                   (0x1 << 1)
>> +#define HOST_CTRL0_PHYSWRST                    (0x1 << 0)
>> +
>> +#define EXYNOS5_PHY_HOST_TUNE0                 (0x04)
>> +
>> +#define EXYNOS5_PHY_HSIC_CTRL1                 (0x10)
>> +
>> +#define EXYNOS5_PHY_HSIC_TUNE1                 (0x14)
>> +
>> +#define EXYNOS5_PHY_HSIC_CTRL2                 (0x20)
>> +
>> +#define EXYNOS5_PHY_HSIC_TUNE2                 (0x24)
>> +
>> +#define HSIC_CTRL_REFCLKSEL_MASK               (0x3)
>> +#define HSIC_CTRL_REFCLKSEL                    (0x2 << 23)
>> +
>> +#define HSIC_CTRL_REFCLKDIV_MASK               (0x7f)
>> +#define HSIC_CTRL_REFCLKDIV(_x)                        ((_x) << 16)
>> +#define HSIC_CTRL_REFCLKDIV_12                 (0x24 << 16)
>> +#define HSIC_CTRL_REFCLKDIV_15                 (0x1c << 16)
>> +#define HSIC_CTRL_REFCLKDIV_16                 (0x1a << 16)
>> +#define HSIC_CTRL_REFCLKDIV_19_2               (0x15 << 16)
>> +#define HSIC_CTRL_REFCLKDIV_20                 (0x14)
>> +
>> +#define HSIC_CTRL_SIDDQ                                (0x1 << 6)
>> +#define HSIC_CTRL_FORCESLEEP                   (0x1 << 5)
>> +#define HSIC_CTRL_FORCESUSPEND                 (0x1 << 4)
>> +#define HSIC_CTRL_WORDINTERFACE                        (0x1 << 3)
>> +#define HSIC_CTRL_UTMISWRST                    (0x1 << 2)
>> +#define HSIC_CTRL_PHYSWRST                     (0x1 << 0)
>> +
>> +#define EXYNOS5_PHY_HOST_EHCICTRL              (0x30)
>> +
>> +#define HOST_EHCICTRL_ENAINCRXALIGN            (0x1 << 29)
>> +#define HOST_EHCICTRL_ENAINCR4                 (0x1 << 28)
>> +#define HOST_EHCICTRL_ENAINCR8                 (0x1 << 27)
>> +#define HOST_EHCICTRL_ENAINCR16                        (0x1 << 26)
>> +
>> +#define EXYNOS5_PHY_HOST_OHCICTRL              (0x34)
>> +
>> +#define HOST_OHCICTRL_SUSPLGCY                 (0x1 << 3)
>> +#define HOST_OHCICTRL_APPSTARTCLK              (0x1 << 2)
>> +#define HOST_OHCICTRL_CNTSEL                   (0x1 << 1)
>> +#define HOST_OHCICTRL_CLKCKTRST                        (0x1 << 0)
>> +
>> +#define EXYNOS5_PHY_OTG_SYS                    (0x38)
>> +
>> +#define OTG_SYS_PHYLINK_SWRESET                        (0x1 << 14)
>> +#define OTG_SYS_LINKSWRST_UOTG                 (0x1 << 13)
>> +#define OTG_SYS_PHY0_SWRST                     (0x1 << 12)
>> +
>> +#define OTG_SYS_REFCLKSEL_MASK                 (0x3 << 9)
>> +#define OTG_SYS_REFCLKSEL_XTAL                 (0x0 << 9)
>> +#define OTG_SYS_REFCLKSEL_EXTL                 (0x1 << 9)
>> +#define OTG_SYS_REFCLKSEL_CLKCORE              (0x2 << 9)
>> +
>> +#define OTG_SYS_IDPULLUP_UOTG                  (0x1 << 8)
>> +#define OTG_SYS_COMMON_ON                      (0x1 << 7)
>> +
>> +#define OTG_SYS_FSEL_MASK                      (0x7 << 4)
>> +#define OTG_SYS_FSEL(_x)                       ((_x) << 4)
>> +
>> +#define OTG_SYS_FORCESLEEP                     (0x1 << 3)
>> +#define OTG_SYS_OTGDISABLE                     (0x1 << 2)
>> +#define OTG_SYS_SIDDQ_UOTG                     (0x1 << 1)
>> +#define OTG_SYS_FORCESUSPEND                   (0x1 << 0)
>> +
>> +#define EXYNOS5_PHY_OTG_TUNE                   (0x40)
>> +
>>  #ifndef MHZ
>>  #define MHZ (1000*1000)
>>  #endif
>> @@ -63,6 +161,7 @@
>>  enum samsung_cpu_type {
>>         TYPE_S3C64XX,
>>         TYPE_EXYNOS4210,
>> +       TYPE_EXYNOS5250,
>>  };
>>
>>  /*
>> @@ -73,9 +172,13 @@ enum samsung_cpu_type {
>>   * @clk: usb phy clock
>>   * @regs: usb phy register memory base
>>   * @devctrl_reg: usb device phy-control pmu register memory base
>> + * @hostctrl_reg: usb host phy-control pmu register memory base
>> + * @phycfg_reg: usb2.0 phy-cfg system register memory base
>>   * @en_mask: enable mask
>>   * @ref_clk_freq: reference clock frequency selection
>>   * @cpu_type: machine identifier
>> + * @phy_type: It keeps track of the PHY type.
>> + * @host_usage: host_phy usage count.
>>   */
>>  struct samsung_usbphy {
>>         struct usb_phy  phy;
>> @@ -84,9 +187,13 @@ struct samsung_usbphy {
>>         struct clk      *clk;
>>         void __iomem    *regs;
>>         void __iomem    *devctrl_reg;
>> +       void __iomem    *hostctrl_reg;
>> +       void __iomem    *phycfg_reg;
>>         u32             en_mask;
>>         int             ref_clk_freq;
>>         int             cpu_type;
>> +       enum samsung_usb_phy_type phy_type;
>> +       atomic_t        host_usage;
>>  };
>>
>>  #define phy_to_sphy(x)         container_of((x), struct samsung_usbphy, phy)
>> @@ -96,26 +203,49 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
>>         struct device_node *usb_phyctrl;
>>         u32 reg;
>>         int lenp;
>> +       int count = 0;
>>
>>         if (!sphy->dev->of_node) {
>>                 sphy->devctrl_reg = NULL;
>
> Remove init to NULL here (and in other error cases).
> ...I was going to suggest instead to add setting of hostctrl_reg and
> phycfg_reg to NULL, but then realized that we should just rely on the
> fact that the devm_kzalloc() will zero things.
>

this will change in accordance with v6 patch for pmu_isolation.

>>                 return -ENODEV;
>>         }
>>
>> -       if (of_get_property(sphy->dev->of_node, "samsung,usb-phyhandle", &lenp)) {
>> -               usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
>> -                                               "samsung,usb-phyhandle", 0);
>> -               if (!usb_phyctrl) {
>> -                       dev_warn(sphy->dev, "Can't get usb-phy handle\n");
>> -                       sphy->devctrl_reg = NULL;
>> -               }
>> -
>> -               of_property_read_u32(usb_phyctrl, "samsung,phyhandle-reg", &reg);
>> +       if (of_get_property(sphy->dev->of_node,
>> +                       "samsung,usb-phyhandle", &lenp)) {
>> +               do {
>
> Indentation gets excessive here.  Can you break this into its own function?
>
ditto.

>> +                       usb_phyctrl = of_parse_phandle(sphy->dev->of_node,
>> +                                                       "samsung,usb-phyhandle",
>> +                                                       count++);
>> +                       if (!usb_phyctrl) {
>> +                               dev_warn(sphy->dev,
>> +                                       "Can't get usb-phy handle\n");
>> +                               sphy->devctrl_reg = NULL;
>
> This is a confusing way to handle the error.  Essentially you want to
> print an error if you get to the end of the function and devctrl_reg,
> hostctrl_reg, and phycfg_reg are all NULL, right?  Just check for
> that.
>
sure, will amend this.

>> +                       }
>> +
>> +                       of_property_read_u32(usb_phyctrl,
>> +                                       "samsung,phyhandle-reg", &reg);
>> +
>> +                       /*
>> +                        * Considering here the maximum number of configurable
>> +                        * register settings: DEVICE_PHY_CONTROL
>> +                        *                    HOST_PHY_CONTROL
>> +                        *                    PHY20_CFG
>> +                        */
>> +                       if (of_device_is_compatible(usb_phyctrl,
>> +                                               "samsung,usbdev-phyctrl"))
>> +                               sphy->devctrl_reg = ioremap(reg, SZ_4);
>> +                       else if (of_device_is_compatible(usb_phyctrl,
>> +                                               "samsung,usbhost-phyctrl"))
>> +                               sphy->hostctrl_reg = ioremap(reg, SZ_4);
>> +                       else if (of_device_is_compatible(usb_phyctrl,
>> +                                               "samsung,usb-phycfg"))
>> +                               sphy->phycfg_reg = ioremap(reg, SZ_4);
>> +
>> +                       of_property_read_u32(sphy->dev->of_node,
>> +                                       "samsung,enable-mask", &sphy->en_mask);
>> +               } while (of_parse_phandle(sphy->dev->of_node,
>> +                               "samsung,usb-phyhandle", count));
>
> Can't you use (*lenp) to figure out how many times to loop?  Seems
> like that would be simpler.
>

this will change in accordance with v6 patch for pmu_isolation.

>>
>> -               sphy->devctrl_reg = ioremap(reg, SZ_4);
>> -
>> -               of_property_read_u32(sphy->dev->of_node, "samsung,enable-mask",
>> -                                                       &sphy->en_mask);
>>                 of_node_put(usb_phyctrl);
>>         } else {
>>                 dev_warn(sphy->dev, "Can't get usb-phy handle\n");
>> @@ -129,13 +259,18 @@ static int samsung_usbphy_parse_dt_param(struct samsung_usbphy *sphy)
>>   * Set isolation here for phy.
>>   * SOCs control this by controlling corresponding PMU registers
>>   */
>> -static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
>> +static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy,
>> +                                                       int on, int type)
>
> Why add type to this function.  It's always sphy->type, isn't it?
>

Valid, :-) will change this.

>>  {
>> -       void __iomem *usb_phyctrl_reg;
>> +       void __iomem *usb_phyctrl_reg = NULL;
>>         u32 en_mask = sphy->en_mask;
>>         u32 reg;
>>
>> -       usb_phyctrl_reg = sphy->devctrl_reg;
>> +       if (type == USB_PHY_TYPE_DEVICE) {
>
> nit: no braces for single line "if".  Please run checkpatch.
>

this will change in accordance with v6 patch for pmu_isolation.

>> +               usb_phyctrl_reg = sphy->devctrl_reg;
>> +       } else if (type == USB_PHY_TYPE_HOST) {
>> +               usb_phyctrl_reg = sphy->hostctrl_reg;
>> +       }
>>
>>         if (!usb_phyctrl_reg) {
>>                 dev_warn(sphy->dev, "Can't set pmu isolation\n");
>> @@ -151,6 +286,47 @@ static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, int on)
>>  }
>>
>>  /*
>> + * Configure the mode of working og usb-phy here: HOST/DEVICE.
>
> s/og/otg?
>

s/og/of here

>> + * SOCs control this by controlling corresponding system register
>> + */
>> +static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy, int type)
>
> Why add type to this function.  It's always sphy->type, isn't it?
>

Sure, no need of type argument here. will change this.

>> +{
>> +       void __iomem *usb_phycfg_reg;
>> +       u32 en_mask = sphy->en_mask;
>> +       u32 reg;
>> +
>> +       usb_phycfg_reg = sphy->phycfg_reg;
>> +
>> +       if (!usb_phycfg_reg) {
>> +               dev_warn(sphy->dev, "Can't select specified phy mode\n");
>> +               return;
>> +       }
>> +
>> +       reg = readl(usb_phycfg_reg);
>> +
>> +       if (type == USB_PHY_TYPE_DEVICE)
>
> This is really confusing.  You disable for device and enable for host?  Eh?
>

This is written badly :-(
Actually resetting the bit puts it to device mode and setting the bit to Host.
Should have used a separate mask for phycfg. Will amend this.

>> +               writel(reg & ~en_mask, usb_phycfg_reg);
>> +       else if (type == USB_PHY_TYPE_HOST)
>> +               writel(reg | en_mask, usb_phycfg_reg);
>> +}
>> +
>> +/*
>> + * PHYs are different for USB Device and USB Host. Controllers can make
>> + * sure that the correct PHY type is selected by calling this function
>> + * before any PHY operation.
>> + */
>> +int samsung_usbphy_set_type(struct usb_phy *phy,
>> +                               enum samsung_usb_phy_type phy_type)
>> +{
>> +       struct samsung_usbphy *sphy = phy_to_sphy(phy);
>> +
>> +       if (sphy->phy_type != phy_type)
>> +               sphy->phy_type = phy_type;
>
> Kill useless "if"
>
Ok

>> +
>> +       return 0;
>> +}
>> +
>> +/*
>>   * Returns reference clock frequency selection value
>>   */
>>  static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
>> @@ -158,34 +334,178 @@ static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
>>         struct clk *ref_clk;
>>         int refclk_freq = 0;
>>
>> -       ref_clk = clk_get(sphy->dev, "xusbxti");
>> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
>> +               ref_clk = clk_get(sphy->dev, "ext_xtal");
>> +       else
>> +               ref_clk = clk_get(sphy->dev, "xusbxti");
>
> Seems strange that this clock has a special different name on 5250.
> Maybe that should be fixed rather than hacking it here?
> clk_add_alias()?
>

Actually, SoC untill exynos4 were using clock "xusbxti" for USB-PHY
which has a fixed rate of 24MHz, now exynos5250 uses "ext_xtal" clock
for USB-PHY whose rate is determined at the time of clk_init (no doubt it's
also 24MHz for exynos5250).

>>         if (IS_ERR(ref_clk)) {
>>                 dev_err(sphy->dev, "Failed to get reference clock\n");
>>                 return PTR_ERR(ref_clk);
>>         }
>>
>> -       switch (clk_get_rate(ref_clk)) {
>> -       case 12 * MHZ:
>> -               refclk_freq = PHYCLK_CLKSEL_12M;
>> -               break;
>> -       case 24 * MHZ:
>> -               refclk_freq = PHYCLK_CLKSEL_24M;
>> -               break;
>> -       case 48 * MHZ:
>> -               refclk_freq = PHYCLK_CLKSEL_48M;
>> -               break;
>> -       default:
>> -               if (sphy->cpu_type == TYPE_S3C64XX)
>> -                       refclk_freq = PHYCLK_CLKSEL_48M;
>> -               else
>> +       if (sphy->cpu_type == TYPE_EXYNOS5250) {
>> +               /* set clock frequency for PLL */
>> +               switch (clk_get_rate(ref_clk)) {
>> +               case 96 * 100000:
>
> nit: change to 9600 * KHZ to match; below too.
>
sure.

>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
>
> Why |= with 0?
>
kept this just to keep things look similar :-). will remove this line,

>> +                       break;
>> +               case 10 * MHZ:
>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_10M;
>> +                       break;
>> +               case 12 * MHZ:
>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_12M;
>> +                       break;
>> +               case 192 * 100000:
>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_19200K;
>> +                       break;
>> +               case 20 * MHZ:
>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_20M;
>> +                       break;
>> +               case 50 * MHZ:
>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_50M;
>> +                       break;
>> +               case 24 * MHZ:
>> +               default:
>> +                       /* default reference clock */
>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_24M;
>> +                       break;
>> +               }
>> +       } else {
>> +               switch (clk_get_rate(ref_clk)) {
>> +               case 12 * MHZ:
>> +                       refclk_freq = PHYCLK_CLKSEL_12M;
>> +                       break;
>> +               case 24 * MHZ:
>>                         refclk_freq = PHYCLK_CLKSEL_24M;
>> -               break;
>> +                       break;
>> +               case 48 * MHZ:
>> +                       refclk_freq = PHYCLK_CLKSEL_48M;
>> +                       break;
>> +               default:
>> +                       if (sphy->cpu_type == TYPE_S3C64XX)
>> +                               refclk_freq = PHYCLK_CLKSEL_48M;
>> +                       else
>> +                               refclk_freq = PHYCLK_CLKSEL_24M;
>> +                       break;
>> +               }
>>         }
>>         clk_put(ref_clk);
>>
>>         return refclk_freq;
>>  }
>>
>> +static int exynos5_phyhost_is_on(void *regs)
>
> return bool?
>
Yeah, sure.

>> +{
>> +       u32 reg;
>> +
>> +       reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
>> +
>> +       return !(reg & HOST_CTRL0_SIDDQ);
>> +}
>> +
>> +static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy)
>> +{
>> +       void __iomem *regs = sphy->regs;
>> +       u32 phyclk = sphy->ref_clk_freq;
>> +       u32 phyhost;
>> +       u32 phyotg;
>> +       u32 phyhsic;
>> +       u32 ehcictrl;
>> +       u32 ohcictrl;
>> +
>> +       atomic_inc(&sphy->host_usage);
>
> Can you explain what situations you expect host_usage to be > 1?  Why
> is that special for exynos5?
>
this host_usage keeps a track of initialization and de-initialization of PHY.
since both ehci and ohci are customers for this phy, host_usage keeps
either of them from disabling the phy when other is still using it.

> If you really expect multiple users of this, it seems like you need
> better locking.  Without better locking one process could be in the
> middle of disabling at the same time another process is enabling,
> couldn't it?
>

Yes, sure we need to add better locking. Will check on this more.

>> +
>> +       if (exynos5_phyhost_is_on(regs)) {
>> +               dev_info(sphy->dev, "Already power on PHY\n");
>> +               return;
>> +       }
>> +
>> +       /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */
>> +       samsung_usbphy_cfg_sel(sphy, USB_PHY_TYPE_HOST);
>> +
>> +       /* Host configuration */
>> +       phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
>> +
>> +       /* phy reference clock configuration */
>> +       phyhost &= ~HOST_CTRL0_FSEL_MASK;
>> +       phyhost |= HOST_CTRL0_FSEL(phyclk);
>> +
>> +       /* host phy reset */
>> +       phyhost &= ~(HOST_CTRL0_PHYSWRST |
>> +                       HOST_CTRL0_PHYSWRSTALL |
>> +                       HOST_CTRL0_SIDDQ |
>> +                       /* Enable normal mode of operation */
>> +                       HOST_CTRL0_FORCESUSPEND |
>> +                       HOST_CTRL0_FORCESLEEP);
>> +
>> +       /* Link reset */
>> +       phyhost |= (HOST_CTRL0_LINKSWRST |
>> +                       HOST_CTRL0_UTMISWRST |
>> +                       /* COMMON Block configuration during suspend */
>> +                       HOST_CTRL0_COMMONON_N);
>> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
>> +       udelay(10);
>> +       phyhost &= ~(HOST_CTRL0_LINKSWRST |
>> +                       HOST_CTRL0_UTMISWRST);
>> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
>> +
>> +       /* OTG configuration */
>> +       phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
>> +
>> +       /* phy reference clock configuration */
>> +       phyotg &= ~OTG_SYS_FSEL_MASK;
>> +       phyotg |= OTG_SYS_FSEL(phyclk);
>> +
>> +       /* Enable normal mode of operation */
>> +       phyotg &= ~(OTG_SYS_FORCESUSPEND |
>> +                       OTG_SYS_SIDDQ_UOTG |
>> +                       OTG_SYS_FORCESLEEP |
>> +                       OTG_SYS_REFCLKSEL_MASK |
>> +                       /* COMMON Block configuration during suspend */
>> +                       OTG_SYS_COMMON_ON);
>> +
>> +       /* OTG phy & link reset */
>> +       phyotg |= (OTG_SYS_PHY0_SWRST |
>> +                       OTG_SYS_LINKSWRST_UOTG |
>> +                       OTG_SYS_PHYLINK_SWRESET |
>> +                       OTG_SYS_OTGDISABLE |
>> +                       /* Set phy refclk */
>> +                       OTG_SYS_REFCLKSEL_CLKCORE);
>> +
>> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
>> +       udelay(10);
>> +       phyotg &= ~(OTG_SYS_PHY0_SWRST |
>> +                       OTG_SYS_LINKSWRST_UOTG |
>> +                       OTG_SYS_PHYLINK_SWRESET);
>> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
>> +
>> +       /* HSIC phy configuration */
>> +       phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
>> +                       HSIC_CTRL_REFCLKSEL |
>> +                       HSIC_CTRL_PHYSWRST);
>> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
>> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
>> +       udelay(10);
>> +       phyhsic &= ~HSIC_CTRL_PHYSWRST;
>> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
>> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
>> +
>> +       udelay(80);
>> +
>> +       /* enable EHCI DMA burst */
>> +       ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL);
>> +       ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN |
>> +                               HOST_EHCICTRL_ENAINCR4 |
>> +                               HOST_EHCICTRL_ENAINCR8 |
>> +                               HOST_EHCICTRL_ENAINCR16);
>> +       writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL);
>> +
>> +       /* set ohci_suspend_on_n */
>> +       ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL);
>> +       ohcictrl |= HOST_OHCICTRL_SUSPLGCY;
>> +       writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL);
>> +}
>> +
>>  static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>>  {
>>         void __iomem *regs = sphy->regs;
>> @@ -221,6 +541,41 @@ static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
>>         writel(rstcon, regs + SAMSUNG_RSTCON);
>>  }
>>
>> +static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy)
>> +{
>> +       void __iomem *regs = sphy->regs;
>> +       u32 phyhost;
>> +       u32 phyotg;
>> +       u32 phyhsic;
>> +
>> +       if (atomic_dec_return(&sphy->host_usage) > 0) {
>> +               dev_info(sphy->dev, "still being used\n");
>> +               return;
>> +       }
>> +
>> +       phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
>> +                       HSIC_CTRL_REFCLKSEL |
>> +                       HSIC_CTRL_SIDDQ |
>> +                       HSIC_CTRL_FORCESLEEP |
>> +                       HSIC_CTRL_FORCESUSPEND);
>> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
>> +       writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
>> +
>> +       phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
>> +       phyhost |= (HOST_CTRL0_SIDDQ |
>> +                       HOST_CTRL0_FORCESUSPEND |
>> +                       HOST_CTRL0_FORCESLEEP |
>> +                       HOST_CTRL0_PHYSWRST |
>> +                       HOST_CTRL0_PHYSWRSTALL);
>> +       writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
>> +
>> +       phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
>> +       phyotg |= (OTG_SYS_FORCESUSPEND |
>> +                       OTG_SYS_SIDDQ_UOTG |
>> +                       OTG_SYS_FORCESLEEP);
>> +       writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
>> +}
>> +
>>  static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
>>  {
>>         void __iomem *regs = sphy->regs;
>> @@ -263,10 +618,13 @@ static int samsung_usbphy_init(struct usb_phy *phy)
>>         if (sphy->plat && sphy->plat->pmu_isolation)
>>                 sphy->plat->pmu_isolation(false);
>>         else
>> -               samsung_usbphy_set_isolation(sphy, false);
>> +               samsung_usbphy_set_isolation(sphy, false, sphy->phy_type);
>>
>>         /* Initialize usb phy registers */
>> -       samsung_usbphy_enable(sphy);
>> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
>> +               samsung_exynos5_usbphy_enable(sphy);
>> +       else
>> +               samsung_usbphy_enable(sphy);
>>
>>         /* Disable the phy clock */
>>         clk_disable_unprepare(sphy->clk);
>> @@ -288,13 +646,16 @@ static void samsung_usbphy_shutdown(struct usb_phy *phy)
>>         }
>>
>>         /* De-initialize usb phy registers */
>> -       samsung_usbphy_disable(sphy);
>> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
>> +               samsung_exynos5_usbphy_disable(sphy);
>> +       else
>> +               samsung_usbphy_disable(sphy);
>>
>>         /* Enable phy isolation */
>>         if (sphy->plat && sphy->plat->pmu_isolation)
>>                 sphy->plat->pmu_isolation(true);
>>         else
>> -               samsung_usbphy_set_isolation(sphy, true);
>> +               samsung_usbphy_set_isolation(sphy, true, sphy->phy_type);
>>
>>         clk_disable_unprepare(sphy->clk);
>>  }
>> @@ -339,12 +700,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>>         if (!sphy)
>>                 return -ENOMEM;
>>
>> -       clk = devm_clk_get(dev, "otg");
>> -       if (IS_ERR(clk)) {
>> -               dev_err(dev, "Failed to get otg clock\n");
>> -               return PTR_ERR(clk);
>> -       }
>> -
>>         sphy->dev = &pdev->dev;
>>
>>         ret = samsung_usbphy_parse_dt_param(sphy);
>> @@ -361,7 +716,6 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>>
>>         sphy->plat              = pdata;
>>         sphy->regs              = phy_base;
>> -       sphy->clk               = clk;
>>         sphy->phy.dev           = sphy->dev;
>>         sphy->phy.label         = "samsung-usbphy";
>>         sphy->phy.init          = samsung_usbphy_init;
>> @@ -371,6 +725,17 @@ static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
>>
>>         platform_set_drvdata(pdev, sphy);
>>
>> +       if (sphy->cpu_type == TYPE_EXYNOS5250)
>> +               clk = devm_clk_get(dev, "usbhost");
>
> Why is 5250 special in that it is always host?  Something doesn't seem
> right here.
>

exynos5250 onward usb-phy block gets its clock from 'usb host' unlike earlier
SoCs where it was getting the clock from 'otg'
So this change was required.

> ...also, are you sure you want to move this down to after
> platform_set_drvdata()?  I don't think it will hurt anything, but
> seems better to leave it where it was and just make call
> samsung_usbphy_get_driver_data(pdev) earlier in the function.
>
Ok, will amend this as suggested.


-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
  2013-01-11 12:40     ` Vivek Gautam
@ 2013-01-11 12:58         ` Felipe Balbi
  2013-01-12  0:50       ` Doug Anderson
  1 sibling, 0 replies; 34+ messages in thread
From: Felipe Balbi @ 2013-01-11 12:58 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Doug Anderson, Vivek Gautam, linux-usb, yulgon.kim,
	linux-samsung-soc, Praveen Paneri, gregkh, devicetree-discuss,
	jg1.han, linux-kernel, balbi, kishon, Kukjin Kim, stern,
	rob.herring, sylvester.nawrocki

[-- Attachment #1: Type: text/plain, Size: 6999 bytes --]

Hi,

On Fri, Jan 11, 2013 at 06:10:48PM +0530, Vivek Gautam wrote:
> Hi Doug,
> 
> Sorry!!  for the delayed response.
> 
> 
> On Thu, Dec 20, 2012 at 4:31 AM, Doug Anderson <dianders@chromium.org> wrote:
> > Vivek,
> >
> > I don't really have a good 10000 foot view about how all of the USB
> > bits fit together, but a few detail-oriented comments below.
> >
> >
> > On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> >> This patch adds host phy support to samsung-usbphy.c and
> >> further adds support for samsung's exynos5250 usb-phy.
> >>
> >> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> >> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> >> ---
> >>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
> >>  drivers/usb/phy/Kconfig                            |    2 +-
> >>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
> >>  include/linux/usb/samsung_usb_phy.h                |   13 +
> >>  4 files changed, 454 insertions(+), 51 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> >> index a7b28b2..2ec5400 100644
> >> --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> >> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> >> @@ -1,23 +1,38 @@
> >>  * Samsung's usb phy transceiver
> >>
> >> -The Samsung's phy transceiver is used for controlling usb otg phy for
> >> -s3c-hsotg usb device controller.
> >> +The Samsung's phy transceiver is used for controlling usb phy for
> >> +s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
> >> +across Samsung SOCs.
> >>  TODO: Adding the PHY binding with controller(s) according to the under
> >>  developement generic PHY driver.
> >>
> >>  Required properties:
> >> +
> >> +Exynos4210:
> >>  - compatible : should be "samsung,exynos4210-usbphy"
> >>  - reg : base physical address of the phy registers and length of memory mapped
> >>         region.
> >>
> >> +Exynos5250:
> >> +- compatible : should be "samsung,exynos5250-usbphy"
> >> +- reg : base physical address of the phy registers and length of memory mapped
> >> +       region.
> >> +
> >>  Optional properties:
> >>  - samsung,usb-phyhandle : should point to usb-phyhandle sub-node which provides
> >>                         binding data to enable/disable device PHY handled by
> >> -                       PMU register.
> >> +                       PMU register; or to configure usb2.0 phy handled by
> >> +                       SYSREG.
> >>
> >>                         Required properties:
> >>                         - compatible : should be "samsung,usbdev-phyctrl" for
> >> -                                       DEVICE type phy.
> >> +                                      DEVICE type phy; or
> >> +                                      should be "samsung,usbhost-phyctrl" for
> >> +                                      HOST type phy; or
> >> +                                      should be "samsung,usb-phycfg" for
> >> +                                      USB2.0 PHY_CFG.
> >>                         - samsung,phyhandle-reg: base physical address of
> >> -                                               PHY_CONTROL register in PMU.
> >> +                                                PHY_CONTROL register in PMU;
> >> +                                                or USB2.0 PHY_CFG register
> >> +                                                in SYSREG.
> >>  - samsung,enable-mask : should be '1'
> >> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> >> index 17ad743..13c0eaf 100644
> >> --- a/drivers/usb/phy/Kconfig
> >> +++ b/drivers/usb/phy/Kconfig
> >> @@ -47,7 +47,7 @@ config USB_RCAR_PHY
> >>
> >>  config SAMSUNG_USBPHY
> >>         bool "Samsung USB PHY controller Driver"
> >> -       depends on USB_S3C_HSOTG
> >> +       depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
> >>         select USB_OTG_UTILS
> >>         help
> >>           Enable this to support Samsung USB phy controller for samsung
> >> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
> >> index 4ceabe3..621348a 100644
> >> --- a/drivers/usb/phy/samsung-usbphy.c
> >> +++ b/drivers/usb/phy/samsung-usbphy.c
> >> @@ -5,7 +5,8 @@
> >>   *
> >>   * Author: Praveen Paneri <p.paneri@samsung.com>
> >>   *
> >> - * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
> >> + * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
> >> + * OHCI-EXYNOS controllers.
> >>   *
> >>   * This program is free software; you can redistribute it and/or modify
> >>   * it under the terms of the GNU General Public License version 2 as
> >> @@ -24,7 +25,7 @@
> >>  #include <linux/err.h>
> >>  #include <linux/io.h>
> >>  #include <linux/of.h>
> >> -#include <linux/usb/otg.h>
> >> +#include <linux/usb/samsung_usb_phy.h>
> >>  #include <linux/platform_data/samsung-usbphy.h>
> >>
> >>  /* Register definitions */
> >> @@ -56,6 +57,103 @@
> >>  #define RSTCON_HLINK_SWRST                     (0x1 << 1)
> >>  #define RSTCON_SWRST                           (0x1 << 0)
> >>
> >> +/* EXYNOS5 */
> >> +#define EXYNOS5_PHY_HOST_CTRL0                 (0x00)
> >> +
> >> +#define HOST_CTRL0_PHYSWRSTALL                 (0x1 << 31)
> >> +
> >> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
> >> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
> >> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
> >> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
> >> +
> >> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
> >> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
> >
> > Add the shifts to the #defines and remove HOST_CTRL0_FSEL(_x).  That
> > makes it match the older phy more closely.
> >
> Wouldn't it hamper the readability when shifts are used ??
> I mean if we have something like this -
> 
> phyhost |= HOST_CTRL0_FSEL(phyclk)

this one looks better to my eyes.

> >> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
> >
> > Why |= with 0?
> >
> kept this just to keep things look similar :-). will remove this line,

I would rather keep it. Compiler will optimize it out anyway and it
makes things logical, I mean, we can see that you're telling IP that
reference clock is 9600KHz.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
@ 2013-01-11 12:58         ` Felipe Balbi
  0 siblings, 0 replies; 34+ messages in thread
From: Felipe Balbi @ 2013-01-11 12:58 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Doug Anderson, Vivek Gautam, linux-usb, yulgon.kim,
	linux-samsung-soc, Praveen Paneri, gregkh, devicetree-discuss,
	jg1.han, linux-kernel, balbi, kishon, Kukjin Kim, stern,
	rob.herring, sylvester.nawrocki

[-- Attachment #1: Type: text/plain, Size: 6999 bytes --]

Hi,

On Fri, Jan 11, 2013 at 06:10:48PM +0530, Vivek Gautam wrote:
> Hi Doug,
> 
> Sorry!!  for the delayed response.
> 
> 
> On Thu, Dec 20, 2012 at 4:31 AM, Doug Anderson <dianders@chromium.org> wrote:
> > Vivek,
> >
> > I don't really have a good 10000 foot view about how all of the USB
> > bits fit together, but a few detail-oriented comments below.
> >
> >
> > On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
> >> This patch adds host phy support to samsung-usbphy.c and
> >> further adds support for samsung's exynos5250 usb-phy.
> >>
> >> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
> >> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
> >> ---
> >>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
> >>  drivers/usb/phy/Kconfig                            |    2 +-
> >>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
> >>  include/linux/usb/samsung_usb_phy.h                |   13 +
> >>  4 files changed, 454 insertions(+), 51 deletions(-)
> >>
> >> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> >> index a7b28b2..2ec5400 100644
> >> --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> >> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
> >> @@ -1,23 +1,38 @@
> >>  * Samsung's usb phy transceiver
> >>
> >> -The Samsung's phy transceiver is used for controlling usb otg phy for
> >> -s3c-hsotg usb device controller.
> >> +The Samsung's phy transceiver is used for controlling usb phy for
> >> +s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
> >> +across Samsung SOCs.
> >>  TODO: Adding the PHY binding with controller(s) according to the under
> >>  developement generic PHY driver.
> >>
> >>  Required properties:
> >> +
> >> +Exynos4210:
> >>  - compatible : should be "samsung,exynos4210-usbphy"
> >>  - reg : base physical address of the phy registers and length of memory mapped
> >>         region.
> >>
> >> +Exynos5250:
> >> +- compatible : should be "samsung,exynos5250-usbphy"
> >> +- reg : base physical address of the phy registers and length of memory mapped
> >> +       region.
> >> +
> >>  Optional properties:
> >>  - samsung,usb-phyhandle : should point to usb-phyhandle sub-node which provides
> >>                         binding data to enable/disable device PHY handled by
> >> -                       PMU register.
> >> +                       PMU register; or to configure usb2.0 phy handled by
> >> +                       SYSREG.
> >>
> >>                         Required properties:
> >>                         - compatible : should be "samsung,usbdev-phyctrl" for
> >> -                                       DEVICE type phy.
> >> +                                      DEVICE type phy; or
> >> +                                      should be "samsung,usbhost-phyctrl" for
> >> +                                      HOST type phy; or
> >> +                                      should be "samsung,usb-phycfg" for
> >> +                                      USB2.0 PHY_CFG.
> >>                         - samsung,phyhandle-reg: base physical address of
> >> -                                               PHY_CONTROL register in PMU.
> >> +                                                PHY_CONTROL register in PMU;
> >> +                                                or USB2.0 PHY_CFG register
> >> +                                                in SYSREG.
> >>  - samsung,enable-mask : should be '1'
> >> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
> >> index 17ad743..13c0eaf 100644
> >> --- a/drivers/usb/phy/Kconfig
> >> +++ b/drivers/usb/phy/Kconfig
> >> @@ -47,7 +47,7 @@ config USB_RCAR_PHY
> >>
> >>  config SAMSUNG_USBPHY
> >>         bool "Samsung USB PHY controller Driver"
> >> -       depends on USB_S3C_HSOTG
> >> +       depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
> >>         select USB_OTG_UTILS
> >>         help
> >>           Enable this to support Samsung USB phy controller for samsung
> >> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
> >> index 4ceabe3..621348a 100644
> >> --- a/drivers/usb/phy/samsung-usbphy.c
> >> +++ b/drivers/usb/phy/samsung-usbphy.c
> >> @@ -5,7 +5,8 @@
> >>   *
> >>   * Author: Praveen Paneri <p.paneri@samsung.com>
> >>   *
> >> - * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
> >> + * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
> >> + * OHCI-EXYNOS controllers.
> >>   *
> >>   * This program is free software; you can redistribute it and/or modify
> >>   * it under the terms of the GNU General Public License version 2 as
> >> @@ -24,7 +25,7 @@
> >>  #include <linux/err.h>
> >>  #include <linux/io.h>
> >>  #include <linux/of.h>
> >> -#include <linux/usb/otg.h>
> >> +#include <linux/usb/samsung_usb_phy.h>
> >>  #include <linux/platform_data/samsung-usbphy.h>
> >>
> >>  /* Register definitions */
> >> @@ -56,6 +57,103 @@
> >>  #define RSTCON_HLINK_SWRST                     (0x1 << 1)
> >>  #define RSTCON_SWRST                           (0x1 << 0)
> >>
> >> +/* EXYNOS5 */
> >> +#define EXYNOS5_PHY_HOST_CTRL0                 (0x00)
> >> +
> >> +#define HOST_CTRL0_PHYSWRSTALL                 (0x1 << 31)
> >> +
> >> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
> >> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
> >> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
> >> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
> >> +
> >> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
> >> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
> >> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
> >
> > Add the shifts to the #defines and remove HOST_CTRL0_FSEL(_x).  That
> > makes it match the older phy more closely.
> >
> Wouldn't it hamper the readability when shifts are used ??
> I mean if we have something like this -
> 
> phyhost |= HOST_CTRL0_FSEL(phyclk)

this one looks better to my eyes.

> >> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
> >
> > Why |= with 0?
> >
> kept this just to keep things look similar :-). will remove this line,

I would rather keep it. Compiler will optimize it out anyway and it
makes things logical, I mean, we can see that you're telling IP that
reference clock is 9600KHz.

-- 
balbi

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
  2013-01-11 12:58         ` Felipe Balbi
  (?)
@ 2013-01-11 13:48         ` Vivek Gautam
  -1 siblings, 0 replies; 34+ messages in thread
From: Vivek Gautam @ 2013-01-11 13:48 UTC (permalink / raw)
  To: balbi
  Cc: Doug Anderson, Vivek Gautam, linux-usb, yulgon.kim,
	linux-samsung-soc, Praveen Paneri, gregkh, devicetree-discuss,
	jg1.han, linux-kernel, kishon, Kukjin Kim, stern, rob.herring,
	sylvester.nawrocki

Hi Felipe,


On Fri, Jan 11, 2013 at 6:28 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Fri, Jan 11, 2013 at 06:10:48PM +0530, Vivek Gautam wrote:
>> Hi Doug,
>>
>> Sorry!!  for the delayed response.
>>
>>
>> On Thu, Dec 20, 2012 at 4:31 AM, Doug Anderson <dianders@chromium.org> wrote:
>> > Vivek,
>> >
>> > I don't really have a good 10000 foot view about how all of the USB
>> > bits fit together, but a few detail-oriented comments below.
>> >
>> >
>> > On Tue, Dec 18, 2012 at 6:43 AM, Vivek Gautam <gautam.vivek@samsung.com> wrote:
>> >> This patch adds host phy support to samsung-usbphy.c and
>> >> further adds support for samsung's exynos5250 usb-phy.
>> >>
>> >> Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
>> >> Signed-off-by: Vivek Gautam <gautam.vivek@samsung.com>
>> >> ---
>> >>  .../devicetree/bindings/usb/samsung-usbphy.txt     |   25 +-
>> >>  drivers/usb/phy/Kconfig                            |    2 +-
>> >>  drivers/usb/phy/samsung-usbphy.c                   |  465 ++++++++++++++++++--
>> >>  include/linux/usb/samsung_usb_phy.h                |   13 +
>> >>  4 files changed, 454 insertions(+), 51 deletions(-)
>> >>
>> >> diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> >> index a7b28b2..2ec5400 100644
>> >> --- a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> >> +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
>> >> @@ -1,23 +1,38 @@
>> >>  * Samsung's usb phy transceiver
>> >>
>> >> -The Samsung's phy transceiver is used for controlling usb otg phy for
>> >> -s3c-hsotg usb device controller.
>> >> +The Samsung's phy transceiver is used for controlling usb phy for
>> >> +s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
>> >> +across Samsung SOCs.
>> >>  TODO: Adding the PHY binding with controller(s) according to the under
>> >>  developement generic PHY driver.
>> >>
>> >>  Required properties:
>> >> +
>> >> +Exynos4210:
>> >>  - compatible : should be "samsung,exynos4210-usbphy"
>> >>  - reg : base physical address of the phy registers and length of memory mapped
>> >>         region.
>> >>
>> >> +Exynos5250:
>> >> +- compatible : should be "samsung,exynos5250-usbphy"
>> >> +- reg : base physical address of the phy registers and length of memory mapped
>> >> +       region.
>> >> +
>> >>  Optional properties:
>> >>  - samsung,usb-phyhandle : should point to usb-phyhandle sub-node which provides
>> >>                         binding data to enable/disable device PHY handled by
>> >> -                       PMU register.
>> >> +                       PMU register; or to configure usb2.0 phy handled by
>> >> +                       SYSREG.
>> >>
>> >>                         Required properties:
>> >>                         - compatible : should be "samsung,usbdev-phyctrl" for
>> >> -                                       DEVICE type phy.
>> >> +                                      DEVICE type phy; or
>> >> +                                      should be "samsung,usbhost-phyctrl" for
>> >> +                                      HOST type phy; or
>> >> +                                      should be "samsung,usb-phycfg" for
>> >> +                                      USB2.0 PHY_CFG.
>> >>                         - samsung,phyhandle-reg: base physical address of
>> >> -                                               PHY_CONTROL register in PMU.
>> >> +                                                PHY_CONTROL register in PMU;
>> >> +                                                or USB2.0 PHY_CFG register
>> >> +                                                in SYSREG.
>> >>  - samsung,enable-mask : should be '1'
>> >> diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
>> >> index 17ad743..13c0eaf 100644
>> >> --- a/drivers/usb/phy/Kconfig
>> >> +++ b/drivers/usb/phy/Kconfig
>> >> @@ -47,7 +47,7 @@ config USB_RCAR_PHY
>> >>
>> >>  config SAMSUNG_USBPHY
>> >>         bool "Samsung USB PHY controller Driver"
>> >> -       depends on USB_S3C_HSOTG
>> >> +       depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
>> >>         select USB_OTG_UTILS
>> >>         help
>> >>           Enable this to support Samsung USB phy controller for samsung
>> >> diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
>> >> index 4ceabe3..621348a 100644
>> >> --- a/drivers/usb/phy/samsung-usbphy.c
>> >> +++ b/drivers/usb/phy/samsung-usbphy.c
>> >> @@ -5,7 +5,8 @@
>> >>   *
>> >>   * Author: Praveen Paneri <p.paneri@samsung.com>
>> >>   *
>> >> - * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
>> >> + * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
>> >> + * OHCI-EXYNOS controllers.
>> >>   *
>> >>   * This program is free software; you can redistribute it and/or modify
>> >>   * it under the terms of the GNU General Public License version 2 as
>> >> @@ -24,7 +25,7 @@
>> >>  #include <linux/err.h>
>> >>  #include <linux/io.h>
>> >>  #include <linux/of.h>
>> >> -#include <linux/usb/otg.h>
>> >> +#include <linux/usb/samsung_usb_phy.h>
>> >>  #include <linux/platform_data/samsung-usbphy.h>
>> >>
>> >>  /* Register definitions */
>> >> @@ -56,6 +57,103 @@
>> >>  #define RSTCON_HLINK_SWRST                     (0x1 << 1)
>> >>  #define RSTCON_SWRST                           (0x1 << 0)
>> >>
>> >> +/* EXYNOS5 */
>> >> +#define EXYNOS5_PHY_HOST_CTRL0                 (0x00)
>> >> +
>> >> +#define HOST_CTRL0_PHYSWRSTALL                 (0x1 << 31)
>> >> +
>> >> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
>> >> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
>> >> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
>> >> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
>> >> +
>> >> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
>> >> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
>> >> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
>> >> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
>> >> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
>> >> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
>> >> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
>> >> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
>> >> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
>> >
>> > Add the shifts to the #defines and remove HOST_CTRL0_FSEL(_x).  That
>> > makes it match the older phy more closely.
>> >
>> Wouldn't it hamper the readability when shifts are used ??
>> I mean if we have something like this -
>>
>> phyhost |= HOST_CTRL0_FSEL(phyclk)
>
> this one looks better to my eyes.
>

Ok, better we keep this.

>> >> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
>> >
>> > Why |= with 0?
>> >
>> kept this just to keep things look similar :-). will remove this line,
>
> I would rather keep it. Compiler will optimize it out anyway and it
> makes things logical, I mean, we can see that you're telling IP that
> reference clock is 9600KHz.
>

ditto !


-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
  2013-01-11 12:40     ` Vivek Gautam
  2013-01-11 12:58         ` Felipe Balbi
@ 2013-01-12  0:50       ` Doug Anderson
  2013-01-14  5:45         ` Vivek Gautam
  1 sibling, 1 reply; 34+ messages in thread
From: Doug Anderson @ 2013-01-12  0:50 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Vivek Gautam, linux-usb, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, jg1.han,
	linux-kernel, balbi, kishon, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

Vivek,

On Fri, Jan 11, 2013 at 4:40 AM, Vivek Gautam <gautamvivek1987@gmail.com> wrote:
>>> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
>>> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
>>> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
>>> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
>>> +
>>> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
>>> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
>>> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
>>> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
>>> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
>>> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
>>> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
>>> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
>>> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
>>
>> Add the shifts to the #defines and remove HOST_CTRL0_FSEL(_x).  That
>> makes it match the older phy more closely.
>>
> Wouldn't it hamper the readability when shifts are used ??
> I mean if we have something like this -
>
> phyhost |= HOST_CTRL0_FSEL(phyclk)
>
> so, if we are using the shifts then
> phyhost |= (HOST_CTRL0_FSEL_CLKSEL_24M << HOST_CTRL0_FSEL_SHIFT)

I was actually suggesting modifying the #defines like this:

#define HOST_CTRL0_FSEL_SHIFT 16
#define HOST_CTRL0_FSEL_MASK                   (0x7 << HOST_CTRL0_FSEL_SHIFT)
#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7 << HOST_CTRL0_FSEL_SHIFT)
#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5 << HOST_CTRL0_FSEL_SHIFT)
#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4 << HOST_CTRL0_FSEL_SHIFT)
#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3 << HOST_CTRL0_FSEL_SHIFT)
#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2 << HOST_CTRL0_FSEL_SHIFT)
#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1 << HOST_CTRL0_FSEL_SHIFT)
#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0 << HOST_CTRL0_FSEL_SHIFT)

...then the code doesn't need to think about shifts, right?


>>>         if (IS_ERR(ref_clk)) {
>>>                 dev_err(sphy->dev, "Failed to get reference clock\n");
>>>                 return PTR_ERR(ref_clk);
>>>         }
>>>
>>> -       switch (clk_get_rate(ref_clk)) {
>>> -       case 12 * MHZ:
>>> -               refclk_freq = PHYCLK_CLKSEL_12M;
>>> -               break;
>>> -       case 24 * MHZ:
>>> -               refclk_freq = PHYCLK_CLKSEL_24M;
>>> -               break;
>>> -       case 48 * MHZ:
>>> -               refclk_freq = PHYCLK_CLKSEL_48M;
>>> -               break;
>>> -       default:
>>> -               if (sphy->cpu_type == TYPE_S3C64XX)
>>> -                       refclk_freq = PHYCLK_CLKSEL_48M;
>>> -               else
>>> +       if (sphy->cpu_type == TYPE_EXYNOS5250) {
>>> +               /* set clock frequency for PLL */
>>> +               switch (clk_get_rate(ref_clk)) {
>>> +               case 96 * 100000:
>>
>> nit: change to 9600 * KHZ to match; below too.
>>
> sure.
>
>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
>>
>> Why |= with 0?
>>
> kept this just to keep things look similar :-). will remove this line,

My comment was about keeping things similar.  Right now the 5250 code
has the |= and the non-5250 code doesn't.  I don't care which is
picked but the two sides of the "if" should be symmetric.

See parts of the patch below.

>>> +                       break;
>>> +               case 10 * MHZ:
>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_10M;
>>> +                       break;
>>> +               case 12 * MHZ:
>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_12M;
>>> +                       break;
>>> +               case 192 * 100000:
>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_19200K;
>>> +                       break;
>>> +               case 20 * MHZ:
>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_20M;
>>> +                       break;
>>> +               case 50 * MHZ:
>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_50M;
>>> +                       break;
>>> +               case 24 * MHZ:
>>> +               default:
>>> +                       /* default reference clock */
>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_24M;
>>> +                       break;
>>> +               }
>>> +       } else {
>>> +               switch (clk_get_rate(ref_clk)) {
>>> +               case 12 * MHZ:
>>> +                       refclk_freq = PHYCLK_CLKSEL_12M;
>>> +                       break;
>>> +               case 24 * MHZ:
>>>                         refclk_freq = PHYCLK_CLKSEL_24M;
>>> -               break;
>>> +                       break;
>>> +               case 48 * MHZ:
>>> +                       refclk_freq = PHYCLK_CLKSEL_48M;
>>> +                       break;
>>> +               default:
>>> +                       if (sphy->cpu_type == TYPE_S3C64XX)
>>> +                               refclk_freq = PHYCLK_CLKSEL_48M;
>>> +                       else
>>> +                               refclk_freq = PHYCLK_CLKSEL_24M;
>>> +                       break;
>>> +               }
>>>         }
>>>         clk_put(ref_clk);
>>>
>>>         return refclk_freq;
>>>  }

-Doug

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
  2013-01-12  0:50       ` Doug Anderson
@ 2013-01-14  5:45         ` Vivek Gautam
  2013-01-14  8:06           ` Vivek Gautam
  0 siblings, 1 reply; 34+ messages in thread
From: Vivek Gautam @ 2013-01-14  5:45 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Vivek Gautam, linux-usb, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, jg1.han,
	linux-kernel, balbi, kishon, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

Hi Doug,


On Sat, Jan 12, 2013 at 6:20 AM, Doug Anderson <dianders@chromium.org> wrote:
> Vivek,
>
> On Fri, Jan 11, 2013 at 4:40 AM, Vivek Gautam <gautamvivek1987@gmail.com> wrote:
>>>> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
>>>> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
>>>> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
>>>> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
>>>> +
>>>> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
>>>> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
>>>> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
>>>> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
>>>> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
>>>> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
>>>> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
>>>> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
>>>> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
>>>
>>> Add the shifts to the #defines and remove HOST_CTRL0_FSEL(_x).  That
>>> makes it match the older phy more closely.
>>>
>> Wouldn't it hamper the readability when shifts are used ??
>> I mean if we have something like this -
>>
>> phyhost |= HOST_CTRL0_FSEL(phyclk)
>>
>> so, if we are using the shifts then
>> phyhost |= (HOST_CTRL0_FSEL_CLKSEL_24M << HOST_CTRL0_FSEL_SHIFT)
>
> I was actually suggesting modifying the #defines like this:
>
> #define HOST_CTRL0_FSEL_SHIFT 16
> #define HOST_CTRL0_FSEL_MASK                   (0x7 << HOST_CTRL0_FSEL_SHIFT)
> #define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7 << HOST_CTRL0_FSEL_SHIFT)
> #define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5 << HOST_CTRL0_FSEL_SHIFT)
> #define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4 << HOST_CTRL0_FSEL_SHIFT)
> #define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3 << HOST_CTRL0_FSEL_SHIFT)
> #define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2 << HOST_CTRL0_FSEL_SHIFT)
> #define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1 << HOST_CTRL0_FSEL_SHIFT)
> #define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0 << HOST_CTRL0_FSEL_SHIFT)
>
> ...then the code doesn't need to think about shifts, right?
>

right right, sorry i din't get your point earlier. :-(

this way things will be similar in samsung_usbphy_get_refclk_freq()
across exynos 5 and older SoCs.

Is it fine if we don't use macro for SHIFT, earlier code also doesn't use it.
Can we just do like this ..
#define HOST_CTRL0_FSEL_MASK                       (0x7 << 16)
#define HOST_CTRL0_FSEL_CLKSEL_50M            (0x7 << 16)
#define HOST_CTRL0_FSEL_CLKSEL_24M            (0x5 << 16)
#define HOST_CTRL0_FSEL_CLKSEL_20M            (0x4 << 16)
#define HOST_CTRL0_FSEL_CLKSEL_19200K       (0x3 << 16)
#define HOST_CTRL0_FSEL_CLKSEL_12M            (0x2 << 16)
#define HOST_CTRL0_FSEL_CLKSEL_10M            (0x1 << 16)
#define HOST_CTRL0_FSEL_CLKSEL_9600K         (0x0 << 16)

>
>>>>         if (IS_ERR(ref_clk)) {
>>>>                 dev_err(sphy->dev, "Failed to get reference clock\n");
>>>>                 return PTR_ERR(ref_clk);
>>>>         }
>>>>
>>>> -       switch (clk_get_rate(ref_clk)) {
>>>> -       case 12 * MHZ:
>>>> -               refclk_freq = PHYCLK_CLKSEL_12M;
>>>> -               break;
>>>> -       case 24 * MHZ:
>>>> -               refclk_freq = PHYCLK_CLKSEL_24M;
>>>> -               break;
>>>> -       case 48 * MHZ:
>>>> -               refclk_freq = PHYCLK_CLKSEL_48M;
>>>> -               break;
>>>> -       default:
>>>> -               if (sphy->cpu_type == TYPE_S3C64XX)
>>>> -                       refclk_freq = PHYCLK_CLKSEL_48M;
>>>> -               else
>>>> +       if (sphy->cpu_type == TYPE_EXYNOS5250) {
>>>> +               /* set clock frequency for PLL */
>>>> +               switch (clk_get_rate(ref_clk)) {
>>>> +               case 96 * 100000:
>>>
>>> nit: change to 9600 * KHZ to match; below too.
>>>
>> sure.
>>
>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
>>>
>>> Why |= with 0?
>>>
>> kept this just to keep things look similar :-). will remove this line,
>
> My comment was about keeping things similar.  Right now the 5250 code
> has the |= and the non-5250 code doesn't.  I don't care which is
> picked but the two sides of the "if" should be symmetric.
>

True, it's good to maintain symmetry in the code.
I shall amend the code as suggested.

> See parts of the patch below.
>
>>>> +                       break;
>>>> +               case 10 * MHZ:
>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_10M;
>>>> +                       break;
>>>> +               case 12 * MHZ:
>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_12M;
>>>> +                       break;
>>>> +               case 192 * 100000:
>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_19200K;
>>>> +                       break;
>>>> +               case 20 * MHZ:
>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_20M;
>>>> +                       break;
>>>> +               case 50 * MHZ:
>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_50M;
>>>> +                       break;
>>>> +               case 24 * MHZ:
>>>> +               default:
>>>> +                       /* default reference clock */
>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_24M;
>>>> +                       break;
>>>> +               }
>>>> +       } else {
>>>> +               switch (clk_get_rate(ref_clk)) {
>>>> +               case 12 * MHZ:
>>>> +                       refclk_freq = PHYCLK_CLKSEL_12M;
>>>> +                       break;
>>>> +               case 24 * MHZ:
>>>>                         refclk_freq = PHYCLK_CLKSEL_24M;
>>>> -               break;
>>>> +                       break;
>>>> +               case 48 * MHZ:
>>>> +                       refclk_freq = PHYCLK_CLKSEL_48M;
>>>> +                       break;
>>>> +               default:
>>>> +                       if (sphy->cpu_type == TYPE_S3C64XX)
>>>> +                               refclk_freq = PHYCLK_CLKSEL_48M;
>>>> +                       else
>>>> +                               refclk_freq = PHYCLK_CLKSEL_24M;
>>>> +                       break;
>>>> +               }
>>>>         }
>>>>         clk_put(ref_clk);
>>>>
>>>>         return refclk_freq;
>>>>  }
>
> -Doug



-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
  2013-01-14  5:45         ` Vivek Gautam
@ 2013-01-14  8:06           ` Vivek Gautam
  2013-01-14 23:45               ` Doug Anderson
  0 siblings, 1 reply; 34+ messages in thread
From: Vivek Gautam @ 2013-01-14  8:06 UTC (permalink / raw)
  To: Doug Anderson
  Cc: Vivek Gautam, linux-usb, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, jg1.han,
	linux-kernel, balbi, kishon, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

Hi Doug,


On Mon, Jan 14, 2013 at 11:15 AM, Vivek Gautam
<gautamvivek1987@gmail.com> wrote:
> Hi Doug,
>
>
> On Sat, Jan 12, 2013 at 6:20 AM, Doug Anderson <dianders@chromium.org> wrote:
>> Vivek,
>>
>> On Fri, Jan 11, 2013 at 4:40 AM, Vivek Gautam <gautamvivek1987@gmail.com> wrote:
>>>>> +#define HOST_CTRL0_REFCLKSEL_MASK              (0x3)
>>>>> +#define HOST_CTRL0_REFCLKSEL_XTAL              (0x0 << 19)
>>>>> +#define HOST_CTRL0_REFCLKSEL_EXTL              (0x1 << 19)
>>>>> +#define HOST_CTRL0_REFCLKSEL_CLKCORE           (0x2 << 19)
>>>>> +
>>>>> +#define HOST_CTRL0_FSEL_MASK                   (0x7 << 16)
>>>>> +#define HOST_CTRL0_FSEL(_x)                    ((_x) << 16)
>>>>> +#define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7)
>>>>> +#define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5)
>>>>> +#define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4)
>>>>> +#define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3)
>>>>> +#define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2)
>>>>> +#define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1)
>>>>> +#define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0)
>>>>
>>>> Add the shifts to the #defines and remove HOST_CTRL0_FSEL(_x).  That
>>>> makes it match the older phy more closely.
>>>>
>>> Wouldn't it hamper the readability when shifts are used ??
>>> I mean if we have something like this -
>>>
>>> phyhost |= HOST_CTRL0_FSEL(phyclk)
>>>
>>> so, if we are using the shifts then
>>> phyhost |= (HOST_CTRL0_FSEL_CLKSEL_24M << HOST_CTRL0_FSEL_SHIFT)
>>
>> I was actually suggesting modifying the #defines like this:
>>
>> #define HOST_CTRL0_FSEL_SHIFT 16
>> #define HOST_CTRL0_FSEL_MASK                   (0x7 << HOST_CTRL0_FSEL_SHIFT)
>> #define HOST_CTRL0_FSEL_CLKSEL_50M             (0x7 << HOST_CTRL0_FSEL_SHIFT)
>> #define HOST_CTRL0_FSEL_CLKSEL_24M             (0x5 << HOST_CTRL0_FSEL_SHIFT)
>> #define HOST_CTRL0_FSEL_CLKSEL_20M             (0x4 << HOST_CTRL0_FSEL_SHIFT)
>> #define HOST_CTRL0_FSEL_CLKSEL_19200K          (0x3 << HOST_CTRL0_FSEL_SHIFT)
>> #define HOST_CTRL0_FSEL_CLKSEL_12M             (0x2 << HOST_CTRL0_FSEL_SHIFT)
>> #define HOST_CTRL0_FSEL_CLKSEL_10M             (0x1 << HOST_CTRL0_FSEL_SHIFT)
>> #define HOST_CTRL0_FSEL_CLKSEL_9600K           (0x0 << HOST_CTRL0_FSEL_SHIFT)
>>
>> ...then the code doesn't need to think about shifts, right?
>>
>
> right right, sorry i din't get your point earlier. :-(
>
> this way things will be similar in samsung_usbphy_get_refclk_freq()
> across exynos 5 and older SoCs.
>
> Is it fine if we don't use macro for SHIFT, earlier code also doesn't use it.
> Can we just do like this ..
> #define HOST_CTRL0_FSEL_MASK                       (0x7 << 16)
> #define HOST_CTRL0_FSEL_CLKSEL_50M            (0x7 << 16)
> #define HOST_CTRL0_FSEL_CLKSEL_24M            (0x5 << 16)
> #define HOST_CTRL0_FSEL_CLKSEL_20M            (0x4 << 16)
> #define HOST_CTRL0_FSEL_CLKSEL_19200K       (0x3 << 16)
> #define HOST_CTRL0_FSEL_CLKSEL_12M            (0x2 << 16)
> #define HOST_CTRL0_FSEL_CLKSEL_10M            (0x1 << 16)
> #define HOST_CTRL0_FSEL_CLKSEL_9600K         (0x0 << 16)
>

Actually missed one thing here, this "HOST_CTRL0_FSEL_CLKSEL_XX" is
being used by
HOST/OTG blocks to prepare reference clock, that's the reason we kept
            #define HOST_CTRL0_FSEL(_x)                  ((_x) << 16)
and       #define OTG_SYS_FSEL(_x)                       ((_x) << 4)
where (_x) is the reference clock returned from
samsung_usbphy_get_refclk_freq().

So in order to avoid confusion we can change the macro names only and
keep something like
#define HOST_CTRL0_FSEL_MASK                       (0x7 << 16)
#define HOST_CTRL0_FSEL(_x)                             ((_x) << 16)

#define FSEL_CLKSEL_50M                                   (0x7)
#define FSEL_CLKSEL_24M                                   (0x5)
#define FSEL_CLKSEL_20M                                   (0x4)
#define FSEL_CLKSEL_19200K                              (0x3)
#define FSEL_CLKSEL_12M                                   (0x2)
#define FSEL_CLKSEL_10M                                   (0x1)
#define FSEL_CLKSEL_9600K                                (0x0)

...

#define OTG_SYS_FSEL_MASK                             (0x7 << 4)
#define OTG_SYS_FSEL(_x)                                   ((_x) << 4)


>>
>>>>>         if (IS_ERR(ref_clk)) {
>>>>>                 dev_err(sphy->dev, "Failed to get reference clock\n");
>>>>>                 return PTR_ERR(ref_clk);
>>>>>         }
>>>>>
>>>>> -       switch (clk_get_rate(ref_clk)) {
>>>>> -       case 12 * MHZ:
>>>>> -               refclk_freq = PHYCLK_CLKSEL_12M;
>>>>> -               break;
>>>>> -       case 24 * MHZ:
>>>>> -               refclk_freq = PHYCLK_CLKSEL_24M;
>>>>> -               break;
>>>>> -       case 48 * MHZ:
>>>>> -               refclk_freq = PHYCLK_CLKSEL_48M;
>>>>> -               break;
>>>>> -       default:
>>>>> -               if (sphy->cpu_type == TYPE_S3C64XX)
>>>>> -                       refclk_freq = PHYCLK_CLKSEL_48M;
>>>>> -               else
>>>>> +       if (sphy->cpu_type == TYPE_EXYNOS5250) {
>>>>> +               /* set clock frequency for PLL */
>>>>> +               switch (clk_get_rate(ref_clk)) {
>>>>> +               case 96 * 100000:
>>>>
>>>> nit: change to 9600 * KHZ to match; below too.
>>>>
>>> sure.
>>>
>>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_9600K;
>>>>
>>>> Why |= with 0?
>>>>
>>> kept this just to keep things look similar :-). will remove this line,
>>
>> My comment was about keeping things similar.  Right now the 5250 code
>> has the |= and the non-5250 code doesn't.  I don't care which is
>> picked but the two sides of the "if" should be symmetric.
>>
>
> True, it's good to maintain symmetry in the code.
> I shall amend the code as suggested.
>

And to maintain symmetry we can avoid putting |=
since refclk_freq is anyways initialized to 0, so this wouldn't make
any difference.
right ?

>> See parts of the patch below.
>>
>>>>> +                       break;
>>>>> +               case 10 * MHZ:
>>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_10M;
>>>>> +                       break;

so we can change this to something like

                           case 10 * MHZ:
                                     refclk_freq = FSEL_CLKSEL_10M;
                                     break;
and so on.
will this be fine ?

>>>>> +               case 12 * MHZ:
>>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_12M;
>>>>> +                       break;
>>>>> +               case 192 * 100000:
>>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_19200K;
>>>>> +                       break;
>>>>> +               case 20 * MHZ:
>>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_20M;
>>>>> +                       break;
>>>>> +               case 50 * MHZ:
>>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_50M;
>>>>> +                       break;
>>>>> +               case 24 * MHZ:
>>>>> +               default:
>>>>> +                       /* default reference clock */
>>>>> +                       refclk_freq |= HOST_CTRL0_FSEL_CLKSEL_24M;
>>>>> +                       break;
>>>>> +               }
>>>>> +       } else {
>>>>> +               switch (clk_get_rate(ref_clk)) {
>>>>> +               case 12 * MHZ:
>>>>> +                       refclk_freq = PHYCLK_CLKSEL_12M;
>>>>> +                       break;
>>>>> +               case 24 * MHZ:
>>>>>                         refclk_freq = PHYCLK_CLKSEL_24M;
>>>>> -               break;
>>>>> +                       break;
>>>>> +               case 48 * MHZ:
>>>>> +                       refclk_freq = PHYCLK_CLKSEL_48M;
>>>>> +                       break;
>>>>> +               default:
>>>>> +                       if (sphy->cpu_type == TYPE_S3C64XX)
>>>>> +                               refclk_freq = PHYCLK_CLKSEL_48M;
>>>>> +                       else
>>>>> +                               refclk_freq = PHYCLK_CLKSEL_24M;
>>>>> +                       break;
>>>>> +               }
>>>>>         }
>>>>>         clk_put(ref_clk);
>>>>>
>>>>>         return refclk_freq;
>>>>>  }
>>


-- 
Thanks & Regards
Vivek

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
@ 2013-01-14 23:45               ` Doug Anderson
  0 siblings, 0 replies; 34+ messages in thread
From: Doug Anderson @ 2013-01-14 23:45 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: Vivek Gautam, linux-usb, yulgon.kim, linux-samsung-soc,
	Praveen Paneri, gregkh, devicetree-discuss, jg1.han,
	linux-kernel, balbi, kishon, Kukjin Kim, Alan Stern, Rob Herring,
	Sylwester Nawrocki

Vivek,


On Mon, Jan 14, 2013 at 12:06 AM, Vivek Gautam
<gautamvivek1987@gmail.com> wrote:
>> Is it fine if we don't use macro for SHIFT, earlier code also doesn't use it.
>> Can we just do like this ..
>> #define HOST_CTRL0_FSEL_MASK                       (0x7 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_50M            (0x7 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_24M            (0x5 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_20M            (0x4 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_19200K       (0x3 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_12M            (0x2 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_10M            (0x1 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_9600K         (0x0 << 16)

I don't have a problem with just putting the << 16 there...

> Actually missed one thing here, this "HOST_CTRL0_FSEL_CLKSEL_XX" is
> being used by
> HOST/OTG blocks to prepare reference clock, that's the reason we kept
>             #define HOST_CTRL0_FSEL(_x)                  ((_x) << 16)
> and       #define OTG_SYS_FSEL(_x)                       ((_x) << 4)
> where (_x) is the reference clock returned from
> samsung_usbphy_get_refclk_freq().

I feel like samsung_usbphy_get_refclk_freq() is supposed to be
returning an already shifted value.  ...at least that's how it appears
to work with existing code.  Why does it feel like that?  ...because
with existing code we have:

#define PHYCLK_CLKSEL_MASK (0x3 << 0)
#define PHYCLK_CLKSEL_48M (0x0 << 0)
#define PHYCLK_CLKSEL_12M (0x2 << 0)
#define PHYCLK_CLKSEL_24M (0x3 << 0)

Those #defines are what are returned by
samsung_usbphy_get_refclk_freq().  The fact that the "<< 0" is there
implies (to me) that the existing function would return shifted values
if it were applicable.

For exynos you are having the same function return things like:

#define FSEL_CLKSEL_50M (0x7)
#define FSEL_CLKSEL_24M (0x5)
#define FSEL_CLKSEL_20M (0x4)

...to me that means that the exynos code is returning unshifted values.


If you say that samsung_usbphy_get_refclk_freq() is in charge of
returning shifted values then you no longer need the HOST_CTRL0_FSEL()
macro.


In any case, I will defer to whatever Felipe thinks is best here (if
he has an opinion on it).  I am only pointing out that the exynos code
and existing code seem to be specifying things differently.  That's
weird to me.


> so we can change this to something like
>
>                            case 10 * MHZ:
>                                      refclk_freq = FSEL_CLKSEL_10M;
>                                      break;
> and so on.
> will this be fine ?

Seems good to me.


-Doug

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

* Re: [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver
@ 2013-01-14 23:45               ` Doug Anderson
  0 siblings, 0 replies; 34+ messages in thread
From: Doug Anderson @ 2013-01-14 23:45 UTC (permalink / raw)
  To: Vivek Gautam
  Cc: jg1.han-Sze3O3UU22JBDgjK7y7TUQ,
	yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Praveen Paneri,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, balbi-l0cyMroinI0,
	kishon-l0cyMroinI0, Kukjin Kim, Alan Stern, Vivek Gautam,
	Sylwester Nawrocki, Rob Herring

Vivek,


On Mon, Jan 14, 2013 at 12:06 AM, Vivek Gautam
<gautamvivek1987-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> Is it fine if we don't use macro for SHIFT, earlier code also doesn't use it.
>> Can we just do like this ..
>> #define HOST_CTRL0_FSEL_MASK                       (0x7 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_50M            (0x7 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_24M            (0x5 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_20M            (0x4 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_19200K       (0x3 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_12M            (0x2 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_10M            (0x1 << 16)
>> #define HOST_CTRL0_FSEL_CLKSEL_9600K         (0x0 << 16)

I don't have a problem with just putting the << 16 there...

> Actually missed one thing here, this "HOST_CTRL0_FSEL_CLKSEL_XX" is
> being used by
> HOST/OTG blocks to prepare reference clock, that's the reason we kept
>             #define HOST_CTRL0_FSEL(_x)                  ((_x) << 16)
> and       #define OTG_SYS_FSEL(_x)                       ((_x) << 4)
> where (_x) is the reference clock returned from
> samsung_usbphy_get_refclk_freq().

I feel like samsung_usbphy_get_refclk_freq() is supposed to be
returning an already shifted value.  ...at least that's how it appears
to work with existing code.  Why does it feel like that?  ...because
with existing code we have:

#define PHYCLK_CLKSEL_MASK (0x3 << 0)
#define PHYCLK_CLKSEL_48M (0x0 << 0)
#define PHYCLK_CLKSEL_12M (0x2 << 0)
#define PHYCLK_CLKSEL_24M (0x3 << 0)

Those #defines are what are returned by
samsung_usbphy_get_refclk_freq().  The fact that the "<< 0" is there
implies (to me) that the existing function would return shifted values
if it were applicable.

For exynos you are having the same function return things like:

#define FSEL_CLKSEL_50M (0x7)
#define FSEL_CLKSEL_24M (0x5)
#define FSEL_CLKSEL_20M (0x4)

...to me that means that the exynos code is returning unshifted values.


If you say that samsung_usbphy_get_refclk_freq() is in charge of
returning shifted values then you no longer need the HOST_CTRL0_FSEL()
macro.


In any case, I will defer to whatever Felipe thinks is best here (if
he has an opinion on it).  I am only pointing out that the exynos code
and existing code seem to be specifying things differently.  That's
weird to me.


> so we can change this to something like
>
>                            case 10 * MHZ:
>                                      refclk_freq = FSEL_CLKSEL_10M;
>                                      break;
> and so on.
> will this be fine ?

Seems good to me.


-Doug

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

end of thread, other threads:[~2013-01-14 23:50 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-18 14:43 [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250 Vivek Gautam
2012-12-18 14:43 ` [PATCH v5 1/4] ARM: EXYNOS: Update & move usb-phy types to generic include layer Vivek Gautam
2012-12-19  5:38   ` Vivek Gautam
2012-12-19  5:38     ` Vivek Gautam
2012-12-19 21:48   ` Doug Anderson
2012-12-19 21:48     ` Doug Anderson
2012-12-20  5:51     ` Vivek Gautam
2012-12-20 16:53       ` Doug Anderson
2012-12-20 19:03         ` Vivek Gautam
2012-12-20 19:03           ` Vivek Gautam
2012-12-18 14:43 ` [PATCH v5 2/4] usb: phy: samsung: Add host phy support to samsung-phy driver Vivek Gautam
2012-12-19  5:40   ` Vivek Gautam
2012-12-19  5:40     ` Vivek Gautam
2012-12-19 23:01   ` Doug Anderson
2013-01-11 12:40     ` Vivek Gautam
2013-01-11 12:58       ` Felipe Balbi
2013-01-11 12:58         ` Felipe Balbi
2013-01-11 13:48         ` Vivek Gautam
2013-01-12  0:50       ` Doug Anderson
2013-01-14  5:45         ` Vivek Gautam
2013-01-14  8:06           ` Vivek Gautam
2013-01-14 23:45             ` Doug Anderson
2013-01-14 23:45               ` Doug Anderson
2012-12-18 14:43 ` [PATCH v5 3/4] USB: ehci-s5p: Add phy driver support Vivek Gautam
2012-12-19  5:41   ` Vivek Gautam
2012-12-19 23:30   ` Doug Anderson
2012-12-20  6:37     ` Vivek Gautam
2012-12-20 17:51       ` Doug Anderson
2012-12-20 17:51         ` Doug Anderson
2012-12-18 14:43 ` [PATCH v5 4/4] USB: ohci-exynos: " Vivek Gautam
2012-12-19  5:41   ` Vivek Gautam
2012-12-19  5:41     ` Vivek Gautam
2012-12-19  5:37 ` [PATCH v5 0/4] Adding usb2.0 host-phy support for exynos5250 Vivek Gautam
2012-12-19  5:37   ` Vivek Gautam

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.