/* Public domain. */ #include #include #include #include #include "i915_drv.h" struct resource intel_graphics_stolen_res = DEFINE_RES_MEM(0, 0); bus_addr_t gen3_stolen_base(struct inteldrm_softc *dev_priv) { uint32_t bsm = pci_conf_read(dev_priv->pc, dev_priv->tag, INTEL_BSM); return bsm & INTEL_BSM_MASK; } bus_addr_t gen11_stolen_base(struct inteldrm_softc *dev_priv) { uint64_t bsm = pci_conf_read(dev_priv->pc, dev_priv->tag, INTEL_GEN11_BSM_DW0); bsm &= INTEL_BSM_MASK; bsm |= (uint64_t)pci_conf_read(dev_priv->pc, dev_priv->tag, INTEL_GEN11_BSM_DW1) << 32; return bsm; } bus_size_t i830_stolen_size(struct inteldrm_softc *dev_priv) { uint16_t gmch_ctl, gms; pci_read_config_word(dev_priv->bridge_dev, I830_GMCH_CTRL, &gmch_ctl); gms = gmch_ctl & I830_GMCH_GMS_MASK; switch (gms) { case I830_GMCH_GMS_STOLEN_512: return 512 * 1024; case I830_GMCH_GMS_STOLEN_1024: return 1 * 1024 * 1024; case I830_GMCH_GMS_STOLEN_8192: return 8 * 1024 * 1024; } return 0; } bus_size_t gen3_stolen_size(struct inteldrm_softc *dev_priv) { uint16_t gmch_ctl, gms; pci_read_config_word(dev_priv->bridge_dev, I830_GMCH_CTRL, &gmch_ctl); gms = gmch_ctl & I855_GMCH_GMS_MASK; switch (gms) { case I855_GMCH_GMS_STOLEN_1M: return 1 * 1024 * 1024; case I855_GMCH_GMS_STOLEN_4M: return 4 * 1024 * 1024; case I855_GMCH_GMS_STOLEN_8M: return 8 * 1024 * 1024; case I855_GMCH_GMS_STOLEN_16M: return 16 * 1024 * 1024; case I855_GMCH_GMS_STOLEN_32M: return 32 * 1024 * 1024; case I915_GMCH_GMS_STOLEN_48M: return 48 * 1024 * 1024; case I915_GMCH_GMS_STOLEN_64M: return 64 * 1024 * 1024; case G33_GMCH_GMS_STOLEN_128M: return 128 * 1024 * 1024; case G33_GMCH_GMS_STOLEN_256M: return 256 * 1024 * 1024; case INTEL_GMCH_GMS_STOLEN_96M: return 96 * 1024 * 1024; case INTEL_GMCH_GMS_STOLEN_160M: return 160 * 1024 * 1024; case INTEL_GMCH_GMS_STOLEN_224M: return 224 * 1024 * 1024; case INTEL_GMCH_GMS_STOLEN_352M: return 352 * 1024 * 1024; } return 0; } bus_size_t gen6_stolen_size(struct inteldrm_softc *dev_priv) { struct pci_dev *pdev = dev_priv->drm.pdev; uint16_t gmch_ctl, gms; pci_read_config_word(pdev, SNB_GMCH_CTRL, &gmch_ctl); gms = (gmch_ctl >> SNB_GMCH_GMS_SHIFT) & SNB_GMCH_GMS_MASK; return gms * (32 * 1024 * 1024); } bus_size_t chv_stolen_size(struct inteldrm_softc *dev_priv) { struct pci_dev *pdev = dev_priv->drm.pdev; uint16_t gmch_ctl, gms; pci_read_config_word(pdev, SNB_GMCH_CTRL, &gmch_ctl); gms = (gmch_ctl >> SNB_GMCH_GMS_SHIFT) & SNB_GMCH_GMS_MASK; if (gms < 0x11) return gms * (32 * 1024 * 1024); else if (gms < 0x17) return (gms - 0x11) * (4 * 1024 * 1024) + (8 * 1024 * 1024); else return (gms - 0x17) + (4 * 1024 * 1024) + (36 * 1024 * 1024); } bus_size_t gen8_stolen_size(struct inteldrm_softc *dev_priv) { struct pci_dev *pdev = dev_priv->drm.pdev; uint16_t gmch_ctl, gms; pci_read_config_word(pdev, SNB_GMCH_CTRL, &gmch_ctl); gms = (gmch_ctl >> BDW_GMCH_GMS_SHIFT) & BDW_GMCH_GMS_MASK; return gms * (32 * 1024 * 1024); } bus_size_t gen9_stolen_size(struct inteldrm_softc *dev_priv) { struct pci_dev *pdev = dev_priv->drm.pdev; uint16_t gmch_ctl, gms; pci_read_config_word(pdev, SNB_GMCH_CTRL, &gmch_ctl); gms = (gmch_ctl >> BDW_GMCH_GMS_SHIFT) & BDW_GMCH_GMS_MASK; if (gms < 0xf0) return gms * (32 * 1024 * 1024); else return (gms - 0xf0) * (4 * 1024 * 1024) + (4 * 1024 * 1024); } void intel_init_stolen_res(struct inteldrm_softc *dev_priv) { bus_addr_t stolen_base = 0; bus_size_t stolen_size = 0; #ifdef notyet if (IS_I830(dev_priv)) stolen_base = i830_stolen_base(dev_priv); else if (IS_I845G(dev_priv)) stolen_base = i845_stolen_base(dev_priv); else if (IS_I85X(dev_priv)) stolen_base = i85x_stolen_base(dev_priv); else if (IS_I865G(dev_priv)) stolen_base = i865_stolen_base(dev_priv); #endif if (INTEL_GEN(dev_priv) >= 3 && INTEL_GEN(dev_priv) < 11) stolen_base = gen3_stolen_base(dev_priv); else if (INTEL_GEN(dev_priv) == 11) stolen_base = gen11_stolen_base(dev_priv); if (IS_I830(dev_priv) || IS_I845G(dev_priv)) stolen_size = i830_stolen_size(dev_priv); else if (IS_I85X(dev_priv) || IS_I865G(dev_priv) || (INTEL_GEN(dev_priv) >= 3 && INTEL_GEN(dev_priv) <= 5)) stolen_size = gen3_stolen_size(dev_priv); else if (IS_CHERRYVIEW(dev_priv)) stolen_size = chv_stolen_size(dev_priv); else if (INTEL_GEN(dev_priv) >= 6 && INTEL_GEN(dev_priv) < 8) stolen_size = gen6_stolen_size(dev_priv); else if (INTEL_GEN(dev_priv) == 8) stolen_size = gen8_stolen_size(dev_priv); else if (INTEL_GEN(dev_priv) >= 9 && INTEL_GEN(dev_priv) < 12) stolen_size = gen9_stolen_size(dev_priv); if (stolen_base == 0 || stolen_size == 0) return; intel_graphics_stolen_res.start = stolen_base; intel_graphics_stolen_res.end = stolen_base + stolen_size - 1; }