// SPDX-License-Identifier: GPL-2.0-or-later /* * (C) Copyright 2024 - Analog Devices, Inc. * * Written and/or maintained by Timesys Corporation * * Contact: Nathan Barrett-Morrison * Contact: Greg Malysa */ #include #include #include #include #define REG_TSGENWR0_CNTCR 0x310AE000 #define REG_PADS0_PCFG0 0x31004604 #define REG_RCU0_BCODE 0x3108C028 #define REG_SPU0_SECUREP_START 0x3108BA00 #define REG_SPU0_WP_START 0x3108B400 #define REG_SPU0_SECUREC0 0x3108B980 #define REG_SCB5_SPI2_OSPI_REMAP 0x30400000 #define BITM_SCB5_SPI2_OSPI_REMAP_REMAP 0x00000003 #define ENUM_SCB5_SPI2_OSPI_REMAP_OSPI0 0x00000001 static struct mm_region sc598_mem_map[] = { { /* Peripherals */ .virt = 0x0UL, .phys = 0x0UL, .size = 0x80000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN }, { /* DDR */ .virt = 0x80000000UL, .phys = 0x80000000UL, .size = 0x40000000UL, .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE }, { /* List terminator */ 0, } }; struct mm_region *mem_map = sc598_mem_map; adi_rom_boot_fn adi_rom_boot = (adi_rom_boot_fn)0x000000e4; void sc5xx_enable_rgmii(void) { writel((readl(REG_PADS0_PCFG0) | 0xc), REG_PADS0_PCFG0); // Set dw for little endian operation as well writel(readl(REG_PADS0_PCFG0) & ~(1 << 19), REG_PADS0_PCFG0); writel(readl(REG_PADS0_PCFG0) & ~(1 << 20), REG_PADS0_PCFG0); } void sc59x_remap_ospi(void) { clrsetbits_le32(REG_SCB5_SPI2_OSPI_REMAP, BITM_SCB5_SPI2_OSPI_REMAP_REMAP, ENUM_SCB5_SPI2_OSPI_REMAP_OSPI0); } /** * SPU/SMPU configuration is the default for permissive access from non-secure * EL1. If TFA and OPTEE are configured, they run *after* this code, as the * current boot flow is SPL -> TFA -> OPTEE -> Proper -> Linux, and will * be expected to configure peripheral security correctly. If they are not * configured, then this permissive setting will allow Linux (which always * runs in NS EL1) to control all access to these peripherals. Without it, * the peripherals would simply be unavailable in a non-security build, * which is not OK. */ void sc5xx_soc_init(void) { phys_addr_t smpus[] = { 0x31007800, //SMPU0 0x31083800, //SMPU2 0x31084800, //SMPU3 0x31085800, //SMPU4 0x31086800, //SMPU5 0x31087800, //SMPU6 0x310A0800, //SMPU9 0x310A1800, //SMPU11 0x31012800, //SMPU12 }; size_t i; // Enable coresight timer writel(1, REG_TSGENWR0_CNTCR); //Do not rerun preboot routine -- // Without this, hardware resets triggered by RCU0_CTL:SYSRST // lead to a deadlock somewhere in the boot ROM writel(0x200, REG_RCU0_BCODE); /* Alter outstanding transactions property of A55*/ writel(0x1, 0x30643108); /* SCB6 A55 M0 Ib.fn Mod */ isb(); /* configure DDR prefetch behavior, per ADI */ writel(0x1, 0x31076000); /* configure smart mode, per ADI */ writel(0x1307, 0x31076004); // Disable SPU and SPU WP registers sc5xx_disable_spu0(REG_SPU0_SECUREP_START, REG_SPU0_SECUREP_START + 4*213); sc5xx_disable_spu0(REG_SPU0_WP_START, REG_SPU0_WP_START + 4*213); /* configure smpus permissively */ for (i = 0; i < ARRAY_SIZE(smpus); ++i) writel(0x500, smpus[i]); sc5xx_enable_ns_sharc_access(REG_SPU0_SECUREC0); }