From patchwork Wed Sep 12 11:15:18 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jos=C3=A9_Miguel_Gon=C3=A7alves?= X-Patchwork-Id: 183331 X-Patchwork-Delegate: albert.aribaud@free.fr Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 91AF32C0095 for ; Wed, 12 Sep 2012 21:26:01 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1211228177; Wed, 12 Sep 2012 13:26:00 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id IM0gO6eFeddK; Wed, 12 Sep 2012 13:25:59 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id ED9E728181; Wed, 12 Sep 2012 13:25:56 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 6AFBB281B0 for ; Wed, 12 Sep 2012 13:25:49 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id i-FuONKz0bSB for ; Wed, 12 Sep 2012 13:25:48 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from lmv.inov.pt (lmv.inov.pt [146.193.64.2]) by theia.denx.de (Postfix) with ESMTPS id E05EA281BE for ; Wed, 12 Sep 2012 13:25:32 +0200 (CEST) Received: from localhost (gtout.inov.pt [146.193.64.254]) by lmv.inov.pt (8.13.1/8.13.1) with ESMTP id q8CBFRoG029646; Wed, 12 Sep 2012 12:15:27 +0100 From: =?UTF-8?q?Jos=C3=A9=20Miguel=20Gon=C3=A7alves?= To: u-boot@lists.denx.de Date: Wed, 12 Sep 2012 12:15:18 +0100 Message-Id: <1347448523-19565-3-git-send-email-jose.goncalves@inov.pt> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1347448523-19565-1-git-send-email-jose.goncalves@inov.pt> References: <1347448523-19565-1-git-send-email-jose.goncalves@inov.pt> MIME-Version: 1.0 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.0.1 (lmv.inov.pt [146.193.64.2]); Wed, 12 Sep 2012 12:15:28 +0100 (WEST) X-INOV-EmailServer-Information: Please contact the Email service provider for more information X-INOV-EmailServer: Found to be clean X-INOV-EmailServer-From: jose.goncalves@inov.pt Cc: scottwood@freescale.com, =?UTF-8?q?Jos=C3=A9=20Miguel=20Gon=C3=A7alves?= Subject: [U-Boot] [PATCH 2/7] S3C24XX: Add core support for Samsung's S3C24XX SoCs X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This patch adds the support for Samsung's S3C24XX SoCs that have an ARM926EJS core. Currently it supports S3C2412, S3C2413, S3C2416 and S3C2450. Tested on an S3C2416 platform. Signed-off-by: José Miguel Gonçalves --- arch/arm/cpu/arm926ejs/s3c24xx/Makefile | 52 +++ arch/arm/cpu/arm926ejs/s3c24xx/cpu.c | 56 +++ arch/arm/cpu/arm926ejs/s3c24xx/cpu_info.c | 56 +++ arch/arm/cpu/arm926ejs/s3c24xx/s3c2412_speed.c | 114 +++++ arch/arm/cpu/arm926ejs/s3c24xx/s3c2416_speed.c | 113 +++++ arch/arm/cpu/arm926ejs/s3c24xx/timer.c | 159 +++++++ arch/arm/include/asm/arch-s3c24xx/s3c2412.h | 120 ++++++ arch/arm/include/asm/arch-s3c24xx/s3c2416.h | 149 +++++++ arch/arm/include/asm/arch-s3c24xx/s3c24xx.h | 503 +++++++++++++++++++++++ arch/arm/include/asm/arch-s3c24xx/s3c24xx_cpu.h | 30 ++ include/common.h | 1 + 11 files changed, 1353 insertions(+) create mode 100644 arch/arm/cpu/arm926ejs/s3c24xx/Makefile create mode 100644 arch/arm/cpu/arm926ejs/s3c24xx/cpu.c create mode 100644 arch/arm/cpu/arm926ejs/s3c24xx/cpu_info.c create mode 100644 arch/arm/cpu/arm926ejs/s3c24xx/s3c2412_speed.c create mode 100644 arch/arm/cpu/arm926ejs/s3c24xx/s3c2416_speed.c create mode 100644 arch/arm/cpu/arm926ejs/s3c24xx/timer.c create mode 100644 arch/arm/include/asm/arch-s3c24xx/s3c2412.h create mode 100644 arch/arm/include/asm/arch-s3c24xx/s3c2416.h create mode 100644 arch/arm/include/asm/arch-s3c24xx/s3c24xx.h create mode 100644 arch/arm/include/asm/arch-s3c24xx/s3c24xx_cpu.h diff --git a/arch/arm/cpu/arm926ejs/s3c24xx/Makefile b/arch/arm/cpu/arm926ejs/s3c24xx/Makefile new file mode 100644 index 0000000..62b8378 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/s3c24xx/Makefile @@ -0,0 +1,52 @@ +# +# (C) Copyright 2012 INOV - INESC Inovacao +# Jose Goncalves +# +# 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).o + +COBJS-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o +ifeq ($(filter y,$(CONFIG_S3C2412) $(CONFIG_S3C2413)),y) +COBJS-y += s3c2412_speed.o +else +COBJS-y += s3c2416_speed.o +endif +COBJS-y += cpu.o +COBJS-y += timer.o + +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm926ejs/s3c24xx/cpu.c b/arch/arm/cpu/arm926ejs/s3c24xx/cpu.c new file mode 100644 index 0000000..326748c --- /dev/null +++ b/arch/arm/cpu/arm926ejs/s3c24xx/cpu.c @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * 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 +#include +#include + +void enable_caches(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); +#endif +} + +/* + * Reset the cpu by setting up the watchdog timer and let him time out. + */ +void reset_cpu(ulong addr) +{ + s3c24xx_watchdog *const watchdog = s3c24xx_get_base_watchdog(); + + /* Disable watchdog */ + writel(0x0000, &watchdog->wtcon); + + /* Initialize watchdog timer count register */ + writel(0x0001, &watchdog->wtcnt); + + /* Enable watchdog timer; assert reset at timer timeout */ + writel(0x0021, &watchdog->wtcon); + + while (1) + /* loop forever and wait for reset to happen */ ; +} diff --git a/arch/arm/cpu/arm926ejs/s3c24xx/cpu_info.c b/arch/arm/cpu/arm926ejs/s3c24xx/cpu_info.c new file mode 100644 index 0000000..37dbff4 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/s3c24xx/cpu_info.c @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2010 + * David Mueller + * + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * 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 +#include +#include + +typedef ulong(*getfreq) (void); + +static const getfreq freq_f[] = { + get_FCLK, + get_HCLK, + get_PCLK, +}; + +static const char freq_c[] = { 'F', 'H', 'P' }; + +int print_cpuinfo(void) +{ + int i; + char buf[32]; + ulong cpuid; + s3c24xx_gpio *const gpio = s3c24xx_get_base_gpio(); + + cpuid = readl(&gpio->gstatus[1]); + printf("CPU: %8s (id %08lX) @ %s MHz\n", s3c24xx_get_cpu_name(), + cpuid, strmhz(buf, get_ARMCLK())); + for (i = 0; i < ARRAY_SIZE(freq_f); i++) + printf("%cCLK: %8s MHz\n", freq_c[i], + strmhz(buf, freq_f[i] ())); + + return 0; +} diff --git a/arch/arm/cpu/arm926ejs/s3c24xx/s3c2412_speed.c b/arch/arm/cpu/arm926ejs/s3c24xx/s3c2412_speed.c new file mode 100644 index 0000000..2b9c905 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/s3c24xx/s3c2412_speed.c @@ -0,0 +1,114 @@ +/* + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * Based on U-Boot 1.3.4 from Samsung. + * + * 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 +#include +#include + +#define MPLL 0 +#define UPLL 1 + +/* ------------------------------------------------------------------------- */ +/* + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +static ulong get_PLLCLK(int pllreg) +{ + s3c2412_sysctl *const sysctl = s3c2412_get_base_sysctl(); + u32 pllcon, f; + u16 mdiv, pdiv, sdiv; + + if (pllreg == MPLL) + pllcon = readl(&sysctl->mpllcon); + else if (pllreg == UPLL) + pllcon = readl(&sysctl->upllcon); + else + hang(); + + mdiv = (pllcon >> 12) & 0xFF; + pdiv = (pllcon >> 4) & 0x3F; + sdiv = pllcon & 0x3; + + f = (mdiv + 8) * (CONFIG_SYS_CLK_FREQ / ((pdiv + 2) << sdiv)); + if (pllreg == MPLL) + f <<= 1; + + return f; +} + +/* return FCLK frequency */ +ulong get_FCLK(void) +{ + return get_PLLCLK(MPLL); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + s3c2412_sysctl *const sysctl = s3c2412_get_base_sysctl(); + u32 clkdivn; + u16 hclk_div, arm_div; + + clkdivn = readl(&sysctl->clkdivn); + hclk_div = (clkdivn & 0x3) + 1; + arm_div = ((clkdivn >> 3) & 0x1) + 1; + + return get_FCLK() / (hclk_div * arm_div); +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + s3c2412_sysctl *const sysctl = s3c2412_get_base_sysctl(); + u32 clkdivn; + + clkdivn = readl(&sysctl->clkdivn); + + return (clkdivn & 0x4) ? get_HCLK() / 2 : get_HCLK(); +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + return get_PLLCLK(UPLL); +} + +/* return ARMCORE frequency */ +ulong get_ARMCLK(void) +{ + s3c2412_sysctl *const sysctl = s3c2412_get_base_sysctl(); + u32 clkdivn; + + clkdivn = readl(&sysctl->clkdivn); + if (clkdivn & 0x10) + return get_FCLK(); + + return (clkdivn & 0x8) ? get_FCLK() / 2 : get_FCLK(); +} diff --git a/arch/arm/cpu/arm926ejs/s3c24xx/s3c2416_speed.c b/arch/arm/cpu/arm926ejs/s3c24xx/s3c2416_speed.c new file mode 100644 index 0000000..40463e2 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/s3c24xx/s3c2416_speed.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * Based on U-Boot 1.3.4 from Samsung. + * + * 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 +#include +#include + +#define MPLL 0 +#define EPLL 1 + +/* ------------------------------------------------------------------------- */ +/* + * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL. + * + * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of + * the specified bus in HZ. + */ +/* ------------------------------------------------------------------------- */ + +static ulong get_PLLCLK(int pllreg) +{ + s3c2416_sysctl *const sysctl = s3c2416_get_base_sysctl(); + u32 pllcon; + u16 mdiv, pdiv, sdiv; + + if (pllreg == MPLL) + pllcon = readl(&sysctl->mpllcon); + else if (pllreg == EPLL) + pllcon = readl(&sysctl->epllcon); + else + hang(); + + mdiv = (pllcon >> 14) & 0x3FF; + pdiv = (pllcon >> 5) & 0x3F; + sdiv = pllcon & 0x7; + + return mdiv * (CONFIG_SYS_CLK_FREQ / (pdiv << sdiv)); +} + +/* return FCLK frequency */ +ulong get_FCLK(void) +{ + return get_PLLCLK(MPLL); +} + +/* return HCLK frequency */ +ulong get_HCLK(void) +{ + s3c2416_sysctl *const sysctl = s3c2416_get_base_sysctl(); + u32 clkdiv0; + u16 hclk_div, pre_div; + + clkdiv0 = readl(&sysctl->clkdiv0); + hclk_div = (clkdiv0 & 0x3) + 1; + pre_div = ((clkdiv0 >> 4) & 0x3) + 1; + + return get_FCLK() / (hclk_div * pre_div); +} + +/* return PCLK frequency */ +ulong get_PCLK(void) +{ + s3c2416_sysctl *const sysctl = s3c2416_get_base_sysctl(); + u32 clkdiv0; + + clkdiv0 = readl(&sysctl->clkdiv0); + + return (clkdiv0 & 0x4) ? get_HCLK() / 2 : get_HCLK(); +} + +/* return UCLK frequency */ +ulong get_UCLK(void) +{ + return get_PLLCLK(EPLL); +} + +/* return ARMCORE frequency */ +ulong get_ARMCLK(void) +{ + s3c2416_sysctl *const sysctl = s3c2416_get_base_sysctl(); + u32 clkdiv0; + u16 arm_div; + + clkdiv0 = readl(&sysctl->clkdiv0); + if (clkdiv0 & 0x2000) + return get_FCLK(); + + arm_div = ((clkdiv0 >> 9) & 0x7) + 1; + + return get_FCLK() / arm_div; +} diff --git a/arch/arm/cpu/arm926ejs/s3c24xx/timer.c b/arch/arm/cpu/arm926ejs/s3c24xx/timer.c new file mode 100644 index 0000000..1ffe169 --- /dev/null +++ b/arch/arm/cpu/arm926ejs/s3c24xx/timer.c @@ -0,0 +1,159 @@ +/* + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * Based on arch/arm/cpu/armv7/s5p-common/timer.c and U-Boot 1.3.4 from Samsung. + * + * 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 +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static ulong get_current_tick(void) +{ + s3c24xx_timers *const timers = s3c24xx_get_base_timers(); + ulong now = readl(&timers->tcnto4); + + if (gd->lastinc >= now) + gd->tbl += gd->lastinc - now; + else + gd->tbl += gd->lastinc + gd->tbu - now; + + gd->lastinc = now; + + return gd->tbl; +} + +int timer_init(void) +{ + s3c24xx_timers *const timers = s3c24xx_get_base_timers(); + ulong tmr; + + /* use PWM Timer 4 because it has no output */ + if (gd->tbu == 0) { + /* set divider value for Timer 4 to 2 */ + tmr = readl(&timers->tcfg1); + tmr &= ~(0xf << 16); + writel(tmr, &timers->tcfg1); + /* set prescaler value for Timer 4 to 15 */ + tmr = readl(&timers->tcfg0); + tmr &= ~(0xff << 8); + tmr |= (15 << 8); + writel(tmr, &timers->tcfg0); + /* + * Timer Freq(HZ) = + * PCLK / (prescaler_value + 1) / (divider_value) + */ + gd->timer_rate_hz = get_PCLK() / (15 + 1) / 2; + gd->tbu = gd->timer_rate_hz / CONFIG_SYS_HZ; + } + /* load value for selected timeout */ + writel(gd->tbu, &timers->tcntb4); + /* auto load, manual update of timer 4 */ + tmr = readl(&timers->tcon); + tmr &= ~(0x7 << 20); + tmr |= (0x6 << 20); + writel(tmr, &timers->tcon); + /* auto load, start timer 4 */ + tmr &= ~(0x7 << 20); + tmr |= (0x5 << 20); + writel(tmr, &timers->tcon); + gd->lastinc = 0; + gd->tbl = 0; + + return 0; +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void __udelay(unsigned long usec) +{ + ulong 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 *= gd->timer_rate_hz; + tmo /= 1000; + } else { + /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * gd->timer_rate_hz; + tmo /= (1000 * 1000); + } + + /* get current timestamp */ + tmp = get_current_tick(); + + /* if setting this fordward will roll time stamp */ + /* reset "advancing" timestamp to 0, set lastinc value */ + /* else, set advancing stamp wake up time */ + if ((tmo + tmp + 1) < tmp) + reset_timer_masked(); + else + tmo += tmp; + + /* loop till event */ + while (get_current_tick() < tmo) + /* NOP */ ; +} + +void reset_timer_masked(void) +{ + s3c24xx_timers *const timers = s3c24xx_get_base_timers(); + + /* reset time */ + gd->lastinc = readl(&timers->tcnto4); + gd->tbl = 0; +} + +ulong get_timer_masked(void) +{ + return get_current_tick() / gd->tbu; +} + +/* + * 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_masked(); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/include/asm/arch-s3c24xx/s3c2412.h b/arch/arm/include/asm/arch-s3c24xx/s3c2412.h new file mode 100644 index 0000000..772e814 --- /dev/null +++ b/arch/arm/include/asm/arch-s3c24xx/s3c2412.h @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * 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 + */ + +/************************************************ + * NAME : s3c2412.h + * + * Based on S3C2412 User's manual Rev 1.06a + ************************************************/ + +#ifndef __S3C2412_H__ +#define __S3C2412_H__ + +/* Base addresses for S3C2412 specific modules */ +#define S3C2412_INTERRUPT_BASE 0x4A000000 +#define S3C2412_SYSCTL_BASE 0x4C000000 +#define S3C2412_LCD_BASE 0x4D000000 +#define S3C2412_USB_DEVICE_BASE 0x52000000 +#define S3C2412_ADC_BASE 0x58000000 +#define S3C2412_SPI_BASE 0x59000000 +#define S3C2412_SDIO_BASE 0x5A000000 + +#define S3C24XX_UART_CHANNELS 3 +#define S3C24XX_DMA_CHANNELS 4 +#define S3C24XX_SMC_BANKS 8 + +#ifdef CONFIG_S3C2412 +#define S3C24XX_CPU_NAME "S3C2412" +#else +#define S3C24XX_CPU_NAME "S3C2413" +#endif + +enum s3c24xx_uarts_nr { + S3C24XX_UART0, + S3C24XX_UART1, + S3C24XX_UART2 +}; + +enum s3c24xx_dmas_nr { + S3C24XX_DMA0, + S3C24XX_DMA1, + S3C24XX_DMA2, + S3C24XX_DMA3 +}; + +enum s3c24xx_smcs_nr { + S3C24XX_SMC0, + S3C24XX_SMC1, + S3C24XX_SMC2, + S3C24XX_SMC3, + S3C24XX_SMC4, + S3C24XX_SMC5, + S3C24XX_SMC6, + S3C24XX_SMC7 +}; + +/* Interrupt Controller */ +typedef struct { + u32 srcpnd; + u32 intmod; + u32 intmsk; + u32 priority; + u32 intpnd; + u32 intoffset; + u32 subsrcpnd; + u32 intsubmsk; +} volatile s3c2412_interrupt; + +/* System Controller */ +typedef struct { + u32 locktime; + u32 mpllcon; + u32 upllcon; + u32 clkcon; + u32 _res1[1]; + u32 clkdivn; + u32 oscset; + u32 clksrc; + u32 _res2[1]; + u32 pwrcfg; + u32 _res3[2]; + u32 swrstcon; + u32 rstcon; + u32 _res4[13]; + u32 inform[4]; +} volatile s3c2412_sysctl; + +static inline s3c2412_interrupt *s3c2412_get_base_interrupt(void) +{ + return (s3c2412_interrupt *) S3C2412_INTERRUPT_BASE; +} + +static inline s3c2412_sysctl *s3c2412_get_base_sysctl(void) +{ + return (s3c2412_sysctl *) S3C2412_SYSCTL_BASE; +} + +/* Include common stuff */ +#include + +#endif /*__S3C2412_H__*/ diff --git a/arch/arm/include/asm/arch-s3c24xx/s3c2416.h b/arch/arm/include/asm/arch-s3c24xx/s3c2416.h new file mode 100644 index 0000000..42f4ad6 --- /dev/null +++ b/arch/arm/include/asm/arch-s3c24xx/s3c2416.h @@ -0,0 +1,149 @@ +/* + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * 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 + */ + +/************************************************ + * NAME : s3c2416.h + * + * Based on S3C2416 User's manual Rev 1.40 + ************************************************/ + +#ifndef __S3C2416_H__ +#define __S3C2416_H__ + +/* Base addresses for S3C2416 specific modules */ +#define S3C2416_USB_DEVICE_BASE 0x49800000 +#define S3C2416_INTERRUPT_BASE 0x4A000000 +#define S3C2416_HSMMC_BASE 0x4A800000 +#define S3C2416_SYSCTL_BASE 0x4C000000 +#define S3C2416_LCD_BASE 0x4C800000 +#define S3C2416_HSSPI_BASE 0x52000000 +#define S3C2416_ADC_BASE 0x58000000 + +#define S3C24XX_UART_CHANNELS 4 +#define S3C24XX_DMA_CHANNELS 6 +#define S3C24XX_SMC_BANKS 6 + +#ifdef CONFIG_S3C2416 +#define S3C24XX_CPU_NAME "S3C2416" +#else +#define S3C24XX_CPU_NAME "S3C2450" +#endif + +enum s3c24xx_uarts_nr { + S3C24XX_UART0, + S3C24XX_UART1, + S3C24XX_UART2, + S3C24XX_UART3 +}; + +enum s3c24xx_dmas_nr { + S3C24XX_DMA0, + S3C24XX_DMA1, + S3C24XX_DMA2, + S3C24XX_DMA3, + S3C24XX_DMA4, + S3C24XX_DMA5 +}; + +enum s3c24xx_smcs_nr { + S3C24XX_SMC0, + S3C24XX_SMC1, + S3C24XX_SMC2, + S3C24XX_SMC3, + S3C24XX_SMC4, + S3C24XX_SMC5 +}; + +/* Interrupt Controller */ +typedef struct { + u32 srcpnd1; + u32 intmod1; + u32 intmsk1; + u32 _res1[1]; + u32 intpnd1; + u32 intoffset1; + u32 subsrcpnd; + u32 intsubmsk; + u32 _res2[4]; + u32 priority_mode1; + u32 priority_update1; + u32 _res3[2]; + u32 srcpnd2; + u32 intmod2; + u32 intmsk2; + u32 _res4[1]; + u32 intpnd2; + u32 intoffset2; + u32 _res5[6]; + u32 priority_mode2; + u32 priority_update2; +} volatile s3c2416_interrupt; + +/* System Controller */ +typedef struct { + u32 lockcon0; + u32 lockcon1; + u32 oscset; + u32 _res1[1]; + u32 mpllcon; + u32 _res2[1]; + u32 epllcon; + u32 epllcon_k; + u32 clksrc; + u32 clkdiv0; + u32 clkdiv1; + u32 clkdiv2; + u32 hclkcon; + u32 pclkcon; + u32 sclkcon; + u32 _res3[1]; + u32 pwrmode; + u32 swrst; + u32 _res4[2]; + u32 busprio; + u32 _res5[3]; + u32 pwrcfg; + u32 rstcon; + u32 rststat; + u32 wkupstat; + u32 inform[4]; + u32 uphyctrl; + u32 uphypwr; + u32 urstcon; + u32 uclkcon; +} volatile s3c2416_sysctl; + +static inline s3c2416_interrupt *s3c2416_get_base_interrupt(void) +{ + return (s3c2416_interrupt *) S3C2416_INTERRUPT_BASE; +} + +static inline s3c2416_sysctl *s3c2416_get_base_sysctl(void) +{ + return (s3c2416_sysctl *) S3C2416_SYSCTL_BASE; +} + +/* Include common stuff */ +#include + +#endif /*__S3C2416_H__*/ diff --git a/arch/arm/include/asm/arch-s3c24xx/s3c24xx.h b/arch/arm/include/asm/arch-s3c24xx/s3c24xx.h new file mode 100644 index 0000000..edcdb8a --- /dev/null +++ b/arch/arm/include/asm/arch-s3c24xx/s3c24xx.h @@ -0,0 +1,503 @@ +/* + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * 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 + */ + +/****************************************************** + * NAME : s3c24xx.h + * + * Common stuff for SAMSUNG S3C24XX SoC (ARM926EJ core) + ******************************************************/ + +#ifndef __S3C24XX_H__ +#define __S3C24XX_H__ + +/* Base addresses for S3C24XX common modules */ +#define S3C24XX_DRAMCTL_BASE 0x48000000 +#define S3C24XX_USB_HOST_BASE 0x49000000 +#define S3C24XX_DMA_BASE 0x4B000000 +#define S3C24XX_NAND_BASE 0x4E000000 +#define S3C24XX_SMC_BASE 0x4F000000 +#define S3C24XX_UART_BASE 0x50000000 +#define S3C24XX_TIMER_BASE 0x51000000 +#define S3C24XX_WATCHDOG_BASE 0x53000000 +#define S3C24XX_I2C_BASE 0x54000000 +#define S3C24XX_I2S_BASE 0x55000000 +#define S3C24XX_GPIO_BASE 0x56000000 +#define S3C24XX_RTC_BASE 0x57000000 +#define S3C24XX_ADC_BASE 0x58000000 + +/* Mobile DRAM Controller */ +typedef struct { + u32 bankcfg; + u32 bankcon1; + u32 bankcon2; + u32 bankcon3; + u32 refresh; + u32 timeout; +} volatile s3c24xx_dramctl; + +/* USB Host Controller */ +typedef struct { + u32 HcRevision; + u32 HcControl; + u32 HcCommonStatus; + u32 HcInterruptStatus; + u32 HcInterruptEnable; + u32 HcInterruptDisable; + u32 HcHCCA; + u32 HcPeriodCuttendED; + u32 HcControlHeadED; + u32 HcControlCurrentED; + u32 HcBulkHeadED; + u32 HcBuldCurrentED; + u32 HcDoneHead; + u32 HcRmInterval; + u32 HcFmRemaining; + u32 HcFmNumber; + u32 HcPeriodicStart; + u32 HcLSThreshold; + u32 HcRhDescriptorA; + u32 HcRhDescriptorB; + u32 HcRhStatus; + u32 HcRhPortStatus1; + u32 HcRhPortStatus2; +} volatile s3c24xx_usb_host; + +/* DMA Controller */ +typedef struct { + u32 disrc; + u32 disrcc; + u32 didst; + u32 didstc; + u32 dcon; + u32 dstat; + u32 dcsrc; + u32 dcdst; + u32 dmasktrig; + u32 dmareqsel0; +} volatile s3c24xx_dma; + +/* NAND Flash Controller */ +typedef struct { + u32 nfconf; + u32 nfcont; + u32 nfcmmd; + u32 nfaddr; + u32 nfdata; + u32 nfmeccd[2]; + u32 nfseccd; + u32 nfsblk; + u32 nfeblk; + u32 nfstat; + u32 nfeccerr[2]; + u32 nfmecc[2]; + u32 nfsecc; + u32 nfmlcbitpt; +#if !(defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413)) + u32 nf8eccerr[3]; + u32 nfm8ecc[4]; + u32 nfmlc8bitpt[2]; +#endif +} volatile s3c24xx_nand; + +/* SMC */ +typedef struct { + u32 smbidcy; + u32 smbwstrd; + u32 smbwstwr; + u32 smbwstoen; + u32 smbwstwen; + u32 smbc; + u32 smbs; + u32 smbwstbrd; +} volatile s3c24xx_smc; + +/* UART */ +typedef struct { + u32 ulcon; + u32 ucon; + u32 ufcon; + u32 umcon; + u32 utrstat; + u32 uerstat; + u32 ufstat; + u32 umstat; +#ifdef __BIG_ENDIAN + u8 _res1[3]; + u8 utxh; + u8 _res2[3]; + u8 urxh; +#else /* Little Endian */ + u8 utxh; + u8 _res1[3]; + u8 urxh; + u8 _res2[3]; +#endif + u32 ubrdiv; + u32 udivslot; +} volatile s3c24xx_uart; + +/* PWM Timer */ +typedef struct { + u32 tcntb; + u32 tcmpb; + u32 tcnto; +} s3c24xx_timer; + +typedef struct { + u32 tcfg0; + u32 tcfg1; + u32 tcon; + s3c24xx_timer ch[4]; + u32 tcntb4; + u32 tcnto4; +} volatile s3c24xx_timers; + +/* Watchdog Timer */ +typedef struct { + u32 wtcon; + u32 wtdat; + u32 wtcnt; +} volatile s3c24xx_watchdog; + +/* IIC-Bus Interface */ +typedef struct { + u32 iiccon; + u32 iicstat; + u32 iicadd; + u32 iicds; + u32 iiclc; +} volatile s3c24xx_i2c; + +/* IIS-Bus Interface */ +typedef struct { + u32 iiscon; + u32 iismod; + u32 iisfic; + u32 iispsr; + u32 iistxd; + u32 iisrxd; +} volatile s3c24xx_i2s; + +/* I/O Ports */ +typedef struct { +#if defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413) + u32 gpacon; + u32 gpadat; + u32 _res1[2]; + u32 gpbcon; + u32 gpbdat; + u32 gpbdn; + u32 gpbslpcon; + u32 gpccon; + u32 gpcdat; + u32 gpcdn; + u32 gpcslpcon; + u32 gpdcon; + u32 gpddat; + u32 gpddn; + u32 gpdslpcon; + u32 gpecon; + u32 gpedat; + u32 gpedn; + u32 gpeslpcon; + u32 gpfcon; + u32 gpfdat; + u32 gpfdn; + u32 _res2; + u32 gpgcon; + u32 gpgdat; + u32 gpgdn; + u32 gpgslpcon; + u32 gphcon; + u32 gphdat; + u32 gphdn; + u32 gphslpcon; + u32 gpjcon; + u32 gpjdat; + u32 gpjdn; + u32 gpjslpcon; + + u32 misccr; + u32 dclkcon; + u32 extint[3]; + u32 eintflt[4]; + u32 eintmask; + u32 eintpend; + u32 gstatus[6]; + u32 mstcon; + u32 mslcon; + u32 dsc[2]; +#else + u32 gpacon; + u32 gpadat; + u32 _res1[2]; + u32 gpbcon; + u32 gpbdat; + u32 gpbudp; + u32 gpbsel; + u32 gpccon; + u32 gpcdat; + u32 gpcudp; + u32 _res2; + u32 gpdcon; + u32 gpddat; + u32 gpdudp; + u32 _res3; + u32 gpecon; + u32 gpedat; + u32 gpeudp; + u32 gpesel; + u32 gpfcon; + u32 gpfdat; + u32 gpfudp; + u32 _res4; + u32 gpgcon; + u32 gpgdat; + u32 gpgudp; + u32 _res5; + u32 gphcon; + u32 gphdat; + u32 gphudp; + u32 _res6; + + u32 misccr; + u32 dclkcon; + u32 extint[3]; + u32 _res7[2]; + u32 eintflt2; + u32 eintflt3; + u32 eintmask; + u32 eintpend; + u32 gstatus[2]; + u32 _res8[3]; + u32 dsc[4]; + + u32 gpjcon; + u32 gpjdat; + u32 gpjudp; + u32 gpjsel; + u32 gpkcon; + u32 gpkdat; + u32 gpkudp; + u32 _res9; + u32 gplcon; + u32 gpldat; + u32 gpludp; + u32 gplsel; + u32 gpmcon; + u32 gpmdat; + u32 gpmudp; + u32 _res10; + + u32 dsc3; + u32 pddmcon; + u32 pdsmcon; +#endif +} volatile s3c24xx_gpio; + +/* RTC */ +typedef struct { +#ifdef __BIG_ENDIAN + u8 _res1[67]; + u8 rtccon; + u8 _res2[3]; + u8 ticnt0; +#if defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413) + u8 _res3[4]; +#else + u8 _res3[3]; + u8 ticnt2; +#endif + u8 _res4[3]; + u8 ticnt1; + u8 _res5[3]; + u8 rtcalm; + u8 _res6[3]; + u8 almsec; + u8 _res7[3]; + u8 almmin; + u8 _res8[3]; + u8 almhour; + u8 _res9[3]; + u8 almdate; + u8 _res10[3]; + u8 almmon; + u8 _res11[3]; + u8 almyear; + u8 _res12[7]; + u8 bcdsec; + u8 _res13[3]; + u8 bcdmin; + u8 _res14[3]; + u8 bcdhour; + u8 _res15[3]; + u8 bcddate; + u8 _res16[3]; + u8 bcdday; + u8 _res17[3]; + u8 bcdmon; + u8 _res18[3]; + u8 bcdyear; +#if !(defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413)) + u8 _res19[3]; + u8 tickcnt; +#endif +#else /* little endian */ + u8 _res0[64]; + u8 rtccon; + u8 _res1[3]; + u8 ticnt0; + u8 _res2[3]; +#if defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413) + u8 _res3[4]; +#else + u8 ticnt2; + u8 _res3[3]; +#endif + u8 ticnt1; + u8 _res4[3]; + u8 rtcalm; + u8 _res5[3]; + u8 almsec; + u8 _res6[3]; + u8 almmin; + u8 _res7[3]; + u8 almhour; + u8 _res8[3]; + u8 almdate; + u8 _res9[3]; + u8 almmon; + u8 _res10[3]; + u8 almyear; + u8 _res11[7]; + u8 bcdsec; + u8 _res12[3]; + u8 bcdmin; + u8 _res13[3]; + u8 bcdhour; + u8 _res14[3]; + u8 bcddate; + u8 _res15[3]; + u8 bcdday; + u8 _res16[3]; + u8 bcdmon; + u8 _res17[3]; + u8 bcdyear; + u8 _res18[3]; +#if !(defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413)) + u8 tickcnt; + u8 _res19[3]; +#endif +#endif +} volatile s3c24xx_rtc; + +/* ADC & Touch Screen Interface */ +typedef struct { + u32 adccon; + u32 adctsc; + u32 adcdly; + u32 adcdat0; + u32 adcdat1; +#if !(defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413)) + u32 adcupdn; + u32 adcmux; +#endif +} volatile s3c24xx_adc; + +static inline s3c24xx_dramctl *s3c24xx_get_base_dramctl(void) +{ + return (s3c24xx_dramctl *) S3C24XX_DRAMCTL_BASE; +} + +static inline s3c24xx_usb_host *s3c24xx_get_base_usb_host(void) +{ + return (s3c24xx_usb_host *) S3C24XX_USB_HOST_BASE; +} + +static inline s3c24xx_dma *s3c24xx_get_base_dma(enum s3c24xx_dmas_nr n) +{ +#if defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413) + return (s3c24xx_dma *) (S3C24XX_DMA_BASE + (n * 0x40)); +#else + return (s3c24xx_dma *) (S3C24XX_DMA_BASE + (n * 0x100)); +#endif +} + +static inline s3c24xx_nand *s3c24xx_get_base_nand(void) +{ + return (s3c24xx_nand *) S3C24XX_NAND_BASE; +} + +static inline s3c24xx_smc *s3c24xx_get_base_smc(enum s3c24xx_smcs_nr n) +{ + return (s3c24xx_smc *) (S3C24XX_SMC_BASE + (n * 0x20)); +} + +static inline s3c24xx_uart *s3c24xx_get_base_uart(enum s3c24xx_uarts_nr n) +{ + return (s3c24xx_uart *) (S3C24XX_UART_BASE + (n * 0x4000)); +} + +static inline s3c24xx_timers *s3c24xx_get_base_timers(void) +{ + return (s3c24xx_timers *) S3C24XX_TIMER_BASE; +} + +static inline s3c24xx_watchdog *s3c24xx_get_base_watchdog(void) +{ + return (s3c24xx_watchdog *) S3C24XX_WATCHDOG_BASE; +} + +static inline s3c24xx_i2c *s3c24xx_get_base_i2c(void) +{ + return (s3c24xx_i2c *) S3C24XX_I2C_BASE; +} + +static inline s3c24xx_i2s *s3c24xx_get_base_i2s(void) +{ + return (s3c24xx_i2s *) S3C24XX_I2S_BASE; +} + +static inline s3c24xx_gpio *s3c24xx_get_base_gpio(void) +{ + return (s3c24xx_gpio *) S3C24XX_GPIO_BASE; +} + +static inline s3c24xx_rtc *s3c24xx_get_base_rtc(void) +{ + return (s3c24xx_rtc *) S3C24XX_RTC_BASE; +} + +static inline s3c24xx_adc *s3c24xx_get_base_adc(void) +{ + return (s3c24xx_adc *) S3C24XX_ADC_BASE; +} + +static inline char *s3c24xx_get_cpu_name(void) +{ + return S3C24XX_CPU_NAME; +} + +extern ulong get_ARMCLK(void); + +#endif /*__S3C24XX_H__*/ diff --git a/arch/arm/include/asm/arch-s3c24xx/s3c24xx_cpu.h b/arch/arm/include/asm/arch-s3c24xx/s3c24xx_cpu.h new file mode 100644 index 0000000..59ccfd4 --- /dev/null +++ b/arch/arm/include/asm/arch-s3c24xx/s3c24xx_cpu.h @@ -0,0 +1,30 @@ +/* + * (C) Copyright 2012 INOV - INESC Inovacao + * Jose Goncalves + * + * 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 + */ + +#if defined(CONFIG_S3C2412) || defined(CONFIG_S3C2413) +#include +#elif defined(CONFIG_S3C2416) || defined(CONFIG_S3C2450) +#include +#else +#error Please define the S3C24XX SoC type +#endif diff --git a/include/common.h b/include/common.h index 55025c0..36f0636 100644 --- a/include/common.h +++ b/include/common.h @@ -628,6 +628,7 @@ ulong get_OPB_freq (void); ulong get_PCI_freq (void); #endif #if defined(CONFIG_S3C24X0) || \ + defined(CONFIG_S3C24XX) || \ defined(CONFIG_LH7A40X) || \ defined(CONFIG_S3C6400) || \ defined(CONFIG_EP93XX)