diff options
28 files changed, 419 insertions, 181 deletions
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index ea4c6d52605..29e51bc0138 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -387,6 +387,7 @@ acpi_get_table_with_size(char *signature,  	return (AE_NOT_FOUND);  } +ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)  acpi_status  acpi_get_table(char *signature, diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 6f007b6c240..6ec0fff79bc 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h @@ -64,6 +64,7 @@  #define I830_PTE_SYSTEM_CACHED  0x00000006  /* GT PTE cache control fields */  #define GEN6_PTE_UNCACHED	0x00000002 +#define HSW_PTE_UNCACHED	0x00000000  #define GEN6_PTE_LLC		0x00000004  #define GEN6_PTE_LLC_MLC	0x00000006  #define GEN6_PTE_GFDT		0x00000008 diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 08fc5cbb13c..58e32f7c322 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1156,6 +1156,30 @@ static bool gen6_check_flags(unsigned int flags)  	return true;  } +static void haswell_write_entry(dma_addr_t addr, unsigned int entry, +				unsigned int flags) +{ +	unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT; +	unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; +	u32 pte_flags; + +	if (type_mask == AGP_USER_MEMORY) +		pte_flags = HSW_PTE_UNCACHED | I810_PTE_VALID; +	else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { +		pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; +		if (gfdt) +			pte_flags |= GEN6_PTE_GFDT; +	} else { /* set 'normal'/'cached' to LLC by default */ +		pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; +		if (gfdt) +			pte_flags |= GEN6_PTE_GFDT; +	} + +	/* gen6 has bit11-4 for physical addr bit39-32 */ +	addr |= (addr >> 28) & 0xff0; +	writel(addr | pte_flags, intel_private.gtt + entry); +} +  static void gen6_write_entry(dma_addr_t addr, unsigned int entry,  			     unsigned int flags)  { @@ -1382,6 +1406,15 @@ static const struct intel_gtt_driver sandybridge_gtt_driver = {  	.check_flags = gen6_check_flags,  	.chipset_flush = i9xx_chipset_flush,  }; +static const struct intel_gtt_driver haswell_gtt_driver = { +	.gen = 6, +	.setup = i9xx_setup, +	.cleanup = gen6_cleanup, +	.write_entry = haswell_write_entry, +	.dma_mask_size = 40, +	.check_flags = gen6_check_flags, +	.chipset_flush = i9xx_chipset_flush, +};  static const struct intel_gtt_driver valleyview_gtt_driver = {  	.gen = 7,  	.setup = i9xx_setup, @@ -1499,77 +1532,77 @@ static const struct intel_gtt_driver_description {  	{ PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG,  	    "ValleyView", &valleyview_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG, -	    "Haswell", &sandybridge_gtt_driver }, +	    "Haswell", &haswell_gtt_driver },  	{ 0, NULL, NULL }  }; diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index b7adb4a967f..28637c181b1 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -706,9 +706,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)  	p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal);  	p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay);  	p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); - -	p->crtc_hadjusted = false; -	p->crtc_vadjusted = false;  }  EXPORT_SYMBOL(drm_mode_set_crtcinfo); diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index 371c695322d..da457b18eaa 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c @@ -89,7 +89,7 @@ static const struct file_operations drm_proc_fops = {   * Create a given set of proc files represented by an array of   * gdm_proc_lists in the given root directory.   */ -int drm_proc_create_files(struct drm_info_list *files, int count, +static int drm_proc_create_files(struct drm_info_list *files, int count,  			  struct proc_dir_entry *root, struct drm_minor *minor)  {  	struct drm_device *dev = minor->dev; @@ -172,7 +172,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,  	return 0;  } -int drm_proc_remove_files(struct drm_info_list *files, int count, +static int drm_proc_remove_files(struct drm_info_list *files, int count,  			  struct drm_minor *minor)  {  	struct list_head *pos, *q; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5c4657a54f9..489e2b162b2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2365,6 +2365,10 @@ int i915_gpu_idle(struct drm_device *dev)  	/* Flush everything onto the inactive list. */  	for_each_ring(ring, dev_priv, i) { +		ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); +		if (ret) +			return ret; +  		ret = i915_ring_idle(ring);  		if (ret)  			return ret; @@ -2372,10 +2376,6 @@ int i915_gpu_idle(struct drm_device *dev)  		/* Is the device fubar? */  		if (WARN_ON(!list_empty(&ring->gpu_write_list)))  			return -EBUSY; - -		ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); -		if (ret) -			return ret;  	}  	return 0; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index ee9b68f6bc3..d9a5372ec56 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -261,7 +261,10 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt,  		pte_flags |= GEN6_PTE_CACHE_LLC;  		break;  	case I915_CACHE_NONE: -		pte_flags |= GEN6_PTE_UNCACHED; +		if (IS_HASWELL(dev)) +			pte_flags |= HSW_PTE_UNCACHED; +		else +			pte_flags |= GEN6_PTE_UNCACHED;  		break;  	default:  		BUG(); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index acc99b21e0b..28725ce5b82 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -115,6 +115,7 @@  #define GEN6_PTE_VALID			(1 << 0)  #define GEN6_PTE_UNCACHED		(1 << 1) +#define HSW_PTE_UNCACHED		(0)  #define GEN6_PTE_CACHE_LLC		(2 << 1)  #define GEN6_PTE_CACHE_LLC_MLC		(3 << 1)  #define GEN6_PTE_CACHE_BITS		(3 << 1) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 7ed4a41c396..23bdc8cd145 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -326,6 +326,36 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)  	return ret;  } +static struct edid *intel_crt_get_edid(struct drm_connector *connector, +				struct i2c_adapter *i2c) +{ +	struct edid *edid; + +	edid = drm_get_edid(connector, i2c); + +	if (!edid && !intel_gmbus_is_forced_bit(i2c)) { +		DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n"); +		intel_gmbus_force_bit(i2c, true); +		edid = drm_get_edid(connector, i2c); +		intel_gmbus_force_bit(i2c, false); +	} + +	return edid; +} + +/* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */ +static int intel_crt_ddc_get_modes(struct drm_connector *connector, +				struct i2c_adapter *adapter) +{ +	struct edid *edid; + +	edid = intel_crt_get_edid(connector, adapter); +	if (!edid) +		return 0; + +	return intel_connector_update_modes(connector, edid); +} +  static bool intel_crt_detect_ddc(struct drm_connector *connector)  {  	struct intel_crt *crt = intel_attached_crt(connector); @@ -336,7 +366,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)  	BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);  	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); -	edid = drm_get_edid(connector, i2c); +	edid = intel_crt_get_edid(connector, i2c);  	if (edid) {  		bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; @@ -544,13 +574,13 @@ static int intel_crt_get_modes(struct drm_connector *connector)  	struct i2c_adapter *i2c;  	i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); -	ret = intel_ddc_get_modes(connector, i2c); +	ret = intel_crt_ddc_get_modes(connector, i2c);  	if (ret || !IS_G4X(dev))  		return ret;  	/* Try to probe digital port for output in DVI-I -> VGA mode. */  	i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); -	return intel_ddc_get_modes(connector, i2c); +	return intel_crt_ddc_get_modes(connector, i2c);  }  static int intel_crt_set_property(struct drm_connector *connector, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 132ab511b90..cd54cf88a28 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -342,6 +342,8 @@ struct intel_fbc_work {  	int interval;  }; +int intel_connector_update_modes(struct drm_connector *connector, +				struct edid *edid);  int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);  extern void intel_attach_force_audio_property(struct drm_connector *connector); diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 45848b9b670..29b72593fbb 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -33,6 +33,25 @@  #include "i915_drv.h"  /** + * intel_connector_update_modes - update connector from edid + * @connector: DRM connector device to use + * @edid: previously read EDID information + */ +int intel_connector_update_modes(struct drm_connector *connector, +				struct edid *edid) +{ +	int ret; + +	drm_mode_connector_update_edid_property(connector, edid); +	ret = drm_add_edid_modes(connector, edid); +	drm_edid_to_eld(connector, edid); +	connector->display_info.raw_edid = NULL; +	kfree(edid); + +	return ret; +} + +/**   * intel_ddc_get_modes - get modelist from monitor   * @connector: DRM connector device to use   * @adapter: i2c adapter @@ -43,18 +62,12 @@ int intel_ddc_get_modes(struct drm_connector *connector,  			struct i2c_adapter *adapter)  {  	struct edid *edid; -	int ret = 0;  	edid = drm_get_edid(connector, adapter); -	if (edid) { -		drm_mode_connector_update_edid_property(connector, edid); -		ret = drm_add_edid_modes(connector, edid); -		drm_edid_to_eld(connector, edid); -		connector->display_info.raw_edid = NULL; -		kfree(edid); -	} +	if (!edid) +		return 0; -	return ret; +	return intel_connector_update_modes(connector, edid);  }  static const struct drm_prop_enum_list force_audio_names[] = { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 58c07cdafb7..1881c8c83f0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2441,17 +2441,10 @@ static void gen6_enable_rps(struct drm_device *dev)  		   dev_priv->max_delay << 24 |  		   dev_priv->min_delay << 16); -	if (IS_HASWELL(dev)) { -		I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); -		I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); -		I915_WRITE(GEN6_RP_UP_EI, 66000); -		I915_WRITE(GEN6_RP_DOWN_EI, 350000); -	} else { -		I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); -		I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); -		I915_WRITE(GEN6_RP_UP_EI, 100000); -		I915_WRITE(GEN6_RP_DOWN_EI, 5000000); -	} +	I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); +	I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); +	I915_WRITE(GEN6_RP_UP_EI, 66000); +	I915_WRITE(GEN6_RP_DOWN_EI, 350000);  	I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);  	I915_WRITE(GEN6_RP_CONTROL, diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d172e987313..d81bb0bf288 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1692,6 +1692,7 @@ static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)  	edid = intel_sdvo_get_edid(connector);  	if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL)  		has_audio = drm_detect_monitor_audio(edid); +	kfree(edid);  	return has_audio;  } diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index c6fcb5b86a4..f4d4505fe83 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -444,11 +444,28 @@ union atom_enable_ss {  static void atombios_crtc_program_ss(struct radeon_device *rdev,  				     int enable,  				     int pll_id, +				     int crtc_id,  				     struct radeon_atom_ss *ss)  { +	unsigned i;  	int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL);  	union atom_enable_ss args; +	if (!enable) { +		for (i = 0; i < rdev->num_crtc; i++) { +			if (rdev->mode_info.crtcs[i] && +			    rdev->mode_info.crtcs[i]->enabled && +			    i != crtc_id && +			    pll_id == rdev->mode_info.crtcs[i]->pll_id) { +				/* one other crtc is using this pll don't turn +				 * off spread spectrum as it might turn off +				 * display on active crtc +				 */ +				return; +			} +		} +	} +  	memset(&args, 0, sizeof(args));  	if (ASIC_IS_DCE5(rdev)) { @@ -1028,7 +1045,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode  		radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,  					  &ref_div, &post_div); -	atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); +	atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss);  	atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,  				  encoder_mode, radeon_encoder->encoder_id, mode->clock, @@ -1051,7 +1068,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode  			ss.step = step_size;  		} -		atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); +		atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss);  	}  } @@ -1572,11 +1589,11 @@ void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)  								   ASIC_INTERNAL_SS_ON_DCPLL,  								   rdev->clock.default_dispclk);  		if (ss_enabled) -			atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); +			atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss);  		/* XXX: DCE5, make sure voltage, dispclk is high enough */  		atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);  		if (ss_enabled) -			atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); +			atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss);  	}  } diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 3dab49cb1d4..ab74e6b149e 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -47,13 +47,17 @@ struct r600_cs_track {  	u32			npipes;  	/* value we track */  	u32			sq_config; +	u32			log_nsamples;  	u32			nsamples;  	u32			cb_color_base_last[8];  	struct radeon_bo	*cb_color_bo[8];  	u64			cb_color_bo_mc[8]; -	u32			cb_color_bo_offset[8]; -	struct radeon_bo	*cb_color_frag_bo[8]; /* unused */ -	struct radeon_bo	*cb_color_tile_bo[8]; /* unused */ +	u64			cb_color_bo_offset[8]; +	struct radeon_bo	*cb_color_frag_bo[8]; +	u64			cb_color_frag_offset[8]; +	struct radeon_bo	*cb_color_tile_bo[8]; +	u64			cb_color_tile_offset[8]; +	u32			cb_color_mask[8];  	u32			cb_color_info[8];  	u32			cb_color_view[8];  	u32			cb_color_size_idx[8]; /* unused */ @@ -349,10 +353,6 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	unsigned array_mode;  	u32 format; -	if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { -		dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); -		return -EINVAL; -	}  	size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];  	format = G_0280A0_FORMAT(track->cb_color_info[i]);  	if (!r600_fmt_is_valid_color(format)) { @@ -420,7 +420,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	}  	/* check offset */ -	tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format); +	tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * +	      r600_fmt_get_blocksize(format) * track->nsamples;  	switch (array_mode) {  	default:  	case V_0280A0_ARRAY_LINEAR_GENERAL: @@ -441,7 +442,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  			 * broken userspace.  			 */  		} else { -			dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n", +			dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n",  				 __func__, i, array_mode,  				 track->cb_color_bo_offset[i], tmp,  				 radeon_bo_size(track->cb_color_bo[i]), @@ -458,6 +459,51 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)  	tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) |  		S_028060_SLICE_TILE_MAX(slice_tile_max - 1);  	ib[track->cb_color_size_idx[i]] = tmp; + +	/* FMASK/CMASK */ +	switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) { +	case V_0280A0_TILE_DISABLE: +		break; +	case V_0280A0_FRAG_ENABLE: +		if (track->nsamples > 1) { +			uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]); +			/* the tile size is 8x8, but the size is in units of bits. +			 * for bytes, do just * 8. */ +			uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1); + +			if (bytes + track->cb_color_frag_offset[i] > +			    radeon_bo_size(track->cb_color_frag_bo[i])) { +				dev_warn(p->dev, "%s FMASK_TILE_MAX too large " +					 "(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", +					 __func__, tile_max, bytes, +					 track->cb_color_frag_offset[i], +					 radeon_bo_size(track->cb_color_frag_bo[i])); +				return -EINVAL; +			} +		} +		/* fall through */ +	case V_0280A0_CLEAR_ENABLE: +	{ +		uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]); +		/* One block = 128x128 pixels, one 8x8 tile has 4 bits.. +		 * (128*128) / (8*8) / 2 = 128 bytes per block. */ +		uint32_t bytes = (block_max + 1) * 128; + +		if (bytes + track->cb_color_tile_offset[i] > +		    radeon_bo_size(track->cb_color_tile_bo[i])) { +			dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large " +				 "(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", +				 __func__, block_max, bytes, +				 track->cb_color_tile_offset[i], +				 radeon_bo_size(track->cb_color_tile_bo[i])); +			return -EINVAL; +		} +		break; +	} +	default: +		dev_warn(p->dev, "%s invalid tile mode\n", __func__); +		return -EINVAL; +	}  	return 0;  } @@ -566,7 +612,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p)  		ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1;  		nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; -		tmp = ntiles * bpe * 64 * nviews; +		tmp = ntiles * bpe * 64 * nviews * track->nsamples;  		if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) {  			dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n",  					array_mode, @@ -1231,6 +1277,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  		break;  	case R_028C04_PA_SC_AA_CONFIG:  		tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); +		track->log_nsamples = tmp;  		track->nsamples = 1 << tmp;  		track->cb_dirty = true;  		break; @@ -1312,16 +1359,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  				dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);  				return -EINVAL;  			} -			ib[idx] = track->cb_color_base_last[tmp];  			track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; +			track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp]; +			ib[idx] = track->cb_color_base_last[tmp];  		} else {  			r = r600_cs_packet_next_reloc(p, &reloc);  			if (r) {  				dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);  				return -EINVAL;  			} -			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);  			track->cb_color_frag_bo[tmp] = reloc->robj; +			track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8; +			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); +		} +		if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { +			track->cb_dirty = true;  		}  		break;  	case R_0280C0_CB_COLOR0_TILE: @@ -1338,16 +1390,35 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)  				dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg);  				return -EINVAL;  			} -			ib[idx] = track->cb_color_base_last[tmp];  			track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; +			track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp]; +			ib[idx] = track->cb_color_base_last[tmp];  		} else {  			r = r600_cs_packet_next_reloc(p, &reloc);  			if (r) {  				dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);  				return -EINVAL;  			} -			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);  			track->cb_color_tile_bo[tmp] = reloc->robj; +			track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8; +			ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); +		} +		if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { +			track->cb_dirty = true; +		} +		break; +	case R_028100_CB_COLOR0_MASK: +	case R_028104_CB_COLOR1_MASK: +	case R_028108_CB_COLOR2_MASK: +	case R_02810C_CB_COLOR3_MASK: +	case R_028110_CB_COLOR4_MASK: +	case R_028114_CB_COLOR5_MASK: +	case R_028118_CB_COLOR6_MASK: +	case R_02811C_CB_COLOR7_MASK: +		tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; +		track->cb_color_mask[tmp] = ib[idx]; +		if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { +			track->cb_dirty = true;  		}  		break;  	case CB_COLOR0_BASE: @@ -1492,7 +1563,7 @@ unsigned r600_mip_minify(unsigned size, unsigned level)  }  static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, -			      unsigned w0, unsigned h0, unsigned d0, unsigned format, +			      unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format,  			      unsigned block_align, unsigned height_align, unsigned base_align,  			      unsigned *l0_size, unsigned *mipmap_size)  { @@ -1520,7 +1591,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,  		depth = r600_mip_minify(d0, i); -		size = nbx * nby * blocksize; +		size = nbx * nby * blocksize * nsamples;  		if (nfaces)  			size *= nfaces;  		else @@ -1672,7 +1743,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,  		nfaces = larray - barray + 1;  	} -	r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format, +	r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format,  			  pitch_align, height_align, base_align,  			  &l0_size, &mipmap_size);  	/* using get ib will give us the offset into the texture bo */ diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index fd328f4c3ea..bdb69a63062 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -92,6 +92,20 @@  #define R_028094_CB_COLOR5_VIEW                      0x028094  #define R_028098_CB_COLOR6_VIEW                      0x028098  #define R_02809C_CB_COLOR7_VIEW                      0x02809C +#define R_028100_CB_COLOR0_MASK                      0x028100 +#define   S_028100_CMASK_BLOCK_MAX(x)                  (((x) & 0xFFF) << 0) +#define   G_028100_CMASK_BLOCK_MAX(x)                  (((x) >> 0) & 0xFFF) +#define   C_028100_CMASK_BLOCK_MAX                     0xFFFFF000 +#define   S_028100_FMASK_TILE_MAX(x)                   (((x) & 0xFFFFF) << 12) +#define   G_028100_FMASK_TILE_MAX(x)                   (((x) >> 12) & 0xFFFFF) +#define   C_028100_FMASK_TILE_MAX                      0x00000FFF +#define R_028104_CB_COLOR1_MASK                      0x028104 +#define R_028108_CB_COLOR2_MASK                      0x028108 +#define R_02810C_CB_COLOR3_MASK                      0x02810C +#define R_028110_CB_COLOR4_MASK                      0x028110 +#define R_028114_CB_COLOR5_MASK                      0x028114 +#define R_028118_CB_COLOR6_MASK                      0x028118 +#define R_02811C_CB_COLOR7_MASK                      0x02811C  #define CB_COLOR0_INFO                                  0x280a0  #	define CB_FORMAT(x)				((x) << 2)  #       define CB_ARRAY_MODE(x)                         ((x) << 8) @@ -1400,6 +1414,9 @@  #define   S_0280A0_TILE_MODE(x)                        (((x) & 0x3) << 18)  #define   G_0280A0_TILE_MODE(x)                        (((x) >> 18) & 0x3)  #define   C_0280A0_TILE_MODE                           0xFFF3FFFF +#define     V_0280A0_TILE_DISABLE			0 +#define     V_0280A0_CLEAR_ENABLE			1 +#define     V_0280A0_FRAG_ENABLE			2  #define   S_0280A0_BLEND_CLAMP(x)                      (((x) & 0x1) << 20)  #define   G_0280A0_BLEND_CLAMP(x)                      (((x) >> 20) & 0x1)  #define   C_0280A0_BLEND_CLAMP                         0xFFEFFFFF diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 99304194a65..59a15315ae9 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -142,21 +142,6 @@ struct radeon_device;  /*   * BIOS.   */ -#define ATRM_BIOS_PAGE 4096 - -#if defined(CONFIG_VGA_SWITCHEROO) -bool radeon_atrm_supported(struct pci_dev *pdev); -int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len); -#else -static inline bool radeon_atrm_supported(struct pci_dev *pdev) -{ -	return false; -} - -static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){ -	return -EINVAL; -} -#endif  bool radeon_get_bios(struct radeon_device *rdev);  /* diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index f9c21f9d16b..d67d4f3eb6f 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -452,7 +452,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,  	}  	/* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ -	if ((dev->pdev->device == 0x9802) && +	if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) &&  	    (dev->pdev->subsystem_vendor == 0x1734) &&  	    (dev->pdev->subsystem_device == 0x11bd)) {  		if (*connector_type == DRM_MODE_CONNECTOR_VGA) { diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 98724fcb008..2a2cf0b88a2 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -30,57 +30,8 @@ static struct radeon_atpx_priv {  	/* handle for device - and atpx */  	acpi_handle dhandle;  	acpi_handle atpx_handle; -	acpi_handle atrm_handle;  } radeon_atpx_priv; -/* retrieve the ROM in 4k blocks */ -static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, -			    int offset, int len) -{ -	acpi_status status; -	union acpi_object atrm_arg_elements[2], *obj; -	struct acpi_object_list atrm_arg; -	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; - -	atrm_arg.count = 2; -	atrm_arg.pointer = &atrm_arg_elements[0]; - -	atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; -	atrm_arg_elements[0].integer.value = offset; - -	atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; -	atrm_arg_elements[1].integer.value = len; - -	status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); -	if (ACPI_FAILURE(status)) { -		printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); -		return -ENODEV; -	} - -	obj = (union acpi_object *)buffer.pointer; -	memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); -	len = obj->buffer.length; -	kfree(buffer.pointer); -	return len; -} - -bool radeon_atrm_supported(struct pci_dev *pdev) -{ -	/* get the discrete ROM only via ATRM */ -	if (!radeon_atpx_priv.atpx_detected) -		return false; - -	if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) -		return false; -	return true; -} - - -int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) -{ -	return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len); -} -  static int radeon_atpx_get_version(acpi_handle handle)  {  	acpi_status status; @@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,  static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)  { -	acpi_handle dhandle, atpx_handle, atrm_handle; +	acpi_handle dhandle, atpx_handle;  	acpi_status status;  	dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); @@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)  	if (ACPI_FAILURE(status))  		return false; -	status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); -	if (ACPI_FAILURE(status)) -		return false; -  	radeon_atpx_priv.dhandle = dhandle;  	radeon_atpx_priv.atpx_handle = atpx_handle; -	radeon_atpx_priv.atrm_handle = atrm_handle;  	return true;  } diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 501f4881e5a..d306cc8fdea 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -32,6 +32,7 @@  #include <linux/vga_switcheroo.h>  #include <linux/slab.h> +#include <linux/acpi.h>  /*   * BIOS.   */ @@ -98,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)  	return true;  } +#ifdef CONFIG_ACPI  /* ATRM is used to get the BIOS on the discrete cards in   * dual-gpu systems.   */ +/* retrieve the ROM in 4k blocks */ +#define ATRM_BIOS_PAGE 4096 +/** + * radeon_atrm_call - fetch a chunk of the vbios + * + * @atrm_handle: acpi ATRM handle + * @bios: vbios image pointer + * @offset: offset of vbios image data to fetch + * @len: length of vbios image data to fetch + * + * Executes ATRM to fetch a chunk of the discrete + * vbios image on PX systems (all asics). + * Returns the length of the buffer fetched. + */ +static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, +			    int offset, int len) +{ +	acpi_status status; +	union acpi_object atrm_arg_elements[2], *obj; +	struct acpi_object_list atrm_arg; +	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; + +	atrm_arg.count = 2; +	atrm_arg.pointer = &atrm_arg_elements[0]; + +	atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; +	atrm_arg_elements[0].integer.value = offset; + +	atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; +	atrm_arg_elements[1].integer.value = len; + +	status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); +	if (ACPI_FAILURE(status)) { +		printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); +		return -ENODEV; +	} + +	obj = (union acpi_object *)buffer.pointer; +	memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); +	len = obj->buffer.length; +	kfree(buffer.pointer); +	return len; +} +  static bool radeon_atrm_get_bios(struct radeon_device *rdev)  {  	int ret;  	int size = 256 * 1024;  	int i; +	struct pci_dev *pdev = NULL; +	acpi_handle dhandle, atrm_handle; +	acpi_status status; +	bool found = false; + +	/* ATRM is for the discrete card only */ +	if (rdev->flags & RADEON_IS_IGP) +		return false; -	if (!radeon_atrm_supported(rdev->pdev)) +	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { +		dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); +		if (!dhandle) +			continue; + +		status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); +		if (!ACPI_FAILURE(status)) { +			found = true; +			break; +		} +	} + +	if (!found)  		return false;  	rdev->bios = kmalloc(size, GFP_KERNEL); @@ -117,9 +183,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)  	}  	for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { -		ret = radeon_atrm_get_bios_chunk(rdev->bios, -						 (i * ATRM_BIOS_PAGE), -						 ATRM_BIOS_PAGE); +		ret = radeon_atrm_call(atrm_handle, +				       rdev->bios, +				       (i * ATRM_BIOS_PAGE), +				       ATRM_BIOS_PAGE);  		if (ret < ATRM_BIOS_PAGE)  			break;  	} @@ -130,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)  	}  	return true;  } +#else +static inline bool radeon_atrm_get_bios(struct radeon_device *rdev) +{ +	return false; +} +#endif  static bool ni_read_disabled_bios(struct radeon_device *rdev)  { @@ -476,6 +549,61 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)  		return legacy_read_disabled_bios(rdev);  } +#ifdef CONFIG_ACPI +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev) +{ +	bool ret = false; +	struct acpi_table_header *hdr; +	acpi_size tbl_size; +	UEFI_ACPI_VFCT *vfct; +	GOP_VBIOS_CONTENT *vbios; +	VFCT_IMAGE_HEADER *vhdr; + +	if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size))) +		return false; +	if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { +		DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); +		goto out_unmap; +	} + +	vfct = (UEFI_ACPI_VFCT *)hdr; +	if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) { +		DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n"); +		goto out_unmap; +	} + +	vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset); +	vhdr = &vbios->VbiosHeader; +	DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n", +			vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction, +			vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength); + +	if (vhdr->PCIBus != rdev->pdev->bus->number || +	    vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) || +	    vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) || +	    vhdr->VendorID != rdev->pdev->vendor || +	    vhdr->DeviceID != rdev->pdev->device) { +		DRM_INFO("ACPI VFCT table is not for this card\n"); +		goto out_unmap; +	}; + +	if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) { +		DRM_ERROR("ACPI VFCT image truncated\n"); +		goto out_unmap; +	} + +	rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); +	ret = !!rdev->bios; + +out_unmap: +	return ret; +} +#else +static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev) +{ +	return false; +} +#endif  bool radeon_get_bios(struct radeon_device *rdev)  { @@ -484,6 +612,8 @@ bool radeon_get_bios(struct radeon_device *rdev)  	r = radeon_atrm_get_bios(rdev);  	if (r == false) +		r = radeon_acpi_vfct_bios(rdev); +	if (r == false)  		r = igp_read_bios_from_vram(rdev);  	if (r == false)  		r = radeon_read_bios(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d7269f48d37..27d22d709c9 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -62,9 +62,10 @@   *   2.18.0 - r600-eg: allow "invalid" DB formats   *   2.19.0 - r600-eg: MSAA textures   *   2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query + *   2.21.0 - r600-r700: FMASK and CMASK   */  #define KMS_DRIVER_MAJOR	2 -#define KMS_DRIVER_MINOR	20 +#define KMS_DRIVER_MINOR	21  #define KMS_DRIVER_PATCHLEVEL	0  int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);  int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1cb014b571a..9024e722283 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -132,6 +132,7 @@ int radeon_bo_create(struct radeon_device *rdev,  	acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size,  				       sizeof(struct radeon_bo)); +retry:  	bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);  	if (bo == NULL)  		return -ENOMEM; @@ -145,8 +146,6 @@ int radeon_bo_create(struct radeon_device *rdev,  	bo->surface_reg = -1;  	INIT_LIST_HEAD(&bo->list);  	INIT_LIST_HEAD(&bo->va); - -retry:  	radeon_ttm_placement_from_domain(bo, domain);  	/* Kernel allocation are uninterruptible */  	down_read(&rdev->pm.mclk_lock); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index ec79b375043..43c431a2686 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -706,6 +706,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig  	if (radeon_debugfs_ring_init(rdev, ring)) {  		DRM_ERROR("Failed to register debugfs file for rings !\n");  	} +	radeon_ring_lockup_update(ring);  	return 0;  } diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index 5e659b034d9..f93e45d869f 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 @@ -744,14 +744,6 @@ r600 0x9400  0x00028C38 CB_CLRCMP_DST  0x00028C3C CB_CLRCMP_MSK  0x00028C34 CB_CLRCMP_SRC -0x00028100 CB_COLOR0_MASK -0x00028104 CB_COLOR1_MASK -0x00028108 CB_COLOR2_MASK -0x0002810C CB_COLOR3_MASK -0x00028110 CB_COLOR4_MASK -0x00028114 CB_COLOR5_MASK -0x00028118 CB_COLOR6_MASK -0x0002811C CB_COLOR7_MASK  0x00028808 CB_COLOR_CONTROL  0x0002842C CB_FOG_BLUE  0x00028428 CB_FOG_GREEN diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index f5dd89e891d..9159d48d1df 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -354,8 +354,7 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc,  static void udl_crtc_disable(struct drm_crtc *crtc)  { - - +	udl_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);  }  static void udl_crtc_destroy(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 6b0078ffa76..c50724bd30f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1688,15 +1688,19 @@ int vmw_du_page_flip(struct drm_crtc *crtc,  	struct vmw_private *dev_priv = vmw_priv(crtc->dev);  	struct drm_framebuffer *old_fb = crtc->fb;  	struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); -	struct drm_file *file_priv = event->base.file_priv; +	struct drm_file *file_priv ;  	struct vmw_fence_obj *fence = NULL;  	struct drm_clip_rect clips;  	int ret; +	if (event == NULL) +		return -EINVAL; +  	/* require ScreenObject support for page flipping */  	if (!dev_priv->sou_priv)  		return -ENOSYS; +	file_priv = event->base.file_priv;  	if (!vmw_kms_screen_object_flippable(dev_priv, crtc))  		return -EINVAL; diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index f8a79fca4a2..88e92041d8f 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -374,6 +374,9 @@ static void fb_flashcursor(struct work_struct *work)  	int mode;  	int ret; +	/* FIXME: we should sort out the unbind locking instead */ +	/* instead we just fail to flash the cursor if we can't get +	 * the lock instead of blocking fbcon deinit */  	ret = console_trylock();  	if (ret == 0)  		return; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index a1a0386e016..ced362533e3 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -166,8 +166,6 @@ struct drm_display_mode {  	int crtc_vsync_start;  	int crtc_vsync_end;  	int crtc_vtotal; -	int crtc_hadjusted; -	int crtc_vadjusted;  	/* Driver private mode info */  	int private_size;  |