diff options
author | Tom Rini <trini@konsulko.com> | 2016-09-26 13:24:46 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2016-09-26 17:10:56 -0400 |
commit | cbe7706ab8aab06c18edaa9b120371f9c8012728 (patch) | |
tree | ebbfacedf031c33969d8d2e4d7459904b7fc1647 /arch/arm/cpu | |
parent | 8f2fe0c86c56175dd7d5d0e3bc26bef41f224f03 (diff) | |
parent | 295a24b3d6a751b79373e7ff2199d91765cae8a9 (diff) |
Merge git://git.denx.de/u-boot-fsl-qoriq
trini: Drop local memset() from
examples/standalone/mem_to_mem_idma2intr.c
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/fsl_epu.c | 157 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/fsl_epu.h | 8 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c | 15 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c | 236 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/psci.S | 11 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/soc.c | 19 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/psci.S | 6 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/Kconfig | 17 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 5 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c | 12 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c | 4 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c | 12 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S | 15 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/ppa.c | 21 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/soc.c | 31 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/spl.c | 9 |
19 files changed, 564 insertions, 26 deletions
diff --git a/arch/arm/cpu/armv7/ls102xa/Kconfig b/arch/arm/cpu/armv7/ls102xa/Kconfig new file mode 100644 index 0000000000..920eb4ad98 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/Kconfig @@ -0,0 +1,6 @@ +config ARCH_LS1021A + bool "Freescale Layerscape LS1021A SoC" + select SYS_FSL_ERRATUM_A010315 + +config LS1_DEEP_SLEEP + bool "Freescale Layerscape 1 deep sleep" diff --git a/arch/arm/cpu/armv7/ls102xa/Makefile b/arch/arm/cpu/armv7/ls102xa/Makefile index 02283009ab..f8300c7775 100644 --- a/arch/arm/cpu/armv7/ls102xa/Makefile +++ b/arch/arm/cpu/armv7/ls102xa/Makefile @@ -16,5 +16,5 @@ obj-$(CONFIG_SYS_HAS_SERDES) += fsl_ls1_serdes.o ls102xa_serdes.o obj-$(CONFIG_SPL) += spl.o ifdef CONFIG_ARMV7_PSCI -obj-y += psci.o +obj-y += psci.o ls102xa_psci.o endif diff --git a/arch/arm/cpu/armv7/ls102xa/fsl_epu.c b/arch/arm/cpu/armv7/ls102xa/fsl_epu.c index 6212640d14..b4de523ee4 100644 --- a/arch/arm/cpu/armv7/ls102xa/fsl_epu.c +++ b/arch/arm/cpu/armv7/ls102xa/fsl_epu.c @@ -9,6 +9,163 @@ #include "fsl_epu.h" +struct fsm_reg_vals epu_default_val[] = { + /* EPGCR (Event Processor Global Control Register) */ + {EPGCR, 0}, + /* EPECR (Event Processor Event Control Registers) */ + {EPECR0 + EPECR_STRIDE * 0, 0}, + {EPECR0 + EPECR_STRIDE * 1, 0}, + {EPECR0 + EPECR_STRIDE * 2, 0xF0004004}, + {EPECR0 + EPECR_STRIDE * 3, 0x80000084}, + {EPECR0 + EPECR_STRIDE * 4, 0x20000084}, + {EPECR0 + EPECR_STRIDE * 5, 0x08000004}, + {EPECR0 + EPECR_STRIDE * 6, 0x80000084}, + {EPECR0 + EPECR_STRIDE * 7, 0x80000084}, + {EPECR0 + EPECR_STRIDE * 8, 0x60000084}, + {EPECR0 + EPECR_STRIDE * 9, 0x08000084}, + {EPECR0 + EPECR_STRIDE * 10, 0x42000084}, + {EPECR0 + EPECR_STRIDE * 11, 0x90000084}, + {EPECR0 + EPECR_STRIDE * 12, 0x80000084}, + {EPECR0 + EPECR_STRIDE * 13, 0x08000084}, + {EPECR0 + EPECR_STRIDE * 14, 0x02000084}, + {EPECR0 + EPECR_STRIDE * 15, 0x00000004}, + /* + * EPEVTCR (Event Processor EVT Pin Control Registers) + * SCU8 triger EVT2, and SCU11 triger EVT9 + */ + {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x80000001}, + {EPEVTCR0 + EPEVTCR_STRIDE * 3, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 4, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 5, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 6, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 7, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 8, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 9, 0xB0000001}, + /* EPCMPR (Event Processor Counter Compare Registers) */ + {EPCMPR0 + EPCMPR_STRIDE * 0, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 1, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 2, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 3, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 4, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 5, 0x00000020}, + {EPCMPR0 + EPCMPR_STRIDE * 6, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 7, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 8, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 9, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 10, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 11, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 12, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 13, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 14, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 15, 0x000000FF}, + /* EPCCR (Event Processor Counter Control Registers) */ + {EPCCR0 + EPCCR_STRIDE * 0, 0}, + {EPCCR0 + EPCCR_STRIDE * 1, 0}, + {EPCCR0 + EPCCR_STRIDE * 2, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 3, 0}, + {EPCCR0 + EPCCR_STRIDE * 4, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 5, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 6, 0}, + {EPCCR0 + EPCCR_STRIDE * 7, 0}, + {EPCCR0 + EPCCR_STRIDE * 8, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 9, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 10, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 11, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 12, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 13, 0}, + {EPCCR0 + EPCCR_STRIDE * 14, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 15, 0x92840000}, + /* EPSMCR (Event Processor SCU Mux Control Registers) */ + {EPSMCR0 + EPSMCR_STRIDE * 0, 0}, + {EPSMCR0 + EPSMCR_STRIDE * 1, 0}, + {EPSMCR0 + EPSMCR_STRIDE * 2, 0x6C700000}, + {EPSMCR0 + EPSMCR_STRIDE * 3, 0x2F000000}, + {EPSMCR0 + EPSMCR_STRIDE * 4, 0x002F0000}, + {EPSMCR0 + EPSMCR_STRIDE * 5, 0x00002E00}, + {EPSMCR0 + EPSMCR_STRIDE * 6, 0x7C000000}, + {EPSMCR0 + EPSMCR_STRIDE * 7, 0x30000000}, + {EPSMCR0 + EPSMCR_STRIDE * 8, 0x64300000}, + {EPSMCR0 + EPSMCR_STRIDE * 9, 0x00003000}, + {EPSMCR0 + EPSMCR_STRIDE * 10, 0x65000030}, + {EPSMCR0 + EPSMCR_STRIDE * 11, 0x31740000}, + {EPSMCR0 + EPSMCR_STRIDE * 12, 0x7F000000}, + {EPSMCR0 + EPSMCR_STRIDE * 13, 0x00003100}, + {EPSMCR0 + EPSMCR_STRIDE * 14, 0x00000031}, + {EPSMCR0 + EPSMCR_STRIDE * 15, 0x76000000}, + /* EPACR (Event Processor Action Control Registers) */ + {EPACR0 + EPACR_STRIDE * 0, 0}, + {EPACR0 + EPACR_STRIDE * 1, 0}, + {EPACR0 + EPACR_STRIDE * 2, 0}, + {EPACR0 + EPACR_STRIDE * 3, 0x00000080}, + {EPACR0 + EPACR_STRIDE * 4, 0}, + {EPACR0 + EPACR_STRIDE * 5, 0x00000040}, + {EPACR0 + EPACR_STRIDE * 6, 0}, + {EPACR0 + EPACR_STRIDE * 7, 0}, + {EPACR0 + EPACR_STRIDE * 8, 0}, + {EPACR0 + EPACR_STRIDE * 9, 0x0000001C}, + {EPACR0 + EPACR_STRIDE * 10, 0x00000020}, + {EPACR0 + EPACR_STRIDE * 11, 0}, + {EPACR0 + EPACR_STRIDE * 12, 0x00000003}, + {EPACR0 + EPACR_STRIDE * 13, 0x06000000}, + {EPACR0 + EPACR_STRIDE * 14, 0x04000000}, + {EPACR0 + EPACR_STRIDE * 15, 0x02000000}, + /* EPIMCR (Event Processor Input Mux Control Registers) */ + {EPIMCR0 + EPIMCR_STRIDE * 0, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 1, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 2, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 3, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 4, 0x44000000}, + {EPIMCR0 + EPIMCR_STRIDE * 5, 0x40000000}, + {EPIMCR0 + EPIMCR_STRIDE * 6, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 7, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 8, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 9, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 10, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 11, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 12, 0x44000000}, + {EPIMCR0 + EPIMCR_STRIDE * 13, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 14, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 15, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 16, 0x6A000000}, + {EPIMCR0 + EPIMCR_STRIDE * 17, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 18, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 19, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 20, 0x48000000}, + {EPIMCR0 + EPIMCR_STRIDE * 21, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 22, 0x6C000000}, + {EPIMCR0 + EPIMCR_STRIDE * 23, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 24, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 25, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 26, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 27, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 28, 0x76000000}, + {EPIMCR0 + EPIMCR_STRIDE * 29, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 30, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 31, 0x76000000}, + /* EPXTRIGCR (Event Processor Crosstrigger Control Register) */ + {EPXTRIGCR, 0x0000FFDF}, + /* end */ + {FSM_END_FLAG, 0}, +}; + +/** + * fsl_epu_setup - Setup EPU registers to default values + */ +void fsl_epu_setup(void *epu_base) +{ + struct fsm_reg_vals *data = epu_default_val; + + if (!epu_base || !data) + return; + + while (data->offset != FSM_END_FLAG) { + out_be32(epu_base + data->offset, data->value); + data++; + } +} + /** * fsl_epu_clean - Clear EPU registers */ diff --git a/arch/arm/cpu/armv7/ls102xa/fsl_epu.h b/arch/arm/cpu/armv7/ls102xa/fsl_epu.h index d658aad2ea..d6f731054d 100644 --- a/arch/arm/cpu/armv7/ls102xa/fsl_epu.h +++ b/arch/arm/cpu/armv7/ls102xa/fsl_epu.h @@ -63,6 +63,14 @@ #define EPCTR31 0xA7C #define EPCTR_STRIDE FSL_STRIDE_4B +#define FSM_END_FLAG 0xFFFFFFFFUL + +struct fsm_reg_vals { + u32 offset; + u32 value; +}; + +void fsl_epu_setup(void *epu_base); void fsl_epu_clean(void *epu_base); #endif diff --git a/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c b/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c index 46fac51341..8e247ee60b 100644 --- a/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c +++ b/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c @@ -23,9 +23,15 @@ int is_serdes_configured(enum srds_prtcl device) u64 ret = 0; #ifdef CONFIG_SYS_FSL_SRDS_1 + if (!(serdes1_prtcl_map & (1ULL << NONE))) + fsl_serdes_init(); + ret |= (1ULL << device) & serdes1_prtcl_map; #endif #ifdef CONFIG_SYS_FSL_SRDS_2 + if (!(serdes2_prtcl_map & (1ULL << NONE))) + fsl_serdes_init(); + ret |= (1ULL << device) & serdes2_prtcl_map; #endif @@ -87,19 +93,24 @@ u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift) serdes_prtcl_map |= (1ULL << lane_prtcl); } + /* Set the first bit to indicate serdes has been initialized */ + serdes_prtcl_map |= (1ULL << NONE); + return serdes_prtcl_map; } void fsl_serdes_init(void) { #ifdef CONFIG_SYS_FSL_SRDS_1 - serdes1_prtcl_map = serdes_init(FSL_SRDS_1, + if (!(serdes1_prtcl_map & (1ULL << NONE))) + serdes1_prtcl_map = serdes_init(FSL_SRDS_1, CONFIG_SYS_FSL_SERDES_ADDR, RCWSR4_SRDS1_PRTCL_MASK, RCWSR4_SRDS1_PRTCL_SHIFT); #endif #ifdef CONFIG_SYS_FSL_SRDS_2 - serdes2_prtcl_map = serdes_init(FSL_SRDS_2, + if (!(serdes2_prtcl_map & (1ULL << NONE))) + serdes2_prtcl_map = serdes_init(FSL_SRDS_2, CONFIG_SYS_FSL_SERDES_ADDR + FSL_SRDS_2 * 0x1000, RCWSR4_SRDS2_PRTCL_MASK, diff --git a/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c b/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c new file mode 100644 index 0000000000..1cbe93cf41 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c @@ -0,0 +1,236 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Author: Hongbo Zhang <hongbo.zhang@nxp.com> + * + * SPDX-License-Identifier: GPL-2.0+ + * This file implements LS102X platform PSCI SYSTEM-SUSPEND function + */ + +#include <config.h> +#include <asm/io.h> +#include <asm/psci.h> +#include <asm/arch/immap_ls102xa.h> +#include <fsl_immap.h> +#include "fsl_epu.h" + +#define __secure __attribute__((section("._secure.text"))) + +#define CCSR_GICD_CTLR 0x1000 +#define CCSR_GICC_CTLR 0x2000 +#define DCSR_RCPM_CG1CR0 0x31c +#define DCSR_RCPM_CSTTACR0 0xb00 +#define DCFG_CRSTSR_WDRFR 0x8 +#define DDR_RESV_LEN 128 + +#ifdef CONFIG_LS1_DEEP_SLEEP +/* + * DDR controller initialization training breaks the first 128 bytes of DDR, + * save them so that the bootloader can restore them while resuming. + */ +static void __secure ls1_save_ddr_head(void) +{ + const char *src = (const char *)CONFIG_SYS_SDRAM_BASE; + char *dest = (char *)(OCRAM_BASE_S_ADDR + OCRAM_S_SIZE - DDR_RESV_LEN); + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + int i; + + out_le32(&scfg->sparecr[2], dest); + + for (i = 0; i < DDR_RESV_LEN; i++) + *dest++ = *src++; +} + +static void __secure ls1_fsm_setup(void) +{ + void *dcsr_epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET); + void *dcsr_rcpm_base = (void *)SYS_FSL_DCSR_RCPM_ADDR; + + out_be32(dcsr_rcpm_base + DCSR_RCPM_CSTTACR0, 0x00001001); + out_be32(dcsr_rcpm_base + DCSR_RCPM_CG1CR0, 0x00000001); + + fsl_epu_setup((void *)dcsr_epu_base); + + /* Pull MCKE signal low before enabling deep sleep signal in FPGA */ + out_be32(dcsr_epu_base + EPECR0, 0x5); + out_be32(dcsr_epu_base + EPSMCR15, 0x76300000); +} + +static void __secure ls1_deepsleep_irq_cfg(void) +{ + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR; + u32 ippdexpcr0, ippdexpcr1, pmcintecr = 0; + + /* Mask interrupts from GIC */ + out_be32(&rcpm->nfiqoutr, 0x0ffffffff); + out_be32(&rcpm->nirqoutr, 0x0ffffffff); + /* Mask deep sleep wake-up interrupts while entering deep sleep */ + out_be32(&rcpm->dsimskr, 0x0ffffffff); + + ippdexpcr0 = in_be32(&rcpm->ippdexpcr0); + /* + * Workaround: There is bug of register ippdexpcr1, when read it always + * returns zero, so its value is saved to a scrachpad register to be + * read, that is why we don't read it from register ippdexpcr1 itself. + */ + ippdexpcr1 = in_le32(&scfg->sparecr[7]); + + if (ippdexpcr0 & RCPM_IPPDEXPCR0_ETSEC) + pmcintecr |= SCFG_PMCINTECR_ETSECRXG0 | + SCFG_PMCINTECR_ETSECRXG1 | + SCFG_PMCINTECR_ETSECERRG0 | + SCFG_PMCINTECR_ETSECERRG1; + + if (ippdexpcr0 & RCPM_IPPDEXPCR0_GPIO) + pmcintecr |= SCFG_PMCINTECR_GPIO; + + if (ippdexpcr1 & RCPM_IPPDEXPCR1_LPUART) + pmcintecr |= SCFG_PMCINTECR_LPUART; + + if (ippdexpcr1 & RCPM_IPPDEXPCR1_FLEXTIMER) + pmcintecr |= SCFG_PMCINTECR_FTM; + + /* Always set external IRQ pins as wakeup source */ + pmcintecr |= SCFG_PMCINTECR_IRQ0 | SCFG_PMCINTECR_IRQ1; + + out_be32(&scfg->pmcintlecr, 0); + /* Clear PMC interrupt status */ + out_be32(&scfg->pmcintsr, 0xffffffff); + /* Enable wakeup interrupt during deep sleep */ + out_be32(&scfg->pmcintecr, pmcintecr); +} + +static void __secure ls1_delay(unsigned int loop) +{ + while (loop--) { + int i = 1000; + while (i--) + ; + } +} + +static void __secure ls1_start_fsm(void) +{ + void *dcsr_epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET); + void *ccsr_gic_base = (void *)SYS_FSL_GIC_ADDR; + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + + /* Set HRSTCR */ + setbits_be32(&scfg->hrstcr, 0x80000000); + + /* Place DDR controller in self refresh mode */ + setbits_be32(&ddr->sdram_cfg_2, 0x80000000); + + ls1_delay(2000); + + /* Set EVT4_B to lock the signal MCKE down */ + out_be32(dcsr_epu_base + EPECR0, 0x0); + + ls1_delay(2000); + + out_be32(ccsr_gic_base + CCSR_GICD_CTLR, 0x0); + out_be32(ccsr_gic_base + CCSR_GICC_CTLR, 0x0); + + /* Enable all EPU Counters */ + setbits_be32(dcsr_epu_base + EPGCR, 0x80000000); + + /* Enable SCU15 */ + setbits_be32(dcsr_epu_base + EPECR15, 0x90000004); + + /* Enter WFI mode, and EPU FSM will start */ + __asm__ __volatile__ ("wfi" : : : "memory"); + + /* NEVER ENTER HERE */ + while (1) + ; +} + +static void __secure ls1_deep_sleep(u32 entry_point) +{ + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR; +#ifdef QIXIS_BASE + u32 tmp; + void *qixis_base = (void *)QIXIS_BASE; +#endif + + /* Enable cluster to enter the PCL10 state */ + out_be32(&scfg->clusterpmcr, SCFG_CLUSTERPMCR_WFIL2EN); + + /* Save the first 128 bytes of DDR data */ + ls1_save_ddr_head(); + + /* Save the kernel resume entry */ + out_le32(&scfg->sparecr[3], entry_point); + + /* Request to put cluster 0 in PCL10 state */ + setbits_be32(&rcpm->clpcl10setr, RCPM_CLPCL10SETR_C0); + + /* Setup the registers of the EPU FSM for deep sleep */ + ls1_fsm_setup(); + +#ifdef QIXIS_BASE + /* Connect the EVENT button to IRQ in FPGA */ + tmp = in_8(qixis_base + QIXIS_CTL_SYS); + tmp &= ~QIXIS_CTL_SYS_EVTSW_MASK; + tmp |= QIXIS_CTL_SYS_EVTSW_IRQ; + out_8(qixis_base + QIXIS_CTL_SYS, tmp); + + /* Enable deep sleep signals in FPGA */ + tmp = in_8(qixis_base + QIXIS_PWR_CTL2); + tmp |= QIXIS_PWR_CTL2_PCTL; + out_8(qixis_base + QIXIS_PWR_CTL2, tmp); + + /* Pull down PCIe RST# */ + tmp = in_8(qixis_base + QIXIS_RST_FORCE_3); + tmp |= QIXIS_RST_FORCE_3_PCIESLOT1; + out_8(qixis_base + QIXIS_RST_FORCE_3, tmp); +#endif + + /* Enable Warm Device Reset */ + setbits_be32(&scfg->dpslpcr, SCFG_DPSLPCR_WDRR_EN); + setbits_be32(&gur->crstsr, DCFG_CRSTSR_WDRFR); + + ls1_deepsleep_irq_cfg(); + + psci_v7_flush_dcache_all(); + + ls1_start_fsm(); +} + +#else +static void __secure ls1_sleep(void) +{ + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR; + +#ifdef QIXIS_BASE + u32 tmp; + void *qixis_base = (void *)QIXIS_BASE; + + /* Connect the EVENT button to IRQ in FPGA */ + tmp = in_8(qixis_base + QIXIS_CTL_SYS); + tmp &= ~QIXIS_CTL_SYS_EVTSW_MASK; + tmp |= QIXIS_CTL_SYS_EVTSW_IRQ; + out_8(qixis_base + QIXIS_CTL_SYS, tmp); +#endif + + /* Enable cluster to enter the PCL10 state */ + out_be32(&scfg->clusterpmcr, SCFG_CLUSTERPMCR_WFIL2EN); + + setbits_be32(&rcpm->powmgtcsr, RCPM_POWMGTCSR_LPM20_REQ); + + __asm__ __volatile__ ("wfi" : : : "memory"); +} +#endif + +void __secure ls1_system_suspend(u32 fn, u32 entry_point, u32 context_id) +{ +#ifdef CONFIG_LS1_DEEP_SLEEP + ls1_deep_sleep(entry_point); +#else + ls1_sleep(); +#endif +} diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 8f386800f6..3d41d37a64 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -29,6 +29,7 @@ #define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0 #define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0 #define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_SUSPEND_FEATURE_MASK 0x0 .pushsection ._secure.text, "ax" @@ -61,6 +62,8 @@ _ls102x_psci_supported_table: .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK .word ARM_PSCI_0_2_FN_SYSTEM_RESET .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK + .word ARM_PSCI_1_0_FN_SYSTEM_SUSPEND + .word PSCI_FN_SYSTEM_SUSPEND_FEATURE_MASK .word 0 .word ARM_PSCI_RET_NI @@ -243,4 +246,12 @@ psci_system_reset: 1: wfi b 1b +.globl psci_system_suspend +psci_system_suspend: + push {lr} + + bl ls1_system_suspend + + pop {pc} + .popsection diff --git a/arch/arm/cpu/armv7/ls102xa/soc.c b/arch/arm/cpu/armv7/ls102xa/soc.c index b1b0c710ae..31f00cbd69 100644 --- a/arch/arm/cpu/armv7/ls102xa/soc.c +++ b/arch/arm/cpu/armv7/ls102xa/soc.c @@ -7,9 +7,11 @@ #include <common.h> #include <asm/arch/clock.h> #include <asm/io.h> +#include <asm/arch/fsl_serdes.h> #include <asm/arch/immap_ls102xa.h> #include <asm/arch/ls102xa_soc.h> #include <asm/arch/ls102xa_stream_id.h> +#include <fsl_csu.h> struct liodn_id_table sec_liodn_tbl[] = { SET_SEC_JR_LIODN_ENTRY(0, 0x10, 0x10), @@ -58,12 +60,29 @@ unsigned int get_soc_major_rev(void) return major; } +#ifdef CONFIG_SYS_FSL_ERRATUM_A010315 +void erratum_a010315(void) +{ + int i; + + for (i = PCIE1; i <= PCIE2; i++) + if (!is_serdes_configured(i)) { + debug("PCIe%d: disabled all R/W permission!\n", i); + set_pcie_ns_access(i, 0); + } +} +#endif + int arch_soc_init(void) { struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; unsigned int major; +#ifdef CONFIG_LAYERSCAPE_NS_ACCESS + enable_layerscape_ns_access(); +#endif + #ifdef CONFIG_FSL_QSPI out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL); #endif diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index f80f6e20d1..6a362085a6 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -187,7 +187,7 @@ ENDPROC(psci_get_cpu_id) .weak psci_get_cpu_id /* Imported from Linux kernel */ -LENTRY(v7_flush_dcache_all) +ENTRY(psci_v7_flush_dcache_all) stmfd sp!, {r4-r5, r7, r9-r11, lr} dmb @ ensure ordering with previous memory accesses mrc p15, 1, r0, c0, c0, 1 @ read clidr @@ -234,7 +234,7 @@ finished: isb ldmfd sp!, {r4-r5, r7, r9-r11, lr} bx lr -ENDPROC(v7_flush_dcache_all) +ENDPROC(psci_v7_flush_dcache_all) ENTRY(psci_disable_smp) mrc p15, 0, r0, c1, c0, 1 @ ACTLR @@ -264,7 +264,7 @@ ENTRY(psci_cpu_off_common) isb dsb - bl v7_flush_dcache_all + bl psci_v7_flush_dcache_all clrex @ Why??? diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig new file mode 100644 index 0000000000..f8057baa03 --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -0,0 +1,17 @@ +config ARCH_LS1012A + bool "Freescale Layerscape LS1012A SoC" + select SYS_FSL_MMDC + select SYS_FSL_ERRATUM_A010315 + +config ARCH_LS1043A + bool "Freescale Layerscape LS1043A SoC" + select SYS_FSL_ERRATUM_A010315 + +config ARCH_LS1046A + bool "Freescale Layerscape LS1046A SoC" + +config SYS_FSL_MMDC + bool "Freescale Multi Mode DDR Controller" + +config SYS_FSL_ERRATUM_A010315 + bool "Workaround for PCIe erratum A010315" diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile index 8c1317faea..51c1ceeb83 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile +++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile @@ -30,10 +30,10 @@ ifneq ($(CONFIG_LS1043A),) obj-$(CONFIG_SYS_HAS_SERDES) += ls1043a_serdes.o endif -ifneq ($(CONFIG_LS1012A),) +ifneq ($(CONFIG_ARCH_LS1012A),) obj-$(CONFIG_SYS_HAS_SERDES) += ls1012a_serdes.o endif -ifneq ($(CONFIG_LS1046A),) +ifneq ($(CONFIG_ARCH_LS1046A),) obj-$(CONFIG_SYS_HAS_SERDES) += ls1046a_serdes.o endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 20be323084..f865373df3 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -18,7 +18,6 @@ #include <asm/arch/mp.h> #endif #include <fm_eth.h> -#include <fsl_debug_server.h> #include <fsl-mc/fsl_mc.h> #ifdef CONFIG_FSL_ESDHC #include <fsl_esdhc.h> @@ -457,10 +456,6 @@ phys_size_t board_reserve_ram_top(phys_size_t ram_size) #ifdef CONFIG_SYS_MEM_TOP_HIDE #error CONFIG_SYS_MEM_TOP_HIDE not to be used together with this function #endif -/* Carve the Debug Server private DRAM block from the end of DRAM */ -#ifdef CONFIG_FSL_DEBUG_SERVER - ram_top -= debug_server_get_dram_block_size(); -#endif /* Carve the MC private DRAM block from the end of DRAM */ #ifdef CONFIG_FSL_MC_ENET diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c index db2771ab40..e06b063740 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_serdes.c @@ -22,9 +22,15 @@ int is_serdes_configured(enum srds_prtcl device) int ret = 0; #ifdef CONFIG_SYS_FSL_SRDS_1 + if (!serdes1_prtcl_map[NONE]) + fsl_serdes_init(); + ret |= serdes1_prtcl_map[device]; #endif #ifdef CONFIG_SYS_FSL_SRDS_2 + if (!serdes2_prtcl_map[NONE]) + fsl_serdes_init(); + ret |= serdes2_prtcl_map[device]; #endif @@ -98,6 +104,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, u32 cfg; int lane; + if (serdes_prtcl_map[NONE]) + return; + memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT); cfg = gur_in32(&gur->rcwsr[4]) & sd_prctl_mask; @@ -115,6 +124,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, else serdes_prtcl_map[lane_prtcl] = 1; } + + /* Set the first element to indicate serdes has been initialized */ + serdes_prtcl_map[NONE] = 1; } void fsl_serdes_init(void) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c index 8922197d43..55005f0420 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c @@ -60,7 +60,7 @@ void get_sys_info(struct sys_info *sys_info) sys_info->freq_ddrbus = sysclk; #endif -#ifdef CONFIG_LS1012A +#ifdef CONFIG_ARCH_LS1012A sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >> FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) & FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK; @@ -91,7 +91,7 @@ void get_sys_info(struct sys_info *sys_info) freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; } -#ifdef CONFIG_LS1012A +#ifdef CONFIG_ARCH_LS1012A sys_info->freq_systembus = sys_info->freq_ddrbus / 2; sys_info->freq_ddrbus *= 2; #endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c index d5f29ee970..7faa86c3fd 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c @@ -28,9 +28,15 @@ int is_serdes_configured(enum srds_prtcl device) int ret = 0; #ifdef CONFIG_SYS_FSL_SRDS_1 + if (!serdes1_prtcl_map[NONE]) + fsl_serdes_init(); + ret |= serdes1_prtcl_map[device]; #endif #ifdef CONFIG_SYS_FSL_SRDS_2 + if (!serdes2_prtcl_map[NONE]) + fsl_serdes_init(); + ret |= serdes2_prtcl_map[device]; #endif @@ -79,6 +85,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, u32 cfg; int lane; + if (serdes_prtcl_map[NONE]) + return; + memset(serdes_prtcl_map, 0, sizeof(u8) * SERDES_PRCTL_COUNT); cfg = gur_in32(&gur->rcwsr[28]) & sd_prctl_mask; @@ -136,6 +145,9 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, #endif } } + + /* Set the first element to indicate serdes has been initialized */ + serdes_prtcl_map[NONE] = 1; } void fsl_serdes_init(void) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S index 5af6b73bc9..5d0b7a45c3 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S @@ -179,6 +179,21 @@ ENTRY(lowlevel_init) isb dsb sy #endif + +#ifdef CONFIG_ARCH_LS1046A + /* Initialize the L2 RAM latency */ + mrs x1, S3_1_c11_c0_2 + mov x0, #0x1C7 + /* Clear L2 Tag RAM latency and L2 Data RAM latency */ + bic x1, x1, x0 + /* Set L2 data ram latency bits [2:0] */ + orr x1, x1, #0x2 + /* set L2 tag ram latency bits [8:6] */ + orr x1, x1, #0x80 + msr S3_1_c11_c0_2, x1 + isb +#endif + mov lr, x29 /* Restore LR */ ret ENDPROC(lowlevel_init) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c index f54ac3f431..b68e87d657 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/ppa.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/ppa.c @@ -17,6 +17,9 @@ #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT #include <asm/armv8/sec_firmware.h> #endif +#ifdef CONFIG_CHAIN_OF_TRUST +#include <fsl_validate.h> +#endif int ppa_init(void) { @@ -24,12 +27,30 @@ int ppa_init(void) u32 *boot_loc_ptr_l, *boot_loc_ptr_h; int ret; +#ifdef CONFIG_CHAIN_OF_TRUST + uintptr_t ppa_esbc_hdr = CONFIG_SYS_LS_PPA_ESBC_ADDR; + uintptr_t ppa_img_addr = 0; +#endif + #ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP ppa_fit_addr = (void *)CONFIG_SYS_LS_PPA_FW_ADDR; #else #error "No CONFIG_SYS_LS_PPA_FW_IN_xxx defined" #endif +#ifdef CONFIG_CHAIN_OF_TRUST + ppa_img_addr = (uintptr_t)ppa_fit_addr; + if (fsl_check_boot_mode_secure() != 0) { + ret = fsl_secboot_validate(ppa_esbc_hdr, + CONFIG_PPA_KEY_HASH, + &ppa_img_addr); + if (ret != 0) + printf("PPA validation failed\n"); + else + printf("PPA validation Successful\n"); + } +#endif + #ifdef CONFIG_FSL_LSCH3 struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); boot_loc_ptr_l = &gur->bootlocptrl; diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index f62b78d102..463d1e30d2 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -8,10 +8,14 @@ #include <fsl_ifc.h> #include <ahci.h> #include <scsi.h> +#include <asm/arch/fsl_serdes.h> #include <asm/arch/soc.h> #include <asm/io.h> #include <asm/global_data.h> #include <asm/arch-fsl-layerscape/config.h> +#ifdef CONFIG_LAYERSCAPE_NS_ACCESS +#include <fsl_csu.h> +#endif #ifdef CONFIG_SYS_FSL_DDR #include <fsl_ddr_sdram.h> #include <fsl_ddr.h> @@ -58,11 +62,13 @@ static void erratum_a008336(void) #ifdef CONFIG_SYS_FSL_ERRATUM_A008336 #ifdef CONFIG_SYS_FSL_DCSR_DDR_ADDR eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800; - out_le32(eddrtqcr1, 0x63b30002); + if (fsl_ddr_get_version(0) == 0x50200) + out_le32(eddrtqcr1, 0x63b30002); #endif #ifdef CONFIG_SYS_FSL_DCSR_DDR2_ADDR eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800; - out_le32(eddrtqcr1, 0x63b30002); + if (fsl_ddr_get_version(0) == 0x50200) + out_le32(eddrtqcr1, 0x63b30002); #endif #endif } @@ -222,6 +228,10 @@ int sata_init(void) { struct ccsr_ahci __iomem *ccsr_ahci = (void *)CONFIG_SYS_SATA; +#ifdef CONFIG_ARCH_LS1046A + /* Disable SATA ECC */ + out_le32((void *)CONFIG_SYS_DCSR_DCFG_ADDR + 0x520, 0x80000000); +#endif out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG); out_le32(&ccsr_ahci->pp2c, AHCI_PORT_PHY_2_CFG); out_le32(&ccsr_ahci->pp3c, AHCI_PORT_PHY_3_CFG); @@ -298,11 +308,28 @@ void erratum_a008850_post(void) #endif } +#ifdef CONFIG_SYS_FSL_ERRATUM_A010315 +void erratum_a010315(void) +{ + int i; + + for (i = PCIE1; i <= PCIE4; i++) + if (!is_serdes_configured(i)) { + debug("PCIe%d: disabled all R/W permission!\n", i); + set_pcie_ns_access(i, 0); + } +} +#endif + void fsl_lsch2_early_init_f(void) { struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; +#ifdef CONFIG_LAYERSCAPE_NS_ACCESS + enable_layerscape_ns_access(); +#endif + #ifdef CONFIG_FSL_IFC init_early_memctl_regs(); /* tighten IFC timing */ #endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c index 19e34fade2..1dabdbb305 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c @@ -8,7 +8,6 @@ #include <spl.h> #include <asm/io.h> #include <fsl_ifc.h> -#include <fsl_csu.h> #include <i2c.h> DECLARE_GLOBAL_DATA_PTR; @@ -62,13 +61,5 @@ void board_init_f(ulong dummy) i2c_init_all(); #endif dram_init(); - - /* Clear the BSS */ - memset(__bss_start, 0, __bss_end - __bss_start); - -#ifdef CONFIG_LAYERSCAPE_NS_ACCESS - enable_layerscape_ns_access(); -#endif - board_init_r(NULL, 0); } #endif |