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:
Olof Johansson 2012-03-10 09:51:26 -08:00
commit f7c8faedf9
27 changed files with 765 additions and 72 deletions

View File

@ -471,6 +471,11 @@ static struct clk init_clocks_off[] = {
.devname = "s5p-mipi-csis.1", .devname = "s5p-mipi-csis.1",
.enable = exynos4_clk_ip_cam_ctrl, .enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 5), .ctrlbit = (1 << 5),
}, {
.name = "jpeg",
.id = 0,
.enable = exynos4_clk_ip_cam_ctrl,
.ctrlbit = (1 << 6),
}, { }, {
.name = "fimc", .name = "fimc",
.devname = "exynos4-fimc.0", .devname = "exynos4-fimc.0",

View File

@ -26,10 +26,12 @@
#include <asm/hardware/gic.h> #include <asm/hardware/gic.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/cacheflush.h>
#include <mach/regs-irq.h> #include <mach/regs-irq.h>
#include <mach/regs-pmu.h> #include <mach/regs-pmu.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <mach/pmu.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/clock.h> #include <plat/clock.h>
@ -45,6 +47,8 @@
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include "common.h" #include "common.h"
#define L2_AUX_VAL 0x7C470001
#define L2_AUX_MASK 0xC200ffff
static const char name_exynos4210[] = "EXYNOS4210"; static const char name_exynos4210[] = "EXYNOS4210";
static const char name_exynos4212[] = "EXYNOS4212"; static const char name_exynos4212[] = "EXYNOS4212";
@ -173,7 +177,12 @@ static struct map_desc exynos4_iodesc[] __initdata = {
}, { }, {
.virtual = (unsigned long)S5P_VA_DMC0, .virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(EXYNOS4_PA_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, .type = MT_DEVICE,
}, { }, {
.virtual = (unsigned long)S3C_VA_USB_HSPHY, .virtual = (unsigned long)S3C_VA_USB_HSPHY,
@ -433,23 +442,48 @@ core_initcall(exynos4_core_init);
#ifdef CONFIG_CACHE_L2X0 #ifdef CONFIG_CACHE_L2X0
static int __init exynos4_l2x0_cache_init(void) static int __init exynos4_l2x0_cache_init(void)
{ {
/* TAG, Data Latency Control: 2cycle */ int ret;
__raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL); 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()) if (!(__raw_readl(S5P_VA_L2CC + L2X0_CTRL) & 0x1)) {
__raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); l2x0_saved_regs.phy_base = EXYNOS4_PA_L2CC;
else if (soc_is_exynos4212() || soc_is_exynos4412()) /* TAG, Data Latency Control: 2 cycles */
__raw_writel(0x120, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL); l2x0_saved_regs.tag_latency = 0x110;
/* L2X0 Prefetch Control */ if (soc_is_exynos4212() || soc_is_exynos4412())
__raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL); l2x0_saved_regs.data_latency = 0x120;
else
l2x0_saved_regs.data_latency = 0x110;
/* L2X0 Power Control */ l2x0_saved_regs.prefetch_ctrl = 0x30000007;
__raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, l2x0_saved_regs.pwr_ctrl =
S5P_VA_L2CC + L2X0_POWER_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; return 0;
} }

View File

@ -11,25 +11,53 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/cpuidle.h> #include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/time.h> #include <linux/time.h>
#include <asm/proc-fns.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, static int exynos4_enter_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv, struct cpuidle_driver *drv,
int index); 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] = { [0] = {
.enter = exynos4_enter_idle, .enter = exynos4_enter_idle,
.exit_latency = 1, .exit_latency = 1,
.target_residency = 100000, .target_residency = 100000,
.flags = CPUIDLE_FLAG_TIME_VALID, .flags = CPUIDLE_FLAG_TIME_VALID,
.name = "IDLE", .name = "C0",
.desc = "ARM clock gating(WFI)", .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); static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
@ -39,9 +67,102 @@ static struct cpuidle_driver exynos4_idle_driver = {
.owner = THIS_MODULE, .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, static int exynos4_enter_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv, struct cpuidle_driver *drv,
int index) int index)
{ {
struct timeval before, after; struct timeval before, after;
int idle_time; int idle_time;
@ -60,6 +181,22 @@ static int exynos4_enter_idle(struct cpuidle_device *dev,
return index; 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) static int __init exynos4_init_cpuidle(void)
{ {
int i, max_cpuidle_state, cpu_id; 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], memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
sizeof(struct cpuidle_state)); sizeof(struct cpuidle_state));
} }
drv->safe_state_index = 0;
cpuidle_register_driver(&exynos4_idle_driver); cpuidle_register_driver(&exynos4_idle_driver);
for_each_cpu(cpu_id, cpu_online_mask) { for_each_cpu(cpu_id, cpu_online_mask) {
device = &per_cpu(exynos4_cpuidle_device, cpu_id); device = &per_cpu(exynos4_cpuidle_device, cpu_id);
device->cpu = 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)) { if (cpuidle_register_device(device)) {
printk(KERN_ERR "CPUidle register device failed\n,"); printk(KERN_ERR "CPUidle register device failed\n,");
return -EIO; return -EIO;
} }
} }
return 0; return 0;
} }
device_initcall(exynos4_init_cpuidle); device_initcall(exynos4_init_cpuidle);

View File

@ -31,6 +31,10 @@
#define EXYNOS4_PA_FIMC2 0x11820000 #define EXYNOS4_PA_FIMC2 0x11820000
#define EXYNOS4_PA_FIMC3 0x11830000 #define EXYNOS4_PA_FIMC3 0x11830000
#define EXYNOS4_PA_JPEG 0x11840000
#define EXYNOS4_PA_G2D 0x12800000
#define EXYNOS4_PA_I2S0 0x03830000 #define EXYNOS4_PA_I2S0 0x03830000
#define EXYNOS4_PA_I2S1 0xE3100000 #define EXYNOS4_PA_I2S1 0xE3100000
#define EXYNOS4_PA_I2S2 0xE2A00000 #define EXYNOS4_PA_I2S2 0xE2A00000
@ -57,6 +61,7 @@
#define EXYNOS4_PA_KEYPAD 0x100A0000 #define EXYNOS4_PA_KEYPAD 0x100A0000
#define EXYNOS4_PA_DMC0 0x10400000 #define EXYNOS4_PA_DMC0 0x10400000
#define EXYNOS4_PA_DMC1 0x10410000
#define EXYNOS4_PA_COMBINER 0x10440000 #define EXYNOS4_PA_COMBINER 0x10440000
@ -162,6 +167,8 @@
#define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1 #define S5P_PA_FIMC1 EXYNOS4_PA_FIMC1
#define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2 #define S5P_PA_FIMC2 EXYNOS4_PA_FIMC2
#define S5P_PA_FIMC3 EXYNOS4_PA_FIMC3 #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_FIMD0 EXYNOS4_PA_FIMD0
#define S5P_PA_HDMI EXYNOS4_PA_HDMI #define S5P_PA_HDMI EXYNOS4_PA_HDMI
#define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY #define S5P_PA_IIC_HDMIPHY EXYNOS4_PA_IIC_HDMIPHY

View File

@ -22,11 +22,13 @@ enum sys_powerdown {
NUM_SYS_POWERDOWN, NUM_SYS_POWERDOWN,
}; };
extern unsigned long l2x0_regs_phys;
struct exynos4_pmu_conf { struct exynos4_pmu_conf {
void __iomem *reg; void __iomem *reg;
unsigned int val[NUM_SYS_POWERDOWN]; unsigned int val[NUM_SYS_POWERDOWN];
}; };
extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode); extern void exynos4_sys_powerdown_conf(enum sys_powerdown mode);
extern void s3c_cpu_resume(void);
#endif /* __ASM_ARCH_PMU_H */ #endif /* __ASM_ARCH_PMU_H */

View File

@ -29,12 +29,13 @@
#include <mach/regs-mct.h> #include <mach/regs-mct.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#define TICK_BASE_CNT 1
enum { enum {
MCT_INT_SPI, MCT_INT_SPI,
MCT_INT_PPI MCT_INT_PPI
}; };
static unsigned long clk_cnt_per_tick;
static unsigned long clk_rate; static unsigned long clk_rate;
static unsigned int mct_int_type; 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, static void exynos4_comp_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
unsigned long cycles_per_jiffy;
exynos4_mct_comp0_stop(); exynos4_mct_comp0_stop();
switch (mode) { switch (mode) {
case CLOCK_EVT_MODE_PERIODIC: 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; break;
case CLOCK_EVT_MODE_ONESHOT: case CLOCK_EVT_MODE_ONESHOT:
@ -248,9 +252,7 @@ static struct irqaction mct_comp_event_irq = {
static void exynos4_clockevent_init(void) static void exynos4_clockevent_init(void)
{ {
clk_cnt_per_tick = clk_rate / 2 / HZ; clockevents_calc_mult_shift(&mct_comp_device, clk_rate, 5);
clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
mct_comp_device.max_delta_ns = mct_comp_device.max_delta_ns =
clockevent_delta2ns(0xffffffff, &mct_comp_device); clockevent_delta2ns(0xffffffff, &mct_comp_device);
mct_comp_device.min_delta_ns = 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 clock_event_device *evt)
{ {
struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
unsigned long cycles_per_jiffy;
exynos4_mct_tick_stop(mevt); exynos4_mct_tick_stop(mevt);
switch (mode) { switch (mode) {
case CLOCK_EVT_MODE_PERIODIC: 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; break;
case CLOCK_EVT_MODE_ONESHOT: 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->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
evt->rating = 450; 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 = evt->max_delta_ns =
clockevent_delta2ns(0x7fffffff, evt); clockevent_delta2ns(0x7fffffff, evt);
evt->min_delta_ns = evt->min_delta_ns =
@ -401,7 +406,7 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
clockevents_register_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 (mct_int_type == MCT_INT_SPI) {
if (cpu == 0) { if (cpu == 0) {

View File

@ -155,13 +155,6 @@ static struct sleep_save exynos4_core_save[] = {
SAVE_ITEM(S5P_SROM_BC3), 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 */ /* For Cortex-A9 Diagnostic and Power control register */
static unsigned int save_arm_register[2]; static unsigned int save_arm_register[2];
@ -182,7 +175,6 @@ static void exynos4_pm_prepare(void)
u32 tmp; u32 tmp;
s3c_pm_do_save(exynos4_core_save, ARRAY_SIZE(exynos4_core_save)); 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_epll_save, ARRAY_SIZE(exynos4_epll_save));
s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_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); scu_enable(S5P_VA_SCU);
#endif #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: early_wakeup:
return; return;
} }

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

@ -22,6 +22,7 @@ obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
# PM # PM
obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
# DMA support # 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_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

@ -206,6 +206,15 @@ static struct clk init_clocks_off[] = {
.parent = &clk_48m, .parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl, .enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MMC2_48, .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", .name = "dma0",
.parent = &clk_h, .parent = &clk_h,
@ -216,6 +225,107 @@ static struct clk init_clocks_off[] = {
.parent = &clk_h, .parent = &clk_h,
.enable = s3c64xx_hclk_ctrl, .enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_DMA1, .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", .name = "watchdog",
.parent = &clk_p, .parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_WDT, .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 = { static struct clk clk_hsmmc0 = {

View 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);

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

@ -65,6 +65,11 @@ config S5PV210_SETUP_SPI
help help
Common setup code for SPI GPIO configurations. Common setup code for SPI GPIO configurations.
config S5PV210_SETUP_USB_PHY
bool
help
Common setup code for USB PHY controller
menu "S5PC110 Machines" menu "S5PC110 Machines"
config MACH_AQUILA config MACH_AQUILA
@ -107,6 +112,7 @@ config MACH_GONI
select S5PV210_SETUP_KEYPAD select S5PV210_SETUP_KEYPAD
select S5PV210_SETUP_SDHCI select S5PV210_SETUP_SDHCI
select S5PV210_SETUP_FIMC select S5PV210_SETUP_FIMC
select S5PV210_SETUP_USB_PHY
help help
Machine support for Samsung GONI board Machine support for Samsung GONI board
S5PC110(MCP) is one of package option of S5PV210 S5PC110(MCP) is one of package option of S5PV210

View 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_KEYPAD) += setup-keypad.o
obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o obj-$(CONFIG_S5PV210_SETUP_SPI) += setup-spi.o
obj-$(CONFIG_S5PV210_SETUP_USB_PHY) += setup-usb-phy.o

View File

@ -13,7 +13,3 @@
#define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C) #define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C)
#define S5PV210_USB_PHY0_EN (1 << 0) #define S5PV210_USB_PHY0_EN (1 << 0)
#define S5PV210_USB_PHY1_EN (1 << 1) #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

View 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;
}

View File

@ -80,6 +80,16 @@ config S5P_DEV_FIMC3
help help
Compile in platform device definitions for FIMC controller 3 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 config S5P_DEV_FIMD0
bool bool
help help

View File

@ -23,9 +23,18 @@
*/ */
#include <linux/linkage.h> #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 * sleep magic, to allow the bootloader to check for an valid
@ -39,11 +48,34 @@
* s3c_cpu_resume * s3c_cpu_resume
* *
* resume code entry for bootloader to call * 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) 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 b cpu_resume
ENDPROC(s3c_cpu_resume)
#ifdef CONFIG_CACHE_L2X0
.globl l2x0_regs_phys
l2x0_regs_phys:
.long 0
#endif

View File

@ -84,31 +84,35 @@ static int clk_null_enable(struct clk *clk, int enable)
int clk_enable(struct clk *clk) int clk_enable(struct clk *clk)
{ {
unsigned long flags;
if (IS_ERR(clk) || clk == NULL) if (IS_ERR(clk) || clk == NULL)
return -EINVAL; return -EINVAL;
clk_enable(clk->parent); clk_enable(clk->parent);
spin_lock(&clocks_lock); spin_lock_irqsave(&clocks_lock, flags);
if ((clk->usage++) == 0) if ((clk->usage++) == 0)
(clk->enable)(clk, 1); (clk->enable)(clk, 1);
spin_unlock(&clocks_lock); spin_unlock_irqrestore(&clocks_lock, flags);
return 0; return 0;
} }
void clk_disable(struct clk *clk) void clk_disable(struct clk *clk)
{ {
unsigned long flags;
if (IS_ERR(clk) || clk == NULL) if (IS_ERR(clk) || clk == NULL)
return; return;
spin_lock(&clocks_lock); spin_lock_irqsave(&clocks_lock, flags);
if ((--clk->usage) == 0) if ((--clk->usage) == 0)
(clk->enable)(clk, 0); (clk->enable)(clk, 0);
spin_unlock(&clocks_lock); spin_unlock_irqrestore(&clocks_lock, flags);
clk_disable(clk->parent); clk_disable(clk->parent);
} }

View File

@ -77,7 +77,7 @@ static struct platform_device samsung_dfl_bl_device __initdata = {
* @gpio_info: structure containing GPIO info for PWM timer * @gpio_info: structure containing GPIO info for PWM timer
* @bl_data: structure containing Backlight control data * @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) struct platform_pwm_backlight_data *bl_data)
{ {
int ret = 0; 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; samsung_bl_data->init = bl_data->init;
if (bl_data->notify) if (bl_data->notify)
samsung_bl_data->notify = 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) if (bl_data->exit)
samsung_bl_data->exit = bl_data->exit; samsung_bl_data->exit = bl_data->exit;
if (bl_data->check_fb) if (bl_data->check_fb)

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>
@ -267,6 +268,52 @@ struct platform_device s5p_device_fimc3 = {
}; };
#endif /* CONFIG_S5P_DEV_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 */ /* FIMD0 */
#ifdef CONFIG_S5P_DEV_FIMD0 #ifdef CONFIG_S5P_DEV_FIMD0
@ -769,7 +816,7 @@ struct platform_device s3c_device_cfcon = {
.resource = s3c_cfcon_resource, .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_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
&s3c_device_cfcon); &s3c_device_cfcon);
@ -887,7 +934,7 @@ struct platform_device s5p_device_mfc_r = {
#ifdef CONFIG_S5P_DEV_CSIS0 #ifdef CONFIG_S5P_DEV_CSIS0
static struct resource s5p_mipi_csis0_resource[] = { 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), [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS0),
}; };
@ -901,7 +948,7 @@ struct platform_device s5p_device_mipi_csis0 = {
#ifdef CONFIG_S5P_DEV_CSIS1 #ifdef CONFIG_S5P_DEV_CSIS1
static struct resource s5p_mipi_csis1_resource[] = { 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), [1] = DEFINE_RES_IRQ(IRQ_MIPI_CSIS1),
}; };
@ -1049,7 +1096,7 @@ struct platform_device s3c64xx_device_onenand1 = {
.resource = s3c64xx_onenand1_resources, .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), s3c_set_platdata(pdata, sizeof(struct onenand_platform_data),
&s3c64xx_device_onenand1); &s3c64xx_device_onenand1);
@ -1423,6 +1470,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

@ -79,6 +79,8 @@ extern struct platform_device s5p_device_fimc1;
extern struct platform_device s5p_device_fimc2; extern struct platform_device s5p_device_fimc2;
extern struct platform_device s5p_device_fimc3; extern struct platform_device s5p_device_fimc3;
extern struct platform_device s5p_device_fimc_md; 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_fimd0;
extern struct platform_device s5p_device_hdmi; extern struct platform_device s5p_device_hdmi;
extern struct platform_device s5p_device_i2c_hdmiphy; extern struct platform_device s5p_device_i2c_hdmiphy;

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);