board: cssi: Load FPGA on MCR3000 board

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
This commit is contained in:
Christophe Leroy 2024-04-14 11:17:13 +02:00
parent 60dcbecfe0
commit 313ffe2746
3 changed files with 9831 additions and 1 deletions

View File

@ -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>;
};
};
};

File diff suppressed because it is too large Load Diff

View File

@ -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");