diff mbox series

[v2,16/17] board: cssi: Load FPGA on MCR3000 board

Message ID 2ad3e3a14b9cad484681889e7cb66335a85a6234.1713160866.git.christophe.leroy@csgroup.eu
State Accepted
Delegated to: Tom Rini
Headers show
Series Misc changes for CSSI boards | expand

Commit Message

Christophe Leroy April 15, 2024, 6:07 a.m. UTC
Unlike CMPC885 and CMPCPRO boards, the FPGA of MCR3000 board doesn't
load code automatically but needs to be loaded by software through SPI.

Until now it was loaded later by Linux, but we'd like U-boot to have
access to some information that require the FPGA, like board address
in racks.

So, implemented the load of FPGA in U-boot.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
To avoid spamming your email boxes, the code isn't included in
the emailed patch but will be present in the PULL request
---
 arch/powerpc/dts/mcr3000.dts   |  6 ++++-
 board/cssi/mcr3000/fpga_code.h | 10 +++++++
 board/cssi/mcr3000/mcr3000.c   | 48 ++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 1 deletion(-)
 create mode 100644 board/cssi/mcr3000/fpga_code.h
diff mbox series

Patch

diff --git a/arch/powerpc/dts/mcr3000.dts b/arch/powerpc/dts/mcr3000.dts
index f678951e22..aa46007b8d 100644
--- a/arch/powerpc/dts/mcr3000.dts
+++ b/arch/powerpc/dts/mcr3000.dts
@@ -33,12 +33,16 @@ 
 			#size-cells = <0>;
 			cell-index = <0>;
 			compatible = "fsl,mpc8xx-spi";
-			gpios = <&csspi 2 0>;
+			gpios = <&csspi 2 0
+				 &csspi 0 0>;
 
 			temp@0 {
 				reg = <0>;
 				compatible = "ti,lm74";
 			};
+			fpga@1 {
+				reg = <1>;
+			};
 		};
 	};
 
diff --git a/board/cssi/mcr3000/fpga_code.h b/board/cssi/mcr3000/fpga_code.h
new file mode 100644
index 0000000000..0d710ba41f
--- /dev/null
+++ b/board/cssi/mcr3000/fpga_code.h
@@ -0,0 +1,10 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2010 CS Systemes d'Information
+ *
+ * uCORE FPGA code for MCR3000 board
+ */
+
+u32 fpga_code[] = {
+	0xdeadbeef,
+};
diff --git a/board/cssi/mcr3000/mcr3000.c b/board/cssi/mcr3000/mcr3000.c
index 537d7fa124..15a2d0d946 100644
--- a/board/cssi/mcr3000/mcr3000.c
+++ b/board/cssi/mcr3000/mcr3000.c
@@ -13,12 +13,15 @@ 
 #include <mpc8xx.h>
 #include <fdt_support.h>
 #include <serial.h>
+#include <spi.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <dm/uclass.h>
 #include <wdt.h>
 #include <linux/delay.h>
 
+#include "fpga_code.h"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #define SDRAM_MAX_SIZE			(32 * 1024 * 1024)
@@ -107,6 +110,49 @@  int dram_init(void)
 	return 0;
 }
 
+static int load_fpga(void)
+{
+	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
+	struct udevice *master;
+	struct spi_slave *slave;
+	int ret;
+
+	ret = uclass_get_device(UCLASS_SPI, 0, &master);
+	if (ret)
+		return ret;
+
+	ret = _spi_get_bus_and_cs(0, 1, 10000000, 0, "spi_generic_drv",
+				  "generic_0:0", &master, &slave);
+	if (ret)
+		return ret;
+
+	ret = spi_claim_bus(slave);
+
+	printf("FPGA Init ... ");
+
+	clrbits_be32(&immr->im_cpm.cp_pbdat, 0x20000);
+	while ((in_be32(&immr->im_cpm.cp_pbdat) & 0x8000))
+		;
+	setbits_be32(&immr->im_cpm.cp_pbdat, 0x20000);
+	while (!(in_be32(&immr->im_cpm.cp_pbdat) & 0x8000))
+		;
+
+	printf("Loading ... ");
+
+	ret = spi_xfer(slave, sizeof(fpga_code) * BITS_PER_BYTE, fpga_code, NULL, 0);
+
+	spi_release_bus(slave);
+
+	if ((in_be32(&immr->im_cpm.cp_pbdat) & 0x4000)) {
+		printf("Done\n");
+	} else {
+		printf("FAILED\n");
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
 int misc_init_r(void)
 {
 	immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
@@ -121,6 +167,8 @@  int misc_init_r(void)
 	setbits_be32(&immr->im_cpm.cp_pbdir, 0xf);
 	clrbits_be32(&immr->im_cpm.cp_pbdat, 0x1);
 
+	load_fpga();
+
 	/* if BTN_ACQ_AL is pressed then bootdelay is changed to 60 second */
 	if ((in_be16(&iop->iop_pcdat) & 0x0004) == 0)
 		env_set("bootdelay", "60");