Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Sep 2006 00:52:06 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 106533 for review
Message-ID:  <200609230052.k8N0q6Dw091998@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=106533

Change 106533 by imp@imp_lighthouse on 2006/09/23 00:51:28

	bridge driver, needs work.

Affected files ...

.. //depot/projects/arm/src/sys/arm/at91/at91_mci.c#2 edit
.. //depot/projects/arm/src/sys/arm/at91/at91_mcireg.h#2 edit
.. //depot/projects/arm/src/sys/arm/conf/TSC4370#8 edit

Differences ...

==== //depot/projects/arm/src/sys/arm/at91/at91_mci.c#2 (text+ko) ====

@@ -1,5 +1,6 @@
 /*-
- * Copyright (c) 2005 Olivier Houchard.  All rights reserved.
+ * Copyright (c) 2006 Berndt Walter.  All rights reserved.
+ * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -50,13 +51,10 @@
 #include <machine/intr.h>
 #include <arm/at91/at91rm92reg.h>
 #include <arm/at91/at91var.h>
-#include <dev/mmc/mmcreg.h>
-#include <arm/at91/at91_qdmmcreg.h>
+#include <arm/at91/at91_mcireg.h>
 #include <arm/at91/at91_pdcreg.h>
 
-#include <geom/geom_disk.h>
-
-struct at91_qdmmc_softc {
+struct at91_mci_softc {
 	void *intrhand;			/* Interrupt handle */
 	device_t dev;
 	struct resource *irq_res;	/* IRQ resource */
@@ -67,450 +65,82 @@
 	struct disk *disk;		/* XXX support only one card for */
 	int nb_cards;
 	struct proc *p;
-	struct {
-		struct bio_queue_head bio_queue;
-		char name[7];
-		uint32_t addr;
-		uint32_t CID[4];
-		uint32_t CSD[4];
-		uint32_t sector_size;
-		uint64_t size;
-		uint32_t mode;
-		uint32_t flags;
-#define READ_PARTIAL	0x001
-#define WRITE_PARTIAL	0x002
-#define ERASE_BLOCK_EN	0x004
-#define	READ_MISALIGN	0x008
-#define WRITE_MISALIGN	0x010
-		uint32_t read_bl;
-		uint32_t write_bl;
-	} cards[MMC_MAX];
 };
 
 static inline uint32_t
-RD4(struct at91_qdmmc_softc *sc, bus_size_t off)
+RD4(struct at91_mci_softc *sc, bus_size_t off)
 {
 	return bus_read_4(sc->mem_res, off);
 }
 
 static inline void
-WR4(struct at91_qdmmc_softc *sc, bus_size_t off, uint32_t val)
+WR4(struct at91_mci_softc *sc, bus_size_t off, uint32_t val)
 {
 	bus_write_4(sc->mem_res, off, val);
 }
 
 /* bus entry points */
-static int at91_qdmmc_probe(device_t dev);
-static int at91_qdmmc_attach(device_t dev);
-static int at91_qdmmc_detach(device_t dev);
-static void at91_qdmmc_intr(void *);
+static int at91_mci_probe(device_t dev);
+static int at91_mci_attach(device_t dev);
+static int at91_mci_detach(device_t dev);
+static void at91_mci_intr(void *);
 
 /* helper routines */
-static int at91_qdmmc_activate(device_t dev);
-static void at91_qdmmc_deactivate(device_t dev);
+static int at91_mci_activate(device_t dev);
+static void at91_mci_deactivate(device_t dev);
 
-/* disk routines */
-static int at91_qdmmc_open(struct disk *dp);
-static int at91_qdmmc_close(struct disk *dp);
-static void at91_qdmmc_strategy(struct bio *bp);
-static void at91_qdmmc_task(void *arg);
-
-#define AT91_QDMMC_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
-#define	AT91_QDMMC_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
-#define AT91_QDMMC_LOCK_INIT(_sc) \
+#define AT91_MCI_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	AT91_MCI_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define AT91_MCI_LOCK_INIT(_sc) \
 	mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \
-	    "qdmmc", MTX_DEF)
-#define AT91_QDMMC_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
-#define AT91_QDMMC_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
-#define AT91_QDMMC_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
+	    "mci", MTX_DEF)
+#define AT91_MCI_LOCK_DESTROY(_sc)	mtx_destroy(&_sc->sc_mtx);
+#define AT91_MCI_ASSERT_LOCKED(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED);
+#define AT91_MCI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
 
-static int
-at91_qdmmc_SendCommand(device_t dev, uint32_t cmd, uint32_t arg)
+static void
+at91_mci_init(device_t dev)
 {
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-	uint32_t error;
+	struct at91_mci_softc *sc = device_get_softc(dev);
 
-	device_printf(dev, "Sending command %x:%x\n", cmd, arg);
-	WR4(sc, MCI_ARGR, arg);
-	WR4(sc, MCI_CMDR, cmd);
-
-	while (!(RD4(sc, MCI_SR) & MCI_SR_CMDRDY))
-		continue;
-
-	error = RD4(sc, MCI_SR) & MCI_SR_ERROR;
-	if (error) {
-		if ((cmd != SDCARD_APP_OP_COND_CMD) &&
-		    (cmd != MMC_SEND_OP_COND_CMD)) {
-			//printf("qdmmc: Error 0x%x\n", error);
-			return (error);
-		}
-		if (error != MCI_SR_RCRCE) {
-			//printf("qdmmc: Error 0x%x\n", error);
-			return (error);
-		}
-	}
-	return (0);
+	WR4(sc, MCI_CR, MCI_CR_MCIEN);		/* Enable controller */
+	WR4(sc, MCI_IDR, 0xffffffff);		/* Turn off interrupts */
+	WR4(sc, MCI_DTOR, MCI_DTOR_DTOMUL_1M | MCI_DTOR_DTOCYC);
+	WR4(sc, MCI_MR, 0x834a);	// XXX GROSS HACK FROM LINUX
+	WR4(sc, MCI_SDCR, 0);			/* SLOT A, 1 bit bus */
 }
 
-static int
-at91_qdmmc_SDCard_SendAppCommand(device_t dev, uint32_t cmd, uint32_t arg)
+static void
+at91_mci_fini(device_t dev)
 {
-	uint32_t status;
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
+	struct at91_mci_softc *sc = device_get_softc(dev);
 
-	// Send the CMD55 for application specific command
-	WR4(sc, MCI_ARGR, sc->cards[0].addr << 16);
-	WR4(sc, MCI_CMDR, APP_CMD);
-
-	printf("CMD55: %x\n", sc->cards[0].addr << 16);
-
-	// wait for CMDRDY Status flag to read the response
-	do
-	{
-		status = RD4(sc, MCI_SR);
-	} while(!(status & MCI_SR_CMDRDY));
-
-	// if an error occurs
-	if ((status & MCI_SR_ERROR) != 0 )
-		return (status & MCI_SR_ERROR);
-
-	return (at91_qdmmc_SendCommand(dev, cmd, arg));
+	WR4(sc, MCI_IDR, 0xffffffff);		/* Turn off interrupts */
+	WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST); /* Put the device into reset */
 }
 
 static int
-at91_qdmmc_probe(device_t dev)
+at91_mci_probe(device_t dev)
 {
 
-	//printf("at91_qdmmc_probe: called\n");
-	device_set_desc(dev, "MMC");
+	device_set_desc(dev, "MCI mmc/sd host bridge");
 	return (0);
 }
 
 static int
-at91_qdmmc_SDCard_GetOCR(device_t dev)
-{
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-	uint32_t response = 0;
-
-	// The RCA to be used for CMD55 in Idle state shall be the card's
-	// default RCA=0x0000.
-	sc->cards[0].addr = 0;
- 	while(!(response & AT91C_CARD_POWER_UP_BUSY)) {
-		response = at91_qdmmc_SDCard_SendAppCommand(dev,
-		    SDCARD_APP_OP_COND_CMD, AT91C_MMC_HOST_VOLTAGE_RANGE);
-		if (response != 0)
-			return (-1);
-		response = RD4(sc, MCI_RSPR);
-		printf("card's OCR is %#x\n", response);
-	}
-	
-	return (response);
-}
-
-static int
-at91_qdmmc_GetCID(device_t dev, uint32_t *response)
-{
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-
-	if (at91_qdmmc_SendCommand(dev, ALL_SEND_CID_CMD, 0))
-		return EIO;
-	response[0] = RD4(sc, MCI_RSPR + 0 * sizeof(response[0]));
-   	response[1] = RD4(sc, MCI_RSPR + 1 * sizeof(response[0]));
-	response[2] = RD4(sc, MCI_RSPR + 2 * sizeof(response[0]));
-	response[3] = RD4(sc, MCI_RSPR + 3 * sizeof(response[0]));
-	return 0;
-}
-
-static int
-at91_qdmmc_GetCSD(device_t dev, uint32_t rca, uint32_t *response)
-{
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-
-	if (at91_qdmmc_SendCommand(dev, SEND_CSD_CMD, rca << 16))
-		return EIO;
-	response[0] = RD4(sc, MCI_RSPR + 0 * sizeof(response[0]));
-   	response[1] = RD4(sc, MCI_RSPR + 1 * sizeof(response[0]));
-	response[2] = RD4(sc, MCI_RSPR + 2 * sizeof(response[0]));
-	response[3] = RD4(sc, MCI_RSPR + 3 * sizeof(response[0]));
-	return 0;
-}
-
-static uint32_t
-at91_qdmmc_GetStatus(device_t dev, uint32_t rca)
-{
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-
-	if (at91_qdmmc_SendCommand(dev, SEND_STATUS_CMD, rca << 16) == 0)
-		return (RD4(sc, MCI_RSPR));
-	return 0xffffffff;
-}
-
-static int
-at91_qdmmc_SetBlocklength(device_t dev, uint32_t length)
-{
-	return (at91_qdmmc_SendCommand(dev, SET_BLOCKLEN_CMD, length) );
-}
-
-static int
-at91_qdmmc_SDCard_SetBusWidth(device_t dev)
-{
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-	uint32_t ret_value, rca;
-	char bus_width;
-
-	rca = sc->cards[0].addr;
-	do {
-		ret_value = at91_qdmmc_GetStatus(dev, rca);
-	} while (ret_value != 0xffffffff &&
-	    !(ret_value & AT91C_SR_READY_FOR_DATA));
-
-	// Select Card
-	at91_qdmmc_SendCommand(dev, SEL_DESEL_CARD_CMD, rca << 16);
-
-	// XXX hard code 1.
-	bus_width = AT91C_BUS_WIDTH_1BIT;
-	printf("Setting bus width to 1 bit\n");
-	if (at91_qdmmc_SDCard_SendAppCommand(dev, SDCARD_SET_BUS_WIDTH_CMD,
-	    bus_width) != 0)
-		return EIO;
-
-	return 0;
-}
-
-static int
-at91_qdmmc_sdcard_init(device_t dev)
-{
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-	uint32_t	*csd, *cid;
-
-	// CMD0
-	at91_qdmmc_SendCommand(dev, GO_IDLE_STATE_CMD, 0);
-
-	if (at91_qdmmc_SDCard_GetOCR(dev) == -1) { // ACMD41
-		printf("SD: can't get OCR\n");
-		return ENXIO;
-	}
-	cid = &sc->cards[0].CID[0];
-	if (at91_qdmmc_GetCID(dev, cid) != 0) {	// CMD2
-		printf("SD: cant get cid\n");
-		return ENXIO;
-	}
-	if (at91_qdmmc_SendCommand(dev, SET_RELATIVE_ADDR_CMD, 0) != 0) {
-		printf("SD: Can't set RCA to 0\n");
-		return ENXIO;
-	}
-	sc->cards[0].addr = RD4(sc, MCI_RSPR) >> 16;
-	printf("SD Card at %#x\n", sc->cards[0].addr);
-	csd = &sc->cards[0].CSD[0];
-	if (at91_qdmmc_GetCSD(dev, sc->cards[0].addr, csd) != 0) {
-		printf("SD: can't get csd\n");
-		return ENXIO;
-	}
-	printf("SD Card - CID = 0x%08x%08x%08x%08x\n",
-	    cid[0],
-	    cid[1],
-	    cid[2],
-	    cid[3]);
-	printf("SD - CSD = 0x%08x%08x%08x%08x\n", csd[0], csd[1], csd[2],
-	    csd[3]);
-	printf("SD: Vendor-ID = 0x%x\n", cid[0] >> 24);
-	printf("SD: OEM-ID = 0x%x\n", (cid[0] >> 8) & 0xffff);
-	sc->cards[0].name[0] = (cid[0] >> 0) & 0xff;
-	sc->cards[0].name[1] = (cid[1] >> 24) & 0xff;
-	sc->cards[0].name[2] = (cid[1] >> 16) & 0xff;
-	sc->cards[0].name[3] = (cid[1] >> 8) & 0xff;
-	sc->cards[0].name[4] = (cid[1] >> 0) & 0xff;
-	sc->cards[0].name[5] = (cid[2] >> 24) & 0xff;
-	sc->cards[0].name[6] = '\0';
-	printf("SD: Productname = %s\n", sc->cards[0].name);
-	printf("SD: Revision = 0x%x\n", (cid[2] >> 16) & 0xff);
-	printf("SD: Serial = 0x%x\n", (cid[2] << 16) |
-	    (cid[3] >> 16));
-	int year = 2001;
-	year += ((cid[3] >> 8) & 0xf);
-	int month = 0;
-	month += ((cid[3] >> 12) & 0xf);
-	printf("SD: Manufacturing Date = %i/%i\n", year, month);
-	sc->cards[0].mode = 5 * MCI_MR_CLKDIV | /* MCI_MR_PWSDIV |
-	    (MCI_MR_PWSDIV << 1) | */ MCI_MR_PDCMODE;
-//	sc->cards[0].mode = 75 * MCI_MR_CLKDIV | MCI_MR_PWSDIV |
-//	    (MCI_MR_PWSDIV << 1);
-	sc->cards[0].flags = 0;
-	if (sc->cards[0].CSD[1] & CSD_1_RD_B_PAR_M)
-		sc->cards[0].flags |= READ_PARTIAL;
-	if (sc->cards[0].CSD[3] & CSD_3_WBLOCK_P_M)
-		sc->cards[0].flags |= WRITE_PARTIAL;
-	sc->cards[0].read_bl = (csd[1] >> CSD_1_RD_B_LEN_S) &
-	    CSD_1_RD_B_LEN_M;
-	sc->cards[0].write_bl = (csd[3] >> CSD_3_WBLEN_S) &
-	    CSD_3_WBLEN_M;
-	bioq_init(&sc->cards[0].bio_queue);
-
-	sc->cards[0].sector_size = 1 << sc->cards[0].read_bl;
-	printf("SD: Blocksize = %i Bytes\n", sc->cards[0].sector_size);
-	uint64_t c_size;
-	uint64_t c_size_mult;
-	c_size = ((sc->cards[0].CSD[1] & CSD_1_CSIZE_H_M) << 2) |
-	    ((sc->cards[0].CSD[2] >> CSD_2_CSIZE_L_S) & CSD_2_CSIZE_L_M);
-	printf("SD: c_size = %lld\n", c_size);
-	c_size_mult = (sc->cards[0].CSD[2] >> CSD_2_C_SIZE_M_S) & 
-	    CSD_2_C_SIZE_M_M;
-	c_size_mult = 1 << (c_size_mult + 2);
-	printf("SD: c_size_mult = %lld\n", c_size_mult);
-	sc->cards[0].size = sc->cards[0].sector_size *
-	    (c_size + 1) * c_size_mult;
-	printf("SD: Size = %lld Bytes\n", sc->cards[0].size);
-	if (at91_qdmmc_SDCard_SetBusWidth(dev)) {
-		printf("Failed to set bus width");
-		return EIO;
-	}
-	if (at91_qdmmc_SetBlocklength(dev, sc->cards[0].sector_size) != 0) {
-		printf("Failed to set block length!\n");
-		return EIO;
-	}
-	sc->nb_cards++;
-	return 0;
-}
-
-static int
-at91_qdmmc_mmc_init(device_t dev)
-{
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
-	uint32_t cond;
-	int err;
-
-	err = 0;
-	/* get all cards into idle state */
-	at91_qdmmc_SendCommand(dev, MMC_GO_IDLE_STATE_CMD, 0);
-
-	/* check operating conditions */
-	do {	/* loop on busy */
-		err = at91_qdmmc_SendCommand(dev, MMC_SEND_OP_COND_CMD,
-		    AT91C_MMC_HOST_VOLTAGE_RANGE);
-		if (err != 0) {
-			err = ENXIO;
-			printf("No MMC cards found\n");
-			goto out;
-		}
-		cond = RD4(sc, MCI_RSPR);
-	} while ((cond & AT91C_CARD_POWER_UP_BUSY) == 0);
-	printf("at91_qdmmc_attach: operating conditions: 0x%x\n",
-	    cond & ~(AT91C_CARD_POWER_UP_BUSY));
-
-	/* now find our cards */
-	for(sc->nb_cards = 0; sc->nb_cards < MMC_MAX; sc->nb_cards++) {
-		int status;
-		int card = sc->nb_cards;
-		if (at91_qdmmc_GetCID(dev, sc->cards[card].CID))
-			break;
-		printf("Found MMC %i - CID = 0x%x%x%x%x\n", card,
-		    sc->cards[card].CID[0],
-		    sc->cards[card].CID[1],
-		    sc->cards[card].CID[2],
-		    sc->cards[card].CID[3]);
-		printf("MMC %i: Vendor-ID = 0x%x\n", card,
-		    sc->cards[card].CID[0] >> 24),
-		printf("MMC %i: OEM-ID = 0x%x\n", card,
-		    (sc->cards[card].CID[0] >> 8) & 0xffff),
-		sc->cards[card].name[0] = (sc->cards[card].CID[0] >> 0) & 0xff;
-		sc->cards[card].name[1] = (sc->cards[card].CID[1] >> 24) & 0xff;
-		sc->cards[card].name[2] = (sc->cards[card].CID[1] >> 16) & 0xff;
-		sc->cards[card].name[3] = (sc->cards[card].CID[1] >> 8) & 0xff;
-		sc->cards[card].name[4] = (sc->cards[card].CID[1] >> 0) & 0xff;
-		sc->cards[card].name[5] = (sc->cards[card].CID[2] >> 24) & 0xff;
-		sc->cards[card].name[6] = '\0';
-		printf("MMC %i: Productname = %s\n", card,
-		    sc->cards[card].name);
-		printf("MMC %i: Revision = 0x%x\n", card,
-		    (sc->cards[card].CID[2] >> 16) & 0xff),
-		printf("MMC %i: Serial = 0x%x\n", card,
-		    (sc->cards[card].CID[2] << 16) |
-		    (sc->cards[card].CID[3] >> 16));
-		int year = 1997;
-		year += ((sc->cards[card].CID[3] >> 8) & 0xf);
-		int month = 0;
-		month += ((sc->cards[card].CID[3] >> 12) & 0xf);
-		printf("MMC %i: Manufacturing Date = %i/%i\n", card, year,
-		    month);
-
-		sc->cards[card].addr = card + MMC_FIRST_RCA;
-		status = at91_qdmmc_SendCommand(dev, MMC_SET_RELATIVE_ADDR_CMD,
-		    (sc->cards[card].addr) << 16);
-		if (status != 0) {
-			printf("Failed to set address for MMC %i\n", card);
-			goto out;
-		}
-		printf("Set MMC %i address to 0x%x\n", card,
-		    sc->cards[card].addr);
-
-		status = at91_qdmmc_SendCommand(dev, SEND_CSD_CMD,
-		    (sc->cards[card].addr) << 16);
-		if (status != 0) {
-			printf("Failed to get CSD for MMC %i\n", card);
-			goto out;
-		}
-		sc->cards[card].CSD[0] = RD4(sc, MCI_RSPR + 0);
-		sc->cards[card].CSD[1] = RD4(sc, MCI_RSPR + 4);
-		sc->cards[card].CSD[2] = RD4(sc, MCI_RSPR + 8);
-		sc->cards[card].CSD[3] = RD4(sc, MCI_RSPR + 12);
-		printf("MMC %i: CSD = 0x%x%x%x%x\n", card,
-		    sc->cards[card].CSD[0],
-		    sc->cards[card].CSD[1],
-		    sc->cards[card].CSD[2],
-		    sc->cards[card].CSD[3]);
-		uint64_t c_size;
-		uint64_t c_size_mult;
-		sc->cards[card].sector_size =
-		    1 << ((sc->cards[card].CSD[1] >> 16) & 0xf);
-		printf("MMC %i: Blocksize = %i Bytes\n", card,
-		    sc->cards[card].sector_size);
-		c_size = ((sc->cards[card].CSD[1] & 0x3ff) << 2) |
-		    ((sc->cards[card].CSD[2] >> 30) & 0x3);
-		printf("MMC %i: c_size = %lld\n", card, c_size);
-		c_size_mult = (sc->cards[card].CSD[2] >> 15) & 0x7;
-		c_size_mult = 1 << (c_size_mult + 2);
-		printf("MMC %i: c_size_mult = %lld\n", card, c_size_mult);
-		sc->cards[card].size = sc->cards[card].sector_size *
-		    (c_size + 1) * c_size_mult;
-		printf("MMC %i: Size = %lld Bytes\n", card,
-		    sc->cards[card].size);
-		/* declare clockrate to 5MHz - XXX the card may allow more */
-		sc->cards[card].mode = 5 * MCI_MR_CLKDIV | /* MCI_MR_PWSDIV |
-		    (MCI_MR_PWSDIV << 1) | */  MCI_MR_PDCMODE;
-//		sc->cards[card].mode = 75 * MCI_MR_CLKDIV | /* MCI_MR_PWSDIV |
-//		    (MCI_MR_PWSDIV << 1); */
-		sc->cards[card].flags = 0;
-		if (sc->cards[card].CSD[1] & CSD_1_RD_B_PAR_M)
-			sc->cards[card].flags |= READ_PARTIAL;
-		if (sc->cards[card].CSD[3] & CSD_3_WBLOCK_P_M)
-			sc->cards[card].flags |= WRITE_PARTIAL;
-		sc->cards[card].read_bl = 0;
-		sc->cards[card].write_bl = 0;
-		bioq_init(&sc->cards[0].bio_queue);
-	}
-	if (sc->nb_cards == 0)
-		err = ENXIO;
-out:;
-	return (err);
-}
-
-static int
-at91_qdmmc_attach(device_t dev)
+at91_mci_attach(device_t dev)
 {
 	/* XXX: asumes MCK = 60MHz */
-	struct at91_qdmmc_softc *sc = device_get_softc(dev);
+	struct at91_mci_softc *sc = device_get_softc(dev);
 	int err;
 
-	//printf("at91_qdmmc_attach: called\n");
-
 	sc->dev = dev;
-	err = at91_qdmmc_activate(dev);
+	err = at91_mci_activate(dev);
 	if (err)
 		goto out;
 
-	AT91_QDMMC_LOCK_INIT(sc);
+	AT91_MCI_LOCK_INIT(sc);
 
-	printf("BEFORE I FUCK WITH IT == mode 0x%x\n", RD4(sc, MCI_MR));
 	/*
 	 * Allocate DMA tags and maps
 	 */
@@ -524,99 +154,39 @@
 	if (err != 0)
 		goto out;
 
-	// reset the MCI
-	WR4(sc, MCI_CR, MCI_CR_SWRST);
-	// disable all interrupt sources
-	WR4(sc, MCI_IDR, 0xffffffff);
-	// set timeout values
-	WR4(sc, MCI_DTOR, MCI_DTOR_DTOMUL_1048576 | MCI_DTOR_DTOCYC);
-	//WR4(sc, MCI_MR, AT91C_MCI_MR_PDCMODE);
-	// set clockrate to just 400kHz needed to identify
-//	WR4(sc, MCI_MR, 74 * MCI_MR_CLKDIV /* | MCI_MR_PWSDIV | (MCI_MR_PWSDIV << 1) */
-//	  | MCI_MR_PDCMODE);
-	WR4(sc, MCI_SDCR, 0);
-	// enable controller
-	WR4(sc, MCI_CR, MCI_CR_MCIEN);
-
-	//WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS);
-	//WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS);
-	//WR4(sc, PDC_RNPR, 0);
-	//WR4(sc, PDC_RNCR, 0);
-	//WR4(sc, PDC_TNPR, 0);
-	//WR4(sc, PDC_TNCR, 0);
-	//WR4(sc, PDC_RPR, 0);
-	//WR4(sc, PDC_RCR, 0);
-	//WR4(sc, PDC_TPR, 0);
-	//WR4(sc, PDC_TCR, 0);
-	//WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
-	//WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN);
+	at91_mci_fini(dev);
+	at91_mci_init(dev);
 
-	RD4(sc, MCI_RDR);
-	RD4(sc, MCI_SR);
-
 	/*
 	 * Activate the interrupt
 	 */
 	err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
-	    at91_qdmmc_intr, sc, &sc->intrhand);
+	    at91_mci_intr, sc, &sc->intrhand);
 	if (err) {
-		AT91_QDMMC_LOCK_DESTROY(sc);
+		AT91_MCI_LOCK_DESTROY(sc);
 		goto out;
 	}
 
-	if (at91_qdmmc_mmc_init(dev) != 0) {
-		printf("MMC FAILED, LET'S TRY SDCARD\n");
-		if (at91_qdmmc_sdcard_init(dev) != 0) {
-			printf("SD CARD FAILED, YOU LOSE\n");
-			err = 0;
-			goto out;
-		}
-	}
-	
-	if (sc->nb_cards == 0) {
-		printf("No MMC cards found\n");
-		goto out;
-	} else {
-		AT91_QDMMC_LOCK(sc);
-		/*
-		 * Register the (XXX) first media as a disk
-		 */
-		sc->disk = disk_alloc();
-		sc->disk->d_open = at91_qdmmc_open;
-		sc->disk->d_close = at91_qdmmc_close;
-		sc->disk->d_strategy = at91_qdmmc_strategy;
-		// sc->disk->d_dump = at91_qdmmc_dump;
-		sc->disk->d_name = "at91_qdmmc";
-		sc->disk->d_drv1 = sc;
-		sc->disk->d_maxsize = DFLTPHYS;
-		sc->disk->d_unit = 0;
-		//sc->disk->d_flags = DISKFLAG_NEEDSGIANT;
-		disk_create(sc->disk, DISK_VERSION);
-	}
-
-	/* set clockrate to 5MHz - XXX the card may allow more */
-//	WR4(sc, MCI_MR, 5 * MCI_MR_CLKDIV | 
-//	  /* MCI_MR_PWSDIV | (MCI_MR_PWSDIV << 1) | */ MCI_MR_PDCMODE);
-
-	AT91_QDMMC_UNLOCK(sc);
+	AT91_MCI_UNLOCK(sc);
 
-	kthread_create(&at91_qdmmc_task, sc, &sc->p, 0, 0, "task: at91_qdmmc");
 out:;
 	if (err)
-		at91_qdmmc_deactivate(dev);
+		at91_mci_deactivate(dev);
 	return (err);
 }
 
 static int
-at91_qdmmc_detach(device_t dev)
+at91_mci_detach(device_t dev)
 {
+	at91_mci_fini(dev);
+	at91_mci_deactivate(dev);
 	return (EBUSY);	/* XXX */
 }
 
 static int
-at91_qdmmc_activate(device_t dev)
+at91_mci_activate(device_t dev)
 {
-	struct at91_qdmmc_softc *sc;
+	struct at91_mci_softc *sc;
 	int rid;
 
 	sc = device_get_softc(dev);
@@ -632,14 +202,14 @@
 		goto errout;
 	return (0);
 errout:
-	at91_qdmmc_deactivate(dev);
+	at91_mci_deactivate(dev);
 	return (ENOMEM);
 }
 
 static void
-at91_qdmmc_deactivate(device_t dev)
+at91_mci_deactivate(device_t dev)
 {
-	struct at91_qdmmc_softc *sc;
+	struct at91_mci_softc *sc;
 
 	sc = device_get_softc(dev);
 	if (sc->intrhand)
@@ -657,291 +227,41 @@
 	return;
 }
 
+#if 0
 static void
 at91_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 {
 	if (error != 0)
-	return;
+		return;
 	*(bus_addr_t *)arg = segs[0].ds_addr;
 }
-
-static int at91_qdmmc_open(struct disk *dp)
-{
-	struct at91_qdmmc_softc *sc;
-
-	//printf("at91_qdmmc_open: called\n");
-	sc = (struct at91_qdmmc_softc *)dp->d_drv1;
-	
-	AT91_QDMMC_LOCK(sc);
-	sc->disk->d_sectorsize = sc->cards[0].sector_size;
-	sc->disk->d_mediasize = sc->cards[0].size;
-	//softc->disk->d_fwsectors = softc->params.secs_per_track;
-	//softc->disk->d_fwheads = softc->params.heads;
-	//sc->disk->d_devstat->block_size = sc->cards[0].sector_size;
-	//softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
-	AT91_QDMMC_UNLOCK(sc);
-
-	return 0;
-}
-
-static int at91_qdmmc_close(struct disk *dp)
-{
-	struct at91_qdmmc_softc *sc;
-
-	//printf("at91_qdmmc_close: called\n");
-	sc = (struct at91_qdmmc_softc *)dp->d_drv1;
-
-	AT91_QDMMC_LOCK(sc);
-	AT91_QDMMC_UNLOCK(sc);
-
-	// XXX do nothing since we don't lock for now
-	return 0;
-}
-
-static void at91_qdmmc_strategy(struct bio *bp)
-{
-	struct at91_qdmmc_softc *sc;
-
-	//printf("at91_qdmmc_strategy: called\n");
-	sc = (struct at91_qdmmc_softc *)bp->bio_disk->d_drv1;
-
-#if 1
-	AT91_QDMMC_LOCK(sc);
-	bioq_disksort(&sc->cards[0].bio_queue, bp);
-	wakeup(sc);
-	AT91_QDMMC_UNLOCK(sc);
-#else
-	biofinish(bp, NULL, EIO);
 #endif
-}
 
-static void
-at91_qdmmc_wait_ready(struct at91_qdmmc_softc *sc)
-{
-	int timeout = 100000;
-
-	// Why doesn't this bit ever clear?  It does in the boot loader.
-	printf("Waiting status %#x\n", RD4(sc, MCI_SR));
-	while (!(RD4(sc, MCI_SR) & MCI_SR_NOTBUSY) && --timeout)
-		continue;
-	printf("Waited status %#x\n", RD4(sc, MCI_SR));
-}
-
-static void
-at91_qdmmc_task(void *arg)
-{
-	struct at91_qdmmc_softc *sc = (struct at91_qdmmc_softc*)arg;
-	struct bio *bp;
-	int status;
-	bus_addr_t paddr;
-	int map = 0;
-	uint32_t *tmpbuf;
-	uint32_t rv;
-	int sz;
-
-	tmpbuf = malloc(sc->cards[0].sector_size, M_DEVBUF, M_WAITOK);
-	AT91_QDMMC_LOCK(sc);
-	printf("at91_qdmmc_task: start\n");
-	for (;;) {
-		do {
-			bp = bioq_first(&sc->cards[0].bio_queue);
-			if (bp == NULL)
-				msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0);
-		} while (bp == NULL);
-		bioq_remove(&sc->cards[0].bio_queue, bp);
-		printf("at91_qdmmc_task: request %p\n", bp);
-		if (bp->bio_cmd == BIO_READ) {
-			printf("at91_qdmmc_task: read block %lld, bcount %ld\n", bp->bio_pblkno, bp->bio_bcount);
-			uint32_t block;
-			// Init Mode Register
-//			WR4(sc, MCI_MR, sc->cards[0].mode | MCI_MR_PDCMODE |
-//			  (sc->cards[0].sector_size << 16));
-			WR4(sc, MCI_MR, 0x8301 | (sc->cards[0].sector_size << 16));
-			printf("mode 0x%x\n", RD4(sc, MCI_MR));
-			sz = sc->cards[0].sector_size;
-			for (block = bp->bio_pblkno; block < bp->bio_pblkno + (bp->bio_bcount / sz); block++) {
-
-				printf("Waiting for not busy\n");
-				// wait until completed
-				while (!(RD4(sc, MCI_SR) & MCI_SR_NOTBUSY))
-					continue;
-				printf("Waiting for the card to become ready\n");
-				do {
-					rv = at91_qdmmc_GetStatus(sc->dev, sc->cards[0].addr);
-					printf(".");
-				} while (rv != 0xffffffff && !(rv & AT91C_SR_READY_FOR_DATA));
-
-				char *vaddr = bp->bio_data + (block - bp->bio_pblkno) * sz;
-
-				if (bus_dmamap_load(sc->dmatag, sc->map, vaddr,
-				    sc->cards[0].sector_size, at91_getaddr, &paddr, 0) != 0)
-					goto out;
-				map = 1;
-
-				bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREREAD);
-				at91_qdmmc_wait_ready(sc);
-				WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
-				WR4(sc, PDC_RPR, paddr);
-				WR4(sc, PDC_RCR, sz);
-
-				printf("block = %#x vaddr = %p, RPR = 0x%x, RCR = 0x%x\n", block, vaddr,
-				    RD4(sc, PDC_RPR), RD4(sc, PDC_RCR));
-				printf("SR is %x before we get going\n", RD4(sc, MCI_SR));
-				WR4(sc, MCI_IER, MCI_SR_ENDRX | 0xffff0000);
-				status = at91_qdmmc_SendCommand(sc->dev, READ_SINGLE_BLOCK_CMD, block * sz);
-				WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
-
-				printf("at91_qdmmc_task: read-status = 0x%x\n", status);
-
-				// wait for completion
-				printf("TO SLEEP, PURCHANCE TO DREAM\n");
-#if 1
-				msleep(sc, &sc->sc_mtx, PRIBIO, "endrx", 0);
-				printf("DONE SLEEPING\n");
-#endif
-				at91_qdmmc_wait_ready(sc);
-				printf("SR is %x\n", RD4(sc, MCI_SR));
-#if 1
-
-				// safety check
-				while ((RD4(sc, MCI_SR) & MCI_SR_ENDRX) == 0)
-					DELAY(700);
-#endif
-
-				printf("DONE WAITING\n");
-				bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTREAD);
-				bus_dmamap_unload(sc->dmatag, sc->map);
-				map = 0;
-
-				WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS);
-				/* Fix Byteorder (Atmel Errata) */
-				uint32_t* base = (uint32_t*)vaddr;
-				for (int i = 0; i < sc->cards[0].sector_size / 4; i++) {
-					uint32_t tmp = base[i];
-					base[i] = (((tmp >> 24) & 0xff)) |
-					    (((tmp >> 16) & 0xff) << 8) |
-					    (((tmp >> 8) & 0xff) << 16) |
-					    ((tmp & 0xff) << 24);
-					printf("%08x", base[i]);
-				}
-				printf("\n");
-			}
-			printf("Delecting card!\n");
-			status = at91_qdmmc_SendCommand(sc->dev,
-			    SEL_DESEL_CARD_CMD, 0);
-			printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
-
-			// Reset Mode Register
-//			WR4(sc, MCI_MR, sc->cards[0].mode);
-			biodone(bp);
-			continue;
-		}
-		if (bp->bio_cmd == BIO_WRITE) {
-			printf("at91_qdmmc_task: write block %lld, bcount %ld\n", bp->bio_pblkno, bp->bio_bcount);
-			uint32_t block;
-			uint32_t *tmpbuf;
-
-			// Init Mode Register
-//			WR4(sc, MCI_MR, sc->cards[0].mode | (sc->cards[0].sector_size << 16));
-			printf("mode 0x%x\n", RD4(sc, MCI_MR));
-
-			status = at91_qdmmc_SendCommand(sc->dev,
-			    SEL_DESEL_CARD_CMD, (sc->cards[0].addr) << 16);
-			printf("at91_qdmmc_task: select_card-status = 0x%x\n", status);
-			status = at91_qdmmc_SendCommand(sc->dev, 
-			    SET_BLOCKLEN_CMD, sc->cards[0].sector_size);
-			printf("at91_qdmmc_task: set_blocklen-status = 0x%x\n", status);
-
-			tmpbuf = malloc(sc->cards[0].sector_size, M_DEVBUF, M_WAITOK);
-			for (block = bp->bio_pblkno; block < bp->bio_pblkno + (bp->bio_bcount / sc->cards[0].sector_size); block++) {
-				char *vaddr = bp->bio_data + (block - bp->bio_pblkno) * sc->cards[0].sector_size;
-
-				/* Fix Byteorder (Atmel Errata) */
-				uint32_t* base = (uint32_t*)vaddr;
-				for (int i = 0; i < sc->cards[0].sector_size / 4; i++) {
-					uint32_t tmp = base[i];
-					tmpbuf[i] = (((tmp >> 24) & 0xff)) |
-					    (((tmp >> 16) & 0xff) << 8) |
-					    (((tmp >> 8) & 0xff) << 16) |
-					    ((tmp & 0xff) << 24);
-				}
-
-				WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
-
-				if (bus_dmamap_load(sc->dmatag, sc->map, tmpbuf,
-				    sc->cards[0].sector_size, at91_getaddr, &paddr, 0) != 0)
-					goto out;
-				map = 1;
-
-				bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREWRITE);
-				WR4(sc, PDC_TPR, paddr);
-				WR4(sc, PDC_TCR, sc->cards[0].sector_size / 4);
-
-				printf("status = 0x%x, tmpbuf = %p, TPR = 0x%x, TCR = 0x%x\n", status, tmpbuf,
-				    RD4(sc, PDC_TPR), RD4(sc, PDC_TCR));
-				status = at91_qdmmc_SendCommand(sc->dev, 
-				    WRITE_BLOCK_CMD, block * sc->cards[0].sector_size);
-				// printf("at91_qdmmc_task: write-status = 0x%x\n", status);
-				WR4(sc, MCI_IER, MCI_SR_NOTBUSY);
-				WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN);
-
-				// wait for completion
-				msleep(sc, &sc->sc_mtx, PRIBIO, "notbusy", 0);
-				// XXX don't know why this safety check is required
-				while ((RD4(sc, MCI_SR) & MCI_SR_NOTBUSY) == 0)
-					DELAY(700);
-
-				bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTWRITE);
-				bus_dmamap_unload(sc->dmatag, sc->map);
-				map = 0;
-			}
-			free(tmpbuf, M_DEVBUF);
-
-			status = at91_qdmmc_SendCommand(sc->dev,
-			    SEL_DESEL_CARD_CMD, 0);
-			printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
-
-			// Reset Mode Register
-//			WR4(sc, MCI_MR, sc->cards[0].mode);
-			biodone(bp);
-			continue;
-		}
-
-out:
-		if (map)
-			bus_dmamap_unload(sc->dmatag, sc->map);
-		status = at91_qdmmc_SendCommand(sc->dev, SEL_DESEL_CARD_CMD, 0);
-		printf("at91_qdmmc_task: deselect_card-status = 0x%x\n", status);
-		AT91_QDMMC_UNLOCK(sc);
-		biofinish(bp, NULL, ENXIO);
-	}
-}
-
-static device_method_t at91_qdmmc_methods[] = {
-	DEVMETHOD(device_probe, at91_qdmmc_probe),
-	DEVMETHOD(device_attach, at91_qdmmc_attach),
-	DEVMETHOD(device_detach, at91_qdmmc_detach),
+static device_method_t at91_mci_methods[] = {
+	DEVMETHOD(device_probe, at91_mci_probe),
+	DEVMETHOD(device_attach, at91_mci_attach),
+	DEVMETHOD(device_detach, at91_mci_detach),
 	{0, 0},
 };
 
-static driver_t at91_qdmmc_driver = {
-	"at91_qdmmc",
-	at91_qdmmc_methods,
-	sizeof(struct at91_qdmmc_softc),
+static driver_t at91_mci_driver = {
+	"at91_mci",
+	at91_mci_methods,
+	sizeof(struct at91_mci_softc),
 };
-static devclass_t at91_qdmmc_devclass;
+static devclass_t at91_mci_devclass;
 
 
-DRIVER_MODULE(at91_qdmmc, atmelarm, at91_qdmmc_driver, at91_qdmmc_devclass, 0, 0);
+DRIVER_MODULE(at91_mci, atmelarm, at91_mci_driver, at91_mci_devclass, 0, 0);
 
 static void
-at91_qdmmc_intr(void *arg)
+at91_mci_intr(void *arg)
 {
-	struct at91_qdmmc_softc *sc = (struct at91_qdmmc_softc*)arg;
+	struct at91_mci_softc *sc = (struct at91_mci_softc*)arg;
 
-	AT91_QDMMC_LOCK(sc);
+	AT91_MCI_LOCK(sc);
 	printf("i 0x%x\n", RD4(sc, MCI_SR));
 	wakeup(sc);
 	WR4(sc, MCI_IDR, 0xffffffff);
-	AT91_QDMMC_UNLOCK(sc);
+	AT91_MCI_UNLOCK(sc);
 }

==== //depot/projects/arm/src/sys/arm/at91/at91_mcireg.h#2 (text+ko) ====

@@ -1,5 +1,6 @@
 /*-
- * Copyright (c) 2005 M. Warner Losh.  All rights reserved.
+ * Copyright (c) 2006 Berndt Walter.  All rights reserved.
+ * Copyright (c) 2006 M. Warner Losh.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -22,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* $FreeBSD: src/sys/arm/at91/at91_streg.h,v 1.1 2006/02/04 23:32:13 imp Exp $ */
+/* $FreeBSD$ */
 
 #ifndef ARM_AT91_AT91QDMMCREG_H
 #define ARM_AT91_AT91QDMMCREG_H
@@ -65,7 +66,7 @@
 #define		MCI_DTOR_DTOMUL_1024                 (0x4u <<  4) /* (MCI) DTOCYC x 1024 */
 #define		MCI_DTOR_DTOMUL_4096                 (0x5u <<  4) /* (MCI) DTOCYC x 4096 */
 #define		MCI_DTOR_DTOMUL_65536                (0x6u <<  4) /* (MCI) DTOCYC x 65536 */
-#define		MCI_DTOR_DTOMUL_1048576              (0x7u <<  4) /* (MCI) DTOCYC x 1048576 */
+#define		MCI_DTOR_DTOMUL_1M                   (0x7u <<  4) /* (MCI) DTOCYC x 1048576 */
 /* -------- MCI_SDCR : (MCI Offset: 0xc) MCI SD Card Register --------  */
 #define	MCI_SDCR_SCDSEL      (0x1u <<  0) /* (MCI) SD Card Selector */
 #define	MCI_SDCR_SCDBUS      (0x1u <<  7) /* (MCI) SD Card Bus Width */

==== //depot/projects/arm/src/sys/arm/conf/TSC4370#8 (text+ko) ====

@@ -94,7 +94,10 @@
 device		at91_spi		# SPI bridge support
 device		at91_ssc
 device		at91_tc
-device		at91_qdmmc
+device		at91_mci
+#device		mmcsd			# mmc/sd bus
+#device		mmc			# mmc flash card

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609230052.k8N0q6Dw091998>