diff options
| author | Tom Rini <[email protected]> | 2024-04-18 10:08:57 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2024-04-18 10:08:57 -0600 |
| commit | cdf0195e90b66f25ed44fa5ed5634ec064e8dcb9 (patch) | |
| tree | 0754178ede128c2313a22d5012841e091becdbef /drivers | |
| parent | cdd20e3f66fe910da0545d3615decf511519b4a6 (diff) | |
| parent | 741e30e8c2b837dc92ee2eedec5478afdd83a316 (diff) | |
Merge branch 'for-2024.07' of https://source.denx.de/u-boot/custodians/u-boot-mpc8xx
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
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/spi/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/spi/mpc8xx_spi.c | 113 | ||||
| -rw-r--r-- | drivers/thermal/Kconfig | 6 | ||||
| -rw-r--r-- | drivers/thermal/Makefile | 1 | ||||
| -rw-r--r-- | drivers/thermal/ti-lm74.c | 52 |
5 files changed, 153 insertions, 21 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 69b184b0d9e..612434633b3 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -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 diff --git a/drivers/spi/mpc8xx_spi.c b/drivers/spi/mpc8xx_spi.c index 5c8d7609351..e1448cc6196 100644 --- a/drivers/spi/mpc8xx_spi.c +++ b/drivers/spi/mpc8xx_spi.c @@ -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) diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 681b621760d..440eb64a566 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -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 diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 8acc7d20cb9..b5ab0fc221f 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -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 diff --git a/drivers/thermal/ti-lm74.c b/drivers/thermal/ti-lm74.c new file mode 100644 index 00000000000..7d56f75df06 --- /dev/null +++ b/drivers/thermal/ti-lm74.c @@ -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, +}; |
