p2020ds: add alternate boot bank support using the ngPIXIS FPGA
authorTimur Tabi <timur@freescale.com>
Thu, 1 Apr 2010 15:49:42 +0000 (10:49 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Wed, 7 Apr 2010 05:21:28 +0000 (00:21 -0500)
The Freescale P2020DS board uses a new type of PIXIS FPGA, called the ngPIXIS.
The ngPIXIS has one distinct new feature: the values of the on-board switches
can be selectively overridden with shadow registers.  This feature is used to
boot from a different NOR flash bank, instead of having a register dedicated
for this purpose.  Because the ngPIXIS is so different from the previous PIXIS,
a new file is introduced: ngpixis.c.

Also update the P2020DS checkboard() function to use the new macros defined
in the header file.

Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
board/freescale/common/Makefile
board/freescale/common/ngpixis.c [new file with mode: 0644]
board/freescale/common/ngpixis.h [new file with mode: 0644]
board/freescale/p2020ds/p2020ds.c
include/configs/P2020DS.h

index 02a824d9f460757138457bd4f3c6d7073cb3641a..620eb16d44159e786ec70bdc29d13bc5061cc527 100644 (file)
@@ -33,6 +33,7 @@ COBJS-${CONFIG_FSL_CADMUS}    += cadmus.o
 COBJS-${CONFIG_FSL_VIA}                += cds_via.o
 COBJS-${CONFIG_FSL_DIU_FB}     += fsl_diu_fb.o fsl_logo_bmp.o
 COBJS-${CONFIG_FSL_PIXIS}      += pixis.o
+COBJS-${CONFIG_FSL_NGPIXIS}    += ngpixis.o
 COBJS-${CONFIG_PQ_MDS_PIB}     += pq-mds-pib.o
 COBJS-${CONFIG_ID_EEPROM}      += sys_eeprom.o
 COBJS-${CONFIG_FSL_SGMII_RISER}        += sgmii_riser.o
diff --git a/board/freescale/common/ngpixis.c b/board/freescale/common/ngpixis.c
new file mode 100644 (file)
index 0000000..bb6794e
--- /dev/null
@@ -0,0 +1,136 @@
+/**
+ * Copyright 2010 Freescale Semiconductor
+ * Author: Timur Tabi <timur@freescale.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 file provides support for the ngPIXIS, a board-specific FPGA used on
+ * some Freescale reference boards.
+ *
+ * A "switch" is black rectangular block on the motherboard.  It contains
+ * eight "bits".  The ngPIXIS has a set of memory-mapped registers (SWx) that
+ * shadow the actual physical switches.  There is also another set of
+ * registers (ENx) that tell the ngPIXIS which bits of SWx should actually be
+ * used to override the values of the bits in the physical switches.
+ *
+ * The following macros need to be defined:
+ *
+ * PIXIS_BASE - The virtual address of the base of the PIXIS register map
+ *
+ * PIXIS_LBMAP_SWITCH - The switch number (i.e. the "x" in "SWx"). This value
+ *    is used in the PIXIS_SW() macro to determine which offset in
+ *    the PIXIS register map corresponds to the physical switch that controls
+ *    the boot bank.
+ *
+ * PIXIS_LBMAP_MASK - A bit mask the defines which bits in SWx to use.
+ *
+ * PIXIS_LBMAP_SHIFT - The shift value that corresponds to PIXIS_LBMAP_MASK.
+ *
+ * PIXIS_LBMAP_ALTBANK - The value to program into SWx to tell the ngPIXIS to
+ *    boot from the alternate bank.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <watchdog.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+
+#include "ngpixis.h"
+
+/*
+ * Reset the board. This ignores the ENx registers.
+ */
+void pixis_reset(void)
+{
+       out_8(&pixis->rst, 0);
+
+       while (1);
+}
+
+/*
+ * Reset the board.  Like pixis_reset(), but it honors the ENx registers.
+ */
+void pixis_bank_reset(void)
+{
+       out_8(&pixis->vctl, 0);
+       out_8(&pixis->vctl, 1);
+
+       while (1);
+}
+
+/**
+ * Set the boot bank to the power-on default bank
+ */
+void clear_altbank(void)
+{
+       /* Tell the ngPIXIS to use this the bits in the physical switch for the
+        * boot bank value, instead of the SWx register.  We need to be careful
+        * only to set the bits in SWx that correspond to the boot bank.
+        */
+       clrbits_8(&PIXIS_EN(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK);
+}
+
+/**
+ * Set the boot bank to the alternate bank
+ */
+void set_altbank(void)
+{
+       /* Program the alternate bank number into the SWx register.
+        */
+       clrsetbits_8(&PIXIS_SW(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK,
+                    PIXIS_LBMAP_ALTBANK);
+
+       /* Tell the ngPIXIS to use this the bits in the SWx register for the
+        * boot bank value, instead of the physical switch.  We need to be
+        * careful only to set the bits in SWx that correspond to the boot bank.
+        */
+       setbits_8(&PIXIS_EN(PIXIS_LBMAP_SWITCH), PIXIS_LBMAP_MASK);
+}
+
+
+int pixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       unsigned int i;
+       char *p_altbank = NULL;
+       char *unknown_param = NULL;
+
+       /* No args is a simple reset request.
+        */
+       if (argc <= 1)
+               pixis_reset();
+
+       for (i = 1; i < argc; i++) {
+               if (strcmp(argv[i], "altbank") == 0) {
+                       p_altbank = argv[i];
+                       continue;
+               }
+
+               unknown_param = argv[i];
+       }
+
+       if (unknown_param) {
+               printf("Invalid option: %s\n", unknown_param);
+               return 1;
+       }
+
+       if (p_altbank)
+               set_altbank();
+       else
+               clear_altbank();
+
+       pixis_bank_reset();
+
+       /* Shouldn't be reached. */
+       return 0;
+}
+
+U_BOOT_CMD(
+       pixis_reset, CONFIG_SYS_MAXARGS, 1, pixis_reset_cmd,
+       "Reset the board using the FPGA sequencer",
+       "- hard reset to default bank\n"
+       "pixis_reset altbank - reset to alternate bank\n"
+       );
diff --git a/board/freescale/common/ngpixis.h b/board/freescale/common/ngpixis.h
new file mode 100644 (file)
index 0000000..284d044
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2010 Freescale Semiconductor
+ * Author: Timur Tabi <timur@freescale.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 file provides support for the ngPIXIS, a board-specific FPGA used on
+ * some Freescale reference boards.
+ */
+
+/* ngPIXIS register set. Hopefully, this won't change too much over time.
+ * Feel free to add board-specific #ifdefs where necessary.
+ */
+typedef struct ngpixis {
+       u8 id;
+       u8 arch;
+       u8 scver;
+       u8 csr;
+       u8 rst;
+       u8 res1;
+       u8 aux;
+       u8 spd;
+       u8 brdcfg0;
+       u8 dma;
+       u8 addr;
+       u8 res2[2];
+       u8 data;
+       u8 led;
+       u8 res3;
+       u8 vctl;
+       u8 vstat;
+       u8 vcfgen0;
+       u8 res4;
+       u8 ocmcsr;
+       u8 ocmmsg;
+       u8 gmdbg;
+       u8 res5[2];
+       u8 sclk[3];
+       u8 dclk[3];
+       u8 watch;
+       struct {
+               u8 sw;
+               u8 en;
+       } s[8];
+} ngpixis_t  __attribute__ ((aligned(1)));
+
+/* Pointer to the PIXIS register set */
+#define pixis ((ngpixis_t *)PIXIS_BASE)
+
+/* The PIXIS SW register that corresponds to board switch X, where x >= 1 */
+#define PIXIS_SW(x)            (pixis->s[(x) - 1].sw)
+
+/* The PIXIS EN register that corresponds to board switch X, where x >= 1 */
+#define PIXIS_EN(x)            (pixis->s[(x) - 1].en)
index 664135cf703d47aa1d6e175bff8029885798b849..f0ff209c0c28764a1906e02ba2a71b9fb656ec58 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/mp.h>
 #include <netdev.h>
 
+#include "../common/ngpixis.h"
 #include "../common/sgmii_riser.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -46,30 +47,24 @@ phys_size_t fixed_sdram(void);
 
 int checkboard(void)
 {
-       u8 sw7;
-       u8 *pixis_base = (u8 *)PIXIS_BASE;
+       u8 sw;
 
        puts("Board: P2020DS ");
 #ifdef CONFIG_PHYS_64BIT
        puts("(36-bit addrmap) ");
 #endif
 
-       printf("Sys ID: 0x%02x, "
-               "Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
-               in_8(pixis_base + PIXIS_ID), in_8(pixis_base + PIXIS_VER),
-               in_8(pixis_base + PIXIS_PVER));
+       printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
+               in_8(&pixis->id), in_8(&pixis->arch), in_8(&pixis->scver));
 
-       sw7 = in_8(pixis_base + PIXIS_SW(7));
-       switch ((sw7 & PIXIS_SW7_LBMAP) >> 6) {
-               case 0:
-               case 1:
-                       printf ("vBank: %d\n", ((sw7 & PIXIS_SW7_VBANK) >> 4));
-                       break;
-               case 2:
-               case 3:
-                       puts ("Promjet\n");
-                       break;
-       }
+       sw = in_8(&PIXIS_SW(PIXIS_LBMAP_SWITCH));
+       sw = (sw & PIXIS_LBMAP_MASK) >> PIXIS_LBMAP_SHIFT;
+
+       if (sw < 0x8)
+               /* The lower two bits are the actual vbank number */
+               printf("vBank: %d\n", sw & 3);
+       else
+               puts("Promjet\n");
 
        return 0;
 }
@@ -370,30 +365,22 @@ unsigned long get_board_ddr_clk(ulong dummy)
        return gd->mem_clk;
 }
 
-unsigned long
-calculate_board_sys_clk(ulong dummy)
+unsigned long calculate_board_sys_clk(ulong dummy)
 {
        ulong val;
-       u8 *pixis_base = (u8 *)PIXIS_BASE;
 
-       val = ics307_clk_freq(
-           in_8(pixis_base + PIXIS_VSYSCLK0),
-           in_8(pixis_base + PIXIS_VSYSCLK1),
-           in_8(pixis_base + PIXIS_VSYSCLK2));
+       val = ics307_clk_freq(in_8(&pixis->sclk[0]), in_8(&pixis->sclk[1]),
+                             in_8(&pixis->sclk[2]));
        debug("sysclk val = %lu\n", val);
        return val;
 }
 
-unsigned long
-calculate_board_ddr_clk(ulong dummy)
+unsigned long calculate_board_ddr_clk(ulong dummy)
 {
        ulong val;
-       u8 *pixis_base = (u8 *)PIXIS_BASE;
 
-       val = ics307_clk_freq(
-           in_8(pixis_base + PIXIS_VDDRCLK0),
-           in_8(pixis_base + PIXIS_VDDRCLK1),
-           in_8(pixis_base + PIXIS_VDDRCLK2));
+       val = ics307_clk_freq(in_8(&pixis->dclk[0]), in_8(&pixis->dclk[1]),
+                             in_8(&pixis->dclk[2]));
        debug("ddrclk val = %lu\n", val);
        return val;
 }
@@ -402,9 +389,8 @@ unsigned long get_board_sys_clk(ulong dummy)
 {
        u8 i;
        ulong val = 0;
-       u8 *pixis_base = (u8 *)PIXIS_BASE;
 
-       i = in_8(pixis_base + PIXIS_SPD);
+       i = in_8(&pixis->spd);
        i &= 0x07;
 
        switch (i) {
@@ -441,9 +427,8 @@ unsigned long get_board_ddr_clk(ulong dummy)
 {
        u8 i;
        ulong val = 0;
-       u8 *pixis_base = (u8 *)PIXIS_BASE;
 
-       i = in_8(pixis_base + PIXIS_SPD);
+       i = in_8(&pixis->spd);
        i &= 0x38;
        i >>= 3;
 
index 30a5a319bcc634719a4afaba451447e8585b5e9b..66be725c8a045a55441d7215d7f23504fec7ea2c 100644 (file)
@@ -238,7 +238,9 @@ extern unsigned long calculate_board_ddr_clk(unsigned long dummy);
 
 #define CONFIG_BOARD_EARLY_INIT_R      /* call board_early_init_r function */
 
-#define CONFIG_FSL_PIXIS       1       /* use common PIXIS code */
+#define CONFIG_FSL_NGPIXIS             /* use common ngPIXIS code */
+
+#ifdef CONFIG_FSL_NGPIXIS
 #define PIXIS_BASE     0xffdf0000      /* PIXIS registers */
 #ifdef CONFIG_PHYS_64BIT
 #define PIXIS_BASE_PHYS        0xfffdf0000ull
@@ -249,59 +251,11 @@ extern unsigned long calculate_board_ddr_clk(unsigned long dummy);
 #define CONFIG_SYS_BR3_PRELIM  (BR_PHYS_ADDR(PIXIS_BASE_PHYS) | BR_PS_8 | BR_V)
 #define CONFIG_SYS_OR3_PRELIM          0xffffeff7      /* 32KB but only 4k mapped */
 
-#define PIXIS_ID               0x0     /* Board ID at offset 0 */
-#define PIXIS_VER              0x1     /* Board version at offset 1 */
-#define PIXIS_PVER             0x2     /* PIXIS FPGA version at offset 2 */
-#define PIXIS_CSR              0x3     /* PIXIS General control/status register */
-#define PIXIS_RST              0x4     /* PIXIS Reset Control register */
-#define PIXIS_PWR              0x5     /* PIXIS Power status register */
-#define PIXIS_AUX              0x6     /* Auxiliary 1 register */
-#define PIXIS_SPD              0x7     /* Register for SYSCLK speed */
-#define PIXIS_AUX2             0x8     /* Auxiliary 2 register */
-#define PIXIS_VCTL             0x10    /* VELA Control Register */
-#define PIXIS_VSTAT            0x11    /* VELA Status Register */
-#define PIXIS_VCFGEN0          0x12    /* VELA Config Enable 0 */
-#define PIXIS_VCFGEN1          0x13    /* VELA Config Enable 1 */
-#define PIXIS_VCORE0           0x14    /* VELA VCORE0 Register */
-#define PIXIS_VBOOT            0x16    /* VELA VBOOT Register */
-#define PIXIS_VSPEED0          0x17    /* VELA VSpeed 0 */
-#define PIXIS_VSPEED1          0x18    /* VELA VSpeed 1 */
-#define PIXIS_VSPEED2          0x19    /* VELA VSpeed 2 */
-#define PIXIS_VSYSCLK0         0x19    /* VELA SYSCLK0 Register */
-#define PIXIS_VSYSCLK1         0x1A    /* VELA SYSCLK1 Register */
-#define PIXIS_VSYSCLK2         0x1B    /* VELA SYSCLK2 Register */
-#define PIXIS_VDDRCLK0         0x1C    /* VELA DDRCLK0 Register */
-#define PIXIS_VDDRCLK1         0x1D    /* VELA DDRCLK1 Register */
-#define PIXIS_VDDRCLK2         0x1E    /* VELA DDRCLK2 Register */
-
-#define PIXIS_VWATCH           0x24    /* Watchdog Register */
-#define PIXIS_LED              0x25    /* LED Register */
-
-#define PIXIS_SW(x)            0x20 + (x - 1) * 2
-#define PIXIS_EN(x)            0x21 + (x - 1) * 2
-#define PIXIS_SW7_LBMAP                0xc0    /* SW7 - cfg_lbmap */
-#define PIXIS_SW7_VBANK                0x30    /* SW7 - cfg_vbank */
-
-/* old pixis referenced names */
-#define PIXIS_VCLKH            0x19    /* VELA VCLKH register */
-#define PIXIS_VCLKL            0x1A    /* VELA VCLKL register */
-#define CONFIG_SYS_PIXIS_VBOOT_MASK    0xc0
-#define PIXIS_VSPEED2_TSEC1SER 0x8
-#define PIXIS_VSPEED2_TSEC2SER 0x4
-#define PIXIS_VSPEED2_TSEC3SER 0x2
-#define PIXIS_VSPEED2_TSEC4SER 0x1
-#define PIXIS_VCFGEN1_TSEC1SER 0x20
-#define PIXIS_VCFGEN1_TSEC2SER 0x20
-#define PIXIS_VCFGEN1_TSEC3SER 0x20
-#define PIXIS_VCFGEN1_TSEC4SER 0x20
-#define PIXIS_VSPEED2_MASK     (PIXIS_VSPEED2_TSEC1SER \
-                                       | PIXIS_VSPEED2_TSEC2SER \
-                                       | PIXIS_VSPEED2_TSEC3SER \
-                                       | PIXIS_VSPEED2_TSEC4SER)
-#define PIXIS_VCFGEN1_MASK     (PIXIS_VCFGEN1_TSEC1SER \
-                                       | PIXIS_VCFGEN1_TSEC2SER \
-                                       | PIXIS_VCFGEN1_TSEC3SER \
-                                       | PIXIS_VCFGEN1_TSEC4SER)
+#define PIXIS_LBMAP_SWITCH     7
+#define PIXIS_LBMAP_MASK       0xf0
+#define PIXIS_LBMAP_SHIFT      4
+#define PIXIS_LBMAP_ALTBANK    0x20
+#endif
 
 #define CONFIG_SYS_INIT_RAM_LOCK       1
 #define CONFIG_SYS_INIT_RAM_ADDR       0xffd00000      /* Initial L1 address */