summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@csgroup.eu>2024-04-12 12:01:25 +0200
committerChristophe Leroy <christophe.leroy@csgroup.eu>2024-04-18 15:47:46 +0200
commitc58074af2ef93dbf4d6e6164d51eefbf562fe7c5 (patch)
tree29b1f8a3ea1a7d8dac99c64f5dff9c54e31e326f
parentc578728d2e33754e38af869f6cdf992d18d058da (diff)
board: cssi: Add support for SPI bus on MCR3000 board
MCR3000 board has some components tied to the SPI bus, like the Texas Instruments LM74 temperature sensor. Add support for SPI bus. The SPI chipselects are a bit special in the way that they are driven by 3 bits in a register of the board's CPLD where the value writen in those bits exclusively activates one of the 7 possible chipselects and value 0 sets all chipselets to inactive. So add a special GPIO driver that simulates GPIOs for those chipselect. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
-rw-r--r--arch/powerpc/dts/mcr3000.dts31
-rw-r--r--board/cssi/mcr3000/Makefile1
-rw-r--r--board/cssi/mcr3000/mcr3000.c5
-rw-r--r--board/cssi/mcr3000/mcr3000_gpio.c109
-rw-r--r--configs/MCR3000_defconfig5
5 files changed, 151 insertions, 0 deletions
diff --git a/arch/powerpc/dts/mcr3000.dts b/arch/powerpc/dts/mcr3000.dts
index c4d7737bc67..edcd8358d09 100644
--- a/arch/powerpc/dts/mcr3000.dts
+++ b/arch/powerpc/dts/mcr3000.dts
@@ -26,6 +26,37 @@
timeout-sec = <2>;
hw_margin_ms = <1000>;
};
+
+ spi: spi@aa0 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl,mpc8xx-spi";
+ };
+ };
+
+ localbus@ff000100 {
+ compatible = "s3k,mcr3000-localbus", "fsl,pq1-localbus", "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ reg = <0xff000100 0x40>; // ORx and BRx register
+
+ ranges = <0 0 0x04000000 0x04000000 // BOOT
+ 1 0 0x00000000 0x04000000 // SDRAM
+ 2 0 0x08000000 0x04000000 // RAMDP
+ 3 0 0x0C000000 0x04000000 // NAND
+ 4 0 0x10000000 0x04000000 // Periphs
+ 5 0 0x14000000 0x04000000 // FPGA
+ 6 0 0x18000000 0x04000000 // mezzanine
+ 7 0 0x1c000000 0x04000000>; // DSP
+
+ csspi: gpio-controller@2 {
+ #gpio-cells = <2>;
+ compatible = "s3k,mcr3000-cpld-csspi";
+ reg = <4 0x802 2>;
+ gpio-controller;
+ };
};
SERIAL: smc@0 {
diff --git a/board/cssi/mcr3000/Makefile b/board/cssi/mcr3000/Makefile
index 7803016af3a..846fd680e99 100644
--- a/board/cssi/mcr3000/Makefile
+++ b/board/cssi/mcr3000/Makefile
@@ -6,3 +6,4 @@
obj-y += mcr3000.o
obj-$(CONFIG_CMD_NAND) += nand.o
+obj-$(CONFIG_MPC8XX_SPI) += mcr3000_gpio.o
diff --git a/board/cssi/mcr3000/mcr3000.c b/board/cssi/mcr3000/mcr3000.c
index 8857c9e42c7..537d7fa124b 100644
--- a/board/cssi/mcr3000/mcr3000.c
+++ b/board/cssi/mcr3000/mcr3000.c
@@ -116,6 +116,11 @@ int misc_init_r(void)
clrbits_be16(&iop->iop_pcpar, 0x4);
clrbits_be16(&iop->iop_pcdir, 0x4);
+ /* Activate SPI */
+ clrsetbits_be32(&immr->im_cpm.cp_pbpar, 0x1, 0xe);
+ setbits_be32(&immr->im_cpm.cp_pbdir, 0xf);
+ clrbits_be32(&immr->im_cpm.cp_pbdat, 0x1);
+
/* 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");
diff --git a/board/cssi/mcr3000/mcr3000_gpio.c b/board/cssi/mcr3000/mcr3000_gpio.c
new file mode 100644
index 00000000000..2bba14e6e57
--- /dev/null
+++ b/board/cssi/mcr3000/mcr3000_gpio.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2024 CS GROUP France
+ * Christophe Leroy <christophe.leroy@csgroup.eu>
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <asm/gpio.h>
+#include <malloc.h>
+
+#include "../common/common.h"
+
+struct mcr3000_spi_gpio_plat {
+ ulong addr;
+};
+
+struct mcr3000_spi_gpio_data {
+ void __iomem *base;
+};
+
+static int mcr3000_spi_gpio_set_value(struct udevice *dev, uint gpio, int value)
+{
+ struct mcr3000_spi_gpio_data *data = dev_get_priv(dev);
+
+ if (value)
+ clrsetbits_be16(data->base, 7 << 5, (gpio & 7) << 5);
+ else
+ clrbits_be16(data->base, 7 << 5);
+
+ return 0;
+}
+
+static int mcr3000_spi_gpio_get_value(struct udevice *dev, uint gpio)
+{
+ struct mcr3000_spi_gpio_data *data = dev_get_priv(dev);
+
+ return gpio == ((in_be16(data->base) >> 5) & 7);
+}
+
+static int mcr3000_spi_gpio_direction_input(struct udevice *dev, uint gpio)
+{
+ return 0;
+}
+
+static int mcr3000_spi_gpio_get_function(struct udevice *dev, uint gpio)
+{
+ return GPIOF_OUTPUT;
+}
+
+static int mcr3000_spi_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+ struct mcr3000_spi_gpio_plat *plat = dev_get_plat(dev);
+ fdt_addr_t addr;
+ u32 reg[2];
+
+ dev_read_u32_array(dev, "reg", reg, 2);
+ addr = dev_translate_address(dev, reg);
+
+ plat->addr = addr;
+
+ return 0;
+}
+
+static int mcr3000_spi_gpio_probe(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct mcr3000_spi_gpio_data *data = dev_get_priv(dev);
+ struct mcr3000_spi_gpio_plat *plat = dev_get_plat(dev);
+ char name[32], *str;
+
+ data->base = map_sysmem(plat->addr, 2);
+
+ snprintf(name, sizeof(name), "CHIPSELECT@%lx_", plat->addr);
+ str = strdup(name);
+
+ if (!str)
+ return -ENOMEM;
+
+ uc_priv->bank_name = str;
+ uc_priv->gpio_count = 16;
+
+ return 0;
+}
+
+static const struct dm_gpio_ops gpio_mcr3000_spi_ops = {
+ .get_value = mcr3000_spi_gpio_get_value,
+ .set_value = mcr3000_spi_gpio_set_value,
+ .direction_input = mcr3000_spi_gpio_direction_input,
+ .direction_output = mcr3000_spi_gpio_set_value,
+ .get_function = mcr3000_spi_gpio_get_function,
+};
+
+static const struct udevice_id mcr3000_spi_gpio_ids[] = {
+ { .compatible = "s3k,mcr3000-cpld-csspi"},
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mcr3000_spi_gpio) = {
+ .name = "mcr3000_spi_chipselect",
+ .id = UCLASS_GPIO,
+ .ops = &gpio_mcr3000_spi_ops,
+ .of_to_plat = mcr3000_spi_gpio_ofdata_to_platdata,
+ .plat_auto = sizeof(struct mcr3000_spi_gpio_plat),
+ .of_match = mcr3000_spi_gpio_ids,
+ .probe = mcr3000_spi_gpio_probe,
+ .priv_auto = sizeof(struct mcr3000_spi_gpio_data),
+};
diff --git a/configs/MCR3000_defconfig b/configs/MCR3000_defconfig
index 8a88fb445c7..ce34c2aa88f 100644
--- a/configs/MCR3000_defconfig
+++ b/configs/MCR3000_defconfig
@@ -2,6 +2,7 @@ CONFIG_PPC=y
CONFIG_TEXT_BASE=0x4000000
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_SECT_SIZE=0x2000
+CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="mcr3000"
CONFIG_SYS_MONITOR_LEN=327680
CONFIG_SYS_CLK_FREQ=132000000
@@ -91,6 +92,7 @@ CONFIG_SYS_OR6_PRELIM=0xFFFF0908
CONFIG_SYS_BR7_PRELIM_BOOL=y
CONFIG_SYS_BR7_PRELIM=0x1C000001
CONFIG_SYS_OR7_PRELIM=0xFFFF810A
+CONFIG_MPC8XX_GPIO=y
# CONFIG_MMC is not set
CONFIG_MTD=y
CONFIG_DM_MTD=y
@@ -102,6 +104,9 @@ CONFIG_SYS_MAX_FLASH_SECT=35
CONFIG_MTD_RAW_NAND=y
CONFIG_MPC8XX_FEC=y
CONFIG_DM_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MPC8XX_SPI=y
CONFIG_WDT=y
CONFIG_WDT_MPC8xxx_BME=y
CONFIG_LZMA=y