mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kishon Vijay Abraham I <kishon@ti.com>
To: <gregkh@linuxfoundation.org>
Cc: <kishon@ti.com>, <linux-kernel@vger.kernel.org>
Subject: [PATCH 06/28] phy: phy-samsung-usb2: Change phy power on/power off sequence
Date: Tue, 22 Jul 2014 16:26:29 +0530	[thread overview]
Message-ID: <1406026611-30493-7-git-send-email-kishon@ti.com> (raw)
In-Reply-To: <1406026611-30493-1-git-send-email-kishon@ti.com>

From: Kamil Debski <k.debski@samsung.com>

The Exynos4412 USB 2.0 PHY hardware differs from the description provided
in the documentation. Some register bits have different function. This
patch fixes the defines of register bits and changes the way how phys are
powered on and off.

Signed-off-by: Kamil Debski <k.debski@samsung.com>
Tested-by: Daniel Drake <drake@endlessm.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/phy/phy-exynos4x12-usb2.c |  112 +++++++++++++++++++++++++------------
 drivers/phy/phy-exynos5250-usb2.c |    2 -
 drivers/phy/phy-samsung-usb2.h    |    3 +-
 3 files changed, 77 insertions(+), 40 deletions(-)

diff --git a/drivers/phy/phy-exynos4x12-usb2.c b/drivers/phy/phy-exynos4x12-usb2.c
index d92a7cc..63134d8 100644
--- a/drivers/phy/phy-exynos4x12-usb2.c
+++ b/drivers/phy/phy-exynos4x12-usb2.c
@@ -86,13 +86,23 @@
 #define EXYNOS_4x12_URSTCON_OTG_HLINK		BIT(1)
 #define EXYNOS_4x12_URSTCON_OTG_PHYLINK		BIT(2)
 #define EXYNOS_4x12_URSTCON_HOST_PHY		BIT(3)
+/* The following bit defines are presented in the
+ * order taken from the Exynos4412 reference manual.
+ *
+ * During experiments with the hardware and debugging
+ * it was determined that the hardware behaves contrary
+ * to the manual.
+ *
+ * The following bit values were chaned accordingly to the
+ * results of real hardware experiments.
+ */
 #define EXYNOS_4x12_URSTCON_PHY1		BIT(4)
-#define EXYNOS_4x12_URSTCON_HSIC0		BIT(5)
-#define EXYNOS_4x12_URSTCON_HSIC1		BIT(6)
+#define EXYNOS_4x12_URSTCON_HSIC0		BIT(6)
+#define EXYNOS_4x12_URSTCON_HSIC1		BIT(5)
 #define EXYNOS_4x12_URSTCON_HOST_LINK_ALL	BIT(7)
-#define EXYNOS_4x12_URSTCON_HOST_LINK_P0	BIT(8)
+#define EXYNOS_4x12_URSTCON_HOST_LINK_P0	BIT(10)
 #define EXYNOS_4x12_URSTCON_HOST_LINK_P1	BIT(9)
-#define EXYNOS_4x12_URSTCON_HOST_LINK_P2	BIT(10)
+#define EXYNOS_4x12_URSTCON_HOST_LINK_P2	BIT(8)
 
 /* Isolation, configured in the power management unit */
 #define EXYNOS_4x12_USB_ISOL_OFFSET		0x704
@@ -188,6 +198,7 @@ static void exynos4x12_setup_clk(struct samsung_usb2_phy_instance *inst)
 	clk = readl(drv->reg_phy + EXYNOS_4x12_UPHYCLK);
 	clk &= ~EXYNOS_4x12_UPHYCLK_PHYFSEL_MASK;
 	clk |= drv->ref_reg_val << EXYNOS_4x12_UPHYCLK_PHYFSEL_OFFSET;
+	clk |= EXYNOS_4x12_UPHYCLK_PHY1_COMMON_ON;
 	writel(clk, drv->reg_phy + EXYNOS_4x12_UPHYCLK);
 }
 
@@ -198,27 +209,22 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
 	u32 phypwr = 0;
 	u32 rst;
 	u32 pwr;
-	u32 mode = 0;
-	u32 switch_mode = 0;
 
 	switch (inst->cfg->id) {
 	case EXYNOS4x12_DEVICE:
 		phypwr =	EXYNOS_4x12_UPHYPWR_PHY0;
 		rstbits =	EXYNOS_4x12_URSTCON_PHY0;
-		mode =		EXYNOS_4x12_MODE_SWITCH_DEVICE;
-		switch_mode =	1;
 		break;
 	case EXYNOS4x12_HOST:
 		phypwr =	EXYNOS_4x12_UPHYPWR_PHY1;
-		rstbits =	EXYNOS_4x12_URSTCON_HOST_PHY;
-		mode =		EXYNOS_4x12_MODE_SWITCH_HOST;
-		switch_mode =	1;
+		rstbits =	EXYNOS_4x12_URSTCON_HOST_PHY |
+				EXYNOS_4x12_URSTCON_PHY1 |
+				EXYNOS_4x12_URSTCON_HOST_LINK_P0;
 		break;
 	case EXYNOS4x12_HSIC0:
 		phypwr =	EXYNOS_4x12_UPHYPWR_HSIC0;
-		rstbits =	EXYNOS_4x12_URSTCON_HSIC1 |
-				EXYNOS_4x12_URSTCON_HOST_LINK_P0 |
-				EXYNOS_4x12_URSTCON_HOST_PHY;
+		rstbits =	EXYNOS_4x12_URSTCON_HSIC0 |
+				EXYNOS_4x12_URSTCON_HOST_LINK_P1;
 		break;
 	case EXYNOS4x12_HSIC1:
 		phypwr =	EXYNOS_4x12_UPHYPWR_HSIC1;
@@ -228,11 +234,6 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
 	};
 
 	if (on) {
-		if (switch_mode)
-			regmap_update_bits(drv->reg_sys,
-					   EXYNOS_4x12_MODE_SWITCH_OFFSET,
-					   EXYNOS_4x12_MODE_SWITCH_MASK, mode);
-
 		pwr = readl(drv->reg_phy + EXYNOS_4x12_UPHYPWR);
 		pwr &= ~phypwr;
 		writel(pwr, drv->reg_phy + EXYNOS_4x12_UPHYPWR);
@@ -253,41 +254,78 @@ static void exynos4x12_phy_pwr(struct samsung_usb2_phy_instance *inst, bool on)
 	}
 }
 
-static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst)
+static void exynos4x12_power_on_int(struct samsung_usb2_phy_instance *inst)
 {
-	struct samsung_usb2_phy_driver *drv = inst->drv;
+	if (inst->int_cnt++ > 0)
+		return;
 
-	inst->enabled = 1;
 	exynos4x12_setup_clk(inst);
-	exynos4x12_phy_pwr(inst, 1);
 	exynos4x12_isol(inst, 0);
+	exynos4x12_phy_pwr(inst, 1);
+}
+
+static int exynos4x12_power_on(struct samsung_usb2_phy_instance *inst)
+{
+	struct samsung_usb2_phy_driver *drv = inst->drv;
+
+	if (inst->ext_cnt++ > 0)
+		return 0;
 
-	/* Power on the device, as it is necessary for HSIC to work */
-	if (inst->cfg->id == EXYNOS4x12_HSIC0) {
-		struct samsung_usb2_phy_instance *device =
-					&drv->instances[EXYNOS4x12_DEVICE];
-		exynos4x12_phy_pwr(device, 1);
-		exynos4x12_isol(device, 0);
+	if (inst->cfg->id == EXYNOS4x12_HOST) {
+		regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
+						EXYNOS_4x12_MODE_SWITCH_MASK,
+						EXYNOS_4x12_MODE_SWITCH_HOST);
+		exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]);
 	}
 
+	if (inst->cfg->id == EXYNOS4x12_DEVICE)
+		regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
+						EXYNOS_4x12_MODE_SWITCH_MASK,
+						EXYNOS_4x12_MODE_SWITCH_DEVICE);
+
+	if (inst->cfg->id == EXYNOS4x12_HSIC0 ||
+		inst->cfg->id == EXYNOS4x12_HSIC1) {
+		exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_DEVICE]);
+		exynos4x12_power_on_int(&drv->instances[EXYNOS4x12_HOST]);
+	}
+
+	exynos4x12_power_on_int(inst);
+
 	return 0;
 }
 
-static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst)
+static void exynos4x12_power_off_int(struct samsung_usb2_phy_instance *inst)
 {
-	struct samsung_usb2_phy_driver *drv = inst->drv;
-	struct samsung_usb2_phy_instance *device =
-					&drv->instances[EXYNOS4x12_DEVICE];
+	if (inst->int_cnt-- > 1)
+		return;
 
-	inst->enabled = 0;
 	exynos4x12_isol(inst, 1);
 	exynos4x12_phy_pwr(inst, 0);
+}
 
-	if (inst->cfg->id == EXYNOS4x12_HSIC0 && !device->enabled) {
-		exynos4x12_isol(device, 1);
-		exynos4x12_phy_pwr(device, 0);
+static int exynos4x12_power_off(struct samsung_usb2_phy_instance *inst)
+{
+	struct samsung_usb2_phy_driver *drv = inst->drv;
+
+	if (inst->ext_cnt-- > 1)
+		return 0;
+
+	if (inst->cfg->id == EXYNOS4x12_DEVICE)
+		regmap_update_bits(drv->reg_sys, EXYNOS_4x12_MODE_SWITCH_OFFSET,
+						EXYNOS_4x12_MODE_SWITCH_MASK,
+						EXYNOS_4x12_MODE_SWITCH_HOST);
+
+	if (inst->cfg->id == EXYNOS4x12_HOST)
+		exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]);
+
+	if (inst->cfg->id == EXYNOS4x12_HSIC0 ||
+		inst->cfg->id == EXYNOS4x12_HSIC1) {
+		exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_DEVICE]);
+		exynos4x12_power_off_int(&drv->instances[EXYNOS4x12_HOST]);
 	}
 
+	exynos4x12_power_off_int(inst);
+
 	return 0;
 }
 
diff --git a/drivers/phy/phy-exynos5250-usb2.c b/drivers/phy/phy-exynos5250-usb2.c
index 94179af..1c139aa 100644
--- a/drivers/phy/phy-exynos5250-usb2.c
+++ b/drivers/phy/phy-exynos5250-usb2.c
@@ -318,7 +318,6 @@ static int exynos5250_power_on(struct samsung_usb2_phy_instance *inst)
 
 		break;
 	}
-	inst->enabled = 1;
 	exynos5250_isol(inst, 0);
 
 	return 0;
@@ -331,7 +330,6 @@ static int exynos5250_power_off(struct samsung_usb2_phy_instance *inst)
 	u32 otg;
 	u32 hsic;
 
-	inst->enabled = 0;
 	exynos5250_isol(inst, 1);
 
 	switch (inst->cfg->id) {
diff --git a/drivers/phy/phy-samsung-usb2.h b/drivers/phy/phy-samsung-usb2.h
index 45b3170..9188478 100644
--- a/drivers/phy/phy-samsung-usb2.h
+++ b/drivers/phy/phy-samsung-usb2.h
@@ -29,7 +29,8 @@ struct samsung_usb2_phy_instance {
 	const struct samsung_usb2_common_phy *cfg;
 	struct phy *phy;
 	struct samsung_usb2_phy_driver *drv;
-	bool enabled;
+	int int_cnt;
+	int ext_cnt;
 };
 
 struct samsung_usb2_phy_driver {
-- 
1.7.9.5


  parent reply	other threads:[~2014-07-22 10:57 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-22 10:56 [GIT PULL 00/28] PHY: for 3.17 Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 01/28] phy: miphy365x: Add MiPHY365x header file for DT x Driver defines Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 02/28] phy: exynos-dp-video: Use PTR_ERR_OR_ZERO Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 03/28] phy: exynos-mipi-video: " Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 04/28] phy: sun4i-usb: " Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 05/28] phy: exynos5-usbdrd: Make local functions static Kishon Vijay Abraham I
2014-07-22 10:56 ` Kishon Vijay Abraham I [this message]
2014-07-22 10:56 ` [PATCH 07/28] phy: phy-omap-pipe3: Add support for PCIe PHY Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 08/28] phy: pipe3: insert delay to enumerate in GEN2 mode Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 09/28] Documentation: Document Hisilicon hix5hd2 sata PHY Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 10/28] phy: add hix5hd2-sata-phy driver Kishon Vijay Abraham I
2014-07-24 11:27   ` Paul Bolle
2014-07-22 10:56 ` [PATCH 11/28] drivers: phy: exynos-usb2: add support for Exynos 3250 Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 12/28] phy: core: Support regulator supply for PHY power Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 13/28] phy: core: Add phy-supply to DT binding documentation Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 14/28] phy: Kconfig: Re-organize Exynos USB 2.0 PHY configs Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 15/28] phy: Kconfig: Update config for Exynos USB DRD Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 16/28] phy: qcom: Add driver for QCOM APQ8064 SATA PHY Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 17/28] phy: qcom: Add APQ8064 SATA PHY device tree bindings Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 18/28] phy: Remove ARCH_KIRKWOOD dependency Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 19/28] phy: add a driver for the Berlin SATA PHY Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 20/28] Documentation: bindings: add " Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 21/28] phy: core: Fix of_phy_provider_lookup to return PHY provider for sub node Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 22/28] phy: core: Let node ptr of PHY point to PHY and not of PHY provider Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 23/28] phy: qcom-apq8064: fix possible timeout without check Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 24/28] phy: qcom: Add driver for QCOM IPQ806x SATA PHY Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 25/28] phy: qcom: Add device tree bindings for " Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 26/28] phy: miphy365x: Add Device Tree bindings for the MiPHY365x Kishon Vijay Abraham I
2014-07-22 10:56 ` [PATCH 27/28] phy: miphy365x: Provide support for the MiPHY356x Generic PHY Kishon Vijay Abraham I
2014-07-24 10:36   ` Paul Bolle
2014-07-22 10:56 ` [PATCH 28/28] phy: miphy365x: Represent each PHY channel as a DT subnode Kishon Vijay Abraham I
2014-07-22 23:33 ` [GIT PULL 00/28] PHY: for 3.17 Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1406026611-30493-7-git-send-email-kishon@ti.com \
    --to=kishon@ti.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®