Commit 853a0231 authored by Arnd Bergmann's avatar Arnd Bergmann

Merge branch 'samsung/soc' into next/soc2

* samsung/soc:
  ARM: EXYNOS: fix cycle count for periodic mode of clock event timers
  ARM: EXYNOS: add support JPEG
  ARM: EXYNOS: Add DMC1, allow PPMU access for DMC
  ARM: SAMSUNG: Correct MIPI-CSIS io memory resource definition
  ARM: SAMSUNG: fix __init attribute on regarding s3c_set_platdata()
  ARM: SAMSUNG: Add __init attribute to samsung_bl_set()
  ARM: S5PV210: Add usb otg phy control
  ARM: S3C64XX: Add usb otg phy control
  ARM: EXYNOS: Enable l2 configuration through device tree
  ARM: EXYNOS: remove useless code to save/restore L2
  ARM: EXYNOS: save L2 settings during bootup
  ARM: S5P: add L2 early resume code
  ARM: EXYNOS: Add support AFTR mode on EXYNOS4210
  ARM: SAMSUNG: use spin_lock_irqsave() in clk_{enable,disable}
  ARM: S3C64XX: Define some additional always off clocks
  ARM: S3C64XX: Reduce residency requirement for cpuidle WFI mode
  ARM: SAMSUNG: Add a callback 'notify_after' for PWM backlight control
  ARM: SAMSUNG: add G2D to plat-s5p and mach-exynos
  ARM: S3C64XX: Gate some more clocks by default
  ARM: S3C64XX: Add basic cpuidle driver

Conflicts:
	arch/arm/mach-exynos/clock.c
	arch/arm/mach-exynos/common.c

This merges the earlier samsung support into the next/soc2 branch to
resolve conflicts between commits in the earlier work and the exynos5
branch.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents e7051e9d 4d2e4d7f
......@@ -470,6 +470,11 @@ static struct clk exynos4_init_clocks_off[] = {
.devname = "s5p-mipi-csis.1",
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 5),
}, {
.name = "jpeg",
.id = 0,
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 6),
}, {
.name = "fimc",
.devname = "exynos4-fimc.0",
......
......@@ -26,10 +26,12 @@
#include <asm/hardware/gic.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/cacheflush.h>
#include <mach/regs-irq.h>
#include <mach/regs-pmu.h>
#include <mach/regs-gpio.h>
#include <mach/pmu.h>
#include <plat/cpu.h>
#include <plat/clock.h>
......@@ -45,6 +47,8 @@
#include <plat/regs-serial.h>
#include "common.h"
#define L2_AUX_VAL 0x7C470001
#define L2_AUX_MASK 0xC200ffff
static const char name_exynos4210[] = "EXYNOS4210";
static const char name_exynos4212[] = "EXYNOS4212";
......@@ -189,7 +193,12 @@ static struct map_desc exynos4_iodesc[] __initdata = {
}, {
.virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
.length = SZ_4K,
.length = SZ_64K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_DMC1,
.pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
.length = SZ_64K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_USB_HSPHY,
......@@ -592,23 +601,48 @@ static int __init exynos4_l2x0_cache_init(void)
if (soc_is_exynos5250())
return 0;
/* TAG, Data Latency Control: 2cycle */
__raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
int ret;
ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
if (!ret) {
l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
return 0;
}
if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) {
l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC;
/* TAG, Data Latency Control: 2 cycles */
l2x0_saved_regs.tag_latency = 0x110;
if (soc_is_exynos4210())
__raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
else if (soc_is_exynos4212() || soc_is_exynos4412())
__raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
if (soc_is_exynos4212() || soc_is_exynos4412())
l2x0_saved_regs.data_latency = 0x120;
else
l2x0_saved_regs.data_latency = 0x110;
l2x0_saved_regs.prefetch_ctrl = 0x30000007;
l2x0_saved_regs.pwr_ctrl =
(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
/* L2X0 Prefetch Control */
__raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
/* L2X0 Power Control */
__raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
S5P_VA_L2CC + L2X0_POWER_CTRL);
__raw_writel(l2x0_saved_regs.tag_latency,
S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
__raw_writel(l2x0_saved_regs.data_latency,
S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
/* L2X0 Prefetch Control */
__raw_writel(l2x0_saved_regs.prefetch_ctrl,
S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
/* L2X0 Power Control */
__raw_writel(l2x0_saved_regs.pwr_ctrl,
S5P_VA_L2CC + L2X0_POWER_CTRL);
clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
clean_dcache_area(&l2x0_saved_regs, sizeof(struct l2x0_regs));
}
l2x0_init(S5P_VA_L2CC, L2_AUX_VAL, L2_AUX_MASK);
return 0;
}
early_initcall(exynos4_l2x0_cache_init);
......
......@@ -11,25 +11,53 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
#include <linux/io.h>
#include <linux/export.h>
#include <linux/time.h>
#include <asm/proc-fns.h>
#include <asm/smp_scu.h>
#include <asm/suspend.h>
#include <asm/unified.h>
#include <mach/regs-pmu.h>
#include <mach/pmu.h>
#include <plat/cpu.h>
#define REG_DIRECTGO_ADDR (samsung_rev() == EXYNOS4210_REV_1_1 ? \
S5P_INFORM7 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
(S5P_VA_SYSRAM + 0x24) : S5P_INFORM0))
#define REG_DIRECTGO_FLAG (samsung_rev() == EXYNOS4210_REV_1_1 ? \
S5P_INFORM6 : (samsung_rev() == EXYNOS4210_REV_1_0 ? \
(S5P_VA_SYSRAM + 0x20) : S5P_INFORM1))
#define S5P_CHECK_AFTR 0xFCBA0D10
static int exynos4_enter_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index);
static int exynos4_enter_lowpower(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index);
static struct cpuidle_state exynos4_cpuidle_set[] = {
static struct cpuidle_state exynos4_cpuidle_set[] __initdata = {
[0] = {
.enter = exynos4_enter_idle,
.exit_latency = 1,
.target_residency = 100000,
.flags = CPUIDLE_FLAG_TIME_VALID,
.name = "IDLE",
.name = "C0",
.desc = "ARM clock gating(WFI)",
},
[1] = {
.enter = exynos4_enter_lowpower,
.exit_latency = 300,
.target_residency = 100000,
.flags = CPUIDLE_FLAG_TIME_VALID,
.name = "C1",
.desc = "ARM power down",
},
};
static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
......@@ -39,9 +67,102 @@ static struct cpuidle_driver exynos4_idle_driver = {
.owner = THIS_MODULE,
};
/* Ext-GIC nIRQ/nFIQ is the only wakeup source in AFTR */
static void exynos4_set_wakeupmask(void)
{
__raw_writel(0x0000ff3e, S5P_WAKEUP_MASK);
}
static unsigned int g_pwr_ctrl, g_diag_reg;
static void save_cpu_arch_register(void)
{
/*read power control register*/
asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc");
/*read diagnostic register*/
asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
return;
}
static void restore_cpu_arch_register(void)
{
/*write power control register*/
asm("mcr p15, 0, %0, c15, c0, 0" : : "r"(g_pwr_ctrl) : "cc");
/*write diagnostic register*/
asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
return;
}
static int idle_finisher(unsigned long flags)
{
cpu_do_idle();
return 1;
}
static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index)
{
struct timeval before, after;
int idle_time;
unsigned long tmp;
local_irq_disable();
do_gettimeofday(&before);
exynos4_set_wakeupmask();
/* Set value of power down register for aftr mode */
exynos4_sys_powerdown_conf(SYS_AFTR);
__raw_writel(virt_to_phys(s3c_cpu_resume), REG_DIRECTGO_ADDR);
__raw_writel(S5P_CHECK_AFTR, REG_DIRECTGO_FLAG);
save_cpu_arch_register();
/* Setting Central Sequence Register for power down mode */
tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
tmp &= ~S5P_CENTRAL_LOWPWR_CFG;
__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
cpu_pm_enter();
cpu_suspend(0, idle_finisher);
#ifdef CONFIG_SMP
scu_enable(S5P_VA_SCU);
#endif
cpu_pm_exit();
restore_cpu_arch_register();
/*
* If PMU failed while entering sleep mode, WFI will be
* ignored by PMU and then exiting cpu_do_idle().
* S5P_CENTRAL_LOWPWR_CFG bit will not be set automatically
* in this situation.
*/
tmp = __raw_readl(S5P_CENTRAL_SEQ_CONFIGURATION);
if (!(tmp & S5P_CENTRAL_LOWPWR_CFG)) {
tmp |= S5P_CENTRAL_LOWPWR_CFG;
__raw_writel(tmp, S5P_CENTRAL_SEQ_CONFIGURATION);
}
/* Clear wakeup state register */
__raw_writel(0x0, S5P_WAKEUP_STAT);
do_gettimeofday(&after);
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
dev->last_residency = idle_time;
return index;
}
static int exynos4_enter_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index)
int index)
{
struct timeval before, after;
int idle_time;
......@@ -60,6 +181,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev,
return index;
}
static int exynos4_enter_lowpower(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index)
{
int new_index = index;
/* This mode only can be entered when other core's are offline */
if (num_online_cpus() > 1)
new_index = drv->safe_state_index;
if (new_index == 0)
return exynos4_enter_idle(dev, drv, new_index);
else
return exynos4_enter_core0_aftr(dev, drv, new_index);
}
static int __init exynos4_init_cpuidle(void)
{
int i, max_cpuidle_state, cpu_id;
......@@ -74,19 +211,25 @@ static int __init exynos4_init_cpuidle(void)
memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
sizeof(struct cpuidle_state));
}
drv->safe_state_index = 0;
cpuidle_register_driver(&exynos4_idle_driver);
for_each_cpu(cpu_id, cpu_online_mask) {
device = &per_cpu(exynos4_cpuidle_device, cpu_id);
device->cpu = cpu_id;
device->state_count = drv->state_count;
if (cpu_id == 0)
device->state_count = (sizeof(exynos4_cpuidle_set) /
sizeof(struct cpuidle_state));
else
device->state_count = 1; /* Support IDLE only */
if (cpuidle_register_device(device)) {
printk(KERN_ERR "CPUidle register device failed\n,");
return -EIO;
}
}
return 0;
}
device_initcall(exynos4_init_cpuidle);
......@@ -32,6 +32,10 @@
#define EXYNOS4_PA_FIMC2 0x11820000
#define EXYNOS4_PA_FIMC3 0x11830000
#define EXYNOS4_PA_JPEG 0x11840000
#define EXYNOS4_PA_G2D 0x12800000
#define EXYNOS4_PA_I2S0 0x03830000
#define EXYNOS4_PA_I2S1 0xE3100000
#define EXYNOS4_PA_I2S2 0xE2A00000
......@@ -67,6 +71,7 @@
#define EXYNOS4_PA_KEYPAD 0x100A0000
#define EXYNOS4_PA_DMC0 0x10400000
#define EXYNOS4_PA_DMC1 0x10410000
#define EXYNOS4_PA_COMBINER 0x10440000
#define EXYNOS5_PA_COMBINER 0x10440000
......@@ -179,6 +184,8 @@
#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1
#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2
#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3
#define S5P_PA_JPEG EXYNOS4_PA_JPEG
#define S5P_PA_G2D EXYNOS4_PA_G2D
#define S5P_PA_FIMD0 EXYNOS4_PA_FIMD0
#define S5P_PA_HDMI EXYNOS4_PA_HDMI
#define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY
......
......@@ -22,11 +22,13 @@ enum sys_powerdown {
NUM_SYS_POWERDOWN,
};
extern unsigned long l2x0_regs_phys;
struct exynos4_pmu_conf {
void __iomem *reg;
unsigned int val[NUM_SYS_POWERDOWN];
};
extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
extern void s3c_cpu_resume(void);
#endif /* __ASM_ARCH_PMU_H */
......@@ -29,12 +29,13 @@
#include <mach/regs-mct.h>
#include <asm/mach/time.h>
#define TICK_BASE_CNT 1
enum {
MCT_INT_SPI,
MCT_INT_PPI
};
static unsigned long clk_cnt_per_tick;
static unsigned long clk_rate;
static unsigned int mct_int_type;
......@@ -205,11 +206,14 @@ static int exynos4_comp_set_next_event(unsigned long cycles,
static void exynos4_comp_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
unsigned long cycles_per_jiffy;
exynos4_mct_comp0_stop();
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
exynos4_mct_comp0_start(mode, clk_cnt_per_tick);
cycles_per_jiffy =
(((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
exynos4_mct_comp0_start(mode, cycles_per_jiffy);
break;
case CLOCK_EVT_MODE_ONESHOT:
......@@ -248,9 +252,7 @@ static struct irqaction mct_comp_event_irq = {
static void exynos4_clockevent_init(void)
{
clk_cnt_per_tick = clk_rate / 2 / HZ;
clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
mct_comp_device.max_delta_ns =
clockevent_delta2ns(0xffffffff, &mct_comp_device);
mct_comp_device.min_delta_ns =
......@@ -317,12 +319,15 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
unsigned long cycles_per_jiffy;
exynos4_mct_tick_stop(mevt);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
exynos4_mct_tick_start(clk_cnt_per_tick, mevt);
cycles_per_jiffy =
(((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
exynos4_mct_tick_start(cycles_per_jiffy, mevt);
break;
case CLOCK_EVT_MODE_ONESHOT:
......@@ -396,7 +401,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
evt->rating = 450;
clockevents_calc_mult_shift(evt, clk_rate / 2, 5);
clockevents_calc_mult_shift(evt, clk_rate / (TICK_BASE_CNT + 1), 5);
evt->max_delta_ns =
clockevent_delta2ns(0x7fffffff, evt);
evt->min_delta_ns =
......@@ -404,7 +409,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
clockevents_register_device(evt);
exynos4_mct_write(0x1, mevt->base + MCT_L_TCNTB_OFFSET);
exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
if (mct_int_type == MCT_INT_SPI) {
if (cpu == 0) {
......
......@@ -155,13 +155,6 @@ static struct sleep_save exynos4_core_save[] = {
SAVE_ITEM(S5P_SROM_BC3),
};
static struct sleep_save exynos4_l2cc_save[] = {
SAVE_ITEM(S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL),
SAVE_ITEM(S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL),
SAVE_ITEM(S5P_VA_L2CC + L2X0_PREFETCH_CTRL),
SAVE_ITEM(S5P_VA_L2CC + L2X0_POWER_CTRL),
SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL),
};
/* For Cortex-A9 Diagnostic and Power control register */
static unsigned int save_arm_register[2];
......@@ -182,7 +175,6 @@ static void exynos4_pm_prepare(void)
u32 tmp;
s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save));
s3c_pm_do_save(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
......@@ -388,13 +380,6 @@ static void exynos4_pm_resume(void)
scu_enable(S5P_VA_SCU);
#endif
#ifdef CONFIG_CACHE_L2X0
s3c_pm_do_restore_core(exynos4_l2cc_save, ARRAY_SIZE(exynos4_l2cc_save));
outer_inv_all();
/* enable L2X0*/
writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
#endif
early_wakeup:
return;
}
......
......@@ -83,6 +83,11 @@ config S3C64XX_SETUP_SPI
help
Common setup code for SPI GPIO configurations
config S3C64XX_SETUP_USB_PHY
bool
help
Common setup code for USB PHY controller
# S36400 Macchine support
config MACH_SMDK6400
......@@ -157,6 +162,7 @@ config MACH_SMDK6410
select S3C64XX_SETUP_IDE
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_KEYPAD
select S3C64XX_SETUP_USB_PHY
help
Machine support for the Samsung SMDK6410
......@@ -256,6 +262,7 @@ config MACH_SMARTQ
select S3C_DEV_USB_HOST
select S3C64XX_SETUP_SDHCI
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_USB_PHY
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_PWM
select SAMSUNG_DEV_TS
......@@ -283,6 +290,7 @@ config MACH_WLF_CRAGG_6410
select S3C64XX_SETUP_FB_24BPP
select S3C64XX_SETUP_KEYPAD
select S3C64XX_SETUP_SPI
select S3C64XX_SETUP_USB_PHY
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_KEYPAD
select S3C_DEV_USB_HOST
......
......@@ -22,6 +22,7 @@ obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
# PM
obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
# DMA support
......@@ -42,6 +43,7 @@ obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi.o
obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy.o
# Machine support
......
......@@ -206,6 +206,15 @@ static struct clk init_clocks_off[] = {
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MMC2_48,
}, {
.name = "ac97",
.parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_AC97,
}, {
.name = "cfcon",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_IHOST,
}, {
.name = "dma0",
.parent = &clk_h,
......@@ -216,6 +225,107 @@ static struct clk init_clocks_off[] = {
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_DMA1,
}, {
.name = "3dse",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_3DSE,
}, {
.name = "hclk_secur",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_SECUR,
}, {
.name = "sdma1",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_SDMA1,
}, {
.name = "sdma0",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_SDMA0,
}, {
.name = "hclk_jpeg",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_JPEG,
}, {
.name = "camif",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_CAMIF,
}, {
.name = "hclk_scaler",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_SCALER,
}, {
.name = "2d",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_2D,
}, {
.name = "tv",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_TV,
}, {
.name = "post0",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_POST0,
}, {
.name = "rot",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_ROT,
}, {
.name = "hclk_mfc",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_MFC,
}, {
.name = "pclk_mfc",
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_MFC,
}, {
.name = "dac27",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_DAC27,
}, {
.name = "tv27",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_TV27,
}, {
.name = "scaler27",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SCALER27,
}, {
.name = "sclk_scaler",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SCALER,
}, {
.name = "post0_27",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_POST0_27,
}, {
.name = "secur",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_SECUR,
}, {
.name = "sclk_mfc",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MFC,
}, {
.name = "cam",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_CAM,
}, {
.name = "sclk_jpeg",
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_JPEG,
},
};
......@@ -289,16 +399,7 @@ static struct clk init_clocks[] = {
.name = "watchdog",
.parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_WDT,
}, {
.name = "ac97",
.parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_AC97,
}, {
.name = "cfcon",
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_IHOST,
}
},
};
static struct clk clk_hsmmc0 = {
......
/* linux/arch/arm/mach-s3c64xx/cpuidle.c
*
* Copyright (c) 2011 Wolfson Microelectronics, plc
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.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 Foundation.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cpuidle.h>
#include <linux/io.h>
#include <linux/export.h>
#include <linux/time.h>
#include <asm/proc-fns.h>
#include <mach/map.h>
#include <mach/regs-sys.h>
#include <mach/regs-syscon-power.h>
static int s3c64xx_enter_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv,
int index)
{
struct timeval before, after;
unsigned long tmp;
int idle_time;
local_irq_disable();
do_gettimeofday(&before);
/* Setup PWRCFG to enter idle mode */
tmp = __raw_readl(S3C64XX_PWR_CFG);
tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
__raw_writel(tmp, S3C64XX_PWR_CFG);
cpu_do_idle();
do_gettimeofday(&after);
local_irq_enable();
idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
(after.tv_usec - before.tv_usec);
dev->last_residency = idle_time;
return index;
}
static struct cpuidle_state s3c64xx_cpuidle_set[] = {
[0] = {
.enter = s3c64xx_enter_idle,
.exit_latency = 1,
.target_residency = 1,
.flags = CPUIDLE_FLAG_TIME_VALID,
.name = "IDLE",
.desc = "System active, ARM gated",
},
};
static struct cpuidle_driver s3c64xx_cpuidle_driver = {
.name = "s3c64xx_cpuidle",
.owner = THIS_MODULE,
.state_count = ARRAY_SIZE(s3c64xx_cpuidle_set),
};
static struct cpuidle_device s3c64xx_cpuidle_device = {
.state_count = ARRAY_SIZE(s3c64xx_cpuidle_set),
};
static int __init s3c64xx_init_cpuidle(void)
{
int ret;
memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set,
sizeof(s3c64xx_cpuidle_set));
cpuidle_register_driver(&s3c64xx_cpuidle_driver);
ret = cpuidle_register_device(&s3c64xx_cpuidle_device);
if (ret) {
pr_err("Failed to register cpuidle device: %d\n", ret);
return ret;
}
return 0;
}
device_initcall(s3c64xx_init_cpuidle);
......@@ -59,6 +59,7 @@
#include <plat/sdhci.h>
#include <plat/gpio-cfg.h>
#include <plat/s3c64xx-spi.h>
#include <plat/udc-hs.h>
#include <plat/keypad.h>
#include <plat/clock.h>
......@@ -698,6 +699,8 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = {
.cfg_gpio = crag6410_cfg_sdhci0,
};
static struct s3c_hsotg_plat crag6410_hsotg_pdata;
static void __init crag6410_machine_init(void)
{
/* Open drain IRQs need pullups */
......@@ -722,6 +725,7 @@ static void __init crag6410_machine_init(void)
s3c_i2c0_set_platdata(&i2c0_pdata);
s3c_i2c1_set_platdata(&i2c1_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(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
......
......@@ -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)
{
int ret;
......@@ -383,6 +385,7 @@ void __init smartq_map_io(void)
void __init smartq_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
s3c_hsotg_set_platdata(&smartq_hsotg_pdata);
s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
......
......@@ -72,6 +72,7 @@
#include <plat/keypad.h>
#include <plat/backlight.h>
#include <plat/regs-fb-v4.h>
#include <plat/udc-hs.h>
#include "common.h"
......@@ -631,6 +632,8 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = {
.pwm_id = 1,
};
static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
static void __init smdk6410_map_io(void)
{
u32 tmp;
......@@ -659,6 +662,7 @@ static void __init smdk6410_machine_init(void)
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_fb_set_platdata(&smdk6410_lcd_pdata);
s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata);
samsung_keypad_set_platdata(&smdk6410_keypad_data);
......
/*
* 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;
}
......@@ -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
......
......@@ -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
......@@ -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
/*
* 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;
}
......@@ -84,6 +84,16 @@ config S5P_DEV_FIMC3
help
Compile in platform device definitions for FIMC controller 3
config S5P_DEV_JPEG
bool
help
Compile in platform device definitions for JPEG codec
config S5P_DEV_G2D
bool
help
Compile in platform device definitions for G2D device
config S5P_DEV_FIMD0
bool
help
......
......@@ -23,9 +23,18 @@
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/hardware/cache-l2x0.h>
.text
/*
* The following code is located into the .data section. This is to
* allow l2x0_regs_phys to be accessed with a relative load while we
* can't rely on any MMU translation. We could have put l2x0_regs_phys
* in the .text section as well, but some setups might insist on it to
* be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
*/
.data
.align
/*
* sleep magic, to allow the bootloader to check for an valid
......@@ -39,11 +48,34 @@
* s3c_cpu_resume
*
* resume code entry for bootloader to call
*
* we must put this code here in the data segment as we have no
* other way of restoring the stack pointer after sleep, and we
* must not write to the code segment (code is read-only)
*/
ENTRY(s3c_cpu_resume)
#ifdef CONFIG_CACHE_L2X0
adr r0, l2x0_regs_phys
ldr r0, [r0]
ldr r1, [r0, #L2X0_R_PHY_BASE]
ldr r2, [r1, #L2X0_CTRL]
tst r2, #0x1
bne resume_l2on
ldr r2, [r0, #L2X0_R_AUX_CTRL]
str r2, [r1, #L2X0_AUX_CTRL]
ldr r2, [r0, #L2X0_R_TAG_LATENCY]
str r2, [r1, #L2X0_TAG_LATENCY_CTRL]
ldr r2, [r0, #L2X0_R_DATA_LATENCY]
str r2, [r1, #L2X0_DATA_LATENCY_CTRL]
ldr r2, [r0, #L2X0_R_PREFETCH_CTRL]
str r2, [r1, #L2X0_PREFETCH_CTRL]
ldr r2, [r0, #L2X0_R_PWR_CTRL]
str r2, [r1, #L2X0_POWER_CTRL]
mov r2, #1
str r2, [r1, #L2X0_CTRL]
resume_l2on:
#endif
b cpu_resume
ENDPROC(s3c_cpu_resume)
#ifdef CONFIG_CACHE_L2X0
.globl l2x0_regs_phys
l2x0_regs_phys:
.long 0
#endif
......@@ -84,31 +84,35 @@ static int clk_null_enable(struct clk *clk, int enable)
int clk_enable(struct clk *clk)
{
unsigned long flags;
if (IS_ERR(clk) || clk == NULL)
return -EINVAL;
clk_enable(clk->parent);
spin_lock(&clocks_lock);
spin_lock_irqsave(&clocks_lock, flags);
if ((clk->usage++) == 0)
(clk->enable)(clk, 1);
spin_unlock(&clocks_lock);
spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
void clk_disable(struct clk *clk)
{
unsigned long flags;
if (IS_ERR(clk) || clk == NULL)
return;
spin_lock(&clocks_lock);
spin_lock_irqsave(&clocks_lock, flags);
if ((--clk->usage) == 0)
(clk->enable)(clk, 0);
spin_unlock(&clocks_lock);
spin_unlock_irqrestore(&clocks_lock, flags);
clk_disable(clk->parent);
}
......
......@@ -77,7 +77,7 @@ static struct platform_device samsung_dfl_bl_device __initdata = {
* @gpio_info: structure containing GPIO info for PWM timer
* @bl_data: structure containing Backlight control data
*/
void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
struct platform_pwm_backlight_data *bl_data)
{
int ret = 0;
......@@ -115,6 +115,8 @@ void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
samsung_bl_data->init = bl_data->init;
if (bl_data->notify)
samsung_bl_data->notify = bl_data->notify;
if (bl_data->notify_after)
samsung_bl_data->notify_after = bl_data->notify_after;
if (bl_data->exit)
samsung_bl_data->exit = bl_data->exit;
if (bl_data->check_fb)
......
......@@ -57,6 +57,7 @@
#include <plat/sdhci.h>
#include <plat/ts.h>
#include <plat/udc.h>
#include <plat/udc-hs.h>
#include <plat/usb-control.h>
#include <plat/usb-phy.h>
#include <plat/regs-iic.h>
......@@ -267,6 +268,52 @@ struct platform_device s5p_device_fimc3 = {
};
#endif /* CONFIG_S5P_DEV_FIMC3 */
/* G2D */
#ifdef CONFIG_S5P_DEV_G2D
static struct resource s5p_g2d_resource[] = {
[0] = {
.start = S5P_PA_G2D,
.end = S5P_PA_G2D + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_2D,
.end = IRQ_2D,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device s5p_device_g2d = {
.name = "s5p-g2d",
.id = 0,
.num_resources = ARRAY_SIZE(s5p_g2d_resource),
.resource = s5p_g2d_resource,
.dev = {
.dma_mask = &samsung_device_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
#endif /* CONFIG_S5P_DEV_G2D */
#ifdef CONFIG_S5P_DEV_JPEG
static struct resource s5p_jpeg_resource[] = {
[0] = DEFINE_RES_MEM(S5P_PA_JPEG, SZ_4K),
[1] = DEFINE_RES_IRQ(IRQ_JPEG),
};
struct platform_device s5p_device_jpeg = {
.name = "s5p-jpeg",
.id = 0,
.num_resources = ARRAY_SIZE(s5p_jpeg_resource),
.resource = s5p_jpeg_resource,
.dev = {
.dma_mask = &samsung_device_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
#endif /* CONFIG_S5P_DEV_JPEG */
/* FIMD0 */
#ifdef CONFIG_S5P_DEV_FIMD0
......@@ -758,7 +805,7 @@ struct platform_device s3c_device_cfcon = {
.resource = s3c_cfcon_resource,
};
void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
void __init s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
{
s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
&s3c_device_cfcon);
......@@ -876,7 +923,7 @@ struct platform_device s5p_device_mfc_r = {
#ifdef CONFIG_S5P_DEV_CSIS0
static struct resource s5p_mipi_csis0_resource[] = {
[0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_4K),
[0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS0, SZ_16K),
[1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0),
};
......@@ -890,7 +937,7 @@ struct platform_device s5p_device_mipi_csis0 = {
#ifdef CONFIG_S5P_DEV_CSIS1
static struct resource s5p_mipi_csis1_resource[] = {
[0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_4K),
[0] = DEFINE_RES_MEM(S5P_PA_MIPI_CSIS1, SZ_16K),
[1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1),
};
......@@ -1038,7 +1085,7 @@ struct platform_device s3c64xx_device_onenand1 = {
.resource = s3c64xx_onenand1_resources,
};
void s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
void __init s3c64xx_onenand1_set_platdata(struct onenand_platform_data *pdata)
{
s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
&s3c64xx_device_onenand1);
......@@ -1412,6 +1459,19 @@ struct platform_device s3c_device_usb_hsotg = {
.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 */
/* USB High Spped 2.0 Device (Gadget) */
......
......@@ -81,6 +81,8 @@ extern struct platform_device s5p_device_fimc1;
extern struct platform_device s5p_device_fimc2;
extern struct platform_device s5p_device_fimc3;
extern struct platform_device s5p_device_fimc_md;
extern struct platform_device s5p_device_jpeg;
extern struct platform_device s5p_device_g2d;
extern struct platform_device s5p_device_fimd0;
extern struct platform_device s5p_device_hdmi;
extern struct platform_device s5p_device_i2c_hdmiphy;
......
......@@ -25,8 +25,9 @@
#define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY)
#define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00)
#define SRC_PHYPWR_OTG_DISABLE (1 << 4)
#define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3)
#define S3C_PHYPWR_NORMAL_MASK (0x19 << 0)
#define S3C_PHYPWR_OTG_DISABLE (1 << 4)
#define S3C_PHYPWR_ANALOG_POWERDOWN (1 << 3)
#define SRC_PHYPWR_FORCE_SUSPEND (1 << 1)
#define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04)
......@@ -42,7 +43,7 @@
#define S3C_RSTCON S3C_HSOTG_PHYREG(0x08)
#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_PHYTUNE S3C_HSOTG_PHYREG(0x20)
......
......@@ -26,4 +26,9 @@ enum s3c_hsotg_dmamode {
struct s3c_hsotg_plat {
enum s3c_hsotg_dmamode dma;
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);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment