
On 21:27 Fri 17 Oct , dirk.behme@googlemail.com wrote:
Subject: [PATCH 06/13 v4] ARM: OMAP3: Add board, clock and interrupts common files
From: Dirk Behme dirk.behme@gmail.com
Add board, clock, cpu and interrupts common files
Signed-off-by: Dirk Behme dirk.behme@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@ti.com>
- Derived from Beagle Board and OMAP3 SDP code by
Richard Woodruff <r-woodruff2@ti.com>
Syed Mohammed Khasim <khasim@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@ti.com
- Syed Moahmmed Khasim khasim@ti.com
- (C) Copyright 2002
- Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- Marius Groeger mgroeger@sysgo.de
- Alex Zuepke azu@sysgo.de
- (C) Copyright 2002
- Gary Jennejohn, DENX Software Engineering, gj@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.