Compare commits

...

2 Commits

Author SHA1 Message Date
Robert Nelson 0fefceeb31 Merge branch 'devel' into 'main'
Move to linux4microchip+fpga-2024.09

See merge request beaglev-fire/BeagleV-Fire-ubuntu!6
2 weeks ago
Lars Randers 08498304e3 linux: move to linux4microchip+fpga-2024.09
- Tweaked the pull urls
- Removed redundant patches
- Added required switches

Signed-off-by: Lars Randers <lranders@mail.dk>
3 weeks ago

@ -13,11 +13,11 @@ UBOOT_BRANCH="v2023.02-BeagleV-Fire"
UBOOT_REPO="https://openbeagle.org/beaglev-fire/beaglev-fire-u-boot.git"
#UBOOT_REPO="git@openbeagle.org:beaglev-fire/beaglev-fire-u-boot.git"
DT_BRANCH="v6.1.x-Beagle"
DT_BRANCH="v6.6.x-Beagle"
DT_REPO="https://openbeagle.org/beagleboard/BeagleBoard-DeviceTrees.git"
#DT_REPO="git@openbeagle.org:beagleboard/BeagleBoard-DeviceTrees.git"
LINUX_BRANCH="linux4microchip+fpga-2023.06"
LINUX_BRANCH="linux4microchip+fpga-2024.09"
LINUX_REPO="https://github.com/linux4microchip/linux.git"
#LINUX_REPO="https://openbeagle.org/beaglev-fire/beaglev-fire-linux.git"
#LINUX_REPO="git@openbeagle.org:beaglev-fire/beaglev-fire-linux.git"

@ -8,23 +8,19 @@ cd ./linux/
if [ ! -f ./.patched ] ; then
if [ -f arch/riscv/configs/mpfs_defconfig ] ; then
git am ../patches/linux/0002-PCIe-Change-controller-and-bridge-base-address.patch
git am ../patches/linux/0003-GPIO-Add-Microchip-CoreGPIO-driver.patch
git am ../patches/linux/0004-ADC-Add-Microchip-MCP356X-driver.patch
git am ../patches/linux/0005-Microchip-QSPI-Add-regular-transfers.patch
git am ../patches/linux/0006-BeagleV-Fire-Add-printk-to-IM219-driver-for-board-te.patch
git am ../patches/linux/0007-MMC-SPI-Hack-to-support-non-DMA-capable-SPI-ctrl.patch
git am ../patches/linux/linux-6.6.y/0002-PCIe-Change-controller-and-bridge-base-address.patch
git am ../patches/linux/0008-Add-wireless-regdb-regulatory-database-file.patch
git am ../patches/linux/0009-Makefile-build-mpfs-beaglev-fire.dtb.patch
git am ../patches/linux/0010-BeagleV-Fire-Add-MPFS-TVS-auxiliary-driver.patch
git am ../patches/linux/linux-6.6.y/0011-can-mpfs_can-add-registration-string.patch
git am ../patches/linux/linux-6.6.y/0012-gpio-gpio-mpfs-add-registration-string.patch
fi
touch .patched
fi
if [ -f arch/riscv/configs/mpfs_defconfig ] ; then
# cp -v ../patches/linux/Makefile arch/riscv/boot/dts/microchip/Makefile
cp -v ../device-tree/src/microchip/mpfs-beaglev-fire.dts arch/riscv/boot/dts/microchip/
cp -v ../device-tree/src/microchip/mpfs-beaglev-fire-fabric.dtsi arch/riscv/boot/dts/microchip/
cp -v ../device-tree/src/riscv/microchip/mpfs-beaglev-fire.dts arch/riscv/boot/dts/microchip/
cp -v ../device-tree/src/riscv/microchip/mpfs-beaglev-fire-fabric.dtsi arch/riscv/boot/dts/microchip/
cp -v ../device-tree/src/riscv/microchip/mpfs-beaglev-fire-pinmux.dtsi arch/riscv/boot/dts/microchip/
#echo "************************************"
#git diff arch/riscv/boot/dts/microchip/ > log.txt ; cat log.txt ; rm log.txt
#echo "************************************"
@ -47,6 +43,17 @@ if [ -f arch/riscv/configs/mpfs_defconfig ] ; then
./scripts/config --set-str CONFIG_LOCALVERSION "-$(date +%Y%m%d)"
#6.1 to 6.6 switches
./scripts/config --disable CONFIG_FW_LOADER_DEBUG
./scripts/config --disable CONFIG_FW_CACHE
./scripts/config --enable CONFIG_MFD_SYSCON
./scripts/config --enable CONFIG_POLARFIRE_SOC_SYS_CTRL
./scripts/config --enable CONFIG_POLARFIRE_SOC_GENERIC_SERVICE
./scripts/config --enable CONFIG_POLARFIRE_SOC_MAILBOX
./scripts/config --enable CONFIG_POLARFIRE_SOC_AUTO_UPDATE
./scripts/config --enable CONFIG_HW_RANDOM_POLARFIRE_SOC
./scripts/config --enable CONFIG_OF_OVERLAY
./scripts/config --disable CONFIG_MODULE_DECOMPRESS
@ -73,7 +80,12 @@ if [ -f arch/riscv/configs/mpfs_defconfig ] ; then
./scripts/config --enable CONFIG_CRYPTO_SHA512
./scripts/config --enable CONFIG_CRYPTO_SHA1
./scripts/config --enable CONFIG_SENSORS_TVS_MPFS
./scripts/config --enable CONFIG_SENSORS_POLARFIRE_SOC_TVS
./scripts/config --module CONFIG_CAN
./scripts/config --module CONFIG_CAN_POLARFIRE_SOC
#non-workable on RevA
./scripts/config --disable CONFIG_VIDEO_IMX219
echo "make -j${CORES} ARCH=riscv CROSS_COMPILE=${CC} olddefconfig"
make -j${CORES} ARCH=riscv CROSS_COMPILE=${CC} olddefconfig
@ -160,8 +172,8 @@ else
make -j${CORES} ARCH=riscv CROSS_COMPILE=${CC} olddefconfig
fi
echo "make -j${CORES} ARCH=riscv CROSS_COMPILE=${CC} Image modules dtbs"
make -j${CORES} ARCH=riscv CROSS_COMPILE="ccache ${CC}" Image modules dtbs
echo "make -j${CORES} ARCH=riscv CROSS_COMPILE=${CC} DTC_FLAGS=\"-@\" Image modules dtbs"
make -j${CORES} ARCH=riscv CROSS_COMPILE="ccache ${CC}" DTC_FLAGS="-@" Image modules dtbs
if [ ! -f ./arch/riscv/boot/Image ] ; then
echo "Build Failed"

@ -1,371 +0,0 @@
From 37ff4eff8ff033c48aa73526fec7291127326dcb Mon Sep 17 00:00:00 2001
From: vauban353 <vauban353@gmail.com>
Date: Fri, 21 Jul 2023 19:33:28 +0100
Subject: [PATCH 3/8] GPIO: Add Microchip CoreGPIO driver.
---
drivers/gpio/Kconfig | 8 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-microchip-core.c | 319 +++++++++++++++++++++++++++++
3 files changed, 328 insertions(+)
create mode 100644 drivers/gpio/gpio-microchip-core.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d71f5bd6f..8e3858e34 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -501,6 +501,14 @@ config GPIO_POLARFIRE_SOC
help
Say yes here to support the GPIO device on Microchip FPGAs.
+config GPIO_MICROCHIP_CORE
+ bool "Microchip FPGA soft-IP GPIO support"
+ depends on OF_GPIO
+ select GPIOLIB_IRQCHIP
+ help
+ Say yes here to support the soft-IP GPIO device on Microchip FPGAs
+
+
config GPIO_PXA
bool "PXA GPIO support"
depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9be0691d9..05a65ff04 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -121,6 +121,7 @@ obj-$(CONFIG_GPIO_PISOSR) += gpio-pisosr.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_PMIC_EIC_SPRD) += gpio-pmic-eic-sprd.o
obj-$(CONFIG_GPIO_POLARFIRE_SOC) += gpio-mpfs.o
+obj-$(CONFIG_GPIO_MICROCHIP_CORE) += gpio-microchip-core.o
obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
obj-$(CONFIG_GPIO_RASPBERRYPI_EXP) += gpio-raspberrypi-exp.o
obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
diff --git a/drivers/gpio/gpio-microchip-core.c b/drivers/gpio/gpio-microchip-core.c
new file mode 100644
index 000000000..fd630cac4
--- /dev/null
+++ b/drivers/gpio/gpio-microchip-core.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: (GPL-2.0)
+/*
+ * Microchip CoreGPIO FPGA soft-IP GPIO controller driver
+ *
+ * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Lewis Hanly <lewis.hanly@microchip.com>
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/gpio/driver.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#define MPFS_GPIO_CTRL(i) (0x4 * (i))
+#define MAX_NUM_GPIO 32
+#define MPFS_GPIO_EN_INT 3
+#define MPFS_GPIO_EN_OUT_BUF BIT(2)
+#define MPFS_GPIO_EN_IN BIT(1)
+#define MPFS_GPIO_EN_OUT BIT(0)
+
+#define MPFS_GPIO_TYPE_INT_EDGE_BOTH 0x80
+#define MPFS_GPIO_TYPE_INT_EDGE_NEG 0x60
+#define MPFS_GPIO_TYPE_INT_EDGE_POS 0x40
+#define MPFS_GPIO_TYPE_INT_LEVEL_LOW 0x20
+#define MPFS_GPIO_TYPE_INT_LEVEL_HIGH 0x00
+#define MPFS_GPIO_TYPE_INT_MASK GENMASK(7, 5)
+#define MPFS_IRQ_REG 0x80
+#define MPFS_INP_REG 0x90
+#define MPFS_OUTP_REG 0xA0
+
+struct mpfs_gpio_chip {
+ void __iomem *base;
+ struct clk *clk;
+ raw_spinlock_t lock;
+ struct gpio_chip gc;
+};
+
+static void mpfs_gpio_assign_bit(void __iomem *addr, unsigned int bit_offset, bool value)
+{
+ unsigned long reg = readl(addr);
+
+ __assign_bit(bit_offset, &reg, value);
+ writel(reg, addr);
+}
+
+static int mpfs_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio_index)
+{
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ u32 gpio_cfg;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&mpfs_gpio->lock, flags);
+
+ gpio_cfg = readl(mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index));
+ gpio_cfg |= MPFS_GPIO_EN_IN;
+ gpio_cfg &= ~(MPFS_GPIO_EN_OUT | MPFS_GPIO_EN_OUT_BUF);
+ writel(gpio_cfg, mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index));
+
+ raw_spin_unlock_irqrestore(&mpfs_gpio->lock, flags);
+
+ return 0;
+}
+
+static int mpfs_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio_index, int value)
+{
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ u32 gpio_cfg;
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&mpfs_gpio->lock, flags);
+
+ gpio_cfg = readl(mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index));
+ gpio_cfg |= MPFS_GPIO_EN_OUT | MPFS_GPIO_EN_OUT_BUF;
+ gpio_cfg &= ~MPFS_GPIO_EN_IN;
+ writel(gpio_cfg, mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index));
+
+ mpfs_gpio_assign_bit(mpfs_gpio->base + MPFS_OUTP_REG, gpio_index, value);
+
+ raw_spin_unlock_irqrestore(&mpfs_gpio->lock, flags);
+
+ return 0;
+}
+
+static int mpfs_gpio_get_direction(struct gpio_chip *gc,
+ unsigned int gpio_index)
+{
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ u32 gpio_cfg;
+
+ gpio_cfg = readl(mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index));
+ if (gpio_cfg & MPFS_GPIO_EN_IN)
+ return GPIO_LINE_DIRECTION_IN;
+
+ return GPIO_LINE_DIRECTION_OUT;
+}
+
+static int mpfs_gpio_get(struct gpio_chip *gc,
+ unsigned int gpio_index)
+{
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+
+ return !!(readl(mpfs_gpio->base + MPFS_INP_REG) & BIT(gpio_index));
+}
+
+static void mpfs_gpio_set(struct gpio_chip *gc, unsigned int gpio_index, int value)
+{
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&mpfs_gpio->lock, flags);
+
+ mpfs_gpio_assign_bit(mpfs_gpio->base + MPFS_OUTP_REG,
+ gpio_index, value);
+
+ raw_spin_unlock_irqrestore(&mpfs_gpio->lock, flags);
+}
+
+static int mpfs_gpio_irq_set_type(struct irq_data *data, unsigned int type)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ int gpio_index = irqd_to_hwirq(data);
+ u32 interrupt_type;
+ u32 gpio_cfg;
+ unsigned long flags;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_BOTH;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_NEG;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_POS;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_HIGH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_LOW;
+ break;
+ }
+
+ raw_spin_lock_irqsave(&mpfs_gpio->lock, flags);
+
+ gpio_cfg = readl(mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index));
+ gpio_cfg &= ~MPFS_GPIO_TYPE_INT_MASK;
+ gpio_cfg |= interrupt_type;
+ writel(gpio_cfg, mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index));
+
+ raw_spin_unlock_irqrestore(&mpfs_gpio->lock, flags);
+
+ return 0;
+}
+
+static void mpfs_gpio_irq_unmask(struct irq_data *data)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ int gpio_index = irqd_to_hwirq(data) % MAX_NUM_GPIO;
+
+ mpfs_gpio_direction_input(gc, gpio_index);
+ mpfs_gpio_assign_bit(mpfs_gpio->base + MPFS_IRQ_REG, gpio_index, 1);
+ mpfs_gpio_assign_bit(mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index),
+ MPFS_GPIO_EN_INT, 1);
+}
+
+static void mpfs_gpio_irq_mask(struct irq_data *data)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
+ struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
+ int gpio_index = irqd_to_hwirq(data) % MAX_NUM_GPIO;
+
+ mpfs_gpio_assign_bit(mpfs_gpio->base + MPFS_IRQ_REG, gpio_index, 1);
+ mpfs_gpio_assign_bit(mpfs_gpio->base + MPFS_GPIO_CTRL(gpio_index),
+ MPFS_GPIO_EN_INT, 0);
+}
+
+static struct irq_chip mpfs_gpio_irqchip = {
+ .name = "mpfs",
+ .irq_set_type = mpfs_gpio_irq_set_type,
+ .irq_mask = mpfs_gpio_irq_mask,
+ .irq_unmask = mpfs_gpio_irq_unmask,
+ .flags = IRQCHIP_MASK_ON_SUSPEND,
+};
+
+static void mpfs_gpio_irq_handler(struct irq_desc *desc)
+{
+ struct irq_chip *irqchip = irq_desc_get_chip(desc);
+ struct mpfs_gpio_chip *mpfs_gpio =
+ gpiochip_get_data(irq_desc_get_handler_data(desc));
+ unsigned long status;
+ int offset;
+
+ chained_irq_enter(irqchip, desc);
+
+ status = readl(mpfs_gpio->base + MPFS_IRQ_REG);
+ for_each_set_bit(offset, &status, mpfs_gpio->gc.ngpio) {
+ mpfs_gpio_assign_bit(mpfs_gpio->base + MPFS_IRQ_REG, offset, 1);
+ generic_handle_irq(irq_find_mapping(mpfs_gpio->gc.irq.domain, offset));
+ }
+
+ chained_irq_exit(irqchip, desc);
+}
+
+static int mpfs_gpio_probe(struct platform_device *pdev)
+{
+ struct clk *clk;
+ struct device *dev = &pdev->dev;
+ struct device_node *node = pdev->dev.of_node;
+ struct mpfs_gpio_chip *mpfs_gpio;
+ struct gpio_irq_chip *girq;
+ int i, ret, ngpios, nirqs;
+
+ mpfs_gpio = devm_kzalloc(dev, sizeof(*mpfs_gpio), GFP_KERNEL);
+ if (!mpfs_gpio)
+ return -ENOMEM;
+
+ mpfs_gpio->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(mpfs_gpio->base))
+ return dev_err_probe(dev, PTR_ERR(mpfs_gpio->base), "memory allocation failure\n");
+
+ clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(clk))
+ return dev_err_probe(dev, PTR_ERR(clk), "devm_clk_get failed\n");
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to enable clock\n");
+
+ mpfs_gpio->clk = clk;
+
+ raw_spin_lock_init(&mpfs_gpio->lock);
+
+ ngpios = MAX_NUM_GPIO;
+ device_property_read_u32(dev, "ngpios", &ngpios);
+ if (ngpios > MAX_NUM_GPIO)
+ ngpios = MAX_NUM_GPIO;
+
+ mpfs_gpio->gc.direction_input = mpfs_gpio_direction_input;
+ mpfs_gpio->gc.direction_output = mpfs_gpio_direction_output;
+ mpfs_gpio->gc.get_direction = mpfs_gpio_get_direction;
+ mpfs_gpio->gc.get = mpfs_gpio_get;
+ mpfs_gpio->gc.set = mpfs_gpio_set;
+ mpfs_gpio->gc.base = -1;
+ mpfs_gpio->gc.ngpio = ngpios;
+ mpfs_gpio->gc.label = dev_name(dev);
+ mpfs_gpio->gc.parent = dev;
+ mpfs_gpio->gc.owner = THIS_MODULE;
+
+ nirqs = of_irq_count(node);
+ if (nirqs > MAX_NUM_GPIO) {
+ ret = -ENXIO;
+ goto cleanup_clock;
+ }
+ girq = &mpfs_gpio->gc.irq;
+ girq->chip = &mpfs_gpio_irqchip;
+ girq->handler = handle_simple_irq;
+ girq->parent_handler = mpfs_gpio_irq_handler;
+ girq->default_type = IRQ_TYPE_NONE;
+ girq->num_parents = nirqs;
+ girq->parents = devm_kcalloc(&pdev->dev, nirqs,
+ sizeof(*girq->parents), GFP_KERNEL);
+ if (!girq->parents) {
+ ret = -ENOMEM;
+ goto cleanup_clock;
+ }
+ for (i = 0; i < nirqs; i++)
+ girq->parents[i] = platform_get_irq(pdev, i);
+
+ ret = gpiochip_add_data(&mpfs_gpio->gc, mpfs_gpio);
+ if (ret)
+ goto cleanup_clock;
+
+ platform_set_drvdata(pdev, mpfs_gpio);
+
+ return 0;
+
+cleanup_clock:
+ clk_disable_unprepare(mpfs_gpio->clk);
+ return ret;
+}
+
+static int mpfs_gpio_remove(struct platform_device *pdev)
+{
+ struct mpfs_gpio_chip *mpfs_gpio = platform_get_drvdata(pdev);
+
+ gpiochip_remove(&mpfs_gpio->gc);
+ clk_disable_unprepare(mpfs_gpio->clk);
+
+ return 0;
+}
+
+static const struct of_device_id mpfs_of_ids[] = {
+ { .compatible = "microchip,core-gpio", },
+ { /* end of list */ }
+};
+
+static struct platform_driver mchp_core_gpio_driver = {
+ .probe = mpfs_gpio_probe,
+ .driver = {
+ .name = "microchip,core-gpio",
+ .of_match_table = mpfs_of_ids,
+ },
+ .remove = mpfs_gpio_remove,
+};
+builtin_platform_driver(mchp_core_gpio_driver);
--
2.39.2

File diff suppressed because it is too large Load Diff

@ -1,275 +0,0 @@
From 0eeed461b7b86e3b822984b1c266316ac70ccf69 Mon Sep 17 00:00:00 2001
From: vauban353 <vauban353@gmail.com>
Date: Sun, 6 Aug 2023 09:37:40 +0100
Subject: [PATCH 5/8] Microchip QSPI: Add regular transfers.
---
drivers/spi/spi-microchip-core-qspi.c | 226 +++++++++++++++++++++++++-
1 file changed, 223 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-microchip-core-qspi.c b/drivers/spi/spi-microchip-core-qspi.c
index 33c19b98b..5f1623ac4 100644
--- a/drivers/spi/spi-microchip-core-qspi.c
+++ b/drivers/spi/spi-microchip-core-qspi.c
@@ -1,3 +1,4 @@
+
// SPDX-License-Identifier: (GPL-2.0)
/*
* Microchip coreQSPI QSPI controller driver
@@ -117,10 +118,10 @@ struct mchp_coreqspi {
struct completion data_completion;
struct mutex op_lock; /* lock access to the device */
u8 *txbuf;
- u8 *rxbuf;
+ volatile u8 *rxbuf;
int irq;
- int tx_len;
- int rx_len;
+ volatile int tx_len;
+ volatile int rx_len;
};
static int mchp_coreqspi_set_mode(struct mchp_coreqspi *qspi, const struct spi_mem_op *op)
@@ -222,6 +223,68 @@ static inline void mchp_coreqspi_write_op(struct mchp_coreqspi *qspi, bool word)
}
}
+static inline void mchp_coreqspi_write_read_op(struct mchp_coreqspi *qspi, bool last)
+{
+ u32 frames, control, data;
+ qspi->rx_len = qspi->tx_len;
+
+ control = readl_relaxed(qspi->regs + REG_CONTROL);
+ control |= CONTROL_FLAGSX4;
+ writel_relaxed(control, qspi->regs + REG_CONTROL);
+
+ while (qspi->tx_len >= 4) {
+ while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL)
+ ;
+
+ data = *(u32 *)qspi->txbuf;
+ qspi->txbuf += 4;
+ qspi->tx_len -= 4;
+ writel_relaxed(data, qspi->regs + REG_X4_TX_DATA);
+
+ if (qspi->rx_len >= 8) {
+ if (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXAVAILABLE) {
+ data = readl_relaxed(qspi->regs + REG_X4_RX_DATA);
+ *(u32 *)qspi->rxbuf = data;
+ qspi->rxbuf += 4;
+ qspi->rx_len -= 4;
+ }
+ }
+ }
+
+ if (!last ) {
+ while (qspi->rx_len >= 4) {
+ while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY)
+ ;
+ data = readl_relaxed(qspi->regs + REG_X4_RX_DATA);
+ *(u32 *)qspi->rxbuf = data;
+ qspi->rxbuf += 4;
+ qspi->rx_len -= 4;
+ }
+ }
+
+ if (qspi->tx_len) {
+ control &= ~CONTROL_FLAGSX4;
+ writel_relaxed(control, qspi->regs + REG_CONTROL);
+
+
+ while (qspi->tx_len--) {
+ while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_TXFIFOFULL)
+ ;
+ data = *qspi->txbuf++;
+ writel_relaxed(data, qspi->regs + REG_TX_DATA);
+ }
+ if (!last) {
+ while (qspi->rx_len--) {
+ while (readl_relaxed(qspi->regs + REG_STATUS) & STATUS_RXFIFOEMPTY)
+ ;
+ data = readl_relaxed(qspi->regs + REG_RX_DATA);
+ *qspi->rxbuf++ = (data & 0xFF);
+ }
+ }
+ }
+}
+
+
static void mchp_coreqspi_enable_ints(struct mchp_coreqspi *qspi)
{
u32 mask = IEN_TXDONE |
@@ -497,6 +560,160 @@ static const struct spi_controller_mem_ops mchp_coreqspi_mem_ops = {
.exec_op = mchp_coreqspi_exec_op,
};
+static int mchp_coreqspi_transfer_one_message(struct spi_controller *ctlr,
+ struct spi_message *m)
+{
+ struct mchp_coreqspi *qspi = spi_controller_get_devdata(ctlr);
+ struct spi_transfer *t = NULL;
+ u32 control, frames, status;
+ u32 total_bytes, cmd_bytes = 0, idle_cycles = 0;
+ int ret;
+ bool quad = false, dual = false;
+ bool keep_cs = false;
+
+ mutex_lock(&qspi->op_lock);
+ ret = readl_poll_timeout(qspi->regs + REG_STATUS, status,
+ (status & STATUS_READY), 0,
+ TIMEOUT_MS);
+ if (ret) {
+ dev_err(&ctlr->dev,
+ "Timeout waiting on QSPI ready.\n");
+ return -ETIMEDOUT;
+ }
+
+ ret = mchp_coreqspi_setup_clock(qspi, m->spi);
+ if (ret)
+ goto error;
+
+ if (m->spi->cs_gpiod) {
+ if (m->spi->mode & SPI_CS_HIGH) {
+ gpiod_set_value(m->spi->cs_gpiod, 0);
+ } else {
+ gpiod_set_value(m->spi->cs_gpiod, 1);
+ }
+ }
+
+ control = readl_relaxed(qspi->regs + REG_CONTROL);
+ control &= ~(CONTROL_MODE12_MASK |
+ CONTROL_MODE0);
+ writel_relaxed(control, qspi->regs + REG_CONTROL);
+
+ reinit_completion(&qspi->data_completion);
+
+ /* Check the total bytes and command bytes */
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+ total_bytes += t->len;
+ if ((!cmd_bytes) && !(t->tx_buf && t->rx_buf))
+ cmd_bytes = t->len;
+ if (!t->rx_buf)
+ cmd_bytes = total_bytes;
+ if (t->tx_nbits == SPI_NBITS_QUAD || t->rx_nbits == SPI_NBITS_QUAD)
+ quad = true;
+ else if (t->tx_nbits == SPI_NBITS_DUAL || t->rx_nbits == SPI_NBITS_DUAL)
+ dual = true;
+ }
+
+ control = readl_relaxed(qspi->regs + REG_CONTROL);
+ if (quad) {
+ control |= (CONTROL_MODE0 | CONTROL_MODE12_EX_RW);
+ } else if (dual) {
+ control &= ~CONTROL_MODE0;
+ control |= CONTROL_MODE12_FULL;
+ } else {
+ control &= ~(CONTROL_MODE12_MASK |
+ CONTROL_MODE0);
+ }
+
+ writel_relaxed(control, qspi->regs + REG_CONTROL);
+ frames = total_bytes & BYTESUPPER_MASK;
+ writel_relaxed(frames, qspi->regs + REG_FRAMESUP);
+ frames = total_bytes & BYTESLOWER_MASK;
+ frames |= cmd_bytes << FRAMES_CMDBYTES_SHIFT;
+ frames |= idle_cycles << FRAMES_IDLE_SHIFT;
+ control = readl_relaxed(qspi->regs + REG_CONTROL);
+ if (control & CONTROL_MODE12_MASK)
+ frames |= (1 << FRAMES_SHIFT);
+
+ frames |= FRAMES_FLAGWORD;
+ writel_relaxed(frames, qspi->regs + REG_FRAMES);
+
+ list_for_each_entry(t, &m->transfers, transfer_list) {
+
+ if ((t->tx_buf) && (t->rx_buf)){
+ bool last = false;
+ qspi->txbuf = (u8 *)t->tx_buf;
+ qspi->rxbuf = (u8 *)t->rx_buf;
+ qspi->tx_len = t->len;
+ if (list_is_last(&t->transfer_list, &m->transfers))
+ last = true;
+ mchp_coreqspi_write_read_op(qspi, last);
+ } else if (t->tx_buf) {
+ qspi->txbuf = (u8 *)t->tx_buf;
+ qspi->tx_len = t->len;
+ mchp_coreqspi_write_op(qspi, true);
+ } else {
+ qspi->rxbuf = (u8 *)t->rx_buf;
+ qspi->rx_len = t->len;
+ }
+
+ if (t->cs_change) {
+ if (list_is_last(&t->transfer_list,
+ &m->transfers)) {
+ keep_cs = true;
+ } else {
+ if (!t->cs_off) {
+// gpiod_set_value(m->spi->cs_gpiod, 0);
+ if (m->spi->mode & SPI_CS_HIGH) {
+ gpiod_set_value(m->spi->cs_gpiod, 0);
+ } else {
+ gpiod_set_value(m->spi->cs_gpiod, 1);
+ }
+ }
+// _spi_transfer_cs_change_delay(m, t);
+ if (!list_next_entry(t, transfer_list)->cs_off) {
+// spi_set_cs(m->spi, true, false);
+ if (m->spi->mode & SPI_CS_HIGH) {
+// gpiod_set_value(m->spi->cs_gpiod, 0);
+ gpiod_set_value(m->spi->cs_gpiod, 1);
+ } else {
+// gpiod_set_value(m->spi->cs_gpiod, 1);
+ gpiod_set_value(m->spi->cs_gpiod, 0);
+ }
+// gpiod_set_value(m->spi->cs_gpiod, 1);
+ }
+ }
+ } else if (!list_is_last(&t->transfer_list, &m->transfers) &&
+ t->cs_off != list_next_entry(t, transfer_list)->cs_off) {
+// spi_set_cs(m->spi, t->cs_off, false);
+ if (m->spi->mode & SPI_CS_HIGH) {
+ gpiod_set_value(m->spi->cs_gpiod, !t->cs_off);
+ } else {
+ gpiod_set_value(m->spi->cs_gpiod, !t->cs_off);
+ }
+ }
+
+
+
+ }
+
+ mchp_coreqspi_enable_ints(qspi);
+
+ if (!wait_for_completion_timeout(&qspi->data_completion, msecs_to_jiffies(1000)))
+ ret = -ETIMEDOUT;
+
+ m->actual_length = total_bytes;
+
+error:
+ if (ret != 0 || !keep_cs)
+ gpiod_set_value(m->spi->cs_gpiod, 0);
+
+ m->status = ret;
+ spi_finalize_current_message(ctlr);
+ mutex_unlock(&qspi->op_lock);
+ mchp_coreqspi_disable_ints(qspi);
+ return ret;
+}
+
static int mchp_coreqspi_probe(struct platform_device *pdev)
{
struct spi_controller *ctlr;
@@ -550,6 +767,9 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)
ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD |
SPI_TX_DUAL | SPI_TX_QUAD;
ctlr->dev.of_node = np;
+ ctlr->transfer_one_message = mchp_coreqspi_transfer_one_message;
+ ctlr->num_chipselect = 2;
+ ctlr->use_gpio_descriptors = true;
ret = devm_spi_register_controller(&pdev->dev, ctlr);
if (ret) {
--
2.39.2

@ -1,45 +0,0 @@
From 747c6d5984cccf7c3e48c2cdb4dd1d626889096e Mon Sep 17 00:00:00 2001
From: vauban353 <vauban353@gmail.com>
Date: Sat, 12 Aug 2023 18:14:01 +0100
Subject: [PATCH 6/8] BeagleV-Fire: Add printk to IM219 driver for board tests.
---
drivers/media/i2c/imx219.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index 7a14688f8..effb399b1 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -1181,6 +1181,9 @@ static int imx219_identify_module(struct imx219 *imx219)
int ret;
u32 val;
+ printk(KERN_INFO "imx219_identify_module()\n");
+
+
ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID,
IMX219_REG_VALUE_16BIT, &val);
if (ret) {
@@ -1195,6 +1198,9 @@ static int imx219_identify_module(struct imx219 *imx219)
return -EIO;
}
+ printk(KERN_INFO "imx219_identify_module() - Success\n");
+
+
return 0;
}
@@ -1402,6 +1408,8 @@ static int imx219_probe(struct i2c_client *client)
struct imx219 *imx219;
int ret;
+ printk(KERN_INFO "imx219_probe()\n");
+
imx219 = devm_kzalloc(&client->dev, sizeof(*imx219), GFP_KERNEL);
if (!imx219)
return -ENOMEM;
--
2.39.2

@ -1,66 +0,0 @@
From e9aea028119afd0858e77989dd1a4ecc21d30dc1 Mon Sep 17 00:00:00 2001
From: vauban353 <vauban353@gmail.com>
Date: Sun, 6 Aug 2023 11:13:27 +0100
Subject: [PATCH 7/8] MMC SPI: Hack to support non DMA capable SPI ctrl.
---
drivers/mmc/host/mmc_spi.c | 6 +++++-
drivers/spi/internals.h | 3 +++
drivers/spi/spi.c | 3 +++
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index cc333ad67..fb45c7fa4 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -29,6 +29,9 @@
#include <asm/unaligned.h>
+//<CJ>:
+#undef CONFIG_HAS_DMA
+//#define DEBUG 1
/* NOTES:
*
@@ -1375,7 +1378,8 @@ static int mmc_spi_probe(struct spi_device *spi)
* that's the only reason not to use a few MHz for f_min (until
* the upper layer reads the target frequency from the CSD).
*/
- mmc->f_min = 400000;
+//<CJ> mmc->f_min = 400000;
+ mmc->f_min = 5000000;
mmc->f_max = spi->max_speed_hz;
host = mmc_priv(mmc);
diff --git a/drivers/spi/internals.h b/drivers/spi/internals.h
index 4a28a8395..c49350240 100644
--- a/drivers/spi/internals.h
+++ b/drivers/spi/internals.h
@@ -12,6 +12,9 @@
#ifndef __LINUX_SPI_INTERNALS_H
#define __LINUX_SPI_INTERNALS_H
+//<CJ>:
+#undef CONFIG_HAS_DMA
+
#include <linux/device.h>
#include <linux/dma-direction.h>
#include <linux/scatterlist.h>
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a221478e5..e198049cc 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -42,6 +42,9 @@ EXPORT_TRACEPOINT_SYMBOL(spi_transfer_stop);
#include "internals.h"
+//<CJ>:
+#undef CONFIG_HAS_DMA
+
static DEFINE_IDR(spi_master_idr);
static void spidev_release(struct device *dev)
--
2.39.2

@ -1,23 +0,0 @@
From 09e2d12d8ade10bb2d8ab1d42e9a1bd8442a74c8 Mon Sep 17 00:00:00 2001
From: Robert Nelson <robertcnelson@gmail.com>
Date: Tue, 10 Oct 2023 10:01:45 -0500
Subject: [PATCH 9/9] Makefile: build mpfs-beaglev-fire.dtb
Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
---
arch/riscv/boot/dts/microchip/Makefile | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/boot/dts/microchip/Makefile b/arch/riscv/boot/dts/microchip/Makefile
index 48c9d3d071f3..4e3529217d9a 100644
--- a/arch/riscv/boot/dts/microchip/Makefile
+++ b/arch/riscv/boot/dts/microchip/Makefile
@@ -5,4 +5,5 @@ dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-m100pfsevp.dtb
dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-polarberry.dtb
dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-video-kit.dtb
dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-tysom-m.dtb
+dtb-$(CONFIG_SOC_MICROCHIP_POLARFIRE) += mpfs-beaglev-fire.dtb
obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
--
2.39.2

@ -1,516 +0,0 @@
From 413071dc2f13f581eb844a0009d571dfa0bb2f02 Mon Sep 17 00:00:00 2001
From: Lars Randers <lranders@mail.dk>
Date: Thu, 20 Jun 2024 13:55:40 +0000
Subject: [PATCH] BeagleV-Fire: Add MPFS TVS auxiliary driver
Signed-off-by: Lars Randers <lranders@mail.dk>
---
drivers/hwmon/Kconfig | 11 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/tvs-mpfs.c | 371 +++++++++++++++++++++++++++++++++
drivers/mailbox/mailbox-mpfs.c | 62 ++++++
4 files changed, 445 insertions(+)
create mode 100644 drivers/hwmon/tvs-mpfs.c
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index a5143d01b..e3564df18 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2108,6 +2108,17 @@ config SENSORS_TMP513
This driver can also be built as a module. If so, the module
will be called tmp513.
+config SENSORS_TVS_MPFS
+ tristate "PolarFire SoC (MPFS) TVS"
+ depends on POLARFIRE_SOC_MAILBOX
+ help
+ This driver adds support for the PolarFire SoC (MPFS) Temperature Voltage Sensor.
+
+ To compile this driver as a module, choose M here. the
+ module will be called tvs-mpfs.
+
+ If unsure, say N.
+
config SENSORS_VEXPRESS
tristate "Versatile Express"
depends on VEXPRESS_CONFIG
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 11d076cad..1cebd0e73 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -203,6 +203,7 @@ obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TMP464) += tmp464.o
obj-$(CONFIG_SENSORS_TMP513) += tmp513.o
+obj-$(CONFIG_SENSORS_TVS_MPFS) += tvs-mpfs.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
diff --git a/drivers/hwmon/tvs-mpfs.c b/drivers/hwmon/tvs-mpfs.c
new file mode 100644
index 000000000..087a8b33f
--- /dev/null
+++ b/drivers/hwmon/tvs-mpfs.c
@@ -0,0 +1,371 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * Author: Lars Randers <lranders@mail.dk>
+ *
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/err.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+#include <linux/hwmon.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#define PFSOC_CONTROL_SCB_TVS_CONTROL 0x08
+#define PFSOC_CONTROL_SCB_TVS_OUTPUT0 0x24
+#define PFSOC_CONTROL_SCB_TVS_OUTPUT1 0x28
+
+#define CTRL_POWEROFF BIT(5)
+#define CTRL_ABORT BIT(4)
+#define CTRL_TEMP BIT(3)
+#define CTRL_2P5 BIT(2)
+#define CTRL_1P8 BIT(1)
+#define CTRL_1P05 BIT(0)
+
+#define OUTPUT0_U1P8_MASK 0x7FFF0000
+#define OUTPUT0_U1P8_OFF 16
+#define OUTPUT0_U1P0_MASK 0x00007FFF
+#define OUTPUT0_U1P0_OFF 0
+#define OUTPUT1_TEMP_MASK 0xFFFF0000
+#define OUTPUT1_TEMP_OFF 16
+#define OUTPUT1_U2P5_MASK 0x00007FFF
+#define OUTPUT1_U2P5_OFF 0
+
+/*
+ * Poll intervals (in milliseconds)
+ */
+#define MPFS_TVS_MIN_POLL_INTERVAL 2000
+
+// The following constant is 273.5 in (16.4) fixedpoint notation
+#define MPFS_TVS_MIN_TEMP_IN_K 0x1112
+
+typedef struct {
+ long min;
+ long actual;
+ long max;
+} mpfs_tvs_sensor_t;
+
+typedef enum {
+ SN_V1P05 = 0,
+ SN_V1P8,
+ SN_V2P5,
+ SN_TEMP,
+
+ SN_MAX
+} mpfs_tvs_sn_t;
+
+static const char *mpfs_tvs_voltage_labels[] = { "U1P05", "U1P8", "U2P5" };
+
+struct mpfs_tvs {
+ struct device *dev;
+ struct device *hwmon_dev;
+ struct task_struct *poll_task;
+ bool kthread_running;
+ long update_interval; /* in milli-seconds */
+ mpfs_tvs_sensor_t sensors[SN_MAX];
+ void __iomem *ctrl_base;
+};
+
+static int mpfs_tvs_update_sensors(struct mpfs_tvs *data) {
+ u32 temp;
+ u32 work;
+
+ /* read measurement */
+ temp = readl(data->ctrl_base + PFSOC_CONTROL_SCB_TVS_OUTPUT1);
+ work = temp;
+
+ /* compute temperature */
+ temp = (temp & OUTPUT1_TEMP_MASK) >> OUTPUT1_TEMP_OFF;
+ temp = clamp_val(temp, MPFS_TVS_MIN_TEMP_IN_K, INT_MAX);
+ temp = temp - MPFS_TVS_MIN_TEMP_IN_K; /* Kelvin to Celsius */
+ temp = (temp * 1000) >> 4;
+ data->sensors[SN_TEMP].actual = temp;
+ data->sensors[SN_TEMP].max =
+ max(data->sensors[SN_TEMP].actual, data->sensors[SN_TEMP].max);
+ data->sensors[SN_TEMP].min =
+ min(data->sensors[SN_TEMP].min, data->sensors[SN_TEMP].actual);
+
+ /* compute voltage */
+ work &= OUTPUT1_U2P5_MASK;
+ work = (1 * work) >> 3;
+ data->sensors[SN_V2P5].actual = work;
+ data->sensors[SN_V2P5].max =
+ max(data->sensors[SN_V2P5].actual, data->sensors[SN_V2P5].max);
+ data->sensors[SN_V2P5].min =
+ min(data->sensors[SN_V2P5].min, data->sensors[SN_V2P5].actual);
+
+ temp = readl(data->ctrl_base + PFSOC_CONTROL_SCB_TVS_OUTPUT0);
+ work = temp;
+ temp = (OUTPUT0_U1P8_MASK & temp) >> OUTPUT0_U1P8_OFF;
+ temp = (1 * temp) >> 3;
+ data->sensors[SN_V1P8].actual = temp;
+ data->sensors[SN_V1P8].max =
+ max(data->sensors[SN_V1P8].actual, data->sensors[SN_V1P8].max);
+ data->sensors[SN_V2P5].min =
+ min(data->sensors[SN_V1P8].min, data->sensors[SN_V1P8].actual);
+
+ work &= OUTPUT0_U1P0_MASK;
+ work = (1 * work) >> 3;
+ data->sensors[SN_V1P05].actual = work;
+ data->sensors[SN_V1P05].max =
+ max(data->sensors[SN_V1P05].actual, data->sensors[SN_V1P05].max);
+ data->sensors[SN_V1P05].min =
+ min(data->sensors[SN_V1P05].min, data->sensors[SN_V1P05].actual);
+
+ return 0;
+}
+
+
+static int mpfs_tvs_chip_read(struct mpfs_tvs *data, long *val)
+{
+ *val = data->update_interval;
+ return 0;
+}
+
+static int mpfs_tvs_temp_read(struct mpfs_tvs *data, u32 attr,
+ int channel, long *val)
+{
+ switch(attr) {
+ case hwmon_temp_input:
+ *val = data->sensors[SN_TEMP].actual;
+ break;
+
+ case hwmon_temp_max:
+ *val = data->sensors[SN_TEMP].max;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+static int mpfs_tvs_voltage_read(struct mpfs_tvs *data, u32 attr,
+ int channel, long *val)
+{
+ dev_dbg(data->dev, "read voltage chan %d\n", channel);
+ switch(attr) {
+ case hwmon_in_input:
+ *val = data->sensors[channel].actual;
+ break;
+
+ case hwmon_in_max:
+ *val = data->sensors[channel].max;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+
+static ssize_t mpfs_tvs_interval_write(struct mpfs_tvs *data, long val)
+{
+ data->update_interval = clamp_val(val,
+ MPFS_TVS_MIN_POLL_INTERVAL, INT_MAX);
+ return 0;
+}
+
+
+static umode_t mpfs_tvs_is_visible(const void *data,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ if(type == hwmon_chip && attr == hwmon_chip_update_interval)
+ return 0644;
+
+ if(type == hwmon_temp) {
+ switch(attr) {
+ case hwmon_temp_input:
+ case hwmon_temp_max:
+ case hwmon_temp_label:
+ return 0444;
+
+ default:
+ return 0;
+ }
+ } else if (type == hwmon_in) {
+ switch (attr) {
+ case hwmon_in_input:
+ case hwmon_in_label:
+ return 0444;
+
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static int mpfs_tvs_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ struct mpfs_tvs *data = dev_get_drvdata(dev);
+
+ switch(type) {
+ case hwmon_temp:
+ return mpfs_tvs_temp_read(data, attr, channel, val);
+ case hwmon_in:
+ return mpfs_tvs_voltage_read(data, attr, channel, val);
+ case hwmon_chip:
+ return mpfs_tvs_chip_read(data, val);
+
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int mpfs_tvs_write(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long val)
+{
+ struct mpfs_tvs *data = dev_get_drvdata(dev);
+
+ switch(type) {
+ case hwmon_chip:
+ return mpfs_tvs_interval_write(data, val);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int mpfs_tvs_read_labels(struct device *dev,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel,
+ const char **str)
+{
+ switch(type) {
+ case hwmon_temp:
+ *str = "CPU Temp";
+ return 0;
+ case hwmon_in:
+ *str = mpfs_tvs_voltage_labels[channel];
+ return 0;
+ default:
+ return -ENOTSUPP;
+ }
+}
+
+
+static const struct hwmon_ops mpfs_tvs_ops = {
+ .is_visible = mpfs_tvs_is_visible,
+ .read_string = mpfs_tvs_read_labels,
+ .read = mpfs_tvs_read,
+ .write = mpfs_tvs_write,
+};
+
+static const struct hwmon_channel_info *mpfs_tvs_info[] = {
+ HWMON_CHANNEL_INFO(chip,
+ HWMON_C_REGISTER_TZ|HWMON_C_UPDATE_INTERVAL),
+ HWMON_CHANNEL_INFO(temp,
+ HWMON_T_INPUT|HWMON_T_MIN|HWMON_T_MAX|HWMON_T_LABEL),
+ HWMON_CHANNEL_INFO(in,
+ HWMON_I_INPUT|HWMON_I_LABEL,
+ HWMON_I_INPUT|HWMON_I_LABEL,
+ HWMON_I_INPUT|HWMON_I_LABEL),
+ NULL
+};
+
+static const struct hwmon_chip_info mpfs_tvs_chip_info = {
+ .ops = &mpfs_tvs_ops,
+ .info = mpfs_tvs_info,
+};
+
+
+static int mpfs_tvs_poll_task(void *ptr)
+{
+ struct mpfs_tvs *data = ptr;
+ int ret = 0;
+
+ data->kthread_running = true;
+
+ set_freezable();
+
+ while(!kthread_should_stop()) {
+ schedule_timeout_interruptible(data->update_interval);
+ try_to_freeze();
+ ret = mpfs_tvs_update_sensors(data);
+ if(ret)
+ break;
+ }
+
+ data->kthread_running = false;
+ return ret;
+}
+
+static int mpfs_tvs_probe(struct auxiliary_device *auxdev,
+ const struct auxiliary_device_id *id)
+{
+ struct device *dev = &auxdev->dev;
+ struct device *hwmon_dev;
+ struct mpfs_tvs *data;
+ struct task_struct *task;
+ int err;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if(!data)
+ return -ENOMEM;
+
+ data->ctrl_base = (void __iomem *)auxdev->dev.platform_data;
+
+ data->dev = dev;
+ data->kthread_running = false;
+
+ hwmon_dev = devm_hwmon_device_register_with_info(dev, "mpfs_tvs",
+ data,
+ &mpfs_tvs_chip_info,
+ NULL);
+
+ if(IS_ERR(hwmon_dev)) {
+ err = PTR_ERR(hwmon_dev);
+ dev_err(dev, "Class registration failed (%d)\n", err);
+ return err;
+ }
+
+ /* enable HW sensor */
+ writel(CTRL_1P05 | CTRL_1P8 | CTRL_2P5 | CTRL_TEMP,
+ data->ctrl_base + PFSOC_CONTROL_SCB_TVS_CONTROL);
+
+ data->hwmon_dev = hwmon_dev;
+ data->sensors[SN_TEMP].max = 0;
+ data->sensors[SN_V1P05].min =
+ data->sensors[SN_V1P8].min =
+ data->sensors[SN_V2P5].min = 20000;
+ data->sensors[SN_V1P05].max =
+ data->sensors[SN_V1P8].max =
+ data->sensors[SN_V2P5].max = 0;
+ data->update_interval = MPFS_TVS_MIN_POLL_INTERVAL;
+ mpfs_tvs_update_sensors(data);
+
+ task = kthread_run(mpfs_tvs_poll_task, data, "tvs-mpfs-kthread");
+ if (IS_ERR(task)) {
+ err = PTR_ERR(task);
+ dev_err(dev, "Unable to run kthread err %d\n", err);
+ return err;
+ }
+
+ data->poll_task = task;
+
+ dev_info(dev, "Registered MPFS TVS auxiliary driver\n");
+ return 0;
+}
+
+static const struct auxiliary_device_id mpfs_tvs_ids[] = {
+ {
+ .name = "mailbox_mpfs.tvs-mpfs",
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(auxiliary, mpfs_reset_ids);
+
+static struct auxiliary_driver mpfs_tvs_driver = {
+ .probe = mpfs_tvs_probe,
+ .id_table = mpfs_tvs_ids,
+};
+module_auxiliary_driver(mpfs_tvs_driver);
+
+MODULE_AUTHOR("Lars Randers <lranders@mail.dk>");
+MODULE_DESCRIPTION("MPFS temperature voltage sensor driver");
+MODULE_LICENSE("GPL");
\ No newline at end of file
diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
index 162df4965..198e6b37d 100644
--- a/drivers/mailbox/mailbox-mpfs.c
+++ b/drivers/mailbox/mailbox-mpfs.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/auxiliary_bus.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -220,6 +221,64 @@ static const struct mbox_chan_ops mpfs_mbox_ops = {
.last_tx_done = mpfs_mbox_last_tx_done,
};
+static void mpfs_mbox_auxdev_release(struct device *dev)
+{
+ struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
+
+ kfree(auxdev);
+}
+
+static struct auxiliary_device *mpfs_mbox_adev_alloc(struct device *parent_dev)
+{
+ struct auxiliary_device *auxdev;
+ int ret;
+
+ auxdev = kzalloc(sizeof(*auxdev), GFP_KERNEL);
+ if(!auxdev)
+ return ERR_PTR(-ENOMEM);
+
+ auxdev->name = "tvs-mpfs";
+ auxdev->dev.parent = parent_dev;
+ auxdev->dev.release = mpfs_mbox_auxdev_release;
+ auxdev->id = 10u;
+
+ ret = auxiliary_device_init(auxdev);
+ if(ret) {
+ kfree(auxdev);
+ return ERR_PTR(ret);
+ }
+
+ return auxdev;
+}
+
+static void mpfs_mbox_unregister_auxdev(void *dev)
+{
+ struct auxiliary_device *auxdev = dev;
+
+ auxiliary_device_delete(auxdev);
+ auxiliary_device_uninit(auxdev);
+}
+
+int mpfs_mbox_auxdev_register(struct device *parent_dev, void __iomem *base)
+{
+ struct auxiliary_device *auxdev;
+ int ret;
+
+ auxdev = mpfs_mbox_adev_alloc(parent_dev);
+ if(IS_ERR(auxdev))
+ return PTR_ERR(auxdev);
+
+ auxdev->dev.platform_data = base;
+
+ ret = auxiliary_device_add(auxdev);
+ if(ret) {
+ auxiliary_device_uninit(auxdev);
+ return ret;
+ }
+
+ return devm_add_action_or_reset(parent_dev, mpfs_mbox_unregister_auxdev, auxdev);
+}
+
static int mpfs_mbox_probe(struct platform_device *pdev)
{
struct mpfs_mbox *mbox;
@@ -261,6 +320,9 @@ static int mpfs_mbox_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Registering MPFS mailbox controller failed\n");
return ret;
}
+
+ mpfs_mbox_auxdev_register(&pdev->dev, mbox->ctrl_base);
+
dev_info(&pdev->dev, "Registered MPFS mailbox controller driver\n");
return 0;
--
2.39.2

@ -1,17 +1,17 @@
From 8911855f7b07ba7f592f73850e551802ae40601d Mon Sep 17 00:00:00 2001
From 4c14a137c399cbdb29d121b6dcdc395976e38579 Mon Sep 17 00:00:00 2001
From: vauban353 <vauban353@gmail.com>
Date: Sat, 5 Nov 2022 17:47:50 +0000
Subject: [PATCH 2/8] PCIe: Change controller and bridge base address.
Date: Fri, 25 Oct 2024 09:17:26 +0000
Subject: [PATCH] PCIe: Change controller and bridge base address.
---
drivers/pci/controller/pcie-microchip-host.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c
index 56306f514..b1b3b7820 100644
index 4030a2bb0..1aa8aca7e 100644
--- a/drivers/pci/controller/pcie-microchip-host.c
+++ b/drivers/pci/controller/pcie-microchip-host.c
@@ -26,8 +26,8 @@
@@ -27,8 +27,8 @@
#define MC_ATT_MASK GENMASK_ULL(63, 31)
/* PCIe Bridge Phy and Controller Phy offsets */
@ -20,8 +20,8 @@ index 56306f514..b1b3b7820 100644
+#define MC_PCIE1_BRIDGE_ADDR 0x00004000u
+#define MC_PCIE1_CTRL_ADDR 0x00006000u
#define MC_PCIE_BRIDGE_ADDR (MC_PCIE1_BRIDGE_ADDR)
#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
/* PCIe Bridge Phy Regs */
#define PCIE_PCI_IRQ_DW0 0xa8
--
2.39.2

@ -0,0 +1,25 @@
From ff3af0236730758e918a3d6c090bb78ce03aedcf Mon Sep 17 00:00:00 2001
From: Lars Randers <lranders@mail.dk>
Date: Mon, 28 Oct 2024 11:46:26 +0000
Subject: [PATCH] can: mpfs_can: add registration string
Signed-off-by: Lars Randers <lranders@mail.dk>
---
drivers/net/can/mpfs_can.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/can/mpfs_can.c b/drivers/net/can/mpfs_can.c
index f741af2c0..0e0aa2384 100644
--- a/drivers/net/can/mpfs_can.c
+++ b/drivers/net/can/mpfs_can.c
@@ -913,6 +913,7 @@ static int mpfs_can_probe(struct platform_device *pdev)
priv->reg, ndev->irq, priv->can.clock.freq,
priv->tx_max);
+ dev_info(&pdev->dev, "Registered MPFS CAN controller %s\n", ndev->name);
return 0;
err:
--
2.39.2

@ -0,0 +1,25 @@
From 6759b8dc43985a2d6083835931257f3229b240f4 Mon Sep 17 00:00:00 2001
From: Lars Randers <lranders@mail.dk>
Date: Mon, 28 Oct 2024 11:55:28 +0000
Subject: [PATCH] gpio: gpio-mpfs: add registration string
Signed-off-by: Lars Randers <lranders@mail.dk>
---
drivers/gpio/gpio-mpfs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpio/gpio-mpfs.c b/drivers/gpio/gpio-mpfs.c
index d7168aa04..abf3e4151 100644
--- a/drivers/gpio/gpio-mpfs.c
+++ b/drivers/gpio/gpio-mpfs.c
@@ -332,6 +332,7 @@ static int mpfs_gpio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mpfs_gpio);
+ dev_info(&pdev->dev, "Registered MPFS GPIO controller\n");
return 0;
cleanup_clock:
--
2.39.2
Loading…
Cancel
Save