From 7295a143c61cca857078f4c94ca4c16b121ce5e1 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 May 2023 12:03:06 +0200 Subject: [PATCH 01/26] [P-R#6052] drivers: stm32_gpio: helper function to register GPIO banks NOTE: change under review at https://github.com/OP-TEE/optee_os/pull/6052 Adds an helper function (dt_stm32_gpio_bank()) to register GPIO banks in stm32_gpio driver based on DT pinctrl nodes. GPIO banks are registered in a local list from which will be later used to find a bank based on its ID number. The function is expected to be called from the driver probe sequence. The function ensures a bank is not registered twice. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 176 +++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 1 deletion(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index e4ec48af17e..8558ccf4c6e 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause /* - * Copyright (c) 2017-2021, STMicroelectronics + * Copyright (c) 2017-2023, STMicroelectronics * * STM32 GPIO driver is used as pin controller for stm32mp SoCs. * The driver API is defined in header file stm32_gpio.h. @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -48,8 +49,34 @@ #define DT_GPIO_PIN_MASK GENMASK_32(11, 8) #define DT_GPIO_MODE_MASK GENMASK_32(7, 0) +#define DT_GPIO_BANK_NAME0 "GPIOA" + +/** + * struct stm32_gpio_bank - GPIO bank instance + * + * @base: base address of the GPIO controller registers. + * @clock: clock identifier. + * @ngpios: number of GPIOs. + * @bank_id: Id of the bank. + * @lock: lock protecting the GPIO bank access. + * @sec_support: True if bank supports pin security protection, otherwise false + * @seccfgr: Secure configuration register value. + * @link: Link in bank list + */ +struct stm32_gpio_bank { + vaddr_t base; + struct clk *clock; + unsigned int ngpios; + unsigned int bank_id; + unsigned int lock; + STAILQ_ENTRY(stm32_gpio_bank) link; +}; + static unsigned int gpio_lock; +static STAILQ_HEAD(, stm32_gpio_bank) bank_list = + STAILQ_HEAD_INITIALIZER(bank_list); + /* Save to output @cfg the current GPIO (@bank/@pin) configuration */ static void get_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) { @@ -301,6 +328,153 @@ static int get_pinctrl_from_fdt(void *fdt, int node, return (int)found; } +/* Get bank ID from bank node property st,bank-name or panic on failure */ +static unsigned int dt_get_bank_id(const void *fdt, int node) +{ + const int dt_name_len = strlen(DT_GPIO_BANK_NAME0); + const fdt32_t *cuint = NULL; + int len = 0; + + /* Parse "st,bank-name" to get its id (eg: GPIOA -> 0) */ + cuint = fdt_getprop(fdt, node, "st,bank-name", &len); + if (!cuint || (len != dt_name_len + 1)) + panic("Missing/wrong st,bank-name property"); + + if (strncmp((const char *)cuint, DT_GPIO_BANK_NAME0, dt_name_len - 1) || + strcmp((const char *)cuint, DT_GPIO_BANK_NAME0) < 0) + panic("Wrong st,bank-name property"); + + return (unsigned int)strcmp((const char *)cuint, DT_GPIO_BANK_NAME0); +} + +/* + * Return whether or not the GPIO bank related to a DT node is already + * registered in the GPIO bank link. + */ +static bool bank_is_registered(const void *fdt, int node) +{ + unsigned int bank_id = dt_get_bank_id(fdt, node); + struct stm32_gpio_bank *bank = NULL; + + STAILQ_FOREACH(bank, &bank_list, link) + if (bank->bank_id == bank_id) + return true; + + return false; +} + +/* Get GPIO bank information from the DT */ +static TEE_Result dt_stm32_gpio_bank(const void *fdt, int node, + const void *compat_data __unused, + int range_offset, + struct stm32_gpio_bank **out_bank) +{ + TEE_Result res = TEE_ERROR_GENERIC; + struct stm32_gpio_bank *bank = NULL; + const fdt32_t *cuint = NULL; + struct io_pa_va pa_va = { }; + struct clk *clk = NULL; + size_t blen = 0; + paddr_t pa = 0; + int len = 0; + int i = 0; + + assert(out_bank); + + /* Probe deferrable devices first */ + res = clk_dt_get_by_index(fdt, node, 0, &clk); + if (res) + return res; + + bank = calloc(1, sizeof(*bank)); + if (!bank) + return TEE_ERROR_OUT_OF_MEMORY; + + /* + * Do not rely *only* on the "reg" property to get the address, + * but consider also the "ranges" translation property + */ + pa = fdt_reg_base_address(fdt, node); + if (pa == DT_INFO_INVALID_REG) + panic("missing reg property"); + + pa_va.pa = pa + range_offset; + + blen = fdt_reg_size(fdt, node); + if (blen == DT_INFO_INVALID_REG_SIZE) + panic("missing reg size property"); + + DMSG("Bank name %s", fdt_get_name(fdt, node, NULL)); + bank->base = io_pa_or_va_secure(&pa_va, blen); + bank->bank_id = dt_get_bank_id(fdt, node); + bank->clock = clk; + + /* Parse gpio-ranges with its 4 parameters */ + cuint = fdt_getprop(fdt, node, "gpio-ranges", &len); + len /= sizeof(*cuint); + if (len % 4) + panic("wrong gpio-ranges syntax"); + + /* Get the last defined gpio line (offset + nb of pins) */ + for (i = 0; i < len / 4; i++) { + bank->ngpios = MAX(bank->ngpios, + (unsigned int)(fdt32_to_cpu(*(cuint + 1)) + + fdt32_to_cpu(*(cuint + 3)))); + cuint += 4; + } + + *out_bank = bank; + return TEE_SUCCESS; +} + +/* Parse a pinctrl node to register the GPIO banks it describes */ +static TEE_Result __unused dt_stm32_gpio_pinctrl(const void *fdt, int node, + const void *compat_data) +{ + TEE_Result res = TEE_SUCCESS; + const fdt32_t *cuint = NULL; + int range_offs = 0; + int b_node = 0; + int len = 0; + + /* Read the ranges property (for regs memory translation) */ + cuint = fdt_getprop(fdt, node, "ranges", &len); + if (!cuint) + panic("missing ranges property"); + + len /= sizeof(*cuint); + if (len == 3) + range_offs = fdt32_to_cpu(*(cuint + 1)) - fdt32_to_cpu(*cuint); + + fdt_for_each_subnode(b_node, fdt, node) { + cuint = fdt_getprop(fdt, b_node, "gpio-controller", &len); + if (cuint) { + /* + * We found a property "gpio-controller" in the node: + * the node is a GPIO bank description, add it to the + * bank list. + */ + struct stm32_gpio_bank *bank = NULL; + + if (fdt_get_status(fdt, b_node) == DT_STATUS_DISABLED || + bank_is_registered(fdt, b_node)) + continue; + + res = dt_stm32_gpio_bank(fdt, b_node, compat_data, + range_offs, &bank); + if (res) + return res; + + STAILQ_INSERT_TAIL(&bank_list, bank, link); + } else { + if (len != -FDT_ERR_NOTFOUND) + panic(); + } + } + + return TEE_SUCCESS; +} + int stm32_pinctrl_fdt_get_pinctrl(void *fdt, int device_node, struct stm32_pinctrl *pinctrl, size_t count) { From a64c3525064541f235dd0df5f789c9a344435935 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 May 2023 12:03:06 +0200 Subject: [PATCH 02/26] [P-R#6052] drivers: stm32_gpio: probe pinctrl nodes NOTE: change under review at https://github.com/OP-TEE/optee_os/pull/6052 This change makes stm32_gpio driver to register GPIO bank when the driver of probed on compatible pin control instances found in the device tree. This change however does not yet register pinctrl providers to DT_DRIVER framework. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 8558ccf4c6e..ae4a0540674 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -428,8 +428,8 @@ static TEE_Result dt_stm32_gpio_bank(const void *fdt, int node, } /* Parse a pinctrl node to register the GPIO banks it describes */ -static TEE_Result __unused dt_stm32_gpio_pinctrl(const void *fdt, int node, - const void *compat_data) +static TEE_Result dt_stm32_gpio_pinctrl(const void *fdt, int node, + const void *compat_data) { TEE_Result res = TEE_SUCCESS; const fdt32_t *cuint = NULL; @@ -611,3 +611,24 @@ void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, bool secure) clk_disable(clk); cpu_spin_unlock_xrestore(&gpio_lock, exceptions); } + +static TEE_Result stm32_pinctrl_probe(const void *fdt, int node, + const void *compat_data) +{ + /* Register GPIO banks described in this pin control node */ + return dt_stm32_gpio_pinctrl(fdt, node, compat_data); +} + +static const struct dt_device_match stm32_pinctrl_match_table[] = { + { .compatible = "st,stm32mp135-pinctrl" }, + { .compatible = "st,stm32mp157-pinctrl" }, + { .compatible = "st,stm32mp157-z-pinctrl" }, + { } +}; + +DEFINE_DT_DRIVER(stm32_pinctrl_dt_driver) = { + .name = "stm32_gpio-pinctrl", + .type = DT_DRIVER_PINCTRL, + .match_table = stm32_pinctrl_match_table, + .probe = stm32_pinctrl_probe, +}; From eb8db6ffa69c27cc16c5cefde57906ac1c32c204 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 May 2023 12:03:06 +0200 Subject: [PATCH 03/26] [P-R#6052] drivers: stm32_gpio: fix driver header file guards NOTE: change under review at https://github.com/OP-TEE/optee_os/pull/6052 Fixes the names of the macro used as stm32_gpio.h header file guard. Signed-off-by: Etienne Carriere --- core/include/drivers/stm32_gpio.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/include/drivers/stm32_gpio.h b/core/include/drivers/stm32_gpio.h index 7ab12f9d123..7033320051e 100644 --- a/core/include/drivers/stm32_gpio.h +++ b/core/include/drivers/stm32_gpio.h @@ -10,8 +10,8 @@ * as STM32 GPIO driver does no register callbacks to the PM framework. */ -#ifndef __STM32_GPIO_H -#define __STM32_GPIO_H +#ifndef DRIVERS_STM32_GPIO_H +#define DRIVERS_STM32_GPIO_H #include #include @@ -181,4 +181,4 @@ static inline void stm32_gpio_set_secure_cfg(unsigned int bank __unused, */ int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank); -#endif /*__STM32_GPIO_H*/ +#endif /*DRIVERS_STM32_GPIO_H*/ From 9e1ea28001de85ed422c8f3b4fd2cf476e706504 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 22 May 2023 21:20:42 +0200 Subject: [PATCH 04/26] [P-R#6041] core: rename dt_driver_phandle_args to dt_pargs NOTE: under review at https://github.com/OP-TEE/optee_os/pull/6041 Renames struct dt_driver_phandle_args to struct dt_pargs to shorten the label and prevent ugly line breaks in function signatures. Signed-off-by: Etienne Carriere --- core/drivers/atmel_piobu.c | 4 ++-- core/drivers/clk/clk-stm32-core.c | 2 +- core/drivers/clk/clk-stm32mp15.c | 2 +- core/drivers/clk/sam/at91_clk.h | 3 +-- core/drivers/clk/sam/at91_pmc.c | 2 +- core/drivers/gpio/gpio.c | 9 ++++----- core/drivers/i2c/atmel_i2c.c | 6 +++--- core/drivers/pinctrl/atmel_pio.c | 5 +++-- core/drivers/rstctrl/stm32_rstctrl.c | 2 +- core/include/drivers/clk_dt.h | 9 ++++----- core/include/drivers/gpio.h | 12 +++++------- core/include/drivers/i2c.h | 4 ++-- core/include/drivers/pinctrl.h | 2 +- core/include/drivers/rstctrl.h | 2 +- core/include/kernel/dt_driver.h | 8 ++++---- core/kernel/dt_driver.c | 2 +- core/pta/tests/dt_driver_test.c | 14 +++++++------- 17 files changed, 42 insertions(+), 46 deletions(-) diff --git a/core/drivers/atmel_piobu.c b/core/drivers/atmel_piobu.c index 337db7f4fea..f060a1ebce3 100644 --- a/core/drivers/atmel_piobu.c +++ b/core/drivers/atmel_piobu.c @@ -204,13 +204,13 @@ static const struct gpio_ops atmel_piobu_ops = { .set_interrupt = secumod_gpio_set_interrupt, }; -static struct gpio *secumod_dt_get(struct dt_driver_phandle_args *a, void *data, +static struct gpio *secumod_dt_get(struct dt_pargs *pargs, void *data, TEE_Result *res) { struct gpio *gpio = NULL; struct gpio_chip *chip = data; - gpio = gpio_dt_alloc_pin(a, res); + gpio = gpio_dt_alloc_pin(pargs, res); if (*res) return NULL; diff --git a/core/drivers/clk/clk-stm32-core.c b/core/drivers/clk/clk-stm32-core.c index f4c903e4552..39f09e77c12 100644 --- a/core/drivers/clk/clk-stm32-core.c +++ b/core/drivers/clk/clk-stm32-core.c @@ -544,7 +544,7 @@ struct clk *stm32mp_rcc_clock_id_to_clk(unsigned long clock_id) return priv->clk_refs[clock_id]; } -static struct clk *stm32mp_clk_dt_get_clk(struct dt_driver_phandle_args *pargs, +static struct clk *stm32mp_clk_dt_get_clk(struct dt_pargs *pargs, void *data __unused, TEE_Result *res) { unsigned long clock_id = pargs->args[0]; diff --git a/core/drivers/clk/clk-stm32mp15.c b/core/drivers/clk/clk-stm32mp15.c index 58432bbb682..1fcc20ddea4 100644 --- a/core/drivers/clk/clk-stm32mp15.c +++ b/core/drivers/clk/clk-stm32mp15.c @@ -1499,7 +1499,7 @@ static TEE_Result register_stm32mp1_clocks(void) return TEE_SUCCESS; } -static struct clk *stm32mp1_clk_dt_get_clk(struct dt_driver_phandle_args *pargs, +static struct clk *stm32mp1_clk_dt_get_clk(struct dt_pargs *pargs, void *data __unused, TEE_Result *res) { unsigned long clock_id = pargs->args[0]; diff --git a/core/drivers/clk/sam/at91_clk.h b/core/drivers/clk/sam/at91_clk.h index ea539e79e4d..58fadd0bc91 100644 --- a/core/drivers/clk/sam/at91_clk.h +++ b/core/drivers/clk/sam/at91_clk.h @@ -130,8 +130,7 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, unsigned int nperiph, unsigned int ngck, unsigned int npck); -struct clk *clk_dt_pmc_get(struct dt_driver_phandle_args *args, void *data, - TEE_Result *res); +struct clk *clk_dt_pmc_get(struct dt_pargs *args, void *data, TEE_Result *res); struct clk *pmc_clk_get_by_name(struct pmc_clk *clks, unsigned int nclk, const char *name); diff --git a/core/drivers/clk/sam/at91_pmc.c b/core/drivers/clk/sam/at91_pmc.c index 93c76f39c81..69d3bf8d21c 100644 --- a/core/drivers/clk/sam/at91_pmc.c +++ b/core/drivers/clk/sam/at91_pmc.c @@ -80,7 +80,7 @@ TEE_Result pmc_clk_get(struct pmc_data *pmc, unsigned int type, return TEE_SUCCESS; } -struct clk *clk_dt_pmc_get(struct dt_driver_phandle_args *clkspec, void *data, +struct clk *clk_dt_pmc_get(struct dt_pargs *clkspec, void *data, TEE_Result *res) { unsigned int type = clkspec->args[0]; diff --git a/core/drivers/gpio/gpio.c b/core/drivers/gpio/gpio.c index 141fac031ff..49d596109f1 100644 --- a/core/drivers/gpio/gpio.c +++ b/core/drivers/gpio/gpio.c @@ -11,12 +11,11 @@ #include #include -struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a, - TEE_Result *res) +struct gpio *gpio_dt_alloc_pin(struct dt_pargs *pargs, TEE_Result *res) { struct gpio *gpio = NULL; - if (a->args_count != 2) { + if (pargs->args_count != 2) { *res = TEE_ERROR_BAD_PARAMETERS; return NULL; } @@ -27,8 +26,8 @@ struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a, return NULL; } - gpio->pin = a->args[0]; - gpio->dt_flags = a->args[1]; + gpio->pin = pargs->args[0]; + gpio->dt_flags = pargs->args[1]; *res = TEE_SUCCESS; return gpio; diff --git a/core/drivers/i2c/atmel_i2c.c b/core/drivers/i2c/atmel_i2c.c index 13c8eb721a3..03959d3bd2e 100644 --- a/core/drivers/i2c/atmel_i2c.c +++ b/core/drivers/i2c/atmel_i2c.c @@ -278,13 +278,13 @@ static const struct i2c_ctrl_ops atmel_i2c_ops = { .smbus = atmel_i2c_smbus, }; -static struct i2c_dev *atmel_i2c_get_dt_i2c(struct dt_driver_phandle_args *a, - void *data, TEE_Result *res) +static struct i2c_dev *atmel_i2c_get_dt_i2c(struct dt_pargs *args, void *data, + TEE_Result *res) { struct i2c_dev *i2c_dev = NULL; struct i2c_ctrl *i2c_ctrl = data; - i2c_dev = i2c_create_dev(i2c_ctrl, a->fdt, a->phandle_node); + i2c_dev = i2c_create_dev(i2c_ctrl, args->fdt, args->phandle_node); if (!i2c_dev) { *res = TEE_ERROR_OUT_OF_MEMORY; return NULL; diff --git a/core/drivers/pinctrl/atmel_pio.c b/core/drivers/pinctrl/atmel_pio.c index 6d63b1791bd..3a2f9f0d19a 100644 --- a/core/drivers/pinctrl/atmel_pio.c +++ b/core/drivers/pinctrl/atmel_pio.c @@ -76,7 +76,7 @@ static const struct pinctrl_ops pio_pinctrl_ops = { .conf_free = pio_conf_free, }; -static struct pinconf *pio_pinctrl_dt_get(struct dt_driver_phandle_args *a, +static struct pinconf *pio_pinctrl_dt_get(struct dt_pargs *pargs, void *data, TEE_Result *res) { int i = 0; @@ -94,7 +94,8 @@ static struct pinconf *pio_pinctrl_dt_get(struct dt_driver_phandle_args *a, struct atmel_pio *atmel_pio = data; struct atmel_pio_pin_conf *pio_conf = NULL; - prop = fdt_getprop(a->fdt, a->phandle_node, "pinmux", &prop_count); + prop = fdt_getprop(pargs->fdt, pargs->phandle_node, "pinmux", + &prop_count); if (!prop) { *res = TEE_ERROR_ITEM_NOT_FOUND; return NULL; diff --git a/core/drivers/rstctrl/stm32_rstctrl.c b/core/drivers/rstctrl/stm32_rstctrl.c index ac05df48bbb..15e07935f7b 100644 --- a/core/drivers/rstctrl/stm32_rstctrl.c +++ b/core/drivers/rstctrl/stm32_rstctrl.c @@ -179,7 +179,7 @@ struct rstctrl *stm32mp_rcc_reset_id_to_rstctrl(unsigned int binding_id) return &rstline->rstctrl; } -static struct rstctrl *stm32_rstctrl_get_dev(struct dt_driver_phandle_args *arg, +static struct rstctrl *stm32_rstctrl_get_dev(struct dt_pargs *arg, void *priv_data __unused, TEE_Result *res) { diff --git a/core/include/drivers/clk_dt.h b/core/include/drivers/clk_dt.h index 018a112343e..6f7c00d548f 100644 --- a/core/include/drivers/clk_dt.h +++ b/core/include/drivers/clk_dt.h @@ -75,8 +75,8 @@ TEE_Result clk_dt_get_by_name(const void *fdt, int nodeoffset, * description or NULL if invalid description in which case @res provides the * error code. */ -typedef struct clk *(*clk_dt_get_func)(struct dt_driver_phandle_args *args, - void *data, TEE_Result *res); +typedef struct clk *(*clk_dt_get_func)(struct dt_pargs *args, void *data, + TEE_Result *res); /** * clk_dt_register_clk_provider - Register a clock provider @@ -100,9 +100,8 @@ TEE_Result clk_dt_register_clk_provider(const void *fdt, int nodeoffset, * clk_dt_get_simple_clk: simple clock matching function for single clock * providers */ -static inline -struct clk *clk_dt_get_simple_clk(struct dt_driver_phandle_args *args __unused, - void *data, TEE_Result *res) +static inline struct clk *clk_dt_get_simple_clk(struct dt_pargs *args __unused, + void *data, TEE_Result *res) { *res = TEE_SUCCESS; diff --git a/core/include/drivers/gpio.h b/core/include/drivers/gpio.h index cca17a2cc7e..9c4078840bc 100644 --- a/core/include/drivers/gpio.h +++ b/core/include/drivers/gpio.h @@ -127,8 +127,7 @@ static inline enum gpio_level gpio_get_value(struct gpio *gpio) * the devicetree description or NULL if invalid description in which case * @res provides the error code. */ -struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a, - TEE_Result *res); +struct gpio *gpio_dt_alloc_pin(struct dt_pargs *pargs, TEE_Result *res); /** * gpio_dt_get_by_index() - Get a GPIO controller at a specific index in @@ -158,9 +157,8 @@ static inline TEE_Result gpio_dt_get_by_index(const void *fdt __unused, return TEE_ERROR_NOT_SUPPORTED; } -static inline -struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a __unused, - TEE_Result *res) +static inline struct gpio *gpio_dt_alloc_pin(struct dt_pargs *pargs __unused, + TEE_Result *res) { *res = TEE_ERROR_NOT_SUPPORTED; return NULL; @@ -182,8 +180,8 @@ struct gpio *gpio_dt_alloc_pin(struct dt_driver_phandle_args *a __unused, * the devicetree description or NULL if invalid description in which case * @res provides the error code. */ -typedef struct gpio *(*gpio_dt_get_func)(struct dt_driver_phandle_args *a, - void *data, TEE_Result *res); +typedef struct gpio *(*gpio_dt_get_func)(struct dt_pargs *pargs, void *data, + TEE_Result *res); /** * gpio_dt_register_provider() - Register a GPIO controller provider diff --git a/core/include/drivers/i2c.h b/core/include/drivers/i2c.h index 32d0915aa24..982e13b2699 100644 --- a/core/include/drivers/i2c.h +++ b/core/include/drivers/i2c.h @@ -239,8 +239,8 @@ static inline TEE_Result i2c_dt_get_dev(const void *fdt __unused, * the devicetree description or NULL if invalid description in which case * @res provides the error code. */ -typedef struct i2c_dev *(*i2c_dt_get_func)(struct dt_driver_phandle_args *a, - void *data, TEE_Result *res); +typedef struct i2c_dev *(*i2c_dt_get_func)(struct dt_pargs *args, void *data, + TEE_Result *res); /** * i2c_dt_register_provider - Register a I2C controller provider and add all the diff --git a/core/include/drivers/pinctrl.h b/core/include/drivers/pinctrl.h index 8cf6f478cc7..ad7b67c12df 100644 --- a/core/include/drivers/pinctrl.h +++ b/core/include/drivers/pinctrl.h @@ -49,7 +49,7 @@ struct pinctrl_ops { void (*conf_free)(struct pinconf *conf); }; -typedef struct pinconf *(*pinctrl_dt_get_func)(struct dt_driver_phandle_args *a, +typedef struct pinconf *(*pinctrl_dt_get_func)(struct dt_pargs *pargs, void *data, TEE_Result *res); #ifdef CFG_DRIVERS_PINCTRL diff --git a/core/include/drivers/rstctrl.h b/core/include/drivers/rstctrl.h index 6fb89c3a93f..36eac6ea0f4 100644 --- a/core/include/drivers/rstctrl.h +++ b/core/include/drivers/rstctrl.h @@ -210,7 +210,7 @@ TEE_Result rstctrl_dt_get_by_name(const void *fdt, int nodeoffset, * the devicetree description or NULL if invalid description in which case * @res provides the error code. */ -typedef struct rstctrl *(*rstctrl_dt_get_func)(struct dt_driver_phandle_args *a, +typedef struct rstctrl *(*rstctrl_dt_get_func)(struct dt_pargs *args, void *data, TEE_Result *res); /** diff --git a/core/include/kernel/dt_driver.h b/core/include/kernel/dt_driver.h index 05d1e3d4d24..d7f410974f0 100644 --- a/core/include/kernel/dt_driver.h +++ b/core/include/kernel/dt_driver.h @@ -78,13 +78,13 @@ struct dt_driver { struct dt_driver_provider; /** - * struct dt_driver_phandle_args - Devicetree phandle arguments + * struct dt_pargs - Devicetree phandle arguments * @fdt: Device-tree to work on * @phandle_node: Node pointed by the specifier phandle * @args_count: Count of cells for the device * @args: Device consumer specifiers */ -struct dt_driver_phandle_args { +struct dt_pargs { const void *fdt; int phandle_node; int args_count; @@ -106,8 +106,8 @@ struct dt_driver_phandle_args { * Return a device opaque reference, e.g. a struct clk pointer for a clock * driver, or NULL if not found in which case @res provides the error code. */ -typedef void *(*get_of_device_func)(struct dt_driver_phandle_args *parg, - void *data, TEE_Result *res); +typedef void *(*get_of_device_func)(struct dt_pargs *parg, void *data, + TEE_Result *res); /** * dt_driver_register_provider - Register a driver provider diff --git a/core/kernel/dt_driver.c b/core/kernel/dt_driver.c index 3055162714d..3ab73f34eee 100644 --- a/core/kernel/dt_driver.c +++ b/core/kernel/dt_driver.c @@ -240,7 +240,7 @@ static void *device_from_provider_prop(struct dt_driver_provider *prv, const void *fdt, int phandle_node, const uint32_t *prop, TEE_Result *res) { - struct dt_driver_phandle_args *pargs = NULL; + struct dt_pargs *pargs = NULL; unsigned int n = 0; void *device = NULL; diff --git a/core/pta/tests/dt_driver_test.c b/core/pta/tests/dt_driver_test.c index a290ba5837f..11a7f9a72b4 100644 --- a/core/pta/tests/dt_driver_test.c +++ b/core/pta/tests/dt_driver_test.c @@ -443,8 +443,8 @@ static const char *dt_test_clk_name[DT_TEST_CLK_COUNT] = { /* Emulating a clock does not require operators */ static const struct clk_ops dt_test_clock_provider_ops; -static struct clk *dt_test_get_clk(struct dt_driver_phandle_args *args, - void *data, TEE_Result *res) +static struct clk *dt_test_get_clk(struct dt_pargs *args, void *data, + TEE_Result *res) { struct clk *clk_ref = data; struct clk *clk = NULL; @@ -566,8 +566,8 @@ const struct rstctrl_ops dt_test_rstctrl_ops = { .get_name = dt_test_rstctrl_name, }; -static struct rstctrl *dt_test_get_rstctrl(struct dt_driver_phandle_args *args, - void *data, TEE_Result *res) +static struct rstctrl *dt_test_get_rstctrl(struct dt_pargs *args, void *data, + TEE_Result *res) { struct dt_test_rstctrl *ref = data; struct rstctrl *rstctrl = NULL; @@ -698,13 +698,13 @@ static const struct gpio_ops dt_test_gpio_ops = { .set_value = dt_test_gpio_set_value, }; -static struct gpio *dt_test_gpio_get_dt(struct dt_driver_phandle_args *a, - void *data, TEE_Result *res) +static struct gpio *dt_test_gpio_get_dt(struct dt_pargs *args, void *data, + TEE_Result *res) { struct gpio *gpio = NULL; struct dt_test_gpio *gpios = (struct dt_test_gpio *)data; - gpio = gpio_dt_alloc_pin(a, res); + gpio = gpio_dt_alloc_pin(args, res); if (*res) return NULL; From a1f9e45f3d925f3639d8242d029f1cb32ed0682a Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 16:37:24 +0200 Subject: [PATCH 05/26] [P-R#6049] drivers: pinctrl: fix stubbed pinctrl_free_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NOTE: under review at https://github.com/OP-TEE/optee_os/pull/6049 Fixes pinctrl_free_state() when CFG_DRIVERS_PINCTRL is disabled as the API function has no return value. The issue is reported by GCC with an error trace like the below: core/include/drivers/pinctrl.h: In function ‘pinctrl_free_state’: lib/libutee/include/tee_api_defines.h:117:43: error: ‘return’ with a value, in function returning void [-Werror=return-type] 117 | #define TEE_ERROR_NOT_SUPPORTED 0xFFFF000A | ^~~~~~~~~~ core/include/drivers/pinctrl.h:158:16: note: in expansion of macro ‘TEE_ERROR_NOT_SUPPORTED’ 158 | return TEE_ERROR_NOT_SUPPORTED; | ^~~~~~~~~~~~~~~~~~~~~~~ In file included from core/include/drivers/stm32_uart.h:10, from core/arch/arm/plat-stm32mp1/main.c:14: core/include/drivers/pinctrl.h:156:6: note: declared here 156 | void pinctrl_free_state(struct pinctrl_state *state __unused) | ^~~~~~~~~~~~~~~~~~ Fixes: 9aec039ec0d7 ("drivers: pinctrl: add pinctrl support") Signed-off-by: Etienne Carriere --- core/include/drivers/pinctrl.h | 1 - 1 file changed, 1 deletion(-) diff --git a/core/include/drivers/pinctrl.h b/core/include/drivers/pinctrl.h index ad7b67c12df..ca03145b080 100644 --- a/core/include/drivers/pinctrl.h +++ b/core/include/drivers/pinctrl.h @@ -155,7 +155,6 @@ TEE_Result pinctrl_get_state_by_idx(const void *fdt __unused, static inline void pinctrl_free_state(struct pinctrl_state *state __unused) { - return TEE_ERROR_NOT_SUPPORTED; } static inline From 814d467155bcd38fa80aaca4094776be0e750600 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 May 2023 11:52:50 +0200 Subject: [PATCH 06/26] [P-R#6053] drivers: stm32_gpio: consider DT output data configuration NOTE: under review at https://github.com/OP-TEE/optee_os/pull/6053 Get output data pin configuration from DT node property "output-high" and "output-low". Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index ae4a0540674..54d92022251 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -258,6 +258,7 @@ static int get_pinctrl_from_fdt(void *fdt, int node, uint32_t pin = 0; uint32_t mode = 0; uint32_t alternate = 0; + uint32_t odata = 0; bool opendrain = false; pincfg = fdt32_to_cpu(*cuint); @@ -303,6 +304,20 @@ static int get_pinctrl_from_fdt(void *fdt, int node, if (fdt_getprop(fdt, node, "drive-open-drain", NULL)) opendrain = true; + if (fdt_getprop(fdt, node, "output-high", NULL)) { + if (mode == GPIO_MODE_INPUT) { + mode = GPIO_MODE_OUTPUT; + odata = 1; + } + } + + if (fdt_getprop(fdt, node, "output-low", NULL)) { + if (mode == GPIO_MODE_INPUT) { + mode = GPIO_MODE_OUTPUT; + odata = 0; + } + } + /* Check GPIO bank clock/base address against platform */ ckeck_gpio_bank(fdt, bank, pinctrl_node); @@ -315,7 +330,7 @@ static int get_pinctrl_from_fdt(void *fdt, int node, ref->active_cfg.otype = opendrain ? 1 : 0; ref->active_cfg.ospeed = speed; ref->active_cfg.pupd = pull; - ref->active_cfg.od = 0; + ref->active_cfg.od = odata; ref->active_cfg.af = alternate; /* Default to analog mode for standby state */ ref->standby_cfg.mode = GPIO_MODE_ANALOG; From 89990ccd8353f7403d4940c49397570d3224a20a Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 26 May 2023 08:30:55 +0200 Subject: [PATCH 07/26] [P-R#6056] drivers: gpio: add put operation handle NOTE: under review at https://github.com/OP-TEE/optee_os/pull/6056 Adds a put operation handler for a GPIO consumer driver to be able to release the GPIO resources it has allocated when getting its GPIO. This is needed for example, when such a consumer driver must defer its probe sequence and will get again its GPIO making gpio_dt_alloc_pin() to be called again. Signed-off-by: Etienne Carriere --- core/include/drivers/gpio.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/include/drivers/gpio.h b/core/include/drivers/gpio.h index 9c4078840bc..07533fea9f1 100644 --- a/core/include/drivers/gpio.h +++ b/core/include/drivers/gpio.h @@ -6,6 +6,7 @@ #ifndef DRIVERS_GPIO_H #define DRIVERS_GPIO_H +#include #include #include #include @@ -46,6 +47,9 @@ enum gpio_interrupt { GPIO_INTERRUPT_ENABLE }; +struct gpio; +struct gpio_ops; + struct gpio_chip { const struct gpio_ops *ops; }; @@ -63,6 +67,8 @@ struct gpio_ops { unsigned int gpio_pin); void (*set_interrupt)(struct gpio_chip *chip, unsigned int gpio_pin, enum gpio_interrupt enable_disable); + /* Release GPIO resources */ + void (*put)(struct gpio_chip *chip, struct gpio *gpio); }; /* @@ -113,6 +119,14 @@ static inline enum gpio_level gpio_get_value(struct gpio *gpio) return value; } +static inline void gpio_put(struct gpio *gpio) +{ + assert(!gpio || (gpio->chip && gpio->chip->ops)); + + if (gpio && gpio->chip->ops->put) + gpio->chip->ops->put(gpio->chip, gpio); +} + #if defined(CFG_DT) && defined(CFG_DRIVERS_GPIO) /** * gpio_dt_alloc_pin() - Get an allocated GPIO instance from its DT phandle From b8e966b4a9484c04ca6508f94c3247d0f718756b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 26 May 2023 08:39:18 +0200 Subject: [PATCH 08/26] drivers: stm32_gpio: support CFG_DRIVERS_GPIO Changes stm32_gpio driver to register GPIO provider resources for each GPIO bank registered when CFG_DRIVERS_GPIO is enabled. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 181 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 54d92022251..63b2e5f6ad9 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ * * @base: base address of the GPIO controller registers. * @clock: clock identifier. + * @gpio_chip: GPIO chip reference for that GPIO bank * @ngpios: number of GPIOs. * @bank_id: Id of the bank. * @lock: lock protecting the GPIO bank access. @@ -66,6 +68,7 @@ struct stm32_gpio_bank { vaddr_t base; struct clk *clock; + struct gpio_chip gpio_chip; unsigned int ngpios; unsigned int bank_id; unsigned int lock; @@ -77,6 +80,118 @@ static unsigned int gpio_lock; static STAILQ_HEAD(, stm32_gpio_bank) bank_list = STAILQ_HEAD_INITIALIZER(bank_list); +static struct stm32_gpio_bank *gpio_chip_to_bank(struct gpio_chip *chip) +{ + return container_of(chip, struct stm32_gpio_bank, gpio_chip); +} + +static enum gpio_level stm32_gpio_get_level(struct gpio_chip *chip, + unsigned int gpio_pin) +{ + struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip); + unsigned int reg_offset = 0; + unsigned int mode = 0; + + assert(gpio_pin < bank->ngpios); + + mode = (io_read32(bank->base + GPIO_MODER_OFFSET) >> (gpio_pin << 1)) & + GPIO_MODE_MASK; + + switch (mode) { + case GPIO_MODE_INPUT: + reg_offset = GPIO_IDR_OFFSET; + break; + case GPIO_MODE_OUTPUT: + reg_offset = GPIO_ODR_OFFSET; + break; + default: + panic(); + } + + if (io_read32(bank->base + reg_offset) & BIT(gpio_pin)) + return GPIO_LEVEL_HIGH; + else + return GPIO_LEVEL_LOW; +} + +static void stm32_gpio_set_level(struct gpio_chip *chip, unsigned int gpio_pin, + enum gpio_level level) +{ + struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip); + + assert(gpio_pin < bank->ngpios); + + if (level == GPIO_LEVEL_HIGH) + io_write32(bank->base + GPIO_BSRR_OFFSET, BIT(gpio_pin)); + else + io_write32(bank->base + GPIO_BSRR_OFFSET, BIT(gpio_pin + 16)); +} + +static enum gpio_dir stm32_gpio_get_direction(struct gpio_chip *chip, + unsigned int gpio_pin) +{ + struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip); + uint32_t mode = 0; + + assert(gpio_pin < bank->ngpios); + + mode = (io_read32(bank->base + GPIO_MODER_OFFSET) >> (gpio_pin << 1)) & + GPIO_MODE_MASK; + + switch (mode) { + case GPIO_MODE_INPUT: + return GPIO_DIR_IN; + case GPIO_MODE_OUTPUT: + return GPIO_DIR_OUT; + default: + panic(); + } +} + +static void stm32_gpio_set_direction(struct gpio_chip *chip, + unsigned int gpio_pin, + enum gpio_dir direction) +{ + struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip); + uint32_t exceptions = 0; + uint32_t mode = 0; + + assert(gpio_pin < bank->ngpios); + + if (direction == GPIO_DIR_IN) + mode = GPIO_MODE_INPUT; + else + mode = GPIO_MODE_OUTPUT; + + exceptions = cpu_spin_lock_xsave(&gpio_lock); + io_clrsetbits32(bank->base + GPIO_MODER_OFFSET, + SHIFT_U32(GPIO_MODE_MASK, gpio_pin << 1), + SHIFT_U32(mode, gpio_pin << 1)); + cpu_spin_unlock_xrestore(&gpio_lock, exceptions); +} + +static bool is_stm32_gpio_chip(struct gpio_chip *chip); + +static void stm32_gpio_put_gpio(struct gpio_chip *chip __maybe_unused, + struct gpio *gpio) +{ + assert(is_stm32_gpio_chip(chip)); + free(gpio); +} + +static const struct gpio_ops stm32_gpio_ops = { + .get_direction = stm32_gpio_get_direction, + .set_direction = stm32_gpio_set_direction, + .get_value = stm32_gpio_get_level, + .set_value = stm32_gpio_set_level, + .put = stm32_gpio_put_gpio, +}; + +static bool __maybe_unused is_stm32_gpio_chip(struct gpio_chip *chip) +{ + return chip && chip->ops == &stm32_gpio_ops; +} + /* Save to output @cfg the current GPIO (@bank/@pin) configuration */ static void get_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) { @@ -343,6 +458,65 @@ static int get_pinctrl_from_fdt(void *fdt, int node, return (int)found; } +static struct gpio *stm32_gpio_get_dt(struct dt_pargs *pargs, + void *data, TEE_Result *res) +{ + struct stm32_gpio_bank *bank = data; + struct gpio *gpio = NULL; + unsigned int shift_1b = 0; + unsigned int shift_2b = 0; + uint32_t exceptions = 0; + uint32_t otype = 0; + uint32_t pupd = 0; + uint32_t mode = 0; + + gpio = gpio_dt_alloc_pin(pargs, res); + if (*res) + return NULL; + + if (gpio->pin >= bank->ngpios) { + DMSG("Invalid GPIO reference"); + free(gpio); + return NULL; + } + + shift_1b = gpio->pin; + shift_2b = SHIFT_U32(gpio->pin, 1); + + if (gpio->dt_flags & GPIO_PULL_UP) + pupd = GPIO_PUPD_PULL_UP; + else if (gpio->dt_flags & GPIO_PULL_DOWN) + pupd = GPIO_PUPD_PULL_DOWN; + else + pupd = GPIO_PUPD_NO_PULL; + + if (gpio->dt_flags & GPIO_LINE_OPEN_DRAIN) + otype = GPIO_OTYPE_OPEN_DRAIN; + else + otype = GPIO_OTYPE_PUSH_PULL; + + exceptions = cpu_spin_lock_xsave(&gpio_lock); + + io_clrsetbits32(bank->base + GPIO_MODER_OFFSET, + SHIFT_U32(GPIO_MODE_MASK, shift_2b), + SHIFT_U32(mode, shift_2b)); + + io_clrsetbits32(bank->base + GPIO_OTYPER_OFFSET, + SHIFT_U32(GPIO_OTYPE_OPEN_DRAIN, shift_1b), + SHIFT_U32(otype, shift_1b)); + + io_clrsetbits32(bank->base + GPIO_PUPDR_OFFSET, + SHIFT_U32(GPIO_PUPD_PULL_MASK, shift_2b), + SHIFT_U32(pupd, shift_2b)); + + cpu_spin_unlock_xrestore(&gpio_lock, exceptions); + + gpio->chip = &bank->gpio_chip; + + *res = TEE_SUCCESS; + return gpio; +} + /* Get bank ID from bank node property st,bank-name or panic on failure */ static unsigned int dt_get_bank_id(const void *fdt, int node) { @@ -423,6 +597,7 @@ static TEE_Result dt_stm32_gpio_bank(const void *fdt, int node, bank->base = io_pa_or_va_secure(&pa_va, blen); bank->bank_id = dt_get_bank_id(fdt, node); bank->clock = clk; + bank->gpio_chip.ops = &stm32_gpio_ops; /* Parse gpio-ranges with its 4 parameters */ cuint = fdt_getprop(fdt, node, "gpio-ranges", &len); @@ -480,6 +655,12 @@ static TEE_Result dt_stm32_gpio_pinctrl(const void *fdt, int node, if (res) return res; + /* Registering a provider should not defer probe */ + res = gpio_register_provider(fdt, b_node, + stm32_gpio_get_dt, bank); + if (res) + panic(); + STAILQ_INSERT_TAIL(&bank_list, bank, link); } else { if (len != -FDT_ERR_NOTFOUND) From 2ce07b41b0c7a5bdcf11d4460427b4a7f8224abb Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 30 May 2023 07:20:17 +0200 Subject: [PATCH 09/26] plat-stm32mp1: enable CFG_DRIVERS_GPIO Enables CFG_DRIVERS_GPIO for platform stm32mp1. Signed-off-by: Etienne Carriere --- core/arch/arm/plat-stm32mp1/conf.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/core/arch/arm/plat-stm32mp1/conf.mk b/core/arch/arm/plat-stm32mp1/conf.mk index a7134e11c3d..13bb465e333 100644 --- a/core/arch/arm/plat-stm32mp1/conf.mk +++ b/core/arch/arm/plat-stm32mp1/conf.mk @@ -92,6 +92,7 @@ include core/arch/arm/cpu/cortex-a7.mk $(call force,CFG_DRIVERS_CLK,y) $(call force,CFG_DRIVERS_CLK_DT,y) +$(call force,CFG_DRIVERS_GPIO,y) $(call force,CFG_GIC,y) $(call force,CFG_INIT_CNTVOFF,y) $(call force,CFG_PSCI_ARM32,y) From 5f89ae3412981ce38092f99607ea7f126dd33fc9 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 26 May 2023 08:50:49 +0200 Subject: [PATCH 10/26] drivers: stm32_gpio: remove GPIO access specific API functions Removes stm32_gpio API functions to access GPIOs as the driver has moved to the generic GPIO framework and consumer driver should use the generic API to access GPIOs. The driver now expects CFG_DRIVERS_GPIO is enabled. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 56 +++---------------------------- core/include/drivers/stm32_gpio.h | 41 ---------------------- 2 files changed, 4 insertions(+), 93 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 63b2e5f6ad9..4918cf6038a 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -3,7 +3,6 @@ * Copyright (c) 2017-2023, STMicroelectronics * * STM32 GPIO driver is used as pin controller for stm32mp SoCs. - * The driver API is defined in header file stm32_gpio.h. */ #include @@ -24,6 +23,10 @@ #include #include +#ifndef CFG_DRIVERS_GPIO +#error stm32_gpio driver expects CFG_DRIVERS_GPIO +#endif + #define GPIO_PIN_MAX 15 #define GPIO_MODER_OFFSET 0x00 @@ -740,57 +743,6 @@ int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank) return -1; } -static __maybe_unused bool valid_gpio_config(unsigned int bank, - unsigned int pin, bool input) -{ - vaddr_t base = stm32_get_gpio_bank_base(bank); - uint32_t mode = (io_read32(base + GPIO_MODER_OFFSET) >> (pin << 1)) & - GPIO_MODE_MASK; - - if (pin > GPIO_PIN_MAX) - return false; - - if (input) - return mode == GPIO_MODE_INPUT; - else - return mode == GPIO_MODE_OUTPUT; -} - -int stm32_gpio_get_input_level(unsigned int bank, unsigned int pin) -{ - vaddr_t base = stm32_get_gpio_bank_base(bank); - struct clk *clk = stm32_get_gpio_bank_clk(bank); - int rc = 0; - - clk_enable(clk); - - assert(valid_gpio_config(bank, pin, true)); - - if (io_read32(base + GPIO_IDR_OFFSET) == BIT(pin)) - rc = 1; - - clk_disable(clk); - - return rc; -} - -void stm32_gpio_set_output_level(unsigned int bank, unsigned int pin, int level) -{ - vaddr_t base = stm32_get_gpio_bank_base(bank); - struct clk *clk = stm32_get_gpio_bank_clk(bank); - - clk_enable(clk); - - assert(valid_gpio_config(bank, pin, false)); - - if (level) - io_write32(base + GPIO_BSRR_OFFSET, BIT(pin)); - else - io_write32(base + GPIO_BSRR_OFFSET, BIT(pin + 16)); - - clk_disable(clk); -} - void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, bool secure) { vaddr_t base = stm32_get_gpio_bank_base(bank); diff --git a/core/include/drivers/stm32_gpio.h b/core/include/drivers/stm32_gpio.h index 7033320051e..f3f5c08daf4 100644 --- a/core/include/drivers/stm32_gpio.h +++ b/core/include/drivers/stm32_gpio.h @@ -111,47 +111,6 @@ void stm32_pinctrl_store_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt); int stm32_pinctrl_fdt_get_pinctrl(void *fdt, int node, struct stm32_pinctrl *pinctrl, size_t count); -/* - * Set target output GPIO pin to high or low level - * - * @bank: GPIO bank identifier as assigned by the platform - * @pin: GPIO pin position in the GPIO bank - * @high: 1 to set GPIO to high level, 0 to set to GPIO low level - */ -void stm32_gpio_set_output_level(unsigned int bank, unsigned int pin, int high); - -/* - * Set output GPIO pin referenced by @pinctrl to high or low level - * - * @pinctrl: Reference to pinctrl - * @high: 1 to set GPIO to high level, 0 to set to GPIO low level - */ -static inline void stm32_pinctrl_set_gpio_level(struct stm32_pinctrl *pinctrl, - int high) -{ - stm32_gpio_set_output_level(pinctrl->bank, pinctrl->pin, high); -} - -/* - * Get input GPIO pin current level, high or low - * - * @bank: GPIO bank identifier as assigned by the platform - * @pin: GPIO pin position in the GPIO bank - * Return 1 if GPIO level is high, 0 if it is low - */ -int stm32_gpio_get_input_level(unsigned int bank, unsigned int pin); - -/* - * Set target output GPIO pin to high or low level - * - * @pinctrl: Reference to pinctrl - * Return 1 if GPIO level is high, 0 if it is low - */ -static inline int stm32_pinctrl_get_gpio_level(struct stm32_pinctrl *pinctrl) -{ - return stm32_gpio_get_input_level(pinctrl->bank, pinctrl->pin); -} - #ifdef CFG_STM32_GPIO /* * Configure pin muxing access permission: can be secure or not From 87cbd91b78d2f94292b326a6f0b60de0d4ceb092 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 May 2023 12:03:06 +0200 Subject: [PATCH 11/26] drivers: stm32_gpio: support CFG_DRIVERS_PINCTRL Changes stm32_gpio driver to support generic pin control framework (CFG_DRIVERS_PINCTRL=y). Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 139 ++++++++++++++++++++++++++++-- core/include/drivers/stm32_gpio.h | 18 ++-- 2 files changed, 143 insertions(+), 14 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 4918cf6038a..e06d6b39b54 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,16 @@ #define DT_GPIO_BANK_NAME0 "GPIOA" +/* + * struct stm32_pinctrl_array - Array of pins in a pin control state + * @count: Number of cells in @pinctrl + * @pinctrl: Pin controls configuration + */ +struct stm32_pinctrl_array { + size_t count; + struct stm32_pinctrl pinctrl[]; +}; + /** * struct stm32_gpio_bank - GPIO bank instance * @@ -196,7 +207,8 @@ static bool __maybe_unused is_stm32_gpio_chip(struct gpio_chip *chip) } /* Save to output @cfg the current GPIO (@bank/@pin) configuration */ -static void get_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) +static void __maybe_unused get_gpio_cfg(uint32_t bank, uint32_t pin, + struct gpio_cfg *cfg) { vaddr_t base = stm32_get_gpio_bank_base(bank); struct clk *clk = stm32_get_gpio_bank_clk(bank); @@ -280,6 +292,7 @@ static void set_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) cpu_spin_unlock_xrestore(&gpio_lock, exceptions); } +#if !defined(CFG_DRIVERS_PINCTRL) void stm32_pinctrl_load_active_cfg(struct stm32_pinctrl *pinctrl, size_t cnt) { size_t n = 0; @@ -308,7 +321,7 @@ void stm32_pinctrl_store_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt) } /* Panic if GPIO bank information from platform do not match DTB description */ -static void ckeck_gpio_bank(void *fdt, uint32_t bank, int pinctrl_node) +static void ckeck_gpio_bank(const void *fdt, uint32_t bank, int pinctrl_node) { int pinctrl_subnode = 0; @@ -340,14 +353,16 @@ static void ckeck_gpio_bank(void *fdt, uint32_t bank, int pinctrl_node) panic(); } +#endif /*CFG_DRIVERS_PINCTRL*/ /* Count pins described in the DT node and get related data if possible */ -static int get_pinctrl_from_fdt(void *fdt, int node, +static int get_pinctrl_from_fdt(const void *fdt, int node, struct stm32_pinctrl *pinctrl, size_t count) { - const fdt32_t *cuint, *slewrate; + const fdt32_t *cuint = NULL; + const fdt32_t *slewrate = NULL; int len = 0; - int pinctrl_node = 0; + int __maybe_unused pinctrl_node = 0; uint32_t i = 0; uint32_t speed = GPIO_OSPEED_LOW; uint32_t pull = GPIO_PUPD_NO_PULL; @@ -357,9 +372,11 @@ static int get_pinctrl_from_fdt(void *fdt, int node, if (!cuint) return -FDT_ERR_NOTFOUND; +#if !defined(CFG_DRIVERS_PINCTRL) pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node)); if (pinctrl_node < 0) return -FDT_ERR_NOTFOUND; +#endif slewrate = fdt_getprop(fdt, node, "slew-rate", NULL); if (slewrate) @@ -436,14 +453,24 @@ static int get_pinctrl_from_fdt(void *fdt, int node, } } +#if !defined(CFG_DRIVERS_PINCTRL) /* Check GPIO bank clock/base address against platform */ ckeck_gpio_bank(fdt, bank, pinctrl_node); +#endif if (found < count) { struct stm32_pinctrl *ref = &pinctrl[found]; ref->bank = (uint8_t)bank; ref->pin = (uint8_t)pin; +#ifdef CFG_DRIVERS_PINCTRL + ref->cfg.mode = mode; + ref->cfg.otype = opendrain ? 1 : 0; + ref->cfg.ospeed = speed; + ref->cfg.pupd = pull; + ref->cfg.od = odata; + ref->cfg.af = alternate; +#else ref->active_cfg.mode = mode; ref->active_cfg.otype = opendrain ? 1 : 0; ref->active_cfg.ospeed = speed; @@ -453,6 +480,7 @@ static int get_pinctrl_from_fdt(void *fdt, int node, /* Default to analog mode for standby state */ ref->standby_cfg.mode = GPIO_MODE_ANALOG; ref->standby_cfg.pupd = GPIO_PUPD_NO_PULL; +#endif } found++; @@ -674,6 +702,7 @@ static TEE_Result dt_stm32_gpio_pinctrl(const void *fdt, int node, return TEE_SUCCESS; } +#ifndef CFG_DRIVERS_PINCTRL int stm32_pinctrl_fdt_get_pinctrl(void *fdt, int device_node, struct stm32_pinctrl *pinctrl, size_t count) { @@ -716,6 +745,7 @@ int stm32_pinctrl_fdt_get_pinctrl(void *fdt, int device_node, return (int)found; } +#endif /*CFG_DRIVERS_PINCTRL*/ int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank) { @@ -760,11 +790,108 @@ void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, bool secure) cpu_spin_unlock_xrestore(&gpio_lock, exceptions); } +#ifdef CFG_DRIVERS_PINCTRL +static TEE_Result stm32_pinctrl_conf_apply(struct pinconf *conf) +{ + struct stm32_pinctrl_array *ref = conf->priv; + struct stm32_pinctrl *p = ref->pinctrl; + size_t pin_count = ref->count; + size_t n = 0; + + for (n = 0; n < pin_count; n++) + set_gpio_cfg(p[n].bank, p[n].pin, &p[n].cfg); + + return TEE_SUCCESS; +} + +static void stm32_pinctrl_conf_free(struct pinconf *conf) +{ + free(conf); +} + +static const struct pinctrl_ops stm32_pinctrl_ops = { + .conf_apply = stm32_pinctrl_conf_apply, + .conf_free = stm32_pinctrl_conf_free, +}; + +DECLARE_KEEP_PAGER(stm32_pinctrl_ops); + +/* Allocate and return a pinctrl configuration from a DT reference */ +static struct pinconf *stm32_pinctrl_dt_get(struct dt_pargs *pargs, + void *data __unused, + TEE_Result *res) +{ + struct conf { + struct pinconf pinconf; + struct stm32_pinctrl_array array_ref; + } *loc_conf = NULL; + struct stm32_pinctrl *pinctrl = NULL; + struct pinconf *pinconf = NULL; + const void *fdt = NULL; + size_t pin_count = 0; + int pinctrl_node = 0; + int pinmux_node = 0; + int count = 0; + + pinctrl_node = pargs->phandle_node; + fdt = pargs->fdt; + assert(fdt && pinctrl_node); + + fdt_for_each_subnode(pinmux_node, fdt, pinctrl_node) { + if (fdt_getprop(fdt, pinmux_node, "pinmux", &count)) + pin_count += (size_t)count / sizeof(uint32_t); + else if (count != -FDT_ERR_NOTFOUND) + panic(); + } + + loc_conf = calloc(1, sizeof(*loc_conf) + sizeof(*pinctrl) * pin_count); + if (!loc_conf) { + *res = TEE_ERROR_OUT_OF_MEMORY; + return NULL; + } + + pinconf = &loc_conf->pinconf; + pinconf->ops = &stm32_pinctrl_ops; + pinconf->priv = &loc_conf->array_ref; + + loc_conf->array_ref.count = pin_count; + pinctrl = loc_conf->array_ref.pinctrl; + + count = 0; + fdt_for_each_subnode(pinmux_node, fdt, pinctrl_node) { + int found = 0; + + found = get_pinctrl_from_fdt(fdt, pinmux_node, pinctrl + count, + pin_count - count); + if (found <= 0 && found > ((int)pin_count - count)) + panic(); + + count += found; + } + + *res = TEE_SUCCESS; + return pinconf; +} +#endif /*CFG_DRIVERS_PINCTRL*/ + static TEE_Result stm32_pinctrl_probe(const void *fdt, int node, const void *compat_data) { + TEE_Result res = TEE_ERROR_GENERIC; + /* Register GPIO banks described in this pin control node */ - return dt_stm32_gpio_pinctrl(fdt, node, compat_data); + res = dt_stm32_gpio_pinctrl(fdt, node, compat_data); + if (res) + return res; + +#ifdef CFG_DRIVERS_PINCTRL + res = pinctrl_register_provider(fdt, node, stm32_pinctrl_dt_get, + (void *)compat_data); + if (res) + return res; +#endif + + return TEE_SUCCESS; } static const struct dt_device_match stm32_pinctrl_match_table[] = { diff --git a/core/include/drivers/stm32_gpio.h b/core/include/drivers/stm32_gpio.h index f3f5c08daf4..36393ca4925 100644 --- a/core/include/drivers/stm32_gpio.h +++ b/core/include/drivers/stm32_gpio.h @@ -1,19 +1,14 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* - * Copyright (c) 2017-2019, STMicroelectronics - * - * STM32 GPIO driver relies on platform util fiunctions to get base address - * and clock ID of the GPIO banks. The drvier API allows to retrieve pin muxing - * configuration for given nodes and load them at runtime. A pin control - * instance provide an active and a standby configuration. Pin onwer is - * responsible to load to expected configuration during PM state transitions - * as STM32 GPIO driver does no register callbacks to the PM framework. + * Copyright (c) 2017-2023, STMicroelectronics */ #ifndef DRIVERS_STM32_GPIO_H #define DRIVERS_STM32_GPIO_H #include +#include +#include #include #include #include @@ -63,16 +58,22 @@ struct gpio_cfg { * * @bank: GPIO bank identifier as assigned by the platform * @pin: Pin number in the GPIO bank + * @cfg: Pin configuration * @active_cfg: Configuration in active state * @standby_cfg: Configuration in standby state */ struct stm32_pinctrl { uint8_t bank; uint8_t pin; +#ifdef CFG_DRIVERS_PINCTRL + struct gpio_cfg cfg; +#else struct gpio_cfg active_cfg; struct gpio_cfg standby_cfg; +#endif }; +#ifndef CFG_DRIVERS_PINCTRL /* * Apply series of pin muxing configuration, active state and standby state * @@ -89,6 +90,7 @@ void stm32_pinctrl_load_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt); * @count: Number of entries in @pinctrl */ void stm32_pinctrl_store_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt); +#endif /* * Save pinctrl instances defined in DT node: identifiers and power states From 2af6403fee14719f4f01f8366f58144c5fb81734 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 26 May 2023 19:21:05 +0200 Subject: [PATCH 12/26] drivers: stm32_gpio: add helper function stm32_gpio_pinctrl_bank_pin() Adds helper function stm32_gpio_pinctrl_bank_pin() to get an array of bank and pin IDs related to a pin control state. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 37 +++++++++++++++++++++++++++++++ core/include/drivers/stm32_gpio.h | 23 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index e06d6b39b54..7d619034b90 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -816,6 +816,43 @@ static const struct pinctrl_ops stm32_pinctrl_ops = { DECLARE_KEEP_PAGER(stm32_pinctrl_ops); +void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *pinctrl, + unsigned int *bank, unsigned int *pin, + unsigned int *count) +{ + size_t conf_index = 0; + size_t pin_count = 0; + size_t n = 0; + + assert(count); + if (!pinctrl) + goto out; + + for (conf_index = 0; conf_index < pinctrl->conf_count; conf_index++) { + struct pinconf *pinconf = pinctrl->confs[conf_index]; + struct stm32_pinctrl_array *ref = pinconf->priv; + + /* Consider only the stm32_gpio pins */ + if (pinconf->ops != &stm32_pinctrl_ops) + continue; + + if (bank || pin) { + for (n = 0; n < ref->count; n++) { + if (bank && pin_count <= *count) + bank[pin_count] = ref->pinctrl[n].bank; + if (pin && pin_count <= *count) + pin[pin_count] = ref->pinctrl[n].pin; + pin_count++; + } + } else { + pin_count += ref->count; + } + } + +out: + *count = pin_count; +} + /* Allocate and return a pinctrl configuration from a DT reference */ static struct pinconf *stm32_pinctrl_dt_get(struct dt_pargs *pargs, void *data __unused, diff --git a/core/include/drivers/stm32_gpio.h b/core/include/drivers/stm32_gpio.h index 36393ca4925..1cebf82121b 100644 --- a/core/include/drivers/stm32_gpio.h +++ b/core/include/drivers/stm32_gpio.h @@ -33,6 +33,8 @@ #define GPIO_OD_LEVEL_LOW 0x0 #define GPIO_OD_LEVEL_HIGH 0x1 +struct pinctrl_state; + /* * GPIO configuration description structured as single 16bit word * for efficient save/restore when GPIO pin suspends or resumes. @@ -142,4 +144,25 @@ static inline void stm32_gpio_set_secure_cfg(unsigned int bank __unused, */ int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank); +#ifdef CFG_DRIVERS_PINCTRL +/* + * Get the bank and pin indices related to a pin control state + * @pinctrl: Pinctrl state + * @bank: Output bank indices array or NULL + * @pin: Output pin indices array or NULL + * @count: [in] Number of cells of @bank and @pin, [out] pin count in @pinctrl + */ +void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *pinctrl, + unsigned int *bank, unsigned int *pin, + unsigned int *count); +#else +static inline +void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *p __unused, + unsigned int *bank __unused, + unsigned int *pin __unused, + unsigned int *count __maybe_unused) +{ + assert(!count); +} +#endif /*CFG_DRIVERS_PINCTRL*/ #endif /*DRIVERS_STM32_GPIO_H*/ From 8668845c9629c79ecbb0894d976f6ffa52cd5c5f Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 26 May 2023 19:23:24 +0200 Subject: [PATCH 13/26] drivers: stm32_gpio: add helper function stm32_pinctrl_set_secure_cfg() Adds helper function stm32_pinctrl_set_secure_cfg() to set the GPIO pin secure state (secure or non-secure) for each pin referenced by a pin control state. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 23 +++++++++++++++++++++++ core/include/drivers/stm32_gpio.h | 15 +++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 7d619034b90..de0988372f2 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -853,6 +853,29 @@ void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *pinctrl, *count = pin_count; } +void stm32_pinctrl_set_secure_cfg(struct pinctrl_state *pinctrl, bool secure) +{ + size_t conf_index = 0; + + if (!pinctrl) + return; + + for (conf_index = 0; conf_index < pinctrl->conf_count; conf_index++) { + struct pinconf *pinconf = pinctrl->confs[conf_index]; + struct stm32_pinctrl_array *ref = pinconf->priv; + struct stm32_pinctrl *pc = NULL; + size_t n = 0; + + for (n = 0; n < ref->count; n++) { + if (pinconf->ops != &stm32_pinctrl_ops) + continue; + + pc = ref->pinctrl + n; + stm32_gpio_set_secure_cfg(pc->bank, pc->pin, secure); + } + } +} + /* Allocate and return a pinctrl configuration from a DT reference */ static struct pinconf *stm32_pinctrl_dt_get(struct dt_pargs *pargs, void *data __unused, diff --git a/core/include/drivers/stm32_gpio.h b/core/include/drivers/stm32_gpio.h index 1cebf82121b..2470c69ada0 100644 --- a/core/include/drivers/stm32_gpio.h +++ b/core/include/drivers/stm32_gpio.h @@ -145,6 +145,14 @@ static inline void stm32_gpio_set_secure_cfg(unsigned int bank __unused, int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank); #ifdef CFG_DRIVERS_PINCTRL +/* + * Configure pin muxing access permission: can be secure or not + * + * @pinctrl: Pin control state where STM32_GPIO pin are to configure + * @secure: True if pin is secure, false otherwise + */ +void stm32_pinctrl_set_secure_cfg(struct pinctrl_state *pinctrl, bool secure); + /* * Get the bank and pin indices related to a pin control state * @pinctrl: Pinctrl state @@ -156,6 +164,13 @@ void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *pinctrl, unsigned int *bank, unsigned int *pin, unsigned int *count); #else +static inline +void stm32_pinctrl_set_secure_cfg(struct pinctrl_state *pinctrl __maybe_unused, + bool secure __unused) +{ + assert(!pinctrl); +} + static inline void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *p __unused, unsigned int *bank __unused, From 882e488cc52fc58a4f645f58ab8d86591123a5a3 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 17:20:01 +0200 Subject: [PATCH 14/26] plat-stm32mp1: shared_resources: support CFG_DRIVERS_PINCTRL Adds shared resources helper functions stm32mp_register_secure_pinctrl() and stm32mp_register_non_secure_pinctrl() for when a platform driver registers pins from a pin control state with secure or non-secure attribute. These function are required when CFG_DRIVERS_PINCTRL is enabled. Signed-off-by: Etienne Carriere --- .../arch/arm/plat-stm32mp1/shared_resources.c | 53 ++++++++++++++++++- core/arch/arm/plat-stm32mp1/stm32_util.h | 25 +++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/core/arch/arm/plat-stm32mp1/shared_resources.c b/core/arch/arm/plat-stm32mp1/shared_resources.c index 2c4ce9e9592..7a07e3efd17 100644 --- a/core/arch/arm/plat-stm32mp1/shared_resources.c +++ b/core/arch/arm/plat-stm32mp1/shared_resources.c @@ -1,9 +1,10 @@ // SPDX-License-Identifier: BSD-3-Clause /* - * Copyright (c) 2017-2022, STMicroelectronics + * Copyright (c) 2017-2023, STMicroelectronics */ #include +#include #include #include #include @@ -370,6 +371,56 @@ void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) } } +void stm32mp_register_secure_pinctrl(struct pinctrl_state *pinctrl) +{ + unsigned int *bank = NULL; + unsigned int *pin = NULL; + size_t count = 0; + size_t n = 0; + + stm32_gpio_pinctrl_bank_pin(pinctrl, NULL, NULL, &count); + if (!count) + return; + + bank = calloc(count, sizeof(*bank)); + pin = calloc(count, sizeof(*pin)); + if (!bank || !pin) + panic(); + + stm32_gpio_pinctrl_bank_pin(pinctrl, bank, pin, &count); + + for (n = 0; n < count; n++) + stm32mp_register_secure_gpio(bank[n], pin[n]); + + free(bank); + free(pin); +} + +void stm32mp_register_non_secure_pinctrl(struct pinctrl_state *pinctrl) +{ + unsigned int *bank = NULL; + unsigned int *pin = NULL; + size_t count = 0; + size_t n = 0; + + stm32_gpio_pinctrl_bank_pin(pinctrl, NULL, NULL, &count); + if (!count) + return; + + bank = calloc(count, sizeof(*bank)); + pin = calloc(count, sizeof(*pin)); + if (!bank || !pin) + panic(); + + stm32_gpio_pinctrl_bank_pin(pinctrl, bank, pin, &count); + + for (n = 0; n < count; n++) + stm32mp_register_non_secure_gpio(bank[n], pin[n]); + + free(bank); + free(pin); +} + static void lock_registering(void) { registering_locked = true; diff --git a/core/arch/arm/plat-stm32mp1/stm32_util.h b/core/arch/arm/plat-stm32mp1/stm32_util.h index 0b741d29ac7..60e38671e52 100644 --- a/core/arch/arm/plat-stm32mp1/stm32_util.h +++ b/core/arch/arm/plat-stm32mp1/stm32_util.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -254,6 +255,20 @@ void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin); */ void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin); +/* + * Register pin resource of a pin control state as a secure peripheral + * @bank: Bank of the target GPIO + * @pin: Bit position of the target GPIO in the bank + */ +void stm32mp_register_secure_pinctrl(struct pinctrl_state *pinctrl); + +/* + * Register pin resource of a pin control state as a non-secure peripheral + * @bank: Bank of the target GPIO + * @pin: Bit position of the target GPIO in the bank + */ +void stm32mp_register_non_secure_pinctrl(struct pinctrl_state *pinctrl); + /* Return true if and only if resource @id is registered as secure */ bool stm32mp_periph_is_secure(enum stm32mp_shres id); @@ -300,6 +315,16 @@ static inline void stm32mp_register_non_secure_gpio(unsigned int bank __unused, { } +static inline +void stm32mp_register_secure_pinctrl(struct pinctrl_state *pinctrl __unused) +{ +} + +static inline +void stm32mp_register_non_secure_pinctrl(struct pinctrl_state *pinctrl __unused) +{ +} + static inline bool stm32mp_periph_is_secure(enum stm32mp_shres id __unused) { return true; From fb8ebc4372b753f75aafb6bfc254fcb66b1a1c20 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 May 2023 11:55:16 +0200 Subject: [PATCH 15/26] drivers: stm32_uart: support CFG_DRIVERS_PINCTRL Updates stm32_uart driver for when CFG_DRIVERS_PINCTRL is enabled making UART driver to get pin control configuration using the generic pin control framework. Signed-off-by: Etienne Carriere --- core/drivers/stm32_uart.c | 28 ++++++++++++++++++++++++++-- core/include/drivers/stm32_uart.h | 19 ++++++++++++++----- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/core/drivers/stm32_uart.c b/core/drivers/stm32_uart.c index 7c1ec52eeb7..0eb8281bf54 100644 --- a/core/drivers/stm32_uart.c +++ b/core/drivers/stm32_uart.c @@ -110,22 +110,30 @@ void stm32_uart_init(struct stm32_uart_pdata *pd, vaddr_t base) static void register_secure_uart(struct stm32_uart_pdata *pd) { - size_t n = 0; + size_t __maybe_unused n = 0; stm32mp_register_secure_periph_iomem(pd->base.pa); +#ifdef CFG_DRIVERS_PINCTRL + stm32mp_register_secure_pinctrl(pd->pinctrl); +#else for (n = 0; n < pd->pinctrl_count; n++) stm32mp_register_secure_gpio(pd->pinctrl[n].bank, pd->pinctrl[n].pin); +#endif } static void register_non_secure_uart(struct stm32_uart_pdata *pd) { - size_t n = 0; + size_t __maybe_unused n = 0; stm32mp_register_non_secure_periph_iomem(pd->base.pa); +#ifdef CFG_DRIVERS_PINCTRL + stm32mp_register_non_secure_pinctrl(pd->pinctrl); +#else for (n = 0; n < pd->pinctrl_count; n++) stm32mp_register_non_secure_gpio(pd->pinctrl[n].bank, pd->pinctrl[n].pin); +#endif } struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node) @@ -133,8 +141,10 @@ struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node) TEE_Result res = TEE_ERROR_GENERIC; struct stm32_uart_pdata *pd = NULL; struct dt_node_info info = { }; +#if !defined(CFG_DRIVERS_PINCTRL) struct stm32_pinctrl *pinctrl_cfg = NULL; int count = 0; +#endif fdt_fill_device_info(fdt, &info, node); @@ -167,6 +177,19 @@ struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node) pd->secure ? MEM_AREA_IO_SEC : MEM_AREA_IO_NSEC, info.reg_size); +#ifdef CFG_DRIVERS_PINCTRL + res = pinctrl_get_state_by_name(fdt, node, "default", &pd->pinctrl); + if (res) + panic(); + + res = pinctrl_get_state_by_name(fdt, node, "sleep", &pd->pinctrl_sleep); + if (res) + panic(); + + res = pinctrl_apply_state(pd->pinctrl); + if (res) + panic(); +#else count = stm32_pinctrl_fdt_get_pinctrl(fdt, node, NULL, 0); if (count < 0) panic(); @@ -181,6 +204,7 @@ struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node) } pd->pinctrl = pinctrl_cfg; pd->pinctrl_count = count; +#endif if (pd->secure) register_secure_uart(pd); diff --git a/core/include/drivers/stm32_uart.h b/core/include/drivers/stm32_uart.h index 021b2b9d892..02747b7b678 100644 --- a/core/include/drivers/stm32_uart.h +++ b/core/include/drivers/stm32_uart.h @@ -1,22 +1,31 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2017-2018, STMicroelectronics + * Copyright (c) 2017-2023, STMicroelectronics */ -#ifndef __STM32_UART_H__ -#define __STM32_UART_H__ +#ifndef DRIVERS_STM32_UART_H +#define DRIVERS_STM32_UART_H #include -#include +#include #include +#include +#include +#include +#include struct stm32_uart_pdata { struct io_pa_va base; struct serial_chip chip; bool secure; struct clk *clock; +#ifdef CFG_DRIVERS_PINCTRL + struct pinctrl_state *pinctrl; +#else struct stm32_pinctrl *pinctrl; size_t pinctrl_count; +#endif + struct pinctrl_state *pinctrl_sleep; }; /* @@ -39,4 +48,4 @@ void stm32_uart_init(struct stm32_uart_pdata *pd, vaddr_t base); */ struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node); -#endif /*__STM32_UART_H__*/ +#endif /*DRIVERS_STM32_UART_H*/ From bb91a0ea9ad4bb6bfaf490eaba3f778bfc349825 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 May 2023 12:00:08 +0200 Subject: [PATCH 16/26] drivers: stm32_i2c: support CFG_DRIVERS_PINCTRL Updates stm32_i2c driver for when CFG_DRIVERS_PINCTRL is enabled making I2C driver to get pin control configuration using the generic pin control framework. When enabled, stm32_i2c driver get the active and standby pin control configuration from the device tree. SE050 and STM32MP1 PMIC drivers that use the stm32_i2c bus are both updated accordingly. Signed-off-by: Etienne Carriere --- .../arm/plat-stm32mp1/drivers/stm32mp1_pmic.c | 39 +++++++++++---- core/drivers/crypto/se050/glue/i2c_stm32.c | 23 +++++++-- core/drivers/stm32_i2c.c | 48 ++++++++++++++++++- core/include/drivers/stm32_i2c.h | 35 ++++++++++++-- 4 files changed, 126 insertions(+), 19 deletions(-) diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c index 8584f4a3739..9a621c85d56 100644 --- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c +++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c @@ -460,8 +460,13 @@ static void parse_regulator_fdt_nodes(void) * Return 0 on success, 1 if no PMIC node found and a negative value otherwise */ static int dt_pmic_i2c_config(struct dt_node_info *i2c_info, +#ifdef CFG_DRIVERS_PINCTRL + struct pinctrl_state **pinctrl_active, + struct pinctrl_state **pinctrl_sleep, +#else struct stm32_pinctrl **pinctrl, size_t *pinctrl_count, +#endif struct stm32_i2c_init_s *init) { int pmic_node = 0; @@ -493,9 +498,15 @@ static int dt_pmic_i2c_config(struct dt_node_info *i2c_info, if (!i2c_info->reg) return -FDT_ERR_NOTFOUND; +#ifdef CFG_DRIVERS_PINCTRL + if (stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init, pinctrl_active, + pinctrl_sleep)) + panic(); +#else if (stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init, pinctrl, pinctrl_count)) panic(); +#endif return 0; } @@ -510,17 +521,22 @@ static bool initialize_pmic_i2c(void) int ret = 0; struct dt_node_info i2c_info = { }; struct i2c_handle_s *i2c = &i2c_handle; - struct stm32_pinctrl *pinctrl = NULL; - size_t pin_count = 0; struct stm32_i2c_init_s i2c_init = { }; - ret = dt_pmic_i2c_config(&i2c_info, &pinctrl, &pin_count, &i2c_init); +#ifdef CFG_DRIVERS_PINCTRL + if (dt_pmic_i2c_config(&i2c_info, &i2c->pinctrl, &i2c->pinctrl_sleep, + &i2c_init)) + panic(); +#else + ret = dt_pmic_i2c_config(&i2c_info, &i2c->pinctrl, &i2c->pinctrl_count, + &i2c_init); if (ret < 0) { EMSG("I2C configuration failed %d", ret); panic(); } if (ret) return false; +#endif /* Initialize PMIC I2C */ i2c->base.pa = i2c_info.reg; @@ -533,9 +549,6 @@ static bool initialize_pmic_i2c(void) i2c_init.analog_filter = true; i2c_init.digital_filter_coef = 0; - i2c->pinctrl = pinctrl; - i2c->pinctrl_count = pin_count; - stm32mp_get_pmic(); ret = stm32_i2c_init(i2c, &i2c_init); @@ -586,26 +599,36 @@ void stm32mp_put_pmic(void) static void register_non_secure_pmic(void) { - size_t n = 0; + size_t __maybe_unused n = 0; /* Allow this function to be called when STPMIC1 not used */ if (!i2c_handle.base.pa) return; +#ifdef CFG_DRIVERS_PINCTRL + stm32mp_register_non_secure_pinctrl(i2c_handle.pinctrl); + stm32mp_register_non_secure_pinctrl(i2c_handle.pinctrl_sleep); +#else for (n = 0; n < i2c_handle.pinctrl_count; n++) stm32mp_register_non_secure_gpio(i2c_handle.pinctrl[n].bank, i2c_handle.pinctrl[n].pin); +#endif stm32mp_register_non_secure_periph_iomem(i2c_handle.base.pa); } static void register_secure_pmic(void) { - size_t n = 0; + size_t __maybe_unused n = 0; +#ifdef CFG_DRIVERS_PINCTRL + stm32mp_register_secure_pinctrl(i2c_handle.pinctrl); + stm32mp_register_secure_pinctrl(i2c_handle.pinctrl_sleep); +#else for (n = 0; n < i2c_handle.pinctrl_count; n++) stm32mp_register_secure_gpio(i2c_handle.pinctrl[n].bank, i2c_handle.pinctrl[n].pin); +#endif stm32mp_register_secure_periph_iomem(i2c_handle.base.pa); register_pm_driver_cb(pmic_pm, NULL, "stm32mp1-pmic"); diff --git a/core/drivers/crypto/se050/glue/i2c_stm32.c b/core/drivers/crypto/se050/glue/i2c_stm32.c index fb2ad6b8db1..ca036cc064c 100644 --- a/core/drivers/crypto/se050/glue/i2c_stm32.c +++ b/core/drivers/crypto/se050/glue/i2c_stm32.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -33,7 +34,13 @@ TEE_Result native_i2c_transfer(struct rpc_i2c_request *req, size_t *bytes) } static int dt_i2c_bus_config(struct stm32_i2c_init_s *init, - struct stm32_pinctrl **pctrl, size_t *pcnt) +#ifdef CFG_DRIVERS_PINCTRL + struct pinctrl_state **pinctrl_active, + struct pinctrl_state **pinctrl_sleep +#else + struct stm32_pinctrl **pctrl, size_t *pcnt +#endif + ) { const fdt32_t *cuint = NULL; const char *path = NULL; @@ -61,29 +68,35 @@ static int dt_i2c_bus_config(struct stm32_i2c_init_s *init, else if (I2C_STANDARD_RATE != CFG_CORE_SE05X_BAUDRATE) IMSG("SE05x ignoring CFG_CORE_SE05X_BAUDRATE, use built-in"); +#ifdef CFG_DRIVERS_PINCTRL + return stm32_i2c_get_setup_from_fdt(fdt, node, init, pinctrl_active, + pinctrl_sleep); +#else return stm32_i2c_get_setup_from_fdt(fdt, node, init, pctrl, pcnt); +#endif } int native_i2c_init(void) { struct stm32_i2c_init_s i2c_init = { }; - struct stm32_pinctrl *pinctrl = NULL; - size_t pin_count = 0; /* No need to re-initialize */ if (i2c.base.pa) return 0; /* Support only one device on the platform */ +#ifdef CFG_DRIVERS_PINCTRL + if (dt_i2c_bus_config(&i2c_init, &i2c.pinctrl, &i2c.pinctrl_sleep)) + return -1; +#else if (dt_i2c_bus_config(&i2c_init, &pinctrl, &pin_count)) return -1; +#endif /* Probe the device */ i2c_init.own_address1 = SMCOM_I2C_ADDRESS; i2c_init.digital_filter_coef = 0; i2c_init.analog_filter = true; - i2c.pinctrl_count = pin_count; - i2c.pinctrl = pinctrl; stm32_i2c_resume(&i2c); diff --git a/core/drivers/stm32_i2c.c b/core/drivers/stm32_i2c.c index 4018717a351..11bb5a88106 100644 --- a/core/drivers/stm32_i2c.c +++ b/core/drivers/stm32_i2c.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -684,13 +686,19 @@ static int i2c_config_analog_filter(struct i2c_handle_s *hi2c, TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, struct stm32_i2c_init_s *init, +#ifdef CFG_DRIVERS_PINCTRL + struct pinctrl_state **pinctrl, + struct pinctrl_state **pinctrl_sleep +#else struct stm32_pinctrl **pinctrl, - size_t *pinctrl_count) + size_t *pinctrl_count +#endif + ) { TEE_Result res = TEE_ERROR_GENERIC; const fdt32_t *cuint = NULL; struct dt_node_info info = { .status = 0 }; - int count = 0; + int __maybe_unused count = 0; /* Default STM32 specific configs caller may need to overwrite */ memset(init, 0, sizeof(*init)); @@ -732,6 +740,20 @@ TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, init->bus_rate = I2C_STANDARD_RATE; } +#ifdef CFG_DRIVERS_PINCTRL + if (pinctrl) { + res = pinctrl_get_state_by_name(fdt, node, "default", pinctrl); + if (res) + return res; + } + + if (pinctrl_sleep) { + res = pinctrl_get_state_by_name(fdt, node, "sleep", + pinctrl_sleep); + if (res) + return res; + } +#else count = stm32_pinctrl_fdt_get_pinctrl(fdt, node, NULL, 0); if (count <= 0) { *pinctrl = NULL; @@ -752,6 +774,7 @@ TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, *pinctrl_count = stm32_pinctrl_fdt_get_pinctrl(fdt, node, *pinctrl, count); assert(*pinctrl_count == (unsigned int)count); +#endif /*CFG_DRIVERS_PINCTRL*/ return TEE_SUCCESS; } @@ -834,9 +857,14 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, if (rc) DMSG("I2C analog filter error %d", rc); +#ifdef CFG_DRIVERS_PINCTRL + if (IS_ENABLED(CFG_STM32MP13)) + stm32_pinctrl_set_secure_cfg(hi2c->pinctrl, true); +#else if (IS_ENABLED(CFG_STM32MP13)) stm32_gpio_set_secure_cfg(hi2c->pinctrl->bank, hi2c->pinctrl->pin, true); +#endif clk_disable(hi2c->clock); @@ -1527,7 +1555,12 @@ void stm32_i2c_resume(struct i2c_handle_s *hi2c) (hi2c->i2c_state != I2C_STATE_SUSPENDED)) panic(); +#ifdef CFG_DRIVERS_PINCTRL + if (pinctrl_apply_state(hi2c->pinctrl)) + panic(); +#else stm32_pinctrl_load_active_cfg(hi2c->pinctrl, hi2c->pinctrl_count); +#endif if (hi2c->i2c_state == I2C_STATE_RESET) { /* There is no valid I2C configuration to be loaded yet */ @@ -1536,9 +1569,14 @@ void stm32_i2c_resume(struct i2c_handle_s *hi2c) restore_cfg(hi2c, &hi2c->sec_cfg); +#ifdef CFG_DRIVERS_PINCTRL + if (IS_ENABLED(CFG_STM32MP13)) + stm32_pinctrl_set_secure_cfg(hi2c->pinctrl, true); +#else if (IS_ENABLED(CFG_STM32MP13)) stm32_gpio_set_secure_cfg(hi2c->pinctrl->bank, hi2c->pinctrl->pin, true); +#endif hi2c->i2c_state = I2C_STATE_READY; } @@ -1552,7 +1590,13 @@ void stm32_i2c_suspend(struct i2c_handle_s *hi2c) panic(); save_cfg(hi2c, &hi2c->sec_cfg); + +#ifdef CFG_DRIVERS_PINCTRL + if (pinctrl_apply_state(hi2c->pinctrl_sleep)) + panic(); +#else stm32_pinctrl_load_standby_cfg(hi2c->pinctrl, hi2c->pinctrl_count); +#endif hi2c->i2c_state = I2C_STATE_SUSPENDED; } diff --git a/core/include/drivers/stm32_i2c.h b/core/include/drivers/stm32_i2c.h index 39b32446623..693b06af5b8 100644 --- a/core/include/drivers/stm32_i2c.h +++ b/core/include/drivers/stm32_i2c.h @@ -1,12 +1,13 @@ /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ /* - * Copyright (c) 2017-2019, STMicroelectronics + * Copyright (c) 2017-2023, STMicroelectronics */ -#ifndef __STM32_I2C_H -#define __STM32_I2C_H +#ifndef DRIVERS_STM32_I2C_H +#define DRIVERS_STM32_I2C_H #include +#include #include #include #include @@ -111,6 +112,10 @@ struct i2c_cfg { * @saved_timing: Saved timing value if already computed * @saved_frequency: Saved frequency value if already computed * @sec_cfg: I2C registers configuration storage + * Case CFG_DRIVERS_PINCTRL + * @pinctrl: Pin control configuration for the I2C bus in active state + * @pinctrl_sleep: Pin control configuration for the I2C bus in standby state + * Case !CFG_DRIVERS_PINCTRL * @pinctrl: PINCTRLs configuration for the I2C PINs * @pinctrl_count: Number of PINCTRLs elements */ @@ -124,8 +129,13 @@ struct i2c_handle_s { uint32_t saved_timing; unsigned long saved_frequency; struct i2c_cfg sec_cfg; +#ifdef CFG_DRIVERS_PINCTRL + struct pinctrl_state *pinctrl; + struct pinctrl_state *pinctrl_sleep; +#else struct stm32_pinctrl *pinctrl; size_t pinctrl_count; +#endif }; /* STM32 specific defines */ @@ -135,6 +145,22 @@ struct i2c_handle_s { #define STM32_I2C_ANALOG_FILTER_DELAY_MAX U(260) /* ns */ #define STM32_I2C_DIGITAL_FILTER_MAX U(16) +#ifdef CFG_DRIVERS_PINCTRL +/* + * Fill struct stm32_i2c_init_s from DT content for a given I2C node + * + * @fdt: Reference to DT + * @node: Target I2C node in the DT + * @init: Output stm32_i2c_init_s structure + * @pinctrl_active: Output active I2C pinctrl state + * @pinctrl_sleep: Output suspended I2C pinctrl state + * Return a TEE_Result compliant value + */ +TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, + struct stm32_i2c_init_s *init, + struct pinctrl_state **pinctrl_active, + struct pinctrl_state **pinctrl_sleep); +#else /* * Fill struct stm32_i2c_init_s from DT content for a given I2C node * @@ -149,6 +175,7 @@ TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, struct stm32_i2c_init_s *init, struct stm32_pinctrl **pinctrl, size_t *pinctrl_count); +#endif /*CFG_DRIVERS_PINCTRL*/ /* * Initialize I2C bus handle from input configuration directives @@ -265,4 +292,4 @@ static inline bool i2c_is_secure(struct i2c_handle_s *hi2c) return hi2c->dt_status == DT_STATUS_OK_SEC; } -#endif /* __STM32_I2C_H */ +#endif /* DRIVERS_STM32_I2C_H*/ From 46ef2d898ede88406feb556b9bc608711f3b6b7f Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 14:28:05 +0200 Subject: [PATCH 17/26] plat-stm32mp1: conf: enable CFG_DRIVERS_PINCTRL Changes platform stm32mp1 configuration to always enable CFG_DRIVERS_PINCTRL. The platform requires pinctrl_apply_state() to be unpaged has it can be used during PM suspend and resume sequences. Signed-off-by: Etienne Carriere --- core/arch/arm/plat-stm32mp1/conf.mk | 1 + core/arch/arm/plat-stm32mp1/main.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/core/arch/arm/plat-stm32mp1/conf.mk b/core/arch/arm/plat-stm32mp1/conf.mk index 13bb465e333..4861462c99b 100644 --- a/core/arch/arm/plat-stm32mp1/conf.mk +++ b/core/arch/arm/plat-stm32mp1/conf.mk @@ -93,6 +93,7 @@ include core/arch/arm/cpu/cortex-a7.mk $(call force,CFG_DRIVERS_CLK,y) $(call force,CFG_DRIVERS_CLK_DT,y) $(call force,CFG_DRIVERS_GPIO,y) +$(call force,CFG_DRIVERS_PINCTRL,y) $(call force,CFG_GIC,y) $(call force,CFG_INIT_CNTVOFF,y) $(call force,CFG_PSCI_ARM32,y) diff --git a/core/arch/arm/plat-stm32mp1/main.c b/core/arch/arm/plat-stm32mp1/main.c index 19da59ad45a..337bbf8076d 100644 --- a/core/arch/arm/plat-stm32mp1/main.c +++ b/core/arch/arm/plat-stm32mp1/main.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -535,3 +536,6 @@ static TEE_Result init_debug(void) } early_init_late(init_debug); #endif /* CFG_STM32_DEBUG_ACCESS */ + +/* Some generic resources need to be unpaged */ +DECLARE_KEEP_PAGER(pinctrl_apply_state); From 3bfb991511ca300eaebf38116765573dcc01139c Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 16:59:24 +0200 Subject: [PATCH 18/26] drivers: stm32_gpio: add help function stm32_gpio_get_bank() Adds helper function stm32_gpio_get_bank() in stm32_gpio to retrieve a GPIO bank instance from the bank ID. This change will allow a later change to remove now useless platform helper functions stm32_get_gpio_bank_base() and stm32_get_gpio_bank_clk(). Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 84 ++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index de0988372f2..58a2b132638 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -206,14 +206,24 @@ static bool __maybe_unused is_stm32_gpio_chip(struct gpio_chip *chip) return chip && chip->ops == &stm32_gpio_ops; } +static struct stm32_gpio_bank *stm32_gpio_get_bank(unsigned int bank_id) +{ + struct stm32_gpio_bank *bank = NULL; + + STAILQ_FOREACH(bank, &bank_list, link) + if (bank_id == bank->bank_id) + break; + + return bank; +} + /* Save to output @cfg the current GPIO (@bank/@pin) configuration */ -static void __maybe_unused get_gpio_cfg(uint32_t bank, uint32_t pin, +static void __maybe_unused get_gpio_cfg(uint32_t bank_id, uint32_t pin, struct gpio_cfg *cfg) { - vaddr_t base = stm32_get_gpio_bank_base(bank); - struct clk *clk = stm32_get_gpio_bank_clk(bank); + struct stm32_gpio_bank *bank = stm32_gpio_get_bank(bank_id); - clk_enable(clk); + clk_enable(bank->clock); /* * Save GPIO configuration bits spread over the few bank registers. @@ -222,73 +232,73 @@ static void __maybe_unused get_gpio_cfg(uint32_t bank, uint32_t pin, * 4bit fields are accessed at bit position being fourth the pin index * but accessed from 2 32bit registers at incremental addresses. */ - cfg->mode = (io_read32(base + GPIO_MODER_OFFSET) >> (pin << 1)) & - GPIO_MODE_MASK; + cfg->mode = (io_read32(bank->base + GPIO_MODER_OFFSET) >> (pin << 1)) & + GPIO_MODE_MASK; - cfg->otype = (io_read32(base + GPIO_OTYPER_OFFSET) >> pin) & 1; + cfg->otype = (io_read32(bank->base + GPIO_OTYPER_OFFSET) >> pin) & 1; - cfg->ospeed = (io_read32(base + GPIO_OSPEEDR_OFFSET) >> (pin << 1)) & - GPIO_OSPEED_MASK; + cfg->ospeed = (io_read32(bank->base + GPIO_OSPEEDR_OFFSET) >> + (pin << 1)) & GPIO_OSPEED_MASK; - cfg->pupd = (io_read32(base + GPIO_PUPDR_OFFSET) >> (pin << 1)) & - GPIO_PUPD_PULL_MASK; + cfg->pupd = (io_read32(bank->base + GPIO_PUPDR_OFFSET) >> (pin << 1)) & + GPIO_PUPD_PULL_MASK; - cfg->od = (io_read32(base + GPIO_ODR_OFFSET) >> (pin << 1)) & 1; + cfg->od = (io_read32(bank->base + GPIO_ODR_OFFSET) >> (pin << 1)) & 1; if (pin < GPIO_ALT_LOWER_LIMIT) - cfg->af = (io_read32(base + GPIO_AFRL_OFFSET) >> (pin << 2)) & - GPIO_ALTERNATE_MASK; + cfg->af = (io_read32(bank->base + GPIO_AFRL_OFFSET) >> + (pin << 2)) & GPIO_ALTERNATE_MASK; else - cfg->af = (io_read32(base + GPIO_AFRH_OFFSET) >> - ((pin - GPIO_ALT_LOWER_LIMIT) << 2)) & - GPIO_ALTERNATE_MASK; + cfg->af = (io_read32(bank->base + GPIO_AFRH_OFFSET) >> + ((pin - GPIO_ALT_LOWER_LIMIT) << 2)) & + GPIO_ALTERNATE_MASK; - clk_disable(clk); + clk_disable(bank->clock); } /* Apply GPIO (@bank/@pin) configuration described by @cfg */ -static void set_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg) +static void set_gpio_cfg(uint32_t bank_id, uint32_t pin, struct gpio_cfg *cfg) { - vaddr_t base = stm32_get_gpio_bank_base(bank); - struct clk *clk = stm32_get_gpio_bank_clk(bank); + struct stm32_gpio_bank *bank = stm32_gpio_get_bank(bank_id); uint32_t exceptions = cpu_spin_lock_xsave(&gpio_lock); - clk_enable(clk); + clk_enable(bank->clock); /* Load GPIO MODE value, 2bit value shifted by twice the pin number */ - io_clrsetbits32(base + GPIO_MODER_OFFSET, + io_clrsetbits32(bank->base + GPIO_MODER_OFFSET, GPIO_MODE_MASK << (pin << 1), cfg->mode << (pin << 1)); /* Load GPIO Output TYPE value, 1bit shifted by pin number value */ - io_clrsetbits32(base + GPIO_OTYPER_OFFSET, BIT(pin), cfg->otype << pin); + io_clrsetbits32(bank->base + GPIO_OTYPER_OFFSET, BIT(pin), + cfg->otype << pin); /* Load GPIO Output Speed confguration, 2bit value */ - io_clrsetbits32(base + GPIO_OSPEEDR_OFFSET, + io_clrsetbits32(bank->base + GPIO_OSPEEDR_OFFSET, GPIO_OSPEED_MASK << (pin << 1), cfg->ospeed << (pin << 1)); /* Load GPIO pull configuration, 2bit value */ - io_clrsetbits32(base + GPIO_PUPDR_OFFSET, BIT(pin), + io_clrsetbits32(bank->base + GPIO_PUPDR_OFFSET, BIT(pin), cfg->pupd << (pin << 1)); /* Load pin mux Alternate Function configuration, 4bit value */ if (pin < GPIO_ALT_LOWER_LIMIT) { - io_clrsetbits32(base + GPIO_AFRL_OFFSET, + io_clrsetbits32(bank->base + GPIO_AFRL_OFFSET, GPIO_ALTERNATE_MASK << (pin << 2), cfg->af << (pin << 2)); } else { size_t shift = (pin - GPIO_ALT_LOWER_LIMIT) << 2; - io_clrsetbits32(base + GPIO_AFRH_OFFSET, + io_clrsetbits32(bank->base + GPIO_AFRH_OFFSET, GPIO_ALTERNATE_MASK << shift, cfg->af << shift); } /* Load GPIO Output direction confuguration, 1bit */ - io_clrsetbits32(base + GPIO_ODR_OFFSET, BIT(pin), cfg->od << pin); + io_clrsetbits32(bank->base + GPIO_ODR_OFFSET, BIT(pin), cfg->od << pin); - clk_disable(clk); + clk_disable(bank->clock); cpu_spin_unlock_xrestore(&gpio_lock, exceptions); } @@ -773,20 +783,20 @@ int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank) return -1; } -void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, bool secure) +void stm32_gpio_set_secure_cfg(unsigned int bank_id, unsigned int pin, + bool secure) { - vaddr_t base = stm32_get_gpio_bank_base(bank); - struct clk *clk = stm32_get_gpio_bank_clk(bank); + struct stm32_gpio_bank *bank = stm32_gpio_get_bank(bank_id); uint32_t exceptions = cpu_spin_lock_xsave(&gpio_lock); - clk_enable(clk); + clk_enable(bank->clock); if (secure) - io_setbits32(base + GPIO_SECR_OFFSET, BIT(pin)); + io_setbits32(bank->base + GPIO_SECR_OFFSET, BIT(pin)); else - io_clrbits32(base + GPIO_SECR_OFFSET, BIT(pin)); + io_clrbits32(bank->base + GPIO_SECR_OFFSET, BIT(pin)); - clk_disable(clk); + clk_disable(bank->clock); cpu_spin_unlock_xrestore(&gpio_lock, exceptions); } From be10e9a4b6d77d3f87fd435ad3bed1d33b548929 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 30 May 2023 09:07:36 +0200 Subject: [PATCH 19/26] drivers: stm32_gpio: use SHIFT_U32() where applicable Replaces 32bit operand raw left shift with use of SHIFT_U32() macro. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 58a2b132638..19818d6b498 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -266,33 +266,33 @@ static void set_gpio_cfg(uint32_t bank_id, uint32_t pin, struct gpio_cfg *cfg) /* Load GPIO MODE value, 2bit value shifted by twice the pin number */ io_clrsetbits32(bank->base + GPIO_MODER_OFFSET, - GPIO_MODE_MASK << (pin << 1), - cfg->mode << (pin << 1)); + SHIFT_U32(GPIO_MODE_MASK, pin << 1), + SHIFT_U32(cfg->mode, pin << 1)); /* Load GPIO Output TYPE value, 1bit shifted by pin number value */ io_clrsetbits32(bank->base + GPIO_OTYPER_OFFSET, BIT(pin), - cfg->otype << pin); + SHIFT_U32(cfg->otype, pin)); /* Load GPIO Output Speed confguration, 2bit value */ io_clrsetbits32(bank->base + GPIO_OSPEEDR_OFFSET, - GPIO_OSPEED_MASK << (pin << 1), - cfg->ospeed << (pin << 1)); + SHIFT_U32(GPIO_OSPEED_MASK, pin << 1), + SHIFT_U32(cfg->ospeed, pin << 1)); /* Load GPIO pull configuration, 2bit value */ io_clrsetbits32(bank->base + GPIO_PUPDR_OFFSET, BIT(pin), - cfg->pupd << (pin << 1)); + SHIFT_U32(cfg->pupd, pin << 1)); /* Load pin mux Alternate Function configuration, 4bit value */ if (pin < GPIO_ALT_LOWER_LIMIT) { io_clrsetbits32(bank->base + GPIO_AFRL_OFFSET, - GPIO_ALTERNATE_MASK << (pin << 2), - cfg->af << (pin << 2)); + SHIFT_U32(GPIO_ALTERNATE_MASK, pin << 2), + SHIFT_U32(cfg->af, pin << 2)); } else { size_t shift = (pin - GPIO_ALT_LOWER_LIMIT) << 2; io_clrsetbits32(bank->base + GPIO_AFRH_OFFSET, - GPIO_ALTERNATE_MASK << shift, - cfg->af << shift); + SHIFT_U32(GPIO_ALTERNATE_MASK, shift), + SHIFT_U32(cfg->af, shift)); } /* Load GPIO Output direction confuguration, 1bit */ From c2b28ac5719481c01faace2823d1a35f7bcf02a8 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 15:00:34 +0200 Subject: [PATCH 20/26] plat-stm32mp1: remove unused gpio bank clock helper functions Removes stm32mp1 platform helper functions stm32_get_gpio_bank_clock() and stm32_get_gpio_bank_clk(). Signed-off-by: Etienne Carriere --- core/arch/arm/plat-stm32mp1/main.c | 22 ---------------------- core/arch/arm/plat-stm32mp1/stm32_util.h | 2 -- 2 files changed, 24 deletions(-) diff --git a/core/arch/arm/plat-stm32mp1/main.c b/core/arch/arm/plat-stm32mp1/main.c index 337bbf8076d..f881503e99c 100644 --- a/core/arch/arm/plat-stm32mp1/main.c +++ b/core/arch/arm/plat-stm32mp1/main.c @@ -445,28 +445,6 @@ unsigned int stm32_get_gpio_bank_offset(unsigned int bank) return bank * GPIO_BANK_OFFSET; } -unsigned int stm32_get_gpio_bank_clock(unsigned int bank) -{ - assert(bank_is_valid(bank)); - -#ifdef CFG_STM32MP15 - if (bank == GPIO_BANK_Z) - return GPIOZ; -#endif - - return GPIOA + bank; -} - -struct clk *stm32_get_gpio_bank_clk(unsigned int bank) -{ - assert(bank_is_valid(bank)); - - if (!IS_ENABLED(CFG_DRIVERS_CLK)) - return NULL; - - return stm32mp_rcc_clock_id_to_clk(stm32_get_gpio_bank_clock(bank)); -} - #ifdef CFG_STM32_IWDG TEE_Result stm32_get_iwdg_otp_config(paddr_t pbase, struct stm32_iwdg_otp_data *otp_data) diff --git a/core/arch/arm/plat-stm32mp1/stm32_util.h b/core/arch/arm/plat-stm32mp1/stm32_util.h index 60e38671e52..8eec6d71612 100644 --- a/core/arch/arm/plat-stm32mp1/stm32_util.h +++ b/core/arch/arm/plat-stm32mp1/stm32_util.h @@ -45,8 +45,6 @@ vaddr_t get_gicd_base(void); */ vaddr_t stm32_get_gpio_bank_base(unsigned int bank); unsigned int stm32_get_gpio_bank_offset(unsigned int bank); -unsigned int stm32_get_gpio_bank_clock(unsigned int bank); -struct clk *stm32_get_gpio_bank_clk(unsigned int bank); /* Platform util for PMIC support */ bool stm32mp_with_pmic(void); From 9525edd9e3ea2213d72c1ed2e28ce712362cc9ac Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 15:02:55 +0200 Subject: [PATCH 21/26] plat-stm32mp1: remove unused gpio bank base address helper function Removes stm32mp1 platform helper function stm32_get_gpio_bank_base(). Signed-off-by: Etienne Carriere --- core/arch/arm/plat-stm32mp1/main.c | 27 ------------------------ core/arch/arm/plat-stm32mp1/stm32_util.h | 1 - 2 files changed, 28 deletions(-) diff --git a/core/arch/arm/plat-stm32mp1/main.c b/core/arch/arm/plat-stm32mp1/main.c index f881503e99c..6242fca792b 100644 --- a/core/arch/arm/plat-stm32mp1/main.c +++ b/core/arch/arm/plat-stm32mp1/main.c @@ -408,33 +408,6 @@ static bool __maybe_unused bank_is_valid(unsigned int bank) panic(); } -vaddr_t stm32_get_gpio_bank_base(unsigned int bank) -{ - static struct io_pa_va base = { .pa = GPIOA_BASE }; - - static_assert(GPIO_BANK_A == 0); - assert(bank_is_valid(bank)); - - if (IS_ENABLED(CFG_STM32MP15)) { - static struct io_pa_va zbase = { .pa = GPIOZ_BASE }; - - /* Get secure mapping address for GPIOZ */ - if (bank == GPIO_BANK_Z) - return io_pa_or_va_secure(&zbase, GPIO_BANK_OFFSET); - - /* Other are mapped non-secure */ - return io_pa_or_va_nsec(&base, (bank + 1) * GPIO_BANK_OFFSET) + - (bank * GPIO_BANK_OFFSET); - } - - if (IS_ENABLED(CFG_STM32MP13)) - return io_pa_or_va_secure(&base, - (bank + 1) * GPIO_BANK_OFFSET) + - (bank * GPIO_BANK_OFFSET); - - panic(); -} - unsigned int stm32_get_gpio_bank_offset(unsigned int bank) { assert(bank_is_valid(bank)); diff --git a/core/arch/arm/plat-stm32mp1/stm32_util.h b/core/arch/arm/plat-stm32mp1/stm32_util.h index 8eec6d71612..f864c553870 100644 --- a/core/arch/arm/plat-stm32mp1/stm32_util.h +++ b/core/arch/arm/plat-stm32mp1/stm32_util.h @@ -43,7 +43,6 @@ vaddr_t get_gicd_base(void); * check DT configuration matches platform implementation of the banks * description. */ -vaddr_t stm32_get_gpio_bank_base(unsigned int bank); unsigned int stm32_get_gpio_bank_offset(unsigned int bank); /* Platform util for PMIC support */ From 2a59bfc49135c0fcea1a4aed6825abdbcf53832b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 23 May 2023 11:58:14 +0200 Subject: [PATCH 22/26] plat-stm32mp1: remove unused stm32mp_gpio_bank_is_shared() Removes platform function stm32mp_gpio_bank_is_shared() that is not used. Signed-off-by: Etienne Carriere --- core/arch/arm/plat-stm32mp1/shared_resources.c | 17 ----------------- core/arch/arm/plat-stm32mp1/stm32_util.h | 3 --- 2 files changed, 20 deletions(-) diff --git a/core/arch/arm/plat-stm32mp1/shared_resources.c b/core/arch/arm/plat-stm32mp1/shared_resources.c index 7a07e3efd17..2b018d6a296 100644 --- a/core/arch/arm/plat-stm32mp1/shared_resources.c +++ b/core/arch/arm/plat-stm32mp1/shared_resources.c @@ -433,23 +433,6 @@ bool stm32mp_periph_is_secure(enum stm32mp_shres id) return shres_state[id] == SHRES_SECURE; } -bool stm32mp_gpio_bank_is_shared(unsigned int bank) -{ - unsigned int not_secure = 0; - unsigned int pin = 0; - - lock_registering(); - - if (bank != GPIO_BANK_Z) - return false; - - for (pin = 0; pin < get_gpioz_nbpin(); pin++) - if (!stm32mp_periph_is_secure(STM32MP1_SHRES_GPIOZ(pin))) - not_secure++; - - return not_secure > 0 && not_secure < get_gpioz_nbpin(); -} - bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) { unsigned int not_secure = 0; diff --git a/core/arch/arm/plat-stm32mp1/stm32_util.h b/core/arch/arm/plat-stm32mp1/stm32_util.h index f864c553870..a563989d27f 100644 --- a/core/arch/arm/plat-stm32mp1/stm32_util.h +++ b/core/arch/arm/plat-stm32mp1/stm32_util.h @@ -272,9 +272,6 @@ bool stm32mp_periph_is_secure(enum stm32mp_shres id); /* Return true if and only if GPIO bank @bank is registered as secure */ bool stm32mp_gpio_bank_is_secure(unsigned int bank); -/* Return true if and only if GPIO bank @bank is registered as shared */ -bool stm32mp_gpio_bank_is_shared(unsigned int bank); - /* Return true if and only if GPIO bank @bank is registered as non-secure */ bool stm32mp_gpio_bank_is_non_secure(unsigned int bank); From 486765906ea9fe1f4b1a757a2a81c4dd2c211901 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 17:43:26 +0200 Subject: [PATCH 23/26] drivers: stm32_gpio: remove cases when CFG_DRIVERS_PINCTRL is disabled Removes implementation when CFG_DRIVERS_PINCTRL is disables as stm32mp1 platform configuration enforces the switch is enabled. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 131 ------------------------------ core/include/drivers/stm32_gpio.h | 35 +------- 2 files changed, 1 insertion(+), 165 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 19818d6b498..78d5003ad1f 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -302,69 +302,6 @@ static void set_gpio_cfg(uint32_t bank_id, uint32_t pin, struct gpio_cfg *cfg) cpu_spin_unlock_xrestore(&gpio_lock, exceptions); } -#if !defined(CFG_DRIVERS_PINCTRL) -void stm32_pinctrl_load_active_cfg(struct stm32_pinctrl *pinctrl, size_t cnt) -{ - size_t n = 0; - - for (n = 0; n < cnt; n++) - set_gpio_cfg(pinctrl[n].bank, pinctrl[n].pin, - &pinctrl[n].active_cfg); -} - -void stm32_pinctrl_load_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt) -{ - size_t n = 0; - - for (n = 0; n < cnt; n++) - set_gpio_cfg(pinctrl[n].bank, pinctrl[n].pin, - &pinctrl[n].standby_cfg); -} - -void stm32_pinctrl_store_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt) -{ - size_t n = 0; - - for (n = 0; n < cnt; n++) - get_gpio_cfg(pinctrl[n].bank, pinctrl[n].pin, - &pinctrl[n].standby_cfg); -} - -/* Panic if GPIO bank information from platform do not match DTB description */ -static void ckeck_gpio_bank(const void *fdt, uint32_t bank, int pinctrl_node) -{ - int pinctrl_subnode = 0; - - fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) { - TEE_Result res = TEE_ERROR_GENERIC; - const fdt32_t *cuint = NULL; - struct clk *clk = NULL; - - if (fdt_getprop(fdt, pinctrl_subnode, - "gpio-controller", NULL) == NULL) - continue; - - /* Check bank register offset matches platform assumptions */ - cuint = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL); - if (fdt32_to_cpu(*cuint) != stm32_get_gpio_bank_offset(bank)) - continue; - - /* Check bank clock matches platform assumptions */ - res = clk_dt_get_by_index(fdt, pinctrl_subnode, 0, &clk); - if (res || clk != stm32_get_gpio_bank_clk(bank)) - panic(); - - /* Check controller is enabled */ - if (fdt_get_status(fdt, pinctrl_subnode) == DT_STATUS_DISABLED) - panic(); - - return; - } - - panic(); -} -#endif /*CFG_DRIVERS_PINCTRL*/ - /* Count pins described in the DT node and get related data if possible */ static int get_pinctrl_from_fdt(const void *fdt, int node, struct stm32_pinctrl *pinctrl, size_t count) @@ -372,7 +309,6 @@ static int get_pinctrl_from_fdt(const void *fdt, int node, const fdt32_t *cuint = NULL; const fdt32_t *slewrate = NULL; int len = 0; - int __maybe_unused pinctrl_node = 0; uint32_t i = 0; uint32_t speed = GPIO_OSPEED_LOW; uint32_t pull = GPIO_PUPD_NO_PULL; @@ -382,12 +318,6 @@ static int get_pinctrl_from_fdt(const void *fdt, int node, if (!cuint) return -FDT_ERR_NOTFOUND; -#if !defined(CFG_DRIVERS_PINCTRL) - pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node)); - if (pinctrl_node < 0) - return -FDT_ERR_NOTFOUND; -#endif - slewrate = fdt_getprop(fdt, node, "slew-rate", NULL); if (slewrate) speed = fdt32_to_cpu(*slewrate); @@ -463,34 +393,17 @@ static int get_pinctrl_from_fdt(const void *fdt, int node, } } -#if !defined(CFG_DRIVERS_PINCTRL) - /* Check GPIO bank clock/base address against platform */ - ckeck_gpio_bank(fdt, bank, pinctrl_node); -#endif - if (found < count) { struct stm32_pinctrl *ref = &pinctrl[found]; ref->bank = (uint8_t)bank; ref->pin = (uint8_t)pin; -#ifdef CFG_DRIVERS_PINCTRL ref->cfg.mode = mode; ref->cfg.otype = opendrain ? 1 : 0; ref->cfg.ospeed = speed; ref->cfg.pupd = pull; ref->cfg.od = odata; ref->cfg.af = alternate; -#else - ref->active_cfg.mode = mode; - ref->active_cfg.otype = opendrain ? 1 : 0; - ref->active_cfg.ospeed = speed; - ref->active_cfg.pupd = pull; - ref->active_cfg.od = odata; - ref->active_cfg.af = alternate; - /* Default to analog mode for standby state */ - ref->standby_cfg.mode = GPIO_MODE_ANALOG; - ref->standby_cfg.pupd = GPIO_PUPD_NO_PULL; -#endif } found++; @@ -712,50 +625,6 @@ static TEE_Result dt_stm32_gpio_pinctrl(const void *fdt, int node, return TEE_SUCCESS; } -#ifndef CFG_DRIVERS_PINCTRL -int stm32_pinctrl_fdt_get_pinctrl(void *fdt, int device_node, - struct stm32_pinctrl *pinctrl, size_t count) -{ - const fdt32_t *cuint = NULL; - int lenp = 0; - int i = 0; - size_t found = 0; - - cuint = fdt_getprop(fdt, device_node, "pinctrl-0", &lenp); - if (!cuint) - return -FDT_ERR_NOTFOUND; - - for (i = 0; i < (lenp / 4); i++) { - int node = 0; - int subnode = 0; - - node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint)); - if (node < 0) - return -FDT_ERR_NOTFOUND; - - fdt_for_each_subnode(subnode, fdt, node) { - size_t n = 0; - int rc = 0; - - if (count > found) - n = count - found; - else - n = 0; - - rc = get_pinctrl_from_fdt(fdt, subnode, - &pinctrl[found], n); - if (rc < 0) - return rc; - - found += (size_t)rc; - } - - cuint++; - } - - return (int)found; -} -#endif /*CFG_DRIVERS_PINCTRL*/ int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank) { diff --git a/core/include/drivers/stm32_gpio.h b/core/include/drivers/stm32_gpio.h index 2470c69ada0..86485e68316 100644 --- a/core/include/drivers/stm32_gpio.h +++ b/core/include/drivers/stm32_gpio.h @@ -67,33 +67,9 @@ struct gpio_cfg { struct stm32_pinctrl { uint8_t bank; uint8_t pin; -#ifdef CFG_DRIVERS_PINCTRL struct gpio_cfg cfg; -#else - struct gpio_cfg active_cfg; - struct gpio_cfg standby_cfg; -#endif }; -#ifndef CFG_DRIVERS_PINCTRL -/* - * Apply series of pin muxing configuration, active state and standby state - * - * @pinctrl: array of pinctrl references - * @count: Number of entries in @pinctrl - */ -void stm32_pinctrl_load_active_cfg(struct stm32_pinctrl *pinctrl, size_t cnt); -void stm32_pinctrl_load_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt); - -/* - * Save the current pin configuration as the standby state for a pin series - * - * @pinctrl: array of pinctrl references - * @count: Number of entries in @pinctrl - */ -void stm32_pinctrl_store_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt); -#endif - /* * Save pinctrl instances defined in DT node: identifiers and power states * @@ -125,14 +101,6 @@ int stm32_pinctrl_fdt_get_pinctrl(void *fdt, int node, */ void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, bool secure); -#else -static inline void stm32_gpio_set_secure_cfg(unsigned int bank __unused, - unsigned int pin __unused, - bool secure __unused) -{ - assert(0); -} -#endif /* * Get the number of GPIO pins supported by a target GPIO bank @@ -144,7 +112,6 @@ static inline void stm32_gpio_set_secure_cfg(unsigned int bank __unused, */ int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank); -#ifdef CFG_DRIVERS_PINCTRL /* * Configure pin muxing access permission: can be secure or not * @@ -179,5 +146,5 @@ void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *p __unused, { assert(!count); } -#endif /*CFG_DRIVERS_PINCTRL*/ +#endif /*CFG_STM32_GPIO*/ #endif /*DRIVERS_STM32_GPIO_H*/ From a7797e98bfb559f121c6a7586fbcd153dab12446 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 17:42:51 +0200 Subject: [PATCH 24/26] drivers: stm32_uart: remove cases when CFG_DRIVERS_PINCTRL is disabled Removes implementation when CFG_DRIVERS_PINCTRL is disables as stm32mp1 platform configuration enforces the switch is enabled. Signed-off-by: Etienne Carriere --- core/drivers/stm32_uart.c | 33 ------------------------------- core/include/drivers/stm32_uart.h | 6 ------ 2 files changed, 39 deletions(-) diff --git a/core/drivers/stm32_uart.c b/core/drivers/stm32_uart.c index 0eb8281bf54..95f4c616652 100644 --- a/core/drivers/stm32_uart.c +++ b/core/drivers/stm32_uart.c @@ -113,13 +113,7 @@ static void register_secure_uart(struct stm32_uart_pdata *pd) size_t __maybe_unused n = 0; stm32mp_register_secure_periph_iomem(pd->base.pa); -#ifdef CFG_DRIVERS_PINCTRL stm32mp_register_secure_pinctrl(pd->pinctrl); -#else - for (n = 0; n < pd->pinctrl_count; n++) - stm32mp_register_secure_gpio(pd->pinctrl[n].bank, - pd->pinctrl[n].pin); -#endif } static void register_non_secure_uart(struct stm32_uart_pdata *pd) @@ -127,13 +121,7 @@ static void register_non_secure_uart(struct stm32_uart_pdata *pd) size_t __maybe_unused n = 0; stm32mp_register_non_secure_periph_iomem(pd->base.pa); -#ifdef CFG_DRIVERS_PINCTRL stm32mp_register_non_secure_pinctrl(pd->pinctrl); -#else - for (n = 0; n < pd->pinctrl_count; n++) - stm32mp_register_non_secure_gpio(pd->pinctrl[n].bank, - pd->pinctrl[n].pin); -#endif } struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node) @@ -141,10 +129,6 @@ struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node) TEE_Result res = TEE_ERROR_GENERIC; struct stm32_uart_pdata *pd = NULL; struct dt_node_info info = { }; -#if !defined(CFG_DRIVERS_PINCTRL) - struct stm32_pinctrl *pinctrl_cfg = NULL; - int count = 0; -#endif fdt_fill_device_info(fdt, &info, node); @@ -177,7 +161,6 @@ struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node) pd->secure ? MEM_AREA_IO_SEC : MEM_AREA_IO_NSEC, info.reg_size); -#ifdef CFG_DRIVERS_PINCTRL res = pinctrl_get_state_by_name(fdt, node, "default", &pd->pinctrl); if (res) panic(); @@ -189,22 +172,6 @@ struct stm32_uart_pdata *stm32_uart_init_from_dt_node(void *fdt, int node) res = pinctrl_apply_state(pd->pinctrl); if (res) panic(); -#else - count = stm32_pinctrl_fdt_get_pinctrl(fdt, node, NULL, 0); - if (count < 0) - panic(); - - if (count) { - pinctrl_cfg = calloc(count, sizeof(*pinctrl_cfg)); - if (!pinctrl_cfg) - panic(); - - stm32_pinctrl_fdt_get_pinctrl(fdt, node, pinctrl_cfg, count); - stm32_pinctrl_load_active_cfg(pinctrl_cfg, count); - } - pd->pinctrl = pinctrl_cfg; - pd->pinctrl_count = count; -#endif if (pd->secure) register_secure_uart(pd); diff --git a/core/include/drivers/stm32_uart.h b/core/include/drivers/stm32_uart.h index 02747b7b678..250737f339f 100644 --- a/core/include/drivers/stm32_uart.h +++ b/core/include/drivers/stm32_uart.h @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -19,12 +18,7 @@ struct stm32_uart_pdata { struct serial_chip chip; bool secure; struct clk *clock; -#ifdef CFG_DRIVERS_PINCTRL struct pinctrl_state *pinctrl; -#else - struct stm32_pinctrl *pinctrl; - size_t pinctrl_count; -#endif struct pinctrl_state *pinctrl_sleep; }; From d860bbb547e1decc15f6568c4653d31182738562 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 17:42:35 +0200 Subject: [PATCH 25/26] drivers: stm32_i2c: remove cases when CFG_DRIVERS_PINCTRL is disabled Removes implementation when CFG_DRIVERS_PINCTRL is disables as stm32mp1 platform configuration enforces the switch is enabled. Signed-off-by: Etienne Carriere --- .../arm/plat-stm32mp1/drivers/stm32mp1_pmic.c | 34 ------------- core/drivers/crypto/se050/glue/i2c_stm32.c | 16 +----- core/drivers/stm32_i2c.c | 51 +------------------ core/include/drivers/stm32_i2c.h | 26 ---------- 4 files changed, 2 insertions(+), 125 deletions(-) diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c index 9a621c85d56..9cb27be730a 100644 --- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c +++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c @@ -460,13 +460,8 @@ static void parse_regulator_fdt_nodes(void) * Return 0 on success, 1 if no PMIC node found and a negative value otherwise */ static int dt_pmic_i2c_config(struct dt_node_info *i2c_info, -#ifdef CFG_DRIVERS_PINCTRL struct pinctrl_state **pinctrl_active, struct pinctrl_state **pinctrl_sleep, -#else - struct stm32_pinctrl **pinctrl, - size_t *pinctrl_count, -#endif struct stm32_i2c_init_s *init) { int pmic_node = 0; @@ -498,15 +493,9 @@ static int dt_pmic_i2c_config(struct dt_node_info *i2c_info, if (!i2c_info->reg) return -FDT_ERR_NOTFOUND; -#ifdef CFG_DRIVERS_PINCTRL if (stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init, pinctrl_active, pinctrl_sleep)) panic(); -#else - if (stm32_i2c_get_setup_from_fdt(fdt, i2c_node, init, - pinctrl, pinctrl_count)) - panic(); -#endif return 0; } @@ -523,20 +512,9 @@ static bool initialize_pmic_i2c(void) struct i2c_handle_s *i2c = &i2c_handle; struct stm32_i2c_init_s i2c_init = { }; -#ifdef CFG_DRIVERS_PINCTRL if (dt_pmic_i2c_config(&i2c_info, &i2c->pinctrl, &i2c->pinctrl_sleep, &i2c_init)) panic(); -#else - ret = dt_pmic_i2c_config(&i2c_info, &i2c->pinctrl, &i2c->pinctrl_count, - &i2c_init); - if (ret < 0) { - EMSG("I2C configuration failed %d", ret); - panic(); - } - if (ret) - return false; -#endif /* Initialize PMIC I2C */ i2c->base.pa = i2c_info.reg; @@ -605,14 +583,8 @@ static void register_non_secure_pmic(void) if (!i2c_handle.base.pa) return; -#ifdef CFG_DRIVERS_PINCTRL stm32mp_register_non_secure_pinctrl(i2c_handle.pinctrl); stm32mp_register_non_secure_pinctrl(i2c_handle.pinctrl_sleep); -#else - for (n = 0; n < i2c_handle.pinctrl_count; n++) - stm32mp_register_non_secure_gpio(i2c_handle.pinctrl[n].bank, - i2c_handle.pinctrl[n].pin); -#endif stm32mp_register_non_secure_periph_iomem(i2c_handle.base.pa); } @@ -621,14 +593,8 @@ static void register_secure_pmic(void) { size_t __maybe_unused n = 0; -#ifdef CFG_DRIVERS_PINCTRL stm32mp_register_secure_pinctrl(i2c_handle.pinctrl); stm32mp_register_secure_pinctrl(i2c_handle.pinctrl_sleep); -#else - for (n = 0; n < i2c_handle.pinctrl_count; n++) - stm32mp_register_secure_gpio(i2c_handle.pinctrl[n].bank, - i2c_handle.pinctrl[n].pin); -#endif stm32mp_register_secure_periph_iomem(i2c_handle.base.pa); register_pm_driver_cb(pmic_pm, NULL, "stm32mp1-pmic"); diff --git a/core/drivers/crypto/se050/glue/i2c_stm32.c b/core/drivers/crypto/se050/glue/i2c_stm32.c index ca036cc064c..c897d5610a0 100644 --- a/core/drivers/crypto/se050/glue/i2c_stm32.c +++ b/core/drivers/crypto/se050/glue/i2c_stm32.c @@ -34,13 +34,8 @@ TEE_Result native_i2c_transfer(struct rpc_i2c_request *req, size_t *bytes) } static int dt_i2c_bus_config(struct stm32_i2c_init_s *init, -#ifdef CFG_DRIVERS_PINCTRL struct pinctrl_state **pinctrl_active, - struct pinctrl_state **pinctrl_sleep -#else - struct stm32_pinctrl **pctrl, size_t *pcnt -#endif - ) + struct pinctrl_state **pinctrl_sleep) { const fdt32_t *cuint = NULL; const char *path = NULL; @@ -68,12 +63,8 @@ static int dt_i2c_bus_config(struct stm32_i2c_init_s *init, else if (I2C_STANDARD_RATE != CFG_CORE_SE05X_BAUDRATE) IMSG("SE05x ignoring CFG_CORE_SE05X_BAUDRATE, use built-in"); -#ifdef CFG_DRIVERS_PINCTRL return stm32_i2c_get_setup_from_fdt(fdt, node, init, pinctrl_active, pinctrl_sleep); -#else - return stm32_i2c_get_setup_from_fdt(fdt, node, init, pctrl, pcnt); -#endif } int native_i2c_init(void) @@ -85,13 +76,8 @@ int native_i2c_init(void) return 0; /* Support only one device on the platform */ -#ifdef CFG_DRIVERS_PINCTRL if (dt_i2c_bus_config(&i2c_init, &i2c.pinctrl, &i2c.pinctrl_sleep)) return -1; -#else - if (dt_i2c_bus_config(&i2c_init, &pinctrl, &pin_count)) - return -1; -#endif /* Probe the device */ i2c_init.own_address1 = SMCOM_I2C_ADDRESS; diff --git a/core/drivers/stm32_i2c.c b/core/drivers/stm32_i2c.c index 11bb5a88106..c32751c9988 100644 --- a/core/drivers/stm32_i2c.c +++ b/core/drivers/stm32_i2c.c @@ -686,14 +686,8 @@ static int i2c_config_analog_filter(struct i2c_handle_s *hi2c, TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, struct stm32_i2c_init_s *init, -#ifdef CFG_DRIVERS_PINCTRL struct pinctrl_state **pinctrl, - struct pinctrl_state **pinctrl_sleep -#else - struct stm32_pinctrl **pinctrl, - size_t *pinctrl_count -#endif - ) + struct pinctrl_state **pinctrl_sleep) { TEE_Result res = TEE_ERROR_GENERIC; const fdt32_t *cuint = NULL; @@ -740,7 +734,6 @@ TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, init->bus_rate = I2C_STANDARD_RATE; } -#ifdef CFG_DRIVERS_PINCTRL if (pinctrl) { res = pinctrl_get_state_by_name(fdt, node, "default", pinctrl); if (res) @@ -753,28 +746,6 @@ TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, if (res) return res; } -#else - count = stm32_pinctrl_fdt_get_pinctrl(fdt, node, NULL, 0); - if (count <= 0) { - *pinctrl = NULL; - *pinctrl_count = count; - DMSG("Failed to get pinctrl: FDT errno %d", count); - return TEE_ERROR_GENERIC; - } - - if (count > 2) { - DMSG("Too many PINCTRLs found: %zd", count); - return TEE_ERROR_GENERIC; - } - - *pinctrl = calloc(count, sizeof(**pinctrl)); - if (!*pinctrl) - return TEE_ERROR_OUT_OF_MEMORY; - - *pinctrl_count = stm32_pinctrl_fdt_get_pinctrl(fdt, node, - *pinctrl, count); - assert(*pinctrl_count == (unsigned int)count); -#endif /*CFG_DRIVERS_PINCTRL*/ return TEE_SUCCESS; } @@ -857,14 +828,8 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, if (rc) DMSG("I2C analog filter error %d", rc); -#ifdef CFG_DRIVERS_PINCTRL if (IS_ENABLED(CFG_STM32MP13)) stm32_pinctrl_set_secure_cfg(hi2c->pinctrl, true); -#else - if (IS_ENABLED(CFG_STM32MP13)) - stm32_gpio_set_secure_cfg(hi2c->pinctrl->bank, - hi2c->pinctrl->pin, true); -#endif clk_disable(hi2c->clock); @@ -1555,12 +1520,8 @@ void stm32_i2c_resume(struct i2c_handle_s *hi2c) (hi2c->i2c_state != I2C_STATE_SUSPENDED)) panic(); -#ifdef CFG_DRIVERS_PINCTRL if (pinctrl_apply_state(hi2c->pinctrl)) panic(); -#else - stm32_pinctrl_load_active_cfg(hi2c->pinctrl, hi2c->pinctrl_count); -#endif if (hi2c->i2c_state == I2C_STATE_RESET) { /* There is no valid I2C configuration to be loaded yet */ @@ -1569,14 +1530,8 @@ void stm32_i2c_resume(struct i2c_handle_s *hi2c) restore_cfg(hi2c, &hi2c->sec_cfg); -#ifdef CFG_DRIVERS_PINCTRL if (IS_ENABLED(CFG_STM32MP13)) stm32_pinctrl_set_secure_cfg(hi2c->pinctrl, true); -#else - if (IS_ENABLED(CFG_STM32MP13)) - stm32_gpio_set_secure_cfg(hi2c->pinctrl->bank, - hi2c->pinctrl->pin, true); -#endif hi2c->i2c_state = I2C_STATE_READY; } @@ -1591,12 +1546,8 @@ void stm32_i2c_suspend(struct i2c_handle_s *hi2c) save_cfg(hi2c, &hi2c->sec_cfg); -#ifdef CFG_DRIVERS_PINCTRL if (pinctrl_apply_state(hi2c->pinctrl_sleep)) panic(); -#else - stm32_pinctrl_load_standby_cfg(hi2c->pinctrl, hi2c->pinctrl_count); -#endif hi2c->i2c_state = I2C_STATE_SUSPENDED; } diff --git a/core/include/drivers/stm32_i2c.h b/core/include/drivers/stm32_i2c.h index 693b06af5b8..68e4b67754d 100644 --- a/core/include/drivers/stm32_i2c.h +++ b/core/include/drivers/stm32_i2c.h @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -112,11 +111,8 @@ struct i2c_cfg { * @saved_timing: Saved timing value if already computed * @saved_frequency: Saved frequency value if already computed * @sec_cfg: I2C registers configuration storage - * Case CFG_DRIVERS_PINCTRL * @pinctrl: Pin control configuration for the I2C bus in active state * @pinctrl_sleep: Pin control configuration for the I2C bus in standby state - * Case !CFG_DRIVERS_PINCTRL - * @pinctrl: PINCTRLs configuration for the I2C PINs * @pinctrl_count: Number of PINCTRLs elements */ struct i2c_handle_s { @@ -129,13 +125,8 @@ struct i2c_handle_s { uint32_t saved_timing; unsigned long saved_frequency; struct i2c_cfg sec_cfg; -#ifdef CFG_DRIVERS_PINCTRL struct pinctrl_state *pinctrl; struct pinctrl_state *pinctrl_sleep; -#else - struct stm32_pinctrl *pinctrl; - size_t pinctrl_count; -#endif }; /* STM32 specific defines */ @@ -145,7 +136,6 @@ struct i2c_handle_s { #define STM32_I2C_ANALOG_FILTER_DELAY_MAX U(260) /* ns */ #define STM32_I2C_DIGITAL_FILTER_MAX U(16) -#ifdef CFG_DRIVERS_PINCTRL /* * Fill struct stm32_i2c_init_s from DT content for a given I2C node * @@ -160,22 +150,6 @@ TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, struct stm32_i2c_init_s *init, struct pinctrl_state **pinctrl_active, struct pinctrl_state **pinctrl_sleep); -#else -/* - * Fill struct stm32_i2c_init_s from DT content for a given I2C node - * - * @fdt: Reference to DT - * @node: Target I2C node in the DT - * @init: Output stm32_i2c_init_s structure - * @pinctrl: Reference to output pinctrl array - * @pinctrl_count: Input @pinctrl array size, output expected size upon success - * Return a TEE_Result compliant value - */ -TEE_Result stm32_i2c_get_setup_from_fdt(void *fdt, int node, - struct stm32_i2c_init_s *init, - struct stm32_pinctrl **pinctrl, - size_t *pinctrl_count); -#endif /*CFG_DRIVERS_PINCTRL*/ /* * Initialize I2C bus handle from input configuration directives From 0a0c12c7eeaf68eca58e1476ab49d18ef0fc3a4c Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 25 May 2023 18:37:29 +0200 Subject: [PATCH 26/26] drivers: stm32_gpio: move definitions to source file Moves macros and structures definitions from stm32_gpio.h header file to the driver source file as these definition do not need to be visible from other drivers thank to pin control abstraction. Signed-off-by: Etienne Carriere --- core/drivers/stm32_gpio.c | 56 ++++++++++++++++++++++++++++++ core/include/drivers/stm32_gpio.h | 57 +------------------------------ 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 78d5003ad1f..e5bd66ec2e0 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -56,6 +57,61 @@ #define DT_GPIO_BANK_NAME0 "GPIOA" +#define GPIO_MODE_INPUT 0x0 +#define GPIO_MODE_OUTPUT 0x1 +#define GPIO_MODE_ALTERNATE 0x2 +#define GPIO_MODE_ANALOG 0x3 + +#define GPIO_OTYPE_PUSH_PULL 0x0 +#define GPIO_OTYPE_OPEN_DRAIN 0x1 + +#define GPIO_OSPEED_LOW 0x0 +#define GPIO_OSPEED_MEDIUM 0x1 +#define GPIO_OSPEED_HIGH 0x2 +#define GPIO_OSPEED_VERY_HIGH 0x3 + +#define GPIO_PUPD_NO_PULL 0x0 +#define GPIO_PUPD_PULL_UP 0x1 +#define GPIO_PUPD_PULL_DOWN 0x2 + +#define GPIO_OD_LEVEL_LOW 0x0 +#define GPIO_OD_LEVEL_HIGH 0x1 + +/* + * GPIO configuration description structured as single 16bit word + * for efficient save/restore when GPIO pin suspends or resumes. + * + * @mode: One of GPIO_MODE_* + * @otype: One of GPIO_OTYPE_* + * @ospeed: One of GPIO_OSPEED_* + * @pupd: One of GPIO_PUPD_* + * @od: One of GPIO_OD_* + * @af: Alternate function numerical ID between 0 and 15 + */ +struct gpio_cfg { + uint16_t mode: 2; + uint16_t otype: 1; + uint16_t ospeed: 2; + uint16_t pupd: 2; + uint16_t od: 1; + uint16_t af: 4; +}; + +/* + * Descrption of a pin and its 2 states muxing + * + * @bank: GPIO bank identifier as assigned by the platform + * @pin: Pin number in the GPIO bank + * @cfg: Pin configuration + * @active_cfg: Configuration in active state + * @standby_cfg: Configuration in standby state + */ +struct stm32_pinctrl { + uint8_t bank; + uint8_t pin; + struct gpio_cfg cfg; +}; + /* * struct stm32_pinctrl_array - Array of pins in a pin control state * @count: Number of cells in @pinctrl diff --git a/core/include/drivers/stm32_gpio.h b/core/include/drivers/stm32_gpio.h index 86485e68316..da028fcaeb4 100644 --- a/core/include/drivers/stm32_gpio.h +++ b/core/include/drivers/stm32_gpio.h @@ -7,68 +7,13 @@ #define DRIVERS_STM32_GPIO_H #include -#include #include #include #include #include -#define GPIO_MODE_INPUT 0x0 -#define GPIO_MODE_OUTPUT 0x1 -#define GPIO_MODE_ALTERNATE 0x2 -#define GPIO_MODE_ANALOG 0x3 - -#define GPIO_OTYPE_PUSH_PULL 0x0 -#define GPIO_OTYPE_OPEN_DRAIN 0x1 - -#define GPIO_OSPEED_LOW 0x0 -#define GPIO_OSPEED_MEDIUM 0x1 -#define GPIO_OSPEED_HIGH 0x2 -#define GPIO_OSPEED_VERY_HIGH 0x3 - -#define GPIO_PUPD_NO_PULL 0x0 -#define GPIO_PUPD_PULL_UP 0x1 -#define GPIO_PUPD_PULL_DOWN 0x2 - -#define GPIO_OD_LEVEL_LOW 0x0 -#define GPIO_OD_LEVEL_HIGH 0x1 - struct pinctrl_state; - -/* - * GPIO configuration description structured as single 16bit word - * for efficient save/restore when GPIO pin suspends or resumes. - * - * @mode: One of GPIO_MODE_* - * @otype: One of GPIO_OTYPE_* - * @ospeed: One of GPIO_OSPEED_* - * @pupd: One of GPIO_PUPD_* - * @od: One of GPIO_OD_* - * @af: Alternate function numerical ID between 0 and 15 - */ -struct gpio_cfg { - uint16_t mode: 2; - uint16_t otype: 1; - uint16_t ospeed: 2; - uint16_t pupd: 2; - uint16_t od: 1; - uint16_t af: 4; -}; - -/* - * Descrption of a pin and its 2 states muxing - * - * @bank: GPIO bank identifier as assigned by the platform - * @pin: Pin number in the GPIO bank - * @cfg: Pin configuration - * @active_cfg: Configuration in active state - * @standby_cfg: Configuration in standby state - */ -struct stm32_pinctrl { - uint8_t bank; - uint8_t pin; - struct gpio_cfg cfg; -}; +struct stm32_pinctrl; /* * Save pinctrl instances defined in DT node: identifiers and power states