From owner-svn-src-stable-9@FreeBSD.ORG Sat May 26 09:11:46 2012 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7019F106566B; Sat, 26 May 2012 09:11:46 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5AFD38FC18; Sat, 26 May 2012 09:11:46 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4Q9BkbZ065094; Sat, 26 May 2012 09:11:46 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4Q9BkaZ065091; Sat, 26 May 2012 09:11:46 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201205260911.q4Q9BkaZ065091@svn.freebsd.org> From: Marius Strobl Date: Sat, 26 May 2012 09:11:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r236084 - stable/9/sys/arm/at91 X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 26 May 2012 09:11:46 -0000 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 */