This pull request adds support for temperature sensors et FPGA loading
on boards from CS GROUP France.

CI: https://source.denx.de/u-boot/custodians/u-boot-mpc8xx/-/pipelines/20416
This commit is contained in:
Tom Rini 2024-04-18 10:08:57 -06:00
commit cdf0195e90
24 changed files with 10244 additions and 39 deletions

View File

@ -92,6 +92,12 @@ void cpu_init_f(immap_t __iomem *immr)
CONFIG_SYS_PLPRCR);
#endif
/* Set SDMA configuration register */
if (IS_ENABLED(CONFIG_MPC885))
out_be32(&immr->im_siu_conf.sc_sdcr, 0x0040);
else
out_be32(&immr->im_siu_conf.sc_sdcr, 0x0001);
/*
* Memory Controller:
*/

View File

@ -83,13 +83,23 @@
spi: spi@aa0 {
status = "okay";
#address-cells = <1>;
#size-cells = <1>;
cell-index = <0>;
#size-cells = <0>;
compatible = "fsl,mpc8xx-spi";
gpios = <&CPM1_PIO_B 21 1>; /* /EEPROM_CS ACTIVE_LOW */
gpios = <&CPM1_PIO_B 21 1 /* /EEPROM_CS ACTIVE_LOW */
&CPM1_PIO_B 23 1 /* Temperature mother board */
&CPM1_PIO_B 14 1>; /* Temperature CPU board */
eeprom@0 {
cell-index = <1>;
reg = <0>;
compatible = "atmel,at25", "cs,eeprom";
};
temp@1 {
reg = <1>;
compatible = "ti,lm74";
};
temp@2 {
reg = <2>;
compatible = "ti,lm74";
};
};
};

View File

@ -140,11 +140,21 @@
compatible = "fsl,mpc832x-spi";
reg = <0x4c0 0x40>;
mode = "cpu";
gpios = <&qe_pio_d 3 1>;
gpios = <&qe_pio_d 3 1
&qe_pio_c 5 1 /* TEMP mother board */
&qe_pio_c 3 1>; /* TEMP CPU board */
clock-frequency = <0>;
eeprom@3 {
eeprom@0 {
reg = <0>;
compatible = "atmel,at25", "cs,eeprom";
cell-index = <1>;
};
temp@1 {
reg = <1>;
compatible = "ti,lm74";
};
temp@2 {
reg = <2>;
compatible = "ti,lm74";
};
};
eth0: ucc@3000 {

View File

@ -26,6 +26,47 @@
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";
gpios = <&csspi 2 0
&csspi 0 0>;
temp@0 {
reg = <0>;
compatible = "ti,lm74";
};
fpga@1 {
reg = <1>;
};
};
};
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

@ -5,6 +5,6 @@
# Christophe Leroy <christophe.leroy@c-s.fr>
#
obj-y += cmpc885.o ../common/common.o
obj-y += cmpc885.o
obj-y += sdram.o
obj-$(CONFIG_CMD_NAND) += nand.o

View File

@ -114,8 +114,10 @@ static int setup_mac(void)
if (memcmp(din + EE_OFF_MAC1, &ident, sizeof(ident)) == 0)
eth_env_set_enetaddr("ethaddr", din + EE_OFF_MAC1);
if (memcmp(din + EE_OFF_MAC2, &ident, sizeof(ident)) == 0)
if (memcmp(din + EE_OFF_MAC2, &ident, sizeof(ident)) == 0) {
eth_env_set_enetaddr("eth1addr", din + EE_OFF_MAC2);
eth_env_set_enetaddr("eth2addr", din + EE_OFF_MAC2);
}
return 0;
}

View File

@ -2,6 +2,6 @@ loadaddr=0x1a00000
filename=cmpc885.itb
console_args=console=ttyCPM0,115200N8
loadkernel=ubi part nand0;ubifsmount ubi0;ubifsload ${loadaddr} /boot/${filename};ubifsumount; ubi detach
flashboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; run loadkernel; bootm $loadaddr#$config
tftpboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; tftp ${loadaddr} ${filename};bootm $loadaddr#$config
flashboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; run loadkernel; bootm ${loadaddr}#${config}
tftpboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; tftp ${loadaddr} ${filename};bootm ${loadaddr}#${config}
update=echo 'Updating ubi image'; if tftp $loadaddr $ubifile; then nand erase.chip; nand write $loadaddr 0x00 $filesize; fi;

View File

@ -5,4 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += cmpcpro.o nand.o ../common/common.o
obj-y += cmpcpro.o nand.o

View File

@ -3,6 +3,6 @@ filename=cmpcpro.itb
netdev=eth0
console_args=console=ttyS0,115200N8
loadkernel=ubi part nand0;ubifsmount ubi0; ubifsload ${loadaddr} /boot/${filename}; ubifsumount; ubi detach
flashboot=mw.w 90000040 0x000E 1; setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; run loadkernel; bootm $loadaddr#$config
tftpboot=mw.w 90000040 0x000E 1; setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; tftp ${loadaddr} ${filename}; bootm $loadaddr#$config
flashboot=mw.w 90000040 0x000E 1; setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; run loadkernel; bootm ${loadaddr}#${config}
tftpboot=mw.w 90000040 0x000E 1; setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ${ofl_args}; tftp ${loadaddr} ${filename}; bootm ${loadaddr}#${config}
update=echo 'Updating ubi image'; mw.w 90000040 0x000E 1; if tftp $loadaddr $ubifile; then nand erase.chip; nand write $loadaddr 0x00 $filesize; fi;

View File

@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2024 CS GROUP France
# Christophe Leroy <christophe.leroy@csgroup.eu>
#
obj-$(CONFIG_TARGET_CMPC885) += common.o
obj-$(CONFIG_TARGET_CMPCPRO) += common.o

View File

@ -164,7 +164,7 @@ int checkboard_common(void)
void misc_init_r_common(void)
{
u8 tmp, far_id;
u8 tmp, far_id, addr;
int count = 3;
switch (in_8(ADDR_FPGA_R_BASE)) {
@ -173,6 +173,10 @@ void misc_init_r_common(void)
if ((in_8(ADDR_FPGA_R_BASE + 0x31) & FPGA_R_ACQ_AL_FAV) == 0)
env_set("bootdelay", "60");
addr = in_8(ADDR_FPGA_R_BASE + 0x43);
printf("Board address: 0x%2.2x (System %d Rack %d Slot %d)\n",
addr, addr >> 7, (addr >> 4) & 7, addr & 15);
env_set("config", CFG_BOARD_MCR3000_2G);
env_set("hostname", CFG_BOARD_MCR3000_2G);
break;
@ -208,12 +212,44 @@ void misc_init_r_common(void)
}
}
static void iop_setup_fpgam_common(void)
{
u8 far_id = in_8(ADDR_FPGA_R_BASE + 0x43) >> 5;
if (far_id == FAR_CASRSA) {
/*
* PFDIR[15] = 0 [0x01]
* PFDIR[14] = 1 [0x02]
* PFDIR[13] = 1 [0x04]
*/
clrsetbits_8(ADDR_FPGA_R_BASE + 0x37, 0x01, 0x06);
/*
* PFODR[15] = 1 [0x01]
* PFODR[14] = 0 [0x02]
* PFODR[13] = 0 [0x04]
*/
clrsetbits_8(ADDR_FPGA_R_BASE + 0x39, 0x06, 0x01);
/*
* PFDAT[15] = 0 [0x01]
* PFDAT[14] = 1 [0x02]
* PFDAT[13] = 1 [0x04]
* PFDAT[12] = 1 [0x08]
*/
clrsetbits_8(ADDR_FPGA_R_BASE + 0x3B, 0x01, 0x0E);
/* Setup TOR_OUT */
out_8(ADDR_FPGA_R_BASE + 0x32, 0x2A);
}
}
void iop_setup_common(void)
{
u8 type = in_8(ADDR_FPGA_R_BASE);
if (type == TYPE_MCR)
if (type == TYPE_MCR) {
iop_setup_mcr();
else if (type == TYPE_MIAE)
} else if (type == TYPE_MIAE) {
iop_setup_miae();
iop_setup_fpgam_common();
}
}

View File

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

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;
@ -116,6 +162,18 @@ 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 (!load_fpga()) {
u8 addr = in_be16((void *)0x1400009c);
printf("Board address: 0x%2.2x (System %d Rack %d Slot %d)\n",
addr, addr >> 7, (addr >> 4) & 7, addr & 15);
}
/* 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

@ -8,7 +8,7 @@ dhcp_ip=ip=:::::eth0:dhcp
console_args=console=ttyCPM0,115200N8
loadkernel=ubi part nand0;ubifsmount ubi0;ubifsload ${loadaddr} /boot/${filename};ubifsumount; ubi detach
bootcmd=run flashboot
flashboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off;${ofl_args}; run loadkernel; bootm ${loadaddr}
flashboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off ${ofl_args}; run loadkernel; bootm ${loadaddr}
tftpboot=setenv bootargs ${console_args} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:mcr3k:eth0:off ${ofl_args}; tftp ${loadaddr} ${filename}; bootm ${loadaddr}
dhcpboot=dhcp ${loadaddr} ${filename};setenv bootargs ${console_args} ${dhcp_ip} ${ofl_args}; bootm ${loadaddr}
update=echo 'Updating ubi image'; if tftp 0x2000 $ubifile; then nand erase.chip; nand write 0x2000 0x00 $filesize; fi

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

@ -50,6 +50,7 @@ CONFIG_CMD_ASKENV=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_MTD=y
CONFIG_CMD_NAND=y
CONFIG_CMD_TEMPERATURE=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_MII_INIT=y
@ -107,6 +108,8 @@ CONFIG_DM_SERIAL=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_MPC8XX_SPI=y
CONFIG_DM_THERMAL=y
CONFIG_TI_LM74_THERMAL=y
CONFIG_WDT=y
CONFIG_WDT_MPC8xxx_BME=y
# CONFIG_REGEX is not set

View File

@ -134,6 +134,7 @@ CONFIG_CMD_ASKENV=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_MTD=y
CONFIG_CMD_NAND=y
CONFIG_CMD_TEMPERATURE=y
CONFIG_CMD_DHCP=y
CONFIG_BOOTP_BOOTFILESIZE=y
CONFIG_CMD_MII=y
@ -197,6 +198,8 @@ CONFIG_DM_SPI=y
CONFIG_MPC8XXX_SPI=y
CONFIG_SYSRESET=y
CONFIG_SYSRESET_MPC83XX=y
CONFIG_DM_THERMAL=y
CONFIG_TI_LM74_THERMAL=y
CONFIG_WDT=y
CONFIG_WDT_MPC8xxx=y
# CONFIG_REGEX is not set

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
@ -46,6 +47,7 @@ CONFIG_CMD_ASKENV=y
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_MTD=y
CONFIG_CMD_NAND=y
CONFIG_CMD_TEMPERATURE=y
# CONFIG_CMD_ECHO is not set
# CONFIG_CMD_ITEST is not set
# CONFIG_CMD_SOURCE is not set
@ -91,6 +93,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 +105,11 @@ 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_DM_THERMAL=y
CONFIG_TI_LM74_THERMAL=y
CONFIG_WDT=y
CONFIG_WDT_MPC8xxx_BME=y
CONFIG_LZMA=y

View File

@ -262,7 +262,7 @@ config MESON_SPIFC_A1
config MPC8XX_SPI
bool "MPC8XX SPI Driver"
depends on MPC8xx
depends on MPC8xx && DM_GPIO
help
Enable support for SPI on MPC8XX

View File

@ -18,6 +18,7 @@
#include <common.h>
#include <dm.h>
#include <malloc.h>
#include <mpc8xx.h>
#include <spi.h>
#include <linux/delay.h>
@ -29,7 +30,8 @@
#define CPM_SPI_BASE_RX CPM_SPI_BASE
#define CPM_SPI_BASE_TX (CPM_SPI_BASE + sizeof(cbd_t))
#define MAX_BUFFER 0x104
#define MAX_BUFFER 0x8000 /* Max possible is 0xffff. We want power of 2 */
#define MIN_HWORD_XFER 64 /* Minimum size for 16 bits transfer */
struct mpc8xx_priv {
spi_t __iomem *spi;
@ -37,6 +39,8 @@ struct mpc8xx_priv {
int max_cs;
};
static char dummy_buffer[MAX_BUFFER];
static int mpc8xx_spi_set_mode(struct udevice *dev, uint mod)
{
return 0;
@ -44,6 +48,21 @@ static int mpc8xx_spi_set_mode(struct udevice *dev, uint mod)
static int mpc8xx_spi_set_speed(struct udevice *dev, uint speed)
{
immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
cpm8xx_t __iomem *cp = &immr->im_cpm;
u8 pm = (gd->arch.brg_clk - 1) / (speed * 16);
if (pm > 16) {
setbits_be16(&cp->cp_spmode, SPMODE_DIV16);
pm /= 16;
if (pm > 16)
pm = 16;
} else {
clrbits_be16(&cp->cp_spmode, SPMODE_DIV16);
}
clrsetbits_be16(&cp->cp_spmode, SPMODE_PM(0xf), SPMODE_PM(pm));
return 0;
}
@ -101,10 +120,6 @@ static int mpc8xx_spi_probe(struct udevice *dev)
while (in_be16(&cp->cp_cpcr) & CPM_CR_FLG)
;
/* 5 */
/* Set SDMA configuration register */
out_be32(&immr->im_siu_conf.sc_sdcr, 0x0001);
/* 6 */
/* Set to big endian. */
out_8(&spi->spi_tfcr, SMC_EB);
@ -145,37 +160,52 @@ static void mpc8xx_spi_cs_deactivate(struct udevice *dev)
dm_gpio_set_value(&priv->gpios[platdata->cs], 0);
}
static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
static int mpc8xx_spi_xfer_one(struct udevice *dev, size_t count,
const void *dout, void *din)
{
immap_t __iomem *immr = (immap_t __iomem *)CONFIG_SYS_IMMR;
cpm8xx_t __iomem *cp = &immr->im_cpm;
cbd_t __iomem *tbdf, *rbdf;
void *bufout, *bufin;
u16 spmode_len;
int tm;
size_t count = (bitlen + 7) / 8;
if (count > MAX_BUFFER)
return -EINVAL;
tbdf = (cbd_t __iomem *)&cp->cp_dpmem[CPM_SPI_BASE_TX];
rbdf = (cbd_t __iomem *)&cp->cp_dpmem[CPM_SPI_BASE_RX];
/* Set CS for device */
if (flags & SPI_XFER_BEGIN)
mpc8xx_spi_cs_activate(dev);
if (!(count & 1) && count >= MIN_HWORD_XFER) {
spmode_len = SPMODE_LEN(16);
if (dout) {
int i;
bufout = malloc(count);
for (i = 0; i < count; i += 2)
*(u16 *)(bufout + i) = swab16(*(u16 *)(dout + i));
} else {
bufout = NULL;
}
if (din)
bufin = malloc(count);
else
bufin = NULL;
} else {
spmode_len = SPMODE_LEN(8);
bufout = (void *)dout;
bufin = din;
}
/* Setting tx bd status and data length */
out_be32(&tbdf->cbd_bufaddr, (ulong)dout);
out_be32(&tbdf->cbd_bufaddr, bufout ? (ulong)bufout : (ulong)dummy_buffer);
out_be16(&tbdf->cbd_sc, BD_SC_READY | BD_SC_LAST | BD_SC_WRAP);
out_be16(&tbdf->cbd_datlen, count);
/* Setting rx bd status and data length */
out_be32(&rbdf->cbd_bufaddr, (ulong)din);
out_be32(&rbdf->cbd_bufaddr, bufin ? (ulong)bufin : (ulong)dummy_buffer);
out_be16(&rbdf->cbd_sc, BD_SC_EMPTY | BD_SC_WRAP);
out_be16(&rbdf->cbd_datlen, 0); /* rx length has no significance */
clrsetbits_be16(&cp->cp_spmode, ~SPMODE_LOOP, SPMODE_REV | SPMODE_MSTR |
SPMODE_EN | SPMODE_LEN(8) | SPMODE_PM(0x8));
clrsetbits_be16(&cp->cp_spmode, ~(SPMODE_LOOP | SPMODE_PM(0xf) | SPMODE_DIV16),
SPMODE_REV | SPMODE_MSTR | SPMODE_EN | spmode_len);
out_8(&cp->cp_spim, 0); /* Mask all SPI events */
out_8(&cp->cp_spie, SPI_EMASK); /* Clear all SPI events */
@ -196,13 +226,56 @@ static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
}
if (tm >= 1000)
printf("*** spi_xfer: Time out while xferring to/from SPI!\n");
return -ETIMEDOUT;
if (!(count & 1) && count > MIN_HWORD_XFER) {
if (dout)
free(bufout);
if (din) {
int i;
bufout = malloc(count);
for (i = 0; i < count; i += 2)
*(u16 *)(din + i) = swab16(*(u16 *)(bufin + i));
free(bufin);
}
}
return 0;
}
static int mpc8xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
size_t count = (bitlen + 7) / 8;
size_t offset = 0;
int ret = 0;
if (!din && !dout)
return -EINVAL;
/* Set CS for device */
if (flags & SPI_XFER_BEGIN)
mpc8xx_spi_cs_activate(dev);
while (count > 0 && !ret) {
size_t chunk = min(count, (size_t)MAX_BUFFER);
const void *out = dout ? dout + offset : NULL;
void *in = din ? din + offset : NULL;
ret = mpc8xx_spi_xfer_one(dev, chunk, out, in);
offset += chunk;
count -= chunk;
}
/* Clear CS for device */
if (flags & SPI_XFER_END)
mpc8xx_spi_cs_deactivate(dev);
return 0;
if (ret)
printf("*** spi_xfer: Time out while xferring to/from SPI!\n");
return ret;
}
static int mpc8xx_spi_ofdata_to_platdata(struct udevice *dev)

View File

@ -41,4 +41,10 @@ config TI_DRA7_THERMAL
Enable thermal support for for the Texas Instruments DRA752 SoC family.
The driver supports reading CPU temperature.
config TI_LM74_THERMAL
bool "Temperature sensor driver for TI LM74 chip"
help
Enable thermal support for the Texas Instruments LM74 chip.
The driver supports reading CPU temperature.
endif # if DM_THERMAL

View File

@ -9,3 +9,4 @@ obj-$(CONFIG_IMX_THERMAL) += imx_thermal.o
obj-$(CONFIG_IMX_SCU_THERMAL) += imx_scu_thermal.o
obj-$(CONFIG_TI_DRA7_THERMAL) += ti-bandgap.o
obj-$(CONFIG_IMX_TMU) += imx_tmu.o
obj-$(CONFIG_TI_LM74_THERMAL) += ti-lm74.o

52
drivers/thermal/ti-lm74.c Normal file
View File

@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* TI LM74 temperature sensor driver
*
* Copyright (C) 2024 CS GROUP France
*
*/
#include <dm.h>
#include <thermal.h>
#include <spi.h>
static int ti_lm74_get_temp(struct udevice *dev, int *temp)
{
char buf[2];
s16 raw;
int ret;
ret = dm_spi_claim_bus(dev);
if (ret)
return ret;
ret = dm_spi_xfer(dev, 16, NULL, buf, SPI_XFER_BEGIN | SPI_XFER_END);
dm_spi_release_bus(dev);
if (ret)
return ret;
raw = ((buf[0] << 8) + buf[1]) >> 3;
*temp = (((int)raw * 125) + 1000) / 2000;
return 0;
}
static struct dm_thermal_ops ti_lm74_ops = {
.get_temp = ti_lm74_get_temp,
};
static const struct udevice_id of_ti_lm74_match[] = {
{
.compatible = "ti,lm74",
},
{},
};
U_BOOT_DRIVER(ti_bandgap_thermal) = {
.name = "ti_lm74_thermal",
.id = UCLASS_THERMAL,
.ops = &ti_lm74_ops,
.of_match = of_ti_lm74_match,
};