Clean up gt and peripherals.

This change tested compile only.
This commit is contained in:
kiyohara 2010-04-28 13:51:55 +00:00
parent 248d65d640
commit a748aedcb5
51 changed files with 7409 additions and 10507 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: EV64260,v 1.43 2010/04/16 13:48:31 pooka Exp $
# $NetBSD: EV64260,v 1.44 2010/04/28 13:51:56 kiyohara Exp $
#
# MVP -- Motorola's Multiprocessing Verification Platform
#
@ -13,22 +13,25 @@ maxusers 32
#options UVMHIST
#options UVMHIST_PRINT
#options MULTIPROCESSOR # Discovery II/III support
# PowerPC options
options ALTIVEC
#options CLOCKBASE=100000000 # EVB64260
options CLOCKBASE=133000000 # EVB64260A
# Marvell options
options GT_MPP_INTERRUPTS=0x2c600000
options GT_MPP_WATCHDOG=0x03000000
options MPSC_CONSOLE=0
options GT_MPSC_DEFAULT_BAUD_RATE=9600
#options GT_BASE=0x14000000 # PMON low
options GT_BASE=0xF8000000 # PPCBoot
options GT_MPSC_FREQUENCY="(cpu_timebase*4)"
options GT_MPSC_CLOCK_SOURCE="BRG_BCR_CLKS_TCLK"
options PCI0_GPPINTS=0xffffff1b,PCI1_GPPINTS=0xffffff1d
options PCI0_SKIPMASK="(~0x180)",PCI1_SKIPMASK="(~0x180)"
options GT_MPP_WATCHDOG=0x03000000
options GT_DEVBUS
#options GT_ECC
options GT_COMM
options GT_WATCHDOG
# EV64260 options
options OBIO0_STRIDE=0,OBIO1_STRIDE=2,OBIO2_STRIDE=2,OBIO3_STRIDE=2
# Options for necessary to use MD
@ -153,40 +156,42 @@ mainbus0 at root
cpu* at mainbus0
gt0 at mainbus0 # Discovery system controller
# Discovery system controller
#gt0 at mainbus0 addr 0x14000000 # PMON low
gt0 at mainbus0 addr 0xf8000000 # PPCBoot
# PCI busses
gtpci0 at gt0 unit 0 # 64-bit, 66MHz
gtpci1 at gt0 unit 1 # 64-bit, 66MHz
pci* at gtpci?
gtpci* at gt? unit ? # 64-bit, 66MHz
pci* at gtpci?
# 16550s off CS2
obio0 at gt0 unit 0 # Chip Select 0
obio1 at gt0 unit 1 # Chip Select 1
obio2 at gt0 unit 2 # Chip Select 2
com0 at obio2 offset 0x0020 size 8 irq 85
com1 at obio2 offset 0x0000 size 8 irq 86
obio3 at gt0 unit 3 # Chip Select 3
obio4 at gt0 unit 4 # Boot Chip Select
obio0 at gt0 unit 0 # Chip Select 0
obio1 at gt0 unit 1 # Chip Select 1
obio2 at gt0 unit 2 # Chip Select 2
com0 at obio2 offset 0x0020 size 8 irq 85
com1 at obio2 offset 0x0000 size 8 irq 86
obio3 at gt0 unit 3 # Chip Select 3
obio4 at gt0 unit 4 # Boot Chip Select
# UARTs
gtmpsc0 at gt0 unit 0 # Serial #0
gtmpsc1 at gt0 unit 1 # Serial #1
gtmpsc* at gt? offset ? # Multi-Protocol Serial Controller
# with Serial Direct Memory Access
# Ethernet and PHY
gfe0 at gt0 unit 0 flags 1 # Ethernet #0 (RMMI)
gfe1 at gt0 unit 1 flags 1 # Ethernet #1 (RMMI)
gfe2 at gt0 unit 2 flags 1 # Ethernet #2 (RMMI)
gfec* at gt? offset ? # Ethernet (RMMI)
gfe* at gfec? port ? irq ? # Ethernet port #0/#1/#2
# I2C
gtiic0 at gt0 unit 0 # I2C controller
iic* at gtiic?
gttwsi* at gt? offset ? irq ? # Two-Wire Serial Interface
iic* at gttwsi?
# DMA
gtidmac* at gt? offset ? irq ? # IDMA Controller
# PCI devices
ppb* at pci? dev ? function ? # PCI-PCI bridges
pci* at ppb? bus ?
#pcib* at pci? dev ? function ? # VIA 82C686B
pchb* at pci? dev ? function ? # PCI Host Bridge
ppb* at pci? dev ? function ? # PCI-PCI Bridges
pci* at ppb? bus ?
#ehci* at pci? dev ? function ? # Enhanced Host Controller
#ohci* at pci? dev ? function ? # Open Host Controller
@ -273,3 +278,5 @@ pseudo-device rnd # /dev/random and in-kernel generator
#pseudo-device wsmux # ick
pseudo-device clockctl # user control of clock subsystem
pseudo-device ksyms # /dev/ksyms
pseudo-device swdmover # softare dmover(9) back-end
pseudo-device dmoverio # /dev/dmover dmover(9) interface

View File

@ -1,33 +1,32 @@
# $NetBSD: files.ev64260,v 1.12 2008/02/20 21:43:34 drochner Exp $
# $NetBSD: files.ev64260,v 1.13 2010/04/28 13:51:56 kiyohara Exp $
#
# Marvell (Galileo) "EV64260" evaluation board's specific configuration info
#
defparam opt_ev64260.h OBIO0_STRIDE OBIO1_STRIDE OBIO2_STRIDE OBIO3_STRIDE
defparam opt_ev64260.h PCI0_GPPINTS PCI1_GPPINTS PCI0_SKIPMASK PCI1_SKIPMASK
#include "arch/powerpc/pic/files.pic"
file arch/evbppc/ev64260/autoconf.c
file arch/evbppc/ev64260/machdep.c
#file arch/evbppc/ev64260/pci_machdep.c
file arch/powerpc/powerpc/clock.c
file arch/powerpc/marvell/extintr.c
#options PIC_DISCOVERY
include "arch/powerpc/pic/files.pic"
file arch/powerpc/marvell/pic_discovery.c
#
# MI devices
#
include "dev/ata/files.ata"
include "dev/i2o/files.i2o"
include "dev/pci/files.pci"
include "dev/scsipi/files.scsipi"
include "dev/usb/files.usb"
#
# Marvell GT (Discovery) devices
#
include "dev/marvell/files.discovery"
#
# Machine-independent SCSI drivers
#
include "dev/scsipi/files.scsipi"
#
# Machine-independent ATA drivers
#
include "dev/ata/files.ata"
#
# Memory Disk for install floppy
@ -41,57 +40,23 @@ file dev/md_root.c memory_disk_hooks
#
# System bus types
#
device mainbus {}
device mainbus { [addr = -1] }
attach mainbus at root
file arch/evbppc/ev64260/mainbus.c mainbus|cpu needs-flag
attach gt at mainbus
file arch/evbppc/ev64260/gt_mainbus.c gt
file arch/evbppc/ev64260/mainbus.c mainbus | cpu needs-flag
device cpu
attach cpu at mainbus
attach gt at mainbus
file arch/evbppc/ev64260/gt_mainbus.c gt
file arch/powerpc/marvell/pci_machdep.c pci
file arch/powerpc/pci/pci_machdep_common.c pci
device pchb: pcibus
attach pchb at pci
file dev/marvell/pchb.c pchb
# com port
attach com at obio with com_obio
file arch/evbppc/ev64260/com_obio.c com_obio
# wdc port
attach wdc at obio with wdc_obio
file arch/evbppc/ev64260/wdc_obio.c wdc_obio
#
# PCI-only drivers
#
include "dev/i2o/files.i2o"
include "dev/pci/files.pci"
# PCI-ISA bridges
device pcib: isabus
attach pcib at pci
file arch/evbppc/pci/pcib.c pcib
#
# ISA drivers
#
include "dev/isa/files.isa"
file arch/evbppc/isa/isa_machdep.c isa
file arch/evbppc/isa/isadma_machdep.c isa
# PC clock
file arch/evbppc/isa/isaclock.c isa
include "dev/pckbport/files.pckbport"
include "dev/usb/files.usb"
# Floppy disk controller
device fdc {drive = -1}: isadma
file dev/isa/fd.c fdc needs-flag
attach fdc at isa with fdc_isa
file dev/isa/fdc_isa.c fdc_isa
device fd: disk
attach fd at fdc

View File

@ -1,4 +1,4 @@
# $NetBSD: std.ev64260,v 1.7 2008/01/08 13:47:49 joerg Exp $
# $NetBSD: std.ev64260,v 1.8 2010/04/28 13:51:56 kiyohara Exp $
#
# standard, required NetBSD/evbppc 'options'
@ -18,6 +18,6 @@ makeoptions BOARDTYPE="ev64260"
options INTSTK=16384
options PPC_INTR_IMPL="<powerpc/marvell/marvell_intr.h>"
options PPC_PCI_MACHDEP_IMPL="<powerpc/marvell/pci_machdep.h>"
options PPC_PCI_MACHDEP_IMPL="<powerpc/pci_machdep.h>"
include "arch/evbppc/conf/files.ev64260"

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.12 2009/03/18 10:22:28 cegger Exp $ */
/* $NetBSD: autoconf.c,v 1.13 2010/04/28 13:51:55 kiyohara Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -37,24 +37,34 @@
/*
* Setup the system to run on the current machine.
*
* Configure() is called at boot time and initializes the vba
* Configure() is called at boot time and initializes the vba
* device tables and the memory controller monitoring. Available
* devices are determined (from possibilities mentioned in ioconf.c),
* and the drivers are initialized.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.12 2009/03/18 10:22:28 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.13 2010/04/28 13:51:55 kiyohara Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/disklabel.h>
#include <sys/conf.h>
#include <sys/reboot.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <net/if.h>
#include <net/if_ether.h>
#include <dev/pci/pcivar.h>
#include <machine/pci_machdep.h>
#include <dev/marvell/gtreg.h>
#include <dev/marvell/marvellvar.h>
static void findroot(void);
void findroot(void);
/*
* Determine i/o configuration for a machine.
@ -62,25 +72,14 @@ void findroot(void);
void
cpu_configure(void)
{
extern void init_interrupt(void);
extintr_disable();
init_interrupt();
if (config_rootfound("mainbus", NULL) == NULL)
panic("configure: mainbus not configured");
printf("biomask %x.%x.%x.%x netmask %x.%x.%x.%x ttymask %x.%x.%x.%x\n",
imask[IPL_BIO].bits[0], imask[IPL_BIO].bits[1],
imask[IPL_BIO].bits[2], imask[IPL_BIO].bits[3],
imask[IPL_NET].bits[0], imask[IPL_NET].bits[1],
imask[IPL_NET].bits[2], imask[IPL_NET].bits[3],
imask[IPL_TTY].bits[0], imask[IPL_TTY].bits[1],
imask[IPL_TTY].bits[2], imask[IPL_TTY].bits[3]);
curcpu()->ci_cpl = IPL_NONE;
extintr_enable();
aprint_normal("biomask %jx netmask %jx ttymask %jx\n",
imask[IPL_BIO] & 0x3fffffffffffffff,
imask[IPL_NET] & 0x3fffffffffffffff,
imask[IPL_TTY] & 0x3fffffffffffffff);
spl0();
}
@ -103,7 +102,7 @@ dev_t bootdev = 0;
* If we can do so, and not instructed not to do so,
* change rootdev to correspond to the load device.
*/
void
static void
findroot(void)
{
device_t dv;
@ -130,4 +129,95 @@ findroot(void)
void
device_register(struct device *dev, void *aux)
{
prop_dictionary_t dict = device_properties(dev);
if (device_is_a(dev, "gfe") &&
device_is_a(device_parent(dev), "gt") ) {
struct marvell_attach_args *mva = aux;
prop_data_t mac;
char enaddr[ETHER_ADDR_LEN] =
{ 0x02, 0x00, 0x04, 0x00, 0x00, 0x04 };
switch (mva->mva_offset) {
case ETH0_BASE: enaddr[5] |= 0; break;
case ETH1_BASE: enaddr[5] |= 1; break;
case ETH2_BASE: enaddr[5] |= 2; break;
default:
aprint_error("WARNING: unknown mac-no. for %s\n",
dev->dv_xname);
}
mac = prop_data_create_data_nocopy(enaddr, ETHER_ADDR_LEN);
KASSERT(mac != NULL);
if (prop_dictionary_set(dict, "mac-addr", mac) == false)
aprint_error(
"WARNING: unable to set mac-addr property for %s\n",
dev->dv_xname);
prop_object_release(mac);
}
if (device_is_a(dev, "gtpci")) {
extern struct powerpc_bus_space
ev64260_pci0_io_bs_tag, ev64260_pci0_mem_bs_tag,
ev64260_pci1_io_bs_tag, ev64260_pci1_mem_bs_tag;
extern struct genppc_pci_chipset
genppc_gtpci0_chipset, genppc_gtpci1_chipset;
struct marvell_attach_args *mva = aux;
struct powerpc_bus_space *pci_io_bs_tag, *pci_mem_bs_tag;
struct genppc_pci_chipset *genppc_gtpci_chipset;
prop_data_t io_bs_tag, mem_bs_tag, pc;
if (mva->mva_unit == 0) {
pci_io_bs_tag = &ev64260_pci0_io_bs_tag;
pci_mem_bs_tag = &ev64260_pci0_mem_bs_tag;
genppc_gtpci_chipset = &genppc_gtpci0_chipset;
} else {
pci_io_bs_tag = &ev64260_pci1_io_bs_tag;
pci_mem_bs_tag = &ev64260_pci1_mem_bs_tag;
genppc_gtpci_chipset = &genppc_gtpci1_chipset;
}
io_bs_tag = prop_data_create_data_nocopy(
pci_io_bs_tag, sizeof(struct powerpc_bus_space));
KASSERT(io_bs_tag != NULL);
prop_dictionary_set(dict, "io-bus-tag", io_bs_tag);
prop_object_release(io_bs_tag);
mem_bs_tag = prop_data_create_data_nocopy(
pci_mem_bs_tag, sizeof(struct powerpc_bus_space));
KASSERT(mem_bs_tag != NULL);
prop_dictionary_set(dict, "mem-bus-tag", mem_bs_tag);
prop_object_release(mem_bs_tag);
genppc_gtpci_chipset->pc_conf_v = device_private(dev);
pc = prop_data_create_data_nocopy(genppc_gtpci_chipset,
sizeof(struct genppc_pci_chipset));
KASSERT(pc != NULL);
prop_dictionary_set(dict, "pci-chipset", pc);
prop_object_release(pc);
prop_dictionary_set_uint64(dict, "iostart", 0x00000600);
prop_dictionary_set_uint64(dict, "ioend", 0x0000ffff);
prop_dictionary_set_uint64(dict, "memstart",
pci_mem_bs_tag->pbs_base);
prop_dictionary_set_uint64(dict, "memend",
pci_mem_bs_tag->pbs_limit - 1);
prop_dictionary_set_uint32(dict, "cache-line-size", 32);
}
if (device_is_a(dev, "obio") &&
device_is_a(device_parent(dev), "gt") ) {
extern struct powerpc_bus_space *ev64260_obio_bs_tags[5];
struct marvell_attach_args *mva = aux;
struct powerpc_bus_space *bst =
ev64260_obio_bs_tags[mva->mva_unit];
prop_data_t bstd;
bstd =
prop_data_create_data_nocopy(bst, sizeof(bus_space_tag_t));
KASSERT(bstd != NULL);
if (prop_dictionary_set(dict, "bus-tag", bstd) == false)
aprint_error(
"WARNING: unable to set bus-tag property for %s\n",
dev->dv_xname);
prop_object_release(bstd);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: com_obio.c,v 1.9 2009/11/21 17:40:28 rmind Exp $ */
/* $NetBSD: com_obio.c,v 1.10 2010/04/28 13:51:55 kiyohara Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: com_obio.c,v 1.9 2009/11/21 17:40:28 rmind Exp $");
__KERNEL_RCSID(0, "$NetBSD: com_obio.c,v 1.10 2010/04/28 13:51:55 kiyohara Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -86,6 +86,8 @@ __KERNEL_RCSID(0, "$NetBSD: com_obio.c,v 1.9 2009/11/21 17:40:28 rmind Exp $");
#include <dev/marvell/gtvar.h>
#include "locators.h"
struct com_obio_softc {
struct com_softc osc_com; /* real "com" softc */
@ -105,8 +107,8 @@ com_obio_match(device_t parent, cfdata_t cf, void *aux)
bus_space_handle_t ioh;
int rv = 0;
if (oa->oa_offset == OBIO_UNK_OFFSET ||
oa->oa_size == OBIO_UNK_SIZE)
if (oa->oa_offset == OBIOCF_OFFSET_DEFAULT ||
oa->oa_size == OBIOCF_SIZE_DEFAULT)
return (0);
if (com_is_console(oa->oa_memt, oa->oa_offset, NULL)) {
@ -146,7 +148,6 @@ com_obio_attach(device_t parent, device_t self, void *aux)
if (oa->oa_irq >= 0) {
intr_establish(oa->oa_irq, IST_EDGE, IPL_SERIAL, comintr, sc);
aprint_normal_dev(self, "interrupting at %s\n",
intr_string(oa->oa_irq));
aprint_normal_dev(self, "interrupting at %d\n", oa->oa_irq);
}
}

View File

@ -0,0 +1,37 @@
/* $NetBSD: ev64260.h,v 1.1 2010/04/28 13:51:55 kiyohara Exp $ */
/*
* Copyright (c) 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _EVBPPC_EV64260_H_
#define _EVBPPC_EV64260_H_
struct mainbus_attach_args {
const char *mba_name;
int mba_unit;
bus_addr_t mba_addr;
};
#endif /* _EVBPPC_EV64260_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: gt_mainbus.c,v 1.14 2007/02/22 05:27:47 thorpej Exp $ */
/* $NetBSD: gt_mainbus.c,v 1.15 2010/04/28 13:51:55 kiyohara Exp $ */
/*
* Copyright (c) 2002 Wasabi Systems, Inc.
@ -36,13 +36,16 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gt_mainbus.c,v 1.14 2007/02/22 05:27:47 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: gt_mainbus.c,v 1.15 2010/04/28 13:51:55 kiyohara Exp $");
#include "opt_ev64260.h"
#include "opt_pci.h"
#include "pci.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/extent.h>
#include <sys/malloc.h>
@ -56,205 +59,188 @@ __KERNEL_RCSID(0, "$NetBSD: gt_mainbus.c,v 1.14 2007/02/22 05:27:47 thorpej Exp
#include "opt_marvell.h"
#include <dev/marvell/gtreg.h>
#include <dev/marvell/gtvar.h>
#include <dev/marvell/gtintrreg.h>
#include <dev/marvell/gtpcireg.h>
#include <dev/marvell/gtpcivar.h>
extern struct powerpc_bus_space gt_mem_bs_tag;
extern struct powerpc_bus_space gt_pci0_mem_bs_tag;
extern struct powerpc_bus_space gt_pci0_io_bs_tag;
extern struct powerpc_bus_space gt_pci1_mem_bs_tag;
extern struct powerpc_bus_space gt_pci1_io_bs_tag;
struct powerpc_bus_dma_tag gt_bus_dma_tag = {
0, /* _bounce_thresh */
_bus_dmamap_create,
_bus_dmamap_destroy,
_bus_dmamap_load,
_bus_dmamap_load_mbuf,
_bus_dmamap_load_uio,
_bus_dmamap_load_raw,
_bus_dmamap_unload,
_bus_dmamap_sync,
_bus_dmamem_alloc,
_bus_dmamem_free,
_bus_dmamem_map,
_bus_dmamem_unmap,
_bus_dmamem_mmap,
gt_dma_phys_to_bus_mem,
gt_dma_bus_mem_to_phys,
};
const int gtpci_skipmask[2] = {
#ifdef PCI0_SKIPMASK
PCI0_SKIPMASK,
#else
0,
#include <dev/marvell/marvellvar.h>
#include <dev/marvell/gtsdmareg.h>
#include <dev/marvell/gtmpscreg.h>
#ifdef MPSC_CONSOLE
#include <dev/marvell/gtmpscvar.h>
#endif
#ifdef PCI1_SKIPMASK
PCI1_SKIPMASK,
#else
0,
#endif
};
static int gt_match(struct device *, struct cfdata *, void *);
static void gt_attach(struct device *, struct device *, void *);
#include <evbppc/ev64260/ev64260.h>
CFATTACH_DECL(gt, sizeof(struct gt_softc), gt_match, gt_attach, NULL, NULL);
#include <powerpc/pic/picvar.h>
extern struct cfdriver gt_cd;
extern bus_space_handle_t gt_memh;
static int gt_found;
static int gt_match(device_t, cfdata_t, void *);
static void gt_attach(device_t, device_t, void *);
void gtpci_md_conf_interrupt(void *, int, int, int, int, int *);
int gtpci_md_conf_hook(void *, int, int, int, pcireg_t);
CFATTACH_DECL_NEW(gt, sizeof(struct gt_softc), gt_match, gt_attach, NULL, NULL);
int
gt_match(struct device *parent, struct cfdata *cf, void *aux)
gt_match(device_t parent, cfdata_t cf, void *aux)
{
const char **busname = aux;
struct mainbus_attach_args *mba = aux;
if (strcmp(*busname, gt_cd.cd_name) != 0)
return 0;
if (gt_found)
if (strcmp(mba->mba_name, "gt") != 0)
return 0;
return 1;
}
void
gt_attach(struct device *parent, struct device *self, void *aux)
gt_attach(device_t parent, device_t self, void *aux)
{
struct gt_softc *gt = (struct gt_softc *) self;
extern struct powerpc_bus_space ev64260_gt_bs_tag;
extern struct powerpc_bus_dma_tag ev64260_bus_dma_tag;
struct mainbus_attach_args *mba = aux;
struct gt_softc *sc = device_private(self);
uint32_t cpumstr, cr, r;
gt->gt_dmat = &gt_bus_dma_tag;
gt->gt_memt = &gt_mem_bs_tag;
gt->gt_pci0_memt = &gt_pci0_mem_bs_tag;
gt->gt_pci0_iot = &gt_pci0_io_bs_tag;
gt->gt_pci0_host = true;
gt->gt_pci1_memt = &gt_pci1_mem_bs_tag;
gt->gt_pci1_iot = &gt_pci1_io_bs_tag;
gt->gt_pci1_host = true;
sc->sc_dev = self;
sc->sc_addr = mba->mba_addr;
sc->sc_iot = &ev64260_gt_bs_tag;
sc->sc_dmat = &ev64260_bus_dma_tag;
gt->gt_memh = gt_memh;
#ifdef MPSC_CONSOLE
{
/* First, unmap already mapped console space. */
gtmpsc_softc_t *gtmpsc = &gtmpsc_cn_softc;
#if 0
GT_DecodeAddr_SET(gt, GT_PCI0_IO_Low_Decode,
gt_pci0_io_bs_tag.pbs_offset + gt_pci0_io_bs_tag.pbs_base);
GT_DecodeAddr_SET(gt, GT_PCI0_IO_High_Decode,
gt_pci0_io_bs_tag.pbs_offset + gt_pci0_io_bs_tag.pbs_limit - 1);
GT_DecodeAddr_SET(gt, GT_PCI1_IO_Low_Decode,
gt_pci1_io_bs_tag.pbs_offset + gt_pci1_io_bs_tag.pbs_base);
GT_DecodeAddr_SET(gt, GT_PCI1_IO_High_Decode,
gt_pci1_io_bs_tag.pbs_offset + gt_pci1_io_bs_tag.pbs_limit - 1);
GT_DecodeAddr_SET(gt, GT_PCI0_Mem0_Low_Decode,
gt_pci0_mem_bs_tag.pbs_offset + gt_pci0_mem_bs_tag.pbs_base);
GT_DecodeAddr_SET(gt, GT_PCI0_Mem0_High_Decode,
gt_pci1_mem_bs_tag.pbs_offset + gt_pci1_mem_bs_tag.pbs_limit - 1);
GT_DecodeAddr_SET(gt, GT_PCI1_Mem0_Low_Decode,
gt_pci1_mem_bs_tag.pbs_offset + gt_pci1_mem_bs_tag.pbs_base);
GT_DecodeAddr_SET(gt, GT_PCI1_Mem0_High_Decode,
gt_pci1_mem_bs_tag.pbs_offset + gt_pci1_mem_bs_tag.pbs_limit - 1);
#endif
gt_attach_common(gt);
}
void
gtpci_bus_configure(struct gtpci_chipset *gtpc)
{
#ifdef PCI_NETBSD_CONFIGURE
struct extent *ioext, *memext;
#if 0
extern int pci_conf_debug;
pci_conf_debug = 1;
#endif
switch (gtpc->gtpc_busno) {
case 0:
ioext = extent_create("pci0-io", 0x00000600, 0x0000ffff,
M_DEVBUF, NULL, 0, EX_NOWAIT);
memext = extent_create("pci0-mem",
gt_pci0_mem_bs_tag.pbs_base,
gt_pci0_mem_bs_tag.pbs_limit-1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
break;
case 1:
ioext = extent_create("pci1-io", 0x00000600, 0x0000ffff,
M_DEVBUF, NULL, 0, EX_NOWAIT);
memext = extent_create("pci1-mem",
gt_pci1_mem_bs_tag.pbs_base,
gt_pci1_mem_bs_tag.pbs_limit-1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
break;
default:
panic("gtpci_bus_configure: unknown bus %d", gtpc->gtpc_busno);
bus_space_unmap(gtmpsc->sc_iot, gtmpsc->sc_mpsch, GTMPSC_SIZE);
bus_space_unmap(gtmpsc->sc_iot, gtmpsc->sc_sdmah, GTSDMA_SIZE);
}
#endif
if (bus_space_map(sc->sc_iot, sc->sc_addr, GT_SIZE, 0, &sc->sc_ioh) !=
0) {
aprint_error_dev(self, "registers map failed\n");
return;
}
#ifdef MPSC_CONSOLE
{
/* Next, remap console space. */
gtmpsc_softc_t *gtmpsc = &gtmpsc_cn_softc;
pci_configure_bus(&gtpc->gtpc_pc, ioext, memext, NULL, 0, 32);
if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
GTMPSC_BASE(gtmpsc->sc_unit), GTMPSC_SIZE,
&gtmpsc->sc_mpsch)) {
aprint_error_dev(self, "Cannot map MPSC registers\n");
return;
}
if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
GTSDMA_BASE(gtmpsc->sc_unit), GTSDMA_SIZE,
&gtmpsc->sc_sdmah)) {
aprint_error_dev(self, "Cannot map SDMA registers\n");
return;
}
}
#endif
extent_destroy(ioext);
extent_destroy(memext);
#endif /* PCI_NETBSD_CONFIGURE */
/*
* Set MPSC Routing:
* MR0 --> Serial Port 0
* MR1 --> Serial Port 1
*/
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTMPSC_MRR, GTMPSC_MRR_RES);
/*
* RX and TX Clock Routing:
* CRR0 --> BRG0
* CRR1 --> BRG1
*/
cr = GTMPSC_CRR(0, GTMPSC_CRR_BRG0) | GTMPSC_CRR(1, GTMPSC_CRR_BRG1);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTMPSC_RCRR, cr);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTMPSC_TCRR, cr);
/*
* Setup Multi-Purpose Pins (MPP).
* Change to GPP.
* GPP 21 (DUART channel A intr)
* GPP 22 (DUART channel B intr)
* GPP 26 (RTC INT)
* GPP 27 (PCI 0 INTA)
* GPP 29 (PCI 1 INTA)
*/
#define PIN2SHIFT(pin) ((pin % 8) * 4)
r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_MPP_Control2);
r |= ((0xf << PIN2SHIFT(21)) | (0xf << PIN2SHIFT(22)));
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_MPP_Control2, r);
r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_MPP_Control3);
r |= ((0xf << PIN2SHIFT(26)));
r |= ((0xf << PIN2SHIFT(27)) | (0xf << PIN2SHIFT(29)));
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_MPP_Control3, r);
/* Also configure GPP. */
#define GPP_EXTERNAL_INTERRUPS \
((1 << 21) | (1 << 22) | (1 << 26) | (1 << 27) | (1 << 29))
r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_IO_Control);
r &= ~GPP_EXTERNAL_INTERRUPS;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_IO_Control, r);
r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Level_Control);
r |= GPP_EXTERNAL_INTERRUPS;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Level_Control, r);
/* clear interrupts */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, ICR_CIM_LO, 0);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, ICR_CIM_HI, 0);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Cause,
~GPP_EXTERNAL_INTERRUPS);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Mask,
GPP_EXTERNAL_INTERRUPS);
discovery_pic->pic_cookie = sc;
intr_establish(IRQ_GPP7_0, IST_LEVEL, IPL_NONE,
pic_handle_intr, discovery_gpp_pic[0]);
intr_establish(IRQ_GPP15_8, IST_LEVEL, IPL_NONE,
pic_handle_intr, discovery_gpp_pic[1]);
intr_establish(IRQ_GPP23_16, IST_LEVEL, IPL_NONE,
pic_handle_intr, discovery_gpp_pic[2]);
intr_establish(IRQ_GPP31_24, IST_LEVEL, IPL_NONE,
pic_handle_intr, discovery_gpp_pic[3]);
cpumstr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_CPU_Master_Ctl);
cpumstr &= ~(GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_CPU_Master_Ctl, cpumstr);
gt_attach_common(sc);
}
void
gtpci_md_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin,
int swiz, int *iline)
gtpci_md_conf_interrupt(void *v, int bus, int dev, int pin, int swiz,
int *iline)
{
#ifdef PCI_NETBSD_CONFIGURE
struct gtpci_chipset *gtpc = (struct gtpci_chipset *)pc;
int line = (gtpc->gtpc_busno == 0 ? PCI0_GPPINTS : PCI1_GPPINTS);
*iline = (line >> (8 * ((pin + swiz - 1) & 3))) & 0xff;
struct gtpci_softc *sc = v;
*iline = (sc->sc_unit == 0 ? 27 : 29);
#define IRQ_GPP_BASE (discovery_pic->pic_numintrs);
if (*iline != 0xff)
*iline += IRQ_GPP_BASE;
#endif /* PCI_NETBSD_CONFIGURE */
}
void
gtpci_md_bus_devorder(pci_chipset_tag_t pc, int busno, char devs[])
{
struct gtpci_chipset *gtpc = (struct gtpci_chipset *)pc;
int dev;
/*
* Don't bother probing the GT itself.
*/
for (dev = 0; dev < 32; dev++) {
if (PCI_CFG_GET_BUSNO(gtpc->gtpc_self) == busno &&
(PCI_CFG_GET_DEVNO(gtpc->gtpc_self) == dev ||
(gtpci_skipmask[gtpc->gtpc_busno] & (1 << dev))))
continue;
*devs++ = dev;
}
*devs = -1;
}
int
gtpci_md_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func,
pcireg_t id)
gtpci_md_conf_hook(void *v, int bus, int dev, int func, pcireg_t id)
{
if (bus == 0 && dev == 0) /* don't configure GT */
return 0;
struct gtpci_softc *sc = v;
return PCI_CONF_DEFAULT;
return gtpci_conf_hook(sc->sc_pc, bus, dev, func, id);
}
int
gtpci_md_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
void *
marvell_intr_establish(int irq, int ipl, int (*func)(void *), void *arg)
{
int pin = pa->pa_intrpin;
int line = pa->pa_intrline;
if (pin > 4 || line >= NIRQ) {
printf("pci_intr_map: bad interrupt pin %d\n", pin);
*ihp = -1;
return 1;
}
*ihp = line;
return 0;
/* pass through */
return intr_establish(irq, IST_LEVEL, ipl, func, arg);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.26 2009/11/26 00:19:16 matt Exp $ */
/* $NetBSD: machdep.c,v 1.27 2010/04/28 13:51:55 kiyohara Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.26 2009/11/26 00:19:16 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.27 2010/04/28 13:51:55 kiyohara Exp $");
#include "opt_marvell.h"
#include "opt_modular.h"
@ -45,53 +45,38 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.26 2009/11/26 00:19:16 matt Exp $");
#include "opt_ns.h"
#include "opt_ipkdb.h"
#define _POWERPC_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/msgbuf.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/extent.h>
#include <sys/syslog.h>
#include <sys/kernel.h>
#include <sys/ksyms.h>
#include <sys/mount.h>
#include <sys/reboot.h>
#include <sys/systm.h>
#include <sys/termios.h>
#include <sys/ksyms.h>
#include <sys/vnode.h>
#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#include <net/netisr.h>
#include <machine/bus.h>
#include <machine/db_machdep.h>
#include <machine/intr.h>
#include <machine/pmap.h>
#include <machine/powerpc.h>
#include <machine/trap.h>
#include <powerpc/oea/bat.h>
#include <powerpc/marvell/watchdog.h>
#include <powerpc/pic/picvar.h>
#include <powerpc/pio.h>
#include <ddb/db_extern.h>
#include <dev/cons.h>
#include "vga.h"
#if (NVGA > 0)
#include <dev/ic/mc6845reg.h>
#include <dev/ic/pcdisplayvar.h>
#include <dev/ic/vgareg.h>
#include <dev/ic/vgavar.h>
#endif
#include "isa.h"
#if (NISA > 0)
void isa_intr_init(void);
#endif
#include "com.h"
#if (NCOM > 0)
#include <dev/ic/comreg.h>
@ -100,16 +85,18 @@ void isa_intr_init(void);
#include <dev/marvell/gtreg.h>
#include <dev/marvell/gtvar.h>
#include <dev/marvell/gtethreg.h>
#include "gtmpsc.h"
#if (NGTMPSC > 0)
#include <dev/marvell/gtbrgreg.h>
#include <dev/marvell/gtsdmareg.h>
#include <dev/marvell/gtmpscreg.h>
#include <dev/marvell/gtmpscvar.h>
#endif
#include "ksyms.h"
#include "locators.h"
/*
* Global variables used here and there
@ -117,64 +104,62 @@ void isa_intr_init(void);
#define PMONMEMREGIONS 32
struct mem_region physmemr[PMONMEMREGIONS], availmemr[PMONMEMREGIONS];
char *bootpath;
void initppc(u_int, u_int, u_int, void *); /* Called from locore */
void strayintr(int);
int lcsplx(int);
void gt_bus_space_init(void);
void gt_find_memory(bus_space_tag_t, bus_space_handle_t, paddr_t);
void gt_halt(bus_space_tag_t, bus_space_handle_t);
void return_to_dink(int);
static void gt_bus_space_init(void);
static inline void gt_record_memory(int, paddr_t, paddr_t, paddr_t);
static void gt_find_memory(paddr_t);
void kcomcnputs(dev_t, const char *);
bus_addr_t gt_base = 0;
struct powerpc_bus_space gt_pci0_mem_bs_tag = {
extern int primary_pic;
struct pic_ops *discovery_pic;
struct pic_ops *discovery_gpp_pic[4];
struct powerpc_bus_space ev64260_pci0_mem_bs_tag = {
_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_pci0_io_bs_tag = {
struct powerpc_bus_space ev64260_pci0_io_bs_tag = {
_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_pci1_mem_bs_tag = {
struct powerpc_bus_space ev64260_pci1_mem_bs_tag = {
_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_pci1_io_bs_tag = {
struct powerpc_bus_space ev64260_pci1_io_bs_tag = {
_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_obio0_bs_tag = {
struct powerpc_bus_space ev64260_obio0_bs_tag = {
_BUS_SPACE_BIG_ENDIAN|_BUS_SPACE_MEM_TYPE|OBIO0_STRIDE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_obio1_bs_tag = {
struct powerpc_bus_space ev64260_obio1_bs_tag = {
_BUS_SPACE_BIG_ENDIAN|_BUS_SPACE_MEM_TYPE|OBIO1_STRIDE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_obio2_bs_tag = {
struct powerpc_bus_space ev64260_obio2_bs_tag = {
_BUS_SPACE_BIG_ENDIAN|_BUS_SPACE_MEM_TYPE|OBIO2_STRIDE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_obio3_bs_tag = {
struct powerpc_bus_space ev64260_obio3_bs_tag = {
_BUS_SPACE_BIG_ENDIAN|_BUS_SPACE_MEM_TYPE|OBIO3_STRIDE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_bootcs_bs_tag = {
struct powerpc_bus_space ev64260_bootcs_bs_tag = {
_BUS_SPACE_BIG_ENDIAN|_BUS_SPACE_MEM_TYPE,
0x00000000, 0x00000000, 0x00000000,
};
struct powerpc_bus_space gt_mem_bs_tag = {
struct powerpc_bus_space ev64260_gt_bs_tag = {
_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE,
GT_BASE, 0x00000000, 0x00010000,
0x00000000, 0x00000000, GT_SIZE,
};
bus_space_handle_t gt_memh;
struct powerpc_bus_space *obio_bs_tags[5] = {
&gt_obio0_bs_tag, &gt_obio1_bs_tag, &gt_obio2_bs_tag,
&gt_obio3_bs_tag, &gt_bootcs_bs_tag
struct powerpc_bus_space *ev64260_obio_bs_tags[5] = {
&ev64260_obio0_bs_tag, &ev64260_obio1_bs_tag, &ev64260_obio2_bs_tag,
&ev64260_obio3_bs_tag, &ev64260_bootcs_bs_tag
};
static char ex_storage[10][EXTENT_FIXED_STORAGE_SIZE(8)]
@ -195,30 +180,54 @@ const struct gt_decode_info {
{ GT_BootCS_Low_Decode, GT_BootCS_High_Decode },
};
struct powerpc_bus_dma_tag ev64260_bus_dma_tag = {
0, /* _bounce_thresh */
_bus_dmamap_create,
_bus_dmamap_destroy,
_bus_dmamap_load,
_bus_dmamap_load_mbuf,
_bus_dmamap_load_uio,
_bus_dmamap_load_raw,
_bus_dmamap_unload,
_bus_dmamap_sync,
_bus_dmamem_alloc,
_bus_dmamem_free,
_bus_dmamem_map,
_bus_dmamem_unmap,
_bus_dmamem_mmap,
};
void
initppc(u_int startkernel, u_int endkernel, u_int args, void *btinfo)
{
oea_batinit(0xf0000000, BAT_BL_256M);
oea_init((void (*)(void))ext_intr);
extern struct cfdata cfdata[];
cfdata_t cf = &cfdata[0];
DELAY(100000);
/* Get mapped address of gt(System Controller) */
while (cf->cf_name != NULL) {
if (strcmp(cf->cf_name, "gt") == 0 &&
*cf->cf_loc != MAINBUSCF_ADDR_DEFAULT)
break;
cf++;
}
if (cf->cf_name == NULL)
panic("where is gt?");
gt_base = *cf->cf_loc;
ev64260_gt_bs_tag.pbs_offset = gt_base;
ev64260_gt_bs_tag.pbs_base = gt_base;
ev64260_gt_bs_tag.pbs_limit += gt_base;
oea_batinit(gt_base, BAT_BL_256M);
oea_init(NULL);
gt_bus_space_init();
gt_find_memory(&gt_mem_bs_tag, gt_memh, roundup(endkernel, PAGE_SIZE));
gt_halt(&gt_mem_bs_tag, gt_memh);
/*
* Now that we known how much memory, reinit the bats.
*/
oea_batinit(0xf0000000, BAT_BL_256M);
gt_find_memory(roundup(endkernel, PAGE_SIZE));
consinit();
#if (NISA > 0)
isa_intr_init();
#endif
/*
/*
* Set the page size.
*/
uvm_setpagesize();
@ -245,67 +254,6 @@ initppc(u_int startkernel, u_int endkernel, u_int args, void *btinfo)
#endif
}
void
mem_regions(struct mem_region **mem, struct mem_region **avail)
{
*mem = physmemr;
*avail = availmemr;
}
static inline void
gt_record_memory(int j, paddr_t start, paddr_t end, paddr_t endkernel)
{
physmemr[j].start = start;
physmemr[j].size = end - start;
if (start < endkernel)
start = endkernel;
availmemr[j].start = start;
availmemr[j].size = end - start;
}
void
gt_find_memory(bus_space_tag_t memt, bus_space_handle_t memh,
paddr_t endkernel)
{
paddr_t start = ~0, end = 0;
int i, j = 0, first = 1;
/*
* Round kernel end to a page boundary.
*/
for (i = 0; i < 4; i++) {
paddr_t nstart, nend;
nstart = GT_LowAddr_GET(bus_space_read_4(&gt_mem_bs_tag,
gt_memh, decode_regs[i].low_decode));
nend = GT_HighAddr_GET(bus_space_read_4(&gt_mem_bs_tag,
gt_memh, decode_regs[i].high_decode)) + 1;
if (nstart >= nend)
continue;
if (first) {
/*
* First entry? Just remember it.
*/
start = nstart;
end = nend;
first = 0;
} else if (nstart == end) {
/*
* Contiguous? Just update the end.
*/
end = nend;
} else {
/*
* Disjoint? record it.
*/
gt_record_memory(j, start, end, endkernel);
start = nstart;
end = nend;
j++;
}
}
gt_record_memory(j, start, end, endkernel);
}
/*
* Machine dependent startup code.
*/
@ -316,6 +264,19 @@ cpu_startup(void)
oea_startup(NULL);
pic_init();
discovery_pic = setup_discovery_pic();
primary_pic = 0;
discovery_gpp_pic[0] = setup_discovery_gpp_pic(discovery_pic, 0);
discovery_gpp_pic[1] = setup_discovery_gpp_pic(discovery_pic, 8);
discovery_gpp_pic[2] = setup_discovery_gpp_pic(discovery_pic, 16);
discovery_gpp_pic[3] = setup_discovery_gpp_pic(discovery_pic, 24);
/*
* GPP interrupts establishes later.
*/
oea_install_extint(pic_ext_intr);
/*
* Now that we have VM, malloc()s are OK in bus_space.
*/
@ -324,7 +285,7 @@ cpu_startup(void)
/*
* Now allow hardware interrupts.
*/
splhigh();
splraise(-1);
__asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0"
: "=r"(msr)
: "K"(PSL_EE));
@ -337,9 +298,34 @@ cpu_startup(void)
void
consinit(void)
{
#ifdef MPSC_CONSOLE
/* PMON using MPSC0 @ 9600 */
gtmpsccnattach(&gt_mem_bs_tag, gt_memh, MPSC_CONSOLE, 9600,
const int brg = GTMPSC_CRR_BRG0;
const int baud = 9600;
uint32_t cr;
#if 1
/*
* XXX HACK FIXME
* PMON output has not been flushed. give him a chance
*/
DELAY(100000); /* XXX */
#endif
/* Setup MPSC Routing Registers */
out32rb(gt_base + GTMPSC_MRR, GTMPSC_MRR_RES);
cr = in32rb(gt_base + GTMPSC_RCRR);
cr &= ~GTMPSC_CRR(MPSC_CONSOLE, GTMPSC_CRR_MASK);
cr |= GTMPSC_CRR(MPSC_CONSOLE, brg);
out32rb(gt_base + GTMPSC_RCRR, cr);
out32rb(gt_base + GTMPSC_TCRR, cr);
/* Setup Baud Rate Configuration Register of Baud Rate Generator */
out32rb(gt_base + BRG_BCR(brg),
BRG_BCR_EN | GT_MPSC_CLOCK_SOURCE | compute_cdv(baud));
gtmpsccnattach(&ev64260_gt_bs_tag, &ev64260_bus_dma_tag, gt_base,
MPSC_CONSOLE, brg, baud,
(TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8);
#else
/* PPCBOOT using COM1 @ 57600 */
@ -349,15 +335,6 @@ consinit(void)
#endif
}
/*
* Stray interrupts.
*/
void
strayintr(int irq)
{
log(LOG_ERR, "stray interrupt %d\n", irq);
}
/*
* Halt or reboot the machine after syncing/dumping according to howto.
*/
@ -405,96 +382,39 @@ cpu_reboot(int howto, char *what)
*ap++ = 0;
if (ap[-2] == '-')
*ap1 = 0;
#if 0
{
void mvpppc_reboot(void);
mvpppc_reboot();
}
#endif
gt_watchdog_reset();
/* NOTREACHED */
while (1);
}
int
lcsplx(int ipl)
{
return spllower(ipl);
}
void
gt_halt(bus_space_tag_t memt, bus_space_handle_t memh)
mem_regions(struct mem_region **mem, struct mem_region **avail)
{
int i;
u_int32_t data;
/*
* Shut down the MPSC ports
*/
for (i = 0; i < 2; i++) {
bus_space_write_4(memt, memh,
SDMA_U_SDCM(i), SDMA_SDCM_AR|SDMA_SDCM_AT);
for (;;) {
data = bus_space_read_4(memt, memh,
SDMA_U_SDCM(i));
if (((SDMA_SDCM_AR|SDMA_SDCM_AT) & data) == 0)
break;
}
}
/*
* Shut down the Ethernets
*/
for (i = 0; i < 3; i++) {
bus_space_write_4(memt, memh,
ETH_ESDCMR(2), ETH_ESDCMR_AR|ETH_ESDCMR_AT);
for (;;) {
data = bus_space_read_4(memt, memh,
ETH_ESDCMR(i));
if (((ETH_ESDCMR_AR|ETH_ESDCMR_AT) & data) == 0)
break;
}
data = bus_space_read_4(memt, memh, ETH_EPCR(i));
data &= ~ETH_EPCR_EN;
bus_space_write_4(memt, memh, ETH_EPCR(i), data);
}
*mem = physmemr;
*avail = availmemr;
}
int
gtget_macaddr(struct gt_softc *gt, int macno, char *enaddr)
{
enaddr[0] = 0x02;
enaddr[1] = 0x00;
enaddr[2] = 0x04;
enaddr[3] = 0x00;
enaddr[4] = 0x00;
enaddr[5] = 0x04 + macno;
return 0;
}
void
static void
gt_bus_space_init(void)
{
bus_space_tag_t gt_memt = &gt_mem_bs_tag;
const struct gt_decode_info *di;
uint32_t datal, datah;
int error;
int bs = 0;
int j;
int error, bs, i;
error = bus_space_init(&gt_mem_bs_tag, "gtmem",
bs = 0;
error = bus_space_init(&ev64260_gt_bs_tag, "gt",
ex_storage[bs], sizeof(ex_storage[bs]));
bs++;
error = bus_space_map(gt_memt, 0, 0x10000, 0, &gt_memh);
for (i = 0, di = &decode_regs[4]; i < 5; i++, di++) {
struct powerpc_bus_space *memt = ev64260_obio_bs_tags[i];
for (j = 0, di = &decode_regs[4]; j < 5; j++, di++) {
struct powerpc_bus_space *memt = obio_bs_tags[j];
datal = bus_space_read_4(gt_memt, gt_memh, di->low_decode);
datah = bus_space_read_4(gt_memt, gt_memh, di->high_decode);
datal = in32rb(gt_base + di->low_decode);
datah = in32rb(gt_base + di->high_decode);
if (GT_LowAddr_GET(datal) >= GT_HighAddr_GET(datal)) {
obio_bs_tags[j] = NULL;
ev64260_obio_bs_tags[i] = NULL;
continue;
}
memt->pbs_offset = GT_LowAddr_GET(datal);
@ -506,119 +426,163 @@ gt_bus_space_init(void)
bs++;
}
datal = bus_space_read_4(gt_memt, gt_memh, GT_PCI0_Mem0_Low_Decode);
datah = bus_space_read_4(gt_memt, gt_memh, GT_PCI0_Mem0_High_Decode);
datal = in32rb(gt_base + GT_PCI0_Mem0_Low_Decode);
datah = in32rb(gt_base + GT_PCI0_Mem0_High_Decode);
#if defined(GT_PCI0_MEMBASE)
datal &= ~0xfff;
datal |= (GT_PCI0_MEMBASE >> 20);
bus_space_write_4(gt_memt, gt_memh, GT_PCI0_Mem0_Low_Decode, datal);
out32rb(gt_base + GT_PCI0_Mem0_Low_Decode, datal);
#endif
#if defined(GT_PCI0_MEMSIZE)
datah &= ~0xfff;
datah |= (GT_PCI0_MEMSIZE + GT_LowAddr_GET(datal) - 1) >> 20;
bus_space_write_4(gt_memt, gt_memh, GT_PCI0_Mem0_High_Decode, datal);
datah |= (GT_PCI0_MEMSIZE + GT_LowAddr_GET(datal) - 1) >> 20;
out32rb(gt_base + GT_PCI0_Mem0_High_Decode, datal);
#endif
gt_pci0_mem_bs_tag.pbs_base = GT_LowAddr_GET(datal);
gt_pci0_mem_bs_tag.pbs_limit = GT_HighAddr_GET(datah) + 1;
ev64260_pci0_mem_bs_tag.pbs_base = GT_LowAddr_GET(datal);
ev64260_pci0_mem_bs_tag.pbs_limit = GT_HighAddr_GET(datah) + 1;
error = bus_space_init(&gt_pci0_mem_bs_tag, "pci0-mem",
error = bus_space_init(&ev64260_pci0_mem_bs_tag, "pci0-mem",
ex_storage[bs], sizeof(ex_storage[bs]));
bs++;
#if 1 /* XXXXXX */
/*
* Make sure PCI0 Memory is BAT mapped.
*/
if (GT_LowAddr_GET(datal) < GT_HighAddr_GET(datal))
oea_iobat_add(gt_pci0_mem_bs_tag.pbs_base & SEGMENT_MASK, BAT_BL_256M);
oea_iobat_add(ev64260_pci0_mem_bs_tag.pbs_base & SEGMENT_MASK,
BAT_BL_256M);
#endif
/*
* Make sure that I/O space start at 0.
*/
bus_space_write_4(gt_memt, gt_memh, GT_PCI1_IO_Remap, 0);
out32rb(gt_base + GT_PCI1_IO_Remap, 0);
datal = bus_space_read_4(gt_memt, gt_memh, GT_PCI0_IO_Low_Decode);
datah = bus_space_read_4(gt_memt, gt_memh, GT_PCI0_IO_High_Decode);
datal = in32rb(gt_base + GT_PCI0_IO_Low_Decode);
datah = in32rb(gt_base + GT_PCI0_IO_High_Decode);
#if defined(GT_PCI0_IOBASE)
datal &= ~0xfff;
datal |= (GT_PCI0_IOBASE >> 20);
bus_space_write_4(gt_memt, gt_memh, GT_PCI0_IO_Low_Decode, datal);
out32rb(gt_base + GT_PCI0_IO_Low_Decode, datal);
#endif
#if defined(GT_PCI0_IOSIZE)
datah &= ~0xfff;
datah |= (GT_PCI0_IOSIZE + GT_LowAddr_GET(datal) - 1) >> 20;
bus_space_write_4(gt_memt, gt_memh, GT_PCI0_IO_High_Decode, datal);
datah |= (GT_PCI0_IOSIZE + GT_LowAddr_GET(datal) - 1) >> 20;
out32rb(gt_base + GT_PCI0_IO_High_Decode, datal);
#endif
gt_pci0_io_bs_tag.pbs_offset = GT_LowAddr_GET(datal);
gt_pci0_io_bs_tag.pbs_limit = GT_HighAddr_GET(datah) + 1 -
gt_pci0_io_bs_tag.pbs_offset;
ev64260_pci0_io_bs_tag.pbs_offset = GT_LowAddr_GET(datal);
ev64260_pci0_io_bs_tag.pbs_limit = GT_HighAddr_GET(datah) + 1 -
ev64260_pci0_io_bs_tag.pbs_offset;
error = bus_space_init(&gt_pci0_io_bs_tag, "pci0-ioport",
error = bus_space_init(&ev64260_pci0_io_bs_tag, "pci0-ioport",
ex_storage[bs], sizeof(ex_storage[bs]));
bs++;
#if 0
error = extent_alloc_region(gt_pci0_io_bs_tag.pbs_extent,
0x10000, 0x7F0000, EX_NOWAIT);
if (error)
panic("gt_bus_space_init: can't block out reserved "
"I/O space 0x10000-0x7fffff: error=%d\n", error);
#endif
datal = bus_space_read_4(gt_memt, gt_memh, GT_PCI1_Mem0_Low_Decode);
datah = bus_space_read_4(gt_memt, gt_memh, GT_PCI1_Mem0_High_Decode);
datal = in32rb(gt_base + GT_PCI1_Mem0_Low_Decode);
datah = in32rb(gt_base + GT_PCI1_Mem0_High_Decode);
#if defined(GT_PCI1_MEMBASE)
datal &= ~0xfff;
datal |= (GT_PCI1_MEMBASE >> 20);
bus_space_write_4(gt_memt, gt_memh, GT_PCI1_Mem0_Low_Decode, datal);
out32rb(gt_base + GT_PCI1_Mem0_Low_Decode, datal);
#endif
#if defined(GT_PCI1_MEMSIZE)
datah &= ~0xfff;
datah |= (GT_PCI1_MEMSIZE + GT_LowAddr_GET(datal) - 1) >> 20;
bus_space_write_4(gt_memt, gt_memh, GT_PCI1_Mem0_High_Decode, datal);
datah |= (GT_PCI1_MEMSIZE + GT_LowAddr_GET(datal) - 1) >> 20;
out32rb(gt_base + GT_PCI1_Mem0_High_Decode, datal);
#endif
gt_pci1_mem_bs_tag.pbs_base = GT_LowAddr_GET(datal);
gt_pci1_mem_bs_tag.pbs_limit = GT_HighAddr_GET(datah) + 1;
ev64260_pci1_mem_bs_tag.pbs_base = GT_LowAddr_GET(datal);
ev64260_pci1_mem_bs_tag.pbs_limit = GT_HighAddr_GET(datah) + 1;
error = bus_space_init(&gt_pci1_mem_bs_tag, "pci1-mem",
error = bus_space_init(&ev64260_pci1_mem_bs_tag, "pci1-mem",
ex_storage[bs], sizeof(ex_storage[bs]));
bs++;
#if 1 /* XXXXXX */
/*
* Make sure PCI1 Memory is BAT mapped.
*/
if (GT_LowAddr_GET(datal) < GT_HighAddr_GET(datal))
oea_iobat_add(gt_pci1_mem_bs_tag.pbs_base & SEGMENT_MASK, BAT_BL_256M);
oea_iobat_add(ev64260_pci1_mem_bs_tag.pbs_base & SEGMENT_MASK,
BAT_BL_256M);
#endif
/*
* Make sure that I/O space start at 0.
*/
bus_space_write_4(gt_memt, gt_memh, GT_PCI1_IO_Remap, 0);
out32rb(gt_base + GT_PCI1_IO_Remap, 0);
datal = bus_space_read_4(gt_memt, gt_memh, GT_PCI1_IO_Low_Decode);
datah = bus_space_read_4(gt_memt, gt_memh, GT_PCI1_IO_High_Decode);
datal = in32rb(gt_base + GT_PCI1_IO_Low_Decode);
datah = in32rb(gt_base + GT_PCI1_IO_High_Decode);
#if defined(GT_PCI1_IOBASE)
datal &= ~0xfff;
datal |= (GT_PCI1_IOBASE >> 20);
bus_space_write_4(gt_memt, gt_memh, GT_PCI1_IO_Low_Decode, datal);
out32rb(gt_base + GT_PCI1_IO_Low_Decode, datal);
#endif
#if defined(GT_PCI1_IOSIZE)
datah &= ~0xfff;
datah |= (GT_PCI1_IOSIZE + GT_LowAddr_GET(datal) - 1) >> 20;
bus_space_write_4(gt_memt, gt_memh, GT_PCI1_IO_High_Decode, datal);
datah |= (GT_PCI1_IOSIZE + GT_LowAddr_GET(datal) - 1) >> 20;
out32rb(gt_base + GT_PCI1_IO_High_Decode, datal);
#endif
gt_pci1_io_bs_tag.pbs_offset = GT_LowAddr_GET(datal);
gt_pci1_io_bs_tag.pbs_limit = GT_HighAddr_GET(datah) + 1 -
gt_pci1_io_bs_tag.pbs_offset;
ev64260_pci1_io_bs_tag.pbs_offset = GT_LowAddr_GET(datal);
ev64260_pci1_io_bs_tag.pbs_limit = GT_HighAddr_GET(datah) + 1 -
ev64260_pci1_io_bs_tag.pbs_offset;
error = bus_space_init(&gt_pci1_io_bs_tag, "pci1-ioport",
error = bus_space_init(&ev64260_pci1_io_bs_tag, "pci1-ioport",
ex_storage[bs], sizeof(ex_storage[bs]));
bs++;
#if 0
error = extent_alloc_region(gt_pci1_io_bs_tag.pbs_extent,
0x10000, 0x7F0000, EX_NOWAIT);
if (error)
panic("gt_bus_space_init: can't block out reserved "
"I/O space 0x10000-0x7fffff: error=%d\n", error);
#endif
}
static inline void
gt_record_memory(int j, paddr_t start, paddr_t end, paddr_t endkernel)
{
physmemr[j].start = start;
physmemr[j].size = end - start;
if (start < endkernel)
start = endkernel;
availmemr[j].start = start;
availmemr[j].size = end - start;
}
static void
gt_find_memory(paddr_t endkernel)
{
paddr_t start = ~0, end = 0;
const struct gt_decode_info *di;
int i, j = 0, first = 1;
/*
* Round kernel end to a page boundary.
*/
for (i = 0; i < 4; i++) {
paddr_t nstart, nend;
di = &decode_regs[i];
nstart = GT_LowAddr_GET(in32rb(gt_base + di->low_decode));
nend = GT_HighAddr_GET(in32rb(gt_base + di->high_decode)) + 1;
if (nstart >= nend)
continue;
if (first) {
/*
* First entry? Just remember it.
*/
start = nstart;
end = nend;
first = 0;
} else if (nstart == end) {
/*
* Contiguous? Just update the end.
*/
end = nend;
} else {
/*
* Disjoint? record it.
*/
gt_record_memory(j, start, end, endkernel);
start = nstart;
end = nend;
j++;
}
}
gt_record_memory(j, start, end, endkernel);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: mainbus.c,v 1.5 2005/12/11 12:17:12 christos Exp $ */
/* $NetBSD: mainbus.c,v 1.6 2010/04/28 13:51:55 kiyohara Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -31,60 +31,39 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.5 2005/12/11 12:17:12 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: mainbus.c,v 1.6 2010/04/28 13:51:55 kiyohara Exp $");
#include "mainbus.h"
#include "pci.h"
#include "opt_multiprocessor.h"
#include "opt_pci.h"
#include <sys/param.h>
#include <sys/extent.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <machine/bus.h>
#include <evbppc/ev64260/ev64260.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pciconf.h>
#include <dev/marvell/gtvar.h>
#include "locators.h"
#if NCPU == 0
#error A cpu device is now required
#endif
struct mainbus_attach_args {
const char *mba_busname;
int mba_unit;
};
int mainbus_match(device_t, cfdata_t, void *);
void mainbus_attach(device_t, device_t, void *);
int mainbus_cfprint(void *, const char *);
int mainbus_match(struct device *, struct cfdata *, void *);
void mainbus_attach(struct device *, struct device *, void *);
CFATTACH_DECL(mainbus, sizeof(struct device),
mainbus_match, mainbus_attach, NULL, NULL);
int
mainbus_cfprint(void *aux, const char *pnp)
{
struct mainbus_attach_args *mba = aux;
if (pnp)
aprint_normal("%s at %s", mba->mba_busname, pnp);
aprint_normal(" unit %d", mba->mba_unit);
return (UNCONF);
}
/*
* Probe for the mainbus; always succeeds.
*/
int
mainbus_match(struct device *parent, struct cfdata *match, void *aux)
mainbus_match(device_t parent, cfdata_t match, void *aux)
{
return 1;
}
@ -92,9 +71,10 @@ mainbus_match(struct device *parent, struct cfdata *match, void *aux)
* Attach the mainbus.
*/
void
mainbus_attach(struct device *parent, struct device *self, void *aux)
mainbus_attach(device_t parent, device_t self, void *aux)
{
struct mainbus_attach_args mba;
extern bus_addr_t gt_base;
printf("\n");
@ -103,50 +83,65 @@ mainbus_attach(struct device *parent, struct device *self, void *aux)
/*
* Always find the CPU
*/
mba.mba_busname = "cpu";
mba.mba_name = "cpu";
mba.mba_unit = 0;
mba.mba_addr = MAINBUSCF_ADDR_DEFAULT;
config_found(self, &mba, mainbus_cfprint);
#ifdef MULTIPROCESSOR
/*
* Try for a second one...
*/
mba.mba_busname = "cpu";
mba.mba_name = "cpu";
mba.mba_unit = 1;
mba.mba_addr = MAINBUSCF_ADDR_DEFAULT;
config_found(self, &mba, mainbus_cfprint);
#endif
/*
* Now try to configure the Discovery
*/
mba.mba_busname = "gt";
mba.mba_unit = 0;
mba.mba_name = "gt";
mba.mba_unit = -1;
mba.mba_addr = gt_base;
config_found(self, &mba, mainbus_cfprint);
}
static int cpu_match(struct device *, struct cfdata *, void *);
static void cpu_attach(struct device *, struct device *, void *);
CFATTACH_DECL(cpu, sizeof(struct device), cpu_match, cpu_attach, NULL, NULL);
extern struct cfdriver cpu_cd;
int
cpu_match(struct device *parent, struct cfdata *cf, void *aux)
mainbus_cfprint(void *aux, const char *pnp)
{
struct mainbus_attach_args *mba = aux;
if (strcmp(mba->mba_busname, cpu_cd.cd_name) != 0)
return 0;
if (pnp)
aprint_normal("%s at %s", mba->mba_name, pnp);
if (mba->mba_unit != -1)
aprint_normal(" unit %d", mba->mba_unit);
if (mba->mba_addr != MAINBUSCF_ADDR_DEFAULT)
aprint_normal(" addr 0x%08x", mba->mba_addr);
return UNCONF;
}
if (cpu_info[0].ci_dev != NULL)
static int cpu_match(device_t, cfdata_t, void *);
static void cpu_attach(device_t, device_t, void *);
CFATTACH_DECL(cpu, sizeof(struct device), cpu_match, cpu_attach, NULL, NULL);
int
cpu_match(device_t parent, cfdata_t cf, void *aux)
{
struct mainbus_attach_args *mba = aux;
if (strcmp(mba->mba_name, "cpu") != 0)
return 0;
return 1;
}
void
cpu_attach(struct device *parent, struct device *self, void *aux)
cpu_attach(device_t parent, device_t self, void *aux)
{
(void) cpu_attach_common(self, 0);
struct mainbus_attach_args *mba = aux;
(void) cpu_attach_common(self, mba->mba_unit);
}

View File

@ -1,753 +0,0 @@
/* $NetBSD: bus_dma.c,v 1.20 2009/03/18 16:00:14 cegger Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``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 FOUNDATION OR CONTRIBUTORS
* 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.20 2009/03/18 16:00:14 cegger Exp $");
#define DEBUG 1
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/mbuf.h>
#include <uvm/uvm.h>
#include <uvm/uvm_extern.h>
#define _POWERPC_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/cpu.h> /* for CACHELINESIZE */
#ifdef DEBUG
int busdmadebug = 0;
# define DPRINTF(x) do { if (busdmadebug) printf x ; } while (0)
#else
# define DPRINTF(x)
#endif
static inline void
invaldcache(vaddr_t va, bus_size_t sz)
{
int off;
DPRINTF(("invaldcache: %#lx %ld\n", va, (long) sz));
KASSERT(sz != 0);
__asm volatile("eieio;");
off = (u_int)va & (curcpu()->ci_ci.dcache_line_size - 1);
sz += off;
va -= off;
while ((int)sz > 0) {
__asm volatile("dcbi 0, %0;" :: "r"(va));
va += curcpu()->ci_ci.dcache_line_size;
sz -= curcpu()->ci_ci.dcache_line_size;
}
__asm volatile("sync;");
}
static inline void
flushdcache(vaddr_t va, bus_size_t sz)
{
int off;
DPRINTF(("flushdcache: %#lx %ld\n", va, (long) sz));
KASSERT(sz != 0);
__asm volatile("eieio;");
off = (u_int)va & (curcpu()->ci_ci.dcache_line_size - 1);
sz += off;
va -= off;
while ((int)sz > curcpu()->ci_ci.dcache_line_size) {
__asm volatile("dcbf 0, %0;" :: "r"(va));
va += curcpu()->ci_ci.dcache_line_size;
sz -= curcpu()->ci_ci.dcache_line_size;
}
/*
* eieio ensures the last cache line flushed is ordered last
* read-after-write ensures last cache line
* (and therefore all cache lines) made it to memory
*/
__asm volatile("eieio; dcbf 0, %0;" :: "r"(va));
__asm volatile("lwz %0,0(%0); sync;" : "+r"(va));
}
static inline void
storedcache(vaddr_t va, bus_size_t sz)
{
int off;
DPRINTF(("storedcache: %#lx %ld\n", va, (long) sz));
KASSERT(sz != 0);
__asm volatile("eieio;");
off = (u_int)va & (curcpu()->ci_ci.dcache_line_size - 1);
sz += off;
va -= off;
while ((int)sz > 0) {
__asm volatile("dcbst 0, %0;" :: "r"(va));
va += curcpu()->ci_ci.dcache_line_size;
sz -= curcpu()->ci_ci.dcache_line_size;
}
__asm volatile("sync;");
}
int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *,
bus_size_t, struct vmspace *, int, paddr_t *, int *, int);
/*
* Common function for DMA map creation. May be called by bus-specific
* DMA map creation functions.
*/
int
_bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
{
struct powerpc_bus_dmamap *map;
void *mapstore;
size_t mapsize;
/*
* Allocate and initialize the DMA map. The end of the map
* is a variable-sized array of segments, so we allocate enough
* room for them in one shot.
*
* Note we don't preserve the WAITOK or NOWAIT flags. Preservation
* of ALLOCNOW notifies others that we've reserved these resources,
* and they are not to be freed.
*
* The bus_dmamap_t includes one bus_dma_segment_t, hence
* the (nsegments - 1).
*/
mapsize = sizeof(struct powerpc_bus_dmamap) +
(sizeof(bus_dma_segment_t) * (nsegments - 1));
if ((mapstore = malloc(mapsize, M_DMAMAP,
(flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL)
return (ENOMEM);
memset(mapstore, 0, mapsize);
map = (struct powerpc_bus_dmamap *)mapstore;
map->_dm_size = size;
map->_dm_segcnt = nsegments;
map->_dm_maxmaxsegsz = maxsegsz;
map->_dm_boundary = boundary;
map->_dm_bounce_thresh = t->_bounce_thresh;
map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT);
map->dm_maxsegsz = maxsegsz;
map->dm_mapsize = 0; /* no valid mappings */
map->dm_nsegs = 0;
*dmamp = map;
return (0);
}
/*
* Common function for DMA map destruction. May be called by bus-specific
* DMA map destruction functions.
*/
void
_bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
{
free(map, M_DMAMAP);
}
/*
* Utility function to load a linear buffer. lastaddrp holds state
* between invocations (for multiple-buffer loads). segp contains
* the starting segment on entrance, and the ending segment on exit.
* first indicates if this is the first invocation of this function.
*/
int
_bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct vmspace *vm, int flags, paddr_t *lastaddrp, int *segp, int first)
{
bus_size_t sgsize;
bus_addr_t curaddr, lastaddr, baddr, bmask;
vaddr_t vaddr = (vaddr_t)buf;
int seg;
lastaddr = *lastaddrp;
bmask = ~(map->_dm_boundary - 1);
for (seg = *segp; buflen > 0 ; ) {
/*
* Get the physical address for this segment.
*/
if (!VMSPACE_IS_KERNEL_P(vm))
(void) pmap_extract(vm_map_pmap(&vm->vm_map),
vaddr, (paddr_t *)&curaddr);
else
curaddr = vtophys(vaddr);
/*
* If we're beyond the bounce threshold, notify
* the caller.
*/
if (map->_dm_bounce_thresh != 0 &&
curaddr >= map->_dm_bounce_thresh)
return (EINVAL);
/*
* Compute the segment size, and adjust counts.
*/
sgsize = PAGE_SIZE - ((u_long)vaddr & PGOFSET);
if (buflen < sgsize)
sgsize = buflen;
/*
* Make sure we don't cross any boundaries.
*/
if (map->_dm_boundary > 0) {
baddr = (curaddr + map->_dm_boundary) & bmask;
if (sgsize > (baddr - curaddr))
sgsize = (baddr - curaddr);
}
/*
* Insert chunk into a segment, coalescing with
* the previous segment if possible.
*/
if (first) {
map->dm_segs[seg].ds_addr = curaddr;
map->dm_segs[seg].ds_len = sgsize;
map->dm_segs[seg].ds_vaddr = vaddr;
first = 0;
} else {
if ((curaddr == lastaddr) &&
(vaddr == map->dm_segs[seg].ds_vaddr +
(curaddr - map->dm_segs[seg].ds_addr)) &&
((map->dm_segs[seg].ds_len + sgsize) <=
map->dm_maxsegsz) &&
((map->_dm_boundary == 0) ||
((map->dm_segs[seg].ds_addr & bmask) ==
(curaddr & bmask)))) {
map->dm_segs[seg].ds_len += sgsize;
} else {
if (++seg >= map->_dm_segcnt) {
#ifdef DEBUG
panic("_bus_dmamap_load_buffer: "
"seg %d >= _dm_segcnt %d\n",
seg, map->_dm_segcnt);
#endif
break;
}
map->dm_segs[seg].ds_addr = curaddr;
map->dm_segs[seg].ds_len = sgsize;
map->dm_segs[seg].ds_vaddr = vaddr;
}
}
lastaddr = curaddr + sgsize;
vaddr += sgsize;
buflen -= sgsize;
}
*segp = seg;
*lastaddrp = lastaddr;
/*
* Did we fit?
*/
if (buflen != 0)
return (EFBIG); /* XXX better return value here? */
return (0);
}
/*
* Common function for loading a DMA map with a linear buffer. May
* be called by bus-specific DMA map load functions.
*/
int
_bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct proc *p, int flags)
{
paddr_t lastaddr;
int seg, error;
struct vmspace *vm;
/*
* Make sure that on error condition we return "no valid mappings".
*/
map->dm_mapsize = 0;
map->dm_nsegs = 0;
KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
if (buflen > map->_dm_size)
return (EINVAL);
if (p != NULL) {
vm = p->p_vmspace;
} else {
vm = vmspace_kernel();
}
seg = 0;
error = _bus_dmamap_load_buffer(t, map, buf, buflen, vm, flags,
&lastaddr, &seg, 1);
if (error == 0) {
map->dm_mapsize = buflen;
map->dm_nsegs = seg + 1;
}
return (error);
}
/*
* Like _bus_dmamap_load(), but for mbufs.
*/
int
_bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0, int flags)
{
paddr_t lastaddr;
int seg, error, first;
struct mbuf *m;
/*
* Make sure that on error condition we return "no valid mappings."
*/
map->dm_mapsize = 0;
map->dm_nsegs = 0;
KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
#ifdef DIAGNOSTIC
if ((m0->m_flags & M_PKTHDR) == 0)
panic("_bus_dmamap_load_mbuf: no packet header");
#endif
if (m0->m_pkthdr.len > map->_dm_size)
return (EINVAL);
first = 1;
seg = 0;
error = 0;
for (m = m0; m != NULL && error == 0; m = m->m_next) {
if (m->m_len == 0)
continue;
error = _bus_dmamap_load_buffer(t, map, m->m_data, m->m_len,
vmspace_kernel(), flags, &lastaddr, &seg, first);
first = 0;
}
if (error == 0) {
map->dm_mapsize = m0->m_pkthdr.len;
map->dm_nsegs = seg + 1;
}
return (error);
}
/*
* Like _bus_dmamap_load(), but for uios.
*/
int
_bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio, int flags)
{
paddr_t lastaddr;
int seg, i, error, first;
bus_size_t minlen, resid;
struct iovec *iov;
void *addr;
/*
* Make sure that on error condition we return "no valid mappings."
*/
map->dm_mapsize = 0;
map->dm_nsegs = 0;
KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz);
resid = uio->uio_resid;
iov = uio->uio_iov;
first = 1;
seg = 0;
error = 0;
for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) {
/*
* Now at the first iovec to load. Load each iovec
* until we have exhausted the residual count.
*/
minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len;
addr = (void *)iov[i].iov_base;
error = _bus_dmamap_load_buffer(t, map, addr, minlen,
uio->uio_vmspace, flags, &lastaddr, &seg, first);
first = 0;
resid -= minlen;
}
if (error == 0) {
map->dm_mapsize = uio->uio_resid;
map->dm_nsegs = seg + 1;
}
return (error);
}
/*
* Like _bus_dmamap_load(), but for raw memory.
*/
int
_bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags)
{
panic("_bus_dmamap_load_raw: not implemented");
}
/*
* Common function for unloading a DMA map. May be called by
* chipset-specific DMA map unload functions.
*/
void
_bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
{
/*
* No resources to free; just mark the mappings as
* invalid.
*/
map->dm_maxsegsz = map->_dm_maxmaxsegsz;
map->dm_mapsize = 0;
map->dm_nsegs = 0;
}
/*
* DMA map synchronization, provides software coherency
*/
void
_bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, bus_size_t len, int ops)
{
int i;
bus_size_t dslen;
bus_size_t minlen;
DPRINTF(("_bus_dmamap_sync %p %p %#lx %ld %#x\n",
t, map, (unsigned long) offset, (unsigned long) len, ops));
/*
* Mixing PRE and POST operations is not allowed.
*/
if (((ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) != 0) &&
((ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) != 0))
panic("_bus_dmamap_sync: mix PRE and POST");
#ifdef DIAGNOSTIC
if (offset >= map->dm_mapsize)
panic("_bus_dmamap_sync: bad offset %#lx (map size is %#lx)",
(unsigned long) offset, (unsigned long) map->dm_mapsize);
if (len == 0 || (offset + len) > map->dm_mapsize)
panic("_bus_dmamap_sync: bad length");
#endif
switch(ops) {
case BUS_DMASYNC_PREWRITE:
for (i=0; i < map->dm_nsegs && len != 0; i++) {
/* find the beginning segment */
dslen = map->dm_segs[i].ds_len;
if (offset >= dslen) {
offset -= dslen;
continue;
}
dslen -= offset;
minlen = len;
if (len > dslen)
minlen = dslen;
storedcache(map->dm_segs[i].ds_vaddr + offset, minlen);
len -= minlen;
offset = 0;
}
break;
case BUS_DMASYNC_PREREAD:
for (i=0; i < map->dm_nsegs && len != 0; i++) {
vaddr_t va;
/* find the beginning segment */
dslen = map->dm_segs[i].ds_len;
if (offset >= dslen) {
offset -= dslen;
continue;
}
dslen -= offset;
minlen = len;
if (len > dslen)
minlen = dslen;
va = map->dm_segs[i].ds_vaddr + offset;
if (va & (curcpu()->ci_ci.dcache_line_size-1))
storedcache(va, 1);
va += minlen;
if (va & (curcpu()->ci_ci.dcache_line_size-1))
storedcache(va, 1);
invaldcache(map->dm_segs[i].ds_vaddr + offset, minlen);
len -= minlen;
offset = 0;
}
break;
case BUS_DMASYNC_POSTREAD:
for (i=0; i < map->dm_nsegs && len != 0; i++) {
/* find the beginning segment */
dslen = map->dm_segs[i].ds_len;
if (offset >= dslen) {
offset -= dslen;
continue;
}
dslen -= offset;
minlen = len;
if (len > dslen)
minlen = dslen;
invaldcache(map->dm_segs[i].ds_vaddr + offset, minlen);
len -= minlen;
offset = 0;
}
break;
case BUS_DMASYNC_POSTWRITE:
break;
case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE:
for (i=0; i < map->dm_nsegs && len != 0; i++) {
/* find the beginning segment */
dslen = map->dm_segs[i].ds_len;
if (offset >= dslen) {
offset -= dslen;
continue;
}
dslen -= offset;
minlen = len;
if (len > dslen)
minlen = dslen;
flushdcache(map->dm_segs[i].ds_vaddr + offset, minlen);
len -= minlen;
offset = 0;
}
break;
case BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE:
for (i=0; i < map->dm_nsegs && len != 0; i++) {
/* find the beginning segment */
dslen = map->dm_segs[i].ds_len;
if (offset >= dslen) {
offset -= dslen;
continue;
}
dslen -= offset;
minlen = len;
if (len > dslen)
minlen = dslen;
invaldcache(map->dm_segs[i].ds_vaddr + offset, minlen);
len -= minlen;
offset = 0;
}
break;
}
}
/*
* Common function for DMA-safe memory allocation. May be called
* by bus-specific DMA memory allocation functions.
*/
int
_bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment, bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags)
{
paddr_t avail_start = 0xffffffff, avail_end = 0;
paddr_t curaddr, lastaddr, high;
struct vm_page *m;
struct pglist mlist;
int curseg, error, bank;
for (bank = 0; bank < vm_nphysseg; bank++) {
if (avail_start > vm_physmem[bank].avail_start << PGSHIFT)
avail_start = vm_physmem[bank].avail_start << PGSHIFT;
if (avail_end < vm_physmem[bank].avail_end << PGSHIFT)
avail_end = vm_physmem[bank].avail_end << PGSHIFT;
}
/* Always round the size. */
size = round_page(size);
high = avail_end - PAGE_SIZE;
/*
* Allocate pages from the VM system.
*/
TAILQ_INIT(&mlist);
error = uvm_pglistalloc(size, avail_start, high, alignment, boundary,
&mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0);
if (error)
return (error);
/*
* Compute the location, size, and number of segments actually
* returned by the VM code.
*/
m = mlist.tqh_first;
curseg = 0;
lastaddr = segs[curseg].ds_addr = VM_PAGE_TO_PHYS(m);
segs[curseg].ds_len = PAGE_SIZE;
segs[curseg].ds_vaddr = (vaddr_t)0xdeadbeef;
m = m->pageq.queue.tqe_next;
for (; m != NULL; m = m->pageq.queue.tqe_next) {
curaddr = VM_PAGE_TO_PHYS(m);
#ifdef DIAGNOSTIC
if (curaddr < avail_start || curaddr >= high) {
printf("vm_page_alloc_memory returned non-sensical"
" address 0x%lx\n", curaddr);
panic("_bus_dmamem_alloc");
}
#endif
if (curaddr == (lastaddr + PAGE_SIZE))
segs[curseg].ds_len += PAGE_SIZE;
else {
curseg++;
segs[curseg].ds_addr = curaddr;
segs[curseg].ds_len = PAGE_SIZE;
segs[curseg].ds_vaddr = (vaddr_t)0xdeadbeef;
}
lastaddr = curaddr;
}
*rsegs = curseg + 1;
return (0);
}
/*
* Common function for freeing DMA-safe memory. May be called by
* bus-specific DMA memory free functions.
*/
void
_bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs)
{
struct vm_page *m;
bus_addr_t addr;
struct pglist mlist;
int curseg;
/*
* Build a list of pages to free back to the VM system.
*/
TAILQ_INIT(&mlist);
for (curseg = 0; curseg < nsegs; curseg++) {
for (addr = segs[curseg].ds_addr;
addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
addr += PAGE_SIZE) {
m = PHYS_TO_VM_PAGE(addr);
TAILQ_INSERT_TAIL(&mlist, m, pageq.queue);
}
}
uvm_pglistfree(&mlist);
}
/*
* Common function for mapping DMA-safe memory. May be called by
* bus-specific DMA memory map functions.
*/
int
_bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, size_t size, void **kvap, int flags)
{
vaddr_t va;
bus_addr_t addr;
int curseg;
const uvm_flag_t kmflags =
(flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0;
size = round_page(size);
va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags);
if (va == 0)
return (ENOMEM);
*kvap = (void *)va;
for (curseg = 0; curseg < nsegs; curseg++) {
for (addr = segs[curseg].ds_addr;
addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) {
if (size == 0)
panic("_bus_dmamem_map: size botch");
pmap_enter(pmap_kernel(), va, addr,
VM_PROT_READ | VM_PROT_WRITE,
VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED|
(flags & BUS_DMA_COHERENT ? PMAP_NC : 0));
}
}
return (0);
}
/*
* Common function for unmapping DMA-safe memory. May be called by
* bus-specific DMA memory unmapping functions.
*/
void
_bus_dmamem_unmap(bus_dma_tag_t t, void *kva, size_t size)
{
#ifdef DIAGNOSTIC
if ((u_long)kva & PGOFSET)
panic("_bus_dmamem_unmap");
#endif
size = round_page(size);
pmap_remove(pmap_kernel(), (vaddr_t)kva, (vaddr_t)kva + size);
pmap_update(pmap_kernel());
uvm_km_free(kernel_map, (vaddr_t)kva, size, UVM_KMF_VAONLY);
}
/*
* Common functin for mmap(2)'ing DMA-safe memory. May be called by
* bus-specific DMA mmap(2)'ing functions.
*/
paddr_t
_bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, off_t off, int prot, int flags)
{
int i;
for (i = 0; i < nsegs; i++) {
#ifdef DIAGNOSTIC
if (off & PGOFSET)
panic("_bus_dmamem_mmap: offset unaligned");
if (segs[i].ds_addr & PGOFSET)
panic("_bus_dmamem_mmap: segment unaligned");
if (segs[i].ds_len & PGOFSET)
panic("_bus_dmamem_mmap: segment size not multiple"
" of page size");
#endif
if (off >= segs[i].ds_len) {
off -= segs[i].ds_len;
continue;
}
return (segs[i].ds_addr + off);
}
/* Page not found. */
return (-1);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: marvell_intr.h,v 1.16 2009/03/14 14:46:05 dsl Exp $ */
/* $NetBSD: marvell_intr.h,v 1.17 2010/04/28 13:51:55 kiyohara Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -29,415 +29,76 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MVPPPC_INTR_H_
#define _MVPPPC_INTR_H_
#ifndef _POWERPC_MARVELL_INTR_H_
#define _POWERPC_MARVELL_INTR_H_
#include <powerpc/psl.h>
#include <powerpc/frame.h>
void *intr_establish(int, int, int, int (*)(void *), void *);
void intr_disestablish(void *);
const char *intr_typename(int);
void genppc_cpu_configure(void);
/*
* Interrupt Priority Levels
*/
/* Interrupt priority `levels'. */
#define IPL_NONE 0 /* nothing */
#define IPL_SOFTCLOCK 1 /* timeouts */
#define IPL_SOFTBIO 2 /* block I/O */
#define IPL_SOFTNET 3 /* protocol stacks */
#define IPL_SOFTSERIAL 4 /* serial */
#define IPL_VM 12 /* memory allocation */
#define IPL_SCHED 14 /* clock */
#define IPL_HIGH 15 /* everything */
#define NIPL 16
#define IPL_PRIMASK 0xf
#define IPL_EE 0x10 /* enable external interrupts on splx */
#define IPL_VM 5 /* memory allocation */
#define IPL_SCHED 6
#define IPL_HIGH 7 /* everything */
#define NIPL 8
/* Interrupt sharing types. */
#define IST_NONE 0 /* none */
#define IST_PULSE 1 /* pulsed */
#define IST_EDGE 2 /* edge-triggered */
#define IST_LEVEL 3 /* level-triggered */
#define IST_SOFT 4 /* software-triggered */
#define IST_CLOCK 5 /* exclusive for clock */
#define NIST 6
#if !defined(_LOCORE) && defined(_KERNEL)
#define CLKF_BASEPRI(frame) ((frame)->pri == IPL_NONE)
#ifndef _LOCORE
/*
* we support 128 IRQs:
* 96 (ICU_LEN) hard interrupt IRQs:
* - 64 Main Cause IRQs,
* - 32 GPP IRQs,
* and 32 softint IRQs
* Interrupt handler chains. intr_establish() inserts a handler into
* the list. The handler is called with its (single) argument.
*/
#define ICU_LEN 96 /* number of HW IRQs */
#define IRQ_GPP_BASE 64 /* base of GPP IRQs */
#define IRQ_GPP_SUM (32+24) /* GPP[7..0] interrupt */ /* XXX */
#define NIRQ 128 /* total # of HW IRQs */
struct intrhand {
int (*ih_fun)(void *);
void *ih_arg;
struct intrhand *ih_next;
int ih_level;
int ih_irq;
};
#define IMASK_ICU_LO 0
#define IMASK_ICU_HI 1
#define IMASK_ICU_GPP 2
#define IMASK_SOFTINT 3
#define IMASK_WORDSHIFT 5 /* log2(32) */
#define IMASK_BITMASK ~((~0) << IMASK_WORDSHIFT)
int splraise(int);
int spllower(int);
void splx(int);
void softintr(int);
#define IRQ_IS_GPP(irq) ((irq >= IRQ_GPP_BASE) && (irq < ICU_LEN))
/*
* interrupt mask bit vector
*/
typedef struct {
u_int32_t bits[4];
} imask_t __attribute__ ((aligned(16)));
static inline void imask_zero(imask_t *);
static inline void imask_zero_v(volatile imask_t *);
static inline void imask_dup_v(imask_t *, const volatile imask_t *);
static inline void imask_and(imask_t *, const imask_t *);
static inline void imask_andnot_v(volatile imask_t *, const imask_t *);
static inline void imask_andnot_icu_vv(volatile imask_t *, const volatile imask_t *);
static inline int imask_empty(const imask_t *);
static inline void imask_orbit(imask_t *, int);
static inline void imask_orbit_v(volatile imask_t *, int);
static inline void imask_clrbit(imask_t *, int);
static inline void imask_clrbit_v(volatile imask_t *, int);
static inline u_int32_t imask_andbit_v(const volatile imask_t *, int);
static inline int imask_test_v(const volatile imask_t *, const imask_t *);
static inline void
imask_zero(imask_t *idp)
{
idp->bits[IMASK_ICU_LO] = 0;
idp->bits[IMASK_ICU_HI] = 0;
idp->bits[IMASK_ICU_GPP] = 0;
idp->bits[IMASK_SOFTINT] = 0;
}
static inline void
imask_zero_v(volatile imask_t *idp)
{
idp->bits[IMASK_ICU_LO] = 0;
idp->bits[IMASK_ICU_HI] = 0;
idp->bits[IMASK_ICU_GPP] = 0;
idp->bits[IMASK_SOFTINT] = 0;
}
static inline void
imask_dup_v(imask_t *idp, const volatile imask_t *isp)
{
*idp = *isp;
}
static inline void
imask_and(imask_t *idp, const imask_t *isp)
{
idp->bits[IMASK_ICU_LO] &= isp->bits[IMASK_ICU_LO];
idp->bits[IMASK_ICU_HI] &= isp->bits[IMASK_ICU_HI];
idp->bits[IMASK_ICU_GPP] &= isp->bits[IMASK_ICU_GPP];
idp->bits[IMASK_SOFTINT] &= isp->bits[IMASK_SOFTINT];
}
static inline void
imask_andnot_v(volatile imask_t *idp, const imask_t *isp)
{
idp->bits[IMASK_ICU_LO] &= ~isp->bits[IMASK_ICU_LO];
idp->bits[IMASK_ICU_HI] &= ~isp->bits[IMASK_ICU_HI];
idp->bits[IMASK_ICU_GPP] &= ~isp->bits[IMASK_ICU_GPP];
idp->bits[IMASK_SOFTINT] &= ~isp->bits[IMASK_SOFTINT];
}
static inline void
imask_andnot_icu_vv(volatile imask_t *idp, const volatile imask_t *isp)
{
idp->bits[IMASK_ICU_LO] &= ~isp->bits[IMASK_ICU_LO];
idp->bits[IMASK_ICU_HI] &= ~isp->bits[IMASK_ICU_HI];
idp->bits[IMASK_ICU_GPP] &= ~isp->bits[IMASK_ICU_GPP];
}
static inline int
imask_empty(const imask_t *isp)
{
return (! (isp->bits[IMASK_ICU_LO] | isp->bits[IMASK_ICU_HI] |
isp->bits[IMASK_ICU_GPP]| isp->bits[IMASK_SOFTINT]));
}
static inline void
imask_orbit(imask_t *idp, int bitno)
{
idp->bits[bitno>>IMASK_WORDSHIFT] |= (1 << (bitno&IMASK_BITMASK));
}
static inline void
imask_orbit_v(volatile imask_t *idp, int bitno)
{
idp->bits[bitno>>IMASK_WORDSHIFT] |= (1 << (bitno&IMASK_BITMASK));
}
static inline void
imask_clrbit(imask_t *idp, int bitno)
{
idp->bits[bitno>>IMASK_WORDSHIFT] &= ~(1 << (bitno&IMASK_BITMASK));
}
static inline void
imask_clrbit_v(volatile imask_t *idp, int bitno)
{
idp->bits[bitno>>IMASK_WORDSHIFT] &= ~(1 << (bitno&IMASK_BITMASK));
}
static inline u_int32_t
imask_andbit_v(const volatile imask_t *idp, int bitno)
{
return idp->bits[bitno>>IMASK_WORDSHIFT] & (1 << (bitno&IMASK_BITMASK));
}
static inline int
imask_test_v(const volatile imask_t *idp, const imask_t *isp)
{
return ((idp->bits[IMASK_ICU_LO] & isp->bits[IMASK_ICU_LO]) ||
(idp->bits[IMASK_ICU_HI] & isp->bits[IMASK_ICU_HI]) ||
(idp->bits[IMASK_ICU_GPP] & isp->bits[IMASK_ICU_GPP])||
(idp->bits[IMASK_SOFTINT] & isp->bits[IMASK_SOFTINT]));
}
#ifdef EXT_INTR_STATS
/*
* ISR timing stats
*/
typedef struct ext_intr_hist {
u_int64_t tcause;
u_int64_t tcommit;
u_int64_t tstart;
u_int64_t tfin;
} ext_intr_hist_t __attribute__ ((aligned(32)));
typedef struct ext_intr_stat {
struct ext_intr_hist *histp;
unsigned int histix;
u_int64_t cnt;
u_int64_t sum;
u_int64_t min;
u_int64_t max;
u_int64_t pnd;
u_int64_t borrowed;
struct ext_intr_stat *save;
unsigned long preempted[NIRQ]; /* XXX */
} ext_intr_stat_t __attribute__ ((aligned(32)));
extern int intr_depth_max;
extern int ext_intr_stats_enb;
extern ext_intr_stat_t ext_intr_stats[];
extern ext_intr_stat_t *ext_intr_statp;
extern void ext_intr_stats_init(void);
extern void ext_intr_stats_cause
(u_int32_t, u_int32_t, u_int32_t, u_int32_t);
extern void ext_intr_stats_pend
(u_int32_t, u_int32_t, u_int32_t, u_int32_t);
extern void ext_intr_stats_commit(imask_t *);
extern void ext_intr_stats_commit_m(imask_t *);
extern void ext_intr_stats_commit_irq(u_int);
extern u_int64_t ext_intr_stats_pre(int);
extern void ext_intr_stats_post(int, u_int64_t);
#define EXT_INTR_STATS_INIT() ext_intr_stats_init()
#define EXT_INTR_STATS_CAUSE(l, h, g, s) ext_intr_stats_cause(l, h, g, s)
#define EXT_INTR_STATS_COMMIT_M(m) ext_intr_stats_commit_m(m)
#define EXT_INTR_STATS_COMMIT_IRQ(i) ext_intr_stats_commit_irq(i)
#define EXT_INTR_STATS_DECL(t) u_int64_t t
#define EXT_INTR_STATS_PRE(i, t) t = ext_intr_stats_pre(i)
#define EXT_INTR_STATS_POST(i, t) ext_intr_stats_post(i, t)
#define EXT_INTR_STATS_PEND(l, h, g, s) ext_intr_stats_pend(l, h, g, s)
#define EXT_INTR_STATS_PEND_IRQ(i) ext_intr_stats[i].pnd++
#define EXT_INTR_STATS_DEPTH() \
intr_depth_max = (intr_depth > intr_depth_max) ? \
intr_depth : intr_depth_max
#else /* EXT_INTR_STATS */
#define EXT_INTR_STATS_INIT()
#define EXT_INTR_STATS_CAUSE(l, h, g, s)
#define EXT_INTR_STATS_COMMIT_M(m)
#define EXT_INTR_STATS_COMMIT_IRQ(i)
#define EXT_INTR_STATS_DECL(t)
#define EXT_INTR_STATS_PRE(irq, t)
#define EXT_INTR_STATS_POST(i, t)
#define EXT_INTR_STATS_PEND(l, h, g, s)
#define EXT_INTR_STATS_PEND_IRQ(i)
#define EXT_INTR_STATS_DEPTH()
#endif /* EXT_INTR_STATS */
#ifdef SPL_STATS
typedef struct spl_hist {
int level;
void *addr;
u_int64_t time;
} spl_hist_t;
extern void spl_stats_init();
extern void spl_stats_log();
extern unsigned int spl_stats_enb;
#define SPL_STATS_INIT() spl_stats_init()
#define SPL_STATS_LOG(ipl, cc) spl_stats_log((ipl), (cc))
#else
#define SPL_STATS_INIT()
#define SPL_STATS_LOG(ipl, cc)
#endif /* SPL_STATS */
void intr_dispatch(void);
#ifdef SPL_INLINE
static inline int splraise(int);
static inline int spllower(int);
static inline void splx(int);
#else
extern int splraise(int);
extern int spllower(int);
extern void splx(int);
#endif
extern volatile int tickspending;
extern volatile imask_t ipending;
typedef uint64_t imask_t;
extern imask_t imask[];
/*
* inlines for manipulating PSL_EE
*/
static inline void
extintr_restore(register_t omsr)
{
__asm volatile ("sync; mtmsr %0;" :: "r"(omsr));
}
#define NVIRQ 64 /* 64 virtual IRQs */
#define NIRQ 128 /* up to 128 HW IRQs */
static inline register_t
extintr_enable(void)
{
register_t omsr;
#define HWIRQ_MAX (NVIRQ - 4 - 1)
#define HWIRQ_MASK 0x0ffffffffffffffeULL
__asm volatile("sync;");
__asm volatile("mfmsr %0;" : "=r"(omsr));
__asm volatile("mtmsr %0;" :: "r"(omsr | PSL_EE));
/* Soft interrupt masks. */
#define SIR_CLOCK 60
#define SIR_BIO 61
#define SIR_NET 62
#define SIR_SERIAL 63
#define SPL_CLOCK 0
return omsr;
}
#define MS_PENDING(p) (((p) & (1 << SPL_CLOCK)) ? SPL_CLOCK : \
(((p) & (0xffffffffULL << 32)) ? \
63 - cntlzw((p) >> 32) : \
32 - cntlzw((p) & 0xffffffff)))
static inline register_t
extintr_disable(void)
{
register_t omsr;
#define setsoftclock() softintr(SIR_CLOCK)
#define setsoftbio() softintr(SIR_BIO)
#define setsoftnet() softintr(SIR_NET)
#define setsoftserial() softintr(SIR_SERIAL)
__asm volatile("mfmsr %0;" : "=r"(omsr));
__asm volatile("mtmsr %0;" :: "r"(omsr & ~PSL_EE));
__asm volatile("isync;");
return omsr;
}
#ifdef SPL_INLINE
static inline int
splraise(int ncpl)
{
int ocpl;
register_t omsr;
omsr = extintr_disable();
ocpl = cpl;
if (ncpl > cpl) {
SPL_STATS_LOG(ncpl, 0);
cpl = ncpl;
if ((ncpl == IPL_HIGH) && ((omsr & PSL_EE) != 0)) {
/* leave external interrupts disabled */
return (ocpl | IPL_EE);
}
}
extintr_restore(omsr);
return (ocpl);
}
static inline void
splx(int xcpl)
{
imask_t *ncplp;
register_t omsr;
int ncpl = xcpl & IPL_PRIMASK;
ncplp = &imask[ncpl];
omsr = extintr_disable();
if (ncpl < cpl) {
cpl = ncpl;
SPL_STATS_LOG(ncpl, 0);
if (imask_test_v(&ipending, ncplp))
intr_dispatch();
}
if (xcpl & IPL_EE)
omsr |= PSL_EE;
extintr_restore(omsr);
}
static inline int
spllower(int ncpl)
{
int ocpl;
imask_t *ncplp;
register_t omsr;
ncpl &= IPL_PRIMASK;
ncplp = &imask[ncpl];
omsr = extintr_disable();
ocpl = cpl;
cpl = ncpl;
SPL_STATS_LOG(ncpl, 0);
#ifdef EXT_INTR_STATS
ext_intr_statp = 0;
#endif
if (imask_test_v(&ipending, ncplp))
intr_dispatch();
if (ncpl < IPL_HIGH)
omsr |= PSL_EE;
extintr_restore(omsr);
return (ocpl);
}
#endif /* SPL_INLINE */
/*
* Soft interrupt IRQs
* see also intrnames[] in locore.S
*/
#define SIR_BASE (NIRQ-32)
#define SIXBIT(ipl) ((ipl) - SIR_BASE) /* XXX rennovate later */
#define SIR_SOFTCLOCK (NIRQ-5)
#define SIR_CLOCK SIXBIT(SIR_SOFTCLOCK) /* XXX rennovate later */
#define SIR_SOFTNET (NIRQ-4)
#define SIR_SOFTBIO (NIRQ-3)
#define SIR_SOFTSERIAL (NIRQ-2)
#define SIR_HWCLOCK (NIRQ-1)
#define SPL_CLOCK SIXBIT(SIR_HWCLOCK) /* XXX rennovate later */
#define SIR_RES ~(SIBIT(SIR_SOFTCLOCK)|\
SIBIT(SIR_SOFTNET)|\
SIBIT(SIR_SOFTBIO)|\
SIBIT(SIR_SOFTSERIAL)|\
SIBIT(SIR_HWCLOCK))
struct intrhand;
/*
* Miscellaneous
*/
#define spl0() spllower(IPL_NONE)
#define spl0() spllower(0)
typedef int ipl_t;
typedef struct {
@ -460,33 +121,13 @@ splraiseipl(ipl_cookie_t icookie)
#include <sys/spl.h>
#define SIBIT(ipl) (1 << ((ipl) - SIR_BASE))
#define ICU_LEN (64 + 32) /* Main Interrupt(64) + GPIO(32) */
void *intr_establish(int, int, int, int (*)(void *), void *);
void intr_disestablish(void *);
void init_interrupt(void);
const char * intr_typename(int);
const char * intr_string(int);
const struct evcnt * intr_evcnt(int);
void ext_intr(struct intrframe *);
/* the following are needed to compile until this port is properly
* converted to ppcoea-rennovation.
*/
void genppc_cpu_configure(void);
void strayintr(int);
/*
* defines for indexing intrcnt
*/
#define CNT_IRQ0 0
#define CNT_CLOCK SIR_HWCLOCK
#define CNT_SOFTCLOCK SIR_SOFTCLOCK
#define CNT_SOFTNET SIR_NET
#define CNT_SOFTSERIAL SIR_SOFTSERIAL
#define CNT_SOFTBIO SIR_BIO
extern struct pic_ops *discovery_pic;
extern struct pic_ops *discovery_gpp_pic[4];
struct pic_ops *setup_discovery_pic(void);
struct pic_ops *setup_discovery_gpp_pic(void *, int);
#endif /* !_LOCORE */
#endif /* _MVPPPC_INTR_H_ */
#endif /* _POWERPC_MARVELL_INTR_H_ */

View File

@ -0,0 +1,94 @@
/* $NetBSD: pci_machdep.c,v 1.1 2010/04/28 13:51:55 kiyohara Exp $ */
/*
* Copyright (c) 2009 KIYOHARA Takashi
* 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.1 2010/04/28 13:51:55 kiyohara Exp $");
#include "gtpci.h"
#include "pci.h"
#include <sys/param.h>
#include <sys/device.h>
#include <sys/extent.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pciconf.h>
#if NGTPCI > 0
#include <dev/marvell/gtpcireg.h>
#include <dev/marvell/gtpcivar.h>
#endif
#include <dev/marvell/marvellvar.h>
#include <machine/pci_machdep.h>
#if NGTPCI > 0
extern void gtpci_md_conf_interrupt(pci_chipset_tag_t, int, int, int, int,
int *);
extern int gtpci_md_conf_hook(void *, int, int, int, pcireg_t);
struct genppc_pci_chipset genppc_gtpci0_chipset = {
NULL, /* pc_conf_v */
gtpci_attach_hook,
(int (*)(pci_chipset_tag_t, int))gtpci_bus_maxdevs,
gtpci_make_tag,
gtpci_conf_read,
gtpci_conf_write,
&genppc_gtpci0_chipset, /* pc_intr_v */
genppc_pci_intr_map,
genppc_pci_intr_string,
genppc_pci_intr_evcnt,
genppc_pci_intr_establish,
genppc_pci_intr_disestablish,
gtpci_md_conf_interrupt,
gtpci_decompose_tag,
(int (*)(pci_chipset_tag_t, int, int, int, pcireg_t))gtpci_md_conf_hook,
};
struct genppc_pci_chipset genppc_gtpci1_chipset = {
NULL, /* pc_conf_v */
gtpci_attach_hook,
(int (*)(pci_chipset_tag_t, int))gtpci_bus_maxdevs,
gtpci_make_tag,
gtpci_conf_read,
gtpci_conf_write,
&genppc_gtpci1_chipset, /* pc_intr_v */
genppc_pci_intr_map,
genppc_pci_intr_string,
genppc_pci_intr_evcnt,
genppc_pci_intr_establish,
genppc_pci_intr_disestablish,
gtpci_md_conf_interrupt,
gtpci_decompose_tag,
(int (*)(pci_chipset_tag_t, int, int, int, pcireg_t))gtpci_md_conf_hook,
};
#endif

View File

@ -1,124 +0,0 @@
/* $NetBSD: pci_machdep.h,v 1.8 2007/12/26 00:58:05 mrg Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
* Copyright (c) 1994 Charles M. Hannum. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Charles M. Hannum.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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.
*/
#ifndef __MACHINE_PCI_MACHDEP_H
#define __MACHINE_PCI_MACHDEP_H
/*
* Machine-specific definitions for PCI autoconfiguration.
*/
#define __PCI_BUS_DEVORDER 1
#define __HAVE_PCI_CONF_HOOK 1
/*
* be-specific PCI structure and type definitions.
* NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE.
*
* Configuration tag; created from a {bus,device,function} triplet by
* pci_make_tag(), and passed to pci_conf_read() and pci_conf_write().
* We could instead always pass the {bus,device,function} triplet to
* the read and write routines, but this would cause extra overhead.
*/
struct pci_attach_args; /* Forward declaration */
/*
* Types provided to machine-independent PCI code
*/
typedef struct pci_chipset *pci_chipset_tag_t;
typedef int pcitag_t;
typedef int pci_intr_handle_t;
struct pci_chipset_functions {
void (*pcf_bus_attach_hook)(struct device *, struct device *,
struct pcibus_attach_args *);
int (*pcf_bus_maxdevs)(pci_chipset_tag_t, int);
void (*pcf_bus_devorder)(pci_chipset_tag_t, int, char []);
pcitag_t (*pcf_make_tag)(pci_chipset_tag_t, int, int, int);
void (*pcf_decompose_tag)(pci_chipset_tag_t, pcitag_t, int *, int *,
int *);
pcireg_t (*pcf_conf_read)(pci_chipset_tag_t, pcitag_t, int);
void (*pcf_conf_write)(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
int (*pcf_conf_hook)(pci_chipset_tag_t, int, int, int, pcireg_t);
void (*pcf_conf_interrupt)(pci_chipset_tag_t, int, int, int, int,
int *);
int (*pcf_intr_map)(struct pci_attach_args *, pci_intr_handle_t *);
const char *(*pcf_intr_string)(pci_chipset_tag_t, pci_intr_handle_t);
const struct evcnt *(*pcf_intr_evcnt)(pci_chipset_tag_t,
pci_intr_handle_t);
void *(*pcf_intr_establish)(pci_chipset_tag_t, pci_intr_handle_t,
int, int (*)(void *), void *);
void (*pcf_intr_disestablish)(pci_chipset_tag_t, void *);
};
struct pci_chipset {
struct device *pc_parent;
const struct pci_chipset_functions *pc_funcs;
};
/*
* Functions provided to machine-independent PCI code.
*/
#define pci_attach_hook(parent, self, pba) \
((*(pba)->pba_pc->pc_funcs->pcf_bus_attach_hook)((parent), (self), (pba)))
#define pci_bus_maxdevs(pc, busno) \
((*(pc)->pc_funcs->pcf_bus_maxdevs)((pc), (busno)))
#define pci_make_tag(pc, bus, dev, func) \
((*(pc)->pc_funcs->pcf_make_tag)((pc), (bus), (dev), (func)))
#define pci_decompose_tag(pc, tag, bp, dp, fp) \
((*(pc)->pc_funcs->pcf_decompose_tag)((pc), (tag), (bp), (dp), (fp)))
#define pci_conf_read(pc, tag, reg) \
((*(pc)->pc_funcs->pcf_conf_read)((pc), (tag), (reg)))
#define pci_conf_write(pc, tag, reg, data) \
((*(pc)->pc_funcs->pcf_conf_write)((pc), (tag), (reg), (data)))
#define pci_conf_hook(pc, bus, dev, func, id) \
((*(pc)->pc_funcs->pcf_conf_hook)((pc), (bus), (dev), (func), (id)))
#define pci_conf_interrupt(pc, bus, dev, pin, swiz, iline) \
((*(pc)->pc_funcs->pcf_conf_interrupt)((pc), (bus), (dev), (pin), (swiz), (iline)))
#define pci_intr_map(pa, ihp) \
((*(pa)->pa_pc->pc_funcs->pcf_intr_map)((pa), (ihp)))
#define pci_intr_string(pc, ih) \
((*(pc)->pc_funcs->pcf_intr_string)((pc), (ih)))
#define pci_intr_evcnt(pc, ih) \
((*(pc)->pc_funcs->pcf_intr_evcnt)((pc), (ih)))
#define pci_intr_establish(pc, ih, ipl, func, arg) \
((*(pc)->pc_funcs->pcf_intr_establish)((pc), (ih), (ipl), (func), (arg)))
#define pci_intr_disestablish(pc, ih) \
((*(pc)->pc_funcs->pcf_intr_disestablish)((pc), (ih)))
#define pci_bus_devorder(pc, bus, devs) \
((*(pc)->pc_funcs->pcf_bus_devorder)((pc), (bus), (devs)))
#endif /* __MACHINE_PCI_MACHDEP_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pic_discovery.c,v 1.2 2007/10/17 19:56:42 garbled Exp $ */
/* $NetBSD: pic_discovery.c,v 1.3 2010/04/28 13:51:55 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -37,412 +37,207 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* extintr.c - external interrupt management for discovery
*
* Interrupts are software-prioritized and preempting,
* they are only actually masked when pending.
* this allows avoiding slow, off-CPU mask reprogramming for spl/splx.
* When a lower priority interrupt preempts a high one,
* it is pended and masked. Masks are re-enabled after service.
*
* `ci->ci_cpl' is a "priority level" not a bitmask.
* `irq' is a bit number in the 128 bit imask_t which reflects
* the GT-64260 Main Cause register pair (64 bits), and
* GPP Cause register (32 bits) interrupts.
*
* Intra IPL dispatch order is defined in cause_irq()
*
* Summary bits in cause registers are not valid IRQs
*
* Within a cause register bit vector ISRs are called in
* order of IRQ (descending).
*
* When IRQs are shared, ISRs are called in order on the queue
* (which is arbitrarily first-established-first-served).
*
* GT64260 GPP setup is for edge-triggered interrupts.
* We maintain a mask of level-triggered type IRQs
* and gather unlatched level from the GPP Value register.
*
* Software interrupts are just like regular IRQs,
* they are established, pended, and dispatched exactly the
* same as HW interrupts.
*
* 128 bit imask_t operations could be implemented with Altivec
* ("vand", "vor", etc however no "vcntlzw" or "vffs"....)
*
* creation Tue Feb 6 17:27:18 PST 2001 cliff
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pic_discovery.c,v 1.2 2007/10/17 19:56:42 garbled Exp $");
#include "opt_marvell.h"
#include "opt_kgdb.h"
__KERNEL_RCSID(0, "$NetBSD: pic_discovery.c,v 1.3 2010/04/28 13:51:55 kiyohara Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <machine/psl.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <powerpc/pic/picvar.h>
#ifdef KGDB
#include <machine/db_machdep.h>
#endif
#include <dev/marvell/gtreg.h>
#include <dev/marvell/gtvar.h>
#include <dev/marvell/gtintrreg.h>
#include <dev/marvell/gtintrvar.h>
#include <uvm/uvm_extern.h>
#if defined(DEBUG) && defined(DDB)
#endif
#ifdef DEBUG
# define STATIC
int intrdebug = 0;
# define DPRINTF(x) do { if (intrdebug) printf x ; } while (0)
# define DPRINTFN(n, x) do { if (intrdebug > (n)) printf x ; } while (0)
#else
# define STATIC static
# define DPRINTF(x)
# define DPRINTFN(n, x)
#endif
#ifdef DIAGNOSTIC
# define DIAGPRF(x) printf x
#else
# define DIAGPRF(x)
#endif
#define ILLEGAL_IRQ(x) (((x) < 0) || ((x) >= NIRQ) || \
((1<<((x)&IMASK_BITMASK)) & imres.bits[(x)>>IMASK_WORDSHIFT]))
extern struct powerpc_bus_space gt_mem_bs_tag;
extern bus_space_handle_t gt_memh;
static const char intr_source_strings[NIRQ][16] = {
"unknown 0", "dev", "dma", "cpu",
"idma 01", "idma 23", "idma 45", "idma 67",
"timer 01", "timer 23", "timer 45", "timer 67",
"pci0-0", "pci0-1", "pci0-2", "pci0-3",
/*16*/ "pci1-0", "ecc", "pci1-1", "pci1-2",
"pci1-3", "pci0-outl", "pci0-outh", "pci1-outl",
"pci1-outh", "unknown 25", "pci0-inl", "pci0-inh",
"pci1-inl", "pci1-inh", "unknown 30", "unknown 31",
/*32*/ "ether 0", "ether 1", "ether 2", "unknown 35",
"sdma", "iic", "unknown 38", "brg",
"mpsc 0", "unknown 41", "mpsc 1", "comm",
"unknown 44", "unknown 45", "unknown 46", "unknown 47",
/*48*/ "unknown 48", "unknown 49", "unknown 50", "unknown 51",
"unknown 52", "unknown 53", "unknown 54", "unknown 55",
"gppsum 0", "gppsum 1", "gppsum 2", "gppsum 3",
"unknown 60", "unknown 61", "unknown 62", "unknown 63",
};
struct discovery_gpp_pic_ops;
struct discovery_pic_ops {
struct pic_ops dsc_pic;
bus_space_tag_t dsc_memt;
bus_space_tag_t dsc_memh;
uint32_t dsc_interrupt_mask[2];
uint8_t dsc_priority[64];
uint8_t dsc_maxpriority[64];
struct pic_ops pic;
union {
uint64_t mask64;
uint32_t mask32[2];
} _mask;
#define enable_mask _mask.mask64
#define enable_mask_high _mask.mask32[1]
#define enable_mask_low _mask.mask32[0]
};
struct discovery_gpp_pic_ops {
struct pic_ops pic;
int gpp_base;
};
struct gpp_pic_ops {
struct pic_ops gpp_pic;
bus_space_tag_t gpp_memt;
bus_space_handle_t gpp_memh;
uint32_t gpp_interrupt_mask;
uint8_t gpp_priority[32];
uint8_t gpp_maxpriority[32];
};
static void
gpp_source_name(struct pic_ops *pic, int irq, char *name, size_t len)
static void discovery_enable_irq(struct pic_ops *, int, int);
static void discovery_disable_irq(struct pic_ops *, int);
static int discovery_get_irq(struct pic_ops *, int);
static void discovery_ack_irq(struct pic_ops *, int);
static void discovery_gpp_enable_irq(struct pic_ops *, int, int);
static void discovery_gpp_disable_irq(struct pic_ops *, int);
static int discovery_gpp_get_irq(struct pic_ops *, int);
static void discovery_gpp_ack_irq(struct pic_ops *, int);
struct pic_ops *
setup_discovery_pic()
{
snprintf(name, len, "gpp %d", irq);
}
struct discovery_pic_ops *discovery;
struct pic_ops *pic;
#define GPP_RES ~GT_MPP_INTERRUPTS /* from config */
discovery =
malloc(sizeof(struct discovery_pic_ops), M_DEVBUF, M_NOWAIT);
KASSERT(discovery != NULL);
static int
gpp_get_irq(struct pic_ops *pic)
{
struct gpppic_ops * const gpp = (void *)pic;
uint32_t mask;
int maybe_irq = -1;
int maybe_priority = IPL_NONE;
pic = &discovery->pic;
pic->pic_numintrs = 64;
pic->pic_cookie = (void *)NULL; /* set later */
pic->pic_enable_irq = discovery_enable_irq;
pic->pic_reenable_irq = discovery_enable_irq;
pic->pic_disable_irq = discovery_disable_irq;
pic->pic_get_irq = discovery_get_irq;
pic->pic_ack_irq = discovery_ack_irq;
pic->pic_establish_irq = dummy_pic_establish_intr;
pic->pic_finish_setup = NULL;
strcpy(pic->pic_name, "discovery");
pic_add(pic);
#ifdef GPP_EDGE
mask = bus_space_read_4(&gpp->gpp_memt, gpp->gpp_memh, GT_GPP_Interrupt_Cause);
#else
mask = bus_space_read_4(&gpp->gpp_memt, gpp->gpp_memh, GT_GPP_Value);
#endif
mask &= gpp->gpp_interrupt_mask;
if (mask == 0)
return NO_IRQ;
discovery->enable_mask = 0;
while (mask != 0) {
int irq = 32 - __builtin_clz(mask);
if (gpp->gpp_priority[irq] > maybe_irq) {
maybe_irq = irq;
maybe_priority = gpp->gpp_priority[irq];
if (maybe_priority > gpp->gpp_maxpriority[irq])
break;
}
mask &= ~(1 << irq);
}
/*
* We now have the highest priority IRQ.
*/
KASSERT(maybe_irq >= 0);
#ifdef GPP_EDGE
mask = 1 << maybe_irq;
bus_space_write_4(&gpp->gpp_memt, gpp->gpp_memh, GT_GPP_Interrupt_Cause, mask);
#endif
return maybe_irq;
}
static void
gpp_establish_irq(struct pic_ops *pic, int irq, int type, int pri)
{
struct gpppic_ops * const gpp = (void *)pic;
const uint32_t mask = 1 << irq;
KASSERT((unsigned) irq < 32);
#ifdef GPP_EDGE
KASSERT(type == IST_EDGE);
#else
KASSERT(type == IST_LEVEL);
#endif
/*
* Set pin to input and active low.
*/
val = bus_space_read_4(gpp->gpp_memt, gpp->gpp_memh, GT_GPP_IO_Control);
val &= ~mask;
bus_space_write_4(gpp->gpp_memt, gpp->gpp_memh, GT_GPP_IO_Control, val);
val = bus_space_read_4(gpp->gpp_memt, gpp->gpp_memh, GT_GPP_Level_Control);
val |= mask;
bus_space_write_4(&gpp->gpp_memt, gpp->gpp_memh, GT_GPP_Level_Control, val);
gpp->gpp_priority[irq] = pri;
/*
* recalculate the maxpriority of an interrupt. This is highest
* priority interrupt from itself to gpp0.
*/
pri = IPL_NONE;
for (i = 0; i < __arraycount(gpp->gpp_priority); i++) {
if (gpp->gpp_priority[i] > pri)
pri = gpp->gpp_priority[i];
gpp->gpp_maxpriority[i] = pri;
}
}
static void
gpp_enable_irq(struct pic_ops *pic, int irq, int type)
{
struct gpppic_ops * const gpp = (void *)pic;
const uint32_t mask = 1 << irq;
KASSERT(type == IST_LEVEL);
KASSERT(gpp->gpp_priority[irq] != IPL_NONE);
gpp->gpp_interrupt_mask |= mask;
bus_space_write_4(&gpp->gpp_memt, gpp->gpp_memh, GT_GPP_Interrupt_Mask,
gpp->gpp_interrupt_mask);
}
static void
gpp_disable_irq(struct pic_ops *pic, int irq)
{
struct gpppic_ops * const gpp = (void *)pic;
const uint32_t mask = 1 << irq;
gpp->gpp_interrupt_mask &= ~mask;
bus_space_write_4(&gpp->gpp_memt, gpp->gpp_memh, GT_GPP_Interrupt_Mask,
gpp->gpp_interrupt_mask);
}
static void
gpp_ack_irq(struct pic_ops *pic, int irq)
{
}
static struct pic_ops *
gpp_pic_setup(bus_space_tag_t memt, bus_space_handle_t memh)
{
struct gpppic_ops * gpp;
uint32_t val;
gpp = malloc(sizeof(*gpp), M_DEVBUF, M_NOWAIT|M_ZERO);
if (!gpp)
panic("gpp_pic_setup: malloc(%zu) failed", sizeof(*gpp));
gpp->gpp_memt = memt;
gpp->gpp_memh = memh;
gpp->gpp_pic.pic_get_irq = gpp_get_irq;
gpp->gpp_pic.pic_enable_irq = gpp_enable_irq;
gpp->gpp_pic.pic_reenable_irq = gpp_enable_irq;
gpp->gpp_pic.pic_disable_irq = gpp_disable_irq;
gpp->gpp_pic.pic_ack_irq = gpp_ack_irq;
gpp->gpp_pic.pic_establish_irq = gpp_establish_irq;
gpp->gpp_pic.pic_source_name = gpp_source_name;
/*
* Force GPP interrupts to be level sensitive.
*/
val = bus_space_read_4(&gpp->gpp_memt, gpp->gpp_memh, 0xf300);
bus_space_write_4(&gpp->gpp_memt, gpp->gpp_memh, 0xf300, val | 0x400);
pic_add(&gpp->gpp_pic);
return &gpp->gpp_pic;
}
static void
discovery_source_name(struct pic_ops *pic, int irq, char *name, size_t len)
{
strlcpy(name, discovery_intr_source_strings[irq], len);
}
static int
discovery_get_irq(struct pic_ops *pic)
{
struct discoverypic_ops * const dsc = (void *)pic;
uint32_t mask;
int irq_base = 0;
int maybe_irq = -1;
int maybe_priority = IPL_NONE;
mask = bus_space_read_4(&dsc->dsc_memt, dsc->dsc_memh, ICR_CSC);
if (!(mask & CSC_STAT))
return NO_IRQ;
irq_base = (mask & CSC_SEL) ? 32 : 0;
mask &= dsc->dsc_interrupt_mask[(mask & CSC_SEL) ? 1 : 0];
while (mask != 0) {
int irq = 32 - __builtin_clz(mask);
if (dsc->dsc_priority[irq_base + irq] > maybe_irq) {
maybe_irq = irq_base + irq;
maybe_priority = dsc->dsc_priority[irq_base + irq];
if (maybe_priority > dsc->dsc_maxpriority[irq_base + irq])
break;
}
mask &= ~(1 << irq);
}
/*
* We now have the highest priority IRQ (except it's cascaded).
*/
KASSERT(maybe_irq >= 0);
return maybe_irq;
}
static void
discovery_establish_irq(struct pic_ops *pic, int irq, int type, int pri)
{
struct discoverypic_ops * const dsc = (void *)pic;
KASSERT((unsigned) irq < 32);
#ifdef GPP_EDGE
KASSERT(type == IST_EDGE);
#else
KASSERT(type == IST_LEVEL);
#endif
dsc->dsc_priority[irq] = pri;
/*
* recalculate the maxpriority of an interrupt. This is highest
* priority interrupt from itself to irq 0.
*/
pri = IPL_NONE;
for (i = 0; i < __arraycount(dsc->dsc_priority); i++) {
if (dsc->dsc_priority[i] > pri)
pri = dsc->dsc_priority[i];
dsc->dsc_maxpriority[i] = pri;
}
return pic;
}
static void
discovery_enable_irq(struct pic_ops *pic, int irq, int type)
{
struct discoverypic_ops * const dsc = (void *)pic;
const uint32_t mask = 1 << (irq & 31);
struct discovery_pic_ops *discovery = (struct discovery_pic_ops *)pic;
KASSERT(type == IST_LEVEL);
KASSERT(dsc->dsc_priority[irq] != IPL_NONE);
if (irq < 32) {
dsc->dsc_interrupt_mask[0] |= mask;
bus_space_write_4(&dsc->dsc_memt, dsc->dsc_memh,
ICR_MIC_LO, dsc->dsc_interrupt_mask[0]);
} else {
dsc->dsc_interrupt_mask[1] |= mask;
bus_space_write_4(&dsc->dsc_memt, dsc->dsc_memh,
ICR_MIC_HI, dsc->dsc_interrupt_mask[1]);
}
discovery->enable_mask |= (1 << irq);
discovery_enable_intr(pic->pic_cookie, irq);
}
static void
discovery_disable_irq(struct pic_ops *pic, int irq)
{
struct discoverypic_ops * const dsc = (void *)pic;
const uint32_t mask = 1 << (irq & 31);
struct discovery_pic_ops *discovery = (struct discovery_pic_ops *)pic;
if (irq < 32) {
dsc->dsc_interrupt_mask[0] &= ~mask;
bus_space_write_4(&dsc->dsc_memt, dsc->dsc_memh,
ICR_MIC_LO, dsc->dsc_interrupt_mask[0]);
} else {
dsc->dsc_interrupt_mask[1] &= ~mask;
bus_space_write_4(&dsc->dsc_memt, dsc->dsc_memh,
ICR_MIC_HI, dsc->dsc_interrupt_mask[1]);
discovery->enable_mask &= ~(1 << irq);
discovery_disable_intr(pic->pic_cookie, irq);
}
static int
discovery_get_irq(struct pic_ops *pic, int mode)
{
struct discovery_pic_ops *discovery = (struct discovery_pic_ops *)pic;
uint32_t cause;
int irq, base, msk;
cause = discovery_mic_low(pic->pic_cookie) & discovery->enable_mask_low;
if (cause)
base = 0;
else {
cause = discovery_mic_high(pic->pic_cookie);
cause &= discovery->enable_mask_high;
if (!cause)
return 255;
base = 32;
}
for (irq = base, msk = 0x00000001; !(cause & msk); irq++, msk <<= 1);
return irq;
}
static void
discovery_ack_irq(struct pic_ops *pic, int irq)
{
/* nothing */
}
void
discoverypic_setup(bus_space_tag_t memt, bus_space_handle_t memh)
struct pic_ops *
setup_discovery_gpp_pic(void *discovery, int gpp_base)
{
struct discoverypic_ops *dsc;
uint32_t val;
struct discovery_gpp_pic_ops *discovery_gpp;
struct pic_ops *pic;
dsc = malloc(sizeof(*dsc), M_DEVBUF, M_NOWAIT|M_ZERO);
if (!dsc)
panic("dsc_pic_setup: malloc(%zu) failed", sizeof(*dsc));
discovery_gpp =
malloc(sizeof(struct discovery_gpp_pic_ops), M_DEVBUF, M_NOWAIT);
KASSERT(discovery_gpp != NULL);
dsc->dsc_memt = memt;
dsc->dsc_memh = memh;
dsc->dsc_pic.pic_get_irq = dsc_get_irq;
dsc->dsc_pic.pic_enable_irq = dsc_enable_irq;
dsc->dsc_pic.pic_reenable_irq = dsc_enable_irq;
dsc->dsc_pic.pic_disable_irq = dsc_disable_irq;
dsc->dsc_pic.pic_ack_irq = dsc_ack_irq;
dsc->dsc_pic.pic_establish_irq = dsc_establish_irq;
dsc->dsc_pic.pic_source_name = dsc_source_name;
pic = &discovery_gpp->pic;
pic->pic_numintrs = 32;
pic->pic_cookie = discovery;
pic->pic_enable_irq = discovery_gpp_enable_irq;
pic->pic_reenable_irq = discovery_gpp_enable_irq;
pic->pic_disable_irq = discovery_gpp_disable_irq;
pic->pic_get_irq = discovery_gpp_get_irq;
pic->pic_ack_irq = discovery_gpp_ack_irq;
pic->pic_establish_irq = dummy_pic_establish_intr;
pic->pic_finish_setup = NULL;
strcpy(pic->pic_name, "discovery_gpp");
pic_add(pic);
pic_add(&dsc->dsc_pic);
KASSERT(dsc->dsc_pic.pic_intrbase == 0);
discovery_gpp->gpp_base = gpp_base;
pic = dscpic_setup(memt, memh);
intr_establish(dsc->dsc_pic.pic_intrbase + IRQ_GPP7_0,
IST_LEVEL, IPL_NONE, pic_handle_intr, pic);
intr_establish(dsc->dsc_pic.pic_intrbase + IRQ_GPP15_8,
IST_LEVEL, IPL_NONE, pic_handle_intr, pic);
intr_establish(dsc->dsc_pic.pic_intrbase + IRQ_GPP23_16,
IST_LEVEL, IPL_NONE, pic_handle_intr, pic);
intr_establish(dsc->dsc_pic.pic_intrbase + IRQ_GPP31_24,
IST_LEVEL, IPL_NONE, pic_handle_intr, pic);
return pic;
}
static void
discovery_gpp_enable_irq(struct pic_ops *pic, int irq, int type)
{
struct discovery_gpp_pic_ops *discovery_gpp =
(struct discovery_gpp_pic_ops *)pic;
struct discovery_pic_ops *discovery = discovery_gpp->pic.pic_cookie;
discovery_gpp_enable_intr(discovery->pic.pic_cookie,
discovery_gpp->gpp_base + irq);
}
static void
discovery_gpp_disable_irq(struct pic_ops *pic, int irq)
{
struct discovery_gpp_pic_ops *discovery_gpp =
(struct discovery_gpp_pic_ops *)pic;
struct discovery_pic_ops *discovery = discovery_gpp->pic.pic_cookie;
discovery_gpp_disable_intr(discovery->pic.pic_cookie,
discovery_gpp->gpp_base + irq);
}
static int
discovery_gpp_get_irq(struct pic_ops *pic, int mode)
{
struct discovery_gpp_pic_ops *discovery_gpp =
(struct discovery_gpp_pic_ops *)pic;
struct discovery_pic_ops *discovery = discovery_gpp->pic.pic_cookie;
uint32_t cause, mask;
int irq, msk, base;
cause = discovery_gpp_cause(discovery->pic.pic_cookie);
mask = discovery_gpp_mask(discovery->pic.pic_cookie);
base = discovery_gpp->gpp_base;
cause &= (mask & (0xff << base));
if (!cause)
return 255;
for (irq = base, msk = (1 << base); !(cause & msk); irq++, msk <<= 1);
return irq;
}
static void
discovery_gpp_ack_irq(struct pic_ops *pic, int irq)
{
struct discovery_gpp_pic_ops *discovery_gpp =
(struct discovery_gpp_pic_ops *)pic;
struct discovery_pic_ops *discovery = discovery_gpp->pic.pic_cookie;
discovery_gpp_clear_cause(discovery->pic.pic_cookie,
discovery_gpp->gpp_base + irq);
}

View File

@ -1,59 +0,0 @@
/* $NetBSD: watchdog.h,v 1.1 2003/03/05 22:08:29 matt Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* 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.
*/
/*
* watchdog.h - MACHINE-specific watchdog hooks for GT-64260
*
* creation Tue Nov 27 09:37:43 PST 2001 cliff
*/
#ifndef _MACHINE_WATCHDOG_H
#define _MACHINE_WATCHDOG_H
void gt_watchdog_disable(void);
void gt_watchdog_enable(void);
void gt_watchdog_service(void);
void gt_watchdog_reset(void) __attribute__((__noreturn__));
#define WATCHDOG_DISABLE() gt_watchdog_disable()
#define WATCHDOG_ENABLE() gt_watchdog_enable()
#define WATCHDOG_SERVICE() gt_watchdog_service()
#endif /* _MACHINE_WATCHDOG_H */

View File

@ -1,33 +0,0 @@
External m.d. interface points:
To config, code should configure 'gt' with a struct gtbus_attach_args
filled in. The code should have already set up the bus_space and
bus_dma tags that are passed in.
m.d. pci_chipset_tag_t should contain at least a copy of the
gtpci_chipset_tag_t data structure.
m.d. code must provide the following functions:
pci_intr_map
pci_intr_string
pci_intr_establish,
pci_intr_disestablish
void *gtmpp_intr_establish(struct gt_softc *gt, int mpp_pin, int ipl,
int (*handler)(void *), void *arg);
Add an interrupt attached to Discovery MPP pin <mpp_pin> at
the given ipl with the given handler.
void gtmpp_intr_disestablish(struct gt_softc *gt, void *cookie);
Remove an interrupt attached to Discovery MPP pin.
int gtget_macaddr(struct gt_softc *gt, int function, char *enaddr);
Get MAC for Discovery ethernet <function>
void intr_enable(void);
Enable all interrupts (disregarding spls)
void intr_disable(void);
Disable all interrupts (disregarding spls)

View File

@ -1,4 +1,4 @@
# $NetBSD: files.discovery,v 1.10 2005/12/11 12:22:16 christos Exp $
# $NetBSD: files.discovery,v 1.11 2010/04/28 13:51:56 kiyohara Exp $
#
# Config file and device description for machine-independent support for
# the Marvell (formerly Galileo Technology) Discovery system controllers.
@ -19,44 +19,78 @@
defparam opt_marvell.h MPSC_CONSOLE
defparam opt_marvell.h GT_MPSC_DEFAULT_BAUD_RATE
defparam opt_marvell.h GT_MPP_INTERRUPTS GT_MPP_WATCHDOG GT_BASE
defparam opt_marvell.h GT_MPSC_FREQUENCY GT_MPSC_CLOCK_SOURCE
defparam opt_marvell.h GT_PCI0_MEMBASE GT_PCI0_MEMSIZE
defparam opt_marvell.h GT_PCI1_MEMBASE GT_PCI1_MEMSIZE
defparam opt_marvell.h GT_PCI0_IOBASE GT_PCI0_IOSIZE
defparam opt_marvell.h GT_PCI1_IOBASE GT_PCI1_IOSIZE
defflag opt_marvell.h GT_PCI0_EXT_ARBITER GT_PCI1_EXT_ARBITER
defflag opt_marvell.h GT_ECC
defparam opt_marvell.h GT_MPP_WATCHDOG
defflag opt_marvell.h GT_DEVBUS GT_ECC GT_COMM GT_WATCHDOG
define gt { [unit = -1] }
define gt { [unit = -1], [offset = -1], [irq = -1] }
device gt: gt
file dev/marvell/gt.c gt
file dev/marvell/gt.c gt
# PCI bus
# PCI Interface
define gtpci
file dev/marvell/gtpci.c gtpci & gtpci_gt needs-flag
device gtpci: pcibus
attach gtpci at gt
file dev/marvell/gtpci.c gt & pci
attach gtpci at gt with gtpci_gt
# PCI Express Interface
#define mvpex
#file dev/marvell/mvpex.c mvpex & (mvpex_gt|mvpex_mbus) needs-flag
#device mvpex: pcibus
#attach mvpex at gt with mvpex_gt
# Fast ethernet
define gfec { [port = -1], [irq = -1] }
device gfec: gfec
attach gfec at gt
device gfe: ether, ifnet, arp, mii
attach gfe at gt
file dev/marvell/if_gfe.c gfe
attach gfe at gfec
file dev/marvell/if_gfe.c gfec | gfe
# Serial controller
# Multi-Protocol Serial controller
device gtmpsc: tty
attach gtmpsc at gt
file dev/marvell/gtmpsc.c gtmpsc needs-flag
file dev/marvell/gtmpsc.c gtmpsc needs-flag
# DMA controller
device gtidma
attach gtidma at gt
file dev/marvell/gtidma.c gtidma
define obio { [offset=-1], [size=0], [irq=-1] }
define obio { [offset = -1], [size = 0], [irq = -1] }
device obio: obio
attach obio at gt
file dev/marvell/obio.c obio
file dev/marvell/obio.c obio
device gtiic: i2cbus
attach gtiic at gt
file dev/marvell/gti2c.c gtiic
# Serial-ATA II Host Controller (SATAHC)
#attach mvsata at gt with mvsata_gt
#file dev/marvell/mvsata_mv.c mvsata_gt | mvsata_mbus
# Gigabit Ethernet Controller Interface
#define mvgbec { [port = -1], [irq = -1] }
#device mvgbec: mvgbec
#attach mvgbec at gt with mvgbec_gt
#device mvgbe: ether, ifnet, arp, mii
#attach mvgbe at mvgbec
#file dev/marvell/if_mvgbe.c mvgbec | mvgbe
# USB 2.0 Interface
#attach ehci at gt with mvusb_gt
#file dev/marvell/ehci_mv.c mvusb_gt | mvusb_mbus
# Cryptographic Engines and Security Accelerator
#define mvcesa
#file dev/marvell/mvcesa.c mvcesa
#device mvcesa: opencrypto
#attach mvcesa at gt with mvcesa_gt
# Two-Wire Serial Interface
define gttwsi
file dev/marvell/gttwsi.c gttwsi
device gttwsi: i2cbus, gttwsi
attach gttwsi at gt with gttwsi_gt
# UART Interface
#attach com at gt with mvuart_gt
#file dev/marvell/com_mv.c mvuart_gt | mvuart_mbus
# IDMA Controller and XOR Engine
#define gtidmac
#file dev/marvell/gtidmac.c gtidmac
#device gtidmac: dmover_service
#attach gtidmac at gt with gtidmac_gt

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: gtbrgreg.h,v 1.1 2003/03/05 22:08:18 matt Exp $ */
/* $NetBSD: gtbrgreg.h,v 1.2 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -53,19 +53,16 @@
#define BITS(hi, lo) ((~((~0) << ((hi) + 1))) & ((~0) << (lo)))
#endif
#define GTBRG_NCHAN 3 /* Number of MPSC channels */
/*******************************************************************************
*
* BRG register address offsets relative to the base mapping
*/
#define BRG_BCR0 0xb200 /* BRG0 Configuration Register */
#define BRG_BTR0 0xb204 /* BRG0 Baud Tuning Register */
#define BRG_BCR1 0xb208 /* BRG1 Configuration Register */
#define BRG_BTR1 0xb20c /* BRG1 Baud Tuning Register */
#define BRG_BCR2 0xb210 /* BRG2 Configuration Register */
#define BRG_BTR2 0xb214 /* BRG2 Baud Tuning Register */
#define BRG_CAUSE 0xb834 /* BRG Cause Register */
#define BRG_MASK 0xb8b4 /* BRG Cause Register */
#define BRG_BCR(c) (0xb200 + ((c) << 3)) /* Baud Config Register */
#define BRG_BTR(c) (0xb204 + ((c) << 3)) /* Baud Tuning Register */
#define BRG_CAUSE 0xb834 /* BRG Cause Register */
#define BRG_MASK 0xb8b4 /* BRG Cause Register */
/*******************************************************************************
*

View File

@ -0,0 +1,39 @@
/* $NetBSD: gtbrgvar.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _GTBRGVAR_H_
#define _GTBRGVAR_H_
static __inline void
gt_brg_bcr(device_t gt, uint32_t brg, uint32_t bc)
{
struct gt_softc *sc = device_private(gt);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, BRG_BCR(brg),
bc | (((bc & BRG_BCR_CDV) != 0) ? BRG_BCR_EN : 0));
}
#endif /* _GTBRGVAR_H_ */

View File

@ -0,0 +1,55 @@
/* $NetBSD: gtdevbusvar.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _GTDEVBUSVAR_H_
#define _GTDEVBUSVAR_H_
static __inline int
gt_devbus_addr(device_t gt, int unit, uint32_t *ldp, uint32_t *hdp)
{
static const struct {
bus_addr_t low_decode;
bus_addr_t high_decode;
} obio_info[5] = {
{ GT_CS0_Low_Decode, GT_CS0_High_Decode, },
{ GT_CS1_Low_Decode, GT_CS1_High_Decode, },
{ GT_CS2_Low_Decode, GT_CS2_High_Decode, },
{ GT_CS3_Low_Decode, GT_CS3_High_Decode, },
{ GT_BootCS_Low_Decode, GT_BootCS_High_Decode, },
};
struct gt_softc *sc = device_private(gt);
if (unit >= __arraycount(obio_info))
return -1;
*ldp = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
obio_info[unit].low_decode);
*hdp = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
obio_info[unit].high_decode);
return 0;
}
#endif /* _GTDEVBUSVAR_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: gtethreg.h,v 1.4 2005/12/11 12:22:16 christos Exp $ */
/* $NetBSD: gtethreg.h,v 1.5 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -44,7 +44,6 @@
#define ETH__LLBIT(bit) (1LLU << (bit))
#define ETH__MASK(bit) (ETH__BIT(bit) - 1)
#define ETH__LLMASK(bit) (ETH__LLBIT(bit) - 1)
#define ETH__GEN(n, off) (0x2400+((n) << 10)+(ETH__ ## off))
#define ETH__EXT(data, bit, len) (((data) >> (bit)) & ETH__MASK(len))
#define ETH__LLEXT(data, bit, len) (((data) >> (bit)) & ETH__LLMASK(len))
#define ETH__CLR(data, bit, len) ((data) &= ~(ETH__MASK(len) << (bit)))
@ -127,81 +126,49 @@ struct gt_eth_desc {
#define HSH_LIMIT 12
#define ETHC_SIZE 0x4000 /* Register Space */
#define ETH_EPAR 0x2000 /* PHY Address Register */
#define ETH_ESMIR 0x2010 /* SMI Register */
#define ETH_BASE_ETH0 0x2400 /* Ethernet0 Register Base */
#define ETH_BASE_ETH1 0x2800 /* Ethernet1 Register Base */
#define ETH_BASE_ETH2 0x2c00 /* Ethernet2 Register Base */
#define ETH_SIZE 0x0400 /* Register Space */
#define ETH_BASE(u) (ETH0_BASE + ((u) << 10)) /* Ethernet Register Base */
#define ETH_NUM 3
#define ETH_SIZE 0x0400 /* Register Space */
#define ETH__EBASE 0x0000 /* Base of Registers */
#define ETH__EPCR 0x0000 /* Port Config. Register */
#define ETH__EPCXR 0x0008 /* Port Config. Extend Reg */
#define ETH__EPCMR 0x0010 /* Port Command Register */
#define ETH__EPSR 0x0018 /* Port Status Register */
#define ETH__ESPR 0x0020 /* Port Serial Parameters Reg */
#define ETH__EHTPR 0x0028 /* Port Hash Table Pointer Reg*/
#define ETH__EFCSAL 0x0030 /* Flow Control Src Addr Low */
#define ETH__EFCSAH 0x0038 /* Flow Control Src Addr High */
#define ETH__ESDCR 0x0040 /* SDMA Configuration Reg */
#define ETH__ESDCMR 0x0048 /* SDMA Command Register */
#define ETH__EICR 0x0050 /* Interrupt Cause Register */
#define ETH__EIMR 0x0058 /* Interrupt Mask Register */
#define ETH__EFRDP0 0x0080 /* First Rx Desc Pointer 0 */
#define ETH__EFRDP1 0x0084 /* First Rx Desc Pointer 1 */
#define ETH__EFRDP2 0x0088 /* First Rx Desc Pointer 2 */
#define ETH__EFRDP3 0x008c /* First Rx Desc Pointer 3 */
#define ETH__ECRDP0 0x00a0 /* Current Rx Desc Pointer 0 */
#define ETH__ECRDP1 0x00a4 /* Current Rx Desc Pointer 1 */
#define ETH__ECRDP2 0x00a8 /* Current Rx Desc Pointer 2 */
#define ETH__ECRDP3 0x00ac /* Current Rx Desc Pointer 3 */
#define ETH__ECTDP0 0x00e0 /* Current Tx Desc Pointer 0 */
#define ETH__ECTDP1 0x00e4 /* Current Tx Desc Pointer 1 */
#define ETH__EDSCP2P0L 0x0060 /* IP Differentiated Services
#define ETH_EBASE 0x0000 /* Base of Registers */
#define ETH_EPCR 0x0000 /* Port Config. Register */
#define ETH_EPCXR 0x0008 /* Port Config. Extend Reg */
#define ETH_EPCMR 0x0010 /* Port Command Register */
#define ETH_EPSR 0x0018 /* Port Status Register */
#define ETH_ESPR 0x0020 /* Port Serial Parameters Reg */
#define ETH_EHTPR 0x0028 /* Port Hash Table Pointer Reg*/
#define ETH_EFCSAL 0x0030 /* Flow Control Src Addr Low */
#define ETH_EFCSAH 0x0038 /* Flow Control Src Addr High */
#define ETH_ESDCR 0x0040 /* SDMA Configuration Reg */
#define ETH_ESDCMR 0x0048 /* SDMA Command Register */
#define ETH_EICR 0x0050 /* Interrupt Cause Register */
#define ETH_EIMR 0x0058 /* Interrupt Mask Register */
#define ETH_EFRDP0 0x0080 /* First Rx Desc Pointer 0 */
#define ETH_EFRDP1 0x0084 /* First Rx Desc Pointer 1 */
#define ETH_EFRDP2 0x0088 /* First Rx Desc Pointer 2 */
#define ETH_EFRDP3 0x008c /* First Rx Desc Pointer 3 */
#define ETH_ECRDP0 0x00a0 /* Current Rx Desc Pointer 0 */
#define ETH_ECRDP1 0x00a4 /* Current Rx Desc Pointer 1 */
#define ETH_ECRDP2 0x00a8 /* Current Rx Desc Pointer 2 */
#define ETH_ECRDP3 0x00ac /* Current Rx Desc Pointer 3 */
#define ETH_ECTDP0 0x00e0 /* Current Tx Desc Pointer 0 */
#define ETH_ECTDP1 0x00e4 /* Current Tx Desc Pointer 1 */
#define ETH_EDSCP2P0L 0x0060 /* IP Differentiated Services
CodePoint to Priority0 low */
#define ETH__EDSCP2P0H 0x0064 /* IP Differentiated Services
#define ETH_EDSCP2P0H 0x0064 /* IP Differentiated Services
CodePoint to Priority0 high*/
#define ETH__EDSCP2P1L 0x0068 /* IP Differentiated Services
#define ETH_EDSCP2P1L 0x0068 /* IP Differentiated Services
CodePoint to Priority1 low */
#define ETH__EDSCP2P1H 0x006c /* IP Differentiated Services
#define ETH_EDSCP2P1H 0x006c /* IP Differentiated Services
CodePoint to Priority1 high*/
#define ETH__EVPT2P 0x0068 /* VLAN Prio. Tag to Priority */
#define ETH__EMIBCTRS 0x0100 /* MIB Counters */
#define ETH_EVPT2P 0x0068 /* VLAN Prio. Tag to Priority */
#define ETH_EMIBCTRS 0x0100 /* MIB Counters */
#define ETH_BASE(n) ETH__GEN(n, EBASE)
#define ETH_EPCR(n) ETH__GEN(n, EPCR) /* Port Config. Register */
#define ETH_EPCXR(n) ETH__GEN(n, EPCXR) /* Port Config. Extend Reg */
#define ETH_EPCMR(n) ETH__GEN(n, EPCMR) /* Port Command Register */
#define ETH_EPSR(n) ETH__GEN(n, EPSR) /* Port Status Register */
#define ETH_ESPR(n) ETH__GEN(n, ESPR) /* Port Serial Parameters Reg */
#define ETH_EHTPR(n) ETH__GEN(n, EHPTR) /* Port Hash Table Pointer Reg*/
#define ETH_EFCSAL(n) ETH__GEN(n, EFCSAL) /* Flow Control Src Addr Low */
#define ETH_EFCSAH(n) ETH__GEN(n, EFCSAH) /* Flow Control Src Addr High */
#define ETH_ESDCR(n) ETH__GEN(n, ESDCR) /* SDMA Configuration Reg */
#define ETH_ESDCMR(n) ETH__GEN(n, ESDCMR) /* SDMA Command Register */
#define ETH_EICR(n) ETH__GEN(n, EICR) /* Interrupt Cause Register */
#define ETH_EIMR(n) ETH__GEN(n, EIMR) /* Interrupt Mask Register */
#define ETH_EFRDP0(n) ETH__GEN(n, EFRDP0) /* First Rx Desc Pointer 0 */
#define ETH_EFRDP1(n) ETH__GEN(n, EFRDP1) /* First Rx Desc Pointer 1 */
#define ETH_EFRDP2(n) ETH__GEN(n, EFRDP2) /* First Rx Desc Pointer 2 */
#define ETH_EFRDP3(n) ETH__GEN(n, EFRDP3) /* First Rx Desc Pointer 3 */
#define ETH_ECRDP0(n) ETH__GEN(n, ECRDP0) /* Current Rx Desc Pointer 0 */
#define ETH_ECRDP1(n) ETH__GEN(n, ECRDP1) /* Current Rx Desc Pointer 1 */
#define ETH_ECRDP2(n) ETH__GEN(n, ECRDP2) /* Current Rx Desc Pointer 2 */
#define ETH_ECRDP3(n) ETH__GEN(n, ECRDP3) /* Current Rx Desc Pointer 3 */
#define ETH_ECTDP0(n) ETH__GEN(n, ECTDP0) /* Current Tx Desc Pointer 0 */
#define ETH_ECTDP1(n) ETH__GEN(n, ECTDP1) /* Current Tx Desc Pointer 1 */
#define ETH_EDSCP2P0L(n) ETH__GEN(n, EDSCP2P0L) /* IP Differentiated Services
CodePoint to Priority0 low */
#define ETH_EDSCP2P0H(n) ETH__GEN(n, EDSCP2P0H) /* IP Differentiated Services
CodePoint to Priority0 high*/
#define ETH_EDSCP2P1L(n) ETH__GEN(n, EDSCP2P1L) /* IP Differentiated Services
CodePoint to Priority1 low */
#define ETH_EDSCP2P1H(n) ETH__GEN(n, EDSCP1P1H) /* IP Differentiated Services
CodePoint to Priority1 high*/
#define ETH_EVPT2P(n) ETH__GEN(n, EVPT2P) /* VLAN Prio. Tag to Priority */
#define ETH_EMIBCTRS(n) ETH__GEN(n, EMIBCTRS) /* MIB Counters */
#define ETH_EPAR_PhyAD_GET(v, n) (((v) >> ((n) * 5)) & 0x1f)
@ -386,6 +353,8 @@ struct gt_eth_desc {
#define ETH_EPCXR_FLP ETH__BIT(11)
#define ETH_EPCXR_FCTL ETH__BIT(12)
#define ETH_EPCXR_MFL_GET(v) ETH__EXT(v, 14, 2)
#define ETH_EPCXR_MFL_SET(v) ((v) << 14)
#define ETH_EPCXR_MFL_MASK 0x3
#define ETH_EPCXR_MFL_1518 0
#define ETH_EPCXR_MFL_1536 1
#define ETH_EPCXR_MFL_2084 2

View File

@ -1,273 +0,0 @@
/* $NetBSD: gti2c.c,v 1.12 2009/05/12 14:30:25 cegger Exp $ */
/*
* Copyright (c) 2005 Brocade Communcations, inc.
* All rights reserved.
*
* Written by Matt Thomas for Brocade Communcations, Inc.
*
* 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.
* 3. The name of Brocade Communications, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY BROCADE COMMUNICATIONS, INC. ``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 EITHER BROCADE COMMUNICATIONS, INC. 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gti2c.c,v 1.12 2009/05/12 14:30:25 cegger Exp $");
#include <sys/param.h>
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/proc.h>
#include <sys/mutex.h>
#include <sys/intr.h>
#include <sys/bus.h>
#include <dev/marvell/gtintrreg.h>
#include <dev/marvell/gti2creg.h>
#include <dev/marvell/gtvar.h>
#include <dev/i2c/i2cvar.h>
struct gti2c_softc {
struct device sc_dev;
struct evcnt sc_ev_intr;
struct i2c_controller sc_i2c;
struct gt_softc *sc_gt;
kmutex_t sc_lock;
};
static int gt_i2c_match(device_t, cfdata_t, void *);
static void gt_i2c_attach(device_t, device_t, void *);
CFATTACH_DECL(gtiic, sizeof(struct gti2c_softc),
gt_i2c_match, gt_i2c_attach, NULL, NULL);
extern struct cfdriver gtiic_cd;
static int
gt_i2c_wait(struct gti2c_softc *sc, uint32_t control,
uint32_t desired_status, int flags)
{
uint32_t status;
int error = 0;
again:
if (flags & I2C_F_POLL)
control |= I2C_Control_IntEn;
if (desired_status != I2C_Status_MasterReadAck)
gt_write(sc->sc_gt, I2C_REG_Control, control);
for (;;) {
control = gt_read(sc->sc_gt, I2C_REG_Control);
if (control & I2C_Control_IFlg)
break;
error = tsleep(sc, PZERO, "gti2cwait",
(flags & I2C_F_POLL) ? 1 : 0);
if (error && (error != ETIMEDOUT || !(flags & I2C_F_POLL)))
return error;
}
status = gt_read(sc->sc_gt, I2C_REG_Status);
if (status != desired_status)
return EIO;
if ((flags & I2C_F_LAST) &&
desired_status != I2C_Status_MasterReadAck) {
control = I2C_Control_Stop;
goto again;
}
return error;
}
static int
gt_i2c_acquire_bus(void *cookie, int flags)
{
struct gti2c_softc * const sc = cookie;
uint32_t status;
if (flags & I2C_F_POLL)
return 0;
mutex_enter(&sc->sc_lock);
status = gt_read(sc->sc_gt, I2C_REG_Status);
if (status != I2C_Status_Idle) {
gt_write(sc->sc_gt, I2C_REG_SoftReset, 1);
}
return 0;
}
static void
gt_i2c_release_bus(void *cookie, int flags)
{
struct gti2c_softc * const sc = cookie;
mutex_exit(&sc->sc_lock);
}
static int
gt_i2c_send_start(void *cookie, int flags)
{
struct gti2c_softc * const sc = cookie;
return gt_i2c_wait(sc, I2C_Control_Start, I2C_Status_Started, flags);
}
static int
gt_i2c_send_stop(void *cookie, int flags)
{
struct gti2c_softc * const sc = cookie;
return gt_i2c_wait(sc, I2C_Control_Stop, I2C_Status_Idle, flags);
}
static int
gt_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
{
struct gti2c_softc * const sc = cookie;
uint32_t data, wanted_status;
uint8_t read_mask = (flags & I2C_F_READ) != 0;
int error;
if (read_mask) {
wanted_status = I2C_Status_AddrReadAck;
} else {
wanted_status = I2C_Status_AddrWriteAck;
}
/*
* First byte contains whether this xfer is a read or write.
*/
data = read_mask;
if (addr > 0x7f) {
/*
* If this is a 10bit request, the first address byte is
* 0b11110<b9><b8><r/w>.
*/
data |= 0xf0 | ((addr & 0x30) >> 7);
gt_write(sc->sc_gt, I2C_REG_Data, data);
error = gt_i2c_wait(sc, 0, wanted_status, flags);
if (error)
return error;
/*
* The first address byte has been sent, now to send
* the second one.
*/
if (read_mask) {
wanted_status = I2C_Status_2ndAddrReadAck;
} else {
wanted_status = I2C_Status_2ndAddrWriteAck;
}
data = (uint8_t) addr;
} else {
data |= (addr << 1);
}
gt_write(sc->sc_gt, I2C_REG_Data, data);
return gt_i2c_wait(sc, 0, wanted_status, flags);
}
static int
gt_i2c_read_byte(void *cookie, uint8_t *dp, int flags)
{
struct gti2c_softc * const sc = cookie;
int error;
gt_write(sc->sc_gt, I2C_REG_Data, *dp);
error = gt_i2c_wait(sc, 0, I2C_Status_MasterReadAck, flags);
if (error == 0) {
*dp = gt_read(sc->sc_gt, I2C_REG_Data);
}
if (flags & I2C_F_LAST)
gt_write(sc->sc_gt, I2C_REG_Control, 0);
return error;
}
static int
gt_i2c_write_byte(void *cookie, uint8_t v, int flags)
{
struct gti2c_softc * const sc = cookie;
gt_write(sc->sc_gt, I2C_REG_Data, v);
return gt_i2c_wait(sc, 0, I2C_Status_MasterWriteAck, flags);
}
static int
gt_i2c_intr(void *aux)
{
struct gti2c_softc * const sc = aux;
uint32_t v;
v = gt_read(sc->sc_gt, I2C_REG_Control);
if ((v & I2C_Control_IFlg) == 0)
return 0;
gt_write(sc->sc_gt, I2C_REG_Control, v & ~I2C_Control_IntEn);
sc->sc_ev_intr.ev_count++;
wakeup(sc);
return 1;
}
int
gt_i2c_match(device_t parent, cfdata_t cfdata, void *aux)
{
struct gt_softc * const gt = device_private(parent);
struct gt_attach_args * const ga = aux;
return GT_I2COK(gt, ga, &gtiic_cd);
}
void
gt_i2c_attach(device_t parent, device_t self, void *aux)
{
struct gt_softc * const gt = device_private(parent);
struct gti2c_softc * const sc = device_private(self);
struct gt_attach_args * const ga = aux;
struct i2cbus_attach_args iba;
sc->sc_gt = gt;
GT_I2CFOUND(gt, ga);
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
sc->sc_i2c.ic_cookie = sc;
sc->sc_i2c.ic_acquire_bus = gt_i2c_acquire_bus;
sc->sc_i2c.ic_release_bus = gt_i2c_release_bus;
sc->sc_i2c.ic_release_bus = gt_i2c_release_bus;
sc->sc_i2c.ic_send_start = gt_i2c_send_start;
sc->sc_i2c.ic_send_stop = gt_i2c_send_stop;
sc->sc_i2c.ic_initiate_xfer = gt_i2c_initiate_xfer;
sc->sc_i2c.ic_read_byte = gt_i2c_read_byte;
sc->sc_i2c.ic_write_byte = gt_i2c_write_byte;
intr_establish(IRQ_I2C, IST_LEVEL, IPL_VM, gt_i2c_intr, sc);
evcnt_attach_dynamic(&sc->sc_ev_intr, EVCNT_TYPE_INTR, NULL,
device_xname(&sc->sc_dev), "intr");
iba.iba_tag = &sc->sc_i2c;
config_found_ia(self, "i2cbus", &iba, iicbus_print);
}

View File

@ -1,83 +0,0 @@
/* $NetBSD: gti2creg.h,v 1.4 2006/03/08 23:46:25 lukem Exp $ */
/*
* Copyright (c) 2005 Brocade Communcations, inc.
* All rights reserved.
*
* Written by Matt Thomas for Brocade Communcations, Inc.
*
* 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.
* 3. The name of Brocade Communications, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY BROCADE COMMUNICATIONS, INC. ``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 EITHER BROCADE COMMUNICATIONS, INC. 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.
*/
#ifndef _DEV_MARVELL_GTI2CREG_H_
#define _DEV_MARVELL_GTI2CREG_H_
#define I2C_REG_SlaveAddr 0xc000
#define I2C_REG_ExtSlaveAddr 0xc010
#define I2C_REG_Data 0xc004
#define I2C_REG_Control 0xc008
#define I2C_REG_Status 0xc00c
#define I2C_REG_BaudRate 0xc00c
#define I2C_REG_SoftReset 0xc01c
#define I2C_SlaveAddr_GCE 0x0001 /* Act as Slave */
#define I2C_SlaveAddr_SAddr 0x7E
#define I2C_Control_ACK 0x04
#define I2C_Control_IFlg 0x08
#define I2C_Control_Stop 0x10
#define I2C_Control_Start 0x20
#define I2C_Control_TWSIEn 0x40
#define I2C_Control_IntEn 0x80
/*
* F(I2C) = F(Tclk) / ( 10 * (M + 1) * (2^(N+1)))
* For Tclk = 100 MHz, M = 4, N = 4: F = 62.5 kHz
* For Tclk = 100 MHz, M = 13, N = 3: F = 96.2 kHz
*/
#define I2C_BaudRate(M, N) (((M) << 3) | (N))
#define I2C_BaudRate_62_5K I2C_BaudRate(4, 4)
#define I2C_BaudRate_96_2K I2C_BaudRate(13, 3)
#define I2C_Status_BusError 0x00 /* Bus error */
#define I2C_Status_Started 0x08 /* Start condition xmitted */
#define I2C_Status_ReStarted 0x10 /* Repeated start condition xmitted */
#define I2C_Status_AddrWriteAck 0x18 /* Adr + wr bit xmtd, ack rcvd */
#define I2C_Status_AddrWriteNoAck 0x20 /* Adr + wr bit xmtd, NO ack rcvd */
#define I2C_Status_MasterWriteAck 0x28 /* Master xmtd data byte, ack rcvd */
#define I2C_Status_MasterWriteNoAck 0x30 /* Master xmtd data byte, NO ack rcvd*/
#define I2C_Status_MasterLostArb 0x38 /* Master lost arbitration during
address or data transfer */
#define I2C_Status_AddrReadAck 0x40 /* Adr + rd bit xmtd, ack rcvd */
#define I2C_Status_AddrReadNoAck 0x48 /* Adr + rd bit xmtd, NO ack rcvd */
#define I2C_Status_MasterReadAck 0x50 /* Master rcvd data bye, ack rcvd */
#define I2C_Status_MasterReadNoAck 0x58 /* Master rcvd data bye, NO ack rcvd */
#define I2C_Status_2ndAddrWriteAck 0xd0 /* 2nd adr + wr bit xmid, ack rcvd */
#define I2C_Status_2ndAddrWriteNoAck 0xd8 /* 2nd adr + wr bit xmid, NO ack rcvd */
#define I2C_Status_2ndAddrReadAck 0xe0 /* 2nd adr + rd bit xmid, ack rcvd */
#define I2C_Status_2ndAddrReadNoAck 0xe8 /* 2nd adr + rd bit xmtd, NO ack rcvd */
#define I2C_Status_Idle 0xf8 /* Idle */
#endif /* _DEV_MARVELL_GTI2CREG_H_ */

File diff suppressed because it is too large Load Diff

1934
sys/dev/marvell/gtidmac.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,265 @@
/* $NetBSD: gtidmacreg.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2008, 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _GTIDMACREG_H_
#define _GTIDMACREG_H_
/*
* IDMA Controller Interface Registers / XOR Engine Control Registers
*/
#define GTIDMAC_SIZE 0x1000
#define GTIDMAC_NWINDOW 8
#define GTIDMAC_NREMAP 4
#define GTIDMAC_NACCPROT 4 /* Num Access Protect */
#define GTIDMAC_NINTRRUPT 4
#define GTIDMAC_MAXXFER (16 * 1024 * 1024 - 1) /* 16M - 1 Byte */
#define MVXORE_NWINDOW 8
#define MVXORE_NREMAP 4
#define MVXORE_NINTRRUPT 2
#define MVXORE_MAXXFER (16 * 1024 * 1024 - 1) /* 16M - 1 Byte */
#define MVXORE_NSRC 8
#define GTIDMAC_CHAN2BASE(c) ((((c) & 0x4) << 6) + (((c) & 0x3) << 2))
/* IDMA Descriptor Register Map */
#define GTIDMAC_CIDMABCR(c) /* Chan IDMA Byte Count */ \
(GTIDMAC_CHAN2BASE(c) + 0x0800)
#define GTIDMAC_CIDMABCR_BYTECNT_MASK 0x00ffffff
#define GTIDMAC_CIDMABCR_BCLEFT (1 << 30) /* Left Byte Count */
#define GTIDMAC_CIDMABCR_OWN (1 << 31) /* Ownership Bit */
#define GTIDMAC_CIDMASAR(c) /* Chan IDMA Source Address */ \
(GTIDMAC_CHAN2BASE(c) + 0x0810)
#define GTIDMAC_CIDMADAR(c) /* Chan IDMA Destination Address */ \
(GTIDMAC_CHAN2BASE(c) + 0x0820)
#define GTIDMAC_CNDPR(c) /* Chan Next Descriptor Pointer */ \
(GTIDMAC_CHAN2BASE(c) + 0x0830)
#define GTIDMAC_CCDPR(c) /* Chan Current Descriptor Pointer */ \
(GTIDMAC_CHAN2BASE(c) + 0x0870)
/* IDMA Control Register Map */
#define GTIDMAC_CCLR(c) /* Chan Control Low */ \
(GTIDMAC_CHAN2BASE(c) + 0x0840)
#define GTIDMAC_CCLR_DBL_MASK (7 << 0) /* DstBurstLimit */
#define GTIDMAC_CCLR_DBL_8B (0 << 0)
#define GTIDMAC_CCLR_DBL_16B (1 << 0)
#define GTIDMAC_CCLR_DBL_32B (3 << 0)
#define GTIDMAC_CCLR_DBL_64B (7 << 0)
#define GTIDMAC_CCLR_DBL_128B (4 << 0)
#define GTIDMAC_CCLR_SRCHOLD (1 << 3) /* Source Hold */
#define GTIDMAC_CCLR_DESTHOLD (1 << 5) /* Destination Hold */
#define GTIDMAC_CCLR_SBL_MASK (7 << 6) /* SrcBurstLimit */
#define GTIDMAC_CCLR_SBL_8B (0 << 6)
#define GTIDMAC_CCLR_SBL_16B (1 << 6)
#define GTIDMAC_CCLR_SBL_32B (3 << 6)
#define GTIDMAC_CCLR_SBL_64B (7 << 6)
#define GTIDMAC_CCLR_SBL_128B (4 << 6)
#define GTIDMAC_CCLR_CHAINMODE_C (0 << 9) /* Chained Mode */
#define GTIDMAC_CCLR_CHAINMODE_NC (1 << 9) /* Non-Chained Mode */
#define GTIDMAC_CCLR_INTMODE (1 << 10) /* Interrupt Mode */
#define GTIDMAC_CCLR_INTMODE_NULL (1 << 10) /* Next Desc NULL */
#define GTIDMAC_CCLR_TRANSFERMODE_D (0 << 11) /* Transfer Mode */
#define GTIDMAC_CCLR_TRANSFERMODE_B (1 << 11) /* Demand/Block */
#define GTIDMAC_CCLR_CHANEN (1 << 12) /* Channel Enable */
#define GTIDMAC_CCLR_FETCHND (1 << 13) /* Fetch Next Desc */
#define GTIDMAC_CCLR_CHANACT (1 << 14) /* IDMA Chan Active */
#define GTIDMAC_CCLR_CDEN (1 << 17) /* Close Desc Enable */
#define GTIDMAC_CCLR_ABR (1 << 20) /* Channel Abort */
#define GTIDMAC_CCLR_SADDROVR_MASK (3 << 21) /* Override Src Addr */
#define GTIDMAC_CCLR_SADDROVR_NO (0 << 21)
#define GTIDMAC_CCLR_SADDROVR_BAR1 (1 << 21)
#define GTIDMAC_CCLR_SADDROVR_BAR2 (2 << 21)
#define GTIDMAC_CCLR_SADDROVR_BAR3 (3 << 21)
#define GTIDMAC_CCLR_NADDROVR_MASK (3 << 21) /* Override Next Addr */
#define GTIDMAC_CCLR_NADDROVR_NO (0 << 21)
#define GTIDMAC_CCLR_NADDROVR_BAR1 (1 << 21)
#define GTIDMAC_CCLR_NADDROVR_BAR2 (2 << 21)
#define GTIDMAC_CCLR_NADDROVR_BAR3 (3 << 21)
#define GTIDMAC_CCLR_DESCMODE_64K (0 << 31)
#define GTIDMAC_CCLR_DESCMODE_16M (1 << 31)
#define GTIDMAC_CCHR(c) /* Chan Control High */ \
(GTIDMAC_CHAN2BASE(c) + 0x0880)
#define GTIDMAC_CCHR_ENDIAN_BE (0 << 0) /* big endian */
#define GTIDMAC_CCHR_ENDIAN_LE (1 << 0) /* little endian */
#define GTIDMAC_CCHR_DESCBYTESWAP (1 << 1) /* Desc Byte Swap */
#define GTIDMAC_ARBR(c) (0x0860 + (((c) & 0x04) << 6)) /* Arbitrate ??*/
#define GTIDMAC_XTOR(c) (0x08d0 + (((c) & 0x04) << 6)) /* x-bar t/o?? */
/* IDMA Interrupt Register Map */
#define GTIDMAC_ICR(c) (0x08c0 + (((c) & 0x04) << 6)) /* Intr Cause */
#define GTIDMAC_IMR(c) (0x08c4 + (((c) & 0x04) << 6)) /* Intr Mask */
#define GTIDMAC_I_BITS 8
#define GTIDMAC_I(c, b) ((b) << (GTIDMAC_I_BITS * ((c) & 0x3)))
#define GTIDMAC_I_COMP (1 << 0) /* Completion */
#define GTIDMAC_I_ADDRMISS (1 << 1) /* Address Miss */
#define GTIDMAC_I_ACCPROT (1 << 2) /* Acc Prot Violation */
#define GTIDMAC_I_WRPROT (1 << 3) /* Write Protect */
#define GTIDMAC_I_OWN (1 << 4) /* Ownership Violation*/
#define GTIDMAC_EAR(c) (0x08c8 + (((c) & 0x04) << 6)) /* Err Address */
#define GTIDMAC_ESR(c) (0x08cc + (((c) & 0x04) << 6)) /* Err Select */
#define GTIDMAC_ESR_SEL 0x1f
/* XOR Engine Control Registers */
#define MVXORE_XECHAR 0x0900 /* Channel Arbiter */
#define MVXORE_XECHAR_SLICEOWN(s, c) ((c) << (s))
#define MVXORE_XEXCR(x) (0x0910 + ((x) << 2)) /* Configuration */
#define MVXORE_XEXCR_OM_MASK (7 << 0) /* Operation Mode */
#define MVXORE_XEXCR_OM_XOR (0 << 0)
#define MVXORE_XEXCR_OM_CRC32 (1 << 0)
#define MVXORE_XEXCR_OM_DMA (2 << 0)
#define MVXORE_XEXCR_OM_ECC (3 << 0) /* ECC cleanup ope */
#define MVXORE_XEXCR_OM_MEMINIT (4 << 0)
#define MVXORE_XEXCR_SBL_MASK (7 << 4) /* SrcBurstLimit */
#define MVXORE_XEXCR_SBL_32B (2 << 4)
#define MVXORE_XEXCR_SBL_64B (3 << 4)
#define MVXORE_XEXCR_SBL_128B (4 << 4)
#define MVXORE_XEXCR_DBL_MASK (7 << 8) /* SrcBurstLimit */
#define MVXORE_XEXCR_DBL_32B (2 << 8)
#define MVXORE_XEXCR_DBL_64B (3 << 8)
#define MVXORE_XEXCR_DBL_128B (4 << 8)
#define MVXORE_XEXCR_DRDRESSWP (1 << 12) /* Endianess Swap */
#define MVXORE_XEXCR_DWRREQSWP (1 << 13) /* ReadReq/WriteRes */
#define MVXORE_XEXCR_DESSWP (1 << 14) /* Desc read/write */
#define MVXORE_XEXCR_REGACCPROTECT (1 << 15) /* Reg Access protect */
#define MVXORE_XEXACTR(x) (0x0920 + ((x) << 2)) /* Activation */
#define MVXORE_XEXACTR_XESTART (1 << 0)
#define MVXORE_XEXACTR_XESTOP (1 << 1)
#define MVXORE_XEXACTR_XEPAUSE (1 << 2)
#define MVXORE_XEXACTR_XERESTART (1 << 3)
#define MVXORE_XEXACTR_XESTATUS_MASK (3 << 4)
#define MVXORE_XEXACTR_XESTATUS_NA (0 << 4) /* not active */
#define MVXORE_XEXACTR_XESTATUS_ACT (1 << 4) /* active */
#define MVXORE_XEXACTR_XESTATUS_P (2 << 4) /* paused */
/* XOR Engine Interrupt Registers */
#define MVXORE_XEICR 0x0930 /* Interrupt Cause */
#define MVXORE_XEIMR 0x0940 /* Interrupt Mask */
#define MVXORE_I_BITS 16
#define MVXORE_I(c, b) ((b) << (MVXORE_I_BITS * (c)))
#define MVXORE_I_EOD (1 << 0) /* End of Descriptor */
#define MVXORE_I_EOC (1 << 1) /* End of Chain */
#define MVXORE_I_STOPPED (1 << 2)
#define MVXORE_I_PAUSED (1 << 3)
#define MVXORE_I_ADDRDECODE (1 << 4)
#define MVXORE_I_ACCPROT (1 << 5) /* Access Protect */
#define MVXORE_I_WRPROT (1 << 6) /* Write Protect */
#define MVXORE_I_OWN (1 << 7) /* Ownership */
#define MVXORE_I_INTPARITY (1 << 8) /* Parity error */
#define MVXORE_I_XBAR (1 << 9) /* Crossbar Parity E */
#define MVXORE_XEECR 0x0950 /* Error Cause */
#define MVXORE_XEECR_ERRORTYPE_MASK 0x0000001f
#define MVXORE_XEEAR 0x0960 /* Error Address */
/* IDMA Address Decoding Registers Map */
#define GTIDMAC_BARX(r) (0x0a00 + ((r) << 3)) /* Base Address x */
#define GTIDMAC_BARX_TARGET(t) ((t) & 0xf)
#define GTIDMAC_BARX_ATTR(a) (((a) & 0xff) << 8)
#define GTIDMAC_BARX_BASE(b) ((b) & 0xffff0000)
#define GTIDMAC_SRX(r) (0x0a04 + ((r) << 3)) /* Size x */
#define GTIDMAC_SRX_SIZE(s) (((s) - 1) & 0xffff0000)
#define GTIDMAC_HARXR(x) (0x0a60 + ((x) << 2)) /* High Addr Remap x */
#define GTIDMAC_BAER 0x0a80 /* Base Addr Enable */
#define GTIDMAC_BAER_EN(w) (1 << (w))
#define GTIDMAC_CXAPR(x) (0x0a70 + ((x) << 2)) /* Chan x Acs Protect */
#define GTIDMAC_CXAPR_WINACC(w, ac) ((ac) << ((w) << 1))
#define GTIDMAC_CXAPR_WINACC_NOAA 0x0 /* No access allowed */
#define GTIDMAC_CXAPR_WINACC_RO 0x1 /* Read Only */
#define GTIDMAC_CXAPR_WINACC_RESV 0x2 /* Reserved */
#define GTIDMAC_CXAPR_WINACC_FA 0x3 /* Full access */
/* XOR Engine Descriptor Registers */
#define MVXORE_XEXNDPR(x) (0x0b00 + ((x) << 2)) /* Next Desc Pointer */
#define MVXORE_XEXCDPR(x) (0x0b10 + ((x) << 2)) /* Current Desc Ptr */
#define MVXORE_XEXBCR(x) (0x0b20 + ((x) << 2)) /* Byte Count */
/* XOR Engine Address Decording Registers */
#define MVXORE_XEXWCR(x) (0x0b40 + ((x) << 2)) /* Window Control */
#define MVXORE_XEXWCR_WINEN(w) (1 << (w))
#define MVXORE_XEXWCR_WINACC(w, ac) ((ac) << (((w) << 1) + 16))
#define MVXORE_XEXWCR_WINACC_NOAA 0x0 /* No access allowed */
#define MVXORE_XEXWCR_WINACC_RO 0x1 /* Read Only */
#define MVXORE_XEXWCR_WINACC_RESV 0x2 /* Reserved */
#define MVXORE_XEXWCR_WINACC_FA 0x3 /* Full access */
#define MVXORE_XEBARX(x) (0x0b50 + ((x) << 2)) /* Base Address */
#define MVXORE_XEBARX_TARGET(t) ((t) & 0xf)
#define MVXORE_XEBARX_ATTR(a) (((a) & 0xff) << 8)
#define MVXORE_XEBARX_BASE(b) ((b) & 0xffff0000)
#define MVXORE_XESMRX(x) (0x0b70 + ((x) << 2)) /* Size Mask */
#define MVXORE_XESMRX_SIZE(s) (((s) - 1) & 0xffff0000)
#define MVXORE_XEHARRX(x) (0x0b90 + ((x) << 2)) /* High Address Remap */
#define MVXORE_XEXAOCR(x) (0x0ba0 + ((x) << 2)) /* Addr Override Ctrl */
/* XOR Engine ECC/MemInit Registers */
#define MVXORE_XEXDPR(x) (0x0bb0 + ((x) << 2)) /* Destination Ptr */
#define MVXORE_XEXBSR(x) (0x0bc0 + ((x) << 2)) /* Block Size */
#define MVXORE_XETMCR 0x0bd0 /* Timer Mode Control */
#define MVXORE_XETMCR_TIMEREN (1 << 0)
#define MVXORE_XETMCR_SECTIONSIZECTRL_MASK 0x1f
#define MVXORE_XETMCR_SECTIONSIZECTRL_SHIFT 8
#define MVXORE_XETMIVR 0x0bd4 /* Tmr Mode Init Val */
#define MVXORE_XETMCVR 0x0bd8 /* Tmr Mode Curr Val */
#define MVXORE_XEIVRL 0x0be0 /* Initial Value Low */
#define MVXORE_XEIVRH 0x0be4 /* Initial Value High */
struct gtidmac_desc {
union {
struct {
uint16_t rbc; /* Remind BC */
uint16_t bcnt;
} mode64k;
struct {
uint32_t bcnt;
} mode16m;
} bc; /* Byte Count */
uint32_t srcaddr; /* Source Address */
uint32_t dstaddr; /* Destination Address */
uint32_t nextdp; /* Next Descriptor Pointer */
} __packed;
#define GTIDMAC_DESC_BYTECOUNT_MASK 0x00ffffff
struct mvxore_desc {
uint32_t stat; /* Status */
uint32_t result; /* CRC-32 Result */
uint32_t cmd; /* Command */
uint32_t nextda; /* Next Descriptor Address */
uint32_t bcnt; /* Byte Count */
uint32_t dstaddr; /* Destination Address */
uint32_t srcaddr[MVXORE_NSRC]; /* Source Address #0-7 */
uint32_t reserved[2];
} __packed;
#define MVXORE_DESC_STAT_SUCCESS (1 << 30)
#define MVXORE_DESC_STAT_OWN (1 << 31)
#define MVXORE_DESC_CMD_SRCCMD(s) (1 << (s))
#define MVXORE_DESC_CMD_CRCLAST (1 << 30) /* Indicate last desc CRC32 */
#define MVXORE_DESC_CMD_EODINTEN (1 << 31) /* End of Desc Intr Enable */
#define MVXORE_DESC_BCNT_MASK 0x00ffffff
#endif /* _GTIDMACREG_H_ */

View File

@ -0,0 +1,45 @@
/* $NetBSD: gtidmacvar.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2008, 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _GTIDMACVAR_H_
#define _GTIDMACVAR_H_
void *gtidmac_tag_get(void);
int gtidmac_chan_alloc(void *, bus_dmamap_t **, bus_dmamap_t **, void *);
void gtidmac_chan_free(void *, int);
int gtidmac_setup(void *, int, int, bus_dmamap_t *, bus_dmamap_t *, bus_size_t);
void gtidmac_start(void *, int,
void (*)(void *, int, bus_dmamap_t *, bus_dmamap_t *, int));
int mvxore_chan_alloc(void *, bus_dmamap_t **, bus_dmamap_t **, void *);
void mvxore_chan_free(void *, int);
int mvxore_setup(void *, int, int, bus_dmamap_t *, bus_dmamap_t *, bus_size_t);
void mvxore_start(void *, int,
void (*)(void *, int, bus_dmamap_t *, bus_dmamap_t *, int));
#endif /* _GTIDMACVAR_H_ */

View File

@ -1,283 +0,0 @@
/* $NetBSD: gtidmareg.h,v 1.6 2008/09/08 23:36:54 gmcgarry Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* 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.
*/
/*
* idmareg.h - register & descriptor definitions for GT-64260 IDMA
*
* creation Wed Aug 15 08:58:37 PDT 2001 cliff
*/
#ifndef _IDMAREG_H
#define _IDMAREG_H
#define NIDMA_CHANS 8
#define IDMA_BOUNDARY 1024*1024 /* boundary for bus_dmamap_create */
#define IDMA_BIT(bitno) (1U << (bitno))
#define IDMA_BITS(hi, lo) ((unsigned int)(~((~0ULL)<<((hi)+1)))&((~0)<<(lo)))
#define IDMA_WORD_SHIFT 2 /* log2(sizeof(u_int32_t) */
static volatile __inline unsigned int
idma_desc_read(u_int32_t *ip)
{
u_int32_t rv;
__asm volatile ("lwbrx %0,0,%1; eieio;"
: "=r"(rv) : "r"(ip));
return rv;
}
static volatile __inline void
idma_desc_write(u_int32_t *ip, u_int32_t val)
{
__asm volatile ("stwbrx %0,0,%1; eieio;"
:: "r"(val), "r"(ip));
}
typedef struct idma_desc {
u_int32_t idd_ctl;
u_int32_t idd_src_addr;
u_int32_t idd_dst_addr;
u_int32_t idd_next;
u_int32_t idd_pad[4]; /* pad to CACHELINESIZE */
} idma_desc_t __aligned(CACHELINESIZE);
#define IDMA_DESC_CTL_CNT IDMA_BITS(23,0)
#define IDMA_DESC_CTL_RES IDMA_BITS(29,24)
#define IDMA_DESC_CTL_TERM IDMA_BIT(30)
#define IDMA_DESC_CTL_OWN IDMA_BIT(31)
#define IDMA_CH0_REG_OFF 0
#define IDMA_CH4_REG_OFF 0x100
#define IDMA_REG(chan, base) \
((chan < 4) ? \
((base) + ((chan) << IDMA_WORD_SHIFT)) : \
(((base) + IDMA_CH4_REG_OFF) \
+ (((chan) - 4) << IDMA_WORD_SHIFT)))
#define IDMA_2X4_REG(chan, base) \
(((chan) < 4) ? \
(base) : \
((base) + IDMA_CH4_REG_OFF))
/*
* IDMA Descriptor Registers
*/
#define IDMA_CNT_REG_BASE 0x800
#define IDMA_CNT_REG(chan) IDMA_REG(chan, IDMA_CNT_REG_BASE)
#define IDMA_SRC_REG_BASE 0x810
#define IDMA_SRC_REG(chan) IDMA_REG(chan, IDMA_SRC_REG_BASE)
#define IDMA_DST_REG_BASE 0x820
#define IDMA_DST_REG(chan) IDMA_REG(chan, IDMA_DST_REG_BASE)
#define IDMA_NXT_REG_BASE 0x830
#define IDMA_NXT_REG(chan) IDMA_REG(chan, IDMA_NXT_REG_BASE)
#define IDMA_CUR_REG_BASE 0x870
#define IDMA_CUR_REG(chan) IDMA_REG(chan, IDMA_CUR_REG_BASE)
#define IDMA_SRC_HIPCI_REG_BASE 0x890
#define IDMA_SRC_HIPCI_REG(chan) \
IDMA_REG(chan, IDMA_SRC_HIPCI_REG_BASE)
#define IDMA_DST_HIPCI_REG_BASE 0x8a0
#define IDMA_DST_HIPCI_REG(chan) \
IDMA_REG(chan, IDMA_DST_HIPCI_REG_BASE)
#define IDMA_NXT_HIPCI_REG_BASE 0x8b0
#define IDMA_NXT_HIPCI_REG(chan) \
IDMA_REG(chan, IDMA_NXT_HIPCI_REG_BASE)
/*
* IDMA Control Registers
*/
#define IDMA_CTLLO_REG_BASE 0x840
#define IDMA_CTLLO_REG(chan) IDMA_REG(chan, IDMA_CTLLO_REG_BASE)
#define IDMA_CTLHI_REG_BASE 0x880
#define IDMA_CTLHI_REG(chan) IDMA_REG(chan, IDMA_CTLHI_REG_BASE)
#define IDMA_ARB_REG_BASE 0x860
#define IDMA_ARB_REG(chan) IDMA_2X4_REG(chan, IDMA_ARB_REG_BASE)
#define IDMA_XTO_REG_BASE 0x8d0
#define IDMA_XTO_REG(chan) IDMA_2X4_REG(chan, IDMA_XTO_REG_BASE)
#define IDMA_CAUSE_REG_BASE 0x8c0
#define IDMA_CAUSE_REG(chan) IDMA_2X4_REG(chan, IDMA_CAUSE_REG_BASE)
#define IDMA_MASK_REG_BASE 0x8c4
#define IDMA_MASK_REG(chan) IDMA_2X4_REG(chan, IDMA_MASK_REG_BASE)
#define IDMA_EADDR_REG_BASE 0x8c8
#define IDMA_EADDR_REG(chan) IDMA_2X4_REG(chan, IDMA_EADDR_REG_BASE)
#define IDMA_ESEL_REG_BASE 0x8cc
#define IDMA_ESEL_REG(chan) IDMA_2X4_REG(chan, IDMA_ESEL_REG_BASE)
/*
* IDMA Channel Control Lo bits
*/
#define IDMA_CTLLO_RESA IDMA_BITS(2,0)
#define IDMA_CTLLO_SRCHOLD IDMA_BIT(3)
#define IDMA_CTLLO_RESB IDMA_BIT(4)
#define IDMA_CTLLO_DSTHOLD IDMA_BIT(5)
#define IDMA_CTLLO_BURSTLIM IDMA_BITS(8,6)
#define IDMA_CTLLO_BURST16 IDMA_BIT(6)
#define IDMA_CTLLO_BURST32 IDMA_BITS(7,6)
#define IDMA_CTLLO_BURST64 IDMA_BITS(8,6)
#define IDMA_CTLLO_NOCHAIN IDMA_BIT(9)
#define IDMA_CTLLO_INTR IDMA_BIT(10)
#define IDMA_CTLLO_BLKMODE IDMA_BIT(11)
#define IDMA_CTLLO_ENB IDMA_BIT(12)
#define IDMA_CTLLO_FETCHND IDMA_BIT(13)
#define IDMA_CTLLO_ACTIVE IDMA_BIT(14)
#define IDMA_CTLLO_REQDIR IDMA_BIT(15)
#define IDMA_CTLLO_REQMODE IDMA_BIT(16)
#define IDMA_CTLLO_CDEN IDMA_BIT(17)
#define IDMA_CTLLO_EOTEN IDMA_BIT(18)
#define IDMA_CTLLO_EOTMODE IDMA_BIT(19)
#define IDMA_CTLLO_ABORT IDMA_BIT(20)
#define IDMA_CTLLO_SADDROVR IDMA_BITS(22,21)
#define IDMA_CTLLO_DADDROVR IDMA_BITS(24,23)
#define IDMA_CTLLO_NADDROVR IDMA_BITS(26,25)
#define IDMA_CTLLO_ACKMODE IDMA_BIT(27)
#define IDMA_CTLLO_TREQ IDMA_BIT(28)
#define IDMA_CTLLO_ACKDIR IDMA_BITS(30,29)
#define IDMA_CTLLO_DESCMODE IDMA_BIT(31)
#define IDMA_CTLLO_RES \
(IDMA_CTLHI_RESA|IDMA_CHN_CTLHI_RESB)
#define IDMA_CTLL0_BURSTCODE(sz) (((sz) == 64) ? IDMA_CTLLO_BURST64 \
: (((sz) == 32) ? IDMA_CTLLO_BURST32 \
: (((sz) == 16) ? IDMA_CTLLO_BURST16 \
: ~0)))
/*
* IDMA Channel Control Hi bits
*/
#define IDMA_CTLHI_RESA IDMA_BITS(3,0)
#define IDMA_CTLHI_SRCPCISWAP IDMA_BITS(5,4)
#define IDMA_CTLHI_SRCPCISWAP_NONE IDMA_BIT(4)
#define IDMA_CTLHI_SRCSNOOP IDMA_BIT(6)
#define IDMA_CTLHI_SRCPCI64 IDMA_BIT(7)
#define IDMA_CTLHI_RESB IDMA_BITS(11,8)
#define IDMA_CTLHI_DSTPCISWAP IDMA_BITS(13,12)
#define IDMA_CTLHI_DSTPCISWAP_NONE IDMA_BIT(12)
#define IDMA_CTLHI_DSTSNOOP IDMA_BIT(14)
#define IDMA_CTLHI_DSTPCI64 IDMA_BIT(15)
#define IDMA_CTLHI_RESC IDMA_BITS(19,16)
#define IDMA_CTLHI_NXTPCISWAP IDMA_BITS(21,20)
#define IDMA_CTLHI_NXTPCISWAP_NONE IDMA_BIT(20)
#define IDMA_CTLHI_NXTSNOOP IDMA_BIT(22)
#define IDMA_CTLHI_NXTPCI64 IDMA_BIT(23)
#define IDMA_CTLHI_RESD IDMA_BITS(31,24)
#define IDMA_CTLHI_RES \
(IDMA_CTLHI_RESA|IDMA_CHN_CTLHI_RESB \
|IDMA_CTLHI_RESC|IDMA_CHN_CTLHI_RESD)
/*
* IDMA Channel Arbiter Control bits
*/
#define IDMA_ARB_ARB_SHIFT 2
#define IDMA_ARB_ARB_MASK(arb) \
(BITS(1,0) << ((arb) << IDMA_ARB_ARB_SHIFT))
/*
* common IDMA Interrupt Register bits
*/
#define IDMA_INTR_COMP IDMA_BIT(0) /* completion */
#define IDMA_INTR_MISS IDMA_BIT(1) /* failed addr decode */
#define IDMA_INTR_ACCESS IDMA_BIT(2) /* access violation */
#define IDMA_INTR_WPROT IDMA_BIT(3) /* write protect */
#define IDMA_INTR_OWN IDMA_BIT(4) /* desc owner violation */
#define IDMA_INTR_EOT IDMA_BIT(5) /* end of xfer */
#define IDMA_INTR_RESX IDMA_BITS(7,6)
#define IDMA_INTR_SHIFT 8
#define IDMA_MASK_BITS IDMA_BITS(7,0)
#define IDMA_INTR_BITS IDMA_BITS(5,0)
#define IDMA_INTR_ERRS IDMA_BITS(5,1)
#define IDMA_INTR_ALL_ERRS (IDMA_INTR_ERRS \
|(IDMA_INTR_ERRS << IDMA_INTR_SHIFT) \
|(IDMA_INTR_ERRS << (IDMA_INTR_SHIFT*2)) \
|(IDMA_INTR_ERRS << (IDMA_INTR_SHIFT*3)))
/*
* IDMA Interrupt Cause Register bits
*/
#define IDMA_CAUSE_RES ( IDMA_INTR_RESX \
|(IDMA_INTR_RESX << IDMA_INTR_SHIFT) \
|(IDMA_INTR_RESX << (IDMA_INTR_SHIFT * 2)) \
|(IDMA_INTR_RESX << (IDMA_INTR_SHIFT * 3)))
/*
* IDMA Interrupt Mask Register bits
*/
#define IDMA_MASK_SHIFT(chan) \
(IDMA_INTR_SHIFT * ((chan < 4) ? chan : (chan - 4)))
#define IDMA_MASK(chan, mask) \
(((mask) & IDMA_MASK_BITS) << IDMA_MASK_SHIFT(chan))
#define IDMA_MASK_RES (IDMA_MASK_RESX(0) \
|IDMA_MASK_RESX(1) \
|IDMA_MASK_RESX(2) \
|IDMA_MASK_RESX(3))
/*
* IDMA Error Select Register bits
*/
#define IDMA_ESEL_MASK IDMA_BITS(4,0)
#define IDMA_ESEL_RES IDMA_BITS(31,5)
/*
* IDMA Debug Registers
*/
#define IDMA_DBG_XADDR_REG_BASE 0x8e0
#define IDMA_DBG_XADDR(xno) IDMA_2X4_REG(xno, IDMA_DBG_XADDR_REG_BASE)
#define IDMA_DBG_XCMD_REG_BASE 0x8e4
#define IDMA_DBG_XCMD(xno) IDMA_2X4_REG(xno, IDMA_DBG_XCMD_REG_BASE)
#define IDMA_DBG_WDATLO_REG_BASE 0x8e8
#define IDMA_DBG_WDATLO(xno) IDMA_2X4_REG(xno, IDMA_DBG_WDATLO_REG_BASE)
#define IDMA_DBG_WDATHI_REG_BASE 0x8ec
#define IDMA_DBG_WDATHI(xno) IDMA_2X4_REG(xno, IDMA_DBG_WDATHI_REG_BASE)
#define IDMA_DBG_RDATLO_REG_BASE 0x8f0
#define IDMA_DBG_RDATLO(xno) IDMA_2X4_REG(xno, IDMA_DBG_RDATLO_REG_BASE)
#define IDMA_DBG_RDATHI_REG_BASE 0x8f4
#define IDMA_DBG_RDATHI(xno) IDMA_2X4_REG(xno, IDMA_DBG_RDATHI_REG_BASE)
#define IDMA_DBG_RID_REG_BASE 0x8fc
#define IDMA_DBG_RID(xno) IDMA_2X4_REG(xno, IDMA_DBG_RID_REG_BASE)
#endif /* _IDMAREG_H */

View File

@ -1,213 +0,0 @@
/* $NetBSD: gtidmavar.h,v 1.5 2007/03/04 06:02:14 christos Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* 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.
*/
/*
* idmavar.h -- defines for GT-64260 IDMA driver
*
* creation Wed Aug 15 00:48:10 PDT 2001 cliff
*/
#ifndef _IDMAVAR_H
#define _IDMAVAR_H
/*
* IDMA Overview:
*
* A driver allocates an IDMA channel, registering for callbacks.
* The channel includes descriptors and a pending queue
*
* The driver allocates & details descriptors, then requests start
*
* ... time passes ...
*
* On completion the callback is made, passing the opaque "arg"
* (e.g. a softc), a descriptor handle, and completion status
* The driver callback completes the transaction and frees
* or recycles the descriptor.
*
* If the channel is no longer needed the driver may free it,
* but we expect drivers to hold channels long term
* (i.e till shutdown).
*
* Descriptors:
*
* Hardware descriptors are coupled 1:1 with descriptor handles.
* The descriptors themselves are as defined by GT-64260 spec;
* descriptor handles control descriptor use. They are separate
* to allow efficient packing of descriptors in DMA mapped memory.
*/
/*
* NOTE:
* interrupt priority IPL_IDMA is determined by worst case client driver
* since each IDMA IRQ is shared across 4 channels
* so adjust as needed
*/
#define IPL_IDMA IPL_NET
#define splidma() splraise(IPL_IDMA)
#define IDMA_DMSEG_MAX 1
typedef struct idma_dmamem {
bus_dmamap_t idm_map; /* dmamem'ed memory */
void *idm_kva; /* kva of dmamem memory */
int idm_nsegs; /* # of segment in idm_segs */
int idm_maxsegs; /* maximum # of segments allowed */
size_t idm_size; /* size of memory region */
bus_dma_segment_t idm_segs[IDMA_DMSEG_MAX];
} idma_dmamem_t;
/*
* descriptor handle
*/
typedef enum {
IDH_FREE,
IDH_ALLOC,
IDH_QWAIT,
IDH_PENDING,
IDH_RETRY,
IDH_DONE,
IDH_CANCEL,
IDH_ABORT
} idma_desch_state_t;
typedef enum {
IDS_OK,
IDS_FAIL
} idma_sts_t;
struct idma_chan;
typedef struct idma_desch {
idma_desch_state_t idh_state;
struct idma_desch *idh_next;
struct idma_chan *idh_chan;
u_int32_t idh_hold;
SIMPLEQ_ENTRY(idma_desch) idh_q;
struct idma_desc *idh_desc_va;
struct idma_desc *idh_desc_pa;
void *idh_aux;
u_int64_t tb;
} idma_desch_t;
/*
* descriptor handle queue head
*/
typedef unsigned int idma_chan_state_t;
#define IDC_FREE 0
#define IDC_ALLOC 1
#define IDC_IDLE 2
#define IDC_STOPPED 4
#define IDC_QFULL 8
typedef struct idma_q {
unsigned int idq_depth;
SIMPLEQ_HEAD(, idma_desch) idq_q;
} idma_q_t;
/*
* IDMA channel control
*/
struct idma_softc;
typedef struct idma_chan {
idma_chan_state_t idc_state;
struct idma_softc *idc_sc;
unsigned int idc_chan; /* channel number */
int (*idc_callback)(void *, struct idma_desch *, u_int32_t);
/* completion callback */
void *idc_arg; /* completion callback arg */
idma_q_t idc_q; /* pending transactions */
unsigned int idc_ndesch; /* # descriptor handles */
idma_desch_t *idc_active; /* active transaction */
idma_desch_t *idc_desch_free; /* allocation ptr */
idma_desch_t *idc_desch_done; /* completion ptr */
idma_desch_t *idc_desch; /* descriptor handles */
idma_dmamem_t idc_desc_mem; /* descriptor dmamem */
unsigned long idc_done_count; /* running done count */
unsigned long idc_abort_count; /* running abort count */
} idma_chan_t;
/*
* IDMA driver softc
*/
typedef unsigned int idma_state_t;
#define IDMA_ATTACHED 1
typedef struct idma_softc {
struct device idma_dev;
struct gt_softc *idma_gt;
bus_space_tag_t idma_bustag;
bus_dma_tag_t idma_dmatag;
bus_space_handle_t idma_bushandle;
bus_addr_t idma_reg_base;
bus_size_t idma_reg_size;
u_int32_t idma_ien;
struct callout idma_callout;
unsigned int idma_callout_state;
unsigned int idma_burst_size;
idma_state_t idma_state;
idma_chan_t idma_chan[NIDMA_CHANS];
void *idma_ih[4];
} idma_softc_t;
/*
* IDMA external function prototypes
*/
extern void idma_chan_free(idma_chan_t *);
extern idma_chan_t *idma_chan_alloc(unsigned int,
int (*)(void *, struct idma_desch *, u_int32_t), void *);
extern void idma_desch_free(idma_desch_t *);
extern idma_desch_t *idma_desch_alloc(idma_chan_t *);
extern void idma_desch_list_free(idma_desch_t *);
extern void idma_desc_list_free(idma_desch_t *);
extern idma_desch_t *idma_desch_list_alloc(idma_chan_t *, unsigned int);
extern void idma_intr_enb(idma_chan_t *);
extern void idma_intr_dis(idma_chan_t *);
extern int idma_start(idma_desch_t *);
extern void idma_qflush(idma_chan_t *);
extern void idma_abort(idma_desch_t *, unsigned int, const char *);
/*
* flags for idma_abort()
*/
#define IDMA_ABORT_CANCEL 1 /* don't atempt completion or retry */
#endif /* _IDMAVAR_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: gtintrreg.h,v 1.4 2005/12/11 12:22:16 christos Exp $ */
/* $NetBSD: gtintrreg.h,v 1.5 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -57,8 +57,6 @@
#ifndef _DISCOVERY_GT64260INTR_H
#define _DISCOVERY_GT64260INTR_H
#define BIT(n) (1<<(n))
/*
* GT-64260 Interrupt Controller Register Map
@ -79,51 +77,6 @@
#define ICR_CI2M 0xe68 /* CPU int[2] mask */
#define ICR_CI3M 0xe6c /* CPU int[3] mask */
/*
* IRQs:
* we define IRQs based on bit number in the
* ICU_LEN dimensioned hardware portion of the imask_t bit vector
* which consists of 64 bits of Main Cause and Mask register pairs
* (ICR_MIC_LO, ICR_MIC_HI and ICR_CIM_LO, ICR_CIM_HI)
* as well as 32 bits in GPP registers (see intr.h):
*
* IRQs:
* 31.............................0 63.............................32
* | | |
* imask_t index: | | |
* | | | |
* ^--------- IM_PIC_LO ----------^ ^------ IM_PIC_HI ------------^
* | | |
* Bitmasks: | | |
* | | | |
* ^--------- IML_* --------------^ ^------ IMH_* ----------------^
* | | |
* Registers: | | |
* | | | |
* ^--------- ICR_MIC_LO ---------^ ^------ ICR_MIC_HI -----------^
* ^--------- ICR_CIM_LO ---------^ ^------ ICR_CIM_HI -----------^
*
* IRQs:
* 95............................64 127............................96
* | | |
* imask_t index: | | |
* | | | |
* ^-------- IMASK_GPP ----------^ ^----- IMASK_SOFTINT --------^
* | | |
* Bitmasks: | | |
* | | | |
* ^--------- GPP_* --------------^ ^------ SIBIT(irq) -----------^
* | | |
* Registers: | | |
* | | | |
* ^--- GT_GPP_Interrupt_Cause ---^ ^------- (none) -----------^
* ^--- GT_GPP_Interrupt_Mask ---^
*
*
* Note that GPP interrupts are summarized in the Main Cause Register.
*
* Some IRQs are "resvered" undefined due to gaps in HW register utilization.
*/
#define IRQ_DEV 1 /* device interface interrupt */
#define IRQ_DMA 2 /* DMA addres error interrupt */
#define IRQ_CPU 3 /* CPU interface interrupt */
@ -152,87 +105,18 @@
#define IRQ_PCI0IN_HI 27 /* PCI 0 inbound interrupt summary */
#define IRQ_PCI1IN_LO 28 /* PCI 1 inbound interrupt summary */
#define IRQ_PCI1IN_HI 29 /* PCI 1 inbound interrupt summary */
#define IRQ_ETH0 (32+0) /* Ethernet controller 0 interrupt */
#define IRQ_ETH1 (32+1) /* Ethernet controller 1 interrupt */
#define IRQ_ETH2 (32+2) /* Ethernet controller 2 interrupt */
#define IRQ_SDMA (32+4) /* SDMA interrupt */
#define IRQ_I2C (32+5) /* I2C interrupt */
#define IRQ_BRG (32+7) /* Baud Rate Generator interrupt */
#define IRQ_MPSC0 (32+8) /* MPSC 0 interrupt */
#define IRQ_MPSC1 (32+10) /* MPSC 1 interrupt */
#define IRQ_COMM (32+11) /* Comm unit interrupt */
#define IRQ_GPP7_0 (32+24) /* GPP[7..0] interrupt */
#define IRQ_GPP15_8 (32+25) /* GPP[15..8] interrupt */
#define IRQ_GPP23_16 (32+26) /* GPP[23..16] interrupt */
#define IRQ_GPP31_24 (32+27) /* GPP[31..24] interrupt */
/*
* low word interrupt mask register bits
*/
#define IML_SUM BIT(0)
#define IML_DEV BIT(IRQ_DEV)
#define IML_DMA BIT(IRQ_DMA)
#define IML_CPU BIT(IRQ_CPU)
#define IML_IDMA0_1 BIT(IRQ_IDMA0_1)
#define IML_IDMA2_3 BIT(IRQ_IDMA2_3)
#define IML_IDMA4_5 BIT(IRQ_IDMA4_5)
#define IML_IDMA6_7 BIT(IRQ_IDMA6_7)
#define IML_TIME0_1 BIT(IRQ_TIME0_1)
#define IML_TIME2_3 BIT(IRQ_TIME2_3)
#define IML_TIME4_5 BIT(IRQ_TIME4_5)
#define IML_TIME6_7 BIT(IRQ_TIME6_7)
#define IML_PCI0_0 BIT(IRQ_PCI0_0)
#define IML_PCI0_1 BIT(IRQ_PCI0_1)
#define IML_PCI0_2 BIT(IRQ_PCI0_2)
#define IML_PCI0_3 BIT(IRQ_PCI0_3)
#define IML_PCI1_0 BIT(IRQ_PCI1_0)
#define IML_ECC BIT(IRQ_ECC)
#define IML_PCI1_1 BIT(IRQ_PCI1_1)
#define IML_PCI1_2 BIT(IRQ_PCI1_2)
#define IML_PCI1_3 BIT(IRQ_PCI1_3)
#define IML_PCI0OUT_LO BIT(IRQ_PCI0OUT_LO)
#define IML_PCI0OUT_HI BIT(IRQ_PCI0OUT_HI)
#define IML_PCI1OUT_LO BIT(IRQ_PCI1OUT_LO)
#define IML_PCI1OUT_HI BIT(IRQ_PCI1OUT_HI)
#define IML_PCI0IN_LO BIT(IRQ_PCI0IN_LO)
#define IML_PCI0IN_HI BIT(IRQ_PCI0IN_HI)
#define IML_PCI1IN_LO BIT(IRQ_PCI1IN_LO)
#define IML_PCI1IN_HI BIT(IRQ_PCI1IN_HI)
#define IML_RES (BIT(25)|BIT(30)|BIT(31))
/*
* high word interrupt mask register bits
*/
#define IMH_ETH0 BIT(IRQ_ETH0-32)
#define IMH_ETH1 BIT(IRQ_ETH1-32)
#define IMH_ETH2 BIT(IRQ_ETH2-32)
#define IMH_SDMA BIT(IRQ_SDMA-32)
#define IMH_I2C BIT(IRQ_I2C-32)
#define IMH_BRG BIT(IRQ_BRG-32)
#define IMH_MPSC0 BIT(IRQ_MPSC0-32)
#define IMH_MPSC1 BIT(IRQ_MPSC1-32)
#define IMH_COMM BIT(IRQ_COMM-32)
#define IMH_GPP7_0 BIT(IRQ_GPP7_0-32)
#define IMH_GPP15_8 BIT(IRQ_GPP15_8-32)
#define IMH_GPP23_16 BIT(IRQ_GPP23_16-32)
#define IMH_GPP31_24 BIT(IRQ_GPP31_24-32)
#define IMH_GPP_SUM (IMH_GPP7_0|IMH_GPP15_8|IMH_GPP23_16|IMH_GPP31_24)
#define IMH_RES (BIT(3) |BIT(6) |BIT(9) |BIT(12)|BIT(13)|BIT(14) \
|BIT(15)|BIT(16)|BIT(17)|BIT(18)|BIT(19)|BIT(20) \
|BIT(21)|BIT(22)|BIT(23)|BIT(28)|BIT(29)|BIT(30) \
|BIT(31))
/*
* ICR_CSC "Select Cause" register bits
*/
#define CSC_SEL BIT(30) /* HI/LO select */
#define CSC_STAT BIT(31) /* ? "irq active" : "irq none" */
#define CSC_CAUSE ~(CSC_SEL|CSC_STAT)
/*
* CPU Int[n] Mask bit(s)
*/
#define CPUINT_SEL 0x80000000 /* HI/LO select */
#define IRQ_ETH0 32 /* Ethernet controller 0 interrupt */
#define IRQ_ETH1 33 /* Ethernet controller 1 interrupt */
#define IRQ_ETH2 34 /* Ethernet controller 2 interrupt */
#define IRQ_SDMA 36 /* SDMA interrupt */
#define IRQ_I2C 37 /* I2C interrupt */
#define IRQ_BRG 39 /* Baud Rate Generator interrupt */
#define IRQ_MPSC0 40 /* MPSC 0 interrupt */
#define IRQ_MPSC1 42 /* MPSC 1 interrupt */
#define IRQ_COMM 43 /* Comm unit interrupt */
#define IRQ_GPP7_0 56 /* GPP[7..0] interrupt */
#define IRQ_GPP15_8 57 /* GPP[15..8] interrupt */
#define IRQ_GPP23_16 58 /* GPP[23..16] interrupt */
#define IRQ_GPP31_24 59 /* GPP[31..24] interrupt */
#endif /* _DISCOVERY_GT64260INTR_H */

128
sys/dev/marvell/gtintrvar.h Normal file
View File

@ -0,0 +1,128 @@
/* $NetBSD: gtintrvar.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _MARVELL_GTINTRVAR_H_
#define _MARVELL_GTINTRVAR_H_
#include <dev/marvell/gtreg.h>
/*
* Main Interrupt related functions
*/
static __inline uint32_t
discovery_enable_intr(struct gt_softc *sc, int irq)
{
bus_size_t reg;
uint32_t cim;
reg = (irq < 32) ? ICR_CIM_LO : ICR_CIM_HI;
cim = bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg);
cim |= 1 << (irq & 31);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, cim);
return cim;
}
static __inline uint32_t
discovery_disable_intr(struct gt_softc *sc, int irq)
{
bus_size_t reg;
uint32_t cim;
reg = (irq < 32) ? ICR_CIM_LO : ICR_CIM_HI;
cim = bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg);
cim &= ~(1 << (irq & 31));
bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, cim);
return cim;
}
static __inline int
discovery_mic_low(struct gt_softc *sc)
{
return bus_space_read_4(sc->sc_iot, sc->sc_ioh, ICR_MIC_LO);
}
static __inline int
discovery_mic_high(struct gt_softc *sc)
{
return bus_space_read_4(sc->sc_iot, sc->sc_ioh, ICR_MIC_HI);
}
/*
* GPP Interrupt related functions
*/
static __inline uint32_t
discovery_gpp_enable_intr(struct gt_softc *sc, int pin)
{
uint32_t gppim;
gppim = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Mask);
gppim |= 1 << pin;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Mask, gppim);
return gppim;
}
static __inline uint32_t
discovery_gpp_disable_intr(struct gt_softc *sc, int pin)
{
uint32_t gppim;
gppim = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Mask);
gppim &= ~(1 << pin);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Mask, gppim);
return gppim;
}
static __inline void
discovery_gpp_clear_cause(struct gt_softc *sc, int pin)
{
uint32_t gppic;
gppic =
bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Cause);
gppic &= ~(1 << pin);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Cause,
gppic);
}
static __inline int
discovery_gpp_cause(struct gt_softc *sc)
{
return bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Cause);
}
static __inline int
discovery_gpp_mask(struct gt_softc *sc)
{
return bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Mask);
}
#endif /* _MARVELL_GTINTRVAR_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: gtmpscreg.h,v 1.3 2005/12/11 12:22:16 christos Exp $ */
/* $NetBSD: gtmpscreg.h,v 1.4 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -47,36 +47,32 @@
#define _GTMPSCREG_H
#ifndef BIT
#define BIT(bitno) (1U << (bitno))
#define BIT(bitno) (1U << (bitno))
#endif
#ifndef BITS
#define BITS(hi, lo) ((~((~0) << ((hi) + 1))) & ((~0) << (lo)))
#define BITS(hi, lo) ((~((~0) << ((hi) + 1))) & ((~0) << (lo)))
#endif
#define GTMPSC_NCHAN 2 /* Number of MPSC channels */
#define GTMPSC_BASE(u) (MPSC0_BASE + ((u) << 12))
#define GTMPSC_SIZE 0x1000
#define GTMPSC_NCHAN 2 /* Number of MPSC channels */
/*******************************************************************************
*
* MPSC register address offsets relative to the base mapping
*/
#define GTMPSC_MMCR_LO 0x000 /* MPSC Main Config Register Low */
#define GTMPSC_MMCR_HI 0x004 /* MPSC Main Config Register High */
#define GTMPSC_MPCR 0x008 /* MPSC Protocol Config Register */
#define GTMPSC_CHR_BASE 0x008 /* MPSC Channel Register Base */
#define GTMPSC_CHRN(n) (GTMPSC_CHR_BASE + ((n) << 2))
#define GTMPSC_NCHR 11 /* CHR 1-11? */
#define GTMPSC_MRR 0xb400 /* MPSC Routing Register */
#define GTMPSC_RCRR 0xb404 /* MPSC RX Clock Routing Register */
#define GTMPSC_TCRR 0xb408 /* MPSC TX Clock Routing Register */
#define GTMPSC_MMCR0_LO 0x8000 /* MPSC0 Main Config Register Lo */
#define GTMPSC_MMCR0_HI 0x8004 /* MPSC0 Main Config Register Hi */
#define GTMPSC_MPCR0 0x8008 /* MPSC0 Protocol Config Register */
#define GTMPSC_CH0_BASE 0x8008 /* MPSC0 Channel Register base */
#define GTMPSC_CHR0(n) (MPSC_CH0_BASE + ((n) << 2))
#define GTMPSC_MMCR1_LO 0x9000 /* MPSC1 Main Config Register Lo */
#define GTMPSC_MMCR1_HI 0x9004 /* MPSC1 Main Config Register Hi */
#define GTMPSC_MPCR1 0x9008 /* MPSC1 Protocol Config Register */
#define GTMPSC_CH1R_BASE 0x9008 /* MPSC1 Channel Register base */
#define GTMPSC_CHR1(n) (GTMPSC_CH1_BASE + ((n) << 2))
#define GTMPSC_U_MMCR_LO(u) (GTMPSC_MMCR0_LO + (((u) & 1) << 12))
#define GTMPSC_U_MMCR_HI(u) (GTMPSC_MMCR0_HI + (((u) & 1) << 12))
#define GTMPSC_U_MPCR(u) (GTMPSC_MPCR0 + (((u) & 1) << 12))
#define GTMPSC_U_CHRN(u, n) (GTMPSC_CH0_BASE + (((u) & 1) << 12) + ((n) << 2))
/*******************************************************************************
*
@ -107,11 +103,10 @@
#define GTMPSC_CRR_SCLK0 0x8 /* SCLK0 */
#define GTMPSC_TCRR_TSCLK0 0x9 /* TSCLK0 (for TCRR only) */
/* all other values resvd. */
#define GTMPSC_CRR0_SHIFT 0
#define GTMPSC_CRR0_MASK BITS(3,0) /* MPSC0 Clock Routing */
#define GTMPSC_CRR(u, v) ((v) << GTMPSC_CRR_SHIFT(u))
#define GTMPSC_CRR_SHIFT(u) ((u) * 8)
#define GTMPSC_CRR_MASK 0xf
#define GTMPSC_CRR_RESa BITS(7,4)
#define GTMPSC_CRR1_SHIFT 8
#define GTMPSC_CRR1_MASK BITS(11,8) /* MPSC1 Clock Routing */
#define GTMPSC_CRR_RESb BITS(31,12)
#define GTMPSC_CRR_RES (GTMPSC_CRR_RESa|GTMPSC_CRR_RESb)
/*
@ -184,11 +179,11 @@
#define GTMPSC_MMCR_HI_RSYL_4BIT (1 << 23) /* 4-bit sync */
#define GTMPSC_MMCR_HI_RSYL_8BIT (2 << 23) /* 8-bit sync */
#define GTMPSC_MMCR_HI_RSYL_16BIT (3 << 23) /* 16-bit sync */
#define GTMPSC_MMCR_HI_RCDV_MASK BITS(26,25) /* Receive Clock Divider */
#define GTMPSC_MMCR_HI_RCDV_1X (0 << 25) /* 1x clock mode (default) */
#define GTMPSC_MMCR_HI_RCDV_8X (1 << 25) /* 8x clock mode (default) */
#define GTMPSC_MMCR_HI_RCDV_16X (2 << 25) /* 16x clock mode (default) */
#define GTMPSC_MMCR_HI_RCDV_32X (3 << 25) /* 16x clock mode (default) */
#define GTMPSC_MMCR_HI_RCDV_MASK BITS(26,25) /* Receive Clock Divider */
#define GTMPSC_MMCR_HI_RCDV_1X (0 << 25) /* 1x clock mode (default) */
#define GTMPSC_MMCR_HI_RCDV_8X (1 << 25) /* 8x clock mode (default) */
#define GTMPSC_MMCR_HI_RCDV_16X (2 << 25) /* 16x clock mode (default) */
#define GTMPSC_MMCR_HI_RCDV_32X (3 << 25) /* 16x clock mode (default) */
#define GTMPSC_MMCR_HI_RENC_MASK BITS(29,27) /* Receive Encoder */
#define GTMPSC_MMCR_HI_RENC_NRZ (0 << 27) /* NRZ (default) */
#define GTMPSC_MMCR_HI_RENC_NRZI (1 << 27) /* NRZI */
@ -265,8 +260,8 @@
#define GTMPSC_MPCR_CL_6 (1 << 12) /* 6 data bits */
#define GTMPSC_MPCR_CL_7 (2 << 12) /* 7 data bits */
#define GTMPSC_MPCR_CL_8 (3 << 12) /* 8 data bits */
#define GTMPSC_MPCR_SBL_1 0x0 /* 1 stop bit */
#define GTMPSC_MPCR_SBL_2 BIT(14) /* 2 stop bits */
#define GTMPSC_MPCR_SBL_1 (0 << 14) /* 1 stop bit */
#define GTMPSC_MPCR_SBL_2 (1 << 14) /* 2 stop bits */
#define GTMPSC_MPCR_FLC_NORM 0x0 /* Normal Flow Ctl mode */
#define GTMPSC_MPCR_FLC_ASYNC BIT(15) /* Asynchronous Flow Ctl mode */
#define GTMPSC_MPCR_RESb BITS(31,16)

View File

@ -1,4 +1,4 @@
/* $NetBSD: gtmpscvar.h,v 1.7 2006/03/06 08:13:58 he Exp $ */
/* $NetBSD: gtmpscvar.h,v 1.8 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -81,57 +81,75 @@ typedef struct {
gtmpsc_pollrx_t rx[GTMPSC_NRXDESC];
} gtmpsc_poll_sdma_t;
/* Size of the Rx FIFO */
#define GTMPSC_RXFIFOSZ (GTMPSC_NRXDESC * GTMPSC_RXBUFSZ * 2)
/* Flags in sc->gtmpsc_flags */
#define GTMPSCF_KGDB 1
#include <sys/timepps.h>
#include <sys/tty.h>
typedef struct gtmpsc_softc {
struct device gtmpsc_dev;
bus_space_tag_t gtmpsc_memt;
bus_space_handle_t gtmpsc_memh;
bus_dma_tag_t gtmpsc_dmat;
device_t sc_dev;
int sc_unit;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_mpsch;
bus_space_handle_t sc_sdmah;
bus_dma_tag_t sc_dmat;
gtmpsc_poll_sdma_t *sc_poll_sdmapage;
bus_dmamap_t sc_rxdma_map;
bus_dmamap_t sc_txdma_map;
int sc_brg; /* using Baud Rate Generator */
int sc_baudrate;
tcflag_t sc_cflag;
void *sc_si; /* softintr cookie */
struct tty *gtmpsc_tty; /* our tty */
int gtmpsc_unit;
unsigned int gtmpsc_flags;
unsigned int gtmpsc_baud_rate;
bus_dma_segment_t gtmpsc_dma_segs[1];
bus_dmamap_t gtmpsc_dma_map;
gtmpsc_poll_sdma_t *gtmpsc_poll_sdmapage;
unsigned int gtmpsc_poll_txix; /* "current" tx xfer index */
unsigned int gtmpsc_poll_rxix; /* "current" rx xfer index */
unsigned int gtmpsc_cx; /* data index in gtmpsc_rxbuf */
unsigned int gtmpsc_nc; /* data count in gtmpsc_rxbuf */
unsigned int gtmpsc_chr2; /* soft copy of CHR2 */
unsigned int gtmpsc_chr3; /* soft copy of CHR3 */
unsigned int gtmpsc_brg_bcr; /* soft copy of BRG_BCR */
volatile u_char sc_heldchange; /* new params wait for output */
struct tty *sc_tty; /* our tty */
uint32_t sc_flags;
#define GTMPSC_CONSOLE (1 << 0)
#define GTMPSC_KGDB (1 << 1)
volatile int sc_rcvcnt; /* byte count of RX buffer */
volatile int sc_roffset; /* offset of RX buffer */
volatile int sc_rcvrx; /* receive rx xfer index */
volatile int sc_rcvdrx; /* received rx xfer index */
volatile int sc_readrx; /* read rx xfer index */
volatile int sc_nexttx; /* "next" tx xfer index */
volatile int sc_lasttx; /* "last" tx xfer index */
volatile u_char sc_rx_ready;
volatile u_char sc_tx_busy;
volatile u_char sc_tx_done;
volatile u_char sc_tx_stopped;
u_char *sc_tba; /* Tx buf ptr */
u_int sc_tbc; /* Tx buf cnt */
u_int sc_heldtbc;
unsigned char gtmpsc_rxbuf[GTMPSC_RXBUFSZ]; /* polling read buffer */
volatile unsigned int gtmpsc_rxfifo_navail;
/* available count in fifo */
unsigned int gtmpsc_rxfifo_putix; /* put index in fifo */
unsigned int gtmpsc_rxfifo_getix; /* get index in fifo */
unsigned char gtmpsc_rxfifo[GTMPSC_RXFIFOSZ];
unsigned int cnt_rx_from_sdma;
unsigned int cnt_rx_to_fifo;
unsigned int cnt_rx_from_fifo;
unsigned int cnt_tx_from_ldisc;
unsigned int cnt_tx_to_sdma;
volatile u_char sc_heldchange; /* new params wait for output */
u_char *sc_tba; /* Tx buf ptr */
u_int sc_tbc; /* Tx buf cnt */
u_int sc_heldtbc;
kmutex_t sc_lock;
struct pps_state sc_pps_state;
} gtmpsc_softc_t;
/* Make receiver interrupt 8 times a second */
#define GTMPSC_MAXIDLE(baudrate) ((baudrate) / (10 * 8)) /* There are 10 bits
in a frame */
/* There are 10 bits in a frame */
#define GTMPSC_MAXIDLE(baudrate) ((baudrate) / (10 * 8))
int gtmpsccnattach(bus_space_tag_t, bus_space_handle_t, int, int, tcflag_t);
int gtmpsc_is_console(bus_space_tag_t, int);
static __inline int
compute_cdv(unsigned int baud)
{
unsigned int cdv;
if (baud == 0)
return 0;
cdv = (GT_MPSC_FREQUENCY / (baud * GTMPSC_CLOCK_DIVIDER) + 1) / 2 - 1;
if (cdv > BRG_BCR_CDV_MAX)
return -1;
return cdv;
}
int gtmpsc_intr(void *);
#ifdef MPSC_CONSOLE
extern gtmpsc_softc_t gtmpsc_cn_softc;
int gtmpsccnattach(bus_space_tag_t, bus_dma_tag_t, bus_addr_t, int, int, int,
tcflag_t);
#endif
#endif /* _DEV_MARVELL_GTPSCVAR_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
/* $NetBSD: gtpcivar.h,v 1.8 2007/02/21 23:00:00 thorpej Exp $ */
/* $NetBSD: gtpcivar.h,v 1.9 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* Copyright (c) 2008 KIYOHARA Takashi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -12,85 +11,48 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* 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
* 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.
*/
#ifndef _DEV_MARVELL_GTPCIVAR_H
#define _DEV_MARVELL_GTPCIVAR_H
#ifndef _GTPCIVAR_H_
#define _GTPCIVAR_H_
/*
*/
struct gtpci_chipset {
struct pci_chipset gtpc_pc;
int gtpc_busno;
pcitag_t gtpc_self;
bus_space_tag_t gtpc_io_bs;
bus_space_tag_t gtpc_mem_bs;
bus_space_tag_t gtpc_gt_memt;
bus_space_handle_t gtpc_gt_memh;
bus_size_t gtpc_cfgaddr;
bus_size_t gtpc_cfgdata;
bus_size_t gtpc_syncreg;
bool gtpc_host;
struct gtpci_softc {
device_t sc_dev;
int sc_model;
int sc_rev;
int sc_unit;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
pci_chipset_tag_t sc_pc;
};
#if NPCI > 0
void gtpci_attach_hook(device_t, device_t, struct pcibus_attach_args *);
int gtpci_bus_maxdevs(void *, int);
pcitag_t gtpci_make_tag(void *, int, int, int);
void gtpci_decompose_tag(void *, pcitag_t, int *, int *, int *);
pcireg_t gtpci_conf_read(void *, pcitag_t, int);
void gtpci_conf_write(void *, pcitag_t, int, pcireg_t);
int gtpci_conf_hook(pci_chipset_tag_t, int, int, int, pcireg_t);
int gtpci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
const char *gtpci_intr_string(void *, pci_intr_handle_t);
const struct evcnt *gtpci_intr_evcnt(void *, pci_intr_handle_t);
void *gtpci_intr_establish(void *, pci_intr_handle_t, int, int (*)(void *),
void *);
void gtpci_intr_disestablish(void *, void *);
#endif
#ifdef _KERNEL
static uint32_t __inline
gtpci_read(struct gtpci_chipset *gtpc, bus_size_t reg)
{
uint32_t rv;
(void) bus_space_read_4(gtpc->gtpc_gt_memt, gtpc->gtpc_gt_memh,
gtpc->gtpc_syncreg);
rv = bus_space_read_4(gtpc->gtpc_gt_memt, gtpc->gtpc_gt_memh, reg);
(void) bus_space_read_4(gtpc->gtpc_gt_memt, gtpc->gtpc_gt_memh,
gtpc->gtpc_syncreg);
return rv;
}
static void __inline
gtpci_write(struct gtpci_chipset *gtpc, bus_size_t reg, uint32_t val)
{
(void) bus_space_read_4(gtpc->gtpc_gt_memt, gtpc->gtpc_gt_memh,
gtpc->gtpc_syncreg);
bus_space_write_4(gtpc->gtpc_gt_memt, gtpc->gtpc_gt_memh, reg, val);
(void) bus_space_read_4(gtpc->gtpc_gt_memt, gtpc->gtpc_gt_memh,
gtpc->gtpc_syncreg);
}
void gtpci_bus_configure(struct gtpci_chipset *);
pcitag_t gtpci_make_tag(pci_chipset_tag_t, int, int, int);
void gtpci_decompose_tag(pci_chipset_tag_t, pcitag_t, int *, int *, int *);
pcireg_t gtpci_conf_read(pci_chipset_tag_t, pcitag_t, int);
void gtpci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
void gtpci_md_bus_devorder(pci_chipset_tag_t, int, char []);
int gtpci_md_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
int gtpci_md_conf_hook(pci_chipset_tag_t, int, int, int, pcireg_t);
void gtpci_md_conf_interrupt(pci_chipset_tag_t, int, int, int, int, int *);
#endif /* _KERNEL */
#endif /* _DEV_MARVELL_GTPCIVAR_H */
#endif /* _GTPCIVAR_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: gtreg.h,v 1.3 2005/12/11 12:22:16 christos Exp $ */
/* $NetBSD: gtreg.h,v 1.4 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -46,6 +46,7 @@
#define GT__CLR(data, bit, len) ((data) &= ~(GT__MASK(len) << (bit)))
#define GT__INS(new, bit) ((new) << (bit))
#define GT_SIZE 0x10000
/*
* Table 30: CPU Address Decode Register Map
@ -175,13 +176,6 @@
#define GT_CPU_Error_Cause 0x0140
#define GT_CPU_Error_Mask 0x0148
#define GT_DecodeAddr_SET(g, r, v) \
do { \
gt_read((g), GT_Internal_Decode); \
gt_write((g), (r), ((v) & 0xfff00000) >> 20); \
while ((gt_read((g), (r)) & 0xfff) != ((v) >> 20)); \
} while (0)
#define GT_LowAddr_GET(v) (GT__EXT((v), 0, 12) << 20)
#define GT_HighAddr_GET(v) ((GT__EXT((v), 0, 12) << 20) | 0xfffff)
@ -191,10 +185,13 @@
#define GT_MPP_Control3 0xf00c
#define GT_GPP_IO_Control 0xf100
#define GT_GPP_Level_Control 0xf110
#define GT_GPP_Value 0xf104
#define GT_GPP_Interrupt_Cause 0xf108
#define GT_GPP_Interrupt_Mask 0xf10c
#define GT_GPP_Level_Control 0xf110
#define GT_GPP_Interrupt_Mask1 0xf114
#define GT_GPP_Value_Set 0xf118
#define GT_GPP_Value_Clear 0xf11c
/*
* Table 36: SCS[0]* Low Decode Address, Offset: 0x008
* Table 38: SCS[1]* Low Decode Address, Offset: 0x208
@ -776,4 +773,10 @@
#define GT_DEVBUS_RES ~(GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr|GT_DEVBUS_Sel)
#define ETH0_BASE 0x2400
#define ETH1_BASE 0x2800
#define ETH2_BASE 0x2c00
#define MPSC0_BASE 0x8000
#define MPSC1_BASE 0x9000
#endif /* !_DISCOVERY_DEV_GTREG_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: gtsdmareg.h,v 1.4 2005/12/11 12:22:16 christos Exp $ */
/* $NetBSD: gtsdmareg.h,v 1.5 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -53,28 +53,22 @@
#define BITS(hi, lo) ((~((~0) << ((hi) + 1))) & ((~0) << (lo)))
#endif
#define GTSDMA_BASE(u) ((u) == 0 ? 0x4000 : 0x6000)
#define GTSDMA_SIZE 0x1000
/*******************************************************************************
*
* SDMA register address offsets relative to the base mapping
*/
#define SDMA_SDC0 0x4000 /* SDMA #0 Configuration Register */
#define SDMA_SDCM0 0x4008 /* SDMA #0 Command Register */
#define SDMA_SCRDP0 0x4810 /* SDMA #0 Current RX Desc. Pointer */
#define SDMA_SCTDP0 0x4c10 /* SDMA #0 Current TX Desc. Pointer */
#define SDMA_SFTDP0 0x4c14 /* SDMA #0 First TX Desc. Pointer */
#define SDMA_SDC1 0x6000 /* SDMA #1 Configuration Register */
#define SDMA_SDCM1 0x6008 /* SDMA #1 Command Register */
#define SDMA_SCRDP1 0x6810 /* SDMA #1 Current RX Desc. Pointer */
#define SDMA_SCTDP1 0x6c10 /* SDMA #1 Current TX Desc. Pointer */
#define SDMA_SFTDP1 0x6c14 /* SDMA #1 First TX Desc. Pointer */
#define SDMA_SDC 0x000 /* SDMA Configuration Register */
#define SDMA_SDCM 0x008 /* SDMA Command Register */
#define SDMA_SCRDP 0x810 /* SDMA Current RX Desc. Pointer */
#define SDMA_SCTDP 0xc10 /* SDMA Current TX Desc. Pointer */
#define SDMA_SFTDP 0xc14 /* SDMA First TX Desc. Pointer */
#define SDMA_ICAUSE 0xb800 /* Interrupt Cause Register */
#define SDMA_IMASK 0xb880 /* Interrupt Mask Register */
#define SDMA_U_SDC(u) (SDMA_SDC0 + (((u) & 1) << 13))
#define SDMA_U_SDCM(u) (SDMA_SDCM0 + (((u) & 1) << 13))
#define SDMA_U_SCRDP(u) (SDMA_SCRDP0 + (((u) & 1) << 13))
#define SDMA_U_SCTDP(u) (SDMA_SCTDP0 + (((u) & 1) << 13))
#define SDMA_U_SFTDP(u) (SDMA_SFTDP0 + (((u) & 1) << 13))
/*******************************************************************************
*
@ -139,10 +133,10 @@
* for MPSC UART mode. Note that pointer fields are physical addrs.
*/
typedef struct sdma_desc {
u_int32_t sdma_cnt; /* size (rx) or shadow (tx) and count */
u_int32_t sdma_csr; /* command/status */
u_int32_t sdma_next; /* next descriptor link */
u_int32_t sdma_bufp; /* buffer pointer */
uint32_t sdma_cnt; /* size (rx) or shadow (tx) and count */
uint32_t sdma_csr; /* command/status */
uint32_t sdma_next; /* next descriptor link */
uint32_t sdma_bufp; /* buffer pointer */
} sdma_desc_t;
#define SDMA_RX_CNT_BCNT_SHIFT 0 /* byte count */

View File

@ -0,0 +1,49 @@
/* $NetBSD: gtsdmavar.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _GTSDMAVAR_H_
#define _GTSDMAVAR_H_
static __inline uint32_t
gt_sdma_icause(device_t gt, uint32_t _imask)
{
struct gt_softc *sc = device_private(gt);
uint32_t icause;
icause = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SDMA_ICAUSE) & _imask;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, SDMA_ICAUSE, icause);
return icause;
}
static __inline void
gt_sdma_imask(device_t gt, uint32_t _imask)
{
struct gt_softc *sc = device_private(gt);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, SDMA_IMASK, _imask);
}
#endif /* _GTSDMAVAR_H_ */

393
sys/dev/marvell/gttwsi.c Normal file
View File

@ -0,0 +1,393 @@
/* $NetBSD: gttwsi.c,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2008 Eiji Kawauchi.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Eiji Kawauchi.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* 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.
*/
/*
* Copyright (c) 2005 Brocade Communcations, inc.
* All rights reserved.
*
* Written by Matt Thomas for Brocade Communcations, Inc.
*
* 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.
* 3. The name of Brocade Communications, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY BROCADE COMMUNICATIONS, INC. ``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 EITHER BROCADE COMMUNICATIONS, INC. 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.
*/
//#define TWSI_DEBUG
/*
* Marvell Two-Wire Serial Interface (aka I2C) master driver
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: gttwsi.c,v 1.1 2010/04/28 13:51:56 kiyohara Exp $");
#include "locators.h"
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/condvar.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/mutex.h>
#include <sys/systm.h>
#include <machine/cpu.h>
#include <machine/param.h>
#include <dev/i2c/i2cvar.h>
#include <dev/marvell/marvellvar.h>
#include <dev/marvell/gttwsireg.h>
struct gttwsi_softc {
device_t sc_dev;
bus_space_tag_t sc_bust;
bus_space_handle_t sc_bush;
uint8_t sc_started;
struct i2c_controller sc_i2c;
kmutex_t sc_buslock;
kmutex_t sc_mtx;
kcondvar_t sc_cv;
};
static int gttwsi_match(device_t, cfdata_t, void *);
static void gttwsi_attach(device_t, device_t, void *);
static int gttwsi_intr(void *);
static int gttwsi_acquire_bus(void *, int);
static void gttwsi_release_bus(void *, int);
static int gttwsi_send_start(void *v, int flags);
static int gttwsi_send_stop(void *v, int flags);
static int gttwsi_initiate_xfer(void *v, i2c_addr_t addr, int flags);
static int gttwsi_read_byte(void *v, uint8_t *valp, int flags);
static int gttwsi_write_byte(void *v, uint8_t val, int flags);
static int gttwsi_wait(struct gttwsi_softc *, uint32_t, uint32_t, int);
static __inline u_int32_t RREG(struct gttwsi_softc *, u_int32_t);
static __inline void WREG(struct gttwsi_softc *, u_int32_t, u_int32_t);
CFATTACH_DECL_NEW(gttwsi_gt, sizeof(struct gttwsi_softc),
gttwsi_match, gttwsi_attach, NULL, NULL);
CFATTACH_DECL_NEW(gttwsi_mbus, sizeof(struct gttwsi_softc),
gttwsi_match, gttwsi_attach, NULL, NULL);
static __inline u_int32_t
RREG(struct gttwsi_softc *sc, u_int32_t reg)
{
u_int32_t val;
val = bus_space_read_4(sc->sc_bust, sc->sc_bush, reg);
#ifdef TWSI_DEBUG
printf("I2C:R:%02x:%02x\n", reg, val);
#else
DELAY(TWSI_READ_DELAY);
#endif
return val;
}
static __inline void
WREG(struct gttwsi_softc *sc, u_int32_t reg, u_int32_t val)
{
bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val);
#ifdef TWSI_DEBUG
printf("I2C:W:%02x:%02x\n", reg, val);
#else
DELAY(TWSI_WRITE_DELAY);
#endif
return;
}
/* ARGSUSED */
static int
gttwsi_match(device_t parent, cfdata_t match, void *aux)
{
struct marvell_attach_args *mva = aux;
if (strcmp(mva->mva_name, match->cf_name) != 0)
return 0;
if (mva->mva_offset == GTCF_OFFSET_DEFAULT ||
mva->mva_irq == GTCF_IRQ_DEFAULT)
return 0;
mva->mva_size = GTTWSI_SIZE;
return 1;
}
/* ARGSUSED */
static void
gttwsi_attach(device_t parent, device_t self, void *args)
{
struct gttwsi_softc *sc = device_private(self);
struct marvell_attach_args *mva = args;
struct i2cbus_attach_args iba;
aprint_naive("\n");
aprint_normal(": Marvell TWSI controller\n");
sc->sc_dev = self;
sc->sc_bust = mva->mva_iot;
if (bus_space_subregion(mva->mva_iot, mva->mva_ioh, mva->mva_offset,
mva->mva_size, &sc->sc_bush)) {
aprint_error_dev(self, "Cannot map registers\n");
return;
}
mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_BIO);
cv_init(&sc->sc_cv, "gttwsi");
sc->sc_started = 0;
sc->sc_i2c.ic_cookie = sc;
sc->sc_i2c.ic_acquire_bus = gttwsi_acquire_bus;
sc->sc_i2c.ic_release_bus = gttwsi_release_bus;
sc->sc_i2c.ic_exec = NULL;
sc->sc_i2c.ic_send_start = gttwsi_send_start;
sc->sc_i2c.ic_send_stop = gttwsi_send_stop;
sc->sc_i2c.ic_initiate_xfer = gttwsi_initiate_xfer;
sc->sc_i2c.ic_read_byte = gttwsi_read_byte;
sc->sc_i2c.ic_write_byte = gttwsi_write_byte;
marvell_intr_establish(mva->mva_irq, IPL_BIO, gttwsi_intr, sc);
/*
* Put the controller into Soft Reset.
*/
/* reset */
WREG(sc, TWSI_SOFTRESET, SOFTRESET_VAL);
memset(&iba, 0, sizeof(iba));
iba.iba_tag = &sc->sc_i2c;
(void) config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
}
static int
gttwsi_intr(void *arg)
{
struct gttwsi_softc *sc = arg;
uint32_t val;
val = RREG(sc, TWSI_CONTROL);
if (val & CONTROL_IFLG) {
WREG(sc, TWSI_CONTROL, val & ~CONTROL_INTEN);
mutex_enter(&sc->sc_mtx);
cv_signal(&sc->sc_cv);
mutex_exit(&sc->sc_mtx);
return 1; /* handled */
}
return 0;
}
/* ARGSUSED */
static int
gttwsi_acquire_bus(void *arg, int flags)
{
struct gttwsi_softc *sc = arg;
mutex_enter(&sc->sc_buslock);
return 0;
}
/* ARGSUSED */
static void
gttwsi_release_bus(void *arg, int flags)
{
struct gttwsi_softc *sc = arg;
mutex_exit(&sc->sc_buslock);
}
static int
gttwsi_send_start(void *v, int flags)
{
struct gttwsi_softc *sc = v;
int expect;
if (sc->sc_started)
expect = STAT_RSCT;
else
expect = STAT_SCT;
sc->sc_started = 1;
return gttwsi_wait(sc, CONTROL_START, expect, flags);
}
static int
gttwsi_send_stop(void *v, int flags)
{
struct gttwsi_softc *sc = v;
int retry = TWSI_RETRY_COUNT;
sc->sc_started = 0;
/* Interrupt is not generated for STAT_NRS. */
WREG(sc, TWSI_CONTROL, CONTROL_STOP | CONTROL_TWSIEN);
while (retry > 0) {
if (RREG(sc, TWSI_STATUS) == STAT_NRS)
return 0;
retry--;
DELAY(TWSI_STAT_DELAY);
}
aprint_error_dev(sc->sc_dev, "send STOP failed\n");
return -1;
}
static int
gttwsi_initiate_xfer(void *v, i2c_addr_t addr, int flags)
{
struct gttwsi_softc *sc = v;
uint32_t data, expect;
int error, read;
gttwsi_send_start(v, flags);
read = (flags & I2C_F_READ) != 0;
if (read)
expect = STAT_ARBT_AR;
else
expect = STAT_AWBT_AR;
/*
* First byte contains whether this xfer is a read or write.
*/
data = read;
if (addr > 0x7f) {
/*
* If this is a 10bit request, the first address byte is
* 0b11110<b9><b8><r/w>.
*/
data |= 0xf0 | ((addr & 0x300) >> 7);
WREG(sc, TWSI_DATA, data);
error = gttwsi_wait(sc, 0, expect, flags);
if (error)
return error;
/*
* The first address byte has been sent, now to send
* the second one.
*/
if (read)
expect = STAT_SARBT_AR;
else
expect = STAT_SAWBT_AR;
data = (uint8_t)addr;
} else
data |= (addr << 1);
WREG(sc, TWSI_DATA, data);
return gttwsi_wait(sc, 0, expect, flags);
}
static int
gttwsi_read_byte(void *v, uint8_t *valp, int flags)
{
struct gttwsi_softc *sc = v;
int error;
error = gttwsi_wait(sc, CONTROL_ACK, STAT_MRRD_AT, flags);
if (!error)
*valp = RREG(sc, TWSI_DATA);
if (flags & I2C_F_LAST)
WREG(sc, TWSI_CONTROL, 0);
return error;
}
static int
gttwsi_write_byte(void *v, uint8_t val, int flags)
{
struct gttwsi_softc *sc = v;
WREG(sc, TWSI_DATA, val);
return gttwsi_wait(sc, 0, STAT_MTDB_AR, flags);
}
static int
gttwsi_wait(struct gttwsi_softc *sc, uint32_t control, uint32_t expect,
int flags)
{
uint32_t status;
int error = 0;
DELAY(5);
if (!(flags & I2C_F_POLL))
control |= CONTROL_INTEN;
WREG(sc, TWSI_CONTROL, control | CONTROL_TWSIEN);
for (;;) {
control = RREG(sc, TWSI_CONTROL);
if (control & CONTROL_IFLG)
break;
if (!(flags & I2C_F_POLL)) {
mutex_enter(&sc->sc_mtx);
error = cv_timedwait_sig(&sc->sc_cv, &sc->sc_mtx, hz);
mutex_exit(&sc->sc_mtx);
if (error)
return error;
}
DELAY(TWSI_RETRY_DELAY);
}
status = RREG(sc, TWSI_STATUS);
if (status != expect) {
aprint_error_dev(sc->sc_dev,
"unexpected status 0x%x: expect 0x%x\n", status, expect);
return EIO;
}
if ((flags & I2C_F_STOP) && expect != STAT_MRRD_AT)
error = gttwsi_send_stop(sc, flags);
return error;
}

View File

@ -0,0 +1,80 @@
/* $NetBSD: gttwsireg.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2008 Eiji Kawauchi.
* 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.
*/
#ifndef _GTTWSIREG_H_
#define _GTTWSIREG_H_
#define GTTWSI_SIZE 0x1000
#define TWSI_SLAVEADDR 0x00
#define TWSI_EXTEND_SLAVEADDR 0x10
#define TWSI_DATA 0x04
#define TWSI_CONTROL 0x08
#define TWSI_STATUS 0x0c /* for read */
#define TWSI_BAUDRATE 0x0c /* for write */
#define TWSI_SOFTRESET 0x1c
#define SLAVEADDR_GCE_MASK 0x01
#define SLAVEADDR_SADDR_MASK 0xfe
#define EXTEND_SLAVEADDR_MASK 0xff
#define DATA_MASK 0xff
#define CONTROL_ACK (1<<2)
#define CONTROL_IFLG (1<<3)
#define CONTROL_STOP (1<<4)
#define CONTROL_START (1<<5)
#define CONTROL_TWSIEN (1<<6)
#define CONTROL_INTEN (1<<7)
#define STAT_BE 0x00 /* Bus Error */
#define STAT_SCT 0x08 /* Start condition transmitted */
#define STAT_RSCT 0x10 /* Repeated start condition transmitted */
#define STAT_AWBT_AR 0x18 /* Address + write bit transd, ack recvd */
#define STAT_AWBT_ANR 0x20 /* Address + write bit transd, ack not recvd */
#define STAT_MTDB_AR 0x28 /* Master transd data byte, ack recvd */
#define STAT_MTDB_ANR 0x30 /* Master transd data byte, ack not recvd */
#define STAT_MLADADT 0x38 /* Master lost arbitr during addr or data tx */
#define STAT_ARBT_AR 0x40 /* Address + read bit transd, ack recvd */
#define STAT_ARBT_ANR 0x48 /* Address + read bit transd, ack not recvd */
#define STAT_MRRD_AT 0x50 /* Master received read data, ack transd */
#define STAT_MRRD_ANT 0x58 /* Master received read data, ack not transd */
#define STAT_SAWBT_AR 0xd0 /* Second addr + write bit transd, ack recvd */
#define STAT_SAWBT_ANR 0xd8 /* S addr + write bit transd, ack not recvd */
#define STAT_SARBT_AR 0xe0 /* Second addr + read bit transd, ack recvd */
#define STAT_SARBT_ANR 0xe8 /* S addr + read bit transd, ack not recvd */
#define STAT_NRS 0xf8 /* No relevant status */
#define SOFTRESET_VAL 0 /* reset value */
#define TWSI_RETRY_COUNT 1000 /* retry loop count */
#define TWSI_RETRY_DELAY 1 /* retry delay */
#define TWSI_STAT_DELAY 1 /* poll status delay */
#define TWSI_READ_DELAY 2 /* read delay */
#define TWSI_WRITE_DELAY 2 /* write delay */
#endif /* _GTTWSIREG_H_ */

View File

@ -1,7 +1,6 @@
/* $NetBSD: gtvar.h,v 1.14 2009/05/12 14:30:25 cegger Exp $ */
/* $NetBSD: gtvar.h,v 1.15 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* Copyright (c) 2009 KIYOHARA Takashi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -12,80 +11,31 @@
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Allegro Networks, Inc., and Wasabi Systems, Inc.
* 4. The name of Allegro Networks, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* 5. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
* WASABI SYSTEMS, INC. ``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 EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
* 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
* 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.
*/
/*
* gtvar.h -- placeholder for GT system controller driver
*/
#ifndef _DISCOVERY_DEV_GTVAR_H_
#define _DISCOVERY_DEV_GTVAR_H_
#include <sys/systm.h>
#ifndef _DEV_DISCOVERY_GTVAR_H_
#define _DEV_DISCOVERY_GTVAR_H_
struct gt_softc {
struct device gt_dev;
bus_dma_tag_t gt_dmat;
bus_space_tag_t gt_memt; /* the GT itself */
bus_space_tag_t gt_pci0_memt; /* PCI0 mem space */
bus_space_tag_t gt_pci0_iot; /* PCI0 i/o space */
bool gt_pci0_host; /* We're host on PCI0 if TRUE */
bus_space_tag_t gt_pci1_memt; /* PCI1 mem space */
bus_space_tag_t gt_pci1_iot; /* PCI1 i/o space */
bool gt_pci1_host; /* We're host on PCI1 if TRUE */
bus_space_handle_t gt_memh; /* to access the GT registers */
int gt_childmask; /* what children are present */
};
#define GT_CHILDOK(gt, ga, cd, pos, max) \
(((ga)->ga_unit) < (max) && \
!((gt)->gt_childmask & (1 << (((ga)->ga_unit) + (pos)))) && \
!strcmp((ga)->ga_name, (cd)->cd_name))
#define GT_MPSCOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 0, 2)
#define GT_PCIOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 2, 2)
#define GT_ETHEROK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 4, 3)
#define GT_OBIOOK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 7, 5)
#define GT_I2COK(gt, ga, cd) GT_CHILDOK((gt), (ga), (cd), 12, 1)
#define GT_CHILDFOUND(gt, ga, pos) \
((void)(((gt)->gt_childmask |= (1 << (((ga)->ga_unit) + (pos))))))
#define GT_MPSCFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 0)
#define GT_PCIFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 2)
#define GT_ETHERFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 4)
#define GT_OBIOFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 7)
#define GT_I2CFOUND(gt, ga) GT_CHILDFOUND((gt), (ga), 12)
struct gt_attach_args {
const char *ga_name; /* class name of device */
bus_dma_tag_t ga_dmat; /* dma tag */
bus_space_tag_t ga_memt; /* GT bus space tag */
bus_space_handle_t ga_memh; /* GT bus space handle */
int ga_unit; /* instance of ga_name */
device_t sc_dev;
int sc_model;
int sc_rev;
bus_addr_t sc_addr;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_dma_tag_t sc_dmat;
};
struct obio_attach_args {
@ -96,63 +46,21 @@ struct obio_attach_args {
int oa_irq; /* irq */
};
#ifdef _KERNEL
#include "locators.h"
#ifdef DEBUG
extern int gtpci_debug;
#endif
/*
* Locators for GT private devices, as specified to config.
*/
#define GT_UNK_UNIT GTCF_UNIT_DEFAULT /* wcarded 'function' */
#define OBIO_UNK_OFFSET OBIOCF_OFFSET_DEFAULT /* wcarded 'offset' */
#define OBIO_UNK_SIZE OBIOCF_SIZE_DEFAULT /* wcarded 'size' */
#define OBIO_UNK_IRQ OBIOCF_IRQ_DEFAULT /* wcarded 'irq' */
void gt_attach_common(struct gt_softc *);
uint32_t gt_read_mpp(void);
int gt_cfprint(void *, const char *);
/* int gt_bs_extent_init(struct discovery_bus_space *, char *); AKB */
#ifdef GT_WATCHDOG
void gt_watchdog_service(void);
void gt_watchdog_reset(void);
#else
#define gt_watchdog_service() ((void)0)
#define gt_watchdog_reset() ((void)0)
#endif
int gt_mii_read(device_t, device_t, int, int);
void gt_mii_write(device_t, device_t, int, int, int);
int gtget_macaddr(struct gt_softc *,int, char *);
void gt_watchdog_service(void);
bus_addr_t gt_dma_phys_to_bus_mem(bus_dma_tag_t, bus_addr_t);
bus_addr_t gt_dma_bus_mem_to_phys(bus_dma_tag_t, bus_addr_t);
#define gt_read(gt,o) \
bus_space_read_4((gt)->gt_memt, (gt)->gt_memh, (o))
#define gt_write(gt,o,v) \
bus_space_write_4((gt)->gt_memt, (gt)->gt_memh, (o), (v))
#if defined(__powerpc__)
static __inline int
atomic_add(volatile int *p, int v)
{
int rv;
int rtmp;
uint32_t gt_read_mpp(void);
__asm volatile(
"1: lwarx %0,0,%2\n"
" add %1,%3,%0\n"
" stwcx. %1,0,%2\n"
" bne- 1b\n"
" sync"
: "=&r"(rv), "=&r"(rtmp)
: "r"(p), "r"(v)
: "cc");
return rv;
}
#endif /* __powerpc__ */
#endif /* _KERNEL */
#endif /* _DISCOVERY_DEV_GTVAR_H_ */
#endif /* _DEV_DISCOVERY_GTVAR_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_gfevar.h,v 1.9 2008/06/10 22:44:07 he Exp $ */
/* $NetBSD: if_gfevar.h,v 1.10 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -36,6 +36,8 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _IF_GFEVAR_H_
#define _IF_GFEVAR_H_
#define GE_RXDESC_MEMSIZE (1 * PAGE_SIZE)
#define GE_RXDESC_MAX 64
@ -114,17 +116,22 @@ enum gfe_rxprio {
GE_RXPRIO_LO=0
};
struct gfec_softc {
device_t sc_dev; /* must be first */
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh; /* subregion for ethernet */
kmutex_t sc_mtx;
};
struct gfe_softc {
struct device sc_dev; /* must be first */
device_t sc_dev; /* must be first */
struct ethercom sc_ec; /* common ethernet glue */
struct callout sc_co; /* resource recovery */
mii_data_t sc_mii; /* mii interface */
/*
*
*/
bus_space_tag_t sc_gt_memt;
bus_space_handle_t sc_gt_memh;
bus_space_tag_t sc_memt;
bus_space_handle_t sc_memh; /* subregion for ethernet */
bus_dma_tag_t sc_dmat;
int sc_macno; /* which mac? 0, 1, or 2 */
@ -159,4 +166,9 @@ struct gfe_softc {
* Receive related members
*/
struct gfe_rxqueue sc_rxq[4]; /* Hi/MedHi/MedLo/Lo receive queues */
#if NRND > 0
rndsource_element_t sc_rnd_source;
#endif
};
#endif /* _IF_GFEVAR_H_ */

View File

@ -0,0 +1,75 @@
/* $NetBSD: marvellreg.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _DEV_MARVELL_MARVELLREG_H_
#define _DEV_MARVELL_MARVELLREG_H_
#include <dev/pci/pcidevs.h>
#define MARVELL_DISCOVERY PCI_PRODUCT_MARVELL_GT64260
#define MARVELL_DISCOVERY_II PCI_PRODUCT_MARVELL_GT64360
#define MARVELL_DISCOVERY_III 0x6480 /* PCI_PRODUCT_MARVELL_GT64460 */
#if 0
#define MARVELL_DISCOVERY_LT /* XXXX */
#define MARVELL_DISCOVERY_V /* XXXX */
#define MARVELL_DISCOVERY_VI /* XXXX */
#endif
#define MARVELL_ORION_1_88F1181 PCI_PRODUCT_MARVELL_88F1181
#define MARVELL_ORION_1_88F5082 PCI_PRODUCT_MARVELL_88F5082
#define MARVELL_ORION_1_88F5180N PCI_PRODUCT_MARVELL_88F5180N
#define MARVELL_ORION_1_88F5181 PCI_PRODUCT_MARVELL_88F5181
#define MARVELL_ORION_1_88F5182 PCI_PRODUCT_MARVELL_88F5182
#define MARVELL_ORION_1_88F6082 PCI_PRODUCT_MARVELL_88F6082
#define MARVELL_ORION_1_88W8660 PCI_PRODUCT_MARVELL_88W8660
#define MARVELL_ORION_2_88F1281 PCI_PRODUCT_MARVELL_88F1281
#define MARVELL_ORION_2_88F5281 PCI_PRODUCT_MARVELL_88F5281
#define MARVELL_DISCOVERY_REVA 0x10
#define MARVELL_DISCOVERY_REVB 0x20
#define MARVELL_ATTR_MASK 0xff
#define MARVELL_ATTR_SDRAM_CS0 0x0e
#define MARVELL_ATTR_SDRAM_CS1 0x0d
#define MARVELL_ATTR_SDRAM_CS2 0x0b
#define MARVELL_ATTR_SDRAM_CS3 0x07
#define MARVELL_ATTR_PEX_CFG 0x79 /* bug workaround ?? */
#define MARVELL_ATTR_PEX_MEM 0x59
#define MARVELL_ATTR_PEX_IO 0x51
#define MARVELL_ATTR_PCI_MEM 0x59
#define MARVELL_ATTR_PCI_IO 0x51
#define MARVELL_ATTR_DEVICE_CS0 0x1e
#define MARVELL_ATTR_DEVICE_CS1 0x1d
#define MARVELL_ATTR_DEVICE_CS2 0x1b
#define MARVELL_ATTR_FLASH_CS 0x1b
#define MARVELL_ATTR_BOOT_CS 0x0f
#define MARVELL_ATTR_CRYPT 0x00
#endif /* _DEV_MARVELL_MARVELLREG_H_ */

View File

@ -0,0 +1,61 @@
/* $NetBSD: marvellvar.h,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2009 KIYOHARA Takashi
* 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.
*/
#ifndef _DEV_MARVELL_MARVELLVAR_H_
#define _DEV_MARVELL_MARVELLVAR_H_
enum marvell_tags {
MARVELL_TAG_SDRAM_CS0,
MARVELL_TAG_SDRAM_CS1,
MARVELL_TAG_SDRAM_CS2,
MARVELL_TAG_SDRAM_CS3,
MARVELL_TAG_UNDEFINED = -1,
};
#include <sys/bus.h>
struct marvell_attach_args {
const char *mva_name;
int mva_model;
int mva_revision;
bus_space_tag_t mva_iot;
bus_space_handle_t mva_ioh;
int mva_unit;
bus_size_t mva_addr;
bus_size_t mva_offset;
bus_size_t mva_size;
bus_dma_tag_t mva_dmat;
int mva_irq;
};
void *marvell_intr_establish(int, int, int (*)(void *), void *);
int marvell_winparams_by_tag(device_t, int, int *, int *, uint64_t *,
uint32_t *);
#endif /* _DEV_MARVELL_MARVELLVAR_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: obio.c,v 1.12 2009/05/12 14:30:25 cegger Exp $ */
/* $NetBSD: obio.c,v 1.13 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@ -37,12 +37,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* gt.c -- GT system controller driver
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.12 2009/05/12 14:30:25 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.13 2010/04/28 13:51:56 kiyohara Exp $");
#include "opt_marvell.h"
@ -53,16 +49,13 @@ __KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.12 2009/05/12 14:30:25 cegger Exp $");
#include <sys/kernel.h>
#include <sys/malloc.h>
#define _BUS_SPACE_PRIVATE
#define _BUS_DMA_PRIVATE
#include <sys/bus.h>
#include <powerpc/spr.h>
#include <powerpc/oea/hid.h>
#include <dev/pci/pcivar.h>
#include <dev/marvell/gtreg.h>
#include <dev/marvell/gtvar.h>
#include <dev/marvell/gtdevbusvar.h>
#include <dev/marvell/marvellvar.h>
#include <prop/proplib.h>
#ifdef DEBUG
#include <sys/systm.h> /* for Debugger() */
@ -70,62 +63,109 @@ __KERNEL_RCSID(0, "$NetBSD: obio.c,v 1.12 2009/05/12 14:30:25 cegger Exp $");
#include "locators.h"
static int obio_match(device_t, cfdata_t, void *);
static void obio_attach(device_t, device_t, void *);
static int obio_cfprint(void *, const char *);
static int obio_cfmatch(device_t, cfdata_t, void *);
static int obio_cfsearch(device_t, cfdata_t,
const int *, void *);
static void obio_cfattach(device_t, device_t, void *);
static int obio_cfsearch(device_t, cfdata_t, const int *, void *);
struct obio_softc {
struct device sc_dev;
bus_space_tag_t sc_memt;
bus_space_tag_t sc_gt_memt;
bus_space_tag_t sc_gt_memh;
device_t sc_dev;
bus_space_tag_t sc_iot;
};
CFATTACH_DECL(obio, sizeof(struct obio_softc),
obio_cfmatch, obio_cfattach, NULL, NULL);
CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc),
obio_match, obio_attach, NULL, NULL);
extern struct cfdriver obio_cd;
static const struct {
bus_addr_t low_decode;
bus_addr_t high_decode;
} obio_info[5] = {
{ GT_CS0_Low_Decode, GT_CS0_High_Decode, },
{ GT_CS1_Low_Decode, GT_CS1_High_Decode, },
{ GT_CS2_Low_Decode, GT_CS2_High_Decode, },
{ GT_CS3_Low_Decode, GT_CS3_High_Decode, },
{ GT_BootCS_Low_Decode, GT_BootCS_High_Decode, },
};
/* ARGSUSED */
int
obio_match(device_t parent, cfdata_t cf, void *aux)
{
struct marvell_attach_args *mva = aux;
if (strcmp(mva->mva_name, cf->cf_name) != 0)
return 0;
#define NUM_OBIO 5
if (mva->mva_unit == GTCF_UNIT_DEFAULT ||
mva->mva_unit > NUM_OBIO)
return 0;
return 1;
}
/* ARGSUSED */
void
obio_attach(device_t parent, device_t self, void *aux)
{
struct obio_softc *sc = device_private(self);
struct marvell_attach_args *mva = aux;
prop_data_t bst;
uint32_t datal, datah;
aprint_naive("\n");
aprint_normal(": Device Bus\n");
sc->sc_dev = self;
if (gt_devbus_addr(parent, mva->mva_unit, &datal, &datah)) {
aprint_error_dev(self, "unknown unit number %d\n",
mva->mva_unit);
return;
}
if (GT_LowAddr_GET(datal) > GT_HighAddr_GET(datah)) {
aprint_normal_dev(self, "disabled\n");
return;
}
bst = prop_dictionary_get(device_properties(sc->sc_dev), "bus-tag");
if (bst != NULL) {
KASSERT(prop_object_type(bst) == PROP_TYPE_DATA);
KASSERT(prop_data_size(bst) == sizeof(bus_space_tag_t));
memcpy(&sc->sc_iot, prop_data_data_nocopy(bst),
sizeof(bus_space_tag_t));
} else
sc->sc_iot = mva->mva_iot;
if (sc->sc_iot == NULL) {
aprint_normal_dev(self, "unused\n");
return;
}
aprint_normal_dev(self, "addr %#x-%#x\n",
GT_LowAddr_GET(datal), GT_HighAddr_GET(datah));
config_search_ia(obio_cfsearch, self, "obio", NULL);
}
extern bus_space_tag_t obio_bs_tags[5];
int
obio_cfprint(void *aux, const char *pnp)
{
struct obio_attach_args *oa = aux;
if (pnp) {
if (pnp)
aprint_normal("%s at %s", oa->oa_name, pnp);
}
aprint_normal(" offset %#x size %#x", oa->oa_offset, oa->oa_size);
aprint_normal(" addr %#x size %#x", oa->oa_offset, oa->oa_size);
if (oa->oa_irq != OBIOCF_IRQ_DEFAULT)
aprint_normal(" irq %d", oa->oa_irq);
return (UNCONF);
return UNCONF;
}
/* ARGSUSED */
int
obio_cfsearch(device_t parent, cfdata_t cf,
const int *ldesc, void *aux)
obio_cfsearch(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
{
struct obio_softc *sc = (struct obio_softc *) parent;
struct obio_softc *sc = device_private(parent);
struct obio_attach_args oa;
oa.oa_name = cf->cf_name;
oa.oa_memt = sc->sc_memt;
oa.oa_memt = sc->sc_iot;
oa.oa_offset = cf->cf_loc[OBIOCF_OFFSET];
oa.oa_size = cf->cf_loc[OBIOCF_SIZE];
oa.oa_irq = cf->cf_loc[OBIOCF_IRQ];
@ -133,47 +173,5 @@ obio_cfsearch(device_t parent, cfdata_t cf,
if (config_match(parent, cf, &oa) > 0)
config_attach(parent, cf, &oa, obio_cfprint);
return (0);
}
int
obio_cfmatch(device_t parent, cfdata_t cf, void *aux)
{
struct gt_softc * const gt = (struct gt_softc *)parent;
struct gt_attach_args * const ga = aux;
return GT_OBIOOK(gt, ga, &obio_cd);
}
void
obio_cfattach(device_t parent, device_t self, void *aux)
{
struct gt_softc * const gt = device_private(parent);
struct obio_softc *sc = device_private(self);
struct gt_attach_args *ga = aux;
uint32_t datal, datah;
GT_OBIOFOUND(gt, ga);
datal = bus_space_read_4(ga->ga_memt, ga->ga_memh,
obio_info[ga->ga_unit].low_decode);
datah = bus_space_read_4(ga->ga_memt, ga->ga_memh,
obio_info[ga->ga_unit].high_decode);
if (GT_LowAddr_GET(datal) > GT_HighAddr_GET(datah)) {
aprint_normal(": disabled\n");
return;
}
sc->sc_memt = obio_bs_tags[ga->ga_unit];
if (sc->sc_memt == NULL) {
aprint_normal(": unused\n");
return;
}
aprint_normal(": addr %#x-%#x, %s-endian\n",
GT_LowAddr_GET(datal), GT_HighAddr_GET(datah),
GT_PCISwap_GET(datal) == 1 ? "little" : "big");
config_search_ia(obio_cfsearch, &sc->sc_dev, "obio", NULL);
return 0;
}

79
sys/dev/marvell/pchb.c Normal file
View File

@ -0,0 +1,79 @@
/* $NetBSD: pchb.c,v 1.1 2010/04/28 13:51:56 kiyohara Exp $ */
/*
* Copyright (c) 2008 KIYOHARA Takashi
* 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.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.1 2010/04/28 13:51:56 kiyohara Exp $");
#include "opt_pci.h"
#include "pci.h"
#include <sys/param.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/marvell/marvellreg.h>
#include <dev/marvell/marvellvar.h>
static int pchb_match(device_t, struct cfdata *, void *);
static void pchb_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(pchb, sizeof(struct device),
pchb_match, pchb_attach, NULL, NULL);
/* ARGSUSED */
static int
pchb_match(device_t parent, struct cfdata *match, void *aux)
{
struct pci_attach_args *pa = aux;
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_MARVELL)
switch (PCI_PRODUCT(pa->pa_id)) {
case MARVELL_ORION_1_88F1181:
case MARVELL_ORION_1_88F5082:
case MARVELL_ORION_1_88F5181:
case MARVELL_ORION_1_88F5182:
case MARVELL_ORION_2_88F5281:
case MARVELL_ORION_1_88W8660:
return 1;
}
return 0;
}
/* ARGSUSED */
static void
pchb_attach(device_t parent, device_t self, void *aux)
{
aprint_normal("\n");
aprint_naive("\n");
}