stm32mp1: split code between common and private parts
Some parts of code could be shared with platform derivatives,
or new platforms.
A new folder plat/st/common is created to put common parts.
stm32mp_common.h is a common API aggregate.
Remove some casts where applicable.
Fix some types where applicable.
Remove also some platform includes that are already in stm32mp1_def.h.
Change-Id: I46d763c8d9e15732d1ee7383207fd58206d7f583
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
new file mode 100644
index 0000000..2eaa9d9
--- /dev/null
+++ b/plat/st/common/stm32mp_dt.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp1_clk.h>
+#include <drivers/st/stm32mp1_ddr.h>
+#include <drivers/st/stm32mp1_ram.h>
+
+#include <stm32mp_dt.h>
+
+static int fdt_checked;
+
+static void *fdt = (void *)(uintptr_t)STM32MP1_DTB_BASE;
+
+/*******************************************************************************
+ * This function checks device tree file with its header.
+ * Returns 0 on success and a negative FDT error code on failure.
+ ******************************************************************************/
+int dt_open_and_check(void)
+{
+ int ret = fdt_check_header(fdt);
+
+ if (ret == 0) {
+ fdt_checked = 1;
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+ * This function gets the address of the DT.
+ * If DT is OK, fdt_addr is filled with DT address.
+ * Returns 1 if success, 0 otherwise.
+ ******************************************************************************/
+int fdt_get_address(void **fdt_addr)
+{
+ if (fdt_checked == 1) {
+ *fdt_addr = fdt;
+ }
+
+ return fdt_checked;
+}
+
+/*******************************************************************************
+ * This function check the presence of a node (generic use of fdt library).
+ * Returns true if present, else return false.
+ ******************************************************************************/
+bool fdt_check_node(int node)
+{
+ int len;
+ const char *cchar;
+
+ cchar = fdt_get_name(fdt, node, &len);
+
+ return (cchar != NULL) && (len >= 0);
+}
+
+/*******************************************************************************
+ * This function return global node status (generic use of fdt library).
+ ******************************************************************************/
+uint8_t fdt_get_status(int node)
+{
+ uint8_t status = DT_DISABLED;
+ int len;
+ const char *cchar;
+
+ cchar = fdt_getprop(fdt, node, "status", &len);
+ if ((cchar == NULL) ||
+ (strncmp(cchar, "okay", (size_t)len) == 0)) {
+ status |= DT_NON_SECURE;
+ }
+
+ cchar = fdt_getprop(fdt, node, "secure-status", &len);
+ if (cchar == NULL) {
+ if (status == DT_NON_SECURE) {
+ status |= DT_SECURE;
+ }
+ } else if (strncmp(cchar, "okay", (size_t)len) == 0) {
+ status |= DT_SECURE;
+ }
+
+ return status;
+}
+
+/*******************************************************************************
+ * This function reads a value of a node property (generic use of fdt
+ * library).
+ * Returns value if success, and a default value if property not found.
+ * Default value is passed as parameter.
+ ******************************************************************************/
+uint32_t fdt_read_uint32_default(int node, const char *prop_name,
+ uint32_t dflt_value)
+{
+ const fdt32_t *cuint;
+ int lenp;
+
+ cuint = fdt_getprop(fdt, node, prop_name, &lenp);
+ if (cuint == NULL) {
+ return dflt_value;
+ }
+
+ return fdt32_to_cpu(*cuint);
+}
+
+/*******************************************************************************
+ * This function reads a series of parameters in a node property
+ * (generic use of fdt library).
+ * It reads the values inside the device tree, from property name and node.
+ * The number of parameters is also indicated as entry parameter.
+ * Returns 0 on success and a negative FDT error code on failure.
+ * If success, values are stored at the third parameter address.
+ ******************************************************************************/
+int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
+ uint32_t count)
+{
+ const fdt32_t *cuint;
+ int len;
+ uint32_t i;
+
+ cuint = fdt_getprop(fdt, node, prop_name, &len);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ if ((uint32_t)len != (count * sizeof(uint32_t))) {
+ return -FDT_ERR_BADLAYOUT;
+ }
+
+ for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+ *array = fdt32_to_cpu(*cuint);
+ array++;
+ cuint++;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function gets the stdout pin configuration information from the DT.
+ * And then calls the sub-function to treat it and set GPIO registers.
+ * Returns 0 on success and a negative FDT error code on failure.
+ ******************************************************************************/
+int dt_set_stdout_pinctrl(void)
+{
+ int node;
+
+ node = dt_get_stdout_node_offset();
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return dt_set_pinctrl_config(node);
+}
+
+/*******************************************************************************
+ * This function fills the generic information from a given node.
+ ******************************************************************************/
+void dt_fill_device_info(struct dt_node_info *info, int node)
+{
+ const fdt32_t *cuint;
+
+ cuint = fdt_getprop(fdt, node, "reg", NULL);
+ if (cuint != NULL) {
+ info->base = fdt32_to_cpu(*cuint);
+ } else {
+ info->base = 0;
+ }
+
+ cuint = fdt_getprop(fdt, node, "clocks", NULL);
+ if (cuint != NULL) {
+ cuint++;
+ info->clock = (int)fdt32_to_cpu(*cuint);
+ } else {
+ info->clock = -1;
+ }
+
+ cuint = fdt_getprop(fdt, node, "resets", NULL);
+ if (cuint != NULL) {
+ cuint++;
+ info->reset = (int)fdt32_to_cpu(*cuint);
+ } else {
+ info->reset = -1;
+ }
+
+ info->status = fdt_get_status(node);
+}
+
+/*******************************************************************************
+ * This function retrieve the generic information from DT.
+ * Returns node on success and a negative FDT error code on failure.
+ ******************************************************************************/
+int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
+{
+ int node;
+
+ node = fdt_node_offset_by_compatible(fdt, offset, compat);
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ dt_fill_device_info(info, node);
+
+ return node;
+}
+
+/*******************************************************************************
+ * This function gets the UART instance info of stdout from the DT.
+ * Returns node on success and a negative FDT error code on failure.
+ ******************************************************************************/
+int dt_get_stdout_uart_info(struct dt_node_info *info)
+{
+ int node;
+
+ node = dt_get_stdout_node_offset();
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ dt_fill_device_info(info, node);
+
+ return node;
+}
+
+/*******************************************************************************
+ * This function gets the stdout path node.
+ * It reads the value indicated inside the device tree.
+ * Returns node if success, and a negative value else.
+ ******************************************************************************/
+int dt_get_stdout_node_offset(void)
+{
+ int node;
+ const char *cchar;
+
+ node = fdt_path_offset(fdt, "/chosen");
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ cchar = fdt_getprop(fdt, node, "stdout-path", NULL);
+ if (cchar == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ node = -FDT_ERR_NOTFOUND;
+ if (strchr(cchar, (int)':') != NULL) {
+ const char *name;
+ char *str = (char *)cchar;
+ int len = 0;
+
+ while (strncmp(":", str, 1)) {
+ len++;
+ str++;
+ }
+
+ name = fdt_get_alias_namelen(fdt, cchar, len);
+
+ if (name != NULL) {
+ node = fdt_path_offset(fdt, name);
+ }
+ } else {
+ node = fdt_path_offset(fdt, cchar);
+ }
+
+ return node;
+}
+
+/*******************************************************************************
+ * This function gets DDR size information from the DT.
+ * Returns value in bytes on success, and 0 on failure.
+ ******************************************************************************/
+uint32_t dt_get_ddr_size(void)
+{
+ int node;
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+ if (node < 0) {
+ INFO("%s: Cannot read DDR node in DT\n", __func__);
+ return 0;
+ }
+
+ return fdt_read_uint32_default(node, "st,mem-size", 0);
+}
+
+/*******************************************************************************
+ * This function retrieves board model from DT
+ * Returns string taken from model node, NULL otherwise
+ ******************************************************************************/
+const char *dt_get_board_model(void)
+{
+ int node = fdt_path_offset(fdt, "/");
+
+ if (node < 0) {
+ return NULL;
+ }
+
+ return (const char *)fdt_getprop(fdt, node, "model", NULL);
+}