mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-20 08:22:39 +00:00
Merge branch 'next/devel-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/soc
* 'next/devel-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung: 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
This commit is contained in:
commit
f7c8faedf9
@ -471,6 +471,11 @@ static struct clk 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";
|
||||
@ -173,7 +177,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,
|
||||
@ -433,23 +442,48 @@ core_initcall(exynos4_core_init);
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
static int __init exynos4_l2x0_cache_init(void)
|
||||
{
|
||||
/* 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 (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 (!(__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;
|
||||
|
||||
/* L2X0 Prefetch Control */
|
||||
__raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
|
||||
if (soc_is_exynos4212() || soc_is_exynos4412())
|
||||
l2x0_saved_regs.data_latency = 0x120;
|
||||
else
|
||||
l2x0_saved_regs.data_latency = 0x110;
|
||||
|
||||
/* L2X0 Power Control */
|
||||
__raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
|
||||
S5P_VA_L2CC + L2X0_POWER_CTRL);
|
||||
l2x0_saved_regs.prefetch_ctrl = 0x30000007;
|
||||
l2x0_saved_regs.pwr_ctrl =
|
||||
(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN);
|
||||
|
||||
l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff);
|
||||
l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
|
||||
|
||||
__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 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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -31,6 +31,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
|
||||
@ -57,6 +61,7 @@
|
||||
#define EXYNOS4_PA_KEYPAD 0x100A0000
|
||||
|
||||
#define EXYNOS4_PA_DMC0 0x10400000
|
||||
#define EXYNOS4_PA_DMC1 0x10410000
|
||||
|
||||
#define EXYNOS4_PA_COMBINER 0x10440000
|
||||
|
||||
@ -162,6 +167,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 =
|
||||
@ -314,12 +316,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:
|
||||
@ -393,7 +398,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 =
|
||||
@ -401,7 +406,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 = {
|
||||
|
91
arch/arm/mach-s3c64xx/cpuidle.c
Normal file
91
arch/arm/mach-s3c64xx/cpuidle.c
Normal file
@ -0,0 +1,91 @@
|
||||
/* 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);
|
||||
|
||||
|
90
arch/arm/mach-s3c64xx/setup-usb-phy.c
Normal file
90
arch/arm/mach-s3c64xx/setup-usb-phy.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
90
arch/arm/mach-s5pv210/setup-usb-phy.c
Normal file
90
arch/arm/mach-s5pv210/setup-usb-phy.c
Normal file
@ -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;
|
||||
}
|
@ -80,6 +80,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
|
||||
@ -769,7 +816,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);
|
||||
@ -887,7 +934,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),
|
||||
};
|
||||
|
||||
@ -901,7 +948,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),
|
||||
};
|
||||
|
||||
@ -1049,7 +1096,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);
|
||||
@ -1423,6 +1470,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) */
|
||||
|
@ -79,6 +79,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);
|
||||
|
Loading…
Reference in New Issue
Block a user