summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorMichael Brandt <Michael.Brandt@stericsson.com>2009-12-18 15:38:36 +0100
committerMichael Brandt <Michael.Brandt@stericsson.com>2009-12-18 15:38:36 +0100
commit0c9ff2faf4cf516dd6631ba18a4bcc5b739eb4c6 (patch)
treeb23479244ad0ccc8ffbf9e2ae6017c418032470a /board
parent9b223555aa390e9a33ee8d4bbd2865fd1fbae9f7 (diff)
parent16bfd518590e30beddf810c004d14e09a880be74 (diff)
Merge branch 'mop500'
Diffstat (limited to 'board')
-rwxr-xr-xboard/st/u8500/config.mk15
-rwxr-xr-xboard/st/u8500/u8500.c222
2 files changed, 214 insertions, 23 deletions
diff --git a/board/st/u8500/config.mk b/board/st/u8500/config.mk
index a75eda429..a7b5c846c 100755
--- a/board/st/u8500/config.mk
+++ b/board/st/u8500/config.mk
@@ -1,5 +1,18 @@
+# mop500/href:
#
-# image should be loaded at 0x01000000
+# Valid values for TEXT_BASE are:
#
+# Standard configuration - all models
+# 0x07F8_0000 run from SDRAM
+#
+# Test configuraton
+# 0x4001_0000 run from eSRAM
+
+sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+
+ifndef TEXT_BASE
TEXT_BASE = 0x07F80000
+endif
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
diff --git a/board/st/u8500/u8500.c b/board/st/u8500/u8500.c
index 4bb94e2b9..3b8c82a96 100755
--- a/board/st/u8500/u8500.c
+++ b/board/st/u8500/u8500.c
@@ -31,11 +31,75 @@
#define NOMADIK_BACKUPRAM0_BASE (NOMADIK_PER4_BASE + 0x00000)
#define NOMADIK_BACKUPRAM1_BASE (NOMADIK_PER4_BASE + 0x01000)
-extern void (*handler)();
-extern unsigned volatile long magic_num;
+/* Power, Reset, Clock Management Unit */
+#define PRCMU_BASE CFG_PRCMU_BASE
+#define PRCM_ARMCLKFIX_MGT_REG (PRCMU_BASE + 0x000)
+#define PRCM_ACLK_MGT_REG (PRCMU_BASE + 0x004)
+#define PRCM_SVAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x008)
+#define PRCM_SIAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x00C)
+#define PRCM_SAAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x010)
+#define PRCM_SGACLK_MGT_REG (PRCMU_BASE + 0x014)
+#define PRCM_UARTCLK_MGT_REG (PRCMU_BASE + 0x018)
+#define PRCM_MSPCLK_MGT_REG (PRCMU_BASE + 0x01C)
+#define PRCM_I2CCLK_MGT_REG (PRCMU_BASE + 0x020)
+#define PRCM_SDMMCCLK_MGT_REG (PRCMU_BASE + 0x024)
+#define PRCM_SLIMCLK_MGT_REG (PRCMU_BASE + 0x028)
+#define PRCM_PER1CLK_MGT_REG (PRCMU_BASE + 0x02C)
+#define PRCM_PER2CLK_MGT_REG (PRCMU_BASE + 0x030)
+#define PRCM_PER3CLK_MGT_REG (PRCMU_BASE + 0x034)
+#define PRCM_PER5CLK_MGT_REG (PRCMU_BASE + 0x038)
+#define PRCM_PER6CLK_MGT_REG (PRCMU_BASE + 0x03C)
+#define PRCM_PER7CLK_MGT_REG (PRCMU_BASE + 0x040)
+#define PRCM_DMACLK_MGT_REG (PRCMU_BASE + 0x074)
+
+enum {
+ GATED = 0,
+ PLLSOC0, /* pllsw = 001 */
+ PLLSOC1, /* pllsw = 010 */
+ PLLDDR, /* pllsw = 100 */
+};
+
+static const char *pll_name[4] = {"GATED", "SOC0", "SOC1", "DDR"};
+static uint32_t pll_khz[4]; /* use ffs(pllsw(reg)) as index */
+
+static struct clk_mgt_regs {
+ uint32_t addr;
+ uint32_t val;
+ const char *descr;
+} clk_mgt_regs[] = {
+ /* register content taken from bootrom settings */
+ {PRCM_ARMCLKFIX_MGT_REG, 0x0120, "ARMCLKFIX"}, /* ena, SOC0/0, ??? */
+ {PRCM_ACLK_MGT_REG, 0x0125, "ACLK"}, /* ena, SOC0/5, 160 MHz */
+ {PRCM_SVAMMDSPCLK_MGT_REG, 0x1122, "SVA"}, /* ena, SOC0/2, 400 MHz */
+ {PRCM_SIAMMDSPCLK_MGT_REG, 0x0022, "SIA"}, /* dis, SOC0/2, 400 MHz */
+ {PRCM_SAAMMDSPCLK_MGT_REG, 0x0822, "SAA"}, /* dis, SOC0/4, 200 MHz */
+ {PRCM_SGACLK_MGT_REG, 0x0024, "SGA"}, /* dis, SOC0/4, 200 MHz */
+ {PRCM_UARTCLK_MGT_REG, 0x0300, "UART"}, /* ena, GATED, CLK38 */
+ {PRCM_MSPCLK_MGT_REG, 0x0200, "MSP"}, /* dis, GATED, CLK38 */
+ {PRCM_I2CCLK_MGT_REG, 0x0130, "I2C"}, /* ena, SOC0/16, 50 MHz */
+ {PRCM_SDMMCCLK_MGT_REG, 0x0130, "SDMMC"}, /* ena, SOC0/16, 50 MHz */
+ {PRCM_PER1CLK_MGT_REG, 0x126, "PER1"}, /* ena, SOC0/6, 133 MHz */
+ {PRCM_PER2CLK_MGT_REG, 0x126, "PER2"}, /* ena, SOC0/6, 133 MHz */
+ {PRCM_PER3CLK_MGT_REG, 0x126, "PER3"}, /* ena, SOC0/6, 133 MHz */
+ {PRCM_PER5CLK_MGT_REG, 0x126, "PER5"}, /* ena, SOC0/6, 133 MHz */
+ {PRCM_PER6CLK_MGT_REG, 0x126, "PER6"}, /* ena, SOC0/6, 133 MHz */
+ {PRCM_PER7CLK_MGT_REG, 0x128, "PER7"}, /* ena, SOC0/8, 100 MHz */
+ {PRCM_DMACLK_MGT_REG, 0x125, "DMA"}, /* ena, SOC0/5, 160 MHz */
+ {0, 0, NULL},
+};
+
+/* U5500 (Maja) alike clock settings */
+static struct clk_mgt_regs maja_clk_regs[] = {
+ {PRCM_SVAMMDSPCLK_MGT_REG, 0x1124, "SVA"}, /* SOC0/4, 200 MHz */
+ {PRCM_SIAMMDSPCLK_MGT_REG, 0x0024, "SIA"}, /* SOC0/6, 133 MHz */
+ {PRCM_SGACLK_MGT_REG, 0x0025, "SGA"}, /* SOC0/5, 160 MHz */
+ {0, 0, NULL},
+};
+
+extern void (*handler)();
extern void secondary_wfe();
-void wake_up_other_cores()
+void wake_up_other_cores(void)
{
handler = secondary_wfe;
*((volatile unsigned int *)(NOMADIK_BACKUPRAM0_BASE+0x1FF4))= handler;
@@ -44,7 +108,7 @@ void wake_up_other_cores()
return;
}
-void init_regs(void);
+static void init_regs(void);
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_SHOW_BOOT_PROGRESS)
@@ -54,18 +118,12 @@ void show_boot_progress(int progress)
}
#endif
-static inline void delay(unsigned long loops)
-{
- __asm__ volatile ("1:\n"
- "subs %0, %1, #1\n" "bne 1b":"=r" (loops):"0"(loops));
-}
-
/*
-* Miscellaneous platform dependent initialisations
-*/
+ * Miscellaneous platform dependent initialisations
+ */
int board_init(void)
-{
+{
gd->bd->bi_arch_number = 0x1A4;
gd->bd->bi_boot_params = 0x00000100;
//enable the timers in PRCMU reg
@@ -85,10 +143,6 @@ int misc_init_r(void)
}
#endif
-/******************************
-Routine:
-Description:
-******************************/
int dram_init(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
@@ -101,7 +155,6 @@ int dram_init(void)
return 0;
}
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
unsigned int addr_vall_arr[] = {
0x8011F000, 0x0000FFFF, // Clocks for HSI TODO Enable reqd only
0x8011F008, 0x00001C44, // Clocks for HSI TODO Enable reqd only
@@ -129,19 +182,144 @@ unsigned int addr_vall_arr[] = {
0xA03FE020, 0x00000FFF, // USB
0xA03FE024, 0x00000000 // USB
};
+
#ifdef BOARD_LATE_INIT
int board_late_init(void)
{
return (0);
}
#endif
-void init_regs(void)
-{
+
+static void init_regs(void)
+{
int i;
for(i = 0; i < ARRAY_SIZE(addr_vall_arr)/2; i++)
{
-
+
*((volatile unsigned int *)(addr_vall_arr[2 * i]))
= addr_vall_arr[(2 * i) + 1];
- }
+ }
+}
+
+/*
+ * get_pll_freq_khz - return PLL frequency in kHz
+ */
+static get_pll_freq_khz(uint32_t inclk_khz, uint32_t freq_reg)
+{
+ uint32_t idf, ldf, odf, seldiv, phi;
+
+ /*
+ * PLLOUTCLK = PHI = (INCLK*LDF)/(2*ODF*IDF) if SELDIV2=0
+ * PLLOUTCLK = PHI = (INCLK*LDF)/(4*ODF*IDF) if SELDIV2=1
+ * where:
+ * IDF=R(2:0) (when R=000, IDF=1d)
+ * LDF = 2*D(7:0) (D must be greater than or equal to 6)
+ * ODF = N(5:0) (when N=000000, 0DF=1d)
+ */
+
+ idf = (freq_reg & 0x70000) >> 16;
+ ldf = (freq_reg & 0xff) * 2;
+ odf = (freq_reg & 0x3f00) >> 8;
+ seldiv = (freq_reg & 0x01000000) >> 24;
+ phi = (inclk_khz * ldf) / (2 * odf * idf);
+ if (seldiv)
+ phi = phi/2;
+
+ return phi;
+}
+
+int do_clkinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ uint32_t inclk_khz = 38400; /* 38.4 MHz */
+ uint32_t reg, phi;
+ uint32_t val;
+ uint32_t clk_khz;
+ unsigned int clk_sel;
+ struct clk_mgt_regs *regs = clk_mgt_regs;
+
+ /* DDR PLL */
+ reg = *(uint32_t *)0x8015708C;
+ phi = get_pll_freq_khz(inclk_khz, reg);
+ pll_khz[PLLDDR] = phi;
+ printf("\nDDR PLL out frequency: %d.%d Mhz\n",
+ phi/1000, phi % 1000);
+ /* ARM PLL */
+ reg = *(uint32_t *)0x80157088;
+ phi = get_pll_freq_khz(inclk_khz, reg);
+ printf("ARM PLL out frequency: %d.%d Mhz\n",
+ phi/1000, phi % 1000);
+ reg = *(uint32_t *)0x80157114; /* PRCM_ARM_CHGCLKREQ_REG */
+ printf("A9 running on ");
+ if (reg & 1)
+ printf("external clock");
+ else
+ printf("ARM PLL");
+ printf("\n");
+
+ /* SOC0 Pll */
+ reg = *(uint32_t *)0x80157080;
+ phi = get_pll_freq_khz(inclk_khz, reg);
+ pll_khz[PLLSOC0] = phi;
+ printf("SOC0 PLL out frequency: %d.%d Mhz\n",
+ phi/1000, phi % 1000);
+
+ /* SOC1 Pll */
+ reg = *(uint32_t *)0x80157084;
+ phi = get_pll_freq_khz(inclk_khz, reg);
+ pll_khz[PLLSOC1] = phi;
+ printf("SOC1 PLL out frequency: %d.%d Mhz\n",
+ phi/1000, phi % 1000);
+ printf("\n");
+
+ /* go through list of clk_mgt_reg */
+ while (regs->addr) {
+ val = readl(regs->addr);
+ /* convert bit position into array index */
+ clk_sel = ffs((val >> 5) & 0x7); /* PLLSW[2:0] */
+ printf("%s(%08x): %08x", regs->descr, regs->addr, val);
+ printf(", PLL %s", pll_name[clk_sel]);
+ if (val & 0x200)
+ clk_khz = 38400; /* CLK38 is set */
+ else if ((val & 0x1f) == 0)
+ /* ARMCLKFIX_MGT is 0x120, e.g. div = 0 ! */
+ clk_khz = 0;
+ else
+ clk_khz = pll_khz[clk_sel] / (val & 0x1f);
+ printf(", CLK %d.%d MHz", clk_khz / 1000, clk_khz % 1000);
+ printf(", %s", (val & 0x100) ? "ena" : "dis");
+ printf("\n");
+ regs++;
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ clkinfo, 1, 1, do_clkinfo,
+ "print clock info",
+ ""
+);
+
+/*
+ * do_clkmaja - change certain register to imitate Maja performance
+ */
+int do_clkmaja(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ uint32_t val;
+ struct clk_mgt_regs *regs = maja_clk_regs;
+
+ while (regs->addr) {
+ val = readl(regs->addr);
+ printf("%s(%08x): %08x -> %08x\n", regs->descr, regs->addr,
+ val, regs->val);
+ writel(regs->val, regs->addr);
+ regs++;
+ }
}
+
+U_BOOT_CMD(
+ clkmaja, 1, 1, do_clkmaja,
+ "set some clocks maja alike",
+ ""
+);
+