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.
This commit is contained in:
parent
2fddb9e2cc
commit
0d93c7da52
95
sys/arm/xscale/ixp425/cambria_exp_space.c
Normal file
95
sys/arm/xscale/ixp425/cambria_exp_space.c
Normal file
@ -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);
|
||||
}
|
@ -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
|
||||
|
@ -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 size)
|
||||
.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, device_t child, int type, int *rid,
|
||||
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, device_t child, int type, int rid,
|
||||
}
|
||||
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);
|
||||
|
@ -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 *);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user