Commit c2eb2fa6 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (21 commits)
  drm/radeon: load the right microcode on rs780
  drm: remove unused "can_grow" parameter from drm_crtc_helper_initial_config
  drm: fix EDID backward compat check
  drm: sync the mode validation for INTERLACE/DBLSCAN
  drm: fix typo in edid vendor parsing.
  DRM: drm_crtc_helper.h doesn't actually need i2c.h
  drm: fix missing inline function on 32-bit powerpc.
  drm: Use pgprot_writecombine in GEM GTT mapping to get the right bits for !PAT.
  drm/i915: Add a spinlock to protect the active_list
  drm/i915: Fix SDVO TV support
  drm/i915: Fix SDVO CREATE_PREFERRED_INPUT_TIMING command
  drm/i915: Fix error in SDVO DTD and modeline convert
  drm/i915: Fix SDVO command debug function
  drm/i915: fix TV mode setting in property change
  drm/i915: only set TV mode when any property changed
  drm/i915: clean up udelay usage
  drm/i915: add VGA hotplug support for 945+
  drm/i915: correctly set IGD device's gtt size for KMS.
  drm/i915: avoid hanging on to a stale pointer to raw_edid.
  drm/i915: check for -EINVAL from vm_insert_pfn
  ...
parents ef8a97bb 029a2edb
...@@ -42,6 +42,26 @@ static struct drm_display_mode std_modes[] = { ...@@ -42,6 +42,26 @@ static struct drm_display_mode std_modes[] = {
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
}; };
static void drm_mode_validate_flag(struct drm_connector *connector,
int flags)
{
struct drm_display_mode *mode, *t;
if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
return;
list_for_each_entry_safe(mode, t, &connector->modes, head) {
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
!(flags & DRM_MODE_FLAG_INTERLACE))
mode->status = MODE_NO_INTERLACE;
if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
!(flags & DRM_MODE_FLAG_DBLSCAN))
mode->status = MODE_NO_DBLESCAN;
}
return;
}
/** /**
* drm_helper_probe_connector_modes - get complete set of display modes * drm_helper_probe_connector_modes - get complete set of display modes
* @dev: DRM device * @dev: DRM device
...@@ -72,6 +92,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, ...@@ -72,6 +92,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
struct drm_connector_helper_funcs *connector_funcs = struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private; connector->helper_private;
int count = 0; int count = 0;
int mode_flags = 0;
DRM_DEBUG("%s\n", drm_get_connector_name(connector)); DRM_DEBUG("%s\n", drm_get_connector_name(connector));
/* set all modes to the unverified state */ /* set all modes to the unverified state */
...@@ -96,6 +117,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, ...@@ -96,6 +117,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
if (maxX && maxY) if (maxX && maxY)
drm_mode_validate_size(dev, &connector->modes, maxX, drm_mode_validate_size(dev, &connector->modes, maxX,
maxY, 0); maxY, 0);
if (connector->interlace_allowed)
mode_flags |= DRM_MODE_FLAG_INTERLACE;
if (connector->doublescan_allowed)
mode_flags |= DRM_MODE_FLAG_DBLSCAN;
drm_mode_validate_flag(connector, mode_flags);
list_for_each_entry_safe(mode, t, &connector->modes, head) { list_for_each_entry_safe(mode, t, &connector->modes, head) {
if (mode->status == MODE_OK) if (mode->status == MODE_OK)
mode->status = connector_funcs->mode_valid(connector, mode->status = connector_funcs->mode_valid(connector,
...@@ -885,7 +913,6 @@ bool drm_helper_plugged_event(struct drm_device *dev) ...@@ -885,7 +913,6 @@ bool drm_helper_plugged_event(struct drm_device *dev)
/** /**
* drm_initial_config - setup a sane initial connector configuration * drm_initial_config - setup a sane initial connector configuration
* @dev: DRM device * @dev: DRM device
* @can_grow: this configuration is growable
* *
* LOCKING: * LOCKING:
* Called at init time, must take mode config lock. * Called at init time, must take mode config lock.
...@@ -897,7 +924,7 @@ bool drm_helper_plugged_event(struct drm_device *dev) ...@@ -897,7 +924,7 @@ bool drm_helper_plugged_event(struct drm_device *dev)
* RETURNS: * RETURNS:
* Zero if everything went ok, nonzero otherwise. * Zero if everything went ok, nonzero otherwise.
*/ */
bool drm_helper_initial_config(struct drm_device *dev, bool can_grow) bool drm_helper_initial_config(struct drm_device *dev)
{ {
struct drm_connector *connector; struct drm_connector *connector;
int count = 0; int count = 0;
......
...@@ -125,10 +125,8 @@ static bool edid_is_valid(struct edid *edid) ...@@ -125,10 +125,8 @@ static bool edid_is_valid(struct edid *edid)
DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version); DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
goto bad; goto bad;
} }
if (edid->revision > 3) { if (edid->revision > 4)
DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision); DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
goto bad;
}
for (i = 0; i < EDID_LENGTH; i++) for (i = 0; i < EDID_LENGTH; i++)
csum += raw_edid[i]; csum += raw_edid[i];
...@@ -162,7 +160,7 @@ static bool edid_vendor(struct edid *edid, char *vendor) ...@@ -162,7 +160,7 @@ static bool edid_vendor(struct edid *edid, char *vendor)
edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@'; edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) | edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
((edid->mfg_id[1] & 0xe0) >> 5)) + '@'; ((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
edid_vendor[2] = (edid->mfg_id[2] & 0x1f) + '@'; edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
return !strncmp(edid_vendor, vendor, 3); return !strncmp(edid_vendor, vendor, 3);
} }
......
...@@ -505,7 +505,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -505,7 +505,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_local_map *map = NULL; struct drm_local_map *map = NULL;
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct drm_hash_item *hash; struct drm_hash_item *hash;
unsigned long prot;
int ret = 0; int ret = 0;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
...@@ -538,11 +537,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) ...@@ -538,11 +537,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = obj->dev->driver->gem_vm_ops; vma->vm_ops = obj->dev->driver->gem_vm_ops;
vma->vm_private_data = map->handle; vma->vm_private_data = map->handle;
/* FIXME: use pgprot_writecombine when available */ /* FIXME: use pgprot_writecombine when available */
prot = pgprot_val(vma->vm_page_prot); vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
#ifdef CONFIG_X86
prot |= _PAGE_CACHE_WC;
#endif
vma->vm_page_prot = __pgprot(prot);
/* Take a ref for this mapping of the object, so that the fault /* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object. * handler can dereference the mmap offset's pointer to the object.
......
...@@ -451,6 +451,7 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) ...@@ -451,6 +451,7 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
} }
EXPORT_SYMBOL(drm_sysfs_hotplug_event);
/** /**
* drm_sysfs_device_add - adds a class device to sysfs for a character driver * drm_sysfs_device_add - adds a class device to sysfs for a character driver
......
...@@ -922,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, ...@@ -922,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
* Some of the preallocated space is taken by the GTT * Some of the preallocated space is taken by the GTT
* and popup. GTT is 1K per MB of aperture size, and popup is 4K. * and popup. GTT is 1K per MB of aperture size, and popup is 4K.
*/ */
if (IS_G4X(dev)) if (IS_G4X(dev) || IS_IGD(dev))
overhead = 4096; overhead = 4096;
else else
overhead = (*aperture_size / 1024) + 4096; overhead = (*aperture_size / 1024) + 4096;
...@@ -1030,13 +1030,6 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -1030,13 +1030,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret) if (ret)
goto destroy_ringbuffer; goto destroy_ringbuffer;
/* FIXME: re-add hotplug support */
#if 0
ret = drm_hotplug_init(dev);
if (ret)
goto destroy_ringbuffer;
#endif
/* Always safe in the mode setting case. */ /* Always safe in the mode setting case. */
/* FIXME: do pre/post-mode set stuff in core KMS code */ /* FIXME: do pre/post-mode set stuff in core KMS code */
dev->vblank_disable_allowed = 1; dev->vblank_disable_allowed = 1;
...@@ -1049,7 +1042,7 @@ static int i915_load_modeset_init(struct drm_device *dev) ...@@ -1049,7 +1042,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
intel_modeset_init(dev); intel_modeset_init(dev);
drm_helper_initial_config(dev, false); drm_helper_initial_config(dev);
return 0; return 0;
......
...@@ -159,6 +159,9 @@ typedef struct drm_i915_private { ...@@ -159,6 +159,9 @@ typedef struct drm_i915_private {
u32 irq_mask_reg; u32 irq_mask_reg;
u32 pipestat[2]; u32 pipestat[2];
u32 hotplug_supported_mask;
struct work_struct hotplug_work;
int tex_lru_log_granularity; int tex_lru_log_granularity;
int allow_batchbuffer; int allow_batchbuffer;
struct mem_block *agp_heap; struct mem_block *agp_heap;
...@@ -297,6 +300,7 @@ typedef struct drm_i915_private { ...@@ -297,6 +300,7 @@ typedef struct drm_i915_private {
* *
* A reference is held on the buffer while on this list. * A reference is held on the buffer while on this list.
*/ */
spinlock_t active_list_lock;
struct list_head active_list; struct list_head active_list;
/** /**
...@@ -810,6 +814,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); ...@@ -810,6 +814,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
IS_I915GM(dev))) IS_I915GM(dev)))
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev)) #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev))
#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024) #define PRIMARY_RINGBUFFER_SIZE (128*1024)
......
...@@ -1072,6 +1072,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -1072,6 +1072,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
case -EAGAIN: case -EAGAIN:
return VM_FAULT_OOM; return VM_FAULT_OOM;
case -EFAULT: case -EFAULT:
case -EINVAL:
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
default: default:
return VM_FAULT_NOPAGE; return VM_FAULT_NOPAGE;
...@@ -1324,8 +1325,10 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno) ...@@ -1324,8 +1325,10 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
obj_priv->active = 1; obj_priv->active = 1;
} }
/* Move from whatever list we were on to the tail of execution. */ /* Move from whatever list we were on to the tail of execution. */
spin_lock(&dev_priv->mm.active_list_lock);
list_move_tail(&obj_priv->list, list_move_tail(&obj_priv->list,
&dev_priv->mm.active_list); &dev_priv->mm.active_list);
spin_unlock(&dev_priv->mm.active_list_lock);
obj_priv->last_rendering_seqno = seqno; obj_priv->last_rendering_seqno = seqno;
} }
...@@ -1467,6 +1470,7 @@ i915_gem_retire_request(struct drm_device *dev, ...@@ -1467,6 +1470,7 @@ i915_gem_retire_request(struct drm_device *dev,
/* Move any buffers on the active list that are no longer referenced /* Move any buffers on the active list that are no longer referenced
* by the ringbuffer to the flushing/inactive lists as appropriate. * by the ringbuffer to the flushing/inactive lists as appropriate.
*/ */
spin_lock(&dev_priv->mm.active_list_lock);
while (!list_empty(&dev_priv->mm.active_list)) { while (!list_empty(&dev_priv->mm.active_list)) {
struct drm_gem_object *obj; struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv; struct drm_i915_gem_object *obj_priv;
...@@ -1481,7 +1485,7 @@ i915_gem_retire_request(struct drm_device *dev, ...@@ -1481,7 +1485,7 @@ i915_gem_retire_request(struct drm_device *dev,
* this seqno. * this seqno.
*/ */
if (obj_priv->last_rendering_seqno != request->seqno) if (obj_priv->last_rendering_seqno != request->seqno)
return; goto out;
#if WATCH_LRU #if WATCH_LRU
DRM_INFO("%s: retire %d moves to inactive list %p\n", DRM_INFO("%s: retire %d moves to inactive list %p\n",
...@@ -1493,6 +1497,8 @@ i915_gem_retire_request(struct drm_device *dev, ...@@ -1493,6 +1497,8 @@ i915_gem_retire_request(struct drm_device *dev,
else else
i915_gem_object_move_to_inactive(obj); i915_gem_object_move_to_inactive(obj);
} }
out:
spin_unlock(&dev_priv->mm.active_list_lock);
} }
/** /**
...@@ -1990,20 +1996,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) ...@@ -1990,20 +1996,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
int regnum = obj_priv->fence_reg; int regnum = obj_priv->fence_reg;
uint32_t val; uint32_t val;
uint32_t pitch_val; uint32_t pitch_val;
uint32_t fence_size_bits;
if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) ||
(obj_priv->gtt_offset & (obj->size - 1))) { (obj_priv->gtt_offset & (obj->size - 1))) {
WARN(1, "%s: object 0x%08x not 1M or size aligned\n", WARN(1, "%s: object 0x%08x not 512K or size aligned\n",
__func__, obj_priv->gtt_offset); __func__, obj_priv->gtt_offset);
return; return;
} }
pitch_val = (obj_priv->stride / 128) - 1; pitch_val = (obj_priv->stride / 128) - 1;
WARN_ON(pitch_val & ~0x0000000f);
val = obj_priv->gtt_offset; val = obj_priv->gtt_offset;
if (obj_priv->tiling_mode == I915_TILING_Y) if (obj_priv->tiling_mode == I915_TILING_Y)
val |= 1 << I830_FENCE_TILING_Y_SHIFT; val |= 1 << I830_FENCE_TILING_Y_SHIFT;
val |= I830_FENCE_SIZE_BITS(obj->size); fence_size_bits = I830_FENCE_SIZE_BITS(obj->size);
WARN_ON(fence_size_bits & ~0x00000f00);
val |= fence_size_bits;
val |= pitch_val << I830_FENCE_PITCH_SHIFT; val |= pitch_val << I830_FENCE_PITCH_SHIFT;
val |= I830_FENCE_REG_VALID; val |= I830_FENCE_REG_VALID;
...@@ -2194,7 +2203,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) ...@@ -2194,7 +2203,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
return -EBUSY; return -EBUSY;
if (alignment == 0) if (alignment == 0)
alignment = i915_gem_get_gtt_alignment(obj); alignment = i915_gem_get_gtt_alignment(obj);
if (alignment & (PAGE_SIZE - 1)) { if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) {
DRM_ERROR("Invalid object alignment requested %u\n", alignment); DRM_ERROR("Invalid object alignment requested %u\n", alignment);
return -EINVAL; return -EINVAL;
} }
...@@ -2211,15 +2220,20 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) ...@@ -2211,15 +2220,20 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
} }
} }
if (obj_priv->gtt_space == NULL) { if (obj_priv->gtt_space == NULL) {
bool lists_empty;
/* If the gtt is empty and we're still having trouble /* If the gtt is empty and we're still having trouble
* fitting our object in, we're out of memory. * fitting our object in, we're out of memory.
*/ */
#if WATCH_LRU #if WATCH_LRU
DRM_INFO("%s: GTT full, evicting something\n", __func__); DRM_INFO("%s: GTT full, evicting something\n", __func__);
#endif #endif
if (list_empty(&dev_priv->mm.inactive_list) && spin_lock(&dev_priv->mm.active_list_lock);
list_empty(&dev_priv->mm.flushing_list) && lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
list_empty(&dev_priv->mm.active_list)) { list_empty(&dev_priv->mm.flushing_list) &&
list_empty(&dev_priv->mm.active_list));
spin_unlock(&dev_priv->mm.active_list_lock);
if (lists_empty) {
DRM_ERROR("GTT full, but LRU list empty\n"); DRM_ERROR("GTT full, but LRU list empty\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -3675,6 +3689,7 @@ i915_gem_idle(struct drm_device *dev) ...@@ -3675,6 +3689,7 @@ i915_gem_idle(struct drm_device *dev)
i915_gem_retire_requests(dev); i915_gem_retire_requests(dev);
spin_lock(&dev_priv->mm.active_list_lock);
if (!dev_priv->mm.wedged) { if (!dev_priv->mm.wedged) {
/* Active and flushing should now be empty as we've /* Active and flushing should now be empty as we've
* waited for a sequence higher than any pending execbuffer * waited for a sequence higher than any pending execbuffer
...@@ -3701,6 +3716,7 @@ i915_gem_idle(struct drm_device *dev) ...@@ -3701,6 +3716,7 @@ i915_gem_idle(struct drm_device *dev)
obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
i915_gem_object_move_to_inactive(obj_priv->obj); i915_gem_object_move_to_inactive(obj_priv->obj);
} }
spin_unlock(&dev_priv->mm.active_list_lock);
while (!list_empty(&dev_priv->mm.flushing_list)) { while (!list_empty(&dev_priv->mm.flushing_list)) {
struct drm_i915_gem_object *obj_priv; struct drm_i915_gem_object *obj_priv;
...@@ -3949,7 +3965,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, ...@@ -3949,7 +3965,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
if (ret != 0) if (ret != 0)
return ret; return ret;
spin_lock(&dev_priv->mm.active_list_lock);
BUG_ON(!list_empty(&dev_priv->mm.active_list)); BUG_ON(!list_empty(&dev_priv->mm.active_list));
spin_unlock(&dev_priv->mm.active_list_lock);
BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
BUG_ON(!list_empty(&dev_priv->mm.request_list)); BUG_ON(!list_empty(&dev_priv->mm.request_list));
...@@ -3993,6 +4012,7 @@ i915_gem_load(struct drm_device *dev) ...@@ -3993,6 +4012,7 @@ i915_gem_load(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
spin_lock_init(&dev_priv->mm.active_list_lock);
INIT_LIST_HEAD(&dev_priv->mm.active_list); INIT_LIST_HEAD(&dev_priv->mm.active_list);
INIT_LIST_HEAD(&dev_priv->mm.flushing_list); INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
INIT_LIST_HEAD(&dev_priv->mm.inactive_list); INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
......
...@@ -105,12 +105,14 @@ i915_dump_lru(struct drm_device *dev, const char *where) ...@@ -105,12 +105,14 @@ i915_dump_lru(struct drm_device *dev, const char *where)
struct drm_i915_gem_object *obj_priv; struct drm_i915_gem_object *obj_priv;
DRM_INFO("active list %s {\n", where); DRM_INFO("active list %s {\n", where);
spin_lock(&dev_priv->mm.active_list_lock);
list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
list) list)
{ {
DRM_INFO(" %p: %08x\n", obj_priv, DRM_INFO(" %p: %08x\n", obj_priv,
obj_priv->last_rendering_seqno); obj_priv->last_rendering_seqno);
} }
spin_unlock(&dev_priv->mm.active_list_lock);
DRM_INFO("}\n"); DRM_INFO("}\n");
DRM_INFO("flushing list %s {\n", where); DRM_INFO("flushing list %s {\n", where);
list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
......
...@@ -69,10 +69,13 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) ...@@ -69,10 +69,13 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv; struct drm_i915_gem_object *obj_priv;
spinlock_t *lock = NULL;
switch (list) { switch (list) {
case ACTIVE_LIST: case ACTIVE_LIST:
seq_printf(m, "Active:\n"); seq_printf(m, "Active:\n");
lock = &dev_priv->mm.active_list_lock;
spin_lock(lock);
head = &dev_priv->mm.active_list; head = &dev_priv->mm.active_list;
break; break;
case INACTIVE_LIST: case INACTIVE_LIST:
...@@ -104,6 +107,9 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) ...@@ -104,6 +107,9 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
seq_printf(m, " (fence: %d\n", obj_priv->fence_reg); seq_printf(m, " (fence: %d\n", obj_priv->fence_reg);
seq_printf(m, "\n"); seq_printf(m, "\n");
} }
if (lock)
spin_unlock(lock);
return 0; return 0;
} }
......
...@@ -216,6 +216,22 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) ...@@ -216,6 +216,22 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
else else
tile_width = 512; tile_width = 512;
/* check maximum stride & object size */
if (IS_I965G(dev)) {
/* i965 stores the end address of the gtt mapping in the fence
* reg, so dont bother to check the size */
if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
return false;
} else if (IS_I9XX(dev)) {
if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL ||
size > (I830_FENCE_MAX_SIZE_VAL << 20))
return false;
} else {
if (stride / 128 > I830_FENCE_MAX_PITCH_VAL ||
size > (I830_FENCE_MAX_SIZE_VAL << 19))
return false;
}
/* 965+ just needs multiples of tile width */ /* 965+ just needs multiples of tile width */
if (IS_I965G(dev)) { if (IS_I965G(dev)) {
if (stride & (tile_width - 1)) if (stride & (tile_width - 1))
......
...@@ -48,10 +48,6 @@ ...@@ -48,10 +48,6 @@
/** Interrupts that we mask and unmask at runtime. */ /** Interrupts that we mask and unmask at runtime. */
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
/** These are all of the interrupts used by the driver */
#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
I915_INTERRUPT_ENABLE_VAR)
#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\ #define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\
PIPE_VBLANK_INTERRUPT_STATUS) PIPE_VBLANK_INTERRUPT_STATUS)
...@@ -187,6 +183,19 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) ...@@ -187,6 +183,19 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
return I915_READ(reg); return I915_READ(reg);
} }
/*
* Handle hotplug events outside the interrupt handler proper.
*/
static void i915_hotplug_work_func(struct work_struct *work)
{
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
hotplug_work);
struct drm_device *dev = dev_priv->dev;
/* Just fire off a uevent and let userspace tell us what to do */
drm_sysfs_hotplug_event(dev);
}
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{ {
struct drm_device *dev = (struct drm_device *) arg; struct drm_device *dev = (struct drm_device *) arg;
...@@ -244,6 +253,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) ...@@ -244,6 +253,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
/* Consume port. Then clear IIR or we'll miss events */
if ((I915_HAS_HOTPLUG(dev)) &&
(iir & I915_DISPLAY_PORT_INTERRUPT)) {
u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
DRM_DEBUG("hotplug event received, stat 0x%08x\n",
hotplug_status);
if (hotplug_status & dev_priv->hotplug_supported_mask)
schedule_work(&dev_priv->hotplug_work);
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
I915_READ(PORT_HOTPLUG_STAT);
}
I915_WRITE(IIR, iir); I915_WRITE(IIR, iir);
new_iir = I915_READ(IIR); /* Flush posted writes */ new_iir = I915_READ(IIR); /* Flush posted writes */
...@@ -528,17 +551,24 @@ void i915_driver_irq_preinstall(struct drm_device * dev) ...@@ -528,17 +551,24 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
atomic_set(&dev_priv->irq_received, 0); atomic_set(&dev_priv->irq_received, 0);
if (I915_HAS_HOTPLUG(dev)) {
I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
}
I915_WRITE(HWSTAM, 0xeffe); I915_WRITE(HWSTAM, 0xeffe);
I915_WRITE(PIPEASTAT, 0); I915_WRITE(PIPEASTAT, 0);
I915_WRITE(PIPEBSTAT, 0); I915_WRITE(PIPEBSTAT, 0);
I915_WRITE(IMR, 0xffffffff); I915_WRITE(IMR, 0xffffffff);
I915_WRITE(IER, 0x0); I915_WRITE(IER, 0x0);
(void) I915_READ(IER); (void) I915_READ(IER);
INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
} }
int i915_driver_irq_postinstall(struct drm_device *dev) int i915_driver_irq_postinstall(struct drm_device *dev)
{ {
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
...@@ -550,13 +580,35 @@ int i915_driver_irq_postinstall(struct drm_device *dev) ...@@ -550,13 +580,35 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
dev_priv->pipestat[0] = 0; dev_priv->pipestat[0] = 0;
dev_priv->pipestat[1] = 0; dev_priv->pipestat[1] = 0;
if (I915_HAS_HOTPLUG(dev)) {
u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
/* Leave other bits alone */
hotplug_en |= HOTPLUG_EN_MASK;
I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS |
TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS |
SDVOB_HOTPLUG_INT_STATUS;
if (IS_G4X(dev)) {
dev_priv->hotplug_supported_mask |=
HDMIB_HOTPLUG_INT_STATUS |
HDMIC_HOTPLUG_INT_STATUS |
HDMID_HOTPLUG_INT_STATUS;
}
/* Enable in IER... */
enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
/* and unmask in IMR */
i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT);
}
/* Disable pipe interrupt enables, clear pending pipe status */ /* Disable pipe interrupt enables, clear pending pipe status */
I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
/* Clear pending interrupt status */ /* Clear pending interrupt status */
I915_WRITE(IIR, I915_READ(IIR)); I915_WRITE(IIR, I915_READ(IIR));
I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK); I915_WRITE(IER, enable_mask);
I915_WRITE(IMR, dev_priv->irq_mask_reg); I915_WRITE(IMR, dev_priv->irq_mask_reg);
(void) I915_READ(IER); (void) I915_READ(IER);
...@@ -575,6 +627,11 @@ void i915_driver_irq_uninstall(struct drm_device * dev) ...@@ -575,6 +627,11 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
dev_priv->vblank_pipe = 0; dev_priv->vblank_pipe = 0;
if (I915_HAS_HOTPLUG(dev)) {
I915_WRITE(PORT_HOTPLUG_EN, 0);
I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
}
I915_WRITE(HWSTAM, 0xffffffff); I915_WRITE(HWSTAM, 0xffffffff);
I915_WRITE(PIPEASTAT, 0); I915_WRITE(PIPEASTAT, 0);
I915_WRITE(PIPEBSTAT, 0); I915_WRITE(PIPEBSTAT, 0);
......
...@@ -190,6 +190,8 @@ ...@@ -190,6 +190,8 @@
#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
#define I830_FENCE_PITCH_SHIFT 4 #define I830_FENCE_PITCH_SHIFT 4
#define I830_FENCE_REG_VALID (1<<0) #define I830_FENCE_REG_VALID (1<<0)
#define I830_FENCE_MAX_PITCH_VAL 0x10
#define I830_FENCE_MAX_SIZE_VAL (1<<8)
#define I915_FENCE_START_MASK 0x0ff00000 #define I915_FENCE_START_MASK 0x0ff00000
#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8) #define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8)
...@@ -198,6 +200,7 @@ ...@@ -198,6 +200,7 @@
#define I965_FENCE_PITCH_SHIFT 2 #define I965_FENCE_PITCH_SHIFT 2
#define I965_FENCE_TILING_Y_SHIFT 1 #define I965_FENCE_TILING_Y_SHIFT 1
#define I965_FENCE_REG_VALID (1<<0) #define I965_FENCE_REG_VALID (1<<0)
#define I965_FENCE_MAX_PITCH_VAL 0x0400
/* /*
* Instruction and interrupt control regs * Instruction and interrupt control regs
...@@ -648,6 +651,14 @@ ...@@ -648,6 +651,14 @@
#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) #define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) #define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
#define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */ #define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */
#define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f
#define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \
HDMIC_HOTPLUG_INT_EN | \
HDMID_HOTPLUG_INT_EN | \
SDVOB_HOTPLUG_INT_EN | \
SDVOC_HOTPLUG_INT_EN | \
TV_HOTPLUG_INT_EN | \
CRT_HOTPLUG_INT_EN)
#define PORT_HOTPLUG_STAT 0x61114 #define PORT_HOTPLUG_STAT 0x61114
......
...@@ -41,7 +41,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) ...@@ -41,7 +41,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
temp = I915_READ(ADPA); temp = I915_READ(ADPA);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
temp &= ~ADPA_DAC_ENABLE; temp |= ADPA_DAC_ENABLE;
switch(mode) { switch(mode) {
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
...@@ -158,7 +158,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) ...@@ -158,7 +158,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
else else
tries = 1; tries = 1;
hotplug_en = I915_READ(PORT_HOTPLUG_EN); hotplug_en = I915_READ(PORT_HOTPLUG_EN);
hotplug_en &= ~(CRT_HOTPLUG_MASK); hotplug_en &= CRT_FORCE_HOTPLUG_MASK;
hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
if (IS_GM45(dev)) if (IS_GM45(dev))
......
...@@ -636,7 +636,7 @@ void ...@@ -636,7 +636,7 @@ void
intel_wait_for_vblank(struct drm_device *dev) intel_wait_for_vblank(struct drm_device *dev)
{ {
/* Wait for 20ms, i.e. one cycle at 50hz. */ /* Wait for 20ms, i.e. one cycle at 50hz. */
udelay(20000); mdelay(20);
} }
static int static int
...@@ -1106,6 +1106,26 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, ...@@ -1106,6 +1106,26 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
return -EINVAL; return -EINVAL;
} }
/* SDVO TV has fixed PLL values depend on its clock range,
this mirrors vbios setting. */
if (is_sdvo && is_tv) {
if (adjusted_mode->clock >= 100000
&& adjusted_mode->clock < 140500) {
clock.p1 = 2;
clock.p2 = 10;
clock.n = 3;
clock.m1 = 16;
clock.m2 = 8;
} else if (adjusted_mode->clock >= 140500
&& adjusted_mode->clock <= 200000) {
clock.p1 = 1;
clock.p2 = 10;
clock.n = 6;
clock.m1 = 12;
clock.m2 = 8;
}
}
if (IS_IGD(dev)) if (IS_IGD(dev))
fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
else else
......
...@@ -76,6 +76,7 @@ int intel_ddc_get_modes(struct intel_output *intel_output) ...@@ -76,6 +76,7 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
drm_mode_connector_update_edid_property(&intel_output->base, drm_mode_connector_update_edid_property(&intel_output->base,
edid); edid);
ret = drm_add_edid_modes(&intel_output->base, edid); ret = drm_add_edid_modes(&intel_output->base, edid);
intel_output->base.display_info.raw_edid = NULL;
kfree(edid); kfree(edid);
} }
......
This diff is collapsed.
...@@ -100,6 +100,9 @@ struct intel_sdvo_preferred_input_timing_args { ...@@ -100,6 +100,9 @@ struct intel_sdvo_preferred_input_timing_args {
u16 clock; u16 clock;
u16 width; u16 width;
u16 height; u16 height;
u8 interlace:1;
u8 scaled:1;
u8 pad:6;
} __attribute__((packed)); } __attribute__((packed));
/* I2C registers for SDVO */ /* I2C registers for SDVO */
......
...@@ -1570,33 +1570,49 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop ...@@ -1570,33 +1570,49 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct intel_output *intel_output = to_intel_output(connector); struct intel_output *intel_output = to_intel_output(connector);
struct intel_tv_priv *tv_priv = intel_output->dev_priv; struct intel_tv_priv *tv_priv = intel_output->dev_priv;
struct drm_encoder *encoder = &intel_output->enc;
struct drm_crtc *crtc = encoder->crtc;
int ret = 0; int ret = 0;
bool changed = false;
ret = drm_connector_property_set_value(connector, property, val); ret = drm_connector_property_set_value(connector, property, val);
if (ret < 0) if (ret < 0)
goto out; goto out;
if (property == dev->mode_config.tv_left_margin_property) if (property == dev->mode_config.tv_left_margin_property &&
tv_priv->margin[TV_MARGIN_LEFT] != val) {
tv_priv->margin[TV_MARGIN_LEFT] = val; tv_priv->margin[TV_MARGIN_LEFT] = val;
else if (property == dev->mode_config.tv_right_margin_property) changed = true;
} else if (property == dev->mode_config.tv_right_margin_property &&
tv_priv->margin[TV_MARGIN_RIGHT] != val) {
tv_priv->margin[TV_MARGIN_RIGHT] = val; tv_priv->margin[TV_MARGIN_RIGHT] = val;
else if (property == dev->mode_config.tv_top_margin_property) changed = true;
} else if (property == dev->mode_config.tv_top_margin_property &&
tv_priv->margin[TV_MARGIN_TOP] != val) {
tv_priv->margin[TV_MARGIN_TOP] = val; tv_priv->margin[TV_MARGIN_TOP] = val;
else if (property == dev->mode_config.tv_bottom_margin_property) changed = true;
} else if (property == dev->mode_config.tv_bottom_margin_property &&
tv_priv->margin[TV_MARGIN_BOTTOM] != val) {
tv_priv->margin[TV_MARGIN_BOTTOM] = val; tv_priv->margin[TV_MARGIN_BOTTOM] = val;
else if (property == dev->mode_config.tv_mode_property) { changed = true;
} else if (property == dev->mode_config.tv_mode_property) {
if (val >= NUM_TV_MODES) { if (val >= NUM_TV_MODES) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
if (!strcmp(tv_priv->tv_format, tv_modes[val].name))
goto out;
tv_priv->tv_format = tv_modes[val].name; tv_priv->tv_format = tv_modes[val].name;
intel_tv_mode_set(&intel_output->enc, NULL, NULL); changed = true;
} else { } else {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
intel_tv_mode_set(&intel_output->enc, NULL, NULL); if (changed && crtc)
drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
crtc->y, crtc->fb);
out: out:
return ret; return ret;
} }
......
...@@ -388,17 +388,17 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) ...@@ -388,17 +388,17 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
DRM_INFO("Loading RS780 CP Microcode\n"); DRM_INFO("Loading RS780 CP Microcode\n");
for (i = 0; i < PM4_UCODE_SIZE; i++) { for (i = 0; i < PM4_UCODE_SIZE; i++) {
RADEON_WRITE(R600_CP_ME_RAM_DATA, RADEON_WRITE(R600_CP_ME_RAM_DATA,
RV670_cp_microcode[i][0]); RS780_cp_microcode[i][0]);
RADEON_WRITE(R600_CP_ME_RAM_DATA, RADEON_WRITE(R600_CP_ME_RAM_DATA,
RV670_cp_microcode[i][1]); RS780_cp_microcode[i][1]);
RADEON_WRITE(R600_CP_ME_RAM_DATA, RADEON_WRITE(R600_CP_ME_RAM_DATA,
RV670_cp_microcode[i][2]); RS780_cp_microcode[i][2]);
} }
RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
DRM_INFO("Loading RS780 PFP Microcode\n"); DRM_INFO("Loading RS780 PFP Microcode\n");
for (i = 0; i < PFP_UCODE_SIZE; i++) for (i = 0; i < PFP_UCODE_SIZE; i++)
RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]);
} }
RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#ifndef __DRM_CRTC_HELPER_H__ #ifndef __DRM_CRTC_HELPER_H__
#define __DRM_CRTC_HELPER_H__ #define __DRM_CRTC_HELPER_H__
#include <linux/i2c.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/idr.h> #include <linux/idr.h>
...@@ -92,7 +91,7 @@ struct drm_connector_helper_funcs { ...@@ -92,7 +91,7 @@ struct drm_connector_helper_funcs {
extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
extern void drm_helper_disable_unused_functions(struct drm_device *dev); extern void drm_helper_disable_unused_functions(struct drm_device *dev);
extern int drm_helper_hotplug_stage_two(struct drm_device *dev); extern int drm_helper_hotplug_stage_two(struct drm_device *dev);
extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow); extern bool drm_helper_initial_config(struct drm_device *dev);
extern int drm_crtc_helper_set_config(struct drm_mode_set *set); extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
struct drm_display_mode *mode, struct drm_display_mode *mode,
......
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
#include <linux/delay.h> #include <linux/delay.h>
#ifndef readq #ifndef readq
static u64 readq(void __iomem *reg) static inline u64 readq(void __iomem *reg)
{ {
return ((u64) readl(reg)) | (((u64) readl(reg + 4UL)) << 32); return ((u64) readl(reg)) | (((u64) readl(reg + 4UL)) << 32);
} }
static void writeq(u64 val, void __iomem *reg) static inline void writeq(u64 val, void __iomem *reg)
{ {
writel(val & 0xffffffff, reg); writel(val & 0xffffffff, reg);
writel(val >> 32, reg + 0x4UL); writel(val >> 32, reg + 0x4UL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment