
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 --- arch/powerpc/dts/mcr3000.dts | 31 +++++++++ board/cssi/mcr3000/Makefile | 1 + board/cssi/mcr3000/mcr3000.c | 5 ++ board/cssi/mcr3000/mcr3000_gpio.c | 109 ++++++++++++++++++++++++++++++ configs/MCR3000_defconfig | 5 ++ 5 files changed, 151 insertions(+) create mode 100644 board/cssi/mcr3000/mcr3000_gpio.c
diff --git a/arch/powerpc/dts/mcr3000.dts b/arch/powerpc/dts/mcr3000.dts index c4d7737bc6..edcd8358d0 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 7803016af3..846fd680e9 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 8857c9e42c..537d7fa124 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 0000000000..2bba14e6e5 --- /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 8a88fb445c..ce34c2aa88 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