ixdp425_pci.c revision 229125
1164426Ssam/* $NetBSD: ixdp425_pci.c,v 1.5 2005/12/11 12:17:09 christos Exp $ */ 2164426Ssam/* 3164426Ssam * Copyright (c) 2003 4164426Ssam * Ichiro FUKUHARA <ichiro@ichiro.org>. 5164426Ssam * All rights reserved. 6164426Ssam * 7164426Ssam * Redistribution and use in source and binary forms, with or without 8164426Ssam * modification, are permitted provided that the following conditions 9164426Ssam * are met: 10164426Ssam * 1. Redistributions of source code must retain the above copyright 11164426Ssam * notice, this list of conditions and the following disclaimer. 12164426Ssam * 2. Redistributions in binary form must reproduce the above copyright 13164426Ssam * notice, this list of conditions and the following disclaimer in the 14164426Ssam * documentation and/or other materials provided with the distribution. 15164426Ssam * 3. All advertising materials mentioning features or use of this software 16164426Ssam * must display the following acknowledgement: 17164426Ssam * This product includes software developed by Ichiro FUKUHARA. 18164426Ssam * 4. The name of the company nor the name of the author may be used to 19164426Ssam * endorse or promote products derived from this software without specific 20164426Ssam * prior written permission. 21164426Ssam * 22164426Ssam * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR 23164426Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24164426Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25164426Ssam * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR 26164426Ssam * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27164426Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28164426Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29164426Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30164426Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31164426Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32164426Ssam * SUCH DAMAGE. 33164426Ssam */ 34164426Ssam 35164426Ssam#include <sys/cdefs.h> 36164426Ssam__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/ixdp425_pci.c 229125 2011-12-31 15:53:34Z marius $"); 37164426Ssam 38164426Ssam#define _ARM32_BUS_DMA_PRIVATE 39164426Ssam#include <sys/param.h> 40164426Ssam#include <sys/systm.h> 41164426Ssam#include <sys/bus.h> 42164426Ssam#include <sys/kernel.h> 43164426Ssam#include <sys/module.h> 44164426Ssam#include <sys/malloc.h> 45164426Ssam#include <sys/rman.h> 46229125Smarius 47229125Smarius#include <dev/pci/pcivar.h> 48229125Smarius 49164426Ssam#include <machine/bus.h> 50164426Ssam#include <machine/intr.h> 51164426Ssam 52164426Ssam#include <arm/xscale/ixp425/ixp425reg.h> 53164426Ssam#include <arm/xscale/ixp425/ixp425var.h> 54164426Ssam#include <arm/xscale/ixp425/ixp425_intr.h> 55164426Ssam#include <arm/xscale/ixp425/ixdp425reg.h> 56164426Ssam 57164426Ssamvoid 58164426Ssamixp425_md_attach(device_t dev) 59164426Ssam{ 60164426Ssam struct ixp425_softc *sc = device_get_softc(device_get_parent(dev)); 61164426Ssam struct ixppcib_softc *pci_sc = device_get_softc(dev); 62164426Ssam uint32_t reg; 63164426Ssam 64164426Ssam 65164426Ssam /* PCI Reset Assert */ 66164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); 67164426Ssam reg &= ~(1U << GPIO_PCI_RESET); 68196479Scognet GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg); 69164426Ssam 70164426Ssam /* PCI Clock Disable */ 71164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); 72164426Ssam reg &= ~GPCLKR_MUX14; 73196479Scognet GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg); 74164426Ssam 75164426Ssam /* 76164426Ssam * set GPIO Direction 77164426Ssam * Output: PCI_CLK, PCI_RESET 78164426Ssam * Input: PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD 79164426Ssam */ 80164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER); 81164426Ssam reg &= ~(1U << GPIO_PCI_CLK); 82164426Ssam reg &= ~(1U << GPIO_PCI_RESET); 83164426Ssam reg |= ((1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) | 84164426Ssam (1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD)); 85164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, reg); 86164426Ssam 87164426Ssam /* 88164426Ssam * Set GPIO interrupt type 89164426Ssam * PCI_INT_A, PCI_INTB, PCI_INT_C, PCI_INT_D: Active Low 90164426Ssam */ 91164426Ssam reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA)); 92164426Ssam reg &= ~GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_MASK); 93164426Ssam reg |= GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_ACT_LOW); 94164426Ssam GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA), reg); 95164426Ssam 96164426Ssam reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB)); 97164426Ssam reg &= ~GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_MASK); 98164426Ssam reg |= GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_ACT_LOW); 99164426Ssam GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB), reg); 100164426Ssam 101164426Ssam reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC)); 102164426Ssam reg &= ~GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_MASK); 103164426Ssam reg |= GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_ACT_LOW); 104164426Ssam GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC), reg); 105164426Ssam 106164426Ssam reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD)); 107164426Ssam reg &= ~GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_MASK); 108164426Ssam reg |= GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_ACT_LOW); 109164426Ssam GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD), reg); 110164426Ssam 111164426Ssam /* clear ISR */ 112164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR, 113164426Ssam (1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) | 114164426Ssam (1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD)); 115164426Ssam 116164426Ssam /* wait 1ms to satisfy "minimum reset assertion time" of the PCI spec */ 117164426Ssam DELAY(1000); 118164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); 119164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg | 120164426Ssam (0xf << GPCLKR_CLK0DC_SHIFT) | (0xf << GPCLKR_CLK0TC_SHIFT)); 121164426Ssam 122164426Ssam /* PCI Clock Enable */ 123164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); 124164426Ssam reg |= GPCLKR_MUX14; 125164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg | GPCLKR_MUX14); 126164426Ssam 127164426Ssam /* 128164426Ssam * wait 100us to satisfy "minimum reset assertion time from clock stable 129164426Ssam * requirement of the PCI spec 130164426Ssam */ 131164426Ssam DELAY(100); 132164426Ssam /* PCI Reset deassert */ 133164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); 134164426Ssam reg |= 1U << GPIO_PCI_RESET; 135164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg | (1U << GPIO_PCI_RESET)); 136164426Ssam pci_sc->sc_irq_rman.rm_type = RMAN_ARRAY; 137164426Ssam pci_sc->sc_irq_rman.rm_descr = "IXP425 PCI IRQs"; 138164426Ssam CTASSERT(PCI_INT_D < PCI_INT_A); 139164426Ssam /* XXX this overlaps the irq's setup in ixp425_attach */ 140164426Ssam if (rman_init(&pci_sc->sc_irq_rman) != 0 || 141164426Ssam rman_manage_region(&pci_sc->sc_irq_rman, PCI_INT_D, PCI_INT_A) != 0) 142164426Ssam panic("ixp425_md_attach: failed to set up IRQ rman"); 143164426Ssam} 144164426Ssam 145177456Ssam#define IXP425_MAX_DEV 5 146164426Ssam#define IXP425_MAX_LINE 4 147164426Ssam 148164426Ssamint 149164426Ssamixp425_md_route_interrupt(device_t bridge, device_t device, int pin) 150164426Ssam{ 151177456Ssam static int ixp425_pci_table[IXP425_MAX_DEV][IXP425_MAX_LINE] = { 152164426Ssam {PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D}, 153164426Ssam {PCI_INT_B, PCI_INT_C, PCI_INT_D, PCI_INT_A}, 154164426Ssam {PCI_INT_C, PCI_INT_D, PCI_INT_A, PCI_INT_B}, 155164426Ssam {PCI_INT_D, PCI_INT_A, PCI_INT_B, PCI_INT_C}, 156177456Ssam /* NB: for optional USB controller on Gateworks Avila */ 157177456Ssam {PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D}, 158164426Ssam }; 159164426Ssam int dev; 160164426Ssam 161164426Ssam dev = pci_get_slot(device); 162164426Ssam if (bootverbose) 163164426Ssam device_printf(bridge, "routing pin %d for %s\n", pin, 164164426Ssam device_get_nameunit(device)); 165164426Ssam if (pin >= 1 && pin <= IXP425_MAX_LINE && 166164426Ssam dev >= 1 && dev <= IXP425_MAX_DEV) { 167164426Ssam return (ixp425_pci_table[dev - 1][pin - 1]); 168164426Ssam } else 169164426Ssam printf("ixppcib: no mapping for %d/%d/%d\n", 170164426Ssam pci_get_bus(device), dev, pci_get_function(device)); 171164426Ssam 172164426Ssam return (-1); 173164426Ssam} 174