powerpc/t4rdb: Add support of CPLD
authorChunhe Lan <Chunhe.Lan@freescale.com>
Fri, 12 Sep 2014 06:47:09 +0000 (14:47 +0800)
committerYork Sun <yorksun@freescale.com>
Fri, 14 Nov 2014 19:12:14 +0000 (11:12 -0800)
This support of CPLD includes

    - Files and register definitions
    - Command to switch alternate bank
    - Command to switch default bank

Signed-off-by: Chunhe Lan <Chunhe.Lan@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>
board/freescale/t4rdb/Makefile
board/freescale/t4rdb/cpld.c [new file with mode: 0644]
board/freescale/t4rdb/cpld.h [new file with mode: 0644]
board/freescale/t4rdb/law.c
board/freescale/t4rdb/t4240rdb.c
board/freescale/t4rdb/tlb.c
include/configs/T4240RDB.h

index f7f7fc01774fb4d2f88dd23859e6be671287368d..3886e3ded107136fc257bf9a5d48c797c11efe17 100644 (file)
@@ -5,6 +5,7 @@
 #
 
 obj-$(CONFIG_T4240RDB) += t4240rdb.o
+obj-y  += cpld.o
 obj-y  += ddr.o
 obj-y  += eth.o
 obj-$(CONFIG_PCI)      += pci.o
diff --git a/board/freescale/t4rdb/cpld.c b/board/freescale/t4rdb/cpld.c
new file mode 100644 (file)
index 0000000..d5f3812
--- /dev/null
@@ -0,0 +1,136 @@
+/**
+ * Copyright 2014 Freescale Semiconductor
+ *
+ * Author: Chunhe Lan <Chunhe.Lan@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * This file provides support for the board-specific CPLD used on some Freescale
+ * reference boards.
+ *
+ * The following macros need to be defined:
+ *
+ * CONFIG_SYS_CPLD_BASE - The virtual address of the base of the
+ * CPLD register map
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+
+#include "cpld.h"
+
+u8 cpld_read(unsigned int reg)
+{
+       void *p = (void *)CONFIG_SYS_CPLD_BASE;
+
+       return in_8(p + reg);
+}
+
+void cpld_write(unsigned int reg, u8 value)
+{
+       void *p = (void *)CONFIG_SYS_CPLD_BASE;
+
+       out_8(p + reg, value);
+}
+
+/**
+ * Set the boot bank to the alternate bank
+ */
+void cpld_set_altbank(void)
+{
+       u8 val, curbank, altbank, override;
+
+       val = CPLD_READ(vbank);
+       curbank = val & CPLD_BANK_SEL_MASK;
+
+       switch (curbank) {
+       case CPLD_SELECT_BANK0:
+               altbank = CPLD_SELECT_BANK4;
+               CPLD_WRITE(vbank, altbank);
+               override = CPLD_READ(software_on);
+               CPLD_WRITE(software_on, override | CPLD_BANK_SEL_EN);
+               CPLD_WRITE(sys_reset, CPLD_SYSTEM_RESET);
+               break;
+       case CPLD_SELECT_BANK4:
+               altbank = CPLD_SELECT_BANK0;
+               CPLD_WRITE(vbank, altbank);
+               override = CPLD_READ(software_on);
+               CPLD_WRITE(software_on, override | CPLD_BANK_SEL_EN);
+               CPLD_WRITE(sys_reset, CPLD_SYSTEM_RESET);
+               break;
+       default:
+               printf("CPLD Altbank Fail: Invalid value!\n");
+               return;
+       }
+}
+
+/**
+ * Set the boot bank to the default bank
+ */
+void cpld_set_defbank(void)
+{
+       u8 val;
+
+       val = CPLD_DEFAULT_BANK;
+
+       CPLD_WRITE(global_reset, val);
+}
+
+#ifdef DEBUG
+static void cpld_dump_regs(void)
+{
+       printf("chip_id1        = 0x%02x\n", CPLD_READ(chip_id1));
+       printf("chip_id2        = 0x%02x\n", CPLD_READ(chip_id2));
+       printf("sw_maj_ver      = 0x%02x\n", CPLD_READ(sw_maj_ver));
+       printf("sw_min_ver      = 0x%02x\n", CPLD_READ(sw_min_ver));
+       printf("hw_ver          = 0x%02x\n", CPLD_READ(hw_ver));
+       printf("software_on     = 0x%02x\n", CPLD_READ(software_on));
+       printf("cfg_rcw_src     = 0x%02x\n", CPLD_READ(cfg_rcw_src));
+       printf("res0            = 0x%02x\n", CPLD_READ(res0));
+       printf("vbank           = 0x%02x\n", CPLD_READ(vbank));
+       printf("sw1_sysclk      = 0x%02x\n", CPLD_READ(sw1_sysclk));
+       printf("sw2_status      = 0x%02x\n", CPLD_READ(sw2_status));
+       printf("sw3_status      = 0x%02x\n", CPLD_READ(sw3_status));
+       printf("sw4_status      = 0x%02x\n", CPLD_READ(sw4_status));
+       printf("sys_reset       = 0x%02x\n", CPLD_READ(sys_reset));
+       printf("global_reset    = 0x%02x\n", CPLD_READ(global_reset));
+       printf("res1            = 0x%02x\n", CPLD_READ(res1));
+       putc('\n');
+}
+#endif
+
+#ifndef CONFIG_SPL_BUILD
+int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       int rc = 0;
+
+       if (argc <= 1)
+               return cmd_usage(cmdtp);
+
+       if (strcmp(argv[1], "reset") == 0) {
+               if (strcmp(argv[2], "altbank") == 0)
+                       cpld_set_altbank();
+               else
+                       cpld_set_defbank();
+#ifdef DEBUG
+       } else if (strcmp(argv[1], "dump") == 0) {
+               cpld_dump_regs();
+#endif
+       } else
+               rc = cmd_usage(cmdtp);
+
+       return rc;
+}
+
+U_BOOT_CMD(
+       cpld, CONFIG_SYS_MAXARGS, 1, do_cpld,
+       "Reset the board or alternate bank",
+       "reset - reset to default bank\n"
+       "cpld reset altbank - reset to alternate bank\n"
+#ifdef DEBUG
+       "cpld dump - display the CPLD registers\n"
+#endif
+       );
+#endif
diff --git a/board/freescale/t4rdb/cpld.h b/board/freescale/t4rdb/cpld.h
new file mode 100644 (file)
index 0000000..0180082
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2014 Freescale Semiconductor
+ *
+ * Author: Chunhe Lan <Chunhe.Lan@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * This file provides support for the ngPIXIS, a board-specific FPGA used on
+ * some Freescale reference boards.
+ */
+
+/*
+ * CPLD register set. Feel free to add board-specific #ifdefs where necessary.
+ */
+struct cpld_data {
+       u8 chip_id1;    /* 0x00 - CPLD Chip ID1 Register */
+       u8 chip_id2;    /* 0x01 - CPLD Chip ID2 Register */
+       u8 sw_maj_ver;  /* 0x02 - CPLD Code Major Version Register */
+       u8 sw_min_ver;  /* 0x03 - CPLD Code Minor Version Register */
+       u8 hw_ver;      /* 0x04 - PCBA Version Register */
+       u8 software_on; /* 0x05 - Override Physical Switch Enable Register */
+       u8 cfg_rcw_src; /* 0x06 - RCW Source Location Control Register */
+       u8 res0;        /* 0x07 - not used */
+       u8 vbank;       /* 0x08 - Flash Bank Selection Control Register */
+       u8 sw1_sysclk;  /* 0x09 - SW1 Status Read Back Register */
+       u8 sw2_status;  /* 0x0a - SW2 Status Read Back Register */
+       u8 sw3_status;  /* 0x0b - SW3 Status Read Back Register */
+       u8 sw4_status;  /* 0x0c - SW4 Status Read Back Register */
+       u8 sys_reset;   /* 0x0d - Reset System With Reserving Registers Value*/
+       u8 global_reset;/* 0x0e - Reset System With Default Registers Value */
+       u8 res1;        /* 0x0f - not used */
+};
+
+#define CPLD_BANK_SEL_MASK     0x07
+#define CPLD_BANK_SEL_EN       0x04
+#define CPLD_SYSTEM_RESET      0x01
+#define CPLD_SELECT_BANK0      0x00
+#define CPLD_SELECT_BANK4      0x04
+#define CPLD_DEFAULT_BANK      0x01
+
+/* Pointer to the CPLD register set */
+
+u8 cpld_read(unsigned int reg);
+void cpld_write(unsigned int reg, u8 value);
+
+#define CPLD_READ(reg) cpld_read(offsetof(struct cpld_data, reg))
+#define CPLD_WRITE(reg, value) \
+               cpld_write(offsetof(struct cpld_data, reg), value)
+
index 1f5876885c051e18276b27faf879bf96b7645add..39818fc4f12f79a861197b342c902c09d4cedc59 100644 (file)
@@ -16,6 +16,9 @@ struct law_entry law_table[] = {
 #ifdef CONFIG_SYS_QMAN_MEM_PHYS
        SET_LAW(CONFIG_SYS_QMAN_MEM_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_QMAN),
 #endif
+#ifdef CONFIG_SYS_CPLD_BASE_PHYS
+       SET_LAW(CONFIG_SYS_CPLD_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_IFC),
+#endif
 #ifdef CONFIG_SYS_DCSRBAR_PHYS
        /* Limit DCSR to 32M to access NPC Trace Buffer */
        SET_LAW(CONFIG_SYS_DCSRBAR_PHYS, LAW_SIZE_32M, LAW_TRGT_IF_DCSR),
index afef7e93d03b6efe06d2b2c913fdff50a2d61211..2ff77b8487313d0862adbd5df93d85edd0a0fec0 100644 (file)
 #include <fm_eth.h>
 
 #include "t4rdb.h"
+#include "cpld.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
 int checkboard(void)
 {
        struct cpu_type *cpu = gd->arch.cpu;
+       u8 sw;
 
        printf("Board: %sRDB, ", cpu->name);
+       printf("Board rev: 0x%02x CPLD ver: 0x%02x%02x, ",
+              CPLD_READ(hw_ver), CPLD_READ(sw_maj_ver), CPLD_READ(sw_min_ver));
+
+       sw = CPLD_READ(vbank);
+       sw = sw & CPLD_BANK_SEL_MASK;
+
+       if (sw <= 7)
+               printf("vBank: %d\n", sw);
+       else
+               printf("Unsupported Bank=%x\n", sw);
 
        puts("SERDES Reference Clocks:\n");
        printf("       SERDES1=100MHz SERDES2=156.25MHz\n"
index 4b50bcd09b04b8d83c8167aa81279af9a855f8ef..474301e2a77e43d86adac3fa58237f2e7ee76d81 100644 (file)
@@ -106,6 +106,11 @@ struct fsl_e_tlb_entry tlb_table[] = {
                      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
                      0, 16, BOOKE_PAGESZ_64K, 1),
 #endif
+#ifdef CONFIG_SYS_CPLD_BASE
+       SET_TLB_ENTRY(1, CONFIG_SYS_CPLD_BASE, CONFIG_SYS_CPLD_BASE_PHYS,
+                     MAS3_SW|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+                     0, 17, BOOKE_PAGESZ_4K, 1),
+#endif
 };
 
 int num_tlb_entries = ARRAY_SIZE(tlb_table);
index 13f4bd3c539fae5629ec1adc374f875ec0417bdc..e639e1d57af0f5c88e15b948785593ecb33f1747 100644 (file)
@@ -514,6 +514,29 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_SYS_CS2_FTIM2           CONFIG_SYS_NOR_FTIM2
 #define CONFIG_SYS_CS2_FTIM3           CONFIG_SYS_NOR_FTIM3
 
+/* CPLD on IFC */
+#define CONFIG_SYS_CPLD_BASE   0xffdf0000
+#define CONFIG_SYS_CPLD_BASE_PHYS      (0xf00000000ull | CONFIG_SYS_CPLD_BASE)
+#define CONFIG_SYS_CSPR3_EXT   (0xf)
+#define CONFIG_SYS_CSPR3       (CSPR_PHYS_ADDR(CONFIG_SYS_CPLD_BASE_PHYS) \
+                               | CSPR_PORT_SIZE_8 \
+                               | CSPR_MSEL_GPCM \
+                               | CSPR_V)
+
+#define CONFIG_SYS_AMASK3      IFC_AMASK(4*1024)
+#define CONFIG_SYS_CSOR3       0x0
+
+/* CPLD Timing parameters for IFC CS3 */
+#define CONFIG_SYS_CS3_FTIM0           (FTIM0_GPCM_TACSE(0x0e) | \
+                                       FTIM0_GPCM_TEADC(0x0e) | \
+                                       FTIM0_GPCM_TEAHC(0x0e))
+#define CONFIG_SYS_CS3_FTIM1           (FTIM1_GPCM_TACO(0x0e) | \
+                                       FTIM1_GPCM_TRAD(0x1f))
+#define CONFIG_SYS_CS3_FTIM2           (FTIM2_GPCM_TCS(0x0e) | \
+                                       FTIM2_GPCM_TCH(0x0) | \
+                                       FTIM2_GPCM_TWP(0x1f))
+#define CONFIG_SYS_CS3_FTIM3           0x0
+
 #if defined(CONFIG_RAMBOOT_PBL)
 #define CONFIG_SYS_RAMBOOT
 #endif