aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/st
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/st')
-rw-r--r--drivers/st/clk/stm32mp1_clk.c437
-rw-r--r--drivers/st/clk/stm32mp_clkfunc.c68
-rw-r--r--drivers/st/crypto/stm32_hash.c17
-rw-r--r--drivers/st/ddr/stm32mp1_ram.c26
-rw-r--r--drivers/st/etzpc/etzpc.c258
-rw-r--r--drivers/st/fmc/stm32_fmc2_nand.c112
-rw-r--r--drivers/st/gpio/stm32_gpio.c14
-rw-r--r--drivers/st/io/io_mmc.c21
-rw-r--r--drivers/st/io/io_stm32image.c3
-rw-r--r--drivers/st/iwdg/stm32_iwdg.c6
-rw-r--r--drivers/st/mmc/stm32_sdmmc2.c43
-rw-r--r--drivers/st/pmic/stm32mp_pmic.c24
-rw-r--r--drivers/st/reset/stm32mp1_reset.c35
-rw-r--r--drivers/st/spi/stm32_qspi.c27
-rw-r--r--drivers/st/uart/aarch32/stm32_console.S30
15 files changed, 903 insertions, 218 deletions
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
index 0cc87cc71..564bd8798 100644
--- a/drivers/st/clk/stm32mp1_clk.c
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -16,6 +16,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <common/debug.h>
+#include <common/fdt_wrappers.h>
#include <drivers/delay_timer.h>
#include <drivers/generic_delay_timer.h>
#include <drivers/st/stm32mp_clkfunc.h>
@@ -105,10 +106,62 @@ enum stm32mp1_parent_sel {
_MCUS_SEL,
_USBPHY_SEL,
_USBO_SEL,
+ _MPU_SEL,
+ _PER_SEL,
+ _RTC_SEL,
_PARENT_SEL_NB,
_UNKNOWN_SEL = 0xff,
};
+/* State the parent clock ID straight related to a clock */
+static const uint8_t parent_id_clock_id[_PARENT_NB] = {
+ [_HSE] = CK_HSE,
+ [_HSI] = CK_HSI,
+ [_CSI] = CK_CSI,
+ [_LSE] = CK_LSE,
+ [_LSI] = CK_LSI,
+ [_I2S_CKIN] = _UNKNOWN_ID,
+ [_USB_PHY_48] = _UNKNOWN_ID,
+ [_HSI_KER] = CK_HSI,
+ [_HSE_KER] = CK_HSE,
+ [_HSE_KER_DIV2] = CK_HSE_DIV2,
+ [_CSI_KER] = CK_CSI,
+ [_PLL1_P] = PLL1_P,
+ [_PLL1_Q] = PLL1_Q,
+ [_PLL1_R] = PLL1_R,
+ [_PLL2_P] = PLL2_P,
+ [_PLL2_Q] = PLL2_Q,
+ [_PLL2_R] = PLL2_R,
+ [_PLL3_P] = PLL3_P,
+ [_PLL3_Q] = PLL3_Q,
+ [_PLL3_R] = PLL3_R,
+ [_PLL4_P] = PLL4_P,
+ [_PLL4_Q] = PLL4_Q,
+ [_PLL4_R] = PLL4_R,
+ [_ACLK] = CK_AXI,
+ [_PCLK1] = CK_AXI,
+ [_PCLK2] = CK_AXI,
+ [_PCLK3] = CK_AXI,
+ [_PCLK4] = CK_AXI,
+ [_PCLK5] = CK_AXI,
+ [_CK_PER] = CK_PER,
+ [_CK_MPU] = CK_MPU,
+ [_CK_MCU] = CK_MCU,
+};
+
+static unsigned int clock_id2parent_id(unsigned long id)
+{
+ unsigned int n;
+
+ for (n = 0U; n < ARRAY_SIZE(parent_id_clock_id); n++) {
+ if (parent_id_clock_id[n] == id) {
+ return n;
+ }
+ }
+
+ return _UNKNOWN_ID;
+}
+
enum stm32mp1_pll_id {
_PLL1,
_PLL2,
@@ -258,7 +311,8 @@ struct stm32mp1_clk_pll {
[_ ## _label ## _SEL] = { \
.offset = _rcc_selr, \
.src = _rcc_selr ## _ ## _label ## SRC_SHIFT, \
- .msk = _rcc_selr ## _ ## _label ## SRC_MASK, \
+ .msk = (_rcc_selr ## _ ## _label ## SRC_MASK) >> \
+ (_rcc_selr ## _ ## _label ## SRC_SHIFT), \
.parent = (_parents), \
.nb_parent = ARRAY_SIZE(_parents) \
}
@@ -280,19 +334,6 @@ struct stm32mp1_clk_pll {
.refclk[3] = (p4), \
}
-static const uint8_t stm32mp1_clks[][2] = {
- { CK_PER, _CK_PER },
- { CK_MPU, _CK_MPU },
- { CK_AXI, _ACLK },
- { CK_MCU, _CK_MCU },
- { CK_HSE, _HSE },
- { CK_CSI, _CSI },
- { CK_LSI, _LSI },
- { CK_LSE, _LSE },
- { CK_HSI, _HSI },
- { CK_HSE_DIV2, _HSE_KER_DIV2 },
-};
-
#define NB_GATES ARRAY_SIZE(stm32mp1_clk_gate)
static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
@@ -368,6 +409,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL),
_CLK_SC_SELEC(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL),
+ _CLK_SELEC(RCC_BDCR, 20, RTC, _RTC_SEL),
_CLK_SELEC(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL),
};
@@ -439,6 +481,18 @@ static const uint8_t usbo_parents[] = {
_PLL4_R, _USB_PHY_48
};
+static const uint8_t mpu_parents[] = {
+ _HSI, _HSE, _PLL1_P, _PLL1_P /* specific div */
+};
+
+static const uint8_t per_parents[] = {
+ _HSI, _HSE, _CSI,
+};
+
+static const uint8_t rtc_parents[] = {
+ _UNKNOWN_ID, _LSE, _LSI, _HSE
+};
+
static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
_CLK_PARENT_SEL(I2C12, RCC_I2C12CKSELR, i2c12_parents),
_CLK_PARENT_SEL(I2C35, RCC_I2C35CKSELR, i2c35_parents),
@@ -447,6 +501,9 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
_CLK_PARENT_SEL(SPI6, RCC_SPI6CKSELR, spi6_parents),
_CLK_PARENT_SEL(UART1, RCC_UART1CKSELR, usart1_parents),
_CLK_PARENT_SEL(RNG1, RCC_RNG1CKSELR, rng1_parents),
+ _CLK_PARENT_SEL(MPU, RCC_MPCKSELR, mpu_parents),
+ _CLK_PARENT_SEL(PER, RCC_CPERCKSELR, per_parents),
+ _CLK_PARENT_SEL(RTC, RCC_BDCR, rtc_parents),
_CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents),
_CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents),
_CLK_PARENT_SEL(UART35, RCC_UART35CKSELR, uart234578_parents),
@@ -520,6 +577,43 @@ static const uint8_t stm32mp1_axi_div[8] = {
1, 2, 3, 4, 4, 4, 4, 4
};
+static const char * const stm32mp1_clk_parent_name[_PARENT_NB] __unused = {
+ [_HSI] = "HSI",
+ [_HSE] = "HSE",
+ [_CSI] = "CSI",
+ [_LSI] = "LSI",
+ [_LSE] = "LSE",
+ [_I2S_CKIN] = "I2S_CKIN",
+ [_HSI_KER] = "HSI_KER",
+ [_HSE_KER] = "HSE_KER",
+ [_HSE_KER_DIV2] = "HSE_KER_DIV2",
+ [_CSI_KER] = "CSI_KER",
+ [_PLL1_P] = "PLL1_P",
+ [_PLL1_Q] = "PLL1_Q",
+ [_PLL1_R] = "PLL1_R",
+ [_PLL2_P] = "PLL2_P",
+ [_PLL2_Q] = "PLL2_Q",
+ [_PLL2_R] = "PLL2_R",
+ [_PLL3_P] = "PLL3_P",
+ [_PLL3_Q] = "PLL3_Q",
+ [_PLL3_R] = "PLL3_R",
+ [_PLL4_P] = "PLL4_P",
+ [_PLL4_Q] = "PLL4_Q",
+ [_PLL4_R] = "PLL4_R",
+ [_ACLK] = "ACLK",
+ [_PCLK1] = "PCLK1",
+ [_PCLK2] = "PCLK2",
+ [_PCLK3] = "PCLK3",
+ [_PCLK4] = "PCLK4",
+ [_PCLK5] = "PCLK5",
+ [_HCLK6] = "KCLK6",
+ [_HCLK2] = "HCLK2",
+ [_CK_PER] = "CK_PER",
+ [_CK_MPU] = "CK_MPU",
+ [_CK_MCU] = "CK_MCU",
+ [_USB_PHY_48] = "USB_PHY_48",
+};
+
/* RCC clock device driver private */
static unsigned long stm32mp1_osc[NB_OSC];
static struct spinlock reg_lock;
@@ -559,15 +653,17 @@ static void stm32mp1_clk_unlock(struct spinlock *lock)
bool stm32mp1_rcc_is_secure(void)
{
uintptr_t rcc_base = stm32mp_rcc_base();
+ uint32_t mask = RCC_TZCR_TZEN;
- return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_TZEN) != 0;
+ return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask;
}
bool stm32mp1_rcc_is_mckprot(void)
{
uintptr_t rcc_base = stm32mp_rcc_base();
+ uint32_t mask = RCC_TZCR_TZEN | RCC_TZCR_MCKPROT;
- return (mmio_read_32(rcc_base + RCC_TZCR) & RCC_TZCR_MCKPROT) != 0;
+ return (mmio_read_32(rcc_base + RCC_TZCR) & mask) == mask;
}
void stm32mp1_clk_rcc_regs_lock(void)
@@ -617,16 +713,16 @@ static enum stm32mp1_parent_id stm32mp1_clk_get_fixed_parent(int i)
static int stm32mp1_clk_get_parent(unsigned long id)
{
const struct stm32mp1_clk_sel *sel;
- uint32_t j, p_sel;
+ uint32_t p_sel;
int i;
enum stm32mp1_parent_id p;
enum stm32mp1_parent_sel s;
uintptr_t rcc_base = stm32mp_rcc_base();
- for (j = 0U; j < ARRAY_SIZE(stm32mp1_clks); j++) {
- if (stm32mp1_clks[j][0] == id) {
- return (int)stm32mp1_clks[j][1];
- }
+ /* Few non gateable clock have a static parent ID, find them */
+ i = (int)clock_id2parent_id(id);
+ if (i != _UNKNOWN_ID) {
+ return i;
}
i = stm32mp1_clk_get_gated_id(id);
@@ -648,7 +744,8 @@ static int stm32mp1_clk_get_parent(unsigned long id)
}
sel = clk_sel_ref(s);
- p_sel = (mmio_read_32(rcc_base + sel->offset) & sel->msk) >> sel->src;
+ p_sel = (mmio_read_32(rcc_base + sel->offset) &
+ (sel->msk << sel->src)) >> sel->src;
if (p_sel < sel->nb_parent) {
return (int)sel->parent[p_sel];
}
@@ -930,27 +1027,27 @@ static void __clk_enable(struct stm32mp1_clk_gate const *gate)
{
uintptr_t rcc_base = stm32mp_rcc_base();
+ VERBOSE("Enable clock %u\n", gate->index);
+
if (gate->set_clr != 0U) {
mmio_write_32(rcc_base + gate->offset, BIT(gate->bit));
} else {
mmio_setbits_32(rcc_base + gate->offset, BIT(gate->bit));
}
-
- VERBOSE("Clock %d has been enabled", gate->index);
}
static void __clk_disable(struct stm32mp1_clk_gate const *gate)
{
uintptr_t rcc_base = stm32mp_rcc_base();
+ VERBOSE("Disable clock %u\n", gate->index);
+
if (gate->set_clr != 0U) {
mmio_write_32(rcc_base + gate->offset + RCC_MP_ENCLRR_OFFSET,
BIT(gate->bit));
} else {
mmio_clrbits_32(rcc_base + gate->offset, BIT(gate->bit));
}
-
- VERBOSE("Clock %d has been disabled", gate->index);
}
static bool __clk_is_enabled(struct stm32mp1_clk_gate const *gate)
@@ -971,12 +1068,41 @@ unsigned int stm32mp1_clk_get_refcount(unsigned long id)
return gate_refcounts[i];
}
+/* Oscillators and PLLs are not gated at runtime */
+static bool clock_is_always_on(unsigned long id)
+{
+ switch (id) {
+ case CK_HSE:
+ case CK_CSI:
+ case CK_LSI:
+ case CK_LSE:
+ case CK_HSI:
+ case CK_HSE_DIV2:
+ case PLL1_Q:
+ case PLL1_R:
+ case PLL2_P:
+ case PLL2_Q:
+ case PLL2_R:
+ case PLL3_P:
+ case PLL3_Q:
+ case PLL3_R:
+ return true;
+ default:
+ return false;
+ }
+}
+
void __stm32mp1_clk_enable(unsigned long id, bool secure)
{
const struct stm32mp1_clk_gate *gate;
- int i = stm32mp1_clk_get_gated_id(id);
+ int i;
unsigned int *refcnt;
+ if (clock_is_always_on(id)) {
+ return;
+ }
+
+ i = stm32mp1_clk_get_gated_id(id);
if (i < 0) {
ERROR("Clock %d can't be enabled\n", (uint32_t)id);
panic();
@@ -997,9 +1123,14 @@ void __stm32mp1_clk_enable(unsigned long id, bool secure)
void __stm32mp1_clk_disable(unsigned long id, bool secure)
{
const struct stm32mp1_clk_gate *gate;
- int i = stm32mp1_clk_get_gated_id(id);
+ int i;
unsigned int *refcnt;
+ if (clock_is_always_on(id)) {
+ return;
+ }
+
+ i = stm32mp1_clk_get_gated_id(id);
if (i < 0) {
ERROR("Clock %d can't be disabled\n", (uint32_t)id);
panic();
@@ -1029,8 +1160,13 @@ void stm32mp_clk_disable(unsigned long id)
bool stm32mp_clk_is_enabled(unsigned long id)
{
- int i = stm32mp1_clk_get_gated_id(id);
+ int i;
+
+ if (clock_is_always_on(id)) {
+ return true;
+ }
+ i = stm32mp1_clk_get_gated_id(id);
if (i < 0) {
panic();
}
@@ -1239,7 +1375,8 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id,
uintptr_t clksrc_address = rcc_base + (clksrc >> 4);
unsigned long refclk;
uint32_t ifrge = 0U;
- uint32_t src, value, fracv;
+ uint32_t src, value, fracv = 0;
+ void *fdt;
/* Check PLL output */
if (mmio_read_32(pllxcr) != RCC_PLLNCR_PLLON) {
@@ -1278,7 +1415,9 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id,
}
/* Fractional configuration */
- fracv = fdt_read_uint32_default(plloff, "frac", 0);
+ if (fdt_get_address(&fdt) == 1) {
+ fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0);
+ }
value = fracv << RCC_PLLNFRACR_FRACV_SHIFT;
value |= RCC_PLLNFRACR_FRACLE;
@@ -1525,28 +1664,26 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css)
static void stm32mp1_stgen_config(void)
{
- uintptr_t stgen;
uint32_t cntfid0;
unsigned long rate;
unsigned long long counter;
- stgen = fdt_get_stgen_base();
- cntfid0 = mmio_read_32(stgen + CNTFID_OFF);
+ cntfid0 = mmio_read_32(STGEN_BASE + CNTFID_OFF);
rate = get_clock_rate(stm32mp1_clk_get_parent(STGEN_K));
if (cntfid0 == rate) {
return;
}
- mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN);
- counter = (unsigned long long)mmio_read_32(stgen + CNTCVL_OFF);
- counter |= ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF)) << 32;
+ mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
+ counter = (unsigned long long)mmio_read_32(STGEN_BASE + CNTCVL_OFF);
+ counter |= ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF)) << 32;
counter = (counter * rate / cntfid0);
- mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)counter);
- mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(counter >> 32));
- mmio_write_32(stgen + CNTFID_OFF, rate);
- mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+ mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)counter);
+ mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(counter >> 32));
+ mmio_write_32(STGEN_BASE + CNTFID_OFF, rate);
+ mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
write_cntfrq((u_register_t)rate);
@@ -1556,20 +1693,17 @@ static void stm32mp1_stgen_config(void)
void stm32mp1_stgen_increment(unsigned long long offset_in_ms)
{
- uintptr_t stgen;
unsigned long long cnt;
- stgen = fdt_get_stgen_base();
+ cnt = ((unsigned long long)mmio_read_32(STGEN_BASE + CNTCVU_OFF) << 32) |
+ mmio_read_32(STGEN_BASE + CNTCVL_OFF);
- cnt = ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF) << 32) |
- mmio_read_32(stgen + CNTCVL_OFF);
+ cnt += (offset_in_ms * mmio_read_32(STGEN_BASE + CNTFID_OFF)) / 1000U;
- cnt += (offset_in_ms * mmio_read_32(stgen + CNTFID_OFF)) / 1000U;
-
- mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN);
- mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)cnt);
- mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(cnt >> 32));
- mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+ mmio_clrbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
+ mmio_write_32(STGEN_BASE + CNTCVL_OFF, (uint32_t)cnt);
+ mmio_write_32(STGEN_BASE + CNTCVU_OFF, (uint32_t)(cnt >> 32));
+ mmio_setbits_32(STGEN_BASE + CNTCR_OFF, CNTCR_EN);
}
static void stm32mp1_pkcs_config(uint32_t pkcs)
@@ -1600,20 +1734,25 @@ int stm32mp1_clk_init(void)
bool pll4_preserve = false;
bool pll4_bootrom = false;
const fdt32_t *pkcs_cell;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return false;
+ }
/* Check status field to disable security */
if (!fdt_get_rcc_secure_status()) {
mmio_write_32(rcc_base + RCC_TZCR, 0);
}
- ret = fdt_rcc_read_uint32_array("st,clksrc", clksrc,
- (uint32_t)CLKSRC_NB);
+ ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB,
+ clksrc);
if (ret < 0) {
return -FDT_ERR_NOTFOUND;
}
- ret = fdt_rcc_read_uint32_array("st,clkdiv", clkdiv,
- (uint32_t)CLKDIV_NB);
+ ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB,
+ clkdiv);
if (ret < 0) {
return -FDT_ERR_NOTFOUND;
}
@@ -1628,8 +1767,8 @@ int stm32mp1_clk_init(void)
continue;
}
- ret = fdt_read_uint32_array(plloff[i], "cfg",
- pllcfg[i], (int)PLLCFG_NB);
+ ret = fdt_read_uint32_array(fdt, plloff[i], "cfg",
+ (int)PLLCFG_NB, pllcfg[i]);
if (ret < 0) {
return -FDT_ERR_NOTFOUND;
}
@@ -1794,14 +1933,14 @@ int stm32mp1_clk_init(void)
continue;
}
- fracv = fdt_read_uint32_default(plloff[i], "frac", 0);
+ fracv = fdt_read_uint32_default(fdt, plloff[i], "frac", 0);
ret = stm32mp1_pll_config(i, pllcfg[i], fracv);
if (ret != 0) {
return ret;
}
- ret = fdt_read_uint32_array(plloff[i], "csg", csg,
- (uint32_t)PLLCSG_NB);
+ ret = fdt_read_uint32_array(fdt, plloff[i], "csg",
+ (uint32_t)PLLCSG_NB, csg);
if (ret == 0) {
stm32mp1_pll_csg(i, csg);
} else if (ret != -FDT_ERR_NOTFOUND) {
@@ -1902,8 +2041,184 @@ static void stm32mp1_osc_init(void)
}
}
+#ifdef STM32MP_SHARED_RESOURCES
+/*
+ * Get the parent ID of the target parent clock, for tagging as secure
+ * shared clock dependencies.
+ */
+static int get_parent_id_parent(unsigned int parent_id)
+{
+ enum stm32mp1_parent_sel s = _UNKNOWN_SEL;
+ enum stm32mp1_pll_id pll_id;
+ uint32_t p_sel;
+ uintptr_t rcc_base = stm32mp_rcc_base();
+
+ switch (parent_id) {
+ case _ACLK:
+ case _PCLK4:
+ case _PCLK5:
+ s = _AXIS_SEL;
+ break;
+ case _PLL1_P:
+ case _PLL1_Q:
+ case _PLL1_R:
+ pll_id = _PLL1;
+ break;
+ case _PLL2_P:
+ case _PLL2_Q:
+ case _PLL2_R:
+ pll_id = _PLL2;
+ break;
+ case _PLL3_P:
+ case _PLL3_Q:
+ case _PLL3_R:
+ pll_id = _PLL3;
+ break;
+ case _PLL4_P:
+ case _PLL4_Q:
+ case _PLL4_R:
+ pll_id = _PLL4;
+ break;
+ case _PCLK1:
+ case _PCLK2:
+ case _HCLK2:
+ case _HCLK6:
+ case _CK_PER:
+ case _CK_MPU:
+ case _CK_MCU:
+ case _USB_PHY_48:
+ /* We do not expect to access these */
+ panic();
+ break;
+ default:
+ /* Other parents have no parent */
+ return -1;
+ }
+
+ if (s != _UNKNOWN_SEL) {
+ const struct stm32mp1_clk_sel *sel = clk_sel_ref(s);
+
+ p_sel = (mmio_read_32(rcc_base + sel->offset) >> sel->src) &
+ sel->msk;
+
+ if (p_sel < sel->nb_parent) {
+ return (int)sel->parent[p_sel];
+ }
+ } else {
+ const struct stm32mp1_clk_pll *pll = pll_ref(pll_id);
+
+ p_sel = mmio_read_32(rcc_base + pll->rckxselr) &
+ RCC_SELR_REFCLK_SRC_MASK;
+
+ if (pll->refclk[p_sel] != _UNKNOWN_OSC_ID) {
+ return (int)pll->refclk[p_sel];
+ }
+ }
+
+ VERBOSE("No parent selected for %s\n",
+ stm32mp1_clk_parent_name[parent_id]);
+
+ return -1;
+}
+
+static void secure_parent_clocks(unsigned long parent_id)
+{
+ int grandparent_id;
+
+ switch (parent_id) {
+ case _PLL3_P:
+ case _PLL3_Q:
+ case _PLL3_R:
+ stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3);
+ break;
+
+ /* These clocks are always secure when RCC is secure */
+ case _ACLK:
+ case _HCLK2:
+ case _HCLK6:
+ case _PCLK4:
+ case _PCLK5:
+ case _PLL1_P:
+ case _PLL1_Q:
+ case _PLL1_R:
+ case _PLL2_P:
+ case _PLL2_Q:
+ case _PLL2_R:
+ case _HSI:
+ case _HSI_KER:
+ case _LSI:
+ case _CSI:
+ case _CSI_KER:
+ case _HSE:
+ case _HSE_KER:
+ case _HSE_KER_DIV2:
+ case _LSE:
+ break;
+
+ default:
+ VERBOSE("Cannot secure parent clock %s\n",
+ stm32mp1_clk_parent_name[parent_id]);
+ panic();
+ }
+
+ grandparent_id = get_parent_id_parent(parent_id);
+ if (grandparent_id >= 0) {
+ secure_parent_clocks(grandparent_id);
+ }
+}
+
+void stm32mp1_register_clock_parents_secure(unsigned long clock_id)
+{
+ int parent_id;
+
+ if (!stm32mp1_rcc_is_secure()) {
+ return;
+ }
+
+ switch (clock_id) {
+ case PLL1:
+ case PLL2:
+ /* PLL1/PLL2 are always secure: nothing to do */
+ break;
+ case PLL3:
+ stm32mp_register_secure_periph(STM32MP1_SHRES_PLL3);
+ break;
+ case PLL4:
+ ERROR("PLL4 cannot be secured\n");
+ panic();
+ break;
+ default:
+ /* Others are expected gateable clock */
+ parent_id = stm32mp1_clk_get_parent(clock_id);
+ if (parent_id < 0) {
+ INFO("No parent found for clock %lu\n", clock_id);
+ } else {
+ secure_parent_clocks(parent_id);
+ }
+ break;
+ }
+}
+#endif /* STM32MP_SHARED_RESOURCES */
+
static void sync_earlyboot_clocks_state(void)
{
+ unsigned int idx;
+ const unsigned long secure_enable[] = {
+ AXIDCG,
+ BSEC,
+ DDRC1, DDRC1LP,
+ DDRC2, DDRC2LP,
+ DDRCAPB, DDRPHYCAPB, DDRPHYCAPBLP,
+ DDRPHYC, DDRPHYCLP,
+ TZC1, TZC2,
+ TZPC,
+ STGEN_K,
+ };
+
+ for (idx = 0U; idx < ARRAY_SIZE(secure_enable); idx++) {
+ stm32mp_clk_enable(secure_enable[idx]);
+ }
+
if (!stm32mp_is_single_core()) {
stm32mp1_clk_enable_secure(RTCAPB);
}
diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c
index 87c8e2b84..8333f6dfb 100644
--- a/drivers/st/clk/stm32mp_clkfunc.c
+++ b/drivers/st/clk/stm32mp_clkfunc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,11 +10,10 @@
#include <platform_def.h>
+#include <common/fdt_wrappers.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32mp_clkfunc.h>
-#define DT_STGEN_COMPAT "st,stm32-stgen"
-
/*
* Get the frequency of an oscillator from its name in device tree.
* @param name: oscillator name
@@ -150,7 +149,8 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
continue;
}
- return fdt_read_uint32_default(subnode, prop_name, dflt_value);
+ return fdt_read_uint32_default(fdt, subnode, prop_name,
+ dflt_value);
}
return dflt_value;
@@ -167,41 +167,14 @@ int fdt_get_rcc_node(void *fdt)
}
/*
- * Get the RCC base address from the device tree
- * @return: RCC address or 0 on error
- */
-uint32_t fdt_rcc_read_addr(void)
-{
- int node;
- void *fdt;
- const fdt32_t *cuint;
-
- if (fdt_get_address(&fdt) == 0) {
- return 0;
- }
-
- node = fdt_get_rcc_node(fdt);
- if (node < 0) {
- return 0;
- }
-
- cuint = fdt_getprop(fdt, node, "reg", NULL);
- if (cuint == NULL) {
- return 0;
- }
-
- return fdt32_to_cpu(*cuint);
-}
-
-/*
* Read a series of parameters in rcc-clk section in device tree
* @param prop_name: Name of the RCC property to be read
* @param array: the array to store the property parameters
* @param count: number of parameters to be read
* @return: 0 on succes or a negative value on error
*/
-int fdt_rcc_read_uint32_array(const char *prop_name,
- uint32_t *array, uint32_t count)
+int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count,
+ uint32_t *array)
{
int node;
void *fdt;
@@ -215,7 +188,7 @@ int fdt_rcc_read_uint32_array(const char *prop_name,
return -FDT_ERR_NOTFOUND;
}
- return fdt_read_uint32_array(node, prop_name, array, count);
+ return fdt_read_uint32_array(fdt, node, prop_name, count, array);
}
/*
@@ -297,33 +270,6 @@ bool fdt_get_rcc_secure_status(void)
}
/*
- * Get the stgen base address.
- * @return: address of stgen on success, and NULL value on failure.
- */
-uintptr_t fdt_get_stgen_base(void)
-{
- int node;
- const fdt32_t *cuint;
- void *fdt;
-
- if (fdt_get_address(&fdt) == 0) {
- return 0;
- }
-
- node = fdt_node_offset_by_compatible(fdt, -1, DT_STGEN_COMPAT);
- if (node < 0) {
- return 0;
- }
-
- cuint = fdt_getprop(fdt, node, "reg", NULL);
- if (cuint == NULL) {
- return 0;
- }
-
- return fdt32_to_cpu(*cuint);
-}
-
-/*
* Get the clock ID of the given node in device tree.
* @param node: node offset
* @return: Clock ID on success, and a negative FDT/ERRNO error code on failure.
diff --git a/drivers/st/crypto/stm32_hash.c b/drivers/st/crypto/stm32_hash.c
index f72787d33..317fd9eb8 100644
--- a/drivers/st/crypto/stm32_hash.c
+++ b/drivers/st/crypto/stm32_hash.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -51,6 +51,7 @@
#define SHA224_DIGEST_SIZE 28U
#define SHA256_DIGEST_SIZE 32U
+#define RESET_TIMEOUT_US_1MS 1000U
#define HASH_TIMEOUT_US 10000U
enum stm32_hash_data_format {
@@ -251,6 +252,8 @@ int stm32_hash_final(uint8_t *digest)
mmio_clrsetbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK,
8U * stm32_remain.length);
zeromem(&stm32_remain, sizeof(stm32_remain));
+ } else {
+ mmio_clrbits_32(hash_base() + HASH_STR, HASH_STR_NBLW_MASK);
}
mmio_setbits_32(hash_base() + HASH_STR, HASH_STR_DCAL);
@@ -299,7 +302,9 @@ int stm32_hash_register(void)
break;
}
#else
+ /* BL32 uses hash if it is assigned only to secure world */
if (hash_info.status == DT_SECURE) {
+ stm32mp_register_secure_periph_iomem(hash_info.base);
break;
}
#endif
@@ -319,9 +324,15 @@ int stm32_hash_register(void)
stm32mp_clk_enable(stm32_hash.clock);
if (hash_info.reset >= 0) {
- stm32mp_reset_assert((unsigned long)hash_info.reset);
+ uint32_t id = (uint32_t)hash_info.reset;
+
+ if (stm32mp_reset_assert(id, RESET_TIMEOUT_US_1MS) != 0) {
+ panic();
+ }
udelay(20);
- stm32mp_reset_deassert((unsigned long)hash_info.reset);
+ if (stm32mp_reset_deassert(id, RESET_TIMEOUT_US_1MS) != 0) {
+ panic();
+ }
}
stm32mp_clk_disable(stm32_hash.clock);
diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c
index 4ae55fcc7..b21c8949f 100644
--- a/drivers/st/ddr/stm32mp1_ram.c
+++ b/drivers/st/ddr/stm32mp1_ram.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2018-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -12,6 +12,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <common/fdt_wrappers.h>
#include <drivers/st/stm32mp1_ddr.h>
#include <drivers/st/stm32mp1_ddr_helpers.h>
#include <drivers/st/stm32mp1_ram.h>
@@ -205,13 +206,13 @@ static int stm32mp1_ddr_setup(void)
return -EINVAL;
}
- config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0);
- if (!config.info.speed) {
+ ret = fdt_read_uint32(fdt, node, "st,mem-speed", &config.info.speed);
+ if (ret < 0) {
VERBOSE("%s: no st,mem-speed\n", __func__);
return -EINVAL;
}
- config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0);
- if (!config.info.size) {
+ ret = fdt_read_uint32(fdt, node, "st,mem-size", &config.info.size);
+ if (ret < 0) {
VERBOSE("%s: no st,mem-size\n", __func__);
return -EINVAL;
}
@@ -223,10 +224,10 @@ static int stm32mp1_ddr_setup(void)
INFO("RAM: %s\n", config.info.name);
for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
- ret = fdt_read_uint32_array(node, param[idx].name,
+ ret = fdt_read_uint32_array(fdt, node, param[idx].name,
+ param[idx].size,
(void *)((uintptr_t)&config +
- param[idx].offset),
- param[idx].size);
+ param[idx].offset));
VERBOSE("%s: %s[0x%x] = %d\n", __func__,
param[idx].name, param[idx].size, ret);
@@ -250,8 +251,9 @@ static int stm32mp1_ddr_setup(void)
VERBOSE("%s : ram size(%x, %x)\n", __func__,
(uint32_t)priv->info.base, (uint32_t)priv->info.size);
- write_sctlr(read_sctlr() & ~SCTLR_C_BIT);
- dcsw_op_all(DC_OP_CISW);
+ if (stm32mp_map_ddr_non_cacheable() != 0) {
+ panic();
+ }
uret = ddr_test_data_bus();
if (uret != 0U) {
@@ -274,7 +276,9 @@ static int stm32mp1_ddr_setup(void)
panic();
}
- write_sctlr(read_sctlr() | SCTLR_C_BIT);
+ if (stm32mp_unmap_ddr() != 0) {
+ panic();
+ }
return 0;
}
diff --git a/drivers/st/etzpc/etzpc.c b/drivers/st/etzpc/etzpc.c
new file mode 100644
index 000000000..ff52a22d9
--- /dev/null
+++ b/drivers/st/etzpc/etzpc.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <drivers/st/etzpc.h>
+#include <dt-bindings/soc/st,stm32-etzpc.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+/* Device Tree related definitions */
+#define ETZPC_COMPAT "st,stm32-etzpc"
+#define ETZPC_LOCK_MASK 0x1U
+#define ETZPC_MODE_SHIFT 8
+#define ETZPC_MODE_MASK GENMASK(1, 0)
+#define ETZPC_ID_SHIFT 16
+#define ETZPC_ID_MASK GENMASK(7, 0)
+
+/* ID Registers */
+#define ETZPC_TZMA0_SIZE 0x000U
+#define ETZPC_DECPROT0 0x010U
+#define ETZPC_DECPROT_LOCK0 0x030U
+#define ETZPC_HWCFGR 0x3F0U
+#define ETZPC_VERR 0x3F4U
+
+/* ID Registers fields */
+#define ETZPC_TZMA0_SIZE_LOCK BIT(31)
+#define ETZPC_DECPROT0_MASK GENMASK(1, 0)
+#define ETZPC_HWCFGR_NUM_TZMA_SHIFT 0
+#define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT 8
+#define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT 16
+#define ETZPC_HWCFGR_CHUNCKS1N4_SHIFT 24
+
+#define DECPROT_SHIFT 1
+#define IDS_PER_DECPROT_REGS 16U
+#define IDS_PER_DECPROT_LOCK_REGS 32U
+
+/*
+ * etzpc_instance.
+ * base : register base address set during init given by user
+ * chunk_size : supported TZMA size steps
+ * num_tzma: number of TZMA zone read from register at init
+ * num_ahb_sec : number of securable AHB master zone read from register
+ * num_per_sec : number of securable AHB & APB Peripherals read from register
+ * revision : IP revision read from register at init
+ */
+struct etzpc_instance {
+ uintptr_t base;
+ uint8_t chunck_size;
+ uint8_t num_tzma;
+ uint8_t num_per_sec;
+ uint8_t num_ahb_sec;
+ uint8_t revision;
+};
+
+/* Only 1 instance of the ETZPC is expected per platform */
+static struct etzpc_instance etzpc_dev;
+
+/*
+ * Implementation uses uint8_t to store each securable DECPROT configuration.
+ * When resuming from deep suspend, the DECPROT configurations are restored.
+ */
+#define PERIPH_LOCK_BIT BIT(7)
+#define PERIPH_ATTR_MASK GENMASK(2, 0)
+
+#if ENABLE_ASSERTIONS
+static bool valid_decprot_id(unsigned int id)
+{
+ return id < (unsigned int)etzpc_dev.num_per_sec;
+}
+
+static bool valid_tzma_id(unsigned int id)
+{
+ return id < (unsigned int)etzpc_dev.num_tzma;
+}
+#endif
+
+/*
+ * etzpc_configure_decprot : Load a DECPROT configuration
+ * decprot_id : ID of the IP
+ * decprot_attr : Restriction access attribute
+ */
+void etzpc_configure_decprot(uint32_t decprot_id,
+ enum etzpc_decprot_attributes decprot_attr)
+{
+ uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS);
+ uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
+ uint32_t masked_decprot = (uint32_t)decprot_attr & ETZPC_DECPROT0_MASK;
+
+ assert(valid_decprot_id(decprot_id));
+
+ mmio_clrsetbits_32(etzpc_dev.base + ETZPC_DECPROT0 + offset,
+ (uint32_t)ETZPC_DECPROT0_MASK << shift,
+ masked_decprot << shift);
+}
+
+/*
+ * etzpc_get_decprot : Get the DECPROT attribute
+ * decprot_id : ID of the IP
+ * return : Attribute of this DECPROT
+ */
+enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id)
+{
+ uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_REGS);
+ uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT;
+ uintptr_t base_decprot = etzpc_dev.base + offset;
+ uint32_t value;
+
+ assert(valid_decprot_id(decprot_id));
+
+ value = (mmio_read_32(base_decprot + ETZPC_DECPROT0) >> shift) &
+ ETZPC_DECPROT0_MASK;
+
+ return (enum etzpc_decprot_attributes)value;
+}
+
+/*
+ * etzpc_lock_decprot : Lock access to the DECPROT attribute
+ * decprot_id : ID of the IP
+ */
+void etzpc_lock_decprot(uint32_t decprot_id)
+{
+ uintptr_t offset = 4U * (decprot_id / IDS_PER_DECPROT_LOCK_REGS);
+ uint32_t shift = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS);
+ uintptr_t base_decprot = etzpc_dev.base + offset;
+
+ assert(valid_decprot_id(decprot_id));
+
+ mmio_write_32(base_decprot + ETZPC_DECPROT_LOCK0, shift);
+}
+
+/*
+ * etzpc_configure_tzma : Configure the target TZMA read only size
+ * tzma_id : ID of the memory
+ * tzma_value : read-only size
+ */
+void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value)
+{
+ assert(valid_tzma_id(tzma_id));
+
+ mmio_write_32(etzpc_dev.base + ETZPC_TZMA0_SIZE +
+ (sizeof(uint32_t) * tzma_id), tzma_value);
+}
+
+/*
+ * etzpc_get_tzma : Get the target TZMA read only size
+ * tzma_id : TZMA ID
+ * return : Size of read only size
+ */
+uint16_t etzpc_get_tzma(uint32_t tzma_id)
+{
+ assert(valid_tzma_id(tzma_id));
+
+ return (uint16_t)mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE +
+ (sizeof(uint32_t) * tzma_id));
+}
+
+/*
+ * etzpc_lock_tzma : Lock the target TZMA
+ * tzma_id : TZMA ID
+ */
+void etzpc_lock_tzma(uint32_t tzma_id)
+{
+ assert(valid_tzma_id(tzma_id));
+
+ mmio_setbits_32(etzpc_dev.base + ETZPC_TZMA0_SIZE +
+ (sizeof(uint32_t) * tzma_id), ETZPC_TZMA0_SIZE_LOCK);
+}
+
+/*
+ * etzpc_get_lock_tzma : Return the lock status of the target TZMA
+ * tzma_id : TZMA ID
+ * return : True if TZMA is locked, false otherwise
+ */
+bool etzpc_get_lock_tzma(uint32_t tzma_id)
+{
+ uint32_t tzma_size;
+
+ assert(valid_tzma_id(tzma_id));
+
+ tzma_size = mmio_read_32(etzpc_dev.base + ETZPC_TZMA0_SIZE +
+ (sizeof(uint32_t) * tzma_id));
+
+ return (tzma_size & ETZPC_TZMA0_SIZE_LOCK) != 0;
+}
+
+/*
+ * etzpc_get_num_per_sec : Return the DECPROT ID limit value
+ */
+uint8_t etzpc_get_num_per_sec(void)
+{
+ return etzpc_dev.num_per_sec;
+}
+
+/*
+ * etzpc_get_revision : Return the ETZPC IP revision
+ */
+uint8_t etzpc_get_revision(void)
+{
+ return etzpc_dev.revision;
+}
+
+/*
+ * etzpc_get_base_address : Return the ETZPC IP base address
+ */
+uintptr_t etzpc_get_base_address(void)
+{
+ return etzpc_dev.base;
+}
+
+/*
+ * etzpc_init : Initialize the ETZPC driver
+ * Return 0 on success and a negative errno on failure
+ */
+int etzpc_init(void)
+{
+ uint32_t hwcfg;
+ int node;
+ struct dt_node_info etzpc_info;
+
+ node = dt_get_node(&etzpc_info, -1, ETZPC_COMPAT);
+ if (node < 0) {
+ return -EIO;
+ }
+
+ /* Check ETZPC is secure only */
+ if (etzpc_info.status != DT_SECURE) {
+ return -EACCES;
+ }
+
+ etzpc_dev.base = etzpc_info.base;
+
+ hwcfg = mmio_read_32(etzpc_dev.base + ETZPC_HWCFGR);
+
+ etzpc_dev.num_tzma = (uint8_t)(hwcfg >> ETZPC_HWCFGR_NUM_TZMA_SHIFT);
+ etzpc_dev.num_per_sec = (uint8_t)(hwcfg >>
+ ETZPC_HWCFGR_NUM_PER_SEC_SHIFT);
+ etzpc_dev.num_ahb_sec = (uint8_t)(hwcfg >>
+ ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT);
+ etzpc_dev.chunck_size = (uint8_t)(hwcfg >>
+ ETZPC_HWCFGR_CHUNCKS1N4_SHIFT);
+
+ etzpc_dev.revision = mmio_read_8(etzpc_dev.base + ETZPC_VERR);
+
+ VERBOSE("ETZPC version 0x%x", etzpc_dev.revision);
+
+ return 0;
+}
diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c
index b694fff6b..a58a243ad 100644
--- a/drivers/st/fmc/stm32_fmc2_nand.c
+++ b/drivers/st/fmc/stm32_fmc2_nand.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -22,9 +22,14 @@
#include <lib/mmio.h>
#include <lib/utils_def.h>
+/* Timeout for device interface reset */
+#define TIMEOUT_US_1_MS 1000U
+
/* FMC2 Compatibility */
-#define DT_FMC2_COMPAT "st,stm32mp15-fmc2"
+#define DT_FMC2_EBI_COMPAT "st,stm32mp1-fmc2-ebi"
+#define DT_FMC2_NFC_COMPAT "st,stm32mp1-fmc2-nfc"
#define MAX_CS 2U
+#define MAX_BANK 5U
/* FMC2 Controller Registers */
#define FMC2_BCR1 0x00U
@@ -34,6 +39,7 @@
#define FMC2_PATT 0x8CU
#define FMC2_HECCR 0x94U
#define FMC2_BCHISR 0x254U
+#define FMC2_BCHICR 0x258U
#define FMC2_BCHDSR0 0x27CU
#define FMC2_BCHDSR1 0x280U
#define FMC2_BCHDSR2 0x284U
@@ -79,6 +85,8 @@
#define FMC2_PATT_DEFAULT 0x0A0A0A0AU
/* FMC2_BCHISR register */
#define FMC2_BCHISR_DERF BIT(1)
+/* FMC2_BCHICR register */
+#define FMC2_BCHICR_CLEAR_IRQ GENMASK_32(4, 0)
/* FMC2_BCHDSR0 register */
#define FMC2_BCHDSR0_DUE BIT(0)
#define FMC2_BCHDSR0_DEF BIT(1)
@@ -365,7 +373,7 @@ static int stm32_fmc2_ham_correct(uint8_t *buffer, uint8_t *eccbuffer,
xor_ecc_2b = ecc[1] ^ eccbuffer[1];
xor_ecc_3b = ecc[2] ^ eccbuffer[2];
- xor_ecc.val = 0L;
+ xor_ecc.val = 0U;
xor_ecc.bytes[2] = xor_ecc_3b;
xor_ecc.bytes[1] = xor_ecc_2b;
xor_ecc.bytes[0] = xor_ecc_1b;
@@ -497,6 +505,7 @@ static void stm32_fmc2_hwctl(struct nand_device *nand)
if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) {
mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN);
+ mmio_write_32(fmc2_base() + FMC2_BCHICR, FMC2_BCHICR_CLEAR_IRQ);
}
stm32_fmc2_set_ecc(true);
@@ -786,22 +795,26 @@ static const struct nand_ctrl_ops ctrl_ops = {
int stm32_fmc2_init(void)
{
- int fmc_node;
- int fmc_subnode = 0;
+ int fmc_ebi_node;
+ int fmc_nfc_node;
+ int fmc_flash_node = 0;
int nchips = 0;
unsigned int i;
void *fdt = NULL;
const fdt32_t *cuint;
struct dt_node_info info;
+ uintptr_t bank_address[MAX_BANK] = { 0, 0, 0, 0, 0 };
+ uint8_t bank_assigned = 0;
+ uint8_t bank;
+ int ret;
if (fdt_get_address(&fdt) == 0) {
return -FDT_ERR_NOTFOUND;
}
- fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT);
- if (fmc_node == -FDT_ERR_NOTFOUND) {
- WARN("No FMC2 node found\n");
- return fmc_node;
+ fmc_ebi_node = dt_get_node(&info, -1, DT_FMC2_EBI_COMPAT);
+ if (fmc_ebi_node < 0) {
+ return fmc_ebi_node;
}
if (info.status == DT_DISABLED) {
@@ -817,27 +830,69 @@ int stm32_fmc2_init(void)
stm32_fmc2.clock_id = (unsigned long)info.clock;
stm32_fmc2.reset_id = (unsigned int)info.reset;
- cuint = fdt_getprop(fdt, fmc_node, "reg", NULL);
+ cuint = fdt_getprop(fdt, fmc_ebi_node, "ranges", NULL);
if (cuint == NULL) {
return -FDT_ERR_BADVALUE;
}
- cuint += 2;
-
- for (i = 0U; i < MAX_CS; i++) {
- stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint);
- stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2));
- stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4));
- cuint += 6;
+ for (i = 0U; i < MAX_BANK; i++) {
+ bank = fdt32_to_cpu(*cuint);
+ if ((bank >= MAX_BANK) || ((bank_assigned & BIT(bank)) != 0U)) {
+ return -FDT_ERR_BADVALUE;
+ }
+ bank_assigned |= BIT(bank);
+ bank_address[bank] = fdt32_to_cpu(*(cuint + 2));
+ cuint += 4;
}
/* Pinctrl initialization */
- if (dt_set_pinctrl_config(fmc_node) != 0) {
+ if (dt_set_pinctrl_config(fmc_ebi_node) != 0) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ /* Parse NFC controller node */
+ fmc_nfc_node = fdt_node_offset_by_compatible(fdt, fmc_ebi_node,
+ DT_FMC2_NFC_COMPAT);
+ if (fmc_nfc_node < 0) {
+ return fmc_nfc_node;
+ }
+
+ if (fdt_get_status(fmc_nfc_node) == DT_DISABLED) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ cuint = fdt_getprop(fdt, fmc_nfc_node, "reg", NULL);
+ if (cuint == NULL) {
return -FDT_ERR_BADVALUE;
}
+ for (i = 0U; i < MAX_CS; i++) {
+ bank = fdt32_to_cpu(*cuint);
+ if (bank >= MAX_BANK) {
+ return -FDT_ERR_BADVALUE;
+ }
+ stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*(cuint + 1)) +
+ bank_address[bank];
+
+ bank = fdt32_to_cpu(*(cuint + 3));
+ if (bank >= MAX_BANK) {
+ return -FDT_ERR_BADVALUE;
+ }
+ stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 4)) +
+ bank_address[bank];
+
+ bank = fdt32_to_cpu(*(cuint + 6));
+ if (bank >= MAX_BANK) {
+ return -FDT_ERR_BADVALUE;
+ }
+ stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 7)) +
+ bank_address[bank];
+
+ cuint += 9;
+ }
+
/* Parse flash nodes */
- fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) {
+ fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) {
nchips++;
}
@@ -846,14 +901,19 @@ int stm32_fmc2_init(void)
return -FDT_ERR_BADVALUE;
}
- fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) {
+ fdt_for_each_subnode(fmc_flash_node, fdt, fmc_nfc_node) {
/* Get chip select */
- cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL);
+ cuint = fdt_getprop(fdt, fmc_flash_node, "reg", NULL);
if (cuint == NULL) {
WARN("Chip select not well defined\n");
return -FDT_ERR_BADVALUE;
}
+
stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint);
+ if (stm32_fmc2.cs_sel >= MAX_CS) {
+ return -FDT_ERR_BADVALUE;
+ }
+
VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel);
}
@@ -861,8 +921,14 @@ int stm32_fmc2_init(void)
stm32mp_clk_enable(stm32_fmc2.clock_id);
/* Reset IP */
- stm32mp_reset_assert(stm32_fmc2.reset_id);
- stm32mp_reset_deassert(stm32_fmc2.reset_id);
+ ret = stm32mp_reset_assert(stm32_fmc2.reset_id, TIMEOUT_US_1_MS);
+ if (ret != 0) {
+ panic();
+ }
+ ret = stm32mp_reset_deassert(stm32_fmc2.reset_id, TIMEOUT_US_1_MS);
+ if (ret != 0) {
+ panic();
+ }
/* Setup default IP registers */
stm32_fmc2_ctrl_init();
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
index a13c341a8..7d63262d7 100644
--- a/drivers/st/gpio/stm32_gpio.c
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2016-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -161,13 +161,14 @@ int dt_set_pinctrl_config(int node)
const fdt32_t *cuint;
int lenp = 0;
uint32_t i;
- uint8_t status = fdt_get_status(node);
+ uint8_t status;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return -FDT_ERR_NOTFOUND;
}
+ status = fdt_get_status(node);
if (status == DT_DISABLED) {
return -FDT_ERR_NOTFOUND;
}
@@ -254,6 +255,15 @@ void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
mmio_read_32(base + GPIO_AFRH_OFFSET));
stm32mp_clk_disable(clock);
+
+ if (status == DT_SECURE) {
+ stm32mp_register_secure_gpio(bank, pin);
+ set_gpio_secure_cfg(bank, pin, true);
+
+ } else {
+ stm32mp_register_non_secure_gpio(bank, pin);
+ set_gpio_secure_cfg(bank, pin, false);
+ }
}
void set_gpio_secure_cfg(uint32_t bank, uint32_t pin, bool secure)
diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c
index 44b7d1907..0ed71540c 100644
--- a/drivers/st/io/io_mmc.c
+++ b/drivers/st/io/io_mmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -97,14 +97,21 @@ static int mmc_block_seek(io_entity_t *entity, int mode,
static int mmc_block_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read)
{
- *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE,
- buffer, length);
-
- if (*length_read != length) {
- return -EIO;
+ uint8_t retries;
+
+ for (retries = 0U; retries < 3U; retries++) {
+ *length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE,
+ buffer, length);
+
+ if (*length_read == length) {
+ return 0;
+ }
+ WARN("%s: length_read = %lu (!= %lu), retry %u\n", __func__,
+ (unsigned long)*length_read, (unsigned long)length,
+ retries + 1U);
}
- return 0;
+ return -EIO;
}
/* Close a file on the mmc device */
diff --git a/drivers/st/io/io_stm32image.c b/drivers/st/io/io_stm32image.c
index 413521b1e..3e377cd48 100644
--- a/drivers/st/io/io_stm32image.c
+++ b/drivers/st/io/io_stm32image.c
@@ -247,7 +247,7 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read)
{
int result;
- uint8_t *local_buffer = (uint8_t *)buffer;
+ uint8_t *local_buffer;
boot_api_image_header_t *header =
(boot_api_image_header_t *)first_lba_buffer;
@@ -255,6 +255,7 @@ static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
assert(buffer != 0U);
assert(length_read != NULL);
+ local_buffer = (uint8_t *)buffer;
*length_read = 0U;
while (*length_read == 0U) {
diff --git a/drivers/st/iwdg/stm32_iwdg.c b/drivers/st/iwdg/stm32_iwdg.c
index ea6fbb2b9..c052b4dfb 100644
--- a/drivers/st/iwdg/stm32_iwdg.c
+++ b/drivers/st/iwdg/stm32_iwdg.c
@@ -137,6 +137,12 @@ int stm32_iwdg_init(void)
((dt_info.status & DT_NON_SECURE) != 0) ?
"non-" : "");
+ if ((dt_info.status & DT_NON_SECURE) != 0) {
+ stm32mp_register_non_secure_periph_iomem(iwdg->base);
+ } else {
+ stm32mp_register_secure_periph_iomem(iwdg->base);
+ }
+
#if defined(IMAGE_BL2)
if (stm32_iwdg_shadow_update(idx, iwdg->flags) != BSEC_OK) {
return -1;
diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c
index 24e6efe98..cff3a344f 100644
--- a/drivers/st/mmc/stm32_sdmmc2.c
+++ b/drivers/st/mmc/stm32_sdmmc2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2018-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -113,6 +113,7 @@
SDMMC_STAR_IDMATE | \
SDMMC_STAR_IDMABTC)
+#define TIMEOUT_US_1_MS 1000U
#define TIMEOUT_US_10_MS 10000U
#define TIMEOUT_US_1_S 1000000U
@@ -257,6 +258,18 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd)
break;
}
+ mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS);
+
+ /*
+ * Clear the SDMMC_DCTRLR if the command does not await data.
+ * Skip CMD55 as the next command could be data related, and
+ * the register could have been set in prepare function.
+ */
+ if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) &&
+ (cmd->cmd_idx != MMC_CMD(55))) {
+ mmio_write_32(base + SDMMC_DCTRLR, 0U);
+ }
+
if ((cmd->resp_type & MMC_RSP_BUSY) != 0U) {
mmio_write_32(base + SDMMC_DTIMER, UINT32_MAX);
}
@@ -372,15 +385,15 @@ err_exit:
static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd)
{
- int8_t retry;
- int err = 0;
+ uint8_t retry;
+ int err;
assert(cmd != NULL);
- for (retry = 0; retry <= 3; retry++) {
+ for (retry = 0U; retry < 3U; retry++) {
err = stm32_sdmmc2_send_cmd_req(cmd);
if (err == 0) {
- return err;
+ return 0;
}
if ((cmd->cmd_idx == MMC_CMD(1)) ||
@@ -389,12 +402,12 @@ static int stm32_sdmmc2_send_cmd(struct mmc_cmd *cmd)
}
/* Command 8 is expected to fail for eMMC */
- if (!(cmd->cmd_idx == MMC_CMD(8))) {
- WARN(" CMD%d, Retry: %d, Error: %d\n",
- cmd->cmd_idx, retry, err);
+ if (cmd->cmd_idx != MMC_CMD(8)) {
+ WARN(" CMD%u, Retry: %u, Error: %d\n",
+ cmd->cmd_idx, retry + 1U, err);
}
- udelay(10);
+ udelay(10U);
}
return err;
@@ -711,6 +724,8 @@ unsigned long long stm32_sdmmc2_mmc_get_device_size(void)
int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params)
{
+ int rc;
+
assert((params != NULL) &&
((params->reg_base & MMC_BLOCK_MASK) == 0U) &&
((params->bus_width == MMC_BUS_WIDTH_1) ||
@@ -726,9 +741,15 @@ int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params)
stm32mp_clk_enable(sdmmc2_params.clock_id);
- stm32mp_reset_assert(sdmmc2_params.reset_id);
+ rc = stm32mp_reset_assert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS);
+ if (rc != 0) {
+ panic();
+ }
udelay(2);
- stm32mp_reset_deassert(sdmmc2_params.reset_id);
+ rc = stm32mp_reset_deassert(sdmmc2_params.reset_id, TIMEOUT_US_1_MS);
+ if (rc != 0) {
+ panic();
+ }
mdelay(1);
sdmmc2_params.clk_rate = stm32mp_clk_get_rate(sdmmc2_params.clock_id);
diff --git a/drivers/st/pmic/stm32mp_pmic.c b/drivers/st/pmic/stm32mp_pmic.c
index 9e9dddc4d..b2bb482f9 100644
--- a/drivers/st/pmic/stm32mp_pmic.c
+++ b/drivers/st/pmic/stm32mp_pmic.c
@@ -54,6 +54,15 @@ int dt_pmic_status(void)
return fdt_get_status(node);
}
+static bool dt_pmic_is_secure(void)
+{
+ int status = dt_pmic_status();
+
+ return (status >= 0) &&
+ (status == DT_SECURE) &&
+ (i2c_handle.dt_status == DT_SECURE);
+}
+
/*
* Get PMIC and its I2C bus configuration from the device tree.
* Return 0 on success, negative on error, 1 if no PMIC node is found.
@@ -223,6 +232,19 @@ bool initialize_pmic_i2c(void)
return true;
}
+static void register_pmic_shared_peripherals(void)
+{
+ uintptr_t i2c_base = i2c_handle.i2c_base_addr;
+
+ if (dt_pmic_is_secure()) {
+ stm32mp_register_secure_periph_iomem(i2c_base);
+ } else {
+ if (i2c_base != 0U) {
+ stm32mp_register_non_secure_periph_iomem(i2c_base);
+ }
+ }
+}
+
void initialize_pmic(void)
{
unsigned long pmic_version;
@@ -232,6 +254,8 @@ void initialize_pmic(void)
return;
}
+ register_pmic_shared_peripherals();
+
if (stpmic1_get_version(&pmic_version) != 0) {
ERROR("Failed to access PMIC\n");
panic();
diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c
index fd3f93e01..98c8dcf71 100644
--- a/drivers/st/reset/stm32mp1_reset.c
+++ b/drivers/st/reset/stm32mp1_reset.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
#include <limits.h>
#include <platform_def.h>
@@ -15,8 +16,6 @@
#include <lib/mmio.h>
#include <lib/utils_def.h>
-#define RESET_TIMEOUT_US_1MS U(1000)
-
static uint32_t id2reg_offset(unsigned int reset_id)
{
return ((reset_id & GENMASK(31, 5)) >> 5) * sizeof(uint32_t);
@@ -27,36 +26,44 @@ static uint8_t id2reg_bit_pos(unsigned int reset_id)
return (uint8_t)(reset_id & GENMASK(4, 0));
}
-void stm32mp_reset_assert(uint32_t id)
+int stm32mp_reset_assert(uint32_t id, unsigned int to_us)
{
uint32_t offset = id2reg_offset(id);
uint32_t bitmsk = BIT(id2reg_bit_pos(id));
- uint64_t timeout_ref;
uintptr_t rcc_base = stm32mp_rcc_base();
mmio_write_32(rcc_base + offset, bitmsk);
- timeout_ref = timeout_init_us(RESET_TIMEOUT_US_1MS);
- while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) {
- if (timeout_elapsed(timeout_ref)) {
- panic();
+ if (to_us != 0U) {
+ uint64_t timeout_ref = timeout_init_us(to_us);
+
+ while ((mmio_read_32(rcc_base + offset) & bitmsk) == 0U) {
+ if (timeout_elapsed(timeout_ref)) {
+ return -ETIMEDOUT;
+ }
}
}
+
+ return 0;
}
-void stm32mp_reset_deassert(uint32_t id)
+int stm32mp_reset_deassert(uint32_t id, unsigned int to_us)
{
uint32_t offset = id2reg_offset(id) + RCC_RSTCLRR_OFFSET;
uint32_t bitmsk = BIT(id2reg_bit_pos(id));
- uint64_t timeout_ref;
uintptr_t rcc_base = stm32mp_rcc_base();
mmio_write_32(rcc_base + offset, bitmsk);
- timeout_ref = timeout_init_us(RESET_TIMEOUT_US_1MS);
- while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) {
- if (timeout_elapsed(timeout_ref)) {
- panic();
+ if (to_us != 0U) {
+ uint64_t timeout_ref = timeout_init_us(to_us);
+
+ while ((mmio_read_32(rcc_base + offset) & bitmsk) != 0U) {
+ if (timeout_elapsed(timeout_ref)) {
+ return -ETIMEDOUT;
+ }
}
}
+
+ return 0;
}
diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c
index 188d2ff80..d67f8313f 100644
--- a/drivers/st/spi/stm32_qspi.c
+++ b/drivers/st/spi/stm32_qspi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2019-2020, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -9,13 +9,18 @@
#include <platform_def.h>
#include <common/debug.h>
+#include <common/fdt_wrappers.h>
#include <drivers/delay_timer.h>
#include <drivers/spi_mem.h>
#include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32_qspi.h>
#include <drivers/st/stm32mp_reset.h>
#include <lib/mmio.h>
#include <lib/utils_def.h>
+/* Timeout for device interface reset */
+#define TIMEOUT_US_1_MS 1000U
+
/* QUADSPI registers */
#define QSPI_CR 0x00U
#define QSPI_DCR 0x04U
@@ -172,9 +177,8 @@ static void stm32_qspi_write_fifo(uint8_t *val, uintptr_t addr)
static int stm32_qspi_poll(const struct spi_mem_op *op)
{
void (*fifo)(uint8_t *val, uintptr_t addr);
- uint32_t len = op->data.nbytes;
+ uint32_t len;
uint8_t *buf;
- uint64_t timeout;
if (op->data.dir == SPI_MEM_DATA_IN) {
fifo = stm32_qspi_read_fifo;
@@ -185,7 +189,8 @@ static int stm32_qspi_poll(const struct spi_mem_op *op)
buf = (uint8_t *)op->data.buf;
for (len = op->data.nbytes; len != 0U; len--) {
- timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US);
+ uint64_t timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US);
+
while ((mmio_read_32(qspi_base() + QSPI_SR) &
QSPI_SR_FTF) == 0U) {
if (timeout_elapsed(timeout)) {
@@ -464,13 +469,13 @@ int stm32_qspi_init(void)
return -FDT_ERR_NOTFOUND;
}
- ret = fdt_get_reg_props_by_name(qspi_node, "qspi",
+ ret = fdt_get_reg_props_by_name(fdt, qspi_node, "qspi",
&stm32_qspi.reg_base, &size);
if (ret != 0) {
return ret;
}
- ret = fdt_get_reg_props_by_name(qspi_node, "qspi_mm",
+ ret = fdt_get_reg_props_by_name(fdt, qspi_node, "qspi_mm",
&stm32_qspi.mm_base,
&stm32_qspi.mm_size);
if (ret != 0) {
@@ -490,8 +495,14 @@ int stm32_qspi_init(void)
stm32mp_clk_enable(stm32_qspi.clock_id);
- stm32mp_reset_assert(stm32_qspi.reset_id);
- stm32mp_reset_deassert(stm32_qspi.reset_id);
+ ret = stm32mp_reset_assert(stm32_qspi.reset_id, TIMEOUT_US_1_MS);
+ if (ret != 0) {
+ panic();
+ }
+ ret = stm32mp_reset_deassert(stm32_qspi.reset_id, TIMEOUT_US_1_MS);
+ if (ret != 0) {
+ panic();
+ }
mmio_write_32(qspi_base() + QSPI_CR, QSPI_CR_SSHIFT);
mmio_write_32(qspi_base() + QSPI_DCR, QSPI_DCR_FSIZE_MASK);
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
index ca3c1f618..686b18b96 100644
--- a/drivers/st/uart/aarch32/stm32_console.S
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -91,14 +91,14 @@ endfunc console_stm32_core_init
/* -------------------------------------------------------
* int console_stm32_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * struct console_stm32 *console);
+ * console_t *console);
* Function to initialize and register a new STM32
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
* In: r0 - UART register base address
* r1 - UART clock in Hz
* r2 - Baud rate
- * r3 - pointer to empty console_stm32 struct
+ * r3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : r0, r1, r2
* -------------------------------------------------------
@@ -108,7 +108,7 @@ func console_stm32_register
mov r4, r3
cmp r4, #0
beq register_fail
- str r0, [r4, #CONSOLE_T_STM32_BASE]
+ str r0, [r4, #CONSOLE_T_BASE]
bl console_stm32_core_init
cmp r0, #0
@@ -157,7 +157,7 @@ putc_error:
endfunc console_stm32_core_putc
/* ------------------------------------------------------------
- * int console_stm32_putc(int c, struct console_stm32 *console)
+ * int console_stm32_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In: r0 - character to be printed
@@ -171,7 +171,7 @@ func console_stm32_putc
cmp r1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r1, [r1, #CONSOLE_T_STM32_BASE]
+ ldr r1, [r1, #CONSOLE_T_BASE]
b console_stm32_core_putc
endfunc console_stm32_putc
@@ -193,37 +193,35 @@ func console_stm32_core_getc
endfunc console_stm32_core_getc
/* ---------------------------------------------------------------
- * int console_core_flush(uintptr_t base_addr)
+ * void console_core_flush(uintptr_t base_addr)
*
* Function to force a write of all buffered data that hasn't been
* output.
*
* In : r0 - console base address
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list : r0, r1
* ---------------------------------------------------------------
*/
func console_stm32_core_flush
+#if ENABLE_ASSERTIONS
cmp r0, #0
- beq flush_error
+ ASM_ASSERT(ne)
+#endif /* ENABLE_ASSERTIONS */
/* Check Transmit Data Register Empty */
txe_loop_3:
ldr r1, [r0, #USART_ISR]
tst r1, #USART_ISR_TXE
beq txe_loop_3
- mov r0, #0
- bx lr
-flush_error:
- mov r0, #-1
bx lr
endfunc console_stm32_core_flush
/* ------------------------------------------------------
- * int console_stm32_flush(struct console_stm32 *console)
+ * void console_stm32_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : r0 - pointer to console_t structure
- * Out : return -1 on error else return 0.
+ * Out : void.
* Clobber list: r0, r1
* ------------------------------------------------------
*/
@@ -232,6 +230,6 @@ func console_stm32_flush
cmp r0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- ldr r0, [r0, #CONSOLE_T_STM32_BASE]
+ ldr r0, [r0, #CONSOLE_T_BASE]
b console_stm32_core_flush
endfunc console_stm32_flush