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 <jukka.laitinen@tii.ae>
This commit is contained in:
Jukka Laitinen 2025-02-18 11:35:10 +02:00 committed by archer
parent e072771516
commit ee98106bc5
3 changed files with 76 additions and 1 deletions

View file

@ -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

View file

@ -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);

View file

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