uboot/arch/x86/cpu/pci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2011 The Chromium OS Authors.
   4 * (C) Copyright 2008,2009
   5 * Graeme Russ, <graeme.russ@gmail.com>
   6 *
   7 * (C) Copyright 2002
   8 * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
   9 */
  10
  11#include <common.h>
  12#include <dm.h>
  13#include <errno.h>
  14#include <log.h>
  15#include <malloc.h>
  16#include <pci.h>
  17#include <asm/io.h>
  18#include <asm/pci.h>
  19
  20int pci_x86_read_config(pci_dev_t bdf, uint offset, ulong *valuep,
  21                        enum pci_size_t size)
  22{
  23        outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR);
  24        switch (size) {
  25        case PCI_SIZE_8:
  26                *valuep = inb(PCI_REG_DATA + (offset & 3));
  27                break;
  28        case PCI_SIZE_16:
  29                *valuep = inw(PCI_REG_DATA + (offset & 2));
  30                break;
  31        case PCI_SIZE_32:
  32                *valuep = inl(PCI_REG_DATA);
  33                break;
  34        }
  35
  36        return 0;
  37}
  38
  39int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value,
  40                         enum pci_size_t size)
  41{
  42        outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR);
  43        switch (size) {
  44        case PCI_SIZE_8:
  45                outb(value, PCI_REG_DATA + (offset & 3));
  46                break;
  47        case PCI_SIZE_16:
  48                outw(value, PCI_REG_DATA + (offset & 2));
  49                break;
  50        case PCI_SIZE_32:
  51                outl(value, PCI_REG_DATA);
  52                break;
  53        }
  54
  55        return 0;
  56}
  57
  58int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
  59                          enum pci_size_t size)
  60{
  61        ulong value;
  62        int ret;
  63
  64        ret = pci_x86_read_config(bdf, offset, &value, size);
  65        if (ret)
  66                return ret;
  67        value &= ~clr;
  68        value |= set;
  69
  70        return pci_x86_write_config(bdf, offset, value, size);
  71}
  72
  73void pci_assign_irqs(int bus, int device, u8 irq[4])
  74{
  75        pci_dev_t bdf;
  76        int func;
  77        u16 vendor;
  78        u8 pin, line;
  79
  80        for (func = 0; func < 8; func++) {
  81                bdf = PCI_BDF(bus, device, func);
  82                pci_read_config16(bdf, PCI_VENDOR_ID, &vendor);
  83                if (vendor == 0xffff || vendor == 0x0000)
  84                        continue;
  85
  86                pci_read_config8(bdf, PCI_INTERRUPT_PIN, &pin);
  87
  88                /* PCI spec says all values except 1..4 are reserved */
  89                if ((pin < 1) || (pin > 4))
  90                        continue;
  91
  92                line = irq[pin - 1];
  93                if (!line)
  94                        continue;
  95
  96                debug("Assigning IRQ %d to PCI device %d.%x.%d (INT%c)\n",
  97                      line, bus, device, func, 'A' + pin - 1);
  98
  99                pci_write_config8(bdf, PCI_INTERRUPT_LINE, line);
 100        }
 101}
 102