Pass through requests for non-standard BARs to the PCI bus layer. This
doesn't cache such resources so only one child device can allocate them
at a time.
Fixes: e8b145c2ba74 ("The recent PCI resource allocation ...")
Differential D53702
vga_pci: Permit child devices to allocate non-standard BARs Authored by jhb on Tue, Nov 11, 8:43 PM. Tags None Referenced Files
Subscribers
Details
Diff Detail
Event TimelineComment Actions This is probably the root cause of the manual BUS_ALLOC_RESOURCE call in drm-kmod I encountered in D53402. Presumably I'll have to bump __FreeBSD_version for this fix, but once this fix is in, intel_alloc_mchbar_resource should in theory be something like this: /* Allocate space for the MCH regs if needed, return nonzero on error */
static int
intel_alloc_mchbar_resource(struct drm_i915_private *i915)
{
int reg = GRAPHICS_VER(i915) >= 4 ? MCHBAR_I965 : MCHBAR_I915;
#if defined(__FreeBSD) && defined(__have_vga_pci_fix)
struct resource *res;
i915->mch_res_rid = reg;
res = bus_alloc_resource_any(
i915->drm.dev->bsddev, SYS_RES_MEMORY, &i915->mch_res_rid, RF_ACTIVE);
if (i915->mch_res_bsd_res == NULL)
return -ENOMEM;
i915->mch_res_bsd_res = res;
i915->gmch.mch_res.start = rman_get_start(res);
i915->gmch.mch_res.end = rman_get_end(res);
return 0;
#else
u32 temp_lo, temp_hi = 0;
u64 mchbar_addr;
int ret;
if (GRAPHICS_VER(i915) >= 4)
pci_read_config_dword(i915->gmch.pdev, reg + 4, &temp_hi);
pci_read_config_dword(i915->gmch.pdev, reg, &temp_lo);
mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
/* If ACPI doesn't have it, assume we need to allocate it ourselves */
#ifdef __linux__
/* CONFIG_PNP is disabled in kconfig.mk */
if (IS_ENABLED(CONFIG_PNP) && mchbar_addr &&
pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE))
return 0;
#endif
/* Get some space for it */
#ifdef __FreeBSD__
ret = 0;
i915->mch_res_rid = 0x100;
i915->mch_res_bsd_res = bsd_intel_pci_bus_alloc_mem(
i915->drm.dev->bsddev, &i915->mch_res_rid, MCHBAR_SIZE,
&i915->gmch.mch_res.start, &i915->gmch.mch_res.end);
if (i915->mch_res_bsd_res == NULL)
ret = -ENOMEM;
#else
i915->gmch.mch_res.name = "i915 MCHBAR";
i915->gmch.mch_res.flags = IORESOURCE_MEM;
ret = pci_bus_alloc_resource(i915->gmch.pdev->bus,
&i915->gmch.mch_res,
MCHBAR_SIZE, MCHBAR_SIZE,
PCIBIOS_MIN_MEM,
0, pcibios_align_resource,
i915->gmch.pdev);
#endif
if (ret) {
drm_dbg(&i915->drm, "failed bus alloc: %d\n", ret);
i915->gmch.mch_res.start = 0;
return ret;
}
if (GRAPHICS_VER(i915) >= 4)
pci_write_config_dword(i915->gmch.pdev, reg + 4,
upper_32_bits(i915->gmch.mch_res.start));
pci_write_config_dword(i915->gmch.pdev, reg,
lower_32_bits(i915->gmch.mch_res.start));
return 0;
#endif
}That is, FreeBSD's PCI bus driver understands BARs at non-standard locations and will size the BAR and update the BAR with the allocated space, etc. automatically. There's no need to dink around with adjusting the BAR by hand. You could then also just #ifdef-out bsd_intel_pci_bus_alloc_mem on systems without the vga_pci fix. If it makes it easier, we could land this set of changes first (and the vga_pci change is easy to MFC) before I land my BUS_ALLOC_RESOURCE change. |