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
config ARCH_S5PV210
bool "Samsung S5PV210/S5PC110"
select CPU_V7
select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
select ARM_L1_CACHE_SHIFT_6
select ARCH_HAS_CPUFREQ
select ARCH_USES_GETTIMEOFFSET
select HAVE_S3C2410_I2C
select HAVE_S3C_RTC
......@@ -740,9 +742,13 @@ config ARCH_S5PV210
config ARCH_S5PV310
bool "Samsung S5PV310/S5PC210"
select CPU_V7
select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
select GENERIC_CLOCKEVENTS
select HAVE_S3C_RTC
select HAVE_S3C2410_I2C
select HAVE_S3C2410_WATCHDOG
help
Samsung S5PV310 series based systems
......
......@@ -53,6 +53,10 @@
#define L2X0_LINE_DATA 0xF10
#define L2X0_LINE_TAG 0xF30
#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__
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
......
......@@ -22,6 +22,8 @@
#ifdef CONFIG_CPU_S3C244X
#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
#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
#endif
......@@ -30,8 +32,10 @@
#include <mach/gpio-nrs.h>
#include <mach/gpio-fns.h>
#ifdef CONFIG_CPU_S3C24XX
#define S3C_GPIO_END (S3C2410_GPIO_BANKJ + 32)
#ifdef CONFIG_CPU_S3C244X
#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
#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32)
#define S3C_GPIO_END (S3C2410_GPH(0) + 32)
#endif
......@@ -118,6 +118,8 @@
#define S3C2443_SCLKCON_UARTCLK (1<<8)
#define S3C2443_SCLKCON_USBHOST (1<<1)
#define S3C2443_PWRCFG_SLEEP (1<<15)
#include <asm/div64.h>
static inline unsigned int
......
......@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xE0000000UL
#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
......@@ -51,6 +51,7 @@
#include <plat/clock.h>
#include <plat/pm.h>
#include <plat/pll.h>
#include <plat/nand-core.h>
#ifndef CONFIG_CPU_S3C2412_ONLY
void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
......@@ -92,7 +93,7 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
/* rename devices that are s3c2412/s3c2413 specific */
s3c_device_sdi.name = "s3c2412-sdi";
s3c_device_lcd.name = "s3c2412-lcd";
s3c_device_nand.name = "s3c2412-nand";
s3c_nand_setname("s3c2412-nand");
/* alter IRQ of SDI controller */
......
......@@ -25,6 +25,11 @@ config S3C2416_DMA
help
Internal config node for S3C2416 DMA support
config S3C2416_PM
bool
help
Internal config node to apply S3C2416 power management
menu "S3C2416 Machines"
config MACH_SMDK2416
......@@ -33,6 +38,7 @@ config MACH_SMDK2416
select S3C_DEV_FB
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C2416_PM if PM
help
Say Y here if you are using an SMDK2416
......
......@@ -11,7 +11,7 @@ obj- :=
obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o
obj-$(CONFIG_CPU_S3C2416) += irq.o
obj-$(CONFIG_S3C2416_PM) += pm.o
#obj-$(CONFIG_S3C2416_DMA) += dma.o
# Machine support
......
......@@ -243,6 +243,8 @@ static int __init s3c2416_irq_add(struct sys_device *sysdev)
static struct sysdev_driver s3c2416_irq_driver = {
.add = s3c2416_irq_add,
.suspend = s3c24xx_irq_suspend,
.resume = s3c24xx_irq_resume,
};
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 @@
#include <plat/iic-core.h>
#include <plat/fb-core.h>
#include <plat/nand-core.h>
static struct map_desc s3c2416_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
......@@ -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);
s3c_device_nand.name = "s3c2416-nand";
s3c_nand_setname("s3c2412-nand");
}
/* s3c2416_map_io
......
......@@ -44,6 +44,7 @@
#include <plat/cpu.h>
#include <plat/pm.h>
#include <plat/pll.h>
#include <plat/nand-core.h>
static struct map_desc s3c244x_iodesc[] __initdata = {
IODESC_ENT(CLKPWR),
......@@ -68,7 +69,7 @@ void __init s3c244x_map_io(void)
s3c_device_sdi.name = "s3c2440-sdi";
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_usbgadget.name = "s3c2440-usbgadget";
}
......
......@@ -36,6 +36,7 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/fb-core.h>
#include <plat/nand-core.h>
static struct map_desc s3c2443_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
......@@ -62,7 +63,7 @@ int __init s3c2443_init(void)
s3c24xx_reset_hook = s3c2443_hard_reset;
s3c_device_nand.name = "s3c2412-nand";
s3c_nand_setname("s3c2412-nand");
s3c_fb_setname("s3c2443-fb");
/* change WDT IRQ number */
......
......@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END (0xe0000000UL)
#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
......@@ -98,12 +98,33 @@ config MACH_ANW6410
help
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
bool "REAL6410"
select CPU_S3C6410
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
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
Machine support for the CoreWind REAL6410
......
......@@ -53,6 +53,7 @@ obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.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_HMT) += mach-hmt.o
obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
......
......@@ -22,27 +22,16 @@
#include <plat/audio.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)
{
unsigned int base;
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK);
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);
base = S3C64XX_GPD(0);
break;
case 1:
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_I2S1_CLK);
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);
base = S3C64XX_GPE(0);
break;
default:
printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
......@@ -50,18 +39,17 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
return 0;
}
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(5), S3C64XX_GPC5_I2S_V40_DO1);
s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_I2S_V40_DO2);
s3c_gpio_cfgpin(S3C64XX_GPH(6), S3C64XX_GPH6_I2S_V40_BCLK);
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);
s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
return 0;
}
......@@ -170,20 +158,14 @@ EXPORT_SYMBOL(s3c64xx_device_iisv4);
static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_PCM0_SCLK);
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);
base = S3C64XX_GPD(0);
break;
case 1:
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_PCM1_SCLK);
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);
base = S3C64XX_GPE(0);
break;
default:
printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
......@@ -191,6 +173,7 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
return 0;
}
......@@ -264,24 +247,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm1);
static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
{
s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_AC97_BITCLK);
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;
return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
}
static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
{
s3c_gpio_cfgpin(S3C64XX_GPE(0), S3C64XX_GPE0_AC97_BITCLK);
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;
return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
}
static struct resource s3c64xx_ac97_resource[] = {
......
......@@ -195,11 +195,6 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
.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[] = {
{
.base = S3C64XX_GPF_BASE,
......@@ -227,12 +222,13 @@ static struct s3c_gpio_chip gpio_2bit[] = {
},
}, {
.base = S3C64XX_GPN_BASE,
.irq_base = IRQ_EINT(0),
.config = &gpio_2bit_cfg_eint10,
.chip = {
.base = S3C64XX_GPN(0),
.ngpio = S3C64XX_GPIO_N_NR,
.label = "GPN",
.to_irq = s3c64xx_gpio2int_gpn,
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = S3C64XX_GPO_BASE,
......
......@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xE0000000UL
#define VMALLOC_END 0xF6000000UL
#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 @@
*
*/
#include <linux/kernel.h>
#include <linux/types.h>
#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/init.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/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/s3c6410.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)
......@@ -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 = {
&real6410_device_eth,
&s3c_device_hsmmc0,
&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)
{
u32 tmp;
s3c64xx_init_io(NULL, 0);
s3c24xx_init_clocks(12000000);
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)
{
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 */
......@@ -136,6 +322,8 @@ static void __init real6410_machine_init(void)
(4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
(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));
}
......
......@@ -23,15 +23,6 @@
extern void s3c64xx_fb_gpio_setup_24bpp(void)
{
unsigned int gpio;
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);
}
s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2));
s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2));
}
......@@ -17,11 +17,11 @@
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <plat/gpio-cfg.h>
#include <plat/ata.h>
void s3c64xx_ide_setup_gpio(void)
{
u32 reg;
u32 gpio = 0;
reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
......@@ -32,15 +32,12 @@ void s3c64xx_ide_setup_gpio(void)
s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
/* Set XhiDATA[15:0] pins as CF Data[15:0] */
for (gpio = S3C64XX_GPK(0); gpio <= S3C64XX_GPK(15); gpio++)
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S3C64XX_GPK(0), 16, S3C_GPIO_SFN(5));
/* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
for (gpio = S3C64XX_GPL(0); gpio <= S3C64XX_GPL(2); gpio++)
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
s3c_gpio_cfgpin_range(S3C64XX_GPL(0), 3, S3C_GPIO_SFN(6));
/* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
for (gpio = S3C64XX_GPM(0); gpio <= S3C64XX_GPM(4); gpio++)
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
s3c_gpio_cfgpin_range(S3C64XX_GPM(0), 5, S3C_GPIO_SFN(6));
}
......@@ -12,23 +12,13 @@
#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <plat/keypad.h>
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] */
end = S3C64XX_GPK(8 + rows);
for (gpio = S3C64XX_GPK(8); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), 8 + rows, S3C_GPIO_SFN(3));
/* Set all the necessary GPL pins to special-function 3: KP_COL[x] */
end = S3C64XX_GPL(0 + cols);
for (gpio = S3C64XX_GPL(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3));
}
......@@ -24,16 +24,9 @@
void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
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 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);
}
/* Set all the necessary GPG pins to special-function 2 */
s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
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)
void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
end = S3C64XX_GPH(2 + width);
/* 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);
}
/* Set all the necessary GPH pins to special-function 2 */
s3c_gpio_cfgrange_nopull(S3C64XX_GPH(0), 2 + width, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
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)
void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
unsigned int gpio;
unsigned int end;
/* Set all the necessary GPH pins to special-function 3 */
s3c_gpio_cfgrange_nopull(S3C64XX_GPH(6), width, S3C_GPIO_SFN(3));
end = S3C64XX_GPH(6 + width);
/* 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);
}
/* Set all the necessary GPC pins to special-function 3 */
s3c_gpio_cfgrange_nopull(S3C64XX_GPC(4), 2, S3C_GPIO_SFN(3));
}
......@@ -11,7 +11,6 @@ if ARCH_S5P6442
config CPU_S5P6442
bool
select PLAT_S5P
select S3C_PL330_DMA
help
Enable S5P6442 CPU support
......
......@@ -192,6 +192,11 @@ static struct clk clk_pclkd1 = {
.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)
{
return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
......@@ -335,6 +340,16 @@ void __init_or_cpufreq s5p6442_setup_clocks(void)
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[] = {
{
.name = "systimer",
......@@ -393,10 +408,23 @@ static struct clk *clks[] __initdata = {
void __init s5p6442_register_clocks(void)
{
struct clk *clkptr;
int i, ret;
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
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();
}
......@@ -21,22 +21,16 @@
static int s5p6442_cfg_i2s(struct platform_device *pdev)
{
unsigned int base;
/* configure GPIO for i2s port */
switch (pdev->id) {
case 1:
s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2));
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));
base = S5P6442_GPC1(0);
break;
case -1:
s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2));
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));
base = S5P6442_GPC0(0);
break;
default:
......@@ -44,6 +38,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev)
return -EINVAL;
}
s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
return 0;
}
......@@ -111,21 +106,15 @@ struct platform_device s5p6442_device_iis1 = {
static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3));
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));
base = S5P6442_GPC0(0);
break;
case 1:
s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3));
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));
base = S5P6442_GPC1(0);
break;
default:
......@@ -133,6 +122,7 @@ static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
return 0;
}
......
......@@ -38,11 +38,9 @@ static int s5p6442_spi_cfg_gpio(struct platform_device *pdev)
switch (pdev->id) {
case 0:
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(2), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5P6442_GPB(3), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5P6442_GPB(2), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break;
default:
......
......@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5p6442_pdma_pdata = {
static struct platform_device s5p6442_device_pdma = {
.name = "s3c-pl330",
.id = 1,
.id = -1,
.num_resources = ARRAY_SIZE(s5p6442_pdma_resource),
.resource = s5p6442_pdma_resource,
.dev = {
......
......@@ -46,6 +46,7 @@
#define S5P_CLK_DIV5 S5P_CLKREG(0x314)
#define S5P_CLK_DIV6 S5P_CLKREG(0x318)
#define S5P_CLKGATE_IP0 S5P_CLKREG(0x460)
#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C)
/* CLK_OUT */
......
......@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xE0000000UL
#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
......@@ -9,14 +9,12 @@ if ARCH_S5P64X0
config CPU_S5P6440
bool
select PLAT_S5P
select S3C_PL330_DMA
help
Enable S5P6440 CPU support
config CPU_S5P6450
bool
select PLAT_S5P
select S3C_PL330_DMA
help
Enable S5P6450 CPU support
......
......@@ -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_k, S5P64X0_EPLL_CON_K);
printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
clk->rate, rate);
clk->rate = rate;
return 0;
}
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,
};
......@@ -149,6 +152,12 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_hclk.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 8),
}, {
.name = "pdma",
.id = -1,
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 12),
}, {
.name = "hsmmc",
.id = 0,
......@@ -330,12 +339,6 @@ static struct clk init_clocks[] = {
.parent = &clk_hclk.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 21),
}, {
.name = "dma",
.id = -1,
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 12),
}, {
.name = "uart",
.id = 0,
......@@ -548,7 +551,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
/* 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_48m.enable = s5p64x0_clk48m_ctrl;
......
......@@ -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_k, S5P64X0_EPLL_CON_K);
printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
clk->rate, rate);
clk->rate = rate;
return 0;
}
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,
};
......@@ -185,6 +188,12 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 3),
}, {
.name = "pdma",
.id = -1,
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 12),
}, {
.name = "hsmmc",
.id = 0,
......@@ -282,12 +291,6 @@ static struct clk init_clocks[] = {
.parent = &clk_hclk.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 21),
}, {
.name = "dma",
.id = -1,
.parent = &clk_hclk_low.clk,
.enable = s5p64x0_hclk0_ctrl,
.ctrlbit = (1 << 12),
}, {
.name = "uart",
.id = 0,
......@@ -581,7 +584,7 @@ void __init_or_cpufreq s5p6450_setup_clocks(void)
/* 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_48m.enable = s5p64x0_clk48m_ctrl;
......
......@@ -73,24 +73,6 @@ static const u32 clock_table[][3] = {
{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 rate = clk_get_rate(clk->parent);
......
......@@ -24,13 +24,8 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev)
/* configure GPIO for i2s port */
switch (pdev->id) {
case -1:
s3c_gpio_cfgpin(S5P6440_GPR(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6440_GPR(5), 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));
s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5));
break;
default:
......@@ -47,13 +42,9 @@ static int s5p6450_cfg_i2s(struct platform_device *pdev)
switch (pdev->id) {
case -1:
s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(4), S3C_GPIO_SFN(5));
s3c_gpio_cfgpin(S5P6450_GPR(5), 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));
s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
break;
default:
......@@ -116,11 +107,8 @@ static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5P6440_GPR(7), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5P6440_GPR(13), 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));
s3c_gpio_cfgpin_range(S5P6440_GPR(6), 3, S3C_GPIO_SFN(2));
s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(2));
break;
default:
......
......@@ -39,23 +39,15 @@ static char *s5p64x0_spi_src_clks[] = {
*/
static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5P6440_GPC(0), S3C_GPIO_SFN(2));
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);
base = S5P6440_GPC(0);
break;
case 1:
s3c_gpio_cfgpin(S5P6440_GPC(4), S3C_GPIO_SFN(2));
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);
base = S5P6440_GPC(4);
break;
default:
......@@ -63,28 +55,23 @@ static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5P6450_GPC(0), S3C_GPIO_SFN(2));
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);
base = S5P6450_GPC(0);
break;
case 1:
s3c_gpio_cfgpin(S5P6450_GPC(4), S3C_GPIO_SFN(2));
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);
base = S5P6450_GPC(4);
break;
default:
......@@ -92,6 +79,9 @@ static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
......
......@@ -122,7 +122,7 @@ static struct s3c_pl330_platdata s5p6450_pdma_pdata = {
static struct platform_device s5p64x0_device_pdma = {
.name = "s3c-pl330",
.id = 0,
.id = -1,
.num_resources = ARRAY_SIZE(s5p64x0_pdma_resource),
.resource = s5p64x0_pdma_resource,
.dev = {
......
......@@ -60,4 +60,6 @@
#define ARM_DIV_RATIO_SHIFT 0
#define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT)
#define S5P_EPLL_CON S5P64X0_EPLL_CON
#endif /* __ASM_ARCH_REGS_CLOCK_H */
......@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END 0xE0000000UL
#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
......@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */
void s5p6440_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5P6440_GPB(5), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6440_GPB(5), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6440_GPB(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6440_GPB(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5P6440_GPB(5), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
void s5p6450_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5P6450_GPB(5), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6450_GPB(5), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6450_GPB(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5P6450_GPB(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5P6450_GPB(5), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
......@@ -25,18 +25,14 @@ struct platform_device; /* don't need the contents */
void s5p6440_i2c1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5P6440_GPR(9), S3C_GPIO_SFN(6));
s3c_gpio_setpull(S5P6440_GPR(9), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6440_GPR(10), S3C_GPIO_SFN(6));
s3c_gpio_setpull(S5P6440_GPR(10), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5P6440_GPR(9), 2,
S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
}
void s5p6450_i2c1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5P6450_GPR(9), S3C_GPIO_SFN(6));
s3c_gpio_setpull(S5P6450_GPR(9), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5P6450_GPR(10), S3C_GPIO_SFN(6));
s3c_gpio_setpull(S5P6450_GPR(10), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5P6450_GPR(9), 2,
S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
}
void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
......@@ -9,7 +9,6 @@ if ARCH_S5PC100
config CPU_S5PC100
bool
select PLAT_S5P
select S5P_EXT_INT
select S3C_PL330_DMA
help
......
......@@ -11,7 +11,7 @@ obj- :=
# 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) += dma.o
......
......@@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = {
.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] = {
{ 32750000, 131, 3, 4 },
{ 32768000, 131, 3, 4 },
......@@ -341,13 +323,16 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
__raw_writel(epll_con, S5P_EPLL_CON);
printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
clk->rate, rate);
clk->rate = rate;
return 0;
}
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,
};
......@@ -691,55 +676,55 @@ static struct clk init_clocks_disable[] = {
}, {
.name = "iis",
.id = 0,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 0),
}, {
.name = "iis",
.id = 1,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 1),
}, {
.name = "iis",
.id = 2,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 2),
}, {
.name = "ac97",
.id = -1,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 3),
}, {
.name = "pcm",
.id = 0,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 4),
}, {
.name = "pcm",
.id = 1,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 5),
}, {
.name = "spdif",
.id = -1,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 6),
}, {
.name = "adc",
.id = -1,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 7),
}, {
.name = "keypad",
.id = -1,
.parent = &clk_div_d1_bus.clk,
.parent = &clk_div_pclkd1.clk,
.enable = s5pc100_d1_5_ctrl,
.ctrlbit = (1 << 8),
}, {
......@@ -848,6 +833,18 @@ struct clksrc_sources clk_src_group3 = {
.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[] = {
[0] = &clk_mout_epll.clk,
[1] = &clk_div_mpll.clk,
......@@ -862,6 +859,18 @@ struct clksrc_sources clk_src_group4 = {
.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[] = {
[0] = &clk_mout_epll.clk,
[1] = &clk_div_mpll.clk,
......@@ -875,6 +884,18 @@ struct clksrc_sources clk_src_group5 = {
.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[] = {
[0] = &s5p_clk_27m,
[1] = &clk_vclk54m,
......@@ -944,6 +965,64 @@ struct clksrc_sources clk_src_pwi = {
.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[] = {
{
.clk = {
......@@ -999,39 +1078,6 @@ static struct clksrc_clk clksrcs[] = {
},
.sources = &clk_src_group6,
.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 = {
.name = "sclk_lcd",
......@@ -1179,6 +1225,10 @@ static struct clksrc_clk *sysclks[] = {
&clk_div_pclkd1,
&clk_div_cam,
&clk_div_hdmi,
&clk_sclk_audio0,
&clk_sclk_audio1,
&clk_sclk_audio2,
&clk_sclk_spdif,
};
void __init_or_cpufreq s5pc100_setup_clocks(void)
......@@ -1196,7 +1246,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void)
unsigned int ptr;
/* 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;
printk(KERN_DEBUG "%s: registering clocks\n", __func__);
......
......@@ -24,19 +24,11 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev)
/* configure GPIO for i2s port */
switch (pdev->id) {
case 1:
s3c_gpio_cfgpin(S5PC100_GPC(0), 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));
s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
break;
case 2:
s3c_gpio_cfgpin(S5PC100_GPG3(0), 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));
s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
break;
case -1: /* Dedicated pins */
......@@ -144,19 +136,11 @@ static int s5pc100_pcm_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5PC100_GPG3(0), 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));
s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(5));
break;
case 1:
s3c_gpio_cfgpin(S5PC100_GPC(0), 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));
s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(3));
break;
default:
......@@ -231,13 +215,7 @@ struct platform_device s5pc100_device_pcm1 = {
static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev)
{
s3c_gpio_cfgpin(S5PC100_GPC(0), 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;
return s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(4));
}
static struct resource s5pc100_ac97_resource[] = {
......@@ -285,3 +263,57 @@ struct platform_device s5pc100_device_ac97 = {
.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)
{
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5PC100_GPB(0), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PC100_GPB(1), S3C_GPIO_SFN(2));
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);
s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break;
case 1:
s3c_gpio_cfgpin(S5PC100_GPB(4), S3C_GPIO_SFN(2));
s3c_gpio_cfgpin(S5PC100_GPB(5), S3C_GPIO_SFN(2));
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);
s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
break;
case 2:
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(2), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S5PC100_GPG3(3), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
break;
default:
......
......@@ -81,7 +81,7 @@ static struct s3c_pl330_platdata s5pc100_pdma0_pdata = {
static struct platform_device s5pc100_device_pdma0 = {
.name = "s3c-pl330",
.id = 1,
.id = 0,
.num_resources = ARRAY_SIZE(s5pc100_pdma0_resource),
.resource = s5pc100_pdma0_resource,
.dev = {
......@@ -143,7 +143,7 @@ static struct s3c_pl330_platdata s5pc100_pdma1_pdata = {
static struct platform_device s5pc100_device_pdma1 = {
.name = "s3c-pl330",
.id = 2,
.id = 1,
.num_resources = ARRAY_SIZE(s5pc100_pdma1_resource),
.resource = s5pc100_pdma1_resource,
.dev = {
......
/*
* arch/arm/plat-s5pc100/gpiolib.c
/* linux/arch/arm/mach-s5pc100/gpiolib.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Copyright 2009 Samsung Electronics Co
* Kyungmin Park <kyungmin.park@samsung.com>
......@@ -61,30 +63,6 @@
* 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 = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
......@@ -104,209 +82,150 @@ static struct s3c_gpio_cfg gpio_cfg_noint = {
.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[] = {
{
.base = S5PC100_GPA0_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPA0(0),
.ngpio = S5PC100_GPIO_A0_NR,
.label = "GPA0",
},
}, {
.base = S5PC100_GPA1_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPA1(0),
.ngpio = S5PC100_GPIO_A1_NR,
.label = "GPA1",
},
}, {
.base = S5PC100_GPB_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPB(0),
.ngpio = S5PC100_GPIO_B_NR,
.label = "GPB",
},
}, {
.base = S5PC100_GPC_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPC(0),
.ngpio = S5PC100_GPIO_C_NR,
.label = "GPC",
},
}, {
.base = S5PC100_GPD_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPD(0),
.ngpio = S5PC100_GPIO_D_NR,
.label = "GPD",
},
}, {
.base = S5PC100_GPE0_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPE0(0),
.ngpio = S5PC100_GPIO_E0_NR,
.label = "GPE0",
},
}, {
.base = S5PC100_GPE1_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPE1(0),
.ngpio = S5PC100_GPIO_E1_NR,
.label = "GPE1",
},
}, {
.base = S5PC100_GPF0_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPF0(0),
.ngpio = S5PC100_GPIO_F0_NR,
.label = "GPF0",
},
}, {
.base = S5PC100_GPF1_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPF1(0),
.ngpio = S5PC100_GPIO_F1_NR,
.label = "GPF1",
},
}, {
.base = S5PC100_GPF2_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPF2(0),
.ngpio = S5PC100_GPIO_F2_NR,
.label = "GPF2",
},
}, {
.base = S5PC100_GPF3_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPF3(0),
.ngpio = S5PC100_GPIO_F3_NR,
.label = "GPF3",
},
}, {
.base = S5PC100_GPG0_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPG0(0),
.ngpio = S5PC100_GPIO_G0_NR,
.label = "GPG0",
},
}, {
.base = S5PC100_GPG1_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPG1(0),
.ngpio = S5PC100_GPIO_G1_NR,
.label = "GPG1",
},
}, {
.base = S5PC100_GPG2_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPG2(0),
.ngpio = S5PC100_GPIO_G2_NR,
.label = "GPG2",
},
}, {
.base = S5PC100_GPG3_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPG3(0),
.ngpio = S5PC100_GPIO_G3_NR,
.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 = {
.base = S5PC100_GPI(0),
.ngpio = S5PC100_GPIO_I_NR,
.label = "GPI",
},
}, {
.base = S5PC100_GPJ0_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ0(0),
.ngpio = S5PC100_GPIO_J0_NR,
.label = "GPJ0",
},
}, {
.base = S5PC100_GPJ1_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ1(0),
.ngpio = S5PC100_GPIO_J1_NR,
.label = "GPJ1",
},
}, {
.base = S5PC100_GPJ2_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ2(0),
.ngpio = S5PC100_GPIO_J2_NR,
.label = "GPJ2",
},
}, {
.base = S5PC100_GPJ3_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ3(0),
.ngpio = S5PC100_GPIO_J3_NR,
.label = "GPJ3",
},
}, {
.base = S5PC100_GPJ4_BASE,
.config = &gpio_cfg,
.chip = {
.base = S5PC100_GPJ4(0),
.ngpio = S5PC100_GPIO_J4_NR,
.label = "GPJ4",
},
}, {
.base = S5PC100_GPK0_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPK0(0),
......@@ -314,7 +233,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK0",
},
}, {
.base = S5PC100_GPK1_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPK1(0),
......@@ -322,7 +240,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK1",
},
}, {
.base = S5PC100_GPK2_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPK2(0),
......@@ -330,7 +247,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK2",
},
}, {
.base = S5PC100_GPK3_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPK3(0),
......@@ -338,7 +254,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPK3",
},
}, {
.base = S5PC100_GPL0_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL0(0),
......@@ -346,7 +261,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL0",
},
}, {
.base = S5PC100_GPL1_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL1(0),
......@@ -354,7 +268,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL1",
},
}, {
.base = S5PC100_GPL2_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL2(0),
......@@ -362,7 +275,6 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL2",
},
}, {
.base = S5PC100_GPL3_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL3(0),
......@@ -370,56 +282,72 @@ static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
.label = "GPL3",
},
}, {
.base = S5PC100_GPL4_BASE,
.config = &gpio_cfg_noint,
.chip = {
.base = S5PC100_GPL4(0),
.ngpio = S5PC100_GPIO_L4_NR,
.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 */
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)
static __init int s5pc100_gpiolib_init(void)
{
/* Interrupt */
if (chip->config == &gpio_cfg) {
int i, irq;
chip->chip.to_irq = s5pc100_gpiolib_to_irq;
struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
int gpioint_group = 0;
int i;
for (i = 0; i < chip->chip.ngpio; i++) {
irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
set_irq_chip(irq, &s5pc100_gpioint);
set_irq_data(irq, &chip->chip);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
for (i = 0; i < nr_chips; i++, chip++) {
if (chip->config == NULL) {
chip->config = &gpio_cfg;
chip->group = gpioint_group++;
}
} else if (chip->config == &gpio_cfg_eint) {
chip->chip.to_irq = s5pc100_gpiolib_to_eint;
if (chip->base == NULL)
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 */
set_irq_chained_handler(IRQ_GPIOINT, s5pc100_irq_gpioint_handler);
samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
return 0;
}
......
......@@ -146,13 +146,6 @@ enum s5p_gpio_number {
/* define the number of gpios we need to the one after the MP04() range */
#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>
#endif /* __ASM_ARCH_GPIO_H */
......@@ -48,8 +48,8 @@
#define IRQ_SPI1 S5P_IRQ_VIC1(16)
#define IRQ_SPI2 S5P_IRQ_VIC1(17)
#define IRQ_IRDA S5P_IRQ_VIC1(18)
#define IRQ_CAN0 S5P_IRQ_VIC1(19)
#define IRQ_CAN1 S5P_IRQ_VIC1(20)
#define IRQ_IIC2 S5P_IRQ_VIC1(19)
#define IRQ_IIC3 S5P_IRQ_VIC1(20)
#define IRQ_HSIRX S5P_IRQ_VIC1(21)
#define IRQ_HSITX S5P_IRQ_VIC1(22)
#define IRQ_UHOST S5P_IRQ_VIC1(23)
......@@ -100,11 +100,12 @@
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
#define S3C_IRQ_GPIO_BASE (IRQ_EINT(31) + 1)
#define S3C_IRQ_GPIO(x) (S3C_IRQ_GPIO_BASE + (x))
/* GPIO interrupt */
#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
#define S5P_GPIOINT_GROUP_MAXNR 21
/* Until MP04 Groups -> 40 (exactly 39) Groups * 8 ~= 320 GPIOs */
#define NR_IRQS (S3C_IRQ_GPIO(320) + 1)
/* Set the default NR_IRQS */
#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
/* Compatibility */
#define IRQ_LCD_FIFO IRQ_LCD0
......
......@@ -110,6 +110,8 @@
#define S5PC100_PA_PCM0 0xF2400000
#define S5PC100_PA_PCM1 0xF2500000
#define S5PC100_PA_SPDIF 0xF2600000
#define S5PC100_PA_TSADC (0xF3000000)
/* KEYPAD */
......
......@@ -11,43 +11,6 @@
#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 S5P_EINT_CON(x) (S5PC100EINT30CON + ((x) * 0x4))
......@@ -64,12 +27,12 @@
#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(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)
#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */
......@@ -12,6 +12,6 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H
#define VMALLOC_END (0xe0000000UL)
#define VMALLOC_END 0xF6000000UL
#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 @@
#include <plat/adc.h>
#include <plat/keypad.h>
#include <plat/ts.h>
#include <plat/audio.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
......@@ -196,6 +197,7 @@ static struct platform_device *smdkc100_devices[] __initdata = {
&s5p_device_fimc0,
&s5p_device_fimc1,
&s5p_device_fimc2,
&s5pc100_device_spdif,
};
static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
......@@ -226,6 +228,8 @@ static void __init smdkc100_machine_init(void)
samsung_keypad_set_platdata(&smdkc100_keypad_data);
s5pc100_spdif_setup_gpio(S5PC100_SPDIF_GPD);
/* LCD init */
gpio_request(S5PC100_GPD(0), "GPD");
gpio_request(S5PC100_GPH0(6), "GPH0");
......
......@@ -22,27 +22,15 @@
#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;
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);
}
s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
}
for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
void s5pc100_fb_gpio_setup_24bpp(void)
{
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 */
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PC100_GPD(3), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
......@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PC100_GPD(5), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
......@@ -17,52 +17,39 @@
#include <mach/regs-clock.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)
{
u32 reg;
u32 gpio = 0;
/* Independent CF interface, CF chip select configuration */
reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f);
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 */
for (gpio = S5PC100_GPJ0(0); gpio <= S5PC100_GPJ0(7); gpio++) {
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);
}
s5pc100_ide_cfg_gpios(S5PC100_GPJ0(0), 8);
/*CF_Data[0 - 7] */
for (gpio = S5PC100_GPJ2(0); gpio <= S5PC100_GPJ2(7); gpio++) {
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);
}
s5pc100_ide_cfg_gpios(S5PC100_GPJ2(0), 8);
/* CF_Data[8 - 15] */
for (gpio = S5PC100_GPJ3(0); gpio <= S5PC100_GPJ3(7); gpio++) {
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);
}
s5pc100_ide_cfg_gpios(S5PC100_GPJ3(0), 8);
/* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
for (gpio = S5PC100_GPJ4(0); gpio <= S5PC100_GPJ4(3); gpio++) {
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);
}
s5pc100_ide_cfg_gpios(S5PC100_GPJ4(0), 4);
/* EBI_OE, EBI_WE */
for (gpio = S5PC100_GPK0(6); gpio <= S5PC100_GPK0(7); gpio++)
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0));
s3c_gpio_cfgpin_range(S5PC100_GPK0(6), 2, S3C_GPIO_SFN(0));
/* CF_OE, CF_WE */
for (gpio = S5PC100_GPK1(6); gpio <= S5PC100_GPK1(7); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PC100_GPK1(6), 8, S3C_GPIO_SFN(2));
/* CF_CD */
s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2));
......
......@@ -15,20 +15,9 @@
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] */
end = S5PC100_GPH3(rows);
for (gpio = S5PC100_GPH3(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PC100_GPH3(0), rows, S3C_GPIO_SFN(3));
/* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
end = S5PC100_GPH2(cols);
for (gpio = S5PC100_GPH2(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PC100_GPH2(0), cols, S3C_GPIO_SFN(3));
}
......@@ -25,8 +25,6 @@
void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
unsigned int num;
num = width;
......@@ -34,20 +32,11 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
if (width == 8)
num = width - 2;
end = S5PC100_GPG0(2 + num);
/* Set all the necessary GPG0/GPG1 pins to special-function 0 */
for (gpio = S5PC100_GPG0(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PC100_GPG0(0), 2 + num, S3C_GPIO_SFN(2));
if (width == 8) {
for (gpio = S5PC100_GPG1(0); gpio <= S5PC100_GPG1(1); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
}
if (width == 8)
s3c_gpio_cfgrange_nopull(S5PC100_GPG1(0), 2, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
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)
void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
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 */
for (gpio = S5PC100_GPG2(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PC100_GPG2(0), 2 + width, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
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)
void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
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 */
for (gpio = S5PC100_GPG3(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PC100_GPG3(0), 2 + width, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
......
......@@ -11,9 +11,9 @@ if ARCH_S5PV210
config CPU_S5PV210
bool
select PLAT_S5P
select S3C_PL330_DMA
select S5P_EXT_INT
select S5PV210_PM if PM
help
Enable S5PV210 CPU support
......@@ -58,7 +58,6 @@ menu "S5PC110 Machines"
config MACH_AQUILA
bool "Aquila"
select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_FB
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
......@@ -75,7 +74,7 @@ config MACH_AQUILA
config MACH_GONI
bool "GONI"
select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S5P_GPIO_INT
select S3C_DEV_FB
select S5P_DEV_FIMC0
select S5P_DEV_FIMC1
......@@ -83,8 +82,15 @@ config MACH_GONI
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
select S3C_DEV_I2C1
select S3C_DEV_I2C2
select S3C_DEV_USB_HSOTG
select S5P_DEV_ONENAND
select SAMSUNG_DEV_KEYPAD
select S5PV210_SETUP_FB_24BPP
select S5PV210_SETUP_I2C1
select S5PV210_SETUP_I2C2
select S5PV210_SETUP_KEYPAD
select S5PV210_SETUP_SDHCI
help
Machine support for Samsung GONI board
......@@ -93,7 +99,6 @@ config MACH_GONI
config MACH_SMDKC110
bool "SMDKC110"
select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_I2C1
select S3C_DEV_I2C2
select S3C_DEV_RTC
......@@ -113,7 +118,6 @@ menu "S5PV210 Machines"
config MACH_SMDKV210
bool "SMDKV210"
select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
......@@ -134,6 +138,29 @@ config MACH_SMDKV210
help
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
config S5PV210_PM
bool
help
Power Management code common to S5PV210
endif
......@@ -14,6 +14,8 @@ obj- :=
obj-$(CONFIG_CPU_S5PV210) += cpu.o init.o clock.o dma.o gpiolib.o
obj-$(CONFIG_CPU_S5PV210) += setup-i2c0.o
obj-$(CONFIG_S5PV210_PM) += pm.o sleep.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
# machine support
......@@ -21,6 +23,7 @@ obj-$(CONFIG_MACH_AQUILA) += mach-aquila.o
obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o
obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o
obj-$(CONFIG_MACH_GONI) += mach-goni.o
obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o
# device support
......
......@@ -31,6 +31,8 @@
#include <plat/clock-clksrc.h>
#include <plat/s5pv210.h>
static unsigned long xtal;
static struct clksrc_clk clk_mout_apll = {
.clk = {
.name = "mout_apll",
......@@ -259,6 +261,36 @@ static struct clksrc_clk clk_sclk_vpll = {
.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)
{
return clk_get_rate(clk->parent) / 2;
......@@ -268,8 +300,29 @@ static struct clk_ops clk_hclk_imem_ops = {
.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[] = {
{
.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",
.id = -1,
.parent = &clk_hclk_dsys.clk,
......@@ -431,6 +484,12 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_p,
.enable = s5pv210_clk_ip3_ctrl,
.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 = {
.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[] = {
[0] = &clk_ext_xtal_mux,
[1] = &clk_xusbxti,
......@@ -743,15 +849,6 @@ static struct clksrc_clk clksrcs[] = {
},
.sources = &clkset_sclk_mixer,
.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 = {
.name = "sclk_fimc",
......@@ -953,12 +1050,93 @@ static struct clksrc_clk *sysclks[] = {
&clk_sclk_dac,
&clk_sclk_pixel,
&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)
{
struct clk *xtal_clk;
unsigned long xtal;
unsigned long vpllsrc;
unsigned long armclk;
unsigned long hclk_msys;
......@@ -974,6 +1152,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
unsigned int ptr;
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__);
clkdiv0 = __raw_readl(S5P_CLK_DIV0);
......@@ -992,11 +1174,12 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
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);
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_epll.rate = epll;
clk_fout_vpll.rate = vpll;
......
......@@ -85,6 +85,21 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S5PV210_PA_SROMC),
.length = SZ_4K,
.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)
/* configure GPIO for i2s port */
switch (pdev->id) {
case 1:
s3c_gpio_cfgpin(S5PV210_GPC0(0), 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));
s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
break;
case 2:
s3c_gpio_cfgpin(S5PV210_GPC1(0), 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));
s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4));
break;
case -1:
s3c_gpio_cfgpin(S5PV210_GPI(0), 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));
s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
break;
default:
......@@ -151,25 +137,13 @@ static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
{
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5PV210_GPI(0), 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));
s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3));
break;
case 1:
s3c_gpio_cfgpin(S5PV210_GPC0(0), 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));
s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3));
break;
case 2:
s3c_gpio_cfgpin(S5PV210_GPC1(0), 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));
s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2));
break;
default:
printk(KERN_DEBUG "Invalid PCM Controller number!");
......@@ -271,13 +245,7 @@ struct platform_device s5pv210_device_pcm2 = {
static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
{
s3c_gpio_cfgpin(S5PV210_GPC0(0), 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;
return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4));
}
static struct resource s5pv210_ac97_resource[] = {
......@@ -325,3 +293,43 @@ struct platform_device s5pv210_device_ac97 = {
.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[] = {
*/
static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
{
unsigned int base;
switch (pdev->id) {
case 0:
s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2));
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);
base = S5PV210_GPB(0);
break;
case 1:
s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2));
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);
base = S5PV210_GPB(4);
break;
default:
......@@ -59,6 +51,9 @@ static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
return -EINVAL;
}
s3c_gpio_cfgall_range(base, 3,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
return 0;
}
......
......@@ -82,7 +82,7 @@ static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
static struct platform_device s5pv210_device_pdma0 = {
.name = "s3c-pl330",
.id = 1,
.id = 0,
.num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
.resource = s5pv210_pdma0_resource,
.dev = {
......@@ -144,7 +144,7 @@ static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
static struct platform_device s5pv210_device_pdma1 = {
.name = "s3c-pl330",
.id = 2,
.id = 1,
.num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
.resource = s5pv210_pdma1_resource,
.dev = {
......
......@@ -150,6 +150,7 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
.label = "GPG3",
},
}, {
.config = &gpio_cfg_noint,
.chip = {
.base = S5PV210_GPI(0),
.ngpio = S5PV210_GPIO_I_NR,
......@@ -223,34 +224,42 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
}, {
.base = (S5P_VA_GPIO + 0xC00),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(0),
.chip = {
.base = S5PV210_GPH0(0),
.ngpio = S5PV210_GPIO_H0_NR,
.label = "GPH0",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC20),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(8),
.chip = {
.base = S5PV210_GPH1(0),
.ngpio = S5PV210_GPIO_H1_NR,
.label = "GPH1",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC40),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(16),
.chip = {
.base = S5PV210_GPH2(0),
.ngpio = S5PV210_GPIO_H2_NR,
.label = "GPH2",
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = (S5P_VA_GPIO + 0xC60),
.config = &gpio_cfg_noint,
.irq_base = IRQ_EINT(24),
.chip = {
.base = S5PV210_GPH3(0),
.ngpio = S5PV210_GPIO_H3_NR,
.label = "GPH3",
.to_irq = samsung_gpiolib_to_irq,
},
},
};
......@@ -259,11 +268,14 @@ static __init int s5pv210_gpiolib_init(void)
{
struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
int gpioint_group = 0;
int i = 0;
for (i = 0; i < nr_chips; i++, chip++) {
if (chip->config == NULL)
if (chip->config == NULL) {
chip->config = &gpio_cfg;
chip->group = gpioint_group++;
}
if (chip->base == NULL)
chip->base = S5PV210_BANK_BASE(i);
}
......
......@@ -55,8 +55,8 @@
#define IRQ_SPI1 S5P_IRQ_VIC1(16)
#define IRQ_SPI2 S5P_IRQ_VIC1(17)
#define IRQ_IRDA S5P_IRQ_VIC1(18)
#define IRQ_CAN0 S5P_IRQ_VIC1(19)
#define IRQ_CAN1 S5P_IRQ_VIC1(20)
#define IRQ_IIC2 S5P_IRQ_VIC1(19)
#define IRQ_IIC3 S5P_IRQ_VIC1(20)
#define IRQ_HSIRX S5P_IRQ_VIC1(21)
#define IRQ_HSITX S5P_IRQ_VIC1(22)
#define IRQ_UHOST S5P_IRQ_VIC1(23)
......@@ -109,7 +109,7 @@
#define IRQ_IPC S5P_IRQ_VIC3(0)
#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_TSI S5P_IRQ_VIC3(4)
#define IRQ_MDNIE0 S5P_IRQ_VIC3(5)
......@@ -121,8 +121,12 @@
#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
#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 */
#define NR_IRQS (IRQ_EINT(31) + 1)
#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
/* Compatibility */
#define IRQ_LCD_FIFO IRQ_LCD0
......
......@@ -57,6 +57,8 @@
#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_CFCON (0xE8200000)
......@@ -73,6 +75,9 @@
#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_VIC1 (0xF2100000)
#define S5PV210_PA_VIC2 (0xF2200000)
......@@ -81,6 +86,9 @@
#define S5PV210_PA_SDRAM (0x20000000)
#define S5P_PA_SDRAM S5PV210_PA_SDRAM
/* S/PDIF */
#define S5PV210_PA_SPDIF 0xE1100000
/* I2S */
#define S5PV210_PA_IIS0 0xEEE30000
#define S5PV210_PA_IIS1 0xE2100000
......@@ -96,6 +104,9 @@
#define S5PV210_PA_ADC (0xE1700000)
#define S5PV210_PA_DMC0 (0xF0000000)
#define S5PV210_PA_DMC1 (0xF1400000)
/* compatibiltiy defines. */
#define S3C_PA_UART S5PV210_PA_UART
#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0)
......@@ -108,6 +119,7 @@
#define S3C_PA_FB S5PV210_PA_FB
#define S3C_PA_RTC S5PV210_PA_RTC
#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_FIMC1 S5PV210_PA_FIMC1
#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 @@
#define S5P_APLL_CON S5P_CLKREG(0x100)
#define S5P_MPLL_CON S5P_CLKREG(0x108)
#define S5P_EPLL_CON S5P_CLKREG(0x110)
#define S5P_EPLL_CON1 S5P_CLKREG(0x114)
#define S5P_VPLL_CON S5P_CLKREG(0x120)
#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
......@@ -67,11 +68,28 @@
#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488)
#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 */
#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_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 */
#define S5P_CLKDIV0_APLL_SHIFT (0)
#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
......@@ -90,8 +108,20 @@
#define S5P_CLKDIV0_PCLK66_SHIFT (28)
#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_ARM_MCS_CON S5P_CLKREG(0x6100)
/* Registers related to power management */
#define S5P_PWR_CFG S5P_CLKREG(0xC000)
#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004)
......@@ -159,8 +189,11 @@
#define S5P_SLEEP_CFG_USBOSC_EN (1 << 1)
/* 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_MIPI_DPHY_EN (1 << 28)
/* MIPI */
#define S5P_MIPI_DPHY_EN (3)
......
......@@ -31,13 +31,6 @@
#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_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 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H __FILE__
#define VMALLOC_END (0xE0000000UL)
#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
......@@ -16,6 +16,8 @@
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/mfd/max8998.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/regulator/fixed.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/gpio.h>
......@@ -379,6 +381,119 @@ static struct max8998_platform_data aquila_max8998_pdata = {
};
#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 */
#define AP_I2C_GPIO_PMIC_BUS_4 4
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 = {
#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 */
static struct gpio_keys_button aquila_gpio_keys_table[] = {
{
......@@ -475,6 +613,7 @@ static void aquila_setup_sdhci(void)
static struct platform_device *aquila_devices[] __initdata = {
&aquila_i2c_gpio_pmic,
&aquila_i2c_gpio5,
&aquila_device_gpiokeys,
&s3c_device_fb,
&s5p_device_onenand,
......@@ -484,8 +623,33 @@ static struct platform_device *aquila_devices[] __initdata = {
&s5p_device_fimc0,
&s5p_device_fimc1,
&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)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
......@@ -506,6 +670,11 @@ static void __init aquila_machine_init(void)
s3c_fimc_setname(1, "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 */
s3c_fb_set_platdata(&aquila_lcd_pdata);
......
......@@ -15,7 +15,13 @@
#include <linux/fb.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/i2c/qt602240_ts.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/input.h>
#include <linux/gpio.h>
......@@ -35,7 +41,10 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/fb.h>
#include <plat/iic.h>
#include <plat/keypad.h>
#include <plat/sdhci.h>
#include <plat/clock.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
......@@ -87,13 +96,12 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
/* Frame Buffer */
static struct s3c_fb_pd_win goni_fb_win0 = {
.win_mode = {
.pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55),
.left_margin = 16,
.right_margin = 16,
.upper_margin = 3,
.upper_margin = 2,
.lower_margin = 28,
.hsync_len = 2,
.vsync_len = 2,
.vsync_len = 1,
.xres = 480,
.yres = 800,
.refresh = 55,
......@@ -111,9 +119,160 @@ static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
.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 */
#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 = {
.constraints = {
.name = "VALIVE_1.1V",
......@@ -153,6 +312,8 @@ static struct regulator_init_data goni_ldo5_data = {
.max_uV = 2800000,
.apply_uV = 1,
},
.num_consumer_supplies = ARRAY_SIZE(goni_ldo5_consumers),
.consumer_supplies = goni_ldo5_consumers,
};
static struct regulator_init_data goni_ldo6_data = {
......@@ -360,6 +521,119 @@ static struct max8998_platform_data goni_max8998_pdata = {
};
#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 */
#define AP_I2C_GPIO_PMIC_BUS_4 4
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 = {
#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 */
static struct gpio_keys_button goni_gpio_keys_table[] = {
{
......@@ -444,11 +741,37 @@ static struct s3c_sdhci_platdata goni_hsmmc2_data __initdata = {
.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)
{
gpio_request(GONI_EXT_FLASH_EN, "FLASH_EN");
gpio_direction_output(GONI_EXT_FLASH_EN, 1);
s3c_sdhci0_set_platdata(&goni_hsmmc0_data);
s3c_sdhci1_set_platdata(&goni_hsmmc1_data);
s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
......@@ -457,7 +780,10 @@ static void goni_setup_sdhci(void)
static struct platform_device *goni_devices[] __initdata = {
&s3c_device_fb,
&s5p_device_onenand,
&goni_spi_gpio,
&goni_i2c_gpio_pmic,
&goni_i2c_gpio5,
&mmc2_fixed_voltage,
&goni_device_gpiokeys,
&s5p_device_fimc0,
&s5p_device_fimc1,
......@@ -465,8 +791,24 @@ static struct platform_device *goni_devices[] __initdata = {
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&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)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
......@@ -476,6 +818,20 @@ static void __init goni_map_io(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 */
goni_pmic_init();
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)
/* 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 */
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));
}
......
......@@ -28,6 +28,7 @@
#include <plat/cpu.h>
#include <plat/ata.h>
#include <plat/iic.h>
#include <plat/pm.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
......@@ -81,6 +82,7 @@ static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
static struct platform_device *smdkc110_devices[] __initdata = {
&s5pv210_device_iis0,
&s5pv210_device_ac97,
&s5pv210_device_spdif,
&s3c_device_cfcon,
&s3c_device_i2c0,
&s3c_device_i2c1,
......@@ -110,6 +112,8 @@ static void __init smdkc110_map_io(void)
static void __init smdkc110_machine_init(void)
{
s3c_pm_init();
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
s3c_i2c2_set_platdata(NULL);
......
......@@ -31,6 +31,7 @@
#include <plat/ata.h>
#include <plat/iic.h>
#include <plat/keypad.h>
#include <plat/pm.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
......@@ -103,6 +104,7 @@ static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
static struct platform_device *smdkv210_devices[] __initdata = {
&s5pv210_device_iis0,
&s5pv210_device_ac97,
&s5pv210_device_spdif,
&s3c_device_adc,
&s3c_device_cfcon,
&s3c_device_hsmmc0,
......@@ -145,6 +147,8 @@ static void __init smdkv210_map_io(void)
static void __init smdkv210_machine_init(void)
{
s3c_pm_init();
samsung_keypad_set_platdata(&smdkv210_keypad_data);
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 @@
#include <mach/regs-clock.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;
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);
}
s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
for (gpio = S5PV210_GPF1(0); gpio <= S5PV210_GPF1(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 (; nr > 0; nr--, base++)
s5p_gpio_set_drvstr(base, 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++) {
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);
}
void s5pv210_fb_gpio_setup_24bpp(void)
{
s5pv210_fb_cfg_gpios(S5PV210_GPF0(0), 8);
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.
*
......
......@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PV210_GPD1(0), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPD1(0), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV210_GPD1(1), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPD1(1), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
......@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PV210_GPD1(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPD1(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);
s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
......@@ -23,8 +23,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c2_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PV210_GPD1(4), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPD1(4), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV210_GPD1(5), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV210_GPD1(5), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
......@@ -15,36 +15,25 @@
#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)
{
unsigned int gpio = 0;
for (gpio = S5PV210_GPJ0(0); gpio <= S5PV210_GPJ0(7); gpio++) {
/* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST,
CF_DMACK */
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_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
s5pv210_ide_cfg_gpios(S5PV210_GPJ0(0), 8);
/* CF_Data[0 - 7] */
s5pv210_ide_cfg_gpios(S5PV210_GPJ2(0), 8);
/* CF_Data[8 - 15] */
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);
}
s5pv210_ide_cfg_gpios(S5PV210_GPJ3(0), 8);
for (gpio = S5PV210_GPJ4(0); gpio <= S5PV210_GPJ4(3); gpio++) {
/* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
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);
}
s5pv210_ide_cfg_gpios(S5PV210_GPJ4(0), 4);
}
......@@ -16,19 +16,9 @@
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] */
end = S5PV210_GPH3(rows);
for (gpio = S5PV210_GPH3(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPH3(0), rows, S3C_GPIO_SFN(3));
/* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
end = S5PV210_GPH2(cols);
for (gpio = S5PV210_GPH2(0); gpio < end; gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPH2(0), cols, S3C_GPIO_SFN(3));
}
......@@ -26,26 +26,17 @@
void s5pv210_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 GPG0/GPG1 pins to special-function 2 */
for (gpio = S5PV210_GPG0(0); gpio < S5PV210_GPG0(2); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2));
switch (width) {
case 8:
/* GPG1[3:6] special-funtion 3 */
for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3));
case 4:
/* GPG0[3:6] special-funtion 2 */
for (gpio = S5PV210_GPG0(3); gpio <= S5PV210_GPG0(6); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2));
default:
break;
}
......@@ -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)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG1[0:1] pins to special-function 2 */
for (gpio = S5PV210_GPG1(0); gpio < S5PV210_GPG1(2); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2));
/* Data pin GPG1[3:6] to special-function 2 */
for (gpio = S5PV210_GPG1(3); gpio <= S5PV210_GPG1(6); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
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)
void s5pv210_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 GPG2[0:1] pins to special-function 2 */
for (gpio = S5PV210_GPG2(0); gpio < S5PV210_GPG2(2); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2));
switch (width) {
case 8:
/* Data pin GPG3[3:6] to special-function 3 */
for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(3));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3));
case 4:
/* Data pin GPG2[3:6] to special-function 2 */
for (gpio = S5PV210_GPG2(3); gpio <= S5PV210_GPG2(6); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2));
default:
break;
}
......@@ -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)
{
struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG3[0:2] pins to special-function 2 */
for (gpio = S5PV210_GPG3(0); gpio < S5PV210_GPG3(2); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
/* Set all the necessary GPG3[0:1] pins to special-function 2 */
s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2));
/* Data pin GPG3[3:6] to special-function 2 */
for (gpio = S5PV210_GPG3(3); gpio <= S5PV210_GPG3(6); gpio++) {
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2));
if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
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
config CPU_S5PV310
bool
select PLAT_S5P
help
Enable S5PV310 CPU support
......@@ -25,21 +24,105 @@ config S5PV310_SETUP_I2C2
help
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
config MACH_SMDKV310
bool "SMDKV310"
menu "S5PC210 Machines"
config MACH_SMDKC210
bool "SMDKC210"
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
Machine support for Samsung SMDKV310
Machine support for Samsung SMDKC210
S5PC210(MCP) is one of package option of S5PV310
config MACH_UNIVERSAL_C210
bool "Mobile UNIVERSAL_C210 Board"
select CPU_S5PV310
select ARCH_SPARSEMEM_ENABLE
select S5P_DEV_ONENAND
select S3C_DEV_I2C1
select S5PV310_SETUP_I2C1
help
Machine support for Samsung Mobile Universal S5PC210 Reference
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
......@@ -13,7 +13,7 @@ obj- :=
# Core support for S5PV310 system
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_LOCAL_TIMERS) += localtimer.o
......@@ -21,6 +21,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
# machine support
obj-$(CONFIG_MACH_SMDKC210) += mach-smdkc210.o
obj-$(CONFIG_MACH_SMDKV310) += mach-smdkv310.o
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_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 = {
.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)
{
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)
{
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 */
static struct clksrc_clk clk_mout_apll = {
......@@ -79,7 +155,7 @@ static struct clksrc_clk clk_mout_mpll = {
};
static struct clk *clkset_moutcore_list[] = {
[0] = &clk_sclk_apll.clk,
[0] = &clk_mout_apll.clk,
[1] = &clk_mout_mpll.clk,
};
......@@ -150,24 +226,6 @@ static struct clksrc_clk clk_periphclk = {
.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 */
static struct clk *clkset_corebus_list[] = {
......@@ -241,7 +299,7 @@ static struct clk *clkset_aclk_top_list[] = {
[1] = &clk_sclk_apll.clk,
};
static struct clksrc_sources clkset_aclk_200 = {
static struct clksrc_sources clkset_aclk = {
.sources = clkset_aclk_top_list,
.nr_sources = ARRAY_SIZE(clkset_aclk_top_list),
};
......@@ -251,52 +309,37 @@ static struct clksrc_clk clk_aclk_200 = {
.name = "aclk_200",
.id = -1,
},
.sources = &clkset_aclk_200,
.sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 12, .size = 1 },
.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 = {
.clk = {
.name = "aclk_100",
.id = -1,
},
.sources = &clkset_aclk_100,
.sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 16, .size = 1 },
.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 = {
.clk = {
.name = "aclk_160",
.id = -1,
},
.sources = &clkset_aclk_160,
.sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 20, .size = 1 },
.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 = {
.clk = {
.name = "aclk_133",
.id = -1,
},
.sources = &clkset_aclk_133,
.sources = &clkset_aclk,
.reg_src = { .reg = S5P_CLKSRC_TOP0, .shift = 24, .size = 1 },
.reg_div = { .reg = S5P_CLKDIV_TOP, .shift = 12, .size = 3 },
};
......@@ -315,6 +358,8 @@ static struct clksrc_clk clk_vpllsrc = {
.clk = {
.name = "vpll_src",
.id = -1,
.enable = s5pv310_clksrc_mask_top_ctrl,
.ctrlbit = (1 << 0),
},
.sources = &clkset_vpllsrc,
.reg_src = { .reg = S5P_CLKSRC_TOP1, .shift = 0, .size = 1 },
......@@ -346,7 +391,175 @@ static struct clk init_clocks_disable[] = {
.parent = &clk_aclk_100.clk,
.enable = s5pv310_clk_ip_peril_ctrl,
.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[] = {
......@@ -387,6 +600,9 @@ static struct clk *clkset_group_list[] = {
[0] = &clk_ext_xtal_mux,
[1] = &clk_xusbxti,
[2] = &clk_sclk_hdmi27m,
[3] = &clk_sclk_usbphy0,
[4] = &clk_sclk_usbphy1,
[5] = &clk_sclk_hdmiphy,
[6] = &clk_mout_mpll.clk,
[7] = &clk_mout_epll.clk,
[8] = &clk_sclk_vpll.clk,
......@@ -397,6 +613,104 @@ static struct clksrc_sources clkset_group = {
.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[] = {
{
.clk = {
......@@ -448,7 +762,200 @@ static struct clksrc_clk clksrcs[] = {
.sources = &clkset_group,
.reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 24, .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 */
......@@ -464,8 +971,6 @@ static struct clksrc_clk *sysclks[] = {
&clk_aclk_cores,
&clk_aclk_corem1,
&clk_periphclk,
&clk_atclk,
&clk_pclk_dbg,
&clk_mout_corebus,
&clk_sclk_dmc,
&clk_aclk_cored,
......@@ -478,6 +983,11 @@ static struct clksrc_clk *sysclks[] = {
&clk_aclk_100,
&clk_aclk_160,
&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)
......@@ -490,15 +1000,11 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
unsigned long vpllsrc;
unsigned long xtal;
unsigned long armclk;
unsigned long aclk_corem0;
unsigned long aclk_cores;
unsigned long aclk_corem1;
unsigned long periphclk;
unsigned long sclk_dmc;
unsigned long aclk_cored;
unsigned long aclk_corep;
unsigned long aclk_acp;
unsigned long pclk_acp;
unsigned long aclk_200;
unsigned long aclk_100;
unsigned long aclk_160;
unsigned long aclk_133;
unsigned int ptr;
printk(KERN_DEBUG "%s: registering clocks\n", __func__);
......@@ -529,26 +1035,21 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
apll, mpll, epll, vpll);
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);
aclk_cored = clk_get_rate(&clk_aclk_cored.clk);
aclk_corep = clk_get_rate(&clk_aclk_corep.clk);
aclk_acp = clk_get_rate(&clk_aclk_acp.clk);
pclk_acp = clk_get_rate(&clk_pclk_acp.clk);
printk(KERN_INFO "S5PV310: ARMCLK=%ld, COREM0=%ld, CORES=%ld\n"
"COREM1=%ld, PERI=%ld, DMC=%ld, CORED=%ld\n"
"COREP=%ld, ACLK_ACP=%ld, PCLK_ACP=%ld",
armclk, aclk_corem0, aclk_cores, aclk_corem1,
periphclk, sclk_dmc, aclk_cored, aclk_corep,
aclk_acp, pclk_acp);
aclk_200 = clk_get_rate(&clk_aclk_200.clk);
aclk_100 = clk_get_rate(&clk_aclk_100.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, DMC=%ld, ACLK200=%ld\n"
"ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
armclk, sclk_dmc, aclk_200,
aclk_100, aclk_160, aclk_133);
clk_f.rate = armclk;
clk_h.rate = sclk_dmc;
clk_p.rate = periphclk;
clk_p.rate = aclk_100;
for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
s3c_set_clksrc(&clksrcs[ptr], true);
......
......@@ -15,10 +15,12 @@
#include <asm/mach/irq.h>
#include <asm/proc-fns.h>
#include <asm/hardware/cache-l2x0.h>
#include <plat/cpu.h>
#include <plat/clock.h>
#include <plat/s5pv310.h>
#include <plat/sdhci.h>
#include <mach/regs-irq.h>
......@@ -56,15 +58,30 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S5P_VA_GPIO,
.virtual = (unsigned long)S5P_VA_GPIO1,
.pfn = __phys_to_pfn(S5PV310_PA_GPIO1),
.length = SZ_4K,
.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,
.pfn = __phys_to_pfn(S3C_PA_UART),
.length = SZ_512K,
.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)
void __init s5pv310_map_io(void)
{
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)
......@@ -131,6 +154,28 @@ static int __init s5pv310_core_init(void)
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)
{
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 @@
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* S5PV210 - IRQ definitions
* S5PV310 - IRQ 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
......@@ -60,6 +60,9 @@
#define IRQ_TIMER3_VIC COMBINER_IRQ(22, 3)
#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_UART1 COMBINER_IRQ(26, 1)
#define IRQ_UART2 COMBINER_IRQ(26, 2)
......@@ -67,13 +70,46 @@
#define IRQ_UART4 COMBINER_IRQ(26, 4)
#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)
/* 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 */
......@@ -25,6 +25,8 @@
#define S5PV310_PA_SYSRAM (0x02025000)
#define S5PV310_PA_SROM_BANK(x) (0x04000000 + ((x) * 0x01000000))
#define S5PC210_PA_ONENAND (0x0C000000)
#define S5P_PA_ONENAND S5PC210_PA_ONENAND
......@@ -34,12 +36,13 @@
#define S5PV310_PA_CHIPID (0x10000000)
#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 S5PV310_PA_CMU (0x10030000)
#define S5PV310_PA_WATCHDOG (0x10060000)
#define S5PV310_PA_RTC (0x10070000)
#define S5PV310_PA_COMBINER (0x10448000)
......@@ -55,6 +58,8 @@
#define S5PV310_PA_HSMMC(x) (0x12510000 + ((x) * 0x10000))
#define S5PV310_PA_SROMC (0x12570000)
#define S5PV310_PA_UART (0x13800000)
#define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET))
......@@ -66,7 +71,7 @@
#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 S5P_PA_TIMER S5PV310_PA_TIMER
......@@ -80,7 +85,15 @@
#define S3C_PA_HSMMC1 S5PV310_PA_HSMMC(1)
#define S3C_PA_HSMMC2 S5PV310_PA_HSMMC(2)
#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
#endif /* __ASM_ARCH_MAP_H */
......@@ -26,11 +26,23 @@
#define S5P_CLKSRC_TOP0 S5P_CLKREG(0x0C210)
#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_PERIL1 S5P_CLKREG(0x0C254)
#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_PERIL1 S5P_CLKREG(0x0C554)
#define S5P_CLKDIV_PERIL2 S5P_CLKREG(0x0C558)
......@@ -38,9 +50,21 @@
#define S5P_CLKDIV_PERIL4 S5P_CLKREG(0x0C560)
#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_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_PERIR S5P_CLKREG(0x0C960)
#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200)
#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500)
......@@ -60,4 +84,8 @@
#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
/* Compatibility defines */
#define S5P_EPLL_CON S5P_EPLL_CON0
#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 @@
#ifndef __ASM_ARCH_VMALLOC_H
#define __ASM_ARCH_VMALLOC_H __FILE__
#define VMALLOC_END (0xF0000000UL)
#define VMALLOC_END 0xF6000000UL
#endif /* __ASM_ARCH_VMALLOC_H */
......@@ -66,11 +66,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
if (status == 0)
goto out;
for (combiner_irq = 0; combiner_irq < 32; combiner_irq++) {
if (status & 0x1)
break;
status >>= 1;
}
combiner_irq = __ffs(status);
cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
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 @@
*/
#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 <asm/hardware/cache-l2x0.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 SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
......@@ -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)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
......@@ -74,9 +182,14 @@ static void __init smdkv310_map_io(void)
static void __init smdkv310_machine_init(void)
{
#ifdef CONFIG_CACHE_L2X0
l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
#endif
smdkv310_smsc911x_init();
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")
......
......@@ -7,15 +7,20 @@
* published by the Free Software Foundation.
*/
#include <linux/platform_device.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-types.h>
#include <asm/hardware/cache-l2x0.h>
#include <plat/regs-serial.h>
#include <plat/s5pv310.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <mach/map.h>
......@@ -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)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
......@@ -69,9 +140,11 @@ static void __init universal_map_io(void)
static void __init universal_machine_init(void)
{
#ifdef CONFIG_CACHE_L2X0
l2x0_init(S5P_VA_L2CC, 1 << 28, 0xffffffff);
#endif
i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
/* Last */
platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
}
MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
......
......@@ -21,8 +21,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PV310_GPD1(0), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPD1(0), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV310_GPD1(1), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPD1(1), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PV310_GPD1(0), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
......@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PV310_GPD1(2), S3C_GPIO_SFN(2));
s3c_gpio_setpull(S5PV310_GPD1(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);
s3c_gpio_cfgall_range(S5PV310_GPD1(2), 2,
S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
}
......@@ -18,8 +18,6 @@ struct platform_device; /* don't need the contents */
void s3c_i2c2_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S5PV310_GPA0(6), S3C_GPIO_SFN(3));
s3c_gpio_setpull(S5PV310_GPA0(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S5PV310_GPA0(7), S3C_GPIO_SFN(3));
s3c_gpio_setpull(S5PV310_GPA0(7), S3C_GPIO_PULL_UP);
s3c_gpio_cfgall_range(S5PV310_GPA0(6), 2,
S3C_GPIO_SFN(3), 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[] = {
[7] = {
.name = "S3C2410 flash partition 7",
.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)
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 = {
.set_config = s3c_gpio_setcfg_s3c24xx_a,
.get_config = s3c_gpio_getcfg_s3c24xx_a,
......@@ -157,12 +152,13 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
[6] = {
.base = S3C2410_GPGCON,
.pm = __gpio_pm(&s3c_gpio_pm_2bit),
.irq_base = IRQ_EINT8,
.chip = {
.base = S3C2410_GPG(0),
.owner = THIS_MODULE,
.label = "GPIOG",
.ngpio = 16,
.to_irq = s3c24xx_gpiolib_bankg_toirq,
.to_irq = samsung_gpiolib_to_irq,
},
}, {
.base = S3C2410_GPHCON,
......
......@@ -32,6 +32,11 @@ config S5P_EXT_INT
Use the external interrupts (other than GPIO interrupts.)
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
bool
help
......
......@@ -18,6 +18,9 @@ obj-y += cpu.o
obj-y += clock.o
obj-y += irq.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
......
......@@ -21,6 +21,8 @@
#include <linux/io.h>
#include <asm/div64.h>
#include <mach/regs-clock.h>
#include <plat/clock.h>
#include <plat/clock-clksrc.h>
#include <plat/s5p-clock.h>
......@@ -88,14 +90,6 @@ struct clk clk_fout_vpll = {
.ctrlbit = (1 << 31),
};
/* ARM clock */
struct clk clk_arm = {
.name = "armclk",
.id = -1,
.rate = 0,
.ctrlbit = 0,
};
/* Possible clock sources for APLL Mux */
static struct clk *clk_src_apll_list[] = {
[0] = &clk_fin_apll,
......@@ -156,6 +150,24 @@ int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
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 = {
&clk_ext_xtal_mux,
&clk_48m,
......@@ -165,7 +177,6 @@ static struct clk *s5p_clks[] __initdata = {
&clk_fout_epll,
&clk_fout_dpll,
&clk_fout_vpll,
&clk_arm,
&clk_vpll,
&clk_xusbxti,
};
......
......@@ -94,4 +94,22 @@
((irq) - S5P_EINT_BASE1) : \
((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 */
......@@ -13,24 +13,38 @@
#ifndef __ASM_PLAT_MAP_S5P_H
#define __ASM_PLAT_MAP_S5P_H __FILE__
#define S5P_VA_CHIPID S3C_ADDR(0x00700000)
#define S5P_VA_GPIO S3C_ADDR(0x00500000)
#define S5P_VA_SYSTIMER S3C_ADDR(0x01200000)
#define S5P_VA_SROMC S3C_ADDR(0x01100000)
#define S5P_VA_SYSRAM S3C_ADDR(0x01180000)
#define S5P_VA_COMBINER_BASE S3C_ADDR(0x00600000)
#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
#define S5P_VA_CMU S3C_ADDR(0x02100000)
#define S5P_VA_GPIO S3C_ADDR(0x02200000)
#define S5P_VA_GPIO1 S5P_VA_GPIO
#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
#define S5P_VA_GPIO3 S3C_ADDR(0x02280000)
#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_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_SCU S5P_VA_COREPERI(0x0)
#define S5P_VA_GIC_CPU S5P_VA_COREPERI(0x100)
#define S5P_VA_TWD S5P_VA_COREPERI(0x600)
#define S5P_VA_GIC_DIST S5P_VA_COREPERI(0x1000)
#define S5P_VA_L2CC S3C_ADDR(0x00900000)
#define S5P_VA_CMU S3C_ADDR(0x00920000)
#define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000)
#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_UART0 S5P_VA_UART(0)
......@@ -42,10 +56,4 @@
#define S3C_UART_OFFSET (0x400)
#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 */
......@@ -43,4 +43,8 @@ extern struct clksrc_sources clk_src_dpll;
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 */
......@@ -67,23 +67,23 @@ static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type)
switch (type) {
case IRQ_TYPE_EDGE_RISING:
newvalue = S5P_EXTINT_RISEEDGE;
newvalue = S5P_IRQ_TYPE_EDGE_RISING;
break;
case IRQ_TYPE_EDGE_FALLING:
newvalue = S5P_EXTINT_FALLEDGE;
newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
break;
case IRQ_TYPE_EDGE_BOTH:
newvalue = S5P_EXTINT_BOTHEDGE;
newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
break;
case IRQ_TYPE_LEVEL_LOW:
newvalue = S5P_EXTINT_LOWLEV;
newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
break;
case IRQ_TYPE_LEVEL_HIGH:
newvalue = S5P_EXTINT_HILEV;
newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
break;
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
help
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
bool
help
......
......@@ -40,6 +40,11 @@ obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.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-y += dev-uart.o
obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
......
......@@ -41,6 +41,7 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
.clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc0 = {
......@@ -59,17 +60,20 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
{
struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
set->max_width = pd->max_width;
set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
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 = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
.clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc1 = {
......@@ -59,17 +60,20 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
{
struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
set->max_width = pd->max_width;
set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
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 = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
.clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc2 = {
......@@ -60,17 +61,20 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
{
struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
set->max_width = pd->max_width;
set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
if (pd->cfg_card)
set->cfg_card = pd->cfg_card;
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[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_MMC3,
.end = IRQ_MMC3,
.start = IRQ_HSMMC3,
.end = IRQ_HSMMC3,
.flags = IORESOURCE_IRQ,
}
};
......@@ -45,6 +45,7 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
.max_width = 4,
.host_caps = (MMC_CAP_4_BIT_DATA |
MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
.clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
};
struct platform_device s3c_device_hsmmc3 = {
......@@ -63,15 +64,20 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
{
struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
set->max_width = pd->max_width;
set->cd_type = pd->cd_type;
set->ext_cd_init = pd->ext_cd_init;
set->ext_cd_cleanup = pd->ext_cd_cleanup;
set->ext_cd_gpio = pd->ext_cd_gpio;
set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->max_width)
set->max_width = pd->max_width;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
if (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[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_CAN0,
.end = IRQ_CAN0,
.start = IRQ_IIC2,
.end = IRQ_IIC2,
.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)
}
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)
{
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)
}
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
int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int cfg)
......
......@@ -157,3 +157,11 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
if (ret >= 0)
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 @@
#define S3C64XX_AC97_GPE 1
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
* @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;
extern struct platform_device s3c_device_i2c0;
extern struct platform_device s3c_device_i2c1;
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_adc;
extern struct platform_device s3c_device_sdi;
......@@ -89,6 +94,7 @@ extern struct platform_device s5pv210_device_pcm2;
extern struct platform_device s5pv210_device_iis0;
extern struct platform_device s5pv210_device_iis1;
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_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_iis1;
extern struct platform_device s5pc100_device_iis2;
extern struct platform_device s5pc100_device_spdif;
extern struct platform_device samsung_device_keypad;
......
......@@ -42,6 +42,12 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
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.
* @chip: The gpio chip that is being configured.
......
......@@ -108,6 +108,19 @@ extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
*/
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.
*
* 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);
*/
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.
*
* 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);
*/
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 */
......@@ -43,6 +43,8 @@ struct s3c_gpio_cfg;
* struct s3c_gpio_chip - wrapper for specific implementation of gpio
* @chip: The chip structure to be exported via gpiolib.
* @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.
* @lock: Lock for exclusive access to this gpio bank.
* @pm_save: Save information for suspend/resume support.
......@@ -63,6 +65,8 @@ struct s3c_gpio_chip {
struct s3c_gpio_cfg *config;
struct s3c_gpio_pm *pm;
void __iomem *base;
int irq_base;
int group;
spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[4];
......@@ -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_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 */
extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
......
......@@ -55,10 +55,20 @@ struct s3c2410_platform_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_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 */
extern void s3c_i2c0_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_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 */
......@@ -14,7 +14,7 @@
#ifndef __ASM_PLAT_MAP_H
#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
* better chance of getting memory.
*
......@@ -22,7 +22,7 @@
* an single MOVS instruction (ie, only 8 bits of set data)
*/
#define S3C_ADDR_BASE (0xF4000000)
#define S3C_ADDR_BASE 0xF6000000
#ifndef __ASSEMBLY__
#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 {
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
* @max_width: The maximum number of data bits supported.
* @host_caps: Standard MMC host capabilities bit field.
* @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
* sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
* notify_func argument is a callback to the sdhci-s3c driver
......@@ -59,6 +65,7 @@ struct s3c_sdhci_platdata {
unsigned int max_width;
unsigned int host_caps;
enum cd_types cd_type;
enum clk_types clk_type;
char **clocks; /* set of clock sources */
......@@ -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_sdhci2_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 */
......@@ -288,4 +299,57 @@ static inline void s5pv210_default_sdhci3(void) { }
#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 */
......@@ -192,7 +192,7 @@ struct s3c_gpio_pm s3c_gpio_pm_2bit = {
.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)
{
chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
......@@ -302,7 +302,7 @@ struct s3c_gpio_pm s3c_gpio_pm_4bit = {
.save = s3c_gpio_pm_4bit_save,
.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
......
......@@ -15,6 +15,8 @@
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <asm/hardware/pl330.h>
......@@ -27,6 +29,7 @@
* @node: To attach to the global list of DMACs.
* @pi: PL330 configuration info for the DMAC.
* @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
* @clk: Pointer of DMAC operation clock.
*/
struct s3c_pl330_dmac {
unsigned busy_chan;
......@@ -34,6 +37,7 @@ struct s3c_pl330_dmac {
struct list_head node;
struct pl330_info *pi;
struct kmem_cache *kmcache;
struct clk *clk;
};
/**
......@@ -1072,16 +1076,25 @@ static int pl330_probe(struct platform_device *pdev)
if (ret)
goto probe_err4;
ret = pl330_add(pl330_info);
if (ret)
goto probe_err5;
/* Allocate a new DMAC */
s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
if (!s3c_pl330_dmac) {
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;
}
clk_enable(s3c_pl330_dmac->clk);
ret = pl330_add(pl330_info);
if (ret)
goto probe_err7;
/* Hook the info */
s3c_pl330_dmac->pi = pl330_info;
......@@ -1094,7 +1107,7 @@ static int pl330_probe(struct platform_device *pdev)
if (!s3c_pl330_dmac->kmcache) {
ret = -ENOMEM;
goto probe_err7;
goto probe_err8;
}
/* Get the list of peripherals */
......@@ -1120,10 +1133,13 @@ static int pl330_probe(struct platform_device *pdev)
return 0;
probe_err8:
pl330_del(pl330_info);
probe_err7:
kfree(s3c_pl330_dmac);
clk_disable(s3c_pl330_dmac->clk);
clk_put(s3c_pl330_dmac->clk);
probe_err6:
pl330_del(pl330_info);
kfree(s3c_pl330_dmac);
probe_err5:
free_irq(irq, pl330_info);
probe_err4:
......@@ -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 */
list_del(&dmac->node);
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