svn commit: r186909 - in head/sys/arm/mv: . discovery kirkwood orion

Rafal Jaworowski raj at FreeBSD.org
Thu Jan 8 10:31:44 PST 2009


Author: raj
Date: Thu Jan  8 18:31:43 2009
New Revision: 186909
URL: http://svn.freebsd.org/changeset/base/186909

Log:
  Improve and extend Marvell SOCs platform code.
  
  - Allow for setting per platform MPP/GPIO configuration in the kernel, so
    that we can override all settings firmware might set.
  
  - Set decode windows for the remaining on-chip peripherals: CESA, SATA and XOR.
  
  - Improve handling of USB controllers so that all port are available on the
    given SOC/platform (e.g. up to three on DB-78xxx), this includes rework of
    USB decode windows set-up.
  
  - Other minor fixes and cosmetics.
  
  Obtained from:	Semihalf

Modified:
  head/sys/arm/mv/common.c
  head/sys/arm/mv/discovery/db78xxx.c
  head/sys/arm/mv/discovery/discovery.c
  head/sys/arm/mv/gpio.c
  head/sys/arm/mv/kirkwood/db88f6xxx.c
  head/sys/arm/mv/kirkwood/kirkwood.c
  head/sys/arm/mv/mv_machdep.c
  head/sys/arm/mv/mvreg.h
  head/sys/arm/mv/mvvar.h
  head/sys/arm/mv/obio.c
  head/sys/arm/mv/orion/db88f5xxx.c
  head/sys/arm/mv/orion/orion.c

Modified: head/sys/arm/mv/common.c
==============================================================================
--- head/sys/arm/mv/common.c	Thu Jan  8 18:24:04 2009	(r186908)
+++ head/sys/arm/mv/common.c	Thu Jan  8 18:31:43 2009	(r186909)
@@ -46,13 +46,19 @@ static int decode_win_cpu_valid(void);
 static int decode_win_usb_valid(void);
 static int decode_win_eth_valid(void);
 static int decode_win_pcie_valid(void);
+static int decode_win_sata_valid(void);
+static int decode_win_cesa_valid(void);
 
 static void decode_win_cpu_setup(void);
-static void decode_win_usb_setup(uint32_t ctrl);
+static void decode_win_usb_setup(void);
 static void decode_win_eth_setup(uint32_t base);
 static void decode_win_pcie_setup(uint32_t base);
+static void decode_win_sata_setup(void);
+static void decode_win_cesa_setup(void);
+
+static void decode_win_cesa_dump(void);
+static void decode_win_usb_dump(void);
 
-static uint32_t dev, rev;
 static uint32_t used_cpu_wins;
 
 uint32_t
@@ -81,6 +87,7 @@ cpu_reset(void)
 uint32_t
 cpu_extra_feat(void)
 {
+	uint32_t dev, rev;
 	uint32_t ef = 0;
 
 	soc_id(&dev, &rev);
@@ -178,22 +185,27 @@ soc_identify(void)
 int
 soc_decode_win(void)
 {
+	uint32_t dev, rev;
 
 	/* Retrieve our ID: some windows facilities vary between SoC models */
 	soc_id(&dev, &rev);
 
 	if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
 	    decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
-	    decode_win_pcie_valid() != 1)
+	    decode_win_pcie_valid() != 1 || decode_win_sata_valid() != 1 ||
+	    decode_win_cesa_valid() != 1)
 		return(-1);
 
 	decode_win_cpu_setup();
-	decode_win_usb_setup(MV_USB0_BASE);
+	decode_win_usb_setup();
 	decode_win_eth_setup(MV_ETH0_BASE);
 	if (dev == MV_DEV_MV78100)
 		decode_win_eth_setup(MV_ETH1_BASE);
+	if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100)
+		decode_win_cesa_setup();
 
 	decode_win_idma_setup();
+	decode_win_xor_setup();
 
 	if (dev == MV_DEV_MV78100) {
 		decode_win_pcie_setup(MV_PCIE00_BASE);
@@ -207,7 +219,8 @@ soc_decode_win(void)
 	} else
 		decode_win_pcie_setup(MV_PCIE_BASE);
 
-	/* TODO set up decode wins for SATA */
+	if (dev != MV_DEV_88F5281)
+		decode_win_sata_setup();
 
 	return (0);
 }
@@ -227,10 +240,15 @@ WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_
 WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
 WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
 
-WIN_REG_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
-WIN_REG_IDX_RD(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
-WIN_REG_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
-WIN_REG_IDX_WR(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
+WIN_REG_IDX_RD2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
+WIN_REG_IDX_RD2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
+WIN_REG_IDX_WR2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
+WIN_REG_IDX_WR2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
+
+WIN_REG_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
+WIN_REG_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
+WIN_REG_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
+WIN_REG_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
 
 WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
 WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
@@ -238,6 +256,16 @@ WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN
 WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
 WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
 WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
+
+WIN_REG_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
+WIN_REG_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
+WIN_REG_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
+WIN_REG_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
+WIN_REG_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
+WIN_REG_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
+WIN_REG_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
+WIN_REG_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
+
 WIN_REG_BASE_RD(win_eth, bare, 0x290)
 WIN_REG_BASE_RD(win_eth, epap, 0x294)
 WIN_REG_BASE_WR(win_eth, bare, 0x290)
@@ -262,12 +290,18 @@ WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDM
 WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
 WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
 
+WIN_REG_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
+WIN_REG_IDX_RD(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
+WIN_REG_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
+WIN_REG_IDX_WR(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
+
 /**************************************************************************
  * Decode windows helper routines
  **************************************************************************/
 void
 soc_dump_decode_win(void)
 {
+	uint32_t dev, rev;
 	int i;
 
 	soc_id(&dev, &rev);
@@ -290,10 +324,6 @@ soc_dump_decode_win(void)
 	for (i = 0; i < MV_WIN_DDR_MAX; i++)
 		printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
 		    ddr_br_read(i), ddr_sz_read(i));
-	
-	for (i = 0; i < MV_WIN_USB_MAX; i++)
-		printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
-		    win_usb_cr_read(i), win_usb_br_read(i));
 
 	for (i = 0; i < MV_WIN_ETH_MAX; i++) {
 		printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
@@ -311,6 +341,8 @@ soc_dump_decode_win(void)
 	    win_eth_epap_read(MV_ETH0_BASE));
 
 	decode_win_idma_dump();
+	decode_win_cesa_dump();
+	decode_win_usb_dump();
 	printf("\n");
 }
 
@@ -320,6 +352,9 @@ soc_dump_decode_win(void)
 int
 win_cpu_can_remap(int i)
 {
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
 
 	/* Depending on the SoC certain windows have remap capability */
 	if ((dev == MV_DEV_88F5182 && i < 2) ||
@@ -549,42 +584,69 @@ decode_win_usb_valid(void)
 	return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
 }
 
+static __inline int
+usb_max_ports(void)
+{
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
+	return (dev == MV_DEV_MV78100 ? 3 : 1);
+}
+
+static void
+decode_win_usb_dump(void)
+{
+	int i, p, m;
+
+	m = usb_max_ports();
+	for (p = 0; p < m; p++)
+		for (i = 0; i < MV_WIN_USB_MAX; i++)
+			printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
+			    win_usb_cr_read(i, p), win_usb_br_read(i, p));
+}
+
 /*
  * Set USB decode windows.
  */
 static void
-decode_win_usb_setup(uint32_t ctrl)
+decode_win_usb_setup(void)
 {
 	uint32_t br, cr;
-	int i, j;
+	int i, j, p, m;
 
-	/* Disable and clear all USB windows */
-	for (i = 0; i < MV_WIN_USB_MAX; i++) {
-		win_usb_cr_write(i, 0);
-		win_usb_br_write(i, 0);
-	}
-
-	/* Only access to active DRAM banks is required */
-	for (i = 0; i < MV_WIN_DDR_MAX; i++)
-		if (ddr_is_active(i)) {
-			br = ddr_base(i);
-			/*
-			 * XXX for 6281 we should handle Mbus write burst limit
-			 * field in the ctrl reg
-			 */
-			cr = (((ddr_size(i) - 1) & 0xffff0000) |
-			    (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
+	/* Disable and clear all USB windows for all ports */
+	m = usb_max_ports();
+	for (p = 0; p < m; p++) {
+
+		for (i = 0; i < MV_WIN_USB_MAX; i++) {
+			win_usb_cr_write(i, p, 0);
+			win_usb_br_write(i, p, 0);
+		}
 
-			/* Set the first free USB window */
-			for (j = 0; j < MV_WIN_USB_MAX; j++) {
-				if (win_usb_cr_read(j) & 0x1)
-					continue;
+		/* Only access to active DRAM banks is required */
+		for (i = 0; i < MV_WIN_DDR_MAX; i++) {
+			if (ddr_is_active(i)) {
+				br = ddr_base(i);
+				/*
+				 * XXX for 6281 we should handle Mbus write
+				 * burst limit field in the ctrl reg
+				 */
+				cr = (((ddr_size(i) - 1) & 0xffff0000) |
+				    (ddr_attr(i) << 8) |
+				    (ddr_target(i) << 4) | 1);
+
+				/* Set the first free USB window */
+				for (j = 0; j < MV_WIN_USB_MAX; j++) {
+					if (win_usb_cr_read(j, p) & 0x1)
+						continue;
 
-				win_usb_br_write(j, br);
-				win_usb_cr_write(j, cr);
-				break;
+					win_usb_br_write(j, p, br);
+					win_usb_cr_write(j, p, cr);
+					break;
+				}
 			}
 		}
+	}
 }
 
 /**************************************************************************
@@ -934,7 +996,7 @@ decode_win_idma_valid(void)
 		j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
 		if (j >= 0) {
 			printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
-			    "with " "#%d (0x%08x - 0x%08x)\n", i, b, e, j,
+			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
 			    idma_wins[j].base,
 			    idma_wins[j].base + idma_wins[j].size - 1);
 			rv = 0;
@@ -983,3 +1045,413 @@ decode_win_idma_dump(void)
 {
 }
 #endif
+
+/**************************************************************************
+ * XOR windows routines
+ **************************************************************************/
+#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+static int
+xor_ctrl_read(int i, int c, int e)
+{
+	uint32_t v;
+	v = win_xor_ctrl_read(c, e);
+	v &= (1 << i);
+
+	return (v >> i);
+}
+
+static void
+xor_ctrl_write(int i, int c, int e, int val)
+{
+	uint32_t v;
+
+	v = win_xor_ctrl_read(c, e);
+	v &= ~(1 << i);
+	v |= (val << i);
+	win_xor_ctrl_write(c, e, v);
+}
+
+/*
+ * Set channel protection 'val' for window 'w' on channel 'c'
+ */
+
+static void
+xor_chan_write(int c, int e, int w, int val)
+{
+	uint32_t v;
+
+	v = win_xor_ctrl_read(c, e);
+	v &= ~(0x3 << (w * 2 + 16));
+	v |= (val << (w * 2 + 16));
+	win_xor_ctrl_write(c, e, v);
+}
+
+/*
+ * Set protection 'val' on all channels for window 'w' on engine 'e'
+ */
+static void
+xor_set_prot(int w, int e, int val)
+{
+	int c;
+
+	for (c = 0; c < MV_XOR_CHAN_MAX; c++)
+		xor_chan_write(c, e, w, val);
+}
+
+static int
+win_xor_can_remap(int i)
+{
+
+	/* XOR decode windows 0-3 have remap capability */
+	if (i < 4)
+		return (1);
+
+	return (0);
+}
+
+static __inline int
+xor_max_eng(void)
+{
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
+	return ((dev == MV_DEV_88F6281) ? 2 :
+	    (dev == MV_DEV_MV78100) ? 1 : 0);
+}
+
+static void
+xor_active_dram(int c, int e, int *window)
+{
+	uint32_t br, sz;
+	int i, m, w;
+
+	/*
+	 * Set up access to all active DRAM banks
+	 */
+	m = xor_max_eng();
+	for (i = 0; i < m; i++)
+		if (ddr_is_active(i)) {
+			br = ddr_base(i) | (ddr_attr(i) << 8) |
+			    ddr_target(i);
+			sz = ((ddr_size(i) - 1) & 0xffff0000);
+
+			/* Place DDR entries in non-remapped windows */
+			for (w = 0; w < MV_WIN_XOR_MAX; w++)
+				if (win_xor_can_remap(w) != 1 &&
+				    (xor_ctrl_read(w, c, e) == 0) &&
+				    w > *window) {
+					/* Configure window */
+					win_xor_br_write(w, e, br);
+					win_xor_sz_write(w, e, sz);
+
+					/* Set protection RW on all channels */
+					xor_set_prot(w, e, 0x3);
+
+					/* Enable window */
+					xor_ctrl_write(w, c, e, 1);
+					(*window)++;
+					break;
+				}
+		}
+}
+
+void
+decode_win_xor_setup(void)
+{
+	uint32_t br, sz;
+	int i, j, z, e = 1, m, window;
+
+	/*
+	 * Disable and clear all XOR windows, revoke protection for all
+	 * channels
+	 */
+	m = xor_max_eng();
+	for (j = 0; j < m; j++, e--) {
+
+		/* Number of non-remaped windows */
+		window = MV_XOR_NON_REMAP - 1;
+
+		for (i = 0; i < MV_WIN_XOR_MAX; i++) {
+			win_xor_br_write(i, e, 0);
+			win_xor_sz_write(i, e, 0);
+		}
+
+		if (win_xor_can_remap(i) == 1)
+			win_xor_har_write(i, e, 0);
+
+		for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
+			win_xor_ctrl_write(i, e, 0);
+			xor_active_dram(i, e, &window);
+		}
+
+		/*
+		 * Remaining targets -- from a statically defined table
+		 */
+		for (i = 0; i < xor_wins_no; i++)
+			if (xor_wins[i].target > 0) {
+				br = (xor_wins[i].base & 0xffff0000) |
+				    (xor_wins[i].attr << 8) |
+				    xor_wins[i].target;
+				sz = ((xor_wins[i].size - 1) & 0xffff0000);
+
+				/* Set the first free XOR window */
+				for (z = 0; z < MV_WIN_XOR_MAX; z++) {
+					if (xor_ctrl_read(z, 0, e) &&
+					    xor_ctrl_read(z, 1, e))
+						continue;
+
+					/* Configure window */
+					win_xor_br_write(z, e, br);
+					win_xor_sz_write(z, e, sz);
+					if (win_xor_can_remap(z) &&
+					    xor_wins[z].remap >= 0)
+						win_xor_har_write(z, e,
+						    xor_wins[z].remap);
+
+					/* Set protection RW on all channels */
+					xor_set_prot(z, e, 0x3);
+
+					/* Enable window */
+					xor_ctrl_write(z, 0, e, 1);
+					xor_ctrl_write(z, 1, e, 1);
+					break;
+				}
+			}
+	}
+}
+
+int
+decode_win_xor_valid(void)
+{
+	const struct decode_win *wintab;
+	int c, i, j, rv;
+	uint32_t b, e, s;
+
+	if (xor_wins_no > MV_WIN_XOR_MAX) {
+		printf("XOR windows: too many entries: %d\n", xor_wins_no);
+		return (-1);
+	}
+	for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i))
+			c++;
+
+	if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
+		printf("XOR windows: too many entries: %d, available: %d\n",
+		    xor_wins_no, MV_WIN_IDMA_MAX - c);
+		return (-1);
+	}
+
+	wintab = xor_wins;
+	rv = 1;
+	for (i = 0; i < xor_wins_no; i++, wintab++) {
+
+		if (wintab->target == 0) {
+			printf("XOR window#%d: DDR target window is not "
+			    "supposed to be reprogrammed!\n", i);
+			rv = 0;
+		}
+
+		if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
+			printf("XOR window#%d: not capable of remapping, but "
+			    "val 0x%08x defined\n", i, wintab->remap);
+			rv = 0;
+		}
+
+		s = wintab->size;
+		b = wintab->base;
+		e = b + s - 1;
+		if (s > (0xFFFFFFFF - b + 1)) {
+			/*
+			 * XXX this boundary check should account for 64bit
+			 * and remapping..
+			 */
+			printf("XOR window#%d: no space for size 0x%08x at "
+			    "0x%08x\n", i, s, b);
+			rv = 0;
+			continue;
+		}
+
+		j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
+		if (j >= 0) {
+			printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
+			    "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
+			    xor_wins[j].base,
+			    xor_wins[j].base + xor_wins[j].size - 1);
+			rv = 0;
+		}
+	}
+
+	return (rv);
+}
+
+void
+decode_win_xor_dump(void)
+{
+	int i, j;
+	int e = 1;
+
+	for (j = 0; j < xor_max_eng(); j++, e--) {
+		for (i = 0; i < MV_WIN_XOR_MAX; i++) {
+			printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
+			    win_xor_br_read(i, e), win_xor_sz_read(i, e));
+
+			if (win_xor_can_remap(i))
+				printf(", ha 0x%08x", win_xor_har_read(i, e));
+
+			printf("\n");
+		}
+		for (i = 0; i < MV_XOR_CHAN_MAX; i++)
+			printf("XOR control#%d: 0x%08x\n", i,
+			    win_xor_ctrl_read(i, e));
+	}
+}
+
+#else
+/* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
+int
+decode_win_xor_valid(void)
+{
+
+	return (1);
+}
+
+void
+decode_win_xor_setup(void)
+{
+}
+
+void
+decode_win_xor_dump(void)
+{
+}
+#endif
+
+/**************************************************************************
+ * CESA TDMA windows routines
+ **************************************************************************/
+#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
+/*
+ * Dump CESA TDMA decode windows.
+ */
+static void
+decode_win_cesa_dump(void)
+{
+	int i;
+
+	for (i = 0; i < MV_WIN_CESA_MAX; i++)
+		printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
+		    win_cesa_cr_read(i), win_cesa_br_read(i));
+}
+
+
+/*
+ * Set CESA TDMA decode windows.
+ */
+static void
+decode_win_cesa_setup(void)
+{
+	uint32_t br, cr;
+	int i, j;
+
+	/* Disable and clear all CESA windows */
+	for (i = 0; i < MV_WIN_CESA_MAX; i++) {
+		win_cesa_cr_write(i, 0);
+		win_cesa_br_write(i, 0);
+	}
+
+	/* Only access to active DRAM banks is required. */
+	for (i = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i)) {
+			br = ddr_base(i);
+			cr = (((ddr_size(i) - 1) & 0xffff0000) |
+			   (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
+
+			/* Set the first available CESA window */
+			for (j = 0; j < MV_WIN_CESA_MAX; j++) {
+				if (win_cesa_cr_read(j) & 0x1)
+					continue;
+
+				win_cesa_br_write(j, br);
+				win_cesa_cr_write(j, cr);
+				break;
+			}
+		}
+}
+
+/*
+ * Check CESA TDMA decode windows.
+ */
+static int
+decode_win_cesa_valid(void)
+{
+
+	return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
+}
+#else
+
+/*
+ * Provide dummy functions to satisfy the build for SoCs not equipped with
+ * CESA
+ */
+
+int
+decode_win_cesa_valid(void)
+{
+
+	return (1);
+}
+
+void
+decode_win_cesa_setup(void)
+{
+}
+
+void
+decode_win_cesa_dump(void)
+{
+}
+#endif
+
+/**************************************************************************
+ * SATA windows routines
+ **************************************************************************/
+static void
+decode_win_sata_setup(void)
+{
+	uint32_t cr, br;
+	int i, j;
+
+	for (i = 0; i < MV_WIN_SATA_MAX; i++) {
+		win_sata_cr_write(i, 0);
+		win_sata_br_write(i, 0);
+	}
+
+	for (i = 0; i < MV_WIN_DDR_MAX; i++)
+		if (ddr_is_active(i)) {
+			cr = ((ddr_size(i) - 1) & 0xffff0000) |
+			    (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
+			br = ddr_base(i);
+
+			/* Use the first available SATA window */
+			for (j = 0; j < MV_WIN_SATA_MAX; j++) {
+				if ((win_sata_cr_read(j) & 1) != 0)
+					continue;
+
+				win_sata_br_write(j, br);
+				win_sata_cr_write(j, cr);
+				break;
+			}
+		}
+}
+
+static int
+decode_win_sata_valid(void)
+{
+	uint32_t dev, rev;
+
+	soc_id(&dev, &rev);
+	if (dev == MV_DEV_88F5281)
+		return (1);
+
+	return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
+}

Modified: head/sys/arm/mv/discovery/db78xxx.c
==============================================================================
--- head/sys/arm/mv/discovery/db78xxx.c	Thu Jan  8 18:24:04 2009	(r186908)
+++ head/sys/arm/mv/discovery/db78xxx.c	Thu Jan  8 18:31:43 2009	(r186909)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
+#include <machine/bus.h>
 #include <machine/pte.h>
 #include <machine/pmap.h>
 #include <machine/vmparam.h>
@@ -99,6 +100,10 @@ static const struct pmap_devmap pmap_dev
 	{ 0, 0, 0, 0, 0, }
 };
 
+const struct gpio_config mv_gpio_config[] = {
+	{ -1, -1, -1 }
+};
+
 int
 platform_pmap_init(void)
 {
@@ -109,6 +114,52 @@ platform_pmap_init(void)
 	return (0);
 }
 
+void
+platform_mpp_init(void)
+{
+
+	/*
+	 * MPP Configuration for DB-78100-BP
+	 *
+	 * MPP[0]:  GE1_TXCLK
+	 * MPP[1]:  GE1_TXCTL
+	 * MPP[2]:  GE1_RXCTL
+	 * MPP[3]:  GE1_RXCLK
+	 * MPP[4]:  GE1_TXD[0]
+	 * MPP[5]:  GE1_TXD[1]
+	 * MPP[6]:  GE1_TXD[2]
+	 * MPP[7]:  GE1_TXD[3]
+	 * MPP[8]:  GE1_RXD[0]
+	 * MPP[9]:  GE1_RXD[1]
+	 * MPP[10]: GE1_RXD[2]
+	 * MPP[11]: GE1_RXD[3]
+	 * MPP[13]: SYSRST_OUTn
+	 * MPP[14]: SATA1_ACT
+	 * MPP[15]: SATA0_ACT
+	 * MPP[16]: UA2_TXD
+	 * MPP[17]: UA2_RXD
+	 * MPP[18]: <UNKNOWN>
+	 * MPP[19]: <UNKNOWN>
+	 * MPP[20]: <UNKNOWN>
+	 * MPP[21]: <UNKNOWN>
+	 * MPP[22]: UA3_TXD
+	 * MPP[23]: UA3_RXD
+	 * MPP[48]: <UNKNOWN>
+	 * MPP[49]: <UNKNOWN>
+	 *
+	 * Others:  GPIO
+	 *
+	 * <UNKNOWN> entries are not documented, not on the schematics etc.
+	 */
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x22222222);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x33302222);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x44333344);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00000000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x0000FFFF);
+}
+
 static void
 platform_identify(void *dummy)
 {
@@ -121,7 +172,3 @@ platform_identify(void *dummy)
 	 */
 }
 SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
-
-/*
- * TODO routine setting GPIO/MPP pins
- */

Modified: head/sys/arm/mv/discovery/discovery.c
==============================================================================
--- head/sys/arm/mv/discovery/discovery.c	Thu Jan  8 18:24:04 2009	(r186908)
+++ head/sys/arm/mv/discovery/discovery.c	Thu Jan  8 18:31:43 2009	(r186909)
@@ -103,6 +103,16 @@ struct obio_device obio_devices[] = {
 		{ -1 },
 		CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
 	},
+	{ "ehci", MV_USB1_BASE, MV_USB_SIZE,
+		{ MV_INT_USB_ERR, MV_INT_USB1, -1 },
+		{ -1 },
+		CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
+	},
+	{ "ehci", MV_USB2_BASE, MV_USB_SIZE,
+		{ MV_INT_USB_ERR, MV_INT_USB2, -1 },
+		{ -1 },
+		CPU_PM_CTRL_USB0 | CPU_PM_CTRL_USB1 | CPU_PM_CTRL_USB2
+	},
 	{ "mge", MV_ETH0_BASE, MV_ETH_SIZE,
 		{ MV_INT_GBERX, MV_INT_GBETX, MV_INT_GBEMISC,
 		  MV_INT_GBESUM, MV_INT_GBE_ERR, -1 },
@@ -177,7 +187,7 @@ const struct obio_pci mv_pci_info[] = {
 	{ 0, 0, 0 }
 };
 
-struct resource_spec mv_gpio_spec[] = {
+struct resource_spec mv_gpio_res[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
@@ -186,7 +196,7 @@ struct resource_spec mv_gpio_spec[] = {
 	{ -1, 0 }
 };
 
-struct resource_spec mv_xor_spec[] = {
+struct resource_spec mv_xor_res[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
@@ -206,6 +216,9 @@ const struct decode_win cpu_win_tbl[] = 
 
 	/* Device bus CS2 */
 	{ 1, 0x3b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
+
+	/* CESA */
+	{ 9, 0x01, MV_CESA_SRAM_PHYS_BASE, MV_CESA_SRAM_SIZE, -1 },
 };
 const struct decode_win *cpu_wins = cpu_win_tbl;
 int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
@@ -227,6 +240,14 @@ const struct decode_win idma_win_tbl[] =
 const struct decode_win *idma_wins = idma_win_tbl;
 int idma_wins_no = sizeof(idma_win_tbl) / sizeof(struct decode_win);
 
+const struct decode_win xor_win_tbl[] = {
+	/* PCIE MEM */
+	{ 4, 0xE8, _MV_PCIE_MEM_PHYS(0), _MV_PCIE_MEM_SIZE, -1},
+	{ 4, 0xD8, _MV_PCIE_MEM_PHYS(1), _MV_PCIE_MEM_SIZE, -1},
+};
+const struct decode_win *xor_wins = xor_win_tbl;
+int xor_wins_no = sizeof(xor_win_tbl) / sizeof(struct decode_win);
+
 uint32_t
 get_tclk(void)
 {

Modified: head/sys/arm/mv/gpio.c
==============================================================================
--- head/sys/arm/mv/gpio.c	Thu Jan  8 18:24:04 2009	(r186908)
+++ head/sys/arm/mv/gpio.c	Thu Jan  8 18:31:43 2009	(r186909)
@@ -62,7 +62,7 @@ struct mv_gpio_softc {
 	uint8_t			use_high;
 };
 
-extern struct resource_spec mv_gpio_spec[];
+extern struct resource_spec mv_gpio_res[];
 
 static struct mv_gpio_softc *mv_gpio_softc = NULL;
 static uint32_t	gpio_setup[MV_GPIO_MAX_NPINS];
@@ -143,7 +143,7 @@ mv_gpio_attach(device_t dev)
 		return (ENXIO);
 	}
 
-	error = bus_alloc_resources(dev, mv_gpio_spec, sc->res);
+	error = bus_alloc_resources(dev, mv_gpio_res, sc->res);
 	if (error) {
 		device_printf(dev, "could not allocate resources\n");
 		return (ENXIO);
@@ -171,21 +171,33 @@ mv_gpio_attach(device_t dev)
 		    INTR_TYPE_MISC | INTR_FAST,
 		    (driver_filter_t *)mv_gpio_intr, NULL,
 		    sc, &sc->ih_cookie[i]) != 0) {
-			bus_release_resources(dev, mv_gpio_spec, sc->res);
+			bus_release_resources(dev, mv_gpio_res, sc->res);
 			device_printf(dev, "could not set up intr %d\n", i);
 			return (ENXIO);
 		}
 	}
 
+	/* Setup GPIO lines */
+	for (i = 0; mv_gpio_config[i].gc_gpio >= 0; i++) {
+		mv_gpio_configure(mv_gpio_config[i].gc_gpio,
+		    mv_gpio_config[i].gc_flags, ~0u);
+
+		if (mv_gpio_config[i].gc_output < 0)
+			mv_gpio_out_en(mv_gpio_config[i].gc_gpio, 0);
+		else
+			mv_gpio_out(mv_gpio_config[i].gc_gpio,
+			    mv_gpio_config[i].gc_output, 1);
+	}
+
 	return (0);
 }
 
 static void
 mv_gpio_intr(void *arg)
 {
-	uint32_t	int_cause, gpio_val;
-	uint32_t	int_cause_hi, gpio_val_hi = 0;
-	int		i;
+	uint32_t int_cause, gpio_val;
+	uint32_t int_cause_hi, gpio_val_hi = 0;
+	int i;
 
 	int_cause = mv_gpio_reg_read(GPIO_INT_CAUSE);
 	gpio_val = mv_gpio_reg_read(GPIO_DATA_IN);
@@ -295,8 +307,8 @@ mv_gpio_configure(uint32_t pin, uint32_t
 
 	if (mask & MV_GPIO_BLINK)
 		mv_gpio_blink(pin, flags & MV_GPIO_BLINK);
-	if (mask & MV_GPIO_POLARITY)
-		mv_gpio_polarity(pin, flags & MV_GPIO_POLARITY);
+	if (mask & MV_GPIO_POLAR_LOW)
+		mv_gpio_polarity(pin, flags & MV_GPIO_POLAR_LOW);
 	if (mask & MV_GPIO_EDGE)
 		mv_gpio_edge(pin, flags & MV_GPIO_EDGE);
 	if (mask & MV_GPIO_LEVEL)

Modified: head/sys/arm/mv/kirkwood/db88f6xxx.c
==============================================================================
--- head/sys/arm/mv/kirkwood/db88f6xxx.c	Thu Jan  8 18:24:04 2009	(r186908)
+++ head/sys/arm/mv/kirkwood/db88f6xxx.c	Thu Jan  8 18:31:43 2009	(r186909)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
+#include <machine/bus.h>
 #include <machine/pte.h>
 #include <machine/pmap.h>
 #include <machine/vmparam.h>
@@ -99,6 +100,10 @@ static const struct pmap_devmap pmap_dev
 	{ 0, 0, 0, 0, 0, }
 };
 
+const struct gpio_config mv_gpio_config[] = {
+	{ -1, -1, -1 }
+};
+
 int
 platform_pmap_init(void)
 {
@@ -109,6 +114,47 @@ platform_pmap_init(void)
 	return (0);
 }
 
+void
+platform_mpp_init(void)
+{
+
+	/*
+	 * MPP configuration for DB-88F6281-BP and DB-88F6281-BP-A
+	 *
+	 * MPP[0]:  NF_IO[2]
+	 * MPP[1]:  NF_IO[3]
+	 * MPP[2]:  NF_IO[4]
+	 * MPP[3]:  NF_IO[5]
+	 * MPP[4]:  NF_IO[6]
+	 * MPP[5]:  NF_IO[7]
+	 * MPP[6]:  SYSRST_OUTn
+	 * MPP[7]:  SPI_SCn
+	 * MPP[8]:  TW_SDA
+	 * MPP[9]:  TW_SCK
+	 * MPP[10]: UA0_TXD
+	 * MPP[11]: UA0_RXD
+	 * MPP[12]: SD_CLK
+	 * MPP[13]: SD_CMD
+	 * MPP[14]: SD_D[0]
+	 * MPP[15]: SD_D[1]
+	 * MPP[16]: SD_D[2]
+	 * MPP[17]: SD_D[3]
+	 * MPP[18]: NF_IO[0]
+	 * MPP[19]: NF_IO[1]
+	 * MPP[20]: SATA1_AC
+	 * MPP[21]: SATA0_AC
+	 *
+	 * Others:  GPIO
+	 */
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL0, 0x21111111);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL1, 0x11113311);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL2, 0x00551111);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL3, 0x00000000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL4, 0x00000000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL5, 0x00000000);
+	bus_space_write_4(obio_tag, MV_MPP_BASE, MPP_CONTROL6, 0x00000000);
+}
+
 static void
 platform_identify(void *dummy)
 {
@@ -121,7 +167,3 @@ platform_identify(void *dummy)
 	 */
 }
 SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, NULL);
-
-/*
- * TODO routine setting GPIO/MPP pins
- */

Modified: head/sys/arm/mv/kirkwood/kirkwood.c
==============================================================================
--- head/sys/arm/mv/kirkwood/kirkwood.c	Thu Jan  8 18:24:04 2009	(r186908)
+++ head/sys/arm/mv/kirkwood/kirkwood.c	Thu Jan  8 18:31:43 2009	(r186909)
@@ -112,7 +112,7 @@ const struct obio_pci mv_pci_info[] = {
 	{ 0, 0, 0 }
 };
 
-struct resource_spec mv_gpio_spec[] = {
+struct resource_spec mv_gpio_res[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
@@ -124,7 +124,7 @@ struct resource_spec mv_gpio_spec[] = {
 	{ -1, 0 }
 };
 
-struct resource_spec mv_xor_spec[] = {
+struct resource_spec mv_xor_res[] = {
 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
 	{ SYS_RES_IRQ,		1,	RF_ACTIVE },
@@ -147,10 +147,21 @@ const struct decode_win cpu_win_tbl[] = 
 
 	/* Device bus CS2 */
 	{ 1, 0x1b, MV_DEV_CS2_PHYS_BASE, MV_DEV_CS2_SIZE, -1 },
+
+	/* CESA */
+	{ 3, 0x00, MV_CESA_SRAM_PHYS_BASE, MV_CESA_SRAM_SIZE, -1 },
+
 };
 const struct decode_win *cpu_wins = cpu_win_tbl;
 int cpu_wins_no = sizeof(cpu_win_tbl) / sizeof(struct decode_win);
 
+const struct decode_win xor_win_tbl[] = {
+	/* PCIE MEM */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list