diff options
Diffstat (limited to 'drivers/gpu')
26 files changed, 211 insertions, 60 deletions
| diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index c58f691ec3ce..b493663c7ba7 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -24,6 +24,7 @@ config DRM_KMS_HELPER  	depends on DRM  	select FB  	select FRAMEBUFFER_CONSOLE if !EXPERT +	select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE  	help  	  FB and CRTC helpers for KMS drivers. diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 950720473967..140b9525b48a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -342,9 +342,22 @@ int drm_fb_helper_debug_leave(struct fb_info *info)  }  EXPORT_SYMBOL(drm_fb_helper_debug_leave); +bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) +{ +	bool error = false; +	int i, ret; +	for (i = 0; i < fb_helper->crtc_count; i++) { +		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; +		ret = drm_crtc_helper_set_config(mode_set); +		if (ret) +			error = true; +	} +	return error; +} +EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode); +  bool drm_fb_helper_force_kernel_mode(void)  { -	int i = 0;  	bool ret, error = false;  	struct drm_fb_helper *helper; @@ -352,12 +365,12 @@ bool drm_fb_helper_force_kernel_mode(void)  		return false;  	list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { -		for (i = 0; i < helper->crtc_count; i++) { -			struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; -			ret = drm_crtc_helper_set_config(mode_set); -			if (ret) -				error = true; -		} +		if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF) +			continue; + +		ret = drm_fb_helper_restore_fbdev_mode(helper); +		if (ret) +			error = true;  	}  	return error;  } @@ -1503,17 +1516,33 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)  }  EXPORT_SYMBOL(drm_fb_helper_initial_config); -bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) +/** + * drm_fb_helper_hotplug_event - respond to a hotplug notification by + *                               probing all the outputs attached to the fb. + * @fb_helper: the drm_fb_helper + * + * LOCKING: + * Called at runtime, must take mode config lock. + * + * Scan the connectors attached to the fb_helper and try to put together a + * setup after *notification of a change in output configuration. + * + * RETURNS: + * 0 on success and a non-zero error code otherwise. + */ +int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)  { +	struct drm_device *dev = fb_helper->dev;  	int count = 0;  	u32 max_width, max_height, bpp_sel;  	bool bound = false, crtcs_bound = false;  	struct drm_crtc *crtc;  	if (!fb_helper->fb) -		return false; +		return 0; -	list_for_each_entry(crtc, &fb_helper->dev->mode_config.crtc_list, head) { +	mutex_lock(&dev->mode_config.mutex); +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {  		if (crtc->fb)  			crtcs_bound = true;  		if (crtc->fb == fb_helper->fb) @@ -1522,7 +1551,8 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)  	if (!bound && crtcs_bound) {  		fb_helper->delayed_hotplug = true; -		return false; +		mutex_unlock(&dev->mode_config.mutex); +		return 0;  	}  	DRM_DEBUG_KMS("\n"); @@ -1533,6 +1563,7 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)  	count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,  						    max_height);  	drm_setup_crtcs(fb_helper); +	mutex_unlock(&dev->mode_config.mutex);  	return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);  } diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 741457bd1c46..a1f12cb043de 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -932,11 +932,34 @@ EXPORT_SYMBOL(drm_vblank_put);  void drm_vblank_off(struct drm_device *dev, int crtc)  { +	struct drm_pending_vblank_event *e, *t; +	struct timeval now;  	unsigned long irqflags; +	unsigned int seq;  	spin_lock_irqsave(&dev->vbl_lock, irqflags);  	vblank_disable_and_save(dev, crtc);  	DRM_WAKEUP(&dev->vbl_queue[crtc]); + +	/* Send any queued vblank events, lest the natives grow disquiet */ +	seq = drm_vblank_count_and_time(dev, crtc, &now); +	list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { +		if (e->pipe != crtc) +			continue; +		DRM_DEBUG("Sending premature vblank event on disable: \ +			  wanted %d, current %d\n", +			  e->event.sequence, seq); + +		e->event.sequence = seq; +		e->event.tv_sec = now.tv_sec; +		e->event.tv_usec = now.tv_usec; +		drm_vblank_put(dev, e->pipe); +		list_move_tail(&e->base.link, &e->base.file_priv->event_list); +		wake_up_interruptible(&e->base.file_priv->event_wait); +		trace_drm_vblank_event_delivered(e->base.pid, e->pipe, +						 e->event.sequence); +	} +  	spin_unlock_irqrestore(&dev->vbl_lock, irqflags);  }  EXPORT_SYMBOL(drm_vblank_off); diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 5d00b0fc0d91..959186cbf328 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -431,7 +431,7 @@ EXPORT_SYMBOL(drm_mm_search_free_in_range);  void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new)  {  	list_replace(&old->node_list, &new->node_list); -	list_replace(&old->node_list, &new->hole_stack); +	list_replace(&old->hole_stack, &new->hole_stack);  	new->hole_follows = old->hole_follows;  	new->mm = old->mm;  	new->start = old->start; @@ -699,8 +699,8 @@ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)  				entry->size);  		total_used += entry->size;  		if (entry->hole_follows) { -			hole_start = drm_mm_hole_node_start(&mm->head_node); -			hole_end = drm_mm_hole_node_end(&mm->head_node); +			hole_start = drm_mm_hole_node_start(entry); +			hole_end = drm_mm_hole_node_end(entry);  			hole_size = hole_end - hole_start;  			seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n",  					hole_start, hole_end, hole_size); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 72730377a01b..12876f2795d2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2207,7 +2207,7 @@ void i915_driver_lastclose(struct drm_device * dev)  	drm_i915_private_t *dev_priv = dev->dev_private;  	if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { -		drm_fb_helper_restore(); +		intel_fb_restore_mode(dev);  		vga_switcheroo_process_delayed_switch();  		return;  	} diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c34a8dd31d02..32d1b3e829c8 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -49,7 +49,7 @@ module_param_named(panel_ignore_lid, i915_panel_ignore_lid, int, 0600);  unsigned int i915_powersave = 1;  module_param_named(powersave, i915_powersave, int, 0600); -unsigned int i915_semaphores = 1; +unsigned int i915_semaphores = 0;  module_param_named(semaphores, i915_semaphores, int, 0600);  unsigned int i915_enable_rc6 = 0; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e522c702b04e..2166ee071ddb 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5605,9 +5605,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)  	intel_clock_t clock;  	if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) -		fp = FP0(pipe); +		fp = I915_READ(FP0(pipe));  	else -		fp = FP1(pipe); +		fp = I915_READ(FP1(pipe));  	clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;  	if (IS_PINEVIEW(dev)) { @@ -6579,8 +6579,10 @@ intel_user_framebuffer_create(struct drm_device *dev,  		return ERR_PTR(-ENOENT);  	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); -	if (!intel_fb) +	if (!intel_fb) { +		drm_gem_object_unreference_unlocked(&obj->base);  		return ERR_PTR(-ENOMEM); +	}  	ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);  	if (ret) { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cb8578b7e443..a4d80314e7f8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1470,7 +1470,8 @@ intel_dp_link_down(struct intel_dp *intel_dp)  	if (!HAS_PCH_CPT(dev) &&  	    I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { -		struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); +		struct drm_crtc *crtc = intel_dp->base.base.crtc; +  		/* Hardware workaround: leaving our transcoder select  		 * set to transcoder B while it's off will prevent the  		 * corresponding HDMI output on transcoder A. @@ -1485,7 +1486,19 @@ intel_dp_link_down(struct intel_dp *intel_dp)  		/* Changes to enable or select take place the vblank  		 * after being written.  		 */ -		intel_wait_for_vblank(dev, intel_crtc->pipe); +		if (crtc == NULL) { +			/* We can arrive here never having been attached +			 * to a CRTC, for instance, due to inheriting +			 * random state from the BIOS. +			 * +			 * If the pipe is not running, play safe and +			 * wait for the clocks to stabilise before +			 * continuing. +			 */ +			POSTING_READ(intel_dp->output_reg); +			msleep(50); +		} else +			intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);  	}  	I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f5b0d8306d83..1d20712d527f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -338,4 +338,5 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data,  			       struct drm_file *file_priv);  extern void intel_fb_output_poll_changed(struct drm_device *dev); +extern void intel_fb_restore_mode(struct drm_device *dev);  #endif /* __INTEL_DRV_H__ */ diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 512782728e51..ec49bae73382 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -264,3 +264,13 @@ void intel_fb_output_poll_changed(struct drm_device *dev)  	drm_i915_private_t *dev_priv = dev->dev_private;  	drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper);  } + +void intel_fb_restore_mode(struct drm_device *dev) +{ +	int ret; +	drm_i915_private_t *dev_priv = dev->dev_private; + +	ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); +	if (ret) +		DRM_DEBUG("failed to restore crtc mode\n"); +} diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index a562bd2648c7..67cb076d271b 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -539,6 +539,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,  	struct drm_device *dev = dev_priv->dev;  	struct drm_connector *connector = dev_priv->int_lvds_connector; +	if (dev->switch_power_state != DRM_SWITCH_POWER_ON) +		return NOTIFY_OK; +  	/*  	 * check and update the status of LVDS connector after receiving  	 * the LID nofication event. diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 5045f8b921d6..c3e953b08992 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -152,8 +152,6 @@ nouveau_mem_vram_fini(struct drm_device *dev)  {  	struct drm_nouveau_private *dev_priv = dev->dev_private; -	nouveau_bo_ref(NULL, &dev_priv->vga_ram); -  	ttm_bo_device_release(&dev_priv->ttm.bdev);  	nouveau_ttm_global_release(dev_priv); diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 4bce801bc588..c77111eca6ac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -42,7 +42,8 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages,  	nvbe->nr_pages = 0;  	while (num_pages--) { -		if (dma_addrs[nvbe->nr_pages] != DMA_ERROR_CODE) { +		/* this code path isn't called and is incorrect anyways */ +		if (0) { /*dma_addrs[nvbe->nr_pages] != DMA_ERROR_CODE)*/  			nvbe->pages[nvbe->nr_pages] =  					dma_addrs[nvbe->nr_pages];  		 	nvbe->ttm_alloced[nvbe->nr_pages] = true; diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index a30adec5beaa..915fbce89595 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -768,6 +768,11 @@ static void nouveau_card_takedown(struct drm_device *dev)  	engine->mc.takedown(dev);  	engine->display.late_takedown(dev); +	if (dev_priv->vga_ram) { +		nouveau_bo_unpin(dev_priv->vga_ram); +		nouveau_bo_ref(NULL, &dev_priv->vga_ram); +	} +  	mutex_lock(&dev->struct_mutex);  	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);  	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e9bc135d9189..9073e3bfb08c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -862,9 +862,15 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev)  		SYSTEM_ACCESS_MODE_NOT_IN_SYS |  		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |  		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); -	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); -	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); -	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); +	if (rdev->flags & RADEON_IS_IGP) { +		WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); +		WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); +		WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); +	} else { +		WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); +		WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); +		WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); +	}  	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);  	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);  	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); @@ -1774,7 +1780,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev)  	mc_shared_chmap = RREG32(MC_SHARED_CHMAP); -	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); +	if (rdev->flags & RADEON_IS_IGP) +		mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG); +	else +		mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);  	switch (rdev->config.evergreen.max_tile_pipes) {  	case 1: @@ -2923,11 +2932,6 @@ static int evergreen_startup(struct radeon_device *rdev)  		rdev->asic->copy = NULL;  		dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);  	} -	/* XXX: ontario has problems blitting to gart at the moment */ -	if (rdev->family == CHIP_PALM) { -		rdev->asic->copy = NULL; -		radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); -	}  	/* allocate wb buffer */  	r = radeon_wb_init(rdev); diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 9aaa3f0c9372..fc40e0cc3451 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -200,6 +200,7 @@  #define		BURSTLENGTH_SHIFT				9  #define		BURSTLENGTH_MASK				0x00000200  #define		CHANSIZE_OVERRIDE				(1 << 11) +#define	FUS_MC_ARB_RAMCFG				0x2768  #define	MC_VM_AGP_TOP					0x2028  #define	MC_VM_AGP_BOT					0x202C  #define	MC_VM_AGP_BASE					0x2030 @@ -221,6 +222,11 @@  #define	MC_VM_MD_L1_TLB0_CNTL				0x2654  #define	MC_VM_MD_L1_TLB1_CNTL				0x2658  #define	MC_VM_MD_L1_TLB2_CNTL				0x265C + +#define	FUS_MC_VM_MD_L1_TLB0_CNTL			0x265C +#define	FUS_MC_VM_MD_L1_TLB1_CNTL			0x2660 +#define	FUS_MC_VM_MD_L1_TLB2_CNTL			0x2664 +  #define	MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR		0x203C  #define	MC_VM_SYSTEM_APERTURE_HIGH_ADDR			0x2038  #define	MC_VM_SYSTEM_APERTURE_LOW_ADDR			0x2034 diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 7aade20f63a8..3d8a7634bbe9 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -674,7 +674,7 @@ static void cayman_gpu_init(struct radeon_device *rdev)  	cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE);  	cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); -	cgts_tcc_disable = RREG32(CGTS_TCC_DISABLE); +	cgts_tcc_disable = 0xff000000;  	gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE);  	gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG);  	cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); @@ -871,7 +871,7 @@ static void cayman_gpu_init(struct radeon_device *rdev)  	smx_dc_ctl0 = RREG32(SMX_DC_CTL0);  	smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); -	smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); +	smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);  	WREG32(SMX_DC_CTL0, smx_dc_ctl0);  	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE); @@ -887,20 +887,20 @@ static void cayman_gpu_init(struct radeon_device *rdev)  	WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO); -	WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | -					POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | -					SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); +	WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) | +					POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) | +					SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1))); -	WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) | -				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) | -				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size))); +	WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) | +				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) | +				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));  	WREG32(VGT_NUM_INSTANCES, 1);  	WREG32(CP_PERFMON_CNTL, 0); -	WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) | +	WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |  				  FETCH_FIFO_HIWATER(0x4) |  				  DONE_FIFO_HIWATER(0xe0) |  				  ALU_UPDATE_FIFO_HIWATER(0x8))); diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index f5d12fb103fa..90dfb2b8cf03 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -431,7 +431,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,  		}  	} -	/* Acer laptop (Acer TravelMate 5730G) has an HDMI port +	/* Acer laptop (Acer TravelMate 5730/5730G) has an HDMI port  	 * on the laptop and a DVI port on the docking station and  	 * both share the same encoder, hpd pin, and ddc line.  	 * So while the bios table is technically correct, @@ -440,7 +440,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,  	 * with different crtcs which isn't possible on the hardware  	 * side and leaves no crtcs for LVDS or VGA.  	 */ -	if ((dev->pdev->device == 0x95c4) && +	if (((dev->pdev->device == 0x95c4) || (dev->pdev->device == 0x9591)) &&  	    (dev->pdev->subsystem_vendor == 0x1025) &&  	    (dev->pdev->subsystem_device == 0x013c)) {  		if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && @@ -1574,9 +1574,17 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct  			ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record;  			ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record;  			bool bad_record = false; -			u8 *record = (u8 *)(mode_info->atom_context->bios + -					    data_offset + -					    le16_to_cpu(lvds_info->info.usModePatchTableOffset)); +			u8 *record; + +			if ((frev == 1) && (crev < 2)) +				/* absolute */ +				record = (u8 *)(mode_info->atom_context->bios + +						le16_to_cpu(lvds_info->info.usModePatchTableOffset)); +			else +				/* relative */ +				record = (u8 *)(mode_info->atom_context->bios + +						data_offset + +						le16_to_cpu(lvds_info->info.usModePatchTableOffset));  			while (*record != ATOM_RECORD_END_TYPE) {  				switch (*record) {  				case LCD_MODE_PATCH_RECORD_MODE_TYPE: @@ -1599,9 +1607,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct  							memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],  							       fake_edid_record->ucFakeEDIDLength); -							if (drm_edid_is_valid(edid)) +							if (drm_edid_is_valid(edid)) {  								rdev->mode_info.bios_hardcoded_edid = edid; -							else +								rdev->mode_info.bios_hardcoded_edid_size = edid_size; +							} else  								kfree(edid);  						}  					} diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index ed5dfe58f29c..9d95792bea3e 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -15,6 +15,9 @@  #define ATPX_VERSION 0  #define ATPX_GPU_PWR 2  #define ATPX_MUX_SELECT 3 +#define ATPX_I2C_MUX_SELECT 4 +#define ATPX_SWITCH_START 5 +#define ATPX_SWITCH_END 6  #define ATPX_INTEGRATED 0  #define ATPX_DISCRETE 1 @@ -149,13 +152,35 @@ static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id)  	return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id);  } +static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id) +{ +	return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id); +} + +static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id) +{ +	return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id); +} + +static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id) +{ +	return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id); +}  static int radeon_atpx_switchto(enum vga_switcheroo_client_id id)  { +	int gpu_id; +  	if (id == VGA_SWITCHEROO_IGD) -		radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 0); +		gpu_id = ATPX_INTEGRATED;  	else -		radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 1); +		gpu_id = ATPX_DISCRETE; + +	radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id); +	radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id); +	radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id); +	radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id); +  	return 0;  } diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index bdf2fa1189ae..3189a7efb2e9 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c @@ -167,9 +167,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,  		return -EINVAL;  	} -	radeon_crtc->cursor_width = width; -	radeon_crtc->cursor_height = height; -  	obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);  	if (!obj) {  		DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); @@ -180,6 +177,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc,  	if (ret)  		goto fail; +	radeon_crtc->cursor_width = width; +	radeon_crtc->cursor_height = height; +  	radeon_lock_cursor(crtc, true);  	/* XXX only 27 bit offset for legacy cursor */  	radeon_set_cursor(crtc, obj, gpu_addr); diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 8a955bbdb608..a533f52fd163 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -181,9 +181,9 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,  	p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE);  	for (i = 0; i < pages; i++, p++) { -		/* On TTM path, we only use the DMA API if TTM_PAGE_FLAG_DMA32 -		 * is requested. */ -		if (dma_addr[i] != DMA_ERROR_CODE) { +		/* we reverted the patch using dma_addr in TTM for now but this +		 * code stops building on alpha so just comment it out for now */ +		if (0) { /*dma_addr[i] != DMA_ERROR_CODE) */  			rdev->gart.ttm_alloced[p] = true;  			rdev->gart.pages_addr[p] = dma_addr[i];  		} else { diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index bf7d4c061451..bd58af658581 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -221,6 +221,22 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  			return -EINVAL;  		}  		break; +	case RADEON_INFO_NUM_TILE_PIPES: +		if (rdev->family >= CHIP_CAYMAN) +			value = rdev->config.cayman.max_tile_pipes; +		else if (rdev->family >= CHIP_CEDAR) +			value = rdev->config.evergreen.max_tile_pipes; +		else if (rdev->family >= CHIP_RV770) +			value = rdev->config.rv770.max_tile_pipes; +		else if (rdev->family >= CHIP_R600) +			value = rdev->config.r600.max_tile_pipes; +		else { +			return -EINVAL; +		} +		break; +	case RADEON_INFO_FUSION_GART_WORKING: +		value = 1; +		break;  	default:  		DRM_DEBUG_KMS("Invalid request %d\n", info->request);  		return -EINVAL; diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman index 6334f8ac1209..0aa8e85a9457 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/cayman +++ b/drivers/gpu/drm/radeon/reg_srcs/cayman @@ -33,6 +33,7 @@ cayman 0x9400  0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS  0x00009100 SPI_CONFIG_CNTL  0x0000913C SPI_CONFIG_CNTL_1 +0x00009508 TA_CNTL_AUX  0x00009830 DB_DEBUG  0x00009834 DB_DEBUG2  0x00009838 DB_DEBUG3 diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen index 7e1637176e08..0e28cae7ea43 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/evergreen +++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen @@ -46,6 +46,7 @@ evergreen 0x9400  0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS  0x00009100 SPI_CONFIG_CNTL  0x0000913C SPI_CONFIG_CNTL_1 +0x00009508 TA_CNTL_AUX  0x00009700 VC_CNTL  0x00009714 VC_ENHANCE  0x00009830 DB_DEBUG diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index af0da4ae3f55..92f1900dc7ca 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 @@ -708,6 +708,7 @@ r600 0x9400  0x00028D0C DB_RENDER_CONTROL  0x00028D10 DB_RENDER_OVERRIDE  0x0002880C DB_SHADER_CONTROL +0x00028D28 DB_SRESULTS_COMPARE_STATE0  0x00028D2C DB_SRESULTS_COMPARE_STATE1  0x00028430 DB_STENCILREFMASK  0x00028434 DB_STENCILREFMASK_BF diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index e01cacba685f..498b284e5ef9 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -219,9 +219,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)  	int i;  	struct vga_switcheroo_client *active = NULL; -	if (new_client->active == true) -		return 0; -  	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) {  		if (vgasr_priv.clients[i].active == true) {  			active = &vgasr_priv.clients[i]; @@ -372,6 +369,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,  		goto out;  	} +	if (client->active == true) +		goto out; +  	/* okay we want a switch - test if devices are willing to switch */  	can_switch = true;  	for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { |