#include <imx_sip.h>
#include <generated/version_autogenerated.h>
#include <asm/setup.h>
+#include <asm/bootm.h>
#ifdef CONFIG_IMX_SEC_INIT
#include <fsl_caam.h>
#endif
writew(enable, &wdog3->wmcr);
}
+#ifdef CONFIG_SECURE_BOOT
+static bool is_hdmi_fused(void) {
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[1];
+ struct fuse_bank1_regs *fuse =
+ (struct fuse_bank1_regs *)bank->fuse_regs;
+
+ u32 value = readl(&fuse->tester4);
+
+ if (is_imx8mq()) {
+ if (value & 0x02000000)
+ return true;
+ }
+
+ return false;
+}
+
+bool is_uid_matched(u64 uid) {
+ struct tag_serialnr nr;
+ get_board_serial(&nr);
+
+ if (lower_32_bits(uid) == nr.low &&
+ upper_32_bits(uid) == nr.high)
+ return true;
+
+ return false;
+}
+
+static void secure_lockup(void)
+{
+ if (is_imx8mq() && is_soc_rev(CHIP_REV_2_1) &&
+ imx_hab_is_enabled() && !is_hdmi_fused()) {
+#ifdef CONFIG_SECURE_STICKY_BITS_LOCKUP
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+
+ clock_enable(CCGR_OCOTP, 1);
+ setbits_le32(&ocotp->sw_sticky, 0x6); /* Lock up field return and SRK revoke */
+ writel(0x80000000, &ocotp->scs_set); /* Lock up SCS */
+
+ /* Clear mfg prot private key in CAAM */
+ setbits_le32((ulong)(CONFIG_SYS_FSL_SEC_ADDR + 0xc), 0x08000000);
+#else
+ /* Check the Unique ID, if it is matched with UID config, then allow to leave sticky bits unlocked */
+ if (!is_uid_matched(CONFIG_IMX_UNIQUE_ID))
+ hang();
+#endif
+ }
+}
+#endif
+
int arch_cpu_init(void)
{
struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
clock_init();
imx_set_wdog_powerdown(false);
+#ifdef CONFIG_SECURE_BOOT
+ secure_lockup();
+#endif
if (is_imx8md() || is_imx8mmd() || is_imx8mmdl() || is_imx8mms() || is_imx8mmsl() ||
is_imx8mnd() || is_imx8mndl() || is_imx8mns() || is_imx8mnsl()) {
/* Power down cpu core 1, 2 and 3 for iMX8M Dual core or Single core */