diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-08-01 17:50:18 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-08-01 17:50:18 +0200 |
commit | a934d16a2aa402f9f417f8a533ea80abcf1d2771 (patch) | |
tree | 3ad455d393a0ef35b44ea2d6aa2ade676801250e /arch/arm/mach-samsung | |
parent | 33838de7a241242c40f23fa3f95939d29c78544d (diff) | |
parent | d65926656c9e51419ec491a48f71017e3c9759cd (diff) | |
download | barebox-a934d16a2aa402f9f417f8a533ea80abcf1d2771.tar.gz barebox-a934d16a2aa402f9f417f8a533ea80abcf1d2771.tar.xz |
Merge branch 'for-next/samsung'
Conflicts:
arch/arm/Makefile
arch/arm/mach-samsung/Makefile
arch/arm/mach-samsung/include/mach/s5pcxx-iomap.h
Diffstat (limited to 'arch/arm/mach-samsung')
-rw-r--r-- | arch/arm/mach-samsung/Kconfig | 40 | ||||
-rw-r--r-- | arch/arm/mach-samsung/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-samsung/clocks-s3c24xx.c (renamed from arch/arm/mach-samsung/s3c24xx-clocks.c) | 0 | ||||
-rw-r--r-- | arch/arm/mach-samsung/clocks-s3c64xx.c | 338 | ||||
-rw-r--r-- | arch/arm/mach-samsung/gpio-s3c64xx.c | 301 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/devices-s3c64xx.h | 40 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/gpio.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/iomux-s3c64xx.h | 542 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/s3c-clocks.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/s3c-generic.h | 17 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/s3c-iomap.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/s3c64xx-clocks.h | 67 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/s3c64xx-iomap.h | 51 | ||||
-rw-r--r-- | arch/arm/mach-samsung/include/mach/s5pcxx-iomap.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-samsung/mem-s3c64xx.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-samsung/s3c-timer.c | 16 |
16 files changed, 1485 insertions, 7 deletions
diff --git a/arch/arm/mach-samsung/Kconfig b/arch/arm/mach-samsung/Kconfig index b28cf1f59c..7312f5e89b 100644 --- a/arch/arm/mach-samsung/Kconfig +++ b/arch/arm/mach-samsung/Kconfig @@ -6,12 +6,16 @@ if ARCH_SAMSUNG config ARCH_TEXT_BASE hex default 0x31fc0000 if MACH_MINI2440 + default 0x57fc0000 if MACH_MINI6410 + default 0x57fc0000 if MACH_TINY6410 default 0x31fc0000 if MACH_A9M2440 default 0x31fc0000 if MACH_A9M2410 default 0x23e00000 if MACH_TINY210 config BOARDINFO default "Mini 2440" if MACH_MINI2440 + default "Mini 6410" if MACH_MINI6410 + default "Tiny 6410" if MACH_TINY6410 default "Digi A9M2440" if MACH_A9M2440 default "Digi A9M2410" if MACH_A9M2410 default "Tiny 210" if MACH_TINY210 @@ -19,6 +23,8 @@ config BOARDINFO config ARCH_BAREBOX_MAX_BARE_INIT_SIZE hex default 0x1ff0 if ARCH_S5PCxx +# TODO + default 0x2000 if ARCH_S3C64xx if ARCH_S3C24xx @@ -86,6 +92,40 @@ endmenu endif +if ARCH_S3C64xx + +config CPU_S3C6410 + bool + +choice + + prompt "S3C64xx Board Type" + +config MACH_MINI6410 + bool "Mini 6410" + select CPU_S3C6410 + select HAS_DM9000 + help + Say Y here if you are using FriendlyARM Mini6410 board equipped + with a Samsung S3C6410 Processor + +config MACH_TINY6410 + bool "Tiny 6410" + select CPU_S3C6410 + help + Say Y here if you are using FriendlyARM Tiny6410 CPU card equipped + with a Samsung S3C6410 Processor + +endchoice + +menu "Board specific settings " + +source arch/arm/boards/friendlyarm-tiny6410/Kconfig + +endmenu + +endif + if ARCH_S5PCxx config CPU_S5PC110 diff --git a/arch/arm/mach-samsung/Makefile b/arch/arm/mach-samsung/Makefile index f7db1f7d05..39aa26957b 100644 --- a/arch/arm/mach-samsung/Makefile +++ b/arch/arm/mach-samsung/Makefile @@ -2,6 +2,7 @@ obj-y += s3c-timer.o generic.o obj-$(CONFIG_RESET_SOURCE) += reset_source.o obj-lowlevel-$(CONFIG_ARCH_S3C24xx) += lowlevel-s3c24x0.o obj-lowlevel-$(CONFIG_ARCH_S5PCxx) += lowlevel-s5pcxx.o -obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o s3c24xx-clocks.o mem-s3c24x0.o +obj-$(CONFIG_ARCH_S3C24xx) += gpio-s3c24x0.o clocks-s3c24xx.o mem-s3c24x0.o +obj-$(CONFIG_ARCH_S3C64xx) += gpio-s3c64xx.o clocks-s3c64xx.o mem-s3c64xx.o obj-$(CONFIG_ARCH_S5PCxx) += gpio-s5pcxx.o clocks-s5pcxx.o mem-s5pcxx.o obj-$(CONFIG_S3C_LOWLEVEL_INIT) += $(obj-lowlevel-y) diff --git a/arch/arm/mach-samsung/s3c24xx-clocks.c b/arch/arm/mach-samsung/clocks-s3c24xx.c index 13e68678e1..13e68678e1 100644 --- a/arch/arm/mach-samsung/s3c24xx-clocks.c +++ b/arch/arm/mach-samsung/clocks-s3c24xx.c diff --git a/arch/arm/mach-samsung/clocks-s3c64xx.c b/arch/arm/mach-samsung/clocks-s3c64xx.c new file mode 100644 index 0000000000..cf7d0716fe --- /dev/null +++ b/arch/arm/mach-samsung/clocks-s3c64xx.c @@ -0,0 +1,338 @@ +/* + * Copyright (C) 2012 Juergen Beisert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <config.h> +#include <common.h> +#include <init.h> +#include <clock.h> +#include <io.h> +#include <asm-generic/div64.h> +#include <mach/s3c-iomap.h> +#include <mach/s3c-generic.h> +#include <mach/s3c-clocks.h> + +/* + * The main clock tree: + * + * ref_in + * | + * v + * o-----------\ + * | MUX -o------------\ + * | / ^ | MUX --- DIV_APLL ------- ARMCLK -> CPU core + * o--- APLL -- | | / | + * | | o--/2 ------- | + * | APLL_SEL | |<-MISC_CON_SYN667 + * | \ | + * o-----------\ MUX-o-------\ | + * | MUX--/ ^ | MUX --- DIV -o--------- HCLKx2 -> SDRAM (max. 266 MHz) + * | / ^ | | / | + * o---- MPLL-- | | o--/5 -- o-- DIV -- HCLK -> AXI / AHB (max. 133 MHz) + * | | | | + * | MPLL_SEL OTHERS_CLK_SELECT o-- DIV -- PCLK -> APB (max. 66 MHz) + * | + * o-----------\ + * | MUX---- to various hardware + * | / ^ + * o---- EPLL-- EPLL_SEL + * + */ + +static unsigned s3c_get_apllclk(void) +{ + uint32_t m, p, s, reg_val; + + if (!(readl(S3C_CLK_SRC) & S3C_CLK_SRC_FOUTAPLL)) + return S3C64XX_CLOCK_REFERENCE; + + reg_val = readl(S3C_APLLCON); + if (!(reg_val & S3C_APLLCON_ENABLE)) + return 0; + m = S3C_APLLCON_GET_MDIV(reg_val); + p = S3C_APLLCON_GET_PDIV(reg_val); + s = S3C_APLLCON_GET_SDIV(reg_val); + + return (S3C64XX_CLOCK_REFERENCE * m) / (p << s); +} + +uint32_t s3c_get_mpllclk(void) +{ + uint32_t m, p, s, reg_val; + + if (!(readl(S3C_CLK_SRC) & S3C_CLK_SRC_FOUTMPLL)) + return S3C64XX_CLOCK_REFERENCE; + + reg_val = readl(S3C_MPLLCON); + if (!(reg_val & S3C_MPLLCON_ENABLE)) + return 0; + + m = S3C_MPLLCON_GET_MDIV(reg_val); + p = S3C_MPLLCON_GET_PDIV(reg_val); + s = S3C_MPLLCON_GET_SDIV(reg_val); + + return (S3C64XX_CLOCK_REFERENCE * m) / (p << s); +} + +unsigned s3c_get_epllclk(void) +{ + u32 m, p, s, k, reg0_val, reg1_val; + u64 tmp; + + if (!(readl(S3C_CLK_SRC) & S3C_CLK_SRC_FOUTEPLL)) + return S3C64XX_CLOCK_REFERENCE; + + reg0_val = readl(S3C_EPLLCON0); + if (!(reg0_val & S3C_EPLLCON0_ENABLE)) + return 0; /* PLL is disabled */ + + reg1_val = readl(S3C_EPLLCON1); + m = S3C_EPLLCON0_GET_MDIV(reg0_val); + p = S3C_EPLLCON0_GET_PDIV(reg0_val); + s = S3C_EPLLCON0_GET_SDIV(reg0_val); + k = S3C_EPLLCON1_GET_KDIV(reg1_val); + + tmp = S3C64XX_CLOCK_REFERENCE; + tmp *= (m << 16) + k; + do_div(tmp, (p << s)); + + return (unsigned)(tmp >> 16); +} + +unsigned s3c_set_epllclk(unsigned m, unsigned p, unsigned s, unsigned k) +{ + u32 con0, con1, src = readl(S3C_CLK_SRC) & ~S3C_CLK_SRC_FOUTEPLL; + + /* do not use the EPLL clock when it is in transit to the new frequency */ + writel(src, S3C_CLK_SRC); + + con0 = S3C_EPLLCON0_SET_MDIV(m) | S3C_EPLLCON0_SET_PDIV(p) | + S3C_EPLLCON0_SET_SDIV(s) | S3C_EPLLCON0_ENABLE; + con1 = S3C_EPLLCON1_SET_KDIV(k); + + /* + * After changing the multiplication value 'm' the PLL output will + * be masked for the time set in the EPLL_LOCK register until it + * settles to the new frequency. EPLL_LOCK contains a value for a + * simple counter which counts the external reference clock. + */ + writel(con0, S3C_EPLLCON0); + writel(con1, S3C_EPLLCON1); + + udelay((1000000000 / S3C64XX_CLOCK_REFERENCE) + * (S3C_EPLL_LOCK_PLL_LOCKTIME(readl(S3C_EPLL_LOCK)) + 1) / 1000); + + /* enable the EPLL's clock output to the system */ + writel(src | S3C_CLK_SRC_FOUTEPLL, S3C_CLK_SRC); + + return s3c_get_epllclk(); +} + +uint32_t s3c_get_fclk(void) +{ + unsigned clk; + + clk = s3c_get_apllclk(); + if (readl(S3C_MISC_CON) & S3C_MISC_CON_SYN667) + clk /= 2; + + return clk / (S3C_CLK_DIV0_GET_ADIV(readl(S3C_CLK_DIV0)) + 1); +} + +static unsigned s3c_get_hclk_in(void) +{ + unsigned clk; + + if (readl(S3C_OTHERS) & S3C_OTHERS_CLK_SELECT) + clk = s3c_get_apllclk(); + else + clk = s3c_get_mpllclk(); + + if (readl(S3C_MISC_CON) & S3C_MISC_CON_SYN667) + clk /= 5; + + return clk; +} + +static unsigned s3c_get_hclkx2(void) +{ + return s3c_get_hclk_in() / + (S3C_CLK_DIV0_GET_HCLK2(readl(S3C_CLK_DIV0)) + 1); +} + +uint32_t s3c_get_hclk(void) +{ + return s3c_get_hclkx2() / + (S3C_CLK_DIV0_GET_HCLK(readl(S3C_CLK_DIV0)) + 1); +} + +uint32_t s3c_get_pclk(void) +{ + return s3c_get_hclkx2() / + (S3C_CLK_DIV0_GET_PCLK(readl(S3C_CLK_DIV0)) + 1); +} + +static void s3c_init_mpll_dout(void) +{ + unsigned reg; + + /* keep it at the same frequency as HCLKx2 */ + reg = readl(S3C_CLK_DIV0) | S3C_CLK_DIV0_SET_MPLL_DIV(1); /* e.g. / 2 */ + writel(reg, S3C_CLK_DIV0); +} + +/* configure and enable UCLK1 */ +static int s3c_init_uart_clock(void) +{ + unsigned reg; + + s3c_init_mpll_dout(); /* to have a reliable clock source */ + + /* source the UART clock from the MPLL, currently *not* from EPLL */ + reg = readl(S3C_CLK_SRC) | S3C_CLK_SRC_UARTMPLL; + writel(reg, S3C_CLK_SRC); + + /* keep UART clock at the same frequency than the PCLK */ + reg = readl(S3C_CLK_DIV2) & ~S3C_CLK_DIV2_UART_MASK; + reg |= S3C_CLK_DIV2_SET_UART(0x3); /* / 4 */ + writel(reg, S3C_CLK_DIV2); + + /* ensure this very special clock is running */ + reg = readl(S3C_SCLK_GATE) | S3C_SCLK_GATE_UART; + writel(reg, S3C_SCLK_GATE); + + return 0; +} +core_initcall(s3c_init_uart_clock); + +/* UART source selection + * The UART related clock path: | + * v + * PCLK --------------------------------------o-----0-\ + * ???? -------------------------------UCLK0--|-----1--\MUX----- UART + * MPLL -----DIV0------\ +-----2--/ + * MUX---DIV2------UCLK1--------3-/ + * EPLL ---------------/ + * ^SRC_UARTMPLL + */ +unsigned s3c_get_uart_clk(unsigned source) +{ + u32 reg; + unsigned clk, pdiv, uartpdiv; + + switch (source) { + default: /* PCLK */ + clk = s3c_get_pclk(); + pdiv = uartpdiv = 1; + break; + case 1: /* UCLK0 */ + clk = 0; + pdiv = uartpdiv = 1; /* TODO */ + break; + case 3: /* UCLK1 */ + reg = readl(S3C_CLK_SRC); + if (reg & S3C_CLK_SRC_UARTMPLL) { + clk = s3c_get_mpllclk(); + pdiv = S3C_CLK_DIV0_GET_MPLL_DIV(readl(S3C_CLK_DIV0)) + 1; + } else { + clk = s3c_get_epllclk(); + pdiv = 1; + } + uartpdiv = S3C_CLK_DIV2_GET_UART(readl(S3C_CLK_DIV2)) + 1; + break; + } + + return clk / pdiv / uartpdiv; +} + +/* + * The MMC related clock path: + * + * MMCx_SEL + * | + * v + * EPLLout --------0-\ + * MPLLout --DIV0--1--\-------SCLK_MMCx----DIV_MMCx------>HSMMCx + * EPLLin --------2--/ on/off / 1..16 + * 27 MHz --------3-/ + * + * The datasheet is not very precise here, so the schematic shown above was + * made by checking various bits in the SYSCON. + */ +unsigned s3c_get_hsmmc_clk(int id) +{ + u32 sel, div, sclk = readl(S3C_SCLK_GATE); + unsigned bclk; + + if (!(sclk & S3C_SCLK_GATE_MMC(id))) + return 0; /* disabled */ + + sel = S3C_CLK_SRC_GET_MMC_SEL(id, readl(S3C_CLK_SRC)); + switch (sel) { + case 0: + bclk = s3c_get_epllclk(); + break; + case 1: + bclk = s3c_get_mpllclk(); + bclk >>= S3C_CLK_DIV0_GET_MPLL_DIV(readl(S3C_CLK_DIV0)); + break; + case 2: + bclk = S3C64XX_CLOCK_REFERENCE; + break; + case 3: + bclk = 27000000; + break; + } + + div = S3C_CLK_DIV0_GET_MMC(id, readl(S3C_CLK_DIV0)) + 1; + + return bclk / div; +} + +void s3c_set_hsmmc_clk(int id, int src, unsigned div) +{ + u32 reg; + + if (!div) + div = 1; + + writel(readl(S3C_SCLK_GATE) & ~S3C_SCLK_GATE_MMC(id), S3C_SCLK_GATE); + + /* select the new clock source */ + reg = readl(S3C_CLK_SRC) & ~S3C_CLK_SRC_SET_MMC_SEL(id, ~0); + reg |= S3C_CLK_SRC_SET_MMC_SEL(id, src); + writel(reg, S3C_CLK_SRC); + + /* select the new pre-divider */ + reg = readl(S3C_CLK_DIV0) & ~ S3C_CLK_DIV0_SET_MMC(id, ~0); + reg |= S3C_CLK_DIV0_SET_MMC(id, div - 1); + writel(reg, S3C_CLK_DIV0); + + /* calling this function implies enabling of the clock */ + writel(readl(S3C_SCLK_GATE) | S3C_SCLK_GATE_MMC(id), S3C_SCLK_GATE); +} + +int s3c64xx_dump_clocks(void) +{ + printf("refclk: %7d kHz\n", S3C64XX_CLOCK_REFERENCE / 1000); + printf("apll: %7d kHz\n", s3c_get_apllclk() / 1000); + printf("mpll: %7d kHz\n", s3c_get_mpllclk() / 1000); + printf("epll: %7d kHz\n", s3c_get_epllclk() / 1000); + printf("CPU: %7d kHz\n", s3c_get_fclk() / 1000); + printf("hclkx2: %7d kHz\n", s3c_get_hclkx2() / 1000); + printf("hclk: %7d kHz\n", s3c_get_hclk() / 1000); + printf("pclk: %7d kHz\n", s3c_get_pclk() / 1000); + return 0; +} + +late_initcall(s3c64xx_dump_clocks); diff --git a/arch/arm/mach-samsung/gpio-s3c64xx.c b/arch/arm/mach-samsung/gpio-s3c64xx.c new file mode 100644 index 0000000000..ee6826134d --- /dev/null +++ b/arch/arm/mach-samsung/gpio-s3c64xx.c @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2012 Juergen Beisert + * + * This code bases partially on code from the Linux kernel: + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <errno.h> +#include <io.h> +#include <gpio.h> +#include <mach/s3c-iomap.h> + +#define S3C_GPACON (S3C_GPIO_BASE) +#define S3C_GPADAT (S3C_GPIO_BASE + 0x04) +#define S3C_GPAPUD (S3C_GPIO_BASE + 0x08) + +static const unsigned short group_offset[] = { + 0x000, /* GPA */ /* 8 pins, 4 bit each */ + 0x020, /* GPB */ /* 7 pins, 4 bit each */ + 0x040, /* GPC */ /* 8 pins, 4 bit each */ + 0x060, /* GPD */ /* 5 pins, 4 bit each */ + 0x080, /* GPE */ /* 5 pins, 4 bit each */ + 0x0a0, /* GPF */ /* 16 pins, 2 bit each */ + 0x0c0, /* GPG */ /* 7 pins, 4 bit each */ + 0x0e0, /* GPH */ /* two registers, 8 + 2 pins, 4 bit each */ + 0x100, /* GPI */ /* 16 pins, 2 bit each */ + 0x120, /* GPJ */ /* 12 pins, 2 bit each */ + 0x800, /* GPK */ /* two registers, 8 + 8 pins, 4 bit each */ + 0x810, /* GPL */ /* two registers, 8 + 8 pins, 4 bit each */ + 0x820, /* GPM */ /* 6 pins, 4 bit each */ + 0x830, /* GPN */ /* 16 pins, 2 bit each */ + 0x140, /* GPO */ /* 16 pins, 2 bit each */ + 0x160, /* GPP */ /* 15 pins, 2 bit each */ + 0x180, /* GPQ */ /* 9 pins, 2 bit each */ +}; + +void gpio_set_value(unsigned gpio, int value) +{ + unsigned group = GET_GROUP(gpio); + unsigned bit = GET_BIT(gpio); + unsigned offset; + uint32_t reg; + + offset = group_offset[group]; + + switch (group) { + case 7: /* GPH */ + case 10: /* GPK */ + case 11: /* GPL */ + offset += 4; + break; + } + + reg = readl(S3C_GPADAT + offset); + reg &= ~(1 << bit); + reg |= (!!value) << bit; + writel(reg, S3C_GPADAT + offset); +} + +int gpio_get_value(unsigned gpio) +{ + unsigned group = GET_GROUP(gpio); + unsigned bit = GET_BIT(gpio); + unsigned offset; + uint32_t reg; + + offset = group_offset[group]; + + switch (group) { + case 7: /* GPH */ + case 10: /* GPK */ + case 11: /* GPL */ + offset += 4; + break; + } + + /* value */ + reg = readl(S3C_GPADAT + offset); + + return !!(reg & (1 << bit)); +} + +static void gpio_direction_input_4b(unsigned offset, unsigned bit) +{ + uint32_t reg; + + if (bit > 31) { + offset += 4; + bit -= 32; + } + + reg = readl(S3C_GPACON + offset) & ~(0xf << bit); + writel(reg, S3C_GPACON + offset); /* b0000 means 'GPIO input' */ +} + +static void gpio_direction_input_2b(unsigned offset, unsigned bit) +{ + uint32_t reg; + + reg = readl(S3C_GPACON + offset) & ~(0x3 << bit); + writel(reg, S3C_GPACON + offset); /* b00 means 'GPIO input' */ +} + +int gpio_direction_input(unsigned gpio) +{ + unsigned group = GET_GROUP(gpio); + unsigned bit = GET_BIT(gpio); + unsigned offset; + + offset = group_offset[group]; + + switch (group) { + case 5: /* GPF */ + case 8: /* GPI */ + case 9: /* GPJ */ + case 13: /* GPN */ + case 14: /* GPO */ + case 15: /* GPP */ + case 16: /* GPQ */ + gpio_direction_input_2b(offset, bit << 1); + break; + default: + gpio_direction_input_4b(offset, bit << 2); + } + + return 0; +} + +static void gpio_direction_output_4b(unsigned offset, unsigned bit) +{ + uint32_t reg; + + if (bit > 31) { + offset += 4; + bit -= 32; + } + + reg = readl(S3C_GPACON + offset) & ~(0xf << bit); + reg |= 0x1 << bit; + writel(reg, S3C_GPACON + offset); /* b0001 means 'GPIO output' */ +} + +static void gpio_direction_output_2b(unsigned offset, unsigned bit) +{ + uint32_t reg; + + /* direction */ + reg = readl(S3C_GPACON + offset) & ~(0x3 << bit); + reg |= 0x1 << bit; + writel(reg, S3C_GPACON + offset); +} + +int gpio_direction_output(unsigned gpio, int value) +{ + unsigned group = GET_GROUP(gpio); + unsigned bit = GET_BIT(gpio); + unsigned offset; + + gpio_set_value(gpio, value); + + offset = group_offset[group]; + switch (group) { + case 5: /* GPF */ + case 8: /* GPI */ + case 9: /* GPJ */ + case 13: /* GPN */ + case 14: /* GPO */ + case 15: /* GPP */ + case 16: /* GPQ */ + gpio_direction_output_2b(offset, bit << 1); + break; + default: + gpio_direction_output_4b(offset, bit << 2); + } + + return 0; +} + +/* one register, 2 bits per function -> GPF, GPI, GPJ, GPN, GPO, GPP, GPQ */ +static void s3c_d2pins(unsigned offset, unsigned pin_mode) +{ + unsigned bit = GET_BIT(pin_mode); + unsigned func = GET_FUNC(pin_mode); + unsigned reg; + + if (PUD_PRESENT(pin_mode)) { + reg = readl(S3C_GPAPUD + offset); + reg &= ~(PUD_MASK << bit); + reg |= GET_PUD(pin_mode) << bit; + writel(reg, S3C_GPAPUD + offset); + } + + /* in the case of pin's function is GPIO it also sets up the direction */ + reg = readl(S3C_GPACON + offset) & ~(0x3 << bit); + writel(reg | (func << bit), S3C_GPACON + offset); + + if (func == 1) { /* output? if yes, also set the initial value */ + reg = readl(S3C_GPADAT + offset) & ~(1 << (bit >> 1)); + reg |= GET_GPIOVAL(pin_mode) << (bit >> 1); + writel(reg, S3C_GPADAT + offset); + } +} + +/* one register, 4 bits per function -> GPA, GPB, GPC, GPD, GPE, GPG, GPM */ +static void s3c_d4pins(unsigned offset, unsigned pin_mode) +{ + unsigned bit = GET_BIT(pin_mode); + unsigned func = GET_FUNC(pin_mode); + unsigned reg; + + if (PUD_PRESENT(pin_mode)) { + reg = readl(S3C_GPAPUD + offset); + reg &= ~(PUD_MASK << (bit >> 1)); + reg |= GET_PUD(pin_mode) << (bit >> 1); + writel(reg, S3C_GPAPUD + offset); + } + + /* in the case of pin's function is GPIO it also sets up the direction */ + reg = readl(S3C_GPACON + offset) & ~(0xf << bit); + writel(reg | (func << bit), S3C_GPACON + offset); + + if (func == 1) { /* output? if yes, also set the initial value */ + reg = readl(S3C_GPADAT + offset) & ~(1 << (bit >> 2)); + reg |= GET_GPIOVAL(pin_mode) << (bit >> 2); + writel(reg, S3C_GPADAT + offset); + } +} + +/* two registers, 4 bits per pin -> GPH, GPK, GPL */ +static void s3c_d42pins(unsigned offset, unsigned pin_mode) +{ + unsigned bit = GET_BIT(pin_mode); + unsigned func = GET_FUNC(pin_mode); + uint32_t reg; + unsigned reg_offs = 0; + + if (PUD_PRESENT(pin_mode)) { + reg = readl(S3C_GPAPUD + 4 + offset); + reg &= ~(PUD_MASK << (bit >> 1)); + reg |= GET_PUD(pin_mode) << (bit >> 1); + writel(reg, S3C_GPACON + 4 + offset); + } + + if (bit > 31) { + reg_offs = 4; + bit -= 32; + } + + /* in the case of pin's function is GPIO it also sets up the direction */ + reg = readl(S3C_GPACON + offset + reg_offs) & ~(0xf << bit); + writel(reg | (func << bit), S3C_GPACON + offset + reg_offs); + + if (func == 1) { /* output? if yes, also set the initial value */ + reg = readl(S3C_GPADAT + 4 + offset) & ~(1 << (bit >> 2)); + reg |= GET_GPIOVAL(pin_mode) << (bit >> 2); + writel(reg, S3C_GPADAT + 4 + offset); + } +} + +/* 'gpio_mode' must be one of the 'GP?_*' macros */ +void s3c_gpio_mode(unsigned gpio_mode) +{ + unsigned group, offset; + + group = GET_GROUP(gpio_mode); + offset = group_offset[group]; + + switch (group) { + case 5: /* GPF */ + case 8: /* GPI */ + case 9: /* GPJ */ + case 13: /* GPN */ + case 14: /* GPO */ + case 15: /* GPP */ + case 16: /* GPQ */ + s3c_d2pins(offset, gpio_mode); + break; + case 7: /* GPH */ + case 10: /* GPK */ + case 11: /* GPL */ + s3c_d42pins(offset, gpio_mode); + break; + default: + s3c_d4pins(offset, gpio_mode); + } +} diff --git a/arch/arm/mach-samsung/include/mach/devices-s3c64xx.h b/arch/arm/mach-samsung/include/mach/devices-s3c64xx.h new file mode 100644 index 0000000000..bcbee972e6 --- /dev/null +++ b/arch/arm/mach-samsung/include/mach/devices-s3c64xx.h @@ -0,0 +1,40 @@ +/* + * Copyright 2012 Juergen Beisert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef INCLUDE_MACH_DEVICES_S3C64XX_H +# define INCLUDE_MACH_DEVICES_S3C64XX_H + +#include <driver.h> +#include <mach/s3c64xx-iomap.h> + +static inline void s3c64xx_add_uart1(void) +{ + add_generic_device("s3c_serial", DEVICE_ID_DYNAMIC, NULL, S3C_UART1_BASE, + S3C_UART1_SIZE, IORESOURCE_MEM, NULL); +} + +static inline void s3c64xx_add_uart2(void) +{ + add_generic_device("s3c_serial", DEVICE_ID_DYNAMIC, NULL, S3C_UART2_BASE, + S3C_UART2_SIZE, IORESOURCE_MEM, NULL); +} + +static inline void s3c64xx_add_uart3(void) +{ + add_generic_device("s3c_serial", DEVICE_ID_DYNAMIC, NULL, S3C_UART3_BASE, + S3C_UART3_SIZE, IORESOURCE_MEM, NULL); +} + +#endif /* INCLUDE_MACH_DEVICES_S3C64XX_H */ diff --git a/arch/arm/mach-samsung/include/mach/gpio.h b/arch/arm/mach-samsung/include/mach/gpio.h index 4d7d2174dd..2b4569547e 100644 --- a/arch/arm/mach-samsung/include/mach/gpio.h +++ b/arch/arm/mach-samsung/include/mach/gpio.h @@ -16,6 +16,9 @@ #ifdef CONFIG_ARCH_S3C24xx # include <mach/iomux-s3c24x0.h> #endif +#ifdef CONFIG_ARCH_S3C64xx +# include <mach/iomux-s3c64xx.h> +#endif #ifdef CONFIG_ARCH_S5PCxx # include <mach/iomux-s5pcxx.h> #endif diff --git a/arch/arm/mach-samsung/include/mach/iomux-s3c64xx.h b/arch/arm/mach-samsung/include/mach/iomux-s3c64xx.h new file mode 100644 index 0000000000..5d68b71ae7 --- /dev/null +++ b/arch/arm/mach-samsung/include/mach/iomux-s3c64xx.h @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2012 Juergen Beisert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __MACH_IOMUX_S3C64XX_H +# define __MACH_IOMUX_S3C64XX_H + +/* 3322222222221111111111 + * 10987654321098765432109876543210 + * ^^^^^^_ Bit offset + * ^^^^^_______ Group Number + * ^^^^____________ Function + * ^________________ initial GPIO out value + * ^_________________ Pull up/down feature present + * ^^__________________ initial pull up/down setting + */ + +#define PIN(group,bit) ((group << 6) + bit) +#define FUNC(x) (((x) & 0xf) << 11) +#define GET_FUNC(x) (((x) >> 11) & 0xf) +#define GET_GROUP(x) (((x) >> 6) & 0x1f) +#define GET_BIT(x) ((x) & 0x3f) +#define GET_GPIOVAL(x) (!!((x) & (1 << 15))) +#define GPIO_OUT (1 << 11) +#define GPIO_IN (0 << 11) +#define GPIO_VAL(x) ((!!(x)) << 15) +#define PUD_MASK 0x3 +#define PUD (1 << 16) +#define PUD_PRESENT(x) (!!((x) & (1 << 16))) +#define DISABLE_PUD (0 << 17) +#define ENABLE_PU (2 << 17) +#define ENABLE_PD (1 << 17) +#define GET_PUD(x) (((x) >> 17) & PUD_MASK) + +/* + * To have a chance for simple GPIO manipulation routines + * define the GPIO numbers with a real simple scheme. + * + * Keep in mind: The 'GPIO_2_NO' creates a value to be used with the real gpio + * routines and *not* for the multiplexer routines! + */ +#define GPIO_2_NO(x,y) (PIN(x,y)) + +/* + * Group A: GPIO 0...7 + * Used GPIO: 0...7 + * These pins can also act as GPIO outputs + */ +#define GPA0 (PIN(0,0) | PUD) +#define GPA0_GPIO (GPA0 | FUNC(0)) +#define GPA0_RXD0 (GPA0 | FUNC(2)) +#define GPA1 (PIN(0,4) | PUD) +#define GPA1_GPIO (GPA1 | FUNC(0)) +#define GPA1_TXD0 (GPA1 | FUNC(2)) +#define GPA2 (PIN(0,8) | PUD) +#define GPA2_GPIO (GPA2 | FUNC(0)) +#define GPA2_NCTS0 (GPA2 | FUNC(2)) +#define GPA3 (PIN(0,12) | PUD) +#define GPA3_GPIO (GPA3 | FUNC(0)) +#define GPA3_NRTS0 (GPA3 | FUNC(2)) +#define GPA4 (PIN(0,16) | PUD) +#define GPA4_GPIO (GPA4 | FUNC(0)) +#define GPA4_RXD1 (GPA4 | FUNC(2)) +#define GPA5 (PIN(0,20) | PUD) +#define GPA5_GPIO (GPA5 | FUNC(0)) +#define GPA5_TXD1 (GPA5 | FUNC(2)) +#define GPA6 (PIN(0,24) | PUD) +#define GPA6_GPIO (GPA6 | FUNC(0)) +#define GPA6_NCTS1 (GPA6 | FUNC(2)) +#define GPA7 (PIN(0,28) | PUD) +#define GPA7_GPIO (GPA7 | FUNC(0)) +#define GPA7_NRTS1 (GPA7 | FUNC(2)) + +/* + * Group B: GPIO 0...7 + * Used GPIO: 8...15 + * These pins can also act as GPIO outputs + */ +#define GPB0 (PIN(1,0) | PUD) +#define GPB0_GPIO (GPB0 | FUNC(0)) +#define GPB0_RXD2 (GPB0 | FUNC(2)) +#define GPB0_DMAREQ (GPB0 | FUNC(3)) +#define GPB0_IRDA_RXD (GPB0 | FUNC(4)) +#define GPB0_ADDR_CF0 (GPB0 | FUNC(5)) +#define GPB1 (PIN(1,4) | PUD) +#define GPB1_GPIO (GPB1 | FUNC(0)) +#define GPB1_TXD2 (GPB1 | FUNC(2)) +#define GPB1_DMAREQ (GPB1 | FUNC(3)) +#define GPB1_IRDA_TXD (GPB1 | FUNC(4)) +#define GPB1_ADDR_CF1 (GPB1 | FUNC(5)) +#define GPB2 (PIN(1,8) | PUD) +#define GPB2_GPIO (GPB2 | FUNC(0)) +#define GPB2_RXD3 (GPB2 | FUNC(2)) +#define GPB2_IRDA_RXD (GPB2 | FUNC(3)) +#define GPB2_DMAREQ (GPB2 | FUNC(4)) +#define GPB2_ADDR_CF2 (GPB2 | FUNC(5)) +#define GPB2_IIC1_SCL (GPB2 | FUNC(6)) +#define GPB3 (PIN(1,12) | PUD) +#define GPB3_GPIO (GPB3 | FUNC(0)) +#define GPB3_TXD3 (GPB3 | FUNC(2)) +#define GPB3_IRDA_TXD (GPB3 | FUNC(3)) +#define GPB3_DMAREQ (GPB3 | FUNC(4)) +#define GPB3_IIC1_SDA (GPB3 | FUNC(6)) +#define GPB4 (PIN(1,16) | PUD) +#define GPB4_GPIO (GPB4 | FUNC(0)) +#define GPB4_SDBW (GPB4 | FUNC(2)) +#define GPB4_CAM_FLD (GPB4 | FUNC(3)) +#define GPB4_CF_DIR (GPB4 | FUNC(4)) +#define GPB5 (PIN(1,20) | PUD) +#define GPB5_GPIO (GPB5 | FUNC(0)) +#define GPB5_IIC0_SCL (GPB5 | FUNC(2)) +#define GPB6 (PIN(1,24) | PUD) +#define GPB6_GPIO (GPB6 | FUNC(0)) +#define GPB6_IIC0_SDA (GPB6 | FUNC(2)) + +#define GPC0 (PIN(2,0) | PUD) +#define GPC0_GPIO (GPC0 | FUNC(0)) +#define GPC0_SPI0_MISO (GPC0 | FUNC(2)) +#define GPC1 (PIN(2,4) | PUD) +#define GPC1_GPIO (GPC1 | FUNC(0)) +#define GPC1_SPI0_CLK (GPC1 | FUNC(2)) +#define GPC2 (PIN(2,8) | PUD) +#define GPC2_GPIO (GPC2 | FUNC(0)) +#define GPC2_SPI0_MOSI (GPC2 | FUNC(2)) +#define GPC3 (PIN(2,12) | PUD) +#define GPC3_GPIO (GPC3 | FUNC(0)) +#define GPC3_SPI0_NCS (GPC3 | FUNC(2)) +#define GPC4 (PIN(2,16) | PUD) +#define GPC4_GPIO (GPC4 | FUNC(0)) +#define GPC4_SPI1_MISO (GPC4 | FUNC(2)) +#define GPC5 (PIN(2,20) | PUD) +#define GPC5_GPIO (GPC5 | FUNC(0)) +#define GPC5_SPI1_CLK (GPC5 | FUNC(2)) +#define GPC6 (PIN(2,24) | PUD) +#define GPC6_GPIO (GPC6 | FUNC(0)) +#define GPC6_SPI1_MOSI (GPC6 | FUNC(2)) +#define GPC7 (PIN(2,28) | PUD) +#define GPC7_GPIO (GPC7 | FUNC(0)) +#define GPC7_SPI1_NCS (GPC7 | FUNC(2)) + +#define GPD0 (PIN(3,0) | PUD) +#define GPD0_AC97_BITCLK (GPD0 | FUNC(4)) +#define GPD1 (PIN(3,4) | PUD) +#define GPD1_AC97_NRST (GPD1 | FUNC(4)) +#define GPD2 (PIN(3,8) | PUD) +#define GPD2_AC97_SYNC (GPD2 | FUNC(4)) +#define GPD3 (PIN(3,12) | PUD) +#define GPD3_AC97_SDI (GPD3 | FUNC(4)) +#define GPD4 (PIN(3,16) | PUD) +#define GPD4_AC97_SDO (GPD4 | FUNC(4)) + +#define GPE0 (PIN(4,0) | PUD) +#define GPE0_GPIO (GPE0 | FUNC(0)) +#define GPE1 (PIN(4,4) | PUD) +#define GPE1_GPIO (GPE1 | FUNC(0)) +#define GPE2 (PIN(4,8) | PUD) +#define GPE2_GPIO (GPE2 | FUNC(0)) +#define GPE3 (PIN(4,12) | PUD) +#define GPE3_GPIO (GPE3 | FUNC(0)) +#define GPE4 (PIN(4,16) | PUD) +#define GPE4_GPIO (GPE4 | FUNC(0)) + +#define GPF0 (PIN(5,0) | PUD) +#define GPF0_GPIO (GPF0 | FUNC(0)) +#define GPF1 (PIN(5,2) | PUD) +#define GPF1_GPIO (GPF1 | FUNC(0)) +#define GPF2 (PIN(5,4) | PUD) +#define GPF2_GPIO (GPF2 | FUNC(0)) +#define GPF3 (PIN(5,6) | PUD) +#define GPF3_GPIO (GPF3 | FUNC(0)) +#define GPF4 (PIN(5,8) | PUD) +#define GPF4_GPIO (GPF4 | FUNC(0)) +#define GPF5 (PIN(5,10) | PUD) +#define GPF5_GPIO (GPF5 | FUNC(0)) +#define GPF6 (PIN(5,12) | PUD) +#define GPF6_GPIO (GPF6 | FUNC(0)) +#define GPF7 (PIN(5,14) | PUD) +#define GPF7_GPIO (GPF7 | FUNC(0)) +#define GPF8 (PIN(5,16) | PUD) +#define GPF8_GPIO (GPF8 | FUNC(0)) +#define GPF9 (PIN(5,18) | PUD) +#define GPF9_GPIO (GPF9 | FUNC(0)) +#define GPF10 (PIN(5,20) | PUD) +#define GPF10_GPIO (GPF10 | FUNC(0)) +#define GPF11 (PIN(5,22) | PUD) +#define GPF11_GPIO (GPF11 | FUNC(0)) +#define GPF12 (PIN(5,24) | PUD) +#define GPF12_GPIO (GPF12 | FUNC(0)) +#define GPF13 (PIN(5,26) | PUD) +#define GPF13_GPIO (GPF13 | FUNC(0)) +#define GPF14 (PIN(5,28) | PUD) +#define GPF14_GPIO (GPF14 | FUNC(0)) +#define GPF14_PWM0 (GPF14 | FUNC(2)) +#define GPF14_CLKOUT (GPF14 | FUNC(3)) +#define GPF15 (PIN(5,30) | PUD) +#define GPF15_GPIO (GPF15 | FUNC(0)) +#define GPF15_PWM1 (GPF15 | FUNC(2)) + +#define GPG0 (PIN(6,0) | PUD) +#define GPG0_MMC0_CLK (GPG0 | FUNC(2)) +#define GPG1 (PIN(6,4) | PUD) +#define GPG1_MMC0_CMD (GPG1 | FUNC(2)) +#define GPG2 (PIN(6,8) | PUD) +#define GPG2_MMC0_DAT0 (GPG2 | FUNC(2)) +#define GPG3 (PIN(6,12) | PUD) +#define GPG3_MMC0_DAT1 (GPG3 | FUNC(2)) +#define GPG4 (PIN(6,16) | PUD) +#define GPG4_MMC0_DAT2 (GPG4 | FUNC(2)) +#define GPG5 (PIN(6,20) | PUD) +#define GPG5_MMC0_DAT3 (GPG5 | FUNC(2)) +#define GPG6 (PIN(6,24) | PUD) +#define GPG6_MMC0_NCD (GPG6 | FUNC(2)) + +#define GPH0 (PIN(7,0) | PUD) +#define GPH0_GPIO (GPH0 | FUNC(0)) +#define GPH1 (PIN(7,4) | PUD) +#define GPH1_GPIO (GPH1 | FUNC(0)) +#define GPH2 (PIN(7,8) | PUD) +#define GPH2_GPIO (GPH2 | FUNC(0)) +#define GPH3 (PIN(7,12) | PUD) +#define GPH3_GPIO (GPH3 | FUNC(0)) +#define GPH4 (PIN(7,16) | PUD) +#define GPH4_GPIO (GPH4 | FUNC(0)) +#define GPH5 (PIN(7,20) | PUD) +#define GPH5_GPIO (GPH5 | FUNC(0)) +#define GPH6 (PIN(7,24) | PUD) +#define GPH6_GPIO (GPH6 | FUNC(0)) +#define GPH7 (PIN(7,28) | PUD) +#define GPH7_GPIO (GPH7 | FUNC(0)) +#define GPH8 (PIN(7,32) | PUD) +#define GPH8_GPIO (GPH8 | FUNC(0)) +#define GPH9 (PIN(7,36) | PUD) +#define GPH9_GPIO (GPH9 | FUNC(0)) + +#define GPI0 (PIN(8,0) | PUD) +#define GPI0_GPIO (GPI0 | FUNC(0)) +#define GPI1 (PIN(8,2) | PUD) +#define GPI1_GPIO (GPI1 | FUNC(0)) +#define GPI2 (PIN(8,4) | PUD) +#define GPI2_GPIO (GPI2 | FUNC(0)) +#define GPI3 (PIN(8,6) | PUD) +#define GPI3_GPIO (GPI3 | FUNC(0)) +#define GPI4 (PIN(8,8) | PUD) +#define GPI4_GPIO (GPI4 | FUNC(0)) +#define GPI5 (PIN(8,10) | PUD) +#define GPI5_GPIO (GPI5 | FUNC(0)) +#define GPI6 (PIN(8,12) | PUD) +#define GPI6_GPIO (GPI6 | FUNC(0)) +#define GPI7 (PIN(8,14) | PUD) +#define GPI7_GPIO (GPI7 | FUNC(0)) +#define GPI8 (PIN(8,16) | PUD) +#define GPI8_GPIO (GPI8 | FUNC(0)) +#define GPI9 (PIN(8,18) | PUD) +#define GPI9_GPIO (GPI9 | FUNC(0)) +#define GPI10 (PIN(8,20) | PUD) +#define GPI10_GPIO (GPI10 | FUNC(0)) +#define GPI11 (PIN(8,22) | PUD) +#define GPI11_GPIO (GPI11 | FUNC(0)) +#define GPI12 (PIN(8,24) | PUD) +#define GPI12_GPIO (GPI12 | FUNC(0)) +#define GPI13 (PIN(8,26) | PUD) +#define GPI13_GPIO (GPI13 | FUNC(0)) +#define GPI14 (PIN(8,28) | PUD) +#define GPI14_GPIO (GPI14 | FUNC(0)) +#define GPI15 (PIN(8,30) | PUD) +#define GPI15_GPIO (GPI15 | FUNC(0)) + +#define GPJ0 (PIN(9,0) | PUD) +#define GPJ0_GPIO (GPJ0 | FUNC(0)) +#define GPJ1 (PIN(9,2) | PUD) +#define GPJ1_GPIO (GPJ1 | FUNC(0)) +#define GPJ2 (PIN(9,4) | PUD) +#define GPJ2_GPIO (GPJ2 | FUNC(0)) +#define GPJ3 (PIN(9,6) | PUD) +#define GPJ3_GPIO (GPJ3 | FUNC(0)) +#define GPJ4 (PIN(9,8) | PUD) +#define GPJ4_GPIO (GPJ4 | FUNC(0)) +#define GPJ5 (PIN(9,10) | PUD) +#define GPJ5_GPIO (GPJ5 | FUNC(0)) +#define GPJ6 (PIN(9,12) | PUD) +#define GPJ6_GPIO (GPJ6 | FUNC(0)) +#define GPJ7 (PIN(9,14) | PUD) +#define GPJ7_GPIO (GPJ7 | FUNC(0)) +#define GPJ8 (PIN(9,16) | PUD) +#define GPJ8_GPIO (GPJ8 | FUNC(0)) +#define GPJ9 (PIN(9,18) | PUD) +#define GPJ9_GPIO (GPJ9 | FUNC(0)) +#define GPJ10 (PIN(9,20) | PUD) +#define GPJ10_GPIO (GPJ10 | FUNC(0)) +#define GPJ11 (PIN(9,22) | PUD) +#define GPJ11_GPIO (GPJ11 | FUNC(0)) + +#define GPK0 (PIN(10,0) | PUD) +#define GPK0_DATA0 (GPK0 | FUNC(2)) +#define GPK0_GPIO (GPK0 | FUNC(0)) +#define GPK1 (PIN(10,4) | PUD) +#define GPK1_DATA1 (GPK1 | FUNC(2)) +#define GPK1_GPIO (GPK1 | FUNC(0)) +#define GPK2 (PIN(10,8) | PUD) +#define GPK2_DATA2 (GPK2 | FUNC(2)) +#define GPK2_GPIO (GPK2 | FUNC(0)) +#define GPK3 (PIN(10,12) | PUD) +#define GPK3_DATA3 (GPK3 | FUNC(2)) +#define GPK3_GPIO (GPK3 | FUNC(0)) +#define GPK4 (PIN(10,16) | PUD) +#define GPK4_DATA4 (GPK4 | FUNC(2)) +#define GPK4_GPIO (GPK4 | FUNC(0)) +#define GPK5 (PIN(10,20) | PUD) +#define GPK5_DATA5 (GPK5 | FUNC(2)) +#define GPK5_GPIO (GPK5 | FUNC(0)) +#define GPK6 (PIN(10,24) | PUD) +#define GPK6_DATA6 (GPK6 | FUNC(2)) +#define GPK6_GPIO (GPK6 | FUNC(0)) +#define GPK7 (PIN(10,28) | PUD) +#define GPK7_DATA7 (GPK7 | FUNC(2)) +#define GPK7_GPIO (GPK7 | FUNC(0)) +#define GPK8 (PIN(10,32) | PUD) +#define GPK8_DATA8 (GPK8 | FUNC(2)) +#define GPK8_GPIO (GPK8 | FUNC(0)) +#define GPK9 (PIN(10,36) | PUD) +#define GPK9_DATA9 (GPK9 | FUNC(2)) +#define GPK9_GPIO (GPK9 | FUNC(0)) +#define GPK10 (PIN(10,40) | PUD) +#define GPK10_DATA10 (GPK10 | FUNC(2)) +#define GPK10_GPIO (GPK10 | FUNC(0)) +#define GPK11 (PIN(10,44) | PUD) +#define GPK11_DATA11 (GPK11 | FUNC(2)) +#define GPK11_GPIO (GPK11 | FUNC(0)) +#define GPK12 (PIN(10,48) | PUD) +#define GPK12_DATA12 (GPK12 | FUNC(2)) +#define GPK12_GPIO (GPK12 | FUNC(0)) +#define GPK13 (PIN(10,52) | PUD) +#define GPK13_DATA13 (GPK13 | FUNC(2)) +#define GPK13_GPIO (GPK13 | FUNC(0)) +#define GPK14 (PIN(10,56) | PUD) +#define GPK14_DATA14 (GPK14 | FUNC(2)) +#define GPK14_GPIO (GPK14 | FUNC(0)) +#define GPK15 (PIN(10,60) | PUD) +#define GPK15_DATA15 (GPK15 | FUNC(2)) +#define GPK15_GPIO (GPK15 | FUNC(0)) + +#define GPL0 (PIN(11,0) | PUD) +#define GPL0_ADDR0 (GPL0 | FUNC(2)) +#define GPL0_GPIO (GPL0 | FUNC(0)) +#define GPL1 (PIN(11,4) | PUD) +#define GPL1_ADDR1 (GPL1 | FUNC(2)) +#define GPL1_GPIO (GPL1 | FUNC(0)) +#define GPL2 (PIN(11,8) | PUD) +#define GPL2_ADDR2 (GPL2 | FUNC(2)) +#define GPL2_GPIO (GPL2 | FUNC(0)) +#define GPL3 (PIN(11,12) | PUD) +#define GPL3_ADDR3 (GPL3 | FUNC(2)) +#define GPL3_GPIO (GPL3 | FUNC(0)) +#define GPL4 (PIN(11,16) | PUD) +#define GPL4_ADDR3 (GPL4 | FUNC(2)) +#define GPL4_GPIO (GPL4 | FUNC(0)) +#define GPL5 (PIN(11,20) | PUD) +#define GPL5_ADDR3 (GPL5 | FUNC(2)) +#define GPL5_GPIO (GPL5 | FUNC(0)) +#define GPL6 (PIN(11,24) | PUD) +#define GPL6_ADDR3 (GPL6 | FUNC(2)) +#define GPL6_GPIO (GPL6 | FUNC(0)) +#define GPL7 (PIN(11,28) | PUD) +#define GPL7_ADDR3 (GPL7 | FUNC(2)) +#define GPL7_GPIO (GPL7 | FUNC(0)) +#define GPL8 (PIN(11,32) | PUD) +#define GPL8_ADDR3 (GPL8 | FUNC(2)) +#define GPL8_GPIO (GPL8 | FUNC(0)) +#define GPL9 (PIN(11,36) | PUD) +#define GPL9_ADDR3 (GPL9 | FUNC(2)) +#define GPL9_GPIO (GPL9 | FUNC(0)) +#define GPL10 (PIN(11,40) | PUD) +#define GPL10_ADDR3 (GPL10 | FUNC(2)) +#define GPL10_GPIO (GPL10 | FUNC(0)) +#define GPL11 (PIN(11,44) | PUD) +#define GPL11_ADDR3 (GPL11 | FUNC(2)) +#define GPL11_GPIO (GPL11 | FUNC(0)) +#define GPL12 (PIN(11,48) | PUD) +#define GPL12_ADDR3 (GPL12 | FUNC(2)) +#define GPL12_GPIO (GPL12 | FUNC(0)) +#define GPL13 (PIN(11,52) | PUD) +#define GPL13_ADDR16 (GPL13 | FUNC(2)) +#define GPL13_GPIO (GPL13 | FUNC(0)) +#define GPL14 (PIN(11,65) | PUD) +#define GPL14_ADDR17 (GPL14 | FUNC(2)) +#define GPL14_GPIO (GPL14 | FUNC(0)) + +#define GPM0 (PIN(12,0) | PUD) +#define GPM0_GPIO (GPM0 | FUNC(0)) +#define GPM1 (PIN(12,4) | PUD) +#define GPM1_GPIO (GPM1 | FUNC(0)) +#define GPM2 (PIN(12,8) | PUD) +#define GPM2_GPIO (GPM2 | FUNC(0)) +#define GPM3 (PIN(12,12) | PUD) +#define GPM3_GPIO (GPM3 | FUNC(0)) +#define GPM4 (PIN(12,16) | PUD) +#define GPM4_GPIO (GPM4 | FUNC(0)) +#define GPM5 (PIN(12,20) | PUD) +#define GPM5_GPIO (GPM5 | FUNC(0)) + +#define GPN0 (PIN(13,0) | PUD) +#define GPN0_GPIO (GPN0 | FUNC(0)) +#define GPN1 (PIN(13,0) | PUD) +#define GPN1_GPIO (GPN1 | FUNC(0)) +#define GPN2 (PIN(13,0) | PUD) +#define GPN2_GPIO (GPN2 | FUNC(0)) +#define GPN3 (PIN(13,0) | PUD) +#define GPN3_GPIO (GPN3 | FUNC(0)) +#define GPN4 (PIN(13,0) | PUD) +#define GPN4_GPIO (GPN4 | FUNC(0)) +#define GPN5 (PIN(13,0) | PUD) +#define GPN5_GPIO (GPN5 | FUNC(0)) +#define GPN6 (PIN(13,0) | PUD) +#define GPN6_GPIO (GPN6 | FUNC(0)) +#define GPN7 (PIN(13,0) | PUD) +#define GPN7_GPIO (GPN7 | FUNC(0)) +#define GPN8 (PIN(13,0) | PUD) +#define GPN8_GPIO (GPN8 | FUNC(0)) +#define GPN9 (PIN(13,0) | PUD) +#define GPN9_GPIO (GPN9 | FUNC(0)) +#define GPN10 (PIN(13,20) | PUD) +#define GPN10_GPIO (GPN10 | FUNC(0)) +#define GPN11 (PIN(13,20) | PUD) +#define GPN11_GPIO (GPN11 | FUNC(0)) +#define GPN12 (PIN(13,20) | PUD) +#define GPN12_GPIO (GPN12 | FUNC(0)) +#define GPN13 (PIN(13,20) | PUD) +#define GPN13_GPIO (GPN13 | FUNC(0)) +#define GPN14 (PIN(13,20) | PUD) +#define GPN14_GPIO (GPN14 | FUNC(0)) +#define GPN15 (PIN(13,20) | PUD) +#define GPN15_GPIO (GPN15 | FUNC(0)) + +#define GPO0 (PIN(14,0) | PUD) +#define GPO0_GPIO (GPO0 | FUNC(0)) +#define GPO0_NCS2 (GPO0 | FUNC(2)) +#define GPO1 (PIN(14,2) | PUD) +#define GPO1_GPIO (GPO1 | FUNC(0)) +#define GPO1_NCS3 (GPO1 | FUNC(2)) +#define GPO2 (PIN(14,4) | PUD) +#define GPO2_GPIO (GPO2 | FUNC(0)) +#define GPO2_NCS4 (GPO2 | FUNC(2)) +#define GPO3 (PIN(14,6) | PUD) +#define GPO3_GPIO (GPO3 | FUNC(0)) +#define GPO3_NCS5 (GPO3 | FUNC(2)) +#define GPO4 (PIN(14,8) | PUD) +#define GPO4_GPIO (GPO4 | FUNC(0)) +#define GPO5 (PIN(14,10) | PUD) +#define GPO5_GPIO (GPO5 | FUNC(0)) +#define GPO6 (PIN(14,12) | PUD) +#define GPO6_GPIO (GPO6 | FUNC(0)) +#define GPO6_ADDR6 (GPO6 | FUNC(2)) +#define GPO7 (PIN(14,14) | PUD) +#define GPO7_GPIO (GPO7 | FUNC(0)) +#define GPO7_ADDR7 (GPO7 | FUNC(2)) +#define GPO8 (PIN(14,16) | PUD) +#define GPO8_GPIO (GPO8 | FUNC(0)) +#define GPO8_ADDR8 (GPO8 | FUNC(2)) +#define GPO9 (PIN(14,18) | PUD) +#define GPO9_GPIO (GPO9 | FUNC(0)) +#define GPO9_ADDR9 (GPO9 | FUNC(2)) +#define GPO10 (PIN(14,20) | PUD) +#define GPO10_GPIO (GPO10 | FUNC(2)) +#define GPO10_ADDR10 (GPO10 | FUNC(2)) +#define GPO11 (PIN(14,22) | PUD) +#define GPO11_GPIO (GPO11 | FUNC(0)) +#define GPO11_ADDR11 (GPO11 | FUNC(2)) +#define GPO12 (PIN(14,24) | PUD) +#define GPO12_GPIO (GPO12 | FUNC(0)) +#define GPO12_ADDR12 (GPO12 | FUNC(2)) +#define GPO13 (PIN(14,26) | PUD) +#define GPO13_GPIO (GPO13 | FUNC(0)) +#define GPO13_ADDR13 (GPO13 | FUNC(2)) +#define GPO14 (PIN(14,28) | PUD) +#define GPO14_GPIO (GPO14 | FUNC(0)) +#define GPO14_ADDR14 (GPO14 | FUNC(2)) +#define GPO15 (PIN(14,30) | PUD) +#define GPO15_GPIO (GPO15 | FUNC(0)) +#define GPO15_ADDR15 (GPO15 | FUNC(2)) + +#define GPP0 (PIN(15,0) | PUD) +#define GPP0_GPIO (GPP0 | FUNC(0)) +#define GPP1 (PIN(15,2) | PUD) +#define GPP1_GPIO (GPP1 | FUNC(0)) +#define GPP2 (PIN(15,4) | PUD) +#define GPP2_NWAIT (GPP2 | FUNC(2)) +#define GPP3 (PIN(15,6) | PUD) +#define GPP3_FALE (GPP3 | FUNC(2)) +#define GPP4 (PIN(15,8) | PUD) +#define GPP4_FCLE (GPP4 | FUNC(2)) +#define GPP5 (PIN(15,10) | PUD) +#define GPP5_FWE (GPP5 | FUNC(2)) +#define GPP6 (PIN(15,12) | PUD) +#define GPP6_FRE (GPP6 | FUNC(2)) +#define GPP7 (PIN(15,14) | PUD) +#define GPP7_RNB (GPP7 | FUNC(2)) +#define GPP8 (PIN(15,16) | PUD) +#define GPP8_GPIO (GPP8 | FUNC(0)) +#define GPP9 (PIN(15,18) | PUD) +#define GPP9_GPIO (GPP9 | FUNC(0)) +#define GPP10 (PIN(15,20) | PUD) +#define GPP10_GPIO (GPP10 | FUNC(0)) +#define GPP11 (PIN(15,22) | PUD) +#define GPP11_GPIO (GPP11 | FUNC(0)) +#define GPP12 (PIN(15,24) | PUD) +#define GPP12_GPIO (GPP12 | FUNC(0)) +#define GPP13 (PIN(15,26) | PUD) +#define GPP13_GPIO (GPP13 | FUNC(0)) +#define GPP14 (PIN(15,28) | PUD) +#define GPP14_GPIO (GPP14 | FUNC(0)) + +#define GPQ0 (PIN(16,0) | PUD) +#define GPQ0_GPIO (GPQ0 | FUNC(0)) +#define GPQ1 (PIN(16,2) | PUD) +#define GPQ1_GPIO (GPQ1 | FUNC(0)) +#define GPQ2 (PIN(16,4) | PUD) +#define GPQ2_GPIO (GPQ2 | FUNC(0)) +#define GPQ3 (PIN(16,8) | PUD) +#define GPQ3_GPIO (GPQ3 | FUNC(0)) +#define GPQ4 (PIN(16,8) | PUD) +#define GPQ4_GPIO (GPQ4 | FUNC(0)) +#define GPQ5 (PIN(16,10) | PUD) +#define GPQ5_GPIO (GPQ5 | FUNC(0)) +#define GPQ6 (PIN(16,12) | PUD) +#define GPQ6_GPIO (GPQ6 | FUNC(0)) +#define GPQ7 (PIN(16,14) | PUD) +#define GPQ7_GPIO (GPQ7 | FUNC(0)) +#define GPQ8 (PIN(16,16) | PUD) +#define GPQ8_GPIO (GPQ7 | FUNC(0)) + + +#endif /* __MACH_IOMUX_S3C64XX_H */ diff --git a/arch/arm/mach-samsung/include/mach/s3c-clocks.h b/arch/arm/mach-samsung/include/mach/s3c-clocks.h index f577306ba5..6920ca96aa 100644 --- a/arch/arm/mach-samsung/include/mach/s3c-clocks.h +++ b/arch/arm/mach-samsung/include/mach/s3c-clocks.h @@ -25,6 +25,9 @@ #ifdef CONFIG_ARCH_S3C24xx # include <mach/s3c24xx-clocks.h> #endif +#ifdef CONFIG_ARCH_S3C64xx +# include <mach/s3c64xx-clocks.h> +#endif #ifdef CONFIG_ARCH_S5PCxx # include <mach/s5pcxx-clocks.h> #endif diff --git a/arch/arm/mach-samsung/include/mach/s3c-generic.h b/arch/arm/mach-samsung/include/mach/s3c-generic.h index 329c2b47f2..e72b104c91 100644 --- a/arch/arm/mach-samsung/include/mach/s3c-generic.h +++ b/arch/arm/mach-samsung/include/mach/s3c-generic.h @@ -47,3 +47,20 @@ void s5p_init_dram_bank_lpddr2(phys_addr_t base, uint32_t mc0, uint32_t mc1, int void s5p_init_dram_bank_ddr2(phys_addr_t base, uint32_t mc0, uint32_t mc1, int bus16); uint32_t s5p_get_memory_size(void); #endif + +#ifdef CONFIG_ARCH_S3C64xx +unsigned s3c_set_epllclk(unsigned, unsigned, unsigned, unsigned); +uint32_t s3c_get_epllclk(void); +unsigned s3c_get_hsmmc_clk(int); +void s3c_set_hsmmc_clk(int, int, unsigned); +unsigned s3c6410_get_memory_size(void); +struct s3c6410_chipselect { + unsigned adr_setup_t; /* in [ns] */ + unsigned access_setup_t; /* in [ns] */ + unsigned access_t; /* in [ns] */ + unsigned cs_hold_t; /* in [ns] */ + unsigned adr_hold_t; /* in [ns] */ + unsigned char width; /* 8 or 16 */ +}; +int s3c6410_setup_chipselect(int, const struct s3c6410_chipselect*); +#endif diff --git a/arch/arm/mach-samsung/include/mach/s3c-iomap.h b/arch/arm/mach-samsung/include/mach/s3c-iomap.h index d34ace47cd..09a6891429 100644 --- a/arch/arm/mach-samsung/include/mach/s3c-iomap.h +++ b/arch/arm/mach-samsung/include/mach/s3c-iomap.h @@ -22,6 +22,9 @@ #ifdef CONFIG_ARCH_S3C24xx # include <mach/s3c24xx-iomap.h> #endif +#ifdef CONFIG_ARCH_S3C64xx +# include <mach/s3c64xx-iomap.h> +#endif #ifdef CONFIG_ARCH_S5PCxx # include <mach/s5pcxx-iomap.h> #endif diff --git a/arch/arm/mach-samsung/include/mach/s3c64xx-clocks.h b/arch/arm/mach-samsung/include/mach/s3c64xx-clocks.h new file mode 100644 index 0000000000..8aa60bcb04 --- /dev/null +++ b/arch/arm/mach-samsung/include/mach/s3c64xx-clocks.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2012 Juergen Beisert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define S3C_EPLL_LOCK (S3C_CLOCK_POWER_BASE + 0x08) +# define S3C_EPLL_LOCK_PLL_LOCKTIME(x) ((x) & 0xffff) +#define S3C_APLLCON (S3C_CLOCK_POWER_BASE + 0x0c) +# define S3C_APLLCON_ENABLE (1 << 31) +# define S3C_APLLCON_GET_MDIV(x) (((x) >> 16) & 0x3ff) +# define S3C_APLLCON_GET_PDIV(x) (((x) >> 8) & 0x3f) +# define S3C_APLLCON_GET_SDIV(x) ((x) & 0x7) +#define S3C_MPLLCON (S3C_CLOCK_POWER_BASE + 0x10) +# define S3C_MPLLCON_ENABLE (1 << 31) +# define S3C_MPLLCON_GET_MDIV(x) (((x) >> 16) & 0x3ff) +# define S3C_MPLLCON_GET_PDIV(x) (((x) >> 8) & 0x3f) +# define S3C_MPLLCON_GET_SDIV(x) ((x) & 0x7) +#define S3C_EPLLCON0 (S3C_CLOCK_POWER_BASE + 0x14) +# define S3C_EPLLCON0_ENABLE (1 << 31) +# define S3C_EPLLCON0_GET_MDIV(x) (((x) >> 16) & 0xff) +# define S3C_EPLLCON0_SET_MDIV(x) (((x) & 0xff) << 16) +# define S3C_EPLLCON0_GET_PDIV(x) (((x) >> 8) & 0x3f) +# define S3C_EPLLCON0_SET_PDIV(x) (((x) & 0x3f) << 8) +# define S3C_EPLLCON0_GET_SDIV(x) ((x) & 0x7) +# define S3C_EPLLCON0_SET_SDIV(x) ((x) & 0x7) +#define S3C_EPLLCON1 (S3C_CLOCK_POWER_BASE + 0x18) +# define S3C_EPLLCON1_GET_KDIV(x) ((x) & 0xffff) +# define S3C_EPLLCON1_SET_KDIV(x) ((x) & 0xffff) +#define S3C_CLKCON (S3C_CLOCK_POWER_BASE + 0xc) +#define S3C_CLKSLOW (S3C_CLOCK_POWER_BASE + 0x10) +#define S3C_CLKDIVN (S3C_CLOCK_POWER_BASE + 0x14) +#define S3C_CLK_SRC (S3C_CLOCK_POWER_BASE + 0x01c) +# define S3C_CLK_SRC_GET_MMC_SEL(x, v) (((v) >> (18 + (x * 2))) & 0x3) +# define S3C_CLK_SRC_SET_MMC_SEL(x, v) (((v) & 0x3) << (18 + (x * 2))) +# define S3C_CLK_SRC_UARTMPLL (1 << 13) +# define S3C_CLK_SRC_FOUTEPLL (1 << 2) +# define S3C_CLK_SRC_FOUTMPLL (1 << 1) +# define S3C_CLK_SRC_FOUTAPLL (1 << 0) +#define S3C_CLK_DIV0 (S3C_CLOCK_POWER_BASE + 0x020) +# define S3C_CLK_DIV0_GET_ADIV(x) ((x) & 0xf) +# define S3C_CLK_DIV0_GET_HCLK2(x) (((x) >> 9) & 0x7) +# define S3C_CLK_DIV0_GET_HCLK(x) (((x) >> 8) & 0x1) +# define S3C_CLK_DIV0_GET_PCLK(x) (((x) >> 12) & 0xf) +# define S3C_CLK_DIV0_SET_MPLL_DIV(x) (((x) & 0x1) << 4) +# define S3C_CLK_DIV0_GET_MPLL_DIV(x) (((x) >> 4) & 0x1) +# define S3C_CLK_DIV0_GET_MMC(x, v) (((v) >> (4 * x)) & 0xf) +# define S3C_CLK_DIV0_SET_MMC(x, v) (((v) & 0xf) << (4 * x)) +#define S3C_CLK_DIV2 (S3C_CLOCK_POWER_BASE + 0x028) +# define S3C_CLK_DIV2_UART_MASK (0xf << 16) +# define S3C_CLK_DIV2_SET_UART(x) ((x) << 16) +# define S3C_CLK_DIV2_GET_UART(x) (((x) >> 16) & 0xf) +#define S3C_SCLK_GATE (S3C_CLOCK_POWER_BASE + 0x038) +# define S3C_SCLK_GATE_UART (1 << 5) +# define S3C_SCLK_GATE_MMC(x) (1 << (24 + x)) +#define S3C_MISC_CON (S3C_CLOCK_POWER_BASE + 0x838) +# define S3C_MISC_CON_SYN667 (1 << 19) +#define S3C_OTHERS (S3C_CLOCK_POWER_BASE + 0x900) +# define S3C_OTHERS_CLK_SELECT (1 << 6) diff --git a/arch/arm/mach-samsung/include/mach/s3c64xx-iomap.h b/arch/arm/mach-samsung/include/mach/s3c64xx-iomap.h new file mode 100644 index 0000000000..9cc3a1bcba --- /dev/null +++ b/arch/arm/mach-samsung/include/mach/s3c64xx-iomap.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012 Juergen Beisert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* S3C64xx device base addresses */ +#define S3C_SROM_SFR 0x70000000 +#define S3C_NAND_BASE 0x70200000 +#define S3C_SDI0_BASE 0x7c200000 +#define S3C_SDI0_SIZE 0x100 +#define S3C_SDI1_BASE 0x7c300000 +#define S3C_SDI1_SIZE 0x100 +#define S3C_SDI2_BASE 0x7c400000 +#define S3C_SDI2_SIZE 0x100 +#define S3C_DRAMC 0x7e001000 +#define S3C_WATCHDOG_BASE 0x7e004000 +#define S3C_CLOCK_POWER_BASE 0x7e00f000 +#define S3C_UART_BASE 0x7f005000 +#define S3C_TIMER_BASE 0x7f006000 +#define S3C_GPIO_BASE 0x7f008000 + +#define S3C_UART1_BASE (S3C_UART_BASE) +#define S3C_UART1_SIZE 0x400 +#define S3C_UART2_BASE (S3C_UART_BASE + 0x400) +#define S3C_UART2_SIZE 0x400 +#define S3C_UART3_BASE (S3C_UART_BASE + 0x800) +#define S3C_UART3_SIZE 0x400 +#define S3C_UART4_BASE (S3C_UART_BASE + 0xc00) +#define S3C_UART4_SIZE 0x400 + +#define S3C_SDRAM_BASE 0x50000000 +#define S3C_SDRAM_END (S3C_SDRAM_BASE + 0x10000000) + +#define S3C_SROM_BW (S3C_SROM_SFR) +#define S3C_SROM_BC0 (S3C_SROM_SFR + 4) + +#define S3C_CS0_BASE 0x10000000 +#define S3C_CS1_BASE 0x18000000 +#define S3C_CS2_BASE 0x20000000 +#define S3C_CS3_BASE 0x28000000 +#define S3C_CS4_BASE 0x30000000 +#define S3C_CS5_BASE 0x38000000 diff --git a/arch/arm/mach-samsung/include/mach/s5pcxx-iomap.h b/arch/arm/mach-samsung/include/mach/s5pcxx-iomap.h index 248f868b1b..448e3b8046 100644 --- a/arch/arm/mach-samsung/include/mach/s5pcxx-iomap.h +++ b/arch/arm/mach-samsung/include/mach/s5pcxx-iomap.h @@ -45,8 +45,6 @@ #define S3C_UART2_SIZE 0x400 #define S3C_UART3_BASE (S3C_UART_BASE + 0x800) #define S3C_UART3_SIZE 0x400 -#define S3C_UART_HAS_UBRDIVSLOT -#define S3C_UART_HAS_UINTM #define S5P_DMC0_BASE 0xF0000000 #define S5P_DMC1_BASE 0xF1400000 diff --git a/arch/arm/mach-samsung/mem-s3c64xx.c b/arch/arm/mach-samsung/mem-s3c64xx.c new file mode 100644 index 0000000000..aca2cf5066 --- /dev/null +++ b/arch/arm/mach-samsung/mem-s3c64xx.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 Juergen Beisert + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <errno.h> +#include <io.h> +#include <mach/s3c-iomap.h> +#include <mach/s3c-generic.h> + +#define S3C_DRAMC_CHIP_0_CFG (S3C_DRAMC + 0x200) + +/* note: this routine honors the first memory bank only */ +unsigned s3c6410_get_memory_size(void) +{ + unsigned reg = readl(S3C_DRAMC_CHIP_0_CFG) & 0xff; + + return ~(reg << 24) + 1; +} + +/* configure the timing of one of the available external chip select lines */ +int s3c6410_setup_chipselect(int no, const struct s3c6410_chipselect *c) +{ + unsigned per_t = 1000000000 / s3c_get_hclk(); + unsigned tacs, tcos, tacc, tcoh, tcah, shift; + uint32_t reg; + + /* start of cycle to chip select assertion (= address/data setup) */ + tacs = DIV_ROUND_UP(c->adr_setup_t, per_t); + /* start of CS to read/write assertion (= access setup) */ + tcos = DIV_ROUND_UP(c->access_setup_t, per_t); + /* length of read/write assertion (= access lenght) */ + tacc = DIV_ROUND_UP(c->access_t, per_t) - 1; + /* CS hold after access is finished */ + tcoh = DIV_ROUND_UP(c->cs_hold_t, per_t); + /* adress/data hold after CS is deasserted */ + tcah = DIV_ROUND_UP(c->adr_hold_t, per_t); + + shift = no * 4; + reg = readl(S3C_SROM_BW) & ~(0xf << shift); + if (c->width == 16) + reg |= 0x1 << shift; + writel(reg, S3C_SROM_BW); +#ifdef DEBUG + if (tacs > 15 || tcos > 15 || tacc > 31 || tcoh > 15 || tcah > 15) { + pr_err("At least one of the timings are invalid\n"); + return -EINVAL; + } + pr_info("Will write 0x%08X\n", tacs << 28 | tcos << 24 | tacc << 16 | + tcoh << 12 | tcah << 8); +#endif + writel(tacs << 28 | tcos << 24 | tacc << 16 | tcoh << 12 | tcah << 8, + S3C_SROM_BC0 + shift); + + return 0; +} diff --git a/arch/arm/mach-samsung/s3c-timer.c b/arch/arm/mach-samsung/s3c-timer.c index 6665c8c3d5..fb3cda074f 100644 --- a/arch/arm/mach-samsung/s3c-timer.c +++ b/arch/arm/mach-samsung/s3c-timer.c @@ -37,11 +37,19 @@ #define S3C_TCNTB4 (S3C_TIMER_BASE + 0x3c) #define S3C_TCNTO4 (S3C_TIMER_BASE + 0x40) -#define TIMER_WIDTH 16 -#define TIMER_SHIFT 10 -#define PRE_MUX 3 -#define PRE_MUX_ADD 1 +#ifdef CONFIG_ARCH_S3C24xx +# define TIMER_WIDTH 16 +# define TIMER_SHIFT 10 +# define PRE_MUX 3 +# define PRE_MUX_ADD 1 static const uint32_t max = 0x0000ffff; +#else /* for S3C64xx and S5Pxx */ +# define TIMER_WIDTH 32 +# define TIMER_SHIFT 10 +# define PRE_MUX 4 +# define PRE_MUX_ADD 0 +static const uint32_t max = ~0; +#endif static void s3c_init_t4_clk_source(void) { |