* (C) Copyright 2000
* 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 <common.h>
#include <asm/io.h>
#include <asm/cache.h>
#include <asm/mmu.h>
+#include <asm/fsl_errata.h>
#include <asm/fsl_law.h>
#include <asm/fsl_serdes.h>
#include <asm/fsl_srio.h>
+#include <fsl_usb.h>
#include <hwconfig.h>
#include <linux/compiler.h>
#include "mp.h"
+#ifdef CONFIG_FSL_CAAM
+#include <fsl_sec.h>
+#endif
#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND
#include <nand.h>
#include <errno.h>
#endif
#include "../../../../drivers/block/fsl_sata.h"
+#ifdef CONFIG_U_QE
+#include "../../../../drivers/qe/qe.h"
+#endif
DECLARE_GLOBAL_DATA_PTR;
-#ifdef CONFIG_QE
+#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
+/*
+ * For deriving usb clock from 100MHz sysclk, reference divisor is set
+ * to a value of 5, which gives an intermediate value 20(100/5). The
+ * multiplication factor integer is set to 24, which when multiplied to
+ * above intermediate value provides clock for usb ip.
+ */
+void usb_single_source_clk_configure(struct ccsr_usb_phy *usb_phy)
+{
+ sys_info_t sysinfo;
+
+ get_sys_info(&sysinfo);
+ if (sysinfo.diff_sysclk == 1) {
+ clrbits_be32(&usb_phy->pllprg[1],
+ CONFIG_SYS_FSL_USB_PLLPRG2_MFI);
+ setbits_be32(&usb_phy->pllprg[1],
+ CONFIG_SYS_FSL_USB_PLLPRG2_REF_DIV_INTERNAL_CLK |
+ CONFIG_SYS_FSL_USB_PLLPRG2_MFI_INTERNAL_CLK |
+ CONFIG_SYS_FSL_USB_INTERNAL_SOC_CLK_EN);
+ }
+}
+#endif
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006261
+void fsl_erratum_a006261_workaround(struct ccsr_usb_phy __iomem *usb_phy)
+{
+#ifdef CONFIG_SYS_FSL_USB_DUAL_PHY_ENABLE
+ u32 xcvrprg = in_be32(&usb_phy->port1.xcvrprg);
+
+ /* Increase Disconnect Threshold by 50mV */
+ xcvrprg &= ~CONFIG_SYS_FSL_USB_XCVRPRG_HS_DCNT_PROG_MASK |
+ INC_DCNT_THRESHOLD_50MV;
+ /* Enable programming of USB High speed Disconnect threshold */
+ xcvrprg |= CONFIG_SYS_FSL_USB_XCVRPRG_HS_DCNT_PROG_EN;
+ out_be32(&usb_phy->port1.xcvrprg, xcvrprg);
+
+ xcvrprg = in_be32(&usb_phy->port2.xcvrprg);
+ /* Increase Disconnect Threshold by 50mV */
+ xcvrprg &= ~CONFIG_SYS_FSL_USB_XCVRPRG_HS_DCNT_PROG_MASK |
+ INC_DCNT_THRESHOLD_50MV;
+ /* Enable programming of USB High speed Disconnect threshold */
+ xcvrprg |= CONFIG_SYS_FSL_USB_XCVRPRG_HS_DCNT_PROG_EN;
+ out_be32(&usb_phy->port2.xcvrprg, xcvrprg);
+#else
+
+ u32 temp = 0;
+ u32 status = in_be32(&usb_phy->status1);
+
+ u32 squelch_prog_rd_0_2 =
+ (status >> CONFIG_SYS_FSL_USB_SQUELCH_PROG_RD_0)
+ & CONFIG_SYS_FSL_USB_SQUELCH_PROG_MASK;
+
+ u32 squelch_prog_rd_3_5 =
+ (status >> CONFIG_SYS_FSL_USB_SQUELCH_PROG_RD_3)
+ & CONFIG_SYS_FSL_USB_SQUELCH_PROG_MASK;
+
+ setbits_be32(&usb_phy->config1,
+ CONFIG_SYS_FSL_USB_HS_DISCNCT_INC);
+ setbits_be32(&usb_phy->config2,
+ CONFIG_SYS_FSL_USB_RX_AUTO_CAL_RD_WR_SEL);
+
+ temp = squelch_prog_rd_0_2 << CONFIG_SYS_FSL_USB_SQUELCH_PROG_WR_0;
+ out_be32(&usb_phy->config2, in_be32(&usb_phy->config2) | temp);
+
+ temp = squelch_prog_rd_3_5 << CONFIG_SYS_FSL_USB_SQUELCH_PROG_WR_3;
+ out_be32(&usb_phy->config2, in_be32(&usb_phy->config2) | temp);
+#endif
+}
+#endif
+
+
+#if defined(CONFIG_QE) && !defined(CONFIG_U_QE)
extern qe_iop_conf_t qe_iop_conf_tab[];
extern void qe_config_iopin(u8 port, u8 pin, int dir,
int open_drain, int assign);
#endif
#ifdef CONFIG_SYS_FSL_CPC
-static void enable_cpc(void)
+#if defined(CONFIG_RAMBOOT_PBL) || defined(CONFIG_SYS_CPC_REINIT_F)
+void disable_cpc_sram(void)
{
int i;
- u32 size = 0;
cpc_corenet_t *cpc = (cpc_corenet_t *)CONFIG_SYS_FSL_CPC_ADDR;
for (i = 0; i < CONFIG_SYS_NUM_CPC; i++, cpc++) {
- u32 cpccfg0 = in_be32(&cpc->cpccfg0);
- size += CPC_CFG0_SZ_K(cpccfg0);
-#ifdef CONFIG_RAMBOOT_PBL
if (in_be32(&cpc->cpcsrcr0) & CPC_SRCR0_SRAMEN) {
/* find and disable LAW of SRAM */
struct law_entry law = find_law(CONFIG_SYS_INIT_L3_ADDR);
out_be32(&cpc->cpccsr0, 0);
out_be32(&cpc->cpcsrcr0, 0);
}
+ }
+}
#endif
+#if defined(T1040_TDM_QUIRK_CCSR_BASE)
+#ifdef CONFIG_POST
+#error POST memory test cannot be enabled with TDM
+#endif
+static void enable_tdm_law(void)
+{
+ int ret;
+ char buffer[HWCONFIG_BUFFER_SIZE] = {0};
+ int tdm_hwconfig_enabled = 0;
+
+ /*
+ * Extract hwconfig from environment since environment
+ * is not setup properly yet. Search for tdm entry in
+ * hwconfig.
+ */
+ ret = getenv_f("hwconfig", buffer, sizeof(buffer));
+ if (ret > 0) {
+ tdm_hwconfig_enabled = hwconfig_f("tdm", buffer);
+ /* If tdm is defined in hwconfig, set law for tdm workaround */
+ if (tdm_hwconfig_enabled)
+ set_next_law(T1040_TDM_QUIRK_CCSR_BASE, LAW_SIZE_16M,
+ LAW_TRGT_IF_CCSR);
+ }
+}
+#endif
+
+void enable_cpc(void)
+{
+ int i;
+ int ret;
+ u32 size = 0;
+ u32 cpccfg0;
+ char buffer[HWCONFIG_BUFFER_SIZE];
+ char cpc_subarg[16];
+ bool have_hwconfig = false;
+ int cpc_args = 0;
+ cpc_corenet_t *cpc = (cpc_corenet_t *)CONFIG_SYS_FSL_CPC_ADDR;
+
+ /* Extract hwconfig from environment */
+ ret = getenv_f("hwconfig", buffer, sizeof(buffer));
+ if (ret > 0) {
+ /*
+ * If "en_cpc" is not defined in hwconfig then by default all
+ * cpcs are enable. If this config is defined then individual
+ * cpcs which have to be enabled should also be defined.
+ * e.g en_cpc:cpc1,cpc2;
+ */
+ if (hwconfig_f("en_cpc", buffer))
+ have_hwconfig = true;
+ }
+
+ for (i = 0; i < CONFIG_SYS_NUM_CPC; i++, cpc++) {
+ if (have_hwconfig) {
+ sprintf(cpc_subarg, "cpc%u", i + 1);
+ cpc_args = hwconfig_sub_f("en_cpc", cpc_subarg, buffer);
+ if (cpc_args == 0)
+ continue;
+ }
+ cpccfg0 = in_be32(&cpc->cpccfg0);
+ size += CPC_CFG0_SZ_K(cpccfg0);
+
#ifdef CONFIG_SYS_FSL_ERRATUM_CPC_A002
setbits_be32(&cpc->cpchdbcr0, CPC_HDBCR0_TAG_ECC_SCRUB_DIS);
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A006593
setbits_be32(&cpc->cpchdbcr0, 1 << (31 - 21));
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006379
+ if (has_erratum_a006379()) {
+ setbits_be32(&cpc->cpchdbcr0,
+ CPC_HDBCR0_SPLRU_LEVEL_EN);
+ }
+#endif
out_be32(&cpc->cpccsr0, CPC_CSR0_CE | CPC_CSR0_PE);
/* Read back to sync write */
}
- printf("Corenet Platform Cache: %d KB enabled\n", size);
+ puts("Corenet Platform Cache: ");
+ print_size(size * 1024, " enabled\n");
}
static void invalidate_cpc(void)
#else
#define enable_cpc()
#define invalidate_cpc()
+#define disable_cpc_sram()
#endif /* CONFIG_SYS_FSL_CPC */
/*
}
#endif
-void cpu_init_f (void)
+#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
+void fsl_erratum_a007212_workaround(void)
+{
+ ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ u32 ddr_pll_ratio;
+ u32 __iomem *plldgdcr1 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c20);
+ u32 __iomem *plldadcr1 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c28);
+ u32 __iomem *dpdovrcr4 = (void *)(CONFIG_SYS_DCSRBAR + 0x21e80);
+#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
+ u32 __iomem *plldgdcr2 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c40);
+ u32 __iomem *plldadcr2 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c48);
+#if (CONFIG_NUM_DDR_CONTROLLERS >= 3)
+ u32 __iomem *plldgdcr3 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c60);
+ u32 __iomem *plldadcr3 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c68);
+#endif
+#endif
+ /*
+ * Even this workaround applies to selected version of SoCs, it is
+ * safe to apply to all versions, with the limitation of odd ratios.
+ * If RCW has disabled DDR PLL, we have to apply this workaround,
+ * otherwise DDR will not work.
+ */
+ ddr_pll_ratio = (in_be32(&gur->rcwsr[0]) >>
+ FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT) &
+ FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
+ /* check if RCW sets ratio to 0, required by this workaround */
+ if (ddr_pll_ratio != 0)
+ return;
+ ddr_pll_ratio = (in_be32(&gur->rcwsr[0]) >>
+ FSL_CORENET_RCWSR0_MEM_PLL_RAT_RESV_SHIFT) &
+ FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
+ /* check if reserved bits have the desired ratio */
+ if (ddr_pll_ratio == 0) {
+ printf("Error: Unknown DDR PLL ratio!\n");
+ return;
+ }
+ ddr_pll_ratio >>= 1;
+
+ setbits_be32(plldadcr1, 0x02000001);
+#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
+ setbits_be32(plldadcr2, 0x02000001);
+#if (CONFIG_NUM_DDR_CONTROLLERS >= 3)
+ setbits_be32(plldadcr3, 0x02000001);
+#endif
+#endif
+ setbits_be32(dpdovrcr4, 0xe0000000);
+ out_be32(plldgdcr1, 0x08000001 | (ddr_pll_ratio << 1));
+#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
+ out_be32(plldgdcr2, 0x08000001 | (ddr_pll_ratio << 1));
+#if (CONFIG_NUM_DDR_CONTROLLERS >= 3)
+ out_be32(plldgdcr3, 0x08000001 | (ddr_pll_ratio << 1));
+#endif
+#endif
+ udelay(100);
+ clrbits_be32(plldadcr1, 0x02000001);
+#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
+ clrbits_be32(plldadcr2, 0x02000001);
+#if (CONFIG_NUM_DDR_CONTROLLERS >= 3)
+ clrbits_be32(plldadcr3, 0x02000001);
+#endif
+#endif
+ clrbits_be32(dpdovrcr4, 0xe0000000);
+}
+#endif
+
+ulong cpu_init_f(void)
{
extern void m8560_cpm_reset (void);
-#ifdef CONFIG_SYS_DCSRBAR_PHYS
+#if defined(CONFIG_SYS_DCSRBAR_PHYS) || \
+ (defined(CONFIG_SECURE_BOOT) && defined(CONFIG_FSL_CORENET))
ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
#endif
#if defined(CONFIG_SECURE_BOOT)
law = find_law(CONFIG_SYS_PBI_FLASH_BASE);
if (law.index != -1)
disable_law(law.index);
+
+#if defined(CONFIG_SYS_CPC_REINIT_F)
+ disable_cpc_sram();
+#endif
+
+#if defined(CONFIG_FSL_CORENET)
+ /* Put PAMU in bypass mode */
+ out_be32(&gur->pamubypenr, FSL_CORENET_PAMU_BYPASS);
+#endif
+
#endif
#ifdef CONFIG_CPM2
#if defined(CONFIG_CPM2)
m8560_cpm_reset();
#endif
-#ifdef CONFIG_QE
+
+#if defined(CONFIG_QE) && !defined(CONFIG_U_QE)
/* Config QE ioports */
config_qe_ioports();
#endif
+
#if defined(CONFIG_FSL_DMA)
dma_init();
#endif
in_be32(&gur->dcsrcr);
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
+ fsl_erratum_a007212_workaround();
+#endif
+
+ return 0;
}
/* Implement a dummy function for those platforms w/o SERDES */
}
__attribute__((weak, alias("__fsl_serdes__init"))) void fsl_serdes_init(void);
-#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
+#if defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && defined(CONFIG_E6500)
int enable_cluster_l2(void)
{
int i = 0;
- u32 cluster;
+ u32 cluster, svr = get_svr();
ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
struct ccsr_cluster_l2 __iomem *l2cache;
+ /* only the L2 of first cluster should be enabled as expected on T4080,
+ * but there is no EOC in the first cluster as HW sake, so return here
+ * to skip enabling L2 cache of the 2nd cluster.
+ */
+ if (SVR_SOC_VER(svr) == SVR_T4080)
+ return 0;
+
cluster = in_be32(&gur->tp_cluster[i].lower);
if (cluster & TP_CLUSTER_EOC)
return 0;
u32 idx = (cluster >> (j*8)) & TP_CLUSTER_INIT_MASK;
u32 type = in_be32(&gur->tp_ityp[idx]);
- if (type & TP_ITYP_AV)
+ if ((type & TP_ITYP_AV) &&
+ TP_ITYP_TYPE(type) == TP_ITYP_TYPE_PPC)
cluster_valid = 1;
}
/*
* Initialize L2 as cache.
- *
- * The newer 8548, etc, parts have twice as much cache, but
- * use the same bit-encoding as the older 8555, etc, parts.
- *
*/
-int cpu_init_r(void)
+int l2cache_init(void)
{
__maybe_unused u32 svr = get_svr();
-#ifdef CONFIG_SYS_LBC_LCRR
- fsl_lbc_t *lbc = (void __iomem *)LBC_BASE_ADDR;
-#endif
#ifdef CONFIG_L2_CACHE
ccsr_l2cache_t *l2cache = (void __iomem *)CONFIG_SYS_MPC85xx_L2_ADDR;
-#elif defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2)
+#elif defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && defined(CONFIG_E6500)
struct ccsr_cluster_l2 * l2cache = (void __iomem *)CONFIG_SYS_FSL_CLUSTER_1_L2;
#endif
-#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
- extern int spin_table_compat;
- const char *spin;
-#endif
-
-#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \
- defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011)
- /*
- * CPU22 and NMG_CPU_A011 share the same workaround.
- * CPU22 applies to P4080 rev 1.0, 2.0, fixed in 3.0
- * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0
- * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1, both
- * fixed in 2.0. NMG_CPU_A011 is activated by default and can
- * be disabled by hwconfig with syntax:
- *
- * fsl_cpu_a011:disable
- */
- extern int enable_cpu_a011_workaround;
-#ifdef CONFIG_SYS_P4080_ERRATUM_CPU22
- enable_cpu_a011_workaround = (SVR_MAJ(svr) < 3);
-#else
- char buffer[HWCONFIG_BUFFER_SIZE];
- char *buf = NULL;
- int n, res;
-
- n = getenv_f("hwconfig", buffer, sizeof(buffer));
- if (n > 0)
- buf = buffer;
-
- res = hwconfig_arg_cmp_f("fsl_cpu_a011", "disable", buf);
- if (res > 0)
- enable_cpu_a011_workaround = 0;
- else {
- if (n >= HWCONFIG_BUFFER_SIZE) {
- printf("fsl_cpu_a011 was not found. hwconfig variable "
- "may be too long\n");
- }
- enable_cpu_a011_workaround =
- (SVR_SOC_VER(svr) == SVR_P4080 && SVR_MAJ(svr) < 3) ||
- (SVR_SOC_VER(svr) != SVR_P4080 && SVR_MAJ(svr) < 2);
- }
-#endif
- if (enable_cpu_a011_workaround) {
- flush_dcache();
- mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS));
- sync();
- }
-#endif
-
-#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
- spin = getenv("spin_table_compat");
- if (spin && (*spin == 'n'))
- spin_table_compat = 0;
- else
- spin_table_compat = 1;
-#endif
puts ("L2: ");
case 0x1:
if (ver == SVR_8540 || ver == SVR_8560 ||
ver == SVR_8541 || ver == SVR_8555) {
- puts("128 KB ");
- /* set L2E=1, L2I=1, & L2BLKSZ=1 (128 Kbyte) */
+ puts("128 KiB ");
+ /* set L2E=1, L2I=1, & L2BLKSZ=1 (128 KiBibyte) */
cache_ctl = 0xc4000000;
} else {
- puts("256 KB ");
+ puts("256 KiB ");
cache_ctl = 0xc0000000; /* set L2E=1, L2I=1, & L2SRAM=0 */
}
break;
case 0x2:
if (ver == SVR_8540 || ver == SVR_8560 ||
ver == SVR_8541 || ver == SVR_8555) {
- puts("256 KB ");
- /* set L2E=1, L2I=1, & L2BLKSZ=2 (256 Kbyte) */
+ puts("256 KiB ");
+ /* set L2E=1, L2I=1, & L2BLKSZ=2 (256 KiBibyte) */
cache_ctl = 0xc8000000;
} else {
- puts ("512 KB ");
+ puts("512 KiB ");
/* set L2E=1, L2I=1, & L2SRAM=0 */
cache_ctl = 0xc0000000;
}
break;
case 0x3:
- puts("1024 KB ");
+ puts("1024 KiB ");
/* set L2E=1, L2I=1, & L2SRAM=0 */
cache_ctl = 0xc0000000;
break;
if (CONFIG_SYS_INIT_L2CSR0 & L2CSR0_L2E) {
while (!(mfspr(SPRN_L2CSR0) & L2CSR0_L2E))
;
- printf("%d KB enabled\n", (l2cfg0 & 0x3fff) * 64);
+ print_size((l2cfg0 & 0x3fff) * 64 * 1024, " enabled\n");
}
skip_l2:
-#elif defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2)
+#elif defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && defined(CONFIG_E6500)
if (l2cache->l2csr0 & L2CSR0_L2E)
- printf("%d KB enabled\n", (l2cache->l2cfg0 & 0x3fff) * 64);
+ print_size((l2cache->l2cfg0 & 0x3fff) * 64 * 1024,
+ " enabled\n");
enable_cluster_l2();
#else
puts("disabled\n");
#endif
+ return 0;
+}
+
+/*
+ *
+ * The newer 8548, etc, parts have twice as much cache, but
+ * use the same bit-encoding as the older 8555, etc, parts.
+ *
+ */
+int cpu_init_r(void)
+{
+ __maybe_unused u32 svr = get_svr();
+#ifdef CONFIG_SYS_LBC_LCRR
+ fsl_lbc_t *lbc = (void __iomem *)LBC_BASE_ADDR;
+#endif
+#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
+ extern int spin_table_compat;
+ const char *spin;
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_SEC_A003571
+ ccsr_sec_t __iomem *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+#endif
+#if defined(CONFIG_SYS_P4080_ERRATUM_CPU22) || \
+ defined(CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011)
+ /*
+ * CPU22 and NMG_CPU_A011 share the same workaround.
+ * CPU22 applies to P4080 rev 1.0, 2.0, fixed in 3.0
+ * NMG_CPU_A011 applies to P4080 rev 1.0, 2.0, fixed in 3.0
+ * also applies to P3041 rev 1.0, 1.1, P2041 rev 1.0, 1.1, both
+ * fixed in 2.0. NMG_CPU_A011 is activated by default and can
+ * be disabled by hwconfig with syntax:
+ *
+ * fsl_cpu_a011:disable
+ */
+ extern int enable_cpu_a011_workaround;
+#ifdef CONFIG_SYS_P4080_ERRATUM_CPU22
+ enable_cpu_a011_workaround = (SVR_MAJ(svr) < 3);
+#else
+ char buffer[HWCONFIG_BUFFER_SIZE];
+ char *buf = NULL;
+ int n, res;
+
+ n = getenv_f("hwconfig", buffer, sizeof(buffer));
+ if (n > 0)
+ buf = buffer;
+
+ res = hwconfig_arg_cmp_f("fsl_cpu_a011", "disable", buf);
+ if (res > 0) {
+ enable_cpu_a011_workaround = 0;
+ } else {
+ if (n >= HWCONFIG_BUFFER_SIZE) {
+ printf("fsl_cpu_a011 was not found. hwconfig variable "
+ "may be too long\n");
+ }
+ enable_cpu_a011_workaround =
+ (SVR_SOC_VER(svr) == SVR_P4080 && SVR_MAJ(svr) < 3) ||
+ (SVR_SOC_VER(svr) != SVR_P4080 && SVR_MAJ(svr) < 2);
+ }
+#endif
+ if (enable_cpu_a011_workaround) {
+ flush_dcache();
+ mtspr(L1CSR2, (mfspr(L1CSR2) | L1CSR2_DCWS));
+ sync();
+ }
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A005812
+ /*
+ * A-005812 workaround sets bit 32 of SPR 976 for SoCs running
+ * in write shadow mode. Checking DCWS before setting SPR 976.
+ */
+ if (mfspr(L1CSR2) & L1CSR2_DCWS)
+ mtspr(SPRN_HDBCR0, (mfspr(SPRN_HDBCR0) | 0x80000000));
+#endif
+
+#if defined(CONFIG_PPC_SPINTABLE_COMPATIBLE) && defined(CONFIG_MP)
+ spin = getenv("spin_table_compat");
+ if (spin && (*spin == 'n'))
+ spin_table_compat = 0;
+ else
+ spin_table_compat = 1;
+#endif
+
+ l2cache_init();
+#if defined(CONFIG_RAMBOOT_PBL)
+ disable_cpc_sram();
+#endif
enable_cpc();
+#if defined(T1040_TDM_QUIRK_CCSR_BASE)
+ enable_tdm_law();
+#endif
+#ifndef CONFIG_SYS_FSL_NO_SERDES
/* needs to be in ram since code uses global static vars */
fsl_serdes_init();
+#endif
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_SEC_A003571
+#define MCFGR_AXIPIPE 0x000000f0
+ if (IS_SVR_REV(svr, 1, 0))
+ sec_clrbits32(&sec->mcfgr, MCFGR_AXIPIPE);
+#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A005871
if (IS_SVR_REV(svr, 1, 0)) {
#ifdef CONFIG_SYS_FSL_USB1_PHY_ENABLE
{
- ccsr_usb_phy_t *usb_phy1 =
+ struct ccsr_usb_phy __iomem *usb_phy1 =
(void *)CONFIG_SYS_MPC85xx_USB1_PHY_ADDR;
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006261
+ if (has_erratum_a006261())
+ fsl_erratum_a006261_workaround(usb_phy1);
+#endif
out_be32(&usb_phy1->usb_enable_override,
CONFIG_SYS_FSL_USB_ENABLE_OVERRIDE);
}
#endif
#ifdef CONFIG_SYS_FSL_USB2_PHY_ENABLE
{
- ccsr_usb_phy_t *usb_phy2 =
+ struct ccsr_usb_phy __iomem *usb_phy2 =
(void *)CONFIG_SYS_MPC85xx_USB2_PHY_ADDR;
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006261
+ if (has_erratum_a006261())
+ fsl_erratum_a006261_workaround(usb_phy2);
+#endif
out_be32(&usb_phy2->usb_enable_override,
CONFIG_SYS_FSL_USB_ENABLE_OVERRIDE);
}
#endif
#if defined(CONFIG_SYS_FSL_USB_DUAL_PHY_ENABLE)
- ccsr_usb_phy_t *usb_phy =
+ struct ccsr_usb_phy __iomem *usb_phy =
(void *)CONFIG_SYS_MPC85xx_USB1_PHY_ADDR;
setbits_be32(&usb_phy->pllprg[1],
CONFIG_SYS_FSL_USB_PLLPRG2_PHY2_CLK_EN |
CONFIG_SYS_FSL_USB_PLLPRG2_PHY1_CLK_EN |
CONFIG_SYS_FSL_USB_PLLPRG2_MFI |
CONFIG_SYS_FSL_USB_PLLPRG2_PLL_EN);
+#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
+ usb_single_source_clk_configure(usb_phy);
+#endif
setbits_be32(&usb_phy->port1.ctrl,
CONFIG_SYS_FSL_USB_CTRL_PHY_EN);
setbits_be32(&usb_phy->port1.drvvbuscfg,
CONFIG_SYS_FSL_USB_DRVVBUS_CR_EN);
setbits_be32(&usb_phy->port2.pwrfltcfg,
CONFIG_SYS_FSL_USB_PWRFLT_CR_EN);
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A006261
+ if (has_erratum_a006261())
+ fsl_erratum_a006261_workaround(usb_phy);
#endif
+#endif /* CONFIG_SYS_FSL_USB_DUAL_PHY_ENABLE */
+
#ifdef CONFIG_FMAN_ENET
fman_enet_init();
#endif
+#ifdef CONFIG_FSL_CAAM
+ sec_init();
+#endif
+
#if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001)
/*
* For P1022/1013 Rev1.0 silicon, after power on SATA host
}
#endif
+ init_used_tlb_cams();
return 0;
}
-extern void setup_ivors(void);
-
void arch_preboot_os(void)
{
u32 msr;
msr = mfmsr();
msr &= ~(MSR_ME|MSR_CE);
mtmsr(msr);
-
- setup_ivors();
}
#if defined(CONFIG_CMD_SATA) && defined(CONFIG_FSL_SATA)
void cpu_secondary_init_r(void)
{
-#ifdef CONFIG_QE
+#ifdef CONFIG_U_QE
+ uint qe_base = CONFIG_SYS_IMMR + 0x00140000; /* QE immr base */
+#elif defined CONFIG_QE
uint qe_base = CONFIG_SYS_IMMR + 0x00080000; /* QE immr base */
-#ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND
- int ret;
- size_t fw_length = CONFIG_SYS_QE_FMAN_FW_LENGTH;
-
- /* load QE firmware from NAND flash to DDR first */
- ret = nand_read(&nand_info[0], (loff_t)CONFIG_SYS_QE_FMAN_FW_IN_NAND,
- &fw_length, (u_char *)CONFIG_SYS_QE_FMAN_FW_ADDR);
-
- if (ret && ret == -EUCLEAN) {
- printf ("NAND read for QE firmware at offset %x failed %d\n",
- CONFIG_SYS_QE_FMAN_FW_IN_NAND, ret);
- }
#endif
+
+#ifdef CONFIG_QE
qe_init(qe_base);
qe_reset();
#endif