[PATCH v2 u-boot-marvell 3/4] arm: mvebu: turris_mox: Setup Linux's device tree before boot

Stefan Roese sr at denx.de
Mon Apr 6 11:12:48 CEST 2020


On 03.04.20 17:25, Marek Behún wrote:
> Patch Linux's device tree according to which Mox modules are connected.
> Linux's device tree has all possible Mox module nodes preprogrammed, but
> in disabled state.
> 
> If MOX B, MOX F or MOX G module is present, this code enables the PCI
> node.
> 
> For the network modules (MOX C, MOX D and MOX E) are present, the code
> enables corresponding ethernet and swtich nodes and DSA connections.
> For the SFP cage the SFP GPIO controller node and SFP node are also
> enabled.
> 
> Signed-off-by: Marek Behún <marek.behun at nic.cz>
> ---

Again, patch revision history  is missing. No need to re-send now, but
please include it next time.

>   board/CZ.NIC/turris_mox/turris_mox.c | 263 +++++++++++++++++++++++++++
>   configs/turris_mox_defconfig         |   1 +
>   2 files changed, 264 insertions(+)
> 
> diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c
> index 0b13d1d190..bc0d067889 100644
> --- a/board/CZ.NIC/turris_mox/turris_mox.c
> +++ b/board/CZ.NIC/turris_mox/turris_mox.c
> @@ -3,6 +3,7 @@
>    * Copyright (C) 2018 Marek Behun <marek.behun at nic.cz>
>    */
>   
> +#include <stdarg.h>

Nitpickung: Please sort include files alpabetically.

>   #include <common.h>
>   #include <init.h>
>   #include <asm/gpio.h>
> @@ -34,7 +35,11 @@
>   #define ARMADA_37XX_SPI_DOUT	0xd0010608
>   #define ARMADA_37XX_SPI_DIN	0xd001060c
>   
> +#define ETH1_PATH	"/soc/internal-regs at d0000000/ethernet at 40000"
> +#define MDIO_PATH	"/soc/internal-regs at d0000000/mdio at 32004"
> +#define SFP_GPIO_PATH	"/soc/internal-regs at d0000000/spi at 10600/moxtet at 1/gpio at 0"
>   #define PCIE_PATH	"/soc/pcie at d0070000"
> +#define SFP_PATH	"/sfp"
>   
>   DECLARE_GLOBAL_DATA_PTR;
>   
> @@ -551,3 +556,261 @@ int last_stage_init(void)
>   
>   	return 0;
>   }
> +
> +#if defined(CONFIG_OF_BOARD_SETUP)
> +
> +static int vnode_by_path(void *blob, const char *fmt, va_list ap)
> +{
> +	char path[128];
> +
> +	vsprintf(path, fmt, ap);

vsnprintf ?

> +	return fdt_path_offset(blob, path);
> +}
> +
> +static int node_by_path(void *blob, const char *fmt, ...)
> +{
> +	va_list ap;
> +	int res;
> +
> +	va_start(ap, fmt);
> +	res = vnode_by_path(blob, fmt, ap);
> +	va_end(ap);
> +
> +	return res;
> +}
> +
> +static int phandle_by_path(void *blob, const char *fmt, ...)
> +{
> +	va_list ap;
> +	int node, phandle, res;
> +
> +	va_start(ap, fmt);
> +	node = vnode_by_path(blob, fmt, ap);
> +	va_end(ap);
> +
> +	if (node < 0)
> +		return node;
> +
> +	phandle = fdt_get_phandle(blob, node);
> +	if (phandle > 0)
> +		return phandle;
> +
> +	phandle = fdt_get_max_phandle(blob);
> +	if (phandle < 0)
> +		return phandle;
> +
> +	phandle += 1;
> +
> +	res = fdt_setprop_u32(blob, node, "linux,phandle", phandle);
> +	if (res < 0)
> +		return res;
> +
> +	res = fdt_setprop_u32(blob, node, "phandle", phandle);
> +	if (res < 0)
> +		return res;
> +
> +	return phandle;
> +}
> +
> +static int enable_by_path(void *blob, const char *fmt, ...)
> +{
> +	va_list ap;
> +	int node;
> +
> +	va_start(ap, fmt);
> +	node = vnode_by_path(blob, fmt, ap);
> +	va_end(ap);
> +
> +	if (node < 0)
> +		return node;
> +
> +	return fdt_setprop_string(blob, node, "status", "okay");
> +}
> +
> +static bool is_topaz(int id)
> +{
> +	return topaz && id == peridot + topaz - 1;
> +}
> +
> +static int switch_addr(int id)
> +{
> +	return is_topaz(id) ? 0x2 : 0x10 + id;
> +}
> +
> +static int setup_switch(void *blob, int id)
> +{
> +	int res, addr, i, node, phandle;
> +
> +	addr = switch_addr(id);
> +
> +	/* first enable the switch by setting status = "okay" */
> +	res = enable_by_path(blob, MDIO_PATH "/switch%i@%x", id, addr);
> +	if (res < 0)
> +		return res;
> +
> +	/*
> +	 * now if there are more switches or a SFP module coming after,
> +	 * enable corresponding ports
> +	 */
> +	if (id < peridot + topaz - 1)
> +		res = enable_by_path(blob,
> +				     MDIO_PATH "/switch%i@%x/ports/port at a",
> +				     id, addr);
> +	else if (id == peridot - 1 && !topaz && sfp)
> +		res = enable_by_path(blob,
> +				     MDIO_PATH "/switch%i@%x/ports/port-sfp at a",
> +				     id, addr);
> +	else
> +		res = 0;

Please use paranthesis on multi-line statements.

> +	if (res < 0)
> +		return res;
> +
> +	if (id >= peridot + topaz - 1)
> +		return 0;
> +
> +	/* finally change link property if needed */
> +	node = node_by_path(blob, MDIO_PATH "/switch%i@%x/ports/port at a", id,
> +			    addr);
> +	if (node < 0)
> +		return node;
> +
> +	for (i = id + 1; i < peridot + topaz; ++i) {
> +		phandle = phandle_by_path(blob,
> +					  MDIO_PATH "/switch%i@%x/ports/port@%x",
> +					  i, switch_addr(i),
> +					  is_topaz(i) ? 5 : 9);
> +		if (phandle < 0)
> +			return phandle;
> +
> +		if (i == id + 1)
> +			res = fdt_setprop_u32(blob, node, "link", phandle);
> +		else
> +			res = fdt_appendprop_u32(blob, node, "link", phandle);
> +		if (res < 0)
> +			return res;
> +	}
> +
> +	return 0;
> +}
> +
> +static int remove_disabled_nodes(void *blob)
> +{
> +	while (1) {
> +		int res, offset;
> +
> +		offset = fdt_node_offset_by_prop_value(blob, -1, "status",
> +						       "disabled", 9);
> +		if (offset < 0)
> +			break;
> +
> +		res = fdt_del_node(blob, offset);
> +		if (res < 0)
> +			return res;
> +	}
> +
> +	return 0;
> +}
> +
> +int ft_board_setup(void *blob, bd_t *bd)
> +{
> +	int node, phandle, res;
> +
> +	/*
> +	 * If MOX B (PCI), MOX F (USB) or MOX G (Passthrough PCI) modules are
> +	 * connected, enable the PCIe node.
> +	 */
> +	if (pci || usb || passpci) {
> +		node = fdt_path_offset(blob, PCIE_PATH);
> +		if (node < 0)
> +			return node;
> +
> +		res = fdt_setprop_string(blob, node, "status", "okay");
> +		if (res < 0)
> +			return res;
> +	}
> +
> +	/*
> +	 * If MOX C (Topaz switch) and/or MOX E (Peridot switch) are connected,
> +	 * enable the eth1 node and setup the switches.
> +	 */
> +	if (peridot || topaz) {
> +		int i;
> +
> +		res = enable_by_path(blob, ETH1_PATH);
> +		if (res < 0)
> +			return res;
> +
> +		for (i = 0; i < peridot + topaz; ++i) {
> +			res = setup_switch(blob, i);
> +			if (res < 0)
> +				return res;
> +		}
> +	}
> +
> +	/*
> +	 * If MOX D (SFP cage module) is connected, enable the SFP node and eth1
> +	 * node. If there is no Peridot switch between MOX A and MOX D, add link
> +	 * to the SFP node to eth1 node.
> +	 * Also enable and configure SFP GPIO controller node.
> +	 */
> +	if (sfp) {
> +		res = enable_by_path(blob, SFP_PATH);
> +		if (res < 0)
> +			return res;
> +
> +		res = enable_by_path(blob, ETH1_PATH);
> +		if (res < 0)
> +			return res;
> +
> +		if (!peridot) {
> +			phandle = phandle_by_path(blob, SFP_PATH);
> +			if (phandle < 0)
> +				return res;
> +
> +			node = node_by_path(blob, ETH1_PATH);
> +			if (node < 0)
> +				return node;
> +
> +			res = fdt_setprop_u32(blob, node, "sfp", phandle);
> +			if (res < 0)
> +				return res;
> +
> +			res = fdt_setprop_string(blob, node, "phy-mode",
> +						 "sgmii");
> +			if (res < 0)
> +				return res;
> +		}
> +
> +		res = enable_by_path(blob, SFP_GPIO_PATH);
> +		if (res < 0)
> +			return res;
> +
> +		if (sfp_pos) {
> +			char newname[16];
> +
> +			/* moxtet-sfp is on non-zero position, change default */
> +			node = node_by_path(blob, SFP_GPIO_PATH);
> +			if (node < 0)
> +				return node;
> +
> +			res = fdt_setprop_u32(blob, node, "reg", sfp_pos);
> +			if (res < 0)
> +				return res;
> +
> +			sprintf(newname, "gpio@%x", sfp_pos);
> +
> +			res = fdt_set_name(blob, node, newname);
> +			if (res < 0)
> +				return res;
> +		}
> +	}
> +
> +	fdt_fixup_ethernet(blob);
> +
> +	/* Finally remove disabled nodes, as per Rob Herring's request. */
> +	remove_disabled_nodes(blob);
> +
> +	return 0;
> +}
> +
> +#endif
> diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig
> index 2e637044c1..3bc69cda4d 100644
> --- a/configs/turris_mox_defconfig
> +++ b/configs/turris_mox_defconfig
> @@ -37,6 +37,7 @@ CONFIG_CMD_BTRFS=y
>   CONFIG_CMD_EXT4_WRITE=y
>   CONFIG_MAC_PARTITION=y
>   CONFIG_OF_BOARD_FIXUP=y
> +CONFIG_OF_BOARD_SETUP=y
>   CONFIG_DEFAULT_DEVICE_TREE="armada-3720-turris-mox"
>   CONFIG_ENV_IS_IN_SPI_FLASH=y
>   CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> 

Other than the above comments:

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

Thanks,
Stefan


More information about the U-Boot mailing list