X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=arch%2Fblackfin%2Fcpu%2Finitcode.c;h=750add06bcefc9db0276c63b464e5fe5d0098aa1;hb=9aeab10bd4ae31518ec8a21c51f4e3b16c66a1ee;hp=9453d5dc4dfc37bc0865bcf9dbd5a6b6fb2fbd87;hpb=b30453ace4eb930ab224012bd2367fa3d1337ced;p=karo-tx-uboot.git diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c index 9453d5dc4d..750add06bc 100644 --- a/arch/blackfin/cpu/initcode.c +++ b/arch/blackfin/cpu/initcode.c @@ -101,6 +101,28 @@ static inline void serial_putc(char c) continue; } +__attribute__((always_inline)) static inline void +program_nmi_handler(void) +{ + u32 tmp1, tmp2; + + /* Older bootroms don't create a dummy NMI handler, + * so make one ourselves ASAP in case it fires. + */ + if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS && !ANOMALY_05000219) + return; + + asm volatile ( + "%0 = RETS;" /* Save current RETS */ + "CALL 1f;" /* Figure out current PC */ + "RTN;" /* The simple NMI handler */ + "1:" + "%1 = RETS;" /* Load addr of NMI handler */ + "RETS = %0;" /* Restore RETS */ + "[%2] = %1;" /* Write NMI handler */ + : "=r"(tmp1), "=r"(tmp2) : "ab"(EVT2) + ); +} /* Max SCLK can be 133MHz ... dividing that by (2*4) gives * us a freq of 16MHz for SPI which should generally be @@ -319,13 +341,13 @@ maybe_self_refresh(ADI_BOOT_DATA *bs) return false; /* If external memory is enabled, put it into self refresh first. */ -#ifdef EBIU_RSTCTL +#if defined(EBIU_RSTCTL) if (bfin_read_EBIU_RSTCTL() & DDR_SRESET) { serial_putc('b'); bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | SRREQ); return true; } -#else +#elif defined(EBIU_SDGCTL) if (bfin_read_EBIU_SDBCTL() & EBE) { serial_putc('b'); bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() | SRFS); @@ -351,12 +373,15 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs) /* If we're entering self refresh, make sure it has happened. */ if (put_into_srfs) -#ifdef EBIU_RSTCTL +#if defined(EBIU_RSTCTL) while (!(bfin_read_EBIU_RSTCTL() & SRACK)) -#else + continue; +#elif defined(EBIU_SDGCTL) while (!(bfin_read_EBIU_SDSTAT() & SDSRA)) -#endif continue; +#else + ; +#endif serial_putc('c'); @@ -369,7 +394,9 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs) /* Always programming PLL_LOCKCNT avoids Anomaly 05000430 */ ADI_SYSCTRL_VALUES memory_settings; - uint32_t actions = SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV | SYSCTRL_LOCKCNT; + uint32_t actions = SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_LOCKCNT; + if (!ANOMALY_05000440) + actions |= SYSCTRL_PLLDIV; if (CONFIG_HAS_VR) { actions |= SYSCTRL_VRCTL; if (CONFIG_VR_CTL_VAL & FREQ_MASK) @@ -388,6 +415,8 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs) serial_putc('e'); bfrom_SysControl(actions, &memory_settings, NULL); serial_putc('f'); + if (ANOMALY_05000440) + bfin_write_PLL_DIV(CONFIG_PLL_DIV_VAL); #if ANOMALY_05000432 bfin_write_SIC_IWR1(-1); #endif @@ -510,7 +539,7 @@ program_memory_controller(ADI_BOOT_DATA *bs, bool put_into_srfs) /* Program the external memory controller before we come out of * self-refresh. This only works with our SDRAM controller. */ -#ifndef EBIU_RSTCTL +#ifdef EBIU_SDGCTL # ifdef CONFIG_EBIU_SDRRC_VAL bfin_write_EBIU_SDRRC(CONFIG_EBIU_SDRRC_VAL); # endif @@ -526,9 +555,9 @@ program_memory_controller(ADI_BOOT_DATA *bs, bool put_into_srfs) /* Now that we've reprogrammed, take things out of self refresh. */ if (put_into_srfs) -#ifdef EBIU_RSTCTL +#if defined(EBIU_RSTCTL) bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ)); -#else +#elif defined(EBIU_SDGCTL) bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() & ~(SRFS)); #endif @@ -620,10 +649,10 @@ program_async_controller(ADI_BOOT_DATA *bs) serial_putc('b'); /* Not all parts have these additional MMRs. */ -#ifdef EBIU_MODE -# ifdef CONFIG_EBIU_MBSCTL_VAL +#ifdef EBIU_MBSCTL bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL); -# endif +#endif +#ifdef EBIU_MODE # ifdef CONFIG_EBIU_MODE_VAL bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL); # endif @@ -640,6 +669,9 @@ void initcode(ADI_BOOT_DATA *bs) { ADI_BOOT_DATA bootstruct_scratch; + /* Setup NMI handler before anything else */ + program_nmi_handler(); + serial_init(); serial_putc('A');