Home | History | Annotate | Line # | Download | only in nslu2
nslu2_pci.c revision 1.1.2.2
      1 /*      $NetBSD: nslu2_pci.c,v 1.1.2.2 2006/03/01 09:27:46 yamt Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2006 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Steve C. Woodford.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 /*
     39  * Copyright (c) 2003
     40  *      Ichiro FUKUHARA <ichiro (at) ichiro.org>.
     41  * All rights reserved.
     42  *
     43  * Redistribution and use in source and binary forms, with or without
     44  * modification, are permitted provided that the following conditions
     45  * are met:
     46  * 1. Redistributions of source code must retain the above copyright
     47  *    notice, this list of conditions and the following disclaimer.
     48  * 2. Redistributions in binary form must reproduce the above copyright
     49  *    notice, this list of conditions and the following disclaimer in the
     50  *    documentation and/or other materials provided with the distribution.
     51  * 3. All advertising materials mentioning features or use of this software
     52  *    must display the following acknowledgement:
     53  *      This product includes software developed by Ichiro FUKUHARA.
     54  * 4. The name of the company nor the name of the author may be used to
     55  *    endorse or promote products derived from this software without specific
     56  *    prior written permission.
     57  *
     58  * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
     59  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     60  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     61  * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
     62  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  * SUCH DAMAGE.
     69  */
     70 
     71 #include <sys/cdefs.h>
     72 __KERNEL_RCSID(0, "$NetBSD: nslu2_pci.c,v 1.1.2.2 2006/03/01 09:27:46 yamt Exp $");
     73 
     74 /*
     75  * Linksys NSLU2 PCI support.
     76  */
     77 
     78 #include <sys/param.h>
     79 #include <sys/systm.h>
     80 #include <sys/device.h>
     81 
     82 #include <arm/xscale/ixp425reg.h>
     83 #include <arm/xscale/ixp425var.h>
     84 
     85 #include <dev/pci/pcivar.h>
     86 
     87 #include <evbarm/nslu2/nslu2reg.h>
     88 
     89 static int
     90 nslu2_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
     91 {
     92 
     93 	KASSERT(pa->pa_bus == 0 && pa->pa_device == 1);
     94 
     95 	switch (pa->pa_function) {
     96 	case 0:
     97 		*ihp = PCI_INT_A;
     98 		break;
     99 
    100 	case 1:
    101 		*ihp = PCI_INT_B;
    102 		break;
    103 
    104 	case 2:
    105 		*ihp = PCI_INT_C;
    106 		break;
    107 
    108 	default:
    109 		return (1);
    110 	}
    111 
    112 	return (0);
    113 }
    114 
    115 static const char *
    116 nslu2_pci_intr_string(void *v, pci_intr_handle_t ih)
    117 {
    118 
    119 	switch (ih) {
    120 	case PCI_INT_A:
    121 		return ("INTA");
    122 
    123 	case PCI_INT_B:
    124 		return ("INTB");
    125 
    126 	case PCI_INT_C:
    127 		return ("INTC");
    128 	}
    129 
    130 	return (NULL);
    131 }
    132 
    133 static const struct evcnt *
    134 nslu2_pci_intr_evcnt(void *v, pci_intr_handle_t ih)
    135 {
    136 
    137 	return (NULL);
    138 }
    139 
    140 static void *
    141 nslu2_pci_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
    142     int (*func)(void *), void *arg)
    143 {
    144 
    145 	return (ixp425_intr_establish(ih, ipl, func, arg));
    146 }
    147 
    148 static void
    149 nslu2_pci_intr_disestablish(void *v, void *cookie)
    150 {
    151 
    152 	ixp425_intr_disestablish(cookie);
    153 }
    154 
    155 void
    156 ixp425_md_pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin,
    157     int swiz, int *ilinep)
    158 {
    159 
    160 	KASSERT(bus == 0 && dev == 1);
    161 
    162 	*ilinep = ((swiz + pin - 1) & 3);
    163 }
    164 
    165 void
    166 ixp425_md_pci_init(struct ixp425_softc *sc)
    167 {
    168 	pci_chipset_tag_t pc = &sc->ia_pci_chipset;
    169 	u_int32_t reg;
    170 
    171 	pc->pc_intr_v = sc;
    172 	pc->pc_intr_map = nslu2_pci_intr_map;
    173 	pc->pc_intr_string = nslu2_pci_intr_string;
    174 	pc->pc_intr_evcnt = nslu2_pci_intr_evcnt;
    175 	pc->pc_intr_establish = nslu2_pci_intr_establish;
    176 	pc->pc_intr_disestablish = nslu2_pci_intr_disestablish;
    177 
    178 	/* PCI Reset Assert */
    179 	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR);
    180 	reg &= ~(1u << GPIO_PCI_RESET);
    181 	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg);
    182 
    183 	/* PCI Clock Disable */
    184 	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
    185 	reg &= ~GPCLKR_MUX14;
    186 	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg);
    187 
    188 	/*
    189 	 * Set GPIO Direction
    190 	 *	Output: PCI_CLK, PCI_RESET
    191 	 *	Input:  PCI_INTA, PCI_INTB, PCI_INTC
    192 	 */
    193 	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER);
    194 	reg &= ~((1u << GPIO_PCI_CLK) | (1u << GPIO_PCI_RESET));
    195 	reg |= (1u << GPIO_PCI_INTA) | (1u << GPIO_PCI_INTB) |
    196 	    (1u << GPIO_PCI_INTC);
    197 	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, reg);
    198 
    199 	/*
    200 	 * Set GPIO interrupt type
    201 	 *      PCI_INT_A, PCI_INTB, PCI_INT_C: Active Low
    202 	 */
    203 	reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA));
    204 	reg &= ~GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_MASK);
    205 	reg |= GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_ACT_LOW);
    206 	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA), reg);
    207 
    208 	reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB));
    209 	reg &= ~GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_MASK);
    210 	reg |= GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_ACT_LOW);
    211 	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB), reg);
    212 
    213 	reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC));
    214 	reg &= ~GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_MASK);
    215 	reg |= GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_ACT_LOW);
    216 	GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC), reg);
    217 
    218 	/* Clear ISR */
    219 	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR, (1u << GPIO_PCI_INTA) |
    220 	    (1u << GPIO_PCI_INTB) | (1u << GPIO_PCI_INTC));
    221 
    222 	/* Wait 1ms to satisfy "minimum reset assertion time" of the PCI spec */
    223 	DELAY(1000);
    224 	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
    225 	reg |= (0xf << GPCLKR_CLK0DC_SHIFT) | (0xf << GPCLKR_CLK0TC_SHIFT);
    226 	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg);
    227 
    228 	/* PCI Clock Enable */
    229 	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
    230 	reg |= GPCLKR_MUX14;
    231 	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg);
    232 
    233 	/*
    234 	 * Wait 100us to satisfy "minimum reset assertion time from clock stable
    235 	 * requirement of the PCI spec
    236 	 */
    237 	DELAY(100);
    238         /* PCI Reset deassert */
    239 	reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR);
    240 	reg |= 1u << GPIO_PCI_RESET;
    241 	GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg);
    242 
    243 	/*
    244 	 * AHB->PCI address translation
    245 	 *	PCI Memory Map allocation in 0x48000000 (64MB)
    246 	 *	see. IXP425_PCI_MEM_HWBASE
    247 	 */
    248 	PCI_CSR_WRITE_4(sc, PCI_PCIMEMBASE, 0x48494a4b);
    249 
    250 	/*
    251 	 * PCI->AHB address translation
    252 	 * 	begin at the physical memory start + OFFSET
    253 	 */
    254 #define	AHB_OFFSET	0x10000000UL
    255 	reg  = (AHB_OFFSET + 0x00000000) >> 0;
    256 	reg |= (AHB_OFFSET + 0x01000000) >> 8;
    257 	reg |= (AHB_OFFSET + 0x02000000) >> 16;
    258 	reg |= (AHB_OFFSET + 0x03000000) >> 24;
    259 	PCI_CSR_WRITE_4(sc, PCI_AHBMEMBASE, reg);
    260 
    261 	/* Write Mapping registers PCI Configuration Registers */
    262 	/* Base Address 0 - 3 */
    263 	ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR0, AHB_OFFSET + 0x00000000);
    264 	ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR1, AHB_OFFSET + 0x01000000);
    265 	ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR2, AHB_OFFSET + 0x02000000);
    266 	ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR3, AHB_OFFSET + 0x03000000);
    267 
    268 	/* Base Address 4 */
    269 	ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR4, 0xffffffff);
    270 
    271 	/* Base Address 5 */
    272 	ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR5, 0x00000000);
    273 
    274 	/* Assert some PCI errors */
    275 	PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_AHBE | ISR_PPE | ISR_PFE | ISR_PSE);
    276 
    277 	/*
    278 	 * Set up byte lane swapping between little-endian PCI
    279 	 * and the big-endian AHB bus
    280 	 */
    281 	PCI_CSR_WRITE_4(sc, PCI_CSR, CSR_IC | CSR_ABE | CSR_PDS);
    282 
    283 	/*
    284 	 * Enable bus mastering and I/O,memory access
    285 	 */
    286 	ixp425_pci_conf_reg_write(sc, PCI_COMMAND_STATUS_REG,
    287 		PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
    288 		PCI_COMMAND_MASTER_ENABLE);
    289 
    290 	/*
    291 	 * Wait some more to ensure PCI devices have stabilised.
    292 	 */
    293 	DELAY(50000);
    294 }
    295