uboot/arch/arm/mach-stm32mp/fdt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
   2/*
   3 * Copyright (C) 2019-2020, STMicroelectronics - All Rights Reserved
   4 */
   5
   6#define LOG_CATEGORY LOGC_ARCH
   7
   8#include <common.h>
   9#include <fdtdec.h>
  10#include <fdt_support.h>
  11#include <log.h>
  12#include <tee.h>
  13#include <asm/arch/sys_proto.h>
  14#include <dt-bindings/pinctrl/stm32-pinfunc.h>
  15#include <linux/io.h>
  16
  17#define ETZPC_DECPROT(n)        (STM32_ETZPC_BASE + 0x10 + 4 * (n))
  18#define ETZPC_DECPROT_NB        6
  19
  20#define DECPROT_MASK            0x03
  21#define NB_PROT_PER_REG         0x10
  22#define DECPROT_NB_BITS         2
  23
  24#define DECPROT_SECURED         0x00
  25#define DECPROT_WRITE_SECURE    0x01
  26#define DECPROT_MCU_ISOLATION   0x02
  27#define DECPROT_NON_SECURED     0x03
  28
  29#define ETZPC_RESERVED          0xffffffff
  30
  31#define STM32_FDCAN_BASE        0x4400e000
  32#define STM32_CRYP2_BASE        0x4c005000
  33#define STM32_CRYP1_BASE        0x54001000
  34#define STM32_GPU_BASE          0x59000000
  35#define STM32_DSI_BASE          0x5a000000
  36
  37static const u32 stm32mp1_ip_addr[] = {
  38        0x5c008000,     /* 00 stgenc */
  39        0x54000000,     /* 01 bkpsram */
  40        0x5c003000,     /* 02 iwdg1 */
  41        0x5c000000,     /* 03 usart1 */
  42        0x5c001000,     /* 04 spi6 */
  43        0x5c002000,     /* 05 i2c4 */
  44        ETZPC_RESERVED, /* 06 reserved */
  45        0x54003000,     /* 07 rng1 */
  46        0x54002000,     /* 08 hash1 */
  47        STM32_CRYP1_BASE,       /* 09 cryp1 */
  48        0x5a003000,     /* 0A ddrctrl */
  49        0x5a004000,     /* 0B ddrphyc */
  50        0x5c009000,     /* 0C i2c6 */
  51        ETZPC_RESERVED, /* 0D reserved */
  52        ETZPC_RESERVED, /* 0E reserved */
  53        ETZPC_RESERVED, /* 0F reserved */
  54        0x40000000,     /* 10 tim2 */
  55        0x40001000,     /* 11 tim3 */
  56        0x40002000,     /* 12 tim4 */
  57        0x40003000,     /* 13 tim5 */
  58        0x40004000,     /* 14 tim6 */
  59        0x40005000,     /* 15 tim7 */
  60        0x40006000,     /* 16 tim12 */
  61        0x40007000,     /* 17 tim13 */
  62        0x40008000,     /* 18 tim14 */
  63        0x40009000,     /* 19 lptim1 */
  64        0x4000a000,     /* 1A wwdg1 */
  65        0x4000b000,     /* 1B spi2 */
  66        0x4000c000,     /* 1C spi3 */
  67        0x4000d000,     /* 1D spdifrx */
  68        0x4000e000,     /* 1E usart2 */
  69        0x4000f000,     /* 1F usart3 */
  70        0x40010000,     /* 20 uart4 */
  71        0x40011000,     /* 21 uart5 */
  72        0x40012000,     /* 22 i2c1 */
  73        0x40013000,     /* 23 i2c2 */
  74        0x40014000,     /* 24 i2c3 */
  75        0x40015000,     /* 25 i2c5 */
  76        0x40016000,     /* 26 cec */
  77        0x40017000,     /* 27 dac */
  78        0x40018000,     /* 28 uart7 */
  79        0x40019000,     /* 29 uart8 */
  80        ETZPC_RESERVED, /* 2A reserved */
  81        ETZPC_RESERVED, /* 2B reserved */
  82        0x4001c000,     /* 2C mdios */
  83        ETZPC_RESERVED, /* 2D reserved */
  84        ETZPC_RESERVED, /* 2E reserved */
  85        ETZPC_RESERVED, /* 2F reserved */
  86        0x44000000,     /* 30 tim1 */
  87        0x44001000,     /* 31 tim8 */
  88        ETZPC_RESERVED, /* 32 reserved */
  89        0x44003000,     /* 33 usart6 */
  90        0x44004000,     /* 34 spi1 */
  91        0x44005000,     /* 35 spi4 */
  92        0x44006000,     /* 36 tim15 */
  93        0x44007000,     /* 37 tim16 */
  94        0x44008000,     /* 38 tim17 */
  95        0x44009000,     /* 39 spi5 */
  96        0x4400a000,     /* 3A sai1 */
  97        0x4400b000,     /* 3B sai2 */
  98        0x4400c000,     /* 3C sai3 */
  99        0x4400d000,     /* 3D dfsdm */
 100        STM32_FDCAN_BASE,       /* 3E tt_fdcan */
 101        ETZPC_RESERVED, /* 3F reserved */
 102        0x50021000,     /* 40 lptim2 */
 103        0x50022000,     /* 41 lptim3 */
 104        0x50023000,     /* 42 lptim4 */
 105        0x50024000,     /* 43 lptim5 */
 106        0x50027000,     /* 44 sai4 */
 107        0x50025000,     /* 45 vrefbuf */
 108        0x4c006000,     /* 46 dcmi */
 109        0x4c004000,     /* 47 crc2 */
 110        0x48003000,     /* 48 adc */
 111        0x4c002000,     /* 49 hash2 */
 112        0x4c003000,     /* 4A rng2 */
 113        STM32_CRYP2_BASE,       /* 4B cryp2 */
 114        ETZPC_RESERVED, /* 4C reserved */
 115        ETZPC_RESERVED, /* 4D reserved */
 116        ETZPC_RESERVED, /* 4E reserved */
 117        ETZPC_RESERVED, /* 4F reserved */
 118        ETZPC_RESERVED, /* 50 sram1 */
 119        ETZPC_RESERVED, /* 51 sram2 */
 120        ETZPC_RESERVED, /* 52 sram3 */
 121        ETZPC_RESERVED, /* 53 sram4 */
 122        ETZPC_RESERVED, /* 54 retram */
 123        0x49000000,     /* 55 otg */
 124        0x48004000,     /* 56 sdmmc3 */
 125        0x48005000,     /* 57 dlybsd3 */
 126        0x48000000,     /* 58 dma1 */
 127        0x48001000,     /* 59 dma2 */
 128        0x48002000,     /* 5A dmamux */
 129        0x58002000,     /* 5B fmc */
 130        0x58003000,     /* 5C qspi */
 131        0x58004000,     /* 5D dlybq */
 132        0x5800a000,     /* 5E eth */
 133        ETZPC_RESERVED, /* 5F reserved */
 134};
 135
 136/* fdt helper */
 137static bool fdt_disable_subnode_by_address(void *fdt, int offset, u32 addr)
 138{
 139        int node;
 140        fdt_addr_t regs;
 141
 142        for (node = fdt_first_subnode(fdt, offset);
 143             node >= 0;
 144             node = fdt_next_subnode(fdt, node)) {
 145                regs = fdtdec_get_addr(fdt, node, "reg");
 146                if (addr == regs) {
 147                        if (fdtdec_get_is_enabled(fdt, node)) {
 148                                fdt_status_disabled(fdt, node);
 149
 150                                return true;
 151                        }
 152                        return false;
 153                }
 154        }
 155
 156        return false;
 157}
 158
 159static int stm32_fdt_fixup_etzpc(void *fdt, int soc_node)
 160{
 161        const u32 *array;
 162        int array_size, i;
 163        int offset, shift;
 164        u32 addr, status, decprot[ETZPC_DECPROT_NB];
 165
 166        array = stm32mp1_ip_addr;
 167        array_size = ARRAY_SIZE(stm32mp1_ip_addr);
 168
 169        for (i = 0; i < ETZPC_DECPROT_NB; i++)
 170                decprot[i] = readl(ETZPC_DECPROT(i));
 171
 172        for (i = 0; i < array_size; i++) {
 173                offset = i / NB_PROT_PER_REG;
 174                shift = (i % NB_PROT_PER_REG) * DECPROT_NB_BITS;
 175                status = (decprot[offset] >> shift) & DECPROT_MASK;
 176                addr = array[i];
 177
 178                log_debug("ETZPC: 0x%08x decprot %d=%d\n", addr, i, status);
 179
 180                if (addr == ETZPC_RESERVED ||
 181                    status == DECPROT_NON_SECURED)
 182                        continue;
 183
 184                if (fdt_disable_subnode_by_address(fdt, soc_node, addr))
 185                        log_notice("ETZPC: 0x%08x node disabled, decprot %d=%d\n",
 186                                   addr, i, status);
 187        }
 188
 189        return 0;
 190}
 191
 192/* deactivate all the cpu except core 0 */
 193static void stm32_fdt_fixup_cpu(void *blob, char *name)
 194{
 195        int off;
 196        u32 reg;
 197
 198        off = fdt_path_offset(blob, "/cpus");
 199        if (off < 0) {
 200                log_warning("%s: couldn't find /cpus node\n", __func__);
 201                return;
 202        }
 203
 204        off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
 205        while (off != -FDT_ERR_NOTFOUND) {
 206                reg = fdtdec_get_addr(blob, off, "reg");
 207                if (reg != 0) {
 208                        fdt_del_node(blob, off);
 209                        log_notice("FDT: cpu %d node remove for %s\n",
 210                                   reg, name);
 211                        /* after delete we can't trust the offsets anymore */
 212                        off = -1;
 213                }
 214                off = fdt_node_offset_by_prop_value(blob, off,
 215                                                    "device_type", "cpu", 4);
 216        }
 217}
 218
 219static void stm32_fdt_disable(void *fdt, int offset, u32 addr,
 220                              const char *string, const char *name)
 221{
 222        if (fdt_disable_subnode_by_address(fdt, offset, addr))
 223                log_notice("FDT: %s@%08x node disabled for %s\n",
 224                           string, addr, name);
 225}
 226
 227static void stm32_fdt_disable_optee(void *blob)
 228{
 229        int off, node;
 230
 231        /* Delete "optee" firmware node */
 232        off = fdt_node_offset_by_compatible(blob, -1, "linaro,optee-tz");
 233        if (off >= 0 && fdtdec_get_is_enabled(blob, off))
 234                fdt_del_node(blob, off);
 235
 236        /* Delete "optee@..." reserved-memory node */
 237        off = fdt_path_offset(blob, "/reserved-memory/");
 238        if (off < 0)
 239                return;
 240        for (node = fdt_first_subnode(blob, off);
 241             node >= 0;
 242             node = fdt_next_subnode(blob, node)) {
 243                if (strncmp(fdt_get_name(blob, node, NULL), "optee@", 6))
 244                        continue;
 245
 246                if (fdt_del_node(blob, node))
 247                        printf("Failed to remove optee reserved-memory node\n");
 248        }
 249}
 250
 251/*
 252 * This function is called right before the kernel is booted. "blob" is the
 253 * device tree that will be passed to the kernel.
 254 */
 255int ft_system_setup(void *blob, struct bd_info *bd)
 256{
 257        int ret = 0;
 258        int soc;
 259        u32 pkg, cpu;
 260        char name[SOC_NAME_SIZE];
 261
 262        soc = fdt_path_offset(blob, "/soc");
 263        if (soc < 0)
 264                return soc;
 265
 266        if (CONFIG_IS_ENABLED(STM32_ETZPC)) {
 267                ret = stm32_fdt_fixup_etzpc(blob, soc);
 268                if (ret)
 269                        return ret;
 270        }
 271
 272        /* MPUs Part Numbers and name*/
 273        cpu = get_cpu_type();
 274        get_soc_name(name);
 275
 276        switch (cpu) {
 277        case CPU_STM32MP151Fxx:
 278        case CPU_STM32MP151Dxx:
 279        case CPU_STM32MP151Cxx:
 280        case CPU_STM32MP151Axx:
 281                stm32_fdt_fixup_cpu(blob, name);
 282                /* after cpu delete we can't trust the soc offsets anymore */
 283                soc = fdt_path_offset(blob, "/soc");
 284                stm32_fdt_disable(blob, soc, STM32_FDCAN_BASE, "can", name);
 285                /* fall through */
 286        case CPU_STM32MP153Fxx:
 287        case CPU_STM32MP153Dxx:
 288        case CPU_STM32MP153Cxx:
 289        case CPU_STM32MP153Axx:
 290                stm32_fdt_disable(blob, soc, STM32_GPU_BASE, "gpu", name);
 291                stm32_fdt_disable(blob, soc, STM32_DSI_BASE, "dsi", name);
 292                break;
 293        default:
 294                break;
 295        }
 296
 297        switch (cpu) {
 298        case CPU_STM32MP157Dxx:
 299        case CPU_STM32MP157Axx:
 300        case CPU_STM32MP153Dxx:
 301        case CPU_STM32MP153Axx:
 302        case CPU_STM32MP151Dxx:
 303        case CPU_STM32MP151Axx:
 304                stm32_fdt_disable(blob, soc, STM32_CRYP1_BASE, "cryp", name);
 305                stm32_fdt_disable(blob, soc, STM32_CRYP2_BASE, "cryp", name);
 306                break;
 307        default:
 308                break;
 309        }
 310
 311        switch (get_cpu_package()) {
 312        case PKG_AA_LBGA448:
 313                pkg = STM32MP_PKG_AA;
 314                break;
 315        case PKG_AB_LBGA354:
 316                pkg = STM32MP_PKG_AB;
 317                break;
 318        case PKG_AC_TFBGA361:
 319                pkg = STM32MP_PKG_AC;
 320                break;
 321        case PKG_AD_TFBGA257:
 322                pkg = STM32MP_PKG_AD;
 323                break;
 324        default:
 325                pkg = 0;
 326                break;
 327        }
 328        if (pkg) {
 329                do_fixup_by_compat_u32(blob, "st,stm32mp157-pinctrl",
 330                                       "st,package", pkg, false);
 331                do_fixup_by_compat_u32(blob, "st,stm32mp157-z-pinctrl",
 332                                       "st,package", pkg, false);
 333        }
 334
 335        /*
 336         * TEMP: remove OP-TEE nodes in kernel device tree
 337         *       copied from U-Boot device tree by optee_copy_fdt_nodes
 338         *       when OP-TEE is not detected (probe failed)
 339         * these OP-TEE nodes are present in <board>-u-boot.dtsi
 340         * under CONFIG_STM32MP15x_STM32IMAGE only for compatibility
 341         * when FIP is not used by TF-A
 342         */
 343        if (CONFIG_IS_ENABLED(STM32MP15x_STM32IMAGE) &&
 344            !tee_find_device(NULL, NULL, NULL, NULL))
 345                stm32_fdt_disable_optee(blob);
 346
 347        return ret;
 348}
 349