Browse Source
* changes: mmc: stm32_sdmmc2: correctly manage block size mmc: stm32_sdmmc2: manage max-frequency property from DT stm32mp1: move check_header() to common code stm32mp1: keep console during runtime stm32mp1: sp_min: initialize MMU and cache earlier stm32mp1: add support for LpDDR3 stm32mp1: use a common function to check spinlock is available clk: stm32mp: enable RTCAPB clock for dual-core chips stm32mp1: check if the SoC is single core stm32mp1: print information about board stm32mp1: print information about SoC stm32mp1: add watchdog supportpull/1934/head
Soby Mathew
5 years ago
committed by
TrustedFirmware Code Review
18 changed files with 791 additions and 87 deletions
@ -0,0 +1,150 @@ |
|||
/*
|
|||
* Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
#include <errno.h> |
|||
#include <string.h> |
|||
|
|||
#include <libfdt.h> |
|||
|
|||
#include <platform_def.h> |
|||
|
|||
#include <arch_helpers.h> |
|||
#include <common/debug.h> |
|||
#include <drivers/arm/gicv2.h> |
|||
#include <drivers/delay_timer.h> |
|||
#include <drivers/st/stm32_iwdg.h> |
|||
#include <drivers/st/stm32mp_clkfunc.h> |
|||
#include <lib/mmio.h> |
|||
#include <lib/utils.h> |
|||
#include <plat/common/platform.h> |
|||
|
|||
/* IWDG registers offsets */ |
|||
#define IWDG_KR_OFFSET 0x00U |
|||
|
|||
/* Registers values */ |
|||
#define IWDG_KR_RELOAD_KEY 0xAAAA |
|||
|
|||
struct stm32_iwdg_instance { |
|||
uintptr_t base; |
|||
unsigned long clock; |
|||
uint8_t flags; |
|||
int num_irq; |
|||
}; |
|||
|
|||
static struct stm32_iwdg_instance stm32_iwdg[IWDG_MAX_INSTANCE]; |
|||
|
|||
static int stm32_iwdg_get_dt_node(struct dt_node_info *info, int offset) |
|||
{ |
|||
int node; |
|||
|
|||
node = dt_get_node(info, offset, DT_IWDG_COMPAT); |
|||
if (node < 0) { |
|||
if (offset == -1) { |
|||
VERBOSE("%s: No IDWG found\n", __func__); |
|||
} |
|||
return -FDT_ERR_NOTFOUND; |
|||
} |
|||
|
|||
return node; |
|||
} |
|||
|
|||
void stm32_iwdg_refresh(void) |
|||
{ |
|||
uint8_t i; |
|||
|
|||
for (i = 0U; i < IWDG_MAX_INSTANCE; i++) { |
|||
struct stm32_iwdg_instance *iwdg = &stm32_iwdg[i]; |
|||
|
|||
/* 0x00000000 is not a valid address for IWDG peripherals */ |
|||
if (iwdg->base != 0U) { |
|||
stm32mp_clk_enable(iwdg->clock); |
|||
|
|||
mmio_write_32(iwdg->base + IWDG_KR_OFFSET, |
|||
IWDG_KR_RELOAD_KEY); |
|||
|
|||
stm32mp_clk_disable(iwdg->clock); |
|||
} |
|||
} |
|||
} |
|||
|
|||
int stm32_iwdg_init(void) |
|||
{ |
|||
int node = -1; |
|||
struct dt_node_info dt_info; |
|||
void *fdt; |
|||
uint32_t __unused count = 0; |
|||
|
|||
if (fdt_get_address(&fdt) == 0) { |
|||
panic(); |
|||
} |
|||
|
|||
for (node = stm32_iwdg_get_dt_node(&dt_info, node); |
|||
node != -FDT_ERR_NOTFOUND; |
|||
node = stm32_iwdg_get_dt_node(&dt_info, node)) { |
|||
struct stm32_iwdg_instance *iwdg; |
|||
uint32_t hw_init; |
|||
uint32_t idx; |
|||
|
|||
count++; |
|||
|
|||
idx = stm32_iwdg_get_instance(dt_info.base); |
|||
iwdg = &stm32_iwdg[idx]; |
|||
iwdg->base = dt_info.base; |
|||
iwdg->clock = (unsigned long)dt_info.clock; |
|||
|
|||
/* DT can specify low power cases */ |
|||
if (fdt_getprop(fdt, node, "stm32,enable-on-stop", NULL) == |
|||
NULL) { |
|||
iwdg->flags |= IWDG_DISABLE_ON_STOP; |
|||
} |
|||
|
|||
if (fdt_getprop(fdt, node, "stm32,enable-on-standby", NULL) == |
|||
NULL) { |
|||
iwdg->flags |= IWDG_DISABLE_ON_STANDBY; |
|||
} |
|||
|
|||
/* Explicit list of supported bit flags */ |
|||
hw_init = stm32_iwdg_get_otp_config(idx); |
|||
|
|||
if ((hw_init & IWDG_HW_ENABLED) != 0) { |
|||
if (dt_info.status == DT_DISABLED) { |
|||
ERROR("OTP enabled but iwdg%u DT-disabled\n", |
|||
idx + 1U); |
|||
panic(); |
|||
} |
|||
iwdg->flags |= IWDG_HW_ENABLED; |
|||
} |
|||
|
|||
if (dt_info.status == DT_DISABLED) { |
|||
zeromem((void *)iwdg, |
|||
sizeof(struct stm32_iwdg_instance)); |
|||
continue; |
|||
} |
|||
|
|||
if ((hw_init & IWDG_DISABLE_ON_STOP) != 0) { |
|||
iwdg->flags |= IWDG_DISABLE_ON_STOP; |
|||
} |
|||
|
|||
if ((hw_init & IWDG_DISABLE_ON_STANDBY) != 0) { |
|||
iwdg->flags |= IWDG_DISABLE_ON_STANDBY; |
|||
} |
|||
|
|||
VERBOSE("IWDG%u found, %ssecure\n", idx + 1U, |
|||
((dt_info.status & DT_NON_SECURE) != 0) ? |
|||
"non-" : ""); |
|||
|
|||
#if defined(IMAGE_BL2) |
|||
if (stm32_iwdg_shadow_update(idx, iwdg->flags) != BSEC_OK) { |
|||
return -1; |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
VERBOSE("%u IWDG instance%s found\n", count, (count > 1U) ? "s" : ""); |
|||
|
|||
return 0; |
|||
} |
@ -0,0 +1,19 @@ |
|||
/*
|
|||
* Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef STM32_IWDG_H |
|||
#define STM32_IWDG_H |
|||
|
|||
#include <stdint.h> |
|||
|
|||
#define IWDG_HW_ENABLED BIT(0) |
|||
#define IWDG_DISABLE_ON_STOP BIT(1) |
|||
#define IWDG_DISABLE_ON_STANDBY BIT(2) |
|||
|
|||
int stm32_iwdg_init(void); |
|||
void stm32_iwdg_refresh(void); |
|||
|
|||
#endif /* STM32_IWDG_H */ |
@ -0,0 +1,23 @@ |
|||
/*
|
|||
* Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef STM32MP1_DBGMCU_H |
|||
#define STM32MP1_DBGMCU_H |
|||
|
|||
#include <stdint.h> |
|||
|
|||
/* Get chip version and ID from DBGMCU registers */ |
|||
int stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version); |
|||
int stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id); |
|||
|
|||
/*
|
|||
* Freeze watchdog when a debugger is attached, if the security configuration |
|||
* allows it. |
|||
* Return 0 on success, a negative error value otherwise. |
|||
*/ |
|||
int stm32mp1_dbgmcu_freeze_iwdg2(void); |
|||
|
|||
#endif /* STM32MP1_DBGMCU_H */ |
@ -0,0 +1,96 @@ |
|||
/*
|
|||
* Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <errno.h> |
|||
|
|||
#include <platform_def.h> |
|||
|
|||
#include <common/debug.h> |
|||
#include <drivers/st/bsec.h> |
|||
#include <drivers/st/stm32mp1_rcc.h> |
|||
#include <lib/mmio.h> |
|||
#include <lib/utils_def.h> |
|||
|
|||
#include <stm32mp1_dbgmcu.h> |
|||
|
|||
#define DBGMCU_IDC U(0x00) |
|||
#define DBGMCU_APB4FZ1 U(0x2C) |
|||
|
|||
#define DBGMCU_IDC_DEV_ID_MASK GENMASK(11, 0) |
|||
#define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16) |
|||
#define DBGMCU_IDC_REV_ID_SHIFT 16 |
|||
|
|||
#define DBGMCU_APB4FZ1_IWDG2 BIT(2) |
|||
|
|||
static uintptr_t get_rcc_base(void) |
|||
{ |
|||
/* This is called before stm32mp_rcc_base() is available */ |
|||
return RCC_BASE; |
|||
} |
|||
|
|||
static int stm32mp1_dbgmcu_init(void) |
|||
{ |
|||
uint32_t dbg_conf; |
|||
uintptr_t rcc_base = get_rcc_base(); |
|||
|
|||
dbg_conf = bsec_read_debug_conf(); |
|||
|
|||
if ((dbg_conf & BSEC_DBGSWGEN) == 0U) { |
|||
uint32_t result = bsec_write_debug_conf(dbg_conf | |
|||
BSEC_DBGSWGEN); |
|||
|
|||
if (result != BSEC_OK) { |
|||
ERROR("Error enabling DBGSWGEN\n"); |
|||
return -1; |
|||
} |
|||
} |
|||
|
|||
mmio_setbits_32(rcc_base + RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
int stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version) |
|||
{ |
|||
if (stm32mp1_dbgmcu_init() != 0) { |
|||
return -EPERM; |
|||
} |
|||
|
|||
*chip_version = (mmio_read_32(DBGMCU_BASE + DBGMCU_IDC) & |
|||
DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
int stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id) |
|||
{ |
|||
if (stm32mp1_dbgmcu_init() != 0) { |
|||
return -EPERM; |
|||
} |
|||
|
|||
*chip_dev_id = mmio_read_32(DBGMCU_BASE + DBGMCU_IDC) & |
|||
DBGMCU_IDC_DEV_ID_MASK; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
int stm32mp1_dbgmcu_freeze_iwdg2(void) |
|||
{ |
|||
uint32_t dbg_conf; |
|||
|
|||
if (stm32mp1_dbgmcu_init() != 0) { |
|||
return -EPERM; |
|||
} |
|||
|
|||
dbg_conf = bsec_read_debug_conf(); |
|||
|
|||
if ((dbg_conf & (BSEC_SPIDEN | BSEC_SPINDEN)) != 0U) { |
|||
mmio_setbits_32(DBGMCU_BASE + DBGMCU_APB4FZ1, |
|||
DBGMCU_APB4FZ1_IWDG2); |
|||
} |
|||
|
|||
return 0; |
|||
} |
Loading…
Reference in new issue