Commit cdc7e184 authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'remotes/lorenzo/pci/vmd'

  - Fix VMD config addressing to ignore starting bus offset (Jon Derrick)

  - Fix VMD shadow offset scratchpad address (Jon Derrick)

* remotes/lorenzo/pci/vmd:
  PCI: vmd: Fix shadow offsets to reflect spec changes
  PCI: vmd: Fix config addressing when using bus offsets
parents 3efa7f1f a1a30170
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#define PCI_REG_VMLOCK 0x70 #define PCI_REG_VMLOCK 0x70
#define MB2_SHADOW_EN(vmlock) (vmlock & 0x2) #define MB2_SHADOW_EN(vmlock) (vmlock & 0x2)
#define MB2_SHADOW_OFFSET 0x2000
#define MB2_SHADOW_SIZE 16
enum vmd_features { enum vmd_features {
/* /*
* Device may contain registers which hint the physical location of the * Device may contain registers which hint the physical location of the
...@@ -94,6 +97,7 @@ struct vmd_dev { ...@@ -94,6 +97,7 @@ struct vmd_dev {
struct resource resources[3]; struct resource resources[3];
struct irq_domain *irq_domain; struct irq_domain *irq_domain;
struct pci_bus *bus; struct pci_bus *bus;
u8 busn_start;
struct dma_map_ops dma_ops; struct dma_map_ops dma_ops;
struct dma_domain dma_domain; struct dma_domain dma_domain;
...@@ -440,7 +444,8 @@ static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus, ...@@ -440,7 +444,8 @@ static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus,
unsigned int devfn, int reg, int len) unsigned int devfn, int reg, int len)
{ {
char __iomem *addr = vmd->cfgbar + char __iomem *addr = vmd->cfgbar +
(bus->number << 20) + (devfn << 12) + reg; ((bus->number - vmd->busn_start) << 20) +
(devfn << 12) + reg;
if ((addr - vmd->cfgbar) + len >= if ((addr - vmd->cfgbar) + len >=
resource_size(&vmd->dev->resource[VMD_CFGBAR])) resource_size(&vmd->dev->resource[VMD_CFGBAR]))
...@@ -563,7 +568,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) ...@@ -563,7 +568,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
unsigned long flags; unsigned long flags;
LIST_HEAD(resources); LIST_HEAD(resources);
resource_size_t offset[2] = {0}; resource_size_t offset[2] = {0};
resource_size_t membar2_offset = 0x2000, busn_start = 0; resource_size_t membar2_offset = 0x2000;
struct pci_bus *child; struct pci_bus *child;
/* /*
...@@ -576,7 +581,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) ...@@ -576,7 +581,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
u32 vmlock; u32 vmlock;
int ret; int ret;
membar2_offset = 0x2018; membar2_offset = MB2_SHADOW_OFFSET + MB2_SHADOW_SIZE;
ret = pci_read_config_dword(vmd->dev, PCI_REG_VMLOCK, &vmlock); ret = pci_read_config_dword(vmd->dev, PCI_REG_VMLOCK, &vmlock);
if (ret || vmlock == ~0) if (ret || vmlock == ~0)
return -ENODEV; return -ENODEV;
...@@ -588,9 +593,9 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) ...@@ -588,9 +593,9 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
if (!membar2) if (!membar2)
return -ENOMEM; return -ENOMEM;
offset[0] = vmd->dev->resource[VMD_MEMBAR1].start - offset[0] = vmd->dev->resource[VMD_MEMBAR1].start -
readq(membar2 + 0x2008); readq(membar2 + MB2_SHADOW_OFFSET);
offset[1] = vmd->dev->resource[VMD_MEMBAR2].start - offset[1] = vmd->dev->resource[VMD_MEMBAR2].start -
readq(membar2 + 0x2010); readq(membar2 + MB2_SHADOW_OFFSET + 8);
pci_iounmap(vmd->dev, membar2); pci_iounmap(vmd->dev, membar2);
} }
} }
...@@ -606,14 +611,14 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) ...@@ -606,14 +611,14 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
pci_read_config_dword(vmd->dev, PCI_REG_VMCONFIG, &vmconfig); pci_read_config_dword(vmd->dev, PCI_REG_VMCONFIG, &vmconfig);
if (BUS_RESTRICT_CAP(vmcap) && if (BUS_RESTRICT_CAP(vmcap) &&
(BUS_RESTRICT_CFG(vmconfig) == 0x1)) (BUS_RESTRICT_CFG(vmconfig) == 0x1))
busn_start = 128; vmd->busn_start = 128;
} }
res = &vmd->dev->resource[VMD_CFGBAR]; res = &vmd->dev->resource[VMD_CFGBAR];
vmd->resources[0] = (struct resource) { vmd->resources[0] = (struct resource) {
.name = "VMD CFGBAR", .name = "VMD CFGBAR",
.start = busn_start, .start = vmd->busn_start,
.end = busn_start + (resource_size(res) >> 20) - 1, .end = vmd->busn_start + (resource_size(res) >> 20) - 1,
.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED, .flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED,
}; };
...@@ -681,8 +686,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) ...@@ -681,8 +686,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]); pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]);
pci_add_resource_offset(&resources, &vmd->resources[2], offset[1]); pci_add_resource_offset(&resources, &vmd->resources[2], offset[1]);
vmd->bus = pci_create_root_bus(&vmd->dev->dev, busn_start, &vmd_ops, vmd->bus = pci_create_root_bus(&vmd->dev->dev, vmd->busn_start,
sd, &resources); &vmd_ops, sd, &resources);
if (!vmd->bus) { if (!vmd->bus) {
pci_free_resource_list(&resources); pci_free_resource_list(&resources);
irq_domain_remove(vmd->irq_domain); irq_domain_remove(vmd->irq_domain);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment