[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