stm32mp1: update clock driver

Remove useless private structure in function prototypes.
Add a reference counter on clocks.
Prepare for future secured/shared/non-secured clocks.

Change-Id: I3dbed81721da5ceff5e10b2c4155b1e340c036ee
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
Signed-off-by: Nicolas LE BAYON <nicolas.le.bayon@st.com>
This commit is contained in:
Yann Gautier 2019-02-14 10:53:33 +01:00
parent 5202cb393d
commit 0d21680c35
14 changed files with 854 additions and 578 deletions

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,6 @@ const char *stm32mp_osc_node_label[NB_OSC] = {
[_HSE] = "clk-hse",
[_CSI] = "clk-csi",
[_I2S_CKIN] = "i2s_ckin",
[_USB_PHY_48] = "ck_usbo_48m"
};
/*

View File

@ -11,10 +11,14 @@
void ddr_enable_clock(void)
{
stm32mp1_clk_rcc_regs_lock();
mmio_setbits_32(stm32mp_rcc_base() + RCC_DDRITFCR,
RCC_DDRITFCR_DDRC1EN |
RCC_DDRITFCR_DDRC2EN |
RCC_DDRITFCR_DDRPHYCEN |
RCC_DDRITFCR_DDRPHYCAPBEN |
RCC_DDRITFCR_DDRCAPBEN);
stm32mp1_clk_rcc_regs_unlock();
}

View File

@ -168,7 +168,7 @@ static int stm32mp1_ddr_setup(void)
int ret;
struct stm32mp1_ddr_config config;
int node, len;
uint32_t tamp_clk_off = 0, uret, idx;
uint32_t uret, idx;
void *fdt;
#define PARAM(x, y) \
@ -237,19 +237,6 @@ static int stm32mp1_ddr_setup(void)
}
}
if (!stm32mp_clk_is_enabled(RTCAPB)) {
tamp_clk_off = 1;
if (stm32mp_clk_enable(RTCAPB) != 0) {
return -EINVAL;
}
}
if (tamp_clk_off != 0U) {
if (stm32mp_clk_disable(RTCAPB) != 0) {
return -EINVAL;
}
}
/* Disable axidcg clock gating during init */
mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);

View File

@ -702,8 +702,6 @@ unsigned long long stm32_sdmmc2_mmc_get_device_size(void)
int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params)
{
int ret;
assert((params != NULL) &&
((params->reg_base & MMC_BLOCK_MASK) == 0U) &&
((params->bus_width == MMC_BUS_WIDTH_1) ||
@ -717,12 +715,7 @@ int stm32_sdmmc2_mmc_init(struct stm32_sdmmc2_params *params)
return -ENOMEM;
}
ret = stm32mp_clk_enable(sdmmc2_params.clock_id);
if (ret != 0) {
ERROR("%s: clock %d failed\n", __func__,
sdmmc2_params.clock_id);
return ret;
}
stm32mp_clk_enable(sdmmc2_params.clock_id);
stm32mp_reset_assert(sdmmc2_params.reset_id);
udelay(2);

View File

@ -11,6 +11,38 @@
int stm32mp1_clk_probe(void);
int stm32mp1_clk_init(void);
bool stm32mp1_rcc_is_secure(void);
void __stm32mp1_clk_enable(unsigned long id, bool caller_is_secure);
void __stm32mp1_clk_disable(unsigned long id, bool caller_is_secure);
static inline void stm32mp1_clk_enable_non_secure(unsigned long id)
{
__stm32mp1_clk_enable(id, false);
}
static inline void stm32mp1_clk_enable_secure(unsigned long id)
{
__stm32mp1_clk_enable(id, true);
}
static inline void stm32mp1_clk_disable_non_secure(unsigned long id)
{
__stm32mp1_clk_disable(id, false);
}
static inline void stm32mp1_clk_disable_secure(unsigned long id)
{
__stm32mp1_clk_disable(id, true);
}
unsigned int stm32mp1_clk_get_refcount(unsigned long id);
/* SMP protection on RCC registers access */
void stm32mp1_clk_rcc_regs_lock(void);
void stm32mp1_clk_rcc_regs_unlock(void);
void stm32mp1_stgen_increment(unsigned long long offset_in_ms);
#endif /* STM32MP1_CLK_H */

View File

@ -18,7 +18,6 @@ enum stm32mp_osc_id {
_LSI,
_LSE,
_I2S_CKIN,
_USB_PHY_48,
NB_OSC,
_UNKNOWN_OSC_ID = 0xFF
};

View File

@ -50,8 +50,8 @@ uint32_t stm32_get_gpio_bank_offset(unsigned int bank);
* @id: Target clock ID, ID used in clock DT bindings
*/
bool stm32mp_clk_is_enabled(unsigned long id);
int stm32mp_clk_enable(unsigned long id);
int stm32mp_clk_disable(unsigned long id);
void stm32mp_clk_enable(unsigned long id);
void stm32mp_clk_disable(unsigned long id);
unsigned long stm32mp_clk_get_rate(unsigned long id);
/* Initialise the IO layer and register platform IO devices */

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2018-2019, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef STM32MP_SHRES_HELPERS_H
#define STM32MP_SHRES_HELPERS_H
#include <stdint.h>
#include <common/debug.h>
/*
* Shared reference counter: increments by 2 on secure increment
* request, decrements by 2 on secure decrement request. Bit #0
* is set to 1 on non-secure increment request and reset to 0 on
* non-secure decrement request. The counter initializes to
* either 0, 1 or 2 upon their expect default state.
* Counters saturates once above UINT_MAX / 2.
*/
#define SHREFCNT_NONSECURE_FLAG 0x1UL
#define SHREFCNT_SECURE_STEP 0x2UL
#define SHREFCNT_MAX (UINT32_MAX / 2)
/* Return 1 if refcnt increments from 0, else return 0 */
static inline int stm32mp_incr_shrefcnt(unsigned int *refcnt, bool secure)
{
int rc = !*refcnt;
if (secure) {
*refcnt += SHREFCNT_SECURE_STEP;
if (*refcnt >= SHREFCNT_MAX) {
panic();
}
} else {
*refcnt |= SHREFCNT_NONSECURE_FLAG;
}
return rc;
}
/* Return 1 if refcnt decrements to 0, else return 0 */
static inline int stm32mp_decr_shrefcnt(unsigned int *refcnt, bool secure)
{
int rc = 0;
if (secure) {
if (*refcnt < SHREFCNT_MAX) {
if (*refcnt < SHREFCNT_SECURE_STEP) {
panic();
}
*refcnt -= SHREFCNT_SECURE_STEP;
rc = !*refcnt;
}
} else {
rc = (*refcnt == SHREFCNT_NONSECURE_FLAG) ? 1 : 0;
*refcnt &= ~SHREFCNT_NONSECURE_FLAG;
}
return rc;
}
static inline int stm32mp_incr_refcnt(unsigned int *refcnt)
{
return stm32mp_incr_shrefcnt(refcnt, true);
}
static inline int stm32mp_decr_refcnt(unsigned int *refcnt)
{
return stm32mp_decr_shrefcnt(refcnt, true);
}
#endif /* STM32MP_SHRES_HELPERS_H */

View File

@ -225,9 +225,7 @@ void bl2_el3_plat_arch_setup(void)
goto skip_console_init;
}
if (stm32mp_clk_enable((unsigned long)dt_uart_info.clock) != 0) {
goto skip_console_init;
}
stm32mp_clk_enable((unsigned long)dt_uart_info.clock);
stm32mp_reset_assert((uint32_t)dt_uart_info.reset);
udelay(2);

View File

@ -20,26 +20,16 @@
int stm32_save_boot_interface(uint32_t interface, uint32_t instance)
{
uint32_t tamp_clk_off = 0;
uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID);
if (!stm32mp_clk_is_enabled(RTCAPB)) {
tamp_clk_off = 1;
if (stm32mp_clk_enable(RTCAPB) != 0) {
return -EINVAL;
}
}
stm32mp_clk_enable(RTCAPB);
mmio_clrsetbits_32(bkpr_itf_idx,
TAMP_BOOT_ITF_MASK,
((interface << 4) | (instance & 0xFU)) <<
TAMP_BOOT_ITF_SHIFT);
if (tamp_clk_off != 0U) {
if (stm32mp_clk_disable(RTCAPB) != 0) {
return -EINVAL;
}
}
stm32mp_clk_disable(RTCAPB);
return 0;
}

View File

@ -20,6 +20,7 @@
#include <boot_api.h>
#include <stm32mp_common.h>
#include <stm32mp_dt.h>
#include <stm32mp_shres_helpers.h>
#include <stm32mp1_private.h>
#endif

View File

@ -59,7 +59,6 @@ static void stm32_cpu_standby(plat_local_state_t cpu_state)
static int stm32_pwr_domain_on(u_register_t mpidr)
{
unsigned long current_cpu_mpidr = read_mpidr_el1();
uint32_t tamp_clk_off = 0;
uint32_t bkpr_core1_addr =
tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX);
uint32_t bkpr_core1_magic =
@ -75,12 +74,7 @@ static int stm32_pwr_domain_on(u_register_t mpidr)
return PSCI_E_INVALID_ADDRESS;
}
if (!stm32mp_clk_is_enabled(RTCAPB)) {
tamp_clk_off = 1;
if (stm32mp_clk_enable(RTCAPB) != 0) {
panic();
}
}
stm32mp_clk_enable(RTCAPB);
cntfrq_core0 = read_cntfrq_el0();
@ -90,11 +84,7 @@ static int stm32_pwr_domain_on(u_register_t mpidr)
/* Write magic number in backup register */
mmio_write_32(bkpr_core1_magic, BOOT_API_A7_CORE1_MAGIC_NUMBER);
if (tamp_clk_off != 0U) {
if (stm32mp_clk_disable(RTCAPB) != 0) {
panic();
}
}
stm32mp_clk_disable(RTCAPB);
/* Generate an IT to core 1 */
gicv2_raise_sgi(ARM_IRQ_SEC_SGI_0, STM32MP_SECONDARY_CPU);

View File

@ -61,14 +61,8 @@ static void init_tzc400(void)
******************************************************************************/
static void early_init_tzc400(void)
{
if (stm32mp_clk_enable(TZC1) != 0) {
ERROR("Cannot enable TZC1 clock\n");
panic();
}
if (stm32mp_clk_enable(TZC2) != 0) {
ERROR("Cannot enable TZC2 clock\n");
panic();
}
stm32mp_clk_enable(TZC1);
stm32mp_clk_enable(TZC2);
tzc400_init(STM32MP1_TZC_BASE);