Re: Octeon MMC driver
Nick Hudson <[email protected]> Sun, 22 Mar 2026 15:43:54 +0000
| Newsgroups | gmane.os.netbsd.ports.mips.devel |
|---|---|
| Message-ID | <[email protected]> |
--Apple-Mail=_56E25E9F-DADC-4AE5-8CB4-AD942A37FD51
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=utf-8
On 19/03/2026 11:35, Kevin Bowling wrote:
> Hi,
> I have ported OpenBSD's Octeon MMC driver to NetBSD here:
> https://people.freebsd.org/~kbowling/oct_mmc.patch
Cool. Thanks for working on this.
> It seems stable with light testing and is now self booting on my ER4:
> Octeon ubnt_e100# set bootcmd 'fatload mmc 0 $loadaddr
> netbsd;bootoctlinux $loadaddr coremask=3D0x3 root=3Dwedge:octeon-root'
> Octeon ubnt_e100# saveenv
> I would be curious if it works for others and if the code can be
> improved as I am not deeply familiar with Net or Open internals.
> There is a lag when attaching, which I suspect is caused by an SDIO
> check that could be improved.
Some comments=E2=80=A6
The cache lock workaround is =E2=80=9Cinteresting=E2=80=9D
Don=E2=80=99t use splsdmmc, but instead use your sc_intr_mtx mutex or =
remove the splsdmmc calls.
Something like the attached.
I guess you=E2=80=99re getting your DTB from a vendor distribution?
~/netbsd/nbcvs/src % grep -r "cavium,octeon-[0-9]*-mmc" =
sys/external/gpl2/dts/dist
~/netbsd/nbcvs/src %
You should provide patches to
sys/arch/mips/dts
See sys/arch/arm/dts for example how a board=E2=80=99s dts is changed =
compared
to the Linux mainline upstream
Nick
--Apple-Mail=_56E25E9F-DADC-4AE5-8CB4-AD942A37FD51
Content-Disposition: attachment;
filename=octeon_mmc.c.diff
Content-Type: application/octet-stream;
x-unix-mode=0644;
name="octeon_mmc.c.diff"
Content-Transfer-Encoding: quoted-printable
diff --git a/sys/arch/mips/cavium/dev/octeon_mmc.c b/sys/arch/mips/cavium/=
dev/octeon_mmc.c
index 2939bb53e73d..980f6ff3adea 100644
=2D-- a/sys/arch/mips/cavium/dev/octeon_mmc.c
+++ b/sys/arch/mips/cavium/dev/octeon_mmc.c
@@ -457,15 +457,15 @@ octmmc_init_bus(struct octmmc_bus *bus)
if (bus->bus_wdog > MIO_EMM_WDOG_CLK_CNT)
bus->bus_wdog =3D MIO_EMM_WDOG_CLK_CNT;
=20
- s =3D splsdmmc();
+ octmmc_acquire(bus);
+
+ mutex_enter(&sc->sc_intr_mtx);
=20
/* Enable the bus. */
reg =3D MMC_RD_8(sc, MIO_EMM_CFG);
reg |=3D 1u << bus->bus_id;
MMC_WR_8(sc, MIO_EMM_CFG, reg);
=20
- octmmc_acquire(bus);
-
/*
* Enable interrupts.
*
@@ -481,9 +481,9 @@ octmmc_init_bus(struct octmmc_bus *bus)
=20
MMC_WR_8(sc, MIO_EMM_STS_MASK, DEF_STS_MASK);
=20
- octmmc_release(bus);
+ mutex_exit(&sc->sc_intr_mtx);
=20
- splx(s);
+ octmmc_release(bus);
=20
return 0;
}
@@ -494,21 +494,25 @@ octmmc_intr(void *arg)
struct octmmc_softc *sc =3D arg;
uint64_t isr;
=20
+ mutex_enter(&sc->sc_intr_mtx);
/* Get and acknowledge pending interrupts. */
isr =3D MMC_RD_8(sc, MIO_EMM_INT);
- if (isr =3D=3D 0)
+ if (isr =3D=3D 0) {
+ mutex_exit(&sc->sc_intr_mtx);
return 0;
+ }
+
MMC_WR_8(sc, MIO_EMM_INT, isr);
=20
if (ISSET(isr, MIO_EMM_INT_CMD_DONE) ||
ISSET(isr, MIO_EMM_INT_CMD_ERR) ||
ISSET(isr, MIO_EMM_INT_DMA_DONE) ||
ISSET(isr, MIO_EMM_INT_DMA_ERR)) {
- mutex_enter(&sc->sc_intr_mtx);
sc->sc_intr_status |=3D isr;
cv_broadcast(&sc->sc_intr_cv);
- mutex_exit(&sc->sc_intr_mtx);
}
+ mutex_exit(&sc->sc_intr_mtx);
+ =09
=20
return 1;
}
@@ -522,10 +526,8 @@ octmmc_host_reset(sdmmc_chipset_handle_t sch)
/* Force reswitch. */
bus->bus_hc->sc_current_switch =3D ~0ull;
=20
- s =3D splsdmmc();
octmmc_acquire(bus);
octmmc_release(bus);
- splx(s);
=20
return 0;
}
@@ -674,7 +676,6 @@ octmmc_exec_dma(struct octmmc_bus *bus, struct sdmmc_c=
ommand *cmd)
return;
}
=20
- s =3D splsdmmc();
octmmc_acquire(bus);
=20
/*
@@ -705,8 +706,6 @@ octmmc_exec_dma(struct octmmc_bus *bus, struct sdmmc_c=
ommand *cmd)
/* Set status mask. */
MMC_WR_8(sc, MIO_EMM_STS_MASK, DEF_STS_MASK);
=20
- mutex_enter(&sc->sc_intr_mtx);
-
/* Prepare and issue the command. */
dmacmd =3D MIO_EMM_DMA_DMA_VAL | MIO_EMM_DMA_MULTI | MIO_EMM_DMA_SECTOR;
dmacmd |=3D (uint64_t)bus->bus_id << MIO_EMM_DMA_BUS_ID_SHIFT;
@@ -715,6 +714,8 @@ octmmc_exec_dma(struct octmmc_bus *bus, struct sdmmc_c=
ommand *cmd)
dmacmd |=3D cmd->c_arg;
if (!ISSET(cmd->c_flags, SCF_CMD_READ))
dmacmd |=3D MIO_EMM_DMA_RW;
+
+ mutex_enter(&sc->sc_intr_mtx);
MMC_WR_8(sc, MIO_EMM_DMA, dmacmd);
=20
wait_intr:
@@ -781,7 +782,6 @@ unload_dma:
=20
dma_out:
octmmc_release(bus);
- splx(s);
}
=20
void
@@ -799,7 +799,6 @@ octmmc_exec_pio(struct octmmc_bus *bus, struct sdmmc_c=
ommand *cmd)
return;
}
=20
- s =3D splsdmmc();
octmmc_acquire(bus);
=20
/* If this is a write, copy data to the controller's buffer. */
@@ -818,14 +817,14 @@ octmmc_exec_pio(struct octmmc_bus *bus, struct sdmmc=
_command *cmd)
/* Set status mask. */
MMC_WR_8(sc, MIO_EMM_STS_MASK, PIO_STS_MASK);
=20
- mutex_enter(&sc->sc_intr_mtx);
-
/* Issue the command. */
piocmd =3D MIO_EMM_CMD_CMD_VAL;
piocmd |=3D (uint64_t)bus->bus_id << MIO_EMM_CMD_BUS_ID_SHIFT;
piocmd |=3D (uint64_t)cmd->c_opcode << MIO_EMM_CMD_CMD_IDX_SHIFT;
piocmd |=3D cmd->c_arg;
piocmd |=3D octmmc_crtype_fixup(cmd);
+
+ mutex_enter(&sc->sc_intr_mtx);
MMC_WR_8(sc, MIO_EMM_CMD, piocmd);
=20
cmd->c_error =3D octmmc_wait_intr(sc, MIO_EMM_INT_CMD_DONE |
@@ -875,7 +874,6 @@ octmmc_exec_pio(struct octmmc_bus *bus, struct sdmmc_c=
ommand *cmd)
=20
pio_out:
octmmc_release(bus);
- splx(s);
}
=20
paddr_t
--Apple-Mail=_56E25E9F-DADC-4AE5-8CB4-AD942A37FD51
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=us-ascii
--Apple-Mail=_56E25E9F-DADC-4AE5-8CB4-AD942A37FD51--