root/arch/mips/pci/pci-malta.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mips_pcibios_init

   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 }

/* [<][>][^][v][top][bottom][index][help] */