LCOV - code coverage report
Current view: top level - arch/x86/kernel - early-quirks.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 31 261 11.9 %
Date: 2022-04-01 14:17:54 Functions: 3 32 9.4 %
Branches: 20 112 17.9 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /* Various workarounds for chipset bugs.
       3                 :            :    This code runs very early and can't use the regular PCI subsystem
       4                 :            :    The entries are keyed to PCI bridges which usually identify chipsets
       5                 :            :    uniquely.
       6                 :            :    This is only for whole classes of chipsets with specific problems which
       7                 :            :    need early invasive action (e.g. before the timers are initialized).
       8                 :            :    Most PCI device specific workarounds can be done later and should be
       9                 :            :    in standard PCI quirks
      10                 :            :    Mainboard specific bugs should be handled by DMI entries.
      11                 :            :    CPU specific bugs in setup.c */
      12                 :            : 
      13                 :            : #include <linux/pci.h>
      14                 :            : #include <linux/acpi.h>
      15                 :            : #include <linux/delay.h>
      16                 :            : #include <linux/pci_ids.h>
      17                 :            : #include <linux/bcma/bcma.h>
      18                 :            : #include <linux/bcma/bcma_regs.h>
      19                 :            : #include <linux/platform_data/x86/apple.h>
      20                 :            : #include <drm/i915_drm.h>
      21                 :            : #include <asm/pci-direct.h>
      22                 :            : #include <asm/dma.h>
      23                 :            : #include <asm/io_apic.h>
      24                 :            : #include <asm/apic.h>
      25                 :            : #include <asm/hpet.h>
      26                 :            : #include <asm/iommu.h>
      27                 :            : #include <asm/gart.h>
      28                 :            : #include <asm/irq_remapping.h>
      29                 :            : #include <asm/early_ioremap.h>
      30                 :            : 
      31                 :          0 : static void __init fix_hypertransport_config(int num, int slot, int func)
      32                 :            : {
      33                 :          0 :         u32 htcfg;
      34                 :            :         /*
      35                 :            :          * we found a hypertransport bus
      36                 :            :          * make sure that we are broadcasting
      37                 :            :          * interrupts to all cpus on the ht bus
      38                 :            :          * if we're using extended apic ids
      39                 :            :          */
      40                 :          0 :         htcfg = read_pci_config(num, slot, func, 0x68);
      41         [ #  # ]:          0 :         if (htcfg & (1 << 18)) {
      42                 :          0 :                 printk(KERN_INFO "Detected use of extended apic ids "
      43                 :            :                                  "on hypertransport bus\n");
      44         [ #  # ]:          0 :                 if ((htcfg & (1 << 17)) == 0) {
      45                 :          0 :                         printk(KERN_INFO "Enabling hypertransport extended "
      46                 :            :                                          "apic interrupt broadcast\n");
      47                 :          0 :                         printk(KERN_INFO "Note this is a bios bug, "
      48                 :            :                                          "please contact your hw vendor\n");
      49                 :          0 :                         htcfg |= (1 << 17);
      50                 :          0 :                         write_pci_config(num, slot, func, 0x68, htcfg);
      51                 :            :                 }
      52                 :            :         }
      53                 :            : 
      54                 :            : 
      55                 :          0 : }
      56                 :            : 
      57                 :          0 : static void __init via_bugs(int  num, int slot, int func)
      58                 :            : {
      59                 :            : #ifdef CONFIG_GART_IOMMU
      60                 :            :         if ((max_pfn > MAX_DMA32_PFN ||  force_iommu) &&
      61                 :            :             !gart_iommu_aperture_allowed) {
      62                 :            :                 printk(KERN_INFO
      63                 :            :                        "Looks like a VIA chipset. Disabling IOMMU."
      64                 :            :                        " Override with iommu=allowed\n");
      65                 :            :                 gart_iommu_aperture_disabled = 1;
      66                 :            :         }
      67                 :            : #endif
      68                 :          0 : }
      69                 :            : 
      70                 :            : #ifdef CONFIG_ACPI
      71                 :            : #ifdef CONFIG_X86_IO_APIC
      72                 :            : 
      73                 :          0 : static int __init nvidia_hpet_check(struct acpi_table_header *header)
      74                 :            : {
      75                 :          0 :         return 0;
      76                 :            : }
      77                 :            : #endif /* CONFIG_X86_IO_APIC */
      78                 :            : #endif /* CONFIG_ACPI */
      79                 :            : 
      80                 :          0 : static void __init nvidia_bugs(int num, int slot, int func)
      81                 :            : {
      82                 :            : #ifdef CONFIG_ACPI
      83                 :            : #ifdef CONFIG_X86_IO_APIC
      84                 :            :         /*
      85                 :            :          * Only applies to Nvidia root ports (bus 0) and not to
      86                 :            :          * Nvidia graphics cards with PCI ports on secondary buses.
      87                 :            :          */
      88         [ #  # ]:          0 :         if (num)
      89                 :            :                 return;
      90                 :            : 
      91                 :            :         /*
      92                 :            :          * All timer overrides on Nvidia are
      93                 :            :          * wrong unless HPET is enabled.
      94                 :            :          * Unfortunately that's not true on many Asus boards.
      95                 :            :          * We don't know yet how to detect this automatically, but
      96                 :            :          * at least allow a command line override.
      97                 :            :          */
      98         [ #  # ]:          0 :         if (acpi_use_timer_override)
      99                 :            :                 return;
     100                 :            : 
     101         [ #  # ]:          0 :         if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check)) {
     102                 :          0 :                 acpi_skip_timer_override = 1;
     103                 :          0 :                 printk(KERN_INFO "Nvidia board "
     104                 :            :                        "detected. Ignoring ACPI "
     105                 :            :                        "timer override.\n");
     106                 :          0 :                 printk(KERN_INFO "If you got timer trouble "
     107                 :            :                         "try acpi_use_timer_override\n");
     108                 :            :         }
     109                 :            : #endif
     110                 :            : #endif
     111                 :            :         /* RED-PEN skip them on mptables too? */
     112                 :            : 
     113                 :            : }
     114                 :            : 
     115                 :            : #if defined(CONFIG_ACPI) && defined(CONFIG_X86_IO_APIC)
     116                 :          0 : static u32 __init ati_ixp4x0_rev(int num, int slot, int func)
     117                 :            : {
     118                 :          0 :         u32 d;
     119                 :          0 :         u8  b;
     120                 :            : 
     121                 :          0 :         b = read_pci_config_byte(num, slot, func, 0xac);
     122                 :          0 :         b &= ~(1<<5);
     123                 :          0 :         write_pci_config_byte(num, slot, func, 0xac, b);
     124                 :            : 
     125                 :          0 :         d = read_pci_config(num, slot, func, 0x70);
     126                 :          0 :         d |= 1<<8;
     127                 :          0 :         write_pci_config(num, slot, func, 0x70, d);
     128                 :            : 
     129                 :          0 :         d = read_pci_config(num, slot, func, 0x8);
     130                 :          0 :         d &= 0xff;
     131                 :          0 :         return d;
     132                 :            : }
     133                 :            : 
     134                 :          0 : static void __init ati_bugs(int num, int slot, int func)
     135                 :            : {
     136                 :          0 :         u32 d;
     137                 :          0 :         u8  b;
     138                 :            : 
     139         [ #  # ]:          0 :         if (acpi_use_timer_override)
     140                 :            :                 return;
     141                 :            : 
     142                 :          0 :         d = ati_ixp4x0_rev(num, slot, func);
     143         [ #  # ]:          0 :         if (d  < 0x82)
     144                 :          0 :                 acpi_skip_timer_override = 1;
     145                 :            :         else {
     146                 :            :                 /* check for IRQ0 interrupt swap */
     147                 :          0 :                 outb(0x72, 0xcd6); b = inb(0xcd7);
     148         [ #  # ]:          0 :                 if (!(b & 0x2))
     149                 :          0 :                         acpi_skip_timer_override = 1;
     150                 :            :         }
     151                 :            : 
     152         [ #  # ]:          0 :         if (acpi_skip_timer_override) {
     153                 :          0 :                 printk(KERN_INFO "SB4X0 revision 0x%x\n", d);
     154                 :          0 :                 printk(KERN_INFO "Ignoring ACPI timer override.\n");
     155                 :          0 :                 printk(KERN_INFO "If you got timer trouble "
     156                 :            :                        "try acpi_use_timer_override\n");
     157                 :            :         }
     158                 :            : }
     159                 :            : 
     160                 :          0 : static u32 __init ati_sbx00_rev(int num, int slot, int func)
     161                 :            : {
     162                 :          0 :         u32 d;
     163                 :            : 
     164                 :          0 :         d = read_pci_config(num, slot, func, 0x8);
     165                 :          0 :         d &= 0xff;
     166                 :            : 
     167                 :          0 :         return d;
     168                 :            : }
     169                 :            : 
     170                 :          0 : static void __init ati_bugs_contd(int num, int slot, int func)
     171                 :            : {
     172                 :          0 :         u32 d, rev;
     173                 :            : 
     174                 :          0 :         rev = ati_sbx00_rev(num, slot, func);
     175         [ #  # ]:          0 :         if (rev >= 0x40)
     176                 :          0 :                 acpi_fix_pin2_polarity = 1;
     177                 :            : 
     178                 :            :         /*
     179                 :            :          * SB600: revisions 0x11, 0x12, 0x13, 0x14, ...
     180                 :            :          * SB700: revisions 0x39, 0x3a, ...
     181                 :            :          * SB800: revisions 0x40, 0x41, ...
     182                 :            :          */
     183         [ #  # ]:          0 :         if (rev >= 0x39)
     184                 :            :                 return;
     185                 :            : 
     186         [ #  # ]:          0 :         if (acpi_use_timer_override)
     187                 :            :                 return;
     188                 :            : 
     189                 :            :         /* check for IRQ0 interrupt swap */
     190                 :          0 :         d = read_pci_config(num, slot, func, 0x64);
     191         [ #  # ]:          0 :         if (!(d & (1<<14)))
     192                 :          0 :                 acpi_skip_timer_override = 1;
     193                 :            : 
     194         [ #  # ]:          0 :         if (acpi_skip_timer_override) {
     195                 :          0 :                 printk(KERN_INFO "SB600 revision 0x%x\n", rev);
     196                 :          0 :                 printk(KERN_INFO "Ignoring ACPI timer override.\n");
     197                 :          0 :                 printk(KERN_INFO "If you got timer trouble "
     198                 :            :                        "try acpi_use_timer_override\n");
     199                 :            :         }
     200                 :            : }
     201                 :            : #else
     202                 :            : static void __init ati_bugs(int num, int slot, int func)
     203                 :            : {
     204                 :            : }
     205                 :            : 
     206                 :            : static void __init ati_bugs_contd(int num, int slot, int func)
     207                 :            : {
     208                 :            : }
     209                 :            : #endif
     210                 :            : 
     211                 :          0 : static void __init intel_remapping_check(int num, int slot, int func)
     212                 :            : {
     213                 :          0 :         u8 revision;
     214                 :          0 :         u16 device;
     215                 :            : 
     216                 :          0 :         device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID);
     217                 :          0 :         revision = read_pci_config_byte(num, slot, func, PCI_REVISION_ID);
     218                 :            : 
     219                 :            :         /*
     220                 :            :          * Revision <= 13 of all triggering devices id in this quirk
     221                 :            :          * have a problem draining interrupts when irq remapping is
     222                 :            :          * enabled, and should be flagged as broken. Additionally
     223                 :            :          * revision 0x22 of device id 0x3405 has this problem.
     224                 :            :          */
     225                 :          0 :         if (revision <= 0x13)
     226                 :            :                 set_irq_remapping_broken();
     227                 :            :         else if (device == 0x3405 && revision == 0x22)
     228                 :            :                 set_irq_remapping_broken();
     229                 :          0 : }
     230                 :            : 
     231                 :            : /*
     232                 :            :  * Systems with Intel graphics controllers set aside memory exclusively
     233                 :            :  * for gfx driver use.  This memory is not marked in the E820 as reserved
     234                 :            :  * or as RAM, and so is subject to overlap from E820 manipulation later
     235                 :            :  * in the boot process.  On some systems, MMIO space is allocated on top,
     236                 :            :  * despite the efforts of the "RAM buffer" approach, which simply rounds
     237                 :            :  * memory boundaries up to 64M to try to catch space that may decode
     238                 :            :  * as RAM and so is not suitable for MMIO.
     239                 :            :  */
     240                 :            : 
     241                 :            : #define KB(x)   ((x) * 1024UL)
     242                 :            : #define MB(x)   (KB (KB (x)))
     243                 :            : 
     244                 :          0 : static resource_size_t __init i830_tseg_size(void)
     245                 :            : {
     246                 :          0 :         u8 esmramc = read_pci_config_byte(0, 0, 0, I830_ESMRAMC);
     247                 :            : 
     248         [ #  # ]:          0 :         if (!(esmramc & TSEG_ENABLE))
     249                 :            :                 return 0;
     250                 :            : 
     251         [ #  # ]:          0 :         if (esmramc & I830_TSEG_SIZE_1M)
     252                 :            :                 return MB(1);
     253                 :            :         else
     254                 :          0 :                 return KB(512);
     255                 :            : }
     256                 :            : 
     257                 :          0 : static resource_size_t __init i845_tseg_size(void)
     258                 :            : {
     259                 :          0 :         u8 esmramc = read_pci_config_byte(0, 0, 0, I845_ESMRAMC);
     260                 :          0 :         u8 tseg_size = esmramc & I845_TSEG_SIZE_MASK;
     261                 :            : 
     262         [ #  # ]:          0 :         if (!(esmramc & TSEG_ENABLE))
     263                 :            :                 return 0;
     264                 :            : 
     265      [ #  #  # ]:          0 :         switch (tseg_size) {
     266                 :            :         case I845_TSEG_SIZE_512K:       return KB(512);
     267                 :          0 :         case I845_TSEG_SIZE_1M:         return MB(1);
     268                 :            :         default:
     269                 :          0 :                 WARN(1, "Unknown ESMRAMC value: %x!\n", esmramc);
     270                 :            :         }
     271                 :          0 :         return 0;
     272                 :            : }
     273                 :            : 
     274                 :          0 : static resource_size_t __init i85x_tseg_size(void)
     275                 :            : {
     276                 :          0 :         u8 esmramc = read_pci_config_byte(0, 0, 0, I85X_ESMRAMC);
     277                 :            : 
     278         [ #  # ]:          0 :         if (!(esmramc & TSEG_ENABLE))
     279                 :          0 :                 return 0;
     280                 :            : 
     281                 :            :         return MB(1);
     282                 :            : }
     283                 :            : 
     284                 :          0 : static resource_size_t __init i830_mem_size(void)
     285                 :            : {
     286                 :          0 :         return read_pci_config_byte(0, 0, 0, I830_DRB3) * MB(32);
     287                 :            : }
     288                 :            : 
     289                 :          0 : static resource_size_t __init i85x_mem_size(void)
     290                 :            : {
     291                 :          0 :         return read_pci_config_byte(0, 0, 1, I85X_DRB3) * MB(32);
     292                 :            : }
     293                 :            : 
     294                 :            : /*
     295                 :            :  * On 830/845/85x the stolen memory base isn't available in any
     296                 :            :  * register. We need to calculate it as TOM-TSEG_SIZE-stolen_size.
     297                 :            :  */
     298                 :          0 : static resource_size_t __init i830_stolen_base(int num, int slot, int func,
     299                 :            :                                                resource_size_t stolen_size)
     300                 :            : {
     301                 :          0 :         return i830_mem_size() - i830_tseg_size() - stolen_size;
     302                 :            : }
     303                 :            : 
     304                 :          0 : static resource_size_t __init i845_stolen_base(int num, int slot, int func,
     305                 :            :                                                resource_size_t stolen_size)
     306                 :            : {
     307                 :          0 :         return i830_mem_size() - i845_tseg_size() - stolen_size;
     308                 :            : }
     309                 :            : 
     310                 :          0 : static resource_size_t __init i85x_stolen_base(int num, int slot, int func,
     311                 :            :                                                resource_size_t stolen_size)
     312                 :            : {
     313                 :          0 :         return i85x_mem_size() - i85x_tseg_size() - stolen_size;
     314                 :            : }
     315                 :            : 
     316                 :          0 : static resource_size_t __init i865_stolen_base(int num, int slot, int func,
     317                 :            :                                                resource_size_t stolen_size)
     318                 :            : {
     319                 :          0 :         u16 toud = 0;
     320                 :            : 
     321                 :          0 :         toud = read_pci_config_16(0, 0, 0, I865_TOUD);
     322                 :            : 
     323                 :          0 :         return toud * KB(64) + i845_tseg_size();
     324                 :            : }
     325                 :            : 
     326                 :          0 : static resource_size_t __init gen3_stolen_base(int num, int slot, int func,
     327                 :            :                                                resource_size_t stolen_size)
     328                 :            : {
     329                 :          0 :         u32 bsm;
     330                 :            : 
     331                 :            :         /* Almost universally we can find the Graphics Base of Stolen Memory
     332                 :            :          * at register BSM (0x5c) in the igfx configuration space. On a few
     333                 :            :          * (desktop) machines this is also mirrored in the bridge device at
     334                 :            :          * different locations, or in the MCHBAR.
     335                 :            :          */
     336                 :          0 :         bsm = read_pci_config(num, slot, func, INTEL_BSM);
     337                 :            : 
     338                 :          0 :         return bsm & INTEL_BSM_MASK;
     339                 :            : }
     340                 :            : 
     341                 :          0 : static resource_size_t __init gen11_stolen_base(int num, int slot, int func,
     342                 :            :                                                 resource_size_t stolen_size)
     343                 :            : {
     344                 :          0 :         u64 bsm;
     345                 :            : 
     346                 :          0 :         bsm = read_pci_config(num, slot, func, INTEL_GEN11_BSM_DW0);
     347                 :          0 :         bsm &= INTEL_BSM_MASK;
     348                 :          0 :         bsm |= (u64)read_pci_config(num, slot, func, INTEL_GEN11_BSM_DW1) << 32;
     349                 :            : 
     350                 :          0 :         return bsm;
     351                 :            : }
     352                 :            : 
     353                 :          0 : static resource_size_t __init i830_stolen_size(int num, int slot, int func)
     354                 :            : {
     355                 :          0 :         u16 gmch_ctrl;
     356                 :          0 :         u16 gms;
     357                 :            : 
     358                 :          0 :         gmch_ctrl = read_pci_config_16(0, 0, 0, I830_GMCH_CTRL);
     359                 :          0 :         gms = gmch_ctrl & I830_GMCH_GMS_MASK;
     360                 :            : 
     361   [ #  #  #  #  :          0 :         switch (gms) {
                      # ]
     362                 :            :         case I830_GMCH_GMS_STOLEN_512:  return KB(512);
     363                 :          0 :         case I830_GMCH_GMS_STOLEN_1024: return MB(1);
     364                 :          0 :         case I830_GMCH_GMS_STOLEN_8192: return MB(8);
     365                 :            :         /* local memory isn't part of the normal address space */
     366                 :          0 :         case I830_GMCH_GMS_LOCAL:       return 0;
     367                 :            :         default:
     368                 :          0 :                 WARN(1, "Unknown GMCH_CTRL value: %x!\n", gmch_ctrl);
     369                 :            :         }
     370                 :            : 
     371                 :          0 :         return 0;
     372                 :            : }
     373                 :            : 
     374                 :          0 : static resource_size_t __init gen3_stolen_size(int num, int slot, int func)
     375                 :            : {
     376                 :          0 :         u16 gmch_ctrl;
     377                 :          0 :         u16 gms;
     378                 :            : 
     379                 :          0 :         gmch_ctrl = read_pci_config_16(0, 0, 0, I830_GMCH_CTRL);
     380                 :          0 :         gms = gmch_ctrl & I855_GMCH_GMS_MASK;
     381                 :            : 
     382   [ #  #  #  #  :          0 :         switch (gms) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     383                 :            :         case I855_GMCH_GMS_STOLEN_1M:   return MB(1);
     384                 :          0 :         case I855_GMCH_GMS_STOLEN_4M:   return MB(4);
     385                 :          0 :         case I855_GMCH_GMS_STOLEN_8M:   return MB(8);
     386                 :          0 :         case I855_GMCH_GMS_STOLEN_16M:  return MB(16);
     387                 :          0 :         case I855_GMCH_GMS_STOLEN_32M:  return MB(32);
     388                 :          0 :         case I915_GMCH_GMS_STOLEN_48M:  return MB(48);
     389                 :          0 :         case I915_GMCH_GMS_STOLEN_64M:  return MB(64);
     390                 :          0 :         case G33_GMCH_GMS_STOLEN_128M:  return MB(128);
     391                 :          0 :         case G33_GMCH_GMS_STOLEN_256M:  return MB(256);
     392                 :          0 :         case INTEL_GMCH_GMS_STOLEN_96M: return MB(96);
     393                 :          0 :         case INTEL_GMCH_GMS_STOLEN_160M:return MB(160);
     394                 :          0 :         case INTEL_GMCH_GMS_STOLEN_224M:return MB(224);
     395                 :          0 :         case INTEL_GMCH_GMS_STOLEN_352M:return MB(352);
     396                 :            :         default:
     397                 :          0 :                 WARN(1, "Unknown GMCH_CTRL value: %x!\n", gmch_ctrl);
     398                 :            :         }
     399                 :            : 
     400                 :          0 :         return 0;
     401                 :            : }
     402                 :            : 
     403                 :          0 : static resource_size_t __init gen6_stolen_size(int num, int slot, int func)
     404                 :            : {
     405                 :          0 :         u16 gmch_ctrl;
     406                 :          0 :         u16 gms;
     407                 :            : 
     408                 :          0 :         gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL);
     409                 :          0 :         gms = (gmch_ctrl >> SNB_GMCH_GMS_SHIFT) & SNB_GMCH_GMS_MASK;
     410                 :            : 
     411                 :          0 :         return gms * MB(32);
     412                 :            : }
     413                 :            : 
     414                 :          0 : static resource_size_t __init gen8_stolen_size(int num, int slot, int func)
     415                 :            : {
     416                 :          0 :         u16 gmch_ctrl;
     417                 :          0 :         u16 gms;
     418                 :            : 
     419                 :          0 :         gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL);
     420                 :          0 :         gms = (gmch_ctrl >> BDW_GMCH_GMS_SHIFT) & BDW_GMCH_GMS_MASK;
     421                 :            : 
     422                 :          0 :         return gms * MB(32);
     423                 :            : }
     424                 :            : 
     425                 :          0 : static resource_size_t __init chv_stolen_size(int num, int slot, int func)
     426                 :            : {
     427                 :          0 :         u16 gmch_ctrl;
     428                 :          0 :         u16 gms;
     429                 :            : 
     430                 :          0 :         gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL);
     431                 :          0 :         gms = (gmch_ctrl >> SNB_GMCH_GMS_SHIFT) & SNB_GMCH_GMS_MASK;
     432                 :            : 
     433                 :            :         /*
     434                 :            :          * 0x0  to 0x10: 32MB increments starting at 0MB
     435                 :            :          * 0x11 to 0x16: 4MB increments starting at 8MB
     436                 :            :          * 0x17 to 0x1d: 4MB increments start at 36MB
     437                 :            :          */
     438         [ #  # ]:          0 :         if (gms < 0x11)
     439                 :          0 :                 return gms * MB(32);
     440         [ #  # ]:          0 :         else if (gms < 0x17)
     441                 :          0 :                 return (gms - 0x11) * MB(4) + MB(8);
     442                 :            :         else
     443                 :          0 :                 return (gms - 0x17) * MB(4) + MB(36);
     444                 :            : }
     445                 :            : 
     446                 :          0 : static resource_size_t __init gen9_stolen_size(int num, int slot, int func)
     447                 :            : {
     448                 :          0 :         u16 gmch_ctrl;
     449                 :          0 :         u16 gms;
     450                 :            : 
     451                 :          0 :         gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL);
     452                 :          0 :         gms = (gmch_ctrl >> BDW_GMCH_GMS_SHIFT) & BDW_GMCH_GMS_MASK;
     453                 :            : 
     454                 :            :         /* 0x0  to 0xef: 32MB increments starting at 0MB */
     455                 :            :         /* 0xf0 to 0xfe: 4MB increments starting at 4MB */
     456         [ #  # ]:          0 :         if (gms < 0xf0)
     457                 :          0 :                 return gms * MB(32);
     458                 :            :         else
     459                 :          0 :                 return (gms - 0xf0) * MB(4) + MB(4);
     460                 :            : }
     461                 :            : 
     462                 :            : struct intel_early_ops {
     463                 :            :         resource_size_t (*stolen_size)(int num, int slot, int func);
     464                 :            :         resource_size_t (*stolen_base)(int num, int slot, int func,
     465                 :            :                                        resource_size_t size);
     466                 :            : };
     467                 :            : 
     468                 :            : static const struct intel_early_ops i830_early_ops __initconst = {
     469                 :            :         .stolen_base = i830_stolen_base,
     470                 :            :         .stolen_size = i830_stolen_size,
     471                 :            : };
     472                 :            : 
     473                 :            : static const struct intel_early_ops i845_early_ops __initconst = {
     474                 :            :         .stolen_base = i845_stolen_base,
     475                 :            :         .stolen_size = i830_stolen_size,
     476                 :            : };
     477                 :            : 
     478                 :            : static const struct intel_early_ops i85x_early_ops __initconst = {
     479                 :            :         .stolen_base = i85x_stolen_base,
     480                 :            :         .stolen_size = gen3_stolen_size,
     481                 :            : };
     482                 :            : 
     483                 :            : static const struct intel_early_ops i865_early_ops __initconst = {
     484                 :            :         .stolen_base = i865_stolen_base,
     485                 :            :         .stolen_size = gen3_stolen_size,
     486                 :            : };
     487                 :            : 
     488                 :            : static const struct intel_early_ops gen3_early_ops __initconst = {
     489                 :            :         .stolen_base = gen3_stolen_base,
     490                 :            :         .stolen_size = gen3_stolen_size,
     491                 :            : };
     492                 :            : 
     493                 :            : static const struct intel_early_ops gen6_early_ops __initconst = {
     494                 :            :         .stolen_base = gen3_stolen_base,
     495                 :            :         .stolen_size = gen6_stolen_size,
     496                 :            : };
     497                 :            : 
     498                 :            : static const struct intel_early_ops gen8_early_ops __initconst = {
     499                 :            :         .stolen_base = gen3_stolen_base,
     500                 :            :         .stolen_size = gen8_stolen_size,
     501                 :            : };
     502                 :            : 
     503                 :            : static const struct intel_early_ops gen9_early_ops __initconst = {
     504                 :            :         .stolen_base = gen3_stolen_base,
     505                 :            :         .stolen_size = gen9_stolen_size,
     506                 :            : };
     507                 :            : 
     508                 :            : static const struct intel_early_ops chv_early_ops __initconst = {
     509                 :            :         .stolen_base = gen3_stolen_base,
     510                 :            :         .stolen_size = chv_stolen_size,
     511                 :            : };
     512                 :            : 
     513                 :            : static const struct intel_early_ops gen11_early_ops __initconst = {
     514                 :            :         .stolen_base = gen11_stolen_base,
     515                 :            :         .stolen_size = gen9_stolen_size,
     516                 :            : };
     517                 :            : 
     518                 :            : static const struct pci_device_id intel_early_ids[] __initconst = {
     519                 :            :         INTEL_I830_IDS(&i830_early_ops),
     520                 :            :         INTEL_I845G_IDS(&i845_early_ops),
     521                 :            :         INTEL_I85X_IDS(&i85x_early_ops),
     522                 :            :         INTEL_I865G_IDS(&i865_early_ops),
     523                 :            :         INTEL_I915G_IDS(&gen3_early_ops),
     524                 :            :         INTEL_I915GM_IDS(&gen3_early_ops),
     525                 :            :         INTEL_I945G_IDS(&gen3_early_ops),
     526                 :            :         INTEL_I945GM_IDS(&gen3_early_ops),
     527                 :            :         INTEL_VLV_IDS(&gen6_early_ops),
     528                 :            :         INTEL_PINEVIEW_G_IDS(&gen3_early_ops),
     529                 :            :         INTEL_PINEVIEW_M_IDS(&gen3_early_ops),
     530                 :            :         INTEL_I965G_IDS(&gen3_early_ops),
     531                 :            :         INTEL_G33_IDS(&gen3_early_ops),
     532                 :            :         INTEL_I965GM_IDS(&gen3_early_ops),
     533                 :            :         INTEL_GM45_IDS(&gen3_early_ops),
     534                 :            :         INTEL_G45_IDS(&gen3_early_ops),
     535                 :            :         INTEL_IRONLAKE_D_IDS(&gen3_early_ops),
     536                 :            :         INTEL_IRONLAKE_M_IDS(&gen3_early_ops),
     537                 :            :         INTEL_SNB_D_IDS(&gen6_early_ops),
     538                 :            :         INTEL_SNB_M_IDS(&gen6_early_ops),
     539                 :            :         INTEL_IVB_M_IDS(&gen6_early_ops),
     540                 :            :         INTEL_IVB_D_IDS(&gen6_early_ops),
     541                 :            :         INTEL_HSW_IDS(&gen6_early_ops),
     542                 :            :         INTEL_BDW_IDS(&gen8_early_ops),
     543                 :            :         INTEL_CHV_IDS(&chv_early_ops),
     544                 :            :         INTEL_SKL_IDS(&gen9_early_ops),
     545                 :            :         INTEL_BXT_IDS(&gen9_early_ops),
     546                 :            :         INTEL_KBL_IDS(&gen9_early_ops),
     547                 :            :         INTEL_CFL_IDS(&gen9_early_ops),
     548                 :            :         INTEL_GLK_IDS(&gen9_early_ops),
     549                 :            :         INTEL_CNL_IDS(&gen9_early_ops),
     550                 :            :         INTEL_ICL_11_IDS(&gen11_early_ops),
     551                 :            :         INTEL_EHL_IDS(&gen11_early_ops),
     552                 :            :         INTEL_TGL_12_IDS(&gen11_early_ops),
     553                 :            : };
     554                 :            : 
     555                 :            : struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0);
     556                 :            : EXPORT_SYMBOL(intel_graphics_stolen_res);
     557                 :            : 
     558                 :            : static void __init
     559                 :            : intel_graphics_stolen(int num, int slot, int func,
     560                 :            :                       const struct intel_early_ops *early_ops)
     561                 :            : {
     562                 :            :         resource_size_t base, size;
     563                 :            :         resource_size_t end;
     564                 :            : 
     565                 :            :         size = early_ops->stolen_size(num, slot, func);
     566                 :            :         base = early_ops->stolen_base(num, slot, func, size);
     567                 :            : 
     568                 :            :         if (!size || !base)
     569                 :            :                 return;
     570                 :            : 
     571                 :            :         end = base + size - 1;
     572                 :            : 
     573                 :            :         intel_graphics_stolen_res.start = base;
     574                 :            :         intel_graphics_stolen_res.end = end;
     575                 :            : 
     576                 :            :         printk(KERN_INFO "Reserving Intel graphics memory at %pR\n",
     577                 :            :                &intel_graphics_stolen_res);
     578                 :            : 
     579                 :            :         /* Mark this space as reserved */
     580                 :            :         e820__range_add(base, size, E820_TYPE_RESERVED);
     581                 :            :         e820__update_table(e820_table);
     582                 :            : }
     583                 :            : 
     584                 :          0 : static void __init intel_graphics_quirks(int num, int slot, int func)
     585                 :            : {
     586                 :          0 :         const struct intel_early_ops *early_ops;
     587                 :          0 :         u16 device;
     588                 :          0 :         int i;
     589                 :            : 
     590                 :          0 :         device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID);
     591                 :            : 
     592         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(intel_early_ids); i++) {
     593                 :          0 :                 kernel_ulong_t driver_data = intel_early_ids[i].driver_data;
     594                 :            : 
     595         [ #  # ]:          0 :                 if (intel_early_ids[i].device != device)
     596                 :          0 :                         continue;
     597                 :            : 
     598                 :          0 :                 early_ops = (typeof(early_ops))driver_data;
     599                 :            : 
     600                 :          0 :                 intel_graphics_stolen(num, slot, func, early_ops);
     601                 :            : 
     602                 :          0 :                 return;
     603                 :            :         }
     604                 :            : }
     605                 :            : 
     606                 :          0 : static void __init force_disable_hpet(int num, int slot, int func)
     607                 :            : {
     608                 :            : #ifdef CONFIG_HPET_TIMER
     609                 :          0 :         boot_hpet_disable = true;
     610                 :          0 :         pr_info("x86/hpet: Will disable the HPET for this platform because it's not reliable\n");
     611                 :            : #endif
     612                 :          0 : }
     613                 :            : 
     614                 :            : #define BCM4331_MMIO_SIZE       16384
     615                 :            : #define BCM4331_PM_CAP          0x40
     616                 :            : #define bcma_aread32(reg)       ioread32(mmio + 1 * BCMA_CORE_SIZE + reg)
     617                 :            : #define bcma_awrite32(reg, val) iowrite32(val, mmio + 1 * BCMA_CORE_SIZE + reg)
     618                 :            : 
     619                 :          0 : static void __init apple_airport_reset(int bus, int slot, int func)
     620                 :            : {
     621                 :          0 :         void __iomem *mmio;
     622                 :          0 :         u16 pmcsr;
     623                 :          0 :         u64 addr;
     624                 :          0 :         int i;
     625                 :            : 
     626         [ #  # ]:          0 :         if (!x86_apple_machine)
     627                 :            :                 return;
     628                 :            : 
     629                 :            :         /* Card may have been put into PCI_D3hot by grub quirk */
     630                 :          0 :         pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
     631                 :            : 
     632         [ #  # ]:          0 :         if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
     633                 :          0 :                 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
     634                 :          0 :                 write_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL, pmcsr);
     635         [ #  # ]:          0 :                 mdelay(10);
     636                 :            : 
     637                 :          0 :                 pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
     638         [ #  # ]:          0 :                 if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
     639                 :          0 :                         pr_err("pci 0000:%02x:%02x.%d: Cannot power up Apple AirPort card\n",
     640                 :            :                                bus, slot, func);
     641                 :          0 :                         return;
     642                 :            :                 }
     643                 :            :         }
     644                 :            : 
     645                 :          0 :         addr  =      read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
     646                 :          0 :         addr |= (u64)read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_1) << 32;
     647                 :          0 :         addr &= PCI_BASE_ADDRESS_MEM_MASK;
     648                 :            : 
     649                 :          0 :         mmio = early_ioremap(addr, BCM4331_MMIO_SIZE);
     650         [ #  # ]:          0 :         if (!mmio) {
     651                 :          0 :                 pr_err("pci 0000:%02x:%02x.%d: Cannot iomap Apple AirPort card\n",
     652                 :            :                        bus, slot, func);
     653                 :          0 :                 return;
     654                 :            :         }
     655                 :            : 
     656                 :          0 :         pr_info("Resetting Apple AirPort card (left enabled by EFI)\n");
     657                 :            : 
     658   [ #  #  #  # ]:          0 :         for (i = 0; bcma_aread32(BCMA_RESET_ST) && i < 30; i++)
     659                 :          0 :                 udelay(10);
     660                 :            : 
     661                 :          0 :         bcma_awrite32(BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
     662                 :          0 :         bcma_aread32(BCMA_RESET_CTL);
     663                 :          0 :         udelay(1);
     664                 :            : 
     665                 :          0 :         bcma_awrite32(BCMA_RESET_CTL, 0);
     666                 :          0 :         bcma_aread32(BCMA_RESET_CTL);
     667                 :          0 :         udelay(10);
     668                 :            : 
     669                 :          0 :         early_iounmap(mmio, BCM4331_MMIO_SIZE);
     670                 :            : }
     671                 :            : 
     672                 :            : #define QFLAG_APPLY_ONCE        0x1
     673                 :            : #define QFLAG_APPLIED           0x2
     674                 :            : #define QFLAG_DONE              (QFLAG_APPLY_ONCE|QFLAG_APPLIED)
     675                 :            : struct chipset {
     676                 :            :         u32 vendor;
     677                 :            :         u32 device;
     678                 :            :         u32 class;
     679                 :            :         u32 class_mask;
     680                 :            :         u32 flags;
     681                 :            :         void (*f)(int num, int slot, int func);
     682                 :            : };
     683                 :            : 
     684                 :            : static struct chipset early_qrk[] __initdata = {
     685                 :            :         { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
     686                 :            :           PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs },
     687                 :            :         { PCI_VENDOR_ID_VIA, PCI_ANY_ID,
     688                 :            :           PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, via_bugs },
     689                 :            :         { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB,
     690                 :            :           PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, fix_hypertransport_config },
     691                 :            :         { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS,
     692                 :            :           PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs },
     693                 :            :         { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
     694                 :            :           PCI_CLASS_SERIAL_SMBUS, PCI_ANY_ID, 0, ati_bugs_contd },
     695                 :            :         { PCI_VENDOR_ID_INTEL, 0x3403, PCI_CLASS_BRIDGE_HOST,
     696                 :            :           PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
     697                 :            :         { PCI_VENDOR_ID_INTEL, 0x3405, PCI_CLASS_BRIDGE_HOST,
     698                 :            :           PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
     699                 :            :         { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST,
     700                 :            :           PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check },
     701                 :            :         { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID,
     702                 :            :           QFLAG_APPLY_ONCE, intel_graphics_quirks },
     703                 :            :         /*
     704                 :            :          * HPET on the current version of the Baytrail platform has accuracy
     705                 :            :          * problems: it will halt in deep idle state - so we disable it.
     706                 :            :          *
     707                 :            :          * More details can be found in section 18.10.1.3 of the datasheet:
     708                 :            :          *
     709                 :            :          *    http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/atom-z8000-datasheet-vol-1.pdf
     710                 :            :          */
     711                 :            :         { PCI_VENDOR_ID_INTEL, 0x0f00,
     712                 :            :                 PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
     713                 :            :         { PCI_VENDOR_ID_INTEL, 0x3e20,
     714                 :            :                 PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
     715                 :            :         { PCI_VENDOR_ID_INTEL, 0x3ec4,
     716                 :            :                 PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
     717                 :            :         { PCI_VENDOR_ID_INTEL, 0x8a12,
     718                 :            :                 PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
     719                 :            :         { PCI_VENDOR_ID_BROADCOM, 0x4331,
     720                 :            :           PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
     721                 :            :         {}
     722                 :            : };
     723                 :            : 
     724                 :            : static void __init early_pci_scan_bus(int bus);
     725                 :            : 
     726                 :            : /**
     727                 :            :  * check_dev_quirk - apply early quirks to a given PCI device
     728                 :            :  * @num: bus number
     729                 :            :  * @slot: slot number
     730                 :            :  * @func: PCI function
     731                 :            :  *
     732                 :            :  * Check the vendor & device ID against the early quirks table.
     733                 :            :  *
     734                 :            :  * If the device is single function, let early_pci_scan_bus() know so we don't
     735                 :            :  * poke at this device again.
     736                 :            :  */
     737                 :        363 : static int __init check_dev_quirk(int num, int slot, int func)
     738                 :            : {
     739                 :        363 :         u16 class;
     740                 :        363 :         u16 vendor;
     741                 :        363 :         u16 device;
     742                 :        363 :         u8 type;
     743                 :        363 :         u8 sec;
     744                 :        363 :         int i;
     745                 :            : 
     746                 :        363 :         class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE);
     747                 :            : 
     748         [ +  + ]:        363 :         if (class == 0xffff)
     749                 :            :                 return -1; /* no class, treat as single function */
     750                 :            : 
     751                 :         66 :         vendor = read_pci_config_16(num, slot, func, PCI_VENDOR_ID);
     752                 :            : 
     753                 :         66 :         device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID);
     754                 :            : 
     755         [ +  + ]:       1056 :         for (i = 0; early_qrk[i].f != NULL; i++) {
     756         [ +  - ]:        924 :                 if (((early_qrk[i].vendor == PCI_ANY_ID) ||
     757         [ +  + ]:        924 :                         (early_qrk[i].vendor == vendor)) &&
     758         [ +  + ]:        264 :                         ((early_qrk[i].device == PCI_ANY_ID) ||
     759         [ -  + ]:        231 :                         (early_qrk[i].device == device)) &&
     760                 :         33 :                         (!((early_qrk[i].class ^ class) &
     761         [ -  + ]:         33 :                             early_qrk[i].class_mask))) {
     762         [ #  # ]:          0 :                                 if ((early_qrk[i].flags &
     763                 :            :                                      QFLAG_DONE) != QFLAG_DONE)
     764                 :          0 :                                         early_qrk[i].f(num, slot, func);
     765                 :          0 :                                 early_qrk[i].flags |= QFLAG_APPLIED;
     766                 :            :                         }
     767                 :            :         }
     768                 :            : 
     769                 :         66 :         type = read_pci_config_byte(num, slot, func,
     770                 :            :                                     PCI_HEADER_TYPE);
     771                 :            : 
     772         [ -  + ]:         66 :         if ((type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
     773                 :          0 :                 sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS);
     774         [ #  # ]:          0 :                 if (sec > num)
     775                 :          0 :                         early_pci_scan_bus(sec);
     776                 :            :         }
     777                 :            : 
     778         [ +  + ]:         66 :         if (!(type & 0x80))
     779                 :         55 :                 return -1;
     780                 :            : 
     781                 :            :         return 0;
     782                 :            : }
     783                 :            : 
     784                 :         11 : static void __init early_pci_scan_bus(int bus)
     785                 :            : {
     786                 :         11 :         int slot, func;
     787                 :            : 
     788                 :            :         /* Poor man's PCI discovery */
     789         [ +  + ]:        363 :         for (slot = 0; slot < 32; slot++)
     790         [ +  - ]:        363 :                 for (func = 0; func < 8; func++) {
     791                 :            :                         /* Only probe function 0 on single fn devices */
     792         [ +  + ]:        363 :                         if (check_dev_quirk(bus, slot, func))
     793                 :            :                                 break;
     794                 :            :                 }
     795                 :         11 : }
     796                 :            : 
     797                 :         11 : void __init early_quirks(void)
     798                 :            : {
     799         [ +  - ]:         11 :         if (!early_pci_allowed())
     800                 :            :                 return;
     801                 :            : 
     802                 :         11 :         early_pci_scan_bus(0);
     803                 :            : }

Generated by: LCOV version 1.14