]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx51/var/v2_0/src/soc_misc.c
877a26c3c539f2ab5ba466912263c37cdadfd1a1
[karo-tx-redboot.git] / packages / hal / arm / mx51 / var / v2_0 / src / soc_misc.c
1 //==========================================================================
2 //
3 //      soc_misc.c
4 //
5 //      HAL misc board support code
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 //
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 //========================================================================*/
41
42 #include <redboot.h>
43 #include <pkgconf/hal.h>
44 #include <pkgconf/system.h>
45 #include CYGBLD_HAL_PLATFORM_H
46
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
50
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>
62 #endif
63
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.
67
68 int _mxc_fis;
69
70 /*
71  * System_rev will have the following format
72  * 31-12 = part # (0x31, 0x32, 0x27, 0x91131, 0x91321, etc)
73  * 11-8 = unused
74  * 7-4 = major (1.y)
75  * 3-0 = minor (x.0)
76  */
77 unsigned int system_rev = CHIP_REV_1_0;
78 static int find_correct_chip;
79
80 static int _reset_reason;
81
82 #define SBMR_BT_MEM_CTL_SHIFT           0
83 #define SBMR_BT_MEM_CTL_MASK            (3 << SBMR_BT_MEM_CTL_SHIFT)
84 #define SBMR_BT_MEM_CTL(r)                      (((r) & SBMR_BT_MEM_CTL_MASK) >> SBMR_BT_MEM_CTL_SHIFT)
85 #define SBMR_BT_BUS_WIDTH_SHIFT         2
86 #define SBMR_BT_BUS_WIDTH_MASK          (1 << SBMR_BT_BUS_WIDTH_SHIFT)
87 #define SBMR_BT_BUS_WIDTH(r)            (((r) & SBMR_BT_BUS_WIDTH_MASK) >> SBMR_BT_BUS_WIDTH_SHIFT)
88 #define SBMR_BT_PAGE_SIZE_SHIFT         3
89 #define SBMR_BT_PAGE_SIZE_MASK          (3 << SBMR_BT_PAGE_SIZE_SHIFT)
90 #define SBMR_BT_PAGE_SIZE(r)            (((r) & SBMR_BT_PAGE_SIZE_MASK) >> SBMR_BT_PAGE_SIZE_SHIFT)
91 #define SBMR_BT_SPARE_SIZE_SHIFT        6
92 #define SBMR_BT_SPARE_SIZE_MASK         (1 << SBMR_BT_SPARE_SIZE_SHIFT)
93 #define SBMR_BT_SPARE_SIZE(r)           (((r) & SBMR_BT_SPARE_SIZE_MASK) >> SBMR_BT_SPARE_SIZE_SHIFT)
94 #define SBMR_BT_MEM_TYPE_SHIFT          7
95 #define SBMR_BT_MEM_TYPE_MASK           (3 << SBMR_BT_MEM_TYPE_SHIFT)
96 #define SBMR_BT_MEM_TYPE(r)                     (((r) & SBMR_BT_MEM_TYPE_MASK) >> SBMR_BT_MEM_TYPE_SHIFT)
97 #define SBMR_BT_MLC_SEL_SHIFT           10
98 #define SBMR_BT_MLC_SEL_MASK            (1 << SBMR_BT_MLC_SEL_SHIFT)
99 #define SBMR_BT_MLC_SEL(r)                      (((r) & SBMR_BT_MLC_SEL_MASK) >> SBMR_BT_MLC_SEL_SHIFT)
100 //#define SBMR_BT_USB_SRC_0_SHIFT       11
101 //#define SBMR_BT_USB_SRC_0_MASK        (1 << ) /* reserved in Ref. Manual *SBMR_BT_USB_SRC_0_SHIFT/
102 //#define SBMR_BT_USB_SRC_0(r)          (((r) & SBMR_BT_USB_SRC_0_MASK) >> SBMR_BT_USB_SRC_0_SHIFT)
103 #ifdef UNUSED
104 #define SBMR_BT_EEPROM_CFG_SHIFT        12
105 #define SBMR_BT_EEPROM_CFG_MASK         (1 << SBMR_BT_EEPROM_CFG_SHIFT)
106 #define SBMR_BT_EEPROM_CFG(r)           (((r) & SBMR_BT_EEPROM_CFG_MASK) >> SBMR_BT_EEPROM_CFG_SHIFT)
107 #endif
108 #define SBMR_DIR_BT_DIS_SHIFT           13
109 #define SBMR_DIR_BT_DIS_MASK            (1 << SBMR_DIR_BT_DIS_SHIFT)
110 #define SBMR_DIR_BT_DIS(r)                      (((r) & SBMR_DIR_BT_DIS_MASK) >> SBMR_DIR_BT_DIS_SHIFT)
111 #define SBMR_BMOD_SHIFT                         14
112 #define SBMR_BMOD_MASK                          (3 << SBMR_BMOD_SHIFT)
113 #define SBMR_BMOD(r)                            (((r) & SBMR_BMOD_MASK) >> SBMR_BMOD_SHIFT)
114 #define SBMR_BT_WEIM_MUXED_SHIFT        16
115 #define SBMR_BT_WEIM_MUXED_MASK         (3 << SBMR_BT_WEIM_MUXED_SHIFT)
116 #ifdef UNUSED
117 #define SBMR_BT_WEIM_MUXED(r)           (((r) & SBMR_BT_WEIM_MUXED_MASK) >> SBMR_BT_WEIM_MUXED_SHIFT)
118 #define SBMR_BT_LPB_EN_SHIFT            18
119 #define SBMR_BT_LPB_EN_MASK                     (1 << SBMR_BT_LPB_EN_SHIFT)
120 #define SBMR_BT_LPB_EN(r)                       (((r) & SBMR_BT_LPB_EN_MASK) >> SBMR_BT_LPB_EN_SHIFT)
121 #endif
122 #define SBMR_BT_SDMMC_SRC_SHIFT         19
123 #define SBMR_BT_SDMMC_SRC_MASK          (3 << SBMR_BT_SDMMC_SRC_SHIFT)
124 #define SBMR_BT_SDMMC_SRC(r)            (((r) & SBMR_BT_SDMMC_SRC_MASK) >> SBMR_BT_SDMMC_SRC_SHIFT)
125 #ifdef UNUSED
126 #define SBMR_BT_OSC_FREQ_SEL_SHIFT      21
127 #define SBMR_BT_OSC_FREQ_SEL_MASK       (3 << SBMR_BT_OSC_FREQ_SEL_SHIFT)
128 #define SBMR_BT_OSC_FREQ_SEL(r)         (((r) & SBMR_BT_OSC_FREQ_SEL_MASK) >> SBMR_BT_OSC_FREQ_SEL_SHIFT)
129 #define SBMR_BT_LPB_SHIFT                       23
130 #define SBMR_BT_LPB_MASK                        (3 << SBMR_BT_LPB_SHIFT)
131 #define SBMR_BT_LPB(r)                          (((r) & SBMR_BT_LPB_MASK) >> SBMR_BT_LPB_SHIFT)
132 #define SBMR_BT_UART_SRC_SHIFT          25
133 #define SBMR_BT_UART_SRC_MASK           (3 << SBMR_BT_UART_SRC_SHIFT)
134 #define SBMR_BT_UART_SRC(r)                     (((r) & SBMR_BT_UART_SRC_MASK) >> SBMR_BT_UART_SRC_SHIFT)
135 #define SBMR_BT_USB_SRC_SHIFT           27
136 #define SBMR_BT_USB_SRC_MASK            (3 << SBMR_BT_USB_SRC_SHIFT)
137 #define SBMR_BT_USB_SRC(r)                      (((r) & SBMR_BT_USB_SRC_MASK) >> SBMR_BT_USB_SRC_SHIFT)
138 #define SBMR_BT_HPN_EN_SHIFT            28
139 #define SBMR_BT_HPN_EN_MASK                     (1 << SBMR_BT_HPN_EN_SHIFT)
140 #define SBMR_BT_HPN_EN(r)                       (((r) & SBMR_BT_HPN_EN_MASK) >> SBMR_BT_HPN_EN_SHIFT)
141 #define SBMR_BT_LPB_FREQ_SHIFT          29
142 #define SBMR_BT_LPB_FREQ_MASK           (7 << SBMR_BT_LPB_FREQ_SHIFT)
143 #define SBMR_BT_LPB_FREQ(r)                     (((r) & SBMR_BT_LPB_FREQ_MASK) >> SBMR_BT_LPB_FREQ_SHIFT)
144 #endif
145
146 /*
147  * This functions reads the IIM module and returns the system revision number.
148  * It returns the IIM silicon revision reg value if valid product rev is found.
149  . Otherwise, it returns -1.
150  */
151 static int read_system_rev(void)
152 {
153         int val;
154         int *rom_id_address;
155
156         rom_id_address = (int *)((unsigned long)ROM_BASE_ADDR_VIRT + ROM_SI_REV_OFFSET);
157
158         val = readl(IIM_BASE_ADDR + IIM_PREV_OFF);
159
160         system_rev = 0x51 << PART_NUMBER_OFFSET; /* For MX51 Platform*/
161
162         /* Now try to retrieve the silicon rev from IIM's SREV register */
163         return *rom_id_address;
164 }
165
166 #ifdef MXCFLASH_SELECT_NAND
167 unsigned int mxc_nfc_soc_setup(unsigned int pg_sz, unsigned int io_sz,
168                                                         unsigned int is_mlc, unsigned int num_of_chips);
169 extern nfc_setup_func_t *nfc_setup;
170 #endif
171
172 #ifdef MXCFLASH_SELECT_MMC
173 //extern mxc_mmc_check_sdhc_boot_slot *check_sdhc_slot;
174 #endif
175
176 int mxc_check_sdhc_boot_slot(unsigned int port, unsigned int *sdhc_addr);
177
178 void hal_hardware_init(void)
179 {
180         int ver = read_system_rev();
181         unsigned int i;
182 #ifndef CYGPKG_HAL_ARM_TX51KARO
183         unsigned int sbmr = readl(SRC_BASE_ADDR + 0x4);
184         unsigned int *fis_addr = (unsigned int *)IRAM_BASE_ADDR;
185
186         switch (*fis_addr) {
187         case FROM_MMC_FLASH:
188                 _mxc_fis = FROM_MMC_FLASH;
189                 break;
190         case FROM_NAND_FLASH:
191                 _mxc_fis = FROM_NAND_FLASH;
192                 break;
193         case FROM_SPI_NOR_FLASH:
194                 _mxc_fis = FROM_SPI_NOR_FLASH;
195                 break;
196         default:
197                 if (SBMR_BT_MEM_CTL(sbmr) == 0x3) {
198                         if (SBMR_BT_MEM_TYPE(sbmr) == 0) {
199                                 _mxc_fis = MMC_FLASH_BOOT;
200                                 *fis_addr = FROM_MMC_FLASH;
201                         } else if (SBMR_BT_MEM_TYPE(sbmr) == 3) {
202                                 _mxc_fis = SPI_NOR_FLASH_BOOT;
203                                 *fis_addr = FROM_SPI_NOR_FLASH;
204                         }
205                 } else if (SBMR_BT_MEM_CTL(sbmr) == 1) {
206                         _mxc_fis = NAND_FLASH_BOOT;
207                         *fis_addr = FROM_NAND_FLASH;
208                 }
209         }
210 #else
211         _mxc_fis = FROM_NAND_FLASH;
212 #endif
213
214         _reset_reason = readl(SRC_BASE_ADDR + 0x8);
215
216         find_correct_chip = ver;
217
218         if (ver != CHIP_VERSION_NONE) {
219                 /* Valid product revision found. Check actual silicon rev from the ROM code. */
220                 if (ver == 0x1) {
221                         HAL_PLATFORM_EXTRA[5] = '1';
222                         HAL_PLATFORM_EXTRA[7] = '0';
223                         system_rev |= 1 << MAJOR_NUMBER_OFFSET; /*Major Number*/
224                         system_rev |= 0 << MINOR_NUMBER_OFFSET; /*Minor Number*/
225                 } else if (ver == 0x2) {
226                         HAL_PLATFORM_EXTRA[5] = '1';
227                         HAL_PLATFORM_EXTRA[7] = '1';
228                         system_rev |= 1 << MAJOR_NUMBER_OFFSET; /*Major Number*/
229                         system_rev |= 1 << MINOR_NUMBER_OFFSET; /*Minor Number*/
230                 } else if (ver == 0x10) {
231                         HAL_PLATFORM_EXTRA[5] = '2';
232                         HAL_PLATFORM_EXTRA[7] = '0';
233                         system_rev |= 2 << MAJOR_NUMBER_OFFSET; /*Major Number*/
234                         system_rev |= 0 << MINOR_NUMBER_OFFSET; /*Minor Number*/
235                 } else if (ver == 0x20) {
236                         HAL_PLATFORM_EXTRA[5] = '3';
237                         HAL_PLATFORM_EXTRA[7] = '0';
238                         system_rev |= 3 << MAJOR_NUMBER_OFFSET; /*Major Number*/
239                         system_rev |= 0 << MINOR_NUMBER_OFFSET; /*Minor Number*/
240                 } else {
241                         HAL_PLATFORM_EXTRA[5] = 'x';
242                         HAL_PLATFORM_EXTRA[7] = 'x';
243                         system_rev |= 3 << MAJOR_NUMBER_OFFSET; /*Major Number*/
244                         system_rev |= 0 << MINOR_NUMBER_OFFSET; /*Minor Number*/
245                         find_correct_chip = CHIP_VERSION_UNKNOWN;
246                 }
247
248         }
249         // Enable caches
250 #ifdef CYGSEM_HAL_ENABLE_ICACHE_ON_STARTUP
251         HAL_ICACHE_ENABLE();
252 #endif
253 #ifdef CYGSEM_HAL_ENABLE_DCACHE_ON_STARTUP
254         HAL_DCACHE_ENABLE();
255 #endif
256
257         // enable EPIT and start it with 32KHz input clock
258         writel(0x00010000, EPIT_BASE_ADDR + EPITCR);
259
260         // make sure reset is complete
261         while ((readl(EPIT_BASE_ADDR + EPITCR) & 0x10000) != 0) {
262         }
263
264         writel(0x030E0002, EPIT_BASE_ADDR + EPITCR);
265         writel(0x030E0003, EPIT_BASE_ADDR + EPITCR);
266
267         writel(0, EPIT_BASE_ADDR + EPITCMPR);  // always compare with 0
268
269         if ((readw(WDOG_BASE_ADDR) & 4) != 0) {
270                 // increase the WDOG timeout value to the max
271                 writew(readw(WDOG_BASE_ADDR) | 0xFF00, WDOG_BASE_ADDR);
272         }
273
274         // Perform any platform specific initializations
275         plf_hardware_init();
276
277         // Set up eCos/ROM interfaces
278         hal_if_init();
279
280         // initial NAND setup
281         writel(0xFFFF0000, UNLOCK_BLK_ADD0_REG);
282         writel(0xFFFF0000, UNLOCK_BLK_ADD1_REG);
283         writel(0xFFFF0000, UNLOCK_BLK_ADD2_REG);
284         writel(0xFFFF0000, UNLOCK_BLK_ADD3_REG);
285         writel(0xFFFF0000, UNLOCK_BLK_ADD4_REG);
286         writel(0xFFFF0000, UNLOCK_BLK_ADD5_REG);
287         writel(0xFFFF0000, UNLOCK_BLK_ADD6_REG);
288         writel(0xFFFF0000, UNLOCK_BLK_ADD7_REG);
289
290         // unlock all the CS's
291         for (i = 0; i < 8; i++) {
292                 writel(0x84 | (i << 3), NFC_WR_PROT_REG);
293         }
294         writel(0, NFC_IPC_REG);
295 #ifdef MXCFLASH_SELECT_NAND
296         nfc_setup = mxc_nfc_soc_setup;
297 #endif
298 }
299
300 // -------------------------------------------------------------------------
301 void hal_clock_initialize(cyg_uint32 period)
302 {
303 }
304
305 // This routine is called during a clock interrupt.
306
307 // Define this if you want to ensure that the clock is perfect (i.e. does
308 // not drift).  One reason to leave it turned off is that it costs some
309 // us per system clock interrupt for this maintenance.
310 #undef COMPENSATE_FOR_CLOCK_DRIFT
311
312 void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
313 {
314 }
315
316 // Read the current value of the clock, returning the number of hardware
317 // "ticks" that have occurred (i.e. how far away the current value is from
318 // the start)
319
320 // Note: The "contract" for this function is that the value is the number
321 // of hardware clocks that have happened since the last interrupt (i.e.
322 // when it was reset).  This value is used to measure interrupt latencies.
323 // However, since the hardware counter runs freely, this routine computes
324 // the difference between the current clock period and the number of hardware
325 // ticks left before the next timer interrupt.
326 void hal_clock_read(cyg_uint32 *pvalue)
327 {
328 }
329
330 // This is to cope with the test read used by tm_basic with
331 // CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY defined; we read the count ASAP
332 // in the ISR, *before* resetting the clock.  Which returns 1tick +
333 // latency if we just use plain hal_clock_read().
334 void hal_clock_latency(cyg_uint32 *pvalue)
335 {
336 }
337
338 unsigned int hal_timer_count(void)
339 {
340         return (0xFFFFFFFF - readl(EPIT_BASE_ADDR + EPITCNR));
341 }
342
343 #define WDT_MAGIC_1                             0x5555
344 #define WDT_MAGIC_2                             0xAAAA
345 #define MXC_WDT_WSR                             0x2
346
347 unsigned int i2c_base_addr[] = {
348         I2C_BASE_ADDR,
349         I2C2_BASE_ADDR,
350 };
351 unsigned int i2c_num = 2;
352
353 static unsigned int led_on = 0;
354 //
355 // Delay for some number of micro-seconds
356 //
357 void hal_delay_us(unsigned int usecs)
358 {
359         /*
360          * This causes overflow.
361          * unsigned int delayCount = (usecs * 32768) / 1000000;
362          * So use the following one instead
363          */
364         unsigned int delayCount = (usecs * 512) / 15625;
365
366         // issue the service sequence instructions
367         if ((readw(WDOG_BASE_ADDR) & 4) != 0) {
368                 writew(WDT_MAGIC_1, WDOG_BASE_ADDR + MXC_WDT_WSR);
369                 writew(WDT_MAGIC_2, WDOG_BASE_ADDR + MXC_WDT_WSR);
370         }
371
372         if (delayCount == 0) {
373                 return;
374         }
375
376         writel(0x01, EPIT_BASE_ADDR + EPITSR); // clear the compare status bit
377
378         writel(delayCount, EPIT_BASE_ADDR + EPITLR);
379
380         while ((0x1 & readl(EPIT_BASE_ADDR + EPITSR)) == 0); // return until compare bit is set
381         if ((++led_on % 3000) == 0)
382                 BOARD_DEBUG_LED(0);
383 }
384
385 // -------------------------------------------------------------------------
386
387 // This routine is called to respond to a hardware interrupt (IRQ).  It
388 // should interrogate the hardware and return the IRQ vector number.
389 int hal_IRQ_handler(void)
390 {
391 #ifdef HAL_EXTENDED_IRQ_HANDLER
392         cyg_uint32 index;
393
394         // Use platform specific IRQ handler, if defined
395         // Note: this macro should do a 'return' with the appropriate
396         // interrupt number if such an extended interrupt exists.  The
397         // assumption is that the line after the macro starts 'normal' processing.
398         HAL_EXTENDED_IRQ_HANDLER(index);
399 #endif
400
401         return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
402 }
403
404 //
405 // Interrupt control
406 //
407
408 void hal_interrupt_mask(int vector)
409 {
410 //    diag_printf("6hal_interrupt_mask(vector=%d) \n", vector);
411 #ifdef HAL_EXTENDED_INTERRUPT_MASK
412         // Use platform specific handling, if defined
413         // Note: this macro should do a 'return' for "extended" values of 'vector'
414         // Normal vectors are handled by code subsequent to the macro call.
415         HAL_EXTENDED_INTERRUPT_MASK(vector);
416 #endif
417 }
418
419 void hal_interrupt_unmask(int vector)
420 {
421 //    diag_printf("7hal_interrupt_unmask(vector=%d) \n", vector);
422
423 #ifdef HAL_EXTENDED_INTERRUPT_UNMASK
424         // Use platform specific handling, if defined
425         // Note: this macro should do a 'return' for "extended" values of 'vector'
426         // Normal vectors are handled by code subsequent to the macro call.
427         HAL_EXTENDED_INTERRUPT_UNMASK(vector);
428 #endif
429 }
430
431 void hal_interrupt_acknowledge(int vector)
432 {
433
434 //    diag_printf("8hal_interrupt_acknowledge(vector=%d) \n", vector);
435 #ifdef HAL_EXTENDED_INTERRUPT_UNMASK
436         // Use platform specific handling, if defined
437         // Note: this macro should do a 'return' for "extended" values of 'vector'
438         // Normal vectors are handled by code subsequent to the macro call.
439         HAL_EXTENDED_INTERRUPT_ACKNOWLEDGE(vector);
440 #endif
441 }
442
443 void hal_interrupt_configure(int vector, int level, int up)
444 {
445
446 #ifdef HAL_EXTENDED_INTERRUPT_CONFIGURE
447         // Use platform specific handling, if defined
448         // Note: this macro should do a 'return' for "extended" values of 'vector'
449         // Normal vectors are handled by code subsequent to the macro call.
450         HAL_EXTENDED_INTERRUPT_CONFIGURE(vector, level, up);
451 #endif
452 }
453
454 void hal_interrupt_set_level(int vector, int level)
455 {
456
457 #ifdef HAL_EXTENDED_INTERRUPT_SET_LEVEL
458         // Use platform specific handling, if defined
459         // Note: this macro should do a 'return' for "extended" values of 'vector'
460         // Normal vectors are handled by code subsequent to the macro call.
461         HAL_EXTENDED_INTERRUPT_SET_LEVEL(vector, level);
462 #endif
463
464         // Interrupt priorities are not configurable.
465 }
466
467 #ifdef MXCFLASH_SELECT_NAND
468 unsigned int mxc_nfc_soc_setup(unsigned int pg_sz, unsigned int io_sz,
469                                                         unsigned int is_mlc, unsigned int num_of_chips)
470 {
471         unsigned int src_scr_reg;
472         unsigned int tmp;
473
474         tmp = readl(NFC_FLASH_CONFIG2_REG);
475         /* Set the ST_CMD to be 0x70 for all NAND devices */
476         tmp &= ~(0xFF << 24);
477         tmp |= (0x70 << 24);
478 #ifndef CYGPKG_HAL_ARM_TX51KARO
479         /* Set the Spare size */
480         tmp &= ~(0xFF << 16);
481         //tmp |= (((flash_params->spare_size & 0xFF) / 2) << 16);
482         tmp |= (64 / 2) << 16;
483 #else
484         tmp = (tmp & ~(0xff << 16)) | ((64 / 2) << 16);
485 #endif
486         /* Set the Page Size */
487         tmp &= ~(0x3);
488         switch (pg_sz) {
489         case 512:
490                 tmp |= 0x0;
491                 break;
492         case 2048:
493                 tmp |= 0x1;
494                 break;
495         case 4096:
496         default:
497                 tmp |= 0x2;
498                 break;
499         }
500 #ifndef CYGPKG_HAL_ARM_TX51KARO
501         /* Set ECC mode */
502 #if 0
503         if (flash_params->spare_size >= 218) {
504                 /* Use 8-bit ECC */
505                 tmp |= (0x1 << 6);
506         } else {
507                 tmp &= ~(0x1 << 6);
508         }
509 #else
510         tmp = (tmp & ~(1 << 6)) | (0 << 6);
511 #endif
512 #else
513         tmp = (tmp & ~(1 << 6)) | (0 << 6);
514 #endif
515 #ifndef CYGPKG_HAL_ARM_TX51KARO
516         /* Pages per block */
517         tmp &= ~(0x3 << 7);
518 #if 0
519         switch (flash_params->pages_per_block) {
520         case 32:
521                 tmp |= 0x0;
522                 break;
523         case 64:
524                 tmp |= (0x1 << 7);
525                 break;
526         case 128:
527                 tmp |= (0x2 << 7);
528                 break;
529         case 256:
530         default:
531                 tmp |= (0x3 << 7);
532                 break;
533         }
534 #else
535         tmp = (tmp & ~(3 << 7)) | (1 << 7);
536 #endif
537 #else
538         tmp = (tmp & ~(3 << 7)) | (1 << 7);
539 #endif
540         /* Set the number of phase bits & ECC enable bit to default value */
541         tmp &= ~(0x3 << 12);
542         tmp |= 0x2038;
543         writel(tmp, NFC_FLASH_CONFIG2_REG);
544
545         tmp = readl(NFC_FLASH_CONFIG3_REG);
546         /* Set the No SDMA bit */
547         tmp |= (0x1 << 20);
548         /* Set the Status Busy Bit to 0x6 (default) */
549         tmp &= ~(0x7 << 8);
550         tmp |= (0x6 << 8);
551         /* Set the Flash Width */
552         if (io_sz == MXC_NAND_16_BIT) {
553                 tmp &= ~(1 << 3);
554         } else {
555                 tmp |= 1 << 3;
556         }
557         /* Set the Number of Nand Chips */
558         tmp &= ~(0x7 << 12);
559         tmp |= ((num_of_chips - 1) << 12);
560         if (num_of_chips > 1)
561                 tmp |= 0x1;
562         writel(tmp, NFC_FLASH_CONFIG3_REG);
563
564         if (((system_rev >> MAJOR_NUMBER_OFFSET) & 0xf) <= 0x2) {
565                 unsigned int sbmr = readl(SRC_BASE_ADDR + 0x4);
566
567                 /* This issue is fixed in MX51 TO 3.0 */
568                 /* Workaround to disable WARM RESET when booting from interleaved NAND devices */
569                 if ((num_of_chips > 1) && (SBMR_BT_MEM_CTL(sbmr) == 1)) {
570                         diag_printf("%s: Disabling WARM reset due to boot from interleaved NAND\n", __FUNCTION__);
571                         src_scr_reg = readl(SRC_BASE_ADDR);
572                         src_scr_reg &= ~0x1;
573                         writel(src_scr_reg, SRC_BASE_ADDR);
574                 }
575         }
576
577         return MXC_NFC_V3;
578 }
579 #endif
580
581 static void show_sys_info(void)
582 {
583         unsigned int sbmr = readl(SRC_BASE_ADDR + 0x4);
584         const char *dlm = "";
585
586         if (find_correct_chip == CHIP_VERSION_UNKNOWN) {
587                 diag_printf("Unrecognized chip version: 0x%08x!!!\n", read_system_rev());
588                 diag_printf("Assuming chip version=0x%08x\n", system_rev);
589         } else if (find_correct_chip == CHIP_VERSION_NONE) {
590                 diag_printf("Unrecognized chip: 0x%08x!!!\n", readl(IIM_BASE_ADDR + IIM_PREV_OFF));
591         }
592
593         diag_printf("Reset reason: ");
594
595         if (_reset_reason & (1 << 0)) {
596                 diag_printf("%sPOWER_ON", dlm);
597                 dlm = " | ";
598         }
599         if (_reset_reason & (1 << 2)) {
600                 diag_printf("%sCSU", dlm);
601                 dlm = " | ";
602         }
603         if (_reset_reason & (1 << 3)) {
604                 diag_printf("%sUSER", dlm);
605                 dlm = " | ";
606         }
607         if (_reset_reason & (1 << 4)) {
608                 CYG_WORD16 wrsr;
609
610                 HAL_READ_UINT16(WDOG_BASE_ADDR + 4, wrsr);
611                 if (wrsr & 0x01) {
612                         diag_printf("%sSOFT", dlm);
613                         dlm = " | ";
614                 }
615                 if (wrsr & 0x10) {
616                         diag_printf("%sWATCHDOG", dlm);
617                         dlm = " | ";
618                 }
619         }
620         if (_reset_reason & (1 << 5)) {
621                 diag_printf("%sJTAG_HW", dlm);
622                 dlm = " | ";
623         }
624         if (_reset_reason & (1 << 6)) {
625                 diag_printf("%sJTAG_SW", dlm);
626                 dlm = " | ";
627         }
628         if (_reset_reason & (1 << 16)) {
629                 diag_printf("%sWARM BOOT", dlm);
630                 dlm = " | ";
631         }
632
633         if (*dlm == '\0') {
634                 diag_printf("UNKNOWN: %08x\n", _reset_reason);
635         } else {
636                 diag_printf(" RESET\n");
637         }
638
639         if (_mxc_fis == MMC_FLASH_BOOT) {
640                 diag_printf("fis/fconfig from MMC\n");
641         } else if (_mxc_fis == SPI_NOR_FLASH_BOOT) {
642                 diag_printf("fis/fconfig from SPI-NOR\n");
643         } else if (_mxc_fis == NAND_FLASH_BOOT) {
644                 diag_printf("fis/fconfig from NAND\n");
645         } else {
646                 diag_printf("Use \"factive [MMC|SPI|NAND]\" to choose fis/fconfig storage\n");
647         }
648
649         diag_printf("SBMR = 0x%08x\n", readl(SRC_BASE_ADDR + 0x4));
650         diag_printf("Boot switch: ");
651         if ((SBMR_BMOD(sbmr)) == 0) {
652                 diag_printf("INTERNAL (GPIO)\n");
653         } else if ((SBMR_BMOD(sbmr)) == 2) {
654                 diag_printf("INTERNAL (FUSE)\n");
655         } else if ((SBMR_BMOD(sbmr)) == 3){
656                 diag_printf("BOOTSTRAP\n");
657         } else if ((SBMR_BMOD(sbmr)) == 0x1 && (SBMR_DIR_BT_DIS(sbmr)) == 0) {
658                 diag_printf("TEST EXEC\n");
659         } else {
660                 diag_printf("UNKNOWN: 0x%x\n", SBMR_BMOD(sbmr));
661         }
662         diag_printf("\t");
663         if ((SBMR_BT_MEM_CTL(sbmr)) == 0) {
664                 diag_printf("WEIM: ");
665                 if ((SBMR_BT_MEM_TYPE(sbmr)) == 0) {
666                         diag_printf("NOR");
667                 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 2) {
668                         diag_printf("ONE NAND");
669                 } else {
670                         diag_printf("UNKNOWN: 0x%x", SBMR_BT_MEM_TYPE(sbmr));
671                 }
672         } else if ((SBMR_BT_MEM_CTL(sbmr)) == 1) {
673                 diag_printf("NAND: ADDR CYCLES:");
674                 if ((SBMR_BT_MEM_TYPE(sbmr)) == 0) {
675                         diag_printf("3: ");
676                 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 1) {
677                         diag_printf("4: ");
678                 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 2) {
679                         diag_printf("5: ");
680                 } else {
681                         diag_printf("UNKNOWN: 0x%x ", SBMR_BT_MEM_TYPE(sbmr));
682                 }
683                 if (SBMR_BT_MLC_SEL(sbmr) == 0) {
684                         diag_printf("SLC: ");
685                 } else {
686                         diag_printf("MLC: ");
687                 }
688                 if ((SBMR_BT_SPARE_SIZE(sbmr)) == 0) {
689                         diag_printf("128B spare (4-bit ECC): ");
690                 } else {
691                         diag_printf("218B spare (8-bit ECC): ");
692                 }
693                 diag_printf("PAGE SIZE: ");
694                 if ((SBMR_BT_PAGE_SIZE(sbmr)) == 0) {
695                         diag_printf("512: ");
696                 } else if ((SBMR_BT_PAGE_SIZE(sbmr)) == 1) {
697                         diag_printf("2K: ");
698                 } else if ((SBMR_BT_PAGE_SIZE(sbmr)) == 2) {
699                         diag_printf("4K: ");
700                 } else {
701                         diag_printf("UNKNOWN: 0x%x", SBMR_BT_PAGE_SIZE(sbmr));
702                 }
703                 diag_printf("BUS WIDTH: ");
704                 if ((SBMR_BT_BUS_WIDTH(sbmr)) == 0) {
705                         diag_printf("8");
706                 } else {
707                         diag_printf("16");
708                 }
709         } else if ((SBMR_BT_MEM_CTL(sbmr)) == 3) {
710                 diag_printf("EXPANSION: ");
711                 if ((SBMR_BT_MEM_TYPE(sbmr)) == 0) {
712                         diag_printf("SD/MMC-%d", (SBMR_BT_SDMMC_SRC(sbmr)));
713                 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 2) {
714                         diag_printf("I2C-NOR: ");
715                         if ((SBMR_BT_SDMMC_SRC(sbmr)) == 0) {
716                                 diag_printf("I2C-1");
717                         } else if ((SBMR_BT_SDMMC_SRC(sbmr)) == 1) {
718                                 diag_printf("I2C-2");
719                         } else if ((SBMR_BT_SDMMC_SRC(sbmr)) == 2) {
720                                 diag_printf("HS-I2C");
721                         } else {
722                                 diag_printf("UNKNOWN: 0x%x", SBMR_BT_SDMMC_SRC(sbmr));
723                         }
724                 } else if ((SBMR_BT_MEM_TYPE(sbmr)) == 3) {
725                         diag_printf("SPI-NOR: ");
726                         if ((SBMR_BT_SDMMC_SRC(sbmr)) == 0) {
727                                 diag_printf("eCSPI1");
728                         } else if ((SBMR_BT_SDMMC_SRC(sbmr)) == 1) {
729                                 diag_printf("eCSPI2");
730                         } else if ((SBMR_BT_SDMMC_SRC(sbmr)) == 2) {
731                                 diag_printf("CSPI");
732                         } else {
733                                 diag_printf("UNKNOWN: 0x%x", SBMR_BT_SDMMC_SRC(sbmr));
734                         }
735                 } else {
736                         diag_printf("UNKNOWN: 0x%x", SBMR_BT_MEM_TYPE(sbmr));
737                 }
738         } else {
739                 diag_printf("UNKNOWN: 0x%x", SBMR_BT_MEM_CTL(sbmr));
740         }
741         diag_printf("\n");
742 }
743
744 RedBoot_init(show_sys_info, RedBoot_INIT_LAST);