~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/pci/pci-malta.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
  4  *      All rights reserved.
  5  *      Authors: Carsten Langgaard <carstenl@mips.com>
  6  *               Maciej W. Rozycki <macro@mips.com>
  7  *
  8  * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
  9  *
 10  * MIPS boards specific PCI support.
 11  */
 12 #include <linux/types.h>
 13 #include <linux/pci.h>
 14 #include <linux/kernel.h>
 15 #include <linux/init.h>
 16 
 17 #include <asm/gt64120.h>
 18 #include <asm/mips-cps.h>
 19 #include <asm/mips-boards/generic.h>
 20 #include <asm/mips-boards/bonito64.h>
 21 #include <asm/mips-boards/msc01_pci.h>
 22 
 23 static struct resource bonito64_mem_resource = {
 24         .name   = "Bonito PCI MEM",
 25         .flags  = IORESOURCE_MEM,
 26 };
 27 
 28 static struct resource bonito64_io_resource = {
 29         .name   = "Bonito PCI I/O",
 30         .start  = 0x00000000UL,
 31         .end    = 0x000fffffUL,
 32         .flags  = IORESOURCE_IO,
 33 };
 34 
 35 static struct resource gt64120_mem_resource = {
 36         .name   = "GT-64120 PCI MEM",
 37         .flags  = IORESOURCE_MEM,
 38 };
 39 
 40 static struct resource gt64120_io_resource = {
 41         .name   = "GT-64120 PCI I/O",
 42         .flags  = IORESOURCE_IO,
 43 };
 44 
 45 static struct resource msc_mem_resource = {
 46         .name   = "MSC PCI MEM",
 47         .flags  = IORESOURCE_MEM,
 48 };
 49 
 50 static struct resource msc_io_resource = {
 51         .name   = "MSC PCI I/O",
 52         .flags  = IORESOURCE_IO,
 53 };
 54 
 55 extern struct pci_ops bonito64_pci_ops;
 56 extern struct pci_ops gt64xxx_pci0_ops;
 57 extern struct pci_ops msc_pci_ops;
 58 
 59 static struct pci_controller bonito64_controller = {
 60         .pci_ops        = &bonito64_pci_ops,
 61         .io_resource    = &bonito64_io_resource,
 62         .mem_resource   = &bonito64_mem_resource,
 63         .io_offset      = 0x00000000UL,
 64 };
 65 
 66 static struct pci_controller gt64120_controller = {
 67         .pci_ops        = &gt64xxx_pci0_ops,
 68         .io_resource    = &gt64120_io_resource,
 69         .mem_resource   = &gt64120_mem_resource,
 70 };
 71 
 72 static struct pci_controller msc_controller = {
 73         .pci_ops        = &msc_pci_ops,
 74         .io_resource    = &msc_io_resource,
 75         .mem_resource   = &msc_mem_resource,
 76 };
 77 
 78 void __init mips_pcibios_init(void)
 79 {
 80         struct pci_controller *controller;
 81         resource_size_t start, end, map, start1, end1, map1, map2, map3, mask;
 82 
 83         switch (mips_revision_sconid) {
 84         case MIPS_REVISION_SCON_GT64120:
 85                 /*
 86                  * Due to a bug in the Galileo system controller, we need
 87                  * to setup the PCI BAR for the Galileo internal registers.
 88                  * This should be done in the bios/bootprom and will be
 89                  * fixed in a later revision of YAMON (the MIPS boards
 90                  * boot prom).
 91                  */
 92                 GT_WRITE(GT_PCI0_CFGADDR_OFS,
 93                          (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
 94                          (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
 95                          (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
 96                          ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
 97                          GT_PCI0_CFGADDR_CONFIGEN_BIT);
 98 
 99                 /* Perform the write */
100                 GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
101 
102                 /* Set up resource ranges from the controller's registers.  */
103                 start = GT_READ(GT_PCI0M0LD_OFS);
104                 end = GT_READ(GT_PCI0M0HD_OFS);
105                 map = GT_READ(GT_PCI0M0REMAP_OFS);
106                 end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
107                 start1 = GT_READ(GT_PCI0M1LD_OFS);
108                 end1 = GT_READ(GT_PCI0M1HD_OFS);
109                 map1 = GT_READ(GT_PCI0M1REMAP_OFS);
110                 end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
111                 /* Cannot support multiple windows, use the wider.  */
112                 if (end1 - start1 > end - start) {
113                         start = start1;
114                         end = end1;
115                         map = map1;
116                 }
117                 mask = ~(start ^ end);
118                 /* We don't support remapping with a discontiguous mask.  */
119                 BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
120                        mask != ~((mask & -mask) - 1));
121                 gt64120_mem_resource.start = start;
122                 gt64120_mem_resource.end = end;
123                 gt64120_controller.mem_offset = (start & mask) - (map & mask);
124                 /* Addresses are 36-bit, so do shifts in the destinations.  */
125                 gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
126                 gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
127                 gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
128                 gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
129 
130                 start = GT_READ(GT_PCI0IOLD_OFS);
131                 end = GT_READ(GT_PCI0IOHD_OFS);
132                 map = GT_READ(GT_PCI0IOREMAP_OFS);
133                 end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
134                 mask = ~(start ^ end);
135                 /* We don't support remapping with a discontiguous mask.  */
136                 BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
137                        mask != ~((mask & -mask) - 1));
138                 gt64120_io_resource.start = map & mask;
139                 gt64120_io_resource.end = (map & mask) | ~mask;
140                 gt64120_controller.io_offset = 0;
141                 /* Addresses are 36-bit, so do shifts in the destinations.  */
142                 gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
143                 gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
144                 gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
145 
146                 controller = &gt64120_controller;
147                 break;
148 
149         case MIPS_REVISION_SCON_BONITO:
150                 /* Set up resource ranges from the controller's registers.  */
151                 map = BONITO_PCIMAP;
152                 map1 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO0) >>
153                        BONITO_PCIMAP_PCIMAP_LO0_SHIFT;
154                 map2 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO1) >>
155                        BONITO_PCIMAP_PCIMAP_LO1_SHIFT;
156                 map3 = (BONITO_PCIMAP & BONITO_PCIMAP_PCIMAP_LO2) >>
157                        BONITO_PCIMAP_PCIMAP_LO2_SHIFT;
158                 /* Combine as many adjacent windows as possible.  */
159                 map = map1;
160                 start = BONITO_PCILO0_BASE;
161                 end = 1;
162                 if (map3 == map2 + 1) {
163                         map = map2;
164                         start = BONITO_PCILO1_BASE;
165                         end++;
166                 }
167                 if (map2 == map1 + 1) {
168                         map = map1;
169                         start = BONITO_PCILO0_BASE;
170                         end++;
171                 }
172                 bonito64_mem_resource.start = start;
173                 bonito64_mem_resource.end = start +
174                                             BONITO_PCIMAP_WINBASE(end) - 1;
175                 bonito64_controller.mem_offset = start -
176                                                  BONITO_PCIMAP_WINBASE(map);
177 
178                 controller = &bonito64_controller;
179                 break;
180 
181         case MIPS_REVISION_SCON_SOCIT:
182         case MIPS_REVISION_SCON_ROCIT:
183         case MIPS_REVISION_SCON_SOCITSC:
184         case MIPS_REVISION_SCON_SOCITSCP:
185                 /* Set up resource ranges from the controller's registers.  */
186                 MSC_READ(MSC01_PCI_SC2PMBASL, start);
187                 MSC_READ(MSC01_PCI_SC2PMMSKL, mask);
188                 MSC_READ(MSC01_PCI_SC2PMMAPL, map);
189                 msc_mem_resource.start = start & mask;
190                 msc_mem_resource.end = (start & mask) | ~mask;
191                 msc_controller.mem_offset = (start & mask) - (map & mask);
192                 if (mips_cps_numiocu(0)) {
193                         write_gcr_reg0_base(start);
194                         write_gcr_reg0_mask(mask |
195                                             CM_GCR_REGn_MASK_CMTGT_IOCU0);
196                 }
197                 MSC_READ(MSC01_PCI_SC2PIOBASL, start);
198                 MSC_READ(MSC01_PCI_SC2PIOMSKL, mask);
199                 MSC_READ(MSC01_PCI_SC2PIOMAPL, map);
200                 msc_io_resource.start = map & mask;
201                 msc_io_resource.end = (map & mask) | ~mask;
202                 msc_controller.io_offset = 0;
203                 ioport_resource.end = ~mask;
204                 if (mips_cps_numiocu(0)) {
205                         write_gcr_reg1_base(start);
206                         write_gcr_reg1_mask(mask |
207                                             CM_GCR_REGn_MASK_CMTGT_IOCU0);
208                 }
209                 /* If ranges overlap I/O takes precedence.  */
210                 start = start & mask;
211                 end = start | ~mask;
212                 if ((start >= msc_mem_resource.start &&
213                      start <= msc_mem_resource.end) ||
214                     (end >= msc_mem_resource.start &&
215                      end <= msc_mem_resource.end)) {
216                         /* Use the larger space.  */
217                         start = max(start, msc_mem_resource.start);
218                         end = min(end, msc_mem_resource.end);
219                         if (start - msc_mem_resource.start >=
220                             msc_mem_resource.end - end)
221                                 msc_mem_resource.end = start - 1;
222                         else
223                                 msc_mem_resource.start = end + 1;
224                 }
225 
226                 controller = &msc_controller;
227                 break;
228         default:
229                 return;
230         }
231 
232         /* PIIX4 ACPI starts at 0x1000 */
233         if (controller->io_resource->start < 0x00001000UL)
234                 controller->io_resource->start = 0x00001000UL;
235 
236         iomem_resource.end &= 0xfffffffffULL;                   /* 64 GB */
237         ioport_resource.end = controller->io_resource->end;
238 
239         controller->io_map_base = mips_io_port_base;
240 
241         register_pci_controller(controller);
242 }
243 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php