]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/hal/arm/mx25/var/v2_0/src/soc_misc.c
Bugfix Release STK5 2010-10-04
[karo-tx-redboot.git] / packages / hal / arm / mx25 / var / v2_0 / src / soc_misc.c
index 1387a10b83ab24d04f61c7d18c460ce4404d103b..66f5fb0290dc2725ed6d599e14ca0cdcb422bf8a 100644 (file)
 #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
@@ -90,77 +91,102 @@ externC void plf_hardware_init(void);
  */
 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;
 }
 
 // -------------------------------------------------------------------------
@@ -203,50 +229,50 @@ void hal_clock_latency(cyg_uint32 *pvalue)
 
 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);
 }
 
 // -------------------------------------------------------------------------
@@ -256,16 +282,16 @@ void hal_delay_us(unsigned int usecs)
 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!
 }
 
 //
@@ -276,10 +302,10 @@ void hal_interrupt_mask(int vector)
 {
 //    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
 }
 
@@ -288,10 +314,10 @@ void hal_interrupt_unmask(int vector)
 //    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
 }
 
@@ -300,10 +326,10 @@ void hal_interrupt_acknowledge(int vector)
 
 //    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
 }
 
@@ -311,10 +337,10 @@ void hal_interrupt_configure(int vector, int level, int up)
 {
 
 #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
 }
 
@@ -322,75 +348,107 @@ void hal_interrupt_set_level(int vector, int level)
 {
 
 #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);