public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Lothar Rubusch <l.rubusch@gmail.com>
To: u-boot@lists.denx.de, trini@konsulko.com, marex@denx.de,
	simon.k.r.goldschmidt@gmail.com, tien.fong.chee@intel.com,
	sumit.garg@linaro.org
Cc: sjg@chromium.org, xypron.glpk@gmx.de, michal.simek@amd.com,
	jit.loon.lim@intel.com, barnas@google.com, l.rubusch@gmail.com
Subject: [PATCH v4 v5 04/10] ARM: socfpga: add Enclustra storage switch
Date: Tue, 19 Nov 2024 22:46:37 +0000	[thread overview]
Message-ID: <20241119224643.27692-5-l.rubusch@gmail.com> (raw)
In-Reply-To: <20241119224643.27692-1-l.rubusch@gmail.com>

Some of Enclustra's Intel SoMs need gpio muxing for setting up
the boot media. This can be done by switching dip switches and also in
software. The image in this case can be loaded from SD card, and flashed
to the eMMC or QSPI. After, the dip switches can set the boot select
accordingly. With altera_set_storage MMC|EMMC|QSPI from off the u-boot
shell, the media is usually switched.

Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com>
---
 .../socfpga_arria10_enclustra_mercury_aa1.dts |  17 ++
 board/enclustra/mercury_aa1/Makefile          |   8 +
 .../mercury_aa1/aa1_set_storage_cmd.c         | 190 ++++++++++++++++++
 doc/board/enclustra/mercury-aa1.rst           |  25 +++
 4 files changed, 240 insertions(+)
 create mode 100644 board/enclustra/mercury_aa1/Makefile
 create mode 100644 board/enclustra/mercury_aa1/aa1_set_storage_cmd.c

diff --git a/arch/arm/dts/socfpga_arria10_enclustra_mercury_aa1.dts b/arch/arm/dts/socfpga_arria10_enclustra_mercury_aa1.dts
index e8cc51a7b8..c038b2352e 100644
--- a/arch/arm/dts/socfpga_arria10_enclustra_mercury_aa1.dts
+++ b/arch/arm/dts/socfpga_arria10_enclustra_mercury_aa1.dts
@@ -5,6 +5,8 @@
 
 /dts-v1/;
 
+#include <dt-bindings/gpio/gpio.h>
+
 /* The arria10 family */
 #include "socfpga/socfpga_arria10_mercury_aa1.dtsi"
 
@@ -17,6 +19,13 @@
 		i2c1 = &i2c0;
 		spi0 = &qspi;
 	};
+
+	altera_set_storage {
+		compatible = "enclustra,altera_set_storage";
+		status = "okay";
+		oe-gpios = <&portb 5 GPIO_ACTIVE_HIGH>;
+		sel-gpios = <&portc 6 GPIO_ACTIVE_HIGH>;
+	};
 };
 
 &qspi {
@@ -35,6 +44,14 @@
 	};
 };
 
+&gpio1 {
+	status = "okay";
+};
+
+&gpio2 {
+	status = "okay";
+};
+
 /* Carrier board support */
 #if IS_ENABLED(CONFIG_ENCLUSTRA_PE1)
 # include "socfpga/socfpga_enclustra_mercury_pe1.dtsi"
diff --git a/board/enclustra/mercury_aa1/Makefile b/board/enclustra/mercury_aa1/Makefile
new file mode 100644
index 0000000000..53c84d8156
--- /dev/null
+++ b/board/enclustra/mercury_aa1/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2024 Enclustra GmbH
+
+ifeq ($(CONFIG_SPL_BUILD),)
+
+obj-y += aa1_set_storage_cmd.o
+
+endif
diff --git a/board/enclustra/mercury_aa1/aa1_set_storage_cmd.c b/board/enclustra/mercury_aa1/aa1_set_storage_cmd.c
new file mode 100644
index 0000000000..31c5ddb23b
--- /dev/null
+++ b/board/enclustra/mercury_aa1/aa1_set_storage_cmd.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2024 Enclustra GmbH
+ * <info@enclustra.com>
+ */
+
+#include <command.h>
+#include <env.h>
+#include <init.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <asm-generic/gpio.h>
+#include <asm/io.h>
+
+/* Pin muxing */
+#define ALTERA_NONE 0
+#define ALTERA_MMC 1
+#define ALTERA_QSPI 2
+#define ALTERA_EMMC 3
+#define MMC_CLK_DIV 0x9
+#define QSPI_CLK_DIV 0x384
+#define ALTERA_PINMUX_OFFS 0xffd07200
+#define ALTERA_CLKMGR_MAINPLL_CNTR6CLK_BASE 0xFFD04078
+
+static int altera_current_storage = ALTERA_NONE;
+
+static const struct udevice_id altera_set_storage_match[] = {
+	{ .compatible = "enclustra,altera_set_storage" },
+	{ }
+};
+
+U_BOOT_DRIVER(altera_set_storage) = {
+	.name		= "altera_set_storage",
+	.id			= UCLASS_MISC,
+	.of_match	= altera_set_storage_match,
+};
+
+static void enclustra_mercury_aa1_write(const u32 *pinmux_arr, int len)
+{
+	u32 i, offset, value;
+
+	for (i = 0; i < len; i += 2) {
+		offset = pinmux_arr[i];
+		value = pinmux_arr[i + 1];
+		writel(value, ALTERA_PINMUX_OFFS + offset);
+	}
+}
+
+static void enclustra_mercury_aa1_set_mux_mmc(void)
+{
+	static const u32 pinmux_arr[] = {0x0c, 0x8,	// IO4 connected to SDMMC
+					 0x10, 0x8,	// IO5
+					 0x14, 0x8,	// IO6
+					 0x18, 0x8,	// IO7
+					 0x1c, 0x8,	// IO8
+					 0x20, 0x8,	// IO9
+					 0x24, 0xf,	// IO10 connected to GPIO
+					 0x28, 0xf,	// IO11
+					 0x2c, 0xf,	// IO12
+					 0x30, 0xf,	// IO13
+					 0x34, 0xf,	// IO14
+					 0x38, 0xf};	// IO15
+	enclustra_mercury_aa1_write(pinmux_arr, ARRAY_SIZE(pinmux_arr));
+}
+
+static void enclustra_mercury_aa1_set_mux_emmc(void)
+{
+	static const u32 pinmux_arr[] = {0x0c, 0x8,	// IO4
+					 0x10, 0x8,	// IO5
+					 0x14, 0x8,	// IO6
+					 0x18, 0x8,	// IO7
+					 0x1c, 0x8,	// IO8
+					 0x20, 0x8,	// IO9
+					 0x24, 0xf,	// IO10
+					 0x28, 0xf,	// IO11
+					 0x2c, 0x8,	// IO12
+					 0x30, 0x8,	// IO13
+					 0x34, 0x8,	// IO14
+					 0x38, 0x8};	// IO15
+	enclustra_mercury_aa1_write(pinmux_arr, ARRAY_SIZE(pinmux_arr));
+}
+
+static void enclustra_mercury_aa1_set_mux_qspi(void)
+{
+	static const u32 pinmux_arr[] = {0x0c, 0x4,	// IO4 connected to QSPI
+					 0x10, 0x4,	// IO5
+					 0x14, 0x4,	// IO6
+					 0x18, 0x4,	// IO7
+					 0x1c, 0x4,	// IO8
+					 0x20, 0x4,	// IO9
+					 0x24, 0xf,	// IO10
+					 0x28, 0xf,	// IO11
+					 0x2c, 0xf,	// IO12
+					 0x30, 0xf,	// IO13
+					 0x34, 0xf,	// IO14
+					 0x38, 0xf};	// IO15
+	enclustra_mercury_aa1_write(pinmux_arr, ARRAY_SIZE(pinmux_arr));
+}
+
+static int altera_set_storage(struct udevice *dev, int store)
+{
+	struct gpio_desc gpio_flash_sel;
+	struct gpio_desc gpio_flash_oe;
+	int ret;
+
+	if (store == altera_current_storage)
+		return CMD_RET_FAILURE;
+
+	/* oe: portb 5 */
+	ret = gpio_request_by_name(dev, "oe-gpios", 0,
+				   &gpio_flash_oe, GPIOD_IS_OUT);
+
+	if (ret) {
+		printf("ERROR: GPIO oe not found\n");
+		return log_msg_ret("gpio", ret);
+	}
+
+	/* sel: portc 6 */
+	ret = gpio_request_by_name(dev, "sel-gpios", 0,
+				   &gpio_flash_sel, GPIOD_IS_OUT);
+	if (ret) {
+		printf("ERROR: GPIO sel not found\n");
+		ret = CMD_RET_FAILURE;
+		goto err;
+	}
+
+	switch (store) {
+	case ALTERA_MMC:
+		enclustra_mercury_aa1_set_mux_mmc();
+		dm_gpio_set_value(&gpio_flash_sel, 0);
+		dm_gpio_set_value(&gpio_flash_oe, 0);
+		altera_current_storage = ALTERA_MMC;
+		writel(MMC_CLK_DIV, ALTERA_CLKMGR_MAINPLL_CNTR6CLK_BASE);
+		break;
+	case ALTERA_EMMC:
+		enclustra_mercury_aa1_set_mux_emmc();
+		dm_gpio_set_value(&gpio_flash_sel, 1);
+		dm_gpio_set_value(&gpio_flash_oe, 1);
+		altera_current_storage = ALTERA_EMMC;
+		writel(MMC_CLK_DIV, ALTERA_CLKMGR_MAINPLL_CNTR6CLK_BASE);
+		break;
+	case ALTERA_QSPI:
+		enclustra_mercury_aa1_set_mux_qspi();
+		dm_gpio_set_value(&gpio_flash_sel, 1);
+		dm_gpio_set_value(&gpio_flash_oe, 0);
+		altera_current_storage = ALTERA_QSPI;
+		writel(QSPI_CLK_DIV, ALTERA_CLKMGR_MAINPLL_CNTR6CLK_BASE);
+		break;
+	default:
+		altera_current_storage = ALTERA_NONE;
+		break;
+	}
+
+	ret = CMD_RET_SUCCESS;
+	dm_gpio_free(dev, &gpio_flash_sel);
+err:
+	dm_gpio_free(dev, &gpio_flash_oe);
+
+	return ret;
+}
+
+static int altera_set_storage_cmd(struct cmd_tbl *cmdtp, int flag,
+				  int argc, char * const argv[])
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_DRIVER_GET(altera_set_storage), &dev);
+	if (ret)
+		return ret;
+
+	if (argc != 2)
+		return CMD_RET_USAGE;
+
+	if (!strcasecmp(argv[1], "mmc"))
+		return altera_set_storage(dev, ALTERA_MMC);
+	else if (!strcasecmp(argv[1], "qspi"))
+		return altera_set_storage(dev, ALTERA_QSPI);
+	else if (!strcasecmp(argv[1], "emmc"))
+		return altera_set_storage(dev, ALTERA_EMMC);
+	else
+		return CMD_RET_USAGE;
+
+	return CMD_RET_FAILURE;
+}
+
+U_BOOT_CMD(altera_set_storage, 2, 0, altera_set_storage_cmd,
+	   "Set non volatile memory access",
+	   "<MMC|QSPI|EMMC> - Set access for the selected memory device");
diff --git a/doc/board/enclustra/mercury-aa1.rst b/doc/board/enclustra/mercury-aa1.rst
index dec7cc3bdd..cba36aae2e 100644
--- a/doc/board/enclustra/mercury-aa1.rst
+++ b/doc/board/enclustra/mercury-aa1.rst
@@ -151,6 +151,31 @@ Alternative boot media are possible as officially documented by Enclustra.
 Note: eMMC and QSPI can be flashed from off the u-boot shell. Usually after
 flashing, the correct boot mode needs to be set by a BSEL switch.
 
+In the u-boot shell use the following command to switch between the boot media.
+This can be used to flash e.g. eMMC or QSPI with an image file stored on the SD
+card. Approaches are described in detail in the official Enclustra
+documentation according to their releases mentioned as links.
+
+ .. code-block:: bash
+
+    Hit any key to stop autoboot:  0
+    => altera_set_storage
+    altera_set_storage - Set non volatile memory access
+    Usage:
+    altera_set_storage <MMC|QSPI|EMMC> - Set access for the selected memory device
+    => altera_set_storage QSPI
+    => sf probe
+    SF: Detected s25fl512s with page size 256 Bytes, erase size 256 KiB, total 64 MiB
+    => altera_set_storage MMC
+    => mmc rescan
+    => mmc list
+    mmc@ff808000: 0 (SD)
+    => altera_set_storage EMMC
+    => mmc rescan
+    => mmc list
+    mmc@ff808000: 0 (eMMC)
+    =>
+
 Before turning on the setup, make sure to have the correct voltage configured
 at the carrier board, using the jumpers on the voltage pin header. Also make
 sure to have switched to the correct boot media using typically some dip
-- 
2.39.2


  parent reply	other threads:[~2024-11-20  0:29 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-19 22:46 [PATCH v4 v5 00/10] add support for Enclustra Mercury AA1 SoMs Lothar Rubusch
2024-11-19 22:46 ` [PATCH v4 v5 01/10] doc: board: enclustra: add Enclustra Mercury+ AA1 Lothar Rubusch
2024-11-19 22:46 ` [PATCH v4 v5 02/10] ARM: socfpga: add Mercury+ AA1 SoM support Lothar Rubusch
2024-11-19 22:46 ` [PATCH v4 v5 03/10] ARM: dts: socfpga: add Mercury+ AA1 for u-boot dts Lothar Rubusch
2025-01-22  4:35   ` Chee, Tien Fong
2025-01-27 10:30     ` Lothar Rubusch
2024-11-19 22:46 ` Lothar Rubusch [this message]
2024-11-19 22:46 ` [PATCH v4 v5 05/10] ARM: socfpga: add Mercury+ AA1 boot scripts Lothar Rubusch
2024-11-19 22:46 ` [PATCH v4 v5 06/10] ARM: socfpga: AA1: support MAC from secure eeprom Lothar Rubusch
2024-11-19 22:46 ` [PATCH v4 v5 07/10] misc: atsha204a: update kconfig description Lothar Rubusch
2024-11-19 22:46 ` [PATCH v4 v5 08/10] ARM: dts: arria10: update according to DTSpec Lothar Rubusch
2024-11-19 22:46 ` [PATCH v4 v5 09/10] ARM: socfpga: update function call to modern API Lothar Rubusch
2024-11-19 22:46 ` [PATCH v4 v5 10/10] ARM: socfpga: apply binman approach to fpga parts Lothar Rubusch

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=20241119224643.27692-5-l.rubusch@gmail.com \
    --to=l.rubusch@gmail.com \
    --cc=barnas@google.com \
    --cc=jit.loon.lim@intel.com \
    --cc=marex@denx.de \
    --cc=michal.simek@amd.com \
    --cc=simon.k.r.goldschmidt@gmail.com \
    --cc=sjg@chromium.org \
    --cc=sumit.garg@linaro.org \
    --cc=tien.fong.chee@intel.com \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox