[U-Boot-Users] [Patch 12/17 Try 2] U-Boot-V2:ARM:OMAP3: Add support forOMAP3 Silicon files

Menon, Nishanth x0nishan at ti.com
Wed Jun 4 07:07:02 CEST 2008


Sascha,
> -----Original Message-----
> From: u-boot-users-bounces at lists.sourceforge.net [mailto:u-boot-users-bounces at lists.sourceforge.net]
> On Behalf Of Menon, Nishanth
> Sent: Wednesday, May 21, 2008 11:30 AM
> To: Sascha Hauer
> Cc: u-boot-users at lists.sourceforge.net; Kamat, Nishant; Syed Mohammed, Khasim; Laurent Desnogues;
> philip.balister at gmail.com
> Subject: [U-Boot-Users] [Patch 12/17] U-Boot-V2:ARM:OMAP3: Add support forOMAP3 Silicon files
>
> This patch introduces support for OMAP3430 clocking infrastructure. Please note that SRAM based
> configuration requires GPMC values to be updated before returning to caller- TBD.
>
Cleanup with BIT defines and return style corrected.

Signed-off-by: Nishanth Menon<x0nishan at ti.com>

---
 arch/arm/mach-omap/omap3_clock.c        |  379 ++++++++++++++++++++++++++++++++
 arch/arm/mach-omap/omap3_clock_core.S   |  312 ++++++++++++++++++++++++++
 arch/arm/mach-omap/s32k_clksource.c     |   80 ++++++
 include/asm-arm/arch-omap/clocks.h      |   48 ++++
 include/asm-arm/arch-omap/omap3-clock.h |  124 ++++++++++
 5 files changed, 943 insertions(+)

Index: u-boot.v2/arch/arm/mach-omap/omap3_clock.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ u-boot.v2/arch/arm/mach-omap/omap3_clock.c  2008-06-03 22:53:19.000000000 -0500
@@ -0,0 +1,379 @@
+/**
+ * @file
+ * @brief OMAP DPLL and various clock configuration
+ *
+ * FileName: arch/arm/mach-omap/omap3_clock.c
+ *
+ * @ref prcm_init This is the second level clock init for PRCM as defined in
+ * clocks.h -- called from SRAM, or Flash (using temp SRAM stack).
+ *
+ * During reconfiguring the clocks while in SDRAM/Flash, we can have invalid
+ * clock configuration to which ARM instruction/data fetch ops can fail.
+ * This critical path is handled by relocating the relevant functions in
+ * omap3_clock_core.S to OMAP's ISRAM and executing it there.
+ *
+ * @warning: IMPORTANT: These functions run from ISRAM stack, so no bss sections
+ * should be used: functions cannot use global variables/switch constructs.
+ *
+ * Originally from http://linux.omap.com/pub/bootloader/3430sdp/u-boot-v1.tar.gz
+ */
+/*
+ * (C) Copyright 2006-2008
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2 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/silicon.h>
+#include <asm/arch/clocks.h>
+#include <asm/arch/timers.h>
+#include <asm/arch/sys_info.h>
+#include <asm/arch/syslib.h>
+
+/* Following functions are exported from omap3_clock_core.S */
+#ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
+/* A.K.A go_to_speed */
+static void (*f_lock_pll) (u32, u32, u32, u32);
+#endif
+/* Helper functions */
+static u32 get_osc_clk_speed(void);
+static void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel);
+static void per_clocks_enable(void);
+
+/**
+ * @brief Determine reference oscillator speed
+ *
+ *  This is based on known 32kHz clock and gptimer.
+ *
+ * @return clock speed S38_4M, S26M S24M S19_2M S13M S12M
+ */
+static u32 get_osc_clk_speed(void)
+{
+       u32 start, cstart, cend, cdiff, val;
+
+       val = __raw_readl(PRM_REG(CLKSRC_CTRL));
+       /* If SYS_CLK is being divided by 2, remove for now */
+       val = (val & (~(0x1 << 7))) | (0x1 << 6);
+       __raw_writel(val, PRM_REG(CLKSRC_CTRL));
+
+       /* enable timer2 */
+       val = __raw_readl(CM_REG(CLKSEL_WKUP)) | (0x1 << 0);
+       __raw_writel(val, CM_REG(CLKSEL_WKUP)); /* select sys_clk for GPT1 */
+
+       /* Enable I and F Clocks for GPT1 */
+       val = __raw_readl(CM_REG(ICLKEN_WKUP)) | (0x1 << 0) | (0x1 << 2);
+       __raw_writel(val, CM_REG(ICLKEN_WKUP));
+       val = __raw_readl(CM_REG(FCLKEN_WKUP)) | (0x1 << 0);
+       __raw_writel(val, CM_REG(FCLKEN_WKUP));
+       /* start counting at 0 */
+       __raw_writel(0, OMAP_GPTIMER1_BASE + TLDR);
+       /* enable clock */
+       __raw_writel(GPT_EN, OMAP_GPTIMER1_BASE + TCLR);
+       /* enable 32kHz source - enabled out of reset */
+       /* 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(OMAP_GPTIMER1_BASE + TCRR);
+       while (__raw_readl(S32K_CR) < (start + 20)) ;   /* wait for 40 cycles */
+       /* get end sys_clk count */
+       cend = __raw_readl(OMAP_GPTIMER1_BASE + TCRR);
+       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;
+}
+
+/**
+ * @brief Returns the sys_clkin_sel field value
+ *
+ * This is based on input oscillator clock frequency.
+ *
+ * @param[in] osc_clk - Oscilaltor Clock to OMAP
+ * @param[out] sys_clkin_sel - returns the sys_clk selection
+ *
+ * @return void
+ */
+static 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;
+}
+
+/**
+ * @brief Inits clocks for PRCM
+ *
+ * This is called from SRAM, or Flash (using temp SRAM stack).
+ * if CONFIG_OMAP3_COPY_CLOCK_SRAM is defined, @ref go_to_speed
+ *
+ * @return void
+ */
+void prcm_init(void)
+{
+       int xip_safe;
+       u32 osc_clk = 0, sys_clkin_sel = 0;
+       u32 clk_index, sil_index;
+       struct dpll_param *dpll_param_p;
+#ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
+       int p0, p1, p2, p3;
+       f_lock_pll = (void *)(OMAP_SRAM_INTVECT + OMAP_SRAM_INTVECT_COPYSIZE);
+#endif
+
+       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);
+       /* set input crystal speed */
+       sr32(PRM_REG(CLKSEL), 0, 3, sys_clkin_sel);
+
+       /* If the input clock is greater than 19.2M always divide/2 */
+       if (sys_clkin_sel > 2) {
+               /* input clock divider */
+               sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 2);
+               clk_index = sys_clkin_sel / 2;
+       } else {
+               /* input clock divider */
+               sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 1);
+               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.
+        */
+       if (get_cpu_rev() >= CPU_ES2)
+               sil_index = 1;
+       /* Unlock MPU DPLL (slows things down, and needed later) */
+       sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOW_POWER_BYPASS);
+       wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_MPU), LDELAY);
+
+       /* Getting the base address of Core DPLL param table */
+       dpll_param_p = (struct dpll_param *)get_core_dpll_param();
+       /* Moving it to the right sysclk and ES rev base */
+       dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
+       if (xip_safe) {
+               /* CORE DPLL */
+               /* sr32(CM_REG(CLKSEL2_EMU)) set override to work when asleep */
+               sr32(CM_REG(CLKEN_PLL), 0, 3, PLL_FAST_RELOCK_BYPASS);
+               wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_CKGEN), LDELAY);
+               /* For 3430 ES1.0 Errata 1.50, default value directly doesnt
+                  work. write another value and then default value. */
+               sr32(CM_REG(CLKSEL1_EMU), 16, 5, CORE_M3X2 + 1);
+               sr32(CM_REG(CLKSEL1_EMU), 16, 5, CORE_M3X2);
+               sr32(CM_REG(CLKSEL1_PLL), 27, 2, dpll_param_p->m2);
+               sr32(CM_REG(CLKSEL1_PLL), 16, 11, dpll_param_p->m);
+               sr32(CM_REG(CLKSEL1_PLL), 8, 7, dpll_param_p->n);
+               sr32(CM_REG(CLKSEL1_PLL), 6, 1, 0);
+               sr32(CM_REG(CLKSEL_CORE), 8, 4, CORE_SSI_DIV);
+               sr32(CM_REG(CLKSEL_CORE), 4, 2, CORE_FUSB_DIV);
+               sr32(CM_REG(CLKSEL_CORE), 2, 2, CORE_L4_DIV);
+               sr32(CM_REG(CLKSEL_CORE), 0, 2, CORE_L3_DIV);
+               sr32(CM_REG(CLKSEL_GFX), 0, 3, GFX_DIV);
+               sr32(CM_REG(CLKSEL_WKUP), 1, 2, WKUP_RSM);
+               sr32(CM_REG(CLKEN_PLL), 4, 4, dpll_param_p->fsel);
+               sr32(CM_REG(CLKEN_PLL), 0, 3, PLL_LOCK);
+               wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_CKGEN), LDELAY);
+       } else if (running_in_flash()) {
+#ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
+               /* if running from flash,
+                * jump to small relocated code area in SRAM.
+                */
+               p0 = __raw_readl(CM_REG(CLKEN_PLL));
+               sr32((u32) &p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
+               sr32((u32) &p0, 4, 4, dpll_param_p->fsel);
+
+               p1 = __raw_readl(CM_REG(CLKSEL1_PLL));
+               sr32((u32) &p1, 27, 2, dpll_param_p->m2);
+               sr32((u32) &p1, 16, 11, dpll_param_p->m);
+               sr32((u32) &p1, 8, 7, dpll_param_p->n);
+               sr32((u32) &p1, 6, 1, 0);       /* set source for 96M */
+               p2 = __raw_readl(CM_REG(CLKSEL_CORE));
+               sr32((u32) &p2, 8, 4, CORE_SSI_DIV);
+               sr32((u32) &p2, 4, 2, CORE_FUSB_DIV);
+               sr32((u32) &p2, 2, 2, CORE_L4_DIV);
+               sr32((u32) &p2, 0, 2, CORE_L3_DIV);
+
+               p3 = CM_REG(IDLEST_CKGEN);
+
+               (*f_lock_pll) (p0, p1, p2, p3);
+#else
+               /***Oopps.. Wrong .config!! *****/
+               hang();
+#endif
+       }
+
+       /* PER DPLL */
+       sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_STOP);
+       wait_on_value((0x1 << 1), 0, CM_REG(IDLEST_CKGEN), LDELAY);
+
+       /* Getting the base address to PER  DPLL param table */
+       /* Set N */
+       dpll_param_p = (struct 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 3430 ES1.0 only */
+       /* If using default divisors, write default divisor + 1
+          and then the actual divisor value */
+       /* Need to change it to silicon and revisino check */
+       if (1) {
+               sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2 + 1); /* set M6 */
+               sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2);     /* set M6 */
+               sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2 + 1);   /* set M5 */
+               sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2);       /* set M5 */
+               sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2 + 1);   /* set M4 */
+               sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2);       /* set M4 */
+               sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2 + 1);   /* set M3 */
+               sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2);       /* set M3 */
+               /* set M2 */
+               sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2 + 1);
+               sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2);
+       } else {
+               sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2);     /* set M6 */
+               sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2);       /* set M5 */
+               sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2);       /* set M4 */
+               sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2);       /* set M3 */
+               sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2);
+       }
+       sr32(CM_REG(CLKSEL2_PLL), 8, 11, dpll_param_p->m);      /* set m */
+       sr32(CM_REG(CLKSEL2_PLL), 0, 7, dpll_param_p->n);       /* set n */
+       sr32(CM_REG(CLKEN_PLL), 20, 4, dpll_param_p->fsel);     /* FREQSEL */
+       sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_LOCK);       /* lock mode */
+       wait_on_value((0x1 << 1), 2, CM_REG(IDLEST_CKGEN), LDELAY);
+
+       /* Getting the base address to MPU DPLL param table */
+       dpll_param_p = (struct dpll_param *)get_mpu_dpll_param();
+       /* Moving it to the right sysclk and ES rev base */
+       dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
+       /* MPU DPLL (unlocked already) */
+       sr32(CM_REG(CLKSEL2_PLL_MPU), 0, 5, dpll_param_p->m2);  /* Set M2 */
+       sr32(CM_REG(CLKSEL1_PLL_MPU), 8, 11, dpll_param_p->m);  /* Set M */
+       sr32(CM_REG(CLKSEL1_PLL_MPU), 0, 7, dpll_param_p->n);   /* Set N */
+       sr32(CM_REG(CLKEN_PLL_MPU), 4, 4, dpll_param_p->fsel);  /* FREQSEL */
+       sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOCK);    /* lock mode */
+       wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_MPU), LDELAY);
+
+       /* Getting the base address to IVA DPLL param table */
+       dpll_param_p = (struct dpll_param *)get_iva_dpll_param();
+       /* Moving it to the right sysclk and ES rev base */
+       dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
+       /* IVA DPLL (set to 12*20=240MHz) */
+       sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_STOP);
+       wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_IVA2), LDELAY);
+       sr32(CM_REG(CLKSEL2_PLL_IVA2), 0, 5, dpll_param_p->m2); /* set M2 */
+       sr32(CM_REG(CLKSEL1_PLL_IVA2), 8, 11, dpll_param_p->m); /* set M */
+       sr32(CM_REG(CLKSEL1_PLL_IVA2), 0, 7, dpll_param_p->n);  /* set N */
+       sr32(CM_REG(CLKEN_PLL_IVA2), 4, 4, dpll_param_p->fsel); /* FREQSEL */
+       sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_LOCK);   /* lock mode */
+       wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_IVA2), LDELAY);
+
+       /* Set up GPTimers to sys_clk source only */
+       sr32(CM_REG(CLKSEL_PER), 0, 8, 0xff);
+       sr32(CM_REG(CLKSEL_WKUP), 0, 1, 1);
+
+       sdelay(5000);
+
+       /* Enable Peripheral Clocks */
+       per_clocks_enable();
+}
+
+/**
+ * @brief Enable the clks & power for perifs
+ *
+ * GPT2 Sysclk, ICLK,FCLK, 32k Sync is enabled by default
+ * Uses CONFIG_OMAP_CLOCK_UART to enable UART clocks
+ * Uses CONFIG_OMAP_CLOCK_I2C to enable I2C clocks
+ * Uses CONFIG_OMAP_CLOCK_ALL to enable All Clocks!
+ *    - Not a wise idea in most cases
+ *
+ * @return void
+ */
+static void per_clocks_enable(void)
+{
+       /* Enable GP2 timer. */
+       sr32(CM_REG(CLKSEL_PER), 0, 1, 0x1);    /* GPT2 = sys clk */
+       sr32(CM_REG(ICLKEN_PER), 3, 1, 0x1);    /* ICKen GPT2 */
+       sr32(CM_REG(FCLKEN_PER), 3, 1, 0x1);    /* FCKen GPT2 */
+       /* Enable the ICLK for 32K Sync Timer as its used in udelay */
+       sr32(CM_REG(ICLKEN_WKUP), 2, 1, 0x1);
+
+#ifdef CONFIG_OMAP_CLOCK_UART
+       /* Enable UART1 clocks */
+       sr32(CM_REG(FCLKEN1_CORE), 13, 1, 0x1);
+       sr32(CM_REG(ICLKEN1_CORE), 13, 1, 0x1);
+#endif
+#ifdef CONFIG_OMAP_CLOCK_I2C
+       /* Turn on all 3 I2C clocks */
+       sr32(CM_REG(FCLKEN1_CORE), 15, 3, 0x7);
+       sr32(CM_REG(ICLKEN1_CORE), 15, 3, 0x7); /* I2C1,2,3 = on */
+#endif
+
+#ifdef CONFIG_OMAP_CLOCK_ALL
+#define FCK_IVA2_ON    0x00000001
+#define FCK_CORE1_ON   0x03fffe29
+#define ICK_CORE1_ON   0x3ffffffb
+#define ICK_CORE2_ON   0x0000001f
+#define        FCK_WKUP_ON     0x000000e9
+#define ICK_WKUP_ON    0x0000003f
+#define FCK_DSS_ON     0x00000005      /* tv+dss1 (not dss2) */
+#define ICK_DSS_ON     0x00000001
+#define FCK_CAM_ON     0x00000001
+#define ICK_CAM_ON     0x00000001
+#define FCK_PER_ON     0x0003ffff
+#define ICK_PER_ON     0x0003ffff
+       sr32(CM_REG(FCLKEN_IVA2), 0, 32, FCK_IVA2_ON);
+       sr32(CM_REG(FCLKEN1_CORE), 0, 32, FCK_CORE1_ON);
+       sr32(CM_REG(ICLKEN1_CORE), 0, 32, ICK_CORE1_ON);
+       sr32(CM_REG(ICLKEN2_CORE), 0, 32, ICK_CORE2_ON);
+       sr32(CM_REG(FCLKEN_WKUP), 0, 32, FCK_WKUP_ON);
+       sr32(CM_REG(ICLKEN_WKUP), 0, 32, ICK_WKUP_ON);
+       sr32(CM_REG(FCLKEN_DSS), 0, 32, FCK_DSS_ON);
+       sr32(CM_REG(ICLKEN_DSS), 0, 32, ICK_DSS_ON);
+       sr32(CM_REG(FCLKEN_CAM), 0, 32, FCK_CAM_ON);
+       sr32(CM_REG(ICLKEN_CAM), 0, 32, ICK_CAM_ON);
+       sr32(CM_REG(FCLKEN_PER), 0, 32, FCK_PER_ON);
+       sr32(CM_REG(ICLKEN_PER), 0, 32, ICK_PER_ON);
+#endif
+       /* Settle down my friend */
+       sdelay(1000);
+}
Index: u-boot.v2/arch/arm/mach-omap/omap3_clock_core.S
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ u-boot.v2/arch/arm/mach-omap/omap3_clock_core.S     2008-06-03 22:49:11.000000000 -0500
@@ -0,0 +1,312 @@
+/**
+ * @file
+ * @brief Provides PRCM divisors and SRAM execution code.
+ *
+ * FileName: arch/arm/mach-omap/omap3_clock_core.S
+ *
+ * This provides two things:
+ * @li @ref omap3_clock.c cannot have switch or global variables.
+ * This file provides the constant data for the file to use.
+ *
+ * @li @ref prcm_init cannot execute certain critical clock
+ * configurations while running in SDRAM/Flash. This provides
+ * relocation and execution capability for the same.
+ *
+ * Orignally from http://linux.omap.com/pub/bootloader/3430sdp/u-boot-v1.tar.gz
+ */
+/*
+ * (C) Copyright 2006-2008
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2 at ti.com>
+ * Nishanth Menon <x0nishan 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 <config.h>
+#include <asm/arch/silicon.h>
+#include <asm/arch/clocks.h>
+#include <asm/arch/gpmc.h>
+
+#ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
+/**
+ * @fn void cpy_clk_code(u32 R1)
+ *
+ * @brief cpy_clk_code: relocates clock code into SRAM where its safer to
+ * execute
+ *
+ * @param[in] R1 = SRAM destination address.
+ *
+ * @return void
+ */
+.global cpy_clk_code
+ cpy_clk_code:
+        /* Copy DPLL code into SRAM */
+        adr     r0, go_to_speed         /* get addr of clock setting code */
+        mov     r2, #384                /* r2 size to copy (div by 32 bytes) */
+        mov     r1, r1                  /* r1 <- dest address (passed in) */
+        add     r2, r2, r0              /* r2 <- source end address */
+next2:
+        ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */
+        stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */
+        cmp     r0, r2                  /* until source end address [r2]    */
+        bne     next2
+       mov     pc, lr                  /* back to caller */
+
+/**
+ * @fn void go_to_speed(u32 R0, u32 R1, u32 R3)
+ *
+ * @brief go_to_speed: Function which configures the clocks
+ *  Moves to bypass, -Commits clock dividers, -puts dpll at speed
+ *               -executed from SRAM.
+ * @warning Note: If core unlocks/relocks and SDRAM is running fast already
+ *        it gets confused.  A reset of the controller gets it back. Taking
+ *        away its L3 when its not in self refresh seems bad for it.
+ *        Normally, this code runs from flash before SDR is init so that
+ *        should be ok.
+ *
+ * @param[in] R1 = SRAM destination address.
+ * @param[in] R0 = CM_CLKEN_PLL-bypass value
+ * @param[in] R1 = CM_CLKSEL1_PLL-m, n, and divider values
+ * @param[in] R2 = CM_CLKSEL_CORE-divider values
+ * @param[in] R3 = CM_IDLEST_CKGEN - addr dpll lock wait
+ *
+ * @return void
+ */
+.global go_to_speed
+ go_to_speed:
+        stmfd sp!, {r4-r6}
+
+        /* move into fast relock bypass */
+        ldr     r4, pll_ctl_add
+        str     r0, [r4]
+wait1:
+        ldr     r5, [r3]       /* get status */
+        and     r5, r5, #0x1   /* isolate core status */
+        cmp     r5, #0x1       /* still locked? */
+        beq     wait1          /* if lock, loop */
+
+       /* set new dpll dividers _after_ in bypass */
+       ldr     r5, pll_div_add1
+        str     r1, [r5]          /* set m, n, m2 */
+        ldr     r5, pll_div_add2
+        str     r2, [r5]          /* set l3/l4/.. dividers*/
+        ldr     r5, pll_div_add3  /* wkup */
+        ldr     r2, pll_div_val3  /* rsm val */
+        str     r2, [r5]
+        ldr     r5, pll_div_add4  /* gfx */
+        ldr     r2, pll_div_val4
+        str     r2, [r5]
+        ldr     r5, pll_div_add5  /* emu */
+        ldr     r2, pll_div_val5
+        str     r2, [r5]
+
+#if 0
+        /* FIXME: now prepare GPMC (flash) for new dpll speed
+        * For NOR/NAND/OneNAND boot ->make this as Kconfig?
+        */
+       /* flash needs to be stable when we jump back to it */
+        ldr     r6, flash_cfg_offset
+        ldr     r5, flash_cfg_addr /* CFG1 */
+        ldr     r2, flash_cfg1_val
+        str     r2, [r5]
+        add    r5, r5, r6 /* CFG2 */
+        ldr     r2, flash_cfg2_val
+        str     r2, [r5]
+        add    r5, r5, r6 /* CFG3 */
+        ldr     r2, flash_cfg3_val
+        str     r2, [r5]
+        add    r5, r5, r6 /* CFG4 */
+        ldr     r2, flash_cfg4_val
+        str     r2, [r5]
+        add    r5, r5, r6 /* CFG5 */
+        ldr     r2, flash_cfg5_val
+        str     r2, [r5]
+        add    r5, r5, r6 /* CFG6 */
+        ldr     r2, flash_cfg6_val
+        str     r2, [r5]
+#endif /* Debug */
+
+        /* lock DPLL3 and wait a bit */
+        orr     r0, r0, #0x7   /* set up for lock mode */
+        str     r0, [r4]       /* lock */
+        nop                    /* ARM slow at this point working at sys_clk */
+        nop
+        nop
+        nop
+wait2:
+        ldr     r5, [r3]       /* get status */
+        and     r5, r5, #0x1   /* isolate core status */
+        cmp     r5, #0x1       /* still locked? */
+        bne     wait2          /* if lock, loop */
+        nop
+        nop
+        nop
+        nop
+        ldmfd sp!, {r4-r6}
+        mov     pc, lr           /* back to caller, locked */
+
+_go_to_speed: .word go_to_speed
+
+/* these constants need to be close for PIC code */
+/* FIXME: The Nor has to be in the Flash Base CS0 for this condition to happen*/
+#if 0
+flash_cfg_addr:
+    .word GPMC_REG(CONFIG1_0)
+flash_cfg_offset:
+    .word GPMC_REG(CONFIG2_0) - GPMC_REG(CONFIG1_0)
+flash_cfg1_val:
+    .word  CONFIG_VALUE_GPMC_CONFIG1
+flash_cfg2_val:
+    .word  CONFIG_VALUE_GPMC_CONFIG2
+flash_cfg3_val:
+    .word  CONFIG_VALUE_GPMC_CONFIG3
+flash_cfg4_val:
+    .word  CONFIG_VALUE_GPMC_CONFIG4
+flash_cfg5_val:
+    .word  CONFIG_VALUE_GPMC_CONFIG5
+flash_cfg6_val:
+    .word  CONFIG_VALUE_GPMC_CONFIG6
+#endif
+pll_ctl_add:
+    .word CM_CLKEN_PLL
+pll_div_add1:
+    .word CM_CLKSEL1_PLL
+pll_div_add2:
+    .word CM_CLKSEL_CORE
+pll_div_add3:
+    .word CM_CLKSEL_WKUP
+pll_div_val3:
+    .word (WKUP_RSM << 1)
+pll_div_add4:
+    .word CM_CLKSEL_GFX
+pll_div_val4:
+    .word (GFX_DIV << 0)
+pll_div_add5:
+    .word CM_CLKSEL1_EMU
+pll_div_val5:
+    .word CLSEL1_EMU_VAL
+
+#endif /* OMAP3_CLOCK_COPY_SRAM */
+
+       /* the literal pools origin */
+       .ltorg
+
+/* DPLL(1-4) PARAM TABLES */
+/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal
+ * OPP (1.2V). The fields are defined according to dpll_param
+ * struct(omap3_clock.c). MAX index is as per omap3_clock.h
+ */
+
+mpu_dpll_param:
+/* 12MHz */
+/* ES2 */
+.word 0x0FA,0x05,0x07,0x01
+
+/* 13MHz */
+/* ES2 */
+.word 0x1F4,0x0C,0x03,0x01
+
+/* 19.2MHz */
+/* ES2 */
+.word 0x271,0x17,0x03,0x01
+
+/* 26MHz */
+/* ES2 */
+.word 0x0FA,0x0C,0x07,0x01
+
+/* 38.4MHz */
+/* ES2 */
+.word 0x271,0x2F,0x03,0x01
+
+.globl get_mpu_dpll_param
+get_mpu_dpll_param:
+       adr r0, mpu_dpll_param
+       mov pc, lr
+
+iva_dpll_param:
+/* 12MHz */
+/* ES2 */
+.word 0x0B4,0x05,0x07,0x01
+
+/* 13MHz */
+/* ES2 */
+.word 0x168,0x0C,0x03,0x01
+
+/* 19.2MHz */
+/* ES2 */
+.word 0x0E1,0x0B,0x06,0x01
+
+/* 26MHz */
+/* ES2 */
+.word 0x0B4,0x0C,0x07,0x01
+
+/* 38.4MHz */
+/* ES2 */
+.word 0x0E1,0x17,0x06,0x01
+
+.globl get_iva_dpll_param
+get_iva_dpll_param:
+       adr r0, iva_dpll_param
+       mov pc, lr
+
+core_dpll_param:
+/* 12MHz */
+/* ES2 */
+.word 0x0A6,0x05,0x07,0x01
+
+/* 13MHz */
+/* ES2 */
+.word 0x14C,0x0C,0x03,0x01
+
+/* 19.2MHz */
+/* ES2 */
+.word 0x19F,0x17,0x03,0x01
+
+/* 26MHz */
+/* ES2 */
+.word 0x0A6,0x0C,0x07,0x01
+
+/* 38.4MHz */
+/* ES2 */
+.word 0x19F,0x2F,0x03,0x01
+
+.globl get_core_dpll_param
+get_core_dpll_param:
+       adr r0, core_dpll_param
+       mov pc, lr
+
+/* PER DPLL values are same for both ES1 and ES2 */
+per_dpll_param:
+/* 12MHz */
+.word 0xD8,0x05,0x07,0x09
+
+/* 13MHz */
+.word 0x1B0,0x0C,0x03,0x09
+
+/* 19.2MHz */
+.word 0xE1,0x09,0x07,0x09
+
+/* 26MHz */
+.word 0xD8,0x0C,0x07,0x09
+
+/* 38.4MHz */
+.word 0xE1,0x13,0x07,0x09
+
+.globl get_per_dpll_param
+get_per_dpll_param:
+       adr r0, per_dpll_param
+       mov pc, lr
Index: u-boot.v2/arch/arm/mach-omap/s32k_clksource.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ u-boot.v2/arch/arm/mach-omap/s32k_clksource.c       2008-06-03 22:49:11.000000000 -0500
@@ -0,0 +1,80 @@
+/**
+ * @file
+ * @brief Provide @ref clocksource functionality for OMAP
+ *
+ * FileName: arch/arm/mach-omap/s32k_clksource.c
+ *
+ * @ref clocksource provides a neat architecture. all we do is
+ * To loop in with Sync 32Khz clock ticking away at 32768hz on OMAP.
+ * Sync 32Khz clock is an always ON clock.
+ *
+ */
+/*
+ * (C) Copyright 2008
+ * Texas Instruments, <www.ti.com>
+ * Nishanth Menon <x0nishan 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 <clock.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch/silicon.h>
+#include <asm/arch/clocks.h>
+#include <asm/arch/timers.h>
+#include <asm/arch/sys_info.h>
+#include <asm/arch/syslib.h>
+
+/**
+ * @brief Provide a simple clock read
+ *
+ * Nothing is simpler.. read direct from clock and provide it
+ * to the caller.
+ *
+ * @return S32K clock counter
+ */
+static uint64_t s32k_clocksource_read(void)
+{
+       return __raw_readl(S32K_CR);
+}
+
+/* A bit obvious isn't it? */
+static struct clocksource s32k_cs = {
+       .read = s32k_clocksource_read,
+       .mask = 0xffffffff,
+       .shift = 10,
+};
+
+/**
+ * @brief Initialize the Clock
+ *
+ * There is nothing to do on OMAP as SYNC32K clock is
+ * always on, and we do a simple data structure initialization.
+ * 32K clock gives 32768 ticks a seconds
+ *
+ * @return result of @ref init_clock
+ */
+static int s32k_clocksource_init(void)
+{
+       s32k_cs.mult = clocksource_hz2mult(S32K_FREQUENCY, s32k_cs.shift);
+
+       return init_clock(&s32k_cs);
+}
+
+/* Run me at boot time */
+core_initcall(s32k_clocksource_init);
Index: u-boot.v2/include/asm-arm/arch-omap/omap3-clock.h
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ u-boot.v2/include/asm-arm/arch-omap/omap3-clock.h   2008-06-03 22:49:11.000000000 -0500
@@ -0,0 +1,124 @@
+/**
+ * @file
+ * @brief Contains the PRM and CM definitions
+ *
+ * FileName: include/asm-arm/arch-omap/omap3-clock.h
+ *
+ * Originally from http://linux.omap.com/pub/bootloader/3430sdp/u-boot-v1.tar.gz
+ *
+ */
+/*
+ * (C) Copyright 2006-2008
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2 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
+ */
+#ifndef _OMAP343X_CLOCKS_H_
+#define _OMAP343X_CLOCKS_H_
+
+/** CM Clock Regs Wrapper */
+#define CM_REG(REGNAME)        (OMAP_CM_BASE + CM_##REGNAME)
+
+#define CM_FCLKEN_IVA2         0X0000
+#define CM_CLKEN_PLL_IVA2      0X0004
+#define CM_IDLEST_PLL_IVA2     0X0024
+#define CM_CLKSEL1_PLL_IVA2    0X0040
+#define CM_CLKSEL2_PLL_IVA2    0X0044
+#define CM_CLKEN_PLL_MPU       0X0904
+#define CM_IDLEST_PLL_MPU      0X0924
+#define CM_CLKSEL1_PLL_MPU     0X0940
+#define CM_CLKSEL2_PLL_MPU     0X0944
+#define CM_FCLKEN1_CORE                0X0A00
+#define CM_ICLKEN1_CORE                0X0A10
+#define CM_ICLKEN2_CORE                0X0A14
+#define CM_CLKSEL_CORE         0X0A40
+#define CM_FCLKEN_GFX          0X0B00
+#define CM_ICLKEN_GFX          0X0B10
+#define CM_CLKSEL_GFX          0X0B40
+#define CM_FCLKEN_WKUP         0X0C00
+#define CM_ICLKEN_WKUP         0X0C10
+#define CM_CLKSEL_WKUP         0X0C40
+#define CM_IDLEST_WKUP         0X0C20
+#define CM_CLKEN_PLL           0X0D00
+#define CM_IDLEST_CKGEN                0X0D20
+#define CM_CLKSEL1_PLL         0X0D40
+#define CM_CLKSEL2_PLL         0X0D44
+#define CM_CLKSEL3_PLL         0X0D48
+#define CM_FCLKEN_DSS          0X0E00
+#define CM_ICLKEN_DSS          0X0E10
+#define CM_CLKSEL_DSS          0X0E40
+#define CM_FCLKEN_CAM          0X0F00
+#define CM_ICLKEN_CAM          0X0F10
+#define CM_CLKSEL_CAM          0X0f40
+#define CM_FCLKEN_PER          0X1000
+#define CM_ICLKEN_PER          0X1010
+#define CM_CLKSEL_PER          0X1040
+#define CM_CLKSEL1_EMU         0X1140
+
+/** PRM Clock Regs */
+#define PRM_REG(REGNAME)       (OMAP_PRM_BASE + PRM_##REGNAME)
+#define PRM_CLKSEL             0x0D40
+#define PRM_RSTCTRL            0x1250
+#define PRM_CLKSRC_CTRL                0x1270
+
+/*************** Clock Values */
+#define PLL_STOP               1       /* PER & IVA */
+#define PLL_LOW_POWER_BYPASS   5       /* MPU, IVA & CORE */
+#define PLL_FAST_RELOCK_BYPASS 6       /* CORE */
+#define PLL_LOCK               7       /* MPU, IVA, CORE & PER */
+
+/* The following configurations are OPP and SysClk value independant
+ * and hence are defined here.
+ */
+
+/* CORE DPLL */
+#define CORE_M3X2              2        /* 332MHz : CM_CLKSEL1_EMU */
+#define CORE_SSI_DIV           3        /* 221MHz : CM_CLKSEL_CORE */
+#define CORE_FUSB_DIV          2        /* 41.5MHz: */
+#define CORE_L4_DIV            2        /*  83MHz : L4 */
+#define CORE_L3_DIV            2        /* 166MHz : L3 {DDR} */
+#define GFX_DIV                        2        /*  83MHz : CM_CLKSEL_GFX */
+#define WKUP_RSM               2        /* 41.5MHz: CM_CLKSEL_WKUP */
+
+/* PER DPLL */
+#define PER_M6X2               3         /* 288MHz: CM_CLKSEL1_EMU */
+#define PER_M5X2               4         /* 216MHz: CM_CLKSEL_CAM */
+#define PER_M4X2               9         /* 96MHz : CM_CLKSEL_DSS-dss1 */
+#define PER_M3X2               16        /* 54MHz : CM_CLKSEL_DSS-tv */
+
+#define CLSEL1_EMU_VAL ((CORE_M3X2 << 16) | (PER_M6X2 << 24) | (0x0a50))
+
+#define MAX_SIL_INDEX  1
+
+#ifndef __ASSEMBLY__
+void prcm_init(void);
+/* Used to index into DPLL parameter tables -See TRM for further details */
+struct dpll_param {
+       unsigned int m;
+       unsigned int n;
+       unsigned int fsel;
+       unsigned int m2;
+};
+/* External functions see omap3_clock_core.S */
+extern struct dpll_param *get_mpu_dpll_param(void);
+extern struct dpll_param *get_iva_dpll_param(void);
+extern struct dpll_param *get_core_dpll_param(void);
+extern struct dpll_param *get_per_dpll_param(void);
+
+#endif /* __ASSEMBLY__ */
+
+#endif  /* endif _OMAP343X_CLOCKS_H_ */
Index: u-boot.v2/include/asm-arm/arch-omap/clocks.h
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ u-boot.v2/include/asm-arm/arch-omap/clocks.h        2008-06-03 22:49:11.000000000 -0500
@@ -0,0 +1,48 @@
+/**
+ * @file
+ * @brief Generic Clock wrapper header.
+ *
+ * FileName: include/asm-arm/arch-omap/clocks.h
+ *
+ * This includes each of the architecture Clock definitions under it.
+ *
+ * Originally from http://linux.omap.com/pub/bootloader/3430sdp/u-boot-v1.tar.gz
+ */
+/*
+ * (C) Copyright 2006-2008
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2 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
+ */
+#ifndef __OMAP_CLOCKS_H_
+#define __OMAP_CLOCKS_H_
+
+#define LDELAY         12000000
+
+/* Standard defines for Various clocks */
+#define S12M           12000000
+#define S13M           13000000
+#define S19_2M         19200000
+#define S24M           24000000
+#define S26M           26000000
+#define S38_4M         38400000
+
+#ifdef CONFIG_ARCH_OMAP3
+#include <asm/arch/omap3-clock.h>
+#endif
+
+#endif /* __OMAP_CLOCKS_H_ */




More information about the U-Boot mailing list