svn commit: r236084 - stable/9/sys/arm/at91
Marius Strobl
marius at FreeBSD.org
Sat May 26 09:11:46 UTC 2012
Author: marius
Date: Sat May 26 09:11:45 2012
New Revision: 236084
URL: http://svn.freebsd.org/changeset/base/236084
Log:
MFC: r234560
- Add support for MCI1 revision 2xx controllers and a work-around for their
"Data Write Operation and number of bytes" erratum.
- Use DEVMETHOD_END.
- Use NULL instead of 0 for pointers.
Modified:
stable/9/sys/arm/at91/at91_mci.c
stable/9/sys/arm/at91/at91_mcireg.h
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
stable/9/sys/dev/ (props changed)
stable/9/sys/dev/e1000/ (props changed)
stable/9/sys/dev/ixgbe/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/fs/ntfs/ (props changed)
stable/9/sys/modules/ (props changed)
Modified: stable/9/sys/arm/at91/at91_mci.c
==============================================================================
--- stable/9/sys/arm/at91/at91_mci.c Sat May 26 09:08:33 2012 (r236083)
+++ stable/9/sys/arm/at91/at91_mci.c Sat May 26 09:11:45 2012 (r236084)
@@ -113,6 +113,7 @@ static void at91_mci_intr(void *);
/* helper routines */
static int at91_mci_activate(device_t dev);
static void at91_mci_deactivate(device_t dev);
+static int at91_mci_is_mci1rev2xx(void);
#define AT91_MCI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define AT91_MCI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
@@ -141,11 +142,16 @@ static void
at91_mci_init(device_t dev)
{
struct at91_mci_softc *sc = device_get_softc(dev);
+ uint32_t val;
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 | 1);
- WR4(sc, MCI_MR, 0x834a); // XXX GROSS HACK FROM LINUX
+ val = MCI_MR_PDCMODE;
+ val |= 0x34a; /* PWSDIV = 3; CLKDIV = 74 */
+ if (at91_mci_is_mci1rev2xx())
+ val |= MCI_MR_RDPROOF | MCI_MR_WRPROOF;
+ WR4(sc, MCI_MR, val);
#ifndef AT91_MCI_SLOT_B
WR4(sc, MCI_SDCR, 0); /* SLOT A, 1 bit bus */
#else
@@ -303,6 +309,29 @@ at91_mci_deactivate(device_t dev)
return;
}
+static int
+at91_mci_is_mci1rev2xx(void)
+{
+
+ switch (AT91_CPU(at91_chip_id)) {
+ case AT91_CPU_SAM9260:
+ case AT91_CPU_SAM9263:
+#ifdef notyet
+ case AT91_CPU_CAP9:
+#endif
+ case AT91_CPU_SAM9G10:
+ case AT91_CPU_SAM9G20:
+#ifdef notyet
+ case AT91_CPU_SAM9RL:
+#endif
+ case AT91_CPU_SAM9XE128:
+ case AT91_CPU_SAM9XE256:
+ case AT91_CPU_SAM9XE512:
+ return(1);
+ }
+ return (0);
+}
+
static void
at91_mci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
{
@@ -346,6 +375,7 @@ at91_mci_update_ios(device_t brdev, devi
static void
at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
{
+ size_t len;
uint32_t cmdr, ier = 0, mr;
uint32_t *src, *dst;
int i;
@@ -397,6 +427,7 @@ at91_mci_start_cmd(struct at91_mci_softc
WR4(sc, MCI_MR, mr | (data->len << 16) | MCI_MR_PDCMODE);
WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS);
if (cmdr & MCI_CMDR_TRCMD_START) {
+ len = data->len;
if (cmdr & MCI_CMDR_TRDIR)
vaddr = cmd->data->data;
else {
@@ -411,6 +442,15 @@ at91_mci_start_cmd(struct at91_mci_softc
vaddr = sc->bounce_buffer;
src = (uint32_t *)cmd->data->data;
dst = (uint32_t *)vaddr;
+ /*
+ * If this is MCI1 revision 2xx controller, apply
+ * a work-around for the "Data Write Operation and
+ * number of bytes" erratum.
+ */
+ if (at91_mci_is_mci1rev2xx() && data->len < 12) {
+ len = 12;
+ memset(dst, 0, 12);
+ }
if (sc->sc_cap & CAP_NEEDS_BYTESWAP) {
for (i = 0; i < data->len / 4; i++)
dst[i] = bswap32(src[i]);
@@ -418,7 +458,7 @@ at91_mci_start_cmd(struct at91_mci_softc
memcpy(dst, src, data->len);
}
data->xfer_len = 0;
- if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, data->len,
+ if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, len,
at91_mci_getaddr, &paddr, 0) != 0) {
cmd->error = MMC_ERR_NO_MEMORY;
sc->req = NULL;
@@ -430,12 +470,12 @@ at91_mci_start_cmd(struct at91_mci_softc
if (cmdr & MCI_CMDR_TRDIR) {
bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREREAD);
WR4(sc, PDC_RPR, paddr);
- WR4(sc, PDC_RCR, data->len / 4);
+ WR4(sc, PDC_RCR, len / 4);
ier = MCI_SR_ENDRX;
} else {
bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREWRITE);
WR4(sc, PDC_TPR, paddr);
- WR4(sc, PDC_TCR, data->len / 4);
+ WR4(sc, PDC_TCR, len / 4);
ier = MCI_SR_TXBUFE;
}
}
@@ -769,7 +809,7 @@ static device_method_t at91_mci_methods[
DEVMETHOD(mmcbr_acquire_host, at91_mci_acquire_host),
DEVMETHOD(mmcbr_release_host, at91_mci_release_host),
- {0, 0},
+ DEVMETHOD_END
};
static driver_t at91_mci_driver = {
@@ -777,7 +817,8 @@ static driver_t at91_mci_driver = {
at91_mci_methods,
sizeof(struct at91_mci_softc),
};
-static devclass_t at91_mci_devclass;
+static devclass_t at91_mci_devclass;
-DRIVER_MODULE(at91_mci, atmelarm, at91_mci_driver, at91_mci_devclass, 0, 0);
+DRIVER_MODULE(at91_mci, atmelarm, at91_mci_driver, at91_mci_devclass, NULL,
+ NULL);
Modified: stable/9/sys/arm/at91/at91_mcireg.h
==============================================================================
--- stable/9/sys/arm/at91/at91_mcireg.h Sat May 26 09:08:33 2012 (r236083)
+++ stable/9/sys/arm/at91/at91_mcireg.h Sat May 26 09:11:45 2012 (r236084)
@@ -54,6 +54,9 @@
/* -------- MCI_MR : (MCI Offset: 0x4) MCI Mode Register -------- */
#define MCI_MR_CLKDIV (0xffu << 0) /* (MCI) Clock Divider */
#define MCI_MR_PWSDIV (0x3fu << 8) /* (MCI) Power Saving Divider */
+#define MCI_MR_RDPROOF (0x1u << 11) /* (MCI) Read Proof Enable */
+#define MCI_MR_WRPROOF (0x1u << 12) /* (MCI) Write Proof Enable */
+#define MCI_MR_PDCFBYTE (0x1u << 13) /* (MCI) PDC Force Byte Transfer */
#define MCI_MR_PDCPADV (0x1u << 14) /* (MCI) PDC Padding Value */
#define MCI_MR_PDCMODE (0x1u << 15) /* (MCI) PDC Oriented Mode */
#define MCI_MR_BLKLEN 0x3fff0000ul /* (MCI) Data Block Length */
More information about the svn-src-stable-9
mailing list