Ver código fonte

drm/i915: Probe for PCH chipset type

PCH is the new name for south bridge from Ironlake/Sandybridge,
which contains most of the display outputs except eDP. This one
adds a probe function to detect current PCH type, and method to
detect Cougarpoint PCH.

Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Zhenyu Wang 15 anos atrás
pai
commit
3bad078183

+ 2 - 0
drivers/gpu/drm/i915/i915_dma.c

@@ -1710,6 +1710,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 	/* Start out suspended */
 	/* Start out suspended */
 	dev_priv->mm.suspended = 1;
 	dev_priv->mm.suspended = 1;
 
 
+	intel_detect_pch(dev);
+
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		ret = i915_load_modeset_init(dev, prealloc_start,
 		ret = i915_load_modeset_init(dev, prealloc_start,
 					     prealloc_size, agp_size);
 					     prealloc_size, agp_size);

+ 29 - 0
drivers/gpu/drm/i915/i915_drv.c

@@ -187,6 +187,35 @@ const static struct pci_device_id pciidlist[] = {
 MODULE_DEVICE_TABLE(pci, pciidlist);
 MODULE_DEVICE_TABLE(pci, pciidlist);
 #endif
 #endif
 
 
+#define INTEL_PCH_DEVICE_ID_MASK	0xff00
+#define INTEL_PCH_CPT_DEVICE_ID_TYPE	0x1c00
+
+void intel_detect_pch (struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct pci_dev *pch;
+
+	/*
+	 * The reason to probe ISA bridge instead of Dev31:Fun0 is to
+	 * make graphics device passthrough work easy for VMM, that only
+	 * need to expose ISA bridge to let driver know the real hardware
+	 * underneath. This is a requirement from virtualization team.
+	 */
+	pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+	if (pch) {
+		if (pch->vendor == PCI_VENDOR_ID_INTEL) {
+			int id;
+			id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
+
+			if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_CPT;
+				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
+			}
+		}
+		pci_dev_put(pch);
+	}
+}
+
 static int i915_drm_freeze(struct drm_device *dev)
 static int i915_drm_freeze(struct drm_device *dev)
 {
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_private *dev_priv = dev->dev_private;

+ 13 - 0
drivers/gpu/drm/i915/i915_drv.h

@@ -221,6 +221,11 @@ enum no_fbc_reason {
 	FBC_NOT_TILED, /* buffer not tiled */
 	FBC_NOT_TILED, /* buffer not tiled */
 };
 };
 
 
+enum intel_pch {
+	PCH_IBX,	/* Ibexpeak PCH */
+	PCH_CPT,	/* Cougarpoint PCH */
+};
+
 typedef struct drm_i915_private {
 typedef struct drm_i915_private {
 	struct drm_device *dev;
 	struct drm_device *dev;
 
 
@@ -331,6 +336,9 @@ typedef struct drm_i915_private {
 	/* Display functions */
 	/* Display functions */
 	struct drm_i915_display_funcs display;
 	struct drm_i915_display_funcs display;
 
 
+	/* PCH chipset type */
+	enum intel_pch pch_type;
+
 	/* Register state */
 	/* Register state */
 	bool modeset_on_lid;
 	bool modeset_on_lid;
 	u8 saveLBB;
 	u8 saveLBB;
@@ -992,6 +1000,8 @@ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
 extern void i8xx_disable_fbc(struct drm_device *dev);
 extern void i8xx_disable_fbc(struct drm_device *dev);
 extern void g4x_disable_fbc(struct drm_device *dev);
 extern void g4x_disable_fbc(struct drm_device *dev);
 
 
+extern void intel_detect_pch (struct drm_device *dev);
+
 /**
 /**
  * Lock test for when it's just for synchronization of ring access.
  * Lock test for when it's just for synchronization of ring access.
  *
  *
@@ -1137,6 +1147,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) ||	\
 #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) ||	\
 			    IS_GEN6(dev))
 			    IS_GEN6(dev))
 
 
+#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
+#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
+
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
 
 #endif
 #endif