Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Jun 2012 02:55:42 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r236372 - head/sys/arm/at91
Message-ID:  <201206010255.q512tgHS078850@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Fri Jun  1 02:55:42 2012
New Revision: 236372
URL: http://svn.freebsd.org/changeset/base/236372

Log:
  Initialize the clocks before we call cninit() so that the serial
  console so initialized will work upon return from cninit.  While this
  is the very next line, other platforms setup all this stuff before
  calling cninit.  Also, initialize the SDRAM base register in the inner
  block in at91_ramsize().

Modified:
  head/sys/arm/at91/at91_machdep.c
  head/sys/arm/at91/at91_mci.c
  head/sys/arm/at91/at91reg.h
  head/sys/arm/at91/at91rm92reg.h
  head/sys/arm/at91/files.at91sam9
  head/sys/arm/at91/std.at91sam9

Modified: head/sys/arm/at91/at91_machdep.c
==============================================================================
--- head/sys/arm/at91/at91_machdep.c	Thu May 31 23:56:10 2012	(r236371)
+++ head/sys/arm/at91/at91_machdep.c	Fri Jun  1 02:55:42 2012	(r236372)
@@ -209,12 +209,11 @@ const struct pmap_devmap at91_devmap[] =
 long
 at91_ramsize(void)
 {
-	uint32_t *SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE);
 	uint32_t cr, mr;
 	int banks, rows, cols, bw;
 
 	if (at91_is_rm92()) {
-		SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE);
+		uint32_t *SDRAMC = (uint32_t *)(AT91_BASE + AT91RM92_SDRAMC_BASE);
 		cr = SDRAMC[AT91RM92_SDRAMC_CR / 4];
 		mr = SDRAMC[AT91RM92_SDRAMC_MR / 4];
 		banks = (cr & AT91RM92_SDRAMC_CR_NB_4) ? 2 : 1;
@@ -222,9 +221,9 @@ at91_ramsize(void)
 		cols = (cr & AT91RM92_SDRAMC_CR_NC_MASK) + 8;
 		bw = (mr & AT91RM92_SDRAMC_MR_DBW_16) ? 1 : 2;
 	} else {
-		/* This should be good for the 9260, 9261 and 9G20 as addresses
+		/* This should be good for the 9260, 9261, 9G20, 9G35 and 9X25 as addresses
 		 * and registers are the same */
-		SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G20_SDRAMC_BASE);
+		uint32_t *SDRAMC = (uint32_t *)(AT91_BASE + AT91SAM9G20_SDRAMC_BASE);
 		cr = SDRAMC[AT91SAM9G20_SDRAMC_CR / 4];
 		mr = SDRAMC[AT91SAM9G20_SDRAMC_MR / 4];
 		banks = (cr & AT91SAM9G20_SDRAMC_CR_NB_4) ? 2 : 1;
@@ -361,12 +360,13 @@ initarm(void *arg, void *arg2)
 	cpu_tlb_flushID();
 	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
 
-	cninit();
+	/* Initialize all the clocks, so that the console can work */
+	at91_pmc_init_clock();
 
-        at91_pmc_init_clock();
 	/* Get chip id so device drivers know about differences */
-	at91_chip_id = *(volatile uint32_t *)
-		(AT91_BASE + AT91_DBGU_BASE + DBGU_C1R);
+	at91_chip_id = *(uint32_t *)(AT91_BASE + AT91_DBGU_BASE + DBGU_C1R);
+
+	cninit();
 
 	memsize = board_init();
 	physmem = memsize / PAGE_SIZE;

Modified: head/sys/arm/at91/at91_mci.c
==============================================================================
--- head/sys/arm/at91/at91_mci.c	Thu May 31 23:56:10 2012	(r236371)
+++ head/sys/arm/at91/at91_mci.c	Fri Jun  1 02:55:42 2012	(r236372)
@@ -69,6 +69,11 @@ __FBSDID("$FreeBSD$");
 
 #define BBSZ	512
 
+/*
+ * Note:  This driver only supports the SlotA card.  No attempt has been made
+ * to support SlotB.
+ */
+
 struct at91_mci_softc {
 	void *intrhand;			/* Interrupt handle */
 	device_t dev;
@@ -244,6 +249,13 @@ at91_mci_attach(device_t dev)
 
 	sc->host.host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
 	sc->host.caps = 0;
+	/*
+	 * The in-tree Linux driver doesn't allow 4-wire operation for the
+	 * at91rm9200, but does for other members of the family.  The atmel
+	 * patches to this do allow it, or have in the past.  It is unclear
+	 * that the hardware even works, but my boot loader uses 4-bit bus
+	 * in polling mode successfully.
+	 */
 	if (sc->sc_cap & CAP_HAS_4WIRE)
 		sc->host.caps |= MMC_CAP_4_BIT_DATA;
 	child = device_add_child(dev, "mmc", 0);
@@ -363,9 +375,9 @@ at91_mci_update_ios(device_t brdev, devi
 			clkdiv = (at91_master_clock / ios->clock) / 2;
 	}
 	if (ios->bus_width == bus_width_4)
-		WR4(sc, MCI_SDCR, RD4(sc, MCI_SDCR) | MCI_SDCR_SDCBUS);
+		WR4(sc, MCI_SDCR, MCI_SDCR_SDCBUS);
 	else
-		WR4(sc, MCI_SDCR, RD4(sc, MCI_SDCR) & ~MCI_SDCR_SDCBUS);
+		WR4(sc, MCI_SDCR, 0);
 	WR4(sc, MCI_MR, (RD4(sc, MCI_MR) & ~MCI_MR_CLKDIV) | clkdiv);
 	/* Do we need a settle time here? */
 	/* XXX We need to turn the device on/off here with a GPIO pin */
@@ -407,7 +419,9 @@ at91_mci_start_cmd(struct at91_mci_softc
 	if (!data) {
 		// The no data case is fairly simple
 		at91_mci_pdc_disable(sc);
-//		printf("CMDR %x ARGR %x\n", cmdr, cmd->arg);
+#ifdef AT91_MCI_DEBUG
+		printf("CMDR %x ARGR %x\n", cmdr, cmd->arg);
+#endif
 		WR4(sc, MCI_ARGR, cmd->arg);
 		WR4(sc, MCI_CMDR, cmdr);
 		WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_CMDRDY);
@@ -479,7 +493,9 @@ at91_mci_start_cmd(struct at91_mci_softc
 			ier = MCI_SR_TXBUFE;
 		}
 	}
-//	printf("CMDR %x ARGR %x with data\n", cmdr, cmd->arg);
+#ifdef AT91_MCI_DEBUG
+	printf("CMDR %x ARGR %x with data\n", cmdr, cmd->arg);
+#endif
 	WR4(sc, MCI_ARGR, cmd->arg);
 	if (cmdr & MCI_CMDR_TRCMD_START) {
 		if (cmdr & MCI_CMDR_TRDIR) {
@@ -518,6 +534,14 @@ at91_mci_start(struct at91_mci_softc *sc
 	sc->req = NULL;
 	sc->curcmd = NULL;
 	req->done(req);
+	/*
+	 * Attempted hack-a-round for the DMA bug for multiple reads.
+	 */
+	if (req->cmd->opcode == MMC_READ_MULTIPLE_BLOCK) {
+		at91_mci_fini(sc->dev);
+		at91_mci_init(sc->dev);
+		at91_mci_update_ios(sc->dev, NULL);
+	}
 }
 
 static int
@@ -578,7 +602,9 @@ at91_mci_read_done(struct at91_mci_softc
 	uint32_t *walker;
 	struct mmc_command *cmd;
 	int i, len;
-
+#ifdef AT91_MCI_DEBUG
+	char *w2;
+#endif
 	cmd = sc->curcmd;
 	bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTREAD);
 	bus_dmamap_unload(sc->dmatag, sc->map);
@@ -589,6 +615,15 @@ at91_mci_read_done(struct at91_mci_softc
 		for (i = 0; i < len; i++)
 			walker[i] = bswap32(walker[i]);
 	}
+#ifdef AT91_MCI_DEBUG
+	printf("Read data\n");
+	for (i = 0, w2 = cmd->data->data; i < cmd->data->len; i++) {
+		if (i % 16 == 0)
+			printf("%08x  ", cmd->arg + i);
+		printf("%02x%s", w2[i], (i + 1) % 16 ? " " : "\n");
+	}
+	printf("\n");
+#endif
 	// Finish up the sequence...
 	WR4(sc, MCI_IDR, MCI_SR_ENDRX);
 	WR4(sc, MCI_IER, MCI_SR_RXBUFF);
@@ -624,14 +659,19 @@ at91_mci_intr(void *arg)
 		if ((sr & MCI_SR_RCRCE) && (cmd->opcode == MMC_SEND_OP_COND ||
 		    cmd->opcode == ACMD_SD_SEND_OP_COND))
 			cmd->error = MMC_ERR_NONE;
-		else if (sr & (MCI_SR_RTOE | MCI_SR_DTOE))
+		else if (sr & (MCI_SR_RTOE | MCI_SR_DTOE)) {
+			printf("TIMEOUT %#x\n", sr);
 			cmd->error = MMC_ERR_TIMEOUT;
-		else if (sr & (MCI_SR_RCRCE | MCI_SR_DCRCE))
+		} else if (sr & (MCI_SR_RCRCE | MCI_SR_DCRCE)) {
+			printf("CRC %#x\n", sr);
 			cmd->error = MMC_ERR_BADCRC;
-		else if (sr & (MCI_SR_OVRE | MCI_SR_UNRE))
+		} else if (sr & (MCI_SR_OVRE | MCI_SR_UNRE)) {
+			printf("FIFO %#x\n", sr);
 			cmd->error = MMC_ERR_FIFO;
-		else
+		} else {
+			printf("FAILED %#x\n", sr);
 			cmd->error = MMC_ERR_FAILED;
+		}
 		done = 1;
 		if (sc->mapped && cmd->error) {
 			bus_dmamap_unload(sc->dmatag, sc->map);
@@ -743,7 +783,7 @@ at91_mci_read_ivar(device_t bus, device_
 		*(int *)result = sc->host.caps;
 		break;
 	case MMCBR_IVAR_MAX_DATA:
-		*(int *)result = 1;
+		*(int *)result = 1024;
 		break;
 	}
 	return (0);

Modified: head/sys/arm/at91/at91reg.h
==============================================================================
--- head/sys/arm/at91/at91reg.h	Thu May 31 23:56:10 2012	(r236371)
+++ head/sys/arm/at91/at91reg.h	Fri Jun  1 02:55:42 2012	(r236372)
@@ -67,6 +67,7 @@
 #define	AT91_CPU_SAM9XE128	0x329973a0
 #define	AT91_CPU_SAM9XE256	0x329a93a0
 #define	AT91_CPU_SAM9XE512	0x329aa3a0
+#define AT91_CPU_SAM9X25  0x819a05a0    /* Same as the SAM9G35 */
 
 #define	AT91_ARCH(chipid)	((chipid >> 20) & 0xff)
 #define	AT91_CPU(chipid)	(chipid & ~AT91_CPU_VERSION_MASK)

Modified: head/sys/arm/at91/at91rm92reg.h
==============================================================================
--- head/sys/arm/at91/at91rm92reg.h	Thu May 31 23:56:10 2012	(r236371)
+++ head/sys/arm/at91/at91rm92reg.h	Fri Jun  1 02:55:42 2012	(r236372)
@@ -399,6 +399,10 @@
 #define AT91RM92_OHCI_PA_BASE	0x00300000
 #define AT91RM92_OHCI_SIZE	0x00100000
 
+#define	AT91RM92_FLS_BASE	0xdf000000
+#define	AT91RM92_FLS_PA_BASE	0x10000000
+#define	AT91RM92_FLS_SIZE	0x02000000	/* Support up to 32MB flash */
+
 #define	AT91RM92_CF_BASE	0xdfd00000
 #define	AT91RM92_CF_PA_BASE	0x51400000
 #define	AT91RM92_CF_SIZE	0x00100000

Modified: head/sys/arm/at91/files.at91sam9
==============================================================================
--- head/sys/arm/at91/files.at91sam9	Thu May 31 23:56:10 2012	(r236371)
+++ head/sys/arm/at91/files.at91sam9	Fri Jun  1 02:55:42 2012	(r236372)
@@ -25,13 +25,15 @@ dev/usb/controller/ohci_atmelarm.c	optio
 #
 # All the "systems on a chip" we support
 #
-arm/at91/at91sam9g20.c		optional	at91sam9g20
 arm/at91/at91sam9260.c		optional	at91sam9260
+arm/at91/at91sam9g20.c		optional	at91sam9g20
+arm/at91/at91sam9x25.c		optional	at91sam9x25
 #
 #
 # All the boards we support
 #
 arm/at91/board_ethernut5.c	optional	at91_board_ethernut5
 arm/at91/board_hl201.c		optional	at91_board_hl201
-arm/at91/board_sam9g20ek.c	optional	at91_board_sam9g20ek
 arm/at91/board_qila9g20.c	optional	at91_board_qila9g20
+arm/at91/board_sam9g20ek.c	optional	at91_board_sam9g20ek
+arm/at91/board_sam9x25ek.c	optional	at91_board_sam9x25ek

Modified: head/sys/arm/at91/std.at91sam9
==============================================================================
--- head/sys/arm/at91/std.at91sam9	Thu May 31 23:56:10 2012	(r236371)
+++ head/sys/arm/at91/std.at91sam9	Fri Jun  1 02:55:42 2012	(r236372)
@@ -7,3 +7,4 @@ options 	PHYSADDR=0x20000000
 
 device		at91sam9g20
 device		at91sam9260
+device		at91sam9x25



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