11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
3aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki *	All rights reserved.
4aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki *	Authors: Carsten Langgaard <carstenl@mips.com>
5aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki *		 Maciej W. Rozycki <macro@mips.com>
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  This program is free software; you can distribute it and/or modify it
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  under the terms of the GNU General Public License (Version 2) as
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  published by the Free Software Foundation.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  This program is distributed in the hope it will be useful, but WITHOUT
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  for more details.
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  You should have received a copy of the GNU General Public License along
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  with this program; if not, write to the Free Software Foundation, Inc.,
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MIPS boards specific PCI support.
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/gt64120.h>
307098f748283b4c056cca9c284c476b03f004ca12Chris Dearman#include <asm/gcmpregs.h>
31aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki#include <asm/mips-boards/generic.h>
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mips-boards/bonito64.h>
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mips-boards/msc01_pci.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct resource bonito64_mem_resource = {
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name	= "Bonito PCI MEM",
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.flags	= IORESOURCE_MEM,
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct resource bonito64_io_resource = {
41aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki	.name	= "Bonito PCI I/O",
42aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki	.start	= 0x00000000UL,
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.end	= 0x000fffffUL,
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.flags	= IORESOURCE_IO,
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct resource gt64120_mem_resource = {
48aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki	.name	= "GT-64120 PCI MEM",
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.flags	= IORESOURCE_MEM,
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct resource gt64120_io_resource = {
53aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki	.name	= "GT-64120 PCI I/O",
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.flags	= IORESOURCE_IO,
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct resource msc_mem_resource = {
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.name	= "MSC PCI MEM",
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.flags	= IORESOURCE_MEM,
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct resource msc_io_resource = {
63aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki	.name	= "MSC PCI I/O",
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.flags	= IORESOURCE_IO,
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern struct pci_ops bonito64_pci_ops;
68252161eccd1a44f32a506d0fedb424d4ff84e4dcYoichi Yuasaextern struct pci_ops gt64xxx_pci0_ops;
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern struct pci_ops msc_pci_ops;
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_controller bonito64_controller = {
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.pci_ops	= &bonito64_pci_ops,
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.io_resource	= &bonito64_io_resource,
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.mem_resource	= &bonito64_mem_resource,
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.io_offset	= 0x00000000UL,
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_controller gt64120_controller = {
79252161eccd1a44f32a506d0fedb424d4ff84e4dcYoichi Yuasa	.pci_ops	= &gt64xxx_pci0_ops,
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.io_resource	= &gt64120_io_resource,
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.mem_resource	= &gt64120_mem_resource,
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
84aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozyckistatic struct pci_controller msc_controller = {
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.pci_ops	= &msc_pci_ops,
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.io_resource	= &msc_io_resource,
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.mem_resource	= &msc_mem_resource,
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
90c83cfc9c9477d0bc0e0a1ba29dfc58e0d42b2fafRalf Baechlevoid __init mips_pcibios_init(void)
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct pci_controller *controller;
9367cac1eba7eee92e2b25c1e8e4737968dc7c8522Yoichi Yuasa	resource_size_t start, end, map, start1, end1, map1, map2, map3, mask;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
95b72c05262298cc2ac92edb657f5ea3a97ad5ea3dChris Dearman	switch (mips_revision_sconid) {
96b72c05262298cc2ac92edb657f5ea3a97ad5ea3dChris Dearman	case MIPS_REVISION_SCON_GT64120:
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * Due to a bug in the Galileo system controller, we need
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * to setup the PCI BAR for the Galileo internal registers.
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * This should be done in the bios/bootprom and will be
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * fixed in a later revision of YAMON (the MIPS boards
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * boot prom).
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		GT_WRITE(GT_PCI0_CFGADDR_OFS,
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
109aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			 GT_PCI0_CFGADDR_CONFIGEN_BIT);
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Perform the write */
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
114aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		/* Set up resource ranges from the controller's registers.  */
115aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		start = GT_READ(GT_PCI0M0LD_OFS);
116aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		end = GT_READ(GT_PCI0M0HD_OFS);
117aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		map = GT_READ(GT_PCI0M0REMAP_OFS);
118aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
119aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		start1 = GT_READ(GT_PCI0M1LD_OFS);
120aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		end1 = GT_READ(GT_PCI0M1HD_OFS);
121aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		map1 = GT_READ(GT_PCI0M1REMAP_OFS);
122aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
123aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		/* Cannot support multiple windows, use the wider.  */
124aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		if (end1 - start1 > end - start) {
125aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			start = start1;
126aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			end = end1;
127aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			map = map1;
128aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		}
129aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		mask = ~(start ^ end);
130aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki                /* We don't support remapping with a discontiguous mask.  */
131aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
132aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		       mask != ~((mask & -mask) - 1));
133aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_mem_resource.start = start;
134aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_mem_resource.end = end;
135aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_controller.mem_offset = (start & mask) - (map & mask);
136aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		/* Addresses are 36-bit, so do shifts in the destinations.  */
137aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
138aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
139aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
140aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
141aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki
142aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		start = GT_READ(GT_PCI0IOLD_OFS);
143aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		end = GT_READ(GT_PCI0IOHD_OFS);
144aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		map = GT_READ(GT_PCI0IOREMAP_OFS);
145aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
146aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		mask = ~(start ^ end);
147aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki                /* We don't support remapping with a discontiguous mask.  */
148aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
149aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		       mask != ~((mask & -mask) - 1));
150aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_io_resource.start = map & mask;
151aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_io_resource.end = (map & mask) | ~mask;
152aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_controller.io_offset = 0;
153aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		/* Addresses are 36-bit, so do shifts in the destinations.  */
154aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
155aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
156aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
157aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		controller = &gt64120_controller;
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
161b72c05262298cc2ac92edb657f5ea3a97ad5ea3dChris Dearman	case MIPS_REVISION_SCON_BONITO:
162aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		/* Set up resource ranges from the controller's registers.  */
163aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		map = BONITO_PCIMAP;
164aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
165aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		       BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
166aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
167aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		       BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
168aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
169aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		       BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
170aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		/* Combine as many adjacent windows as possible.  */
171aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		map = map1;
172aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		start = BONITO_PCILO0_BASE;
173aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		end = 1;
174aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		if (map3 == map2 + 1) {
175aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			map = map2;
176aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			start = BONITO_PCILO1_BASE;
177aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			end++;
178aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		}
179aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		if (map2 == map1 + 1) {
180aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			map = map1;
181aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			start = BONITO_PCILO0_BASE;
182aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			end++;
183aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		}
184aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		bonito64_mem_resource.start = start;
185aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		bonito64_mem_resource.end = start +
186aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki					    BONITO_PCIMAP_WINBASE(end) - 1;
187aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		bonito64_controller.mem_offset = start -
188aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki						 BONITO_PCIMAP_WINBASE(map);
189aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		controller = &bonito64_controller;
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
193b72c05262298cc2ac92edb657f5ea3a97ad5ea3dChris Dearman	case MIPS_REVISION_SCON_SOCIT:
194b72c05262298cc2ac92edb657f5ea3a97ad5ea3dChris Dearman	case MIPS_REVISION_SCON_ROCIT:
195b72c05262298cc2ac92edb657f5ea3a97ad5ea3dChris Dearman	case MIPS_REVISION_SCON_SOCITSC:
196b72c05262298cc2ac92edb657f5ea3a97ad5ea3dChris Dearman	case MIPS_REVISION_SCON_SOCITSCP:
197aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		/* Set up resource ranges from the controller's registers.  */
198aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		MSC_READ(MSC01_PCI_SC2PMBASL, start);
199aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
200aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		MSC_READ(MSC01_PCI_SC2PMMAPL, map);
201aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		msc_mem_resource.start = start & mask;
202aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		msc_mem_resource.end = (start & mask) | ~mask;
203aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		msc_controller.mem_offset = (start & mask) - (map & mask);
2047098f748283b4c056cca9c284c476b03f004ca12Chris Dearman#ifdef CONFIG_MIPS_CMP
2057098f748283b4c056cca9c284c476b03f004ca12Chris Dearman		if (gcmp_niocu())
2067098f748283b4c056cca9c284c476b03f004ca12Chris Dearman			gcmp_setregion(0, start, mask,
2077098f748283b4c056cca9c284c476b03f004ca12Chris Dearman				GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
2087098f748283b4c056cca9c284c476b03f004ca12Chris Dearman#endif
209aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		MSC_READ(MSC01_PCI_SC2PIOBASL, start);
210aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
211aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
212aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		msc_io_resource.start = map & mask;
213aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		msc_io_resource.end = (map & mask) | ~mask;
214aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		msc_controller.io_offset = 0;
215aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		ioport_resource.end = ~mask;
2167098f748283b4c056cca9c284c476b03f004ca12Chris Dearman#ifdef CONFIG_MIPS_CMP
2177098f748283b4c056cca9c284c476b03f004ca12Chris Dearman		if (gcmp_niocu())
2187098f748283b4c056cca9c284c476b03f004ca12Chris Dearman			gcmp_setregion(1, start, mask,
2197098f748283b4c056cca9c284c476b03f004ca12Chris Dearman				GCMP_GCB_GCMPB_CMDEFTGT_IOCU1);
2207098f748283b4c056cca9c284c476b03f004ca12Chris Dearman#endif
221aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		/* If ranges overlap I/O takes precedence.  */
222aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		start = start & mask;
223aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		end = start | ~mask;
224aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		if ((start >= msc_mem_resource.start &&
225aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		     start <= msc_mem_resource.end) ||
226aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		    (end >= msc_mem_resource.start &&
227aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		     end <= msc_mem_resource.end)) {
228aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			/* Use the larger space.  */
229aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			start = max(start, msc_mem_resource.start);
230aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			end = min(end, msc_mem_resource.end);
231aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			if (start - msc_mem_resource.start >=
232aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			    msc_mem_resource.end - end)
233aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki				msc_mem_resource.end = start - 1;
234aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki			else
235aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki				msc_mem_resource.start = end + 1;
236aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		}
237aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		controller = &msc_controller;
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
241c83cfc9c9477d0bc0e0a1ba29dfc58e0d42b2fafRalf Baechle		return;
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
244aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki	if (controller->io_resource->start < 0x00001000UL)	/* FIXME */
245aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki		controller->io_resource->start = 0x00001000UL;
246aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki
247aa0980b8090878bf42bc73a13d051a203a201d7dMaciej W. Rozycki	iomem_resource.end &= 0xfffffffffULL;			/* 64 GB */
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ioport_resource.end = controller->io_resource->end;
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2508faf2e6c201d95b780cd3b4674b7a55ede6dcbbbBen Hutchings	controller->io_map_base = mips_io_port_base;
2518faf2e6c201d95b780cd3b4674b7a55ede6dcbbbBen Hutchings
25249a89efbbbcc178a39555c43bd59a7593c429664Ralf Baechle	register_pci_controller(controller);
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
254a951f2829adba3f2945172b740528fce4366907dRalf Baechle
255a951f2829adba3f2945172b740528fce4366907dRalf Baechle/* Enable PCI 2.1 compatibility in PIIX4 */
256a951f2829adba3f2945172b740528fce4366907dRalf Baechlestatic void __init quirk_dlcsetup(struct pci_dev *dev)
257a951f2829adba3f2945172b740528fce4366907dRalf Baechle{
258a951f2829adba3f2945172b740528fce4366907dRalf Baechle	u8 odlc, ndlc;
259a951f2829adba3f2945172b740528fce4366907dRalf Baechle	(void) pci_read_config_byte(dev, 0x82, &odlc);
260a951f2829adba3f2945172b740528fce4366907dRalf Baechle	/* Enable passive releases and delayed transaction */
261a951f2829adba3f2945172b740528fce4366907dRalf Baechle	ndlc = odlc | 7;
262a951f2829adba3f2945172b740528fce4366907dRalf Baechle	(void) pci_write_config_byte(dev, 0x82, ndlc);
263a951f2829adba3f2945172b740528fce4366907dRalf Baechle}
264a951f2829adba3f2945172b740528fce4366907dRalf Baechle
265a951f2829adba3f2945172b740528fce4366907dRalf BaechleDECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
266a951f2829adba3f2945172b740528fce4366907dRalf Baechle	quirk_dlcsetup);
267