Module Name:    src
Committed By:   kiyohara
Date:           Thu Aug  4 07:14:50 UTC 2016

Modified Files:
        src/sys/arch/arm/omap: omap3_sdhc.c omap3_sdmmcreg.h

Log Message:
Support OMAP 4430.  But ADMA2 don't working yet.
tested on Gumstix DuoVero.


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/arm/omap/omap3_sdhc.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/omap/omap3_sdmmcreg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/omap/omap3_sdhc.c
diff -u src/sys/arch/arm/omap/omap3_sdhc.c:1.21 src/sys/arch/arm/omap/omap3_sdhc.c:1.22
--- src/sys/arch/arm/omap/omap3_sdhc.c:1.21	Mon Jul  4 15:45:37 2016
+++ src/sys/arch/arm/omap/omap3_sdhc.c	Thu Aug  4 07:14:50 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: omap3_sdhc.c,v 1.21 2016/07/04 15:45:37 kiyohara Exp $	*/
+/*	$NetBSD: omap3_sdhc.c,v 1.22 2016/08/04 07:14:50 kiyohara Exp $	*/
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: omap3_sdhc.c,v 1.21 2016/07/04 15:45:37 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: omap3_sdhc.c,v 1.22 2016/08/04 07:14:50 kiyohara Exp $");
 
 #include "opt_omap.h"
 #include "edma.h"
@@ -87,7 +87,6 @@ static void obiosdhc_attach(device_t, de
 static int obiosdhc_detach(device_t, int);
 
 static int obiosdhc_bus_width(struct sdhc_softc *, int);
-static int obiosdhc_bus_clock(struct sdhc_softc *, int);
 static int obiosdhc_rod(struct sdhc_softc *, int);
 static int obiosdhc_write_protect(struct sdhc_softc *);
 static int obiosdhc_card_detect(struct sdhc_softc *);
@@ -96,6 +95,7 @@ struct obiosdhc_softc {
 	struct sdhc_softc	sc;
 	bus_space_tag_t		sc_bst;
 	bus_space_handle_t	sc_bsh;
+	bus_space_handle_t	sc_hl_bsh;
 	bus_space_handle_t	sc_sdhc_bsh;
 	struct sdhc_host	*sc_hosts[1];
 	void 			*sc_ih;		/* interrupt vectoring */
@@ -173,19 +173,19 @@ obiosdhc_match(device_t parent, cfdata_t
 	if (oa->obio_addr == SDMMC1_BASE_3430
 	    || oa->obio_addr == SDMMC2_BASE_3430
 	    || oa->obio_addr == SDMMC3_BASE_3430)
-                return 1;
+		return 1;
 #elif defined(OMAP_3530)
 	if (oa->obio_addr == SDMMC1_BASE_3530
 	    || oa->obio_addr == SDMMC2_BASE_3530
 	    || oa->obio_addr == SDMMC3_BASE_3530)
-                return 1;
+		return 1;
 #elif defined(OMAP4) || defined(OMAP5)
 	if (oa->obio_addr == SDMMC1_BASE_4430
 	    || oa->obio_addr == SDMMC2_BASE_4430
 	    || oa->obio_addr == SDMMC3_BASE_4430
 	    || oa->obio_addr == SDMMC4_BASE_4430
 	    || oa->obio_addr == SDMMC5_BASE_4430)
-                return 1;
+		return 1;
 #endif
 
 #ifdef TI_AM335X
@@ -195,7 +195,7 @@ obiosdhc_match(device_t parent, cfdata_t
 			return 1;
 #endif
 
-        return 0;
+	return 0;
 }
 
 static void
@@ -208,6 +208,10 @@ obiosdhc_attach(device_t parent, device_
 	int error, timo, clksft, n;
 	bool support8bit = false;
 	const char *transfer_mode = "PIO";
+#if defined(OMAP4)
+	uint32_t v;
+	int x, y;
+#endif
 #ifdef TI_AM335X
 	size_t i;
 #endif
@@ -219,16 +223,44 @@ obiosdhc_attach(device_t parent, device_
 	sc->sc.sc_flags |= SDHC_FLAG_32BIT_ACCESS;
 	sc->sc.sc_flags |= SDHC_FLAG_NO_LED_ON;
 	sc->sc.sc_flags |= SDHC_FLAG_RSP136_CRC;
-	sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY;
 	if (support8bit)
 		sc->sc.sc_flags |= SDHC_FLAG_8BIT_MODE;
-#ifdef TI_AM335X
+#if defined(OMAP_3430)
+	sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY;
+#elif defined(OMAP_3530) || defined(TI_DM37XX)
+	/*
+	 * Advisory 2.1.1.128: MMC: Multiple Block Read Operation Issue
+	 * from "OMAP3530/25/15/03 Applications Processor Silicon Revisions
+	 * 3.1.2, 3.1, 3.0, 2.1, and 2.0".
+	 */
+	switch (omap_devid()) {
+	case DEVID_OMAP35X_ES10:
+	case DEVID_OMAP35X_ES20:
+	case DEVID_OMAP35X_ES21:
+	case DEVID_AMDM37X_ES10:	/* XXXX ? */
+	case DEVID_AMDM37X_ES11:	/* XXXX ? */
+	case DEVID_AMDM37X_ES12:	/* XXXX ? */
+		sc->sc.sc_flags |= SDHC_FLAG_SINGLE_ONLY;
+		break;
+	default:
+		break;
+	}
+	sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT;
+#elif defined(TI_AM335X)
 	sc->sc.sc_flags |= SDHC_FLAG_WAIT_RESET;
-	sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
-#endif
-#if defined(OMAP_3530)
-	if (omap_chipid() == CHIPID_OMAP3530)
-		sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
+#elif defined(OMAP_4430)
+	/*
+	 * MMCHS_HCTL.HSPE Is Not Functional
+	 * Errata ID: i626
+	 *
+	 * Due to design issue MMCHS_HCTL.HSPE bit does not work as intended.
+	 * This means that the configuration must always be the normal speed
+	 * mode configuration (MMCHS_HCTL.HSPE=0).
+	 */
+	sc->sc.sc_flags |= SDHC_FLAG_NO_HS_BIT;
+
+//	sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
+//	sc->sc.sc_flags |= SDHC_FLAG_USE_ADMA2;
 #endif
 	sc->sc.sc_host = sc->sc_hosts;
 	sc->sc.sc_clkbase = 96000;	/* 96MHZ */
@@ -237,7 +269,6 @@ obiosdhc_attach(device_t parent, device_
 	sc->sc.sc_vendor_rod = obiosdhc_rod;
 	sc->sc.sc_vendor_write_protect = obiosdhc_write_protect;
 	sc->sc.sc_vendor_card_detect = obiosdhc_card_detect;
-	sc->sc.sc_vendor_bus_clock = obiosdhc_bus_clock;
 	sc->sc.sc_vendor_bus_width = obiosdhc_bus_width;
 	sc->sc_bst = oa->obio_iot;
 
@@ -246,6 +277,13 @@ obiosdhc_attach(device_t parent, device_
 #if defined(TI_AM335X)
 	error = bus_space_map(sc->sc_bst, oa->obio_addr + OMAP4_SDMMC_HL_SIZE,
 	    oa->obio_size - OMAP4_SDMMC_HL_SIZE, 0, &sc->sc_bsh);
+#elif defined(OMAP4)
+	error = bus_space_map(sc->sc_bst, oa->obio_addr, oa->obio_size, 0,
+	    &sc->sc_hl_bsh);
+	if (!error)
+		bus_space_subregion(sc->sc_bst, sc->sc_hl_bsh,
+		    OMAP4_SDMMC_HL_SIZE, oa->obio_size - OMAP4_SDMMC_HL_SIZE,
+		    &sc->sc_bsh);
 #else
 	error = bus_space_map(sc->sc_bst, oa->obio_addr, oa->obio_size, 0,
 	    &sc->sc_bsh);
@@ -266,20 +304,50 @@ obiosdhc_attach(device_t parent, device_
 
 		cv_init(&sc->sc_edma_cv, "sdhcedma");
 		sc->sc_edma_fifo = oa->obio_addr +
-		    OMAP4_SDMMC_HL_SIZE + OMAP3_SDMMC_SDHC_OFFSET + SDHC_DATA;
+#ifdef TI_AM335X
+		    OMAP4_SDMMC_HL_SIZE +
+#endif
+		    OMAP3_SDMMC_SDHC_OFFSET + SDHC_DATA;
 		sc->sc.sc_flags |= SDHC_FLAG_USE_DMA;
 		sc->sc.sc_flags |= SDHC_FLAG_EXTERNAL_DMA;
 		sc->sc.sc_flags |= SDHC_FLAG_EXTDMA_DMAEN;
-		sc->sc.sc_flags &= ~SDHC_FLAG_SINGLE_ONLY;
 		sc->sc.sc_vendor_transfer_data_dma = obiosdhc_edma_xfer_data;
 		transfer_mode = "EDMA";
 	}
 no_dma:
 #endif
+	if (sc->sc.sc_flags & SDHC_FLAG_USE_ADMA2)
+		transfer_mode = "ADMA2";
 
 	aprint_naive("\n");
 	aprint_normal(": SDHC controller (%s)\n", transfer_mode);
 
+#if defined(OMAP4)
+	v = bus_space_read_4(sc->sc_bst, sc->sc_hl_bsh, MMCHS_HL_REV);
+	aprint_normal_dev(sc->sc.sc_dev, "IP Rev 0x%08x", v);
+	v = bus_space_read_4(sc->sc_bst, sc->sc_hl_bsh, MMCHS_HL_HWINFO);
+	aprint_normal("%s", v & HL_HWINFO_RETMODE ? ", Retention Mode" : "");
+	x = 0;
+	switch (v & HL_HWINFO_MEM_SIZE_MASK) {
+	case HL_HWINFO_MEM_SIZE_512: 	x = 512;	y = 512;	break;
+	case HL_HWINFO_MEM_SIZE_1024:	x = 1024;	y = 1024;	break;
+	case HL_HWINFO_MEM_SIZE_2048:	x = 2048;	y = 2048;	break;
+	case HL_HWINFO_MEM_SIZE_4096:	x = 4096;	y = 2048;	break;
+	}
+	if (x != 0)
+		aprint_normal(", %d byte FIFO, max block length %d bytes",
+		    x, y);
+	aprint_normal("\n");
+#endif
+
+#if NEDMA > 0
+	if (strcmp(transfer_mode, "EDMA") == 0)
+		aprint_normal_dev(sc->sc.sc_dev,
+		    "EDMA tx channel %d, rx channel %d\n",
+		    edma_channel_index(sc->sc_edma_tx),
+		    edma_channel_index(sc->sc_edma_rx));
+#endif
+
 #ifdef TI_AM335X
 	/* XXX Not really AM335X-specific.  */
 	for (i = 0; i < __arraycount(am335x_sdhc); i++)
@@ -293,7 +361,7 @@ no_dma:
 	if (oa->obio_addr == SDMMC2_BASE_TIAM335X) {
 		const char *mode;
 		u_int state;
-		
+
 		const struct am335x_padconf *padconf = am335x_padconf_mmc1;
 		for (i = 0; padconf[i].padname; i++) {
 			const char *padname = padconf[i].padname;
@@ -387,30 +455,28 @@ no_dma:
 
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) | CON_INIT);
-	for (; n > 0; n--) {
-		SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000);
-		timo = 3000000;	/* XXXX 3 sec. */
-		stat = 0;
-		while (!(stat & SDHC_COMMAND_COMPLETE)) {
-			stat = SDHC_READ(sc, SDHC_NINTR_STATUS);
-			if (--timo == 0)
-				break;
-			delay(1);
-		}
-		if (timo == 0) {
-			aprint_error_dev(self, "INIT Procedure timeout\n");
-			break;
-		}
-		SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat);
-	}
+	SDHC_WRITE(sc, SDHC_TRANSFER_MODE, 0x00000000);
+	delay(1000);
+	stat = SDHC_READ(sc, SDHC_NINTR_STATUS);
+	SDHC_WRITE(sc, SDHC_NINTR_STATUS, stat | SDHC_COMMAND_COMPLETE);
 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON,
 	    bus_space_read_4(sc->sc_bst, sc->sc_bsh, MMCHS_CON) & ~CON_INIT);
+	SDHC_WRITE(sc, SDHC_NINTR_STATUS, 0xffffffff);
+
 	SDHC_WRITE(sc, SDHC_CLOCK_CTL,
 	    SDHC_READ(sc, SDHC_CLOCK_CTL) & ~SDHC_SDCLK_ENABLE);
 	SDHC_WRITE(sc, SDHC_CLOCK_CTL,
 	    SDHC_READ(sc, SDHC_CLOCK_CTL) & ~sc->sc.sc_clkmsk);
 	SDHC_WRITE(sc, SDHC_CLOCK_CTL,
 	    SDHC_READ(sc, SDHC_CLOCK_CTL) | CLKD(150) << clksft);
+	timo = 3000000;	/* XXXX 3 sec. */
+	while (--timo) {
+		if (SDHC_READ(sc, SDHC_CLOCK_CTL) & SDHC_INTCLK_STABLE)
+			break;
+		delay(1);
+	}
+	if (timo == 0)
+		aprint_error_dev(self, "ICS timeout(2)\n");
 	SDHC_WRITE(sc, SDHC_CLOCK_CTL,
 	    SDHC_READ(sc, SDHC_CLOCK_CTL) | SDHC_SDCLK_ENABLE);
 
@@ -487,23 +553,6 @@ obiosdhc_bus_width(struct sdhc_softc *sc
 	return 0;
 }
 
-static int
-obiosdhc_bus_clock(struct sdhc_softc *sc, int clk)
-{
-	struct obiosdhc_softc *osc = (struct obiosdhc_softc *)sc;
-	uint32_t ctl;
-
-	ctl = bus_space_read_4(osc->sc_bst, osc->sc_bsh, MMCHS_SYSCTL);
-	if (clk == 0) {
-		ctl &= ~SYSCTL_CEN;
-	} else {
-		ctl |= SYSCTL_CEN;
-	}
-	bus_space_write_4(osc->sc_bst, osc->sc_bsh, MMCHS_SYSCTL, ctl);
-
-	return 0;
-}
-
 #if NEDMA > 0
 static int
 obiosdhc_edma_init(struct obiosdhc_softc *sc, unsigned int edmabase)
@@ -518,10 +567,6 @@ obiosdhc_edma_init(struct obiosdhc_softc
 	    obiosdhc_edma_done, sc);
 	KASSERT(sc->sc_edma_rx != NULL);
 
-	device_printf(sc->sc.sc_dev, "EDMA tx channel %d, rx channel %d\n",
-	    edma_channel_index(sc->sc_edma_tx),
-	    edma_channel_index(sc->sc_edma_rx));
-
 	/* Allocate some PaRAM pages */
 	for (i = 0; i < __arraycount(sc->sc_edma_param_tx); i++) {
 		sc->sc_edma_param_tx[i] = edma_param_alloc(sc->sc_edma_tx);
@@ -676,7 +721,7 @@ obiosdhc_edma_transfer(struct sdhc_softc
 		 */
 		KASSERT((cmd->c_dmamap->dm_segs[seg].ds_addr & 0x1f) == 0);
 
-                /*
+		/*
 		 * For unknown reason, the A-DMA transfers never completes for
 		 * transfers larger than 64 butes. So use a AB transfer,
 		 * with a 64 bytes A len

Index: src/sys/arch/arm/omap/omap3_sdmmcreg.h
diff -u src/sys/arch/arm/omap/omap3_sdmmcreg.h:1.8 src/sys/arch/arm/omap/omap3_sdmmcreg.h:1.9
--- src/sys/arch/arm/omap/omap3_sdmmcreg.h:1.8	Mon Jul  4 15:45:37 2016
+++ src/sys/arch/arm/omap/omap3_sdmmcreg.h	Thu Aug  4 07:14:50 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: omap3_sdmmcreg.h,v 1.8 2016/07/04 15:45:37 kiyohara Exp $	*/
+/*	$NetBSD: omap3_sdmmcreg.h,v 1.9 2016/08/04 07:14:50 kiyohara Exp $	*/
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -54,6 +54,30 @@
 
 #define	OMAP4_SDMMC_HL_SIZE	0x100
 
+#define MMCHS_HL_REV		0x000
+#define MMCHS_HL_HWINFO		0x004
+#  define HL_HWINFO_RETMODE		(1 << 8)
+#  define HL_HWINFO_MEM_SIZE_MASK	(0xf << 2)
+#  define HL_HWINFO_MEM_SIZE_512	(0x1 << 2)
+#  define HL_HWINFO_MEM_SIZE_1024	(0x2 << 2)
+#  define HL_HWINFO_MEM_SIZE_2048	(0x4 << 2)
+#  define HL_HWINFO_MEM_SIZE_4096	(0x8 << 2)
+#  define HL_HWINFO_MEMRGE_MEM		(1 << 1)
+#  define HL_HWINFO_MADMA_EN		(1 << 0)
+#define MMCHS_HL_SYSCONFIG	0x010
+#  define HL_SYSCONFIG_STANDBYMODE_MASK	(0x3 << 2)
+#  define HL_SYSCONFIG_STANDBYMODE_FORCE (0 << 2)
+#  define HL_SYSCONFIG_STANDBYMODE_NO	(1 << 2)
+#  define HL_SYSCONFIG_STANDBYMODE_SMART (2 << 2)
+#  define HL_SYSCONFIG_STANDBYMODE_WC	(3 << 2) /* Smart-Idle wakeup-capable */
+#  define HL_SYSCONFIG_IDLEMODE_MASK	(0x3 << 2)
+#  define HL_SYSCONFIG_IDLEMODE_FORCE	(0 << 2)
+#  define HL_SYSCONFIG_IDLEMODE_NO	(1 << 2)
+#  define HL_SYSCONFIG_IDLEMODE_SMART	(2 << 2)
+#  define HL_SYSCONFIG_IDLEMODE_WC	(3 << 2) /* Smart-Idle wakeup-capable */
+#  define HL_SYSCONFIG_FREEEMU		(1 << 1)
+#  define HL_SYSCONFIG_SOFTRESET	(1 << 0)
+
 #define MMCHS_SYSCONFIG		0x010	/* System Configuration */
 #  define SYSCONFIG_CLOCKACTIVITY_MASK	(3 << 8)
 #  define SYSCONFIG_CLOCKACTIVITY_FCLK	(2 << 8)
@@ -88,7 +112,5 @@
 #  define CON_INIT			(1 << 1)	/* Send init stream */
 #  define CON_OD			(1 << 0)	/* Card open drain */
 #define MMCHS_PWCNT		0x030	/* Power counter */
-#define MMCHS_SYSCTL		0x12c	/* SD system control register */
-#  define SYSCTL_CEN			(1 << 2)	/* Clock enable */
 
 #endif

Reply via email to