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 */