ixdp425_pci.c revision 177456
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 177456 2008-03-20 15:54:19Z sam $"); 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> 46164426Ssam#include <machine/bus.h> 47164426Ssam#include <machine/intr.h> 48164426Ssam 49164426Ssam#include <arm/xscale/ixp425/ixp425reg.h> 50164426Ssam#include <arm/xscale/ixp425/ixp425var.h> 51164426Ssam#include <arm/xscale/ixp425/ixp425_intr.h> 52164426Ssam#include <arm/xscale/ixp425/ixdp425reg.h> 53164426Ssam 54164426Ssamvoid 55164426Ssamixp425_md_attach(device_t dev) 56164426Ssam{ 57164426Ssam struct ixp425_softc *sc = device_get_softc(device_get_parent(dev)); 58164426Ssam struct ixppcib_softc *pci_sc = device_get_softc(dev); 59164426Ssam uint32_t reg; 60164426Ssam 61164426Ssam 62164426Ssam /* PCI Reset Assert */ 63164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); 64164426Ssam reg &= ~(1U << GPIO_PCI_RESET); 65164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg & ~(1U << GPIO_PCI_RESET)); 66164426Ssam 67164426Ssam /* PCI Clock Disable */ 68164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); 69164426Ssam reg &= ~GPCLKR_MUX14; 70164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg & ~GPCLKR_MUX14); 71164426Ssam 72164426Ssam /* 73164426Ssam * set GPIO Direction 74164426Ssam * Output: PCI_CLK, PCI_RESET 75164426Ssam * Input: PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD 76164426Ssam */ 77164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER); 78164426Ssam reg &= ~(1U << GPIO_PCI_CLK); 79164426Ssam reg &= ~(1U << GPIO_PCI_RESET); 80164426Ssam reg |= ((1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) | 81164426Ssam (1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD)); 82164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, reg); 83164426Ssam 84164426Ssam /* 85164426Ssam * Set GPIO interrupt type 86164426Ssam * PCI_INT_A, PCI_INTB, PCI_INT_C, PCI_INT_D: Active Low 87164426Ssam */ 88164426Ssam reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA)); 89164426Ssam reg &= ~GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_MASK); 90164426Ssam reg |= GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_ACT_LOW); 91164426Ssam GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA), reg); 92164426Ssam 93164426Ssam reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB)); 94164426Ssam reg &= ~GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_MASK); 95164426Ssam reg |= GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_ACT_LOW); 96164426Ssam GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB), reg); 97164426Ssam 98164426Ssam reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC)); 99164426Ssam reg &= ~GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_MASK); 100164426Ssam reg |= GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_ACT_LOW); 101164426Ssam GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC), reg); 102164426Ssam 103164426Ssam reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD)); 104164426Ssam reg &= ~GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_MASK); 105164426Ssam reg |= GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_ACT_LOW); 106164426Ssam GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD), reg); 107164426Ssam 108164426Ssam /* clear ISR */ 109164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR, 110164426Ssam (1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) | 111164426Ssam (1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD)); 112164426Ssam 113164426Ssam /* wait 1ms to satisfy "minimum reset assertion time" of the PCI spec */ 114164426Ssam DELAY(1000); 115164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); 116164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg | 117164426Ssam (0xf << GPCLKR_CLK0DC_SHIFT) | (0xf << GPCLKR_CLK0TC_SHIFT)); 118164426Ssam 119164426Ssam /* PCI Clock Enable */ 120164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); 121164426Ssam reg |= GPCLKR_MUX14; 122164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg | GPCLKR_MUX14); 123164426Ssam 124164426Ssam /* 125164426Ssam * wait 100us to satisfy "minimum reset assertion time from clock stable 126164426Ssam * requirement of the PCI spec 127164426Ssam */ 128164426Ssam DELAY(100); 129164426Ssam /* PCI Reset deassert */ 130164426Ssam reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); 131164426Ssam reg |= 1U << GPIO_PCI_RESET; 132164426Ssam GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg | (1U << GPIO_PCI_RESET)); 133164426Ssam pci_sc->sc_irq_rman.rm_type = RMAN_ARRAY; 134164426Ssam pci_sc->sc_irq_rman.rm_descr = "IXP425 PCI IRQs"; 135164426Ssam CTASSERT(PCI_INT_D < PCI_INT_A); 136164426Ssam /* XXX this overlaps the irq's setup in ixp425_attach */ 137164426Ssam if (rman_init(&pci_sc->sc_irq_rman) != 0 || 138164426Ssam rman_manage_region(&pci_sc->sc_irq_rman, PCI_INT_D, PCI_INT_A) != 0) 139164426Ssam panic("ixp425_md_attach: failed to set up IRQ rman"); 140164426Ssam} 141164426Ssam 142177456Ssam#define IXP425_MAX_DEV 5 143164426Ssam#define IXP425_MAX_LINE 4 144164426Ssam 145164426Ssamint 146164426Ssamixp425_md_route_interrupt(device_t bridge, device_t device, int pin) 147164426Ssam{ 148177456Ssam static int ixp425_pci_table[IXP425_MAX_DEV][IXP425_MAX_LINE] = { 149164426Ssam {PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D}, 150164426Ssam {PCI_INT_B, PCI_INT_C, PCI_INT_D, PCI_INT_A}, 151164426Ssam {PCI_INT_C, PCI_INT_D, PCI_INT_A, PCI_INT_B}, 152164426Ssam {PCI_INT_D, PCI_INT_A, PCI_INT_B, PCI_INT_C}, 153177456Ssam /* NB: for optional USB controller on Gateworks Avila */ 154177456Ssam {PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D}, 155164426Ssam }; 156164426Ssam int dev; 157164426Ssam 158164426Ssam dev = pci_get_slot(device); 159164426Ssam if (bootverbose) 160164426Ssam device_printf(bridge, "routing pin %d for %s\n", pin, 161164426Ssam device_get_nameunit(device)); 162164426Ssam if (pin >= 1 && pin <= IXP425_MAX_LINE && 163164426Ssam dev >= 1 && dev <= IXP425_MAX_DEV) { 164164426Ssam return (ixp425_pci_table[dev - 1][pin - 1]); 165164426Ssam } else 166164426Ssam printf("ixppcib: no mapping for %d/%d/%d\n", 167164426Ssam pci_get_bus(device), dev, pci_get_function(device)); 168164426Ssam 169164426Ssam return (-1); 170164426Ssam} 171