mmc.c revision 183446
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.
24170002Simp *
25170002Simp * Portions of this software may have been developed with reference to
26170002Simp * the SD Simplified Specification.  The following disclaimer may apply:
27170002Simp *
28170002Simp * The following conditions apply to the release of the simplified
29170002Simp * specification ("Simplified Specification") by the SD Card Association and
30170002Simp * the SD Group. The Simplified Specification is a subset of the complete SD
31170002Simp * Specification which is owned by the SD Card Association and the SD
32170002Simp * Group. This Simplified Specification is provided on a non-confidential
33170002Simp * basis subject to the disclaimers below. Any implementation of the
34170002Simp * Simplified Specification may require a license from the SD Card
35170002Simp * Association, SD Group, SD-3C LLC or other third parties.
36170002Simp *
37170002Simp * Disclaimers:
38170002Simp *
39170002Simp * The information contained in the Simplified Specification is presented only
40170002Simp * as a standard specification for SD Cards and SD Host/Ancillary products and
41170002Simp * is provided "AS-IS" without any representations or warranties of any
42170002Simp * kind. No responsibility is assumed by the SD Group, SD-3C LLC or the SD
43170002Simp * Card Association for any damages, any infringements of patents or other
44170002Simp * right of the SD Group, SD-3C LLC, the SD Card Association or any third
45170002Simp * parties, which may result from its use. No license is granted by
46170002Simp * implication, estoppel or otherwise under any patent or other rights of the
47170002Simp * SD Group, SD-3C LLC, the SD Card Association or any third party. Nothing
48170002Simp * herein shall be construed as an obligation by the SD Group, the SD-3C LLC
49170002Simp * or the SD Card Association to disclose or distribute any technical
50170002Simp * information, know-how or other confidential information to any third party.
51163516Simp */
52163516Simp
53163516Simp#include <sys/cdefs.h>
54163516Simp__FBSDID("$FreeBSD: head/sys/dev/mmc/mmc.c 183446 2008-09-28 22:27:29Z imp $");
55163516Simp
56163516Simp#include <sys/param.h>
57163516Simp#include <sys/systm.h>
58163516Simp#include <sys/kernel.h>
59163516Simp#include <sys/malloc.h>
60163516Simp#include <sys/lock.h>
61163516Simp#include <sys/module.h>
62163516Simp#include <sys/mutex.h>
63163516Simp#include <sys/bus.h>
64163516Simp
65163516Simp#include <dev/mmc/mmcreg.h>
66163516Simp#include <dev/mmc/mmcbrvar.h>
67163516Simp#include <dev/mmc/mmcvar.h>
68163516Simp#include "mmcbr_if.h"
69163516Simp#include "mmcbus_if.h"
70163516Simp
71163516Simpstruct mmc_softc {
72163516Simp	device_t dev;
73163516Simp	struct mtx sc_mtx;
74163516Simp	struct intr_config_hook config_intrhook;
75163516Simp	device_t owner;
76163516Simp	uint32_t last_rca;
77163516Simp};
78163516Simp
79163516Simp/*
80163516Simp * Per-card data
81163516Simp */
82163516Simpstruct mmc_ivars {
83163516Simp	uint32_t raw_cid[4];	/* Raw bits of the CID */
84163516Simp	uint32_t raw_csd[4];	/* Raw bits of the CSD */
85163516Simp	uint16_t rca;
86163516Simp	enum mmc_card_mode mode;
87163516Simp	struct mmc_cid cid;	/* cid decoded */
88163516Simp	struct mmc_csd csd;	/* csd decoded */
89163516Simp};
90163516Simp
91163516Simp#define CMD_RETRIES	3
92163516Simp
93163516Simp/* bus entry points */
94163516Simpstatic int mmc_probe(device_t dev);
95163516Simpstatic int mmc_attach(device_t dev);
96163516Simpstatic int mmc_detach(device_t dev);
97163516Simp
98163516Simp#define MMC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
99163516Simp#define	MMC_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
100183444Simp#define MMC_LOCK_INIT(_sc)					\
101183444Simp	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
102163516Simp	    "mmc", MTX_DEF)
103163516Simp#define MMC_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
104163516Simp#define MMC_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
105163516Simp#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
106163516Simp
107163516Simpstatic void mmc_delayed_attach(void *);
108163516Simpstatic int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd,
109163516Simp    int retries);
110163516Simpstatic int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
111163516Simp    uint32_t arg, uint32_t flags, uint32_t *resp, int retries);
112163516Simp
113163516Simpstatic void
114163516Simpmmc_ms_delay(int ms)
115163516Simp{
116163516Simp	DELAY(1000 * ms);	/* XXX BAD */
117163516Simp}
118163516Simp
119163516Simpstatic int
120163516Simpmmc_probe(device_t dev)
121163516Simp{
122163516Simp
123183445Simp	device_set_desc(dev, "MMC/SD bus");
124163516Simp	return (0);
125163516Simp}
126163516Simp
127163516Simpstatic int
128163516Simpmmc_attach(device_t dev)
129163516Simp{
130163516Simp	struct mmc_softc *sc;
131163516Simp
132163516Simp	sc = device_get_softc(dev);
133163516Simp	sc->dev = dev;
134163516Simp	MMC_LOCK_INIT(sc);
135163516Simp
136163516Simp	/* We'll probe and attach our children later, but before / mount */
137163516Simp	sc->config_intrhook.ich_func = mmc_delayed_attach;
138163516Simp	sc->config_intrhook.ich_arg = sc;
139163516Simp	if (config_intrhook_establish(&sc->config_intrhook) != 0)
140163516Simp		device_printf(dev, "config_intrhook_establish failed\n");
141163516Simp	return (0);
142163516Simp}
143163516Simp
144163516Simpstatic int
145163516Simpmmc_detach(device_t dev)
146163516Simp{
147169567Simp	struct mmc_softc *sc = device_get_softc(dev);
148169567Simp	device_t *kids;
149169567Simp	int i, nkid;
150169567Simp
151169567Simp	/* kill children [ph33r].  -sorbo */
152169567Simp	if (device_get_children(sc->dev, &kids, &nkid) != 0)
153169567Simp		return 0;
154169567Simp	for (i = 0; i < nkid; i++) {
155169567Simp		device_t kid = kids[i];
156169567Simp		void *ivar = device_get_ivars(kid);
157169567Simp
158169567Simp		device_detach(kid);
159169567Simp		device_delete_child(sc->dev, kid);
160169567Simp		free(ivar, M_DEVBUF);
161169567Simp	}
162169567Simp	free(kids, M_TEMP);
163169567Simp
164169567Simp	MMC_LOCK_DESTROY(sc);
165169567Simp
166169567Simp	return 0;
167163516Simp}
168163516Simp
169163516Simpstatic int
170163516Simpmmc_acquire_bus(device_t busdev, device_t dev)
171163516Simp{
172163516Simp	struct mmc_softc *sc;
173163516Simp	int err;
174163516Simp	int rca;
175163516Simp
176163516Simp	err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), dev);
177163516Simp	if (err)
178163516Simp		return (err);
179163516Simp	sc = device_get_softc(busdev);
180163516Simp	MMC_LOCK(sc);
181163516Simp	if (sc->owner)
182163516Simp		panic("mmc: host bridge didn't seralize us.");
183163516Simp	sc->owner = dev;
184163516Simp	MMC_UNLOCK(sc);
185163516Simp
186163516Simp	if (busdev != dev) {
187163516Simp		// Keep track of the last rca that we've selected.  If
188163516Simp		// we're asked to do it again, don't.  We never unselect
189163516Simp		// unless the bus code itself wants the mmc bus.
190163516Simp		rca = mmc_get_rca(dev);
191163516Simp		if (sc->last_rca != rca) {
192163516Simp			mmc_wait_for_command(sc, MMC_SELECT_CARD, rca << 16,
193163516Simp			    MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES);
194163516Simp			sc->last_rca = rca;
195163516Simp		}
196163516Simp		// XXX should set bus width here?
197163516Simp	} else {
198163516Simp		// If there's a card selected, stand down.
199163516Simp		if (sc->last_rca != 0) {
200163516Simp			mmc_wait_for_command(sc, MMC_SELECT_CARD, 0,
201163516Simp			    MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES);
202163516Simp			sc->last_rca = 0;
203163516Simp		}
204163516Simp		// XXX should set bus width here?
205163516Simp	}
206163516Simp
207163516Simp	return (0);
208163516Simp}
209163516Simp
210163516Simpstatic int
211163516Simpmmc_release_bus(device_t busdev, device_t dev)
212163516Simp{
213163516Simp	struct mmc_softc *sc;
214163516Simp	int err;
215163516Simp
216163516Simp	sc = device_get_softc(busdev);
217163516Simp
218163516Simp	MMC_LOCK(sc);
219163516Simp	if (!sc->owner)
220163516Simp		panic("mmc: releasing unowned bus.");
221163516Simp	if (sc->owner != dev)
222163516Simp		panic("mmc: you don't own the bus.  game over.");
223163516Simp	MMC_UNLOCK(sc);
224163516Simp	err = MMCBR_RELEASE_HOST(device_get_parent(busdev), dev);
225163516Simp	if (err)
226163516Simp		return (err);
227163516Simp	MMC_LOCK(sc);
228163516Simp	sc->owner = NULL;
229163516Simp	MMC_UNLOCK(sc);
230163516Simp	return (0);
231163516Simp}
232163516Simp
233163516Simpstatic void
234163516Simpmmc_rescan_cards(struct mmc_softc *sc)
235163516Simp{
236163516Simp	/* XXX: Look at the children and see if they respond to status */
237163516Simp}
238163516Simp
239163516Simpstatic uint32_t
240163516Simpmmc_select_vdd(struct mmc_softc *sc, uint32_t ocr)
241163516Simp{
242183446Simp
243183446Simp	return ocr & MMC_OCR_VOLTAGE;
244163516Simp}
245163516Simp
246163516Simpstatic int
247163516Simpmmc_highest_voltage(uint32_t ocr)
248163516Simp{
249163516Simp	int i;
250163516Simp
251163516Simp	for (i = 30; i >= 0; i--)
252163516Simp		if (ocr & (1 << i))
253163516Simp			return i;
254163516Simp	return (-1);
255163516Simp}
256163516Simp
257163516Simpstatic void
258163516Simpmmc_wakeup(struct mmc_request *req)
259163516Simp{
260163516Simp	struct mmc_softc *sc;
261163516Simp
262163516Simp//	printf("Wakeup for req %p done_data %p\n", req, req->done_data);
263163516Simp	sc = (struct mmc_softc *)req->done_data;
264163516Simp	MMC_LOCK(sc);
265163516Simp	req->flags |= MMC_REQ_DONE;
266163516Simp	wakeup(req);
267163516Simp	MMC_UNLOCK(sc);
268163516Simp}
269163516Simp
270163516Simpstatic int
271163516Simpmmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req)
272163516Simp{
273163516Simp	int err;
274163516Simp
275163516Simp	req->done = mmc_wakeup;
276163516Simp	req->done_data = sc;
277163516Simp//	printf("Submitting request %p sc %p\n", req, sc);
278163516Simp	MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req);
279163516Simp	MMC_LOCK(sc);
280163516Simp	do {
281163516Simp		err = msleep(req, &sc->sc_mtx, PZERO | PCATCH, "mmcreq",
282163516Simp		    hz / 10);
283163516Simp	} while (!(req->flags & MMC_REQ_DONE) && err == EAGAIN);
284163516Simp//	printf("Request %p done with error %d\n", req, err);
285163516Simp	MMC_UNLOCK(sc);
286163516Simp	return (err);
287163516Simp}
288163516Simp
289163516Simpstatic int
290163516Simpmmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req)
291163516Simp{
292163516Simp	struct mmc_softc *sc = device_get_softc(brdev);
293163516Simp
294163516Simp	return mmc_wait_for_req(sc, req);
295163516Simp}
296163516Simp
297163516Simpstatic int
298163516Simpmmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries)
299163516Simp{
300163516Simp	struct mmc_request mreq;
301163516Simp
302163516Simp	memset(&mreq, 0, sizeof(mreq));
303163516Simp	memset(cmd->resp, 0, sizeof(cmd->resp));
304163516Simp	cmd->retries = retries;
305163516Simp	cmd->data = NULL;
306163516Simp	mreq.cmd = cmd;
307163516Simp//	printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg);
308163516Simp	mmc_wait_for_req(sc, &mreq);
309163516Simp	return (cmd->error);
310163516Simp}
311163516Simp
312163516Simpstatic int
313163516Simpmmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca,
314163516Simp    struct mmc_command *cmd, int retries)
315163516Simp{
316163516Simp	struct mmc_command appcmd;
317163516Simp	int err = MMC_ERR_NONE, i;
318163516Simp
319163516Simp	for (i = 0; i <= retries; i++) {
320163516Simp		appcmd.opcode = MMC_APP_CMD;
321163516Simp		appcmd.arg = rca << 16;
322163516Simp		appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
323163516Simp		mmc_wait_for_cmd(sc, &appcmd, 0);
324163516Simp		err = appcmd.error;
325163516Simp		if (err != MMC_ERR_NONE)
326163516Simp			continue;
327163516Simp		if (!(appcmd.resp[0] & R1_APP_CMD))
328163516Simp			return MMC_ERR_FAILED;
329163516Simp		mmc_wait_for_cmd(sc, cmd, 0);
330163516Simp		err = cmd->error;
331163516Simp		if (err == MMC_ERR_NONE)
332163516Simp			break;
333163516Simp	}
334163516Simp	return (err);
335163516Simp}
336163516Simp
337163516Simpstatic int
338163516Simpmmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
339163516Simp    uint32_t arg, uint32_t flags, uint32_t *resp, int retries)
340163516Simp{
341163516Simp	struct mmc_command cmd;
342163516Simp	int err;
343163516Simp
344163516Simp	memset(&cmd, 0, sizeof(cmd));
345163516Simp	cmd.opcode = opcode;
346163516Simp	cmd.arg = arg;
347163516Simp	cmd.flags = flags;
348163516Simp	err = mmc_wait_for_cmd(sc, &cmd, retries);
349163516Simp	if (err)
350163516Simp		return (err);
351163516Simp	if (cmd.error)
352163516Simp		return (cmd.error);
353163516Simp	if (resp) {
354163516Simp		if (flags & MMC_RSP_136)
355163516Simp			memcpy(resp, cmd.resp, 4 * sizeof(uint32_t));
356163516Simp		else
357163516Simp			*resp = cmd.resp[0];
358163516Simp	}
359163516Simp	return (0);
360163516Simp}
361163516Simp
362163516Simpstatic void
363163516Simpmmc_idle_cards(struct mmc_softc *sc)
364163516Simp{
365163516Simp	device_t dev;
366163516Simp	struct mmc_command cmd;
367163516Simp
368163516Simp	dev = sc->dev;
369163516Simp	mmcbr_set_chip_select(dev, cs_high);
370163516Simp	mmcbr_update_ios(dev);
371163516Simp	mmc_ms_delay(1);
372163516Simp
373163516Simp	memset(&cmd, 0, sizeof(cmd));
374163516Simp	cmd.opcode = MMC_GO_IDLE_STATE;
375163516Simp	cmd.arg = 0;
376163516Simp	cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
377163516Simp	mmc_wait_for_cmd(sc, &cmd, 0);
378163516Simp	mmc_ms_delay(1);
379163516Simp
380163516Simp	mmcbr_set_chip_select(dev, cs_dontcare);
381163516Simp	mmcbr_update_ios(dev);
382163516Simp	mmc_ms_delay(1);
383163516Simp}
384163516Simp
385163516Simpstatic int
386163516Simpmmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr)
387163516Simp{
388163516Simp	struct mmc_command cmd;
389163516Simp	int err = MMC_ERR_NONE, i;
390163516Simp
391163516Simp	memset(&cmd, 0, sizeof(cmd));
392163516Simp	cmd.opcode = ACMD_SD_SEND_OP_COND;
393163516Simp	cmd.arg = ocr;
394163516Simp	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
395163516Simp
396170337Simp	for (i = 0; i < 100; i++) {
397163516Simp		err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES);
398163516Simp		if (err != MMC_ERR_NONE)
399163516Simp			break;
400163516Simp		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0)
401163516Simp			break;
402163516Simp		err = MMC_ERR_TIMEOUT;
403163516Simp		mmc_ms_delay(10);
404163516Simp	}
405163516Simp	if (rocr && err == MMC_ERR_NONE)
406163516Simp		*rocr = cmd.resp[0];
407163516Simp	return err;
408163516Simp}
409163516Simp
410163516Simpstatic int
411163516Simpmmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr)
412163516Simp{
413163516Simp	struct mmc_command cmd;
414163516Simp	int err = MMC_ERR_NONE, i;
415163516Simp
416163516Simp	memset(&cmd, 0, sizeof(cmd));
417163516Simp	cmd.opcode = MMC_SEND_OP_COND;
418163516Simp	cmd.arg = ocr;
419163516Simp	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
420163516Simp
421163516Simp	for (i = 0; i < 100; i++) {
422163516Simp		err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
423163516Simp		if (err != MMC_ERR_NONE)
424163516Simp			break;
425163516Simp		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0)
426163516Simp			break;
427163516Simp		err = MMC_ERR_TIMEOUT;
428163516Simp		mmc_ms_delay(10);
429163516Simp	}
430163516Simp	if (rocr && err == MMC_ERR_NONE)
431163516Simp		*rocr = cmd.resp[0];
432163516Simp	return err;
433163516Simp}
434163516Simp
435163516Simpstatic void
436163516Simpmmc_power_up(struct mmc_softc *sc)
437163516Simp{
438163516Simp	device_t dev;
439163516Simp
440163516Simp	dev = sc->dev;
441163516Simp	mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev)));
442163516Simp	mmcbr_set_bus_mode(dev, opendrain);
443163516Simp	mmcbr_set_chip_select(dev, cs_dontcare);
444163516Simp	mmcbr_set_bus_width(dev, bus_width_1);
445163516Simp	mmcbr_set_power_mode(dev, power_up);
446163516Simp	mmcbr_set_clock(dev, 0);
447163516Simp	mmcbr_update_ios(dev);
448163516Simp	mmc_ms_delay(1);
449163516Simp
450163516Simp	mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev));
451163516Simp	mmcbr_set_power_mode(dev, power_on);
452163516Simp	mmcbr_update_ios(dev);
453163516Simp	mmc_ms_delay(2);
454163516Simp}
455163516Simp
456163516Simp// I wonder if the following is endian safe.
457163516Simpstatic uint32_t
458163516Simpmmc_get_bits(uint32_t *bits, int start, int size)
459163516Simp{
460163516Simp	const int i = 3 - (start / 32);
461163516Simp	const int shift = start & 31;
462163516Simp	uint32_t retval = bits[i] >> shift;
463163516Simp	if (size + shift > 32)
464163516Simp		retval |= bits[i - 1] << (32 - shift);
465163516Simp	return retval & ((1 << size) - 1);
466163516Simp}
467163516Simp
468163516Simpstatic void
469163516Simpmmc_decode_cid(int is_sd, uint32_t *raw_cid, struct mmc_cid *cid)
470163516Simp{
471163516Simp	int i;
472163516Simp
473163516Simp	memset(cid, 0, sizeof(*cid));
474163516Simp	if (is_sd) {
475163516Simp		/* There's no version info, so we take it on faith */
476163516Simp		cid->mid = mmc_get_bits(raw_cid, 120, 8);
477163516Simp		cid->oid = mmc_get_bits(raw_cid, 104, 16);
478163516Simp		for (i = 0; i < 5; i++)
479163516Simp			cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
480163516Simp		cid->prv = mmc_get_bits(raw_cid, 56, 8);
481163516Simp		cid->psn = mmc_get_bits(raw_cid, 24, 32);
482163516Simp		cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001;
483163516Simp		cid->mdt_month = mmc_get_bits(raw_cid, 8, 4);
484163516Simp	} else {
485163516Simp		// XXX write me
486163516Simp		panic("write mmc cid decoder");
487163516Simp	}
488163516Simp}
489163516Simp
490163516Simpstatic const int exp[8] = {
491163516Simp	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
492163516Simp};
493163516Simpstatic const int mant[16] = {
494163516Simp	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
495163516Simp};
496163516Simpstatic const int cur_min[8] = {
497163516Simp	500, 1000, 5000, 10000, 25000, 35000, 60000, 100000
498163516Simp};
499163516Simpstatic const int cur_max[8] = {
500163516Simp	1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000
501163516Simp};
502163516Simp
503163516Simpstatic void
504163516Simpmmc_decode_csd(int is_sd, uint32_t *raw_csd, struct mmc_csd *csd)
505163516Simp{
506163516Simp	int v;
507163516Simp	int m;
508163516Simp	int e;
509163516Simp
510163516Simp	memset(csd, 0, sizeof(*csd));
511163516Simp	if (is_sd) {
512163516Simp		csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2);
513163516Simp		if (v == 0) {
514163516Simp			m = mmc_get_bits(raw_csd, 115, 4);
515163516Simp			e = mmc_get_bits(raw_csd, 112, 3);
516163516Simp			csd->tacc = exp[e] * mant[m] + 9 / 10;
517163516Simp			csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
518163516Simp			m = mmc_get_bits(raw_csd, 99, 4);
519163516Simp			e = mmc_get_bits(raw_csd, 96, 3);
520163516Simp			csd->tran_speed = exp[e] * 10000 * mant[m];
521163516Simp			csd->ccc = mmc_get_bits(raw_csd, 84, 12);
522163516Simp			csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
523163516Simp			csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
524163516Simp			csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
525163516Simp			csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
526163516Simp			csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
527163516Simp			csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)];
528163516Simp			csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)];
529163516Simp			csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)];
530163516Simp			csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)];
531163516Simp			m = mmc_get_bits(raw_csd, 62, 12);
532163516Simp			e = mmc_get_bits(raw_csd, 47, 3);
533163516Simp			csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
534163516Simp			csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
535163516Simp			csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
536163516Simp			csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
537163516Simp			csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
538163516Simp			csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
539163516Simp			csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
540163516Simp			csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
541163516Simp		} else if (v == 1) {
542163516Simp			panic("Write SDHC CSD parser");
543163516Simp		} else
544163516Simp			panic("unknown SD CSD version");
545163516Simp	} else {
546163516Simp		panic("Write a MMC CSD parser");
547163516Simp	}
548163516Simp}
549163516Simp
550163516Simpstatic int
551163516Simpmmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid)
552163516Simp{
553163516Simp	struct mmc_command cmd;
554163516Simp	int err;
555163516Simp
556163516Simp	cmd.opcode = MMC_ALL_SEND_CID;
557163516Simp	cmd.arg = 0;
558163516Simp	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
559163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
560163516Simp	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
561163516Simp	return (err);
562163516Simp}
563163516Simp
564163516Simpstatic int
565163516Simpmmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcid)
566163516Simp{
567163516Simp	struct mmc_command cmd;
568163516Simp	int err;
569163516Simp
570163516Simp	cmd.opcode = MMC_SEND_CSD;
571163516Simp	cmd.arg = rca << 16;
572163516Simp	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
573163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
574163516Simp	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
575163516Simp	return (err);
576163516Simp}
577163516Simp
578163516Simpstatic int
579163516Simpmmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp)
580163516Simp{
581163516Simp	struct mmc_command cmd;
582163516Simp	int err;
583163516Simp
584163516Simp	cmd.opcode = SD_SEND_RELATIVE_ADDR;
585163516Simp	cmd.arg = 0;
586163516Simp	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
587163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
588163516Simp	*resp = cmd.resp[0];
589163516Simp	return (err);
590163516Simp}
591163516Simp
592163516Simpstatic void
593163516Simpmmc_discover_cards(struct mmc_softc *sc)
594163516Simp{
595163516Simp	struct mmc_ivars *ivar;
596163516Simp	int err;
597163516Simp	uint32_t resp;
598163516Simp	device_t child;
599163516Simp
600163516Simp	while (1) {
601163516Simp		ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, M_WAITOK);
602169567Simp		if (!ivar)
603169567Simp			return;
604163516Simp		err = mmc_all_send_cid(sc, ivar->raw_cid);
605163516Simp		if (err == MMC_ERR_TIMEOUT)
606163516Simp			break;
607163516Simp		if (err != MMC_ERR_NONE) {
608163516Simp			printf("Error reading CID %d\n", err);
609163516Simp			break;
610163516Simp		}
611163516Simp		if (mmcbr_get_mode(sc->dev) == mode_sd) {
612163516Simp			ivar->mode = mode_sd;
613163516Simp			mmc_decode_cid(1, ivar->raw_cid, &ivar->cid);
614163516Simp			mmc_send_relative_addr(sc, &resp);
615163516Simp			ivar->rca = resp >> 16;
616163516Simp			// RO check
617163516Simp			mmc_send_csd(sc, ivar->rca, ivar->raw_csd);
618163516Simp			mmc_decode_csd(1, ivar->raw_csd, &ivar->csd);
619169567Simp			printf("SD CARD: %lld bytes\n", (long long)
620169567Simp			    ivar->csd.capacity);
621163516Simp			child = device_add_child(sc->dev, NULL, -1);
622163516Simp			device_set_ivars(child, ivar);
623169567Simp			return;
624163516Simp		}
625163516Simp		panic("Write MMC card code here");
626163516Simp	}
627169567Simp	free(ivar, M_DEVBUF);
628163516Simp}
629163516Simp
630163516Simpstatic void
631163516Simpmmc_go_discovery(struct mmc_softc *sc)
632163516Simp{
633163516Simp	uint32_t ocr;
634163516Simp	device_t dev;
635163516Simp
636163516Simp	dev = sc->dev;
637163516Simp	if (mmcbr_get_power_mode(dev) != power_on) {
638163516Simp		// First, try SD modes
639163516Simp		mmcbr_set_mode(dev, mode_sd);
640163516Simp		mmc_power_up(sc);
641163516Simp		mmcbr_set_bus_mode(dev, pushpull);
642163516Simp		mmc_idle_cards(sc);
643163516Simp		if (mmc_send_app_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) {
644163516Simp			// Failed, try MMC
645163516Simp			mmcbr_set_mode(dev, mode_mmc);
646163516Simp			if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE)
647163516Simp				return;	// Failed both, punt! XXX power down?
648163516Simp		}
649163516Simp		mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
650163516Simp		if (mmcbr_get_ocr(dev) != 0)
651163516Simp			mmc_idle_cards(sc);
652163516Simp	} else {
653163516Simp		mmcbr_set_bus_mode(dev, opendrain);
654163516Simp		mmcbr_set_clock(dev, mmcbr_get_f_min(dev));
655163516Simp		mmcbr_update_ios(dev);
656163516Simp		// XXX recompute vdd based on new cards?
657163516Simp	}
658163516Simp	/*
659163516Simp	 * Make sure that we have a mutually agreeable voltage to at least
660163516Simp	 * one card on the bus.
661163516Simp	 */
662163516Simp	if (mmcbr_get_ocr(dev) == 0)
663163516Simp		return;
664163516Simp	/*
665163516Simp	 * Reselect the cards after we've idled them above.
666163516Simp	 */
667163516Simp	if (mmcbr_get_mode(dev) == mode_sd)
668163516Simp		mmc_send_app_op_cond(sc, mmcbr_get_ocr(dev), NULL);
669163516Simp	else
670163516Simp		mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL);
671163516Simp	mmc_discover_cards(sc);
672163516Simp
673163516Simp	mmcbr_set_bus_mode(dev, pushpull);
674163516Simp	mmcbr_update_ios(dev);
675163516Simp	bus_generic_attach(dev);
676163516Simp//	mmc_update_children_sysctl(dev);
677163516Simp}
678163516Simp
679163516Simpstatic int
680163516Simpmmc_calculate_clock(struct mmc_softc *sc)
681163516Simp{
682163516Simp	int max_dtr = 0;
683163516Simp	int nkid, i, f_min, f_max;
684163516Simp	device_t *kids;
685163516Simp
686163516Simp	f_min = mmcbr_get_f_min(sc->dev);
687163516Simp	f_max = mmcbr_get_f_max(sc->dev);
688163516Simp	max_dtr = f_max;
689163516Simp	if (device_get_children(sc->dev, &kids, &nkid) != 0)
690163516Simp		panic("can't get children");
691163516Simp	for (i = 0; i < nkid; i++)
692163516Simp		if (mmc_get_tran_speed(kids[i]) < max_dtr)
693163516Simp			max_dtr = mmc_get_tran_speed(kids[i]);
694163516Simp	free(kids, M_TEMP);
695163516Simp	device_printf(sc->dev, "setting transfer rate to %d.%03dMHz\n",
696163516Simp	    max_dtr / 1000000, (max_dtr / 1000) % 1000);
697163516Simp	return max_dtr;
698163516Simp}
699163516Simp
700163516Simpstatic void
701163516Simpmmc_scan(struct mmc_softc *sc)
702163516Simp{
703163516Simp	device_t dev;
704163516Simp
705163516Simp	dev = sc->dev;
706163516Simp	mmc_acquire_bus(dev, dev);
707163516Simp
708163516Simp	if (mmcbr_get_power_mode(dev) == power_on)
709163516Simp		mmc_rescan_cards(sc);
710163516Simp	mmc_go_discovery(sc);
711163516Simp	mmcbr_set_clock(dev, mmc_calculate_clock(sc));
712163516Simp	mmcbr_update_ios(dev);
713163516Simp
714163516Simp	mmc_release_bus(dev, dev);
715163516Simp	// XXX probe/attach/detach children?
716163516Simp}
717163516Simp
718163516Simpstatic int
719163516Simpmmc_read_ivar(device_t bus, device_t child, int which, u_char *result)
720163516Simp{
721163516Simp	struct mmc_ivars *ivar = device_get_ivars(child);
722163516Simp
723163516Simp	switch (which) {
724163516Simp	default:
725163516Simp		return (EINVAL);
726163516Simp	case MMC_IVAR_DSR_IMP:
727163516Simp		*(int *)result = ivar->csd.dsr_imp;
728163516Simp		break;
729163516Simp	case MMC_IVAR_MEDIA_SIZE:
730163516Simp		*(int *)result = ivar->csd.capacity;
731163516Simp		break;
732163516Simp	case MMC_IVAR_RCA:
733163516Simp		*(int *)result = ivar->rca;
734163516Simp		break;
735163516Simp	case MMC_IVAR_SECTOR_SIZE:
736163516Simp		*(int *)result = 512;
737163516Simp		break;
738163516Simp	case MMC_IVAR_TRAN_SPEED:
739163516Simp		*(int *)result = ivar->csd.tran_speed;
740163516Simp		break;
741163516Simp	}
742163516Simp	return (0);
743163516Simp}
744163516Simp
745163516Simpstatic int
746163516Simpmmc_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
747163516Simp{
748163516Simp	// None are writable ATM
749163516Simp	switch (which) {
750163516Simp	default:
751163516Simp		return (EINVAL);
752163516Simp	}
753163516Simp	return (0);
754163516Simp}
755163516Simp
756163516Simp
757163516Simpstatic void
758163516Simpmmc_delayed_attach(void *xsc)
759163516Simp{
760163516Simp	struct mmc_softc *sc = xsc;
761163516Simp
762163516Simp	mmc_scan(sc);
763163516Simp	config_intrhook_disestablish(&sc->config_intrhook);
764163516Simp}
765163516Simp
766163516Simpstatic device_method_t mmc_methods[] = {
767163516Simp	/* device_if */
768163516Simp	DEVMETHOD(device_probe, mmc_probe),
769163516Simp	DEVMETHOD(device_attach, mmc_attach),
770163516Simp	DEVMETHOD(device_detach, mmc_detach),
771163516Simp
772163516Simp	/* Bus interface */
773163516Simp	DEVMETHOD(bus_read_ivar, mmc_read_ivar),
774163516Simp	DEVMETHOD(bus_write_ivar, mmc_write_ivar),
775163516Simp
776163516Simp	/* MMC Bus interface */
777163516Simp	DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request),
778163516Simp	DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus),
779163516Simp	DEVMETHOD(mmcbus_release_bus, mmc_release_bus),
780163516Simp
781163516Simp	{0, 0},
782163516Simp};
783163516Simp
784163516Simpstatic driver_t mmc_driver = {
785163516Simp	"mmc",
786163516Simp	mmc_methods,
787163516Simp	sizeof(struct mmc_softc),
788163516Simp};
789163516Simpstatic devclass_t mmc_devclass;
790163516Simp
791163516Simp
792163516SimpDRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0);
793169567SimpDRIVER_MODULE(mmc, sdh, mmc_driver, mmc_devclass, 0, 0);
794