ARM: S3C64XX: Add usb otg phy control

This patch supports to control usb otg phy of S3C64XX. Currently, the
driver for usb otg controls usb otg phy but it can be removed by this
patch.

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
[Rebased on the newest git/kgene/linux-samsung #for-next]
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Acked-by: Mark Brown<broonie@opensource.wolfsonmicro.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
This commit is contained in:
Joonyoung Shim 2012-03-07 04:23:47 -08:00 committed by Kukjin Kim
parent 6cdeddcc81
commit 99f6e1f50c
9 changed files with 133 additions and 3 deletions

View File

@ -83,6 +83,11 @@ config S3C64XX_SETUP_SPI
help help
Common setup code for SPI GPIO configurations Common setup code for SPI GPIO configurations
config S3C64XX_SETUP_USB_PHY
bool
help
Common setup code for USB PHY controller
# S36400 Macchine support # S36400 Macchine support
config MACH_SMDK6400 config MACH_SMDK6400
@ -157,6 +162,7 @@ config MACH_SMDK6410
select S3C64XX_SETUP_IDE select S3C64XX_SETUP_IDE
select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_KEYPAD select S3C64XX_SETUP_KEYPAD
select S3C64XX_SETUP_USB_PHY
help help
Machine support for the Samsung SMDK6410 Machine support for the Samsung SMDK6410
@ -256,6 +262,7 @@ config MACH_SMARTQ
select S3C_DEV_USB_HOST select S3C_DEV_USB_HOST
select S3C64XX_SETUP_SDHCI select S3C64XX_SETUP_SDHCI
select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_USB_PHY
select SAMSUNG_DEV_ADC select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_PWM select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS select SAMSUNG_DEV_TS
@ -283,6 +290,7 @@ config MACH_WLF_CRAGG_6410
select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_KEYPAD select S3C64XX_SETUP_KEYPAD
select S3C64XX_SETUP_SPI select S3C64XX_SETUP_SPI
select S3C64XX_SETUP_USB_PHY
select SAMSUNG_DEV_ADC select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_KEYPAD
select S3C_DEV_USB_HOST select S3C_DEV_USB_HOST

View File

@ -43,6 +43,7 @@ obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o
obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o
# Machine support # Machine support

View File

@ -59,6 +59,7 @@
#include <plat/sdhci.h> #include <plat/sdhci.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <plat/s3c64xx-spi.h> #include <plat/s3c64xx-spi.h>
#include <plat/udc-hs.h>
#include <plat/keypad.h> #include <plat/keypad.h>
#include <plat/clock.h> #include <plat/clock.h>
@ -698,6 +699,8 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = {
.cfg_gpio = crag6410_cfg_sdhci0, .cfg_gpio = crag6410_cfg_sdhci0,
}; };
static struct s3c_hsotg_plat crag6410_hsotg_pdata;
static void __init crag6410_machine_init(void) static void __init crag6410_machine_init(void)
{ {
/* Open drain IRQs need pullups */ /* Open drain IRQs need pullups */
@ -722,6 +725,7 @@ static void __init crag6410_machine_init(void)
s3c_i2c0_set_platdata(&i2c0_pdata); s3c_i2c0_set_platdata(&i2c0_pdata);
s3c_i2c1_set_platdata(&i2c1_pdata); s3c_i2c1_set_platdata(&i2c1_pdata);
s3c_fb_set_platdata(&crag6410_lcd_pdata); s3c_fb_set_platdata(&crag6410_lcd_pdata);
s3c_hsotg_set_platdata(&crag6410_hsotg_pdata);
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));

View File

@ -187,6 +187,8 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
}, },
}; };
static struct s3c_hsotg_plat smartq_hsotg_pdata;
static int __init smartq_lcd_setup_gpio(void) static int __init smartq_lcd_setup_gpio(void)
{ {
int ret; int ret;
@ -383,6 +385,7 @@ void __init smartq_map_io(void)
void __init smartq_machine_init(void) void __init smartq_machine_init(void)
{ {
s3c_i2c0_set_platdata(NULL); s3c_i2c0_set_platdata(NULL);
s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
s3c_hwmon_set_platdata(&smartq_hwmon_pdata); s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata); s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata); s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);

View File

@ -72,6 +72,7 @@
#include <plat/keypad.h> #include <plat/keypad.h>
#include <plat/backlight.h> #include <plat/backlight.h>
#include <plat/regs-fb-v4.h> #include <plat/regs-fb-v4.h>
#include <plat/udc-hs.h>
#include "common.h" #include "common.h"
@ -631,6 +632,8 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
.pwm_id = 1, .pwm_id = 1,
}; };
static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
static void __init smdk6410_map_io(void) static void __init smdk6410_map_io(void)
{ {
u32 tmp; u32 tmp;
@ -659,6 +662,7 @@ static void __init smdk6410_machine_init(void)
s3c_i2c0_set_platdata(NULL); s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL); s3c_i2c1_set_platdata(NULL);
s3c_fb_set_platdata(&smdk6410_lcd_pdata); s3c_fb_set_platdata(&smdk6410_lcd_pdata);
s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
samsung_keypad_set_platdata(&smdk6410_keypad_data); samsung_keypad_set_platdata(&smdk6410_keypad_data);

View File

@ -0,0 +1,90 @@
/*
* Copyright (C) 2011 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 as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#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 s3c_usb_otgphy_init(struct platform_device *pdev)
{
struct clk *xusbxti;
u32 phyclk;
writel(readl(S3C64XX_OTHERS) | S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
/* 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 s3c_usb_otgphy_exit(struct platform_device *pdev)
{
writel((readl(S3C_PHYPWR) | S3C_PHYPWR_ANALOG_POWERDOWN |
S3C_PHYPWR_OTG_DISABLE), S3C_PHYPWR);
writel(readl(S3C64XX_OTHERS) & ~S3C64XX_OTHERS_USBMASK, S3C64XX_OTHERS);
return 0;
}
int s5p_usb_phy_init(struct platform_device *pdev, int type)
{
if (type == S5P_USB_PHY_DEVICE)
return s3c_usb_otgphy_init(pdev);
return -EINVAL;
}
int s5p_usb_phy_exit(struct platform_device *pdev, int type)
{
if (type == S5P_USB_PHY_DEVICE)
return s3c_usb_otgphy_exit(pdev);
return -EINVAL;
}

View File

@ -57,6 +57,7 @@
#include <plat/sdhci.h> #include <plat/sdhci.h>
#include <plat/ts.h> #include <plat/ts.h>
#include <plat/udc.h> #include <plat/udc.h>
#include <plat/udc-hs.h>
#include <plat/usb-control.h> #include <plat/usb-control.h>
#include <plat/usb-phy.h> #include <plat/usb-phy.h>
#include <plat/regs-iic.h> #include <plat/regs-iic.h>
@ -1449,6 +1450,19 @@ struct platform_device s3c_device_usb_hsotg = {
.coherent_dma_mask = DMA_BIT_MASK(32), .coherent_dma_mask = DMA_BIT_MASK(32),
}, },
}; };
void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd)
{
struct s3c_hsotg_plat *npd;
npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat),
&s3c_device_usb_hsotg);
if (!npd->phy_init)
npd->phy_init = s5p_usb_phy_init;
if (!npd->phy_exit)
npd->phy_exit = s5p_usb_phy_exit;
}
#endif /* CONFIG_S3C_DEV_USB_HSOTG */ #endif /* CONFIG_S3C_DEV_USB_HSOTG */
/* USB High Spped 2.0 Device (Gadget) */ /* USB High Spped 2.0 Device (Gadget) */

View File

@ -25,8 +25,9 @@
#define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY) #define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY)
#define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00) #define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00)
#define SRC_PHYPWR_OTG_DISABLE (1 << 4) #define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
#define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3) #define S3C_PHYPWR_OTG_DISABLE (1 << 4)
#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
#define SRC_PHYPWR_FORCE_SUSPEND (1 << 1) #define SRC_PHYPWR_FORCE_SUSPEND (1 << 1)
#define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04) #define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04)
@ -42,7 +43,7 @@
#define S3C_RSTCON S3C_HSOTG_PHYREG(0x08) #define S3C_RSTCON S3C_HSOTG_PHYREG(0x08)
#define S3C_RSTCON_PHYCLK (1 << 2) #define S3C_RSTCON_PHYCLK (1 << 2)
#define S3C_RSTCON_HCLK (1 << 2) #define S3C_RSTCON_HCLK (1 << 1)
#define S3C_RSTCON_PHY (1 << 0) #define S3C_RSTCON_PHY (1 << 0)
#define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20) #define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20)

View File

@ -26,4 +26,9 @@ enum s3c_hsotg_dmamode {
struct s3c_hsotg_plat { struct s3c_hsotg_plat {
enum s3c_hsotg_dmamode dma; enum s3c_hsotg_dmamode dma;
unsigned int is_osc : 1; unsigned int is_osc : 1;
int (*phy_init)(struct platform_device *pdev, int type);
int (*phy_exit)(struct platform_device *pdev, int type);
}; };
extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd);