svn commit: r194670 - head/sys/arm/xscale/ixp425

Sam Leffler sam at FreeBSD.org
Mon Jun 22 22:54:14 UTC 2009


Author: sam
Date: Mon Jun 22 22:54:13 2009
New Revision: 194670
URL: http://svn.freebsd.org/changeset/base/194670

Log:
  o add a bus space tag that forces a 2usec delay between r/w ops; this is
    used for the optional GPS+RS485 uarts on the Gateworks Cambria boards
    which otherwise are unreliable
  o setup the hack bus space tag for the GPS+RS485 uarts
  o program the gpio interrupts for the uarts to be edge-rising
  o force timing on the expansion bus for the uarts to be "slow"
  
  Thanks to Chris Lang of Gateworks for these tips.

Added:
  head/sys/arm/xscale/ixp425/cambria_exp_space.c   (contents, props changed)
Modified:
  head/sys/arm/xscale/ixp425/files.avila
  head/sys/arm/xscale/ixp425/ixp425.c
  head/sys/arm/xscale/ixp425/ixp425var.h

Added: head/sys/arm/xscale/ixp425/cambria_exp_space.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/xscale/ixp425/cambria_exp_space.c	Mon Jun 22 22:54:13 2009	(r194670)
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2009 Sam Leffler.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Hack bus space tag for slow devices on the Cambria expansion bus;
+ * we slow the timing and add a 2us delay between r/w ops.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+
+#include <arm/xscale/ixp425/ixp425reg.h>
+#include <arm/xscale/ixp425/ixp425var.h>
+
+/* Prototypes for all the bus_space structure functions */
+bs_protos(exp);
+bs_protos(generic);
+bs_protos(generic_armv4);
+
+static uint8_t
+cambria_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o)
+{
+	DELAY(2);
+	return bus_space_read_1((struct bus_space *)t, h, o);
+}
+
+static void
+cambria_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
+{
+	DELAY(2);
+	bus_space_write_1((struct bus_space *)t, h, o, v);
+}
+
+/* NB: we only define what's needed by uart */
+struct bus_space cambria_exp_bs_tag = {
+	/* mapping/unmapping */
+	.bs_map		= generic_bs_map,
+	.bs_unmap	= generic_bs_unmap,
+
+	/* barrier */
+	.bs_barrier	= generic_bs_barrier,
+
+	/* read (single) */
+	.bs_r_1		= cambria_bs_r_1,
+
+	/* write (single) */
+	.bs_w_1		= cambria_bs_w_1,
+};
+
+void
+cambria_exp_bus_init(struct ixp425_softc *sc)
+{
+	uint32_t cs3;
+
+	KASSERT(cpu_is_ixp43x(), ("wrong cpu type"));
+
+	cambria_exp_bs_tag.bs_cookie = sc->sc_iot;
+
+	cs3 = EXP_BUS_READ_4(sc, EXP_TIMING_CS3_OFFSET);
+	/* XXX force slowest possible timings and byte mode */
+	EXP_BUS_WRITE_4(sc, EXP_TIMING_CS3_OFFSET,
+	    cs3 | (EXP_T1|EXP_T2|EXP_T3|EXP_T4|EXP_T5) | EXP_BYTE_EN);
+
+	/* XXX force GPIO 3+4 for GPS+RS485 uarts */
+	ixp425_set_gpio(sc, 3, GPIO_TYPE_EDG_RISING);
+	ixp425_set_gpio(sc, 4, GPIO_TYPE_EDG_RISING);
+}

Modified: head/sys/arm/xscale/ixp425/files.avila
==============================================================================
--- head/sys/arm/xscale/ixp425/files.avila	Mon Jun 22 22:47:06 2009	(r194669)
+++ head/sys/arm/xscale/ixp425/files.avila	Mon Jun 22 22:54:13 2009	(r194670)
@@ -2,6 +2,7 @@
 arm/xscale/ixp425/avila_machdep.c	standard
 arm/xscale/ixp425/avila_ata.c		optional avila_ata
 arm/xscale/ixp425/avila_led.c		optional avila_led
-arm/xscale/ixp425/cambria_led.c		optional cambria_led
+arm/xscale/ixp425/cambria_exp_space.c	standard
 arm/xscale/ixp425/cambria_fled.c	optional cambria_fled
+arm/xscale/ixp425/cambria_led.c		optional cambria_led
 arm/xscale/ixp425/ixdp425_pci.c		optional pci

Modified: head/sys/arm/xscale/ixp425/ixp425.c
==============================================================================
--- head/sys/arm/xscale/ixp425/ixp425.c	Mon Jun 22 22:47:06 2009	(r194669)
+++ head/sys/arm/xscale/ixp425/ixp425.c	Mon Jun 22 22:54:13 2009	(r194670)
@@ -313,6 +313,17 @@ ixp425_attach(device_t dev)
 	}
 	arm_post_filter = ixp425_post_filter;
 
+	if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE,
+	    0, &sc->sc_gpio_ioh))
+		panic("%s: unable to map GPIO registers", __func__);
+	if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
+	    0, &sc->sc_exp_ioh))
+		panic("%s: unable to map Expansion Bus registers", __func__);
+
+	/* XXX belongs in platform init */
+	if (cpu_is_ixp43x())
+		cambria_exp_bus_init(sc);
+
 	if (bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT,
 	    BUS_SPACE_MAXADDR, NULL, NULL,  0xffffffff, 0xff, 0xffffffff, 0, 
 	    NULL, NULL, &sc->sc_dmat))
@@ -339,13 +350,6 @@ ixp425_attach(device_t dev)
 	/* attach wired devices via hints */
 	bus_enumerate_hinted_children(dev);
 
-	if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE,
-	    0, &sc->sc_gpio_ioh))
-		panic("%s: unable to map GPIO registers", __func__);
-	if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
-	    0, &sc->sc_exp_ioh))
-		panic("%s: unable to map Expansion Bus registers", __func__);
-
 	bus_generic_probe(dev);
 	bus_generic_attach(dev);
 
@@ -420,6 +424,7 @@ struct hwvtrans {
 	uint32_t	size;
 	uint32_t	vbase;
 	int		isa4x;	/* XXX needs special bus space tag */
+	int		isslow;	/* XXX needs special bus space tag */
 };
 
 static const struct hwvtrans *
@@ -453,10 +458,12 @@ gethwvtrans(uint32_t hwbase, uint32_t si
 	      .vbase	= IXP435_USB2_VBASE },
 	    { .hwbase	= CAMBRIA_GPS_HWBASE,
 	      .size 	= CAMBRIA_GPS_SIZE,
-	      .vbase	= CAMBRIA_GPS_VBASE },
+	      .vbase	= CAMBRIA_GPS_VBASE,
+	      .isslow	= 1 },
 	    { .hwbase	= CAMBRIA_RS485_HWBASE,
 	      .size 	= CAMBRIA_RS485_SIZE,
-	      .vbase	= CAMBRIA_RS485_VBASE },
+	      .vbase	= CAMBRIA_RS485_VBASE,
+	      .isslow	= 1 },
 	};
 	int i;
 
@@ -522,7 +529,8 @@ ixp425_alloc_resource(device_t dev, devi
 					device_printf(child,
 					    "%s: assign 0x%lx:0x%lx%s\n",
 					    __func__, start, end - start,
-					    vtrans->isa4x ? " A4X" : "");
+					    vtrans->isa4x ? " A4X" : 
+					    vtrans->isslow ? " SLOW" : "");
 			}
 		} else
 			vtrans = gethwvtrans(start, end - start);
@@ -578,6 +586,8 @@ ixp425_activate_resource(device_t dev, d
 		}
 		if (vtrans->isa4x)
 			rman_set_bustag(r, &ixp425_a4x_bs_tag);
+		else if (vtrans->isslow)
+			rman_set_bustag(r, &cambria_exp_bs_tag);
 		else
 			rman_set_bustag(r, sc->sc_iot);
 		rman_set_bushandle(r, vtrans->vbase);

Modified: head/sys/arm/xscale/ixp425/ixp425var.h
==============================================================================
--- head/sys/arm/xscale/ixp425/ixp425var.h	Mon Jun 22 22:47:06 2009	(r194669)
+++ head/sys/arm/xscale/ixp425/ixp425var.h	Mon Jun 22 22:54:13 2009	(r194670)
@@ -97,6 +97,9 @@ struct ixppcib_softc {
 extern struct bus_space ixp425_bs_tag;
 extern struct bus_space ixp425_a4x_bs_tag;
 
+extern struct bus_space cambria_exp_bs_tag;
+void	cambria_exp_bus_init(struct ixp425_softc *);
+
 void	ixp425_io_bs_init(bus_space_tag_t, void *);
 void	ixp425_mem_bs_init(bus_space_tag_t, void *);
 


More information about the svn-src-all mailing list