
On 9/17/24 8:21 AM, Lothar Rubusch wrote:
[...]
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig index 6b6a162f56..d42e7817be 100644 --- a/arch/arm/mach-socfpga/Kconfig +++ b/arch/arm/mach-socfpga/Kconfig @@ -221,6 +221,10 @@ config TARGET_SOCFPGA_TERASIC_SOCKIT bool "Terasic SoCkit (Cyclone V)" select TARGET_SOCFPGA_CYCLONE5
+config TARGET_SOCFPGA_ENCLUSTRA_MERCURY_AA1
- bool "Enclustra Mercury+ AA1"
- select TARGET_SOCFPGA_ARRIA10
Keep the list sorted.
endchoice
config SYS_BOARD @@ -244,6 +248,7 @@ config SYS_BOARD default "sr1500" if TARGET_SOCFPGA_SR1500 default "stratix10-socdk" if TARGET_SOCFPGA_STRATIX10_SOCDK default "vining_fpga" if TARGET_SOCFPGA_SOFTING_VINING_FPGA
- default "mercury_aa1" if TARGET_SOCFPGA_ENCLUSTRA_MERCURY_AA1
Keep the list sorted.
config SYS_VENDOR default "intel" if TARGET_SOCFPGA_AGILEX5_SOCDK @@ -264,6 +269,7 @@ config SYS_VENDOR default "terasic" if TARGET_SOCFPGA_TERASIC_DE10_NANO default "terasic" if TARGET_SOCFPGA_TERASIC_DE10_STANDARD default "terasic" if TARGET_SOCFPGA_TERASIC_SOCKIT
- default "enclustra" if TARGET_SOCFPGA_ENCLUSTRA_MERCURY_AA1
Keep the list sorted.
config SYS_SOC default "socfpga" @@ -289,5 +295,8 @@ config SYS_CONFIG_NAME default "socfpga_sr1500" if TARGET_SOCFPGA_SR1500 default "socfpga_stratix10_socdk" if TARGET_SOCFPGA_STRATIX10_SOCDK default "socfpga_vining_fpga" if TARGET_SOCFPGA_SOFTING_VINING_FPGA
- default "socfpga_mercury_aa1" if TARGET_SOCFPGA_ENCLUSTRA_MERCURY_AA1
Keep the list sorted.
+source "board/enclustra/common/Kconfig"
include the socfpga Kconfig directly, if more SoMs gets upstreamed, they might be Xilinx too so including common/Kconfig won't make sense here.
endif
[...]
diff --git a/board/enclustra/mercury_aa1/MAINTAINERS b/board/enclustra/mercury_aa1/MAINTAINERS new file mode 100644 index 0000000000..862cb1ae31 --- /dev/null +++ b/board/enclustra/mercury_aa1/MAINTAINERS @@ -0,0 +1,11 @@ +Enclustra Mercury+ AA1 +M: Lothar Rubusch l.rubusch@gmail.com +S: Maintained +F: board/enclustra/mercury_aa1/ +F: board/enclustra/common/ +F: include/configs/socfpga_mercury_aa1.h +F: configs/socfpga_enclustra_mercury_aa1_defconfig +F: arch/arm/dts/socfpga_enclustra_mercury_aa1.dtsi +F: arch/arm/dts/socfpga_enclustra_mercury_aa1_emmc_boot.dtsi +F: arch/arm/dts/socfpga_enclustra_mercury_aa1_qspi_boot.dtsi
Try these regex patterns (see top level MAINTAINERS file for details) , they should cover pretty much everything listed here automatically:
N: enclustra N: mercury_aa1
+F: doc/board/enclustra/mercury-aa1.rst 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..650457feba --- /dev/null +++ b/board/enclustra/mercury_aa1/aa1_set_storage_cmd.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2024 Enclustra GmbH
- */
+#include <command.h> +#include <env.h> +#include <init.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 void set_mux_mmc(void) +{
- u32 pinmux_arr[] = {0x0c, 0x8, // IO4 connected to SDMMC
This can be static const u32 , DTTO all the other arrays.
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
- u32 len, i, offset, value;
- len = sizeof(pinmux_arr) / sizeof(u32);
- for (i = 0; i < len; i += 2) {
Surely this function and all of its follow up almost identical copies can be deduplicated.
offset = pinmux_arr[i];
value = pinmux_arr[i + 1];
writel(value, ALTERA_PINMUX_OFFS + offset);
- }
+}
+static void set_mux_emmc(void) +{
- 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
- u32 len, i, offset, value;
- len = sizeof(pinmux_arr) / sizeof(u32);
- for (i = 0; i < len; i += 2) {
offset = pinmux_arr[i];
value = pinmux_arr[i + 1];
writel(value, ALTERA_PINMUX_OFFS + offset);
- }
+}
+static void set_mux_qspi(void)
Some more specific name of this symbol would be useful, e.g. enclustra_mercury_aa1_set_mux_qspi , since that symbol then shows up in e.g. objdump -D and unique name makes it easy to identify what it is.
+{
- 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
- u32 len, i, offset, value;
- len = sizeof(pinmux_arr) / sizeof(u32);
- for (i = 0; i < len; i += 2) {
offset = pinmux_arr[i];
value = pinmux_arr[i + 1];
writel(value, ALTERA_PINMUX_OFFS + offset);
- }
+}
+static void altera_set_storage(int store) +{
- unsigned int gpio_flash_sel;
- unsigned int gpio_flash_oe;
- if (store == altera_current_storage)
return;
- if (gpio_lookup_name("portb5", NULL, NULL, &gpio_flash_oe)) {
printf("ERROR: GPIO not found\n");
return;
- }
- if (gpio_request(gpio_flash_oe, "flash_oe")) {
printf("ERROR: GPIO request failed\n");
Does this look up have to be done for every single invocation of the command ?
This is missing gpio_free() for fail case.
Return value should be propagated in case of failure.
return;
- }
- if (gpio_lookup_name("portc6", NULL, NULL, &gpio_flash_sel)) {
printf("ERROR: GPIO not found\n");
return;
- }
- if (gpio_request(gpio_flash_sel, "flash_sel")) {
printf("ERROR: GPIO request failed\n");
return;
- }
- switch (store) {
- case ALTERA_MMC:
set_mux_mmc();
gpio_direction_output(gpio_flash_sel, 0);
gpio_direction_output(gpio_flash_oe, 0);
altera_current_storage = ALTERA_MMC;
writel(MMC_CLK_DIV, ALTERA_CLKMGR_MAINPLL_CNTR6CLK_BASE);
break;
- case ALTERA_EMMC:
set_mux_emmc();
gpio_direction_output(gpio_flash_sel, 1);
gpio_direction_output(gpio_flash_oe, 1);
altera_current_storage = ALTERA_EMMC;
writel(MMC_CLK_DIV, ALTERA_CLKMGR_MAINPLL_CNTR6CLK_BASE);
break;
- case ALTERA_QSPI:
set_mux_qspi();
gpio_direction_output(gpio_flash_sel, 1);
gpio_direction_output(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;
- }
- gpio_free(gpio_flash_sel);
- gpio_free(gpio_flash_oe);
+}
+static int altera_set_storage_cmd(struct cmd_tbl *cmdtp, int flag,
int argc, char * const argv[])
+{
- if (argc != 2)
return CMD_RET_USAGE;
- if (!strcmp(argv[1], "MMC"))
altera_set_storage(ALTERA_MMC);
- else if (!strcmp(argv[1], "QSPI"))
altera_set_storage(ALTERA_QSPI);
- else if (!strcmp(argv[1], "EMMC"))
altera_set_storage(ALTERA_EMMC);
- else
return CMD_RET_USAGE;
- return CMD_RET_SUCCESS;
+}
+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/board/enclustra/mercury_aa1/bitstream.its b/board/enclustra/mercury_aa1/bitstream.its new file mode 100644 index 0000000000..d16e4598de --- /dev/null +++ b/board/enclustra/mercury_aa1/bitstream.its @@ -0,0 +1,32 @@ +/dts-v1/;
+/ {
- description = "FIT image with FPGA bistream";
- #address-cells = <1>;
This address-cells shouldn't be needed here ?
- images {
fpga-periph-1 {
description = "FPGA peripheral bitstream";
data = /incbin/("bitstream.periph.rbf");
type = "fpga";
arch = "arm";
compression = "none";
};
fpga-core-1 {
description = "FPGA core bitstream";
data = /incbin/("bitstream.core.rbf");
type = "fpga";
arch = "arm";
compression = "none";
};
- };
- configurations {
default = "config-1";
config-1 {
description = "Boot with FPGA early IO release config";
fpga = "fpga-periph-1", "fpga-core-1";
};
- };
+};
[...]
diff --git a/include/configs/socfpga_mercury_aa1.h b/include/configs/socfpga_mercury_aa1.h new file mode 100644 index 0000000000..a5b63336e8 --- /dev/null +++ b/include/configs/socfpga_mercury_aa1.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2024 Enclustra GmbH
- */
+#ifndef __CONFIG_SOCFGPA_MERCURY_AA1_H__ +#define __CONFIG_SOCFGPA_MERCURY_AA1_H__
+#include <asm/arch/base_addr_a10.h>
+/*
- U-Boot general configurations
- */
+/* Memory configurations */ +#define PHYS_SDRAM_1_SIZE 0x80000000
+/*
- Serial / UART configurations
- */
+#define CFG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, 115200}
Is this needed or is the default baud rate table enough ?
+/*
- L4 OSC1 Timer 0
- */
+/* reload value when timer count to zero */ +#define TIMER_LOAD_VAL 0xFFFFFFFF
Is this needed ?