Commit 2c07245f authored by Zhenyu Wang's avatar Zhenyu Wang Committed by Eric Anholt
Browse files

drm/i915: enable kernel modesetting on IGDNG



This adds kernel mode setting on IGDNG with VGA output support.
Note that suspend/resume doesn't work yet.

Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 2cce0d87
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -922,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
	 * Some of the preallocated space is taken by the GTT
	 * and popup.  GTT is 1K per MB of aperture size, and popup is 4K.
	 */
	if (IS_G4X(dev) || IS_IGD(dev))
	if (IS_G4X(dev) || IS_IGD(dev) || IS_IGDNG(dev))
		overhead = 4096;
	else
		overhead = (*aperture_size / 1024) + 4096;
+68 −8
Original line number Diff line number Diff line
@@ -37,9 +37,14 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 temp;
	u32 temp, reg;

	temp = I915_READ(ADPA);
	if (IS_IGDNG(dev))
		reg = PCH_ADPA;
	else
		reg = ADPA;

	temp = I915_READ(reg);
	temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
	temp |= ADPA_DAC_ENABLE;

@@ -58,7 +63,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
		break;
	}

	I915_WRITE(ADPA, temp);
	I915_WRITE(reg, temp);
}

static int intel_crt_mode_valid(struct drm_connector *connector,
@@ -101,17 +106,23 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
	struct drm_i915_private *dev_priv = dev->dev_private;
	int dpll_md_reg;
	u32 adpa, dpll_md;
	u32 adpa_reg;

	if (intel_crtc->pipe == 0)
		dpll_md_reg = DPLL_A_MD;
	else
		dpll_md_reg = DPLL_B_MD;

	if (IS_IGDNG(dev))
		adpa_reg = PCH_ADPA;
	else
		adpa_reg = ADPA;

	/*
	 * Disable separate mode multiplier used when cloning SDVO to CRT
	 * XXX this needs to be adjusted when we really are cloning
	 */
	if (IS_I965G(dev)) {
	if (IS_I965G(dev) && !IS_IGDNG(dev)) {
		dpll_md = I915_READ(dpll_md_reg);
		I915_WRITE(dpll_md_reg,
			   dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
@@ -125,13 +136,53 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,

	if (intel_crtc->pipe == 0) {
		adpa |= ADPA_PIPE_A_SELECT;
		if (!IS_IGDNG(dev))
			I915_WRITE(BCLRPAT_A, 0);
	} else {
		adpa |= ADPA_PIPE_B_SELECT;
		if (!IS_IGDNG(dev))
			I915_WRITE(BCLRPAT_B, 0);
	}

	I915_WRITE(ADPA, adpa);
	I915_WRITE(adpa_reg, adpa);
}

static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 adpa, temp;
	bool ret;

	temp = adpa = I915_READ(PCH_ADPA);

	adpa &= ~ADPA_CRT_HOTPLUG_MASK;

	adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 |
			ADPA_CRT_HOTPLUG_WARMUP_10MS |
			ADPA_CRT_HOTPLUG_SAMPLE_4S |
			ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */
			ADPA_CRT_HOTPLUG_VOLREF_325MV |
			ADPA_CRT_HOTPLUG_ENABLE |
			ADPA_CRT_HOTPLUG_FORCE_TRIGGER);

	DRM_DEBUG("pch crt adpa 0x%x", adpa);
	I915_WRITE(PCH_ADPA, adpa);

	/* This might not be needed as not specified in spec...*/
	udelay(1000);

	/* Check the status to see if both blue and green are on now */
	adpa = I915_READ(PCH_ADPA);
	if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) ==
			ADPA_CRT_HOTPLUG_MONITOR_COLOR)
		ret = true;
	else
		ret = false;

	/* restore origin register */
	I915_WRITE(PCH_ADPA, temp);
	return ret;
}

/**
@@ -148,6 +199,10 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 hotplug_en;
	int i, tries = 0;

	if (IS_IGDNG(dev))
		return intel_igdng_crt_detect_hotplug(connector);

	/*
	 * On 4 series desktop, CRT detect sequence need to be done twice
	 * to get a reliable result.
@@ -427,6 +482,7 @@ void intel_crt_init(struct drm_device *dev)
{
	struct drm_connector *connector;
	struct intel_output *intel_output;
	u32 i2c_reg;

	intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
	if (!intel_output)
@@ -443,7 +499,11 @@ void intel_crt_init(struct drm_device *dev)
					  &intel_output->enc);

	/* Set up the DDC bus. */
	intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
	if (IS_IGDNG(dev))
		i2c_reg = PCH_GPIOA;
	else
		i2c_reg = GPIOA;
	intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
	if (!intel_output->ddc_bus) {
		dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
			   "failed.\n");
+574 −29

File changed.

Preview size limit exceeded, changes collapsed.