From patchwork Wed Apr 22 13:52:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238301 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:12 +0800 Subject: [PATCH 01/24] imx: fix cpu_type helper Message-ID: <20200422135235.14756-1-peng.fan@nxp.com> i.MX8MP use 0x182 as its ID, so 0xff is not valid to get the cpu type, extend it to 0x1ff. Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/sys_proto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 35b39b1f86..103dde4d36 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -16,7 +16,7 @@ #define is_soc_rev(rev) (soc_rev() == rev) /* returns MXC_CPU_ value */ -#define cpu_type(rev) (((rev) >> 12) & 0xff) +#define cpu_type(rev) (((rev) >> 12) & 0x1ff) #define soc_type(rev) (((rev) >> 12) & 0xf0) /* both macros return/take MXC_CPU_ constants */ #define get_cpu_type() (cpu_type(get_cpu_rev())) From patchwork Wed Apr 22 13:52:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238302 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:13 +0800 Subject: [PATCH 02/24] imx8mm: Update CPU speed grading In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-2-peng.fan@nxp.com> From: Ye Li According to iMX8MM datasheet (IMX8MMIEC_Rev_D and IMX8MMCEC_Rev_D), the speed grading for imx8mm is 800Mhz, 1.2Ghz, 1.6Ghz and 1.8Ghz. Update them to get_cpu_speed_grade_hz function. Signed-off-by: Ye Li Reviewed-by: Peng Fan --- arch/arm/mach-imx/cpu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index bfa85c64c6..55e3539cff 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -332,11 +332,11 @@ u32 get_cpu_speed_grade_hz(void) case OCOTP_TESTER3_SPEED_GRADE0: return 800000000; case OCOTP_TESTER3_SPEED_GRADE1: - return is_mx7() ? 500000000 : 1000000000; + return (is_mx7() ? 500000000 : (is_imx8mq() ? 1000000000 : 1200000000)); case OCOTP_TESTER3_SPEED_GRADE2: - return is_mx7() ? 1000000000 : 1300000000; + return (is_mx7() ? 1000000000 : (is_imx8mq() ? 1300000000 : 1600000000)); case OCOTP_TESTER3_SPEED_GRADE3: - return is_mx7() ? 1200000000 : 1500000000; + return (is_mx7() ? 1200000000 : (is_imx8mq() ? 1500000000 : 1800000000)); } return 0; From patchwork Wed Apr 22 13:52:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238304 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:14 +0800 Subject: [PATCH 03/24] imx8mn: Update speed grade In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-3-peng.fan@nxp.com> imx8mn speed grade fuse uses new definitions as below. So have to update get_cpu_speed_grade_hz function to match it. SPEED_GRADE[5:4] SPEED_GRADE[3:0] MHz xx 0000 2300 xx 0001 2200 xx 0010 2100 xx 0011 2000 xx 0100 1900 xx 0101 1800 xx 0110 1700 xx 0111 1600 xx 1000 1500 xx 1001 1400 xx 1010 1300 xx 1011 1200 xx 1100 1100 xx 1101 1000 xx 1110 900 xx 1111 800 Signed-off-by: Peng Fan --- arch/arm/mach-imx/cpu.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 55e3539cff..5b979cc1f5 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -314,6 +314,7 @@ enum cpu_speed { OCOTP_TESTER3_SPEED_GRADE1, OCOTP_TESTER3_SPEED_GRADE2, OCOTP_TESTER3_SPEED_GRADE3, + OCOTP_TESTER3_SPEED_GRADE4, }; u32 get_cpu_speed_grade_hz(void) @@ -326,7 +327,16 @@ u32 get_cpu_speed_grade_hz(void) val = readl(&fuse->tester3); val >>= OCOTP_TESTER3_SPEED_SHIFT; - val &= 0x3; + + if (is_imx8mn()) { + val &= 0xf; + return 2300000000 - val * 100000000; + } + + if (is_imx8mm()) + val &= 0x7; + else + val &= 0x3; switch(val) { case OCOTP_TESTER3_SPEED_GRADE0: @@ -337,6 +347,8 @@ u32 get_cpu_speed_grade_hz(void) return (is_mx7() ? 1000000000 : (is_imx8mq() ? 1300000000 : 1600000000)); case OCOTP_TESTER3_SPEED_GRADE3: return (is_mx7() ? 1200000000 : (is_imx8mq() ? 1500000000 : 1800000000)); + case OCOTP_TESTER3_SPEED_GRADE4: + return 2000000000; } return 0; From patchwork Wed Apr 22 13:52:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238303 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:15 +0800 Subject: [PATCH 04/24] imx: cpu: support speed grade for i.MX8MP In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-4-peng.fan@nxp.com> i.MX8MP speed grade use same layout as i.MX8MN, so reuse it for i.MX8MP Reviewed-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 5b979cc1f5..8217913b4a 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -328,7 +328,7 @@ u32 get_cpu_speed_grade_hz(void) val = readl(&fuse->tester3); val >>= OCOTP_TESTER3_SPEED_SHIFT; - if (is_imx8mn()) { + if (is_imx8mn() || is_imx8mp()) { val &= 0xf; return 2300000000 - val * 100000000; } From patchwork Wed Apr 22 13:52:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238305 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:16 +0800 Subject: [PATCH 05/24] imx: imx8m: add i.MX8MQ Dual and QuadLite support In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-5-peng.fan@nxp.com> Add i.MX8MQ Dual and QuadLite variants. Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx/cpu.h | 2 ++ arch/arm/include/asm/mach-imx/sys_proto.h | 4 +++- arch/arm/mach-imx/cpu.c | 6 +++++- arch/arm/mach-imx/imx8m/soc.c | 10 +++++++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h index 5ade63665a..71f0715dd1 100644 --- a/arch/arm/include/asm/arch-imx/cpu.h +++ b/arch/arm/include/asm/arch-imx/cpu.h @@ -26,6 +26,8 @@ #define MXC_CPU_MX7S 0x71 /* dummy ID */ #define MXC_CPU_MX7D 0x72 #define MXC_CPU_IMX8MQ 0x82 +#define MXC_CPU_IMX8MD 0x83 /* dummy ID */ +#define MXC_CPU_IMX8MQL 0x84 /* dummy ID */ #define MXC_CPU_IMX8MM 0x85 /* dummy ID */ #define MXC_CPU_IMX8MML 0x86 /* dummy ID */ #define MXC_CPU_IMX8MMD 0x87 /* dummy ID */ diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 103dde4d36..59b145bab1 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -43,7 +43,9 @@ #define is_mx7ulp() (is_cpu_type(MXC_CPU_MX7ULP)) -#define is_imx8mq() (is_cpu_type(MXC_CPU_IMX8MQ)) +#define is_imx8mq() (is_cpu_type(MXC_CPU_IMX8MQ) || is_cpu_type(MXC_CPU_IMX8MD) || is_cpu_type(MXC_CPU_IMX8MQL)) +#define is_imx8md() (is_cpu_type(MXC_CPU_IMX8MD)) +#define is_imx8mql() (is_cpu_type(MXC_CPU_IMX8MQL)) #define is_imx8qm() (is_cpu_type(MXC_CPU_IMX8QM)) #define is_imx8mm() (is_cpu_type(MXC_CPU_IMX8MM) || is_cpu_type(MXC_CPU_IMX8MML) ||\ is_cpu_type(MXC_CPU_IMX8MMD) || is_cpu_type(MXC_CPU_IMX8MMDL) || \ diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 8217913b4a..e07ca5821a 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -109,7 +109,11 @@ const char *get_imx_type(u32 imxtype) case MXC_CPU_IMX8MMSL: return "8MMSL"; /* Single-core Lite version of the imx8mm */ case MXC_CPU_IMX8MQ: - return "8MQ"; /* Quad-core version of the imx8m */ + return "8MQ"; /* Quad-core version of the imx8mq */ + case MXC_CPU_IMX8MQL: + return "8MQLite"; /* Quad-core Lite version of the imx8mq */ + case MXC_CPU_IMX8MD: + return "8MD"; /* Dual-core version of the imx8mq */ case MXC_CPU_MX7S: return "7S"; /* Single-core version of the mx7 */ case MXC_CPU_MX7D: diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 7fcbd53f30..c449b8b1ec 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -165,7 +165,13 @@ static u32 get_cpu_variant_type(u32 type) u32 value = readl(&fuse->tester4); - if (type == MXC_CPU_IMX8MM) { + if (type == MXC_CPU_IMX8MQ) { + if ((value & 0x3) == 0x2) + return MXC_CPU_IMX8MD; + else if (value & 0x200000) + return MXC_CPU_IMX8MQL; + + } else if (type == MXC_CPU_IMX8MM) { switch (value & 0x3) { case 2: if (value & 0x1c0000) @@ -226,6 +232,8 @@ u32 get_cpu_rev(void) } } } + + type = get_cpu_variant_type(type); } return (type << 12) | reg; From patchwork Wed Apr 22 13:52:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238307 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:17 +0800 Subject: [PATCH 06/24] imx: imx8m: add i.MX8MN variants support In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-6-peng.fan@nxp.com> Add i.MX8MN variants support Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx/cpu.h | 5 +++++ arch/arm/include/asm/mach-imx/sys_proto.h | 9 ++++++++- arch/arm/mach-imx/cpu.c | 12 +++++++++++- arch/arm/mach-imx/imx8m/soc.c | 19 ++++++++++++++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h index 71f0715dd1..b52565473d 100644 --- a/arch/arm/include/asm/arch-imx/cpu.h +++ b/arch/arm/include/asm/arch-imx/cpu.h @@ -35,6 +35,11 @@ #define MXC_CPU_IMX8MMS 0x89 /* dummy ID */ #define MXC_CPU_IMX8MMSL 0x8a /* dummy ID */ #define MXC_CPU_IMX8MN 0x8b /* dummy ID */ +#define MXC_CPU_IMX8MND 0x8c /* dummy ID */ +#define MXC_CPU_IMX8MNS 0x8d /* dummy ID */ +#define MXC_CPU_IMX8MNL 0x8e /* dummy ID */ +#define MXC_CPU_IMX8MNDL 0x8f /* dummy ID */ +#define MXC_CPU_IMX8MNSL 0x181 /* dummy ID */ #define MXC_CPU_IMX8MP 0x182/* dummy ID */ #define MXC_CPU_IMX8QXP_A0 0x90 /* dummy ID */ #define MXC_CPU_IMX8QM 0x91 /* dummy ID */ diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index 59b145bab1..a02cd40c7d 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -55,7 +55,14 @@ #define is_imx8mmdl() (is_cpu_type(MXC_CPU_IMX8MMDL)) #define is_imx8mms() (is_cpu_type(MXC_CPU_IMX8MMS)) #define is_imx8mmsl() (is_cpu_type(MXC_CPU_IMX8MMSL)) -#define is_imx8mn() (is_cpu_type(MXC_CPU_IMX8MN)) +#define is_imx8mn() (is_cpu_type(MXC_CPU_IMX8MN) || is_cpu_type(MXC_CPU_IMX8MND) || \ + is_cpu_type(MXC_CPU_IMX8MNS) || is_cpu_type(MXC_CPU_IMX8MNL) || \ + is_cpu_type(MXC_CPU_IMX8MNDL) || is_cpu_type(MXC_CPU_IMX8MNSL)) +#define is_imx8mnd() (is_cpu_type(MXC_CPU_IMX8MND)) +#define is_imx8mns() (is_cpu_type(MXC_CPU_IMX8MNS)) +#define is_imx8mnl() (is_cpu_type(MXC_CPU_IMX8MNL)) +#define is_imx8mndl() (is_cpu_type(MXC_CPU_IMX8MNDL)) +#define is_imx8mnsl() (is_cpu_type(MXC_CPU_IMX8MNSL)) #define is_imx8mp() (is_cpu_type(MXC_CPU_IMX8MP)) #define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP)) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index e07ca5821a..e83f6934cd 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -95,7 +95,17 @@ const char *get_imx_type(u32 imxtype) case MXC_CPU_IMX8MP: return "8MP"; /* Quad-core version of the imx8mp */ case MXC_CPU_IMX8MN: - return "8MNano";/* Quad-core version of the imx8mn */ + return "8MNano Quad"; /* Quad-core version */ + case MXC_CPU_IMX8MND: + return "8MNano Dual"; /* Dual-core version */ + case MXC_CPU_IMX8MNS: + return "8MNano Solo"; /* Single-core version */ + case MXC_CPU_IMX8MNL: + return "8MNano QuadLite"; /* Quad-core Lite version */ + case MXC_CPU_IMX8MNDL: + return "8MNano DualLite"; /* Dual-core Lite version */ + case MXC_CPU_IMX8MNSL: + return "8MNano SoloLite"; /* Single-core Lite version */ case MXC_CPU_IMX8MM: return "8MMQ"; /* Quad-core version of the imx8mm */ case MXC_CPU_IMX8MML: diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index c449b8b1ec..871179509c 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -188,6 +188,23 @@ static u32 get_cpu_variant_type(u32 type) return MXC_CPU_IMX8MML; break; } + } else if (type == MXC_CPU_IMX8MN) { + switch (value & 0x3) { + case 2: + if (value & 0x1000000) + return MXC_CPU_IMX8MNDL; + else + return MXC_CPU_IMX8MND; + case 3: + if (value & 0x1000000) + return MXC_CPU_IMX8MNSL; + else + return MXC_CPU_IMX8MNS; + default: + if (value & 0x1000000) + return MXC_CPU_IMX8MNL; + break; + } } return type; @@ -208,7 +225,7 @@ u32 get_cpu_rev(void) return (MXC_CPU_IMX8MP << 12) | reg; } else if (major_low == 0x42) { /* iMX8MN */ - return (MXC_CPU_IMX8MN << 12) | reg; + type = get_cpu_variant_type(MXC_CPU_IMX8MN); } else if (major_low == 0x41) { type = get_cpu_variant_type(MXC_CPU_IMX8MM); } else { From patchwork Wed Apr 22 13:52:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238308 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:18 +0800 Subject: [PATCH 07/24] imx: update is_imx6ull to include i.MX6ULZ In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-7-peng.fan@nxp.com> Update is_imx6ull helper to include i.MX6ULZ SoC. i.MX6ULZ could share same macro, then we no need to add is_imx6ulz in various drivers. Signed-off-by: Peng Fan --- arch/arm/include/asm/mach-imx/sys_proto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index a02cd40c7d..2a997f280d 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -37,7 +37,7 @@ #define is_mx6sl() (is_cpu_type(MXC_CPU_MX6SL)) #define is_mx6solo() (is_cpu_type(MXC_CPU_MX6SOLO)) #define is_mx6ul() (is_cpu_type(MXC_CPU_MX6UL)) -#define is_mx6ull() (is_cpu_type(MXC_CPU_MX6ULL)) +#define is_mx6ull() (is_cpu_type(MXC_CPU_MX6ULL) || is_cpu_type(MXC_CPU_MX6ULZ)) #define is_mx6ulz() (is_cpu_type(MXC_CPU_MX6ULZ)) #define is_mx6sll() (is_cpu_type(MXC_CPU_MX6SLL)) From patchwork Wed Apr 22 13:52:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238322 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:19 +0800 Subject: [PATCH 08/24] imx8: move SIP macro to common header In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-8-peng.fan@nxp.com> Move the SIP macro to common header and unify the name to make others could reuse them. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/misc.c | 8 +++----- include/imx_sip.h | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-imx/imx8/misc.c b/arch/arm/mach-imx/imx8/misc.c index 00fe4670bb..76d6571d8b 100644 --- a/arch/arm/mach-imx/imx8/misc.c +++ b/arch/arm/mach-imx/imx8/misc.c @@ -2,6 +2,7 @@ #include #include #include +#include int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate) { @@ -26,9 +27,6 @@ int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate) return 0; } -#define FSL_SIP_BUILDINFO 0xC2000003 -#define FSL_SIP_BUILDINFO_GET_COMMITHASH 0x00 - void build_info(void) { u32 seco_build = 0, seco_commit = 0; @@ -51,8 +49,8 @@ void build_info(void) } /* Get ARM Trusted Firmware commit id */ - atf_commit = call_imx_sip(FSL_SIP_BUILDINFO, - FSL_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); + atf_commit = call_imx_sip(IMX_SIP_BUILDINFO, + IMX_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); if (atf_commit == 0xffffffff) { debug("ATF does not support build info\n"); atf_commit = 0x30; /* Display 0 */ diff --git a/include/imx_sip.h b/include/imx_sip.h index 139ff61b8a..26dbe0421a 100644 --- a/include/imx_sip.h +++ b/include/imx_sip.h @@ -7,7 +7,10 @@ #define _IMX_SIP_H_ #define IMX_SIP_GPC 0xC2000000 -#define IMX_SIP_GPC_PM_DOMAIN 0x03 +#define IMX_SIP_GPC_PM_DOMAIN 0x03 + +#define IMX_SIP_BUILDINFO 0xC2000003 +#define IMX_SIP_BUILDINFO_GET_COMMITHASH 0x00 #define IMX_SIP_SRC 0xC2000005 #define IMX_SIP_SRC_M4_START 0x00 From patchwork Wed Apr 22 13:52:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238306 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:20 +0800 Subject: [PATCH 09/24] imx8m: acquire ATF commit hash In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-9-peng.fan@nxp.com> Acquire ATF commit hash when booting U-Boot to make user easy to know the ATF version. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 871179509c..8b6be7bc19 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -425,3 +425,27 @@ void reset_cpu(ulong addr) } } #endif + +#if defined(CONFIG_ARCH_MISC_INIT) +static void acquire_buildinfo(void) +{ + u64 atf_commit = 0; + + /* Get ARM Trusted Firmware commit id */ + atf_commit = call_imx_sip(IMX_SIP_BUILDINFO, + IMX_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); + if (atf_commit == 0xffffffff) { + debug("ATF does not support build info\n"); + atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */ + } + + printf("\n BuildInfo:\n - ATF %s\n\n", (char *)&atf_commit); +} + +int arch_misc_init(void) +{ + acquire_buildinfo(); + + return 0; +} +#endif From patchwork Wed Apr 22 13:52:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238313 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:21 +0800 Subject: [PATCH 10/24] imx8m: update clock root and fix core_sel In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-10-peng.fan@nxp.com> Update clock root table to let it be easy to configure clock at very early stage. Also the core_sel mux parent should be A53 CLK root and ARM PLL. Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8m/clock_imx8mm.h | 3 +- arch/arm/mach-imx/imx8m/clock_slice.c | 824 ++++++++++++++++++++++++- 2 files changed, 809 insertions(+), 18 deletions(-) diff --git a/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h b/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h index debed6bac7..84ed61d21e 100644 --- a/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h +++ b/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h @@ -363,7 +363,8 @@ enum clk_root_src { EXT_CLK_2, EXT_CLK_3, EXT_CLK_4, - OSC_HDMI_CLK + OSC_HDMI_CLK, + ARM_A53_ALT_CLK, }; enum clk_ccgr_index { diff --git a/arch/arm/mach-imx/imx8m/clock_slice.c b/arch/arm/mach-imx/imx8m/clock_slice.c index 8b7a4dad65..b5ed27a923 100644 --- a/arch/arm/mach-imx/imx8m/clock_slice.c +++ b/arch/arm/mach-imx/imx8m/clock_slice.c @@ -472,33 +472,545 @@ static struct clk_root_map root_array[] = { {DRAM_PLL1_CLK} }, {CORE_SEL_CFG, CORE_SEL_CLOCK_SLICE, 0, + {ARM_A53_ALT_CLK, ARM_PLL_CLK} + }, +}; +#elif defined(CONFIG_IMX8MM) +static struct clk_root_map root_array[] = { + {ARM_A53_CLK_ROOT, CORE_CLOCK_SLICE, 0, + {OSC_24M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL3_CLK} + }, + {ARM_M4_CLK_ROOT, CORE_CLOCK_SLICE, 1, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK} + }, + {VPU_A53_CLK_ROOT, CORE_CLOCK_SLICE, 2, + {OSC_24M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, VPU_PLL_CLK} + }, + {GPU3D_CLK_ROOT, CORE_CLOCK_SLICE, 3, + {OSC_24M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {GPU2D_CLK_ROOT, CORE_CLOCK_SLICE, 4, + {OSC_24M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {MAIN_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 0, + {OSC_24M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL1_100M_CLK} + }, + {ENET_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 1, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK} + }, + {NAND_USDHC_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 2, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_133M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL1_CLK} + }, + {VPU_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 3, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, VPU_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_100M_CLK} + }, + {DISPLAY_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 4, + {OSC_24M_CLK, SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_40M_CLK, AUDIO_PLL2_CLK, + EXT_CLK_1, EXT_CLK_4} + }, + {DISPLAY_APB_CLK_ROOT, BUS_CLOCK_SLICE, 5, + {OSC_24M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_40M_CLK, AUDIO_PLL2_CLK, + EXT_CLK_1, EXT_CLK_3} + }, + {DISPLAY_RTRM_CLK_ROOT, BUS_CLOCK_SLICE, 6, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_1000M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + EXT_CLK_2, EXT_CLK_3} + }, + {USB_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 7, + {OSC_24M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {GPU_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 8, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {GPU_AHB_CLK_ROOT, BUS_CLOCK_SLICE, 9, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {NOC_CLK_ROOT, BUS_CLOCK_SLICE, 10, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_500M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {NOC_APB_CLK_ROOT, BUS_CLOCK_SLICE, 11, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_800M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + }, + {AHB_CLK_ROOT, AHB_CLOCK_SLICE, 0, + {OSC_24M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL1_400M_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + }, + {AUDIO_AHB_CLK_ROOT, AHB_CLOCK_SLICE, 1, + {OSC_24M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_166M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + }, + {MIPI_DSI_ESC_RX_CLK_ROOT, AHB_CLOCK_SLICE, 2, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {DRAM_ALT_CLK_ROOT, IP_CLOCK_SLICE, 0, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL1_100M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL1_266M_CLK} + }, + {DRAM_APB_CLK_ROOT, IP_CLOCK_SLICE, 1, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {VPU_G1_CLK_ROOT, IP_CLOCK_SLICE, 2, + {OSC_24M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_100M_CLK, + SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK} + }, + {VPU_G2_CLK_ROOT, IP_CLOCK_SLICE, 3, + {OSC_24M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_100M_CLK, + SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK} + }, + {DISPLAY_DTRC_CLK_ROOT, IP_CLOCK_SLICE, 4, + {OSC_24M_CLK, VIDEO_PLL2_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_160M_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK} + }, + {DISPLAY_DC8000_CLK_ROOT, IP_CLOCK_SLICE, 5, + {OSC_24M_CLK, VIDEO_PLL2_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_160M_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK} + }, + {PCIE_CTRL_CLK_ROOT, IP_CLOCK_SLICE, 6, + {OSC_24M_CLK, SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL3_CLK} + }, + {PCIE_PHY_CLK_ROOT, IP_CLOCK_SLICE, 7, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_500M_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4, + SYSTEM_PLL1_400M_CLK} + }, + {PCIE_AUX_CLK_ROOT, IP_CLOCK_SLICE, 8, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_200M_CLK} + }, + {DC_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 9, + {OSC_24M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, + AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} + }, + {LCDIF_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 10, + {OSC_24M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, + AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} + }, + {SAI1_CLK_ROOT, IP_CLOCK_SLICE, 11, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_1, EXT_CLK_2} + }, + {SAI2_CLK_ROOT, IP_CLOCK_SLICE, 12, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {SAI3_CLK_ROOT, IP_CLOCK_SLICE, 13, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_3, EXT_CLK_4} + }, + {SAI4_CLK_ROOT, IP_CLOCK_SLICE, 14, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_1, EXT_CLK_2} + }, + {SAI5_CLK_ROOT, IP_CLOCK_SLICE, 15, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {SAI6_CLK_ROOT, IP_CLOCK_SLICE, 16, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_3, EXT_CLK_4} + }, + {SPDIF1_CLK_ROOT, IP_CLOCK_SLICE, 17, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {SPDIF2_CLK_ROOT, IP_CLOCK_SLICE, 18, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_3, EXT_CLK_4} + }, + {ENET_REF_CLK_ROOT, IP_CLOCK_SLICE, 19, + {OSC_24M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, EXT_CLK_4} + }, + {ENET_TIMER_CLK_ROOT, IP_CLOCK_SLICE, 20, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, AUDIO_PLL1_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4, + VIDEO_PLL_CLK} + }, + {ENET_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 21, + {OSC_24M_CLK, SYSTEM_PLL2_50M_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_500M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {NAND_CLK_ROOT, IP_CLOCK_SLICE, 22, + {OSC_24M_CLK, SYSTEM_PLL2_500M_CLK, AUDIO_PLL1_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL2_250M_CLK, VIDEO_PLL_CLK} + }, + {QSPI_CLK_ROOT, IP_CLOCK_SLICE, 23, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL2_333M_CLK, + SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK} + }, + {USDHC1_CLK_ROOT, IP_CLOCK_SLICE, 24, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL1_266M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL1_100M_CLK} + }, + {USDHC2_CLK_ROOT, IP_CLOCK_SLICE, 25, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL1_266M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL1_100M_CLK} + }, + {I2C1_CLK_ROOT, IP_CLOCK_SLICE, 26, + {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C2_CLK_ROOT, IP_CLOCK_SLICE, 27, + {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C3_CLK_ROOT, IP_CLOCK_SLICE, 28, + {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C4_CLK_ROOT, IP_CLOCK_SLICE, 29, + {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {UART1_CLK_ROOT, IP_CLOCK_SLICE, 30, + {OSC_24M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {UART2_CLK_ROOT, IP_CLOCK_SLICE, 31, + {OSC_24M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {UART3_CLK_ROOT, IP_CLOCK_SLICE, 32, + {OSC_24M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {UART4_CLK_ROOT, IP_CLOCK_SLICE, 33, + {OSC_24M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {USB_CORE_REF_CLK_ROOT, IP_CLOCK_SLICE, 34, + {OSC_24M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {USB_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 35, + {OSC_24M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {GIC_CLK_ROOT, IP_CLOCK_SLICE, 36, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_800M_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {ECSPI1_CLK_ROOT, IP_CLOCK_SLICE, 37, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {ECSPI2_CLK_ROOT, IP_CLOCK_SLICE, 38, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {PWM1_CLK_ROOT, IP_CLOCK_SLICE, 39, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM2_CLK_ROOT, IP_CLOCK_SLICE, 40, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM3_CLK_ROOT, IP_CLOCK_SLICE, 41, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_2, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM4_CLK_ROOT, IP_CLOCK_SLICE, 42, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_2, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {GPT1_CLK_ROOT, IP_CLOCK_SLICE, 43, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1} + }, + {GPT2_CLK_ROOT, IP_CLOCK_SLICE, 44, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2} + }, + {GPT3_CLK_ROOT, IP_CLOCK_SLICE, 45, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3} + }, + {GPT4_CLK_ROOT, IP_CLOCK_SLICE, 46, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1} + }, + {GPT5_CLK_ROOT, IP_CLOCK_SLICE, 47, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2} + }, + {GPT6_CLK_ROOT, IP_CLOCK_SLICE, 48, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3} + }, + {TRACE_CLK_ROOT, IP_CLOCK_SLICE, 49, + {OSC_24M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK, + VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_1, EXT_CLK_3} + }, + {WDOG_CLK_ROOT, IP_CLOCK_SLICE, 50, + {OSC_24M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK, + VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_166M_CLK} + }, + {WRCLK_CLK_ROOT, IP_CLOCK_SLICE, 51, + {OSC_24M_CLK, SYSTEM_PLL1_40M_CLK, VPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_100M_CLK} + }, + {IPP_DO_CLKO1, IP_CLOCK_SLICE, 52, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, OSC_HDMI_CLK, + SYSTEM_PLL1_200M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL2_500M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_80M_CLK} + }, + {IPP_DO_CLKO2, IP_CLOCK_SLICE, 53, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL2_166M_CLK, SYSTEM_PLL3_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, OSC_32K_CLK} + }, + {MIPI_DSI_CORE_CLK_ROOT, IP_CLOCK_SLICE, 54, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_DSI_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 55, + {OSC_24M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_DSI_DBI_CLK_ROOT, IP_CLOCK_SLICE, 56, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {USDHC3_CLK_ROOT, IP_CLOCK_SLICE, 57, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL1_266M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL1_100M_CLK} + }, + {MIPI_CSI1_CORE_CLK_ROOT, IP_CLOCK_SLICE, 58, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI1_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 59, + {OSC_24M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI1_ESC_CLK_ROOT, IP_CLOCK_SLICE, 60, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {MIPI_CSI2_CORE_CLK_ROOT, IP_CLOCK_SLICE, 61, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI2_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 62, + {OSC_24M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI2_ESC_CLK_ROOT, IP_CLOCK_SLICE, 63, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {PCIE2_CTRL_CLK_ROOT, IP_CLOCK_SLICE, 64, + {OSC_24M_CLK, SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL3_CLK} + }, + {PCIE2_PHY_CLK_ROOT, IP_CLOCK_SLICE, 65, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_500M_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, + EXT_CLK_4, SYSTEM_PLL1_400M_CLK} + }, + {PCIE2_AUX_CLK_ROOT, IP_CLOCK_SLICE, 66, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_80M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_200M_CLK} + }, + {ECSPI3_CLK_ROOT, IP_CLOCK_SLICE, 67, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {PDM_CLK_ROOT, IP_CLOCK_SLICE, 68, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, AUDIO_PLL1_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK}, + }, + {VPU_H1_CLK_ROOT, IP_CLOCK_SLICE, 69, + {OSC_24M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK} + }, + {DRAM_SEL_CFG, DRAM_SEL_CLOCK_SLICE, 0, {DRAM_PLL1_CLK} }, + {CORE_SEL_CFG, CORE_SEL_CLOCK_SLICE, 0, + {ARM_A53_ALT_CLK, ARM_PLL_CLK} + }, }; -#elif defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN) +#elif defined(CONFIG_IMX8MN) static struct clk_root_map root_array[] = { {ARM_A53_CLK_ROOT, CORE_CLOCK_SLICE, 0, {OSC_24M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL3_CLK} }, - {NAND_USDHC_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 2, - {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, - SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_133M_CLK, - SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL1_CLK} + {ARM_M7_CLK_ROOT, CORE_CLOCK_SLICE, 1, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_250M_CLK, + VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK} + }, + {GPU_CORE_CLK_ROOT, CORE_CLOCK_SLICE, 3, + {OSC_24M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {GPU_SHADER_CLK_ROOT, CORE_CLOCK_SLICE, 4, + {OSC_24M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {MAIN_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 0, + {OSC_24M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL1_100M_CLK} + }, + {ENET_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 1, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK} + }, + {NAND_USDHC_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 2, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_133M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL1_CLK} + }, + {DISPLAY_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 4, + {OSC_24M_CLK, SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_40M_CLK, AUDIO_PLL2_CLK, + EXT_CLK_1, EXT_CLK_4} + }, + {DISPLAY_APB_CLK_ROOT, BUS_CLOCK_SLICE, 5, + {OSC_24M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_40M_CLK, AUDIO_PLL2_CLK, + EXT_CLK_1, EXT_CLK_3} + }, + {USB_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 7, + {OSC_24M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {GPU_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 8, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {GPU_AHB_CLK_ROOT, BUS_CLOCK_SLICE, 9, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} }, {NOC_CLK_ROOT, BUS_CLOCK_SLICE, 10, {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_500M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} }, -#ifdef CONFIG_IMX8MM - {NOC_APB_CLK_ROOT, BUS_CLOCK_SLICE, 11, - {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL3_CLK, - SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_200M_CLK, - SYSTEM_PLL1_800M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + {AHB_CLK_ROOT, AHB_CLOCK_SLICE, 0, + {OSC_24M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL1_400M_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + }, + {AUDIO_AHB_CLK_ROOT, AHB_CLOCK_SLICE, 1, + {OSC_24M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_166M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} }, -#endif {DRAM_ALT_CLK_ROOT, IP_CLOCK_SLICE, 0, {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_1000M_CLK, @@ -509,6 +1021,91 @@ static struct clk_root_map root_array[] = { SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} }, + {DISPLAY_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 10, + {OSC_24M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, + AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} + }, + {SAI2_CLK_ROOT, IP_CLOCK_SLICE, 12, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {SAI3_CLK_ROOT, IP_CLOCK_SLICE, 13, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_3, EXT_CLK_4} + }, + {SAI5_CLK_ROOT, IP_CLOCK_SLICE, 15, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {SAI6_CLK_ROOT, IP_CLOCK_SLICE, 16, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_3, EXT_CLK_4} + }, + {SPDIF1_CLK_ROOT, IP_CLOCK_SLICE, 17, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {ENET_REF_CLK_ROOT, IP_CLOCK_SLICE, 19, + {OSC_24M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, EXT_CLK_4} + }, + {ENET_TIMER_CLK_ROOT, IP_CLOCK_SLICE, 20, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, AUDIO_PLL1_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4, + VIDEO_PLL_CLK} + }, + {ENET_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 21, + {OSC_24M_CLK, SYSTEM_PLL2_50M_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_500M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {NAND_CLK_ROOT, IP_CLOCK_SLICE, 22, + {OSC_24M_CLK, SYSTEM_PLL2_500M_CLK, AUDIO_PLL1_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL2_250M_CLK, VIDEO_PLL_CLK} + }, + {QSPI_CLK_ROOT, IP_CLOCK_SLICE, 23, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL2_333M_CLK, + SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK} + }, + {USDHC1_CLK_ROOT, IP_CLOCK_SLICE, 24, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL1_266M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL1_100M_CLK} + }, + {USDHC2_CLK_ROOT, IP_CLOCK_SLICE, 25, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL1_266M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL1_100M_CLK} + }, + {I2C1_CLK_ROOT, IP_CLOCK_SLICE, 26, + {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C2_CLK_ROOT, IP_CLOCK_SLICE, 27, + {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C3_CLK_ROOT, IP_CLOCK_SLICE, 28, + {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C4_CLK_ROOT, IP_CLOCK_SLICE, 29, + {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, {UART1_CLK_ROOT, IP_CLOCK_SLICE, 30, {OSC_24M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, @@ -529,19 +1126,167 @@ static struct clk_root_map root_array[] = { SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} }, + {USB_CORE_REF_CLK_ROOT, IP_CLOCK_SLICE, 34, + {OSC_24M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {USB_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 35, + {OSC_24M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, {GIC_CLK_ROOT, IP_CLOCK_SLICE, 36, {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_800M_CLK, EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} }, + {ECSPI1_CLK_ROOT, IP_CLOCK_SLICE, 37, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {ECSPI2_CLK_ROOT, IP_CLOCK_SLICE, 38, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {PWM1_CLK_ROOT, IP_CLOCK_SLICE, 39, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM2_CLK_ROOT, IP_CLOCK_SLICE, 40, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM3_CLK_ROOT, IP_CLOCK_SLICE, 41, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_2, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM4_CLK_ROOT, IP_CLOCK_SLICE, 42, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_2, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {GPT1_CLK_ROOT, IP_CLOCK_SLICE, 43, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1} + }, + {GPT2_CLK_ROOT, IP_CLOCK_SLICE, 44, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2} + }, + {GPT3_CLK_ROOT, IP_CLOCK_SLICE, 45, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3} + }, + {GPT4_CLK_ROOT, IP_CLOCK_SLICE, 46, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1} + }, + {GPT5_CLK_ROOT, IP_CLOCK_SLICE, 47, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2} + }, + {GPT6_CLK_ROOT, IP_CLOCK_SLICE, 48, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3} + }, + {TRACE_CLK_ROOT, IP_CLOCK_SLICE, 49, + {OSC_24M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK, + VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_1, EXT_CLK_3} + }, {WDOG_CLK_ROOT, IP_CLOCK_SLICE, 50, {OSC_24M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK, VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_166M_CLK} }, + {WRCLK_CLK_ROOT, IP_CLOCK_SLICE, 51, + {OSC_24M_CLK, SYSTEM_PLL1_40M_CLK, VPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_100M_CLK} + }, + {IPP_DO_CLKO1, IP_CLOCK_SLICE, 52, + {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, OSC_HDMI_CLK, + SYSTEM_PLL1_200M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL2_500M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_80M_CLK} + }, + {IPP_DO_CLKO2, IP_CLOCK_SLICE, 53, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL2_166M_CLK, SYSTEM_PLL3_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, OSC_32K_CLK} + }, + {MIPI_DSI_CORE_CLK_ROOT, IP_CLOCK_SLICE, 54, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {DISPLAY_DSI_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 55, + {OSC_24M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_DSI_DBI_CLK_ROOT, IP_CLOCK_SLICE, 56, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {USDHC3_CLK_ROOT, IP_CLOCK_SLICE, 57, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL1_266M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL1_100M_CLK} + }, + {DISPLAY_CAMERA_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 58, + {OSC_24M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI1_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 59, + {OSC_24M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI2_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 62, + {OSC_24M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI2_ESC_CLK_ROOT, IP_CLOCK_SLICE, 63, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {ECSPI3_CLK_ROOT, IP_CLOCK_SLICE, 67, + {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {PDM_CLK_ROOT, IP_CLOCK_SLICE, 68, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, AUDIO_PLL1_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK}, + }, + {SAI7_CLK_ROOT, IP_CLOCK_SLICE, 70, + {OSC_24M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_HDMI_CLK, EXT_CLK_3, EXT_CLK_4} + }, {DRAM_SEL_CFG, DRAM_SEL_CLOCK_SLICE, 0, {DRAM_PLL1_CLK} }, + {CORE_SEL_CFG, CORE_SEL_CLOCK_SLICE, 0, + {ARM_A53_ALT_CLK, ARM_PLL_CLK} + }, }; #elif defined(CONFIG_IMX8MP) static struct clk_root_map root_array[] = { @@ -580,6 +1325,26 @@ static struct clk_root_map root_array[] = { SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL1_CLK} }, + {MEDIA_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 4, + {OSC_24M_CLK, SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_40M_CLK, + AUDIO_PLL2_CLK, EXT_CLK_1, SYSTEM_PLL2_500M_CLK} + }, + {MEDIA_APB_CLK_ROOT, BUS_CLOCK_SLICE, 5, + {OSC_24M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_40M_CLK, + AUDIO_PLL2_CLK, EXT_CLK_1, SYSTEM_PLL1_133M_CLK} + }, + {HDMI_APB_CLK_ROOT, BUS_CLOCK_SLICE, 6, + {OSC_24M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_40M_CLK, + AUDIO_PLL2_CLK, EXT_CLK_1, SYSTEM_PLL1_133M_CLK} + }, + {HDMI_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 7, + {OSC_24M_CLK, SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_40M_CLK, + AUDIO_PLL2_CLK, EXT_CLK_1, SYSTEM_PLL2_500M_CLK} + }, {NOC_CLK_ROOT, BUS_CLOCK_SLICE, 10, {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_500M_CLK, @@ -605,6 +1370,11 @@ static struct clk_root_map root_array[] = { SYSTEM_PLL1_400M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} }, + {MEDIA_DISP2_CLK_ROOT, AHB_CLOCK_SLICE, 3, + {OSC_24M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, + AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} + }, {DRAM_ALT_CLK_ROOT, IP_CLOCK_SLICE, 0, {OSC_24M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_1000M_CLK, @@ -615,11 +1385,6 @@ static struct clk_root_map root_array[] = { SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} }, - {MEMREPAIR_CLK_ROOT, IP_CLOCK_SLICE, 6, - {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, - SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, - SYSTEM_PLL1_133M_CLK} - }, {I2C5_CLK_ROOT, IP_CLOCK_SLICE, 9, {OSC_24M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, @@ -798,11 +1563,36 @@ static struct clk_root_map root_array[] = { SYSTEM_PLL3_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_100M_CLK} }, + {HDMI_REF_266M_CLK_ROOT, IP_CLOCK_SLICE, 56, + {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL2_333M_CLK, SYSTEM_PLL1_266M_CLK, + SYSTEM_PLL2_200M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + }, {USDHC3_CLK_ROOT, IP_CLOCK_SLICE, 57, {OSC_24M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_266M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL1_100M_CLK} }, + {MEDIA_MIPI_PHY1_REF_CLK_ROOT, IP_CLOCK_SLICE, 59, + {OSC_24M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MEDIA_DISP1_PIX_CLK_ROOT, IP_CLOCK_SLICE, 60, + {OSC_24M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, + AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} + }, + {MEDIA_LDB_CLK_ROOT, IP_CLOCK_SLICE, 62, + {OSC_24M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MEMREPAIR_CLK_ROOT, IP_CLOCK_SLICE, 63, + {OSC_24M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} + }, {ECSPI3_CLK_ROOT, IP_CLOCK_SLICE, 67, {OSC_24M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, @@ -812,7 +1602,7 @@ static struct clk_root_map root_array[] = { {DRAM_PLL1_CLK} }, {CORE_SEL_CFG, CORE_SEL_CLOCK_SLICE, 0, - {DRAM_PLL1_CLK} + {ARM_A53_ALT_CLK, ARM_PLL_CLK} }, }; #endif From patchwork Wed Apr 22 13:52:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238309 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:22 +0800 Subject: [PATCH 11/24] imx8mq: Enable eMMC HS400 and SD UHS mode on EVK In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-11-peng.fan@nxp.com> From: Ye Li iMX8MQ EVK board has a eMMC5.0 chip and supports SD3.0, so enable the UHS and HS400 configs to enhance the eMMC/SD access. The change also needs to set usdhc clock to 400Mhz, and add the off-on-delay-us to SD reset pin, otherwise some SD cards will fail to select UHS mode in re-initialization. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/clock_imx8mq.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mq.c b/arch/arm/mach-imx/imx8m/clock_imx8mq.c index aad9cf13ef..76104e4f92 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mq.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mq.c @@ -428,15 +428,13 @@ void init_clk_usdhc(u32 index) case 0: clock_enable(CCGR_USDHC1, 0); clock_set_target_val(USDHC1_CLK_ROOT, CLK_ROOT_ON | - CLK_ROOT_SOURCE_SEL(1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2)); + CLK_ROOT_SOURCE_SEL(1)); clock_enable(CCGR_USDHC1, 1); return; case 1: clock_enable(CCGR_USDHC2, 0); clock_set_target_val(USDHC2_CLK_ROOT, CLK_ROOT_ON | - CLK_ROOT_SOURCE_SEL(1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2)); + CLK_ROOT_SOURCE_SEL(1)); clock_enable(CCGR_USDHC2, 1); return; default: From patchwork Wed Apr 22 13:52:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238311 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:23 +0800 Subject: [PATCH 12/24] imx8mq: Set ARM core clock directly from ARM PLL In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-12-peng.fan@nxp.com> For ARM core clock, there are two input branches, and can select via mux: one from ARM PLL directly, second from CCM A53 clock root. Currently we are using second branch. But IC confirmed the CCM A53 root signoff timing is 1Ghz, so we should switch to input from ARM PLL directly. This patch fixes the CORE SEL slice configuration and switch ARM clock to ARM PLL. Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8m/clock_imx8mq.h | 3 +- arch/arm/mach-imx/imx8m/clock_imx8mq.c | 49 +++++++++++++++++--------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/arch/arm/include/asm/arch-imx8m/clock_imx8mq.h b/arch/arm/include/asm/arch-imx8m/clock_imx8mq.h index 38a6f5966b..9dda6ddc8c 100644 --- a/arch/arm/include/asm/arch-imx8m/clock_imx8mq.h +++ b/arch/arm/include/asm/arch-imx8m/clock_imx8mq.h @@ -153,6 +153,7 @@ enum clk_root_src { EXT_CLK_3, EXT_CLK_4, OSC_27M_CLK, + ARM_A53_ALT_CLK, }; /* CCGR index */ @@ -419,7 +420,7 @@ enum clk_src_index { enum frac_pll_out_val { FRAC_PLL_OUT_1000M, - FRAC_PLL_OUT_1600M, + FRAC_PLL_OUT_800M, }; void init_nand_clk(void); diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mq.c b/arch/arm/mach-imx/imx8m/clock_imx8mq.c index 76104e4f92..fb85a8d06e 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mq.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mq.c @@ -15,6 +15,8 @@ static struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR; +static u32 get_root_clk(enum clk_root_index clock_id); + static u32 decode_frac_pll(enum clk_root_src frac_pll) { u32 pll_cfg0, pll_cfg1, pllout; @@ -275,6 +277,8 @@ static u32 get_root_src_clk(enum clk_root_src root_src) case SYSTEM_PLL2_50M_CLK: case SYSTEM_PLL3_CLK: return decode_sscg_pll(root_src); + case ARM_A53_ALT_CLK: + return get_root_clk(ARM_A53_CLK_ROOT); default: return 0; } @@ -322,13 +326,26 @@ int enable_i2c_clk(unsigned char enable, unsigned int i2c_num) return 0; } +u32 get_arm_core_clk(void) +{ + enum clk_root_src root_src; + u32 root_src_clk; + + if (clock_get_src(CORE_SEL_CFG, &root_src) < 0) + return 0; + + root_src_clk = get_root_src_clk(root_src); + + return root_src_clk; +} + unsigned int mxc_get_clock(enum mxc_clock clk) { u32 val; - switch(clk) { + switch (clk) { case MXC_ARM_CLK: - return get_root_clk(ARM_A53_CLK_ROOT); + return get_arm_core_clk(); case MXC_IPG_CLK: clock_get_target_val(IPG_CLK_ROOT, &val); val = val & 0x3; @@ -637,7 +654,7 @@ void dram_pll_init(ulong pll_val) static int frac_pll_init(u32 pll, enum frac_pll_out_val val) { void __iomem *pll_cfg0, __iomem *pll_cfg1; - u32 val_cfg0, val_cfg1; + u32 val_cfg0, val_cfg1, divq; int ret; switch (pll) { @@ -645,14 +662,17 @@ static int frac_pll_init(u32 pll, enum frac_pll_out_val val) pll_cfg0 = &ana_pll->arm_pll_cfg0; pll_cfg1 = &ana_pll->arm_pll_cfg1; - if (val == FRAC_PLL_OUT_1000M) + if (val == FRAC_PLL_OUT_1000M) { val_cfg1 = FRAC_PLL_INT_DIV_CTL_VAL(49); - else + divq = 0; + } else { val_cfg1 = FRAC_PLL_INT_DIV_CTL_VAL(79); + divq = 1; + } val_cfg0 = FRAC_PLL_CLKE_MASK | FRAC_PLL_REFCLK_SEL_OSC_25M | FRAC_PLL_LOCK_SEL_MASK | FRAC_PLL_NEWDIV_VAL_MASK | FRAC_PLL_REFCLK_DIV_VAL(4) | - FRAC_PLL_OUTPUT_DIV_VAL(0); + FRAC_PLL_OUTPUT_DIV_VAL(divq); break; default: return -EINVAL; @@ -688,17 +708,14 @@ int clock_init(void) * We set ARM clock to 1Ghz for consumer, 800Mhz for industrial */ grade = get_cpu_temp_grade(NULL, NULL); - if (!grade) { + if (!grade) frac_pll_init(ANATOP_ARM_PLL, FRAC_PLL_OUT_1000M); - clock_set_target_val(ARM_A53_CLK_ROOT, CLK_ROOT_ON | - CLK_ROOT_SOURCE_SEL(1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1)); - } else { - frac_pll_init(ANATOP_ARM_PLL, FRAC_PLL_OUT_1600M); - clock_set_target_val(ARM_A53_CLK_ROOT, CLK_ROOT_ON | - CLK_ROOT_SOURCE_SEL(1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2)); - } + else + frac_pll_init(ANATOP_ARM_PLL, FRAC_PLL_OUT_800M); + + /* Bypass CCM A53 ROOT, Switch to ARM PLL -> MUX-> CPU */ + clock_set_target_val(CORE_SEL_CFG, CLK_ROOT_SOURCE_SEL(1)); + /* * According to ANAMIX SPEC * sys pll1 fixed at 800MHz From patchwork Wed Apr 22 13:52:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238310 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:24 +0800 Subject: [PATCH 13/24] imx8m: Dump DRAM PLL rate by clocks command In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-13-peng.fan@nxp.com> From: Ye Li Add the dump of DRAM PLL into "clocks" command Reviewed-by: Peng Fan Signed-off-by: Ye Li --- arch/arm/mach-imx/imx8m/clock_imx8mq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mq.c b/arch/arm/mach-imx/imx8m/clock_imx8mq.c index fb85a8d06e..ee18cdee50 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mq.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mq.c @@ -762,6 +762,8 @@ static int do_imx8m_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, freq = decode_frac_pll(ARM_PLL_CLK); printf("ARM_PLL %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(DRAM_PLL1_CLK); + printf("DRAM_PLL %8d MHz\n", freq / 1000000); freq = decode_sscg_pll(SYSTEM_PLL1_800M_CLK); printf("SYS_PLL1_800 %8d MHz\n", freq / 1000000); freq = decode_sscg_pll(SYSTEM_PLL1_400M_CLK); From patchwork Wed Apr 22 13:52:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238314 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:25 +0800 Subject: [PATCH 14/24] imx8: parser: fix 'end address' parameter of rm_find_memreg In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-14-peng.fan@nxp.com> parameter 'end address' must be inclusive of address range. Modified from Seb's downstream patch. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/parse-container.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/imx8/parse-container.c b/arch/arm/mach-imx/imx8/parse-container.c index b57e68e412..e192b0c6d2 100644 --- a/arch/arm/mach-imx/imx8/parse-container.c +++ b/arch/arm/mach-imx/imx8/parse-container.c @@ -29,7 +29,7 @@ static int authenticate_image(struct boot_img_t *img, int image_index) /* Find the memreg and set permission for seco pt */ err = sc_rm_find_memreg(-1, &mr, img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), - ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE)); + ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1); if (err) { printf("can't find memreg for image: %d, err %d\n", From patchwork Wed Apr 22 13:52:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238312 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:26 +0800 Subject: [PATCH 15/24] imx8: Change to use new SECO API commands In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-15-peng.fan@nxp.com> From: Ye Li Latest SCFW has removed old MISC SECO commands. So update the codes to use new SECO commands. Signed-off-by: Ye Li Reviewed-by: Peng Fan --- arch/arm/mach-imx/imx8/ahab.c | 6 +++--- arch/arm/mach-imx/imx8/parse-container.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c index cf3c7d762a..361c578efc 100644 --- a/arch/arm/mach-imx/imx8/ahab.c +++ b/arch/arm/mach-imx/imx8/ahab.c @@ -75,7 +75,7 @@ int authenticate_os_container(ulong addr) memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)addr, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); - err = sc_seco_authenticate(-1, SC_MISC_AUTH_CONTAINER, + err = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER, SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); if (err) { printf("Authenticate container hdr failed, return %d\n", @@ -123,7 +123,7 @@ int authenticate_os_container(ulong addr) goto exit; } - err = sc_seco_authenticate(-1, SC_MISC_VERIFY_IMAGE, + err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE, (1 << i)); if (err) { printf("Authenticate img %d failed, return %d\n", @@ -144,7 +144,7 @@ int authenticate_os_container(ulong addr) } exit: - if (sc_seco_authenticate(-1, SC_MISC_REL_CONTAINER, 0) != SC_ERR_NONE) + if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0) != SC_ERR_NONE) printf("Error: release container failed!\n"); return ret; diff --git a/arch/arm/mach-imx/imx8/parse-container.c b/arch/arm/mach-imx/imx8/parse-container.c index e192b0c6d2..62e5b45610 100644 --- a/arch/arm/mach-imx/imx8/parse-container.c +++ b/arch/arm/mach-imx/imx8/parse-container.c @@ -49,7 +49,7 @@ static int authenticate_image(struct boot_img_t *img, int image_index) return -EPERM; } - err = sc_seco_authenticate(-1, SC_MISC_VERIFY_IMAGE, + err = sc_seco_authenticate(-1, SC_SECO_VERIFY_IMAGE, 1 << image_index); if (err) { printf("authenticate img %d failed, return %d\n", @@ -168,7 +168,7 @@ static int read_auth_container(struct spl_image_info *spl_image, memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container, ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); - ret = sc_seco_authenticate(-1, SC_MISC_AUTH_CONTAINER, + ret = sc_seco_authenticate(-1, SC_SECO_AUTH_CONTAINER, SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); if (ret) { printf("authenticate container hdr failed, return %d\n", ret); @@ -194,7 +194,7 @@ static int read_auth_container(struct spl_image_info *spl_image, end_auth: #ifdef CONFIG_AHAB_BOOT - if (sc_seco_authenticate(-1, SC_MISC_REL_CONTAINER, 0)) + if (sc_seco_authenticate(-1, SC_SECO_REL_CONTAINER, 0)) printf("Error: release container failed!\n"); #endif return ret; From patchwork Wed Apr 22 13:52:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238315 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:27 +0800 Subject: [PATCH 16/24] imx8: ahab: fix 'end address' parameter of rm_find_memreg In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-16-peng.fan@nxp.com> parameter 'end address' must be inclusive of address range. Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/ahab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c index 361c578efc..89544b3dc6 100644 --- a/arch/arm/mach-imx/imx8/ahab.c +++ b/arch/arm/mach-imx/imx8/ahab.c @@ -97,7 +97,7 @@ int authenticate_os_container(ulong addr) img->size); s = img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1); - e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE); + e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1; flush_dcache_range(s, e); From patchwork Wed Apr 22 13:52:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238316 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:28 +0800 Subject: [PATCH 17/24] imx8: ahab: fix some bad debug message formating In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-17-peng.fan@nxp.com> From: Seb Fagard In SPL build, the formatting '%llx' in debug() is not supported. Also, fix some misplaced parameters in printf. Reviewed-by: Ye Li Signed-off-by: Seb Fagard Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/ahab.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c index 89544b3dc6..6d25abe5ce 100644 --- a/arch/arm/mach-imx/imx8/ahab.c +++ b/arch/arm/mach-imx/imx8/ahab.c @@ -90,8 +90,8 @@ int authenticate_os_container(ulong addr) sizeof(struct container_hdr) + i * sizeof(struct boot_img_t)); - debug("img %d, dst 0x%llx, src 0x%lx, size 0x%x\n", - i, img->dst, img->offset + addr, img->size); + debug("img %d, dst 0x%x, src 0x%x, size 0x%x\n", + i, (uint32_t) img->dst, img->offset + addr, img->size); memcpy((void *)img->dst, (const void *)(img->offset + addr), img->size); @@ -104,8 +104,7 @@ int authenticate_os_container(ulong addr) /* Find the memreg and set permission for seco pt */ err = sc_rm_find_memreg(-1, &mr, s, e); if (err) { - printf("Not found memreg for image: %d, error %d\n", - i, err); + printf("Error: can't find memreg for image load address 0x%x, error %d\n", img->dst, err); ret = -ENOMEM; goto exit; } From patchwork Wed Apr 22 13:52:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238323 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:29 +0800 Subject: [PATCH 18/24] imx8: parser: fix some bad debug message formating In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-18-peng.fan@nxp.com> In SPL build, the formatting '%llx' in debug() is not supported. Also, fix some misplaced parameters in printf. Modified from Seb Fagard's downstream patch Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8/parse-container.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-imx/imx8/parse-container.c b/arch/arm/mach-imx/imx8/parse-container.c index 62e5b45610..cc8a51ad55 100644 --- a/arch/arm/mach-imx/imx8/parse-container.c +++ b/arch/arm/mach-imx/imx8/parse-container.c @@ -23,8 +23,8 @@ static int authenticate_image(struct boot_img_t *img, int image_index) int err; int ret = 0; - debug("img %d, dst 0x%llx, src 0x%x, size 0x%x\n", - image_index, img->dst, img->offset, img->size); + debug("img %d, dst 0x%x, src 0x%x, size 0x%x\n", + image_index, (uint32_t)img->dst, img->offset, img->size); /* Find the memreg and set permission for seco pt */ err = sc_rm_find_memreg(-1, &mr, @@ -32,14 +32,14 @@ static int authenticate_image(struct boot_img_t *img, int image_index) ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE) - 1); if (err) { - printf("can't find memreg for image: %d, err %d\n", - image_index, err); + printf("can't find memreg for image %d load address 0x%x, error %d\n", + image_index, img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), err); return -ENOMEM; } err = sc_rm_get_memreg_info(-1, mr, &start, &end); if (!err) - debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end); + debug("memreg %u 0x%x -- 0x%x\n", mr, start, end); err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT, SC_RM_PERM_FULL); From patchwork Wed Apr 22 13:52:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238324 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:30 +0800 Subject: [PATCH 19/24] imx8mm: clock: fix fracpll decode issue In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-19-peng.fan@nxp.com> From: Ye Li The fracpll decoding is using the bit definitions for int pll. Most of them are same, but the CLKE bit is different. Fix the wrong CLKE_MASK for fracpll and correct all bit definitions in fracpll decoding. Reviewed-by: Peng Fan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8m/clock_imx8mm.h | 2 +- arch/arm/mach-imx/imx8m/clock_imx8mm.c | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h b/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h index 84ed61d21e..140e8bbabd 100644 --- a/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h +++ b/arch/arm/include/asm/arch-imx8m/clock_imx8mm.h @@ -19,7 +19,7 @@ #define LOCK_STATUS BIT(31) #define LOCK_SEL_MASK BIT(29) -#define CLKE_MASK BIT(11) +#define CLKE_MASK BIT(13) #define RST_MASK BIT(9) #define BYPASS_MASK BIT(4) #define MDIV_SHIFT 12 diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index c423ac0058..8c9a6b8b12 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -447,34 +447,34 @@ static u32 decode_fracpll(enum clk_root_src frac_pll) } /* Only support SYS_XTAL 24M, PAD_CLK not take into consideration */ - if ((pll_gnrl_ctl & INTPLL_REF_CLK_SEL_MASK) != 0) + if ((pll_gnrl_ctl & GENMASK(1, 0)) != 0) return 0; - if ((pll_gnrl_ctl & INTPLL_RST_MASK) == 0) + if ((pll_gnrl_ctl & RST_MASK) == 0) return 0; /* * When BYPASS is equal to 1, PLL enters the bypass mode * regardless of the values of RESETB */ - if (pll_gnrl_ctl & INTPLL_BYPASS_MASK) + if (pll_gnrl_ctl & BYPASS_MASK) return 24000000u; - if (!(pll_gnrl_ctl & INTPLL_LOCK_MASK)) { + if (!(pll_gnrl_ctl & LOCK_STATUS)) { puts("pll not locked\n"); return 0; } - if (!(pll_gnrl_ctl & INTPLL_CLKE_MASK)) + if (!(pll_gnrl_ctl & CLKE_MASK)) return 0; - main_div = (pll_fdiv_ctl0 & INTPLL_MAIN_DIV_MASK) >> - INTPLL_MAIN_DIV_SHIFT; - pre_div = (pll_fdiv_ctl0 & INTPLL_PRE_DIV_MASK) >> - INTPLL_PRE_DIV_SHIFT; - post_div = (pll_fdiv_ctl0 & INTPLL_POST_DIV_MASK) >> - INTPLL_POST_DIV_SHIFT; + main_div = (pll_fdiv_ctl0 & MDIV_MASK) >> + MDIV_SHIFT; + pre_div = (pll_fdiv_ctl0 & PDIV_MASK) >> + PDIV_SHIFT; + post_div = (pll_fdiv_ctl0 & SDIV_MASK) >> + SDIV_SHIFT; - k = pll_fdiv_ctl1 & GENMASK(15, 0); + k = pll_fdiv_ctl1 & KDIV_MASK; return lldiv((main_div * 65536 + k) * 24000000ULL, 65536 * pre_div * (1 << post_div)); From patchwork Wed Apr 22 13:52:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238317 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:31 +0800 Subject: [PATCH 20/24] imx8m: Enable WDOG_B for timeout In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-20-peng.fan@nxp.com> From: Ye Li When doing reset_cpu, in normal case the WDOG_B outputs immediately after we clean WDA bit. But on mscale, the WDOG_B may be later than internal reset, and cause PMIC not reset. As we enabled the SD3.0 support, the PMIC must be reset to reset SD card. Change the reset_cpu to enable the WDOG_B for timeout as well, and set WDOG timeout to 1s. Acked-by: Peng Fan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/mach-imx/imx8m/soc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 8b6be7bc19..f10b71c345 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -410,19 +410,19 @@ int ft_system_setup(void *blob, bd_t *bd) #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_SYSRESET) void reset_cpu(ulong addr) { - struct watchdog_regs *wdog = (struct watchdog_regs *)addr; + struct watchdog_regs *wdog = (struct watchdog_regs *)addr; - if (!addr) - wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; + if (!addr) + wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; - /* Clear WDA to trigger WDOG_B immediately */ - writew((WCR_WDE | WCR_SRS), &wdog->wcr); + /* Clear WDA to trigger WDOG_B immediately */ + writew((SET_WCR_WT(1) | WCR_WDT | WCR_WDE | WCR_SRS), &wdog->wcr); - while (1) { - /* - * spin for .5 seconds before reset - */ - } + while (1) { + /* + * spin for 1 second before timeout reset + */ + } } #endif From patchwork Wed Apr 22 13:52:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238318 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:32 +0800 Subject: [PATCH 21/24] doc: ahab: Add encrypted boot documentation for i.MX8/8x devices In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-21-peng.fan@nxp.com> From: Breno Lima Add AHAB encrypted boot documentation for i.MX8/8x family devices covering the following topics: - How to encrypt and sign the 2nd container in flash.bin image. - How to encrypt and sign a standalone container image. Include a CSF example to encrypt 2nd container in flash.bin image. Signed-off-by: Catia Han Signed-off-by: Breno Lima Signed-off-by: Peng Fan --- doc/imx/ahab/csf_examples/csf_enc_boot_image.txt | 27 +++ doc/imx/ahab/guides/mx8_mx8x_encrypted_boot.txt | 293 +++++++++++++++++++++++ 2 files changed, 320 insertions(+) create mode 100644 doc/imx/ahab/csf_examples/csf_enc_boot_image.txt create mode 100644 doc/imx/ahab/guides/mx8_mx8x_encrypted_boot.txt diff --git a/doc/imx/ahab/csf_examples/csf_enc_boot_image.txt b/doc/imx/ahab/csf_examples/csf_enc_boot_image.txt new file mode 100644 index 0000000000..6c70db657b --- /dev/null +++ b/doc/imx/ahab/csf_examples/csf_enc_boot_image.txt @@ -0,0 +1,27 @@ +[Header] +Target = AHAB +Version = 1.0 + +[Install SRK] +# SRK table generated by srktool +File = "./release/crts/SRK_1_2_3_4_table.bin" +# Public key certificate in PEM format +Source = "./release/crts/SRK1_sha384_secp384r1_v3_usr_crt.pem" +# Index of the public key certificate within the SRK table (0 .. 3) +Source index = 0 +# Type of SRK set (NXP or OEM) +Source set = OEM +# bitmask of the revoked SRKs +Revocations = 0x0 + +[Authenticate Data] +# Binary to be signed generated by mkimage +File = "flash.bin" +# Offsets = Container header Signature block (printed out by mkimage) +Offsets = 0x400 0x590 + +[Install Secret Key] +Key = "dek.bin" +Key Length = 128 +#Key Identifier = 0x1234CAFE +Image Indexes = 0xFFFFFFFE diff --git a/doc/imx/ahab/guides/mx8_mx8x_encrypted_boot.txt b/doc/imx/ahab/guides/mx8_mx8x_encrypted_boot.txt new file mode 100644 index 0000000000..dfea4c8277 --- /dev/null +++ b/doc/imx/ahab/guides/mx8_mx8x_encrypted_boot.txt @@ -0,0 +1,293 @@ + +=========================================================+ + + i.MX 8, i.MX 8X Encrypted Boot guide using AHAB + + +=========================================================+ + +1. AHAB Encrypted Boot process +------------------------------- + +This document describes a step-by-step procedure on how to encrypt and sign a +bootloader image for i.MX8/8x family devices. It is assumed that the reader +is familiar with basic AHAB concepts and has already closed the device, +step-by-step procedure can be found in mx8_mx8x_secure_boot.txt and +mx8_mx8x_spl_secure_boot.txt guides. + +The steps described in this document were based in i.MX8QM device, the same +concept can be applied to others processors in i.MX8/8X family devices. + +1.1 Understanding the encrypted image signature block +------------------------------------------------------ + +As described in mx8_mx8x_secure_boot.txt guide a single binary is used to boot +the device. The imx-mkimage tool combines all the input images in a container +structure, generating a flash.bin binary. + +AHAB is able to decrypt image containers by calling SECO authentication +functions, the image must be encrypted by CST and the resulting DEK (Data +Encryption Key) must be encapsulated and included into the container signature +block: + + +----------------------------+ + | | ^ + | | | + | Container header | | + | | | + | | | + +---+------------------------+ | + | S | Signature block header | | Signed + | i +------------------------+ | + | g | | | + | n | | | + | a | SRK table | | + | t | | | + | u | | v + | r +------------------------+ + | e | Signature | + | +------------------------+ + | B | | + | l | SGK Key | + | o | Certificate (optional) | + | c | | + | k +------------------------+ + | | DEK Blob | + +---+------------------------+ + +1.1.1 Understanding and generating the DEK blob +------------------------------------------------ + +The encrypted boot image requires a DEK blob on each time AHAB is used to +decrypt an image. The DEK blob is used as a security layer to wrap and store +the DEK off-chip using the OTPMK which is unique per device. + +On i.MX8/8x devices the DEK blob is generated using the SECO API, the following +funtion is available in U-Boot and can be executed through dek_blob command: + +- sc_seco_gen_key_blob(sc_ipc_t ipc, uint32_t id, sc_faddr_t load_addr, + sc_faddr_t export_addr, uint16_t max_size) + +Details in API usage can be found in SCFW API guide [1]. + +1.2 Enabling the encrypted boot support in U-Boot +-------------------------------------------------- + +For deploying an encrypted boot image additional U-Boot tools are needed, +please be sure to have the following features enabled, this can be achieved +by following one of the methods below: + +- Defconfig: + + CONFIG_AHAB_BOOT=y + CONFIG_CMD_DEKBLOB=y + CONFIG_IMX_SECO_DEK_ENCAP=y + CONFIG_FAT_WRITE=y + +- Kconfig: + + ARM architecture -> Support i.MX8 AHAB features + ARM architecture -> Support the 'dek_blob' command + File systems -> Enable FAT filesystem support-> Enable FAT filesystem + write support + +1.3 Enabling the encrypted boot support in CST +----------------------------------------------- + +The encryption feature is not enabled by default in Code Signing tools (CST). +The CST backend must be recompiled, execute the following commands to enable +encryption support in CST: + + $ sudo apt-get install libssl-dev openssl + $ cd /code/back_end/src + $ gcc -o cst_encrypted -I ../hdr -L ../../../linux64/lib *.c + -lfrontend -lcrypto + $ cp cst_encrypted ../../../linux64/bin/ + +1.4 Preparing the image container +---------------------------------- + +The container generation is explained in and mx8_mx8x_secure_boot.txt and +mx8_mx8x_spl_secure_boot.txt guides. This document is based in imx-mkimage +flash target (2 containers in flash.bin). + +- Assembly flash.bin binary: + + $ make SOC= flash + +The mkimage log is used during the encrypted boot procedure to create the +Command Sequence File (CSF): + + CST: CONTAINER 0 offset: 0x400 + CST: CONTAINER 0: Signature Block: offset is at 0x590 + DONE. + Note: Please copy image to offset: IVT_OFFSET + IMAGE_OFFSET + +1.6 Creating the CSF description to encrypt the 2nd container +-------------------------------------------------------------- + +The csf_enc_boot_image.txt available under ahab/csf_examples/ can be used as +example for encrypting the flash.bin binary, the main change is the Install +Secret Key command that must be added after Authenticate Data command. + + [Install Secret Key] + Key = "dek.bin" + Key Length = 128 + #Key Identifier = 0x1234CAFE + Image Indexes = 0xFFFFFFFE + +By default all images are encrypted and image indexes parameter can be used +to mask the images indexes that must be encrypted, on this example only the +2nd container will be encrypted. + +Optionally users can provide a key identifier that must match the value +provided during the blob generation, by default its value is zero. + +1.7 Encrypting the 2nd container +--------------------------------- + +The image is encrypted using the Code Signing Tool. The tool generates the +encrypted image and a random dek.bin file. + +- Encrypt flash.bin binary: + + $ ./cst_encrypted -i csf_enc_boot_image.txt -o enc_flash.bin + The DEK BLOB must be inserted at offset 0x7c0 (its expected size is 72 bytes) + CSF Processed successfully and signed image available in enc_boot_image.bin + +The output log will be used in a later step to insert the DEK blob into the +signature block. + +1.8 Generating the DEK Blob +---------------------------- + +The DEK must be encapsulated into a CAAM blob so it can be included into the +final encrypted binary. The U-Boot provides a tool called dek_blob which is +calling the SECO blob encapsulation API. + +Copy the dek.bin in SDCard FAT partition and run the following commands from +U-Boot prompt: + + => mmc list + FSL_SDHC: 1 (SD) + FSL_SDHC: 2 + => fatload mmc 1:1 0x80280000 dek.bin + => dek_blob 0x80280000 0x80280100 128 + => fatwrite mmc 1:1 0x80280100 dek_blob.bin 0x48 + +In host PC copy the generated dek_blob.bin to the CST directory. + +1.9 Assembling the encrypted image +----------------------------------- + +The DEK blob generated in the step above have to be inserted into the container +signature block. + +The CSF log is used to determine the DEK Blob offset: + + The DEK BLOB must be inserted at offset 0x7c0 (its expected size is 72 bytes) + CSF Processed successfully and signed image available in enc_boot_image.bin + +- Insert DEK Blob into container signature block: + + $ dd if=dek_blob.bin of=enc_flash.bin bs=1 seek=$((0x7c0)) conv=notrunc + +1.10 Flashing the encrypted boot image +--------------------------------------- + +The same offset is used for encrypted boot images, in case booting from +eMMC/SDCard the offset is 32K. + +- Flash encrypted image in SDCard: + + $ sudo dd if=enc_flash.bin of=/dev/sd bs=1K seek=32 && sync + +2.0 Encrypting a standalone container +-------------------------------------- + +CST is also able to encrypt additional images containers, the steps documented +in this section are based in OS container but can be also applied to SPL +targets and 3rd containers. + +2.1 Creating the OS container +------------------------------ + +As explained in mx8_mx8x_secure_boot.txt guide the imx-mkimage tool is used to +generate an image container for OS images, the mkimage log is used during the +encrypted boot procedure to create the Command Sequence File (CSF). + +- Creating OS container: + + $ make SOC= flash_kernel + ... + CST: CONTAINER 0 offset: 0x0 + CST: CONTAINER 0: Signature Block: offset is at 0x110 + +2.2 Creating the CSF description file for standalone container +--------------------------------------------------------------- + +The Image Indexes parameter is used to mask the images that are encrypted by +CST, as a single container is used for OS images the Image Indexes command can +be commented or set to 0xFFFFFFFF. + + [Install Secret Key] + Key = "dek_os.bin" + Key Length = 128 + #Key Identifier = 0x1234CAFE + Image Indexes = 0xFFFFFFFF + +2.3 Encrypting the standalone container +---------------------------------------- + +As explained in section 1.7 the CST generates the encrypted image and a random +dek.bin file. + +- Encrypt the standalone container: + + $ ./cst_encrypted -i csf_linux_img.txt -o enc_flash_os.bin + The DEK BLOB must be inserted at offset 0x340 (its expected size is 72 bytes) + CSF Processed successfully and signed image available in enc_flash_os.bin + +The output log will be used in a later step to insert the DEK blob into the +signature block. + +2.4 Generating the DEK Blob for standalone container +---------------------------------------------------- + +Similar to section 1.8 the DEK must be encapsulated into a CAAM blob so it can +be included into the final encrypted binary. + +Copy the dek_os.bin in SDCard FAT partition and run the following commands from +U-Boot prompt: + + => mmc list + FSL_SDHC: 1 (SD) + FSL_SDHC: 2 + => fatload mmc 1:1 0x80280000 dek_os.bin + => dek_blob 0x80280000 0x80280100 128 + => fatwrite mmc 1:1 0x80280100 dek_blob_os.bin 0x48 + +In host PC copy the generated dek_blob_os.bin to the CST directory. + +2.5 Assembling the encrypted image +----------------------------------- + +The DEK blob generated in the step above have to be inserted into the container +signature block. + +The CSF log is used to determine the DEK Blob offset: + + The DEK BLOB must be inserted at offset 0x340 (its expected size is 72 bytes) + CSF Processed successfully and signed image available in enc_flash_os.bin + +- Insert DEK Blob into container signature block: + + $ dd if=dek_blob_os.bin of=enc_flash_os.bin bs=1 seek=$((0x340)) conv=notrunc + +2.6 Copy encrypted image to SDCard +----------------------------------- + +The encrypted container can be copied to SDCard FAT partition, please note +that U-Boot requires signed and encrypted containers to be named as +os_cntr_signed.bin. + + $ sudo cp enc_flash_os.bin /media/UserID/Boot\ imx8/os_cntr_signed.bin + +References: +[1] SCFW API guide: "System Controller Firmware API Reference Guide - Rev 1.5" From patchwork Wed Apr 22 13:52:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238319 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:33 +0800 Subject: [PATCH 22/24] imx8: scu api: Add support for SECO manufacturing protection APIs In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-22-peng.fan@nxp.com> From: Breno Lima SECO provides APIs to support CAAM manufacturing protection: - sc_seco_get_mp_key() - sc_seco_get_mp_sign() - sc_seco_update_mpmr() Add SCFW APIs support. Signed-off-by: Breno Lima Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8/sci/sci.h | 4 ++ drivers/misc/imx8/scu_api.c | 80 ++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h b/arch/arm/include/asm/arch-imx8/sci/sci.h index 14ee6f999b..ac65f199b8 100644 --- a/arch/arm/include/asm/arch-imx8/sci/sci.h +++ b/arch/arm/include/asm/arch-imx8/sci/sci.h @@ -122,5 +122,9 @@ void sc_seco_build_info(sc_ipc_t ipc, u32 *version, u32 *commit); int sc_seco_get_event(sc_ipc_t ipc, u8 idx, u32 *event); int sc_seco_gen_key_blob(sc_ipc_t ipc, u32 id, sc_faddr_t load_addr, sc_faddr_t export_addr, u16 max_size); +int sc_seco_get_mp_key(sc_ipc_t ipc, sc_faddr_t dst_addr, u16 dst_size); +int sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr, u8 size, u8 lock); +int sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr, + u16 msg_size, sc_faddr_t dst_addr, u16 dst_size); #endif diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index 3ad21c1ea0..c1e54fc4bc 100644 --- a/drivers/misc/imx8/scu_api.c +++ b/drivers/misc/imx8/scu_api.c @@ -948,3 +948,83 @@ int sc_seco_gen_key_blob(sc_ipc_t ipc, u32 id, sc_faddr_t load_addr, return ret; } + +int sc_seco_get_mp_key(sc_ipc_t ipc, sc_faddr_t dst_addr, + u16 dst_size) +{ + struct udevice *dev = gd->arch.scu_dev; + struct sc_rpc_msg_s msg; + int size = sizeof(struct sc_rpc_msg_s); + int ret; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 4U; + RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO); + RPC_FUNC(&msg) = (u8)(SECO_FUNC_GET_MP_KEY); + + RPC_U32(&msg, 0U) = (u32)(dst_addr >> 32ULL); + RPC_U32(&msg, 4U) = (u32)(dst_addr); + RPC_U16(&msg, 8U) = (u16)(dst_size); + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret) + printf("%s, dst_addr:0x%llx, res:%d\n", + __func__, dst_addr, RPC_R8(&msg)); + + return ret; +} + +int sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr, uint8_t size_m, + uint8_t lock) +{ + struct udevice *dev = gd->arch.scu_dev; + struct sc_rpc_msg_s msg; + int size = sizeof(struct sc_rpc_msg_s); + int ret; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 4U; + RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO); + RPC_FUNC(&msg) = (u8)(SECO_FUNC_UPDATE_MPMR); + + RPC_U32(&msg, 0U) = (u32)(addr >> 32ULL); + RPC_U32(&msg, 4U) = (u32)(addr); + RPC_U8(&msg, 8U) = (u8)(size_m); + RPC_U8(&msg, 9U) = (u8)(lock); + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret) + printf("%s, addr:0x%llx, size_m:%x, lock:0x%x, res:%d\n", + __func__, addr, size_m, lock, RPC_R8(&msg)); + return ret; +} + +int sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr, + u16 msg_size, sc_faddr_t dst_addr, + u16 dst_size) +{ + struct udevice *dev = gd->arch.scu_dev; + struct sc_rpc_msg_s msg; + int size = sizeof(struct sc_rpc_msg_s); + int ret; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 6U; + RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO); + RPC_FUNC(&msg) = (u8)(SECO_FUNC_GET_MP_SIGN); + + RPC_U32(&msg, 0U) = (u32)(msg_addr >> 32ULL); + RPC_U32(&msg, 4U) = (u32)(msg_addr); + RPC_U32(&msg, 8U) = (u32)(dst_addr >> 32ULL); + RPC_U32(&msg, 12U) = (u32)(dst_addr); + RPC_U16(&msg, 16U) = (u16)(msg_size); + RPC_U16(&msg, 18U) = (u16)(dst_size); + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret) + printf("%s, msg_addr:0x%llx, msg_size:%x, dst_addr:0x%llx," + "dst_size:%x, res:%d\n", __func__, msg_addr, msg_size, + dst_addr, dst_size, RPC_R8(&msg)); + + return ret; +} From patchwork Wed Apr 22 13:52:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238320 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:34 +0800 Subject: [PATCH 23/24] imx8: Update SCFW API to version 1.5 In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-23-peng.fan@nxp.com> From: Ye Li Sync the latest SCFW API with below commit 6dcd0242ae7a53ac ("SCF-105: Revert accidental change") to add interfaces for PM resource reset and read/write SNVS security violation and tamper DGO registers. Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8/sci/rpc.h | 86 ++++++++++++++++++------ arch/arm/include/asm/arch-imx8/sci/sci.h | 2 + arch/arm/include/asm/arch-imx8/sci/svc/pad/api.h | 3 + arch/arm/include/asm/arch-imx8/sci/types.h | 6 ++ drivers/misc/imx8/scu_api.c | 50 ++++++++++++++ 5 files changed, 126 insertions(+), 21 deletions(-) diff --git a/arch/arm/include/asm/arch-imx8/sci/rpc.h b/arch/arm/include/asm/arch-imx8/sci/rpc.h index 8e1e9bbf43..c1a9c353ba 100644 --- a/arch/arm/include/asm/arch-imx8/sci/rpc.h +++ b/arch/arm/include/asm/arch-imx8/sci/rpc.h @@ -8,6 +8,11 @@ #define SC_RPC_H /* Note: Check SCFW API Released DOC before you want to modify something */ +/* Defines */ + +#define SCFW_API_VERSION_MAJOR 1U +#define SCFW_API_VERSION_MINOR 15U + #define SC_RPC_VERSION 1U #define SC_RPC_MAX_MSG 8U @@ -17,9 +22,13 @@ #define RPC_SVC(MSG) ((MSG)->svc) #define RPC_FUNC(MSG) ((MSG)->func) #define RPC_R8(MSG) ((MSG)->func) +#define RPC_I64(MSG, IDX) ((s64)(RPC_U32((MSG), (IDX))) << 32ULL) | \ + (s64)(RPC_U32((MSG), (IDX) + 4U)) #define RPC_I32(MSG, IDX) ((MSG)->DATA.i32[(IDX) / 4U]) #define RPC_I16(MSG, IDX) ((MSG)->DATA.i16[(IDX) / 2U]) #define RPC_I8(MSG, IDX) ((MSG)->DATA.i8[(IDX)]) +#define RPC_U64(MSG, IDX) ((u64)(RPC_U32((MSG), (IDX))) << 32ULL) | \ + (u64)(RPC_U32((MSG), (IDX) + 4U)) #define RPC_U32(MSG, IDX) ((MSG)->DATA.u32[(IDX) / 4U]) #define RPC_U16(MSG, IDX) ((MSG)->DATA.u16[(IDX) / 2U]) #define RPC_U8(MSG, IDX) ((MSG)->DATA.u8[(IDX)]) @@ -76,6 +85,8 @@ struct sc_rpc_msg_s { #define PM_FUNC_REBOOT 9U #define PM_FUNC_REBOOT_PARTITION 12U #define PM_FUNC_CPU_START 11U +#define PM_FUNC_CPU_RESET 23U +#define PM_FUNC_RESOURCE_RESET 29U #define PM_FUNC_IS_PARTITION_STARTED 24U /* MISC RPC */ @@ -160,26 +171,59 @@ struct sc_rpc_msg_s { #define RM_FUNC_DUMP 27U /* SECO RPC */ -#define SECO_FUNC_UNKNOWN 0 -#define SECO_FUNC_IMAGE_LOAD 1U -#define SECO_FUNC_AUTHENTICATE 2U -#define SECO_FUNC_FORWARD_LIFECYCLE 3U -#define SECO_FUNC_RETURN_LIFECYCLE 4U -#define SECO_FUNC_COMMIT 5U -#define SECO_FUNC_ATTEST_MODE 6U -#define SECO_FUNC_ATTEST 7U -#define SECO_FUNC_GET_ATTEST_PKEY 8U -#define SECO_FUNC_GET_ATTEST_SIGN 9U -#define SECO_FUNC_ATTEST_VERIFY 10U -#define SECO_FUNC_GEN_KEY_BLOB 11U -#define SECO_FUNC_LOAD_KEY 12U -#define SECO_FUNC_GET_MP_KEY 13U -#define SECO_FUNC_UPDATE_MPMR 14U -#define SECO_FUNC_GET_MP_SIGN 15U -#define SECO_FUNC_BUILD_INFO 16U -#define SECO_FUNC_CHIP_INFO 17U -#define SECO_FUNC_ENABLE_DEBUG 18U -#define SECO_FUNC_GET_EVENT 19U -#define SECO_FUNC_FUSE_WRITE 20U +#define SECO_FUNC_UNKNOWN 0 /* Unknown function */ +#define SECO_FUNC_IMAGE_LOAD 1U /* Index for seco_image_load() RPC call */ +#define SECO_FUNC_AUTHENTICATE 2U /* Index for seco_authenticate() RPC call */ +#define SECO_FUNC_ENH_AUTHENTICATE 24U /* Index for sc_seco_enh_authenticate() RPC call */ +#define SECO_FUNC_FORWARD_LIFECYCLE 3U /* Index for seco_forward_lifecycle() RPC call */ +#define SECO_FUNC_RETURN_LIFECYCLE 4U /* Index for seco_return_lifecycle() RPC call */ +#define SECO_FUNC_COMMIT 5U /* Index for seco_commit() RPC call */ +#define SECO_FUNC_ATTEST_MODE 6U /* Index for seco_attest_mode() RPC call */ +#define SECO_FUNC_ATTEST 7U /* Index for seco_attest() RPC call */ +#define SECO_FUNC_GET_ATTEST_PKEY 8U /* Index for seco_get_attest_pkey() RPC call */ +#define SECO_FUNC_GET_ATTEST_SIGN 9U /* Index for seco_get_attest_sign() RPC call */ +#define SECO_FUNC_ATTEST_VERIFY 10U /* Index for seco_attest_verify() RPC call */ +#define SECO_FUNC_GEN_KEY_BLOB 11U /* Index for seco_gen_key_blob() RPC call */ +#define SECO_FUNC_LOAD_KEY 12U /* Index for seco_load_key() RPC call */ +#define SECO_FUNC_GET_MP_KEY 13U /* Index for seco_get_mp_key() RPC call */ +#define SECO_FUNC_UPDATE_MPMR 14U /* Index for seco_update_mpmr() RPC call */ +#define SECO_FUNC_GET_MP_SIGN 15U /* Index for seco_get_mp_sign() RPC call */ +#define SECO_FUNC_BUILD_INFO 16U /* Index for seco_build_info() RPC call */ +#define SECO_FUNC_CHIP_INFO 17U /* Index for seco_chip_info() RPC call */ +#define SECO_FUNC_ENABLE_DEBUG 18U /* Index for seco_enable_debug() RPC call */ +#define SECO_FUNC_GET_EVENT 19U /* Index for seco_get_event() RPC call */ +#define SECO_FUNC_FUSE_WRITE 20U /* Index for seco_fuse_write() RPC call */ +#define SECO_FUNC_PATCH 21U /* Index for sc_seco_patch() RPC call */ +#define SECO_FUNC_START_RNG 22U /* Index for sc_seco_start_rng() RPC call */ +#define SECO_FUNC_SAB_MSG 23U /* Index for sc_seco_sab_msg() RPC call */ +#define SECO_FUNC_SECVIO_ENABLE 25U /* Index for sc_seco_secvio_enable() RPC call */ +#define SECO_FUNC_SECVIO_CONFIG 26U /* Index for sc_seco_secvio_config() RPC call */ +#define SECO_FUNC_SECVIO_DGO_CONFIG 27U /* Index for sc_seco_secvio_dgo_config() RPC call */ + +/* IRQ RPC */ +#define IRQ_FUNC_UNKNOWN 0 /* Unknown function */ +#define IRQ_FUNC_ENABLE 1U /* Index for sc_irq_enable() RPC call */ +#define IRQ_FUNC_STATUS 2U /* Index for sc_irq_status() RPC call */ + +/* TIMER RPC */ +#define TIMER_FUNC_UNKNOWN 0 /* Unknown function */ +#define TIMER_FUNC_SET_WDOG_TIMEOUT 1U /* Index for sc_timer_set_wdog_timeout() RPC call */ +#define TIMER_FUNC_SET_WDOG_PRE_TIMEOUT 12U /* Index for sc_timer_set_wdog_pre_timeout() RPC call */ +#define TIMER_FUNC_START_WDOG 2U /* Index for sc_timer_start_wdog() RPC call */ +#define TIMER_FUNC_STOP_WDOG 3U /* Index for sc_timer_stop_wdog() RPC call */ +#define TIMER_FUNC_PING_WDOG 4U /* Index for sc_timer_ping_wdog() RPC call */ +#define TIMER_FUNC_GET_WDOG_STATUS 5U /* Index for sc_timer_get_wdog_status() RPC call */ +#define TIMER_FUNC_PT_GET_WDOG_STATUS 13U /* Index for sc_timer_pt_get_wdog_status() RPC call */ +#define TIMER_FUNC_SET_WDOG_ACTION 10U /* Index for sc_timer_set_wdog_action() RPC call */ +#define TIMER_FUNC_SET_RTC_TIME 6U /* Index for sc_timer_set_rtc_time() RPC call */ +#define TIMER_FUNC_GET_RTC_TIME 7U /* Index for sc_timer_get_rtc_time() RPC call */ +#define TIMER_FUNC_GET_RTC_SEC1970 9U /* Index for sc_timer_get_rtc_sec1970() RPC call */ +#define TIMER_FUNC_SET_RTC_ALARM 8U /* Index for sc_timer_set_rtc_alarm() RPC call */ +#define TIMER_FUNC_SET_RTC_PERIODIC_ALARM 14U /* Index for sc_timer_set_rtc_periodic_alarm() RPC call */ +#define TIMER_FUNC_CANCEL_RTC_ALARM 15U /* Index for sc_timer_cancel_rtc_alarm() RPC call */ +#define TIMER_FUNC_SET_RTC_CALB 11U /* Index for sc_timer_set_rtc_calb() RPC call */ +#define TIMER_FUNC_SET_SYSCTR_ALARM 16U /* Index for sc_timer_set_sysctr_alarm() RPC call */ +#define TIMER_FUNC_SET_SYSCTR_PERIODIC_ALARM 17U /* Index for sc_timer_set_sysctr_periodic_alarm() RPC call */ +#define TIMER_FUNC_CANCEL_SYSCTR_ALARM 18U /* Index for sc_timer_cancel_sysctr_alarm() RPC call */ #endif /* SC_RPC_H */ diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h b/arch/arm/include/asm/arch-imx8/sci/sci.h index ac65f199b8..179037ae17 100644 --- a/arch/arm/include/asm/arch-imx8/sci/sci.h +++ b/arch/arm/include/asm/arch-imx8/sci/sci.h @@ -72,6 +72,7 @@ int sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk, int sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable, sc_faddr_t address); sc_bool_t sc_pm_is_partition_started(sc_ipc_t ipc, sc_rm_pt_t pt); +int sc_pm_resource_reset(sc_ipc_t ipc, sc_rsrc_t resource); /* MISC API */ int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource, @@ -126,5 +127,6 @@ int sc_seco_get_mp_key(sc_ipc_t ipc, sc_faddr_t dst_addr, u16 dst_size); int sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr, u8 size, u8 lock); int sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr, u16 msg_size, sc_faddr_t dst_addr, u16 dst_size); +int sc_seco_secvio_dgo_config(sc_ipc_t ipc, u8 id, u8 access, u32 *data); #endif diff --git a/arch/arm/include/asm/arch-imx8/sci/svc/pad/api.h b/arch/arm/include/asm/arch-imx8/sci/svc/pad/api.h index 905c56834e..df368e8c8b 100644 --- a/arch/arm/include/asm/arch-imx8/sci/svc/pad/api.h +++ b/arch/arm/include/asm/arch-imx8/sci/svc/pad/api.h @@ -6,6 +6,9 @@ #ifndef SC_PAD_API_H #define SC_PAD_API_H +/* Defines for type widths */ +#define SC_PAD_MUX_W 3U /* Width of mux parameter */ + /* Defines for sc_pad_config_t */ #define SC_PAD_CONFIG_NORMAL 0U /* Normal */ #define SC_PAD_CONFIG_OD 1U /* Open Drain */ diff --git a/arch/arm/include/asm/arch-imx8/sci/types.h b/arch/arm/include/asm/arch-imx8/sci/types.h index 9eadc88592..adfed13e33 100644 --- a/arch/arm/include/asm/arch-imx8/sci/types.h +++ b/arch/arm/include/asm/arch-imx8/sci/types.h @@ -32,6 +32,7 @@ typedef u64 sc_ipc_t; #define SC_83MHZ 83333333U /* 83MHz */ #define SC_84MHZ 84375000U /* 84.37MHz */ #define SC_100MHZ 100000000U /* 100MHz */ +#define SC_114MHZ 114000000U /* 114MHz */ #define SC_125MHZ 125000000U /* 125MHz */ #define SC_133MHZ 133333333U /* 133MHz */ #define SC_135MHZ 135000000U /* 135MHz */ @@ -52,6 +53,7 @@ typedef u64 sc_ipc_t; #define SC_372MHZ 372000000U /* 372MHz */ #define SC_375MHZ 375000000U /* 375MHz */ #define SC_400MHZ 400000000U /* 400MHz */ +#define SC_465MHZ 465000000U /* 465MHz */ #define SC_500MHZ 500000000U /* 500MHz */ #define SC_594MHZ 594000000U /* 594MHz */ #define SC_625MHZ 625000000U /* 625MHz */ @@ -75,6 +77,7 @@ typedef u64 sc_ipc_t; #define SC_1500MHZ 1500000000U /* 1.5GHz */ #define SC_1600MHZ 1600000000U /* 1.6GHz */ #define SC_1800MHZ 1800000000U /* 1.8GHz */ +#define SC_1860MHZ 1860000000U /* 1.86GHz */ #define SC_2000MHZ 2000000000U /* 2.0GHz */ #define SC_2112MHZ 2112000000U /* 2.12GHz */ @@ -89,6 +92,7 @@ typedef u64 sc_ipc_t; #define SC_144MHZ 144000000U /* 144MHz */ #define SC_192MHZ 192000000U /* 192MHz */ #define SC_211MHZ 211200000U /* 211.2MHz */ +#define SC_228MHZ 228000000U /* 233MHz */ #define SC_240MHZ 240000000U /* 240MHz */ #define SC_264MHZ 264000000U /* 264MHz */ #define SC_352MHZ 352000000U /* 352MHz */ @@ -96,11 +100,13 @@ typedef u64 sc_ipc_t; #define SC_384MHZ 384000000U /* 384MHz */ #define SC_396MHZ 396000000U /* 396MHz */ #define SC_432MHZ 432000000U /* 432MHz */ +#define SC_456MHZ 456000000U /* 466MHz */ #define SC_480MHZ 480000000U /* 480MHz */ #define SC_600MHZ 600000000U /* 600MHz */ #define SC_744MHZ 744000000U /* 744MHz */ #define SC_792MHZ 792000000U /* 792MHz */ #define SC_864MHZ 864000000U /* 864MHz */ +#define SC_912MHZ 912000000U /* 912MHz */ #define SC_960MHZ 960000000U /* 960MHz */ #define SC_1056MHZ 1056000000U /* 1056MHz */ #define SC_1104MHZ 1104000000U /* 1104MHz */ diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index c1e54fc4bc..227bc52873 100644 --- a/drivers/misc/imx8/scu_api.c +++ b/drivers/misc/imx8/scu_api.c @@ -174,6 +174,28 @@ sc_bool_t sc_pm_is_partition_started(sc_ipc_t ipc, sc_rm_pt_t pt) return !!result; } +int sc_pm_resource_reset(sc_ipc_t ipc, sc_rsrc_t resource) +{ + struct udevice *dev = gd->arch.scu_dev; + int size = sizeof(struct sc_rpc_msg_s); + struct sc_rpc_msg_s msg; + int ret; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 2U; + RPC_SVC(&msg) = (u8)(SC_RPC_SVC_PM); + RPC_FUNC(&msg) = (u8)(PM_FUNC_RESOURCE_RESET); + + RPC_U16(&msg, 0U) = (u16)(resource); + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret) + printf("%s: resource:%d res:%d\n", + __func__, resource, RPC_R8(&msg)); + + return ret; +} + /* PAD */ int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val) { @@ -1028,3 +1050,31 @@ int sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr, return ret; } + +int sc_seco_secvio_dgo_config(sc_ipc_t ipc, uint8_t id, uint8_t access, + u32 *data) +{ + struct udevice *dev = gd->arch.scu_dev; + struct sc_rpc_msg_s msg; + int size = sizeof(struct sc_rpc_msg_s); + int ret; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 3U; + RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO); + RPC_FUNC(&msg) = (u8)(SECO_FUNC_SECVIO_DGO_CONFIG); + + RPC_U32(&msg, 0U) = (u32)(*data); + RPC_U8(&msg, 4U) = (u8)(id); + RPC_U8(&msg, 5U) = (u8)(access); + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret) + printf("%s, id:0x%x, access:%x, res:%d\n", + __func__, id, access, RPC_R8(&msg)); + + if (data) + *data = RPC_U32(&msg, 0U); + + return ret; +} From patchwork Wed Apr 22 13:52:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Fan X-Patchwork-Id: 238321 List-Id: U-Boot discussion From: peng.fan at nxp.com (Peng Fan) Date: Wed, 22 Apr 2020 21:52:35 +0800 Subject: [PATCH 24/24] imx8: Configure SNVS In-Reply-To: <20200422135235.14756-1-peng.fan@nxp.com> References: <20200422135235.14756-1-peng.fan@nxp.com> Message-ID: <20200422135235.14756-24-peng.fan@nxp.com> From: Franck LENORMAND Add a module to configure the tamper and secure violation of the SNVS using the SCU API. The module also adds some commands: - snvs_cfg: Configure the SNVS HP and LP registers - snvs_dgo_cfg: Configure the SNVS DGO bloc if present (8QXP) - tamper_pin_cfg: Change the configuration of the tamper pins - snvs_clear_status: Allow to write to LPSR and LPTDSR to clear status bits Signed-off-by: Franck LENORMAND Signed-off-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8/sci/sci.h | 4 + arch/arm/include/asm/arch-imx8/snvs_security_sc.h | 11 + arch/arm/mach-imx/imx8/Kconfig | 13 + arch/arm/mach-imx/imx8/Makefile | 1 + arch/arm/mach-imx/imx8/snvs_security_sc.c | 923 ++++++++++++++++++++++ board/freescale/imx8qxp_mek/imx8qxp_mek.c | 10 + drivers/misc/imx8/scu_api.c | 72 +- 7 files changed, 1030 insertions(+), 4 deletions(-) create mode 100644 arch/arm/include/asm/arch-imx8/snvs_security_sc.h create mode 100644 arch/arm/mach-imx/imx8/snvs_security_sc.c diff --git a/arch/arm/include/asm/arch-imx8/sci/sci.h b/arch/arm/include/asm/arch-imx8/sci/sci.h index 179037ae17..05f736f14f 100644 --- a/arch/arm/include/asm/arch-imx8/sci/sci.h +++ b/arch/arm/include/asm/arch-imx8/sci/sci.h @@ -109,6 +109,7 @@ int sc_rm_get_resource_owner(sc_ipc_t ipc, sc_rsrc_t resource, /* PAD API */ int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val); +int sc_pad_get(sc_ipc_t ipc, sc_pad_t pad, uint32_t *val); /* SMMU API */ int sc_rm_set_master_sid(sc_ipc_t ipc, sc_rsrc_t resource, sc_rm_sid_t sid); @@ -128,5 +129,8 @@ int sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr, u8 size, u8 lock); int sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr, u16 msg_size, sc_faddr_t dst_addr, u16 dst_size); int sc_seco_secvio_dgo_config(sc_ipc_t ipc, u8 id, u8 access, u32 *data); +int sc_seco_secvio_config(sc_ipc_t ipc, u8 id, u8 access, + u32 *data0, u32 *data1, u32 *data2, u32 *data3, + u32 *data4, u8 size); #endif diff --git a/arch/arm/include/asm/arch-imx8/snvs_security_sc.h b/arch/arm/include/asm/arch-imx8/snvs_security_sc.h new file mode 100644 index 0000000000..0b7ded7ba6 --- /dev/null +++ b/arch/arm/include/asm/arch-imx8/snvs_security_sc.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 NXP + */ + +#ifndef _SNVS_SECURITY_SC_H +#define _SNVS_SECURITY_SC_H + +int snvs_security_sc_init(void); + +#endif /* _SNVS_SECURITY_SC_H */ diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index 5827ab334f..1f8add015f 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -90,4 +90,17 @@ source "board/toradex/apalis-imx8/Kconfig" source "board/toradex/colibri-imx8x/Kconfig" source "board/siemens/capricorn/Kconfig" +config IMX_SNVS_SEC_SC + bool "Support SNVS configuration" + help + Allow to configure the SNVS via SCU API to configure tampers and secure + violation. + +config IMX_SNVS_SEC_SC_AUTO + bool "Support SNVS configuration command" + depends on IMX_SNVS_SEC_SC + help + This configuration will apply the selected configurations automatically + at boot. + endif diff --git a/arch/arm/mach-imx/imx8/Makefile b/arch/arm/mach-imx/imx8/Makefile index 7ffb7e95b2..bbb41adbe4 100644 --- a/arch/arm/mach-imx/imx8/Makefile +++ b/arch/arm/mach-imx/imx8/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_AHAB_BOOT) += ahab.o ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_LOAD_IMX_CONTAINER) += image.o parse-container.o endif +obj-$(CONFIG_IMX_SNVS_SEC_SC) += snvs_security_sc.o diff --git a/arch/arm/mach-imx/imx8/snvs_security_sc.c b/arch/arm/mach-imx/imx8/snvs_security_sc.c new file mode 100644 index 0000000000..73f5651161 --- /dev/null +++ b/arch/arm/mach-imx/imx8/snvs_security_sc.c @@ -0,0 +1,923 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019-2020 NXP. + */ + +/* + * Configuration of the Tamper pins in different mode: + * - default (no tamper pins): _default_ + * - passive mode expecting VCC on the line: "_passive_vcc_" + * - passive mode expecting VCC on the line: "_passive_gnd_" + * - active mode: "_active_" + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Access to gd */ +DECLARE_GLOBAL_DATA_PTR; + +#define SC_WRITE_CONF 1 + +#define PGD_HEX_VALUE 0x41736166 +#define SRTC_EN 0x1 +#define DP_EN BIT(5) + +struct snvs_security_sc_conf { + struct snvs_hp_conf { + u32 lock; /* HPLR - HP Lock */ + u32 __cmd; /* HPCOMR - HP Command */ + u32 __ctl; /* HPCR - HP Control */ + u32 secvio_intcfg; /* HPSICR - Security Violation Int + * Config + */ + u32 secvio_ctl; /* HPSVCR - Security Violation Control*/ + u32 status; /* HPSR - HP Status */ + u32 secvio_status; /* HPSVSR - Security Violation Status */ + u32 __ha_counteriv; /* High Assurance Counter IV */ + u32 __ha_counter; /* High Assurance Counter */ + u32 __rtc_msb; /* Real Time Clock/Counter MSB */ + u32 __rtc_lsb; /* Real Time Counter LSB */ + u32 __time_alarm_msb; /* Time Alarm MSB */ + u32 __time_alarm_lsb; /* Time Alarm LSB */ + } hp; + struct snvs_lp_conf { + u32 lock; + u32 __ctl; + u32 __mstr_key_ctl; /* Master Key Control */ + u32 secvio_ctl; /* Security Violation Control */ + u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration*/ + u32 tamper_det_cfg; /* Tamper Detectors Configuration */ + u32 status; + u32 __srtc_msb; /* Secure Real Time Clock/Counter MSB */ + u32 __srtc_lsb; /* Secure Real Time Clock/Counter LSB */ + u32 __time_alarm; /* Time Alarm */ + u32 __smc_msb; /* Secure Monotonic Counter MSB */ + u32 __smc_lsb; /* Secure Monotonic Counter LSB */ + u32 __pwr_glitch_det; /* Power Glitch Detector */ + u32 __gen_purpose; + u8 __zmk[32]; /* Zeroizable Master Key */ + u32 __rsvd0; + u32 __gen_purposes[4]; /* gp0_30 to gp0_33 */ + u32 tamper_det_cfg2; /* Tamper Detectors Configuration2 */ + u32 tamper_det_status; /* Tamper Detectors status */ + u32 tamper_filt1_cfg; /* Tamper Glitch Filter1 Configuration*/ + u32 tamper_filt2_cfg; /* Tamper Glitch Filter2 Configuration*/ + u32 __rsvd1[4]; + u32 act_tamper1_cfg; /* Active Tamper1 Configuration */ + u32 act_tamper2_cfg; /* Active Tamper2 Configuration */ + u32 act_tamper3_cfg; /* Active Tamper3 Configuration */ + u32 act_tamper4_cfg; /* Active Tamper4 Configuration */ + u32 act_tamper5_cfg; /* Active Tamper5 Configuration */ + u32 __rsvd2[3]; + u32 act_tamper_ctl; /* Active Tamper Control */ + u32 act_tamper_clk_ctl; /* Active Tamper Clock Control */ + u32 act_tamper_routing_ctl1;/* Active Tamper Routing Control1 */ + u32 act_tamper_routing_ctl2;/* Active Tamper Routing Control2 */ + } lp; +}; + +static struct snvs_security_sc_conf snvs_default_config = { + .hp = { + .lock = 0x1f0703ff, + .secvio_ctl = 0x3000007f, + }, + .lp = { + .lock = 0x1f0003ff, + .secvio_ctl = 0x36, + .tamper_filt_cfg = 0, + .tamper_det_cfg = 0x76, /* analogic tampers + * + rollover tampers + */ + .tamper_det_cfg2 = 0, + .tamper_filt1_cfg = 0, + .tamper_filt2_cfg = 0, + .act_tamper1_cfg = 0, + .act_tamper2_cfg = 0, + .act_tamper3_cfg = 0, + .act_tamper4_cfg = 0, + .act_tamper5_cfg = 0, + .act_tamper_ctl = 0, + .act_tamper_clk_ctl = 0, + .act_tamper_routing_ctl1 = 0, + .act_tamper_routing_ctl2 = 0, + } +}; + +static struct snvs_security_sc_conf snvs_passive_vcc_config = { + .hp = { + .lock = 0x1f0703ff, + .secvio_ctl = 0x3000007f, + }, + .lp = { + .lock = 0x1f0003ff, + .secvio_ctl = 0x36, + .tamper_filt_cfg = 0, + .tamper_det_cfg = 0x276, /* ET1 will trig on line at GND + * + analogic tampers + * + rollover tampers + */ + .tamper_det_cfg2 = 0, + .tamper_filt1_cfg = 0, + .tamper_filt2_cfg = 0, + .act_tamper1_cfg = 0, + .act_tamper2_cfg = 0, + .act_tamper3_cfg = 0, + .act_tamper4_cfg = 0, + .act_tamper5_cfg = 0, + .act_tamper_ctl = 0, + .act_tamper_clk_ctl = 0, + .act_tamper_routing_ctl1 = 0, + .act_tamper_routing_ctl2 = 0, + } +}; + +static struct snvs_security_sc_conf snvs_passive_gnd_config = { + .hp = { + .lock = 0x1f0703ff, + .secvio_ctl = 0x3000007f, + }, + .lp = { + .lock = 0x1f0003ff, + .secvio_ctl = 0x36, + .tamper_filt_cfg = 0, + .tamper_det_cfg = 0xa76, /* ET1 will trig on line at VCC + * + analogic tampers + * + rollover tampers + */ + .tamper_det_cfg2 = 0, + .tamper_filt1_cfg = 0, + .tamper_filt2_cfg = 0, + .act_tamper1_cfg = 0, + .act_tamper2_cfg = 0, + .act_tamper3_cfg = 0, + .act_tamper4_cfg = 0, + .act_tamper5_cfg = 0, + .act_tamper_ctl = 0, + .act_tamper_clk_ctl = 0, + .act_tamper_routing_ctl1 = 0, + .act_tamper_routing_ctl2 = 0, + } +}; + +static struct snvs_security_sc_conf snvs_active_config = { + .hp = { + .lock = 0x1f0703ff, + .secvio_ctl = 0x3000007f, + }, + .lp = { + .lock = 0x1f0003ff, + .secvio_ctl = 0x36, + .tamper_filt_cfg = 0x00800000, /* Enable filtering */ + .tamper_det_cfg = 0x276, /* ET1 enabled + analogic tampers + * + rollover tampers + */ + .tamper_det_cfg2 = 0, + .tamper_filt1_cfg = 0, + .tamper_filt2_cfg = 0, + .act_tamper1_cfg = 0x84001111, + .act_tamper2_cfg = 0, + .act_tamper3_cfg = 0, + .act_tamper4_cfg = 0, + .act_tamper5_cfg = 0, + .act_tamper_ctl = 0x00010001, + .act_tamper_clk_ctl = 0, + .act_tamper_routing_ctl1 = 0x1, + .act_tamper_routing_ctl2 = 0, + } +}; + +static struct snvs_security_sc_conf *get_snvs_config(void) +{ + return &snvs_default_config; +} + +struct snvs_dgo_conf { + u32 tamper_offset_ctl; + u32 tamper_pull_ctl; + u32 tamper_ana_test_ctl; + u32 tamper_sensor_trim_ctl; + u32 tamper_misc_ctl; + u32 tamper_core_volt_mon_ctl; +}; + +static struct snvs_dgo_conf snvs_dgo_default_config = { + .tamper_misc_ctl = 0x80000000, /* Lock the DGO */ +}; + +static struct snvs_dgo_conf snvs_dgo_passive_vcc_config = { + .tamper_misc_ctl = 0x80000000, /* Lock the DGO */ + .tamper_pull_ctl = 0x00000001, /* Pull down ET1 */ + .tamper_ana_test_ctl = 0x20000000, /* Enable tamper */ +}; + +static struct snvs_dgo_conf snvs_dgo_passive_gnd_config = { + .tamper_misc_ctl = 0x80000000, /* Lock the DGO */ + .tamper_pull_ctl = 0x00000401, /* Pull up ET1 */ + .tamper_ana_test_ctl = 0x20000000, /* Enable tamper */ +}; + +static struct snvs_dgo_conf snvs_dgo_active_config = { + .tamper_misc_ctl = 0x80000000, /* Lock the DGO */ + .tamper_ana_test_ctl = 0x20000000, /* Enable tamper */ +}; + +static struct snvs_dgo_conf *get_snvs_dgo_config(void) +{ + return &snvs_dgo_default_config; +} + +struct tamper_pin_cfg { + u32 pad; + u32 mux_conf; +}; + +static struct tamper_pin_cfg tamper_pin_list_default_config[] = { + {SC_P_CSI_D00, 0}, /* Tamp_Out0 */ + {SC_P_CSI_D01, 0}, /* Tamp_Out1 */ + {SC_P_CSI_D02, 0}, /* Tamp_Out2 */ + {SC_P_CSI_D03, 0}, /* Tamp_Out3 */ + {SC_P_CSI_D04, 0}, /* Tamp_Out4 */ + {SC_P_CSI_D05, 0}, /* Tamp_In0 */ + {SC_P_CSI_D06, 0}, /* Tamp_In1 */ + {SC_P_CSI_D07, 0}, /* Tamp_In2 */ + {SC_P_CSI_HSYNC, 0}, /* Tamp_In3 */ + {SC_P_CSI_VSYNC, 0}, /* Tamp_In4 */ +}; + +static struct tamper_pin_cfg tamper_pin_list_passive_vcc_config[] = { + {SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */ +}; + +static struct tamper_pin_cfg tamper_pin_list_passive_gnd_config[] = { + {SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */ +}; + +static struct tamper_pin_cfg tamper_pin_list_active_config[] = { + {SC_P_CSI_D00, 0x1a000060}, /* Tamp_Out0 */ /* Sel tamper + OD */ + {SC_P_CSI_D05, 0x1c000060}, /* Tamp_In0 */ /* Sel tamper + OD input */ +}; + +#define TAMPER_PIN_LIST_CHOSEN tamper_pin_list_default_config + +static struct tamper_pin_cfg *get_tamper_pin_cfg_list(u32 *size) +{ + *size = sizeof(TAMPER_PIN_LIST_CHOSEN) / + sizeof(TAMPER_PIN_LIST_CHOSEN[0]); + + return TAMPER_PIN_LIST_CHOSEN; +} + +#define SC_CONF_OFFSET_OF(_field) \ + (offsetof(struct snvs_security_sc_conf, _field)) + +static u32 ptr_value(u32 *_p) +{ + return (_p) ? *_p : 0xdeadbeef; +} + +static int check_write_secvio_config(u32 id, u32 *_p1, u32 *_p2, + u32 *_p3, u32 *_p4, u32 *_p5, + u32 _cnt) +{ + int scierr = 0; + u32 d1 = ptr_value(_p1); + u32 d2 = ptr_value(_p2); + u32 d3 = ptr_value(_p3); + u32 d4 = ptr_value(_p4); + u32 d5 = ptr_value(_p5); + + scierr = sc_seco_secvio_config(-1, id, SC_WRITE_CONF, &d1, &d2, &d3, + &d4, &d4, _cnt); + if (scierr != SC_ERR_NONE) { + printf("Failed to set secvio configuration\n"); + debug("Failed to set conf id 0x%x with values ", id); + debug("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x (cnt: %d)\n", + d1, d2, d3, d4, d5, _cnt); + goto exit; + } + + if (_p1) + *(u32 *)_p1 = d1; + if (_p2) + *(u32 *)_p2 = d2; + if (_p3) + *(u32 *)_p3 = d3; + if (_p4) + *(u32 *)_p4 = d4; + if (_p5) + *(u32 *)_p5 = d5; + +exit: + return scierr; +} + +#define SC_CHECK_WRITE1(id, _p1) \ + check_write_secvio_config(id, _p1, NULL, NULL, NULL, NULL, 1) + +static int apply_snvs_config(struct snvs_security_sc_conf *cnf) +{ + int scierr = 0; + + debug("%s\n", __func__); + + debug("Applying config:\n" + "\thp.lock = 0x%.8x\n" + "\thp.secvio_ctl = 0x%.8x\n" + "\tlp.lock = 0x%.8x\n" + "\tlp.secvio_ctl = 0x%.8x\n" + "\tlp.tamper_filt_cfg = 0x%.8x\n" + "\tlp.tamper_det_cfg = 0x%.8x\n" + "\tlp.tamper_det_cfg2 = 0x%.8x\n" + "\tlp.tamper_filt1_cfg = 0x%.8x\n" + "\tlp.tamper_filt2_cfg = 0x%.8x\n" + "\tlp.act_tamper1_cfg = 0x%.8x\n" + "\tlp.act_tamper2_cfg = 0x%.8x\n" + "\tlp.act_tamper3_cfg = 0x%.8x\n" + "\tlp.act_tamper4_cfg = 0x%.8x\n" + "\tlp.act_tamper5_cfg = 0x%.8x\n" + "\tlp.act_tamper_ctl = 0x%.8x\n" + "\tlp.act_tamper_clk_ctl = 0x%.8x\n" + "\tlp.act_tamper_routing_ctl1 = 0x%.8x\n" + "\tlp.act_tamper_routing_ctl2 = 0x%.8x\n", + cnf->hp.lock, + cnf->hp.secvio_ctl, + cnf->lp.lock, + cnf->lp.secvio_ctl, + cnf->lp.tamper_filt_cfg, + cnf->lp.tamper_det_cfg, + cnf->lp.tamper_det_cfg2, + cnf->lp.tamper_filt1_cfg, + cnf->lp.tamper_filt2_cfg, + cnf->lp.act_tamper1_cfg, + cnf->lp.act_tamper2_cfg, + cnf->lp.act_tamper3_cfg, + cnf->lp.act_tamper4_cfg, + cnf->lp.act_tamper5_cfg, + cnf->lp.act_tamper_ctl, + cnf->lp.act_tamper_clk_ctl, + cnf->lp.act_tamper_routing_ctl1, + cnf->lp.act_tamper_routing_ctl2); + + scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_filt_cfg), + &cnf->lp.tamper_filt_cfg, + &cnf->lp.tamper_filt1_cfg, + &cnf->lp.tamper_filt2_cfg, NULL, + NULL, 3); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Configure AT */ + scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper1_cfg), + &cnf->lp.act_tamper1_cfg, + &cnf->lp.act_tamper2_cfg, + &cnf->lp.act_tamper2_cfg, + &cnf->lp.act_tamper2_cfg, + &cnf->lp.act_tamper2_cfg, 5); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Configure AT routing */ + scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.act_tamper_routing_ctl1), + &cnf->lp.act_tamper_routing_ctl1, + &cnf->lp.act_tamper_routing_ctl2, + NULL, NULL, NULL, 2); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Configure AT frequency */ + scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_clk_ctl), + &cnf->lp.act_tamper_clk_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Activate the ATs */ + scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.act_tamper_ctl), + &cnf->lp.act_tamper_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Activate the detectors */ + scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_cfg), + &cnf->lp.tamper_det_cfg, + &cnf->lp.tamper_det_cfg2, NULL, NULL, + NULL, 2); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Configure LP secvio */ + scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.secvio_ctl), + &cnf->lp.secvio_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Configure HP secvio */ + scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.secvio_ctl), + &cnf->hp.secvio_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Lock access */ + scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(hp.lock), &cnf->hp.lock); + if (scierr != SC_ERR_NONE) + goto exit; + + scierr = SC_CHECK_WRITE1(SC_CONF_OFFSET_OF(lp.lock), &cnf->lp.lock); + if (scierr != SC_ERR_NONE) + goto exit; + +exit: + return (scierr == SC_ERR_NONE) ? 0 : -EIO; +} + +static int dgo_write(u32 _id, u8 _access, u32 *_pdata) +{ + int scierr = sc_seco_secvio_dgo_config(-1, _id, _access, _pdata); + + if (scierr != SC_ERR_NONE) { + printf("Failed to set dgo configuration\n"); + debug("Failed to set conf id 0x%x : 0x%.8x", _id, *_pdata); + } + + return scierr; +} + +static int apply_snvs_dgo_config(struct snvs_dgo_conf *cnf) +{ + int scierr = 0; + + debug("%s\n", __func__); + + debug("Applying config:\n" + "\ttamper_offset_ctl = 0x%.8x\n" + "\ttamper_pull_ctl = 0x%.8x\n" + "\ttamper_ana_test_ctl = 0x%.8x\n" + "\ttamper_sensor_trim_ctl = 0x%.8x\n" + "\ttamper_misc_ctl = 0x%.8x\n" + "\ttamper_core_volt_mon_ctl = 0x%.8x\n", + cnf->tamper_offset_ctl, + cnf->tamper_pull_ctl, + cnf->tamper_ana_test_ctl, + cnf->tamper_sensor_trim_ctl, + cnf->tamper_misc_ctl, + cnf->tamper_core_volt_mon_ctl); + + dgo_write(0x04, 1, &cnf->tamper_offset_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + dgo_write(0x14, 1, &cnf->tamper_pull_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + dgo_write(0x24, 1, &cnf->tamper_ana_test_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + dgo_write(0x34, 1, &cnf->tamper_sensor_trim_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + dgo_write(0x54, 1, &cnf->tamper_core_volt_mon_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + + /* Last as it could lock the writes */ + dgo_write(0x44, 1, &cnf->tamper_misc_ctl); + if (scierr != SC_ERR_NONE) + goto exit; + +exit: + return (scierr == SC_ERR_NONE) ? 0 : -EIO; +} + +static int pad_write(u32 _pad, u32 _value) +{ + int scierr = sc_pad_set(-1, _pad, _value); + + if (scierr != SC_ERR_NONE) { + printf("Failed to set pad configuration\n"); + debug("Failed to set conf pad 0x%x : 0x%.8x", _pad, _value); + } + + return scierr; +} + +static int apply_tamper_pin_list_config(struct tamper_pin_cfg *confs, u32 size) +{ + int scierr = 0; + u32 idx; + + debug("%s\n", __func__); + + for (idx = 0; idx < size; idx++) { + debug("\t idx %d: pad %d: 0x%.8x\n", idx, confs[idx].pad, + confs[idx].mux_conf); + pad_write(confs[idx].pad, 3 << 30 | confs[idx].mux_conf); + if (scierr != SC_ERR_NONE) + goto exit; + } + +exit: + return (scierr == SC_ERR_NONE) ? 0 : -EIO; +} + +int examples(void) +{ + u32 size; + struct snvs_security_sc_conf *snvs_conf; + struct snvs_dgo_conf *snvs_dgo_conf; + struct tamper_pin_cfg *tamper_pin_conf; + + /* Caller */ + snvs_conf = get_snvs_config(); + snvs_dgo_conf = get_snvs_dgo_config(); + tamper_pin_conf = get_tamper_pin_cfg_list(&size); + + /* Default */ + snvs_conf = &snvs_default_config; + snvs_dgo_conf = &snvs_dgo_default_config; + tamper_pin_conf = tamper_pin_list_default_config; + + /* Passive tamper expecting VCC on the line */ + snvs_conf = &snvs_passive_vcc_config; + snvs_dgo_conf = &snvs_dgo_passive_vcc_config; + tamper_pin_conf = tamper_pin_list_passive_vcc_config; + + /* Passive tamper expecting GND on the line */ + snvs_conf = &snvs_passive_gnd_config; + snvs_dgo_conf = &snvs_dgo_passive_gnd_config; + tamper_pin_conf = tamper_pin_list_passive_gnd_config; + + /* Active tamper */ + snvs_conf = &snvs_active_config; + snvs_dgo_conf = &snvs_dgo_active_config; + tamper_pin_conf = tamper_pin_list_active_config; + + return !snvs_conf + !snvs_dgo_conf + !tamper_pin_conf; +} + +#ifdef CONFIG_IMX_SNVS_SEC_SC_AUTO +int snvs_security_sc_init(void) +{ + int err = 0; + + struct snvs_security_sc_conf *snvs_conf; + struct snvs_dgo_conf *snvs_dgo_conf; + struct tamper_pin_cfg *tamper_pin_conf; + u32 size; + + debug("%s\n", __func__); + + snvs_conf = get_snvs_config(); + snvs_dgo_conf = get_snvs_dgo_config(); + + tamper_pin_conf = get_tamper_pin_cfg_list(&size); + + err = apply_tamper_pin_list_config(tamper_pin_conf, size); + if (err) { + debug("Failed to set pins\n"); + goto exit; + } + + err = apply_snvs_dgo_config(snvs_dgo_conf); + if (err) { + debug("Failed to set dgo\n"); + goto exit; + } + + err = apply_snvs_config(snvs_conf); + if (err) { + debug("Failed to set snvs\n"); + goto exit; + } + +exit: + return err; +} +#endif /* CONFIG_IMX_SNVS_SEC_SC_AUTO */ + +static char snvs_cfg_help_text[] = + "snvs_cfg\n" + "\thp.lock\n" + "\thp.secvio_ctl\n" + "\tlp.lock\n" + "\tlp.secvio_ctl\n" + "\tlp.tamper_filt_cfg\n" + "\tlp.tamper_det_cfg\n" + "\tlp.tamper_det_cfg2\n" + "\tlp.tamper_filt1_cfg\n" + "\tlp.tamper_filt2_cfg\n" + "\tlp.act_tamper1_cfg\n" + "\tlp.act_tamper2_cfg\n" + "\tlp.act_tamper3_cfg\n" + "\tlp.act_tamper4_cfg\n" + "\tlp.act_tamper5_cfg\n" + "\tlp.act_tamper_ctl\n" + "\tlp.act_tamper_clk_ctl\n" + "\tlp.act_tamper_routing_ctl1\n" + "\tlp.act_tamper_routing_ctl2\n" + "\n" + "ALL values should be in hexadecimal format"; + +#define NB_REGISTERS 18 +static int do_snvs_cfg(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + int err = 0; + u32 idx = 0; + + struct snvs_security_sc_conf conf = {0}; + + if (argc != (NB_REGISTERS + 1)) + return CMD_RET_USAGE; + + conf.hp.lock = simple_strtoul(argv[++idx], NULL, 16); + conf.hp.secvio_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.lock = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.secvio_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.tamper_filt_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.tamper_det_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.tamper_det_cfg2 = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.tamper_filt1_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.tamper_filt2_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper1_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper2_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper3_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper4_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper5_cfg = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper_clk_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper_routing_ctl1 = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.act_tamper_routing_ctl2 = simple_strtoul(argv[++idx], NULL, 16); + + err = apply_snvs_config(&conf); + + return err; +} + +U_BOOT_CMD(snvs_cfg, + NB_REGISTERS + 1, 1, do_snvs_cfg, + "Security violation configuration", + snvs_cfg_help_text +); + +static char snvs_dgo_cfg_help_text[] = + "snvs_dgo_cfg\n" + "\ttamper_offset_ctl\n" + "\ttamper_pull_ctl\n" + "\ttamper_ana_test_ctl\n" + "\ttamper_sensor_trim_ctl\n" + "\ttamper_misc_ctl\n" + "\ttamper_core_volt_mon_ctl\n" + "\n" + "ALL values should be in hexadecimal format"; + +static int do_snvs_dgo_cfg(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int err = 0; + u32 idx = 0; + + struct snvs_dgo_conf conf = {0}; + + if (argc != (6 + 1)) + return CMD_RET_USAGE; + + conf.tamper_offset_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.tamper_pull_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.tamper_ana_test_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.tamper_sensor_trim_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.tamper_misc_ctl = simple_strtoul(argv[++idx], NULL, 16); + conf.tamper_core_volt_mon_ctl = simple_strtoul(argv[++idx], NULL, 16); + + err = apply_snvs_dgo_config(&conf); + + return err; +} + +U_BOOT_CMD(snvs_dgo_cfg, + 7, 1, do_snvs_dgo_cfg, + "SNVS DGO configuration", + snvs_dgo_cfg_help_text +); + +static char tamper_pin_cfg_help_text[] = + "snvs_dgo_cfg\n" + "\tpad\n" + "\tvalue\n" + "\n" + "ALL values should be in hexadecimal format"; + +static int do_tamper_pin_cfg(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int err = 0; + u32 idx = 0; + + struct tamper_pin_cfg conf = {0}; + + if (argc != (2 + 1)) + return CMD_RET_USAGE; + + conf.pad = simple_strtoul(argv[++idx], NULL, 10); + conf.mux_conf = simple_strtoul(argv[++idx], NULL, 16); + + err = apply_tamper_pin_list_config(&conf, 1); + + return err; +} + +U_BOOT_CMD(tamper_pin_cfg, + 3, 1, do_tamper_pin_cfg, + "tamper pin configuration", + tamper_pin_cfg_help_text +); + +static char snvs_clear_status_help_text[] = + "snvs_clear_status\n" + "\tHPSR\n" + "\tHPSVSR\n" + "\tLPSR\n" + "\tLPTDSR\n" + "\n" + "Write the status registers with the value provided," + " clearing the status"; + +static int do_snvs_clear_status(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int scierr = 0; + u32 idx = 0; + + struct snvs_security_sc_conf conf = {0}; + + if (argc != (2 + 1)) + return CMD_RET_USAGE; + + conf.lp.status = simple_strtoul(argv[++idx], NULL, 16); + conf.lp.tamper_det_status = simple_strtoul(argv[++idx], NULL, 16); + + scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.status), + &conf.lp.status, NULL, NULL, NULL, + NULL, 1); + if (scierr != SC_ERR_NONE) + goto exit; + + scierr = check_write_secvio_config(SC_CONF_OFFSET_OF(lp.tamper_det_status), + &conf.lp.tamper_det_status, NULL, + NULL, NULL, NULL, 1); + if (scierr != SC_ERR_NONE) + goto exit; + +exit: + return (scierr == SC_ERR_NONE) ? 0 : 1; +} + +U_BOOT_CMD(snvs_clear_status, + 3, 1, do_snvs_clear_status, + "snvs clear status", + snvs_clear_status_help_text +); + +static char snvs_sec_status_help_text[] = + "snvs_sec_status\n" + "Display information about the security related to tamper and secvio"; + +static int do_snvs_sec_status(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + int scierr; + u32 idx; + + u32 data[5]; + + u32 pads[] = { + SC_P_CSI_D00, + SC_P_CSI_D01, + SC_P_CSI_D02, + SC_P_CSI_D03, + SC_P_CSI_D04, + SC_P_CSI_D05, + SC_P_CSI_D06, + SC_P_CSI_D07, + SC_P_CSI_HSYNC, + SC_P_CSI_VSYNC, + }; + + u32 fuses[] = { + 14, + 30, + 31, + 260, + 261, + 262, + 263, + 768, + }; + + struct snvs_reg { + u32 id; + u32 nb; + } snvs[] = { + /* Locks */ + {0x0, 1}, + {0x34, 1}, + /* Security violation */ + {0xc, 1}, + {0x10, 1}, + {0x18, 1}, + {0x40, 1}, + /* Temper detectors */ + {0x48, 2}, + {0x4c, 1}, + {0xa4, 1}, + /* */ + {0x44, 3}, + {0xe0, 1}, + {0xe4, 1}, + {0xe8, 2}, + /* Misc */ + {0x3c, 1}, + {0x5c, 2}, + {0x64, 1}, + {0xf8, 2}, + }; + + u32 dgo[] = { + 0x0, + 0x10, + 0x20, + 0x30, + 0x40, + 0x50, + }; + + /* Pins */ + printf("Pins:\n"); + for (idx = 0; idx < ARRAY_SIZE(pads); idx++) { + u8 pad_id = pads[idx]; + + scierr = sc_pad_get(-1, pad_id, &data[0]); + if (scierr == 0) + printf("\t- Pin %d: %.8x\n", pad_id, data[0]); + else + printf("Failed to read Pin %d\n", pad_id); + } + + /* Fuses */ + printf("Fuses:\n"); + for (idx = 0; idx < ARRAY_SIZE(fuses); idx++) { + u32 fuse_id = fuses[idx]; + + scierr = sc_misc_otp_fuse_read(-1, fuse_id, &data[0]); + if (scierr == 0) + printf("\t- Fuse %d: %.8x\n", fuse_id, data[0]); + else + printf("Failed to read Fuse %d\n", fuse_id); + } + + /* SNVS */ + printf("SNVS:\n"); + for (idx = 0; idx < ARRAY_SIZE(snvs); idx++) { + struct snvs_reg *reg = &snvs[idx]; + + scierr = sc_seco_secvio_config(-1, reg->id, 0, &data[0], + &data[1], &data[2], &data[3], + &data[4], reg->nb); + if (scierr == 0) { + int subidx; + + printf("\t- SNVS %.2x(%d):", reg->id, reg->nb); + for (subidx = 0; subidx < reg->nb; subidx++) + printf(" %.8x", data[subidx]); + printf("\n"); + } else { + printf("Failed to read SNVS %d\n", reg->id); + } + } + + /* DGO */ + printf("DGO:\n"); + for (idx = 0; idx < ARRAY_SIZE(dgo); idx++) { + u8 dgo_id = dgo[idx]; + + scierr = sc_seco_secvio_dgo_config(-1, dgo_id, 0, &data[0]); + if (scierr == 0) + printf("\t- DGO %.2x: %.8x\n", dgo_id, data[0]); + else + printf("Failed to read DGO %d\n", dgo_id); + } + + return 0; +} + +U_BOOT_CMD(snvs_sec_status, + 1, 1, do_snvs_sec_status, + "tamper pin configuration", + snvs_sec_status_help_text +); diff --git a/board/freescale/imx8qxp_mek/imx8qxp_mek.c b/board/freescale/imx8qxp_mek/imx8qxp_mek.c index b96f0da21e..93f0cd827c 100644 --- a/board/freescale/imx8qxp_mek/imx8qxp_mek.c +++ b/board/freescale/imx8qxp_mek/imx8qxp_mek.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -111,6 +112,15 @@ int board_init(void) { board_gpio_init(); +#ifdef CONFIG_IMX_SNVS_SEC_SC_AUTO + { + int ret = snvs_security_sc_init(); + + if (ret) + return ret; + } +#endif + return 0; } diff --git a/drivers/misc/imx8/scu_api.c b/drivers/misc/imx8/scu_api.c index 227bc52873..3e38edbf5d 100644 --- a/drivers/misc/imx8/scu_api.c +++ b/drivers/misc/imx8/scu_api.c @@ -222,6 +222,34 @@ int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val) return ret; } +int sc_pad_get(sc_ipc_t ipc, sc_pad_t pad, u32 *val) +{ + struct udevice *dev = gd->arch.scu_dev; + int size = sizeof(struct sc_rpc_msg_s); + struct sc_rpc_msg_s msg; + int ret; + + if (!dev) + hang(); + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 2U; + RPC_SVC(&msg) = (u8)(SC_RPC_SVC_PAD); + RPC_FUNC(&msg) = (u8)(PAD_FUNC_GET); + + RPC_U16(&msg, 0U) = (u16)(pad); + + ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size); + if (ret) + printf("%s: pad:%d: res:%d\n", + __func__, pad, RPC_R8(&msg)); + + if (val) + *val = (u32)RPC_U32(&msg, 0U); + + return ret; +} + /* MISC */ int sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl, u32 val) @@ -996,8 +1024,8 @@ int sc_seco_get_mp_key(sc_ipc_t ipc, sc_faddr_t dst_addr, return ret; } -int sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr, uint8_t size_m, - uint8_t lock) +int sc_seco_update_mpmr(sc_ipc_t ipc, sc_faddr_t addr, u8 size_m, + u8 lock) { struct udevice *dev = gd->arch.scu_dev; struct sc_rpc_msg_s msg; @@ -1051,8 +1079,44 @@ int sc_seco_get_mp_sign(sc_ipc_t ipc, sc_faddr_t msg_addr, return ret; } -int sc_seco_secvio_dgo_config(sc_ipc_t ipc, uint8_t id, uint8_t access, - u32 *data) +int sc_seco_secvio_config(sc_ipc_t ipc, u8 id, u8 access, + u32 *data0, u32 *data1, u32 *data2, u32 *data3, + u32 *data4, u8 size) +{ + struct udevice *dev = gd->arch.scu_dev; + struct sc_rpc_msg_s msg; + int msg_size = sizeof(struct sc_rpc_msg_s); + int ret; + + RPC_VER(&msg) = SC_RPC_VERSION; + RPC_SIZE(&msg) = 7U; + RPC_SVC(&msg) = (u8)(SC_RPC_SVC_SECO); + RPC_FUNC(&msg) = (u8)(SECO_FUNC_SECVIO_CONFIG); + + RPC_U32(&msg, 0U) = (u32)(*data0); + RPC_U32(&msg, 4U) = (u32)(*data1); + RPC_U32(&msg, 8U) = (u32)(*data2); + RPC_U32(&msg, 12U) = (u32)(*data3); + RPC_U32(&msg, 16U) = (u32)(*data4); + RPC_U8(&msg, 20U) = (u8)(id); + RPC_U8(&msg, 21U) = (u8)(access); + RPC_U8(&msg, 22U) = (u8)(size); + + ret = misc_call(dev, SC_FALSE, &msg, msg_size, &msg, msg_size); + if (ret) + printf("%s, id:0x%x, access:%x, res:%d\n", + __func__, id, access, RPC_R8(&msg)); + + *data0 = (u32)RPC_U32(&msg, 0U); + *data1 = (u32)RPC_U32(&msg, 4U); + *data2 = (u32)RPC_U32(&msg, 8U); + *data3 = (u32)RPC_U32(&msg, 12U); + *data4 = (u32)RPC_U32(&msg, 16U); + + return ret; +} + +int sc_seco_secvio_dgo_config(sc_ipc_t ipc, u8 id, u8 access, u32 *data) { struct udevice *dev = gd->arch.scu_dev; struct sc_rpc_msg_s msg;