mmc.c revision 183763
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 183763 2008-10-11 13:05:13Z mav $");
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>
64183704Smav#include <sys/endian.h>
65163516Simp
66163516Simp#include <dev/mmc/mmcreg.h>
67163516Simp#include <dev/mmc/mmcbrvar.h>
68163516Simp#include <dev/mmc/mmcvar.h>
69163516Simp#include "mmcbr_if.h"
70163516Simp#include "mmcbus_if.h"
71163516Simp
72163516Simpstruct mmc_softc {
73163516Simp	device_t dev;
74163516Simp	struct mtx sc_mtx;
75163516Simp	struct intr_config_hook config_intrhook;
76163516Simp	device_t owner;
77163516Simp	uint32_t last_rca;
78163516Simp};
79163516Simp
80163516Simp/*
81163516Simp * Per-card data
82163516Simp */
83163516Simpstruct mmc_ivars {
84163516Simp	uint32_t raw_cid[4];	/* Raw bits of the CID */
85163516Simp	uint32_t raw_csd[4];	/* Raw bits of the CSD */
86183704Smav	uint32_t raw_scr[2];	/* Raw bits of the SCR */
87183704Smav	uint8_t raw_ext_csd[512];	/* Raw bits of the EXT_CSD */
88163516Simp	uint16_t rca;
89163516Simp	enum mmc_card_mode mode;
90163516Simp	struct mmc_cid cid;	/* cid decoded */
91163516Simp	struct mmc_csd csd;	/* csd decoded */
92183704Smav	struct mmc_scr scr;	/* scr decoded */
93183447Simp	u_char read_only;	/* True when the device is read-only */
94183704Smav	u_char bus_width;	/* Bus width to use */
95183704Smav	u_char timing;		/* Bus timing support */
96183731Smav	u_char high_cap;	/* High Capacity card (block addressed) */
97183731Smav	uint32_t sec_count;	/* Card capacity in 512byte blocks */
98183704Smav	uint32_t tran_speed;	/* Max speed in normal mode */
99183704Smav	uint32_t hs_tran_speed;	/* Max speed in high speed mode */
100163516Simp};
101163516Simp
102163516Simp#define CMD_RETRIES	3
103163516Simp
104163516Simp/* bus entry points */
105163516Simpstatic int mmc_probe(device_t dev);
106163516Simpstatic int mmc_attach(device_t dev);
107163516Simpstatic int mmc_detach(device_t dev);
108163516Simp
109163516Simp#define MMC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
110163516Simp#define	MMC_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
111183444Simp#define MMC_LOCK_INIT(_sc)					\
112183444Simp	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev),	\
113163516Simp	    "mmc", MTX_DEF)
114163516Simp#define MMC_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
115163516Simp#define MMC_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
116163516Simp#define MMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
117163516Simp
118183763Smavstatic int mmc_calculate_clock(struct mmc_softc *sc);
119163516Simpstatic void mmc_delayed_attach(void *);
120183449Simpstatic void mmc_power_down(struct mmc_softc *sc);
121163516Simpstatic int mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd,
122163516Simp    int retries);
123163516Simpstatic int mmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
124163516Simp    uint32_t arg, uint32_t flags, uint32_t *resp, int retries);
125183704Smavstatic int mmc_select_card(struct mmc_softc *sc, uint16_t rca);
126183763Smavstatic int mmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width);
127183704Smavstatic int mmc_app_send_scr(struct mmc_softc *sc, uint16_t rca, uint32_t *rawscr);
128183704Smavstatic void mmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr);
129183704Smavstatic int mmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd);
130163516Simp
131163516Simpstatic void
132163516Simpmmc_ms_delay(int ms)
133163516Simp{
134163516Simp	DELAY(1000 * ms);	/* XXX BAD */
135163516Simp}
136163516Simp
137163516Simpstatic int
138163516Simpmmc_probe(device_t dev)
139163516Simp{
140163516Simp
141183445Simp	device_set_desc(dev, "MMC/SD bus");
142163516Simp	return (0);
143163516Simp}
144163516Simp
145163516Simpstatic int
146163516Simpmmc_attach(device_t dev)
147163516Simp{
148163516Simp	struct mmc_softc *sc;
149163516Simp
150163516Simp	sc = device_get_softc(dev);
151163516Simp	sc->dev = dev;
152163516Simp	MMC_LOCK_INIT(sc);
153163516Simp
154163516Simp	/* We'll probe and attach our children later, but before / mount */
155163516Simp	sc->config_intrhook.ich_func = mmc_delayed_attach;
156163516Simp	sc->config_intrhook.ich_arg = sc;
157163516Simp	if (config_intrhook_establish(&sc->config_intrhook) != 0)
158163516Simp		device_printf(dev, "config_intrhook_establish failed\n");
159163516Simp	return (0);
160163516Simp}
161163516Simp
162163516Simpstatic int
163163516Simpmmc_detach(device_t dev)
164163516Simp{
165169567Simp	struct mmc_softc *sc = device_get_softc(dev);
166169567Simp	device_t *kids;
167169567Simp	int i, nkid;
168169567Simp
169169567Simp	/* kill children [ph33r].  -sorbo */
170169567Simp	if (device_get_children(sc->dev, &kids, &nkid) != 0)
171183467Simp		return (0);
172169567Simp	for (i = 0; i < nkid; i++) {
173169567Simp		device_t kid = kids[i];
174169567Simp		void *ivar = device_get_ivars(kid);
175169567Simp
176169567Simp		device_detach(kid);
177169567Simp		device_delete_child(sc->dev, kid);
178169567Simp		free(ivar, M_DEVBUF);
179169567Simp	}
180169567Simp	free(kids, M_TEMP);
181183449Simp	mmc_power_down(sc);
182169567Simp
183169567Simp	MMC_LOCK_DESTROY(sc);
184169567Simp
185183467Simp	return (0);
186163516Simp}
187163516Simp
188163516Simpstatic int
189163516Simpmmc_acquire_bus(device_t busdev, device_t dev)
190163516Simp{
191163516Simp	struct mmc_softc *sc;
192183704Smav	struct mmc_ivars *ivar;
193163516Simp	int err;
194163516Simp	int rca;
195163516Simp
196183452Simp	err = MMCBR_ACQUIRE_HOST(device_get_parent(busdev), busdev);
197163516Simp	if (err)
198163516Simp		return (err);
199163516Simp	sc = device_get_softc(busdev);
200163516Simp	MMC_LOCK(sc);
201163516Simp	if (sc->owner)
202163516Simp		panic("mmc: host bridge didn't seralize us.");
203163516Simp	sc->owner = dev;
204163516Simp	MMC_UNLOCK(sc);
205163516Simp
206163516Simp	if (busdev != dev) {
207183453Simp		/*
208183453Simp		 * Keep track of the last rca that we've selected.  If
209183453Simp		 * we're asked to do it again, don't.  We never
210183453Simp		 * unselect unless the bus code itself wants the mmc
211183453Simp		 * bus, and constantly reselecting causes problems.
212183453Simp		 */
213163516Simp		rca = mmc_get_rca(dev);
214163516Simp		if (sc->last_rca != rca) {
215183704Smav			mmc_select_card(sc, rca);
216163516Simp			sc->last_rca = rca;
217183704Smav			/* Prepare bus width for the new card. */
218183704Smav			ivar = device_get_ivars(dev);
219183763Smav			if (bootverbose) {
220183763Smav				device_printf(busdev,
221183763Smav				    "setting bus width to %d bits\n",
222183763Smav				    (ivar->bus_width == bus_width_4)?4:
223183763Smav				    (ivar->bus_width == bus_width_8)?8:1);
224183763Smav			}
225183763Smav			mmc_set_card_bus_width(sc, rca, ivar->bus_width);
226183704Smav			mmcbr_set_bus_width(busdev, ivar->bus_width);
227183704Smav			mmcbr_update_ios(busdev);
228163516Simp		}
229163516Simp	} else {
230183453Simp		/*
231183453Simp		 * If there's a card selected, stand down.
232183453Simp		 */
233163516Simp		if (sc->last_rca != 0) {
234183704Smav			mmc_select_card(sc, 0);
235163516Simp			sc->last_rca = 0;
236163516Simp		}
237163516Simp	}
238163516Simp
239163516Simp	return (0);
240163516Simp}
241163516Simp
242163516Simpstatic int
243163516Simpmmc_release_bus(device_t busdev, device_t dev)
244163516Simp{
245163516Simp	struct mmc_softc *sc;
246163516Simp	int err;
247163516Simp
248163516Simp	sc = device_get_softc(busdev);
249163516Simp
250163516Simp	MMC_LOCK(sc);
251163516Simp	if (!sc->owner)
252163516Simp		panic("mmc: releasing unowned bus.");
253163516Simp	if (sc->owner != dev)
254163516Simp		panic("mmc: you don't own the bus.  game over.");
255163516Simp	MMC_UNLOCK(sc);
256183452Simp	err = MMCBR_RELEASE_HOST(device_get_parent(busdev), busdev);
257163516Simp	if (err)
258163516Simp		return (err);
259163516Simp	MMC_LOCK(sc);
260163516Simp	sc->owner = NULL;
261163516Simp	MMC_UNLOCK(sc);
262163516Simp	return (0);
263163516Simp}
264163516Simp
265163516Simpstatic void
266163516Simpmmc_rescan_cards(struct mmc_softc *sc)
267163516Simp{
268163516Simp	/* XXX: Look at the children and see if they respond to status */
269163516Simp}
270163516Simp
271163516Simpstatic uint32_t
272163516Simpmmc_select_vdd(struct mmc_softc *sc, uint32_t ocr)
273163516Simp{
274183446Simp
275183467Simp	return (ocr & MMC_OCR_VOLTAGE);
276163516Simp}
277163516Simp
278163516Simpstatic int
279163516Simpmmc_highest_voltage(uint32_t ocr)
280163516Simp{
281163516Simp	int i;
282163516Simp
283163516Simp	for (i = 30; i >= 0; i--)
284163516Simp		if (ocr & (1 << i))
285183467Simp			return (i);
286163516Simp	return (-1);
287163516Simp}
288163516Simp
289163516Simpstatic void
290163516Simpmmc_wakeup(struct mmc_request *req)
291163516Simp{
292163516Simp	struct mmc_softc *sc;
293163516Simp
294183453Simp/*	printf("Wakeup for req %p done_data %p\n", req, req->done_data); */
295163516Simp	sc = (struct mmc_softc *)req->done_data;
296163516Simp	MMC_LOCK(sc);
297163516Simp	req->flags |= MMC_REQ_DONE;
298163516Simp	wakeup(req);
299163516Simp	MMC_UNLOCK(sc);
300163516Simp}
301163516Simp
302163516Simpstatic int
303163516Simpmmc_wait_for_req(struct mmc_softc *sc, struct mmc_request *req)
304163516Simp{
305163516Simp	int err;
306163516Simp
307163516Simp	req->done = mmc_wakeup;
308163516Simp	req->done_data = sc;
309183453Simp/*	printf("Submitting request %p sc %p\n", req, sc); */
310163516Simp	MMCBR_REQUEST(device_get_parent(sc->dev), sc->dev, req);
311163516Simp	MMC_LOCK(sc);
312163516Simp	do {
313163516Simp		err = msleep(req, &sc->sc_mtx, PZERO | PCATCH, "mmcreq",
314163516Simp		    hz / 10);
315163516Simp	} while (!(req->flags & MMC_REQ_DONE) && err == EAGAIN);
316183453Simp/*	printf("Request %p done with error %d\n", req, err); */
317163516Simp	MMC_UNLOCK(sc);
318163516Simp	return (err);
319163516Simp}
320163516Simp
321163516Simpstatic int
322163516Simpmmc_wait_for_request(device_t brdev, device_t reqdev, struct mmc_request *req)
323163516Simp{
324163516Simp	struct mmc_softc *sc = device_get_softc(brdev);
325163516Simp
326183467Simp	return (mmc_wait_for_req(sc, req));
327163516Simp}
328163516Simp
329163516Simpstatic int
330163516Simpmmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries)
331163516Simp{
332163516Simp	struct mmc_request mreq;
333163516Simp
334163516Simp	memset(&mreq, 0, sizeof(mreq));
335163516Simp	memset(cmd->resp, 0, sizeof(cmd->resp));
336163516Simp	cmd->retries = retries;
337163516Simp	mreq.cmd = cmd;
338183453Simp/*	printf("CMD: %x ARG %x\n", cmd->opcode, cmd->arg); */
339163516Simp	mmc_wait_for_req(sc, &mreq);
340163516Simp	return (cmd->error);
341163516Simp}
342163516Simp
343163516Simpstatic int
344163516Simpmmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca,
345163516Simp    struct mmc_command *cmd, int retries)
346163516Simp{
347163516Simp	struct mmc_command appcmd;
348163516Simp	int err = MMC_ERR_NONE, i;
349163516Simp
350163516Simp	for (i = 0; i <= retries; i++) {
351163516Simp		appcmd.opcode = MMC_APP_CMD;
352163516Simp		appcmd.arg = rca << 16;
353163516Simp		appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
354183470Simp		appcmd.data = NULL;
355163516Simp		mmc_wait_for_cmd(sc, &appcmd, 0);
356163516Simp		err = appcmd.error;
357163516Simp		if (err != MMC_ERR_NONE)
358163516Simp			continue;
359163516Simp		if (!(appcmd.resp[0] & R1_APP_CMD))
360163516Simp			return MMC_ERR_FAILED;
361163516Simp		mmc_wait_for_cmd(sc, cmd, 0);
362163516Simp		err = cmd->error;
363163516Simp		if (err == MMC_ERR_NONE)
364163516Simp			break;
365163516Simp	}
366163516Simp	return (err);
367163516Simp}
368163516Simp
369163516Simpstatic int
370163516Simpmmc_wait_for_command(struct mmc_softc *sc, uint32_t opcode,
371163516Simp    uint32_t arg, uint32_t flags, uint32_t *resp, int retries)
372163516Simp{
373163516Simp	struct mmc_command cmd;
374163516Simp	int err;
375163516Simp
376163516Simp	memset(&cmd, 0, sizeof(cmd));
377163516Simp	cmd.opcode = opcode;
378163516Simp	cmd.arg = arg;
379163516Simp	cmd.flags = flags;
380183470Simp	cmd.data = NULL;
381163516Simp	err = mmc_wait_for_cmd(sc, &cmd, retries);
382163516Simp	if (err)
383163516Simp		return (err);
384163516Simp	if (cmd.error)
385163516Simp		return (cmd.error);
386163516Simp	if (resp) {
387163516Simp		if (flags & MMC_RSP_136)
388163516Simp			memcpy(resp, cmd.resp, 4 * sizeof(uint32_t));
389163516Simp		else
390163516Simp			*resp = cmd.resp[0];
391163516Simp	}
392163516Simp	return (0);
393163516Simp}
394163516Simp
395163516Simpstatic void
396163516Simpmmc_idle_cards(struct mmc_softc *sc)
397163516Simp{
398163516Simp	device_t dev;
399163516Simp	struct mmc_command cmd;
400163516Simp
401163516Simp	dev = sc->dev;
402163516Simp	mmcbr_set_chip_select(dev, cs_high);
403163516Simp	mmcbr_update_ios(dev);
404163516Simp	mmc_ms_delay(1);
405163516Simp
406163516Simp	memset(&cmd, 0, sizeof(cmd));
407163516Simp	cmd.opcode = MMC_GO_IDLE_STATE;
408163516Simp	cmd.arg = 0;
409163516Simp	cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
410183470Simp	cmd.data = NULL;
411163516Simp	mmc_wait_for_cmd(sc, &cmd, 0);
412163516Simp	mmc_ms_delay(1);
413163516Simp
414163516Simp	mmcbr_set_chip_select(dev, cs_dontcare);
415163516Simp	mmcbr_update_ios(dev);
416163516Simp	mmc_ms_delay(1);
417163516Simp}
418163516Simp
419163516Simpstatic int
420163516Simpmmc_send_app_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr)
421163516Simp{
422163516Simp	struct mmc_command cmd;
423163516Simp	int err = MMC_ERR_NONE, i;
424163516Simp
425163516Simp	memset(&cmd, 0, sizeof(cmd));
426163516Simp	cmd.opcode = ACMD_SD_SEND_OP_COND;
427163516Simp	cmd.arg = ocr;
428163516Simp	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
429183470Simp	cmd.data = NULL;
430163516Simp
431170337Simp	for (i = 0; i < 100; i++) {
432163516Simp		err = mmc_wait_for_app_cmd(sc, 0, &cmd, CMD_RETRIES);
433163516Simp		if (err != MMC_ERR_NONE)
434163516Simp			break;
435183709Smav		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) ||
436183709Smav		    (ocr & MMC_OCR_VOLTAGE) == 0)
437163516Simp			break;
438163516Simp		err = MMC_ERR_TIMEOUT;
439163516Simp		mmc_ms_delay(10);
440163516Simp	}
441163516Simp	if (rocr && err == MMC_ERR_NONE)
442163516Simp		*rocr = cmd.resp[0];
443183467Simp	return (err);
444163516Simp}
445163516Simp
446163516Simpstatic int
447163516Simpmmc_send_op_cond(struct mmc_softc *sc, uint32_t ocr, uint32_t *rocr)
448163516Simp{
449163516Simp	struct mmc_command cmd;
450163516Simp	int err = MMC_ERR_NONE, i;
451163516Simp
452163516Simp	memset(&cmd, 0, sizeof(cmd));
453163516Simp	cmd.opcode = MMC_SEND_OP_COND;
454163516Simp	cmd.arg = ocr;
455163516Simp	cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
456183470Simp	cmd.data = NULL;
457163516Simp
458163516Simp	for (i = 0; i < 100; i++) {
459163516Simp		err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
460163516Simp		if (err != MMC_ERR_NONE)
461163516Simp			break;
462183709Smav		if ((cmd.resp[0] & MMC_OCR_CARD_BUSY) ||
463183709Smav		    (ocr & MMC_OCR_VOLTAGE) == 0)
464163516Simp			break;
465163516Simp		err = MMC_ERR_TIMEOUT;
466163516Simp		mmc_ms_delay(10);
467163516Simp	}
468163516Simp	if (rocr && err == MMC_ERR_NONE)
469163516Simp		*rocr = cmd.resp[0];
470183467Simp	return (err);
471163516Simp}
472163516Simp
473183704Smavstatic int
474183704Smavmmc_send_if_cond(struct mmc_softc *sc, uint8_t vhs)
475183704Smav{
476183704Smav	struct mmc_command cmd;
477183704Smav	int err;
478183704Smav
479183704Smav	memset(&cmd, 0, sizeof(cmd));
480183704Smav	cmd.opcode = SD_SEND_IF_COND;
481183704Smav	cmd.arg = (vhs << 8) + 0xAA;
482183704Smav	cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;
483183704Smav	cmd.data = NULL;
484183704Smav
485183704Smav	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
486183704Smav	return (err);
487183704Smav}
488183704Smav
489163516Simpstatic void
490163516Simpmmc_power_up(struct mmc_softc *sc)
491163516Simp{
492163516Simp	device_t dev;
493163516Simp
494163516Simp	dev = sc->dev;
495163516Simp	mmcbr_set_vdd(dev, mmc_highest_voltage(mmcbr_get_host_ocr(dev)));
496163516Simp	mmcbr_set_bus_mode(dev, opendrain);
497163516Simp	mmcbr_set_chip_select(dev, cs_dontcare);
498163516Simp	mmcbr_set_bus_width(dev, bus_width_1);
499163516Simp	mmcbr_set_power_mode(dev, power_up);
500163516Simp	mmcbr_set_clock(dev, 0);
501163516Simp	mmcbr_update_ios(dev);
502163516Simp	mmc_ms_delay(1);
503163516Simp
504163516Simp	mmcbr_set_clock(dev, mmcbr_get_f_min(sc->dev));
505183704Smav	mmcbr_set_timing(dev, bus_timing_normal);
506163516Simp	mmcbr_set_power_mode(dev, power_on);
507163516Simp	mmcbr_update_ios(dev);
508163516Simp	mmc_ms_delay(2);
509163516Simp}
510163516Simp
511183449Simpstatic void
512183449Simpmmc_power_down(struct mmc_softc *sc)
513183449Simp{
514183449Simp	device_t dev = sc->dev;
515183449Simp
516183449Simp	mmcbr_set_bus_mode(dev, opendrain);
517183449Simp	mmcbr_set_chip_select(dev, cs_dontcare);
518183449Simp	mmcbr_set_bus_width(dev, bus_width_1);
519183449Simp	mmcbr_set_power_mode(dev, power_off);
520183449Simp	mmcbr_set_clock(dev, 0);
521183704Smav	mmcbr_set_timing(dev, bus_timing_normal);
522183449Simp	mmcbr_update_ios(dev);
523183449Simp}
524183449Simp
525183704Smavstatic int
526183704Smavmmc_select_card(struct mmc_softc *sc, uint16_t rca)
527183704Smav{
528183704Smav	return (mmc_wait_for_command(sc, MMC_SELECT_CARD, ((uint32_t)rca) << 16,
529183704Smav	    MMC_RSP_R1B | MMC_CMD_AC, NULL, CMD_RETRIES));
530183704Smav}
531183704Smav
532183704Smavstatic int
533183704Smavmmc_switch(struct mmc_softc *sc, uint8_t set, uint8_t index, uint8_t value)
534183704Smav{
535183704Smav	struct mmc_command cmd;
536183704Smav	int err;
537183704Smav
538183704Smav	cmd.opcode = MMC_SWITCH_FUNC;
539183704Smav	cmd.arg = (MMC_SWITCH_FUNC_WR << 24) |
540183704Smav	    (index << 16) |
541183704Smav	    (value << 8) |
542183704Smav	    set;
543183704Smav	cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
544183704Smav	cmd.data = NULL;
545183704Smav	err = mmc_wait_for_cmd(sc, &cmd, 0);
546183704Smav	return (err);
547183704Smav}
548183704Smav
549183704Smavstatic int
550183704Smavmmc_sd_switch(struct mmc_softc *sc, uint8_t mode, uint8_t grp, uint8_t value, uint8_t *res)
551183704Smav{
552183704Smav	int err;
553183704Smav	struct mmc_command cmd;
554183704Smav	struct mmc_data data;
555183704Smav
556183704Smav	memset(&cmd, 0, sizeof(struct mmc_command));
557183704Smav	memset(&data, 0, sizeof(struct mmc_data));
558183704Smav
559183704Smav	memset(res, 0, 64);
560183704Smav	cmd.opcode = SD_SWITCH_FUNC;
561183704Smav	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
562183704Smav	cmd.arg = mode << 31;
563183704Smav	cmd.arg |= 0x00FFFFFF;
564183705Smav	cmd.arg &= ~(0xF << (grp * 4));
565183705Smav	cmd.arg |= value << (grp * 4);
566183704Smav	cmd.data = &data;
567183704Smav
568183704Smav	data.data = res;
569183704Smav	data.len = 64;
570183704Smav	data.flags = MMC_DATA_READ;
571183704Smav
572183704Smav	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
573183704Smav	return (err);
574183704Smav}
575183704Smav
576183704Smavstatic int
577183763Smavmmc_set_card_bus_width(struct mmc_softc *sc, uint16_t rca, int width)
578183704Smav{
579183704Smav	int err;
580183704Smav
581183704Smav	if (mmcbr_get_mode(sc->dev) == mode_sd) {
582183704Smav		struct mmc_command cmd;
583183704Smav
584183704Smav		memset(&cmd, 0, sizeof(struct mmc_command));
585183704Smav		cmd.opcode = ACMD_SET_BUS_WIDTH;
586183704Smav		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
587183704Smav		switch (width) {
588183704Smav		case bus_width_1:
589183704Smav			cmd.arg = SD_BUS_WIDTH_1;
590183704Smav			break;
591183704Smav		case bus_width_4:
592183704Smav			cmd.arg = SD_BUS_WIDTH_4;
593183704Smav			break;
594183704Smav		default:
595183704Smav			return (MMC_ERR_INVALID);
596183704Smav		}
597183704Smav		err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
598183704Smav	} else {
599183704Smav		uint8_t	value;
600183704Smav
601183704Smav		switch (width) {
602183704Smav		case bus_width_1:
603183704Smav			value = EXT_CSD_BUS_WIDTH_1;
604183704Smav			break;
605183704Smav		case bus_width_4:
606183704Smav			value = EXT_CSD_BUS_WIDTH_4;
607183704Smav			break;
608183704Smav		case bus_width_8:
609183704Smav			value = EXT_CSD_BUS_WIDTH_8;
610183704Smav			break;
611183704Smav		default:
612183704Smav			return (MMC_ERR_INVALID);
613183704Smav		}
614183704Smav		err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, value);
615183704Smav	}
616183704Smav	return (err);
617183704Smav}
618183704Smav
619183704Smavstatic int
620183704Smavmmc_set_timing(struct mmc_softc *sc, int timing)
621183704Smav{
622183704Smav	int err;
623183704Smav	uint8_t	value;
624183704Smav
625183704Smav	switch (timing) {
626183704Smav	case bus_timing_normal:
627183704Smav		value = 0;
628183704Smav		break;
629183704Smav	case bus_timing_hs:
630183704Smav		value = 1;
631183704Smav		break;
632183704Smav	default:
633183704Smav		return (MMC_ERR_INVALID);
634183704Smav	}
635183704Smav	if (mmcbr_get_mode(sc->dev) == mode_sd) {
636183704Smav		u_char switch_res[64];
637183704Smav
638183704Smav		err = mmc_sd_switch(sc, 1, 0, value, switch_res);
639183704Smav	} else {
640183704Smav		err = mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL,
641183704Smav		    EXT_CSD_HS_TIMING, value);
642183704Smav	}
643183704Smav	return (err);
644183704Smav}
645183704Smav
646183704Smavstatic int
647183704Smavmmc_test_bus_width(struct mmc_softc *sc)
648183704Smav{
649183704Smav	struct mmc_command cmd;
650183704Smav	struct mmc_data data;
651183704Smav	int err;
652183704Smav	uint8_t buf[8];
653183704Smav	uint8_t	p8[8] =   { 0x55, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
654183704Smav	uint8_t	p8ok[8] = { 0xAA, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
655183704Smav	uint8_t	p4[4] =   { 0x5A, 0x00, 0x00, 0x00, };
656183704Smav	uint8_t	p4ok[4] = { 0xA5, 0x00, 0x00, 0x00, };
657183704Smav
658183704Smav	if (mmcbr_get_caps(sc->dev) & MMC_CAP_8_BIT_DATA) {
659183704Smav		mmcbr_set_bus_width(sc->dev, bus_width_8);
660183704Smav		mmcbr_update_ios(sc->dev);
661183704Smav
662183704Smav		cmd.opcode = MMC_BUSTEST_W;
663183704Smav		cmd.arg = 0;
664183704Smav		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
665183704Smav		cmd.data = &data;
666183704Smav
667183704Smav		data.data = p8;
668183704Smav		data.len = 8;
669183704Smav		data.flags = MMC_DATA_WRITE;
670183704Smav		mmc_wait_for_cmd(sc, &cmd, 0);
671183704Smav
672183704Smav		cmd.opcode = MMC_BUSTEST_R;
673183704Smav		cmd.arg = 0;
674183704Smav		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
675183704Smav		cmd.data = &data;
676183704Smav
677183704Smav		data.data = buf;
678183704Smav		data.len = 8;
679183704Smav		data.flags = MMC_DATA_READ;
680183704Smav		err = mmc_wait_for_cmd(sc, &cmd, 0);
681183704Smav
682183704Smav		mmcbr_set_bus_width(sc->dev, bus_width_1);
683183704Smav		mmcbr_update_ios(sc->dev);
684183704Smav
685183704Smav		if (err == MMC_ERR_NONE && memcmp(buf, p8ok, 8) == 0)
686183704Smav			return (bus_width_8);
687183704Smav	}
688183704Smav
689183704Smav	if (mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) {
690183704Smav		mmcbr_set_bus_width(sc->dev, bus_width_4);
691183704Smav		mmcbr_update_ios(sc->dev);
692183704Smav
693183704Smav		cmd.opcode = MMC_BUSTEST_W;
694183704Smav		cmd.arg = 0;
695183704Smav		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
696183704Smav		cmd.data = &data;
697183704Smav
698183704Smav		data.data = p4;
699183704Smav		data.len = 4;
700183704Smav		data.flags = MMC_DATA_WRITE;
701183704Smav		mmc_wait_for_cmd(sc, &cmd, 0);
702183704Smav
703183704Smav		cmd.opcode = MMC_BUSTEST_R;
704183704Smav		cmd.arg = 0;
705183704Smav		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
706183704Smav		cmd.data = &data;
707183704Smav
708183704Smav		data.data = buf;
709183704Smav		data.len = 4;
710183704Smav		data.flags = MMC_DATA_READ;
711183704Smav		err = mmc_wait_for_cmd(sc, &cmd, 0);
712183704Smav
713183704Smav		mmcbr_set_bus_width(sc->dev, bus_width_1);
714183704Smav		mmcbr_update_ios(sc->dev);
715183704Smav
716183704Smav		if (err == MMC_ERR_NONE && memcmp(buf, p4ok, 4) == 0)
717183704Smav			return (bus_width_4);
718183704Smav	}
719183704Smav	return (bus_width_1);
720183704Smav}
721183704Smav
722163516Simpstatic uint32_t
723163516Simpmmc_get_bits(uint32_t *bits, int start, int size)
724163516Simp{
725183729Simp	const int bit_len = 128;
726183729Simp	const int i = (bit_len / 32) - (start / 32) - 1;
727163516Simp	const int shift = start & 31;
728163516Simp	uint32_t retval = bits[i] >> shift;
729163516Simp	if (size + shift > 32)
730163516Simp		retval |= bits[i - 1] << (32 - shift);
731183467Simp	return (retval & ((1 << size) - 1));
732163516Simp}
733163516Simp
734163516Simpstatic void
735183729Simpmmc_decode_cid_sd(uint32_t *raw_cid, struct mmc_cid *cid)
736163516Simp{
737163516Simp	int i;
738163516Simp
739183729Simp	/* There's no version info, so we take it on faith */
740163516Simp	memset(cid, 0, sizeof(*cid));
741183729Simp	cid->mid = mmc_get_bits(raw_cid, 120, 8);
742183729Simp	cid->oid = mmc_get_bits(raw_cid, 104, 16);
743183729Simp	for (i = 0; i < 5; i++)
744183729Simp		cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
745183729Simp	cid->prv = mmc_get_bits(raw_cid, 56, 8);
746183729Simp	cid->psn = mmc_get_bits(raw_cid, 24, 32);
747183729Simp	cid->mdt_year = mmc_get_bits(raw_cid, 12, 8) + 2001;
748183729Simp	cid->mdt_month = mmc_get_bits(raw_cid, 8, 4);
749163516Simp}
750163516Simp
751183729Simpstatic void
752183729Simpmmc_decode_cid_mmc(uint32_t *raw_cid, struct mmc_cid *cid)
753183729Simp{
754183729Simp	int i;
755183729Simp
756183729Simp	/* There's no version info, so we take it on faith */
757183729Simp	memset(cid, 0, sizeof(*cid));
758183729Simp	cid->mid = mmc_get_bits(raw_cid, 120, 8);
759183729Simp	cid->oid = mmc_get_bits(raw_cid, 104, 8);
760183729Simp	for (i = 0; i < 6; i++)
761183729Simp		cid->pnm[i] = mmc_get_bits(raw_cid, 96 - i * 8, 8);
762183729Simp	cid->prv = mmc_get_bits(raw_cid, 48, 8);
763183729Simp	cid->psn = mmc_get_bits(raw_cid, 16, 32);
764183729Simp	cid->mdt_month = mmc_get_bits(raw_cid, 12, 4);
765183729Simp	cid->mdt_year = mmc_get_bits(raw_cid, 8, 4) + 1997;
766183729Simp}
767183729Simp
768163516Simpstatic const int exp[8] = {
769163516Simp	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
770163516Simp};
771163516Simpstatic const int mant[16] = {
772163516Simp	10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
773163516Simp};
774163516Simpstatic const int cur_min[8] = {
775163516Simp	500, 1000, 5000, 10000, 25000, 35000, 60000, 100000
776163516Simp};
777163516Simpstatic const int cur_max[8] = {
778163516Simp	1000, 5000, 10000, 25000, 35000, 45000, 800000, 200000
779163516Simp};
780163516Simp
781163516Simpstatic void
782183729Simpmmc_decode_csd_sd(uint32_t *raw_csd, struct mmc_csd *csd)
783163516Simp{
784163516Simp	int v;
785163516Simp	int m;
786163516Simp	int e;
787163516Simp
788163516Simp	memset(csd, 0, sizeof(*csd));
789183729Simp	csd->csd_structure = v = mmc_get_bits(raw_csd, 126, 2);
790183729Simp	if (v == 0) {
791183704Smav		m = mmc_get_bits(raw_csd, 115, 4);
792183704Smav		e = mmc_get_bits(raw_csd, 112, 3);
793183704Smav		csd->tacc = exp[e] * mant[m] + 9 / 10;
794183704Smav		csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
795183704Smav		m = mmc_get_bits(raw_csd, 99, 4);
796183704Smav		e = mmc_get_bits(raw_csd, 96, 3);
797183704Smav		csd->tran_speed = exp[e] * 10000 * mant[m];
798183704Smav		csd->ccc = mmc_get_bits(raw_csd, 84, 12);
799183704Smav		csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
800183704Smav		csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
801183704Smav		csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
802183704Smav		csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
803183704Smav		csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
804183704Smav		csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)];
805183704Smav		csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)];
806183704Smav		csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)];
807183704Smav		csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)];
808183704Smav		m = mmc_get_bits(raw_csd, 62, 12);
809183704Smav		e = mmc_get_bits(raw_csd, 47, 3);
810183704Smav		csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
811183729Simp		csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
812183729Simp		csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
813183729Simp		csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
814183704Smav		csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
815183704Smav		csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
816183704Smav		csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
817183704Smav		csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
818183729Simp	} else if (v == 1) {
819183729Simp		m = mmc_get_bits(raw_csd, 115, 4);
820183729Simp		e = mmc_get_bits(raw_csd, 112, 3);
821183729Simp		csd->tacc = exp[e] * mant[m] + 9 / 10;
822183729Simp		csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
823183729Simp		m = mmc_get_bits(raw_csd, 99, 4);
824183729Simp		e = mmc_get_bits(raw_csd, 96, 3);
825183729Simp		csd->tran_speed = exp[e] * 10000 * mant[m];
826183729Simp		csd->ccc = mmc_get_bits(raw_csd, 84, 12);
827183729Simp		csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
828183729Simp		csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
829183729Simp		csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
830183729Simp		csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
831183729Simp		csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
832183729Simp		csd->capacity = ((uint64_t)mmc_get_bits(raw_csd, 48, 22) + 1) *
833183729Simp		    512 * 1024;
834183729Simp		csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
835183729Simp		csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
836183729Simp		csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 7);
837183729Simp		csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
838183729Simp		csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
839183729Simp		csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
840183729Simp		csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
841183729Simp	} else
842183729Simp		panic("unknown SD CSD version");
843163516Simp}
844163516Simp
845183704Smavstatic void
846183729Simpmmc_decode_csd_mmc(uint32_t *raw_csd, struct mmc_csd *csd)
847183729Simp{
848183729Simp	int m;
849183729Simp	int e;
850183729Simp
851183729Simp	memset(csd, 0, sizeof(*csd));
852183729Simp	csd->csd_structure = mmc_get_bits(raw_csd, 126, 2);
853183729Simp	csd->spec_vers = mmc_get_bits(raw_csd, 122, 4);
854183729Simp	m = mmc_get_bits(raw_csd, 115, 4);
855183729Simp	e = mmc_get_bits(raw_csd, 112, 3);
856183729Simp	csd->tacc = exp[e] * mant[m] + 9 / 10;
857183729Simp	csd->nsac = mmc_get_bits(raw_csd, 104, 8) * 100;
858183729Simp	m = mmc_get_bits(raw_csd, 99, 4);
859183729Simp	e = mmc_get_bits(raw_csd, 96, 3);
860183729Simp	csd->tran_speed = exp[e] * 10000 * mant[m];
861183729Simp	csd->ccc = mmc_get_bits(raw_csd, 84, 12);
862183729Simp	csd->read_bl_len = 1 << mmc_get_bits(raw_csd, 80, 4);
863183729Simp	csd->read_bl_partial = mmc_get_bits(raw_csd, 79, 1);
864183729Simp	csd->write_blk_misalign = mmc_get_bits(raw_csd, 78, 1);
865183729Simp	csd->read_blk_misalign = mmc_get_bits(raw_csd, 77, 1);
866183729Simp	csd->dsr_imp = mmc_get_bits(raw_csd, 76, 1);
867183729Simp	csd->vdd_r_curr_min = cur_min[mmc_get_bits(raw_csd, 59, 3)];
868183729Simp	csd->vdd_r_curr_max = cur_max[mmc_get_bits(raw_csd, 56, 3)];
869183729Simp	csd->vdd_w_curr_min = cur_min[mmc_get_bits(raw_csd, 53, 3)];
870183729Simp	csd->vdd_w_curr_max = cur_max[mmc_get_bits(raw_csd, 50, 3)];
871183729Simp	m = mmc_get_bits(raw_csd, 62, 12);
872183729Simp	e = mmc_get_bits(raw_csd, 47, 3);
873183729Simp	csd->capacity = ((1 + m) << (e + 2)) * csd->read_bl_len;
874183729Simp//	csd->erase_blk_en = mmc_get_bits(raw_csd, 46, 1);
875183729Simp//	csd->sector_size = mmc_get_bits(raw_csd, 39, 7);
876183729Simp	csd->wp_grp_size = mmc_get_bits(raw_csd, 32, 5);
877183729Simp	csd->wp_grp_enable = mmc_get_bits(raw_csd, 31, 1);
878183729Simp	csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 26, 3);
879183729Simp	csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 22, 4);
880183729Simp	csd->write_bl_partial = mmc_get_bits(raw_csd, 21, 1);
881183729Simp}
882183729Simp
883183729Simpstatic void
884183704Smavmmc_app_decode_scr(uint32_t *raw_scr, struct mmc_scr *scr)
885183704Smav{
886183704Smav	unsigned int scr_struct;
887183704Smav	uint32_t tmp[4];
888183704Smav
889183704Smav	tmp[3] = raw_scr[1];
890183704Smav	tmp[2] = raw_scr[0];
891183704Smav
892183704Smav	memset(scr, 0, sizeof(*scr));
893183729Simp
894183704Smav	scr_struct = mmc_get_bits(tmp, 60, 4);
895183704Smav	if (scr_struct != 0) {
896183704Smav		printf("Unrecognised SCR structure version %d\n",
897183704Smav		    scr_struct);
898183704Smav		return;
899183704Smav	}
900183704Smav	scr->sda_vsn = mmc_get_bits(tmp, 56, 4);
901183704Smav	scr->bus_widths = mmc_get_bits(tmp, 48, 4);
902183704Smav}
903183704Smav
904163516Simpstatic int
905163516Simpmmc_all_send_cid(struct mmc_softc *sc, uint32_t *rawcid)
906163516Simp{
907163516Simp	struct mmc_command cmd;
908163516Simp	int err;
909163516Simp
910163516Simp	cmd.opcode = MMC_ALL_SEND_CID;
911163516Simp	cmd.arg = 0;
912163516Simp	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
913183470Simp	cmd.data = NULL;
914163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
915163516Simp	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
916163516Simp	return (err);
917163516Simp}
918163516Simp
919163516Simpstatic int
920163516Simpmmc_send_csd(struct mmc_softc *sc, uint16_t rca, uint32_t *rawcid)
921163516Simp{
922163516Simp	struct mmc_command cmd;
923163516Simp	int err;
924163516Simp
925163516Simp	cmd.opcode = MMC_SEND_CSD;
926163516Simp	cmd.arg = rca << 16;
927163516Simp	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
928183470Simp	cmd.data = NULL;
929163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
930163516Simp	memcpy(rawcid, cmd.resp, 4 * sizeof(uint32_t));
931163516Simp	return (err);
932163516Simp}
933163516Simp
934163516Simpstatic int
935183704Smavmmc_app_send_scr(struct mmc_softc *sc, uint16_t rca, uint32_t *rawscr)
936183704Smav{
937183704Smav	int err;
938183704Smav	struct mmc_command cmd;
939183704Smav	struct mmc_data data;
940183704Smav
941183704Smav	memset(&cmd, 0, sizeof(struct mmc_command));
942183704Smav	memset(&data, 0, sizeof(struct mmc_data));
943183704Smav
944183704Smav	memset(rawscr, 0, 8);
945183704Smav	cmd.opcode = ACMD_SEND_SCR;
946183704Smav	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
947183704Smav	cmd.arg = 0;
948183704Smav	cmd.data = &data;
949183704Smav
950183704Smav	data.data = rawscr;
951183704Smav	data.len = 8;
952183704Smav	data.flags = MMC_DATA_READ;
953183704Smav
954183704Smav	err = mmc_wait_for_app_cmd(sc, rca, &cmd, CMD_RETRIES);
955183704Smav	rawscr[0] = be32toh(rawscr[0]);
956183704Smav	rawscr[1] = be32toh(rawscr[1]);
957183704Smav	return (err);
958183704Smav}
959183704Smav
960183704Smavstatic int
961183704Smavmmc_send_ext_csd(struct mmc_softc *sc, uint8_t *rawextcsd)
962183704Smav{
963183704Smav	int err;
964183704Smav	struct mmc_command cmd;
965183704Smav	struct mmc_data data;
966183704Smav
967183704Smav	memset(&cmd, 0, sizeof(struct mmc_command));
968183704Smav	memset(&data, 0, sizeof(struct mmc_data));
969183704Smav
970183704Smav	memset(rawextcsd, 0, 512);
971183704Smav	cmd.opcode = MMC_SEND_EXT_CSD;
972183704Smav	cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
973183704Smav	cmd.arg = 0;
974183704Smav	cmd.data = &data;
975183704Smav
976183704Smav	data.data = rawextcsd;
977183704Smav	data.len = 512;
978183704Smav	data.flags = MMC_DATA_READ;
979183704Smav
980183704Smav	err = mmc_wait_for_cmd(sc, &cmd, CMD_RETRIES);
981183704Smav	return (err);
982183704Smav}
983183704Smav
984183704Smavstatic int
985183704Smavmmc_set_relative_addr(struct mmc_softc *sc, uint16_t resp)
986183704Smav{
987183704Smav	struct mmc_command cmd;
988183704Smav	int err;
989183704Smav
990183704Smav	cmd.opcode = MMC_SET_RELATIVE_ADDR;
991183704Smav	cmd.arg = resp << 16;
992183704Smav	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
993183704Smav	cmd.data = NULL;
994183704Smav	err = mmc_wait_for_cmd(sc, &cmd, 0);
995183704Smav	return (err);
996183704Smav}
997183704Smav
998183704Smavstatic int
999163516Simpmmc_send_relative_addr(struct mmc_softc *sc, uint32_t *resp)
1000163516Simp{
1001163516Simp	struct mmc_command cmd;
1002163516Simp	int err;
1003163516Simp
1004163516Simp	cmd.opcode = SD_SEND_RELATIVE_ADDR;
1005163516Simp	cmd.arg = 0;
1006163516Simp	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
1007183470Simp	cmd.data = NULL;
1008163516Simp	err = mmc_wait_for_cmd(sc, &cmd, 0);
1009163516Simp	*resp = cmd.resp[0];
1010163516Simp	return (err);
1011163516Simp}
1012163516Simp
1013163516Simpstatic void
1014163516Simpmmc_discover_cards(struct mmc_softc *sc)
1015163516Simp{
1016163516Simp	struct mmc_ivars *ivar;
1017163516Simp	int err;
1018183731Smav	uint32_t resp, sec_count;
1019163516Simp	device_t child;
1020183704Smav	uint16_t rca = 2;
1021183704Smav	u_char switch_res[64];
1022163516Simp
1023163516Simp	while (1) {
1024183468Simp		ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF,
1025183468Simp		    M_WAITOK | M_ZERO);
1026169567Simp		if (!ivar)
1027169567Simp			return;
1028163516Simp		err = mmc_all_send_cid(sc, ivar->raw_cid);
1029163516Simp		if (err == MMC_ERR_TIMEOUT)
1030163516Simp			break;
1031163516Simp		if (err != MMC_ERR_NONE) {
1032183468Simp			device_printf(sc->dev, "Error reading CID %d\n", err);
1033163516Simp			break;
1034163516Simp		}
1035183704Smav		if (mmcbr_get_ro(sc->dev))
1036183704Smav			ivar->read_only = 1;
1037183704Smav		ivar->bus_width = bus_width_1;
1038183704Smav		ivar->mode = mmcbr_get_mode(sc->dev);
1039183704Smav		if (ivar->mode == mode_sd) {
1040183729Simp			mmc_decode_cid_sd(ivar->raw_cid, &ivar->cid);
1041163516Simp			mmc_send_relative_addr(sc, &resp);
1042163516Simp			ivar->rca = resp >> 16;
1043183704Smav			/* Get card CSD. */
1044163516Simp			mmc_send_csd(sc, ivar->rca, ivar->raw_csd);
1045183729Simp			mmc_decode_csd_sd(ivar->raw_csd, &ivar->csd);
1046183731Smav			ivar->sec_count = ivar->csd.capacity / MMC_SECTOR_SIZE;
1047183704Smav			if (ivar->csd.csd_structure > 0)
1048183704Smav				ivar->high_cap = 1;
1049183704Smav			ivar->tran_speed = ivar->csd.tran_speed;
1050183704Smav			/* Get card SCR. Card must be selected to fetch it. */
1051183704Smav			mmc_select_card(sc, ivar->rca);
1052183704Smav			mmc_app_send_scr(sc, ivar->rca, ivar->raw_scr);
1053183704Smav			mmc_app_decode_scr(ivar->raw_scr, &ivar->scr);
1054183704Smav			/* Get card switch capabilities. */
1055183704Smav			if ((ivar->scr.sda_vsn >= 1) &&
1056183704Smav			    (ivar->csd.ccc & (1<<10))) {
1057183704Smav				mmc_sd_switch(sc, 0, 0, 0xF, switch_res);
1058183704Smav				if (switch_res[13] & 2) {
1059183704Smav					ivar->timing = bus_timing_hs;
1060183704Smav					ivar->hs_tran_speed = 50000000;
1061183704Smav				}
1062183704Smav			}
1063183704Smav			mmc_select_card(sc, 0);
1064183704Smav			/* Find max supported bus width. */
1065183704Smav			if ((mmcbr_get_caps(sc->dev) & MMC_CAP_4_BIT_DATA) &&
1066183704Smav			    (ivar->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
1067183704Smav				ivar->bus_width = bus_width_4;
1068183704Smav			/* Add device. */
1069163516Simp			child = device_add_child(sc->dev, NULL, -1);
1070163516Simp			device_set_ivars(child, ivar);
1071169567Simp			return;
1072163516Simp		}
1073183729Simp		mmc_decode_cid_mmc(ivar->raw_cid, &ivar->cid);
1074183704Smav		ivar->rca = rca++;
1075183704Smav		mmc_set_relative_addr(sc, ivar->rca);
1076183704Smav		/* Get card CSD. */
1077183704Smav		mmc_send_csd(sc, ivar->rca, ivar->raw_csd);
1078183729Simp		mmc_decode_csd_mmc(ivar->raw_csd, &ivar->csd);
1079183731Smav		ivar->sec_count = ivar->csd.capacity / MMC_SECTOR_SIZE;
1080183704Smav		ivar->tran_speed = ivar->csd.tran_speed;
1081183704Smav		/* Only MMC >= 4.x cards support EXT_CSD. */
1082183704Smav		if (ivar->csd.spec_vers >= 4) {
1083183704Smav			/* Card must be selected to fetch EXT_CSD. */
1084183704Smav			mmc_select_card(sc, ivar->rca);
1085183704Smav			mmc_send_ext_csd(sc, ivar->raw_ext_csd);
1086183731Smav			/* Handle extended capacity from EXT_CSD */
1087183731Smav			sec_count = ivar->raw_ext_csd[EXT_CSD_SEC_CNT] +
1088183731Smav			    (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 1] << 8) +
1089183731Smav			    (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 2] << 16) +
1090183731Smav			    (ivar->raw_ext_csd[EXT_CSD_SEC_CNT + 3] << 24);
1091183731Smav			if (sec_count != 0) {
1092183731Smav				ivar->sec_count = sec_count;
1093183731Smav				ivar->high_cap = 1;
1094183731Smav			}
1095183704Smav			/* Get card speed in high speed mode. */
1096183704Smav			ivar->timing = bus_timing_hs;
1097183731Smav			if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE]
1098183704Smav			    & EXT_CSD_CARD_TYPE_52)
1099183704Smav				ivar->hs_tran_speed = 52000000;
1100183731Smav			else if (ivar->raw_ext_csd[EXT_CSD_CARD_TYPE]
1101183704Smav			    & EXT_CSD_CARD_TYPE_26)
1102183704Smav				ivar->hs_tran_speed = 26000000;
1103183704Smav			else
1104183704Smav				ivar->hs_tran_speed = ivar->tran_speed;
1105183704Smav			/* Find max supported bus width. */
1106183704Smav			ivar->bus_width = mmc_test_bus_width(sc);
1107183704Smav			mmc_select_card(sc, 0);
1108183704Smav		} else {
1109183704Smav			ivar->bus_width = bus_width_1;
1110183704Smav			ivar->timing = bus_timing_normal;
1111183704Smav		}
1112183704Smav		/* Add device. */
1113183704Smav		child = device_add_child(sc->dev, NULL, -1);
1114183704Smav		device_set_ivars(child, ivar);
1115163516Simp	}
1116169567Simp	free(ivar, M_DEVBUF);
1117163516Simp}
1118163516Simp
1119163516Simpstatic void
1120163516Simpmmc_go_discovery(struct mmc_softc *sc)
1121163516Simp{
1122163516Simp	uint32_t ocr;
1123163516Simp	device_t dev;
1124183704Smav	int err;
1125163516Simp
1126163516Simp	dev = sc->dev;
1127163516Simp	if (mmcbr_get_power_mode(dev) != power_on) {
1128183453Simp		/*
1129183453Simp		 * First, try SD modes
1130183453Simp		 */
1131163516Simp		mmcbr_set_mode(dev, mode_sd);
1132163516Simp		mmc_power_up(sc);
1133163516Simp		mmcbr_set_bus_mode(dev, pushpull);
1134163516Simp		mmc_idle_cards(sc);
1135183704Smav		err = mmc_send_if_cond(sc, 1);
1136183704Smav		if (mmc_send_app_op_cond(sc, err?0:MMC_OCR_CCS, &ocr) !=
1137183704Smav		    MMC_ERR_NONE) {
1138183453Simp			/*
1139183453Simp			 * Failed, try MMC
1140183453Simp			 */
1141163516Simp			mmcbr_set_mode(dev, mode_mmc);
1142163516Simp			if (mmc_send_op_cond(sc, 0, &ocr) != MMC_ERR_NONE)
1143183453Simp				return;	/* Failed both, punt! XXX powerdown? */
1144163516Simp		}
1145163516Simp		mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
1146163516Simp		if (mmcbr_get_ocr(dev) != 0)
1147163516Simp			mmc_idle_cards(sc);
1148163516Simp	} else {
1149163516Simp		mmcbr_set_bus_mode(dev, opendrain);
1150163516Simp		mmcbr_set_clock(dev, mmcbr_get_f_min(dev));
1151163516Simp		mmcbr_update_ios(dev);
1152183453Simp		/* XXX recompute vdd based on new cards? */
1153163516Simp	}
1154163516Simp	/*
1155163516Simp	 * Make sure that we have a mutually agreeable voltage to at least
1156163516Simp	 * one card on the bus.
1157163516Simp	 */
1158163516Simp	if (mmcbr_get_ocr(dev) == 0)
1159163516Simp		return;
1160163516Simp	/*
1161163516Simp	 * Reselect the cards after we've idled them above.
1162163516Simp	 */
1163183704Smav	if (mmcbr_get_mode(dev) == mode_sd) {
1164183704Smav		err = mmc_send_if_cond(sc, 1);
1165183704Smav		mmc_send_app_op_cond(sc,
1166183704Smav		    (err?0:MMC_OCR_CCS)|mmcbr_get_ocr(dev), NULL);
1167183704Smav	} else
1168163516Simp		mmc_send_op_cond(sc, mmcbr_get_ocr(dev), NULL);
1169163516Simp	mmc_discover_cards(sc);
1170163516Simp
1171163516Simp	mmcbr_set_bus_mode(dev, pushpull);
1172163516Simp	mmcbr_update_ios(dev);
1173183763Smav	mmc_calculate_clock(sc);
1174163516Simp	bus_generic_attach(dev);
1175183453Simp/*	mmc_update_children_sysctl(dev);*/
1176163516Simp}
1177163516Simp
1178163516Simpstatic int
1179163516Simpmmc_calculate_clock(struct mmc_softc *sc)
1180163516Simp{
1181183704Smav	int max_dtr, max_hs_dtr, max_timing;
1182163516Simp	int nkid, i, f_min, f_max;
1183163516Simp	device_t *kids;
1184183704Smav	struct mmc_ivars *ivar;
1185163516Simp
1186163516Simp	f_min = mmcbr_get_f_min(sc->dev);
1187163516Simp	f_max = mmcbr_get_f_max(sc->dev);
1188183704Smav	max_dtr = max_hs_dtr = f_max;
1189183704Smav	if ((mmcbr_get_caps(sc->dev) & MMC_CAP_HSPEED))
1190183704Smav		max_timing = bus_timing_hs;
1191183704Smav	else
1192183704Smav		max_timing = bus_timing_normal;
1193163516Simp	if (device_get_children(sc->dev, &kids, &nkid) != 0)
1194163516Simp		panic("can't get children");
1195183704Smav	for (i = 0; i < nkid; i++) {
1196183704Smav		ivar = device_get_ivars(kids[i]);
1197183704Smav		if (ivar->timing < max_timing)
1198183704Smav			max_timing = ivar->timing;
1199183704Smav		if (ivar->tran_speed < max_dtr)
1200183704Smav			max_dtr = ivar->tran_speed;
1201183704Smav		if (ivar->hs_tran_speed < max_dtr)
1202183704Smav			max_hs_dtr = ivar->hs_tran_speed;
1203183704Smav	}
1204183704Smav	for (i = 0; i < nkid; i++) {
1205183704Smav		ivar = device_get_ivars(kids[i]);
1206183704Smav		if (ivar->timing == bus_timing_normal)
1207183704Smav			continue;
1208183704Smav		mmc_select_card(sc, ivar->rca);
1209183704Smav		mmc_set_timing(sc, max_timing);
1210183704Smav	}
1211183704Smav	mmc_select_card(sc, 0);
1212163516Simp	free(kids, M_TEMP);
1213183704Smav	if (max_timing == bus_timing_hs)
1214183704Smav		max_dtr = max_hs_dtr;
1215183763Smav	if (bootverbose) {
1216183763Smav		device_printf(sc->dev, "setting transfer rate to %d.%03dMHz%s\n",
1217183763Smav		    max_dtr / 1000000, (max_dtr / 1000) % 1000,
1218183763Smav		    (max_timing == bus_timing_hs)?" with high speed timing":"");
1219183763Smav	}
1220183704Smav	mmcbr_set_timing(sc->dev, max_timing);
1221183704Smav	mmcbr_set_clock(sc->dev, max_dtr);
1222183704Smav	mmcbr_update_ios(sc->dev);
1223183704Smav	return max_dtr;
1224163516Simp}
1225163516Simp
1226163516Simpstatic void
1227163516Simpmmc_scan(struct mmc_softc *sc)
1228163516Simp{
1229163516Simp	device_t dev;
1230163516Simp
1231163516Simp	dev = sc->dev;
1232163516Simp	mmc_acquire_bus(dev, dev);
1233163516Simp
1234163516Simp	if (mmcbr_get_power_mode(dev) == power_on)
1235163516Simp		mmc_rescan_cards(sc);
1236163516Simp	mmc_go_discovery(sc);
1237163516Simp
1238163516Simp	mmc_release_bus(dev, dev);
1239183453Simp	/* XXX probe/attach/detach children? */
1240163516Simp}
1241163516Simp
1242163516Simpstatic int
1243163516Simpmmc_read_ivar(device_t bus, device_t child, int which, u_char *result)
1244163516Simp{
1245163516Simp	struct mmc_ivars *ivar = device_get_ivars(child);
1246163516Simp
1247163516Simp	switch (which) {
1248163516Simp	default:
1249163516Simp		return (EINVAL);
1250163516Simp	case MMC_IVAR_DSR_IMP:
1251163516Simp		*(int *)result = ivar->csd.dsr_imp;
1252163516Simp		break;
1253163516Simp	case MMC_IVAR_MEDIA_SIZE:
1254183731Smav		*(off_t *)result = ivar->sec_count;
1255163516Simp		break;
1256163516Simp	case MMC_IVAR_RCA:
1257163516Simp		*(int *)result = ivar->rca;
1258163516Simp		break;
1259163516Simp	case MMC_IVAR_SECTOR_SIZE:
1260183542Simp		*(int *)result = MMC_SECTOR_SIZE;
1261163516Simp		break;
1262163516Simp	case MMC_IVAR_TRAN_SPEED:
1263183763Smav		*(int *)result = mmcbr_get_clock(bus);
1264163516Simp		break;
1265183447Simp	case MMC_IVAR_READ_ONLY:
1266183447Simp		*(int *)result = ivar->read_only;
1267183447Simp		break;
1268183704Smav	case MMC_IVAR_HIGH_CAP:
1269183704Smav		*(int *)result = ivar->high_cap;
1270183704Smav		break;
1271183763Smav	case MMC_IVAR_CARD_TYPE:
1272183763Smav		*(int *)result = ivar->mode;
1273183763Smav		break;
1274183763Smav	case MMC_IVAR_BUS_WIDTH:
1275183763Smav		*(int *)result = ivar->bus_width;
1276183763Smav		break;
1277163516Simp	}
1278163516Simp	return (0);
1279163516Simp}
1280163516Simp
1281163516Simpstatic int
1282163516Simpmmc_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
1283163516Simp{
1284183453Simp	/*
1285183453Simp	 * None are writable ATM
1286183453Simp	 */
1287183453Simp	return (EINVAL);
1288163516Simp}
1289163516Simp
1290163516Simp
1291163516Simpstatic void
1292163516Simpmmc_delayed_attach(void *xsc)
1293163516Simp{
1294163516Simp	struct mmc_softc *sc = xsc;
1295163516Simp
1296163516Simp	mmc_scan(sc);
1297163516Simp	config_intrhook_disestablish(&sc->config_intrhook);
1298163516Simp}
1299163516Simp
1300163516Simpstatic device_method_t mmc_methods[] = {
1301163516Simp	/* device_if */
1302163516Simp	DEVMETHOD(device_probe, mmc_probe),
1303163516Simp	DEVMETHOD(device_attach, mmc_attach),
1304163516Simp	DEVMETHOD(device_detach, mmc_detach),
1305163516Simp
1306163516Simp	/* Bus interface */
1307163516Simp	DEVMETHOD(bus_read_ivar, mmc_read_ivar),
1308163516Simp	DEVMETHOD(bus_write_ivar, mmc_write_ivar),
1309163516Simp
1310163516Simp	/* MMC Bus interface */
1311163516Simp	DEVMETHOD(mmcbus_wait_for_request, mmc_wait_for_request),
1312163516Simp	DEVMETHOD(mmcbus_acquire_bus, mmc_acquire_bus),
1313163516Simp	DEVMETHOD(mmcbus_release_bus, mmc_release_bus),
1314163516Simp
1315163516Simp	{0, 0},
1316163516Simp};
1317163516Simp
1318163516Simpstatic driver_t mmc_driver = {
1319163516Simp	"mmc",
1320163516Simp	mmc_methods,
1321163516Simp	sizeof(struct mmc_softc),
1322163516Simp};
1323163516Simpstatic devclass_t mmc_devclass;
1324163516Simp
1325163516Simp
1326163516SimpDRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0);
1327183708SmavDRIVER_MODULE(mmc, sdhci, mmc_driver, mmc_devclass, 0, 0);
1328