uboot/arch/arm/mach-stm32mp/spl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
   2/*
   3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
   4 */
   5
   6#define LOG_CATEGORY LOGC_ARCH
   7
   8#include <common.h>
   9#include <cpu_func.h>
  10#include <dm.h>
  11#include <hang.h>
  12#include <init.h>
  13#include <log.h>
  14#include <ram.h>
  15#include <spl.h>
  16#include <asm/cache.h>
  17#include <asm/global_data.h>
  18#include <asm/io.h>
  19#include <asm/arch/sys_proto.h>
  20#include <mach/tzc.h>
  21#include <linux/libfdt.h>
  22
  23u32 spl_boot_device(void)
  24{
  25        u32 boot_mode;
  26
  27        boot_mode = get_bootmode();
  28
  29        switch (boot_mode) {
  30        case BOOT_FLASH_SD_1:
  31        case BOOT_FLASH_EMMC_1:
  32                return BOOT_DEVICE_MMC1;
  33        case BOOT_FLASH_SD_2:
  34        case BOOT_FLASH_EMMC_2:
  35                return BOOT_DEVICE_MMC2;
  36        case BOOT_SERIAL_UART_1:
  37        case BOOT_SERIAL_UART_2:
  38        case BOOT_SERIAL_UART_3:
  39        case BOOT_SERIAL_UART_4:
  40        case BOOT_SERIAL_UART_5:
  41        case BOOT_SERIAL_UART_6:
  42        case BOOT_SERIAL_UART_7:
  43        case BOOT_SERIAL_UART_8:
  44                return BOOT_DEVICE_UART;
  45        case BOOT_SERIAL_USB_OTG:
  46                return BOOT_DEVICE_USB;
  47        case BOOT_FLASH_NAND_FMC:
  48                return BOOT_DEVICE_NAND;
  49        case BOOT_FLASH_NOR_QSPI:
  50                return BOOT_DEVICE_SPI;
  51        case BOOT_FLASH_SPINAND_1:
  52                return BOOT_DEVICE_NONE; /* SPINAND not supported in SPL */
  53        }
  54
  55        return BOOT_DEVICE_MMC1;
  56}
  57
  58u32 spl_mmc_boot_mode(const u32 boot_device)
  59{
  60        return MMCSD_MODE_RAW;
  61}
  62
  63#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
  64int spl_mmc_boot_partition(const u32 boot_device)
  65{
  66        switch (boot_device) {
  67        case BOOT_DEVICE_MMC1:
  68                return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;
  69        case BOOT_DEVICE_MMC2:
  70                return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2;
  71        default:
  72                return -EINVAL;
  73        }
  74}
  75#endif
  76
  77#ifdef CONFIG_SPL_DISPLAY_PRINT
  78void spl_display_print(void)
  79{
  80        DECLARE_GLOBAL_DATA_PTR;
  81        const char *model;
  82
  83        /* same code than show_board_info() but not compiled for SPL
  84         * see CONFIG_DISPLAY_BOARDINFO & common/board_info.c
  85         */
  86        model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
  87        if (model)
  88                log_info("Model: %s\n", model);
  89}
  90#endif
  91
  92__weak int board_early_init_f(void)
  93{
  94        return 0;
  95}
  96
  97uint32_t stm32mp_get_dram_size(void)
  98{
  99        struct ram_info ram;
 100        struct udevice *dev;
 101        int ret;
 102
 103        if (uclass_get_device(UCLASS_RAM, 0, &dev))
 104                return 0;
 105
 106        ret = ram_get_info(dev, &ram);
 107        if (ret)
 108                return 0;
 109
 110        return ram.size;
 111}
 112
 113static int optee_get_reserved_memory(uint32_t *start, uint32_t *size)
 114{
 115        phys_size_t fdt_mem_size;
 116        fdt_addr_t fdt_start;
 117        ofnode node;
 118
 119        node = ofnode_path("/reserved-memory/optee");
 120        if (!ofnode_valid(node))
 121                return 0;
 122
 123        fdt_start = ofnode_get_addr_size(node, "reg", &fdt_mem_size);
 124        *start = fdt_start;
 125        *size = fdt_mem_size;
 126        return (fdt_start < 0) ? fdt_start : 0;
 127}
 128
 129#define CFG_SHMEM_SIZE                  0x200000
 130#define STM32_TZC_NSID_ALL              0xffff
 131#define STM32_TZC_FILTER_ALL            3
 132
 133void stm32_init_tzc_for_optee(void)
 134{
 135        const uint32_t dram_size = stm32mp_get_dram_size();
 136        const uintptr_t dram_top = STM32_DDR_BASE + (dram_size - 1);
 137        uint32_t optee_base, optee_size, tee_shmem_base;
 138        const uintptr_t tzc = STM32_TZC_BASE;
 139        int ret;
 140
 141        if (dram_size == 0)
 142                panic("Cannot determine DRAM size from devicetree\n");
 143
 144        ret = optee_get_reserved_memory(&optee_base, &optee_size);
 145        if (ret < 0 || optee_size <= CFG_SHMEM_SIZE)
 146                panic("Invalid OPTEE reserved memory in devicetree\n");
 147
 148        tee_shmem_base = optee_base + optee_size - CFG_SHMEM_SIZE;
 149
 150        const struct tzc_region optee_config[] = {
 151                {
 152                        .base = STM32_DDR_BASE,
 153                        .top = optee_base - 1,
 154                        .sec_mode = TZC_ATTR_SEC_NONE,
 155                        .nsec_id = STM32_TZC_NSID_ALL,
 156                        .filters_mask = STM32_TZC_FILTER_ALL,
 157                }, {
 158                        .base = optee_base,
 159                        .top = tee_shmem_base - 1,
 160                        .sec_mode = TZC_ATTR_SEC_RW,
 161                        .nsec_id = 0,
 162                        .filters_mask = STM32_TZC_FILTER_ALL,
 163                }, {
 164                        .base = tee_shmem_base,
 165                        .top = dram_top,
 166                        .sec_mode = TZC_ATTR_SEC_NONE,
 167                        .nsec_id = STM32_TZC_NSID_ALL,
 168                        .filters_mask = STM32_TZC_FILTER_ALL,
 169                }, {
 170                        .top = 0,
 171                }
 172        };
 173
 174        flush_dcache_all();
 175
 176        tzc_configure(tzc, optee_config);
 177        tzc_dump_config(tzc);
 178
 179        dcache_disable();
 180}
 181
 182void spl_board_prepare_for_optee(void *fdt)
 183{
 184        stm32_init_tzc_for_optee();
 185}
 186
 187void board_init_f(ulong dummy)
 188{
 189        struct udevice *dev;
 190        int ret;
 191
 192        arch_cpu_init();
 193
 194        ret = spl_early_init();
 195        if (ret) {
 196                log_debug("spl_early_init() failed: %d\n", ret);
 197                hang();
 198        }
 199
 200        ret = uclass_get_device(UCLASS_CLK, 0, &dev);
 201        if (ret) {
 202                log_debug("Clock init failed: %d\n", ret);
 203                hang();
 204        }
 205
 206        ret = uclass_get_device(UCLASS_RESET, 0, &dev);
 207        if (ret) {
 208                log_debug("Reset init failed: %d\n", ret);
 209                hang();
 210        }
 211
 212        ret = uclass_get_device(UCLASS_PINCTRL, 0, &dev);
 213        if (ret) {
 214                log_debug("%s: Cannot find pinctrl device\n", __func__);
 215                hang();
 216        }
 217
 218        /* enable console uart printing */
 219        preloader_console_init();
 220
 221        ret = board_early_init_f();
 222        if (ret) {
 223                log_debug("board_early_init_f() failed: %d\n", ret);
 224                hang();
 225        }
 226
 227        ret = uclass_get_device(UCLASS_RAM, 0, &dev);
 228        if (ret) {
 229                log_err("DRAM init failed: %d\n", ret);
 230                hang();
 231        }
 232
 233        /*
 234         * activate cache on DDR only when DDR is fully initialized
 235         * to avoid speculative access and issue in get_ram_size()
 236         */
 237        if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
 238                mmu_set_region_dcache_behaviour(STM32_DDR_BASE,
 239                                                CONFIG_DDR_CACHEABLE_SIZE,
 240                                                DCACHE_DEFAULT_OPTION);
 241}
 242
 243void spl_board_prepare_for_boot(void)
 244{
 245        dcache_disable();
 246}
 247
 248void spl_board_prepare_for_linux(void)
 249{
 250        dcache_disable();
 251}
 252