diff options
27 files changed, 765 insertions, 72 deletions
| diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c index 6504d8b1f8e5..df54c2a92225 100644 --- a/arch/arm/mach-exynos/clock-exynos4.c +++ b/arch/arm/mach-exynos/clock-exynos4.c @@ -471,6 +471,11 @@ static struct clk exynos4_init_clocks_off[] = {  		.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",  		.enable		= exynos4_clk_ip_cam_ctrl, diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index cbbaca54966a..66742e914641 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -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); diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index 4ebb382c5979..33ab4e7558af 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -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); diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index bf90bb0ab2b8..188d87d6ec41 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -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 diff --git a/arch/arm/mach-exynos/include/mach/pmu.h b/arch/arm/mach-exynos/include/mach/pmu.h index 632dd5630138..e76b7faba66b 100644 --- a/arch/arm/mach-exynos/include/mach/pmu.h +++ b/arch/arm/mach-exynos/include/mach/pmu.h @@ -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 */ diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c index 1016515dc9a8..cae3e2dae2e2 100644 --- a/arch/arm/mach-exynos/mct.c +++ b/arch/arm/mach-exynos/mct.c @@ -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) { diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index f105bd2b6765..428cfeb57724 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -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;  } diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index dd20c66cd700..326ea3a98725 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -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 diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 1822ac2eba31..f9ce1dc28ce4 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -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 diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index aebbcc291b4e..52f079a691cb 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -207,6 +207,15 @@ static struct clk init_clocks_off[] = {  		.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,  		.enable		= s3c64xx_hclk_ctrl, @@ -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 = { diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c new file mode 100644 index 000000000000..179460f38db7 --- /dev/null +++ b/arch/arm/mach-s3c64xx/cpuidle.c @@ -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); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 8077f650eb0e..3b56bd9cb880 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -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)); diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index ce31db136231..ce745e19aa27 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -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); diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index ca6fc204f0ea..d55bc96d9582 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -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); diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c new file mode 100644 index 000000000000..f6757e02d7db --- /dev/null +++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c @@ -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; +} diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 2cdc42e838b8..82525e3831e9 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -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 diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile index 76a121dd52b4..1c4e41998a10 100644 --- a/arch/arm/mach-s5pv210/Makefile +++ b/arch/arm/mach-s5pv210/Makefile @@ -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 diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h index 26691d39d0f4..cccb1eddaa38 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-sys.h +++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h @@ -13,7 +13,3 @@  #define S5PV210_USB_PHY_CON	(S3C_VA_SYS + 0xE80C)  #define S5PV210_USB_PHY0_EN	(1 << 0)  #define S5PV210_USB_PHY1_EN	(1 << 1) - -/* compatibility defines for s3c-hsotg driver */ -#define S3C64XX_OTHERS		S5PV210_USB_PHY_CON -#define S3C64XX_OTHERS_USBMASK	S5PV210_USB_PHY0_EN diff --git a/arch/arm/mach-s5pv210/setup-usb-phy.c b/arch/arm/mach-s5pv210/setup-usb-phy.c new file mode 100644 index 000000000000..be39cf4aa91b --- /dev/null +++ b/arch/arm/mach-s5pv210/setup-usb-phy.c @@ -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; +} diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 88795ea2ecaa..96bea3202304 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -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 diff --git a/arch/arm/plat-s5p/sleep.S b/arch/arm/plat-s5p/sleep.S index 0fd591bfc9fd..006bd01eda02 100644 --- a/arch/arm/plat-s5p/sleep.S +++ b/arch/arm/plat-s5p/sleep.S @@ -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 diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 10f71179071f..65c5eca475e7 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -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);  } diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c index a976c023b286..5f197dcaf10c 100644 --- a/arch/arm/plat-samsung/dev-backlight.c +++ b/arch/arm/plat-samsung/dev-backlight.c @@ -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) diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 98b864777a31..cd5aac08a265 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -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) */ diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 32cc67e6be13..2155d4af62a3 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -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; diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h index a111ad871833..fcf279662067 100644 --- a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h +++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h @@ -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) diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h index a22a4f2eea94..c9e3667cb2b1 100644 --- a/arch/arm/plat-samsung/include/plat/udc-hs.h +++ b/arch/arm/plat-samsung/include/plat/udc-hs.h @@ -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); | 
