summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorJustin Waters <justin.waters@timesys.com>2013-04-24 17:41:45 -0400
committerJustin Waters <justin.waters@timesys.com>2013-04-24 17:41:45 -0400
commit18282017b14c0b32b4aa6fd05df58ba5cff0b472 (patch)
tree24344ef4d64f38baee4f5b56a9b44cc775ab4b62 /arch/arm
parent75c641ece39c136001340df61f0ad57028ce4ffc (diff)
LogicPD Support for OMAP3/DM3/AM3 boards 2.2 Update
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/cpu/armv7/omap3/board.c38
-rw-r--r--arch/arm/cpu/armv7/omap3/sys_info.c82
-rw-r--r--arch/arm/include/asm/arch-omap3/cpu.h2
-rw-r--r--arch/arm/include/asm/arch-omap3/sys_proto.h3
-rw-r--r--arch/arm/lib/reset.c8
5 files changed, 129 insertions, 4 deletions
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index 18133d876d0..81df64d82a3 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -248,7 +248,7 @@ void abort(void)
/******************************************************************************
* 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 * const argv[])
+int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
struct mtd_info *mtd;
struct nand_chip *nand;
@@ -308,6 +308,42 @@ U_BOOT_CMD(
"[hw/sw/chip] - Switch between NAND hardware (hw), software (sw),\n in-chip (chip) ecc algorithm, or BCH (bch) ecc algorithm"
);
+#ifdef CONFIG_CMD_NAND_CHIP_ECC
+int do_switch_chip_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+{
+ int set, get, enable;
+
+ if (argc == 1) {
+ get = 1;
+ } else if (argc == 2) {
+ get = 0;
+ if (!strcmp(argv[1], "on"))
+ enable = 1;
+ else if (!strcmp(argv[1], "off"))
+ enable = 0;
+ else
+ goto usage;
+ }
+ set = omap_nand_switch_chip_ecc(get, enable);
+ if (set < 0) {
+ printf("NAND chip does not have internal ECC engine\n");
+ return 1;
+ }
+ if (get)
+ printf("in-chip ECC: %s\n", set?"on":"off");
+ return 0;
+
+ usage:
+ printf ("Usage: nandchip_ecc %s\n", cmdtp->usage);
+ return 1;
+}
+
+U_BOOT_CMD(
+ nandchip_ecc, 2, 1, do_switch_chip_ecc,
+ "enable/disable Micron in-chip ECC engine",
+ "[on/off] - Enable/disable in-chip ECC engine"
+);
+#endif
#endif /* CONFIG_NAND_OMAP_GPMC */
#ifdef CONFIG_DISPLAY_BOARDINFO
diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c
index 598457610f0..09bce91bba9 100644
--- a/arch/arm/cpu/armv7/omap3/sys_info.c
+++ b/arch/arm/cpu/armv7/omap3/sys_info.c
@@ -264,12 +264,88 @@ u32 get_device_type(void)
}
#ifdef CONFIG_DISPLAY_CPUINFO
+
+static int extract_sys_clk(u32 clksel)
+{
+ clksel &= 0x7;
+ switch(clksel) {
+ case 0:
+ return 12000000;
+ case 1:
+ return 13000000;
+ case 2:
+ return 19200000;
+ case 3:
+ return 26000000;
+ case 4:
+ return 38400000;
+ case 5:
+ return 16800000;
+ default:
+ return 0;
+ }
+}
+
+/* Find the speed the SDRC (in Hz) is current setup for */
+unsigned int extract_l3_ick(void)
+{
+ struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+ u32 osc_clk;
+ u32 sysclkdiv;
+ u32 fsys_clk;
+ u32 fclkout;
+ u32 l3_ick;
+ u32 fcore_clk;
+ u32 m, n, m2, div_l3;
+ u32 reg;
+
+ /* Get pk_clksel and use to find crystal speed */
+ reg = __raw_readl(PRM_CLKSEL);
+ osc_clk = extract_sys_clk(reg);
+ osc_clk /= 1000; /* Scale down by KHz to keep in scale */
+
+ /* Find sys clock divisor */
+ sysclkdiv = __raw_readl(PRM_CLKSRC_CTRL);
+ sysclkdiv >>= 6;
+ sysclkdiv &= 0x3;
+
+ fsys_clk = osc_clk / sysclkdiv;
+
+ reg = __raw_readl((u32)&prcm_base->clksel1_pll);
+ m = reg >> 16;
+ m &= 0x7ff;
+ n = reg >> 8;
+ n &= 0x7f;
+
+ fclkout = (fsys_clk * m) / (n + 1);
+
+ div_l3 = __raw_readl((u32)&prcm_base->clksel_core);
+ div_l3 &= 0x3;
+
+ l3_ick = fclkout / div_l3;
+
+ m2 = __raw_readl((u32)&prcm_base->clksel1_pll);
+ m2 >>= 27;
+ m2 &= 0x3f;
+
+ fcore_clk = fclkout / m2;
+
+#if 0
+ printf("DPLL3:\n");
+ printf("\tfclkout = (%u * %u) / (%u + 1) = %u\n", fsys_clk * 1000, m, n, fclkout * 1000);
+ printf("\tL3_ick: %u\n", l3_ick * 1000);
+ printf("\tfcore_clk: %u\n", fcore_clk * 1000);
+#endif
+ return l3_ick * 1000;
+}
+
/**
* Print CPU information
*/
int print_cpuinfo (void)
{
char *cpu_family_s, *cpu_s, *sec_s, *max_clk;
+ u32 l3_ick;
switch (get_cpu_family()) {
case CPU_OMAP34XX:
@@ -348,9 +424,11 @@ int print_cpuinfo (void)
sec_s = "?";
}
- printf("%s%s-%s ES%s, CPU-OPP2, L3-165MHz, Max CPU Clock %s\n",
+ l3_ick = extract_l3_ick() / 1000000;
+
+ printf("%s%s-%s ES%s, CPU-OPP2, L3-%uMHz, Max CPU Clock %s\n",
cpu_family_s, cpu_s, sec_s,
- rev_s[get_cpu_rev()], max_clk);
+ rev_s[get_cpu_rev()], l3_ick, max_clk);
return 0;
}
diff --git a/arch/arm/include/asm/arch-omap3/cpu.h b/arch/arm/include/asm/arch-omap3/cpu.h
index def013768c2..94f53c41b4b 100644
--- a/arch/arm/include/asm/arch-omap3/cpu.h
+++ b/arch/arm/include/asm/arch-omap3/cpu.h
@@ -417,6 +417,8 @@ struct prcm {
#endif /* __KERNEL_STRICT_NAMES */
#define PRM_BASE 0x48306000
+#define PRM_CLKSEL 0x48306d40
+#define PRM_CLKSRC_CTRL 0x48307270
#ifndef __KERNEL_STRICT_NAMES
#ifndef __ASSEMBLY__
diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h
index cb45504c228..8c4f364d01a 100644
--- a/arch/arm/include/asm/arch-omap3/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap3/sys_proto.h
@@ -70,6 +70,9 @@ enum omap_nand_ecc_mode {
OMAP_ECC_SOFT_BCH,
};
extern void omap_nand_switch_ecc(enum omap_nand_ecc_mode mode);
+#ifdef CONFIG_CMD_NAND_CHIP_ECC
+extern int omap_nand_switch_chip_ecc(int get, int enable);
+#endif
extern enum omap_nand_ecc_mode omap_nand_current_ecc_method(void);
int omap_nand_chip_has_ecc(void);
diff --git a/arch/arm/lib/reset.c b/arch/arm/lib/reset.c
index 08e6acb2615..b0f3a5eca17 100644
--- a/arch/arm/lib/reset.c
+++ b/arch/arm/lib/reset.c
@@ -38,11 +38,17 @@
*/
#include <common.h>
-
+#include <nand.h>
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
puts ("resetting ...\n");
+#ifdef CONFIG_OMAP3_LOGIC
+ /* Disable the in-chip ECC since reset doesn't cause the PoP NAND
+ * to internally reset */
+ nand_disable_in_chip_ecc();
+#endif
+
udelay (50000); /* wait 50 ms */
disable_interrupts();