plat/stm32mp1: fdt helpers for secure aware gpio bank

New helper functions to get GPIO banks configuration from the FDT.

stm32_get_gpio_bank_pinctrl_node() allows stm32mp platforms to
differentiate specific GPIO banks when these are defined with a specific
path in the FDT.

fdt_get_gpio_bank_pin_count() returns the number of pins in a GPIO bank
as it depends on the SoC variant.

Change-Id: I4481774152b3c6bf35bf986f58e357c2f9c19176
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h
index 27ddab0..feeb4a7 100644
--- a/plat/st/common/include/stm32mp_common.h
+++ b/plat/st/common/include/stm32mp_common.h
@@ -61,6 +61,9 @@
 unsigned long stm32_get_gpio_bank_clock(unsigned int bank);
 uint32_t stm32_get_gpio_bank_offset(unsigned int bank);
 
+/* Return node offset for target GPIO bank ID @bank or a FDT error code */
+int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank);
+
 /* Print CPU information */
 void stm32mp_print_cpuinfo(void);
 
diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h
index e79551a..44ad820 100644
--- a/plat/st/common/include/stm32mp_dt.h
+++ b/plat/st/common/include/stm32mp_dt.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2020, STMicroelectronics - All Rights Reserved
  * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
@@ -39,5 +40,6 @@
 uint32_t dt_get_pwr_vdd_voltage(void);
 uintptr_t dt_get_syscfg_base(void);
 const char *dt_get_board_model(void);
+int fdt_get_gpio_bank_pin_count(unsigned int bank);
 
 #endif /* STM32MP_DT_H */
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index 155f784..4b8b2db 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -393,3 +393,51 @@
 
 	return (const char *)fdt_getprop(fdt, node, "model", NULL);
 }
+
+/*******************************************************************************
+ * This function gets the pin count for a GPIO bank based from the FDT.
+ * It also checks node consistency.
+ ******************************************************************************/
+int fdt_get_gpio_bank_pin_count(unsigned int bank)
+{
+	int pinctrl_node;
+	int node;
+	uint32_t bank_offset;
+
+	pinctrl_node = stm32_get_gpio_bank_pinctrl_node(fdt, bank);
+	if (pinctrl_node < 0) {
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	bank_offset = stm32_get_gpio_bank_offset(bank);
+
+	fdt_for_each_subnode(node, fdt, pinctrl_node) {
+		const fdt32_t *cuint;
+
+		if (fdt_getprop(fdt, node, "gpio-controller", NULL) == NULL) {
+			continue;
+		}
+
+		cuint = fdt_getprop(fdt, node, "reg", NULL);
+		if (cuint == NULL) {
+			continue;
+		}
+
+		if (fdt32_to_cpu(*cuint) != bank_offset) {
+			continue;
+		}
+
+		if (fdt_get_status(node) == DT_DISABLED) {
+			return 0;
+		}
+
+		cuint = fdt_getprop(fdt, node, "ngpios", NULL);
+		if (cuint == NULL) {
+			return -FDT_ERR_NOTFOUND;
+		}
+
+		return (int)fdt32_to_cpu(*cuint);
+	}
+
+	return 0;
+}
diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c
index 284ec9f..779228d 100644
--- a/plat/st/stm32mp1/stm32mp1_private.c
+++ b/plat/st/stm32mp1/stm32mp1_private.c
@@ -109,6 +109,28 @@
 	return GPIOA + (bank - GPIO_BANK_A);
 }
 
+int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
+{
+	switch (bank) {
+	case GPIO_BANK_A:
+	case GPIO_BANK_B:
+	case GPIO_BANK_C:
+	case GPIO_BANK_D:
+	case GPIO_BANK_E:
+	case GPIO_BANK_F:
+	case GPIO_BANK_G:
+	case GPIO_BANK_H:
+	case GPIO_BANK_I:
+	case GPIO_BANK_J:
+	case GPIO_BANK_K:
+		return fdt_path_offset(fdt, "/soc/pin-controller");
+	case GPIO_BANK_Z:
+		return fdt_path_offset(fdt, "/soc/pin-controller-z");
+	default:
+		panic();
+	}
+}
+
 static int get_part_number(uint32_t *part_nb)
 {
 	uint32_t part_number;