mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2
@ 2025-09-25 11:59 David Picard
  2025-09-25 11:59 ` [PATCH v2 01/10] Add handoff files David Picard
                   ` (11 more replies)
  0 siblings, 12 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard, Ahmad Fatoum

Add support for the Enclustra Mercury+ SA2, a Cyclone V based
SoC FPGA.
https://www.enclustra.com/en/products/system-on-chip-modules/mercury-sa2/

The SoM provides a 64MiB NOR QSPI flash, DDR3, Ethernet PHY, RTC.

The Cyclone V features a hardware ARM core (aka HPS) that can boot
from SD card (MMC), QSPI flash. This patch series focusses on MMC.

Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
---
Changes in v2:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v1: https://lore.kernel.org/r/20250917-boards-enclustra-sa2-add-support-v1-0-2de8f69107a1@clermont.in2p3.fr

---
David Picard (8):
      Add handoff files
      Add Enclustra Mercury+ SA2 module
      ARM: dts: socfpga: use upstream SA2 device tree
      ARM: dts: socfpga: adapt upstream SA2 device tree
      boards: enclustra-sa2: read MAC address from EEPROM
      boards: enclustra-sa2: configure SI5338
      boards: enclustra-sa2: enable SI5338
      boards: enclustra-sa2: read S/N from EEPROM

Sascha Hauer (2):
      lib: add crc16 support
      nvmem: add support for Atmel sha204(a)

 arch/arm/boards/Makefile                           |   1 +
 arch/arm/boards/enclustra-sa2/Makefile             |   2 +
 .../boards/enclustra-sa2/Si5338-RevB-Registers.h   | 433 +++++++++++++
 arch/arm/boards/enclustra-sa2/board.c              | 148 +++++
 .../boards/enclustra-sa2/iocsr_config_cyclone5.c   | 678 +++++++++++++++++++++
 arch/arm/boards/enclustra-sa2/lowlevel.c           |  15 +
 arch/arm/boards/enclustra-sa2/pinmux_config.c      | 241 ++++++++
 arch/arm/boards/enclustra-sa2/pll_config.h         | 107 ++++
 arch/arm/boards/enclustra-sa2/sdram_config.h       | 112 ++++
 arch/arm/boards/enclustra-sa2/sequencer_auto.h     | 225 +++++++
 .../boards/enclustra-sa2/sequencer_auto_ac_init.c  |  67 ++
 .../enclustra-sa2/sequencer_auto_inst_init.c       | 158 +++++
 arch/arm/boards/enclustra-sa2/sequencer_defines.h  | 165 +++++
 arch/arm/boards/enclustra-sa2/si5338_config.c      | 252 ++++++++
 arch/arm/boards/enclustra-sa2/si5338_config.h      |  22 +
 arch/arm/configs/socfpga-xload_defconfig           |   1 +
 arch/arm/configs/socfpga_defconfig                 |   3 +-
 arch/arm/dts/Makefile                              |   1 +
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts      |  17 +
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi     | 213 +++++++
 arch/arm/mach-socfpga/Kconfig                      |   8 +
 drivers/nvmem/Kconfig                              |  15 +
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/atmel-i2c.c                          | 302 +++++++++
 drivers/nvmem/atmel-i2c.h                          | 180 ++++++
 drivers/nvmem/atmel-sha204a.c                      | 114 ++++
 images/Makefile.socfpga                            |   8 +
 include/linux/crc16.h                              |  21 +
 lib/Kconfig                                        |   3 +
 lib/Makefile                                       |   1 +
 lib/crc16.c                                        |  69 +++
 31 files changed, 3582 insertions(+), 2 deletions(-)
---
base-commit: 85c11b44889eb73921b2095f2c42492ac3d686a0
change-id: 20250916-boards-enclustra-sa2-add-support-4704233a6861

Best regards,
-- 
David Picard <david.picard@clermont.in2p3.fr>




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

* [PATCH v2 01/10] Add handoff files
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-25 11:59 ` [PATCH v2 02/10] Add Enclustra Mercury+ SA2 module David Picard
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

Copy handoff files from Mercury_SA2_ST1_Reference_Design
released by Enclustra.

Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
---
 .../boards/enclustra-sa2/iocsr_config_cyclone5.c   | 678 +++++++++++++++++++++
 arch/arm/boards/enclustra-sa2/pinmux_config.c      | 241 ++++++++
 arch/arm/boards/enclustra-sa2/pll_config.h         | 107 ++++
 arch/arm/boards/enclustra-sa2/sdram_config.h       | 112 ++++
 arch/arm/boards/enclustra-sa2/sequencer_auto.h     | 225 +++++++
 .../boards/enclustra-sa2/sequencer_auto_ac_init.c  |  67 ++
 .../enclustra-sa2/sequencer_auto_inst_init.c       | 158 +++++
 arch/arm/boards/enclustra-sa2/sequencer_defines.h  | 165 +++++
 8 files changed, 1753 insertions(+)

diff --git a/arch/arm/boards/enclustra-sa2/iocsr_config_cyclone5.c b/arch/arm/boards/enclustra-sa2/iocsr_config_cyclone5.c
new file mode 100644
index 0000000000000000000000000000000000000000..30af190f340a065ffb385790d3bab328b1ff1ebf
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/iocsr_config_cyclone5.c
@@ -0,0 +1,678 @@
+/* GENERATED FILE - DO NOT EDIT */
+/*
+ * Copyright Altera Corporation (C) 2012-2014. All rights reserved
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *    * Neither the name of Altera Corporation nor the
+ *      names of its contributors may be used to endorse or promote products
+ *      derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <mach/socfpga/cyclone5-scan-manager.h>
+
+static const unsigned long iocsr_scan_chain0_table[((CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH / 32) + 1)]
+    = {
+	0x00000000,
+	0x00000000,
+	0x0FF00000,
+	0xC0000000,
+	0x0000003F,
+	0x00008000,
+	0x00060180,
+	0x18060000,
+	0x18000000,
+	0x00018060,
+	0x00000000,
+	0x00004000,
+	0x000300C0,
+	0x0C030000,
+	0x0C000000,
+	0x00000030,
+	0x0000C030,
+	0x00002000,
+	0x00018060,
+	0x06018000,
+	0x06000000,
+	0x00000018,
+	0x00006018,
+	0x00001000,
+};
+
+static const unsigned long iocsr_scan_chain1_table[((CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH / 32) + 1)]
+    = {
+	0x000C0300,
+	0x300C0000,
+	0x300000C0,
+	0x000000C0,
+	0x000300C0,
+	0x00008000,
+	0x00060180,
+	0x18060000,
+	0x18000000,
+	0x00000060,
+	0x00018060,
+	0x00004000,
+	0x000300C0,
+	0x0C030000,
+	0x0C000000,
+	0x00000030,
+	0x0000C030,
+	0x00002000,
+	0x06018060,
+	0x06018000,
+	0x01FE0000,
+	0xF8000000,
+	0x00000007,
+	0x00001000,
+	0x0000C030,
+	0x0300C000,
+	0x03000000,
+	0x0000300C,
+	0x0000300C,
+	0x00000800,
+	0x00000000,
+	0x00000000,
+	0x01800000,
+	0x00000006,
+	0x00001806,
+	0x00000400,
+	0x00000000,
+	0x00C03000,
+	0x00000003,
+	0x00000000,
+	0x00000000,
+	0x00000200,
+	0x00601806,
+	0x00000000,
+	0x80600000,
+	0x80000601,
+	0x00000601,
+	0x00000100,
+	0x00300C03,
+	0xC0300C00,
+	0xC0300000,
+	0xC0000300,
+	0x000C0300,
+	0x00000080,
+};
+
+static const unsigned long iocsr_scan_chain2_table[((CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH / 32) + 1)]
+    = {
+	0x000C0300,
+	0x00000000,
+	0x0FF00000,
+	0x00000000,
+	0x0C0300C0,
+	0x00008000,
+	0x00060180,
+	0x18060000,
+	0x18000000,
+	0x00000060,
+	0x00018060,
+	0x00004000,
+	0x200300C0,
+	0x0C030000,
+	0x0C000000,
+	0x00000030,
+	0x0000C030,
+	0x00002000,
+	0x00018060,
+	0x06018000,
+	0x06000000,
+	0x00010018,
+	0x00006018,
+	0x00001000,
+	0x0000C030,
+	0x0300C000,
+	0x03000000,
+	0x0000000C,
+	0x0000300C,
+	0x00000800,
+};
+
+static const unsigned long iocsr_scan_chain3_table[((CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH / 32) + 1)]
+    = {
+	0x0C420D80,
+	0x0C3000FF,
+	0x0A804001,
+	0x07900000,
+	0x0A800000,
+	0x07900000,
+	0x0A800000,
+	0x07900000,
+	0x08020000,
+	0x00100000,
+	0x20430000,
+	0x0C003001,
+	0x00C00481,
+	0x00000000,
+	0x4810C021,
+	0x82000C00,
+	0x05400000,
+	0x03C80000,
+	0x04010000,
+	0x00080000,
+	0x05400000,
+	0x03C80000,
+	0x05400000,
+	0x03C80000,
+	0x90218000,
+	0x86001800,
+	0x00600240,
+	0x80090218,
+	0x00000001,
+	0x40000000,
+	0x02A00000,
+	0x01E40000,
+	0x02A00000,
+	0x01E40000,
+	0x02A00000,
+	0x01E40000,
+	0x02A00000,
+	0x01E40000,
+	0x4810C000,
+	0x43000C00,
+	0x00300120,
+	0xC004810C,
+	0x12043000,
+	0x20000300,
+	0x00040000,
+	0x50670000,
+	0x00000010,
+	0x24590000,
+	0x00001000,
+	0xA0000034,
+	0x0D000001,
+	0x40680208,
+	0x8E034010,
+	0x1C701A03,
+	0x802080D0,
+	0x34010406,
+	0x01A00410,
+	0x300D0000,
+	0x1040680C,
+	0x00410340,
+	0xD002081A,
+	0x06802080,
+	0x10040000,
+	0x00200000,
+	0x10040000,
+	0x00200000,
+	0x15000000,
+	0x0F200000,
+	0x15000000,
+	0x0F200000,
+	0x01FE0000,
+	0x18000000,
+	0x01800902,
+	0x00240860,
+	0x007F8006,
+	0x00000000,
+	0x0A800001,
+	0x07900000,
+	0x0A800000,
+	0x07900000,
+	0x0A800000,
+	0x07900000,
+	0x08020000,
+	0x00100000,
+	0x20430000,
+	0x0C003001,
+	0x00C00481,
+	0x00000FF0,
+	0x4810C000,
+	0x80000C00,
+	0x05400000,
+	0x02480000,
+	0x04000000,
+	0x00080000,
+	0x05400000,
+	0x03C80000,
+	0x05400000,
+	0x03C80000,
+	0x90218000,
+	0x86001800,
+	0x00600240,
+	0x80090218,
+	0x24086001,
+	0x40000600,
+	0x02A00040,
+	0x01E40000,
+	0x02A00000,
+	0x01E40000,
+	0x02A00000,
+	0x01E40000,
+	0x02A00000,
+	0x01E40000,
+	0x4810C000,
+	0x43000C00,
+	0x00300120,
+	0xC004810C,
+	0x12043000,
+	0x20000300,
+	0x00040000,
+	0x50670000,
+	0x00000010,
+	0x24590000,
+	0x00001000,
+	0xA0000034,
+	0x0D000001,
+	0x40680C30,
+	0x41034010,
+	0x02081A00,
+	0x802080D0,
+	0x34051406,
+	0x01A00040,
+	0x080D0002,
+	0x10406802,
+	0x00410340,
+	0xD002081A,
+	0x06802080,
+	0x10040000,
+	0x00200000,
+	0x10040000,
+	0x00200000,
+	0x15000000,
+	0x0F200000,
+	0x15000000,
+	0x0F200000,
+	0x01FE0000,
+	0x18000000,
+	0x01800902,
+	0x00240860,
+	0x007F8006,
+	0x00000000,
+	0x99300001,
+	0x34343400,
+	0xAA0D4000,
+	0x01C3A800,
+	0xAA0D4000,
+	0x01C3A800,
+	0xAA0D4000,
+	0x01C3A800,
+	0x00040100,
+	0x00000800,
+	0x00000000,
+	0x00001208,
+	0x00482000,
+	0x01000000,
+	0x00000000,
+	0x00410482,
+	0x0006A000,
+	0x0001B400,
+	0x00020000,
+	0x00000400,
+	0x0002A000,
+	0x0001E400,
+	0x5506A000,
+	0x00E1D400,
+	0x00000000,
+	0x2043090C,
+	0x00003001,
+	0x90400000,
+	0x00000000,
+	0x2020C243,
+	0x2A835000,
+	0x0070EA00,
+	0x2A835000,
+	0x0070EA00,
+	0x2A835000,
+	0x0070EA00,
+	0x00010040,
+	0x00000200,
+	0x00000000,
+	0x00000482,
+	0x00120800,
+	0x00000000,
+	0x80000000,
+	0x00104120,
+	0x00000200,
+	0xAC0D5F80,
+	0xFFFFFFFF,
+	0x14F3690D,
+	0x1A041414,
+	0x00D00000,
+	0x18864000,
+	0x49247A06,
+	0xB3CF23D9,
+	0xF751451E,
+	0x0342E388,
+	0x821A0000,
+	0x0000D000,
+	0x01040680,
+	0xD149247A,
+	0x1EB3CF23,
+	0x88F75E79,
+	0x000342E3,
+	0x00080200,
+	0x00001000,
+	0x00080200,
+	0x00001000,
+	0x000A8000,
+	0x00075000,
+	0x541A8000,
+	0x03875001,
+	0x00000000,
+	0x00000000,
+	0x0080C000,
+	0x41000000,
+	0x00003FC2,
+	0x00820000,
+	0xAA0D4000,
+	0x01C3A800,
+	0xAA0D4000,
+	0x01C3A800,
+	0xAA0D4000,
+	0x01C3A800,
+	0x00040100,
+	0x00000800,
+	0x00000000,
+	0x00001208,
+	0x00482000,
+	0x00000000,
+	0x00000000,
+	0x00410482,
+	0x0006A000,
+	0x0001B400,
+	0x00020000,
+	0x00000400,
+	0x00020080,
+	0x00000400,
+	0x5506A000,
+	0x00E1D400,
+	0x00000000,
+	0x0000090C,
+	0x00000000,
+	0x90400000,
+	0x00000000,
+	0x2020C243,
+	0x2A835000,
+	0x0070EA00,
+	0x2A835000,
+	0x0070EA00,
+	0x2A835000,
+	0x0070EA00,
+	0x00015000,
+	0x0000F200,
+	0x00000000,
+	0x00000482,
+	0x86120800,
+	0x00600240,
+	0x80000000,
+	0x00104120,
+	0x00000200,
+	0xAC0D5F80,
+	0xFFFFFFFF,
+	0x14F3690D,
+	0x1A041414,
+	0x00D00000,
+	0x18864000,
+	0x49247A06,
+	0xB3CF23D9,
+	0xF75E791E,
+	0x0342E388,
+	0x821A028A,
+	0x0000D000,
+	0x00000680,
+	0xD149247A,
+	0x1EB2CB23,
+	0x88F55E79,
+	0x000342E3,
+	0x00080200,
+	0x00001000,
+	0x00080200,
+	0x00001000,
+	0x000A8000,
+	0x00075000,
+	0x541A8000,
+	0x03875001,
+	0x00000000,
+	0x00000000,
+	0x0080C000,
+	0x41000000,
+	0x00000002,
+	0x00820000,
+	0xAA0D4000,
+	0x01C3A800,
+	0xAA0D4000,
+	0x01C3A800,
+	0xAA0D4000,
+	0x01C3A800,
+	0x00040100,
+	0x00000800,
+	0x00000000,
+	0x00001208,
+	0x00482000,
+	0x00000000,
+	0x00000000,
+	0x00410482,
+	0x0006A000,
+	0x0001B400,
+	0x00020000,
+	0x00000400,
+	0x0002A000,
+	0x0001E400,
+	0x5506A000,
+	0x00E1D400,
+	0x00000000,
+	0x2043090C,
+	0x00003001,
+	0x90400000,
+	0x00000000,
+	0x2020C243,
+	0x2A835000,
+	0x0070EA00,
+	0x2A835000,
+	0x0070EA00,
+	0x2A835000,
+	0x0070EA00,
+	0x00010040,
+	0x00000200,
+	0x00000000,
+	0x00000482,
+	0x00120800,
+	0x00000000,
+	0x80000000,
+	0x00104120,
+	0x00000200,
+	0xAC0D5F80,
+	0xFFFFFFFF,
+	0x14F3690D,
+	0x1A041414,
+	0x00D00000,
+	0x04864000,
+	0x69A47A01,
+	0xF228A3D5,
+	0xF751451E,
+	0x03529248,
+	0x821A0000,
+	0x0000D000,
+	0x00000680,
+	0xD969A47A,
+	0x1EB3CF23,
+	0x48F75145,
+	0x00035292,
+	0x00080200,
+	0x00001000,
+	0x00080200,
+	0x00001000,
+	0x000A8000,
+	0x00075000,
+	0x541A8000,
+	0x03875001,
+	0x00000000,
+	0x00000000,
+	0x0080C000,
+	0x41000000,
+	0x00000002,
+	0x00820000,
+	0xAA0D4000,
+	0x01C3A800,
+	0xAA0D4000,
+	0x01C3A800,
+	0xAA0D4000,
+	0x01C3A800,
+	0x00040100,
+	0x00000800,
+	0x00000000,
+	0x00001208,
+	0x00482000,
+	0x00000000,
+	0x00000000,
+	0x00410482,
+	0x0006A000,
+	0x0001B400,
+	0x00020000,
+	0x00000400,
+	0x00020080,
+	0x00000400,
+	0x5506A000,
+	0x00E1D400,
+	0x00000000,
+	0x0000090C,
+	0x00000000,
+	0x90400000,
+	0x00000000,
+	0x2020C243,
+	0x2A835000,
+	0x0070EA00,
+	0x2A835000,
+	0x0070EA00,
+	0x2A835000,
+	0x0070EA00,
+	0x00010040,
+	0x00000200,
+	0x00000000,
+	0x00000482,
+	0x00120800,
+	0x00400000,
+	0x80000000,
+	0x00104120,
+	0x00000200,
+	0xAC0D5F80,
+	0xFFFFFFFF,
+	0x14F1690D,
+	0x1A041414,
+	0x00D00000,
+	0x18864000,
+	0x49247A06,
+	0xB2CB23D1,
+	0xF75E791E,
+	0x035CE388,
+	0x821A0000,
+	0x0000D000,
+	0x00000680,
+	0xD949247A,
+	0x1EB3CF23,
+	0x88F75E79,
+	0x000342E3,
+	0x00080200,
+	0x00001000,
+	0x00080200,
+	0x00001000,
+	0x000A8000,
+	0x00075000,
+	0x541A8000,
+	0x03875001,
+	0x00000000,
+	0x00000000,
+	0x0080C000,
+	0x41000000,
+	0x00000002,
+	0x00820000,
+	0x00489800,
+	0x801A1A1A,
+	0x00000200,
+	0x80000004,
+	0x00000200,
+	0x80000004,
+	0x00000200,
+	0x80000004,
+	0x00000200,
+	0x00000004,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x40002000,
+	0x00000100,
+	0x40000002,
+	0x00000100,
+	0x40000002,
+	0x00000100,
+	0x40000002,
+	0x00000100,
+	0x00000002,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x20001000,
+	0x00000080,
+	0x20000001,
+	0x00000080,
+	0x20000001,
+	0x00000080,
+	0x20000001,
+	0x00000080,
+	0x00000001,
+	0x00000000,
+	0x00000000,
+	0x00FF0000,
+	0x00000000,
+	0x00000000,
+	0x00000800,
+	0xC0000001,
+	0x00041419,
+	0x40000000,
+	0x04000816,
+	0x000D0000,
+	0x00006800,
+	0x00000340,
+	0xD000001A,
+	0x06800000,
+	0x00340000,
+	0x0001A000,
+	0x00000D00,
+	0x40000068,
+	0x1A000003,
+	0x00D00000,
+	0x00068000,
+	0x00003400,
+	0x000001A0,
+	0x00000401,
+	0x00000008,
+	0x00000401,
+	0x00000008,
+	0x00000401,
+	0x00000008,
+	0x00000401,
+	0x80000008,
+	0x0000007F,
+	0x00000000,
+	0x00000000,
+	0xE0000000,
+	0x0000001F,
+	0x00004000,
+};
diff --git a/arch/arm/boards/enclustra-sa2/pinmux_config.c b/arch/arm/boards/enclustra-sa2/pinmux_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..8bcb0b5196bc0fa0d5fb748c5e8104db7a206dfc
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/pinmux_config.c
@@ -0,0 +1,241 @@
+/* GENERATED FILE - DO NOT EDIT */
+/*
+ * Copyright Altera Corporation (C) 2012-2014. All rights reserved
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *    * Neither the name of Altera Corporation nor the
+ *      names of its contributors may be used to endorse or promote products
+ *      derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <common.h>
+
+/* pin MUX configuration data */
+static unsigned long sys_mgr_init_table[] = {
+	0,			/* EMACIO0 */
+	2,			/* EMACIO1 */
+	2,			/* EMACIO2 */
+	2,			/* EMACIO3 */
+	2,			/* EMACIO4 */
+	2,			/* EMACIO5 */
+	2,			/* EMACIO6 */
+	2,			/* EMACIO7 */
+	2,			/* EMACIO8 */
+	0,			/* EMACIO9 */
+	2,			/* EMACIO10 */
+	2,			/* EMACIO11 */
+	2,			/* EMACIO12 */
+	2,			/* EMACIO13 */
+	0,			/* EMACIO14 */
+	0,			/* EMACIO15 */
+	0,			/* EMACIO16 */
+	0,			/* EMACIO17 */
+	0,			/* EMACIO18 */
+	0,			/* EMACIO19 */
+	3,			/* FLASHIO0 */
+	0,			/* FLASHIO1 */
+	3,			/* FLASHIO2 */
+	3,			/* FLASHIO3 */
+	0,			/* FLASHIO4 */
+	0,			/* FLASHIO5 */
+	0,			/* FLASHIO6 */
+	0,			/* FLASHIO7 */
+	0,			/* FLASHIO8 */
+	3,			/* FLASHIO9 */
+	3,			/* FLASHIO10 */
+	3,			/* FLASHIO11 */
+	0,			/* GENERALIO0 */
+	0,			/* GENERALIO1 */
+	0,			/* GENERALIO2 */
+	0,			/* GENERALIO3 */
+	0,			/* GENERALIO4 */
+	0,			/* GENERALIO5 */
+	0,			/* GENERALIO6 */
+	1,			/* GENERALIO7 */
+	1,			/* GENERALIO8 */
+	0,			/* GENERALIO9 */
+	0,			/* GENERALIO10 */
+	0,			/* GENERALIO11 */
+	0,			/* GENERALIO12 */
+	0,			/* GENERALIO13 */
+	0,			/* GENERALIO14 */
+	0,			/* GENERALIO15 */
+	0,			/* GENERALIO16 */
+	2,			/* GENERALIO17 */
+	2,			/* GENERALIO18 */
+	0,			/* GENERALIO19 */
+	0,			/* GENERALIO20 */
+	0,			/* GENERALIO21 */
+	0,			/* GENERALIO22 */
+	0,			/* GENERALIO23 */
+	0,			/* GENERALIO24 */
+	0,			/* GENERALIO25 */
+	0,			/* GENERALIO26 */
+	0,			/* GENERALIO27 */
+	0,			/* GENERALIO28 */
+	0,			/* GENERALIO29 */
+	0,			/* GENERALIO30 */
+	0,			/* GENERALIO31 */
+	2,			/* MIXED1IO0 */
+	2,			/* MIXED1IO1 */
+	2,			/* MIXED1IO2 */
+	2,			/* MIXED1IO3 */
+	2,			/* MIXED1IO4 */
+	2,			/* MIXED1IO5 */
+	2,			/* MIXED1IO6 */
+	2,			/* MIXED1IO7 */
+	2,			/* MIXED1IO8 */
+	2,			/* MIXED1IO9 */
+	2,			/* MIXED1IO10 */
+	2,			/* MIXED1IO11 */
+	2,			/* MIXED1IO12 */
+	2,			/* MIXED1IO13 */
+	0,			/* MIXED1IO14 */
+	3,			/* MIXED1IO15 */
+	3,			/* MIXED1IO16 */
+	3,			/* MIXED1IO17 */
+	3,			/* MIXED1IO18 */
+	3,			/* MIXED1IO19 */
+	3,			/* MIXED1IO20 */
+	0,			/* MIXED1IO21 */
+	0,			/* MIXED2IO0 */
+	0,			/* MIXED2IO1 */
+	0,			/* MIXED2IO2 */
+	0,			/* MIXED2IO3 */
+	0,			/* MIXED2IO4 */
+	0,			/* MIXED2IO5 */
+	0,			/* MIXED2IO6 */
+	0,			/* MIXED2IO7 */
+	0,			/* GPLINMUX48 */
+	0,			/* GPLINMUX49 */
+	0,			/* GPLINMUX50 */
+	0,			/* GPLINMUX51 */
+	0,			/* GPLINMUX52 */
+	0,			/* GPLINMUX53 */
+	0,			/* GPLINMUX54 */
+	0,			/* GPLINMUX55 */
+	0,			/* GPLINMUX56 */
+	0,			/* GPLINMUX57 */
+	0,			/* GPLINMUX58 */
+	0,			/* GPLINMUX59 */
+	0,			/* GPLINMUX60 */
+	0,			/* GPLINMUX61 */
+	0,			/* GPLINMUX62 */
+	0,			/* GPLINMUX63 */
+	0,			/* GPLINMUX64 */
+	0,			/* GPLINMUX65 */
+	0,			/* GPLINMUX66 */
+	0,			/* GPLINMUX67 */
+	0,			/* GPLINMUX68 */
+	0,			/* GPLINMUX69 */
+	0,			/* GPLINMUX70 */
+	1,			/* GPLMUX0 */
+	1,			/* GPLMUX1 */
+	1,			/* GPLMUX2 */
+	1,			/* GPLMUX3 */
+	1,			/* GPLMUX4 */
+	1,			/* GPLMUX5 */
+	1,			/* GPLMUX6 */
+	1,			/* GPLMUX7 */
+	1,			/* GPLMUX8 */
+	1,			/* GPLMUX9 */
+	1,			/* GPLMUX10 */
+	1,			/* GPLMUX11 */
+	1,			/* GPLMUX12 */
+	1,			/* GPLMUX13 */
+	1,			/* GPLMUX14 */
+	1,			/* GPLMUX15 */
+	1,			/* GPLMUX16 */
+	1,			/* GPLMUX17 */
+	1,			/* GPLMUX18 */
+	1,			/* GPLMUX19 */
+	1,			/* GPLMUX20 */
+	1,			/* GPLMUX21 */
+	1,			/* GPLMUX22 */
+	1,			/* GPLMUX23 */
+	1,			/* GPLMUX24 */
+	1,			/* GPLMUX25 */
+	1,			/* GPLMUX26 */
+	1,			/* GPLMUX27 */
+	1,			/* GPLMUX28 */
+	1,			/* GPLMUX29 */
+	1,			/* GPLMUX30 */
+	1,			/* GPLMUX31 */
+	1,			/* GPLMUX32 */
+	1,			/* GPLMUX33 */
+	1,			/* GPLMUX34 */
+	1,			/* GPLMUX35 */
+	1,			/* GPLMUX36 */
+	1,			/* GPLMUX37 */
+	1,			/* GPLMUX38 */
+	1,			/* GPLMUX39 */
+	1,			/* GPLMUX40 */
+	1,			/* GPLMUX41 */
+	1,			/* GPLMUX42 */
+	1,			/* GPLMUX43 */
+	1,			/* GPLMUX44 */
+	1,			/* GPLMUX45 */
+	1,			/* GPLMUX46 */
+	1,			/* GPLMUX47 */
+	1,			/* GPLMUX48 */
+	1,			/* GPLMUX49 */
+	1,			/* GPLMUX50 */
+	1,			/* GPLMUX51 */
+	1,			/* GPLMUX52 */
+	1,			/* GPLMUX53 */
+	1,			/* GPLMUX54 */
+	1,			/* GPLMUX55 */
+	1,			/* GPLMUX56 */
+	1,			/* GPLMUX57 */
+	1,			/* GPLMUX58 */
+	1,			/* GPLMUX59 */
+	1,			/* GPLMUX60 */
+	1,			/* GPLMUX61 */
+	1,			/* GPLMUX62 */
+	1,			/* GPLMUX63 */
+	1,			/* GPLMUX64 */
+	1,			/* GPLMUX65 */
+	1,			/* GPLMUX66 */
+	1,			/* GPLMUX67 */
+	1,			/* GPLMUX68 */
+	1,			/* GPLMUX69 */
+	1,			/* GPLMUX70 */
+	0,			/* NANDUSEFPGA */
+	0,			/* UART0USEFPGA */
+	0,			/* RGMII1USEFPGA */
+	0,			/* SPIS0USEFPGA */
+	0,			/* CAN0USEFPGA */
+	0,			/* I2C0USEFPGA */
+	0,			/* SDMMCUSEFPGA */
+	0,			/* QSPIUSEFPGA */
+	0,			/* SPIS1USEFPGA */
+	0,			/* RGMII0USEFPGA */
+	0,			/* UART1USEFPGA */
+	0,			/* CAN1USEFPGA */
+	0,			/* USB1USEFPGA */
+	0,			/* I2C3USEFPGA */
+	0,			/* I2C2USEFPGA */
+	1,			/* I2C1USEFPGA */
+	0,			/* SPIM1USEFPGA */
+	0,			/* USB0USEFPGA */
+	0			/* SPIM0USEFPGA */
+};
diff --git a/arch/arm/boards/enclustra-sa2/pll_config.h b/arch/arm/boards/enclustra-sa2/pll_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..df04f312cdd1213f846edb0945fde31f67886b43
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/pll_config.h
@@ -0,0 +1,107 @@
+/* GENERATED FILE - DO NOT EDIT */
+/*
+ * Copyright Altera Corporation (C) 2012-2014. All rights reserved
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *    * Neither the name of Altera Corporation nor the
+ *      names of its contributors may be used to endorse or promote products
+ *      derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _PRELOADER_PLL_CONFIG_H_
+#define _PRELOADER_PLL_CONFIG_H_
+
+#define CONFIG_HPS_DBCTRL_STAYOSC1 (1)
+
+#define CONFIG_HPS_MAINPLLGRP_VCO_DENOM (0)
+#define CONFIG_HPS_MAINPLLGRP_VCO_NUMER (31)
+#define CONFIG_HPS_MAINPLLGRP_MPUCLK_CNT (0)
+#define CONFIG_HPS_MAINPLLGRP_MAINCLK_CNT (0)
+#define CONFIG_HPS_MAINPLLGRP_DBGATCLK_CNT (0)
+#define CONFIG_HPS_MAINPLLGRP_MAINQSPICLK_CNT (3)
+#define CONFIG_HPS_MAINPLLGRP_MAINNANDSDMMCCLK_CNT (511)
+#define CONFIG_HPS_MAINPLLGRP_CFGS2FUSER0CLK_CNT (15)
+#define CONFIG_HPS_MAINPLLGRP_MAINDIV_L3MPCLK (1)
+#define CONFIG_HPS_MAINPLLGRP_MAINDIV_L3SPCLK (1)
+#define CONFIG_HPS_MAINPLLGRP_MAINDIV_L4MPCLK (1)
+#define CONFIG_HPS_MAINPLLGRP_MAINDIV_L4SPCLK (1)
+#define CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGATCLK (0)
+#define CONFIG_HPS_MAINPLLGRP_DBGDIV_DBGCLK (1)
+#define CONFIG_HPS_MAINPLLGRP_TRACEDIV_TRACECLK (0)
+#define CONFIG_HPS_MAINPLLGRP_L4SRC_L4MP (1)
+#define CONFIG_HPS_MAINPLLGRP_L4SRC_L4SP (1)
+
+#define CONFIG_HPS_PERPLLGRP_VCO_DENOM (0)
+#define CONFIG_HPS_PERPLLGRP_VCO_NUMER (19)
+#define CONFIG_HPS_PERPLLGRP_VCO_PSRC (0)
+#define CONFIG_HPS_PERPLLGRP_EMAC0CLK_CNT (511)
+#define CONFIG_HPS_PERPLLGRP_EMAC1CLK_CNT (3)
+#define CONFIG_HPS_PERPLLGRP_PERQSPICLK_CNT (511)
+#define CONFIG_HPS_PERPLLGRP_PERNANDSDMMCCLK_CNT (4)
+#define CONFIG_HPS_PERPLLGRP_PERBASECLK_CNT (4)
+#define CONFIG_HPS_PERPLLGRP_S2FUSER1CLK_CNT (39)
+#define CONFIG_HPS_PERPLLGRP_DIV_USBCLK (0)
+#define CONFIG_HPS_PERPLLGRP_DIV_SPIMCLK (4)
+#define CONFIG_HPS_PERPLLGRP_DIV_CAN0CLK (4)
+#define CONFIG_HPS_PERPLLGRP_DIV_CAN1CLK (4)
+#define CONFIG_HPS_PERPLLGRP_GPIODIV_GPIODBCLK (6249)
+#define CONFIG_HPS_PERPLLGRP_SRC_SDMMC (2)
+#define CONFIG_HPS_PERPLLGRP_SRC_NAND (2)
+#define CONFIG_HPS_PERPLLGRP_SRC_QSPI (1)
+
+#define CONFIG_HPS_SDRPLLGRP_VCO_DENOM (0)
+#define CONFIG_HPS_SDRPLLGRP_VCO_NUMER (15)
+#define CONFIG_HPS_SDRPLLGRP_VCO_SSRC (0)
+#define CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_CNT (1)
+#define CONFIG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE (0)
+#define CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT (0)
+#define CONFIG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE (0)
+#define CONFIG_HPS_SDRPLLGRP_DDRDQCLK_CNT (1)
+#define CONFIG_HPS_SDRPLLGRP_DDRDQCLK_PHASE (4)
+#define CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT (15)
+#define CONFIG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE (0)
+
+#define CONFIG_HPS_CLK_OSC1_HZ (50000000)
+#define CONFIG_HPS_CLK_OSC2_HZ (25000000)
+#define CONFIG_HPS_CLK_F2S_SDR_REF_HZ (0)
+#define CONFIG_HPS_CLK_F2S_PER_REF_HZ (0)
+#define CONFIG_HPS_CLK_MAINVCO_HZ (1600000000)
+#define CONFIG_HPS_CLK_PERVCO_HZ (1000000000)
+#define CONFIG_HPS_CLK_SDRVCO_HZ (800000000)
+#define CONFIG_HPS_CLK_EMAC0_HZ (1953125)
+#define CONFIG_HPS_CLK_EMAC1_HZ (250000000)
+#define CONFIG_HPS_CLK_USBCLK_HZ (200000000)
+#define CONFIG_HPS_CLK_NAND_HZ (50000000)
+#define CONFIG_HPS_CLK_SDMMC_HZ (200000000)
+#define CONFIG_HPS_CLK_QSPI_HZ (400000000)
+#define CONFIG_HPS_CLK_SPIM_HZ (12500000)
+#define CONFIG_HPS_CLK_CAN0_HZ (12500000)
+#define CONFIG_HPS_CLK_CAN1_HZ (12500000)
+#define CONFIG_HPS_CLK_GPIODB_HZ (32000)
+#define CONFIG_HPS_CLK_L4_MP_HZ (100000000)
+#define CONFIG_HPS_CLK_L4_SP_HZ (100000000)
+
+#define CONFIG_HPS_ALTERAGRP_MPUCLK (1)
+#define CONFIG_HPS_ALTERAGRP_MAINCLK (3)
+#define CONFIG_HPS_ALTERAGRP_DBGATCLK (3)
+
+#endif /* _PRELOADER_PLL_CONFIG_H_ */
diff --git a/arch/arm/boards/enclustra-sa2/sdram_config.h b/arch/arm/boards/enclustra-sa2/sdram_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..9b117d845a051cdd12281f029027c8062bddb868
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/sdram_config.h
@@ -0,0 +1,112 @@
+/* GENERATED FILE - DO NOT EDIT */
+/*
+ * Copyright Altera Corporation (C) 2012-2014. All rights reserved
+ *
+ * SPDX-License-Identifier:    BSD-3-Clause
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *    * Neither the name of Altera Corporation nor the
+ *      names of its contributors may be used to endorse or promote products
+ *      derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SDRAM_CONFIG_H
+#define __SDRAM_CONFIG_H
+
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE			(2)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL			(8)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER		(0)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN			(0)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN		(0)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN		(1)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT		(10)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN			(0)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS			(0)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL			(5)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL			(0)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL			(6)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD			(4)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW			(12)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC			(104)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI		(3120)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD		(6)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP		(6)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR		(6)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR		(4)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP			(4)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS			(15)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC			(21)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD			(4)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD			(4)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT		(512)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT		(3)
+#define CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES	(0)
+#define CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES	(8)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS		(10)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS		(16)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS		(3)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS			(1)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH		(32)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH		(8)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN			(0)
+#define CONFIG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK		(3)
+#define CONFIG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL			(2)
+#define CONFIG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA		(0)
+#define CONFIG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH		(2)
+#define CONFIG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN		(0)
+#define CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE			(0)
+#define CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC			(0)
+#define CONFIG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY		(0x0)
+#define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0	(0x21084210)
+#define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32	(0x10441)
+#define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0	(0x78)
+#define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14	(0x0)
+#define CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46	(0x0)
+#define CONFIG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0		(0x200)
+
+#define CONFIG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH		(0x44555)
+#define CONFIG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP		(0x2C011000)
+#define CONFIG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP		(0xB00088)
+#define CONFIG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP		(0x760210)
+#define CONFIG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP		(0x980543)
+#define CONFIG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR		(0x5A56A)
+#define CONFIG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0	(0x20820820)
+#define CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32	(0x8208208)
+#define CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0	(0)
+#define CONFIG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4	(0x41041041)
+#define CONFIG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36	(0x410410)
+#define CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0 \
+(0x01010101)
+#define CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32 \
+(0x01010101)
+#define CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64 \
+(0x0101)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMODT_READ			(0)
+#define CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE			(1)
+#define CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST_READ_PORT_USED	(0x1)
+#define CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST_WRITE_PORT_USED	(0x1)
+#define CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST_COMMAND_PORT_USED	(0x1)
+#define CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST			(0x111)
+
+#define CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR (2)
+#define CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC (2)
+#define CONFIG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP (2)
+
+#endif /*#ifndef__SDRAM_CONFIG_H */
diff --git a/arch/arm/boards/enclustra-sa2/sequencer_auto.h b/arch/arm/boards/enclustra-sa2/sequencer_auto.h
new file mode 100644
index 0000000000000000000000000000000000000000..a740d3ce70d3541b0a382db101635d27c3ebbb82
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/sequencer_auto.h
@@ -0,0 +1,225 @@
+/*
+Copyright (C) 2023  Intel Corporation. All rights reserved.
+
+SPDX-License-Identifier:    BSD-3-Clause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Intel Corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#define __RW_MGR_ac_mrs1 0x04
+#define __RW_MGR_ac_mrs3 0x06
+#define __RW_MGR_ac_write_bank_0_col_0_nodata_wl_1 0x1C
+#define __RW_MGR_ac_act_1 0x11
+#define __RW_MGR_ac_write_postdata 0x1A
+#define __RW_MGR_ac_act_0 0x10
+#define __RW_MGR_ac_des 0x0D
+#define __RW_MGR_ac_init_reset_1_cke_0 0x01
+#define __RW_MGR_ac_write_data 0x19
+#define __RW_MGR_ac_init_reset_0_cke_0 0x00
+#define __RW_MGR_ac_read_bank_0_1_norden 0x22
+#define __RW_MGR_ac_pre_all 0x12
+#define __RW_MGR_ac_mrs0_user 0x02
+#define __RW_MGR_ac_mrs0_dll_reset 0x03
+#define __RW_MGR_ac_read_bank_0_0 0x1D
+#define __RW_MGR_ac_write_bank_0_col_1 0x16
+#define __RW_MGR_ac_read_bank_0_1 0x1F
+#define __RW_MGR_ac_write_bank_1_col_0 0x15
+#define __RW_MGR_ac_write_bank_1_col_1 0x17
+#define __RW_MGR_ac_write_bank_0_col_0 0x14
+#define __RW_MGR_ac_read_bank_1_0 0x1E
+#define __RW_MGR_ac_mrs1_mirr 0x0A
+#define __RW_MGR_ac_read_bank_1_1 0x20
+#define __RW_MGR_ac_des_odt_1 0x0E
+#define __RW_MGR_ac_mrs0_dll_reset_mirr 0x09
+#define __RW_MGR_ac_zqcl 0x07
+#define __RW_MGR_ac_write_predata 0x18
+#define __RW_MGR_ac_mrs0_user_mirr 0x08
+#define __RW_MGR_ac_ref 0x13
+#define __RW_MGR_ac_nop 0x0F
+#define __RW_MGR_ac_rdimm 0x23
+#define __RW_MGR_ac_mrs2_mirr 0x0B
+#define __RW_MGR_ac_write_bank_0_col_0_nodata 0x1B
+#define __RW_MGR_ac_read_en 0x21
+#define __RW_MGR_ac_mrs3_mirr 0x0C
+#define __RW_MGR_ac_mrs2 0x05
+#define __RW_MGR_CONTENT_ac_mrs1 0x10090044
+#define __RW_MGR_CONTENT_ac_mrs3 0x100B0000
+#define __RW_MGR_CONTENT_ac_write_bank_0_col_0_nodata_wl_1 0x18980000
+#define __RW_MGR_CONTENT_ac_act_1 0x106B0000
+#define __RW_MGR_CONTENT_ac_write_postdata 0x38780000
+#define __RW_MGR_CONTENT_ac_act_0 0x10680000
+#define __RW_MGR_CONTENT_ac_des 0x30780000
+#define __RW_MGR_CONTENT_ac_init_reset_1_cke_0 0x20780000
+#define __RW_MGR_CONTENT_ac_write_data 0x3CF80000
+#define __RW_MGR_CONTENT_ac_init_reset_0_cke_0 0x20700000
+#define __RW_MGR_CONTENT_ac_read_bank_0_1_norden 0x10580008
+#define __RW_MGR_CONTENT_ac_pre_all 0x10280400
+#define __RW_MGR_CONTENT_ac_mrs0_user 0x10080421
+#define __RW_MGR_CONTENT_ac_mrs0_dll_reset 0x10080520
+#define __RW_MGR_CONTENT_ac_read_bank_0_0 0x13580000
+#define __RW_MGR_CONTENT_ac_write_bank_0_col_1 0x1C980008
+#define __RW_MGR_CONTENT_ac_read_bank_0_1 0x13580008
+#define __RW_MGR_CONTENT_ac_write_bank_1_col_0 0x1C9B0000
+#define __RW_MGR_CONTENT_ac_write_bank_1_col_1 0x1C9B0008
+#define __RW_MGR_CONTENT_ac_write_bank_0_col_0 0x1C980000
+#define __RW_MGR_CONTENT_ac_read_bank_1_0 0x135B0000
+#define __RW_MGR_CONTENT_ac_mrs1_mirr 0x100A0024
+#define __RW_MGR_CONTENT_ac_read_bank_1_1 0x135B0008
+#define __RW_MGR_CONTENT_ac_des_odt_1 0x38780000
+#define __RW_MGR_CONTENT_ac_mrs0_dll_reset_mirr 0x100804C0
+#define __RW_MGR_CONTENT_ac_zqcl 0x10380400
+#define __RW_MGR_CONTENT_ac_write_predata 0x38F80000
+#define __RW_MGR_CONTENT_ac_mrs0_user_mirr 0x10080441
+#define __RW_MGR_CONTENT_ac_ref 0x10480000
+#define __RW_MGR_CONTENT_ac_nop 0x30780000
+#define __RW_MGR_CONTENT_ac_rdimm 0x10780000
+#define __RW_MGR_CONTENT_ac_mrs2_mirr 0x10090200
+#define __RW_MGR_CONTENT_ac_write_bank_0_col_0_nodata 0x18180000
+#define __RW_MGR_CONTENT_ac_read_en 0x33780000
+#define __RW_MGR_CONTENT_ac_mrs3_mirr 0x100B0000
+#define __RW_MGR_CONTENT_ac_mrs2 0x100A0200
+
+/*
+Copyright (C) 2023  Intel Corporation. All rights reserved.
+
+SPDX-License-Identifier:    BSD-3-Clause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Intel Corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#define __RW_MGR_READ_B2B_WAIT2 0x6B
+#define __RW_MGR_LFSR_WR_RD_BANK_0_WAIT 0x32
+#define __RW_MGR_REFRESH_ALL 0x14
+#define __RW_MGR_ZQCL 0x06
+#define __RW_MGR_LFSR_WR_RD_BANK_0_NOP 0x23
+#define __RW_MGR_LFSR_WR_RD_BANK_0_DQS 0x24
+#define __RW_MGR_ACTIVATE_0_AND_1 0x0D
+#define __RW_MGR_MRS2_MIRR 0x0A
+#define __RW_MGR_INIT_RESET_0_CKE_0 0x6F
+#define __RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT 0x46
+#define __RW_MGR_ACTIVATE_1 0x0F
+#define __RW_MGR_MRS2 0x04
+#define __RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1 0x35
+#define __RW_MGR_MRS1 0x03
+#define __RW_MGR_IDLE_LOOP1 0x7B
+#define __RW_MGR_GUARANTEED_WRITE_WAIT2 0x19
+#define __RW_MGR_MRS3 0x05
+#define __RW_MGR_IDLE_LOOP2 0x7A
+#define __RW_MGR_GUARANTEED_WRITE_WAIT1 0x1F
+#define __RW_MGR_LFSR_WR_RD_BANK_0_DATA 0x25
+#define __RW_MGR_GUARANTEED_WRITE_WAIT3 0x1D
+#define __RW_MGR_RDIMM_CMD 0x79
+#define __RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP 0x37
+#define __RW_MGR_GUARANTEED_WRITE_WAIT0 0x1B
+#define __RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA 0x39
+#define __RW_MGR_GUARANTEED_READ_CONT 0x54
+#define __RW_MGR_REFRESH_DELAY 0x15
+#define __RW_MGR_MRS3_MIRR 0x0B
+#define __RW_MGR_IDLE 0x00
+#define __RW_MGR_READ_B2B 0x59
+#define __RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS 0x38
+#define __RW_MGR_GUARANTEED_WRITE 0x18
+#define __RW_MGR_PRECHARGE_ALL 0x12
+#define __RW_MGR_SGLE_READ 0x7D
+#define __RW_MGR_MRS0_USER_MIRR 0x0C
+#define __RW_MGR_RETURN 0x01
+#define __RW_MGR_LFSR_WR_RD_DM_BANK_0 0x36
+#define __RW_MGR_MRS0_USER 0x07
+#define __RW_MGR_GUARANTEED_READ 0x4C
+#define __RW_MGR_MRS0_DLL_RESET_MIRR 0x08
+#define __RW_MGR_INIT_RESET_1_CKE_0 0x74
+#define __RW_MGR_ACTIVATE_0_AND_1_WAIT2 0x10
+#define __RW_MGR_LFSR_WR_RD_BANK_0_WL_1 0x21
+#define __RW_MGR_MRS0_DLL_RESET 0x02
+#define __RW_MGR_ACTIVATE_0_AND_1_WAIT1 0x0E
+#define __RW_MGR_LFSR_WR_RD_BANK_0 0x22
+#define __RW_MGR_CLEAR_DQS_ENABLE 0x49
+#define __RW_MGR_MRS1_MIRR 0x09
+#define __RW_MGR_READ_B2B_WAIT1 0x61
+#define __RW_MGR_CONTENT_READ_B2B_WAIT2 0x00C680
+#define __RW_MGR_CONTENT_LFSR_WR_RD_BANK_0_WAIT 0x00A680
+#define __RW_MGR_CONTENT_REFRESH_ALL 0x000980
+#define __RW_MGR_CONTENT_ZQCL 0x008380
+#define __RW_MGR_CONTENT_LFSR_WR_RD_BANK_0_NOP 0x00E700
+#define __RW_MGR_CONTENT_LFSR_WR_RD_BANK_0_DQS 0x000C00
+#define __RW_MGR_CONTENT_ACTIVATE_0_AND_1 0x000800
+#define __RW_MGR_CONTENT_MRS2_MIRR 0x008580
+#define __RW_MGR_CONTENT_INIT_RESET_0_CKE_0 0x000000
+#define __RW_MGR_CONTENT_LFSR_WR_RD_DM_BANK_0_WAIT 0x00A680
+#define __RW_MGR_CONTENT_ACTIVATE_1 0x000880
+#define __RW_MGR_CONTENT_MRS2 0x008280
+#define __RW_MGR_CONTENT_LFSR_WR_RD_DM_BANK_0_WL_1 0x00CE00
+#define __RW_MGR_CONTENT_MRS1 0x008200
+#define __RW_MGR_CONTENT_IDLE_LOOP1 0x00A680
+#define __RW_MGR_CONTENT_GUARANTEED_WRITE_WAIT2 0x00CCE8
+#define __RW_MGR_CONTENT_MRS3 0x008300
+#define __RW_MGR_CONTENT_IDLE_LOOP2 0x008680
+#define __RW_MGR_CONTENT_GUARANTEED_WRITE_WAIT1 0x00AC88
+#define __RW_MGR_CONTENT_LFSR_WR_RD_BANK_0_DATA 0x020CE0
+#define __RW_MGR_CONTENT_GUARANTEED_WRITE_WAIT3 0x00EC88
+#define __RW_MGR_CONTENT_RDIMM_CMD 0x009180
+#define __RW_MGR_CONTENT_LFSR_WR_RD_DM_BANK_0_NOP 0x00E700
+#define __RW_MGR_CONTENT_GUARANTEED_WRITE_WAIT0 0x008CE8
+#define __RW_MGR_CONTENT_LFSR_WR_RD_DM_BANK_0_DATA 0x030CE0
+#define __RW_MGR_CONTENT_GUARANTEED_READ_CONT 0x001168
+#define __RW_MGR_CONTENT_REFRESH_DELAY 0x00A680
+#define __RW_MGR_CONTENT_MRS3_MIRR 0x008600
+#define __RW_MGR_CONTENT_IDLE 0x080000
+#define __RW_MGR_CONTENT_READ_B2B 0x040E88
+#define __RW_MGR_CONTENT_LFSR_WR_RD_DM_BANK_0_DQS 0x000C00
+#define __RW_MGR_CONTENT_GUARANTEED_WRITE 0x000B68
+#define __RW_MGR_CONTENT_PRECHARGE_ALL 0x000900
+#define __RW_MGR_CONTENT_SGLE_READ 0x040F08
+#define __RW_MGR_CONTENT_MRS0_USER_MIRR 0x008400
+#define __RW_MGR_CONTENT_RETURN 0x080680
+#define __RW_MGR_CONTENT_LFSR_WR_RD_DM_BANK_0 0x00CD80
+#define __RW_MGR_CONTENT_MRS0_USER 0x008100
+#define __RW_MGR_CONTENT_GUARANTEED_READ 0x001168
+#define __RW_MGR_CONTENT_MRS0_DLL_RESET_MIRR 0x008480
+#define __RW_MGR_CONTENT_INIT_RESET_1_CKE_0 0x000080
+#define __RW_MGR_CONTENT_ACTIVATE_0_AND_1_WAIT2 0x00A680
+#define __RW_MGR_CONTENT_LFSR_WR_RD_BANK_0_WL_1 0x00CE00
+#define __RW_MGR_CONTENT_MRS0_DLL_RESET 0x008180
+#define __RW_MGR_CONTENT_ACTIVATE_0_AND_1_WAIT1 0x008680
+#define __RW_MGR_CONTENT_LFSR_WR_RD_BANK_0 0x00CD80
+#define __RW_MGR_CONTENT_CLEAR_DQS_ENABLE 0x001158
+#define __RW_MGR_CONTENT_MRS1_MIRR 0x008500
+#define __RW_MGR_CONTENT_READ_B2B_WAIT1 0x00A680
diff --git a/arch/arm/boards/enclustra-sa2/sequencer_auto_ac_init.c b/arch/arm/boards/enclustra-sa2/sequencer_auto_ac_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..5bea3ae501044510541fcae3d871d3a9465e1f04
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/sequencer_auto_ac_init.c
@@ -0,0 +1,67 @@
+/*
+Copyright (C) 2023  Intel Corporation. All rights reserved.
+
+SPDX-License-Identifier:    BSD-3-Clause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Intel Corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+static const uint32_t ac_rom_init_size = 36;
+static const uint32_t ac_rom_init[36] = {
+	0x20700000,
+	0x20780000,
+	0x10080421,
+	0x10080520,
+	0x10090044,
+	0x100a0200,
+	0x100b0000,
+	0x10380400,
+	0x10080441,
+	0x100804c0,
+	0x100a0024,
+	0x10090200,
+	0x100b0000,
+	0x30780000,
+	0x38780000,
+	0x30780000,
+	0x10680000,
+	0x106b0000,
+	0x10280400,
+	0x10480000,
+	0x1c980000,
+	0x1c9b0000,
+	0x1c980008,
+	0x1c9b0008,
+	0x38f80000,
+	0x3cf80000,
+	0x38780000,
+	0x18180000,
+	0x18980000,
+	0x13580000,
+	0x135b0000,
+	0x13580008,
+	0x135b0008,
+	0x33780000,
+	0x10580008,
+	0x10780000
+};
diff --git a/arch/arm/boards/enclustra-sa2/sequencer_auto_inst_init.c b/arch/arm/boards/enclustra-sa2/sequencer_auto_inst_init.c
new file mode 100644
index 0000000000000000000000000000000000000000..c3c79973ad412ea720fae64acbe0732dcca28f30
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/sequencer_auto_inst_init.c
@@ -0,0 +1,158 @@
+/*
+Copyright (C) 2023  Intel Corporation. All rights reserved.
+
+SPDX-License-Identifier:    BSD-3-Clause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Intel Corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+static const uint32_t inst_rom_init_size = 127;
+static const uint32_t inst_rom_init[127] = {
+	0x80000,
+	0x80680,
+	0x8180,
+	0x8200,
+	0x8280,
+	0x8300,
+	0x8380,
+	0x8100,
+	0x8480,
+	0x8500,
+	0x8580,
+	0x8600,
+	0x8400,
+	0x800,
+	0x8680,
+	0x880,
+	0xa680,
+	0x80680,
+	0x900,
+	0x80680,
+	0x980,
+	0xa680,
+	0x8680,
+	0x80680,
+	0xb68,
+	0xcce8,
+	0xae8,
+	0x8ce8,
+	0xb88,
+	0xec88,
+	0xa08,
+	0xac88,
+	0x80680,
+	0xce00,
+	0xcd80,
+	0xe700,
+	0xc00,
+	0x20ce0,
+	0x20ce0,
+	0x20ce0,
+	0x20ce0,
+	0xd00,
+	0x680,
+	0x680,
+	0x680,
+	0x680,
+	0x60e80,
+	0x61080,
+	0x61080,
+	0x61080,
+	0xa680,
+	0x8680,
+	0x80680,
+	0xce00,
+	0xcd80,
+	0xe700,
+	0xc00,
+	0x30ce0,
+	0x30ce0,
+	0x30ce0,
+	0x30ce0,
+	0xd00,
+	0x680,
+	0x680,
+	0x680,
+	0x680,
+	0x70e80,
+	0x71080,
+	0x71080,
+	0x71080,
+	0xa680,
+	0x8680,
+	0x80680,
+	0x1158,
+	0x6d8,
+	0x80680,
+	0x1168,
+	0x7e8,
+	0x7e8,
+	0x87e8,
+	0x40fe8,
+	0x410e8,
+	0x410e8,
+	0x410e8,
+	0x1168,
+	0x7e8,
+	0x7e8,
+	0xa7e8,
+	0x80680,
+	0x40e88,
+	0x41088,
+	0x41088,
+	0x41088,
+	0x40f68,
+	0x410e8,
+	0x410e8,
+	0x410e8,
+	0xa680,
+	0x40fe8,
+	0x410e8,
+	0x410e8,
+	0x410e8,
+	0x41008,
+	0x41088,
+	0x41088,
+	0x41088,
+	0x1100,
+	0xc680,
+	0x8680,
+	0xe680,
+	0x80680,
+	0x0,
+	0x8000,
+	0xa000,
+	0xc000,
+	0x80000,
+	0x80,
+	0x8080,
+	0xa080,
+	0xc080,
+	0x80080,
+	0x9180,
+	0x8680,
+	0xa680,
+	0x80680,
+	0x40f08,
+	0x80680
+};
diff --git a/arch/arm/boards/enclustra-sa2/sequencer_defines.h b/arch/arm/boards/enclustra-sa2/sequencer_defines.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6c5dda6fa34c4eee4063258984765b1a38594b0
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/sequencer_defines.h
@@ -0,0 +1,165 @@
+/*
+Copyright (C) 2016 Intel Corporation
+All rights reserved.
+
+SPDX-License-Identifier:    BSD-3-Clause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Altera Corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ALTERA CORPORATION BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _SEQUENCER_DEFINES_H_
+#define _SEQUENCER_DEFINES_H_
+
+#define AC_ROM_MR1_MIRR 0000000100100
+#define AC_ROM_MR1_OCD_ENABLE
+#define AC_ROM_MR2_MIRR 0001000000000
+#define AC_ROM_MR3_MIRR 0000000000000
+#define AC_ROM_MR0_CALIB
+#define AC_ROM_MR0_DLL_RESET_MIRR 0010011000000
+#define AC_ROM_MR0_DLL_RESET 0010100100000
+#define AC_ROM_MR0_MIRR 0010001000001
+#define AC_ROM_MR0 0010000100001
+#define AC_ROM_MR1 0000001000100
+#define AC_ROM_MR2 0001000000000
+#define AC_ROM_MR3 0000000000000
+#define AC_ROM_USER_ADD_0 0_0000_0000_0000
+#define AC_ROM_USER_ADD_1 0_0000_0000_1000
+#define AFI_CLK_FREQ 401
+#define AFI_RATE_RATIO 1
+#define AP_MODE 0
+#define ARRIAVGZ 0
+#define ARRIAV 0
+#define AVL_CLK_FREQ 67
+#define BFM_MODE 0
+#define BURST2 0
+#define CALIBRATE_BIT_SLIPS 0
+#define CALIB_LFIFO_OFFSET 7
+#define CALIB_VFIFO_OFFSET 5
+#define CYCLONEV 1
+#define DDR2 0
+#define DDR3 1
+#define DDRX 1
+#define DM_PINS_ENABLED 1
+#define ENABLE_ASSERT 0
+#define ENABLE_BRINGUP_DEBUGGING 0
+#define ENABLE_DELAY_CHAIN_WRITE 0
+#define ENABLE_DQS_IN_CENTERING 1
+#define ENABLE_DQS_OUT_CENTERING 0
+#define ENABLE_EXPORT_SEQ_DEBUG_BRIDGE 0
+#define ENABLE_INST_ROM_WRITE 1
+#define ENABLE_MARGIN_REPORT_GEN 0
+#define ENABLE_NON_DESTRUCTIVE_CALIB 0
+#define ENABLE_NON_DES_CAL_TEST 0
+#define ENABLE_NON_DES_CAL 0
+#define ENABLE_SUPER_QUICK_CALIBRATION 0
+#define ENABLE_TCL_DEBUG 0
+#define FAKE_CAL_FAIL 0
+#define FIX_READ_LATENCY 8
+#define FULL_RATE 1
+#define GUARANTEED_READ_BRINGUP_TEST 0
+#define HALF_RATE 0
+#define HARD_PHY 1
+#define HARD_VFIFO 1
+#define HCX_COMPAT_MODE 0
+#define HHP_HPS_SIMULATION 0
+#define HHP_HPS_VERIFICATION 0
+#define HHP_HPS 1
+#define HPS_HW 1
+#define HR_DDIO_OUT_HAS_THREE_REGS 0
+#define IO_DELAY_PER_DCHAIN_TAP 25
+#define IO_DELAY_PER_DQS_EN_DCHAIN_TAP 25
+#define IO_DELAY_PER_OPA_TAP 312
+#define IO_DLL_CHAIN_LENGTH 8
+#define IO_DM_OUT_RESERVE 0
+#define IO_DQDQS_OUT_PHASE_MAX 0
+#define IO_DQS_EN_DELAY_MAX 31
+#define IO_DQS_EN_DELAY_OFFSET 0
+#define IO_DQS_EN_PHASE_MAX 7
+#define IO_DQS_IN_DELAY_MAX 31
+#define IO_DQS_IN_RESERVE 4
+#define IO_DQS_OUT_RESERVE 4
+#define IO_DQ_OUT_RESERVE 0
+#define IO_IO_IN_DELAY_MAX 31
+#define IO_IO_OUT1_DELAY_MAX 31
+#define IO_IO_OUT2_DELAY_MAX 0
+#define IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS 0
+#define LPDDR1 0
+#define LPDDR2 0
+#define LRDIMM 0
+#define MARGIN_VARIATION_TEST 0
+#define MAX_LATENCY_COUNT_WIDTH 5
+#define MEM_ADDR_WIDTH 13
+#define MRS_MIRROR_PING_PONG_ATSO 0
+#define MULTIPLE_AFI_WLAT 0
+#define NON_DES_CAL 0
+#define NUM_SHADOW_REGS 1
+#define QDRII 0
+#define QUARTER_RATE 0
+#define RDIMM 0
+#define READ_AFTER_WRITE_CALIBRATION 1
+#define READ_VALID_FIFO_SIZE 16
+#define REG_FILE_INIT_SEQ_SIGNATURE 0x555504dd
+#define RLDRAM3 0
+#define RLDRAMII 0
+#define RLDRAMX 0
+#define RUNTIME_CAL_REPORT 0
+#define RW_MGR_MEM_ADDRESS_MIRRORING 0
+#define RW_MGR_MEM_ADDRESS_WIDTH 16
+#define RW_MGR_MEM_BANK_WIDTH 3
+#define RW_MGR_MEM_CHIP_SELECT_WIDTH 1
+#define RW_MGR_MEM_CLK_EN_WIDTH 1
+#define RW_MGR_MEM_CONTROL_WIDTH 1
+#define RW_MGR_MEM_DATA_MASK_WIDTH 4
+#define RW_MGR_MEM_DATA_WIDTH 32
+#define RW_MGR_MEM_DQ_PER_READ_DQS 8
+#define RW_MGR_MEM_DQ_PER_WRITE_DQS 8
+#define RW_MGR_MEM_IF_READ_DQS_WIDTH 4
+#define RW_MGR_MEM_IF_WRITE_DQS_WIDTH 4
+#define RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM 1
+#define RW_MGR_MEM_NUMBER_OF_RANKS 1
+#define RW_MGR_MEM_ODT_WIDTH 1
+#define RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS 1
+#define RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS 1
+#define RW_MGR_MR0_BL 1
+#define RW_MGR_MR0_CAS_LATENCY 2
+#define RW_MGR_TRUE_MEM_DATA_MASK_WIDTH 4
+#define RW_MGR_WRITE_TO_DEBUG_READ 1.0
+#define SET_FIX_READ_LATENCY_ENABLE 0
+#define SKEW_CALIBRATION 0
+#define SKIP_PTAP_0_DQS_EN_CAL 1
+#define STATIC_FULL_CALIBRATION 1
+#define STATIC_SIM_FILESET 0
+#define STATIC_SKIP_MEM_INIT 0
+#define STRATIXV 0
+#define TINIT_CNTR1_VAL 32
+#define TINIT_CNTR2_VAL 32
+#define TINIT_CNTR0_VAL 99
+#define TRACKING_ERROR_TEST 0
+#define TRACKING_WATCH_TEST 0
+#define TRESET_CNTR1_VAL 99
+#define TRESET_CNTR2_VAL 10
+#define TRESET_CNTR0_VAL 99
+#define USE_DQS_TRACKING 1
+#define USE_SHADOW_REGS 0
+#define USE_USER_RDIMM_VALUE 0
+
+#endif /* _SEQUENCER_DEFINES_H_ */

-- 
2.43.0




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

* [PATCH v2 02/10] Add Enclustra Mercury+ SA2 module
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
  2025-09-25 11:59 ` [PATCH v2 01/10] Add handoff files David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-25 11:59 ` [PATCH v2 03/10] ARM: dts: socfpga: use upstream SA2 device tree David Picard
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

Implement the files necessary to support the Enclustra Mercury+ SA2
module (SoM).

Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
---
 arch/arm/boards/Makefile                      |  1 +
 arch/arm/boards/enclustra-sa2/Makefile        |  2 ++
 arch/arm/boards/enclustra-sa2/board.c         | 34 +++++++++++++++++++++++++++
 arch/arm/boards/enclustra-sa2/lowlevel.c      | 15 ++++++++++++
 arch/arm/configs/socfpga-xload_defconfig      |  1 +
 arch/arm/configs/socfpga_defconfig            |  3 +--
 arch/arm/dts/Makefile                         |  1 +
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts | 31 ++++++++++++++++++++++++
 arch/arm/mach-socfpga/Kconfig                 |  4 ++++
 images/Makefile.socfpga                       |  8 +++++++
 10 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index c851e1546bd6e0840a4361a53f60852df07c0a95..61cc7b056607e7e87b277e37c4bc3376ad252593 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -120,6 +120,7 @@ obj-$(CONFIG_MACH_SOCFPGA_ALTERA_SOCDK)		+= altera-socdk/
 obj-$(CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE)	+= arrow-axe5-eagle/
 obj-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES)		+= ebv-socrates/
 obj-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_AA1)	+= enclustra-aa1/
+obj-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2)	+= enclustra-sa2/
 obj-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES)	+= reflex-achilles/
 obj-$(CONFIG_MACH_SOCFPGA_TERASIC_DE0_NANO_SOC)	+= terasic-de0-nano-soc/
 obj-$(CONFIG_MACH_SOCFPGA_TERASIC_DE10_NANO)	+= terasic-de10-nano/
diff --git a/arch/arm/boards/enclustra-sa2/Makefile b/arch/arm/boards/enclustra-sa2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8c927fe291a6b3eb20a32a2db96c73f231ab4697
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/Makefile
@@ -0,0 +1,2 @@
+obj-y += lowlevel.o board.o
+pbl-y += lowlevel.o
diff --git a/arch/arm/boards/enclustra-sa2/board.c b/arch/arm/boards/enclustra-sa2/board.c
new file mode 100644
index 0000000000000000000000000000000000000000..d3117e9a1058738ea541f45b28c6a95184331554
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/board.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <common.h>
+#include <types.h>
+#include <driver.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <linux/mdio.h>
+#include <linux/micrel_phy.h>
+#include <linux/phy.h>
+#include <linux/sizes.h>
+#include <fcntl.h>
+#include <fs.h>
+#include <mach/socfpga/cyclone5-regs.h>
+
+/*
+ * Ethernet PHY: Microchip/Micrel KSZ9031RNX
+ */
+static int phy_fixup(struct phy_device *dev)
+{
+	return 0;
+}
+
+static int socfpga_init(void)
+{
+	if (!of_machine_is_compatible("enclustra,mercury-sa2"))
+		return 0;
+
+	if (IS_ENABLED(CONFIG_PHYLIB))
+		phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK, phy_fixup);
+
+	return 0;
+}
+console_initcall(socfpga_init);
diff --git a/arch/arm/boards/enclustra-sa2/lowlevel.c b/arch/arm/boards/enclustra-sa2/lowlevel.c
new file mode 100644
index 0000000000000000000000000000000000000000..08744756949f96c041e255963362f04c4d3d186a
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/lowlevel.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "sdram_config.h"
+#include "pinmux_config.c"
+#include "pll_config.h"
+#include "sequencer_defines.h"
+#include "sequencer_auto.h"
+#include "sequencer_auto_inst_init.c"
+#include "sequencer_auto_ac_init.c"
+#include "iocsr_config_cyclone5.c"
+
+#include <mach/socfpga/lowlevel.h>
+
+SOCFPGA_C5_ENTRY(start_socfpga_sa2, socfpga_cyclone5_mercury_sa2, SZ_1G);
+SOCFPGA_C5_XLOAD_ENTRY(start_socfpga_sa2_xload, SZ_1G);
diff --git a/arch/arm/configs/socfpga-xload_defconfig b/arch/arm/configs/socfpga-xload_defconfig
index 892f1d24cb268387668ed064db48c674dbbf4ef8..00841b8530ded7f09a16c6c3b957ecd902211ec2 100644
--- a/arch/arm/configs/socfpga-xload_defconfig
+++ b/arch/arm/configs/socfpga-xload_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARCH_SOCFPGA=y
 CONFIG_ARCH_SOCFPGA_XLOAD=y
 CONFIG_MACH_SOCFPGA_ALTERA_SOCDK=y
 CONFIG_MACH_SOCFPGA_EBV_SOCRATES=y
+CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2=y
 CONFIG_MACH_SOCFPGA_TERASIC_DE0_NANO_SOC=y
 CONFIG_MACH_SOCFPGA_TERASIC_DE10_NANO=y
 CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT=y
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index a24934cd8bda229fea6a41d94d5c049bff585699..e9b93bc19775667d70ce02a01ab4dcae26053b86 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -1,8 +1,7 @@
 CONFIG_ARCH_SOCFPGA=y
 CONFIG_MACH_SOCFPGA_ALTERA_SOCDK=y
 CONFIG_MACH_SOCFPGA_EBV_SOCRATES=y
-CONFIG_MACH_SOCFPGA_ENCLUSTRA_AA1=y
-CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES=y
+CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2=y
 CONFIG_MACH_SOCFPGA_TERASIC_DE0_NANO_SOC=y
 CONFIG_MACH_SOCFPGA_TERASIC_DE10_NANO=y
 CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT=y
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 021573a266ca30d46ce0a2dc9083a61461949540..5d04636cd3946084d66596a90c276b119f9dcb2c 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -142,6 +142,7 @@ lwl-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += imx6sx-sdb.dtb.o
 lwl-$(CONFIG_MACH_SOCFPGA_ALTERA_SOCDK) += socfpga_cyclone5_socdk.dtb.o
 lwl-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += socfpga_cyclone5_socrates.dtb.o
 lwl-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_AA1) += socfpga_arria10_mercury_aa1.dtb.o
+lwl-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2) += socfpga_cyclone5_mercury_sa2.dtb.o
 lwl-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += socfpga_arria10_achilles.dtb.o
 lwl-$(CONFIG_MACH_SOCFPGA_TERASIC_DE0_NANO_SOC) += socfpga_cyclone5_de0_nano_soc.dtb.o
 lwl-$(CONFIG_MACH_SOCFPGA_TERASIC_DE10_NANO) += socfpga_cyclone5_de10_nano.dtb.o
diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts
new file mode 100644
index 0000000000000000000000000000000000000000..9e2f2c1af19e68c0c662f62bc154856f75df2510
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (C) 2025 David Picard <david.picard@clermont.in2p3.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <arm/intel/socfpga/socfpga_cyclone5_mercury_sa2.dts>
+#include "socfpga.dtsi"
+
+/ {
+	chosen {
+		stdout-path = &uart0;
+
+		environment {
+			compatible = "barebox,environment";
+			device-path = &mmc, "partname:1";
+			file-path = "barebox.env";
+		};
+	};
+};
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index f0dce3bad0429d38840975a2f3c3640731e7a605..61935c260c8f06acec119377af7d46411e3e2744 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -38,6 +38,10 @@ config MACH_SOCFPGA_EBV_SOCRATES
 	select ARCH_SOCFPGA_CYCLONE5
 	bool "EBV Socrates"
 
+config MACH_SOCFPGA_ENCLUSTRA_SA2
+	select ARCH_SOCFPGA_CYCLONE5
+	bool "Enclustra SA2"
+
 config MACH_SOCFPGA_TERASIC_DE0_NANO_SOC
 	select ARCH_SOCFPGA_CYCLONE5
 	bool "Terasic DE0-NANO-SoC aka Atlas"
diff --git a/images/Makefile.socfpga b/images/Makefile.socfpga
index db1a47b6a1ad7f6a7d08036bdeed6a50b707ac47..ec1bce5079c9e1b334f6ae8225f9d91282615b6d 100644
--- a/images/Makefile.socfpga
+++ b/images/Makefile.socfpga
@@ -59,6 +59,14 @@ pblb-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_AA1) += start_socfpga_aa1_bringup
 FILE_barebox-socfpga-aa1-bringup.img = start_socfpga_aa1_bringup.pblb
 socfpga-barebox-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_AA1) += barebox-socfpga-aa1-bringup.img
 
+pblb-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2) += start_socfpga_sa2_xload
+FILE_barebox-socfpga-sa2-xload.img = start_socfpga_sa2_xload.pblb.socfpgaimg
+socfpga-xload-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2) += barebox-socfpga-sa2-xload.img
+
+pblb-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2) += start_socfpga_sa2
+FILE_barebox-socfpga-sa2.img = start_socfpga_sa2.pblb
+socfpga-barebox-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2) += barebox-socfpga-sa2.img
+
 pblb-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += start_socfpga_achilles_xload
 FILE_barebox-socfpga-achilles-xload.img = start_socfpga_achilles_xload.pblb.socfpgaimg
 socfpga-barebox-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += barebox-socfpga-achilles-xload.img

-- 
2.43.0




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

* [PATCH v2 03/10] ARM: dts: socfpga: use upstream SA2 device tree
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
  2025-09-25 11:59 ` [PATCH v2 01/10] Add handoff files David Picard
  2025-09-25 11:59 ` [PATCH v2 02/10] Add Enclustra Mercury+ SA2 module David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-25 11:59 ` [PATCH v2 04/10] ARM: dts: socfpga: adapt " David Picard
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard, Ahmad Fatoum

The devicetree files from the Enclustra BSP are outdated and not
compatible with what barebox expects. Use the upstream SoC devicetree
imported from Linux instead. For the board itself, we import the
devicetree in the most recent posting[1] to the kernel mailing lists.

[1]: https://lore.kernel.org/all/20241116131025.114542-1-l.rubusch@gmail.com/

Co-developed-by: Ahmad Fatoum <ahmad@a3f.at>
Signed-off-by: Ahmad Fatoum <ahmad@a3f.at>
Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
---
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts  |  18 +--
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi | 150 +++++++++++++++++++++++++
 2 files changed, 152 insertions(+), 16 deletions(-)

diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts
index 9e2f2c1af19e68c0c662f62bc154856f75df2510..2e69f33b030a144d08d55eacb01fd69b009f38e8 100644
--- a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts
+++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts
@@ -1,27 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
  *  Copyright (C) 2025 David Picard <david.picard@clermont.in2p3.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <arm/intel/socfpga/socfpga_cyclone5_mercury_sa2.dts>
+#include "socfpga_cyclone5_mercury_sa2.dtsi"
 #include "socfpga.dtsi"
 
 / {
 	chosen {
-		stdout-path = &uart0;
-
 		environment {
 			compatible = "barebox,environment";
 			device-path = &mmc, "partname:1";
diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..73bd75fcf224fbf31fce27dda6566d4bfe37d624
--- /dev/null
+++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0+ OR MIT
+/*
+ * Copyright (C) 2024 Enclustra GmbH - https://www.enclustra.com
+ *
+ * TODO: This whole file should be dropped, once the patches[1] are upstream
+ * and synced into barebox dts/src/arm.
+ * [1]: https://lore.kernel.org/all/20241116131025.114542-1-l.rubusch@gmail.com/
+ */
+
+#include <arm/intel/socfpga/socfpga_cyclone5.dtsi>
+
+/ {
+	model = "Enclustra Mercury+ SA2";
+	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		ethernet0 = &gmac1;
+	};
+
+	/* Adjusted the i2c labels to use generic base-board dtsi files for
+	 * Enclustra Arria10 and Cyclone5 SoMs.
+	 *
+	 * The set of i2c0 and i2c1 labels defined in socfpga_cyclone5.dtsi and in
+	 * socfpga_arria10.dtsi do not allow for using the same base-board .dtsi
+	 * fragments. Thus define generic labels here to match the correct i2c
+	 * bus in a generic base-board .dtsi file.
+	 */
+	soc {
+		i2c_encl: i2c@ffc04000 {
+		};
+		i2c_encl_fpga: i2c@ffc05000 {
+		};
+	};
+
+	memory {
+		name = "memory";
+		device_type = "memory";
+		reg = <0x0 0x80000000>; /* 2GB */
+	};
+};
+
+&osc1 {
+	clock-frequency = <50000000>;
+};
+
+&i2c_encl {
+	i2c-sda-hold-time-ns = <300>;
+	clock-frequency = <100000>;
+	status = "okay";
+
+	isl12020: rtc@6f {
+		compatible = "isil,isl12022";
+		reg = <0x6f>;
+	};
+
+	atsha204a: crypto@64 {
+		compatible = "atmel,atsha204a";
+		reg = <0x64>;
+	};
+};
+
+&i2c_encl_fpga {
+	i2c-sda-hold-time-ns = <300>;
+	status = "disabled";
+};
+
+&uart0 {
+	clock-frequency = <100000000>;
+};
+
+&mmc0 {
+	status = "okay";
+};
+
+&qspi {
+	status = "okay";
+
+	flash0: flash@0 {
+		u-boot,dm-pre-reloc;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spansion,s25fl512s", "jedec,spi-nor";
+		reg = <0>;
+
+		spi-rx-bus-width = <4>;
+		spi-tx-bus-width = <4>;
+		spi-max-frequency = <10000000>;
+
+		cdns,read-delay = <4>;
+		cdns,tshsl-ns = <50>;
+		cdns,tsd2d-ns = <50>;
+		cdns,tchsh-ns = <4>;
+		cdns,tslch-ns = <4>;
+
+		partition@raw {
+			label = "Flash Raw";
+			reg = <0x0 0x4000000>;
+		};
+	};
+};
+
+&gpio0 {
+	status = "okay";
+};
+
+&gpio1 {
+	status = "okay";
+};
+
+&gmac1 {
+	status = "okay";
+	/delete-property/ mac-address;
+	phy-mode = "rgmii";
+	phy-handle = <&phy3>;
+
+	mdio0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,dwmac-mdio";
+
+		phy3: ethernet-phy@3 {
+			reg = <3>;
+
+			/* Add 2ns RX clock delay (1.2ns + 0.78ns)*/
+			rxc-skew-ps = <1680>;
+			rxd0-skew-ps = <420>;
+			rxd1-skew-ps = <420>;
+			rxd2-skew-ps = <420>;
+			rxd3-skew-ps = <420>;
+			rxdv-skew-ps = <420>;
+
+			/* Add 1.38ns TX clock delay (0.96ns + 0.42ns)*/
+			txc-skew-ps = <1860>;
+			txd0-skew-ps = <0>;
+			txd1-skew-ps = <0>;
+			txd2-skew-ps = <0>;
+			txd3-skew-ps = <0>;
+			txen-skew-ps = <0>;
+		};
+	};
+};
+
+&usb1 {
+	status = "okay";
+	dr_mode = "host";
+};

-- 
2.43.0




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

* [PATCH v2 04/10] ARM: dts: socfpga: adapt upstream SA2 device tree
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (2 preceding siblings ...)
  2025-09-25 11:59 ` [PATCH v2 03/10] ARM: dts: socfpga: use upstream SA2 device tree David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-25 11:59 ` [PATCH v2 05/10] boards: enclustra-sa2: read MAC address from EEPROM David Picard
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

Adapt the upstream devicetree file:
- use new Barebox deep-probe feature
- make the compatible string more specific
- enable LWHPS2FPGA and HPS2FPGA bridges to allow data exchange between
  FPGA and HPS

Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
---
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi | 35 ++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
index 73bd75fcf224fbf31fce27dda6566d4bfe37d624..fa80b7c63d28d17a24d63ac3ee87531ad320ddb1 100644
--- a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
@@ -9,9 +9,14 @@
 
 #include <arm/intel/socfpga/socfpga_cyclone5.dtsi>
 
+/ {
+	barebox,deep-probe;
+};
+
 / {
 	model = "Enclustra Mercury+ SA2";
-	compatible = "altr,socfpga-cyclone5", "altr,socfpga";
+	compatible = "enclustra,mercury-sa2-st1", "enclustra,mercury-sa2", "altr,socfpga-cyclone5", "altr,socfpga";
+
 
 	chosen {
 		stdout-path = "serial0:115200n8";
@@ -47,6 +52,16 @@ &osc1 {
 	clock-frequency = <50000000>;
 };
 
+&fpga_bridge0 {
+	status = "okay";
+	bridge-enable = <0x1>;
+};
+
+&fpga_bridge1 {
+	status = "okay";
+	bridge-enable = <0x1>;
+};
+
 &i2c_encl {
 	i2c-sda-hold-time-ns = <300>;
 	clock-frequency = <100000>;
@@ -57,7 +72,8 @@ isl12020: rtc@6f {
 		reg = <0x6f>;
 	};
 
-	atsha204a: crypto@64 {
+	atsha204a: atsha204a@64 {
+		status = "okay";
 		compatible = "atmel,atsha204a";
 		reg = <0x64>;
 	};
@@ -125,6 +141,21 @@ mdio0 {
 		phy3: ethernet-phy@3 {
 			reg = <3>;
 
+			/*
+			Ethernet PHY reset pin (active low, GPIO44) :
+			- 1st field: GPIO controller phandle
+			- 2nd field: GPIO line offset
+			- 3rd field: flags (see gpio.txt)
+
+			Reference:
+			- Cyclone 5 HPS technical reference, table 23-1: GPIO44 is on controller
+			GPIO1, whose 1st line is GPIO29. The offset is thus 44 - 29 = 15.
+			- Linux documentation:
+				- Documentation/devicetree/bindings/gpio/gpio.txt
+				- Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml
+			*/
+			reset-gpios = <&portb 15 0x01>;
+
 			/* Add 2ns RX clock delay (1.2ns + 0.78ns)*/
 			rxc-skew-ps = <1680>;
 			rxd0-skew-ps = <420>;

-- 
2.43.0




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

* [PATCH v2 05/10] boards: enclustra-sa2: read MAC address from EEPROM
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (3 preceding siblings ...)
  2025-09-25 11:59 ` [PATCH v2 04/10] ARM: dts: socfpga: adapt " David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-26 12:40   ` Sascha Hauer
  2025-09-25 11:59 ` [PATCH v2 06/10] boards: enclustra-sa2: configure SI5338 David Picard
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>

---
v1 --> v2:
  - Use the atsha204a driver to read the MAC address instead of
    board-specific code.
---
---
 arch/arm/boards/enclustra-sa2/board.c          | 74 +++++++++++++++++++++++++-
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi | 16 +++++-
 2 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boards/enclustra-sa2/board.c b/arch/arm/boards/enclustra-sa2/board.c
index d3117e9a1058738ea541f45b28c6a95184331554..4c2b44252d84c78ed8de5754051d0bf194ce8d02 100644
--- a/arch/arm/boards/enclustra-sa2/board.c
+++ b/arch/arm/boards/enclustra-sa2/board.c
@@ -12,6 +12,12 @@
 #include <fcntl.h>
 #include <fs.h>
 #include <mach/socfpga/cyclone5-regs.h>
+#include <net.h>
+#include <linux/nvmem-consumer.h>
+
+/** Enclustra's MAC address vendor prefix is 20:B0:F7 */
+#define ENCLUSTRA_PREFIX            (0x20b0f7)
+#define MAC_ADDR_NUM_BYTES          (6)
 
 /*
  * Ethernet PHY: Microchip/Micrel KSZ9031RNX
@@ -21,14 +27,78 @@ static int phy_fixup(struct phy_device *dev)
 	return 0;
 }
 
+/*
+ * Read the MAC address via the atsha204a driver.
+ *
+ * Set two consecutive MAC addresses, as specified by the manufacturer.
+ */
+static void set_mac_addr(void)
+{
+	uint8_t hwaddr[MAC_ADDR_NUM_BYTES] = { 0, 0, 0, 0, 0, 0 };
+	uint32_t hwaddr_prefix;
+	u8 *data = NULL;
+	static const char * const aliases[] = { "ethernet0" };
+	struct device_node *np, *root;
+	/* Fallback MAC addresses, used if we can't read from EEPROM: */
+	const uint8_t enclustra_ethaddr_fallback1[] = { 0x20, 0xB0, 0xF7, 0x01,
+													0x02, 0x03 };
+	const uint8_t enclustra_ethaddr_fallback2[] = { 0x20, 0xB0, 0xF7, 0x01,
+													0x02, 0x04 };
+
+	root = of_get_root_node();
+
+	for (int i = 0; i < ARRAY_SIZE(aliases); i++) {
+		const char *alias = aliases[i];
+		np = of_find_node_by_alias(root, alias);
+		if (!np) {
+			pr_warn("%s() >> ERROR: can't find alias %s\n", __func__, alias);
+			continue;
+		}
+		data = nvmem_cell_get_and_read(np, "mac-address", MAC_ADDR_NUM_BYTES);
+		if (IS_ERR(data)) {
+			pr_warn("%s() >> ERROR: can't read NVMEM cell\n", __func__);
+			data = NULL;
+		}
+	}
+	if (!data)
+		goto fallback_addr;
+
+	memcpy(hwaddr, data, MAC_ADDR_NUM_BYTES);
+
+	debug("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+		  hwaddr[0], hwaddr[1], hwaddr[2],
+		  hwaddr[3], hwaddr[4], hwaddr[5]);
+
+	/* check vendor prefix and set the environment variable */
+	hwaddr_prefix = (hwaddr[0] << 16) | (hwaddr[1] << 8) | (hwaddr[2]);
+	if (hwaddr_prefix == ENCLUSTRA_PREFIX) {
+		eth_register_ethaddr(0, hwaddr);
+		hwaddr[5]++;    /* calculate 2nd, consecutive MAC address */
+		eth_register_ethaddr(1, hwaddr);
+	} else {
+		printf("%s() >> ERROR: invalid MAC address vendor prefix,"
+			   "using fallback addresses\n", __func__);
+		goto fallback_addr;
+	}
+
+	return;
+
+fallback_addr:
+	eth_register_ethaddr(0, enclustra_ethaddr_fallback1);
+	eth_register_ethaddr(1, enclustra_ethaddr_fallback2);
+}
+
 static int socfpga_init(void)
 {
 	if (!of_machine_is_compatible("enclustra,mercury-sa2"))
 		return 0;
 
 	if (IS_ENABLED(CONFIG_PHYLIB))
-		phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK, phy_fixup);
+		phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
+								   phy_fixup);
+
+	set_mac_addr();
 
 	return 0;
 }
-console_initcall(socfpga_init);
+late_initcall(socfpga_init);
diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
index fa80b7c63d28d17a24d63ac3ee87531ad320ddb1..55d54d289c81fa4a6d46123bcb93c5fc483485e4 100644
--- a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
@@ -76,6 +76,19 @@ atsha204a: atsha204a@64 {
 		status = "okay";
 		compatible = "atmel,atsha204a";
 		reg = <0x64>;
+
+		nvmem-layout {
+		compatible = "fixed-layout";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+			mac_address_0: mac@10 {
+				compatible = "mac-base";
+				reg = <0x10 0x6>;
+				nvmem-cell-cells = <1>;
+				nvmem-cell-names = "mac-address";
+			};
+		};
 	};
 };
 
@@ -129,9 +142,10 @@ &gpio1 {
 
 &gmac1 {
 	status = "okay";
-	/delete-property/ mac-address;
 	phy-mode = "rgmii";
 	phy-handle = <&phy3>;
+	nvmem-cells = <&mac_address_0>;
+	nvmem-cell-names = "mac-address";
 
 	mdio0 {
 		#address-cells = <1>;

-- 
2.43.0




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

* [PATCH v2 06/10] boards: enclustra-sa2: configure SI5338
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (4 preceding siblings ...)
  2025-09-25 11:59 ` [PATCH v2 05/10] boards: enclustra-sa2: read MAC address from EEPROM David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-25 11:59 ` [PATCH v2 07/10] boards: enclustra-sa2: enable SI5338 David Picard
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

Configure the SI5338 clock generator on the ST1 baseboard.

Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>

---
v1 -> v2:
  - replace custom functions to read and write a byte to a
    I2C register with regmap functions.
  - replace custom functions to update bits in a
    I2C register with regmap functions.
---
---
 arch/arm/boards/enclustra-sa2/Makefile             |   2 +-
 .../boards/enclustra-sa2/Si5338-RevB-Registers.h   | 433 +++++++++++++++++++++
 arch/arm/boards/enclustra-sa2/board.c              |   6 +
 arch/arm/boards/enclustra-sa2/si5338_config.c      | 252 ++++++++++++
 arch/arm/boards/enclustra-sa2/si5338_config.h      |  22 ++
 arch/arm/mach-socfpga/Kconfig                      |   4 +
 6 files changed, 718 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boards/enclustra-sa2/Makefile b/arch/arm/boards/enclustra-sa2/Makefile
index 8c927fe291a6b3eb20a32a2db96c73f231ab4697..2185c84fc482776681a5f2fc3cad7434f0160561 100644
--- a/arch/arm/boards/enclustra-sa2/Makefile
+++ b/arch/arm/boards/enclustra-sa2/Makefile
@@ -1,2 +1,2 @@
-obj-y += lowlevel.o board.o
+obj-y += lowlevel.o board.o si5338_config.o
 pbl-y += lowlevel.o
diff --git a/arch/arm/boards/enclustra-sa2/Si5338-RevB-Registers.h b/arch/arm/boards/enclustra-sa2/Si5338-RevB-Registers.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea9093e8601835e01391b4b19aa98787c4861b41
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/Si5338-RevB-Registers.h
@@ -0,0 +1,433 @@
+//Register map for use with AN428 (JumpStart)
+//http://www.skyworksinc.com/timing
+//#BEGIN_HEADER
+//Date = Friday, June 09, 2023 5:03 PM
+//File version = 3
+//Software Name = ClockBuilder Pro
+//Software version = 4.9.0.0
+//Software date = 4 24, 2023
+//Chip = Si533x
+//Part Number = Si533x
+//#END_HEADER
+//Input Frequency (MHz) = 24.000000000
+//Input Type = CMOS_SSTL_HSTL
+//P1 = 1
+//Input Mux = RefClk
+//FDBK Input Frequency (MHz) = 24.000000000
+//FDBK Input Type = OFF
+//P2 = 1
+//FDBK Mux = NoClk
+//PFD Input Frequency (MHz) = 24.000000000
+//VCO Frequency (GHz) = 2.500000
+//N = 104  1/6  (104.1667)
+//Internal feedback enabled
+//Output Clock 0
+// Output Frequency (MHz) = 125.000000000
+// Mux Selection = IDn
+// MultiSynth = 20  (20.0000)
+// R = 1
+//Output Clock 1
+// Output is off
+//Output Clock 2
+// Output is off
+//Output Clock 3
+// Output Frequency (MHz) = 100.000000000
+// Mux Selection = IDn
+// MultiSynth = 25  (25.0000)
+// R = 1
+//Driver 0
+// Enabled
+// Powered on
+// Output voltage = 3.30
+// Output type = 3.3V LVDS
+// Output state when disabled = Tristate
+//Driver 1
+// Disabled
+// Powered off
+// Output voltage = 3.30
+// Output type = 3.3V LVDS
+// Output state when disabled = StopLow
+//Driver 2
+// Disabled
+// Powered off
+// Output voltage = 3.30
+// Output type = 3.3V LVDS
+// Output state when disabled = StopLow
+//Driver 3
+// Enabled
+// Powered on
+// Output voltage = 3.30
+// Output type = 3.3V CMOS on A
+// Output state when disabled = Tristate
+//Clock 0 phase inc/dec step size (ns) = 0.000
+//Clock 1 phase inc/dec step size (ns) = 0.000
+//Clock 2 phase inc/dec step size (ns) = 0.000
+//Clock 3 phase inc/dec step size (ns) = 0.000
+//Phase increment and decrement pin control is off
+//Frequency increment and decrement pin control is off
+//Frequency increment and decrement is disabled
+//Initial phase offset 0 (ns) = 0.000
+//Initial phase offset 1 (ns) = 0.000
+//Initial phase offset 2 (ns) = 0.000
+//Initial phase offset 3 (ns) = 0.000
+//SSC is disabled
+
+#define NUM_REGS_MAX 350
+
+typedef struct Reg_Data {
+	unsigned char Reg_Addr;
+	unsigned char Reg_Val;
+	unsigned char Reg_Mask;
+} Reg_Data;
+
+Reg_Data const Reg_Store[NUM_REGS_MAX] = {
+	{  0, 0x00, 0x00 },
+	{  1, 0x00, 0x00 },
+	{  2, 0x00, 0x00 },
+	{  3, 0x00, 0x00 },
+	{  4, 0x00, 0x00 },
+	{  5, 0x00, 0x00 },
+	{  6, 0x08, 0x1D },
+	{  7, 0x00, 0x00 },
+	{  8, 0x70, 0x00 },
+	{  9, 0x0F, 0x00 },
+	{ 10, 0x00, 0x00 },
+	{ 11, 0x00, 0x00 },
+	{ 12, 0x00, 0x00 },
+	{ 13, 0x00, 0x00 },
+	{ 14, 0x00, 0x00 },
+	{ 15, 0x00, 0x00 },
+	{ 16, 0x00, 0x00 },
+	{ 17, 0x00, 0x00 },
+	{ 18, 0x00, 0x00 },
+	{ 19, 0x00, 0x00 },
+	{ 20, 0x00, 0x00 },
+	{ 21, 0x00, 0x00 },
+	{ 22, 0x00, 0x00 },
+	{ 23, 0x00, 0x00 },
+	{ 24, 0x00, 0x00 },
+	{ 25, 0x00, 0x00 },
+	{ 26, 0x00, 0x00 },
+	{ 27, 0x70, 0x80 },
+	{ 28, 0x0B, 0xFF },
+	{ 29, 0x08, 0xFF },
+	{ 30, 0xB0, 0xFF },
+	{ 31, 0xC0, 0xFF },
+	{ 32, 0xE3, 0xFF },
+	{ 33, 0xE3, 0xFF },
+	{ 34, 0xC0, 0xFF },
+	{ 35, 0x00, 0xFF },
+	{ 36, 0x06, 0x1F },
+	{ 37, 0x00, 0x1F },
+	{ 38, 0x00, 0x1F },
+	{ 39, 0x01, 0x1F },
+	{ 40, 0x63, 0xFF },
+	{ 41, 0x0C, 0x7F },
+	{ 42, 0x37, 0x3F },
+	{ 43, 0x00, 0x00 },
+	{ 44, 0x00, 0x00 },
+	{ 45, 0x00, 0xFF },
+	{ 46, 0x00, 0xFF },
+	{ 47, 0x14, 0x3F },
+	{ 48, 0x3C, 0xFF },
+	{ 49, 0x00, 0xFF },
+	{ 50, 0xC4, 0xFF },
+	{ 51, 0x07, 0xFF },
+	{ 52, 0x10, 0xFF },
+	{ 53, 0x00, 0xFF },
+	{ 54, 0x08, 0xFF },
+	{ 55, 0x00, 0xFF },
+	{ 56, 0x00, 0xFF },
+	{ 57, 0x00, 0xFF },
+	{ 58, 0x00, 0xFF },
+	{ 59, 0x01, 0xFF },
+	{ 60, 0x00, 0xFF },
+	{ 61, 0x00, 0xFF },
+	{ 62, 0x00, 0x3F },
+	{ 63, 0x10, 0xFF },
+	{ 64, 0x00, 0xFF },
+	{ 65, 0x00, 0xFF },
+	{ 66, 0x00, 0xFF },
+	{ 67, 0x00, 0xFF },
+	{ 68, 0x00, 0xFF },
+	{ 69, 0x00, 0xFF },
+	{ 70, 0x00, 0xFF },
+	{ 71, 0x00, 0xFF },
+	{ 72, 0x00, 0xFF },
+	{ 73, 0x00, 0x3F },
+	{ 74, 0x10, 0xFF },
+	{ 75, 0x00, 0xFF },
+	{ 76, 0x00, 0xFF },
+	{ 77, 0x00, 0xFF },
+	{ 78, 0x00, 0xFF },
+	{ 79, 0x00, 0xFF },
+	{ 80, 0x00, 0xFF },
+	{ 81, 0x00, 0xFF },
+	{ 82, 0x00, 0xFF },
+	{ 83, 0x00, 0xFF },
+	{ 84, 0x00, 0x3F },
+	{ 85, 0x10, 0xFF },
+	{ 86, 0x80, 0xFF },
+	{ 87, 0x0A, 0xFF },
+	{ 88, 0x00, 0xFF },
+	{ 89, 0x00, 0xFF },
+	{ 90, 0x00, 0xFF },
+	{ 91, 0x00, 0xFF },
+	{ 92, 0x01, 0xFF },
+	{ 93, 0x00, 0xFF },
+	{ 94, 0x00, 0xFF },
+	{ 95, 0x00, 0x3F },
+	{ 96, 0x10, 0x00 },
+	{ 97, 0x15, 0xFF },
+	{ 98, 0x32, 0xFF },
+	{ 99, 0x08, 0xFF },
+	{ 100, 0x00, 0xFF },
+	{ 101, 0x00, 0xFF },
+	{ 102, 0x00, 0xFF },
+	{ 103, 0x06, 0xFF },
+	{ 104, 0x00, 0xFF },
+	{ 105, 0x00, 0xFF },
+	{ 106, 0x80, 0xBF },
+	{ 107, 0x00, 0xFF },
+	{ 108, 0x00, 0xFF },
+	{ 109, 0x00, 0xFF },
+	{ 110, 0x00, 0xFF },
+	{ 111, 0x00, 0xFF },
+	{ 112, 0x00, 0xFF },
+	{ 113, 0x00, 0xFF },
+	{ 114, 0x40, 0xFF },
+	{ 115, 0x00, 0xFF },
+	{ 116, 0x80, 0xFF },
+	{ 117, 0x00, 0xFF },
+	{ 118, 0x40, 0xFF },
+	{ 119, 0x00, 0xFF },
+	{ 120, 0x00, 0xFF },
+	{ 121, 0x00, 0xFF },
+	{ 122, 0x00, 0xFF },
+	{ 123, 0x00, 0xFF },
+	{ 124, 0x00, 0xFF },
+	{ 125, 0x00, 0xFF },
+	{ 126, 0x00, 0xFF },
+	{ 127, 0x00, 0xFF },
+	{ 128, 0x00, 0xFF },
+	{ 129, 0x00, 0x0F },
+	{ 130, 0x00, 0x0F },
+	{ 131, 0x00, 0xFF },
+	{ 132, 0x00, 0xFF },
+	{ 133, 0x00, 0xFF },
+	{ 134, 0x00, 0xFF },
+	{ 135, 0x00, 0xFF },
+	{ 136, 0x00, 0xFF },
+	{ 137, 0x00, 0xFF },
+	{ 138, 0x00, 0xFF },
+	{ 139, 0x00, 0xFF },
+	{ 140, 0x00, 0xFF },
+	{ 141, 0x00, 0xFF },
+	{ 142, 0x00, 0xFF },
+	{ 143, 0x00, 0xFF },
+	{ 144, 0x00, 0xFF },
+	{ 145, 0x00, 0x00 },
+	{ 146, 0xFF, 0x00 },
+	{ 147, 0x00, 0x00 },
+	{ 148, 0x00, 0x00 },
+	{ 149, 0x00, 0x00 },
+	{ 150, 0x00, 0x00 },
+	{ 151, 0x00, 0x00 },
+	{ 152, 0x00, 0xFF },
+	{ 153, 0x00, 0xFF },
+	{ 154, 0x00, 0xFF },
+	{ 155, 0x00, 0xFF },
+	{ 156, 0x00, 0xFF },
+	{ 157, 0x00, 0xFF },
+	{ 158, 0x00, 0x0F },
+	{ 159, 0x00, 0x0F },
+	{ 160, 0x00, 0xFF },
+	{ 161, 0x00, 0xFF },
+	{ 162, 0x00, 0xFF },
+	{ 163, 0x00, 0xFF },
+	{ 164, 0x00, 0xFF },
+	{ 165, 0x00, 0xFF },
+	{ 166, 0x00, 0xFF },
+	{ 167, 0x00, 0xFF },
+	{ 168, 0x00, 0xFF },
+	{ 169, 0x00, 0xFF },
+	{ 170, 0x00, 0xFF },
+	{ 171, 0x00, 0xFF },
+	{ 172, 0x00, 0xFF },
+	{ 173, 0x00, 0xFF },
+	{ 174, 0x00, 0xFF },
+	{ 175, 0x00, 0xFF },
+	{ 176, 0x00, 0xFF },
+	{ 177, 0x00, 0xFF },
+	{ 178, 0x00, 0xFF },
+	{ 179, 0x00, 0xFF },
+	{ 180, 0x00, 0xFF },
+	{ 181, 0x00, 0x0F },
+	{ 182, 0x00, 0xFF },
+	{ 183, 0x00, 0xFF },
+	{ 184, 0x00, 0xFF },
+	{ 185, 0x00, 0xFF },
+	{ 186, 0x00, 0xFF },
+	{ 187, 0x00, 0xFF },
+	{ 188, 0x00, 0xFF },
+	{ 189, 0x00, 0xFF },
+	{ 190, 0x00, 0xFF },
+	{ 191, 0x00, 0xFF },
+	{ 192, 0x00, 0xFF },
+	{ 193, 0x00, 0xFF },
+	{ 194, 0x00, 0xFF },
+	{ 195, 0x00, 0xFF },
+	{ 196, 0x00, 0xFF },
+	{ 197, 0x00, 0xFF },
+	{ 198, 0x00, 0xFF },
+	{ 199, 0x00, 0xFF },
+	{ 200, 0x00, 0xFF },
+	{ 201, 0x00, 0xFF },
+	{ 202, 0x00, 0xFF },
+	{ 203, 0x00, 0x0F },
+	{ 204, 0x00, 0xFF },
+	{ 205, 0x00, 0xFF },
+	{ 206, 0x00, 0xFF },
+	{ 207, 0x00, 0xFF },
+	{ 208, 0x00, 0xFF },
+	{ 209, 0x00, 0xFF },
+	{ 210, 0x00, 0xFF },
+	{ 211, 0x00, 0xFF },
+	{ 212, 0x00, 0xFF },
+	{ 213, 0x00, 0xFF },
+	{ 214, 0x00, 0xFF },
+	{ 215, 0x00, 0xFF },
+	{ 216, 0x00, 0xFF },
+	{ 217, 0x00, 0xFF },
+	{ 218, 0x00, 0x00 },
+	{ 219, 0x00, 0x00 },
+	{ 220, 0x00, 0x00 },
+	{ 221, 0x0D, 0x00 },
+	{ 222, 0x00, 0x00 },
+	{ 223, 0x00, 0x00 },
+	{ 224, 0xF4, 0x00 },
+	{ 225, 0xF0, 0x00 },
+	{ 226, 0x00, 0x00 },
+	{ 227, 0x00, 0x00 },
+	{ 228, 0x00, 0x00 },
+	{ 229, 0x00, 0x00 },
+	{ 231, 0x00, 0x00 },
+	{ 232, 0x00, 0x00 },
+	{ 233, 0x00, 0x00 },
+	{ 234, 0x00, 0x00 },
+	{ 235, 0x00, 0x00 },
+	{ 236, 0x00, 0x00 },
+	{ 237, 0x00, 0x00 },
+	{ 238, 0x14, 0x00 },
+	{ 239, 0x00, 0x00 },
+	{ 240, 0x00, 0x00 },
+	{ 242, 0x02, 0x02 },
+	{ 243, 0xF0, 0x00 },
+	{ 244, 0x00, 0x00 },
+	{ 245, 0x00, 0x00 },
+	{ 247, 0x00, 0x00 },
+	{ 248, 0x00, 0x00 },
+	{ 249, 0xA8, 0x00 },
+	{ 250, 0x00, 0x00 },
+	{ 251, 0x84, 0x00 },
+	{ 252, 0x00, 0x00 },
+	{ 253, 0x00, 0x00 },
+	{ 254, 0x00, 0x00 },
+	{ 255, 1, 0xFF }, // set page bit to 1
+	{  0, 0x00, 0x00 },
+	{  1, 0x00, 0x00 },
+	{  2, 0x00, 0x00 },
+	{  3, 0x00, 0x00 },
+	{  4, 0x00, 0x00 },
+	{  5, 0x00, 0x00 },
+	{  6, 0x00, 0x00 },
+	{  7, 0x00, 0x00 },
+	{  8, 0x00, 0x00 },
+	{  9, 0x00, 0x00 },
+	{ 10, 0x00, 0x00 },
+	{ 11, 0x00, 0x00 },
+	{ 12, 0x00, 0x00 },
+	{ 13, 0x00, 0x00 },
+	{ 14, 0x00, 0x00 },
+	{ 15, 0x00, 0x00 },
+	{ 16, 0x00, 0x00 },
+	{ 17, 0x01, 0x00 },
+	{ 18, 0x00, 0x00 },
+	{ 19, 0x00, 0x00 },
+	{ 20, 0x90, 0x00 },
+	{ 21, 0x31, 0x00 },
+	{ 22, 0x00, 0x00 },
+	{ 23, 0x00, 0x00 },
+	{ 24, 0x01, 0x00 },
+	{ 25, 0x00, 0x00 },
+	{ 26, 0x00, 0x00 },
+	{ 27, 0x00, 0x00 },
+	{ 28, 0x00, 0x00 },
+	{ 29, 0x00, 0x00 },
+	{ 30, 0x00, 0x00 },
+	{ 31, 0x00, 0xFF },
+	{ 32, 0x00, 0xFF },
+	{ 33, 0x01, 0xFF },
+	{ 34, 0x00, 0xFF },
+	{ 35, 0x00, 0xFF },
+	{ 36, 0x90, 0xFF },
+	{ 37, 0x31, 0xFF },
+	{ 38, 0x00, 0xFF },
+	{ 39, 0x00, 0xFF },
+	{ 40, 0x01, 0xFF },
+	{ 41, 0x00, 0xFF },
+	{ 42, 0x00, 0xFF },
+	{ 43, 0x00, 0x0F },
+	{ 44, 0x00, 0x00 },
+	{ 45, 0x00, 0x00 },
+	{ 46, 0x00, 0x00 },
+	{ 47, 0x00, 0xFF },
+	{ 48, 0x00, 0xFF },
+	{ 49, 0x01, 0xFF },
+	{ 50, 0x00, 0xFF },
+	{ 51, 0x00, 0xFF },
+	{ 52, 0x90, 0xFF },
+	{ 53, 0x31, 0xFF },
+	{ 54, 0x00, 0xFF },
+	{ 55, 0x00, 0xFF },
+	{ 56, 0x01, 0xFF },
+	{ 57, 0x00, 0xFF },
+	{ 58, 0x00, 0xFF },
+	{ 59, 0x00, 0x0F },
+	{ 60, 0x00, 0x00 },
+	{ 61, 0x00, 0x00 },
+	{ 62, 0x00, 0x00 },
+	{ 63, 0x00, 0xFF },
+	{ 64, 0x00, 0xFF },
+	{ 65, 0x01, 0xFF },
+	{ 66, 0x00, 0xFF },
+	{ 67, 0x00, 0xFF },
+	{ 68, 0x90, 0xFF },
+	{ 69, 0x31, 0xFF },
+	{ 70, 0x00, 0xFF },
+	{ 71, 0x00, 0xFF },
+	{ 72, 0x01, 0xFF },
+	{ 73, 0x00, 0xFF },
+	{ 74, 0x00, 0xFF },
+	{ 75, 0x00, 0x0F },
+	{ 76, 0x00, 0x00 },
+	{ 77, 0x00, 0x00 },
+	{ 78, 0x00, 0x00 },
+	{ 79, 0x00, 0xFF },
+	{ 80, 0x00, 0xFF },
+	{ 81, 0x00, 0xFF },
+	{ 82, 0x00, 0xFF },
+	{ 83, 0x00, 0xFF },
+	{ 84, 0x90, 0xFF },
+	{ 85, 0x31, 0xFF },
+	{ 86, 0x00, 0xFF },
+	{ 87, 0x00, 0xFF },
+	{ 88, 0x01, 0xFF },
+	{ 89, 0x00, 0xFF },
+	{ 90, 0x00, 0xFF },
+	{ 91, 0x00, 0x0F },
+	{ 92, 0x00, 0x00 },
+	{ 93, 0x00, 0x00 },
+	{ 94, 0x00, 0x00 },
+	{ 255, 0, 0xFF } }; // set page bit to 0
+//End of file
diff --git a/arch/arm/boards/enclustra-sa2/board.c b/arch/arm/boards/enclustra-sa2/board.c
index 4c2b44252d84c78ed8de5754051d0bf194ce8d02..d2e539cbf9460adddc158885473f4ef0004dc284 100644
--- a/arch/arm/boards/enclustra-sa2/board.c
+++ b/arch/arm/boards/enclustra-sa2/board.c
@@ -14,6 +14,7 @@
 #include <mach/socfpga/cyclone5-regs.h>
 #include <net.h>
 #include <linux/nvmem-consumer.h>
+#include "si5338_config.h"
 
 /** Enclustra's MAC address vendor prefix is 20:B0:F7 */
 #define ENCLUSTRA_PREFIX            (0x20b0f7)
@@ -99,6 +100,11 @@ static int socfpga_init(void)
 
 	set_mac_addr();
 
+#ifdef CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2_SI5338
+	/* configure clock generator on the Enclustra ST1 baseboard: */
+	si5338_init();
+#endif
+
 	return 0;
 }
 late_initcall(socfpga_init);
diff --git a/arch/arm/boards/enclustra-sa2/si5338_config.c b/arch/arm/boards/enclustra-sa2/si5338_config.c
new file mode 100644
index 0000000000000000000000000000000000000000..deb8a460be3dc8712add893710825e6b0746181a
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/si5338_config.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <i2c/i2c.h>
+#include <clock.h>
+#include <linux/kernel.h>              /* ARRAY_SIZE */
+#include <linux/regmap.h>
+#include "si5338_config.h"
+#include "Si5338-RevB-Registers.h"
+
+struct si5338 {
+	struct device *dev;
+	struct regmap *map;
+	struct i2c_client *client;
+	int revision;
+	int type;
+} si_dev = { NULL, NULL, NULL, 0, 0 };
+
+
+/**
+ * @brief Get the device from the devicetree
+ * @return A pointer to the device if found, or \t NULL otherwise.
+ */
+static struct device *get_dev(void)
+{
+	struct device *dev;
+	struct i2c_client *client;
+
+	dev = get_device_by_name("si53380");
+	if (dev == NULL) {
+		printf("%s() >> ERROR: can't find device SI5338\n", __func__);
+		return NULL;
+	}
+	client = to_i2c_client(dev);
+	debug("%s() >> SI5338 found at I2C address 0x%02x\n", __func__,
+		  client->addr);
+
+	return dev;
+}
+
+/**
+ * @brief Write a single byte to a register in the SI5338
+ * @param[in] ctx A pointer to a struct si5338.
+ * @param[in] reg The register address.
+ * @param[in] val The byte to be written to the register.
+ * @return 0 on success, a negative value from `asm-generic/errno.h` on error.
+ */
+static int regmap_reg_write(void *ctx, unsigned int reg, unsigned int val)
+{
+	int ret;
+	struct si5338 *si = ctx;
+	u8 buf[] = { val };			/* register value */
+
+	ret = i2c_write_reg(si->client, reg, buf, 1);
+
+	return ret == 1 ? 0 : ret;
+}
+
+/**
+ * @brief Read a single byte from a register in the SI5338
+ * @param[in] ctx A pointer to a struct si5338.
+ * @param[in] reg The register address.
+ * @param[out] val The byte to be written to the register.
+ * @return 0 on success, a negative value from `asm-generic/errno.h` on error.
+ */
+static int regmap_reg_read(void *ctx, unsigned int reg, unsigned int *val)
+{
+	struct si5338 *si = ctx;
+	u8 buf[1];
+	int ret;
+
+	ret = i2c_read_reg(si->client, reg, buf, 1);
+	*val = buf[0];
+
+	return ret == 1 ? 0 : ret;
+}
+
+/**
+ * @brief Validate input clock status
+ * @param[in] dev The I²C device.
+ *
+ * Loop until the \c LOS_CLKIN bit is clear.
+ *
+ * @return 0 on success, a negative value from `asm-generic/errno.h` on error.
+ */
+static int check_input_clock(struct device *dev)
+{
+	// validate input clock status
+	int ret;
+	unsigned int val;
+
+	do {
+		ret = regmap_reg_read(&si_dev, 218, &val);
+		if (ret) {
+			printf("%s() >> ERROR: SI5338 read failed addr: 218\n", __func__);
+			return ret;
+		}
+	} while (val & 0x04);
+
+	return 0;
+}
+
+/**
+ * @brief Check output PLL status
+ * @param[in] dev The I²C device.
+ *
+ * Loop until the \c PLL_LOL, \c LOS_CLKIN and \c SYS_CAL bits are clear.
+ *
+ * @return 0 on success, a negative value from `asm-generic/errno.h` on error
+ * (-EIO if too many trials).
+ */
+static int check_pll(struct device *dev)
+{
+	int ret;
+	int try = 0;
+	unsigned int val;
+
+	do {
+		ret = regmap_reg_read(&si_dev, 218, &val);
+		if (ret < 0)
+			return ret;
+		mdelay(100);
+		try++;
+		if (try > 10) {
+			printf("%s() >> ERROR: SI5338 PLL is not locking\n", __func__);
+			return -EIO;
+		}
+	} while (val & 0x15);
+
+	return 0;
+}
+
+int si5338_init(void)
+{
+	unsigned int val;
+	struct device *dev;
+	int ret;
+	struct regmap_config rgmp_cfg = {
+		.reg_bits = 8,          /* register addresses are coded on 8 bits */
+		.reg_stride = 1,        /* register addresses increment by 1 */
+		.pad_bits = 0,
+		.val_bits = 8,
+		.max_register = 0xff,   /* maximum register address */
+		.reg_format_endian = REGMAP_ENDIAN_DEFAULT,
+		.val_format_endian = REGMAP_ENDIAN_DEFAULT,
+		.read_flag_mask = 0,
+		.write_flag_mask = 0,
+	};
+	struct regmap_bus rgmp_i2c_bus = {
+		.reg_write = regmap_reg_write,
+		.reg_read = regmap_reg_read,
+	};
+
+	si_dev.dev = get_dev();
+	if (si_dev.dev == NULL)
+		return -ENODEV;
+	si_dev.client = to_i2c_client(si_dev.dev);
+	si_dev.map = regmap_init(si_dev.dev, &rgmp_i2c_bus,
+							 &si_dev, &rgmp_cfg);
+
+	dev = get_dev();
+	if (dev == NULL)
+		return -ENODEV;
+
+	/* Set PAGE_SEL bit to 0. If bit is 1, registers with address
+	 * greater than 255 can be addressed.
+	 */
+	if (regmap_reg_write(&si_dev, 255, 0x00))
+		return -1;
+
+	// disable outputs
+	if (regmap_update_bits(si_dev.map, 230, 0x10, 0x10))
+		return -1;
+
+	// pause lol
+	if (regmap_update_bits(si_dev.map, 241, 0x80, 0x80))
+		return -1;
+
+	// write new configuration
+	for (int i = 0; i < NUM_REGS_MAX; i++)
+		if (regmap_update_bits(si_dev.map, Reg_Store[i].Reg_Addr,
+							   Reg_Store[i].Reg_Mask, Reg_Store[i].Reg_Val))
+			return -1;
+
+	ret = check_input_clock(dev);
+	if (ret)
+		return ret;
+
+	// configure PLL for locking
+	ret = regmap_update_bits(si_dev.map, 49, 0x80, 0x00);
+	if (ret)
+		return ret;
+
+	// initiate locking of PLL
+	ret = regmap_reg_write(&si_dev, 246, 0x02);
+	if (ret)
+		return ret;
+
+	// wait 25ms (100ms to be on the safe side)
+	mdelay(100);
+
+	// restart lol
+	ret = regmap_update_bits(si_dev.map, 241, 0xff, 0x65);
+	if (ret)
+		return ret;
+
+	ret = check_pll(dev);
+	if (ret)
+		return ret;
+
+	// copy fcal values to active registers: FCAL[17:16]
+	ret = regmap_reg_read(&si_dev, 237, &val);
+	if (ret)
+		return ret;
+	ret = regmap_update_bits(si_dev.map, 47, 0x03, val);
+	if (ret)
+		return ret;
+
+	// copy fcal values to active registers: FCAL[15:8]
+	ret = regmap_reg_read(&si_dev, 236, &val);
+	if (ret)
+		return ret;
+	ret = regmap_reg_write(&si_dev, 46, val);
+	if (ret)
+		return ret;
+
+	// copy fcal values to active registers: FCAL[7:0]
+	ret = regmap_reg_read(&si_dev, 235, &val);
+	if (ret)
+		return ret;
+	ret = regmap_reg_write(&si_dev, 45, val);
+	if (ret)
+		return ret;
+
+	// Must write 000101b to these bits if the device is not factory programmed
+	ret = regmap_update_bits(si_dev.map, 47, 0xFC, 0x14);
+	if (ret)
+		return ret;
+
+	// set PLL to use FCAL values
+	ret = regmap_update_bits(si_dev.map, 49, 0x80, 0x80);
+	if (ret)
+		return ret;
+
+	// enable outputs
+	ret = regmap_reg_write(&si_dev, 230, 0x00);
+	if (ret)
+		return ret;
+
+	printf("SI5338 init successful\n");
+
+	return 0;
+}
diff --git a/arch/arm/boards/enclustra-sa2/si5338_config.h b/arch/arm/boards/enclustra-sa2/si5338_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..69eb81e57e55db4fecc5ba7307ec05cd2bcc772d
--- /dev/null
+++ b/arch/arm/boards/enclustra-sa2/si5338_config.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Initialize the Si5338 clock generator.
+ *
+ * Datasheet: https://www.skyworksinc.com/en/application-pages/-/media/SkyWorks/SL/documents/public/data-sheets/Si5338.pdf
+ * Reference manual: https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/reference-manuals/Si5338-RM.pdf
+ */
+
+#pragma once
+
+/**
+ * @brief Initialize the SI5338
+ *
+ * Get the I²C address from the devicetree and write the registers of the
+ * SI5338 after the configuration in \c Si5338-RevB-Registers.h, generated
+ * by [ClockBuilder Pro](https://www.skyworksinc.com/Application-Pages/Clockbuilder-Pro-Software).
+ *
+ * @return 0 on success, a negative value from `asm-generic/errno.h` on error.
+ */
+
+int si5338_init(void);
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 61935c260c8f06acec119377af7d46411e3e2744..7b05646eac0b39a119cf1bcc61b06ebc631feb28 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -42,6 +42,10 @@ config MACH_SOCFPGA_ENCLUSTRA_SA2
 	select ARCH_SOCFPGA_CYCLONE5
 	bool "Enclustra SA2"
 
+config MACH_SOCFPGA_ENCLUSTRA_SA2_SI5338
+	depends on MACH_SOCFPGA_ENCLUSTRA_SA2
+	bool "Configure the SI5338 clock generator on ST1 baseboard"
+
 config MACH_SOCFPGA_TERASIC_DE0_NANO_SOC
 	select ARCH_SOCFPGA_CYCLONE5
 	bool "Terasic DE0-NANO-SoC aka Atlas"

-- 
2.43.0




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

* [PATCH v2 07/10] boards: enclustra-sa2: enable SI5338
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (5 preceding siblings ...)
  2025-09-25 11:59 ` [PATCH v2 06/10] boards: enclustra-sa2: configure SI5338 David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-25 11:59 ` [PATCH v2 08/10] lib: add crc16 support David Picard
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

The clock generator SI5338 is not implemented on the SA2 module itself,
but on e.g. the ST1 baseboard.

Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
---
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
index 55d54d289c81fa4a6d46123bcb93c5fc483485e4..78ba8008af5d60f10d6a64b0f05e97bf2381079c 100644
--- a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
@@ -90,6 +90,12 @@ mac_address_0: mac@10 {
 			};
 		};
 	};
+
+	si5338: si5338@70 {
+		status = "okay";
+		compatible = "silabs,si5338";
+		reg = <0x70>;
+	};
 };
 
 &i2c_encl_fpga {

-- 
2.43.0




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

* [PATCH v2 08/10] lib: add crc16 support
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (6 preceding siblings ...)
  2025-09-25 11:59 ` [PATCH v2 07/10] boards: enclustra-sa2: enable SI5338 David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-26 12:43   ` Sascha Hauer
  2025-09-25 11:59 ` [PATCH v2 09/10] nvmem: add support for Atmel sha204(a) David Picard
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

From: Sascha Hauer <s.hauer@pengutronix.de>

This adds crc16 support taken straight out of Linux-6.16

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 include/linux/crc16.h | 21 ++++++++++++++++
 lib/Kconfig           |  3 +++
 lib/Makefile          |  1 +
 lib/crc16.c           | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 94 insertions(+)

diff --git a/include/linux/crc16.h b/include/linux/crc16.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b53d62d81f0d5db9b98dd29bf2625bb34e2bb4e
--- /dev/null
+++ b/include/linux/crc16.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *	crc16.h - CRC-16 routine
+ *
+ * Implements the standard CRC-16:
+ *   Width 16
+ *   Poly  0x8005 (x^16 + x^15 + x^2 + 1)
+ *   Init  0
+ *
+ * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
+ */
+
+#ifndef __CRC16_H
+#define __CRC16_H
+
+#include <linux/types.h>
+
+u16 crc16(u16 crc, const u8 *buffer, size_t len);
+
+#endif /* __CRC16_H */
+
diff --git a/lib/Kconfig b/lib/Kconfig
index d07e2f3b695916df56775bc8c1a98bad8bd52b52..c83589e2d9e442caa2351bfb400d197296819c16 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -162,6 +162,9 @@ config CRC8
 	  when they need to do cyclic redundancy check according CRC8
 	  algorithm. Module will be called crc8.
 
+config CRC16
+	bool "CRC16 function"
+
 source "lib/gui/Kconfig"
 
 source "lib/fonts/Kconfig"
diff --git a/lib/Makefile b/lib/Makefile
index 13f1de1420083df3e8c846b503968f58474e36f0..e9f152b21dad3f521cb9dbbf88d6012fdee19c3c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -85,6 +85,7 @@ obj-y			+= parseopt.o
 obj-y			+= clz_ctz.o
 obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
 obj-$(CONFIG_CRC8)	+= crc8.o
+obj-$(CONFIG_CRC16)	+= crc16.o
 obj-$(CONFIG_NLS)	+= nls_base.o
 obj-$(CONFIG_FSL_QE_FIRMWARE) += fsl-qe-firmware.o
 obj-$(CONFIG_UBSAN_STANDALONE)	+= ubsan.o
diff --git a/lib/crc16.c b/lib/crc16.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d0354ba6b7a6a02367cf42e7bec30d64ce57e0b
--- /dev/null
+++ b/lib/crc16.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *      crc16.c
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc16.h>
+
+/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
+static u16 const crc16_table[256] = {
+	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+static inline u16 crc16_byte(u16 crc, const u8 data)
+{
+	return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
+}
+
+/**
+ * crc16 - compute the CRC-16 for the data buffer
+ * @crc:	previous CRC value
+ * @buffer:	data pointer
+ * @len:	number of bytes in the buffer
+ *
+ * Returns the updated CRC value.
+ */
+u16 crc16(u16 crc, u8 const *buffer, size_t len)
+{
+	while (len--)
+		crc = crc16_byte(crc, *buffer++);
+	return crc;
+}
+EXPORT_SYMBOL(crc16);
+
+MODULE_DESCRIPTION("CRC16 calculations");
+MODULE_LICENSE("GPL");
+

-- 
2.43.0




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

* [PATCH v2 09/10] nvmem: add support for Atmel sha204(a)
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (7 preceding siblings ...)
  2025-09-25 11:59 ` [PATCH v2 08/10] lib: add crc16 support David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-25 11:59 ` [PATCH v2 10/10] boards: enclustra-sa2: read S/N from EEPROM David Picard
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

From: Sascha Hauer <s.hauer@pengutronix.de>

This adds support for the Atmel SHA204(a) which is a SHA accelerator
with hwrng and OTP support. This only adds the OTP functionality, hence
the driver resides in drivers/nvmem for now. The code is based on the
corresponding Linux driver.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

---
v1 -> v2:
  - replace devm_kmalloc() with devm_kzalloc() in atmel_i2c_probe().
---
---
 drivers/nvmem/Kconfig         |  15 +++
 drivers/nvmem/Makefile        |   2 +
 drivers/nvmem/atmel-i2c.c     | 302 ++++++++++++++++++++++++++++++++++++++++++
 drivers/nvmem/atmel-i2c.h     | 180 +++++++++++++++++++++++++
 drivers/nvmem/atmel-sha204a.c | 114 ++++++++++++++++
 5 files changed, 613 insertions(+)

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 41a3bf26dda04155e7457a5bd9473ff4be646574..7428512e28babc35fb3ca3b144a6b8a762ea584e 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -121,4 +121,19 @@ config STARFIVE_OTP
 	  This adds support for the StarFive OTP controller. Only reading
 	  is currently supported.
 
+config NVMEM_ATMEL_SHA204A
+	bool "Support for Microchip / Atmel SHA accelerator OTP support"
+	depends on I2C
+	select CRC16
+	select BITREV
+	select NVMEM_ATMEL_I2C
+	help
+	  Microchip / Atmel SHA accelerator and RNG.
+	  Select this if you want to use the Microchip / Atmel SHA204A
+	  chip. This driver currently only supports reading the OTP memory
+
+config NVMEM_ATMEL_I2C
+	bool
+	select BITREVERSE
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index fdd5c63e321db009f5eaa282e0b37fe0c8f28572..9cdc669a966958551e708bc4ef21ff353f0cfe83 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -34,3 +34,5 @@ nvmem-kvx-otp-nv-y		:= kvx-otp-nv.o
 obj-$(CONFIG_NVMEM_ROCKCHIP_OTP)+= rockchip-otp.o
 obj-$(CONFIG_STARFIVE_OTP)	+= starfive-otp.o
 obj-$(CONFIG_IMX_OCOTP_ELE)	+= imx-ocotp-ele.o
+obj-$(CONFIG_NVMEM_ATMEL_I2C)	+= atmel-i2c.o
+obj-$(CONFIG_NVMEM_ATMEL_SHA204A) += atmel-sha204a.o
diff --git a/drivers/nvmem/atmel-i2c.c b/drivers/nvmem/atmel-i2c.c
new file mode 100644
index 0000000000000000000000000000000000000000..19ab5f89240be31a02ecb3af83f2dcb26cb75bae
--- /dev/null
+++ b/drivers/nvmem/atmel-i2c.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Microchip / Atmel ECC (I2C) driver.
+ *
+ * Copyright (c) 2017, Microchip Technology Inc.
+ * Author: Tudor Ambarus
+ */
+
+#include <linux/bitrev.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <i2c/i2c.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include "atmel-i2c.h"
+
+static const struct {
+	u8 value;
+	const char *error_text;
+} error_list[] = {
+	{ 0x01, "CheckMac or Verify miscompare" },
+	{ 0x03, "Parse Error" },
+	{ 0x05, "ECC Fault" },
+	{ 0x0F, "Execution Error" },
+	{ 0xEE, "Watchdog about to expire" },
+	{ 0xFF, "CRC or other communication error" },
+};
+u16 crc16(u16 crc, const u8 *buffer, size_t len);
+/**
+ * atmel_i2c_checksum() - Generate 16-bit CRC as required by ATMEL ECC.
+ * CRC16 verification of the count, opcode, param1, param2 and data bytes.
+ * The checksum is saved in little-endian format in the least significant
+ * two bytes of the command. CRC polynomial is 0x8005 and the initial register
+ * value should be zero.
+ *
+ * @cmd : structure used for communicating with the device.
+ */
+static void atmel_i2c_checksum(struct atmel_i2c_cmd *cmd)
+{
+	u8 *data = &cmd->count;
+	size_t len = cmd->count - CRC_SIZE;
+	__le16 *__crc16 = (__le16 *)(data + len);
+
+	*__crc16 = cpu_to_le16(bitrev16(crc16(0, data, len)));
+}
+
+void atmel_i2c_init_read_config_cmd(struct atmel_i2c_cmd *cmd)
+{
+	cmd->word_addr = COMMAND;
+	cmd->opcode = OPCODE_READ;
+	/*
+	 * Read the word from Configuration zone that contains the lock bytes
+	 * (UserExtra, Selector, LockValue, LockConfig).
+	 */
+	cmd->param1 = CONFIGURATION_ZONE;
+	cmd->param2 = cpu_to_le16(DEVICE_LOCK_ADDR);
+	cmd->count = READ_COUNT;
+
+	atmel_i2c_checksum(cmd);
+
+	cmd->msecs = MAX_EXEC_TIME_READ;
+	cmd->rxsize = READ_RSP_SIZE;
+}
+EXPORT_SYMBOL(atmel_i2c_init_read_config_cmd);
+
+int atmel_i2c_init_read_otp_cmd(struct atmel_i2c_cmd *cmd, u16 addr)
+{
+	if (addr > OTP_ZONE_SIZE)
+		return -EINVAL;
+
+	cmd->word_addr = COMMAND;
+	cmd->opcode = OPCODE_READ;
+	/*
+	 * Read the word from OTP zone that may contain e.g. serial
+	 * numbers or similar if persistently pre-initialized and locked
+	 */
+	cmd->param1 = OTP_ZONE;
+	cmd->param2 = cpu_to_le16(addr);
+	cmd->count = READ_COUNT;
+
+	atmel_i2c_checksum(cmd);
+
+	cmd->msecs = MAX_EXEC_TIME_READ;
+	cmd->rxsize = READ_RSP_SIZE;
+
+	return 0;
+}
+EXPORT_SYMBOL(atmel_i2c_init_read_otp_cmd);
+
+/*
+ * After wake and after execution of a command, there will be error, status, or
+ * result bytes in the device's output register that can be retrieved by the
+ * system. When the length of that group is four bytes, the codes returned are
+ * detailed in error_list.
+ */
+static int atmel_i2c_status(struct device *dev, u8 *status)
+{
+	size_t err_list_len = ARRAY_SIZE(error_list);
+	int i;
+	u8 err_id = status[1];
+
+	if (*status != STATUS_SIZE)
+		return 0;
+
+	if (err_id == STATUS_WAKE_SUCCESSFUL || err_id == STATUS_NOERR)
+		return 0;
+
+	for (i = 0; i < err_list_len; i++)
+		if (error_list[i].value == err_id)
+			break;
+
+	/* if err_id is not in the error_list then ignore it */
+	if (i != err_list_len) {
+		dev_err(dev, "%02x: %s:\n", err_id, error_list[i].error_text);
+		return err_id;
+	}
+
+	return 0;
+}
+
+/**
+ * i2c_transfer_buffer_flags - issue a single I2C message transferring data
+ *                             to/from a buffer
+ * @client: Handle to slave device
+ * @buf: Where the data is stored
+ * @count: How many bytes to transfer, must be less than 64k since msg.len is u16
+ * @flags: The flags to be used for the message, e.g. I2C_M_RD for reads
+ *
+ * Returns negative errno, or else the number of bytes transferred.
+ */
+static int i2c_transfer_buffer_flags(const struct i2c_client *client, char *buf,
+			      int count, u16 flags)
+{
+	int ret;
+	struct i2c_msg msg = {
+		.addr = client->addr,
+		.flags = flags,
+		.len = count,
+		.buf = buf,
+	};
+
+	ret = i2c_transfer(client->adapter, &msg, 1);
+
+	/*
+	 * If everything went ok (i.e. 1 msg transferred), return #bytes
+	 * transferred, else error code.
+	 */
+	return (ret == 1) ? count : ret;
+}
+
+static int atmel_i2c_wakeup(struct i2c_client *client)
+{
+	struct atmel_i2c_client_priv *i2c_priv = i2c_get_clientdata(client);
+	u8 status[STATUS_RSP_SIZE];
+	int ret;
+
+	/*
+	 * The device ignores any levels or transitions on the SCL pin when the
+	 * device is idle, asleep or during waking up. Don't check for error
+	 * when waking up the device.
+	 */
+	i2c_transfer_buffer_flags(client, i2c_priv->wake_token,
+				i2c_priv->wake_token_sz, I2C_M_IGNORE_NAK);
+
+	/*
+	 * Wait to wake the device. Typical execution times for ecdh and genkey
+	 * are around tens of milliseconds. Delta is chosen to 50 microseconds.
+	 */
+	udelay(TWHI_MIN);
+
+	ret = i2c_master_recv(client, status, STATUS_SIZE);
+	if (ret < 0)
+		return ret;
+
+	return atmel_i2c_status(&client->dev, status);
+}
+
+static int atmel_i2c_sleep(struct i2c_client *client)
+{
+	u8 sleep = SLEEP_TOKEN;
+
+	return i2c_master_send(client, &sleep, 1);
+}
+
+/*
+ * atmel_i2c_send_receive() - send a command to the device and receive its
+ *                            response.
+ * @client: i2c client device
+ * @cmd   : structure used to communicate with the device
+ *
+ * After the device receives a Wake token, a watchdog counter starts within the
+ * device. After the watchdog timer expires, the device enters sleep mode
+ * regardless of whether some I/O transmission or command execution is in
+ * progress. If a command is attempted when insufficient time remains prior to
+ * watchdog timer execution, the device will return the watchdog timeout error
+ * code without attempting to execute the command. There is no way to reset the
+ * counter other than to put the device into sleep or idle mode and then
+ * wake it up again.
+ */
+int atmel_i2c_send_receive(struct i2c_client *client, struct atmel_i2c_cmd *cmd)
+{
+	int ret;
+
+	ret = atmel_i2c_wakeup(client);
+	if (ret)
+		goto err;
+
+	/* send the command */
+	ret = i2c_master_send(client, (u8 *)cmd, cmd->count + WORD_ADDR_SIZE);
+	if (ret < 0)
+		goto err;
+
+	/* delay the appropriate amount of time for command to execute */
+	mdelay(cmd->msecs);
+
+	/* receive the response */
+	ret = i2c_master_recv(client, cmd->data, cmd->rxsize);
+	if (ret < 0)
+		goto err;
+
+	/* put the device into low-power mode */
+	ret = atmel_i2c_sleep(client);
+	if (ret < 0)
+		goto err;
+
+	return atmel_i2c_status(&client->dev, cmd->data);
+err:
+	return ret;
+}
+EXPORT_SYMBOL(atmel_i2c_send_receive);
+
+static inline size_t atmel_i2c_wake_token_sz(u32 bus_clk_rate)
+{
+	u32 no_of_bits = DIV_ROUND_UP(TWLO_USEC * bus_clk_rate, USEC_PER_SEC);
+
+	/* return the size of the wake_token in bytes */
+	return DIV_ROUND_UP(no_of_bits, 8);
+}
+
+static int device_sanity_check(struct i2c_client *client)
+{
+	struct atmel_i2c_cmd *cmd;
+	int ret;
+
+	cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	atmel_i2c_init_read_config_cmd(cmd);
+
+	ret = atmel_i2c_send_receive(client, cmd);
+	if (ret)
+		goto free_cmd;
+
+	/*
+	 * It is vital that the Configuration, Data and OTP zones be locked
+	 * prior to release into the field of the system containing the device.
+	 * Failure to lock these zones may permit modification of any secret
+	 * keys and may lead to other security problems.
+	 */
+	if (cmd->data[LOCK_CONFIG_IDX] || cmd->data[LOCK_VALUE_IDX]) {
+		dev_err(&client->dev, "Configuration or Data and OTP zones are unlocked!\n");
+		ret = -ENOTSUPP;
+	}
+
+	/* fall through */
+free_cmd:
+	kfree(cmd);
+	return ret;
+}
+
+int atmel_i2c_probe(struct i2c_client *client)
+{
+	struct atmel_i2c_client_priv *i2c_priv;
+	struct device *dev = &client->dev;
+	int bus_clk_rate = 1000000; /* maximum */
+
+	i2c_priv = devm_kzalloc(dev, sizeof(*i2c_priv), GFP_KERNEL);
+	if (!i2c_priv)
+		return -ENOMEM;
+
+	i2c_priv->client = client;
+
+	/*
+	 * WAKE_TOKEN_MAX_SIZE was calculated for the maximum bus_clk_rate -
+	 * 1MHz. The previous bus_clk_rate check ensures us that wake_token_sz
+	 * will always be smaller than or equal to WAKE_TOKEN_MAX_SIZE.
+	 */
+	i2c_priv->wake_token_sz = atmel_i2c_wake_token_sz(bus_clk_rate);
+
+	memset(i2c_priv->wake_token, 0, sizeof(i2c_priv->wake_token));
+
+	i2c_set_clientdata(client, i2c_priv);
+
+	return device_sanity_check(client);
+}
+EXPORT_SYMBOL(atmel_i2c_probe);
+
+MODULE_AUTHOR("Tudor Ambarus");
+MODULE_DESCRIPTION("Microchip / Atmel ECC (I2C) driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/nvmem/atmel-i2c.h b/drivers/nvmem/atmel-i2c.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e8b2b12951d988dd8b8e37751dd82c9f41d9411
--- /dev/null
+++ b/drivers/nvmem/atmel-i2c.h
@@ -0,0 +1,180 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017, Microchip Technology Inc.
+ * Author: Tudor Ambarus
+ */
+
+#ifndef __ATMEL_I2C_H__
+#define __ATMEL_I2C_H__
+
+#include <linux/types.h>
+#include <linux/nvmem-provider.h>
+
+#define ATMEL_ECC_PRIORITY		300
+
+#define COMMAND				0x03 /* packet function */
+#define SLEEP_TOKEN			0x01
+#define WAKE_TOKEN_MAX_SIZE		8
+
+/* Definitions of Data and Command sizes */
+#define WORD_ADDR_SIZE			1
+#define COUNT_SIZE			1
+#define CRC_SIZE			2
+#define CMD_OVERHEAD_SIZE		(COUNT_SIZE + CRC_SIZE)
+
+/* size in bytes of the n prime */
+#define ATMEL_ECC_NIST_P256_N_SIZE	32
+#define ATMEL_ECC_PUBKEY_SIZE		(2 * ATMEL_ECC_NIST_P256_N_SIZE)
+
+#define STATUS_RSP_SIZE			4
+#define ECDH_RSP_SIZE			(32 + CMD_OVERHEAD_SIZE)
+#define GENKEY_RSP_SIZE			(ATMEL_ECC_PUBKEY_SIZE + \
+					 CMD_OVERHEAD_SIZE)
+#define READ_RSP_SIZE			(4 + CMD_OVERHEAD_SIZE)
+#define RANDOM_RSP_SIZE			(32 + CMD_OVERHEAD_SIZE)
+#define MAX_RSP_SIZE			GENKEY_RSP_SIZE
+
+/**
+ * atmel_i2c_cmd - structure used for communicating with the device.
+ * @word_addr: indicates the function of the packet sent to the device. This
+ *             byte should have a value of COMMAND for normal operation.
+ * @count    : number of bytes to be transferred to (or from) the device.
+ * @opcode   : the command code.
+ * @param1   : the first parameter; always present.
+ * @param2   : the second parameter; always present.
+ * @data     : optional remaining input data. Includes a 2-byte CRC.
+ * @rxsize   : size of the data received from i2c client.
+ * @msecs    : command execution time in milliseconds
+ */
+struct atmel_i2c_cmd {
+	u8 word_addr;
+	u8 count;
+	u8 opcode;
+	u8 param1;
+	__le16 param2;
+	u8 data[MAX_RSP_SIZE];
+	u8 msecs;
+	u16 rxsize;
+} __packed;
+
+/* Status/Error codes */
+#define STATUS_SIZE			0x04
+#define STATUS_NOERR			0x00
+#define STATUS_WAKE_SUCCESSFUL		0x11
+
+/* Definitions for eeprom organization */
+#define CONFIGURATION_ZONE		0
+#define OTP_ZONE			1
+
+/* Definitions for eeprom zone sizes */
+#define OTP_ZONE_SIZE			64
+
+/* Definitions for Indexes common to all commands */
+#define RSP_DATA_IDX			1 /* buffer index of data in response */
+#define DATA_SLOT_2			2 /* used for ECDH private key */
+
+/* Definitions for the device lock state */
+#define DEVICE_LOCK_ADDR		0x15
+#define LOCK_VALUE_IDX			(RSP_DATA_IDX + 2)
+#define LOCK_CONFIG_IDX			(RSP_DATA_IDX + 3)
+
+/*
+ * Wake High delay to data communication (microseconds). SDA should be stable
+ * high for this entire duration.
+ */
+#define TWHI_MIN			1500
+#define TWHI_MAX			1550
+
+/* Wake Low duration */
+#define TWLO_USEC			60
+
+/* Command execution time (milliseconds) */
+#define MAX_EXEC_TIME_ECDH		58
+#define MAX_EXEC_TIME_GENKEY		115
+#define MAX_EXEC_TIME_READ		1
+#define MAX_EXEC_TIME_RANDOM		50
+
+/* Command opcode */
+#define OPCODE_ECDH			0x43
+#define OPCODE_GENKEY			0x40
+#define OPCODE_READ			0x02
+#define OPCODE_RANDOM			0x1b
+
+/* Definitions for the READ Command */
+#define READ_COUNT			7
+
+/* Definitions for the RANDOM Command */
+#define RANDOM_COUNT			7
+
+/* Definitions for the GenKey Command */
+#define GENKEY_COUNT			7
+#define GENKEY_MODE_PRIVATE		0x04
+
+/* Definitions for the ECDH Command */
+#define ECDH_COUNT			71
+#define ECDH_PREFIX_MODE		0x00
+
+/**
+ * atmel_i2c_client_priv - i2c_client private data
+ * @client              : pointer to i2c client device
+ * @i2c_client_list_node: part of i2c_client_list
+ * @lock                : lock for sending i2c commands
+ * @wake_token          : wake token array of zeros
+ * @wake_token_sz       : size in bytes of the wake_token
+ * @tfm_count           : number of active crypto transformations on i2c client
+ * @hwrng               : hold the hardware generated rng
+ *
+ * Reads and writes from/to the i2c client are sequential. The first byte
+ * transmitted to the device is treated as the byte size. Any attempt to send
+ * more than this number of bytes will cause the device to not ACK those bytes.
+ * After the host writes a single command byte to the input buffer, reads are
+ * prohibited until after the device completes command execution. Use a mutex
+ * when sending i2c commands.
+ */
+struct atmel_i2c_client_priv {
+	struct i2c_client *client;
+	u8 wake_token[WAKE_TOKEN_MAX_SIZE];
+	size_t wake_token_sz;
+	struct nvmem_config nvmem_config;
+	struct nvmem_device *nvmem;
+	void *data;
+};
+
+/**
+ * atmel_i2c_work_data - data structure representing the work
+ * @ctx : transformation context.
+ * @cbk : pointer to a callback function to be invoked upon completion of this
+ *        request. This has the form:
+ *        callback(struct atmel_i2c_work_data *work_data, void *areq, u8 status)
+ *        where:
+ *        @work_data: data structure representing the work
+ *        @areq     : optional pointer to an argument passed with the original
+ *                    request.
+ *        @status   : status returned from the i2c client device or i2c error.
+ * @areq: optional pointer to a user argument for use at callback time.
+ * @work: describes the task to be executed.
+ * @cmd : structure used for communicating with the device.
+ */
+struct atmel_i2c_work_data {
+	void *ctx;
+	struct i2c_client *client;
+	void (*cbk)(struct atmel_i2c_work_data *work_data, void *areq,
+		    int status);
+	void *areq;
+	struct atmel_i2c_cmd cmd;
+};
+
+int atmel_i2c_probe(struct i2c_client *client);
+
+void atmel_i2c_enqueue(struct atmel_i2c_work_data *work_data,
+		       void (*cbk)(struct atmel_i2c_work_data *work_data,
+				   void *areq, int status),
+		       void *areq);
+void atmel_i2c_flush_queue(void);
+
+int atmel_i2c_send_receive(struct i2c_client *client, struct atmel_i2c_cmd *cmd);
+
+void atmel_i2c_init_read_config_cmd(struct atmel_i2c_cmd *cmd);
+int atmel_i2c_init_read_otp_cmd(struct atmel_i2c_cmd *cmd, u16 addr);
+
+#endif /* __ATMEL_I2C_H__ */
diff --git a/drivers/nvmem/atmel-sha204a.c b/drivers/nvmem/atmel-sha204a.c
new file mode 100644
index 0000000000000000000000000000000000000000..3bf077c057286ae2f659a76ebb0c02c62f647535
--- /dev/null
+++ b/drivers/nvmem/atmel-sha204a.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Microchip / Atmel SHA204A (I2C) driver.
+ *
+ * Copyright (c) 2019 Linaro, Ltd. <ard.biesheuvel@linaro.org>
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <i2c/i2c.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "atmel-i2c.h"
+
+static int atmel_sha204a_otp_read_full(struct atmel_i2c_client_priv *i2c_priv, void *buf)
+{
+	u16 addr;
+	struct atmel_i2c_cmd cmd;
+	struct i2c_client *client = i2c_priv->client;
+	int ret;
+
+	for (addr = 0; addr < OTP_ZONE_SIZE / 4; addr++) {
+		ret = atmel_i2c_init_read_otp_cmd(&cmd, addr);
+		if (ret) {
+			dev_err(&client->dev, "failed, invalid otp address %04X\n",
+				addr);
+			return ret;
+		}
+
+		ret = atmel_i2c_send_receive(client, &cmd);
+
+		if (cmd.data[0] == 0xff) {
+			dev_err(&client->dev, "failed, device not ready\n");
+			return -EINVAL;
+		}
+
+		memcpy(buf, cmd.data + 1, 4);
+		buf += 4;
+	}
+
+	return 0;
+}
+
+static int atmel_sha204a_otp_read(void *ctx, unsigned off, void *val, size_t count)
+{
+	struct atmel_i2c_client_priv *i2c_priv = ctx;
+	int ret;
+
+	if (!i2c_priv->data) {
+		i2c_priv->data = xzalloc(OTP_ZONE_SIZE);
+		ret = atmel_sha204a_otp_read_full(i2c_priv, i2c_priv->data);
+		if (ret) {
+			free(i2c_priv->data);
+			i2c_priv->data = NULL;
+			return ret;
+		}
+	}
+
+	memcpy(val, i2c_priv->data + off, count);
+
+	return 0;
+}
+
+static int atmel_sha204a_probe(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct atmel_i2c_client_priv *i2c_priv;
+	int ret;
+
+	ret = atmel_i2c_probe(client);
+	if (ret)
+		return ret;
+
+	i2c_priv = i2c_get_clientdata(client);
+
+	i2c_priv->nvmem_config.name = dev_name(&client->dev);
+	i2c_priv->nvmem_config.dev = &client->dev;
+	i2c_priv->nvmem_config.priv = i2c_priv;
+	i2c_priv->nvmem_config.read_only = true;
+	i2c_priv->nvmem_config.reg_read = atmel_sha204a_otp_read;
+
+	i2c_priv->nvmem_config.stride = 4;
+	i2c_priv->nvmem_config.word_size = 1;
+	i2c_priv->nvmem_config.size = OTP_ZONE_SIZE;
+
+	i2c_priv->nvmem = nvmem_register(&i2c_priv->nvmem_config);
+	if (IS_ERR(i2c_priv->nvmem)) {
+		ret = PTR_ERR(i2c_priv->nvmem);
+		goto fail;
+	}
+
+fail:
+	return ret;
+}
+
+static const struct of_device_id atmel_sha204a_dt_ids[] __maybe_unused = {
+	{ .compatible = "atmel,atsha204", },
+	{ .compatible = "atmel,atsha204a", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, atmel_sha204a_dt_ids);
+
+static struct driver sha204a_driver = {
+	.name  = "atmel-sha204a",
+	.probe = atmel_sha204a_probe,
+	.of_compatible = DRV_OF_COMPAT(atmel_sha204a_dt_ids),
+};
+device_i2c_driver(sha204a_driver);
+
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_DESCRIPTION("Microchip / Atmel SHA204A (I2C) driver");
+MODULE_LICENSE("GPL v2");

-- 
2.43.0




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

* [PATCH v2 10/10] boards: enclustra-sa2: read S/N from EEPROM
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (8 preceding siblings ...)
  2025-09-25 11:59 ` [PATCH v2 09/10] nvmem: add support for Atmel sha204(a) David Picard
@ 2025-09-25 11:59 ` David Picard
  2025-09-26 12:47 ` [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 Sascha Hauer
  2025-09-30 10:40 ` Sascha Hauer
  11 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-25 11:59 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: David Picard

Read the SoM serial number from the EEPROM and set it in the
Barebox environment. The serial number can be checked:
- in Barebox, printenv global.serial_number
- in Linux, cat /proc/device-tree/serial-number

Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
---
 arch/arm/boards/enclustra-sa2/board.c          | 38 ++++++++++++++++++++++++++
 arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi | 12 ++++++++
 2 files changed, 50 insertions(+)

diff --git a/arch/arm/boards/enclustra-sa2/board.c b/arch/arm/boards/enclustra-sa2/board.c
index d2e539cbf9460adddc158885473f4ef0004dc284..03539132654716460cedc2a6edcaf13935dea22c 100644
--- a/arch/arm/boards/enclustra-sa2/board.c
+++ b/arch/arm/boards/enclustra-sa2/board.c
@@ -19,6 +19,7 @@
 /** Enclustra's MAC address vendor prefix is 20:B0:F7 */
 #define ENCLUSTRA_PREFIX            (0x20b0f7)
 #define MAC_ADDR_NUM_BYTES          (6)
+#define SERIAL_NUMBER_NUM_BYTES     (4)
 
 /*
  * Ethernet PHY: Microchip/Micrel KSZ9031RNX
@@ -89,6 +90,42 @@ static void set_mac_addr(void)
 	eth_register_ethaddr(1, enclustra_ethaddr_fallback2);
 }
 
+/*
+ * Read the SoM serial number via the atsha204a driver.
+ */
+static void set_ser_num(void)
+{
+	u8 *data = NULL;
+	uint32_t ser_num = 0;
+	char ser_num_str[12];
+	static const char * const aliases[] = { "som-sernum" };
+	struct device_node *np, *root;
+
+	root = of_get_root_node();
+
+	for (int i = 0; i < ARRAY_SIZE(aliases); i++) {
+		const char *alias = aliases[i];
+
+		np = of_find_node_by_alias(root, alias);
+		if (!np) {
+			pr_warn("%s() >> ERROR: can't find alias %s\n", __func__, alias);
+			continue;
+		}
+		data = nvmem_cell_get_and_read(np, "serial-number",
+									   SERIAL_NUMBER_NUM_BYTES);
+		if (IS_ERR(data)) {
+			pr_warn("%s() >> ERROR: can't read NVMEM cell\n", __func__);
+			data = NULL;
+		}
+	}
+	if (!data)
+		return;
+
+	ser_num = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
+	sprintf(ser_num_str, "%d", ser_num);
+	barebox_set_serial_number(ser_num_str);
+}
+
 static int socfpga_init(void)
 {
 	if (!of_machine_is_compatible("enclustra,mercury-sa2"))
@@ -99,6 +136,7 @@ static int socfpga_init(void)
 								   phy_fixup);
 
 	set_mac_addr();
+	set_ser_num();
 
 #ifdef CONFIG_MACH_SOCFPGA_ENCLUSTRA_SA2_SI5338
 	/* configure clock generator on the Enclustra ST1 baseboard: */
diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
index 78ba8008af5d60f10d6a64b0f05e97bf2381079c..ade6f4f6df3a329ee404b2b7a70fcd00c8815fdd 100644
--- a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
+++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
@@ -24,6 +24,7 @@ chosen {
 
 	aliases {
 		ethernet0 = &gmac1;
+		som-sernum = "/serial-number";
 	};
 
 	/* Adjusted the i2c labels to use generic base-board dtsi files for
@@ -46,6 +47,11 @@ memory {
 		device_type = "memory";
 		reg = <0x0 0x80000000>; /* 2GB */
 	};
+
+	serial-number {
+		nvmem-cells = <&ser_num>;
+		nvmem-cell-names = "serial-number";
+	};
 };
 
 &osc1 {
@@ -82,6 +88,12 @@ nvmem-layout {
 		#address-cells = <1>;
 		#size-cells = <1>;
 
+			ser_num: serial-number@0 {
+				reg = <0x00 0x4>;
+				nvmem-cell-cells = <1>;
+				nvmem-cell-names = "serial-number";
+			};
+
 			mac_address_0: mac@10 {
 				compatible = "mac-base";
 				reg = <0x10 0x6>;

-- 
2.43.0




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

* Re: [PATCH v2 05/10] boards: enclustra-sa2: read MAC address from EEPROM
  2025-09-25 11:59 ` [PATCH v2 05/10] boards: enclustra-sa2: read MAC address from EEPROM David Picard
@ 2025-09-26 12:40   ` Sascha Hauer
  2025-09-26 12:57     ` David Picard
  0 siblings, 1 reply; 20+ messages in thread
From: Sascha Hauer @ 2025-09-26 12:40 UTC (permalink / raw)
  To: David Picard; +Cc: BAREBOX

On Thu, Sep 25, 2025 at 01:59:12PM +0200, David Picard wrote:
> Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
> 
> ---
> v1 --> v2:
>   - Use the atsha204a driver to read the MAC address instead of
>     board-specific code.
> ---
> ---
>  arch/arm/boards/enclustra-sa2/board.c          | 74 +++++++++++++++++++++++++-
>  arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi | 16 +++++-
>  2 files changed, 87 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boards/enclustra-sa2/board.c b/arch/arm/boards/enclustra-sa2/board.c
> index d3117e9a1058738ea541f45b28c6a95184331554..4c2b44252d84c78ed8de5754051d0bf194ce8d02 100644
> --- a/arch/arm/boards/enclustra-sa2/board.c
> +++ b/arch/arm/boards/enclustra-sa2/board.c
> @@ -12,6 +12,12 @@
>  #include <fcntl.h>
>  #include <fs.h>
>  #include <mach/socfpga/cyclone5-regs.h>
> +#include <net.h>
> +#include <linux/nvmem-consumer.h>
> +
> +/** Enclustra's MAC address vendor prefix is 20:B0:F7 */
> +#define ENCLUSTRA_PREFIX            (0x20b0f7)
> +#define MAC_ADDR_NUM_BYTES          (6)
>  
>  /*
>   * Ethernet PHY: Microchip/Micrel KSZ9031RNX
> @@ -21,14 +27,78 @@ static int phy_fixup(struct phy_device *dev)
>  	return 0;
>  }
>  
> +/*
> + * Read the MAC address via the atsha204a driver.
> + *
> + * Set two consecutive MAC addresses, as specified by the manufacturer.
> + */
> +static void set_mac_addr(void)
> +{
> +	uint8_t hwaddr[MAC_ADDR_NUM_BYTES] = { 0, 0, 0, 0, 0, 0 };
> +	uint32_t hwaddr_prefix;
> +	u8 *data = NULL;
> +	static const char * const aliases[] = { "ethernet0" };
> +	struct device_node *np, *root;
> +	/* Fallback MAC addresses, used if we can't read from EEPROM: */
> +	const uint8_t enclustra_ethaddr_fallback1[] = { 0x20, 0xB0, 0xF7, 0x01,
> +													0x02, 0x03 };
> +	const uint8_t enclustra_ethaddr_fallback2[] = { 0x20, 0xB0, 0xF7, 0x01,
> +													0x02, 0x04 };

Please no fallback addresses. Just skip setting these and barebox will
use a random MAC.

> +
> +	root = of_get_root_node();
> +
> +	for (int i = 0; i < ARRAY_SIZE(aliases); i++) {
> +		const char *alias = aliases[i];
> +		np = of_find_node_by_alias(root, alias);
> +		if (!np) {
> +			pr_warn("%s() >> ERROR: can't find alias %s\n", __func__, alias);
> +			continue;
> +		}
> +		data = nvmem_cell_get_and_read(np, "mac-address", MAC_ADDR_NUM_BYTES);
> +		if (IS_ERR(data)) {
> +			pr_warn("%s() >> ERROR: can't read NVMEM cell\n", __func__);
> +			data = NULL;
> +		}
> +	}

You shouldn't need this. of_get_mac_addr_nvmem() called by the net layer
during startup should handle this for you.

> +	if (!data)
> +		goto fallback_addr;
> +
> +	memcpy(hwaddr, data, MAC_ADDR_NUM_BYTES);
> +
> +	debug("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
> +		  hwaddr[0], hwaddr[1], hwaddr[2],
> +		  hwaddr[3], hwaddr[4], hwaddr[5]);
> +
> +	/* check vendor prefix and set the environment variable */
> +	hwaddr_prefix = (hwaddr[0] << 16) | (hwaddr[1] << 8) | (hwaddr[2]);
> +	if (hwaddr_prefix == ENCLUSTRA_PREFIX) {
> +		eth_register_ethaddr(0, hwaddr);
> +		hwaddr[5]++;    /* calculate 2nd, consecutive MAC address */
> +		eth_register_ethaddr(1, hwaddr);
> +	} else {
> +		printf("%s() >> ERROR: invalid MAC address vendor prefix,"
> +			   "using fallback addresses\n", __func__);
> +		goto fallback_addr;
> +	}

Not sure what to do about the consecutive MAC address. There seems to be
beginning support for this in fixed-cell.yaml, but I can't find an
implementation for it.

> diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
> index fa80b7c63d28d17a24d63ac3ee87531ad320ddb1..55d54d289c81fa4a6d46123bcb93c5fc483485e4 100644
> --- a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
> +++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
> @@ -76,6 +76,19 @@ atsha204a: atsha204a@64 {
>  		status = "okay";
>  		compatible = "atmel,atsha204a";
>  		reg = <0x64>;
> +
> +		nvmem-layout {
> +		compatible = "fixed-layout";
> +		#address-cells = <1>;
> +		#size-cells = <1>;

Indentation wrong here.

> +
> +			mac_address_0: mac@10 {
> +				compatible = "mac-base";
> +				reg = <0x10 0x6>;
> +				nvmem-cell-cells = <1>;

must be #nvmem-cell-cells#

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] 20+ messages in thread

* Re: [PATCH v2 08/10] lib: add crc16 support
  2025-09-25 11:59 ` [PATCH v2 08/10] lib: add crc16 support David Picard
@ 2025-09-26 12:43   ` Sascha Hauer
  0 siblings, 0 replies; 20+ messages in thread
From: Sascha Hauer @ 2025-09-26 12:43 UTC (permalink / raw)
  To: David Picard; +Cc: BAREBOX

On Thu, Sep 25, 2025 at 01:59:15PM +0200, David Picard wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
> 
> This adds crc16 support taken straight out of Linux-6.16
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---

Please rebase on -next. The patch is already included there.

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] 20+ messages in thread

* Re: [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (9 preceding siblings ...)
  2025-09-25 11:59 ` [PATCH v2 10/10] boards: enclustra-sa2: read S/N from EEPROM David Picard
@ 2025-09-26 12:47 ` Sascha Hauer
  2025-09-30 10:40 ` Sascha Hauer
  11 siblings, 0 replies; 20+ messages in thread
From: Sascha Hauer @ 2025-09-26 12:47 UTC (permalink / raw)
  To: David Picard; +Cc: BAREBOX, Ahmad Fatoum

Hi David,

Please squash patches 2, 3, 4, 5, 6, 7 and 10 into one patch.
It's easier to review the end result rather than development steps.
The handoff files should stay a separate commit though because they are
quite big and only contain autogenerated stuff.

Sascha


On Thu, Sep 25, 2025 at 01:59:07PM +0200, David Picard wrote:
> Add support for the Enclustra Mercury+ SA2, a Cyclone V based
> SoC FPGA.
> https://www.enclustra.com/en/products/system-on-chip-modules/mercury-sa2/
> 
> The SoM provides a 64MiB NOR QSPI flash, DDR3, Ethernet PHY, RTC.
> 
> The Cyclone V features a hardware ARM core (aka HPS) that can boot
> from SD card (MMC), QSPI flash. This patch series focusses on MMC.
> 
> Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
> ---
> Changes in v2:
> - EDITME: describe what is new in this series revision.
> - EDITME: use bulletpoints and terse descriptions.
> - Link to v1: https://lore.kernel.org/r/20250917-boards-enclustra-sa2-add-support-v1-0-2de8f69107a1@clermont.in2p3.fr
> 
> ---
> David Picard (8):
>       Add handoff files
>       Add Enclustra Mercury+ SA2 module
>       ARM: dts: socfpga: use upstream SA2 device tree
>       ARM: dts: socfpga: adapt upstream SA2 device tree
>       boards: enclustra-sa2: read MAC address from EEPROM
>       boards: enclustra-sa2: configure SI5338
>       boards: enclustra-sa2: enable SI5338
>       boards: enclustra-sa2: read S/N from EEPROM
> 
> Sascha Hauer (2):
>       lib: add crc16 support
>       nvmem: add support for Atmel sha204(a)
> 
>  arch/arm/boards/Makefile                           |   1 +
>  arch/arm/boards/enclustra-sa2/Makefile             |   2 +
>  .../boards/enclustra-sa2/Si5338-RevB-Registers.h   | 433 +++++++++++++
>  arch/arm/boards/enclustra-sa2/board.c              | 148 +++++
>  .../boards/enclustra-sa2/iocsr_config_cyclone5.c   | 678 +++++++++++++++++++++
>  arch/arm/boards/enclustra-sa2/lowlevel.c           |  15 +
>  arch/arm/boards/enclustra-sa2/pinmux_config.c      | 241 ++++++++
>  arch/arm/boards/enclustra-sa2/pll_config.h         | 107 ++++
>  arch/arm/boards/enclustra-sa2/sdram_config.h       | 112 ++++
>  arch/arm/boards/enclustra-sa2/sequencer_auto.h     | 225 +++++++
>  .../boards/enclustra-sa2/sequencer_auto_ac_init.c  |  67 ++
>  .../enclustra-sa2/sequencer_auto_inst_init.c       | 158 +++++
>  arch/arm/boards/enclustra-sa2/sequencer_defines.h  | 165 +++++
>  arch/arm/boards/enclustra-sa2/si5338_config.c      | 252 ++++++++
>  arch/arm/boards/enclustra-sa2/si5338_config.h      |  22 +
>  arch/arm/configs/socfpga-xload_defconfig           |   1 +
>  arch/arm/configs/socfpga_defconfig                 |   3 +-
>  arch/arm/dts/Makefile                              |   1 +
>  arch/arm/dts/socfpga_cyclone5_mercury_sa2.dts      |  17 +
>  arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi     | 213 +++++++
>  arch/arm/mach-socfpga/Kconfig                      |   8 +
>  drivers/nvmem/Kconfig                              |  15 +
>  drivers/nvmem/Makefile                             |   2 +
>  drivers/nvmem/atmel-i2c.c                          | 302 +++++++++
>  drivers/nvmem/atmel-i2c.h                          | 180 ++++++
>  drivers/nvmem/atmel-sha204a.c                      | 114 ++++
>  images/Makefile.socfpga                            |   8 +
>  include/linux/crc16.h                              |  21 +
>  lib/Kconfig                                        |   3 +
>  lib/Makefile                                       |   1 +
>  lib/crc16.c                                        |  69 +++
>  31 files changed, 3582 insertions(+), 2 deletions(-)
> ---
> base-commit: 85c11b44889eb73921b2095f2c42492ac3d686a0
> change-id: 20250916-boards-enclustra-sa2-add-support-4704233a6861
> 
> Best regards,
> -- 
> David Picard <david.picard@clermont.in2p3.fr>
> 
> 

-- 
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] 20+ messages in thread

* Re: [PATCH v2 05/10] boards: enclustra-sa2: read MAC address from EEPROM
  2025-09-26 12:40   ` Sascha Hauer
@ 2025-09-26 12:57     ` David Picard
  2025-09-29  8:04       ` David Picard
  0 siblings, 1 reply; 20+ messages in thread
From: David Picard @ 2025-09-26 12:57 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: BAREBOX

The SoM manual states, p46, bottom:
"The Ethernet MAC address is stored using big-endian byte order (MSB on 
the lowest address). Each module
is assigned two sequential MAC addresses; only the lower one is stored 
in the EEPROM."
https://filesender.renater.fr/?s=download&token=c553d226-7c90-41e3-8c74-96393f1f1edd 


What's the problem with fallback addresses? At least, the board will 
look like an Enclustra product.


Le 26/09/2025 à 14:40, Sascha Hauer a écrit :
> On Thu, Sep 25, 2025 at 01:59:12PM +0200, David Picard wrote:
>> Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
>>
>> ---
>> v1 --> v2:
>>    - Use the atsha204a driver to read the MAC address instead of
>>      board-specific code.
>> ---
>> ---
>>   arch/arm/boards/enclustra-sa2/board.c          | 74 +++++++++++++++++++++++++-
>>   arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi | 16 +++++-
>>   2 files changed, 87 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/boards/enclustra-sa2/board.c b/arch/arm/boards/enclustra-sa2/board.c
>> index d3117e9a1058738ea541f45b28c6a95184331554..4c2b44252d84c78ed8de5754051d0bf194ce8d02 100644
>> --- a/arch/arm/boards/enclustra-sa2/board.c
>> +++ b/arch/arm/boards/enclustra-sa2/board.c
>> @@ -12,6 +12,12 @@
>>   #include <fcntl.h>
>>   #include <fs.h>
>>   #include <mach/socfpga/cyclone5-regs.h>
>> +#include <net.h>
>> +#include <linux/nvmem-consumer.h>
>> +
>> +/** Enclustra's MAC address vendor prefix is 20:B0:F7 */
>> +#define ENCLUSTRA_PREFIX            (0x20b0f7)
>> +#define MAC_ADDR_NUM_BYTES          (6)
>>   
>>   /*
>>    * Ethernet PHY: Microchip/Micrel KSZ9031RNX
>> @@ -21,14 +27,78 @@ static int phy_fixup(struct phy_device *dev)
>>   	return 0;
>>   }
>>   
>> +/*
>> + * Read the MAC address via the atsha204a driver.
>> + *
>> + * Set two consecutive MAC addresses, as specified by the manufacturer.
>> + */
>> +static void set_mac_addr(void)
>> +{
>> +	uint8_t hwaddr[MAC_ADDR_NUM_BYTES] = { 0, 0, 0, 0, 0, 0 };
>> +	uint32_t hwaddr_prefix;
>> +	u8 *data = NULL;
>> +	static const char * const aliases[] = { "ethernet0" };
>> +	struct device_node *np, *root;
>> +	/* Fallback MAC addresses, used if we can't read from EEPROM: */
>> +	const uint8_t enclustra_ethaddr_fallback1[] = { 0x20, 0xB0, 0xF7, 0x01,
>> +													0x02, 0x03 };
>> +	const uint8_t enclustra_ethaddr_fallback2[] = { 0x20, 0xB0, 0xF7, 0x01,
>> +													0x02, 0x04 };
> Please no fallback addresses. Just skip setting these and barebox will
> use a random MAC.
>
>> +
>> +	root = of_get_root_node();
>> +
>> +	for (int i = 0; i < ARRAY_SIZE(aliases); i++) {
>> +		const char *alias = aliases[i];
>> +		np = of_find_node_by_alias(root, alias);
>> +		if (!np) {
>> +			pr_warn("%s() >> ERROR: can't find alias %s\n", __func__, alias);
>> +			continue;
>> +		}
>> +		data = nvmem_cell_get_and_read(np, "mac-address", MAC_ADDR_NUM_BYTES);
>> +		if (IS_ERR(data)) {
>> +			pr_warn("%s() >> ERROR: can't read NVMEM cell\n", __func__);
>> +			data = NULL;
>> +		}
>> +	}
> You shouldn't need this. of_get_mac_addr_nvmem() called by the net layer
> during startup should handle this for you.
>
>> +	if (!data)
>> +		goto fallback_addr;
>> +
>> +	memcpy(hwaddr, data, MAC_ADDR_NUM_BYTES);
>> +
>> +	debug("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
>> +		  hwaddr[0], hwaddr[1], hwaddr[2],
>> +		  hwaddr[3], hwaddr[4], hwaddr[5]);
>> +
>> +	/* check vendor prefix and set the environment variable */
>> +	hwaddr_prefix = (hwaddr[0] << 16) | (hwaddr[1] << 8) | (hwaddr[2]);
>> +	if (hwaddr_prefix == ENCLUSTRA_PREFIX) {
>> +		eth_register_ethaddr(0, hwaddr);
>> +		hwaddr[5]++;    /* calculate 2nd, consecutive MAC address */
>> +		eth_register_ethaddr(1, hwaddr);
>> +	} else {
>> +		printf("%s() >> ERROR: invalid MAC address vendor prefix,"
>> +			   "using fallback addresses\n", __func__);
>> +		goto fallback_addr;
>> +	}
> Not sure what to do about the consecutive MAC address. There seems to be
> beginning support for this in fixed-cell.yaml, but I can't find an
> implementation for it.
>
>> diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
>> index fa80b7c63d28d17a24d63ac3ee87531ad320ddb1..55d54d289c81fa4a6d46123bcb93c5fc483485e4 100644
>> --- a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
>> +++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
>> @@ -76,6 +76,19 @@ atsha204a: atsha204a@64 {
>>   		status = "okay";
>>   		compatible = "atmel,atsha204a";
>>   		reg = <0x64>;
>> +
>> +		nvmem-layout {
>> +		compatible = "fixed-layout";
>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
> Indentation wrong here.
>
>> +
>> +			mac_address_0: mac@10 {
>> +				compatible = "mac-base";
>> +				reg = <0x10 0x6>;
>> +				nvmem-cell-cells = <1>;
> must be #nvmem-cell-cells#
>
> Sascha
>




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

* Re: [PATCH v2 05/10] boards: enclustra-sa2: read MAC address from EEPROM
  2025-09-26 12:57     ` David Picard
@ 2025-09-29  8:04       ` David Picard
  0 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-29  8:04 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: BAREBOX

Hello,

Did you make up your mind, in the light of the manual statement below?

David

Le 26/09/2025 à 14:57, David Picard a écrit :
> The SoM manual states, p46, bottom:
> "The Ethernet MAC address is stored using big-endian byte order (MSB 
> on the lowest address). Each module
> is assigned two sequential MAC addresses; only the lower one is stored 
> in the EEPROM."
> https://filesender.renater.fr/?s=download&token=c553d226-7c90-41e3-8c74-96393f1f1edd 
>
>
> What's the problem with fallback addresses? At least, the board will 
> look like an Enclustra product.
>
>
> Le 26/09/2025 à 14:40, Sascha Hauer a écrit :
>> On Thu, Sep 25, 2025 at 01:59:12PM +0200, David Picard wrote:
>>> Signed-off-by: David Picard <david.picard@clermont.in2p3.fr>
>>>
>>> ---
>>> v1 --> v2:
>>>    - Use the atsha204a driver to read the MAC address instead of
>>>      board-specific code.
>>> ---
>>> ---
>>>   arch/arm/boards/enclustra-sa2/board.c          | 74 
>>> +++++++++++++++++++++++++-
>>>   arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi | 16 +++++-
>>>   2 files changed, 87 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/arch/arm/boards/enclustra-sa2/board.c 
>>> b/arch/arm/boards/enclustra-sa2/board.c
>>> index 
>>> d3117e9a1058738ea541f45b28c6a95184331554..4c2b44252d84c78ed8de5754051d0bf194ce8d02 
>>> 100644
>>> --- a/arch/arm/boards/enclustra-sa2/board.c
>>> +++ b/arch/arm/boards/enclustra-sa2/board.c
>>> @@ -12,6 +12,12 @@
>>>   #include <fcntl.h>
>>>   #include <fs.h>
>>>   #include <mach/socfpga/cyclone5-regs.h>
>>> +#include <net.h>
>>> +#include <linux/nvmem-consumer.h>
>>> +
>>> +/** Enclustra's MAC address vendor prefix is 20:B0:F7 */
>>> +#define ENCLUSTRA_PREFIX            (0x20b0f7)
>>> +#define MAC_ADDR_NUM_BYTES          (6)
>>>     /*
>>>    * Ethernet PHY: Microchip/Micrel KSZ9031RNX
>>> @@ -21,14 +27,78 @@ static int phy_fixup(struct phy_device *dev)
>>>       return 0;
>>>   }
>>>   +/*
>>> + * Read the MAC address via the atsha204a driver.
>>> + *
>>> + * Set two consecutive MAC addresses, as specified by the 
>>> manufacturer.
>>> + */
>>> +static void set_mac_addr(void)
>>> +{
>>> +    uint8_t hwaddr[MAC_ADDR_NUM_BYTES] = { 0, 0, 0, 0, 0, 0 };
>>> +    uint32_t hwaddr_prefix;
>>> +    u8 *data = NULL;
>>> +    static const char * const aliases[] = { "ethernet0" };
>>> +    struct device_node *np, *root;
>>> +    /* Fallback MAC addresses, used if we can't read from EEPROM: */
>>> +    const uint8_t enclustra_ethaddr_fallback1[] = { 0x20, 0xB0, 
>>> 0xF7, 0x01,
>>> +                                                    0x02, 0x03 };
>>> +    const uint8_t enclustra_ethaddr_fallback2[] = { 0x20, 0xB0, 
>>> 0xF7, 0x01,
>>> +                                                    0x02, 0x04 };
>> Please no fallback addresses. Just skip setting these and barebox will
>> use a random MAC.
>>
>>> +
>>> +    root = of_get_root_node();
>>> +
>>> +    for (int i = 0; i < ARRAY_SIZE(aliases); i++) {
>>> +        const char *alias = aliases[i];
>>> +        np = of_find_node_by_alias(root, alias);
>>> +        if (!np) {
>>> +            pr_warn("%s() >> ERROR: can't find alias %s\n", 
>>> __func__, alias);
>>> +            continue;
>>> +        }
>>> +        data = nvmem_cell_get_and_read(np, "mac-address", 
>>> MAC_ADDR_NUM_BYTES);
>>> +        if (IS_ERR(data)) {
>>> +            pr_warn("%s() >> ERROR: can't read NVMEM cell\n", 
>>> __func__);
>>> +            data = NULL;
>>> +        }
>>> +    }
>> You shouldn't need this. of_get_mac_addr_nvmem() called by the net layer
>> during startup should handle this for you.
>>
>>> +    if (!data)
>>> +        goto fallback_addr;
>>> +
>>> +    memcpy(hwaddr, data, MAC_ADDR_NUM_BYTES);
>>> +
>>> +    debug("MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
>>> +          hwaddr[0], hwaddr[1], hwaddr[2],
>>> +          hwaddr[3], hwaddr[4], hwaddr[5]);
>>> +
>>> +    /* check vendor prefix and set the environment variable */
>>> +    hwaddr_prefix = (hwaddr[0] << 16) | (hwaddr[1] << 8) | 
>>> (hwaddr[2]);
>>> +    if (hwaddr_prefix == ENCLUSTRA_PREFIX) {
>>> +        eth_register_ethaddr(0, hwaddr);
>>> +        hwaddr[5]++;    /* calculate 2nd, consecutive MAC address */
>>> +        eth_register_ethaddr(1, hwaddr);
>>> +    } else {
>>> +        printf("%s() >> ERROR: invalid MAC address vendor prefix,"
>>> +               "using fallback addresses\n", __func__);
>>> +        goto fallback_addr;
>>> +    }
>> Not sure what to do about the consecutive MAC address. There seems to be
>> beginning support for this in fixed-cell.yaml, but I can't find an
>> implementation for it.
>>
>>> diff --git a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi 
>>> b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
>>> index 
>>> fa80b7c63d28d17a24d63ac3ee87531ad320ddb1..55d54d289c81fa4a6d46123bcb93c5fc483485e4 
>>> 100644
>>> --- a/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
>>> +++ b/arch/arm/dts/socfpga_cyclone5_mercury_sa2.dtsi
>>> @@ -76,6 +76,19 @@ atsha204a: atsha204a@64 {
>>>           status = "okay";
>>>           compatible = "atmel,atsha204a";
>>>           reg = <0x64>;
>>> +
>>> +        nvmem-layout {
>>> +        compatible = "fixed-layout";
>>> +        #address-cells = <1>;
>>> +        #size-cells = <1>;
>> Indentation wrong here.
>>
>>> +
>>> +            mac_address_0: mac@10 {
>>> +                compatible = "mac-base";
>>> +                reg = <0x10 0x6>;
>>> +                nvmem-cell-cells = <1>;
>> must be #nvmem-cell-cells#
>>
>> Sascha
>>
>
>




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

* Re: [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2
  2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
                   ` (10 preceding siblings ...)
  2025-09-26 12:47 ` [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 Sascha Hauer
@ 2025-09-30 10:40 ` Sascha Hauer
  2025-09-30 11:47   ` David Picard
       [not found]   ` <aade6cdb-3244-4468-8bab-215a54fdef15@clermont.in2p3.fr>
  11 siblings, 2 replies; 20+ messages in thread
From: Sascha Hauer @ 2025-09-30 10:40 UTC (permalink / raw)
  To: BAREBOX, David Picard; +Cc: Ahmad Fatoum


On Thu, 25 Sep 2025 13:59:07 +0200, David Picard wrote:
> Add support for the Enclustra Mercury+ SA2, a Cyclone V based
> SoC FPGA.
> https://www.enclustra.com/en/products/system-on-chip-modules/mercury-sa2/
> 
> The SoM provides a 64MiB NOR QSPI flash, DDR3, Ethernet PHY, RTC.
> 
> The Cyclone V features a hardware ARM core (aka HPS) that can boot
> from SD card (MMC), QSPI flash. This patch series focusses on MMC.
> 
> [...]

Applied, thanks!

[01/10] Add handoff files
        (no commit info)
[02/10] Add Enclustra Mercury+ SA2 module
        (no commit info)
[03/10] ARM: dts: socfpga: use upstream SA2 device tree
        (no commit info)
[04/10] ARM: dts: socfpga: adapt upstream SA2 device tree
        (no commit info)
[05/10] boards: enclustra-sa2: read MAC address from EEPROM
        (no commit info)
[06/10] boards: enclustra-sa2: configure SI5338
        (no commit info)
[07/10] boards: enclustra-sa2: enable SI5338
        (no commit info)
[08/10] lib: add crc16 support
        https://git.pengutronix.de/cgit/barebox/commit/?id=83865ed69b4d (link may not be stable)
[09/10] nvmem: add support for Atmel sha204(a)
        https://git.pengutronix.de/cgit/barebox/commit/?id=0837819622a2 (link may not be stable)
[10/10] boards: enclustra-sa2: read S/N from EEPROM
        (no commit info)

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




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

* Re: [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2
  2025-09-30 10:40 ` Sascha Hauer
@ 2025-09-30 11:47   ` David Picard
  2025-09-30 11:49     ` David Picard
       [not found]   ` <aade6cdb-3244-4468-8bab-215a54fdef15@clermont.in2p3.fr>
  1 sibling, 1 reply; 20+ messages in thread
From: David Picard @ 2025-09-30 11:47 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Ahmad Fatoum

Hi,

I was about to submit v3, with the changes you requested.

I was waiting for you to decide wether I keep the fallback MAC 
addresses, as suggested by the manufacturer manual that I shared, or if 
I drop them and let Barebox set a random one.

David

Le 30/09/2025 à 12:40, Sascha Hauer a écrit :
> On Thu, 25 Sep 2025 13:59:07 +0200, David Picard wrote:
>> Add support for the Enclustra Mercury+ SA2, a Cyclone V based
>> SoC FPGA.
>> https://www.enclustra.com/en/products/system-on-chip-modules/mercury-sa2/
>>
>> The SoM provides a 64MiB NOR QSPI flash, DDR3, Ethernet PHY, RTC.
>>
>> The Cyclone V features a hardware ARM core (aka HPS) that can boot
>> from SD card (MMC), QSPI flash. This patch series focusses on MMC.
>>
>> [...]
> Applied, thanks!
>
> [01/10] Add handoff files
>          (no commit info)
> [02/10] Add Enclustra Mercury+ SA2 module
>          (no commit info)
> [03/10] ARM: dts: socfpga: use upstream SA2 device tree
>          (no commit info)
> [04/10] ARM: dts: socfpga: adapt upstream SA2 device tree
>          (no commit info)
> [05/10] boards: enclustra-sa2: read MAC address from EEPROM
>          (no commit info)
> [06/10] boards: enclustra-sa2: configure SI5338
>          (no commit info)
> [07/10] boards: enclustra-sa2: enable SI5338
>          (no commit info)
> [08/10] lib: add crc16 support
>          https://git.pengutronix.de/cgit/barebox/commit/?id=83865ed69b4d (link may not be stable)
> [09/10] nvmem: add support for Atmel sha204(a)
>          https://git.pengutronix.de/cgit/barebox/commit/?id=0837819622a2 (link may not be stable)
> [10/10] boards: enclustra-sa2: read S/N from EEPROM
>          (no commit info)
>
> Best regards,




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

* Re: [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2
  2025-09-30 11:47   ` David Picard
@ 2025-09-30 11:49     ` David Picard
  0 siblings, 0 replies; 20+ messages in thread
From: David Picard @ 2025-09-30 11:49 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Ahmad Fatoum

Sorry, I didn't see your other message.

Le 30/09/2025 à 13:47, David Picard a écrit :
> Hi,
>
> I was about to submit v3, with the changes you requested.
>
> I was waiting for you to decide wether I keep the fallback MAC 
> addresses, as suggested by the manufacturer manual that I shared, or 
> if I drop them and let Barebox set a random one.
>
> David
>
> Le 30/09/2025 à 12:40, Sascha Hauer a écrit :
>> On Thu, 25 Sep 2025 13:59:07 +0200, David Picard wrote:
>>> Add support for the Enclustra Mercury+ SA2, a Cyclone V based
>>> SoC FPGA.
>>> https://www.enclustra.com/en/products/system-on-chip-modules/mercury-sa2/ 
>>>
>>>
>>> The SoM provides a 64MiB NOR QSPI flash, DDR3, Ethernet PHY, RTC.
>>>
>>> The Cyclone V features a hardware ARM core (aka HPS) that can boot
>>> from SD card (MMC), QSPI flash. This patch series focusses on MMC.
>>>
>>> [...]
>> Applied, thanks!
>>
>> [01/10] Add handoff files
>>          (no commit info)
>> [02/10] Add Enclustra Mercury+ SA2 module
>>          (no commit info)
>> [03/10] ARM: dts: socfpga: use upstream SA2 device tree
>>          (no commit info)
>> [04/10] ARM: dts: socfpga: adapt upstream SA2 device tree
>>          (no commit info)
>> [05/10] boards: enclustra-sa2: read MAC address from EEPROM
>>          (no commit info)
>> [06/10] boards: enclustra-sa2: configure SI5338
>>          (no commit info)
>> [07/10] boards: enclustra-sa2: enable SI5338
>>          (no commit info)
>> [08/10] lib: add crc16 support
>> https://git.pengutronix.de/cgit/barebox/commit/?id=83865ed69b4d (link 
>> may not be stable)
>> [09/10] nvmem: add support for Atmel sha204(a)
>> https://git.pengutronix.de/cgit/barebox/commit/?id=0837819622a2 (link 
>> may not be stable)
>> [10/10] boards: enclustra-sa2: read S/N from EEPROM
>>          (no commit info)
>>
>> Best regards,
>
>




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

* Re: [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2
       [not found]   ` <aade6cdb-3244-4468-8bab-215a54fdef15@clermont.in2p3.fr>
@ 2025-10-01  8:29     ` Sascha Hauer
  0 siblings, 0 replies; 20+ messages in thread
From: Sascha Hauer @ 2025-10-01  8:29 UTC (permalink / raw)
  To: David Picard; +Cc: BAREBOX, Ahmad Fatoum

On Tue, Sep 30, 2025 at 03:04:52PM +0200, David Picard wrote:
>    Hi,
> 
>    It works. Except you missed the changes in arch/arm/dts/socfpga_cyclo
>    ne5_mercury_sa2.dtsi
>    Here is a patch to fix it.

Ok, thanks. I merged in the missing change.

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] 20+ messages in thread

end of thread, other threads:[~2025-10-01  8:29 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-25 11:59 [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 David Picard
2025-09-25 11:59 ` [PATCH v2 01/10] Add handoff files David Picard
2025-09-25 11:59 ` [PATCH v2 02/10] Add Enclustra Mercury+ SA2 module David Picard
2025-09-25 11:59 ` [PATCH v2 03/10] ARM: dts: socfpga: use upstream SA2 device tree David Picard
2025-09-25 11:59 ` [PATCH v2 04/10] ARM: dts: socfpga: adapt " David Picard
2025-09-25 11:59 ` [PATCH v2 05/10] boards: enclustra-sa2: read MAC address from EEPROM David Picard
2025-09-26 12:40   ` Sascha Hauer
2025-09-26 12:57     ` David Picard
2025-09-29  8:04       ` David Picard
2025-09-25 11:59 ` [PATCH v2 06/10] boards: enclustra-sa2: configure SI5338 David Picard
2025-09-25 11:59 ` [PATCH v2 07/10] boards: enclustra-sa2: enable SI5338 David Picard
2025-09-25 11:59 ` [PATCH v2 08/10] lib: add crc16 support David Picard
2025-09-26 12:43   ` Sascha Hauer
2025-09-25 11:59 ` [PATCH v2 09/10] nvmem: add support for Atmel sha204(a) David Picard
2025-09-25 11:59 ` [PATCH v2 10/10] boards: enclustra-sa2: read S/N from EEPROM David Picard
2025-09-26 12:47 ` [PATCH v2 00/10] ARM: boards: add support for Enclustra Mercury SA2 Sascha Hauer
2025-09-30 10:40 ` Sascha Hauer
2025-09-30 11:47   ` David Picard
2025-09-30 11:49     ` David Picard
     [not found]   ` <aade6cdb-3244-4468-8bab-215a54fdef15@clermont.in2p3.fr>
2025-10-01  8:29     ` Sascha Hauer

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