usb: ehci-s5p: Add support for HSIC to the Exynos 4x12 SoC family
authorKamil Debski <k.debski@samsung.com>
Tue, 2 Jul 2013 14:14:44 +0000 (16:14 +0200)
committerChanho Park <chanho61.park@samsung.com>
Tue, 18 Nov 2014 02:43:20 +0000 (11:43 +0900)
Add support for HSIC to the Exynos 4x12 SoC family.

Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
drivers/usb/phy/phy-samsung-usb.h
drivers/usb/phy/phy-samsung-usb2.c

index 585d12f..3614a0f 100644 (file)
 #define PHYPWR_FORCE_SUSPEND                   (0x1 << 1)
 /* For Exynos4 */
 #define PHYPWR_NORMAL_MASK_PHY0                        (0x39 << 0)
+#define PHYPWR_NORMAL_MASK_PHY1                        (0x7 << 6)
+#define PHYPWR_NORMAL_MASK_HSIC0_4210          (0x3 << 9)
+#define PHYPWR_NORMAL_MASK_HSIC1_4210          (0x3 << 11)
+#define PHYPWR_NORMAL_MASK_HSIC0_4X12          (0x7 << 9)
+#define PHYPWR_NORMAL_MASK_HSIC1_4X12          (0x7 << 12)
 #define PHYPWR_SLEEP_PHY0                      (0x1 << 5)
 
 #define SAMSUNG_PHYCLK                         (0x04)
 #define RSTCON_PHYLINK_SWRST                   (0x1 << 2)
 #define RSTCON_HLINK_SWRST                     (0x1 << 1)
 #define RSTCON_SWRST                           (0x1 << 0)
+/* This following values will also reset some fields marked as "reserved"
+   The question is... was it intentional?                                 */
+#define RSTCON_SWRST_HOST_4X12                 (0xff << 3)
+#define RSTCON_SWRST_HOST_4210                 (0x7f << 3)
+
+#define EXYNOS4_PHY1CON                                (0x34)
+#define PHY1CON_FPENABLEN                      (0x1 << 0)
 
 /* EXYNOS5 */
 #define EXYNOS5_PHY_HOST_CTRL0                 (0x00)
 #define KHZ (1000)
 #endif
 
-#define EXYNOS_USBHOST_PHY_CTRL_OFFSET         (0x4)
+#define EXYNOS5_USBHOST_PHY_CTRL_OFFSET                (0x4)
+#define EXYNOS4x12_HSIC1_PHY_CTRL_OFFSET       (0x4)
+#define EXYNOS4x12_HSIC2_PHY_CTRL_OFFSET       (0x8)
 #define S3C64XX_USBPHY_ENABLE                  (0x1 << 16)
 #define EXYNOS_USBPHY_ENABLE                   (0x1 << 0)
 #define EXYNOS_USB20PHY_CFG_HOST_LINK          (0x1 << 0)
index 03180c0..cebf34b 100644 (file)
@@ -68,6 +68,7 @@ static void samsung_exynos5_usb2phy_enable(struct samsung_usbphy *sphy)
         * the last consumer to disable it.
         */
 
+
        atomic_inc(&sphy->phy_usage);
 
        if (exynos5_phyhost_is_on(regs)) {
@@ -164,22 +165,41 @@ static void samsung_usb2phy_enable(struct samsung_usbphy *sphy)
        u32 phypwr;
        u32 phyclk;
        u32 rstcon;
+       u32 rstbits;
 
        /* set clock frequency for PLL */
        phyclk = sphy->ref_clk_freq;
        phypwr = readl(regs + SAMSUNG_PHYPWR);
        rstcon = readl(regs + SAMSUNG_RSTCON);
+       rstbits = 0;
 
        switch (sphy->drv_data->cpu_type) {
        case TYPE_S3C64XX:
                phyclk &= ~PHYCLK_COMMON_ON_N;
                phypwr &= ~PHYPWR_NORMAL_MASK;
-               rstcon |= RSTCON_SWRST;
+               rstbits = RSTCON_SWRST;
                break;
        case TYPE_EXYNOS4210:
-       case TYPE_EXYNOS4X12:
                phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
-               rstcon |= RSTCON_SWRST;
+               rstbits = RSTCON_SWRST;
+               break;
+       case TYPE_EXYNOS4X12:
+               if (sphy->phy_type == USB_PHY_TYPE_HOST) {
+                       phypwr &= ~PHYPWR_NORMAL_MASK_PHY1;
+                       phypwr &= ~PHYPWR_NORMAL_MASK_HSIC0_4X12;
+                       phypwr &= ~PHYPWR_NORMAL_MASK_HSIC1_4X12;
+                       rstbits = RSTCON_SWRST_HOST_4X12;
+                       /* The following register (0x125b0034) is not documented
+                        * for Exynos4412, however it is documented for S5PC210.
+                        * There is means that is should not be used, but hey,
+                        * who knows? */
+                       writel(PHY1CON_FPENABLEN, regs + EXYNOS4_PHY1CON);
+               } else {
+                       phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
+                       rstbits |= RSTCON_SWRST;
+               }
+               break;
+
        default:
                break;
        }
@@ -188,9 +208,11 @@ static void samsung_usb2phy_enable(struct samsung_usbphy *sphy)
        /* Configure PHY0 for normal operation*/
        writel(phypwr, regs + SAMSUNG_PHYPWR);
        /* reset all ports of PHY and Link */
+       /* Keep track of which bits are reset with rstbits. */
+       rstcon |= rstbits;
        writel(rstcon, regs + SAMSUNG_RSTCON);
        udelay(10);
-       rstcon &= ~RSTCON_SWRST;
+       rstcon &= ~rstbits;
        writel(rstcon, regs + SAMSUNG_RSTCON);
 }
 
@@ -241,8 +263,17 @@ static void samsung_usb2phy_disable(struct samsung_usbphy *sphy)
                phypwr |= PHYPWR_NORMAL_MASK;
                break;
        case TYPE_EXYNOS4210:
-       case TYPE_EXYNOS4X12:
                phypwr |= PHYPWR_NORMAL_MASK_PHY0;
+               break;
+       case TYPE_EXYNOS4X12:
+               if (sphy->phy_type == USB_PHY_TYPE_HOST) {
+                       phypwr |= PHYPWR_NORMAL_MASK_PHY1;
+                       phypwr |= PHYPWR_NORMAL_MASK_HSIC0_4X12;
+                       phypwr |= PHYPWR_NORMAL_MASK_HSIC1_4X12;
+               } else {
+                       phypwr |= PHYPWR_NORMAL_MASK_PHY0;
+               }
+               break;
        default:
                break;
        }
@@ -457,6 +488,7 @@ static const struct samsung_usbphy_drvdata usb2phy_exynos4x12 = {
        .cpu_type               = TYPE_EXYNOS4X12,
        .devphy_en_mask         = EXYNOS_USBPHY_ENABLE,
        .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
+       .hostphy_reg_offset     = EXYNOS4x12_HSIC1_PHY_CTRL_OFFSET,
        .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
        .set_isolation          = samsung_usbphy_set_isolation_4210,
        .phy_enable             = samsung_usb2phy_enable,
@@ -466,7 +498,7 @@ static const struct samsung_usbphy_drvdata usb2phy_exynos4x12 = {
 static struct samsung_usbphy_drvdata usb2phy_exynos5 = {
        .cpu_type               = TYPE_EXYNOS5250,
        .hostphy_en_mask        = EXYNOS_USBPHY_ENABLE,
-       .hostphy_reg_offset     = EXYNOS_USBHOST_PHY_CTRL_OFFSET,
+       .hostphy_reg_offset     = EXYNOS5_USBHOST_PHY_CTRL_OFFSET,
        .rate_to_clksel         = samsung_usbphy_rate_to_clksel_4x12,
        .set_isolation          = samsung_usbphy_set_isolation_4210,
        .phy_enable             = samsung_exynos5_usb2phy_enable,