#include <pkgconf/system.h>
#include CYGBLD_HAL_PLATFORM_H
-#include <cyg/infra/cyg_type.h> // base types
-#include <cyg/infra/cyg_trac.h> // tracing macros
-#include <cyg/infra/cyg_ass.h> // assertion macros
+#include <cyg/infra/cyg_type.h> // base types
+#include <cyg/infra/cyg_trac.h> // tracing macros
+#include <cyg/infra/cyg_ass.h> // assertion macros
-#include <cyg/hal/hal_misc.h> // Size constants
-#include <cyg/hal/hal_io.h> // IO macros
-#include <cyg/hal/hal_arch.h> // Register state info
+#include <cyg/hal/hal_misc.h> // Size constants
+#include <cyg/hal/hal_io.h> // IO macros
+#include <cyg/hal/hal_arch.h> // Register state info
#include <cyg/hal/hal_diag.h>
-#include <cyg/hal/hal_intr.h> // Interrupt names
-#include <cyg/hal/hal_cache.h> // Cache control
-#include <cyg/hal/hal_soc.h> // Hardware definitions
-#include <cyg/hal/hal_mm.h> // MMap table definitions
+#include <cyg/hal/hal_intr.h> // Interrupt names
+#include <cyg/hal/hal_cache.h> // Cache control
+#include <cyg/hal/hal_soc.h> // Hardware definitions
+#include <cyg/hal/hal_mm.h> // MMap table definitions
-#include <cyg/infra/diag.h> // diag_printf
+#include <cyg/infra/diag.h> // diag_printf
+#include <cyg/io/imx_nfc.h>
// Most initialization has already been done before we get here.
// All we do here is set up the interrupt environment.
externC void plf_hardware_init(void);
-#define IIM_PROD_REV_SH 3
-#define IIM_PROD_REV_LEN 5
-#define IIM_SREV_REV_SH 4
-#define IIM_SREV_REV_LEN 4
+#define IIM_PROD_REV_SH 3
+#define IIM_PROD_REV_LEN 5
+#define IIM_SREV_REV_SH 4
+#define IIM_SREV_REV_LEN 4
-#define PROD_SIGNATURE_MX25 0x1
+#define PROD_SIGNATURE_MX25 0x1F
-#define PROD_SIGNATURE_SUPPORTED_1 PROD_SIGNATURE_MX25
+#define PROD_SIGNATURE_SUPPORTED_1 PROD_SIGNATURE_MX25
-#define CHIP_VERSION_NONE 0xFFFFFFFF // invalid product ID
-#define CHIP_VERSION_UNKNOWN 0xDEADBEEF // invalid chip rev
+#define CHIP_VERSION_NONE 0xFFFFFFFF // invalid product ID
+#define CHIP_VERSION_UNKNOWN 0xDEADBEEF // invalid chip rev
-#define PART_NUMBER_OFFSET (12)
-#define MAJOR_NUMBER_OFFSET (4)
-#define MINOR_NUMBER_OFFSET (0)
+#define PART_NUMBER_OFFSET 12
+#define MAJOR_NUMBER_OFFSET 4
+#define MINOR_NUMBER_OFFSET 0
/*
* System_rev will have the following format
*/
unsigned int system_rev = CHIP_REV_1_0;
static int find_correct_chip;
-extern char HAL_PLATFORM_EXTRA[55];
/*
* This functions reads the IIM module and returns the system revision number.
* It returns the IIM silicon revision reg value if valid product rev is found.
- . Otherwise, it returns -1.
+ * Otherwise, it returns CHIP_VERSION_NONE.
*/
static int read_system_rev(void)
{
- int val;
+ int val;
- val = readl(IIM_BASE_ADDR + IIM_PREV_OFF);
+ val = readl(IIM_BASE_ADDR + IIM_PREV_OFF);
- system_rev = 0x25 << PART_NUMBER_OFFSET; /* For MX25 Platform*/
- /* If the IIM doesn't contain valid product signature, return
- * the lowest revision number */
- if ((MXC_GET_FIELD(val, IIM_PROD_REV_LEN, IIM_PROD_REV_SH) !=
- PROD_SIGNATURE_SUPPORTED_1)) {
- return CHIP_VERSION_NONE;
- }
+ system_rev = 0x25 << PART_NUMBER_OFFSET; /* For MX25 Platform*/
+ /* If the IIM doesn't contain a valid product signature, return
+ * the lowest revision number */
+ if ((MXC_GET_FIELD(val, IIM_PROD_REV_LEN, IIM_PROD_REV_SH) !=
+ PROD_SIGNATURE_SUPPORTED_1)) {
+ return CHIP_VERSION_NONE;
+ }
- /* Now trying to retrieve the silicon rev from IIM's SREV register */
- return readl(IIM_BASE_ADDR + IIM_SREV_OFF);
+ /* Now trying to retrieve the silicon rev from IIM's SREV register */
+ return readl(IIM_BASE_ADDR + IIM_SREV_OFF);
}
extern nfc_setup_func_t *nfc_setup;
unsigned int mxc_nfc_soc_setup(unsigned int pg_sz, unsigned int io_sz,
- unsigned int is_mlc, unsigned int num_of_chips);
+ unsigned int is_mlc, unsigned int num_of_chips);
void hal_hardware_init(void)
{
- int ver;
-
- ver = read_system_rev();
- find_correct_chip = ver;
-
- // Mask all interrupts
- writel(0xFFFFFFFF, ASIC_NIMASK);
-
- // Make all interrupts do IRQ and not FIQ
- // FIXME: Change this if you use FIQs.
- writel(0, ASIC_INTTYPEH);
- writel(0, ASIC_INTTYPEL);
-
- // Enable caches
- HAL_ICACHE_ENABLE();
- HAL_DCACHE_ENABLE();
-
- // enable EPIT and start it with 32KHz input clock
- writel(0x00010000, EPIT_BASE_ADDR + EPITCR);
-
- // make sure reset is complete
- while ((readl(EPIT_BASE_ADDR + EPITCR) & 0x10000) != 0) {
- }
-
- writel(0x030E0002, EPIT_BASE_ADDR + EPITCR);
- writel(0x030E0003, EPIT_BASE_ADDR + EPITCR);
-
- writel(0, EPIT_BASE_ADDR + EPITCMPR); // always compare with 0
-
- if ((readw(WDOG_BASE_ADDR) & 4) != 0) {
- // increase the WDOG timeout value to the max
- writew(readw(WDOG_BASE_ADDR) | 0xFF00, WDOG_BASE_ADDR);
- }
-
- // Perform any platform specific initializations
- plf_hardware_init();
-
- // Set up eCos/ROM interfaces
- hal_if_init();
-
- nfc_setup = (nfc_setup_func_t*)mxc_nfc_soc_setup;
+ int ver;
+
+ ver = read_system_rev();
+ find_correct_chip = ver;
+
+ if (ver != CHIP_VERSION_NONE) {
+ /* Valid product revision found. Check actual silicon rev from the ROM code. */
+ if (ver == 0x0) {
+ HAL_PLATFORM_EXTRA[5] = '1';
+ HAL_PLATFORM_EXTRA[7] = '0';
+ system_rev |= 1 << MAJOR_NUMBER_OFFSET;
+ system_rev |= 0 << MINOR_NUMBER_OFFSET;
+ } else if (ver == 0x1) {
+ HAL_PLATFORM_EXTRA[5] = '1';
+ HAL_PLATFORM_EXTRA[7] = '1';
+ system_rev |= 1 << MAJOR_NUMBER_OFFSET;
+ system_rev |= 1 << MINOR_NUMBER_OFFSET;
+ } else if (ver == 0x2) {
+ HAL_PLATFORM_EXTRA[5] = '1';
+ HAL_PLATFORM_EXTRA[7] = '1';
+ system_rev |= 1 << MAJOR_NUMBER_OFFSET;
+ system_rev |= 2 << MINOR_NUMBER_OFFSET;
+ } else {
+ HAL_PLATFORM_EXTRA[5] = '-';
+ HAL_PLATFORM_EXTRA[7] = '-';
+ system_rev |= 1 << MAJOR_NUMBER_OFFSET;
+ system_rev |= 0 << MINOR_NUMBER_OFFSET;
+ find_correct_chip = CHIP_VERSION_UNKNOWN;
+ }
+ }
+
+ // Mask all interrupts
+ writel(0xFFFFFFFF, ASIC_NIMASK);
+
+ // Make all interrupts do IRQ and not FIQ
+ // FIXME: Change this if you use FIQs.
+ writel(0, ASIC_INTTYPEH);
+ writel(0, ASIC_INTTYPEL);
+
+ // Enable caches
+ HAL_ICACHE_ENABLE();
+ HAL_DCACHE_ENABLE();
+
+ // enable EPIT and start it with 32KHz input clock
+ writel(0x00010000, EPIT_BASE_ADDR + EPITCR);
+
+ // make sure reset is complete
+ while ((readl(EPIT_BASE_ADDR + EPITCR) & 0x10000) != 0) {
+ }
+
+ writel(0x030E0002, EPIT_BASE_ADDR + EPITCR);
+ writel(0x030E0003, EPIT_BASE_ADDR + EPITCR);
+
+ writel(0, EPIT_BASE_ADDR + EPITCMPR); // always compare with 0
+
+ if ((readw(WDOG_BASE_ADDR) & 4) != 0) {
+ // increase the WDOG timeout value to the max
+ writew(readw(WDOG_BASE_ADDR) | 0xFF00, WDOG_BASE_ADDR);
+ }
+
+ // Perform any platform specific initializations
+ plf_hardware_init();
+
+ // Set up eCos/ROM interfaces
+ hal_if_init();
+
+ nfc_setup = (nfc_setup_func_t*)mxc_nfc_soc_setup;
}
// -------------------------------------------------------------------------
unsigned int hal_timer_count(void)
{
- return (0xFFFFFFFF - readl(EPIT_BASE_ADDR + EPITCNR));
+ return 0 - readl(EPIT_BASE_ADDR + EPITCNR);
}
-#define WDT_MAGIC_1 0x5555
-#define WDT_MAGIC_2 0xAAAA
-#define MXC_WDT_WSR 0x2
+#define WDT_MAGIC_1 0x5555
+#define WDT_MAGIC_2 0xAAAA
+#define MXC_WDT_WSR 0x2
unsigned int i2c_base_addr[] = {
- I2C_BASE_ADDR,
- I2C2_BASE_ADDR,
- I2C3_BASE_ADDR
+ I2C_BASE_ADDR,
+ I2C2_BASE_ADDR,
+ I2C3_BASE_ADDR
};
unsigned int i2c_num = 3;
static unsigned int led_on = 0;
//
-// Delay for some number of micro-seconds
+// Delay for some number of microseconds
//
void hal_delay_us(unsigned int usecs)
{
- /*
- * This causes overflow.
- * unsigned int delayCount = (usecs * 32000) / 1000000;
- * So use the following one instead
- */
- unsigned int delayCount = (usecs*4 + 124) / 125;
-
- if (delayCount == 0) {
- return;
- }
-
- // issue the service sequence instructions
- if ((readw(WDOG_BASE_ADDR) & 4) != 0) {
- writew(WDT_MAGIC_1, WDOG_BASE_ADDR + MXC_WDT_WSR);
- writew(WDT_MAGIC_2, WDOG_BASE_ADDR + MXC_WDT_WSR);
- }
-
- writel(0x01, EPIT_BASE_ADDR + EPITSR); // clear the compare status bit
-
- writel(delayCount, EPIT_BASE_ADDR + EPITLR);
-
- while ((0x1 & readl(EPIT_BASE_ADDR + EPITSR)) == 0); // return until compare bit is set
- if ((++led_on % 2000) == 0)
- BOARD_DEBUG_LED(0);
+ /*
+ * This causes overflow.
+ * unsigned int delayCount = (usecs * 32000) / 1000000;
+ * So use the following one instead
+ */
+ unsigned int delayCount = (usecs * 512) / 16000;
+
+ if (delayCount == 0) {
+ return;
+ }
+
+ // issue the service sequence instructions
+ if ((readw(WDOG_BASE_ADDR) & 4) != 0) {
+ writew(WDT_MAGIC_1, WDOG_BASE_ADDR + MXC_WDT_WSR);
+ writew(WDT_MAGIC_2, WDOG_BASE_ADDR + MXC_WDT_WSR);
+ }
+
+ writel(0x01, EPIT_BASE_ADDR + EPITSR); // clear the compare status bit
+
+ writel(delayCount, EPIT_BASE_ADDR + EPITLR);
+
+ while ((0x1 & readl(EPIT_BASE_ADDR + EPITSR)) == 0); // return until compare bit is set
+ if ((++led_on % 2000) == 0)
+ BOARD_DEBUG_LED(0);
}
// -------------------------------------------------------------------------
int hal_IRQ_handler(void)
{
#ifdef HAL_EXTENDED_IRQ_HANDLER
- cyg_uint32 index;
+ cyg_uint32 index;
- // Use platform specific IRQ handler, if defined
- // Note: this macro should do a 'return' with the appropriate
- // interrupt number if such an extended interrupt exists. The
- // assumption is that the line after the macro starts 'normal' processing.
- HAL_EXTENDED_IRQ_HANDLER(index);
+ // Use platform specific IRQ handler, if defined
+ // Note: this macro should do a 'return' with the appropriate
+ // interrupt number if such an extended interrupt exists. The
+ // assumption is that the line after the macro starts 'normal' processing.
+ HAL_EXTENDED_IRQ_HANDLER(index);
#endif
- return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
+ return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
}
//
{
// diag_printf("6hal_interrupt_mask(vector=%d) \n", vector);
#ifdef HAL_EXTENDED_INTERRUPT_MASK
- // Use platform specific handling, if defined
- // Note: this macro should do a 'return' for "extended" values of 'vector'
- // Normal vectors are handled by code subsequent to the macro call.
- HAL_EXTENDED_INTERRUPT_MASK(vector);
+ // Use platform specific handling, if defined
+ // Note: this macro should do a 'return' for "extended" values of 'vector'
+ // Normal vectors are handled by code subsequent to the macro call.
+ HAL_EXTENDED_INTERRUPT_MASK(vector);
#endif
}
// diag_printf("7hal_interrupt_unmask(vector=%d) \n", vector);
#ifdef HAL_EXTENDED_INTERRUPT_UNMASK
- // Use platform specific handling, if defined
- // Note: this macro should do a 'return' for "extended" values of 'vector'
- // Normal vectors are handled by code subsequent to the macro call.
- HAL_EXTENDED_INTERRUPT_UNMASK(vector);
+ // Use platform specific handling, if defined
+ // Note: this macro should do a 'return' for "extended" values of 'vector'
+ // Normal vectors are handled by code subsequent to the macro call.
+ HAL_EXTENDED_INTERRUPT_UNMASK(vector);
#endif
}
// diag_printf("8hal_interrupt_acknowledge(vector=%d) \n", vector);
#ifdef HAL_EXTENDED_INTERRUPT_UNMASK
- // Use platform specific handling, if defined
- // Note: this macro should do a 'return' for "extended" values of 'vector'
- // Normal vectors are handled by code subsequent to the macro call.
- HAL_EXTENDED_INTERRUPT_ACKNOWLEDGE(vector);
+ // Use platform specific handling, if defined
+ // Note: this macro should do a 'return' for "extended" values of 'vector'
+ // Normal vectors are handled by code subsequent to the macro call.
+ HAL_EXTENDED_INTERRUPT_ACKNOWLEDGE(vector);
#endif
}
{
#ifdef HAL_EXTENDED_INTERRUPT_CONFIGURE
- // Use platform specific handling, if defined
- // Note: this macro should do a 'return' for "extended" values of 'vector'
- // Normal vectors are handled by code subsequent to the macro call.
- HAL_EXTENDED_INTERRUPT_CONFIGURE(vector, level, up);
+ // Use platform specific handling, if defined
+ // Note: this macro should do a 'return' for "extended" values of 'vector'
+ // Normal vectors are handled by code subsequent to the macro call.
+ HAL_EXTENDED_INTERRUPT_CONFIGURE(vector, level, up);
#endif
}
{
#ifdef HAL_EXTENDED_INTERRUPT_SET_LEVEL
- // Use platform specific handling, if defined
- // Note: this macro should do a 'return' for "extended" values of 'vector'
- // Normal vectors are handled by code subsequent to the macro call.
- HAL_EXTENDED_INTERRUPT_SET_LEVEL(vector, level);
+ // Use platform specific handling, if defined
+ // Note: this macro should do a 'return' for "extended" values of 'vector'
+ // Normal vectors are handled by code subsequent to the macro call.
+ HAL_EXTENDED_INTERRUPT_SET_LEVEL(vector, level);
#endif
- // Interrupt priorities are not configurable.
+ // Interrupt priorities are not configurable.
}
-unsigned int mxc_nfc_soc_setup(unsigned int pg_sz, unsigned int io_sz, unsigned int is_mlc, unsigned int num_of_chips)
+unsigned int mxc_nfc_soc_setup(unsigned int pg_sz, unsigned int io_sz, unsigned int is_mlc,
+ unsigned int num_of_chips)
{
- unsigned int tmp ;
- if (is_mlc) {
- tmp = readw(NAND_REG_BASE + NAND_FLASH_CONFIG1_REG_OFF) | (1 << 8);
- } else {
- tmp = readw(NAND_REG_BASE + NAND_FLASH_CONFIG1_REG_OFF) & (~(1 << 8));
- }
-
- writew(tmp, NAND_REG_BASE + NAND_FLASH_CONFIG1_REG_OFF);
- tmp = readl(CCM_BASE_ADDR + CLKCTL_RCSR);
- if (io_sz == 16) {
- tmp |= (1 << 14);
- } else {
- tmp &= (~(1 << 14));
- }
-
- tmp &= ~(3<<8);
- switch(pg_sz = 2048){
- case 2048:
- tmp |= (1<<8);
- break;
- case 4096:
- tmp |= (1<<9);
- break;
- }
-
- writel(tmp, CCM_BASE_ADDR + CLKCTL_RCSR);
- diag_printf("NAND: RCSR=%x\n", tmp);
- return 0x10;
+ unsigned int tmp ;
+ if (is_mlc) {
+ tmp = readw(NAND_REG_BASE + NAND_FLASH_CONFIG1_REG_OFF) | (1 << 8);
+ } else {
+ tmp = readw(NAND_REG_BASE + NAND_FLASH_CONFIG1_REG_OFF) & ~(1 << 8);
+ }
+
+ writew(tmp, NAND_REG_BASE + NAND_FLASH_CONFIG1_REG_OFF);
+ tmp = readl(CCM_BASE_ADDR + CLKCTL_RCSR);
+ if (io_sz == 16) {
+ tmp |= (1 << 14);
+ } else {
+ tmp &= ~(1 << 14);
+ }
+
+ tmp &= ~(3<<8);
+ switch (pg_sz) {
+ case 2048:
+ tmp |= (1<<8);
+ break;
+ case 4096:
+ tmp |= (1<<9);
+ break;
+ }
+
+ writel(tmp, CCM_BASE_ADDR + CLKCTL_RCSR);
+ return MXC_NFC_V1_1;
}
+#define WDOG_WRSR ((CYG_WORD16 *)(WDOG_BASE_ADDR + 0x4))
+#define CRM_RCSR ((CYG_WORD32 *)(CCM_BASE_ADDR + 0x28))
+
static void check_reset_source(void)
{
+#if 1
+ char *reset_cause = "UNKNOWN";
+ CYG_WORD16 wrsr;
+ CYG_WORD32 rcsr;
+
+ HAL_READ_UINT32(CRM_RCSR, rcsr);
+ HAL_READ_UINT16(WDOG_WRSR, wrsr);
+ rcsr &= 0x0f;
+ if (rcsr == 0) {
+ reset_cause = "POWER_ON RESET";
+ } else if (rcsr == 1) {
+ reset_cause = "EXTERNAL RESET";
+ } else if (rcsr & (1 << 3)) {
+ reset_cause = "JTAG RESET";
+ } else if (rcsr & (1 << 2)) {
+ reset_cause = "SOFT RESET";
+ } else if (rcsr & (1 << 1)) {
+ if (wrsr & (1 << 0)) {
+ reset_cause = "SOFTWARE RESET";
+ } else if (wrsr & (1 << 1)) {
+ reset_cause = "WATCHDOG TIMEOUT";
+ }
+ } else {
+ diag_printf("Unknown RESET cause: RCSR=0x%08x WRSR=0x%04x\n", rcsr, wrsr);
+ return;
+ }
+ diag_printf("Last RESET cause: %s\n", reset_cause);
+#else
unsigned int rest = readl(CCM_BASE_ADDR + CLKCTL_RCSR) & 0xF;
if (rest == 0)
diag_printf("hardware reset by POR\n");
else if (rest == 1)
diag_printf("hardware reset by Board reset signal\n");
- else if ((rest & 2) == 2)
+ else if (rest & 2)
diag_printf("hardware reset by WDOG\n");
- else if ((rest & 4) == 4)
+ else if (rest & 4)
diag_printf("hardware reset by SOFT RESET\n");
- else if ((rest & 8) == 8)
+ else if (rest & 8)
diag_printf("hardware reset by JTAG SW RESET\n");
else
diag_printf("hardware reset by unknown source (REST=%x)\n", rest);
+#endif
}
RedBoot_init(check_reset_source, RedBoot_INIT_LAST);
static void check_correct_chip(void)
{
- if (find_correct_chip == CHIP_VERSION_UNKNOWN) {
- diag_printf("Unrecognized chip version: 0x%x!!!\n", read_system_rev());
- diag_printf("Assuming chip version=0x%x\n", system_rev);
- } else if (find_correct_chip == CHIP_VERSION_NONE) {
- diag_printf("Unrecognized chip: 0x%x!!!\n", readl(IIM_BASE_ADDR + IIM_PREV_OFF));
- }
+ if (find_correct_chip == CHIP_VERSION_UNKNOWN) {
+ diag_printf("Unrecognized chip version: 0x%x!!!\n", read_system_rev());
+ diag_printf("Assuming chip version=0x%x\n", system_rev);
+ } else if (find_correct_chip == CHIP_VERSION_NONE) {
+ diag_printf("Unrecognized chip: 0x%x!!!\n", readl(IIM_BASE_ADDR + IIM_PREV_OFF));
+ }
}
RedBoot_init(check_correct_chip, RedBoot_INIT_LAST);