mmc.c revision 163516
1163516Simp/*-
2163516Simp * Copyright (c) 2006 Bernd Walter.  All rights reserved.
3163516Simp * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
4163516Simp *
5163516Simp * Redistribution and use in source and binary forms, with or without
6163516Simp * modification, are permitted provided that the following conditions
7163516Simp * are met:
8163516Simp * 1. Redistributions of source code must retain the above copyright
9163516Simp *    notice, this list of conditions and the following disclaimer.
10163516Simp * 2. Redistributions in binary form must reproduce the above copyright
11163516Simp *    notice, this list of conditions and the following disclaimer in the
12163516Simp *    documentation and/or other materials provided with the distribution.
13163516Simp *
14163516Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15163516Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16163516Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17163516Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18163516Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19163516Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20163516Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21163516Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22163516Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23163516Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24163516Simp */
25163516Simp
26163516Simp#include <sys/cdefs.h>
27163516Simp__FBSDID("$FreeBSD: head/sys/dev/mmc/mmc.c 163516 2006-10-20 06:39:59Z imp $");
28163516Simp
29163516Simp#include <sys/param.h>
30163516Simp#include <sys/systm.h>
31163516Simp#include <sys/kernel.h>
32163516Simp#include <sys/malloc.h>
33163516Simp#include <sys/lock.h>
34163516Simp#include <sys/module.h>
35163516Simp#include <sys/mutex.h>
36163516Simp#include <sys/bus.h>
37163516Simp
38163516Simp#include <dev/mmc/mmcreg.h>
39163516Simp#include <dev/mmc/mmcbrvar.h>
40163516Simp#include <dev/mmc/mmcvar.h>
41163516Simp#include "mmcbr_if.h"
42163516Simp#include "mmcbus_if.h"
43163516Simp
44163516Simpstruct mmc_softc {
45163516Simp	device_t dev;
46163516Simp	struct mtx sc_mtx;
47163516Simp	struct intr_config_hook config_intrhook;
48163516Simp	device_t owner;
49163516Simp	uint32_t last_rca;
50163516Simp};
51163516Simp
52163516Simp/*
53163516Simp * Per-card data
54163516Simp */
55163516Simpstruct mmc_ivars {
56163516Simp	uint32_t raw_cid[4];	/* Raw bits of the CID */
57163516Simp	uint32_t raw_csd[4];	/* Raw bits of the CSD */
58163516Simp	uint16_t rca;
59163516Simp	enum mmc_card_mode mode;
60163516Simp	struct mmc_cid cid;	/* cid decoded */
61163516Simp	struct mmc_csd csd;	/* csd decoded */
62163516Simp};
63163516Simp
64163516Simp#define CMD_RETRIES	3
65163516Simp
66163516Simp/* bus entry points */
67163516Simpstatic int mmc_probe(device_t dev);
68163516Simpstatic int mmc_attach(device_t dev);
69163516Simpstatic int mmc_detach(device_t dev);
70163516Simp
71163516Simp#define MMC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
72163516Simp#define	MMC_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
73163516Simp#define MMC_LOCK_INIT(_sc) \
74163516Simp	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
75163516Simp	    "mmc", MTX_DEF)
76163516Simp#define MMC_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
77163516Simp#define MMC_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
78163516Simp#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
79163516Simp
80163516Simpstatic void mmc_delayed_attach(void *);
81163516Simpstatic int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd,
82163516Simp    int retries);
83163516Simpstatic int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
84163516Simp    uint32_t arg, uint32_t flags, uint32_t *resp, int retries);
85163516Simp
86163516Simpstatic void
87163516Simpmmc_ms_delay(int ms)
88163516Simp{
89163516Simp	DELAY(1000 * ms);	/* XXX BAD */
90163516Simp}
91163516Simp
92163516Simpstatic int
93163516Simpmmc_probe(device_t dev)
94163516Simp{
95163516Simp
96163516Simp	device_set_desc(dev, "mmc/sd bus");
97163516Simp	return (0);
98163516Simp}
99163516Simp
100163516Simpstatic int
101163516Simpmmc_attach(device_t dev)
102163516Simp{
103163516Simp	struct mmc_softc *sc;
104163516Simp
105163516Simp	sc = device_get_softc(dev);
106163516Simp	sc->dev = dev;
107163516Simp	MMC_LOCK_INIT(sc);
108163516Simp
109163516Simp	/* We'll probe and attach our children later, but before / mount */
110163516Simp	sc->config_intrhook.ich_func = mmc_delayed_attach;
111163516Simp	sc->config_intrhook.ich_arg = sc;
112163516Simp	if (config_intrhook_establish(&sc->config_intrhook) != 0)
113163516Simp		device_printf(dev, "config_intrhook_establish failed\n");
114163516Simp	return (0);
115163516Simp}
116163516Simp
117163516Simpstatic int
118163516Simpmmc_detach(device_t dev)
119163516Simp{
120163516Simp	return (EBUSY);	/* XXX */
121163516Simp}
122163516Simp
123163516Simpstatic int
124163516Simpmmc_acquire_bus(device_t busdev, device_t dev)
125163516Simp{
126163516Simp	struct mmc_softc *sc;
127163516Simp	int err;
128163516Simp	int rca;
129163516Simp
130163516Simp	err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), dev);
131163516Simp	if (err)
132163516Simp		return (err);
133163516Simp	sc = device_get_softc(busdev);
134163516Simp	MMC_LOCK(sc);
135163516Simp	if (sc->owner)
136163516Simp		panic("mmc: host bridge didn't seralize us.");
137163516Simp	sc->owner = dev;
138163516Simp	MMC_UNLOCK(sc);
139163516Simp
140163516Simp	if (busdev != dev) {
141163516Simp		// Keep track of the last rca that we've selected.  If
142163516Simp		// we're asked to do it again, don't.  We never unselect
143163516Simp		// unless the bus code itself wants the mmc bus.
144163516Simp		rca = mmc_get_rca(dev);
145163516Simp		if (sc->last_rca != rca) {
146163516Simp			mmc_wait_for_command(sc, MMC_SELECT_CARD, rca << 16,
147163516Simp			    MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES);
148163516Simp			sc->last_rca = rca;
149163516Simp		}
150163516Simp		// XXX should set bus width here?
151163516Simp	} else {
152163516Simp		// If there's a card selected, stand down.
153163516Simp		if (sc->last_rca != 0) {
154163516Simp			mmc_wait_for_command(sc, MMC_SELECT_CARD, 0,
155163516Simp			    MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES);
156163516Simp			sc->last_rca = 0;
157163516Simp		}
158163516Simp		// XXX should set bus width here?
159163516Simp	}
160163516Simp
161163516Simp	return (0);
162163516Simp}
163163516Simp
164163516Simpstatic int
165163516Simpmmc_release_bus(device_t busdev, device_t dev)
166163516Simp{
167163516Simp	struct mmc_softc *sc;
168163516Simp	int err;
169163516Simp
170163516Simp	sc = device_get_softc(busdev);
171163516Simp
172163516Simp	MMC_LOCK(sc);
173163516Simp	if (!sc->owner)
174163516Simp		panic("mmc: releasing unowned bus.");
175163516Simp	if (sc->owner != dev)
176163516Simp		panic("mmc: you don't own the bus.  game over.");
177163516Simp	MMC_UNLOCK(sc);
178163516Simp	err = MMCBR_RELEASE_HOST(device_get_parent(busdev), dev);
179163516Simp	if (err)
180163516Simp		return (err);
181163516Simp	MMC_LOCK(sc);
182163516Simp	sc->owner = NULL;
183163516Simp	MMC_UNLOCK(sc);
184163516Simp	return (0);
185163516Simp}
186163516Simp
187163516Simpstatic void
188163516Simpmmc_rescan_cards(struct mmc_softc *sc)
189163516Simp{
190163516Simp	/* XXX: Look at the children and see if they respond to status */
191163516Simp}
192163516Simp
193163516Simpstatic uint32_t
194163516Simpmmc_select_vdd(struct mmc_softc *sc, uint32_t ocr)
195163516Simp{
196163516Simp    // XXX
197163516Simp	return ocr;
198163516Simp}
199163516Simp
200163516Simpstatic int
201163516Simpmmc_highest_voltage(uint32_t ocr)
202163516Simp{
203163516Simp	int i;
204163516Simp
205163516Simp	for (i = 30; i >= 0; i--)
206163516Simp		if (ocr & (1 << i))
207163516Simp			return i;
208163516Simp	return (-1);
209163516Simp}
210163516Simp
211163516Simpstatic void
212163516Simpmmc_wakeup(struct mmc_request *req)
213163516Simp{
214163516Simp	struct mmc_softc *sc;
215163516Simp
216163516Simp//	printf("Wakeup for req %p done_data %p\n", req, req->done_data);
217163516Simp	sc = (struct mmc_softc *)req->done_data;
218163516Simp	MMC_LOCK(sc);
219163516Simp	req->flags |= MMC_REQ_DONE;
220163516Simp	wakeup(req);
221163516Simp	MMC_UNLOCK(sc);
222163516Simp}
223163516Simp
224163516Simpstatic int
225163516Simpmmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req)
226163516Simp{
227163516Simp	int err;
228163516Simp
229163516Simp	req->done = mmc_wakeup;
230163516Simp	req->done_data = sc;
231163516Simp//	printf("Submitting request %p sc %p\n", req, sc);
232163516Simp	MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req);
233163516Simp	MMC_LOCK(sc);
234163516Simp	do {
235163516Simp		err = msleep(req, &sc->sc_mtx, PZERO | PCATCH, "mmcreq",
236163516Simp		    hz / 10);
237163516Simp	} while (!(req->flags & MMC_REQ_DONE) && err == EAGAIN);
238163516Simp//	printf("Request %p done with error %d\n", req, err);
239163516Simp	MMC_UNLOCK(sc);
240163516Simp	return (err);
241163516Simp}
242163516Simp
243163516Simpstatic int
244163516Simpmmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req)
245163516Simp{
246163516Simp	struct mmc_softc *sc = device_get_softc(brdev);
247163516Simp
248163516Simp	return mmc_wait_for_req(sc, req);
249163516Simp}
250163516Simp
251163516Simpstatic int
252163516Simpmmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries)
253163516Simp{
254163516Simp	struct mmc_request mreq;
255163516Simp
256163516Simp	memset(&mreq, 0, sizeof(mreq));
257163516Simp	memset(cmd->resp, 0, sizeof(cmd->resp));
258163516Simp	cmd->retries = retries;
259163516Simp	cmd->data = NULL;
260163516Simp	mreq.cmd = cmd;
261163516Simp//	printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg);
262163516Simp	mmc_wait_for_req(sc, &mreq);
263163516Simp	return (cmd->error);
264163516Simp}
265163516Simp
266163516Simpstatic int
267163516Simpmmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca,
268163516Simp    struct mmc_command *cmd, int retries)
269163516Simp{
270163516Simp	struct mmc_command appcmd;
271163516Simp	int err = MMC_ERR_NONE, i;
272163516Simp
273163516Simp	for (i = 0; i <= retries; i++) {
274163516Simp		appcmd.opcode = MMC_APP_CMD;
275163516Simp		appcmd.arg = rca << 16;
276163516Simp		appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
277163516Simp		mmc_wait_for_cmd(sc, &appcmd, 0);
278163516Simp		err = appcmd.error;
279163516Simp		if (err != MMC_ERR_NONE)
280163516Simp			continue;
281163516Simp		if (!(appcmd.resp[0] & R1_APP_CMD))
282163516Simp			return MMC_ERR_FAILED;
283163516Simp		mmc_wait_for_cmd(sc, cmd, 0);
284163516Simp		err = cmd->error;
285163516Simp		if (err == MMC_ERR_NONE)
286163516Simp			break;
287163516Simp	}
288163516Simp	return (err);
289163516Simp}
290163516Simp
291163516Simpstatic int
292163516Simpmmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
293163516Simp    uint32_t arg, uint32_t flags, uint32_t *resp, int retries)
294163516Simp{
295163516Simp	struct mmc_command cmd;
296163516Simp	int err;
297163516Simp
298163516Simp	memset(&cmd, 0, sizeof(cmd));
299163516Simp	cmd.opcode = opcode;
300163516Simp	cmd.arg = arg;
301163516Simp	cmd.flags = flags;
302163516Simp	err = mmc_wait_for_cmd(sc, &cmd, retries);
303163516Simp	if (err)
304163516Simp		return (err);
305163516Simp	if (cmd.error)
306163516Simp		return (cmd.error);
307163516Simp	if (resp) {
308163516Simp		if (flags & MMC_RSP_136)
309163516Simp			memcpy(resp, cmd.resp, 4 * sizeof(uint32_t));
310163516Simp		else
311163516Simp			*resp = cmd.resp[0];
312163516Simp	}
313163516Simp	return (0);
314163516Simp}
315163516Simp
316163516Simpstatic void
317163516Simpmmc_idle_cards(struct mmc_softc *sc)
318163516Simp{
319163516Simp	device_t dev;
320163516Simp	struct mmc_command cmd;
321163516Simp
322163516Simp	dev = sc->dev;
323163516Simp	mmcbr_set_chip_select(dev, cs_high);
324163516Simp	mmcbr_update_ios(dev);
325163516Simp	mmc_ms_delay(1);
326163516Simp
327163516Simp	memset(&cmd, 0, sizeof(cmd));
328163516Simp	cmd.opcode = MMC_GO_IDLE_STATE;
329163516Simp	cmd.arg = 0;
330163516Simp	cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
331163516Simp	mmc_wait_for_cmd(sc, &cmd, 0);
332163516Simp	mmc_ms_delay(1);
333163516Simp
334163516Simp	mmcbr_set_chip_select(dev, cs_dontcare);
335163516Simp	mmcbr_update_ios(dev);
336163516Simp	mmc_ms_delay(1);
337163516Simp}
338163516Simp
339163516Simpstatic int
340163516Simpmmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr)
341163516Simp{
342163516Simp	struct mmc_command cmd;
343163516Simp	int err = MMC_ERR_NONE, i;
344163516Simp
345163516Simp	memset(&cmd, 0, sizeof(cmd));
346163516Simp	cmd.opcode = ACMD_SD_SEND_OP_COND;
347163516Simp	cmd.arg = ocr;
348163516Simp	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
349163516Simp
350163516Simp	for (i = 0; i < 10; i++) {
351163516Simp		err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES);
352163516Simp		if (err != MMC_ERR_NONE)
353163516Simp			break;
354163516Simp		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0)
355163516Simp			break;
356163516Simp		err = MMC_ERR_TIMEOUT;
357163516Simp		mmc_ms_delay(10);
358163516Simp	}
359163516Simp	if (rocr && err == MMC_ERR_NONE)
360163516Simp		*rocr = cmd.resp[0];
361163516Simp	return err;
362163516Simp}
363163516Simp
364163516Simpstatic int
365163516Simpmmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr)
366163516Simp{
367163516Simp	struct mmc_command cmd;
368163516Simp	int err = MMC_ERR_NONE, i;
369163516Simp
370163516Simp	memset(&cmd, 0, sizeof(cmd));
371163516Simp	cmd.opcode = MMC_SEND_OP_COND;
372163516Simp	cmd.arg = ocr;
373163516Simp	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
374163516Simp
375163516Simp	for (i = 0; i < 100; i++) {
376163516Simp		err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
377163516Simp		if (err != MMC_ERR_NONE)
378163516Simp			break;
379163516Simp		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0)
380163516Simp			break;
381163516Simp		err = MMC_ERR_TIMEOUT;
382163516Simp		mmc_ms_delay(10);
383163516Simp	}
384163516Simp	if (rocr && err == MMC_ERR_NONE)
385163516Simp		*rocr = cmd.resp[0];
386163516Simp	return err;
387163516Simp}
388163516Simp
389163516Simpstatic void
390163516Simpmmc_power_up(struct mmc_softc *sc)
391163516Simp{
392163516Simp	device_t dev;
393163516Simp
394163516Simp	dev = sc->dev;
395163516Simp	mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev)));
396163516Simp	mmcbr_set_bus_mode(dev, opendrain);
397163516Simp	mmcbr_set_chip_select(dev, cs_dontcare);
398163516Simp	mmcbr_set_bus_width(dev, bus_width_1);
399163516Simp	mmcbr_set_power_mode(dev, power_up);
400163516Simp	mmcbr_set_clock(dev, 0);
401163516Simp	mmcbr_update_ios(dev);
402163516Simp	mmc_ms_delay(1);
403163516Simp
404163516Simp	mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev));
405163516Simp	mmcbr_set_power_mode(dev, power_on);
406163516Simp	mmcbr_update_ios(dev);
407163516Simp	mmc_ms_delay(2);
408163516Simp}
409163516Simp
410163516Simp// I wonder if the following is endian safe.
411163516Simpstatic uint32_t
412163516Simpmmc_get_bits(uint32_t *bits, int start, int size)
413163516Simp{
414163516Simp	const int i = 3 - (start / 32);
415163516Simp	const int shift = start & 31;
416163516Simp	uint32_t retval = bits[i] >> shift;
417163516Simp	if (size + shift > 32)
418163516Simp		retval |= bits[i - 1] << (32 - shift);
419163516Simp	return retval & ((1 << size) - 1);
420163516Simp}
421163516Simp
422163516Simpstatic void
423163516Simpmmc_decode_cid(int is_sd, uint32_t *raw_cid, struct mmc_cid *cid)
424163516Simp{
425163516Simp	int i;
426163516Simp
427163516Simp	memset(cid, 0, sizeof(*cid));
428163516Simp	if (is_sd) {
429163516Simp		/* There's no version info, so we take it on faith */
430163516Simp		cid->mid = mmc_get_bits(raw_cid, 120, 8);
431163516Simp		cid->oid = mmc_get_bits(raw_cid, 104, 16);
432163516Simp		for (i = 0; i < 5; i++)
433163516Simp			cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
434163516Simp		cid->prv = mmc_get_bits(raw_cid, 56, 8);
435163516Simp		cid->psn = mmc_get_bits(raw_cid, 24, 32);
436163516Simp		cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001;
437163516Simp		cid->mdt_month = mmc_get_bits(raw_cid, 8, 4);
438163516Simp	} else {
439163516Simp		// XXX write me
440163516Simp		panic("write mmc cid decoder");
441163516Simp	}
442163516Simp}
443163516Simp
444163516Simpstatic const int exp[8] = {
445163516Simp	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
446163516Simp};
447163516Simpstatic const int mant[16] = {
448163516Simp	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
449163516Simp};
450163516Simpstatic const int cur_min[8] = {
451163516Simp	500, 1000, 5000, 10000, 25000, 35000, 60000, 100000
452163516Simp};
453163516Simpstatic const int cur_max[8] = {
454163516Simp	1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000
455163516Simp};
456163516Simp
457163516Simpstatic void
458163516Simpmmc_decode_csd(int is_sd, uint32_t *raw_csd, struct mmc_csd *csd)
459163516Simp{
460163516Simp	int v;
461163516Simp	int m;
462163516Simp	int e;
463163516Simp
464163516Simp	memset(csd, 0, sizeof(*csd));
465163516Simp	if (is_sd) {
466163516Simp		csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2);
467163516Simp		if (v == 0) {
468163516Simp			m = mmc_get_bits(raw_csd, 115, 4);
469163516Simp			e = mmc_get_bits(raw_csd, 112, 3);
470163516Simp			csd->tacc = exp[e] * mant[m] + 9 / 10;
471163516Simp			csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
472163516Simp			m = mmc_get_bits(raw_csd, 99, 4);
473163516Simp			e = mmc_get_bits(raw_csd, 96, 3);
474163516Simp			csd->tran_speed = exp[e] * 10000 * mant[m];
475163516Simp			csd->ccc = mmc_get_bits(raw_csd, 84, 12);
476163516Simp			csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
477163516Simp			csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
478163516Simp			csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
479163516Simp			csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
480163516Simp			csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
481163516Simp			csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)];
482163516Simp			csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)];
483163516Simp			csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)];
484163516Simp			csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)];
485163516Simp			m = mmc_get_bits(raw_csd, 62, 12);
486163516Simp			e = mmc_get_bits(raw_csd, 47, 3);
487163516Simp			csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
488163516Simp			csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
489163516Simp			csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
490163516Simp			csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
491163516Simp			csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
492163516Simp			csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
493163516Simp			csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
494163516Simp			csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
495163516Simp		} else if (v == 1) {
496163516Simp			panic("Write SDHC CSD parser");
497163516Simp		} else
498163516Simp			panic("unknown SD CSD version");
499163516Simp	} else {
500163516Simp		panic("Write a MMC CSD parser");
501163516Simp	}
502163516Simp}
503163516Simp
504163516Simpstatic int
505163516Simpmmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid)
506163516Simp{
507163516Simp	struct mmc_command cmd;
508163516Simp	int err;
509163516Simp
510163516Simp	cmd.opcode = MMC_ALL_SEND_CID;
511163516Simp	cmd.arg = 0;
512163516Simp	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
513163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
514163516Simp	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
515163516Simp	return (err);
516163516Simp}
517163516Simp
518163516Simpstatic int
519163516Simpmmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcid)
520163516Simp{
521163516Simp	struct mmc_command cmd;
522163516Simp	int err;
523163516Simp
524163516Simp	cmd.opcode = MMC_SEND_CSD;
525163516Simp	cmd.arg = rca << 16;
526163516Simp	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
527163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
528163516Simp	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
529163516Simp	return (err);
530163516Simp}
531163516Simp
532163516Simpstatic int
533163516Simpmmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp)
534163516Simp{
535163516Simp	struct mmc_command cmd;
536163516Simp	int err;
537163516Simp
538163516Simp	cmd.opcode = SD_SEND_RELATIVE_ADDR;
539163516Simp	cmd.arg = 0;
540163516Simp	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
541163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
542163516Simp	*resp = cmd.resp[0];
543163516Simp	return (err);
544163516Simp}
545163516Simp
546163516Simpstatic void
547163516Simpmmc_discover_cards(struct mmc_softc *sc)
548163516Simp{
549163516Simp	struct mmc_ivars *ivar;
550163516Simp	int err;
551163516Simp	uint32_t resp;
552163516Simp	device_t child;
553163516Simp
554163516Simp	while (1) {
555163516Simp		ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, M_WAITOK);
556163516Simp		err = mmc_all_send_cid(sc, ivar->raw_cid);
557163516Simp		if (err == MMC_ERR_TIMEOUT)
558163516Simp			break;
559163516Simp		if (err != MMC_ERR_NONE) {
560163516Simp			printf("Error reading CID %d\n", err);
561163516Simp			break;
562163516Simp		}
563163516Simp		if (mmcbr_get_mode(sc->dev) == mode_sd) {
564163516Simp			ivar->mode = mode_sd;
565163516Simp			mmc_decode_cid(1, ivar->raw_cid, &ivar->cid);
566163516Simp			mmc_send_relative_addr(sc, &resp);
567163516Simp			ivar->rca = resp >> 16;
568163516Simp			// RO check
569163516Simp			mmc_send_csd(sc, ivar->rca, ivar->raw_csd);
570163516Simp			mmc_decode_csd(1, ivar->raw_csd, &ivar->csd);
571163516Simp			printf("SD CARD: %lld bytes\n", ivar->csd.capacity);
572163516Simp			child = device_add_child(sc->dev, NULL, -1);
573163516Simp			device_set_ivars(child, ivar);
574163516Simp			break;
575163516Simp		}
576163516Simp		panic("Write MMC card code here");
577163516Simp	}
578163516Simp}
579163516Simp
580163516Simpstatic void
581163516Simpmmc_go_discovery(struct mmc_softc *sc)
582163516Simp{
583163516Simp	uint32_t ocr;
584163516Simp	device_t dev;
585163516Simp
586163516Simp	dev = sc->dev;
587163516Simp	if (mmcbr_get_power_mode(dev) != power_on) {
588163516Simp		// First, try SD modes
589163516Simp		mmcbr_set_mode(dev, mode_sd);
590163516Simp		mmc_power_up(sc);
591163516Simp		mmcbr_set_bus_mode(dev, pushpull);
592163516Simp		mmc_idle_cards(sc);
593163516Simp		if (mmc_send_app_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) {
594163516Simp			// Failed, try MMC
595163516Simp			mmcbr_set_mode(dev, mode_mmc);
596163516Simp			if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE)
597163516Simp				return;	// Failed both, punt! XXX power down?
598163516Simp		}
599163516Simp		mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
600163516Simp		if (mmcbr_get_ocr(dev) != 0)
601163516Simp			mmc_idle_cards(sc);
602163516Simp	} else {
603163516Simp		mmcbr_set_bus_mode(dev, opendrain);
604163516Simp		mmcbr_set_clock(dev, mmcbr_get_f_min(dev));
605163516Simp		mmcbr_update_ios(dev);
606163516Simp		// XXX recompute vdd based on new cards?
607163516Simp	}
608163516Simp	/*
609163516Simp	 * Make sure that we have a mutually agreeable voltage to at least
610163516Simp	 * one card on the bus.
611163516Simp	 */
612163516Simp	if (mmcbr_get_ocr(dev) == 0)
613163516Simp		return;
614163516Simp	/*
615163516Simp	 * Reselect the cards after we've idled them above.
616163516Simp	 */
617163516Simp	if (mmcbr_get_mode(dev) == mode_sd)
618163516Simp		mmc_send_app_op_cond(sc, mmcbr_get_ocr(dev), NULL);
619163516Simp	else
620163516Simp		mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL);
621163516Simp	mmc_discover_cards(sc);
622163516Simp
623163516Simp	mmcbr_set_bus_mode(dev, pushpull);
624163516Simp	mmcbr_update_ios(dev);
625163516Simp	bus_generic_attach(dev);
626163516Simp//	mmc_update_children_sysctl(dev);
627163516Simp}
628163516Simp
629163516Simpstatic int
630163516Simpmmc_calculate_clock(struct mmc_softc *sc)
631163516Simp{
632163516Simp	int max_dtr = 0;
633163516Simp	int nkid, i, f_min, f_max;
634163516Simp	device_t *kids;
635163516Simp
636163516Simp	f_min = mmcbr_get_f_min(sc->dev);
637163516Simp	f_max = mmcbr_get_f_max(sc->dev);
638163516Simp	max_dtr = f_max;
639163516Simp	if (device_get_children(sc->dev, &kids, &nkid) != 0)
640163516Simp		panic("can't get children");
641163516Simp	for (i = 0; i < nkid; i++)
642163516Simp		if (mmc_get_tran_speed(kids[i]) < max_dtr)
643163516Simp			max_dtr = mmc_get_tran_speed(kids[i]);
644163516Simp	free(kids, M_TEMP);
645163516Simp	device_printf(sc->dev, "setting transfer rate to %d.%03dMHz\n",
646163516Simp	    max_dtr / 1000000, (max_dtr / 1000) % 1000);
647163516Simp	return max_dtr;
648163516Simp}
649163516Simp
650163516Simpstatic void
651163516Simpmmc_scan(struct mmc_softc *sc)
652163516Simp{
653163516Simp	device_t dev;
654163516Simp
655163516Simp	dev = sc->dev;
656163516Simp	mmc_acquire_bus(dev, dev);
657163516Simp
658163516Simp	if (mmcbr_get_power_mode(dev) == power_on)
659163516Simp		mmc_rescan_cards(sc);
660163516Simp	mmc_go_discovery(sc);
661163516Simp	mmcbr_set_clock(dev, mmc_calculate_clock(sc));
662163516Simp	mmcbr_update_ios(dev);
663163516Simp
664163516Simp	mmc_release_bus(dev, dev);
665163516Simp	// XXX probe/attach/detach children?
666163516Simp}
667163516Simp
668163516Simpstatic int
669163516Simpmmc_read_ivar(device_t bus, device_t child, int which, u_char *result)
670163516Simp{
671163516Simp	struct mmc_ivars *ivar = device_get_ivars(child);
672163516Simp
673163516Simp	switch (which) {
674163516Simp	default:
675163516Simp		return (EINVAL);
676163516Simp	case MMC_IVAR_DSR_IMP:
677163516Simp		*(int *)result = ivar->csd.dsr_imp;
678163516Simp		break;
679163516Simp	case MMC_IVAR_MEDIA_SIZE:
680163516Simp		*(int *)result = ivar->csd.capacity;
681163516Simp		break;
682163516Simp	case MMC_IVAR_MODE:
683163516Simp		*(int *)result = ivar->mode;
684163516Simp		break;
685163516Simp	case MMC_IVAR_RCA:
686163516Simp		*(int *)result = ivar->rca;
687163516Simp		break;
688163516Simp	case MMC_IVAR_SECTOR_SIZE:
689163516Simp		*(int *)result = 512;
690163516Simp		break;
691163516Simp	case MMC_IVAR_TRAN_SPEED:
692163516Simp		*(int *)result = ivar->csd.tran_speed;
693163516Simp		break;
694163516Simp	}
695163516Simp	return (0);
696163516Simp}
697163516Simp
698163516Simpstatic int
699163516Simpmmc_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
700163516Simp{
701163516Simp	// None are writable ATM
702163516Simp	switch (which) {
703163516Simp	default:
704163516Simp		return (EINVAL);
705163516Simp	}
706163516Simp	return (0);
707163516Simp}
708163516Simp
709163516Simp
710163516Simpstatic void
711163516Simpmmc_delayed_attach(void *xsc)
712163516Simp{
713163516Simp	struct mmc_softc *sc = xsc;
714163516Simp
715163516Simp	mmc_scan(sc);
716163516Simp	config_intrhook_disestablish(&sc->config_intrhook);
717163516Simp}
718163516Simp
719163516Simpstatic device_method_t mmc_methods[] = {
720163516Simp	/* device_if */
721163516Simp	DEVMETHOD(device_probe, mmc_probe),
722163516Simp	DEVMETHOD(device_attach, mmc_attach),
723163516Simp	DEVMETHOD(device_detach, mmc_detach),
724163516Simp
725163516Simp	/* Bus interface */
726163516Simp	DEVMETHOD(bus_read_ivar, mmc_read_ivar),
727163516Simp	DEVMETHOD(bus_write_ivar, mmc_write_ivar),
728163516Simp
729163516Simp	/* MMC Bus interface */
730163516Simp	DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request),
731163516Simp	DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus),
732163516Simp	DEVMETHOD(mmcbus_release_bus, mmc_release_bus),
733163516Simp
734163516Simp	{0, 0},
735163516Simp};
736163516Simp
737163516Simpstatic driver_t mmc_driver = {
738163516Simp	"mmc",
739163516Simp	mmc_methods,
740163516Simp	sizeof(struct mmc_softc),
741163516Simp};
742163516Simpstatic devclass_t mmc_devclass;
743163516Simp
744163516Simp
745163516SimpDRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0);
746