Commit f9cef506 authored by Russell King's avatar Russell King

Merge branch 'for-rmk' of...

Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into devel-stable

Conflicts:
	arch/arm/mach-s3c64xx/dev-audio.c
parents 9ae21ca3 cbff3eb3
...@@ -727,9 +727,11 @@ config ARCH_S5PC100 ...@@ -727,9 +727,11 @@ config ARCH_S5PC100
config ARCH_S5PV210 config ARCH_S5PV210
bool "Samsung S5PV210/S5PC110" bool "Samsung S5PV210/S5PC110"
select CPU_V7 select CPU_V7
select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO select GENERIC_GPIO
select HAVE_CLK select HAVE_CLK
select ARM_L1_CACHE_SHIFT_6 select ARM_L1_CACHE_SHIFT_6
select ARCH_HAS_CPUFREQ
select ARCH_USES_GETTIMEOFFSET select ARCH_USES_GETTIMEOFFSET
select HAVE_S3C2410_I2C select HAVE_S3C2410_I2C
select HAVE_S3C_RTC select HAVE_S3C_RTC
...@@ -740,9 +742,13 @@ config ARCH_S5PV210 ...@@ -740,9 +742,13 @@ config ARCH_S5PV210
config ARCH_S5PV310 config ARCH_S5PV310
bool "Samsung S5PV310/S5PC210" bool "Samsung S5PV310/S5PC210"
select CPU_V7 select CPU_V7
select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO select GENERIC_GPIO
select HAVE_CLK select HAVE_CLK
select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS
select HAVE_S3C_RTC
select HAVE_S3C2410_I2C
select HAVE_S3C2410_WATCHDOG
help help
Samsung S5PV310 series based systems Samsung S5PV310 series based systems
......
...@@ -53,6 +53,10 @@ ...@@ -53,6 +53,10 @@
#define L2X0_LINE_DATA 0xF10 #define L2X0_LINE_DATA 0xF10
#define L2X0_LINE_TAG 0xF30 #define L2X0_LINE_TAG 0xF30
#define L2X0_DEBUG_CTRL 0xF40 #define L2X0_DEBUG_CTRL 0xF40
#define L2X0_PREFETCH_CTRL 0xF60
#define L2X0_POWER_CTRL 0xF80
#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
#define L2X0_STNDBY_MODE_EN (1 << 0)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#ifdef CONFIG_CPU_S3C244X #ifdef CONFIG_CPU_S3C244X
#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA) #define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
#define ARCH_NR_GPIOS (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA)
#else #else
#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA) #define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
#endif #endif
...@@ -30,8 +32,10 @@ ...@@ -30,8 +32,10 @@
#include <mach/gpio-nrs.h> #include <mach/gpio-nrs.h>
#include <mach/gpio-fns.h> #include <mach/gpio-fns.h>
#ifdef CONFIG_CPU_S3C24XX #ifdef CONFIG_CPU_S3C244X
#define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32) #define S3C_GPIO_END (S3C2410_GPJ(0) + 32)
#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
#define S3C_GPIO_END (S3C2410_GPM(0) + 32)
#else #else
#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32) #define S3C_GPIO_END (S3C2410_GPH(0) + 32)
#endif #endif
...@@ -118,6 +118,8 @@ ...@@ -118,6 +118,8 @@
#define S3C2443_SCLKCON_UARTCLK (1<<8) #define S3C2443_SCLKCON_UARTCLK (1<<8)
#define S3C2443_SCLKCON_USBHOST (1<<1) #define S3C2443_SCLKCON_USBHOST (1<<1)
#define S3C2443_PWRCFG_SLEEP (1<<15)
#include <asm/div64.h> #include <asm/div64.h>
static inline unsigned int static inline unsigned int
......
...@@ -15,6 +15,6 @@ ...@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H #ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H #define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xE0000000UL #define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */ #endif /* __ASM_ARCH_VMALLOC_H */
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/pm.h> #include <plat/pm.h>
#include <plat/pll.h> #include <plat/pll.h>
#include <plat/nand-core.h>
#ifndef CONFIG_CPU_S3C2412_ONLY #ifndef CONFIG_CPU_S3C2412_ONLY
void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
...@@ -92,7 +93,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -92,7 +93,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
/* rename devices that are s3c2412/s3c2413 specific */ /* rename devices that are s3c2412/s3c2413 specific */
s3c_device_sdi.name = "s3c2412-sdi"; s3c_device_sdi.name = "s3c2412-sdi";
s3c_device_lcd.name = "s3c2412-lcd"; s3c_device_lcd.name = "s3c2412-lcd";
s3c_device_nand.name = "s3c2412-nand"; s3c_nand_setname("s3c2412-nand");
/* alter IRQ of SDI controller */ /* alter IRQ of SDI controller */
......
...@@ -25,6 +25,11 @@ config S3C2416_DMA ...@@ -25,6 +25,11 @@ config S3C2416_DMA
help help
Internal config node for S3C2416 DMA support Internal config node for S3C2416 DMA support
config S3C2416_PM
bool
help
Internal config node to apply S3C2416 power management
menu "S3C2416 Machines" menu "S3C2416 Machines"
config MACH_SMDK2416 config MACH_SMDK2416
...@@ -33,6 +38,7 @@ config MACH_SMDK2416 ...@@ -33,6 +38,7 @@ config MACH_SMDK2416
select S3C_DEV_FB select S3C_DEV_FB
select S3C_DEV_HSMMC select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC1
select S3C2416_PM if PM
help help
Say Y here if you are using an SMDK2416 Say Y here if you are using an SMDK2416
......
...@@ -11,7 +11,7 @@ obj- := ...@@ -11,7 +11,7 @@ obj- :=
obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o
obj-$(CONFIG_CPU_S3C2416) += irq.o obj-$(CONFIG_CPU_S3C2416) += irq.o
obj-$(CONFIG_S3C2416_PM) += pm.o
#obj-$(CONFIG_S3C2416_DMA) += dma.o #obj-$(CONFIG_S3C2416_DMA) += dma.o
# Machine support # Machine support
......
...@@ -243,6 +243,8 @@ static int __init s3c2416_irq_add(struct sys_device *sysdev) ...@@ -243,6 +243,8 @@ static int __init s3c2416_irq_add(struct sys_device *sysdev)
static struct sysdev_driver s3c2416_irq_driver = { static struct sysdev_driver s3c2416_irq_driver = {
.add = s3c2416_irq_add, .add = s3c2416_irq_add,
.suspend = s3c24xx_irq_suspend,
.resume = s3c24xx_irq_resume,
}; };
static int __init s3c2416_irq_init(void) static int __init s3c2416_irq_init(void)
......
/* linux/arch/arm/mach-s3c2416/pm.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)
*
* 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/sysdev.h>
#include <linux/io.h>
#include <asm/cacheflush.h>
#include <mach/regs-power.h>
#include <mach/regs-s3c2443-clock.h>
#include <plat/cpu.h>
#include <plat/pm.h>
extern void s3c2412_sleep_enter(void);
static void s3c2416_cpu_suspend(void)
{
flush_cache_all();
/* enable wakeup sources regardless of battery state */
__raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);
/* set the mode as sleep, 2BED represents "Go to BED" */
__raw_writel(0x2BED, S3C2443_PWRMODE);
s3c2412_sleep_enter();
}
static void s3c2416_pm_prepare(void)
{
/*
* write the magic value u-boot uses to check for resume into
* the INFORM0 register, and ensure INFORM1 is set to the
* correct address to resume from.
*/
__raw_writel(0x2BED, S3C2412_INFORM0);
__raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
}
static int s3c2416_pm_add(struct sys_device *sysdev)
{
pm_cpu_prep = s3c2416_pm_prepare;
pm_cpu_sleep = s3c2416_cpu_suspend;
return 0;
}
static int s3c2416_pm_suspend(struct sys_device *dev, pm_message_t state)
{
return 0;
}
static int s3c2416_pm_resume(struct sys_device *dev)
{
/* unset the return-from-sleep amd inform flags */
__raw_writel(0x0, S3C2443_PWRMODE);
__raw_writel(0x0, S3C2412_INFORM0);
__raw_writel(0x0, S3C2412_INFORM1);
return 0;
}
static struct sysdev_driver s3c2416_pm_driver = {
.add = s3c2416_pm_add,
.suspend = s3c2416_pm_suspend,
.resume = s3c2416_pm_resume,
};
static __init int s3c2416_pm_init(void)
{
return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
}
arch_initcall(s3c2416_pm_init);
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#include <plat/iic-core.h> #include <plat/iic-core.h>
#include <plat/fb-core.h> #include <plat/fb-core.h>
#include <plat/nand-core.h>
static struct map_desc s3c2416_iodesc[] __initdata = { static struct map_desc s3c2416_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG), IODESC_ENT(WATCHDOG),
...@@ -100,7 +101,7 @@ void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no) ...@@ -100,7 +101,7 @@ void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{ {
s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no); s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
s3c_device_nand.name = "s3c2416-nand"; s3c_nand_setname("s3c2412-nand");
} }
/* s3c2416_map_io /* s3c2416_map_io
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/pm.h> #include <plat/pm.h>
#include <plat/pll.h> #include <plat/pll.h>
#include <plat/nand-core.h>
static struct map_desc s3c244x_iodesc[] __initdata = { static struct map_desc s3c244x_iodesc[] __initdata = {
IODESC_ENT(CLKPWR), IODESC_ENT(CLKPWR),
...@@ -68,7 +69,7 @@ void __init s3c244x_map_io(void) ...@@ -68,7 +69,7 @@ void __init s3c244x_map_io(void)
s3c_device_sdi.name = "s3c2440-sdi"; s3c_device_sdi.name = "s3c2440-sdi";
s3c_device_i2c0.name = "s3c2440-i2c"; s3c_device_i2c0.name = "s3c2440-i2c";
s3c_device_nand.name = "s3c2440-nand"; s3c_nand_setname("s3c2440-nand");
s3c_device_ts.name = "s3c2440-ts"; s3c_device_ts.name = "s3c2440-ts";
s3c_device_usbgadget.name = "s3c2440-usbgadget"; s3c_device_usbgadget.name = "s3c2440-usbgadget";
} }
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <plat/devs.h> #include <plat/devs.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/fb-core.h> #include <plat/fb-core.h>
#include <plat/nand-core.h>
static struct map_desc s3c2443_iodesc[] __initdata = { static struct map_desc s3c2443_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG), IODESC_ENT(WATCHDOG),
...@@ -62,7 +63,7 @@ int __init s3c2443_init(void) ...@@ -62,7 +63,7 @@ int __init s3c2443_init(void)
s3c24xx_reset_hook = s3c2443_hard_reset; s3c24xx_reset_hook = s3c2443_hard_reset;
s3c_device_nand.name = "s3c2412-nand"; s3c_nand_setname("s3c2412-nand");
s3c_fb_setname("s3c2443-fb"); s3c_fb_setname("s3c2443-fb");
/* change WDT IRQ number */ /* change WDT IRQ number */
......
...@@ -12,6 +12,6 @@ ...@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H #ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H #define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END (0xe0000000UL) #define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */ #endif /* __ASM_ARCH_VMALLOC_H */
...@@ -98,12 +98,33 @@ config MACH_ANW6410 ...@@ -98,12 +98,33 @@ config MACH_ANW6410
help help
Machine support for the A&W6410 Machine support for the A&W6410
config MACH_MINI6410
bool "MINI6410"
select CPU_S3C6410
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C64XX_SETUP_SDHCI
select S3C_DEV_USB_HOST
select S3C_DEV_NAND
select S3C_DEV_FB
select S3C64XX_SETUP_FB_24BPP
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_TS
help
Machine support for the FriendlyARM MINI6410
config MACH_REAL6410 config MACH_REAL6410
bool "REAL6410" bool "REAL6410"
select CPU_S3C6410 select CPU_S3C6410
select S3C_DEV_HSMMC select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC1
select S3C64XX_SETUP_SDHCI select S3C64XX_SETUP_SDHCI
select S3C_DEV_FB
select S3C64XX_SETUP_FB_24BPP
select S3C_DEV_NAND
select SAMSUNG_DEV_ADC
select SAMSUNG_DEV_TS
select S3C_DEV_USB_HOST
help help
Machine support for the CoreWind REAL6410 Machine support for the CoreWind REAL6410
......
...@@ -53,6 +53,7 @@ obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o ...@@ -53,6 +53,7 @@ obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o
obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o
obj-$(CONFIG_MACH_NCP) += mach-ncp.o obj-$(CONFIG_MACH_NCP) += mach-ncp.o
obj-$(CONFIG_MACH_HMT) += mach-hmt.o obj-$(CONFIG_MACH_HMT) += mach-hmt.o
obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
......
...@@ -22,27 +22,16 @@ ...@@ -22,27 +22,16 @@
#include <plat/audio.h> #include <plat/audio.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <mach/gpio-bank-c.h>
#include <mach/gpio-bank-d.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-h.h>
static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
{ {
unsigned int base;
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); base = S3C64XX_GPD(0);
s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK);
s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_I2S0_LRCLK);
s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_I2S0_DI);
s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_I2S0_D0);
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK); base = S3C64XX_GPE(0);
s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_I2S1_CDCLK);
s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_I2S1_LRCLK);
s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_I2S1_DI);
s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_I2S1_D0);
break; break;
default: default:
printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
...@@ -50,18 +39,17 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) ...@@ -50,18 +39,17 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
return 0; return 0;
} }
static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev) static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
{ {
s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_I2S_V40_DO0); s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_I2S_V40_DO1); s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2); s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK); s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPH(7), S3C64XX_GPH7_I2S_V40_CDCLK);
s3c_gpio_cfgpin(S3C64XX_GPH(8), S3C64XX_GPH8_I2S_V40_LRCLK);
s3c_gpio_cfgpin(S3C64XX_GPH(9), S3C64XX_GPH9_I2S_V40_DI);
return 0; return 0;
} }
...@@ -170,20 +158,14 @@ EXPORT_SYMBOL(s3c64xx_device_iisv4); ...@@ -170,20 +158,14 @@ EXPORT_SYMBOL(s3c64xx_device_iisv4);
static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev) static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
{ {
unsigned int base;
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK); base = S3C64XX_GPD(0);
s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_PCM0_EXTCLK);
s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_PCM0_FSYNC);
s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_PCM0_SIN);
s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_PCM0_SOUT);
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK); base = S3C64XX_GPE(0);
s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_PCM1_EXTCLK);
s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_PCM1_FSYNC);
s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_PCM1_SIN);
s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_PCM1_SOUT);
break; break;
default: default:
printk(KERN_DEBUG "Invalid PCM Controller number: %d\n", printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
...@@ -191,6 +173,7 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev) ...@@ -191,6 +173,7 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
return 0; return 0;
} }
...@@ -264,24 +247,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm1); ...@@ -264,24 +247,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm1);
static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev) static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
{ {
s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_AC97_BITCLK); return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_AC97_nRESET);
s3c_gpio_cfgpin(S3C64XX_GPD(2), S3C64XX_GPD2_AC97_SYNC);
s3c_gpio_cfgpin(S3C64XX_GPD(3), S3C64XX_GPD3_AC97_SDI);
s3c_gpio_cfgpin(S3C64XX_GPD(4), S3C64XX_GPD4_AC97_SDO);
return 0;
} }
static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev) static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
{ {
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_AC97_BITCLK); return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S3C64XX_GPE(1), S3C64XX_GPE1_AC97_nRESET);
s3c_gpio_cfgpin(S3C64XX_GPE(2), S3C64XX_GPE2_AC97_SYNC);
s3c_gpio_cfgpin(S3C64XX_GPE(3), S3C64XX_GPE3_AC97_SDI);
s3c_gpio_cfgpin(S3C64XX_GPE(4), S3C64XX_GPE4_AC97_SDO);
return 0;
} }
static struct resource s3c64xx_ac97_resource[] = { static struct resource s3c64xx_ac97_resource[] = {
......
...@@ -195,11 +195,6 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = { ...@@ -195,11 +195,6 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
.get_pull = s3c_gpio_getpull_updown, .get_pull = s3c_gpio_getpull_updown,
}; };
int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
{
return IRQ_EINT(0) + pin;
}
static struct s3c_gpio_chip gpio_2bit[] = { static struct s3c_gpio_chip gpio_2bit[] = {
{ {
.base = S3C64XX_GPF_BASE, .base = S3C64XX_GPF_BASE,
...@@ -227,12 +222,13 @@ static struct s3c_gpio_chip gpio_2bit[] = { ...@@ -227,12 +222,13 @@ static struct s3c_gpio_chip gpio_2bit[] = {
}, },
}, { }, {
.base = S3C64XX_GPN_BASE, .base = S3C64XX_GPN_BASE,
.irq_base = IRQ_EINT(0),
.config = &gpio_2bit_cfg_eint10, .config = &gpio_2bit_cfg_eint10,
.chip = { .chip = {
.base = S3C64XX_GPN(0), .base = S3C64XX_GPN(0),
.ngpio = S3C64XX_GPIO_N_NR, .ngpio = S3C64XX_GPIO_N_NR,
.label = "GPN", .label = "GPN",
.to_irq = s3c64xx_gpio2int_gpn, .to_irq = samsung_gpiolib_to_irq,
}, },
}, { }, {
.base = S3C64XX_GPO_BASE, .base = S3C64XX_GPO_BASE,
......
...@@ -15,6 +15,6 @@ ...@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H #ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H #define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xE0000000UL #define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */ #endif /* __ASM_ARCH_VMALLOC_H */
/* linux/arch/arm/mach-s3c64xx/mach-mini6410.c
*
* Copyright 2010 Darius Augulis <augulis.darius@gmail.com>
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* 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/init.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/dm9000.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/serial_core.h>
#include <linux/types.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/map.h>
#include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/regs-modem.h>
#include <mach/regs-srom.h>
#include <mach/s3c6410.h>
#include <plat/adc.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/fb.h>
#include <plat/nand.h>
#include <plat/regs-serial.h>
#include <plat/ts.h>
#include <video/platform_lcd.h>
#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
static struct s3c2410_uartcfg mini6410_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = UCON,
.ulcon = ULCON,
.ufcon = UFCON,
},
};
/* DM9000AEP 10/100 ethernet controller */
static struct resource mini6410_dm9k_resource[] = {
[0] = {
.start = S3C64XX_PA_XM0CSN1,
.end = S3C64XX_PA_XM0CSN1 + 1,
.flags = IORESOURCE_MEM
},
[1] = {
.start = S3C64XX_PA_XM0CSN1 + 4,
.end = S3C64XX_PA_XM0CSN1 + 5,
.flags = IORESOURCE_MEM
},
[2] = {
.start = S3C_EINT(7),
.end = S3C_EINT(7),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
}
};
static struct dm9000_plat_data mini6410_dm9k_pdata = {
.flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
};
static struct platform_device mini6410_device_eth = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(mini6410_dm9k_resource),
.resource = mini6410_dm9k_resource,
.dev = {
.platform_data = &mini6410_dm9k_pdata,
},
};
static struct mtd_partition mini6410_nand_part[] = {
[0] = {
.name = "uboot",
.size = SZ_1M,
.offset = 0,
},
[1] = {
.name = "kernel",
.size = SZ_2M,
.offset = SZ_1M,
},
[2] = {
.name = "rootfs",
.size = MTDPART_SIZ_FULL,
.offset = SZ_1M + SZ_2M,
},
};
static struct s3c2410_nand_set mini6410_nand_sets[] = {
[0] = {
.name = "nand",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(mini6410_nand_part),
.partitions = mini6410_nand_part,
},
};
static struct s3c2410_platform_nand mini6410_nand_info = {
.tacls = 25,
.twrph0 = 55,
.twrph1 = 40,
.nr_sets = ARRAY_SIZE(mini6410_nand_sets),
.sets = mini6410_nand_sets,
};
static struct s3c_fb_pd_win mini6410_fb_win[] = {
{
.win_mode = { /* 4.3" 480x272 */
.left_margin = 3,
.right_margin = 2,
.upper_margin = 1,
.lower_margin = 1,
.hsync_len = 40,
.vsync_len = 1,
.xres = 480,
.yres = 272,
},
.max_bpp = 32,
.default_bpp = 16,
}, {
.win_mode = { /* 7.0" 800x480 */
.left_margin = 8,
.right_margin = 13,
.upper_margin = 7,
.lower_margin = 5,
.hsync_len = 3,
.vsync_len = 1,
.xres = 800,
.yres = 480,
},
.max_bpp = 32,
.default_bpp = 16,
},
};
static struct s3c_fb_platdata mini6410_lcd_pdata __initdata = {
.setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
.win[0] = &mini6410_fb_win[0],
.vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
.vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
};
static void mini6410_lcd_power_set(struct plat_lcd_data *pd,
unsigned int power)
{
if (power)
gpio_direction_output(S3C64XX_GPE(0), 1);
else
gpio_direction_output(S3C64XX_GPE(0), 0);
}
static struct plat_lcd_data mini6410_lcd_power_data = {
.set_power = mini6410_lcd_power_set,
};
static struct platform_device mini6410_lcd_powerdev = {
.name = "platform-lcd",
.dev.parent = &s3c_device_fb.dev,
.dev.platform_data = &mini6410_lcd_power_data,
};
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
};
static struct platform_device *mini6410_devices[] __initdata = {
&mini6410_device_eth,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_ohci,
&s3c_device_nand,
&s3c_device_fb,
&mini6410_lcd_powerdev,
&s3c_device_adc,
&s3c_device_ts,
};
static void __init mini6410_map_io(void)
{
u32 tmp;
s3c64xx_init_io(NULL, 0);
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
/* set the LCD type */
tmp = __raw_readl(S3C64XX_SPCON);
tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
__raw_writel(tmp, S3C64XX_SPCON);
/* remove the LCD bypass */
tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
tmp &= ~MIFPCON_LCD_BYPASS;
__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
}
/*
* mini6410_features string
*
* 0-9 LCD configuration
*
*/
static char mini6410_features_str[12] __initdata = "0";
static int __init mini6410_features_setup(char *str)
{
if (str)
strlcpy(mini6410_features_str, str,
sizeof(mini6410_features_str));
return 1;
}
__setup("mini6410=", mini6410_features_setup);
#define FEATURE_SCREEN (1 << 0)
struct mini6410_features_t {
int done;
int lcd_index;
};
static void mini6410_parse_features(
struct mini6410_features_t *features,
const char *features_str)
{
const char *fp = features_str;
features->done = 0;
features->lcd_index = 0;
while (*fp) {
char f = *fp++;
switch (f) {
case '0'...'9': /* tft screen */
if (features->done & FEATURE_SCREEN) {
printk(KERN_INFO "MINI6410: '%c' ignored, "
"screen type already set\n", f);
} else {
int li = f - '0';
if (li >= ARRAY_SIZE(mini6410_fb_win))
printk(KERN_INFO "MINI6410: '%c' out "
"of range LCD mode\n", f);
else {
features->lcd_index = li;
}
}
features->done |= FEATURE_SCREEN;
break;
}
}
}
static void __init mini6410_machine_init(void)
{
u32 cs1;
struct mini6410_features_t features = { 0 };
printk(KERN_INFO "MINI6410: Option string mini6410=%s\n",
mini6410_features_str);
/* Parse the feature string */
mini6410_parse_features(&features, mini6410_features_str);
mini6410_lcd_pdata.win[0] = &mini6410_fb_win[features.lcd_index];
printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n",
mini6410_lcd_pdata.win[0]->win_mode.xres,
mini6410_lcd_pdata.win[0]->win_mode.yres);
s3c_nand_set_platdata(&mini6410_nand_info);
s3c_fb_set_platdata(&mini6410_lcd_pdata);
s3c24xx_ts_set_platdata(&s3c_ts_platform);
/* configure nCS1 width to 16 bits */
cs1 = __raw_readl(S3C64XX_SROM_BW) &
~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
(1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
(1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
S3C64XX_SROM_BW__NCS1__SHIFT;
__raw_writel(cs1, S3C64XX_SROM_BW);
/* set timing for nCS1 suitable for ethernet chip */
__raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
(6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
(4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
(1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
(13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
(4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
(0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
gpio_request(S3C64XX_GPF(15), "LCD power");
gpio_request(S3C64XX_GPE(0), "LCD power");
platform_add_devices(mini6410_devices, ARRAY_SIZE(mini6410_devices));
}
MACHINE_START(MINI6410, "MINI6410")
/* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
.boot_params = S3C64XX_PA_SDRAM + 0x100,
.init_irq = s3c6410_init_irq,
.map_io = mini6410_map_io,
.init_machine = mini6410_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
...@@ -12,23 +12,39 @@ ...@@ -12,23 +12,39 @@
* *
*/ */
#include <linux/kernel.h> #include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/init.h>
#include <linux/dm9000.h> #include <linux/dm9000.h>
#include <linux/serial_core.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/types.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <mach/map.h> #include <mach/map.h>
#include <mach/s3c6410.h> #include <mach/regs-fb.h>
#include <mach/regs-gpio.h>
#include <mach/regs-modem.h>
#include <mach/regs-srom.h> #include <mach/regs-srom.h>
#include <mach/s3c6410.h>
#include <plat/adc.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/devs.h> #include <plat/devs.h>
#include <plat/fb.h>
#include <plat/nand.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <plat/ts.h>
#include <video/platform_lcd.h>
#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
...@@ -99,22 +115,192 @@ static struct platform_device real6410_device_eth = { ...@@ -99,22 +115,192 @@ static struct platform_device real6410_device_eth = {
}, },
}; };
static struct s3c_fb_pd_win real6410_fb_win[] = {
{
.win_mode = { /* 4.3" 480x272 */
.left_margin = 3,
.right_margin = 2,
.upper_margin = 1,
.lower_margin = 1,
.hsync_len = 40,
.vsync_len = 1,
.xres = 480,
.yres = 272,
},
.max_bpp = 32,
.default_bpp = 16,
}, {
.win_mode = { /* 7.0" 800x480 */
.left_margin = 8,
.right_margin = 13,
.upper_margin = 7,
.lower_margin = 5,
.hsync_len = 3,
.vsync_len = 1,
.xres = 800,
.yres = 480,
},
.max_bpp = 32,
.default_bpp = 16,
},
};
static struct s3c_fb_platdata real6410_lcd_pdata __initdata = {
.setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
.win[0] = &real6410_fb_win[0],
.vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
.vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
};
static struct mtd_partition real6410_nand_part[] = {
[0] = {
.name = "uboot",
.size = SZ_1M,
.offset = 0,
},
[1] = {
.name = "kernel",
.size = SZ_2M,
.offset = SZ_1M,
},
[2] = {
.name = "rootfs",
.size = MTDPART_SIZ_FULL,
.offset = SZ_1M + SZ_2M,
},
};
static struct s3c2410_nand_set real6410_nand_sets[] = {
[0] = {
.name = "nand",
.nr_chips = 1,
.nr_partitions = ARRAY_SIZE(real6410_nand_part),
.partitions = real6410_nand_part,
},
};
static struct s3c2410_platform_nand real6410_nand_info = {
.tacls = 25,
.twrph0 = 55,
.twrph1 = 40,
.nr_sets = ARRAY_SIZE(real6410_nand_sets),
.sets = real6410_nand_sets,
};
static struct platform_device *real6410_devices[] __initdata = { static struct platform_device *real6410_devices[] __initdata = {
&real6410_device_eth, &real6410_device_eth,
&s3c_device_hsmmc0, &s3c_device_hsmmc0,
&s3c_device_hsmmc1, &s3c_device_hsmmc1,
&s3c_device_fb,
&s3c_device_nand,
&s3c_device_adc,
&s3c_device_ts,
&s3c_device_ohci,
};
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
}; };
static void __init real6410_map_io(void) static void __init real6410_map_io(void)
{ {
u32 tmp;
s3c64xx_init_io(NULL, 0); s3c64xx_init_io(NULL, 0);
s3c24xx_init_clocks(12000000); s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs)); s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs));
/* set the LCD type */
tmp = __raw_readl(S3C64XX_SPCON);
tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
__raw_writel(tmp, S3C64XX_SPCON);
/* remove the LCD bypass */
tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
tmp &= ~MIFPCON_LCD_BYPASS;
__raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
}
/*
* real6410_features string
*
* 0-9 LCD configuration
*
*/
static char real6410_features_str[12] __initdata = "0";
static int __init real6410_features_setup(char *str)
{
if (str)
strlcpy(real6410_features_str, str,
sizeof(real6410_features_str));
return 1;
}
__setup("real6410=", real6410_features_setup);
#define FEATURE_SCREEN (1 << 0)
struct real6410_features_t {
int done;
int lcd_index;
};
static void real6410_parse_features(
struct real6410_features_t *features,
const char *features_str)
{
const char *fp = features_str;
features->done = 0;
features->lcd_index = 0;
while (*fp) {
char f = *fp++;
switch (f) {
case '0'...'9': /* tft screen */
if (features->done & FEATURE_SCREEN) {
printk(KERN_INFO "REAL6410: '%c' ignored, "
"screen type already set\n", f);
} else {
int li = f - '0';
if (li >= ARRAY_SIZE(real6410_fb_win))
printk(KERN_INFO "REAL6410: '%c' out "
"of range LCD mode\n", f);
else {
features->lcd_index = li;
}
}
features->done |= FEATURE_SCREEN;
break;
}
}
} }
static void __init real6410_machine_init(void) static void __init real6410_machine_init(void)
{ {
u32 cs1; u32 cs1;
struct real6410_features_t features = { 0 };
printk(KERN_INFO "REAL6410: Option string real6410=%s\n",
real6410_features_str);
/* Parse the feature string */
real6410_parse_features(&features, real6410_features_str);
real6410_lcd_pdata.win[0] = &real6410_fb_win[features.lcd_index];
printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n",
real6410_lcd_pdata.win[0]->win_mode.xres,
real6410_lcd_pdata.win[0]->win_mode.yres);
s3c_fb_set_platdata(&real6410_lcd_pdata);
s3c_nand_set_platdata(&real6410_nand_info);
s3c24xx_ts_set_platdata(&s3c_ts_platform);
/* configure nCS1 width to 16 bits */ /* configure nCS1 width to 16 bits */
...@@ -136,6 +322,8 @@ static void __init real6410_machine_init(void) ...@@ -136,6 +322,8 @@ static void __init real6410_machine_init(void)
(4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
(0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
gpio_request(S3C64XX_GPF(15), "LCD power");
platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices)); platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices));
} }
......
...@@ -23,15 +23,6 @@ ...@@ -23,15 +23,6 @@
extern void s3c64xx_fb_gpio_setup_24bpp(void) extern void s3c64xx_fb_gpio_setup_24bpp(void)
{ {
unsigned int gpio; s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2));
s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2));
for (gpio = S3C64XX_GPI(0); gpio <= S3C64XX_GPI(15); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
for (gpio = S3C64XX_GPJ(0); gpio <= S3C64XX_GPJ(11); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
} }
...@@ -17,11 +17,11 @@ ...@@ -17,11 +17,11 @@
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <plat/ata.h>
void s3c64xx_ide_setup_gpio(void) void s3c64xx_ide_setup_gpio(void)
{ {
u32 reg; u32 reg;
u32 gpio = 0;
reg = readl(S3C_MEM_SYS_CFG) & (~0x3f); reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
...@@ -32,15 +32,12 @@ void s3c64xx_ide_setup_gpio(void) ...@@ -32,15 +32,12 @@ void s3c64xx_ide_setup_gpio(void)
s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4)); s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
/* Set XhiDATA[15:0] pins as CF Data[15:0] */ /* Set XhiDATA[15:0] pins as CF Data[15:0] */
for (gpio = S3C64XX_GPK(0); gpio <= S3C64XX_GPK(15); gpio++) s3c_gpio_cfgpin_range(S3C64XX_GPK(0), 16, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(5));
/* Set XhiADDR[2:0] pins as CF ADDR[2:0] */ /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
for (gpio = S3C64XX_GPL(0); gpio <= S3C64XX_GPL(2); gpio++) s3c_gpio_cfgpin_range(S3C64XX_GPL(0), 3, S3C_GPIO_SFN(6));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
/* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */ /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1)); s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
for (gpio = S3C64XX_GPM(0); gpio <= S3C64XX_GPM(4); gpio++) s3c_gpio_cfgpin_range(S3C64XX_GPM(0), 5, S3C_GPIO_SFN(6));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
} }
...@@ -12,23 +12,13 @@ ...@@ -12,23 +12,13 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
#include <plat/keypad.h>
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{ {
unsigned int gpio;
unsigned int end;
/* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */ /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */
end = S3C64XX_GPK(8 + rows); s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), 8 + rows, S3C_GPIO_SFN(3));
for (gpio = S3C64XX_GPK(8); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
/* Set all the necessary GPL pins to special-function 3: KP_COL[x] */ /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */
end = S3C64XX_GPL(0 + cols); s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3));
for (gpio = S3C64XX_GPL(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
} }
...@@ -24,16 +24,9 @@ ...@@ -24,16 +24,9 @@
void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
end = S3C64XX_GPG(2 + width); /* Set all the necessary GPG pins to special-function 2 */
s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
/* Set all the necessary GPG pins to special-function 0 */
for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
...@@ -44,16 +37,9 @@ void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) ...@@ -44,16 +37,9 @@ void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
end = S3C64XX_GPH(2 + width); /* Set all the necessary GPH pins to special-function 2 */
s3c_gpio_cfgrange_nopull(S3C64XX_GPH(0), 2 + width, S3C_GPIO_SFN(2));
/* Set all the necessary GPG pins to special-function 0 */
for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
...@@ -63,20 +49,9 @@ void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) ...@@ -63,20 +49,9 @@ void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{ {
unsigned int gpio; /* Set all the necessary GPH pins to special-function 3 */
unsigned int end; s3c_gpio_cfgrange_nopull(S3C64XX_GPH(6), width, S3C_GPIO_SFN(3));
end = S3C64XX_GPH(6 + width); /* Set all the necessary GPC pins to special-function 3 */
s3c_gpio_cfgrange_nopull(S3C64XX_GPC(4), 2, S3C_GPIO_SFN(3));
/* Set all the necessary GPH pins to special-function 1 */
for (gpio = S3C64XX_GPH(6); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
/* Set all the necessary GPC pins to special-function 1 */
for (gpio = S3C64XX_GPC(4); gpio < S3C64XX_GPC(6); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
} }
...@@ -11,7 +11,6 @@ if ARCH_S5P6442 ...@@ -11,7 +11,6 @@ if ARCH_S5P6442
config CPU_S5P6442 config CPU_S5P6442
bool bool
select PLAT_S5P
select S3C_PL330_DMA select S3C_PL330_DMA
help help
Enable S5P6442 CPU support Enable S5P6442 CPU support
......
...@@ -192,6 +192,11 @@ static struct clk clk_pclkd1 = { ...@@ -192,6 +192,11 @@ static struct clk clk_pclkd1 = {
.parent = &clk_hclkd1, .parent = &clk_hclkd1,
}; };
int s5p6442_clk_ip0_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
}
int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable) int s5p6442_clk_ip3_ctrl(struct clk *clk, int enable)
{ {
return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable); return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
...@@ -335,6 +340,16 @@ void __init_or_cpufreq s5p6442_setup_clocks(void) ...@@ -335,6 +340,16 @@ void __init_or_cpufreq s5p6442_setup_clocks(void)
clk_pclkd1.rate = pclkd1; clk_pclkd1.rate = pclkd1;
} }
static struct clk init_clocks_disable[] = {
{
.name = "pdma",
.id = -1,
.parent = &clk_pclkd1,
.enable = s5p6442_clk_ip0_ctrl,
.ctrlbit = (1 << 3),
},
};
static struct clk init_clocks[] = { static struct clk init_clocks[] = {
{ {
.name = "systimer", .name = "systimer",
...@@ -393,10 +408,23 @@ static struct clk *clks[] __initdata = { ...@@ -393,10 +408,23 @@ static struct clk *clks[] __initdata = {
void __init s5p6442_register_clocks(void) void __init s5p6442_register_clocks(void)
{ {
struct clk *clkptr;
int i, ret;
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
clkptr = init_clocks_disable;
for (i = 0; i < ARRAY_SIZE(init_clocks_disable); i++, clkptr++) {
ret = s3c24xx_register_clock(clkptr);
if (ret < 0) {
printk(KERN_ERR "Fail to register clock %s (%d)\n",
clkptr->name, ret);
} else
(clkptr->enable)(clkptr, 0);
}
s3c_pwmclk_init(); s3c_pwmclk_init();
} }
...@@ -21,22 +21,16 @@ ...@@ -21,22 +21,16 @@
static int s5p6442_cfg_i2s(struct platform_device *pdev) static int s5p6442_cfg_i2s(struct platform_device *pdev)
{ {
unsigned int base;
/* configure GPIO for i2s port */ /* configure GPIO for i2s port */
switch (pdev->id) { switch (pdev->id) {
case 1: case 1:
s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2)); base = S5P6442_GPC1(0);
s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(2));
break; break;
case -1: case -1:
s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2)); base = S5P6442_GPC0(0);
s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(2));
break; break;
default: default:
...@@ -44,6 +38,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev) ...@@ -44,6 +38,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
return 0; return 0;
} }
...@@ -111,21 +106,15 @@ struct platform_device s5p6442_device_iis1 = { ...@@ -111,21 +106,15 @@ struct platform_device s5p6442_device_iis1 = {
static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev) static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
{ {
unsigned int base;
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3)); base = S5P6442_GPC0(0);
s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(3));
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3)); base = S5P6442_GPC1(0);
s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(3));
break; break;
default: default:
...@@ -133,6 +122,7 @@ static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev) ...@@ -133,6 +122,7 @@ static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
return 0; return 0;
} }
......
...@@ -38,11 +38,9 @@ static int s5p6442_spi_cfg_gpio(struct platform_device *pdev) ...@@ -38,11 +38,9 @@ static int s5p6442_spi_cfg_gpio(struct platform_device *pdev)
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2)); s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6442_GPB(2), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6442_GPB(3), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6442_GPB(2), S3C_GPIO_PULL_UP); s3c_gpio_cfgall_range(S5P6442_GPB(2), 2,
s3c_gpio_setpull(S5P6442_GPB(3), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break; break;
default: default:
......
...@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5p6442_pdma_pdata = { ...@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5p6442_pdma_pdata = {
static struct platform_device s5p6442_device_pdma = { static struct platform_device s5p6442_device_pdma = {
.name = "s3c-pl330", .name = "s3c-pl330",
.id = 1, .id = -1,
.num_resources = ARRAY_SIZE(s5p6442_pdma_resource), .num_resources = ARRAY_SIZE(s5p6442_pdma_resource),
.resource = s5p6442_pdma_resource, .resource = s5p6442_pdma_resource,
.dev = { .dev = {
......
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#define S5P_CLK_DIV5 S5P_CLKREG(0x314) #define S5P_CLK_DIV5 S5P_CLKREG(0x314)
#define S5P_CLK_DIV6 S5P_CLKREG(0x318) #define S5P_CLK_DIV6 S5P_CLKREG(0x318)
#define S5P_CLKGATE_IP0 S5P_CLKREG(0x460)
#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C) #define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C)
/* CLK_OUT */ /* CLK_OUT */
......
...@@ -12,6 +12,6 @@ ...@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H #ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H #define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xE0000000UL #define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */ #endif /* __ASM_ARCH_VMALLOC_H */
...@@ -9,14 +9,12 @@ if ARCH_S5P64X0 ...@@ -9,14 +9,12 @@ if ARCH_S5P64X0
config CPU_S5P6440 config CPU_S5P6440
bool bool
select PLAT_S5P
select S3C_PL330_DMA select S3C_PL330_DMA
help help
Enable S5P6440 CPU support Enable S5P6440 CPU support
config CPU_S5P6450 config CPU_S5P6450
bool bool
select PLAT_S5P
select S3C_PL330_DMA select S3C_PL330_DMA
help help
Enable S5P6450 CPU support Enable S5P6450 CPU support
......
...@@ -79,13 +79,16 @@ static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate) ...@@ -79,13 +79,16 @@ static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
__raw_writel(epll_con, S5P64X0_EPLL_CON); __raw_writel(epll_con, S5P64X0_EPLL_CON);
__raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
clk->rate, rate);
clk->rate = rate; clk->rate = rate;
return 0; return 0;
} }
static struct clk_ops s5p6440_epll_ops = { static struct clk_ops s5p6440_epll_ops = {
.get_rate = s5p64x0_epll_get_rate, .get_rate = s5p_epll_get_rate,
.set_rate = s5p6440_epll_set_rate, .set_rate = s5p6440_epll_set_rate,
}; };
...@@ -149,6 +152,12 @@ static struct clk init_clocks_disable[] = { ...@@ -149,6 +152,12 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_hclk.clk, .parent = &clk_hclk.clk,
.enable = s5p64x0_hclk0_ctrl, .enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 8), .ctrlbit = (1 << 8),
}, {
.name = "pdma",
.id = -1,
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 12),
}, { }, {
.name = "hsmmc", .name = "hsmmc",
.id = 0, .id = 0,
...@@ -330,12 +339,6 @@ static struct clk init_clocks[] = { ...@@ -330,12 +339,6 @@ static struct clk init_clocks[] = {
.parent = &clk_hclk.clk, .parent = &clk_hclk.clk,
.enable = s5p64x0_hclk0_ctrl, .enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 21), .ctrlbit = (1 << 21),
}, {
.name = "dma",
.id = -1,
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 12),
}, { }, {
.name = "uart", .name = "uart",
.id = 0, .id = 0,
...@@ -548,7 +551,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void) ...@@ -548,7 +551,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
/* Set S5P6440 functions for clk_fout_epll */ /* Set S5P6440 functions for clk_fout_epll */
clk_fout_epll.enable = s5p64x0_epll_enable; clk_fout_epll.enable = s5p_epll_enable;
clk_fout_epll.ops = &s5p6440_epll_ops; clk_fout_epll.ops = &s5p6440_epll_ops;
clk_48m.enable = s5p64x0_clk48m_ctrl; clk_48m.enable = s5p64x0_clk48m_ctrl;
......
...@@ -80,13 +80,16 @@ static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate) ...@@ -80,13 +80,16 @@ static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
__raw_writel(epll_con, S5P64X0_EPLL_CON); __raw_writel(epll_con, S5P64X0_EPLL_CON);
__raw_writel(epll_con_k, S5P64X0_EPLL_CON_K); __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
clk->rate, rate);
clk->rate = rate; clk->rate = rate;
return 0; return 0;
} }
static struct clk_ops s5p6450_epll_ops = { static struct clk_ops s5p6450_epll_ops = {
.get_rate = s5p64x0_epll_get_rate, .get_rate = s5p_epll_get_rate,
.set_rate = s5p6450_epll_set_rate, .set_rate = s5p6450_epll_set_rate,
}; };
...@@ -185,6 +188,12 @@ static struct clk init_clocks_disable[] = { ...@@ -185,6 +188,12 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_hclk_low.clk, .parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl, .enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 3), .ctrlbit = (1 << 3),
}, {
.name = "pdma",
.id = -1,
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 12),
}, { }, {
.name = "hsmmc", .name = "hsmmc",
.id = 0, .id = 0,
...@@ -282,12 +291,6 @@ static struct clk init_clocks[] = { ...@@ -282,12 +291,6 @@ static struct clk init_clocks[] = {
.parent = &clk_hclk.clk, .parent = &clk_hclk.clk,
.enable = s5p64x0_hclk0_ctrl, .enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 21), .ctrlbit = (1 << 21),
}, {
.name = "dma",
.id = -1,
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 12),
}, { }, {
.name = "uart", .name = "uart",
.id = 0, .id = 0,
...@@ -581,7 +584,7 @@ void __init_or_cpufreq s5p6450_setup_clocks(void) ...@@ -581,7 +584,7 @@ void __init_or_cpufreq s5p6450_setup_clocks(void)
/* Set S5P6450 functions for clk_fout_epll */ /* Set S5P6450 functions for clk_fout_epll */
clk_fout_epll.enable = s5p64x0_epll_enable; clk_fout_epll.enable = s5p_epll_enable;
clk_fout_epll.ops = &s5p6450_epll_ops; clk_fout_epll.ops = &s5p6450_epll_ops;
clk_48m.enable = s5p64x0_clk48m_ctrl; clk_48m.enable = s5p64x0_clk48m_ctrl;
......
...@@ -73,24 +73,6 @@ static const u32 clock_table[][3] = { ...@@ -73,24 +73,6 @@ static const u32 clock_table[][3] = {
{L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)}, {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
}; };
int s5p64x0_epll_enable(struct clk *clk, int enable)
{
unsigned int ctrlbit = clk->ctrlbit;
unsigned int epll_con = __raw_readl(S5P64X0_EPLL_CON) & ~ctrlbit;
if (enable)
__raw_writel(epll_con | ctrlbit, S5P64X0_EPLL_CON);
else
__raw_writel(epll_con, S5P64X0_EPLL_CON);
return 0;
}
unsigned long s5p64x0_epll_get_rate(struct clk *clk)
{
return clk->rate;
}
unsigned long s5p64x0_armclk_get_rate(struct clk *clk) unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
{ {
unsigned long rate = clk_get_rate(clk->parent); unsigned long rate = clk_get_rate(clk->parent);
......
...@@ -24,13 +24,8 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev) ...@@ -24,13 +24,8 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev)
/* configure GPIO for i2s port */ /* configure GPIO for i2s port */
switch (pdev->id) { switch (pdev->id) {
case -1: case -1:
s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5)); s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6440_GPR(5), S3C_GPIO_SFN(5)); s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(5));
break; break;
default: default:
...@@ -47,13 +42,9 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev) ...@@ -47,13 +42,9 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev)
switch (pdev->id) { switch (pdev->id) {
case -1: case -1:
s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5)); s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(5)); s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(5), S3C_GPIO_SFN(5)); s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(6), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(7), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(8), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(13), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(14), S3C_GPIO_SFN(5));
break; break;
default: default:
...@@ -116,11 +107,8 @@ static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev) ...@@ -116,11 +107,8 @@ static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
{ {
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2)); s3c_gpio_cfgpin_range(S5P6440_GPR(6), 3, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6440_GPR(13), S3C_GPIO_SFN(2)); s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6440_GPR(14), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6440_GPR(8), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6440_GPR(6), S3C_GPIO_SFN(2));
break; break;
default: default:
......
...@@ -39,23 +39,15 @@ static char *s5p64x0_spi_src_clks[] = { ...@@ -39,23 +39,15 @@ static char *s5p64x0_spi_src_clks[] = {
*/ */
static int s5p6440_spi_cfg_gpio(struct platform_device *pdev) static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
{ {
unsigned int base;
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2)); base = S5P6440_GPC(0);
s3c_gpio_cfgpin(S5P6440_GPC(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6440_GPC(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6440_GPC(0), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6440_GPC(1), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6440_GPC(2), S3C_GPIO_PULL_UP);
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2)); base = S5P6440_GPC(4);
s3c_gpio_cfgpin(S5P6440_GPC(5), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6440_GPC(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6440_GPC(4), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6440_GPC(5), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6440_GPC(6), S3C_GPIO_PULL_UP);
break; break;
default: default:
...@@ -63,28 +55,23 @@ static int s5p6440_spi_cfg_gpio(struct platform_device *pdev) ...@@ -63,28 +55,23 @@ static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0; return 0;
} }
static int s5p6450_spi_cfg_gpio(struct platform_device *pdev) static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
{ {
unsigned int base;
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5P6450_GPC(0), S3C_GPIO_SFN(2)); base = S5P6450_GPC(0);
s3c_gpio_cfgpin(S5P6450_GPC(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6450_GPC(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6450_GPC(0), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6450_GPC(1), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6450_GPC(2), S3C_GPIO_PULL_UP);
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S5P6450_GPC(4), S3C_GPIO_SFN(2)); base = S5P6450_GPC(4);
s3c_gpio_cfgpin(S5P6450_GPC(5), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6450_GPC(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6450_GPC(4), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6450_GPC(5), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6450_GPC(6), S3C_GPIO_PULL_UP);
break; break;
default: default:
...@@ -92,6 +79,9 @@ static int s5p6450_spi_cfg_gpio(struct platform_device *pdev) ...@@ -92,6 +79,9 @@ static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0; return 0;
} }
......
...@@ -122,7 +122,7 @@ static struct s3c_pl330_platdata s5p6450_pdma_pdata = { ...@@ -122,7 +122,7 @@ static struct s3c_pl330_platdata s5p6450_pdma_pdata = {
static struct platform_device s5p64x0_device_pdma = { static struct platform_device s5p64x0_device_pdma = {
.name = "s3c-pl330", .name = "s3c-pl330",
.id = 0, .id = -1,
.num_resources = ARRAY_SIZE(s5p64x0_pdma_resource), .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource),
.resource = s5p64x0_pdma_resource, .resource = s5p64x0_pdma_resource,
.dev = { .dev = {
......
...@@ -60,4 +60,6 @@ ...@@ -60,4 +60,6 @@
#define ARM_DIV_RATIO_SHIFT 0 #define ARM_DIV_RATIO_SHIFT 0
#define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT) #define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT)
#define S5P_EPLL_CON S5P64X0_EPLL_CON
#endif /* __ASM_ARCH_REGS_CLOCK_H */ #endif /* __ASM_ARCH_REGS_CLOCK_H */
...@@ -15,6 +15,6 @@ ...@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H #ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H #define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xE0000000UL #define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */ #endif /* __ASM_ARCH_VMALLOC_H */
...@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */ ...@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */
void s5p6440_i2c0_cfg_gpio(struct platform_device *dev) void s5p6440_i2c0_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5P6440_GPB(5), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5P6440_GPB(5), 2,
s3c_gpio_setpull(S5P6440_GPB(5), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6440_GPB(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6440_GPB(6), S3C_GPIO_PULL_UP);
} }
void s5p6450_i2c0_cfg_gpio(struct platform_device *dev) void s5p6450_i2c0_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5P6450_GPB(5), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5P6450_GPB(5), 2,
s3c_gpio_setpull(S5P6450_GPB(5), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6450_GPB(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6450_GPB(6), S3C_GPIO_PULL_UP);
} }
void s3c_i2c0_cfg_gpio(struct platform_device *dev) { } void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
...@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */ ...@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */
void s5p6440_i2c1_cfg_gpio(struct platform_device *dev) void s5p6440_i2c1_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5P6440_GPR(9), S3C_GPIO_SFN(6)); s3c_gpio_cfgall_range(S5P6440_GPR(9), 2,
s3c_gpio_setpull(S5P6440_GPR(9), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6440_GPR(10), S3C_GPIO_SFN(6));
s3c_gpio_setpull(S5P6440_GPR(10), S3C_GPIO_PULL_UP);
} }
void s5p6450_i2c1_cfg_gpio(struct platform_device *dev) void s5p6450_i2c1_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5P6450_GPR(9), S3C_GPIO_SFN(6)); s3c_gpio_cfgall_range(S5P6450_GPR(9), 2,
s3c_gpio_setpull(S5P6450_GPR(9), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6450_GPR(10), S3C_GPIO_SFN(6));
s3c_gpio_setpull(S5P6450_GPR(10), S3C_GPIO_PULL_UP);
} }
void s3c_i2c1_cfg_gpio(struct platform_device *dev) { } void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
...@@ -9,7 +9,6 @@ if ARCH_S5PC100 ...@@ -9,7 +9,6 @@ if ARCH_S5PC100
config CPU_S5PC100 config CPU_S5PC100
bool bool
select PLAT_S5P
select S5P_EXT_INT select S5P_EXT_INT
select S3C_PL330_DMA select S3C_PL330_DMA
help help
......
...@@ -11,7 +11,7 @@ obj- := ...@@ -11,7 +11,7 @@ obj- :=
# Core support for S5PC100 system # Core support for S5PC100 system
obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o irq-gpio.o obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o gpiolib.o
obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o
obj-$(CONFIG_CPU_S5PC100) += dma.o obj-$(CONFIG_CPU_S5PC100) += dma.o
......
...@@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = { ...@@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = {
.reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 }, .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 },
}; };
static int s5pc100_epll_enable(struct clk *clk, int enable)
{
unsigned int ctrlbit = clk->ctrlbit;
unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
if (enable)
__raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
else
__raw_writel(epll_con, S5P_EPLL_CON);
return 0;
}
static unsigned long s5pc100_epll_get_rate(struct clk *clk)
{
return clk->rate;
}
static u32 epll_div[][4] = { static u32 epll_div[][4] = {
{ 32750000, 131, 3, 4 }, { 32750000, 131, 3, 4 },
{ 32768000, 131, 3, 4 }, { 32768000, 131, 3, 4 },
...@@ -341,13 +323,16 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate) ...@@ -341,13 +323,16 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
__raw_writel(epll_con, S5P_EPLL_CON); __raw_writel(epll_con, S5P_EPLL_CON);
printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
clk->rate, rate);
clk->rate = rate; clk->rate = rate;
return 0; return 0;
} }
static struct clk_ops s5pc100_epll_ops = { static struct clk_ops s5pc100_epll_ops = {
.get_rate = s5pc100_epll_get_rate, .get_rate = s5p_epll_get_rate,
.set_rate = s5pc100_epll_set_rate, .set_rate = s5pc100_epll_set_rate,
}; };
...@@ -691,55 +676,55 @@ static struct clk init_clocks_disable[] = { ...@@ -691,55 +676,55 @@ static struct clk init_clocks_disable[] = {
}, { }, {
.name = "iis", .name = "iis",
.id = 0, .id = 0,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 0), .ctrlbit = (1 << 0),
}, { }, {
.name = "iis", .name = "iis",
.id = 1, .id = 1,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 1), .ctrlbit = (1 << 1),
}, { }, {
.name = "iis", .name = "iis",
.id = 2, .id = 2,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 2), .ctrlbit = (1 << 2),
}, { }, {
.name = "ac97", .name = "ac97",
.id = -1, .id = -1,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 3), .ctrlbit = (1 << 3),
}, { }, {
.name = "pcm", .name = "pcm",
.id = 0, .id = 0,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 4), .ctrlbit = (1 << 4),
}, { }, {
.name = "pcm", .name = "pcm",
.id = 1, .id = 1,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 5), .ctrlbit = (1 << 5),
}, { }, {
.name = "spdif", .name = "spdif",
.id = -1, .id = -1,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 6), .ctrlbit = (1 << 6),
}, { }, {
.name = "adc", .name = "adc",
.id = -1, .id = -1,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 7), .ctrlbit = (1 << 7),
}, { }, {
.name = "keypad", .name = "keypad",
.id = -1, .id = -1,
.parent = &clk_div_d1_bus.clk, .parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl, .enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 8), .ctrlbit = (1 << 8),
}, { }, {
...@@ -848,6 +833,18 @@ struct clksrc_sources clk_src_group3 = { ...@@ -848,6 +833,18 @@ struct clksrc_sources clk_src_group3 = {
.nr_sources = ARRAY_SIZE(clk_src_group3_list), .nr_sources = ARRAY_SIZE(clk_src_group3_list),
}; };
static struct clksrc_clk clk_sclk_audio0 = {
.clk = {
.name = "sclk_audio",
.id = 0,
.ctrlbit = (1 << 8),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_group3,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
};
static struct clk *clk_src_group4_list[] = { static struct clk *clk_src_group4_list[] = {
[0] = &clk_mout_epll.clk, [0] = &clk_mout_epll.clk,
[1] = &clk_div_mpll.clk, [1] = &clk_div_mpll.clk,
...@@ -862,6 +859,18 @@ struct clksrc_sources clk_src_group4 = { ...@@ -862,6 +859,18 @@ struct clksrc_sources clk_src_group4 = {
.nr_sources = ARRAY_SIZE(clk_src_group4_list), .nr_sources = ARRAY_SIZE(clk_src_group4_list),
}; };
static struct clksrc_clk clk_sclk_audio1 = {
.clk = {
.name = "sclk_audio",
.id = 1,
.ctrlbit = (1 << 9),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_group4,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
};
static struct clk *clk_src_group5_list[] = { static struct clk *clk_src_group5_list[] = {
[0] = &clk_mout_epll.clk, [0] = &clk_mout_epll.clk,
[1] = &clk_div_mpll.clk, [1] = &clk_div_mpll.clk,
...@@ -875,6 +884,18 @@ struct clksrc_sources clk_src_group5 = { ...@@ -875,6 +884,18 @@ struct clksrc_sources clk_src_group5 = {
.nr_sources = ARRAY_SIZE(clk_src_group5_list), .nr_sources = ARRAY_SIZE(clk_src_group5_list),
}; };
static struct clksrc_clk clk_sclk_audio2 = {
.clk = {
.name = "sclk_audio",
.id = 2,
.ctrlbit = (1 << 10),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_group5,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
};
static struct clk *clk_src_group6_list[] = { static struct clk *clk_src_group6_list[] = {
[0] = &s5p_clk_27m, [0] = &s5p_clk_27m,
[1] = &clk_vclk54m, [1] = &clk_vclk54m,
...@@ -944,6 +965,64 @@ struct clksrc_sources clk_src_pwi = { ...@@ -944,6 +965,64 @@ struct clksrc_sources clk_src_pwi = {
.nr_sources = ARRAY_SIZE(clk_src_pwi_list), .nr_sources = ARRAY_SIZE(clk_src_pwi_list),
}; };
static struct clk *clk_sclk_spdif_list[] = {
[0] = &clk_sclk_audio0.clk,
[1] = &clk_sclk_audio1.clk,
[2] = &clk_sclk_audio2.clk,
};
struct clksrc_sources clk_src_sclk_spdif = {
.sources = clk_sclk_spdif_list,
.nr_sources = ARRAY_SIZE(clk_sclk_spdif_list),
};
static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate)
{
struct clk *pclk;
int ret;
pclk = clk_get_parent(clk);
if (IS_ERR(pclk))
return -EINVAL;
ret = pclk->ops->set_rate(pclk, rate);
clk_put(pclk);
return ret;
}
static unsigned long s5pc100_spdif_get_rate(struct clk *clk)
{
struct clk *pclk;
int rate;
pclk = clk_get_parent(clk);
if (IS_ERR(pclk))
return -EINVAL;
rate = pclk->ops->get_rate(clk);
clk_put(pclk);
return rate;
}
static struct clk_ops s5pc100_sclk_spdif_ops = {
.set_rate = s5pc100_spdif_set_rate,
.get_rate = s5pc100_spdif_get_rate,
};
static struct clksrc_clk clk_sclk_spdif = {
.clk = {
.name = "sclk_spdif",
.id = -1,
.ctrlbit = (1 << 11),
.enable = s5pc100_sclk1_ctrl,
.ops = &s5pc100_sclk_spdif_ops,
},
.sources = &clk_src_sclk_spdif,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 },
};
static struct clksrc_clk clksrcs[] = { static struct clksrc_clk clksrcs[] = {
{ {
.clk = { .clk = {
...@@ -999,39 +1078,6 @@ static struct clksrc_clk clksrcs[] = { ...@@ -999,39 +1078,6 @@ static struct clksrc_clk clksrcs[] = {
}, },
.sources = &clk_src_group6, .sources = &clk_src_group6,
.reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 }, .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 },
}, {
.clk = {
.name = "sclk_audio",
.id = 0,
.ctrlbit = (1 << 8),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_group3,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
}, {
.clk = {
.name = "sclk_audio",
.id = 1,
.ctrlbit = (1 << 9),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_group4,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
}, {
.clk = {
.name = "sclk_audio",
.id = 2,
.ctrlbit = (1 << 10),
.enable = s5pc100_sclk1_ctrl,
},
.sources = &clk_src_group5,
.reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
.reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
}, { }, {
.clk = { .clk = {
.name = "sclk_lcd", .name = "sclk_lcd",
...@@ -1179,6 +1225,10 @@ static struct clksrc_clk *sysclks[] = { ...@@ -1179,6 +1225,10 @@ static struct clksrc_clk *sysclks[] = {
&clk_div_pclkd1, &clk_div_pclkd1,
&clk_div_cam, &clk_div_cam,
&clk_div_hdmi, &clk_div_hdmi,
&clk_sclk_audio0,
&clk_sclk_audio1,
&clk_sclk_audio2,
&clk_sclk_spdif,
}; };
void __init_or_cpufreq s5pc100_setup_clocks(void) void __init_or_cpufreq s5pc100_setup_clocks(void)
...@@ -1196,7 +1246,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void) ...@@ -1196,7 +1246,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
unsigned int ptr; unsigned int ptr;
/* Set S5PC100 functions for clk_fout_epll */ /* Set S5PC100 functions for clk_fout_epll */
clk_fout_epll.enable = s5pc100_epll_enable; clk_fout_epll.enable = s5p_epll_enable;
clk_fout_epll.ops = &s5pc100_epll_ops; clk_fout_epll.ops = &s5pc100_epll_ops;
printk(KERN_DEBUG "%s: registering clocks\n", __func__); printk(KERN_DEBUG "%s: registering clocks\n", __func__);
......
...@@ -24,19 +24,11 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev) ...@@ -24,19 +24,11 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
/* configure GPIO for i2s port */ /* configure GPIO for i2s port */
switch (pdev->id) { switch (pdev->id) {
case 1: case 1:
s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(2)); s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(2));
break; break;
case 2: case 2:
s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(4)); s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(4));
break; break;
case -1: /* Dedicated pins */ case -1: /* Dedicated pins */
...@@ -144,19 +136,11 @@ static int s5pc100_pcm_cfg_gpio(struct platform_device *pdev) ...@@ -144,19 +136,11 @@ static int s5pc100_pcm_cfg_gpio(struct platform_device *pdev)
{ {
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(5)); s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5PC100_GPG3(1), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5PC100_GPG3(4), S3C_GPIO_SFN(5));
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(3)); s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(3));
break; break;
default: default:
...@@ -231,13 +215,7 @@ struct platform_device s5pc100_device_pcm1 = { ...@@ -231,13 +215,7 @@ struct platform_device s5pc100_device_pcm1 = {
static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev) static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev)
{ {
s3c_gpio_cfgpin(S5PC100_GPC(0), S3C_GPIO_SFN(4)); return s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PC100_GPC(1), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PC100_GPC(2), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PC100_GPC(3), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PC100_GPC(4), S3C_GPIO_SFN(4));
return 0;
} }
static struct resource s5pc100_ac97_resource[] = { static struct resource s5pc100_ac97_resource[] = {
...@@ -285,3 +263,57 @@ struct platform_device s5pc100_device_ac97 = { ...@@ -285,3 +263,57 @@ struct platform_device s5pc100_device_ac97 = {
.coherent_dma_mask = DMA_BIT_MASK(32), .coherent_dma_mask = DMA_BIT_MASK(32),
}, },
}; };
/* S/PDIF Controller platform_device */
static int s5pc100_spdif_cfg_gpd(struct platform_device *pdev)
{
s3c_gpio_cfgpin_range(S5PC100_GPD(5), 2, S3C_GPIO_SFN(3));
return 0;
}
static int s5pc100_spdif_cfg_gpg3(struct platform_device *pdev)
{
s3c_gpio_cfgpin_range(S5PC100_GPG3(5), 2, S3C_GPIO_SFN(3));
return 0;
}
static struct resource s5pc100_spdif_resource[] = {
[0] = {
.start = S5PC100_PA_SPDIF,
.end = S5PC100_PA_SPDIF + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPDIF,
.end = DMACH_SPDIF,
.flags = IORESOURCE_DMA,
},
};
static struct s3c_audio_pdata s5p_spdif_pdata = {
.cfg_gpio = s5pc100_spdif_cfg_gpd,
};
static u64 s5pc100_spdif_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pc100_device_spdif = {
.name = "samsung-spdif",
.id = -1,
.num_resources = ARRAY_SIZE(s5pc100_spdif_resource),
.resource = s5pc100_spdif_resource,
.dev = {
.platform_data = &s5p_spdif_pdata,
.dma_mask = &s5pc100_spdif_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
void __init s5pc100_spdif_setup_gpio(int gpio)
{
if (gpio == S5PC100_SPDIF_GPD)
s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpd;
else
s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpg3;
}
...@@ -38,30 +38,20 @@ static int s5pc100_spi_cfg_gpio(struct platform_device *pdev) ...@@ -38,30 +38,20 @@ static int s5pc100_spi_cfg_gpio(struct platform_device *pdev)
{ {
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5PC100_GPB(0), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
s3c_gpio_cfgpin(S5PC100_GPB(1), S3C_GPIO_SFN(2)); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PC100_GPB(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PC100_GPB(0), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PC100_GPB(1), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PC100_GPB(2), S3C_GPIO_PULL_UP);
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S5PC100_GPB(4), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
s3c_gpio_cfgpin(S5PC100_GPB(5), S3C_GPIO_SFN(2)); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PC100_GPB(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PC100_GPB(4), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PC100_GPB(5), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PC100_GPB(6), S3C_GPIO_PULL_UP);
break; break;
case 2: case 2:
s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3)); s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PC100_GPG3(2), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PC100_GPG3(3), S3C_GPIO_SFN(3));
s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PC100_GPG3(2), S3C_GPIO_PULL_UP); s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
s3c_gpio_setpull(S5PC100_GPG3(3), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
break; break;
default: default:
......
...@@ -81,7 +81,7 @@ static struct s3c_pl330_platdata s5pc100_pdma0_pdata = { ...@@ -81,7 +81,7 @@ static struct s3c_pl330_platdata s5pc100_pdma0_pdata = {
static struct platform_device s5pc100_device_pdma0 = { static struct platform_device s5pc100_device_pdma0 = {
.name = "s3c-pl330", .name = "s3c-pl330",
.id = 1, .id = 0,
.num_resources = ARRAY_SIZE(s5pc100_pdma0_resource), .num_resources = ARRAY_SIZE(s5pc100_pdma0_resource),
.resource = s5pc100_pdma0_resource, .resource = s5pc100_pdma0_resource,
.dev = { .dev = {
...@@ -143,7 +143,7 @@ static struct s3c_pl330_platdata s5pc100_pdma1_pdata = { ...@@ -143,7 +143,7 @@ static struct s3c_pl330_platdata s5pc100_pdma1_pdata = {
static struct platform_device s5pc100_device_pdma1 = { static struct platform_device s5pc100_device_pdma1 = {
.name = "s3c-pl330", .name = "s3c-pl330",
.id = 2, .id = 1,
.num_resources = ARRAY_SIZE(s5pc100_pdma1_resource), .num_resources = ARRAY_SIZE(s5pc100_pdma1_resource),
.resource = s5pc100_pdma1_resource, .resource = s5pc100_pdma1_resource,
.dev = { .dev = {
......
/* /* linux/arch/arm/mach-s5pc100/gpiolib.c
* arch/arm/plat-s5pc100/gpiolib.c *
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
* *
* Copyright 2009 Samsung Electronics Co * Copyright 2009 Samsung Electronics Co
* Kyungmin Park <kyungmin.park@samsung.com> * Kyungmin Park <kyungmin.park@samsung.com>
...@@ -61,30 +63,6 @@ ...@@ -61,30 +63,6 @@
* L3 8 4Bit None * L3 8 4Bit None
*/ */
static int s5pc100_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
{
return S3C_IRQ_GPIO(chip->base + offset);
}
static int s5pc100_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
{
int base;
base = chip->base - S5PC100_GPH0(0);
if (base == 0)
return IRQ_EINT(offset);
base = chip->base - S5PC100_GPH1(0);
if (base == 0)
return IRQ_EINT(8 + offset);
base = chip->base - S5PC100_GPH2(0);
if (base == 0)
return IRQ_EINT(16 + offset);
base = chip->base - S5PC100_GPH3(0);
if (base == 0)
return IRQ_EINT(24 + offset);
return -EINVAL;
}
static struct s3c_gpio_cfg gpio_cfg = { static struct s3c_gpio_cfg gpio_cfg = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit, .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown, .set_pull = s3c_gpio_setpull_updown,
...@@ -104,209 +82,150 @@ static struct s3c_gpio_cfg gpio_cfg_noint = { ...@@ -104,209 +82,150 @@ static struct s3c_gpio_cfg gpio_cfg_noint = {
.get_pull = s3c_gpio_getpull_updown, .get_pull = s3c_gpio_getpull_updown,
}; };
/*
* GPIO bank's base address given the index of the bank in the
* list of all gpio banks.
*/
#define S5PC100_BANK_BASE(bank_nr) (S5P_VA_GPIO + ((bank_nr) * 0x20))
/*
* Following are the gpio banks in S5PC100.
*
* The 'config' member when left to NULL, is initialized to the default
* structure gpio_cfg in the init function below.
*
* The 'base' member is also initialized in the init function below.
* Note: The initialization of 'base' member of s3c_gpio_chip structure
* uses the above macro and depends on the banks being listed in order here.
*/
static struct s3c_gpio_chip s5pc100_gpio_chips[] = { static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
{ {
.base = S5PC100_GPA0_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPA0(0), .base = S5PC100_GPA0(0),
.ngpio = S5PC100_GPIO_A0_NR, .ngpio = S5PC100_GPIO_A0_NR,
.label = "GPA0", .label = "GPA0",
}, },
}, { }, {
.base = S5PC100_GPA1_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPA1(0), .base = S5PC100_GPA1(0),
.ngpio = S5PC100_GPIO_A1_NR, .ngpio = S5PC100_GPIO_A1_NR,
.label = "GPA1", .label = "GPA1",
}, },
}, { }, {
.base = S5PC100_GPB_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPB(0), .base = S5PC100_GPB(0),
.ngpio = S5PC100_GPIO_B_NR, .ngpio = S5PC100_GPIO_B_NR,
.label = "GPB", .label = "GPB",
}, },
}, { }, {
.base = S5PC100_GPC_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPC(0), .base = S5PC100_GPC(0),
.ngpio = S5PC100_GPIO_C_NR, .ngpio = S5PC100_GPIO_C_NR,
.label = "GPC", .label = "GPC",
}, },
}, { }, {
.base = S5PC100_GPD_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPD(0), .base = S5PC100_GPD(0),
.ngpio = S5PC100_GPIO_D_NR, .ngpio = S5PC100_GPIO_D_NR,
.label = "GPD", .label = "GPD",
}, },
}, { }, {
.base = S5PC100_GPE0_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPE0(0), .base = S5PC100_GPE0(0),
.ngpio = S5PC100_GPIO_E0_NR, .ngpio = S5PC100_GPIO_E0_NR,
.label = "GPE0", .label = "GPE0",
}, },
}, { }, {
.base = S5PC100_GPE1_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPE1(0), .base = S5PC100_GPE1(0),
.ngpio = S5PC100_GPIO_E1_NR, .ngpio = S5PC100_GPIO_E1_NR,
.label = "GPE1", .label = "GPE1",
}, },
}, { }, {
.base = S5PC100_GPF0_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPF0(0), .base = S5PC100_GPF0(0),
.ngpio = S5PC100_GPIO_F0_NR, .ngpio = S5PC100_GPIO_F0_NR,
.label = "GPF0", .label = "GPF0",
}, },
}, { }, {
.base = S5PC100_GPF1_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPF1(0), .base = S5PC100_GPF1(0),
.ngpio = S5PC100_GPIO_F1_NR, .ngpio = S5PC100_GPIO_F1_NR,
.label = "GPF1", .label = "GPF1",
}, },
}, { }, {
.base = S5PC100_GPF2_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPF2(0), .base = S5PC100_GPF2(0),
.ngpio = S5PC100_GPIO_F2_NR, .ngpio = S5PC100_GPIO_F2_NR,
.label = "GPF2", .label = "GPF2",
}, },
}, { }, {
.base = S5PC100_GPF3_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPF3(0), .base = S5PC100_GPF3(0),
.ngpio = S5PC100_GPIO_F3_NR, .ngpio = S5PC100_GPIO_F3_NR,
.label = "GPF3", .label = "GPF3",
}, },
}, { }, {
.base = S5PC100_GPG0_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPG0(0), .base = S5PC100_GPG0(0),
.ngpio = S5PC100_GPIO_G0_NR, .ngpio = S5PC100_GPIO_G0_NR,
.label = "GPG0", .label = "GPG0",
}, },
}, { }, {
.base = S5PC100_GPG1_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPG1(0), .base = S5PC100_GPG1(0),
.ngpio = S5PC100_GPIO_G1_NR, .ngpio = S5PC100_GPIO_G1_NR,
.label = "GPG1", .label = "GPG1",
}, },
}, { }, {
.base = S5PC100_GPG2_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPG2(0), .base = S5PC100_GPG2(0),
.ngpio = S5PC100_GPIO_G2_NR, .ngpio = S5PC100_GPIO_G2_NR,
.label = "GPG2", .label = "GPG2",
}, },
}, { }, {
.base = S5PC100_GPG3_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPG3(0), .base = S5PC100_GPG3(0),
.ngpio = S5PC100_GPIO_G3_NR, .ngpio = S5PC100_GPIO_G3_NR,
.label = "GPG3", .label = "GPG3",
}, },
}, { }, {
.base = S5PC100_GPH0_BASE,
.config = &gpio_cfg_eint,
.chip = {
.base = S5PC100_GPH0(0),
.ngpio = S5PC100_GPIO_H0_NR,
.label = "GPH0",
},
}, {
.base = S5PC100_GPH1_BASE,
.config = &gpio_cfg_eint,
.chip = {
.base = S5PC100_GPH1(0),
.ngpio = S5PC100_GPIO_H1_NR,
.label = "GPH1",
},
}, {
.base = S5PC100_GPH2_BASE,
.config = &gpio_cfg_eint,
.chip = {
.base = S5PC100_GPH2(0),
.ngpio = S5PC100_GPIO_H2_NR,
.label = "GPH2",
},
}, {
.base = S5PC100_GPH3_BASE,
.config = &gpio_cfg_eint,
.chip = {
.base = S5PC100_GPH3(0),
.ngpio = S5PC100_GPIO_H3_NR,
.label = "GPH3",
},
}, {
.base = S5PC100_GPI_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPI(0), .base = S5PC100_GPI(0),
.ngpio = S5PC100_GPIO_I_NR, .ngpio = S5PC100_GPIO_I_NR,
.label = "GPI", .label = "GPI",
}, },
}, { }, {
.base = S5PC100_GPJ0_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPJ0(0), .base = S5PC100_GPJ0(0),
.ngpio = S5PC100_GPIO_J0_NR, .ngpio = S5PC100_GPIO_J0_NR,
.label = "GPJ0", .label = "GPJ0",
}, },
}, { }, {
.base = S5PC100_GPJ1_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPJ1(0), .base = S5PC100_GPJ1(0),
.ngpio = S5PC100_GPIO_J1_NR, .ngpio = S5PC100_GPIO_J1_NR,
.label = "GPJ1", .label = "GPJ1",
}, },
}, { }, {
.base = S5PC100_GPJ2_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPJ2(0), .base = S5PC100_GPJ2(0),
.ngpio = S5PC100_GPIO_J2_NR, .ngpio = S5PC100_GPIO_J2_NR,
.label = "GPJ2", .label = "GPJ2",
}, },
}, { }, {
.base = S5PC100_GPJ3_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPJ3(0), .base = S5PC100_GPJ3(0),
.ngpio = S5PC100_GPIO_J3_NR, .ngpio = S5PC100_GPIO_J3_NR,
.label = "GPJ3", .label = "GPJ3",
}, },
}, { }, {
.base = S5PC100_GPJ4_BASE,
.config = &gpio_cfg,
.chip = { .chip = {
.base = S5PC100_GPJ4(0), .base = S5PC100_GPJ4(0),
.ngpio = S5PC100_GPIO_J4_NR, .ngpio = S5PC100_GPIO_J4_NR,
.label = "GPJ4", .label = "GPJ4",
}, },
}, { }, {
.base = S5PC100_GPK0_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPK0(0), .base = S5PC100_GPK0(0),
...@@ -314,7 +233,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { ...@@ -314,7 +233,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK0", .label = "GPK0",
}, },
}, { }, {
.base = S5PC100_GPK1_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPK1(0), .base = S5PC100_GPK1(0),
...@@ -322,7 +240,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { ...@@ -322,7 +240,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK1", .label = "GPK1",
}, },
}, { }, {
.base = S5PC100_GPK2_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPK2(0), .base = S5PC100_GPK2(0),
...@@ -330,7 +247,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { ...@@ -330,7 +247,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK2", .label = "GPK2",
}, },
}, { }, {
.base = S5PC100_GPK3_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPK3(0), .base = S5PC100_GPK3(0),
...@@ -338,7 +254,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { ...@@ -338,7 +254,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK3", .label = "GPK3",
}, },
}, { }, {
.base = S5PC100_GPL0_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPL0(0), .base = S5PC100_GPL0(0),
...@@ -346,7 +261,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { ...@@ -346,7 +261,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL0", .label = "GPL0",
}, },
}, { }, {
.base = S5PC100_GPL1_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPL1(0), .base = S5PC100_GPL1(0),
...@@ -354,7 +268,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { ...@@ -354,7 +268,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL1", .label = "GPL1",
}, },
}, { }, {
.base = S5PC100_GPL2_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPL2(0), .base = S5PC100_GPL2(0),
...@@ -362,7 +275,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { ...@@ -362,7 +275,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL2", .label = "GPL2",
}, },
}, { }, {
.base = S5PC100_GPL3_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPL3(0), .base = S5PC100_GPL3(0),
...@@ -370,56 +282,72 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = { ...@@ -370,56 +282,72 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL3", .label = "GPL3",
}, },
}, { }, {
.base = S5PC100_GPL4_BASE,
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PC100_GPL4(0), .base = S5PC100_GPL4(0),
.ngpio = S5PC100_GPIO_L4_NR, .ngpio = S5PC100_GPIO_L4_NR,
.label = "GPL4", .label = "GPL4",
}, },
}, {
.base = (S5P_VA_GPIO + 0xC00),
.config = &gpio_cfg_eint,
.irq_base = IRQ_EINT(0),
.chip = {
.base = S5PC100_GPH0(0),
.ngpio = S5PC100_GPIO_H0_NR,
.label = "GPH0",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC20),
.config = &gpio_cfg_eint,
.irq_base = IRQ_EINT(8),
.chip = {
.base = S5PC100_GPH1(0),
.ngpio = S5PC100_GPIO_H1_NR,
.label = "GPH1",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC40),
.config = &gpio_cfg_eint,
.irq_base = IRQ_EINT(16),
.chip = {
.base = S5PC100_GPH2(0),
.ngpio = S5PC100_GPIO_H2_NR,
.label = "GPH2",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC60),
.config = &gpio_cfg_eint,
.irq_base = IRQ_EINT(24),
.chip = {
.base = S5PC100_GPH3(0),
.ngpio = S5PC100_GPIO_H3_NR,
.label = "GPH3",
.to_irq = samsung_gpiolib_to_irq,
},
}, },
}; };
/* FIXME move from irq-gpio.c */ static __init int s5pc100_gpiolib_init(void)
extern struct irq_chip s5pc100_gpioint;
extern void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip)
{ {
/* Interrupt */ struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
if (chip->config == &gpio_cfg) { int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
int i, irq; int gpioint_group = 0;
int i;
chip->chip.to_irq = s5pc100_gpiolib_to_irq;
for (i = 0; i < chip->chip.ngpio; i++) { for (i = 0; i < nr_chips; i++, chip++) {
irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i; if (chip->config == NULL) {
set_irq_chip(irq, &s5pc100_gpioint); chip->config = &gpio_cfg;
set_irq_data(irq, &chip->chip); chip->group = gpioint_group++;
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
} }
} else if (chip->config == &gpio_cfg_eint) { if (chip->base == NULL)
chip->chip.to_irq = s5pc100_gpiolib_to_eint; chip->base = S5PC100_BANK_BASE(i);
} }
}
static __init int s5pc100_gpiolib_init(void)
{
struct s3c_gpio_chip *chip;
int nr_chips;
chip = s5pc100_gpio_chips;
nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
for (; nr_chips > 0; nr_chips--, chip++)
s5pc100_gpiolib_link(chip);
samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips,
ARRAY_SIZE(s5pc100_gpio_chips));
/* Interrupt */ samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
set_irq_chained_handler(IRQ_GPIOINT, s5pc100_irq_gpioint_handler);
return 0; return 0;
} }
......
...@@ -146,13 +146,6 @@ enum s5p_gpio_number { ...@@ -146,13 +146,6 @@ enum s5p_gpio_number {
/* define the number of gpios we need to the one after the MP04() range */ /* define the number of gpios we need to the one after the MP04() range */
#define ARCH_NR_GPIOS (S5PC100_GPIO_END + 1) #define ARCH_NR_GPIOS (S5PC100_GPIO_END + 1)
#define EINT_MODE S3C_GPIO_SFN(0x2)
#define EINT_GPIO_0(x) S5PC100_GPH0(x)
#define EINT_GPIO_1(x) S5PC100_GPH1(x)
#define EINT_GPIO_2(x) S5PC100_GPH2(x)
#define EINT_GPIO_3(x) S5PC100_GPH3(x)
#include <asm-generic/gpio.h> #include <asm-generic/gpio.h>
#endif /* __ASM_ARCH_GPIO_H */ #endif /* __ASM_ARCH_GPIO_H */
...@@ -48,8 +48,8 @@ ...@@ -48,8 +48,8 @@
#define IRQ_SPI1 S5P_IRQ_VIC1(16) #define IRQ_SPI1 S5P_IRQ_VIC1(16)
#define IRQ_SPI2 S5P_IRQ_VIC1(17) #define IRQ_SPI2 S5P_IRQ_VIC1(17)
#define IRQ_IRDA S5P_IRQ_VIC1(18) #define IRQ_IRDA S5P_IRQ_VIC1(18)
#define IRQ_CAN0 S5P_IRQ_VIC1(19) #define IRQ_IIC2 S5P_IRQ_VIC1(19)
#define IRQ_CAN1 S5P_IRQ_VIC1(20) #define IRQ_IIC3 S5P_IRQ_VIC1(20)
#define IRQ_HSIRX S5P_IRQ_VIC1(21) #define IRQ_HSIRX S5P_IRQ_VIC1(21)
#define IRQ_HSITX S5P_IRQ_VIC1(22) #define IRQ_HSITX S5P_IRQ_VIC1(22)
#define IRQ_UHOST S5P_IRQ_VIC1(23) #define IRQ_UHOST S5P_IRQ_VIC1(23)
...@@ -100,11 +100,12 @@ ...@@ -100,11 +100,12 @@
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) #define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
#define S3C_IRQ_GPIO_BASE (IRQ_EINT(31) + 1) /* GPIO interrupt */
#define S3C_IRQ_GPIO(x) (S3C_IRQ_GPIO_BASE + (x)) #define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
#define S5P_GPIOINT_GROUP_MAXNR 21
/* Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs */ /* Set the default NR_IRQS */
#define NR_IRQS (S3C_IRQ_GPIO(320) + 1) #define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
/* Compatibility */ /* Compatibility */
#define IRQ_LCD_FIFO IRQ_LCD0 #define IRQ_LCD_FIFO IRQ_LCD0
......
...@@ -110,6 +110,8 @@ ...@@ -110,6 +110,8 @@
#define S5PC100_PA_PCM0 0xF2400000 #define S5PC100_PA_PCM0 0xF2400000
#define S5PC100_PA_PCM1 0xF2500000 #define S5PC100_PA_PCM1 0xF2500000
#define S5PC100_PA_SPDIF 0xF2600000
#define S5PC100_PA_TSADC (0xF3000000) #define S5PC100_PA_TSADC (0xF3000000)
/* KEYPAD */ /* KEYPAD */
......
...@@ -11,43 +11,6 @@ ...@@ -11,43 +11,6 @@
#include <mach/map.h> #include <mach/map.h>
/* S5PC100 */
#define S5PC100_GPIO_BASE S5P_VA_GPIO
#define S5PC100_GPA0_BASE (S5PC100_GPIO_BASE + 0x0000)
#define S5PC100_GPA1_BASE (S5PC100_GPIO_BASE + 0x0020)
#define S5PC100_GPB_BASE (S5PC100_GPIO_BASE + 0x0040)
#define S5PC100_GPC_BASE (S5PC100_GPIO_BASE + 0x0060)
#define S5PC100_GPD_BASE (S5PC100_GPIO_BASE + 0x0080)
#define S5PC100_GPE0_BASE (S5PC100_GPIO_BASE + 0x00A0)
#define S5PC100_GPE1_BASE (S5PC100_GPIO_BASE + 0x00C0)
#define S5PC100_GPF0_BASE (S5PC100_GPIO_BASE + 0x00E0)
#define S5PC100_GPF1_BASE (S5PC100_GPIO_BASE + 0x0100)
#define S5PC100_GPF2_BASE (S5PC100_GPIO_BASE + 0x0120)
#define S5PC100_GPF3_BASE (S5PC100_GPIO_BASE + 0x0140)
#define S5PC100_GPG0_BASE (S5PC100_GPIO_BASE + 0x0160)
#define S5PC100_GPG1_BASE (S5PC100_GPIO_BASE + 0x0180)
#define S5PC100_GPG2_BASE (S5PC100_GPIO_BASE + 0x01A0)
#define S5PC100_GPG3_BASE (S5PC100_GPIO_BASE + 0x01C0)
#define S5PC100_GPH0_BASE (S5PC100_GPIO_BASE + 0x0C00)
#define S5PC100_GPH1_BASE (S5PC100_GPIO_BASE + 0x0C20)
#define S5PC100_GPH2_BASE (S5PC100_GPIO_BASE + 0x0C40)
#define S5PC100_GPH3_BASE (S5PC100_GPIO_BASE + 0x0C60)
#define S5PC100_GPI_BASE (S5PC100_GPIO_BASE + 0x01E0)
#define S5PC100_GPJ0_BASE (S5PC100_GPIO_BASE + 0x0200)
#define S5PC100_GPJ1_BASE (S5PC100_GPIO_BASE + 0x0220)
#define S5PC100_GPJ2_BASE (S5PC100_GPIO_BASE + 0x0240)
#define S5PC100_GPJ3_BASE (S5PC100_GPIO_BASE + 0x0260)
#define S5PC100_GPJ4_BASE (S5PC100_GPIO_BASE + 0x0280)
#define S5PC100_GPK0_BASE (S5PC100_GPIO_BASE + 0x02A0)
#define S5PC100_GPK1_BASE (S5PC100_GPIO_BASE + 0x02C0)
#define S5PC100_GPK2_BASE (S5PC100_GPIO_BASE + 0x02E0)
#define S5PC100_GPK3_BASE (S5PC100_GPIO_BASE + 0x0300)
#define S5PC100_GPL0_BASE (S5PC100_GPIO_BASE + 0x0320)
#define S5PC100_GPL1_BASE (S5PC100_GPIO_BASE + 0x0340)
#define S5PC100_GPL2_BASE (S5PC100_GPIO_BASE + 0x0360)
#define S5PC100_GPL3_BASE (S5PC100_GPIO_BASE + 0x0380)
#define S5PC100_GPL4_BASE (S5PC100_GPIO_BASE + 0x03A0)
#define S5PC100EINT30CON (S5P_VA_GPIO + 0xE00) #define S5PC100EINT30CON (S5P_VA_GPIO + 0xE00)
#define S5P_EINT_CON(x) (S5PC100EINT30CON + ((x) * 0x4)) #define S5P_EINT_CON(x) (S5PC100EINT30CON + ((x) * 0x4))
...@@ -64,12 +27,12 @@ ...@@ -64,12 +27,12 @@
#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
/* values for S5P_EXTINT0 */ #define EINT_MODE S3C_GPIO_SFN(0x2)
#define S5P_EXTINT_LOWLEV (0x00)
#define S5P_EXTINT_HILEV (0x01) #define EINT_GPIO_0(x) S5PC100_GPH0(x)
#define S5P_EXTINT_FALLEDGE (0x02) #define EINT_GPIO_1(x) S5PC100_GPH1(x)
#define S5P_EXTINT_RISEEDGE (0x03) #define EINT_GPIO_2(x) S5PC100_GPH2(x)
#define S5P_EXTINT_BOTHEDGE (0x04) #define EINT_GPIO_3(x) S5PC100_GPH3(x)
#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */ #endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */
...@@ -12,6 +12,6 @@ ...@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H #ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H #define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END (0xe0000000UL) #define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */ #endif /* __ASM_ARCH_VMALLOC_H */
/*
* arch/arm/mach-s5pc100/irq-gpio.c
*
* Copyright (C) 2009 Samsung Electronics
*
* S5PC100 - Interrupt handling for IRQ_GPIO${group}(x)
*
* 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/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <mach/map.h>
#include <plat/gpio-cfg.h>
#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
#define CON_OFFSET 0x700
#define MASK_OFFSET 0x900
#define PEND_OFFSET 0xA00
#define CON_OFFSET_2 0xE00
#define MASK_OFFSET_2 0xF00
#define PEND_OFFSET_2 0xF40
#define GPIOINT_LEVEL_LOW 0x0
#define GPIOINT_LEVEL_HIGH 0x1
#define GPIOINT_EDGE_FALLING 0x2
#define GPIOINT_EDGE_RISING 0x3
#define GPIOINT_EDGE_BOTH 0x4
static int group_to_con_offset(int group)
{
return group << 2;
}
static int group_to_mask_offset(int group)
{
return group << 2;
}
static int group_to_pend_offset(int group)
{
return group << 2;
}
static int s5pc100_get_start(unsigned int group)
{
switch (group) {
case 0: return S5PC100_GPIO_A0_START;
case 1: return S5PC100_GPIO_A1_START;
case 2: return S5PC100_GPIO_B_START;
case 3: return S5PC100_GPIO_C_START;
case 4: return S5PC100_GPIO_D_START;
case 5: return S5PC100_GPIO_E0_START;
case 6: return S5PC100_GPIO_E1_START;
case 7: return S5PC100_GPIO_F0_START;
case 8: return S5PC100_GPIO_F1_START;
case 9: return S5PC100_GPIO_F2_START;
case 10: return S5PC100_GPIO_F3_START;
case 11: return S5PC100_GPIO_G0_START;
case 12: return S5PC100_GPIO_G1_START;
case 13: return S5PC100_GPIO_G2_START;
case 14: return S5PC100_GPIO_G3_START;
case 15: return S5PC100_GPIO_I_START;
case 16: return S5PC100_GPIO_J0_START;
case 17: return S5PC100_GPIO_J1_START;
case 18: return S5PC100_GPIO_J2_START;
case 19: return S5PC100_GPIO_J3_START;
case 20: return S5PC100_GPIO_J4_START;
default:
BUG();
}
return -EINVAL;
}
static int s5pc100_get_group(unsigned int irq)
{
irq -= S3C_IRQ_GPIO(0);
switch (irq) {
case S5PC100_GPIO_A0_START ... S5PC100_GPIO_A1_START - 1:
return 0;
case S5PC100_GPIO_A1_START ... S5PC100_GPIO_B_START - 1:
return 1;
case S5PC100_GPIO_B_START ... S5PC100_GPIO_C_START - 1:
return 2;
case S5PC100_GPIO_C_START ... S5PC100_GPIO_D_START - 1:
return 3;
case S5PC100_GPIO_D_START ... S5PC100_GPIO_E0_START - 1:
return 4;
case S5PC100_GPIO_E0_START ... S5PC100_GPIO_E1_START - 1:
return 5;
case S5PC100_GPIO_E1_START ... S5PC100_GPIO_F0_START - 1:
return 6;
case S5PC100_GPIO_F0_START ... S5PC100_GPIO_F1_START - 1:
return 7;
case S5PC100_GPIO_F1_START ... S5PC100_GPIO_F2_START - 1:
return 8;
case S5PC100_GPIO_F2_START ... S5PC100_GPIO_F3_START - 1:
return 9;
case S5PC100_GPIO_F3_START ... S5PC100_GPIO_G0_START - 1:
return 10;
case S5PC100_GPIO_G0_START ... S5PC100_GPIO_G1_START - 1:
return 11;
case S5PC100_GPIO_G1_START ... S5PC100_GPIO_G2_START - 1:
return 12;
case S5PC100_GPIO_G2_START ... S5PC100_GPIO_G3_START - 1:
return 13;
case S5PC100_GPIO_G3_START ... S5PC100_GPIO_H0_START - 1:
return 14;
case S5PC100_GPIO_I_START ... S5PC100_GPIO_J0_START - 1:
return 15;
case S5PC100_GPIO_J0_START ... S5PC100_GPIO_J1_START - 1:
return 16;
case S5PC100_GPIO_J1_START ... S5PC100_GPIO_J2_START - 1:
return 17;
case S5PC100_GPIO_J2_START ... S5PC100_GPIO_J3_START - 1:
return 18;
case S5PC100_GPIO_J3_START ... S5PC100_GPIO_J4_START - 1:
return 19;
case S5PC100_GPIO_J4_START ... S5PC100_GPIO_K0_START - 1:
return 20;
default:
BUG();
}
return -EINVAL;
}
static int s5pc100_get_offset(unsigned int irq)
{
struct gpio_chip *chip = get_irq_data(irq);
return irq - S3C_IRQ_GPIO(chip->base);
}
static void s5pc100_gpioint_ack(unsigned int irq)
{
int group, offset, pend_offset;
unsigned int value;
group = s5pc100_get_group(irq);
offset = s5pc100_get_offset(irq);
pend_offset = group_to_pend_offset(group);
value = __raw_readl(S5P_GPIOREG(PEND_OFFSET) + pend_offset);
value |= 1 << offset;
__raw_writel(value, S5P_GPIOREG(PEND_OFFSET) + pend_offset);
}
static void s5pc100_gpioint_mask(unsigned int irq)
{
int group, offset, mask_offset;
unsigned int value;
group = s5pc100_get_group(irq);
offset = s5pc100_get_offset(irq);
mask_offset = group_to_mask_offset(group);
value = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
value |= 1 << offset;
__raw_writel(value, S5P_GPIOREG(MASK_OFFSET) + mask_offset);
}
static void s5pc100_gpioint_unmask(unsigned int irq)
{
int group, offset, mask_offset;
unsigned int value;
group = s5pc100_get_group(irq);
offset = s5pc100_get_offset(irq);
mask_offset = group_to_mask_offset(group);
value = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
value &= ~(1 << offset);
__raw_writel(value, S5P_GPIOREG(MASK_OFFSET) + mask_offset);
}
static void s5pc100_gpioint_mask_ack(unsigned int irq)
{
s5pc100_gpioint_mask(irq);
s5pc100_gpioint_ack(irq);
}
static int s5pc100_gpioint_set_type(unsigned int irq, unsigned int type)
{
int group, offset, con_offset;
unsigned int value;
group = s5pc100_get_group(irq);
offset = s5pc100_get_offset(irq);
con_offset = group_to_con_offset(group);
switch (type) {
case IRQ_TYPE_NONE:
printk(KERN_WARNING "No irq type\n");
return -EINVAL;
case IRQ_TYPE_EDGE_RISING:
type = GPIOINT_EDGE_RISING;
break;
case IRQ_TYPE_EDGE_FALLING:
type = GPIOINT_EDGE_FALLING;
break;
case IRQ_TYPE_EDGE_BOTH:
type = GPIOINT_EDGE_BOTH;
break;
case IRQ_TYPE_LEVEL_HIGH:
type = GPIOINT_LEVEL_HIGH;
break;
case IRQ_TYPE_LEVEL_LOW:
type = GPIOINT_LEVEL_LOW;
break;
default:
BUG();
}
value = __raw_readl(S5P_GPIOREG(CON_OFFSET) + con_offset);
value &= ~(0xf << (offset * 0x4));
value |= (type << (offset * 0x4));
__raw_writel(value, S5P_GPIOREG(CON_OFFSET) + con_offset);
return 0;
}
struct irq_chip s5pc100_gpioint = {
.name = "GPIO",
.ack = s5pc100_gpioint_ack,
.mask = s5pc100_gpioint_mask,
.mask_ack = s5pc100_gpioint_mask_ack,
.unmask = s5pc100_gpioint_unmask,
.set_type = s5pc100_gpioint_set_type,
};
void s5pc100_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
int group, offset, pend_offset, mask_offset;
int real_irq, group_end;
unsigned int pend, mask;
group_end = 21;
for (group = 0; group < group_end; group++) {
pend_offset = group_to_pend_offset(group);
pend = __raw_readl(S5P_GPIOREG(PEND_OFFSET) + pend_offset);
if (!pend)
continue;
mask_offset = group_to_mask_offset(group);
mask = __raw_readl(S5P_GPIOREG(MASK_OFFSET) + mask_offset);
pend &= ~mask;
for (offset = 0; offset < 8; offset++) {
if (pend & (1 << offset)) {
real_irq = s5pc100_get_start(group) + offset;
generic_handle_irq(S3C_IRQ_GPIO(real_irq));
}
}
}
}
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include <plat/adc.h> #include <plat/adc.h>
#include <plat/keypad.h> #include <plat/keypad.h>
#include <plat/ts.h> #include <plat/ts.h>
#include <plat/audio.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */ /* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ #define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
...@@ -196,6 +197,7 @@ static struct platform_device *smdkc100_devices[] __initdata = { ...@@ -196,6 +197,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
&s5p_device_fimc0, &s5p_device_fimc0,
&s5p_device_fimc1, &s5p_device_fimc1,
&s5p_device_fimc2, &s5p_device_fimc2,
&s5pc100_device_spdif,
}; };
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = { static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
...@@ -226,6 +228,8 @@ static void __init smdkc100_machine_init(void) ...@@ -226,6 +228,8 @@ static void __init smdkc100_machine_init(void)
samsung_keypad_set_platdata(&smdkc100_keypad_data); samsung_keypad_set_platdata(&smdkc100_keypad_data);
s5pc100_spdif_setup_gpio(S5PC100_SPDIF_GPD);
/* LCD init */ /* LCD init */
gpio_request(S5PC100_GPD(0), "GPD"); gpio_request(S5PC100_GPD(0), "GPD");
gpio_request(S5PC100_GPH0(6), "GPH0"); gpio_request(S5PC100_GPH0(6), "GPH0");
......
...@@ -22,27 +22,15 @@ ...@@ -22,27 +22,15 @@
#define DISR_OFFSET 0x7008 #define DISR_OFFSET 0x7008
void s5pc100_fb_gpio_setup_24bpp(void) static void s5pc100_fb_setgpios(unsigned int base, unsigned int nr)
{ {
unsigned int gpio = 0; s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
}
for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) { void s5pc100_fb_gpio_setup_24bpp(void)
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); {
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); s5pc100_fb_setgpios(S5PC100_GPF0(0), 8);
} s5pc100_fb_setgpios(S5PC100_GPF1(0), 8);
s5pc100_fb_setgpios(S5PC100_GPF2(0), 8);
s5pc100_fb_setgpios(S5PC100_GPF3(0), 4);
} }
...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */ ...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev) void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PC100_GPD(3), 2,
s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
} }
...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */ ...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev) void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PC100_GPD(5), 2,
s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
} }
...@@ -17,52 +17,39 @@ ...@@ -17,52 +17,39 @@
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
static void s5pc100_ide_cfg_gpios(unsigned int base, unsigned int nr)
{
s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
for (; nr > 0; nr--, base++)
s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
}
void s5pc100_ide_setup_gpio(void) void s5pc100_ide_setup_gpio(void)
{ {
u32 reg; u32 reg;
u32 gpio = 0;
/* Independent CF interface, CF chip select configuration */ /* Independent CF interface, CF chip select configuration */
reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f); reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f);
writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG); writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG);
/* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */ /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
for (gpio = S5PC100_GPJ0(0); gpio <= S5PC100_GPJ0(7); gpio++) { s5pc100_ide_cfg_gpios(S5PC100_GPJ0(0), 8);
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
/*CF_Data[0 - 7] */ /*CF_Data[0 - 7] */
for (gpio = S5PC100_GPJ2(0); gpio <= S5PC100_GPJ2(7); gpio++) { s5pc100_ide_cfg_gpios(S5PC100_GPJ2(0), 8);
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
/* CF_Data[8 - 15] */ /* CF_Data[8 - 15] */
for (gpio = S5PC100_GPJ3(0); gpio <= S5PC100_GPJ3(7); gpio++) { s5pc100_ide_cfg_gpios(S5PC100_GPJ3(0), 8);
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
/* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */ /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
for (gpio = S5PC100_GPJ4(0); gpio <= S5PC100_GPJ4(3); gpio++) { s5pc100_ide_cfg_gpios(S5PC100_GPJ4(0), 4);
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
/* EBI_OE, EBI_WE */ /* EBI_OE, EBI_WE */
for (gpio = S5PC100_GPK0(6); gpio <= S5PC100_GPK0(7); gpio++) s3c_gpio_cfgpin_range(S5PC100_GPK0(6), 2, S3C_GPIO_SFN(0));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0));
/* CF_OE, CF_WE */ /* CF_OE, CF_WE */
for (gpio = S5PC100_GPK1(6); gpio <= S5PC100_GPK1(7); gpio++) { s3c_gpio_cfgrange_nopull(S5PC100_GPK1(6), 8, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
/* CF_CD */ /* CF_CD */
s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2)); s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2));
......
...@@ -15,20 +15,9 @@ ...@@ -15,20 +15,9 @@
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{ {
unsigned int gpio;
unsigned int end;
/* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */ /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
end = S5PC100_GPH3(rows); s3c_gpio_cfgrange_nopull(S5PC100_GPH3(0), rows, S3C_GPIO_SFN(3));
for (gpio = S5PC100_GPH3(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
/* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */ /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
end = S5PC100_GPH2(cols); s3c_gpio_cfgrange_nopull(S5PC100_GPH2(0), cols, S3C_GPIO_SFN(3));
for (gpio = S5PC100_GPH2(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
} }
...@@ -25,8 +25,6 @@ ...@@ -25,8 +25,6 @@
void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
unsigned int num; unsigned int num;
num = width; num = width;
...@@ -34,20 +32,11 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) ...@@ -34,20 +32,11 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
if (width == 8) if (width == 8)
num = width - 2; num = width - 2;
end = S5PC100_GPG0(2 + num);
/* Set all the necessary GPG0/GPG1 pins to special-function 0 */ /* Set all the necessary GPG0/GPG1 pins to special-function 0 */
for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) { s3c_gpio_cfgrange_nopull(S5PC100_GPG0(0), 2 + num, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
if (width == 8) { if (width == 8)
for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) { s3c_gpio_cfgrange_nopull(S5PC100_GPG1(0), 2, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
...@@ -58,16 +47,9 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) ...@@ -58,16 +47,9 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
end = S5PC100_GPG2(2 + width);
/* Set all the necessary GPG2 pins to special-function 2 */ /* Set all the necessary GPG2 pins to special-function 2 */
for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) { s3c_gpio_cfgrange_nopull(S5PC100_GPG2(0), 2 + width, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
...@@ -78,16 +60,9 @@ void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) ...@@ -78,16 +60,9 @@ void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
end = S5PC100_GPG3(2 + width);
/* Set all the necessary GPG3 pins to special-function 2 */ /* Set all the necessary GPG3 pins to special-function 2 */
for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) { s3c_gpio_cfgrange_nopull(S5PC100_GPG3(0), 2 + width, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
......
...@@ -11,9 +11,9 @@ if ARCH_S5PV210 ...@@ -11,9 +11,9 @@ if ARCH_S5PV210
config CPU_S5PV210 config CPU_S5PV210
bool bool
select PLAT_S5P
select S3C_PL330_DMA select S3C_PL330_DMA
select S5P_EXT_INT select S5P_EXT_INT
select S5PV210_PM if PM
help help
Enable S5PV210 CPU support Enable S5PV210 CPU support
...@@ -58,7 +58,6 @@ menu "S5PC110 Machines" ...@@ -58,7 +58,6 @@ menu "S5PC110 Machines"
config MACH_AQUILA config MACH_AQUILA
bool "Aquila" bool "Aquila"
select CPU_S5PV210 select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_FB select S3C_DEV_FB
select S5P_DEV_FIMC0 select S5P_DEV_FIMC0
select S5P_DEV_FIMC1 select S5P_DEV_FIMC1
...@@ -75,7 +74,7 @@ config MACH_AQUILA ...@@ -75,7 +74,7 @@ config MACH_AQUILA
config MACH_GONI config MACH_GONI
bool "GONI" bool "GONI"
select CPU_S5PV210 select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE select S5P_GPIO_INT
select S3C_DEV_FB select S3C_DEV_FB
select S5P_DEV_FIMC0 select S5P_DEV_FIMC0
select S5P_DEV_FIMC1 select S5P_DEV_FIMC1
...@@ -83,8 +82,15 @@ config MACH_GONI ...@@ -83,8 +82,15 @@ config MACH_GONI
select S3C_DEV_HSMMC select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC2
select S3C_DEV_I2C1
select S3C_DEV_I2C2
select S3C_DEV_USB_HSOTG
select S5P_DEV_ONENAND select S5P_DEV_ONENAND
select SAMSUNG_DEV_KEYPAD
select S5PV210_SETUP_FB_24BPP select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_I2C1
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_KEYPAD
select S5PV210_SETUP_SDHCI select S5PV210_SETUP_SDHCI
help help
Machine support for Samsung GONI board Machine support for Samsung GONI board
...@@ -93,7 +99,6 @@ config MACH_GONI ...@@ -93,7 +99,6 @@ config MACH_GONI
config MACH_SMDKC110 config MACH_SMDKC110
bool "SMDKC110" bool "SMDKC110"
select CPU_S5PV210 select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_I2C1 select S3C_DEV_I2C1
select S3C_DEV_I2C2 select S3C_DEV_I2C2
select S3C_DEV_RTC select S3C_DEV_RTC
...@@ -113,7 +118,6 @@ menu "S5PV210 Machines" ...@@ -113,7 +118,6 @@ menu "S5PV210 Machines"
config MACH_SMDKV210 config MACH_SMDKV210
bool "SMDKV210" bool "SMDKV210"
select CPU_S5PV210 select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_HSMMC select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC2
...@@ -134,6 +138,29 @@ config MACH_SMDKV210 ...@@ -134,6 +138,29 @@ config MACH_SMDKV210
help help
Machine support for Samsung SMDKV210 Machine support for Samsung SMDKV210
config MACH_TORBRECK
bool "Torbreck"
select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
select S3C_DEV_I2C1
select S3C_DEV_I2C2
select S3C_DEV_RTC
select S3C_DEV_WDT
select S5PV210_SETUP_I2C1
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_SDHCI
help
Machine support for aESOP Torbreck
endmenu endmenu
config S5PV210_PM
bool
help
Power Management code common to S5PV210
endif endif
...@@ -14,6 +14,8 @@ obj- := ...@@ -14,6 +14,8 @@ obj- :=
obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o
obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
# machine support # machine support
...@@ -21,6 +23,7 @@ obj-$(CONFIG_MACH_AQUILA) += mach-aquila.o ...@@ -21,6 +23,7 @@ obj-$(CONFIG_MACH_AQUILA) += mach-aquila.o
obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o
obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o
obj-$(CONFIG_MACH_GONI) += mach-goni.o obj-$(CONFIG_MACH_GONI) += mach-goni.o
obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o
# device support # device support
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <plat/clock-clksrc.h> #include <plat/clock-clksrc.h>
#include <plat/s5pv210.h> #include <plat/s5pv210.h>
static unsigned long xtal;
static struct clksrc_clk clk_mout_apll = { static struct clksrc_clk clk_mout_apll = {
.clk = { .clk = {
.name = "mout_apll", .name = "mout_apll",
...@@ -259,6 +261,36 @@ static struct clksrc_clk clk_sclk_vpll = { ...@@ -259,6 +261,36 @@ static struct clksrc_clk clk_sclk_vpll = {
.reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 }, .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
}; };
static struct clk *clkset_moutdmc0src_list[] = {
[0] = &clk_sclk_a2m.clk,
[1] = &clk_mout_mpll.clk,
[2] = NULL,
[3] = NULL,
};
static struct clksrc_sources clkset_moutdmc0src = {
.sources = clkset_moutdmc0src_list,
.nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list),
};
static struct clksrc_clk clk_mout_dmc0 = {
.clk = {
.name = "mout_dmc0",
.id = -1,
},
.sources = &clkset_moutdmc0src,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
};
static struct clksrc_clk clk_sclk_dmc0 = {
.clk = {
.name = "sclk_dmc0",
.id = -1,
.parent = &clk_mout_dmc0.clk,
},
.reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
};
static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk) static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
{ {
return clk_get_rate(clk->parent) / 2; return clk_get_rate(clk->parent) / 2;
...@@ -268,8 +300,29 @@ static struct clk_ops clk_hclk_imem_ops = { ...@@ -268,8 +300,29 @@ static struct clk_ops clk_hclk_imem_ops = {
.get_rate = s5pv210_clk_imem_get_rate, .get_rate = s5pv210_clk_imem_get_rate,
}; };
static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
{
return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
}
static struct clk_ops clk_fout_apll_ops = {
.get_rate = s5pv210_clk_fout_apll_get_rate,
};
static struct clk init_clocks_disable[] = { static struct clk init_clocks_disable[] = {
{ {
.name = "pdma",
.id = 0,
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip0_ctrl,
.ctrlbit = (1 << 3),
}, {
.name = "pdma",
.id = 1,
.parent = &clk_hclk_psys.clk,
.enable = s5pv210_clk_ip0_ctrl,
.ctrlbit = (1 << 4),
}, {
.name = "rot", .name = "rot",
.id = -1, .id = -1,
.parent = &clk_hclk_dsys.clk, .parent = &clk_hclk_dsys.clk,
...@@ -431,6 +484,12 @@ static struct clk init_clocks_disable[] = { ...@@ -431,6 +484,12 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_p, .parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl, .enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 6), .ctrlbit = (1 << 6),
}, {
.name = "spdif",
.id = -1,
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.ctrlbit = (1 << 0),
}, },
}; };
...@@ -660,6 +719,53 @@ static struct clksrc_sources clkset_sclk_spdif = { ...@@ -660,6 +719,53 @@ static struct clksrc_sources clkset_sclk_spdif = {
.nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list), .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
}; };
static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate)
{
struct clk *pclk;
int ret;
pclk = clk_get_parent(clk);
if (IS_ERR(pclk))
return -EINVAL;
ret = pclk->ops->set_rate(pclk, rate);
clk_put(pclk);
return ret;
}
static unsigned long s5pv210_spdif_get_rate(struct clk *clk)
{
struct clk *pclk;
int rate;
pclk = clk_get_parent(clk);
if (IS_ERR(pclk))
return -EINVAL;
rate = pclk->ops->get_rate(clk);
clk_put(pclk);
return rate;
}
static struct clk_ops s5pv210_sclk_spdif_ops = {
.set_rate = s5pv210_spdif_set_rate,
.get_rate = s5pv210_spdif_get_rate,
};
static struct clksrc_clk clk_sclk_spdif = {
.clk = {
.name = "sclk_spdif",
.id = -1,
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 27),
.ops = &s5pv210_sclk_spdif_ops,
},
.sources = &clkset_sclk_spdif,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
};
static struct clk *clkset_group2_list[] = { static struct clk *clkset_group2_list[] = {
[0] = &clk_ext_xtal_mux, [0] = &clk_ext_xtal_mux,
[1] = &clk_xusbxti, [1] = &clk_xusbxti,
...@@ -743,15 +849,6 @@ static struct clksrc_clk clksrcs[] = { ...@@ -743,15 +849,6 @@ static struct clksrc_clk clksrcs[] = {
}, },
.sources = &clkset_sclk_mixer, .sources = &clkset_sclk_mixer,
.reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
}, {
.clk = {
.name = "sclk_spdif",
.id = -1,
.enable = s5pv210_clk_mask0_ctrl,
.ctrlbit = (1 << 27),
},
.sources = &clkset_sclk_spdif,
.reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
}, { }, {
.clk = { .clk = {
.name = "sclk_fimc", .name = "sclk_fimc",
...@@ -953,12 +1050,93 @@ static struct clksrc_clk *sysclks[] = { ...@@ -953,12 +1050,93 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_dac, &clk_sclk_dac,
&clk_sclk_pixel, &clk_sclk_pixel,
&clk_sclk_hdmi, &clk_sclk_hdmi,
&clk_mout_dmc0,
&clk_sclk_dmc0,
&clk_sclk_audio0,
&clk_sclk_audio1,
&clk_sclk_audio2,
&clk_sclk_spdif,
};
static u32 epll_div[][6] = {
{ 48000000, 0, 48, 3, 3, 0 },
{ 96000000, 0, 48, 3, 2, 0 },
{ 144000000, 1, 72, 3, 2, 0 },
{ 192000000, 0, 48, 3, 1, 0 },
{ 288000000, 1, 72, 3, 1, 0 },
{ 32750000, 1, 65, 3, 4, 35127 },
{ 32768000, 1, 65, 3, 4, 35127 },
{ 45158400, 0, 45, 3, 3, 10355 },
{ 45000000, 0, 45, 3, 3, 10355 },
{ 45158000, 0, 45, 3, 3, 10355 },
{ 49125000, 0, 49, 3, 3, 9961 },
{ 49152000, 0, 49, 3, 3, 9961 },
{ 67737600, 1, 67, 3, 3, 48366 },
{ 67738000, 1, 67, 3, 3, 48366 },
{ 73800000, 1, 73, 3, 3, 47710 },
{ 73728000, 1, 73, 3, 3, 47710 },
{ 36000000, 1, 32, 3, 4, 0 },
{ 60000000, 1, 60, 3, 3, 0 },
{ 72000000, 1, 72, 3, 3, 0 },
{ 80000000, 1, 80, 3, 3, 0 },
{ 84000000, 0, 42, 3, 2, 0 },
{ 50000000, 0, 50, 3, 3, 0 },
};
static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
{
unsigned int epll_con, epll_con_k;
unsigned int i;
/* Return if nothing changed */
if (clk->rate == rate)
return 0;
epll_con = __raw_readl(S5P_EPLL_CON);
epll_con_k = __raw_readl(S5P_EPLL_CON1);
epll_con_k &= ~PLL46XX_KDIV_MASK;
epll_con &= ~(1 << 27 |
PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
if (epll_div[i][0] == rate) {
epll_con_k |= epll_div[i][5] << 0;
epll_con |= (epll_div[i][1] << 27 |
epll_div[i][2] << PLL46XX_MDIV_SHIFT |
epll_div[i][3] << PLL46XX_PDIV_SHIFT |
epll_div[i][4] << PLL46XX_SDIV_SHIFT);
break;
}
}
if (i == ARRAY_SIZE(epll_div)) {
printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
__func__);
return -EINVAL;
}
__raw_writel(epll_con, S5P_EPLL_CON);
__raw_writel(epll_con_k, S5P_EPLL_CON1);
printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
clk->rate, rate);
clk->rate = rate;
return 0;
}
static struct clk_ops s5pv210_epll_ops = {
.set_rate = s5pv210_epll_set_rate,
.get_rate = s5p_epll_get_rate,
}; };
void __init_or_cpufreq s5pv210_setup_clocks(void) void __init_or_cpufreq s5pv210_setup_clocks(void)
{ {
struct clk *xtal_clk; struct clk *xtal_clk;
unsigned long xtal;
unsigned long vpllsrc; unsigned long vpllsrc;
unsigned long armclk; unsigned long armclk;
unsigned long hclk_msys; unsigned long hclk_msys;
...@@ -974,6 +1152,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) ...@@ -974,6 +1152,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
unsigned int ptr; unsigned int ptr;
u32 clkdiv0, clkdiv1; u32 clkdiv0, clkdiv1;
/* Set functions for clk_fout_epll */
clk_fout_epll.enable = s5p_epll_enable;
clk_fout_epll.ops = &s5pv210_epll_ops;
printk(KERN_DEBUG "%s: registering clocks\n", __func__); printk(KERN_DEBUG "%s: registering clocks\n", __func__);
clkdiv0 = __raw_readl(S5P_CLK_DIV0); clkdiv0 = __raw_readl(S5P_CLK_DIV0);
...@@ -992,11 +1174,12 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) ...@@ -992,11 +1174,12 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508); apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502); mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500); epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
__raw_readl(S5P_EPLL_CON1), pll_4600);
vpllsrc = clk_get_rate(&clk_vpllsrc.clk); vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502); vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
clk_fout_apll.rate = apll; clk_fout_apll.ops = &clk_fout_apll_ops;
clk_fout_mpll.rate = mpll; clk_fout_mpll.rate = mpll;
clk_fout_epll.rate = epll; clk_fout_epll.rate = epll;
clk_fout_vpll.rate = vpll; clk_fout_vpll.rate = vpll;
......
...@@ -85,6 +85,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = { ...@@ -85,6 +85,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S5PV210_PA_SROMC), .pfn = __phys_to_pfn(S5PV210_PA_SROMC),
.length = SZ_4K, .length = SZ_4K,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_DMC0,
.pfn = __phys_to_pfn(S5PV210_PA_DMC0),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_DMC1,
.pfn = __phys_to_pfn(S5PV210_PA_DMC1),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_USB_HSPHY,
.pfn =__phys_to_pfn(S5PV210_PA_HSPHY),
.length = SZ_4K,
.type = MT_DEVICE,
} }
}; };
......
/* linux/arch/arm/mach-s5pv210/cpufreq.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* CPU frequency scaling for S5PC110/S5PV210
*
* 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/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/cpufreq.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
static struct clk *cpu_clk;
static struct clk *dmc0_clk;
static struct clk *dmc1_clk;
static struct cpufreq_freqs freqs;
/* APLL M,P,S values for 1G/800Mhz */
#define APLL_VAL_1000 ((1 << 31) | (125 << 16) | (3 << 8) | 1)
#define APLL_VAL_800 ((1 << 31) | (100 << 16) | (3 << 8) | 1)
/*
* DRAM configurations to calculate refresh counter for changing
* frequency of memory.
*/
struct dram_conf {
unsigned long freq; /* HZ */
unsigned long refresh; /* DRAM refresh counter * 1000 */
};
/* DRAM configuration (DMC0 and DMC1) */
static struct dram_conf s5pv210_dram_conf[2];
enum perf_level {
L0, L1, L2, L3, L4,
};
enum s5pv210_mem_type {
LPDDR = 0x1,
LPDDR2 = 0x2,
DDR2 = 0x4,
};
enum s5pv210_dmc_port {
DMC0 = 0,
DMC1,
};
static struct cpufreq_frequency_table s5pv210_freq_table[] = {
{L0, 1000*1000},
{L1, 800*1000},
{L2, 400*1000},
{L3, 200*1000},
{L4, 100*1000},
{0, CPUFREQ_TABLE_END},
};
static u32 clkdiv_val[5][11] = {
/*
* Clock divider value for following
* { APLL, A2M, HCLK_MSYS, PCLK_MSYS,
* HCLK_DSYS, PCLK_DSYS, HCLK_PSYS, PCLK_PSYS,
* ONEDRAM, MFC, G3D }
*/
/* L0 : [1000/200/100][166/83][133/66][200/200] */
{0, 4, 4, 1, 3, 1, 4, 1, 3, 0, 0},
/* L1 : [800/200/100][166/83][133/66][200/200] */
{0, 3, 3, 1, 3, 1, 4, 1, 3, 0, 0},
/* L2 : [400/200/100][166/83][133/66][200/200] */
{1, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
/* L3 : [200/200/100][166/83][133/66][200/200] */
{3, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
/* L4 : [100/100/100][83/83][66/66][100/100] */
{7, 7, 0, 0, 7, 0, 9, 0, 7, 0, 0},
};
/*
* This function set DRAM refresh counter
* accoriding to operating frequency of DRAM
* ch: DMC port number 0 or 1
* freq: Operating frequency of DRAM(KHz)
*/
static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
{
unsigned long tmp, tmp1;
void __iomem *reg = NULL;
if (ch == DMC0)
reg = (S5P_VA_DMC0 + 0x30);
else if (ch == DMC1)
reg = (S5P_VA_DMC1 + 0x30);
else
printk(KERN_ERR "Cannot find DMC port\n");
/* Find current DRAM frequency */
tmp = s5pv210_dram_conf[ch].freq;
do_div(tmp, freq);
tmp1 = s5pv210_dram_conf[ch].refresh;
do_div(tmp1, tmp);
__raw_writel(tmp1, reg);
}
int s5pv210_verify_speed(struct cpufreq_policy *policy)
{
if (policy->cpu)
return -EINVAL;
return cpufreq_frequency_table_verify(policy, s5pv210_freq_table);
}
unsigned int s5pv210_getspeed(unsigned int cpu)
{
if (cpu)
return 0;
return clk_get_rate(cpu_clk) / 1000;
}
static int s5pv210_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned long reg;
unsigned int index, priv_index;
unsigned int pll_changing = 0;
unsigned int bus_speed_changing = 0;
freqs.old = s5pv210_getspeed(0);
if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
target_freq, relation, &index))
return -EINVAL;
freqs.new = s5pv210_freq_table[index].frequency;
freqs.cpu = 0;
if (freqs.new == freqs.old)
return 0;
/* Finding current running level index */
if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
freqs.old, relation, &priv_index))
return -EINVAL;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
if (freqs.new > freqs.old) {
/* Voltage up: will be implemented */
}
/* Check if there need to change PLL */
if ((index == L0) || (priv_index == L0))
pll_changing = 1;
/* Check if there need to change System bus clock */
if ((index == L4) || (priv_index == L4))
bus_speed_changing = 1;
if (bus_speed_changing) {
/*
* Reconfigure DRAM refresh counter value for minimum
* temporary clock while changing divider.
* expected clock is 83Mhz : 7.8usec/(1/83Mhz) = 0x287
*/
if (pll_changing)
s5pv210_set_refresh(DMC1, 83000);
else
s5pv210_set_refresh(DMC1, 100000);
s5pv210_set_refresh(DMC0, 83000);
}
/*
* APLL should be changed in this level
* APLL -> MPLL(for stable transition) -> APLL
* Some clock source's clock API are not prepared.
* Do not use clock API in below code.
*/
if (pll_changing) {
/*
* 1. Temporary Change divider for MFC and G3D
* SCLKA2M(200/1=200)->(200/4=50)Mhz
*/
reg = __raw_readl(S5P_CLK_DIV2);
reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
reg |= (3 << S5P_CLKDIV2_G3D_SHIFT) |
(3 << S5P_CLKDIV2_MFC_SHIFT);
__raw_writel(reg, S5P_CLK_DIV2);
/* For MFC, G3D dividing */
do {
reg = __raw_readl(S5P_CLKDIV_STAT0);
} while (reg & ((1 << 16) | (1 << 17)));
/*
* 2. Change SCLKA2M(200Mhz)to SCLKMPLL in MFC_MUX, G3D MUX
* (200/4=50)->(667/4=166)Mhz
*/
reg = __raw_readl(S5P_CLK_SRC2);
reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
reg |= (1 << S5P_CLKSRC2_G3D_SHIFT) |
(1 << S5P_CLKSRC2_MFC_SHIFT);
__raw_writel(reg, S5P_CLK_SRC2);
do {
reg = __raw_readl(S5P_CLKMUX_STAT1);
} while (reg & ((1 << 7) | (1 << 3)));
/*
* 3. DMC1 refresh count for 133Mhz if (index == L4) is
* true refresh counter is already programed in upper
* code. 0x287@83Mhz
*/
if (!bus_speed_changing)
s5pv210_set_refresh(DMC1, 133000);
/* 4. SCLKAPLL -> SCLKMPLL */
reg = __raw_readl(S5P_CLK_SRC0);
reg &= ~(S5P_CLKSRC0_MUX200_MASK);
reg |= (0x1 << S5P_CLKSRC0_MUX200_SHIFT);
__raw_writel(reg, S5P_CLK_SRC0);
do {
reg = __raw_readl(S5P_CLKMUX_STAT0);
} while (reg & (0x1 << 18));
}
/* Change divider */
reg = __raw_readl(S5P_CLK_DIV0);
reg &= ~(S5P_CLKDIV0_APLL_MASK | S5P_CLKDIV0_A2M_MASK |
S5P_CLKDIV0_HCLK200_MASK | S5P_CLKDIV0_PCLK100_MASK |
S5P_CLKDIV0_HCLK166_MASK | S5P_CLKDIV0_PCLK83_MASK |
S5P_CLKDIV0_HCLK133_MASK | S5P_CLKDIV0_PCLK66_MASK);
reg |= ((clkdiv_val[index][0] << S5P_CLKDIV0_APLL_SHIFT) |
(clkdiv_val[index][1] << S5P_CLKDIV0_A2M_SHIFT) |
(clkdiv_val[index][2] << S5P_CLKDIV0_HCLK200_SHIFT) |
(clkdiv_val[index][3] << S5P_CLKDIV0_PCLK100_SHIFT) |
(clkdiv_val[index][4] << S5P_CLKDIV0_HCLK166_SHIFT) |
(clkdiv_val[index][5] << S5P_CLKDIV0_PCLK83_SHIFT) |
(clkdiv_val[index][6] << S5P_CLKDIV0_HCLK133_SHIFT) |
(clkdiv_val[index][7] << S5P_CLKDIV0_PCLK66_SHIFT));
__raw_writel(reg, S5P_CLK_DIV0);
do {
reg = __raw_readl(S5P_CLKDIV_STAT0);
} while (reg & 0xff);
/* ARM MCS value changed */
reg = __raw_readl(S5P_ARM_MCS_CON);
reg &= ~0x3;
if (index >= L3)
reg |= 0x3;
else
reg |= 0x1;
__raw_writel(reg, S5P_ARM_MCS_CON);
if (pll_changing) {
/* 5. Set Lock time = 30us*24Mhz = 0x2cf */
__raw_writel(0x2cf, S5P_APLL_LOCK);
/*
* 6. Turn on APLL
* 6-1. Set PMS values
* 6-2. Wait untile the PLL is locked
*/
if (index == L0)
__raw_writel(APLL_VAL_1000, S5P_APLL_CON);
else
__raw_writel(APLL_VAL_800, S5P_APLL_CON);
do {
reg = __raw_readl(S5P_APLL_CON);
} while (!(reg & (0x1 << 29)));
/*
* 7. Change souce clock from SCLKMPLL(667Mhz)
* to SCLKA2M(200Mhz) in MFC_MUX and G3D MUX
* (667/4=166)->(200/4=50)Mhz
*/
reg = __raw_readl(S5P_CLK_SRC2);
reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
reg |= (0 << S5P_CLKSRC2_G3D_SHIFT) |
(0 << S5P_CLKSRC2_MFC_SHIFT);
__raw_writel(reg, S5P_CLK_SRC2);
do {
reg = __raw_readl(S5P_CLKMUX_STAT1);
} while (reg & ((1 << 7) | (1 << 3)));
/*
* 8. Change divider for MFC and G3D
* (200/4=50)->(200/1=200)Mhz
*/
reg = __raw_readl(S5P_CLK_DIV2);
reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
reg |= (clkdiv_val[index][10] << S5P_CLKDIV2_G3D_SHIFT) |
(clkdiv_val[index][9] << S5P_CLKDIV2_MFC_SHIFT);
__raw_writel(reg, S5P_CLK_DIV2);
/* For MFC, G3D dividing */
do {
reg = __raw_readl(S5P_CLKDIV_STAT0);
} while (reg & ((1 << 16) | (1 << 17)));
/* 9. Change MPLL to APLL in MSYS_MUX */
reg = __raw_readl(S5P_CLK_SRC0);
reg &= ~(S5P_CLKSRC0_MUX200_MASK);
reg |= (0x0 << S5P_CLKSRC0_MUX200_SHIFT);
__raw_writel(reg, S5P_CLK_SRC0);
do {
reg = __raw_readl(S5P_CLKMUX_STAT0);
} while (reg & (0x1 << 18));
/*
* 10. DMC1 refresh counter
* L4 : DMC1 = 100Mhz 7.8us/(1/100) = 0x30c
* Others : DMC1 = 200Mhz 7.8us/(1/200) = 0x618
*/
if (!bus_speed_changing)
s5pv210_set_refresh(DMC1, 200000);
}
/*
* L4 level need to change memory bus speed, hence onedram clock divier
* and memory refresh parameter should be changed
*/
if (bus_speed_changing) {
reg = __raw_readl(S5P_CLK_DIV6);
reg &= ~S5P_CLKDIV6_ONEDRAM_MASK;
reg |= (clkdiv_val[index][8] << S5P_CLKDIV6_ONEDRAM_SHIFT);
__raw_writel(reg, S5P_CLK_DIV6);
do {
reg = __raw_readl(S5P_CLKDIV_STAT1);
} while (reg & (1 << 15));
/* Reconfigure DRAM refresh counter value */
if (index != L4) {
/*
* DMC0 : 166Mhz
* DMC1 : 200Mhz
*/
s5pv210_set_refresh(DMC0, 166000);
s5pv210_set_refresh(DMC1, 200000);
} else {
/*
* DMC0 : 83Mhz
* DMC1 : 100Mhz
*/
s5pv210_set_refresh(DMC0, 83000);
s5pv210_set_refresh(DMC1, 100000);
}
}
if (freqs.new < freqs.old) {
/* Voltage down: will be implemented */
}
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
printk(KERN_DEBUG "Perf changed[L%d]\n", index);
return 0;
}
#ifdef CONFIG_PM
static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy,
pm_message_t pmsg)
{
return 0;
}
static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)
{
return 0;
}
#endif
static int check_mem_type(void __iomem *dmc_reg)
{
unsigned long val;
val = __raw_readl(dmc_reg + 0x4);
val = (val & (0xf << 8));
return val >> 8;
}
static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
{
unsigned long mem_type;
cpu_clk = clk_get(NULL, "armclk");
if (IS_ERR(cpu_clk))
return PTR_ERR(cpu_clk);
dmc0_clk = clk_get(NULL, "sclk_dmc0");
if (IS_ERR(dmc0_clk)) {
clk_put(cpu_clk);
return PTR_ERR(dmc0_clk);
}
dmc1_clk = clk_get(NULL, "hclk_msys");
if (IS_ERR(dmc1_clk)) {
clk_put(dmc0_clk);
clk_put(cpu_clk);
return PTR_ERR(dmc1_clk);
}
if (policy->cpu != 0)
return -EINVAL;
/*
* check_mem_type : This driver only support LPDDR & LPDDR2.
* other memory type is not supported.
*/
mem_type = check_mem_type(S5P_VA_DMC0);
if ((mem_type != LPDDR) && (mem_type != LPDDR2)) {
printk(KERN_ERR "CPUFreq doesn't support this memory type\n");
return -EINVAL;
}
/* Find current refresh counter and frequency each DMC */
s5pv210_dram_conf[0].refresh = (__raw_readl(S5P_VA_DMC0 + 0x30) * 1000);
s5pv210_dram_conf[0].freq = clk_get_rate(dmc0_clk);
s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000);
s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk);
policy->cur = policy->min = policy->max = s5pv210_getspeed(0);
cpufreq_frequency_table_get_attr(s5pv210_freq_table, policy->cpu);
policy->cpuinfo.transition_latency = 40000;
return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table);
}
static struct cpufreq_driver s5pv210_driver = {
.flags = CPUFREQ_STICKY,
.verify = s5pv210_verify_speed,
.target = s5pv210_target,
.get = s5pv210_getspeed,
.init = s5pv210_cpu_init,
.name = "s5pv210",
#ifdef CONFIG_PM
.suspend = s5pv210_cpufreq_suspend,
.resume = s5pv210_cpufreq_resume,
#endif
};
static int __init s5pv210_cpufreq_init(void)
{
return cpufreq_register_driver(&s5pv210_driver);
}
late_initcall(s5pv210_cpufreq_init);
...@@ -24,29 +24,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev) ...@@ -24,29 +24,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev)
/* configure GPIO for i2s port */ /* configure GPIO for i2s port */
switch (pdev->id) { switch (pdev->id) {
case 1: case 1:
s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2)); s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2));
break; break;
case 2: case 2:
s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4)); s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4));
break; break;
case -1: case -1:
s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2)); s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2));
break; break;
default: default:
...@@ -151,25 +137,13 @@ static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev) ...@@ -151,25 +137,13 @@ static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
{ {
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3)); s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3));
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3)); s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3));
break; break;
case 2: case 2:
s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2)); s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(2));
break; break;
default: default:
printk(KERN_DEBUG "Invalid PCM Controller number!"); printk(KERN_DEBUG "Invalid PCM Controller number!");
...@@ -271,13 +245,7 @@ struct platform_device s5pv210_device_pcm2 = { ...@@ -271,13 +245,7 @@ struct platform_device s5pv210_device_pcm2 = {
static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev) static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
{ {
s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4)); return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4));
s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4));
return 0;
} }
static struct resource s5pv210_ac97_resource[] = { static struct resource s5pv210_ac97_resource[] = {
...@@ -325,3 +293,43 @@ struct platform_device s5pv210_device_ac97 = { ...@@ -325,3 +293,43 @@ struct platform_device s5pv210_device_ac97 = {
.coherent_dma_mask = DMA_BIT_MASK(32), .coherent_dma_mask = DMA_BIT_MASK(32),
}, },
}; };
/* S/PDIF Controller platform_device */
static int s5pv210_spdif_cfg_gpio(struct platform_device *pdev)
{
s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 2, S3C_GPIO_SFN(3));
return 0;
}
static struct resource s5pv210_spdif_resource[] = {
[0] = {
.start = S5PV210_PA_SPDIF,
.end = S5PV210_PA_SPDIF + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = DMACH_SPDIF,
.end = DMACH_SPDIF,
.flags = IORESOURCE_DMA,
},
};
static struct s3c_audio_pdata samsung_spdif_pdata = {
.cfg_gpio = s5pv210_spdif_cfg_gpio,
};
static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32);
struct platform_device s5pv210_device_spdif = {
.name = "samsung-spdif",
.id = -1,
.num_resources = ARRAY_SIZE(s5pv210_spdif_resource),
.resource = s5pv210_spdif_resource,
.dev = {
.platform_data = &samsung_spdif_pdata,
.dma_mask = &s5pv210_spdif_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
};
...@@ -35,23 +35,15 @@ static char *spi_src_clks[] = { ...@@ -35,23 +35,15 @@ static char *spi_src_clks[] = {
*/ */
static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
{ {
unsigned int base;
switch (pdev->id) { switch (pdev->id) {
case 0: case 0:
s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2)); base = S5PV210_GPB(0);
s3c_gpio_cfgpin(S5PV210_GPB(1), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPB(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PV210_GPB(1), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP);
break; break;
case 1: case 1:
s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2)); base = S5PV210_GPB(4);
s3c_gpio_cfgpin(S5PV210_GPB(5), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PV210_GPB(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PV210_GPB(5), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PV210_GPB(6), S3C_GPIO_PULL_UP);
break; break;
default: default:
...@@ -59,6 +51,9 @@ static int s5pv210_spi_cfg_gpio(struct platform_device *pdev) ...@@ -59,6 +51,9 @@ static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0; return 0;
} }
......
...@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = { ...@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
static struct platform_device s5pv210_device_pdma0 = { static struct platform_device s5pv210_device_pdma0 = {
.name = "s3c-pl330", .name = "s3c-pl330",
.id = 1, .id = 0,
.num_resources = ARRAY_SIZE(s5pv210_pdma0_resource), .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
.resource = s5pv210_pdma0_resource, .resource = s5pv210_pdma0_resource,
.dev = { .dev = {
...@@ -144,7 +144,7 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = { ...@@ -144,7 +144,7 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
static struct platform_device s5pv210_device_pdma1 = { static struct platform_device s5pv210_device_pdma1 = {
.name = "s3c-pl330", .name = "s3c-pl330",
.id = 2, .id = 1,
.num_resources = ARRAY_SIZE(s5pv210_pdma1_resource), .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
.resource = s5pv210_pdma1_resource, .resource = s5pv210_pdma1_resource,
.dev = { .dev = {
......
...@@ -150,6 +150,7 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = { ...@@ -150,6 +150,7 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
.label = "GPG3", .label = "GPG3",
}, },
}, { }, {
.config = &gpio_cfg_noint,
.chip = { .chip = {
.base = S5PV210_GPI(0), .base = S5PV210_GPI(0),
.ngpio = S5PV210_GPIO_I_NR, .ngpio = S5PV210_GPIO_I_NR,
...@@ -223,34 +224,42 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = { ...@@ -223,34 +224,42 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
}, { }, {
.base = (S5P_VA_GPIO + 0xC00), .base = (S5P_VA_GPIO + 0xC00),
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(0),
.chip = { .chip = {
.base = S5PV210_GPH0(0), .base = S5PV210_GPH0(0),
.ngpio = S5PV210_GPIO_H0_NR, .ngpio = S5PV210_GPIO_H0_NR,
.label = "GPH0", .label = "GPH0",
.to_irq = samsung_gpiolib_to_irq,
}, },
}, { }, {
.base = (S5P_VA_GPIO + 0xC20), .base = (S5P_VA_GPIO + 0xC20),
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(8),
.chip = { .chip = {
.base = S5PV210_GPH1(0), .base = S5PV210_GPH1(0),
.ngpio = S5PV210_GPIO_H1_NR, .ngpio = S5PV210_GPIO_H1_NR,
.label = "GPH1", .label = "GPH1",
.to_irq = samsung_gpiolib_to_irq,
}, },
}, { }, {
.base = (S5P_VA_GPIO + 0xC40), .base = (S5P_VA_GPIO + 0xC40),
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(16),
.chip = { .chip = {
.base = S5PV210_GPH2(0), .base = S5PV210_GPH2(0),
.ngpio = S5PV210_GPIO_H2_NR, .ngpio = S5PV210_GPIO_H2_NR,
.label = "GPH2", .label = "GPH2",
.to_irq = samsung_gpiolib_to_irq,
}, },
}, { }, {
.base = (S5P_VA_GPIO + 0xC60), .base = (S5P_VA_GPIO + 0xC60),
.config = &gpio_cfg_noint, .config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(24),
.chip = { .chip = {
.base = S5PV210_GPH3(0), .base = S5PV210_GPH3(0),
.ngpio = S5PV210_GPIO_H3_NR, .ngpio = S5PV210_GPIO_H3_NR,
.label = "GPH3", .label = "GPH3",
.to_irq = samsung_gpiolib_to_irq,
}, },
}, },
}; };
...@@ -259,11 +268,14 @@ static __init int s5pv210_gpiolib_init(void) ...@@ -259,11 +268,14 @@ static __init int s5pv210_gpiolib_init(void)
{ {
struct s3c_gpio_chip *chip = s5pv210_gpio_4bit; struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit); int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
int gpioint_group = 0;
int i = 0; int i = 0;
for (i = 0; i < nr_chips; i++, chip++) { for (i = 0; i < nr_chips; i++, chip++) {
if (chip->config == NULL) if (chip->config == NULL) {
chip->config = &gpio_cfg; chip->config = &gpio_cfg;
chip->group = gpioint_group++;
}
if (chip->base == NULL) if (chip->base == NULL)
chip->base = S5PV210_BANK_BASE(i); chip->base = S5PV210_BANK_BASE(i);
} }
......
...@@ -55,8 +55,8 @@ ...@@ -55,8 +55,8 @@
#define IRQ_SPI1 S5P_IRQ_VIC1(16) #define IRQ_SPI1 S5P_IRQ_VIC1(16)
#define IRQ_SPI2 S5P_IRQ_VIC1(17) #define IRQ_SPI2 S5P_IRQ_VIC1(17)
#define IRQ_IRDA S5P_IRQ_VIC1(18) #define IRQ_IRDA S5P_IRQ_VIC1(18)
#define IRQ_CAN0 S5P_IRQ_VIC1(19) #define IRQ_IIC2 S5P_IRQ_VIC1(19)
#define IRQ_CAN1 S5P_IRQ_VIC1(20) #define IRQ_IIC3 S5P_IRQ_VIC1(20)
#define IRQ_HSIRX S5P_IRQ_VIC1(21) #define IRQ_HSIRX S5P_IRQ_VIC1(21)
#define IRQ_HSITX S5P_IRQ_VIC1(22) #define IRQ_HSITX S5P_IRQ_VIC1(22)
#define IRQ_UHOST S5P_IRQ_VIC1(23) #define IRQ_UHOST S5P_IRQ_VIC1(23)
...@@ -109,7 +109,7 @@ ...@@ -109,7 +109,7 @@
#define IRQ_IPC S5P_IRQ_VIC3(0) #define IRQ_IPC S5P_IRQ_VIC3(0)
#define IRQ_HOSTIF S5P_IRQ_VIC3(1) #define IRQ_HOSTIF S5P_IRQ_VIC3(1)
#define IRQ_MMC3 S5P_IRQ_VIC3(2) #define IRQ_HSMMC3 S5P_IRQ_VIC3(2)
#define IRQ_CEC S5P_IRQ_VIC3(3) #define IRQ_CEC S5P_IRQ_VIC3(3)
#define IRQ_TSI S5P_IRQ_VIC3(4) #define IRQ_TSI S5P_IRQ_VIC3(4)
#define IRQ_MDNIE0 S5P_IRQ_VIC3(5) #define IRQ_MDNIE0 S5P_IRQ_VIC3(5)
...@@ -121,8 +121,12 @@ ...@@ -121,8 +121,12 @@
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) #define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) #define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
/* GPIO interrupt */
#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
#define S5P_GPIOINT_GROUP_MAXNR 22
/* Set the default NR_IRQS */ /* Set the default NR_IRQS */
#define NR_IRQS (IRQ_EINT(31) + 1) #define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
/* Compatibility */ /* Compatibility */
#define IRQ_LCD_FIFO IRQ_LCD0 #define IRQ_LCD_FIFO IRQ_LCD0
......
...@@ -57,6 +57,8 @@ ...@@ -57,6 +57,8 @@
#define S5P_SZ_UART SZ_256 #define S5P_SZ_UART SZ_256
#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
#define S5PV210_PA_SROMC (0xE8000000) #define S5PV210_PA_SROMC (0xE8000000)
#define S5PV210_PA_CFCON (0xE8200000) #define S5PV210_PA_CFCON (0xE8200000)
...@@ -73,6 +75,9 @@ ...@@ -73,6 +75,9 @@
#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000)) #define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
#define S5PV210_PA_HSOTG (0xEC000000)
#define S5PV210_PA_HSPHY (0xEC100000)
#define S5PV210_PA_VIC0 (0xF2000000) #define S5PV210_PA_VIC0 (0xF2000000)
#define S5PV210_PA_VIC1 (0xF2100000) #define S5PV210_PA_VIC1 (0xF2100000)
#define S5PV210_PA_VIC2 (0xF2200000) #define S5PV210_PA_VIC2 (0xF2200000)
...@@ -81,6 +86,9 @@ ...@@ -81,6 +86,9 @@
#define S5PV210_PA_SDRAM (0x20000000) #define S5PV210_PA_SDRAM (0x20000000)
#define S5P_PA_SDRAM S5PV210_PA_SDRAM #define S5P_PA_SDRAM S5PV210_PA_SDRAM
/* S/PDIF */
#define S5PV210_PA_SPDIF 0xE1100000
/* I2S */ /* I2S */
#define S5PV210_PA_IIS0 0xEEE30000 #define S5PV210_PA_IIS0 0xEEE30000
#define S5PV210_PA_IIS1 0xE2100000 #define S5PV210_PA_IIS1 0xE2100000
...@@ -96,6 +104,9 @@ ...@@ -96,6 +104,9 @@
#define S5PV210_PA_ADC (0xE1700000) #define S5PV210_PA_ADC (0xE1700000)
#define S5PV210_PA_DMC0 (0xF0000000)
#define S5PV210_PA_DMC1 (0xF1400000)
/* compatibiltiy defines. */ /* compatibiltiy defines. */
#define S3C_PA_UART S5PV210_PA_UART #define S3C_PA_UART S5PV210_PA_UART
#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0) #define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0)
...@@ -108,6 +119,7 @@ ...@@ -108,6 +119,7 @@
#define S3C_PA_FB S5PV210_PA_FB #define S3C_PA_FB S5PV210_PA_FB
#define S3C_PA_RTC S5PV210_PA_RTC #define S3C_PA_RTC S5PV210_PA_RTC
#define S3C_PA_WDT S5PV210_PA_WATCHDOG #define S3C_PA_WDT S5PV210_PA_WATCHDOG
#define S3C_PA_USB_HSOTG S5PV210_PA_HSOTG
#define S5P_PA_FIMC0 S5PV210_PA_FIMC0 #define S5P_PA_FIMC0 S5PV210_PA_FIMC0
#define S5P_PA_FIMC1 S5PV210_PA_FIMC1 #define S5P_PA_FIMC1 S5PV210_PA_FIMC1
#define S5P_PA_FIMC2 S5PV210_PA_FIMC2 #define S5P_PA_FIMC2 S5PV210_PA_FIMC2
......
/* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S5PV210 - PM core support for arch/arm/plat-s5p/pm.c
*
* 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.
*/
static inline void s3c_pm_debug_init_uart(void)
{
/* nothing here yet */
}
static inline void s3c_pm_arch_prepare_irqs(void)
{
__raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
__raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
}
static inline void s3c_pm_arch_stop_clocks(void)
{
/* nothing here yet */
}
static inline void s3c_pm_arch_show_resume_irqs(void)
{
/* nothing here yet */
}
static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
{
/* nothing here yet */
}
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define S5P_APLL_CON S5P_CLKREG(0x100) #define S5P_APLL_CON S5P_CLKREG(0x100)
#define S5P_MPLL_CON S5P_CLKREG(0x108) #define S5P_MPLL_CON S5P_CLKREG(0x108)
#define S5P_EPLL_CON S5P_CLKREG(0x110) #define S5P_EPLL_CON S5P_CLKREG(0x110)
#define S5P_EPLL_CON1 S5P_CLKREG(0x114)
#define S5P_VPLL_CON S5P_CLKREG(0x120) #define S5P_VPLL_CON S5P_CLKREG(0x120)
#define S5P_CLK_SRC0 S5P_CLKREG(0x200) #define S5P_CLK_SRC0 S5P_CLKREG(0x200)
...@@ -67,11 +68,28 @@ ...@@ -67,11 +68,28 @@
#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488) #define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488)
#define S5P_CLK_OUT S5P_CLKREG(0x500) #define S5P_CLK_OUT S5P_CLKREG(0x500)
/* DIV/MUX STATUS */
#define S5P_CLKDIV_STAT0 S5P_CLKREG(0x1000)
#define S5P_CLKDIV_STAT1 S5P_CLKREG(0x1004)
#define S5P_CLKMUX_STAT0 S5P_CLKREG(0x1100)
#define S5P_CLKMUX_STAT1 S5P_CLKREG(0x1104)
/* CLKSRC0 */ /* CLKSRC0 */
#define S5P_CLKSRC0_MUX200_MASK (0x1<<16) #define S5P_CLKSRC0_MUX200_SHIFT (16)
#define S5P_CLKSRC0_MUX200_MASK (0x1 << S5P_CLKSRC0_MUX200_SHIFT)
#define S5P_CLKSRC0_MUX166_MASK (0x1<<20) #define S5P_CLKSRC0_MUX166_MASK (0x1<<20)
#define S5P_CLKSRC0_MUX133_MASK (0x1<<24) #define S5P_CLKSRC0_MUX133_MASK (0x1<<24)
/* CLKSRC2 */
#define S5P_CLKSRC2_G3D_SHIFT (0)
#define S5P_CLKSRC2_G3D_MASK (0x3 << S5P_CLKSRC2_G3D_SHIFT)
#define S5P_CLKSRC2_MFC_SHIFT (4)
#define S5P_CLKSRC2_MFC_MASK (0x3 << S5P_CLKSRC2_MFC_SHIFT)
/* CLKSRC6*/
#define S5P_CLKSRC6_ONEDRAM_SHIFT (24)
#define S5P_CLKSRC6_ONEDRAM_MASK (0x3 << S5P_CLKSRC6_ONEDRAM_SHIFT)
/* CLKDIV0 */ /* CLKDIV0 */
#define S5P_CLKDIV0_APLL_SHIFT (0) #define S5P_CLKDIV0_APLL_SHIFT (0)
#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT) #define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
...@@ -90,8 +108,20 @@ ...@@ -90,8 +108,20 @@
#define S5P_CLKDIV0_PCLK66_SHIFT (28) #define S5P_CLKDIV0_PCLK66_SHIFT (28)
#define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT) #define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
/* CLKDIV2 */
#define S5P_CLKDIV2_G3D_SHIFT (0)
#define S5P_CLKDIV2_G3D_MASK (0xF << S5P_CLKDIV2_G3D_SHIFT)
#define S5P_CLKDIV2_MFC_SHIFT (4)
#define S5P_CLKDIV2_MFC_MASK (0xF << S5P_CLKDIV2_MFC_SHIFT)
/* CLKDIV6 */
#define S5P_CLKDIV6_ONEDRAM_SHIFT (28)
#define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT)
#define S5P_SWRESET S5P_CLKREG(0x2000) #define S5P_SWRESET S5P_CLKREG(0x2000)
#define S5P_ARM_MCS_CON S5P_CLKREG(0x6100)
/* Registers related to power management */ /* Registers related to power management */
#define S5P_PWR_CFG S5P_CLKREG(0xC000) #define S5P_PWR_CFG S5P_CLKREG(0xC000)
#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004) #define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004)
...@@ -159,8 +189,11 @@ ...@@ -159,8 +189,11 @@
#define S5P_SLEEP_CFG_USBOSC_EN (1 << 1) #define S5P_SLEEP_CFG_USBOSC_EN (1 << 1)
/* OTHERS Resgister */ /* OTHERS Resgister */
#define S5P_OTHERS_RET_IO (1 << 31)
#define S5P_OTHERS_RET_CF (1 << 30)
#define S5P_OTHERS_RET_MMC (1 << 29)
#define S5P_OTHERS_RET_UART (1 << 28)
#define S5P_OTHERS_USB_SIG_MASK (1 << 16) #define S5P_OTHERS_USB_SIG_MASK (1 << 16)
#define S5P_OTHERS_MIPI_DPHY_EN (1 << 28)
/* MIPI */ /* MIPI */
#define S5P_MIPI_DPHY_EN (3) #define S5P_MIPI_DPHY_EN (3)
......
...@@ -31,13 +31,6 @@ ...@@ -31,13 +31,6 @@
#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) #define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
/* values for S5P_EXTINT0 */
#define S5P_EXTINT_LOWLEV (0x00)
#define S5P_EXTINT_HILEV (0x01)
#define S5P_EXTINT_FALLEDGE (0x02)
#define S5P_EXTINT_RISEEDGE (0x03)
#define S5P_EXTINT_BOTHEDGE (0x04)
#define EINT_MODE S3C_GPIO_SFN(0xf) #define EINT_MODE S3C_GPIO_SFN(0xf)
#define EINT_GPIO_0(x) S5PV210_GPH0(x) #define EINT_GPIO_0(x) S5PV210_GPH0(x)
......
/* arch/arm/mach-s5pv210/include/mach/regs-sys.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5PV210 - System registers definitions
*
* 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.
*/
#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
...@@ -17,6 +17,6 @@ ...@@ -17,6 +17,6 @@
#ifndef __ASM_ARCH_VMALLOC_H #ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H __FILE__ #define __ASM_ARCH_VMALLOC_H __FILE__
#define VMALLOC_END (0xE0000000UL) #define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */ #endif /* __ASM_ARCH_VMALLOC_H */
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-gpio.h> #include <linux/i2c-gpio.h>
#include <linux/mfd/max8998.h> #include <linux/mfd/max8998.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/regulator/fixed.h>
#include <linux/gpio_keys.h> #include <linux/gpio_keys.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/gpio.h> #include <linux/gpio.h>
...@@ -379,6 +381,119 @@ static struct max8998_platform_data aquila_max8998_pdata = { ...@@ -379,6 +381,119 @@ static struct max8998_platform_data aquila_max8998_pdata = {
}; };
#endif #endif
static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
{
.dev_name = "5-001a",
.supply = "DBVDD",
}, {
.dev_name = "5-001a",
.supply = "AVDD2",
}, {
.dev_name = "5-001a",
.supply = "CPVDD",
},
};
static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
{
.dev_name = "5-001a",
.supply = "SPKVDD1",
}, {
.dev_name = "5-001a",
.supply = "SPKVDD2",
},
};
static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
.constraints = {
.always_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
.consumer_supplies = wm8994_fixed_voltage0_supplies,
};
static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
.constraints = {
.always_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
.consumer_supplies = wm8994_fixed_voltage1_supplies,
};
static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
.supply_name = "VCC_1.8V_PDA",
.microvolts = 1800000,
.gpio = -EINVAL,
.init_data = &wm8994_fixed_voltage0_init_data,
};
static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
.supply_name = "V_BAT",
.microvolts = 3700000,
.gpio = -EINVAL,
.init_data = &wm8994_fixed_voltage1_init_data,
};
static struct platform_device wm8994_fixed_voltage0 = {
.name = "reg-fixed-voltage",
.id = 0,
.dev = {
.platform_data = &wm8994_fixed_voltage0_config,
},
};
static struct platform_device wm8994_fixed_voltage1 = {
.name = "reg-fixed-voltage",
.id = 1,
.dev = {
.platform_data = &wm8994_fixed_voltage1_config,
},
};
static struct regulator_consumer_supply wm8994_avdd1_supply = {
.dev_name = "5-001a",
.supply = "AVDD1",
};
static struct regulator_consumer_supply wm8994_dcvdd_supply = {
.dev_name = "5-001a",
.supply = "DCVDD",
};
static struct regulator_init_data wm8994_ldo1_data = {
.constraints = {
.name = "AVDD1_3.0V",
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = 1,
.consumer_supplies = &wm8994_avdd1_supply,
};
static struct regulator_init_data wm8994_ldo2_data = {
.constraints = {
.name = "DCVDD_1.0V",
},
.num_consumer_supplies = 1,
.consumer_supplies = &wm8994_dcvdd_supply,
};
static struct wm8994_pdata wm8994_platform_data = {
/* configure gpio1 function: 0x0001(Logic level input/output) */
.gpio_defaults[0] = 0x0001,
/* configure gpio3/4/5/7 function for AIF2 voice */
.gpio_defaults[2] = 0x8100,
.gpio_defaults[3] = 0x8100,
.gpio_defaults[4] = 0x8100,
.gpio_defaults[6] = 0x0100,
/* configure gpio8/9/10/11 function for AIF3 BT */
.gpio_defaults[7] = 0x8100,
.gpio_defaults[8] = 0x0100,
.gpio_defaults[9] = 0x0100,
.gpio_defaults[10] = 0x0100,
.ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
.ldo[1] = { 0, NULL, &wm8994_ldo2_data },
};
/* GPIO I2C PMIC */ /* GPIO I2C PMIC */
#define AP_I2C_GPIO_PMIC_BUS_4 4 #define AP_I2C_GPIO_PMIC_BUS_4 4
static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = { static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = {
...@@ -404,6 +519,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = { ...@@ -404,6 +519,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
#endif #endif
}; };
/* GPIO I2C AP 1.8V */
#define AP_I2C_GPIO_BUS_5 5
static struct i2c_gpio_platform_data aquila_i2c_gpio5_data = {
.sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */
.scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */
};
static struct platform_device aquila_i2c_gpio5 = {
.name = "i2c-gpio",
.id = AP_I2C_GPIO_BUS_5,
.dev = {
.platform_data = &aquila_i2c_gpio5_data,
},
};
static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
{
/* CS/ADDR = low 0x34 (FYI: high = 0x36) */
I2C_BOARD_INFO("wm8994", 0x1a),
.platform_data = &wm8994_platform_data,
},
};
/* PMIC Power button */ /* PMIC Power button */
static struct gpio_keys_button aquila_gpio_keys_table[] = { static struct gpio_keys_button aquila_gpio_keys_table[] = {
{ {
...@@ -475,6 +613,7 @@ static void aquila_setup_sdhci(void) ...@@ -475,6 +613,7 @@ static void aquila_setup_sdhci(void)
static struct platform_device *aquila_devices[] __initdata = { static struct platform_device *aquila_devices[] __initdata = {
&aquila_i2c_gpio_pmic, &aquila_i2c_gpio_pmic,
&aquila_i2c_gpio5,
&aquila_device_gpiokeys, &aquila_device_gpiokeys,
&s3c_device_fb, &s3c_device_fb,
&s5p_device_onenand, &s5p_device_onenand,
...@@ -484,8 +623,33 @@ static struct platform_device *aquila_devices[] __initdata = { ...@@ -484,8 +623,33 @@ static struct platform_device *aquila_devices[] __initdata = {
&s5p_device_fimc0, &s5p_device_fimc0,
&s5p_device_fimc1, &s5p_device_fimc1,
&s5p_device_fimc2, &s5p_device_fimc2,
&s5pv210_device_iis0,
&wm8994_fixed_voltage0,
&wm8994_fixed_voltage1,
}; };
static void __init aquila_sound_init(void)
{
unsigned int gpio;
/* CODEC_XTAL_EN
*
* The Aquila board have a oscillator which provide main clock
* to WM8994 codec. The oscillator provide 24MHz clock to WM8994
* clock. Set gpio setting of "CODEC_XTAL_EN" to enable a oscillator.
* */
gpio = S5PV210_GPH3(2); /* XEINT_26 */
gpio_request(gpio, "CODEC_XTAL_EN");
s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
/* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
* The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
* because it needs 24MHz clock to operate WM8994 codec.
*/
__raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
}
static void __init aquila_map_io(void) static void __init aquila_map_io(void)
{ {
s5p_init_io(NULL, 0, S5P_VA_CHIPID); s5p_init_io(NULL, 0, S5P_VA_CHIPID);
...@@ -506,6 +670,11 @@ static void __init aquila_machine_init(void) ...@@ -506,6 +670,11 @@ static void __init aquila_machine_init(void)
s3c_fimc_setname(1, "s5p-fimc"); s3c_fimc_setname(1, "s5p-fimc");
s3c_fimc_setname(2, "s5p-fimc"); s3c_fimc_setname(2, "s5p-fimc");
/* SOUND */
aquila_sound_init();
i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
ARRAY_SIZE(i2c_gpio5_devs));
/* FB */ /* FB */
s3c_fb_set_platdata(&aquila_lcd_pdata); s3c_fb_set_platdata(&aquila_lcd_pdata);
......
...@@ -15,7 +15,13 @@ ...@@ -15,7 +15,13 @@
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-gpio.h> #include <linux/i2c-gpio.h>
#include <linux/i2c/qt602240_ts.h>
#include <linux/mfd/max8998.h> #include <linux/mfd/max8998.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/regulator/fixed.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
#include <linux/lcd.h>
#include <linux/gpio_keys.h> #include <linux/gpio_keys.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/gpio.h> #include <linux/gpio.h>
...@@ -35,7 +41,10 @@ ...@@ -35,7 +41,10 @@
#include <plat/devs.h> #include <plat/devs.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/fb.h> #include <plat/fb.h>
#include <plat/iic.h>
#include <plat/keypad.h>
#include <plat/sdhci.h> #include <plat/sdhci.h>
#include <plat/clock.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */ /* Following are default values for UCON, ULCON and UFCON UART registers */
#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ #define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
...@@ -87,13 +96,12 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = { ...@@ -87,13 +96,12 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
/* Frame Buffer */ /* Frame Buffer */
static struct s3c_fb_pd_win goni_fb_win0 = { static struct s3c_fb_pd_win goni_fb_win0 = {
.win_mode = { .win_mode = {
.pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55),
.left_margin = 16, .left_margin = 16,
.right_margin = 16, .right_margin = 16,
.upper_margin = 3, .upper_margin = 2,
.lower_margin = 28, .lower_margin = 28,
.hsync_len = 2, .hsync_len = 2,
.vsync_len = 2, .vsync_len = 1,
.xres = 480, .xres = 480,
.yres = 800, .yres = 800,
.refresh = 55, .refresh = 55,
...@@ -111,9 +119,160 @@ static struct s3c_fb_platdata goni_lcd_pdata __initdata = { ...@@ -111,9 +119,160 @@ static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
.setup_gpio = s5pv210_fb_gpio_setup_24bpp, .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
}; };
static int lcd_power_on(struct lcd_device *ld, int enable)
{
return 1;
}
static int reset_lcd(struct lcd_device *ld)
{
static unsigned int first = 1;
int reset_gpio = -1;
reset_gpio = S5PV210_MP05(5);
if (first) {
gpio_request(reset_gpio, "MLCD_RST");
first = 0;
}
gpio_direction_output(reset_gpio, 1);
return 1;
}
static struct lcd_platform_data goni_lcd_platform_data = {
.reset = reset_lcd,
.power_on = lcd_power_on,
.lcd_enabled = 0,
.reset_delay = 120, /* 120ms */
.power_on_delay = 25, /* 25ms */
.power_off_delay = 200, /* 200ms */
};
#define LCD_BUS_NUM 3
static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "s6e63m0",
.platform_data = &goni_lcd_platform_data,
.max_speed_hz = 1200000,
.bus_num = LCD_BUS_NUM,
.chip_select = 0,
.mode = SPI_MODE_3,
.controller_data = (void *)S5PV210_MP01(1), /* DISPLAY_CS */
},
};
static struct spi_gpio_platform_data lcd_spi_gpio_data = {
.sck = S5PV210_MP04(1), /* DISPLAY_CLK */
.mosi = S5PV210_MP04(3), /* DISPLAY_SI */
.miso = SPI_GPIO_NO_MISO,
.num_chipselect = 1,
};
static struct platform_device goni_spi_gpio = {
.name = "spi_gpio",
.id = LCD_BUS_NUM,
.dev = {
.parent = &s3c_device_fb.dev,
.platform_data = &lcd_spi_gpio_data,
},
};
/* KEYPAD */
static uint32_t keymap[] __initdata = {
/* KEY(row, col, keycode) */
KEY(0, 1, KEY_MENU), /* Send */
KEY(0, 2, KEY_BACK), /* End */
KEY(1, 1, KEY_CONFIG), /* Half shot */
KEY(1, 2, KEY_VOLUMEUP),
KEY(2, 1, KEY_CAMERA), /* Full shot */
KEY(2, 2, KEY_VOLUMEDOWN),
};
static struct matrix_keymap_data keymap_data __initdata = {
.keymap = keymap,
.keymap_size = ARRAY_SIZE(keymap),
};
static struct samsung_keypad_platdata keypad_data __initdata = {
.keymap_data = &keymap_data,
.rows = 3,
.cols = 3,
};
/* Radio */
static struct i2c_board_info i2c1_devs[] __initdata = {
{
I2C_BOARD_INFO("si470x", 0x10),
},
};
static void __init goni_radio_init(void)
{
int gpio;
gpio = S5PV210_GPJ2(4); /* XMSMDATA_4 */
gpio_request(gpio, "FM_INT");
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
i2c1_devs[0].irq = gpio_to_irq(gpio);
gpio = S5PV210_GPJ2(5); /* XMSMDATA_5 */
gpio_request(gpio, "FM_RST");
gpio_direction_output(gpio, 1);
}
/* TSP */
static struct qt602240_platform_data qt602240_platform_data = {
.x_line = 17,
.y_line = 11,
.x_size = 800,
.y_size = 480,
.blen = 0x21,
.threshold = 0x28,
.voltage = 2800000, /* 2.8V */
.orient = QT602240_DIAGONAL,
};
static struct s3c2410_platform_i2c i2c2_data __initdata = {
.flags = 0,
.bus_num = 2,
.slave_addr = 0x10,
.frequency = 400 * 1000,
.sda_delay = 100,
};
static struct i2c_board_info i2c2_devs[] __initdata = {
{
I2C_BOARD_INFO("qt602240_ts", 0x4a),
.platform_data = &qt602240_platform_data,
},
};
static void __init goni_tsp_init(void)
{
int gpio;
gpio = S5PV210_GPJ1(3); /* XMSMADDR_11 */
gpio_request(gpio, "TSP_LDO_ON");
gpio_direction_output(gpio, 1);
gpio_export(gpio, 0);
gpio = S5PV210_GPJ0(5); /* XMSMADDR_5 */
gpio_request(gpio, "TSP_INT");
s5p_register_gpio_interrupt(gpio);
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
i2c2_devs[0].irq = gpio_to_irq(gpio);
}
/* MAX8998 regulators */ /* MAX8998 regulators */
#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE) #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
static struct regulator_consumer_supply goni_ldo5_consumers[] = {
REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
};
static struct regulator_init_data goni_ldo2_data = { static struct regulator_init_data goni_ldo2_data = {
.constraints = { .constraints = {
.name = "VALIVE_1.1V", .name = "VALIVE_1.1V",
...@@ -153,6 +312,8 @@ static struct regulator_init_data goni_ldo5_data = { ...@@ -153,6 +312,8 @@ static struct regulator_init_data goni_ldo5_data = {
.max_uV = 2800000, .max_uV = 2800000,
.apply_uV = 1, .apply_uV = 1,
}, },
.num_consumer_supplies = ARRAY_SIZE(goni_ldo5_consumers),
.consumer_supplies = goni_ldo5_consumers,
}; };
static struct regulator_init_data goni_ldo6_data = { static struct regulator_init_data goni_ldo6_data = {
...@@ -360,6 +521,119 @@ static struct max8998_platform_data goni_max8998_pdata = { ...@@ -360,6 +521,119 @@ static struct max8998_platform_data goni_max8998_pdata = {
}; };
#endif #endif
static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
{
.dev_name = "5-001a",
.supply = "DBVDD",
}, {
.dev_name = "5-001a",
.supply = "AVDD2",
}, {
.dev_name = "5-001a",
.supply = "CPVDD",
},
};
static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
{
.dev_name = "5-001a",
.supply = "SPKVDD1",
}, {
.dev_name = "5-001a",
.supply = "SPKVDD2",
},
};
static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
.constraints = {
.always_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
.consumer_supplies = wm8994_fixed_voltage0_supplies,
};
static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
.constraints = {
.always_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
.consumer_supplies = wm8994_fixed_voltage1_supplies,
};
static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
.supply_name = "VCC_1.8V_PDA",
.microvolts = 1800000,
.gpio = -EINVAL,
.init_data = &wm8994_fixed_voltage0_init_data,
};
static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
.supply_name = "V_BAT",
.microvolts = 3700000,
.gpio = -EINVAL,
.init_data = &wm8994_fixed_voltage1_init_data,
};
static struct platform_device wm8994_fixed_voltage0 = {
.name = "reg-fixed-voltage",
.id = 0,
.dev = {
.platform_data = &wm8994_fixed_voltage0_config,
},
};
static struct platform_device wm8994_fixed_voltage1 = {
.name = "reg-fixed-voltage",
.id = 1,
.dev = {
.platform_data = &wm8994_fixed_voltage1_config,
},
};
static struct regulator_consumer_supply wm8994_avdd1_supply = {
.dev_name = "5-001a",
.supply = "AVDD1",
};
static struct regulator_consumer_supply wm8994_dcvdd_supply = {
.dev_name = "5-001a",
.supply = "DCVDD",
};
static struct regulator_init_data wm8994_ldo1_data = {
.constraints = {
.name = "AVDD1_3.0V",
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = 1,
.consumer_supplies = &wm8994_avdd1_supply,
};
static struct regulator_init_data wm8994_ldo2_data = {
.constraints = {
.name = "DCVDD_1.0V",
},
.num_consumer_supplies = 1,
.consumer_supplies = &wm8994_dcvdd_supply,
};
static struct wm8994_pdata wm8994_platform_data = {
/* configure gpio1 function: 0x0001(Logic level input/output) */
.gpio_defaults[0] = 0x0001,
/* configure gpio3/4/5/7 function for AIF2 voice */
.gpio_defaults[2] = 0x8100,
.gpio_defaults[3] = 0x8100,
.gpio_defaults[4] = 0x8100,
.gpio_defaults[6] = 0x0100,
/* configure gpio8/9/10/11 function for AIF3 BT */
.gpio_defaults[7] = 0x8100,
.gpio_defaults[8] = 0x0100,
.gpio_defaults[9] = 0x0100,
.gpio_defaults[10] = 0x0100,
.ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
.ldo[1] = { 0, NULL, &wm8994_ldo2_data },
};
/* GPIO I2C PMIC */ /* GPIO I2C PMIC */
#define AP_I2C_GPIO_PMIC_BUS_4 4 #define AP_I2C_GPIO_PMIC_BUS_4 4
static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = { static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = {
...@@ -385,6 +659,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = { ...@@ -385,6 +659,29 @@ static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
#endif #endif
}; };
/* GPIO I2C AP 1.8V */
#define AP_I2C_GPIO_BUS_5 5
static struct i2c_gpio_platform_data goni_i2c_gpio5_data = {
.sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */
.scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */
};
static struct platform_device goni_i2c_gpio5 = {
.name = "i2c-gpio",
.id = AP_I2C_GPIO_BUS_5,
.dev = {
.platform_data = &goni_i2c_gpio5_data,
},
};
static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
{
/* CS/ADDR = low 0x34 (FYI: high = 0x36) */
I2C_BOARD_INFO("wm8994", 0x1a),
.platform_data = &wm8994_platform_data,
},
};
/* PMIC Power button */ /* PMIC Power button */
static struct gpio_keys_button goni_gpio_keys_table[] = { static struct gpio_keys_button goni_gpio_keys_table[] = {
{ {
...@@ -444,11 +741,37 @@ static struct s3c_sdhci_platdata goni_hsmmc2_data __initdata = { ...@@ -444,11 +741,37 @@ static struct s3c_sdhci_platdata goni_hsmmc2_data __initdata = {
.ext_cd_gpio_invert = 1, .ext_cd_gpio_invert = 1,
}; };
static struct regulator_consumer_supply mmc2_supplies[] = {
REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"),
};
static struct regulator_init_data mmc2_fixed_voltage_init_data = {
.constraints = {
.name = "V_TF_2.8V",
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(mmc2_supplies),
.consumer_supplies = mmc2_supplies,
};
static struct fixed_voltage_config mmc2_fixed_voltage_config = {
.supply_name = "EXT_FLASH_EN",
.microvolts = 2800000,
.gpio = GONI_EXT_FLASH_EN,
.enable_high = true,
.init_data = &mmc2_fixed_voltage_init_data,
};
static struct platform_device mmc2_fixed_voltage = {
.name = "reg-fixed-voltage",
.id = 2,
.dev = {
.platform_data = &mmc2_fixed_voltage_config,
},
};
static void goni_setup_sdhci(void) static void goni_setup_sdhci(void)
{ {
gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN");
gpio_direction_output(GONI_EXT_FLASH_EN, 1);
s3c_sdhci0_set_platdata(&goni_hsmmc0_data); s3c_sdhci0_set_platdata(&goni_hsmmc0_data);
s3c_sdhci1_set_platdata(&goni_hsmmc1_data); s3c_sdhci1_set_platdata(&goni_hsmmc1_data);
s3c_sdhci2_set_platdata(&goni_hsmmc2_data); s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
...@@ -457,7 +780,10 @@ static void goni_setup_sdhci(void) ...@@ -457,7 +780,10 @@ static void goni_setup_sdhci(void)
static struct platform_device *goni_devices[] __initdata = { static struct platform_device *goni_devices[] __initdata = {
&s3c_device_fb, &s3c_device_fb,
&s5p_device_onenand, &s5p_device_onenand,
&goni_spi_gpio,
&goni_i2c_gpio_pmic, &goni_i2c_gpio_pmic,
&goni_i2c_gpio5,
&mmc2_fixed_voltage,
&goni_device_gpiokeys, &goni_device_gpiokeys,
&s5p_device_fimc0, &s5p_device_fimc0,
&s5p_device_fimc1, &s5p_device_fimc1,
...@@ -465,8 +791,24 @@ static struct platform_device *goni_devices[] __initdata = { ...@@ -465,8 +791,24 @@ static struct platform_device *goni_devices[] __initdata = {
&s3c_device_hsmmc0, &s3c_device_hsmmc0,
&s3c_device_hsmmc1, &s3c_device_hsmmc1,
&s3c_device_hsmmc2, &s3c_device_hsmmc2,
&s5pv210_device_iis0,
&s3c_device_usb_hsotg,
&samsung_device_keypad,
&s3c_device_i2c1,
&s3c_device_i2c2,
&wm8994_fixed_voltage0,
&wm8994_fixed_voltage1,
}; };
static void __init goni_sound_init(void)
{
/* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
* The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
* because it needs 24MHz clock to operate WM8994 codec.
*/
__raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
}
static void __init goni_map_io(void) static void __init goni_map_io(void)
{ {
s5p_init_io(NULL, 0, S5P_VA_CHIPID); s5p_init_io(NULL, 0, S5P_VA_CHIPID);
...@@ -476,6 +818,20 @@ static void __init goni_map_io(void) ...@@ -476,6 +818,20 @@ static void __init goni_map_io(void)
static void __init goni_machine_init(void) static void __init goni_machine_init(void)
{ {
/* Radio: call before I2C 1 registeration */
goni_radio_init();
/* I2C1 */
s3c_i2c1_set_platdata(NULL);
i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
/* TSP: call before I2C 2 registeration */
goni_tsp_init();
/* I2C2 */
s3c_i2c2_set_platdata(&i2c2_data);
i2c_register_board_info(2, i2c2_devs, ARRAY_SIZE(i2c2_devs));
/* PMIC */ /* PMIC */
goni_pmic_init(); goni_pmic_init();
i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs, i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
...@@ -483,9 +839,22 @@ static void __init goni_machine_init(void) ...@@ -483,9 +839,22 @@ static void __init goni_machine_init(void)
/* SDHCI */ /* SDHCI */
goni_setup_sdhci(); goni_setup_sdhci();
/* SOUND */
goni_sound_init();
i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
ARRAY_SIZE(i2c_gpio5_devs));
/* FB */ /* FB */
s3c_fb_set_platdata(&goni_lcd_pdata); s3c_fb_set_platdata(&goni_lcd_pdata);
/* SPI */
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
/* KEYPAD */
samsung_keypad_set_platdata(&keypad_data);
clk_xusbxti.rate = 24000000;
platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices)); platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/ata.h> #include <plat/ata.h>
#include <plat/iic.h> #include <plat/iic.h>
#include <plat/pm.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */ /* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ #define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
...@@ -81,6 +82,7 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = { ...@@ -81,6 +82,7 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
static struct platform_device *smdkc110_devices[] __initdata = { static struct platform_device *smdkc110_devices[] __initdata = {
&s5pv210_device_iis0, &s5pv210_device_iis0,
&s5pv210_device_ac97, &s5pv210_device_ac97,
&s5pv210_device_spdif,
&s3c_device_cfcon, &s3c_device_cfcon,
&s3c_device_i2c0, &s3c_device_i2c0,
&s3c_device_i2c1, &s3c_device_i2c1,
...@@ -110,6 +112,8 @@ static void __init smdkc110_map_io(void) ...@@ -110,6 +112,8 @@ static void __init smdkc110_map_io(void)
static void __init smdkc110_machine_init(void) static void __init smdkc110_machine_init(void)
{ {
s3c_pm_init();
s3c_i2c0_set_platdata(NULL); s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL); s3c_i2c1_set_platdata(NULL);
s3c_i2c2_set_platdata(NULL); s3c_i2c2_set_platdata(NULL);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <plat/ata.h> #include <plat/ata.h>
#include <plat/iic.h> #include <plat/iic.h>
#include <plat/keypad.h> #include <plat/keypad.h>
#include <plat/pm.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */ /* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ #define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
...@@ -103,6 +104,7 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = { ...@@ -103,6 +104,7 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
static struct platform_device *smdkv210_devices[] __initdata = { static struct platform_device *smdkv210_devices[] __initdata = {
&s5pv210_device_iis0, &s5pv210_device_iis0,
&s5pv210_device_ac97, &s5pv210_device_ac97,
&s5pv210_device_spdif,
&s3c_device_adc, &s3c_device_adc,
&s3c_device_cfcon, &s3c_device_cfcon,
&s3c_device_hsmmc0, &s3c_device_hsmmc0,
...@@ -145,6 +147,8 @@ static void __init smdkv210_map_io(void) ...@@ -145,6 +147,8 @@ static void __init smdkv210_map_io(void)
static void __init smdkv210_machine_init(void) static void __init smdkv210_machine_init(void)
{ {
s3c_pm_init();
samsung_keypad_set_platdata(&smdkv210_keypad_data); samsung_keypad_set_platdata(&smdkv210_keypad_data);
s3c24xx_ts_set_platdata(&s3c_ts_platform); s3c24xx_ts_set_platdata(&s3c_ts_platform);
......
/* linux/arch/arm/mach-s5pv210/mach-torbreck.c
*
* Copyright (c) 2010 aESOP Community
* http://www.aesop.or.kr/
*
* 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/types.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <plat/regs-serial.h>
#include <plat/s5pv210.h>
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/iic.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define TORBRECK_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
S3C2410_UCON_TXIRQMODE | \
S3C2410_UCON_RXIRQMODE | \
S3C2410_UCON_RXFIFO_TOI | \
S3C2443_UCON_RXERR_IRQEN)
#define TORBRECK_ULCON_DEFAULT S3C2410_LCON_CS8
#define TORBRECK_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
S5PV210_UFCON_TXTRIG4 | \
S5PV210_UFCON_RXTRIG4)
static struct s3c2410_uartcfg torbreck_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = TORBRECK_UCON_DEFAULT,
.ulcon = TORBRECK_ULCON_DEFAULT,
.ufcon = TORBRECK_UFCON_DEFAULT,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = TORBRECK_UCON_DEFAULT,
.ulcon = TORBRECK_ULCON_DEFAULT,
.ufcon = TORBRECK_UFCON_DEFAULT,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = TORBRECK_UCON_DEFAULT,
.ulcon = TORBRECK_ULCON_DEFAULT,
.ufcon = TORBRECK_UFCON_DEFAULT,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = TORBRECK_UCON_DEFAULT,
.ulcon = TORBRECK_ULCON_DEFAULT,
.ufcon = TORBRECK_UFCON_DEFAULT,
},
};
static struct platform_device *torbreck_devices[] __initdata = {
&s5pv210_device_iis0,
&s3c_device_cfcon,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
&s3c_device_hsmmc3,
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_i2c2,
&s3c_device_rtc,
&s3c_device_wdt,
};
static struct i2c_board_info torbreck_i2c_devs0[] __initdata = {
/* To Be Updated */
};
static struct i2c_board_info torbreck_i2c_devs1[] __initdata = {
/* To Be Updated */
};
static struct i2c_board_info torbreck_i2c_devs2[] __initdata = {
/* To Be Updated */
};
static void __init torbreck_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
}
static void __init torbreck_machine_init(void)
{
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_i2c2_set_platdata(NULL);
i2c_register_board_info(0, torbreck_i2c_devs0,
ARRAY_SIZE(torbreck_i2c_devs0));
i2c_register_board_info(1, torbreck_i2c_devs1,
ARRAY_SIZE(torbreck_i2c_devs1));
i2c_register_board_info(2, torbreck_i2c_devs2,
ARRAY_SIZE(torbreck_i2c_devs2));
platform_add_devices(torbreck_devices, ARRAY_SIZE(torbreck_devices));
}
MACHINE_START(TORBRECK, "TORBRECK")
/* Maintainer: Hyunchul Ko <ghcstop@gmail.com> */
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = torbreck_map_io,
.init_machine = torbreck_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END
/* linux/arch/arm/mach-s5pv210/pm.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV210 - Power Management support
*
* Based on arch/arm/mach-s3c2410/pm.c
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* 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/init.h>
#include <linux/suspend.h>
#include <linux/io.h>
#include <plat/cpu.h>
#include <plat/pm.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <mach/regs-clock.h>
static struct sleep_save s5pv210_core_save[] = {
/* Clock source */
SAVE_ITEM(S5P_CLK_SRC0),
SAVE_ITEM(S5P_CLK_SRC1),
SAVE_ITEM(S5P_CLK_SRC2),
SAVE_ITEM(S5P_CLK_SRC3),
SAVE_ITEM(S5P_CLK_SRC4),
SAVE_ITEM(S5P_CLK_SRC5),
SAVE_ITEM(S5P_CLK_SRC6),
/* Clock source Mask */
SAVE_ITEM(S5P_CLK_SRC_MASK0),
SAVE_ITEM(S5P_CLK_SRC_MASK1),
/* Clock Divider */
SAVE_ITEM(S5P_CLK_DIV0),
SAVE_ITEM(S5P_CLK_DIV1),
SAVE_ITEM(S5P_CLK_DIV2),
SAVE_ITEM(S5P_CLK_DIV3),
SAVE_ITEM(S5P_CLK_DIV4),
SAVE_ITEM(S5P_CLK_DIV5),
SAVE_ITEM(S5P_CLK_DIV6),
SAVE_ITEM(S5P_CLK_DIV7),
/* Clock Main Gate */
SAVE_ITEM(S5P_CLKGATE_MAIN0),
SAVE_ITEM(S5P_CLKGATE_MAIN1),
SAVE_ITEM(S5P_CLKGATE_MAIN2),
/* Clock source Peri Gate */
SAVE_ITEM(S5P_CLKGATE_PERI0),
SAVE_ITEM(S5P_CLKGATE_PERI1),
/* Clock source SCLK Gate */
SAVE_ITEM(S5P_CLKGATE_SCLK0),
SAVE_ITEM(S5P_CLKGATE_SCLK1),
/* Clock IP Clock gate */
SAVE_ITEM(S5P_CLKGATE_IP0),
SAVE_ITEM(S5P_CLKGATE_IP1),
SAVE_ITEM(S5P_CLKGATE_IP2),
SAVE_ITEM(S5P_CLKGATE_IP3),
SAVE_ITEM(S5P_CLKGATE_IP4),
/* Clock Blcok and Bus gate */
SAVE_ITEM(S5P_CLKGATE_BLOCK),
SAVE_ITEM(S5P_CLKGATE_BUS0),
/* Clock ETC */
SAVE_ITEM(S5P_CLK_OUT),
SAVE_ITEM(S5P_MDNIE_SEL),
/* PWM Register */
SAVE_ITEM(S3C2410_TCFG0),
SAVE_ITEM(S3C2410_TCFG1),
SAVE_ITEM(S3C64XX_TINT_CSTAT),
SAVE_ITEM(S3C2410_TCON),
SAVE_ITEM(S3C2410_TCNTB(0)),
SAVE_ITEM(S3C2410_TCMPB(0)),
SAVE_ITEM(S3C2410_TCNTO(0)),
};
void s5pv210_cpu_suspend(void)
{
unsigned long tmp;
/* issue the standby signal into the pm unit. Note, we
* issue a write-buffer drain just in case */
tmp = 0;
asm("b 1f\n\t"
".align 5\n\t"
"1:\n\t"
"mcr p15, 0, %0, c7, c10, 5\n\t"
"mcr p15, 0, %0, c7, c10, 4\n\t"
"wfi" : : "r" (tmp));
/* we should never get past here */
panic("sleep resumed to originator?");
}
static void s5pv210_pm_prepare(void)
{
unsigned int tmp;
/* ensure at least INFORM0 has the resume address */
__raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
tmp = __raw_readl(S5P_SLEEP_CFG);
tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN);
__raw_writel(tmp, S5P_SLEEP_CFG);
/* WFI for SLEEP mode configuration by SYSCON */
tmp = __raw_readl(S5P_PWR_CFG);
tmp &= S5P_CFG_WFI_CLEAN;
tmp |= S5P_CFG_WFI_SLEEP;
__raw_writel(tmp, S5P_PWR_CFG);
/* SYSCON interrupt handling disable */
tmp = __raw_readl(S5P_OTHERS);
tmp |= S5P_OTHER_SYSC_INTOFF;
__raw_writel(tmp, S5P_OTHERS);
s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
}
static int s5pv210_pm_add(struct sys_device *sysdev)
{
pm_cpu_prep = s5pv210_pm_prepare;
pm_cpu_sleep = s5pv210_cpu_suspend;
return 0;
}
static int s5pv210_pm_resume(struct sys_device *dev)
{
u32 tmp;
tmp = __raw_readl(S5P_OTHERS);
tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\
S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART);
__raw_writel(tmp , S5P_OTHERS);
s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
return 0;
}
static struct sysdev_driver s5pv210_pm_driver = {
.add = s5pv210_pm_add,
.resume = s5pv210_pm_resume,
};
static __init int s5pv210_pm_drvinit(void)
{
return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
}
arch_initcall(s5pv210_pm_drvinit);
...@@ -21,33 +21,21 @@ ...@@ -21,33 +21,21 @@
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
void s5pv210_fb_gpio_setup_24bpp(void) static void s5pv210_fb_cfg_gpios(unsigned int base, unsigned int nr)
{ {
unsigned int gpio = 0; s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
for (gpio = S5PV210_GPF0(0); gpio <= S5PV210_GPF0(7); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
for (gpio = S5PV210_GPF1(0); gpio <= S5PV210_GPF1(7); gpio++) { for (; nr > 0; nr--, base++)
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); }
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
for (gpio = S5PV210_GPF2(0); gpio <= S5PV210_GPF2(7); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
for (gpio = S5PV210_GPF3(0); gpio <= S5PV210_GPF3(3); gpio++) { void s5pv210_fb_gpio_setup_24bpp(void)
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); {
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); s5pv210_fb_cfg_gpios(S5PV210_GPF0(0), 8);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4); s5pv210_fb_cfg_gpios(S5PV210_GPF1(0), 8);
} s5pv210_fb_cfg_gpios(S5PV210_GPF2(0), 8);
s5pv210_fb_cfg_gpios(S5PV210_GPF3(0), 4);
/* Set DISPLAY_CONTROL register for Display path selection. /* Set DISPLAY_CONTROL register for Display path selection.
* *
......
...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */ ...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev) void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2,
s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
} }
...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */ ...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev) void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2,
s3c_gpio_setpull(S5PV210_GPD1(2), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV210_GPD1(3), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPD1(3), S3C_GPIO_PULL_UP);
} }
...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */ ...@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c2_cfg_gpio(struct platform_device *dev) void s3c_i2c2_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2,
s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
} }
...@@ -15,36 +15,25 @@ ...@@ -15,36 +15,25 @@
#include <plat/gpio-cfg.h> #include <plat/gpio-cfg.h>
static void s5pv210_ide_cfg_gpios(unsigned int base, unsigned int nr)
{
s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
for (; nr > 0; nr--, base++)
s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
}
void s5pv210_ide_setup_gpio(void) void s5pv210_ide_setup_gpio(void)
{ {
unsigned int gpio = 0; /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
s5pv210_ide_cfg_gpios(S5PV210_GPJ0(0), 8);
for (gpio = S5PV210_GPJ0(0); gpio <= S5PV210_GPJ0(7); gpio++) {
/* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, /* CF_Data[0 - 7] */
CF_DMACK */ s5pv210_ide_cfg_gpios(S5PV210_GPJ2(0), 8);
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
for (gpio = S5PV210_GPJ2(0); gpio <= S5PV210_GPJ2(7); gpio++) {
/*CF_Data[0 - 7] */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
for (gpio = S5PV210_GPJ3(0); gpio <= S5PV210_GPJ3(7); gpio++) {
/* CF_Data[8 - 15] */ /* CF_Data[8 - 15] */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); s5pv210_ide_cfg_gpios(S5PV210_GPJ3(0), 8);
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
for (gpio = S5PV210_GPJ4(0); gpio <= S5PV210_GPJ4(3); gpio++) {
/* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */ /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4)); s5pv210_ide_cfg_gpios(S5PV210_GPJ4(0), 4);
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
} }
...@@ -16,19 +16,9 @@ ...@@ -16,19 +16,9 @@
void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
{ {
unsigned int gpio, end;
/* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */ /* Set all the necessary GPH3 pins to special-function 3: KP_ROW[x] */
end = S5PV210_GPH3(rows); s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3));
for (gpio = S5PV210_GPH3(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
/* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */ /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
end = S5PV210_GPH2(cols); s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3));
for (gpio = S5PV210_GPH2(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
} }
...@@ -26,26 +26,17 @@ ...@@ -26,26 +26,17 @@
void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG0/GPG1 pins to special-function 2 */ /* Set all the necessary GPG0/GPG1 pins to special-function 2 */
for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
switch (width) { switch (width) {
case 8: case 8:
/* GPG1[3:6] special-funtion 3 */ /* GPG1[3:6] special-funtion 3 */
for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
case 4: case 4:
/* GPG0[3:6] special-funtion 2 */ /* GPG0[3:6] special-funtion 2 */
for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
default: default:
break; break;
} }
...@@ -59,19 +50,12 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) ...@@ -59,19 +50,12 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG1[0:1] pins to special-function 2 */ /* Set all the necessary GPG1[0:1] pins to special-function 2 */
for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
/* Data pin GPG1[3:6] to special-function 2 */ /* Data pin GPG1[3:6] to special-function 2 */
for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
...@@ -82,27 +66,17 @@ void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) ...@@ -82,27 +66,17 @@ void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG2[0:1] pins to special-function 2 */ /* Set all the necessary GPG2[0:1] pins to special-function 2 */
for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
switch (width) { switch (width) {
case 8: case 8:
/* Data pin GPG3[3:6] to special-function 3 */ /* Data pin GPG3[3:6] to special-function 3 */
for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
case 4: case 4:
/* Data pin GPG2[3:6] to special-function 2 */ /* Data pin GPG2[3:6] to special-function 2 */
for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
default: default:
break; break;
} }
...@@ -116,19 +90,12 @@ void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width) ...@@ -116,19 +90,12 @@ void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
{ {
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG3[0:2] pins to special-function 2 */ /* Set all the necessary GPG3[0:1] pins to special-function 2 */
for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
/* Data pin GPG3[3:6] to special-function 2 */ /* Data pin GPG3[3:6] to special-function 2 */
for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) { s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) { if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
......
/* linux/arch/arm/plat-s5p/sleep.S
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV210 power Manager (Suspend-To-RAM) support
* Based on S3C2410 sleep code by:
* Ben Dooks, (c) 2004 Simtec Electronics
*
* Based on PXA/SA1100 sleep code by:
* Nicolas Pitre, (c) 2002 Monta Vista Software Inc
* Cliff Brake, (c) 2001
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/memory.h>
.text
/* s3c_cpu_save
*
* entry:
* r0 = save address (virtual addr of s3c_sleep_save_phys)
*/
ENTRY(s3c_cpu_save)
stmfd sp!, { r3 - r12, lr }
mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
mrc p15, 0, r5, c3, c0, 0 @ Domain ID
mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
mrc p15, 0, r9, c1, c0, 0 @ Control register
mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
mrc p15, 0, r12, c10, c2, 0 @ Read PRRR
mrc p15, 0, r3, c10, c2, 1 @ READ NMRR
stmia r0, { r3 - r13 }
bl s3c_pm_cb_flushcache
ldr r0, =pm_cpu_sleep
ldr r0, [ r0 ]
mov pc, r0
resume_with_mmu:
/*
* After MMU is turned on, restore the previous MMU table.
*/
ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET)
add r4, r4, r9
str r12, [r4]
ldmfd sp!, { r3 - r12, pc }
.ltorg
.data
.global s3c_sleep_save_phys
s3c_sleep_save_phys:
.word 0
/* sleep magic, to allow the bootloader to check for an valid
* image to resume to. Must be the first word before the
* s3c_cpu_resume entry.
*/
.word 0x2bedf00d
/* 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)
mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
msr cpsr_c, r0
mov r1, #0
mcr p15, 0, r1, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r1, c7, c5, 0 @ invalidate I Cache
ldr r0, s3c_sleep_save_phys @ address of restore block
ldmia r0, { r3 - r13 }
mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
mcr p15, 0, r5, c3, c0, 0 @ Domain ID
mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB
mov r0, #0 @ restore copro access
mcr p15, 0, r11, c1, c0, 2 @ Co-processor access
mcr p15, 0, r0, c7, c5, 4
mcr p15, 0, r12, c10, c2, 0 @ write PRRR
mcr p15, 0, r3, c10, c2, 1 @ write NMRR
/*
* In Cortex-A8, when MMU is turned on, the pipeline is flushed.
* And there are no valid entries in the MMU table at this point.
* So before turning on the MMU, the MMU entry for the DRAM address
* range is added. After the MMU is turned on, the other entries
* in the MMU table will be restored.
*/
/* r6 = Translation Table BASE0 */
mov r4, r6
mov r4, r4, LSR #14
mov r4, r4, LSL #14
/* Load address for adding to MMU table list */
ldr r11, =0xE010F000 @ INFORM0 reg.
ldr r10, [r11, #0]
mov r10, r10, LSR #18
bic r10, r10, #0x3
orr r4, r4, r10
/* Calculate MMU table entry */
mov r10, r10, LSL #18
ldr r5, =0x40E
orr r10, r10, r5
/* Back up originally data */
ldr r12, [r4]
/* Add calculated MMU table entry into MMU table list */
str r10, [r4]
ldr r2, =resume_with_mmu
mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc
nop
nop
nop
nop
nop @ second-to-last before mmu
mov pc, r2 @ go back to virtual address
.ltorg
...@@ -11,7 +11,6 @@ if ARCH_S5PV310 ...@@ -11,7 +11,6 @@ if ARCH_S5PV310
config CPU_S5PV310 config CPU_S5PV310
bool bool
select PLAT_S5P
help help
Enable S5PV310 CPU support Enable S5PV310 CPU support
...@@ -25,21 +24,105 @@ config S5PV310_SETUP_I2C2 ...@@ -25,21 +24,105 @@ config S5PV310_SETUP_I2C2
help help
Common setup code for i2c bus 2. Common setup code for i2c bus 2.
config S5PV310_SETUP_I2C3
bool
help
Common setup code for i2c bus 3.
config S5PV310_SETUP_I2C4
bool
help
Common setup code for i2c bus 4.
config S5PV310_SETUP_I2C5
bool
help
Common setup code for i2c bus 5.
config S5PV310_SETUP_I2C6
bool
help
Common setup code for i2c bus 6.
config S5PV310_SETUP_I2C7
bool
help
Common setup code for i2c bus 7.
config S5PV310_SETUP_SDHCI
bool
select S5PV310_SETUP_SDHCI_GPIO
help
Internal helper functions for S5PV310 based SDHCI systems.
config S5PV310_SETUP_SDHCI_GPIO
bool
help
Common setup code for SDHCI gpio.
# machine support # machine support
config MACH_SMDKV310 menu "S5PC210 Machines"
bool "SMDKV310"
config MACH_SMDKC210
bool "SMDKC210"
select CPU_S5PV310 select CPU_S5PV310
select ARCH_SPARSEMEM_ENABLE select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
select S5PV310_SETUP_SDHCI
help help
Machine support for Samsung SMDKV310 Machine support for Samsung SMDKC210
S5PC210(MCP) is one of package option of S5PV310
config MACH_UNIVERSAL_C210 config MACH_UNIVERSAL_C210
bool "Mobile UNIVERSAL_C210 Board" bool "Mobile UNIVERSAL_C210 Board"
select CPU_S5PV310 select CPU_S5PV310
select ARCH_SPARSEMEM_ENABLE select S5P_DEV_ONENAND
select S3C_DEV_I2C1
select S5PV310_SETUP_I2C1
help help
Machine support for Samsung Mobile Universal S5PC210 Reference Machine support for Samsung Mobile Universal S5PC210 Reference
Board. S5PC210(MCP) is one of package option of S5PV310 Board. S5PC210(MCP) is one of package option of S5PV310
endmenu
menu "S5PV310 Machines"
config MACH_SMDKV310
bool "SMDKV310"
select CPU_S5PV310
select S3C_DEV_RTC
select S3C_DEV_WDT
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
select S5PV310_SETUP_SDHCI
help
Machine support for Samsung SMDKV310
endmenu
comment "Configuration for HSMMC bus width"
menu "Use 8-bit bus width"
config S5PV310_SDHCI_CH0_8BIT
bool "Channel 0 with 8-bit bus"
help
Support HSMMC Channel 0 8-bit bus.
If selected, Channel 1 is disabled.
config S5PV310_SDHCI_CH2_8BIT
bool "Channel 2 with 8-bit bus"
help
Support HSMMC Channel 2 8-bit bus.
If selected, Channel 3 is disabled.
endmenu
endif endif
...@@ -13,7 +13,7 @@ obj- := ...@@ -13,7 +13,7 @@ obj- :=
# Core support for S5PV310 system # Core support for S5PV310 system
obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o
obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
...@@ -21,6 +21,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o ...@@ -21,6 +21,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
# machine support # machine support
obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o
obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
...@@ -28,3 +29,10 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o ...@@ -28,3 +29,10 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o
obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o
obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o
obj-$(CONFIG_S5PV310_SETUP_I2C4) += setup-i2c4.o
obj-$(CONFIG_S5PV310_SETUP_I2C5) += setup-i2c5.o
obj-$(CONFIG_S5PV310_SETUP_I2C6) += setup-i2c6.o
obj-$(CONFIG_S5PV310_SETUP_I2C7) += setup-i2c7.o
obj-$(CONFIG_S5PV310_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S5PV310_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
...@@ -30,16 +30,92 @@ static struct clk clk_sclk_hdmi27m = { ...@@ -30,16 +30,92 @@ static struct clk clk_sclk_hdmi27m = {
.rate = 27000000, .rate = 27000000,
}; };
static struct clk clk_sclk_hdmiphy = {
.name = "sclk_hdmiphy",
.id = -1,
};
static struct clk clk_sclk_usbphy0 = {
.name = "sclk_usbphy0",
.id = -1,
.rate = 27000000,
};
static struct clk clk_sclk_usbphy1 = {
.name = "sclk_usbphy1",
.id = -1,
};
static int s5pv310_clksrc_mask_top_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
}
static int s5pv310_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKSRC_MASK_CAM, clk, enable);
}
static int s5pv310_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKSRC_MASK_LCD0, clk, enable);
}
static int s5pv310_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKSRC_MASK_LCD1, clk, enable);
}
static int s5pv310_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKSRC_MASK_FSYS, clk, enable);
}
static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable) static int s5pv310_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
{ {
return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable); return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL0, clk, enable);
} }
static int s5pv310_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
}
static int s5pv310_clk_ip_cam_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
}
static int s5pv310_clk_ip_image_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
}
static int s5pv310_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP_LCD0, clk, enable);
}
static int s5pv310_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP_LCD1, clk, enable);
}
static int s5pv310_clk_ip_fsys_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP_FSYS, clk, enable);
}
static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable) static int s5pv310_clk_ip_peril_ctrl(struct clk *clk, int enable)
{ {
return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable); return s5p_gatectrl(S5P_CLKGATE_IP_PERIL, clk, enable);
} }
static int s5pv310_clk_ip_perir_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
}
/* Core list of CMU_CPU side */ /* Core list of CMU_CPU side */
static struct clksrc_clk clk_mout_apll = { static struct clksrc_clk clk_mout_apll = {
...@@ -79,7 +155,7 @@ static struct clksrc_clk clk_mout_mpll = { ...@@ -79,7 +155,7 @@ static struct clksrc_clk clk_mout_mpll = {
}; };
static struct clk *clkset_moutcore_list[] = { static struct clk *clkset_moutcore_list[] = {
[0] = &clk_sclk_apll.clk, [0] = &clk_mout_apll.clk,
[1] = &clk_mout_mpll.clk, [1] = &clk_mout_mpll.clk,
}; };
...@@ -150,24 +226,6 @@ static struct clksrc_clk clk_periphclk = { ...@@ -150,24 +226,6 @@ static struct clksrc_clk clk_periphclk = {
.reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 }, .reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 12, .size = 3 },
}; };
static struct clksrc_clk clk_atclk = {
.clk = {
.name = "atclk",
.id = -1,
.parent = &clk_moutcore.clk,
},
.reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 16, .size = 3 },
};
static struct clksrc_clk clk_pclk_dbg = {
.clk = {
.name = "pclk_dbg",
.id = -1,
.parent = &clk_atclk.clk,
},
.reg_div = { .reg = S5P_CLKDIV_CPU, .shift = 20, .size = 3 },
};
/* Core list of CMU_CORE side */ /* Core list of CMU_CORE side */
static struct clk *clkset_corebus_list[] = { static struct clk *clkset_corebus_list[] = {
...@@ -241,7 +299,7 @@ static struct clk *clkset_aclk_top_list[] = { ...@@ -241,7 +299,7 @@ static struct clk *clkset_aclk_top_list[] = {
[1] = &clk_sclk_apll.clk, [1] = &clk_sclk_apll.clk,
}; };
static struct clksrc_sources clkset_aclk_200 = { static struct clksrc_sources clkset_aclk = {
.sources = clkset_aclk_top_list, .sources = clkset_aclk_top_list,
.nr_sources = ARRAY_SIZE(clkset_aclk_top_list), .nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
}; };
...@@ -251,52 +309,37 @@ static struct clksrc_clk clk_aclk_200 = { ...@@ -251,52 +309,37 @@ static struct clksrc_clk clk_aclk_200 = {
.name = "aclk_200", .name = "aclk_200",
.id = -1, .id = -1,
}, },
.sources = &clkset_aclk_200, .sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 }, .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 }, .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 0, .size = 3 },
}; };
static struct clksrc_sources clkset_aclk_100 = {
.sources = clkset_aclk_top_list,
.nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
};
static struct clksrc_clk clk_aclk_100 = { static struct clksrc_clk clk_aclk_100 = {
.clk = { .clk = {
.name = "aclk_100", .name = "aclk_100",
.id = -1, .id = -1,
}, },
.sources = &clkset_aclk_100, .sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 }, .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 }, .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 4, .size = 4 },
}; };
static struct clksrc_sources clkset_aclk_160 = {
.sources = clkset_aclk_top_list,
.nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
};
static struct clksrc_clk clk_aclk_160 = { static struct clksrc_clk clk_aclk_160 = {
.clk = { .clk = {
.name = "aclk_160", .name = "aclk_160",
.id = -1, .id = -1,
}, },
.sources = &clkset_aclk_160, .sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 }, .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 }, .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 8, .size = 3 },
}; };
static struct clksrc_sources clkset_aclk_133 = {
.sources = clkset_aclk_top_list,
.nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
};
static struct clksrc_clk clk_aclk_133 = { static struct clksrc_clk clk_aclk_133 = {
.clk = { .clk = {
.name = "aclk_133", .name = "aclk_133",
.id = -1, .id = -1,
}, },
.sources = &clkset_aclk_133, .sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 }, .reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 }, .reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
}; };
...@@ -315,6 +358,8 @@ static struct clksrc_clk clk_vpllsrc = { ...@@ -315,6 +358,8 @@ static struct clksrc_clk clk_vpllsrc = {
.clk = { .clk = {
.name = "vpll_src", .name = "vpll_src",
.id = -1, .id = -1,
.enable = s5pv310_clksrc_mask_top_ctrl,
.ctrlbit = (1 << 0),
}, },
.sources = &clkset_vpllsrc, .sources = &clkset_vpllsrc,
.reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 }, .reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
...@@ -346,7 +391,175 @@ static struct clk init_clocks_disable[] = { ...@@ -346,7 +391,175 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_aclk_100.clk, .parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl, .enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1<<24), .ctrlbit = (1<<24),
} }, {
.name = "csis",
.id = 0,
.enable = s5pv310_clk_ip_cam_ctrl,
.ctrlbit = (1 << 4),
}, {
.name = "csis",
.id = 1,
.enable = s5pv310_clk_ip_cam_ctrl,
.ctrlbit = (1 << 5),
}, {
.name = "fimc",
.id = 0,
.enable = s5pv310_clk_ip_cam_ctrl,
.ctrlbit = (1 << 0),
}, {
.name = "fimc",
.id = 1,
.enable = s5pv310_clk_ip_cam_ctrl,
.ctrlbit = (1 << 1),
}, {
.name = "fimc",
.id = 2,
.enable = s5pv310_clk_ip_cam_ctrl,
.ctrlbit = (1 << 2),
}, {
.name = "fimc",
.id = 3,
.enable = s5pv310_clk_ip_cam_ctrl,
.ctrlbit = (1 << 3),
}, {
.name = "fimd",
.id = 0,
.enable = s5pv310_clk_ip_lcd0_ctrl,
.ctrlbit = (1 << 0),
}, {
.name = "fimd",
.id = 1,
.enable = s5pv310_clk_ip_lcd1_ctrl,
.ctrlbit = (1 << 0),
}, {
.name = "hsmmc",
.id = 0,
.parent = &clk_aclk_133.clk,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 5),
}, {
.name = "hsmmc",
.id = 1,
.parent = &clk_aclk_133.clk,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 6),
}, {
.name = "hsmmc",
.id = 2,
.parent = &clk_aclk_133.clk,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 7),
}, {
.name = "hsmmc",
.id = 3,
.parent = &clk_aclk_133.clk,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 8),
}, {
.name = "hsmmc",
.id = 4,
.parent = &clk_aclk_133.clk,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 9),
}, {
.name = "sata",
.id = -1,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 10),
}, {
.name = "adc",
.id = -1,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 15),
}, {
.name = "rtc",
.id = -1,
.enable = s5pv310_clk_ip_perir_ctrl,
.ctrlbit = (1 << 15),
}, {
.name = "watchdog",
.id = -1,
.enable = s5pv310_clk_ip_perir_ctrl,
.ctrlbit = (1 << 14),
}, {
.name = "usbhost",
.id = -1,
.enable = s5pv310_clk_ip_fsys_ctrl ,
.ctrlbit = (1 << 12),
}, {
.name = "otg",
.id = -1,
.enable = s5pv310_clk_ip_fsys_ctrl,
.ctrlbit = (1 << 13),
}, {
.name = "spi",
.id = 0,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 16),
}, {
.name = "spi",
.id = 1,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 17),
}, {
.name = "spi",
.id = 2,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 18),
}, {
.name = "fimg2d",
.id = -1,
.enable = s5pv310_clk_ip_image_ctrl,
.ctrlbit = (1 << 0),
}, {
.name = "i2c",
.id = 0,
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 6),
}, {
.name = "i2c",
.id = 1,
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 7),
}, {
.name = "i2c",
.id = 2,
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 8),
}, {
.name = "i2c",
.id = 3,
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 9),
}, {
.name = "i2c",
.id = 4,
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 10),
}, {
.name = "i2c",
.id = 5,
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 11),
}, {
.name = "i2c",
.id = 6,
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 12),
}, {
.name = "i2c",
.id = 7,
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.ctrlbit = (1 << 13),
},
}; };
static struct clk init_clocks[] = { static struct clk init_clocks[] = {
...@@ -387,6 +600,9 @@ static struct clk *clkset_group_list[] = { ...@@ -387,6 +600,9 @@ static struct clk *clkset_group_list[] = {
[0] = &clk_ext_xtal_mux, [0] = &clk_ext_xtal_mux,
[1] = &clk_xusbxti, [1] = &clk_xusbxti,
[2] = &clk_sclk_hdmi27m, [2] = &clk_sclk_hdmi27m,
[3] = &clk_sclk_usbphy0,
[4] = &clk_sclk_usbphy1,
[5] = &clk_sclk_hdmiphy,
[6] = &clk_mout_mpll.clk, [6] = &clk_mout_mpll.clk,
[7] = &clk_mout_epll.clk, [7] = &clk_mout_epll.clk,
[8] = &clk_sclk_vpll.clk, [8] = &clk_sclk_vpll.clk,
...@@ -397,6 +613,104 @@ static struct clksrc_sources clkset_group = { ...@@ -397,6 +613,104 @@ static struct clksrc_sources clkset_group = {
.nr_sources = ARRAY_SIZE(clkset_group_list), .nr_sources = ARRAY_SIZE(clkset_group_list),
}; };
static struct clk *clkset_mout_g2d0_list[] = {
[0] = &clk_mout_mpll.clk,
[1] = &clk_sclk_apll.clk,
};
static struct clksrc_sources clkset_mout_g2d0 = {
.sources = clkset_mout_g2d0_list,
.nr_sources = ARRAY_SIZE(clkset_mout_g2d0_list),
};
static struct clksrc_clk clk_mout_g2d0 = {
.clk = {
.name = "mout_g2d0",
.id = -1,
},
.sources = &clkset_mout_g2d0,
.reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 0, .size = 1 },
};
static struct clk *clkset_mout_g2d1_list[] = {
[0] = &clk_mout_epll.clk,
[1] = &clk_sclk_vpll.clk,
};
static struct clksrc_sources clkset_mout_g2d1 = {
.sources = clkset_mout_g2d1_list,
.nr_sources = ARRAY_SIZE(clkset_mout_g2d1_list),
};
static struct clksrc_clk clk_mout_g2d1 = {
.clk = {
.name = "mout_g2d1",
.id = -1,
},
.sources = &clkset_mout_g2d1,
.reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 4, .size = 1 },
};
static struct clk *clkset_mout_g2d_list[] = {
[0] = &clk_mout_g2d0.clk,
[1] = &clk_mout_g2d1.clk,
};
static struct clksrc_sources clkset_mout_g2d = {
.sources = clkset_mout_g2d_list,
.nr_sources = ARRAY_SIZE(clkset_mout_g2d_list),
};
static struct clksrc_clk clk_dout_mmc0 = {
.clk = {
.name = "dout_mmc0",
.id = -1,
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_dout_mmc1 = {
.clk = {
.name = "dout_mmc1",
.id = -1,
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 4, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 16, .size = 4 },
};
static struct clksrc_clk clk_dout_mmc2 = {
.clk = {
.name = "dout_mmc2",
.id = -1,
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 8, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 0, .size = 4 },
};
static struct clksrc_clk clk_dout_mmc3 = {
.clk = {
.name = "dout_mmc3",
.id = -1,
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 12, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 16, .size = 4 },
};
static struct clksrc_clk clk_dout_mmc4 = {
.clk = {
.name = "dout_mmc4",
.id = -1,
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 16, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 0, .size = 4 },
};
static struct clksrc_clk clksrcs[] = { static struct clksrc_clk clksrcs[] = {
{ {
.clk = { .clk = {
...@@ -448,7 +762,200 @@ static struct clksrc_clk clksrcs[] = { ...@@ -448,7 +762,200 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group, .sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 }, .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 }, .reg_div = { .reg = S5P_CLKDIV_PERIL3, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_csis",
.id = 0,
.enable = s5pv310_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 24),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 24, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 24, .size = 4 },
}, {
.clk = {
.name = "sclk_csis",
.id = 1,
.enable = s5pv310_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 28),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 28, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 28, .size = 4 },
}, {
.clk = {
.name = "sclk_cam",
.id = 0,
.enable = s5pv310_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 16),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 16, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 16, .size = 4 },
}, {
.clk = {
.name = "sclk_cam",
.id = 1,
.enable = s5pv310_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 20),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 20, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 20, .size = 4 },
}, {
.clk = {
.name = "sclk_fimc",
.id = 0,
.enable = s5pv310_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 0),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_fimc",
.id = 1,
.enable = s5pv310_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 4),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 4, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 4, .size = 4 },
}, {
.clk = {
.name = "sclk_fimc",
.id = 2,
.enable = s5pv310_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 8),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 8, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 8, .size = 4 },
}, {
.clk = {
.name = "sclk_fimc",
.id = 3,
.enable = s5pv310_clksrc_mask_cam_ctrl,
.ctrlbit = (1 << 12),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_CAM, .shift = 12, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_CAM, .shift = 12, .size = 4 },
}, {
.clk = {
.name = "sclk_fimd",
.id = 0,
.enable = s5pv310_clksrc_mask_lcd0_ctrl,
.ctrlbit = (1 << 0),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_LCD0, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_LCD0, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_fimd",
.id = 1,
.enable = s5pv310_clksrc_mask_lcd1_ctrl,
.ctrlbit = (1 << 0),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_LCD1, .shift = 0, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_LCD1, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_sata",
.id = -1,
.enable = s5pv310_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 24),
},
.sources = &clkset_mout_corebus,
.reg_src = { .reg = S5P_CLKSRC_FSYS, .shift = 24, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_FSYS0, .shift = 20, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.id = 0,
.enable = s5pv310_clksrc_mask_peril1_ctrl,
.ctrlbit = (1 << 16),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 16, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.id = 1,
.enable = s5pv310_clksrc_mask_peril1_ctrl,
.ctrlbit = (1 << 20),
}, },
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 20, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL1, .shift = 16, .size = 4 },
}, {
.clk = {
.name = "sclk_spi",
.id = 2,
.enable = s5pv310_clksrc_mask_peril1_ctrl,
.ctrlbit = (1 << 24),
},
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL1, .shift = 24, .size = 4 },
.reg_div = { .reg = S5P_CLKDIV_PERIL2, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_fimg2d",
.id = -1,
},
.sources = &clkset_mout_g2d,
.reg_src = { .reg = S5P_CLKSRC_IMAGE, .shift = 8, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_IMAGE, .shift = 0, .size = 4 },
}, {
.clk = {
.name = "sclk_mmc",
.id = 0,
.parent = &clk_dout_mmc0.clk,
.enable = s5pv310_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 0),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 8, .size = 8 },
}, {
.clk = {
.name = "sclk_mmc",
.id = 1,
.parent = &clk_dout_mmc1.clk,
.enable = s5pv310_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 4),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS1, .shift = 24, .size = 8 },
}, {
.clk = {
.name = "sclk_mmc",
.id = 2,
.parent = &clk_dout_mmc2.clk,
.enable = s5pv310_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 8),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 8, .size = 8 },
}, {
.clk = {
.name = "sclk_mmc",
.id = 3,
.parent = &clk_dout_mmc3.clk,
.enable = s5pv310_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 12),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS2, .shift = 24, .size = 8 },
}, {
.clk = {
.name = "sclk_mmc",
.id = 4,
.parent = &clk_dout_mmc4.clk,
.enable = s5pv310_clksrc_mask_fsys_ctrl,
.ctrlbit = (1 << 16),
},
.reg_div = { .reg = S5P_CLKDIV_FSYS3, .shift = 8, .size = 8 },
}
}; };
/* Clock initialization code */ /* Clock initialization code */
...@@ -464,8 +971,6 @@ static struct clksrc_clk *sysclks[] = { ...@@ -464,8 +971,6 @@ static struct clksrc_clk *sysclks[] = {
&clk_aclk_cores, &clk_aclk_cores,
&clk_aclk_corem1, &clk_aclk_corem1,
&clk_periphclk, &clk_periphclk,
&clk_atclk,
&clk_pclk_dbg,
&clk_mout_corebus, &clk_mout_corebus,
&clk_sclk_dmc, &clk_sclk_dmc,
&clk_aclk_cored, &clk_aclk_cored,
...@@ -478,6 +983,11 @@ static struct clksrc_clk *sysclks[] = { ...@@ -478,6 +983,11 @@ static struct clksrc_clk *sysclks[] = {
&clk_aclk_100, &clk_aclk_100,
&clk_aclk_160, &clk_aclk_160,
&clk_aclk_133, &clk_aclk_133,
&clk_dout_mmc0,
&clk_dout_mmc1,
&clk_dout_mmc2,
&clk_dout_mmc3,
&clk_dout_mmc4,
}; };
void __init_or_cpufreq s5pv310_setup_clocks(void) void __init_or_cpufreq s5pv310_setup_clocks(void)
...@@ -490,15 +1000,11 @@ void __init_or_cpufreq s5pv310_setup_clocks(void) ...@@ -490,15 +1000,11 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
unsigned long vpllsrc; unsigned long vpllsrc;
unsigned long xtal; unsigned long xtal;
unsigned long armclk; unsigned long armclk;
unsigned long aclk_corem0;
unsigned long aclk_cores;
unsigned long aclk_corem1;
unsigned long periphclk;
unsigned long sclk_dmc; unsigned long sclk_dmc;
unsigned long aclk_cored; unsigned long aclk_200;
unsigned long aclk_corep; unsigned long aclk_100;
unsigned long aclk_acp; unsigned long aclk_160;
unsigned long pclk_acp; unsigned long aclk_133;
unsigned int ptr; unsigned int ptr;
printk(KERN_DEBUG "%s: registering clocks\n", __func__); printk(KERN_DEBUG "%s: registering clocks\n", __func__);
...@@ -529,26 +1035,21 @@ void __init_or_cpufreq s5pv310_setup_clocks(void) ...@@ -529,26 +1035,21 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
apll, mpll, epll, vpll); apll, mpll, epll, vpll);
armclk = clk_get_rate(&clk_armclk.clk); armclk = clk_get_rate(&clk_armclk.clk);
aclk_corem0 = clk_get_rate(&clk_aclk_corem0.clk);
aclk_cores = clk_get_rate(&clk_aclk_cores.clk);
aclk_corem1 = clk_get_rate(&clk_aclk_corem1.clk);
periphclk = clk_get_rate(&clk_periphclk.clk);
sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk); sclk_dmc = clk_get_rate(&clk_sclk_dmc.clk);
aclk_cored = clk_get_rate(&clk_aclk_cored.clk);
aclk_corep = clk_get_rate(&clk_aclk_corep.clk); aclk_200 = clk_get_rate(&clk_aclk_200.clk);
aclk_acp = clk_get_rate(&clk_aclk_acp.clk); aclk_100 = clk_get_rate(&clk_aclk_100.clk);
pclk_acp = clk_get_rate(&clk_pclk_acp.clk); aclk_160 = clk_get_rate(&clk_aclk_160.clk);
aclk_133 = clk_get_rate(&clk_aclk_133.clk);
printk(KERN_INFO "S5PV310: ARMCLK=%ld, COREM0=%ld, CORES=%ld\n"
"COREM1=%ld, PERI=%ld, DMC=%ld, CORED=%ld\n" printk(KERN_INFO "S5PV310: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
"COREP=%ld, ACLK_ACP=%ld, PCLK_ACP=%ld", "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
armclk, aclk_corem0, aclk_cores, aclk_corem1, armclk, sclk_dmc, aclk_200,
periphclk, sclk_dmc, aclk_cored, aclk_corep, aclk_100, aclk_160, aclk_133);
aclk_acp, pclk_acp);
clk_f.rate = armclk; clk_f.rate = armclk;
clk_h.rate = sclk_dmc; clk_h.rate = sclk_dmc;
clk_p.rate = periphclk; clk_p.rate = aclk_100;
for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
s3c_set_clksrc(&clksrcs[ptr], true); s3c_set_clksrc(&clksrcs[ptr], true);
......
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <asm/proc-fns.h> #include <asm/proc-fns.h>
#include <asm/hardware/cache-l2x0.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/s5pv310.h> #include <plat/s5pv310.h>
#include <plat/sdhci.h>
#include <mach/regs-irq.h> #include <mach/regs-irq.h>
...@@ -56,15 +58,30 @@ static struct map_desc s5pv310_iodesc[] __initdata = { ...@@ -56,15 +58,30 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
.length = SZ_4K, .length = SZ_4K,
.type = MT_DEVICE, .type = MT_DEVICE,
}, { }, {
.virtual = (unsigned long)S5P_VA_GPIO, .virtual = (unsigned long)S5P_VA_GPIO1,
.pfn = __phys_to_pfn(S5PV310_PA_GPIO1), .pfn = __phys_to_pfn(S5PV310_PA_GPIO1),
.length = SZ_4K, .length = SZ_4K,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_GPIO2,
.pfn = __phys_to_pfn(S5PV310_PA_GPIO2),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_GPIO3,
.pfn = __phys_to_pfn(S5PV310_PA_GPIO3),
.length = SZ_256,
.type = MT_DEVICE,
}, { }, {
.virtual = (unsigned long)S3C_VA_UART, .virtual = (unsigned long)S3C_VA_UART,
.pfn = __phys_to_pfn(S3C_PA_UART), .pfn = __phys_to_pfn(S3C_PA_UART),
.length = SZ_512K, .length = SZ_512K,
.type = MT_DEVICE, .type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_SROMC,
.pfn = __phys_to_pfn(S5PV310_PA_SROMC),
.length = SZ_4K,
.type = MT_DEVICE,
}, },
}; };
...@@ -83,6 +100,12 @@ static void s5pv310_idle(void) ...@@ -83,6 +100,12 @@ static void s5pv310_idle(void)
void __init s5pv310_map_io(void) void __init s5pv310_map_io(void)
{ {
iotable_init(s5pv310_iodesc, ARRAY_SIZE(s5pv310_iodesc)); iotable_init(s5pv310_iodesc, ARRAY_SIZE(s5pv310_iodesc));
/* initialize device information early */
s5pv310_default_sdhci0();
s5pv310_default_sdhci1();
s5pv310_default_sdhci2();
s5pv310_default_sdhci3();
} }
void __init s5pv310_init_clocks(int xtal) void __init s5pv310_init_clocks(int xtal)
...@@ -131,6 +154,28 @@ static int __init s5pv310_core_init(void) ...@@ -131,6 +154,28 @@ static int __init s5pv310_core_init(void)
core_initcall(s5pv310_core_init); core_initcall(s5pv310_core_init);
#ifdef CONFIG_CACHE_L2X0
static int __init s5pv310_l2x0_cache_init(void)
{
/* TAG, Data Latency Control: 2cycle */
__raw_writel(0x110, S5P_VA_L2CC + L2X0_TAG_LATENCY_CTRL);
__raw_writel(0x110, S5P_VA_L2CC + L2X0_DATA_LATENCY_CTRL);
/* L2X0 Prefetch Control */
__raw_writel(0x30000007, S5P_VA_L2CC + L2X0_PREFETCH_CTRL);
/* L2X0 Power Control */
__raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN,
S5P_VA_L2CC + L2X0_POWER_CTRL);
l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff);
return 0;
}
early_initcall(s5pv310_l2x0_cache_init);
#endif
int __init s5pv310_init(void) int __init s5pv310_init(void)
{ {
printk(KERN_INFO "S5PV310: Initializing architecture\n"); printk(KERN_INFO "S5PV310: Initializing architecture\n");
......
/* linux/arch/arm/mach-s5pv310/gpiolib.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - GPIOlib support
*
* 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/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <mach/map.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
static struct s3c_gpio_cfg gpio_cfg = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
static struct s3c_gpio_cfg gpio_cfg_noint = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
/*
* Following are the gpio banks in v310.
*
* The 'config' member when left to NULL, is initialized to the default
* structure gpio_cfg in the init function below.
*
* The 'base' member is also initialized in the init function below.
* Note: The initialization of 'base' member of s3c_gpio_chip structure
* uses the above macro and depends on the banks being listed in order here.
*/
static struct s3c_gpio_chip s5pv310_gpio_part1_4bit[] = {
{
.chip = {
.base = S5PV310_GPA0(0),
.ngpio = S5PV310_GPIO_A0_NR,
.label = "GPA0",
},
}, {
.chip = {
.base = S5PV310_GPA1(0),
.ngpio = S5PV310_GPIO_A1_NR,
.label = "GPA1",
},
}, {
.chip = {
.base = S5PV310_GPB(0),
.ngpio = S5PV310_GPIO_B_NR,
.label = "GPB",
},
}, {
.chip = {
.base = S5PV310_GPC0(0),
.ngpio = S5PV310_GPIO_C0_NR,
.label = "GPC0",
},
}, {
.chip = {
.base = S5PV310_GPC1(0),
.ngpio = S5PV310_GPIO_C1_NR,
.label = "GPC1",
},
}, {
.chip = {
.base = S5PV310_GPD0(0),
.ngpio = S5PV310_GPIO_D0_NR,
.label = "GPD0",
},
}, {
.chip = {
.base = S5PV310_GPD1(0),
.ngpio = S5PV310_GPIO_D1_NR,
.label = "GPD1",
},
}, {
.chip = {
.base = S5PV310_GPE0(0),
.ngpio = S5PV310_GPIO_E0_NR,
.label = "GPE0",
},
}, {
.chip = {
.base = S5PV310_GPE1(0),
.ngpio = S5PV310_GPIO_E1_NR,
.label = "GPE1",
},
}, {
.chip = {
.base = S5PV310_GPE2(0),
.ngpio = S5PV310_GPIO_E2_NR,
.label = "GPE2",
},
}, {
.chip = {
.base = S5PV310_GPE3(0),
.ngpio = S5PV310_GPIO_E3_NR,
.label = "GPE3",
},
}, {
.chip = {
.base = S5PV310_GPE4(0),
.ngpio = S5PV310_GPIO_E4_NR,
.label = "GPE4",
},
}, {
.chip = {
.base = S5PV310_GPF0(0),
.ngpio = S5PV310_GPIO_F0_NR,
.label = "GPF0",
},
}, {
.chip = {
.base = S5PV310_GPF1(0),
.ngpio = S5PV310_GPIO_F1_NR,
.label = "GPF1",
},
}, {
.chip = {
.base = S5PV310_GPF2(0),
.ngpio = S5PV310_GPIO_F2_NR,
.label = "GPF2",
},
}, {
.chip = {
.base = S5PV310_GPF3(0),
.ngpio = S5PV310_GPIO_F3_NR,
.label = "GPF3",
},
},
};
static struct s3c_gpio_chip s5pv310_gpio_part2_4bit[] = {
{
.chip = {
.base = S5PV310_GPJ0(0),
.ngpio = S5PV310_GPIO_J0_NR,
.label = "GPJ0",
},
}, {
.chip = {
.base = S5PV310_GPJ1(0),
.ngpio = S5PV310_GPIO_J1_NR,
.label = "GPJ1",
},
}, {
.chip = {
.base = S5PV310_GPK0(0),
.ngpio = S5PV310_GPIO_K0_NR,
.label = "GPK0",
},
}, {
.chip = {
.base = S5PV310_GPK1(0),
.ngpio = S5PV310_GPIO_K1_NR,
.label = "GPK1",
},
}, {
.chip = {
.base = S5PV310_GPK2(0),
.ngpio = S5PV310_GPIO_K2_NR,
.label = "GPK2",
},
}, {
.chip = {
.base = S5PV310_GPK3(0),
.ngpio = S5PV310_GPIO_K3_NR,
.label = "GPK3",
},
}, {
.chip = {
.base = S5PV310_GPL0(0),
.ngpio = S5PV310_GPIO_L0_NR,
.label = "GPL0",
},
}, {
.chip = {
.base = S5PV310_GPL1(0),
.ngpio = S5PV310_GPIO_L1_NR,
.label = "GPL1",
},
}, {
.chip = {
.base = S5PV310_GPL2(0),
.ngpio = S5PV310_GPIO_L2_NR,
.label = "GPL2",
},
}, {
.base = (S5P_VA_GPIO2 + 0xC00),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(0),
.chip = {
.base = S5PV310_GPX0(0),
.ngpio = S5PV310_GPIO_X0_NR,
.label = "GPX0",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO2 + 0xC20),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(8),
.chip = {
.base = S5PV310_GPX1(0),
.ngpio = S5PV310_GPIO_X1_NR,
.label = "GPX1",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO2 + 0xC40),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(16),
.chip = {
.base = S5PV310_GPX2(0),
.ngpio = S5PV310_GPIO_X2_NR,
.label = "GPX2",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO2 + 0xC60),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(24),
.chip = {
.base = S5PV310_GPX3(0),
.ngpio = S5PV310_GPIO_X3_NR,
.label = "GPX3",
.to_irq = samsung_gpiolib_to_irq,
},
},
};
static struct s3c_gpio_chip s5pv310_gpio_part3_4bit[] = {
{
.chip = {
.base = S5PV310_GPZ(0),
.ngpio = S5PV310_GPIO_Z_NR,
.label = "GPZ",
},
},
};
static __init int s5pv310_gpiolib_init(void)
{
struct s3c_gpio_chip *chip;
int i;
int nr_chips;
/* GPIO part 1 */
chip = s5pv310_gpio_part1_4bit;
nr_chips = ARRAY_SIZE(s5pv310_gpio_part1_4bit);
for (i = 0; i < nr_chips; i++, chip++) {
if (chip->config == NULL)
chip->config = &gpio_cfg;
if (chip->base == NULL)
chip->base = S5P_VA_GPIO1 + (i) * 0x20;
}
samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part1_4bit, nr_chips);
/* GPIO part 2 */
chip = s5pv310_gpio_part2_4bit;
nr_chips = ARRAY_SIZE(s5pv310_gpio_part2_4bit);
for (i = 0; i < nr_chips; i++, chip++) {
if (chip->config == NULL)
chip->config = &gpio_cfg;
if (chip->base == NULL)
chip->base = S5P_VA_GPIO2 + (i) * 0x20;
}
samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part2_4bit, nr_chips);
/* GPIO part 3 */
chip = s5pv310_gpio_part3_4bit;
nr_chips = ARRAY_SIZE(s5pv310_gpio_part3_4bit);
for (i = 0; i < nr_chips; i++, chip++) {
if (chip->config == NULL)
chip->config = &gpio_cfg;
if (chip->base == NULL)
chip->base = S5P_VA_GPIO3 + (i) * 0x20;
}
samsung_gpiolib_add_4bit_chips(s5pv310_gpio_part3_4bit, nr_chips);
return 0;
}
core_initcall(s5pv310_gpiolib_init);
/* linux arch/arm/mach-s5pv310/hotplug.c
*
* Cloned from linux/arch/arm/mach-realview/hotplug.c
*
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
*
* 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/errno.h>
#include <linux/smp.h>
#include <linux/completion.h>
#include <asm/cacheflush.h>
extern volatile int pen_release;
static DECLARE_COMPLETION(cpu_killed);
static inline void cpu_enter_lowpower(void)
{
unsigned int v;
flush_cache_all();
asm volatile(
" mcr p15, 0, %1, c7, c5, 0\n"
" mcr p15, 0, %1, c7, c10, 4\n"
/*
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1\n"
" bic %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n"
" mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, #0x04\n"
" mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v)
: "r" (0)
: "cc");
}
static inline void cpu_leave_lowpower(void)
{
unsigned int v;
asm volatile(
"mrc p15, 0, %0, c1, c0, 0\n"
" orr %0, %0, #0x04\n"
" mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n"
" orr %0, %0, #0x20\n"
" mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v)
:
: "cc");
}
static inline void platform_do_lowpower(unsigned int cpu)
{
/*
* there is no power-control hardware on this platform, so all
* we can do is put the core into WFI; this is safe as the calling
* code will have already disabled interrupts
*/
for (;;) {
/*
* here's the WFI
*/
asm(".word 0xe320f003\n"
:
:
: "memory", "cc");
if (pen_release == cpu) {
/*
* OK, proper wakeup, we're done
*/
break;
}
/*
* getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen
*
* The trouble is, letting people know about this is not really
* possible, since we are currently running incoherently, and
* therefore cannot safely call printk() or anything else
*/
#ifdef DEBUG
printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
#endif
}
}
int platform_cpu_kill(unsigned int cpu)
{
return wait_for_completion_timeout(&cpu_killed, 5000);
}
/*
* platform-specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
void platform_cpu_die(unsigned int cpu)
{
#ifdef DEBUG
unsigned int this_cpu = hard_smp_processor_id();
if (cpu != this_cpu) {
printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
this_cpu, cpu);
BUG();
}
#endif
printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
complete(&cpu_killed);
/*
* we're ready for shutdown now, so do it
*/
cpu_enter_lowpower();
platform_do_lowpower(cpu);
/*
* bring this CPU back into the world of cache
* coherency, and then restore interrupts
*/
cpu_leave_lowpower();
}
int platform_cpu_disable(unsigned int cpu)
{
/*
* we don't allow CPU 0 to be shutdown (it is still too special
* e.g. clock tick interrupts)
*/
return cpu == 0 ? -EPERM : 0;
}
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Copyright (c) 2010 Samsung Electronics Co., Ltd. * Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/ * http://www.samsung.com/
* *
* S5PV210 - IRQ definitions * S5PV310 - IRQ definitions
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -60,6 +60,9 @@ ...@@ -60,6 +60,9 @@
#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3) #define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3)
#define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4) #define IRQ_TIMER4_VIC COMBINER_IRQ(22, 4)
#define IRQ_RTC_ALARM COMBINER_IRQ(23, 0)
#define IRQ_RTC_TIC COMBINER_IRQ(23, 1)
#define IRQ_UART0 COMBINER_IRQ(26, 0) #define IRQ_UART0 COMBINER_IRQ(26, 0)
#define IRQ_UART1 COMBINER_IRQ(26, 1) #define IRQ_UART1 COMBINER_IRQ(26, 1)
#define IRQ_UART2 COMBINER_IRQ(26, 2) #define IRQ_UART2 COMBINER_IRQ(26, 2)
...@@ -67,13 +70,46 @@ ...@@ -67,13 +70,46 @@
#define IRQ_UART4 COMBINER_IRQ(26, 4) #define IRQ_UART4 COMBINER_IRQ(26, 4)
#define IRQ_IIC COMBINER_IRQ(27, 0) #define IRQ_IIC COMBINER_IRQ(27, 0)
#define IRQ_IIC1 COMBINER_IRQ(27, 1)
#define IRQ_IIC2 COMBINER_IRQ(27, 2)
#define IRQ_IIC3 COMBINER_IRQ(27, 3)
#define IRQ_IIC4 COMBINER_IRQ(27, 4)
#define IRQ_IIC5 COMBINER_IRQ(27, 5)
#define IRQ_IIC6 COMBINER_IRQ(27, 6)
#define IRQ_IIC7 COMBINER_IRQ(27, 7)
#define IRQ_HSMMC0 COMBINER_IRQ(29, 0)
#define IRQ_HSMMC1 COMBINER_IRQ(29, 1)
#define IRQ_HSMMC2 COMBINER_IRQ(29, 2)
#define IRQ_HSMMC3 COMBINER_IRQ(29, 3)
#define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0) #define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0)
/* Set the default NR_IRQS */ #define IRQ_EINT4 COMBINER_IRQ(37, 0)
#define IRQ_EINT5 COMBINER_IRQ(37, 1)
#define IRQ_EINT6 COMBINER_IRQ(37, 2)
#define IRQ_EINT7 COMBINER_IRQ(37, 3)
#define IRQ_EINT8 COMBINER_IRQ(38, 0)
#define IRQ_EINT9 COMBINER_IRQ(38, 1)
#define IRQ_EINT10 COMBINER_IRQ(38, 2)
#define IRQ_EINT11 COMBINER_IRQ(38, 3)
#define IRQ_EINT12 COMBINER_IRQ(38, 4)
#define IRQ_EINT13 COMBINER_IRQ(38, 5)
#define IRQ_EINT14 COMBINER_IRQ(38, 6)
#define IRQ_EINT15 COMBINER_IRQ(38, 7)
#define IRQ_EINT16_31 COMBINER_IRQ(39, 0)
#define NR_IRQS COMBINER_IRQ(MAX_COMBINER_NR, 0) #define MAX_COMBINER_NR 40
#define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0)
#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE + 0)
#define S5P_EINT_BASE2 (S5P_IRQ_EINT_BASE + 16)
/* Set the default NR_IRQS */
#define MAX_COMBINER_NR 39 #define NR_IRQS (S5P_IRQ_EINT_BASE + 32)
#endif /* __ASM_ARCH_IRQS_H */ #endif /* __ASM_ARCH_IRQS_H */
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#define S5PV310_PA_SYSRAM (0x02025000) #define S5PV310_PA_SYSRAM (0x02025000)
#define S5PV310_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
#define S5PC210_PA_ONENAND (0x0C000000) #define S5PC210_PA_ONENAND (0x0C000000)
#define S5P_PA_ONENAND S5PC210_PA_ONENAND #define S5P_PA_ONENAND S5PC210_PA_ONENAND
...@@ -34,12 +36,13 @@ ...@@ -34,12 +36,13 @@
#define S5PV310_PA_CHIPID (0x10000000) #define S5PV310_PA_CHIPID (0x10000000)
#define S5P_PA_CHIPID S5PV310_PA_CHIPID #define S5P_PA_CHIPID S5PV310_PA_CHIPID
#define S5PV310_PA_SYSCON (0x10020000) #define S5PV310_PA_SYSCON (0x10010000)
#define S5P_PA_SYSCON S5PV310_PA_SYSCON #define S5P_PA_SYSCON S5PV310_PA_SYSCON
#define S5PV310_PA_CMU (0x10030000) #define S5PV310_PA_CMU (0x10030000)
#define S5PV310_PA_WATCHDOG (0x10060000) #define S5PV310_PA_WATCHDOG (0x10060000)
#define S5PV310_PA_RTC (0x10070000)
#define S5PV310_PA_COMBINER (0x10448000) #define S5PV310_PA_COMBINER (0x10448000)
...@@ -55,6 +58,8 @@ ...@@ -55,6 +58,8 @@
#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000)) #define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
#define S5PV310_PA_SROMC (0x12570000)
#define S5PV310_PA_UART (0x13800000) #define S5PV310_PA_UART (0x13800000)
#define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET)) #define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET))
...@@ -66,7 +71,7 @@ ...@@ -66,7 +71,7 @@
#define S5P_SZ_UART SZ_256 #define S5P_SZ_UART SZ_256
#define S5PV310_PA_IIC0 (0x13860000) #define S5PV310_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
#define S5PV310_PA_TIMER (0x139D0000) #define S5PV310_PA_TIMER (0x139D0000)
#define S5P_PA_TIMER S5PV310_PA_TIMER #define S5P_PA_TIMER S5PV310_PA_TIMER
...@@ -80,7 +85,15 @@ ...@@ -80,7 +85,15 @@
#define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1) #define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1)
#define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2) #define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2)
#define S3C_PA_HSMMC3 S5PV310_PA_HSMMC(3) #define S3C_PA_HSMMC3 S5PV310_PA_HSMMC(3)
#define S3C_PA_IIC S5PV310_PA_IIC0 #define S3C_PA_IIC S5PV310_PA_IIC(0)
#define S3C_PA_IIC1 S5PV310_PA_IIC(1)
#define S3C_PA_IIC2 S5PV310_PA_IIC(2)
#define S3C_PA_IIC3 S5PV310_PA_IIC(3)
#define S3C_PA_IIC4 S5PV310_PA_IIC(4)
#define S3C_PA_IIC5 S5PV310_PA_IIC(5)
#define S3C_PA_IIC6 S5PV310_PA_IIC(6)
#define S3C_PA_IIC7 S5PV310_PA_IIC(7)
#define S3C_PA_RTC S5PV310_PA_RTC
#define S3C_PA_WDT S5PV310_PA_WATCHDOG #define S3C_PA_WDT S5PV310_PA_WATCHDOG
#endif /* __ASM_ARCH_MAP_H */ #endif /* __ASM_ARCH_MAP_H */
...@@ -26,11 +26,23 @@ ...@@ -26,11 +26,23 @@
#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210) #define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210)
#define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214) #define S5P_CLKSRC_TOP1 S5P_CLKREG(0x0C214)
#define S5P_CLKSRC_CAM S5P_CLKREG(0x0C220)
#define S5P_CLKSRC_IMAGE S5P_CLKREG(0x0C230)
#define S5P_CLKSRC_LCD0 S5P_CLKREG(0x0C234)
#define S5P_CLKSRC_LCD1 S5P_CLKREG(0x0C238)
#define S5P_CLKSRC_FSYS S5P_CLKREG(0x0C240)
#define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250) #define S5P_CLKSRC_PERIL0 S5P_CLKREG(0x0C250)
#define S5P_CLKSRC_PERIL1 S5P_CLKREG(0x0C254)
#define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510) #define S5P_CLKDIV_TOP S5P_CLKREG(0x0C510)
#define S5P_CLKDIV_CAM S5P_CLKREG(0x0C520)
#define S5P_CLKDIV_IMAGE S5P_CLKREG(0x0C530)
#define S5P_CLKDIV_LCD0 S5P_CLKREG(0x0C534)
#define S5P_CLKDIV_LCD1 S5P_CLKREG(0x0C538)
#define S5P_CLKDIV_FSYS0 S5P_CLKREG(0x0C540)
#define S5P_CLKDIV_FSYS1 S5P_CLKREG(0x0C544)
#define S5P_CLKDIV_FSYS2 S5P_CLKREG(0x0C548)
#define S5P_CLKDIV_FSYS3 S5P_CLKREG(0x0C54C)
#define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550) #define S5P_CLKDIV_PERIL0 S5P_CLKREG(0x0C550)
#define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554) #define S5P_CLKDIV_PERIL1 S5P_CLKREG(0x0C554)
#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558) #define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558)
...@@ -38,9 +50,21 @@ ...@@ -38,9 +50,21 @@
#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560) #define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560)
#define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564) #define S5P_CLKDIV_PERIL5 S5P_CLKREG(0x0C564)
#define S5P_CLKSRC_MASK_TOP S5P_CLKREG(0x0C310)
#define S5P_CLKSRC_MASK_CAM S5P_CLKREG(0x0C320)
#define S5P_CLKSRC_MASK_LCD0 S5P_CLKREG(0x0C334)
#define S5P_CLKSRC_MASK_LCD1 S5P_CLKREG(0x0C338)
#define S5P_CLKSRC_MASK_FSYS S5P_CLKREG(0x0C340)
#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350) #define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
#define S5P_CLKGATE_IP_LCD1 S5P_CLKREG(0x0C938)
#define S5P_CLKGATE_IP_FSYS S5P_CLKREG(0x0C940)
#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) #define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200) #define S5P_CLKSRC_CORE S5P_CLKREG(0x10200)
#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500) #define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500)
...@@ -60,4 +84,8 @@ ...@@ -60,4 +84,8 @@
#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
/* Compatibility defines */
#define S5P_EPLL_CON S5P_EPLL_CON0
#endif /* __ASM_ARCH_REGS_CLOCK_H */ #endif /* __ASM_ARCH_REGS_CLOCK_H */
/* linux/arch/arm/mach-s5pv310/include/mach/regs-gpio.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - GPIO (including EINT) register definitions
*
* 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.
*/
#ifndef __ASM_ARCH_REGS_GPIO_H
#define __ASM_ARCH_REGS_GPIO_H __FILE__
#include <mach/map.h>
#include <mach/irqs.h>
#define S5PV310_EINT40CON (S5P_VA_GPIO2 + 0xE00)
#define S5P_EINT_CON(x) (S5PV310_EINT40CON + ((x) * 0x4))
#define S5PV310_EINT40FLTCON0 (S5P_VA_GPIO2 + 0xE80)
#define S5P_EINT_FLTCON(x) (S5PV310_EINT40FLTCON0 + ((x) * 0x4))
#define S5PV310_EINT40MASK (S5P_VA_GPIO2 + 0xF00)
#define S5P_EINT_MASK(x) (S5PV310_EINT40MASK + ((x) * 0x4))
#define S5PV310_EINT40PEND (S5P_VA_GPIO2 + 0xF40)
#define S5P_EINT_PEND(x) (S5PV310_EINT40PEND + ((x) * 0x4))
#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3)
#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7))
#define EINT_MODE S3C_GPIO_SFN(0xf)
#define EINT_GPIO_0(x) S5PV310_GPX0(x)
#define EINT_GPIO_1(x) S5PV310_GPX1(x)
#define EINT_GPIO_2(x) S5PV310_GPX2(x)
#define EINT_GPIO_3(x) S5PV310_GPX3(x)
#endif /* __ASM_ARCH_REGS_GPIO_H */
/* linux/arch/arm/mach-s5pv310/include/mach/regs-srom.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - SROMC register definitions
*
* 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.
*/
#ifndef __ASM_ARCH_REGS_SROM_H
#define __ASM_ARCH_REGS_SROM_H __FILE__
#include <mach/map.h>
#define S5PV310_SROMREG(x) (S5P_VA_SROMC + (x))
#define S5PV310_SROM_BW S5PV310_SROMREG(0x0)
#define S5PV310_SROM_BC0 S5PV310_SROMREG(0x4)
#define S5PV310_SROM_BC1 S5PV310_SROMREG(0x8)
#define S5PV310_SROM_BC2 S5PV310_SROMREG(0xc)
#define S5PV310_SROM_BC3 S5PV310_SROMREG(0x10)
/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
#define S5PV310_SROM_BW__DATAWIDTH__SHIFT 0
#define S5PV310_SROM_BW__ADDRMODE__SHIFT 1
#define S5PV310_SROM_BW__WAITENABLE__SHIFT 2
#define S5PV310_SROM_BW__BYTEENABLE__SHIFT 3
#define S5PV310_SROM_BW__CS_MASK 0xf
#define S5PV310_SROM_BW__NCS0__SHIFT 0
#define S5PV310_SROM_BW__NCS1__SHIFT 4
#define S5PV310_SROM_BW__NCS2__SHIFT 8
#define S5PV310_SROM_BW__NCS3__SHIFT 12
/* applies to same to BCS0 - BCS3 */
#define S5PV310_SROM_BCX__PMC__SHIFT 0
#define S5PV310_SROM_BCX__TACP__SHIFT 4
#define S5PV310_SROM_BCX__TCAH__SHIFT 8
#define S5PV310_SROM_BCX__TCOH__SHIFT 12
#define S5PV310_SROM_BCX__TACC__SHIFT 16
#define S5PV310_SROM_BCX__TCOS__SHIFT 24
#define S5PV310_SROM_BCX__TACS__SHIFT 28
#endif /* __ASM_ARCH_REGS_SROM_H */
...@@ -17,6 +17,6 @@ ...@@ -17,6 +17,6 @@
#ifndef __ASM_ARCH_VMALLOC_H #ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H __FILE__ #define __ASM_ARCH_VMALLOC_H __FILE__
#define VMALLOC_END (0xF0000000UL) #define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */ #endif /* __ASM_ARCH_VMALLOC_H */
...@@ -66,11 +66,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) ...@@ -66,11 +66,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
if (status == 0) if (status == 0)
goto out; goto out;
for (combiner_irq = 0; combiner_irq < 32; combiner_irq++) { combiner_irq = __ffs(status);
if (status & 0x1)
break;
status >>= 1;
}
cascade_irq = combiner_irq + (chip_data->irq_offset & ~31); cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
if (unlikely(cascade_irq >= NR_IRQS)) if (unlikely(cascade_irq >= NR_IRQS))
......
/* linux/arch/arm/mach-s5pv310/irq-eint.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - IRQ EINT support
*
* 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/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/sysdev.h>
#include <linux/gpio.h>
#include <plat/pm.h>
#include <plat/cpu.h>
#include <plat/gpio-cfg.h>
#include <mach/regs-gpio.h>
static DEFINE_SPINLOCK(eint_lock);
static unsigned int eint0_15_data[16];
static unsigned int s5pv310_get_irq_nr(unsigned int number)
{
u32 ret = 0;
switch (number) {
case 0 ... 3:
ret = (number + IRQ_EINT0);
break;
case 4 ... 7:
ret = (number + (IRQ_EINT4 - 4));
break;
case 8 ... 15:
ret = (number + (IRQ_EINT8 - 8));
break;
default:
printk(KERN_ERR "number available : %d\n", number);
}
return ret;
}
static inline void s5pv310_irq_eint_mask(unsigned int irq)
{
u32 mask;
spin_lock(&eint_lock);
mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
mask |= eint_irq_to_bit(irq);
__raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
spin_unlock(&eint_lock);
}
static void s5pv310_irq_eint_unmask(unsigned int irq)
{
u32 mask;
spin_lock(&eint_lock);
mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(irq)));
mask &= ~(eint_irq_to_bit(irq));
__raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(irq)));
spin_unlock(&eint_lock);
}
static inline void s5pv310_irq_eint_ack(unsigned int irq)
{
__raw_writel(eint_irq_to_bit(irq), S5P_EINT_PEND(EINT_REG_NR(irq)));
}
static void s5pv310_irq_eint_maskack(unsigned int irq)
{
s5pv310_irq_eint_mask(irq);
s5pv310_irq_eint_ack(irq);
}
static int s5pv310_irq_eint_set_type(unsigned int irq, unsigned int type)
{
int offs = EINT_OFFSET(irq);
int shift;
u32 ctrl, mask;
u32 newvalue = 0;
switch (type) {
case IRQ_TYPE_EDGE_RISING:
newvalue = S5P_IRQ_TYPE_EDGE_RISING;
break;
case IRQ_TYPE_EDGE_FALLING:
newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
break;
case IRQ_TYPE_EDGE_BOTH:
newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
break;
case IRQ_TYPE_LEVEL_LOW:
newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
break;
case IRQ_TYPE_LEVEL_HIGH:
newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
break;
default:
printk(KERN_ERR "No such irq type %d", type);
return -EINVAL;
}
shift = (offs & 0x7) * 4;
mask = 0x7 << shift;
spin_lock(&eint_lock);
ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(irq)));
ctrl &= ~mask;
ctrl |= newvalue << shift;
__raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(irq)));
spin_unlock(&eint_lock);
switch (offs) {
case 0 ... 7:
s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
break;
case 8 ... 15:
s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
break;
case 16 ... 23:
s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
break;
case 24 ... 31:
s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
break;
default:
printk(KERN_ERR "No such irq number %d", offs);
}
return 0;
}
static struct irq_chip s5pv310_irq_eint = {
.name = "s5pv310-eint",
.mask = s5pv310_irq_eint_mask,
.unmask = s5pv310_irq_eint_unmask,
.mask_ack = s5pv310_irq_eint_maskack,
.ack = s5pv310_irq_eint_ack,
.set_type = s5pv310_irq_eint_set_type,
#ifdef CONFIG_PM
.set_wake = s3c_irqext_wake,
#endif
};
/* s5pv310_irq_demux_eint
*
* This function demuxes the IRQ from from EINTs 16 to 31.
* It is designed to be inlined into the specific handler
* s5p_irq_demux_eintX_Y.
*
* Each EINT pend/mask registers handle eight of them.
*/
static inline void s5pv310_irq_demux_eint(unsigned int start)
{
unsigned int irq;
u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
status &= ~mask;
status &= 0xff;
while (status) {
irq = fls(status) - 1;
generic_handle_irq(irq + start);
status &= ~(1 << irq);
}
}
static void s5pv310_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
{
s5pv310_irq_demux_eint(IRQ_EINT(16));
s5pv310_irq_demux_eint(IRQ_EINT(24));
}
static void s5pv310_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
{
u32 *irq_data = get_irq_data(irq);
struct irq_chip *chip = get_irq_chip(irq);
chip->mask(irq);
if (chip->ack)
chip->ack(irq);
generic_handle_irq(*irq_data);
chip->unmask(irq);
}
int __init s5pv310_init_irq_eint(void)
{
int irq;
for (irq = 0 ; irq <= 31 ; irq++) {
set_irq_chip(IRQ_EINT(irq), &s5pv310_irq_eint);
set_irq_handler(IRQ_EINT(irq), handle_level_irq);
set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
}
set_irq_chained_handler(IRQ_EINT16_31, s5pv310_irq_demux_eint16_31);
for (irq = 0 ; irq <= 15 ; irq++) {
eint0_15_data[irq] = IRQ_EINT(irq);
set_irq_data(s5pv310_get_irq_nr(irq), &eint0_15_data[irq]);
set_irq_chained_handler(s5pv310_get_irq_nr(irq),
s5pv310_irq_eint0_15);
}
return 0;
}
arch_initcall(s5pv310_init_irq_eint);
/* linux/arch/arm/mach-s5pv310/mach-smdkc210.c
*
* Copyright (c) 2010 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/serial_core.h>
#include <linux/gpio.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
#include <linux/io.h>
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
#include <plat/regs-serial.h>
#include <plat/s5pv310.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/sdhci.h>
#include <mach/map.h>
#include <mach/regs-srom.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
S3C2410_UCON_RXILEVEL | \
S3C2410_UCON_TXIRQMODE | \
S3C2410_UCON_RXIRQMODE | \
S3C2410_UCON_RXFIFO_TOI | \
S3C2443_UCON_RXERR_IRQEN)
#define SMDKC210_ULCON_DEFAULT S3C2410_LCON_CS8
#define SMDKC210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
S5PV210_UFCON_TXTRIG4 | \
S5PV210_UFCON_RXTRIG4)
static struct s3c2410_uartcfg smdkc210_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = SMDKC210_UCON_DEFAULT,
.ulcon = SMDKC210_ULCON_DEFAULT,
.ufcon = SMDKC210_UFCON_DEFAULT,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = SMDKC210_UCON_DEFAULT,
.ulcon = SMDKC210_ULCON_DEFAULT,
.ufcon = SMDKC210_UFCON_DEFAULT,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = SMDKC210_UCON_DEFAULT,
.ulcon = SMDKC210_ULCON_DEFAULT,
.ufcon = SMDKC210_UFCON_DEFAULT,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = SMDKC210_UCON_DEFAULT,
.ulcon = SMDKC210_ULCON_DEFAULT,
.ufcon = SMDKC210_UFCON_DEFAULT,
},
};
static struct s3c_sdhci_platdata smdkc210_hsmmc0_pdata __initdata = {
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S5PV310_GPK0(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
#ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT
.max_width = 8,
.host_caps = MMC_CAP_8_BIT_DATA,
#endif
};
static struct s3c_sdhci_platdata smdkc210_hsmmc1_pdata __initdata = {
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S5PV310_GPK0(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
};
static struct s3c_sdhci_platdata smdkc210_hsmmc2_pdata __initdata = {
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S5PV310_GPK2(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
#ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT
.max_width = 8,
.host_caps = MMC_CAP_8_BIT_DATA,
#endif
};
static struct s3c_sdhci_platdata smdkc210_hsmmc3_pdata __initdata = {
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S5PV310_GPK2(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
};
static struct resource smdkc210_smsc911x_resources[] = {
[0] = {
.start = S5PV310_PA_SROM_BANK(1),
.end = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_EINT(5),
.end = IRQ_EINT(5),
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
},
};
static struct smsc911x_platform_config smsc9215_config = {
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
.irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
.flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
.phy_interface = PHY_INTERFACE_MODE_MII,
.mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
};
static struct platform_device smdkc210_smsc911x = {
.name = "smsc911x",
.id = -1,
.num_resources = ARRAY_SIZE(smdkc210_smsc911x_resources),
.resource = smdkc210_smsc911x_resources,
.dev = {
.platform_data = &smsc9215_config,
},
};
static struct platform_device *smdkc210_devices[] __initdata = {
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
&s3c_device_hsmmc3,
&s3c_device_rtc,
&s3c_device_wdt,
&smdkc210_smsc911x,
};
static void __init smdkc210_smsc911x_init(void)
{
u32 cs1;
/* configure nCS1 width to 16 bits */
cs1 = __raw_readl(S5PV310_SROM_BW) &
~(S5PV310_SROM_BW__CS_MASK <<
S5PV310_SROM_BW__NCS1__SHIFT);
cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
(1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
(1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
S5PV310_SROM_BW__NCS1__SHIFT;
__raw_writel(cs1, S5PV310_SROM_BW);
/* set timing for nCS1 suitable for ethernet chip */
__raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
(0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
(0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
(0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
(0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
(0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
(0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
}
static void __init smdkc210_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
s3c24xx_init_clocks(24000000);
s3c24xx_init_uarts(smdkc210_uartcfgs, ARRAY_SIZE(smdkc210_uartcfgs));
}
static void __init smdkc210_machine_init(void)
{
smdkc210_smsc911x_init();
s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata);
s3c_sdhci1_set_platdata(&smdkc210_hsmmc1_pdata);
s3c_sdhci2_set_platdata(&smdkc210_hsmmc2_pdata);
s3c_sdhci3_set_platdata(&smdkc210_hsmmc3_pdata);
platform_add_devices(smdkc210_devices, ARRAY_SIZE(smdkc210_devices));
}
MACHINE_START(SMDKC210, "SMDKC210")
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv310_init_irq,
.map_io = smdkc210_map_io,
.init_machine = smdkc210_machine_init,
.timer = &s5pv310_timer,
MACHINE_END
...@@ -9,16 +9,23 @@ ...@@ -9,16 +9,23 @@
*/ */
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/gpio.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
#include <linux/smsc911x.h>
#include <linux/io.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/hardware/cache-l2x0.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <plat/s5pv310.h> #include <plat/s5pv310.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/sdhci.h>
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-srom.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */ /* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ #define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
...@@ -65,6 +72,107 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = { ...@@ -65,6 +72,107 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
}, },
}; };
static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S5PV310_GPK0(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
#ifdef CONFIG_S5PV310_SDHCI_CH0_8BIT
.max_width = 8,
.host_caps = MMC_CAP_8_BIT_DATA,
#endif
};
static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S5PV310_GPK0(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
};
static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S5PV310_GPK2(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
#ifdef CONFIG_S5PV310_SDHCI_CH2_8BIT
.max_width = 8,
.host_caps = MMC_CAP_8_BIT_DATA,
#endif
};
static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
.cd_type = S3C_SDHCI_CD_GPIO,
.ext_cd_gpio = S5PV310_GPK2(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
};
static struct resource smdkv310_smsc911x_resources[] = {
[0] = {
.start = S5PV310_PA_SROM_BANK(1),
.end = S5PV310_PA_SROM_BANK(1) + SZ_64K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_EINT(5),
.end = IRQ_EINT(5),
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
},
};
static struct smsc911x_platform_config smsc9215_config = {
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
.irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
.flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
.phy_interface = PHY_INTERFACE_MODE_MII,
.mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
};
static struct platform_device smdkv310_smsc911x = {
.name = "smsc911x",
.id = -1,
.num_resources = ARRAY_SIZE(smdkv310_smsc911x_resources),
.resource = smdkv310_smsc911x_resources,
.dev = {
.platform_data = &smsc9215_config,
},
};
static struct platform_device *smdkv310_devices[] __initdata = {
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
&s3c_device_hsmmc3,
&s3c_device_rtc,
&s3c_device_wdt,
&smdkv310_smsc911x,
};
static void __init smdkv310_smsc911x_init(void)
{
u32 cs1;
/* configure nCS1 width to 16 bits */
cs1 = __raw_readl(S5PV310_SROM_BW) &
~(S5PV310_SROM_BW__CS_MASK <<
S5PV310_SROM_BW__NCS1__SHIFT);
cs1 |= ((1 << S5PV310_SROM_BW__DATAWIDTH__SHIFT) |
(1 << S5PV310_SROM_BW__WAITENABLE__SHIFT) |
(1 << S5PV310_SROM_BW__BYTEENABLE__SHIFT)) <<
S5PV310_SROM_BW__NCS1__SHIFT;
__raw_writel(cs1, S5PV310_SROM_BW);
/* set timing for nCS1 suitable for ethernet chip */
__raw_writel((0x1 << S5PV310_SROM_BCX__PMC__SHIFT) |
(0x9 << S5PV310_SROM_BCX__TACP__SHIFT) |
(0xc << S5PV310_SROM_BCX__TCAH__SHIFT) |
(0x1 << S5PV310_SROM_BCX__TCOH__SHIFT) |
(0x6 << S5PV310_SROM_BCX__TACC__SHIFT) |
(0x1 << S5PV310_SROM_BCX__TCOS__SHIFT) |
(0x1 << S5PV310_SROM_BCX__TACS__SHIFT), S5PV310_SROM_BC1);
}
static void __init smdkv310_map_io(void) static void __init smdkv310_map_io(void)
{ {
s5p_init_io(NULL, 0, S5P_VA_CHIPID); s5p_init_io(NULL, 0, S5P_VA_CHIPID);
...@@ -74,9 +182,14 @@ static void __init smdkv310_map_io(void) ...@@ -74,9 +182,14 @@ static void __init smdkv310_map_io(void)
static void __init smdkv310_machine_init(void) static void __init smdkv310_machine_init(void)
{ {
#ifdef CONFIG_CACHE_L2X0 smdkv310_smsc911x_init();
l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
#endif s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata);
s3c_sdhci1_set_platdata(&smdkv310_hsmmc1_pdata);
s3c_sdhci2_set_platdata(&smdkv310_hsmmc2_pdata);
s3c_sdhci3_set_platdata(&smdkv310_hsmmc3_pdata);
platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
} }
MACHINE_START(SMDKV310, "SMDKV310") MACHINE_START(SMDKV310, "SMDKV310")
......
...@@ -7,15 +7,20 @@ ...@@ -7,15 +7,20 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/platform_device.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/gpio_keys.h>
#include <linux/gpio.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/hardware/cache-l2x0.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <plat/s5pv310.h> #include <plat/s5pv310.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/devs.h>
#include <mach/map.h> #include <mach/map.h>
...@@ -60,6 +65,72 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = { ...@@ -60,6 +65,72 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
}, },
}; };
static struct gpio_keys_button universal_gpio_keys_tables[] = {
{
.code = KEY_VOLUMEUP,
.gpio = S5PV310_GPX2(0), /* XEINT16 */
.desc = "gpio-keys: KEY_VOLUMEUP",
.type = EV_KEY,
.active_low = 1,
.debounce_interval = 1,
}, {
.code = KEY_VOLUMEDOWN,
.gpio = S5PV310_GPX2(1), /* XEINT17 */
.desc = "gpio-keys: KEY_VOLUMEDOWN",
.type = EV_KEY,
.active_low = 1,
.debounce_interval = 1,
}, {
.code = KEY_CONFIG,
.gpio = S5PV310_GPX2(2), /* XEINT18 */
.desc = "gpio-keys: KEY_CONFIG",
.type = EV_KEY,
.active_low = 1,
.debounce_interval = 1,
}, {
.code = KEY_CAMERA,
.gpio = S5PV310_GPX2(3), /* XEINT19 */
.desc = "gpio-keys: KEY_CAMERA",
.type = EV_KEY,
.active_low = 1,
.debounce_interval = 1,
}, {
.code = KEY_OK,
.gpio = S5PV310_GPX3(5), /* XEINT29 */
.desc = "gpio-keys: KEY_OK",
.type = EV_KEY,
.active_low = 1,
.debounce_interval = 1,
},
};
static struct gpio_keys_platform_data universal_gpio_keys_data = {
.buttons = universal_gpio_keys_tables,
.nbuttons = ARRAY_SIZE(universal_gpio_keys_tables),
};
static struct platform_device universal_gpio_keys = {
.name = "gpio-keys",
.dev = {
.platform_data = &universal_gpio_keys_data,
},
};
/* I2C0 */
static struct i2c_board_info i2c0_devs[] __initdata = {
/* Camera, To be updated */
};
/* I2C1 */
static struct i2c_board_info i2c1_devs[] __initdata = {
/* Gyro, To be updated */
};
static struct platform_device *universal_devices[] __initdata = {
&universal_gpio_keys,
&s5p_device_onenand,
};
static void __init universal_map_io(void) static void __init universal_map_io(void)
{ {
s5p_init_io(NULL, 0, S5P_VA_CHIPID); s5p_init_io(NULL, 0, S5P_VA_CHIPID);
...@@ -69,9 +140,11 @@ static void __init universal_map_io(void) ...@@ -69,9 +140,11 @@ static void __init universal_map_io(void)
static void __init universal_machine_init(void) static void __init universal_machine_init(void)
{ {
#ifdef CONFIG_CACHE_L2X0 i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff); i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
#endif
/* Last */
platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
} }
MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210") MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
......
...@@ -21,8 +21,6 @@ struct platform_device; /* don't need the contents */ ...@@ -21,8 +21,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev) void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5PV310_GPD1(0), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PV310_GPD1(0), 2,
s3c_gpio_setpull(S5PV310_GPD1(0), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV310_GPD1(1), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPD1(1), S3C_GPIO_PULL_UP);
} }
...@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */ ...@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev) void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5PV310_GPD1(2), S3C_GPIO_SFN(2)); s3c_gpio_cfgall_range(S5PV310_GPD1(2), 2,
s3c_gpio_setpull(S5PV310_GPD1(2), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV310_GPD1(3), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPD1(3), S3C_GPIO_PULL_UP);
} }
...@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */ ...@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c2_cfg_gpio(struct platform_device *dev) void s3c_i2c2_cfg_gpio(struct platform_device *dev)
{ {
s3c_gpio_cfgpin(S5PV310_GPA0(6), S3C_GPIO_SFN(3)); s3c_gpio_cfgall_range(S5PV310_GPA0(6), 2,
s3c_gpio_setpull(S5PV310_GPA0(6), S3C_GPIO_PULL_UP); S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV310_GPA0(7), S3C_GPIO_SFN(3));
s3c_gpio_setpull(S5PV310_GPA0(7), S3C_GPIO_PULL_UP);
} }
/*
* linux/arch/arm/mach-s5pv310/setup-i2c3.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
* I2C3 GPIO configuration.
*
* 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.
*/
struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
void s3c_i2c3_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PV310_GPA1(2), 2,
S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
/*
* linux/arch/arm/mach-s5pv310/setup-i2c4.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
* I2C4 GPIO configuration.
*
* 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.
*/
struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
void s3c_i2c4_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PV310_GPB(2), 2,
S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
/*
* linux/arch/arm/mach-s5pv310/setup-i2c5.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
* I2C5 GPIO configuration.
*
* 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.
*/
struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
void s3c_i2c5_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PV310_GPB(6), 2,
S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
/*
* linux/arch/arm/mach-s5pv310/setup-i2c6.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
* I2C6 GPIO configuration.
*
* 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.
*/
struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
void s3c_i2c6_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PV310_GPC1(3), 2,
S3C_GPIO_SFN(4), S3C_GPIO_PULL_UP);
}
/*
* linux/arch/arm/mach-s5pv310/setup-i2c7.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
*
* I2C7 GPIO configuration.
*
* 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.
*/
struct platform_device; /* don't need the contents */
#include <linux/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-cfg.h>
void s3c_i2c7_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgall_range(S5PV310_GPD0(2), 2,
S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
}
/* linux/arch/arm/mach-s5pv310/setup-sdhci-gpio.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5PV310 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
*
* 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/types.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-sdhci.h>
#include <plat/sdhci.h>
void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPK0[0:1] pins to special-function 2 */
for (gpio = S5PV310_GPK0(0); gpio < S5PV310_GPK0(2); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
switch (width) {
case 8:
for (gpio = S5PV310_GPK1(3); gpio <= S5PV310_GPK1(6); gpio++) {
/* Data pin GPK1[3:6] to special-funtion 3 */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
case 4:
for (gpio = S5PV310_GPK0(3); gpio <= S5PV310_GPK0(6); gpio++) {
/* Data pin GPK0[3:6] to special-funtion 2 */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
default:
break;
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_cfgpin(S5PV310_GPK0(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPK0(2), S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
}
void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPK1[0:1] pins to special-function 2 */
for (gpio = S5PV310_GPK1(0); gpio < S5PV310_GPK1(2); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
for (gpio = S5PV310_GPK1(3); gpio <= S5PV310_GPK1(6); gpio++) {
/* Data pin GPK1[3:6] to special-function 2 */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_cfgpin(S5PV310_GPK1(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPK1(2), S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
}
void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPK2[0:1] pins to special-function 2 */
for (gpio = S5PV310_GPK2(0); gpio < S5PV310_GPK2(2); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
switch (width) {
case 8:
for (gpio = S5PV310_GPK3(3); gpio <= S5PV310_GPK3(6); gpio++) {
/* Data pin GPK3[3:6] to special-function 3 */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
case 4:
for (gpio = S5PV310_GPK2(3); gpio <= S5PV310_GPK2(6); gpio++) {
/* Data pin GPK2[3:6] to special-function 2 */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
default:
break;
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_cfgpin(S5PV310_GPK2(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPK2(2), S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
}
void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPK3[0:1] pins to special-function 2 */
for (gpio = S5PV310_GPK3(0); gpio < S5PV310_GPK3(2); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
for (gpio = S5PV310_GPK3(3); gpio <= S5PV310_GPK3(6); gpio++) {
/* Data pin GPK3[3:6] to special-function 2 */
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_cfgpin(S5PV310_GPK3(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPK3(2), S3C_GPIO_PULL_UP);
s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
}
}
/* linux/arch/arm/mach-s5pv310/setup-sdhci.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5PV310 - Helper functions for settign up SDHCI device(s) (HSMMC)
*
* 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/types.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <plat/regs-sdhci.h>
/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
char *s5pv310_hsmmc_clksrcs[4] = {
[0] = NULL,
[1] = NULL,
[2] = "sclk_mmc", /* mmc_bus */
[3] = NULL,
};
void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r,
struct mmc_ios *ios, struct mmc_card *card)
{
u32 ctrl2, ctrl3;
/* don't need to alter anything acording to card-type */
ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
/* select base clock source to HCLK */
ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
/*
* clear async mode, enable conflict mask, rx feedback ctrl, SD
* clk hold and no use debounce count
*/
ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
S3C_SDHCI_CTRL2_ENFBCLKRX |
S3C_SDHCI_CTRL2_DFCNT_NONE |
S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
/* Tx and Rx feedback clock delay control */
if (ios->clock < 25 * 1000000)
ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
S3C_SDHCI_CTRL3_FCSEL2 |
S3C_SDHCI_CTRL3_FCSEL1 |
S3C_SDHCI_CTRL3_FCSEL0);
else
ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
writel(ctrl2, r + S3C_SDHCI_CONTROL2);
writel(ctrl3, r + S3C_SDHCI_CONTROL3);
}
...@@ -147,7 +147,7 @@ static struct mtd_partition smdk_default_nand_part[] = { ...@@ -147,7 +147,7 @@ static struct mtd_partition smdk_default_nand_part[] = {
[7] = { [7] = {
.name = "S3C2410 flash partition 7", .name = "S3C2410 flash partition 7",
.offset = SZ_1M * 48, .offset = SZ_1M * 48,
.size = SZ_16M, .size = MTDPART_SIZ_FULL,
} }
}; };
......
...@@ -74,11 +74,6 @@ static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset) ...@@ -74,11 +74,6 @@ static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
return -EINVAL; return -EINVAL;
} }
static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
{
return IRQ_EINT8 + offset;
}
static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
.set_config = s3c_gpio_setcfg_s3c24xx_a, .set_config = s3c_gpio_setcfg_s3c24xx_a,
.get_config = s3c_gpio_getcfg_s3c24xx_a, .get_config = s3c_gpio_getcfg_s3c24xx_a,
...@@ -157,12 +152,13 @@ struct s3c_gpio_chip s3c24xx_gpios[] = { ...@@ -157,12 +152,13 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
[6] = { [6] = {
.base = S3C2410_GPGCON, .base = S3C2410_GPGCON,
.pm = __gpio_pm(&s3c_gpio_pm_2bit), .pm = __gpio_pm(&s3c_gpio_pm_2bit),
.irq_base = IRQ_EINT8,
.chip = { .chip = {
.base = S3C2410_GPG(0), .base = S3C2410_GPG(0),
.owner = THIS_MODULE, .owner = THIS_MODULE,
.label = "GPIOG", .label = "GPIOG",
.ngpio = 16, .ngpio = 16,
.to_irq = s3c24xx_gpiolib_bankg_toirq, .to_irq = samsung_gpiolib_to_irq,
}, },
}, { }, {
.base = S3C2410_GPHCON, .base = S3C2410_GPHCON,
......
...@@ -32,6 +32,11 @@ config S5P_EXT_INT ...@@ -32,6 +32,11 @@ config S5P_EXT_INT
Use the external interrupts (other than GPIO interrupts.) Use the external interrupts (other than GPIO interrupts.)
Note: Do not choose this for S5P6440 and S5P6450. Note: Do not choose this for S5P6440 and S5P6450.
config S5P_GPIO_INT
bool
help
Common code for the GPIO interrupts (other than external interrupts.)
config S5P_DEV_FIMC0 config S5P_DEV_FIMC0
bool bool
help help
......
...@@ -18,6 +18,9 @@ obj-y += cpu.o ...@@ -18,6 +18,9 @@ obj-y += cpu.o
obj-y += clock.o obj-y += clock.o
obj-y += irq.o obj-y += irq.o
obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += irq-pm.o
# devices # devices
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/div64.h> #include <asm/div64.h>
#include <mach/regs-clock.h>
#include <plat/clock.h> #include <plat/clock.h>
#include <plat/clock-clksrc.h> #include <plat/clock-clksrc.h>
#include <plat/s5p-clock.h> #include <plat/s5p-clock.h>
...@@ -88,14 +90,6 @@ struct clk clk_fout_vpll = { ...@@ -88,14 +90,6 @@ struct clk clk_fout_vpll = {
.ctrlbit = (1 << 31), .ctrlbit = (1 << 31),
}; };
/* ARM clock */
struct clk clk_arm = {
.name = "armclk",
.id = -1,
.rate = 0,
.ctrlbit = 0,
};
/* Possible clock sources for APLL Mux */ /* Possible clock sources for APLL Mux */
static struct clk *clk_src_apll_list[] = { static struct clk *clk_src_apll_list[] = {
[0] = &clk_fin_apll, [0] = &clk_fin_apll,
...@@ -156,6 +150,24 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable) ...@@ -156,6 +150,24 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
return 0; return 0;
} }
int s5p_epll_enable(struct clk *clk, int enable)
{
unsigned int ctrlbit = clk->ctrlbit;
unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
if (enable)
__raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
else
__raw_writel(epll_con, S5P_EPLL_CON);
return 0;
}
unsigned long s5p_epll_get_rate(struct clk *clk)
{
return clk->rate;
}
static struct clk *s5p_clks[] __initdata = { static struct clk *s5p_clks[] __initdata = {
&clk_ext_xtal_mux, &clk_ext_xtal_mux,
&clk_48m, &clk_48m,
...@@ -165,7 +177,6 @@ static struct clk *s5p_clks[] __initdata = { ...@@ -165,7 +177,6 @@ static struct clk *s5p_clks[] __initdata = {
&clk_fout_epll, &clk_fout_epll,
&clk_fout_dpll, &clk_fout_dpll,
&clk_fout_vpll, &clk_fout_vpll,
&clk_arm,
&clk_vpll, &clk_vpll,
&clk_xusbxti, &clk_xusbxti,
}; };
......
...@@ -94,4 +94,22 @@ ...@@ -94,4 +94,22 @@
((irq) - S5P_EINT_BASE1) : \ ((irq) - S5P_EINT_BASE1) : \
((irq) + 16 - S5P_EINT_BASE2)) ((irq) + 16 - S5P_EINT_BASE2))
#define IRQ_EINT_BIT(x) EINT_OFFSET(x)
/* Typically only a few gpio chips require gpio interrupt support.
To avoid memory waste irq descriptors are allocated only for
S5P_GPIOINT_GROUP_COUNT chips, each with total number of
S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
to any gpio chip with the s5p_register_gpio_interrupt() function */
#define S5P_GPIOINT_GROUP_COUNT 4
#define S5P_GPIOINT_GROUP_SIZE 8
#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
/* IRQ types common for all s5p platforms */
#define S5P_IRQ_TYPE_LEVEL_LOW (0x00)
#define S5P_IRQ_TYPE_LEVEL_HIGH (0x01)
#define S5P_IRQ_TYPE_EDGE_FALLING (0x02)
#define S5P_IRQ_TYPE_EDGE_RISING (0x03)
#define S5P_IRQ_TYPE_EDGE_BOTH (0x04)
#endif /* __ASM_PLAT_S5P_IRQS_H */ #endif /* __ASM_PLAT_S5P_IRQS_H */
...@@ -13,24 +13,38 @@ ...@@ -13,24 +13,38 @@
#ifndef __ASM_PLAT_MAP_S5P_H #ifndef __ASM_PLAT_MAP_S5P_H
#define __ASM_PLAT_MAP_S5P_H __FILE__ #define __ASM_PLAT_MAP_S5P_H __FILE__
#define S5P_VA_CHIPID S3C_ADDR(0x00700000) #define S5P_VA_CHIPID S3C_ADDR(0x02000000)
#define S5P_VA_GPIO S3C_ADDR(0x00500000) #define S5P_VA_CMU S3C_ADDR(0x02100000)
#define S5P_VA_SYSTIMER S3C_ADDR(0x01200000) #define S5P_VA_GPIO S3C_ADDR(0x02200000)
#define S5P_VA_SROMC S3C_ADDR(0x01100000) #define S5P_VA_GPIO1 S5P_VA_GPIO
#define S5P_VA_SYSRAM S3C_ADDR(0x01180000) #define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
#define S5P_VA_GPIO3 S3C_ADDR(0x02280000)
#define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000)
#define S5P_VA_SYSRAM S3C_ADDR(0x02400000)
#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
#define S5P_VA_SYSTIMER S3C_ADDR(0x02500000)
#define S5P_VA_L2CC S3C_ADDR(0x02600000)
#define S5P_VA_COMBINER_BASE S3C_ADDR(0x02700000)
#define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10) #define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10)
#define S5P_VA_COREPERI_BASE S3C_ADDR(0x00800000) #define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000)
#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) #define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
#define S5P_VA_SCU S5P_VA_COREPERI(0x0) #define S5P_VA_SCU S5P_VA_COREPERI(0x0)
#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100) #define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100)
#define S5P_VA_TWD S5P_VA_COREPERI(0x600) #define S5P_VA_TWD S5P_VA_COREPERI(0x600)
#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000) #define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000)
#define S5P_VA_L2CC S3C_ADDR(0x00900000) #define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000)
#define S5P_VA_CMU S3C_ADDR(0x00920000)
#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
#define VA_VIC0 VA_VIC(0)
#define VA_VIC1 VA_VIC(1)
#define VA_VIC2 VA_VIC(2)
#define VA_VIC3 VA_VIC(3)
#define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET)) #define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
#define S5P_VA_UART0 S5P_VA_UART(0) #define S5P_VA_UART0 S5P_VA_UART(0)
...@@ -42,10 +56,4 @@ ...@@ -42,10 +56,4 @@
#define S3C_UART_OFFSET (0x400) #define S3C_UART_OFFSET (0x400)
#endif #endif
#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
#define VA_VIC0 VA_VIC(0)
#define VA_VIC1 VA_VIC(1)
#define VA_VIC2 VA_VIC(2)
#define VA_VIC3 VA_VIC(3)
#endif /* __ASM_PLAT_MAP_S5P_H */ #endif /* __ASM_PLAT_MAP_S5P_H */
...@@ -43,4 +43,8 @@ extern struct clksrc_sources clk_src_dpll; ...@@ -43,4 +43,8 @@ extern struct clksrc_sources clk_src_dpll;
extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable); extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
/* Common EPLL operations for S5P platform */
extern int s5p_epll_enable(struct clk *clk, int enable);
extern unsigned long s5p_epll_get_rate(struct clk *clk);
#endif /* __ASM_PLAT_S5P_CLOCK_H */ #endif /* __ASM_PLAT_S5P_CLOCK_H */
...@@ -67,23 +67,23 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type) ...@@ -67,23 +67,23 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
switch (type) { switch (type) {
case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_RISING:
newvalue = S5P_EXTINT_RISEEDGE; newvalue = S5P_IRQ_TYPE_EDGE_RISING;
break; break;
case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_FALLING:
newvalue = S5P_EXTINT_FALLEDGE; newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
break; break;
case IRQ_TYPE_EDGE_BOTH: case IRQ_TYPE_EDGE_BOTH:
newvalue = S5P_EXTINT_BOTHEDGE; newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
break; break;
case IRQ_TYPE_LEVEL_LOW: case IRQ_TYPE_LEVEL_LOW:
newvalue = S5P_EXTINT_LOWLEV; newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
break; break;
case IRQ_TYPE_LEVEL_HIGH: case IRQ_TYPE_LEVEL_HIGH:
newvalue = S5P_EXTINT_HILEV; newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
break; break;
default: default:
......
/* linux/arch/arm/plat-s5p/irq-gpioint.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* Author: Kyungmin Park <kyungmin.park@samsung.com>
* Author: Joonyoung Shim <jy0922.shim@samsung.com>
* Author: Marek Szyprowski <m.szyprowski@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/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <mach/map.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>
#define S5P_GPIOREG(x) (S5P_VA_GPIO + (x))
#define GPIOINT_CON_OFFSET 0x700
#define GPIOINT_MASK_OFFSET 0x900
#define GPIOINT_PEND_OFFSET 0xA00
static struct s3c_gpio_chip *irq_chips[S5P_GPIOINT_GROUP_MAXNR];
static int s5p_gpioint_get_group(unsigned int irq)
{
struct gpio_chip *chip = get_irq_data(irq);
struct s3c_gpio_chip *s3c_chip = container_of(chip,
struct s3c_gpio_chip, chip);
int group;
for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++)
if (s3c_chip == irq_chips[group])
break;
return group;
}
static int s5p_gpioint_get_offset(unsigned int irq)
{
struct gpio_chip *chip = get_irq_data(irq);
struct s3c_gpio_chip *s3c_chip = container_of(chip,
struct s3c_gpio_chip, chip);
return irq - s3c_chip->irq_base;
}
static void s5p_gpioint_ack(unsigned int irq)
{
int group, offset, pend_offset;
unsigned int value;
group = s5p_gpioint_get_group(irq);
offset = s5p_gpioint_get_offset(irq);
pend_offset = group << 2;
value = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
value |= 1 << offset;
__raw_writel(value, S5P_GPIOREG(GPIOINT_PEND_OFFSET) + pend_offset);
}
static void s5p_gpioint_mask(unsigned int irq)
{
int group, offset, mask_offset;
unsigned int value;
group = s5p_gpioint_get_group(irq);
offset = s5p_gpioint_get_offset(irq);
mask_offset = group << 2;
value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
value |= 1 << offset;
__raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
}
static void s5p_gpioint_unmask(unsigned int irq)
{
int group, offset, mask_offset;
unsigned int value;
group = s5p_gpioint_get_group(irq);
offset = s5p_gpioint_get_offset(irq);
mask_offset = group << 2;
value = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
value &= ~(1 << offset);
__raw_writel(value, S5P_GPIOREG(GPIOINT_MASK_OFFSET) + mask_offset);
}
static void s5p_gpioint_mask_ack(unsigned int irq)
{
s5p_gpioint_mask(irq);
s5p_gpioint_ack(irq);
}
static int s5p_gpioint_set_type(unsigned int irq, unsigned int type)
{
int group, offset, con_offset;
unsigned int value;
group = s5p_gpioint_get_group(irq);
offset = s5p_gpioint_get_offset(irq);
con_offset = group << 2;
switch (type) {
case IRQ_TYPE_EDGE_RISING:
type = S5P_IRQ_TYPE_EDGE_RISING;
break;
case IRQ_TYPE_EDGE_FALLING:
type = S5P_IRQ_TYPE_EDGE_FALLING;
break;
case IRQ_TYPE_EDGE_BOTH:
type = S5P_IRQ_TYPE_EDGE_BOTH;
break;
case IRQ_TYPE_LEVEL_HIGH:
type = S5P_IRQ_TYPE_LEVEL_HIGH;
break;
case IRQ_TYPE_LEVEL_LOW:
type = S5P_IRQ_TYPE_LEVEL_LOW;
break;
case IRQ_TYPE_NONE:
default:
printk(KERN_WARNING "No irq type\n");
return -EINVAL;
}
value = __raw_readl(S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
value &= ~(0x7 << (offset * 0x4));
value |= (type << (offset * 0x4));
__raw_writel(value, S5P_GPIOREG(GPIOINT_CON_OFFSET) + con_offset);
return 0;
}
struct irq_chip s5p_gpioint = {
.name = "s5p_gpioint",
.ack = s5p_gpioint_ack,
.mask = s5p_gpioint_mask,
.mask_ack = s5p_gpioint_mask_ack,
.unmask = s5p_gpioint_unmask,
.set_type = s5p_gpioint_set_type,
};
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
int group, offset, pend_offset, mask_offset;
int real_irq;
unsigned int pend, mask;
for (group = 0; group < S5P_GPIOINT_GROUP_MAXNR; group++) {
pend_offset = group << 2;
pend = __raw_readl(S5P_GPIOREG(GPIOINT_PEND_OFFSET) +
pend_offset);
if (!pend)
continue;
mask_offset = group << 2;
mask = __raw_readl(S5P_GPIOREG(GPIOINT_MASK_OFFSET) +
mask_offset);
pend &= ~mask;
for (offset = 0; offset < 8; offset++) {
if (pend & (1 << offset)) {
struct s3c_gpio_chip *chip = irq_chips[group];
if (chip) {
real_irq = chip->irq_base + offset;
generic_handle_irq(real_irq);
}
}
}
}
}
static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
{
static int used_gpioint_groups = 0;
static bool handler_registered = 0;
int irq, group = chip->group;
int i;
if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
return -ENOMEM;
chip->irq_base = S5P_GPIOINT_BASE +
used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
used_gpioint_groups++;
if (!handler_registered) {
set_irq_chained_handler(IRQ_GPIOINT, s5p_gpioint_handler);
handler_registered = 1;
}
irq_chips[group] = chip;
for (i = 0; i < chip->chip.ngpio; i++) {
irq = chip->irq_base + i;
set_irq_chip(irq, &s5p_gpioint);
set_irq_data(irq, &chip->chip);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
return 0;
}
int __init s5p_register_gpio_interrupt(int pin)
{
struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin);
int offset, group;
int ret;
if (!my_chip)
return -EINVAL;
offset = pin - my_chip->chip.base;
group = my_chip->group;
/* check if the group has been already registered */
if (my_chip->irq_base)
return my_chip->irq_base + offset;
/* register gpio group */
ret = s5p_gpioint_add(my_chip);
if (ret == 0) {
my_chip->chip.to_irq = samsung_gpiolib_to_irq;
printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
group);
return my_chip->irq_base + offset;
}
return ret;
}
/* linux/arch/arm/plat-s5p/irq-pm.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Based on arch/arm/plat-s3c24xx/irq-pm.c,
* Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* 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/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/sysdev.h>
#include <plat/cpu.h>
#include <plat/irqs.h>
#include <plat/pm.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/regs-irq.h>
/* state for IRQs over sleep */
/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM,
* as wakeup sources
*
* set bit to 1 in allow bitfield to enable the wakeup settings on it
*/
unsigned long s3c_irqwake_intallow = 0x00000006L;
unsigned long s3c_irqwake_eintallow = 0xffffffffL;
int s3c_irq_wake(unsigned int irqno, unsigned int state)
{
unsigned long irqbit;
switch (irqno) {
case IRQ_RTC_TIC:
case IRQ_RTC_ALARM:
irqbit = 1 << (irqno + 1 - IRQ_RTC_ALARM);
if (!state)
s3c_irqwake_intmask |= irqbit;
else
s3c_irqwake_intmask &= ~irqbit;
break;
default:
return -ENOENT;
}
return 0;
}
static struct sleep_save eint_save[] = {
SAVE_ITEM(S5P_EINT_CON(0)),
SAVE_ITEM(S5P_EINT_CON(1)),
SAVE_ITEM(S5P_EINT_CON(2)),
SAVE_ITEM(S5P_EINT_CON(3)),
SAVE_ITEM(S5P_EINT_FLTCON(0)),
SAVE_ITEM(S5P_EINT_FLTCON(1)),
SAVE_ITEM(S5P_EINT_FLTCON(2)),
SAVE_ITEM(S5P_EINT_FLTCON(3)),
SAVE_ITEM(S5P_EINT_FLTCON(4)),
SAVE_ITEM(S5P_EINT_FLTCON(5)),
SAVE_ITEM(S5P_EINT_FLTCON(6)),
SAVE_ITEM(S5P_EINT_FLTCON(7)),
SAVE_ITEM(S5P_EINT_MASK(0)),
SAVE_ITEM(S5P_EINT_MASK(1)),
SAVE_ITEM(S5P_EINT_MASK(2)),
SAVE_ITEM(S5P_EINT_MASK(3)),
};
int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
{
s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
return 0;
}
int s3c24xx_irq_resume(struct sys_device *dev)
{
s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
return 0;
}
/* linux/arch/arm/plat-s5p/pm.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5P Power Manager (Suspend-To-RAM) support
*
* Based on arch/arm/plat-s3c24xx/pm.c
* Copyright (c) 2004,2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* 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/suspend.h>
#include <plat/pm.h>
#define PFX "s5p pm: "
/* s3c_pm_check_resume_pin
*
* check to see if the pin is configured correctly for sleep mode, and
* make any necessary adjustments if it is not
*/
static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
{
/* nothing here yet */
}
/* s3c_pm_configure_extint
*
* configure all external interrupt pins
*/
void s3c_pm_configure_extint(void)
{
/* nothing here yet */
}
void s3c_pm_restore_core(void)
{
/* nothing here yet */
}
void s3c_pm_save_core(void)
{
/* nothing here yet */
}
...@@ -180,6 +180,31 @@ config S3C_DEV_I2C2 ...@@ -180,6 +180,31 @@ config S3C_DEV_I2C2
help help
Compile in platform device definitions for I2C channel 2 Compile in platform device definitions for I2C channel 2
config S3C_DEV_I2C3
bool
help
Compile in platform device definition for I2C controller 3
config S3C_DEV_I2C4
bool
help
Compile in platform device definition for I2C controller 4
config S3C_DEV_I2C5
bool
help
Compile in platform device definition for I2C controller 5
config S3C_DEV_I2C6
bool
help
Compile in platform device definition for I2C controller 6
config S3C_DEV_I2C7
bool
help
Compile in platform device definition for I2C controller 7
config S3C_DEV_FB config S3C_DEV_FB
bool bool
help help
......
...@@ -40,6 +40,11 @@ obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o ...@@ -40,6 +40,11 @@ obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
obj-y += dev-i2c0.o obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o
obj-$(CONFIG_S3C_DEV_I2C3) += dev-i2c3.o
obj-$(CONFIG_S3C_DEV_I2C4) += dev-i2c4.o
obj-$(CONFIG_S3C_DEV_I2C5) += dev-i2c5.o
obj-$(CONFIG_S3C_DEV_I2C6) += dev-i2c6.o
obj-$(CONFIG_S3C_DEV_I2C7) += dev-i2c7.o
obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
obj-y += dev-uart.o obj-y += dev-uart.o
obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
......
...@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { ...@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
.max_width = 4, .max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA | .host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
.clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
}; };
struct platform_device s3c_device_hsmmc0 = { struct platform_device s3c_device_hsmmc0 = {
...@@ -59,17 +60,20 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) ...@@ -59,17 +60,20 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
{ {
struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata; struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
set->max_width = pd->max_width;
set->cd_type = pd->cd_type; set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init; set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup; set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio; set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio) if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio; set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card) if (pd->cfg_card)
set->cfg_card = pd->cfg_card; set->cfg_card = pd->cfg_card;
if (pd->host_caps) if (pd->host_caps)
set->host_caps = pd->host_caps; set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
} }
...@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { ...@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
.max_width = 4, .max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA | .host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
.clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
}; };
struct platform_device s3c_device_hsmmc1 = { struct platform_device s3c_device_hsmmc1 = {
...@@ -59,17 +60,20 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) ...@@ -59,17 +60,20 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
{ {
struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata; struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
set->max_width = pd->max_width;
set->cd_type = pd->cd_type; set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init; set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup; set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio; set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio) if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio; set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card) if (pd->cfg_card)
set->cfg_card = pd->cfg_card; set->cfg_card = pd->cfg_card;
if (pd->host_caps) if (pd->host_caps)
set->host_caps = pd->host_caps; set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
} }
...@@ -42,6 +42,7 @@ struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = { ...@@ -42,6 +42,7 @@ struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
.max_width = 4, .max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA | .host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
.clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
}; };
struct platform_device s3c_device_hsmmc2 = { struct platform_device s3c_device_hsmmc2 = {
...@@ -60,17 +61,20 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd) ...@@ -60,17 +61,20 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
{ {
struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata; struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
set->max_width = pd->max_width;
set->cd_type = pd->cd_type; set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init; set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup; set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio; set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio) if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio; set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card) if (pd->cfg_card)
set->cfg_card = pd->cfg_card; set->cfg_card = pd->cfg_card;
if (pd->host_caps) if (pd->host_caps)
set->host_caps = pd->host_caps; set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
} }
...@@ -33,8 +33,8 @@ static struct resource s3c_hsmmc3_resource[] = { ...@@ -33,8 +33,8 @@ static struct resource s3c_hsmmc3_resource[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
[1] = { [1] = {
.start = IRQ_MMC3, .start = IRQ_HSMMC3,
.end = IRQ_MMC3, .end = IRQ_HSMMC3,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
} }
}; };
...@@ -45,6 +45,7 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = { ...@@ -45,6 +45,7 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
.max_width = 4, .max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA | .host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
.clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
}; };
struct platform_device s3c_device_hsmmc3 = { struct platform_device s3c_device_hsmmc3 = {
...@@ -63,15 +64,20 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd) ...@@ -63,15 +64,20 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
{ {
struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata; struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
set->max_width = pd->max_width;
set->cd_type = pd->cd_type; set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init; set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup; set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio; set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert; set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio) if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio; set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card) if (pd->cfg_card)
set->cfg_card = pd->cfg_card; set->cfg_card = pd->cfg_card;
if (pd->host_caps)
set->host_caps |= pd->host_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
} }
...@@ -32,8 +32,8 @@ static struct resource s3c_i2c_resource[] = { ...@@ -32,8 +32,8 @@ static struct resource s3c_i2c_resource[] = {
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
[1] = { [1] = {
.start = IRQ_CAN0, .start = IRQ_IIC2,
.end = IRQ_CAN0, .end = IRQ_IIC2,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
}; };
......
/* linux/arch/arm/plat-samsung/dev-i2c3.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5P series device definition for i2c device 3
*
* 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/gfp.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <plat/regs-iic.h>
#include <plat/iic.h>
#include <plat/devs.h>
#include <plat/cpu.h>
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC3,
.end = S3C_PA_IIC3 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IIC3,
.end = IRQ_IIC3,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device s3c_device_i2c3 = {
.name = "s3c2440-i2c",
.id = 3,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
static struct s3c2410_platform_i2c default_i2c_data3 __initdata = {
.flags = 0,
.bus_num = 3,
.slave_addr = 0x10,
.frequency = 100*1000,
.sda_delay = 100,
};
void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
if (!pd)
pd = &default_i2c_data3;
npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
if (!npd)
printk(KERN_ERR "%s: no memory for platform data\n", __func__);
else if (!npd->cfg_gpio)
npd->cfg_gpio = s3c_i2c3_cfg_gpio;
s3c_device_i2c3.dev.platform_data = npd;
}
/* linux/arch/arm/plat-samsung/dev-i2c4.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5P series device definition for i2c device 3
*
* 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/gfp.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <plat/regs-iic.h>
#include <plat/iic.h>
#include <plat/devs.h>
#include <plat/cpu.h>
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC4,
.end = S3C_PA_IIC4 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IIC4,
.end = IRQ_IIC4,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device s3c_device_i2c4 = {
.name = "s3c2440-i2c",
.id = 4,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
static struct s3c2410_platform_i2c default_i2c_data4 __initdata = {
.flags = 0,
.bus_num = 4,
.slave_addr = 0x10,
.frequency = 100*1000,
.sda_delay = 100,
};
void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
if (!pd)
pd = &default_i2c_data4;
npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
if (!npd)
printk(KERN_ERR "%s: no memory for platform data\n", __func__);
else if (!npd->cfg_gpio)
npd->cfg_gpio = s3c_i2c4_cfg_gpio;
s3c_device_i2c4.dev.platform_data = npd;
}
/* linux/arch/arm/plat-samsung/dev-i2c3.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5P series device definition for i2c device 3
*
* 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/gfp.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <plat/regs-iic.h>
#include <plat/iic.h>
#include <plat/devs.h>
#include <plat/cpu.h>
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC5,
.end = S3C_PA_IIC5 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IIC5,
.end = IRQ_IIC5,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device s3c_device_i2c5 = {
.name = "s3c2440-i2c",
.id = 5,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
static struct s3c2410_platform_i2c default_i2c_data5 __initdata = {
.flags = 0,
.bus_num = 5,
.slave_addr = 0x10,
.frequency = 100*1000,
.sda_delay = 100,
};
void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
if (!pd)
pd = &default_i2c_data5;
npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
if (!npd)
printk(KERN_ERR "%s: no memory for platform data\n", __func__);
else if (!npd->cfg_gpio)
npd->cfg_gpio = s3c_i2c5_cfg_gpio;
s3c_device_i2c5.dev.platform_data = npd;
}
/* linux/arch/arm/plat-samsung/dev-i2c6.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5P series device definition for i2c device 6
*
* 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/gfp.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <plat/regs-iic.h>
#include <plat/iic.h>
#include <plat/devs.h>
#include <plat/cpu.h>
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC6,
.end = S3C_PA_IIC6 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IIC6,
.end = IRQ_IIC6,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device s3c_device_i2c6 = {
.name = "s3c2440-i2c",
.id = 6,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
static struct s3c2410_platform_i2c default_i2c_data6 __initdata = {
.flags = 0,
.bus_num = 6,
.slave_addr = 0x10,
.frequency = 100*1000,
.sda_delay = 100,
};
void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
if (!pd)
pd = &default_i2c_data6;
npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
if (!npd)
printk(KERN_ERR "%s: no memory for platform data\n", __func__);
else if (!npd->cfg_gpio)
npd->cfg_gpio = s3c_i2c6_cfg_gpio;
s3c_device_i2c6.dev.platform_data = npd;
}
/* linux/arch/arm/plat-samsung/dev-i2c7.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5P series device definition for i2c device 7
*
* 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/gfp.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <plat/regs-iic.h>
#include <plat/iic.h>
#include <plat/devs.h>
#include <plat/cpu.h>
static struct resource s3c_i2c_resource[] = {
[0] = {
.start = S3C_PA_IIC7,
.end = S3C_PA_IIC7 + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_IIC7,
.end = IRQ_IIC7,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device s3c_device_i2c7 = {
.name = "s3c2440-i2c",
.id = 7,
.num_resources = ARRAY_SIZE(s3c_i2c_resource),
.resource = s3c_i2c_resource,
};
static struct s3c2410_platform_i2c default_i2c_data7 __initdata = {
.flags = 0,
.bus_num = 7,
.slave_addr = 0x10,
.frequency = 100*1000,
.sda_delay = 100,
};
void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
{
struct s3c2410_platform_i2c *npd;
if (!pd)
pd = &default_i2c_data7;
npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
if (!npd)
printk(KERN_ERR "%s: no memory for platform data\n", __func__);
else if (!npd->cfg_gpio)
npd->cfg_gpio = s3c_i2c7_cfg_gpio;
s3c_device_i2c7.dev.platform_data = npd;
}
...@@ -41,6 +41,37 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) ...@@ -41,6 +41,37 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
} }
EXPORT_SYMBOL(s3c_gpio_cfgpin); EXPORT_SYMBOL(s3c_gpio_cfgpin);
int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
unsigned int cfg)
{
int ret;
for (; nr > 0; nr--, start++) {
ret = s3c_gpio_cfgpin(start, cfg);
if (ret != 0)
return ret;
}
return 0;
}
EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
unsigned int cfg, s3c_gpio_pull_t pull)
{
int ret;
for (; nr > 0; nr--, start++) {
s3c_gpio_setpull(start, pull);
ret = s3c_gpio_cfgpin(start, cfg);
if (ret != 0)
return ret;
}
return 0;
}
EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
unsigned s3c_gpio_getcfg(unsigned int pin) unsigned s3c_gpio_getcfg(unsigned int pin)
{ {
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
...@@ -80,6 +111,25 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull) ...@@ -80,6 +111,25 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
} }
EXPORT_SYMBOL(s3c_gpio_setpull); EXPORT_SYMBOL(s3c_gpio_setpull);
s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
{
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
unsigned long flags;
int offset;
u32 pup = 0;
if (chip) {
offset = pin - chip->chip.base;
s3c_gpio_lock(chip, flags);
pup = s3c_gpio_do_getpull(chip, offset);
s3c_gpio_unlock(chip, flags);
}
return (__force s3c_gpio_pull_t)pup;
}
EXPORT_SYMBOL(s3c_gpio_getpull);
#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg) unsigned int off, unsigned int cfg)
......
...@@ -157,3 +157,11 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) ...@@ -157,3 +157,11 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
if (ret >= 0) if (ret >= 0)
s3c_gpiolib_track(chip); s3c_gpiolib_track(chip);
} }
int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
{
struct s3c_gpio_chip *s3c_chip = container_of(chip,
struct s3c_gpio_chip, chip);
return s3c_chip->irq_base + offset;
}
...@@ -16,6 +16,15 @@ ...@@ -16,6 +16,15 @@
#define S3C64XX_AC97_GPE 1 #define S3C64XX_AC97_GPE 1
extern void s3c64xx_ac97_setup_gpio(int); extern void s3c64xx_ac97_setup_gpio(int);
/*
* The machine init code calls s5p*_spdif_setup_gpio with
* one of these defines in order to select appropriate bank
* of GPIO for S/PDIF pins
*/
#define S5PC100_SPDIF_GPD 0
#define S5PC100_SPDIF_GPG3 1
extern void s5pc100_spdif_setup_gpio(int);
/** /**
* struct s3c_audio_pdata - common platform data for audio device drivers * struct s3c_audio_pdata - common platform data for audio device drivers
* @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
......
...@@ -48,6 +48,11 @@ extern struct platform_device s3c_device_wdt; ...@@ -48,6 +48,11 @@ extern struct platform_device s3c_device_wdt;
extern struct platform_device s3c_device_i2c0; extern struct platform_device s3c_device_i2c0;
extern struct platform_device s3c_device_i2c1; extern struct platform_device s3c_device_i2c1;
extern struct platform_device s3c_device_i2c2; extern struct platform_device s3c_device_i2c2;
extern struct platform_device s3c_device_i2c3;
extern struct platform_device s3c_device_i2c4;
extern struct platform_device s3c_device_i2c5;
extern struct platform_device s3c_device_i2c6;
extern struct platform_device s3c_device_i2c7;
extern struct platform_device s3c_device_rtc; extern struct platform_device s3c_device_rtc;
extern struct platform_device s3c_device_adc; extern struct platform_device s3c_device_adc;
extern struct platform_device s3c_device_sdi; extern struct platform_device s3c_device_sdi;
...@@ -89,6 +94,7 @@ extern struct platform_device s5pv210_device_pcm2; ...@@ -89,6 +94,7 @@ extern struct platform_device s5pv210_device_pcm2;
extern struct platform_device s5pv210_device_iis0; extern struct platform_device s5pv210_device_iis0;
extern struct platform_device s5pv210_device_iis1; extern struct platform_device s5pv210_device_iis1;
extern struct platform_device s5pv210_device_iis2; extern struct platform_device s5pv210_device_iis2;
extern struct platform_device s5pv210_device_spdif;
extern struct platform_device s5p6442_device_pcm0; extern struct platform_device s5p6442_device_pcm0;
extern struct platform_device s5p6442_device_pcm1; extern struct platform_device s5p6442_device_pcm1;
...@@ -108,6 +114,7 @@ extern struct platform_device s5pc100_device_pcm1; ...@@ -108,6 +114,7 @@ extern struct platform_device s5pc100_device_pcm1;
extern struct platform_device s5pc100_device_iis0; extern struct platform_device s5pc100_device_iis0;
extern struct platform_device s5pc100_device_iis1; extern struct platform_device s5pc100_device_iis1;
extern struct platform_device s5pc100_device_iis2; extern struct platform_device s5pc100_device_iis2;
extern struct platform_device s5pc100_device_spdif;
extern struct platform_device samsung_device_keypad; extern struct platform_device samsung_device_keypad;
......
...@@ -42,6 +42,12 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip, ...@@ -42,6 +42,12 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
return (chip->config->set_pull)(chip, off, pull); return (chip->config->set_pull)(chip, off, pull);
} }
static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
unsigned int off)
{
return chip->config->get_pull(chip, off);
}
/** /**
* s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration. * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
* @chip: The gpio chip that is being configured. * @chip: The gpio chip that is being configured.
......
...@@ -108,6 +108,19 @@ extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to); ...@@ -108,6 +108,19 @@ extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
*/ */
extern unsigned s3c_gpio_getcfg(unsigned int pin); extern unsigned s3c_gpio_getcfg(unsigned int pin);
/**
* s3c_gpio_cfgpin_range() - Change the GPIO function for configuring pin range
* @start: The pin number to start at
* @nr: The number of pins to configure from @start.
* @cfg: The configuration for the pin's function
*
* Call s3c_gpio_cfgpin() for the @nr pins starting at @start.
*
* @sa s3c_gpio_cfgpin.
*/
extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
unsigned int cfg);
/* Define values for the pull-{up,down} available for each gpio pin. /* Define values for the pull-{up,down} available for each gpio pin.
* *
* These values control the state of the weak pull-{up,down} resistors * These values control the state of the weak pull-{up,down} resistors
...@@ -140,6 +153,31 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull); ...@@ -140,6 +153,31 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
*/ */
extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
/* configure `all` aspects of an gpio */
/**
* s3c_gpio_cfgall_range() - configure range of gpio functtion and pull.
* @start: The gpio number to start at.
* @nr: The number of gpio to configure from @start.
* @cfg: The configuration to use
* @pull: The pull setting to use.
*
* Run s3c_gpio_cfgpin() and s3c_gpio_setpull() over the gpio range starting
* @gpio and running for @size.
*
* @sa s3c_gpio_cfgpin
* @sa s3c_gpio_setpull
* @sa s3c_gpio_cfgpin_range
*/
extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
unsigned int cfg, s3c_gpio_pull_t pull);
static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size,
unsigned int cfg)
{
return s3c_gpio_cfgall_range(pin, size, cfg, S3C_GPIO_PULL_NONE);
}
/* Define values for the drvstr available for each gpio pin. /* Define values for the drvstr available for each gpio pin.
* *
* These values control the value of the output signal driver strength, * These values control the value of the output signal driver strength,
...@@ -169,4 +207,22 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin); ...@@ -169,4 +207,22 @@ extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
*/ */
extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr); extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
/**
* s5p_register_gpio_interrupt() - register interrupt support for a gpio group
* @pin: The pin number from the group to be registered
*
* This function registers gpio interrupt support for the group that the
* specified pin belongs to.
*
* The total number of gpio pins is quite large ob s5p series. Registering
* irq support for all of them would be a resource waste. Because of that the
* interrupt support for standard gpio pins is registered dynamically.
*
* It will return the irq number of the interrupt that has been registered
* or -ENOMEM if no more gpio interrupts can be registered. It is allowed
* to call this function more than once for the same gpio group (the group
* will be registered only once).
*/
extern int s5p_register_gpio_interrupt(int pin);
#endif /* __PLAT_GPIO_CFG_H */ #endif /* __PLAT_GPIO_CFG_H */
...@@ -43,6 +43,8 @@ struct s3c_gpio_cfg; ...@@ -43,6 +43,8 @@ struct s3c_gpio_cfg;
* struct s3c_gpio_chip - wrapper for specific implementation of gpio * struct s3c_gpio_chip - wrapper for specific implementation of gpio
* @chip: The chip structure to be exported via gpiolib. * @chip: The chip structure to be exported via gpiolib.
* @base: The base pointer to the gpio configuration registers. * @base: The base pointer to the gpio configuration registers.
* @group: The group register number for gpio interrupt support.
* @irq_base: The base irq number.
* @config: special function and pull-resistor control information. * @config: special function and pull-resistor control information.
* @lock: Lock for exclusive access to this gpio bank. * @lock: Lock for exclusive access to this gpio bank.
* @pm_save: Save information for suspend/resume support. * @pm_save: Save information for suspend/resume support.
...@@ -63,6 +65,8 @@ struct s3c_gpio_chip { ...@@ -63,6 +65,8 @@ struct s3c_gpio_chip {
struct s3c_gpio_cfg *config; struct s3c_gpio_cfg *config;
struct s3c_gpio_pm *pm; struct s3c_gpio_pm *pm;
void __iomem *base; void __iomem *base;
int irq_base;
int group;
spinlock_t lock; spinlock_t lock;
#ifdef CONFIG_PM #ifdef CONFIG_PM
u32 pm_save[4]; u32 pm_save[4];
...@@ -118,6 +122,17 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip, ...@@ -118,6 +122,17 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip); extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip); extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
/**
* samsung_gpiolib_to_irq - convert gpio pin to irq number
* @chip: The gpio chip that the pin belongs to.
* @offset: The offset of the pin in the chip.
*
* This helper returns the irq number calculated from the chip->irq_base and
* the provided offset.
*/
extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset);
/* exported for core SoC support to change */ /* exported for core SoC support to change */
extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default; extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
......
...@@ -55,10 +55,20 @@ struct s3c2410_platform_i2c { ...@@ -55,10 +55,20 @@ struct s3c2410_platform_i2c {
extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c); extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c); extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c); extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
/* defined by architecture to configure gpio */ /* defined by architecture to configure gpio */
extern void s3c_i2c0_cfg_gpio(struct platform_device *dev); extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c1_cfg_gpio(struct platform_device *dev); extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c2_cfg_gpio(struct platform_device *dev); extern void s3c_i2c2_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c3_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c4_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
#endif /* __ASM_ARCH_IIC_H */ #endif /* __ASM_ARCH_IIC_H */
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#ifndef __ASM_PLAT_MAP_H #ifndef __ASM_PLAT_MAP_H
#define __ASM_PLAT_MAP_H __FILE__ #define __ASM_PLAT_MAP_H __FILE__
/* Fit all our registers in at 0xF4000000 upwards, trying to use as /* Fit all our registers in at 0xF6000000 upwards, trying to use as
* little of the VA space as possible so vmalloc and friends have a * little of the VA space as possible so vmalloc and friends have a
* better chance of getting memory. * better chance of getting memory.
* *
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
* an single MOVS instruction (ie, only 8 bits of set data) * an single MOVS instruction (ie, only 8 bits of set data)
*/ */
#define S3C_ADDR_BASE (0xF4000000) #define S3C_ADDR_BASE 0xF6000000
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x)) #define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
......
/* arch/arm/plat-samsung/include/plat/nand-core.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S3C - Nand Controller core functions
*
* 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.
*/
#ifndef __ASM_ARCH_NAND_CORE_H
#define __ASM_ARCH_NAND_CORE_H __FILE__
/* These functions are only for use with the core support code, such as
* the cpu specific initialisation code
*/
/* re-define device name depending on support. */
static inline void s3c_nand_setname(char *name)
{
#ifdef CONFIG_S3C_DEV_NAND
s3c_device_nand.name = name;
#endif
}
#endif /* __ASM_ARCH_NAND_CORE_H */
...@@ -28,11 +28,17 @@ enum cd_types { ...@@ -28,11 +28,17 @@ enum cd_types {
S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */ S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
}; };
enum clk_types {
S3C_SDHCI_CLK_DIV_INTERNAL, /* use mmc internal clock divider */
S3C_SDHCI_CLK_DIV_EXTERNAL, /* use external clock divider */
};
/** /**
* struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
* @max_width: The maximum number of data bits supported. * @max_width: The maximum number of data bits supported.
* @host_caps: Standard MMC host capabilities bit field. * @host_caps: Standard MMC host capabilities bit field.
* @cd_type: Type of Card Detection method (see cd_types enum above) * @cd_type: Type of Card Detection method (see cd_types enum above)
* @clk_type: Type of clock divider method (see clk_types enum above)
* @ext_cd_init: Initialize external card detect subsystem. Called on * @ext_cd_init: Initialize external card detect subsystem. Called on
* sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL. * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
* notify_func argument is a callback to the sdhci-s3c driver * notify_func argument is a callback to the sdhci-s3c driver
...@@ -59,6 +65,7 @@ struct s3c_sdhci_platdata { ...@@ -59,6 +65,7 @@ struct s3c_sdhci_platdata {
unsigned int max_width; unsigned int max_width;
unsigned int host_caps; unsigned int host_caps;
enum cd_types cd_type; enum cd_types cd_type;
enum clk_types clk_type;
char **clocks; /* set of clock sources */ char **clocks; /* set of clock sources */
...@@ -110,6 +117,10 @@ extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w); ...@@ -110,6 +117,10 @@ extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w); extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w); extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w); extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
extern void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
/* S3C64XX SDHCI setup */ /* S3C64XX SDHCI setup */
...@@ -288,4 +299,57 @@ static inline void s5pv210_default_sdhci3(void) { } ...@@ -288,4 +299,57 @@ static inline void s5pv210_default_sdhci3(void) { }
#endif /* CONFIG_S5PV210_SETUP_SDHCI */ #endif /* CONFIG_S5PV210_SETUP_SDHCI */
/* S5PV310 SDHCI setup */
#ifdef CONFIG_S5PV310_SETUP_SDHCI
extern char *s5pv310_hsmmc_clksrcs[4];
extern void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev,
void __iomem *r,
struct mmc_ios *ios,
struct mmc_card *card);
static inline void s5pv310_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
s3c_hsmmc0_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
s3c_hsmmc0_def_platdata.cfg_gpio = s5pv310_setup_sdhci0_cfg_gpio;
s3c_hsmmc0_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
#endif
}
static inline void s5pv310_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
s3c_hsmmc1_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
s3c_hsmmc1_def_platdata.cfg_gpio = s5pv310_setup_sdhci1_cfg_gpio;
s3c_hsmmc1_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
#endif
}
static inline void s5pv310_default_sdhci2(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC2
s3c_hsmmc2_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
s3c_hsmmc2_def_platdata.cfg_gpio = s5pv310_setup_sdhci2_cfg_gpio;
s3c_hsmmc2_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
#endif
}
static inline void s5pv310_default_sdhci3(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC3
s3c_hsmmc3_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
s3c_hsmmc3_def_platdata.cfg_gpio = s5pv310_setup_sdhci3_cfg_gpio;
s3c_hsmmc3_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
#endif
}
#else
static inline void s5pv310_default_sdhci0(void) { }
static inline void s5pv310_default_sdhci1(void) { }
static inline void s5pv310_default_sdhci2(void) { }
static inline void s5pv310_default_sdhci3(void) { }
#endif /* CONFIG_S5PV310_SETUP_SDHCI */
#endif /* __PLAT_S3C_SDHCI_H */ #endif /* __PLAT_S3C_SDHCI_H */
...@@ -192,7 +192,7 @@ struct s3c_gpio_pm s3c_gpio_pm_2bit = { ...@@ -192,7 +192,7 @@ struct s3c_gpio_pm s3c_gpio_pm_2bit = {
.resume = s3c_gpio_pm_2bit_resume, .resume = s3c_gpio_pm_2bit_resume,
}; };
#ifdef CONFIG_ARCH_S3C64XX #if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip) static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
{ {
chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON); chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
...@@ -302,7 +302,7 @@ struct s3c_gpio_pm s3c_gpio_pm_4bit = { ...@@ -302,7 +302,7 @@ struct s3c_gpio_pm s3c_gpio_pm_4bit = {
.save = s3c_gpio_pm_4bit_save, .save = s3c_gpio_pm_4bit_save,
.resume = s3c_gpio_pm_4bit_resume, .resume = s3c_gpio_pm_4bit_resume,
}; };
#endif /* CONFIG_ARCH_S3C64XX */ #endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
/** /**
* s3c_pm_save_gpio() - save gpio chip data for suspend * s3c_pm_save_gpio() - save gpio chip data for suspend
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <asm/hardware/pl330.h> #include <asm/hardware/pl330.h>
...@@ -27,6 +29,7 @@ ...@@ -27,6 +29,7 @@
* @node: To attach to the global list of DMACs. * @node: To attach to the global list of DMACs.
* @pi: PL330 configuration info for the DMAC. * @pi: PL330 configuration info for the DMAC.
* @kmcache: Pool to quickly allocate xfers for all channels in the dmac. * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
* @clk: Pointer of DMAC operation clock.
*/ */
struct s3c_pl330_dmac { struct s3c_pl330_dmac {
unsigned busy_chan; unsigned busy_chan;
...@@ -34,6 +37,7 @@ struct s3c_pl330_dmac { ...@@ -34,6 +37,7 @@ struct s3c_pl330_dmac {
struct list_head node; struct list_head node;
struct pl330_info *pi; struct pl330_info *pi;
struct kmem_cache *kmcache; struct kmem_cache *kmcache;
struct clk *clk;
}; };
/** /**
...@@ -1072,16 +1076,25 @@ static int pl330_probe(struct platform_device *pdev) ...@@ -1072,16 +1076,25 @@ static int pl330_probe(struct platform_device *pdev)
if (ret) if (ret)
goto probe_err4; goto probe_err4;
ret = pl330_add(pl330_info);
if (ret)
goto probe_err5;
/* Allocate a new DMAC */ /* Allocate a new DMAC */
s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL); s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
if (!s3c_pl330_dmac) { if (!s3c_pl330_dmac) {
ret = -ENOMEM; ret = -ENOMEM;
goto probe_err5;
}
/* Get operation clock and enable it */
s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
if (IS_ERR(s3c_pl330_dmac->clk)) {
dev_err(&pdev->dev, "Cannot get operation clock.\n");
ret = -EINVAL;
goto probe_err6; goto probe_err6;
} }
clk_enable(s3c_pl330_dmac->clk);
ret = pl330_add(pl330_info);
if (ret)
goto probe_err7;
/* Hook the info */ /* Hook the info */
s3c_pl330_dmac->pi = pl330_info; s3c_pl330_dmac->pi = pl330_info;
...@@ -1094,7 +1107,7 @@ static int pl330_probe(struct platform_device *pdev) ...@@ -1094,7 +1107,7 @@ static int pl330_probe(struct platform_device *pdev)
if (!s3c_pl330_dmac->kmcache) { if (!s3c_pl330_dmac->kmcache) {
ret = -ENOMEM; ret = -ENOMEM;
goto probe_err7; goto probe_err8;
} }
/* Get the list of peripherals */ /* Get the list of peripherals */
...@@ -1120,10 +1133,13 @@ static int pl330_probe(struct platform_device *pdev) ...@@ -1120,10 +1133,13 @@ static int pl330_probe(struct platform_device *pdev)
return 0; return 0;
probe_err8:
pl330_del(pl330_info);
probe_err7: probe_err7:
kfree(s3c_pl330_dmac); clk_disable(s3c_pl330_dmac->clk);
clk_put(s3c_pl330_dmac->clk);
probe_err6: probe_err6:
pl330_del(pl330_info); kfree(s3c_pl330_dmac);
probe_err5: probe_err5:
free_irq(irq, pl330_info); free_irq(irq, pl330_info);
probe_err4: probe_err4:
...@@ -1188,6 +1204,10 @@ static int pl330_remove(struct platform_device *pdev) ...@@ -1188,6 +1204,10 @@ static int pl330_remove(struct platform_device *pdev)
} }
} }
/* Disable operation clock */
clk_disable(dmac->clk);
clk_put(dmac->clk);
/* Remove the DMAC */ /* Remove the DMAC */
list_del(&dmac->node); list_del(&dmac->node);
kfree(dmac); kfree(dmac);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment