[U-Boot] [PATCH 0/4] Updates for Turris Mox

Here are some updates for Turris Mox board.
The first patch updates Marvell's comphy driver to call function board_update_comphy_map. The comphy driver contains a weak definition of this function, which does nothing. Board file can then define this function to update the serdes map before comphy lanes are initialized. This is needed because on Turris Mox serdes lane 0 has to be initialized to different speed when Topaz module is connected and when SFP module is connected. This is a temporary solution. Once comphy driver for Armada 3720 is in kernel, the comphy driver in u-boot shall also be rewritten to support changing the speed even after the comphy lane is initialized.
The second patch changes the turris_mox board file to switch SERDES speed according to module topology.
The third patch adds support for differentiating whether the board is with eMMC card or with SD card slot.
The fourth patch adds the gpio command to turris_mox_defconfig.
Signed-off-by: Marek Behun marek.behun@nic.cz

This adds a weak definition of board_update_comphy_map to comphy_core, which does nothing. If this function is defined elsewhere, for example in board file, the board file can change some parameters of SERDES configuration.
This is needed on Turris Mox, where the SERDES speed on lane 1 has to be set differently when SFP module is connected and when Topaz Switch module is connected.
This is a temporary solution. When the comphy driver for armada-3720 will be added to the kernel, the comphy driver in u-boot shall also be updated and this should be done differently then.
Signed-off-by: Marek Behun marek.behun@nic.cz
rename drivers/phy/marvell/{comphy.h => comphy_core.h} (96%) create mode 100644 include/comphy.h
diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h index a14767d809..b0941ffb37 100644 --- a/drivers/phy/marvell/comphy_a3700.h +++ b/drivers/phy/marvell/comphy_a3700.h @@ -6,7 +6,7 @@ #ifndef _COMPHY_A3700_H_ #define _COMPHY_A3700_H_
-#include "comphy.h" +#include "comphy_core.h" #include "comphy_hpipe.h"
#define MVEBU_REG(offs) \ diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c index c6e2cc8897..74b9f11b08 100644 --- a/drivers/phy/marvell/comphy_core.c +++ b/drivers/phy/marvell/comphy_core.c @@ -11,7 +11,7 @@ #include <linux/errno.h> #include <asm/io.h>
-#include "comphy.h" +#include "comphy_core.h"
#define COMPHY_MAX_CHIP 4
@@ -66,6 +66,10 @@ void comphy_print(struct chip_serdes_phy_config *chip_cfg, } }
+__weak void board_update_comphy_map(struct comphy_map *serdes_map, int count) +{ +} + static int comphy_probe(struct udevice *dev) { const void *blob = gd->fdt_blob; @@ -143,6 +147,8 @@ static int comphy_probe(struct udevice *dev) lane++; }
+ board_update_comphy_map(comphy_map_data, chip_cfg->comphy_lanes_count); + /* Save CP index for MultiCP devices (A8K) */ chip_cfg->cp_index = current_idx++; /* PHY power UP sequence */ diff --git a/drivers/phy/marvell/comphy.h b/drivers/phy/marvell/comphy_core.h similarity index 96% rename from drivers/phy/marvell/comphy.h rename to drivers/phy/marvell/comphy_core.h index b588ae41f0..e1da90e75b 100644 --- a/drivers/phy/marvell/comphy.h +++ b/drivers/phy/marvell/comphy_core.h @@ -3,11 +3,11 @@ * Copyright (C) 2015-2016 Marvell International Ltd. */
-#ifndef _COMPHY_H_ -#define _COMPHY_H_ +#ifndef _COMPHY_CORE_H_ +#define _COMPHY_CORE_H_
-#include <dt-bindings/comphy/comphy_data.h> #include <fdtdec.h> +#include <comphy.h>
#if defined(DEBUG) #define debug_enter() printf("----> Enter %s\n", __func__); @@ -80,14 +80,6 @@ struct comphy_mux_data { struct comphy_mux_options mux_values[MAX_LANE_OPTIONS]; };
-struct comphy_map { - u32 type; - u32 speed; - u32 invert; - bool clk_src; - bool end_point; -}; - struct chip_serdes_phy_config { struct comphy_mux_data *mux_data; int (*ptr_comphy_chip_init)(struct chip_serdes_phy_config *, @@ -183,5 +175,5 @@ void comphy_pcie_config_detect(u32 comphy_max_count, struct comphy_map *serdes_map); void comphy_pcie_unit_general_config(u32 pex_index);
-#endif /* _COMPHY_H_ */ +#endif /* _COMPHY_CORE_H_ */
diff --git a/drivers/phy/marvell/comphy_cp110.c b/drivers/phy/marvell/comphy_cp110.c index b0d5d5ca26..6a60da3df0 100644 --- a/drivers/phy/marvell/comphy_cp110.c +++ b/drivers/phy/marvell/comphy_cp110.c @@ -9,7 +9,7 @@ #include <asm/arch/cpu.h> #include <asm/arch/soc.h>
-#include "comphy.h" +#include "comphy_core.h" #include "comphy_hpipe.h" #include "sata.h" #include "utmi_phy.h" diff --git a/drivers/phy/marvell/comphy_mux.c b/drivers/phy/marvell/comphy_mux.c index 1f757d8e04..c67ba99762 100644 --- a/drivers/phy/marvell/comphy_mux.c +++ b/drivers/phy/marvell/comphy_mux.c @@ -6,7 +6,7 @@ #include <common.h> #include <asm/io.h>
-#include "comphy.h" +#include "comphy_core.h" #include "comphy_hpipe.h"
/* diff --git a/include/comphy.h b/include/comphy.h new file mode 100644 index 0000000000..2ebb50d418 --- /dev/null +++ b/include/comphy.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2015-2016 Marvell International Ltd. + */ + +#ifndef _COMPHY_H_ +#define _COMPHY_H_ + +#include <dt-bindings/comphy/comphy_data.h> + +struct comphy_map { + u32 type; + u32 speed; + u32 invert; + bool clk_src; + bool end_point; +}; + +void board_update_comphy_map(struct comphy_map *serdes_map, int count); + +#endif /* _COMPHY_H_ */ +

On 16.05.2018 16:39, Marek Behún wrote:
This adds a weak definition of board_update_comphy_map to comphy_core, which does nothing. If this function is defined elsewhere, for example in board file, the board file can change some parameters of SERDES configuration.
This is needed on Turris Mox, where the SERDES speed on lane 1 has to be set differently when SFP module is connected and when Topaz Switch module is connected.
This is a temporary solution. When the comphy driver for armada-3720 will be added to the kernel, the comphy driver in u-boot shall also be updated and this should be done differently then.
Signed-off-by: Marek Behun marek.behun@nic.cz
rename drivers/phy/marvell/{comphy.h => comphy_core.h} (96%) create mode 100644 include/comphy.h
diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h index a14767d809..b0941ffb37 100644 --- a/drivers/phy/marvell/comphy_a3700.h +++ b/drivers/phy/marvell/comphy_a3700.h @@ -6,7 +6,7 @@ #ifndef _COMPHY_A3700_H_ #define _COMPHY_A3700_H_
-#include "comphy.h" +#include "comphy_core.h" #include "comphy_hpipe.h"
#define MVEBU_REG(offs) \ diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c index c6e2cc8897..74b9f11b08 100644 --- a/drivers/phy/marvell/comphy_core.c +++ b/drivers/phy/marvell/comphy_core.c @@ -11,7 +11,7 @@ #include <linux/errno.h> #include <asm/io.h>
-#include "comphy.h" +#include "comphy_core.h"
#define COMPHY_MAX_CHIP 4
@@ -66,6 +66,10 @@ void comphy_print(struct chip_serdes_phy_config *chip_cfg, } }
+__weak void board_update_comphy_map(struct comphy_map *serdes_map, int count) +{ +}
Perhaps its better to move "comphy_" to the beginning of this function name, like:
comphy_update_map()
What do you think?
static int comphy_probe(struct udevice *dev) { const void *blob = gd->fdt_blob; @@ -143,6 +147,8 @@ static int comphy_probe(struct udevice *dev) lane++; }
- board_update_comphy_map(comphy_map_data, chip_cfg->comphy_lanes_count);
I would prefer to add a return code this this function and bail out here, if something goes wrong.
/* Save CP index for MultiCP devices (A8K) */ chip_cfg->cp_index = current_idx++; /* PHY power UP sequence */ diff --git a/drivers/phy/marvell/comphy.h b/drivers/phy/marvell/comphy_core.h similarity index 96% rename from drivers/phy/marvell/comphy.h rename to drivers/phy/marvell/comphy_core.h index b588ae41f0..e1da90e75b 100644 --- a/drivers/phy/marvell/comphy.h +++ b/drivers/phy/marvell/comphy_core.h @@ -3,11 +3,11 @@
- Copyright (C) 2015-2016 Marvell International Ltd.
*/
-#ifndef _COMPHY_H_ -#define _COMPHY_H_ +#ifndef _COMPHY_CORE_H_ +#define _COMPHY_CORE_H_
-#include <dt-bindings/comphy/comphy_data.h> #include <fdtdec.h> +#include <comphy.h>
#if defined(DEBUG) #define debug_enter() printf("----> Enter %s\n", __func__); @@ -80,14 +80,6 @@ struct comphy_mux_data { struct comphy_mux_options mux_values[MAX_LANE_OPTIONS]; };
-struct comphy_map {
- u32 type;
- u32 speed;
- u32 invert;
- bool clk_src;
- bool end_point;
-};
- struct chip_serdes_phy_config { struct comphy_mux_data *mux_data; int (*ptr_comphy_chip_init)(struct chip_serdes_phy_config *,
@@ -183,5 +175,5 @@ void comphy_pcie_config_detect(u32 comphy_max_count, struct comphy_map *serdes_map); void comphy_pcie_unit_general_config(u32 pex_index);
-#endif /* _COMPHY_H_ */ +#endif /* _COMPHY_CORE_H_ */
diff --git a/drivers/phy/marvell/comphy_cp110.c b/drivers/phy/marvell/comphy_cp110.c index b0d5d5ca26..6a60da3df0 100644 --- a/drivers/phy/marvell/comphy_cp110.c +++ b/drivers/phy/marvell/comphy_cp110.c @@ -9,7 +9,7 @@ #include <asm/arch/cpu.h> #include <asm/arch/soc.h>
-#include "comphy.h" +#include "comphy_core.h" #include "comphy_hpipe.h" #include "sata.h" #include "utmi_phy.h" diff --git a/drivers/phy/marvell/comphy_mux.c b/drivers/phy/marvell/comphy_mux.c index 1f757d8e04..c67ba99762 100644 --- a/drivers/phy/marvell/comphy_mux.c +++ b/drivers/phy/marvell/comphy_mux.c @@ -6,7 +6,7 @@ #include <common.h> #include <asm/io.h>
-#include "comphy.h" +#include "comphy_core.h" #include "comphy_hpipe.h"
/* diff --git a/include/comphy.h b/include/comphy.h new file mode 100644 index 0000000000..2ebb50d418 --- /dev/null +++ b/include/comphy.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2015-2016 Marvell International Ltd.
- */
+#ifndef _COMPHY_H_ +#define _COMPHY_H_
+#include <dt-bindings/comphy/comphy_data.h>
+struct comphy_map {
- u32 type;
- u32 speed;
- u32 invert;
- bool clk_src;
- bool end_point;
+};
+void board_update_comphy_map(struct comphy_map *serdes_map, int count);
+#endif /* _COMPHY_H_ */
I'm not so happy with "polluting" the common "include" directory with board / platform specific files. Please at least make this file name platform specific, like "mvebu_comphy.h". Or add a mvebu subdirectory here.
Thanks, Stefan

When SFP module is present, the SGMII lane speed should be 1.25 Gbps, otherwise SFP won't work. Topaz still needs 3.125 Gbps.
Signed-off-by: Marek Behun marek.behun@nic.cz
diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 130d4c606d..f7fb2c2955 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -8,6 +8,7 @@ #include <clk.h> #include <spi.h> #include <linux/string.h> +#include <comphy.h>
#ifdef CONFIG_WDT_ARMADA_3720 #include <wdt.h> @@ -53,14 +54,20 @@ int board_init(void) return 0; }
-int last_stage_init(void) +static int mox_read_topology(const u8 **ptopology, int *psize) { + static u8 topology[9]; + static int size = 0; struct spi_slave *slave; struct udevice *dev; u8 din[10], dout[10]; int ret, i; - size_t len = 0; - char module_topology[128]; + + if (size) { + *ptopology = topology; + *psize = size; + return 0; + }
ret = spi_get_bus_and_cs(0, 1, 20000000, SPI_CPHA, "spi_generic_drv", "mox-modules@1", &dev, &slave); @@ -78,30 +85,87 @@ int last_stage_init(void) if (ret) goto fail_release;
- if (din[0] != 0x00 && din[0] != 0xff) + if (din[0] != 0x00 && din[0] != 0xff) { + ret = -ENODEV; goto fail_release; + } + + for (i = 1; i < 10 && din[i] != 0xff; ++i) + topology[i-1] = din[i] & 0xf; + size = i-1; + + *ptopology = topology; + *psize = size; + +fail_release: + spi_release_bus(slave); +fail_free: + spi_free_slave(slave); +fail: + return ret; +} + +void board_update_comphy_map(struct comphy_map *serdes_map, int count) +{ + int ret, i, size, has = 0; + const u8 *topology; + + ret = mox_read_topology(&topology, &size); + if (ret) + return; + + for (i = 0; i < size; ++i) { + if (has && (topology[i] == 0x1 || topology[i] == 0x3)) { + printf("Warning: two or more incompatible Mox modules " + "found, using only first!\n"); + break; + } else if (topology[i] == 0x1) { + printf("SFP module found, changing SERDES lane 0 speed" + " to 1.25 Gbps\n"); + serdes_map[0].speed = PHY_SPEED_1_25G; + has = topology[i]; + } else if (topology[i] == 0x3) { + printf("Topaz Switch module found, changing SERDES lane" + " 0 speed to 3.125 Gbps\n"); + serdes_map[0].speed = PHY_SPEED_3_125G; + has = topology[i]; + } + } +} + +int last_stage_init(void) +{ + int ret, i, size; + size_t len = 0; + const u8 *topology; + char module_topology[128]; + + ret = mox_read_topology(&topology, &size); + if (ret) { + printf("Cannot read module topology!\n"); + return 0; + }
printf("Module Topology:\n"); - for (i = 1; i < 10 && din[i] != 0xff; ++i) { - u8 mid = din[i] & 0xf; + for (i = 0; i < size; ++i) { size_t mlen; const char *mname = "";
- switch (mid) { + switch (topology[i]) { case 0x1: mname = "sfp-"; - printf("% 4i: SFP Module\n", i); + printf("% 4i: SFP Module\n", i+1); break; case 0x2: mname = "pci-"; - printf("% 4i: Mini-PCIe Module\n", i); + printf("% 4i: Mini-PCIe Module\n", i+1); break; case 0x3: mname = "topaz-"; - printf("% 4i: Topaz Switch Module\n", i); + printf("% 4i: Topaz Switch Module\n", i+1); break; default: - printf("% 4i: unknown (ID %i)\n", i, mid); + printf("% 4i: unknown (ID %i)\n", i+1, topology[i]); }
mlen = strlen(mname); @@ -116,12 +180,5 @@ int last_stage_init(void)
env_set("module_topology", module_topology);
-fail_release: - spi_release_bus(slave); -fail_free: - spi_free_slave(slave); -fail: - if (ret) - printf("Cannot read module topology!\n"); - return ret; + return 0; }

The first byte of the string read from SPI bus from which Mox module toplogy is detected contains ID of the CPU module. This ID can differentiate between the version with SD card slot and the one with eMMC card.
Signed-off-by: Marek Behun marek.behun@nic.cz
diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index f7fb2c2955..c8ead5d67b 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -54,8 +54,16 @@ int board_init(void) return 0; }
-static int mox_read_topology(const u8 **ptopology, int *psize) +typedef enum { + MOX_UNKNOWN, + MOX_EMMC, + MOX_SD +} mox_version_t; + +static int mox_read_topology(const u8 **ptopology, int *psize, + mox_version_t *pversion) { + static mox_version_t mox_version; static u8 topology[9]; static int size = 0; struct spi_slave *slave; @@ -64,8 +72,12 @@ static int mox_read_topology(const u8 **ptopology, int *psize) int ret, i;
if (size) { - *ptopology = topology; - *psize = size; + if (ptopology) + *ptopology = topology; + if (psize) + *psize = size; + if (pversion) + *pversion = mox_version; return 0; }
@@ -85,7 +97,17 @@ static int mox_read_topology(const u8 **ptopology, int *psize) if (ret) goto fail_release;
- if (din[0] != 0x00 && din[0] != 0xff) { + switch (din[0]) { + case 0x00: + mox_version = MOX_EMMC; + break; + case 0x10: + mox_version = MOX_SD; + break; + case 0xff: + mox_version = MOX_UNKNOWN; + break; + default: ret = -ENODEV; goto fail_release; } @@ -94,8 +116,12 @@ static int mox_read_topology(const u8 **ptopology, int *psize) topology[i-1] = din[i] & 0xf; size = i-1;
- *ptopology = topology; - *psize = size; + if (ptopology) + *ptopology = topology; + if (psize) + *psize = size; + if (pversion) + *pversion = mox_version;
fail_release: spi_release_bus(slave); @@ -110,7 +136,7 @@ void board_update_comphy_map(struct comphy_map *serdes_map, int count) int ret, i, size, has = 0; const u8 *topology;
- ret = mox_read_topology(&topology, &size); + ret = mox_read_topology(&topology, &size, NULL); if (ret) return;
@@ -139,13 +165,17 @@ int last_stage_init(void) size_t len = 0; const u8 *topology; char module_topology[128]; + mox_version_t version;
- ret = mox_read_topology(&topology, &size); + ret = mox_read_topology(&topology, &size, &version); if (ret) { printf("Cannot read module topology!\n"); return 0; }
+ printf("Found Turris Mox %s version\n", version == MOX_SD ? "SD" : + version == MOX_EMMC ? "eMMC" : + "unknown"); printf("Module Topology:\n"); for (i = 0; i < size; ++i) { size_t mlen; @@ -179,6 +209,8 @@ int last_stage_init(void) module_topology[len > 0 ? len - 1 : 0] = '\0';
env_set("module_topology", module_topology); + env_set("mox_version", version == MOX_SD ? "sd" : + version == MOX_EMMC ? "emmc" : "");
return 0; }

This can be used to detect whether the button is pressed or light the LED diode.
Signed-off-by: Marek Behun marek.behun@nic.cz
diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig index 7dea7157dc..9538903bd3 100644 --- a/configs/turris_mox_defconfig +++ b/configs/turris_mox_defconfig @@ -13,6 +13,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_ARCH_EARLY_INIT_R=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_CLK=y +CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_SF=y

On Wed, May 16, 2018 at 04:39:42PM +0200, Marek Behún wrote:
This can be used to detect whether the button is pressed or light the LED diode.
Well, I know it is annoying, but as patch is oneliner anyway, let's get at least commit log right.
LED stands for Light-Emitting Diode, so Light-Emitting Diode diode does not look very nice.
(Yes, I know "LED dióda" is commonly used idiom, but this does not make it any more right)
Thanks, ladis
Signed-off-by: Marek Behun marek.behun@nic.cz
diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig index 7dea7157dc..9538903bd3 100644 --- a/configs/turris_mox_defconfig +++ b/configs/turris_mox_defconfig @@ -13,6 +13,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_ARCH_EARLY_INIT_R=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_CLK=y +CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_SF=y -- 2.16.1
U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
participants (3)
-
Ladislav Michl
-
Marek Behún
-
Stefan Roese