diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 2e89ecf..4275f3b 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -18,10 +18,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include diff --git a/drivers/st/clk/stm32mp1_clkfunc.c b/drivers/st/clk/stm32mp1_clkfunc.c index 19dfe1b..06c417b 100644 --- a/drivers/st/clk/stm32mp1_clkfunc.c +++ b/drivers/st/clk/stm32mp1_clkfunc.c @@ -10,17 +10,12 @@ #include +#include +#include #include #include #include -#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", @@ -31,20 +26,12 @@ [_USB_PHY_48] = "ck_usbo_48m" }; -/******************************************************************************* - * This function returns the RCC node in the device tree. - ******************************************************************************/ -static int fdt_get_rcc_node(void *fdt) -{ - return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); -} - -/******************************************************************************* - * This function reads the frequency of an oscillator from its name. - * It reads the value indicated inside the device tree. - * Returns 0 on success, and a negative FDT/ERRNO error code on failure. - * On success, value is stored in the second parameter. - ******************************************************************************/ +/* + * Get the frequency of an oscillator from its name in device tree. + * @param name: oscillator name + * @param freq: stores the frequency of the oscillator + * @return: 0 on success, and a negative FDT/ERRNO error code on failure. + */ int fdt_osc_read_freq(const char *name, uint32_t *freq) { int node, subnode; @@ -88,11 +75,12 @@ 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. - ******************************************************************************/ +/* + * Check the presence of an oscillator property from its id. + * @param osc_id: oscillator ID + * @param prop_name: property name + * @return: true/false regarding search result. + */ bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name) { int node, subnode; @@ -133,11 +121,13 @@ return false; } -/******************************************************************************* - * This function reads a value of a oscillator property from its id. - * Returns value on success, and a default value if property not found. - * Default value is passed as parameter. - ******************************************************************************/ +/* + * Get the value of a oscillator property from its ID. + * @param osc_id: oscillator ID + * @param prop_name: property name + * @param dflt_value: default value + * @return oscillator value on success, default value if property not found. + */ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, const char *prop_name, uint32_t dflt_value) { @@ -176,201 +166,3 @@ 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 on success, and a negative FDT/ERRNO error code on failure. - ******************************************************************************/ -int fdt_rcc_subnode_offset(const char *name) -{ - int node, subnode; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return -ENOENT; - } - - node = fdt_get_rcc_node(fdt); - 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 on success, and NULL value on failure. - ******************************************************************************/ -const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp) -{ - const fdt32_t *cuint; - int node, len; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return NULL; - } - - node = fdt_get_rcc_node(fdt); - 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 true if rcc is available from secure world, false if not. - ******************************************************************************/ -bool fdt_get_rcc_secure_status(void) -{ - int node; - void *fdt; - - if (fdt_get_address(&fdt) == 0) { - return false; - } - - node = fdt_get_rcc_node(fdt); - if (node < 0) { - return false; - } - - return (fdt_get_status(node) & DT_SECURE) != 0U; -} - -/******************************************************************************* - * This function reads the stgen base address. - * It reads the value indicated inside the device tree. - * Returns address 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); -} - -/******************************************************************************* - * This function gets the clock ID of the given node. - * It reads the value indicated inside the device tree. - * Returns ID on success, and a negative FDT/ERRNO error code on failure. - ******************************************************************************/ -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); -} diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c new file mode 100644 index 0000000..16acef0 --- /dev/null +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include + +#include +#include + +#define DT_STGEN_COMPAT "st,stm32-stgen" + +/* + * Get the RCC node offset from the device tree + * @param fdt: Device tree reference + * @return: Node offset or a negative value on error + */ +int fdt_get_rcc_node(void *fdt) +{ + return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); +} + +/* + * 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 node; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return -ENOENT; + } + + node = fdt_get_rcc_node(fdt); + if (node < 0) { + return -FDT_ERR_NOTFOUND; + } + + return fdt_read_uint32_array(node, prop_name, array, count); +} + +/* + * Get the subnode offset in rcc-clk section from its name in device tree + * @param name: name of the RCC property + * @return: offset on success, and a negative FDT/ERRNO error code on failure. + */ +int fdt_rcc_subnode_offset(const char *name) +{ + int node, subnode; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return -ENOENT; + } + + node = fdt_get_rcc_node(fdt); + if (node < 0) { + return -FDT_ERR_NOTFOUND; + } + + subnode = fdt_subnode_offset(fdt, node, name); + if (subnode <= 0) { + return -FDT_ERR_NOTFOUND; + } + + return subnode; +} + +/* + * Get the pointer to a rcc-clk property from its name. + * @param name: name of the RCC property + * @param lenp: stores the length of the property. + * @return: pointer to the property on success, and NULL value on failure. + */ +const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp) +{ + const fdt32_t *cuint; + int node, len; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return NULL; + } + + node = fdt_get_rcc_node(fdt); + if (node < 0) { + return NULL; + } + + cuint = fdt_getprop(fdt, node, prop_name, &len); + if (cuint == NULL) { + return NULL; + } + + *lenp = len; + return cuint; +} + +/* + * Get the secure status for rcc node in device tree. + * @return: true if rcc is available from secure world, false if not. + */ +bool fdt_get_rcc_secure_status(void) +{ + int node; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return false; + } + + node = fdt_get_rcc_node(fdt); + if (node < 0) { + return false; + } + + return !!(fdt_get_status(node) & DT_SECURE); +} + +/* + * 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. + */ +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); +} diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c index 5733046..343ad6c 100644 --- a/drivers/st/gpio/stm32_gpio.c +++ b/drivers/st/gpio/stm32_gpio.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/include/drivers/st/stm32mp1_clkfunc.h b/include/drivers/st/stm32mp1_clkfunc.h index 106dcae..41b68fd 100644 --- a/include/drivers/st/stm32mp1_clkfunc.h +++ b/include/drivers/st/stm32mp1_clkfunc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -31,14 +31,4 @@ 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 fdt32_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 */ diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h new file mode 100644 index 0000000..5beb06b --- /dev/null +++ b/include/drivers/st/stm32mp_clkfunc.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP_CLKFUNC_H +#define STM32MP_CLKFUNC_H + +#include + +#include + +int fdt_get_rcc_node(void *fdt); +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 fdt32_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 /* STM32MP_CLKFUNC_H */ diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 1c5f627..3e34601 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -50,6 +50,7 @@ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/st/bsec/bsec.c \ + drivers/st/clk/stm32mp_clkfunc.c \ drivers/st/clk/stm32mp1_clk.c \ drivers/st/clk/stm32mp1_clkfunc.c \ drivers/st/ddr/stm32mp1_ddr_helpers.c \ diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 95d3412..beb588c 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -250,4 +250,9 @@ ******************************************************************************/ #define I2C4_BASE U(0x5C002000) +/******************************************************************************* + * Device Tree defines + ******************************************************************************/ +#define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" + #endif /* STM32MP1_DEF_H */