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>
This commit is contained in:
Christophe Leroy 2024-04-12 12:01:25 +02:00
parent c578728d2e
commit c58074af2e
5 changed files with 151 additions and 0 deletions

View File

@ -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 {

View File

@ -6,3 +6,4 @@
obj-y += mcr3000.o
obj-$(CONFIG_CMD_NAND) += nand.o
obj-$(CONFIG_MPC8XX_SPI) += mcr3000_gpio.o

View File

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

View File

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

View File

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