All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Simek <michal.simek@xilinx.com>
To: u-boot@lists.denx.de, git@xilinx.com
Cc: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>,
	Michal Simek <monstr@monstr.eu>,
	T Karthik Reddy <t.karthik.reddy@xilinx.com>
Subject: [PATCH 10/10] xilinx: common: Enabling generic function for DT reselection
Date: Thu, 19 Aug 2021 13:19:49 +0200	[thread overview]
Message-ID: <acf97284a85deeb5dd91f8ac4441d4697465eee5.1629371983.git.michal.simek@xilinx.com> (raw)
In-Reply-To: <cover.1629371983.git.michal.simek@xilinx.com>

U-Boot support board detection at run time and based on it change DT.
This feature is implemented for SOM Kria platforms which contain two
eeproms which contain information about SOM module and CC (Carrier card).
Full U-Boot starts with minimal DT file defined by
CONFIG_DEFAULT_DEVICE_TREE which is available in multi DTB fit image.
It is using default setup of board_name variable initializaed to
DEVICE_TREE which corresponds to CONFIG_DEFAULT_DEVICE_TREE option.

When DTB_RESELECT is enabled board_detection() is called. Keep it your mind
that this code is called before relocation. board_detection() is calling
xilinx_read_eeprom() which fills board_info (xilinx_board_description)
structure which are parsed in board_name_decode().
Based on DT configuration and amount of nvmemX aliases name of the board is
composed by concatenating CONFIG_SYS_BOARD "-" <board_name> "-rev"
<board_revision> "-" <cc_name> "-rev" <cc_revision>.

If CC is not present or more are available it keeps going.

When board name is composed and returned from board_name_decode() it is
assigned to board_name variable which is used by
board_fit_config_name_match() which is called via fdtdec_setup() when it
goes over config options in multi dtb FIT image.

From practical point of view multi DTB image is key point here which has to
contain configs for detected combinations. Unfortunately as of now they
have to be full DTBs and DTBOs are not supported.

That's why configuration like:
config_X {
	description = "zynqmp-board-cc";
	fdt = "board", "cc";
};

needs to be squashed together with:
fdtoverlay -o zynqmp-board-cc -i arch/arm/dts/zynqmp-board.dtb \
arch/arm/dts/zynqmp-cc.dtbo

and only one dtb is in fit:
config_X {
	description = "zynqmp-board-cc";
	fdt = "board-cc";
};

For creating multi DTBs fit image use mkimage -E, e.g.:
mkimage -E -f all.its all.dtb

When DTB_RESELECT is enabled xilinx_read_eeprom() is called before
relocation and it uses calloc for getting a buffer. Because this is dynamic
memory it is not relocated that's why xilinx_read_eeprom() is called again
as the part of board_init(). This second read with calloc buffer placed in
proper position board_late_init_xilinx() can setup u-boot variables as
before.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 arch/arm/dts/zynqmp-sm-k26-revA.dts |  3 ++
 board/xilinx/common/board.c         | 84 ++++++++++++++++++++++++++---
 2 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/arch/arm/dts/zynqmp-sm-k26-revA.dts b/arch/arm/dts/zynqmp-sm-k26-revA.dts
index e274100a9bc5..5f55df28f331 100644
--- a/arch/arm/dts/zynqmp-sm-k26-revA.dts
+++ b/arch/arm/dts/zynqmp-sm-k26-revA.dts
@@ -204,17 +204,20 @@
 
 &i2c1 {
 	status = "okay";
+	u-boot,dm-pre-reloc;
 	clock-frequency = <400000>;
 	scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>;
 	sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>;
 
 	eeprom: eeprom@50 { /* u46 - also at address 0x58 */
+		u-boot,dm-pre-reloc;
 		compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
 		reg = <0x50>;
 		/* WP pin EE_WP_EN connected to slg7x644092@68 */
 	};
 
 	eeprom_cc: eeprom@51 { /* required by spec - also at address 0x59 */
+		u-boot,dm-pre-reloc;
 		compatible = "st,24c64", "atmel,24c64"; /* st m24c64 */
 		reg = <0x51>;
 	};
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 92874272893a..979df44306af 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -19,6 +19,7 @@
 #include <net.h>
 #include <generated/dt.h>
 #include <soc.h>
+#include <linux/ctype.h>
 
 #include "fru.h"
 
@@ -188,12 +189,14 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
 		goto end;
 	}
 
-	printf("Xilinx I2C FRU format at %s:\n", name);
-	fru_capture((unsigned long)fru_content);
-	ret = fru_display(0);
-	if (ret) {
-		printf("FRU format decoding failed.\n");
-		goto end;
+	if (gd->flags & GD_FLG_RELOC || (_DEBUG && CONFIG_IS_ENABLED(DTB_RESELECT))) {
+		printf("Xilinx I2C FRU format at %s:\n", name);
+		fru_capture((unsigned long)fru_content);
+		ret = fru_display(0);
+		if (ret) {
+			printf("FRU format decoding failed.\n");
+			goto end;
+		}
 	}
 
 	if (desc->header == EEPROM_HEADER_MAGIC) {
@@ -465,13 +468,82 @@ int print_cpuinfo(void)
 #endif
 
 #if CONFIG_IS_ENABLED(DTB_RESELECT)
+#define MAX_NAME_LENGTH	50
+
 char * __maybe_unused __weak board_name_decode(void)
 {
+	char *board_local_name;
+	struct xilinx_board_description *desc;
+	int i, id;
+
+	board_local_name = calloc(1, MAX_NAME_LENGTH);
+	if (!board_info)
+		return NULL;
+
+	for (id = 0; id <= highest_id; id++) {
+		desc = &board_info[id];
+
+		/* No board description */
+		if (!desc)
+			goto error;
+
+		/* Board is not detected */
+		if (desc->header != EEPROM_HEADER_MAGIC)
+			continue;
+
+		/* The first string should be soc name */
+		if (!id)
+			strcat(board_local_name, CONFIG_SYS_BOARD);
+
+		/*
+		 * For two purpose here:
+		 * soc_name- eg: zynqmp-
+		 * and between base board and CC eg: ..revA-sck...
+		 */
+		strcat(board_local_name, "-");
+
+		if (desc->name[0]) {
+			/* For DT composition name needs to be lowercase */
+			for (i = 0; i < sizeof(desc->name); i++)
+				desc->name[i] = tolower(desc->name[i]);
+
+			strcat(board_local_name, desc->name);
+		}
+		if (desc->revision[0]) {
+			strcat(board_local_name, "-rev");
+
+			/* And revision needs to be uppercase */
+			for (i = 0; i < sizeof(desc->revision); i++)
+				desc->revision[i] = toupper(desc->revision[i]);
+
+			strcat(board_local_name, desc->revision);
+		}
+	}
+
+	/*
+	 * Longer strings will end up with buffer overflow and potential
+	 * attacks that's why check it
+	 */
+	if (strlen(board_local_name) >= MAX_NAME_LENGTH)
+		panic("Board name can't be determined\n");
+
+	if (strlen(board_local_name))
+		return board_local_name;
+
+error:
+	free(board_local_name);
 	return NULL;
 }
 
 bool __maybe_unused __weak board_detection(void)
 {
+	if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM)) {
+		int ret;
+
+		ret = xilinx_read_eeprom();
+		return !ret ? true : false;
+	}
+
 	return false;
 }
 
-- 
2.32.0


  parent reply	other threads:[~2021-08-19 11:21 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-19 11:19 [PATCH 00/10] xilinx: Add support for DTB reselection Michal Simek
2021-08-19 11:19 ` [PATCH 01/10] xilinx: fru: Replace spaces with \0 in detected name Michal Simek
2021-08-19 11:19 ` [PATCH 02/10] xilinx: Use variable for passing board_name Michal Simek
2021-08-19 11:19 ` [PATCH 03/10] xilinx: common: Change board_info[] handling Michal Simek
2021-08-19 11:19 ` [PATCH 04/10] xilinx: common: Free allocated structure Michal Simek
2021-08-19 11:19 ` [PATCH 05/10] xilinx: Add support for generic board detection Michal Simek
2021-08-19 11:19 ` [PATCH 06/10] xilinx: zynqmp: Check that DT is 64bit aligned Michal Simek
2021-08-19 11:19 ` [PATCH 07/10] Makefile: Align fit-dtb.blob and u-boot.itb by 64bits for 64bit systems Michal Simek
2021-08-19 15:56   ` Andre Przywara
2021-08-19 16:01     ` Michal Simek
2021-08-19 16:18       ` Tom Rini
2021-08-19 16:31         ` Michal Simek
2021-08-19 16:44           ` Tom Rini
2021-08-19 11:19 ` [PATCH 08/10] arm64: dts: Make sure that all DTBs are 64bit aligned " Michal Simek
2021-08-19 16:10   ` Andre Przywara
2021-08-19 16:34     ` Michal Simek
2021-08-19 11:19 ` [PATCH 09/10] xilinx: zynqmp: Generate different u-boot.itb for MULTI_DTB_FIT Michal Simek
2021-08-19 11:19 ` Michal Simek [this message]
2021-08-23  7:37 [PATCH 00/10] xilinx: Add support for DTB reselection Michal Simek
2021-08-23  7:37 ` [PATCH 10/10] xilinx: common: Enabling generic function for DT reselection Michal Simek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=acf97284a85deeb5dd91f8ac4441d4697465eee5.1629371983.git.michal.simek@xilinx.com \
    --to=michal.simek@xilinx.com \
    --cc=ashok.reddy.soma@xilinx.com \
    --cc=git@xilinx.com \
    --cc=monstr@monstr.eu \
    --cc=t.karthik.reddy@xilinx.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.