[U-Boot] [PATCH 06/13 v4] ARM: OMAP3: Add board, clock and interrupts common files
Jean-Christophe PLAGNIOL-VILLARD
plagnioj at jcrosoft.com
Sun Oct 26 18:07:36 CET 2008
On 21:27 Fri 17 Oct , dirk.behme at googlemail.com wrote:
> Subject: [PATCH 06/13 v4] ARM: OMAP3: Add board, clock and interrupts common files
>
> From: Dirk Behme <dirk.behme at gmail.com>
>
> Add board, clock, cpu and interrupts common files
>
> Signed-off-by: Dirk Behme <dirk.behme at gmail.com>
>
> ---
>
> Changes in version v3:
>
> - Add detection and support for 128MB/256MB RAM by Mans Rullgard
>
> Changes in version v2:
>
> - Move common ARM Cortex A8 code to cpu/arm_cortexa8/ and OMAP3 SoC specific common code to cpu/arm_cortexa8/omap3 as proposed by Wolfgang.
>
> cpu/arm_cortexa8/omap3/Makefile | 2
> cpu/arm_cortexa8/omap3/board.c | 326 ++++++++++++++++++++++++++++++++++++
> cpu/arm_cortexa8/omap3/clock.c | 305 +++++++++++++++++++++++++++++++++
> cpu/arm_cortexa8/omap3/interrupts.c | 304 +++++++++++++++++++++++++++++++++
> 4 files changed, 936 insertions(+), 1 deletion(-)
>
> Index: u-boot-arm/cpu/arm_cortexa8/omap3/Makefile
> ===================================================================
> --- u-boot-arm.orig/cpu/arm_cortexa8/omap3/Makefile
> +++ u-boot-arm/cpu/arm_cortexa8/omap3/Makefile
> @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
> LIB = lib$(SOC).a
>
> SOBJS := lowlevel_init.o
> -OBJS := sys_info.o
> +OBJS := sys_info.o board.o clock.o interrupts.o
>
> all: .depend $(LIB)
please use the current way
to allow builddir
>
> Index: u-boot-arm/cpu/arm_cortexa8/omap3/board.c
> ===================================================================
> --- /dev/null
> +++ u-boot-arm/cpu/arm_cortexa8/omap3/board.c
> @@ -0,0 +1,326 @@
> +/*
> + *
> + * Common board functions for OMAP3 based boards.
> + *
> + * (C) Copyright 2004-2008
> + * Texas Instruments, <www.ti.com>
> +
> +/******************************************************************************
> + * Dummy function to handle errors for EABI incompatibility
> + *****************************************************************************/
> +void abort(void)
> +{
> +}
> +
> +#ifdef CONFIG_NAND_OMAP_GPMC
> +/******************************************************************************
> + * OMAP3 specific command to switch between NAND HW and SW ecc
> + *****************************************************************************/
> +static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
> +{
> + if (argc != 2)
> + goto usage;
> + if (strncmp(argv[1], "hw", 2) == 0)
> + omap_nand_switch_ecc(1);
> + else if (strncmp(argv[1], "sw", 2) == 0)
> + omap_nand_switch_ecc(0);
> + else
> + goto usage;
> +
> + return 0;
> +
> +usage:
> + printf ("Usage: nandecc %s\n", cmdtp->help);
> + return 1;
> +}
> +
> +U_BOOT_CMD(
> + nandecc, 2, 1, do_switch_ecc,
> + "nandecc - switch OMAP3 NAND ECC calculation algorithm\n",
> + "[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm\n"
> + );
> +
please add a README about it
> +#endif /* CONFIG_NAND_OMAP_GPMC */
> Index: u-boot-arm/cpu/arm_cortexa8/omap3/clock.c
> ===================================================================
> --- /dev/null
> +++ u-boot-arm/cpu/arm_cortexa8/omap3/clock.c
> @@ -0,0 +1,305 @@
> +/*
> + * (C) Copyright 2008
> + * Texas Instruments, <www.ti.com>
> + *
> + * Author :
> + * Manikandan Pillai <mani.pillai at ti.com>
> + *
> + * Derived from Beagle Board and OMAP3 SDP code by
> + * Richard Woodruff <r-woodruff2 at ti.com>
> + * Syed Mohammed Khasim <khasim at ti.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
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/bits.h>
> +#include <asm/arch/clocks.h>
> +#include <asm/arch/clocks_omap3.h>
> +#include <asm/arch/mem.h>
> +#include <asm/arch/sys_proto.h>
> +#include <environment.h>
> +#include <command.h>
> +
> +/******************************************************************************
> + * get_sys_clk_speed() - determine reference oscillator speed
> + * based on known 32kHz clock and gptimer.
> + *****************************************************************************/
> +u32 get_osc_clk_speed(void)
> +{
> + u32 start, cstart, cend, cdiff, val;
> +
> + val = readl(PRM_CLKSRC_CTRL);
> +
> + /* If SYS_CLK is being divided by 2, remove for now */
> + val = (val & (~BIT7)) | BIT6;
> + writel(val, PRM_CLKSRC_CTRL);
> +
> + /* enable timer2 */
> + val = readl(CM_CLKSEL_WKUP) | BIT0;
> + writel(val, CM_CLKSEL_WKUP); /* select sys_clk for GPT1 */
> +
> + /* Enable I and F Clocks for GPT1 */
> + val = readl(CM_ICLKEN_WKUP) | BIT0 | BIT2;
> + writel(val, CM_ICLKEN_WKUP);
> + val = readl(CM_FCLKEN_WKUP) | BIT0;
> + writel(val, CM_FCLKEN_WKUP);
> +
> + writel(0, OMAP34XX_GPT1 + TLDR); /* start counting at 0 */
> + writel(GPT_EN, OMAP34XX_GPT1 + TCLR); /* enable clock */
> +
> + /* enable 32kHz source, determine sys_clk via gauging */
> + start = 20 + readl(S32K_CR); /* start time in 20 cycles */
> + while (readl(S32K_CR) < start) ; /* dead loop till start time */
> + /* get start sys_clk count */
> + cstart = readl(OMAP34XX_GPT1 + TCRR);
> + /* wait for 40 cycles */
> + while (readl(S32K_CR) < (start + 20)) ;
> + cend = readl(OMAP34XX_GPT1 + TCRR); /* get end sys_clk count */
> + cdiff = cend - cstart; /* get elapsed ticks */
> +
> + /* based on number of ticks assign speed */
> + if (cdiff > 19000)
> + return S38_4M;
> + else if (cdiff > 15200)
> + return S26M;
> + else if (cdiff > 13000)
> + return S24M;
> + else if (cdiff > 9000)
> + return S19_2M;
> + else if (cdiff > 7600)
> + return S13M;
> + else
> + return S12M;
> +}
> +
> +/******************************************************************************
> + * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on
> + * input oscillator clock frequency.
> + *****************************************************************************/
> +void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
> +{
> + if (osc_clk == S38_4M)
> + *sys_clkin_sel = 4;
> + else if (osc_clk == S26M)
> + *sys_clkin_sel = 3;
> + else if (osc_clk == S19_2M)
> + *sys_clkin_sel = 2;
> + else if (osc_clk == S13M)
> + *sys_clkin_sel = 1;
> + else if (osc_clk == S12M)
> + *sys_clkin_sel = 0;
please use switch instead
> +}
> +
> +/******************************************************************************
> + * prcm_init() - inits clocks for PRCM as defined in clocks.h
> + * called from SRAM, or Flash (using temp SRAM stack).
> + *****************************************************************************/
> +void prcm_init(void)
> +{
> + void (*f_lock_pll) (u32, u32, u32, u32);
> + int xip_safe, p0, p1, p2, p3;
> + u32 osc_clk = 0, sys_clkin_sel;
> + u32 clk_index, sil_index;
> + dpll_param *dpll_param_p;
> +
> + f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
> + SRAM_VECT_CODE);
> +
> + xip_safe = running_in_sram();
> +
> + /* Gauge the input clock speed and find out the sys_clkin_sel
> + * value corresponding to the input clock.
> + */
> + osc_clk = get_osc_clk_speed();
> + get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
> +
> + sr32(PRM_CLKSEL, 0, 3, sys_clkin_sel); /* set input crystal speed */
> +
> + /* If the input clock is greater than 19.2M always divide/2 */
> + if (sys_clkin_sel > 2) {
> + sr32(PRM_CLKSRC_CTRL, 6, 2, 2); /* input clock divider */
> + clk_index = sys_clkin_sel / 2;
> + } else {
> + sr32(PRM_CLKSRC_CTRL, 6, 2, 1); /* input clock divider */
> + clk_index = sys_clkin_sel;
> + }
> +
> + /* The DPLL tables are defined according to sysclk value and
> + * silicon revision. The clk_index value will be used to get
> + * the values for that input sysclk from the DPLL param table
> + * and sil_index will get the values for that SysClk for the
> + * appropriate silicon rev.
> + */
> + sil_index = get_cpu_rev() - 1;
this part is unreadable maybe you can add some blank line
> + /* Unlock MPU DPLL (slows things down, and needed later) */
> + sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOW_POWER_BYPASS);
> + wait_on_value(BIT0, 0, CM_IDLEST_PLL_MPU, LDELAY);
> +
> + /* Getting the base address of Core DPLL param table */
> + dpll_param_p = (dpll_param *) get_core_dpll_param();
> + /* Moving it to the right sysclk and ES rev base */
> + dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
> + if (xip_safe) {
> + /* CORE DPLL */
> + /* sr32(CM_CLKSEL2_EMU) set override to work when asleep */
> + sr32(CM_CLKEN_PLL, 0, 3, PLL_FAST_RELOCK_BYPASS);
> + wait_on_value(BIT0, 0, CM_IDLEST_CKGEN, LDELAY);
> + /* For OMAP3 ES1.0 Errata 1.50, default value directly doesnt
> + work. write another value and then default value. */
please use this style of comment
/*
*
*/
please also fix the whitespace
> + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2 + 1); /* m3x2 */
> + sr32(CM_CLKSEL1_EMU, 16, 5, CORE_M3X2); /* m3x2 */
> + sr32(CM_CLKSEL1_PLL, 27, 2, dpll_param_p->m2); /* Set M2 */
> + sr32(CM_CLKSEL1_PLL, 16, 11, dpll_param_p->m); /* Set M */
> + sr32(CM_CLKSEL1_PLL, 8, 7, dpll_param_p->n); /* Set N */
> + sr32(CM_CLKSEL1_PLL, 6, 1, 0); /* 96M Src */
> + sr32(CM_CLKSEL_CORE, 8, 4, CORE_SSI_DIV); /* ssi */
> + sr32(CM_CLKSEL_CORE, 4, 2, CORE_FUSB_DIV); /* fsusb */
> + sr32(CM_CLKSEL_CORE, 2, 2, CORE_L4_DIV); /* l4 */
> Index: u-boot-arm/cpu/arm_cortexa8/omap3/interrupts.c
> ===================================================================
> --- /dev/null
> +++ u-boot-arm/cpu/arm_cortexa8/omap3/interrupts.c
> @@ -0,0 +1,304 @@
> +/*
> + * (C) Copyright 2008
> + * Texas Instruments
> + *
> + * Richard Woodruff <r-woodruff2 at ti.com>
> + * Syed Moahmmed Khasim <khasim at ti.com>
> + *
> + * (C) Copyright 2002
> + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
> + * Marius Groeger <mgroeger at sysgo.de>
> + * Alex Zuepke <azu at sysgo.de>
> + *
> + * (C) Copyright 2002
> + * Gary Jennejohn, DENX Software Engineering, <gj 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
> + */
> +
> +#include <common.h>
> +#include <asm/arch/bits.h>
> +
> +#include <asm/proc-armv/ptrace.h>
> +
> +#define TIMER_LOAD_VAL 0
> +
> +/* macro to read the 32 bit timer */
> +#define READ_TIMER (*(volatile ulong *)(CONFIG_SYS_TIMERBASE+TCRR))
> +
> +#ifdef CONFIG_USE_IRQ
> +/* enable IRQ interrupts */
> +void enable_interrupts(void)
> +{
> + unsigned long temp;
> + __asm__ __volatile__("mrs %0, cpsr\n"
> + "bic %0, %0, #0x80\n" "msr cpsr_c, %0":"=r"(temp)
> + ::"memory");
> +}
> +
> +/*
> + * disable IRQ/FIQ interrupts
> + * returns true if interrupts had been enabled before we disabled them
> + */
> +int disable_interrupts(void)
> +{
> + unsigned long old, temp;
> + __asm__ __volatile__("mrs %0, cpsr\n"
> + "orr %1, %0, #0xc0\n"
> + "msr cpsr_c, %1":"=r"(old), "=r"(temp)
> + ::"memory");
> + return (old & 0x80) == 0;
> +}
> +#else
> +void enable_interrupts(void)
> +{
> + return;
> +}
> +int disable_interrupts(void)
> +{
> + return 0;
> +}
> +#endif
> +
> +void bad_mode(void)
> +{
> + panic("Resetting CPU ...\n");
> + reset_cpu(0);
> +}
> +
> +void show_regs(struct pt_regs *regs)
> +{
> + unsigned long flags;
> + const char *processor_modes[] = {
> + "USER_26", "FIQ_26", "IRQ_26", "SVC_26",
> + "UK4_26", "UK5_26", "UK6_26", "UK7_26",
> + "UK8_26", "UK9_26", "UK10_26", "UK11_26",
> + "UK12_26", "UK13_26", "UK14_26", "UK15_26",
> + "USER_32", "FIQ_32", "IRQ_32", "SVC_32",
> + "UK4_32", "UK5_32", "UK6_32", "ABT_32",
> + "UK8_32", "UK9_32", "UK10_32", "UND_32",
> + "UK12_32", "UK13_32", "UK14_32", "SYS_32",
> + };
> +
> + flags = condition_codes(regs);
> +
please fix the whitespace
> + printf("pc : [<%08lx>] lr : [<%08lx>]\n"
> + "sp : %08lx ip : %08lx fp : %08lx\n",
> + instruction_pointer(regs),
> + regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
> + printf("r10: %08lx r9 : %08lx r8 : %08lx\n",
> + regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
> + printf("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
> + regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
> + printf("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
> + regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
> + printf("Flags: %c%c%c%c",
> + flags & CC_N_BIT ? 'N' : 'n',
> + flags & CC_Z_BIT ? 'Z' : 'z',
> + flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
> + printf(" IRQs %s FIQs %s Mode %s%s\n",
> + interrupts_enabled(regs) ? "on" : "off",
> + fast_interrupts_enabled(regs) ? "on" : "off",
> + processor_modes[processor_mode(regs)],
> + thumb_mode(regs) ? " (T)" : "");
> +}
> +
> +void do_undefined_instruction(struct pt_regs *pt_regs)
> +{
> + printf("undefined instruction\n");
> + show_regs(pt_regs);
> + bad_mode();
> +}
> +
> +void do_software_interrupt(struct pt_regs *pt_regs)
> +{
> + printf("software interrupt\n");
> + show_regs(pt_regs);
> + bad_mode();
> +}
> +
> +void do_prefetch_abort(struct pt_regs *pt_regs)
> +{
> + printf("prefetch abort\n");
> + show_regs(pt_regs);
> + bad_mode();
> +}
> +
> +void do_data_abort(struct pt_regs *pt_regs)
> +{
> + printf("data abort\n");
> + show_regs(pt_regs);
> + bad_mode();
> +}
> +
> +void do_not_used(struct pt_regs *pt_regs)
> +{
> + printf("not used\n");
> + show_regs(pt_regs);
> + bad_mode();
> +}
> +
> +void do_fiq(struct pt_regs *pt_regs)
> +{
> + printf("fast interrupt request\n");
> + show_regs(pt_regs);
> + bad_mode();
> +}
> +
> +void do_irq(struct pt_regs *pt_regs)
> +{
> + printf("interrupt request\n");
> + show_regs(pt_regs);
> + bad_mode();
> +}
> +
> +
> +static ulong timestamp;
> +static ulong lastinc;
> +
> +/* nothing really to do with interrupts, just starts up a counter. */
> +int interrupt_init(void)
> +{
> + int32_t val;
> +
> + /* Start the counter ticking up */
Best Regards,
J.
More information about the U-Boot
mailing list