ARM: S5PV210: Add usb otg phy control
authorJoonyoung Shim <jy0922.shim@samsung.com>
Thu, 8 Mar 2012 10:52:25 +0000 (19:52 +0900)
committerKukjin Kim <kgene.kim@samsung.com>
Fri, 9 Mar 2012 15:31:34 +0000 (07:31 -0800)
This patch supports to control usb otg phy of S5PV210. Based on
setup-usb-phy.c of S3C64XX.

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
[Test HW: GONI S5PC110]
Tested-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/Makefile
arch/arm/mach-s5pv210/include/mach/regs-sys.h
arch/arm/mach-s5pv210/setup-usb-phy.c [new file with mode: 0644]

index 2cdc42e838b8deb663395966096f0f7b9ca6dd4b..82525e3831e9d831bfa42382963993d8551c52c1 100644 (file)
@@ -65,6 +65,11 @@ config S5PV210_SETUP_SPI
        help
          Common setup code for SPI GPIO configurations.
 
+config S5PV210_SETUP_USB_PHY
+       bool
+       help
+         Common setup code for USB PHY controller
+
 menu "S5PC110 Machines"
 
 config MACH_AQUILA
@@ -107,6 +112,7 @@ config MACH_GONI
        select S5PV210_SETUP_KEYPAD
        select S5PV210_SETUP_SDHCI
        select S5PV210_SETUP_FIMC
+       select S5PV210_SETUP_USB_PHY
        help
          Machine support for Samsung GONI board
          S5PC110(MCP) is one of package option of S5PV210
index 76a121dd52b434fd4ae865dbf8aa6685082c4d41..1c4e41998a1031f2dcc6de7e3b690494391bba17 100644 (file)
@@ -39,3 +39,4 @@ obj-$(CONFIG_S5PV210_SETUP_IDE)               += setup-ide.o
 obj-$(CONFIG_S5PV210_SETUP_KEYPAD)     += setup-keypad.o
 obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
 obj-$(CONFIG_S5PV210_SETUP_SPI)                += setup-spi.o
+obj-$(CONFIG_S5PV210_SETUP_USB_PHY) += setup-usb-phy.o
index 26691d39d0f4cd41a2a2d48b3e9dd4d1180e2ba1..cccb1eddaa3838a959eb10ffc018b68713da3e8b 100644 (file)
@@ -13,7 +13,3 @@
 #define S5PV210_USB_PHY_CON    (S3C_VA_SYS + 0xE80C)
 #define S5PV210_USB_PHY0_EN    (1 << 0)
 #define S5PV210_USB_PHY1_EN    (1 << 1)
-
-/* compatibility defines for s3c-hsotg driver */
-#define S3C64XX_OTHERS         S5PV210_USB_PHY_CON
-#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN
diff --git a/arch/arm/mach-s5pv210/setup-usb-phy.c b/arch/arm/mach-s5pv210/setup-usb-phy.c
new file mode 100644 (file)
index 0000000..be39cf4
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * 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
+ * published by the Free Software Foundationr
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/map.h>
+#include <mach/regs-sys.h>
+#include <plat/cpu.h>
+#include <plat/regs-usb-hsotg-phy.h>
+#include <plat/usb-phy.h>
+
+static int s5pv210_usb_otgphy_init(struct platform_device *pdev)
+{
+       struct clk *xusbxti;
+       u32 phyclk;
+
+       writel(readl(S5PV210_USB_PHY_CON) | S5PV210_USB_PHY0_EN,
+                       S5PV210_USB_PHY_CON);
+
+       /* set clock frequency for PLL */
+       phyclk = readl(S3C_PHYCLK) & ~S3C_PHYCLK_CLKSEL_MASK;
+
+       xusbxti = clk_get(&pdev->dev, "xusbxti");
+       if (xusbxti && !IS_ERR(xusbxti)) {
+               switch (clk_get_rate(xusbxti)) {
+               case 12 * MHZ:
+                       phyclk |= S3C_PHYCLK_CLKSEL_12M;
+                       break;
+               case 24 * MHZ:
+                       phyclk |= S3C_PHYCLK_CLKSEL_24M;
+                       break;
+               default:
+               case 48 * MHZ:
+                       /* default reference clock */
+                       break;
+               }
+               clk_put(xusbxti);
+       }
+
+       /* TODO: select external clock/oscillator */
+       writel(phyclk | S3C_PHYCLK_CLK_FORCE, S3C_PHYCLK);
+
+       /* set to normal OTG PHY */
+       writel((readl(S3C_PHYPWR) & ~S3C_PHYPWR_NORMAL_MASK), S3C_PHYPWR);
+       mdelay(1);
+
+       /* reset OTG PHY and Link */
+       writel(S3C_RSTCON_PHY | S3C_RSTCON_HCLK | S3C_RSTCON_PHYCLK,
+                       S3C_RSTCON);
+       udelay(20);     /* at-least 10uS */
+       writel(0, S3C_RSTCON);
+
+       return 0;
+}
+
+static int s5pv210_usb_otgphy_exit(struct platform_device *pdev)
+{
+       writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
+                               S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
+
+       writel(readl(S5PV210_USB_PHY_CON) & ~S5PV210_USB_PHY0_EN,
+                       S5PV210_USB_PHY_CON);
+
+       return 0;
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_DEVICE)
+               return s5pv210_usb_otgphy_init(pdev);
+
+       return -EINVAL;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+       if (type == S5P_USB_PHY_DEVICE)
+               return s5pv210_usb_otgphy_exit(pdev);
+
+       return -EINVAL;
+}