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