mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries
@ 2024-06-22 17:48 Oleksij Rempel
  2024-06-22 17:48 ` [PATCH v2 2/2] ARM: at91: microchip-sama5d3-eds: implement MDIO and SPI extension boards detection Oleksij Rempel
  2024-07-01 12:44 ` (subset) [PATCH v2 1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries Sascha Hauer
  0 siblings, 2 replies; 4+ messages in thread
From: Oleksij Rempel @ 2024-06-22 17:48 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

Current implementation of GPIO-based chip select configuration in this
driver only considers the first valid GPIO and ignores
subsequent entries. This patch ensures that all valid GPIO entries are
processed correctly, enabling configurations with multiple valid and
invalid entries.

Specifically, this change addresses the issue where configurations like
`cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioC 28 0>;` are not handled
correctly, leading to the last valid GPIO being ignored.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/spi/atmel_spi.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 90f655dc3e..4adad241b4 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -414,11 +414,7 @@ static int atmel_spi_probe(struct device *dev)
 		for (i = 0; i < master->num_chipselect; i++) {
 			as->cs_pins[i] = of_get_named_gpio(node, "cs-gpios", i);
 
-			if (!gpio_is_valid(as->cs_pins[i]))
-			    break;
 		}
-
-		master->num_chipselect = i;
 	}
 
 	as->clk = clk_get(dev, "spi_clk");
@@ -438,9 +434,10 @@ static int atmel_spi_probe(struct device *dev)
 	atmel_get_caps(as);
 
 	for (i = 0; i < master->num_chipselect; i++) {
-		ret = gpio_request(as->cs_pins[i], dev_name(dev));
-		if (ret)
-			goto out_gpio;
+		if (gpio_is_valid(as->cs_pins[i]))
+			ret = gpio_request(as->cs_pins[i], dev_name(dev));
+			if (ret)
+				goto out_gpio;
 	}
 
 	/* Initialize the hardware */
-- 
2.39.2




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] ARM: at91: microchip-sama5d3-eds: implement MDIO and SPI extension boards detection
  2024-06-22 17:48 [PATCH v2 1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries Oleksij Rempel
@ 2024-06-22 17:48 ` Oleksij Rempel
  2024-07-01 12:43   ` Sascha Hauer
  2024-07-01 12:44 ` (subset) [PATCH v2 1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries Sascha Hauer
  1 sibling, 1 reply; 4+ messages in thread
From: Oleksij Rempel @ 2024-06-22 17:48 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

Detect extension boards managed over MDIO or SPI buses. For now following
extension boards are supported:
- EVB-VSC8541-EDS
- EVB-LAN8841
- EVB-LAN9370-LC

If supported board is detected, the board code will apply devicetree
overlay on the barebox and fixup kernel DT too.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 .../arm/boards/microchip-sama5d3-eds/Makefile |   1 +
 arch/arm/boards/microchip-sama5d3-eds/board.c | 414 ++++++++++++++++++
 arch/arm/dts/Makefile                         |   3 +
 arch/arm/dts/at91-microchip-sama5d3-eds.dts   |  29 ++
 arch/arm/dts/sama5d3_eds_lan9370.dtso         |  77 ++++
 arch/arm/dts/sama5d3_eds_rgmii_phy.dtso       |  52 +++
 arch/arm/mach-at91/Kconfig                    |   1 +
 7 files changed, 577 insertions(+)
 create mode 100644 arch/arm/boards/microchip-sama5d3-eds/board.c
 create mode 100644 arch/arm/dts/sama5d3_eds_lan9370.dtso
 create mode 100644 arch/arm/dts/sama5d3_eds_rgmii_phy.dtso

diff --git a/arch/arm/boards/microchip-sama5d3-eds/Makefile b/arch/arm/boards/microchip-sama5d3-eds/Makefile
index 458f520900..da63d2625f 100644
--- a/arch/arm/boards/microchip-sama5d3-eds/Makefile
+++ b/arch/arm/boards/microchip-sama5d3-eds/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
+obj-y += board.o
 lwl-y += lowlevel.o
diff --git a/arch/arm/boards/microchip-sama5d3-eds/board.c b/arch/arm/boards/microchip-sama5d3-eds/board.c
new file mode 100644
index 0000000000..f14071efcd
--- /dev/null
+++ b/arch/arm/boards/microchip-sama5d3-eds/board.c
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2024 Oleksij Rempel <o.rempel@pengutronix.de>
+
+#include <common.h>
+#include <deep-probe.h>
+#include <envfs.h>
+#include <environment.h>
+#include <gpio.h>
+#include <init.h>
+#include <linux/phy.h>
+#include <spi/spi.h>
+
+#define BASE_BOARD_NAME_SIZE 100
+static char base_board_name[BASE_BOARD_NAME_SIZE] = "MCP_S5D3_EDS";
+
+extern char __dtbo_sama5d3_eds_rgmii_phy_start[];
+extern char __dtbo_sama5d3_eds_lan9370_start[];
+
+#define MCP_S5D3_EDS_MDIO_EXT_BOARD_FLAG_IGNGORE	BIT(0)
+
+struct mcp_s5d3_eds_mdio_ext_board {
+	int mdio_bus_idx;
+	int phy_addr;
+	int phy_id1;
+	int phy_id2;
+	char board_name[32];
+	char board_abbreviation[8];
+	const void *overlay;
+	u32 flags;
+};
+
+static const struct
+mcp_s5d3_eds_mdio_ext_board mcp_s5d3_eds_mdio_ext_boards[] = {
+	{
+		.mdio_bus_idx = 0,
+		.phy_addr = 3,
+		.phy_id1 = 0x0007,
+		.phy_id2 = 0x0772,
+		.board_name = "EVB-VSC8541-EDS",
+		.board_abbreviation = "VSC8541",
+		.overlay = __dtbo_sama5d3_eds_rgmii_phy_start,
+	},
+	{
+		.mdio_bus_idx = 0,
+		.phy_addr = 3,
+		.phy_id1 = 0x0022,
+		.phy_id2 = 0x1652,
+		.board_name = "EVB-LAN8841",
+		.board_abbreviation = "LAN8841",
+		.overlay = __dtbo_sama5d3_eds_rgmii_phy_start,
+	},
+	{
+		.mdio_bus_idx = 1,
+		.phy_addr = 1,
+		.phy_id1 = 0x0007,
+		.phy_id2 = 0xc1d1,
+		/* Manly EVB-LAN9370-LC is managed over SPI. Ignore MDIO
+		 * interface
+		 */
+		.flags = MCP_S5D3_EDS_MDIO_EXT_BOARD_FLAG_IGNGORE,
+	},
+};
+
+struct mcp_s5d3_eds_spi_scan {
+	int spi_bus_idx;
+	int spi_chip_select;
+};
+
+static const struct mcp_s5d3_eds_spi_scan mcp_s5d3_eds_spi_scans[] = {
+	{
+		.spi_bus_idx = 1,
+		.spi_chip_select = 0,
+	},
+	{
+		.spi_bus_idx = 1,
+		.spi_chip_select = 3,
+	},
+	{
+		.spi_bus_idx = 0,
+		.spi_chip_select = 0,
+	},
+	{
+		.spi_bus_idx = 0,
+		.spi_chip_select = 3,
+	},
+};
+
+struct mcp_s5d3_eds_spi_ext_board {
+	int spi_bus_idx;
+	int spi_chip_select;
+	u8 expected_response[4];
+	char board_name[32];
+	char board_abbreviation[8];
+	const void *overlay;
+};
+
+static const struct mcp_s5d3_eds_spi_ext_board mcp_s5d3_eds_spi_ext_boards[] = {
+	{
+		.spi_bus_idx = 1,
+		.spi_chip_select = 3,
+		.expected_response = { 0x00, 0x93, 0x70, 0x10 },
+		.board_name = "EVB-LAN9370-LC",
+		.board_abbreviation = "LAN9370",
+		.overlay = __dtbo_sama5d3_eds_lan9370_start,
+	},
+};
+
+static void mcp_s5d3_eds_append_board_name_part(const char *part)
+{
+	if (base_board_name[0] != '\0')
+		strncat(base_board_name, "-",
+			BASE_BOARD_NAME_SIZE - strlen(base_board_name) - 1);
+
+	strncat(base_board_name, part,
+		BASE_BOARD_NAME_SIZE - strlen(base_board_name) - 1);
+}
+
+static void mcp_s5d3_eds_apply_overlay(struct device *dev,
+				       const void *raw_overlay)
+{
+	struct device_node *overlay;
+	int ret;
+
+	overlay = of_unflatten_dtb(raw_overlay, INT_MAX);
+	ret = of_overlay_apply_tree(dev->of_node, overlay);
+	if (ret)
+		dev_warn(dev, "Failed to apply overlay: %pe\n", ERR_PTR(ret));
+
+	ret = of_register_overlay(overlay);
+	if (ret)
+		dev_warn(dev, "Failed to register overlay: %pe\n",
+			 ERR_PTR(ret));
+
+}
+
+static int mcp_s5d3_eds_spi_find_ksz_switch(struct device *dev, int bus_idx,
+					    int chip_select, u8 *response,
+					    size_t response_size)
+{
+	struct device_node *spi_node;
+	struct spi_device spi = {
+		.max_speed_hz = 1 * 1000 * 1000,  /* 1 MHz */
+		.bits_per_word = 8,
+		.chip_select = chip_select,
+	};
+	/* read command for ksz switch */
+	u8 tx_buf[4] = {0x60, 0x00, 0x00, 0x00};
+	u8 rx_buf[4] = {0};
+	int ret, i;
+	bool all_zeros = true, all_ones = true;
+	char spi_alias[] = "spiX";
+
+	snprintf(spi_alias, sizeof(spi_alias), "spi%d", bus_idx);
+
+	spi_node = of_find_node_by_alias(NULL, spi_alias);
+	if (!spi_node)
+		return -ENODEV;
+
+	of_device_ensure_probed(spi_node);
+
+	spi.controller = spi_get_controller(bus_idx);
+	spi.master = spi.controller;
+
+	if (!spi.controller) {
+		dev_err(dev, "SPI bus %d not found\n", bus_idx);
+		return -ENODEV;
+	}
+
+	ret = spi.controller->setup(&spi);
+	if (ret) {
+		dev_err(dev, "Cannot setup SPI controller %d (%d)\n", bus_idx,
+			ret);
+		return ret;
+	}
+
+	ret = spi_write_then_read(&spi, tx_buf, sizeof(tx_buf), rx_buf,
+				  sizeof(rx_buf));
+	if (ret) {
+		dev_err(dev, "Failed to communicate with SPI device on bus %d chip select %d\n",
+			bus_idx, chip_select);
+		return ret;
+	}
+
+	for (i = 0; i < sizeof(rx_buf); i++) {
+		if (rx_buf[i] != 0x00) {
+			all_zeros = false;
+		}
+		if (rx_buf[i] != 0xFF) {
+			all_ones = false;
+		}
+	}
+
+	if (all_zeros || all_ones)
+		return 0;
+
+	if (response_size < sizeof(rx_buf)) {
+		dev_err(dev, "Response storage is too small\n");
+		return -EINVAL;
+	}
+
+	memcpy(response, rx_buf, sizeof(rx_buf));
+
+	return 1;
+}
+
+static bool mcp_s5d3_eds_spi_check_and_apply_board(struct device *dev,
+						   int bus_idx, int chip_select,
+						   u8 *response)
+{
+	const struct mcp_s5d3_eds_spi_ext_board *detected_board = NULL;
+	bool switch_detected = false;
+
+	for (int i = 0; i < ARRAY_SIZE(mcp_s5d3_eds_spi_ext_boards); i++) {
+		const struct mcp_s5d3_eds_spi_ext_board *board =
+			&mcp_s5d3_eds_spi_ext_boards[i];
+
+		if (board->spi_bus_idx == bus_idx &&
+		    board->spi_chip_select == chip_select &&
+		    memcmp(response, board->expected_response,
+			   sizeof(board->expected_response)) == 0) {
+
+			switch_detected = true;
+			detected_board = board;
+			break;
+		}
+	}
+
+	if (!switch_detected)
+		return false;
+	
+	dev_info(dev, "Found SPI managed extension board: %s\n",
+		 detected_board->board_name);
+
+	mcp_s5d3_eds_append_board_name_part(detected_board->board_abbreviation);
+
+	if (detected_board->overlay)
+		mcp_s5d3_eds_apply_overlay(dev, detected_board->overlay);
+
+	return true;
+}
+
+static void mcp_s5d3_eds_scan_spi_buses(struct device *dev)
+{
+	u8 response[4];
+	int ret, i;
+
+	for (i = 0; i < (ARRAY_SIZE(mcp_s5d3_eds_spi_scans)); i++) {
+		const struct mcp_s5d3_eds_spi_scan *scan =
+			&mcp_s5d3_eds_spi_scans[i];
+		bool found = false;
+
+		ret = mcp_s5d3_eds_spi_find_ksz_switch(dev, scan->spi_bus_idx,
+						       scan->spi_chip_select,
+						       response,
+						       sizeof(response));
+		if (ret <= 0)
+			continue;
+	
+		found = mcp_s5d3_eds_spi_check_and_apply_board(dev,
+							scan->spi_bus_idx,
+							scan->spi_chip_select,
+							response);
+		if (!found)
+			dev_warn(dev, "No match for SPI device on bus %d chip select %d, response: %02x %02x %02x %02x\n",
+				 scan->spi_bus_idx, scan->spi_chip_select,
+				 response[0], response[1], response[2],
+				 response[3]);
+	}
+}
+
+static int mcp_s5d3_eds_mdio_find_first_dev(struct mii_bus *bus, int *phy_addr,
+					    int *phy_id1, int *phy_id2)
+{
+	int i, reg2, reg3;
+
+	for (i = 0; i < PHY_MAX_ADDR; i++) {
+		reg2 = mdiobus_read(bus, i, MII_PHYSID1);
+		if (reg2 < 0)
+			return reg2;
+
+		if (reg2 == 0xffff || reg2 == 0x0)
+			continue;
+
+		reg3 = mdiobus_read(bus, i, MII_PHYSID2);
+		if (reg3 < 0)
+			return reg3;
+
+		*phy_addr = i;
+		*phy_id1 = reg2;
+		*phy_id2 = reg3;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static bool mcp_s5d3_eds_mdio_check_and_apply_board(struct device *dev,
+						    int board_idx,
+						    int mdio_bus_idx,
+						    int phy_addr, int phy_id1,
+						    int phy_id2)
+{
+	const struct mcp_s5d3_eds_mdio_ext_board *board =
+		&mcp_s5d3_eds_mdio_ext_boards[board_idx];
+
+	if (board->mdio_bus_idx != mdio_bus_idx ||
+	    board->phy_addr != phy_addr || board->phy_id1 != phy_id1 ||
+	    board->phy_id2 != phy_id2)
+		return false;
+
+	if (board->flags & MCP_S5D3_EDS_MDIO_EXT_BOARD_FLAG_IGNGORE)
+		return true;
+
+	dev_info(dev, "Found MDIO managed extension board: %s\n",
+		 board->board_name);
+
+	mcp_s5d3_eds_append_board_name_part(board->board_abbreviation);
+
+	if (board->overlay)
+		mcp_s5d3_eds_apply_overlay(dev, board->overlay);
+
+	return true;
+}
+
+static int mcp_s5d3_eds_scan_mdio_bus(struct device *dev,
+				      int mdio_bus_idx)
+{
+	struct device_node *eth_node, *mdio_node;
+	int phy_addr, phy_id1, phy_id2;
+	char eth_alias[] = "ethernetX";
+	char mdio_alias[] = "mdioX";
+	struct mii_bus *mdio_bus;
+	bool found = false;
+	int ret;
+
+	snprintf(eth_alias, sizeof(eth_alias), "ethernet%d", mdio_bus_idx);
+	snprintf(mdio_alias, sizeof(mdio_alias), "mdio%d", mdio_bus_idx);
+
+	eth_node = of_find_node_by_alias(NULL, eth_alias);
+	if (!eth_node)
+		return -ENODEV;
+
+	of_device_ensure_probed(eth_node);
+
+	mdio_node = of_find_node_by_alias(NULL, mdio_alias);
+	if (!mdio_node)
+		return -ENODEV;
+
+	of_device_ensure_probed(mdio_node);
+
+	mdio_bus = of_mdio_find_bus(mdio_node);
+	if (!mdio_bus)
+		return -ENODEV;
+
+	ret = mcp_s5d3_eds_mdio_find_first_dev(mdio_bus, &phy_addr, &phy_id1,
+					       &phy_id2);
+	if (ret < 0)
+		return ret;
+	else if (!ret)
+		return 0;
+
+	for (int i = 0; i < ARRAY_SIZE(mcp_s5d3_eds_mdio_ext_boards); i++) {
+		found = mcp_s5d3_eds_mdio_check_and_apply_board(dev, i,
+								mdio_bus_idx,
+								phy_addr,
+								phy_id1,
+								phy_id2);
+
+		if (found)
+			break;
+	}
+
+	if (!found)
+		dev_warn(dev, "No match for MDIO device at bus %d, address %d: %04x:%04x\n",
+			 mdio_bus_idx, phy_addr, phy_id1, phy_id2);
+
+	return 0;
+}
+
+static void mcp_s5d3_eds_scan_mdio_buses(struct device *dev)
+{
+	int ret, i;
+
+	for (i = 0; i < 2; i++) {
+		ret = mcp_s5d3_eds_scan_mdio_bus(dev, i);
+		if (ret)
+			dev_warn(dev, "Failed to scan mdio%d bus: %pe\n", i,
+				 ERR_PTR(ret));
+	}
+}
+
+static int mcp_s5d3_eds_probe(struct device *dev)
+{
+	mcp_s5d3_eds_scan_mdio_buses(dev);
+	mcp_s5d3_eds_scan_spi_buses(dev);
+
+	barebox_set_model(base_board_name);
+
+	return 0;
+}
+
+static const struct of_device_id mcp_s5d3_eds_of_match[] = {
+	{ .compatible = "microchip,sama5d3-eds"},
+	{ /* sentinel */ },
+};
+BAREBOX_DEEP_PROBE_ENABLE(mcp_s5d3_eds_of_match);
+
+static struct driver mcp_s5d3_eds_board_driver = {
+	.name = "board-microchip-sama5d3-eds",
+	.probe = mcp_s5d3_eds_probe,
+	.of_compatible = DRV_OF_COMPAT(mcp_s5d3_eds_of_match),
+};
+device_platform_driver(mcp_s5d3_eds_board_driver);
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 68585e1e4b..1302a059bb 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -230,6 +230,9 @@ lwl-$(CONFIG_MACH_VARISCITE_DT8MCUSTOMBOARD_IMX8MP) += imx8mp-var-dart-dt8mcusto
 lwl-$(CONFIG_MACH_TQMA93XX) += imx93-tqma9352-mba93xxca.dtb.o \
 			       imx93-tqma9352-mba93xxla.dtb.o
 
+obj-$(CONFIG_MACH_MICROCHIP_SAMA5D3_EDS) += sama5d3_eds_rgmii_phy.dtbo.o
+obj-$(CONFIG_MACH_MICROCHIP_SAMA5D3_EDS) += sama5d3_eds_lan9370.dtbo.o
+
 obj-$(CONFIG_MACH_WOLFVISION_PF5) += rk3568-wolfvision-pf5-io-expander.dtbo.o
 
 clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts *.dtb.z
diff --git a/arch/arm/dts/at91-microchip-sama5d3-eds.dts b/arch/arm/dts/at91-microchip-sama5d3-eds.dts
index d35c8c3c6e..250e64d7a1 100644
--- a/arch/arm/dts/at91-microchip-sama5d3-eds.dts
+++ b/arch/arm/dts/at91-microchip-sama5d3-eds.dts
@@ -11,4 +11,33 @@ environment {
 			file-path = "barebox.env";
 		};
 	};
+
+	aliases {
+		ethernet0 = &macb0;
+		ethernet1 = &macb1;
+		mdio0 = &mdio0;
+		mdio1 = &mdio1;
+		spi0 = &spi0;
+		spi1 = &spi1;
+	};
+};
+
+&macb0 {
+	phy-mode = "rgmii-id";
+	status = "okay";
+
+	mdio0: mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+};
+
+&macb1 {
+	phy-mode = "rmii";
+	status = "okay";
+
+	mdio1: mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
 };
diff --git a/arch/arm/dts/sama5d3_eds_lan9370.dtso b/arch/arm/dts/sama5d3_eds_lan9370.dtso
new file mode 100644
index 0000000000..eb45ec27d1
--- /dev/null
+++ b/arch/arm/dts/sama5d3_eds_lan9370.dtso
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for SAMA5D3 EDS board
+ * overlay blob for the LAN9370 RMII add-on board.
+ *
+ * Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Jerry Ray <jerry.ray@microchip.com>
+ *
+ * 5-Port 100BASE-T1 Gigabit Ethernet Switch
+ * https://www.microchip.com/en-us/development-tool/EV64C55A
+ *
+ */
+/dts-v1/;
+/plugin/;
+
+#include "dt-bindings/interrupt-controller/irq.h"
+#include "dt-bindings/pinctrl/at91.h"
+
+&macb1 {
+	phy-mode = "rmii";
+	status = "okay";
+
+	fixed-link {
+		speed = <100>;
+		full-duplex;
+	};
+};
+
+&spi1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	lan9370: lan9370@3 {
+		compatible = "microchip,lan9370";
+		reg = <3>;
+		spi-max-frequency = <44000000>;
+		interrupt-parent = <&pioB>;
+		interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-0 = <&pinctrl_spi_irqn>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0x0>;
+				phy-mode = "internal";
+				label = "lan1";
+			};
+			port@1 {
+				reg = <0x1>;
+				phy-mode = "internal";
+				label = "lan2";
+			};
+			port@2 {
+				reg = <0x2>;
+				phy-mode = "internal";
+				label = "lan3";
+			};
+			port@3 {
+				reg = <0x3>;
+				phy-mode = "internal";
+				label = "lan4";
+			};
+			port@4 {
+				reg = <4>;
+				phy-mode = "rmii";
+				ethernet = <&macb1>;
+				fixed-link {
+					speed = <100>;
+					full-duplex;
+				};
+			};
+		};
+	};
+};
diff --git a/arch/arm/dts/sama5d3_eds_rgmii_phy.dtso b/arch/arm/dts/sama5d3_eds_rgmii_phy.dtso
new file mode 100644
index 0000000000..5d7e1ee54c
--- /dev/null
+++ b/arch/arm/dts/sama5d3_eds_rgmii_phy.dtso
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree file for SAMA5D3 EDS board
+ *
+ * Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Jerry Ray <jerry.ray@microchip.com>
+ *
+ * Supported extension boards:
+ * - EVB-LAN8841 - https://www.microchip.com/en-us/development-tool/EV19G28A
+ *   Note: Depopulate R43 (remove RXER signal) to allow this board to
+ *         function properly with the SAMA5D3-EDS.
+ * - EVB-VSC8541-EDS - https://www.microchip.com/en-us/development-tool/EV35M06A
+ */
+/dts-v1/;
+/plugin/;
+
+#include "dt-bindings/gpio/gpio.h"
+#include "dt-bindings/interrupt-controller/irq.h"
+#include "dt-bindings/pinctrl/at91.h"
+
+&macb0 {
+	phy-mode = "rgmii-id";
+	phy-handle = <&rgmii_phy>;
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		rgmii_phy: ethernet-phy@3 {
+			reg = <0x3>;
+			pinctrl-0 = <&pinctrl_rgmii_rstn>;
+			pinctrl-1 = <&pinctrl_spi_irqn>;
+			interrupt-parent = <&pioB>;
+			interrupts = <28 IRQ_TYPE_EDGE_FALLING>;
+			resetb-gpios = <&pioD 18 GPIO_ACTIVE_LOW>;
+			/* LAN8841 - 1us */
+			/* VSC8541 - 100ns */
+			/* take one 1ms to be safe */
+			reset-assert-us = <1000>;
+			/* LAN8841 - 10ms? */
+			/* VSC8541- 15ms */
+			reset-deassert-us = <15000>;
+			status = "okay";
+		};
+	};
+};
+
+&usart0 {
+	status = "disabled";    /* Conflicts with using pioD 18 as GPIO */
+};
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index afcea257c3..3cf40463be 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -612,6 +612,7 @@ config MACH_MICROCHIP_SAMA5D3_EDS
 	select OFDEVICE
 	select MCI_ATMEL_PBL
 	select COMMON_CLK_OF_PROVIDER
+	select OF_OVERLAY
 	help
 	  Select this if you are using Microchip's SAMA5D3 Ethernet Development
 	  System.
-- 
2.39.2




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 2/2] ARM: at91: microchip-sama5d3-eds: implement MDIO and SPI extension boards detection
  2024-06-22 17:48 ` [PATCH v2 2/2] ARM: at91: microchip-sama5d3-eds: implement MDIO and SPI extension boards detection Oleksij Rempel
@ 2024-07-01 12:43   ` Sascha Hauer
  0 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2024-07-01 12:43 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: barebox

Hi Oleksij,

Some small nitpicks inside.

On Sat, Jun 22, 2024 at 07:48:15PM +0200, Oleksij Rempel wrote:
> +++ b/arch/arm/boards/microchip-sama5d3-eds/board.c
> @@ -0,0 +1,414 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +// SPDX-FileCopyrightText: 2024 Oleksij Rempel <o.rempel@pengutronix.de>
> +
> +#include <common.h>
> +#include <deep-probe.h>
> +#include <envfs.h>
> +#include <environment.h>
> +#include <gpio.h>
> +#include <init.h>
> +#include <linux/phy.h>
> +#include <spi/spi.h>
> +
> +#define BASE_BOARD_NAME_SIZE 100
> +static char base_board_name[BASE_BOARD_NAME_SIZE] = "MCP_S5D3_EDS";
> +
> +extern char __dtbo_sama5d3_eds_rgmii_phy_start[];
> +extern char __dtbo_sama5d3_eds_lan9370_start[];
> +
> +#define MCP_S5D3_EDS_MDIO_EXT_BOARD_FLAG_IGNGORE	BIT(0)

s/IGNGORE/IGNORE/

> +static int mcp_s5d3_eds_spi_find_ksz_switch(struct device *dev, int bus_idx,
> +					    int chip_select, u8 *response,
> +					    size_t response_size)
> +{
> +	struct device_node *spi_node;
> +	struct spi_device spi = {
> +		.max_speed_hz = 1 * 1000 * 1000,  /* 1 MHz */
> +		.bits_per_word = 8,
> +		.chip_select = chip_select,
> +	};
> +	/* read command for ksz switch */
> +	u8 tx_buf[4] = {0x60, 0x00, 0x00, 0x00};
> +	u8 rx_buf[4] = {0};
> +	int ret, i;
> +	bool all_zeros = true, all_ones = true;
> +	char spi_alias[] = "spiX";
> +
> +	snprintf(spi_alias, sizeof(spi_alias), "spi%d", bus_idx);
> +
> +	spi_node = of_find_node_by_alias(NULL, spi_alias);
> +	if (!spi_node)
> +		return -ENODEV;
> +
> +	of_device_ensure_probed(spi_node);
> +
> +	spi.controller = spi_get_controller(bus_idx);
> +	spi.master = spi.controller;
> +
> +	if (!spi.controller) {
> +		dev_err(dev, "SPI bus %d not found\n", bus_idx);
> +		return -ENODEV;
> +	}
> +
> +	ret = spi.controller->setup(&spi);
> +	if (ret) {
> +		dev_err(dev, "Cannot setup SPI controller %d (%d)\n", bus_idx,
> +			ret);

You can use ": %pe\n", ERR_PTR(ret) here.

> +		return ret;
> +	}
> +
> +	ret = spi_write_then_read(&spi, tx_buf, sizeof(tx_buf), rx_buf,
> +				  sizeof(rx_buf));
> +	if (ret) {
> +		dev_err(dev, "Failed to communicate with SPI device on bus %d chip select %d\n",
> +			bus_idx, chip_select);
> +		return ret;
> +	}
> +
> +	for (i = 0; i < sizeof(rx_buf); i++) {
> +		if (rx_buf[i] != 0x00) {
> +			all_zeros = false;
> +		}
> +		if (rx_buf[i] != 0xFF) {
> +			all_ones = false;
> +		}
> +	}
> +
> +	if (all_zeros || all_ones)
> +		return 0;
> +
> +	if (response_size < sizeof(rx_buf)) {
> +		dev_err(dev, "Response storage is too small\n");

No need to print this message, it's more a sanity check if your code is
correct. Also, you can move this up and catch this before you are
sending SPI messages.

> +							scan->spi_bus_idx,
> +							scan->spi_chip_select,
> +							response);
> +		if (!found)
> +			dev_warn(dev, "No match for SPI device on bus %d chip select %d, response: %02x %02x %02x %02x\n",
> +				 scan->spi_bus_idx, scan->spi_chip_select,
> +				 response[0], response[1], response[2],
> +				 response[3]);

printf can print (small) hexdumps now using "%*ph" whic comes in handy
here.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: (subset) [PATCH v2 1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries
  2024-06-22 17:48 [PATCH v2 1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries Oleksij Rempel
  2024-06-22 17:48 ` [PATCH v2 2/2] ARM: at91: microchip-sama5d3-eds: implement MDIO and SPI extension boards detection Oleksij Rempel
@ 2024-07-01 12:44 ` Sascha Hauer
  1 sibling, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2024-07-01 12:44 UTC (permalink / raw)
  To: barebox, Oleksij Rempel


On Sat, 22 Jun 2024 19:48:14 +0200, Oleksij Rempel wrote:
> Current implementation of GPIO-based chip select configuration in this
> driver only considers the first valid GPIO and ignores
> subsequent entries. This patch ensures that all valid GPIO entries are
> processed correctly, enabling configurations with multiple valid and
> invalid entries.
> 
> Specifically, this change addresses the issue where configurations like
> `cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioC 28 0>;` are not handled
> correctly, leading to the last valid GPIO being ignored.
> 
> [...]

Applied, thanks!

[1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries
      https://git.pengutronix.de/cgit/barebox/commit/?id=22467a5fc41f (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-07-01 12:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-22 17:48 [PATCH v2 1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries Oleksij Rempel
2024-06-22 17:48 ` [PATCH v2 2/2] ARM: at91: microchip-sama5d3-eds: implement MDIO and SPI extension boards detection Oleksij Rempel
2024-07-01 12:43   ` Sascha Hauer
2024-07-01 12:44 ` (subset) [PATCH v2 1/2] spi: atmel_spi: Fix GPIO-based chip select handling to support multiple valid entries Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox