1 //==========================================================================
5 // HAL misc board support code
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //========================================================================*/
43 #include <pkgconf/hal.h>
44 #include <pkgconf/system.h>
45 #include CYGBLD_HAL_PLATFORM_H
47 #include <cyg/infra/cyg_type.h> // base types
48 #include <cyg/infra/cyg_trac.h> // tracing macros
49 #include <cyg/infra/cyg_ass.h> // assertion macros
51 #include <cyg/hal/hal_misc.h> // Size constants
52 #include <cyg/hal/hal_io.h> // IO macros
53 #include <cyg/hal/hal_arch.h> // Register state info
54 #include <cyg/hal/hal_diag.h>
55 #include <cyg/hal/hal_intr.h> // Interrupt names
56 #include <cyg/hal/hal_cache.h> // Cache control
57 #include <cyg/hal/hal_soc.h> // Hardware definitions
58 #include <cyg/hal/hal_mm.h> // MMap table definitions
59 #include <cyg/infra/diag.h> // diag_printf
60 #ifdef MXCFLASH_SELECT_NAND
61 #include <cyg/io/imx_nfc.h>
64 // Most initialization has already been done before we get here.
65 // All we do here is set up the interrupt environment.
66 // FIXME: some of the stuff in hal_platform_setup could be moved here.
71 * System_rev will have the following format
72 * 31-12 = part # (0x31, 0x32, 0x27, 0x91131, 0x91321, etc)
77 unsigned int system_rev = CHIP_REV_1_0;
78 static int find_correct_chip;
80 #define SBMR_BT_MEM_CTL_SHIFT 0
81 #define SBMR_BT_MEM_CTL_MASK (3 << SBMR_BT_MEM_CTL_SHIFT)
82 #define SBMR_BT_MEM_CTL(r) (((r) & SBMR_BT_MEM_CTL_MASK) >> SBMR_BT_MEM_CTL_SHIFT)
83 #define SBMR_BT_BUS_WIDTH_SHIFT 2
84 #define SBMR_BT_BUS_WIDTH_MASK (1 << SBMR_BT_BUS_WIDTH_SHIFT)
85 #define SBMR_BT_BUS_WIDTH(r) (((r) & SBMR_BT_BUS_WIDTH_MASK) >> SBMR_BT_BUS_WIDTH_SHIFT)
86 #define SBMR_BT_PAGE_SIZE_SHIFT 3
87 #define SBMR_BT_PAGE_SIZE_MASK (3 << SBMR_BT_PAGE_SIZE_SHIFT)
88 #define SBMR_BT_PAGE_SIZE(r) (((r) & SBMR_BT_PAGE_SIZE_MASK) >> SBMR_BT_PAGE_SIZE_SHIFT)
89 #define SBMR_BT_SPARE_SIZE_SHIFT 6
90 #define SBMR_BT_SPARE_SIZE_MASK (1 << SBMR_BT_SPARE_SIZE_SHIFT)
91 #define SBMR_BT_SPARE_SIZE(r) (((r) & SBMR_BT_SPARE_SIZE_MASK) >> SBMR_BT_SPARE_SIZE_SHIFT)
92 #define SBMR_BT_MEM_TYPE_SHIFT 7
93 #define SBMR_BT_MEM_TYPE_MASK (3 << SBMR_BT_MEM_TYPE_SHIFT)
94 #define SBMR_BT_MEM_TYPE(r) (((r) & SBMR_BT_MEM_TYPE_MASK) >> SBMR_BT_MEM_TYPE_SHIFT)
95 #define SBMR_BT_MLC_SEL_SHIFT 10
96 #define SBMR_BT_MLC_SEL_MASK (1 << SBMR_BT_MLC_SEL_SHIFT)
97 #define SBMR_BT_MLC_SEL(r) (((r) & SBMR_BT_MLC_SEL_MASK) >> SBMR_BT_MLC_SEL_SHIFT)
98 //#define SBMR_BT_USB_SRC_0_SHIFT 11
99 //#define SBMR_BT_USB_SRC_0_MASK (1 << ) /* reserved in Ref. Manual *SBMR_BT_USB_SRC_0_SHIFT/
100 //#define SBMR_BT_USB_SRC_0(r) (((r) & SBMR_BT_USB_SRC_0_MASK) >> SBMR_BT_USB_SRC_0_SHIFT)
102 #define SBMR_BT_EEPROM_CFG_SHIFT 12
103 #define SBMR_BT_EEPROM_CFG_MASK (1 << SBMR_BT_EEPROM_CFG_SHIFT)
104 #define SBMR_BT_EEPROM_CFG(r) (((r) & SBMR_BT_EEPROM_CFG_MASK) >> SBMR_BT_EEPROM_CFG_SHIFT)
106 #define SBMR_DIR_BT_DIS_SHIFT 13
107 #define SBMR_DIR_BT_DIS_MASK (1 << SBMR_DIR_BT_DIS_SHIFT)
108 #define SBMR_DIR_BT_DIS(r) (((r) & SBMR_DIR_BT_DIS_MASK) >> SBMR_DIR_BT_DIS_SHIFT)
109 #define SBMR_BMOD_SHIFT 14
110 #define SBMR_BMOD_MASK (3 << SBMR_BMOD_SHIFT)
111 #define SBMR_BMOD(r) (((r) & SBMR_BMOD_MASK) >> SBMR_BMOD_SHIFT)
112 #define SBMR_BT_WEIM_MUXED_SHIFT 16
113 #define SBMR_BT_WEIM_MUXED_MASK (3 << SBMR_BT_WEIM_MUXED_SHIFT)
115 #define SBMR_BT_WEIM_MUXED(r) (((r) & SBMR_BT_WEIM_MUXED_MASK) >> SBMR_BT_WEIM_MUXED_SHIFT)
116 #define SBMR_BT_LPB_EN_SHIFT 18
117 #define SBMR_BT_LPB_EN_MASK (1 << SBMR_BT_LPB_EN_SHIFT)
118 #define SBMR_BT_LPB_EN(r) (((r) & SBMR_BT_LPB_EN_MASK) >> SBMR_BT_LPB_EN_SHIFT)
120 #define SBMR_BT_SDMMC_SRC_SHIFT 19
121 #define SBMR_BT_SDMMC_SRC_MASK (3 << SBMR_BT_SDMMC_SRC_SHIFT)
122 #define SBMR_BT_SDMMC_SRC(r) (((r) & SBMR_BT_SDMMC_SRC_MASK) >> SBMR_BT_SDMMC_SRC_SHIFT)
124 #define SBMR_BT_OSC_FREQ_SEL_SHIFT 21
125 #define SBMR_BT_OSC_FREQ_SEL_MASK (3 << SBMR_BT_OSC_FREQ_SEL_SHIFT)
126 #define SBMR_BT_OSC_FREQ_SEL(r) (((r) & SBMR_BT_OSC_FREQ_SEL_MASK) >> SBMR_BT_OSC_FREQ_SEL_SHIFT)
127 #define SBMR_BT_LPB_SHIFT 23
128 #define SBMR_BT_LPB_MASK (3 << SBMR_BT_LPB_SHIFT)
129 #define SBMR_BT_LPB(r) (((r) & SBMR_BT_LPB_MASK) >> SBMR_BT_LPB_SHIFT)
130 #define SBMR_BT_UART_SRC_SHIFT 25
131 #define SBMR_BT_UART_SRC_MASK (3 << SBMR_BT_UART_SRC_SHIFT)
132 #define SBMR_BT_UART_SRC(r) (((r) & SBMR_BT_UART_SRC_MASK) >> SBMR_BT_UART_SRC_SHIFT)
133 #define SBMR_BT_USB_SRC_SHIFT 27
134 #define SBMR_BT_USB_SRC_MASK (3 << SBMR_BT_USB_SRC_SHIFT)
135 #define SBMR_BT_USB_SRC(r) (((r) & SBMR_BT_USB_SRC_MASK) >> SBMR_BT_USB_SRC_SHIFT)
136 #define SBMR_BT_HPN_EN_SHIFT 28
137 #define SBMR_BT_HPN_EN_MASK (1 << SBMR_BT_HPN_EN_SHIFT)
138 #define SBMR_BT_HPN_EN(r) (((r) & SBMR_BT_HPN_EN_MASK) >> SBMR_BT_HPN_EN_SHIFT)
139 #define SBMR_BT_LPB_FREQ_SHIFT 29
140 #define SBMR_BT_LPB_FREQ_MASK (7 << SBMR_BT_LPB_FREQ_SHIFT)
141 #define SBMR_BT_LPB_FREQ(r) (((r) & SBMR_BT_LPB_FREQ_MASK) >> SBMR_BT_LPB_FREQ_SHIFT)
145 * This functions reads the IIM module and returns the system revision number.
146 * It returns the IIM silicon revision reg value if valid product rev is found.
147 . Otherwise, it returns -1.
149 static int read_system_rev(void)
154 rom_id_address = (int *)((unsigned long)ROM_BASE_ADDR_VIRT + ROM_SI_REV_OFFSET);
156 val = readl(IIM_BASE_ADDR + IIM_PREV_OFF);
158 system_rev = 0x51 << PART_NUMBER_OFFSET; /* For MX51 Platform*/
160 /* Now try to retrieve the silicon rev from IIM's SREV register */
161 return *rom_id_address;
164 #ifdef MXCFLASH_SELECT_NAND
165 unsigned int mxc_nfc_soc_setup(unsigned int pg_sz, unsigned int io_sz,
166 unsigned int is_mlc, unsigned int num_of_chips);
167 extern nfc_setup_func_t *nfc_setup;
170 #ifdef MXCFLASH_SELECT_MMC
171 //extern mxc_mmc_check_sdhc_boot_slot *check_sdhc_slot;
174 int mxc_check_sdhc_boot_slot(unsigned int port, unsigned int *sdhc_addr);
176 void hal_hardware_init(void)
178 int ver = read_system_rev();
180 #ifndef CYGPKG_HAL_ARM_TX51KARO
181 unsigned int sbmr = readl(SRC_BASE_ADDR + 0x4);
182 unsigned int *fis_addr = (unsigned int *)IRAM_BASE_ADDR;
186 _mxc_fis = FROM_MMC_FLASH;
188 case FROM_NAND_FLASH:
189 _mxc_fis = FROM_NAND_FLASH;
191 case FROM_SPI_NOR_FLASH:
192 _mxc_fis = FROM_SPI_NOR_FLASH;
195 if (SBMR_BT_MEM_CTL(sbmr) == 0x3) {
196 if (SBMR_BT_MEM_TYPE(sbmr) == 0) {
197 _mxc_fis = MMC_FLASH_BOOT;
198 *fis_addr = FROM_MMC_FLASH;
199 } else if (SBMR_BT_MEM_TYPE(sbmr) == 3) {
200 _mxc_fis = SPI_NOR_FLASH_BOOT;
201 *fis_addr = FROM_SPI_NOR_FLASH;
203 } else if (SBMR_BT_MEM_CTL(sbmr) == 1) {
204 _mxc_fis = NAND_FLASH_BOOT;
205 *fis_addr = FROM_NAND_FLASH;
209 _mxc_fis = FROM_NAND_FLASH;
212 find_correct_chip = ver;
214 if (ver != CHIP_VERSION_NONE) {
215 /* Valid product revision found. Check actual silicon rev from the ROM code. */
217 HAL_PLATFORM_EXTRA[5] = '1';
218 HAL_PLATFORM_EXTRA[7] = '0';
219 system_rev |= 1 << MAJOR_NUMBER_OFFSET; /*Major Number*/
220 system_rev |= 0 << MINOR_NUMBER_OFFSET; /*Minor Number*/
221 } else if (ver == 0x2) {
222 HAL_PLATFORM_EXTRA[5] = '1';
223 HAL_PLATFORM_EXTRA[7] = '1';
224 system_rev |= 1 << MAJOR_NUMBER_OFFSET; /*Major Number*/
225 system_rev |= 1 << MINOR_NUMBER_OFFSET; /*Minor Number*/
226 } else if (ver == 0x10) {
227 HAL_PLATFORM_EXTRA[5] = '2';
228 HAL_PLATFORM_EXTRA[7] = '0';
229 system_rev |= 2 << MAJOR_NUMBER_OFFSET; /*Major Number*/
230 system_rev |= 0 << MINOR_NUMBER_OFFSET; /*Minor Number*/
231 } else if (ver == 0x20) {
232 HAL_PLATFORM_EXTRA[5] = '3';
233 HAL_PLATFORM_EXTRA[7] = '0';
234 system_rev |= 3 << MAJOR_NUMBER_OFFSET; /*Major Number*/
235 system_rev |= 0 << MINOR_NUMBER_OFFSET; /*Minor Number*/
237 HAL_PLATFORM_EXTRA[5] = 'x';
238 HAL_PLATFORM_EXTRA[7] = 'x';
239 system_rev |= 3 << MAJOR_NUMBER_OFFSET; /*Major Number*/
240 system_rev |= 0 << MINOR_NUMBER_OFFSET; /*Minor Number*/
241 find_correct_chip = CHIP_VERSION_UNKNOWN;
246 #ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
249 #ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
253 // enable EPIT and start it with 32KHz input clock
254 writel(0x00010000, EPIT_BASE_ADDR + EPITCR);
256 // make sure reset is complete
257 while ((readl(EPIT_BASE_ADDR + EPITCR) & 0x10000) != 0) {
260 writel(0x030E0002, EPIT_BASE_ADDR + EPITCR);
261 writel(0x030E0003, EPIT_BASE_ADDR + EPITCR);
263 writel(0, EPIT_BASE_ADDR + EPITCMPR); // always compare with 0
265 if ((readw(WDOG_BASE_ADDR) & 4) != 0) {
266 // increase the WDOG timeout value to the max
267 writew(readw(WDOG_BASE_ADDR) | 0xFF00, WDOG_BASE_ADDR);
270 // Perform any platform specific initializations
273 // Set up eCos/ROM interfaces
276 // initial NAND setup
277 writel(0xFFFF0000, UNLOCK_BLK_ADD0_REG);
278 writel(0xFFFF0000, UNLOCK_BLK_ADD1_REG);
279 writel(0xFFFF0000, UNLOCK_BLK_ADD2_REG);
280 writel(0xFFFF0000, UNLOCK_BLK_ADD3_REG);
281 writel(0xFFFF0000, UNLOCK_BLK_ADD4_REG);
282 writel(0xFFFF0000, UNLOCK_BLK_ADD5_REG);
283 writel(0xFFFF0000, UNLOCK_BLK_ADD6_REG);
284 writel(0xFFFF0000, UNLOCK_BLK_ADD7_REG);
286 // unlock all the CS's
287 for (i = 0; i < 8; i++) {
288 writel(0x84 | (i << 3), NFC_WR_PROT_REG);
290 writel(0, NFC_IPC_REG);
291 #ifdef MXCFLASH_SELECT_NAND
292 nfc_setup = mxc_nfc_soc_setup;
296 // -------------------------------------------------------------------------
297 void hal_clock_initialize(cyg_uint32 period)
301 // This routine is called during a clock interrupt.
303 // Define this if you want to ensure that the clock is perfect (i.e. does
304 // not drift). One reason to leave it turned off is that it costs some
305 // us per system clock interrupt for this maintenance.
306 #undef COMPENSATE_FOR_CLOCK_DRIFT
308 void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
312 // Read the current value of the clock, returning the number of hardware
313 // "ticks" that have occurred (i.e. how far away the current value is from
316 // Note: The "contract" for this function is that the value is the number
317 // of hardware clocks that have happened since the last interrupt (i.e.
318 // when it was reset). This value is used to measure interrupt latencies.
319 // However, since the hardware counter runs freely, this routine computes
320 // the difference between the current clock period and the number of hardware
321 // ticks left before the next timer interrupt.
322 void hal_clock_read(cyg_uint32 *pvalue)
326 // This is to cope with the test read used by tm_basic with
327 // CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY defined; we read the count ASAP
328 // in the ISR, *before* resetting the clock. Which returns 1tick +
329 // latency if we just use plain hal_clock_read().
330 void hal_clock_latency(cyg_uint32 *pvalue)
334 unsigned int hal_timer_count(void)
336 return (0xFFFFFFFF - readl(EPIT_BASE_ADDR + EPITCNR));
339 #define WDT_MAGIC_1 0x5555
340 #define WDT_MAGIC_2 0xAAAA
341 #define MXC_WDT_WSR 0x2
343 unsigned int i2c_base_addr[] = {
347 unsigned int i2c_num = 2;
349 static unsigned int led_on = 0;
351 // Delay for some number of micro-seconds
353 void hal_delay_us(unsigned int usecs)
356 * This causes overflow.
357 * unsigned int delayCount = (usecs * 32768) / 1000000;
358 * So use the following one instead
360 unsigned int delayCount = (usecs * 512) / 15625;
362 // issue the service sequence instructions
363 if ((readw(WDOG_BASE_ADDR) & 4) != 0) {
364 writew(WDT_MAGIC_1, WDOG_BASE_ADDR + MXC_WDT_WSR);
365 writew(WDT_MAGIC_2, WDOG_BASE_ADDR + MXC_WDT_WSR);
368 if (delayCount == 0) {
372 writel(0x01, EPIT_BASE_ADDR + EPITSR); // clear the compare status bit
374 writel(delayCount, EPIT_BASE_ADDR + EPITLR);
376 while ((0x1 & readl(EPIT_BASE_ADDR + EPITSR)) == 0); // wait until compare bit is set
377 if ((++led_on % 3000) == 0)
381 // -------------------------------------------------------------------------
383 // This routine is called to respond to a hardware interrupt (IRQ). It
384 // should interrogate the hardware and return the IRQ vector number.
385 int hal_IRQ_handler(void)
387 #ifdef HAL_EXTENDED_IRQ_HANDLER
390 // Use platform specific IRQ handler, if defined
391 // Note: this macro should do a 'return' with the appropriate
392 // interrupt number if such an extended interrupt exists. The
393 // assumption is that the line after the macro starts 'normal' processing.
394 HAL_EXTENDED_IRQ_HANDLER(index);
397 return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
404 void hal_interrupt_mask(int vector)
406 // diag_printf("6hal_interrupt_mask(vector=%d) \n", vector);
407 #ifdef HAL_EXTENDED_INTERRUPT_MASK
408 // Use platform specific handling, if defined
409 // Note: this macro should do a 'return' for "extended" values of 'vector'
410 // Normal vectors are handled by code subsequent to the macro call.
411 HAL_EXTENDED_INTERRUPT_MASK(vector);
415 void hal_interrupt_unmask(int vector)
417 // diag_printf("7hal_interrupt_unmask(vector=%d) \n", vector);
419 #ifdef HAL_EXTENDED_INTERRUPT_UNMASK
420 // Use platform specific handling, if defined
421 // Note: this macro should do a 'return' for "extended" values of 'vector'
422 // Normal vectors are handled by code subsequent to the macro call.
423 HAL_EXTENDED_INTERRUPT_UNMASK(vector);
427 void hal_interrupt_acknowledge(int vector)
430 // diag_printf("8hal_interrupt_acknowledge(vector=%d) \n", vector);
431 #ifdef HAL_EXTENDED_INTERRUPT_UNMASK
432 // Use platform specific handling, if defined
433 // Note: this macro should do a 'return' for "extended" values of 'vector'
434 // Normal vectors are handled by code subsequent to the macro call.
435 HAL_EXTENDED_INTERRUPT_ACKNOWLEDGE(vector);
439 void hal_interrupt_configure(int vector, int level, int up)
442 #ifdef HAL_EXTENDED_INTERRUPT_CONFIGURE
443 // Use platform specific handling, if defined
444 // Note: this macro should do a 'return' for "extended" values of 'vector'
445 // Normal vectors are handled by code subsequent to the macro call.
446 HAL_EXTENDED_INTERRUPT_CONFIGURE(vector, level, up);
450 void hal_interrupt_set_level(int vector, int level)
453 #ifdef HAL_EXTENDED_INTERRUPT_SET_LEVEL
454 // Use platform specific handling, if defined
455 // Note: this macro should do a 'return' for "extended" values of 'vector'
456 // Normal vectors are handled by code subsequent to the macro call.
457 HAL_EXTENDED_INTERRUPT_SET_LEVEL(vector, level);
460 // Interrupt priorities are not configurable.
463 #ifdef MXCFLASH_SELECT_NAND
464 unsigned int mxc_nfc_soc_setup(unsigned int pg_sz, unsigned int io_sz,
465 unsigned int is_mlc, unsigned int num_of_chips)
467 unsigned int src_scr_reg;
470 tmp = readl(NFC_FLASH_CONFIG2_REG);
471 /* Set the ST_CMD to be 0x70 for all NAND devices */
472 tmp &= ~(0xFF << 24);
474 #ifndef CYGPKG_HAL_ARM_TX51KARO
475 /* Set the Spare size */
476 tmp &= ~(0xFF << 16);
477 //tmp |= (((flash_params->spare_size & 0xFF) / 2) << 16);
478 tmp |= (64 / 2) << 16;
480 tmp = (tmp & ~(0xff << 16)) | ((64 / 2) << 16);
482 /* Set the Page Size */
496 #ifndef CYGPKG_HAL_ARM_TX51KARO
499 if (flash_params->spare_size >= 218) {
506 tmp = (tmp & ~(1 << 6)) | (0 << 6);
509 tmp = (tmp & ~(1 << 6)) | (0 << 6);
511 #ifndef CYGPKG_HAL_ARM_TX51KARO
512 /* Pages per block */
515 switch (flash_params->pages_per_block) {
531 tmp = (tmp & ~(3 << 7)) | (1 << 7);
534 tmp = (tmp & ~(3 << 7)) | (1 << 7);
536 /* Set the number of phase bits & ECC enable bit to default value */
539 writel(tmp, NFC_FLASH_CONFIG2_REG);
541 tmp = readl(NFC_FLASH_CONFIG3_REG);
542 /* Set the No SDMA bit */
544 /* Set the Status Busy Bit to 0x6 (default) */
547 /* Set the Flash Width */
548 if (io_sz == MXC_NAND_16_BIT) {
553 /* Set the Number of Nand Chips */
555 tmp |= ((num_of_chips - 1) << 12);
556 if (num_of_chips > 1)
558 writel(tmp, NFC_FLASH_CONFIG3_REG);
560 if (((system_rev >> MAJOR_NUMBER_OFFSET) & 0xf) <= 0x2) {
561 unsigned int sbmr = readl(SRC_BASE_ADDR + 0x4);
563 /* This issue is fixed in MX51 TO 3.0 */
564 /* Workaround to disable WARM RESET when booting from interleaved NAND devices */
565 if ((num_of_chips > 1) && (SBMR_BT_MEM_CTL(sbmr) == 1)) {
566 diag_printf("%s: Disabling WARM reset due to boot from interleaved NAND\n", __FUNCTION__);
567 src_scr_reg = readl(SRC_BASE_ADDR);
569 writel(src_scr_reg, SRC_BASE_ADDR);
577 static void show_sys_info(void)
579 cyg_uint32 sbmr = readl(SRC_BASE_ADDR + 0x4);
580 cyg_uint32 srsr = readl(SRC_BASE_ADDR + 0x8);
581 const char *dlm = "";
583 if (find_correct_chip == CHIP_VERSION_UNKNOWN) {
584 diag_printf("Unrecognized chip version: 0x%08x!!!\n", read_system_rev());
585 diag_printf("Assuming chip version=0x%08x\n", system_rev);
586 } else if (find_correct_chip == CHIP_VERSION_NONE) {
587 diag_printf("Unrecognized chip: 0x%08x!!!\n", readl(IIM_BASE_ADDR + IIM_PREV_OFF));
590 diag_printf("Reset reason: ");
592 if (srsr & (1 << 0)) {
593 diag_printf("%sPOWER_ON", dlm);
596 if (srsr & (1 << 2)) {
597 diag_printf("%sCSU", dlm);
600 if (srsr & (1 << 3)) {
601 diag_printf("%sUSER", dlm);
604 if (srsr & (1 << 4)) {
607 HAL_READ_UINT16(WDOG_BASE_ADDR + 4, wrsr);
608 if (wrsr & (1 << 0)) {
609 diag_printf("%sSOFT", dlm);
612 if (wrsr & (1 << 1)) {
613 diag_printf("%sWATCHDOG", dlm);
617 if (srsr & (1 << 5)) {
618 diag_printf("%sJTAG_HW", dlm);
621 if (srsr & (1 << 6)) {
622 diag_printf("%sJTAG_SW", dlm);
625 if (srsr & (1 << 16)) {
626 diag_printf("%sWARM BOOT", dlm);
631 diag_printf("UNKNOWN: %08x\n", srsr);
633 diag_printf(" RESET\n");
636 if (_mxc_fis == MMC_FLASH_BOOT) {
637 diag_printf("fis/fconfig from MMC\n");
638 } else if (_mxc_fis == SPI_NOR_FLASH_BOOT) {
639 diag_printf("fis/fconfig from SPI-NOR\n");
640 } else if (_mxc_fis == NAND_FLASH_BOOT) {
641 diag_printf("fis/fconfig from NAND\n");
643 diag_printf("Use \"factive [MMC|SPI|NAND]\" to choose fis/fconfig storage\n");
646 diag_printf("Boot switch: ");
647 if ((SBMR_BMOD(sbmr)) == 0) {
648 diag_printf("INTERNAL (GPIO)\n");
649 } else if ((SBMR_BMOD(sbmr)) == 2) {
650 diag_printf("INTERNAL (FUSE)\n");
651 } else if ((SBMR_BMOD(sbmr)) == 3){
652 diag_printf("BOOTSTRAP\n");
653 } else if ((SBMR_BMOD(sbmr)) == 0x1 && (SBMR_DIR_BT_DIS(sbmr)) == 0) {
654 diag_printf("TEST EXEC\n");
656 diag_printf("UNKNOWN: 0x%x\n", SBMR_BMOD(sbmr));
659 if ((SBMR_BT_MEM_CTL(sbmr)) == 0) {
660 diag_printf("WEIM: ");
661 if ((SBMR_BT_MEM_TYPE(sbmr)) == 0) {
663 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 2) {
664 diag_printf("ONE NAND");
666 diag_printf("UNKNOWN: 0x%x", SBMR_BT_MEM_TYPE(sbmr));
668 } else if ((SBMR_BT_MEM_CTL(sbmr)) == 1) {
669 diag_printf("NAND: ADDR CYCLES:");
670 if ((SBMR_BT_MEM_TYPE(sbmr)) == 0) {
672 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 1) {
674 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 2) {
677 diag_printf("UNKNOWN: 0x%x ", SBMR_BT_MEM_TYPE(sbmr));
679 if (SBMR_BT_MLC_SEL(sbmr) == 0) {
680 diag_printf("SLC: ");
682 diag_printf("MLC: ");
684 if ((SBMR_BT_SPARE_SIZE(sbmr)) == 0) {
685 diag_printf("128B spare (4-bit ECC): ");
687 diag_printf("218B spare (8-bit ECC): ");
689 diag_printf("PAGE SIZE: ");
690 if ((SBMR_BT_PAGE_SIZE(sbmr)) == 0) {
691 diag_printf("512: ");
692 } else if ((SBMR_BT_PAGE_SIZE(sbmr)) == 1) {
694 } else if ((SBMR_BT_PAGE_SIZE(sbmr)) == 2) {
697 diag_printf("UNKNOWN: 0x%x", SBMR_BT_PAGE_SIZE(sbmr));
699 diag_printf("BUS WIDTH: ");
700 if ((SBMR_BT_BUS_WIDTH(sbmr)) == 0) {
705 } else if ((SBMR_BT_MEM_CTL(sbmr)) == 3) {
706 diag_printf("EXPANSION: ");
707 if ((SBMR_BT_MEM_TYPE(sbmr)) == 0) {
708 diag_printf("SD/MMC-%d", (SBMR_BT_SDMMC_SRC(sbmr)));
709 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 2) {
710 diag_printf("I2C-NOR: ");
711 if ((SBMR_BT_SDMMC_SRC(sbmr)) == 0) {
712 diag_printf("I2C-1");
713 } else if ((SBMR_BT_SDMMC_SRC(sbmr)) == 1) {
714 diag_printf("I2C-2");
715 } else if ((SBMR_BT_SDMMC_SRC(sbmr)) == 2) {
716 diag_printf("HS-I2C");
718 diag_printf("UNKNOWN: 0x%x", SBMR_BT_SDMMC_SRC(sbmr));
720 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 3) {
721 diag_printf("SPI-NOR: ");
722 if ((SBMR_BT_SDMMC_SRC(sbmr)) == 0) {
723 diag_printf("eCSPI1");
724 } else if ((SBMR_BT_SDMMC_SRC(sbmr)) == 1) {
725 diag_printf("eCSPI2");
726 } else if ((SBMR_BT_SDMMC_SRC(sbmr)) == 2) {
729 diag_printf("UNKNOWN: 0x%x", SBMR_BT_SDMMC_SRC(sbmr));
732 diag_printf("UNKNOWN: 0x%x", SBMR_BT_MEM_TYPE(sbmr));
735 diag_printf("UNKNOWN: 0x%x", SBMR_BT_MEM_CTL(sbmr));
740 RedBoot_init(show_sys_info, RedBoot_INIT_LAST);