diff options
Diffstat (limited to 'drivers/gpu/drm')
34 files changed, 361 insertions, 330 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 82db1850666..fe738f05309 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -499,6 +499,7 @@ void drm_connector_cleanup(struct drm_connector *connector)  	mutex_lock(&dev->mode_config.mutex);  	drm_mode_object_put(dev, &connector->base);  	list_del(&connector->head); +	dev->mode_config.num_connector--;  	mutex_unlock(&dev->mode_config.mutex);  }  EXPORT_SYMBOL(drm_connector_cleanup); @@ -529,6 +530,7 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)  	mutex_lock(&dev->mode_config.mutex);  	drm_mode_object_put(dev, &encoder->base);  	list_del(&encoder->head); +	dev->mode_config.num_encoder--;  	mutex_unlock(&dev->mode_config.mutex);  }  EXPORT_SYMBOL(drm_encoder_cleanup); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 802b61ac313..f7c6854eb4d 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -256,7 +256,6 @@ int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed,  {  	printk(KERN_ERR "panic occurred, switching back to text console\n");  	return drm_fb_helper_force_kernel_mode(); -	return 0;  }  EXPORT_SYMBOL(drm_fb_helper_panic); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ce045a8cf82..f07e4252b70 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -67,11 +67,11 @@ module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);  MODULE_PARM_DESC(i915_enable_rc6,  		"Enable power-saving render C-state 6 (default: true)"); -unsigned int i915_enable_fbc __read_mostly = 1; +unsigned int i915_enable_fbc __read_mostly = -1;  module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);  MODULE_PARM_DESC(i915_enable_fbc,  		"Enable frame buffer compression for power savings " -		"(default: false)"); +		"(default: -1 (use per-chip default))");  unsigned int i915_lvds_downclock __read_mostly = 0;  module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ee1d701317f..04411ad2e77 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -878,7 +878,7 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,  	int pp_reg, lvds_reg;  	u32 val;  	enum pipe panel_pipe = PIPE_A; -	bool locked = locked; +	bool locked = true;  	if (HAS_PCH_SPLIT(dev_priv->dev)) {  		pp_reg = PCH_PP_CONTROL; @@ -1799,6 +1799,7 @@ static void intel_update_fbc(struct drm_device *dev)  	struct drm_framebuffer *fb;  	struct intel_framebuffer *intel_fb;  	struct drm_i915_gem_object *obj; +	int enable_fbc;  	DRM_DEBUG_KMS("\n"); @@ -1839,8 +1840,15 @@ static void intel_update_fbc(struct drm_device *dev)  	intel_fb = to_intel_framebuffer(fb);  	obj = intel_fb->obj; -	if (!i915_enable_fbc) { -		DRM_DEBUG_KMS("fbc disabled per module param (default off)\n"); +	enable_fbc = i915_enable_fbc; +	if (enable_fbc < 0) { +		DRM_DEBUG_KMS("fbc set to per-chip default\n"); +		enable_fbc = 1; +		if (INTEL_INFO(dev)->gen <= 5) +			enable_fbc = 0; +	} +	if (!enable_fbc) { +		DRM_DEBUG_KMS("fbc disabled per module param\n");  		dev_priv->no_fbc_reason = FBC_MODULE_PARAM;  		goto out_disable;  	} @@ -4687,13 +4695,13 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,  		bpc = 6; /* min is 18bpp */  		break;  	case 24: -		bpc = min((unsigned int)8, display_bpc); +		bpc = 8;  		break;  	case 30: -		bpc = min((unsigned int)10, display_bpc); +		bpc = 10;  		break;  	case 48: -		bpc = min((unsigned int)12, display_bpc); +		bpc = 12;  		break;  	default:  		DRM_DEBUG("unsupported depth, assuming 24 bits\n"); @@ -4701,10 +4709,12 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,  		break;  	} +	display_bpc = min(display_bpc, bpc); +  	DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n",  			 bpc, display_bpc); -	*pipe_bpp = bpc * 3; +	*pipe_bpp = display_bpc * 3;  	return display_bpc != bpc;  } @@ -7238,8 +7248,6 @@ static void intel_setup_outputs(struct drm_device *dev)  			intel_encoder_clones(dev, encoder->clone_mask);  	} -	intel_panel_setup_backlight(dev); -  	/* disable all the possible outputs/crtcs before entering KMS mode */  	drm_helper_disable_unused_functions(dev);  } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0b2ee9d3998..fe1099d8817 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -337,9 +337,6 @@ extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,  					   struct drm_connector *connector,  					   struct intel_load_detect_pipe *old); -extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); -extern int intel_sdvo_supports_hotplug(struct drm_connector *connector); -extern void intel_sdvo_set_hotplug(struct drm_connector *connector, int enable);  extern void intelfb_restore(void);  extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,  				    u16 blue, int regno); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 30fe554d893..6348c499616 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -92,6 +92,11 @@ struct intel_sdvo {  	*/  	uint16_t attached_output; +	/* +	 * Hotplug activation bits for this device +	 */ +	uint8_t hotplug_active[2]; +  	/**  	 * This is used to select the color range of RBG outputs in HDMI mode.  	 * It is only valid when using TMDS encoding and 8 bit per color mode. @@ -1208,74 +1213,20 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in  	return true;  } -/* No use! */ -#if 0 -struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) -{ -	struct drm_connector *connector = NULL; -	struct intel_sdvo *iout = NULL; -	struct intel_sdvo *sdvo; - -	/* find the sdvo connector */ -	list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -		iout = to_intel_sdvo(connector); - -		if (iout->type != INTEL_OUTPUT_SDVO) -			continue; - -		sdvo = iout->dev_priv; - -		if (sdvo->sdvo_reg == SDVOB && sdvoB) -			return connector; - -		if (sdvo->sdvo_reg == SDVOC && !sdvoB) -			return connector; - -	} - -	return NULL; -} - -int intel_sdvo_supports_hotplug(struct drm_connector *connector) +static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo)  {  	u8 response[2]; -	u8 status; -	struct intel_sdvo *intel_sdvo; -	DRM_DEBUG_KMS("\n"); - -	if (!connector) -		return 0; - -	intel_sdvo = to_intel_sdvo(connector);  	return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,  				    &response, 2) && response[0];  } -void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) +static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)  { -	u8 response[2]; -	u8 status; -	struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector); - -	intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); -	intel_sdvo_read_response(intel_sdvo, &response, 2); - -	if (on) { -		intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); -		status = intel_sdvo_read_response(intel_sdvo, &response, 2); - -		intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); -	} else { -		response[0] = 0; -		response[1] = 0; -		intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); -	} +	struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); -	intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); -	intel_sdvo_read_response(intel_sdvo, &response, 2); +	intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &intel_sdvo->hotplug_active, 2);  } -#endif  static bool  intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo) @@ -2045,6 +1996,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)  {  	struct drm_encoder *encoder = &intel_sdvo->base.base;  	struct drm_connector *connector; +	struct intel_encoder *intel_encoder = to_intel_encoder(encoder);  	struct intel_connector *intel_connector;  	struct intel_sdvo_connector *intel_sdvo_connector; @@ -2062,7 +2014,17 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)  	intel_connector = &intel_sdvo_connector->base;  	connector = &intel_connector->base; -	connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; +	if (intel_sdvo_supports_hotplug(intel_sdvo) & (1 << device)) { +		connector->polled = DRM_CONNECTOR_POLL_HPD; +		intel_sdvo->hotplug_active[0] |= 1 << device; +		/* Some SDVO devices have one-shot hotplug interrupts. +		 * Ensure that they get re-enabled when an interrupt happens. +		 */ +		intel_encoder->hot_plug = intel_sdvo_enable_hotplug; +		intel_sdvo_enable_hotplug(intel_encoder); +	} +	else +		connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;  	encoder->encoder_type = DRM_MODE_ENCODER_TMDS;  	connector->connector_type = DRM_MODE_CONNECTOR_DVID; @@ -2569,6 +2531,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)  	if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))  		goto err; +	/* Set up hotplug command - note paranoia about contents of reply. +	 * We assume that the hardware is in a sane state, and only touch +	 * the bits we think we understand. +	 */ +	intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, +			     &intel_sdvo->hotplug_active, 2); +	intel_sdvo->hotplug_active[0] &= ~0x3; +  	if (intel_sdvo_output_setup(intel_sdvo,  				    intel_sdvo->caps.output_flags) != true) {  		DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 8d02d875376..c919cfc8f2f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -530,7 +530,8 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)  		nouveau_gpuobj_ref(NULL, &obj);  		if (ret)  			return ret; -	} else { +	} else +	if (USE_SEMA(dev)) {  		/* map fence bo into channel's vm */  		ret = nouveau_bo_vma_add(dev_priv->fence.bo, chan->vm,  					 &chan->fence.vma); diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index c444cadbf84..2706cb3d871 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -37,8 +37,11 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,  		return -ENOMEM;  	nvbe->ttm_alloced = kmalloc(sizeof(bool) * num_pages, GFP_KERNEL); -	if (!nvbe->ttm_alloced) +	if (!nvbe->ttm_alloced) { +		kfree(nvbe->pages); +		nvbe->pages = NULL;  		return -ENOMEM; +	}  	nvbe->nr_pages = 0;  	while (num_pages--) { @@ -126,7 +129,7 @@ nv04_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)  		for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) {  			nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3); -			dma_offset += NV_CTXDMA_PAGE_SIZE; +			offset_l += NV_CTXDMA_PAGE_SIZE;  		}  	} diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index 118261d4927..5e45398a9e2 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -781,11 +781,20 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,  	struct drm_device *dev = crtc->dev;  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct nv04_crtc_reg *regp = &dev_priv->mode_reg.crtc_reg[nv_crtc->index]; -	struct drm_framebuffer *drm_fb = nv_crtc->base.fb; -	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); +	struct drm_framebuffer *drm_fb; +	struct nouveau_framebuffer *fb;  	int arb_burst, arb_lwm;  	int ret; +	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); + +	/* no fb bound */ +	if (!atomic && !crtc->fb) { +		NV_DEBUG_KMS(dev, "No FB bound\n"); +		return 0; +	} + +  	/* If atomic, we want to switch to the fb we were passed, so  	 * now we update pointers to do that.  (We don't pin; just  	 * assume we're already pinned and update the base address.) @@ -794,6 +803,8 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,  		drm_fb = passed_fb;  		fb = nouveau_framebuffer(passed_fb);  	} else { +		drm_fb = crtc->fb; +		fb = nouveau_framebuffer(crtc->fb);  		/* If not atomic, we can go ahead and pin, and unpin the  		 * old fb we were passed.  		 */ diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 46ad59ea218..5d989073ba6 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -519,12 +519,18 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,  	struct drm_device *dev = nv_crtc->base.dev;  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct nouveau_channel *evo = nv50_display(dev)->master; -	struct drm_framebuffer *drm_fb = nv_crtc->base.fb; -	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); +	struct drm_framebuffer *drm_fb; +	struct nouveau_framebuffer *fb;  	int ret;  	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); +	/* no fb bound */ +	if (!atomic && !crtc->fb) { +		NV_DEBUG_KMS(dev, "No FB bound\n"); +		return 0; +	} +  	/* If atomic, we want to switch to the fb we were passed, so  	 * now we update pointers to do that.  (We don't pin; just  	 * assume we're already pinned and update the base address.) @@ -533,6 +539,8 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,  		drm_fb = passed_fb;  		fb = nouveau_framebuffer(passed_fb);  	} else { +		drm_fb = crtc->fb; +		fb = nouveau_framebuffer(crtc->fb);  		/* If not atomic, we can go ahead and pin, and unpin the  		 * old fb we were passed.  		 */ diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index e88c64417a8..14cc88aaf3a 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,  	case ATOM_ARG_FB:  		idx = U8(*ptr);  		(*ptr)++; -		val = gctx->scratch[((gctx->fb_base + idx) / 4)]; +		if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) { +			DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n", +				  gctx->fb_base + (idx * 4), gctx->scratch_size_bytes); +			val = 0; +		} else +			val = gctx->scratch[(gctx->fb_base / 4) + idx];  		if (print)  			DEBUG("FB[0x%02X]", idx);  		break; @@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr,  	case ATOM_ARG_FB:  		idx = U8(*ptr);  		(*ptr)++; -		gctx->scratch[((gctx->fb_base + idx) / 4)] = val; +		if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) { +			DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n", +				  gctx->fb_base + (idx * 4), gctx->scratch_size_bytes); +		} else +			gctx->scratch[(gctx->fb_base / 4) + idx] = val;  		DEBUG("FB[0x%02X]", idx);  		break;  	case ATOM_ARG_PLL: @@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)  		usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;  	} +	ctx->scratch_size_bytes = 0;  	if (usage_bytes == 0)  		usage_bytes = 20 * 1024;  	/* allocate some scratch memory */  	ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);  	if (!ctx->scratch)  		return -ENOMEM; +	ctx->scratch_size_bytes = usage_bytes;  	return 0;  } diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index a589a55b223..93cfe2086ba 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h @@ -137,6 +137,7 @@ struct atom_context {  	int cs_equal, cs_above;  	int io_mode;  	uint32_t *scratch; +	int scratch_size_bytes;  };  extern int atom_debug; diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index c742944d380..a515b2a09d8 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -466,7 +466,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,  			return;  		}  		args.v2.ucEnable = enable; -		if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK)) +		if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev))  			args.v2.ucEnable = ATOM_DISABLE;  	} else if (ASIC_IS_DCE3(rdev)) {  		args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 7ad43c6b1db..79e8ebc0530 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -115,6 +115,7 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,  	u8 msg[20];  	int msg_bytes = send_bytes + 4;  	u8 ack; +	unsigned retry;  	if (send_bytes > 16)  		return -1; @@ -125,20 +126,22 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,  	msg[3] = (msg_bytes << 4) | (send_bytes - 1);  	memcpy(&msg[4], send, send_bytes); -	while (1) { +	for (retry = 0; retry < 4; retry++) {  		ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,  					    msg, msg_bytes, NULL, 0, delay, &ack); -		if (ret < 0) +		if (ret == -EBUSY) +			continue; +		else if (ret < 0)  			return ret;  		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) -			break; +			return send_bytes;  		else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)  			udelay(400);  		else  			return -EIO;  	} -	return send_bytes; +	return -EIO;  }  static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, @@ -149,26 +152,31 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,  	int msg_bytes = 4;  	u8 ack;  	int ret; +	unsigned retry;  	msg[0] = address;  	msg[1] = address >> 8;  	msg[2] = AUX_NATIVE_READ << 4;  	msg[3] = (msg_bytes << 4) | (recv_bytes - 1); -	while (1) { +	for (retry = 0; retry < 4; retry++) {  		ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,  					    msg, msg_bytes, recv, recv_bytes, delay, &ack); -		if (ret == 0) -			return -EPROTO; -		if (ret < 0) +		if (ret == -EBUSY) +			continue; +		else if (ret < 0)  			return ret;  		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)  			return ret;  		else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)  			udelay(400); +		else if (ret == 0) +			return -EPROTO;  		else  			return -EIO;  	} + +	return -EIO;  }  static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector, @@ -232,7 +240,9 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,  	for (retry = 0; retry < 4; retry++) {  		ret = radeon_process_aux_ch(auxch,  					    msg, msg_bytes, reply, reply_bytes, 0, &ack); -		if (ret < 0) { +		if (ret == -EBUSY) +			continue; +		else if (ret < 0) {  			DRM_DEBUG_KMS("aux_ch failed %d\n", ret);  			return ret;  		} diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index fb5fa089886..c4ffa14fb2f 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -41,6 +41,31 @@ static void evergreen_gpu_init(struct radeon_device *rdev);  void evergreen_fini(struct radeon_device *rdev);  static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); +void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) +{ +	u16 ctl, v; +	int cap, err; + +	cap = pci_pcie_cap(rdev->pdev); +	if (!cap) +		return; + +	err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl); +	if (err) +		return; + +	v = (ctl & PCI_EXP_DEVCTL_READRQ) >> 12; + +	/* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it +	 * to avoid hangs or perfomance issues +	 */ +	if ((v == 0) || (v == 6) || (v == 7)) { +		ctl &= ~PCI_EXP_DEVCTL_READRQ; +		ctl |= (2 << 12); +		pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl); +	} +} +  void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc)  {  	/* enable the pflip int */ @@ -1357,6 +1382,7 @@ int evergreen_cp_resume(struct radeon_device *rdev)  				 SOFT_RESET_PA |  				 SOFT_RESET_SH |  				 SOFT_RESET_VGT | +				 SOFT_RESET_SPI |  				 SOFT_RESET_SX));  	RREG32(GRBM_SOFT_RESET);  	mdelay(15); @@ -1378,7 +1404,8 @@ int evergreen_cp_resume(struct radeon_device *rdev)  	/* Initialize the ring buffer's read and write pointers */  	WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);  	WREG32(CP_RB_RPTR_WR, 0); -	WREG32(CP_RB_WPTR, 0); +	rdev->cp.wptr = 0; +	WREG32(CP_RB_WPTR, rdev->cp.wptr);  	/* set the wb address wether it's enabled or not */  	WREG32(CP_RB_RPTR_ADDR, @@ -1400,7 +1427,6 @@ int evergreen_cp_resume(struct radeon_device *rdev)  	WREG32(CP_DEBUG, (1 << 27) | (1 << 28));  	rdev->cp.rptr = RREG32(CP_RB_RPTR); -	rdev->cp.wptr = RREG32(CP_RB_WPTR);  	evergreen_cp_start(rdev);  	rdev->cp.ready = true; @@ -1564,48 +1590,6 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev,  	return backend_map;  } -static void evergreen_program_channel_remap(struct radeon_device *rdev) -{ -	u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; - -	tmp = RREG32(MC_SHARED_CHMAP); -	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { -	case 0: -	case 1: -	case 2: -	case 3: -	default: -		/* default mapping */ -		mc_shared_chremap = 0x00fac688; -		break; -	} - -	switch (rdev->family) { -	case CHIP_HEMLOCK: -	case CHIP_CYPRESS: -	case CHIP_BARTS: -		tcp_chan_steer_lo = 0x54763210; -		tcp_chan_steer_hi = 0x0000ba98; -		break; -	case CHIP_JUNIPER: -	case CHIP_REDWOOD: -	case CHIP_CEDAR: -	case CHIP_PALM: -	case CHIP_SUMO: -	case CHIP_SUMO2: -	case CHIP_TURKS: -	case CHIP_CAICOS: -	default: -		tcp_chan_steer_lo = 0x76543210; -		tcp_chan_steer_hi = 0x0000ba98; -		break; -	} - -	WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); -	WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); -	WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); -} -  static void evergreen_gpu_init(struct radeon_device *rdev)  {  	u32 cc_rb_backend_disable = 0; @@ -1862,6 +1846,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev)  	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); +	evergreen_fix_pci_max_read_req_size(rdev); +  	cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & ~2;  	cc_gc_shader_pipe_config |= @@ -2050,8 +2036,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev)  	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);  	WREG32(HDP_ADDR_CONFIG, gb_addr_config); -	evergreen_program_channel_remap(rdev); -  	num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1;  	grbm_gfx_index = INSTANCE_BROADCAST_WRITES; @@ -3143,21 +3127,23 @@ int evergreen_suspend(struct radeon_device *rdev)  }  int evergreen_copy_blit(struct radeon_device *rdev, -			uint64_t src_offset, uint64_t dst_offset, -			unsigned num_pages, struct radeon_fence *fence) +			uint64_t src_offset, +			uint64_t dst_offset, +			unsigned num_gpu_pages, +			struct radeon_fence *fence)  {  	int r;  	mutex_lock(&rdev->r600_blit.mutex);  	rdev->r600_blit.vb_ib = NULL; -	r = evergreen_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); +	r = evergreen_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE);  	if (r) {  		if (rdev->r600_blit.vb_ib)  			radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);  		mutex_unlock(&rdev->r600_blit.mutex);  		return r;  	} -	evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); +	evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE);  	evergreen_blit_done_copy(rdev, fence);  	mutex_unlock(&rdev->r600_blit.mutex);  	return 0; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 44c4750f451..8c79ca97753 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -39,6 +39,7 @@ extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev);  extern void evergreen_mc_program(struct radeon_device *rdev);  extern void evergreen_irq_suspend(struct radeon_device *rdev);  extern int evergreen_mc_init(struct radeon_device *rdev); +extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);  #define EVERGREEN_PFP_UCODE_SIZE 1120  #define EVERGREEN_PM4_UCODE_SIZE 1376 @@ -568,36 +569,6 @@ static u32 cayman_get_tile_pipe_to_backend_map(struct radeon_device *rdev,  	return backend_map;  } -static void cayman_program_channel_remap(struct radeon_device *rdev) -{ -	u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; - -	tmp = RREG32(MC_SHARED_CHMAP); -	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { -	case 0: -	case 1: -	case 2: -	case 3: -	default: -		/* default mapping */ -		mc_shared_chremap = 0x00fac688; -		break; -	} - -	switch (rdev->family) { -	case CHIP_CAYMAN: -	default: -		//tcp_chan_steer_lo = 0x54763210 -		tcp_chan_steer_lo = 0x76543210; -		tcp_chan_steer_hi = 0x0000ba98; -		break; -	} - -	WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); -	WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); -	WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); -} -  static u32 cayman_get_disable_mask_per_asic(struct radeon_device *rdev,  					    u32 disable_mask_per_se,  					    u32 max_disable_mask_per_se, @@ -669,6 +640,8 @@ static void cayman_gpu_init(struct radeon_device *rdev)  	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); +	evergreen_fix_pci_max_read_req_size(rdev); +  	mc_shared_chmap = RREG32(MC_SHARED_CHMAP);  	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); @@ -839,8 +812,6 @@ static void cayman_gpu_init(struct radeon_device *rdev)  	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);  	WREG32(HDP_ADDR_CONFIG, gb_addr_config); -	cayman_program_channel_remap(rdev); -  	/* primary versions */  	WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);  	WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); @@ -1159,6 +1130,7 @@ int cayman_cp_resume(struct radeon_device *rdev)  				 SOFT_RESET_PA |  				 SOFT_RESET_SH |  				 SOFT_RESET_VGT | +				 SOFT_RESET_SPI |  				 SOFT_RESET_SX));  	RREG32(GRBM_SOFT_RESET);  	mdelay(15); @@ -1183,7 +1155,8 @@ int cayman_cp_resume(struct radeon_device *rdev)  	/* Initialize the ring buffer's read and write pointers */  	WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); -	WREG32(CP_RB0_WPTR, 0); +	rdev->cp.wptr = 0; +	WREG32(CP_RB0_WPTR, rdev->cp.wptr);  	/* set the wb address wether it's enabled or not */  	WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1203,7 +1176,6 @@ int cayman_cp_resume(struct radeon_device *rdev)  	WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8);  	rdev->cp.rptr = RREG32(CP_RB0_RPTR); -	rdev->cp.wptr = RREG32(CP_RB0_WPTR);  	/* ring1  - compute only */  	/* Set ring buffer size */ @@ -1216,7 +1188,8 @@ int cayman_cp_resume(struct radeon_device *rdev)  	/* Initialize the ring buffer's read and write pointers */  	WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); -	WREG32(CP_RB1_WPTR, 0); +	rdev->cp1.wptr = 0; +	WREG32(CP_RB1_WPTR, rdev->cp1.wptr);  	/* set the wb address wether it's enabled or not */  	WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1228,7 +1201,6 @@ int cayman_cp_resume(struct radeon_device *rdev)  	WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8);  	rdev->cp1.rptr = RREG32(CP_RB1_RPTR); -	rdev->cp1.wptr = RREG32(CP_RB1_WPTR);  	/* ring2 - compute only */  	/* Set ring buffer size */ @@ -1241,7 +1213,8 @@ int cayman_cp_resume(struct radeon_device *rdev)  	/* Initialize the ring buffer's read and write pointers */  	WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); -	WREG32(CP_RB2_WPTR, 0); +	rdev->cp2.wptr = 0; +	WREG32(CP_RB2_WPTR, rdev->cp2.wptr);  	/* set the wb address wether it's enabled or not */  	WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1253,7 +1226,6 @@ int cayman_cp_resume(struct radeon_device *rdev)  	WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8);  	rdev->cp2.rptr = RREG32(CP_RB2_RPTR); -	rdev->cp2.wptr = RREG32(CP_RB2_WPTR);  	/* start the rings */  	cayman_cp_start(rdev); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index f2204cb1ccd..7fcdbbbf297 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -721,11 +721,11 @@ void r100_fence_ring_emit(struct radeon_device *rdev,  int r100_copy_blit(struct radeon_device *rdev,  		   uint64_t src_offset,  		   uint64_t dst_offset, -		   unsigned num_pages, +		   unsigned num_gpu_pages,  		   struct radeon_fence *fence)  {  	uint32_t cur_pages; -	uint32_t stride_bytes = PAGE_SIZE; +	uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE;  	uint32_t pitch;  	uint32_t stride_pixels;  	unsigned ndw; @@ -737,7 +737,7 @@ int r100_copy_blit(struct radeon_device *rdev,  	/* radeon pitch is /64 */  	pitch = stride_bytes / 64;  	stride_pixels = stride_bytes / 4; -	num_loops = DIV_ROUND_UP(num_pages, 8191); +	num_loops = DIV_ROUND_UP(num_gpu_pages, 8191);  	/* Ask for enough room for blit + flush + fence */  	ndw = 64 + (10 * num_loops); @@ -746,12 +746,12 @@ int r100_copy_blit(struct radeon_device *rdev,  		DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);  		return -EINVAL;  	} -	while (num_pages > 0) { -		cur_pages = num_pages; +	while (num_gpu_pages > 0) { +		cur_pages = num_gpu_pages;  		if (cur_pages > 8191) {  			cur_pages = 8191;  		} -		num_pages -= cur_pages; +		num_gpu_pages -= cur_pages;  		/* pages are in Y direction - height  		   page width in X direction - width */ @@ -773,8 +773,8 @@ int r100_copy_blit(struct radeon_device *rdev,  		radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16));  		radeon_ring_write(rdev, 0);  		radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); -		radeon_ring_write(rdev, num_pages); -		radeon_ring_write(rdev, num_pages); +		radeon_ring_write(rdev, num_gpu_pages); +		radeon_ring_write(rdev, num_gpu_pages);  		radeon_ring_write(rdev, cur_pages | (stride_pixels << 16));  	}  	radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); @@ -990,7 +990,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)  	/* Force read & write ptr to 0 */  	WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE);  	WREG32(RADEON_CP_RB_RPTR_WR, 0); -	WREG32(RADEON_CP_RB_WPTR, 0); +	rdev->cp.wptr = 0; +	WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);  	/* set the wb address whether it's enabled or not */  	WREG32(R_00070C_CP_RB_RPTR_ADDR, @@ -1007,9 +1008,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)  	WREG32(RADEON_CP_RB_CNTL, tmp);  	udelay(10);  	rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); -	rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR); -	/* protect against crazy HW on resume */ -	rdev->cp.wptr &= rdev->cp.ptr_mask;  	/* Set cp mode to bus mastering & enable cp*/  	WREG32(RADEON_CP_CSQ_MODE,  	       REG_SET(RADEON_INDIRECT2_START, indirect2_start) | diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index f2405830041..a1f3ba063c2 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -84,7 +84,7 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)  int r200_copy_dma(struct radeon_device *rdev,  		  uint64_t src_offset,  		  uint64_t dst_offset, -		  unsigned num_pages, +		  unsigned num_gpu_pages,  		  struct radeon_fence *fence)  {  	uint32_t size; @@ -93,7 +93,7 @@ int r200_copy_dma(struct radeon_device *rdev,  	int r = 0;  	/* radeon pitch is /64 */ -	size = num_pages << PAGE_SHIFT; +	size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT;  	num_loops = DIV_ROUND_UP(size, 0x1FFFFF);  	r = radeon_ring_lock(rdev, num_loops * 4 + 64);  	if (r) { diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index aa5571b73aa..720dd99163f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2209,7 +2209,8 @@ int r600_cp_resume(struct radeon_device *rdev)  	/* Initialize the ring buffer's read and write pointers */  	WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);  	WREG32(CP_RB_RPTR_WR, 0); -	WREG32(CP_RB_WPTR, 0); +	rdev->cp.wptr = 0; +	WREG32(CP_RB_WPTR, rdev->cp.wptr);  	/* set the wb address whether it's enabled or not */  	WREG32(CP_RB_RPTR_ADDR, @@ -2231,7 +2232,6 @@ int r600_cp_resume(struct radeon_device *rdev)  	WREG32(CP_DEBUG, (1 << 27) | (1 << 28));  	rdev->cp.rptr = RREG32(CP_RB_RPTR); -	rdev->cp.wptr = RREG32(CP_RB_WPTR);  	r600_cp_start(rdev);  	rdev->cp.ready = true; @@ -2353,21 +2353,23 @@ void r600_fence_ring_emit(struct radeon_device *rdev,  }  int r600_copy_blit(struct radeon_device *rdev, -		   uint64_t src_offset, uint64_t dst_offset, -		   unsigned num_pages, struct radeon_fence *fence) +		   uint64_t src_offset, +		   uint64_t dst_offset, +		   unsigned num_gpu_pages, +		   struct radeon_fence *fence)  {  	int r;  	mutex_lock(&rdev->r600_blit.mutex);  	rdev->r600_blit.vb_ib = NULL; -	r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); +	r = r600_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE);  	if (r) {  		if (rdev->r600_blit.vb_ib)  			radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);  		mutex_unlock(&rdev->r600_blit.mutex);  		return r;  	} -	r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); +	r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE);  	r600_blit_done_copy(rdev, fence);  	mutex_unlock(&rdev->r600_blit.mutex);  	return 0; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 32807baf55e..c1e056b35b2 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -322,6 +322,7 @@ union radeon_gart_table {  #define RADEON_GPU_PAGE_SIZE 4096  #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) +#define RADEON_GPU_PAGE_SHIFT 12  struct radeon_gart {  	dma_addr_t			table_addr; @@ -914,17 +915,17 @@ struct radeon_asic {  	int (*copy_blit)(struct radeon_device *rdev,  			 uint64_t src_offset,  			 uint64_t dst_offset, -			 unsigned num_pages, +			 unsigned num_gpu_pages,  			 struct radeon_fence *fence);  	int (*copy_dma)(struct radeon_device *rdev,  			uint64_t src_offset,  			uint64_t dst_offset, -			unsigned num_pages, +			unsigned num_gpu_pages,  			struct radeon_fence *fence);  	int (*copy)(struct radeon_device *rdev,  		    uint64_t src_offset,  		    uint64_t dst_offset, -		    unsigned num_pages, +		    unsigned num_gpu_pages,  		    struct radeon_fence *fence);  	uint32_t (*get_engine_clock)(struct radeon_device *rdev);  	void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 3d7a0d7c6a9..3dedaa07aac 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -75,7 +75,7 @@ uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg);  int r100_copy_blit(struct radeon_device *rdev,  		   uint64_t src_offset,  		   uint64_t dst_offset, -		   unsigned num_pages, +		   unsigned num_gpu_pages,  		   struct radeon_fence *fence);  int r100_set_surface_reg(struct radeon_device *rdev, int reg,  			 uint32_t tiling_flags, uint32_t pitch, @@ -143,7 +143,7 @@ extern void r100_post_page_flip(struct radeon_device *rdev, int crtc);  extern int r200_copy_dma(struct radeon_device *rdev,  			 uint64_t src_offset,  			 uint64_t dst_offset, -			 unsigned num_pages, +			 unsigned num_gpu_pages,  			 struct radeon_fence *fence);  void r200_set_safe_registers(struct radeon_device *rdev); @@ -311,7 +311,7 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);  int r600_ring_test(struct radeon_device *rdev);  int r600_copy_blit(struct radeon_device *rdev,  		   uint64_t src_offset, uint64_t dst_offset, -		   unsigned num_pages, struct radeon_fence *fence); +		   unsigned num_gpu_pages, struct radeon_fence *fence);  void r600_hpd_init(struct radeon_device *rdev);  void r600_hpd_fini(struct radeon_device *rdev);  bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); @@ -403,7 +403,7 @@ void evergreen_bandwidth_update(struct radeon_device *rdev);  void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);  int evergreen_copy_blit(struct radeon_device *rdev,  			uint64_t src_offset, uint64_t dst_offset, -			unsigned num_pages, struct radeon_fence *fence); +			unsigned num_gpu_pages, struct radeon_fence *fence);  void evergreen_hpd_init(struct radeon_device *rdev);  void evergreen_hpd_fini(struct radeon_device *rdev);  bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c index dcd0863e31a..b6e18c8db9f 100644 --- a/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/drivers/gpu/drm/radeon/radeon_clocks.c @@ -219,6 +219,9 @@ void radeon_get_clock_info(struct drm_device *dev)  		} else {  			DRM_INFO("Using generic clock info\n"); +			/* may need to be per card */ +			rdev->clock.max_pixel_clock = 35000; +  			if (rdev->flags & RADEON_IS_IGP) {  				p1pll->reference_freq = 1432;  				p2pll->reference_freq = 1432; diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index e0138b674ac..63675241c7f 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -3298,6 +3298,14 @@ void radeon_combios_asic_init(struct drm_device *dev)  	    rdev->pdev->subsystem_device == 0x30a4)  		return; +	/* quirk for rs4xx Compaq Presario V5245EU laptop to make it resume +	 * - it hangs on resume inside the dynclk 1 table. +	 */ +	if (rdev->family == CHIP_RS480 && +	    rdev->pdev->subsystem_vendor == 0x103c && +	    rdev->pdev->subsystem_device == 0x30ae) +		return; +  	/* DYN CLK 1 */  	table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);  	if (table) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 7f65940f918..449c3d8c683 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -68,11 +68,11 @@ void radeon_connector_hotplug(struct drm_connector *connector)  	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {  		int saved_dpms = connector->dpms; -		if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) && -		    radeon_dp_needs_link_train(radeon_connector)) -			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); -		else +		/* Only turn off the display it it's physically disconnected */ +		if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))  			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); +		else if (radeon_dp_needs_link_train(radeon_connector)) +			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);  		connector->dpms = saved_dpms;  	}  } @@ -466,6 +466,16 @@ static bool radeon_connector_needs_extended_probe(struct radeon_device *dev,  		    (supported_device == ATOM_DEVICE_DFP2_SUPPORT))  			return true;  	} +	/* TOSHIBA Satellite L300D with ATI Mobility Radeon x1100 +	 * (RS690M) sends data to i2c bus for a HDMI connector that +	 * is not implemented */ +	if ((dev->pdev->device == 0x791f) && +	    (dev->pdev->subsystem_vendor == 0x1179) && +	    (dev->pdev->subsystem_device == 0xff68)) { +		if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && +		    (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) +			return true; +	}  	/* Default: no EDID header probe required for DDC probing */  	return false; @@ -1287,12 +1297,24 @@ radeon_dp_detect(struct drm_connector *connector, bool force)  		if (!radeon_dig_connector->edp_on)  			atombios_set_edp_panel_power(connector,  						     ATOM_TRANSMITTER_ACTION_POWER_OFF); -	} else { -		/* need to setup ddc on the bridge */ -		if (radeon_connector_encoder_is_dp_bridge(connector)) { -			if (encoder) -				radeon_atom_ext_encoder_setup_ddc(encoder); +	} else if (radeon_connector_encoder_is_dp_bridge(connector)) { +		/* DP bridges are always DP */ +		radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; +		/* get the DPCD from the bridge */ +		radeon_dp_getdpcd(radeon_connector); + +		if (encoder) { +			/* setup ddc on the bridge */ +			radeon_atom_ext_encoder_setup_ddc(encoder); +			if (radeon_ddc_probe(radeon_connector, +					     radeon_connector->requires_extended_probe)) /* try DDC */ +				ret = connector_status_connected; +			else if (radeon_connector->dac_load_detect) { /* try load detection */ +				struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; +				ret = encoder_funcs->detect(encoder, connector); +			}  		} +	} else {  		radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);  		if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {  			ret = connector_status_connected; @@ -1308,16 +1330,6 @@ radeon_dp_detect(struct drm_connector *connector, bool force)  					ret = connector_status_connected;  			}  		} - -		if ((ret == connector_status_disconnected) && -		    radeon_connector->dac_load_detect) { -			struct drm_encoder *encoder = radeon_best_single_encoder(connector); -			struct drm_encoder_helper_funcs *encoder_funcs; -			if (encoder) { -				encoder_funcs = encoder->helper_private; -				ret = encoder_funcs->detect(encoder, connector); -			} -		}  	}  	radeon_connector_update_scratch_regs(connector, ret); diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 3189a7efb2e..fde25c0d65a 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -208,23 +208,25 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,  	int xorigin = 0, yorigin = 0;  	int w = radeon_crtc->cursor_width; -	if (x < 0) -		xorigin = -x + 1; -	if (y < 0) -		yorigin = -y + 1; -	if (xorigin >= CURSOR_WIDTH) -		xorigin = CURSOR_WIDTH - 1; -	if (yorigin >= CURSOR_HEIGHT) -		yorigin = CURSOR_HEIGHT - 1; -  	if (ASIC_IS_AVIVO(rdev)) { -		int i = 0; -		struct drm_crtc *crtc_p; -  		/* avivo cursor are offset into the total surface */  		x += crtc->x;  		y += crtc->y; -		DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); +	} +	DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); + +	if (x < 0) { +		xorigin = min(-x, CURSOR_WIDTH - 1); +		x = 0; +	} +	if (y < 0) { +		yorigin = min(-y, CURSOR_HEIGHT - 1); +		y = 0; +	} + +	if (ASIC_IS_AVIVO(rdev)) { +		int i = 0; +		struct drm_crtc *crtc_p;  		/* avivo cursor image can't end on 128 pixel boundary or  		 * go past the end of the frame if both crtcs are enabled @@ -253,16 +255,12 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,  	radeon_lock_cursor(crtc, true);  	if (ASIC_IS_DCE4(rdev)) { -		WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, -		       ((xorigin ? 0 : x) << 16) | -		       (yorigin ? 0 : y)); +		WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y);  		WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);  		WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset,  		       ((w - 1) << 16) | (radeon_crtc->cursor_height - 1));  	} else if (ASIC_IS_AVIVO(rdev)) { -		WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, -			     ((xorigin ? 0 : x) << 16) | -			     (yorigin ? 0 : y)); +		WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y);  		WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);  		WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,  		       ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); @@ -276,8 +274,8 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc,  			| yorigin));  		WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset,  		       (RADEON_CUR_LOCK -			| ((xorigin ? 0 : x) << 16) -			| (yorigin ? 0 : y))); +			| (x << 16) +			| y));  		/* offset is from DISP(2)_BASE_ADDRESS */  		WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, (radeon_crtc->legacy_cursor_offset +  								      (yorigin * 256))); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index a3b011b4946..b51e15725c6 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -301,6 +301,8 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64  		mc->mc_vram_size = mc->aper_size;  	}  	mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; +	if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size) +		mc->real_vram_size = radeon_vram_limit;  	dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",  			mc->mc_vram_size >> 20, mc->vram_start,  			mc->vram_end, mc->real_vram_size >> 20); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1a858944e4f..6adb3e58aff 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -473,8 +473,8 @@ pflip_cleanup:  	spin_lock_irqsave(&dev->event_lock, flags);  	radeon_crtc->unpin_work = NULL;  unlock_free: -	drm_gem_object_unreference_unlocked(old_radeon_fb->obj);  	spin_unlock_irqrestore(&dev->event_lock, flags); +	drm_gem_object_unreference_unlocked(old_radeon_fb->obj);  	radeon_fence_unref(&work->fence);  	kfree(work); @@ -707,16 +707,21 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)  		radeon_router_select_ddc_port(radeon_connector);  	if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || -	    (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { +	    (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || +	    radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) {  		struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; +  		if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||  		     dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus) -			radeon_connector->edid = drm_get_edid(&radeon_connector->base, &dig->dp_i2c_bus->adapter); -	} -	if (!radeon_connector->ddc_bus) -		return -1; -	if (!radeon_connector->edid) { -		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); +			radeon_connector->edid = drm_get_edid(&radeon_connector->base, +							      &dig->dp_i2c_bus->adapter); +		else if (radeon_connector->ddc_bus && !radeon_connector->edid) +			radeon_connector->edid = drm_get_edid(&radeon_connector->base, +							      &radeon_connector->ddc_bus->adapter); +	} else { +		if (radeon_connector->ddc_bus && !radeon_connector->edid) +			radeon_connector->edid = drm_get_edid(&radeon_connector->base, +							      &radeon_connector->ddc_bus->adapter);  	}  	if (!radeon_connector->edid) { diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 319d85d7e75..eb3f6dc6df8 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1507,7 +1507,14 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)  		switch (mode) {  		case DRM_MODE_DPMS_ON:  			args.ucAction = ATOM_ENABLE; -			atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); +			/* workaround for DVOOutputControl on some RS690 systems */ +			if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DDI) { +				u32 reg = RREG32(RADEON_BIOS_3_SCRATCH); +				WREG32(RADEON_BIOS_3_SCRATCH, reg & ~ATOM_S3_DFP2I_ACTIVE); +				atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); +				WREG32(RADEON_BIOS_3_SCRATCH, reg); +			} else +				atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);  			if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {  				args.ucAction = ATOM_LCD_BLON;  				atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); @@ -1631,7 +1638,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)  			break;  		case 2:  			args.v2.ucCRTC = radeon_crtc->crtc_id; -			args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); +			if (radeon_encoder_is_dp_bridge(encoder)) { +				struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + +				if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) +					args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; +				else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA) +					args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT; +				else +					args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder); +			} else +				args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);  			switch (radeon_encoder->encoder_id) {  			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:  			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: @@ -1748,9 +1765,17 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)  	/* DCE4/5 */  	if (ASIC_IS_DCE4(rdev)) {  		dig = radeon_encoder->enc_priv; -		if (ASIC_IS_DCE41(rdev)) -			return radeon_crtc->crtc_id; -		else { +		if (ASIC_IS_DCE41(rdev)) { +			/* ontario follows DCE4 */ +			if (rdev->family == CHIP_PALM) { +				if (dig->linkb) +					return 1; +				else +					return 0; +			} else +				/* llano follows DCE3.2 */ +				return radeon_crtc->crtc_id; +		} else {  			switch (radeon_encoder->encoder_id) {  			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:  				if (dig->linkb) diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7fd4e3e5ad5..3475a09f946 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -48,7 +48,7 @@ static void radeon_fence_write(struct radeon_device *rdev, u32 seq)  			scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;  		else  			scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; -		rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);; +		rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);  	} else  		WREG32(rdev->fence_drv.scratch_reg, seq);  } diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index dee4a0c1b4b..602fa3541c4 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -40,10 +40,14 @@ void radeon_test_moves(struct radeon_device *rdev)  	size = 1024 * 1024;  	/* Number of tests = -	 * (Total GTT - IB pool - writeback page - ring buffer) / test size +	 * (Total GTT - IB pool - writeback page - ring buffers) / test size  	 */ -	n = ((u32)(rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - RADEON_GPU_PAGE_SIZE - -	     rdev->cp.ring_size)) / size; +	n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - rdev->cp.ring_size; +	if (rdev->wb.wb_obj) +		n -= RADEON_GPU_PAGE_SIZE; +	if (rdev->ih.ring_obj) +		n -= rdev->ih.ring_size; +	n /= size;  	gtt_obj = kzalloc(n * sizeof(*gtt_obj), GFP_KERNEL);  	if (!gtt_obj) { @@ -132,9 +136,15 @@ void radeon_test_moves(struct radeon_device *rdev)  		     gtt_start++, vram_start++) {  			if (*vram_start != gtt_start) {  				DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, " -					  "expected 0x%p (GTT map 0x%p-0x%p)\n", -					  i, *vram_start, gtt_start, gtt_map, -					  gtt_end); +					  "expected 0x%p (GTT/VRAM offset " +					  "0x%16llx/0x%16llx)\n", +					  i, *vram_start, gtt_start, +					  (unsigned long long) +					  (gtt_addr - rdev->mc.gtt_start + +					   (void*)gtt_start - gtt_map), +					  (unsigned long long) +					  (vram_addr - rdev->mc.vram_start + +					   (void*)gtt_start - gtt_map));  				radeon_bo_kunmap(vram_obj);  				goto out_cleanup;  			} @@ -175,9 +185,15 @@ void radeon_test_moves(struct radeon_device *rdev)  		     gtt_start++, vram_start++) {  			if (*gtt_start != vram_start) {  				DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, " -					  "expected 0x%p (VRAM map 0x%p-0x%p)\n", -					  i, *gtt_start, vram_start, vram_map, -					  vram_end); +					  "expected 0x%p (VRAM/GTT offset " +					  "0x%16llx/0x%16llx)\n", +					  i, *gtt_start, vram_start, +					  (unsigned long long) +					  (vram_addr - rdev->mc.vram_start + +					   (void*)vram_start - vram_map), +					  (unsigned long long) +					  (gtt_addr - rdev->mc.gtt_start + +					   (void*)vram_start - vram_map));  				radeon_bo_kunmap(gtt_obj[i]);  				goto out_cleanup;  			} diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 60125ddba1e..0b5468bfaf5 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -277,7 +277,12 @@ static int radeon_move_blit(struct ttm_buffer_object *bo,  		DRM_ERROR("Trying to move memory with CP turned off.\n");  		return -EINVAL;  	} -	r = radeon_copy(rdev, old_start, new_start, new_mem->num_pages, fence); + +	BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); + +	r = radeon_copy(rdev, old_start, new_start, +			new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ +			fence);  	/* FIXME: handle copy error */  	r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL,  				      evict, no_wait_reserve, no_wait_gpu, new_mem); @@ -450,6 +455,29 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_  			return -EINVAL;  		mem->bus.base = rdev->mc.aper_base;  		mem->bus.is_iomem = true; +#ifdef __alpha__ +		/* +		 * Alpha: use bus.addr to hold the ioremap() return, +		 * so we can modify bus.base below. +		 */ +		if (mem->placement & TTM_PL_FLAG_WC) +			mem->bus.addr = +				ioremap_wc(mem->bus.base + mem->bus.offset, +					   mem->bus.size); +		else +			mem->bus.addr = +				ioremap_nocache(mem->bus.base + mem->bus.offset, +						mem->bus.size); + +		/* +		 * Alpha: Use just the bus offset plus +		 * the hose/domain memory base for bus.base. +		 * It then can be used to build PTEs for VRAM +		 * access, as done in ttm_bo_vm_fault(). +		 */ +		mem->bus.base = (mem->bus.base & 0x0ffffffffUL) + +			rdev->ddev->hose->dense_mem_base; +#endif  		break;  	default:  		return -EINVAL; diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4720d000d44..b13c2eedc32 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -536,55 +536,6 @@ static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev,  	return backend_map;  } -static void rv770_program_channel_remap(struct radeon_device *rdev) -{ -	u32 tcp_chan_steer, mc_shared_chremap, tmp; -	bool force_no_swizzle; - -	switch (rdev->family) { -	case CHIP_RV770: -	case CHIP_RV730: -		force_no_swizzle = false; -		break; -	case CHIP_RV710: -	case CHIP_RV740: -	default: -		force_no_swizzle = true; -		break; -	} - -	tmp = RREG32(MC_SHARED_CHMAP); -	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { -	case 0: -	case 1: -	default: -		/* default mapping */ -		mc_shared_chremap = 0x00fac688; -		break; -	case 2: -	case 3: -		if (force_no_swizzle) -			mc_shared_chremap = 0x00fac688; -		else -			mc_shared_chremap = 0x00bbc298; -		break; -	} - -	if (rdev->family == CHIP_RV740) -		tcp_chan_steer = 0x00ef2a60; -	else -		tcp_chan_steer = 0x00fac688; - -	/* RV770 CE has special chremap setup */ -	if (rdev->pdev->device == 0x944e) { -		tcp_chan_steer = 0x00b08b08; -		mc_shared_chremap = 0x00b08b08; -	} - -	WREG32(TCP_CHAN_STEER, tcp_chan_steer); -	WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); -} -  static void rv770_gpu_init(struct radeon_device *rdev)  {  	int i, j, num_qd_pipes; @@ -785,8 +736,6 @@ static void rv770_gpu_init(struct radeon_device *rdev)  	WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));  	WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); -	rv770_program_channel_remap(rdev); -  	WREG32(CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);  	WREG32(CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);  	WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 56619f64b6b..ef06194c5aa 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -353,8 +353,10 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)  		ret = ttm_tt_set_user(bo->ttm, current,  				      bo->buffer_start, bo->num_pages); -		if (unlikely(ret != 0)) +		if (unlikely(ret != 0)) {  			ttm_tt_destroy(bo->ttm); +			bo->ttm = NULL; +		}  		break;  	default:  		printk(KERN_ERR TTM_PFX "Illegal buffer object type\n"); @@ -390,10 +392,13 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,  	 * Create and bind a ttm if required.  	 */ -	if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED) && (bo->ttm == NULL)) { -		ret = ttm_bo_add_ttm(bo, false); -		if (ret) -			goto out_err; +	if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) { +		if (bo->ttm == NULL) { +			bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED); +			ret = ttm_bo_add_ttm(bo, zero); +			if (ret) +				goto out_err; +		}  		ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);  		if (ret) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 77dbf408c0d..082fcaea583 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -321,7 +321,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,  	struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];  	struct ttm_tt *ttm = bo->ttm;  	struct ttm_mem_reg *old_mem = &bo->mem; -	struct ttm_mem_reg old_copy; +	struct ttm_mem_reg old_copy = *old_mem;  	void *old_iomap;  	void *new_iomap;  	int ret; @@ -635,13 +635,13 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,  		if (ret)  			return ret; -		ttm_bo_free_old_node(bo);  		if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&  		    (bo->ttm != NULL)) {  			ttm_tt_unbind(bo->ttm);  			ttm_tt_destroy(bo->ttm);  			bo->ttm = NULL;  		} +		ttm_bo_free_old_node(bo);  	} else {  		/**  		 * This should help pipeline ordinary buffer moves.  |