From ee98106bc58a755ff4909831fcedfe5fbbadfdf6 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 18 Feb 2025 11:35:10 +0200 Subject: [PATCH] arch/risc-v/src/mpfs: Implement wrcomplete support for coremmc driver If CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE is defined, the coremmc driver uses SD card's dat0 line to detect whether the sd card is still busy. This requires that the FPGA design using coremmc block wires dat0 line to some fabric irq; and configures CONFIG_MPFS_COREMMC_WRCOMPLETE_IRQNUM to point to that. Default for the irq number is 4. (MSS_INT_F2M_4) Signed-off-by: Jukka Laitinen --- arch/risc-v/src/mpfs/Kconfig | 12 ++++++ arch/risc-v/src/mpfs/mpfs_coremmc.c | 62 +++++++++++++++++++++++++++- arch/risc-v/src/mpfs/mpfs_sdio_dev.h | 3 ++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/arch/risc-v/src/mpfs/Kconfig b/arch/risc-v/src/mpfs/Kconfig index 34e459907d0..008e9b4de79 100644 --- a/arch/risc-v/src/mpfs/Kconfig +++ b/arch/risc-v/src/mpfs/Kconfig @@ -369,6 +369,7 @@ config MPFS_EMMCSD config MPFS_COREMMC bool "COREMMC" select ARCH_HAVE_SDIO + select ARCH_HAVE_SDIOWAIT_WRCOMPLETE select SDIO_BLOCKSETUP default n ---help--- @@ -385,6 +386,17 @@ config MPFS_COREMMC_IRQNUM range 0 63 depends on MPFS_COREMMC +config MPFS_COREMMC_WRCOMPLETE_IRQNUM + int "Number of F2H interrupt" + default 4 + range 0 63 + depends on MPFS_COREMMC + depends on MMCSD_SDIOWAIT_WRCOMPLETE + ---help--- + In case SD card's DAT0 line is connected to an F2H IRQ in the FPGA + design, select CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE and configure the + correct IRQ line here. + config MPFS_IHC_CLIENT bool "IHC slave" depends on RPTUN && !MPFS_BOOTLOADER diff --git a/arch/risc-v/src/mpfs/mpfs_coremmc.c b/arch/risc-v/src/mpfs/mpfs_coremmc.c index 0fe32a28268..135e6d37eb4 100644 --- a/arch/risc-v/src/mpfs/mpfs_coremmc.c +++ b/arch/risc-v/src/mpfs/mpfs_coremmc.c @@ -210,6 +210,11 @@ static int mpfs_registercallback(struct sdio_dev_s *dev, worker_t callback, void *arg); static void mpfs_callback(void *arg); +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE +static int mpfs_coremmc_wrcomplete_interrupt(int irq, void *context, + void *arg); +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -246,6 +251,10 @@ struct mpfs_dev_s g_coremmc_dev = }, .hw_base = CONFIG_MPFS_COREMMC_BASE, .plic_irq = MPFS_IRQ_FABRIC_F2H_0 + CONFIG_MPFS_COREMMC_IRQNUM, +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + .wrcomplete_irq = MPFS_IRQ_FABRIC_F2H_0 + + CONFIG_MPFS_COREMMC_WRCOMPLETE_IRQNUM, +#endif .blocksize = 512, .fifo_depth = 0, .onebit = false, @@ -477,6 +486,17 @@ static void mpfs_configwaitints(struct mpfs_dev_s *priv, uint32_t waitmask, flags = enter_critical_section(); +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + if ((waitevents & SDIOWAIT_WRCOMPLETE) != 0) + { + up_enable_irq(priv->wrcomplete_irq); + } + else if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0) + { + up_disable_irq(priv->wrcomplete_irq); + } +#endif + priv->waitevents = waitevents; priv->wkupevent = wkupevent; priv->waitmask = waitmask; @@ -778,6 +798,34 @@ static void mpfs_endtransfer(struct mpfs_dev_s *priv, } } +/**************************************************************************** + * Name: mpfs_coremmc_wrcomplete_interrupt + * + * Description: + * coremmc interrupt handler for SD card wrcomplete (DAT0) detection + * + * Input Parameters: + * priv - Instance of the coremmc private state structure. + * + * Returned Value: + * OK - Interrupt handled + * + ****************************************************************************/ + +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE +static int mpfs_coremmc_wrcomplete_interrupt(int irq, void *context, + void *arg) +{ + struct mpfs_dev_s *priv = (struct mpfs_dev_s *)arg; + + DEBUGASSERT(priv != NULL); + + mpfs_endwait(priv, SDIOWAIT_WRCOMPLETE); + + return OK; +} +#endif + /**************************************************************************** * Name: mpfs_coremmc_interrupt * @@ -1311,7 +1359,19 @@ static int mpfs_attach(struct sdio_dev_s *dev) mpfs_putreg8(priv, 0x00, MPFS_COREMMC_MBIMR); mpfs_putreg8(priv, 0xff, MPFS_COREMMC_MBICR); - up_enable_irq(priv->plic_irq); +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + ret = irq_attach(priv->wrcomplete_irq, + mpfs_coremmc_wrcomplete_interrupt, priv); + + if (ret != OK) + { + irq_detach(priv->plic_irq); + } + else +#endif + { + up_enable_irq(priv->plic_irq); + } } mcinfo("attach: %d\n", ret); diff --git a/arch/risc-v/src/mpfs/mpfs_sdio_dev.h b/arch/risc-v/src/mpfs/mpfs_sdio_dev.h index 7b0774bde78..10e36c60843 100644 --- a/arch/risc-v/src/mpfs/mpfs_sdio_dev.h +++ b/arch/risc-v/src/mpfs/mpfs_sdio_dev.h @@ -44,6 +44,9 @@ struct mpfs_dev_s const uintptr_t hw_base; /* Base address */ const int plic_irq; /* PLIC interrupt */ +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + const int wrcomplete_irq; /* Card write complete interrupt */ +#endif bool clk_enabled; /* Clk state */ /* eMMC / SD and HW parameters */