Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Sep 2006 22:58:20 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 106689 for review
Message-ID:  <200609252258.k8PMwKRc029099@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=106689

Change 106689 by imp@imp_lighthouse on 2006/09/25 22:57:32

	checkpoint

Affected files ...

.. //depot/projects/arm/src/sys/dev/mmc/bridge.h#3 edit
.. //depot/projects/arm/src/sys/dev/mmc/mmc.c#3 edit
.. //depot/projects/arm/src/sys/dev/mmc/mmcbrvar.h#1 add

Differences ...

==== //depot/projects/arm/src/sys/dev/mmc/bridge.h#3 (text+ko) ====

@@ -59,6 +59,10 @@
 	vdd_330, vdd_340, vdd_350, vdd_360
 };
 
+enum mmc_poewr_mode {
+	power_off = 0, power_up, power_on
+};
+
 enum mmc_bus_mode {
 	opendrain = 1, pushpull
 };
@@ -68,7 +72,7 @@
 };
 
 enum mmc_bus_width {
-	bus_width_1 = 0, bus_width_4 = 2
+	bus_width_1 = 0, bus_width_4 = 2, bus_width_8 = 3
 };
 
 struct mmc_ios {
@@ -91,6 +95,7 @@
 #define MMC_CAP_4_BIT_DATA	(1 << 0) /* Can do 4-bit data transfers */
 #define MMC_CAP_8_BIT_DATA	(1 << 1) /* Can do 8-bit data transfers */
 	enum mmc_card_mode mode;
+	struct mmc_ios ios;	/* Current state of the host */
 };
 
 #endif /* DEV_MMC_BRIDGE_H */

==== //depot/projects/arm/src/sys/dev/mmc/mmc.c#3 (text+ko) ====

@@ -36,6 +36,9 @@
 #include <sys/bus.h>
 
 #include <dev/mmc/mmcreg.h>
+#include <dev/mmc/mmcbrvar.h>
+#include "mmcbr_if.h"
+#include "mmcbus_if.h"
 
 struct mmc_softc {
 	device_t dev;
@@ -90,12 +93,109 @@
 	return (EBUSY);	/* XXX */
 }
 
+static int
+mmcbr_update_ios(device_t dev)
+{
+	return (MMCBR_UPDATE_IOS(device_get_parent(dev), dev));
+}
+
+static void
+mmc_rescan_cards(struct mmc_softc *sc)
+{
+	/* XXX: Look at the children and see if they respond to status */
+}
+
+static void
+mmc_power_up(struct mmc_softc *sc)
+{
+	device_t dev;
+
+	dev = sc->dev;
+	mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev)));
+	mmcbr_set_bus_mode(dev, opendrain);
+	mmcbr_set_chip_select(dev, cs_dontcare);
+	mmcbr_set_bus_width(dev, bus_width_1);
+	mmcbr_set_power_mode(dev, power_up);
+	mmcbr_set_clock(dev, 0);
+	mmcbr_update_ios(dev);
+
+	// delay 1ms ?
+
+	mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev));
+	mmcbr_set_power_mode(dev, power_on);
+	mmcbr_update_ios(dev);
+
+	// delay 2ms ?
+}
+
+static void
+mmc_go_discovery(struct mmc_softc *sc)
+{
+	uint32_t ocr;
+	device_t dev;
+
+	dev = sc->dev;
+	if (mmcbr_get_power_mode(dev) != power_on) {
+		// First, try SD modes
+		mmcbr_set_mode(dev, mode_sd);
+		mmc_power_up(sc);
+		mmc_idle_cards(sc);
+		if (mmc_send_app_op_cond(sc, 0, &ocr)) {
+			// Failed, try MMC
+			mmcbr_set_mode(dev, mode_mmc);
+			if (mmc_send_op_cond(sc, 0, &ocr))
+				return;	// Failed both, punt! XXX power down?
+		}
+		mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
+		if (mmcbr_get_ocr(dev) != 0)
+			mmc_idle_cards(sc);
+	} else {
+		mmcbr_set_bus_mode(dev, opendrain);
+		mmcbr_set_clock(dev, mmcbr_get_f_min(dev));
+		mmcbr_update_ios(dev);
+		// XXX recompute vdd based on new cards?
+	}
+	/*
+	 * Make sure that we have a mutually agreeable voltage to at least
+	 * one card on the bus.
+	 */
+	if (mmcbr_get_ocr(dev) == 0)
+		return;
+	/* XXX Linux re-sends op_cond command here */
+	mmc_discover_cards(sc);
+
+	mmcbr_set_bus_mode(dev, pushpull);
+	mmcbr_update_ios(dev);
+	mmc_read_csds(sc);
+	if (mmcbr_get_mode(dev) == mode_sd)
+		mmc_read_scrs(sc);
+}
+
 static void
+mmc_scan(struct mmc_softc *sc)
+{
+	device_t dev;
+
+	dev = sc->dev;
+	mmc_aquire_bus(sc);
+
+	if (mmcbr_get_power_mode(dev) == power_on)
+		mmc_rescan_cards(sc);
+	mmc_go_discovery(sc);
+	mmcbr_set_clock(dev, mmc_calculate_clock(sc));
+	mmcbr_update_ios(dev);
+
+	mmc_release_bus(sc);
+	// XXX probe/attach/detach children?
+}
+
+static void
 mmc_delayed_attach(void *xsc)
 {
 	struct mmc_softc *sc = xsc;
 	
 	device_printf(sc->dev, "insert mmc/sd probe code here\n");
+	mmc_scan(sc);
 	config_intrhook_disestablish(&sc->config_intrhook);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609252258.k8PMwKRc029099>