[U-Boot-Users] [PATCH 3/7 v6] ARM: Add arm1176 core with S3C6400 SoC
Jean-Christophe PLAGNIOL-VILLARD
plagnioj at jcrosoft.com
Sat Aug 9 11:11:01 CEST 2008
> +
> +void dcache_disable (void)
> +{
> + ulong reg;
> +
> + reg = read_p15_c1 ();
> + cp_delay ();
> + reg &= ~C1_DC;
> + write_p15_c1 (reg);
why not as the other implementation?
> + write_p15_c1 (reg & ~C1_DC);
> +}
> +
> +int dcache_status (void)
> +{
> + return (read_p15_c1 () & C1_DC) != 0;
> +}
> +
> +/* flush I/D-cache */
> +static void cache_flush (void)
> +{
> + /* invalidate both caches and flush btb */
> + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0));
> + /* mem barrier to sync things */
> + asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0));
> +}
> + * The timer is set to wrap after 100s, at 66MHz this obviously
> + * happens after 10,000,000 ticks. A long variable can thus
> + * keep values up to 40,000s, i.e., 11 hours. This should be
> + * enough for most uses:-) Possible optimizations: select a
> + * binary-friendly frequency, e.g., 1ms / 128. Also calculate
> + * the prescaler automatically for other PCLK frequencies.
> + */
> + /* Set timer frequency to 500KHz, at 66MHz we get prescaler=132 < 255 */
> + timers->TCFG0 = PRESCALER << 8;
> + if (timer_load_val == 0) {
> + /*
> + * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 and
> + * prescaler = 16. Should be 10390 @33.25MHz and 15625 @ 50 MHz
> + */
> + timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */
> + /*printf("Calculated %lu timer_load_val\n", timer_load_val);*/
please remove if not need
> + timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000;
> + }
> +
please add some empty line to be more readable
> + /* load value for 10 ms timeout */
> + lastdec = timers->TCNTB4 = timer_load_val;
> + /* auto load, manual update of Timer 4 */
> + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO |
> + TCON_4_UPDATE;
> + /* auto load, start Timer 4 */
> + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON;
> + timestamp = 0;
> +
> + return 0;
> +}
> +
> +/*
> + * timer without interrupts
> + */
> +
> +/*
> + * 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)
> +{
> + ulong now = read_timer();
> +
> + if (lastdec >= now) {
> + /* normal mode */
> +#define MPLL 1
> +#define EPLL 2
> +
> +/* ------------------------------------------------------------------------- */
> +/*
> + * NOTE: This describes the proper use of this file.
> + *
> + * 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)
please not uppercase
> +{
> + ulong r, m, p, s;
> +
> + if (pllreg == APLL)
> + r = APLL_CON_REG;
> + else if (pllreg == MPLL)
> + r = MPLL_CON_REG;
> + else if (pllreg == EPLL)
> + r = EPLL_CON0_REG;
> + else
> + hang();
please move to switch implementation
> +
> + m = (r >> 16) & 0x3ff;
> + p = (r >> 8) & 0x3f;
> + s = r & 0x7;
> +
> + return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s)));
> +}
> +
> +/* return ARMCORE frequency */
> +ulong get_ARMCLK(void)
please not uppercase
> +{
> + ulong div;
> +
> + div = CLK_DIV0_REG;
> +
> + return get_PLLCLK(APLL) / ((div & 0x7) + 1);
> +}
> +
> +/* return FCLK frequency */
> +ulong get_FCLK(void)
please not uppercase
> +{
> + return get_PLLCLK(APLL);
> +}
> +
> +/* return HCLK frequency */
> +ulong get_HCLK(void)
please not uppercase
> +{
> + ulong fclk;
> +
> + uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
> + uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1;
> +
> + /*
> + * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on
> + * s3c6400 and is always 0, and it is indeed running in ASYNC mode
> + */
> + if (OTHERS_REG & 0x80)
> + fclk = get_FCLK(); /* SYNC Mode */
> + else
> + fclk = get_PLLCLK(MPLL); /* ASYNC Mode */
> +
> + return fclk / (hclk_div * hclkx2_div);
> +}
> +
> +/* return PCLK frequency */
> +ulong get_PCLK(void)
please not uppercase
> +{
> + ulong fclk;
> + uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
> + uint pre_div = ((CLK_DIV0_REG >> 12) & 0xf) + 1;
> +
> + if (OTHERS_REG & 0x80)
> + fclk = get_FCLK(); /* SYNC Mode */
> + else
> + fclk = get_PLLCLK(MPLL); /* ASYNC Mode */
> +
> + return fclk / (hclkx2_div * pre_div);
> +}
> +
> +/* return UCLK frequency */
> +ulong get_UCLK(void)
please not uppercase
> +{
> + return get_PLLCLK(EPLL);
> +}
> +
> +int print_cpuinfo(void)
> +{
> + printf("\nCPU: S3C6400@%luMHz\n", get_ARMCLK() / 1000000);
> + printf(" Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ",
> + get_FCLK() / 1000000, get_HCLK() / 1000000,
> + get_PCLK() / 1000000);
maybe a macro like HZ_TO_MHZ(x) could be helpfull to avoid typo
> +
> + if (OTHERS_REG & 0x80)
> + printf("(SYNC Mode) \n");
> + else
> + printf("(ASYNC Mode) \n");
> + return 0;
> +}
> diff --git a/cpu/arm1176/start.S b/cpu/arm1176/start.S
> new file mode 100644
> index 0000000..00cc186
> --- /dev/null
> +++ b/cpu/arm1176/start.S
> @@ -0,0 +1,469 @@
> +/*
> + * armboot - Startup Code for S3C6400/ARM1176 CPU-core
> + *
> + * Copyright (c) 2007 Samsung Electronics
> + *
> + * Copyright (C) 2008
> + * Guennadi Liakhovetki, DENX Software Engineering, <lg at 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
> + *
> + * 2007-09-21 - Restructured codes by jsgood (jsgood.yang at samsung.com)
> + * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
> + * jsgood (jsgood.yang at samsung.com)
> + * Base codes by scsuh (sc.suh)
> + */
> +
> +#include <config.h>
> +#include <version.h>
> +#ifdef CONFIG_ENABLE_MMU
> +#include <asm/proc/domain.h>
> +#endif
> +#include <s3c6400.h>
> +
> +#if !defined(CONFIG_ENABLE_MMU) && !defined(CFG_PHY_UBOOT_BASE)
> +#define CFG_PHY_UBOOT_BASE CFG_UBOOT_BASE
> +#endif
> +
> +.globl _armboot_start
> +_armboot_start:
> + .word _start
> +
> +/*
> + * These are defined in the board-specific linker script.
> + */
> +.globl _bss_start
> +_bss_start:
> + .word __bss_start
> +
> +.globl _bss_end
> +_bss_end:
> + .word _end
> +
> +/*
> + * the actual reset code
> + */
> +
> +reset:
> + /*
> + * set the cpu to SVC32 mode
> + */
please add space between parameter
> + mrs r0,cpsr
> + bic r0,r0,#0x3f
> + orr r0,r0,#0xd3
> + msr cpsr,r0
> +
> +/*
> + *************************************************************************
> + *
> + * CPU_init_critical registers
> + *
> + * setup important registers
> + * setup memory timing
> + *
> + *************************************************************************
> + */
> + /*
> + * we do sys-critical inits only at reboot,
> + * not when booting from ram!
> + */
> diff --git a/include/common.h b/include/common.h
> index 06ed278..ba87322 100644
> --- a/include/common.h
> +++ b/include/common.h
> @@ -491,7 +491,8 @@ int prt_mpc8220_clks (void);
> ulong get_OPB_freq (void);
> ulong get_PCI_freq (void);
> #endif
> -#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X)
> +#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
> + defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400)
Is it possible to have a better and simpler ifdef?
> void s3c2410_irq(void);
> #define ARM920_IRQ_CALLBACK s3c2410_irq
> ulong get_FCLK (void);
> diff --git a/include/s3c6400.h b/include/s3c6400.h
> new file mode 100644
> index 0000000..8814747
> --- /dev/null
> +#define NFCONF (ELFIN_NAND_BASE+NFCONF_OFFSET)
> +#define NFCONT (ELFIN_NAND_BASE+NFCONT_OFFSET)
> +#define NFCMMD (ELFIN_NAND_BASE+NFCMMD_OFFSET)
> +#define NFADDR (ELFIN_NAND_BASE+NFADDR_OFFSET)
^^^^^^^^^^^
please remove whitesapce
> +#define NFDATA (ELFIN_NAND_BASE+NFDATA_OFFSET)
Ditto
> +#define NFMECCDATA0 (ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
Ditto
> +#define NFMECCDATA1 (ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
Ditto
> +#define NFSECCDATA0 (ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
Ditto
> +#define NFSBLK (ELFIN_NAND_BASE+NFSBLK_OFFSET)
Ditto
> +#define NFEBLK (ELFIN_NAND_BASE+NFEBLK_OFFSET)
Ditto
> +#define NFSTAT (ELFIN_NAND_BASE+NFSTAT_OFFSET)
Ditto
> +#define NFESTAT0 (ELFIN_NAND_BASE+NFESTAT0_OFFSET)
Ditto
> +#define NFESTAT1 (ELFIN_NAND_BASE+NFESTAT1_OFFSET)
Ditto
> +#define NFMECC0 (ELFIN_NAND_BASE+NFMECC0_OFFSET)
Ditto
> +#define NFMECC1 (ELFIN_NAND_BASE+NFMECC1_OFFSET)
Ditto
> +#define NFSECC (ELFIN_NAND_BASE+NFSECC_OFFSET)
Ditto
> +#define NFMLCBITPT (ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
Ditto
> +
> +#define NFCONF_REG __REG(ELFIN_NAND_BASE+NFCONF_OFFSET)
> +#define NFCONT_REG __REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
> +#define NFCMD_REG __REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
> +#define NFADDR_REG __REG(ELFIN_NAND_BASE+NFADDR_OFFSET)
Ditto
> +#define NFDATA_REG __REG(ELFIN_NAND_BASE+NFDATA_OFFSET)
Ditto
> +#define NFDATA8_REG __REGb(ELFIN_NAND_BASE+NFDATA_OFFSET)
Ditto
> +#define NFMECCDATA0_REG __REG(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
Ditto
> +#define NFMECCDATA1_REG __REG(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
Ditto
> +#define NFSECCDATA0_REG __REG(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
Ditto
> +#define NFSBLK_REG __REG(ELFIN_NAND_BASE+NFSBLK_OFFSET)
Ditto
> +#define NFEBLK_REG __REG(ELFIN_NAND_BASE+NFEBLK_OFFSET)
Ditto
> +#define NFSTAT_REG __REG(ELFIN_NAND_BASE+NFSTAT_OFFSET)
Ditto
> +#define NFESTAT0_REG __REG(ELFIN_NAND_BASE+NFESTAT0_OFFSET)
Ditto
> +#define NFESTAT1_REG __REG(ELFIN_NAND_BASE+NFESTAT1_OFFSET)
Ditto
> +#define NFMECC0_REG __REG(ELFIN_NAND_BASE+NFMECC0_OFFSET)
Ditto
> +#define NFMECC1_REG __REG(ELFIN_NAND_BASE+NFMECC1_OFFSET)
Ditto
> +#define NFSECC_REG __REG(ELFIN_NAND_BASE+NFSECC_OFFSET)
Ditto
> +#define NFMLCBITPT_REG __REG(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
Ditto
> +
btw on all macro please add space beetwen operator like
> +#define NFCONF_REG __REG(ELFIN_NAND_BASE+NFCONF_OFFSET)
to
#define NFCONF_REG __REG(ELFIN_NAND_BASE + NFCONF_OFFSET)
> +#define TIMER3_MANUP (TCON_3_MAN*1)
> +#define TIMER3_NOP (FClrBit(TCON, TCON_3_MAN))
> +#define TCON_3_ONOFF (1 << 16) /* 0: Stop, 1: start Timer 3 */
> +#define TIMER3_ON (TCON_3_ONOFF * 1)
> +#define TIMER3_OFF (FClrBit(TCON, TCON_3_ONOFF))
> +
> +#if defined(CONFIG_CLK_400_100_50)
> +#define Startup_AMDIV 400
for macro I'll prefer upercase
> +#define Startup_MDIV 400
> +#define Startup_PDIV 6
> +#define Startup_SDIV 1
> +
> +
> +/*-----------------------------------------------------------------------
> + * Physical Memory Map
> + */
> +#define DMC1_MEM_CFG 0x80010012 /* Chip1, Burst4, Row/Column bit */
> +#define DMC1_MEM_CFG2 0xB45
> +#define DMC1_CHIP0_CFG 0x150F8 /* 0x4000_0000 ~ 0x43ff_ffff (64MB) */
> +#define DMC_DDR_32_CFG 0x0 /* 32bit, DDR */
^
whitespace please remove
> +
> +/* Memory Parameters */
> +/* DDR Parameters */
> +#define DDR_tREFRESH 7800 /* ns */
> +#define DDR_tRAS 45 /* ns (min: 45ns)*/
> +#define DDR_tRC 68 /* ns (min: 67.5ns)*/
^
whitespace please remove
> +#define DDR_tRCD 23 /* ns (min: 22.5ns)*/
> +#define DDR_tRFC 80 /* ns (min: 80ns)*/
> +#define DDR_tRP 23 /* ns (min: 22.5ns)*/
^
whitespace please remove
> +#define DDR_tRRD 15 /* ns (min: 15ns)*/
> +#define DDR_tWR 15 /* ns (min: 15ns)*/
^
whitespace please remove
> +#define DDR_tXSR 120 /* ns (min: 120ns)*/
> +#define DDR_CASL 3 /* CAS Latency 3 */
> +
> +/*
> + * mDDR memory configuration
> + */
> +#define DMC_DDR_BA_EMRS 2
^
whitespace please remove
> +#define DMC_DDR_MEM_CASLAT 3
> +/* 6 Set Cas Latency to 3 */
> +#define DMC_DDR_CAS_LATENCY (DDR_CASL << 1)
> +/* Min 0.75 ~ 1.25 */
> --- /dev/null
> +++ b/include/s3c64x0.h
> @@ -0,0 +1,92 @@
> +/*
> + * (C) Copyright 2003
> + * David MÃŒller ELSOFT AG Switzerland. d.mueller at elsoft.ch
> + *
> + * (C) Copyright 2008
> + * Guennadi Liakhovetki, DENX Software Engineering, <lg at 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
> + */
> +
> +/************************************************
> + * NAME : S3C64XX.h
> + * Version : 31.3.2003
> + *
> + * common stuff for SAMSUNG S3C64XX SoC
> + ************************************************/
> +
> +#ifndef __S3C64XX_H__
> +#define __S3C64XX_H__
> +
> +#if defined(CONFIG_SYNC_MODE) && defined(CONFIG_S3C6400)
> +#error CONFIG_SYNC_MODE unavailable on S3C6400, please, fix your configuration!
> +#endif
> +
> +typedef vu_char S3C64XX_REG8;
> +typedef vu_short S3C64XX_REG16;
> +typedef vu_long S3C64XX_REG32;
I'll prefer you use the type directly
> +
> +/* UART (see manual chapter 11) */
> +typedef struct {
> + S3C64XX_REG32 ULCON;
> + S3C64XX_REG32 UCON;
> + S3C64XX_REG32 UFCON;
> + S3C64XX_REG32 UMCON;
> + S3C64XX_REG32 UTRSTAT;
> + S3C64XX_REG32 UERSTAT;
> + S3C64XX_REG32 UFSTAT;
> + S3C64XX_REG32 UMSTAT;
> +#ifdef __BIG_ENDIAN
> + S3C64XX_REG8 res1[3];
> + S3C64XX_REG8 UTXH;
> + S3C64XX_REG8 res2[3];
> + S3C64XX_REG8 URXH;
> +#else /* Little Endian */
> + S3C64XX_REG8 UTXH;
> + S3C64XX_REG8 res1[3];
> + S3C64XX_REG8 URXH;
> + S3C64XX_REG8 res2[3];
> +#endif
> + S3C64XX_REG32 UBRDIV;
> +#ifdef __BIG_ENDIAN
> + S3C64XX_REG8 res3[2];
> + S3C64XX_REG16 UDIVSLOT;
> +#else
> + S3C64XX_REG16 UDIVSLOT;
> + S3C64XX_REG8 res3[2];
> +#endif
> +} /*__attribute__((__packed__))*/ s3c64xx_uart;
why do you remove the packed attribute?
> +
> +/* PWM TIMER (see manual chapter 10) */
> +typedef struct {
> + S3C64XX_REG32 TCNTB;
> + S3C64XX_REG32 TCMPB;
> + S3C64XX_REG32 TCNTO;
> +} /*__attribute__((__packed__))*/ s3c64xx_timer;
Ditto
> +
> +typedef struct {
> + S3C64XX_REG32 TCFG0;
> + S3C64XX_REG32 TCFG1;
> + S3C64XX_REG32 TCON;
> + s3c64xx_timer ch[4];
> + S3C64XX_REG32 TCNTB4;
> + S3C64XX_REG32 TCNTO4;
> +} /*__attribute__((__packed__))*/ s3c64xx_timers;
Ditto
> +
> +#endif /*__S3C64XX_H__*/
Best Regards,
J.
More information about the U-Boot
mailing list