Subject: [PATCH 05/11 v1] ARM: OMAP3: Add board, clock, cpu and interrupts 
common files

From: Dirk Behme <[EMAIL PROTECTED]>

Add board, clock, cpu and interrupts common files

Signed-off-by: Dirk Behme <[EMAIL PROTECTED]>

---
 cpu/omap3/Makefile     |    2 
 cpu/omap3/board.c      |  294 +++++++++++++++++++++++++++++++++++++++++++++++
 cpu/omap3/clock.c      |  305 +++++++++++++++++++++++++++++++++++++++++++++++++
 cpu/omap3/cpu.c        |  221 +++++++++++++++++++++++++++++++++++
 cpu/omap3/interrupts.c |  304 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 1125 insertions(+), 1 deletion(-)

Index: u-boot_master/cpu/omap3/Makefile
===================================================================
--- u-boot_master.orig/cpu/omap3/Makefile
+++ u-boot_master/cpu/omap3/Makefile
@@ -27,7 +27,7 @@ LIB   = lib$(CPU).a
 
 START  := start.o
 SOBJS  := lowlevel_init.o
-OBJS   := sys_info.o
+OBJS   := sys_info.o board.o clock.o cpu.o interrupts.o
 
 all:   .depend $(START) $(LIB)
 
Index: u-boot_master/cpu/omap3/board.c
===================================================================
--- /dev/null
+++ u-boot_master/cpu/omap3/board.c
@@ -0,0 +1,294 @@
+/*
+ *
+ * Common board functions for OMAP3 based boards.
+ *
+ * (C) Copyright 2004-2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *      Sunil Kumar <[EMAIL PROTECTED]>
+ *      Shashi Ranjan <[EMAIL PROTECTED]>
+ *
+ * Derived from Beagle Board and 3430 SDP code by
+ *      Richard Woodruff <[EMAIL PROTECTED]>
+ *      Syed Mohammed Khasim <[EMAIL PROTECTED]>
+ *
+ *
+ * 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/io.h>
+#include <asm/arch/bits.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/mem.h>
+
+#define NOT_EARLY 0
+
+/* Permission values for registers -Full fledged permissions to all */
+#define UNLOCK_1 0xFFFFFFFF
+#define UNLOCK_2 0x00000000
+#define UNLOCK_3 0x0000FFFF
+
+/******************************************************************************
+ * Routine: delay
+ * Description: spinning delay to use before udelay works
+ *****************************************************************************/
+static inline void delay(unsigned long loops)
+{
+       __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
+                         "bne 1b":"=r" (loops):"0"(loops));
+}
+
+/******************************************************************************
+ * Routine: secure_unlock
+ * Description: Setup security registers for access
+ *              (GP Device only)
+ *****************************************************************************/
+void secure_unlock_mem(void)
+{
+       /* Protection Module Register Target APE (PM_RT) */
+       __raw_writel(UNLOCK_1, RT_REQ_INFO_PERMISSION_1);
+       __raw_writel(UNLOCK_1, RT_READ_PERMISSION_0);
+       __raw_writel(UNLOCK_1, RT_WRITE_PERMISSION_0);
+       __raw_writel(UNLOCK_2, RT_ADDR_MATCH_1);
+
+       __raw_writel(UNLOCK_3, GPMC_REQ_INFO_PERMISSION_0);
+       __raw_writel(UNLOCK_3, GPMC_READ_PERMISSION_0);
+       __raw_writel(UNLOCK_3, GPMC_WRITE_PERMISSION_0);
+
+       __raw_writel(UNLOCK_3, OCM_REQ_INFO_PERMISSION_0);
+       __raw_writel(UNLOCK_3, OCM_READ_PERMISSION_0);
+       __raw_writel(UNLOCK_3, OCM_WRITE_PERMISSION_0);
+       __raw_writel(UNLOCK_2, OCM_ADDR_MATCH_2);
+
+       /* IVA Changes */
+       __raw_writel(UNLOCK_3, IVA2_REQ_INFO_PERMISSION_0);
+       __raw_writel(UNLOCK_3, IVA2_READ_PERMISSION_0);
+       __raw_writel(UNLOCK_3, IVA2_WRITE_PERMISSION_0);
+
+       __raw_writel(UNLOCK_1, SMS_RG_ATT0);    /* SDRC region 0 public */
+}
+
+/******************************************************************************
+ * Routine: secureworld_exit()
+ * Description: If chip is EMU and boot type is external
+ *             configure secure registers and exit secure world
+ *              general use.
+ *****************************************************************************/
+void secureworld_exit()
+{
+       unsigned long i;
+
+       /* configrue non-secure access control register */
+       __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 2":"=r"(i));
+       /* enabling co-processor CP10 and CP11 accesses in NS world */
+       __asm__ __volatile__("orr %0, %0, #0xC00":"=r"(i));
+       /* allow allocation of locked TLBs and L2 lines in NS world */
+       /* allow use of PLE registers in NS world also */
+       __asm__ __volatile__("orr %0, %0, #0x70000":"=r"(i));
+       __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 2":"=r"(i));
+
+       /* Enable ASA in ACR register */
+       __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
+       __asm__ __volatile__("orr %0, %0, #0x10":"=r"(i));
+       __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
+
+       /* Exiting secure world */
+       __asm__ __volatile__("mrc p15, 0, %0, c1, c1, 0":"=r"(i));
+       __asm__ __volatile__("orr %0, %0, #0x31":"=r"(i));
+       __asm__ __volatile__("mcr p15, 0, %0, c1, c1, 0":"=r"(i));
+}
+
+/******************************************************************************
+ * Routine: setup_auxcr()
+ * Description: Write to AuxCR desired value using SMI.
+ *              general use.
+ *****************************************************************************/
+void setup_auxcr()
+{
+       unsigned long i;
+       volatile unsigned int j;
+       /* Save r0, r12 and restore them after usage */
+       __asm__ __volatile__("mov %0, r12":"=r"(j));
+       __asm__ __volatile__("mov %0, r0":"=r"(i));
+
+       /* GP Device ROM code API usage here */
+       /* r12 = AUXCR Write function and r0 value */
+       __asm__ __volatile__("mov r12, #0x3");
+       __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
+       /* Enabling ASA */
+       __asm__ __volatile__("orr r0, r0, #0x10");
+       /* SMI instruction to call ROM Code API */
+       __asm__ __volatile__(".word 0xE1600070");
+       __asm__ __volatile__("mov r0, %0":"=r"(i));
+       __asm__ __volatile__("mov r12, %0":"=r"(j));
+}
+
+/******************************************************************************
+ * Routine: try_unlock_sram()
+ * Description: If chip is GP/EMU(special) type, unlock the SRAM for
+ *              general use.
+ *****************************************************************************/
+void try_unlock_memory()
+{
+       int mode;
+       int in_sdram = running_in_sdram();
+
+       /* if GP device unlock device SRAM for general use */
+       /* secure code breaks for Secure/Emulation device - HS/E/T */
+       mode = get_device_type();
+       if (mode == GP_DEVICE)
+               secure_unlock_mem();
+
+       /* If device is EMU and boot is XIP external booting
+        * Unlock firewalls and disable L2 and put chip
+        * out of secure world
+        */
+       /* Assuming memories are unlocked by the demon who put us in SDRAM */
+       if ((mode <= EMU_DEVICE) && (get_boot_type() == 0x1F)
+           && (!in_sdram)) {
+               secure_unlock_mem();
+               secureworld_exit();
+       }
+
+       return;
+}
+
+/******************************************************************************
+ * Routine: s_init
+ * Description: Does early system init of muxing and clocks.
+ *              - Called path is with SRAM stack.
+ *****************************************************************************/
+void s_init(void)
+{
+       int in_sdram = running_in_sdram();
+
+       watchdog_init();
+
+       try_unlock_memory();
+
+       /* Right now flushing at low MPU speed.
+          Need to move after clock init */
+       v7_flush_dcache_all(get_device_type());
+#ifndef CONFIG_ICACHE_OFF
+       icache_enable();
+#endif
+
+#ifdef CONFIG_L2_OFF
+       l2cache_disable();
+#else
+       l2cache_enable();
+#endif
+       /* Writing to AuxCR in U-boot using SMI for GP DEV */
+       /* Currently SMI in Kernel on ES2 devices seems to have an isse
+        * Once that is resolved, we can postpone this config to kernel
+        */
+       if (get_device_type() == GP_DEVICE)
+               setup_auxcr();
+
+       set_muxconf_regs();
+       delay(100);
+
+       prcm_init();
+
+       per_clocks_enable();
+
+       if (!in_sdram)
+               sdrc_init();
+}
+
+/******************************************************************************
+ * Routine: wait_for_command_complete
+ * Description: Wait for posting to finish on watchdog
+ *****************************************************************************/
+void wait_for_command_complete(unsigned int wd_base)
+{
+       int pending = 1;
+       do {
+               pending = __raw_readl(wd_base + WWPS);
+       } while (pending);
+}
+
+/******************************************************************************
+ * Routine: watchdog_init
+ * Description: Shut down watch dogs
+ *****************************************************************************/
+void watchdog_init(void)
+{
+       /* There are 3 watch dogs WD1=Secure, WD2=MPU, WD3=IVA. WD1 is
+        * either taken care of by ROM (HS/EMU) or not accessible (GP).
+        * We need to take care of WD2-MPU or take a PRCM reset. WD3
+        * should not be running and does not generate a PRCM reset.
+        */
+
+       sr32(CM_FCLKEN_WKUP, 5, 1, 1);
+       sr32(CM_ICLKEN_WKUP, 5, 1, 1);
+       wait_on_value(BIT5, 0x20, CM_IDLEST_WKUP, 5);   /* some issue here */
+
+       __raw_writel(WD_UNLOCK1, WD2_BASE + WSPR);
+       wait_for_command_complete(WD2_BASE);
+       __raw_writel(WD_UNLOCK2, WD2_BASE + WSPR);
+}
+
+/******************************************************************************
+ * Routine: dram_init
+ * Description: sets uboots idea of sdram size
+ *****************************************************************************/
+int dram_init(void)
+{
+       DECLARE_GLOBAL_DATA_PTR;
+       unsigned int size0 = 0, size1 = 0;
+       u32 mtype, btype;
+
+       btype = get_board_type();
+       mtype = get_mem_type();
+
+       display_board_info(btype);
+
+       /* If a second bank of DDR is attached to CS1 this is
+        * where it can be started.  Early init code will init
+        * memory on CS0.
+        */
+       if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED))
+               do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY);
+
+       size0 = get_sdr_cs_size(SDRC_CS0_OSET);
+       size1 = get_sdr_cs_size(SDRC_CS1_OSET);
+
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = size0;
+       gd->bd->bi_dram[1].start = PHYS_SDRAM_1 + size0;
+       gd->bd->bi_dram[1].size = size1;
+
+       return 0;
+}
+
+/******************************************************************************
+ * Dummy function to handle errors for EABI incompatibility
+ *****************************************************************************/
+void raise(void)
+{
+}
+
+/******************************************************************************
+ * Dummy function to handle errors for EABI incompatibility
+ *****************************************************************************/
+void abort(void)
+{
+}
Index: u-boot_master/cpu/omap3/clock.c
===================================================================
--- /dev/null
+++ u-boot_master/cpu/omap3/clock.c
@@ -0,0 +1,305 @@
+/*
+ * (C) Copyright 2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *      Manikandan Pillai <[EMAIL PROTECTED]>
+ *
+ * Derived from Beagle Board and OMAP3 SDP code by
+ *      Richard Woodruff <[EMAIL PROTECTED]>
+ *      Syed Mohammed Khasim <[EMAIL PROTECTED]>
+ *
+ * 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 = __raw_readl(PRM_CLKSRC_CTRL);
+
+       /* If SYS_CLK is being divided by 2, remove for now */
+       val = (val & (~BIT7)) | BIT6;
+       __raw_writel(val, PRM_CLKSRC_CTRL);
+
+       /* enable timer2 */
+       val = __raw_readl(CM_CLKSEL_WKUP) | BIT0;
+       __raw_writel(val, CM_CLKSEL_WKUP);      /* select sys_clk for GPT1 */
+
+       /* Enable I and F Clocks for GPT1 */
+       val = __raw_readl(CM_ICLKEN_WKUP) | BIT0 | BIT2;
+       __raw_writel(val, CM_ICLKEN_WKUP);
+       val = __raw_readl(CM_FCLKEN_WKUP) | BIT0;
+       __raw_writel(val, CM_FCLKEN_WKUP);
+
+       __raw_writel(0, OMAP34XX_GPT1 + TLDR);  /* start counting at 0 */
+       __raw_writel(GPT_EN, OMAP34XX_GPT1 + TCLR);     /* enable clock */
+
+       /* enable 32kHz source, determine sys_clk via gauging */
+       start = 20 + __raw_readl(S32K_CR);      /* start time in 20 cycles */
+       while (__raw_readl(S32K_CR) < start) ;  /* dead loop till start time */
+       /* get start sys_clk count */
+       cstart = __raw_readl(OMAP34XX_GPT1 + TCRR);
+       /* wait for 40 cycles */
+       while (__raw_readl(S32K_CR) < (start + 20)) ;
+       cend = __raw_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;
+}
+
+/******************************************************************************
+ * 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;
+       /* 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. */
+               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 */
+               sr32(CM_CLKSEL_CORE, 0, 2, CORE_L3_DIV);        /* l3 */
+               sr32(CM_CLKSEL_GFX, 0, 3, GFX_DIV);             /* gfx */
+               sr32(CM_CLKSEL_WKUP, 1, 2, WKUP_RSM);           /* reset mgr */
+               sr32(CM_CLKEN_PLL, 4, 4, dpll_param_p->fsel);   /* FREQSEL */
+               sr32(CM_CLKEN_PLL, 0, 3, PLL_LOCK);             /* lock mode */
+               wait_on_value(BIT0, 1, CM_IDLEST_CKGEN, LDELAY);
+       } else if (running_in_flash()) {
+               /* if running from flash, jump to small relocated code
+                  area in SRAM. */
+               p0 = __raw_readl(CM_CLKEN_PLL);
+               sr32((u32) &p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
+               sr32((u32) &p0, 4, 4, dpll_param_p->fsel);      /* FREQSEL */
+
+               p1 = __raw_readl(CM_CLKSEL1_PLL);
+               sr32((u32) &p1, 27, 2, dpll_param_p->m2);       /* Set M2 */
+               sr32((u32) &p1, 16, 11, dpll_param_p->m);       /* Set M */
+               sr32((u32) &p1, 8, 7, dpll_param_p->n);         /* Set N */
+               sr32((u32) &p1, 6, 1, 0);           /* set source for 96M */
+               p2 = __raw_readl(CM_CLKSEL_CORE);
+               sr32((u32) &p2, 8, 4, CORE_SSI_DIV);    /* ssi */
+               sr32((u32) &p2, 4, 2, CORE_FUSB_DIV);   /* fsusb */
+               sr32((u32) &p2, 2, 2, CORE_L4_DIV);     /* l4 */
+               sr32((u32) &p2, 0, 2, CORE_L3_DIV);     /* l3 */
+
+               p3 = CM_IDLEST_CKGEN;
+
+               (*f_lock_pll) (p0, p1, p2, p3);
+       }
+
+       /* PER DPLL */
+       sr32(CM_CLKEN_PLL, 16, 3, PLL_STOP);
+       wait_on_value(BIT1, 0, CM_IDLEST_CKGEN, LDELAY);
+
+       /* Getting the base address to PER  DPLL param table */
+       /* Set N */
+       dpll_param_p = (dpll_param *) get_per_dpll_param();
+       /* Moving it to the right sysclk base */
+       dpll_param_p = dpll_param_p + clk_index;
+       /* Errata 1.50 Workaround for OMAP3 ES1.0 only */
+       /* If using default divisors, write default divisor + 1
+          and then the actual divisor value */
+       sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2 + 1);        /* set M6 */
+       sr32(CM_CLKSEL1_EMU, 24, 5, PER_M6X2);            /* set M6 */
+       sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2 + 1);          /* set M5 */
+       sr32(CM_CLKSEL_CAM, 0, 5, PER_M5X2);              /* set M5 */
+       sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2 + 1);          /* set M4 */
+       sr32(CM_CLKSEL_DSS, 0, 5, PER_M4X2);              /* set M4 */
+       sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2 + 1);          /* set M3 */
+       sr32(CM_CLKSEL_DSS, 8, 5, PER_M3X2);              /* set M3 */
+       sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2 + 1); /* set M2 */
+       sr32(CM_CLKSEL3_PLL, 0, 5, dpll_param_p->m2);     /* set M2 */
+       /* Workaround end */
+       sr32(CM_CLKSEL2_PLL, 8, 11, dpll_param_p->m);   /* set m */
+       sr32(CM_CLKSEL2_PLL, 0, 7, dpll_param_p->n);    /* set n */
+       sr32(CM_CLKEN_PLL, 20, 4, dpll_param_p->fsel);  /* FREQSEL */
+       sr32(CM_CLKEN_PLL, 16, 3, PLL_LOCK);    /* lock mode */
+       wait_on_value(BIT1, 2, CM_IDLEST_CKGEN, LDELAY);
+
+       /* Getting the base address to MPU DPLL param table */
+       dpll_param_p = (dpll_param *) get_mpu_dpll_param();
+       /* Moving it to the right sysclk and ES rev base */
+       dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
+       /* MPU DPLL (unlocked already) */
+       sr32(CM_CLKSEL2_PLL_MPU, 0, 5, dpll_param_p->m2);       /* Set M2 */
+       sr32(CM_CLKSEL1_PLL_MPU, 8, 11, dpll_param_p->m);       /* Set M */
+       sr32(CM_CLKSEL1_PLL_MPU, 0, 7, dpll_param_p->n);        /* Set N */
+       sr32(CM_CLKEN_PLL_MPU, 4, 4, dpll_param_p->fsel);       /* FREQSEL */
+       sr32(CM_CLKEN_PLL_MPU, 0, 3, PLL_LOCK); /* lock mode */
+       wait_on_value(BIT0, 1, CM_IDLEST_PLL_MPU, LDELAY);
+
+       /* Getting the base address to IVA DPLL param table */
+       dpll_param_p = (dpll_param *) get_iva_dpll_param();
+       /* Moving it to the right sysclk and ES rev base */
+       dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
+       /* IVA DPLL (set to 12*20=240MHz) */
+       sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_STOP);
+       wait_on_value(BIT0, 0, CM_IDLEST_PLL_IVA2, LDELAY);
+       sr32(CM_CLKSEL2_PLL_IVA2, 0, 5, dpll_param_p->m2);      /* set M2 */
+       sr32(CM_CLKSEL1_PLL_IVA2, 8, 11, dpll_param_p->m);      /* set M */
+       sr32(CM_CLKSEL1_PLL_IVA2, 0, 7, dpll_param_p->n);       /* set N */
+       sr32(CM_CLKEN_PLL_IVA2, 4, 4, dpll_param_p->fsel);      /* FREQSEL */
+       sr32(CM_CLKEN_PLL_IVA2, 0, 3, PLL_LOCK);        /* lock mode */
+       wait_on_value(BIT0, 1, CM_IDLEST_PLL_IVA2, LDELAY);
+
+       /* Set up GPTimers to sys_clk source only */
+       sr32(CM_CLKSEL_PER, 0, 8, 0xff);
+       sr32(CM_CLKSEL_WKUP, 0, 1, 1);
+
+       sdelay(5000);
+}
+
+/******************************************************************************
+ * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...)
+ *****************************************************************************/
+void per_clocks_enable(void)
+{
+       /* Enable GP2 timer. */
+       sr32(CM_CLKSEL_PER, 0, 1, 0x1); /* GPT2 = sys clk */
+       sr32(CM_ICLKEN_PER, 3, 1, 0x1); /* ICKen GPT2 */
+       sr32(CM_FCLKEN_PER, 3, 1, 0x1); /* FCKen GPT2 */
+
+#ifdef CFG_NS16550
+       /* Enable UART1 clocks */
+       sr32(CM_FCLKEN1_CORE, 13, 1, 0x1);
+       sr32(CM_ICLKEN1_CORE, 13, 1, 0x1);
+
+       /* UART 3 Clocks */
+       sr32(CM_FCLKEN_PER, 11, 1, 0x1);
+       sr32(CM_ICLKEN_PER, 11, 1, 0x1);
+#endif
+#ifdef CONFIG_DRIVER_OMAP34XX_I2C
+       /* Turn on all 3 I2C clocks */
+       sr32(CM_FCLKEN1_CORE, 15, 3, 0x7);
+       sr32(CM_ICLKEN1_CORE, 15, 3, 0x7);      /* I2C1,2,3 = on */
+#endif
+       /* Enable the ICLK for 32K Sync Timer as its used in udelay */
+       sr32(CM_ICLKEN_WKUP, 2, 1, 0x1);
+
+       sr32(CM_FCLKEN_IVA2, 0, 32, FCK_IVA2_ON);
+       sr32(CM_FCLKEN1_CORE, 0, 32, FCK_CORE1_ON);
+       sr32(CM_ICLKEN1_CORE, 0, 32, ICK_CORE1_ON);
+       sr32(CM_ICLKEN2_CORE, 0, 32, ICK_CORE2_ON);
+       sr32(CM_FCLKEN_WKUP, 0, 32, FCK_WKUP_ON);
+       sr32(CM_ICLKEN_WKUP, 0, 32, ICK_WKUP_ON);
+       sr32(CM_FCLKEN_DSS, 0, 32, FCK_DSS_ON);
+       sr32(CM_ICLKEN_DSS, 0, 32, ICK_DSS_ON);
+       sr32(CM_FCLKEN_CAM, 0, 32, FCK_CAM_ON);
+       sr32(CM_ICLKEN_CAM, 0, 32, ICK_CAM_ON);
+       sr32(CM_FCLKEN_PER, 0, 32, FCK_PER_ON);
+       sr32(CM_ICLKEN_PER, 0, 32, ICK_PER_ON);
+
+       sdelay(1000);
+}
Index: u-boot_master/cpu/omap3/cpu.c
===================================================================
--- /dev/null
+++ u-boot_master/cpu/omap3/cpu.c
@@ -0,0 +1,221 @@
+/*
+ * (C) Copyright 2008 Texas Insturments
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <[EMAIL PROTECTED]>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <[EMAIL PROTECTED]>
+ *
+ * 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
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/arch/sys_proto.h>
+
+#ifdef CONFIG_USE_IRQ
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
+#ifndef CONFIG_L2_OFF
+void l2cache_disable(void);
+#endif
+
+/* read co-processor 15, register #1 (control register) */
+static unsigned long read_p15_c1(void)
+{
+       unsigned long value;
+
+       __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 0\
+                            @ read control reg\n":"=r"(value)
+                            ::"memory");
+       return value;
+}
+
+/* write to co-processor 15, register #1 (control register) */
+static void write_p15_c1(unsigned long value)
+{
+       __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 0\
+                            @ write it back\n"::"r"(value)
+                            : "memory");
+
+       read_p15_c1();
+}
+
+static void cp_delay(void)
+{
+       volatile int i;
+
+       /* Many OMAP regs need at least 2 nops  */
+       for (i = 0; i < 100; i++) ;
+}
+
+/* See also ARM Ref. Man. */
+#define C1_MMU         (1<<0)  /* mmu off/on */
+#define C1_ALIGN       (1<<1)  /* alignment faults off/on */
+#define C1_DC          (1<<2)  /* dcache off/on */
+#define C1_WB          (1<<3)  /* merging write buffer on/off */
+#define C1_BIG_ENDIAN  (1<<7)  /* big endian off/on */
+#define C1_SYS_PROT    (1<<8)  /* system protection */
+#define C1_ROM_PROT    (1<<9)  /* ROM protection */
+#define C1_IC          (1<<12) /* icache off/on */
+#define C1_HIGH_VECTORS        (1<<13) /* location of vectors: low/high 
addresses */
+#define RESERVED_1     (0xf << 3)      /* must be 111b for R/W */
+
+int cpu_init(void)
+{
+       /*
+        * setup up stacks if necessary
+        */
+#ifdef CONFIG_USE_IRQ
+       IRQ_STACK_START =
+           _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
+       FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
+#endif
+       return 0;
+}
+
+int cleanup_before_linux(void)
+{
+       unsigned int i;
+
+       /*
+        * this function is called just before we call linux
+        * it prepares the processor for linux
+        *
+        * we turn off caches etc ...
+        */
+       disable_interrupts();
+
+       /* turn off I/D-cache */
+       asm("mrc p15, 0, %0, c1, c0, 0":"=r"(i));
+       i &= ~(C1_DC | C1_IC);
+       asm("mcr p15, 0, %0, c1, c0, 0": :"r"(i));
+
+       /* invalidate I-cache */
+       arm_cache_flush();
+#ifndef CONFIG_L2_OFF
+       /* turn off L2 cache */
+       l2cache_disable();
+       /* invalidate L2 cache also */
+       v7_flush_dcache_all(get_device_type());
+#endif
+       i = 0;
+       /* mem barrier to sync up things */
+       asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
+
+#ifndef CONFIG_L2_OFF
+       l2cache_enable();
+#endif
+
+       return 0;
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       disable_interrupts();
+       reset_cpu(0);
+
+       /* NOTREACHED */
+       return 0;
+}
+
+void icache_enable(void)
+{
+       ulong reg;
+
+       reg = read_p15_c1();    /* get control reg. */
+       cp_delay();
+       write_p15_c1(reg | C1_IC);
+}
+
+void icache_disable(void)
+{
+       ulong reg;
+
+       reg = read_p15_c1();
+       cp_delay();
+       write_p15_c1(reg & ~C1_IC);
+}
+
+void l2cache_enable()
+{
+       unsigned long i;
+       volatile unsigned int j;
+
+       /* ES2 onwards we can disable/enable L2 ourselves */
+       if (get_cpu_rev() == CPU_3430_ES2) {
+               __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
+               __asm__ __volatile__("orr %0, %0, #0x2":"=r"(i));
+               __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
+       } else {
+               /* Save r0, r12 and restore them after usage */
+               __asm__ __volatile__("mov %0, r12":"=r"(j));
+               __asm__ __volatile__("mov %0, r0":"=r"(i));
+
+               /* GP Device ROM code API usage here */
+               /* r12 = AUXCR Write function and r0 value */
+               __asm__ __volatile__("mov r12, #0x3");
+               __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
+               __asm__ __volatile__("orr r0, r0, #0x2");
+               /* SMI instruction to call ROM Code API */
+               __asm__ __volatile__(".word 0xE1600070");
+               __asm__ __volatile__("mov r0, %0":"=r"(i));
+               __asm__ __volatile__("mov r12, %0":"=r"(j));
+       }
+
+}
+
+void l2cache_disable()
+{
+       unsigned long i;
+       volatile unsigned int j;
+
+       /* ES2 onwards we can disable/enable L2 ourselves */
+       if (get_cpu_rev() == CPU_3430_ES2) {
+               __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1":"=r"(i));
+               __asm__ __volatile__("bic %0, %0, #0x2":"=r"(i));
+               __asm__ __volatile__("mcr p15, 0, %0, c1, c0, 1":"=r"(i));
+       } else {
+               /* Save r0, r12 and restore them after usage */
+               __asm__ __volatile__("mov %0, r12":"=r"(j));
+               __asm__ __volatile__("mov %0, r0":"=r"(i));
+
+               /* GP Device ROM code API usage here */
+               /* r12 = AUXCR Write function and r0 value */
+               __asm__ __volatile__("mov r12, #0x3");
+               __asm__ __volatile__("mrc p15, 0, r0, c1, c0, 1");
+               __asm__ __volatile__("bic r0, r0, #0x2");
+               /* SMI instruction to call ROM Code API */
+               __asm__ __volatile__(".word 0xE1600070");
+               __asm__ __volatile__("mov r0, %0":"=r"(i));
+               __asm__ __volatile__("mov r12, %0":"=r"(j));
+       }
+}
+
+int icache_status(void)
+{
+       return (read_p15_c1() & C1_IC) != 0;
+}
Index: u-boot_master/cpu/omap3/interrupts.c
===================================================================
--- /dev/null
+++ u-boot_master/cpu/omap3/interrupts.c
@@ -0,0 +1,304 @@
+/*
+ * (C) Copyright 2008
+ * Texas Instruments
+ *
+ * Richard Woodruff <[EMAIL PROTECTED]>
+ * Syed Moahmmed Khasim <[EMAIL PROTECTED]>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <[EMAIL PROTECTED]>
+ * Alex Zuepke <[EMAIL PROTECTED]>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <[EMAIL PROTECTED]>
+ *
+ * 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 *)(CFG_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);
+
+       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 */
+       /* reload value on overflow */
+       *((int32_t *) (CFG_TIMERBASE + TLDR)) = TIMER_LOAD_VAL;
+       /* mask to enable timer */
+       val = (CFG_PVT << 2) | BIT5 | BIT1 | BIT0;
+       *((int32_t *) (CFG_TIMERBASE + TCLR)) = val;    /* start timer */
+
+       reset_timer_masked();   /* init the timestamp and lastinc value */
+
+       return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+void reset_timer(void)
+{
+       reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+       return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+       timestamp = t;
+}
+
+/* delay x useconds AND perserve advance timstamp value */
+void udelay(unsigned long usec)
+{
+       ulong tmo, tmp;
+
+       /* if "big" number, spread normalization to seconds */
+       if (usec >= 1000) {
+               /* if "big" number, spread normalization to seconds */
+               tmo = usec / 1000;
+               /* find number of "ticks" to wait to achieve target */
+               tmo *= CFG_HZ;
+               tmo /= 1000;    /* finish normalize. */
+       } else {/* else small number, don't kill it prior to HZ multiply */
+               tmo = usec * CFG_HZ;
+               tmo /= (1000 * 1000);
+       }
+
+       tmp = get_timer(0);     /* get current timestamp */
+       /* if setting this forward will roll time stamp */
+       if ((tmo + tmp + 1) < tmp)
+               /* reset "advancing" timestamp to 0, set lastinc value */
+               reset_timer_masked();
+       else
+               tmo += tmp;     /* else, set advancing stamp wake up time */
+       while (get_timer_masked() < tmo)        /* loop till event */
+                /*NOP*/;
+}
+
+void reset_timer_masked(void)
+{
+       /* reset time */
+       lastinc = READ_TIMER;   /* capture current incrementer value time */
+       timestamp = 0;          /* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked(void)
+{
+       ulong now = READ_TIMER; /* current tick value */
+
+       if (now >= lastinc)     /* normal mode (non roll) */
+               /* move stamp fordward with absoulte diff ticks */
+               timestamp += (now - lastinc);
+       else    /* we have rollover of incrementer */
+               timestamp += (0xFFFFFFFF - lastinc) + now;
+       lastinc = now;
+       return timestamp;
+}
+
+/* waits specified delay value and resets timestamp */
+void udelay_masked(unsigned long usec)
+{
+       ulong tmo;
+       ulong endtime;
+       signed long diff;
+
+       /* if "big" number, spread normalization to seconds */
+       if (usec >= 1000) {
+               /* start to normalize for usec to ticks per sec */
+               tmo = usec / 1000;
+               /* find number of "ticks" to wait to achieve target */
+               tmo *= CFG_HZ;
+               tmo /= 1000;    /* finish normalize. */
+       } else {                /* else small number, */
+                               /* don't kill it prior to HZ multiply */
+               tmo = usec * CFG_HZ;
+               tmo /= (1000 * 1000);
+       }
+       endtime = get_timer_masked() + tmo;
+
+       do {
+               ulong now = get_timer_masked();
+               diff = endtime - now;
+       } while (diff >= 0);
+}
+
+/*
+ * 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(0);
+}
+
+/*
+ * 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)
+{
+       ulong tbclk;
+       tbclk = CFG_HZ;
+       return tbclk;
+}
+
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to