From owner-p4-projects@FreeBSD.ORG Mon Sep 25 22:58:21 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id BBCEC16A412; Mon, 25 Sep 2006 22:58:21 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8207616A403 for ; Mon, 25 Sep 2006 22:58:21 +0000 (UTC) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4BC6743D46 for ; Mon, 25 Sep 2006 22:58:21 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k8PMwL95029102 for ; Mon, 25 Sep 2006 22:58:21 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k8PMwKRc029099 for perforce@freebsd.org; Mon, 25 Sep 2006 22:58:20 GMT (envelope-from imp@freebsd.org) Date: Mon, 25 Sep 2006 22:58:20 GMT Message-Id: <200609252258.k8PMwKRc029099@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 106689 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Sep 2006 22:58:22 -0000 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 #include +#include +#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); }