stm32mp1: Add clock and reset support

The clock driver is under dual license, BSD and GPLv2.
The clock driver uses device tree, so a minimal support for this is added.
The required files for driver and DTS files are in include/dt-bindings/.

Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Signed-off-by: Nicolas Le Bayon <nicolas.le.bayon@st.com>
Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
This commit is contained in:
Yann Gautier 2018-07-24 17:13:36 +02:00
parent 4353bb20cc
commit 7839a05090
12 changed files with 2832 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,365 @@
/*
* Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <dt-bindings/clock/stm32mp1-clksrc.h>
#include <errno.h>
#include <libfdt.h>
#include <stm32mp1_clk.h>
#include <stm32mp1_clkfunc.h>
#include <stm32mp1_dt.h>
#define DT_RCC_NODE_NAME "rcc@50000000"
#define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc"
#define DT_RCC_COMPAT "syscon"
#define DT_STGEN_COMPAT "st,stm32-stgen"
#define DT_UART_COMPAT "st,stm32h7-uart"
#define DT_USART_COMPAT "st,stm32h7-usart"
const char *stm32mp_osc_node_label[NB_OSC] = {
[_LSI] = "clk-lsi",
[_LSE] = "clk-lse",
[_HSI] = "clk-hsi",
[_HSE] = "clk-hse",
[_CSI] = "clk-csi",
[_I2S_CKIN] = "i2s_ckin",
[_USB_PHY_48] = "ck_usbo_48m"
};
/*******************************************************************************
* This function reads the frequency of an oscillator from its name.
* It reads the value indicated inside the device tree.
* Returns 0 if success, and a negative value else.
* If success, value is stored in the second parameter.
******************************************************************************/
int fdt_osc_read_freq(const char *name, uint32_t *freq)
{
int node, subnode;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return -ENOENT;
}
node = fdt_path_offset(fdt, "/clocks");
if (node < 0) {
return -FDT_ERR_NOTFOUND;
}
fdt_for_each_subnode(subnode, fdt, node) {
const char *cchar;
int ret;
cchar = fdt_get_name(fdt, subnode, &ret);
if (cchar == NULL) {
return ret;
}
if (strncmp(cchar, name, (size_t)ret) == 0) {
const fdt32_t *cuint;
cuint = fdt_getprop(fdt, subnode, "clock-frequency",
&ret);
if (cuint == NULL) {
return ret;
}
*freq = fdt32_to_cpu(*cuint);
return 0;
}
}
/* Oscillator not found, freq=0 */
*freq = 0;
return 0;
}
/*******************************************************************************
* This function checks the presence of an oscillator property from its id.
* The search is done inside the device tree.
* Returns true/false regarding search result.
******************************************************************************/
bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name)
{
int node, subnode;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return false;
}
if (osc_id >= NB_OSC) {
return false;
}
node = fdt_path_offset(fdt, "/clocks");
if (node < 0) {
return false;
}
fdt_for_each_subnode(subnode, fdt, node) {
const char *cchar;
int ret;
cchar = fdt_get_name(fdt, subnode, &ret);
if (cchar == NULL) {
return false;
}
if (strncmp(cchar, stm32mp_osc_node_label[osc_id],
(size_t)ret) != 0) {
continue;
}
if (fdt_getprop(fdt, subnode, prop_name, NULL) != NULL) {
return true;
}
}
return false;
}
/*******************************************************************************
* This function reads a value of a oscillator property from its id.
* Returns value if success, and a default value if property not found.
* Default value is passed as parameter.
******************************************************************************/
uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
const char *prop_name, uint32_t dflt_value)
{
int node, subnode;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return dflt_value;
}
if (osc_id >= NB_OSC) {
return dflt_value;
}
node = fdt_path_offset(fdt, "/clocks");
if (node < 0) {
return dflt_value;
}
fdt_for_each_subnode(subnode, fdt, node) {
const char *cchar;
int ret;
cchar = fdt_get_name(fdt, subnode, &ret);
if (cchar == NULL) {
return dflt_value;
}
if (strncmp(cchar, stm32mp_osc_node_label[osc_id],
(size_t)ret) != 0) {
continue;
}
return fdt_read_uint32_default(subnode, prop_name, dflt_value);
}
return dflt_value;
}
/*******************************************************************************
* This function reads the rcc base address.
* It reads the value indicated inside the device tree.
* Returns address if success, and 0 value else.
******************************************************************************/
uint32_t fdt_rcc_read_addr(void)
{
int node, subnode;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return 0;
}
node = fdt_path_offset(fdt, "/soc");
if (node < 0) {
return 0;
}
fdt_for_each_subnode(subnode, fdt, node) {
const char *cchar;
int ret;
cchar = fdt_get_name(fdt, subnode, &ret);
if (cchar == NULL) {
return 0;
}
if (strncmp(cchar, DT_RCC_NODE_NAME, (size_t)ret) == 0) {
const fdt32_t *cuint;
cuint = fdt_getprop(fdt, subnode, "reg", NULL);
if (cuint == NULL) {
return 0;
}
return fdt32_to_cpu(*cuint);
}
}
return 0;
}
/*******************************************************************************
* This function reads a series of parameters in rcc-clk section.
* It reads the values indicated inside the device tree, from property name.
* The number of parameters is also indicated as entry parameter.
* Returns 0 if success, and a negative value else.
* If success, values are stored at the second parameter address.
******************************************************************************/
int fdt_rcc_read_uint32_array(const char *prop_name,
uint32_t *array, uint32_t count)
{
int node;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return -ENOENT;
}
node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
if (node < 0) {
return -FDT_ERR_NOTFOUND;
}
return fdt_read_uint32_array(node, prop_name, array, count);
}
/*******************************************************************************
* This function gets the subnode offset in rcc-clk section from its name.
* It reads the values indicated inside the device tree.
* Returns offset if success, and a negative value else.
******************************************************************************/
int fdt_rcc_subnode_offset(const char *name)
{
int node, subnode;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return -ENOENT;
}
node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
if (node < 0) {
return -FDT_ERR_NOTFOUND;
}
subnode = fdt_subnode_offset(fdt, node, name);
if (subnode <= 0) {
return -FDT_ERR_NOTFOUND;
}
return subnode;
}
/*******************************************************************************
* This function gets the pointer to a rcc-clk property from its name.
* It reads the values indicated inside the device tree.
* Length of the property is stored in the second parameter.
* Returns pointer if success, and NULL value else.
******************************************************************************/
const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
{
const uint32_t *cuint;
int node, len;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return NULL;
}
node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
if (node < 0) {
return NULL;
}
cuint = fdt_getprop(fdt, node, prop_name, &len);
if (cuint == NULL) {
return NULL;
}
*lenp = len;
return cuint;
}
/*******************************************************************************
* This function gets the secure status for rcc node.
* It reads secure-status in device tree.
* Returns 1 if rcc is available from secure world, 0 else.
******************************************************************************/
bool fdt_get_rcc_secure_status(void)
{
int node;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return false;
}
node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_COMPAT);
if (node < 0) {
return false;
}
return fdt_check_secure_status(node);
}
/*******************************************************************************
* This function reads the stgen base address.
* It reads the value indicated inside the device tree.
* Returns address if success, and NULL value else.
******************************************************************************/
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);
}
/*******************************************************************************
* This function gets the clock ID of the given node.
* It reads the value indicated inside the device tree.
* Returns ID if success, and a negative value else.
******************************************************************************/
int fdt_get_clock_id(int node)
{
const fdt32_t *cuint;
void *fdt;
if (fdt_get_address(&fdt) == 0) {
return -ENOENT;
}
cuint = fdt_getprop(fdt, node, "clocks", NULL);
if (cuint == NULL) {
return -FDT_ERR_NOTFOUND;
}
cuint++;
return (int)fdt32_to_cpu(*cuint);
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2018, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bl_common.h>
#include <debug.h>
#include <limits.h>
#include <mmio.h>
#include <platform_def.h>
#include <stm32mp1_rcc.h>
#include <stm32mp1_reset.h>
#include <utils_def.h>
#define RST_CLR_OFFSET 4U
void stm32mp1_reset_assert(uint32_t id)
{
uint32_t offset = (id / (uint32_t)__LONG_BIT) * sizeof(uintptr_t);
uint32_t bit = id % (uint32_t)__LONG_BIT;
mmio_write_32(RCC_BASE + offset, BIT(bit));
while ((mmio_read_32(RCC_BASE + offset) & BIT(bit)) == 0U) {
;
}
}
void stm32mp1_reset_deassert(uint32_t id)
{
uint32_t offset = ((id / (uint32_t)__LONG_BIT) * sizeof(uintptr_t)) +
RST_CLR_OFFSET;
uint32_t bit = id % (uint32_t)__LONG_BIT;
mmio_write_32(RCC_BASE + offset, BIT(bit));
while ((mmio_read_32(RCC_BASE + offset) & BIT(bit)) != 0U) {
;
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __STM32MP1_CLK_H__
#define __STM32MP1_CLK_H__
#include <arch_helpers.h>
#include <stdbool.h>
int stm32mp1_clk_probe(void);
int stm32mp1_clk_init(void);
bool stm32mp1_clk_is_enabled(unsigned long id);
int stm32mp1_clk_enable(unsigned long id);
int stm32mp1_clk_disable(unsigned long id);
unsigned long stm32mp1_clk_get_rate(unsigned long id);
void stm32mp1_stgen_increment(unsigned long long offset_in_ms);
static inline uint32_t get_timer(uint32_t base)
{
if (base == 0U) {
return (uint32_t)(~read_cntpct_el0());
}
return base - (uint32_t)(~read_cntpct_el0());
}
#endif /* __STM32MP1_CLK_H__ */

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __STM32MP1_CLKFUNC_H__
#define __STM32MP1_CLKFUNC_H__
#include <stdbool.h>
enum stm32mp_osc_id {
_HSI,
_HSE,
_CSI,
_LSI,
_LSE,
_I2S_CKIN,
_USB_PHY_48,
NB_OSC,
_UNKNOWN_OSC_ID = 0xFF
};
extern const char *stm32mp_osc_node_label[NB_OSC];
int fdt_osc_read_freq(const char *name, uint32_t *freq);
bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name);
uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
const char *prop_name,
uint32_t dflt_value);
uint32_t fdt_rcc_read_addr(void);
int fdt_rcc_read_uint32_array(const char *prop_name,
uint32_t *array, uint32_t count);
int fdt_rcc_subnode_offset(const char *name);
const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp);
bool fdt_get_rcc_secure_status(void);
uintptr_t fdt_get_stgen_base(void);
int fdt_get_clock_id(int node);
#endif /* __STM32MP1_CLKFUNC_H__ */

View File

@ -0,0 +1,15 @@
/*
* Copyright (c) 2018, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __STM32MP1_RESET_H__
#define __STM32MP1_RESET_H__
#include <stdint.h>
void stm32mp1_reset_assert(uint32_t reset_id);
void stm32mp1_reset_deassert(uint32_t reset_id);
#endif /* __STM32MP1_RESET_H__ */

View File

@ -0,0 +1,251 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/*
* Copyright (C) STMicroelectronics 2018 - All Rights Reserved
* Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
*/
#ifndef _DT_BINDINGS_STM32MP1_CLKS_H_
#define _DT_BINDINGS_STM32MP1_CLKS_H_
/* OSCILLATOR clocks */
#define CK_HSE 0
#define CK_CSI 1
#define CK_LSI 2
#define CK_LSE 3
#define CK_HSI 4
#define CK_HSE_DIV2 5
/* Bus clocks */
#define TIM2 6
#define TIM3 7
#define TIM4 8
#define TIM5 9
#define TIM6 10
#define TIM7 11
#define TIM12 12
#define TIM13 13
#define TIM14 14
#define LPTIM1 15
#define SPI2 16
#define SPI3 17
#define USART2 18
#define USART3 19
#define UART4 20
#define UART5 21
#define UART7 22
#define UART8 23
#define I2C1 24
#define I2C2 25
#define I2C3 26
#define I2C5 27
#define SPDIF 28
#define CEC 29
#define DAC12 30
#define MDIO 31
#define TIM1 32
#define TIM8 33
#define TIM15 34
#define TIM16 35
#define TIM17 36
#define SPI1 37
#define SPI4 38
#define SPI5 39
#define USART6 40
#define SAI1 41
#define SAI2 42
#define SAI3 43
#define DFSDM 44
#define FDCAN 45
#define LPTIM2 46
#define LPTIM3 47
#define LPTIM4 48
#define LPTIM5 49
#define SAI4 50
#define SYSCFG 51
#define VREF 52
#define TMPSENS 53
#define PMBCTRL 54
#define HDP 55
#define LTDC 56
#define DSI 57
#define IWDG2 58
#define USBPHY 59
#define STGENRO 60
#define SPI6 61
#define I2C4 62
#define I2C6 63
#define USART1 64
#define RTCAPB 65
#define TZC1 66
#define TZPC 67
#define IWDG1 68
#define BSEC 69
#define STGEN 70
#define DMA1 71
#define DMA2 72
#define DMAMUX 73
#define ADC12 74
#define USBO 75
#define SDMMC3 76
#define DCMI 77
#define CRYP2 78
#define HASH2 79
#define RNG2 80
#define CRC2 81
#define HSEM 82
#define IPCC 83
#define GPIOA 84
#define GPIOB 85
#define GPIOC 86
#define GPIOD 87
#define GPIOE 88
#define GPIOF 89
#define GPIOG 90
#define GPIOH 91
#define GPIOI 92
#define GPIOJ 93
#define GPIOK 94
#define GPIOZ 95
#define CRYP1 96
#define HASH1 97
#define RNG1 98
#define BKPSRAM 99
#define MDMA 100
#define GPU 101
#define ETHCK 102
#define ETHTX 103
#define ETHRX 104
#define ETHMAC 105
#define FMC 106
#define QSPI 107
#define SDMMC1 108
#define SDMMC2 109
#define CRC1 110
#define USBH 111
#define ETHSTP 112
#define TZC2 113
/* Kernel clocks */
#define SDMMC1_K 118
#define SDMMC2_K 119
#define SDMMC3_K 120
#define FMC_K 121
#define QSPI_K 122
#define ETHCK_K 123
#define RNG1_K 124
#define RNG2_K 125
#define GPU_K 126
#define USBPHY_K 127
#define STGEN_K 128
#define SPDIF_K 129
#define SPI1_K 130
#define SPI2_K 131
#define SPI3_K 132
#define SPI4_K 133
#define SPI5_K 134
#define SPI6_K 135
#define CEC_K 136
#define I2C1_K 137
#define I2C2_K 138
#define I2C3_K 139
#define I2C4_K 140
#define I2C5_K 141
#define I2C6_K 142
#define LPTIM1_K 143
#define LPTIM2_K 144
#define LPTIM3_K 145
#define LPTIM4_K 146
#define LPTIM5_K 147
#define USART1_K 148
#define USART2_K 149
#define USART3_K 150
#define UART4_K 151
#define UART5_K 152
#define USART6_K 153
#define UART7_K 154
#define UART8_K 155
#define DFSDM_K 156
#define FDCAN_K 157
#define SAI1_K 158
#define SAI2_K 159
#define SAI3_K 160
#define SAI4_K 161
#define ADC12_K 162
#define DSI_K 163
#define DSI_PX 164
#define ADFSDM_K 165
#define USBO_K 166
#define LTDC_PX 167
#define DAC12_K 168
#define ETHPTP_K 169
/* PLL */
#define PLL1 176
#define PLL2 177
#define PLL3 178
#define PLL4 179
/* ODF */
#define PLL1_P 180
#define PLL1_Q 181
#define PLL1_R 182
#define PLL2_P 183
#define PLL2_Q 184
#define PLL2_R 185
#define PLL3_P 186
#define PLL3_Q 187
#define PLL3_R 188
#define PLL4_P 189
#define PLL4_Q 190
#define PLL4_R 191
/* AUX */
#define RTC 192
/* MCLK */
#define CK_PER 193
#define CK_MPU 194
#define CK_AXI 195
#define CK_MCU 196
/* Time base */
#define TIM2_K 197
#define TIM3_K 198
#define TIM4_K 199
#define TIM5_K 200
#define TIM6_K 201
#define TIM7_K 202
#define TIM12_K 203
#define TIM13_K 204
#define TIM14_K 205
#define TIM1_K 206
#define TIM8_K 207
#define TIM15_K 208
#define TIM16_K 209
#define TIM17_K 210
/* MCO clocks */
#define CK_MCO1 211
#define CK_MCO2 212
/* TRACE & DEBUG clocks */
#define CK_DBG 214
#define CK_TRACE 215
/* DDR */
#define DDRC1 220
#define DDRC1LP 221
#define DDRC2 222
#define DDRC2LP 223
#define DDRPHYC 224
#define DDRPHYCLP 225
#define DDRCAPB 226
#define DDRCAPBLP 227
#define AXIDCG 228
#define DDRPHYCAPB 229
#define DDRPHYCAPBLP 230
#define DDRPERFM 231
#define STM32MP1_LAST_CLK 232
#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */

View File

@ -0,0 +1,283 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/*
* Copyright (C) 2017, STMicroelectronics - All Rights Reserved
*/
#ifndef _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
#define _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
/* PLL output is enable when x=1, with x=p,q or r */
#define PQR(p, q, r) (((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
/* st,clksrc: mandatory clock source */
#define CLK_MPU_HSI 0x00000200
#define CLK_MPU_HSE 0x00000201
#define CLK_MPU_PLL1P 0x00000202
#define CLK_MPU_PLL1P_DIV 0x00000203
#define CLK_AXI_HSI 0x00000240
#define CLK_AXI_HSE 0x00000241
#define CLK_AXI_PLL2P 0x00000242
#define CLK_MCU_HSI 0x00000480
#define CLK_MCU_HSE 0x00000481
#define CLK_MCU_CSI 0x00000482
#define CLK_MCU_PLL3P 0x00000483
#define CLK_PLL12_HSI 0x00000280
#define CLK_PLL12_HSE 0x00000281
#define CLK_PLL3_HSI 0x00008200
#define CLK_PLL3_HSE 0x00008201
#define CLK_PLL3_CSI 0x00008202
#define CLK_PLL4_HSI 0x00008240
#define CLK_PLL4_HSE 0x00008241
#define CLK_PLL4_CSI 0x00008242
#define CLK_PLL4_I2SCKIN 0x00008243
#define CLK_RTC_DISABLED 0x00001400
#define CLK_RTC_LSE 0x00001401
#define CLK_RTC_LSI 0x00001402
#define CLK_RTC_HSE 0x00001403
#define CLK_MCO1_HSI 0x00008000
#define CLK_MCO1_HSE 0x00008001
#define CLK_MCO1_CSI 0x00008002
#define CLK_MCO1_LSI 0x00008003
#define CLK_MCO1_LSE 0x00008004
#define CLK_MCO1_DISABLED 0x0000800F
#define CLK_MCO2_MPU 0x00008040
#define CLK_MCO2_AXI 0x00008041
#define CLK_MCO2_MCU 0x00008042
#define CLK_MCO2_PLL4P 0x00008043
#define CLK_MCO2_HSE 0x00008044
#define CLK_MCO2_HSI 0x00008045
#define CLK_MCO2_DISABLED 0x0000804F
/* st,pkcs: peripheral kernel clock source */
#define CLK_I2C12_PCLK1 0x00008C00
#define CLK_I2C12_PLL4R 0x00008C01
#define CLK_I2C12_HSI 0x00008C02
#define CLK_I2C12_CSI 0x00008C03
#define CLK_I2C12_DISABLED 0x00008C07
#define CLK_I2C35_PCLK1 0x00008C40
#define CLK_I2C35_PLL4R 0x00008C41
#define CLK_I2C35_HSI 0x00008C42
#define CLK_I2C35_CSI 0x00008C43
#define CLK_I2C35_DISABLED 0x00008C47
#define CLK_I2C46_PCLK5 0x00000C00
#define CLK_I2C46_PLL3Q 0x00000C01
#define CLK_I2C46_HSI 0x00000C02
#define CLK_I2C46_CSI 0x00000C03
#define CLK_I2C46_DISABLED 0x00000C07
#define CLK_SAI1_PLL4Q 0x00008C80
#define CLK_SAI1_PLL3Q 0x00008C81
#define CLK_SAI1_I2SCKIN 0x00008C82
#define CLK_SAI1_CKPER 0x00008C83
#define CLK_SAI1_PLL3R 0x00008C84
#define CLK_SAI1_DISABLED 0x00008C87
#define CLK_SAI2_PLL4Q 0x00008CC0
#define CLK_SAI2_PLL3Q 0x00008CC1
#define CLK_SAI2_I2SCKIN 0x00008CC2
#define CLK_SAI2_CKPER 0x00008CC3
#define CLK_SAI2_SPDIF 0x00008CC4
#define CLK_SAI2_PLL3R 0x00008CC5
#define CLK_SAI2_DISABLED 0x00008CC7
#define CLK_SAI3_PLL4Q 0x00008D00
#define CLK_SAI3_PLL3Q 0x00008D01
#define CLK_SAI3_I2SCKIN 0x00008D02
#define CLK_SAI3_CKPER 0x00008D03
#define CLK_SAI3_PLL3R 0x00008D04
#define CLK_SAI3_DISABLED 0x00008D07
#define CLK_SAI4_PLL4Q 0x00008D40
#define CLK_SAI4_PLL3Q 0x00008D41
#define CLK_SAI4_I2SCKIN 0x00008D42
#define CLK_SAI4_CKPER 0x00008D43
#define CLK_SAI4_PLL3R 0x00008D44
#define CLK_SAI4_DISABLED 0x00008D47
#define CLK_SPI2S1_PLL4P 0x00008D80
#define CLK_SPI2S1_PLL3Q 0x00008D81
#define CLK_SPI2S1_I2SCKIN 0x00008D82
#define CLK_SPI2S1_CKPER 0x00008D83
#define CLK_SPI2S1_PLL3R 0x00008D84
#define CLK_SPI2S1_DISABLED 0x00008D87
#define CLK_SPI2S23_PLL4P 0x00008DC0
#define CLK_SPI2S23_PLL3Q 0x00008DC1
#define CLK_SPI2S23_I2SCKIN 0x00008DC2
#define CLK_SPI2S23_CKPER 0x00008DC3
#define CLK_SPI2S23_PLL3R 0x00008DC4
#define CLK_SPI2S23_DISABLED 0x00008DC7
#define CLK_SPI45_PCLK2 0x00008E00
#define CLK_SPI45_PLL4Q 0x00008E01
#define CLK_SPI45_HSI 0x00008E02
#define CLK_SPI45_CSI 0x00008E03
#define CLK_SPI45_HSE 0x00008E04
#define CLK_SPI45_DISABLED 0x00008E07
#define CLK_SPI6_PCLK5 0x00000C40
#define CLK_SPI6_PLL4Q 0x00000C41
#define CLK_SPI6_HSI 0x00000C42
#define CLK_SPI6_CSI 0x00000C43
#define CLK_SPI6_HSE 0x00000C44
#define CLK_SPI6_PLL3Q 0x00000C45
#define CLK_SPI6_DISABLED 0x00000C47
#define CLK_UART6_PCLK2 0x00008E40
#define CLK_UART6_PLL4Q 0x00008E41
#define CLK_UART6_HSI 0x00008E42
#define CLK_UART6_CSI 0x00008E43
#define CLK_UART6_HSE 0x00008E44
#define CLK_UART6_DISABLED 0x00008E47
#define CLK_UART24_PCLK1 0x00008E80
#define CLK_UART24_PLL4Q 0x00008E81
#define CLK_UART24_HSI 0x00008E82
#define CLK_UART24_CSI 0x00008E83
#define CLK_UART24_HSE 0x00008E84
#define CLK_UART24_DISABLED 0x00008E87
#define CLK_UART35_PCLK1 0x00008EC0
#define CLK_UART35_PLL4Q 0x00008EC1
#define CLK_UART35_HSI 0x00008EC2
#define CLK_UART35_CSI 0x00008EC3
#define CLK_UART35_HSE 0x00008EC4
#define CLK_UART35_DISABLED 0x00008EC7
#define CLK_UART78_PCLK1 0x00008F00
#define CLK_UART78_PLL4Q 0x00008F01
#define CLK_UART78_HSI 0x00008F02
#define CLK_UART78_CSI 0x00008F03
#define CLK_UART78_HSE 0x00008F04
#define CLK_UART78_DISABLED 0x00008F07
#define CLK_UART1_PCLK5 0x00000C80
#define CLK_UART1_PLL3Q 0x00000C81
#define CLK_UART1_HSI 0x00000C82
#define CLK_UART1_CSI 0x00000C83
#define CLK_UART1_PLL4Q 0x00000C84
#define CLK_UART1_HSE 0x00000C85
#define CLK_UART1_DISABLED 0x00000C87
#define CLK_SDMMC12_HCLK6 0x00008F40
#define CLK_SDMMC12_PLL3R 0x00008F41
#define CLK_SDMMC12_PLL4P 0x00008F42
#define CLK_SDMMC12_HSI 0x00008F43
#define CLK_SDMMC12_DISABLED 0x00008F47
#define CLK_SDMMC3_HCLK2 0x00008F80
#define CLK_SDMMC3_PLL3R 0x00008F81
#define CLK_SDMMC3_PLL4P 0x00008F82
#define CLK_SDMMC3_HSI 0x00008F83
#define CLK_SDMMC3_DISABLED 0x00008F87
#define CLK_ETH_PLL4P 0x00008FC0
#define CLK_ETH_PLL3Q 0x00008FC1
#define CLK_ETH_DISABLED 0x00008FC3
#define CLK_QSPI_ACLK 0x00009000
#define CLK_QSPI_PLL3R 0x00009001
#define CLK_QSPI_PLL4P 0x00009002
#define CLK_QSPI_CKPER 0x00009003
#define CLK_FMC_ACLK 0x00009040
#define CLK_FMC_PLL3R 0x00009041
#define CLK_FMC_PLL4P 0x00009042
#define CLK_FMC_CKPER 0x00009043
#define CLK_FDCAN_HSE 0x000090C0
#define CLK_FDCAN_PLL3Q 0x000090C1
#define CLK_FDCAN_PLL4Q 0x000090C2
#define CLK_FDCAN_PLL4R 0x000090C3
#define CLK_SPDIF_PLL4P 0x00009140
#define CLK_SPDIF_PLL3Q 0x00009141
#define CLK_SPDIF_HSI 0x00009142
#define CLK_SPDIF_DISABLED 0x00009143
#define CLK_CEC_LSE 0x00009180
#define CLK_CEC_LSI 0x00009181
#define CLK_CEC_CSI_DIV122 0x00009182
#define CLK_CEC_DISABLED 0x00009183
#define CLK_USBPHY_HSE 0x000091C0
#define CLK_USBPHY_PLL4R 0x000091C1
#define CLK_USBPHY_HSE_DIV2 0x000091C2
#define CLK_USBPHY_DISABLED 0x000091C3
#define CLK_USBO_PLL4R 0x800091C0
#define CLK_USBO_USBPHY 0x800091C1
#define CLK_RNG1_CSI 0x00000CC0
#define CLK_RNG1_PLL4R 0x00000CC1
#define CLK_RNG1_LSE 0x00000CC2
#define CLK_RNG1_LSI 0x00000CC3
#define CLK_RNG2_CSI 0x00009200
#define CLK_RNG2_PLL4R 0x00009201
#define CLK_RNG2_LSE 0x00009202
#define CLK_RNG2_LSI 0x00009203
#define CLK_CKPER_HSI 0x00000D00
#define CLK_CKPER_CSI 0x00000D01
#define CLK_CKPER_HSE 0x00000D02
#define CLK_CKPER_DISABLED 0x00000D03
#define CLK_STGEN_HSI 0x00000D40
#define CLK_STGEN_HSE 0x00000D41
#define CLK_STGEN_DISABLED 0x00000D43
#define CLK_DSI_DSIPLL 0x00009240
#define CLK_DSI_PLL4P 0x00009241
#define CLK_ADC_PLL4R 0x00009280
#define CLK_ADC_CKPER 0x00009281
#define CLK_ADC_PLL3Q 0x00009282
#define CLK_ADC_DISABLED 0x00009283
#define CLK_LPTIM45_PCLK3 0x000092C0
#define CLK_LPTIM45_PLL4P 0x000092C1
#define CLK_LPTIM45_PLL3Q 0x000092C2
#define CLK_LPTIM45_LSE 0x000092C3
#define CLK_LPTIM45_LSI 0x000092C4
#define CLK_LPTIM45_CKPER 0x000092C5
#define CLK_LPTIM45_DISABLED 0x000092C7
#define CLK_LPTIM23_PCLK3 0x00009300
#define CLK_LPTIM23_PLL4Q 0x00009301
#define CLK_LPTIM23_CKPER 0x00009302
#define CLK_LPTIM23_LSE 0x00009303
#define CLK_LPTIM23_LSI 0x00009304
#define CLK_LPTIM23_DISABLED 0x00009307
#define CLK_LPTIM1_PCLK1 0x00009340
#define CLK_LPTIM1_PLL4P 0x00009341
#define CLK_LPTIM1_PLL3Q 0x00009342
#define CLK_LPTIM1_LSE 0x00009343
#define CLK_LPTIM1_LSI 0x00009344
#define CLK_LPTIM1_CKPER 0x00009345
#define CLK_LPTIM1_DISABLED 0x00009347
/* define for st,pll /csg */
#define SSCG_MODE_CENTER_SPREAD 0
#define SSCG_MODE_DOWN_SPREAD 1
/* define for st,drive */
#define LSEDRV_LOWEST 0
#define LSEDRV_MEDIUM_LOW 1
#define LSEDRV_MEDIUM_HIGH 2
#define LSEDRV_HIGHEST 3
#endif

View File

@ -16,6 +16,8 @@
#include <mmio.h>
#include <platform.h>
#include <platform_def.h>
#include <stm32mp1_clk.h>
#include <stm32mp1_dt.h>
#include <stm32mp1_private.h>
#include <stm32mp1_pwr.h>
#include <stm32mp1_rcc.h>
@ -76,5 +78,17 @@ void bl2_el3_plat_arch_setup(void)
generic_delay_timer_init();
if (dt_open_and_check() < 0) {
panic();
}
if (stm32mp1_clk_probe() < 0) {
panic();
}
if (stm32mp1_clk_init() < 0) {
panic();
}
stm32mp1_io_setup();
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __STM32MP1_DT_H__
#define __STM32MP1_DT_H__
#include <stdbool.h>
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
int dt_open_and_check(void);
int fdt_get_address(void **fdt_addr);
bool fdt_check_node(int node);
bool fdt_check_status(int node);
bool fdt_check_secure_status(int node);
uint32_t fdt_read_uint32_default(int node, const char *prop_name,
uint32_t dflt_value);
int fdt_read_uint32_array(int node, const char *prop_name,
uint32_t *array, uint32_t count);
#endif /* __STM32MP1_DT_H__ */

View File

@ -39,6 +39,10 @@ PLAT_BL_COMMON_SOURCES += lib/cpus/aarch32/cortex_a7.S
PLAT_BL_COMMON_SOURCES += ${LIBFDT_SRCS} \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
drivers/st/clk/stm32mp1_clk.c \
drivers/st/clk/stm32mp1_clkfunc.c \
drivers/st/reset/stm32mp1_reset.c \
plat/st/stm32mp1/stm32mp1_dt.c \
plat/st/stm32mp1/stm32mp1_helper.S
BL2_SOURCES += drivers/io/io_dummy.c \

View File

@ -0,0 +1,153 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <debug.h>
#include <libfdt.h>
#include <platform_def.h>
#include <stm32mp1_clk.h>
#include <stm32mp1_clkfunc.h>
#include <stm32mp1_dt.h>
#define DT_GPIO_BANK_SHIFT 12
#define DT_GPIO_BANK_MASK 0x1F000U
#define DT_GPIO_PIN_SHIFT 8
#define DT_GPIO_PIN_MASK 0xF00U
#define DT_GPIO_MODE_MASK 0xFFU
static int fdt_checked;
static void *fdt = (void *)(uintptr_t)STM32MP1_DTB_BASE;
/*******************************************************************************
* This function checks device tree file with its header.
* Returns 0 if success, and a negative value else.
******************************************************************************/
int dt_open_and_check(void)
{
int ret = fdt_check_header(fdt);
if (ret == 0) {
fdt_checked = 1;
}
return ret;
}
/*******************************************************************************
* This function gets the address of the DT.
* If DT is OK, fdt_addr is filled with DT address.
* Returns 1 if success, 0 otherwise.
******************************************************************************/
int fdt_get_address(void **fdt_addr)
{
if (fdt_checked == 1) {
*fdt_addr = fdt;
}
return fdt_checked;
}
/*******************************************************************************
* This function check the presence of a node (generic use of fdt library).
* Returns true if present, false else.
******************************************************************************/
bool fdt_check_node(int node)
{
int len;
const char *cchar;
cchar = fdt_get_name(fdt, node, &len);
return (cchar != NULL) && (len >= 0);
}
/*******************************************************************************
* This function check the status of a node (generic use of fdt library).
* Returns true if "okay" or missing, false else.
******************************************************************************/
bool fdt_check_status(int node)
{
int len;
const char *cchar;
cchar = fdt_getprop(fdt, node, "status", &len);
if (cchar == NULL) {
return true;
}
return strncmp(cchar, "okay", (size_t)len) == 0;
}
/*******************************************************************************
* This function check the secure-status of a node (generic use of fdt library).
* Returns true if "okay" or missing, false else.
******************************************************************************/
bool fdt_check_secure_status(int node)
{
int len;
const char *cchar;
cchar = fdt_getprop(fdt, node, "secure-status", &len);
if (cchar == NULL) {
return true;
}
return strncmp(cchar, "okay", (size_t)len) == 0;
}
/*******************************************************************************
* This function reads a value of a node property (generic use of fdt
* library).
* Returns value if success, and a default value if property not found.
* Default value is passed as parameter.
******************************************************************************/
uint32_t fdt_read_uint32_default(int node, const char *prop_name,
uint32_t dflt_value)
{
const fdt32_t *cuint;
int lenp;
cuint = fdt_getprop(fdt, node, prop_name, &lenp);
if (cuint == NULL) {
return dflt_value;
}
return fdt32_to_cpu(*cuint);
}
/*******************************************************************************
* This function reads a series of parameters in a node property
* (generic use of fdt library).
* It reads the values inside the device tree, from property name and node.
* The number of parameters is also indicated as entry parameter.
* Returns 0 if success, and a negative value else.
* If success, values are stored at the third parameter address.
******************************************************************************/
int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
uint32_t count)
{
const fdt32_t *cuint;
int len;
uint32_t i;
cuint = fdt_getprop(fdt, node, prop_name, &len);
if (cuint == NULL) {
return -FDT_ERR_NOTFOUND;
}
if ((uint32_t)len != (count * sizeof(uint32_t))) {
return -FDT_ERR_BADLAYOUT;
}
for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
*array = fdt32_to_cpu(*cuint);
array++;
cuint++;
}
return 0;
}