diff options
Diffstat (limited to 'drivers/gpu/drm')
156 files changed, 4858 insertions, 3044 deletions
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index d68888fe3df..ba38e014722 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c @@ -33,6 +33,7 @@  #include "drmP.h"  #include <linux/module.h> +#include <linux/slab.h>  #if __OS_HAS_AGP diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 8417cc4c43f..f7ba82ebf65 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c @@ -34,6 +34,7 @@   */  #include <linux/vmalloc.h> +#include <linux/slab.h>  #include <linux/log2.h>  #include <asm/shmparam.h>  #include "drmP.h" diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d91fb8c0b7b..61b9bcfdf04 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -30,6 +30,7 @@   *      Jesse Barnes <jesse.barnes@intel.com>   */  #include <linux/list.h> +#include <linux/slab.h>  #include "drm.h"  #include "drmP.h"  #include "drm_crtc.h" diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index f2aaf39be39..51103aa469f 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,  	if (connector->status == connector_status_disconnected) {  		DRM_DEBUG_KMS("%s is disconnected\n",  			  drm_get_connector_name(connector)); +		drm_mode_connector_update_edid_property(connector, NULL);  		goto prune;  	} diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 9903f270e44..677b275fa72 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -32,6 +32,7 @@  #include <linux/debugfs.h>  #include <linux/seq_file.h> +#include <linux/slab.h>  #include "drmP.h"  #if defined(CONFIG_DEBUG_FS) diff --git a/drivers/gpu/drm/drm_dp_i2c_helper.c b/drivers/gpu/drm/drm_dp_i2c_helper.c index 548887c8506..f7eba0a0973 100644 --- a/drivers/gpu/drm/drm_dp_i2c_helper.c +++ b/drivers/gpu/drm/drm_dp_i2c_helper.c @@ -23,7 +23,6 @@  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/delay.h> -#include <linux/slab.h>  #include <linux/init.h>  #include <linux/errno.h>  #include <linux/sched.h> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index f3c58e2bd75..4a66201edae 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -47,6 +47,7 @@   */  #include <linux/debugfs.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm_core.h" diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f97e7c42ac8..18f41d7061f 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -27,6 +27,7 @@   * DEALINGS IN THE SOFTWARE.   */  #include <linux/kernel.h> +#include <linux/slab.h>  #include <linux/i2c.h>  #include <linux/i2c-algo-bit.h>  #include "drmP.h" @@ -84,6 +85,8 @@ static struct edid_quirk {  	/* Envision Peripherals, Inc. EN-7100e */  	{ "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH }, +	/* Envision EN2028 */ +	{ "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },  	/* Funai Electronics PM36B */  	{ "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 | @@ -707,15 +710,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,  	mode->vsync_end = mode->vsync_start + vsync_pulse_width;  	mode->vtotal = mode->vdisplay + vblank; -	/* perform the basic check for the detailed timing */ -	if (mode->hsync_end > mode->htotal || -		mode->vsync_end > mode->vtotal) { -		drm_mode_destroy(dev, mode); -		DRM_DEBUG_KMS("Incorrect detailed timing. " -				"Sync is beyond the blank.\n"); -		return NULL; -	} -  	/* Some EDIDs have bogus h/vtotal values */  	if (mode->hsync_end > mode->htotal)  		mode->htotal = mode->hsync_end + 1; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 50549703584..288ea2f3277 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -29,6 +29,7 @@   */  #include <linux/kernel.h>  #include <linux/sysrq.h> +#include <linux/slab.h>  #include <linux/fb.h>  #include "drmP.h"  #include "drm_crtc.h" @@ -283,6 +284,8 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {  	.help_msg = "force-fb(V)",  	.action_msg = "Restore framebuffer console",  }; +#else +static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };  #endif  static void drm_fb_helper_on(struct fb_info *info) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 08d14df3bb4..9d532d7fdf5 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -36,6 +36,7 @@  #include "drmP.h"  #include <linux/poll.h> +#include <linux/slab.h>  #include <linux/smp_lock.h>  static int drm_open_helper(struct inode *inode, struct file *filp, @@ -140,14 +141,16 @@ int drm_open(struct inode *inode, struct file *filp)  		spin_unlock(&dev->count_lock);  	}  out: -	mutex_lock(&dev->struct_mutex); -	if (minor->type == DRM_MINOR_LEGACY) { -		BUG_ON((dev->dev_mapping != NULL) && -			(dev->dev_mapping != inode->i_mapping)); -		if (dev->dev_mapping == NULL) -			dev->dev_mapping = inode->i_mapping; +	if (!retcode) { +		mutex_lock(&dev->struct_mutex); +		if (minor->type == DRM_MINOR_LEGACY) { +			if (dev->dev_mapping == NULL) +				dev->dev_mapping = inode->i_mapping; +			else if (dev->dev_mapping != inode->i_mapping) +				retcode = -ENODEV; +		} +		mutex_unlock(&dev->struct_mutex);  	} -	mutex_unlock(&dev->struct_mutex);  	return retcode;  } diff --git a/drivers/gpu/drm/drm_hashtab.c b/drivers/gpu/drm/drm_hashtab.c index f36b21c5b2e..a93d7b4ddaa 100644 --- a/drivers/gpu/drm/drm_hashtab.c +++ b/drivers/gpu/drm/drm_hashtab.c @@ -35,6 +35,7 @@  #include "drmP.h"  #include "drm_hashtab.h"  #include <linux/hash.h> +#include <linux/slab.h>  int drm_ht_create(struct drm_open_hash *ht, unsigned int order)  { diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index b98384dbd9a..a263b7070fc 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -36,6 +36,7 @@  #include "drmP.h"  #include <linux/interrupt.h>	/* For task queue support */ +#include <linux/slab.h>  #include <linux/vgaarb.h>  /** @@ -475,6 +476,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)  	unsigned long irqflags;  	spin_lock_irqsave(&dev->vbl_lock, irqflags); +	dev->driver->disable_vblank(dev, crtc);  	DRM_WAKEUP(&dev->vbl_queue[crtc]);  	dev->vblank_enabled[crtc] = 0;  	dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c index e4865f99989..7732268eced 100644 --- a/drivers/gpu/drm/drm_memory.c +++ b/drivers/gpu/drm/drm_memory.c @@ -77,7 +77,7 @@ static void *agp_remap(unsigned long offset, unsigned long size,  		    && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=  		    (offset + size))  			break; -	if (!agpmem) +	if (&agpmem->head == &dev->agp->memory)  		return NULL;  	/* diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index e68ebf92fa2..2ea9ad4a8d6 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -37,6 +37,7 @@   */  #include <linux/pci.h> +#include <linux/slab.h>  #include <linux/dma-mapping.h>  #include "drmP.h" diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index d379c4f2892..a9ba6b69ad3 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c @@ -38,6 +38,7 @@   */  #include <linux/seq_file.h> +#include <linux/slab.h>  #include "drmP.h"  /*************************************************** diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c index c7823c863d4..9034c4c6100 100644 --- a/drivers/gpu/drm/drm_scatter.c +++ b/drivers/gpu/drm/drm_scatter.c @@ -32,6 +32,7 @@   */  #include <linux/vmalloc.h> +#include <linux/slab.h>  #include "drmP.h"  #define DEBUG_SCATTER 0 diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index ad73e141afd..a0c365f2e52 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -33,6 +33,7 @@  #include <linux/module.h>  #include <linux/moduleparam.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm_core.h" @@ -515,8 +516,6 @@ void drm_put_dev(struct drm_device *dev)  	}  	driver = dev->driver; -	drm_vblank_cleanup(dev); -  	drm_lastclose(dev);  	if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && @@ -536,6 +535,8 @@ void drm_put_dev(struct drm_device *dev)  		dev->agp = NULL;  	} +	drm_vblank_cleanup(dev); +  	list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)  		drm_rmmap(dev, r_list->map);  	drm_ht_remove(&dev->map_hash); diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 014ce24761b..25bbd30ed7a 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -14,6 +14,7 @@  #include <linux/device.h>  #include <linux/kdev_t.h> +#include <linux/gfp.h>  #include <linux/err.h>  #include "drm_sysfs.h" @@ -353,7 +354,10 @@ static struct bin_attribute edid_attr = {  int drm_sysfs_connector_add(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev; -	int ret = 0, i, j; +	int attr_cnt = 0; +	int opt_cnt = 0; +	int i; +	int ret = 0;  	/* We shouldn't get called more than once for the same connector */  	BUG_ON(device_is_registered(&connector->kdev)); @@ -376,8 +380,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)  	/* Standard attributes */ -	for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) { -		ret = device_create_file(&connector->kdev, &connector_attrs[i]); +	for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) { +		ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]);  		if (ret)  			goto err_out_files;  	} @@ -393,8 +397,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)  		case DRM_MODE_CONNECTOR_SVIDEO:  		case DRM_MODE_CONNECTOR_Component:  		case DRM_MODE_CONNECTOR_TV: -			for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) { -				ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]); +			for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) { +				ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]);  				if (ret)  					goto err_out_files;  			} @@ -413,10 +417,10 @@ int drm_sysfs_connector_add(struct drm_connector *connector)  	return 0;  err_out_files: -	if (i > 0) -		for (j = 0; j < i; j++) -			device_remove_file(&connector->kdev, -					   &connector_attrs[i]); +	for (i = 0; i < opt_cnt; i++) +		device_remove_file(&connector->kdev, &connector_attrs_opt1[i]); +	for (i = 0; i < attr_cnt; i++) +		device_remove_file(&connector->kdev, &connector_attrs[i]);  	device_unregister(&connector->kdev);  out: diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 4ac900f4647..c3b13fb41d0 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -36,6 +36,7 @@  #include "drmP.h"  #if defined(__ia64__)  #include <linux/efi.h> +#include <linux/slab.h>  #endif  static void drm_vm_open(struct vm_area_struct *vma); diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index de32d22a8c3..997d91707ad 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c @@ -36,6 +36,7 @@  #include "i810_drv.h"  #include <linux/interrupt.h>	/* For task queue support */  #include <linux/delay.h> +#include <linux/slab.h>  #include <linux/pagemap.h>  #define I810_BUF_FREE		2 diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 06bd732e646..65759a9a85c 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c @@ -38,6 +38,7 @@  #include <linux/interrupt.h>	/* For task queue support */  #include <linux/pagemap.h>  #include <linux/delay.h> +#include <linux/slab.h>  #include <asm/uaccess.h>  #define I830_BUF_FREE		2 diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1376dfe44c9..a0b8447b06e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -28,6 +28,7 @@  #include <linux/seq_file.h>  #include <linux/debugfs.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "i915_drm.h" @@ -225,7 +226,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)  		} else {  			struct drm_i915_gem_object *obj_priv; -			obj_priv = obj->driver_private; +			obj_priv = to_intel_bo(obj);  			seq_printf(m, "Fenced object[%2d] = %p: %s "  				   "%08x %08zx %08x %s %08x %08x %d",  				   i, obj, get_pin_flag(obj_priv), diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 8bfc0bbf13e..c3cfafcbfe7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -38,6 +38,7 @@  #include <linux/acpi.h>  #include <linux/pnp.h>  #include <linux/vga_switcheroo.h> +#include <linux/slab.h>  /* Really want an OS-independent resettable timer.  Would like to have   * this loop run for (eg) 3 sec, but have the timer reset every time @@ -1356,6 +1357,8 @@ static void i915_setup_compression(struct drm_device *dev, int size)  	dev_priv->cfb_size = size; +	dev_priv->compressed_fb = compressed_fb; +  	if (IS_GM45(dev)) {  		g4x_disable_fbc(dev);  		I915_WRITE(DPFC_CB_BASE, compressed_fb->start); @@ -1363,12 +1366,22 @@ static void i915_setup_compression(struct drm_device *dev, int size)  		i8xx_disable_fbc(dev);  		I915_WRITE(FBC_CFB_BASE, cfb_base);  		I915_WRITE(FBC_LL_BASE, ll_base); +		dev_priv->compressed_llb = compressed_llb;  	}  	DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,  		  ll_base, size >> 20);  } +static void i915_cleanup_compression(struct drm_device *dev) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; + +	drm_mm_put_block(dev_priv->compressed_fb); +	if (!IS_GM45(dev)) +		drm_mm_put_block(dev_priv->compressed_llb); +} +  /* true = enable decode, false = disable decoder */  static unsigned int i915_vga_set_decode(void *cookie, bool state)  { @@ -1786,6 +1799,8 @@ int i915_driver_unload(struct drm_device *dev)  		mutex_lock(&dev->struct_mutex);  		i915_gem_cleanup_ringbuffer(dev);  		mutex_unlock(&dev->struct_mutex); +		if (I915_HAS_FBC(dev) && i915_powersave) +			i915_cleanup_compression(dev);  		drm_mm_takedown(&dev_priv->vram);  		i915_gem_lastclose(dev); @@ -1881,29 +1896,29 @@ struct drm_ioctl_desc i915_ioctls[] = {  	DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE,  i915_vblank_pipe_get, DRM_AUTH ),  	DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),  	DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -	DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH), -	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH), -	DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), -	DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY), -	DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH), -	DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH), -	DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -	DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -	DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0), -	DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0), -	DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW), -	DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW), +	DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), +	DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),  };  int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1b2e95455c0..cc03537bb88 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -69,7 +69,8 @@ const static struct intel_device_info intel_845g_info = {  };  const static struct intel_device_info intel_i85x_info = { -	.is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1, +	.is_i8xx = 1, .is_i85x = 1, .is_mobile = 1, +	.cursor_needs_physical = 1,  };  const static struct intel_device_info intel_i865g_info = { @@ -80,14 +81,14 @@ const static struct intel_device_info intel_i915g_info = {  	.is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,  };  const static struct intel_device_info intel_i915gm_info = { -	.is_i9xx = 1,  .is_mobile = 1, .has_fbc = 1, +	.is_i9xx = 1,  .is_mobile = 1,  	.cursor_needs_physical = 1,  };  const static struct intel_device_info intel_i945g_info = {  	.is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,  };  const static struct intel_device_info intel_i945gm_info = { -	.is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1, +	.is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,  	.has_hotplug = 1, .cursor_needs_physical = 1,  }; @@ -139,19 +140,19 @@ const static struct intel_device_info intel_ironlake_m_info = {  const static struct intel_device_info intel_sandybridge_d_info = {  	.is_i965g = 1, .is_i9xx = 1, .need_gfx_hws = 1, -	.has_hotplug = 1, +	.has_hotplug = 1, .is_gen6 = 1,  };  const static struct intel_device_info intel_sandybridge_m_info = {  	.is_i965g = 1, .is_mobile = 1, .is_i9xx = 1, .need_gfx_hws = 1, -	.has_hotplug = 1, +	.has_hotplug = 1, .is_gen6 = 1,  };  const static struct pci_device_id pciidlist[] = {  	INTEL_VGA_DEVICE(0x3577, &intel_i830_info),  	INTEL_VGA_DEVICE(0x2562, &intel_845g_info),  	INTEL_VGA_DEVICE(0x3582, &intel_i85x_info), -	INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info), +	INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),  	INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),  	INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),  	INTEL_VGA_DEVICE(0x258a, &intel_i915g_info), @@ -361,7 +362,7 @@ int i965_reset(struct drm_device *dev, u8 flags)  	    !dev_priv->mm.suspended) {  		drm_i915_ring_buffer_t *ring = &dev_priv->ring;  		struct drm_gem_object *obj = ring->ring_obj; -		struct drm_i915_gem_object *obj_priv = obj->driver_private; +		struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  		dev_priv->mm.suspended = 0;  		/* Stop the ring if it's running. */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 979439cfb82..6e4790065d9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -195,6 +195,7 @@ struct intel_overlay;  struct intel_device_info {  	u8 is_mobile : 1;  	u8 is_i8xx : 1; +	u8 is_i85x : 1;  	u8 is_i915g : 1;  	u8 is_i9xx : 1;  	u8 is_i945gm : 1; @@ -205,6 +206,7 @@ struct intel_device_info {  	u8 is_g4x : 1;  	u8 is_pineview : 1;  	u8 is_ironlake : 1; +	u8 is_gen6 : 1;  	u8 has_fbc : 1;  	u8 has_rc6 : 1;  	u8 has_pipe_cxsr : 1; @@ -234,11 +236,14 @@ typedef struct drm_i915_private {  	drm_dma_handle_t *status_page_dmah;  	void *hw_status_page; +	void *seqno_page;  	dma_addr_t dma_status_page;  	uint32_t counter;  	unsigned int status_gfx_addr; +	unsigned int seqno_gfx_addr;  	drm_local_map_t hws_map;  	struct drm_gem_object *hws_obj; +	struct drm_gem_object *seqno_obj;  	struct drm_gem_object *pwrctx;  	struct resource mch_res; @@ -610,6 +615,8 @@ typedef struct drm_i915_private {  	/* Reclocking support */  	bool render_reclock_avail;  	bool lvds_downclock_avail; +	/* indicate whether the LVDS EDID is OK */ +	bool lvds_edid_good;  	/* indicates the reduced downclock for LVDS*/  	int lvds_downclock;  	struct work_struct idle_work; @@ -627,6 +634,9 @@ typedef struct drm_i915_private {  	u8 max_delay;  	enum no_fbc_reason no_fbc_reason; + +	struct drm_mm_node *compressed_fb; +	struct drm_mm_node *compressed_llb;  } drm_i915_private_t;  /** driver private structure attached to each drm_gem_object */ @@ -730,6 +740,8 @@ struct drm_i915_gem_object {  	atomic_t pending_flip;  }; +#define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private) +  /**   * Request queue structure.   * @@ -1065,7 +1077,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define IS_I830(dev)		((dev)->pci_device == 0x3577)  #define IS_845G(dev)		((dev)->pci_device == 0x2562) -#define IS_I85X(dev)		((dev)->pci_device == 0x3582) +#define IS_I85X(dev)		(INTEL_INFO(dev)->is_i85x)  #define IS_I865G(dev)		((dev)->pci_device == 0x2572)  #define IS_GEN2(dev)		(INTEL_INFO(dev)->is_i8xx)  #define IS_I915G(dev)		(INTEL_INFO(dev)->is_i915g) @@ -1084,6 +1096,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define IS_IRONLAKE_M(dev)	((dev)->pci_device == 0x0046)  #define IS_IRONLAKE(dev)	(INTEL_INFO(dev)->is_ironlake)  #define IS_I9XX(dev)		(INTEL_INFO(dev)->is_i9xx) +#define IS_GEN6(dev)		(INTEL_INFO(dev)->is_gen6)  #define IS_MOBILE(dev)		(INTEL_INFO(dev)->is_mobile)  #define IS_GEN3(dev)	(IS_I915G(dev) ||			\ @@ -1107,8 +1120,6 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws) -#define IS_GEN6(dev)	((dev)->pci_device == 0x0102) -  /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte   * rows, which changed the alignment requirements and fence programming.   */ @@ -1131,6 +1142,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);  #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) ||	\  			    IS_GEN6(dev)) +#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))  #define PRIMARY_RINGBUFFER_SIZE         (128*1024) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fba37e9f775..ef3d91dda71 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -31,6 +31,7 @@  #include "i915_drv.h"  #include "i915_trace.h"  #include "intel_drv.h" +#include <linux/slab.h>  #include <linux/swap.h>  #include <linux/pci.h> @@ -162,7 +163,7 @@ fast_shmem_read(struct page **pages,  static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)  {  	drm_i915_private_t *dev_priv = obj->dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&  		obj_priv->tiling_mode != I915_TILING_NONE; @@ -263,7 +264,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,  			  struct drm_i915_gem_pread *args,  			  struct drm_file *file_priv)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	ssize_t remain;  	loff_t offset, page_base;  	char __user *user_data; @@ -284,7 +285,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,  	if (ret != 0)  		goto fail_put_pages; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	offset = args->offset;  	while (remain > 0) { @@ -353,7 +354,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,  			  struct drm_i915_gem_pread *args,  			  struct drm_file *file_priv)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	struct mm_struct *mm = current->mm;  	struct page **user_pages;  	ssize_t remain; @@ -402,7 +403,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,  	if (ret != 0)  		goto fail_put_pages; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	offset = args->offset;  	while (remain > 0) { @@ -478,7 +479,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,  	obj = drm_gem_object_lookup(dev, file_priv, args->handle);  	if (obj == NULL)  		return -EBADF; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	/* Bounds check source.  	 * @@ -580,7 +581,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,  			 struct drm_i915_gem_pwrite *args,  			 struct drm_file *file_priv)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	drm_i915_private_t *dev_priv = dev->dev_private;  	ssize_t remain;  	loff_t offset, page_base; @@ -604,7 +605,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,  	if (ret)  		goto fail; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	offset = obj_priv->gtt_offset + args->offset;  	while (remain > 0) { @@ -654,7 +655,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,  			 struct drm_i915_gem_pwrite *args,  			 struct drm_file *file_priv)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	drm_i915_private_t *dev_priv = dev->dev_private;  	ssize_t remain;  	loff_t gtt_page_base, offset; @@ -698,7 +699,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,  	if (ret)  		goto out_unpin_object; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	offset = obj_priv->gtt_offset + args->offset;  	while (remain > 0) { @@ -760,7 +761,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,  			   struct drm_i915_gem_pwrite *args,  			   struct drm_file *file_priv)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	ssize_t remain;  	loff_t offset, page_base;  	char __user *user_data; @@ -780,7 +781,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,  	if (ret != 0)  		goto fail_put_pages; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	offset = args->offset;  	obj_priv->dirty = 1; @@ -828,7 +829,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,  			   struct drm_i915_gem_pwrite *args,  			   struct drm_file *file_priv)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	struct mm_struct *mm = current->mm;  	struct page **user_pages;  	ssize_t remain; @@ -876,7 +877,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,  	if (ret != 0)  		goto fail_put_pages; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	offset = args->offset;  	obj_priv->dirty = 1; @@ -951,7 +952,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,  	obj = drm_gem_object_lookup(dev, file_priv, args->handle);  	if (obj == NULL)  		return -EBADF; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	/* Bounds check destination.  	 * @@ -1033,7 +1034,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,  	obj = drm_gem_object_lookup(dev, file_priv, args->handle);  	if (obj == NULL)  		return -EBADF; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	mutex_lock(&dev->struct_mutex); @@ -1095,7 +1096,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,  	DRM_INFO("%s: sw_finish %d (%p %zd)\n",  		 __func__, args->handle, obj, obj->size);  #endif -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	/* Pinned buffers may be scanout, so flush the cache */  	if (obj_priv->pin_count) @@ -1166,7 +1167,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)  	struct drm_gem_object *obj = vma->vm_private_data;  	struct drm_device *dev = obj->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	pgoff_t page_offset;  	unsigned long pfn;  	int ret = 0; @@ -1233,7 +1234,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	struct drm_gem_mm *mm = dev->mm_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	struct drm_map_list *list;  	struct drm_local_map *map;  	int ret = 0; @@ -1304,7 +1305,7 @@ void  i915_gem_release_mmap(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	if (dev->dev_mapping)  		unmap_mapping_range(dev->dev_mapping, @@ -1315,7 +1316,7 @@ static void  i915_gem_free_mmap_offset(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	struct drm_gem_mm *mm = dev->mm_private;  	struct drm_map_list *list; @@ -1346,7 +1347,7 @@ static uint32_t  i915_gem_get_gtt_alignment(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int start, i;  	/* @@ -1405,7 +1406,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,  	mutex_lock(&dev->struct_mutex); -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	if (obj_priv->madv != I915_MADV_WILLNEED) {  		DRM_ERROR("Attempting to mmap a purgeable buffer\n"); @@ -1449,7 +1450,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,  void  i915_gem_object_put_pages(struct drm_gem_object *obj)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int page_count = obj->size / PAGE_SIZE;  	int i; @@ -1466,9 +1467,6 @@ i915_gem_object_put_pages(struct drm_gem_object *obj)  		obj_priv->dirty = 0;  	for (i = 0; i < page_count; i++) { -		if (obj_priv->pages[i] == NULL) -			break; -  		if (obj_priv->dirty)  			set_page_dirty(obj_priv->pages[i]); @@ -1488,7 +1486,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	/* Add a reference if we're newly entering the active list. */  	if (!obj_priv->active) { @@ -1508,7 +1506,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	BUG_ON(!obj_priv->active);  	list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list); @@ -1519,7 +1517,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)  static void  i915_gem_object_truncate(struct drm_gem_object *obj)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	struct inode *inode;  	inode = obj->filp->f_path.dentry->d_inode; @@ -1540,7 +1538,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	i915_verify_inactive(dev, __FILE__, __LINE__);  	if (obj_priv->pin_count != 0) @@ -1590,6 +1588,13 @@ i915_gem_process_flushing_list(struct drm_device *dev,  	}  } +#define PIPE_CONTROL_FLUSH(addr)					\ +	OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |		\ +		 PIPE_CONTROL_DEPTH_STALL);				\ +	OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT);			\ +	OUT_RING(0);							\ +	OUT_RING(0);							\ +  /**   * Creates a new sequence number, emitting a write of it to the status page   * plus an interrupt, which will trigger i915_user_interrupt_handler. @@ -1624,13 +1629,47 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,  	if (dev_priv->mm.next_gem_seqno == 0)  		dev_priv->mm.next_gem_seqno++; -	BEGIN_LP_RING(4); -	OUT_RING(MI_STORE_DWORD_INDEX); -	OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); -	OUT_RING(seqno); +	if (HAS_PIPE_CONTROL(dev)) { +		u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; -	OUT_RING(MI_USER_INTERRUPT); -	ADVANCE_LP_RING(); +		/* +		 * Workaround qword write incoherence by flushing the +		 * PIPE_NOTIFY buffers out to memory before requesting +		 * an interrupt. +		 */ +		BEGIN_LP_RING(32); +		OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | +			 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); +		OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); +		OUT_RING(seqno); +		OUT_RING(0); +		PIPE_CONTROL_FLUSH(scratch_addr); +		scratch_addr += 128; /* write to separate cachelines */ +		PIPE_CONTROL_FLUSH(scratch_addr); +		scratch_addr += 128; +		PIPE_CONTROL_FLUSH(scratch_addr); +		scratch_addr += 128; +		PIPE_CONTROL_FLUSH(scratch_addr); +		scratch_addr += 128; +		PIPE_CONTROL_FLUSH(scratch_addr); +		scratch_addr += 128; +		PIPE_CONTROL_FLUSH(scratch_addr); +		OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | +			 PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | +			 PIPE_CONTROL_NOTIFY); +		OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); +		OUT_RING(seqno); +		OUT_RING(0); +		ADVANCE_LP_RING(); +	} else { +		BEGIN_LP_RING(4); +		OUT_RING(MI_STORE_DWORD_INDEX); +		OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); +		OUT_RING(seqno); + +		OUT_RING(MI_USER_INTERRUPT); +		ADVANCE_LP_RING(); +	}  	DRM_DEBUG_DRIVER("%d\n", seqno); @@ -1754,7 +1793,10 @@ i915_get_gem_seqno(struct drm_device *dev)  {  	drm_i915_private_t *dev_priv = dev->dev_private; -	return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX); +	if (HAS_PIPE_CONTROL(dev)) +		return ((volatile u32 *)(dev_priv->seqno_page))[0]; +	else +		return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);  }  /** @@ -1967,7 +2009,7 @@ static int  i915_gem_object_wait_rendering(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int ret;  	/* This function only exists to support waiting for existing rendering, @@ -1999,7 +2041,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int ret = 0;  #if WATCH_BUF @@ -2175,7 +2217,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)  #if WATCH_LRU  			DRM_INFO("%s: evicting %p\n", __func__, obj);  #endif -			obj_priv = obj->driver_private; +			obj_priv = to_intel_bo(obj);  			BUG_ON(obj_priv->pin_count != 0);  			BUG_ON(obj_priv->active); @@ -2227,11 +2269,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)  				seqno = i915_add_request(dev, NULL, obj->write_domain);  				if (seqno == 0)  					return -ENOMEM; - -				ret = i915_wait_request(dev, seqno); -				if (ret) -					return ret; -  				continue;  			}  		} @@ -2251,12 +2288,11 @@ int  i915_gem_object_get_pages(struct drm_gem_object *obj,  			  gfp_t gfpmask)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int page_count, i;  	struct address_space *mapping;  	struct inode *inode;  	struct page *page; -	int ret;  	if (obj_priv->pages_refcount++ != 0)  		return 0; @@ -2279,11 +2315,9 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,  					   mapping_gfp_mask (mapping) |  					   __GFP_COLD |  					   gfpmask); -		if (IS_ERR(page)) { -			ret = PTR_ERR(page); -			i915_gem_object_put_pages(obj); -			return ret; -		} +		if (IS_ERR(page)) +			goto err_pages; +  		obj_priv->pages[i] = page;  	} @@ -2291,6 +2325,15 @@ i915_gem_object_get_pages(struct drm_gem_object *obj,  		i915_gem_object_do_bit_17_swizzle(obj);  	return 0; + +err_pages: +	while (i--) +		page_cache_release(obj_priv->pages[i]); + +	drm_free_large(obj_priv->pages); +	obj_priv->pages = NULL; +	obj_priv->pages_refcount--; +	return PTR_ERR(page);  }  static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) @@ -2298,7 +2341,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)  	struct drm_gem_object *obj = reg->obj;  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int regnum = obj_priv->fence_reg;  	uint64_t val; @@ -2320,7 +2363,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)  	struct drm_gem_object *obj = reg->obj;  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int regnum = obj_priv->fence_reg;  	uint64_t val; @@ -2340,7 +2383,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)  	struct drm_gem_object *obj = reg->obj;  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int regnum = obj_priv->fence_reg;  	int tile_width;  	uint32_t fence_reg, val; @@ -2363,6 +2406,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)  	pitch_val = obj_priv->stride / tile_width;  	pitch_val = ffs(pitch_val) - 1; +	if (obj_priv->tiling_mode == I915_TILING_Y && +	    HAS_128_BYTE_Y_TILING(dev)) +		WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); +	else +		WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); +  	val = obj_priv->gtt_offset;  	if (obj_priv->tiling_mode == I915_TILING_Y)  		val |= 1 << I830_FENCE_TILING_Y_SHIFT; @@ -2382,7 +2431,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)  	struct drm_gem_object *obj = reg->obj;  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int regnum = obj_priv->fence_reg;  	uint32_t val;  	uint32_t pitch_val; @@ -2426,7 +2475,7 @@ static int i915_find_fence_reg(struct drm_device *dev)  		if (!reg->obj)  			return i; -		obj_priv = reg->obj->driver_private; +		obj_priv = to_intel_bo(reg->obj);  		if (!obj_priv->pin_count)  		    avail++;  	} @@ -2481,7 +2530,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	struct drm_i915_fence_reg *reg = NULL;  	int ret; @@ -2548,7 +2597,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	if (IS_GEN6(dev)) {  		I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + @@ -2584,7 +2633,7 @@ int  i915_gem_object_put_fence_reg(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	if (obj_priv->fence_reg == I915_FENCE_REG_NONE)  		return 0; @@ -2622,7 +2671,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	struct drm_mm_node *free_space;  	gfp_t gfpmask =  __GFP_NORETRY | __GFP_NOWARN;  	int ret; @@ -2729,7 +2778,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)  void  i915_gem_clflush_object(struct drm_gem_object *obj)  { -	struct drm_i915_gem_object	*obj_priv = obj->driver_private; +	struct drm_i915_gem_object	*obj_priv = to_intel_bo(obj);  	/* If we don't have a page list set up, then we're not pinned  	 * to GPU, and we can ignore the cache flush because it'll happen @@ -2830,7 +2879,7 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj)  int  i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	uint32_t old_write_domain, old_read_domains;  	int ret; @@ -2880,7 +2929,7 @@ int  i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	uint32_t old_write_domain, old_read_domains;  	int ret; @@ -3093,7 +3142,7 @@ static void  i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)  {  	struct drm_device		*dev = obj->dev; -	struct drm_i915_gem_object	*obj_priv = obj->driver_private; +	struct drm_i915_gem_object	*obj_priv = to_intel_bo(obj);  	uint32_t			invalidate_domains = 0;  	uint32_t			flush_domains = 0;  	uint32_t			old_read_domains; @@ -3178,7 +3227,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)  static void  i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	if (!obj_priv->page_cpu_valid)  		return; @@ -3218,7 +3267,7 @@ static int  i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,  					  uint64_t offset, uint64_t size)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	uint32_t old_read_domains;  	int i, ret; @@ -3287,7 +3336,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int i, ret;  	void __iomem *reloc_page;  	bool need_fence; @@ -3338,7 +3387,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,  			i915_gem_object_unpin(obj);  			return -EBADF;  		} -		target_obj_priv = target_obj->driver_private; +		target_obj_priv = to_intel_bo(target_obj);  #if WATCH_RELOC  		DRM_INFO("%s: obj %p offset %08x target %d " @@ -3690,7 +3739,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev,  		prepare_to_wait(&dev_priv->pending_flip_queue,  				&wait, TASK_INTERRUPTIBLE);  		for (i = 0; i < count; i++) { -			obj_priv = object_list[i]->driver_private; +			obj_priv = to_intel_bo(object_list[i]);  			if (atomic_read(&obj_priv->pending_flip) > 0)  				break;  		} @@ -3799,7 +3848,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,  			goto err;  		} -		obj_priv = object_list[i]->driver_private; +		obj_priv = to_intel_bo(object_list[i]);  		if (obj_priv->in_execbuffer) {  			DRM_ERROR("Object %p appears more than once in object list\n",  				   object_list[i]); @@ -3925,7 +3974,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,  	for (i = 0; i < args->buffer_count; i++) {  		struct drm_gem_object *obj = object_list[i]; -		struct drm_i915_gem_object *obj_priv = obj->driver_private; +		struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  		uint32_t old_write_domain = obj->write_domain;  		obj->write_domain = obj->pending_write_domain; @@ -4000,7 +4049,7 @@ err:  	for (i = 0; i < args->buffer_count; i++) {  		if (object_list[i]) { -			obj_priv = object_list[i]->driver_private; +			obj_priv = to_intel_bo(object_list[i]);  			obj_priv->in_execbuffer = false;  		}  		drm_gem_object_unreference(object_list[i]); @@ -4178,7 +4227,7 @@ int  i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int ret;  	i915_verify_inactive(dev, __FILE__, __LINE__); @@ -4211,7 +4260,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	i915_verify_inactive(dev, __FILE__, __LINE__);  	obj_priv->pin_count--; @@ -4251,7 +4300,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,  		mutex_unlock(&dev->struct_mutex);  		return -EBADF;  	} -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	if (obj_priv->madv != I915_MADV_WILLNEED) {  		DRM_ERROR("Attempting to pin a purgeable buffer\n"); @@ -4308,7 +4357,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,  		return -EBADF;  	} -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	if (obj_priv->pin_filp != file_priv) {  		DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",  			  args->handle); @@ -4350,7 +4399,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,  	 */  	i915_gem_retire_requests(dev); -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	/* Don't count being on the flushing list against the object being  	 * done.  Otherwise, a buffer left on the flushing list but not getting  	 * flushed (because nobody's flushing that domain) won't ever return @@ -4396,7 +4445,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,  	}  	mutex_lock(&dev->struct_mutex); -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	if (obj_priv->pin_count) {  		drm_gem_object_unreference(obj); @@ -4457,7 +4506,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)  void i915_gem_free_object(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	trace_i915_gem_object_destroy(obj); @@ -4547,6 +4596,49 @@ i915_gem_idle(struct drm_device *dev)  	return 0;  } +/* + * 965+ support PIPE_CONTROL commands, which provide finer grained control + * over cache flushing. + */ +static int +i915_gem_init_pipe_control(struct drm_device *dev) +{ +	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_gem_object *obj; +	struct drm_i915_gem_object *obj_priv; +	int ret; + +	obj = drm_gem_object_alloc(dev, 4096); +	if (obj == NULL) { +		DRM_ERROR("Failed to allocate seqno page\n"); +		ret = -ENOMEM; +		goto err; +	} +	obj_priv = to_intel_bo(obj); +	obj_priv->agp_type = AGP_USER_CACHED_MEMORY; + +	ret = i915_gem_object_pin(obj, 4096); +	if (ret) +		goto err_unref; + +	dev_priv->seqno_gfx_addr = obj_priv->gtt_offset; +	dev_priv->seqno_page =  kmap(obj_priv->pages[0]); +	if (dev_priv->seqno_page == NULL) +		goto err_unpin; + +	dev_priv->seqno_obj = obj; +	memset(dev_priv->seqno_page, 0, PAGE_SIZE); + +	return 0; + +err_unpin: +	i915_gem_object_unpin(obj); +err_unref: +	drm_gem_object_unreference(obj); +err: +	return ret; +} +  static int  i915_gem_init_hws(struct drm_device *dev)  { @@ -4564,15 +4656,16 @@ i915_gem_init_hws(struct drm_device *dev)  	obj = drm_gem_object_alloc(dev, 4096);  	if (obj == NULL) {  		DRM_ERROR("Failed to allocate status page\n"); -		return -ENOMEM; +		ret = -ENOMEM; +		goto err;  	} -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	obj_priv->agp_type = AGP_USER_CACHED_MEMORY;  	ret = i915_gem_object_pin(obj, 4096);  	if (ret != 0) {  		drm_gem_object_unreference(obj); -		return ret; +		goto err_unref;  	}  	dev_priv->status_gfx_addr = obj_priv->gtt_offset; @@ -4581,10 +4674,16 @@ i915_gem_init_hws(struct drm_device *dev)  	if (dev_priv->hw_status_page == NULL) {  		DRM_ERROR("Failed to map status page.\n");  		memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); -		i915_gem_object_unpin(obj); -		drm_gem_object_unreference(obj); -		return -EINVAL; +		ret = -EINVAL; +		goto err_unpin; +	} + +	if (HAS_PIPE_CONTROL(dev)) { +		ret = i915_gem_init_pipe_control(dev); +		if (ret) +			goto err_unpin;  	} +  	dev_priv->hws_obj = obj;  	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);  	if (IS_GEN6(dev)) { @@ -4597,6 +4696,30 @@ i915_gem_init_hws(struct drm_device *dev)  	DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);  	return 0; + +err_unpin: +	i915_gem_object_unpin(obj); +err_unref: +	drm_gem_object_unreference(obj); +err: +	return 0; +} + +static void +i915_gem_cleanup_pipe_control(struct drm_device *dev) +{ +	drm_i915_private_t *dev_priv = dev->dev_private; +	struct drm_gem_object *obj; +	struct drm_i915_gem_object *obj_priv; + +	obj = dev_priv->seqno_obj; +	obj_priv = to_intel_bo(obj); +	kunmap(obj_priv->pages[0]); +	i915_gem_object_unpin(obj); +	drm_gem_object_unreference(obj); +	dev_priv->seqno_obj = NULL; + +	dev_priv->seqno_page = NULL;  }  static void @@ -4610,7 +4733,7 @@ i915_gem_cleanup_hws(struct drm_device *dev)  		return;  	obj = dev_priv->hws_obj; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	kunmap(obj_priv->pages[0]);  	i915_gem_object_unpin(obj); @@ -4620,6 +4743,9 @@ i915_gem_cleanup_hws(struct drm_device *dev)  	memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));  	dev_priv->hw_status_page = NULL; +	if (HAS_PIPE_CONTROL(dev)) +		i915_gem_cleanup_pipe_control(dev); +  	/* Write high address into HWS_PGA when disabling. */  	I915_WRITE(HWS_PGA, 0x1ffff000);  } @@ -4644,7 +4770,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)  		i915_gem_cleanup_hws(dev);  		return -ENOMEM;  	} -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	ret = i915_gem_object_pin(obj, 4096);  	if (ret != 0) { @@ -4730,6 +4856,11 @@ i915_gem_init_ringbuffer(struct drm_device *dev)  			ring->space += ring->Size;  	} +	if (IS_I9XX(dev) && !IS_GEN3(dev)) { +		I915_WRITE(MI_MODE, +			   (VS_TIMER_DISPATCH) << 16 | VS_TIMER_DISPATCH); +	} +  	return 0;  } @@ -4932,7 +5063,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev,  	int ret;  	int page_count; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	if (!obj_priv->phys_obj)  		return; @@ -4971,7 +5102,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,  	if (id > I915_MAX_PHYS_OBJECT)  		return -EINVAL; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	if (obj_priv->phys_obj) {  		if (obj_priv->phys_obj->id == id) @@ -5022,7 +5153,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,  		     struct drm_i915_gem_pwrite *args,  		     struct drm_file *file_priv)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	void *obj_addr;  	int ret;  	char __user *user_data; diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index e602614bd3f..35507cf53fa 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -72,7 +72,7 @@ void  i915_gem_dump_object(struct drm_gem_object *obj, int len,  		     const char *where, uint32_t mark)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int page;  	DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); @@ -137,7 +137,7 @@ void  i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int page;  	uint32_t *gtt_mapping;  	uint32_t *backing_map = NULL; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index b5c55d88ff7..4bdccefcf2c 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -202,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)  		 * reg, so dont bother to check the size */  		if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)  			return false; -	} else if (IS_I9XX(dev)) { -		uint32_t pitch_val = ffs(stride / tile_width) - 1; - -		/* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB) -		 * instead of 4 (2KB) on 945s. -		 */ -		if (pitch_val > I915_FENCE_MAX_PITCH_VAL || -		    size > (I830_FENCE_MAX_SIZE_VAL << 20)) +	} else if (IS_GEN3(dev) || IS_GEN2(dev)) { +		if (stride > 8192)  			return false; -	} else { -		uint32_t pitch_val = ffs(stride / tile_width) - 1; -		if (pitch_val > I830_FENCE_MAX_PITCH_VAL || -		    size > (I830_FENCE_MAX_SIZE_VAL << 19)) -			return false; +		if (IS_GEN3(dev)) { +			if (size > I830_FENCE_MAX_SIZE_VAL << 20) +				return false; +		} else { +			if (size > I830_FENCE_MAX_SIZE_VAL << 19) +				return false; +		}  	}  	/* 965+ just needs multiples of tile width */ @@ -240,7 +236,7 @@ bool  i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)  {  	struct drm_device *dev = obj->dev; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	if (obj_priv->gtt_space == NULL)  		return true; @@ -280,7 +276,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,  	obj = drm_gem_object_lookup(dev, file_priv, args->handle);  	if (obj == NULL)  		return -EINVAL; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {  		drm_gem_object_unreference_unlocked(obj); @@ -325,9 +321,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,  		 * need to ensure that any fence register is cleared.  		 */  		if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) -		    ret = i915_gem_object_unbind(obj); +			ret = i915_gem_object_unbind(obj); +		else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) +			ret = i915_gem_object_put_fence_reg(obj);  		else -		    ret = i915_gem_object_put_fence_reg(obj); +			i915_gem_release_mmap(obj); +  		if (ret != 0) {  			WARN(ret != -ERESTARTSYS,  			     "failed to reset object for tiling switch"); @@ -361,7 +360,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,  	obj = drm_gem_object_lookup(dev, file_priv, args->handle);  	if (obj == NULL)  		return -EINVAL; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	mutex_lock(&dev->struct_mutex); @@ -424,7 +423,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int page_count = obj->size >> PAGE_SHIFT;  	int i; @@ -453,7 +452,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)  {  	struct drm_device *dev = obj->dev;  	drm_i915_private_t *dev_priv = dev->dev_private; -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	int page_count = obj->size >> PAGE_SHIFT;  	int i; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5388354da0d..df6a9cd82c4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -27,6 +27,7 @@   */  #include <linux/sysrq.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "i915_drm.h" @@ -259,10 +260,10 @@ static void i915_hotplug_work_func(struct work_struct *work)  	if (mode_config->num_connector) {  		list_for_each_entry(connector, &mode_config->connector_list, head) { -			struct intel_output *intel_output = to_intel_output(connector); +			struct intel_encoder *intel_encoder = to_intel_encoder(connector); -			if (intel_output->hot_plug) -				(*intel_output->hot_plug) (intel_output); +			if (intel_encoder->hot_plug) +				(*intel_encoder->hot_plug) (intel_encoder);  		}  	}  	/* Just fire off a uevent and let userspace tell us what to do */ @@ -348,7 +349,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)  				READ_BREADCRUMB(dev_priv);  	} -	if (gt_iir & GT_USER_INTERRUPT) { +	if (gt_iir & GT_PIPE_NOTIFY) {  		u32 seqno = i915_get_gem_seqno(dev);  		dev_priv->mm.irq_gem_seqno = seqno;  		trace_i915_gem_request_complete(dev, seqno); @@ -443,7 +444,7 @@ i915_error_object_create(struct drm_device *dev,  	if (src == NULL)  		return NULL; -	src_priv = src->driver_private; +	src_priv = to_intel_bo(src);  	if (src_priv->pages == NULL)  		return NULL; @@ -455,11 +456,15 @@ i915_error_object_create(struct drm_device *dev,  	for (page = 0; page < page_count; page++) {  		void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); +		unsigned long flags; +  		if (d == NULL)  			goto unwind; -		s = kmap_atomic(src_priv->pages[page], KM_USER0); +		local_irq_save(flags); +		s = kmap_atomic(src_priv->pages[page], KM_IRQ0);  		memcpy(d, s, PAGE_SIZE); -		kunmap_atomic(s, KM_USER0); +		kunmap_atomic(s, KM_IRQ0); +		local_irq_restore(flags);  		dst->pages[page] = d;  	}  	dst->page_count = page_count; @@ -1004,7 +1009,7 @@ void i915_user_irq_get(struct drm_device *dev)  	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);  	if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {  		if (HAS_PCH_SPLIT(dev)) -			ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); +			ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);  		else  			i915_enable_irq(dev_priv, I915_USER_INTERRUPT);  	} @@ -1020,7 +1025,7 @@ void i915_user_irq_put(struct drm_device *dev)  	BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);  	if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {  		if (HAS_PCH_SPLIT(dev)) -			ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT); +			ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);  		else  			i915_disable_irq(dev_priv, I915_USER_INTERRUPT);  	} @@ -1304,7 +1309,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)  	/* enable kind of interrupts always enabled */  	u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |  			   DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; -	u32 render_mask = GT_USER_INTERRUPT; +	u32 render_mask = GT_PIPE_NOTIFY;  	u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |  			   SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index 7cc8410239c..8fcc75c1aa2 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c @@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev)  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct intel_opregion *opregion = &dev_priv->opregion;  	struct drm_connector *connector; +	acpi_handle handle; +	struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; +	unsigned long long device_id; +	acpi_status status;  	int i = 0; +	handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); +	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) +		return; + +	if (acpi_is_video_device(acpi_dev)) +		acpi_video_bus = acpi_dev; +	else { +		list_for_each_entry(acpi_cdev, &acpi_dev->children, node) { +			if (acpi_is_video_device(acpi_cdev)) { +				acpi_video_bus = acpi_cdev; +				break; +			} +		} +	} + +	if (!acpi_video_bus) { +		printk(KERN_WARNING "No ACPI video bus found\n"); +		return; +	} + +	list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { +		if (i >= 8) { +			dev_printk (KERN_ERR, &dev->pdev->dev, +				    "More than 8 outputs detected\n"); +			return; +		} +		status = +			acpi_evaluate_integer(acpi_cdev->handle, "_ADR", +						NULL, &device_id); +		if (ACPI_SUCCESS(status)) { +			if (!device_id) +				goto blind_set; +			opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f); +			i++; +		} +	} + +end: +	/* If fewer than 8 outputs, the list must be null terminated */ +	if (i < 8) +		opregion->acpi->didl[i] = 0; +	return; + +blind_set: +	i = 0;  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {  		int output_type = ACPI_OTHER_OUTPUT;  		if (i >= 8) { @@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev)  		opregion->acpi->didl[i] |= (1<<31) | output_type | i;  		i++;  	} - -	/* If fewer than 8 outputs, the list must be null terminated */ -	if (i < 8) -		opregion->acpi->didl[i] = 0; +	goto end;  }  int intel_opregion_init(struct drm_device *dev, int resume) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3d59862c7cc..4cbc5210fd3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -230,6 +230,16 @@  #define   ASYNC_FLIP                (1<<22)  #define   DISPLAY_PLANE_A           (0<<20)  #define   DISPLAY_PLANE_B           (1<<20) +#define GFX_OP_PIPE_CONTROL	((0x3<<29)|(0x3<<27)|(0x2<<24)|2) +#define   PIPE_CONTROL_QW_WRITE	(1<<14) +#define   PIPE_CONTROL_DEPTH_STALL (1<<13) +#define   PIPE_CONTROL_WC_FLUSH	(1<<12) +#define   PIPE_CONTROL_IS_FLUSH	(1<<11) /* MBZ on Ironlake */ +#define   PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */ +#define   PIPE_CONTROL_ISP_DIS	(1<<9) +#define   PIPE_CONTROL_NOTIFY	(1<<8) +#define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */ +#define   PIPE_CONTROL_STALL_EN	(1<<1) /* in addr word, Ironlake+ only */  /*   * Fence registers @@ -241,7 +251,7 @@  #define   I830_FENCE_SIZE_BITS(size)	((ffs((size) >> 19) - 1) << 8)  #define   I830_FENCE_PITCH_SHIFT	4  #define   I830_FENCE_REG_VALID		(1<<0) -#define   I915_FENCE_MAX_PITCH_VAL	0x10 +#define   I915_FENCE_MAX_PITCH_VAL	4  #define   I830_FENCE_MAX_PITCH_VAL	6  #define   I830_FENCE_MAX_SIZE_VAL	(1<<8) @@ -298,6 +308,10 @@  #define INSTDONE	0x02090  #define NOPID		0x02094  #define HWSTAM		0x02098 + +#define MI_MODE		0x0209c +# define VS_TIMER_DISPATCH				(1 << 6) +  #define SCPD0		0x0209c /* 915+ only */  #define IER		0x020a0  #define IIR		0x020a4 @@ -366,7 +380,7 @@  #define   FBC_CTL_PERIODIC	(1<<30)  #define   FBC_CTL_INTERVAL_SHIFT (16)  #define   FBC_CTL_UNCOMPRESSIBLE (1<<14) -#define   FBC_C3_IDLE		(1<<13) +#define   FBC_CTL_C3_IDLE	(1<<13)  #define   FBC_CTL_STRIDE_SHIFT	(5)  #define   FBC_CTL_FENCENO	(1<<0)  #define FBC_COMMAND		0x0320c @@ -2172,6 +2186,14 @@  #define DISPLAY_PORT_PLL_BIOS_1         0x46010  #define DISPLAY_PORT_PLL_BIOS_2         0x46014 +#define PCH_DSPCLK_GATE_D	0x42020 +# define DPFDUNIT_CLOCK_GATE_DISABLE		(1 << 7) +# define DPARBUNIT_CLOCK_GATE_DISABLE		(1 << 5) + +#define PCH_3DCGDIS0		0x46020 +# define MARIUNIT_CLOCK_GATE_DISABLE		(1 << 18) +# define SVSMUNIT_CLOCK_GATE_DISABLE		(1 << 1) +  #define FDI_PLL_FREQ_CTL        0x46030  #define  FDI_PLL_FREQ_CHANGE_REQUEST    (1<<24)  #define  FDI_PLL_FREQ_LOCK_LIMIT_MASK   0xfff00 @@ -2273,6 +2295,7 @@  #define DEIER   0x4400c  /* GT interrupt */ +#define GT_PIPE_NOTIFY		(1 << 4)  #define GT_SYNC_STATUS          (1 << 2)  #define GT_USER_INTERRUPT       (1 << 0) diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 70c9d4ba704..f9ba452f0cb 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -417,8 +417,9 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)  	edp = find_section(bdb, BDB_EDP);  	if (!edp) {  		if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp_support) { -			DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported,\ -				       assume 18bpp panel color depth.\n"); +			DRM_DEBUG_KMS("No eDP BDB found but eDP panel " +				      "supported, assume 18bpp panel color " +				      "depth.\n");  			dev_priv->edp_bpp = 18;  		}  		return; diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index fccf07470c8..759c2ef72ef 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -25,6 +25,7 @@   */  #include <linux/i2c.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "drm_crtc.h" @@ -246,19 +247,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)  static bool intel_crt_detect_ddc(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector);  	/* CRT should always be at 0, but check anyway */ -	if (intel_output->type != INTEL_OUTPUT_ANALOG) +	if (intel_encoder->type != INTEL_OUTPUT_ANALOG)  		return false; -	return intel_ddc_probe(intel_output); +	return intel_ddc_probe(intel_encoder);  }  static enum drm_connector_status -intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output) +intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)  { -	struct drm_encoder *encoder = &intel_output->enc; +	struct drm_encoder *encoder = &intel_encoder->enc;  	struct drm_device *dev = encoder->dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -386,8 +387,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)  static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev; -	struct intel_output *intel_output = to_intel_output(connector); -	struct drm_encoder *encoder = &intel_output->enc; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct drm_encoder *encoder = &intel_encoder->enc;  	struct drm_crtc *crtc;  	int dpms_mode;  	enum drm_connector_status status; @@ -404,13 +405,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto  	/* for pre-945g platforms use load detect */  	if (encoder->crtc && encoder->crtc->enabled) { -		status = intel_crt_load_detect(encoder->crtc, intel_output); +		status = intel_crt_load_detect(encoder->crtc, intel_encoder);  	} else { -		crtc = intel_get_load_detect_pipe(intel_output, +		crtc = intel_get_load_detect_pipe(intel_encoder,  						  NULL, &dpms_mode);  		if (crtc) { -			status = intel_crt_load_detect(crtc, intel_output); -			intel_release_load_detect_pipe(intel_output, dpms_mode); +			status = intel_crt_load_detect(crtc, intel_encoder); +			intel_release_load_detect_pipe(intel_encoder, dpms_mode);  		} else  			status = connector_status_unknown;  	} @@ -420,9 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto  static void intel_crt_destroy(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); -	intel_i2c_destroy(intel_output->ddc_bus); +	intel_i2c_destroy(intel_encoder->ddc_bus);  	drm_sysfs_connector_remove(connector);  	drm_connector_cleanup(connector);  	kfree(connector); @@ -431,28 +432,28 @@ static void intel_crt_destroy(struct drm_connector *connector)  static int intel_crt_get_modes(struct drm_connector *connector)  {  	int ret; -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector);  	struct i2c_adapter *ddcbus;  	struct drm_device *dev = connector->dev; -	ret = intel_ddc_get_modes(intel_output); +	ret = intel_ddc_get_modes(intel_encoder);  	if (ret || !IS_G4X(dev))  		goto end; -	ddcbus = intel_output->ddc_bus; +	ddcbus = intel_encoder->ddc_bus;  	/* Try to probe digital port for output in DVI-I -> VGA mode. */ -	intel_output->ddc_bus = +	intel_encoder->ddc_bus =  		intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); -	if (!intel_output->ddc_bus) { -		intel_output->ddc_bus = ddcbus; +	if (!intel_encoder->ddc_bus) { +		intel_encoder->ddc_bus = ddcbus;  		dev_printk(KERN_ERR, &connector->dev->pdev->dev,  			   "DDC bus registration failed for CRTDDC_D.\n");  		goto end;  	}  	/* Try to get modes by GPIOD port */ -	ret = intel_ddc_get_modes(intel_output); +	ret = intel_ddc_get_modes(intel_encoder);  	intel_i2c_destroy(ddcbus);  end: @@ -505,23 +506,23 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {  void intel_crt_init(struct drm_device *dev)  {  	struct drm_connector *connector; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct drm_i915_private *dev_priv = dev->dev_private;  	u32 i2c_reg; -	intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); -	if (!intel_output) +	intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); +	if (!intel_encoder)  		return; -	connector = &intel_output->base; -	drm_connector_init(dev, &intel_output->base, +	connector = &intel_encoder->base; +	drm_connector_init(dev, &intel_encoder->base,  			   &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); -	drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, +	drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs,  			 DRM_MODE_ENCODER_DAC); -	drm_mode_connector_attach_encoder(&intel_output->base, -					  &intel_output->enc); +	drm_mode_connector_attach_encoder(&intel_encoder->base, +					  &intel_encoder->enc);  	/* Set up the DDC bus. */  	if (HAS_PCH_SPLIT(dev)) @@ -532,22 +533,22 @@ void intel_crt_init(struct drm_device *dev)  		if (dev_priv->crt_ddc_bus != 0)  			i2c_reg = dev_priv->crt_ddc_bus;  	} -	intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); -	if (!intel_output->ddc_bus) { +	intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); +	if (!intel_encoder->ddc_bus) {  		dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "  			   "failed.\n");  		return;  	} -	intel_output->type = INTEL_OUTPUT_ANALOG; -	intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | +	intel_encoder->type = INTEL_OUTPUT_ANALOG; +	intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |  				   (1 << INTEL_ANALOG_CLONE_BIT) |  				   (1 << INTEL_SDVO_LVDS_CLONE_BIT); -	intel_output->crtc_mask = (1 << 0) | (1 << 1); +	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);  	connector->interlace_allowed = 0;  	connector->doublescan_allowed = 0; -	drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs); +	drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);  	drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);  	drm_sysfs_connector_add(connector); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9cd6de5f990..c7502b6b160 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -28,6 +28,7 @@  #include <linux/input.h>  #include <linux/i2c.h>  #include <linux/kernel.h> +#include <linux/slab.h>  #include "drmP.h"  #include "intel_drv.h"  #include "i915_drm.h" @@ -746,16 +747,16 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)      list_for_each_entry(l_entry, &mode_config->connector_list, head) {  	    if (l_entry->encoder &&  	        l_entry->encoder->crtc == crtc) { -		    struct intel_output *intel_output = to_intel_output(l_entry); -		    if (intel_output->type == type) +		    struct intel_encoder *intel_encoder = to_intel_encoder(l_entry); +		    if (intel_encoder->type == type)  			    return true;  	    }      }      return false;  } -struct drm_connector * -intel_pipe_get_output (struct drm_crtc *crtc) +static struct drm_connector * +intel_pipe_get_connector (struct drm_crtc *crtc)  {      struct drm_device *dev = crtc->dev;      struct drm_mode_config *mode_config = &dev->mode_config; @@ -1002,7 +1003,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_framebuffer *fb = crtc->fb;  	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); -	struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);  	int plane, i;  	u32 fbc_ctl, fbc_ctl2; @@ -1032,7 +1033,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)  	/* enable it... */  	fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC;  	if (IS_I945GM(dev)) -		fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */ +		fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */  	fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;  	fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;  	if (obj_priv->tiling_mode != I915_TILING_NONE) @@ -1079,7 +1080,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval)  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_framebuffer *fb = crtc->fb;  	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); -	struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);  	int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA :  		     DPFC_CTL_PLANEB); @@ -1175,7 +1176,7 @@ static void intel_update_fbc(struct drm_crtc *crtc,  		return;  	intel_fb = to_intel_framebuffer(fb); -	obj_priv = intel_fb->obj->driver_private; +	obj_priv = to_intel_bo(intel_fb->obj);  	/*  	 * If FBC is already on, we just have to verify that we can @@ -1242,7 +1243,7 @@ out_disable:  static int  intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)  { -	struct drm_i915_gem_object *obj_priv = obj->driver_private; +	struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);  	u32 alignment;  	int ret; @@ -1322,7 +1323,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,  	intel_fb = to_intel_framebuffer(crtc->fb);  	obj = intel_fb->obj; -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	mutex_lock(&dev->struct_mutex);  	ret = intel_pin_and_fence_fb_obj(dev, obj); @@ -1400,7 +1401,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,  	if (old_fb) {  		intel_fb = to_intel_framebuffer(old_fb); -		obj_priv = intel_fb->obj->driver_private; +		obj_priv = to_intel_bo(intel_fb->obj);  		i915_gem_object_unpin(intel_fb->obj);  	}  	intel_increase_pllclock(crtc, true); @@ -2916,7 +2917,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,  	int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;  	int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;  	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; -	int refclk, num_outputs = 0; +	int refclk, num_connectors = 0;  	intel_clock_t clock, reduced_clock;  	u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;  	bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; @@ -2942,19 +2943,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,  	drm_vblank_pre_modeset(dev, pipe);  	list_for_each_entry(connector, &mode_config->connector_list, head) { -		struct intel_output *intel_output = to_intel_output(connector); +		struct intel_encoder *intel_encoder = to_intel_encoder(connector);  		if (!connector->encoder || connector->encoder->crtc != crtc)  			continue; -		switch (intel_output->type) { +		switch (intel_encoder->type) {  		case INTEL_OUTPUT_LVDS:  			is_lvds = true;  			break;  		case INTEL_OUTPUT_SDVO:  		case INTEL_OUTPUT_HDMI:  			is_sdvo = true; -			if (intel_output->needs_tv_clock) +			if (intel_encoder->needs_tv_clock)  				is_tv = true;  			break;  		case INTEL_OUTPUT_DVO: @@ -2974,10 +2975,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,  			break;  		} -		num_outputs++; +		num_connectors++;  	} -	if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) { +	if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) {  		refclk = dev_priv->lvds_ssc_freq * 1000;  		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",  					refclk / 1000); @@ -3048,8 +3049,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,  		if (is_edp) {  			struct drm_connector *edp;  			target_clock = mode->clock; -			edp = intel_pipe_get_output(crtc); -			intel_edp_link_config(to_intel_output(edp), +			edp = intel_pipe_get_connector(crtc); +			intel_edp_link_config(to_intel_encoder(edp),  					&lane, &link_bw);  		} else {  			/* DP over FDI requires target mode clock @@ -3230,7 +3231,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,  		/* XXX: just matching BIOS for now */  		/*	dpll |= PLL_REF_INPUT_TVCLKINBC; */  		dpll |= 3; -	else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) +	else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2)  		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;  	else  		dpll |= PLL_REF_INPUT_DREFCLK; @@ -3510,7 +3511,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,  	if (!bo)  		return -ENOENT; -	obj_priv = bo->driver_private; +	obj_priv = to_intel_bo(bo);  	if (bo->size < width * height * 4) {  		DRM_ERROR("buffer is to small\n"); @@ -3654,9 +3655,9 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,   * detection.   *   * It will be up to the load-detect code to adjust the pipe as appropriate for - * its requirements.  The pipe will be connected to no other outputs. + * its requirements.  The pipe will be connected to no other encoders.   * - * Currently this code will only succeed if there is a pipe with no outputs + * Currently this code will only succeed if there is a pipe with no encoders   * configured for it.  In the future, it could choose to temporarily disable   * some outputs to free up a pipe for its use.   * @@ -3669,14 +3670,14 @@ static struct drm_display_mode load_detect_mode = {  		 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),  }; -struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, +struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,  					    struct drm_display_mode *mode,  					    int *dpms_mode)  {  	struct intel_crtc *intel_crtc;  	struct drm_crtc *possible_crtc;  	struct drm_crtc *supported_crtc =NULL; -	struct drm_encoder *encoder = &intel_output->enc; +	struct drm_encoder *encoder = &intel_encoder->enc;  	struct drm_crtc *crtc = NULL;  	struct drm_device *dev = encoder->dev;  	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; @@ -3728,8 +3729,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,  	}  	encoder->crtc = crtc; -	intel_output->base.encoder = encoder; -	intel_output->load_detect_temp = true; +	intel_encoder->base.encoder = encoder; +	intel_encoder->load_detect_temp = true;  	intel_crtc = to_intel_crtc(crtc);  	*dpms_mode = intel_crtc->dpms_mode; @@ -3754,23 +3755,23 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,  	return crtc;  } -void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode) +void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode)  { -	struct drm_encoder *encoder = &intel_output->enc; +	struct drm_encoder *encoder = &intel_encoder->enc;  	struct drm_device *dev = encoder->dev;  	struct drm_crtc *crtc = encoder->crtc;  	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;  	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; -	if (intel_output->load_detect_temp) { +	if (intel_encoder->load_detect_temp) {  		encoder->crtc = NULL; -		intel_output->base.encoder = NULL; -		intel_output->load_detect_temp = false; +		intel_encoder->base.encoder = NULL; +		intel_encoder->load_detect_temp = false;  		crtc->enabled = drm_helper_crtc_in_use(crtc);  		drm_helper_disable_unused_functions(dev);  	} -	/* Switch crtc and output back off if necessary */ +	/* Switch crtc and encoder back off if necessary */  	if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {  		if (encoder->crtc == crtc)  			encoder_funcs->dpms(encoder, dpms_mode); @@ -4155,7 +4156,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)  	work = intel_crtc->unpin_work;  	if (work == NULL || !work->pending) {  		if (work && !work->pending) { -			obj_priv = work->pending_flip_obj->driver_private; +			obj_priv = to_intel_bo(work->pending_flip_obj);  			DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",  					 obj_priv,  					 atomic_read(&obj_priv->pending_flip)); @@ -4180,7 +4181,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)  	spin_unlock_irqrestore(&dev->event_lock, flags); -	obj_priv = work->pending_flip_obj->driver_private; +	obj_priv = to_intel_bo(work->pending_flip_obj);  	/* Initial scanout buffer will have a 0 pending flip count */  	if ((atomic_read(&obj_priv->pending_flip) == 0) || @@ -4251,7 +4252,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,  	ret = intel_pin_and_fence_fb_obj(dev, obj);  	if (ret != 0) {  		DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", -			  obj->driver_private); +			  to_intel_bo(obj));  		kfree(work);  		intel_crtc->unpin_work = NULL;  		mutex_unlock(&dev->struct_mutex); @@ -4265,7 +4266,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,  	crtc->fb = fb;  	i915_gem_object_flush_write_domain(obj);  	drm_vblank_get(dev, intel_crtc->pipe); -	obj_priv = obj->driver_private; +	obj_priv = to_intel_bo(obj);  	atomic_inc(&obj_priv->pending_flip);  	work->pending_flip_obj = obj; @@ -4398,8 +4399,8 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)  	int entry = 0;          list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -		struct intel_output *intel_output = to_intel_output(connector); -		if (type_mask & intel_output->clone_mask) +		struct intel_encoder *intel_encoder = to_intel_encoder(connector); +		if (type_mask & intel_encoder->clone_mask)  			index_mask |= (1 << entry);  		entry++;  	} @@ -4494,12 +4495,12 @@ static void intel_setup_outputs(struct drm_device *dev)  		intel_tv_init(dev);  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -		struct intel_output *intel_output = to_intel_output(connector); -		struct drm_encoder *encoder = &intel_output->enc; +		struct intel_encoder *intel_encoder = to_intel_encoder(connector); +		struct drm_encoder *encoder = &intel_encoder->enc; -		encoder->possible_crtcs = intel_output->crtc_mask; +		encoder->possible_crtcs = intel_encoder->crtc_mask;  		encoder->possible_clones = intel_connector_clones(dev, -						intel_output->clone_mask); +						intel_encoder->clone_mask);  	}  } @@ -4717,6 +4718,20 @@ void intel_init_clock_gating(struct drm_device *dev)  	 * specs, but enable as much else as we can.  	 */  	if (HAS_PCH_SPLIT(dev)) { +		uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE; + +		if (IS_IRONLAKE(dev)) { +			/* Required for FBC */ +			dspclk_gate |= DPFDUNIT_CLOCK_GATE_DISABLE; +			/* Required for CxSR */ +			dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE; + +			I915_WRITE(PCH_3DCGDIS0, +				   MARIUNIT_CLOCK_GATE_DISABLE | +				   SVSMUNIT_CLOCK_GATE_DISABLE); +		} + +		I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);  		return;  	} else if (IS_G4X(dev)) {  		uint32_t dspclk_gate; @@ -4764,14 +4779,14 @@ void intel_init_clock_gating(struct drm_device *dev)  		struct drm_i915_gem_object *obj_priv = NULL;  		if (dev_priv->pwrctx) { -			obj_priv = dev_priv->pwrctx->driver_private; +			obj_priv = to_intel_bo(dev_priv->pwrctx);  		} else {  			struct drm_gem_object *pwrctx;  			pwrctx = intel_alloc_power_context(dev);  			if (pwrctx) {  				dev_priv->pwrctx = pwrctx; -				obj_priv = pwrctx->driver_private; +				obj_priv = to_intel_bo(pwrctx);  			}  		} @@ -4800,7 +4815,7 @@ static void intel_init_display(struct drm_device *dev)  			dev_priv->display.fbc_enabled = g4x_fbc_enabled;  			dev_priv->display.enable_fbc = g4x_enable_fbc;  			dev_priv->display.disable_fbc = g4x_disable_fbc; -		} else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) { +		} else if (IS_I965GM(dev)) {  			dev_priv->display.fbc_enabled = i8xx_fbc_enabled;  			dev_priv->display.enable_fbc = i8xx_enable_fbc;  			dev_priv->display.disable_fbc = i8xx_disable_fbc; @@ -4838,17 +4853,18 @@ static void intel_init_display(struct drm_device *dev)  		dev_priv->display.update_wm = g4x_update_wm;  	else if (IS_I965G(dev))  		dev_priv->display.update_wm = i965_update_wm; -	else if (IS_I9XX(dev) || IS_MOBILE(dev)) { +	else if (IS_I9XX(dev)) {  		dev_priv->display.update_wm = i9xx_update_wm;  		dev_priv->display.get_fifo_size = i9xx_get_fifo_size; +	} else if (IS_I85X(dev)) { +		dev_priv->display.update_wm = i9xx_update_wm; +		dev_priv->display.get_fifo_size = i85x_get_fifo_size;  	} else { -		if (IS_I85X(dev)) -			dev_priv->display.get_fifo_size = i85x_get_fifo_size; -		else if (IS_845G(dev)) +		dev_priv->display.update_wm = i830_update_wm; +		if (IS_845G(dev))  			dev_priv->display.get_fifo_size = i845_get_fifo_size;  		else  			dev_priv->display.get_fifo_size = i830_get_fifo_size; -		dev_priv->display.update_wm = i830_update_wm;  	}  } @@ -4942,7 +4958,7 @@ void intel_modeset_cleanup(struct drm_device *dev)  	if (dev_priv->pwrctx) {  		struct drm_i915_gem_object *obj_priv; -		obj_priv = dev_priv->pwrctx->driver_private; +		obj_priv = to_intel_bo(dev_priv->pwrctx);  		I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);  		I915_READ(PWRCTXA);  		i915_gem_object_unpin(dev_priv->pwrctx); @@ -4963,9 +4979,9 @@ void intel_modeset_cleanup(struct drm_device *dev)  */  struct drm_encoder *intel_best_encoder(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); -	return &intel_output->enc; +	return &intel_encoder->enc;  }  /* diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3ef3a0d0edd..77e40cfcf21 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -26,6 +26,7 @@   */  #include <linux/i2c.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "drm_crtc.h" @@ -54,23 +55,23 @@ struct intel_dp_priv {  	uint8_t link_bw;  	uint8_t lane_count;  	uint8_t dpcd[4]; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct i2c_adapter adapter;  	struct i2c_algo_dp_aux_data algo;  };  static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, +intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,  		    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);  static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); +intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);  void -intel_edp_link_config (struct intel_output *intel_output, +intel_edp_link_config (struct intel_encoder *intel_encoder,  		int *lane_num, int *link_bw)  { -	struct intel_dp_priv   *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;  	*lane_num = dp_priv->lane_count;  	if (dp_priv->link_bw == DP_LINK_BW_1_62) @@ -80,9 +81,9 @@ intel_edp_link_config (struct intel_output *intel_output,  }  static int -intel_dp_max_lane_count(struct intel_output *intel_output) +intel_dp_max_lane_count(struct intel_encoder *intel_encoder)  { -	struct intel_dp_priv   *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;  	int max_lane_count = 4;  	if (dp_priv->dpcd[0] >= 0x11) { @@ -98,9 +99,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output)  }  static int -intel_dp_max_link_bw(struct intel_output *intel_output) +intel_dp_max_link_bw(struct intel_encoder *intel_encoder)  { -	struct intel_dp_priv   *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;  	int max_link_bw = dp_priv->dpcd[1];  	switch (max_link_bw) { @@ -126,11 +127,11 @@ intel_dp_link_clock(uint8_t link_bw)  /* I think this is a fiction */  static int  intel_dp_link_required(struct drm_device *dev, -		       struct intel_output *intel_output, int pixel_clock) +		       struct intel_encoder *intel_encoder, int pixel_clock)  {  	struct drm_i915_private *dev_priv = dev->dev_private; -	if (IS_eDP(intel_output)) +	if (IS_eDP(intel_encoder))  		return (pixel_clock * dev_priv->edp_bpp) / 8;  	else  		return pixel_clock * 3; @@ -140,11 +141,11 @@ static int  intel_dp_mode_valid(struct drm_connector *connector,  		    struct drm_display_mode *mode)  { -	struct intel_output *intel_output = to_intel_output(connector); -	int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); -	int max_lanes = intel_dp_max_lane_count(intel_output); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); +	int max_lanes = intel_dp_max_lane_count(intel_encoder); -	if (intel_dp_link_required(connector->dev, intel_output, mode->clock) +	if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)  			> max_link_clock * max_lanes)  		return MODE_CLOCK_HIGH; @@ -208,13 +209,13 @@ intel_hrawclk(struct drm_device *dev)  }  static int -intel_dp_aux_ch(struct intel_output *intel_output, +intel_dp_aux_ch(struct intel_encoder *intel_encoder,  		uint8_t *send, int send_bytes,  		uint8_t *recv, int recv_size)  { -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	uint32_t output_reg = dp_priv->output_reg; -	struct drm_device *dev = intel_output->base.dev; +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	uint32_t ch_ctl = output_reg + 0x10;  	uint32_t ch_data = ch_ctl + 4; @@ -229,7 +230,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,  	 * and would like to run at 2MHz. So, take the  	 * hrawclk value and divide by 2 and use that  	 */ -	if (IS_eDP(intel_output)) +	if (IS_eDP(intel_encoder))  		aux_clock_divider = 225; /* eDP input clock at 450Mhz */  	else if (HAS_PCH_SPLIT(dev))  		aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ @@ -312,7 +313,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,  /* Write data to the aux channel in native mode */  static int -intel_dp_aux_native_write(struct intel_output *intel_output, +intel_dp_aux_native_write(struct intel_encoder *intel_encoder,  			  uint16_t address, uint8_t *send, int send_bytes)  {  	int ret; @@ -329,7 +330,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output,  	memcpy(&msg[4], send, send_bytes);  	msg_bytes = send_bytes + 4;  	for (;;) { -		ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1); +		ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);  		if (ret < 0)  			return ret;  		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) @@ -344,15 +345,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output,  /* Write a single byte to the aux channel in native mode */  static int -intel_dp_aux_native_write_1(struct intel_output *intel_output, +intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,  			    uint16_t address, uint8_t byte)  { -	return intel_dp_aux_native_write(intel_output, address, &byte, 1); +	return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);  }  /* read bytes from a native aux channel */  static int -intel_dp_aux_native_read(struct intel_output *intel_output, +intel_dp_aux_native_read(struct intel_encoder *intel_encoder,  			 uint16_t address, uint8_t *recv, int recv_bytes)  {  	uint8_t msg[4]; @@ -371,7 +372,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output,  	reply_bytes = recv_bytes + 1;  	for (;;) { -		ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, +		ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,  				      reply, reply_bytes);  		if (ret == 0)  			return -EPROTO; @@ -397,7 +398,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,  	struct intel_dp_priv *dp_priv = container_of(adapter,  						     struct intel_dp_priv,  						     adapter); -	struct intel_output *intel_output = dp_priv->intel_output; +	struct intel_encoder *intel_encoder = dp_priv->intel_encoder;  	uint16_t address = algo_data->address;  	uint8_t msg[5];  	uint8_t reply[2]; @@ -436,7 +437,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,  	}  	for (;;) { -	  ret = intel_dp_aux_ch(intel_output, +	  ret = intel_dp_aux_ch(intel_encoder,  				msg, msg_bytes,  				reply, reply_bytes);  		if (ret < 0) { @@ -464,9 +465,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,  }  static int -intel_dp_i2c_init(struct intel_output *intel_output, const char *name) +intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name)  { -	struct intel_dp_priv   *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;  	DRM_DEBUG_KMS("i2c_init %s\n", name);  	dp_priv->algo.running = false; @@ -479,7 +480,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)  	strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);  	dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';  	dp_priv->adapter.algo_data = &dp_priv->algo; -	dp_priv->adapter.dev.parent = &intel_output->base.kdev; +	dp_priv->adapter.dev.parent = &intel_encoder->base.kdev;  	return i2c_dp_aux_add_bus(&dp_priv->adapter);  } @@ -488,18 +489,18 @@ static bool  intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,  		    struct drm_display_mode *adjusted_mode)  { -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_dp_priv   *dp_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;  	int lane_count, clock; -	int max_lane_count = intel_dp_max_lane_count(intel_output); -	int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0; +	int max_lane_count = intel_dp_max_lane_count(intel_encoder); +	int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;  	static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };  	for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {  		for (clock = 0; clock <= max_clock; clock++) {  			int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; -			if (intel_dp_link_required(encoder->dev, intel_output, mode->clock) +			if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)  					<= link_avail) {  				dp_priv->link_bw = bws[clock];  				dp_priv->lane_count = lane_count; @@ -561,16 +562,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,  	struct intel_dp_m_n m_n;  	/* -	 * Find the lane count in the intel_output private +	 * Find the lane count in the intel_encoder private  	 */  	list_for_each_entry(connector, &mode_config->connector_list, head) { -		struct intel_output *intel_output = to_intel_output(connector); -		struct intel_dp_priv *dp_priv = intel_output->dev_priv; +		struct intel_encoder *intel_encoder = to_intel_encoder(connector); +		struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  		if (!connector->encoder || connector->encoder->crtc != crtc)  			continue; -		if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) { +		if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {  			lane_count = dp_priv->lane_count;  			break;  		} @@ -625,9 +626,9 @@ static void  intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,  		  struct drm_display_mode *adjusted_mode)  { -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; -	struct drm_crtc *crtc = intel_output->enc.crtc; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; +	struct drm_crtc *crtc = intel_encoder->enc.crtc;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);  	dp_priv->DP = (DP_LINK_TRAIN_OFF | @@ -666,7 +667,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,  	if (intel_crtc->pipe == 1)  		dp_priv->DP |= DP_PIPEB_SELECT; -	if (IS_eDP(intel_output)) { +	if (IS_eDP(intel_encoder)) {  		/* don't miss out required setting for eDP */  		dp_priv->DP |= DP_PLL_ENABLE;  		if (adjusted_mode->clock < 200000) @@ -701,22 +702,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)  static void  intel_dp_dpms(struct drm_encoder *encoder, int mode)  { -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; -	struct drm_device *dev = intel_output->base.dev; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	uint32_t dp_reg = I915_READ(dp_priv->output_reg);  	if (mode != DRM_MODE_DPMS_ON) {  		if (dp_reg & DP_PORT_EN) { -			intel_dp_link_down(intel_output, dp_priv->DP); -			if (IS_eDP(intel_output)) +			intel_dp_link_down(intel_encoder, dp_priv->DP); +			if (IS_eDP(intel_encoder))  				ironlake_edp_backlight_off(dev);  		}  	} else {  		if (!(dp_reg & DP_PORT_EN)) { -			intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); -			if (IS_eDP(intel_output)) +			intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); +			if (IS_eDP(intel_encoder))  				ironlake_edp_backlight_on(dev);  		}  	} @@ -728,12 +729,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)   * link status information   */  static bool -intel_dp_get_link_status(struct intel_output *intel_output, +intel_dp_get_link_status(struct intel_encoder *intel_encoder,  			 uint8_t link_status[DP_LINK_STATUS_SIZE])  {  	int ret; -	ret = intel_dp_aux_native_read(intel_output, +	ret = intel_dp_aux_native_read(intel_encoder,  				       DP_LANE0_1_STATUS,  				       link_status, DP_LINK_STATUS_SIZE);  	if (ret != DP_LINK_STATUS_SIZE) @@ -751,13 +752,13 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],  static void  intel_dp_save(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct drm_device *dev = intel_output->base.dev; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	dp_priv->save_DP = I915_READ(dp_priv->output_reg); -	intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET, +	intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET,  				 dp_priv->save_link_configuration,  				 sizeof (dp_priv->save_link_configuration));  } @@ -824,7 +825,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)  }  static void -intel_get_adjust_train(struct intel_output *intel_output, +intel_get_adjust_train(struct intel_encoder *intel_encoder,  		       uint8_t link_status[DP_LINK_STATUS_SIZE],  		       int lane_count,  		       uint8_t train_set[4]) @@ -941,15 +942,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)  }  static bool -intel_dp_set_link_train(struct intel_output *intel_output, +intel_dp_set_link_train(struct intel_encoder *intel_encoder,  			uint32_t dp_reg_value,  			uint8_t dp_train_pat,  			uint8_t train_set[4],  			bool first)  { -	struct drm_device *dev = intel_output->base.dev; +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	int ret;  	I915_WRITE(dp_priv->output_reg, dp_reg_value); @@ -957,11 +958,11 @@ intel_dp_set_link_train(struct intel_output *intel_output,  	if (first)  		intel_wait_for_vblank(dev); -	intel_dp_aux_native_write_1(intel_output, +	intel_dp_aux_native_write_1(intel_encoder,  				    DP_TRAINING_PATTERN_SET,  				    dp_train_pat); -	ret = intel_dp_aux_native_write(intel_output, +	ret = intel_dp_aux_native_write(intel_encoder,  					DP_TRAINING_LANE0_SET, train_set, 4);  	if (ret != 4)  		return false; @@ -970,12 +971,12 @@ intel_dp_set_link_train(struct intel_output *intel_output,  }  static void -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, +intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,  		    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])  { -	struct drm_device *dev = intel_output->base.dev; +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	uint8_t	train_set[4];  	uint8_t link_status[DP_LINK_STATUS_SIZE];  	int i; @@ -986,7 +987,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,  	int tries;  	/* Write the link configuration data */ -	intel_dp_aux_native_write(intel_output, 0x100, +	intel_dp_aux_native_write(intel_encoder, 0x100,  				  link_configuration, DP_LINK_CONFIGURATION_SIZE);  	DP |= DP_PORT_EN; @@ -1000,14 +1001,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,  		uint32_t    signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);  		DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; -		if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1, +		if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1,  					     DP_TRAINING_PATTERN_1, train_set, first))  			break;  		first = false;  		/* Set training pattern 1 */  		udelay(100); -		if (!intel_dp_get_link_status(intel_output, link_status)) +		if (!intel_dp_get_link_status(intel_encoder, link_status))  			break;  		if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { @@ -1032,7 +1033,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,  		voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;  		/* Compute new train_set as requested by target */ -		intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); +		intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);  	}  	/* channel equalization */ @@ -1044,13 +1045,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,  		DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;  		/* channel eq pattern */ -		if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2, +		if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2,  					     DP_TRAINING_PATTERN_2, train_set,  					     false))  			break;  		udelay(400); -		if (!intel_dp_get_link_status(intel_output, link_status)) +		if (!intel_dp_get_link_status(intel_encoder, link_status))  			break;  		if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { @@ -1063,26 +1064,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,  			break;  		/* Compute new train_set as requested by target */ -		intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); +		intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);  		++tries;  	}  	I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF);  	POSTING_READ(dp_priv->output_reg); -	intel_dp_aux_native_write_1(intel_output, +	intel_dp_aux_native_write_1(intel_encoder,  				    DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);  }  static void -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) +intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)  { -	struct drm_device *dev = intel_output->base.dev; +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	DRM_DEBUG_KMS("\n"); -	if (IS_eDP(intel_output)) { +	if (IS_eDP(intel_encoder)) {  		DP &= ~DP_PLL_ENABLE;  		I915_WRITE(dp_priv->output_reg, DP);  		POSTING_READ(dp_priv->output_reg); @@ -1095,7 +1096,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)  	udelay(17000); -	if (IS_eDP(intel_output)) +	if (IS_eDP(intel_encoder))  		DP |= DP_LINK_TRAIN_OFF;  	I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);  	POSTING_READ(dp_priv->output_reg); @@ -1104,13 +1105,13 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)  static void  intel_dp_restore(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	if (dp_priv->save_DP & DP_PORT_EN) -		intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration); +		intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration);  	else -		intel_dp_link_down(intel_output,  dp_priv->save_DP); +		intel_dp_link_down(intel_encoder,  dp_priv->save_DP);  }  /* @@ -1123,32 +1124,32 @@ intel_dp_restore(struct drm_connector *connector)   */  static void -intel_dp_check_link_status(struct intel_output *intel_output) +intel_dp_check_link_status(struct intel_encoder *intel_encoder)  { -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	uint8_t link_status[DP_LINK_STATUS_SIZE]; -	if (!intel_output->enc.crtc) +	if (!intel_encoder->enc.crtc)  		return; -	if (!intel_dp_get_link_status(intel_output, link_status)) { -		intel_dp_link_down(intel_output, dp_priv->DP); +	if (!intel_dp_get_link_status(intel_encoder, link_status)) { +		intel_dp_link_down(intel_encoder, dp_priv->DP);  		return;  	}  	if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) -		intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); +		intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);  }  static enum drm_connector_status  ironlake_dp_detect(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	enum drm_connector_status status;  	status = connector_status_disconnected; -	if (intel_dp_aux_native_read(intel_output, +	if (intel_dp_aux_native_read(intel_encoder,  				     0x000, dp_priv->dpcd,  				     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))  	{ @@ -1167,10 +1168,10 @@ ironlake_dp_detect(struct drm_connector *connector)  static enum drm_connector_status  intel_dp_detect(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct drm_device *dev = intel_output->base.dev; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	uint32_t temp, bit;  	enum drm_connector_status status; @@ -1209,7 +1210,7 @@ intel_dp_detect(struct drm_connector *connector)  		return connector_status_disconnected;  	status = connector_status_disconnected; -	if (intel_dp_aux_native_read(intel_output, +	if (intel_dp_aux_native_read(intel_encoder,  				     0x000, dp_priv->dpcd,  				     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))  	{ @@ -1221,20 +1222,20 @@ intel_dp_detect(struct drm_connector *connector)  static int intel_dp_get_modes(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct drm_device *dev = intel_output->base.dev; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	int ret;  	/* We should parse the EDID data and find out if it has an audio sink  	 */ -	ret = intel_ddc_get_modes(intel_output); +	ret = intel_ddc_get_modes(intel_encoder);  	if (ret)  		return ret;  	/* if eDP has no EDID, try to use fixed panel mode from VBT */ -	if (IS_eDP(intel_output)) { +	if (IS_eDP(intel_encoder)) {  		if (dev_priv->panel_fixed_mode != NULL) {  			struct drm_display_mode *mode;  			mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); @@ -1248,13 +1249,13 @@ static int intel_dp_get_modes(struct drm_connector *connector)  static void  intel_dp_destroy (struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); -	if (intel_output->i2c_bus) -		intel_i2c_destroy(intel_output->i2c_bus); +	if (intel_encoder->i2c_bus) +		intel_i2c_destroy(intel_encoder->i2c_bus);  	drm_sysfs_connector_remove(connector);  	drm_connector_cleanup(connector); -	kfree(intel_output); +	kfree(intel_encoder);  }  static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { @@ -1290,12 +1291,12 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {  };  void -intel_dp_hot_plug(struct intel_output *intel_output) +intel_dp_hot_plug(struct intel_encoder *intel_encoder)  { -	struct intel_dp_priv *dp_priv = intel_output->dev_priv; +	struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;  	if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) -		intel_dp_check_link_status(intel_output); +		intel_dp_check_link_status(intel_encoder);  }  void @@ -1303,53 +1304,53 @@ intel_dp_init(struct drm_device *dev, int output_reg)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_connector *connector; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct intel_dp_priv *dp_priv;  	const char *name = NULL; -	intel_output = kcalloc(sizeof(struct intel_output) +  +	intel_encoder = kcalloc(sizeof(struct intel_encoder) +  			       sizeof(struct intel_dp_priv), 1, GFP_KERNEL); -	if (!intel_output) +	if (!intel_encoder)  		return; -	dp_priv = (struct intel_dp_priv *)(intel_output + 1); +	dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); -	connector = &intel_output->base; +	connector = &intel_encoder->base;  	drm_connector_init(dev, connector, &intel_dp_connector_funcs,  			   DRM_MODE_CONNECTOR_DisplayPort);  	drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);  	if (output_reg == DP_A) -		intel_output->type = INTEL_OUTPUT_EDP; +		intel_encoder->type = INTEL_OUTPUT_EDP;  	else -		intel_output->type = INTEL_OUTPUT_DISPLAYPORT; +		intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;  	if (output_reg == DP_B || output_reg == PCH_DP_B) -		intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT); +		intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);  	else if (output_reg == DP_C || output_reg == PCH_DP_C) -		intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT); +		intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);  	else if (output_reg == DP_D || output_reg == PCH_DP_D) -		intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); +		intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); -	if (IS_eDP(intel_output)) -		intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT); +	if (IS_eDP(intel_encoder)) +		intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); -	intel_output->crtc_mask = (1 << 0) | (1 << 1); +	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);  	connector->interlace_allowed = true;  	connector->doublescan_allowed = 0; -	dp_priv->intel_output = intel_output; +	dp_priv->intel_encoder = intel_encoder;  	dp_priv->output_reg = output_reg;  	dp_priv->has_audio = false;  	dp_priv->dpms_mode = DRM_MODE_DPMS_ON; -	intel_output->dev_priv = dp_priv; +	intel_encoder->dev_priv = dp_priv; -	drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs, +	drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs,  			 DRM_MODE_ENCODER_TMDS); -	drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs); +	drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs); -	drm_mode_connector_attach_encoder(&intel_output->base, -					  &intel_output->enc); +	drm_mode_connector_attach_encoder(&intel_encoder->base, +					  &intel_encoder->enc);  	drm_sysfs_connector_add(connector);  	/* Set up the DDC bus. */ @@ -1377,10 +1378,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)  			break;  	} -	intel_dp_i2c_init(intel_output, name); +	intel_dp_i2c_init(intel_encoder, name); -	intel_output->ddc_bus = &dp_priv->adapter; -	intel_output->hot_plug = intel_dp_hot_plug; +	intel_encoder->ddc_bus = &dp_priv->adapter; +	intel_encoder->hot_plug = intel_dp_hot_plug;  	if (output_reg == DP_A) {  		/* initialize panel mode from VBT if available for eDP */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3a467ca5785..e30253755f1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -95,7 +95,7 @@ struct intel_framebuffer {  }; -struct intel_output { +struct intel_encoder {  	struct drm_connector base;  	struct drm_encoder enc; @@ -105,7 +105,7 @@ struct intel_output {  	bool load_detect_temp;  	bool needs_tv_clock;  	void *dev_priv; -	void (*hot_plug)(struct intel_output *); +	void (*hot_plug)(struct intel_encoder *);  	int crtc_mask;  	int clone_mask;  }; @@ -152,15 +152,15 @@ struct intel_crtc {  };  #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) -#define to_intel_output(x) container_of(x, struct intel_output, base) -#define enc_to_intel_output(x) container_of(x, struct intel_output, enc) +#define to_intel_encoder(x) container_of(x, struct intel_encoder, base) +#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)  #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)  struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,  				     const char *name);  void intel_i2c_destroy(struct i2c_adapter *adapter); -int intel_ddc_get_modes(struct intel_output *intel_output); -extern bool intel_ddc_probe(struct intel_output *intel_output); +int intel_ddc_get_modes(struct intel_encoder *intel_encoder); +extern bool intel_ddc_probe(struct intel_encoder *intel_encoder);  void intel_i2c_quirk_set(struct drm_device *dev, bool enable);  void intel_i2c_reset_gmbus(struct drm_device *dev); @@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);  void  intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,  		 struct drm_display_mode *adjusted_mode); -extern void intel_edp_link_config (struct intel_output *, int *, int *); +extern void intel_edp_link_config (struct intel_encoder *, int *, int *);  extern int intel_panel_fitter_pipe (struct drm_device *dev); @@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,  				struct drm_file *file_priv);  extern void intel_wait_for_vblank(struct drm_device *dev);  extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); -extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output, +extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,  						   struct drm_display_mode *mode,  						   int *dpms_mode); -extern void intel_release_load_detect_pipe(struct intel_output *intel_output, +extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,  					   int dpms_mode);  extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index a4d2606de77..ebf213c96b9 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -25,6 +25,7 @@   *	Eric Anholt <eric@anholt.net>   */  #include <linux/i2c.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "drm_crtc.h" @@ -79,8 +80,8 @@ static struct intel_dvo_device intel_dvo_devices[] = {  static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)  {  	struct drm_i915_private *dev_priv = encoder->dev->dev_private; -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	u32 dvo_reg = dvo->dvo_reg;  	u32 temp = I915_READ(dvo_reg); @@ -98,8 +99,8 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)  static void intel_dvo_save(struct drm_connector *connector)  {  	struct drm_i915_private *dev_priv = connector->dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	/* Each output should probably just save the registers it touches,  	 * but for now, use more overkill. @@ -114,8 +115,8 @@ static void intel_dvo_save(struct drm_connector *connector)  static void intel_dvo_restore(struct drm_connector *connector)  {  	struct drm_i915_private *dev_priv = connector->dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	dvo->dev_ops->restore(dvo); @@ -127,8 +128,8 @@ static void intel_dvo_restore(struct drm_connector *connector)  static int intel_dvo_mode_valid(struct drm_connector *connector,  				struct drm_display_mode *mode)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)  		return MODE_NO_DBLESCAN; @@ -149,8 +150,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,  				 struct drm_display_mode *mode,  				 struct drm_display_mode *adjusted_mode)  { -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	/* If we have timings from the BIOS for the panel, put them in  	 * to the adjusted mode.  The CRTC will be set up for this mode, @@ -185,8 +186,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,  	struct drm_device *dev = encoder->dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	int pipe = intel_crtc->pipe;  	u32 dvo_val;  	u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; @@ -240,23 +241,23 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,   */  static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	return dvo->dev_ops->detect(dvo);  }  static int intel_dvo_get_modes(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	/* We should probably have an i2c driver get_modes function for those  	 * devices which will have a fixed set of modes determined by the chip  	 * (TV-out, for example), but for now with just TMDS and LVDS,  	 * that's not the case.  	 */ -	intel_ddc_get_modes(intel_output); +	intel_ddc_get_modes(intel_encoder);  	if (!list_empty(&connector->probed_modes))  		return 1; @@ -274,8 +275,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector)  static void intel_dvo_destroy (struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	if (dvo) {  		if (dvo->dev_ops->destroy) @@ -285,13 +286,13 @@ static void intel_dvo_destroy (struct drm_connector *connector)  		/* no need, in i830_dvoices[] now */  		//kfree(dvo);  	} -	if (intel_output->i2c_bus) -		intel_i2c_destroy(intel_output->i2c_bus); -	if (intel_output->ddc_bus) -		intel_i2c_destroy(intel_output->ddc_bus); +	if (intel_encoder->i2c_bus) +		intel_i2c_destroy(intel_encoder->i2c_bus); +	if (intel_encoder->ddc_bus) +		intel_i2c_destroy(intel_encoder->ddc_bus);  	drm_sysfs_connector_remove(connector);  	drm_connector_cleanup(connector); -	kfree(intel_output); +	kfree(intel_encoder);  }  #ifdef RANDR_GET_CRTC_INTERFACE @@ -299,8 +300,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);  	return intel_pipe_to_crtc(pScrn, pipe); @@ -351,8 +352,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_dvo_device *dvo = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_dvo_device *dvo = intel_encoder->dev_priv;  	uint32_t dvo_reg = dvo->dvo_reg;  	uint32_t dvo_val = I915_READ(dvo_reg);  	struct drm_display_mode *mode = NULL; @@ -382,24 +383,24 @@ intel_dvo_get_current_mode (struct drm_connector *connector)  void intel_dvo_init(struct drm_device *dev)  { -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct intel_dvo_device *dvo;  	struct i2c_adapter *i2cbus = NULL;  	int ret = 0;  	int i;  	int encoder_type = DRM_MODE_ENCODER_NONE; -	intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); -	if (!intel_output) +	intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL); +	if (!intel_encoder)  		return;  	/* Set up the DDC bus */ -	intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); -	if (!intel_output->ddc_bus) +	intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); +	if (!intel_encoder->ddc_bus)  		goto free_intel;  	/* Now, try to find a controller */  	for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { -		struct drm_connector *connector = &intel_output->base; +		struct drm_connector *connector = &intel_encoder->base;  		int gpio;  		dvo = &intel_dvo_devices[i]; @@ -434,11 +435,11 @@ void intel_dvo_init(struct drm_device *dev)  		if (!ret)  			continue; -		intel_output->type = INTEL_OUTPUT_DVO; -		intel_output->crtc_mask = (1 << 0) | (1 << 1); +		intel_encoder->type = INTEL_OUTPUT_DVO; +		intel_encoder->crtc_mask = (1 << 0) | (1 << 1);  		switch (dvo->type) {  		case INTEL_DVO_CHIP_TMDS: -			intel_output->clone_mask = +			intel_encoder->clone_mask =  				(1 << INTEL_DVO_TMDS_CLONE_BIT) |  				(1 << INTEL_ANALOG_CLONE_BIT);  			drm_connector_init(dev, connector, @@ -447,7 +448,7 @@ void intel_dvo_init(struct drm_device *dev)  			encoder_type = DRM_MODE_ENCODER_TMDS;  			break;  		case INTEL_DVO_CHIP_LVDS: -			intel_output->clone_mask = +			intel_encoder->clone_mask =  				(1 << INTEL_DVO_LVDS_CLONE_BIT);  			drm_connector_init(dev, connector,  					   &intel_dvo_connector_funcs, @@ -462,16 +463,16 @@ void intel_dvo_init(struct drm_device *dev)  		connector->interlace_allowed = false;  		connector->doublescan_allowed = false; -		intel_output->dev_priv = dvo; -		intel_output->i2c_bus = i2cbus; +		intel_encoder->dev_priv = dvo; +		intel_encoder->i2c_bus = i2cbus; -		drm_encoder_init(dev, &intel_output->enc, +		drm_encoder_init(dev, &intel_encoder->enc,  				 &intel_dvo_enc_funcs, encoder_type); -		drm_encoder_helper_add(&intel_output->enc, +		drm_encoder_helper_add(&intel_encoder->enc,  				       &intel_dvo_helper_funcs); -		drm_mode_connector_attach_encoder(&intel_output->base, -						  &intel_output->enc); +		drm_mode_connector_attach_encoder(&intel_encoder->base, +						  &intel_encoder->enc);  		if (dvo->type == INTEL_DVO_CHIP_LVDS) {  			/* For our LVDS chipsets, we should hopefully be able  			 * to dig the fixed panel mode out of the BIOS data. @@ -489,10 +490,10 @@ void intel_dvo_init(struct drm_device *dev)  		return;  	} -	intel_i2c_destroy(intel_output->ddc_bus); +	intel_i2c_destroy(intel_encoder->ddc_bus);  	/* Didn't find a chip, so tear down. */  	if (i2cbus != NULL)  		intel_i2c_destroy(i2cbus);  free_intel: -	kfree(intel_output); +	kfree(intel_encoder);  } diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 8cd791dc5b2..8a0b3bcdc7b 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -30,7 +30,6 @@  #include <linux/string.h>  #include <linux/mm.h>  #include <linux/tty.h> -#include <linux/slab.h>  #include <linux/sysrq.h>  #include <linux/delay.h>  #include <linux/fb.h> @@ -145,7 +144,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,  		ret = -ENOMEM;  		goto out;  	} -	obj_priv = fbo->driver_private; +	obj_priv = to_intel_bo(fbo);  	mutex_lock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index a30f8bfc198..48cade0cf7b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -27,6 +27,7 @@   */  #include <linux/i2c.h> +#include <linux/slab.h>  #include <linux/delay.h>  #include "drmP.h"  #include "drm.h" @@ -50,8 +51,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_crtc *crtc = encoder->crtc;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;  	u32 sdvox;  	sdvox = SDVO_ENCODING_HDMI | @@ -73,8 +74,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)  {  	struct drm_device *dev = encoder->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;  	u32 temp;  	temp = I915_READ(hdmi_priv->sdvox_reg); @@ -109,8 +110,8 @@ static void intel_hdmi_save(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;  	hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg);  } @@ -119,8 +120,8 @@ static void intel_hdmi_restore(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;  	I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX);  	POSTING_READ(hdmi_priv->sdvox_reg); @@ -150,21 +151,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,  static enum drm_connector_status  intel_hdmi_detect(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;  	struct edid *edid = NULL;  	enum drm_connector_status status = connector_status_disconnected;  	hdmi_priv->has_hdmi_sink = false; -	edid = drm_get_edid(&intel_output->base, -			    intel_output->ddc_bus); +	edid = drm_get_edid(&intel_encoder->base, +			    intel_encoder->ddc_bus);  	if (edid) {  		if (edid->input & DRM_EDID_INPUT_DIGITAL) {  			status = connector_status_connected;  			hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);  		} -		intel_output->base.display_info.raw_edid = NULL; +		intel_encoder->base.display_info.raw_edid = NULL;  		kfree(edid);  	} @@ -173,24 +174,24 @@ intel_hdmi_detect(struct drm_connector *connector)  static int intel_hdmi_get_modes(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector);  	/* We should parse the EDID data and find out if it's an HDMI sink so  	 * we can send audio to it.  	 */ -	return intel_ddc_get_modes(intel_output); +	return intel_ddc_get_modes(intel_encoder);  }  static void intel_hdmi_destroy(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); -	if (intel_output->i2c_bus) -		intel_i2c_destroy(intel_output->i2c_bus); +	if (intel_encoder->i2c_bus) +		intel_i2c_destroy(intel_encoder->i2c_bus);  	drm_sysfs_connector_remove(connector);  	drm_connector_cleanup(connector); -	kfree(intel_output); +	kfree(intel_encoder);  }  static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { @@ -229,63 +230,63 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_connector *connector; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct intel_hdmi_priv *hdmi_priv; -	intel_output = kcalloc(sizeof(struct intel_output) + +	intel_encoder = kcalloc(sizeof(struct intel_encoder) +  			       sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); -	if (!intel_output) +	if (!intel_encoder)  		return; -	hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1); +	hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); -	connector = &intel_output->base; +	connector = &intel_encoder->base;  	drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,  			   DRM_MODE_CONNECTOR_HDMIA);  	drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); -	intel_output->type = INTEL_OUTPUT_HDMI; +	intel_encoder->type = INTEL_OUTPUT_HDMI;  	connector->interlace_allowed = 0;  	connector->doublescan_allowed = 0; -	intel_output->crtc_mask = (1 << 0) | (1 << 1); +	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);  	/* Set up the DDC bus. */  	if (sdvox_reg == SDVOB) { -		intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); -		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); +		intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); +		intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");  		dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;  	} else if (sdvox_reg == SDVOC) { -		intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); -		intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); +		intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); +		intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");  		dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;  	} else if (sdvox_reg == HDMIB) { -		intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); -		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, +		intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); +		intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,  								"HDMIB");  		dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;  	} else if (sdvox_reg == HDMIC) { -		intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); -		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, +		intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); +		intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,  								"HDMIC");  		dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;  	} else if (sdvox_reg == HDMID) { -		intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); -		intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, +		intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); +		intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,  								"HDMID");  		dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;  	} -	if (!intel_output->ddc_bus) +	if (!intel_encoder->ddc_bus)  		goto err_connector;  	hdmi_priv->sdvox_reg = sdvox_reg; -	intel_output->dev_priv = hdmi_priv; +	intel_encoder->dev_priv = hdmi_priv; -	drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs, +	drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,  			 DRM_MODE_ENCODER_TMDS); -	drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs); +	drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs); -	drm_mode_connector_attach_encoder(&intel_output->base, -					  &intel_output->enc); +	drm_mode_connector_attach_encoder(&intel_encoder->base, +					  &intel_encoder->enc);  	drm_sysfs_connector_add(connector);  	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written @@ -301,7 +302,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)  err_connector:  	drm_connector_cleanup(connector); -	kfree(intel_output); +	kfree(intel_encoder);  	return;  } diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index fcc753ca5d9..c2649c7df14 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -26,6 +26,7 @@   *	Eric Anholt <eric@anholt.net>   */  #include <linux/i2c.h> +#include <linux/slab.h>  #include <linux/i2c-id.h>  #include <linux/i2c-algo-bit.h>  #include "drmP.h" diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 14e516fdc2d..b66806a37d3 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -30,6 +30,7 @@  #include <acpi/button.h>  #include <linux/dmi.h>  #include <linux/i2c.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "drm_crtc.h" @@ -238,8 +239,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);  	struct drm_encoder *tmp_encoder; -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;  	u32 pfit_control = 0, pfit_pgm_ratios = 0;  	int left_border = 0, right_border = 0, top_border = 0;  	int bottom_border = 0; @@ -586,8 +587,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,  {  	struct drm_device *dev = encoder->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;  	/*  	 * The LVDS pin pair will already have been turned on in the @@ -607,53 +608,6 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,  	I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control);  } -/* Some lid devices report incorrect lid status, assume they're connected */ -static const struct dmi_system_id bad_lid_status[] = { -	{ -		.ident = "Compaq nx9020", -		.matches = { -			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), -			DMI_MATCH(DMI_BOARD_NAME, "3084"), -		}, -	}, -	{ -		.ident = "Samsung SX20S", -		.matches = { -			DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), -			DMI_MATCH(DMI_BOARD_NAME, "SX20S"), -		}, -	}, -	{ -		.ident = "Aspire One", -		.matches = { -			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), -			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"), -		}, -	}, -	{ -		.ident = "Aspire 1810T", -		.matches = { -			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), -			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1810T"), -		}, -	}, -	{ -		.ident = "PC-81005", -		.matches = { -			DMI_MATCH(DMI_SYS_VENDOR, "MALATA"), -			DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), -		}, -	}, -	{ -		.ident = "Clevo M5x0N", -		.matches = { -			DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), -			DMI_MATCH(DMI_BOARD_NAME, "M5x0N"), -		}, -	}, -	{ } -}; -  /**   * Detect the LVDS connection.   * @@ -669,12 +623,9 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect  	/* ACPI lid methods were generally unreliable in this generation, so  	 * don't even bother.  	 */ -	if (IS_GEN2(dev)) +	if (IS_GEN2(dev) || IS_GEN3(dev))  		return connector_status_connected; -	if (!dmi_check_system(bad_lid_status) && !acpi_lid_open()) -		status = connector_status_disconnected; -  	return status;  } @@ -684,14 +635,16 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect  static int intel_lvds_get_modes(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev; -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector);  	struct drm_i915_private *dev_priv = dev->dev_private;  	int ret = 0; -	ret = intel_ddc_get_modes(intel_output); +	if (dev_priv->lvds_edid_good) { +		ret = intel_ddc_get_modes(intel_encoder); -	if (ret) -		return ret; +		if (ret) +			return ret; +	}  	/* Didn't get an EDID, so  	 * Set wide sync ranges so we get all modes @@ -764,11 +717,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,  static void intel_lvds_destroy(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev; -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector);  	struct drm_i915_private *dev_priv = dev->dev_private; -	if (intel_output->ddc_bus) -		intel_i2c_destroy(intel_output->ddc_bus); +	if (intel_encoder->ddc_bus) +		intel_i2c_destroy(intel_encoder->ddc_bus);  	if (dev_priv->lid_notifier.notifier_call)  		acpi_lid_notifier_unregister(&dev_priv->lid_notifier);  	drm_sysfs_connector_remove(connector); @@ -781,13 +734,13 @@ static int intel_lvds_set_property(struct drm_connector *connector,  				   uint64_t value)  {  	struct drm_device *dev = connector->dev; -	struct intel_output *intel_output = -			to_intel_output(connector); +	struct intel_encoder *intel_encoder = +			to_intel_encoder(connector);  	if (property == dev->mode_config.scaling_mode_property &&  				connector->encoder) {  		struct drm_crtc *crtc = connector->encoder->crtc; -		struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; +		struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;  		if (value == DRM_MODE_SCALE_NONE) {  			DRM_DEBUG_KMS("no scaling not supported\n");  			return 0; @@ -907,6 +860,14 @@ static const struct dmi_system_id intel_no_lvds[] = {  			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),  		},  	}, +	{ +		.callback = intel_no_lvds_dmi_callback, +		.ident = "Clientron U800", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), +			DMI_MATCH(DMI_PRODUCT_NAME, "U800"), +		}, +	},  	{ }	/* terminating entry */  }; @@ -1017,7 +978,7 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)  void intel_lvds_init(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct drm_connector *connector;  	struct drm_encoder *encoder;  	struct drm_display_mode *scan; /* *modes, *bios_mode; */ @@ -1045,40 +1006,40 @@ void intel_lvds_init(struct drm_device *dev)  		gpio = PCH_GPIOC;  	} -	intel_output = kzalloc(sizeof(struct intel_output) + +	intel_encoder = kzalloc(sizeof(struct intel_encoder) +  				sizeof(struct intel_lvds_priv), GFP_KERNEL); -	if (!intel_output) { +	if (!intel_encoder) {  		return;  	} -	connector = &intel_output->base; -	encoder = &intel_output->enc; -	drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs, +	connector = &intel_encoder->base; +	encoder = &intel_encoder->enc; +	drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs,  			   DRM_MODE_CONNECTOR_LVDS); -	drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs, +	drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs,  			 DRM_MODE_ENCODER_LVDS); -	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); -	intel_output->type = INTEL_OUTPUT_LVDS; +	drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); +	intel_encoder->type = INTEL_OUTPUT_LVDS; -	intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); -	intel_output->crtc_mask = (1 << 1); +	intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); +	intel_encoder->crtc_mask = (1 << 1);  	drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);  	drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);  	connector->display_info.subpixel_order = SubPixelHorizontalRGB;  	connector->interlace_allowed = false;  	connector->doublescan_allowed = false; -	lvds_priv = (struct intel_lvds_priv *)(intel_output + 1); -	intel_output->dev_priv = lvds_priv; +	lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1); +	intel_encoder->dev_priv = lvds_priv;  	/* create the scaling mode property */  	drm_mode_create_scaling_mode_property(dev);  	/*  	 * the initial panel fitting mode will be FULL_SCREEN.  	 */ -	drm_connector_attach_property(&intel_output->base, +	drm_connector_attach_property(&intel_encoder->base,  				      dev->mode_config.scaling_mode_property,  				      DRM_MODE_SCALE_FULLSCREEN);  	lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; @@ -1093,8 +1054,8 @@ void intel_lvds_init(struct drm_device *dev)  	 */  	/* Set up the DDC bus. */ -	intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); -	if (!intel_output->ddc_bus) { +	intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); +	if (!intel_encoder->ddc_bus) {  		dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "  			   "failed.\n");  		goto failed; @@ -1104,7 +1065,10 @@ void intel_lvds_init(struct drm_device *dev)  	 * Attempt to get the fixed panel mode from DDC.  Assume that the  	 * preferred mode is the right one.  	 */ -	intel_ddc_get_modes(intel_output); +	dev_priv->lvds_edid_good = true; + +	if (!intel_ddc_get_modes(intel_encoder)) +		dev_priv->lvds_edid_good = false;  	list_for_each_entry(scan, &connector->probed_modes, head) {  		mutex_lock(&dev->mode_config.mutex); @@ -1182,9 +1146,9 @@ out:  failed:  	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); -	if (intel_output->ddc_bus) -		intel_i2c_destroy(intel_output->ddc_bus); +	if (intel_encoder->ddc_bus) +		intel_i2c_destroy(intel_encoder->ddc_bus);  	drm_connector_cleanup(connector);  	drm_encoder_cleanup(encoder); -	kfree(intel_output); +	kfree(intel_encoder);  } diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 67e2f4632a2..8e5c83b2d12 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c @@ -23,6 +23,7 @@   * DEALINGS IN THE SOFTWARE.   */ +#include <linux/slab.h>  #include <linux/i2c.h>  #include <linux/fb.h>  #include "drmP.h" @@ -33,7 +34,7 @@   * intel_ddc_probe   *   */ -bool intel_ddc_probe(struct intel_output *intel_output) +bool intel_ddc_probe(struct intel_encoder *intel_encoder)  {  	u8 out_buf[] = { 0x0, 0x0};  	u8 buf[2]; @@ -53,9 +54,9 @@ bool intel_ddc_probe(struct intel_output *intel_output)  		}  	}; -	intel_i2c_quirk_set(intel_output->base.dev, true); -	ret = i2c_transfer(intel_output->ddc_bus, msgs, 2); -	intel_i2c_quirk_set(intel_output->base.dev, false); +	intel_i2c_quirk_set(intel_encoder->base.dev, true); +	ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2); +	intel_i2c_quirk_set(intel_encoder->base.dev, false);  	if (ret == 2)  		return true; @@ -68,19 +69,19 @@ bool intel_ddc_probe(struct intel_output *intel_output)   *   * Fetch the EDID information from @connector using the DDC bus.   */ -int intel_ddc_get_modes(struct intel_output *intel_output) +int intel_ddc_get_modes(struct intel_encoder *intel_encoder)  {  	struct edid *edid;  	int ret = 0; -	intel_i2c_quirk_set(intel_output->base.dev, true); -	edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); -	intel_i2c_quirk_set(intel_output->base.dev, false); +	intel_i2c_quirk_set(intel_encoder->base.dev, true); +	edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus); +	intel_i2c_quirk_set(intel_encoder->base.dev, false);  	if (edid) { -		drm_mode_connector_update_edid_property(&intel_output->base, +		drm_mode_connector_update_edid_property(&intel_encoder->base,  							edid); -		ret = drm_add_edid_modes(&intel_output->base, edid); -		intel_output->base.display_info.raw_edid = NULL; +		ret = drm_add_edid_modes(&intel_encoder->base, edid); +		intel_encoder->base.display_info.raw_edid = NULL;  		kfree(edid);  	} diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d355d1d527e..6d524a1fc27 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -724,7 +724,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,  	int ret, tmp_width;  	struct overlay_registers *regs;  	bool scale_changed = false; -	struct drm_i915_gem_object *bo_priv = new_bo->driver_private; +	struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);  	struct drm_device *dev = overlay->dev;  	BUG_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -809,7 +809,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,  	intel_overlay_continue(overlay, scale_changed);  	overlay->old_vid_bo = overlay->vid_bo; -	overlay->vid_bo = new_bo->driver_private; +	overlay->vid_bo = to_intel_bo(new_bo);  	return 0; @@ -1068,14 +1068,18 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,  	drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,                          DRM_MODE_OBJECT_CRTC); -	if (!drmmode_obj) -		return -ENOENT; +	if (!drmmode_obj) { +		ret = -ENOENT; +		goto out_free; +	}  	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));  	new_bo = drm_gem_object_lookup(dev, file_priv,  			put_image_rec->bo_handle); -	if (!new_bo) -		return -ENOENT; +	if (!new_bo) { +		ret = -ENOENT; +		goto out_free; +	}  	mutex_lock(&dev->mode_config.mutex);  	mutex_lock(&dev->struct_mutex); @@ -1165,6 +1169,7 @@ out_unlock:  	mutex_unlock(&dev->struct_mutex);  	mutex_unlock(&dev->mode_config.mutex);  	drm_gem_object_unreference_unlocked(new_bo); +out_free:  	kfree(params);  	return ret; @@ -1339,7 +1344,7 @@ void intel_setup_overlay(struct drm_device *dev)  	reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE);  	if (!reg_bo)  		goto out_free; -	overlay->reg_bo = reg_bo->driver_private; +	overlay->reg_bo = to_intel_bo(reg_bo);  	if (OVERLAY_NONPHYSICAL(dev)) {  		ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 48daee5c9c6..87d953664cb 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -26,6 +26,7 @@   *	Eric Anholt <eric@anholt.net>   */  #include <linux/i2c.h> +#include <linux/slab.h>  #include <linux/delay.h>  #include "drmP.h"  #include "drm.h" @@ -53,7 +54,7 @@ struct intel_sdvo_priv {  	u8 slave_addr;  	/* Register for the SDVO device: SDVOB or SDVOC */ -	int output_device; +	int sdvo_reg;  	/* Active outputs controlled by this SDVO output */  	uint16_t controlled_output; @@ -123,7 +124,7 @@ struct intel_sdvo_priv {  	 */  	struct intel_sdvo_encode encode; -	/* DDC bus used by this SDVO output */ +	/* DDC bus used by this SDVO encoder */  	uint8_t ddc_bus;  	/* Mac mini hack -- use the same DDC as the analog connector */ @@ -161,22 +162,22 @@ struct intel_sdvo_priv {  };  static bool -intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags); +intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags);  /**   * Writes the SDVOB or SDVOC with the given value, but always writes both   * SDVOB and SDVOC to work around apparent hardware issues (according to   * comments in the BIOS).   */ -static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val) +static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)  { -	struct drm_device *dev = intel_output->base.dev; +	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_sdvo_priv   *sdvo_priv = intel_output->dev_priv; +	struct intel_sdvo_priv   *sdvo_priv = intel_encoder->dev_priv;  	u32 bval = val, cval = val;  	int i; -	if (sdvo_priv->output_device == SDVOB) { +	if (sdvo_priv->sdvo_reg == SDVOB) {  		cval = I915_READ(SDVOC);  	} else {  		bval = I915_READ(SDVOB); @@ -195,10 +196,10 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)  	}  } -static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, +static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,  				 u8 *ch)  { -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	u8 out_buf[2];  	u8 buf[2];  	int ret; @@ -221,7 +222,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,  	out_buf[0] = addr;  	out_buf[1] = 0; -	if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) +	if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)  	{  		*ch = buf[0];  		return true; @@ -231,10 +232,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,  	return false;  } -static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, +static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,  				  u8 ch)  { -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	u8 out_buf[2];  	struct i2c_msg msgs[] = {  		{ @@ -248,7 +249,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,  	out_buf[0] = addr;  	out_buf[1] = ch; -	if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) +	if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)  	{  		return true;  	} @@ -352,13 +353,13 @@ static const struct _sdvo_cmd_name {      SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),  }; -#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") -#define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv) +#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC") +#define SDVO_PRIV(encoder)   ((struct intel_sdvo_priv *) (encoder)->dev_priv) -static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, +static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,  				   void *args, int args_len)  { -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	int i;  	DRM_DEBUG_KMS("%s: W: %02X ", @@ -378,19 +379,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,  	DRM_LOG_KMS("\n");  } -static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd, +static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,  				 void *args, int args_len)  {  	int i; -	intel_sdvo_debug_write(intel_output, cmd, args, args_len); +	intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);  	for (i = 0; i < args_len; i++) { -		intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i, +		intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,  				      ((u8*)args)[i]);  	} -	intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd); +	intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);  }  static const char *cmd_status_names[] = { @@ -403,11 +404,11 @@ static const char *cmd_status_names[] = {  	"Scaling not supported"  }; -static void intel_sdvo_debug_response(struct intel_output *intel_output, +static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,  				      void *response, int response_len,  				      u8 status)  { -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	int i;  	DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); @@ -422,7 +423,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,  	DRM_LOG_KMS("\n");  } -static u8 intel_sdvo_read_response(struct intel_output *intel_output, +static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,  				   void *response, int response_len)  {  	int i; @@ -432,16 +433,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output,  	while (retry--) {  		/* Read the command response */  		for (i = 0; i < response_len; i++) { -			intel_sdvo_read_byte(intel_output, +			intel_sdvo_read_byte(intel_encoder,  					     SDVO_I2C_RETURN_0 + i,  					     &((u8 *)response)[i]);  		}  		/* read the return status */ -		intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS, +		intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,  				     &status); -		intel_sdvo_debug_response(intel_output, response, response_len, +		intel_sdvo_debug_response(intel_encoder, response, response_len,  					  status);  		if (status != SDVO_CMD_STATUS_PENDING)  			return status; @@ -469,10 +470,10 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)   * another I2C transaction after issuing the DDC bus switch, it will be   * switched to the internal SDVO register.   */ -static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, +static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,  					      u8 target)  { -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	u8 out_buf[2], cmd_buf[2], ret_value[2], ret;  	struct i2c_msg msgs[] = {  		{ @@ -496,10 +497,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,  		},  	}; -	intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, +	intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,  					&target, 1);  	/* write the DDC switch command argument */ -	intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target); +	intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);  	out_buf[0] = SDVO_I2C_OPCODE;  	out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; @@ -508,7 +509,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,  	ret_value[0] = 0;  	ret_value[1] = 0; -	ret = i2c_transfer(intel_output->i2c_bus, msgs, 3); +	ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);  	if (ret != 3) {  		/* failure in I2C transfer */  		DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); @@ -522,7 +523,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,  	return;  } -static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) +static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)  {  	struct intel_sdvo_set_target_input_args targets = {0};  	u8 status; @@ -533,10 +534,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool  	if (target_1)  		targets.target_1 = 1; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,  			     sizeof(targets)); -	status = intel_sdvo_read_response(intel_output, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	return (status == SDVO_CMD_STATUS_SUCCESS);  } @@ -547,13 +548,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool   * This function is making an assumption about the layout of the response,   * which should be checked against the docs.   */ -static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2) +static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)  {  	struct intel_sdvo_get_trained_inputs_response response;  	u8 status; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); -	status = intel_sdvo_read_response(intel_output, &response, sizeof(response)); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; @@ -562,29 +563,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo  	return true;  } -static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output, +static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder,  					  u16 *outputs)  {  	u8 status; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); -	status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs)); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs));  	return (status == SDVO_CMD_STATUS_SUCCESS);  } -static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output, +static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,  					  u16 outputs)  {  	u8 status; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,  			     sizeof(outputs)); -	status = intel_sdvo_read_response(intel_output, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	return (status == SDVO_CMD_STATUS_SUCCESS);  } -static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output, +static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,  					       int mode)  {  	u8 status, state = SDVO_ENCODER_STATE_ON; @@ -604,24 +605,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output  		break;  	} -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,  			     sizeof(state)); -	status = intel_sdvo_read_response(intel_output, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	return (status == SDVO_CMD_STATUS_SUCCESS);  } -static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output, +static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,  						   int *clock_min,  						   int *clock_max)  {  	struct intel_sdvo_pixel_clock_range clocks;  	u8 status; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,  			     NULL, 0); -	status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks)); +	status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; @@ -633,31 +634,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou  	return true;  } -static bool intel_sdvo_set_target_output(struct intel_output *intel_output, +static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,  					 u16 outputs)  {  	u8 status; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,  			     sizeof(outputs)); -	status = intel_sdvo_read_response(intel_output, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	return (status == SDVO_CMD_STATUS_SUCCESS);  } -static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd, +static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd,  				  struct intel_sdvo_dtd *dtd)  {  	u8 status; -	intel_sdvo_write_cmd(intel_output, cmd, NULL, 0); -	status = intel_sdvo_read_response(intel_output, &dtd->part1, +	intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, &dtd->part1,  					  sizeof(dtd->part1));  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; -	intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0); -	status = intel_sdvo_read_response(intel_output, &dtd->part2, +	intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, &dtd->part2,  					  sizeof(dtd->part2));  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; @@ -665,60 +666,60 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,  	return true;  } -static bool intel_sdvo_get_input_timing(struct intel_output *intel_output, +static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder,  					 struct intel_sdvo_dtd *dtd)  { -	return intel_sdvo_get_timing(intel_output, +	return intel_sdvo_get_timing(intel_encoder,  				     SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);  } -static bool intel_sdvo_get_output_timing(struct intel_output *intel_output, +static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder,  					 struct intel_sdvo_dtd *dtd)  { -	return intel_sdvo_get_timing(intel_output, +	return intel_sdvo_get_timing(intel_encoder,  				     SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);  } -static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd, +static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,  				  struct intel_sdvo_dtd *dtd)  {  	u8 status; -	intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1)); -	status = intel_sdvo_read_response(intel_output, NULL, 0); +	intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1)); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; -	intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2)); -	status = intel_sdvo_read_response(intel_output, NULL, 0); +	intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2)); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false;  	return true;  } -static bool intel_sdvo_set_input_timing(struct intel_output *intel_output, +static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,  					 struct intel_sdvo_dtd *dtd)  { -	return intel_sdvo_set_timing(intel_output, +	return intel_sdvo_set_timing(intel_encoder,  				     SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);  } -static bool intel_sdvo_set_output_timing(struct intel_output *intel_output, +static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,  					 struct intel_sdvo_dtd *dtd)  { -	return intel_sdvo_set_timing(intel_output, +	return intel_sdvo_set_timing(intel_encoder,  				     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);  }  static bool -intel_sdvo_create_preferred_input_timing(struct intel_output *output, +intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,  					 uint16_t clock,  					 uint16_t width,  					 uint16_t height)  {  	struct intel_sdvo_preferred_input_timing_args args; -	struct intel_sdvo_priv *sdvo_priv = output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	uint8_t status;  	memset(&args, 0, sizeof(args)); @@ -732,32 +733,33 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,  	    sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))  		args.scaled = 1; -	intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, +	intel_sdvo_write_cmd(intel_encoder, +			     SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,  			     &args, sizeof(args)); -	status = intel_sdvo_read_response(output, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false;  	return true;  } -static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output, +static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,  						  struct intel_sdvo_dtd *dtd)  {  	bool status; -	intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,  			     NULL, 0); -	status = intel_sdvo_read_response(output, &dtd->part1, +	status = intel_sdvo_read_response(intel_encoder, &dtd->part1,  					  sizeof(dtd->part1));  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; -	intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,  			     NULL, 0); -	status = intel_sdvo_read_response(output, &dtd->part2, +	status = intel_sdvo_read_response(intel_encoder, &dtd->part2,  					  sizeof(dtd->part2));  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; @@ -765,12 +767,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,  	return false;  } -static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) +static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder)  {  	u8 response, status; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); -	status = intel_sdvo_read_response(intel_output, &response, 1); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, &response, 1);  	if (status != SDVO_CMD_STATUS_SUCCESS) {  		DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n"); @@ -782,12 +784,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)  	return response;  } -static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val) +static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)  {  	u8 status; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); -	status = intel_sdvo_read_response(intel_output, NULL, 0); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; @@ -876,13 +878,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,  		mode->flags |= DRM_MODE_FLAG_PVSYNC;  } -static bool intel_sdvo_get_supp_encode(struct intel_output *output, +static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,  				       struct intel_sdvo_encode *encode)  {  	uint8_t status; -	intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); -	status = intel_sdvo_read_response(output, encode, sizeof(*encode)); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));  	if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */  		memset(encode, 0, sizeof(*encode));  		return false; @@ -891,29 +893,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output,  	return true;  } -static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode) +static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, +				  uint8_t mode)  {  	uint8_t status; -	intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1); -	status = intel_sdvo_read_response(output, NULL, 0); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	return (status == SDVO_CMD_STATUS_SUCCESS);  } -static bool intel_sdvo_set_colorimetry(struct intel_output *output, +static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,  				       uint8_t mode)  {  	uint8_t status; -	intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1); -	status = intel_sdvo_read_response(output, NULL, 0); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	return (status == SDVO_CMD_STATUS_SUCCESS);  }  #if 0 -static void intel_sdvo_dump_hdmi_buf(struct intel_output *output) +static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)  {  	int i, j;  	uint8_t set_buf_index[2]; @@ -922,43 +925,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)  	uint8_t buf[48];  	uint8_t *pos; -	intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); -	intel_sdvo_read_response(output, &av_split, 1); +	intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); +	intel_sdvo_read_response(encoder, &av_split, 1);  	for (i = 0; i <= av_split; i++) {  		set_buf_index[0] = i; set_buf_index[1] = 0; -		intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, +		intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,  				     set_buf_index, 2); -		intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0); -		intel_sdvo_read_response(output, &buf_size, 1); +		intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0); +		intel_sdvo_read_response(encoder, &buf_size, 1);  		pos = buf;  		for (j = 0; j <= buf_size; j += 8) { -			intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, +			intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,  					     NULL, 0); -			intel_sdvo_read_response(output, pos, 8); +			intel_sdvo_read_response(encoder, pos, 8);  			pos += 8;  		}  	}  }  #endif -static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index, -				uint8_t *data, int8_t size, uint8_t tx_rate) +static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, +				    int index, +				    uint8_t *data, int8_t size, uint8_t tx_rate)  {      uint8_t set_buf_index[2];      set_buf_index[0] = index;      set_buf_index[1] = 0; -    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); +    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX, +			 set_buf_index, 2);      for (; size > 0; size -= 8) { -	intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);  	data += 8;      } -    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); +    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);  }  static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) @@ -1033,7 +1038,7 @@ struct dip_infoframe {  	} __attribute__ ((packed)) u;  } __attribute__((packed)); -static void intel_sdvo_set_avi_infoframe(struct intel_output *output, +static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,  					 struct drm_display_mode * mode)  {  	struct dip_infoframe avi_if = { @@ -1044,15 +1049,16 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,  	avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,  						    4 + avi_if.len); -	intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len, +	intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, +				4 + avi_if.len,  				SDVO_HBUF_TX_VSYNC);  } -static void intel_sdvo_set_tv_format(struct intel_output *output) +static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)  {  	struct intel_sdvo_tv_format format; -	struct intel_sdvo_priv *sdvo_priv = output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	uint32_t format_map, i;  	uint8_t status; @@ -1065,10 +1071,10 @@ static void intel_sdvo_set_tv_format(struct intel_output *output)  	memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?  			sizeof(format) : sizeof(format_map)); -	intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map,  			     sizeof(format)); -	status = intel_sdvo_read_response(output, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	if (status != SDVO_CMD_STATUS_SUCCESS)  		DRM_DEBUG_KMS("%s: Failed to set TV format\n",  			  SDVO_NAME(sdvo_priv)); @@ -1078,8 +1084,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,  				  struct drm_display_mode *mode,  				  struct drm_display_mode *adjusted_mode)  { -	struct intel_output *output = enc_to_intel_output(encoder); -	struct intel_sdvo_priv *dev_priv = output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv;  	if (dev_priv->is_tv) {  		struct intel_sdvo_dtd output_dtd; @@ -1094,22 +1100,22 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,  		/* Set output timings */  		intel_sdvo_get_dtd_from_mode(&output_dtd, mode); -		intel_sdvo_set_target_output(output, +		intel_sdvo_set_target_output(intel_encoder,  					     dev_priv->controlled_output); -		intel_sdvo_set_output_timing(output, &output_dtd); +		intel_sdvo_set_output_timing(intel_encoder, &output_dtd);  		/* Set the input timing to the screen. Assume always input 0. */ -		intel_sdvo_set_target_input(output, true, false); +		intel_sdvo_set_target_input(intel_encoder, true, false); -		success = intel_sdvo_create_preferred_input_timing(output, +		success = intel_sdvo_create_preferred_input_timing(intel_encoder,  								   mode->clock / 10,  								   mode->hdisplay,  								   mode->vdisplay);  		if (success) {  			struct intel_sdvo_dtd input_dtd; -			intel_sdvo_get_preferred_input_timing(output, +			intel_sdvo_get_preferred_input_timing(intel_encoder,  							     &input_dtd);  			intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);  			dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; @@ -1132,16 +1138,16 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,  		intel_sdvo_get_dtd_from_mode(&output_dtd,  				dev_priv->sdvo_lvds_fixed_mode); -		intel_sdvo_set_target_output(output, +		intel_sdvo_set_target_output(intel_encoder,  					     dev_priv->controlled_output); -		intel_sdvo_set_output_timing(output, &output_dtd); +		intel_sdvo_set_output_timing(intel_encoder, &output_dtd);  		/* Set the input timing to the screen. Assume always input 0. */ -		intel_sdvo_set_target_input(output, true, false); +		intel_sdvo_set_target_input(intel_encoder, true, false);  		success = intel_sdvo_create_preferred_input_timing( -				output, +				intel_encoder,  				mode->clock / 10,  				mode->hdisplay,  				mode->vdisplay); @@ -1149,7 +1155,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,  		if (success) {  			struct intel_sdvo_dtd input_dtd; -			intel_sdvo_get_preferred_input_timing(output, +			intel_sdvo_get_preferred_input_timing(intel_encoder,  							     &input_dtd);  			intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);  			dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; @@ -1181,8 +1187,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_crtc *crtc = encoder->crtc;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -	struct intel_output *output = enc_to_intel_output(encoder); -	struct intel_sdvo_priv *sdvo_priv = output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	u32 sdvox = 0;  	int sdvo_pixel_multiply;  	struct intel_sdvo_in_out_map in_out; @@ -1201,12 +1207,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	in_out.in0 = sdvo_priv->controlled_output;  	in_out.in1 = 0; -	intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,  			     &in_out, sizeof(in_out)); -	status = intel_sdvo_read_response(output, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, NULL, 0);  	if (sdvo_priv->is_hdmi) { -		intel_sdvo_set_avi_infoframe(output, mode); +		intel_sdvo_set_avi_infoframe(intel_encoder, mode);  		sdvox |= SDVO_AUDIO_ENABLE;  	} @@ -1223,16 +1229,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	 */  	if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {  		/* Set the output timing to the screen */ -		intel_sdvo_set_target_output(output, +		intel_sdvo_set_target_output(intel_encoder,  					     sdvo_priv->controlled_output); -		intel_sdvo_set_output_timing(output, &input_dtd); +		intel_sdvo_set_output_timing(intel_encoder, &input_dtd);  	}  	/* Set the input timing to the screen. Assume always input 0. */ -	intel_sdvo_set_target_input(output, true, false); +	intel_sdvo_set_target_input(intel_encoder, true, false);  	if (sdvo_priv->is_tv) -		intel_sdvo_set_tv_format(output); +		intel_sdvo_set_tv_format(intel_encoder);  	/* We would like to use intel_sdvo_create_preferred_input_timing() to  	 * provide the device with a timing it can support, if it supports that @@ -1240,29 +1246,29 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	 * output the preferred timing, and we don't support that currently.  	 */  #if 0 -	success = intel_sdvo_create_preferred_input_timing(output, clock, +	success = intel_sdvo_create_preferred_input_timing(encoder, clock,  							   width, height);  	if (success) {  		struct intel_sdvo_dtd *input_dtd; -		intel_sdvo_get_preferred_input_timing(output, &input_dtd); -		intel_sdvo_set_input_timing(output, &input_dtd); +		intel_sdvo_get_preferred_input_timing(encoder, &input_dtd); +		intel_sdvo_set_input_timing(encoder, &input_dtd);  	}  #else -	intel_sdvo_set_input_timing(output, &input_dtd); +	intel_sdvo_set_input_timing(intel_encoder, &input_dtd);  #endif  	switch (intel_sdvo_get_pixel_multiplier(mode)) {  	case 1: -		intel_sdvo_set_clock_rate_mult(output, +		intel_sdvo_set_clock_rate_mult(intel_encoder,  					       SDVO_CLOCK_RATE_MULT_1X);  		break;  	case 2: -		intel_sdvo_set_clock_rate_mult(output, +		intel_sdvo_set_clock_rate_mult(intel_encoder,  					       SDVO_CLOCK_RATE_MULT_2X);  		break;  	case 4: -		intel_sdvo_set_clock_rate_mult(output, +		intel_sdvo_set_clock_rate_mult(intel_encoder,  					       SDVO_CLOCK_RATE_MULT_4X);  		break;  	} @@ -1273,8 +1279,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  			SDVO_VSYNC_ACTIVE_HIGH |  			SDVO_HSYNC_ACTIVE_HIGH;  	} else { -		sdvox |= I915_READ(sdvo_priv->output_device); -		switch (sdvo_priv->output_device) { +		sdvox |= I915_READ(sdvo_priv->sdvo_reg); +		switch (sdvo_priv->sdvo_reg) {  		case SDVOB:  			sdvox &= SDVOB_PRESERVE_MASK;  			break; @@ -1298,26 +1304,26 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,  	if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)  		sdvox |= SDVO_STALL_SELECT; -	intel_sdvo_write_sdvox(output, sdvox); +	intel_sdvo_write_sdvox(intel_encoder, sdvox);  }  static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)  {  	struct drm_device *dev = encoder->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	u32 temp;  	if (mode != DRM_MODE_DPMS_ON) { -		intel_sdvo_set_active_outputs(intel_output, 0); +		intel_sdvo_set_active_outputs(intel_encoder, 0);  		if (0) -			intel_sdvo_set_encoder_power_state(intel_output, mode); +			intel_sdvo_set_encoder_power_state(intel_encoder, mode);  		if (mode == DRM_MODE_DPMS_OFF) { -			temp = I915_READ(sdvo_priv->output_device); +			temp = I915_READ(sdvo_priv->sdvo_reg);  			if ((temp & SDVO_ENABLE) != 0) { -				intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE); +				intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);  			}  		}  	} else { @@ -1325,13 +1331,13 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)  		int i;  		u8 status; -		temp = I915_READ(sdvo_priv->output_device); +		temp = I915_READ(sdvo_priv->sdvo_reg);  		if ((temp & SDVO_ENABLE) == 0) -			intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE); +			intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);  		for (i = 0; i < 2; i++)  		  intel_wait_for_vblank(dev); -		status = intel_sdvo_get_trained_inputs(intel_output, &input1, +		status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,  						       &input2); @@ -1345,8 +1351,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)  		}  		if (0) -			intel_sdvo_set_encoder_power_state(intel_output, mode); -		intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output); +			intel_sdvo_set_encoder_power_state(intel_encoder, mode); +		intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output);  	}  	return;  } @@ -1355,22 +1361,22 @@ static void intel_sdvo_save(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	int o; -	sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output); -	intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs); +	sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder); +	intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs);  	if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { -		intel_sdvo_set_target_input(intel_output, true, false); -		intel_sdvo_get_input_timing(intel_output, +		intel_sdvo_set_target_input(intel_encoder, true, false); +		intel_sdvo_get_input_timing(intel_encoder,  					    &sdvo_priv->save_input_dtd_1);  	}  	if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { -		intel_sdvo_set_target_input(intel_output, false, true); -		intel_sdvo_get_input_timing(intel_output, +		intel_sdvo_set_target_input(intel_encoder, false, true); +		intel_sdvo_get_input_timing(intel_encoder,  					    &sdvo_priv->save_input_dtd_2);  	} @@ -1379,8 +1385,8 @@ static void intel_sdvo_save(struct drm_connector *connector)  	        u16  this_output = (1 << o);  		if (sdvo_priv->caps.output_flags & this_output)  		{ -			intel_sdvo_set_target_output(intel_output, this_output); -			intel_sdvo_get_output_timing(intel_output, +			intel_sdvo_set_target_output(intel_encoder, this_output); +			intel_sdvo_get_output_timing(intel_encoder,  						     &sdvo_priv->save_output_dtd[o]);  		}  	} @@ -1388,66 +1394,66 @@ static void intel_sdvo_save(struct drm_connector *connector)  		/* XXX: Save TV format/enhancements. */  	} -	sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device); +	sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg);  }  static void intel_sdvo_restore(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	int o;  	int i;  	bool input1, input2;  	u8 status; -	intel_sdvo_set_active_outputs(intel_output, 0); +	intel_sdvo_set_active_outputs(intel_encoder, 0);  	for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)  	{  		u16  this_output = (1 << o);  		if (sdvo_priv->caps.output_flags & this_output) { -			intel_sdvo_set_target_output(intel_output, this_output); -			intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]); +			intel_sdvo_set_target_output(intel_encoder, this_output); +			intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]);  		}  	}  	if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { -		intel_sdvo_set_target_input(intel_output, true, false); -		intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1); +		intel_sdvo_set_target_input(intel_encoder, true, false); +		intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1);  	}  	if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { -		intel_sdvo_set_target_input(intel_output, false, true); -		intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2); +		intel_sdvo_set_target_input(intel_encoder, false, true); +		intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2);  	} -	intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult); +	intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult);  	if (sdvo_priv->is_tv) {  		/* XXX: Restore TV format/enhancements. */  	} -	intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX); +	intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX);  	if (sdvo_priv->save_SDVOX & SDVO_ENABLE)  	{  		for (i = 0; i < 2; i++)  			intel_wait_for_vblank(dev); -		status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2); +		status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2);  		if (status == SDVO_CMD_STATUS_SUCCESS && !input1)  			DRM_DEBUG_KMS("First %s output reported failure to "  					"sync\n", SDVO_NAME(sdvo_priv));  	} -	intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs); +	intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs);  }  static int intel_sdvo_mode_valid(struct drm_connector *connector,  				 struct drm_display_mode *mode)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)  		return MODE_NO_DBLESCAN; @@ -1472,12 +1478,12 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector,  	return MODE_OK;  } -static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps) +static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)  {  	u8 status; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); -	status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps)); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return false; @@ -1487,22 +1493,22 @@ static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struc  struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)  {  	struct drm_connector *connector = NULL; -	struct intel_output *iout = NULL; +	struct intel_encoder *iout = NULL;  	struct intel_sdvo_priv *sdvo;  	/* find the sdvo connector */  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -		iout = to_intel_output(connector); +		iout = to_intel_encoder(connector);  		if (iout->type != INTEL_OUTPUT_SDVO)  			continue;  		sdvo = iout->dev_priv; -		if (sdvo->output_device == SDVOB && sdvoB) +		if (sdvo->sdvo_reg == SDVOB && sdvoB)  			return connector; -		if (sdvo->output_device == SDVOC && !sdvoB) +		if (sdvo->sdvo_reg == SDVOC && !sdvoB)  			return connector;  	} @@ -1514,16 +1520,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)  {  	u8 response[2];  	u8 status; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	DRM_DEBUG_KMS("\n");  	if (!connector)  		return 0; -	intel_output = to_intel_output(connector); +	intel_encoder = to_intel_encoder(connector); -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); -	status = intel_sdvo_read_response(intel_output, &response, 2); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); +	status = intel_sdvo_read_response(intel_encoder, &response, 2);  	if (response[0] !=0)  		return 1; @@ -1535,30 +1541,30 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)  {  	u8 response[2];  	u8 status; -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); -	intel_sdvo_read_response(intel_output, &response, 2); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); +	intel_sdvo_read_response(intel_encoder, &response, 2);  	if (on) { -		intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); -		status = intel_sdvo_read_response(intel_output, &response, 2); +		intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); +		status = intel_sdvo_read_response(intel_encoder, &response, 2); -		intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); +		intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);  	} else {  		response[0] = 0;  		response[1] = 0; -		intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); +		intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);  	} -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); -	intel_sdvo_read_response(intel_output, &response, 2); +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); +	intel_sdvo_read_response(intel_encoder, &response, 2);  }  static bool -intel_sdvo_multifunc_encoder(struct intel_output *intel_output) +intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)  { -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	int caps = 0;  	if (sdvo_priv->caps.output_flags & @@ -1592,11 +1598,11 @@ static struct drm_connector *  intel_find_analog_connector(struct drm_device *dev)  {  	struct drm_connector *connector; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -		intel_output = to_intel_output(connector); -		if (intel_output->type == INTEL_OUTPUT_ANALOG) +		intel_encoder = to_intel_encoder(connector); +		if (intel_encoder->type == INTEL_OUTPUT_ANALOG)  			return connector;  	}  	return NULL; @@ -1621,16 +1627,16 @@ intel_analog_is_connected(struct drm_device *dev)  enum drm_connector_status  intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	enum drm_connector_status status = connector_status_connected;  	struct edid *edid = NULL; -	edid = drm_get_edid(&intel_output->base, -			    intel_output->ddc_bus); +	edid = drm_get_edid(&intel_encoder->base, +			    intel_encoder->ddc_bus);  	/* This is only applied to SDVO cards with multiple outputs */ -	if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) { +	if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {  		uint8_t saved_ddc, temp_ddc;  		saved_ddc = sdvo_priv->ddc_bus;  		temp_ddc = sdvo_priv->ddc_bus >> 1; @@ -1640,8 +1646,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)  		 */  		while(temp_ddc > 1) {  			sdvo_priv->ddc_bus = temp_ddc; -			edid = drm_get_edid(&intel_output->base, -				intel_output->ddc_bus); +			edid = drm_get_edid(&intel_encoder->base, +				intel_encoder->ddc_bus);  			if (edid) {  				/*  				 * When we can get the EDID, maybe it is the @@ -1660,8 +1666,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)  	 */  	if (edid == NULL &&  	    sdvo_priv->analog_ddc_bus && -	    !intel_analog_is_connected(intel_output->base.dev)) -		edid = drm_get_edid(&intel_output->base, +	    !intel_analog_is_connected(intel_encoder->base.dev)) +		edid = drm_get_edid(&intel_encoder->base,  				    sdvo_priv->analog_ddc_bus);  	if (edid != NULL) {  		/* Don't report the output as connected if it's a DVI-I @@ -1676,7 +1682,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)  		}  		kfree(edid); -		intel_output->base.display_info.raw_edid = NULL; +		intel_encoder->base.display_info.raw_edid = NULL;  	} else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))  		status = connector_status_disconnected; @@ -1688,16 +1694,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect  {  	uint16_t response;  	u8 status; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; -	intel_sdvo_write_cmd(intel_output, +	intel_sdvo_write_cmd(intel_encoder,  			     SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);  	if (sdvo_priv->is_tv) {  		/* add 30ms delay when the output type is SDVO-TV */  		mdelay(30);  	} -	status = intel_sdvo_read_response(intel_output, &response, 2); +	status = intel_sdvo_read_response(intel_encoder, &response, 2);  	DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); @@ -1707,10 +1713,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect  	if (response == 0)  		return connector_status_disconnected; -	if (intel_sdvo_multifunc_encoder(intel_output) && +	if (intel_sdvo_multifunc_encoder(intel_encoder) &&  		sdvo_priv->attached_output != response) {  		if (sdvo_priv->controlled_output != response && -			intel_sdvo_output_setup(intel_output, response) != true) +			intel_sdvo_output_setup(intel_encoder, response) != true)  			return connector_status_unknown;  		sdvo_priv->attached_output = response;  	} @@ -1719,12 +1725,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect  static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	int num_modes;  	/* set the bus switch and get the modes */ -	num_modes = intel_ddc_get_modes(intel_output); +	num_modes = intel_ddc_get_modes(intel_encoder);  	/*  	 * Mac mini hack.  On this device, the DVI-I connector shares one DDC @@ -1734,17 +1740,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)  	 */  	if (num_modes == 0 &&  	    sdvo_priv->analog_ddc_bus && -	    !intel_analog_is_connected(intel_output->base.dev)) { +	    !intel_analog_is_connected(intel_encoder->base.dev)) {  		struct i2c_adapter *digital_ddc_bus;  		/* Switch to the analog ddc bus and try that  		 */ -		digital_ddc_bus = intel_output->ddc_bus; -		intel_output->ddc_bus = sdvo_priv->analog_ddc_bus; +		digital_ddc_bus = intel_encoder->ddc_bus; +		intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus; -		(void) intel_ddc_get_modes(intel_output); +		(void) intel_ddc_get_modes(intel_encoder); -		intel_output->ddc_bus = digital_ddc_bus; +		intel_encoder->ddc_bus = digital_ddc_bus;  	}  } @@ -1815,7 +1821,7 @@ struct drm_display_mode sdvo_tv_modes[] = {  static void intel_sdvo_get_tv_modes(struct drm_connector *connector)  { -	struct intel_output *output = to_intel_output(connector); +	struct intel_encoder *output = to_intel_encoder(connector);  	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;  	struct intel_sdvo_sdtv_resolution_request tv_res;  	uint32_t reply = 0, format_map = 0; @@ -1857,9 +1863,9 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)  static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector);  	struct drm_i915_private *dev_priv = connector->dev->dev_private; -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	struct drm_display_mode *newmode;  	/* @@ -1867,7 +1873,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)  	 * Assume that the preferred modes are  	 * arranged in priority order.  	 */ -	intel_ddc_get_modes(intel_output); +	intel_ddc_get_modes(intel_encoder);  	if (list_empty(&connector->probed_modes) == false)  		goto end; @@ -1896,7 +1902,7 @@ end:  static int intel_sdvo_get_modes(struct drm_connector *connector)  { -	struct intel_output *output = to_intel_output(connector); +	struct intel_encoder *output = to_intel_encoder(connector);  	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;  	if (sdvo_priv->is_tv) @@ -1914,8 +1920,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)  static  void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	struct drm_device *dev = connector->dev;  	if (sdvo_priv->is_tv) { @@ -1952,13 +1958,13 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)  static void intel_sdvo_destroy(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; -	if (intel_output->i2c_bus) -		intel_i2c_destroy(intel_output->i2c_bus); -	if (intel_output->ddc_bus) -		intel_i2c_destroy(intel_output->ddc_bus); +	if (intel_encoder->i2c_bus) +		intel_i2c_destroy(intel_encoder->i2c_bus); +	if (intel_encoder->ddc_bus) +		intel_i2c_destroy(intel_encoder->ddc_bus);  	if (sdvo_priv->analog_ddc_bus)  		intel_i2c_destroy(sdvo_priv->analog_ddc_bus); @@ -1976,7 +1982,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector)  	drm_sysfs_connector_remove(connector);  	drm_connector_cleanup(connector); -	kfree(intel_output); +	kfree(intel_encoder);  }  static int @@ -1984,9 +1990,9 @@ intel_sdvo_set_property(struct drm_connector *connector,  			struct drm_property *property,  			uint64_t val)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; -	struct drm_encoder *encoder = &intel_output->enc; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; +	struct drm_encoder *encoder = &intel_encoder->enc;  	struct drm_crtc *crtc = encoder->crtc;  	int ret = 0;  	bool changed = false; @@ -2094,8 +2100,8 @@ intel_sdvo_set_property(struct drm_connector *connector,  			sdvo_priv->cur_brightness = temp_value;  		}  		if (cmd) { -			intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2); -			status = intel_sdvo_read_response(intel_output, +			intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); +			status = intel_sdvo_read_response(intel_encoder,  								NULL, 0);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO command \n"); @@ -2190,7 +2196,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)  }  static bool -intel_sdvo_get_digital_encoding_mode(struct intel_output *output) +intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output)  {  	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;  	uint8_t status; @@ -2204,42 +2210,42 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output)  	return true;  } -static struct intel_output * -intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) +static struct intel_encoder * +intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan)  {  	struct drm_device *dev = chan->drm_dev;  	struct drm_connector *connector; -	struct intel_output *intel_output = NULL; +	struct intel_encoder *intel_encoder = NULL;  	list_for_each_entry(connector,  			&dev->mode_config.connector_list, head) { -		if (to_intel_output(connector)->ddc_bus == &chan->adapter) { -			intel_output = to_intel_output(connector); +		if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) { +			intel_encoder = to_intel_encoder(connector);  			break;  		}  	} -	return intel_output; +	return intel_encoder;  }  static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,  				  struct i2c_msg msgs[], int num)  { -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct intel_sdvo_priv *sdvo_priv;  	struct i2c_algo_bit_data *algo_data;  	const struct i2c_algorithm *algo;  	algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; -	intel_output = -		intel_sdvo_chan_to_intel_output( +	intel_encoder = +		intel_sdvo_chan_to_intel_encoder(  				(struct intel_i2c_chan *)(algo_data->data)); -	if (intel_output == NULL) +	if (intel_encoder == NULL)  		return -EINVAL; -	sdvo_priv = intel_output->dev_priv; -	algo = intel_output->i2c_bus->algo; +	sdvo_priv = intel_encoder->dev_priv; +	algo = intel_encoder->i2c_bus->algo; -	intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); +	intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus);  	return algo->master_xfer(i2c_adap, msgs, num);  } @@ -2248,12 +2254,12 @@ static struct i2c_algorithm intel_sdvo_i2c_bit_algo = {  };  static u8 -intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) +intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct sdvo_device_mapping *my_mapping, *other_mapping; -	if (output_device == SDVOB) { +	if (sdvo_reg == SDVOB) {  		my_mapping = &dev_priv->sdvo_mappings[0];  		other_mapping = &dev_priv->sdvo_mappings[1];  	} else { @@ -2278,7 +2284,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)  	/* No SDVO device info is found for another DVO port,  	 * so use mapping assumption we had before BIOS parsing.  	 */ -	if (output_device == SDVOB) +	if (sdvo_reg == SDVOB)  		return 0x70;  	else  		return 0x72; @@ -2304,15 +2310,15 @@ static struct dmi_system_id intel_sdvo_bad_tv[] = {  };  static bool -intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) +intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)  { -	struct drm_connector *connector = &intel_output->base; -	struct drm_encoder *encoder = &intel_output->enc; -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct drm_connector *connector = &intel_encoder->base; +	struct drm_encoder *encoder = &intel_encoder->enc; +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	bool ret = true, registered = false;  	sdvo_priv->is_tv = false; -	intel_output->needs_tv_clock = false; +	intel_encoder->needs_tv_clock = false;  	sdvo_priv->is_lvds = false;  	if (device_is_registered(&connector->kdev)) { @@ -2330,16 +2336,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)  		encoder->encoder_type = DRM_MODE_ENCODER_TMDS;  		connector->connector_type = DRM_MODE_CONNECTOR_DVID; -		if (intel_sdvo_get_supp_encode(intel_output, +		if (intel_sdvo_get_supp_encode(intel_encoder,  					       &sdvo_priv->encode) && -		    intel_sdvo_get_digital_encoding_mode(intel_output) && +		    intel_sdvo_get_digital_encoding_mode(intel_encoder) &&  		    sdvo_priv->is_hdmi) {  			/* enable hdmi encoding mode if supported */ -			intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); -			intel_sdvo_set_colorimetry(intel_output, +			intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); +			intel_sdvo_set_colorimetry(intel_encoder,  						   SDVO_COLORIMETRY_RGB256);  			connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; -			intel_output->clone_mask = +			intel_encoder->clone_mask =  					(1 << INTEL_SDVO_NON_TV_CLONE_BIT) |  					(1 << INTEL_ANALOG_CLONE_BIT);  		} @@ -2350,21 +2356,21 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)  		encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;  		connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;  		sdvo_priv->is_tv = true; -		intel_output->needs_tv_clock = true; -		intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; +		intel_encoder->needs_tv_clock = true; +		intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;  	} else if (flags & SDVO_OUTPUT_RGB0) {  		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;  		encoder->encoder_type = DRM_MODE_ENCODER_DAC;  		connector->connector_type = DRM_MODE_CONNECTOR_VGA; -		intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | +		intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |  					(1 << INTEL_ANALOG_CLONE_BIT);  	} else if (flags & SDVO_OUTPUT_RGB1) {  		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;  		encoder->encoder_type = DRM_MODE_ENCODER_DAC;  		connector->connector_type = DRM_MODE_CONNECTOR_VGA; -		intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | +		intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |  					(1 << INTEL_ANALOG_CLONE_BIT);  	} else if (flags & SDVO_OUTPUT_CVBS0) { @@ -2372,15 +2378,15 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)  		encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;  		connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;  		sdvo_priv->is_tv = true; -		intel_output->needs_tv_clock = true; -		intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; +		intel_encoder->needs_tv_clock = true; +		intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;  	} else if (flags & SDVO_OUTPUT_LVDS0) {  		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;  		encoder->encoder_type = DRM_MODE_ENCODER_LVDS;  		connector->connector_type = DRM_MODE_CONNECTOR_LVDS;  		sdvo_priv->is_lvds = true; -		intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | +		intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |  					(1 << INTEL_SDVO_LVDS_CLONE_BIT);  	} else if (flags & SDVO_OUTPUT_LVDS1) { @@ -2388,7 +2394,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)  		encoder->encoder_type = DRM_MODE_ENCODER_LVDS;  		connector->connector_type = DRM_MODE_CONNECTOR_LVDS;  		sdvo_priv->is_lvds = true; -		intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | +		intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |  					(1 << INTEL_SDVO_LVDS_CLONE_BIT);  	} else { @@ -2401,7 +2407,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)  			      bytes[0], bytes[1]);  		ret = false;  	} -	intel_output->crtc_mask = (1 << 0) | (1 << 1); +	intel_encoder->crtc_mask = (1 << 0) | (1 << 1);  	if (ret && registered)  		ret = drm_sysfs_connector_add(connector) == 0 ? true : false; @@ -2413,18 +2419,18 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)  static void intel_sdvo_tv_create_property(struct drm_connector *connector)  { -      struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +      struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	struct intel_sdvo_tv_format format;  	uint32_t format_map, i;  	uint8_t status; -	intel_sdvo_set_target_output(intel_output, +	intel_sdvo_set_target_output(intel_encoder,  				     sdvo_priv->controlled_output); -	intel_sdvo_write_cmd(intel_output, +	intel_sdvo_write_cmd(intel_encoder,  			     SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); -	status = intel_sdvo_read_response(intel_output, +	status = intel_sdvo_read_response(intel_encoder,  					  &format, sizeof(format));  	if (status != SDVO_CMD_STATUS_SUCCESS)  		return; @@ -2462,16 +2468,16 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector)  static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;  	struct intel_sdvo_enhancements_reply sdvo_data;  	struct drm_device *dev = connector->dev;  	uint8_t status;  	uint16_t response, data_value[2]; -	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, +	intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,  						NULL, 0); -	status = intel_sdvo_read_response(intel_output, &sdvo_data, +	status = intel_sdvo_read_response(intel_encoder, &sdvo_data,  					sizeof(sdvo_data));  	if (status != SDVO_CMD_STATUS_SUCCESS) {  		DRM_DEBUG_KMS(" incorrect response is returned\n"); @@ -2487,18 +2493,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  		 * property  		 */  		if (sdvo_data.overscan_h) { -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&data_value, 4);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO max "  						"h_overscan\n");  				return;  			} -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_OVERSCAN_H, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&response, 2);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); @@ -2528,18 +2534,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  					data_value[0], data_value[1], response);  		}  		if (sdvo_data.overscan_v) { -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&data_value, 4);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO max "  						"v_overscan\n");  				return;  			} -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_OVERSCAN_V, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&response, 2);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); @@ -2569,17 +2575,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  					data_value[0], data_value[1], response);  		}  		if (sdvo_data.position_h) { -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&data_value, 4);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");  				return;  			} -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_POSITION_H, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&response, 2);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); @@ -2600,17 +2606,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  					data_value[0], data_value[1], response);  		}  		if (sdvo_data.position_v) { -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&data_value, 4);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");  				return;  			} -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_POSITION_V, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&response, 2);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); @@ -2633,17 +2639,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  	}  	if (sdvo_priv->is_tv) {  		if (sdvo_data.saturation) { -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_MAX_SATURATION, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&data_value, 4);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");  				return;  			} -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_SATURATION, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&response, 2);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); @@ -2665,17 +2671,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  					data_value[0], data_value[1], response);  		}  		if (sdvo_data.contrast) { -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&data_value, 4);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");  				return;  			} -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_CONTRAST, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&response, 2);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); @@ -2696,17 +2702,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  					data_value[0], data_value[1], response);  		}  		if (sdvo_data.hue) { -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_MAX_HUE, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&data_value, 4);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");  				return;  			} -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_HUE, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&response, 2);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); @@ -2729,17 +2735,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  	}  	if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {  		if (sdvo_data.brightness) { -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&data_value, 4);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");  				return;  			} -			intel_sdvo_write_cmd(intel_output, +			intel_sdvo_write_cmd(intel_encoder,  				SDVO_CMD_GET_BRIGHTNESS, NULL, 0); -			status = intel_sdvo_read_response(intel_output, +			status = intel_sdvo_read_response(intel_encoder,  				&response, 2);  			if (status != SDVO_CMD_STATUS_SUCCESS) {  				DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); @@ -2764,81 +2770,81 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)  	return;  } -bool intel_sdvo_init(struct drm_device *dev, int output_device) +bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_connector *connector; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct intel_sdvo_priv *sdvo_priv;  	u8 ch[0x40];  	int i; -	intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); -	if (!intel_output) { +	intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); +	if (!intel_encoder) {  		return false;  	} -	sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); -	sdvo_priv->output_device = output_device; +	sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); +	sdvo_priv->sdvo_reg = sdvo_reg; -	intel_output->dev_priv = sdvo_priv; -	intel_output->type = INTEL_OUTPUT_SDVO; +	intel_encoder->dev_priv = sdvo_priv; +	intel_encoder->type = INTEL_OUTPUT_SDVO;  	/* setup the DDC bus. */ -	if (output_device == SDVOB) -		intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); +	if (sdvo_reg == SDVOB) +		intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");  	else -		intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); +		intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); -	if (!intel_output->i2c_bus) +	if (!intel_encoder->i2c_bus)  		goto err_inteloutput; -	sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); +	sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);  	/* Save the bit-banging i2c functionality for use by the DDC wrapper */ -	intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; +	intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;  	/* Read the regs to test if we can talk to the device */  	for (i = 0; i < 0x40; i++) { -		if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { +		if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {  			DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", -					output_device == SDVOB ? 'B' : 'C'); +					sdvo_reg == SDVOB ? 'B' : 'C');  			goto err_i2c;  		}  	}  	/* setup the DDC bus. */ -	if (output_device == SDVOB) { -		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); +	if (sdvo_reg == SDVOB) { +		intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");  		sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,  						"SDVOB/VGA DDC BUS");  		dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;  	} else { -		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); +		intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");  		sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,  						"SDVOC/VGA DDC BUS");  		dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;  	} -	if (intel_output->ddc_bus == NULL) +	if (intel_encoder->ddc_bus == NULL)  		goto err_i2c;  	/* Wrap with our custom algo which switches to DDC mode */ -	intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; +	intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;  	/* In default case sdvo lvds is false */ -	intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); +	intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); -	if (intel_sdvo_output_setup(intel_output, +	if (intel_sdvo_output_setup(intel_encoder,  				    sdvo_priv->caps.output_flags) != true) {  		DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", -			  output_device == SDVOB ? 'B' : 'C'); +			  sdvo_reg == SDVOB ? 'B' : 'C');  		goto err_i2c;  	} -	connector = &intel_output->base; +	connector = &intel_encoder->base;  	drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,  			   connector->connector_type); @@ -2847,12 +2853,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)  	connector->doublescan_allowed = 0;  	connector->display_info.subpixel_order = SubPixelHorizontalRGB; -	drm_encoder_init(dev, &intel_output->enc, -			&intel_sdvo_enc_funcs, intel_output->enc.encoder_type); +	drm_encoder_init(dev, &intel_encoder->enc, +			&intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type); -	drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); +	drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); -	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); +	drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);  	if (sdvo_priv->is_tv)  		intel_sdvo_tv_create_property(connector); @@ -2864,9 +2870,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)  	intel_sdvo_select_ddc_bus(sdvo_priv);  	/* Set the input timing to the screen. Assume always input 0. */ -	intel_sdvo_set_target_input(intel_output, true, false); +	intel_sdvo_set_target_input(intel_encoder, true, false); -	intel_sdvo_get_input_pixel_clock_range(intel_output, +	intel_sdvo_get_input_pixel_clock_range(intel_encoder,  					       &sdvo_priv->pixel_clock_min,  					       &sdvo_priv->pixel_clock_max); @@ -2893,12 +2899,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)  err_i2c:  	if (sdvo_priv->analog_ddc_bus != NULL)  		intel_i2c_destroy(sdvo_priv->analog_ddc_bus); -	if (intel_output->ddc_bus != NULL) -		intel_i2c_destroy(intel_output->ddc_bus); -	if (intel_output->i2c_bus != NULL) -		intel_i2c_destroy(intel_output->i2c_bus); +	if (intel_encoder->ddc_bus != NULL) +		intel_i2c_destroy(intel_encoder->ddc_bus); +	if (intel_encoder->i2c_bus != NULL) +		intel_i2c_destroy(intel_encoder->i2c_bus);  err_inteloutput: -	kfree(intel_output); +	kfree(intel_encoder);  	return false;  } diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 552ec110b74..d7d39b2327d 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_tv_priv *tv_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;  	int i;  	tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1); @@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *connector)  {  	struct drm_device *dev = connector->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_tv_priv *tv_priv = intel_output->dev_priv; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;  	struct drm_crtc *crtc = connector->encoder->crtc;  	struct intel_crtc *intel_crtc;  	int i; @@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format)  }  static const struct tv_mode * -intel_tv_mode_find (struct intel_output *intel_output) +intel_tv_mode_find (struct intel_encoder *intel_encoder)  { -	struct intel_tv_priv *tv_priv = intel_output->dev_priv; +	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;  	return intel_tv_mode_lookup(tv_priv->tv_format);  } @@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output *intel_output)  static enum drm_mode_status  intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)  { -	struct intel_output *intel_output = to_intel_output(connector); -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);  	/* Ensure TV refresh is close to desired refresh */  	if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) @@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,  {  	struct drm_device *dev = encoder->dev;  	struct drm_mode_config *drm_config = &dev->mode_config; -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output); +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);  	struct drm_encoder *other_encoder;  	if (!tv_mode) @@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_crtc *crtc = encoder->crtc;  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -	struct intel_output *intel_output = enc_to_intel_output(encoder); -	struct intel_tv_priv *tv_priv = intel_output->dev_priv; -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); +	struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); +	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; +	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);  	u32 tv_ctl;  	u32 hctl1, hctl2, hctl3;  	u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; @@ -1360,9 +1360,9 @@ static const struct drm_display_mode reported_modes[] = {   * \return false if TV is disconnected.   */  static int -intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) +intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)  { -	struct drm_encoder *encoder = &intel_output->enc; +	struct drm_encoder *encoder = &intel_encoder->enc;  	struct drm_device *dev = encoder->dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	unsigned long irqflags; @@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)   */  static void intel_tv_find_better_format(struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_tv_priv *tv_priv = intel_output->dev_priv; -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; +	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);  	int i;  	if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == @@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *connector)  {  	struct drm_crtc *crtc;  	struct drm_display_mode mode; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_tv_priv *tv_priv = intel_output->dev_priv; -	struct drm_encoder *encoder = &intel_output->enc; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; +	struct drm_encoder *encoder = &intel_encoder->enc;  	int dpms_mode;  	int type = tv_priv->type; @@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *connector)  	drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);  	if (encoder->crtc && encoder->crtc->enabled) { -		type = intel_tv_detect_type(encoder->crtc, intel_output); +		type = intel_tv_detect_type(encoder->crtc, intel_encoder);  	} else { -		crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode); +		crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode);  		if (crtc) { -			type = intel_tv_detect_type(crtc, intel_output); -			intel_release_load_detect_pipe(intel_output, dpms_mode); +			type = intel_tv_detect_type(crtc, intel_encoder); +			intel_release_load_detect_pipe(intel_encoder, dpms_mode);  		} else  			type = -1;  	} @@ -1525,8 +1525,8 @@ static void  intel_tv_chose_preferred_modes(struct drm_connector *connector,  			       struct drm_display_mode *mode_ptr)  { -	struct intel_output *intel_output = to_intel_output(connector); -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);  	if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)  		mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; @@ -1550,8 +1550,8 @@ static int  intel_tv_get_modes(struct drm_connector *connector)  {  	struct drm_display_mode *mode_ptr; -	struct intel_output *intel_output = to_intel_output(connector); -	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);  	int j, count = 0;  	u64 tmp; @@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector *connector)  static void  intel_tv_destroy (struct drm_connector *connector)  { -	struct intel_output *intel_output = to_intel_output(connector); +	struct intel_encoder *intel_encoder = to_intel_encoder(connector);  	drm_sysfs_connector_remove(connector);  	drm_connector_cleanup(connector); -	kfree(intel_output); +	kfree(intel_encoder);  } @@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop  		      uint64_t val)  {  	struct drm_device *dev = connector->dev; -	struct intel_output *intel_output = to_intel_output(connector); -	struct intel_tv_priv *tv_priv = intel_output->dev_priv; -	struct drm_encoder *encoder = &intel_output->enc; +	struct intel_encoder *intel_encoder = to_intel_encoder(connector); +	struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; +	struct drm_encoder *encoder = &intel_encoder->enc;  	struct drm_crtc *crtc = encoder->crtc;  	int ret = 0;  	bool changed = false; @@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_connector *connector; -	struct intel_output *intel_output; +	struct intel_encoder *intel_encoder;  	struct intel_tv_priv *tv_priv;  	u32 tv_dac_on, tv_dac_off, save_tv_dac;  	char **tv_format_names; @@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev)  	    (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)  		return; -	intel_output = kzalloc(sizeof(struct intel_output) + +	intel_encoder = kzalloc(sizeof(struct intel_encoder) +  			       sizeof(struct intel_tv_priv), GFP_KERNEL); -	if (!intel_output) { +	if (!intel_encoder) {  		return;  	} -	connector = &intel_output->base; +	connector = &intel_encoder->base;  	drm_connector_init(dev, connector, &intel_tv_connector_funcs,  			   DRM_MODE_CONNECTOR_SVIDEO); -	drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs, +	drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs,  			 DRM_MODE_ENCODER_TVDAC); -	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); -	tv_priv = (struct intel_tv_priv *)(intel_output + 1); -	intel_output->type = INTEL_OUTPUT_TVOUT; -	intel_output->crtc_mask = (1 << 0) | (1 << 1); -	intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); -	intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); -	intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); -	intel_output->dev_priv = tv_priv; +	drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc); +	tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); +	intel_encoder->type = INTEL_OUTPUT_TVOUT; +	intel_encoder->crtc_mask = (1 << 0) | (1 << 1); +	intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); +	intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); +	intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); +	intel_encoder->dev_priv = tv_priv;  	tv_priv->type = DRM_MODE_CONNECTOR_Unknown;  	/* BIOS margin values */ @@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev)  	tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); -	drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs); +	drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);  	drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);  	connector->interlace_allowed = false;  	connector->doublescan_allowed = false; diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 32db806f3b5..453df3f6053 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -12,7 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \               nouveau_dp.o nouveau_grctx.o \               nv04_timer.o \               nv04_mc.o nv40_mc.o nv50_mc.o \ -             nv04_fb.o nv10_fb.o nv40_fb.o \ +             nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \               nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \               nv04_graph.o nv10_graph.o nv20_graph.o \               nv40_graph.o nv50_graph.o \ @@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \               nv50_cursor.o nv50_display.o nv50_fbcon.o \               nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \               nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ -             nv17_gpio.o +             nv17_gpio.o nv50_gpio.o  nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o  nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 0e0730a5313..e13f6af0037 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -1,5 +1,6 @@  #include <linux/pci.h>  #include <linux/acpi.h> +#include <linux/slab.h>  #include <acpi/acpi_drivers.h>  #include <acpi/acpi_bus.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 20564f8cb0e..406228f4a2a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -89,19 +89,21 @@ static struct backlight_ops nv50_bl_ops = {  static int nouveau_nv40_backlight_init(struct drm_device *dev)  { +	struct backlight_properties props;  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct backlight_device *bd;  	if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))  		return 0; +	memset(&props, 0, sizeof(struct backlight_properties)); +	props.max_brightness = 31;  	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, -				       &nv40_bl_ops); +				       &nv40_bl_ops, &props);  	if (IS_ERR(bd))  		return PTR_ERR(bd);  	dev_priv->backlight = bd; -	bd->props.max_brightness = 31;  	bd->props.brightness = nv40_get_intensity(bd);  	backlight_update_status(bd); @@ -110,19 +112,21 @@ static int nouveau_nv40_backlight_init(struct drm_device *dev)  static int nouveau_nv50_backlight_init(struct drm_device *dev)  { +	struct backlight_properties props;  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct backlight_device *bd;  	if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))  		return 0; +	memset(&props, 0, sizeof(struct backlight_properties)); +	props.max_brightness = 1025;  	bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev, -				       &nv50_bl_ops); +				       &nv50_bl_ops, &props);  	if (IS_ERR(bd))  		return PTR_ERR(bd);  	dev_priv->backlight = bd; -	bd->props.max_brightness = 1025;  	bd->props.brightness = nv50_get_intensity(bd);  	backlight_update_status(bd);  	return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 71247da17da..abc382a9918 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -2573,48 +2573,34 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)  	 * each GPIO according to various values listed in each entry  	 */ -	const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; +	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;  	const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; -	const uint8_t *gpio_table = &bios->data[bios->dcb.gpio_table_ptr]; -	const uint8_t *gpio_entry;  	int i; -	if (!iexec->execute) -		return 1; - -	if (bios->dcb.version != 0x40) { -		NV_ERROR(bios->dev, "DCB table not version 4.0\n"); -		return 0; +	if (dev_priv->card_type != NV_50) { +		NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n"); +		return -ENODEV;  	} -	if (!bios->dcb.gpio_table_ptr) { -		NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n"); -		return 0; -	} +	if (!iexec->execute) +		return 1; -	gpio_entry = gpio_table + gpio_table[1]; -	for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) { -		uint32_t entry = ROM32(gpio_entry[0]), r, s, v; -		int line = (entry & 0x0000001f); +	for (i = 0; i < bios->dcb.gpio.entries; i++) { +		struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i]; +		uint32_t r, s, v; -		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry); +		BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); -		if ((entry & 0x0000ff00) == 0x0000ff00) -			continue; +		nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default); -		r = nv50_gpio_reg[line >> 3]; -		s = (line & 0x07) << 2; -		v = bios_rd32(bios, r) & ~(0x00000003 << s); -		if (entry & 0x01000000) -			v |= (((entry & 0x60000000) >> 29) ^ 2) << s; -		else -			v |= (((entry & 0x18000000) >> 27) ^ 2) << s; -		bios_wr32(bios, r, v); - -		r = nv50_gpio_ctl[line >> 4]; -		s = (line & 0x0f); +		/* The NVIDIA binary driver doesn't appear to actually do +		 * any of this, my VBIOS does however. +		 */ +		/* Not a clue, needs de-magicing */ +		r = nv50_gpio_ctl[gpio->line >> 4]; +		s = (gpio->line & 0x0f);  		v = bios_rd32(bios, r) & ~(0x00010001 << s); -		switch ((entry & 0x06000000) >> 25) { +		switch ((gpio->entry & 0x06000000) >> 25) {  		case 1:  			v |= (0x00000001 << s);  			break; @@ -3198,7 +3184,6 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int  	struct nvbios *bios = &dev_priv->vbios;  	unsigned int outputset = (dcbent->or == 4) ? 1 : 0;  	uint16_t scriptptr = 0, clktable; -	uint8_t clktableptr = 0;  	/*  	 * For now we assume version 3.0 table - g80 support will need some @@ -3217,26 +3202,29 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int  		scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);  		break;  	case LVDS_RESET: +		clktable = bios->fp.lvdsmanufacturerpointer + 15; +		if (dcbent->or == 4) +			clktable += 8; +  		if (dcbent->lvdsconf.use_straps_for_mode) {  			if (bios->fp.dual_link) -				clktableptr += 2; -			if (bios->fp.BITbit1) -				clktableptr++; +				clktable += 4; +			if (bios->fp.if_is_24bit) +				clktable += 2;  		} else {  			/* using EDID */ -			uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4]; -			int fallbackcmpval = (dcbent->or == 4) ? 4 : 1; +			int cmpval_24bit = (dcbent->or == 4) ? 4 : 1;  			if (bios->fp.dual_link) { -				clktableptr += 2; -				fallbackcmpval *= 2; +				clktable += 4; +				cmpval_24bit <<= 1;  			} -			if (fallbackcmpval & fallback) -				clktableptr++; + +			if (bios->fp.strapless_is_24bit & cmpval_24bit) +				clktable += 2;  		} -		/* adding outputset * 8 may not be correct */ -		clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]); +		clktable = ROM16(bios->data[clktable]);  		if (!clktable) {  			NV_ERROR(dev, "Pixel clock comparison table not found\n");  			return -ENOENT; @@ -3545,7 +3533,7 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b  	 * at which modes should be set up in the dual link style.  	 *  	 * Following the header, the BMP (ver 0xa) table has several records, -	 * indexed by a seperate xlat table, indexed in turn by the fp strap in +	 * indexed by a separate xlat table, indexed in turn by the fp strap in  	 * EXTDEV_BOOT. Each record had a config byte, followed by 6 script  	 * numbers for use by INIT_SUB which controlled panel init and power,  	 * and finally a dword of ms to sleep between power off and on @@ -3638,37 +3626,40 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b  		*if_is_24bit = bios->data[lvdsofs] & 16;  		break;  	case 0x30: -		/* -		 * My money would be on there being a 24 bit interface bit in -		 * this table, but I have no example of a laptop bios with a -		 * 24 bit panel to confirm that. Hence we shout loudly if any -		 * bit other than bit 0 is set (I've not even seen bit 1) -		 */ -		if (bios->data[lvdsofs] > 1) -			NV_ERROR(dev, -				 "You have a very unusual laptop display; please report it\n"); +	case 0x40:  		/*  		 * No sign of the "power off for reset" or "reset for panel  		 * on" bits, but it's safer to assume we should  		 */  		bios->fp.power_off_for_reset = true;  		bios->fp.reset_after_pclk_change = true; +  		/*  		 * It's ok lvdsofs is wrong for nv4x edid case; dual_link is -		 * over-written, and BITbit1 isn't used +		 * over-written, and if_is_24bit isn't used  		 */  		bios->fp.dual_link = bios->data[lvdsofs] & 1; -		bios->fp.BITbit1 = bios->data[lvdsofs] & 2; -		bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10; -		break; -	case 0x40: -		bios->fp.dual_link = bios->data[lvdsofs] & 1;  		bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;  		bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];  		bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;  		break;  	} +	/* Dell Latitude D620 reports a too-high value for the dual-link +	 * transition freq, causing us to program the panel incorrectly. +	 * +	 * It doesn't appear the VBIOS actually uses its transition freq +	 * (90000kHz), instead it uses the "Number of LVDS channels" field +	 * out of the panel ID structure (http://www.spwg.org/). +	 * +	 * For the moment, a quirk will do :) +	 */ +	if ((dev->pdev->device == 0x01d7) && +	    (dev->pdev->subsystem_vendor == 0x1028) && +	    (dev->pdev->subsystem_device == 0x01c2)) { +		bios->fp.duallink_transition_clk = 80000; +	} +  	/* set dual_link flag for EDID case */  	if (pxclk && (chip_version < 0x25 || chip_version > 0x28))  		bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk); @@ -5077,25 +5068,25 @@ parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)  	gpio->tag = tag;  	gpio->line = line;  	gpio->invert = flags != 4; +	gpio->entry = ent;  }  static void  parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)  { +	uint32_t entry = ROM32(bios->data[offset]);  	struct dcb_gpio_entry *gpio; -	uint32_t ent = ROM32(bios->data[offset]); -	uint8_t line = ent & 0x1f, -		tag = ent >> 8 & 0xff; -	if (tag == 0xff) +	if ((entry & 0x0000ff00) == 0x0000ff00)  		return;  	gpio = new_gpio_entry(bios); - -	/* Currently unused, we may need more fields parsed at some -	 * point. */ -	gpio->tag = tag; -	gpio->line = line; +	gpio->tag = (entry & 0x0000ff00) >> 8; +	gpio->line = (entry & 0x0000001f) >> 0; +	gpio->state_default = (entry & 0x01000000) >> 24; +	gpio->state[0] = (entry & 0x18000000) >> 27; +	gpio->state[1] = (entry & 0x60000000) >> 29; +	gpio->entry = entry;  }  static void @@ -5211,6 +5202,21 @@ divine_connector_type(struct nvbios *bios, int index)  }  static void +apply_dcb_connector_quirks(struct nvbios *bios, int idx) +{ +	struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[idx]; +	struct drm_device *dev = bios->dev; + +	/* Gigabyte NX85T */ +	if ((dev->pdev->device == 0x0421) && +	    (dev->pdev->subsystem_vendor == 0x1458) && +	    (dev->pdev->subsystem_device == 0x344c)) { +		if (cte->type == DCB_CONNECTOR_HDMI_1) +			cte->type = DCB_CONNECTOR_DVI_I; +	} +} + +static void  parse_dcb_connector_table(struct nvbios *bios)  {  	struct drm_device *dev = bios->dev; @@ -5238,13 +5244,14 @@ parse_dcb_connector_table(struct nvbios *bios)  	entry = conntab + conntab[1];  	cte = &ct->entry[0];  	for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) { +		cte->index = i;  		if (conntab[3] == 2)  			cte->entry = ROM16(entry[0]);  		else  			cte->entry = ROM32(entry[0]);  		cte->type  = (cte->entry & 0x000000ff) >> 0; -		cte->index = (cte->entry & 0x00000f00) >> 8; +		cte->index2 = (cte->entry & 0x00000f00) >> 8;  		switch (cte->entry & 0x00033000) {  		case 0x00001000:  			cte->gpio_tag = 0x07; @@ -5266,6 +5273,8 @@ parse_dcb_connector_table(struct nvbios *bios)  		if (cte->type == 0xff)  			continue; +		apply_dcb_connector_quirks(bios, i); +  		NV_INFO(dev, "  %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n",  			i, cte->entry, cte->type, cte->index, cte->gpio_tag); @@ -5287,10 +5296,16 @@ parse_dcb_connector_table(struct nvbios *bios)  			break;  		default:  			cte->type = divine_connector_type(bios, cte->index); -			NV_WARN(dev, "unknown type, using 0x%02x", cte->type); +			NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type);  			break;  		} +		if (nouveau_override_conntype) { +			int type = divine_connector_type(bios, cte->index); +			if (type != cte->type) +				NV_WARN(dev, " -> type 0x%02x\n", cte->type); +		} +  	}  } diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 9f688aa9a65..c0d7b0a3ece 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -49,6 +49,9 @@ struct dcb_gpio_entry {  	enum dcb_gpio_tag tag;  	int line;  	bool invert; +	uint32_t entry; +	uint8_t state_default; +	uint8_t state[2];  };  struct dcb_gpio_table { @@ -72,9 +75,10 @@ enum dcb_connector_type {  };  struct dcb_connector_table_entry { +	uint8_t index;  	uint32_t entry;  	enum dcb_connector_type type; -	uint8_t index; +	uint8_t index2;  	uint8_t gpio_tag;  }; @@ -266,7 +270,6 @@ struct nvbios {  		bool reset_after_pclk_change;  		bool dual_link;  		bool link_c_increment; -		bool BITbit1;  		bool if_is_24bit;  		int duallink_transition_clk;  		uint8_t strapless_is_24bit; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 028719fddf7..957d1762984 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -34,6 +34,7 @@  #include "nouveau_dma.h"  #include <linux/log2.h> +#include <linux/slab.h>  static void  nouveau_bo_del_ttm(struct ttm_buffer_object *bo) @@ -71,7 +72,7 @@ nouveau_bo_fixup_align(struct drm_device *dev,  	 * many small buffers.  	 */  	if (dev_priv->card_type == NV_50) { -		uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15; +		uint32_t block_size = dev_priv->vram_size >> 15;  		int i;  		switch (tile_flags) { @@ -153,7 +154,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,  	nvbo->placement.fpfn = 0;  	nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; -	nouveau_bo_placement_set(nvbo, flags); +	nouveau_bo_placement_set(nvbo, flags, 0);  	nvbo->channel = chan;  	ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, @@ -172,26 +173,33 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,  	return 0;  } +static void +set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags) +{ +	*n = 0; + +	if (type & TTM_PL_FLAG_VRAM) +		pl[(*n)++] = TTM_PL_FLAG_VRAM | flags; +	if (type & TTM_PL_FLAG_TT) +		pl[(*n)++] = TTM_PL_FLAG_TT | flags; +	if (type & TTM_PL_FLAG_SYSTEM) +		pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags; +} +  void -nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype) +nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)  { -	int n = 0; +	struct ttm_placement *pl = &nvbo->placement; +	uint32_t flags = TTM_PL_MASK_CACHING | +		(nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0); -	if (memtype & TTM_PL_FLAG_VRAM) -		nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING; -	if (memtype & TTM_PL_FLAG_TT) -		nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; -	if (memtype & TTM_PL_FLAG_SYSTEM) -		nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING; -	nvbo->placement.placement = nvbo->placements; -	nvbo->placement.busy_placement = nvbo->placements; -	nvbo->placement.num_placement = n; -	nvbo->placement.num_busy_placement = n; +	pl->placement = nvbo->placements; +	set_placement_list(nvbo->placements, &pl->num_placement, +			   type, flags); -	if (nvbo->pin_refcnt) { -		while (n--) -			nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT; -	} +	pl->busy_placement = nvbo->busy_placements; +	set_placement_list(nvbo->busy_placements, &pl->num_busy_placement, +			   type | busy, flags);  }  int @@ -199,7 +207,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)  {  	struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);  	struct ttm_buffer_object *bo = &nvbo->bo; -	int ret, i; +	int ret;  	if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {  		NV_ERROR(nouveau_bdev(bo->bdev)->dev, @@ -215,9 +223,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)  	if (ret)  		goto out; -	nouveau_bo_placement_set(nvbo, memtype); -	for (i = 0; i < nvbo->placement.num_placement; i++) -		nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT; +	nouveau_bo_placement_set(nvbo, memtype, 0);  	ret = ttm_bo_validate(bo, &nvbo->placement, false, false);  	if (ret == 0) { @@ -244,7 +250,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)  {  	struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);  	struct ttm_buffer_object *bo = &nvbo->bo; -	int ret, i; +	int ret;  	if (--nvbo->pin_refcnt)  		return 0; @@ -253,8 +259,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)  	if (ret)  		return ret; -	for (i = 0; i < nvbo->placement.num_placement; i++) -		nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT; +	nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);  	ret = ttm_bo_validate(bo, &nvbo->placement, false, false);  	if (ret == 0) { @@ -395,8 +400,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,  		man->io_addr = NULL;  		man->io_offset = drm_get_resource_start(dev, 1);  		man->io_size = drm_get_resource_len(dev, 1); -		if (man->io_size > nouveau_mem_fb_amount(dev)) -			man->io_size = nouveau_mem_fb_amount(dev); +		if (man->io_size > dev_priv->vram_size) +			man->io_size = dev_priv->vram_size;  		man->gpu_offset = dev_priv->vm_vram_base;  		break; @@ -439,11 +444,11 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)  	switch (bo->mem.mem_type) {  	case TTM_PL_VRAM: -		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT | +		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT,  					 TTM_PL_FLAG_SYSTEM);  		break;  	default: -		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); +		nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0);  		break;  	} diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 6dfb425cbae..1fc57ef5829 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -142,7 +142,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,  					   GFP_KERNEL);  	if (!dev_priv->fifos[channel])  		return -ENOMEM; -	dev_priv->fifo_alloc_count++;  	chan = dev_priv->fifos[channel];  	INIT_LIST_HEAD(&chan->nvsw.vbl_wait);  	INIT_LIST_HEAD(&chan->fence.pending); @@ -321,7 +320,6 @@ nouveau_channel_free(struct nouveau_channel *chan)  		iounmap(chan->user);  	dev_priv->fifos[chan->id] = NULL; -	dev_priv->fifo_alloc_count--;  	kfree(chan);  } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 24327f468c4..14afe1e47e5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -302,7 +302,7 @@ nouveau_connector_detect(struct drm_connector *connector)  detect_analog:  	nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); -	if (!nv_encoder) +	if (!nv_encoder && !nouveau_tv_disable)  		nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);  	if (nv_encoder) {  		struct drm_encoder *encoder = to_drm_encoder(nv_encoder); diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 8ff9ef5d4b4..a251886a0ce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -137,10 +137,9 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data)  {  	struct drm_info_node *node = (struct drm_info_node *) m->private;  	struct drm_minor *minor = node->minor; -	struct drm_device *dev = minor->dev; +	struct drm_nouveau_private *dev_priv = minor->dev->dev_private; -	seq_printf(m, "VRAM total: %dKiB\n", -		   (int)(nouveau_mem_fb_amount(dev) >> 10)); +	seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10));  	return 0;  } diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index c8482a108a7..65c441a1999 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -190,6 +190,11 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,  	nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);  	chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; + +	DRM_MEMORYBARRIER(); +	/* Flush writes. */ +	nouveau_bo_rd32(pb, 0); +  	nvchan_wr32(chan, 0x8c, chan->dma.ib_put);  	chan->dma.ib_free--;  } diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index f954ad93e81..deeb21c6865 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -483,7 +483,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,  	ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT);  	ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT); -	for (;;) { +	for (i = 0; i < 16; i++) {  		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000);  		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl);  		nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000); @@ -502,6 +502,12 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,  			break;  	} +	if (i == 16) { +		NV_ERROR(dev, "auxch DEFER too many times, bailing\n"); +		ret = -EREMOTEIO; +		goto out; +	} +  	if (cmd & 1) {  		if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) {  			ret = -EREMOTEIO; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 30cc09e8a70..1de974acbc6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -83,6 +83,14 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");  int nouveau_nofbaccel = 0;  module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); +MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type"); +int nouveau_override_conntype = 0; +module_param_named(override_conntype, nouveau_override_conntype, int, 0400); + +MODULE_PARM_DESC(tv_disable, "Disable TV-out detection\n"); +int nouveau_tv_disable = 0; +module_param_named(tv_disable, nouveau_tv_disable, int, 0400); +  MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"  		 "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"  		 "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n" @@ -154,9 +162,11 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)  	if (pm_state.event == PM_EVENT_PRETHAW)  		return 0; +	NV_INFO(dev, "Disabling fbcon acceleration...\n");  	fbdev_flags = dev_priv->fbdev_info->flags;  	dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; +	NV_INFO(dev, "Unpinning framebuffer(s)...\n");  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {  		struct nouveau_framebuffer *nouveau_fb; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5f8d987af36..ace630aa89e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -76,6 +76,7 @@ struct nouveau_bo {  	struct ttm_buffer_object bo;  	struct ttm_placement placement;  	u32 placements[3]; +	u32 busy_placements[3];  	struct ttm_bo_kmap_obj kmap;  	struct list_head head; @@ -519,6 +520,7 @@ struct drm_nouveau_private {  	struct workqueue_struct *wq;  	struct work_struct irq_work; +	struct work_struct hpd_work;  	struct list_head vbl_waiting; @@ -533,7 +535,6 @@ struct drm_nouveau_private {  	struct fb_info *fbdev_info; -	int fifo_alloc_count;  	struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];  	struct nouveau_engine engine; @@ -553,12 +554,6 @@ struct drm_nouveau_private {  	uint32_t ramro_offset;  	uint32_t ramro_size; -	/* base physical adresses */ -	uint64_t fb_phys; -	uint64_t fb_available_size; -	uint64_t fb_mappable_pages; -	uint64_t fb_aper_free; -  	struct {  		enum {  			NOUVEAU_GART_NONE = 0, @@ -572,10 +567,6 @@ struct drm_nouveau_private {  		struct nouveau_gpuobj *sg_ctxdma;  		struct page *sg_dummy_page;  		dma_addr_t sg_dummy_bus; - -		/* nottm hack */ -		struct drm_ttm_backend *sg_be; -		unsigned long sg_handle;  	} gart_info;  	/* nv10-nv40 tiling regions */ @@ -584,6 +575,16 @@ struct drm_nouveau_private {  		spinlock_t lock;  	} tile; +	/* VRAM/fb configuration */ +	uint64_t vram_size; +	uint64_t vram_sys_base; + +	uint64_t fb_phys; +	uint64_t fb_available_size; +	uint64_t fb_mappable_pages; +	uint64_t fb_aper_free; +	int fb_mtrr; +  	/* G8x/G9x virtual address space */  	uint64_t vm_gart_base;  	uint64_t vm_gart_size; @@ -592,10 +593,6 @@ struct drm_nouveau_private {  	uint64_t vm_end;  	struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];  	int vm_vram_pt_nr; -	uint64_t vram_sys_base; - -	/* the mtrr covering the FB */ -	int fb_mtrr;  	struct mem_block *ramin_heap; @@ -614,11 +611,7 @@ struct drm_nouveau_private {  	uint32_t dac_users[4];  	struct nouveau_suspend_resume { -		uint32_t fifo_mode; -		uint32_t graph_ctx_control; -		uint32_t graph_state;  		uint32_t *ramin_copy; -		uint64_t ramin_size;  	} susres;  	struct backlight_device *backlight; @@ -681,6 +674,7 @@ extern int nouveau_uscript_tmds;  extern int nouveau_vram_pushbuf;  extern int nouveau_vram_notify;  extern int nouveau_fbpercrtc; +extern int nouveau_tv_disable;  extern char *nouveau_tv_norm;  extern int nouveau_reg_debug;  extern char *nouveau_vbios; @@ -688,6 +682,7 @@ extern int nouveau_ctxfw;  extern int nouveau_ignorelid;  extern int nouveau_nofbaccel;  extern int nouveau_noaccel; +extern int nouveau_override_conntype;  extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);  extern int nouveau_pci_resume(struct pci_dev *pdev); @@ -715,7 +710,7 @@ extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,  						 struct drm_file *, int tail);  extern void nouveau_mem_takedown(struct mem_block **heap);  extern void nouveau_mem_free_block(struct mem_block *); -extern uint64_t nouveau_mem_fb_amount(struct drm_device *); +extern int  nouveau_mem_detect(struct drm_device *dev);  extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);  extern int  nouveau_mem_init(struct drm_device *);  extern int  nouveau_mem_init_agp(struct drm_device *); @@ -926,6 +921,10 @@ extern void nv40_fb_takedown(struct drm_device *);  extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,  				      uint32_t, uint32_t); +/* nv50_fb.c */ +extern int  nv50_fb_init(struct drm_device *); +extern void nv50_fb_takedown(struct drm_device *); +  /* nv04_fifo.c */  extern int  nv04_fifo_init(struct drm_device *);  extern void nv04_fifo_disable(struct drm_device *); @@ -1118,7 +1117,8 @@ extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);  extern int nouveau_bo_unpin(struct nouveau_bo *);  extern int nouveau_bo_map(struct nouveau_bo *);  extern void nouveau_bo_unmap(struct nouveau_bo *); -extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype); +extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type, +				     uint32_t busy);  extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);  extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);  extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); @@ -1162,6 +1162,10 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *,  int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);  int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); +/* nv50_gpio.c */ +int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); +int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); +  #ifndef ioread32_native  #ifdef __BIG_ENDIAN  #define ioread16_native ioread16be diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index bc4a24029ed..9f28b94e479 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -47,6 +47,7 @@ struct nouveau_encoder {  	union {  		struct { +			int mc_unknown;  			int dpcd_version;  			int link_nr;  			int link_bw; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 68cedd9194f..8e7dc1d4912 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -30,7 +30,6 @@  #include <linux/string.h>  #include <linux/mm.h>  #include <linux/tty.h> -#include <linux/slab.h>  #include <linux/sysrq.h>  #include <linux/delay.h>  #include <linux/fb.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0d22f66f1c7..1bc0b38a516 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -180,40 +180,35 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,  {  	struct nouveau_bo *nvbo = gem->driver_private;  	struct ttm_buffer_object *bo = &nvbo->bo; -	uint64_t flags; +	uint32_t domains = valid_domains & +		(write_domains ? write_domains : read_domains); +	uint32_t pref_flags = 0, valid_flags = 0; -	if (!valid_domains || (!read_domains && !write_domains)) +	if (!domains)  		return -EINVAL; -	if (write_domains) { -		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && -		    (write_domains & NOUVEAU_GEM_DOMAIN_VRAM)) -			flags = TTM_PL_FLAG_VRAM; -		else -		if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && -		    (write_domains & NOUVEAU_GEM_DOMAIN_GART)) -			flags = TTM_PL_FLAG_TT; -		else -			return -EINVAL; -	} else { -		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && -		    (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) && -		    bo->mem.mem_type == TTM_PL_VRAM) -			flags = TTM_PL_FLAG_VRAM; -		else -		if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && -		    (read_domains & NOUVEAU_GEM_DOMAIN_GART) && -		    bo->mem.mem_type == TTM_PL_TT) -			flags = TTM_PL_FLAG_TT; -		else -		if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && -		    (read_domains & NOUVEAU_GEM_DOMAIN_VRAM)) -			flags = TTM_PL_FLAG_VRAM; -		else -			flags = TTM_PL_FLAG_TT; -	} +	if (valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) +		valid_flags |= TTM_PL_FLAG_VRAM; + +	if (valid_domains & NOUVEAU_GEM_DOMAIN_GART) +		valid_flags |= TTM_PL_FLAG_TT; + +	if ((domains & NOUVEAU_GEM_DOMAIN_VRAM) && +	    bo->mem.mem_type == TTM_PL_VRAM) +		pref_flags |= TTM_PL_FLAG_VRAM; + +	else if ((domains & NOUVEAU_GEM_DOMAIN_GART) && +		 bo->mem.mem_type == TTM_PL_TT) +		pref_flags |= TTM_PL_FLAG_TT; + +	else if (domains & NOUVEAU_GEM_DOMAIN_VRAM) +		pref_flags |= TTM_PL_FLAG_VRAM; + +	else +		pref_flags |= TTM_PL_FLAG_TT; + +	nouveau_bo_placement_set(nvbo, pref_flags, valid_flags); -	nouveau_bo_placement_set(nvbo, flags);  	return 0;  } diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c index c7ebec69674..32f0e495464 100644 --- a/drivers/gpu/drm/nouveau/nouveau_grctx.c +++ b/drivers/gpu/drm/nouveau/nouveau_grctx.c @@ -23,6 +23,7 @@   */  #include <linux/firmware.h> +#include <linux/slab.h>  #include "drmP.h"  #include "nouveau_drv.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 95220ddebb4..13e73cee4c4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -51,6 +51,7 @@ nouveau_irq_preinstall(struct drm_device *dev)  	if (dev_priv->card_type == NV_50) {  		INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); +		INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);  		INIT_LIST_HEAD(&dev_priv->vbl_waiting);  	}  } @@ -311,6 +312,31 @@ nouveau_print_bitfield_names_(uint32_t value,  #define nouveau_print_bitfield_names(val, namelist) \  	nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist)) +struct nouveau_enum_names { +	uint32_t value; +	const char *name; +}; + +static void +nouveau_print_enum_names_(uint32_t value, +				const struct nouveau_enum_names *namelist, +				const int namelist_len) +{ +	/* +	 * Caller must have already printed the KERN_* log level for us. +	 * Also the caller is responsible for adding the newline. +	 */ +	int i; +	for (i = 0; i < namelist_len; ++i) { +		if (value == namelist[i].value) { +			printk("%s", namelist[i].name); +			return; +		} +	} +	printk("unknown value 0x%08x", value); +} +#define nouveau_print_enum_names(val, namelist) \ +	nouveau_print_enum_names_((val), (namelist), ARRAY_SIZE(namelist))  static int  nouveau_graph_chid_from_grctx(struct drm_device *dev) @@ -427,14 +453,16 @@ nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id,  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	uint32_t nsource = trap->nsource, nstatus = trap->nstatus; -	NV_INFO(dev, "%s - nSource:", id); -	nouveau_print_bitfield_names(nsource, nsource_names); -	printk(", nStatus:"); -	if (dev_priv->card_type < NV_10) -		nouveau_print_bitfield_names(nstatus, nstatus_names); -	else -		nouveau_print_bitfield_names(nstatus, nstatus_names_nv10); -	printk("\n"); +	if (dev_priv->card_type < NV_50) { +		NV_INFO(dev, "%s - nSource:", id); +		nouveau_print_bitfield_names(nsource, nsource_names); +		printk(", nStatus:"); +		if (dev_priv->card_type < NV_10) +			nouveau_print_bitfield_names(nstatus, nstatus_names); +		else +			nouveau_print_bitfield_names(nstatus, nstatus_names_nv10); +		printk("\n"); +	}  	NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x "  					"Data 0x%08x:0x%08x\n", @@ -578,27 +606,502 @@ nouveau_pgraph_irq_handler(struct drm_device *dev)  }  static void +nv50_pfb_vm_trap(struct drm_device *dev, int display, const char *name) +{ +	struct drm_nouveau_private *dev_priv = dev->dev_private; +	uint32_t trap[6]; +	int i, ch; +	uint32_t idx = nv_rd32(dev, 0x100c90); +	if (idx & 0x80000000) { +		idx &= 0xffffff; +		if (display) { +			for (i = 0; i < 6; i++) { +				nv_wr32(dev, 0x100c90, idx | i << 24); +				trap[i] = nv_rd32(dev, 0x100c94); +			} +			for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { +				struct nouveau_channel *chan = dev_priv->fifos[ch]; + +				if (!chan || !chan->ramin) +					continue; + +				if (trap[1] == chan->ramin->instance >> 12) +					break; +			} +			NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x %08x channel %d\n", +					name, (trap[5]&0x100?"read":"write"), +					trap[5]&0xff, trap[4]&0xffff, +					trap[3]&0xffff, trap[0], trap[2], ch); +		} +		nv_wr32(dev, 0x100c90, idx | 0x80000000); +	} else if (display) { +		NV_INFO(dev, "%s - no VM fault?\n", name); +	} +} + +static struct nouveau_enum_names nv50_mp_exec_error_names[] = +{ +	{ 3, "STACK_UNDERFLOW" }, +	{ 4, "QUADON_ACTIVE" }, +	{ 8, "TIMEOUT" }, +	{ 0x10, "INVALID_OPCODE" }, +	{ 0x40, "BREAKPOINT" }, +}; + +static void +nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display) +{ +	struct drm_nouveau_private *dev_priv = dev->dev_private; +	uint32_t units = nv_rd32(dev, 0x1540); +	uint32_t addr, mp10, status, pc, oplow, ophigh; +	int i; +	int mps = 0; +	for (i = 0; i < 4; i++) { +		if (!(units & 1 << (i+24))) +			continue; +		if (dev_priv->chipset < 0xa0) +			addr = 0x408200 + (tpid << 12) + (i << 7); +		else +			addr = 0x408100 + (tpid << 11) + (i << 7); +		mp10 = nv_rd32(dev, addr + 0x10); +		status = nv_rd32(dev, addr + 0x14); +		if (!status) +			continue; +		if (display) { +			nv_rd32(dev, addr + 0x20); +			pc = nv_rd32(dev, addr + 0x24); +			oplow = nv_rd32(dev, addr + 0x70); +			ophigh= nv_rd32(dev, addr + 0x74); +			NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " +					"TP %d MP %d: ", tpid, i); +			nouveau_print_enum_names(status, +					nv50_mp_exec_error_names); +			printk(" at %06x warp %d, opcode %08x %08x\n", +					pc&0xffffff, pc >> 24, +					oplow, ophigh); +		} +		nv_wr32(dev, addr + 0x10, mp10); +		nv_wr32(dev, addr + 0x14, 0); +		mps++; +	} +	if (!mps && display) +		NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: " +				"No MPs claiming errors?\n", tpid); +} + +static void +nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old, +		uint32_t ustatus_new, int display, const char *name) +{ +	struct drm_nouveau_private *dev_priv = dev->dev_private; +	int tps = 0; +	uint32_t units = nv_rd32(dev, 0x1540); +	int i, r; +	uint32_t ustatus_addr, ustatus; +	for (i = 0; i < 16; i++) { +		if (!(units & (1 << i))) +			continue; +		if (dev_priv->chipset < 0xa0) +			ustatus_addr = ustatus_old + (i << 12); +		else +			ustatus_addr = ustatus_new + (i << 11); +		ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff; +		if (!ustatus) +			continue; +		tps++; +		switch (type) { +		case 6: /* texture error... unknown for now */ +			nv50_pfb_vm_trap(dev, display, name); +			if (display) { +				NV_ERROR(dev, "magic set %d:\n", i); +				for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) +					NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, +						nv_rd32(dev, r)); +			} +			break; +		case 7: /* MP error */ +			if (ustatus & 0x00010000) { +				nv50_pgraph_mp_trap(dev, i, display); +				ustatus &= ~0x00010000; +			} +			break; +		case 8: /* TPDMA error */ +			{ +			uint32_t e0c = nv_rd32(dev, ustatus_addr + 4); +			uint32_t e10 = nv_rd32(dev, ustatus_addr + 8); +			uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc); +			uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10); +			uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14); +			uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18); +			uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c); +			nv50_pfb_vm_trap(dev, display, name); +			/* 2d engine destination */ +			if (ustatus & 0x00000010) { +				if (display) { +					NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n", +							i, e14, e10); +					NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", +							i, e0c, e18, e1c, e20, e24); +				} +				ustatus &= ~0x00000010; +			} +			/* Render target */ +			if (ustatus & 0x00000040) { +				if (display) { +					NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n", +							i, e14, e10); +					NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", +							i, e0c, e18, e1c, e20, e24); +				} +				ustatus &= ~0x00000040; +			} +			/* CUDA memory: l[], g[] or stack. */ +			if (ustatus & 0x00000080) { +				if (display) { +					if (e18 & 0x80000000) { +						/* g[] read fault? */ +						NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n", +								i, e14, e10 | ((e18 >> 24) & 0x1f)); +						e18 &= ~0x1f000000; +					} else if (e18 & 0xc) { +						/* g[] write fault? */ +						NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n", +								i, e14, e10 | ((e18 >> 7) & 0x1f)); +						e18 &= ~0x00000f80; +					} else { +						NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n", +								i, e14, e10); +					} +					NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", +							i, e0c, e18, e1c, e20, e24); +				} +				ustatus &= ~0x00000080; +			} +			} +			break; +		} +		if (ustatus) { +			if (display) +				NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus); +		} +		nv_wr32(dev, ustatus_addr, 0xc0000000); +	} + +	if (!tps && display) +		NV_INFO(dev, "%s - No TPs claiming errors?\n", name); +} + +static void +nv50_pgraph_trap_handler(struct drm_device *dev) +{ +	struct nouveau_pgraph_trap trap; +	uint32_t status = nv_rd32(dev, 0x400108); +	uint32_t ustatus; +	int display = nouveau_ratelimit(); + + +	if (!status && display) { +		nouveau_graph_trap_info(dev, &trap); +		nouveau_graph_dump_trap_info(dev, "PGRAPH_TRAP", &trap); +		NV_INFO(dev, "PGRAPH_TRAP - no units reporting traps?\n"); +	} + +	/* DISPATCH: Relays commands to other units and handles NOTIFY, +	 * COND, QUERY. If you get a trap from it, the command is still stuck +	 * in DISPATCH and you need to do something about it. */ +	if (status & 0x001) { +		ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff; +		if (!ustatus && display) { +			NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n"); +		} + +		/* Known to be triggered by screwed up NOTIFY and COND... */ +		if (ustatus & 0x00000001) { +			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT"); +			nv_wr32(dev, 0x400500, 0); +			if (nv_rd32(dev, 0x400808) & 0x80000000) { +				if (display) { +					if (nouveau_graph_trapped_channel(dev, &trap.channel)) +						trap.channel = -1; +					trap.class = nv_rd32(dev, 0x400814); +					trap.mthd = nv_rd32(dev, 0x400808) & 0x1ffc; +					trap.subc = (nv_rd32(dev, 0x400808) >> 16) & 0x7; +					trap.data = nv_rd32(dev, 0x40080c); +					trap.data2 = nv_rd32(dev, 0x400810); +					nouveau_graph_dump_trap_info(dev, +							"PGRAPH_TRAP_DISPATCH_FAULT", &trap); +					NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400808: %08x\n", nv_rd32(dev, 0x400808)); +					NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400848: %08x\n", nv_rd32(dev, 0x400848)); +				} +				nv_wr32(dev, 0x400808, 0); +			} else if (display) { +				NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - No stuck command?\n"); +			} +			nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3); +			nv_wr32(dev, 0x400848, 0); +			ustatus &= ~0x00000001; +		} +		if (ustatus & 0x00000002) { +			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY"); +			nv_wr32(dev, 0x400500, 0); +			if (nv_rd32(dev, 0x40084c) & 0x80000000) { +				if (display) { +					if (nouveau_graph_trapped_channel(dev, &trap.channel)) +						trap.channel = -1; +					trap.class = nv_rd32(dev, 0x400814); +					trap.mthd = nv_rd32(dev, 0x40084c) & 0x1ffc; +					trap.subc = (nv_rd32(dev, 0x40084c) >> 16) & 0x7; +					trap.data = nv_rd32(dev, 0x40085c); +					trap.data2 = 0; +					nouveau_graph_dump_trap_info(dev, +							"PGRAPH_TRAP_DISPATCH_QUERY", &trap); +					NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - 40084c: %08x\n", nv_rd32(dev, 0x40084c)); +				} +				nv_wr32(dev, 0x40084c, 0); +			} else if (display) { +				NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - No stuck command?\n"); +			} +			ustatus &= ~0x00000002; +		} +		if (ustatus && display) +			NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - Unhandled ustatus 0x%08x\n", ustatus); +		nv_wr32(dev, 0x400804, 0xc0000000); +		nv_wr32(dev, 0x400108, 0x001); +		status &= ~0x001; +	} + +	/* TRAPs other than dispatch use the "normal" trap regs. */ +	if (status && display) { +		nouveau_graph_trap_info(dev, &trap); +		nouveau_graph_dump_trap_info(dev, +				"PGRAPH_TRAP", &trap); +	} + +	/* M2MF: Memory to memory copy engine. */ +	if (status & 0x002) { +		ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff; +		if (!ustatus && display) { +			NV_INFO(dev, "PGRAPH_TRAP_M2MF - no ustatus?\n"); +		} +		if (ustatus & 0x00000001) { +			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY"); +			ustatus &= ~0x00000001; +		} +		if (ustatus & 0x00000002) { +			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN"); +			ustatus &= ~0x00000002; +		} +		if (ustatus & 0x00000004) { +			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT"); +			ustatus &= ~0x00000004; +		} +		NV_INFO (dev, "PGRAPH_TRAP_M2MF - %08x %08x %08x %08x\n", +				nv_rd32(dev, 0x406804), +				nv_rd32(dev, 0x406808), +				nv_rd32(dev, 0x40680c), +				nv_rd32(dev, 0x406810)); +		if (ustatus && display) +			NV_INFO(dev, "PGRAPH_TRAP_M2MF - Unhandled ustatus 0x%08x\n", ustatus); +		/* No sane way found yet -- just reset the bugger. */ +		nv_wr32(dev, 0x400040, 2); +		nv_wr32(dev, 0x400040, 0); +		nv_wr32(dev, 0x406800, 0xc0000000); +		nv_wr32(dev, 0x400108, 0x002); +		status &= ~0x002; +	} + +	/* VFETCH: Fetches data from vertex buffers. */ +	if (status & 0x004) { +		ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff; +		if (!ustatus && display) { +			NV_INFO(dev, "PGRAPH_TRAP_VFETCH - no ustatus?\n"); +		} +		if (ustatus & 0x00000001) { +			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT"); +			NV_INFO (dev, "PGRAPH_TRAP_VFETCH_FAULT - %08x %08x %08x %08x\n", +					nv_rd32(dev, 0x400c00), +					nv_rd32(dev, 0x400c08), +					nv_rd32(dev, 0x400c0c), +					nv_rd32(dev, 0x400c10)); +			ustatus &= ~0x00000001; +		} +		if (ustatus && display) +			NV_INFO(dev, "PGRAPH_TRAP_VFETCH - Unhandled ustatus 0x%08x\n", ustatus); +		nv_wr32(dev, 0x400c04, 0xc0000000); +		nv_wr32(dev, 0x400108, 0x004); +		status &= ~0x004; +	} + +	/* STRMOUT: DirectX streamout / OpenGL transform feedback. */ +	if (status & 0x008) { +		ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff; +		if (!ustatus && display) { +			NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - no ustatus?\n"); +		} +		if (ustatus & 0x00000001) { +			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT"); +			NV_INFO (dev, "PGRAPH_TRAP_STRMOUT_FAULT - %08x %08x %08x %08x\n", +					nv_rd32(dev, 0x401804), +					nv_rd32(dev, 0x401808), +					nv_rd32(dev, 0x40180c), +					nv_rd32(dev, 0x401810)); +			ustatus &= ~0x00000001; +		} +		if (ustatus && display) +			NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - Unhandled ustatus 0x%08x\n", ustatus); +		/* No sane way found yet -- just reset the bugger. */ +		nv_wr32(dev, 0x400040, 0x80); +		nv_wr32(dev, 0x400040, 0); +		nv_wr32(dev, 0x401800, 0xc0000000); +		nv_wr32(dev, 0x400108, 0x008); +		status &= ~0x008; +	} + +	/* CCACHE: Handles code and c[] caches and fills them. */ +	if (status & 0x010) { +		ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff; +		if (!ustatus && display) { +			NV_INFO(dev, "PGRAPH_TRAP_CCACHE - no ustatus?\n"); +		} +		if (ustatus & 0x00000001) { +			nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT"); +			NV_INFO (dev, "PGRAPH_TRAP_CCACHE_FAULT - %08x %08x %08x %08x %08x %08x %08x\n", +					nv_rd32(dev, 0x405800), +					nv_rd32(dev, 0x405804), +					nv_rd32(dev, 0x405808), +					nv_rd32(dev, 0x40580c), +					nv_rd32(dev, 0x405810), +					nv_rd32(dev, 0x405814), +					nv_rd32(dev, 0x40581c)); +			ustatus &= ~0x00000001; +		} +		if (ustatus && display) +			NV_INFO(dev, "PGRAPH_TRAP_CCACHE - Unhandled ustatus 0x%08x\n", ustatus); +		nv_wr32(dev, 0x405018, 0xc0000000); +		nv_wr32(dev, 0x400108, 0x010); +		status &= ~0x010; +	} + +	/* Unknown, not seen yet... 0x402000 is the only trap status reg +	 * remaining, so try to handle it anyway. Perhaps related to that +	 * unknown DMA slot on tesla? */ +	if (status & 0x20) { +		nv50_pfb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04"); +		ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff; +		if (display) +			NV_INFO(dev, "PGRAPH_TRAP_UNKC04 - Unhandled ustatus 0x%08x\n", ustatus); +		nv_wr32(dev, 0x402000, 0xc0000000); +		/* no status modifiction on purpose */ +	} + +	/* TEXTURE: CUDA texturing units */ +	if (status & 0x040) { +		nv50_pgraph_tp_trap (dev, 6, 0x408900, 0x408600, display, +				"PGRAPH_TRAP_TEXTURE"); +		nv_wr32(dev, 0x400108, 0x040); +		status &= ~0x040; +	} + +	/* MP: CUDA execution engines. */ +	if (status & 0x080) { +		nv50_pgraph_tp_trap (dev, 7, 0x408314, 0x40831c, display, +				"PGRAPH_TRAP_MP"); +		nv_wr32(dev, 0x400108, 0x080); +		status &= ~0x080; +	} + +	/* TPDMA:  Handles TP-initiated uncached memory accesses: +	 * l[], g[], stack, 2d surfaces, render targets. */ +	if (status & 0x100) { +		nv50_pgraph_tp_trap (dev, 8, 0x408e08, 0x408708, display, +				"PGRAPH_TRAP_TPDMA"); +		nv_wr32(dev, 0x400108, 0x100); +		status &= ~0x100; +	} + +	if (status) { +		if (display) +			NV_INFO(dev, "PGRAPH_TRAP - Unknown trap 0x%08x\n", +				status); +		nv_wr32(dev, 0x400108, status); +	} +} + +/* There must be a *lot* of these. Will take some time to gather them up. */ +static struct nouveau_enum_names nv50_data_error_names[] = +{ +	{ 4,	"INVALID_VALUE" }, +	{ 5,	"INVALID_ENUM" }, +	{ 8,	"INVALID_OBJECT" }, +	{ 0xc,	"INVALID_BITFIELD" }, +	{ 0x28,	"MP_NO_REG_SPACE" }, +	{ 0x2b,	"MP_BLOCK_SIZE_MISMATCH" }, +}; + +static void  nv50_pgraph_irq_handler(struct drm_device *dev)  { +	struct nouveau_pgraph_trap trap; +	int unhandled = 0;  	uint32_t status;  	while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) { -		uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); - +		/* NOTIFY: You've set a NOTIFY an a command and it's done. */  		if (status & 0x00000001) { -			nouveau_pgraph_intr_notify(dev, nsource); +			nouveau_graph_trap_info(dev, &trap); +			if (nouveau_ratelimit()) +				nouveau_graph_dump_trap_info(dev, +						"PGRAPH_NOTIFY", &trap);  			status &= ~0x00000001;  			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001);  		} -		if (status & 0x00000010) { -			nouveau_pgraph_intr_error(dev, nsource | -					NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); +		/* COMPUTE_QUERY: Purpose and exact cause unknown, happens +		 * when you write 0x200 to 0x50c0 method 0x31c. */ +		if (status & 0x00000002) { +			nouveau_graph_trap_info(dev, &trap); +			if (nouveau_ratelimit()) +				nouveau_graph_dump_trap_info(dev, +						"PGRAPH_COMPUTE_QUERY", &trap); +			status &= ~0x00000002; +			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000002); +		} + +		/* Unknown, never seen: 0x4 */ +		/* ILLEGAL_MTHD: You used a wrong method for this class. */ +		if (status & 0x00000010) { +			nouveau_graph_trap_info(dev, &trap); +			if (nouveau_pgraph_intr_swmthd(dev, &trap)) +				unhandled = 1; +			if (unhandled && nouveau_ratelimit()) +				nouveau_graph_dump_trap_info(dev, +						"PGRAPH_ILLEGAL_MTHD", &trap);  			status &= ~0x00000010;  			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010);  		} +		/* ILLEGAL_CLASS: You used a wrong class. */ +		if (status & 0x00000020) { +			nouveau_graph_trap_info(dev, &trap); +			if (nouveau_ratelimit()) +				nouveau_graph_dump_trap_info(dev, +						"PGRAPH_ILLEGAL_CLASS", &trap); +			status &= ~0x00000020; +			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000020); +		} + +		/* DOUBLE_NOTIFY: You tried to set a NOTIFY on another NOTIFY. */ +		if (status & 0x00000040) { +			nouveau_graph_trap_info(dev, &trap); +			if (nouveau_ratelimit()) +				nouveau_graph_dump_trap_info(dev, +						"PGRAPH_DOUBLE_NOTIFY", &trap); +			status &= ~0x00000040; +			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000040); +		} + +		/* CONTEXT_SWITCH: PGRAPH needs us to load a new context */  		if (status & 0x00001000) {  			nv_wr32(dev, 0x400500, 0x00000000);  			nv_wr32(dev, NV03_PGRAPH_INTR, @@ -613,49 +1116,59 @@ nv50_pgraph_irq_handler(struct drm_device *dev)  			status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;  		} -		if (status & 0x00100000) { -			nouveau_pgraph_intr_error(dev, nsource | -					NV03_PGRAPH_NSOURCE_DATA_ERROR); +		/* BUFFER_NOTIFY: Your m2mf transfer finished */ +		if (status & 0x00010000) { +			nouveau_graph_trap_info(dev, &trap); +			if (nouveau_ratelimit()) +				nouveau_graph_dump_trap_info(dev, +						"PGRAPH_BUFFER_NOTIFY", &trap); +			status &= ~0x00010000; +			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00010000); +		} +		/* DATA_ERROR: Invalid value for this method, or invalid +		 * state in current PGRAPH context for this operation */ +		if (status & 0x00100000) { +			nouveau_graph_trap_info(dev, &trap); +			if (nouveau_ratelimit()) { +				nouveau_graph_dump_trap_info(dev, +						"PGRAPH_DATA_ERROR", &trap); +				NV_INFO (dev, "PGRAPH_DATA_ERROR - "); +				nouveau_print_enum_names(nv_rd32(dev, 0x400110), +						nv50_data_error_names); +				printk("\n"); +			}  			status &= ~0x00100000;  			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000);  		} +		/* TRAP: Something bad happened in the middle of command +		 * execution.  Has a billion types, subtypes, and even +		 * subsubtypes. */  		if (status & 0x00200000) { -			int r; - -			nouveau_pgraph_intr_error(dev, nsource | -					NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); - -			NV_ERROR(dev, "magic set 1:\n"); -			for (r = 0x408900; r <= 0x408910; r += 4) -				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, -					nv_rd32(dev, r)); -			nv_wr32(dev, 0x408900, -				nv_rd32(dev, 0x408904) | 0xc0000000); -			for (r = 0x408e08; r <= 0x408e24; r += 4) -				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, -							nv_rd32(dev, r)); -			nv_wr32(dev, 0x408e08, -				nv_rd32(dev, 0x408e08) | 0xc0000000); - -			NV_ERROR(dev, "magic set 2:\n"); -			for (r = 0x409900; r <= 0x409910; r += 4) -				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, -					nv_rd32(dev, r)); -			nv_wr32(dev, 0x409900, -				nv_rd32(dev, 0x409904) | 0xc0000000); -			for (r = 0x409e08; r <= 0x409e24; r += 4) -				NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, -					nv_rd32(dev, r)); -			nv_wr32(dev, 0x409e08, -				nv_rd32(dev, 0x409e08) | 0xc0000000); - +			nv50_pgraph_trap_handler(dev);  			status &= ~0x00200000; -			nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource);  			nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000);  		} +		/* Unknown, never seen: 0x00400000 */ + +		/* SINGLE_STEP: Happens on every method if you turned on +		 * single stepping in 40008c */ +		if (status & 0x01000000) { +			nouveau_graph_trap_info(dev, &trap); +			if (nouveau_ratelimit()) +				nouveau_graph_dump_trap_info(dev, +						"PGRAPH_SINGLE_STEP", &trap); +			status &= ~0x01000000; +			nv_wr32(dev, NV03_PGRAPH_INTR, 0x01000000); +		} + +		/* 0x02000000 happens when you pause a ctxprog... +		 * but the only way this can happen that I know is by +		 * poking the relevant MMIO register, and we don't +		 * do that. */ +  		if (status) {  			NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n",  				status); @@ -672,7 +1185,8 @@ nv50_pgraph_irq_handler(struct drm_device *dev)  	}  	nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); -	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); +	if (nv_rd32(dev, 0x400824) & (1 << 31)) +		nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));  }  static void diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 2dc09dbd817..775a7017af6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -347,6 +347,20 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,  		return -EBUSY;  	} +	nv_wr32(dev, 0x100c80, 0x00040001); +	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +		return -EBUSY; +	} + +	nv_wr32(dev, 0x100c80, 0x00060001); +	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +		return -EBUSY; +	} +  	return 0;  } @@ -387,6 +401,20 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)  	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {  		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");  		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +		return; +	} + +	nv_wr32(dev, 0x100c80, 0x00040001); +	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); +		return; +	} + +	nv_wr32(dev, 0x100c80, 0x00060001); +	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));  	}  } @@ -449,9 +477,30 @@ void nouveau_mem_close(struct drm_device *dev)  	}  } -/*XXX won't work on BSD because of pci_read_config_dword */  static uint32_t -nouveau_mem_fb_amount_igp(struct drm_device *dev) +nouveau_mem_detect_nv04(struct drm_device *dev) +{ +	uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0); + +	if (boot0 & 0x00000100) +		return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; + +	switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { +	case NV04_BOOT_0_RAM_AMOUNT_32MB: +		return 32 * 1024 * 1024; +	case NV04_BOOT_0_RAM_AMOUNT_16MB: +		return 16 * 1024 * 1024; +	case NV04_BOOT_0_RAM_AMOUNT_8MB: +		return 8 * 1024 * 1024; +	case NV04_BOOT_0_RAM_AMOUNT_4MB: +		return 4 * 1024 * 1024; +	} + +	return 0; +} + +static uint32_t +nouveau_mem_detect_nforce(struct drm_device *dev)  {  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct pci_dev *bridge; @@ -463,11 +512,11 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)  		return 0;  	} -	if (dev_priv->flags&NV_NFORCE) { +	if (dev_priv->flags & NV_NFORCE) {  		pci_read_config_dword(bridge, 0x7C, &mem);  		return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;  	} else -	if (dev_priv->flags&NV_NFORCE2) { +	if (dev_priv->flags & NV_NFORCE2) {  		pci_read_config_dword(bridge, 0x84, &mem);  		return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;  	} @@ -477,50 +526,32 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)  }  /* returns the amount of FB ram in bytes */ -uint64_t nouveau_mem_fb_amount(struct drm_device *dev) +int +nouveau_mem_detect(struct drm_device *dev)  {  	struct drm_nouveau_private *dev_priv = dev->dev_private; -	uint32_t boot0; -	switch (dev_priv->card_type) { -	case NV_04: -		boot0 = nv_rd32(dev, NV03_BOOT_0); -		if (boot0 & 0x00000100) -			return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024; +	if (dev_priv->card_type == NV_04) { +		dev_priv->vram_size = nouveau_mem_detect_nv04(dev); +	} else +	if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { +		dev_priv->vram_size = nouveau_mem_detect_nforce(dev); +	} else { +		dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA); +		dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK; +		if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) +			dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; +	} -		switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) { -		case NV04_BOOT_0_RAM_AMOUNT_32MB: -			return 32 * 1024 * 1024; -		case NV04_BOOT_0_RAM_AMOUNT_16MB: -			return 16 * 1024 * 1024; -		case NV04_BOOT_0_RAM_AMOUNT_8MB: -			return 8 * 1024 * 1024; -		case NV04_BOOT_0_RAM_AMOUNT_4MB: -			return 4 * 1024 * 1024; -		} -		break; -	case NV_10: -	case NV_20: -	case NV_30: -	case NV_40: -	case NV_50: -	default: -		if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) { -			return nouveau_mem_fb_amount_igp(dev); -		} else { -			uint64_t mem; -			mem = (nv_rd32(dev, NV04_FIFO_DATA) & -					NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >> -					NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT; -			return mem * 1024 * 1024; -		} -		break; +	NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); +	if (dev_priv->vram_sys_base) { +		NV_INFO(dev, "Stolen system memory at: 0x%010llx\n", +			dev_priv->vram_sys_base);  	} -	NV_ERROR(dev, -		"Unable to detect video ram size. Please report your setup to " -							DRIVER_EMAIL "\n"); -	return 0; +	if (dev_priv->vram_size) +		return 0; +	return -ENOMEM;  }  #if __OS_HAS_AGP @@ -631,15 +662,12 @@ nouveau_mem_init(struct drm_device *dev)  	spin_lock_init(&dev_priv->ttm.bo_list_lock);  	spin_lock_init(&dev_priv->tile.lock); -	dev_priv->fb_available_size = nouveau_mem_fb_amount(dev); - +	dev_priv->fb_available_size = dev_priv->vram_size;  	dev_priv->fb_mappable_pages = dev_priv->fb_available_size;  	if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))  		dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);  	dev_priv->fb_mappable_pages >>= PAGE_SHIFT; -	NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20)); -  	/* remove reserved space at end of vram from available amount */  	dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;  	dev_priv->fb_aper_free = dev_priv->fb_available_size; diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index ed1590577b6..1d6ee8b5515 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -1,6 +1,7 @@  #include "drmP.h"  #include "nouveau_drv.h"  #include <linux/pagemap.h> +#include <linux/slab.h>  #define NV_CTXDMA_PAGE_SHIFT 12  #define NV_CTXDMA_PAGE_SIZE  (1 << NV_CTXDMA_PAGE_SHIFT) @@ -171,6 +172,24 @@ nouveau_sgdma_unbind(struct ttm_backend *be)  	}  	dev_priv->engine.instmem.finish_access(nvbe->dev); +	if (dev_priv->card_type == NV_50) { +		nv_wr32(dev, 0x100c80, 0x00050001); +		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +			NV_ERROR(dev, "0x100c80 = 0x%08x\n", +						nv_rd32(dev, 0x100c80)); +			return -EBUSY; +		} + +		nv_wr32(dev, 0x100c80, 0x00000001); +		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { +			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); +			NV_ERROR(dev, "0x100c80 = 0x%08x\n", +						nv_rd32(dev, 0x100c80)); +			return -EBUSY; +		} +	} +  	nvbe->bound = false;  	return 0;  } diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index eb8f084d5f5..e1710640a27 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -24,6 +24,7 @@   */  #include <linux/swab.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "drm_sarea.h" @@ -35,7 +36,6 @@  #include "nouveau_drm.h"  #include "nv50_display.h" -static int nouveau_stub_init(struct drm_device *dev) { return 0; }  static void nouveau_stub_takedown(struct drm_device *dev) {}  static int nouveau_init_engine_ptrs(struct drm_device *dev) @@ -277,8 +277,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)  		engine->timer.init		= nv04_timer_init;  		engine->timer.read		= nv04_timer_read;  		engine->timer.takedown		= nv04_timer_takedown; -		engine->fb.init			= nouveau_stub_init; -		engine->fb.takedown		= nouveau_stub_takedown; +		engine->fb.init			= nv50_fb_init; +		engine->fb.takedown		= nv50_fb_takedown;  		engine->graph.grclass		= nv50_graph_grclass;  		engine->graph.init		= nv50_graph_init;  		engine->graph.takedown		= nv50_graph_takedown; @@ -341,7 +341,7 @@ nouveau_card_init_channel(struct drm_device *dev)  	gpuobj = NULL;  	ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, -				     0, nouveau_mem_fb_amount(dev), +				     0, dev_priv->vram_size,  				     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,  				     &gpuobj);  	if (ret) @@ -427,6 +427,10 @@ nouveau_card_init(struct drm_device *dev)  			goto out;  	} +	ret = nouveau_mem_detect(dev); +	if (ret) +		goto out_bios; +  	ret = nouveau_gpuobj_early_init(dev);  	if (ret)  		goto out_bios; @@ -502,7 +506,7 @@ nouveau_card_init(struct drm_device *dev)  		else  			ret = nv04_display_create(dev);  		if (ret) -			goto out_irq; +			goto out_channel;  	}  	ret = nouveau_backlight_init(dev); @@ -516,6 +520,11 @@ nouveau_card_init(struct drm_device *dev)  	return 0; +out_channel: +	if (dev_priv->channel) { +		nouveau_channel_free(dev_priv->channel); +		dev_priv->channel = NULL; +	}  out_irq:  	drm_irq_uninstall(dev);  out_fifo: @@ -533,6 +542,7 @@ out_mc:  out_gpuobj:  	nouveau_gpuobj_takedown(dev);  out_mem: +	nouveau_sgdma_takedown(dev);  	nouveau_mem_close(dev);  out_instmem:  	engine->instmem.takedown(dev); diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index a1d1ebb073d..eba687f1099 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -230,9 +230,9 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)  	struct drm_framebuffer *fb = crtc->fb;  	/* Calculate our timings */ -	int horizDisplay	= (mode->crtc_hdisplay >> 3) 	- 1; -	int horizStart		= (mode->crtc_hsync_start >> 3) 	- 1; -	int horizEnd		= (mode->crtc_hsync_end >> 3) 	- 1; +	int horizDisplay	= (mode->crtc_hdisplay >> 3)		- 1; +	int horizStart		= (mode->crtc_hsync_start >> 3) 	+ 1; +	int horizEnd		= (mode->crtc_hsync_end >> 3)		+ 1;  	int horizTotal		= (mode->crtc_htotal >> 3)		- 5;  	int horizBlankStart	= (mode->crtc_hdisplay >> 3)		- 1;  	int horizBlankEnd	= (mode->crtc_htotal >> 3)		- 1; diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 3da90c2c4e6..813b25cec72 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -118,8 +118,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)  		return;  	} -	width = ALIGN(image->width, 32); -	dsize = (width * image->height) >> 5; +	width = ALIGN(image->width, 8); +	dsize = ALIGN(width * image->height, 32) >> 5;  	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||  	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) { @@ -136,8 +136,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)  			 ((image->dx + image->width) & 0xffff));  	OUT_RING(chan, bg);  	OUT_RING(chan, fg); -	OUT_RING(chan, (image->height << 16) | image->width);  	OUT_RING(chan, (image->height << 16) | width); +	OUT_RING(chan, (image->height << 16) | image->width);  	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));  	while (dsize) { diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index 6b2ef4a9fce..500ccfd3a0b 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c @@ -278,7 +278,7 @@ nv40_fifo_init_ramxx(struct drm_device *dev)  	default:  		nv_wr32(dev, 0x2230, 0);  		nv_wr32(dev, NV40_PFIFO_RAMFC, -			((nouveau_mem_fb_amount(dev) - 512 * 1024 + +			((dev_priv->vram_size - 512 * 1024 +  			  dev_priv->ramfc_offset) >> 16) | (3 << 16));  		break;  	} diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 53e8afe1dcd..0616c96e4b6 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -335,6 +335,27 @@ nv40_graph_init(struct drm_device *dev)  	nv_wr32(dev, 0x400b38, 0x2ffff800);  	nv_wr32(dev, 0x400b3c, 0x00006000); +	/* Tiling related stuff. */ +	switch (dev_priv->chipset) { +	case 0x44: +	case 0x4a: +		nv_wr32(dev, 0x400bc4, 0x1003d888); +		nv_wr32(dev, 0x400bbc, 0xb7a7b500); +		break; +	case 0x46: +		nv_wr32(dev, 0x400bc4, 0x0000e024); +		nv_wr32(dev, 0x400bbc, 0xb7a7b520); +		break; +	case 0x4c: +	case 0x4e: +	case 0x67: +		nv_wr32(dev, 0x400bc4, 0x1003d888); +		nv_wr32(dev, 0x400bbc, 0xb7a7b540); +		break; +	default: +		break; +	} +  	/* Turn all the tiling regions off. */  	for (i = 0; i < pfb->num_tiles; i++)  		nv40_graph_set_region_tiling(dev, i, 0, 0, 0); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 61a89f2dc55..649db4c1b69 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -143,7 +143,7 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)  	}  	ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19, -				  0, nouveau_mem_fb_amount(dev)); +				  0, dev_priv->vram_size);  	if (ret) {  		nv50_evo_channel_del(pchan);  		return ret; @@ -231,7 +231,7 @@ nv50_display_init(struct drm_device *dev)  	/* This used to be in crtc unblank, but seems out of place there. */  	nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);  	/* RAM is clamped to 256 MiB. */ -	ram_amount = nouveau_mem_fb_amount(dev); +	ram_amount = dev_priv->vram_size;  	NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount);  	if (ram_amount > 256*1024*1024)  		ram_amount = 256*1024*1024; @@ -522,15 +522,17 @@ int nv50_display_create(struct drm_device *dev)  	}  	for (i = 0 ; i < dcb->connector.entries; i++) { -		if (i != 0 && dcb->connector.entry[i].index == -			      dcb->connector.entry[i - 1].index) +		if (i != 0 && dcb->connector.entry[i].index2 == +			      dcb->connector.entry[i - 1].index2)  			continue;  		nouveau_connector_create(dev, &dcb->connector.entry[i]);  	}  	ret = nv50_display_init(dev); -	if (ret) +	if (ret) { +		nv50_display_destroy(dev);  		return ret; +	}  	return 0;  } @@ -885,10 +887,12 @@ nv50_display_error_handler(struct drm_device *dev)  	nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000);  } -static void -nv50_display_irq_hotplug(struct drm_device *dev) +void +nv50_display_irq_hotplug_bh(struct work_struct *work)  { -	struct drm_nouveau_private *dev_priv = dev->dev_private; +	struct drm_nouveau_private *dev_priv = +		container_of(work, struct drm_nouveau_private, hpd_work); +	struct drm_device *dev = dev_priv->dev;  	struct drm_connector *connector;  	const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };  	uint32_t unplug_mask, plug_mask, change_mask; @@ -949,8 +953,10 @@ nv50_display_irq_handler(struct drm_device *dev)  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	uint32_t delayed = 0; -	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) -		nv50_display_irq_hotplug(dev); +	if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { +		if (!work_pending(&dev_priv->hpd_work)) +			queue_work(dev_priv->wq, &dev_priv->hpd_work); +	}  	while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {  		uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index 3ae8d0725f6..581d405ac01 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -37,6 +37,7 @@  void nv50_display_irq_handler(struct drm_device *dev);  void nv50_display_irq_handler_bh(struct work_struct *work); +void nv50_display_irq_hotplug_bh(struct work_struct *work);  int nv50_display_init(struct drm_device *dev);  int nv50_display_create(struct drm_device *dev);  int nv50_display_destroy(struct drm_device *dev); diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c new file mode 100644 index 00000000000..a95e6941ba8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_fb.c @@ -0,0 +1,32 @@ +#include "drmP.h" +#include "drm.h" +#include "nouveau_drv.h" +#include "nouveau_drm.h" + +int +nv50_fb_init(struct drm_device *dev) +{ +	/* This is needed to get meaningful information from 100c90 +	 * on traps. No idea what these values mean exactly. */ +	struct drm_nouveau_private *dev_priv = dev->dev_private; + +	switch (dev_priv->chipset) { +	case 0x50: +		nv_wr32(dev, 0x100c90, 0x0707ff); +		break; +	case 0xa5: +	case 0xa8: +		nv_wr32(dev, 0x100c90, 0x0d0fff); +		break; +	default: +		nv_wr32(dev, 0x100c90, 0x1d07ff); +		break; +	} + +	return 0; +} + +void +nv50_fb_takedown(struct drm_device *dev) +{ +} diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 993c7126fbd..a8c70e7e918 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -157,8 +157,11 @@ nv50_fbcon_accel_init(struct fb_info *info)  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct nouveau_channel *chan = dev_priv->channel;  	struct nouveau_gpuobj *eng2d = NULL; +	uint64_t fb;  	int ret, format; +	fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base; +  	switch (info->var.bits_per_pixel) {  	case 8:  		format = 0xf3; @@ -233,7 +236,7 @@ nv50_fbcon_accel_init(struct fb_info *info)  	BEGIN_RING(chan, NvSub2D, 0x0808, 3);  	OUT_RING(chan, 0);  	OUT_RING(chan, 0); -	OUT_RING(chan, 0); +	OUT_RING(chan, 1);  	BEGIN_RING(chan, NvSub2D, 0x081c, 1);  	OUT_RING(chan, 1);  	BEGIN_RING(chan, NvSub2D, 0x0840, 4); @@ -248,9 +251,8 @@ nv50_fbcon_accel_init(struct fb_info *info)  	OUT_RING(chan, info->fix.line_length);  	OUT_RING(chan, info->var.xres_virtual);  	OUT_RING(chan, info->var.yres_virtual); -	OUT_RING(chan, 0); -	OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + -			 dev_priv->vm_vram_base); +	OUT_RING(chan, upper_32_bits(fb)); +	OUT_RING(chan, lower_32_bits(fb));  	BEGIN_RING(chan, NvSub2D, 0x0230, 2);  	OUT_RING(chan, format);  	OUT_RING(chan, 1); @@ -258,9 +260,8 @@ nv50_fbcon_accel_init(struct fb_info *info)  	OUT_RING(chan, info->fix.line_length);  	OUT_RING(chan, info->var.xres_virtual);  	OUT_RING(chan, info->var.yres_virtual); -	OUT_RING(chan, 0); -	OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + -			 dev_priv->vm_vram_base); +	OUT_RING(chan, upper_32_bits(fb)); +	OUT_RING(chan, lower_32_bits(fb));  	return 0;  } diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c new file mode 100644 index 00000000000..c61782b314e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -0,0 +1,76 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_hw.h" + +static int +nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift) +{ +	const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; + +	if (gpio->line > 32) +		return -EINVAL; + +	*reg = nv50_gpio_reg[gpio->line >> 3]; +	*shift = (gpio->line & 7) << 2; +	return 0; +} + +int +nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag) +{ +	struct dcb_gpio_entry *gpio; +	uint32_t r, s, v; + +	gpio = nouveau_bios_gpio_entry(dev, tag); +	if (!gpio) +		return -ENOENT; + +	if (nv50_gpio_location(gpio, &r, &s)) +		return -EINVAL; + +	v = nv_rd32(dev, r) >> (s + 2); +	return ((v & 1) == (gpio->state[1] & 1)); +} + +int +nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) +{ +	struct dcb_gpio_entry *gpio; +	uint32_t r, s, v; + +	gpio = nouveau_bios_gpio_entry(dev, tag); +	if (!gpio) +		return -ENOENT; + +	if (nv50_gpio_location(gpio, &r, &s)) +		return -EINVAL; + +	v  = nv_rd32(dev, r) & ~(0x3 << s); +	v |= (gpio->state[state] ^ 2) << s; +	nv_wr32(dev, r, v); +	return 0; +} diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 857a09671a3..b203d06f601 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -56,6 +56,10 @@ nv50_graph_init_intr(struct drm_device *dev)  static void  nv50_graph_init_regs__nv(struct drm_device *dev)  { +	struct drm_nouveau_private *dev_priv = dev->dev_private; +	uint32_t units = nv_rd32(dev, 0x1540); +	int i; +  	NV_DEBUG(dev, "\n");  	nv_wr32(dev, 0x400804, 0xc0000000); @@ -65,6 +69,20 @@ nv50_graph_init_regs__nv(struct drm_device *dev)  	nv_wr32(dev, 0x405018, 0xc0000000);  	nv_wr32(dev, 0x402000, 0xc0000000); +	for (i = 0; i < 16; i++) { +		if (units & 1 << i) { +			if (dev_priv->chipset < 0xa0) { +				nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000); +				nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000); +				nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000); +			} else { +				nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000); +				nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000); +				nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000); +			} +		} +	} +  	nv_wr32(dev, 0x400108, 0xffffffff);  	nv_wr32(dev, 0x400824, 0x00004000); @@ -229,10 +247,6 @@ nv50_graph_create_context(struct nouveau_channel *chan)  		nouveau_grctx_vals_load(dev, ctx);  	}  	nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); -	if ((dev_priv->chipset & 0xf0) == 0xa0) -		nv_wo32(dev, ctx, 0x00004/4, 0x00000000); -	else -		nv_wo32(dev, ctx, 0x0011c/4, 0x00000000);  	dev_priv->engine.instmem.finish_access(dev);  	return 0; @@ -396,9 +410,10 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {  	{ 0x5039, false, NULL }, /* m2mf */  	{ 0x502d, false, NULL }, /* 2d */  	{ 0x50c0, false, NULL }, /* compute */ +	{ 0x85c0, false, NULL }, /* compute (nva3, nva5, nva8) */  	{ 0x5097, false, NULL }, /* tesla (nv50) */ -	{ 0x8297, false, NULL }, /* tesla (nv80/nv90) */ -	{ 0x8397, false, NULL }, /* tesla (nva0) */ -	{ 0x8597, false, NULL }, /* tesla (nva8) */ +	{ 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */ +	{ 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */ +	{ 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */  	{}  }; diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c index d105fcd42ca..42a8fb20c1e 100644 --- a/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c @@ -55,15 +55,18 @@  #define CP_FLAG_AUTO_LOAD             ((2 * 32) + 5)  #define CP_FLAG_AUTO_LOAD_NOT_PENDING 0  #define CP_FLAG_AUTO_LOAD_PENDING     1 +#define CP_FLAG_NEWCTX                ((2 * 32) + 10) +#define CP_FLAG_NEWCTX_BUSY           0 +#define CP_FLAG_NEWCTX_DONE           1  #define CP_FLAG_XFER                  ((2 * 32) + 11)  #define CP_FLAG_XFER_IDLE             0  #define CP_FLAG_XFER_BUSY             1 -#define CP_FLAG_NEWCTX                ((2 * 32) + 12) -#define CP_FLAG_NEWCTX_BUSY           0 -#define CP_FLAG_NEWCTX_DONE           1  #define CP_FLAG_ALWAYS                ((2 * 32) + 13)  #define CP_FLAG_ALWAYS_FALSE          0  #define CP_FLAG_ALWAYS_TRUE           1 +#define CP_FLAG_INTR                  ((2 * 32) + 15) +#define CP_FLAG_INTR_NOT_PENDING      0 +#define CP_FLAG_INTR_PENDING          1  #define CP_CTX                   0x00100000  #define CP_CTX_COUNT             0x000f0000 @@ -174,6 +177,7 @@ nv50_grctx_init(struct nouveau_grctx *ctx)  	case 0x96:  	case 0x98:  	case 0xa0: +	case 0xa3:  	case 0xa5:  	case 0xa8:  	case 0xaa: @@ -214,6 +218,8 @@ nv50_grctx_init(struct nouveau_grctx *ctx)  	cp_name(ctx, cp_setup_save);  	cp_set (ctx, UNK1D, SET);  	cp_wait(ctx, STATUS, BUSY); +	cp_wait(ctx, INTR, PENDING); +	cp_bra (ctx, STATUS, BUSY, cp_setup_save);  	cp_set (ctx, UNK01, SET);  	cp_set (ctx, SWAP_DIRECTION, SAVE); @@ -269,7 +275,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  	int offset, base;  	uint32_t units = nv_rd32 (ctx->dev, 0x1540); -	/* 0800 */ +	/* 0800: DISPATCH */  	cp_ctx(ctx, 0x400808, 7);  	gr_def(ctx, 0x400814, 0x00000030);  	cp_ctx(ctx, 0x400834, 0x32); @@ -300,7 +306,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  		gr_def(ctx, 0x400b20, 0x0001629d);  	} -	/* 0C00 */ +	/* 0C00: VFETCH */  	cp_ctx(ctx, 0x400c08, 0x2);  	gr_def(ctx, 0x400c08, 0x0000fe0c); @@ -326,7 +332,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  	cp_ctx(ctx, 0x401540, 0x5);  	gr_def(ctx, 0x401550, 0x00001018); -	/* 1800 */ +	/* 1800: STREAMOUT */  	cp_ctx(ctx, 0x401814, 0x1);  	gr_def(ctx, 0x401814, 0x000000ff);  	if (dev_priv->chipset == 0x50) { @@ -359,6 +365,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  	case 0xac:  		gr_def(ctx, 0x401c00, 0x042500df);  		break; +	case 0xa3:  	case 0xa5:  	case 0xa8:  		gr_def(ctx, 0x401c00, 0x142500df); @@ -413,6 +420,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  		break;  	case 0x84:  	case 0xa0: +	case 0xa3:  	case 0xa5:  	case 0xa8:  	case 0xaa: @@ -641,7 +649,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  	if (dev_priv->chipset == 0x50)  		cp_ctx(ctx, 0x4063e0, 0x1); -	/* 6800 */ +	/* 6800: M2MF */  	if (dev_priv->chipset < 0x90) {  		cp_ctx(ctx, 0x406814, 0x2b);  		gr_def(ctx, 0x406818, 0x00000f80); @@ -787,6 +795,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  				case 0xa5:  					gr_def(ctx, offset + 0x1c, 0x310c0000);  					break; +				case 0xa3:  				case 0xa8:  				case 0xaa:  				case 0xac: @@ -854,6 +863,8 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)  			else  				gr_def(ctx, offset + 0x8, 0x05010202);  			gr_def(ctx, offset + 0xc, 0x00030201); +			if (dev_priv->chipset == 0xa3) +				cp_ctx(ctx, base + 0x36c, 1);  			cp_ctx(ctx, base + 0x400, 2);  			gr_def(ctx, base + 0x404, 0x00000040); @@ -1154,7 +1165,9 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)  		nv50_graph_construct_gene_unk8(ctx);  		if (dev_priv->chipset == 0xa0)  			xf_emit(ctx, 0x189, 0); -		else if (dev_priv->chipset < 0xa8) +		else if (dev_priv->chipset == 0xa3) +			xf_emit(ctx, 0xd5, 0); +		else if (dev_priv->chipset == 0xa5)  			xf_emit(ctx, 0x99, 0);  		else if (dev_priv->chipset == 0xaa)  			xf_emit(ctx, 0x65, 0); @@ -1192,6 +1205,8 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)  		ctx->ctxvals_pos = offset + 4;  		if (dev_priv->chipset == 0xa0)  			xf_emit(ctx, 0xa80, 0); +		else if (dev_priv->chipset == 0xa3) +			xf_emit(ctx, 0xa7c, 0);  		else  			xf_emit(ctx, 0xa7a, 0);  		xf_emit(ctx, 1, 0x3fffff); @@ -1336,6 +1351,7 @@ nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx)  		xf_emit(ctx, 0x942, 0);  		break;  	case 0xa0: +	case 0xa3:  		xf_emit(ctx, 0x2042, 0);  		break;  	case 0xa5: diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index de1f5b0062c..5f21df31f3a 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -63,9 +63,10 @@ nv50_instmem_init(struct drm_device *dev)  	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct nouveau_channel *chan;  	uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size; +	uint32_t save_nv001700; +	uint64_t v;  	struct nv50_instmem_priv *priv;  	int ret, i; -	uint32_t v, save_nv001700;  	priv = kzalloc(sizeof(*priv), GFP_KERNEL);  	if (!priv) @@ -76,17 +77,12 @@ nv50_instmem_init(struct drm_device *dev)  	for (i = 0x1700; i <= 0x1710; i += 4)  		priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); -	if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) -		dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; -	else -		dev_priv->vram_sys_base = 0; -  	/* Reserve the last MiB of VRAM, we should probably try to avoid  	 * setting up the below tables over the top of the VBIOS image at  	 * some point.  	 */  	dev_priv->ramin_rsvd_vram = 1 << 20; -	c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram; +	c_offset = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;  	c_size   = 128 << 10;  	c_vmpd   = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200;  	c_ramfc  = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20; @@ -106,7 +102,7 @@ nv50_instmem_init(struct drm_device *dev)  	dev_priv->vm_gart_size = NV50_VM_BLOCK;  	dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; -	dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev); +	dev_priv->vm_vram_size = dev_priv->vram_size;  	if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM)  		dev_priv->vm_vram_size = NV50_VM_MAX_VRAM;  	dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK); @@ -189,8 +185,8 @@ nv50_instmem_init(struct drm_device *dev)  	i = 0;  	while (v < dev_priv->vram_sys_base + c_offset + c_size) { -		BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v); -		BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); +		BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, lower_32_bits(v)); +		BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, upper_32_bits(v));  		v += 0x1000;  		i += 8;  	} diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index c2fff543b06..0c68698f23d 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c @@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,  			mode_ctl = 0x0200;  		break;  	case OUTPUT_DP: -		mode_ctl |= 0x00050000; +		mode_ctl |= (nv_encoder->dp.mc_unknown << 16);  		if (nv_encoder->dcb->sorconf.link & 1)  			mode_ctl |= 0x00000800;  		else @@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {  int  nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)  { +	struct drm_nouveau_private *dev_priv = dev->dev_private;  	struct nouveau_encoder *nv_encoder = NULL;  	struct drm_encoder *encoder;  	bool dum; @@ -319,5 +320,27 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)  	encoder->possible_crtcs = entry->heads;  	encoder->possible_clones = 0; +	if (nv_encoder->dcb->type == OUTPUT_DP) { +		uint32_t mc, or = nv_encoder->or; + +		if (dev_priv->chipset < 0x90 || +		    dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) +			mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or)); +		else +			mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or)); + +		switch ((mc & 0x00000f00) >> 8) { +		case 8: +		case 9: +			nv_encoder->dp.mc_unknown = (mc & 0x000f0000) >> 16; +			break; +		default: +			break; +		} + +		if (!nv_encoder->dp.mc_unknown) +			nv_encoder->dp.mc_unknown = 5; +	} +  	return 0;  } diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c index 4c39a407aa4..e671d0e74d4 100644 --- a/drivers/gpu/drm/r128/r128_cce.c +++ b/drivers/gpu/drm/r128/r128_cce.c @@ -31,6 +31,7 @@  #include <linux/firmware.h>  #include <linux/platform_device.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h" diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index ed38262d998..3c91312dea9 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -50,7 +50,7 @@ $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h  radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \  	radeon_irq.o r300_cmdbuf.o r600_cp.o  # add KMS driver -radeon-y += radeon_device.o radeon_kms.o \ +radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \  	radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \  	atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \  	radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \ diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index d75788feac6..1d569830ed9 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -24,6 +24,7 @@  #include <linux/module.h>  #include <linux/sched.h> +#include <linux/slab.h>  #include <asm/unaligned.h>  #define ATOM_DEBUG @@ -52,15 +53,17 @@  typedef struct {  	struct atom_context *ctx; -  	uint32_t *ps, *ws;  	int ps_shift;  	uint16_t start; +	unsigned last_jump; +	unsigned long last_jump_jiffies; +	bool abort;  } atom_exec_context;  int atom_debug = 0; -static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); -void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); +static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); +int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);  static uint32_t atom_arg_mask[8] =      { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, @@ -604,12 +607,17 @@ static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg)  static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)  {  	int idx = U8((*ptr)++); +	int r = 0; +  	if (idx < ATOM_TABLE_NAMES_CNT)  		SDEBUG("   table: %d (%s)\n", idx, atom_table_names[idx]);  	else  		SDEBUG("   table: %d\n", idx);  	if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) -		atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); +		r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); +	if (r) { +		ctx->abort = true; +	}  }  static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) @@ -673,6 +681,8 @@ static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg)  static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)  {  	int execute = 0, target = U16(*ptr); +	unsigned long cjiffies; +  	(*ptr) += 2;  	switch (arg) {  	case ATOM_COND_ABOVE: @@ -700,8 +710,25 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)  	if (arg != ATOM_COND_ALWAYS)  		SDEBUG("   taken: %s\n", execute ? "yes" : "no");  	SDEBUG("   target: 0x%04X\n", target); -	if (execute) +	if (execute) { +		if (ctx->last_jump == (ctx->start + target)) { +			cjiffies = jiffies; +			if (time_after(cjiffies, ctx->last_jump_jiffies)) { +				cjiffies -= ctx->last_jump_jiffies; +				if ((jiffies_to_msecs(cjiffies) > 1000)) { +					DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n"); +					ctx->abort = true; +				} +			} else { +				/* jiffies wrap around we will just wait a little longer */ +				ctx->last_jump_jiffies = jiffies; +			} +		} else { +			ctx->last_jump = ctx->start + target; +			ctx->last_jump_jiffies = jiffies; +		}  		*ptr = ctx->start + target; +	}  }  static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) @@ -881,11 +908,16 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)  	uint8_t attr = U8((*ptr)++), shift;  	uint32_t saved, dst;  	int dptr = *ptr; +	uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];  	SDEBUG("   dst: ");  	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); +	/* op needs to full dst value */ +	dst = saved;  	shift = atom_get_src(ctx, attr, ptr);  	SDEBUG("   shift: %d\n", shift);  	dst <<= shift; +	dst &= atom_arg_mask[dst_align]; +	dst >>= atom_arg_shift[dst_align];  	SDEBUG("   dst: ");  	atom_put_dst(ctx, arg, attr, &dptr, dst, saved);  } @@ -895,11 +927,16 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)  	uint8_t attr = U8((*ptr)++), shift;  	uint32_t saved, dst;  	int dptr = *ptr; +	uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];  	SDEBUG("   dst: ");  	dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); +	/* op needs to full dst value */ +	dst = saved;  	shift = atom_get_src(ctx, attr, ptr);  	SDEBUG("   shift: %d\n", shift);  	dst >>= shift; +	dst &= atom_arg_mask[dst_align]; +	dst >>= atom_arg_shift[dst_align];  	SDEBUG("   dst: ");  	atom_put_dst(ctx, arg, attr, &dptr, dst, saved);  } @@ -1104,15 +1141,16 @@ static struct {  	atom_op_shr, ATOM_ARG_MC}, {  atom_op_debug, 0},}; -static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) +static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)  {  	int base = CU16(ctx->cmd_table + 4 + 2 * index);  	int len, ws, ps, ptr;  	unsigned char op;  	atom_exec_context ectx; +	int ret = 0;  	if (!base) -		return; +		return -EINVAL;  	len = CU16(base + ATOM_CT_SIZE_PTR);  	ws = CU8(base + ATOM_CT_WS_PTR); @@ -1125,6 +1163,8 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3  	ectx.ps_shift = ps / 4;  	ectx.start = base;  	ectx.ps = params; +	ectx.abort = false; +	ectx.last_jump = 0;  	if (ws)  		ectx.ws = kzalloc(4 * ws, GFP_KERNEL);  	else @@ -1137,6 +1177,12 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3  			SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1);  		else  			SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1); +		if (ectx.abort) { +			DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n", +				base, len, ws, ps, ptr - 1); +			ret = -EINVAL; +			goto free; +		}  		if (op < ATOM_OP_CNT && op > 0)  			opcode_table[op].func(&ectx, &ptr, @@ -1150,12 +1196,16 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3  	debug_depth--;  	SDEBUG("<<\n"); +free:  	if (ws)  		kfree(ectx.ws); +	return ret;  } -void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) +int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)  { +	int r; +  	mutex_lock(&ctx->mutex);  	/* reset reg block */  	ctx->reg_block = 0; @@ -1163,8 +1213,9 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)  	ctx->fb_base = 0;  	/* reset io mode */  	ctx->io_mode = ATOM_IO_MM; -	atom_execute_table_locked(ctx, index, params); +	r = atom_execute_table_locked(ctx, index, params);  	mutex_unlock(&ctx->mutex); +	return r;  }  static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; @@ -1248,9 +1299,7 @@ int atom_asic_init(struct atom_context *ctx)  	if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))  		return 1; -	atom_execute_table(ctx, ATOM_CMD_INIT, ps); - -	return 0; +	return atom_execute_table(ctx, ATOM_CMD_INIT, ps);  }  void atom_destroy(struct atom_context *ctx) @@ -1260,12 +1309,16 @@ void atom_destroy(struct atom_context *ctx)  	kfree(ctx);  } -void atom_parse_data_header(struct atom_context *ctx, int index, +bool atom_parse_data_header(struct atom_context *ctx, int index,  			    uint16_t * size, uint8_t * frev, uint8_t * crev,  			    uint16_t * data_start)  {  	int offset = index * 2 + 4;  	int idx = CU16(ctx->data_table + offset); +	u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4); + +	if (!mdt[index]) +		return false;  	if (size)  		*size = CU16(idx); @@ -1274,38 +1327,42 @@ void atom_parse_data_header(struct atom_context *ctx, int index,  	if (crev)  		*crev = CU8(idx + 3);  	*data_start = idx; -	return; +	return true;  } -void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, +bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,  			   uint8_t * crev)  {  	int offset = index * 2 + 4;  	int idx = CU16(ctx->cmd_table + offset); +	u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4); + +	if (!mct[index]) +		return false;  	if (frev)  		*frev = CU8(idx + 2);  	if (crev)  		*crev = CU8(idx + 3); -	return; +	return true;  }  int atom_allocate_fb_scratch(struct atom_context *ctx)  {  	int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);  	uint16_t data_offset; -	int usage_bytes; +	int usage_bytes = 0;  	struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; -	atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); +	if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { +		firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); -	firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); +		DRM_DEBUG("atom firmware requested %08x %dkb\n", +			  firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, +			  firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); -	DRM_DEBUG("atom firmware requested %08x %dkb\n", -		  firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, -		  firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); - -	usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; +		usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; +	}  	if (usage_bytes == 0)  		usage_bytes = 20 * 1024;  	/* allocate some scratch memory */ diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index bc73781423a..cd1b64ab5ca 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h @@ -140,11 +140,13 @@ struct atom_context {  extern int atom_debug;  struct atom_context *atom_parse(struct card_info *, void *); -void atom_execute_table(struct atom_context *, int, uint32_t *); +int atom_execute_table(struct atom_context *, int, uint32_t *);  int atom_asic_init(struct atom_context *);  void atom_destroy(struct atom_context *); -void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); -void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); +bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, +			    uint8_t *frev, uint8_t *crev, uint16_t *data_start); +bool atom_parse_cmd_header(struct atom_context *ctx, int index, +			   uint8_t *frev, uint8_t *crev);  int atom_allocate_fb_scratch(struct atom_context *ctx);  #include "atom-types.h"  #include "atombios.h" diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 6732b5dd8ff..27e2c715be1 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -2912,7 +2912,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2    UCHAR                    ucTV_BootUpDefaultStandard;     UCHAR                    ucExt_TV_ASIC_ID;    UCHAR                    ucExt_TV_ASIC_SlaveAddr; -  ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING]; +  ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING_V1_2];  }ATOM_ANALOG_TV_INFO_V1_2;  typedef struct _ATOM_DPCD_INFO diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index dd9fdf56061..a87990b3ae8 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -353,12 +353,55 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,  	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);  } +static void atombios_disable_ss(struct drm_crtc *crtc) +{ +	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); +	struct drm_device *dev = crtc->dev; +	struct radeon_device *rdev = dev->dev_private; +	u32 ss_cntl; + +	if (ASIC_IS_DCE4(rdev)) { +		switch (radeon_crtc->pll_id) { +		case ATOM_PPLL1: +			ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); +			ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; +			WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl); +			break; +		case ATOM_PPLL2: +			ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL); +			ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; +			WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl); +			break; +		case ATOM_DCPLL: +		case ATOM_PPLL_INVALID: +			return; +		} +	} else if (ASIC_IS_AVIVO(rdev)) { +		switch (radeon_crtc->pll_id) { +		case ATOM_PPLL1: +			ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); +			ss_cntl &= ~1; +			WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl); +			break; +		case ATOM_PPLL2: +			ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL); +			ss_cntl &= ~1; +			WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl); +			break; +		case ATOM_DCPLL: +		case ATOM_PPLL_INVALID: +			return; +		} +	} +} + +  union atom_enable_ss {  	ENABLE_LVDS_SS_PARAMETERS legacy;  	ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;  }; -static void atombios_set_ss(struct drm_crtc *crtc, int enable) +static void atombios_enable_ss(struct drm_crtc *crtc)  {  	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);  	struct drm_device *dev = crtc->dev; @@ -387,9 +430,9 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)  					step = dig->ss->step;  					delay = dig->ss->delay;  					range = dig->ss->range; -				} else if (enable) +				} else  					return; -			} else if (enable) +			} else  				return;  			break;  		} @@ -406,13 +449,13 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)  		args.v1.ucSpreadSpectrumDelay = delay;  		args.v1.ucSpreadSpectrumRange = range;  		args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; -		args.v1.ucEnable = enable; +		args.v1.ucEnable = ATOM_ENABLE;  	} else {  		args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage);  		args.legacy.ucSpreadSpectrumType = type;  		args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;  		args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; -		args.legacy.ucEnable = enable; +		args.legacy.ucEnable = ATOM_ENABLE;  	}  	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);  } @@ -478,10 +521,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,  				/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */  				if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)  					adjusted_clock = mode->clock * 2; -				/* LVDS PLL quirks */ -				if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { -					struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; -					pll->algo = dig->pll_algo; +				if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { +					pll->algo = PLL_ALGO_LEGACY; +					pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;  				}  			} else {  				if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) @@ -503,8 +545,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,  		int index;  		index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); -		atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, -				      &crev); +		if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, +					   &crev)) +			return adjusted_clock;  		memset(&args, 0, sizeof(args)); @@ -542,11 +585,16 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,  					}  				} else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {  					/* may want to enable SS on DP/eDP eventually */ -					args.v3.sInput.ucDispPllConfig |= -						DISPPLL_CONFIG_SS_ENABLE; -					if (mode->clock > 165000) +					/*args.v3.sInput.ucDispPllConfig |= +						DISPPLL_CONFIG_SS_ENABLE;*/ +					if (encoder_mode == ATOM_ENCODER_MODE_DP)  						args.v3.sInput.ucDispPllConfig |= -							DISPPLL_CONFIG_DUAL_LINK; +							DISPPLL_CONFIG_COHERENT_MODE; +					else { +						if (mode->clock > 165000) +							args.v3.sInput.ucDispPllConfig |= +								DISPPLL_CONFIG_DUAL_LINK; +					}  				}  				atom_execute_table(rdev->mode_info.atom_context,  						   index, (uint32_t *)&args); @@ -592,8 +640,9 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)  	memset(&args, 0, sizeof(args));  	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); -	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, -			      &crev); +	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, +				   &crev)) +		return;  	switch (frev) {  	case 1: @@ -667,8 +716,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode  			   &ref_div, &post_div);  	index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); -	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, -			      &crev); +	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, +				   &crev)) +		return;  	switch (frev) {  	case 1: @@ -1083,15 +1133,12 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,  	/* TODO color tiling */ -	/* pick pll */ -	radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); - -	atombios_set_ss(crtc, 0); +	atombios_disable_ss(crtc);  	/* always set DCPLL */  	if (ASIC_IS_DCE4(rdev))  		atombios_crtc_set_dcpll(crtc);  	atombios_crtc_set_pll(crtc, adjusted_mode); -	atombios_set_ss(crtc, 1); +	atombios_enable_ss(crtc);  	if (ASIC_IS_DCE4(rdev))  		atombios_set_crtc_dtd_timing(crtc, adjusted_mode); @@ -1120,6 +1167,11 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,  static void atombios_crtc_prepare(struct drm_crtc *crtc)  { +	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + +	/* pick pll */ +	radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); +  	atombios_lock_crtc(crtc, ATOM_ENABLE);  	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);  } diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 8a133bda00a..28b31c64f48 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -745,14 +745,14 @@ void dp_link_train(struct drm_encoder *encoder,  			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT);  	/* disable the training pattern on the sink */ +	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE); + +	/* disable the training pattern on the source */  	if (ASIC_IS_DCE4(rdev))  		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);  	else  		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,  					  dig_connector->dp_clock, enc_id, 0); - -	radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, -				  dig_connector->dp_clock, enc_id, 0);  }  int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index bd2e7aa85c1..e8f447e2050 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -23,8 +23,10 @@   */  #include <linux/firmware.h>  #include <linux/platform_device.h> +#include <linux/slab.h>  #include "drmP.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "radeon_drm.h"  #include "rv770d.h"  #include "atom.h" @@ -436,7 +438,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev)  int evergreen_mc_init(struct radeon_device *rdev)  { -	fixed20_12 a;  	u32 tmp;  	int chansize, numchan; @@ -481,12 +482,8 @@ int evergreen_mc_init(struct radeon_device *rdev)  		rdev->mc.real_vram_size = rdev->mc.aper_size;  	}  	r600_vram_gtt_location(rdev, &rdev->mc); -	/* FIXME: we should enforce default clock in case GPU is not in -	 * default setup -	 */ -	a.full = rfixed_const(100); -	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); -	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); +	radeon_update_bandwidth_info(rdev); +  	return 0;  } @@ -746,6 +743,7 @@ int evergreen_init(struct radeon_device *rdev)  void evergreen_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	evergreen_suspend(rdev);  #if 0  	r600_blit_fini(rdev); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 91eb762eb3f..cf60c0b3ef1 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -26,11 +26,13 @@   *          Jerome Glisse   */  #include <linux/seq_file.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "radeon_drm.h"  #include "radeon_reg.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "r100d.h"  #include "rs100d.h"  #include "rv200d.h" @@ -235,9 +237,9 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)  void r100_pci_gart_fini(struct radeon_device *rdev)  { +	radeon_gart_fini(rdev);  	r100_pci_gart_disable(rdev);  	radeon_gart_table_ram_free(rdev); -	radeon_gart_fini(rdev);  }  int r100_irq_set(struct radeon_device *rdev) @@ -312,10 +314,12 @@ int r100_irq_process(struct radeon_device *rdev)  		/* Vertical blank interrupts */  		if (status & RADEON_CRTC_VBLANK_STAT) {  			drm_handle_vblank(rdev->ddev, 0); +			rdev->pm.vblank_sync = true;  			wake_up(&rdev->irq.vblank_queue);  		}  		if (status & RADEON_CRTC2_VBLANK_STAT) {  			drm_handle_vblank(rdev->ddev, 1); +			rdev->pm.vblank_sync = true;  			wake_up(&rdev->irq.vblank_queue);  		}  		if (status & RADEON_FP_DETECT_STAT) { @@ -741,6 +745,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)  	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) | @@ -1804,6 +1810,7 @@ void r100_set_common_regs(struct radeon_device *rdev)  {  	struct drm_device *dev = rdev->ddev;  	bool force_dac2 = false; +	u32 tmp;  	/* set these so they don't interfere with anything */  	WREG32(RADEON_OV0_SCALE_CNTL, 0); @@ -1875,6 +1882,12 @@ void r100_set_common_regs(struct radeon_device *rdev)  		WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);  		WREG32(RADEON_DAC_CNTL2, dac2_cntl);  	} + +	/* switch PM block to ACPI mode */ +	tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL); +	tmp &= ~RADEON_PM_MODE_SEL; +	WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); +  }  /* @@ -2022,6 +2035,7 @@ void r100_mc_init(struct radeon_device *rdev)  	radeon_vram_location(rdev, &rdev->mc, base);  	if (!(rdev->flags & RADEON_IS_AGP))  		radeon_gtt_location(rdev, &rdev->mc); +	radeon_update_bandwidth_info(rdev);  } @@ -2385,6 +2399,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)  	uint32_t pixel_bytes1 = 0;  	uint32_t pixel_bytes2 = 0; +	radeon_update_display_priority(rdev); +  	if (rdev->mode_info.crtcs[0]->base.enabled) {  		mode1 = &rdev->mode_info.crtcs[0]->base.mode;  		pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; @@ -2413,11 +2429,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)  	/*  	 * determine is there is enough bw for current mode  	 */ -	mclk_ff.full = rfixed_const(rdev->clock.default_mclk); -	temp_ff.full = rfixed_const(100); -	mclk_ff.full = rfixed_div(mclk_ff, temp_ff); -	sclk_ff.full = rfixed_const(rdev->clock.default_sclk); -	sclk_ff.full = rfixed_div(sclk_ff, temp_ff); +	sclk_ff = rdev->pm.sclk; +	mclk_ff = rdev->pm.mclk;  	temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);  	temp_ff.full = rfixed_const(temp); @@ -2878,7 +2891,7 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,  {  	struct radeon_bo *robj;  	unsigned long size; -	unsigned u, i, w, h; +	unsigned u, i, w, h, d;  	int ret;  	for (u = 0; u < track->num_texture; u++) { @@ -2910,20 +2923,25 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,  			h = h / (1 << i);  			if (track->textures[u].roundup_h)  				h = roundup_pow_of_two(h); +			if (track->textures[u].tex_coord_type == 1) { +				d = (1 << track->textures[u].txdepth) / (1 << i); +				if (!d) +					d = 1; +			} else { +				d = 1; +			}  			if (track->textures[u].compress_format) { -				size += r100_track_compress_size(track->textures[u].compress_format, w, h); +				size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d;  				/* compressed textures are block based */  			} else -				size += w * h; +				size += w * h * d;  		}  		size *= track->textures[u].cpp;  		switch (track->textures[u].tex_coord_type) {  		case 0: -			break;  		case 1: -			size *= (1 << track->textures[u].txdepth);  			break;  		case 2:  			if (track->separate_cube) { @@ -2957,7 +2975,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)  	for (i = 0; i < track->num_cb; i++) {  		if (track->cb[i].robj == NULL) { -			if (!(track->fastfill || track->color_channel_mask || +			if (!(track->zb_cb_clear || track->color_channel_mask ||  			      track->blend_read_enable)) {  				continue;  			} @@ -2994,7 +3012,11 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)  		}  	}  	prim_walk = (track->vap_vf_cntl >> 4) & 0x3; -	nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; +	if (track->vap_vf_cntl & (1 << 14)) { +		nverts = track->vap_alt_nverts; +	} else { +		nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; +	}  	switch (prim_walk) {  	case 1:  		for (i = 0; i < track->num_arrays; i++) { @@ -3440,6 +3462,7 @@ int r100_suspend(struct radeon_device *rdev)  void r100_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r100_cp_fini(rdev);  	r100_wb_fini(rdev);  	r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index b27a6999d21..f47cdca1c00 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -64,6 +64,7 @@ struct r100_cs_track {  	unsigned			maxy;  	unsigned			vtx_size;  	unsigned			vap_vf_cntl; +	unsigned			vap_alt_nverts;  	unsigned			immd_dwords;  	unsigned			num_arrays;  	unsigned			max_indx; @@ -74,7 +75,7 @@ struct r100_cs_track {  	struct r100_cs_track_texture	textures[R300_TRACK_MAX_TEXTURE];  	bool				z_enabled;  	bool                            separate_cube; -	bool				fastfill; +	bool				zb_cb_clear;  	bool				blend_read_enable;  }; diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 1146c9909c2..85617c31121 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -30,6 +30,7 @@  #include "radeon_drm.h"  #include "radeon_reg.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "r100d.h"  #include "r200_reg_safe.h" diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 4cef90cd74e..a5ff8076b42 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -26,10 +26,12 @@   *          Jerome Glisse   */  #include <linux/seq_file.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "radeon_reg.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "radeon_drm.h"  #include "r100_track.h"  #include "r300d.h" @@ -164,9 +166,9 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)  void rv370_pcie_gart_fini(struct radeon_device *rdev)  { +	radeon_gart_fini(rdev);  	rv370_pcie_gart_disable(rdev);  	radeon_gart_table_vram_free(rdev); -	radeon_gart_fini(rdev);  }  void r300_fence_ring_emit(struct radeon_device *rdev, @@ -322,12 +324,12 @@ void r300_gpu_init(struct radeon_device *rdev)  	uint32_t gb_tile_config, tmp;  	r100_hdp_reset(rdev); -	/* FIXME: rv380 one pipes ? */ -	if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) { +	if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) || +	    (rdev->family == CHIP_R350 && rdev->pdev->device != 0x4148)) {  		/* r300,r350 */  		rdev->num_gb_pipes = 2;  	} else { -		/* rv350,rv370,rv380 */ +		/* rv350,rv370,rv380,r300 AD, r350 AH */  		rdev->num_gb_pipes = 1;  	}  	rdev->num_z_pipes = 1; @@ -481,6 +483,7 @@ void r300_mc_init(struct radeon_device *rdev)  	radeon_vram_location(rdev, &rdev->mc, base);  	if (!(rdev->flags & RADEON_IS_AGP))  		radeon_gtt_location(rdev, &rdev->mc); +	radeon_update_bandwidth_info(rdev);  }  void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes) @@ -726,6 +729,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  		/* VAP_VF_MAX_VTX_INDX */  		track->max_indx = idx_value & 0x00FFFFFFUL;  		break; +	case 0x2088: +		/* VAP_ALT_NUM_VERTICES - only valid on r500 */ +		if (p->rdev->family < CHIP_RV515) +			goto fail; +		track->vap_alt_nverts = idx_value & 0xFFFFFF; +		break;  	case 0x43E4:  		/* SC_SCISSOR1 */  		track->maxy = ((idx_value >> 13) & 0x1FFF) + 1; @@ -763,7 +772,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  		tmp = idx_value & ~(0x7 << 16);  		tmp |= tile_flags;  		ib[idx] = tmp; -  		i = (reg - 0x4E38) >> 2;  		track->cb[i].pitch = idx_value & 0x3FFE;  		switch (((idx_value >> 21) & 0xF)) { @@ -1036,7 +1044,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  		break;  	case 0x4d1c:  		/* ZB_BW_CNTL */ -		track->fastfill = !!(idx_value & (1 << 2)); +		track->zb_cb_clear = !!(idx_value & (1 << 5));  		break;  	case 0x4e04:  		/* RB3D_BLENDCNTL */ @@ -1048,11 +1056,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p,  			break;  		/* fallthrough do not move */  	default: -		printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", -		       reg, idx); -		return -EINVAL; +		goto fail;  	}  	return 0; +fail: +	printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", +	       reg, idx); +	return -EINVAL;  }  static int r300_packet3_check(struct radeon_cs_parser *p, @@ -1334,6 +1344,7 @@ int r300_suspend(struct radeon_device *rdev)  void r300_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r100_cp_fini(rdev);  	r100_wb_fini(rdev);  	r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c index ea46d558e8f..c5c2742e414 100644 --- a/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c @@ -921,7 +921,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,  	ptr_addr = drm_buffer_read_object(cmdbuf->buffer,  			sizeof(stack_ptr_addr), &stack_ptr_addr); -	ref_age_base = (u32 *)(unsigned long)*ptr_addr; +	ref_age_base = (u32 *)(unsigned long)get_unaligned(ptr_addr);  	for (i=0; i < header.scratch.n_bufs; i++) {  		buf_idx = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0); diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index c7593b8f58e..c2bda4ad62e 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -26,9 +26,11 @@   *          Jerome Glisse   */  #include <linux/seq_file.h> +#include <linux/slab.h>  #include "drmP.h"  #include "radeon_reg.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "atom.h"  #include "r100d.h"  #include "r420d.h" @@ -57,6 +59,12 @@ void r420_pipes_init(struct radeon_device *rdev)  	/* get max number of pipes */  	gb_pipe_select = RREG32(0x402C);  	num_pipes = ((gb_pipe_select >> 12) & 3) + 1; + +	/* SE chips have 1 pipe */ +	if ((rdev->pdev->device == 0x5e4c) || +	    (rdev->pdev->device == 0x5e4f)) +		num_pipes = 1; +  	rdev->num_gb_pipes = num_pipes;  	tmp = 0;  	switch (num_pipes) { @@ -266,6 +274,7 @@ int r420_suspend(struct radeon_device *rdev)  void r420_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r100_cp_fini(rdev);  	r100_wb_fini(rdev);  	r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 2b8a5dd1351..3c44b8d3931 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -27,6 +27,7 @@   */  #include "drmP.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "atom.h"  #include "r520d.h" @@ -121,19 +122,13 @@ static void r520_vram_get_type(struct radeon_device *rdev)  void r520_mc_init(struct radeon_device *rdev)  { -	fixed20_12 a;  	r520_vram_get_type(rdev);  	r100_vram_init_sizes(rdev);  	radeon_vram_location(rdev, &rdev->mc, 0);  	if (!(rdev->flags & RADEON_IS_AGP))  		radeon_gtt_location(rdev, &rdev->mc); -	/* FIXME: we should enforce default clock in case GPU is not in -	 * default setup -	 */ -	a.full = rfixed_const(100); -	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); -	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); +	radeon_update_bandwidth_info(rdev);  }  void r520_mc_program(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c5229019729..8f3454e2056 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -25,12 +25,14 @@   *          Alex Deucher   *          Jerome Glisse   */ +#include <linux/slab.h>  #include <linux/seq_file.h>  #include <linux/firmware.h>  #include <linux/platform_device.h>  #include "drmP.h"  #include "radeon_drm.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "radeon_mode.h"  #include "r600d.h"  #include "atom.h" @@ -491,9 +493,9 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)  void r600_pcie_gart_fini(struct radeon_device *rdev)  { +	radeon_gart_fini(rdev);  	r600_pcie_gart_disable(rdev);  	radeon_gart_table_vram_free(rdev); -	radeon_gart_fini(rdev);  }  void r600_agp_enable(struct radeon_device *rdev) @@ -675,7 +677,6 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)  int r600_mc_init(struct radeon_device *rdev)  { -	fixed20_12 a;  	u32 tmp;  	int chansize, numchan; @@ -719,14 +720,10 @@ int r600_mc_init(struct radeon_device *rdev)  		rdev->mc.real_vram_size = rdev->mc.aper_size;  	}  	r600_vram_gtt_location(rdev, &rdev->mc); -	/* FIXME: we should enforce default clock in case GPU is not in -	 * default setup -	 */ -	a.full = rfixed_const(100); -	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); -	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); +  	if (rdev->flags & RADEON_IS_IGP)  		rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); +	radeon_update_bandwidth_info(rdev);  	return 0;  } @@ -1132,6 +1129,7 @@ void r600_gpu_init(struct radeon_device *rdev)  	/* Setup pipes */  	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);  	tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);  	WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); @@ -2119,6 +2117,7 @@ int r600_init(struct radeon_device *rdev)  void r600_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r600_audio_fini(rdev);  	r600_blit_fini(rdev);  	r600_cp_fini(rdev); @@ -2398,19 +2397,19 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev)  		WREG32(DC_HPD4_INT_CONTROL, tmp);  		if (ASIC_IS_DCE32(rdev)) {  			tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; -			WREG32(DC_HPD5_INT_CONTROL, 0); +			WREG32(DC_HPD5_INT_CONTROL, tmp);  			tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; -			WREG32(DC_HPD6_INT_CONTROL, 0); +			WREG32(DC_HPD6_INT_CONTROL, tmp);  		}  	} else {  		WREG32(DACA_AUTODETECT_INT_CONTROL, 0);  		WREG32(DACB_AUTODETECT_INT_CONTROL, 0);  		tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; -		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0); +		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);  		tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; -		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0); +		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);  		tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; -		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0); +		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);  	}  } @@ -2765,6 +2764,7 @@ restart_ih:  			case 0: /* D1 vblank */  				if (disp_int & LB_D1_VBLANK_INTERRUPT) {  					drm_handle_vblank(rdev->ddev, 0); +					rdev->pm.vblank_sync = true;  					wake_up(&rdev->irq.vblank_queue);  					disp_int &= ~LB_D1_VBLANK_INTERRUPT;  					DRM_DEBUG("IH: D1 vblank\n"); @@ -2786,6 +2786,7 @@ restart_ih:  			case 0: /* D2 vblank */  				if (disp_int & LB_D2_VBLANK_INTERRUPT) {  					drm_handle_vblank(rdev->ddev, 1); +					rdev->pm.vblank_sync = true;  					wake_up(&rdev->irq.vblank_queue);  					disp_int &= ~LB_D2_VBLANK_INTERRUPT;  					DRM_DEBUG("IH: D2 vblank\n"); @@ -2834,14 +2835,14 @@ restart_ih:  				break;  			case 10:  				if (disp_int_cont2 & DC_HPD5_INTERRUPT) { -					disp_int_cont &= ~DC_HPD5_INTERRUPT; +					disp_int_cont2 &= ~DC_HPD5_INTERRUPT;  					queue_hotplug = true;  					DRM_DEBUG("IH: HPD5\n");  				}  				break;  			case 12:  				if (disp_int_cont2 & DC_HPD6_INTERRUPT) { -					disp_int_cont &= ~DC_HPD6_INTERRUPT; +					disp_int_cont2 &= ~DC_HPD6_INTERRUPT;  					queue_hotplug = true;  					DRM_DEBUG("IH: HPD6\n");  				} diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index db928016d03..1d898051c63 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -35,7 +35,7 @@   */  static int r600_audio_chipset_supported(struct radeon_device *rdev)  { -	return rdev->family >= CHIP_R600 +	return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR)  		|| rdev->family == CHIP_RS600  		|| rdev->family == CHIP_RS690  		|| rdev->family == CHIP_RS740; @@ -182,41 +182,6 @@ int r600_audio_init(struct radeon_device *rdev)  }  /* - * determin how the encoders and audio interface is wired together - */ -int r600_audio_tmds_index(struct drm_encoder *encoder) -{ -	struct drm_device *dev = encoder->dev; -	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -	struct drm_encoder *other; - -	switch (radeon_encoder->encoder_id) { -	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: -		return 0; - -	case ENCODER_OBJECT_ID_INTERNAL_LVTM1: -		/* special case check if an TMDS1 is present */ -		list_for_each_entry(other, &dev->mode_config.encoder_list, head) { -			if (to_radeon_encoder(other)->encoder_id == -				ENCODER_OBJECT_ID_INTERNAL_TMDS1) -				return 1; -		} -		return 0; - -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: -	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: -		return 1; - -	default: -		DRM_ERROR("Unsupported encoder type 0x%02X\n", -			  radeon_encoder->encoder_id); -		return -1; -	} -} - -/*   * atach the audio codec to the clock source of the encoder   */  void r600_audio_set_clock(struct drm_encoder *encoder, int clock) @@ -224,6 +189,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)  	struct drm_device *dev = encoder->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); +	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;  	int base_rate = 48000;  	switch (radeon_encoder->encoder_id) { @@ -231,32 +197,34 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)  	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:  		WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);  		break; -  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:  	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:  	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:  		WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);  		break; -  	default:  		DRM_ERROR("Unsupported encoder type 0x%02X\n",  			  radeon_encoder->encoder_id);  		return;  	} -	switch (r600_audio_tmds_index(encoder)) { +	switch (dig->dig_encoder) {  	case 0: -		WREG32(R600_AUDIO_PLL1_MUL, base_rate*50); -		WREG32(R600_AUDIO_PLL1_DIV, clock*100); +		WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50); +		WREG32(R600_AUDIO_PLL1_DIV, clock * 100);  		WREG32(R600_AUDIO_CLK_SRCSEL, 0);  		break;  	case 1: -		WREG32(R600_AUDIO_PLL2_MUL, base_rate*50); -		WREG32(R600_AUDIO_PLL2_DIV, clock*100); +		WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50); +		WREG32(R600_AUDIO_PLL2_DIV, clock * 100);  		WREG32(R600_AUDIO_CLK_SRCSEL, 1);  		break; +	default: +		dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n", +			  radeon_encoder->encoder_id); +		return;  	}  } diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index a112c59f9d8..0271b53fa2d 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -1,7 +1,42 @@ +/* + * Copyright 2009 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + *     Alex Deucher <alexander.deucher@amd.com> + */  #include <linux/types.h>  #include <linux/kernel.h> +/* + * R6xx+ cards need to use the 3D engine to blit data which requires + * quite a bit of hw state setup.  Rather than pull the whole 3D driver + * (which normally generates the 3D state) into the DRM, we opt to use + * statically generated state tables.  The regsiter state and shaders + * were hand generated to support blitting functionality.  See the 3D + * driver or documentation for descriptions of the registers and + * shader instructions. + */ +  const u32 r6xx_default_state[] =  {  	0xc0002400, diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 40416c068d9..68e6f434930 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c @@ -1548,10 +1548,13 @@ static void r700_gfx_init(struct drm_device *dev,  	RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);  	RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config); +	RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);  	RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);  	RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0);  	RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0); +	RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0); +	RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0);  	num_qd_pipes =  		R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8); diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index cd2c63bce50..c39c1bc1301 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -45,6 +45,7 @@ struct r600_cs_track {  	u32			nbanks;  	u32			npipes;  	/* value we track */ +	u32			sq_config;  	u32			nsamples;  	u32			cb_color_base_last[8];  	struct radeon_bo	*cb_color_bo[8]; @@ -141,6 +142,8 @@ static void r600_cs_track_init(struct r600_cs_track *track)  {  	int i; +	/* assume DX9 mode */ +	track->sq_config = DX9_CONSTS;  	for (i = 0; i < 8; i++) {  		track->cb_color_base_last[i] = 0;  		track->cb_color_size[i] = 0; @@ -715,6 +718,9 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx  		tmp =radeon_get_ib_value(p, idx);  		ib[idx] = 0;  		break; +	case SQ_CONFIG: +		track->sq_config = radeon_get_ib_value(p, idx); +		break;  	case R_028800_DB_DEPTH_CONTROL:  		track->db_depth_control = radeon_get_ib_value(p, idx);  		break; @@ -869,6 +875,54 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx  	case SQ_PGM_START_VS:  	case SQ_PGM_START_GS:  	case SQ_PGM_START_PS: +	case SQ_ALU_CONST_CACHE_GS_0: +	case SQ_ALU_CONST_CACHE_GS_1: +	case SQ_ALU_CONST_CACHE_GS_2: +	case SQ_ALU_CONST_CACHE_GS_3: +	case SQ_ALU_CONST_CACHE_GS_4: +	case SQ_ALU_CONST_CACHE_GS_5: +	case SQ_ALU_CONST_CACHE_GS_6: +	case SQ_ALU_CONST_CACHE_GS_7: +	case SQ_ALU_CONST_CACHE_GS_8: +	case SQ_ALU_CONST_CACHE_GS_9: +	case SQ_ALU_CONST_CACHE_GS_10: +	case SQ_ALU_CONST_CACHE_GS_11: +	case SQ_ALU_CONST_CACHE_GS_12: +	case SQ_ALU_CONST_CACHE_GS_13: +	case SQ_ALU_CONST_CACHE_GS_14: +	case SQ_ALU_CONST_CACHE_GS_15: +	case SQ_ALU_CONST_CACHE_PS_0: +	case SQ_ALU_CONST_CACHE_PS_1: +	case SQ_ALU_CONST_CACHE_PS_2: +	case SQ_ALU_CONST_CACHE_PS_3: +	case SQ_ALU_CONST_CACHE_PS_4: +	case SQ_ALU_CONST_CACHE_PS_5: +	case SQ_ALU_CONST_CACHE_PS_6: +	case SQ_ALU_CONST_CACHE_PS_7: +	case SQ_ALU_CONST_CACHE_PS_8: +	case SQ_ALU_CONST_CACHE_PS_9: +	case SQ_ALU_CONST_CACHE_PS_10: +	case SQ_ALU_CONST_CACHE_PS_11: +	case SQ_ALU_CONST_CACHE_PS_12: +	case SQ_ALU_CONST_CACHE_PS_13: +	case SQ_ALU_CONST_CACHE_PS_14: +	case SQ_ALU_CONST_CACHE_PS_15: +	case SQ_ALU_CONST_CACHE_VS_0: +	case SQ_ALU_CONST_CACHE_VS_1: +	case SQ_ALU_CONST_CACHE_VS_2: +	case SQ_ALU_CONST_CACHE_VS_3: +	case SQ_ALU_CONST_CACHE_VS_4: +	case SQ_ALU_CONST_CACHE_VS_5: +	case SQ_ALU_CONST_CACHE_VS_6: +	case SQ_ALU_CONST_CACHE_VS_7: +	case SQ_ALU_CONST_CACHE_VS_8: +	case SQ_ALU_CONST_CACHE_VS_9: +	case SQ_ALU_CONST_CACHE_VS_10: +	case SQ_ALU_CONST_CACHE_VS_11: +	case SQ_ALU_CONST_CACHE_VS_12: +	case SQ_ALU_CONST_CACHE_VS_13: +	case SQ_ALU_CONST_CACHE_VS_14: +	case SQ_ALU_CONST_CACHE_VS_15:  		r = r600_cs_packet_next_reloc(p, &reloc);  		if (r) {  			dev_warn(p->dev, "bad SET_CONTEXT_REG " @@ -1226,13 +1280,15 @@ static int r600_packet3_check(struct radeon_cs_parser *p,  		}  		break;  	case PACKET3_SET_ALU_CONST: -		start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET; -		end_reg = 4 * pkt->count + start_reg - 4; -		if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || -		    (start_reg >= PACKET3_SET_ALU_CONST_END) || -		    (end_reg >= PACKET3_SET_ALU_CONST_END)) { -			DRM_ERROR("bad SET_ALU_CONST\n"); -			return -EINVAL; +		if (track->sq_config & DX9_CONSTS) { +			start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET; +			end_reg = 4 * pkt->count + start_reg - 4; +			if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || +			    (start_reg >= PACKET3_SET_ALU_CONST_END) || +			    (end_reg >= PACKET3_SET_ALU_CONST_END)) { +				DRM_ERROR("bad SET_ALU_CONST\n"); +				return -EINVAL; +			}  		}  		break;  	case PACKET3_SET_BOOL_CONST: diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index fcc949df0e5..2616b822ba6 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -42,13 +42,13 @@ enum r600_hdmi_color_format {   */  enum r600_hdmi_iec_status_bits {  	AUDIO_STATUS_DIG_ENABLE   = 0x01, -	AUDIO_STATUS_V	    = 0x02, -	AUDIO_STATUS_VCFG	 = 0x04, +	AUDIO_STATUS_V            = 0x02, +	AUDIO_STATUS_VCFG         = 0x04,  	AUDIO_STATUS_EMPHASIS     = 0x08,  	AUDIO_STATUS_COPYRIGHT    = 0x10,  	AUDIO_STATUS_NONAUDIO     = 0x20,  	AUDIO_STATUS_PROFESSIONAL = 0x40, -	AUDIO_STATUS_LEVEL	= 0x80 +	AUDIO_STATUS_LEVEL        = 0x80  };  struct { @@ -85,7 +85,7 @@ struct {  static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)  {  	if (*CTS == 0) -		*CTS = clock*N/(128*freq)*1000; +		*CTS = clock * N / (128 * freq) * 1000;  	DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",  		  N, *CTS, freq);  } @@ -131,11 +131,11 @@ static void r600_hdmi_infoframe_checksum(uint8_t packetType,  					 uint8_t length,  					 uint8_t *frame)  { -    int i; -    frame[0] = packetType + versionNumber + length; -    for (i = 1; i <= length; i++) -	frame[0] += frame[i]; -    frame[0] = 0x100 - frame[0]; +	int i; +	frame[0] = packetType + versionNumber + length; +	for (i = 1; i <= length; i++) +		frame[0] += frame[i]; +	frame[0] = 0x100 - frame[0];  }  /* @@ -314,6 +314,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod  	struct radeon_device *rdev = dev->dev_private;  	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; +	if (ASIC_IS_DCE4(rdev)) +		return; +  	if (!offset)  		return; @@ -417,90 +420,147 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,  	WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);  } -/* - * enable/disable the HDMI engine - */ -void r600_hdmi_enable(struct drm_encoder *encoder, int enable) +static int r600_hdmi_find_free_block(struct drm_device *dev) +{ +	struct radeon_device *rdev = dev->dev_private; +	struct drm_encoder *encoder; +	struct radeon_encoder *radeon_encoder; +	bool free_blocks[3] = { true, true, true }; + +	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { +		radeon_encoder = to_radeon_encoder(encoder); +		switch (radeon_encoder->hdmi_offset) { +		case R600_HDMI_BLOCK1: +			free_blocks[0] = false; +			break; +		case R600_HDMI_BLOCK2: +			free_blocks[1] = false; +			break; +		case R600_HDMI_BLOCK3: +			free_blocks[2] = false; +			break; +		} +	} + +	if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) { +		return free_blocks[0] ? R600_HDMI_BLOCK1 : 0; +	} else if (rdev->family >= CHIP_R600) { +		if (free_blocks[0]) +			return R600_HDMI_BLOCK1; +		else if (free_blocks[1]) +			return R600_HDMI_BLOCK2; +	} +	return 0; +} + +static void r600_hdmi_assign_block(struct drm_encoder *encoder)  {  	struct drm_device *dev = encoder->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -	uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; +	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; -	if (!offset) +	if (!dig) { +		dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");  		return; +	} -	DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset); +	if (ASIC_IS_DCE4(rdev)) { +		/* TODO */ +	} else if (ASIC_IS_DCE3(rdev)) { +		radeon_encoder->hdmi_offset = dig->dig_encoder ? +			R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; +		if (ASIC_IS_DCE32(rdev)) +			radeon_encoder->hdmi_config_offset = dig->dig_encoder ? +				R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; +	} else if (rdev->family >= CHIP_R600) { +		radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev); +	} +} -	/* some version of atombios ignore the enable HDMI flag -	 * so enabling/disabling HDMI was moved here for TMDS1+2 */ -	switch (radeon_encoder->encoder_id) { -	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: -		WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4); -		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0); -		break; +/* + * enable the HDMI engine + */ +void r600_hdmi_enable(struct drm_encoder *encoder) +{ +	struct drm_device *dev = encoder->dev; +	struct radeon_device *rdev = dev->dev_private; +	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -	case ENCODER_OBJECT_ID_INTERNAL_LVTM1: -		WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4); -		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0); -		break; +	if (ASIC_IS_DCE4(rdev)) +		return; -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: -	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: -		/* This part is doubtfull in my opinion */ -		WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0); -		break; +	if (!radeon_encoder->hdmi_offset) { +		r600_hdmi_assign_block(encoder); +		if (!radeon_encoder->hdmi_offset) { +			dev_warn(rdev->dev, "Could not find HDMI block for " +				"0x%x encoder\n", radeon_encoder->encoder_id); +			return; +		} +	} -	default: -		DRM_ERROR("unknown HDMI output type\n"); -		break; +	if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { +		WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); +	} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { +		int offset = radeon_encoder->hdmi_offset; +		switch (radeon_encoder->encoder_id) { +		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: +			WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4); +			WREG32(offset + R600_HDMI_ENABLE, 0x101); +			break; +		case ENCODER_OBJECT_ID_INTERNAL_LVTM1: +			WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4); +			WREG32(offset + R600_HDMI_ENABLE, 0x105); +			break; +		default: +			dev_err(rdev->dev, "Unknown HDMI output type\n"); +			break; +		}  	} + +	DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", +		radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);  }  /* - * determin at which register offset the HDMI encoder is + * disable the HDMI engine   */ -void r600_hdmi_init(struct drm_encoder *encoder) +void r600_hdmi_disable(struct drm_encoder *encoder)  { +	struct drm_device *dev = encoder->dev; +	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -	switch (radeon_encoder->encoder_id) { -	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: -		radeon_encoder->hdmi_offset = R600_HDMI_TMDS1; -		break; +	if (ASIC_IS_DCE4(rdev)) +		return; -	case ENCODER_OBJECT_ID_INTERNAL_LVTM1: -		switch (r600_audio_tmds_index(encoder)) { -		case 0: -			radeon_encoder->hdmi_offset = R600_HDMI_TMDS1; +	if (!radeon_encoder->hdmi_offset) { +		dev_err(rdev->dev, "Disabling not enabled HDMI\n"); +		return; +	} + +	DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", +		radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); + +	if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { +		WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); +	} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { +		int offset = radeon_encoder->hdmi_offset; +		switch (radeon_encoder->encoder_id) { +		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: +			WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4); +			WREG32(offset + R600_HDMI_ENABLE, 0);  			break; -		case 1: -			radeon_encoder->hdmi_offset = R600_HDMI_TMDS2; +		case ENCODER_OBJECT_ID_INTERNAL_LVTM1: +			WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4); +			WREG32(offset + R600_HDMI_ENABLE, 0);  			break;  		default: -			radeon_encoder->hdmi_offset = 0; +			dev_err(rdev->dev, "Unknown HDMI output type\n");  			break;  		} -	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: -		radeon_encoder->hdmi_offset = R600_HDMI_TMDS2; -		break; - -	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: -		radeon_encoder->hdmi_offset = R600_HDMI_DIG; -		break; - -	default: -		radeon_encoder->hdmi_offset = 0; -		break;  	} -	DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n", -		  radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); - -	/* TODO: make this configureable */ -	radeon_encoder->hdmi_audio_workaround = 0; +	radeon_encoder->hdmi_offset = 0; +	radeon_encoder->hdmi_config_offset = 0;  } diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h index d0e28ffdeda..7b1d22370f6 100644 --- a/drivers/gpu/drm/radeon/r600_reg.h +++ b/drivers/gpu/drm/radeon/r600_reg.h @@ -152,9 +152,9 @@  #define R600_AUDIO_STATUS_BITS            0x73d8  /* HDMI base register addresses */ -#define R600_HDMI_TMDS1                   0x7400 -#define R600_HDMI_TMDS2                   0x7700 -#define R600_HDMI_DIG                     0x7800 +#define R600_HDMI_BLOCK1                  0x7400 +#define R600_HDMI_BLOCK2                  0x7700 +#define R600_HDMI_BLOCK3                  0x7800  /* HDMI registers */  #define R600_HDMI_ENABLE           0x00 @@ -185,4 +185,8 @@  #define R600_HDMI_AUDIO_DEBUG_2    0xe8  #define R600_HDMI_AUDIO_DEBUG_3    0xec +/* HDMI additional config base register addresses */ +#define R600_HDMI_CONFIG1                 0x7600 +#define R600_HDMI_CONFIG2                 0x7a00 +  #endif diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 5b2e4d44282..59c1f8793e6 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -77,6 +77,55 @@  #define CB_COLOR0_FRAG                                  0x280e0  #define CB_COLOR0_MASK                                  0x28100 +#define SQ_ALU_CONST_CACHE_PS_0				0x28940 +#define SQ_ALU_CONST_CACHE_PS_1				0x28944 +#define SQ_ALU_CONST_CACHE_PS_2				0x28948 +#define SQ_ALU_CONST_CACHE_PS_3				0x2894c +#define SQ_ALU_CONST_CACHE_PS_4				0x28950 +#define SQ_ALU_CONST_CACHE_PS_5				0x28954 +#define SQ_ALU_CONST_CACHE_PS_6				0x28958 +#define SQ_ALU_CONST_CACHE_PS_7				0x2895c +#define SQ_ALU_CONST_CACHE_PS_8				0x28960 +#define SQ_ALU_CONST_CACHE_PS_9				0x28964 +#define SQ_ALU_CONST_CACHE_PS_10			0x28968 +#define SQ_ALU_CONST_CACHE_PS_11			0x2896c +#define SQ_ALU_CONST_CACHE_PS_12			0x28970 +#define SQ_ALU_CONST_CACHE_PS_13			0x28974 +#define SQ_ALU_CONST_CACHE_PS_14			0x28978 +#define SQ_ALU_CONST_CACHE_PS_15			0x2897c +#define SQ_ALU_CONST_CACHE_VS_0				0x28980 +#define SQ_ALU_CONST_CACHE_VS_1				0x28984 +#define SQ_ALU_CONST_CACHE_VS_2				0x28988 +#define SQ_ALU_CONST_CACHE_VS_3				0x2898c +#define SQ_ALU_CONST_CACHE_VS_4				0x28990 +#define SQ_ALU_CONST_CACHE_VS_5				0x28994 +#define SQ_ALU_CONST_CACHE_VS_6				0x28998 +#define SQ_ALU_CONST_CACHE_VS_7				0x2899c +#define SQ_ALU_CONST_CACHE_VS_8				0x289a0 +#define SQ_ALU_CONST_CACHE_VS_9				0x289a4 +#define SQ_ALU_CONST_CACHE_VS_10			0x289a8 +#define SQ_ALU_CONST_CACHE_VS_11			0x289ac +#define SQ_ALU_CONST_CACHE_VS_12			0x289b0 +#define SQ_ALU_CONST_CACHE_VS_13			0x289b4 +#define SQ_ALU_CONST_CACHE_VS_14			0x289b8 +#define SQ_ALU_CONST_CACHE_VS_15			0x289bc +#define SQ_ALU_CONST_CACHE_GS_0				0x289c0 +#define SQ_ALU_CONST_CACHE_GS_1				0x289c4 +#define SQ_ALU_CONST_CACHE_GS_2				0x289c8 +#define SQ_ALU_CONST_CACHE_GS_3				0x289cc +#define SQ_ALU_CONST_CACHE_GS_4				0x289d0 +#define SQ_ALU_CONST_CACHE_GS_5				0x289d4 +#define SQ_ALU_CONST_CACHE_GS_6				0x289d8 +#define SQ_ALU_CONST_CACHE_GS_7				0x289dc +#define SQ_ALU_CONST_CACHE_GS_8				0x289e0 +#define SQ_ALU_CONST_CACHE_GS_9				0x289e4 +#define SQ_ALU_CONST_CACHE_GS_10			0x289e8 +#define SQ_ALU_CONST_CACHE_GS_11			0x289ec +#define SQ_ALU_CONST_CACHE_GS_12			0x289f0 +#define SQ_ALU_CONST_CACHE_GS_13			0x289f4 +#define SQ_ALU_CONST_CACHE_GS_14			0x289f8 +#define SQ_ALU_CONST_CACHE_GS_15			0x289fc +  #define	CONFIG_MEMSIZE					0x5428  #define CONFIG_CNTL					0x5424  #define	CP_STAT						0x8680 diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 829e26e8a4b..034218c3dbb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -91,6 +91,8 @@ extern int radeon_tv;  extern int radeon_new_pll;  extern int radeon_dynpm;  extern int radeon_audio; +extern int radeon_disp_priority; +extern int radeon_hw_i2c;  /*   * Copy from radeon_drv.h so we don't have to include both and have conflicting @@ -168,6 +170,7 @@ struct radeon_clock {   * Power management   */  int radeon_pm_init(struct radeon_device *rdev); +void radeon_pm_fini(struct radeon_device *rdev);  void radeon_pm_compute_clocks(struct radeon_device *rdev);  void radeon_combios_get_power_modes(struct radeon_device *rdev);  void radeon_atombios_get_power_modes(struct radeon_device *rdev); @@ -687,6 +690,7 @@ struct radeon_pm {  	bool 			downclocked;  	int			active_crtcs;  	int			req_vblank; +	bool			vblank_sync;  	fixed20_12		max_bandwidth;  	fixed20_12		igp_sideport_mclk;  	fixed20_12		igp_system_mclk; @@ -697,6 +701,7 @@ struct radeon_pm {  	fixed20_12		ht_bandwidth;  	fixed20_12		core_bandwidth;  	fixed20_12		sclk; +	fixed20_12		mclk;  	fixed20_12		needed_bandwidth;  	/* XXX: use a define for num power modes */  	struct radeon_power_state power_state[8]; @@ -707,6 +712,7 @@ struct radeon_pm {  	struct radeon_power_state *requested_power_state;  	struct radeon_pm_clock_info *requested_clock_mode;  	struct radeon_power_state *default_power_state; +	struct radeon_i2c_chan *i2c_bus;  }; @@ -729,8 +735,6 @@ int radeon_debugfs_add_files(struct radeon_device *rdev,  			     struct drm_info_list *files,  			     unsigned nfiles);  int radeon_debugfs_fence_init(struct radeon_device *rdev); -int r100_debugfs_rbbm_init(struct radeon_device *rdev); -int r100_debugfs_cp_init(struct radeon_device *rdev);  /* @@ -782,7 +786,7 @@ struct radeon_asic {  	int (*set_surface_reg)(struct radeon_device *rdev, int reg,  			       uint32_t tiling_flags, uint32_t pitch,  			       uint32_t offset, uint32_t obj_size); -	int (*clear_surface_reg)(struct radeon_device *rdev, int reg); +	void (*clear_surface_reg)(struct radeon_device *rdev, int reg);  	void (*bandwidth_update)(struct radeon_device *rdev);  	void (*hpd_init)(struct radeon_device *rdev);  	void (*hpd_fini)(struct radeon_device *rdev); @@ -862,6 +866,12 @@ union radeon_asic_config {  	struct rv770_asic	rv770;  }; +/* + * asic initizalization from radeon_asic.c + */ +void radeon_agp_disable(struct radeon_device *rdev); +int radeon_asic_init(struct radeon_device *rdev); +  /*   * IOCTL. @@ -1172,6 +1182,8 @@ extern void radeon_gart_restore(struct radeon_device *rdev);  extern int radeon_modeset_init(struct radeon_device *rdev);  extern void radeon_modeset_fini(struct radeon_device *rdev);  extern bool radeon_card_posted(struct radeon_device *rdev); +extern void radeon_update_bandwidth_info(struct radeon_device *rdev); +extern void radeon_update_display_priority(struct radeon_device *rdev);  extern bool radeon_boot_test_post_card(struct radeon_device *rdev);  extern int radeon_clocks_init(struct radeon_device *rdev);  extern void radeon_clocks_fini(struct radeon_device *rdev); @@ -1188,51 +1200,6 @@ extern int radeon_resume_kms(struct drm_device *dev);  extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);  /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ -struct r100_mc_save { -	u32	GENMO_WT; -	u32	CRTC_EXT_CNTL; -	u32	CRTC_GEN_CNTL; -	u32	CRTC2_GEN_CNTL; -	u32	CUR_OFFSET; -	u32	CUR2_OFFSET; -}; -extern void r100_cp_disable(struct radeon_device *rdev); -extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); -extern void r100_cp_fini(struct radeon_device *rdev); -extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev); -extern int r100_pci_gart_init(struct radeon_device *rdev); -extern void r100_pci_gart_fini(struct radeon_device *rdev); -extern int r100_pci_gart_enable(struct radeon_device *rdev); -extern void r100_pci_gart_disable(struct radeon_device *rdev); -extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); -extern int r100_debugfs_mc_info_init(struct radeon_device *rdev); -extern int r100_gui_wait_for_idle(struct radeon_device *rdev); -extern void r100_ib_fini(struct radeon_device *rdev); -extern int r100_ib_init(struct radeon_device *rdev); -extern void r100_irq_disable(struct radeon_device *rdev); -extern int r100_irq_set(struct radeon_device *rdev); -extern void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save); -extern void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save); -extern void r100_vram_init_sizes(struct radeon_device *rdev); -extern void r100_wb_disable(struct radeon_device *rdev); -extern void r100_wb_fini(struct radeon_device *rdev); -extern int r100_wb_init(struct radeon_device *rdev); -extern void r100_hdp_reset(struct radeon_device *rdev); -extern int r100_rb2d_reset(struct radeon_device *rdev); -extern int r100_cp_reset(struct radeon_device *rdev); -extern void r100_vga_render_disable(struct radeon_device *rdev); -extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, -						struct radeon_cs_packet *pkt, -						struct radeon_bo *robj); -extern int r100_cs_parse_packet0(struct radeon_cs_parser *p, -				struct radeon_cs_packet *pkt, -				const unsigned *auth, unsigned n, -				radeon_packet0_check_t check); -extern int r100_cs_packet_parse(struct radeon_cs_parser *p, -				struct radeon_cs_packet *pkt, -				unsigned idx); -extern void r100_enable_bm(struct radeon_device *rdev); -extern void r100_set_common_regs(struct radeon_device *rdev);  /* rv200,rv250,rv280 */  extern void r200_set_safe_registers(struct radeon_device *rdev); @@ -1322,7 +1289,8 @@ extern int r600_audio_tmds_index(struct drm_encoder *encoder);  extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);  extern void r600_audio_fini(struct radeon_device *rdev);  extern void r600_hdmi_init(struct drm_encoder *encoder); -extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable); +extern void r600_hdmi_enable(struct drm_encoder *encoder); +extern void r600_hdmi_disable(struct drm_encoder *encoder);  extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);  extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);  extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index c4457791dff..28e473f1f56 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -134,12 +134,10 @@ int radeon_agp_init(struct radeon_device *rdev)  	int ret;  	/* Acquire AGP. */ -	if (!rdev->ddev->agp->acquired) { -		ret = drm_agp_acquire(rdev->ddev); -		if (ret) { -			DRM_ERROR("Unable to acquire AGP: %d\n", ret); -			return ret; -		} +	ret = drm_agp_acquire(rdev->ddev); +	if (ret) { +		DRM_ERROR("Unable to acquire AGP: %d\n", ret); +		return ret;  	}  	ret = drm_agp_info(rdev->ddev, &info); diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c new file mode 100644 index 00000000000..a4b4bc9fa32 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -0,0 +1,772 @@ +/* + * Copyright 2008 Advanced Micro Devices, Inc. + * Copyright 2008 Red Hat Inc. + * Copyright 2009 Jerome Glisse. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + *          Alex Deucher + *          Jerome Glisse + */ + +#include <linux/console.h> +#include <drm/drmP.h> +#include <drm/drm_crtc_helper.h> +#include <drm/radeon_drm.h> +#include <linux/vgaarb.h> +#include <linux/vga_switcheroo.h> +#include "radeon_reg.h" +#include "radeon.h" +#include "radeon_asic.h" +#include "atom.h" + +/* + * Registers accessors functions. + */ +static uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg) +{ +	DRM_ERROR("Invalid callback to read register 0x%04X\n", reg); +	BUG_ON(1); +	return 0; +} + +static void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) +{ +	DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n", +		  reg, v); +	BUG_ON(1); +} + +static void radeon_register_accessor_init(struct radeon_device *rdev) +{ +	rdev->mc_rreg = &radeon_invalid_rreg; +	rdev->mc_wreg = &radeon_invalid_wreg; +	rdev->pll_rreg = &radeon_invalid_rreg; +	rdev->pll_wreg = &radeon_invalid_wreg; +	rdev->pciep_rreg = &radeon_invalid_rreg; +	rdev->pciep_wreg = &radeon_invalid_wreg; + +	/* Don't change order as we are overridding accessor. */ +	if (rdev->family < CHIP_RV515) { +		rdev->pcie_reg_mask = 0xff; +	} else { +		rdev->pcie_reg_mask = 0x7ff; +	} +	/* FIXME: not sure here */ +	if (rdev->family <= CHIP_R580) { +		rdev->pll_rreg = &r100_pll_rreg; +		rdev->pll_wreg = &r100_pll_wreg; +	} +	if (rdev->family >= CHIP_R420) { +		rdev->mc_rreg = &r420_mc_rreg; +		rdev->mc_wreg = &r420_mc_wreg; +	} +	if (rdev->family >= CHIP_RV515) { +		rdev->mc_rreg = &rv515_mc_rreg; +		rdev->mc_wreg = &rv515_mc_wreg; +	} +	if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { +		rdev->mc_rreg = &rs400_mc_rreg; +		rdev->mc_wreg = &rs400_mc_wreg; +	} +	if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { +		rdev->mc_rreg = &rs690_mc_rreg; +		rdev->mc_wreg = &rs690_mc_wreg; +	} +	if (rdev->family == CHIP_RS600) { +		rdev->mc_rreg = &rs600_mc_rreg; +		rdev->mc_wreg = &rs600_mc_wreg; +	} +	if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { +		rdev->pciep_rreg = &r600_pciep_rreg; +		rdev->pciep_wreg = &r600_pciep_wreg; +	} +} + + +/* helper to disable agp */ +void radeon_agp_disable(struct radeon_device *rdev) +{ +	rdev->flags &= ~RADEON_IS_AGP; +	if (rdev->family >= CHIP_R600) { +		DRM_INFO("Forcing AGP to PCIE mode\n"); +		rdev->flags |= RADEON_IS_PCIE; +	} else if (rdev->family >= CHIP_RV515 || +			rdev->family == CHIP_RV380 || +			rdev->family == CHIP_RV410 || +			rdev->family == CHIP_R423) { +		DRM_INFO("Forcing AGP to PCIE mode\n"); +		rdev->flags |= RADEON_IS_PCIE; +		rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; +		rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; +	} else { +		DRM_INFO("Forcing AGP to PCI mode\n"); +		rdev->flags |= RADEON_IS_PCI; +		rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; +		rdev->asic->gart_set_page = &r100_pci_gart_set_page; +	} +	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; +} + +/* + * ASIC + */ +static struct radeon_asic r100_asic = { +	.init = &r100_init, +	.fini = &r100_fini, +	.suspend = &r100_suspend, +	.resume = &r100_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &r100_gpu_reset, +	.gart_tlb_flush = &r100_pci_gart_tlb_flush, +	.gart_set_page = &r100_pci_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &r100_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &r100_irq_set, +	.irq_process = &r100_irq_process, +	.get_vblank_counter = &r100_get_vblank_counter, +	.fence_ring_emit = &r100_fence_ring_emit, +	.cs_parse = &r100_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = NULL, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_legacy_get_engine_clock, +	.set_engine_clock = &radeon_legacy_set_engine_clock, +	.get_memory_clock = &radeon_legacy_get_memory_clock, +	.set_memory_clock = NULL, +	.get_pcie_lanes = NULL, +	.set_pcie_lanes = NULL, +	.set_clock_gating = &radeon_legacy_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &r100_bandwidth_update, +	.hpd_init = &r100_hpd_init, +	.hpd_fini = &r100_hpd_fini, +	.hpd_sense = &r100_hpd_sense, +	.hpd_set_polarity = &r100_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r200_asic = { +	.init = &r100_init, +	.fini = &r100_fini, +	.suspend = &r100_suspend, +	.resume = &r100_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &r100_gpu_reset, +	.gart_tlb_flush = &r100_pci_gart_tlb_flush, +	.gart_set_page = &r100_pci_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &r100_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &r100_irq_set, +	.irq_process = &r100_irq_process, +	.get_vblank_counter = &r100_get_vblank_counter, +	.fence_ring_emit = &r100_fence_ring_emit, +	.cs_parse = &r100_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_legacy_get_engine_clock, +	.set_engine_clock = &radeon_legacy_set_engine_clock, +	.get_memory_clock = &radeon_legacy_get_memory_clock, +	.set_memory_clock = NULL, +	.set_pcie_lanes = NULL, +	.set_clock_gating = &radeon_legacy_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &r100_bandwidth_update, +	.hpd_init = &r100_hpd_init, +	.hpd_fini = &r100_hpd_fini, +	.hpd_sense = &r100_hpd_sense, +	.hpd_set_polarity = &r100_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r300_asic = { +	.init = &r300_init, +	.fini = &r300_fini, +	.suspend = &r300_suspend, +	.resume = &r300_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &r300_gpu_reset, +	.gart_tlb_flush = &r100_pci_gart_tlb_flush, +	.gart_set_page = &r100_pci_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &r300_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &r100_irq_set, +	.irq_process = &r100_irq_process, +	.get_vblank_counter = &r100_get_vblank_counter, +	.fence_ring_emit = &r300_fence_ring_emit, +	.cs_parse = &r300_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_legacy_get_engine_clock, +	.set_engine_clock = &radeon_legacy_set_engine_clock, +	.get_memory_clock = &radeon_legacy_get_memory_clock, +	.set_memory_clock = NULL, +	.get_pcie_lanes = &rv370_get_pcie_lanes, +	.set_pcie_lanes = &rv370_set_pcie_lanes, +	.set_clock_gating = &radeon_legacy_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &r100_bandwidth_update, +	.hpd_init = &r100_hpd_init, +	.hpd_fini = &r100_hpd_fini, +	.hpd_sense = &r100_hpd_sense, +	.hpd_set_polarity = &r100_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r300_asic_pcie = { +	.init = &r300_init, +	.fini = &r300_fini, +	.suspend = &r300_suspend, +	.resume = &r300_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &r300_gpu_reset, +	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, +	.gart_set_page = &rv370_pcie_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &r300_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &r100_irq_set, +	.irq_process = &r100_irq_process, +	.get_vblank_counter = &r100_get_vblank_counter, +	.fence_ring_emit = &r300_fence_ring_emit, +	.cs_parse = &r300_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_legacy_get_engine_clock, +	.set_engine_clock = &radeon_legacy_set_engine_clock, +	.get_memory_clock = &radeon_legacy_get_memory_clock, +	.set_memory_clock = NULL, +	.set_pcie_lanes = &rv370_set_pcie_lanes, +	.set_clock_gating = &radeon_legacy_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &r100_bandwidth_update, +	.hpd_init = &r100_hpd_init, +	.hpd_fini = &r100_hpd_fini, +	.hpd_sense = &r100_hpd_sense, +	.hpd_set_polarity = &r100_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r420_asic = { +	.init = &r420_init, +	.fini = &r420_fini, +	.suspend = &r420_suspend, +	.resume = &r420_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &r300_gpu_reset, +	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, +	.gart_set_page = &rv370_pcie_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &r300_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &r100_irq_set, +	.irq_process = &r100_irq_process, +	.get_vblank_counter = &r100_get_vblank_counter, +	.fence_ring_emit = &r300_fence_ring_emit, +	.cs_parse = &r300_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = &radeon_atom_get_memory_clock, +	.set_memory_clock = &radeon_atom_set_memory_clock, +	.get_pcie_lanes = &rv370_get_pcie_lanes, +	.set_pcie_lanes = &rv370_set_pcie_lanes, +	.set_clock_gating = &radeon_atom_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &r100_bandwidth_update, +	.hpd_init = &r100_hpd_init, +	.hpd_fini = &r100_hpd_fini, +	.hpd_sense = &r100_hpd_sense, +	.hpd_set_polarity = &r100_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic rs400_asic = { +	.init = &rs400_init, +	.fini = &rs400_fini, +	.suspend = &rs400_suspend, +	.resume = &rs400_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &r300_gpu_reset, +	.gart_tlb_flush = &rs400_gart_tlb_flush, +	.gart_set_page = &rs400_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &r300_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &r100_irq_set, +	.irq_process = &r100_irq_process, +	.get_vblank_counter = &r100_get_vblank_counter, +	.fence_ring_emit = &r300_fence_ring_emit, +	.cs_parse = &r300_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_legacy_get_engine_clock, +	.set_engine_clock = &radeon_legacy_set_engine_clock, +	.get_memory_clock = &radeon_legacy_get_memory_clock, +	.set_memory_clock = NULL, +	.get_pcie_lanes = NULL, +	.set_pcie_lanes = NULL, +	.set_clock_gating = &radeon_legacy_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &r100_bandwidth_update, +	.hpd_init = &r100_hpd_init, +	.hpd_fini = &r100_hpd_fini, +	.hpd_sense = &r100_hpd_sense, +	.hpd_set_polarity = &r100_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic rs600_asic = { +	.init = &rs600_init, +	.fini = &rs600_fini, +	.suspend = &rs600_suspend, +	.resume = &rs600_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &r300_gpu_reset, +	.gart_tlb_flush = &rs600_gart_tlb_flush, +	.gart_set_page = &rs600_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &r300_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &rs600_irq_set, +	.irq_process = &rs600_irq_process, +	.get_vblank_counter = &rs600_get_vblank_counter, +	.fence_ring_emit = &r300_fence_ring_emit, +	.cs_parse = &r300_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = &radeon_atom_get_memory_clock, +	.set_memory_clock = &radeon_atom_set_memory_clock, +	.get_pcie_lanes = NULL, +	.set_pcie_lanes = NULL, +	.set_clock_gating = &radeon_atom_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &rs600_bandwidth_update, +	.hpd_init = &rs600_hpd_init, +	.hpd_fini = &rs600_hpd_fini, +	.hpd_sense = &rs600_hpd_sense, +	.hpd_set_polarity = &rs600_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic rs690_asic = { +	.init = &rs690_init, +	.fini = &rs690_fini, +	.suspend = &rs690_suspend, +	.resume = &rs690_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &r300_gpu_reset, +	.gart_tlb_flush = &rs400_gart_tlb_flush, +	.gart_set_page = &rs400_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &r300_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &rs600_irq_set, +	.irq_process = &rs600_irq_process, +	.get_vblank_counter = &rs600_get_vblank_counter, +	.fence_ring_emit = &r300_fence_ring_emit, +	.cs_parse = &r300_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r200_copy_dma, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = &radeon_atom_get_memory_clock, +	.set_memory_clock = &radeon_atom_set_memory_clock, +	.get_pcie_lanes = NULL, +	.set_pcie_lanes = NULL, +	.set_clock_gating = &radeon_atom_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &rs690_bandwidth_update, +	.hpd_init = &rs600_hpd_init, +	.hpd_fini = &rs600_hpd_fini, +	.hpd_sense = &rs600_hpd_sense, +	.hpd_set_polarity = &rs600_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic rv515_asic = { +	.init = &rv515_init, +	.fini = &rv515_fini, +	.suspend = &rv515_suspend, +	.resume = &rv515_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &rv515_gpu_reset, +	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, +	.gart_set_page = &rv370_pcie_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &rv515_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &rs600_irq_set, +	.irq_process = &rs600_irq_process, +	.get_vblank_counter = &rs600_get_vblank_counter, +	.fence_ring_emit = &r300_fence_ring_emit, +	.cs_parse = &r300_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = &radeon_atom_get_memory_clock, +	.set_memory_clock = &radeon_atom_set_memory_clock, +	.get_pcie_lanes = &rv370_get_pcie_lanes, +	.set_pcie_lanes = &rv370_set_pcie_lanes, +	.set_clock_gating = &radeon_atom_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &rv515_bandwidth_update, +	.hpd_init = &rs600_hpd_init, +	.hpd_fini = &rs600_hpd_fini, +	.hpd_sense = &rs600_hpd_sense, +	.hpd_set_polarity = &rs600_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r520_asic = { +	.init = &r520_init, +	.fini = &rv515_fini, +	.suspend = &rv515_suspend, +	.resume = &r520_resume, +	.vga_set_state = &r100_vga_set_state, +	.gpu_reset = &rv515_gpu_reset, +	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, +	.gart_set_page = &rv370_pcie_gart_set_page, +	.cp_commit = &r100_cp_commit, +	.ring_start = &rv515_ring_start, +	.ring_test = &r100_ring_test, +	.ring_ib_execute = &r100_ring_ib_execute, +	.irq_set = &rs600_irq_set, +	.irq_process = &rs600_irq_process, +	.get_vblank_counter = &rs600_get_vblank_counter, +	.fence_ring_emit = &r300_fence_ring_emit, +	.cs_parse = &r300_cs_parse, +	.copy_blit = &r100_copy_blit, +	.copy_dma = &r200_copy_dma, +	.copy = &r100_copy_blit, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = &radeon_atom_get_memory_clock, +	.set_memory_clock = &radeon_atom_set_memory_clock, +	.get_pcie_lanes = &rv370_get_pcie_lanes, +	.set_pcie_lanes = &rv370_set_pcie_lanes, +	.set_clock_gating = &radeon_atom_set_clock_gating, +	.set_surface_reg = r100_set_surface_reg, +	.clear_surface_reg = r100_clear_surface_reg, +	.bandwidth_update = &rv515_bandwidth_update, +	.hpd_init = &rs600_hpd_init, +	.hpd_fini = &rs600_hpd_fini, +	.hpd_sense = &rs600_hpd_sense, +	.hpd_set_polarity = &rs600_hpd_set_polarity, +	.ioctl_wait_idle = NULL, +}; + +static struct radeon_asic r600_asic = { +	.init = &r600_init, +	.fini = &r600_fini, +	.suspend = &r600_suspend, +	.resume = &r600_resume, +	.cp_commit = &r600_cp_commit, +	.vga_set_state = &r600_vga_set_state, +	.gpu_reset = &r600_gpu_reset, +	.gart_tlb_flush = &r600_pcie_gart_tlb_flush, +	.gart_set_page = &rs600_gart_set_page, +	.ring_test = &r600_ring_test, +	.ring_ib_execute = &r600_ring_ib_execute, +	.irq_set = &r600_irq_set, +	.irq_process = &r600_irq_process, +	.get_vblank_counter = &rs600_get_vblank_counter, +	.fence_ring_emit = &r600_fence_ring_emit, +	.cs_parse = &r600_cs_parse, +	.copy_blit = &r600_copy_blit, +	.copy_dma = &r600_copy_blit, +	.copy = &r600_copy_blit, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = &radeon_atom_get_memory_clock, +	.set_memory_clock = &radeon_atom_set_memory_clock, +	.get_pcie_lanes = &rv370_get_pcie_lanes, +	.set_pcie_lanes = NULL, +	.set_clock_gating = NULL, +	.set_surface_reg = r600_set_surface_reg, +	.clear_surface_reg = r600_clear_surface_reg, +	.bandwidth_update = &rv515_bandwidth_update, +	.hpd_init = &r600_hpd_init, +	.hpd_fini = &r600_hpd_fini, +	.hpd_sense = &r600_hpd_sense, +	.hpd_set_polarity = &r600_hpd_set_polarity, +	.ioctl_wait_idle = r600_ioctl_wait_idle, +}; + +static struct radeon_asic rs780_asic = { +	.init = &r600_init, +	.fini = &r600_fini, +	.suspend = &r600_suspend, +	.resume = &r600_resume, +	.cp_commit = &r600_cp_commit, +	.vga_set_state = &r600_vga_set_state, +	.gpu_reset = &r600_gpu_reset, +	.gart_tlb_flush = &r600_pcie_gart_tlb_flush, +	.gart_set_page = &rs600_gart_set_page, +	.ring_test = &r600_ring_test, +	.ring_ib_execute = &r600_ring_ib_execute, +	.irq_set = &r600_irq_set, +	.irq_process = &r600_irq_process, +	.get_vblank_counter = &rs600_get_vblank_counter, +	.fence_ring_emit = &r600_fence_ring_emit, +	.cs_parse = &r600_cs_parse, +	.copy_blit = &r600_copy_blit, +	.copy_dma = &r600_copy_blit, +	.copy = &r600_copy_blit, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = NULL, +	.set_memory_clock = NULL, +	.get_pcie_lanes = NULL, +	.set_pcie_lanes = NULL, +	.set_clock_gating = NULL, +	.set_surface_reg = r600_set_surface_reg, +	.clear_surface_reg = r600_clear_surface_reg, +	.bandwidth_update = &rs690_bandwidth_update, +	.hpd_init = &r600_hpd_init, +	.hpd_fini = &r600_hpd_fini, +	.hpd_sense = &r600_hpd_sense, +	.hpd_set_polarity = &r600_hpd_set_polarity, +	.ioctl_wait_idle = r600_ioctl_wait_idle, +}; + +static struct radeon_asic rv770_asic = { +	.init = &rv770_init, +	.fini = &rv770_fini, +	.suspend = &rv770_suspend, +	.resume = &rv770_resume, +	.cp_commit = &r600_cp_commit, +	.gpu_reset = &rv770_gpu_reset, +	.vga_set_state = &r600_vga_set_state, +	.gart_tlb_flush = &r600_pcie_gart_tlb_flush, +	.gart_set_page = &rs600_gart_set_page, +	.ring_test = &r600_ring_test, +	.ring_ib_execute = &r600_ring_ib_execute, +	.irq_set = &r600_irq_set, +	.irq_process = &r600_irq_process, +	.get_vblank_counter = &rs600_get_vblank_counter, +	.fence_ring_emit = &r600_fence_ring_emit, +	.cs_parse = &r600_cs_parse, +	.copy_blit = &r600_copy_blit, +	.copy_dma = &r600_copy_blit, +	.copy = &r600_copy_blit, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = &radeon_atom_get_memory_clock, +	.set_memory_clock = &radeon_atom_set_memory_clock, +	.get_pcie_lanes = &rv370_get_pcie_lanes, +	.set_pcie_lanes = NULL, +	.set_clock_gating = &radeon_atom_set_clock_gating, +	.set_surface_reg = r600_set_surface_reg, +	.clear_surface_reg = r600_clear_surface_reg, +	.bandwidth_update = &rv515_bandwidth_update, +	.hpd_init = &r600_hpd_init, +	.hpd_fini = &r600_hpd_fini, +	.hpd_sense = &r600_hpd_sense, +	.hpd_set_polarity = &r600_hpd_set_polarity, +	.ioctl_wait_idle = r600_ioctl_wait_idle, +}; + +static struct radeon_asic evergreen_asic = { +	.init = &evergreen_init, +	.fini = &evergreen_fini, +	.suspend = &evergreen_suspend, +	.resume = &evergreen_resume, +	.cp_commit = NULL, +	.gpu_reset = &evergreen_gpu_reset, +	.vga_set_state = &r600_vga_set_state, +	.gart_tlb_flush = &r600_pcie_gart_tlb_flush, +	.gart_set_page = &rs600_gart_set_page, +	.ring_test = NULL, +	.ring_ib_execute = NULL, +	.irq_set = NULL, +	.irq_process = NULL, +	.get_vblank_counter = NULL, +	.fence_ring_emit = NULL, +	.cs_parse = NULL, +	.copy_blit = NULL, +	.copy_dma = NULL, +	.copy = NULL, +	.get_engine_clock = &radeon_atom_get_engine_clock, +	.set_engine_clock = &radeon_atom_set_engine_clock, +	.get_memory_clock = &radeon_atom_get_memory_clock, +	.set_memory_clock = &radeon_atom_set_memory_clock, +	.set_pcie_lanes = NULL, +	.set_clock_gating = NULL, +	.set_surface_reg = r600_set_surface_reg, +	.clear_surface_reg = r600_clear_surface_reg, +	.bandwidth_update = &evergreen_bandwidth_update, +	.hpd_init = &evergreen_hpd_init, +	.hpd_fini = &evergreen_hpd_fini, +	.hpd_sense = &evergreen_hpd_sense, +	.hpd_set_polarity = &evergreen_hpd_set_polarity, +}; + +int radeon_asic_init(struct radeon_device *rdev) +{ +	radeon_register_accessor_init(rdev); +	switch (rdev->family) { +	case CHIP_R100: +	case CHIP_RV100: +	case CHIP_RS100: +	case CHIP_RV200: +	case CHIP_RS200: +		rdev->asic = &r100_asic; +		break; +	case CHIP_R200: +	case CHIP_RV250: +	case CHIP_RS300: +	case CHIP_RV280: +		rdev->asic = &r200_asic; +		break; +	case CHIP_R300: +	case CHIP_R350: +	case CHIP_RV350: +	case CHIP_RV380: +		if (rdev->flags & RADEON_IS_PCIE) +			rdev->asic = &r300_asic_pcie; +		else +			rdev->asic = &r300_asic; +		break; +	case CHIP_R420: +	case CHIP_R423: +	case CHIP_RV410: +		rdev->asic = &r420_asic; +		break; +	case CHIP_RS400: +	case CHIP_RS480: +		rdev->asic = &rs400_asic; +		break; +	case CHIP_RS600: +		rdev->asic = &rs600_asic; +		break; +	case CHIP_RS690: +	case CHIP_RS740: +		rdev->asic = &rs690_asic; +		break; +	case CHIP_RV515: +		rdev->asic = &rv515_asic; +		break; +	case CHIP_R520: +	case CHIP_RV530: +	case CHIP_RV560: +	case CHIP_RV570: +	case CHIP_R580: +		rdev->asic = &r520_asic; +		break; +	case CHIP_R600: +	case CHIP_RV610: +	case CHIP_RV630: +	case CHIP_RV620: +	case CHIP_RV635: +	case CHIP_RV670: +		rdev->asic = &r600_asic; +		break; +	case CHIP_RS780: +	case CHIP_RS880: +		rdev->asic = &rs780_asic; +		break; +	case CHIP_RV770: +	case CHIP_RV730: +	case CHIP_RV710: +	case CHIP_RV740: +		rdev->asic = &rv770_asic; +		break; +	case CHIP_CEDAR: +	case CHIP_REDWOOD: +	case CHIP_JUNIPER: +	case CHIP_CYPRESS: +	case CHIP_HEMLOCK: +		rdev->asic = &evergreen_asic; +		break; +	default: +		/* FIXME: not supported yet */ +		return -EINVAL; +	} + +	if (rdev->flags & RADEON_IS_IGP) { +		rdev->asic->get_memory_clock = NULL; +		rdev->asic->set_memory_clock = NULL; +	} + +	/* set the number of crtcs */ +	if (rdev->flags & RADEON_SINGLE_CRTC) +		rdev->num_crtc = 1; +	else { +		if (ASIC_IS_DCE4(rdev)) +			rdev->num_crtc = 6; +		else +			rdev->num_crtc = 2; +	} + +	return 0; +} + +/* + * Wrapper around modesetting bits. Move to radeon_clocks.c? + */ +int radeon_clocks_init(struct radeon_device *rdev) +{ +	int r; + +	r = radeon_static_clocks_init(rdev->ddev); +	if (r) { +		return r; +	} +	DRM_INFO("Clocks initialized !\n"); +	return 0; +} + +void radeon_clocks_fini(struct radeon_device *rdev) +{ +} diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index d3a157b2bcb..a0b8280663d 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -45,10 +45,18 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);  /*   * r100,rv100,rs100,rv200,rs200   */ -extern int r100_init(struct radeon_device *rdev); -extern void r100_fini(struct radeon_device *rdev); -extern int r100_suspend(struct radeon_device *rdev); -extern int r100_resume(struct radeon_device *rdev); +struct r100_mc_save { +	u32	GENMO_WT; +	u32	CRTC_EXT_CNTL; +	u32	CRTC_GEN_CNTL; +	u32	CRTC2_GEN_CNTL; +	u32	CUR_OFFSET; +	u32	CUR2_OFFSET; +}; +int r100_init(struct radeon_device *rdev); +void r100_fini(struct radeon_device *rdev); +int r100_suspend(struct radeon_device *rdev); +int r100_resume(struct radeon_device *rdev);  uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);  void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);  void r100_vga_set_state(struct radeon_device *rdev, bool state); @@ -73,7 +81,7 @@ int r100_copy_blit(struct radeon_device *rdev,  int r100_set_surface_reg(struct radeon_device *rdev, int reg,  			 uint32_t tiling_flags, uint32_t pitch,  			 uint32_t offset, uint32_t obj_size); -int r100_clear_surface_reg(struct radeon_device *rdev, int reg); +void r100_clear_surface_reg(struct radeon_device *rdev, int reg);  void r100_bandwidth_update(struct radeon_device *rdev);  void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);  int r100_ring_test(struct radeon_device *rdev); @@ -82,44 +90,42 @@ void r100_hpd_fini(struct radeon_device *rdev);  bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);  void r100_hpd_set_polarity(struct radeon_device *rdev,  			   enum radeon_hpd_id hpd); - -static struct radeon_asic r100_asic = { -	.init = &r100_init, -	.fini = &r100_fini, -	.suspend = &r100_suspend, -	.resume = &r100_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &r100_gpu_reset, -	.gart_tlb_flush = &r100_pci_gart_tlb_flush, -	.gart_set_page = &r100_pci_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &r100_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &r100_irq_set, -	.irq_process = &r100_irq_process, -	.get_vblank_counter = &r100_get_vblank_counter, -	.fence_ring_emit = &r100_fence_ring_emit, -	.cs_parse = &r100_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = NULL, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_legacy_get_engine_clock, -	.set_engine_clock = &radeon_legacy_set_engine_clock, -	.get_memory_clock = &radeon_legacy_get_memory_clock, -	.set_memory_clock = NULL, -	.get_pcie_lanes = NULL, -	.set_pcie_lanes = NULL, -	.set_clock_gating = &radeon_legacy_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &r100_bandwidth_update, -	.hpd_init = &r100_hpd_init, -	.hpd_fini = &r100_hpd_fini, -	.hpd_sense = &r100_hpd_sense, -	.hpd_set_polarity = &r100_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; +int r100_debugfs_rbbm_init(struct radeon_device *rdev); +int r100_debugfs_cp_init(struct radeon_device *rdev); +void r100_cp_disable(struct radeon_device *rdev); +int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); +void r100_cp_fini(struct radeon_device *rdev); +int r100_pci_gart_init(struct radeon_device *rdev); +void r100_pci_gart_fini(struct radeon_device *rdev); +int r100_pci_gart_enable(struct radeon_device *rdev); +void r100_pci_gart_disable(struct radeon_device *rdev); +int r100_debugfs_mc_info_init(struct radeon_device *rdev); +int r100_gui_wait_for_idle(struct radeon_device *rdev); +void r100_ib_fini(struct radeon_device *rdev); +int r100_ib_init(struct radeon_device *rdev); +void r100_irq_disable(struct radeon_device *rdev); +void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save); +void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save); +void r100_vram_init_sizes(struct radeon_device *rdev); +void r100_wb_disable(struct radeon_device *rdev); +void r100_wb_fini(struct radeon_device *rdev); +int r100_wb_init(struct radeon_device *rdev); +void r100_hdp_reset(struct radeon_device *rdev); +int r100_rb2d_reset(struct radeon_device *rdev); +int r100_cp_reset(struct radeon_device *rdev); +void r100_vga_render_disable(struct radeon_device *rdev); +int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, +					 struct radeon_cs_packet *pkt, +					 struct radeon_bo *robj); +int r100_cs_parse_packet0(struct radeon_cs_parser *p, +			  struct radeon_cs_packet *pkt, +			  const unsigned *auth, unsigned n, +			  radeon_packet0_check_t check); +int r100_cs_packet_parse(struct radeon_cs_parser *p, +			 struct radeon_cs_packet *pkt, +			 unsigned idx); +void r100_enable_bm(struct radeon_device *rdev); +void r100_set_common_regs(struct radeon_device *rdev);  /*   * r200,rv250,rs300,rv280 @@ -129,43 +135,6 @@ extern int r200_copy_dma(struct radeon_device *rdev,  			uint64_t dst_offset,  			unsigned num_pages,  			struct radeon_fence *fence); -static struct radeon_asic r200_asic = { -	.init = &r100_init, -	.fini = &r100_fini, -	.suspend = &r100_suspend, -	.resume = &r100_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &r100_gpu_reset, -	.gart_tlb_flush = &r100_pci_gart_tlb_flush, -	.gart_set_page = &r100_pci_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &r100_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &r100_irq_set, -	.irq_process = &r100_irq_process, -	.get_vblank_counter = &r100_get_vblank_counter, -	.fence_ring_emit = &r100_fence_ring_emit, -	.cs_parse = &r100_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_legacy_get_engine_clock, -	.set_engine_clock = &radeon_legacy_set_engine_clock, -	.get_memory_clock = &radeon_legacy_get_memory_clock, -	.set_memory_clock = NULL, -	.set_pcie_lanes = NULL, -	.set_clock_gating = &radeon_legacy_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &r100_bandwidth_update, -	.hpd_init = &r100_hpd_init, -	.hpd_fini = &r100_hpd_fini, -	.hpd_sense = &r100_hpd_sense, -	.hpd_set_polarity = &r100_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; -  /*   * r300,r350,rv350,rv380 @@ -186,82 +155,6 @@ extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v  extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);  extern int rv370_get_pcie_lanes(struct radeon_device *rdev); -static struct radeon_asic r300_asic = { -	.init = &r300_init, -	.fini = &r300_fini, -	.suspend = &r300_suspend, -	.resume = &r300_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &r300_gpu_reset, -	.gart_tlb_flush = &r100_pci_gart_tlb_flush, -	.gart_set_page = &r100_pci_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &r300_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &r100_irq_set, -	.irq_process = &r100_irq_process, -	.get_vblank_counter = &r100_get_vblank_counter, -	.fence_ring_emit = &r300_fence_ring_emit, -	.cs_parse = &r300_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_legacy_get_engine_clock, -	.set_engine_clock = &radeon_legacy_set_engine_clock, -	.get_memory_clock = &radeon_legacy_get_memory_clock, -	.set_memory_clock = NULL, -	.get_pcie_lanes = &rv370_get_pcie_lanes, -	.set_pcie_lanes = &rv370_set_pcie_lanes, -	.set_clock_gating = &radeon_legacy_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &r100_bandwidth_update, -	.hpd_init = &r100_hpd_init, -	.hpd_fini = &r100_hpd_fini, -	.hpd_sense = &r100_hpd_sense, -	.hpd_set_polarity = &r100_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; - - -static struct radeon_asic r300_asic_pcie = { -	.init = &r300_init, -	.fini = &r300_fini, -	.suspend = &r300_suspend, -	.resume = &r300_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &r300_gpu_reset, -	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, -	.gart_set_page = &rv370_pcie_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &r300_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &r100_irq_set, -	.irq_process = &r100_irq_process, -	.get_vblank_counter = &r100_get_vblank_counter, -	.fence_ring_emit = &r300_fence_ring_emit, -	.cs_parse = &r300_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_legacy_get_engine_clock, -	.set_engine_clock = &radeon_legacy_set_engine_clock, -	.get_memory_clock = &radeon_legacy_get_memory_clock, -	.set_memory_clock = NULL, -	.set_pcie_lanes = &rv370_set_pcie_lanes, -	.set_clock_gating = &radeon_legacy_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &r100_bandwidth_update, -	.hpd_init = &r100_hpd_init, -	.hpd_fini = &r100_hpd_fini, -	.hpd_sense = &r100_hpd_sense, -	.hpd_set_polarity = &r100_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; -  /*   * r420,r423,rv410   */ @@ -269,44 +162,6 @@ extern int r420_init(struct radeon_device *rdev);  extern void r420_fini(struct radeon_device *rdev);  extern int r420_suspend(struct radeon_device *rdev);  extern int r420_resume(struct radeon_device *rdev); -static struct radeon_asic r420_asic = { -	.init = &r420_init, -	.fini = &r420_fini, -	.suspend = &r420_suspend, -	.resume = &r420_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &r300_gpu_reset, -	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, -	.gart_set_page = &rv370_pcie_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &r300_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &r100_irq_set, -	.irq_process = &r100_irq_process, -	.get_vblank_counter = &r100_get_vblank_counter, -	.fence_ring_emit = &r300_fence_ring_emit, -	.cs_parse = &r300_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_atom_get_engine_clock, -	.set_engine_clock = &radeon_atom_set_engine_clock, -	.get_memory_clock = &radeon_atom_get_memory_clock, -	.set_memory_clock = &radeon_atom_set_memory_clock, -	.get_pcie_lanes = &rv370_get_pcie_lanes, -	.set_pcie_lanes = &rv370_set_pcie_lanes, -	.set_clock_gating = &radeon_atom_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &r100_bandwidth_update, -	.hpd_init = &r100_hpd_init, -	.hpd_fini = &r100_hpd_fini, -	.hpd_sense = &r100_hpd_sense, -	.hpd_set_polarity = &r100_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; -  /*   * rs400,rs480 @@ -319,44 +174,6 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev);  int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);  uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);  void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -static struct radeon_asic rs400_asic = { -	.init = &rs400_init, -	.fini = &rs400_fini, -	.suspend = &rs400_suspend, -	.resume = &rs400_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &r300_gpu_reset, -	.gart_tlb_flush = &rs400_gart_tlb_flush, -	.gart_set_page = &rs400_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &r300_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &r100_irq_set, -	.irq_process = &r100_irq_process, -	.get_vblank_counter = &r100_get_vblank_counter, -	.fence_ring_emit = &r300_fence_ring_emit, -	.cs_parse = &r300_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_legacy_get_engine_clock, -	.set_engine_clock = &radeon_legacy_set_engine_clock, -	.get_memory_clock = &radeon_legacy_get_memory_clock, -	.set_memory_clock = NULL, -	.get_pcie_lanes = NULL, -	.set_pcie_lanes = NULL, -	.set_clock_gating = &radeon_legacy_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &r100_bandwidth_update, -	.hpd_init = &r100_hpd_init, -	.hpd_fini = &r100_hpd_fini, -	.hpd_sense = &r100_hpd_sense, -	.hpd_set_polarity = &r100_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; -  /*   * rs600. @@ -379,45 +196,6 @@ bool rs600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);  void rs600_hpd_set_polarity(struct radeon_device *rdev,  			    enum radeon_hpd_id hpd); -static struct radeon_asic rs600_asic = { -	.init = &rs600_init, -	.fini = &rs600_fini, -	.suspend = &rs600_suspend, -	.resume = &rs600_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &r300_gpu_reset, -	.gart_tlb_flush = &rs600_gart_tlb_flush, -	.gart_set_page = &rs600_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &r300_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &rs600_irq_set, -	.irq_process = &rs600_irq_process, -	.get_vblank_counter = &rs600_get_vblank_counter, -	.fence_ring_emit = &r300_fence_ring_emit, -	.cs_parse = &r300_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_atom_get_engine_clock, -	.set_engine_clock = &radeon_atom_set_engine_clock, -	.get_memory_clock = &radeon_atom_get_memory_clock, -	.set_memory_clock = &radeon_atom_set_memory_clock, -	.get_pcie_lanes = NULL, -	.set_pcie_lanes = NULL, -	.set_clock_gating = &radeon_atom_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &rs600_bandwidth_update, -	.hpd_init = &rs600_hpd_init, -	.hpd_fini = &rs600_hpd_fini, -	.hpd_sense = &rs600_hpd_sense, -	.hpd_set_polarity = &rs600_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; - -  /*   * rs690,rs740   */ @@ -428,44 +206,6 @@ int rs690_suspend(struct radeon_device *rdev);  uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);  void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);  void rs690_bandwidth_update(struct radeon_device *rdev); -static struct radeon_asic rs690_asic = { -	.init = &rs690_init, -	.fini = &rs690_fini, -	.suspend = &rs690_suspend, -	.resume = &rs690_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &r300_gpu_reset, -	.gart_tlb_flush = &rs400_gart_tlb_flush, -	.gart_set_page = &rs400_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &r300_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &rs600_irq_set, -	.irq_process = &rs600_irq_process, -	.get_vblank_counter = &rs600_get_vblank_counter, -	.fence_ring_emit = &r300_fence_ring_emit, -	.cs_parse = &r300_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r200_copy_dma, -	.get_engine_clock = &radeon_atom_get_engine_clock, -	.set_engine_clock = &radeon_atom_set_engine_clock, -	.get_memory_clock = &radeon_atom_get_memory_clock, -	.set_memory_clock = &radeon_atom_set_memory_clock, -	.get_pcie_lanes = NULL, -	.set_pcie_lanes = NULL, -	.set_clock_gating = &radeon_atom_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &rs690_bandwidth_update, -	.hpd_init = &rs600_hpd_init, -	.hpd_fini = &rs600_hpd_fini, -	.hpd_sense = &rs600_hpd_sense, -	.hpd_set_polarity = &rs600_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; -  /*   * rv515 @@ -481,87 +221,12 @@ void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);  void rv515_bandwidth_update(struct radeon_device *rdev);  int rv515_resume(struct radeon_device *rdev);  int rv515_suspend(struct radeon_device *rdev); -static struct radeon_asic rv515_asic = { -	.init = &rv515_init, -	.fini = &rv515_fini, -	.suspend = &rv515_suspend, -	.resume = &rv515_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &rv515_gpu_reset, -	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, -	.gart_set_page = &rv370_pcie_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &rv515_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &rs600_irq_set, -	.irq_process = &rs600_irq_process, -	.get_vblank_counter = &rs600_get_vblank_counter, -	.fence_ring_emit = &r300_fence_ring_emit, -	.cs_parse = &r300_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_atom_get_engine_clock, -	.set_engine_clock = &radeon_atom_set_engine_clock, -	.get_memory_clock = &radeon_atom_get_memory_clock, -	.set_memory_clock = &radeon_atom_set_memory_clock, -	.get_pcie_lanes = &rv370_get_pcie_lanes, -	.set_pcie_lanes = &rv370_set_pcie_lanes, -	.set_clock_gating = &radeon_atom_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &rv515_bandwidth_update, -	.hpd_init = &rs600_hpd_init, -	.hpd_fini = &rs600_hpd_fini, -	.hpd_sense = &rs600_hpd_sense, -	.hpd_set_polarity = &rs600_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -}; -  /*   * r520,rv530,rv560,rv570,r580   */  int r520_init(struct radeon_device *rdev);  int r520_resume(struct radeon_device *rdev); -static struct radeon_asic r520_asic = { -	.init = &r520_init, -	.fini = &rv515_fini, -	.suspend = &rv515_suspend, -	.resume = &r520_resume, -	.vga_set_state = &r100_vga_set_state, -	.gpu_reset = &rv515_gpu_reset, -	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush, -	.gart_set_page = &rv370_pcie_gart_set_page, -	.cp_commit = &r100_cp_commit, -	.ring_start = &rv515_ring_start, -	.ring_test = &r100_ring_test, -	.ring_ib_execute = &r100_ring_ib_execute, -	.irq_set = &rs600_irq_set, -	.irq_process = &rs600_irq_process, -	.get_vblank_counter = &rs600_get_vblank_counter, -	.fence_ring_emit = &r300_fence_ring_emit, -	.cs_parse = &r300_cs_parse, -	.copy_blit = &r100_copy_blit, -	.copy_dma = &r200_copy_dma, -	.copy = &r100_copy_blit, -	.get_engine_clock = &radeon_atom_get_engine_clock, -	.set_engine_clock = &radeon_atom_set_engine_clock, -	.get_memory_clock = &radeon_atom_get_memory_clock, -	.set_memory_clock = &radeon_atom_set_memory_clock, -	.get_pcie_lanes = &rv370_get_pcie_lanes, -	.set_pcie_lanes = &rv370_set_pcie_lanes, -	.set_clock_gating = &radeon_atom_set_clock_gating, -	.set_surface_reg = r100_set_surface_reg, -	.clear_surface_reg = r100_clear_surface_reg, -	.bandwidth_update = &rv515_bandwidth_update, -	.hpd_init = &rs600_hpd_init, -	.hpd_fini = &rs600_hpd_fini, -	.hpd_sense = &rs600_hpd_sense, -	.hpd_set_polarity = &rs600_hpd_set_polarity, -	.ioctl_wait_idle = NULL, -};  /*   * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880 @@ -591,7 +256,7 @@ int r600_gpu_reset(struct radeon_device *rdev);  int r600_set_surface_reg(struct radeon_device *rdev, int reg,  			 uint32_t tiling_flags, uint32_t pitch,  			 uint32_t offset, uint32_t obj_size); -int r600_clear_surface_reg(struct radeon_device *rdev, int reg); +void r600_clear_surface_reg(struct radeon_device *rdev, int reg);  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, @@ -604,43 +269,6 @@ void r600_hpd_set_polarity(struct radeon_device *rdev,  			   enum radeon_hpd_id hpd);  extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo); -static struct radeon_asic r600_asic = { -	.init = &r600_init, -	.fini = &r600_fini, -	.suspend = &r600_suspend, -	.resume = &r600_resume, -	.cp_commit = &r600_cp_commit, -	.vga_set_state = &r600_vga_set_state, -	.gpu_reset = &r600_gpu_reset, -	.gart_tlb_flush = &r600_pcie_gart_tlb_flush, -	.gart_set_page = &rs600_gart_set_page, -	.ring_test = &r600_ring_test, -	.ring_ib_execute = &r600_ring_ib_execute, -	.irq_set = &r600_irq_set, -	.irq_process = &r600_irq_process, -	.get_vblank_counter = &rs600_get_vblank_counter, -	.fence_ring_emit = &r600_fence_ring_emit, -	.cs_parse = &r600_cs_parse, -	.copy_blit = &r600_copy_blit, -	.copy_dma = &r600_copy_blit, -	.copy = &r600_copy_blit, -	.get_engine_clock = &radeon_atom_get_engine_clock, -	.set_engine_clock = &radeon_atom_set_engine_clock, -	.get_memory_clock = &radeon_atom_get_memory_clock, -	.set_memory_clock = &radeon_atom_set_memory_clock, -	.get_pcie_lanes = &rv370_get_pcie_lanes, -	.set_pcie_lanes = NULL, -	.set_clock_gating = NULL, -	.set_surface_reg = r600_set_surface_reg, -	.clear_surface_reg = r600_clear_surface_reg, -	.bandwidth_update = &rv515_bandwidth_update, -	.hpd_init = &r600_hpd_init, -	.hpd_fini = &r600_hpd_fini, -	.hpd_sense = &r600_hpd_sense, -	.hpd_set_polarity = &r600_hpd_set_polarity, -	.ioctl_wait_idle = r600_ioctl_wait_idle, -}; -  /*   * rv770,rv730,rv710,rv740   */ @@ -650,43 +278,6 @@ int rv770_suspend(struct radeon_device *rdev);  int rv770_resume(struct radeon_device *rdev);  int rv770_gpu_reset(struct radeon_device *rdev); -static struct radeon_asic rv770_asic = { -	.init = &rv770_init, -	.fini = &rv770_fini, -	.suspend = &rv770_suspend, -	.resume = &rv770_resume, -	.cp_commit = &r600_cp_commit, -	.gpu_reset = &rv770_gpu_reset, -	.vga_set_state = &r600_vga_set_state, -	.gart_tlb_flush = &r600_pcie_gart_tlb_flush, -	.gart_set_page = &rs600_gart_set_page, -	.ring_test = &r600_ring_test, -	.ring_ib_execute = &r600_ring_ib_execute, -	.irq_set = &r600_irq_set, -	.irq_process = &r600_irq_process, -	.get_vblank_counter = &rs600_get_vblank_counter, -	.fence_ring_emit = &r600_fence_ring_emit, -	.cs_parse = &r600_cs_parse, -	.copy_blit = &r600_copy_blit, -	.copy_dma = &r600_copy_blit, -	.copy = &r600_copy_blit, -	.get_engine_clock = &radeon_atom_get_engine_clock, -	.set_engine_clock = &radeon_atom_set_engine_clock, -	.get_memory_clock = &radeon_atom_get_memory_clock, -	.set_memory_clock = &radeon_atom_set_memory_clock, -	.get_pcie_lanes = &rv370_get_pcie_lanes, -	.set_pcie_lanes = NULL, -	.set_clock_gating = &radeon_atom_set_clock_gating, -	.set_surface_reg = r600_set_surface_reg, -	.clear_surface_reg = r600_clear_surface_reg, -	.bandwidth_update = &rv515_bandwidth_update, -	.hpd_init = &r600_hpd_init, -	.hpd_fini = &r600_hpd_fini, -	.hpd_sense = &r600_hpd_sense, -	.hpd_set_polarity = &r600_hpd_set_polarity, -	.ioctl_wait_idle = r600_ioctl_wait_idle, -}; -  /*   * evergreen   */ @@ -701,40 +292,4 @@ void evergreen_hpd_fini(struct radeon_device *rdev);  bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd);  void evergreen_hpd_set_polarity(struct radeon_device *rdev,  				enum radeon_hpd_id hpd); - -static struct radeon_asic evergreen_asic = { -	.init = &evergreen_init, -	.fini = &evergreen_fini, -	.suspend = &evergreen_suspend, -	.resume = &evergreen_resume, -	.cp_commit = NULL, -	.gpu_reset = &evergreen_gpu_reset, -	.vga_set_state = &r600_vga_set_state, -	.gart_tlb_flush = &r600_pcie_gart_tlb_flush, -	.gart_set_page = &rs600_gart_set_page, -	.ring_test = NULL, -	.ring_ib_execute = NULL, -	.irq_set = NULL, -	.irq_process = NULL, -	.get_vblank_counter = NULL, -	.fence_ring_emit = NULL, -	.cs_parse = NULL, -	.copy_blit = NULL, -	.copy_dma = NULL, -	.copy = NULL, -	.get_engine_clock = &radeon_atom_get_engine_clock, -	.set_engine_clock = &radeon_atom_set_engine_clock, -	.get_memory_clock = &radeon_atom_get_memory_clock, -	.set_memory_clock = &radeon_atom_set_memory_clock, -	.set_pcie_lanes = NULL, -	.set_clock_gating = NULL, -	.set_surface_reg = r600_set_surface_reg, -	.clear_surface_reg = r600_clear_surface_reg, -	.bandwidth_update = &evergreen_bandwidth_update, -	.hpd_init = &evergreen_hpd_init, -	.hpd_fini = &evergreen_hpd_fini, -	.hpd_sense = &evergreen_hpd_sense, -	.hpd_set_polarity = &evergreen_hpd_set_polarity, -}; -  #endif diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 93783b15c81..9916d825401 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -69,52 +69,54 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev  	struct radeon_i2c_bus_rec i2c;  	int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);  	struct _ATOM_GPIO_I2C_INFO *i2c_info; -	uint16_t data_offset; -	int i; +	uint16_t data_offset, size; +	int i, num_indices;  	memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));  	i2c.valid = false; -	atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); +	if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { +		i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); -	i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); +		num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / +			sizeof(ATOM_GPIO_I2C_ASSIGMENT); +		for (i = 0; i < num_indices; i++) { +			gpio = &i2c_info->asGPIO_Info[i]; -	for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) { -		gpio = &i2c_info->asGPIO_Info[i]; +			if (gpio->sucI2cId.ucAccess == id) { +				i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; +				i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; +				i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; +				i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; +				i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; +				i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; +				i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; +				i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; +				i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); +				i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); +				i2c.en_clk_mask = (1 << gpio->ucClkEnShift); +				i2c.en_data_mask = (1 << gpio->ucDataEnShift); +				i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); +				i2c.y_data_mask = (1 << gpio->ucDataY_Shift); +				i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); +				i2c.a_data_mask = (1 << gpio->ucDataA_Shift); -		if (gpio->sucI2cId.ucAccess == id) { -			i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; -			i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; -			i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; -			i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; -			i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; -			i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; -			i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; -			i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; -			i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); -			i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); -			i2c.en_clk_mask = (1 << gpio->ucClkEnShift); -			i2c.en_data_mask = (1 << gpio->ucDataEnShift); -			i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); -			i2c.y_data_mask = (1 << gpio->ucDataY_Shift); -			i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); -			i2c.a_data_mask = (1 << gpio->ucDataA_Shift); - -			if (gpio->sucI2cId.sbfAccess.bfHW_Capable) -				i2c.hw_capable = true; -			else -				i2c.hw_capable = false; +				if (gpio->sucI2cId.sbfAccess.bfHW_Capable) +					i2c.hw_capable = true; +				else +					i2c.hw_capable = false; -			if (gpio->sucI2cId.ucAccess == 0xa0) -				i2c.mm_i2c = true; -			else -				i2c.mm_i2c = false; +				if (gpio->sucI2cId.ucAccess == 0xa0) +					i2c.mm_i2c = true; +				else +					i2c.mm_i2c = false; -			i2c.i2c_id = gpio->sucI2cId.ucAccess; +				i2c.i2c_id = gpio->sucI2cId.ucAccess; -			i2c.valid = true; -			break; +				i2c.valid = true; +				break; +			}  		}  	} @@ -135,20 +137,21 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd  	memset(&gpio, 0, sizeof(struct radeon_gpio_rec));  	gpio.valid = false; -	atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset); - -	gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); +	if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { +		gpio_info = (struct _ATOM_GPIO_PIN_LUT *)(ctx->bios + data_offset); -	num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / sizeof(ATOM_GPIO_PIN_ASSIGNMENT); +		num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) / +			sizeof(ATOM_GPIO_PIN_ASSIGNMENT); -	for (i = 0; i < num_indices; i++) { -		pin = &gpio_info->asGPIO_Pin[i]; -		if (id == pin->ucGPIO_ID) { -			gpio.id = pin->ucGPIO_ID; -			gpio.reg = pin->usGpioPin_AIndex * 4; -			gpio.mask = (1 << pin->ucGpioPinBitShift); -			gpio.valid = true; -			break; +		for (i = 0; i < num_indices; i++) { +			pin = &gpio_info->asGPIO_Pin[i]; +			if (id == pin->ucGPIO_ID) { +				gpio.id = pin->ucGPIO_ID; +				gpio.reg = pin->usGpioPin_AIndex * 4; +				gpio.mask = (1 << pin->ucGpioPinBitShift); +				gpio.valid = true; +				break; +			}  		}  	} @@ -264,6 +267,8 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,  		if ((supported_device == ATOM_DEVICE_CRT1_SUPPORT) ||  		    (supported_device == ATOM_DEVICE_DFP2_SUPPORT))  			return false; +		if (supported_device == ATOM_DEVICE_CRT2_SUPPORT) +			*line_mux = 0x90;  	}  	/* ASUS HD 3600 XT board lists the DVI port as HDMI */ @@ -395,9 +400,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)  	struct radeon_gpio_rec gpio;  	struct radeon_hpd hpd; -	atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); - -	if (data_offset == 0) +	if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset))  		return false;  	if (crev < 2) @@ -449,37 +452,43 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)  				    GetIndexIntoMasterTable(DATA,  							    IntegratedSystemInfo); -				atom_parse_data_header(ctx, index, &size, &frev, -						       &crev, &igp_offset); +				if (atom_parse_data_header(ctx, index, &size, &frev, +							   &crev, &igp_offset)) { -				if (crev >= 2) { -					igp_obj = -					    (ATOM_INTEGRATED_SYSTEM_INFO_V2 -					     *) (ctx->bios + igp_offset); +					if (crev >= 2) { +						igp_obj = +							(ATOM_INTEGRATED_SYSTEM_INFO_V2 +							 *) (ctx->bios + igp_offset); -					if (igp_obj) { -						uint32_t slot_config, ct; +						if (igp_obj) { +							uint32_t slot_config, ct; -						if (con_obj_num == 1) -							slot_config = -							    igp_obj-> -							    ulDDISlot1Config; -						else -							slot_config = -							    igp_obj-> -							    ulDDISlot2Config; +							if (con_obj_num == 1) +								slot_config = +									igp_obj-> +									ulDDISlot1Config; +							else +								slot_config = +									igp_obj-> +									ulDDISlot2Config; -						ct = (slot_config >> 16) & 0xff; -						connector_type = -						    object_connector_convert -						    [ct]; -						connector_object_id = ct; -						igp_lane_info = -						    slot_config & 0xffff; +							ct = (slot_config >> 16) & 0xff; +							connector_type = +								object_connector_convert +								[ct]; +							connector_object_id = ct; +							igp_lane_info = +								slot_config & 0xffff; +						} else +							continue;  					} else  						continue; -				} else -					continue; +				} else { +					igp_lane_info = 0; +					connector_type = +						object_connector_convert[con_obj_id]; +					connector_object_id = con_obj_id; +				}  			} else {  				igp_lane_info = 0;  				connector_type = @@ -627,20 +636,23 @@ static uint16_t atombios_get_connector_object_id(struct drm_device *dev,  		uint8_t frev, crev;  		ATOM_XTMDS_INFO *xtmds; -		atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); -		xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); +		if (atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) { +			xtmds = (ATOM_XTMDS_INFO *)(ctx->bios + data_offset); -		if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { -			if (connector_type == DRM_MODE_CONNECTOR_DVII) -				return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; -			else -				return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; -		} else { -			if (connector_type == DRM_MODE_CONNECTOR_DVII) -				return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; -			else -				return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; -		} +			if (xtmds->ucSupportedLink & ATOM_XTMDS_SUPPORTED_DUALLINK) { +				if (connector_type == DRM_MODE_CONNECTOR_DVII) +					return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I; +				else +					return CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D; +			} else { +				if (connector_type == DRM_MODE_CONNECTOR_DVII) +					return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; +				else +					return CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D; +			} +		} else +			return supported_devices_connector_object_id_convert +				[connector_type];  	} else {  		return supported_devices_connector_object_id_convert  			[connector_type]; @@ -672,7 +684,8 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct  	int i, j, max_device;  	struct bios_connector bios_connectors[ATOM_MAX_SUPPORTED_DEVICE]; -	atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset); +	if (!atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset)) +		return false;  	supported_devices =  	    (union atom_supported_devices *)(ctx->bios + data_offset); @@ -865,14 +878,11 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)  	struct radeon_pll *mpll = &rdev->clock.mpll;  	uint16_t data_offset; -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, -			       &crev, &data_offset); - -	firmware_info = -	    (union firmware_info *)(mode_info->atom_context->bios + -				    data_offset); - -	if (firmware_info) { +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { +		firmware_info = +			(union firmware_info *)(mode_info->atom_context->bios + +						data_offset);  		/* pixel clocks */  		p1pll->reference_freq =  		    le16_to_cpu(firmware_info->info.usReferenceClock); @@ -887,6 +897,20 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)  		p1pll->pll_out_max =  		    le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); +		if (crev >= 4) { +			p1pll->lcd_pll_out_min = +				le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100; +			if (p1pll->lcd_pll_out_min == 0) +				p1pll->lcd_pll_out_min = p1pll->pll_out_min; +			p1pll->lcd_pll_out_max = +				le16_to_cpu(firmware_info->info_14.usLcdMaxPixelClockPLL_Output) * 100; +			if (p1pll->lcd_pll_out_max == 0) +				p1pll->lcd_pll_out_max = p1pll->pll_out_max; +		} else { +			p1pll->lcd_pll_out_min = p1pll->pll_out_min; +			p1pll->lcd_pll_out_max = p1pll->pll_out_max; +		} +  		if (p1pll->pll_out_min == 0) {  			if (ASIC_IS_AVIVO(rdev))  				p1pll->pll_out_min = 64800; @@ -992,13 +1016,10 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev)  	u8 frev, crev;  	u16 data_offset; -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, -			       &crev, &data_offset); - -	igp_info = (union igp_info *)(mode_info->atom_context->bios + +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { +		igp_info = (union igp_info *)(mode_info->atom_context->bios +  				      data_offset); - -	if (igp_info) {  		switch (crev) {  		case 1:  			if (igp_info->info.ucMemoryType & 0xf0) @@ -1029,14 +1050,12 @@ bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,  	uint16_t maxfreq;  	int i; -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, -			       &crev, &data_offset); - -	tmds_info = -	    (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + -				       data_offset); +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { +		tmds_info = +			(struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + +						   data_offset); -	if (tmds_info) {  		maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);  		for (i = 0; i < 4; i++) {  			tmds->tmds_pll[i].freq = @@ -1085,13 +1104,11 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct  	if (id > ATOM_MAX_SS_ENTRY)  		return NULL; -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, -			       &crev, &data_offset); +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { +		ss_info = +			(struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); -	ss_info = -	    (struct _ATOM_SPREAD_SPECTRUM_INFO *)(mode_info->atom_context->bios + data_offset); - -	if (ss_info) {  		ss =  		    kzalloc(sizeof(struct radeon_atom_ss), GFP_KERNEL); @@ -1114,30 +1131,6 @@ static struct radeon_atom_ss *radeon_atombios_get_ss_info(struct  	return ss;  } -static void radeon_atom_apply_lvds_quirks(struct drm_device *dev, -					  struct radeon_encoder_atom_dig *lvds) -{ - -	/* Toshiba A300-1BU laptop panel doesn't like new pll divider algo */ -	if ((dev->pdev->device == 0x95c4) && -	    (dev->pdev->subsystem_vendor == 0x1179) && -	    (dev->pdev->subsystem_device == 0xff50)) { -		if ((lvds->native_mode.hdisplay == 1280) && -		    (lvds->native_mode.vdisplay == 800)) -			lvds->pll_algo = PLL_ALGO_LEGACY; -	} - -	/* Dell Studio 15 laptop panel doesn't like new pll divider algo */ -	if ((dev->pdev->device == 0x95c4) && -	    (dev->pdev->subsystem_vendor == 0x1028) && -	    (dev->pdev->subsystem_device == 0x029f)) { -		if ((lvds->native_mode.hdisplay == 1280) && -		    (lvds->native_mode.vdisplay == 800)) -			lvds->pll_algo = PLL_ALGO_LEGACY; -	} - -} -  union lvds_info {  	struct _ATOM_LVDS_INFO info;  	struct _ATOM_LVDS_INFO_V12 info_12; @@ -1156,13 +1149,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct  	uint8_t frev, crev;  	struct radeon_encoder_atom_dig *lvds = NULL; -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, -			       &crev, &data_offset); - -	lvds_info = -	    (union lvds_info *)(mode_info->atom_context->bios + data_offset); - -	if (lvds_info) { +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { +		lvds_info = +			(union lvds_info *)(mode_info->atom_context->bios + data_offset);  		lvds =  		    kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); @@ -1220,9 +1210,6 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct  				lvds->pll_algo = PLL_ALGO_LEGACY;  		} -		/* LVDS quirks */ -		radeon_atom_apply_lvds_quirks(dev, lvds); -  		encoder->native_mode = lvds->native_mode;  	}  	return lvds; @@ -1241,11 +1228,11 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)  	uint8_t bg, dac;  	struct radeon_encoder_primary_dac *p_dac = NULL; -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { +		dac_info = (struct _COMPASSIONATE_DATA *) +			(mode_info->atom_context->bios + data_offset); -	dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset); - -	if (dac_info) {  		p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL);  		if (!p_dac) @@ -1270,12 +1257,14 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,  	u8 frev, crev;  	u16 data_offset, misc; -	atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); +	if (!atom_parse_data_header(mode_info->atom_context, data_index, NULL, +				    &frev, &crev, &data_offset)) +		return false;  	switch (crev) {  	case 1:  		tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); -		if (index > MAX_SUPPORTED_TV_TIMING) +		if (index >= MAX_SUPPORTED_TV_TIMING)  			return false;  		mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); @@ -1313,7 +1302,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,  		break;  	case 2:  		tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset); -		if (index > MAX_SUPPORTED_TV_TIMING_V1_2) +		if (index >= MAX_SUPPORTED_TV_TIMING_V1_2)  			return false;  		dtd_timings = &tv_info_v1_2->aModeTimings[index]; @@ -1362,47 +1351,50 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev)  	struct _ATOM_ANALOG_TV_INFO *tv_info;  	enum radeon_tv_std tv_std = TV_STD_NTSC; -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { -	tv_info = (struct _ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); +		tv_info = (struct _ATOM_ANALOG_TV_INFO *) +			(mode_info->atom_context->bios + data_offset); -	switch (tv_info->ucTV_BootUpDefaultStandard) { -	case ATOM_TV_NTSC: -		tv_std = TV_STD_NTSC; -		DRM_INFO("Default TV standard: NTSC\n"); -		break; -	case ATOM_TV_NTSCJ: -		tv_std = TV_STD_NTSC_J; -		DRM_INFO("Default TV standard: NTSC-J\n"); -		break; -	case ATOM_TV_PAL: -		tv_std = TV_STD_PAL; -		DRM_INFO("Default TV standard: PAL\n"); -		break; -	case ATOM_TV_PALM: -		tv_std = TV_STD_PAL_M; -		DRM_INFO("Default TV standard: PAL-M\n"); -		break; -	case ATOM_TV_PALN: -		tv_std = TV_STD_PAL_N; -		DRM_INFO("Default TV standard: PAL-N\n"); -		break; -	case ATOM_TV_PALCN: -		tv_std = TV_STD_PAL_CN; -		DRM_INFO("Default TV standard: PAL-CN\n"); -		break; -	case ATOM_TV_PAL60: -		tv_std = TV_STD_PAL_60; -		DRM_INFO("Default TV standard: PAL-60\n"); -		break; -	case ATOM_TV_SECAM: -		tv_std = TV_STD_SECAM; -		DRM_INFO("Default TV standard: SECAM\n"); -		break; -	default: -		tv_std = TV_STD_NTSC; -		DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); -		break; +		switch (tv_info->ucTV_BootUpDefaultStandard) { +		case ATOM_TV_NTSC: +			tv_std = TV_STD_NTSC; +			DRM_INFO("Default TV standard: NTSC\n"); +			break; +		case ATOM_TV_NTSCJ: +			tv_std = TV_STD_NTSC_J; +			DRM_INFO("Default TV standard: NTSC-J\n"); +			break; +		case ATOM_TV_PAL: +			tv_std = TV_STD_PAL; +			DRM_INFO("Default TV standard: PAL\n"); +			break; +		case ATOM_TV_PALM: +			tv_std = TV_STD_PAL_M; +			DRM_INFO("Default TV standard: PAL-M\n"); +			break; +		case ATOM_TV_PALN: +			tv_std = TV_STD_PAL_N; +			DRM_INFO("Default TV standard: PAL-N\n"); +			break; +		case ATOM_TV_PALCN: +			tv_std = TV_STD_PAL_CN; +			DRM_INFO("Default TV standard: PAL-CN\n"); +			break; +		case ATOM_TV_PAL60: +			tv_std = TV_STD_PAL_60; +			DRM_INFO("Default TV standard: PAL-60\n"); +			break; +		case ATOM_TV_SECAM: +			tv_std = TV_STD_SECAM; +			DRM_INFO("Default TV standard: SECAM\n"); +			break; +		default: +			tv_std = TV_STD_NTSC; +			DRM_INFO("Unknown TV standard; defaulting to NTSC\n"); +			break; +		}  	}  	return tv_std;  } @@ -1420,11 +1412,12 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)  	uint8_t bg, dac;  	struct radeon_encoder_tv_dac *tv_dac = NULL; -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { -	dac_info = (struct _COMPASSIONATE_DATA *)(mode_info->atom_context->bios + data_offset); +		dac_info = (struct _COMPASSIONATE_DATA *) +			(mode_info->atom_context->bios + data_offset); -	if (dac_info) {  		tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL);  		if (!tv_dac) @@ -1447,6 +1440,30 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)  	return tv_dac;  } +static const char *thermal_controller_names[] = { +	"NONE", +	"LM63", +	"ADM1032", +	"ADM1030", +	"MUA6649", +	"LM64", +	"F75375", +	"ASC7512", +}; + +static const char *pp_lib_thermal_controller_names[] = { +	"NONE", +	"LM63", +	"ADM1032", +	"ADM1030", +	"MUA6649", +	"LM64", +	"F75375", +	"RV6xx", +	"RV770", +	"ADT7473", +}; +  union power_info {  	struct _ATOM_POWERPLAY_INFO info;  	struct _ATOM_POWERPLAY_INFO_V2 info_2; @@ -1466,15 +1483,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)  	struct _ATOM_PPLIB_STATE *power_state;  	int num_modes = 0, i, j;  	int state_index = 0, mode_index = 0; - -	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); - -	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); +	struct radeon_i2c_bus_rec i2c_bus;  	rdev->pm.default_power_state = NULL; -	if (power_info) { +	if (atom_parse_data_header(mode_info->atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { +		power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);  		if (frev < 4) { +			/* add the i2c bus for thermal/fan chip */ +			if (power_info->info.ucOverdriveThermalController > 0) { +				DRM_INFO("Possible %s thermal controller at 0x%02x\n", +					 thermal_controller_names[power_info->info.ucOverdriveThermalController], +					 power_info->info.ucOverdriveControllerAddress >> 1); +				i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); +				rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal"); +			}  			num_modes = power_info->info.ucNumOfPowerModeEntries;  			if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK)  				num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; @@ -1684,6 +1708,24 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev)  				}  			}  		} else if (frev == 4) { +			/* add the i2c bus for thermal/fan chip */ +			/* no support for internal controller yet */ +			if (power_info->info_4.sThermalController.ucType > 0) { +				if ((power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || +				    (power_info->info_4.sThermalController.ucType == ATOM_PP_THERMALCONTROLLER_RV770)) { +					DRM_INFO("Internal thermal controller %s fan control\n", +						 (power_info->info_4.sThermalController.ucFanParameters & +						  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); +				} else { +					DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", +						 pp_lib_thermal_controller_names[power_info->info_4.sThermalController.ucType], +						 power_info->info_4.sThermalController.ucI2cAddress >> 1, +						 (power_info->info_4.sThermalController.ucFanParameters & +						  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); +					i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info_4.sThermalController.ucI2cLine); +					rdev->pm.i2c_bus = radeon_i2c_create(rdev->ddev, &i2c_bus, "Thermal"); +				} +			}  			for (i = 0; i < power_info->info_4.ucNumStates; i++) {  				mode_index = 0;  				power_state = (struct _ATOM_PPLIB_STATE *) diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 3f557c4151e..ed5dfe58f29 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -7,6 +7,7 @@   * ATPX support for both Intel/ATI   */  #include <linux/vga_switcheroo.h> +#include <linux/slab.h>  #include <acpi/acpi.h>  #include <acpi/acpi_bus.h>  #include <linux/pci.h> diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 55724046052..8ad71f70131 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -31,6 +31,7 @@  #include "atom.h"  #include <linux/vga_switcheroo.h> +#include <linux/slab.h>  /*   * BIOS.   */ diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index e9ea38ece37..37db8adb274 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -531,10 +531,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde  	case CHIP_RS300:  		switch (ddc_line) {  		case RADEON_GPIO_DVI_DDC: -			/* in theory this should be hw capable, -			 * but it doesn't seem to work -			 */ -			i2c.hw_capable = false; +			i2c.hw_capable = true;  			break;  		default:  			i2c.hw_capable = false; @@ -633,6 +630,8 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)  		p1pll->reference_div = RBIOS16(pll_info + 0x10);  		p1pll->pll_out_min = RBIOS32(pll_info + 0x12);  		p1pll->pll_out_max = RBIOS32(pll_info + 0x16); +		p1pll->lcd_pll_out_min = p1pll->pll_out_min; +		p1pll->lcd_pll_out_max = p1pll->pll_out_max;  		if (rev > 9) {  			p1pll->pll_in_min = RBIOS32(pll_info + 0x36); @@ -761,7 +760,9 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct  			dac = RBIOS8(dac_info + 0x3) & 0xf;  			p_dac->ps2_pdac_adj = (bg << 8) | (dac);  		} -		found = 1; +		/* if the values are all zeros, use the table */ +		if (p_dac->ps2_pdac_adj) +			found = 1;  	}  	if (!found) /* fallback to defaults */ @@ -896,7 +897,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct  			bg = RBIOS8(dac_info + 0x10) & 0xf;  			dac = RBIOS8(dac_info + 0x11) & 0xf;  			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); -			found = 1; +			/* if the values are all zeros, use the table */ +			if (tv_dac->ps2_tvdac_adj) +				found = 1;  		} else if (rev > 1) {  			bg = RBIOS8(dac_info + 0xc) & 0xf;  			dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf; @@ -909,7 +912,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct  			bg = RBIOS8(dac_info + 0xe) & 0xf;  			dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;  			tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20); -			found = 1; +			/* if the values are all zeros, use the table */ +			if (tv_dac->ps2_tvdac_adj) +				found = 1;  		}  		tv_dac->tv_std = radeon_combios_get_tv_info(rdev);  	} @@ -926,7 +931,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct  				    (bg << 16) | (dac << 20);  				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;  				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; -				found = 1; +				/* if the values are all zeros, use the table */ +				if (tv_dac->ps2_tvdac_adj) +					found = 1;  			} else {  				bg = RBIOS8(dac_info + 0x4) & 0xf;  				dac = RBIOS8(dac_info + 0x5) & 0xf; @@ -934,7 +941,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct  				    (bg << 16) | (dac << 20);  				tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;  				tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj; -				found = 1; +				/* if the values are all zeros, use the table */ +				if (tv_dac->ps2_tvdac_adj) +					found = 1;  			}  		} else {  			DRM_INFO("No TV DAC info found in BIOS\n"); diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index ee0083f982d..4559a53d5e5 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -162,12 +162,14 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,  {  	struct drm_device *dev = connector->dev;  	struct drm_connector *conflict; +	struct radeon_connector *radeon_conflict;  	int i;  	list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {  		if (conflict == connector)  			continue; +		radeon_conflict = to_radeon_connector(conflict);  		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {  			if (conflict->encoder_ids[i] == 0)  				break; @@ -177,6 +179,9 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,  				if (conflict->status != connector_status_connected)  					continue; +				if (radeon_conflict->use_digital) +					continue; +  				if (priority == true) {  					DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));  					DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); @@ -287,6 +292,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr  	if (property == rdev->mode_info.coherent_mode_property) {  		struct radeon_encoder_atom_dig *dig; +		bool new_coherent_mode;  		/* need to find digital encoder on connector */  		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS); @@ -299,8 +305,11 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr  			return 0;  		dig = radeon_encoder->enc_priv; -		dig->coherent_mode = val ? true : false; -		radeon_property_change_mode(&radeon_encoder->base); +		new_coherent_mode = val ? true : false; +		if (dig->coherent_mode != new_coherent_mode) { +			dig->coherent_mode = new_coherent_mode; +			radeon_property_change_mode(&radeon_encoder->base); +		}  	}  	if (property == rdev->mode_info.tv_std_property) { @@ -315,7 +324,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr  		radeon_encoder = to_radeon_encoder(encoder);  		if (!radeon_encoder->enc_priv)  			return 0; -		if (rdev->is_atom_bios) { +		if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) {  			struct radeon_encoder_atom_dac *dac_int;  			dac_int = radeon_encoder->enc_priv;  			dac_int->tv_std = val; @@ -940,7 +949,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)  	if (radeon_connector->edid)  		kfree(radeon_connector->edid);  	if (radeon_dig_connector->dp_i2c_bus) -		radeon_i2c_destroy_dp(radeon_dig_connector->dp_i2c_bus); +		radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);  	kfree(radeon_connector->con_priv);  	drm_sysfs_connector_remove(connector);  	drm_connector_cleanup(connector); @@ -1307,6 +1316,8 @@ radeon_add_legacy_connector(struct drm_device *dev,  			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");  			if (!radeon_connector->ddc_bus)  				goto failed; +		} +		if (connector_type == DRM_MODE_CONNECTOR_DVII) {  			radeon_connector->dac_load_detect = true;  			drm_connector_attach_property(&radeon_connector->base,  						      rdev->mode_info.load_detect_property, diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index dc6eba6b96d..2f042a3c0e6 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c @@ -417,8 +417,9 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)  	return -EBUSY;  } -static void radeon_init_pipes(drm_radeon_private_t *dev_priv) +static void radeon_init_pipes(struct drm_device *dev)  { +	drm_radeon_private_t *dev_priv = dev->dev_private;  	uint32_t gb_tile_config, gb_pipe_sel = 0;  	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) { @@ -434,13 +435,19 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)  	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {  		gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);  		dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1; +		/* SE cards have 1 pipe */ +		if ((dev->pdev->device == 0x5e4c) || +		    (dev->pdev->device == 0x5e4f)) +			dev_priv->num_gb_pipes = 1;  	} else {  		/* R3xx */ -		if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || -		    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) { +		if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 && +		     dev->pdev->device != 0x4144) || +		    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 && +		     dev->pdev->device != 0x4148)) {  			dev_priv->num_gb_pipes = 2;  		} else { -			/* R3Vxx */ +			/* RV3xx/R300 AD/R350 AH */  			dev_priv->num_gb_pipes = 1;  		}  	} @@ -736,7 +743,7 @@ static int radeon_do_engine_reset(struct drm_device * dev)  	/* setup the raster pipes */  	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300) -	    radeon_init_pipes(dev_priv); +	    radeon_init_pipes(dev);  	/* Reset the CP ring */  	radeon_do_cp_reset(dev_priv); diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 70ba02ed772..f9b0fe002c0 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -193,9 +193,11 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)  		radeon_bo_list_fence(&parser->validated, parser->ib->fence);  	}  	radeon_bo_list_unreserve(&parser->validated); -	for (i = 0; i < parser->nrelocs; i++) { -		if (parser->relocs[i].gobj) -			drm_gem_object_unreference_unlocked(parser->relocs[i].gobj); +	if (parser->relocs != NULL) { +		for (i = 0; i < parser->nrelocs; i++) { +			if (parser->relocs[i].gobj) +				drm_gem_object_unreference_unlocked(parser->relocs[i].gobj); +		}  	}  	kfree(parser->track);  	kfree(parser->relocs); @@ -243,7 +245,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  	}  	r = radeon_cs_parser_relocs(&parser);  	if (r) { -		DRM_ERROR("Failed to parse relocation !\n"); +		if (r != -ERESTARTSYS) +			DRM_ERROR("Failed to parse relocation %d!\n", r);  		radeon_cs_parser_fini(&parser, r);  		mutex_unlock(&rdev->cs_mutex);  		return r; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e28e4ed5f72..7b629e30556 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -26,6 +26,7 @@   *          Jerome Glisse   */  #include <linux/console.h> +#include <linux/slab.h>  #include <drm/drmP.h>  #include <drm/drm_crtc_helper.h>  #include <drm/radeon_drm.h> @@ -33,9 +34,56 @@  #include <linux/vga_switcheroo.h>  #include "radeon_reg.h"  #include "radeon.h" -#include "radeon_asic.h"  #include "atom.h" +static const char radeon_family_name[][16] = { +	"R100", +	"RV100", +	"RS100", +	"RV200", +	"RS200", +	"R200", +	"RV250", +	"RS300", +	"RV280", +	"R300", +	"R350", +	"RV350", +	"RV380", +	"R420", +	"R423", +	"RV410", +	"RS400", +	"RS480", +	"RS600", +	"RS690", +	"RS740", +	"RV515", +	"R520", +	"RV530", +	"RV560", +	"RV570", +	"R580", +	"R600", +	"RV610", +	"RV630", +	"RV670", +	"RV620", +	"RV635", +	"RS780", +	"RS880", +	"RV770", +	"RV730", +	"RV710", +	"RV740", +	"CEDAR", +	"REDWOOD", +	"JUNIPER", +	"CYPRESS", +	"HEMLOCK", +	"LAST", +}; +  /*   * Clear GPU surface registers.   */ @@ -242,6 +290,36 @@ bool radeon_card_posted(struct radeon_device *rdev)  } +void radeon_update_bandwidth_info(struct radeon_device *rdev) +{ +	fixed20_12 a; +	u32 sclk, mclk; + +	if (rdev->flags & RADEON_IS_IGP) { +		sclk = radeon_get_engine_clock(rdev); +		mclk = rdev->clock.default_mclk; + +		a.full = rfixed_const(100); +		rdev->pm.sclk.full = rfixed_const(sclk); +		rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); +		rdev->pm.mclk.full = rfixed_const(mclk); +		rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a); + +		a.full = rfixed_const(16); +		/* core_bandwidth = sclk(Mhz) * 16 */ +		rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a); +	} else { +		sclk = radeon_get_engine_clock(rdev); +		mclk = radeon_get_memory_clock(rdev); + +		a.full = rfixed_const(100); +		rdev->pm.sclk.full = rfixed_const(sclk); +		rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); +		rdev->pm.mclk.full = rfixed_const(mclk); +		rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a); +	} +} +  bool radeon_boot_test_post_card(struct radeon_device *rdev)  {  	if (radeon_card_posted(rdev)) @@ -288,181 +366,6 @@ void radeon_dummy_page_fini(struct radeon_device *rdev)  } -/* - * Registers accessors functions. - */ -uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg) -{ -	DRM_ERROR("Invalid callback to read register 0x%04X\n", reg); -	BUG_ON(1); -	return 0; -} - -void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -{ -	DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n", -		  reg, v); -	BUG_ON(1); -} - -void radeon_register_accessor_init(struct radeon_device *rdev) -{ -	rdev->mc_rreg = &radeon_invalid_rreg; -	rdev->mc_wreg = &radeon_invalid_wreg; -	rdev->pll_rreg = &radeon_invalid_rreg; -	rdev->pll_wreg = &radeon_invalid_wreg; -	rdev->pciep_rreg = &radeon_invalid_rreg; -	rdev->pciep_wreg = &radeon_invalid_wreg; - -	/* Don't change order as we are overridding accessor. */ -	if (rdev->family < CHIP_RV515) { -		rdev->pcie_reg_mask = 0xff; -	} else { -		rdev->pcie_reg_mask = 0x7ff; -	} -	/* FIXME: not sure here */ -	if (rdev->family <= CHIP_R580) { -		rdev->pll_rreg = &r100_pll_rreg; -		rdev->pll_wreg = &r100_pll_wreg; -	} -	if (rdev->family >= CHIP_R420) { -		rdev->mc_rreg = &r420_mc_rreg; -		rdev->mc_wreg = &r420_mc_wreg; -	} -	if (rdev->family >= CHIP_RV515) { -		rdev->mc_rreg = &rv515_mc_rreg; -		rdev->mc_wreg = &rv515_mc_wreg; -	} -	if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) { -		rdev->mc_rreg = &rs400_mc_rreg; -		rdev->mc_wreg = &rs400_mc_wreg; -	} -	if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { -		rdev->mc_rreg = &rs690_mc_rreg; -		rdev->mc_wreg = &rs690_mc_wreg; -	} -	if (rdev->family == CHIP_RS600) { -		rdev->mc_rreg = &rs600_mc_rreg; -		rdev->mc_wreg = &rs600_mc_wreg; -	} -	if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) { -		rdev->pciep_rreg = &r600_pciep_rreg; -		rdev->pciep_wreg = &r600_pciep_wreg; -	} -} - - -/* - * ASIC - */ -int radeon_asic_init(struct radeon_device *rdev) -{ -	radeon_register_accessor_init(rdev); -	switch (rdev->family) { -	case CHIP_R100: -	case CHIP_RV100: -	case CHIP_RS100: -	case CHIP_RV200: -	case CHIP_RS200: -		rdev->asic = &r100_asic; -		break; -	case CHIP_R200: -	case CHIP_RV250: -	case CHIP_RS300: -	case CHIP_RV280: -		rdev->asic = &r200_asic; -		break; -	case CHIP_R300: -	case CHIP_R350: -	case CHIP_RV350: -	case CHIP_RV380: -		if (rdev->flags & RADEON_IS_PCIE) -			rdev->asic = &r300_asic_pcie; -		else -			rdev->asic = &r300_asic; -		break; -	case CHIP_R420: -	case CHIP_R423: -	case CHIP_RV410: -		rdev->asic = &r420_asic; -		break; -	case CHIP_RS400: -	case CHIP_RS480: -		rdev->asic = &rs400_asic; -		break; -	case CHIP_RS600: -		rdev->asic = &rs600_asic; -		break; -	case CHIP_RS690: -	case CHIP_RS740: -		rdev->asic = &rs690_asic; -		break; -	case CHIP_RV515: -		rdev->asic = &rv515_asic; -		break; -	case CHIP_R520: -	case CHIP_RV530: -	case CHIP_RV560: -	case CHIP_RV570: -	case CHIP_R580: -		rdev->asic = &r520_asic; -		break; -	case CHIP_R600: -	case CHIP_RV610: -	case CHIP_RV630: -	case CHIP_RV620: -	case CHIP_RV635: -	case CHIP_RV670: -	case CHIP_RS780: -	case CHIP_RS880: -		rdev->asic = &r600_asic; -		break; -	case CHIP_RV770: -	case CHIP_RV730: -	case CHIP_RV710: -	case CHIP_RV740: -		rdev->asic = &rv770_asic; -		break; -	case CHIP_CEDAR: -	case CHIP_REDWOOD: -	case CHIP_JUNIPER: -	case CHIP_CYPRESS: -	case CHIP_HEMLOCK: -		rdev->asic = &evergreen_asic; -		break; -	default: -		/* FIXME: not supported yet */ -		return -EINVAL; -	} - -	if (rdev->flags & RADEON_IS_IGP) { -		rdev->asic->get_memory_clock = NULL; -		rdev->asic->set_memory_clock = NULL; -	} - -	return 0; -} - - -/* - * Wrapper around modesetting bits. - */ -int radeon_clocks_init(struct radeon_device *rdev) -{ -	int r; - -	r = radeon_static_clocks_init(rdev->ddev); -	if (r) { -		return r; -	} -	DRM_INFO("Clocks initialized !\n"); -	return 0; -} - -void radeon_clocks_fini(struct radeon_device *rdev) -{ -} -  /* ATOM accessor methods */  static uint32_t cail_pll_read(struct card_info *info, uint32_t reg)  { @@ -567,29 +470,6 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state)  		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;  } -void radeon_agp_disable(struct radeon_device *rdev) -{ -	rdev->flags &= ~RADEON_IS_AGP; -	if (rdev->family >= CHIP_R600) { -		DRM_INFO("Forcing AGP to PCIE mode\n"); -		rdev->flags |= RADEON_IS_PCIE; -	} else if (rdev->family >= CHIP_RV515 || -			rdev->family == CHIP_RV380 || -			rdev->family == CHIP_RV410 || -			rdev->family == CHIP_R423) { -		DRM_INFO("Forcing AGP to PCIE mode\n"); -		rdev->flags |= RADEON_IS_PCIE; -		rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; -		rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; -	} else { -		DRM_INFO("Forcing AGP to PCI mode\n"); -		rdev->flags |= RADEON_IS_PCI; -		rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; -		rdev->asic->gart_set_page = &r100_pci_gart_set_page; -	} -	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; -} -  void radeon_check_arguments(struct radeon_device *rdev)  {  	/* vramlimit must be a power of two */ @@ -694,7 +574,6 @@ int radeon_device_init(struct radeon_device *rdev,  	int r;  	int dma_bits; -	DRM_INFO("radeon: Initializing kernel modesetting.\n");  	rdev->shutdown = false;  	rdev->dev = &pdev->dev;  	rdev->ddev = ddev; @@ -706,6 +585,10 @@ int radeon_device_init(struct radeon_device *rdev,  	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;  	rdev->gpu_lockup = false;  	rdev->accel_working = false; + +	DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n", +		radeon_family_name[rdev->family], pdev->vendor, pdev->device); +  	/* mutex initialization are all done here so we  	 * can recall function without having locking issues */  	mutex_init(&rdev->cs_mutex); @@ -731,6 +614,14 @@ int radeon_device_init(struct radeon_device *rdev,  		return r;  	radeon_check_arguments(rdev); +	/* all of the newer IGP chips have an internal gart +	 * However some rs4xx report as AGP, so remove that here. +	 */ +	if ((rdev->family >= CHIP_RS400) && +	    (rdev->flags & RADEON_IS_IGP)) { +		rdev->flags &= ~RADEON_IS_AGP; +	} +  	if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {  		radeon_agp_disable(rdev);  	} diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index ba8d806dcf3..bb1c122cad2 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -86,12 +86,12 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc)  	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);  	WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff); -	WREG32(EVERGREEN_DC_LUT_RW_MODE, radeon_crtc->crtc_id); -	WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK, 0x00000007); +	WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0); +	WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007); -	WREG32(EVERGREEN_DC_LUT_RW_INDEX, 0); +	WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);  	for (i = 0; i < 256; i++) { -		WREG32(EVERGREEN_DC_LUT_30_COLOR, +		WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,  		       (radeon_crtc->lut_r[i] << 20) |  		       (radeon_crtc->lut_g[i] << 10) |  		       (radeon_crtc->lut_b[i] << 0)); @@ -368,10 +368,9 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)  	if (rdev->bios) {  		if (rdev->is_atom_bios) { -			if (rdev->family >= CHIP_R600) +			ret = radeon_get_atom_connector_info_from_supported_devices_table(dev); +			if (ret == false)  				ret = radeon_get_atom_connector_info_from_object_table(dev); -			else -				ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);  		} else {  			ret = radeon_get_legacy_connector_info_from_bios(dev);  			if (ret == false) @@ -469,10 +468,19 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,  	uint32_t best_error = 0xffffffff;  	uint32_t best_vco_diff = 1;  	uint32_t post_div; +	u32 pll_out_min, pll_out_max;  	DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);  	freq = freq * 1000; +	if (pll->flags & RADEON_PLL_IS_LCD) { +		pll_out_min = pll->lcd_pll_out_min; +		pll_out_max = pll->lcd_pll_out_max; +	} else { +		pll_out_min = pll->pll_out_min; +		pll_out_max = pll->pll_out_max; +	} +  	if (pll->flags & RADEON_PLL_USE_REF_DIV)  		min_ref_div = max_ref_div = pll->reference_div;  	else { @@ -536,10 +544,10 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,  				tmp = (uint64_t)pll->reference_freq * feedback_div;  				vco = radeon_div(tmp, ref_div); -				if (vco < pll->pll_out_min) { +				if (vco < pll_out_min) {  					min_feed_div = feedback_div + 1;  					continue; -				} else if (vco > pll->pll_out_max) { +				} else if (vco > pll_out_max) {  					max_feed_div = feedback_div;  					continue;  				} @@ -675,6 +683,15 @@ calc_fb_ref_div(struct radeon_pll *pll,  {  	fixed20_12 ffreq, max_error, error, pll_out, a;  	u32 vco; +	u32 pll_out_min, pll_out_max; + +	if (pll->flags & RADEON_PLL_IS_LCD) { +		pll_out_min = pll->lcd_pll_out_min; +		pll_out_max = pll->lcd_pll_out_max; +	} else { +		pll_out_min = pll->pll_out_min; +		pll_out_max = pll->pll_out_max; +	}  	ffreq.full = rfixed_const(freq);  	/* max_error = ffreq * 0.0025; */ @@ -686,7 +703,7 @@ calc_fb_ref_div(struct radeon_pll *pll,  			vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac));  			vco = vco / ((*ref_div) * 10); -			if ((vco < pll->pll_out_min) || (vco > pll->pll_out_max)) +			if ((vco < pll_out_min) || (vco > pll_out_max))  				continue;  			/* pll_out = vco / post_div; */ @@ -714,6 +731,15 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,  {  	u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0;  	u32 best_freq = 0, vco_frequency; +	u32 pll_out_min, pll_out_max; + +	if (pll->flags & RADEON_PLL_IS_LCD) { +		pll_out_min = pll->lcd_pll_out_min; +		pll_out_max = pll->lcd_pll_out_max; +	} else { +		pll_out_min = pll->pll_out_min; +		pll_out_max = pll->pll_out_max; +	}  	/* freq = freq / 10; */  	do_div(freq, 10); @@ -724,7 +750,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,  			goto done;  		vco_frequency = freq * post_div; -		if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) +		if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))  			goto done;  		if (pll->flags & RADEON_PLL_USE_REF_DIV) { @@ -749,7 +775,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,  				continue;  			vco_frequency = freq * post_div; -			if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) +			if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))  				continue;  			if (pll->flags & RADEON_PLL_USE_REF_DIV) {  				ref_div = pll->reference_div; @@ -945,6 +971,23 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)  	return 0;  } +void radeon_update_display_priority(struct radeon_device *rdev) +{ +	/* adjustment options for the display watermarks */ +	if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) { +		/* set display priority to high for r3xx, rv515 chips +		 * this avoids flickering due to underflow to the +		 * display controllers during heavy acceleration. +		 */ +		if (ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515)) +			rdev->disp_priority = 2; +		else +			rdev->disp_priority = 0; +	} else +		rdev->disp_priority = radeon_disp_priority; + +} +  int radeon_modeset_init(struct radeon_device *rdev)  {  	int i; @@ -976,15 +1019,6 @@ int radeon_modeset_init(struct radeon_device *rdev)  		radeon_combios_check_hardcoded_edid(rdev);  	} -	if (rdev->flags & RADEON_SINGLE_CRTC) -		rdev->num_crtc = 1; -	else { -		if (ASIC_IS_DCE4(rdev)) -			rdev->num_crtc = 6; -		else -			rdev->num_crtc = 2; -	} -  	/* allocate crtcs */  	for (i = 0; i < rdev->num_crtc; i++) {  		radeon_crtc_init(rdev->ddev, i); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 6eec0ece6a6..b3749d47be7 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -42,9 +42,11 @@   * KMS wrapper.   * - 2.0.0 - initial interface   * - 2.1.0 - add square tiling interface + * - 2.2.0 - add r6xx/r7xx const buffer support + * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs   */  #define KMS_DRIVER_MAJOR	2 -#define KMS_DRIVER_MINOR	1 +#define KMS_DRIVER_MINOR	3  #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); @@ -91,6 +93,8 @@ int radeon_tv = 1;  int radeon_new_pll = -1;  int radeon_dynpm = -1;  int radeon_audio = 1; +int radeon_disp_priority = 0; +int radeon_hw_i2c = 0;  MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");  module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -134,6 +138,12 @@ module_param_named(dynpm, radeon_dynpm, int, 0444);  MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");  module_param_named(audio, radeon_audio, int, 0444); +MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)"); +module_param_named(disp_priority, radeon_disp_priority, int, 0444); + +MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)"); +module_param_named(hw_i2c, radeon_hw_i2c, int, 0444); +  static int radeon_suspend(struct drm_device *dev, pm_message_t state)  {  	drm_radeon_private_t *dev_priv = dev->dev_private; @@ -206,6 +216,7 @@ static struct drm_driver driver_old = {  		 .mmap = drm_mmap,  		 .poll = drm_poll,  		 .fasync = drm_fasync, +		 .read = drm_read,  #ifdef CONFIG_COMPAT  		 .compat_ioctl = radeon_compat_ioctl,  #endif @@ -294,6 +305,7 @@ static struct drm_driver kms_driver = {  		 .mmap = radeon_mmap,  		 .poll = drm_poll,  		 .fasync = drm_fasync, +		 .read = drm_read,  #ifdef CONFIG_COMPAT  		 .compat_ioctl = radeon_kms_compat_ioctl,  #endif diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index ec55f2b23c2..448eba89d1e 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -107,9 +107,10 @@   * 1.30- Add support for occlusion queries   * 1.31- Add support for num Z pipes from GET_PARAM   * 1.32- fixes for rv740 setup + * 1.33- Add r6xx/r7xx const buffer support   */  #define DRIVER_MAJOR		1 -#define DRIVER_MINOR		32 +#define DRIVER_MINOR		33  #define DRIVER_PATCHLEVEL	0  enum radeon_cp_microcode_version { diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index bc926ea0a53..c5ddaf58563 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -254,6 +254,53 @@ radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder)  	return dig_connector;  } +void radeon_panel_mode_fixup(struct drm_encoder *encoder, +			     struct drm_display_mode *adjusted_mode) +{ +	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); +	struct drm_device *dev = encoder->dev; +	struct radeon_device *rdev = dev->dev_private; +	struct drm_display_mode *native_mode = &radeon_encoder->native_mode; +	unsigned hblank = native_mode->htotal - native_mode->hdisplay; +	unsigned vblank = native_mode->vtotal - native_mode->vdisplay; +	unsigned hover = native_mode->hsync_start - native_mode->hdisplay; +	unsigned vover = native_mode->vsync_start - native_mode->vdisplay; +	unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start; +	unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start; + +	adjusted_mode->clock = native_mode->clock; +	adjusted_mode->flags = native_mode->flags; + +	if (ASIC_IS_AVIVO(rdev)) { +		adjusted_mode->hdisplay = native_mode->hdisplay; +		adjusted_mode->vdisplay = native_mode->vdisplay; +	} + +	adjusted_mode->htotal = native_mode->hdisplay + hblank; +	adjusted_mode->hsync_start = native_mode->hdisplay + hover; +	adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width; + +	adjusted_mode->vtotal = native_mode->vdisplay + vblank; +	adjusted_mode->vsync_start = native_mode->vdisplay + vover; +	adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width; + +	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + +	if (ASIC_IS_AVIVO(rdev)) { +		adjusted_mode->crtc_hdisplay = native_mode->hdisplay; +		adjusted_mode->crtc_vdisplay = native_mode->vdisplay; +	} + +	adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank; +	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover; +	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width; + +	adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank; +	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover; +	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width; + +} +  static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,  				   struct drm_display_mode *mode,  				   struct drm_display_mode *adjusted_mode) @@ -275,18 +322,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,  		adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;  	/* get the native mode for LVDS */ -	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { -		struct drm_display_mode *native_mode = &radeon_encoder->native_mode; -		int mode_id = adjusted_mode->base.id; -		*adjusted_mode = *native_mode; -		if (!ASIC_IS_AVIVO(rdev)) { -			adjusted_mode->hdisplay = mode->hdisplay; -			adjusted_mode->vdisplay = mode->vdisplay; -			adjusted_mode->crtc_hdisplay = mode->hdisplay; -			adjusted_mode->crtc_vdisplay = mode->vdisplay; -		} -		adjusted_mode->base.id = mode_id; -	} +	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) +		radeon_panel_mode_fixup(encoder, adjusted_mode);  	/* get the native mode for TV */  	if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) { @@ -302,7 +339,7 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,  	}  	if (ASIC_IS_DCE3(rdev) && -	    (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT))) { +	    (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))) {  		struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);  		radeon_dp_set_link_config(connector, mode);  	} @@ -317,12 +354,8 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);  	DAC_ENCODER_CONTROL_PS_ALLOCATION args; -	int index = 0, num = 0; +	int index = 0;  	struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; -	enum radeon_tv_std tv_std = TV_STD_NTSC; - -	if (dac_info->tv_std) -		tv_std = dac_info->tv_std;  	memset(&args, 0, sizeof(args)); @@ -330,12 +363,10 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)  	case ENCODER_OBJECT_ID_INTERNAL_DAC1:  	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:  		index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); -		num = 1;  		break;  	case ENCODER_OBJECT_ID_INTERNAL_DAC2:  	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:  		index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); -		num = 2;  		break;  	} @@ -346,7 +377,7 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)  	else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))  		args.ucDacStandard = ATOM_DAC1_CV;  	else { -		switch (tv_std) { +		switch (dac_info->tv_std) {  		case TV_STD_PAL:  		case TV_STD_PAL_M:  		case TV_STD_SCART_PAL: @@ -377,10 +408,6 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)  	TV_ENCODER_CONTROL_PS_ALLOCATION args;  	int index = 0;  	struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv; -	enum radeon_tv_std tv_std = TV_STD_NTSC; - -	if (dac_info->tv_std) -		tv_std = dac_info->tv_std;  	memset(&args, 0, sizeof(args)); @@ -391,7 +418,7 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)  	if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))  		args.sTVEncoder.ucTvStandard = ATOM_TV_CV;  	else { -		switch (tv_std) { +		switch (dac_info->tv_std) {  		case TV_STD_NTSC:  			args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;  			break; @@ -519,7 +546,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)  		break;  	} -	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); +	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) +		return;  	switch (frev) {  	case 1: @@ -593,7 +621,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)  	}  	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -	r600_hdmi_enable(encoder, hdmi_detected);  }  int @@ -708,7 +735,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)  	struct radeon_connector_atom_dig *dig_connector =  		radeon_get_atom_connector_priv_from_encoder(encoder);  	union dig_encoder_control args; -	int index = 0, num = 0; +	int index = 0;  	uint8_t frev, crev;  	if (!dig || !dig_connector) @@ -724,9 +751,9 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)  		else  			index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);  	} -	num = dig->dig_encoder + 1; -	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); +	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) +		return;  	args.v1.ucAction = action;  	args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); @@ -785,7 +812,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t  	struct drm_connector *connector;  	struct radeon_connector *radeon_connector;  	union dig_transmitter_control args; -	int index = 0, num = 0; +	int index = 0;  	uint8_t frev, crev;  	bool is_dp = false;  	int pll_id = 0; @@ -814,7 +841,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t  		}  	} -	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); +	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) +		return;  	args.v1.ucAction = action;  	if (action == ATOM_TRANSMITTER_ACTION_INIT) { @@ -860,15 +888,12 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t  		switch (radeon_encoder->encoder_id) {  		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:  			args.v3.acConfig.ucTransmitterSel = 0; -			num = 0;  			break;  		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:  			args.v3.acConfig.ucTransmitterSel = 1; -			num = 1;  			break;  		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:  			args.v3.acConfig.ucTransmitterSel = 2; -			num = 2;  			break;  		} @@ -877,25 +902,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t  		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {  			if (dig->coherent_mode)  				args.v3.acConfig.fCoherentMode = 1; +			if (radeon_encoder->pixel_clock > 165000) +				args.v3.acConfig.fDualLinkConnector = 1;  		}  	} else if (ASIC_IS_DCE32(rdev)) { -		if (dig->dig_encoder == 1) -			args.v2.acConfig.ucEncoderSel = 1; +		args.v2.acConfig.ucEncoderSel = dig->dig_encoder;  		if (dig_connector->linkb)  			args.v2.acConfig.ucLinkSel = 1;  		switch (radeon_encoder->encoder_id) {  		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:  			args.v2.acConfig.ucTransmitterSel = 0; -			num = 0;  			break;  		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:  			args.v2.acConfig.ucTransmitterSel = 1; -			num = 1;  			break;  		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:  			args.v2.acConfig.ucTransmitterSel = 2; -			num = 2;  			break;  		} @@ -904,6 +927,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t  		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {  			if (dig->coherent_mode)  				args.v2.acConfig.fCoherentMode = 1; +			if (radeon_encoder->pixel_clock > 165000) +				args.v2.acConfig.fDualLinkConnector = 1;  		}  	} else {  		args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; @@ -913,31 +938,25 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t  		else  			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER; -		switch (radeon_encoder->encoder_id) { -		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: -			if (rdev->flags & RADEON_IS_IGP) { -				if (radeon_encoder->pixel_clock > 165000) { -					if (dig_connector->igp_lane_info & 0x3) -						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; -					else if (dig_connector->igp_lane_info & 0xc) -						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; -				} else { -					if (dig_connector->igp_lane_info & 0x1) -						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; -					else if (dig_connector->igp_lane_info & 0x2) -						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; -					else if (dig_connector->igp_lane_info & 0x4) -						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; -					else if (dig_connector->igp_lane_info & 0x8) -						args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; -				} +		if ((rdev->flags & RADEON_IS_IGP) && +		    (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { +			if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { +				if (dig_connector->igp_lane_info & 0x1) +					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; +				else if (dig_connector->igp_lane_info & 0x2) +					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; +				else if (dig_connector->igp_lane_info & 0x4) +					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; +				else if (dig_connector->igp_lane_info & 0x8) +					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; +			} else { +				if (dig_connector->igp_lane_info & 0x3) +					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; +				else if (dig_connector->igp_lane_info & 0xc) +					args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;  			} -			break;  		} -		if (radeon_encoder->pixel_clock > 165000) -			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; -  		if (dig_connector->linkb)  			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB;  		else @@ -948,6 +967,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t  		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {  			if (dig->coherent_mode)  				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; +			if (radeon_encoder->pixel_clock > 165000) +				args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;  		}  	} @@ -1054,16 +1075,25 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)  	if (is_dig) {  		switch (mode) {  		case DRM_MODE_DPMS_ON: -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); -			{ +			if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {  				struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); +  				dp_link_train(encoder, connector); +				if (ASIC_IS_DCE4(rdev)) +					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON);  			} +			if (!ASIC_IS_DCE4(rdev)) +				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);  			break;  		case DRM_MODE_DPMS_STANDBY:  		case DRM_MODE_DPMS_SUSPEND:  		case DRM_MODE_DPMS_OFF: -			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); +			if (!ASIC_IS_DCE4(rdev)) +				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); +			if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { +				if (ASIC_IS_DCE4(rdev)) +					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); +			}  			break;  		}  	} else { @@ -1104,7 +1134,8 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)  	memset(&args, 0, sizeof(args)); -	atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); +	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) +		return;  	switch (frev) {  	case 1: @@ -1216,6 +1247,9 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)  	}  	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + +	/* update scratch regs with new routing */ +	radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);  }  static void @@ -1326,20 +1360,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,  	struct drm_device *dev = encoder->dev;  	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); -	if (radeon_encoder->active_device & -	    (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { -		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; -		if (dig) -			dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); -	}  	radeon_encoder->pixel_clock = adjusted_mode->clock; -	radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); -	atombios_set_encoder_crtc_source(encoder); - -	if (ASIC_IS_AVIVO(rdev)) { +	if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {  		if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))  			atombios_yuv_setup(encoder, true);  		else @@ -1390,15 +1414,20 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,  	case ENCODER_OBJECT_ID_INTERNAL_DAC2:  	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:  		atombios_dac_setup(encoder, ATOM_ENABLE); -		if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) -			atombios_tv_setup(encoder, ATOM_ENABLE); +		if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { +			if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) +				atombios_tv_setup(encoder, ATOM_ENABLE); +			else +				atombios_tv_setup(encoder, ATOM_DISABLE); +		}  		break;  	}  	atombios_apply_encoder_quirks(encoder, adjusted_mode); -	/* XXX */ -	if (!ASIC_IS_DCE4(rdev)) +	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { +		r600_hdmi_enable(encoder);  		r600_hdmi_setmode(encoder, adjusted_mode); +	}  }  static bool @@ -1418,7 +1447,8 @@ atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *conn  		memset(&args, 0, sizeof(args)); -		atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); +		if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) +			return false;  		args.sDacload.ucMisc = 0; @@ -1492,8 +1522,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec  static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)  { +	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + +	if (radeon_encoder->active_device & +	    (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { +		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +		if (dig) +			dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); +	} +  	radeon_atom_output_lock(encoder, true);  	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); + +	/* this is needed for the pll/ss setup to work correctly in some cases */ +	atombios_set_encoder_crtc_source(encoder);  }  static void radeon_atom_encoder_commit(struct drm_encoder *encoder) @@ -1509,6 +1551,8 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)  	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);  	if (radeon_encoder_is_digital(encoder)) { +		if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) +			r600_hdmi_disable(encoder);  		dig = radeon_encoder->enc_priv;  		dig->dig_encoder = -1;  	} @@ -1549,12 +1593,14 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = {  struct radeon_encoder_atom_dac *  radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)  { +	struct drm_device *dev = radeon_encoder->base.dev; +	struct radeon_device *rdev = dev->dev_private;  	struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);  	if (!dac)  		return NULL; -	dac->tv_std = TV_STD_NTSC; +	dac->tv_std = radeon_atombios_get_tv_info(rdev);  	return dac;  } @@ -1632,6 +1678,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su  		break;  	case ENCODER_OBJECT_ID_INTERNAL_DAC1:  		drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC); +		radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);  		drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);  		break;  	case ENCODER_OBJECT_ID_INTERNAL_DAC2: @@ -1659,6 +1706,4 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su  		drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);  		break;  	} - -	r600_hdmi_init(encoder);  } diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 93c7d5d4191..e329066dcab 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h @@ -36,7 +36,7 @@   * Radeon chip families   */  enum radeon_family { -	CHIP_R100, +	CHIP_R100 = 0,  	CHIP_RV100,  	CHIP_RS100,  	CHIP_RV200, @@ -99,4 +99,5 @@ enum radeon_chip_flags {  	RADEON_IS_PCI = 0x00800000UL,  	RADEON_IS_IGPGART = 0x01000000UL,  }; +  #endif diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 8fccbf29235..9ac57a09784 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -28,6 +28,7 @@       */  #include <linux/module.h> +#include <linux/slab.h>  #include <linux/fb.h>  #include "drmP.h" diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 8495d4e32e1..d90f95b405c 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -33,6 +33,7 @@  #include <linux/wait.h>  #include <linux/list.h>  #include <linux/kref.h> +#include <linux/slab.h>  #include "drmP.h"  #include "drm.h"  #include "radeon_reg.h" diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 4ae50c19589..5def6f5dff3 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -59,6 +59,7 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector)  	return false;  } +/* bit banging i2c */  static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state)  { @@ -181,13 +182,30 @@ static void set_data(void *i2c_priv, int data)  	WREG32(rec->en_data_reg, val);  } +static int pre_xfer(struct i2c_adapter *i2c_adap) +{ +	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + +	radeon_i2c_do_lock(i2c, 1); + +	return 0; +} + +static void post_xfer(struct i2c_adapter *i2c_adap) +{ +	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + +	radeon_i2c_do_lock(i2c, 0); +} + +/* hw i2c */ +  static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)  { -	struct radeon_pll *spll = &rdev->clock.spll;  	u32 sclk = radeon_get_engine_clock(rdev);  	u32 prescale = 0; -	u32 n, m; -	u8 loop; +	u32 nm; +	u8 n, m, loop;  	int i2c_clock;  	switch (rdev->family) { @@ -203,13 +221,15 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)  	case CHIP_R300:  	case CHIP_R350:  	case CHIP_RV350: -		n = (spll->reference_freq) / (4 * 6); +		i2c_clock = 60; +		nm = (sclk * 10) / (i2c_clock * 4);  		for (loop = 1; loop < 255; loop++) { -			if ((loop * (loop - 1)) > n) +			if ((nm / loop) < loop)  				break;  		} -		m = loop - 1; -		prescale = m | (loop << 8); +		n = loop - 1; +		m = loop - 2; +		prescale = m | (n << 8);  		break;  	case CHIP_RV380:  	case CHIP_RS400: @@ -217,7 +237,6 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)  	case CHIP_R420:  	case CHIP_R423:  	case CHIP_RV410: -		sclk = radeon_get_engine_clock(rdev);  		prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128;  		break;  	case CHIP_RS600: @@ -232,7 +251,6 @@ static u32 radeon_get_i2c_prescale(struct radeon_device *rdev)  	case CHIP_RV570:  	case CHIP_R580:  		i2c_clock = 50; -		sclk = radeon_get_engine_clock(rdev);  		if (rdev->family == CHIP_R520)  			prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock));  		else @@ -291,6 +309,7 @@ static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap,  	prescale = radeon_get_i2c_prescale(rdev);  	reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) | +	       RADEON_I2C_DRIVE_EN |  	       RADEON_I2C_START |  	       RADEON_I2C_STOP |  	       RADEON_I2C_GO); @@ -757,26 +776,13 @@ done:  	return ret;  } -static int radeon_sw_i2c_xfer(struct i2c_adapter *i2c_adap, +static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap,  			      struct i2c_msg *msgs, int num)  {  	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); -	int ret; - -	radeon_i2c_do_lock(i2c, 1); -	ret = i2c_transfer(&i2c->algo.radeon.bit_adapter, msgs, num); -	radeon_i2c_do_lock(i2c, 0); - -	return ret; -} - -static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap, -			   struct i2c_msg *msgs, int num) -{ -	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);  	struct radeon_device *rdev = i2c->dev->dev_private;  	struct radeon_i2c_bus_rec *rec = &i2c->rec; -	int ret; +	int ret = 0;  	switch (rdev->family) {  	case CHIP_R100: @@ -797,16 +803,12 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,  	case CHIP_RV410:  	case CHIP_RS400:  	case CHIP_RS480: -		if (rec->hw_capable) -			ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); -		else -			ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); +		ret = r100_hw_i2c_xfer(i2c_adap, msgs, num);  		break;  	case CHIP_RS600:  	case CHIP_RS690:  	case CHIP_RS740:  		/* XXX fill in hw i2c implementation */ -		ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);  		break;  	case CHIP_RV515:  	case CHIP_R520: @@ -814,20 +816,16 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,  	case CHIP_RV560:  	case CHIP_RV570:  	case CHIP_R580: -		if (rec->hw_capable) { -			if (rec->mm_i2c) -				ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); -			else -				ret = r500_hw_i2c_xfer(i2c_adap, msgs, num); -		} else -			ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num); +		if (rec->mm_i2c) +			ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); +		else +			ret = r500_hw_i2c_xfer(i2c_adap, msgs, num);  		break;  	case CHIP_R600:  	case CHIP_RV610:  	case CHIP_RV630:  	case CHIP_RV670:  		/* XXX fill in hw i2c implementation */ -		ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);  		break;  	case CHIP_RV620:  	case CHIP_RV635: @@ -838,7 +836,6 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,  	case CHIP_RV710:  	case CHIP_RV740:  		/* XXX fill in hw i2c implementation */ -		ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);  		break;  	case CHIP_CEDAR:  	case CHIP_REDWOOD: @@ -846,7 +843,6 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,  	case CHIP_CYPRESS:  	case CHIP_HEMLOCK:  		/* XXX fill in hw i2c implementation */ -		ret = radeon_sw_i2c_xfer(i2c_adap, msgs, num);  		break;  	default:  		DRM_ERROR("i2c: unhandled radeon chip\n"); @@ -857,20 +853,21 @@ static int radeon_i2c_xfer(struct i2c_adapter *i2c_adap,  	return ret;  } -static u32 radeon_i2c_func(struct i2c_adapter *adap) +static u32 radeon_hw_i2c_func(struct i2c_adapter *adap)  {  	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;  }  static const struct i2c_algorithm radeon_i2c_algo = { -	.master_xfer = radeon_i2c_xfer, -	.functionality = radeon_i2c_func, +	.master_xfer = radeon_hw_i2c_xfer, +	.functionality = radeon_hw_i2c_func,  };  struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,  					  struct radeon_i2c_bus_rec *rec,  					  const char *name)  { +	struct radeon_device *rdev = dev->dev_private;  	struct radeon_i2c_chan *i2c;  	int ret; @@ -878,37 +875,43 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,  	if (i2c == NULL)  		return NULL; -	/* set the internal bit adapter */ -	i2c->algo.radeon.bit_adapter.owner = THIS_MODULE; -	i2c_set_adapdata(&i2c->algo.radeon.bit_adapter, i2c); -	sprintf(i2c->algo.radeon.bit_adapter.name, "Radeon internal i2c bit bus %s", name); -	i2c->algo.radeon.bit_adapter.algo_data = &i2c->algo.radeon.bit_data; -	i2c->algo.radeon.bit_data.setsda = set_data; -	i2c->algo.radeon.bit_data.setscl = set_clock; -	i2c->algo.radeon.bit_data.getsda = get_data; -	i2c->algo.radeon.bit_data.getscl = get_clock; -	i2c->algo.radeon.bit_data.udelay = 20; -	/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always -	 * make this, 2 jiffies is a lot more reliable */ -	i2c->algo.radeon.bit_data.timeout = 2; -	i2c->algo.radeon.bit_data.data = i2c; -	ret = i2c_bit_add_bus(&i2c->algo.radeon.bit_adapter); -	if (ret) { -		DRM_ERROR("Failed to register internal bit i2c %s\n", name); -		goto out_free; -	} -	/* set the radeon i2c adapter */ -	i2c->dev = dev;  	i2c->rec = *rec;  	i2c->adapter.owner = THIS_MODULE; +	i2c->dev = dev;  	i2c_set_adapdata(&i2c->adapter, i2c); -	sprintf(i2c->adapter.name, "Radeon i2c %s", name); -	i2c->adapter.algo_data = &i2c->algo.radeon; -	i2c->adapter.algo = &radeon_i2c_algo; -	ret = i2c_add_adapter(&i2c->adapter); -	if (ret) { -		DRM_ERROR("Failed to register i2c %s\n", name); -		goto out_free; +	if (rec->mm_i2c || +	    (rec->hw_capable && +	     radeon_hw_i2c && +	     ((rdev->family <= CHIP_RS480) || +	      ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) { +		/* set the radeon hw i2c adapter */ +		sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name); +		i2c->adapter.algo = &radeon_i2c_algo; +		ret = i2c_add_adapter(&i2c->adapter); +		if (ret) { +			DRM_ERROR("Failed to register hw i2c %s\n", name); +			goto out_free; +		} +	} else { +		/* set the radeon bit adapter */ +		sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name); +		i2c->adapter.algo_data = &i2c->algo.bit; +		i2c->algo.bit.pre_xfer = pre_xfer; +		i2c->algo.bit.post_xfer = post_xfer; +		i2c->algo.bit.setsda = set_data; +		i2c->algo.bit.setscl = set_clock; +		i2c->algo.bit.getsda = get_data; +		i2c->algo.bit.getscl = get_clock; +		i2c->algo.bit.udelay = 20; +		/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always +		 * make this, 2 jiffies is a lot more reliable */ +		i2c->algo.bit.timeout = 2; +		i2c->algo.bit.data = i2c; +		ret = i2c_bit_add_bus(&i2c->adapter); +		if (ret) { +			DRM_ERROR("Failed to register bit i2c %s\n", name); +			goto out_free; +		}  	}  	return i2c; @@ -953,16 +956,6 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)  {  	if (!i2c)  		return; -	i2c_del_adapter(&i2c->algo.radeon.bit_adapter); -	i2c_del_adapter(&i2c->adapter); -	kfree(i2c); -} - -void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c) -{ -	if (!i2c) -		return; -  	i2c_del_adapter(&i2c->adapter);  	kfree(i2c);  } diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 3cfd60fd008..a212041e8b0 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -67,9 +67,10 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev)  	/* Disable *all* interrupts */  	rdev->irq.sw_int = false; -	for (i = 0; i < 2; i++) { +	for (i = 0; i < rdev->num_crtc; i++)  		rdev->irq.crtc_vblank_int[i] = false; -	} +	for (i = 0; i < 6; i++) +		rdev->irq.hpd[i] = false;  	radeon_irq_set(rdev);  	/* Clear bits */  	radeon_irq_process(rdev); @@ -95,34 +96,29 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)  	}  	/* Disable *all* interrupts */  	rdev->irq.sw_int = false; -	for (i = 0; i < 2; i++) { +	for (i = 0; i < rdev->num_crtc; i++)  		rdev->irq.crtc_vblank_int[i] = false; +	for (i = 0; i < 6; i++)  		rdev->irq.hpd[i] = false; -	}  	radeon_irq_set(rdev);  }  int radeon_irq_kms_init(struct radeon_device *rdev)  {  	int r = 0; -	int num_crtc = 2; -	if (rdev->flags & RADEON_SINGLE_CRTC) -		num_crtc = 1;  	spin_lock_init(&rdev->irq.sw_lock); -	r = drm_vblank_init(rdev->ddev, num_crtc); +	r = drm_vblank_init(rdev->ddev, rdev->num_crtc);  	if (r) {  		return r;  	}  	/* enable msi */  	rdev->msi_enabled = 0; -	/* MSIs don't seem to work on my rs780; -	 * not sure about rs880 or other rs780s. -	 * Needs more investigation. +	/* MSIs don't seem to work reliably on all IGP +	 * chips.  Disable MSI on them for now.  	 */  	if ((rdev->family >= CHIP_RV380) && -	    (rdev->family != CHIP_RS780) && -	    (rdev->family != CHIP_RS880)) { +	    (!(rdev->flags & RADEON_IS_IGP))) {  		int ret = pci_enable_msi(rdev->pdev);  		if (!ret) {  			rdev->msi_enabled = 1; diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 20ec276e759..c633319f98e 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -31,6 +31,7 @@  #include "radeon_drm.h"  #include <linux/vga_switcheroo.h> +#include <linux/slab.h>  int radeon_driver_unload_kms(struct drm_device *dev)  { @@ -164,7 +165,7 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)  {  	struct radeon_device *rdev = dev->dev_private; -	if (crtc < 0 || crtc > 1) { +	if (crtc < 0 || crtc >= rdev->num_crtc) {  		DRM_ERROR("Invalid crtc %d\n", crtc);  		return -EINVAL;  	} @@ -176,7 +177,7 @@ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)  {  	struct radeon_device *rdev = dev->dev_private; -	if (crtc < 0 || crtc > 1) { +	if (crtc < 0 || crtc >= rdev->num_crtc) {  		DRM_ERROR("Invalid crtc %d\n", crtc);  		return -EINVAL;  	} @@ -190,7 +191,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)  {  	struct radeon_device *rdev = dev->dev_private; -	if (crtc < 0 || crtc > 1) { +	if (crtc < 0 || crtc >= rdev->num_crtc) {  		DRM_ERROR("Invalid crtc %d\n", crtc);  		return;  	} diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index df23d6a01d0..88865e38fe3 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c @@ -603,6 +603,10 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod  				      ? RADEON_CRTC2_INTERLACE_EN  				      : 0)); +		/* rs4xx chips seem to like to have the crtc enabled when the timing is set */ +		if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480)) +			crtc2_gen_cntl |= RADEON_CRTC2_EN; +  		disp2_merge_cntl = RREG32(RADEON_DISP2_MERGE_CNTL);  		disp2_merge_cntl &= ~RADEON_DISP2_RGB_OFFSET_EN; @@ -630,6 +634,10 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod  				    ? RADEON_CRTC_INTERLACE_EN  				    : 0)); +		/* rs4xx chips seem to like to have the crtc enabled when the timing is set */ +		if ((rdev->family == CHIP_RS400) || (rdev->family == CHIP_RS480)) +			crtc_gen_cntl |= RADEON_CRTC_EN; +  		crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);  		crtc_ext_cntl |= (RADEON_XCRT_CNT_EN |  				  RADEON_CRTC_VSYNC_DIS | diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index cf389ce50a8..0274abe17ad 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -228,16 +228,8 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,  	drm_mode_set_crtcinfo(adjusted_mode, 0);  	/* get the native mode for LVDS */ -	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { -		struct drm_display_mode *native_mode = &radeon_encoder->native_mode; -		int mode_id = adjusted_mode->base.id; -		*adjusted_mode = *native_mode; -		adjusted_mode->hdisplay = mode->hdisplay; -		adjusted_mode->vdisplay = mode->vdisplay; -		adjusted_mode->crtc_hdisplay = mode->hdisplay; -		adjusted_mode->crtc_vdisplay = mode->vdisplay; -		adjusted_mode->base.id = mode_id; -	} +	if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) +		radeon_panel_mode_fixup(encoder, adjusted_mode);  	return true;  } @@ -830,8 +822,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)  				crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;  			if (rdev->family == CHIP_R420 || -					rdev->family == CHIP_R423 || -					rdev->family == CHIP_RV410) +			    rdev->family == CHIP_R423 || +			    rdev->family == CHIP_RV410)  				tv_dac_cntl |= (R420_TV_DAC_RDACPD |  						R420_TV_DAC_GDACPD |  						R420_TV_DAC_BDACPD | @@ -907,35 +899,43 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,  	if (rdev->family != CHIP_R200) {  		tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);  		if (rdev->family == CHIP_R420 || -				rdev->family == CHIP_R423 || -				rdev->family == CHIP_RV410) { +		    rdev->family == CHIP_R423 || +		    rdev->family == CHIP_RV410) {  			tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | -					RADEON_TV_DAC_BGADJ_MASK | -					R420_TV_DAC_DACADJ_MASK | -					R420_TV_DAC_RDACPD | -					R420_TV_DAC_GDACPD | -					R420_TV_DAC_BDACPD | -					R420_TV_DAC_TVENABLE); +					 RADEON_TV_DAC_BGADJ_MASK | +					 R420_TV_DAC_DACADJ_MASK | +					 R420_TV_DAC_RDACPD | +					 R420_TV_DAC_GDACPD | +					 R420_TV_DAC_BDACPD | +					 R420_TV_DAC_TVENABLE);  		} else {  			tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | -					RADEON_TV_DAC_BGADJ_MASK | -					RADEON_TV_DAC_DACADJ_MASK | -					RADEON_TV_DAC_RDACPD | -					RADEON_TV_DAC_GDACPD | -					RADEON_TV_DAC_BDACPD); +					 RADEON_TV_DAC_BGADJ_MASK | +					 RADEON_TV_DAC_DACADJ_MASK | +					 RADEON_TV_DAC_RDACPD | +					 RADEON_TV_DAC_GDACPD | +					 RADEON_TV_DAC_BDACPD);  		} -		/*  FIXME TV */ -		if (tv_dac) { -			struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; -			tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | -					RADEON_TV_DAC_NHOLD | -					RADEON_TV_DAC_STD_PS2 | -					tv_dac->ps2_tvdac_adj); +		tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD; + +		if (is_tv) { +			if (tv_dac->tv_std == TV_STD_NTSC || +			    tv_dac->tv_std == TV_STD_NTSC_J || +			    tv_dac->tv_std == TV_STD_PAL_M || +			    tv_dac->tv_std == TV_STD_PAL_60) +				tv_dac_cntl |= tv_dac->ntsc_tvdac_adj; +			else +				tv_dac_cntl |= tv_dac->pal_tvdac_adj; + +			if (tv_dac->tv_std == TV_STD_NTSC || +			    tv_dac->tv_std == TV_STD_NTSC_J) +				tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; +			else +				tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;  		} else -			tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | -					RADEON_TV_DAC_NHOLD | -					RADEON_TV_DAC_STD_PS2); +			tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2 | +					tv_dac->ps2_tvdac_adj);  		WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);  	} diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c index 417684daef4..f2ed27c8055 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_tv.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c @@ -57,6 +57,10 @@  #define NTSC_TV_PLL_N_14 693  #define NTSC_TV_PLL_P_14 7 +#define PAL_TV_PLL_M_14 19 +#define PAL_TV_PLL_N_14 353 +#define PAL_TV_PLL_P_14 5 +  #define VERT_LEAD_IN_LINES 2  #define FRAC_BITS 0xe  #define FRAC_MASK 0x3fff @@ -205,9 +209,24 @@ static const struct radeon_tv_mode_constants available_tv_modes[] = {  		630627,             /* defRestart */  		347,                /* crtcPLL_N */  		14,                 /* crtcPLL_M */ -			8,                  /* crtcPLL_postDiv */ +		8,                  /* crtcPLL_postDiv */  		1022,               /* pixToTV */  	}, +	{ /* PAL timing for 14 Mhz ref clk */ +		800,                /* horResolution */ +		600,                /* verResolution */ +		TV_STD_PAL,         /* standard */ +		1131,               /* horTotal */ +		742,                /* verTotal */ +		813,                /* horStart */ +		840,                /* horSyncStart */ +		633,                /* verSyncStart */ +		708369,             /* defRestart */ +		211,                /* crtcPLL_N */ +		9,                  /* crtcPLL_M */ +		8,                  /* crtcPLL_postDiv */ +		759,                /* pixToTV */ +	},  };  #define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes) @@ -242,7 +261,7 @@ static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(stru  		if (pll->reference_freq == 2700)  			const_ptr = &available_tv_modes[1];  		else -			const_ptr = &available_tv_modes[1]; /* FIX ME */ +			const_ptr = &available_tv_modes[3];  	}  	return const_ptr;  } @@ -685,9 +704,9 @@ void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,  			n = PAL_TV_PLL_N_27;  			p = PAL_TV_PLL_P_27;  		} else { -			m = PAL_TV_PLL_M_27; -			n = PAL_TV_PLL_N_27; -			p = PAL_TV_PLL_P_27; +			m = PAL_TV_PLL_M_14; +			n = PAL_TV_PLL_N_14; +			p = PAL_TV_PLL_P_14;  		}  	} diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 1702b820aa4..5413fcd6308 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -129,6 +129,7 @@ struct radeon_tmds_pll {  #define RADEON_PLL_USE_FRAC_FB_DIV      (1 << 10)  #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)  #define RADEON_PLL_USE_POST_DIV         (1 << 12) +#define RADEON_PLL_IS_LCD               (1 << 13)  /* pll algo */  enum radeon_pll_algo { @@ -149,6 +150,8 @@ struct radeon_pll {  	uint32_t pll_in_max;  	uint32_t pll_out_min;  	uint32_t pll_out_max; +	uint32_t lcd_pll_out_min; +	uint32_t lcd_pll_out_max;  	uint32_t best_vco;  	/* divider limits */ @@ -170,17 +173,12 @@ struct radeon_pll {  	enum radeon_pll_algo algo;  }; -struct i2c_algo_radeon_data { -	struct i2c_adapter bit_adapter; -	struct i2c_algo_bit_data bit_data; -}; -  struct radeon_i2c_chan {  	struct i2c_adapter adapter;  	struct drm_device *dev;  	union { +		struct i2c_algo_bit_data bit;  		struct i2c_algo_dp_aux_data dp; -		struct i2c_algo_radeon_data radeon;  	} algo;  	struct radeon_i2c_bus_rec rec;  }; @@ -342,6 +340,7 @@ struct radeon_encoder {  	struct drm_display_mode native_mode;  	void *enc_priv;  	int hdmi_offset; +	int hdmi_config_offset;  	int hdmi_audio_workaround;  	int hdmi_buffer_status;  }; @@ -431,7 +430,6 @@ extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,  						 struct radeon_i2c_bus_rec *rec,  						 const char *name);  extern void radeon_i2c_destroy(struct radeon_i2c_chan *i2c); -extern void radeon_i2c_destroy_dp(struct radeon_i2c_chan *i2c);  extern void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,  				u8 slave_addr,  				u8 addr, @@ -560,6 +558,8 @@ extern int radeon_static_clocks_init(struct drm_device *dev);  bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,  					struct drm_display_mode *mode,  					struct drm_display_mode *adjusted_mode); +void radeon_panel_mode_fixup(struct drm_encoder *encoder, +			     struct drm_display_mode *adjusted_mode);  void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);  /* legacy tv */ diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index fc9d00ac6b1..122774742bd 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -30,6 +30,7 @@   *    Dave Airlie   */  #include <linux/list.h> +#include <linux/slab.h>  #include <drm/drmP.h>  #include "radeon_drm.h"  #include "radeon.h" @@ -185,8 +186,10 @@ int radeon_bo_pin(struct radeon_bo *bo, u32 domain, u64 *gpu_addr)  		return 0;  	}  	radeon_ttm_placement_from_domain(bo, domain); -	/* force to pin into visible video ram */ -	bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT; +	if (domain == RADEON_GEM_DOMAIN_VRAM) { +		/* force to pin into visible video ram */ +		bo->placement.lpfn = bo->rdev->mc.visible_vram_size >> PAGE_SHIFT; +	}  	for (i = 0; i < bo->placement.num_placement; i++)  		bo->placements[i] |= TTM_PL_FLAG_NO_EVICT;  	r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index d4d1c39a0e9..a4b57493aa7 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -28,6 +28,7 @@  #define RADEON_RECLOCK_DELAY_MS 200  #define RADEON_WAIT_VBLANK_TIMEOUT 200 +static bool radeon_pm_debug_check_in_vbl(struct radeon_device *rdev, bool finish);  static void radeon_pm_set_clocks_locked(struct radeon_device *rdev);  static void radeon_pm_set_clocks(struct radeon_device *rdev);  static void radeon_pm_idle_work_handler(struct work_struct *work); @@ -179,6 +180,16 @@ static void radeon_get_power_state(struct radeon_device *rdev,  		 rdev->pm.requested_power_state->non_clock_info.pcie_lanes);  } +static inline void radeon_sync_with_vblank(struct radeon_device *rdev) +{ +	if (rdev->pm.active_crtcs) { +		rdev->pm.vblank_sync = false; +		wait_event_timeout( +			rdev->irq.vblank_queue, rdev->pm.vblank_sync, +			msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); +	} +} +  static void radeon_set_power_state(struct radeon_device *rdev)  {  	/* if *_clock_mode are the same, *_power_state are as well */ @@ -189,11 +200,28 @@ static void radeon_set_power_state(struct radeon_device *rdev)  		 rdev->pm.requested_clock_mode->sclk,  		 rdev->pm.requested_clock_mode->mclk,  		 rdev->pm.requested_power_state->non_clock_info.pcie_lanes); +  	/* set pcie lanes */ +	/* TODO */ +  	/* set voltage */ +	/* TODO */ +  	/* set engine clock */ +	radeon_sync_with_vblank(rdev); +	radeon_pm_debug_check_in_vbl(rdev, false);  	radeon_set_engine_clock(rdev, rdev->pm.requested_clock_mode->sclk); +	radeon_pm_debug_check_in_vbl(rdev, true); + +#if 0  	/* set memory clock */ +	if (rdev->asic->set_memory_clock) { +		radeon_sync_with_vblank(rdev); +		radeon_pm_debug_check_in_vbl(rdev, false); +		radeon_set_memory_clock(rdev, rdev->pm.requested_clock_mode->mclk); +		radeon_pm_debug_check_in_vbl(rdev, true); +	} +#endif  	rdev->pm.current_power_state = rdev->pm.requested_power_state;  	rdev->pm.current_clock_mode = rdev->pm.requested_clock_mode; @@ -229,6 +257,12 @@ int radeon_pm_init(struct radeon_device *rdev)  	return 0;  } +void radeon_pm_fini(struct radeon_device *rdev) +{ +	if (rdev->pm.i2c_bus) +		radeon_i2c_destroy(rdev->pm.i2c_bus); +} +  void radeon_pm_compute_clocks(struct radeon_device *rdev)  {  	struct drm_device *ddev = rdev->ddev; @@ -245,7 +279,8 @@ void radeon_pm_compute_clocks(struct radeon_device *rdev)  	list_for_each_entry(connector,  		&ddev->mode_config.connector_list, head) {  		if (connector->encoder && -			connector->dpms != DRM_MODE_DPMS_OFF) { +		    connector->encoder->crtc && +		    connector->dpms != DRM_MODE_DPMS_OFF) {  			radeon_crtc = to_radeon_crtc(connector->encoder->crtc);  			rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);  			++count; @@ -333,10 +368,7 @@ static void radeon_pm_set_clocks_locked(struct radeon_device *rdev)  		break;  	} -	/* check if we are in vblank */ -	radeon_pm_debug_check_in_vbl(rdev, false);  	radeon_set_power_state(rdev); -	radeon_pm_debug_check_in_vbl(rdev, true);  	rdev->pm.planned_action = PM_ACTION_NONE;  } @@ -353,10 +385,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)  		rdev->pm.req_vblank |= (1 << 1);  		drm_vblank_get(rdev->ddev, 1);  	} -	if (rdev->pm.active_crtcs) -		wait_event_interruptible_timeout( -			rdev->irq.vblank_queue, 0, -			msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT)); +	radeon_pm_set_clocks_locked(rdev);  	if (rdev->pm.req_vblank & (1 << 0)) {  		rdev->pm.req_vblank &= ~(1 << 0);  		drm_vblank_put(rdev->ddev, 0); @@ -366,7 +395,6 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)  		drm_vblank_put(rdev->ddev, 1);  	} -	radeon_pm_set_clocks_locked(rdev);  	mutex_unlock(&rdev->cp.mutex);  } diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 5c0dc082d33..eabbc9cf30a 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h @@ -346,6 +346,7 @@  #       define RADEON_TVPLL_PWRMGT_OFF      (1 << 30)  #       define RADEON_TVCLK_TURNOFF         (1 << 31)  #define RADEON_PLL_PWRMGT_CNTL              0x0015 /* PLL */ +#	define RADEON_PM_MODE_SEL           (1 << 13)  #       define RADEON_TCL_BYPASS_DISABLE    (1 << 20)  #define RADEON_CLR_CMP_CLR_3D               0x1a24  #define RADEON_CLR_CMP_CLR_DST              0x15c8 diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index e50513a6273..f6e1e8d4d98 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -26,6 +26,7 @@   *          Jerome Glisse   */  #include <linux/seq_file.h> +#include <linux/slab.h>  #include "drmP.h"  #include "radeon_drm.h"  #include "radeon_reg.h" diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 3c32f840dcd..cc5316dcf58 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -424,7 +424,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *  		if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&  		    (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {  			u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3); -			offset = *cmd << 10; +			offset = *cmd3 << 10;  			if (radeon_check_and_fixup_offset  			    (dev_priv, file_priv, &offset)) {  				DRM_ERROR("Invalid second packet offset\n"); @@ -1093,7 +1093,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,  					/* judging by the first tile offset needed, could possibly  					   directly address/clear 4x4 tiles instead of 8x2 * 4x4  					   macro tiles, though would still need clear mask for -					   right/bottom if truely 4x4 granularity is desired ? */ +					   right/bottom if truly 4x4 granularity is desired ? */  					OUT_RING(tileoffset * 16);  					/* the number of tiles to clear */  					OUT_RING(nrtilesx + 1); @@ -2895,9 +2895,12 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,  			return rv;  		rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer,  						cmdbuf->bufsz); -		if (rv) +		if (rv) { +			drm_buffer_free(cmdbuf->buffer);  			return rv; -	} +		} +	} else +		goto done;  	orig_nbox = cmdbuf->nbox; @@ -2905,8 +2908,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,  		int temp;  		temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); -		if (cmdbuf->bufsz != 0) -			drm_buffer_free(cmdbuf->buffer); +		drm_buffer_free(cmdbuf->buffer);  		return temp;  	} @@ -3012,16 +3014,15 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,  		}  	} -	if (cmdbuf->bufsz != 0) -		drm_buffer_free(cmdbuf->buffer); +	drm_buffer_free(cmdbuf->buffer); +      done:  	DRM_DEBUG("DONE\n");  	COMMIT_RING();  	return 0;        err: -	if (cmdbuf->bufsz != 0) -		drm_buffer_free(cmdbuf->buffer); +	drm_buffer_free(cmdbuf->buffer);  	return -EINVAL;  } diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 43c5ab34b63..d031b686308 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -36,6 +36,7 @@  #include <drm/drmP.h>  #include <drm/radeon_drm.h>  #include <linux/seq_file.h> +#include <linux/slab.h>  #include "radeon_reg.h"  #include "radeon.h" diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index 19c4663fa9c..1e97b2d129f 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 @@ -125,6 +125,8 @@ r300 0x4f60  0x4000 GB_VAP_RASTER_VTX_FMT_0  0x4004 GB_VAP_RASTER_VTX_FMT_1  0x4008 GB_ENABLE +0x4010 GB_MSPOS0 +0x4014 GB_MSPOS1  0x401C GB_SELECT  0x4020 GB_AA_CONFIG  0x4024 GB_FIFO_SIZE diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index 989f7a02083..e958980d00f 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 @@ -125,6 +125,8 @@ r420 0x4f60  0x4000 GB_VAP_RASTER_VTX_FMT_0  0x4004 GB_VAP_RASTER_VTX_FMT_1  0x4008 GB_ENABLE +0x4010 GB_MSPOS0 +0x4014 GB_MSPOS1  0x401C GB_SELECT  0x4020 GB_AA_CONFIG  0x4024 GB_FIFO_SIZE diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index 8f414a5f520..af0da4ae3f5 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 @@ -26,20 +26,16 @@ r600 0x9400  0x00028408 VGT_INDX_OFFSET  0x00028AA0 VGT_INSTANCE_STEP_RATE_0  0x00028AA4 VGT_INSTANCE_STEP_RATE_1 -0x000088C0 VGT_LAST_COPY_STATE  0x00028400 VGT_MAX_VTX_INDX -0x000088D8 VGT_MC_LAT_CNTL  0x00028404 VGT_MIN_VTX_INDX  0x00028A94 VGT_MULTI_PRIM_IB_RESET_EN  0x0002840C VGT_MULTI_PRIM_IB_RESET_INDX  0x00008970 VGT_NUM_INDICES  0x00008974 VGT_NUM_INSTANCES  0x00028A10 VGT_OUTPUT_PATH_CNTL -0x00028C5C VGT_OUT_DEALLOC_CNTL  0x00028A84 VGT_PRIMITIVEID_EN  0x00008958 VGT_PRIMITIVE_TYPE  0x00028AB4 VGT_REUSE_OFF -0x00028C58 VGT_VERTEX_REUSE_BLOCK_CNTL  0x00028AB8 VGT_VTX_CNT_EN  0x000088B0 VGT_VTX_VECT_EJECT_REG  0x00028810 PA_CL_CLIP_CNTL @@ -280,7 +276,6 @@ r600 0x9400  0x00028E00 PA_SU_POLY_OFFSET_FRONT_SCALE  0x00028814 PA_SU_SC_MODE_CNTL  0x00028C08 PA_SU_VTX_CNTL -0x00008C00 SQ_CONFIG  0x00008C04 SQ_GPR_RESOURCE_MGMT_1  0x00008C08 SQ_GPR_RESOURCE_MGMT_2  0x00008C10 SQ_STACK_RESOURCE_MGMT_1 @@ -320,18 +315,6 @@ r600 0x9400  0x000283FC SQ_VTX_SEMANTIC_31  0x000288E0 SQ_VTX_SEMANTIC_CLEAR  0x0003CFF4 SQ_VTX_START_INST_LOC -0x0003C000 SQ_TEX_SAMPLER_WORD0_0 -0x0003C004 SQ_TEX_SAMPLER_WORD1_0 -0x0003C008 SQ_TEX_SAMPLER_WORD2_0 -0x00030000 SQ_ALU_CONSTANT0_0 -0x00030004 SQ_ALU_CONSTANT1_0 -0x00030008 SQ_ALU_CONSTANT2_0 -0x0003000C SQ_ALU_CONSTANT3_0 -0x0003E380 SQ_BOOL_CONST_0 -0x0003E384 SQ_BOOL_CONST_1 -0x0003E388 SQ_BOOL_CONST_2 -0x0003E200 SQ_LOOP_CONST_0 -0x0003E200 SQ_LOOP_CONST_DX10_0  0x000281C0 SQ_ALU_CONST_BUFFER_SIZE_GS_0  0x000281C4 SQ_ALU_CONST_BUFFER_SIZE_GS_1  0x000281C8 SQ_ALU_CONST_BUFFER_SIZE_GS_2 @@ -380,54 +363,6 @@ r600 0x9400  0x000281B4 SQ_ALU_CONST_BUFFER_SIZE_VS_13  0x000281B8 SQ_ALU_CONST_BUFFER_SIZE_VS_14  0x000281BC SQ_ALU_CONST_BUFFER_SIZE_VS_15 -0x000289C0 SQ_ALU_CONST_CACHE_GS_0 -0x000289C4 SQ_ALU_CONST_CACHE_GS_1 -0x000289C8 SQ_ALU_CONST_CACHE_GS_2 -0x000289CC SQ_ALU_CONST_CACHE_GS_3 -0x000289D0 SQ_ALU_CONST_CACHE_GS_4 -0x000289D4 SQ_ALU_CONST_CACHE_GS_5 -0x000289D8 SQ_ALU_CONST_CACHE_GS_6 -0x000289DC SQ_ALU_CONST_CACHE_GS_7 -0x000289E0 SQ_ALU_CONST_CACHE_GS_8 -0x000289E4 SQ_ALU_CONST_CACHE_GS_9 -0x000289E8 SQ_ALU_CONST_CACHE_GS_10 -0x000289EC SQ_ALU_CONST_CACHE_GS_11 -0x000289F0 SQ_ALU_CONST_CACHE_GS_12 -0x000289F4 SQ_ALU_CONST_CACHE_GS_13 -0x000289F8 SQ_ALU_CONST_CACHE_GS_14 -0x000289FC SQ_ALU_CONST_CACHE_GS_15 -0x00028940 SQ_ALU_CONST_CACHE_PS_0 -0x00028944 SQ_ALU_CONST_CACHE_PS_1 -0x00028948 SQ_ALU_CONST_CACHE_PS_2 -0x0002894C SQ_ALU_CONST_CACHE_PS_3 -0x00028950 SQ_ALU_CONST_CACHE_PS_4 -0x00028954 SQ_ALU_CONST_CACHE_PS_5 -0x00028958 SQ_ALU_CONST_CACHE_PS_6 -0x0002895C SQ_ALU_CONST_CACHE_PS_7 -0x00028960 SQ_ALU_CONST_CACHE_PS_8 -0x00028964 SQ_ALU_CONST_CACHE_PS_9 -0x00028968 SQ_ALU_CONST_CACHE_PS_10 -0x0002896C SQ_ALU_CONST_CACHE_PS_11 -0x00028970 SQ_ALU_CONST_CACHE_PS_12 -0x00028974 SQ_ALU_CONST_CACHE_PS_13 -0x00028978 SQ_ALU_CONST_CACHE_PS_14 -0x0002897C SQ_ALU_CONST_CACHE_PS_15 -0x00028980 SQ_ALU_CONST_CACHE_VS_0 -0x00028984 SQ_ALU_CONST_CACHE_VS_1 -0x00028988 SQ_ALU_CONST_CACHE_VS_2 -0x0002898C SQ_ALU_CONST_CACHE_VS_3 -0x00028990 SQ_ALU_CONST_CACHE_VS_4 -0x00028994 SQ_ALU_CONST_CACHE_VS_5 -0x00028998 SQ_ALU_CONST_CACHE_VS_6 -0x0002899C SQ_ALU_CONST_CACHE_VS_7 -0x000289A0 SQ_ALU_CONST_CACHE_VS_8 -0x000289A4 SQ_ALU_CONST_CACHE_VS_9 -0x000289A8 SQ_ALU_CONST_CACHE_VS_10 -0x000289AC SQ_ALU_CONST_CACHE_VS_11 -0x000289B0 SQ_ALU_CONST_CACHE_VS_12 -0x000289B4 SQ_ALU_CONST_CACHE_VS_13 -0x000289B8 SQ_ALU_CONST_CACHE_VS_14 -0x000289BC SQ_ALU_CONST_CACHE_VS_15  0x000288D8 SQ_PGM_CF_OFFSET_ES  0x000288DC SQ_PGM_CF_OFFSET_FS  0x000288D4 SQ_PGM_CF_OFFSET_GS @@ -494,12 +429,7 @@ r600 0x9400  0x00028438 SX_ALPHA_REF  0x00028410 SX_ALPHA_TEST_CONTROL  0x00028350 SX_MISC -0x0000A020 SMX_DC_CTL0 -0x0000A024 SMX_DC_CTL1 -0x0000A028 SMX_DC_CTL2 -0x00009608 TC_CNTL  0x00009604 TC_INVALIDATE -0x00009490 TD_CNTL  0x00009400 TD_FILTER4  0x00009404 TD_FILTER4_1  0x00009408 TD_FILTER4_2 @@ -824,14 +754,9 @@ r600 0x9400  0x00028428 CB_FOG_GREEN  0x00028424 CB_FOG_RED  0x00008040 WAIT_UNTIL -0x00008950 CC_GC_SHADER_PIPE_CONFIG -0x00008954 GC_USER_SHADER_PIPE_CONFIG  0x00009714 VC_ENHANCE  0x00009830 DB_DEBUG  0x00009838 DB_WATERMARKS  0x00028D28 DB_SRESULTS_COMPARE_STATE0  0x00028D44 DB_ALPHA_TO_MASK -0x00009504 TA_CNTL  0x00009700 VC_CNTL -0x00009718 VC_CONFIG -0x0000A02C SMX_DC_MC_INTF_CTL diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 6801b865d1c..83e8bc0c2bb 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 @@ -125,6 +125,8 @@ rs600 0x6d40  0x4000 GB_VAP_RASTER_VTX_FMT_0  0x4004 GB_VAP_RASTER_VTX_FMT_1  0x4008 GB_ENABLE +0x4010 GB_MSPOS0 +0x4014 GB_MSPOS1  0x401C GB_SELECT  0x4020 GB_AA_CONFIG  0x4024 GB_FIFO_SIZE diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 38abf63bf2c..1e46233985e 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -35,6 +35,7 @@ rv515 0x6d40  0x1DA8 VAP_VPORT_ZSCALE  0x1DAC VAP_VPORT_ZOFFSET  0x2080 VAP_CNTL +0x208C VAP_INDEX_OFFSET  0x2090 VAP_OUT_VTX_FMT_0  0x2094 VAP_OUT_VTX_FMT_1  0x20B0 VAP_VTE_CNTL @@ -158,6 +159,8 @@ rv515 0x6d40  0x4000 GB_VAP_RASTER_VTX_FMT_0  0x4004 GB_VAP_RASTER_VTX_FMT_1  0x4008 GB_ENABLE +0x4010 GB_MSPOS0 +0x4014 GB_MSPOS1  0x401C GB_SELECT  0x4020 GB_AA_CONFIG  0x4024 GB_FIFO_SIZE diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 626d51891ee..1a41cb268b7 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -26,8 +26,10 @@   *          Jerome Glisse   */  #include <linux/seq_file.h> +#include <linux/slab.h>  #include <drm/drmP.h>  #include "radeon.h" +#include "radeon_asic.h"  #include "rs400d.h"  /* This files gather functions specifics to : rs400,rs480 */ @@ -202,9 +204,9 @@ void rs400_gart_disable(struct radeon_device *rdev)  void rs400_gart_fini(struct radeon_device *rdev)  { +	radeon_gart_fini(rdev);  	rs400_gart_disable(rdev);  	radeon_gart_table_ram_free(rdev); -	radeon_gart_fini(rdev);  }  int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) @@ -264,6 +266,7 @@ void rs400_mc_init(struct radeon_device *rdev)  	base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;  	radeon_vram_location(rdev, &rdev->mc, base);  	radeon_gtt_location(rdev, &rdev->mc); +	radeon_update_bandwidth_info(rdev);  }  uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg) @@ -388,6 +391,8 @@ static int rs400_startup(struct radeon_device *rdev)  {  	int r; +	r100_set_common_regs(rdev); +  	rs400_mc_program(rdev);  	/* Resume clock */  	r300_clock_startup(rdev); @@ -453,6 +458,7 @@ int rs400_suspend(struct radeon_device *rdev)  void rs400_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r100_cp_fini(rdev);  	r100_wb_fini(rdev);  	r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 47f046b78c6..a81bc7a21e1 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -37,6 +37,7 @@   */  #include "drmP.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "atom.h"  #include "rs600d.h" @@ -158,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)  	WREG32_MC(R_000100_MC_PT0_CNTL, tmp);  	tmp = RREG32_MC(R_000100_MC_PT0_CNTL); -	tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1); +	tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1);  	WREG32_MC(R_000100_MC_PT0_CNTL, tmp);  	tmp = RREG32_MC(R_000100_MC_PT0_CNTL); @@ -267,9 +268,9 @@ void rs600_gart_disable(struct radeon_device *rdev)  void rs600_gart_fini(struct radeon_device *rdev)  { +	radeon_gart_fini(rdev);  	rs600_gart_disable(rdev);  	radeon_gart_table_vram_free(rdev); -	radeon_gart_fini(rdev);  }  #define R600_PTE_VALID     (1 << 0) @@ -392,10 +393,12 @@ int rs600_irq_process(struct radeon_device *rdev)  		/* Vertical blank interrupts */  		if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) {  			drm_handle_vblank(rdev->ddev, 0); +			rdev->pm.vblank_sync = true;  			wake_up(&rdev->irq.vblank_queue);  		}  		if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) {  			drm_handle_vblank(rdev->ddev, 1); +			rdev->pm.vblank_sync = true;  			wake_up(&rdev->irq.vblank_queue);  		}  		if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { @@ -472,13 +475,38 @@ void rs600_mc_init(struct radeon_device *rdev)  	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);  	base = RREG32_MC(R_000004_MC_FB_LOCATION);  	base = G_000004_MC_FB_START(base) << 16; +	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);  	radeon_vram_location(rdev, &rdev->mc, base);  	radeon_gtt_location(rdev, &rdev->mc); +	radeon_update_bandwidth_info(rdev);  }  void rs600_bandwidth_update(struct radeon_device *rdev)  { -	/* FIXME: implement, should this be like rs690 ? */ +	struct drm_display_mode *mode0 = NULL; +	struct drm_display_mode *mode1 = NULL; +	u32 d1mode_priority_a_cnt, d2mode_priority_a_cnt; +	/* FIXME: implement full support */ + +	radeon_update_display_priority(rdev); + +	if (rdev->mode_info.crtcs[0]->base.enabled) +		mode0 = &rdev->mode_info.crtcs[0]->base.mode; +	if (rdev->mode_info.crtcs[1]->base.enabled) +		mode1 = &rdev->mode_info.crtcs[1]->base.mode; + +	rs690_line_buffer_adjust(rdev, mode0, mode1); + +	if (rdev->disp_priority == 2) { +		d1mode_priority_a_cnt = RREG32(R_006548_D1MODE_PRIORITY_A_CNT); +		d2mode_priority_a_cnt = RREG32(R_006D48_D2MODE_PRIORITY_A_CNT); +		d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); +		d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); +		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); +		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); +	}  }  uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg) @@ -598,6 +626,7 @@ int rs600_suspend(struct radeon_device *rdev)  void rs600_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r100_cp_fini(rdev);  	r100_wb_fini(rdev);  	r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h index c1c8f5885cb..e52d2695510 100644 --- a/drivers/gpu/drm/radeon/rs600d.h +++ b/drivers/gpu/drm/radeon/rs600d.h @@ -535,4 +535,57 @@  #define   G_00016C_INVALIDATE_L1_TLB(x)                (((x) >> 20) & 0x1)  #define   C_00016C_INVALIDATE_L1_TLB                   0xFFEFFFFF +#define R_006548_D1MODE_PRIORITY_A_CNT               0x006548 +#define   S_006548_D1MODE_PRIORITY_MARK_A(x)           (((x) & 0x7FFF) << 0) +#define   G_006548_D1MODE_PRIORITY_MARK_A(x)           (((x) >> 0) & 0x7FFF) +#define   C_006548_D1MODE_PRIORITY_MARK_A              0xFFFF8000 +#define   S_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16) +#define   G_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1) +#define   C_006548_D1MODE_PRIORITY_A_OFF               0xFFFEFFFF +#define   S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20) +#define   G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1) +#define   C_006548_D1MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF +#define   S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24) +#define   G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1) +#define   C_006548_D1MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF +#define R_00654C_D1MODE_PRIORITY_B_CNT               0x00654C +#define   S_00654C_D1MODE_PRIORITY_MARK_B(x)           (((x) & 0x7FFF) << 0) +#define   G_00654C_D1MODE_PRIORITY_MARK_B(x)           (((x) >> 0) & 0x7FFF) +#define   C_00654C_D1MODE_PRIORITY_MARK_B              0xFFFF8000 +#define   S_00654C_D1MODE_PRIORITY_B_OFF(x)            (((x) & 0x1) << 16) +#define   G_00654C_D1MODE_PRIORITY_B_OFF(x)            (((x) >> 16) & 0x1) +#define   C_00654C_D1MODE_PRIORITY_B_OFF               0xFFFEFFFF +#define   S_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) & 0x1) << 20) +#define   G_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) >> 20) & 0x1) +#define   C_00654C_D1MODE_PRIORITY_B_ALWAYS_ON         0xFFEFFFFF +#define   S_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x)     (((x) & 0x1) << 24) +#define   G_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x)     (((x) >> 24) & 0x1) +#define   C_00654C_D1MODE_PRIORITY_B_FORCE_MASK        0xFEFFFFFF +#define R_006D48_D2MODE_PRIORITY_A_CNT               0x006D48 +#define   S_006D48_D2MODE_PRIORITY_MARK_A(x)           (((x) & 0x7FFF) << 0) +#define   G_006D48_D2MODE_PRIORITY_MARK_A(x)           (((x) >> 0) & 0x7FFF) +#define   C_006D48_D2MODE_PRIORITY_MARK_A              0xFFFF8000 +#define   S_006D48_D2MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16) +#define   G_006D48_D2MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1) +#define   C_006D48_D2MODE_PRIORITY_A_OFF               0xFFFEFFFF +#define   S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20) +#define   G_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1) +#define   C_006D48_D2MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF +#define   S_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24) +#define   G_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1) +#define   C_006D48_D2MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF +#define R_006D4C_D2MODE_PRIORITY_B_CNT               0x006D4C +#define   S_006D4C_D2MODE_PRIORITY_MARK_B(x)           (((x) & 0x7FFF) << 0) +#define   G_006D4C_D2MODE_PRIORITY_MARK_B(x)           (((x) >> 0) & 0x7FFF) +#define   C_006D4C_D2MODE_PRIORITY_MARK_B              0xFFFF8000 +#define   S_006D4C_D2MODE_PRIORITY_B_OFF(x)            (((x) & 0x1) << 16) +#define   G_006D4C_D2MODE_PRIORITY_B_OFF(x)            (((x) >> 16) & 0x1) +#define   C_006D4C_D2MODE_PRIORITY_B_OFF               0xFFFEFFFF +#define   S_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) & 0x1) << 20) +#define   G_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x)      (((x) >> 20) & 0x1) +#define   C_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON         0xFFEFFFFF +#define   S_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x)     (((x) & 0x1) << 24) +#define   G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x)     (((x) >> 24) & 0x1) +#define   C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK        0xFEFFFFFF +  #endif diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 83b9174f76f..bbf3da790fd 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -27,6 +27,7 @@   */  #include "drmP.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "atom.h"  #include "rs690d.h" @@ -57,42 +58,57 @@ static void rs690_gpu_init(struct radeon_device *rdev)  	}  } +union igp_info { +	struct _ATOM_INTEGRATED_SYSTEM_INFO info; +	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2; +}; +  void rs690_pm_info(struct radeon_device *rdev)  {  	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); -	struct _ATOM_INTEGRATED_SYSTEM_INFO *info; -	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *info_v2; -	void *ptr; +	union igp_info *info;  	uint16_t data_offset;  	uint8_t frev, crev;  	fixed20_12 tmp; -	atom_parse_data_header(rdev->mode_info.atom_context, index, NULL, -			       &frev, &crev, &data_offset); -	ptr = rdev->mode_info.atom_context->bios + data_offset; -	info = (struct _ATOM_INTEGRATED_SYSTEM_INFO *)ptr; -	info_v2 = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *)ptr; -	/* Get various system informations from bios */ -	switch (crev) { -	case 1: -		tmp.full = rfixed_const(100); -		rdev->pm.igp_sideport_mclk.full = rfixed_const(info->ulBootUpMemoryClock); -		rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); -		rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->usK8MemoryClock)); -		rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->usFSBClock)); -		rdev->pm.igp_ht_link_width.full = rfixed_const(info->ucHTLinkWidth); -		break; -	case 2: -		tmp.full = rfixed_const(100); -		rdev->pm.igp_sideport_mclk.full = rfixed_const(info_v2->ulBootUpSidePortClock); -		rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); -		rdev->pm.igp_system_mclk.full = rfixed_const(info_v2->ulBootUpUMAClock); -		rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); -		rdev->pm.igp_ht_link_clk.full = rfixed_const(info_v2->ulHTLinkFreq); -		rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp); -		rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info_v2->usMinHTLinkWidth)); -		break; -	default: +	if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL, +				   &frev, &crev, &data_offset)) { +		info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset); + +		/* Get various system informations from bios */ +		switch (crev) { +		case 1: +			tmp.full = rfixed_const(100); +			rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info.ulBootUpMemoryClock); +			rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); +			rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); +			rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->info.usFSBClock)); +			rdev->pm.igp_ht_link_width.full = rfixed_const(info->info.ucHTLinkWidth); +			break; +		case 2: +			tmp.full = rfixed_const(100); +			rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info_v2.ulBootUpSidePortClock); +			rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); +			rdev->pm.igp_system_mclk.full = rfixed_const(info->info_v2.ulBootUpUMAClock); +			rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); +			rdev->pm.igp_ht_link_clk.full = rfixed_const(info->info_v2.ulHTLinkFreq); +			rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp); +			rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); +			break; +		default: +			tmp.full = rfixed_const(100); +			/* We assume the slower possible clock ie worst case */ +			/* DDR 333Mhz */ +			rdev->pm.igp_sideport_mclk.full = rfixed_const(333); +			/* FIXME: system clock ? */ +			rdev->pm.igp_system_mclk.full = rfixed_const(100); +			rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); +			rdev->pm.igp_ht_link_clk.full = rfixed_const(200); +			rdev->pm.igp_ht_link_width.full = rfixed_const(8); +			DRM_ERROR("No integrated system info for your GPU, using safe default\n"); +			break; +		} +	} else {  		tmp.full = rfixed_const(100);  		/* We assume the slower possible clock ie worst case */  		/* DDR 333Mhz */ @@ -103,7 +119,6 @@ void rs690_pm_info(struct radeon_device *rdev)  		rdev->pm.igp_ht_link_clk.full = rfixed_const(200);  		rdev->pm.igp_ht_link_width.full = rfixed_const(8);  		DRM_ERROR("No integrated system info for your GPU, using safe default\n"); -		break;  	}  	/* Compute various bandwidth */  	/* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4  */ @@ -131,7 +146,6 @@ void rs690_pm_info(struct radeon_device *rdev)  void rs690_mc_init(struct radeon_device *rdev)  { -	fixed20_12 a;  	u64 base;  	rs400_gart_adjust_size(rdev); @@ -145,18 +159,10 @@ void rs690_mc_init(struct radeon_device *rdev)  	base = RREG32_MC(R_000100_MCCFG_FB_LOCATION);  	base = G_000100_MC_FB_START(base) << 16;  	rs690_pm_info(rdev); -	/* FIXME: we should enforce default clock in case GPU is not in -	 * default setup -	 */ -	a.full = rfixed_const(100); -	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); -	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); -	a.full = rfixed_const(16); -	/* core_bandwidth = sclk(Mhz) * 16 */ -	rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);  	rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);  	radeon_vram_location(rdev, &rdev->mc, base);  	radeon_gtt_location(rdev, &rdev->mc); +	radeon_update_bandwidth_info(rdev);  }  void rs690_line_buffer_adjust(struct radeon_device *rdev, @@ -394,10 +400,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev)  	struct drm_display_mode *mode1 = NULL;  	struct rs690_watermark wm0;  	struct rs690_watermark wm1; -	u32 tmp; +	u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;  	fixed20_12 priority_mark02, priority_mark12, fill_rate;  	fixed20_12 a, b; +	radeon_update_display_priority(rdev); +  	if (rdev->mode_info.crtcs[0]->base.enabled)  		mode0 = &rdev->mode_info.crtcs[0]->base.mode;  	if (rdev->mode_info.crtcs[1]->base.enabled) @@ -407,7 +415,8 @@ void rs690_bandwidth_update(struct radeon_device *rdev)  	 * modes if the user specifies HIGH for displaypriority  	 * option.  	 */ -	if (rdev->disp_priority == 2) { +	if ((rdev->disp_priority == 2) && +	    ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))) {  		tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER);  		tmp &= C_000104_MC_DISP0R_INIT_LAT;  		tmp &= C_000104_MC_DISP1R_INIT_LAT; @@ -482,10 +491,16 @@ void rs690_bandwidth_update(struct radeon_device *rdev)  			priority_mark12.full = 0;  		if (wm1.priority_mark_max.full > priority_mark12.full)  			priority_mark12.full = wm1.priority_mark_max.full; -		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); -		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); -		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); -		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); +		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); +		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); +		if (rdev->disp_priority == 2) { +			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); +			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); +		} +		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); +		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);  	} else if (mode0) {  		if (rfixed_trunc(wm0.dbpp) > 64)  			a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair); @@ -512,8 +527,11 @@ void rs690_bandwidth_update(struct radeon_device *rdev)  			priority_mark02.full = 0;  		if (wm0.priority_mark_max.full > priority_mark02.full)  			priority_mark02.full = wm0.priority_mark_max.full; -		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); -		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); +		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); +		if (rdev->disp_priority == 2) +			d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); +		WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);  		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,  			S_006D48_D2MODE_PRIORITY_A_OFF(1));  		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, @@ -544,12 +562,15 @@ void rs690_bandwidth_update(struct radeon_device *rdev)  			priority_mark12.full = 0;  		if (wm1.priority_mark_max.full > priority_mark12.full)  			priority_mark12.full = wm1.priority_mark_max.full; +		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); +		if (rdev->disp_priority == 2) +			d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1);  		WREG32(R_006548_D1MODE_PRIORITY_A_CNT,  			S_006548_D1MODE_PRIORITY_A_OFF(1));  		WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,  			S_00654C_D1MODE_PRIORITY_B_OFF(1)); -		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); -		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); +		WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +		WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);  	}  } @@ -657,6 +678,7 @@ int rs690_suspend(struct radeon_device *rdev)  void rs690_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r100_cp_fini(rdev);  	r100_wb_fini(rdev);  	r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/rs690d.h b/drivers/gpu/drm/radeon/rs690d.h index 62d31e7a897..36e6398a98a 100644 --- a/drivers/gpu/drm/radeon/rs690d.h +++ b/drivers/gpu/drm/radeon/rs690d.h @@ -182,6 +182,9 @@  #define   S_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) & 0x1) << 16)  #define   G_006548_D1MODE_PRIORITY_A_OFF(x)            (((x) >> 16) & 0x1)  #define   C_006548_D1MODE_PRIORITY_A_OFF               0xFFFEFFFF +#define   S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) & 0x1) << 20) +#define   G_006548_D1MODE_PRIORITY_A_ALWAYS_ON(x)      (((x) >> 20) & 0x1) +#define   C_006548_D1MODE_PRIORITY_A_ALWAYS_ON         0xFFEFFFFF  #define   S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) & 0x1) << 24)  #define   G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x)     (((x) >> 24) & 0x1)  #define   C_006548_D1MODE_PRIORITY_A_FORCE_MASK        0xFEFFFFFF diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index bea747da123..9035121f4b5 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -26,9 +26,11 @@   *          Jerome Glisse   */  #include <linux/seq_file.h> +#include <linux/slab.h>  #include "drmP.h"  #include "rv515d.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "atom.h"  #include "rv515_reg_safe.h" @@ -279,19 +281,13 @@ static void rv515_vram_get_type(struct radeon_device *rdev)  void rv515_mc_init(struct radeon_device *rdev)  { -	fixed20_12 a;  	rv515_vram_get_type(rdev);  	r100_vram_init_sizes(rdev);  	radeon_vram_location(rdev, &rdev->mc, 0);  	if (!(rdev->flags & RADEON_IS_AGP))  		radeon_gtt_location(rdev, &rdev->mc); -	/* FIXME: we should enforce default clock in case GPU is not in -	 * default setup -	 */ -	a.full = rfixed_const(100); -	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); -	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); +	radeon_update_bandwidth_info(rdev);  }  uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg) @@ -539,6 +535,7 @@ void rv515_set_safe_registers(struct radeon_device *rdev)  void rv515_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r100_cp_fini(rdev);  	r100_wb_fini(rdev);  	r100_ib_fini(rdev); @@ -1020,7 +1017,7 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)  	struct drm_display_mode *mode1 = NULL;  	struct rv515_watermark wm0;  	struct rv515_watermark wm1; -	u32 tmp; +	u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt;  	fixed20_12 priority_mark02, priority_mark12, fill_rate;  	fixed20_12 a, b; @@ -1088,10 +1085,16 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)  			priority_mark12.full = 0;  		if (wm1.priority_mark_max.full > priority_mark12.full)  			priority_mark12.full = wm1.priority_mark_max.full; -		WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); -		WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); -		WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); -		WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); +		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); +		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); +		if (rdev->disp_priority == 2) { +			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; +			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; +		} +		WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +		WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); +		WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +		WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);  	} else if (mode0) {  		if (rfixed_trunc(wm0.dbpp) > 64)  			a.full = rfixed_div(wm0.dbpp, wm0.num_line_pair); @@ -1118,8 +1121,11 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)  			priority_mark02.full = 0;  		if (wm0.priority_mark_max.full > priority_mark02.full)  			priority_mark02.full = wm0.priority_mark_max.full; -		WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); -		WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); +		d1mode_priority_a_cnt = rfixed_trunc(priority_mark02); +		if (rdev->disp_priority == 2) +			d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; +		WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +		WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt);  		WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);  		WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);  	} else { @@ -1148,10 +1154,13 @@ void rv515_bandwidth_avivo_update(struct radeon_device *rdev)  			priority_mark12.full = 0;  		if (wm1.priority_mark_max.full > priority_mark12.full)  			priority_mark12.full = wm1.priority_mark_max.full; +		d2mode_priority_a_cnt = rfixed_trunc(priority_mark12); +		if (rdev->disp_priority == 2) +			d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON;  		WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);  		WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); -		WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); -		WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); +		WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +		WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt);  	}  } @@ -1161,6 +1170,8 @@ void rv515_bandwidth_update(struct radeon_device *rdev)  	struct drm_display_mode *mode0 = NULL;  	struct drm_display_mode *mode1 = NULL; +	radeon_update_display_priority(rdev); +  	if (rdev->mode_info.crtcs[0]->base.enabled)  		mode0 = &rdev->mode_info.crtcs[0]->base.mode;  	if (rdev->mode_info.crtcs[1]->base.enabled) @@ -1170,7 +1181,8 @@ void rv515_bandwidth_update(struct radeon_device *rdev)  	 * modes if the user specifies HIGH for displaypriority  	 * option.  	 */ -	if (rdev->disp_priority == 2) { +	if ((rdev->disp_priority == 2) && +	    (rdev->family == CHIP_RV515)) {  		tmp = RREG32_MC(MC_MISC_LAT_TIMER);  		tmp &= ~MC_DISP1R_INIT_LAT_MASK;  		tmp &= ~MC_DISP0R_INIT_LAT_MASK; diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 37887dee12a..97958a64df1 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -27,8 +27,10 @@   */  #include <linux/firmware.h>  #include <linux/platform_device.h> +#include <linux/slab.h>  #include "drmP.h"  #include "radeon.h" +#include "radeon_asic.h"  #include "radeon_drm.h"  #include "rv770d.h"  #include "atom.h" @@ -125,9 +127,9 @@ void rv770_pcie_gart_disable(struct radeon_device *rdev)  void rv770_pcie_gart_fini(struct radeon_device *rdev)  { +	radeon_gart_fini(rdev);  	rv770_pcie_gart_disable(rdev);  	radeon_gart_table_vram_free(rdev); -	radeon_gart_fini(rdev);  } @@ -647,10 +649,13 @@ static void rv770_gpu_init(struct radeon_device *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);  	WREG32(CC_SYS_RB_BACKEND_DISABLE,  cc_rb_backend_disable);  	WREG32(CGTS_SYS_TCC_DISABLE, 0);  	WREG32(CGTS_TCC_DISABLE, 0); +	WREG32(CGTS_USER_SYS_TCC_DISABLE, 0); +	WREG32(CGTS_USER_TCC_DISABLE, 0);  	num_qd_pipes =  		R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); @@ -864,7 +869,6 @@ static void rv770_gpu_init(struct radeon_device *rdev)  int rv770_mc_init(struct radeon_device *rdev)  { -	fixed20_12 a;  	u32 tmp;  	int chansize, numchan; @@ -908,12 +912,8 @@ int rv770_mc_init(struct radeon_device *rdev)  		rdev->mc.real_vram_size = rdev->mc.aper_size;  	}  	r600_vram_gtt_location(rdev, &rdev->mc); -	/* FIXME: we should enforce default clock in case GPU is not in -	 * default setup -	 */ -	a.full = rfixed_const(100); -	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); -	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); +	radeon_update_bandwidth_info(rdev); +  	return 0;  } @@ -1013,6 +1013,13 @@ int rv770_resume(struct radeon_device *rdev)  		DRM_ERROR("radeon: failled testing IB (%d).\n", r);  		return r;  	} + +	r = r600_audio_init(rdev); +	if (r) { +		dev_err(rdev->dev, "radeon: audio init failed\n"); +		return r; +	} +  	return r;  } @@ -1021,6 +1028,7 @@ int rv770_suspend(struct radeon_device *rdev)  {  	int r; +	r600_audio_fini(rdev);  	/* FIXME: we should wait for ring to be empty */  	r700_cp_stop(rdev);  	rdev->cp.ready = false; @@ -1144,11 +1152,19 @@ int rv770_init(struct radeon_device *rdev)  			}  		}  	} + +	r = r600_audio_init(rdev); +	if (r) { +		dev_err(rdev->dev, "radeon: audio init failed\n"); +		return r; +	} +  	return 0;  }  void rv770_fini(struct radeon_device *rdev)  { +	radeon_pm_fini(rdev);  	r600_blit_fini(rdev);  	r600_cp_fini(rdev);  	r600_wb_fini(rdev); diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index 4648ed2f014..4bf69c40449 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c @@ -35,6 +35,7 @@  #include "ttm/ttm_placement.h"  #include <linux/agp_backend.h>  #include <linux/module.h> +#include <linux/slab.h>  #include <linux/io.h>  #include <asm/agp.h> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 89c38c49066..0e3754a3a30 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1425,8 +1425,8 @@ int ttm_bo_global_init(struct ttm_global_reference *ref)  	atomic_set(&glob->bo_count, 0); -	kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type); -	ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects"); +	ret = kobject_init_and_add( +		&glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects");  	if (unlikely(ret != 0))  		kobject_put(&glob->kobj);  	return ret; @@ -1716,40 +1716,12 @@ int ttm_bo_wait(struct ttm_buffer_object *bo,  }  EXPORT_SYMBOL(ttm_bo_wait); -void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo) -{ -	atomic_set(&bo->reserved, 0); -	wake_up_all(&bo->event_queue); -} - -int ttm_bo_block_reservation(struct ttm_buffer_object *bo, bool interruptible, -			     bool no_wait) -{ -	int ret; - -	while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) { -		if (no_wait) -			return -EBUSY; -		else if (interruptible) { -			ret = wait_event_interruptible -			    (bo->event_queue, atomic_read(&bo->reserved) == 0); -			if (unlikely(ret != 0)) -				return ret; -		} else { -			wait_event(bo->event_queue, -				   atomic_read(&bo->reserved) == 0); -		} -	} -	return 0; -} -  int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)  {  	int ret = 0;  	/* -	 * Using ttm_bo_reserve instead of ttm_bo_block_reservation -	 * makes sure the lru lists are updated. +	 * Using ttm_bo_reserve makes sure the lru lists are updated.  	 */  	ret = ttm_bo_reserve(bo, true, no_wait, false, 0); diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 5ca37a58a98..d764e82e799 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -33,6 +33,7 @@  #include <linux/io.h>  #include <linux/highmem.h>  #include <linux/wait.h> +#include <linux/slab.h>  #include <linux/vmalloc.h>  #include <linux/module.h> diff --git a/drivers/gpu/drm/ttm/ttm_lock.c b/drivers/gpu/drm/ttm/ttm_lock.c index 3d172ef04ee..de41e55a944 100644 --- a/drivers/gpu/drm/ttm/ttm_lock.c +++ b/drivers/gpu/drm/ttm/ttm_lock.c @@ -204,7 +204,6 @@ static int __ttm_vt_unlock(struct ttm_lock *lock)  	lock->flags &= ~TTM_VT_LOCK;  	wake_up_all(&lock->queue);  	spin_unlock(&lock->lock); -	printk(KERN_INFO TTM_PFX "vt unlock.\n");  	return ret;  } @@ -265,10 +264,8 @@ int ttm_vt_lock(struct ttm_lock *lock,  				   ttm_lock_type, &ttm_vt_lock_remove, NULL);  	if (ret)  		(void)__ttm_vt_unlock(lock); -	else { +	else  		lock->vt_holder = tfile; -		printk(KERN_INFO TTM_PFX "vt lock.\n"); -	}  	return ret;  } diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c index eb143e04d40..801b702566e 100644 --- a/drivers/gpu/drm/ttm/ttm_memory.c +++ b/drivers/gpu/drm/ttm/ttm_memory.c @@ -32,6 +32,7 @@  #include <linux/wait.h>  #include <linux/mm.h>  #include <linux/module.h> +#include <linux/slab.h>  #define TTM_MEMORY_ALLOC_RETRIES 4 @@ -260,8 +261,8 @@ static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob,  	zone->used_mem = 0;  	zone->glob = glob;  	glob->zone_kernel = zone; -	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); -	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); +	ret = kobject_init_and_add( +		&zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);  	if (unlikely(ret != 0)) {  		kobject_put(&zone->kobj);  		return ret; @@ -296,8 +297,8 @@ static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob,  	zone->used_mem = 0;  	zone->glob = glob;  	glob->zone_highmem = zone; -	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); -	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); +	ret = kobject_init_and_add( +		&zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);  	if (unlikely(ret != 0)) {  		kobject_put(&zone->kobj);  		return ret; @@ -343,8 +344,8 @@ static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob,  	zone->used_mem = 0;  	zone->glob = glob;  	glob->zone_dma32 = zone; -	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); -	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); +	ret = kobject_init_and_add( +		&zone->kobj, &ttm_mem_zone_kobj_type, &glob->kobj, zone->name);  	if (unlikely(ret != 0)) {  		kobject_put(&zone->kobj);  		return ret; @@ -365,10 +366,8 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)  	glob->swap_queue = create_singlethread_workqueue("ttm_swap");  	INIT_WORK(&glob->work, ttm_shrink_work);  	init_waitqueue_head(&glob->queue); -	kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type); -	ret = kobject_add(&glob->kobj, -			  ttm_get_kobj(), -			  "memory_accounting"); +	ret = kobject_init_and_add( +		&glob->kobj, &ttm_mem_glob_kobj_type, ttm_get_kobj(), "memory_accounting");  	if (unlikely(ret != 0)) {  		kobject_put(&glob->kobj);  		return ret; diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index a759170763b..d5fd5b8faeb 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -28,13 +28,14 @@   * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>   */ -#include <linux/vmalloc.h>  #include <linux/sched.h>  #include <linux/highmem.h>  #include <linux/pagemap.h>  #include <linux/file.h>  #include <linux/swap.h> +#include <linux/slab.h>  #include "drm_cache.h" +#include "drm_mem_util.h"  #include "ttm/ttm_module.h"  #include "ttm/ttm_bo_driver.h"  #include "ttm/ttm_placement.h" @@ -43,32 +44,15 @@ static int ttm_tt_swapin(struct ttm_tt *ttm);  /**   * Allocates storage for pointers to the pages that back the ttm. - * - * Uses kmalloc if possible. Otherwise falls back to vmalloc.   */  static void ttm_tt_alloc_page_directory(struct ttm_tt *ttm)  { -	unsigned long size = ttm->num_pages * sizeof(*ttm->pages); -	ttm->pages = NULL; - -	if (size <= PAGE_SIZE) -		ttm->pages = kzalloc(size, GFP_KERNEL); - -	if (!ttm->pages) { -		ttm->pages = vmalloc_user(size); -		if (ttm->pages) -			ttm->page_flags |= TTM_PAGE_FLAG_VMALLOC; -	} +	ttm->pages = drm_calloc_large(ttm->num_pages, sizeof(*ttm->pages));  }  static void ttm_tt_free_page_directory(struct ttm_tt *ttm)  { -	if (ttm->page_flags & TTM_PAGE_FLAG_VMALLOC) { -		vfree(ttm->pages); -		ttm->page_flags &= ~TTM_PAGE_FLAG_VMALLOC; -	} else { -		kfree(ttm->pages); -	} +	drm_free_large(ttm->pages);  	ttm->pages = NULL;  } diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c index 327380888b4..4c54f043068 100644 --- a/drivers/gpu/drm/via/via_dmablit.c +++ b/drivers/gpu/drm/via/via_dmablit.c @@ -40,6 +40,7 @@  #include "via_dmablit.h"  #include <linux/pagemap.h> +#include <linux/slab.h>  #define VIA_PGDN(x)	     (((unsigned long)(x)) & PAGE_MASK)  #define VIA_PGOFF(x)	    (((unsigned long)(x)) & ~PAGE_MASK) diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index 5935b8842e8..34079f251cd 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c @@ -150,7 +150,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)  		cur_irq++;  	} -	/* Acknowlege interrupts */ +	/* Acknowledge interrupts */  	VIA_WRITE(VIA_REG_INTERRUPT, status); @@ -165,7 +165,7 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)  	u32 status;  	if (dev_priv) { -		/* Acknowlege interrupts */ +		/* Acknowledge interrupts */  		status = VIA_READ(VIA_REG_INTERRUPT);  		VIA_WRITE(VIA_REG_INTERRUPT, status |  			  dev_priv->irq_pending_mask); diff --git a/drivers/gpu/drm/via/via_video.c b/drivers/gpu/drm/via/via_video.c index 6ec04ac1245..6efac8117c9 100644 --- a/drivers/gpu/drm/via/via_video.c +++ b/drivers/gpu/drm/via/via_video.c @@ -75,7 +75,7 @@ int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_  	DRM_DEBUG("\n"); -	if (fx->lock > VIA_NR_XVMC_LOCKS) +	if (fx->lock >= VIA_NR_XVMC_LOCKS)  		return -EFAULT;  	lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock); diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index f20b8bcbef3..30ad13344f7 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig @@ -1,6 +1,6 @@  config DRM_VMWGFX  	tristate "DRM driver for VMware Virtual GPU" -	depends on DRM && PCI +	depends on DRM && PCI && FB  	select FB_DEFERRED_IO  	select FB_CFB_FILLRECT  	select FB_CFB_COPYAREA  |