[U-Boot] [PATCH 1/4 v2] s5pc1xx: support Samsung s5pc1xx SoC

This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com --- cpu/arm_cortexa8/s5pc1xx/Makefile | 53 ++++++ cpu/arm_cortexa8/s5pc1xx/cache.c | 43 +++++ cpu/arm_cortexa8/s5pc1xx/clock.c | 302 ++++++++++++++++++++++++++++++ cpu/arm_cortexa8/s5pc1xx/cpu_info.c | 75 ++++++++ cpu/arm_cortexa8/s5pc1xx/reset.S | 47 +++++ cpu/arm_cortexa8/s5pc1xx/timer.c | 195 +++++++++++++++++++ include/asm-arm/arch-s5pc1xx/clk.h | 46 +++++ include/asm-arm/arch-s5pc1xx/clock.h | 100 ++++++++++ include/asm-arm/arch-s5pc1xx/cpu.h | 73 +++++++ include/asm-arm/arch-s5pc1xx/gpio.h | 127 +++++++++++++ include/asm-arm/arch-s5pc1xx/hardware.h | 63 ++++++ include/asm-arm/arch-s5pc1xx/i2c.h | 43 +++++ include/asm-arm/arch-s5pc1xx/interrupt.h | 40 ++++ include/asm-arm/arch-s5pc1xx/mem.h | 58 ++++++ include/asm-arm/arch-s5pc1xx/power.h | 42 ++++ include/asm-arm/arch-s5pc1xx/pwm.h | 65 +++++++ include/asm-arm/arch-s5pc1xx/uart.h | 53 ++++++ 17 files changed, 1425 insertions(+), 0 deletions(-) create mode 100644 cpu/arm_cortexa8/s5pc1xx/Makefile create mode 100644 cpu/arm_cortexa8/s5pc1xx/cache.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/clock.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/cpu_info.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/reset.S create mode 100644 cpu/arm_cortexa8/s5pc1xx/timer.c create mode 100644 include/asm-arm/arch-s5pc1xx/clk.h create mode 100644 include/asm-arm/arch-s5pc1xx/clock.h create mode 100644 include/asm-arm/arch-s5pc1xx/cpu.h create mode 100644 include/asm-arm/arch-s5pc1xx/gpio.h create mode 100644 include/asm-arm/arch-s5pc1xx/hardware.h create mode 100644 include/asm-arm/arch-s5pc1xx/i2c.h create mode 100644 include/asm-arm/arch-s5pc1xx/interrupt.h create mode 100644 include/asm-arm/arch-s5pc1xx/mem.h create mode 100644 include/asm-arm/arch-s5pc1xx/power.h create mode 100644 include/asm-arm/arch-s5pc1xx/pwm.h create mode 100644 include/asm-arm/arch-s5pc1xx/uart.h
diff --git a/cpu/arm_cortexa8/s5pc1xx/Makefile b/cpu/arm_cortexa8/s5pc1xx/Makefile new file mode 100644 index 0000000..e08d9d8 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, lg@denx.de +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS = reset.o + +COBJS += cache.o +COBJS += clock.o +COBJS += cpu_info.o +COBJS += timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/arm_cortexa8/s5pc1xx/cache.c b/cpu/arm_cortexa8/s5pc1xx/cache.c new file mode 100644 index 0000000..8652a45 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/cache.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/cache.h> + +void l2_cache_enable(void) +{ + unsigned long i; + + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); + __asm__ __volatile__("orr %0, %0, #0x2":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); +} + +void l2_cache_disable(void) +{ + unsigned long i; + + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); + __asm__ __volatile__("bic %0, %0, #0x2":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); +} diff --git a/cpu/arm_cortexa8/s5pc1xx/clock.c b/cpu/arm_cortexa8/s5pc1xx/clock.c new file mode 100644 index 0000000..da56fda --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/clock.c @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/clock.h> + +#define APLL 0 +#define MPLL 1 +#define EPLL 2 +#define HPLL 3 +#define VPLL 4 + +#ifndef CONFIG_SYS_CLK_FREQ_C100 +#define CONFIG_SYS_CLK_FREQ_C100 12000000 +#endif +#ifndef CONFIG_SYS_CLK_FREQ_C110 +#define CONFIG_SYS_CLK_FREQ_C110 24000000 +#endif + +/* + * CONFIG_SYS_CLK_FREQ_C1xx should be defined as the input frequency + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ + */ +unsigned long get_pll_clk(int pllreg) +{ + struct s5pc100_clock *clk_c100 = + (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + struct s5pc110_clock *clk_c110 = + (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + if (cpu_is_s5pc110()) + r = readl(&clk_c110->APLL_CON); + else + r = readl(&clk_c100->APLL_CON); + break; + case MPLL: + if (cpu_is_s5pc110()) + r = readl(&clk_c110->MPLL_CON); + else + r = readl(&clk_c100->MPLL_CON); + break; + case EPLL: + if (cpu_is_s5pc110()) + r = readl(&clk_c110->EPLL_CON); + else + r = readl(&clk_c100->EPLL_CON); + break; + case HPLL: + if (cpu_is_s5pc110()) { + puts("s5pc110 don't use HPLL\n"); + return 0; + } + r = readl(&clk_c100->HPLL_CON); + break; + case VPLL: + if (cpu_is_s5pc100()) { + puts("s5pc100 don't use VPLL\n"); + return 0; + } + r = readl(&clk_c110->VPLL_CON); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + if (cpu_is_s5pc110()) { + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [25:16] + * EPLL_CON: MIDV [24:16] + * VPLL_CON: MIDV [24:16] + */ + if (pllreg == APLL || pllreg == MPLL) + mask = 0x3ff; + else + mask = 0x1ff; + } else { + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [23:16] + * EPLL_CON: MIDV [23:16] + * HPLL_CON: MIDV [23:16] + */ + if (pllreg == APLL) + mask = 0x3ff; + else + mask = 0x0ff; + } + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + if (cpu_is_s5pc110()) { + freq = CONFIG_SYS_CLK_FREQ_C110; + if (pllreg == APLL) { + if (s < 1) + s = 1; + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ + fout = m * (freq / (p * (1 << (s - 1)))); + } else + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + fout = m * (freq / (p * (1 << s))); + } else { + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + freq = CONFIG_SYS_CLK_FREQ_C100; + fout = m * (freq / (p * (1 << s))); + } + + return fout; +} + +/* return ARMCORE frequency */ +unsigned long get_arm_clk(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio, arm_ratio; + + div = readl(&clk->DIV0); + if (cpu_is_s5pc110()) { + /* ARM_RATIO: don't use */ + arm_ratio = 0; + /* APLL_RATIO: [2:0] */ + apll_ratio = div & 0x7; + } else { + /* ARM_RATIO: [6:4] */ + arm_ratio = (div >> 4) & 0x7; + /* APLL_RATIO: [0] */ + apll_ratio = div & 0x1; + } + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll / (arm_ratio + 1); + + return armclk; +} + +/* return FCLK frequency */ +unsigned long get_fclk(void) +{ + return get_pll_clk(APLL); +} + +/* return MCLK frequency */ +unsigned long get_mclk(void) +{ + return get_pll_clk(MPLL); +} + +/* s5pc100: return HCLKD0 frequency */ +unsigned long get_hclk(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long hclkd0; + uint div, d0_bus_ratio; + + div = readl(&clk->DIV0); + /* D0_BUS_RATIO: [10:8] */ + d0_bus_ratio = (div >> 8) & 0x7; + + hclkd0 = get_arm_clk() / (d0_bus_ratio + 1); + + return hclkd0; +} + +/* s5pc100: return PCLKD0 frequency */ +unsigned long get_pclkd0(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long pclkd0; + uint div, pclkd0_ratio; + + div = readl(&clk->DIV0); + /* PCLKD0_RATIO: [14:12] */ + pclkd0_ratio = (div >> 12) & 0x7; + + pclkd0 = get_hclk() / (pclkd0_ratio + 1); + + return pclkd0; +} + +/* s5pc100: return PCLKD1 frequency */ +unsigned long get_pclkd1(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long d1_bus, pclkd1; + uint div, d1_bus_ratio, pclkd1_ratio; + + div = readl(&clk->DIV0); + /* D1_BUS_RATIO: [14:12] */ + d1_bus_ratio = (div >> 12) & 0x7; + /* PCLKD1_RATIO: [18:16] */ + pclkd1_ratio = (div >> 16) & 0x7; + + /* ASYNC Mode */ + d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1); + pclkd1 = d1_bus / (pclkd1_ratio + 1); + + return pclkd1; +} + +/* s5pc110: return HCLKs frequency */ +unsigned long get_hclk_sys(int dom) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long hclk; + unsigned int div; + unsigned int offset; + unsigned int hclk_sys_ratio; + + if (dom == CLK_M) + return get_hclk(); + + div = readl(&clk->DIV0); + + /* + * HCLK_MSYS_RATIO: [10:8] + * HCLK_DSYS_RATIO: [19:16] + * HCLK_PSYS_RATIO: [27:24] + */ + offset = 8 + (dom << 0x3); + + hclk_sys_ratio = (div >> offset) & 0xf; + + hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1); + + return hclk; +} + +/* s5pc110: return PCLKs frequency */ +unsigned long get_pclk_sys(int dom) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long pclk; + unsigned int div; + unsigned int offset; + unsigned int pclk_sys_ratio; + + div = readl(&clk->DIV0); + + /* + * PCLK_MSYS_RATIO: [14:12] + * PCLK_DSYS_RATIO: [22:20] + * PCLK_PSYS_RATIO: [30:28] + */ + offset = 12 + (dom << 0x3); + + pclk_sys_ratio = (div >> offset) & 0x7; + + pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1); + + return pclk; +} + +/* return peripheral clock */ +unsigned long get_pclk(void) +{ + if (cpu_is_s5pc110()) + return get_pclk_sys(CLK_P); + else + return get_pclkd1(); +} + +/* return UCLK frequency */ +unsigned long get_uclk(void) +{ + return get_pll_clk(EPLL); +} diff --git a/cpu/arm_cortexa8/s5pc1xx/cpu_info.c b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c new file mode 100644 index 0000000..eacacc8 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clk.h> + +/* Default is s5pc100 */ +unsigned int s5pc1xx_cpu_id = 0xC100; + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + s5pc1xx_cpu_id = readl(S5PC1XX_PRO_ID); + s5pc1xx_cpu_id = 0xC000 | ((s5pc1xx_cpu_id & 0x00FFF000) >> 12); + + return 0; +} +#endif + +u32 get_device_type(void) +{ + return s5pc1xx_cpu_id; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU:\tS5P%X@%sMHz\n", + s5pc1xx_cpu_id, strmhz(buf, get_arm_clk())); + if (cpu_is_s5pc110()) { + printf("\tAPLL = %s MHz, ", strmhz(buf, get_fclk())); + printf("MPLL = %s MHz, ", strmhz(buf, get_mclk())); + printf("EPLL = %s MHz\n", strmhz(buf, get_uclk())); + + printf("\tHclk: Msys %s MHz, ", + strmhz(buf, get_hclk_sys(CLK_M))); + printf("Dsys %7s MHz, ", strmhz(buf, get_hclk_sys(CLK_D))); + printf("Psys %7s MHz\n", strmhz(buf, get_hclk_sys(CLK_P))); + + printf("\tPclk: Msys %s MHz, ", + strmhz(buf, get_pclk_sys(CLK_M))); + printf("Dsys %7s MHz, ", strmhz(buf, get_pclk_sys(CLK_D))); + printf("Psys %7s MHz\n", strmhz(buf, get_pclk_sys(CLK_P))); + } else { + printf("\tFclk = %s MHz\n", strmhz(buf, get_fclk())); + printf("\tHclkD0 = %s MHz\n", strmhz(buf, get_hclk())); + printf("\tPclkD0 = %s MHz\n", strmhz(buf, get_pclkd0())); + printf("\tPclkD1 = %s MHz\n", strmhz(buf, get_pclkd1())); + } + + return 0; +} +#endif diff --git a/cpu/arm_cortexa8/s5pc1xx/reset.S b/cpu/arm_cortexa8/s5pc1xx/reset.S new file mode 100644 index 0000000..7f6ff9c --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/reset.S @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2009 Samsung Electronics. + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm/arch/cpu.h> + +#define S5PC100_SWRESET 0xE0200000 +#define S5PC110_SWRESET 0xE0102000 + +.globl reset_cpu +reset_cpu: + ldr r1, =S5PC1XX_PRO_ID + ldr r2, [r1] + ldr r4, =0x00010000 + and r4, r2, r4 + cmp r4, #0 + bne 110f + /* S5PC100 */ + ldr r1, =S5PC100_SWRESET + ldr r2, =0xC100 + b 200f +110: /* S5PC110 */ + ldr r1, =S5PC110_SWRESET + mov r2, #1 +200: + str r2, [r1] +_loop_forever: + b _loop_forever diff --git a/cpu/arm_cortexa8/s5pc1xx/timer.c b/cpu/arm_cortexa8/s5pc1xx/timer.c new file mode 100644 index 0000000..f3d94b8 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/timer.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Heungjun Kim riverful.kim@samsung.com + * Inki Dae inki.dae@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/pwm.h> +#include <asm/arch/clk.h> + +#define PRESCALER_1 (16 - 1) /* prescaler of timer 2, 3, 4 */ +#define MUX_DIV_2 1 /* 1/2 period */ +#define MUX_DIV_4 2 /* 1/4 period */ +#define MUX_DIV_8 3 /* 1/8 period */ +#define MUX_DIV_16 4 /* 1/16 period */ +#define MUX4_DIV_SHIFT 16 + +#define TCON_TIMER4_SHIFT 20 + +static unsigned long count_value; + +/* Internal tick units */ +static unsigned long long timestamp; /* Monotonic incrementing timer */ +static unsigned long lastdec; /* Last decremneter snapshot */ + +/* macro to read the 16 bit timer */ +static inline struct s5pc1xx_timer *s5pc1xx_get_base_timer(void) +{ + if (cpu_is_s5pc110()) + return (struct s5pc1xx_timer *)S5PC110_TIMER_BASE; + else + return (struct s5pc1xx_timer *)S5PC100_TIMER_BASE; +} + +int timer_init(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + u32 val; + + /* + * @ PWM Timer 4 + * Timer Freq(HZ) = + * PCLK / { (prescaler_value + 1) * (divider_value) } + */ + + /* set prescaler : 16 */ + /* set divider : 2 */ + writel((PRESCALER_1 & 0xff) << 8, &timer->TCFG0); + writel((MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT, &timer->TCFG1); + + if (count_value == 0) { + /* reset initial value */ + /* count_value = 2085937.5(HZ) (per 1 sec)*/ + count_value = get_pclk() / ((PRESCALER_1 + 1) * + (MUX_DIV_2 + 1)); + + /* count_value / 100 = 20859.375(HZ) (per 10 msec) */ + count_value = count_value / 100; + } + + /* set count value */ + writel(count_value, &timer->TCNTB4); + lastdec = count_value; + + val = (readl(&timer->TCON) & ~(0x07 << TCON_TIMER4_SHIFT)) | + S5PC1XX_TCON4_AUTO_RELOAD; + + /* auto reload & manual update */ + writel(val | S5PC1XX_TCON4_UPDATE, &timer->TCON); + + /* start PWM timer 4 */ + writel(val | S5PC1XX_TCON4_START, &timer->TCON); + + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ +void reset_timer(void) +{ + reset_timer_masked(); +} + +unsigned long get_timer(unsigned long base) +{ + return get_timer_masked() - base; +} + +void set_timer(unsigned long t) +{ + timestamp = t; +} + +/* delay x useconds */ +void udelay(unsigned long usec) +{ + unsigned long tmo, tmp; + + if (usec >= 1000) { + /* + * if "big" number, spread normalization + * to seconds + * 1. start to normalize for usec to ticks per sec + * 2. find number of "ticks" to wait to achieve target + * 3. finish normalize. + */ + tmo = usec / 1000; + tmo *= (CONFIG_SYS_HZ * count_value / 10); + tmo /= 1000; + } else { + /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ * count_value / 10; + tmo /= (1000 * 1000); + } + + /* get current timestamp */ + tmp = get_timer(0); + + /* if setting this fordward will roll time stamp */ + /* reset "advancing" timestamp to 0, set lastdec value */ + /* else, set advancing stamp wake up time */ + if ((tmo + tmp + 1) < tmp) + reset_timer_masked(); + else + tmo += tmp; + + /* loop till event */ + while (get_timer_masked() < tmo) + ; /* nop */ +} + +void reset_timer_masked(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + + /* reset time */ + lastdec = readl(&timer->TCNTO4); + timestamp = 0; +} + +unsigned long get_timer_masked(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + unsigned long now = readl(&timer->TCNTO4); + + if (lastdec >= now) + timestamp += lastdec - now; + else + timestamp += lastdec + count_value - now; + + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/include/asm-arm/arch-s5pc1xx/clk.h b/include/asm-arm/arch-s5pc1xx/clk.h new file mode 100644 index 0000000..9c13a71 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/clk.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_ + +unsigned long get_pll_clk(int pllreg); +unsigned long get_arm_clk(void); +unsigned long get_fclk(void); +unsigned long get_mclk(void); +unsigned long get_hclk(void); +unsigned long get_pclk(void); +unsigned long get_uclk(void); + +/*s5pc110 */ +#define CLK_M 0 +#define CLK_D 1 +#define CLK_P 2 + +unsigned long get_hclk_sys(int dom); +unsigned long get_pclk_sys(int dom); + +/* s5pc100 */ +unsigned long get_pclkd0(void); +unsigned long get_pclkd1(void); + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/clock.h b/include/asm-arm/arch-s5pc1xx/clock.h new file mode 100644 index 0000000..f11c9ce --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/clock.h @@ -0,0 +1,100 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_CLOCK_H_ +#define __ASM_ARM_ARCH_CLOCK_H_ + +/* + * Clock control + */ + +/* Clock Register */ + +#ifndef __ASSEMBLY__ +struct s5pc100_clock { + unsigned long APLL_LOCK; + unsigned long MPLL_LOCK; + unsigned long EPLL_LOCK; + unsigned long HPLL_LOCK; + unsigned char res1[0xf0]; + unsigned long APLL_CON; + unsigned long MPLL_CON; + unsigned long EPLL_CON; + unsigned long HPLL_CON; + unsigned char res2[0xf0]; + unsigned long SRC0; + unsigned long SRC1; + unsigned long SRC2; + unsigned long SRC3; + unsigned char res3[0xf0]; + unsigned long DIV0; + unsigned long DIV1; + unsigned long DIV2; + unsigned long DIV3; + unsigned long DIV4; + unsigned char res4[0x1ec]; + unsigned long GATE_D00; + unsigned long GATE_D01; + unsigned long GATE_D02; + unsigned char res5[0x54]; + unsigned long GATE_SCLK0; + unsigned long GATE_SCLK1; +}; + +struct s5pc110_clock { + unsigned long APLL_LOCK; + unsigned char res1[0x4]; + unsigned long MPLL_LOCK; + unsigned char res2[0x4]; + unsigned long EPLL_LOCK; + unsigned char res3[0xc]; + unsigned long VPLL_LOCK; + unsigned char res4[0xdc]; + unsigned long APLL_CON; + unsigned char res5[0x4]; + unsigned long MPLL_CON; + unsigned char res6[0x4]; + unsigned long EPLL_CON; + unsigned char res7[0xc]; + unsigned long VPLL_CON; + unsigned char res8[0xdc]; + unsigned long SRC0; + unsigned long SRC1; + unsigned long SRC2; + unsigned long SRC3; + unsigned char res9[0xf0]; + unsigned long DIV0; + unsigned long DIV1; + unsigned long DIV2; + unsigned long DIV3; + unsigned long DIV4; + unsigned char res10[0x1ec]; + unsigned long GATE_D00; + unsigned long GATE_D01; + unsigned long GATE_D02; + unsigned char res11[0x54]; + unsigned long GATE_SCLK0; + unsigned long GATE_SCLK1; +}; +#endif + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/cpu.h b/include/asm-arm/arch-s5pc1xx/cpu.h new file mode 100644 index 0000000..c7d7183 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/cpu.h @@ -0,0 +1,73 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _S5PC1XX_CPU_H +#define _S5PC1XX_CPU_H + +#include <asm/hardware.h> + +#define S5PC1XX_ADDR_BASE 0xe0000000 +#define S5P_ADDR(x) (S5PC1XX_ADDR_BASE + (x)) + +#define S5PC1XX_CLOCK_BASE 0xE0100000 +#define S5P_PA_CLK_OTHERS S5P_ADDR(0x00200000) /* Clock Others Base */ + +/* Note that write the macro by address order */ +#define S5PC100_VIC0_BASE 0xE4000000 +#define S5PC100_VIC1_BASE 0xE4100000 +#define S5PC100_VIC2_BASE 0xE4200000 +#define S5PC100_SROMC_BASE 0xE7000000 +#define S5PC100_ONENAND_BASE 0xE7100000 +#define S5PC100_WATCHDOG_BASE 0xEA200000 + +#define S5PC110_WATCHDOG_BASE 0xE2700000 +#define S5PC110_SROMC_BASE 0xE8000000 +#define S5PC110_VIC0_BASE 0xF2000000 +#define S5PC110_VIC1_BASE 0xF2100000 +#define S5PC110_VIC2_BASE 0xF2200000 +#define S5PC110_VIC3_BASE 0xF2300000 + +/* + * Chip ID + */ +#define S5PC1XX_CHIP_ID(x) (0xE0000000 + (x)) +#define S5PC1XX_PRO_ID S5PC1XX_CHIP_ID(0) +#define S5PC1XX_OMR S5PC1XX_CHIP_ID(4) + +#ifndef __ASSEMBLY__ +/* CPU detection macros */ +extern unsigned int s5pc1xx_cpu_id; + +#define IS_SAMSUNG_TYPE(type, id) \ +static inline int is_##type(void) \ +{ \ + return (s5pc1xx_cpu_id == (id)) ? 1 : 0; \ +} + +IS_SAMSUNG_TYPE(s5pc100, 0xc100) +IS_SAMSUNG_TYPE(s5pc110, 0xc110) + +#define cpu_is_s5pc100() is_s5pc100() +#define cpu_is_s5pc110() is_s5pc110() +#endif + +#endif /* _S5PC1XX_CPU_H */ diff --git a/include/asm-arm/arch-s5pc1xx/gpio.h b/include/asm-arm/arch-s5pc1xx/gpio.h new file mode 100644 index 0000000..26d0950 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/gpio.h @@ -0,0 +1,127 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __S5PC1XX_GPIO_H +#define __S5PC1XX_GPIO_H + +/* GPIO Bank Base */ +#define S5PC100_GPIO_BASE(x) (0xE0300000 + (x)) +#define S5PC110_GPIO_BASE(x) (0xE0200000 + (x)) + +/* S5PC100 bank offset */ +#define S5PC100_GPIO_A0_OFFSET 0x000 +#define S5PC100_GPIO_A1_OFFSET 0x020 +#define S5PC100_GPIO_B_OFFSET 0x040 +#define S5PC100_GPIO_C_OFFSET 0x060 +#define S5PC100_GPIO_D_OFFSET 0x080 +#define S5PC100_GPIO_E0_OFFSET 0x0A0 +#define S5PC100_GPIO_E1_OFFSET 0x0C0 +#define S5PC100_GPIO_F0_OFFSET 0x0E0 +#define S5PC100_GPIO_F1_OFFSET 0x100 +#define S5PC100_GPIO_F2_OFFSET 0x120 +#define S5PC100_GPIO_F3_OFFSET 0x140 +#define S5PC100_GPIO_G0_OFFSET 0x160 +#define S5PC100_GPIO_G1_OFFSET 0x180 +#define S5PC100_GPIO_G2_OFFSET 0x1A0 +#define S5PC100_GPIO_G3_OFFSET 0x1C0 +#define S5PC100_GPIO_I_OFFSET 0x1E0 +#define S5PC100_GPIO_J0_OFFSET 0x200 +#define S5PC100_GPIO_J1_OFFSET 0x220 +#define S5PC100_GPIO_J2_OFFSET 0x240 +#define S5PC100_GPIO_J3_OFFSET 0x260 +#define S5PC100_GPIO_J4_OFFSET 0x280 +#define S5PC100_GPIO_K0_OFFSET 0x2A0 +#define S5PC100_GPIO_K1_OFFSET 0x2C0 +#define S5PC100_GPIO_K2_OFFSET 0x2E0 +#define S5PC100_GPIO_K3_OFFSET 0x300 +#define S5PC100_GPIO_L0_OFFSET 0x320 +#define S5PC100_GPIO_L1_OFFSET 0x340 +#define S5PC100_GPIO_L2_OFFSET 0x360 +#define S5PC100_GPIO_L3_OFFSET 0x380 +#define S5PC100_GPIO_L4_OFFSET 0x3A0 +#define S5PC100_GPIO_H0_OFFSET 0xC00 +#define S5PC100_GPIO_H1_OFFSET 0xC20 +#define S5PC100_GPIO_H2_OFFSET 0xC40 +#define S5PC100_GPIO_H3_OFFSET 0xC60 + +/* S5PC110 bank offset */ +#define S5PC110_GPIO_A0_OFFSET 0x000 +#define S5PC110_GPIO_A1_OFFSET 0x020 +#define S5PC110_GPIO_B_OFFSET 0x040 +#define S5PC110_GPIO_C0_OFFSET 0x060 +#define S5PC110_GPIO_C1_OFFSET 0x080 +#define S5PC110_GPIO_D0_OFFSET 0x0A0 +#define S5PC110_GPIO_D1_OFFSET 0x0C0 +#define S5PC110_GPIO_E0_OFFSET 0x0E0 +#define S5PC110_GPIO_E1_OFFSET 0x110 +#define S5PC110_GPIO_F0_OFFSET 0x120 +#define S5PC110_GPIO_F1_OFFSET 0x140 +#define S5PC110_GPIO_F2_OFFSET 0x160 +#define S5PC110_GPIO_F3_OFFSET 0x180 +#define S5PC110_GPIO_G0_OFFSET 0x1A0 +#define S5PC110_GPIO_G1_OFFSET 0x1C0 +#define S5PC110_GPIO_G2_OFFSET 0x1E0 +#define S5PC110_GPIO_G3_OFFSET 0x200 +#define S5PC110_GPIO_I_OFFSET 0x220 +#define S5PC110_GPIO_J0_OFFSET 0x240 +#define S5PC110_GPIO_J1_OFFSET 0x260 +#define S5PC110_GPIO_J2_OFFSET 0x280 +#define S5PC110_GPIO_J3_OFFSET 0x2A0 +#define S5PC110_GPIO_J4_OFFSET 0x2C0 +#define S5PC110_GPIO_MP0_1_OFFSET 0x2E0 +#define S5PC110_GPIO_MP0_2_OFFSET 0x300 +#define S5PC110_GPIO_MP0_3_OFFSET 0x320 +#define S5PC110_GPIO_MP0_4_OFFSET 0x340 +#define S5PC110_GPIO_MP0_5_OFFSET 0x360 +#define S5PC110_GPIO_MP0_6_OFFSET 0x380 +#define S5PC110_GPIO_MP0_7_OFFSET 0x3A0 +#define S5PC110_GPIO_MP1_0_OFFSET 0x3C0 +#define S5PC110_GPIO_MP1_1_OFFSET 0x3E0 +#define S5PC110_GPIO_MP1_2_OFFSET 0x410 +#define S5PC110_GPIO_MP1_3_OFFSET 0x420 +#define S5PC110_GPIO_MP1_4_OFFSET 0x440 +#define S5PC110_GPIO_MP1_5_OFFSET 0x460 +#define S5PC110_GPIO_MP1_6_OFFSET 0x480 +#define S5PC110_GPIO_MP1_7_OFFSET 0x4A0 +#define S5PC110_GPIO_MP1_8_OFFSET 0x4C0 +#define S5PC110_GPIO_MP2_0_OFFSET 0x4E0 +#define S5PC110_GPIO_MP2_1_OFFSET 0x510 +#define S5PC110_GPIO_MP2_2_OFFSET 0x520 +#define S5PC110_GPIO_MP2_3_OFFSET 0x540 +#define S5PC110_GPIO_MP2_4_OFFSET 0x560 +#define S5PC110_GPIO_MP2_5_OFFSET 0x580 +#define S5PC110_GPIO_MP2_6_OFFSET 0x5A0 +#define S5PC110_GPIO_MP2_7_OFFSET 0x5C0 +#define S5PC110_GPIO_MP2_8_OFFSET 0x5E0 +#define S5PC110_GPIO_H0_OFFSET 0xC00 +#define S5PC110_GPIO_H1_OFFSET 0xC20 +#define S5PC110_GPIO_H2_OFFSET 0xC40 +#define S5PC110_GPIO_H3_OFFSET 0xC60 + +/* GPIO bank Offset */ +#define S5PC1XX_GPIO_CON_OFFSET 0x0 +#define S5PC1XX_GPIO_DAT_OFFSET 0x4 +#define S5PC1XX_GPIO_PULL_OFFSET 0x8 +#define S5PC1XX_GPIO_DRV_OFFSET 0xc +#define S5PC1XX_GPIO_PDNCON_OFFSET 0x10 +#define S5PC1XX_GPIO_PDNPULL_OFFSET 0x14 + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/hardware.h b/include/asm-arm/arch-s5pc1xx/hardware.h new file mode 100644 index 0000000..ca95c3d --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/hardware.h @@ -0,0 +1,63 @@ +/* + * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400 + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, lg@denx.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ARCH_HARDWARE_H_ +#define _ARCH_HARDWARE_H_ + +#include <asm/sizes.h> + +#ifndef __ASSEMBLY__ +#define UData(Data) ((unsigned long)(Data)) + +#define __REG(x) (*(vu_long *)(x)) +#define __REGl(x) (*(vu_long *)(x)) +#define __REGw(x) (*(vu_short *)(x)) +#define __REGb(x) (*(vu_char *)(x)) +#define __REG2(x, y) (*(vu_long *)((x) + (y))) +#else +#define UData(Data) (Data) + +#define __REG(x) (x) +#define __REGl(x) (x) +#define __REGw(x) (x) +#define __REGb(x) (x) +#define __REG2(x, y) ((x) + (y)) +#endif + +#define Fld(Size, Shft) (((Size) << 16) + (Shft)) + +#define FSize(Field) ((Field) >> 16) +#define FShft(Field) ((Field) & 0x0000FFFF) +#define FMsk(Field) (((UData(1) << FSize(Field)) - 1) << FShft(Field)) +#define FAlnMsk(Field) ((UData(1) << FSize(Field)) - 1) +#define F1stBit(Field) (UData(1) << FShft(Field)) + +#define FClrBit(Data, Bit) (Data = (Data & ~(Bit))) +#define FClrFld(Data, Field) (Data = (Data & ~FMsk(Field))) + +#define FInsrt(Value, Field) \ + (UData(Value) << FShft(Field)) + +#define FExtr(Data, Field) \ + ((UData(Data) >> FShft(Field)) & FAlnMsk(Field)) + +#endif /* _ARCH_HARDWARE_H_ */ diff --git a/include/asm-arm/arch-s5pc1xx/i2c.h b/include/asm-arm/arch-s5pc1xx/i2c.h new file mode 100644 index 0000000..6c7d3b6 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/i2c.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Kyungnin Park kyungmin.park@samsung.com + * + * based on s3c24x0_i2c.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_I2C_H_ +#define __ASM_ARCH_I2C_H_ + +/* I2C */ +#define S5PC100_I2C0_BASE 0xEC100000 +#define S5PC100_I2C1_BASE 0xEC200000 +#define S5PC110_I2C0_BASE 0xE1800000 +#define S5PC110_I2C2_BASE 0xE1A00000 + +#ifndef __ASSEMBLY__ +struct s5pc1xx_i2c { + unsigned long IICCON; + unsigned long IICSTAT; + unsigned long IICADD; + unsigned long IICDS; + unsigned long IICLC; +}; +#endif + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/interrupt.h b/include/asm-arm/arch-s5pc1xx/interrupt.h new file mode 100644 index 0000000..a3c8680 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/interrupt.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_INTERRUPT_H_ +#define __ASM_ARM_ARCH_INTERRUPT_H_ + +/* Vector Interrupt Offset */ +#define VIC_IRQSTATUS_OFFSET 0x0 +#define VIC_FIQSTATUS_OFFSET 0x4 +#define VIC_RAWINTR_OFFSET 0x8 +#define VIC_INTSELECT_OFFSET 0xc +#define VIC_INTENABLE_OFFSET 0x10 +#define VIC_INTENCLEAR_OFFSET 0x14 +#define VIC_SOFTINT_OFFSET 0x18 +#define VIC_SOFTINTCLEAR_OFFSET 0x1c +#define VIC_PROTECTION_OFFSET 0x20 +#define VIC_SWPRIORITYMASK_OFFSET 0x24 +#define VIC_PRIORITYDAISY_OFFSET 0x28 +#define VIC_INTADDRESS_OFFSET 0xf00 + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/mem.h b/include/asm-arm/arch-s5pc1xx/mem.h new file mode 100644 index 0000000..4b06aaf --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/mem.h @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_MEM_H_ +#define __ASM_ARM_ARCH_MEM_H_ + +/* + * SROMC Controller + */ +/* DRAM Memory Controller */ +#define S5PC100_DMC_BASE 0xE6000000 +#define S5PC110_DMC0_BASE 0xF0000000 +#define S5PC110_DMC1_BASE 0xF1400000 + +/* DMC offset */ +#define CONCONTROL_OFFSET 0x00 +#define MEMCONTROL_OFFSET 0x04 +#define MEMCONFIG0_OFFSET 0x08 +#define MEMCONFIG1_OFFSET 0x0c +#define DIRECTCMD_OFFSET 0x10 +#define PRECHCONFIG_OFFSET 0x14 +#define PHYCONTROL0_OFFSET 0x18 +#define PHYCONTROL1_OFFSET 0x1c +#define PHYCONTROL2_OFFSET 0x20 +#define PWRDNCONFIG_OFFSET 0x28 +#define TIMINGAREF_OFFSET 0x30 +#define TIMINGROW_OFFSET 0x34 +#define TIMINGDATA_OFFSET 0x38 +#define TIMINGPOWER_OFFSET 0x3c +#define PHYSTATUS0_OFFSET 0x40 +#define PHYSTATUS1_OFFSET 0x44 +#define CHIP0STATUS_OFFSET 0x48 +#define CHIP1STATUS_OFFSET 0x4c +#define AREFSTATUS_OFFSET 0x50 +#define MRSTATUS_OFFSET 0x54 +#define PHYTEST0_OFFSET 0x58 +#define PHYTEST1_OFFSET 0x5c + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/power.h b/include/asm-arm/arch-s5pc1xx/power.h new file mode 100644 index 0000000..57e2a2b --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/power.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2009 Samsung Electronics + * Kyungmin Park kyungmin.park@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_POWER_H_ +#define __ASM_ARM_ARCH_POWER_H_ + +/* + * Power control + */ +#define S5PC100_OTHERS 0xE0108200 +#define S5PC100_RST_STAT 0xE0108300 +#define S5PC100_SLEEP_WAKEUP (1 << 3) +#define S5PC100_WAKEUP_STAT 0xE0108304 +#define S5PC100_INFORM0 0xE0108400 + +#define S5PC110_RST_STAT 0xE010A000 +#define S5PC110_SLEEP_WAKEUP (1 << 3) +#define S5PC110_WAKEUP_STAT 0xE010C200 +#define S5PC110_OTHERS 0xE010E000 +#define S5PC110_USB_PHY_CON 0xE010E80C +#define S5PC110_INFORM0 0xE010F000 + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/pwm.h b/include/asm-arm/arch-s5pc1xx/pwm.h new file mode 100644 index 0000000..85c63d7 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/pwm.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Kyungmin Park kyungmin.park@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_ARCH_PWM_H_ +#define __ASM_ARM_ARCH_PWM_H_ + +/* + * PWM Timer + */ +#define S5PC100_PWMTIMER_BASE 0xEA000000 +#define S5PC110_PWMTIMER_BASE 0xE2500000 + +/* PWM timer addressing */ +#define S5PC100_TIMER_BASE S5PC100_PWMTIMER_BASE +#define S5PC110_TIMER_BASE S5PC110_PWMTIMER_BASE + +/* Interval mode(Auto Reload) of PWM Timer 4 */ +#define S5PC1XX_TCON4_AUTO_RELOAD (1 << 22) +/* Update TCNTB4 */ +#define S5PC1XX_TCON4_UPDATE (1 << 21) +/* start bit of PWM Timer 4 */ +#define S5PC1XX_TCON4_START (1 << 20) + +#ifndef __ASSEMBLY__ +struct s5pc1xx_timer { + unsigned long TCFG0; + unsigned long TCFG1; + unsigned long TCON; + unsigned long TCNTB0; + unsigned long TCMPB0; + unsigned long TCNTO0; + unsigned long TCNTB1; + unsigned long TCMPB1; + unsigned long TCNTO1; + unsigned long TCNTB2; + unsigned long TCMPB2; + unsigned long TCNTO2; + unsigned long TCNTB3; + unsigned long res1; + unsigned long TCNTO3; + unsigned long TCNTB4; + unsigned long TCNTO4; + unsigned long TINTCSTAT; +}; +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/uart.h b/include/asm-arm/arch-s5pc1xx/uart.h new file mode 100644 index 0000000..1a2ca41 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/uart.h @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_UART_H_ +#define __ASM_ARCH_UART_H_ + +/* + * UART + */ +/* uart base address */ +#define S5PC100_PA_UART 0xEC000000 +#define S5PC110_PA_UART 0xE2900000 + +#ifndef __ASSEMBLY__ +struct s5pc1xx_uart { + unsigned long ULCON; + unsigned long UCON; + unsigned long UFCON; + unsigned long UMCON; + unsigned long UTRSTAT; + unsigned long UERSTAT; + unsigned long UFSTAT; + unsigned long UMSTAT; + unsigned char UTXH; + unsigned char res1[3]; + unsigned char URXH; + unsigned char res2[3]; + unsigned long UBRDIV; + unsigned short UDIVSLOT; + unsigned char res3[2]; +}; +#endif /* __ASSEMBLY__ */ + +#endif

Dear Minkyu Kang,
In message 4AA8AC30.2070807@samsung.com you wrote:
This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com
When posting new versions of patches, please always make sure to set appropriate "In-reply-to:" and "References:" headers, so your new versions get correctly threaded with the previous discussion, which makes it much easier to check previous review comments against what you actually changed.
Also, please always include a list of changed between the current and the previous version of the patch, otherwise we have to review the whole code completely again.
Please consider using "git send-email" to submit patches which will make your (and our) life easier, for example because it prompts you for the message IDs to be used in the "In-reply-to:" and "References:" headers.
But the biggest problem with your new version is that you obviously ignore some (large) parts of my previous review comments. This is not the way it is supposed to work.
I don't waste my time on reviewing your code if you don't bother to fix it.
If you want to get your code into mainline, than please clean it up as requested. If you don't understand what changes are required, then please ask. If you think a change request is unreasonable, the ask. But silently ignoring review comments is not helpful.
+unsigned long get_pll_clk(int pllreg) +{
- struct s5pc100_clock *clk_c100 =
(struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
- struct s5pc110_clock *clk_c110 =
(struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
- unsigned long r, m, p, s, mask, fout;
- unsigned int freq;
- switch (pllreg) {
- case APLL:
if (cpu_is_s5pc110())
r = readl(&clk_c110->APLL_CON);
else
r = readl(&clk_c100->APLL_CON);
break;
- case MPLL:
if (cpu_is_s5pc110())
r = readl(&clk_c110->MPLL_CON);
else
r = readl(&clk_c100->MPLL_CON);
break;
- case EPLL:
if (cpu_is_s5pc110())
r = readl(&clk_c110->EPLL_CON);
else
r = readl(&clk_c100->EPLL_CON);
break;
- case HPLL:
if (cpu_is_s5pc110()) {
puts("s5pc110 don't use HPLL\n");
return 0;
}
r = readl(&clk_c100->HPLL_CON);
break;
- case VPLL:
if (cpu_is_s5pc100()) {
puts("s5pc100 don't use VPLL\n");
return 0;
}
r = readl(&clk_c110->VPLL_CON);
break;
I think this code is inefficient, and it does not scale at all if you ever have to add additional processors. I recomment we don't try to mix this code all in a single function that covers all processors.
Instead, provide two separate functions, one for each of the CPU types, and then set a fuction pointer to the right function. This way we have only a single test for the CPU type (when stting the function pointer). And this allows easily to add support for other CPU types, and even then the code will remain readable.
- if (cpu_is_s5pc110()) {
freq = CONFIG_SYS_CLK_FREQ_C110;
if (pllreg == APLL) {
if (s < 1)
s = 1;
/* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
fout = m * (freq / (p * (1 << (s - 1))));
} else
/* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
fout = m * (freq / (p * (1 << s)));
- } else {
/* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
freq = CONFIG_SYS_CLK_FREQ_C100;
fout = m * (freq / (p * (1 << s)));
- }
Similar here. I suggest you move this CPU dependent code into separate functions. There will be more such places below. In the end, you can probably even split the CPU specific code off into separate files, and set up a table with method pointers. At a central place a single test for the CPU type will be done, and the right method table be selected.
The code here will then be lean and completely independent of CPU types. Thsi will be much easier to read, and easier to maintain.
+unsigned long get_arm_clk(void) +{
- struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
- unsigned long div;
- unsigned long dout_apll, armclk;
- unsigned int apll_ratio, arm_ratio;
- div = readl(&clk->DIV0);
- if (cpu_is_s5pc110()) {
/* ARM_RATIO: don't use */
arm_ratio = 0;
/* APLL_RATIO: [2:0] */
apll_ratio = div & 0x7;
- } else {
/* ARM_RATIO: [6:4] */
arm_ratio = (div >> 4) & 0x7;
/* APLL_RATIO: [0] */
apll_ratio = div & 0x1;
- }
- dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
- armclk = dout_apll / (arm_ratio + 1);
- return armclk;
+}
This is another such candiate.
+/* return FCLK frequency */ +unsigned long get_fclk(void) +{
- return get_pll_clk(APLL);
+}
+/* return MCLK frequency */ +unsigned long get_mclk(void) +{
- return get_pll_clk(MPLL);
+}
It seems nobody else uses these functions, and get_pll_clk() is globally visible, too. So we can probably omit get_fclk() and get_mclk() and rather call get_pll_clk() directly?
+/* s5pc100: return HCLKD0 frequency */ +unsigned long get_hclk(void)
...
+/* s5pc100: return PCLKD0 frequency */ +unsigned long get_pclkd0(void)
...
+/* s5pc100: return PCLKD1 frequency */ +unsigned long get_pclkd1(void)
...
+/* s5pc110: return HCLKs frequency */ +unsigned long get_hclk_sys(int dom)
...
+/* s5pc110: return PCLKs frequency */ +unsigned long get_pclk_sys(int dom)
...
Seems these are even more candiates for method pointers...
And more follow. I think this should be reworked globally.
+int print_cpuinfo(void) +{
- char buf[32];
- printf("CPU:\tS5P%X@%sMHz\n",
s5pc1xx_cpu_id, strmhz(buf, get_arm_clk()));
- if (cpu_is_s5pc110()) {
printf("\tAPLL = %s MHz, ", strmhz(buf, get_fclk()));
printf("MPLL = %s MHz, ", strmhz(buf, get_mclk()));
printf("EPLL = %s MHz\n", strmhz(buf, get_uclk()));
printf("\tHclk: Msys %s MHz, ",
strmhz(buf, get_hclk_sys(CLK_M)));
printf("Dsys %7s MHz, ", strmhz(buf, get_hclk_sys(CLK_D)));
printf("Psys %7s MHz\n", strmhz(buf, get_hclk_sys(CLK_P)));
printf("\tPclk: Msys %s MHz, ",
strmhz(buf, get_pclk_sys(CLK_M)));
printf("Dsys %7s MHz, ", strmhz(buf, get_pclk_sys(CLK_D)));
printf("Psys %7s MHz\n", strmhz(buf, get_pclk_sys(CLK_P)));
- } else {
printf("\tFclk = %s MHz\n", strmhz(buf, get_fclk()));
printf("\tHclkD0 = %s MHz\n", strmhz(buf, get_hclk()));
printf("\tPclkD0 = %s MHz\n", strmhz(buf, get_pclkd0()));
printf("\tPclkD1 = %s MHz\n", strmhz(buf, get_pclkd1()));
- }
Please review how much of this is really significant information for the end user, and how much is more or less only interesting for the developer. Consider to change such development-only parts into debug() calls.
diff --git a/include/asm-arm/arch-s5pc1xx/clock.h b/include/asm-arm/arch-s5pc1xx/clock.h new file mode 100644 index 0000000..f11c9ce --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/clock.h
...
+/* Clock Register */
+#ifndef __ASSEMBLY__ +struct s5pc100_clock {
- unsigned long APLL_LOCK;
- unsigned long MPLL_LOCK;
- unsigned long EPLL_LOCK;
- unsigned long HPLL_LOCK;
- unsigned char res1[0xf0];
- unsigned long APLL_CON;
- unsigned long MPLL_CON;
- unsigned long EPLL_CON;
- unsigned long HPLL_CON;
- unsigned char res2[0xf0];
- unsigned long SRC0;
- unsigned long SRC1;
- unsigned long SRC2;
- unsigned long SRC3;
- unsigned char res3[0xf0];
- unsigned long DIV0;
- unsigned long DIV1;
- unsigned long DIV2;
- unsigned long DIV3;
- unsigned long DIV4;
- unsigned char res4[0x1ec];
- unsigned long GATE_D00;
- unsigned long GATE_D01;
- unsigned long GATE_D02;
- unsigned char res5[0x54];
- unsigned long GATE_SCLK0;
- unsigned long GATE_SCLK1;
+};
Sorry, but variable names must not use upper case letters; these are reserved for macro definitions only. Please rename and use lower case letters only. Also for other names in the rest of the patch.
diff --git a/include/asm-arm/arch-s5pc1xx/cpu.h b/include/asm-arm/arch-s5pc1xx/cpu.h new file mode 100644 index 0000000..c7d7183 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/cpu.h
..
+#define S5PC1XX_ADDR_BASE 0xe0000000 +#define S5P_ADDR(x) (S5PC1XX_ADDR_BASE + (x))
+#define S5PC1XX_CLOCK_BASE 0xE0100000 +#define S5P_PA_CLK_OTHERS S5P_ADDR(0x00200000) /* Clock Others Base */
Seems thisis the only place where S5P_ADDR is used - consider to avoid it.
By the way: I already commented about this part in my previous review. Why did you not change it?
+/*
- Chip ID
- */
+#define S5PC1XX_CHIP_ID(x) (0xE0000000 + (x)) +#define S5PC1XX_PRO_ID S5PC1XX_CHIP_ID(0) +#define S5PC1XX_OMR S5PC1XX_CHIP_ID(4)
Create a C struct instead of using base address + offset?
+#define IS_SAMSUNG_TYPE(type, id) \ +static inline int is_##type(void) \ +{ \
- return (s5pc1xx_cpu_id == (id)) ? 1 : 0; \
+}
+IS_SAMSUNG_TYPE(s5pc100, 0xc100) +IS_SAMSUNG_TYPE(s5pc110, 0xc110)
+#define cpu_is_s5pc100() is_s5pc100() +#define cpu_is_s5pc110() is_s5pc110() +#endif
Why do we need both the inline functions and a macro? Maybe we can use the right name in the inline functions and drop the macro?
diff --git a/include/asm-arm/arch-s5pc1xx/gpio.h b/include/asm-arm/arch-s5pc1xx/gpio.h new file mode 100644 index 0000000..26d0950 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/gpio.h
...
+/* GPIO Bank Base */ +#define S5PC100_GPIO_BASE(x) (0xE0300000 + (x)) +#define S5PC110_GPIO_BASE(x) (0xE0200000 + (x))
+/* S5PC100 bank offset */ +#define S5PC100_GPIO_A0_OFFSET 0x000 +#define S5PC100_GPIO_A1_OFFSET 0x020 +#define S5PC100_GPIO_B_OFFSET 0x040 +#define S5PC100_GPIO_C_OFFSET 0x060 +#define S5PC100_GPIO_D_OFFSET 0x080 +#define S5PC100_GPIO_E0_OFFSET 0x0A0 +#define S5PC100_GPIO_E1_OFFSET 0x0C0 +#define S5PC100_GPIO_F0_OFFSET 0x0E0 +#define S5PC100_GPIO_F1_OFFSET 0x100 +#define S5PC100_GPIO_F2_OFFSET 0x120 +#define S5PC100_GPIO_F3_OFFSET 0x140 +#define S5PC100_GPIO_G0_OFFSET 0x160 +#define S5PC100_GPIO_G1_OFFSET 0x180 +#define S5PC100_GPIO_G2_OFFSET 0x1A0 +#define S5PC100_GPIO_G3_OFFSET 0x1C0 +#define S5PC100_GPIO_I_OFFSET 0x1E0 +#define S5PC100_GPIO_J0_OFFSET 0x200 +#define S5PC100_GPIO_J1_OFFSET 0x220 +#define S5PC100_GPIO_J2_OFFSET 0x240 +#define S5PC100_GPIO_J3_OFFSET 0x260 +#define S5PC100_GPIO_J4_OFFSET 0x280 +#define S5PC100_GPIO_K0_OFFSET 0x2A0 +#define S5PC100_GPIO_K1_OFFSET 0x2C0 +#define S5PC100_GPIO_K2_OFFSET 0x2E0 +#define S5PC100_GPIO_K3_OFFSET 0x300 +#define S5PC100_GPIO_L0_OFFSET 0x320 +#define S5PC100_GPIO_L1_OFFSET 0x340 +#define S5PC100_GPIO_L2_OFFSET 0x360 +#define S5PC100_GPIO_L3_OFFSET 0x380 +#define S5PC100_GPIO_L4_OFFSET 0x3A0 +#define S5PC100_GPIO_H0_OFFSET 0xC00 +#define S5PC100_GPIO_H1_OFFSET 0xC20 +#define S5PC100_GPIO_H2_OFFSET 0xC40 +#define S5PC100_GPIO_H3_OFFSET 0xC60
...
If this should be used anywhere in the code, add this needs to be converted in a C struct, too.
But as far as I can see, only S5PC100_GPIO_A*_OFFSET are ever referenced (from assembler code); maybe we can omit most of this stuff ? These offsets should then be auto-generated.
But again this is a part I already commented about in my previous review.
diff --git a/include/asm-arm/arch-s5pc1xx/hardware.h b/include/asm-arm/arch-s5pc1xx/hardware.h new file mode 100644 index 0000000..ca95c3d --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/hardware.h
...
+#ifndef __ASSEMBLY__ +#define UData(Data) ((unsigned long)(Data))
+#define __REG(x) (*(vu_long *)(x)) +#define __REGl(x) (*(vu_long *)(x)) +#define __REGw(x) (*(vu_short *)(x)) +#define __REGb(x) (*(vu_char *)(x)) +#define __REG2(x, y) (*(vu_long *)((x) + (y))) +#else +#define UData(Data) (Data)
+#define __REG(x) (x) +#define __REGl(x) (x) +#define __REGw(x) (x) +#define __REGb(x) (x) +#define __REG2(x, y) ((x) + (y)) +#endif
+#define Fld(Size, Shft) (((Size) << 16) + (Shft))
+#define FSize(Field) ((Field) >> 16) +#define FShft(Field) ((Field) & 0x0000FFFF) +#define FMsk(Field) (((UData(1) << FSize(Field)) - 1) << FShft(Field)) +#define FAlnMsk(Field) ((UData(1) << FSize(Field)) - 1) +#define F1stBit(Field) (UData(1) << FShft(Field))
+#define FClrBit(Data, Bit) (Data = (Data & ~(Bit))) +#define FClrFld(Data, Field) (Data = (Data & ~FMsk(Field)))
+#define FInsrt(Value, Field) \
(UData(Value) << FShft(Field))
+#define FExtr(Data, Field) \
((UData(Data) >> FShft(Field)) & FAlnMsk(Field))
I wrote before:
Please get rid of all these definitions. None of these will be accepted in U-Boot.
Please use existent accessors and macros instead.
Why did you not implement the required chanegs?
Review stops here. Please fix first.
Wolfgang Denk

Dear Wolfgang
2009/9/10 Wolfgang Denk wd@denx.de:
Dear Minkyu Kang,
In message 4AA8AC30.2070807@samsung.com you wrote:
This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com
When posting new versions of patches, please always make sure to set appropriate "In-reply-to:" and "References:" headers, so your new versions get correctly threaded with the previous discussion, which makes it much easier to check previous review comments against what you actually changed.
Also, please always include a list of changed between the current and the previous version of the patch, otherwise we have to review the whole code completely again.
Please consider using "git send-email" to submit patches which will make your (and our) life easier, for example because it prompts you for the message IDs to be used in the "In-reply-to:" and "References:" headers.
I see.
But the biggest problem with your new version is that you obviously ignore some (large) parts of my previous review comments. This is not the way it is supposed to work.
I don't waste my time on reviewing your code if you don't bother to fix it.
If you want to get your code into mainline, than please clean it up as requested. If you don't understand what changes are required, then please ask. If you think a change request is unreasonable, the ask. But silently ignoring review comments is not helpful.
hm.. did I? sorry, I just missing.. I'll check all of your comments again.. I'm sorry to your time
+unsigned long get_pll_clk(int pllreg) +{
- struct s5pc100_clock *clk_c100 =
- (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
- struct s5pc110_clock *clk_c110 =
- (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE;
- unsigned long r, m, p, s, mask, fout;
- unsigned int freq;
- switch (pllreg) {
- case APLL:
- if (cpu_is_s5pc110())
- r = readl(&clk_c110->APLL_CON);
- else
- r = readl(&clk_c100->APLL_CON);
- break;
- case MPLL:
- if (cpu_is_s5pc110())
- r = readl(&clk_c110->MPLL_CON);
- else
- r = readl(&clk_c100->MPLL_CON);
- break;
- case EPLL:
- if (cpu_is_s5pc110())
- r = readl(&clk_c110->EPLL_CON);
- else
- r = readl(&clk_c100->EPLL_CON);
- break;
- case HPLL:
- if (cpu_is_s5pc110()) {
- puts("s5pc110 don't use HPLL\n");
- return 0;
- }
- r = readl(&clk_c100->HPLL_CON);
- break;
- case VPLL:
- if (cpu_is_s5pc100()) {
- puts("s5pc100 don't use VPLL\n");
- return 0;
- }
- r = readl(&clk_c110->VPLL_CON);
- break;
I think this code is inefficient, and it does not scale at all if you ever have to add additional processors. I recomment we don't try to mix this code all in a single function that covers all processors.
Instead, provide two separate functions, one for each of the CPU types, and then set a fuction pointer to the right function. This way we have only a single test for the CPU type (when stting the function pointer). And this allows easily to add support for other CPU types, and even then the code will remain readable.
I'll split the function. and I think we don't need the function pointer fully. get_pclkd0, get_pclkd1, get_hclk_sys and get_pclk_sys are not generic functions. but, get_pll_clk, get_arm_clk and get_pclk can be make function pointer.
- if (cpu_is_s5pc110()) {
- freq = CONFIG_SYS_CLK_FREQ_C110;
- if (pllreg == APLL) {
- if (s < 1)
- s = 1;
- /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
- fout = m * (freq / (p * (1 << (s - 1))));
- } else
- /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
- fout = m * (freq / (p * (1 << s)));
- } else {
- /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
- freq = CONFIG_SYS_CLK_FREQ_C100;
- fout = m * (freq / (p * (1 << s)));
- }
Similar here. I suggest you move this CPU dependent code into separate functions. There will be more such places below. In the end, you can probably even split the CPU specific code off into separate files, and set up a table with method pointers. Â At a central place a single test for the CPU type will be done, and the right method table be selected.
The code here will then be lean and completely independent of CPU types. Â Thsi will be much easier to read, and easier to maintain.
+unsigned long get_arm_clk(void) +{
- struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE;
- unsigned long div;
- unsigned long dout_apll, armclk;
- unsigned int apll_ratio, arm_ratio;
- div = readl(&clk->DIV0);
- if (cpu_is_s5pc110()) {
- /* ARM_RATIO: don't use */
- arm_ratio = 0;
- /* APLL_RATIO: [2:0] */
- apll_ratio = div & 0x7;
- } else {
- /* ARM_RATIO: [6:4] */
- arm_ratio = (div >> 4) & 0x7;
- /* APLL_RATIO: [0] */
- apll_ratio = div & 0x1;
- }
- dout_apll = get_pll_clk(APLL) / (apll_ratio + 1);
- armclk = dout_apll / (arm_ratio + 1);
- return armclk;
+}
This is another such candiate.
+/* return FCLK frequency */ +unsigned long get_fclk(void) +{
- return get_pll_clk(APLL);
+}
+/* return MCLK frequency */ +unsigned long get_mclk(void) +{
- return get_pll_clk(MPLL);
+}
It seems nobody else uses these functions, and get_pll_clk() is globally visible, too. So we can probably omit get_fclk() and get_mclk() and rather call get_pll_clk() directly?
+/* s5pc100: return HCLKD0 frequency */ +unsigned long get_hclk(void)
...
+/* s5pc100: return PCLKD0 frequency */ +unsigned long get_pclkd0(void)
...
+/* s5pc100: return PCLKD1 frequency */ +unsigned long get_pclkd1(void)
...
+/* s5pc110: return HCLKs frequency */ +unsigned long get_hclk_sys(int dom)
...
+/* s5pc110: return PCLKs frequency */ +unsigned long get_pclk_sys(int dom)
...
Seems these are even more candiates for method pointers...
And more follow. I think this should be reworked globally.
ok i'll rechek.
+int print_cpuinfo(void) +{
- char buf[32];
- printf("CPU:\tS5P%X@%sMHz\n",
- s5pc1xx_cpu_id, strmhz(buf, get_arm_clk()));
- if (cpu_is_s5pc110()) {
- printf("\tAPLL = %s MHz, ", strmhz(buf, get_fclk()));
- printf("MPLL = %s MHz, ", strmhz(buf, get_mclk()));
- printf("EPLL = %s MHz\n", strmhz(buf, get_uclk()));
- printf("\tHclk: Msys %s MHz, ",
- strmhz(buf, get_hclk_sys(CLK_M)));
- printf("Dsys %7s MHz, ", strmhz(buf, get_hclk_sys(CLK_D)));
- printf("Psys %7s MHz\n", strmhz(buf, get_hclk_sys(CLK_P)));
- printf("\tPclk: Msys %s MHz, ",
- strmhz(buf, get_pclk_sys(CLK_M)));
- printf("Dsys %7s MHz, ", strmhz(buf, get_pclk_sys(CLK_D)));
- printf("Psys %7s MHz\n", strmhz(buf, get_pclk_sys(CLK_P)));
- } else {
- printf("\tFclk = %s MHz\n", strmhz(buf, get_fclk()));
- printf("\tHclkD0 = %s MHz\n", strmhz(buf, get_hclk()));
- printf("\tPclkD0 = %s MHz\n", strmhz(buf, get_pclkd0()));
- printf("\tPclkD1 = %s MHz\n", strmhz(buf, get_pclkd1()));
- }
Please review how much of this is really significant information for the end user, and how much is more or less only interesting for the developer. Consider to change such development-only parts into debug() calls.
diff --git a/include/asm-arm/arch-s5pc1xx/clock.h b/include/asm-arm/arch-s5pc1xx/clock.h new file mode 100644 index 0000000..f11c9ce --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/clock.h
...
+/* Clock Register */
+#ifndef __ASSEMBLY__ +struct s5pc100_clock {
- unsigned long  APLL_LOCK;
- unsigned long  MPLL_LOCK;
- unsigned long  EPLL_LOCK;
- unsigned long  HPLL_LOCK;
- unsigned char  res1[0xf0];
- unsigned long  APLL_CON;
- unsigned long  MPLL_CON;
- unsigned long  EPLL_CON;
- unsigned long  HPLL_CON;
- unsigned char  res2[0xf0];
- unsigned long  SRC0;
- unsigned long  SRC1;
- unsigned long  SRC2;
- unsigned long  SRC3;
- unsigned char  res3[0xf0];
- unsigned long  DIV0;
- unsigned long  DIV1;
- unsigned long  DIV2;
- unsigned long  DIV3;
- unsigned long  DIV4;
- unsigned char  res4[0x1ec];
- unsigned long  GATE_D00;
- unsigned long  GATE_D01;
- unsigned long  GATE_D02;
- unsigned char  res5[0x54];
- unsigned long  GATE_SCLK0;
- unsigned long  GATE_SCLK1;
+};
Sorry, but variable names must not use upper case letters; these are reserved for macro definitions only. Please rename and use lower case letters only. Also for other names in the rest of the patch.
ok. I will fix it.
diff --git a/include/asm-arm/arch-s5pc1xx/cpu.h b/include/asm-arm/arch-s5pc1xx/cpu.h new file mode 100644 index 0000000..c7d7183 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/cpu.h
..
+#define S5PC1XX_ADDR_BASE Â Â 0xe0000000 +#define S5P_ADDR(x) Â Â Â Â Â (S5PC1XX_ADDR_BASE + (x))
+#define S5PC1XX_CLOCK_BASE Â 0xE0100000 +#define S5P_PA_CLK_OTHERS Â Â S5P_ADDR(0x00200000) Â Â /* Clock Others Base */
Seems thisis the only place where S5P_ADDR is used - consider to avoid it.
i'll fix it, too.
By the way: I already commented about this part in my previous review. Why did you not change it?
sorry again.
+/*
- Chip ID
- */
+#define S5PC1XX_CHIP_ID(x) Â (0xE0000000 + (x)) +#define S5PC1XX_PRO_ID Â Â Â Â Â Â Â S5PC1XX_CHIP_ID(0) +#define S5PC1XX_OMR Â Â Â Â Â S5PC1XX_CHIP_ID(4)
Create a C struct instead of using base address + offset?
we don't use S5PC1XX_OMR so I'll delete it. and will fix like this
+#define S5PC1XX_PRO_ID 0xE0000000
+#define IS_SAMSUNG_TYPE(type, id) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â \ +static inline int is_##type(void) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â \ +{ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â \
- return (s5pc1xx_cpu_id == (id)) ? 1 : 0; Â Â Â Â Â Â Â Â Â Â Â Â \
+}
+IS_SAMSUNG_TYPE(s5pc100, 0xc100) +IS_SAMSUNG_TYPE(s5pc110, 0xc110)
+#define cpu_is_s5pc100() Â Â is_s5pc100() +#define cpu_is_s5pc110() Â Â is_s5pc110() +#endif
Why do we need both the inline functions and a macro? Maybe we can use the right name in the inline functions and drop the macro?
agreed. i'll drop the macro.
diff --git a/include/asm-arm/arch-s5pc1xx/gpio.h b/include/asm-arm/arch-s5pc1xx/gpio.h new file mode 100644 index 0000000..26d0950 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/gpio.h
...
+/* GPIO Bank Base */ +#define S5PC100_GPIO_BASE(x) Â Â Â Â (0xE0300000 + (x)) +#define S5PC110_GPIO_BASE(x) Â Â Â Â (0xE0200000 + (x))
+/* S5PC100 bank offset */ +#define S5PC100_GPIO_A0_OFFSET Â Â Â Â Â Â Â 0x000 +#define S5PC100_GPIO_A1_OFFSET Â Â Â Â Â Â Â 0x020 +#define S5PC100_GPIO_B_OFFSET Â Â Â Â Â Â Â Â 0x040 +#define S5PC100_GPIO_C_OFFSET Â Â Â Â Â Â Â Â 0x060 +#define S5PC100_GPIO_D_OFFSET Â Â Â Â Â Â Â Â 0x080 +#define S5PC100_GPIO_E0_OFFSET Â Â Â Â Â Â Â 0x0A0 +#define S5PC100_GPIO_E1_OFFSET Â Â Â Â Â Â Â 0x0C0 +#define S5PC100_GPIO_F0_OFFSET Â Â Â Â Â Â Â 0x0E0 +#define S5PC100_GPIO_F1_OFFSET Â Â Â Â Â Â Â 0x100 +#define S5PC100_GPIO_F2_OFFSET Â Â Â Â Â Â Â 0x120 +#define S5PC100_GPIO_F3_OFFSET Â Â Â Â Â Â Â 0x140 +#define S5PC100_GPIO_G0_OFFSET Â Â Â Â Â Â Â 0x160 +#define S5PC100_GPIO_G1_OFFSET Â Â Â Â Â Â Â 0x180 +#define S5PC100_GPIO_G2_OFFSET Â Â Â Â Â Â Â 0x1A0 +#define S5PC100_GPIO_G3_OFFSET Â Â Â Â Â Â Â 0x1C0 +#define S5PC100_GPIO_I_OFFSET Â Â Â Â Â Â Â Â 0x1E0 +#define S5PC100_GPIO_J0_OFFSET Â Â Â Â Â Â Â 0x200 +#define S5PC100_GPIO_J1_OFFSET Â Â Â Â Â Â Â 0x220 +#define S5PC100_GPIO_J2_OFFSET Â Â Â Â Â Â Â 0x240 +#define S5PC100_GPIO_J3_OFFSET Â Â Â Â Â Â Â 0x260 +#define S5PC100_GPIO_J4_OFFSET Â Â Â Â Â Â Â 0x280 +#define S5PC100_GPIO_K0_OFFSET Â Â Â Â Â Â Â 0x2A0 +#define S5PC100_GPIO_K1_OFFSET Â Â Â Â Â Â Â 0x2C0 +#define S5PC100_GPIO_K2_OFFSET Â Â Â Â Â Â Â 0x2E0 +#define S5PC100_GPIO_K3_OFFSET Â Â Â Â Â Â Â 0x300 +#define S5PC100_GPIO_L0_OFFSET Â Â Â Â Â Â Â 0x320 +#define S5PC100_GPIO_L1_OFFSET Â Â Â Â Â Â Â 0x340 +#define S5PC100_GPIO_L2_OFFSET Â Â Â Â Â Â Â 0x360 +#define S5PC100_GPIO_L3_OFFSET Â Â Â Â Â Â Â 0x380 +#define S5PC100_GPIO_L4_OFFSET Â Â Â Â Â Â Â 0x3A0 +#define S5PC100_GPIO_H0_OFFSET Â Â Â Â Â Â Â 0xC00 +#define S5PC100_GPIO_H1_OFFSET Â Â Â Â Â Â Â 0xC20 +#define S5PC100_GPIO_H2_OFFSET Â Â Â Â Â Â Â 0xC40 +#define S5PC100_GPIO_H3_OFFSET Â Â Â Â Â Â Â 0xC60
...
If this should be used anywhere in the code, add this needs to be converted in a C struct, too.
But as far as I can see, only S5PC100_GPIO_A*_OFFSET are ever referenced (from assembler code); maybe we can omit most of this stuff ? These offsets should then be auto-generated.
on smdkc100? yes right.. but, our other boards use so many gpios. so, it was hard to rework. but, I will consider to convert C struct.
But again this is a part I already commented about in my previous review.
diff --git a/include/asm-arm/arch-s5pc1xx/hardware.h b/include/asm-arm/arch-s5pc1xx/hardware.h new file mode 100644 index 0000000..ca95c3d --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/hardware.h
...
+#ifndef __ASSEMBLY__ +#define UData(Data) Â ((unsigned long)(Data))
+#define __REG(x) Â Â (*(vu_long *)(x)) +#define __REGl(x) Â Â (*(vu_long *)(x)) +#define __REGw(x) Â Â (*(vu_short *)(x)) +#define __REGb(x) Â Â (*(vu_char *)(x)) +#define __REG2(x, y) (*(vu_long *)((x) + (y))) +#else +#define UData(Data) Â (Data)
+#define __REG(x) Â Â (x) +#define __REGl(x) Â Â (x) +#define __REGw(x) Â Â (x) +#define __REGb(x) Â Â (x) +#define __REG2(x, y) ((x) + (y)) +#endif
+#define Fld(Size, Shft) Â Â Â (((Size) << 16) + (Shft))
+#define FSize(Field) ((Field) >> 16) +#define FShft(Field) ((Field) & 0x0000FFFF) +#define FMsk(Field) Â (((UData(1) << FSize(Field)) - 1) << FShft(Field)) +#define FAlnMsk(Field) Â Â Â ((UData(1) << FSize(Field)) - 1) +#define F1stBit(Field) Â Â Â (UData(1) << FShft(Field))
+#define FClrBit(Data, Bit) Â (Data = (Data & ~(Bit))) +#define FClrFld(Data, Field) (Data = (Data & ~FMsk(Field)))
+#define FInsrt(Value, Field) \
- (UData(Value) << FShft(Field))
+#define FExtr(Data, Field) \
- ((UData(Data) >> FShft(Field)) & FAlnMsk(Field))
I wrote before:
Please get rid of all these definitions. None of these will be accepted in U-Boot.
Please use existent accessors and macros instead.
Why did you not implement the required chanegs?
sorry, this file will be deleted.
Review stops here. Please fix first.
Wolfgang Denk
-- DENX Software Engineering GmbH,   MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de "Here's a fish hangs in the net like a poor man's right in  the  law. 'Twill hardly come out."   - Shakespeare, Pericles, Act II, Scene 1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
thanks.

This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com --- Changes since v1: - make C struct instead of base+offset - use writel/readl function - use the strmhz function - fix some comments
Changes since v2: - use function pointer for separate Soc - provide two separate functions for each Soc - remove not helpful cpu informations - modify to lower case letter in C struct - remove unnecessary Macro and header files
cpu/arm_cortexa8/s5pc1xx/Makefile | 53 ++++++ cpu/arm_cortexa8/s5pc1xx/cache.c | 43 +++++ cpu/arm_cortexa8/s5pc1xx/clock.c | 308 ++++++++++++++++++++++++++++++++++ cpu/arm_cortexa8/s5pc1xx/cpu_info.c | 57 +++++++ cpu/arm_cortexa8/s5pc1xx/reset.S | 47 +++++ cpu/arm_cortexa8/s5pc1xx/timer.c | 195 +++++++++++++++++++++ include/asm-arm/arch-s5pc1xx/clk.h | 32 ++++ include/asm-arm/arch-s5pc1xx/clock.h | 94 ++++++++++ include/asm-arm/arch-s5pc1xx/cpu.h | 72 ++++++++ include/asm-arm/arch-s5pc1xx/gpio.h | 129 ++++++++++++++ include/asm-arm/arch-s5pc1xx/power.h | 42 +++++ include/asm-arm/arch-s5pc1xx/pwm.h | 59 +++++++ include/asm-arm/arch-s5pc1xx/uart.h | 47 +++++ 13 files changed, 1178 insertions(+), 0 deletions(-) create mode 100644 cpu/arm_cortexa8/s5pc1xx/Makefile create mode 100644 cpu/arm_cortexa8/s5pc1xx/cache.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/clock.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/cpu_info.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/reset.S create mode 100644 cpu/arm_cortexa8/s5pc1xx/timer.c create mode 100644 include/asm-arm/arch-s5pc1xx/clk.h create mode 100644 include/asm-arm/arch-s5pc1xx/clock.h create mode 100644 include/asm-arm/arch-s5pc1xx/cpu.h create mode 100644 include/asm-arm/arch-s5pc1xx/gpio.h create mode 100644 include/asm-arm/arch-s5pc1xx/power.h create mode 100644 include/asm-arm/arch-s5pc1xx/pwm.h create mode 100644 include/asm-arm/arch-s5pc1xx/uart.h
diff --git a/cpu/arm_cortexa8/s5pc1xx/Makefile b/cpu/arm_cortexa8/s5pc1xx/Makefile new file mode 100644 index 0000000..e08d9d8 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, lg@denx.de +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS = reset.o + +COBJS += cache.o +COBJS += clock.o +COBJS += cpu_info.o +COBJS += timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/arm_cortexa8/s5pc1xx/cache.c b/cpu/arm_cortexa8/s5pc1xx/cache.c new file mode 100644 index 0000000..8652a45 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/cache.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/cache.h> + +void l2_cache_enable(void) +{ + unsigned long i; + + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); + __asm__ __volatile__("orr %0, %0, #0x2":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); +} + +void l2_cache_disable(void) +{ + unsigned long i; + + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); + __asm__ __volatile__("bic %0, %0, #0x2":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); +} diff --git a/cpu/arm_cortexa8/s5pc1xx/clock.c b/cpu/arm_cortexa8/s5pc1xx/clock.c new file mode 100644 index 0000000..a9e78dd --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/clock.c @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> + +#define APLL 0 +#define MPLL 1 +#define EPLL 2 +#define HPLL 3 +#define VPLL 4 + +#define CLK_M 0 +#define CLK_D 1 +#define CLK_P 2 + +#ifndef CONFIG_SYS_CLK_FREQ_C100 +#define CONFIG_SYS_CLK_FREQ_C100 12000000 +#endif +#ifndef CONFIG_SYS_CLK_FREQ_C110 +#define CONFIG_SYS_CLK_FREQ_C110 24000000 +#endif + +unsigned long (*get_pclk)(void); +unsigned long (*get_arm_clk)(void); +unsigned long (*get_pll_clk)(int); + +/* s5pc110: return pll clock frequency */ +static unsigned long s5pc100_get_pll_clk(int pllreg) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con); + break; + case MPLL: + r = readl(&clk->mpll_con); + break; + case EPLL: + r = readl(&clk->epll_con); + break; + case HPLL: + r = readl(&clk->hpll_con); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [23:16] + * EPLL_CON: MIDV [23:16] + * HPLL_CON: MIDV [23:16] + */ + if (pllreg == APLL) + mask = 0x3ff; + else + mask = 0x0ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + freq = CONFIG_SYS_CLK_FREQ_C100; + fout = m * (freq / (p * (1 << s))); + + return fout; +} + +/* s5pc100: return pll clock frequency */ +static unsigned long s5pc110_get_pll_clk(int pllreg) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con); + break; + case MPLL: + r = readl(&clk->mpll_con); + break; + case EPLL: + r = readl(&clk->epll_con); + break; + case VPLL: + r = readl(&clk->vpll_con); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [25:16] + * EPLL_CON: MIDV [24:16] + * VPLL_CON: MIDV [24:16] + */ + if (pllreg == APLL || pllreg == MPLL) + mask = 0x3ff; + else + mask = 0x1ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + freq = CONFIG_SYS_CLK_FREQ_C110; + if (pllreg == APLL) { + if (s < 1) + s = 1; + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ + fout = m * (freq / (p * (1 << (s - 1)))); + } else + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + fout = m * (freq / (p * (1 << s))); + + return fout; +} + +/* s5pc110: return ARM clock frequency */ +static unsigned long s5pc110_get_arm_clk(void) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio; + + div = readl(&clk->div0); + + /* APLL_RATIO: [2:0] */ + apll_ratio = div & 0x7; + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll; + + return armclk; +} + +/* s5pc100: return ARM clock frequency */ +static unsigned long s5pc100_get_arm_clk(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio, arm_ratio; + + div = readl(&clk->div0); + + /* ARM_RATIO: [6:4] */ + arm_ratio = (div >> 4) & 0x7; + /* APLL_RATIO: [0] */ + apll_ratio = div & 0x1; + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll / (arm_ratio + 1); + + return armclk; +} + +/* s5pc100: return HCLKD0 frequency */ +static unsigned long get_hclk(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long hclkd0; + uint div, d0_bus_ratio; + + div = readl(&clk->div0); + /* D0_BUS_RATIO: [10:8] */ + d0_bus_ratio = (div >> 8) & 0x7; + + hclkd0 = get_arm_clk() / (d0_bus_ratio + 1); + + return hclkd0; +} + +/* s5pc100: return PCLKD1 frequency */ +static unsigned long get_pclkd1(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long d1_bus, pclkd1; + uint div, d1_bus_ratio, pclkd1_ratio; + + div = readl(&clk->div0); + /* D1_BUS_RATIO: [14:12] */ + d1_bus_ratio = (div >> 12) & 0x7; + /* PCLKD1_RATIO: [18:16] */ + pclkd1_ratio = (div >> 16) & 0x7; + + /* ASYNC Mode */ + d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1); + pclkd1 = d1_bus / (pclkd1_ratio + 1); + + return pclkd1; +} + +/* s5pc110: return HCLKs frequency */ +static unsigned long get_hclk_sys(int dom) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long hclk; + unsigned int div; + unsigned int offset; + unsigned int hclk_sys_ratio; + + if (dom == CLK_M) + return get_hclk(); + + div = readl(&clk->div0); + + /* + * HCLK_MSYS_RATIO: [10:8] + * HCLK_DSYS_RATIO: [19:16] + * HCLK_PSYS_RATIO: [27:24] + */ + offset = 8 + (dom << 0x3); + + hclk_sys_ratio = (div >> offset) & 0xf; + + hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1); + + return hclk; +} + +/* s5pc110: return PCLKs frequency */ +static unsigned long get_pclk_sys(int dom) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long pclk; + unsigned int div; + unsigned int offset; + unsigned int pclk_sys_ratio; + + div = readl(&clk->div0); + + /* + * PCLK_MSYS_RATIO: [14:12] + * PCLK_DSYS_RATIO: [22:20] + * PCLK_PSYS_RATIO: [30:28] + */ + offset = 12 + (dom << 0x3); + + pclk_sys_ratio = (div >> offset) & 0x7; + + pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1); + + return pclk; +} + +/* s5pc110: return peripheral clock frequency */ +static unsigned long s5pc110_get_pclk(void) +{ + return get_pclk_sys(CLK_P); +} + +/* s5pc100: return peripheral clock frequency */ +static unsigned long s5pc100_get_pclk(void) +{ + return get_pclkd1(); +} + +void s5pc1xx_clock_init(void) +{ + if (cpu_is_s5pc110()) { + get_pll_clk = s5pc110_get_pll_clk; + get_arm_clk = s5pc110_get_arm_clk; + get_pclk = s5pc110_get_pclk; + } else { + get_pll_clk = s5pc100_get_pll_clk; + get_arm_clk = s5pc100_get_arm_clk; + get_pclk = s5pc100_get_pclk; + } +} diff --git a/cpu/arm_cortexa8/s5pc1xx/cpu_info.c b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c new file mode 100644 index 0000000..f16c0ff --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clk.h> + +/* Default is s5pc100 */ +unsigned int s5pc1xx_cpu_id = 0xC100; + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + s5pc1xx_cpu_id = readl(S5PC1XX_PRO_ID); + s5pc1xx_cpu_id = 0xC000 | ((s5pc1xx_cpu_id & 0x00FFF000) >> 12); + + s5pc1xx_clock_init(); + + return 0; +} +#endif + +u32 get_device_type(void) +{ + return s5pc1xx_cpu_id; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU:\tS5P%X@%sMHz\n", + s5pc1xx_cpu_id, strmhz(buf, get_arm_clk())); + + return 0; +} +#endif diff --git a/cpu/arm_cortexa8/s5pc1xx/reset.S b/cpu/arm_cortexa8/s5pc1xx/reset.S new file mode 100644 index 0000000..7f6ff9c --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/reset.S @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2009 Samsung Electronics. + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm/arch/cpu.h> + +#define S5PC100_SWRESET 0xE0200000 +#define S5PC110_SWRESET 0xE0102000 + +.globl reset_cpu +reset_cpu: + ldr r1, =S5PC1XX_PRO_ID + ldr r2, [r1] + ldr r4, =0x00010000 + and r4, r2, r4 + cmp r4, #0 + bne 110f + /* S5PC100 */ + ldr r1, =S5PC100_SWRESET + ldr r2, =0xC100 + b 200f +110: /* S5PC110 */ + ldr r1, =S5PC110_SWRESET + mov r2, #1 +200: + str r2, [r1] +_loop_forever: + b _loop_forever diff --git a/cpu/arm_cortexa8/s5pc1xx/timer.c b/cpu/arm_cortexa8/s5pc1xx/timer.c new file mode 100644 index 0000000..cdba5d9 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/timer.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Heungjun Kim riverful.kim@samsung.com + * Inki Dae inki.dae@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/pwm.h> +#include <asm/arch/clk.h> + +#define PRESCALER_1 (16 - 1) /* prescaler of timer 2, 3, 4 */ +#define MUX_DIV_2 1 /* 1/2 period */ +#define MUX_DIV_4 2 /* 1/4 period */ +#define MUX_DIV_8 3 /* 1/8 period */ +#define MUX_DIV_16 4 /* 1/16 period */ +#define MUX4_DIV_SHIFT 16 + +#define TCON_TIMER4_SHIFT 20 + +static unsigned long count_value; + +/* Internal tick units */ +static unsigned long long timestamp; /* Monotonic incrementing timer */ +static unsigned long lastdec; /* Last decremneter snapshot */ + +/* macro to read the 16 bit timer */ +static inline struct s5pc1xx_timer *s5pc1xx_get_base_timer(void) +{ + if (cpu_is_s5pc110()) + return (struct s5pc1xx_timer *)S5PC110_TIMER_BASE; + else + return (struct s5pc1xx_timer *)S5PC100_TIMER_BASE; +} + +int timer_init(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + u32 val; + + /* + * @ PWM Timer 4 + * Timer Freq(HZ) = + * PCLK / { (prescaler_value + 1) * (divider_value) } + */ + + /* set prescaler : 16 */ + /* set divider : 2 */ + writel((PRESCALER_1 & 0xff) << 8, &timer->tcfg0); + writel((MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT, &timer->tcfg1); + + if (count_value == 0) { + /* reset initial value */ + /* count_value = 2085937.5(HZ) (per 1 sec)*/ + count_value = get_pclk() / ((PRESCALER_1 + 1) * + (MUX_DIV_2 + 1)); + + /* count_value / 100 = 20859.375(HZ) (per 10 msec) */ + count_value = count_value / 100; + } + + /* set count value */ + writel(count_value, &timer->tcntb4); + lastdec = count_value; + + val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) | + S5PC1XX_TCON4_AUTO_RELOAD; + + /* auto reload & manual update */ + writel(val | S5PC1XX_TCON4_UPDATE, &timer->tcon); + + /* start PWM timer 4 */ + writel(val | S5PC1XX_TCON4_START, &timer->tcon); + + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ +void reset_timer(void) +{ + reset_timer_masked(); +} + +unsigned long get_timer(unsigned long base) +{ + return get_timer_masked() - base; +} + +void set_timer(unsigned long t) +{ + timestamp = t; +} + +/* delay x useconds */ +void udelay(unsigned long usec) +{ + unsigned long tmo, tmp; + + if (usec >= 1000) { + /* + * if "big" number, spread normalization + * to seconds + * 1. start to normalize for usec to ticks per sec + * 2. find number of "ticks" to wait to achieve target + * 3. finish normalize. + */ + tmo = usec / 1000; + tmo *= (CONFIG_SYS_HZ * count_value / 10); + tmo /= 1000; + } else { + /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ * count_value / 10; + tmo /= (1000 * 1000); + } + + /* get current timestamp */ + tmp = get_timer(0); + + /* if setting this fordward will roll time stamp */ + /* reset "advancing" timestamp to 0, set lastdec value */ + /* else, set advancing stamp wake up time */ + if ((tmo + tmp + 1) < tmp) + reset_timer_masked(); + else + tmo += tmp; + + /* loop till event */ + while (get_timer_masked() < tmo) + ; /* nop */ +} + +void reset_timer_masked(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + + /* reset time */ + lastdec = readl(&timer->tcnto4); + timestamp = 0; +} + +unsigned long get_timer_masked(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + unsigned long now = readl(&timer->tcnto4); + + if (lastdec >= now) + timestamp += lastdec - now; + else + timestamp += lastdec + count_value - now; + + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/include/asm-arm/arch-s5pc1xx/clk.h b/include/asm-arm/arch-s5pc1xx/clk.h new file mode 100644 index 0000000..f1aa44f --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/clk.h @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_ + +void s5pc1xx_clock_init(void); + +extern unsigned long (*get_pll_clk)(int pllreg); +extern unsigned long (*get_arm_clk)(void); +extern unsigned long (*get_pclk)(void); + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/clock.h b/include/asm-arm/arch-s5pc1xx/clock.h new file mode 100644 index 0000000..0cad922 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/clock.h @@ -0,0 +1,94 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_CLOCK_H_ +#define __ASM_ARM_ARCH_CLOCK_H_ + +#ifndef __ASSEMBLY__ +struct s5pc100_clock { + unsigned long apll_lock; + unsigned long mpll_lock; + unsigned long epll_lock; + unsigned long hpll_lock; + unsigned char res1[0xf0]; + unsigned long apll_con; + unsigned long mpll_con; + unsigned long epll_con; + unsigned long hpll_con; + unsigned char res2[0xf0]; + unsigned long src0; + unsigned long src1; + unsigned long src2; + unsigned long src3; + unsigned char res3[0xf0]; + unsigned long div0; + unsigned long div1; + unsigned long div2; + unsigned long div3; + unsigned long div4; + unsigned char res4[0x1ec]; + unsigned long gate_d00; + unsigned long gate_d01; + unsigned long gate_d02; + unsigned char res5[0x54]; + unsigned long gate_sclk0; + unsigned long gate_sclk1; +}; + +struct s5pc110_clock { + unsigned long apll_lock; + unsigned char res1[0x4]; + unsigned long mpll_lock; + unsigned char res2[0x4]; + unsigned long epll_lock; + unsigned char res3[0xc]; + unsigned long vpll_lock; + unsigned char res4[0xdc]; + unsigned long apll_con; + unsigned char res5[0x4]; + unsigned long mpll_con; + unsigned char res6[0x4]; + unsigned long epll_con; + unsigned char res7[0xc]; + unsigned long vpll_con; + unsigned char res8[0xdc]; + unsigned long src0; + unsigned long src1; + unsigned long src2; + unsigned long src3; + unsigned char res9[0xf0]; + unsigned long div0; + unsigned long div1; + unsigned long div2; + unsigned long div3; + unsigned long div4; + unsigned char res10[0x1ec]; + unsigned long gate_d00; + unsigned long gate_d01; + unsigned long gate_d02; + unsigned char res11[0x54]; + unsigned long gate_sclk0; + unsigned long gate_sclk1; +}; +#endif + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/cpu.h b/include/asm-arm/arch-s5pc1xx/cpu.h new file mode 100644 index 0000000..90485aa --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/cpu.h @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _S5PC1XX_CPU_H +#define _S5PC1XX_CPU_H + +#define S5PC1XX_ADDR_BASE 0xE0000000 + +#define S5PC1XX_CLOCK_BASE 0xE0100000 + +/* S5PC100 */ +#define S5PC100_GPIO_BASE 0xE0300000 +#define S5PC100_VIC0_BASE 0xE4000000 +#define S5PC100_VIC1_BASE 0xE4100000 +#define S5PC100_VIC2_BASE 0xE4200000 +#define S5PC100_DMC_BASE 0xE6000000 +#define S5PC100_SROMC_BASE 0xE7000000 +#define S5PC100_ONENAND_BASE 0xE7100000 +#define S5PC100_PWMTIMER_BASE 0xEA000000 +#define S5PC100_WATCHDOG_BASE 0xEA200000 +#define S5PC100_UART_BASE 0xEC000000 + +/* S5PC110 */ +#define S5PC110_GPIO_BASE 0xE0200000 +#define S5PC110_PWMTIMER_BASE 0xE2500000 +#define S5PC110_WATCHDOG_BASE 0xE2700000 +#define S5PC110_UART_BASE 0xE2900000 +#define S5PC110_SROMC_BASE 0xE8000000 +#define S5PC110_DMC0_BASE 0xF0000000 +#define S5PC110_DMC1_BASE 0xF1400000 +#define S5PC110_VIC0_BASE 0xF2000000 +#define S5PC110_VIC1_BASE 0xF2100000 +#define S5PC110_VIC2_BASE 0xF2200000 +#define S5PC110_VIC3_BASE 0xF2300000 + +/* Chip ID */ +#define S5PC1XX_PRO_ID 0xE0000000 + +#ifndef __ASSEMBLY__ +/* CPU detection macros */ +extern unsigned int s5pc1xx_cpu_id; + +#define IS_SAMSUNG_TYPE(type, id) \ +static inline int cpu_is_##type(void) \ +{ \ + return s5pc1xx_cpu_id == id ? 1 : 0; \ +} + +IS_SAMSUNG_TYPE(s5pc100, 0xc100) +IS_SAMSUNG_TYPE(s5pc110, 0xc110) +#endif + +#endif /* _S5PC1XX_CPU_H */ diff --git a/include/asm-arm/arch-s5pc1xx/gpio.h b/include/asm-arm/arch-s5pc1xx/gpio.h new file mode 100644 index 0000000..0010405 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/gpio.h @@ -0,0 +1,129 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H + +#ifndef __ASSEMBLY__ +struct s5pc1xx_gpio_bank { + unsigned long con; + unsigned long dat; + unsigned long pull; + unsigned long drv; + unsigned long pdn_con; + unsigned long pdn_pull; + unsigned char res1[8]; +}; + +struct s5pc100_gpio { + struct s5pc1xx_gpio_bank gpio_a0; + struct s5pc1xx_gpio_bank gpio_a1; + struct s5pc1xx_gpio_bank gpio_b; + struct s5pc1xx_gpio_bank gpio_c; + struct s5pc1xx_gpio_bank gpio_d; + struct s5pc1xx_gpio_bank gpio_e0; + struct s5pc1xx_gpio_bank gpio_e1; + struct s5pc1xx_gpio_bank gpio_f0; + struct s5pc1xx_gpio_bank gpio_f1; + struct s5pc1xx_gpio_bank gpio_f2; + struct s5pc1xx_gpio_bank gpio_f3; + struct s5pc1xx_gpio_bank gpio_g0; + struct s5pc1xx_gpio_bank gpio_g1; + struct s5pc1xx_gpio_bank gpio_g2; + struct s5pc1xx_gpio_bank gpio_g3; + struct s5pc1xx_gpio_bank gpio_i; + struct s5pc1xx_gpio_bank gpio_j0; + struct s5pc1xx_gpio_bank gpio_j1; + struct s5pc1xx_gpio_bank gpio_j2; + struct s5pc1xx_gpio_bank gpio_j3; + struct s5pc1xx_gpio_bank gpio_j4; + struct s5pc1xx_gpio_bank gpio_k0; + struct s5pc1xx_gpio_bank gpio_k1; + struct s5pc1xx_gpio_bank gpio_k2; + struct s5pc1xx_gpio_bank gpio_k3; + struct s5pc1xx_gpio_bank gpio_l0; + struct s5pc1xx_gpio_bank gpio_l1; + struct s5pc1xx_gpio_bank gpio_l2; + struct s5pc1xx_gpio_bank gpio_l3; + struct s5pc1xx_gpio_bank gpio_l4; + struct s5pc1xx_gpio_bank gpio_h0; + struct s5pc1xx_gpio_bank gpio_h1; + struct s5pc1xx_gpio_bank gpio_h2; + struct s5pc1xx_gpio_bank gpio_h3; +}; + +struct s5pc110_gpio { + struct s5pc1xx_gpio_bank gpio_a0; + struct s5pc1xx_gpio_bank gpio_a1; + struct s5pc1xx_gpio_bank gpio_b; + struct s5pc1xx_gpio_bank gpio_c0; + struct s5pc1xx_gpio_bank gpio_c1; + struct s5pc1xx_gpio_bank gpio_d0; + struct s5pc1xx_gpio_bank gpio_d1; + struct s5pc1xx_gpio_bank gpio_e0; + struct s5pc1xx_gpio_bank gpio_e1; + struct s5pc1xx_gpio_bank gpio_f0; + struct s5pc1xx_gpio_bank gpio_f1; + struct s5pc1xx_gpio_bank gpio_f2; + struct s5pc1xx_gpio_bank gpio_f3; + struct s5pc1xx_gpio_bank gpio_g0; + struct s5pc1xx_gpio_bank gpio_g1; + struct s5pc1xx_gpio_bank gpio_g2; + struct s5pc1xx_gpio_bank gpio_g3; + struct s5pc1xx_gpio_bank gpio_i; + struct s5pc1xx_gpio_bank gpio_j0; + struct s5pc1xx_gpio_bank gpio_j1; + struct s5pc1xx_gpio_bank gpio_j2; + struct s5pc1xx_gpio_bank gpio_j3; + struct s5pc1xx_gpio_bank gpio_j4; + struct s5pc1xx_gpio_bank gpio_mp0_1; + struct s5pc1xx_gpio_bank gpio_mp0_2; + struct s5pc1xx_gpio_bank gpio_mp0_3; + struct s5pc1xx_gpio_bank gpio_mp0_4; + struct s5pc1xx_gpio_bank gpio_mp0_5; + struct s5pc1xx_gpio_bank gpio_mp0_6; + struct s5pc1xx_gpio_bank gpio_mp0_7; + struct s5pc1xx_gpio_bank gpio_mp1_0; + struct s5pc1xx_gpio_bank gpio_mp1_1; + struct s5pc1xx_gpio_bank gpio_mp1_2; + struct s5pc1xx_gpio_bank gpio_mp1_3; + struct s5pc1xx_gpio_bank gpio_mp1_4; + struct s5pc1xx_gpio_bank gpio_mp1_5; + struct s5pc1xx_gpio_bank gpio_mp1_6; + struct s5pc1xx_gpio_bank gpio_mp1_7; + struct s5pc1xx_gpio_bank gpio_mp1_8; + struct s5pc1xx_gpio_bank gpio_mp2_0; + struct s5pc1xx_gpio_bank gpio_mp2_1; + struct s5pc1xx_gpio_bank gpio_mp2_2; + struct s5pc1xx_gpio_bank gpio_mp2_3; + struct s5pc1xx_gpio_bank gpio_mp2_4; + struct s5pc1xx_gpio_bank gpio_mp2_5; + struct s5pc1xx_gpio_bank gpio_mp2_6; + struct s5pc1xx_gpio_bank gpio_mp2_7; + struct s5pc1xx_gpio_bank gpio_mp2_8; + struct s5pc1xx_gpio_bank res1[48]; + struct s5pc1xx_gpio_bank gpio_h0; + struct s5pc1xx_gpio_bank gpio_h1; + struct s5pc1xx_gpio_bank gpio_h2; + struct s5pc1xx_gpio_bank gpio_h3; +}; +#endif + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/power.h b/include/asm-arm/arch-s5pc1xx/power.h new file mode 100644 index 0000000..57e2a2b --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/power.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2009 Samsung Electronics + * Kyungmin Park kyungmin.park@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_POWER_H_ +#define __ASM_ARM_ARCH_POWER_H_ + +/* + * Power control + */ +#define S5PC100_OTHERS 0xE0108200 +#define S5PC100_RST_STAT 0xE0108300 +#define S5PC100_SLEEP_WAKEUP (1 << 3) +#define S5PC100_WAKEUP_STAT 0xE0108304 +#define S5PC100_INFORM0 0xE0108400 + +#define S5PC110_RST_STAT 0xE010A000 +#define S5PC110_SLEEP_WAKEUP (1 << 3) +#define S5PC110_WAKEUP_STAT 0xE010C200 +#define S5PC110_OTHERS 0xE010E000 +#define S5PC110_USB_PHY_CON 0xE010E80C +#define S5PC110_INFORM0 0xE010F000 + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/pwm.h b/include/asm-arm/arch-s5pc1xx/pwm.h new file mode 100644 index 0000000..53c23cd --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/pwm.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Kyungmin Park kyungmin.park@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_ARCH_PWM_H_ +#define __ASM_ARM_ARCH_PWM_H_ + +/* PWM timer addressing */ +#define S5PC100_TIMER_BASE S5PC100_PWMTIMER_BASE +#define S5PC110_TIMER_BASE S5PC110_PWMTIMER_BASE + +/* Interval mode(Auto Reload) of PWM Timer 4 */ +#define S5PC1XX_TCON4_AUTO_RELOAD (1 << 22) +/* Update TCNTB4 */ +#define S5PC1XX_TCON4_UPDATE (1 << 21) +/* start bit of PWM Timer 4 */ +#define S5PC1XX_TCON4_START (1 << 20) + +#ifndef __ASSEMBLY__ +struct s5pc1xx_timer { + unsigned long tcfg0; + unsigned long tcfg1; + unsigned long tcon; + unsigned long tcntb0; + unsigned long tcmpb0; + unsigned long tcnto0; + unsigned long tcntb1; + unsigned long tcmpb1; + unsigned long tcnto1; + unsigned long tcntb2; + unsigned long tcmpb2; + unsigned long tcnto2; + unsigned long tcntb3; + unsigned long res1; + unsigned long tcnto3; + unsigned long tcntb4; + unsigned long tcnto4; + unsigned long tintcstat; +}; +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/uart.h b/include/asm-arm/arch-s5pc1xx/uart.h new file mode 100644 index 0000000..bd7d6b2 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/uart.h @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_UART_H_ +#define __ASM_ARCH_UART_H_ + +#ifndef __ASSEMBLY__ +struct s5pc1xx_uart { + unsigned long ulcon; + unsigned long ucon; + unsigned long ufcon; + unsigned long umcon; + unsigned long utrstat; + unsigned long uerstat; + unsigned long ufstat; + unsigned long umstat; + unsigned char utxh; + unsigned char res1[3]; + unsigned char urxh; + unsigned char res2[3]; + unsigned long ubrdiv; + unsigned short udivslot; + unsigned char res3[2]; + unsigned char res4[0x3d0]; +}; +#endif /* __ASSEMBLY__ */ + +#endif

Minkyu Kang wrote:
This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com
Ack-ed Tom

Dear Tom
2009/9/22 Tom Tom.Rix@windriver.com:
Minkyu Kang wrote:
This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com
Ack-ed Tom _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Thanks for review
and I have one question when I send next patch or commit this patch, should I add Acked-by?
Thanks again Minkyu Kang

Minkyu Kang wrote:
Dear Tom
2009/9/22 Tom Tom.Rix@windriver.com:
Minkyu Kang wrote:
This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com
Ack-ed Tom _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Thanks for review
and I have one question when I send next patch or commit this patch, should I add Acked-by?
Good question! From the way you submitted the patch, you added yourself as the sign off line. When you push the patch, you may add me to the sign off. As long as the original author gets the credit.
This is also useful so multiple re-reviews of an ack-ed patch do not stall submission.
Tom
Thanks again Minkyu Kang

This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com --- Changes since v1: - make C struct instead of base+offset - use writel/readl function - use the strmhz function - fix some comments
Changes since v2: - use function pointer for separate Soc - provide two separate functions for each Soc - remove not helpful cpu informations - modify to lower case letter in C struct - remove unnecessary Macro and header files
Changes since v3: - N/A
cpu/arm_cortexa8/s5pc1xx/Makefile | 53 ++++++ cpu/arm_cortexa8/s5pc1xx/cache.c | 43 +++++ cpu/arm_cortexa8/s5pc1xx/clock.c | 308 ++++++++++++++++++++++++++++++++++ cpu/arm_cortexa8/s5pc1xx/cpu_info.c | 57 +++++++ cpu/arm_cortexa8/s5pc1xx/reset.S | 47 +++++ cpu/arm_cortexa8/s5pc1xx/timer.c | 195 +++++++++++++++++++++ include/asm-arm/arch-s5pc1xx/clk.h | 32 ++++ include/asm-arm/arch-s5pc1xx/clock.h | 94 ++++++++++ include/asm-arm/arch-s5pc1xx/cpu.h | 72 ++++++++ include/asm-arm/arch-s5pc1xx/gpio.h | 129 ++++++++++++++ include/asm-arm/arch-s5pc1xx/power.h | 42 +++++ include/asm-arm/arch-s5pc1xx/pwm.h | 59 +++++++ include/asm-arm/arch-s5pc1xx/uart.h | 47 +++++ 13 files changed, 1178 insertions(+), 0 deletions(-) create mode 100644 cpu/arm_cortexa8/s5pc1xx/Makefile create mode 100644 cpu/arm_cortexa8/s5pc1xx/cache.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/clock.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/cpu_info.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/reset.S create mode 100644 cpu/arm_cortexa8/s5pc1xx/timer.c create mode 100644 include/asm-arm/arch-s5pc1xx/clk.h create mode 100644 include/asm-arm/arch-s5pc1xx/clock.h create mode 100644 include/asm-arm/arch-s5pc1xx/cpu.h create mode 100644 include/asm-arm/arch-s5pc1xx/gpio.h create mode 100644 include/asm-arm/arch-s5pc1xx/power.h create mode 100644 include/asm-arm/arch-s5pc1xx/pwm.h create mode 100644 include/asm-arm/arch-s5pc1xx/uart.h
diff --git a/cpu/arm_cortexa8/s5pc1xx/Makefile b/cpu/arm_cortexa8/s5pc1xx/Makefile new file mode 100644 index 0000000..e08d9d8 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, lg@denx.de +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).a + +SOBJS = reset.o + +COBJS += cache.o +COBJS += clock.o +COBJS += cpu_info.o +COBJS += timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/cpu/arm_cortexa8/s5pc1xx/cache.c b/cpu/arm_cortexa8/s5pc1xx/cache.c new file mode 100644 index 0000000..8652a45 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/cache.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/cache.h> + +void l2_cache_enable(void) +{ + unsigned long i; + + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); + __asm__ __volatile__("orr %0, %0, #0x2":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); +} + +void l2_cache_disable(void) +{ + unsigned long i; + + __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i)); + __asm__ __volatile__("bic %0, %0, #0x2":"=r"(i)); + __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i)); +} diff --git a/cpu/arm_cortexa8/s5pc1xx/clock.c b/cpu/arm_cortexa8/s5pc1xx/clock.c new file mode 100644 index 0000000..a9e78dd --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/clock.c @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> + +#define APLL 0 +#define MPLL 1 +#define EPLL 2 +#define HPLL 3 +#define VPLL 4 + +#define CLK_M 0 +#define CLK_D 1 +#define CLK_P 2 + +#ifndef CONFIG_SYS_CLK_FREQ_C100 +#define CONFIG_SYS_CLK_FREQ_C100 12000000 +#endif +#ifndef CONFIG_SYS_CLK_FREQ_C110 +#define CONFIG_SYS_CLK_FREQ_C110 24000000 +#endif + +unsigned long (*get_pclk)(void); +unsigned long (*get_arm_clk)(void); +unsigned long (*get_pll_clk)(int); + +/* s5pc110: return pll clock frequency */ +static unsigned long s5pc100_get_pll_clk(int pllreg) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con); + break; + case MPLL: + r = readl(&clk->mpll_con); + break; + case EPLL: + r = readl(&clk->epll_con); + break; + case HPLL: + r = readl(&clk->hpll_con); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [23:16] + * EPLL_CON: MIDV [23:16] + * HPLL_CON: MIDV [23:16] + */ + if (pllreg == APLL) + mask = 0x3ff; + else + mask = 0x0ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + freq = CONFIG_SYS_CLK_FREQ_C100; + fout = m * (freq / (p * (1 << s))); + + return fout; +} + +/* s5pc100: return pll clock frequency */ +static unsigned long s5pc110_get_pll_clk(int pllreg) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long r, m, p, s, mask, fout; + unsigned int freq; + + switch (pllreg) { + case APLL: + r = readl(&clk->apll_con); + break; + case MPLL: + r = readl(&clk->mpll_con); + break; + case EPLL: + r = readl(&clk->epll_con); + break; + case VPLL: + r = readl(&clk->vpll_con); + break; + default: + printf("Unsupported PLL (%d)\n", pllreg); + return 0; + } + + /* + * APLL_CON: MIDV [25:16] + * MPLL_CON: MIDV [25:16] + * EPLL_CON: MIDV [24:16] + * VPLL_CON: MIDV [24:16] + */ + if (pllreg == APLL || pllreg == MPLL) + mask = 0x3ff; + else + mask = 0x1ff; + + m = (r >> 16) & mask; + + /* PDIV [13:8] */ + p = (r >> 8) & 0x3f; + /* SDIV [2:0] */ + s = r & 0x7; + + freq = CONFIG_SYS_CLK_FREQ_C110; + if (pllreg == APLL) { + if (s < 1) + s = 1; + /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ + fout = m * (freq / (p * (1 << (s - 1)))); + } else + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ + fout = m * (freq / (p * (1 << s))); + + return fout; +} + +/* s5pc110: return ARM clock frequency */ +static unsigned long s5pc110_get_arm_clk(void) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio; + + div = readl(&clk->div0); + + /* APLL_RATIO: [2:0] */ + apll_ratio = div & 0x7; + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll; + + return armclk; +} + +/* s5pc100: return ARM clock frequency */ +static unsigned long s5pc100_get_arm_clk(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long div; + unsigned long dout_apll, armclk; + unsigned int apll_ratio, arm_ratio; + + div = readl(&clk->div0); + + /* ARM_RATIO: [6:4] */ + arm_ratio = (div >> 4) & 0x7; + /* APLL_RATIO: [0] */ + apll_ratio = div & 0x1; + + dout_apll = get_pll_clk(APLL) / (apll_ratio + 1); + armclk = dout_apll / (arm_ratio + 1); + + return armclk; +} + +/* s5pc100: return HCLKD0 frequency */ +static unsigned long get_hclk(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long hclkd0; + uint div, d0_bus_ratio; + + div = readl(&clk->div0); + /* D0_BUS_RATIO: [10:8] */ + d0_bus_ratio = (div >> 8) & 0x7; + + hclkd0 = get_arm_clk() / (d0_bus_ratio + 1); + + return hclkd0; +} + +/* s5pc100: return PCLKD1 frequency */ +static unsigned long get_pclkd1(void) +{ + struct s5pc100_clock *clk = (struct s5pc100_clock *)S5PC1XX_CLOCK_BASE; + unsigned long d1_bus, pclkd1; + uint div, d1_bus_ratio, pclkd1_ratio; + + div = readl(&clk->div0); + /* D1_BUS_RATIO: [14:12] */ + d1_bus_ratio = (div >> 12) & 0x7; + /* PCLKD1_RATIO: [18:16] */ + pclkd1_ratio = (div >> 16) & 0x7; + + /* ASYNC Mode */ + d1_bus = get_pll_clk(MPLL) / (d1_bus_ratio + 1); + pclkd1 = d1_bus / (pclkd1_ratio + 1); + + return pclkd1; +} + +/* s5pc110: return HCLKs frequency */ +static unsigned long get_hclk_sys(int dom) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long hclk; + unsigned int div; + unsigned int offset; + unsigned int hclk_sys_ratio; + + if (dom == CLK_M) + return get_hclk(); + + div = readl(&clk->div0); + + /* + * HCLK_MSYS_RATIO: [10:8] + * HCLK_DSYS_RATIO: [19:16] + * HCLK_PSYS_RATIO: [27:24] + */ + offset = 8 + (dom << 0x3); + + hclk_sys_ratio = (div >> offset) & 0xf; + + hclk = get_pll_clk(MPLL) / (hclk_sys_ratio + 1); + + return hclk; +} + +/* s5pc110: return PCLKs frequency */ +static unsigned long get_pclk_sys(int dom) +{ + struct s5pc110_clock *clk = (struct s5pc110_clock *)S5PC1XX_CLOCK_BASE; + unsigned long pclk; + unsigned int div; + unsigned int offset; + unsigned int pclk_sys_ratio; + + div = readl(&clk->div0); + + /* + * PCLK_MSYS_RATIO: [14:12] + * PCLK_DSYS_RATIO: [22:20] + * PCLK_PSYS_RATIO: [30:28] + */ + offset = 12 + (dom << 0x3); + + pclk_sys_ratio = (div >> offset) & 0x7; + + pclk = get_hclk_sys(dom) / (pclk_sys_ratio + 1); + + return pclk; +} + +/* s5pc110: return peripheral clock frequency */ +static unsigned long s5pc110_get_pclk(void) +{ + return get_pclk_sys(CLK_P); +} + +/* s5pc100: return peripheral clock frequency */ +static unsigned long s5pc100_get_pclk(void) +{ + return get_pclkd1(); +} + +void s5pc1xx_clock_init(void) +{ + if (cpu_is_s5pc110()) { + get_pll_clk = s5pc110_get_pll_clk; + get_arm_clk = s5pc110_get_arm_clk; + get_pclk = s5pc110_get_pclk; + } else { + get_pll_clk = s5pc100_get_pll_clk; + get_arm_clk = s5pc100_get_arm_clk; + get_pclk = s5pc100_get_pclk; + } +} diff --git a/cpu/arm_cortexa8/s5pc1xx/cpu_info.c b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c new file mode 100644 index 0000000..f16c0ff --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/cpu_info.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clk.h> + +/* Default is s5pc100 */ +unsigned int s5pc1xx_cpu_id = 0xC100; + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init(void) +{ + s5pc1xx_cpu_id = readl(S5PC1XX_PRO_ID); + s5pc1xx_cpu_id = 0xC000 | ((s5pc1xx_cpu_id & 0x00FFF000) >> 12); + + s5pc1xx_clock_init(); + + return 0; +} +#endif + +u32 get_device_type(void) +{ + return s5pc1xx_cpu_id; +} + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + char buf[32]; + + printf("CPU:\tS5P%X@%sMHz\n", + s5pc1xx_cpu_id, strmhz(buf, get_arm_clk())); + + return 0; +} +#endif diff --git a/cpu/arm_cortexa8/s5pc1xx/reset.S b/cpu/arm_cortexa8/s5pc1xx/reset.S new file mode 100644 index 0000000..7f6ff9c --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/reset.S @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2009 Samsung Electronics. + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm/arch/cpu.h> + +#define S5PC100_SWRESET 0xE0200000 +#define S5PC110_SWRESET 0xE0102000 + +.globl reset_cpu +reset_cpu: + ldr r1, =S5PC1XX_PRO_ID + ldr r2, [r1] + ldr r4, =0x00010000 + and r4, r2, r4 + cmp r4, #0 + bne 110f + /* S5PC100 */ + ldr r1, =S5PC100_SWRESET + ldr r2, =0xC100 + b 200f +110: /* S5PC110 */ + ldr r1, =S5PC110_SWRESET + mov r2, #1 +200: + str r2, [r1] +_loop_forever: + b _loop_forever diff --git a/cpu/arm_cortexa8/s5pc1xx/timer.c b/cpu/arm_cortexa8/s5pc1xx/timer.c new file mode 100644 index 0000000..cdba5d9 --- /dev/null +++ b/cpu/arm_cortexa8/s5pc1xx/timer.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Heungjun Kim riverful.kim@samsung.com + * Inki Dae inki.dae@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/pwm.h> +#include <asm/arch/clk.h> + +#define PRESCALER_1 (16 - 1) /* prescaler of timer 2, 3, 4 */ +#define MUX_DIV_2 1 /* 1/2 period */ +#define MUX_DIV_4 2 /* 1/4 period */ +#define MUX_DIV_8 3 /* 1/8 period */ +#define MUX_DIV_16 4 /* 1/16 period */ +#define MUX4_DIV_SHIFT 16 + +#define TCON_TIMER4_SHIFT 20 + +static unsigned long count_value; + +/* Internal tick units */ +static unsigned long long timestamp; /* Monotonic incrementing timer */ +static unsigned long lastdec; /* Last decremneter snapshot */ + +/* macro to read the 16 bit timer */ +static inline struct s5pc1xx_timer *s5pc1xx_get_base_timer(void) +{ + if (cpu_is_s5pc110()) + return (struct s5pc1xx_timer *)S5PC110_TIMER_BASE; + else + return (struct s5pc1xx_timer *)S5PC100_TIMER_BASE; +} + +int timer_init(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + u32 val; + + /* + * @ PWM Timer 4 + * Timer Freq(HZ) = + * PCLK / { (prescaler_value + 1) * (divider_value) } + */ + + /* set prescaler : 16 */ + /* set divider : 2 */ + writel((PRESCALER_1 & 0xff) << 8, &timer->tcfg0); + writel((MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT, &timer->tcfg1); + + if (count_value == 0) { + /* reset initial value */ + /* count_value = 2085937.5(HZ) (per 1 sec)*/ + count_value = get_pclk() / ((PRESCALER_1 + 1) * + (MUX_DIV_2 + 1)); + + /* count_value / 100 = 20859.375(HZ) (per 10 msec) */ + count_value = count_value / 100; + } + + /* set count value */ + writel(count_value, &timer->tcntb4); + lastdec = count_value; + + val = (readl(&timer->tcon) & ~(0x07 << TCON_TIMER4_SHIFT)) | + S5PC1XX_TCON4_AUTO_RELOAD; + + /* auto reload & manual update */ + writel(val | S5PC1XX_TCON4_UPDATE, &timer->tcon); + + /* start PWM timer 4 */ + writel(val | S5PC1XX_TCON4_START, &timer->tcon); + + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ +void reset_timer(void) +{ + reset_timer_masked(); +} + +unsigned long get_timer(unsigned long base) +{ + return get_timer_masked() - base; +} + +void set_timer(unsigned long t) +{ + timestamp = t; +} + +/* delay x useconds */ +void udelay(unsigned long usec) +{ + unsigned long tmo, tmp; + + if (usec >= 1000) { + /* + * if "big" number, spread normalization + * to seconds + * 1. start to normalize for usec to ticks per sec + * 2. find number of "ticks" to wait to achieve target + * 3. finish normalize. + */ + tmo = usec / 1000; + tmo *= (CONFIG_SYS_HZ * count_value / 10); + tmo /= 1000; + } else { + /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * CONFIG_SYS_HZ * count_value / 10; + tmo /= (1000 * 1000); + } + + /* get current timestamp */ + tmp = get_timer(0); + + /* if setting this fordward will roll time stamp */ + /* reset "advancing" timestamp to 0, set lastdec value */ + /* else, set advancing stamp wake up time */ + if ((tmo + tmp + 1) < tmp) + reset_timer_masked(); + else + tmo += tmp; + + /* loop till event */ + while (get_timer_masked() < tmo) + ; /* nop */ +} + +void reset_timer_masked(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + + /* reset time */ + lastdec = readl(&timer->tcnto4); + timestamp = 0; +} + +unsigned long get_timer_masked(void) +{ + struct s5pc1xx_timer *const timer = s5pc1xx_get_base_timer(); + unsigned long now = readl(&timer->tcnto4); + + if (lastdec >= now) + timestamp += lastdec - now; + else + timestamp += lastdec + count_value - now; + + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/include/asm-arm/arch-s5pc1xx/clk.h b/include/asm-arm/arch-s5pc1xx/clk.h new file mode 100644 index 0000000..f1aa44f --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/clk.h @@ -0,0 +1,32 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_ + +void s5pc1xx_clock_init(void); + +extern unsigned long (*get_pll_clk)(int pllreg); +extern unsigned long (*get_arm_clk)(void); +extern unsigned long (*get_pclk)(void); + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/clock.h b/include/asm-arm/arch-s5pc1xx/clock.h new file mode 100644 index 0000000..0cad922 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/clock.h @@ -0,0 +1,94 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_CLOCK_H_ +#define __ASM_ARM_ARCH_CLOCK_H_ + +#ifndef __ASSEMBLY__ +struct s5pc100_clock { + unsigned long apll_lock; + unsigned long mpll_lock; + unsigned long epll_lock; + unsigned long hpll_lock; + unsigned char res1[0xf0]; + unsigned long apll_con; + unsigned long mpll_con; + unsigned long epll_con; + unsigned long hpll_con; + unsigned char res2[0xf0]; + unsigned long src0; + unsigned long src1; + unsigned long src2; + unsigned long src3; + unsigned char res3[0xf0]; + unsigned long div0; + unsigned long div1; + unsigned long div2; + unsigned long div3; + unsigned long div4; + unsigned char res4[0x1ec]; + unsigned long gate_d00; + unsigned long gate_d01; + unsigned long gate_d02; + unsigned char res5[0x54]; + unsigned long gate_sclk0; + unsigned long gate_sclk1; +}; + +struct s5pc110_clock { + unsigned long apll_lock; + unsigned char res1[0x4]; + unsigned long mpll_lock; + unsigned char res2[0x4]; + unsigned long epll_lock; + unsigned char res3[0xc]; + unsigned long vpll_lock; + unsigned char res4[0xdc]; + unsigned long apll_con; + unsigned char res5[0x4]; + unsigned long mpll_con; + unsigned char res6[0x4]; + unsigned long epll_con; + unsigned char res7[0xc]; + unsigned long vpll_con; + unsigned char res8[0xdc]; + unsigned long src0; + unsigned long src1; + unsigned long src2; + unsigned long src3; + unsigned char res9[0xf0]; + unsigned long div0; + unsigned long div1; + unsigned long div2; + unsigned long div3; + unsigned long div4; + unsigned char res10[0x1ec]; + unsigned long gate_d00; + unsigned long gate_d01; + unsigned long gate_d02; + unsigned char res11[0x54]; + unsigned long gate_sclk0; + unsigned long gate_sclk1; +}; +#endif + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/cpu.h b/include/asm-arm/arch-s5pc1xx/cpu.h new file mode 100644 index 0000000..90485aa --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/cpu.h @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _S5PC1XX_CPU_H +#define _S5PC1XX_CPU_H + +#define S5PC1XX_ADDR_BASE 0xE0000000 + +#define S5PC1XX_CLOCK_BASE 0xE0100000 + +/* S5PC100 */ +#define S5PC100_GPIO_BASE 0xE0300000 +#define S5PC100_VIC0_BASE 0xE4000000 +#define S5PC100_VIC1_BASE 0xE4100000 +#define S5PC100_VIC2_BASE 0xE4200000 +#define S5PC100_DMC_BASE 0xE6000000 +#define S5PC100_SROMC_BASE 0xE7000000 +#define S5PC100_ONENAND_BASE 0xE7100000 +#define S5PC100_PWMTIMER_BASE 0xEA000000 +#define S5PC100_WATCHDOG_BASE 0xEA200000 +#define S5PC100_UART_BASE 0xEC000000 + +/* S5PC110 */ +#define S5PC110_GPIO_BASE 0xE0200000 +#define S5PC110_PWMTIMER_BASE 0xE2500000 +#define S5PC110_WATCHDOG_BASE 0xE2700000 +#define S5PC110_UART_BASE 0xE2900000 +#define S5PC110_SROMC_BASE 0xE8000000 +#define S5PC110_DMC0_BASE 0xF0000000 +#define S5PC110_DMC1_BASE 0xF1400000 +#define S5PC110_VIC0_BASE 0xF2000000 +#define S5PC110_VIC1_BASE 0xF2100000 +#define S5PC110_VIC2_BASE 0xF2200000 +#define S5PC110_VIC3_BASE 0xF2300000 + +/* Chip ID */ +#define S5PC1XX_PRO_ID 0xE0000000 + +#ifndef __ASSEMBLY__ +/* CPU detection macros */ +extern unsigned int s5pc1xx_cpu_id; + +#define IS_SAMSUNG_TYPE(type, id) \ +static inline int cpu_is_##type(void) \ +{ \ + return s5pc1xx_cpu_id == id ? 1 : 0; \ +} + +IS_SAMSUNG_TYPE(s5pc100, 0xc100) +IS_SAMSUNG_TYPE(s5pc110, 0xc110) +#endif + +#endif /* _S5PC1XX_CPU_H */ diff --git a/include/asm-arm/arch-s5pc1xx/gpio.h b/include/asm-arm/arch-s5pc1xx/gpio.h new file mode 100644 index 0000000..0010405 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/gpio.h @@ -0,0 +1,129 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_GPIO_H +#define __ASM_ARCH_GPIO_H + +#ifndef __ASSEMBLY__ +struct s5pc1xx_gpio_bank { + unsigned long con; + unsigned long dat; + unsigned long pull; + unsigned long drv; + unsigned long pdn_con; + unsigned long pdn_pull; + unsigned char res1[8]; +}; + +struct s5pc100_gpio { + struct s5pc1xx_gpio_bank gpio_a0; + struct s5pc1xx_gpio_bank gpio_a1; + struct s5pc1xx_gpio_bank gpio_b; + struct s5pc1xx_gpio_bank gpio_c; + struct s5pc1xx_gpio_bank gpio_d; + struct s5pc1xx_gpio_bank gpio_e0; + struct s5pc1xx_gpio_bank gpio_e1; + struct s5pc1xx_gpio_bank gpio_f0; + struct s5pc1xx_gpio_bank gpio_f1; + struct s5pc1xx_gpio_bank gpio_f2; + struct s5pc1xx_gpio_bank gpio_f3; + struct s5pc1xx_gpio_bank gpio_g0; + struct s5pc1xx_gpio_bank gpio_g1; + struct s5pc1xx_gpio_bank gpio_g2; + struct s5pc1xx_gpio_bank gpio_g3; + struct s5pc1xx_gpio_bank gpio_i; + struct s5pc1xx_gpio_bank gpio_j0; + struct s5pc1xx_gpio_bank gpio_j1; + struct s5pc1xx_gpio_bank gpio_j2; + struct s5pc1xx_gpio_bank gpio_j3; + struct s5pc1xx_gpio_bank gpio_j4; + struct s5pc1xx_gpio_bank gpio_k0; + struct s5pc1xx_gpio_bank gpio_k1; + struct s5pc1xx_gpio_bank gpio_k2; + struct s5pc1xx_gpio_bank gpio_k3; + struct s5pc1xx_gpio_bank gpio_l0; + struct s5pc1xx_gpio_bank gpio_l1; + struct s5pc1xx_gpio_bank gpio_l2; + struct s5pc1xx_gpio_bank gpio_l3; + struct s5pc1xx_gpio_bank gpio_l4; + struct s5pc1xx_gpio_bank gpio_h0; + struct s5pc1xx_gpio_bank gpio_h1; + struct s5pc1xx_gpio_bank gpio_h2; + struct s5pc1xx_gpio_bank gpio_h3; +}; + +struct s5pc110_gpio { + struct s5pc1xx_gpio_bank gpio_a0; + struct s5pc1xx_gpio_bank gpio_a1; + struct s5pc1xx_gpio_bank gpio_b; + struct s5pc1xx_gpio_bank gpio_c0; + struct s5pc1xx_gpio_bank gpio_c1; + struct s5pc1xx_gpio_bank gpio_d0; + struct s5pc1xx_gpio_bank gpio_d1; + struct s5pc1xx_gpio_bank gpio_e0; + struct s5pc1xx_gpio_bank gpio_e1; + struct s5pc1xx_gpio_bank gpio_f0; + struct s5pc1xx_gpio_bank gpio_f1; + struct s5pc1xx_gpio_bank gpio_f2; + struct s5pc1xx_gpio_bank gpio_f3; + struct s5pc1xx_gpio_bank gpio_g0; + struct s5pc1xx_gpio_bank gpio_g1; + struct s5pc1xx_gpio_bank gpio_g2; + struct s5pc1xx_gpio_bank gpio_g3; + struct s5pc1xx_gpio_bank gpio_i; + struct s5pc1xx_gpio_bank gpio_j0; + struct s5pc1xx_gpio_bank gpio_j1; + struct s5pc1xx_gpio_bank gpio_j2; + struct s5pc1xx_gpio_bank gpio_j3; + struct s5pc1xx_gpio_bank gpio_j4; + struct s5pc1xx_gpio_bank gpio_mp0_1; + struct s5pc1xx_gpio_bank gpio_mp0_2; + struct s5pc1xx_gpio_bank gpio_mp0_3; + struct s5pc1xx_gpio_bank gpio_mp0_4; + struct s5pc1xx_gpio_bank gpio_mp0_5; + struct s5pc1xx_gpio_bank gpio_mp0_6; + struct s5pc1xx_gpio_bank gpio_mp0_7; + struct s5pc1xx_gpio_bank gpio_mp1_0; + struct s5pc1xx_gpio_bank gpio_mp1_1; + struct s5pc1xx_gpio_bank gpio_mp1_2; + struct s5pc1xx_gpio_bank gpio_mp1_3; + struct s5pc1xx_gpio_bank gpio_mp1_4; + struct s5pc1xx_gpio_bank gpio_mp1_5; + struct s5pc1xx_gpio_bank gpio_mp1_6; + struct s5pc1xx_gpio_bank gpio_mp1_7; + struct s5pc1xx_gpio_bank gpio_mp1_8; + struct s5pc1xx_gpio_bank gpio_mp2_0; + struct s5pc1xx_gpio_bank gpio_mp2_1; + struct s5pc1xx_gpio_bank gpio_mp2_2; + struct s5pc1xx_gpio_bank gpio_mp2_3; + struct s5pc1xx_gpio_bank gpio_mp2_4; + struct s5pc1xx_gpio_bank gpio_mp2_5; + struct s5pc1xx_gpio_bank gpio_mp2_6; + struct s5pc1xx_gpio_bank gpio_mp2_7; + struct s5pc1xx_gpio_bank gpio_mp2_8; + struct s5pc1xx_gpio_bank res1[48]; + struct s5pc1xx_gpio_bank gpio_h0; + struct s5pc1xx_gpio_bank gpio_h1; + struct s5pc1xx_gpio_bank gpio_h2; + struct s5pc1xx_gpio_bank gpio_h3; +}; +#endif + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/power.h b/include/asm-arm/arch-s5pc1xx/power.h new file mode 100644 index 0000000..57e2a2b --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/power.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2009 Samsung Electronics + * Kyungmin Park kyungmin.park@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARM_ARCH_POWER_H_ +#define __ASM_ARM_ARCH_POWER_H_ + +/* + * Power control + */ +#define S5PC100_OTHERS 0xE0108200 +#define S5PC100_RST_STAT 0xE0108300 +#define S5PC100_SLEEP_WAKEUP (1 << 3) +#define S5PC100_WAKEUP_STAT 0xE0108304 +#define S5PC100_INFORM0 0xE0108400 + +#define S5PC110_RST_STAT 0xE010A000 +#define S5PC110_SLEEP_WAKEUP (1 << 3) +#define S5PC110_WAKEUP_STAT 0xE010C200 +#define S5PC110_OTHERS 0xE010E000 +#define S5PC110_USB_PHY_CON 0xE010E80C +#define S5PC110_INFORM0 0xE010F000 + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/pwm.h b/include/asm-arm/arch-s5pc1xx/pwm.h new file mode 100644 index 0000000..53c23cd --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/pwm.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2009 Samsung Electronics + * Kyungmin Park kyungmin.park@samsung.com + * Minkyu Kang mk7.kang@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_ARCH_PWM_H_ +#define __ASM_ARM_ARCH_PWM_H_ + +/* PWM timer addressing */ +#define S5PC100_TIMER_BASE S5PC100_PWMTIMER_BASE +#define S5PC110_TIMER_BASE S5PC110_PWMTIMER_BASE + +/* Interval mode(Auto Reload) of PWM Timer 4 */ +#define S5PC1XX_TCON4_AUTO_RELOAD (1 << 22) +/* Update TCNTB4 */ +#define S5PC1XX_TCON4_UPDATE (1 << 21) +/* start bit of PWM Timer 4 */ +#define S5PC1XX_TCON4_START (1 << 20) + +#ifndef __ASSEMBLY__ +struct s5pc1xx_timer { + unsigned long tcfg0; + unsigned long tcfg1; + unsigned long tcon; + unsigned long tcntb0; + unsigned long tcmpb0; + unsigned long tcnto0; + unsigned long tcntb1; + unsigned long tcmpb1; + unsigned long tcnto1; + unsigned long tcntb2; + unsigned long tcmpb2; + unsigned long tcnto2; + unsigned long tcntb3; + unsigned long res1; + unsigned long tcnto3; + unsigned long tcntb4; + unsigned long tcnto4; + unsigned long tintcstat; +}; +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/include/asm-arm/arch-s5pc1xx/uart.h b/include/asm-arm/arch-s5pc1xx/uart.h new file mode 100644 index 0000000..bd7d6b2 --- /dev/null +++ b/include/asm-arm/arch-s5pc1xx/uart.h @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_ARCH_UART_H_ +#define __ASM_ARCH_UART_H_ + +#ifndef __ASSEMBLY__ +struct s5pc1xx_uart { + unsigned long ulcon; + unsigned long ucon; + unsigned long ufcon; + unsigned long umcon; + unsigned long utrstat; + unsigned long uerstat; + unsigned long ufstat; + unsigned long umstat; + unsigned char utxh; + unsigned char res1[3]; + unsigned char urxh; + unsigned char res2[3]; + unsigned long ubrdiv; + unsigned short udivslot; + unsigned char res3[2]; + unsigned char res4[0x3d0]; +}; +#endif /* __ASSEMBLY__ */ + +#endif

Minkyu Kang wrote:
This patch adds support for the Samsung s5pc100 and s5pc110 SoCs. The s5pc1xx SoC is an ARM Cortex A8 processor.
Signed-off-by: Minkyu Kang mk7.kang@samsung.com Signed-off-by: HeungJun, Kim riverful.kim@samsung.com
Changes since v1:
- make C struct instead of base+offset
- use writel/readl function
- use the strmhz function
- fix some comments
Changes since v2:
- use function pointer for separate Soc
- provide two separate functions for each Soc
- remove not helpful cpu informations
- modify to lower case letter in C struct
- remove unnecessary Macro and header files
Changes since v3:
- N/A
cpu/arm_cortexa8/s5pc1xx/Makefile | 53 ++++++ cpu/arm_cortexa8/s5pc1xx/cache.c | 43 +++++ cpu/arm_cortexa8/s5pc1xx/clock.c | 308 ++++++++++++++++++++++++++++++++++ cpu/arm_cortexa8/s5pc1xx/cpu_info.c | 57 +++++++ cpu/arm_cortexa8/s5pc1xx/reset.S | 47 +++++ cpu/arm_cortexa8/s5pc1xx/timer.c | 195 +++++++++++++++++++++ include/asm-arm/arch-s5pc1xx/clk.h | 32 ++++ include/asm-arm/arch-s5pc1xx/clock.h | 94 ++++++++++ include/asm-arm/arch-s5pc1xx/cpu.h | 72 ++++++++ include/asm-arm/arch-s5pc1xx/gpio.h | 129 ++++++++++++++ include/asm-arm/arch-s5pc1xx/power.h | 42 +++++ include/asm-arm/arch-s5pc1xx/pwm.h | 59 +++++++ include/asm-arm/arch-s5pc1xx/uart.h | 47 +++++ 13 files changed, 1178 insertions(+), 0 deletions(-) create mode 100644 cpu/arm_cortexa8/s5pc1xx/Makefile create mode 100644 cpu/arm_cortexa8/s5pc1xx/cache.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/clock.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/cpu_info.c create mode 100644 cpu/arm_cortexa8/s5pc1xx/reset.S create mode 100644 cpu/arm_cortexa8/s5pc1xx/timer.c create mode 100644 include/asm-arm/arch-s5pc1xx/clk.h create mode 100644 include/asm-arm/arch-s5pc1xx/clock.h create mode 100644 include/asm-arm/arch-s5pc1xx/cpu.h create mode 100644 include/asm-arm/arch-s5pc1xx/gpio.h create mode 100644 include/asm-arm/arch-s5pc1xx/power.h create mode 100644 include/asm-arm/arch-s5pc1xx/pwm.h create mode 100644 include/asm-arm/arch-s5pc1xx/uart.h
applied to u-boot-samsung
Minkyu Kang
participants (4)
-
Minkyu Kang
-
Minkyu Kang
-
Tom
-
Wolfgang Denk