add idl4k kernel firmware version 1.13.0.105

This commit is contained in:
Jaroslav Kysela
2015-03-26 17:22:37 +01:00
parent 5194d2792e
commit e9070cdc77
31064 changed files with 12769984 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
# arch/arm/plat-s3c64xx/Kconfig
#
# Copyright 2008 Openmoko, Inc.
# Copyright 2008 Simtec Electronics
# Ben Dooks <ben@simtec.co.uk>
#
# Licensed under GPLv2
config PLAT_S3C64XX
bool
depends on ARCH_S3C64XX
default y
select CPU_V6
select PLAT_S3C
select ARM_VIC
select NO_IOPORT
select ARCH_REQUIRE_GPIOLIB
select S3C_GPIO_TRACK
select S3C_GPIO_PULL_UPDOWN
select S3C_GPIO_CFG_S3C24XX
select S3C_GPIO_CFG_S3C64XX
select S3C_DEV_NAND
select USB_ARCH_HAS_OHCI
help
Base platform code for any Samsung S3C64XX device
if PLAT_S3C64XX
# Configuration options shared by all S3C64XX implementations
config CPU_S3C6400_INIT
bool
help
Common initialisation code for the S3C6400 that is shared
by other CPUs in the series, such as the S3C6410.
config CPU_S3C6400_CLOCK
bool
help
Common clock support code for the S3C6400 that is shared
by other CPUs in the series, such as the S3C6410.
config S3C64XX_DMA
bool "S3C64XX DMA"
select S3C_DMA
# platform specific device setup
config S3C64XX_SETUP_I2C0
bool
default y
help
Common setup code for i2c bus 0.
Note, currently since i2c0 is always compiled, this setup helper
is always compiled with it.
config S3C64XX_SETUP_I2C1
bool
help
Common setup code for i2c bus 1.
config S3C64XX_SETUP_FB_24BPP
bool
help
Common setup code for S3C64XX with an 24bpp RGB display helper.
config S3C64XX_SETUP_SDHCI_GPIO
bool
help
Common setup code for S3C64XX SDHCI GPIO configurations
endif

View File

@@ -0,0 +1,44 @@
# arch/arm/plat-s3c64xx/Makefile
#
# Copyright 2008 Openmoko, Inc.
# Copyright 2008 Simtec Electronics
#
# Licensed under GPLv2
obj-y :=
obj-m :=
obj-n := dummy.o
obj- :=
# Core files
obj-y += dev-uart.o
obj-y += cpu.o
obj-y += irq.o
obj-y += irq-eint.o
obj-y += clock.o
obj-y += gpiolib.o
# CPU support
obj-$(CONFIG_CPU_S3C6400_INIT) += s3c6400-init.o
obj-$(CONFIG_CPU_S3C6400_CLOCK) += s3c6400-clock.o
obj-$(CONFIG_CPU_FREQ_S3C64XX) += cpufreq.o
# PM support
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_PM) += irq-pm.o
# DMA support
obj-$(CONFIG_S3C64XX_DMA) += dma.o
# Device setup
obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o

View File

@@ -0,0 +1,300 @@
/* linux/arch/arm/plat-s3c64xx/clock.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX Base clock 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/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <plat/regs-sys.h>
#include <plat/regs-clock.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/clock.h>
struct clk clk_h2 = {
.name = "hclk2",
.id = -1,
.rate = 0,
};
struct clk clk_27m = {
.name = "clk_27m",
.id = -1,
.rate = 27000000,
};
static int clk_48m_ctrl(struct clk *clk, int enable)
{
unsigned long flags;
u32 val;
/* can't rely on clock lock, this register has other usages */
local_irq_save(flags);
val = __raw_readl(S3C64XX_OTHERS);
if (enable)
val |= S3C64XX_OTHERS_USBMASK;
else
val &= ~S3C64XX_OTHERS_USBMASK;
__raw_writel(val, S3C64XX_OTHERS);
local_irq_restore(flags);
return 0;
}
struct clk clk_48m = {
.name = "clk_48m",
.id = -1,
.rate = 48000000,
.enable = clk_48m_ctrl,
};
static int inline s3c64xx_gate(void __iomem *reg,
struct clk *clk,
int enable)
{
unsigned int ctrlbit = clk->ctrlbit;
u32 con;
con = __raw_readl(reg);
if (enable)
con |= ctrlbit;
else
con &= ~ctrlbit;
__raw_writel(con, reg);
return 0;
}
static int s3c64xx_pclk_ctrl(struct clk *clk, int enable)
{
return s3c64xx_gate(S3C_PCLK_GATE, clk, enable);
}
static int s3c64xx_hclk_ctrl(struct clk *clk, int enable)
{
return s3c64xx_gate(S3C_HCLK_GATE, clk, enable);
}
int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
{
return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
}
static struct clk init_clocks_disable[] = {
{
.name = "nand",
.id = -1,
.parent = &clk_h,
}, {
.name = "adc",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_TSADC,
}, {
.name = "i2c",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_IIC,
}, {
.name = "iis",
.id = 0,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_IIS0,
}, {
.name = "iis",
.id = 1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_IIS1,
}, {
.name = "spi",
.id = 0,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_SPI0,
}, {
.name = "spi",
.id = 1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_SPI1,
}, {
.name = "48m",
.id = 0,
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MMC0_48,
}, {
.name = "48m",
.id = 1,
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MMC1_48,
}, {
.name = "48m",
.id = 2,
.parent = &clk_48m,
.enable = s3c64xx_sclk_ctrl,
.ctrlbit = S3C_CLKCON_SCLK_MMC2_48,
}, {
.name = "dma0",
.id = -1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_DMA0,
}, {
.name = "dma1",
.id = -1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_DMA1,
},
};
static struct clk init_clocks[] = {
{
.name = "lcd",
.id = -1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_LCD,
}, {
.name = "gpio",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_GPIO,
}, {
.name = "usb-host",
.id = -1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_UHOST,
}, {
.name = "hsmmc",
.id = 0,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
}, {
.name = "hsmmc",
.id = 1,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
}, {
.name = "hsmmc",
.id = 2,
.parent = &clk_h,
.enable = s3c64xx_hclk_ctrl,
.ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
}, {
.name = "timers",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_PWM,
}, {
.name = "uart",
.id = 0,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_UART0,
}, {
.name = "uart",
.id = 1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_UART1,
}, {
.name = "uart",
.id = 2,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_UART2,
}, {
.name = "uart",
.id = 3,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_UART3,
}, {
.name = "rtc",
.id = -1,
.parent = &clk_p,
.enable = s3c64xx_pclk_ctrl,
.ctrlbit = S3C_CLKCON_PCLK_RTC,
}, {
.name = "watchdog",
.id = -1,
.parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_WDT,
}, {
.name = "ac97",
.id = -1,
.parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_AC97,
}
};
static struct clk *clks[] __initdata = {
&clk_ext,
&clk_epll,
&clk_27m,
&clk_48m,
&clk_h2,
};
void __init s3c64xx_register_clocks(void)
{
struct clk *clkp;
int ret;
int ptr;
s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
clkp = init_clocks;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
}
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
(clkp->enable)(clkp, 0);
}
s3c_pwmclk_init();
}

View File

@@ -0,0 +1,151 @@
/* linux/arch/arm/plat-s3c64xx/cpu.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX CPU 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/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/sysdev.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <plat/regs-serial.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/clock.h>
#include <plat/s3c6400.h>
#include <plat/s3c6410.h>
/* table of supported CPUs */
static const char name_s3c6400[] = "S3C6400";
static const char name_s3c6410[] = "S3C6410";
static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x36400000,
.idmask = 0xfffff000,
.map_io = s3c6400_map_io,
.init_clocks = s3c6400_init_clocks,
.init_uarts = s3c6400_init_uarts,
.init = s3c6400_init,
.name = name_s3c6400,
}, {
.idcode = 0x36410100,
.idmask = 0xffffff00,
.map_io = s3c6410_map_io,
.init_clocks = s3c6410_init_clocks,
.init_uarts = s3c6410_init_uarts,
.init = s3c6410_init,
.name = name_s3c6410,
},
};
/* minimal IO mapping */
/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */
#define UART_OFFS (S3C_PA_UART & 0xfffff)
static struct map_desc s3c_iodesc[] __initdata = {
{
.virtual = (unsigned long)S3C_VA_SYS,
.pfn = __phys_to_pfn(S3C64XX_PA_SYSCON),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)(S3C_VA_UART + UART_OFFS),
.pfn = __phys_to_pfn(S3C_PA_UART),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_VIC0,
.pfn = __phys_to_pfn(S3C64XX_PA_VIC0),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_VIC1,
.pfn = __phys_to_pfn(S3C64XX_PA_VIC1),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_TIMER,
.pfn = __phys_to_pfn(S3C_PA_TIMER),
.length = SZ_16K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C64XX_VA_GPIO,
.pfn = __phys_to_pfn(S3C64XX_PA_GPIO),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C64XX_VA_MODEM,
.pfn = __phys_to_pfn(S3C64XX_PA_MODEM),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = (unsigned long)S3C_VA_WATCHDOG,
.pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG),
.length = SZ_4K,
.type = MT_DEVICE,
},
};
struct sysdev_class s3c64xx_sysclass = {
.name = "s3c64xx-core",
};
static struct sys_device s3c64xx_sysdev = {
.cls = &s3c64xx_sysclass,
};
/* read cpu identification code */
void __init s3c64xx_init_io(struct map_desc *mach_desc, int size)
{
unsigned long idcode;
/* initialise the io descriptors we need for initialisation */
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
iotable_init(mach_desc, size);
idcode = __raw_readl(S3C_VA_SYS + 0x118);
if (!idcode) {
/* S3C6400 has the ID register in a different place,
* and needs a write before it can be read. */
__raw_writel(0x0, S3C_VA_SYS + 0xA1C);
idcode = __raw_readl(S3C_VA_SYS + 0xA1C);
}
s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
}
static __init int s3c64xx_sysdev_init(void)
{
sysdev_class_register(&s3c64xx_sysclass);
return sysdev_register(&s3c64xx_sysdev);
}
core_initcall(s3c64xx_sysdev_init);

View File

@@ -0,0 +1,262 @@
/* linux/arch/arm/plat-s3c64xx/cpufreq.c
*
* Copyright 2009 Wolfson Microelectronics plc
*
* S3C64xx CPUfreq 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/types.h>
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/regulator/consumer.h>
static struct clk *armclk;
static struct regulator *vddarm;
#ifdef CONFIG_CPU_S3C6410
struct s3c64xx_dvfs {
unsigned int vddarm_min;
unsigned int vddarm_max;
};
static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
[0] = { 1000000, 1000000 },
[1] = { 1000000, 1050000 },
[2] = { 1050000, 1100000 },
[3] = { 1050000, 1150000 },
[4] = { 1250000, 1350000 },
};
static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
{ 0, 66000 },
{ 0, 133000 },
{ 1, 222000 },
{ 1, 266000 },
{ 2, 333000 },
{ 2, 400000 },
{ 3, 532000 },
{ 3, 533000 },
{ 4, 667000 },
{ 0, CPUFREQ_TABLE_END },
};
#endif
static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy)
{
if (policy->cpu != 0)
return -EINVAL;
return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table);
}
static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
{
if (cpu != 0)
return 0;
return clk_get_rate(armclk) / 1000;
}
static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
int ret;
unsigned int i;
struct cpufreq_freqs freqs;
struct s3c64xx_dvfs *dvfs;
ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table,
target_freq, relation, &i);
if (ret != 0)
return ret;
freqs.cpu = 0;
freqs.old = clk_get_rate(armclk) / 1000;
freqs.new = s3c64xx_freq_table[i].frequency;
freqs.flags = 0;
dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].index];
if (freqs.old == freqs.new)
return 0;
pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
#ifdef CONFIG_REGULATOR
if (vddarm && freqs.new > freqs.old) {
ret = regulator_set_voltage(vddarm,
dvfs->vddarm_min,
dvfs->vddarm_max);
if (ret != 0) {
pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
freqs.new, ret);
goto err;
}
}
#endif
ret = clk_set_rate(armclk, freqs.new * 1000);
if (ret < 0) {
pr_err("cpufreq: Failed to set rate %dkHz: %d\n",
freqs.new, ret);
goto err;
}
#ifdef CONFIG_REGULATOR
if (vddarm && freqs.new < freqs.old) {
ret = regulator_set_voltage(vddarm,
dvfs->vddarm_min,
dvfs->vddarm_max);
if (ret != 0) {
pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
freqs.new, ret);
goto err_clk;
}
}
#endif
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
pr_debug("cpufreq: Set actual frequency %lukHz\n",
clk_get_rate(armclk) / 1000);
return 0;
err_clk:
if (clk_set_rate(armclk, freqs.old * 1000) < 0)
pr_err("Failed to restore original clock rate\n");
err:
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return ret;
}
#ifdef CONFIG_REGULATOR
static void __init s3c64xx_cpufreq_constrain_voltages(void)
{
int count, v, i, found;
struct cpufreq_frequency_table *freq;
struct s3c64xx_dvfs *dvfs;
count = regulator_count_voltages(vddarm);
if (count < 0) {
pr_err("cpufreq: Unable to check supported voltages\n");
return;
}
freq = s3c64xx_freq_table;
while (freq->frequency != CPUFREQ_TABLE_END) {
if (freq->frequency == CPUFREQ_ENTRY_INVALID)
continue;
dvfs = &s3c64xx_dvfs_table[freq->index];
found = 0;
for (i = 0; i < count; i++) {
v = regulator_list_voltage(vddarm, i);
if (v >= dvfs->vddarm_min && v <= dvfs->vddarm_max)
found = 1;
}
if (!found) {
pr_debug("cpufreq: %dkHz unsupported by regulator\n",
freq->frequency);
freq->frequency = CPUFREQ_ENTRY_INVALID;
}
freq++;
}
}
#endif
static int __init s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
{
int ret;
struct cpufreq_frequency_table *freq;
if (policy->cpu != 0)
return -EINVAL;
if (s3c64xx_freq_table == NULL) {
pr_err("cpufreq: No frequency information for this CPU\n");
return -ENODEV;
}
armclk = clk_get(NULL, "armclk");
if (IS_ERR(armclk)) {
pr_err("cpufreq: Unable to obtain ARMCLK: %ld\n",
PTR_ERR(armclk));
return PTR_ERR(armclk);
}
#ifdef CONFIG_REGULATOR
vddarm = regulator_get(NULL, "vddarm");
if (IS_ERR(vddarm)) {
ret = PTR_ERR(vddarm);
pr_err("cpufreq: Failed to obtain VDDARM: %d\n", ret);
pr_err("cpufreq: Only frequency scaling available\n");
vddarm = NULL;
} else {
s3c64xx_cpufreq_constrain_voltages();
}
#endif
freq = s3c64xx_freq_table;
while (freq->frequency != CPUFREQ_TABLE_END) {
unsigned long r;
/* Check for frequencies we can generate */
r = clk_round_rate(armclk, freq->frequency * 1000);
r /= 1000;
if (r != freq->frequency)
freq->frequency = CPUFREQ_ENTRY_INVALID;
/* If we have no regulator then assume startup
* frequency is the maximum we can support. */
if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0))
freq->frequency = CPUFREQ_ENTRY_INVALID;
freq++;
}
policy->cur = clk_get_rate(armclk) / 1000;
/* Pick a conservative guess in ns: we'll need ~1 I2C/SPI
* write plus clock reprogramming. */
policy->cpuinfo.transition_latency = 2 * 1000 * 1000;
ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table);
if (ret != 0) {
pr_err("cpufreq: Failed to configure frequency table: %d\n",
ret);
regulator_put(vddarm);
clk_put(armclk);
}
return ret;
}
static struct cpufreq_driver s3c64xx_cpufreq_driver = {
.owner = THIS_MODULE,
.flags = 0,
.verify = s3c64xx_cpufreq_verify_speed,
.target = s3c64xx_cpufreq_set_target,
.get = s3c64xx_cpufreq_get_speed,
.init = s3c64xx_cpufreq_driver_init,
.name = "s3c",
};
static int __init s3c64xx_cpufreq_init(void)
{
return cpufreq_register_driver(&s3c64xx_cpufreq_driver);
}
module_init(s3c64xx_cpufreq_init);

View File

@@ -0,0 +1,68 @@
/* linux/arch/arm/plat-s3c/dev-audio.c
*
* Copyright 2009 Wolfson Microelectronics
* Mark Brown <broonie@opensource.wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include <plat/devs.h>
static struct resource s3c64xx_iis0_resource[] = {
[0] = {
.start = S3C64XX_PA_IIS0,
.end = S3C64XX_PA_IIS0 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device s3c64xx_device_iis0 = {
.name = "s3c64xx-iis",
.id = 0,
.num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
.resource = s3c64xx_iis0_resource,
};
EXPORT_SYMBOL(s3c64xx_device_iis0);
static struct resource s3c64xx_iis1_resource[] = {
[0] = {
.start = S3C64XX_PA_IIS1,
.end = S3C64XX_PA_IIS1 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device s3c64xx_device_iis1 = {
.name = "s3c64xx-iis",
.id = 1,
.num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
.resource = s3c64xx_iis1_resource,
};
EXPORT_SYMBOL(s3c64xx_device_iis1);
static struct resource s3c64xx_iisv4_resource[] = {
[0] = {
.start = S3C64XX_PA_IISV4,
.end = S3C64XX_PA_IISV4 + 0x100 - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device s3c64xx_device_iisv4 = {
.name = "s3c64xx-iis-v4",
.id = -1,
.num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
.resource = s3c64xx_iisv4_resource,
};
EXPORT_SYMBOL(s3c64xx_device_iisv4);

View File

@@ -0,0 +1,176 @@
/* linux/arch/arm/plat-s3c64xx/dev-uart.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Base S3C64XX UART resource and device 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.
*
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <plat/devs.h>
/* Serial port registrations */
/* 64xx uarts are closer together */
static struct resource s3c64xx_uart0_resource[] = {
[0] = {
.start = S3C_PA_UART0,
.end = S3C_PA_UART0 + 0x100,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX0,
.end = IRQ_S3CUART_RX0,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_S3CUART_TX0,
.end = IRQ_S3CUART_TX0,
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = IRQ_S3CUART_ERR0,
.end = IRQ_S3CUART_ERR0,
.flags = IORESOURCE_IRQ,
}
};
static struct resource s3c64xx_uart1_resource[] = {
[0] = {
.start = S3C_PA_UART1,
.end = S3C_PA_UART1 + 0x100,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX1,
.end = IRQ_S3CUART_RX1,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_S3CUART_TX1,
.end = IRQ_S3CUART_TX1,
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = IRQ_S3CUART_ERR1,
.end = IRQ_S3CUART_ERR1,
.flags = IORESOURCE_IRQ,
},
};
static struct resource s3c6xx_uart2_resource[] = {
[0] = {
.start = S3C_PA_UART2,
.end = S3C_PA_UART2 + 0x100,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX2,
.end = IRQ_S3CUART_RX2,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_S3CUART_TX2,
.end = IRQ_S3CUART_TX2,
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = IRQ_S3CUART_ERR2,
.end = IRQ_S3CUART_ERR2,
.flags = IORESOURCE_IRQ,
},
};
static struct resource s3c64xx_uart3_resource[] = {
[0] = {
.start = S3C_PA_UART3,
.end = S3C_PA_UART3 + 0x100,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_S3CUART_RX3,
.end = IRQ_S3CUART_RX3,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_S3CUART_TX3,
.end = IRQ_S3CUART_TX3,
.flags = IORESOURCE_IRQ,
},
[3] = {
.start = IRQ_S3CUART_ERR3,
.end = IRQ_S3CUART_ERR3,
.flags = IORESOURCE_IRQ,
},
};
struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = {
[0] = {
.resources = s3c64xx_uart0_resource,
.nr_resources = ARRAY_SIZE(s3c64xx_uart0_resource),
},
[1] = {
.resources = s3c64xx_uart1_resource,
.nr_resources = ARRAY_SIZE(s3c64xx_uart1_resource),
},
[2] = {
.resources = s3c6xx_uart2_resource,
.nr_resources = ARRAY_SIZE(s3c6xx_uart2_resource),
},
[3] = {
.resources = s3c64xx_uart3_resource,
.nr_resources = ARRAY_SIZE(s3c64xx_uart3_resource),
},
};
/* uart devices */
static struct platform_device s3c24xx_uart_device0 = {
.id = 0,
};
static struct platform_device s3c24xx_uart_device1 = {
.id = 1,
};
static struct platform_device s3c24xx_uart_device2 = {
.id = 2,
};
static struct platform_device s3c24xx_uart_device3 = {
.id = 3,
};
struct platform_device *s3c24xx_uart_src[4] = {
&s3c24xx_uart_device0,
&s3c24xx_uart_device1,
&s3c24xx_uart_device2,
&s3c24xx_uart_device3,
};
struct platform_device *s3c24xx_uart_devs[4] = {
};

View File

@@ -0,0 +1,750 @@
/* linux/arch/arm/plat-s3c64xx/dma.c
*
* Copyright 2009 Openmoko, Inc.
* Copyright 2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX DMA core
*
* 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/module.h>
#include <linux/interrupt.h>
#include <linux/dmapool.h>
#include <linux/sysdev.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <mach/dma.h>
#include <mach/map.h>
#include <mach/irqs.h>
#include <plat/dma-plat.h>
#include <plat/regs-sys.h>
#include <asm/hardware/pl080.h>
/* dma channel state information */
struct s3c64xx_dmac {
struct sys_device sysdev;
struct clk *clk;
void __iomem *regs;
struct s3c2410_dma_chan *channels;
enum dma_ch chanbase;
};
/* pool to provide LLI buffers */
static struct dma_pool *dma_pool;
/* Debug configuration and code */
static unsigned char debug_show_buffs = 0;
static void dbg_showchan(struct s3c2410_dma_chan *chan)
{
pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
chan->number,
readl(chan->regs + PL080_CH_SRC_ADDR),
readl(chan->regs + PL080_CH_DST_ADDR),
readl(chan->regs + PL080_CH_LLI),
readl(chan->regs + PL080_CH_CONTROL),
readl(chan->regs + PL080S_CH_CONTROL2),
readl(chan->regs + PL080S_CH_CONFIG));
}
static void show_lli(struct pl080s_lli *lli)
{
pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
lli, lli->src_addr, lli->dst_addr, lli->next_lli,
lli->control0, lli->control1);
}
static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
{
struct s3c64xx_dma_buff *ptr;
struct s3c64xx_dma_buff *end;
pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
chan->number, chan->next, chan->curr, chan->end);
ptr = chan->next;
end = chan->end;
if (debug_show_buffs) {
for (; ptr != NULL; ptr = ptr->next) {
pr_debug("DMA%d: %08x ",
chan->number, ptr->lli_dma);
show_lli(ptr->lli);
}
}
}
/* End of Debug */
static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
{
struct s3c2410_dma_chan *chan;
unsigned int start, offs;
start = 0;
if (channel >= DMACH_PCM1_TX)
start = 8;
for (offs = 0; offs < 8; offs++) {
chan = &s3c2410_chans[start + offs];
if (!chan->in_use)
goto found;
}
return NULL;
found:
s3c_dma_chan_map[channel] = chan;
return chan;
}
int s3c2410_dma_config(unsigned int channel, int xferunit)
{
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
if (chan == NULL)
return -EINVAL;
switch (xferunit) {
case 1:
chan->hw_width = 0;
break;
case 2:
chan->hw_width = 1;
break;
case 4:
chan->hw_width = 2;
break;
default:
printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(s3c2410_dma_config);
static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
struct pl080s_lli *lli,
dma_addr_t data, int size)
{
dma_addr_t src, dst;
u32 control0, control1;
switch (chan->source) {
case S3C2410_DMASRC_HW:
src = chan->dev_addr;
dst = data;
control0 = PL080_CONTROL_SRC_AHB2;
control0 |= PL080_CONTROL_DST_INCR;
break;
case S3C2410_DMASRC_MEM:
src = data;
dst = chan->dev_addr;
control0 = PL080_CONTROL_DST_AHB2;
control0 |= PL080_CONTROL_SRC_INCR;
break;
default:
BUG();
}
/* note, we do not currently setup any of the burst controls */
control1 = size >> chan->hw_width; /* size in no of xfers */
control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */
control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */
control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
lli->src_addr = src;
lli->dst_addr = dst;
lli->next_lli = 0;
lli->control0 = control0;
lli->control1 = control1;
}
static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
struct pl080s_lli *lli)
{
void __iomem *regs = chan->regs;
pr_debug("%s: LLI %p => regs\n", __func__, lli);
show_lli(lli);
writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
writel(lli->next_lli, regs + PL080_CH_LLI);
writel(lli->control0, regs + PL080_CH_CONTROL);
writel(lli->control1, regs + PL080S_CH_CONTROL2);
}
static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
{
struct s3c64xx_dmac *dmac = chan->dmac;
u32 config;
u32 bit = chan->bit;
dbg_showchan(chan);
pr_debug("%s: clearing interrupts\n", __func__);
/* clear interrupts */
writel(bit, dmac->regs + PL080_TC_CLEAR);
writel(bit, dmac->regs + PL080_ERR_CLEAR);
pr_debug("%s: starting channel\n", __func__);
config = readl(chan->regs + PL080S_CH_CONFIG);
config |= PL080_CONFIG_ENABLE;
pr_debug("%s: writing config %08x\n", __func__, config);
writel(config, chan->regs + PL080S_CH_CONFIG);
return 0;
}
static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
{
u32 config;
int timeout;
pr_debug("%s: stopping channel\n", __func__);
dbg_showchan(chan);
config = readl(chan->regs + PL080S_CH_CONFIG);
config |= PL080_CONFIG_HALT;
writel(config, chan->regs + PL080S_CH_CONFIG);
timeout = 1000;
do {
config = readl(chan->regs + PL080S_CH_CONFIG);
pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
if (config & PL080_CONFIG_ACTIVE)
udelay(10);
else
break;
} while (--timeout > 0);
if (config & PL080_CONFIG_ACTIVE) {
printk(KERN_ERR "%s: channel still active\n", __func__);
return -EFAULT;
}
config = readl(chan->regs + PL080S_CH_CONFIG);
config &= ~PL080_CONFIG_ENABLE;
writel(config, chan->regs + PL080S_CH_CONFIG);
return 0;
}
static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
struct s3c64xx_dma_buff *buf,
enum s3c2410_dma_buffresult result)
{
if (chan->callback_fn != NULL)
(chan->callback_fn)(chan, buf->pw, 0, result);
}
static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
{
dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
kfree(buff);
}
static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
{
struct s3c64xx_dma_buff *buff, *next;
u32 config;
dbg_showchan(chan);
pr_debug("%s: flushing channel\n", __func__);
config = readl(chan->regs + PL080S_CH_CONFIG);
config &= ~PL080_CONFIG_ENABLE;
writel(config, chan->regs + PL080S_CH_CONFIG);
/* dump all the buffers associated with this channel */
for (buff = chan->curr; buff != NULL; buff = next) {
next = buff->next;
pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
s3c64xx_dma_freebuff(buff);
}
chan->curr = chan->next = chan->end = NULL;
return 0;
}
int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
{
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
WARN_ON(!chan);
if (!chan)
return -EINVAL;
switch (op) {
case S3C2410_DMAOP_START:
return s3c64xx_dma_start(chan);
case S3C2410_DMAOP_STOP:
return s3c64xx_dma_stop(chan);
case S3C2410_DMAOP_FLUSH:
return s3c64xx_dma_flush(chan);
/* belive PAUSE/RESUME are no-ops */
case S3C2410_DMAOP_PAUSE:
case S3C2410_DMAOP_RESUME:
case S3C2410_DMAOP_STARTED:
case S3C2410_DMAOP_TIMEOUT:
return 0;
}
return -ENOENT;
}
EXPORT_SYMBOL(s3c2410_dma_ctrl);
/* s3c2410_dma_enque
*
*/
int s3c2410_dma_enqueue(unsigned int channel, void *id,
dma_addr_t data, int size)
{
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
struct s3c64xx_dma_buff *next;
struct s3c64xx_dma_buff *buff;
struct pl080s_lli *lli;
unsigned long flags;
int ret;
WARN_ON(!chan);
if (!chan)
return -EINVAL;
buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
if (!buff) {
printk(KERN_ERR "%s: no memory for buffer\n", __func__);
return -ENOMEM;
}
lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
if (!lli) {
printk(KERN_ERR "%s: no memory for lli\n", __func__);
ret = -ENOMEM;
goto err_buff;
}
pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
__func__, buff, data, lli, (u32)buff->lli_dma, size);
buff->lli = lli;
buff->pw = id;
s3c64xx_dma_fill_lli(chan, lli, data, size);
local_irq_save(flags);
if ((next = chan->next) != NULL) {
struct s3c64xx_dma_buff *end = chan->end;
struct pl080s_lli *endlli = end->lli;
pr_debug("enquing onto channel\n");
end->next = buff;
endlli->next_lli = buff->lli_dma;
if (chan->flags & S3C2410_DMAF_CIRCULAR) {
struct s3c64xx_dma_buff *curr = chan->curr;
lli->next_lli = curr->lli_dma;
}
if (next == chan->curr) {
writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
chan->next = buff;
}
show_lli(endlli);
chan->end = buff;
} else {
pr_debug("enquing onto empty channel\n");
chan->curr = buff;
chan->next = buff;
chan->end = buff;
s3c64xx_lli_to_regs(chan, lli);
}
local_irq_restore(flags);
show_lli(lli);
dbg_showchan(chan);
dbg_showbuffs(chan);
return 0;
err_buff:
kfree(buff);
return ret;
}
EXPORT_SYMBOL(s3c2410_dma_enqueue);
int s3c2410_dma_devconfig(int channel,
enum s3c2410_dmasrc source,
unsigned long devaddr)
{
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
u32 peripheral;
u32 config = 0;
pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
__func__, channel, source, devaddr, chan);
WARN_ON(!chan);
if (!chan)
return -EINVAL;
peripheral = (chan->peripheral & 0xf);
chan->source = source;
chan->dev_addr = devaddr;
pr_debug("%s: peripheral %d\n", __func__, peripheral);
switch (source) {
case S3C2410_DMASRC_HW:
config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
break;
case S3C2410_DMASRC_MEM:
config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
break;
default:
printk(KERN_ERR "%s: bad source\n", __func__);
return -EINVAL;
}
/* allow TC and ERR interrupts */
config |= PL080_CONFIG_TC_IRQ_MASK;
config |= PL080_CONFIG_ERR_IRQ_MASK;
pr_debug("%s: config %08x\n", __func__, config);
writel(config, chan->regs + PL080S_CH_CONFIG);
return 0;
}
EXPORT_SYMBOL(s3c2410_dma_devconfig);
int s3c2410_dma_getposition(unsigned int channel,
dma_addr_t *src, dma_addr_t *dst)
{
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
WARN_ON(!chan);
if (!chan)
return -EINVAL;
if (src != NULL)
*src = readl(chan->regs + PL080_CH_SRC_ADDR);
if (dst != NULL)
*dst = readl(chan->regs + PL080_CH_DST_ADDR);
return 0;
}
EXPORT_SYMBOL(s3c2410_dma_getposition);
/* s3c2410_request_dma
*
* get control of an dma channel
*/
int s3c2410_dma_request(unsigned int channel,
struct s3c2410_dma_client *client,
void *dev)
{
struct s3c2410_dma_chan *chan;
unsigned long flags;
pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
channel, client->name, dev);
local_irq_save(flags);
chan = s3c64xx_dma_map_channel(channel);
if (chan == NULL) {
local_irq_restore(flags);
return -EBUSY;
}
dbg_showchan(chan);
chan->client = client;
chan->in_use = 1;
chan->peripheral = channel;
local_irq_restore(flags);
/* need to setup */
pr_debug("%s: channel initialised, %p\n", __func__, chan);
return chan->number | DMACH_LOW_LEVEL;
}
EXPORT_SYMBOL(s3c2410_dma_request);
/* s3c2410_dma_free
*
* release the given channel back to the system, will stop and flush
* any outstanding transfers, and ensure the channel is ready for the
* next claimant.
*
* Note, although a warning is currently printed if the freeing client
* info is not the same as the registrant's client info, the free is still
* allowed to go through.
*/
int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
{
struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
unsigned long flags;
if (chan == NULL)
return -EINVAL;
local_irq_save(flags);
if (chan->client != client) {
printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
channel, chan->client, client);
}
/* sort out stopping and freeing the channel */
chan->client = NULL;
chan->in_use = 0;
if (!(channel & DMACH_LOW_LEVEL))
s3c_dma_chan_map[channel] = NULL;
local_irq_restore(flags);
return 0;
}
EXPORT_SYMBOL(s3c2410_dma_free);
static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
{
struct s3c64xx_dmac *dmac = pw;
struct s3c2410_dma_chan *chan;
enum s3c2410_dma_buffresult res;
u32 tcstat, errstat;
u32 bit;
int offs;
tcstat = readl(dmac->regs + PL080_TC_STATUS);
errstat = readl(dmac->regs + PL080_ERR_STATUS);
for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
struct s3c64xx_dma_buff *buff;
if (!(errstat & bit) && !(tcstat & bit))
continue;
chan = dmac->channels + offs;
res = S3C2410_RES_ERR;
if (tcstat & bit) {
writel(bit, dmac->regs + PL080_TC_CLEAR);
res = S3C2410_RES_OK;
}
if (errstat & bit)
writel(bit, dmac->regs + PL080_ERR_CLEAR);
/* 'next' points to the buffer that is next to the
* currently active buffer.
* For CIRCULAR queues, 'next' will be same as 'curr'
* when 'end' is the active buffer.
*/
buff = chan->curr;
while (buff && buff != chan->next
&& buff->next != chan->next)
buff = buff->next;
if (!buff)
BUG();
if (buff == chan->next)
buff = chan->end;
s3c64xx_dma_bufffdone(chan, buff, res);
/* Free the node and update curr, if non-circular queue */
if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
chan->curr = buff->next;
s3c64xx_dma_freebuff(buff);
}
/* Update 'next' */
buff = chan->next;
if (chan->next == chan->end) {
chan->next = chan->curr;
if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
chan->end = NULL;
} else {
chan->next = buff->next;
}
}
return IRQ_HANDLED;
}
static struct sysdev_class dma_sysclass = {
.name = "s3c64xx-dma",
};
static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
int irq, unsigned int base)
{
struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
struct s3c64xx_dmac *dmac;
char clkname[16];
void __iomem *regs;
void __iomem *regptr;
int err, ch;
dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
if (!dmac) {
printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
return -ENOMEM;
}
dmac->sysdev.id = chno / 8;
dmac->sysdev.cls = &dma_sysclass;
err = sysdev_register(&dmac->sysdev);
if (err) {
printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
goto err_alloc;
}
regs = ioremap(base, 0x200);
if (!regs) {
printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
err = -ENXIO;
goto err_dev;
}
snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);
dmac->clk = clk_get(NULL, clkname);
if (IS_ERR(dmac->clk)) {
printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
err = PTR_ERR(dmac->clk);
goto err_map;
}
clk_enable(dmac->clk);
dmac->regs = regs;
dmac->chanbase = chbase;
dmac->channels = chptr;
err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
if (err < 0) {
printk(KERN_ERR "%s: failed to get irq\n", __func__);
goto err_clk;
}
regptr = regs + PL080_Cx_BASE(0);
for (ch = 0; ch < 8; ch++, chno++, chptr++) {
printk(KERN_INFO "%s: registering DMA %d (%p)\n",
__func__, chno, regptr);
chptr->bit = 1 << ch;
chptr->number = chno;
chptr->dmac = dmac;
chptr->regs = regptr;
regptr += PL008_Cx_STRIDE;
}
/* for the moment, permanently enable the controller */
writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
printk(KERN_INFO "PL080: IRQ %d, at %p\n", irq, regs);
return 0;
err_clk:
clk_disable(dmac->clk);
clk_put(dmac->clk);
err_map:
iounmap(regs);
err_dev:
sysdev_unregister(&dmac->sysdev);
err_alloc:
kfree(dmac);
return err;
}
static int __init s3c64xx_dma_init(void)
{
int ret;
printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
if (!dma_pool) {
printk(KERN_ERR "%s: failed to create pool\n", __func__);
return -ENOMEM;
}
ret = sysdev_class_register(&dma_sysclass);
if (ret) {
printk(KERN_ERR "%s: failed to create sysclass\n", __func__);
return -ENOMEM;
}
/* Set all DMA configuration to be DMA, not SDMA */
writel(0xffffff, S3C_SYSREG(0x110));
/* Register standard DMA controlers */
s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
return 0;
}
arch_initcall(s3c64xx_dma_init);

View File

@@ -0,0 +1,434 @@
/* arch/arm/plat-s3c64xx/gpiolib.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - 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 <mach/map.h>
#include <mach/gpio.h>
#include <mach/gpio-core.h>
#include <plat/gpio-cfg.h>
#include <plat/gpio-cfg-helpers.h>
#include <plat/regs-gpio.h>
/* GPIO bank summary:
*
* Bank GPIOs Style SlpCon ExtInt Group
* A 8 4Bit Yes 1
* B 7 4Bit Yes 1
* C 8 4Bit Yes 2
* D 5 4Bit Yes 3
* E 5 4Bit Yes None
* F 16 2Bit Yes 4 [1]
* G 7 4Bit Yes 5
* H 10 4Bit[2] Yes 6
* I 16 2Bit Yes None
* J 12 2Bit Yes None
* K 16 4Bit[2] No None
* L 15 4Bit[2] No None
* M 6 4Bit No IRQ_EINT
* N 16 2Bit No IRQ_EINT
* O 16 2Bit Yes 7
* P 15 2Bit Yes 8
* Q 9 2Bit Yes 9
*
* [1] BANKF pins 14,15 do not form part of the external interrupt sources
* [2] BANK has two control registers, GPxCON0 and GPxCON1
*/
#define OFF_GPCON (0x00)
#define OFF_GPDAT (0x04)
#define con_4bit_shift(__off) ((__off) * 4)
#if 1
#define gpio_dbg(x...) do { } while(0)
#else
#define gpio_dbg(x...) printk(KERN_DEBUG x)
#endif
/* The s3c64xx_gpiolib_4bit routines are to control the gpio banks where
* the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
* following example:
*
* base + 0x00: Control register, 4 bits per gpio
* gpio n: 4 bits starting at (4*n)
* 0000 = input, 0001 = output, others mean special-function
* base + 0x04: Data register, 1 bit per gpio
* bit n: data bit n
*
* Note, since the data register is one bit per gpio and is at base + 0x4
* we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
* the output.
*/
static int s3c64xx_gpiolib_4bit_input(struct gpio_chip *chip, unsigned offset)
{
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
void __iomem *base = ourchip->base;
unsigned long con;
con = __raw_readl(base + OFF_GPCON);
con &= ~(0xf << con_4bit_shift(offset));
__raw_writel(con, base + OFF_GPCON);
gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
return 0;
}
static int s3c64xx_gpiolib_4bit_output(struct gpio_chip *chip,
unsigned offset, int value)
{
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
void __iomem *base = ourchip->base;
unsigned long con;
unsigned long dat;
con = __raw_readl(base + OFF_GPCON);
con &= ~(0xf << con_4bit_shift(offset));
con |= 0x1 << con_4bit_shift(offset);
dat = __raw_readl(base + OFF_GPDAT);
if (value)
dat |= 1 << offset;
else
dat &= ~(1 << offset);
__raw_writel(dat, base + OFF_GPDAT);
__raw_writel(con, base + OFF_GPCON);
__raw_writel(dat, base + OFF_GPDAT);
gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
return 0;
}
/* The next set of routines are for the case where the GPIO configuration
* registers are 4 bits per GPIO but there is more than one register (the
* bank has more than 8 GPIOs.
*
* This case is the similar to the 4 bit case, but the registers are as
* follows:
*
* base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
* gpio n: 4 bits starting at (4*n)
* 0000 = input, 0001 = output, others mean special-function
* base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
* gpio n: 4 bits starting at (4*n)
* 0000 = input, 0001 = output, others mean special-function
* base + 0x08: Data register, 1 bit per gpio
* bit n: data bit n
*
* To allow us to use the s3c_gpiolib_get and s3c_gpiolib_set routines we
* store the 'base + 0x4' address so that these routines see the data
* register at ourchip->base + 0x04.
*/
static int s3c64xx_gpiolib_4bit2_input(struct gpio_chip *chip, unsigned offset)
{
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
void __iomem *base = ourchip->base;
void __iomem *regcon = base;
unsigned long con;
if (offset > 7)
offset -= 8;
else
regcon -= 4;
con = __raw_readl(regcon);
con &= ~(0xf << con_4bit_shift(offset));
__raw_writel(con, regcon);
gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
return 0;
}
static int s3c64xx_gpiolib_4bit2_output(struct gpio_chip *chip,
unsigned offset, int value)
{
struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
void __iomem *base = ourchip->base;
void __iomem *regcon = base;
unsigned long con;
unsigned long dat;
if (offset > 7)
offset -= 8;
else
regcon -= 4;
con = __raw_readl(regcon);
con &= ~(0xf << con_4bit_shift(offset));
con |= 0x1 << con_4bit_shift(offset);
dat = __raw_readl(base + OFF_GPDAT);
if (value)
dat |= 1 << offset;
else
dat &= ~(1 << offset);
__raw_writel(dat, base + OFF_GPDAT);
__raw_writel(con, regcon);
__raw_writel(dat, base + OFF_GPDAT);
gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
return 0;
}
static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
.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_4bit_cfg_eint0111 = {
.cfg_eint = 7,
.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_4bit_cfg_eint0011 = {
.cfg_eint = 3,
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
static struct s3c_gpio_chip gpio_4bit[] = {
{
.base = S3C64XX_GPA_BASE,
.config = &gpio_4bit_cfg_eint0111,
.chip = {
.base = S3C64XX_GPA(0),
.ngpio = S3C64XX_GPIO_A_NR,
.label = "GPA",
},
}, {
.base = S3C64XX_GPB_BASE,
.config = &gpio_4bit_cfg_eint0111,
.chip = {
.base = S3C64XX_GPB(0),
.ngpio = S3C64XX_GPIO_B_NR,
.label = "GPB",
},
}, {
.base = S3C64XX_GPC_BASE,
.config = &gpio_4bit_cfg_eint0111,
.chip = {
.base = S3C64XX_GPC(0),
.ngpio = S3C64XX_GPIO_C_NR,
.label = "GPC",
},
}, {
.base = S3C64XX_GPD_BASE,
.config = &gpio_4bit_cfg_eint0111,
.chip = {
.base = S3C64XX_GPD(0),
.ngpio = S3C64XX_GPIO_D_NR,
.label = "GPD",
},
}, {
.base = S3C64XX_GPE_BASE,
.config = &gpio_4bit_cfg_noint,
.chip = {
.base = S3C64XX_GPE(0),
.ngpio = S3C64XX_GPIO_E_NR,
.label = "GPE",
},
}, {
.base = S3C64XX_GPG_BASE,
.config = &gpio_4bit_cfg_eint0111,
.chip = {
.base = S3C64XX_GPG(0),
.ngpio = S3C64XX_GPIO_G_NR,
.label = "GPG",
},
}, {
.base = S3C64XX_GPM_BASE,
.config = &gpio_4bit_cfg_eint0011,
.chip = {
.base = S3C64XX_GPM(0),
.ngpio = S3C64XX_GPIO_M_NR,
.label = "GPM",
},
},
};
static struct s3c_gpio_chip gpio_4bit2[] = {
{
.base = S3C64XX_GPH_BASE + 0x4,
.config = &gpio_4bit_cfg_eint0111,
.chip = {
.base = S3C64XX_GPH(0),
.ngpio = S3C64XX_GPIO_H_NR,
.label = "GPH",
},
}, {
.base = S3C64XX_GPK_BASE + 0x4,
.config = &gpio_4bit_cfg_noint,
.chip = {
.base = S3C64XX_GPK(0),
.ngpio = S3C64XX_GPIO_K_NR,
.label = "GPK",
},
}, {
.base = S3C64XX_GPL_BASE + 0x4,
.config = &gpio_4bit_cfg_eint0011,
.chip = {
.base = S3C64XX_GPL(0),
.ngpio = S3C64XX_GPIO_L_NR,
.label = "GPL",
},
},
};
static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
.set_config = s3c_gpio_setcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
.cfg_eint = 2,
.set_config = s3c_gpio_setcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
.cfg_eint = 3,
.set_config = s3c_gpio_setcfg_s3c24xx,
.set_pull = s3c_gpio_setpull_updown,
.get_pull = s3c_gpio_getpull_updown,
};
int s3c64xx_gpio2int_gpn(struct gpio_chip *chip, unsigned pin)
{
return IRQ_EINT(0) + pin;
}
static struct s3c_gpio_chip gpio_2bit[] = {
{
.base = S3C64XX_GPF_BASE,
.config = &gpio_2bit_cfg_eint11,
.chip = {
.base = S3C64XX_GPF(0),
.ngpio = S3C64XX_GPIO_F_NR,
.label = "GPF",
},
}, {
.base = S3C64XX_GPI_BASE,
.config = &gpio_2bit_cfg_noint,
.chip = {
.base = S3C64XX_GPI(0),
.ngpio = S3C64XX_GPIO_I_NR,
.label = "GPI",
},
}, {
.base = S3C64XX_GPJ_BASE,
.config = &gpio_2bit_cfg_noint,
.chip = {
.base = S3C64XX_GPJ(0),
.ngpio = S3C64XX_GPIO_J_NR,
.label = "GPJ",
},
}, {
.base = S3C64XX_GPN_BASE,
.config = &gpio_2bit_cfg_eint10,
.chip = {
.base = S3C64XX_GPN(0),
.ngpio = S3C64XX_GPIO_N_NR,
.label = "GPN",
.to_irq = s3c64xx_gpio2int_gpn,
},
}, {
.base = S3C64XX_GPO_BASE,
.config = &gpio_2bit_cfg_eint11,
.chip = {
.base = S3C64XX_GPO(0),
.ngpio = S3C64XX_GPIO_O_NR,
.label = "GPO",
},
}, {
.base = S3C64XX_GPP_BASE,
.config = &gpio_2bit_cfg_eint11,
.chip = {
.base = S3C64XX_GPP(0),
.ngpio = S3C64XX_GPIO_P_NR,
.label = "GPP",
},
}, {
.base = S3C64XX_GPQ_BASE,
.config = &gpio_2bit_cfg_eint11,
.chip = {
.base = S3C64XX_GPQ(0),
.ngpio = S3C64XX_GPIO_Q_NR,
.label = "GPQ",
},
},
};
static __init void s3c64xx_gpiolib_add_4bit(struct s3c_gpio_chip *chip)
{
chip->chip.direction_input = s3c64xx_gpiolib_4bit_input;
chip->chip.direction_output = s3c64xx_gpiolib_4bit_output;
chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
}
static __init void s3c64xx_gpiolib_add_4bit2(struct s3c_gpio_chip *chip)
{
chip->chip.direction_input = s3c64xx_gpiolib_4bit2_input;
chip->chip.direction_output = s3c64xx_gpiolib_4bit2_output;
chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
}
static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
{
chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
}
static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
int nr_chips,
void (*fn)(struct s3c_gpio_chip *))
{
for (; nr_chips > 0; nr_chips--, chips++) {
if (fn)
(fn)(chips);
s3c_gpiolib_add(chips);
}
}
static __init int s3c64xx_gpiolib_init(void)
{
s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
s3c64xx_gpiolib_add_4bit);
s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
s3c64xx_gpiolib_add_4bit2);
s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
s3c64xx_gpiolib_add_2bit);
return 0;
}
core_initcall(s3c64xx_gpiolib_init);

View File

@@ -0,0 +1,70 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/dma-plat.h
*
* Copyright 2009 Openmoko, Inc.
* Copyright 2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX DMA core
*
* 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 DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
struct s3c64xx_dma_buff;
/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
* @next: Pointer to next buffer in queue or ring.
* @pw: Client provided identifier
* @lli: Pointer to hardware descriptor this buffer is associated with.
* @lli_dma: Hardare address of the descriptor.
*/
struct s3c64xx_dma_buff {
struct s3c64xx_dma_buff *next;
void *pw;
struct pl080s_lli *lli;
dma_addr_t lli_dma;
};
struct s3c64xx_dmac;
struct s3c2410_dma_chan {
unsigned char number; /* number of this dma channel */
unsigned char in_use; /* channel allocated */
unsigned char bit; /* bit for enable/disable/etc */
unsigned char hw_width;
unsigned char peripheral;
unsigned int flags;
enum s3c2410_dmasrc source;
dma_addr_t dev_addr;
struct s3c2410_dma_client *client;
struct s3c64xx_dmac *dmac; /* pointer to controller */
void __iomem *regs;
/* cdriver callbacks */
s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
s3c2410_dma_opfn_t op_fn; /* channel op callback */
/* buffer list and information */
struct s3c64xx_dma_buff *curr; /* current dma buffer */
struct s3c64xx_dma_buff *next; /* next buffer to load */
struct s3c64xx_dma_buff *end; /* end of queue */
/* note, when channel is running in circular mode, curr is the
* first buffer enqueued, end is the last and curr is where the
* last buffer-done event is set-at. The buffers are not freed
* and the last buffer hardware descriptor points back to the
* first.
*/
};
#include <plat/dma-core.h>

View File

@@ -0,0 +1,48 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-a.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank A register and configuration 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 S3C64XX_GPACON (S3C64XX_GPA_BASE + 0x00)
#define S3C64XX_GPADAT (S3C64XX_GPA_BASE + 0x04)
#define S3C64XX_GPAPUD (S3C64XX_GPA_BASE + 0x08)
#define S3C64XX_GPACONSLP (S3C64XX_GPA_BASE + 0x0c)
#define S3C64XX_GPAPUDSLP (S3C64XX_GPA_BASE + 0x10)
#define S3C64XX_GPA_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S3C64XX_GPA_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S3C64XX_GPA_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
#define S3C64XX_GPA0_UART_RXD0 (0x02 << 0)
#define S3C64XX_GPA0_EINT_G1_0 (0x07 << 0)
#define S3C64XX_GPA1_UART_TXD0 (0x02 << 4)
#define S3C64XX_GPA1_EINT_G1_1 (0x07 << 4)
#define S3C64XX_GPA2_UART_nCTS0 (0x02 << 8)
#define S3C64XX_GPA2_EINT_G1_2 (0x07 << 8)
#define S3C64XX_GPA3_UART_nRTS0 (0x02 << 12)
#define S3C64XX_GPA3_EINT_G1_3 (0x07 << 12)
#define S3C64XX_GPA4_UART_RXD1 (0x02 << 16)
#define S3C64XX_GPA4_EINT_G1_4 (0x07 << 16)
#define S3C64XX_GPA5_UART_TXD1 (0x02 << 20)
#define S3C64XX_GPA5_EINT_G1_5 (0x07 << 20)
#define S3C64XX_GPA6_UART_nCTS1 (0x02 << 24)
#define S3C64XX_GPA6_EINT_G1_6 (0x07 << 24)
#define S3C64XX_GPA7_UART_nRTS1 (0x02 << 28)
#define S3C64XX_GPA7_EINT_G1_7 (0x07 << 28)

View File

@@ -0,0 +1,60 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-b.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank B register and configuration 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 S3C64XX_GPBCON (S3C64XX_GPB_BASE + 0x00)
#define S3C64XX_GPBDAT (S3C64XX_GPB_BASE + 0x04)
#define S3C64XX_GPBPUD (S3C64XX_GPB_BASE + 0x08)
#define S3C64XX_GPBCONSLP (S3C64XX_GPB_BASE + 0x0c)
#define S3C64XX_GPBPUDSLP (S3C64XX_GPB_BASE + 0x10)
#define S3C64XX_GPB_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S3C64XX_GPB_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S3C64XX_GPB_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
#define S3C64XX_GPB0_UART_RXD2 (0x02 << 0)
#define S3C64XX_GPB0_EXTDMA_REQ (0x03 << 0)
#define S3C64XX_GPB0_IrDA_RXD (0x04 << 0)
#define S3C64XX_GPB0_ADDR_CF0 (0x05 << 0)
#define S3C64XX_GPB0_EINT_G1_8 (0x07 << 0)
#define S3C64XX_GPB1_UART_TXD2 (0x02 << 4)
#define S3C64XX_GPB1_EXTDMA_ACK (0x03 << 4)
#define S3C64XX_GPB1_IrDA_TXD (0x04 << 4)
#define S3C64XX_GPB1_ADDR_CF1 (0x05 << 4)
#define S3C64XX_GPB1_EINT_G1_9 (0x07 << 4)
#define S3C64XX_GPB2_UART_RXD3 (0x02 << 8)
#define S3C64XX_GPB2_IrDA_RXD (0x03 << 8)
#define S3C64XX_GPB2_EXTDMA_REQ (0x04 << 8)
#define S3C64XX_GPB2_ADDR_CF2 (0x05 << 8)
#define S3C64XX_GPB2_I2C_SCL1 (0x06 << 8)
#define S3C64XX_GPB2_EINT_G1_10 (0x07 << 8)
#define S3C64XX_GPB3_UART_TXD3 (0x02 << 12)
#define S3C64XX_GPB3_IrDA_TXD (0x03 << 12)
#define S3C64XX_GPB3_EXTDMA_ACK (0x04 << 12)
#define S3C64XX_GPB3_I2C_SDA1 (0x06 << 12)
#define S3C64XX_GPB3_EINT_G1_11 (0x07 << 12)
#define S3C64XX_GPB4_IrDA_SDBW (0x02 << 16)
#define S3C64XX_GPB4_CAM_FIELD (0x03 << 16)
#define S3C64XX_GPB4_CF_DATA_DIR (0x04 << 16)
#define S3C64XX_GPB4_EINT_G1_12 (0x07 << 16)
#define S3C64XX_GPB5_I2C_SCL0 (0x02 << 20)
#define S3C64XX_GPB5_EINT_G1_13 (0x07 << 20)
#define S3C64XX_GPB6_I2C_SDA0 (0x02 << 24)
#define S3C64XX_GPB6_EINT_G1_14 (0x07 << 24)

View File

@@ -0,0 +1,53 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-c.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank C register and configuration 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 S3C64XX_GPCCON (S3C64XX_GPC_BASE + 0x00)
#define S3C64XX_GPCDAT (S3C64XX_GPC_BASE + 0x04)
#define S3C64XX_GPCPUD (S3C64XX_GPC_BASE + 0x08)
#define S3C64XX_GPCCONSLP (S3C64XX_GPC_BASE + 0x0c)
#define S3C64XX_GPCPUDSLP (S3C64XX_GPC_BASE + 0x10)
#define S3C64XX_GPC_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S3C64XX_GPC_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S3C64XX_GPC_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
#define S3C64XX_GPC0_SPI_MISO0 (0x02 << 0)
#define S3C64XX_GPC0_EINT_G2_0 (0x07 << 0)
#define S3C64XX_GPC1_SPI_CLKO (0x02 << 4)
#define S3C64XX_GPC1_EINT_G2_1 (0x07 << 4)
#define S3C64XX_GPC2_SPI_MOSIO (0x02 << 8)
#define S3C64XX_GPC2_EINT_G2_2 (0x07 << 8)
#define S3C64XX_GPC3_SPI_nCSO (0x02 << 12)
#define S3C64XX_GPC3_EINT_G2_3 (0x07 << 12)
#define S3C64XX_GPC4_SPI_MISO1 (0x02 << 16)
#define S3C64XX_GPC4_MMC2_CMD (0x03 << 16)
#define S3C64XX_GPC4_I2S0_V40_DO (0x05 << 16)
#define S3C64XX_GPC4_EINT_G2_4 (0x07 << 16)
#define S3C64XX_GPC5_SPI_CLK1 (0x02 << 20)
#define S3C64XX_GPC5_MMC2_CLK (0x03 << 20)
#define S3C64XX_GPC5_I2S1_V40_DO (0x05 << 20)
#define S3C64XX_GPC5_EINT_G2_5 (0x07 << 20)
#define S3C64XX_GPC6_SPI_MOSI1 (0x02 << 24)
#define S3C64XX_GPC6_EINT_G2_6 (0x07 << 24)
#define S3C64XX_GPC7_SPI_nCS1 (0x02 << 28)
#define S3C64XX_GPC7_I2S2_V40_DO (0x05 << 28)
#define S3C64XX_GPC7_EINT_G2_7 (0x07 << 28)

View File

@@ -0,0 +1,49 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-d.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank D register and configuration 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 S3C64XX_GPDCON (S3C64XX_GPD_BASE + 0x00)
#define S3C64XX_GPDDAT (S3C64XX_GPD_BASE + 0x04)
#define S3C64XX_GPDPUD (S3C64XX_GPD_BASE + 0x08)
#define S3C64XX_GPDCONSLP (S3C64XX_GPD_BASE + 0x0c)
#define S3C64XX_GPDPUDSLP (S3C64XX_GPD_BASE + 0x10)
#define S3C64XX_GPD_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S3C64XX_GPD_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S3C64XX_GPD_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
#define S3C64XX_GPD0_PCM0_SCLK (0x02 << 0)
#define S3C64XX_GPD0_I2S0_CLK (0x03 << 0)
#define S3C64XX_GPD0_AC97_BITCLK (0x04 << 0)
#define S3C64XX_GPD0_EINT_G3_0 (0x07 << 0)
#define S3C64XX_GPD1_PCM0_EXTCLK (0x02 << 4)
#define S3C64XX_GPD1_I2S0_CDCLK (0x03 << 4)
#define S3C64XX_GPD1_AC97_nRESET (0x04 << 4)
#define S3C64XX_GPD1_EINT_G3_1 (0x07 << 4)
#define S3C64XX_GPD2_PCM0_FSYNC (0x02 << 8)
#define S3C64XX_GPD2_I2S0_LRCLK (0x03 << 8)
#define S3C64XX_GPD2_AC97_SYNC (0x04 << 8)
#define S3C64XX_GPD2_EINT_G3_2 (0x07 << 8)
#define S3C64XX_GPD3_PCM0_SIN (0x02 << 12)
#define S3C64XX_GPD3_I2S0_DI (0x03 << 12)
#define S3C64XX_GPD3_AC97_SDI (0x04 << 12)
#define S3C64XX_GPD3_EINT_G3_3 (0x07 << 12)
#define S3C64XX_GPD4_PCM0_SOUT (0x02 << 16)
#define S3C64XX_GPD4_I2S0_D0 (0x03 << 16)
#define S3C64XX_GPD4_AC97_SDO (0x04 << 16)
#define S3C64XX_GPD4_EINT_G3_4 (0x07 << 16)

View File

@@ -0,0 +1,44 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-e.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank E register and configuration 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 S3C64XX_GPECON (S3C64XX_GPE_BASE + 0x00)
#define S3C64XX_GPEDAT (S3C64XX_GPE_BASE + 0x04)
#define S3C64XX_GPEPUD (S3C64XX_GPE_BASE + 0x08)
#define S3C64XX_GPECONSLP (S3C64XX_GPE_BASE + 0x0c)
#define S3C64XX_GPEPUDSLP (S3C64XX_GPE_BASE + 0x10)
#define S3C64XX_GPE_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S3C64XX_GPE_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S3C64XX_GPE_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
#define S3C64XX_GPE0_PCM1_SCLK (0x02 << 0)
#define S3C64XX_GPE0_I2S1_CLK (0x03 << 0)
#define S3C64XX_GPE0_AC97_BITCLK (0x04 << 0)
#define S3C64XX_GPE1_PCM1_EXTCLK (0x02 << 4)
#define S3C64XX_GPE1_I2S1_CDCLK (0x03 << 4)
#define S3C64XX_GPE1_AC97_nRESET (0x04 << 4)
#define S3C64XX_GPE2_PCM1_FSYNC (0x02 << 8)
#define S3C64XX_GPE2_I2S1_LRCLK (0x03 << 8)
#define S3C64XX_GPE2_AC97_SYNC (0x04 << 8)
#define S3C64XX_GPE3_PCM1_SIN (0x02 << 12)
#define S3C64XX_GPE3_I2S1_DI (0x03 << 12)
#define S3C64XX_GPE3_AC97_SDI (0x04 << 12)
#define S3C64XX_GPE4_PCM1_SOUT (0x02 << 16)
#define S3C64XX_GPE4_I2S1_D0 (0x03 << 16)
#define S3C64XX_GPE4_AC97_SDO (0x04 << 16)

View File

@@ -0,0 +1,71 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-f.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank F register and configuration 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 S3C64XX_GPFCON (S3C64XX_GPF_BASE + 0x00)
#define S3C64XX_GPFDAT (S3C64XX_GPF_BASE + 0x04)
#define S3C64XX_GPFPUD (S3C64XX_GPF_BASE + 0x08)
#define S3C64XX_GPFCONSLP (S3C64XX_GPF_BASE + 0x0c)
#define S3C64XX_GPFPUDSLP (S3C64XX_GPF_BASE + 0x10)
#define S3C64XX_GPF_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S3C64XX_GPF_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S3C64XX_GPF_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
#define S3C64XX_GPF0_CAMIF_CLK (0x02 << 0)
#define S3C64XX_GPF0_EINT_G4_0 (0x03 << 0)
#define S3C64XX_GPF1_CAMIF_HREF (0x02 << 2)
#define S3C64XX_GPF1_EINT_G4_1 (0x03 << 2)
#define S3C64XX_GPF2_CAMIF_PCLK (0x02 << 4)
#define S3C64XX_GPF2_EINT_G4_2 (0x03 << 4)
#define S3C64XX_GPF3_CAMIF_nRST (0x02 << 6)
#define S3C64XX_GPF3_EINT_G4_3 (0x03 << 6)
#define S3C64XX_GPF4_CAMIF_VSYNC (0x02 << 8)
#define S3C64XX_GPF4_EINT_G4_4 (0x03 << 8)
#define S3C64XX_GPF5_CAMIF_YDATA0 (0x02 << 10)
#define S3C64XX_GPF5_EINT_G4_5 (0x03 << 10)
#define S3C64XX_GPF6_CAMIF_YDATA1 (0x02 << 12)
#define S3C64XX_GPF6_EINT_G4_6 (0x03 << 12)
#define S3C64XX_GPF7_CAMIF_YDATA2 (0x02 << 14)
#define S3C64XX_GPF7_EINT_G4_7 (0x03 << 14)
#define S3C64XX_GPF8_CAMIF_YDATA3 (0x02 << 16)
#define S3C64XX_GPF8_EINT_G4_8 (0x03 << 16)
#define S3C64XX_GPF9_CAMIF_YDATA4 (0x02 << 18)
#define S3C64XX_GPF9_EINT_G4_9 (0x03 << 18)
#define S3C64XX_GPF10_CAMIF_YDATA5 (0x02 << 20)
#define S3C64XX_GPF10_EINT_G4_10 (0x03 << 20)
#define S3C64XX_GPF11_CAMIF_YDATA6 (0x02 << 22)
#define S3C64XX_GPF11_EINT_G4_11 (0x03 << 22)
#define S3C64XX_GPF12_CAMIF_YDATA7 (0x02 << 24)
#define S3C64XX_GPF12_EINT_G4_12 (0x03 << 24)
#define S3C64XX_GPF13_PWM_ECLK (0x02 << 26)
#define S3C64XX_GPF13_EINT_G4_13 (0x03 << 26)
#define S3C64XX_GPF14_PWM_TOUT0 (0x02 << 28)
#define S3C64XX_GPF14_CLKOUT0 (0x03 << 28)
#define S3C64XX_GPF15_PWM_TOUT1 (0x02 << 30)

View File

@@ -0,0 +1,42 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-g.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank G register and configuration 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 S3C64XX_GPGCON (S3C64XX_GPG_BASE + 0x00)
#define S3C64XX_GPGDAT (S3C64XX_GPG_BASE + 0x04)
#define S3C64XX_GPGPUD (S3C64XX_GPG_BASE + 0x08)
#define S3C64XX_GPGCONSLP (S3C64XX_GPG_BASE + 0x0c)
#define S3C64XX_GPGPUDSLP (S3C64XX_GPG_BASE + 0x10)
#define S3C64XX_GPG_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S3C64XX_GPG_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S3C64XX_GPG_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
#define S3C64XX_GPG0_MMC0_CLK (0x02 << 0)
#define S3C64XX_GPG0_EINT_G5_0 (0x07 << 0)
#define S3C64XX_GPG1_MMC0_CMD (0x02 << 4)
#define S3C64XX_GPG1_EINT_G5_1 (0x07 << 4)
#define S3C64XX_GPG2_MMC0_DATA0 (0x02 << 8)
#define S3C64XX_GPG2_EINT_G5_2 (0x07 << 8)
#define S3C64XX_GPG3_MMC0_DATA1 (0x02 << 12)
#define S3C64XX_GPG3_EINT_G5_3 (0x07 << 12)
#define S3C64XX_GPG4_MMC0_DATA2 (0x02 << 16)
#define S3C64XX_GPG4_EINT_G5_4 (0x07 << 16)
#define S3C64XX_GPG5_MMC0_DATA3 (0x02 << 20)
#define S3C64XX_GPG5_EINT_G5_5 (0x07 << 20)

View File

@@ -0,0 +1,74 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-h.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank H register and configuration 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 S3C64XX_GPHCON0 (S3C64XX_GPH_BASE + 0x00)
#define S3C64XX_GPHCON1 (S3C64XX_GPH_BASE + 0x04)
#define S3C64XX_GPHDAT (S3C64XX_GPH_BASE + 0x08)
#define S3C64XX_GPHPUD (S3C64XX_GPH_BASE + 0x0c)
#define S3C64XX_GPHCONSLP (S3C64XX_GPH_BASE + 0x10)
#define S3C64XX_GPHPUDSLP (S3C64XX_GPH_BASE + 0x14)
#define S3C64XX_GPH_CONMASK(__gpio) (0xf << ((__gpio) * 4))
#define S3C64XX_GPH_INPUT(__gpio) (0x0 << ((__gpio) * 4))
#define S3C64XX_GPH_OUTPUT(__gpio) (0x1 << ((__gpio) * 4))
#define S3C64XX_GPH0_MMC1_CLK (0x02 << 0)
#define S3C64XX_GPH0_KP_COL0 (0x04 << 0)
#define S3C64XX_GPH0_EINT_G6_0 (0x07 << 0)
#define S3C64XX_GPH1_MMC1_CMD (0x02 << 4)
#define S3C64XX_GPH1_KP_COL1 (0x04 << 4)
#define S3C64XX_GPH1_EINT_G6_1 (0x07 << 4)
#define S3C64XX_GPH2_MMC1_DATA0 (0x02 << 8)
#define S3C64XX_GPH2_KP_COL2 (0x04 << 8)
#define S3C64XX_GPH2_EINT_G6_2 (0x07 << 8)
#define S3C64XX_GPH3_MMC1_DATA1 (0x02 << 12)
#define S3C64XX_GPH3_KP_COL3 (0x04 << 12)
#define S3C64XX_GPH3_EINT_G6_3 (0x07 << 12)
#define S3C64XX_GPH4_MMC1_DATA2 (0x02 << 16)
#define S3C64XX_GPH4_KP_COL4 (0x04 << 16)
#define S3C64XX_GPH4_EINT_G6_4 (0x07 << 16)
#define S3C64XX_GPH5_MMC1_DATA3 (0x02 << 20)
#define S3C64XX_GPH5_KP_COL5 (0x04 << 20)
#define S3C64XX_GPH5_EINT_G6_5 (0x07 << 20)
#define S3C64XX_GPH6_MMC1_DATA4 (0x02 << 24)
#define S3C64XX_GPH6_MMC2_DATA0 (0x03 << 24)
#define S3C64XX_GPH6_KP_COL6 (0x04 << 24)
#define S3C64XX_GPH6_I2S_V40_BCLK (0x05 << 24)
#define S3C64XX_GPH6_ADDR_CF0 (0x06 << 24)
#define S3C64XX_GPH6_EINT_G6_6 (0x07 << 24)
#define S3C64XX_GPH7_MMC1_DATA5 (0x02 << 28)
#define S3C64XX_GPH7_MMC2_DATA1 (0x03 << 28)
#define S3C64XX_GPH7_KP_COL7 (0x04 << 28)
#define S3C64XX_GPH7_I2S_V40_CDCLK (0x05 << 28)
#define S3C64XX_GPH7_ADDR_CF1 (0x06 << 28)
#define S3C64XX_GPH7_EINT_G6_7 (0x07 << 28)
#define S3C64XX_GPH8_MMC1_DATA6 (0x02 << 0)
#define S3C64XX_GPH8_MMC2_DATA2 (0x03 << 0)
#define S3C64XX_GPH8_I2S_V40_LRCLK (0x05 << 0)
#define S3C64XX_GPH8_ADDR_CF2 (0x06 << 0)
#define S3C64XX_GPH8_EINT_G6_8 (0x07 << 0)
#define S3C64XX_GPH9_OUTPUT (0x01 << 4)
#define S3C64XX_GPH9_MMC1_DATA7 (0x02 << 4)
#define S3C64XX_GPH9_MMC2_DATA3 (0x03 << 4)
#define S3C64XX_GPH9_I2S_V40_DI (0x05 << 4)
#define S3C64XX_GPH9_EINT_G6_9 (0x07 << 4)

View File

@@ -0,0 +1,40 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-i.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank I register and configuration 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 S3C64XX_GPICON (S3C64XX_GPI_BASE + 0x00)
#define S3C64XX_GPIDAT (S3C64XX_GPI_BASE + 0x04)
#define S3C64XX_GPIPUD (S3C64XX_GPI_BASE + 0x08)
#define S3C64XX_GPICONSLP (S3C64XX_GPI_BASE + 0x0c)
#define S3C64XX_GPIPUDSLP (S3C64XX_GPI_BASE + 0x10)
#define S3C64XX_GPI_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S3C64XX_GPI_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S3C64XX_GPI_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
#define S3C64XX_GPI0_VD0 (0x02 << 0)
#define S3C64XX_GPI1_VD1 (0x02 << 2)
#define S3C64XX_GPI2_VD2 (0x02 << 4)
#define S3C64XX_GPI3_VD3 (0x02 << 6)
#define S3C64XX_GPI4_VD4 (0x02 << 8)
#define S3C64XX_GPI5_VD5 (0x02 << 10)
#define S3C64XX_GPI6_VD6 (0x02 << 12)
#define S3C64XX_GPI7_VD7 (0x02 << 14)
#define S3C64XX_GPI8_VD8 (0x02 << 16)
#define S3C64XX_GPI9_VD9 (0x02 << 18)
#define S3C64XX_GPI10_VD10 (0x02 << 20)
#define S3C64XX_GPI11_VD11 (0x02 << 22)
#define S3C64XX_GPI12_VD12 (0x02 << 24)
#define S3C64XX_GPI13_VD13 (0x02 << 26)
#define S3C64XX_GPI14_VD14 (0x02 << 28)
#define S3C64XX_GPI15_VD15 (0x02 << 30)

View File

@@ -0,0 +1,36 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-j.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank J register and configuration 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 S3C64XX_GPJCON (S3C64XX_GPJ_BASE + 0x00)
#define S3C64XX_GPJDAT (S3C64XX_GPJ_BASE + 0x04)
#define S3C64XX_GPJPUD (S3C64XX_GPJ_BASE + 0x08)
#define S3C64XX_GPJCONSLP (S3C64XX_GPJ_BASE + 0x0c)
#define S3C64XX_GPJPUDSLP (S3C64XX_GPJ_BASE + 0x10)
#define S3C64XX_GPJ_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S3C64XX_GPJ_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S3C64XX_GPJ_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
#define S3C64XX_GPJ0_VD16 (0x02 << 0)
#define S3C64XX_GPJ1_VD17 (0x02 << 2)
#define S3C64XX_GPJ2_VD18 (0x02 << 4)
#define S3C64XX_GPJ3_VD19 (0x02 << 6)
#define S3C64XX_GPJ4_VD20 (0x02 << 8)
#define S3C64XX_GPJ5_VD21 (0x02 << 10)
#define S3C64XX_GPJ6_VD22 (0x02 << 12)
#define S3C64XX_GPJ7_VD23 (0x02 << 14)
#define S3C64XX_GPJ8_LCD_HSYNC (0x02 << 16)
#define S3C64XX_GPJ9_LCD_VSYNC (0x02 << 18)
#define S3C64XX_GPJ10_LCD_VDEN (0x02 << 20)
#define S3C64XX_GPJ11_LCD_VCLK (0x02 << 22)

View File

@@ -0,0 +1,54 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-n.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank N register and configuration 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 S3C64XX_GPNCON (S3C64XX_GPN_BASE + 0x00)
#define S3C64XX_GPNDAT (S3C64XX_GPN_BASE + 0x04)
#define S3C64XX_GPNPUD (S3C64XX_GPN_BASE + 0x08)
#define S3C64XX_GPN_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S3C64XX_GPN_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S3C64XX_GPN_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
#define S3C64XX_GPN0_EINT0 (0x02 << 0)
#define S3C64XX_GPN0_KP_ROW0 (0x03 << 0)
#define S3C64XX_GPN1_EINT1 (0x02 << 2)
#define S3C64XX_GPN1_KP_ROW1 (0x03 << 2)
#define S3C64XX_GPN2_EINT2 (0x02 << 4)
#define S3C64XX_GPN2_KP_ROW2 (0x03 << 4)
#define S3C64XX_GPN3_EINT3 (0x02 << 6)
#define S3C64XX_GPN3_KP_ROW3 (0x03 << 6)
#define S3C64XX_GPN4_EINT4 (0x02 << 8)
#define S3C64XX_GPN4_KP_ROW4 (0x03 << 8)
#define S3C64XX_GPN5_EINT5 (0x02 << 10)
#define S3C64XX_GPN5_KP_ROW5 (0x03 << 10)
#define S3C64XX_GPN6_EINT6 (0x02 << 12)
#define S3C64XX_GPN6_KP_ROW6 (0x03 << 12)
#define S3C64XX_GPN7_EINT7 (0x02 << 14)
#define S3C64XX_GPN7_KP_ROW7 (0x03 << 14)
#define S3C64XX_GPN8_EINT8 (0x02 << 16)
#define S3C64XX_GPN9_EINT9 (0x02 << 18)
#define S3C64XX_GPN10_EINT10 (0x02 << 20)
#define S3C64XX_GPN11_EINT11 (0x02 << 22)
#define S3C64XX_GPN12_EINT12 (0x02 << 24)
#define S3C64XX_GPN13_EINT13 (0x02 << 26)
#define S3C64XX_GPN14_EINT14 (0x02 << 28)
#define S3C64XX_GPN15_EINT15 (0x02 << 30)

View File

@@ -0,0 +1,70 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-o.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank O register and configuration 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 S3C64XX_GPOCON (S3C64XX_GPO_BASE + 0x00)
#define S3C64XX_GPODAT (S3C64XX_GPO_BASE + 0x04)
#define S3C64XX_GPOPUD (S3C64XX_GPO_BASE + 0x08)
#define S3C64XX_GPOCONSLP (S3C64XX_GPO_BASE + 0x0c)
#define S3C64XX_GPOPUDSLP (S3C64XX_GPO_BASE + 0x10)
#define S3C64XX_GPO_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S3C64XX_GPO_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S3C64XX_GPO_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
#define S3C64XX_GPO0_MEM0_nCS2 (0x02 << 0)
#define S3C64XX_GPO0_EINT_G7_0 (0x03 << 0)
#define S3C64XX_GPO1_MEM0_nCS3 (0x02 << 2)
#define S3C64XX_GPO1_EINT_G7_1 (0x03 << 2)
#define S3C64XX_GPO2_MEM0_nCS4 (0x02 << 4)
#define S3C64XX_GPO2_EINT_G7_2 (0x03 << 4)
#define S3C64XX_GPO3_MEM0_nCS5 (0x02 << 6)
#define S3C64XX_GPO3_EINT_G7_3 (0x03 << 6)
#define S3C64XX_GPO4_EINT_G7_4 (0x03 << 8)
#define S3C64XX_GPO5_EINT_G7_5 (0x03 << 10)
#define S3C64XX_GPO6_MEM0_ADDR6 (0x02 << 12)
#define S3C64XX_GPO6_EINT_G7_6 (0x03 << 12)
#define S3C64XX_GPO7_MEM0_ADDR7 (0x02 << 14)
#define S3C64XX_GPO7_EINT_G7_7 (0x03 << 14)
#define S3C64XX_GPO8_MEM0_ADDR8 (0x02 << 16)
#define S3C64XX_GPO8_EINT_G7_8 (0x03 << 16)
#define S3C64XX_GPO9_MEM0_ADDR9 (0x02 << 18)
#define S3C64XX_GPO9_EINT_G7_9 (0x03 << 18)
#define S3C64XX_GPO10_MEM0_ADDR10 (0x02 << 20)
#define S3C64XX_GPO10_EINT_G7_10 (0x03 << 20)
#define S3C64XX_GPO11_MEM0_ADDR11 (0x02 << 22)
#define S3C64XX_GPO11_EINT_G7_11 (0x03 << 22)
#define S3C64XX_GPO12_MEM0_ADDR12 (0x02 << 24)
#define S3C64XX_GPO12_EINT_G7_12 (0x03 << 24)
#define S3C64XX_GPO13_MEM0_ADDR13 (0x02 << 26)
#define S3C64XX_GPO13_EINT_G7_13 (0x03 << 26)
#define S3C64XX_GPO14_MEM0_ADDR14 (0x02 << 28)
#define S3C64XX_GPO14_EINT_G7_14 (0x03 << 28)
#define S3C64XX_GPO15_MEM0_ADDR15 (0x02 << 30)
#define S3C64XX_GPO15_EINT_G7_15 (0x03 << 30)

View File

@@ -0,0 +1,69 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-p.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank P register and configuration 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 S3C64XX_GPPCON (S3C64XX_GPP_BASE + 0x00)
#define S3C64XX_GPPDAT (S3C64XX_GPP_BASE + 0x04)
#define S3C64XX_GPPPUD (S3C64XX_GPP_BASE + 0x08)
#define S3C64XX_GPPCONSLP (S3C64XX_GPP_BASE + 0x0c)
#define S3C64XX_GPPPUDSLP (S3C64XX_GPP_BASE + 0x10)
#define S3C64XX_GPP_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S3C64XX_GPP_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S3C64XX_GPP_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
#define S3C64XX_GPP0_MEM0_ADDRV (0x02 << 0)
#define S3C64XX_GPP0_EINT_G8_0 (0x03 << 0)
#define S3C64XX_GPP1_MEM0_SMCLK (0x02 << 2)
#define S3C64XX_GPP1_EINT_G8_1 (0x03 << 2)
#define S3C64XX_GPP2_MEM0_nWAIT (0x02 << 4)
#define S3C64XX_GPP2_EINT_G8_2 (0x03 << 4)
#define S3C64XX_GPP3_MEM0_RDY0_ALE (0x02 << 6)
#define S3C64XX_GPP3_EINT_G8_3 (0x03 << 6)
#define S3C64XX_GPP4_MEM0_RDY1_CLE (0x02 << 8)
#define S3C64XX_GPP4_EINT_G8_4 (0x03 << 8)
#define S3C64XX_GPP5_MEM0_INTsm0_FWE (0x02 << 10)
#define S3C64XX_GPP5_EINT_G8_5 (0x03 << 10)
#define S3C64XX_GPP6_MEM0_(null) (0x02 << 12)
#define S3C64XX_GPP6_EINT_G8_6 (0x03 << 12)
#define S3C64XX_GPP7_MEM0_INTsm1_FRE (0x02 << 14)
#define S3C64XX_GPP7_EINT_G8_7 (0x03 << 14)
#define S3C64XX_GPP8_MEM0_RPn_RnB (0x02 << 16)
#define S3C64XX_GPP8_EINT_G8_8 (0x03 << 16)
#define S3C64XX_GPP9_MEM0_ATA_RESET (0x02 << 18)
#define S3C64XX_GPP9_EINT_G8_9 (0x03 << 18)
#define S3C64XX_GPP10_MEM0_ATA_INPACK (0x02 << 20)
#define S3C64XX_GPP10_EINT_G8_10 (0x03 << 20)
#define S3C64XX_GPP11_MEM0_ATA_REG (0x02 << 22)
#define S3C64XX_GPP11_EINT_G8_11 (0x03 << 22)
#define S3C64XX_GPP12_MEM0_ATA_WE (0x02 << 24)
#define S3C64XX_GPP12_EINT_G8_12 (0x03 << 24)
#define S3C64XX_GPP13_MEM0_ATA_OE (0x02 << 26)
#define S3C64XX_GPP13_EINT_G8_13 (0x03 << 26)
#define S3C64XX_GPP14_MEM0_ATA_CD (0x02 << 28)
#define S3C64XX_GPP14_EINT_G8_14 (0x03 << 28)

View File

@@ -0,0 +1,46 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-q.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* GPIO Bank Q register and configuration 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 S3C64XX_GPQCON (S3C64XX_GPQ_BASE + 0x00)
#define S3C64XX_GPQDAT (S3C64XX_GPQ_BASE + 0x04)
#define S3C64XX_GPQPUD (S3C64XX_GPQ_BASE + 0x08)
#define S3C64XX_GPQCONSLP (S3C64XX_GPQ_BASE + 0x0c)
#define S3C64XX_GPQPUDSLP (S3C64XX_GPQ_BASE + 0x10)
#define S3C64XX_GPQ_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
#define S3C64XX_GPQ_INPUT(__gpio) (0x0 << ((__gpio) * 2))
#define S3C64XX_GPQ_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
#define S3C64XX_GPQ0_MEM0_ADDR18_RAS (0x02 << 0)
#define S3C64XX_GPQ0_EINT_G9_0 (0x03 << 0)
#define S3C64XX_GPQ1_MEM0_ADDR19_CAS (0x02 << 2)
#define S3C64XX_GPQ1_EINT_G9_1 (0x03 << 2)
#define S3C64XX_GPQ2_EINT_G9_2 (0x03 << 4)
#define S3C64XX_GPQ3_EINT_G9_3 (0x03 << 6)
#define S3C64XX_GPQ4_EINT_G9_4 (0x03 << 8)
#define S3C64XX_GPQ5_EINT_G9_5 (0x03 << 10)
#define S3C64XX_GPQ6_EINT_G9_6 (0x03 << 12)
#define S3C64XX_GPQ7_MEM0_ADDR17_WENDMC (0x02 << 14)
#define S3C64XX_GPQ7_EINT_G9_7 (0x03 << 14)
#define S3C64XX_GPQ8_MEM0_ADDR16_APDMC (0x02 << 16)
#define S3C64XX_GPQ8_EINT_G9_8 (0x03 << 16)

View File

@@ -0,0 +1,210 @@
/* linux/arch/arm/plat-s3c64xx/include/mach/irqs.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - Common IRQ support
*/
#ifndef __ASM_PLAT_S3C64XX_IRQS_H
#define __ASM_PLAT_S3C64XX_IRQS_H __FILE__
/* we keep the first set of CPU IRQs out of the range of
* the ISA space, so that the PC104 has them to itself
* and we don't end up having to do horrible things to the
* standard ISA drivers....
*
* note, since we're using the VICs, our start must be a
* mulitple of 32 to allow the common code to work
*/
#define S3C_IRQ_OFFSET (32)
#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET)
#define S3C_VIC0_BASE S3C_IRQ(0)
#define S3C_VIC1_BASE S3C_IRQ(32)
/* UART interrupts, each UART has 4 intterupts per channel so
* use the space between the ISA and S3C main interrupts. Note, these
* are not in the same order as the S3C24XX series! */
#define IRQ_S3CUART_BASE0 (16)
#define IRQ_S3CUART_BASE1 (20)
#define IRQ_S3CUART_BASE2 (24)
#define IRQ_S3CUART_BASE3 (28)
#define UART_IRQ_RXD (0)
#define UART_IRQ_ERR (1)
#define UART_IRQ_TXD (2)
#define UART_IRQ_MODEM (3)
#define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
#define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
#define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
#define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
#define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
#define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
#define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
#define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
#define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
#define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
#define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
#define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
/* VIC based IRQs */
#define S3C64XX_IRQ_VIC0(x) (S3C_VIC0_BASE + (x))
#define S3C64XX_IRQ_VIC1(x) (S3C_VIC1_BASE + (x))
/* VIC0 */
#define IRQ_EINT0_3 S3C64XX_IRQ_VIC0(0)
#define IRQ_EINT4_11 S3C64XX_IRQ_VIC0(1)
#define IRQ_RTC_TIC S3C64XX_IRQ_VIC0(2)
#define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3)
#define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4)
#define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5)
#define IRQ_S3C6410_IIC1 S3C64XX_IRQ_VIC0(5)
#define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6)
#define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6)
#define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7)
#define IRQ_S3C6410_G3D S3C64XX_IRQ_VIC0(8)
#define IRQ_S3C6400_CAMIF_WE_P S3C64XX_IRQ_VIC0(8)
#define IRQ_POST0 S3C64XX_IRQ_VIC0(9)
#define IRQ_ROTATOR S3C64XX_IRQ_VIC0(10)
#define IRQ_2D S3C64XX_IRQ_VIC0(11)
#define IRQ_TVENC S3C64XX_IRQ_VIC0(12)
#define IRQ_SCALER S3C64XX_IRQ_VIC0(13)
#define IRQ_BATF S3C64XX_IRQ_VIC0(14)
#define IRQ_JPEG S3C64XX_IRQ_VIC0(15)
#define IRQ_MFC S3C64XX_IRQ_VIC0(16)
#define IRQ_SDMA0 S3C64XX_IRQ_VIC0(17)
#define IRQ_SDMA1 S3C64XX_IRQ_VIC0(18)
#define IRQ_ARM_DMAERR S3C64XX_IRQ_VIC0(19)
#define IRQ_ARM_DMA S3C64XX_IRQ_VIC0(20)
#define IRQ_ARM_DMAS S3C64XX_IRQ_VIC0(21)
#define IRQ_KEYPAD S3C64XX_IRQ_VIC0(22)
#define IRQ_TIMER0_VIC S3C64XX_IRQ_VIC0(23)
#define IRQ_TIMER1_VIC S3C64XX_IRQ_VIC0(24)
#define IRQ_TIMER2_VIC S3C64XX_IRQ_VIC0(25)
#define IRQ_WDT S3C64XX_IRQ_VIC0(26)
#define IRQ_TIMER3_VIC S3C64XX_IRQ_VIC0(27)
#define IRQ_TIMER4_VIC S3C64XX_IRQ_VIC0(28)
#define IRQ_LCD_FIFO S3C64XX_IRQ_VIC0(29)
#define IRQ_LCD_VSYNC S3C64XX_IRQ_VIC0(30)
#define IRQ_LCD_SYSTEM S3C64XX_IRQ_VIC0(31)
/* VIC1 */
#define IRQ_EINT12_19 S3C64XX_IRQ_VIC1(0)
#define IRQ_EINT20_27 S3C64XX_IRQ_VIC1(1)
#define IRQ_PCM0 S3C64XX_IRQ_VIC1(2)
#define IRQ_PCM1 S3C64XX_IRQ_VIC1(3)
#define IRQ_AC97 S3C64XX_IRQ_VIC1(4)
#define IRQ_UART0 S3C64XX_IRQ_VIC1(5)
#define IRQ_UART1 S3C64XX_IRQ_VIC1(6)
#define IRQ_UART2 S3C64XX_IRQ_VIC1(7)
#define IRQ_UART3 S3C64XX_IRQ_VIC1(8)
#define IRQ_DMA0 S3C64XX_IRQ_VIC1(9)
#define IRQ_DMA1 S3C64XX_IRQ_VIC1(10)
#define IRQ_ONENAND0 S3C64XX_IRQ_VIC1(11)
#define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12)
#define IRQ_NFC S3C64XX_IRQ_VIC1(13)
#define IRQ_CFCON S3C64XX_IRQ_VIC1(14)
#define IRQ_USBH S3C64XX_IRQ_VIC1(15)
#define IRQ_SPI0 S3C64XX_IRQ_VIC1(16)
#define IRQ_SPI1 S3C64XX_IRQ_VIC1(17)
#define IRQ_IIC S3C64XX_IRQ_VIC1(18)
#define IRQ_HSItx S3C64XX_IRQ_VIC1(19)
#define IRQ_HSIrx S3C64XX_IRQ_VIC1(20)
#define IRQ_RESERVED S3C64XX_IRQ_VIC1(21)
#define IRQ_MSM S3C64XX_IRQ_VIC1(22)
#define IRQ_HOSTIF S3C64XX_IRQ_VIC1(23)
#define IRQ_HSMMC0 S3C64XX_IRQ_VIC1(24)
#define IRQ_HSMMC1 S3C64XX_IRQ_VIC1(25)
#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */
#define IRQ_OTG S3C64XX_IRQ_VIC1(26)
#define IRQ_IRDA S3C64XX_IRQ_VIC1(27)
#define IRQ_RTC_ALARM S3C64XX_IRQ_VIC1(28)
#define IRQ_SEC S3C64XX_IRQ_VIC1(29)
#define IRQ_PENDN S3C64XX_IRQ_VIC1(30)
#define IRQ_TC IRQ_PENDN
#define IRQ_ADC S3C64XX_IRQ_VIC1(31)
#define S3C64XX_TIMER_IRQ(x) S3C_IRQ(64 + (x))
#define IRQ_TIMER0 S3C64XX_TIMER_IRQ(0)
#define IRQ_TIMER1 S3C64XX_TIMER_IRQ(1)
#define IRQ_TIMER2 S3C64XX_TIMER_IRQ(2)
#define IRQ_TIMER3 S3C64XX_TIMER_IRQ(3)
#define IRQ_TIMER4 S3C64XX_TIMER_IRQ(4)
/* compatibility for device defines */
#define IRQ_IIC1 IRQ_S3C6410_IIC1
/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
* we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
* which we place after the pair of VICs. */
#define S3C_IRQ_EINT_BASE S3C_IRQ(64+5)
#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
#define IRQ_EINT(x) S3C_EINT(x)
#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0))
/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
* that they are sourced from the GPIO pins but with a different scheme for
* priority and source indication.
*
* The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
* interrupts, but for historical reasons they are kept apart from these
* next interrupts.
*
* Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
* machine specific support files.
*/
#define IRQ_EINT_GROUP1_NR (15)
#define IRQ_EINT_GROUP2_NR (8)
#define IRQ_EINT_GROUP3_NR (5)
#define IRQ_EINT_GROUP4_NR (14)
#define IRQ_EINT_GROUP5_NR (7)
#define IRQ_EINT_GROUP6_NR (10)
#define IRQ_EINT_GROUP7_NR (16)
#define IRQ_EINT_GROUP8_NR (15)
#define IRQ_EINT_GROUP9_NR (9)
#define IRQ_EINT_GROUP_BASE S3C_EINT(28)
#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0x00)
#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
#define IRQ_EINT_GROUP3_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
#define IRQ_EINT_GROUP4_BASE (IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
#define IRQ_EINT_GROUP7_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
#define IRQ_EINT_GROUP9_BASE (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##_BASE + (no))
/* Define a group of interrupts for board-specific use (eg, for MFD
* interrupt controllers). */
#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
#define IRQ_BOARD_NR 16
#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
/* Set the default NR_IRQS */
#define NR_IRQS (IRQ_BOARD_END + 1)
#endif /* __ASM_PLAT_S3C64XX_IRQS_H */

View File

@@ -0,0 +1,74 @@
/* arch/arm/plat-s3c64xx/include/plat/pll.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX PLL code
*
* 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 S3C6400_PLL_MDIV_MASK ((1 << (25-16+1)) - 1)
#define S3C6400_PLL_PDIV_MASK ((1 << (13-8+1)) - 1)
#define S3C6400_PLL_SDIV_MASK ((1 << (2-0+1)) - 1)
#define S3C6400_PLL_MDIV_SHIFT (16)
#define S3C6400_PLL_PDIV_SHIFT (8)
#define S3C6400_PLL_SDIV_SHIFT (0)
#include <asm/div64.h>
static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
u32 pllcon)
{
u32 mdiv, pdiv, sdiv;
u64 fvco = baseclk;
mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
fvco *= mdiv;
do_div(fvco, (pdiv << sdiv));
return (unsigned long)fvco;
}
#define S3C6400_EPLL_MDIV_MASK ((1 << (23-16)) - 1)
#define S3C6400_EPLL_PDIV_MASK ((1 << (13-8)) - 1)
#define S3C6400_EPLL_SDIV_MASK ((1 << (2-0)) - 1)
#define S3C6400_EPLL_MDIV_SHIFT (16)
#define S3C6400_EPLL_PDIV_SHIFT (8)
#define S3C6400_EPLL_SDIV_SHIFT (0)
#define S3C6400_EPLL_KDIV_MASK (0xffff)
static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
{
unsigned long result;
u32 epll0 = __raw_readl(S3C_EPLL_CON0);
u32 epll1 = __raw_readl(S3C_EPLL_CON1);
u32 mdiv, pdiv, sdiv, kdiv;
u64 tmp;
mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
/* We need to multiple baseclk by mdiv (the integer part) and kdiv
* which is in 2^16ths, so shift mdiv up (does not overflow) and
* add kdiv before multiplying. The use of tmp is to avoid any
* overflows before shifting bac down into result when multipling
* by the mdiv and kdiv pair.
*/
tmp = baseclk;
tmp *= (mdiv << 16) + kdiv;
do_div(tmp, (pdiv << sdiv));
result = tmp >> 16;
return result;
}

View File

@@ -0,0 +1,98 @@
/* linux/arch/arm/plat-s3c64xx/include/plat/pm-core.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - PM core support for arch/arm/plat-s3c/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.
*/
#include <plat/regs-gpio.h>
static inline void s3c_pm_debug_init_uart(void)
{
u32 tmp = __raw_readl(S3C_PCLK_GATE);
/* As a note, since the S3C64XX UARTs generally have multiple
* clock sources, we simply enable PCLK at the moment and hope
* that the resume settings for the UART are suitable for the
* use with PCLK.
*/
tmp |= S3C_CLKCON_PCLK_UART0;
tmp |= S3C_CLKCON_PCLK_UART1;
tmp |= S3C_CLKCON_PCLK_UART2;
tmp |= S3C_CLKCON_PCLK_UART3;
__raw_writel(tmp, S3C_PCLK_GATE);
udelay(10);
}
static inline void s3c_pm_arch_prepare_irqs(void)
{
/* VIC should have already been taken care of */
/* clear any pending EINT0 interrupts */
__raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
}
static inline void s3c_pm_arch_stop_clocks(void)
{
}
static inline void s3c_pm_arch_show_resume_irqs(void)
{
}
/* make these defines, we currently do not have any need to change
* the IRQ wake controls depending on the CPU we are running on */
#define s3c_irqwake_eintallow ((1 << 28) - 1)
#define s3c_irqwake_intallow (0)
static inline void s3c_pm_arch_update_uart(void __iomem *regs,
struct pm_uart_save *save)
{
u32 ucon = __raw_readl(regs + S3C2410_UCON);
u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
u32 new_ucon;
u32 delta;
/* S3C64XX UART blocks only support level interrupts, so ensure that
* when we restore unused UART blocks we force the level interrupt
* settigs. */
save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
/* We have a constraint on changing the clock type of the UART
* between UCLKx and PCLK, so ensure that when we restore UCON
* that the CLK field is correctly modified if the bootloader
* has changed anything.
*/
if (ucon_clk != save_clk) {
new_ucon = save->ucon;
delta = ucon_clk ^ save_clk;
/* change from UCLKx => wrong PCLK,
* either UCLK can be tested for by a bit-test
* with UCLK0 */
if (ucon_clk & S3C6400_UCON_UCLK0 &&
!(save_clk & S3C6400_UCON_UCLK0) &&
delta & S3C6400_UCON_PCLK2) {
new_ucon &= ~S3C6400_UCON_UCLK0;
} else if (delta == S3C6400_UCON_PCLK2) {
/* as an precaution, don't change from
* PCLK2 => PCLK or vice-versa */
new_ucon ^= S3C6400_UCON_PCLK2;
}
S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
ucon, new_ucon, save->ucon);
save->ucon = new_ucon;
}
}

View File

@@ -0,0 +1,225 @@
/* arch/arm/plat-s3c64xx/include/plat/regs-clock.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX clock 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 __PLAT_REGS_CLOCK_H
#define __PLAT_REGS_CLOCK_H __FILE__
#define S3C_CLKREG(x) (S3C_VA_SYS + (x))
#define S3C_APLL_LOCK S3C_CLKREG(0x00)
#define S3C_MPLL_LOCK S3C_CLKREG(0x04)
#define S3C_EPLL_LOCK S3C_CLKREG(0x08)
#define S3C_APLL_CON S3C_CLKREG(0x0C)
#define S3C_MPLL_CON S3C_CLKREG(0x10)
#define S3C_EPLL_CON0 S3C_CLKREG(0x14)
#define S3C_EPLL_CON1 S3C_CLKREG(0x18)
#define S3C_CLK_SRC S3C_CLKREG(0x1C)
#define S3C_CLK_DIV0 S3C_CLKREG(0x20)
#define S3C_CLK_DIV1 S3C_CLKREG(0x24)
#define S3C_CLK_DIV2 S3C_CLKREG(0x28)
#define S3C_CLK_OUT S3C_CLKREG(0x2C)
#define S3C_HCLK_GATE S3C_CLKREG(0x30)
#define S3C_PCLK_GATE S3C_CLKREG(0x34)
#define S3C_SCLK_GATE S3C_CLKREG(0x38)
#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
/* CLKDIV0 */
#define S3C6400_CLKDIV0_MFC_MASK (0xf << 28)
#define S3C6400_CLKDIV0_MFC_SHIFT (28)
#define S3C6400_CLKDIV0_JPEG_MASK (0xf << 24)
#define S3C6400_CLKDIV0_JPEG_SHIFT (24)
#define S3C6400_CLKDIV0_CAM_MASK (0xf << 20)
#define S3C6400_CLKDIV0_CAM_SHIFT (20)
#define S3C6400_CLKDIV0_SECURITY_MASK (0x3 << 18)
#define S3C6400_CLKDIV0_SECURITY_SHIFT (18)
#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
#define S3C6400_CLKDIV0_PCLK_SHIFT (12)
#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9)
#define S3C6400_CLKDIV0_HCLK2_SHIFT (9)
#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8)
#define S3C6400_CLKDIV0_HCLK_SHIFT (8)
#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4)
#define S3C6400_CLKDIV0_MPLL_SHIFT (4)
#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0)
#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0)
#define S3C6400_CLKDIV0_ARM_SHIFT (0)
/* CLKDIV1 */
#define S3C6410_CLKDIV1_FIMC_MASK (0xf << 24)
#define S3C6410_CLKDIV1_FIMC_SHIFT (24)
#define S3C6400_CLKDIV1_UHOST_MASK (0xf << 20)
#define S3C6400_CLKDIV1_UHOST_SHIFT (20)
#define S3C6400_CLKDIV1_SCALER_MASK (0xf << 16)
#define S3C6400_CLKDIV1_SCALER_SHIFT (16)
#define S3C6400_CLKDIV1_LCD_MASK (0xf << 12)
#define S3C6400_CLKDIV1_LCD_SHIFT (12)
#define S3C6400_CLKDIV1_MMC2_MASK (0xf << 8)
#define S3C6400_CLKDIV1_MMC2_SHIFT (8)
#define S3C6400_CLKDIV1_MMC1_MASK (0xf << 4)
#define S3C6400_CLKDIV1_MMC1_SHIFT (4)
#define S3C6400_CLKDIV1_MMC0_MASK (0xf << 0)
#define S3C6400_CLKDIV1_MMC0_SHIFT (0)
/* CLKDIV2 */
#define S3C6410_CLKDIV2_AUDIO2_MASK (0xf << 24)
#define S3C6410_CLKDIV2_AUDIO2_SHIFT (24)
#define S3C6400_CLKDIV2_IRDA_MASK (0xf << 20)
#define S3C6400_CLKDIV2_IRDA_SHIFT (20)
#define S3C6400_CLKDIV2_UART_MASK (0xf << 16)
#define S3C6400_CLKDIV2_UART_SHIFT (16)
#define S3C6400_CLKDIV2_AUDIO1_MASK (0xf << 12)
#define S3C6400_CLKDIV2_AUDIO1_SHIFT (12)
#define S3C6400_CLKDIV2_AUDIO0_MASK (0xf << 8)
#define S3C6400_CLKDIV2_AUDIO0_SHIFT (8)
#define S3C6400_CLKDIV2_SPI1_MASK (0xf << 4)
#define S3C6400_CLKDIV2_SPI1_SHIFT (4)
#define S3C6400_CLKDIV2_SPI0_MASK (0xf << 0)
#define S3C6400_CLKDIV2_SPI0_SHIFT (0)
/* HCLK GATE Registers */
#define S3C_CLKCON_HCLK_3DSE (1<<31)
#define S3C_CLKCON_HCLK_UHOST (1<<29)
#define S3C_CLKCON_HCLK_SECUR (1<<28)
#define S3C_CLKCON_HCLK_SDMA1 (1<<27)
#define S3C_CLKCON_HCLK_SDMA0 (1<<26)
#define S3C_CLKCON_HCLK_IROM (1<<25)
#define S3C_CLKCON_HCLK_DDR1 (1<<24)
#define S3C_CLKCON_HCLK_DDR0 (1<<23)
#define S3C_CLKCON_HCLK_MEM1 (1<<22)
#define S3C_CLKCON_HCLK_MEM0 (1<<21)
#define S3C_CLKCON_HCLK_USB (1<<20)
#define S3C_CLKCON_HCLK_HSMMC2 (1<<19)
#define S3C_CLKCON_HCLK_HSMMC1 (1<<18)
#define S3C_CLKCON_HCLK_HSMMC0 (1<<17)
#define S3C_CLKCON_HCLK_MDP (1<<16)
#define S3C_CLKCON_HCLK_DHOST (1<<15)
#define S3C_CLKCON_HCLK_IHOST (1<<14)
#define S3C_CLKCON_HCLK_DMA1 (1<<13)
#define S3C_CLKCON_HCLK_DMA0 (1<<12)
#define S3C_CLKCON_HCLK_JPEG (1<<11)
#define S3C_CLKCON_HCLK_CAMIF (1<<10)
#define S3C_CLKCON_HCLK_SCALER (1<<9)
#define S3C_CLKCON_HCLK_2D (1<<8)
#define S3C_CLKCON_HCLK_TV (1<<7)
#define S3C_CLKCON_HCLK_POST0 (1<<5)
#define S3C_CLKCON_HCLK_ROT (1<<4)
#define S3C_CLKCON_HCLK_LCD (1<<3)
#define S3C_CLKCON_HCLK_TZIC (1<<2)
#define S3C_CLKCON_HCLK_INTC (1<<1)
#define S3C_CLKCON_HCLK_MFC (1<<0)
/* PCLK GATE Registers */
#define S3C6410_CLKCON_PCLK_I2C1 (1<<27)
#define S3C6410_CLKCON_PCLK_IIS2 (1<<26)
#define S3C_CLKCON_PCLK_SKEY (1<<24)
#define S3C_CLKCON_PCLK_CHIPID (1<<23)
#define S3C_CLKCON_PCLK_SPI1 (1<<22)
#define S3C_CLKCON_PCLK_SPI0 (1<<21)
#define S3C_CLKCON_PCLK_HSIRX (1<<20)
#define S3C_CLKCON_PCLK_HSITX (1<<19)
#define S3C_CLKCON_PCLK_GPIO (1<<18)
#define S3C_CLKCON_PCLK_IIC (1<<17)
#define S3C_CLKCON_PCLK_IIS1 (1<<16)
#define S3C_CLKCON_PCLK_IIS0 (1<<15)
#define S3C_CLKCON_PCLK_AC97 (1<<14)
#define S3C_CLKCON_PCLK_TZPC (1<<13)
#define S3C_CLKCON_PCLK_TSADC (1<<12)
#define S3C_CLKCON_PCLK_KEYPAD (1<<11)
#define S3C_CLKCON_PCLK_IRDA (1<<10)
#define S3C_CLKCON_PCLK_PCM1 (1<<9)
#define S3C_CLKCON_PCLK_PCM0 (1<<8)
#define S3C_CLKCON_PCLK_PWM (1<<7)
#define S3C_CLKCON_PCLK_RTC (1<<6)
#define S3C_CLKCON_PCLK_WDT (1<<5)
#define S3C_CLKCON_PCLK_UART3 (1<<4)
#define S3C_CLKCON_PCLK_UART2 (1<<3)
#define S3C_CLKCON_PCLK_UART1 (1<<2)
#define S3C_CLKCON_PCLK_UART0 (1<<1)
#define S3C_CLKCON_PCLK_MFC (1<<0)
/* SCLK GATE Registers */
#define S3C_CLKCON_SCLK_UHOST (1<<30)
#define S3C_CLKCON_SCLK_MMC2_48 (1<<29)
#define S3C_CLKCON_SCLK_MMC1_48 (1<<28)
#define S3C_CLKCON_SCLK_MMC0_48 (1<<27)
#define S3C_CLKCON_SCLK_MMC2 (1<<26)
#define S3C_CLKCON_SCLK_MMC1 (1<<25)
#define S3C_CLKCON_SCLK_MMC0 (1<<24)
#define S3C_CLKCON_SCLK_SPI1_48 (1<<23)
#define S3C_CLKCON_SCLK_SPI0_48 (1<<22)
#define S3C_CLKCON_SCLK_SPI1 (1<<21)
#define S3C_CLKCON_SCLK_SPI0 (1<<20)
#define S3C_CLKCON_SCLK_DAC27 (1<<19)
#define S3C_CLKCON_SCLK_TV27 (1<<18)
#define S3C_CLKCON_SCLK_SCALER27 (1<<17)
#define S3C_CLKCON_SCLK_SCALER (1<<16)
#define S3C_CLKCON_SCLK_LCD27 (1<<15)
#define S3C_CLKCON_SCLK_LCD (1<<14)
#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13)
#define S3C6410_CLKCON_FIMC (1<<13)
#define S3C_CLKCON_SCLK_POST0_27 (1<<12)
#define S3C6400_CLKCON_SCLK_POST1 (1<<11)
#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11)
#define S3C_CLKCON_SCLK_POST0 (1<<10)
#define S3C_CLKCON_SCLK_AUDIO1 (1<<9)
#define S3C_CLKCON_SCLK_AUDIO0 (1<<8)
#define S3C_CLKCON_SCLK_SECUR (1<<7)
#define S3C_CLKCON_SCLK_IRDA (1<<6)
#define S3C_CLKCON_SCLK_UART (1<<5)
#define S3C_CLKCON_SCLK_ONENAND (1<<4)
#define S3C_CLKCON_SCLK_MFC (1<<3)
#define S3C_CLKCON_SCLK_CAM (1<<2)
#define S3C_CLKCON_SCLK_JPEG (1<<1)
/* CLKSRC */
#define S3C6400_CLKSRC_APLL_MOUT (1 << 0)
#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1)
#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2)
#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0)
#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1)
#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
#define S3C6400_CLKSRC_MFC (1 << 4)
#define S3C6410_CLKSRC_TV27_MASK (0x1 << 31)
#define S3C6410_CLKSRC_TV27_SHIFT (31)
#define S3C6410_CLKSRC_DAC27_MASK (0x1 << 30)
#define S3C6410_CLKSRC_DAC27_SHIFT (30)
#define S3C6400_CLKSRC_SCALER_MASK (0x3 << 28)
#define S3C6400_CLKSRC_SCALER_SHIFT (28)
#define S3C6400_CLKSRC_LCD_MASK (0x3 << 26)
#define S3C6400_CLKSRC_LCD_SHIFT (26)
#define S3C6400_CLKSRC_IRDA_MASK (0x3 << 24)
#define S3C6400_CLKSRC_IRDA_SHIFT (24)
#define S3C6400_CLKSRC_MMC2_MASK (0x3 << 22)
#define S3C6400_CLKSRC_MMC2_SHIFT (22)
#define S3C6400_CLKSRC_MMC1_MASK (0x3 << 20)
#define S3C6400_CLKSRC_MMC1_SHIFT (20)
#define S3C6400_CLKSRC_MMC0_MASK (0x3 << 18)
#define S3C6400_CLKSRC_MMC0_SHIFT (18)
#define S3C6400_CLKSRC_SPI1_MASK (0x3 << 16)
#define S3C6400_CLKSRC_SPI1_SHIFT (16)
#define S3C6400_CLKSRC_SPI0_MASK (0x3 << 14)
#define S3C6400_CLKSRC_SPI0_SHIFT (14)
#define S3C6400_CLKSRC_UART_MASK (0x1 << 13)
#define S3C6400_CLKSRC_UART_SHIFT (13)
#define S3C6400_CLKSRC_AUDIO1_MASK (0x7 << 10)
#define S3C6400_CLKSRC_AUDIO1_SHIFT (10)
#define S3C6400_CLKSRC_AUDIO0_MASK (0x7 << 7)
#define S3C6400_CLKSRC_AUDIO0_SHIFT (7)
#define S3C6400_CLKSRC_UHOST_MASK (0x3 << 5)
#define S3C6400_CLKSRC_UHOST_SHIFT (5)
#endif /* _PLAT_REGS_CLOCK_H */

View File

@@ -0,0 +1,25 @@
/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio-memport.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - GPIO memory port register definitions
*/
#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H
#define __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H __FILE__
#define S3C64XX_MEM0CONSTOP S3C64XX_GPIOREG(0x1B0)
#define S3C64XX_MEM1CONSTOP S3C64XX_GPIOREG(0x1B4)
#define S3C64XX_MEM0CONSLP0 S3C64XX_GPIOREG(0x1C0)
#define S3C64XX_MEM0CONSLP1 S3C64XX_GPIOREG(0x1C4)
#define S3C64XX_MEM1CONSLP S3C64XX_GPIOREG(0x1C8)
#define S3C64XX_MEM0DRVCON S3C64XX_GPIOREG(0x1D0)
#define S3C64XX_MEM1DRVCON S3C64XX_GPIOREG(0x1D4)
#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H */

View File

@@ -0,0 +1,187 @@
/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - GPIO register definitions
*/
#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H
#define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__
/* Base addresses for each of the banks */
#define S3C64XX_GPIOREG(reg) (S3C64XX_VA_GPIO + (reg))
#define S3C64XX_GPA_BASE S3C64XX_GPIOREG(0x0000)
#define S3C64XX_GPB_BASE S3C64XX_GPIOREG(0x0020)
#define S3C64XX_GPC_BASE S3C64XX_GPIOREG(0x0040)
#define S3C64XX_GPD_BASE S3C64XX_GPIOREG(0x0060)
#define S3C64XX_GPE_BASE S3C64XX_GPIOREG(0x0080)
#define S3C64XX_GPF_BASE S3C64XX_GPIOREG(0x00A0)
#define S3C64XX_GPG_BASE S3C64XX_GPIOREG(0x00C0)
#define S3C64XX_GPH_BASE S3C64XX_GPIOREG(0x00E0)
#define S3C64XX_GPI_BASE S3C64XX_GPIOREG(0x0100)
#define S3C64XX_GPJ_BASE S3C64XX_GPIOREG(0x0120)
#define S3C64XX_GPK_BASE S3C64XX_GPIOREG(0x0800)
#define S3C64XX_GPL_BASE S3C64XX_GPIOREG(0x0810)
#define S3C64XX_GPM_BASE S3C64XX_GPIOREG(0x0820)
#define S3C64XX_GPN_BASE S3C64XX_GPIOREG(0x0830)
#define S3C64XX_GPO_BASE S3C64XX_GPIOREG(0x0140)
#define S3C64XX_GPP_BASE S3C64XX_GPIOREG(0x0160)
#define S3C64XX_GPQ_BASE S3C64XX_GPIOREG(0x0180)
/* SPCON */
#define S3C64XX_SPCON S3C64XX_GPIOREG(0x1A0)
#define S3C64XX_SPCON_DRVCON_CAM_MASK (0x3 << 30)
#define S3C64XX_SPCON_DRVCON_CAM_SHIFT (30)
#define S3C64XX_SPCON_DRVCON_CAM_2mA (0x0 << 30)
#define S3C64XX_SPCON_DRVCON_CAM_4mA (0x1 << 30)
#define S3C64XX_SPCON_DRVCON_CAM_7mA (0x2 << 30)
#define S3C64XX_SPCON_DRVCON_CAM_9mA (0x3 << 30)
#define S3C64XX_SPCON_DRVCON_HSSPI_MASK (0x3 << 28)
#define S3C64XX_SPCON_DRVCON_HSSPI_SHIFT (28)
#define S3C64XX_SPCON_DRVCON_HSSPI_2mA (0x0 << 28)
#define S3C64XX_SPCON_DRVCON_HSSPI_4mA (0x1 << 28)
#define S3C64XX_SPCON_DRVCON_HSSPI_7mA (0x2 << 28)
#define S3C64XX_SPCON_DRVCON_HSSPI_9mA (0x3 << 28)
#define S3C64XX_SPCON_DRVCON_HSMMC_MASK (0x3 << 26)
#define S3C64XX_SPCON_DRVCON_HSMMC_SHIFT (26)
#define S3C64XX_SPCON_DRVCON_HSMMC_2mA (0x0 << 26)
#define S3C64XX_SPCON_DRVCON_HSMMC_4mA (0x1 << 26)
#define S3C64XX_SPCON_DRVCON_HSMMC_7mA (0x2 << 26)
#define S3C64XX_SPCON_DRVCON_HSMMC_9mA (0x3 << 26)
#define S3C64XX_SPCON_DRVCON_LCD_MASK (0x3 << 24)
#define S3C64XX_SPCON_DRVCON_LCD_SHIFT (24)
#define S3C64XX_SPCON_DRVCON_LCD_2mA (0x0 << 24)
#define S3C64XX_SPCON_DRVCON_LCD_4mA (0x1 << 24)
#define S3C64XX_SPCON_DRVCON_LCD_7mA (0x2 << 24)
#define S3C64XX_SPCON_DRVCON_LCD_9mA (0x3 << 24)
#define S3C64XX_SPCON_DRVCON_MODEM_MASK (0x3 << 22)
#define S3C64XX_SPCON_DRVCON_MODEM_SHIFT (22)
#define S3C64XX_SPCON_DRVCON_MODEM_2mA (0x0 << 22)
#define S3C64XX_SPCON_DRVCON_MODEM_4mA (0x1 << 22)
#define S3C64XX_SPCON_DRVCON_MODEM_7mA (0x2 << 22)
#define S3C64XX_SPCON_DRVCON_MODEM_9mA (0x3 << 22)
#define S3C64XX_SPCON_nRSTOUT_OEN (1 << 21)
#define S3C64XX_SPCON_DRVCON_SPICLK1_MASK (0x3 << 18)
#define S3C64XX_SPCON_DRVCON_SPICLK1_SHIFT (18)
#define S3C64XX_SPCON_DRVCON_SPICLK1_2mA (0x0 << 18)
#define S3C64XX_SPCON_DRVCON_SPICLK1_4mA (0x1 << 18)
#define S3C64XX_SPCON_DRVCON_SPICLK1_7mA (0x2 << 18)
#define S3C64XX_SPCON_DRVCON_SPICLK1_9mA (0x3 << 18)
#define S3C64XX_SPCON_MEM1_DQS_PUD_MASK (0x3 << 16)
#define S3C64XX_SPCON_MEM1_DQS_PUD_SHIFT (16)
#define S3C64XX_SPCON_MEM1_DQS_PUD_DISABLED (0x0 << 16)
#define S3C64XX_SPCON_MEM1_DQS_PUD_DOWN (0x1 << 16)
#define S3C64XX_SPCON_MEM1_DQS_PUD_UP (0x2 << 16)
#define S3C64XX_SPCON_MEM1_D_PUD1_MASK (0x3 << 14)
#define S3C64XX_SPCON_MEM1_D_PUD1_SHIFT (14)
#define S3C64XX_SPCON_MEM1_D_PUD1_DISABLED (0x0 << 14)
#define S3C64XX_SPCON_MEM1_D_PUD1_DOWN (0x1 << 14)
#define S3C64XX_SPCON_MEM1_D_PUD1_UP (0x2 << 14)
#define S3C64XX_SPCON_MEM1_D_PUD0_MASK (0x3 << 12)
#define S3C64XX_SPCON_MEM1_D_PUD0_SHIFT (12)
#define S3C64XX_SPCON_MEM1_D_PUD0_DISABLED (0x0 << 12)
#define S3C64XX_SPCON_MEM1_D_PUD0_DOWN (0x1 << 12)
#define S3C64XX_SPCON_MEM1_D_PUD0_UP (0x2 << 12)
#define S3C64XX_SPCON_MEM0_D_PUD_MASK (0x3 << 8)
#define S3C64XX_SPCON_MEM0_D_PUD_SHIFT (8)
#define S3C64XX_SPCON_MEM0_D_PUD_DISABLED (0x0 << 8)
#define S3C64XX_SPCON_MEM0_D_PUD_DOWN (0x1 << 8)
#define S3C64XX_SPCON_MEM0_D_PUD_UP (0x2 << 8)
#define S3C64XX_SPCON_USBH_DMPD (1 << 7)
#define S3C64XX_SPCON_USBH_DPPD (1 << 6)
#define S3C64XX_SPCON_USBH_PUSW2 (1 << 5)
#define S3C64XX_SPCON_USBH_PUSW1 (1 << 4)
#define S3C64XX_SPCON_USBH_SUSPND (1 << 3)
#define S3C64XX_SPCON_LCD_SEL_MASK (0x3 << 0)
#define S3C64XX_SPCON_LCD_SEL_SHIFT (0)
#define S3C64XX_SPCON_LCD_SEL_HOST (0x0 << 0)
#define S3C64XX_SPCON_LCD_SEL_RGB (0x1 << 0)
#define S3C64XX_SPCON_LCD_SEL_606_656 (0x2 << 0)
/* External interrupt registers */
#define S3C64XX_EINT12CON S3C64XX_GPIOREG(0x200)
#define S3C64XX_EINT34CON S3C64XX_GPIOREG(0x204)
#define S3C64XX_EINT56CON S3C64XX_GPIOREG(0x208)
#define S3C64XX_EINT78CON S3C64XX_GPIOREG(0x20C)
#define S3C64XX_EINT9CON S3C64XX_GPIOREG(0x210)
#define S3C64XX_EINT12FLTCON S3C64XX_GPIOREG(0x220)
#define S3C64XX_EINT34FLTCON S3C64XX_GPIOREG(0x224)
#define S3C64XX_EINT56FLTCON S3C64XX_GPIOREG(0x228)
#define S3C64XX_EINT78FLTCON S3C64XX_GPIOREG(0x22C)
#define S3C64XX_EINT9FLTCON S3C64XX_GPIOREG(0x230)
#define S3C64XX_EINT12MASK S3C64XX_GPIOREG(0x240)
#define S3C64XX_EINT34MASK S3C64XX_GPIOREG(0x244)
#define S3C64XX_EINT56MASK S3C64XX_GPIOREG(0x248)
#define S3C64XX_EINT78MASK S3C64XX_GPIOREG(0x24C)
#define S3C64XX_EINT9MASK S3C64XX_GPIOREG(0x250)
#define S3C64XX_EINT12PEND S3C64XX_GPIOREG(0x260)
#define S3C64XX_EINT34PEND S3C64XX_GPIOREG(0x264)
#define S3C64XX_EINT56PEND S3C64XX_GPIOREG(0x268)
#define S3C64XX_EINT78PEND S3C64XX_GPIOREG(0x26C)
#define S3C64XX_EINT9PEND S3C64XX_GPIOREG(0x270)
#define S3C64XX_PRIORITY S3C64XX_GPIOREG(0x280)
#define S3C64XX_PRIORITY_ARB(x) (1 << (x))
#define S3C64XX_SERVICE S3C64XX_GPIOREG(0x284)
#define S3C64XX_SERVICEPEND S3C64XX_GPIOREG(0x288)
#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900)
#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904)
#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910)
#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914)
#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918)
#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C)
#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920)
#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924)
/* GPIO sleep configuration */
#define S3C64XX_SPCONSLP S3C64XX_GPIOREG(0x880)
#define S3C64XX_SPCONSLP_TDO_PULLDOWN (1 << 14)
#define S3C64XX_SPCONSLP_CKE1INIT (1 << 5)
#define S3C64XX_SPCONSLP_RSTOUT_MASK (0x3 << 12)
#define S3C64XX_SPCONSLP_RSTOUT_OUT0 (0x0 << 12)
#define S3C64XX_SPCONSLP_RSTOUT_OUT1 (0x1 << 12)
#define S3C64XX_SPCONSLP_RSTOUT_HIZ (0x2 << 12)
#define S3C64XX_SPCONSLP_KPCOL_MASK (0x3 << 0)
#define S3C64XX_SPCONSLP_KPCOL_OUT0 (0x0 << 0)
#define S3C64XX_SPCONSLP_KPCOL_OUT1 (0x1 << 0)
#define S3C64XX_SPCONSLP_KPCOL_INP (0x2 << 0)
#define S3C64XX_SLPEN S3C64XX_GPIOREG(0x930)
#define S3C64XX_SLPEN_USE_xSLP (1 << 0)
#define S3C64XX_SLPEN_CFG_BYSLPEN (1 << 1)
#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */

View File

@@ -0,0 +1,31 @@
/* arch/arm/plat-s3c64xx/include/plat/regs-modem.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C64XX - modem block registers
*
* 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 __PLAT_S3C64XX_REGS_MODEM_H
#define __PLAT_S3C64XX_REGS_MODEM_H __FILE__
#define S3C64XX_MODEMREG(x) (S3C64XX_VA_MODEM + (x))
#define S3C64XX_MODEM_INT2AP S3C64XX_MODEMREG(0x0)
#define S3C64XX_MODEM_INT2MODEM S3C64XX_MODEMREG(0x4)
#define S3C64XX_MODEM_MIFCON S3C64XX_MODEMREG(0x8)
#define S3C64XX_MODEM_MIFPCON S3C64XX_MODEMREG(0xC)
#define S3C64XX_MODEM_INTCLR S3C64XX_MODEMREG(0x10)
#define S3C64XX_MODEM_DMA_TXADDR S3C64XX_MODEMREG(0x14)
#define S3C64XX_MODEM_DMA_RXADDR S3C64XX_MODEMREG(0x18)
#define MIFPCON_INT2M_LEVEL (1 << 4)
#define MIFPCON_LCD_BYPASS (1 << 3)
#endif /* __PLAT_S3C64XX_REGS_MODEM_H */

View File

@@ -0,0 +1,28 @@
/* arch/arm/plat-s3c64xx/include/plat/regs-sys.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX system 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 __PLAT_REGS_SYS_H
#define __PLAT_REGS_SYS_H __FILE__
#define S3C_SYSREG(x) (S3C_VA_SYS + (x))
#define S3C64XX_AHB_CON0 S3C_SYSREG(0x100)
#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104)
#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108)
#define S3C64XX_OTHERS S3C_SYSREG(0x900)
#define S3C64XX_OTHERS_USBMASK (1 << 16)
#endif /* _PLAT_REGS_SYS_H */

View File

@@ -0,0 +1,116 @@
/* arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* S3C64XX - syscon power and sleep control registers
*
* 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 __PLAT_S3C64XX_REGS_SYSCON_POWER_H
#define __PLAT_S3C64XX_REGS_SYSCON_POWER_H __FILE__
#define S3C64XX_PWR_CFG S3C_SYSREG(0x804)
#define S3C64XX_PWRCFG_OSC_OTG_DISABLE (1 << 17)
#define S3C64XX_PWRCFG_MMC2_DISABLE (1 << 16)
#define S3C64XX_PWRCFG_MMC1_DISABLE (1 << 15)
#define S3C64XX_PWRCFG_MMC0_DISABLE (1 << 14)
#define S3C64XX_PWRCFG_HSI_DISABLE (1 << 13)
#define S3C64XX_PWRCFG_TS_DISABLE (1 << 12)
#define S3C64XX_PWRCFG_RTC_TICK_DISABLE (1 << 11)
#define S3C64XX_PWRCFG_RTC_ALARM_DISABLE (1 << 10)
#define S3C64XX_PWRCFG_MSM_DISABLE (1 << 9)
#define S3C64XX_PWRCFG_KEY_DISABLE (1 << 8)
#define S3C64XX_PWRCFG_BATF_DISABLE (1 << 7)
#define S3C64XX_PWRCFG_CFG_WFI_MASK (0x3 << 5)
#define S3C64XX_PWRCFG_CFG_WFI_SHIFT (5)
#define S3C64XX_PWRCFG_CFG_WFI_IGNORE (0x0 << 5)
#define S3C64XX_PWRCFG_CFG_WFI_IDLE (0x1 << 5)
#define S3C64XX_PWRCFG_CFG_WFI_STOP (0x2 << 5)
#define S3C64XX_PWRCFG_CFG_WFI_SLEEP (0x3 << 5)
#define S3C64XX_PWRCFG_CFG_BATFLT_MASK (0x3 << 3)
#define S3C64XX_PWRCFG_CFG_BATFLT_SHIFT (3)
#define S3C64XX_PWRCFG_CFG_BATFLT_IGNORE (0x0 << 3)
#define S3C64XX_PWRCFG_CFG_BATFLT_IRQ (0x1 << 3)
#define S3C64XX_PWRCFG_CFG_BATFLT_SLEEP (0x3 << 3)
#define S3C64XX_PWRCFG_CFG_BAT_WAKE (1 << 2)
#define S3C64XX_PWRCFG_OSC27_EN (1 << 0)
#define S3C64XX_EINT_MASK S3C_SYSREG(0x808)
#define S3C64XX_NORMAL_CFG S3C_SYSREG(0x810)
#define S3C64XX_NORMALCFG_IROM_ON (1 << 30)
#define S3C64XX_NORMALCFG_DOMAIN_ETM_ON (1 << 16)
#define S3C64XX_NORMALCFG_DOMAIN_S_ON (1 << 15)
#define S3C64XX_NORMALCFG_DOMAIN_F_ON (1 << 14)
#define S3C64XX_NORMALCFG_DOMAIN_P_ON (1 << 13)
#define S3C64XX_NORMALCFG_DOMAIN_I_ON (1 << 12)
#define S3C64XX_NORMALCFG_DOMAIN_G_ON (1 << 10)
#define S3C64XX_NORMALCFG_DOMAIN_V_ON (1 << 9)
#define S3C64XX_STOP_CFG S3C_SYSREG(0x814)
#define S3C64XX_STOPCFG_MEMORY_ARM_ON (1 << 29)
#define S3C64XX_STOPCFG_TOP_MEMORY_ON (1 << 20)
#define S3C64XX_STOPCFG_ARM_LOGIC_ON (1 << 17)
#define S3C64XX_STOPCFG_TOP_LOGIC_ON (1 << 8)
#define S3C64XX_STOPCFG_OSC_EN (1 << 0)
#define S3C64XX_SLEEP_CFG S3C_SYSREG(0x818)
#define S3C64XX_SLEEPCFG_OSC_EN (1 << 0)
#define S3C64XX_STOP_MEM_CFG S3C_SYSREG(0x81c)
#define S3C64XX_STOPMEMCFG_MODEMIF_RETAIN (1 << 6)
#define S3C64XX_STOPMEMCFG_HOSTIF_RETAIN (1 << 5)
#define S3C64XX_STOPMEMCFG_OTG_RETAIN (1 << 4)
#define S3C64XX_STOPMEMCFG_HSMCC_RETAIN (1 << 3)
#define S3C64XX_STOPMEMCFG_IROM_RETAIN (1 << 2)
#define S3C64XX_STOPMEMCFG_IRDA_RETAIN (1 << 1)
#define S3C64XX_STOPMEMCFG_NFCON_RETAIN (1 << 0)
#define S3C64XX_OSC_STABLE S3C_SYSREG(0x824)
#define S3C64XX_PWR_STABLE S3C_SYSREG(0x828)
#define S3C64XX_WAKEUP_STAT S3C_SYSREG(0x908)
#define S3C64XX_WAKEUPSTAT_MMC2 (1 << 11)
#define S3C64XX_WAKEUPSTAT_MMC1 (1 << 10)
#define S3C64XX_WAKEUPSTAT_MMC0 (1 << 9)
#define S3C64XX_WAKEUPSTAT_HSI (1 << 8)
#define S3C64XX_WAKEUPSTAT_BATFLT (1 << 6)
#define S3C64XX_WAKEUPSTAT_MSM (1 << 5)
#define S3C64XX_WAKEUPSTAT_KEY (1 << 4)
#define S3C64XX_WAKEUPSTAT_TS (1 << 3)
#define S3C64XX_WAKEUPSTAT_RTC_TICK (1 << 2)
#define S3C64XX_WAKEUPSTAT_RTC_ALARM (1 << 1)
#define S3C64XX_WAKEUPSTAT_EINT (1 << 0)
#define S3C64XX_BLK_PWR_STAT S3C_SYSREG(0x90c)
#define S3C64XX_BLKPWRSTAT_G (1 << 7)
#define S3C64XX_BLKPWRSTAT_ETM (1 << 6)
#define S3C64XX_BLKPWRSTAT_S (1 << 5)
#define S3C64XX_BLKPWRSTAT_F (1 << 4)
#define S3C64XX_BLKPWRSTAT_P (1 << 3)
#define S3C64XX_BLKPWRSTAT_I (1 << 2)
#define S3C64XX_BLKPWRSTAT_V (1 << 1)
#define S3C64XX_BLKPWRSTAT_TOP (1 << 0)
#define S3C64XX_INFORM0 S3C_SYSREG(0xA00)
#define S3C64XX_INFORM1 S3C_SYSREG(0xA04)
#define S3C64XX_INFORM2 S3C_SYSREG(0xA08)
#define S3C64XX_INFORM3 S3C_SYSREG(0xA0C)
#endif /* __PLAT_S3C64XX_REGS_SYSCON_POWER_H */

View File

@@ -0,0 +1,36 @@
/* arch/arm/plat-s3c64xx/include/plat/s3c6400.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Header file for s3c6400 cpu 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.
*/
/* Common init code for S3C6400 related SoCs */
extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c6400_register_clocks(unsigned armclk_divlimit);
extern void s3c6400_setup_clocks(void);
#ifdef CONFIG_CPU_S3C6400
extern int s3c6400_init(void);
extern void s3c6400_init_irq(void);
extern void s3c6400_map_io(void);
extern void s3c6400_init_clocks(int xtal);
#define s3c6400_init_uarts s3c6400_common_init_uarts
#else
#define s3c6400_init_clocks NULL
#define s3c6400_init_uarts NULL
#define s3c6400_map_io NULL
#define s3c6400_init NULL
#endif

View File

@@ -0,0 +1,29 @@
/* arch/arm/plat-s3c64xx/include/plat/s3c6410.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Header file for s3c6410 cpu 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.
*/
#ifdef CONFIG_CPU_S3C6410
extern int s3c6410_init(void);
extern void s3c6410_init_irq(void);
extern void s3c6410_map_io(void);
extern void s3c6410_init_clocks(int xtal);
#define s3c6410_init_uarts s3c6400_common_init_uarts
#else
#define s3c6410_init_clocks NULL
#define s3c6410_init_uarts NULL
#define s3c6410_map_io NULL
#define s3c6410_init NULL
#endif

View File

@@ -0,0 +1,204 @@
/* arch/arm/plat-s3c64xx/irq-eint.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - Interrupt handling for IRQ_EINT(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/sysdev.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/hardware/vic.h>
#include <plat/regs-irqtype.h>
#include <plat/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/map.h>
#include <plat/cpu.h>
#include <plat/pm.h>
#define eint_offset(irq) ((irq) - IRQ_EINT(0))
#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
static inline void s3c_irq_eint_mask(unsigned int irq)
{
u32 mask;
mask = __raw_readl(S3C64XX_EINT0MASK);
mask |= eint_irq_to_bit(irq);
__raw_writel(mask, S3C64XX_EINT0MASK);
}
static void s3c_irq_eint_unmask(unsigned int irq)
{
u32 mask;
mask = __raw_readl(S3C64XX_EINT0MASK);
mask &= ~eint_irq_to_bit(irq);
__raw_writel(mask, S3C64XX_EINT0MASK);
}
static inline void s3c_irq_eint_ack(unsigned int irq)
{
__raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND);
}
static void s3c_irq_eint_maskack(unsigned int irq)
{
/* compiler should in-line these */
s3c_irq_eint_mask(irq);
s3c_irq_eint_ack(irq);
}
static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type)
{
int offs = eint_offset(irq);
int pin;
int shift;
u32 ctrl, mask;
u32 newvalue = 0;
void __iomem *reg;
if (offs > 27)
return -EINVAL;
if (offs <= 15)
reg = S3C64XX_EINT0CON0;
else
reg = S3C64XX_EINT0CON1;
switch (type) {
case IRQ_TYPE_NONE:
printk(KERN_WARNING "No edge setting!\n");
break;
case IRQ_TYPE_EDGE_RISING:
newvalue = S3C2410_EXTINT_RISEEDGE;
break;
case IRQ_TYPE_EDGE_FALLING:
newvalue = S3C2410_EXTINT_FALLEDGE;
break;
case IRQ_TYPE_EDGE_BOTH:
newvalue = S3C2410_EXTINT_BOTHEDGE;
break;
case IRQ_TYPE_LEVEL_LOW:
newvalue = S3C2410_EXTINT_LOWLEV;
break;
case IRQ_TYPE_LEVEL_HIGH:
newvalue = S3C2410_EXTINT_HILEV;
break;
default:
printk(KERN_ERR "No such irq type %d", type);
return -1;
}
shift = (offs / 2) * 4;
mask = 0x7 << shift;
ctrl = __raw_readl(reg);
ctrl &= ~mask;
ctrl |= newvalue << shift;
__raw_writel(ctrl, reg);
/* set the GPIO pin appropriately */
if (offs < 23)
pin = S3C64XX_GPN(offs);
else
pin = S3C64XX_GPM(offs - 23);
s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(2));
return 0;
}
static struct irq_chip s3c_irq_eint = {
.name = "s3c-eint",
.mask = s3c_irq_eint_mask,
.unmask = s3c_irq_eint_unmask,
.mask_ack = s3c_irq_eint_maskack,
.ack = s3c_irq_eint_ack,
.set_type = s3c_irq_eint_set_type,
.set_wake = s3c_irqext_wake,
};
/* s3c_irq_demux_eint
*
* This function demuxes the IRQ from the group0 external interrupts,
* from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
* the specific handlers s3c_irq_demux_eintX_Y.
*/
static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
{
u32 status = __raw_readl(S3C64XX_EINT0PEND);
u32 mask = __raw_readl(S3C64XX_EINT0MASK);
unsigned int irq;
status &= ~mask;
status >>= start;
status &= (1 << (end - start + 1)) - 1;
for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
if (status & 1)
generic_handle_irq(irq);
status >>= 1;
}
}
static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_eint(0, 3);
}
static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_eint(4, 11);
}
static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_eint(12, 19);
}
static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_eint(20, 27);
}
static int __init s3c64xx_init_irq_eint(void)
{
int irq;
for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
set_irq_chip(irq, &s3c_irq_eint);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
return 0;
}
arch_initcall(s3c64xx_init_irq_eint);

View File

@@ -0,0 +1,111 @@
/* arch/arm/plat-s3c64xx/irq-pm.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - Interrupt handling Power Management
*
* 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/sysdev.h>
#include <linux/interrupt.h>
#include <linux/serial_core.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <mach/map.h>
#include <plat/regs-serial.h>
#include <plat/regs-timer.h>
#include <plat/regs-gpio.h>
#include <plat/cpu.h>
#include <plat/pm.h>
/* We handled all the IRQ types in this code, to save having to make several
* small files to handle each different type separately. Having the EINT_GRP
* code here shouldn't be as much bloat as the IRQ table space needed when
* they are enabled. The added benefit is we ensure that these registers are
* in the same state as we suspended.
*/
static struct sleep_save irq_save[] = {
SAVE_ITEM(S3C64XX_PRIORITY),
SAVE_ITEM(S3C64XX_EINT0CON0),
SAVE_ITEM(S3C64XX_EINT0CON1),
SAVE_ITEM(S3C64XX_EINT0FLTCON0),
SAVE_ITEM(S3C64XX_EINT0FLTCON1),
SAVE_ITEM(S3C64XX_EINT0FLTCON2),
SAVE_ITEM(S3C64XX_EINT0FLTCON3),
SAVE_ITEM(S3C64XX_EINT0MASK),
SAVE_ITEM(S3C64XX_TINT_CSTAT),
};
static struct irq_grp_save {
u32 fltcon;
u32 con;
u32 mask;
} eint_grp_save[5];
static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
{
struct irq_grp_save *grp = eint_grp_save;
int i;
S3C_PMDBG("%s: suspending IRQs\n", __func__);
s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4));
grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4));
grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4));
}
return 0;
}
static int s3c64xx_irq_pm_resume(struct sys_device *dev)
{
struct irq_grp_save *grp = eint_grp_save;
int i;
S3C_PMDBG("%s: resuming IRQs\n", __func__);
s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
__raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
__raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4));
__raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4));
__raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4));
}
S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
return 0;
}
static struct sysdev_driver s3c64xx_irq_driver = {
.suspend = s3c64xx_irq_pm_suspend,
.resume = s3c64xx_irq_pm_resume,
};
static int __init s3c64xx_irq_pm_init(void)
{
return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver);
}
arch_initcall(s3c64xx_irq_pm_init);

View File

@@ -0,0 +1,256 @@
/* arch/arm/plat-s3c64xx/irq.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - Interrupt handling
*
* 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/serial_core.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <asm/hardware/vic.h>
#include <mach/map.h>
#include <plat/regs-serial.h>
#include <plat/regs-timer.h>
#include <plat/cpu.h>
/* Timer interrupt handling */
static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
{
generic_handle_irq(sub_irq);
}
static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER0);
}
static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER1);
}
static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER2);
}
static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER3);
}
static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
{
s3c_irq_demux_timer(irq, IRQ_TIMER4);
}
/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
static void s3c_irq_timer_mask(unsigned int irq)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
reg &= 0x1f; /* mask out pending interrupts */
reg &= ~(1 << (irq - IRQ_TIMER0));
__raw_writel(reg, S3C64XX_TINT_CSTAT);
}
static void s3c_irq_timer_unmask(unsigned int irq)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
reg &= 0x1f; /* mask out pending interrupts */
reg |= 1 << (irq - IRQ_TIMER0);
__raw_writel(reg, S3C64XX_TINT_CSTAT);
}
static void s3c_irq_timer_ack(unsigned int irq)
{
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
reg &= 0x1f;
reg |= (1 << 5) << (irq - IRQ_TIMER0);
__raw_writel(reg, S3C64XX_TINT_CSTAT);
}
static struct irq_chip s3c_irq_timer = {
.name = "s3c-timer",
.mask = s3c_irq_timer_mask,
.unmask = s3c_irq_timer_unmask,
.ack = s3c_irq_timer_ack,
};
struct uart_irq {
void __iomem *regs;
unsigned int base_irq;
unsigned int parent_irq;
};
/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
* are consecutive when looking up the interrupt in the demux routines.
*/
static struct uart_irq uart_irqs[] = {
[0] = {
.regs = S3C_VA_UART0,
.base_irq = IRQ_S3CUART_BASE0,
.parent_irq = IRQ_UART0,
},
[1] = {
.regs = S3C_VA_UART1,
.base_irq = IRQ_S3CUART_BASE1,
.parent_irq = IRQ_UART1,
},
[2] = {
.regs = S3C_VA_UART2,
.base_irq = IRQ_S3CUART_BASE2,
.parent_irq = IRQ_UART2,
},
[3] = {
.regs = S3C_VA_UART3,
.base_irq = IRQ_S3CUART_BASE3,
.parent_irq = IRQ_UART3,
},
};
static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
{
struct uart_irq *uirq = get_irq_chip_data(irq);
return uirq->regs;
}
static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
{
return irq & 3;
}
/* UART interrupt registers, not worth adding to seperate include header */
static void s3c_irq_uart_mask(unsigned int irq)
{
void __iomem *regs = s3c_irq_uart_base(irq);
unsigned int bit = s3c_irq_uart_bit(irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
reg |= (1 << bit);
__raw_writel(reg, regs + S3C64XX_UINTM);
}
static void s3c_irq_uart_maskack(unsigned int irq)
{
void __iomem *regs = s3c_irq_uart_base(irq);
unsigned int bit = s3c_irq_uart_bit(irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
reg |= (1 << bit);
__raw_writel(reg, regs + S3C64XX_UINTM);
__raw_writel(1 << bit, regs + S3C64XX_UINTP);
}
static void s3c_irq_uart_unmask(unsigned int irq)
{
void __iomem *regs = s3c_irq_uart_base(irq);
unsigned int bit = s3c_irq_uart_bit(irq);
u32 reg;
reg = __raw_readl(regs + S3C64XX_UINTM);
reg &= ~(1 << bit);
__raw_writel(reg, regs + S3C64XX_UINTM);
}
static void s3c_irq_uart_ack(unsigned int irq)
{
void __iomem *regs = s3c_irq_uart_base(irq);
unsigned int bit = s3c_irq_uart_bit(irq);
__raw_writel(1 << bit, regs + S3C64XX_UINTP);
}
static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
{
struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
int base = uirq->base_irq;
if (pend & (1 << 0))
generic_handle_irq(base);
if (pend & (1 << 1))
generic_handle_irq(base + 1);
if (pend & (1 << 2))
generic_handle_irq(base + 2);
if (pend & (1 << 3))
generic_handle_irq(base + 3);
}
static struct irq_chip s3c_irq_uart = {
.name = "s3c-uart",
.mask = s3c_irq_uart_mask,
.unmask = s3c_irq_uart_unmask,
.mask_ack = s3c_irq_uart_maskack,
.ack = s3c_irq_uart_ack,
};
static void __init s3c64xx_uart_irq(struct uart_irq *uirq)
{
void __iomem *reg_base = uirq->regs;
unsigned int irq;
int offs;
/* mask all interrupts at the start. */
__raw_writel(0xf, reg_base + S3C64XX_UINTM);
for (offs = 0; offs < 3; offs++) {
irq = uirq->base_irq + offs;
set_irq_chip(irq, &s3c_irq_uart);
set_irq_chip_data(irq, uirq);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
}
void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
{
int uart, irq;
printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
/* initialise the pair of VICs */
vic_init(S3C_VA_VIC0, S3C_VIC0_BASE, vic0_valid, 0);
vic_init(S3C_VA_VIC1, S3C_VIC1_BASE, vic1_valid, 0);
/* add the timer sub-irqs */
set_irq_chained_handler(IRQ_TIMER0_VIC, s3c_irq_demux_timer0);
set_irq_chained_handler(IRQ_TIMER1_VIC, s3c_irq_demux_timer1);
set_irq_chained_handler(IRQ_TIMER2_VIC, s3c_irq_demux_timer2);
set_irq_chained_handler(IRQ_TIMER3_VIC, s3c_irq_demux_timer3);
set_irq_chained_handler(IRQ_TIMER4_VIC, s3c_irq_demux_timer4);
for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
set_irq_chip(irq, &s3c_irq_timer);
set_irq_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
s3c64xx_uart_irq(&uart_irqs[uart]);
}

View File

@@ -0,0 +1,173 @@
/* linux/arch/arm/plat-s3c64xx/pm.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX CPU 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/init.h>
#include <linux/suspend.h>
#include <linux/serial_core.h>
#include <linux/io.h>
#include <mach/map.h>
#include <plat/pm.h>
#include <plat/regs-sys.h>
#include <plat/regs-gpio.h>
#include <plat/regs-clock.h>
#include <plat/regs-syscon-power.h>
#include <plat/regs-gpio-memport.h>
#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
#include <plat/gpio-bank-n.h>
void s3c_pm_debug_smdkled(u32 set, u32 clear)
{
unsigned long flags;
u32 reg;
local_irq_save(flags);
reg = __raw_readl(S3C64XX_GPNCON);
reg &= ~(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) |
S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15));
reg |= S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) |
S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15);
__raw_writel(reg, S3C64XX_GPNCON);
reg = __raw_readl(S3C64XX_GPNDAT);
reg &= ~(clear << 12);
reg |= set << 12;
__raw_writel(reg, S3C64XX_GPNDAT);
local_irq_restore(flags);
}
#endif
static struct sleep_save core_save[] = {
SAVE_ITEM(S3C_APLL_LOCK),
SAVE_ITEM(S3C_MPLL_LOCK),
SAVE_ITEM(S3C_EPLL_LOCK),
SAVE_ITEM(S3C_CLK_SRC),
SAVE_ITEM(S3C_CLK_DIV0),
SAVE_ITEM(S3C_CLK_DIV1),
SAVE_ITEM(S3C_CLK_DIV2),
SAVE_ITEM(S3C_CLK_OUT),
SAVE_ITEM(S3C_HCLK_GATE),
SAVE_ITEM(S3C_PCLK_GATE),
SAVE_ITEM(S3C_SCLK_GATE),
SAVE_ITEM(S3C_MEM0_GATE),
SAVE_ITEM(S3C_EPLL_CON1),
SAVE_ITEM(S3C_EPLL_CON0),
SAVE_ITEM(S3C64XX_MEM0DRVCON),
SAVE_ITEM(S3C64XX_MEM1DRVCON),
#ifndef CONFIG_CPU_FREQ
SAVE_ITEM(S3C_APLL_CON),
SAVE_ITEM(S3C_MPLL_CON),
#endif
};
static struct sleep_save misc_save[] = {
SAVE_ITEM(S3C64XX_AHB_CON0),
SAVE_ITEM(S3C64XX_AHB_CON1),
SAVE_ITEM(S3C64XX_AHB_CON2),
SAVE_ITEM(S3C64XX_SPCON),
SAVE_ITEM(S3C64XX_MEM0CONSTOP),
SAVE_ITEM(S3C64XX_MEM1CONSTOP),
SAVE_ITEM(S3C64XX_MEM0CONSLP0),
SAVE_ITEM(S3C64XX_MEM0CONSLP1),
SAVE_ITEM(S3C64XX_MEM1CONSLP),
};
void s3c_pm_configure_extint(void)
{
__raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK);
}
void s3c_pm_restore_core(void)
{
__raw_writel(0, S3C64XX_EINT_MASK);
s3c_pm_debug_smdkled(1 << 2, 0);
s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
}
void s3c_pm_save_core(void)
{
s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
}
/* since both s3c6400 and s3c6410 share the same sleep pm calls, we
* put the per-cpu code in here until any new cpu comes along and changes
* this.
*/
static void s3c64xx_cpu_suspend(void)
{
unsigned long tmp;
/* set our standby method to sleep */
tmp = __raw_readl(S3C64XX_PWR_CFG);
tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP;
__raw_writel(tmp, S3C64XX_PWR_CFG);
/* clear any old wakeup */
__raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT),
S3C64XX_WAKEUP_STAT);
/* set the LED state to 0110 over sleep */
s3c_pm_debug_smdkled(3 << 1, 0xf);
/* 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"
"mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
/* we should never get past here */
panic("sleep resumed to originator?");
}
static void s3c64xx_pm_prepare(void)
{
/* store address of resume. */
__raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
/* ensure previous wakeup state is cleared before sleeping */
__raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
}
static int s3c64xx_pm_init(void)
{
pm_cpu_prep = s3c64xx_pm_prepare;
pm_cpu_sleep = s3c64xx_cpu_suspend;
pm_uart_udivslot = 1;
return 0;
}
arch_initcall(s3c64xx_pm_init);

View File

@@ -0,0 +1,766 @@
/* linux/arch/arm/plat-s3c64xx/s3c6400-clock.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C6400 based common clock 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/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/sysdev.h>
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <plat/cpu-freq.h>
#include <plat/regs-clock.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/pll.h>
/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
* ext_xtal_mux for want of an actual name from the manual.
*/
static struct clk clk_ext_xtal_mux = {
.name = "ext_xtal",
.id = -1,
};
#define clk_fin_apll clk_ext_xtal_mux
#define clk_fin_mpll clk_ext_xtal_mux
#define clk_fin_epll clk_ext_xtal_mux
#define clk_fout_mpll clk_mpll
struct clk_sources {
unsigned int nr_sources;
struct clk **sources;
};
struct clksrc_clk {
struct clk clk;
unsigned int mask;
unsigned int shift;
struct clk_sources *sources;
unsigned int divider_shift;
void __iomem *reg_divider;
};
static struct clk clk_fout_apll = {
.name = "fout_apll",
.id = -1,
};
static struct clk *clk_src_apll_list[] = {
[0] = &clk_fin_apll,
[1] = &clk_fout_apll,
};
static struct clk_sources clk_src_apll = {
.sources = clk_src_apll_list,
.nr_sources = ARRAY_SIZE(clk_src_apll_list),
};
static struct clksrc_clk clk_mout_apll = {
.clk = {
.name = "mout_apll",
.id = -1,
},
.shift = S3C6400_CLKSRC_APLL_MOUT_SHIFT,
.mask = S3C6400_CLKSRC_APLL_MOUT,
.sources = &clk_src_apll,
};
static struct clk clk_fout_epll = {
.name = "fout_epll",
.id = -1,
};
static struct clk *clk_src_epll_list[] = {
[0] = &clk_fin_epll,
[1] = &clk_fout_epll,
};
static struct clk_sources clk_src_epll = {
.sources = clk_src_epll_list,
.nr_sources = ARRAY_SIZE(clk_src_epll_list),
};
static struct clksrc_clk clk_mout_epll = {
.clk = {
.name = "mout_epll",
.id = -1,
},
.shift = S3C6400_CLKSRC_EPLL_MOUT_SHIFT,
.mask = S3C6400_CLKSRC_EPLL_MOUT,
.sources = &clk_src_epll,
};
static struct clk *clk_src_mpll_list[] = {
[0] = &clk_fin_mpll,
[1] = &clk_fout_mpll,
};
static struct clk_sources clk_src_mpll = {
.sources = clk_src_mpll_list,
.nr_sources = ARRAY_SIZE(clk_src_mpll_list),
};
static struct clksrc_clk clk_mout_mpll = {
.clk = {
.name = "mout_mpll",
.id = -1,
},
.shift = S3C6400_CLKSRC_MPLL_MOUT_SHIFT,
.mask = S3C6400_CLKSRC_MPLL_MOUT,
.sources = &clk_src_mpll,
};
static unsigned int armclk_mask;
static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk)
{
unsigned long rate = clk_get_rate(clk->parent);
u32 clkdiv;
/* divisor mask starts at bit0, so no need to shift */
clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask;
return rate / (clkdiv + 1);
}
static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk,
unsigned long rate)
{
unsigned long parent = clk_get_rate(clk->parent);
u32 div;
if (parent < rate)
return parent;
div = (parent / rate) - 1;
if (div > armclk_mask)
div = armclk_mask;
return parent / (div + 1);
}
static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate)
{
unsigned long parent = clk_get_rate(clk->parent);
u32 div;
u32 val;
if (rate < parent / (armclk_mask + 1))
return -EINVAL;
rate = clk_round_rate(clk, rate);
div = clk_get_rate(clk->parent) / rate;
val = __raw_readl(S3C_CLK_DIV0);
val &= ~armclk_mask;
val |= (div - 1);
__raw_writel(val, S3C_CLK_DIV0);
return 0;
}
static struct clk clk_arm = {
.name = "armclk",
.id = -1,
.parent = &clk_mout_apll.clk,
.get_rate = s3c64xx_clk_arm_get_rate,
.set_rate = s3c64xx_clk_arm_set_rate,
.round_rate = s3c64xx_clk_arm_round_rate,
};
static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
{
unsigned long rate = clk_get_rate(clk->parent);
printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK)
rate /= 2;
return rate;
}
static struct clk clk_dout_mpll = {
.name = "dout_mpll",
.id = -1,
.parent = &clk_mout_mpll.clk,
.get_rate = s3c64xx_clk_doutmpll_get_rate,
};
static struct clk *clkset_spi_mmc_list[] = {
&clk_mout_epll.clk,
&clk_dout_mpll,
&clk_fin_epll,
&clk_27m,
};
static struct clk_sources clkset_spi_mmc = {
.sources = clkset_spi_mmc_list,
.nr_sources = ARRAY_SIZE(clkset_spi_mmc_list),
};
static struct clk *clkset_irda_list[] = {
&clk_mout_epll.clk,
&clk_dout_mpll,
NULL,
&clk_27m,
};
static struct clk_sources clkset_irda = {
.sources = clkset_irda_list,
.nr_sources = ARRAY_SIZE(clkset_irda_list),
};
static struct clk *clkset_uart_list[] = {
&clk_mout_epll.clk,
&clk_dout_mpll,
NULL,
NULL
};
static struct clk_sources clkset_uart = {
.sources = clkset_uart_list,
.nr_sources = ARRAY_SIZE(clkset_uart_list),
};
static struct clk *clkset_uhost_list[] = {
&clk_48m,
&clk_mout_epll.clk,
&clk_dout_mpll,
&clk_fin_epll,
};
static struct clk_sources clkset_uhost = {
.sources = clkset_uhost_list,
.nr_sources = ARRAY_SIZE(clkset_uhost_list),
};
/* The peripheral clocks are all controlled via clocksource followed
* by an optional divider and gate stage. We currently roll this into
* one clock which hides the intermediate clock from the mux.
*
* Note, the JPEG clock can only be an even divider...
*
* The scaler and LCD clocks depend on the S3C64XX version, and also
* have a common parent divisor so are not included here.
*/
static inline struct clksrc_clk *to_clksrc(struct clk *clk)
{
return container_of(clk, struct clksrc_clk, clk);
}
static unsigned long s3c64xx_getrate_clksrc(struct clk *clk)
{
struct clksrc_clk *sclk = to_clksrc(clk);
unsigned long rate = clk_get_rate(clk->parent);
u32 clkdiv = __raw_readl(sclk->reg_divider);
clkdiv >>= sclk->divider_shift;
clkdiv &= 0xf;
clkdiv++;
rate /= clkdiv;
return rate;
}
static int s3c64xx_setrate_clksrc(struct clk *clk, unsigned long rate)
{
struct clksrc_clk *sclk = to_clksrc(clk);
void __iomem *reg = sclk->reg_divider;
unsigned int div;
u32 val;
rate = clk_round_rate(clk, rate);
div = clk_get_rate(clk->parent) / rate;
if (div > 16)
return -EINVAL;
val = __raw_readl(reg);
val &= ~(0xf << sclk->divider_shift);
val |= (div - 1) << sclk->divider_shift;
__raw_writel(val, reg);
return 0;
}
static int s3c64xx_setparent_clksrc(struct clk *clk, struct clk *parent)
{
struct clksrc_clk *sclk = to_clksrc(clk);
struct clk_sources *srcs = sclk->sources;
u32 clksrc = __raw_readl(S3C_CLK_SRC);
int src_nr = -1;
int ptr;
for (ptr = 0; ptr < srcs->nr_sources; ptr++)
if (srcs->sources[ptr] == parent) {
src_nr = ptr;
break;
}
if (src_nr >= 0) {
clksrc &= ~sclk->mask;
clksrc |= src_nr << sclk->shift;
__raw_writel(clksrc, S3C_CLK_SRC);
clk->parent = parent;
return 0;
}
return -EINVAL;
}
static unsigned long s3c64xx_roundrate_clksrc(struct clk *clk,
unsigned long rate)
{
unsigned long parent_rate = clk_get_rate(clk->parent);
int div;
if (rate > parent_rate)
rate = parent_rate;
else {
div = parent_rate / rate;
if (div == 0)
div = 1;
if (div > 16)
div = 16;
rate = parent_rate / div;
}
return rate;
}
static struct clksrc_clk clk_mmc0 = {
.clk = {
.name = "mmc_bus",
.id = 0,
.ctrlbit = S3C_CLKCON_SCLK_MMC0,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_MMC0_SHIFT,
.mask = S3C6400_CLKSRC_MMC0_MASK,
.sources = &clkset_spi_mmc,
.divider_shift = S3C6400_CLKDIV1_MMC0_SHIFT,
.reg_divider = S3C_CLK_DIV1,
};
static struct clksrc_clk clk_mmc1 = {
.clk = {
.name = "mmc_bus",
.id = 1,
.ctrlbit = S3C_CLKCON_SCLK_MMC1,
.enable = s3c64xx_sclk_ctrl,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.set_parent = s3c64xx_setparent_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_MMC1_SHIFT,
.mask = S3C6400_CLKSRC_MMC1_MASK,
.sources = &clkset_spi_mmc,
.divider_shift = S3C6400_CLKDIV1_MMC1_SHIFT,
.reg_divider = S3C_CLK_DIV1,
};
static struct clksrc_clk clk_mmc2 = {
.clk = {
.name = "mmc_bus",
.id = 2,
.ctrlbit = S3C_CLKCON_SCLK_MMC2,
.enable = s3c64xx_sclk_ctrl,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.set_parent = s3c64xx_setparent_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_MMC2_SHIFT,
.mask = S3C6400_CLKSRC_MMC2_MASK,
.sources = &clkset_spi_mmc,
.divider_shift = S3C6400_CLKDIV1_MMC2_SHIFT,
.reg_divider = S3C_CLK_DIV1,
};
static struct clksrc_clk clk_usbhost = {
.clk = {
.name = "usb-bus-host",
.id = -1,
.ctrlbit = S3C_CLKCON_SCLK_UHOST,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_UHOST_SHIFT,
.mask = S3C6400_CLKSRC_UHOST_MASK,
.sources = &clkset_uhost,
.divider_shift = S3C6400_CLKDIV1_UHOST_SHIFT,
.reg_divider = S3C_CLK_DIV1,
};
static struct clksrc_clk clk_uart_uclk1 = {
.clk = {
.name = "uclk1",
.id = -1,
.ctrlbit = S3C_CLKCON_SCLK_UART,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_UART_SHIFT,
.mask = S3C6400_CLKSRC_UART_MASK,
.sources = &clkset_uart,
.divider_shift = S3C6400_CLKDIV2_UART_SHIFT,
.reg_divider = S3C_CLK_DIV2,
};
/* Where does UCLK0 come from? */
static struct clksrc_clk clk_spi0 = {
.clk = {
.name = "spi-bus",
.id = 0,
.ctrlbit = S3C_CLKCON_SCLK_SPI0,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_SPI0_SHIFT,
.mask = S3C6400_CLKSRC_SPI0_MASK,
.sources = &clkset_spi_mmc,
.divider_shift = S3C6400_CLKDIV2_SPI0_SHIFT,
.reg_divider = S3C_CLK_DIV2,
};
static struct clksrc_clk clk_spi1 = {
.clk = {
.name = "spi-bus",
.id = 1,
.ctrlbit = S3C_CLKCON_SCLK_SPI1,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_SPI1_SHIFT,
.mask = S3C6400_CLKSRC_SPI1_MASK,
.sources = &clkset_spi_mmc,
.divider_shift = S3C6400_CLKDIV2_SPI1_SHIFT,
.reg_divider = S3C_CLK_DIV2,
};
static struct clk clk_iis_cd0 = {
.name = "iis_cdclk0",
.id = -1,
};
static struct clk clk_iis_cd1 = {
.name = "iis_cdclk1",
.id = -1,
};
static struct clk clk_pcm_cd = {
.name = "pcm_cdclk",
.id = -1,
};
static struct clk *clkset_audio0_list[] = {
[0] = &clk_mout_epll.clk,
[1] = &clk_dout_mpll,
[2] = &clk_fin_epll,
[3] = &clk_iis_cd0,
[4] = &clk_pcm_cd,
};
static struct clk_sources clkset_audio0 = {
.sources = clkset_audio0_list,
.nr_sources = ARRAY_SIZE(clkset_audio0_list),
};
static struct clksrc_clk clk_audio0 = {
.clk = {
.name = "audio-bus",
.id = 0,
.ctrlbit = S3C_CLKCON_SCLK_AUDIO0,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_AUDIO0_SHIFT,
.mask = S3C6400_CLKSRC_AUDIO0_MASK,
.sources = &clkset_audio0,
.divider_shift = S3C6400_CLKDIV2_AUDIO0_SHIFT,
.reg_divider = S3C_CLK_DIV2,
};
static struct clk *clkset_audio1_list[] = {
[0] = &clk_mout_epll.clk,
[1] = &clk_dout_mpll,
[2] = &clk_fin_epll,
[3] = &clk_iis_cd1,
[4] = &clk_pcm_cd,
};
static struct clk_sources clkset_audio1 = {
.sources = clkset_audio1_list,
.nr_sources = ARRAY_SIZE(clkset_audio1_list),
};
static struct clksrc_clk clk_audio1 = {
.clk = {
.name = "audio-bus",
.id = 1,
.ctrlbit = S3C_CLKCON_SCLK_AUDIO1,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_AUDIO1_SHIFT,
.mask = S3C6400_CLKSRC_AUDIO1_MASK,
.sources = &clkset_audio1,
.divider_shift = S3C6400_CLKDIV2_AUDIO1_SHIFT,
.reg_divider = S3C_CLK_DIV2,
};
static struct clksrc_clk clk_irda = {
.clk = {
.name = "irda-bus",
.id = 0,
.ctrlbit = S3C_CLKCON_SCLK_IRDA,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = S3C6400_CLKSRC_IRDA_SHIFT,
.mask = S3C6400_CLKSRC_IRDA_MASK,
.sources = &clkset_irda,
.divider_shift = S3C6400_CLKDIV2_IRDA_SHIFT,
.reg_divider = S3C_CLK_DIV2,
};
static struct clk *clkset_camif_list[] = {
&clk_h2,
};
static struct clk_sources clkset_camif = {
.sources = clkset_camif_list,
.nr_sources = ARRAY_SIZE(clkset_camif_list),
};
static struct clksrc_clk clk_camif = {
.clk = {
.name = "camera",
.id = -1,
.ctrlbit = S3C_CLKCON_SCLK_CAM,
.enable = s3c64xx_sclk_ctrl,
.set_parent = s3c64xx_setparent_clksrc,
.get_rate = s3c64xx_getrate_clksrc,
.set_rate = s3c64xx_setrate_clksrc,
.round_rate = s3c64xx_roundrate_clksrc,
},
.shift = 0,
.mask = 0,
.sources = &clkset_camif,
.divider_shift = S3C6400_CLKDIV0_CAM_SHIFT,
.reg_divider = S3C_CLK_DIV0,
};
/* Clock initialisation code */
static struct clksrc_clk *init_parents[] = {
&clk_mout_apll,
&clk_mout_epll,
&clk_mout_mpll,
&clk_mmc0,
&clk_mmc1,
&clk_mmc2,
&clk_usbhost,
&clk_uart_uclk1,
&clk_spi0,
&clk_spi1,
&clk_audio0,
&clk_audio1,
&clk_irda,
&clk_camif,
};
static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk)
{
struct clk_sources *srcs = clk->sources;
u32 clksrc = __raw_readl(S3C_CLK_SRC);
clksrc &= clk->mask;
clksrc >>= clk->shift;
if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
printk(KERN_ERR "%s: bad source %d\n",
clk->clk.name, clksrc);
return;
}
clk->clk.parent = srcs->sources[clksrc];
printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
clk->clk.name, clk->clk.parent->name, clksrc,
clk_get_rate(&clk->clk));
}
#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
void __init_or_cpufreq s3c6400_setup_clocks(void)
{
struct clk *xtal_clk;
unsigned long xtal;
unsigned long fclk;
unsigned long hclk;
unsigned long hclk2;
unsigned long pclk;
unsigned long epll;
unsigned long apll;
unsigned long mpll;
unsigned int ptr;
u32 clkdiv0;
printk(KERN_DEBUG "%s: registering clocks\n", __func__);
clkdiv0 = __raw_readl(S3C_CLK_DIV0);
printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0);
xtal_clk = clk_get(NULL, "xtal");
BUG_ON(IS_ERR(xtal_clk));
xtal = clk_get_rate(xtal_clk);
clk_put(xtal_clk);
printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
/* For now assume the mux always selects the crystal */
clk_ext_xtal_mux.parent = xtal_clk;
epll = s3c6400_get_epll(xtal);
mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
fclk = mpll;
printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
apll, mpll, epll);
hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n",
hclk2, hclk, pclk);
clk_fout_mpll.rate = mpll;
clk_fout_epll.rate = epll;
clk_fout_apll.rate = apll;
clk_h2.rate = hclk2;
clk_h.rate = hclk;
clk_p.rate = pclk;
clk_f.rate = fclk;
for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
s3c6400_set_clksrc(init_parents[ptr]);
}
static struct clk *clks[] __initdata = {
&clk_ext_xtal_mux,
&clk_iis_cd0,
&clk_iis_cd1,
&clk_pcm_cd,
&clk_mout_epll.clk,
&clk_fout_epll,
&clk_mout_mpll.clk,
&clk_dout_mpll,
&clk_mmc0.clk,
&clk_mmc1.clk,
&clk_mmc2.clk,
&clk_usbhost.clk,
&clk_uart_uclk1.clk,
&clk_spi0.clk,
&clk_spi1.clk,
&clk_audio0.clk,
&clk_audio1.clk,
&clk_irda.clk,
&clk_camif.clk,
&clk_arm,
};
/**
* s3c6400_register_clocks - register clocks for s3c6400 and above
* @armclk_divlimit: Divisor mask for ARMCLK
*
* Register the clocks for the S3C6400 and above SoC range, such
* as ARMCLK and the clocks which have divider chains attached.
*
* This call does not setup the clocks, which is left to the
* s3c6400_setup_clocks() call which may be needed by the cpufreq
* or resume code to re-set the clocks if the bootloader has changed
* them.
*/
void __init s3c6400_register_clocks(unsigned armclk_divlimit)
{
struct clk *clkp;
int ret;
int ptr;
armclk_mask = armclk_divlimit;
for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
clkp = clks[ptr];
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
}
clk_mpll.parent = &clk_mout_mpll.clk;
clk_epll.parent = &clk_mout_epll.clk;
}

View File

@@ -0,0 +1,29 @@
/* linux/arch/arm/plat-s3c64xx/s3c6400-init.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C6400 - CPU initialisation (common with other S3C64XX chips)
*
* 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/init.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/s3c6400.h>
#include <plat/s3c6410.h>
/* uart registration process */
void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
{
s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
}

View File

@@ -0,0 +1,37 @@
/* linux/arch/arm/plat-s3c64xx/setup-fb-24bpp.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Base S3C64XX setup information for 24bpp LCD framebuffer
*
* 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/fb.h>
#include <mach/regs-fb.h>
#include <mach/gpio.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
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);
}
}

View File

@@ -0,0 +1,31 @@
/* linux/arch/arm/plat-s3c64xx/setup-i2c0.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Base S3C64XX I2C bus 0 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.
*/
#include <linux/kernel.h>
#include <linux/types.h>
struct platform_device; /* don't need the contents */
#include <mach/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-bank-b.h>
#include <plat/gpio-cfg.h>
void s3c_i2c0_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S3C64XX_GPB(5), S3C64XX_GPB5_I2C_SCL0);
s3c_gpio_cfgpin(S3C64XX_GPB(6), S3C64XX_GPB6_I2C_SDA0);
s3c_gpio_setpull(S3C64XX_GPB(5), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S3C64XX_GPB(6), S3C_GPIO_PULL_UP);
}

View File

@@ -0,0 +1,31 @@
/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* Base S3C64XX I2C bus 1 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.
*/
#include <linux/kernel.h>
#include <linux/types.h>
struct platform_device; /* don't need the contents */
#include <mach/gpio.h>
#include <plat/iic.h>
#include <plat/gpio-bank-b.h>
#include <plat/gpio-cfg.h>
void s3c_i2c1_cfg_gpio(struct platform_device *dev)
{
s3c_gpio_cfgpin(S3C64XX_GPB(2), S3C64XX_GPB2_I2C_SCL1);
s3c_gpio_cfgpin(S3C64XX_GPB(3), S3C64XX_GPB3_I2C_SDA1);
s3c_gpio_setpull(S3C64XX_GPB(2), S3C_GPIO_PULL_UP);
s3c_gpio_setpull(S3C64XX_GPB(3), S3C_GPIO_PULL_UP);
}

View File

@@ -0,0 +1,55 @@
/* linux/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
*
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX - 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 <mach/gpio.h>
#include <plat/gpio-cfg.h>
void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
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);
}
s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
}
void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
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);
}
s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
}

View File

@@ -0,0 +1,144 @@
/* linux/0arch/arm/plat-s3c64xx/sleep.S
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX CPU sleep code
*
* 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/linkage.h>
#include <asm/assembler.h>
#include <mach/map.h>
#undef S3C64XX_VA_GPIO
#define S3C64XX_VA_GPIO (0x0)
#include <plat/regs-gpio.h>
#include <plat/gpio-bank-n.h>
#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
.text
/* s3c_cpu_save
*
* Save enough processor state to allow the restart of the pm.c
* code after resume.
*
* entry:
* r0 = pointer to the save block
*/
ENTRY(s3c_cpu_save)
stmfd sp!, { r4 - 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
stmia r0, { r4 - r13 } @ Save CP registers and SP
@@ save our state to ram
bl s3c_pm_cb_flushcache
@@ call final suspend code
ldr r0, =pm_cpu_sleep
ldr pc, [r0]
@@ return to the caller, after the MMU is turned on.
@@ restore the last bits of the stack and return.
resume_with_mmu:
ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
.data
/* the next bit is code, but it requires easy access to the
* s3c_sleep_save_phys data before the MMU is switched on, so
* we store the code that needs this variable in the .data where
* the value can be written to (the .text segment is RO).
*/
.global s3c_sleep_save_phys
s3c_sleep_save_phys:
.word 0
/* Sleep magic, the word before the resume entry point so that the
* bootloader can check for a resumeable image. */
.word 0x2bedf00d
/* s3c_cpu_reusme
*
* This is the entry point, stored by whatever method the bootloader
* requires to get the kernel runnign again. This code expects to be
* entered with no caches live and the MMU disabled. It will then
* restore the MMU and other basic CP registers saved and restart
* the kernel C code to finish the resume code.
*/
ENTRY(s3c_cpu_resume)
msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
ldr r2, =LL_UART /* for debug */
#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
/* Initialise the GPIO state if we are debugging via the SMDK LEDs,
* as the uboot version supplied resets these to inputs during the
* resume checks.
*/
ldr r3, =S3C64XX_PA_GPIO
ldr r0, [ r3, #S3C64XX_GPNCON ]
bic r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
orr r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
str r0, [ r3, #S3C64XX_GPNCON ]
ldr r0, [ r3, #S3C64XX_GPNDAT ]
bic r0, r0, #0xf << 12 @ GPN12..15
orr r0, r0, #1 << 15 @ GPN15
str r0, [ r3, #S3C64XX_GPNDAT ]
#endif
/* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
* are thoroughly cleaned just in case the bootloader didn't do it
* for us. */
mov r0, #0
mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
@@mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
@@mcr p15, 0, r0, c7, c7, 0 @ Invalidate I + D caches
ldr r0, s3c_sleep_save_phys
ldmia r0, { r4 - r13 }
mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
mcr p15, 0, r5, c3, c0, 0 @ Domain ID
mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
mov r0, #0 @ restore copro access controls
mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls
mcr p15, 0, r0, c7, c5, 4
ldr r2, =resume_with_mmu
mcr p15, 0, r9, c1, c0, 0 /* turn mmu back on */
nop
mov pc, r2 /* jump back */
.end