X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Fpowerpc%2Fcpu%2Fppc4xx%2Fcpu_init.c;h=4013a0c24ae2aac5337172a819d80cf388f17250;hb=dc557e9a1fe00ca9d884bd88feef5bebf23fede4;hp=2a727b1df38b94b96a27ba70dddd02a886c3a6a9;hpb=db682a0b59b2e97b24275214f1837197a73fdb03;p=oweals%2Fu-boot.git diff --git a/arch/powerpc/cpu/ppc4xx/cpu_init.c b/arch/powerpc/cpu/ppc4xx/cpu_init.c index 2a727b1df3..4013a0c24a 100644 --- a/arch/powerpc/cpu/ppc4xx/cpu_init.c +++ b/arch/powerpc/cpu/ppc4xx/cpu_init.c @@ -2,23 +2,7 @@ * (C) Copyright 2000-2007 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -28,9 +12,7 @@ #include #include -#if defined(CONFIG_405GP) || defined(CONFIG_405EP) DECLARE_GLOBAL_DATA_PTR; -#endif #ifndef CONFIG_SYS_PLL_RECONFIG #define CONFIG_SYS_PLL_RECONFIG 0 @@ -221,6 +203,66 @@ void reconfigure_pll(u32 new_cpu_freq) #endif } +#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA +void +chip_21_errata(void) +{ + /* + * See rev 1.09 of the 405EX/405EXr errata. CHIP_21 says that + * sometimes reading the PVR and/or SDR0_ECID results in incorrect + * values. Since the rev-D chip uses the SDR0_ECID bits to control + * internal features, that means the second PCIe or ethernet of an EX + * variant could fail to work. Also, security features of both EX and + * EXr might be incorrectly disabled. + * + * The suggested workaround is as follows (covering rev-C and rev-D): + * + * 1.Read the PVR and SDR0_ECID3. + * + * 2.If the PVR matches an expected Revision C PVR value AND if + * SDR0_ECID3[12:15] is different from PVR[28:31], then processor is + * Revision C: continue executing the initialization code (no reset + * required). else go to step 3. + * + * 3.If the PVR matches an expected Revision D PVR value AND if + * SDR0_ECID3[10:11] matches its expected value, then continue + * executing initialization code, no reset required. else write + * DBCR0[RST] = 0b11 to generate a SysReset. + */ + + u32 pvr; + u32 pvr_28_31; + u32 ecid3; + u32 ecid3_10_11; + u32 ecid3_12_15; + + /* Step 1: */ + pvr = get_pvr(); + mfsdr(SDR0_ECID3, ecid3); + + /* Step 2: */ + pvr_28_31 = pvr & 0xf; + ecid3_10_11 = (ecid3 >> 20) & 0x3; + ecid3_12_15 = (ecid3 >> 16) & 0xf; + if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_C) && + (pvr_28_31 != ecid3_12_15)) { + /* No reset required. */ + return; + } + + /* Step 3: */ + if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_D) && + (ecid3_10_11 == CONFIG_405EX_CHIP21_ECID3_REV_D)) { + /* No reset required. */ + return; + } + + /* Reset required. */ + __asm__ __volatile__ ("sync; isync"); + mtspr(SPRN_DBCR0, 0x30000000); +} +#endif + /* * Breath some life into the CPU... * @@ -235,10 +277,14 @@ cpu_init_f (void) u32 val; #endif +#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA + chip_21_errata(); +#endif + reconfigure_pll(CONFIG_SYS_PLL_RECONFIG); #if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && \ - !defined(CONFIG_APM821XX) &&!defined(CONFIG_SYS_4xx_GPIO_TABLE) + !defined(CONFIG_SYS_4xx_GPIO_TABLE) /* * GPIO0 setup (select GPIO or alternate function) */ @@ -278,7 +324,7 @@ cpu_init_f (void) * External Bus Controller (EBC) Setup */ #if (defined(CONFIG_SYS_EBC_PB0AP) && defined(CONFIG_SYS_EBC_PB0CR)) -#if (defined(CONFIG_405GP) || defined(CONFIG_405CR) || \ +#if (defined(CONFIG_405GP) || \ defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \ defined(CONFIG_405EX) || defined(CONFIG_405)) /* @@ -342,7 +388,7 @@ cpu_init_f (void) #endif #if defined(CONFIG_WATCHDOG) - val = mfspr(tcr); + val = mfspr(SPRN_TCR); #if defined(CONFIG_440EP) || defined(CONFIG_440GR) val |= 0xb8000000; /* generate system reset after 1.34 seconds */ #elif defined(CONFIG_440EPX) @@ -354,11 +400,11 @@ cpu_init_f (void) val &= ~0x30000000; /* clear WRC bits */ val |= CONFIG_SYS_4xx_RESET_TYPE << 28; /* set board specific WRC type */ #endif - mtspr(tcr, val); + mtspr(SPRN_TCR, val); - val = mfspr(tsr); + val = mfspr(SPRN_TSR); val |= 0x80000000; /* enable watchdog timer */ - mtspr(tsr, val); + mtspr(SPRN_TSR, val); reset_4xx_watchdog(); #endif /* CONFIG_WATCHDOG */ @@ -394,7 +440,7 @@ cpu_init_f (void) #if defined(CONFIG_405EX) || \ defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ - defined(CONFIG_460SX) || defined(CONFIG_APM821XX) + defined(CONFIG_460SX) /* * Set PLB4 arbiter (Segment 0 and 1) to 4 deep pipeline read */