mmc.c revision 183453
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 183453 2008-09-29 01:32:21Z 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 */
89183447Simp	u_char read_only;	/* True when the device is read-only */
90163516Simp};
91163516Simp
92163516Simp#define CMD_RETRIES	3
93163516Simp
94163516Simp/* bus entry points */
95163516Simpstatic int mmc_probe(device_t dev);
96163516Simpstatic int mmc_attach(device_t dev);
97163516Simpstatic int mmc_detach(device_t dev);
98163516Simp
99163516Simp#define MMC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
100163516Simp#define	MMC_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
101183444Simp#define MMC_LOCK_INIT(_sc)					\
102183444Simp	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
103163516Simp	    "mmc", MTX_DEF)
104163516Simp#define MMC_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
105163516Simp#define MMC_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
106163516Simp#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
107163516Simp
108163516Simpstatic void mmc_delayed_attach(void *);
109183449Simpstatic void mmc_power_down(struct mmc_softc *sc);
110163516Simpstatic int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd,
111163516Simp    int retries);
112163516Simpstatic int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
113163516Simp    uint32_t arg, uint32_t flags, uint32_t *resp, int retries);
114163516Simp
115163516Simpstatic void
116163516Simpmmc_ms_delay(int ms)
117163516Simp{
118163516Simp	DELAY(1000 * ms);	/* XXX BAD */
119163516Simp}
120163516Simp
121163516Simpstatic int
122163516Simpmmc_probe(device_t dev)
123163516Simp{
124163516Simp
125183445Simp	device_set_desc(dev, "MMC/SD bus");
126163516Simp	return (0);
127163516Simp}
128163516Simp
129163516Simpstatic int
130163516Simpmmc_attach(device_t dev)
131163516Simp{
132163516Simp	struct mmc_softc *sc;
133163516Simp
134163516Simp	sc = device_get_softc(dev);
135163516Simp	sc->dev = dev;
136163516Simp	MMC_LOCK_INIT(sc);
137163516Simp
138163516Simp	/* We'll probe and attach our children later, but before / mount */
139163516Simp	sc->config_intrhook.ich_func = mmc_delayed_attach;
140163516Simp	sc->config_intrhook.ich_arg = sc;
141163516Simp	if (config_intrhook_establish(&sc->config_intrhook) != 0)
142163516Simp		device_printf(dev, "config_intrhook_establish failed\n");
143163516Simp	return (0);
144163516Simp}
145163516Simp
146163516Simpstatic int
147163516Simpmmc_detach(device_t dev)
148163516Simp{
149169567Simp	struct mmc_softc *sc = device_get_softc(dev);
150169567Simp	device_t *kids;
151169567Simp	int i, nkid;
152169567Simp
153169567Simp	/* kill children [ph33r].  -sorbo */
154169567Simp	if (device_get_children(sc->dev, &kids, &nkid) != 0)
155169567Simp		return 0;
156169567Simp	for (i = 0; i < nkid; i++) {
157169567Simp		device_t kid = kids[i];
158169567Simp		void *ivar = device_get_ivars(kid);
159169567Simp
160169567Simp		device_detach(kid);
161169567Simp		device_delete_child(sc->dev, kid);
162169567Simp		free(ivar, M_DEVBUF);
163169567Simp	}
164169567Simp	free(kids, M_TEMP);
165183449Simp	mmc_power_down(sc);
166169567Simp
167169567Simp	MMC_LOCK_DESTROY(sc);
168169567Simp
169169567Simp	return 0;
170163516Simp}
171163516Simp
172163516Simpstatic int
173163516Simpmmc_acquire_bus(device_t busdev, device_t dev)
174163516Simp{
175163516Simp	struct mmc_softc *sc;
176163516Simp	int err;
177163516Simp	int rca;
178163516Simp
179183452Simp	err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), busdev);
180163516Simp	if (err)
181163516Simp		return (err);
182163516Simp	sc = device_get_softc(busdev);
183163516Simp	MMC_LOCK(sc);
184163516Simp	if (sc->owner)
185163516Simp		panic("mmc: host bridge didn't seralize us.");
186163516Simp	sc->owner = dev;
187163516Simp	MMC_UNLOCK(sc);
188163516Simp
189163516Simp	if (busdev != dev) {
190183453Simp		/*
191183453Simp		 * Keep track of the last rca that we've selected.  If
192183453Simp		 * we're asked to do it again, don't.  We never
193183453Simp		 * unselect unless the bus code itself wants the mmc
194183453Simp		 * bus, and constantly reselecting causes problems.
195183453Simp		 */
196163516Simp		rca = mmc_get_rca(dev);
197163516Simp		if (sc->last_rca != rca) {
198163516Simp			mmc_wait_for_command(sc, MMC_SELECT_CARD, rca << 16,
199163516Simp			    MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES);
200163516Simp			sc->last_rca = rca;
201163516Simp		}
202183453Simp		/* XXX should set bus width here? */
203163516Simp	} else {
204183453Simp		/*
205183453Simp		 * If there's a card selected, stand down.
206183453Simp		 */
207163516Simp		if (sc->last_rca != 0) {
208163516Simp			mmc_wait_for_command(sc, MMC_SELECT_CARD, 0,
209163516Simp			    MMC_RSP_R1 | MMC_CMD_AC, NULL, CMD_RETRIES);
210163516Simp			sc->last_rca = 0;
211163516Simp		}
212183453Simp		/* XXX should set bus width here? */
213163516Simp	}
214163516Simp
215163516Simp	return (0);
216163516Simp}
217163516Simp
218163516Simpstatic int
219163516Simpmmc_release_bus(device_t busdev, device_t dev)
220163516Simp{
221163516Simp	struct mmc_softc *sc;
222163516Simp	int err;
223163516Simp
224163516Simp	sc = device_get_softc(busdev);
225163516Simp
226163516Simp	MMC_LOCK(sc);
227163516Simp	if (!sc->owner)
228163516Simp		panic("mmc: releasing unowned bus.");
229163516Simp	if (sc->owner != dev)
230163516Simp		panic("mmc: you don't own the bus.  game over.");
231163516Simp	MMC_UNLOCK(sc);
232183452Simp	err = MMCBR_RELEASE_HOST(device_get_parent(busdev), busdev);
233163516Simp	if (err)
234163516Simp		return (err);
235163516Simp	MMC_LOCK(sc);
236163516Simp	sc->owner = NULL;
237163516Simp	MMC_UNLOCK(sc);
238163516Simp	return (0);
239163516Simp}
240163516Simp
241163516Simpstatic void
242163516Simpmmc_rescan_cards(struct mmc_softc *sc)
243163516Simp{
244163516Simp	/* XXX: Look at the children and see if they respond to status */
245163516Simp}
246163516Simp
247163516Simpstatic uint32_t
248163516Simpmmc_select_vdd(struct mmc_softc *sc, uint32_t ocr)
249163516Simp{
250183446Simp
251183446Simp	return ocr & MMC_OCR_VOLTAGE;
252163516Simp}
253163516Simp
254163516Simpstatic int
255163516Simpmmc_highest_voltage(uint32_t ocr)
256163516Simp{
257163516Simp	int i;
258163516Simp
259163516Simp	for (i = 30; i >= 0; i--)
260163516Simp		if (ocr & (1 << i))
261163516Simp			return i;
262163516Simp	return (-1);
263163516Simp}
264163516Simp
265163516Simpstatic void
266163516Simpmmc_wakeup(struct mmc_request *req)
267163516Simp{
268163516Simp	struct mmc_softc *sc;
269163516Simp
270183453Simp/*	printf("Wakeup for req %p done_data %p\n", req, req->done_data); */
271163516Simp	sc = (struct mmc_softc *)req->done_data;
272163516Simp	MMC_LOCK(sc);
273163516Simp	req->flags |= MMC_REQ_DONE;
274163516Simp	wakeup(req);
275163516Simp	MMC_UNLOCK(sc);
276163516Simp}
277163516Simp
278163516Simpstatic int
279163516Simpmmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req)
280163516Simp{
281163516Simp	int err;
282163516Simp
283163516Simp	req->done = mmc_wakeup;
284163516Simp	req->done_data = sc;
285183453Simp/*	printf("Submitting request %p sc %p\n", req, sc); */
286163516Simp	MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req);
287163516Simp	MMC_LOCK(sc);
288163516Simp	do {
289163516Simp		err = msleep(req, &sc->sc_mtx, PZERO | PCATCH, "mmcreq",
290163516Simp		    hz / 10);
291163516Simp	} while (!(req->flags & MMC_REQ_DONE) && err == EAGAIN);
292183453Simp/*	printf("Request %p done with error %d\n", req, err); */
293163516Simp	MMC_UNLOCK(sc);
294163516Simp	return (err);
295163516Simp}
296163516Simp
297163516Simpstatic int
298163516Simpmmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req)
299163516Simp{
300163516Simp	struct mmc_softc *sc = device_get_softc(brdev);
301163516Simp
302163516Simp	return mmc_wait_for_req(sc, req);
303163516Simp}
304163516Simp
305163516Simpstatic int
306163516Simpmmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries)
307163516Simp{
308163516Simp	struct mmc_request mreq;
309163516Simp
310163516Simp	memset(&mreq, 0, sizeof(mreq));
311163516Simp	memset(cmd->resp, 0, sizeof(cmd->resp));
312163516Simp	cmd->retries = retries;
313163516Simp	cmd->data = NULL;
314163516Simp	mreq.cmd = cmd;
315183453Simp/*	printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg); */
316163516Simp	mmc_wait_for_req(sc, &mreq);
317163516Simp	return (cmd->error);
318163516Simp}
319163516Simp
320163516Simpstatic int
321163516Simpmmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca,
322163516Simp    struct mmc_command *cmd, int retries)
323163516Simp{
324163516Simp	struct mmc_command appcmd;
325163516Simp	int err = MMC_ERR_NONE, i;
326163516Simp
327163516Simp	for (i = 0; i <= retries; i++) {
328163516Simp		appcmd.opcode = MMC_APP_CMD;
329163516Simp		appcmd.arg = rca << 16;
330163516Simp		appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
331163516Simp		mmc_wait_for_cmd(sc, &appcmd, 0);
332163516Simp		err = appcmd.error;
333163516Simp		if (err != MMC_ERR_NONE)
334163516Simp			continue;
335163516Simp		if (!(appcmd.resp[0] & R1_APP_CMD))
336163516Simp			return MMC_ERR_FAILED;
337163516Simp		mmc_wait_for_cmd(sc, cmd, 0);
338163516Simp		err = cmd->error;
339163516Simp		if (err == MMC_ERR_NONE)
340163516Simp			break;
341163516Simp	}
342163516Simp	return (err);
343163516Simp}
344163516Simp
345163516Simpstatic int
346163516Simpmmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
347163516Simp    uint32_t arg, uint32_t flags, uint32_t *resp, int retries)
348163516Simp{
349163516Simp	struct mmc_command cmd;
350163516Simp	int err;
351163516Simp
352163516Simp	memset(&cmd, 0, sizeof(cmd));
353163516Simp	cmd.opcode = opcode;
354163516Simp	cmd.arg = arg;
355163516Simp	cmd.flags = flags;
356163516Simp	err = mmc_wait_for_cmd(sc, &cmd, retries);
357163516Simp	if (err)
358163516Simp		return (err);
359163516Simp	if (cmd.error)
360163516Simp		return (cmd.error);
361163516Simp	if (resp) {
362163516Simp		if (flags & MMC_RSP_136)
363163516Simp			memcpy(resp, cmd.resp, 4 * sizeof(uint32_t));
364163516Simp		else
365163516Simp			*resp = cmd.resp[0];
366163516Simp	}
367163516Simp	return (0);
368163516Simp}
369163516Simp
370163516Simpstatic void
371163516Simpmmc_idle_cards(struct mmc_softc *sc)
372163516Simp{
373163516Simp	device_t dev;
374163516Simp	struct mmc_command cmd;
375163516Simp
376163516Simp	dev = sc->dev;
377163516Simp	mmcbr_set_chip_select(dev, cs_high);
378163516Simp	mmcbr_update_ios(dev);
379163516Simp	mmc_ms_delay(1);
380163516Simp
381163516Simp	memset(&cmd, 0, sizeof(cmd));
382163516Simp	cmd.opcode = MMC_GO_IDLE_STATE;
383163516Simp	cmd.arg = 0;
384163516Simp	cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
385163516Simp	mmc_wait_for_cmd(sc, &cmd, 0);
386163516Simp	mmc_ms_delay(1);
387163516Simp
388163516Simp	mmcbr_set_chip_select(dev, cs_dontcare);
389163516Simp	mmcbr_update_ios(dev);
390163516Simp	mmc_ms_delay(1);
391163516Simp}
392163516Simp
393163516Simpstatic int
394163516Simpmmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr)
395163516Simp{
396163516Simp	struct mmc_command cmd;
397163516Simp	int err = MMC_ERR_NONE, i;
398163516Simp
399163516Simp	memset(&cmd, 0, sizeof(cmd));
400163516Simp	cmd.opcode = ACMD_SD_SEND_OP_COND;
401163516Simp	cmd.arg = ocr;
402163516Simp	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
403163516Simp
404170337Simp	for (i = 0; i < 100; i++) {
405163516Simp		err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES);
406163516Simp		if (err != MMC_ERR_NONE)
407163516Simp			break;
408163516Simp		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0)
409163516Simp			break;
410163516Simp		err = MMC_ERR_TIMEOUT;
411163516Simp		mmc_ms_delay(10);
412163516Simp	}
413163516Simp	if (rocr && err == MMC_ERR_NONE)
414163516Simp		*rocr = cmd.resp[0];
415163516Simp	return err;
416163516Simp}
417163516Simp
418163516Simpstatic int
419163516Simpmmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr)
420163516Simp{
421163516Simp	struct mmc_command cmd;
422163516Simp	int err = MMC_ERR_NONE, i;
423163516Simp
424163516Simp	memset(&cmd, 0, sizeof(cmd));
425163516Simp	cmd.opcode = MMC_SEND_OP_COND;
426163516Simp	cmd.arg = ocr;
427163516Simp	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
428163516Simp
429163516Simp	for (i = 0; i < 100; i++) {
430163516Simp		err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
431163516Simp		if (err != MMC_ERR_NONE)
432163516Simp			break;
433163516Simp		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) || ocr == 0)
434163516Simp			break;
435163516Simp		err = MMC_ERR_TIMEOUT;
436163516Simp		mmc_ms_delay(10);
437163516Simp	}
438163516Simp	if (rocr && err == MMC_ERR_NONE)
439163516Simp		*rocr = cmd.resp[0];
440163516Simp	return err;
441163516Simp}
442163516Simp
443163516Simpstatic void
444163516Simpmmc_power_up(struct mmc_softc *sc)
445163516Simp{
446163516Simp	device_t dev;
447163516Simp
448163516Simp	dev = sc->dev;
449163516Simp	mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev)));
450163516Simp	mmcbr_set_bus_mode(dev, opendrain);
451163516Simp	mmcbr_set_chip_select(dev, cs_dontcare);
452163516Simp	mmcbr_set_bus_width(dev, bus_width_1);
453163516Simp	mmcbr_set_power_mode(dev, power_up);
454163516Simp	mmcbr_set_clock(dev, 0);
455163516Simp	mmcbr_update_ios(dev);
456163516Simp	mmc_ms_delay(1);
457163516Simp
458163516Simp	mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev));
459163516Simp	mmcbr_set_power_mode(dev, power_on);
460163516Simp	mmcbr_update_ios(dev);
461163516Simp	mmc_ms_delay(2);
462163516Simp}
463163516Simp
464183449Simpstatic void
465183449Simpmmc_power_down(struct mmc_softc *sc)
466183449Simp{
467183449Simp	device_t dev = sc->dev;
468183449Simp
469183449Simp	mmcbr_set_bus_mode(dev, opendrain);
470183449Simp	mmcbr_set_chip_select(dev, cs_dontcare);
471183449Simp	mmcbr_set_bus_width(dev, bus_width_1);
472183449Simp	mmcbr_set_power_mode(dev, power_off);
473183449Simp	mmcbr_set_clock(dev, 0);
474183449Simp	mmcbr_update_ios(dev);
475183449Simp}
476183449Simp
477163516Simpstatic uint32_t
478163516Simpmmc_get_bits(uint32_t *bits, int start, int size)
479163516Simp{
480163516Simp	const int i = 3 - (start / 32);
481163516Simp	const int shift = start & 31;
482163516Simp	uint32_t retval = bits[i] >> shift;
483163516Simp	if (size + shift > 32)
484163516Simp		retval |= bits[i - 1] << (32 - shift);
485163516Simp	return retval & ((1 << size) - 1);
486163516Simp}
487163516Simp
488163516Simpstatic void
489163516Simpmmc_decode_cid(int is_sd, uint32_t *raw_cid, struct mmc_cid *cid)
490163516Simp{
491163516Simp	int i;
492163516Simp
493163516Simp	memset(cid, 0, sizeof(*cid));
494163516Simp	if (is_sd) {
495163516Simp		/* There's no version info, so we take it on faith */
496163516Simp		cid->mid = mmc_get_bits(raw_cid, 120, 8);
497163516Simp		cid->oid = mmc_get_bits(raw_cid, 104, 16);
498163516Simp		for (i = 0; i < 5; i++)
499163516Simp			cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
500163516Simp		cid->prv = mmc_get_bits(raw_cid, 56, 8);
501163516Simp		cid->psn = mmc_get_bits(raw_cid, 24, 32);
502163516Simp		cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001;
503163516Simp		cid->mdt_month = mmc_get_bits(raw_cid, 8, 4);
504163516Simp	} else {
505183453Simp		/* XXX write me */
506163516Simp		panic("write mmc cid decoder");
507163516Simp	}
508163516Simp}
509163516Simp
510163516Simpstatic const int exp[8] = {
511163516Simp	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
512163516Simp};
513163516Simpstatic const int mant[16] = {
514163516Simp	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
515163516Simp};
516163516Simpstatic const int cur_min[8] = {
517163516Simp	500, 1000, 5000, 10000, 25000, 35000, 60000, 100000
518163516Simp};
519163516Simpstatic const int cur_max[8] = {
520163516Simp	1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000
521163516Simp};
522163516Simp
523163516Simpstatic void
524163516Simpmmc_decode_csd(int is_sd, uint32_t *raw_csd, struct mmc_csd *csd)
525163516Simp{
526163516Simp	int v;
527163516Simp	int m;
528163516Simp	int e;
529163516Simp
530163516Simp	memset(csd, 0, sizeof(*csd));
531163516Simp	if (is_sd) {
532163516Simp		csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2);
533163516Simp		if (v == 0) {
534163516Simp			m = mmc_get_bits(raw_csd, 115, 4);
535163516Simp			e = mmc_get_bits(raw_csd, 112, 3);
536163516Simp			csd->tacc = exp[e] * mant[m] + 9 / 10;
537163516Simp			csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
538163516Simp			m = mmc_get_bits(raw_csd, 99, 4);
539163516Simp			e = mmc_get_bits(raw_csd, 96, 3);
540163516Simp			csd->tran_speed = exp[e] * 10000 * mant[m];
541163516Simp			csd->ccc = mmc_get_bits(raw_csd, 84, 12);
542163516Simp			csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
543163516Simp			csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
544163516Simp			csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
545163516Simp			csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
546163516Simp			csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
547163516Simp			csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)];
548163516Simp			csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)];
549163516Simp			csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)];
550163516Simp			csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)];
551163516Simp			m = mmc_get_bits(raw_csd, 62, 12);
552163516Simp			e = mmc_get_bits(raw_csd, 47, 3);
553163516Simp			csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
554163516Simp			csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
555163516Simp			csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
556163516Simp			csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
557163516Simp			csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
558163516Simp			csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
559163516Simp			csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
560163516Simp			csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
561163516Simp		} else if (v == 1) {
562163516Simp			panic("Write SDHC CSD parser");
563163516Simp		} else
564163516Simp			panic("unknown SD CSD version");
565163516Simp	} else {
566163516Simp		panic("Write a MMC CSD parser");
567163516Simp	}
568163516Simp}
569163516Simp
570163516Simpstatic int
571163516Simpmmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid)
572163516Simp{
573163516Simp	struct mmc_command cmd;
574163516Simp	int err;
575163516Simp
576163516Simp	cmd.opcode = MMC_ALL_SEND_CID;
577163516Simp	cmd.arg = 0;
578163516Simp	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
579163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
580163516Simp	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
581163516Simp	return (err);
582163516Simp}
583163516Simp
584163516Simpstatic int
585163516Simpmmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcid)
586163516Simp{
587163516Simp	struct mmc_command cmd;
588163516Simp	int err;
589163516Simp
590163516Simp	cmd.opcode = MMC_SEND_CSD;
591163516Simp	cmd.arg = rca << 16;
592163516Simp	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
593163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
594163516Simp	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
595163516Simp	return (err);
596163516Simp}
597163516Simp
598163516Simpstatic int
599163516Simpmmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp)
600163516Simp{
601163516Simp	struct mmc_command cmd;
602163516Simp	int err;
603163516Simp
604163516Simp	cmd.opcode = SD_SEND_RELATIVE_ADDR;
605163516Simp	cmd.arg = 0;
606163516Simp	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
607163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
608163516Simp	*resp = cmd.resp[0];
609163516Simp	return (err);
610163516Simp}
611163516Simp
612163516Simpstatic void
613163516Simpmmc_discover_cards(struct mmc_softc *sc)
614163516Simp{
615163516Simp	struct mmc_ivars *ivar;
616163516Simp	int err;
617163516Simp	uint32_t resp;
618163516Simp	device_t child;
619163516Simp
620163516Simp	while (1) {
621163516Simp		ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, M_WAITOK);
622169567Simp		if (!ivar)
623169567Simp			return;
624163516Simp		err = mmc_all_send_cid(sc, ivar->raw_cid);
625163516Simp		if (err == MMC_ERR_TIMEOUT)
626163516Simp			break;
627163516Simp		if (err != MMC_ERR_NONE) {
628163516Simp			printf("Error reading CID %d\n", err);
629163516Simp			break;
630163516Simp		}
631163516Simp		if (mmcbr_get_mode(sc->dev) == mode_sd) {
632163516Simp			ivar->mode = mode_sd;
633163516Simp			mmc_decode_cid(1, ivar->raw_cid, &ivar->cid);
634163516Simp			mmc_send_relative_addr(sc, &resp);
635163516Simp			ivar->rca = resp >> 16;
636183447Simp			if (mmcbr_get_ro(sc->dev))
637183447Simp				ivar->read_only = 1;
638163516Simp			mmc_send_csd(sc, ivar->rca, ivar->raw_csd);
639163516Simp			mmc_decode_csd(1, ivar->raw_csd, &ivar->csd);
640169567Simp			printf("SD CARD: %lld bytes\n", (long long)
641169567Simp			    ivar->csd.capacity);
642163516Simp			child = device_add_child(sc->dev, NULL, -1);
643163516Simp			device_set_ivars(child, ivar);
644169567Simp			return;
645163516Simp		}
646163516Simp		panic("Write MMC card code here");
647163516Simp	}
648169567Simp	free(ivar, M_DEVBUF);
649163516Simp}
650163516Simp
651163516Simpstatic void
652163516Simpmmc_go_discovery(struct mmc_softc *sc)
653163516Simp{
654163516Simp	uint32_t ocr;
655163516Simp	device_t dev;
656163516Simp
657163516Simp	dev = sc->dev;
658163516Simp	if (mmcbr_get_power_mode(dev) != power_on) {
659183453Simp		/*
660183453Simp		 * First, try SD modes
661183453Simp		 */
662163516Simp		mmcbr_set_mode(dev, mode_sd);
663163516Simp		mmc_power_up(sc);
664163516Simp		mmcbr_set_bus_mode(dev, pushpull);
665163516Simp		mmc_idle_cards(sc);
666163516Simp		if (mmc_send_app_op_cond(sc, 0, &ocr) != MMC_ERR_NONE) {
667183453Simp			/*
668183453Simp			 * Failed, try MMC
669183453Simp			 */
670163516Simp			mmcbr_set_mode(dev, mode_mmc);
671163516Simp			if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE)
672183453Simp				return;	/* Failed both, punt! XXX powerdown? */
673163516Simp		}
674163516Simp		mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
675163516Simp		if (mmcbr_get_ocr(dev) != 0)
676163516Simp			mmc_idle_cards(sc);
677163516Simp	} else {
678163516Simp		mmcbr_set_bus_mode(dev, opendrain);
679163516Simp		mmcbr_set_clock(dev, mmcbr_get_f_min(dev));
680163516Simp		mmcbr_update_ios(dev);
681183453Simp		/* XXX recompute vdd based on new cards? */
682163516Simp	}
683163516Simp	/*
684163516Simp	 * Make sure that we have a mutually agreeable voltage to at least
685163516Simp	 * one card on the bus.
686163516Simp	 */
687163516Simp	if (mmcbr_get_ocr(dev) == 0)
688163516Simp		return;
689163516Simp	/*
690163516Simp	 * Reselect the cards after we've idled them above.
691163516Simp	 */
692163516Simp	if (mmcbr_get_mode(dev) == mode_sd)
693163516Simp		mmc_send_app_op_cond(sc, mmcbr_get_ocr(dev), NULL);
694163516Simp	else
695163516Simp		mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL);
696163516Simp	mmc_discover_cards(sc);
697163516Simp
698163516Simp	mmcbr_set_bus_mode(dev, pushpull);
699163516Simp	mmcbr_update_ios(dev);
700163516Simp	bus_generic_attach(dev);
701183453Simp/*	mmc_update_children_sysctl(dev);*/
702163516Simp}
703163516Simp
704163516Simpstatic int
705163516Simpmmc_calculate_clock(struct mmc_softc *sc)
706163516Simp{
707163516Simp	int max_dtr = 0;
708163516Simp	int nkid, i, f_min, f_max;
709163516Simp	device_t *kids;
710163516Simp
711163516Simp	f_min = mmcbr_get_f_min(sc->dev);
712163516Simp	f_max = mmcbr_get_f_max(sc->dev);
713163516Simp	max_dtr = f_max;
714163516Simp	if (device_get_children(sc->dev, &kids, &nkid) != 0)
715163516Simp		panic("can't get children");
716163516Simp	for (i = 0; i < nkid; i++)
717163516Simp		if (mmc_get_tran_speed(kids[i]) < max_dtr)
718163516Simp			max_dtr = mmc_get_tran_speed(kids[i]);
719163516Simp	free(kids, M_TEMP);
720163516Simp	device_printf(sc->dev, "setting transfer rate to %d.%03dMHz\n",
721163516Simp	    max_dtr / 1000000, (max_dtr / 1000) % 1000);
722163516Simp	return max_dtr;
723163516Simp}
724163516Simp
725163516Simpstatic void
726163516Simpmmc_scan(struct mmc_softc *sc)
727163516Simp{
728163516Simp	device_t dev;
729163516Simp
730163516Simp	dev = sc->dev;
731163516Simp	mmc_acquire_bus(dev, dev);
732163516Simp
733163516Simp	if (mmcbr_get_power_mode(dev) == power_on)
734163516Simp		mmc_rescan_cards(sc);
735163516Simp	mmc_go_discovery(sc);
736163516Simp	mmcbr_set_clock(dev, mmc_calculate_clock(sc));
737163516Simp	mmcbr_update_ios(dev);
738163516Simp
739163516Simp	mmc_release_bus(dev, dev);
740183453Simp	/* XXX probe/attach/detach children? */
741163516Simp}
742163516Simp
743163516Simpstatic int
744163516Simpmmc_read_ivar(device_t bus, device_t child, int which, u_char *result)
745163516Simp{
746163516Simp	struct mmc_ivars *ivar = device_get_ivars(child);
747163516Simp
748163516Simp	switch (which) {
749163516Simp	default:
750163516Simp		return (EINVAL);
751163516Simp	case MMC_IVAR_DSR_IMP:
752163516Simp		*(int *)result = ivar->csd.dsr_imp;
753163516Simp		break;
754163516Simp	case MMC_IVAR_MEDIA_SIZE:
755163516Simp		*(int *)result = ivar->csd.capacity;
756163516Simp		break;
757163516Simp	case MMC_IVAR_RCA:
758163516Simp		*(int *)result = ivar->rca;
759163516Simp		break;
760163516Simp	case MMC_IVAR_SECTOR_SIZE:
761163516Simp		*(int *)result = 512;
762163516Simp		break;
763163516Simp	case MMC_IVAR_TRAN_SPEED:
764163516Simp		*(int *)result = ivar->csd.tran_speed;
765163516Simp		break;
766183447Simp	case MMC_IVAR_READ_ONLY:
767183447Simp		*(int *)result = ivar->read_only;
768183447Simp		break;
769163516Simp	}
770163516Simp	return (0);
771163516Simp}
772163516Simp
773163516Simpstatic int
774163516Simpmmc_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
775163516Simp{
776183453Simp	/*
777183453Simp	 * None are writable ATM
778183453Simp	 */
779183453Simp	return (EINVAL);
780163516Simp}
781163516Simp
782163516Simp
783163516Simpstatic void
784163516Simpmmc_delayed_attach(void *xsc)
785163516Simp{
786163516Simp	struct mmc_softc *sc = xsc;
787163516Simp
788163516Simp	mmc_scan(sc);
789163516Simp	config_intrhook_disestablish(&sc->config_intrhook);
790163516Simp}
791163516Simp
792163516Simpstatic device_method_t mmc_methods[] = {
793163516Simp	/* device_if */
794163516Simp	DEVMETHOD(device_probe, mmc_probe),
795163516Simp	DEVMETHOD(device_attach, mmc_attach),
796163516Simp	DEVMETHOD(device_detach, mmc_detach),
797163516Simp
798163516Simp	/* Bus interface */
799163516Simp	DEVMETHOD(bus_read_ivar, mmc_read_ivar),
800163516Simp	DEVMETHOD(bus_write_ivar, mmc_write_ivar),
801163516Simp
802163516Simp	/* MMC Bus interface */
803163516Simp	DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request),
804163516Simp	DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus),
805163516Simp	DEVMETHOD(mmcbus_release_bus, mmc_release_bus),
806163516Simp
807163516Simp	{0, 0},
808163516Simp};
809163516Simp
810163516Simpstatic driver_t mmc_driver = {
811163516Simp	"mmc",
812163516Simp	mmc_methods,
813163516Simp	sizeof(struct mmc_softc),
814163516Simp};
815163516Simpstatic devclass_t mmc_devclass;
816163516Simp
817163516Simp
818163516SimpDRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0);
819169567SimpDRIVER_MODULE(mmc, sdh, mmc_driver, mmc_devclass, 0, 0);
820