From 473f1fc280505f03a250ac77052b5b0fd51fe590 Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Tue, 15 Nov 2016 17:15:20 +0800 Subject: fsl/ddr: Enable erratum-a009942 workaround for B/T-series Enable ERRATUM_A009942 workaround for B-series and T-series platforms. Signed-off-by: Shengzhou Liu Reviewed-by: York Sun diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index 603d6ae..8cfc612 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -517,6 +517,7 @@ #define CONFIG_SYS_FSL_ERRATUM_A007186 #define CONFIG_SYS_FSL_ERRATUM_A006593 #define CONFIG_SYS_FSL_ERRATUM_A007798 +#define CONFIG_SYS_FSL_ERRATUM_A009942 #define CONFIG_SYS_FSL_SFP_VER_3_0 #define CONFIG_SYS_FSL_PCI_VER_3_X @@ -557,6 +558,7 @@ #define CONFIG_SYS_FSL_ERRATUM_A006384 #define CONFIG_SYS_FSL_ERRATUM_A007212 #define CONFIG_SYS_FSL_ERRATUM_A004477 +#define CONFIG_SYS_FSL_ERRATUM_A009942 #define CONFIG_SYS_FSL_SFP_VER_3_0 #ifdef CONFIG_ARCH_B4860 @@ -626,6 +628,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022) #define CONFIG_SYS_FSL_SFP_VER_3_0 #define CONFIG_SYS_FSL_ERRATUM_A008378 #define CONFIG_SYS_FSL_ERRATUM_A009663 +#define CONFIG_SYS_FSL_ERRATUM_A009942 #elif defined(CONFIG_ARCH_T1024) || defined(CONFIG_ARCH_T1023) ||\ defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013) @@ -668,6 +671,7 @@ defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013) #define CONFIG_SYS_FSL_SFP_VER_3_0 #define CONFIG_SYS_FSL_ERRATUM_A008378 #define CONFIG_SYS_FSL_ERRATUM_A009663 +#define CONFIG_SYS_FSL_ERRATUM_A009942 #elif defined(CONFIG_ARCH_T2080) || defined(CONFIG_ARCH_T2081) #define CONFIG_E6500 @@ -717,6 +721,7 @@ defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013) #define CONFIG_SYS_FSL_ERRATUM_A006593 #define CONFIG_SYS_FSL_ERRATUM_A007186 #define CONFIG_SYS_FSL_ERRATUM_A006379 +#define CONFIG_SYS_FSL_ERRATUM_A009942 #define ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE #define CONFIG_SYS_FSL_SFP_VER_3_0 -- cgit v0.10.2 From 90101386f16d22c66ba69fb09f87dd08c0e60b4b Mon Sep 17 00:00:00 2001 From: Shengzhou Liu Date: Tue, 15 Nov 2016 17:15:21 +0800 Subject: fsl/board/ddr: optimize board-specific cpo for erratum A-009942 Optimize board-specific cpo for erratum A-009942 on b4860qds, ls1043aqds, ls1043ardb, ls1046aqds, ls1046ardb, ls2080ardb, t102xqds, t102xrdb, t1040qds, t104xrdb, t208xqds, t208xrdb, t4qds, t4rdb boards. Signed-off-by: Shengzhou Liu Reviewed-by: York Sun diff --git a/board/freescale/b4860qds/ddr.c b/board/freescale/b4860qds/ddr.c index 31b186e..3885acc 100644 --- a/board/freescale/b4860qds/ddr.c +++ b/board/freescale/b4860qds/ddr.c @@ -171,6 +171,9 @@ found: /* DHC_EN =1, ODT = 75 Ohm */ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x3e; } phys_size_t initdram(int board_type) diff --git a/board/freescale/ls1043aqds/ddr.c b/board/freescale/ls1043aqds/ddr.c index d4540d0..7882a9a 100644 --- a/board/freescale/ls1043aqds/ddr.c +++ b/board/freescale/ls1043aqds/ddr.c @@ -96,6 +96,9 @@ found: popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */ + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x59; #else popts->cswl_override = DDR_CSWL_CS0; diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c index 61b1cc4..849f1d1 100644 --- a/board/freescale/ls1043ardb/ddr.c +++ b/board/freescale/ls1043ardb/ddr.c @@ -91,6 +91,9 @@ found: /* Enable ZQ calibration */ popts->zq_en = 1; + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x46; + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */ diff --git a/board/freescale/ls1046aqds/ddr.c b/board/freescale/ls1046aqds/ddr.c index d813965..4ea8b23 100644 --- a/board/freescale/ls1046aqds/ddr.c +++ b/board/freescale/ls1046aqds/ddr.c @@ -87,6 +87,9 @@ found: popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2; + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x70; } phys_size_t initdram(int board_type) diff --git a/board/freescale/ls1046ardb/ddr.c b/board/freescale/ls1046ardb/ddr.c index a9b7dbd..dd3b5d0 100644 --- a/board/freescale/ls1046ardb/ddr.c +++ b/board/freescale/ls1046ardb/ddr.c @@ -91,6 +91,9 @@ found: popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2; + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x70; } phys_size_t initdram(int board_type) diff --git a/board/freescale/ls2080ardb/ddr.c b/board/freescale/ls2080ardb/ddr.c index ecd1e71..959dfeb 100644 --- a/board/freescale/ls2080ardb/ddr.c +++ b/board/freescale/ls2080ardb/ddr.c @@ -134,6 +134,9 @@ found: /* Enable ZQ calibration */ popts->zq_en = 1; + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x6e; + if (ddr_freq < 2350) { if (pdimm[0].n_ranks == 2 && pdimm[1].n_ranks == 2) { /* four chip-selects */ diff --git a/board/freescale/t102xqds/ddr.c b/board/freescale/t102xqds/ddr.c index c26f350..b6b1191 100644 --- a/board/freescale/t102xqds/ddr.c +++ b/board/freescale/t102xqds/ddr.c @@ -139,6 +139,9 @@ found: #else popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x5f; #endif /* T1023 supports max DDR bus 32bit width, T1024 supports DDR 64bit, diff --git a/board/freescale/t102xrdb/ddr.c b/board/freescale/t102xrdb/ddr.c index edfbdbf..9e1b16b 100644 --- a/board/freescale/t102xrdb/ddr.c +++ b/board/freescale/t102xrdb/ddr.c @@ -139,6 +139,10 @@ found: #ifdef CONFIG_T1023RDB popts->wrlvl_ctl_2 = 0x07070606; popts->half_strength_driver_enable = 1; + popts->cpo_sample = 0x43; +#elif defined(CONFIG_T1024RDB) + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x52; #endif } diff --git a/board/freescale/t1040qds/ddr.c b/board/freescale/t1040qds/ddr.c index 8240240..cb58d1e 100644 --- a/board/freescale/t1040qds/ddr.c +++ b/board/freescale/t1040qds/ddr.c @@ -95,6 +95,9 @@ found: popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */ + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x69; #else popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); diff --git a/board/freescale/t104xrdb/ddr.c b/board/freescale/t104xrdb/ddr.c index 22d6a5f..302f19b 100644 --- a/board/freescale/t104xrdb/ddr.c +++ b/board/freescale/t104xrdb/ddr.c @@ -77,6 +77,8 @@ found: */ #ifdef CONFIG_SYS_FSL_DDR4 popts->half_strength_driver_enable = 1; + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x59; #else popts->half_strength_driver_enable = 0; #endif diff --git a/board/freescale/t208xqds/ddr.c b/board/freescale/t208xqds/ddr.c index f96470f..d6e4554 100644 --- a/board/freescale/t208xqds/ddr.c +++ b/board/freescale/t208xqds/ddr.c @@ -99,6 +99,9 @@ found: /* DHC_EN =1, ODT = 75 Ohm */ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x64; } phys_size_t initdram(int board_type) diff --git a/board/freescale/t208xrdb/ddr.c b/board/freescale/t208xrdb/ddr.c index f6c8ca3..3487261 100644 --- a/board/freescale/t208xrdb/ddr.c +++ b/board/freescale/t208xrdb/ddr.c @@ -92,6 +92,9 @@ found: /* DHC_EN =1, ODT = 75 Ohm */ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x54; } phys_size_t initdram(int board_type) diff --git a/board/freescale/t4qds/ddr.c b/board/freescale/t4qds/ddr.c index d533924..842073b 100644 --- a/board/freescale/t4qds/ddr.c +++ b/board/freescale/t4qds/ddr.c @@ -107,6 +107,9 @@ found: /* DHC_EN =1, ODT = 75 Ohm */ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x63; } phys_size_t initdram(int board_type) diff --git a/board/freescale/t4rdb/ddr.c b/board/freescale/t4rdb/ddr.c index 230f031..7b05821 100644 --- a/board/freescale/t4rdb/ddr.c +++ b/board/freescale/t4rdb/ddr.c @@ -100,6 +100,9 @@ found: /* DHC_EN =1, ODT = 75 Ohm */ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); + + /* optimize cpo for erratum A-009942 */ + popts->cpo_sample = 0x64; } phys_size_t initdram(int board_type) -- cgit v0.10.2 From f667d86ef33bd67b6af868b3348f23bd7b074800 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 6 Dec 2016 15:27:48 +0800 Subject: armv8: ls1043ardb: dts: Fix the unit-address of some I2C device nodes The unit-address should be the same as the I2C address of the device. Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun diff --git a/arch/arm/dts/fsl-ls1043a-rdb.dts b/arch/arm/dts/fsl-ls1043a-rdb.dts index 16c5c89..5744075 100644 --- a/arch/arm/dts/fsl-ls1043a-rdb.dts +++ b/arch/arm/dts/fsl-ls1043a-rdb.dts @@ -47,12 +47,12 @@ compatible = "adi,adt7461a"; reg = <0x4c>; }; - eeprom@56 { + eeprom@52 { compatible = "at24,24c512"; reg = <0x52>; }; - eeprom@57 { + eeprom@53 { compatible = "at24,24c512"; reg = <0x53>; }; -- cgit v0.10.2 From 4002eab2c2bdbcb730620a12dafab32298c48135 Mon Sep 17 00:00:00 2001 From: Hou Zhiqiang Date: Tue, 6 Dec 2016 15:27:49 +0800 Subject: armv8: ls1043a: dts: Fix the ranges table of IFC node Corrected the ranges table of the IFC node. Signed-off-by: Hou Zhiqiang Reviewed-by: York Sun diff --git a/arch/arm/dts/fsl-ls1043a-qds.dtsi b/arch/arm/dts/fsl-ls1043a-qds.dtsi index 2e9f1f9..2101172 100644 --- a/arch/arm/dts/fsl-ls1043a-qds.dtsi +++ b/arch/arm/dts/fsl-ls1043a-qds.dtsi @@ -135,8 +135,8 @@ #size-cells = <1>; /* NOR, NAND Flashes and FPGA on board */ ranges = <0x0 0x0 0x0 0x60000000 0x08000000 - 0x2 0x0 0x0 0x7e800000 0x00010000 - 0x3 0x0 0x0 0x7fb00000 0x00000100>; + 0x1 0x0 0x0 0x7e800000 0x00010000 + 0x2 0x0 0x0 0x7fb00000 0x00000100>; status = "okay"; nor@0,0 { @@ -148,21 +148,21 @@ device-width = <1>; }; - nand@2,0 { + nand@1,0 { compatible = "fsl,ifc-nand"; #address-cells = <1>; #size-cells = <1>; reg = <0x1 0x0 0x10000>; }; - fpga: board-control@3,0 { + fpga: board-control@2,0 { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; - reg = <0x3 0x0 0x0000100>; + reg = <0x2 0x0 0x0000100>; bank-width = <1>; device-width = <1>; - ranges = <0 3 0 0x100>; + ranges = <0 2 0 0x100>; }; }; diff --git a/arch/arm/dts/fsl-ls1043a-rdb.dts b/arch/arm/dts/fsl-ls1043a-rdb.dts index 5744075..f271e71 100644 --- a/arch/arm/dts/fsl-ls1043a-rdb.dts +++ b/arch/arm/dts/fsl-ls1043a-rdb.dts @@ -69,8 +69,8 @@ #size-cells = <1>; /* NOR, NAND Flashes and FPGA on board */ ranges = <0x0 0x0 0x0 0x60000000 0x08000000 - 0x2 0x0 0x0 0x7e800000 0x00010000 - 0x3 0x0 0x0 0x7fb00000 0x00000100>; + 0x1 0x0 0x0 0x7e800000 0x00010000 + 0x2 0x0 0x0 0x7fb00000 0x00000100>; nor@0,0 { compatible = "cfi-flash"; -- cgit v0.10.2 From 8e62f1ee03c82ad285a4e2245e25fc348320749e Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Wed, 7 Dec 2016 12:04:05 +0530 Subject: driver: fsl-mc: qbman: Add QBMAN 4.1 support LS2080A SoC family has QBMAN ver 4.0 whereas newer SoCs like LS2088A, LS1088A has QBMAN ver 4.1 QBMAN ver 4.0 and ver 4.1 supports dqrr size as 4 and 8 respectively. Add support of to check QBMAN version based on SoC SVR update dqrr_size accordingly update code to support larger dqrr_size Signed-off-by: Priyanka Jain Signed-off-by: Prabhakar Kushwaha Reviewed-by: York Sun diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c index 4b64c8a..86dc13d 100644 --- a/drivers/net/fsl-mc/dpio/qbman_portal.c +++ b/drivers/net/fsl-mc/dpio/qbman_portal.c @@ -25,7 +25,7 @@ #define QBMAN_CENA_SWP_VDQCR 0x780 /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */ -#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0xff) >> 6) +#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6) /*******************************/ /* Pre-defined attribute codes */ @@ -65,6 +65,7 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) { int ret; struct qbman_swp *p = malloc(sizeof(struct qbman_swp)); + u32 major = 0, minor = 0; if (!p) return NULL; @@ -80,8 +81,20 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) atomic_set(&p->vdq.busy, 1); p->vdq.valid_bit = QB_VALID_BIT; p->dqrr.next_idx = 0; + + qbman_version(&major, &minor); + if (!major) { + printf("invalid qbman version\n"); + return NULL; + } + + if (major >= 4 && minor >= 1) + p->dqrr.dqrr_size = QBMAN_VER_4_1_DQRR_SIZE; + else + p->dqrr.dqrr_size = QBMAN_VER_4_0_DQRR_SIZE; + p->dqrr.valid_bit = QB_VALID_BIT; - ret = qbman_swp_sys_init(&p->sys, d); + ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size); if (ret) { free(p); printf("qbman_swp_sys_init() failed %d\n", ret); @@ -380,7 +393,7 @@ const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s) /* There's something there. Move "next_idx" attention to the next ring * entry (and prefetch it) before returning what we found. */ s->dqrr.next_idx++; - s->dqrr.next_idx &= QBMAN_DQRR_SIZE - 1; /* Wrap around at 4 */ + s->dqrr.next_idx &= s->dqrr.dqrr_size - 1;/* Wrap around at dqrr_size */ /* TODO: it's possible to do all this without conditionals, optimise it * later. */ if (!s->dqrr.next_idx) diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.h b/drivers/net/fsl-mc/dpio/qbman_portal.h index 86e2c3a..97a47aa 100644 --- a/drivers/net/fsl-mc/dpio/qbman_portal.h +++ b/drivers/net/fsl-mc/dpio/qbman_portal.h @@ -14,8 +14,8 @@ /* Management command result codes */ #define QBMAN_MC_RSLT_OK 0xf0 -/* TBD: as of QBMan 4.1, DQRR will be 8 rather than 4! */ -#define QBMAN_DQRR_SIZE 4 +#define QBMAN_VER_4_0_DQRR_SIZE 4 +#define QBMAN_VER_4_1_DQRR_SIZE 8 /* --------------------- */ @@ -71,6 +71,7 @@ struct qbman_swp { struct { uint32_t next_idx; uint32_t valid_bit; + uint8_t dqrr_size; } dqrr; }; diff --git a/drivers/net/fsl-mc/dpio/qbman_private.h b/drivers/net/fsl-mc/dpio/qbman_private.h index f1f16b8..73bbae3 100644 --- a/drivers/net/fsl-mc/dpio/qbman_private.h +++ b/drivers/net/fsl-mc/dpio/qbman_private.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #define QBMAN_CHECKING @@ -166,4 +167,22 @@ static inline void dcbz(void *ptr) #define lwsync() +void qbman_version(u32 *major, u32 *minor) +{ + u32 svr_dev_id; + + /* + * LS2080A SoC and its personalities has qbman cotroller version 4.0 + * New SoCs like LS2088A, LS1088A has qbman conroller version 4.1 + */ + svr_dev_id = get_svr() >> 16; + if (svr_dev_id == SVR_DEV_LS2080A) { + *major = 4; + *minor = 0; + } else { + *major = 4; + *minor = 1; + } +} + #include "qbman_sys.h" diff --git a/drivers/net/fsl-mc/dpio/qbman_sys.h b/drivers/net/fsl-mc/dpio/qbman_sys.h index 7a537fb..72d74c5 100644 --- a/drivers/net/fsl-mc/dpio/qbman_sys.h +++ b/drivers/net/fsl-mc/dpio/qbman_sys.h @@ -239,16 +239,18 @@ static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn, { uint32_t reg; - reg = e32_uint8_t(20, 3, max_fill) | e32_uint8_t(16, 3, est) | - e32_uint8_t(12, 2, rpm) | e32_uint8_t(10, 2, dcm) | - e32_uint8_t(8, 2, epm) | e32_int(5, 1, sd) | - e32_int(4, 1, sp) | e32_int(3, 1, se) | e32_int(2, 1, dp) | - e32_int(1, 1, de) | e32_int(0, 1, ep) | e32_uint8_t(14, 1, wn); + reg = e32_uint8_t(20, (uint32_t)(3 + (max_fill >> 3)), max_fill) | + e32_uint8_t(16, 3, est) | e32_uint8_t(12, 2, rpm) | + e32_uint8_t(10, 2, dcm) | e32_uint8_t(8, 2, epm) | + e32_int(5, 1, sd) | e32_int(4, 1, sp) | e32_int(3, 1, se) | + e32_int(2, 1, dp) | e32_int(1, 1, de) | e32_int(0, 1, ep) | + e32_uint8_t(14, 1, wn); return reg; } static inline int qbman_swp_sys_init(struct qbman_swp_sys *s, - const struct qbman_swp_desc *d) + const struct qbman_swp_desc *d, + uint8_t dqrr_size) { uint32_t reg; @@ -270,9 +272,9 @@ static inline int qbman_swp_sys_init(struct qbman_swp_sys *s, BUG_ON(reg); #endif #ifdef QBMAN_CINH_ONLY - reg = qbman_set_swp_cfg(4, 1, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0); + reg = qbman_set_swp_cfg(dqrr_size, 1, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0); #else - reg = qbman_set_swp_cfg(4, 0, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0); + reg = qbman_set_swp_cfg(dqrr_size, 0, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0); #endif qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg); reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG); -- cgit v0.10.2 From 2d16a1a6c9eeb30fa6828f048df06ee9807792d3 Mon Sep 17 00:00:00 2001 From: "macro.wave.z@gmail.com" Date: Thu, 8 Dec 2016 11:58:21 +0800 Subject: ARMv8: LS1043A: change macro CONFIG_ARMV8_PSCI definition NXP/Freescale uses macro CONFIG_ARMV8_PSCI to enable their private PSCI implementation in PPA firmware, but this macro naming too generic, so this patch replaces it with a specic one CONFIG_FSL_PPA_ARMV8_PSCI. And this macro CONFIG_ARMV8_PSCI will be used for a generic PSCI for ARMv8 which will be added in following patchs. Signed-off-by: Hongbo Zhang Reviewed-by: Tom Rini Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/cpu-dt.c b/arch/arm/cpu/armv8/cpu-dt.c index 9ffb49c..659ec27 100644 --- a/arch/arm/cpu/armv8/cpu-dt.c +++ b/arch/arm/cpu/armv8/cpu-dt.c @@ -13,7 +13,7 @@ int psci_update_dt(void *fdt) { #ifdef CONFIG_MP -#if defined(CONFIG_ARMV8_PSCI) +#if defined(CONFIG_FSL_PPA_ARMV8_PSCI) #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT /* * If the PSCI in SEC Firmware didn't work, avoid to update the diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index 6772584..d28a422 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -44,6 +44,26 @@ config FSL_LSCH3 menu "Layerscape architecture" depends on FSL_LSCH2 || FSL_LSCH3 +menu "Layerscape PPA" +config FSL_LS_PPA + bool "FSL Layerscape PPA firmware support" + depends on ARCH_LS1043A || ARCH_LS1046A + select FSL_PPA_ARMV8_PSCI + help + The FSL Primary Protected Application (PPA) is a software component + which is loaded during boot stage, and then remains resident in RAM + and runs in the TrustZone after boot. + Say y to enable it. + +config FSL_PPA_ARMV8_PSCI + bool "PSCI implementation in PPA firmware" + depends on FSL_LS_PPA + help + This config enables the ARMv8 PSCI implementation in PPA firmware. + This is a private PSCI implementation and different from those + implemented under the common ARMv8 PSCI framework. +endmenu + config SYS_FSL_MMDC bool diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index ffbbd72..467d9af 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -410,7 +410,8 @@ int arch_early_init_r(void) erratum_a009942_check_cpo(); #endif #ifdef CONFIG_MP -#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI) +#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && \ + defined(CONFIG_FSL_PPA_ARMV8_PSCI) /* Check the psci version to determine if the psci is supported */ psci_ver = sec_firmware_support_psci_version(); #endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index 0dae5fa..c10ccf9 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c @@ -42,7 +42,8 @@ void ft_fixup_cpu(void *blob) int addr_cells; u64 val, core_id; size_t *boot_code_size = &(__secondary_boot_code_size); -#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && defined(CONFIG_ARMV8_PSCI) +#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && \ + defined(CONFIG_FSL_PPA_ARMV8_PSCI) int node; u32 psci_ver; diff --git a/arch/arm/cpu/armv8/sec_firmware.c b/arch/arm/cpu/armv8/sec_firmware.c index 2ddd67e..0b973f0 100644 --- a/arch/arm/cpu/armv8/sec_firmware.c +++ b/arch/arm/cpu/armv8/sec_firmware.c @@ -209,7 +209,7 @@ __weak bool sec_firmware_is_valid(const void *sec_firmware_img) return true; } -#ifdef CONFIG_ARMV8_PSCI +#ifdef CONFIG_FSL_PPA_ARMV8_PSCI /* * The PSCI_VERSION function is added from PSCI v0.2. When the PSCI * v0.1 received this function, the NOT_SUPPORTED (0xffff_ffff) error diff --git a/arch/arm/cpu/armv8/sec_firmware_asm.S b/arch/arm/cpu/armv8/sec_firmware_asm.S index 1b39f1d..903195d 100644 --- a/arch/arm/cpu/armv8/sec_firmware_asm.S +++ b/arch/arm/cpu/armv8/sec_firmware_asm.S @@ -41,7 +41,7 @@ WEAK(_sec_firmware_entry) ret ENDPROC(_sec_firmware_entry) -#ifdef CONFIG_ARMV8_PSCI +#ifdef CONFIG_FSL_PPA_ARMV8_PSCI ENTRY(_sec_firmware_support_psci_version) mov x0, 0x84000000 mov x1, 0x0 diff --git a/arch/arm/include/asm/armv8/sec_firmware.h b/arch/arm/include/asm/armv8/sec_firmware.h index eb68185..a4e144b 100644 --- a/arch/arm/include/asm/armv8/sec_firmware.h +++ b/arch/arm/include/asm/armv8/sec_firmware.h @@ -14,7 +14,7 @@ int sec_firmware_init(const void *, u32 *, u32 *); int _sec_firmware_entry(const void *, u32 *, u32 *); bool sec_firmware_is_valid(const void *); -#ifdef CONFIG_ARMV8_PSCI +#ifdef CONFIG_FSL_PPA_ARMV8_PSCI unsigned int sec_firmware_support_psci_version(void); unsigned int _sec_firmware_support_psci_version(void); #endif diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c index 4481f9e..1615756 100644 --- a/arch/arm/lib/bootm-fdt.c +++ b/arch/arm/lib/bootm-fdt.c @@ -52,7 +52,7 @@ int arch_fixup_fdt(void *blob) return ret; #endif -#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV8_PSCI) +#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_FSL_PPA_ARMV8_PSCI) ret = psci_update_dt(blob); if (ret) return ret; diff --git a/arch/arm/lib/psci-dt.c b/arch/arm/lib/psci-dt.c index baf6d70..41e139e 100644 --- a/arch/arm/lib/psci-dt.c +++ b/arch/arm/lib/psci-dt.c @@ -16,7 +16,7 @@ int fdt_psci(void *fdt) { -#if defined(CONFIG_ARMV8_PSCI) || defined(CONFIG_ARMV7_PSCI) +#if defined(CONFIG_FSL_PPA_ARMV8_PSCI) || defined(CONFIG_ARMV7_PSCI) int nodeoff; unsigned int psci_ver = 0; int tmp; diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h index 849a6cb..71c26bd 100644 --- a/include/configs/ls1043ardb.h +++ b/include/configs/ls1043ardb.h @@ -12,7 +12,6 @@ #if defined(CONFIG_FSL_LS_PPA) #define CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT #define SEC_FIRMWARE_ERET_ADDR_REVERT -#define CONFIG_ARMV8_PSCI #define CONFIG_SYS_LS_PPA_FW_IN_XIP #ifdef CONFIG_SYS_LS_PPA_FW_IN_XIP -- cgit v0.10.2 From df88cb3b91019e7d7293c73b01a5913a02be9c32 Mon Sep 17 00:00:00 2001 From: "macro.wave.z@gmail.com" Date: Thu, 8 Dec 2016 11:58:22 +0800 Subject: ARMv8: Add secure sections for PSCI text and data This patch adds secure_text, secure_data and secure_stack sections for ARMv8 to hold PSCI text and data, and it is based on the legacy implementation of ARMv7. ARMV8_SECURE_BASE defines the address for PSCI secure sections, ARMV8_PSCI and ARMV8_PSCI_NR_CPUS are firstly used in this patch, so they are introduce here in Kconfig too. Signed-off-by: Hongbo Zhang Reviewed-by: Tom Rini Reviewed-by: York Sun diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 008da39..3a81f13 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -121,7 +121,8 @@ endif # limit ourselves to the sections we want in the .bin. ifdef CONFIG_ARM64 -OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn +OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \ + -j .u_boot_list -j .rela.dyn else OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \ -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig index 965a8d1..edae43d 100644 --- a/arch/arm/cpu/armv8/Kconfig +++ b/arch/arm/cpu/armv8/Kconfig @@ -40,4 +40,35 @@ config PSCI_RESET Select Y here to make use of PSCI calls for system reset +config ARMV8_PSCI + bool "Enable PSCI support" if EXPERT + default n + help + PSCI is Power State Coordination Interface defined by ARM. + The PSCI in U-boot provides a general framework and each platform + can implement their own specific PSCI functions. + Say Y here to enable PSCI support on ARMv8 platform. + +config ARMV8_PSCI_NR_CPUS + int "Maximum supported CPUs for PSCI" + depends on ARMV8_PSCI + default 4 + help + The maximum number of CPUs supported in the PSCI firmware. + It is no problem to set a larger value than the number of CPUs in + the actual hardware implementation. + +if SYS_HAS_ARMV8_SECURE_BASE + +config ARMV8_SECURE_BASE + hex "Secure address for PSCI image" + depends on ARMV8_PSCI + help + Address for placing the PSCI text, data and stack sections. + If not defined, the PSCI sections are placed together with the u-boot + but platform can choose to place PSCI code image separately in other + places such as some secure RAM built-in SOC etc. + +endif + endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig index d28a422..cc0dc88 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Kconfig +++ b/arch/arm/cpu/armv8/fsl-layerscape/Kconfig @@ -47,6 +47,7 @@ menu "Layerscape architecture" menu "Layerscape PPA" config FSL_LS_PPA bool "FSL Layerscape PPA firmware support" + depends on !ARMV8_PSCI depends on ARCH_LS1043A || ARCH_LS1046A select FSL_PPA_ARMV8_PSCI help diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds index fd15ad5..22195b8 100644 --- a/arch/arm/cpu/armv8/u-boot.lds +++ b/arch/arm/cpu/armv8/u-boot.lds @@ -8,11 +8,17 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include +#include + OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") OUTPUT_ARCH(aarch64) ENTRY(_start) SECTIONS { +#ifdef CONFIG_ARMV8_SECURE_BASE + /DISCARD/ : { *(.rela._secure*) } +#endif . = 0x00000000; . = ALIGN(8); @@ -23,6 +29,57 @@ SECTIONS *(.text*) } +#ifdef CONFIG_ARMV8_PSCI + .__secure_start : +#ifndef CONFIG_ARMV8_SECURE_BASE + ALIGN(CONSTANT(COMMONPAGESIZE)) +#endif + { + KEEP(*(.__secure_start)) + } + +#ifndef CONFIG_ARMV8_SECURE_BASE +#define CONFIG_ARMV8_SECURE_BASE +#define __ARMV8_PSCI_STACK_IN_RAM +#endif + .secure_text CONFIG_ARMV8_SECURE_BASE : + AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) + { + *(._secure.text) + } + + .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text)) + { + *(._secure.data) + } + + .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data), + CONSTANT(COMMONPAGESIZE)) (NOLOAD) : +#ifdef __ARMV8_PSCI_STACK_IN_RAM + AT(ADDR(.secure_stack)) +#else + AT(LOADADDR(.secure_data) + SIZEOF(.secure_data)) +#endif + { + KEEP(*(.__secure_stack_start)) + + . = . + CONFIG_ARMV8_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE; + + . = ALIGN(CONSTANT(COMMONPAGESIZE)); + + KEEP(*(.__secure_stack_end)) + } + +#ifndef __ARMV8_PSCI_STACK_IN_RAM + . = LOADADDR(.secure_stack); +#endif + + .__secure_end : AT(ADDR(.__secure_end)) { + KEEP(*(.__secure_end)) + LONG(0x1d1071c); /* Must output something to reset LMA */ + } +#endif + . = ALIGN(8); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } -- cgit v0.10.2 From 5cc8d6682f6bb2934f5303786af6c57e68613a79 Mon Sep 17 00:00:00 2001 From: "macro.wave.z@gmail.com" Date: Thu, 8 Dec 2016 11:58:23 +0800 Subject: ARMv8: Enable SMC instruction PSCI implementation needs the SMC instruction to be enabled. Signed-off-by: Hongbo Zhang Reviewed-by: Tom Rini Reviewed-by: York Sun diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h index 2553e3e..e1916f7 100644 --- a/arch/arm/include/asm/macro.h +++ b/arch/arm/include/asm/macro.h @@ -182,11 +182,17 @@ lr .req x30 /* * The next lower exception level is AArch64, 64bit EL2 | HCE | - * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1. + * RES1 (Bits[5:4]) | Non-secure EL0/EL1. + * and the SMD depends on requirements. */ +#ifdef CONFIG_ARMV8_PSCI + ldr \tmp, =(SCR_EL3_RW_AARCH64 | SCR_EL3_HCE_EN |\ + SCR_EL3_RES1 | SCR_EL3_NS_EN) +#else ldr \tmp, =(SCR_EL3_RW_AARCH64 | SCR_EL3_HCE_EN |\ SCR_EL3_SMD_DIS | SCR_EL3_RES1 |\ SCR_EL3_NS_EN) +#endif msr scr_el3, \tmp /* Return to the EL2_SP2 mode from EL3 */ -- cgit v0.10.2 From 14bf25d50d934e95ffd7fc1276f9ab1e6c67bfbb Mon Sep 17 00:00:00 2001 From: "macro.wave.z@gmail.com" Date: Thu, 8 Dec 2016 11:58:24 +0800 Subject: ARMv8: Add basic PSCI framework This patch introduces a generic ARMv8 PSCI framework, with all functions returning a dummy ARM_PSCI_RET_NI (Not Implemented), then it is up to each platform to implement their own functions based on this framework. Signed-off-by: Hongbo Zhang Reviewed-by: Tom Rini Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig index edae43d..22dce88 100644 --- a/arch/arm/cpu/armv8/Kconfig +++ b/arch/arm/cpu/armv8/Kconfig @@ -58,6 +58,16 @@ config ARMV8_PSCI_NR_CPUS It is no problem to set a larger value than the number of CPUs in the actual hardware implementation. +config ARMV8_PSCI_CPUS_PER_CLUSTER + int "Number of CPUs per cluster" + depends on ARMV8_PSCI + default 0 + help + The number of CPUs per cluster, suppose each cluster has same number + of CPU cores, platforms with asymmetric clusters don't apply here. + A value 0 or no definition of it works for single cluster system. + System with multi-cluster should difine their own exact value. + if SYS_HAS_ARMV8_SECURE_BASE config ARMV8_SECURE_BASE diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index dea1465..28ba786 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -25,3 +25,4 @@ obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/ obj-$(CONFIG_S32V234) += s32v234/ obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/ obj-$(CONFIG_TARGET_HIKEY) += hisilicon/ +obj-$(CONFIG_ARMV8_PSCI) += psci.o diff --git a/arch/arm/cpu/armv8/psci.S b/arch/arm/cpu/armv8/psci.S new file mode 100644 index 0000000..43d5d6b --- /dev/null +++ b/arch/arm/cpu/armv8/psci.S @@ -0,0 +1,286 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Author: Hongbo Zhang + * + * SPDX-License-Identifier: GPL-2.0+ + * This file implements LS102X platform PSCI SYSTEM-SUSPEND function + */ + +#include +#include +#include + +/* Default PSCI function, return -1, Not Implemented */ +#define PSCI_DEFAULT(__fn) \ + ENTRY(__fn); \ + mov w0, #ARM_PSCI_RET_NI; \ + ret; \ + ENDPROC(__fn); \ + .weak __fn + +/* PSCI function and ID table definition*/ +#define PSCI_TABLE(__id, __fn) \ + .word __id; \ + .word __fn + +.pushsection ._secure.text, "ax" + +/* 32 bits PSCI default functions */ +PSCI_DEFAULT(psci_version) +PSCI_DEFAULT(psci_cpu_suspend) +PSCI_DEFAULT(psci_cpu_off) +PSCI_DEFAULT(psci_cpu_on) +PSCI_DEFAULT(psci_affinity_info) +PSCI_DEFAULT(psci_migrate) +PSCI_DEFAULT(psci_migrate_info_type) +PSCI_DEFAULT(psci_migrate_info_up_cpu) +PSCI_DEFAULT(psci_system_off) +PSCI_DEFAULT(psci_system_reset) +PSCI_DEFAULT(psci_features) +PSCI_DEFAULT(psci_cpu_freeze) +PSCI_DEFAULT(psci_cpu_default_suspend) +PSCI_DEFAULT(psci_node_hw_state) +PSCI_DEFAULT(psci_system_suspend) +PSCI_DEFAULT(psci_set_suspend_mode) +PSCI_DEFAULT(psi_stat_residency) +PSCI_DEFAULT(psci_stat_count) + +.align 3 +_psci_32_table: +PSCI_TABLE(ARM_PSCI_FN_CPU_SUSPEND, psci_cpu_suspend) +PSCI_TABLE(ARM_PSCI_FN_CPU_OFF, psci_cpu_off) +PSCI_TABLE(ARM_PSCI_FN_CPU_ON, psci_cpu_on) +PSCI_TABLE(ARM_PSCI_FN_MIGRATE, psci_migrate) +PSCI_TABLE(ARM_PSCI_0_2_FN_PSCI_VERSION, psci_version) +PSCI_TABLE(ARM_PSCI_0_2_FN_CPU_SUSPEND, psci_cpu_suspend) +PSCI_TABLE(ARM_PSCI_0_2_FN_CPU_OFF, psci_cpu_off) +PSCI_TABLE(ARM_PSCI_0_2_FN_CPU_ON, psci_cpu_on) +PSCI_TABLE(ARM_PSCI_0_2_FN_AFFINITY_INFO, psci_affinity_info) +PSCI_TABLE(ARM_PSCI_0_2_FN_MIGRATE, psci_migrate) +PSCI_TABLE(ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE, psci_migrate_info_type) +PSCI_TABLE(ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU, psci_migrate_info_up_cpu) +PSCI_TABLE(ARM_PSCI_0_2_FN_SYSTEM_OFF, psci_system_off) +PSCI_TABLE(ARM_PSCI_0_2_FN_SYSTEM_RESET, psci_system_reset) +PSCI_TABLE(ARM_PSCI_1_0_FN_PSCI_FEATURES, psci_features) +PSCI_TABLE(ARM_PSCI_1_0_FN_CPU_FREEZE, psci_cpu_freeze) +PSCI_TABLE(ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND, psci_cpu_default_suspend) +PSCI_TABLE(ARM_PSCI_1_0_FN_NODE_HW_STATE, psci_node_hw_state) +PSCI_TABLE(ARM_PSCI_1_0_FN_SYSTEM_SUSPEND, psci_system_suspend) +PSCI_TABLE(ARM_PSCI_1_0_FN_SET_SUSPEND_MODE, psci_set_suspend_mode) +PSCI_TABLE(ARM_PSCI_1_0_FN_STAT_RESIDENCY, psi_stat_residency) +PSCI_TABLE(ARM_PSCI_1_0_FN_STAT_COUNT, psci_stat_count) +PSCI_TABLE(0, 0) + +/* 64 bits PSCI default functions */ +PSCI_DEFAULT(psci_cpu_suspend_64) +PSCI_DEFAULT(psci_cpu_on_64) +PSCI_DEFAULT(psci_affinity_info_64) +PSCI_DEFAULT(psci_migrate_64) +PSCI_DEFAULT(psci_migrate_info_up_cpu_64) +PSCI_DEFAULT(psci_cpu_default_suspend_64) +PSCI_DEFAULT(psci_node_hw_state_64) +PSCI_DEFAULT(psci_system_suspend_64) +PSCI_DEFAULT(psci_stat_residency_64) +PSCI_DEFAULT(psci_stat_count_64) + +.align 3 +_psci_64_table: +PSCI_TABLE(ARM_PSCI_0_2_FN64_CPU_SUSPEND, psci_cpu_suspend_64) +PSCI_TABLE(ARM_PSCI_0_2_FN64_CPU_ON, psci_cpu_on_64) +PSCI_TABLE(ARM_PSCI_0_2_FN64_AFFINITY_INFO, psci_affinity_info_64) +PSCI_TABLE(ARM_PSCI_0_2_FN64_MIGRATE, psci_migrate_64) +PSCI_TABLE(ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU, psci_migrate_info_up_cpu_64) +PSCI_TABLE(ARM_PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND, psci_cpu_default_suspend_64) +PSCI_TABLE(ARM_PSCI_1_0_FN64_NODE_HW_STATE, psci_node_hw_state_64) +PSCI_TABLE(ARM_PSCI_1_0_FN64_SYSTEM_SUSPEND, psci_system_suspend_64) +PSCI_TABLE(ARM_PSCI_1_0_FN64_STAT_RESIDENCY, psci_stat_residency_64) +PSCI_TABLE(ARM_PSCI_1_0_FN64_STAT_COUNT, psci_stat_count_64) +PSCI_TABLE(0, 0) + +.macro psci_enter + /* PSCI call is Fast Call(atomic), so mask DAIF */ + mrs x15, DAIF + stp x15, xzr, [sp, #-16]! + ldr x15, =0x3C0 + msr DAIF, x15 + /* SMC convention, x18 ~ x30 should be saved by callee */ + stp x29, x30, [sp, #-16]! + stp x27, x28, [sp, #-16]! + stp x25, x26, [sp, #-16]! + stp x23, x24, [sp, #-16]! + stp x21, x22, [sp, #-16]! + stp x19, x20, [sp, #-16]! + mrs x15, elr_el3 + stp x18, x15, [sp, #-16]! +.endm + +.macro psci_return + /* restore registers */ + ldp x18, x15, [sp], #16 + msr elr_el3, x15 + ldp x19, x20, [sp], #16 + ldp x21, x22, [sp], #16 + ldp x23, x24, [sp], #16 + ldp x25, x26, [sp], #16 + ldp x27, x28, [sp], #16 + ldp x29, x30, [sp], #16 + /* restore DAIF */ + ldp x15, xzr, [sp], #16 + msr DAIF, x15 + eret +.endm + +/* Caller must put PSCI function-ID table base in x9 */ +handle_psci: + psci_enter +1: ldr x10, [x9] /* Load PSCI function table */ + ubfx x11, x10, #32, #32 + ubfx x10, x10, #0, #32 + cbz x10, 3f /* If reach the end, bail out */ + cmp x10, x0 + b.eq 2f /* PSCI function found */ + add x9, x9, #8 /* If not match, try next entry */ + b 1b + +2: blr x11 /* Call PSCI function */ + psci_return + +3: mov x0, #ARM_PSCI_RET_NI + psci_return + +unknown_smc_id: + ldr x0, =0xFFFFFFFF + eret + +handle_smc32: + /* SMC function ID 0x84000000-0x8400001F: 32 bits PSCI */ + ldr w9, =0x8400001F + cmp w0, w9 + b.gt unknown_smc_id + ldr w9, =0x84000000 + cmp w0, w9 + b.lt unknown_smc_id + + adr x9, _psci_32_table + b handle_psci + +handle_smc64: + /* check SMC32 or SMC64 calls */ + ubfx x9, x0, #30, #1 + cbz x9, handle_smc32 + + /* SMC function ID 0xC4000000-0xC400001F: 64 bits PSCI */ + ldr x9, =0xC400001F + cmp x0, x9 + b.gt unknown_smc_id + ldr x9, =0xC4000000 + cmp x0, x9 + b.lt unknown_smc_id + + adr x9, _psci_64_table + b handle_psci + +/* + * Get CPU ID from MPIDR, suppose every cluster has same number of CPU cores, + * Platform with asymmetric clusters should implement their own interface. + * In case this function being called by other platform's C code, the ARM + * Architecture Procedure Call Standard is considered, e.g. register X0 is + * used for the return value, while in this PSCI environment, X0 usually holds + * the SMC function identifier, so X0 should be saved by caller function. + */ +ENTRY(psci_get_cpu_id) +#ifdef CONFIG_ARMV8_PSCI_CPUS_PER_CLUSTER + mrs x9, MPIDR_EL1 + ubfx x9, x9, #8, #8 + ldr x10, =CONFIG_ARMV8_PSCI_CPUS_PER_CLUSTER + mul x9, x10, x9 +#else + mov x9, xzr +#endif + mrs x10, MPIDR_EL1 + ubfx x10, x10, #0, #8 + add x0, x10, x9 + ret +ENDPROC(psci_get_cpu_id) +.weak psci_get_cpu_id + +/* CPU ID input in x0, stack top output in x0*/ +LENTRY(psci_get_cpu_stack_top) + adr x9, __secure_stack_end + lsl x0, x0, #ARM_PSCI_STACK_SHIFT + sub x0, x9, x0 + ret +ENDPROC(psci_get_cpu_stack_top) + +unhandled_exception: + b unhandled_exception /* simply dead loop */ + +handle_sync: + mov x15, x30 + mov x14, x0 + + bl psci_get_cpu_id + bl psci_get_cpu_stack_top + mov x9, #1 + msr spsel, x9 + mov sp, x0 + + mov x0, x14 + mov x30, x15 + + mrs x9, esr_el3 + ubfx x9, x9, #26, #6 + cmp x9, #0x13 + b.eq handle_smc32 + cmp x9, #0x17 + b.eq handle_smc64 + + b unhandled_exception + + .align 11 + .globl el3_exception_vectors +el3_exception_vectors: + b unhandled_exception /* Sync, Current EL using SP0 */ + .align 7 + b unhandled_exception /* IRQ, Current EL using SP0 */ + .align 7 + b unhandled_exception /* FIQ, Current EL using SP0 */ + .align 7 + b unhandled_exception /* SError, Current EL using SP0 */ + .align 7 + b unhandled_exception /* Sync, Current EL using SPx */ + .align 7 + b unhandled_exception /* IRQ, Current EL using SPx */ + .align 7 + b unhandled_exception /* FIQ, Current EL using SPx */ + .align 7 + b unhandled_exception /* SError, Current EL using SPx */ + .align 7 + b handle_sync /* Sync, Lower EL using AArch64 */ + .align 7 + b unhandled_exception /* IRQ, Lower EL using AArch64 */ + .align 7 + b unhandled_exception /* FIQ, Lower EL using AArch64 */ + .align 7 + b unhandled_exception /* SError, Lower EL using AArch64 */ + .align 7 + b unhandled_exception /* Sync, Lower EL using AArch32 */ + .align 7 + b unhandled_exception /* IRQ, Lower EL using AArch32 */ + .align 7 + b unhandled_exception /* FIQ, Lower EL using AArch32 */ + .align 7 + b unhandled_exception /* SError, Lower EL using AArch32 */ + +ENTRY(psci_setup_vectors) + adr x0, el3_exception_vectors + msr vbar_el3, x0 + ret +ENDPROC(psci_setup_vectors) + +ENTRY(psci_arch_init) + ret +ENDPROC(psci_arch_init) +.weak psci_arch_init + +.popsection diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index 9f1f779..ac8b00d 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -45,6 +45,9 @@ #define ARM_PSCI_0_2_FN_BASE 0x84000000 #define ARM_PSCI_0_2_FN(n) (ARM_PSCI_0_2_FN_BASE + (n)) +#define ARM_PSCI_0_2_FN64_BASE 0xC4000000 +#define ARM_PSCI_0_2_FN64(n) (ARM_PSCI_0_2_FN64_BASE + (n)) + #define ARM_PSCI_0_2_FN_PSCI_VERSION ARM_PSCI_0_2_FN(0) #define ARM_PSCI_0_2_FN_CPU_SUSPEND ARM_PSCI_0_2_FN(1) #define ARM_PSCI_0_2_FN_CPU_OFF ARM_PSCI_0_2_FN(2) @@ -56,6 +59,12 @@ #define ARM_PSCI_0_2_FN_SYSTEM_OFF ARM_PSCI_0_2_FN(8) #define ARM_PSCI_0_2_FN_SYSTEM_RESET ARM_PSCI_0_2_FN(9) +#define ARM_PSCI_0_2_FN64_CPU_SUSPEND ARM_PSCI_0_2_FN64(1) +#define ARM_PSCI_0_2_FN64_CPU_ON ARM_PSCI_0_2_FN64(3) +#define ARM_PSCI_0_2_FN64_AFFINITY_INFO ARM_PSCI_0_2_FN64(4) +#define ARM_PSCI_0_2_FN64_MIGRATE ARM_PSCI_0_2_FN64(5) +#define ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN64(7) + /* PSCI 1.0 interface */ #define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10) #define ARM_PSCI_1_0_FN_CPU_FREEZE ARM_PSCI_0_2_FN(11) @@ -66,6 +75,12 @@ #define ARM_PSCI_1_0_FN_STAT_RESIDENCY ARM_PSCI_0_2_FN(16) #define ARM_PSCI_1_0_FN_STAT_COUNT ARM_PSCI_0_2_FN(17) +#define ARM_PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND ARM_PSCI_0_2_FN64(12) +#define ARM_PSCI_1_0_FN64_NODE_HW_STATE ARM_PSCI_0_2_FN64(13) +#define ARM_PSCI_1_0_FN64_SYSTEM_SUSPEND ARM_PSCI_0_2_FN64(14) +#define ARM_PSCI_1_0_FN64_STAT_RESIDENCY ARM_PSCI_0_2_FN64(16) +#define ARM_PSCI_1_0_FN64_STAT_COUNT ARM_PSCI_0_2_FN64(17) + /* 1KB stack per core */ #define ARM_PSCI_STACK_SHIFT 10 #define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT) -- cgit v0.10.2 From 9a561753ce48def18dbc4aa278c685c93ed0a77d Mon Sep 17 00:00:00 2001 From: "macro.wave.z@gmail.com" Date: Thu, 8 Dec 2016 11:58:25 +0800 Subject: ARMv8: Setup PSCI memory and device tree Newly add ARMv8 PSCI needs to be initialized, be copied or reserved in right place, this patch does all the setup steps. Signed-off-by: Hongbo Zhang Reviewed-by: Tom Rini Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/cpu-dt.c b/arch/arm/cpu/armv8/cpu-dt.c index 659ec27..3a5afe8 100644 --- a/arch/arm/cpu/armv8/cpu-dt.c +++ b/arch/arm/cpu/armv8/cpu-dt.c @@ -6,6 +6,7 @@ #include #include +#include #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT #include #endif @@ -13,7 +14,8 @@ int psci_update_dt(void *fdt) { #ifdef CONFIG_MP -#if defined(CONFIG_FSL_PPA_ARMV8_PSCI) +#if defined(CONFIG_ARMV8_PSCI) || defined(CONFIG_FSL_PPA_ARMV8_PSCI) + #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT /* * If the PSCI in SEC Firmware didn't work, avoid to update the @@ -25,6 +27,13 @@ int psci_update_dt(void *fdt) return 0; #endif fdt_psci(fdt); + +#if defined(CONFIG_ARMV8_PSCI) && !defined(CONFIG_ARMV8_SECURE_BASE) + /* secure code lives in RAM, keep it alive */ + fdt_add_mem_rsv(fdt, (unsigned long)__secure_start, + __secure_end - __secure_start); +#endif + #endif #endif return 0; diff --git a/arch/arm/cpu/armv8/cpu.c b/arch/arm/cpu/armv8/cpu.c index e06c3cc..5dcb5e2 100644 --- a/arch/arm/cpu/armv8/cpu.c +++ b/arch/arm/cpu/armv8/cpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include int cleanup_before_linux(void) @@ -41,3 +42,24 @@ int cleanup_before_linux(void) return 0; } + +#ifdef CONFIG_ARMV8_PSCI +static void relocate_secure_section(void) +{ +#ifdef CONFIG_ARMV8_SECURE_BASE + size_t sz = __secure_end - __secure_start; + + memcpy((void *)CONFIG_ARMV8_SECURE_BASE, __secure_start, sz); + flush_dcache_range(CONFIG_ARMV8_SECURE_BASE, + CONFIG_ARMV8_SECURE_BASE + sz + 1); + invalidate_icache_all(); +#endif +} + +void armv8_setup_psci(void) +{ + relocate_secure_section(); + secure_ram_addr(psci_setup_vectors)(); + secure_ram_addr(psci_arch_init)(); +} +#endif diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h index 5a403bc..d23044a 100644 --- a/arch/arm/include/asm/secure.h +++ b/arch/arm/include/asm/secure.h @@ -6,7 +6,7 @@ #define __secure __attribute__ ((section ("._secure.text"))) #define __secure_data __attribute__ ((section ("._secure.data"))) -#ifdef CONFIG_ARMV7_SECURE_BASE +#if defined(CONFIG_ARMV7_SECURE_BASE) || defined(CONFIG_ARMV8_SECURE_BASE) /* * Warning, horror ahead. * diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 01efc43..dc4c991 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -237,6 +237,17 @@ void smc_call(struct pt_regs *args); void __noreturn psci_system_reset(void); void __noreturn psci_system_off(void); +#ifdef CONFIG_ARMV8_PSCI +extern char __secure_start[]; +extern char __secure_end[]; +extern char __secure_stack_start[]; +extern char __secure_stack_end[]; + +void armv8_setup_psci(void); +void psci_setup_vectors(void); +void psci_arch_init(void); +#endif + #endif /* __ASSEMBLY__ */ #else /* CONFIG_ARM64 */ diff --git a/arch/arm/lib/bootm-fdt.c b/arch/arm/lib/bootm-fdt.c index 1615756..e261d4f 100644 --- a/arch/arm/lib/bootm-fdt.c +++ b/arch/arm/lib/bootm-fdt.c @@ -52,7 +52,8 @@ int arch_fixup_fdt(void *blob) return ret; #endif -#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_FSL_PPA_ARMV8_PSCI) +#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV8_PSCI) || \ + defined(CONFIG_FSL_PPA_ARMV8_PSCI) ret = psci_update_dt(blob); if (ret) return ret; diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 4eee13a..43cc83e 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -316,6 +316,9 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) announce_and_cleanup(fake); if (!fake) { +#ifdef CONFIG_ARMV8_PSCI + armv8_setup_psci(); +#endif do_nonsec_virt_switch(); update_os_arch_secondary_cores(images->os.arch); diff --git a/arch/arm/lib/psci-dt.c b/arch/arm/lib/psci-dt.c index 41e139e..45af037 100644 --- a/arch/arm/lib/psci-dt.c +++ b/arch/arm/lib/psci-dt.c @@ -16,7 +16,8 @@ int fdt_psci(void *fdt) { -#if defined(CONFIG_FSL_PPA_ARMV8_PSCI) || defined(CONFIG_ARMV7_PSCI) +#if defined(CONFIG_ARMV7_PSCI) || defined(CONFIG_ARMV8_PSCI) || \ + defined(CONFIG_FSL_PPA_ARMV8_PSCI) int nodeoff; unsigned int psci_ver = 0; int tmp; @@ -65,7 +66,7 @@ int fdt_psci(void *fdt) init_psci_node: #ifdef CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT psci_ver = sec_firmware_support_psci_version(); -#elif defined(CONFIG_ARMV7_PSCI_1_0) +#elif defined(CONFIG_ARMV7_PSCI_1_0) || defined(CONFIG_ARMV8_PSCI) psci_ver = ARM_PSCI_VER_1_0; #endif switch (psci_ver) { -- cgit v0.10.2 From c151cb5b516e609a0846bd392d6207a77b66a7ff Mon Sep 17 00:00:00 2001 From: "macro.wave.z@gmail.com" Date: Thu, 8 Dec 2016 11:58:26 +0800 Subject: ARMv8: LS1043A: Enable LS1043A default PSCI support A most basic PSCI implementation with only one psci_version is added for LS1043A, this can verify the generic PSCI framework, and more platform specific implementation will be added later. Signed-off-by: Hongbo Zhang Reviewed-by: Tom Rini Reviewed-by: York Sun diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile index 51c1cee..423b4b3 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile +++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile @@ -28,6 +28,7 @@ endif ifneq ($(CONFIG_LS1043A),) obj-$(CONFIG_SYS_HAS_SERDES) += ls1043a_serdes.o +obj-$(CONFIG_ARMV8_PSCI) += ls1043a_psci.o endif ifneq ($(CONFIG_ARCH_LS1012A),) diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_psci.S b/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_psci.S new file mode 100644 index 0000000..86045ac --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-layerscape/ls1043a_psci.S @@ -0,0 +1,20 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Author: Hongbo Zhang + * + * SPDX-License-Identifier: GPL-2.0+ + * This file implements LS102X platform PSCI SYSTEM-SUSPEND function + */ + +#include +#include +#include + + .pushsection ._secure.text, "ax" + +.globl psci_version +psci_version: + ldr w0, =0x00010000 /* PSCI v1.0 */ + ret + + .popsection diff --git a/board/freescale/ls1043ardb/Kconfig b/board/freescale/ls1043ardb/Kconfig index 51818ec..80203a4 100644 --- a/board/freescale/ls1043ardb/Kconfig +++ b/board/freescale/ls1043ardb/Kconfig @@ -13,4 +13,13 @@ config SYS_SOC config SYS_CONFIG_NAME default "ls1043ardb" +config SYS_HAS_ARMV8_SECURE_BASE + bool "Enable secure address for PSCI image" + depends on ARMV8_PSCI + default n + help + PSCI image can be re-located to secure RAM. + If enabled, please also define the value for ARMV8_SECURE_BASE, + for LS1043ARDB, it could be some address in OCRAM. + endif -- cgit v0.10.2