diff mbox series

[u-boot-mvebu,2/2] arm: mvebu: turris_omnia: fixup MTD partitions in Linux' DTB

Message ID 20210715172102.28549-2-marek.behun@nic.cz
State Accepted
Commit 92f36c8e74c19a7a84aca4dcea121eabc97b05f1
Delegated to: Stefan Roese
Headers show
Series [u-boot-mvebu,1/2] ARM: dts: armada-385-turris-omnia: add `u-boot-env` NOR partition | expand

Commit Message

Marek Behún July 15, 2021, 5:21 p.m. UTC
Fixup SPI NOR partition nodes in Linux' device tree prior booting Linux.

Linux' devicetree does not contain "u-boot-env" partition and we do not
want to add it there because the address is different between stock
U-Boot and current upstream U-Boot.

Instead we add code that recreates partition nodes from scratch
according to how U-Boot sees them (which is defined in U-Boot's device
tree).

Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
Hi Stefan,

the code of the fixup_mtd_partitions() function I am adding with this
patch is generic enough to be potentially used on other boards (for
example EspressoBIN's board code does something similar, so it could use
this function).

Indeed I want to generalize it, since there are multiple boards fixing
partition nodes in DTS prior booting Linux and there is already code for
this in common/fdt_support.c. The problem is that that code does not work
with DM_MTD, but rather with the obsolete MTDPARTS and several boards use
it. I want to convert those boards into using this new API, but this will
take some time and should be done via u-boot-spi tree.

So please for now merge this code via the mvebu tree. In the meantime
till this is merged into Tom's tree I shall be working on converting
those other boards that use fdt_fixup_mtdparts() to use device tree for
defining MTD partitions so that we can remove fdt_fixup_mtdparts(), move
this new code into common/fdt_support.c and covert those boards to use
this new code.
---
 board/CZ.NIC/turris_omnia/turris_omnia.c | 90 ++++++++++++++++++++++++
 configs/turris_omnia_defconfig           |  1 +
 2 files changed, 91 insertions(+)

Comments

Stefan Roese July 19, 2021, 7:03 a.m. UTC | #1
Hi Marek,

On 15.07.21 19:21, Marek Behún wrote:
> Fixup SPI NOR partition nodes in Linux' device tree prior booting Linux.
> 
> Linux' devicetree does not contain "u-boot-env" partition and we do not
> want to add it there because the address is different between stock
> U-Boot and current upstream U-Boot.
> 
> Instead we add code that recreates partition nodes from scratch
> according to how U-Boot sees them (which is defined in U-Boot's device
> tree).
> 
> Signed-off-by: Marek Behún <marek.behun@nic.cz>
> ---
> Hi Stefan,
> 
> the code of the fixup_mtd_partitions() function I am adding with this
> patch is generic enough to be potentially used on other boards (for
> example EspressoBIN's board code does something similar, so it could use
> this function).
> 
> Indeed I want to generalize it, since there are multiple boards fixing
> partition nodes in DTS prior booting Linux and there is already code for
> this in common/fdt_support.c. The problem is that that code does not work
> with DM_MTD, but rather with the obsolete MTDPARTS and several boards use
> it. I want to convert those boards into using this new API, but this will
> take some time and should be done via u-boot-spi tree.
> 
> So please for now merge this code via the mvebu tree. In the meantime
> till this is merged into Tom's tree I shall be working on converting
> those other boards that use fdt_fixup_mtdparts() to use device tree for
> defining MTD partitions so that we can remove fdt_fixup_mtdparts(), move
> this new code into common/fdt_support.c and covert those boards to use
> this new code.

Thanks for the details explanation and also thanks for working on this
generalization of this "feature".

With this background:

Reviewed-by: Stefan Roese <sr@denx.de>

Thanks,
Stefan

> ---
>   board/CZ.NIC/turris_omnia/turris_omnia.c | 90 ++++++++++++++++++++++++
>   configs/turris_omnia_defconfig           |  1 +
>   2 files changed, 91 insertions(+)
> 
> diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
> index 8b2f94f959..a7e5f56eed 100644
> --- a/board/CZ.NIC/turris_omnia/turris_omnia.c
> +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
> @@ -13,6 +13,7 @@
>   #include <init.h>
>   #include <log.h>
>   #include <miiphy.h>
> +#include <mtd.h>
>   #include <net.h>
>   #include <netdev.h>
>   #include <asm/global_data.h>
> @@ -31,6 +32,8 @@
>   
>   DECLARE_GLOBAL_DATA_PTR;
>   
> +#define OMNIA_SPI_NOR_PATH		"/soc/spi@10600/spi-nor@0"
> +
>   #define OMNIA_I2C_BUS_NAME		"i2c@11000->i2cmux@70->i2c@0"
>   
>   #define OMNIA_I2C_MCU_CHIP_ADDR		0x2a
> @@ -557,3 +560,90 @@ out:
>   	return 0;
>   }
>   
> +#if defined(CONFIG_OF_BOARD_SETUP)
> +/*
> + * I plan to generalize this function and move it to common/fdt_support.c.
> + * This will require some more work on multiple boards, though, so for now leave
> + * it here.
> + */
> +static bool fixup_mtd_partitions(void *blob, int offset, struct mtd_info *mtd)
> +{
> +	struct mtd_info *slave;
> +	int parts;
> +
> +	parts = fdt_subnode_offset(blob, offset, "partitions");
> +	if (parts < 0)
> +		return false;
> +
> +	if (fdt_del_node(blob, parts) < 0)
> +		return false;
> +
> +	parts = fdt_add_subnode(blob, offset, "partitions");
> +	if (parts < 0)
> +		return false;
> +
> +	if (fdt_setprop_u32(blob, parts, "#address-cells", 1) < 0)
> +		return false;
> +
> +	if (fdt_setprop_u32(blob, parts, "#size-cells", 1) < 0)
> +		return false;
> +
> +	if (fdt_setprop_string(blob, parts, "compatible",
> +			       "fixed-partitions") < 0)
> +		return false;
> +
> +	mtd_probe_devices();
> +
> +	list_for_each_entry(slave, &mtd->partitions, node) {
> +		char name[32];
> +		int part;
> +
> +		snprintf(name, sizeof(name), "partition@%llx", slave->offset);
> +		part = fdt_add_subnode(blob, parts, name);
> +		if (part < 0)
> +			return false;
> +
> +		if (fdt_setprop_u32(blob, part, "reg", slave->offset) < 0)
> +			return false;
> +
> +		if (fdt_appendprop_u32(blob, part, "reg", slave->size) < 0)
> +			return false;
> +
> +		if (fdt_setprop_string(blob, part, "label", slave->name) < 0)
> +			return false;
> +
> +		if (!(slave->flags & MTD_WRITEABLE))
> +			if (fdt_setprop_empty(blob, part, "read-only") < 0)
> +				return false;
> +
> +		if (slave->flags & MTD_POWERUP_LOCK)
> +			if (fdt_setprop_empty(blob, part, "lock") < 0)
> +				return false;
> +	}
> +
> +	return true;
> +}
> +
> +int ft_board_setup(void *blob, struct bd_info *bd)
> +{
> +	struct mtd_info *mtd;
> +	int node;
> +
> +	mtd = get_mtd_device_nm(OMNIA_SPI_NOR_PATH);
> +	if (IS_ERR_OR_NULL(mtd))
> +		goto fail;
> +
> +	node = fdt_path_offset(blob, OMNIA_SPI_NOR_PATH);
> +	if (node < 0)
> +		goto fail;
> +
> +	if (!fixup_mtd_partitions(blob, node, mtd))
> +		goto fail;
> +
> +	return 0;
> +
> +fail:
> +	printf("Failed fixing SPI NOR partitions!\n");
> +	return 0;
> +}
> +#endif
> diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
> index f860cf5e7d..5f7b1a67a2 100644
> --- a/configs/turris_omnia_defconfig
> +++ b/configs/turris_omnia_defconfig
> @@ -23,6 +23,7 @@ CONFIG_SPL=y
>   CONFIG_DEBUG_UART_BASE=0xd0012000
>   CONFIG_DEBUG_UART_CLOCK=250000000
>   CONFIG_DEBUG_UART=y
> +CONFIG_OF_BOARD_SETUP=y
>   CONFIG_AHCI=y
>   CONFIG_DISTRO_DEFAULTS=y
>   CONFIG_FIT=y
>
diff mbox series

Patch

diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
index 8b2f94f959..a7e5f56eed 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -13,6 +13,7 @@ 
 #include <init.h>
 #include <log.h>
 #include <miiphy.h>
+#include <mtd.h>
 #include <net.h>
 #include <netdev.h>
 #include <asm/global_data.h>
@@ -31,6 +32,8 @@ 
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#define OMNIA_SPI_NOR_PATH		"/soc/spi@10600/spi-nor@0"
+
 #define OMNIA_I2C_BUS_NAME		"i2c@11000->i2cmux@70->i2c@0"
 
 #define OMNIA_I2C_MCU_CHIP_ADDR		0x2a
@@ -557,3 +560,90 @@  out:
 	return 0;
 }
 
+#if defined(CONFIG_OF_BOARD_SETUP)
+/*
+ * I plan to generalize this function and move it to common/fdt_support.c.
+ * This will require some more work on multiple boards, though, so for now leave
+ * it here.
+ */
+static bool fixup_mtd_partitions(void *blob, int offset, struct mtd_info *mtd)
+{
+	struct mtd_info *slave;
+	int parts;
+
+	parts = fdt_subnode_offset(blob, offset, "partitions");
+	if (parts < 0)
+		return false;
+
+	if (fdt_del_node(blob, parts) < 0)
+		return false;
+
+	parts = fdt_add_subnode(blob, offset, "partitions");
+	if (parts < 0)
+		return false;
+
+	if (fdt_setprop_u32(blob, parts, "#address-cells", 1) < 0)
+		return false;
+
+	if (fdt_setprop_u32(blob, parts, "#size-cells", 1) < 0)
+		return false;
+
+	if (fdt_setprop_string(blob, parts, "compatible",
+			       "fixed-partitions") < 0)
+		return false;
+
+	mtd_probe_devices();
+
+	list_for_each_entry(slave, &mtd->partitions, node) {
+		char name[32];
+		int part;
+
+		snprintf(name, sizeof(name), "partition@%llx", slave->offset);
+		part = fdt_add_subnode(blob, parts, name);
+		if (part < 0)
+			return false;
+
+		if (fdt_setprop_u32(blob, part, "reg", slave->offset) < 0)
+			return false;
+
+		if (fdt_appendprop_u32(blob, part, "reg", slave->size) < 0)
+			return false;
+
+		if (fdt_setprop_string(blob, part, "label", slave->name) < 0)
+			return false;
+
+		if (!(slave->flags & MTD_WRITEABLE))
+			if (fdt_setprop_empty(blob, part, "read-only") < 0)
+				return false;
+
+		if (slave->flags & MTD_POWERUP_LOCK)
+			if (fdt_setprop_empty(blob, part, "lock") < 0)
+				return false;
+	}
+
+	return true;
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+	struct mtd_info *mtd;
+	int node;
+
+	mtd = get_mtd_device_nm(OMNIA_SPI_NOR_PATH);
+	if (IS_ERR_OR_NULL(mtd))
+		goto fail;
+
+	node = fdt_path_offset(blob, OMNIA_SPI_NOR_PATH);
+	if (node < 0)
+		goto fail;
+
+	if (!fixup_mtd_partitions(blob, node, mtd))
+		goto fail;
+
+	return 0;
+
+fail:
+	printf("Failed fixing SPI NOR partitions!\n");
+	return 0;
+}
+#endif
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index f860cf5e7d..5f7b1a67a2 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -23,6 +23,7 @@  CONFIG_SPL=y
 CONFIG_DEBUG_UART_BASE=0xd0012000
 CONFIG_DEBUG_UART_CLOCK=250000000
 CONFIG_DEBUG_UART=y
+CONFIG_OF_BOARD_SETUP=y
 CONFIG_AHCI=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_FIT=y