From: <jb...@ke...> - 2007-04-12 15:58:07
|
linux-core/drm_fops.c | 3 +-- linux-core/drm_modes.c | 3 ++- linux-core/intel_crt.c | 36 +++++++++++++----------------------- linux-core/intel_lvds.c | 20 ++++++++++++-------- shared-core/i915_init.c | 2 -- 5 files changed, 28 insertions(+), 36 deletions(-) New commits: diff-tree c2fce380c26d72f2d7971a4d08076da33c41f5ae (from 258e1cf70345198209e6d49a428efc3de8ce8238) Author: Jesse Barnes <jb...@ho...> Date: Thu Apr 12 08:57:58 2007 -0700 Move i2c init back to where it belongs and add i2c unregistration in *_destroy. diff --git a/linux-core/intel_crt.c b/linux-core/intel_crt.c index ca7ae7b..fe846eb 100644 --- a/linux-core/intel_crt.c +++ b/linux-core/intel_crt.c @@ -189,26 +189,19 @@ static enum drm_output_status intel_crt_ return output_status_disconnected; } - /* Set up the DDC bus. */ - intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return 0; - } - - if (intel_crt_detect_ddc(output)) { - intel_i2c_destroy(intel_output->ddc_bus); + if (intel_crt_detect_ddc(output)) return output_status_connected; - } - intel_i2c_destroy(intel_output->ddc_bus); /* TODO use load detect */ return output_status_unknown; } static void intel_crt_destroy(struct drm_output *output) { + struct intel_output *intel_output = output->driver_private; + + intel_i2c_destroy(intel_output->ddc_bus); + if (output->driver_private) kfree(output->driver_private); } @@ -219,17 +212,7 @@ static int intel_crt_get_modes(struct dr struct intel_output *intel_output = output->driver_private; int ret; - /* Set up the DDC bus. */ - intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return 0; - } - - ret = intel_ddc_get_modes(output); - intel_i2c_destroy(intel_output->ddc_bus); - return ret; + return intel_ddc_get_modes(output); } /* @@ -261,6 +244,13 @@ void intel_crt_init(drm_device_t *dev) drm_output_destroy(output); return; } + /* Set up the DDC bus. */ + intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A"); + if (!intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + return; + } intel_output->type = INTEL_OUTPUT_ANALOG; output->driver_private = intel_output; diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index e8670ad..d2725e2 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -268,14 +268,7 @@ static int intel_lvds_get_modes(struct d struct edid *edid_info; int ret = 0; - intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C"); - if (!intel_output->ddc_bus) { - dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " - "failed.\n"); - return 0; - } ret = intel_ddc_get_modes(output); - intel_i2c_destroy(intel_output->ddc_bus); if (ret) return ret; @@ -312,8 +305,19 @@ out: return 0; } +/** + * intel_lvds_destroy - unregister and free LVDS structures + * @output: output to free + * + * Unregister the DDC bus for this output then free the driver private + * structure. + */ static void intel_lvds_destroy(struct drm_output *output) { + struct intel_output *intel_output = output->driver_private; + + intel_i2c_destroy(intel_output->ddc_bus); + if (output->driver_private) kfree(output->driver_private); } @@ -375,7 +379,7 @@ void intel_lvds_init(struct drm_device * * preferred mode is the right one. */ intel_ddc_get_modes(output); - intel_i2c_destroy(intel_output->ddc_bus); + list_for_each_entry(scan, &output->probed_modes, head) { if (scan->type & DRM_MODE_TYPE_PREFERRED) { dev_priv->panel_fixed_mode = diff-tree 258e1cf70345198209e6d49a428efc3de8ce8238 (from e7b97f552390319d817595da8accefbe56199346) Author: Jesse Barnes <jb...@ho...> Date: Thu Apr 12 08:56:34 2007 -0700 Whitespace cleanup diff --git a/linux-core/drm_modes.c b/linux-core/drm_modes.c index 14c7acd..df34fc2 100644 --- a/linux-core/drm_modes.c +++ b/linux-core/drm_modes.c @@ -146,7 +146,8 @@ EXPORT_SYMBOL(drm_mode_set_crtcinfo); * Just allocate a new mode, copy the existing mode into it, and return * a pointer to it. Used to create new instances of established modes. */ -struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, struct drm_display_mode *mode) +struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, + struct drm_display_mode *mode) { struct drm_display_mode *nmode; int new_id; diff-tree e7b97f552390319d817595da8accefbe56199346 (from parents) Merge: f2e3d790ac05b2792e795f47fee32fe896a096cc cf016891435a0aa74dc4909ed4125c7ed906b7d1 Author: Jesse Barnes <jb...@ho...> Date: Thu Apr 12 08:55:51 2007 -0700 Merge branch 'modesetting-101' of git+ssh://git.freedesktop.org/git/mesa/drm into origin/modesetting-101 diff-tree f2e3d790ac05b2792e795f47fee32fe896a096cc (from e8bd9fdf31bf3db91431b69ce1fc8d419148c838) Author: Jesse Barnes <jb...@ho...> Date: Thu Apr 12 08:53:03 2007 -0700 Revert "Export drm_setup for use by new driver init code.", we don't really want to use this function This reverts commit e114b981bc291049fa6996d487334a408acc1ce2. diff --git a/linux-core/drm_fops.c b/linux-core/drm_fops.c index 6f0465f..d400a4d 100644 --- a/linux-core/drm_fops.c +++ b/linux-core/drm_fops.c @@ -41,7 +41,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t * dev); -int drm_setup(drm_device_t * dev) +static int drm_setup(drm_device_t * dev) { drm_local_map_t *map; int i; @@ -121,7 +121,6 @@ int drm_setup(drm_device_t * dev) return 0; } -EXPORT_SYMBOL(drm_setup); /** * Open file. diff-tree e8bd9fdf31bf3db91431b69ce1fc8d419148c838 (from parents) Merge: 0430a80fc7861a3397a3f2649dfeb9eff14359a5 b1f0fd6dfbd1495aa08c6358e936582eeca042c8 Author: Jesse Barnes <jb...@ho...> Date: Wed Apr 11 20:41:54 2007 -0700 Merge branch 'modesetting-101' of git+ssh://git.freedesktop.org/git/mesa/drm into origin/modesetting-101 diff-tree 0430a80fc7861a3397a3f2649dfeb9eff14359a5 (from 9d7160c43a7475b9d2ab06c5c353acb9456efa12) Author: Jesse Barnes <jb...@ho...> Date: Wed Apr 11 20:41:27 2007 -0700 Remove debug statement about buffer objects diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index b942b70..7616b33 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -193,8 +193,6 @@ int i915_driver_load(drm_device_t *dev, 0, PAGE_SIZE, 0, &entry); - DRM_DEBUG("allocated bo, start: 0x%lx, offset: 0x%lx\n", - entry->buffer_start, entry->offset); intel_modeset_init(dev); fb = drm_framebuffer_create(dev); |
From: <ai...@ke...> - 2007-04-18 04:50:38
|
libdrm/xf86drm.c | 14 +++++++------- linux-core/drm_bo.c | 45 +++++++++++++++++---------------------------- shared-core/via_dma.c | 6 ++++-- 3 files changed, 28 insertions(+), 37 deletions(-) New commits: diff-tree e46e028bd21552331ca4db409c2b45e54491ced6 (from parents) Merge: c71c44bb9288e0bf1b319ec19a2e25f4467d9583 5a96d59ce9d9ad5816e2d0e195afa9902445f594 Author: Dave Airlie <airlied@airlied2.(none)> Date: Wed Apr 18 14:11:49 2007 +1000 Merge branch 'origin' into modesetting-101 Conflicts: linux-core/drm_bo.c Merge in changes from master from Thomas fixiing TTM problems diff --cc linux-core/drm_bo.c index d6dce10,450e448..27016d8 @@@ -1684,9 -1665,11 +1680,12 @@@ rep.ret = 0; switch (req->op) { case drm_bo_create: + rep.ret = drm_bo_lock_test(dev, filp); + if (rep.ret) + break; rep.ret = - drm_buffer_object_create(priv, req->size, + drm_buffer_object_create(priv->head->dev, + req->size, req->type, req->mask, req->hint, @@@ -1735,17 -1718,8 +1734,7 @@@ drm_buffer_type, &uo); if (rep.ret) break; - mutex_lock(&dev->struct_mutex); - uo = drm_lookup_user_object(priv, req->handle); - entry = - drm_user_object_entry(uo, drm_buffer_object_t, - base); - /* I don't think this is needed - D.A. */ - // atomic_dec(&entry->usage); - mutex_unlock(&dev->struct_mutex); - mutex_lock(&entry->mutex); - drm_bo_fill_rep_arg(entry, &rep); - mutex_unlock(&entry->mutex); - + rep.ret = drm_bo_handle_info(priv, req->handle, &rep); break; case drm_bo_unreference: rep.ret = drm_user_object_unref(priv, req->handle, diff-tree 5a96d59ce9d9ad5816e2d0e195afa9902445f594 (from 5432cc4abf672ed3adb10fd5d61a6a5716089a98) Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Tue Apr 17 14:15:37 2007 +0200 Don't always free up memory space when we unpin buffers. diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 88adfc9..450e448 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1399,7 +1399,10 @@ static int drm_buffer_object_validate(dr } else if (bo->pinned_node != NULL) { mutex_lock(&dev->struct_mutex); - drm_mm_put_block(bo->pinned_node); + + if (bo->pinned_node != bo->mem.mm_node) + drm_mm_put_block(bo->pinned_node); + list_del_init(&bo->pinned_lru); bo->pinned_node = NULL; mutex_unlock(&dev->struct_mutex); diff-tree 5432cc4abf672ed3adb10fd5d61a6a5716089a98 (from e805ca959dbef85ac7b508639a64832a7995703a) Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Tue Apr 17 10:53:19 2007 +0200 Fix buffer object reference problems. (Reported by Dave Airlie). diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 4ecfb79..88adfc9 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1716,22 +1716,7 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS) if (rep.ret) break; - /* - * Note: The following code is only to - * fill in the rep argument. drm_lookup_user_object ups the - * refcount which is decreased again when we're done with the bo. - */ - - mutex_lock(&dev->struct_mutex); - uo = drm_lookup_user_object(priv, req->handle); - entry = - drm_user_object_entry(uo, drm_buffer_object_t, - base); - atomic_dec(&entry->usage); - mutex_unlock(&dev->struct_mutex); - mutex_lock(&entry->mutex); - drm_bo_fill_rep_arg(entry, &rep); - mutex_unlock(&entry->mutex); + rep.ret = drm_bo_handle_info(priv, req->handle, &rep); break; case drm_bo_unreference: rep.ret = drm_user_object_unref(priv, req->handle, diff-tree e805ca959dbef85ac7b508639a64832a7995703a (from e91ceff6c98661bfae5db008e024b71a8a0f5129) Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Tue Apr 17 08:58:23 2007 +0200 via: Make sure we flush write-combining using a follow-up read. diff --git a/shared-core/via_dma.c b/shared-core/via_dma.c index 8c5a5c6..c73634e 100644 --- a/shared-core/via_dma.c +++ b/shared-core/via_dma.c @@ -430,8 +430,10 @@ static int via_hook_segment(drm_via_priv paused = 0; via_flush_write_combine(); - *dev_priv->last_pause_ptr = pause_addr_lo; + (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); + *paused_at = pause_addr_lo; via_flush_write_combine(); + (void) *paused_at; reader = *(dev_priv->hw_addr_ptr); ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; @@ -536,7 +538,7 @@ static void via_cmdbuf_start(drm_via_pri &pause_addr_hi, & pause_addr_lo, 1) - 1; via_flush_write_combine(); - while(! *dev_priv->last_pause_ptr); + (void) *(volatile uint32_t *)dev_priv->last_pause_ptr; VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); VIA_WRITE(VIA_REG_TRANSPACE, command); diff-tree e91ceff6c98661bfae5db008e024b71a8a0f5129 (from e6e4946c82ab6f63143df7f49f38fa56f7e8980a) Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Tue Apr 17 08:46:45 2007 +0200 Add a code comment. diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index b08700a..4ecfb79 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1715,6 +1715,13 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS) drm_buffer_type, &uo); if (rep.ret) break; + + /* + * Note: The following code is only to + * fill in the rep argument. drm_lookup_user_object ups the + * refcount which is decreased again when we're done with the bo. + */ + mutex_lock(&dev->struct_mutex); uo = drm_lookup_user_object(priv, req->handle); entry = diff-tree e6e4946c82ab6f63143df7f49f38fa56f7e8980a (from 9b7211dd6793dc62d11ad1ae980b22fa2d61f9dd) Author: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> Date: Mon Apr 16 16:23:05 2007 +0200 Require the hardware lock for buffer creation (since that implies a validate). Fix drm_bo_wait_unfenced error messages and codes. Fix some return codes from libdrm. diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index a815ed7..2473162 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2814,7 +2814,7 @@ int drmBOMap(int fd, drmBO *buf, unsigne } while (ret != 0 && errno == EAGAIN); if (ret) - return ret; + return -errno; if (!arg.handled) return -EFAULT; if (rep->ret) @@ -2870,7 +2870,7 @@ int drmBOValidate(int fd, drmBO *buf, un } while (ret && errno == EAGAIN); if (ret) - return ret; + return -errno; if (!arg.handled) return -EFAULT; if (rep->ret) @@ -2897,7 +2897,7 @@ int drmBOFence(int fd, drmBO *buf, unsig ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); if (ret) - return ret; + return -errno; if (!arg.handled) return -EFAULT; if (rep->ret) @@ -2919,7 +2919,7 @@ int drmBOInfo(int fd, drmBO *buf) ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg); if (ret) - return ret; + return -errno; if (!arg.handled) return -EFAULT; if (rep->ret) @@ -2947,7 +2947,7 @@ int drmBOWaitIdle(int fd, drmBO *buf, un } while (ret && errno == EAGAIN); if (ret) - return ret; + return -errno; if (!arg.handled) return -EFAULT; if (rep->ret) @@ -3199,7 +3199,7 @@ int drmMMLock(int fd, unsigned memType) ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg); } while (ret && errno == EAGAIN); - return ret; + return -errno; } int drmMMUnlock(int fd, unsigned memType) @@ -3215,7 +3215,7 @@ int drmMMUnlock(int fd, unsigned memType ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg); } while (ret && errno == EAGAIN); - return ret; + return -errno; } #define DRM_MAX_FDS 16 diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 17d6fbc..b08700a 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1024,30 +1024,23 @@ static int drm_bo_wait_unfenced(drm_buff int eagain_if_wait) { int ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED); - unsigned long _end = jiffies + 3 * DRM_HZ; if (ret && no_wait) return -EBUSY; else if (!ret) return 0; - do { - mutex_unlock(&bo->mutex); - DRM_WAIT_ON(ret, bo->event_queue, 3 * DRM_HZ, - !drm_bo_check_unfenced(bo)); - mutex_lock(&bo->mutex); - if (ret == -EINTR) - return -EAGAIN; - if (ret) { - DRM_ERROR - ("Error waiting for buffer to become fenced\n"); - return ret; - } - ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED); - } while (ret && !time_after_eq(jiffies, _end)); + ret = 0; + mutex_unlock(&bo->mutex); + DRM_WAIT_ON(ret, bo->event_queue, 3 * DRM_HZ, + !drm_bo_check_unfenced(bo)); + mutex_lock(&bo->mutex); + if (ret == -EINTR) + return -EAGAIN; + ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED); if (ret) { DRM_ERROR("Timeout waiting for buffer to become fenced\n"); - return ret; + return -EBUSY; } if (eagain_if_wait) return -EAGAIN; @@ -1669,6 +1662,9 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS) rep.ret = 0; switch (req->op) { case drm_bo_create: + rep.ret = drm_bo_lock_test(dev, filp); + if (rep.ret) + break; rep.ret = drm_buffer_object_create(priv, req->size, req->type, |
From: <al...@ke...> - 2007-11-05 10:22:46
|
libdrm/xf86drmMode.c | 4 ++-- linux-core/drm_compat.h | 2 +- linux-core/drm_crtc.c | 1 + linux-core/drm_drv.c | 7 ------- linux-core/drm_objects.h | 1 - 5 files changed, 4 insertions(+), 11 deletions(-) New commits: commit 1b91113957e731d264d1e5d49326597f3b78e96f Author: Alan Hourihane <al...@tu...> Date: Mon Nov 5 10:06:37 2007 +0000 remove unused define diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index 01876d9..bbce2ea 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -157,7 +157,6 @@ struct drm_fence_object { }; #define _DRM_FENCE_CLASSES 8 -#define _DRM_FENCE_TYPE_EXE 0x00 struct drm_fence_class_manager { struct list_head ring; commit 306bb12603ad724f50fb6ce212a090ea7ea78013 Author: Alan Hourihane <al...@tu...> Date: Mon Nov 5 10:05:01 2007 +0000 remove duplicate and obsolete ioctl statements diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 1c9895e..e46e8d9 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -116,9 +116,6 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), - // DRM_IOCTL_DEF(DRM_IOCTL_BUFOBJ, drm_bo_ioctl, DRM_AUTH), - DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl, - DRM_AUTH ), DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY), @@ -131,10 +128,6 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode, DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode, DRM_MASTER|DRM_ROOT_ONLY), - // DRM_IOCTL_DEF(DRM_IOCTL_BUFOBJ, drm_bo_ioctl, DRM_AUTH), - - DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), commit 71385d6f75bb3b551e2f8d9f74a4438f0f3da9df Author: Alan Hourihane <al...@tu...> Date: Mon Nov 5 10:03:26 2007 +0000 add missing lock diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 5bc0220..cad7cd8 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1575,6 +1575,7 @@ int drm_mode_rmfb(struct drm_device *dev, uint32_t *id = data; int ret = 0; + mutex_lock(&dev->mode_config.mutex); fb = idr_find(&dev->mode_config.crtc_idr, *id); /* TODO check that we realy get a framebuffer back. */ if (!fb || (*id != fb->id)) { commit d0956339e322238d2af5d63a2e65405ca3b8c4f8 Author: Alan Hourihane <al...@tu...> Date: Mon Nov 5 10:02:46 2007 +0000 Use _size diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h index 0895e5e..f861abf 100644 --- a/linux-core/drm_compat.h +++ b/linux-core/drm_compat.h @@ -159,7 +159,7 @@ static __inline__ void *kcalloc(size_t nmemb, size_t size, int flags) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) #define vmalloc_user(_size) ({void * tmp = vmalloc(_size); \ - if (tmp) memset(tmp, 0, size); \ + if (tmp) memset(tmp, 0, _size); \ (tmp);}) #endif commit 0bee83a8c8bca817459a0ee9caa6e13f3f1aa281 Author: Alan Hourihane <al...@tu...> Date: Mon Nov 5 10:00:43 2007 +0000 Pass pointer to drmModeRmMode. diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index cfe133f..e7ac58b 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -368,7 +368,7 @@ uint32_t drmModeAddMode(int fd, struct drm_mode_modeinfo *mode_info) int drmModeRmMode(int fd, uint32_t mode_id) { - return ioctl(fd, DRM_IOCTL_MODE_RMMODE, mode_id); + return ioctl(fd, DRM_IOCTL_MODE_RMMODE, &mode_id); } int drmModeAttachMode(int fd, uint32_t output_id, uint32_t mode_id) commit 5e86f67a34c50ec49e1d7b3b834d1695ebf5d4c8 Author: Alan Hourihane <al...@tu...> Date: Mon Nov 5 10:00:11 2007 +0000 pass pointer for drmModeRmFB diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index a7241ff..cfe133f 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -212,7 +212,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, int drmModeRmFB(int fd, uint32_t bufferId) { - return ioctl(fd, DRM_IOCTL_MODE_RMFB, bufferId); + return ioctl(fd, DRM_IOCTL_MODE_RMFB, &bufferId); } drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) |
From: <gl...@ke...> - 2007-12-07 23:49:35
|
linux-core/Makefile | 4 linux-core/Makefile.kernel | 8 linux-core/radeon_ms.h | 1 linux-core/radeon_ms_bo.c | 1 linux-core/radeon_ms_bus.c | 1 linux-core/radeon_ms_compat.c | 67 + linux-core/radeon_ms_cp.c | 1 linux-core/radeon_ms_cp_mc.c | 1 linux-core/radeon_ms_crtc.c | 1 linux-core/radeon_ms_dac.c | 1 linux-core/radeon_ms_drm.c | 1 linux-core/radeon_ms_drm.h | 1 linux-core/radeon_ms_drv.c | 146 +++ linux-core/radeon_ms_drv.h | 45 + linux-core/radeon_ms_exec.c | 1 linux-core/radeon_ms_family.c | 1 linux-core/radeon_ms_fb.c | 457 +++++++++++ linux-core/radeon_ms_fence.c | 1 linux-core/radeon_ms_gpu.c | 1 linux-core/radeon_ms_i2c.c | 1 linux-core/radeon_ms_irq.c | 1 linux-core/radeon_ms_output.c | 1 linux-core/radeon_ms_reg.h | 1 linux-core/radeon_ms_state.c | 1 shared-core/drm_pciids.txt | 4 shared-core/radeon_ms.h | 607 +++++++++++++++ shared-core/radeon_ms_bo.c | 311 +++++++ shared-core/radeon_ms_bus.c | 453 +++++++++++ shared-core/radeon_ms_cp.c | 345 ++++++++ shared-core/radeon_ms_cp_mc.c | 801 +++++++++++++++++++ shared-core/radeon_ms_crtc.c | 800 +++++++++++++++++++ shared-core/radeon_ms_dac.c | 400 +++++++++ shared-core/radeon_ms_drm.c | 298 +++++++ shared-core/radeon_ms_drm.h | 60 + shared-core/radeon_ms_exec.c | 242 +++++ shared-core/radeon_ms_family.c | 229 +++++ shared-core/radeon_ms_fence.c | 129 +++ shared-core/radeon_ms_gpu.c | 589 ++++++++++++++ shared-core/radeon_ms_i2c.c | 279 ++++++ shared-core/radeon_ms_irq.c | 160 +++ shared-core/radeon_ms_output.c | 337 ++++++++ shared-core/radeon_ms_reg.h | 1655 +++++++++++++++++++++++++++++++++++++++++ shared-core/radeon_ms_state.c | 45 + 43 files changed, 8488 insertions(+), 1 deletion(-) New commits: commit 9d064966d8495038921d0e731c0bfca0cd58d244 Author: Jerome Glisse <gl...@fr...> Date: Sat Dec 8 00:45:33 2007 +0100 radeon_ms: fix pll computation to follow hw constraint diff --git a/shared-core/radeon_ms_crtc.c b/shared-core/radeon_ms_crtc.c index a9387f9..fe89e5e 100644 --- a/shared-core/radeon_ms_crtc.c +++ b/shared-core/radeon_ms_crtc.c @@ -379,13 +379,26 @@ static void radeon_ms_crtc_mode_prepare(struct drm_crtc *crtc) crtc->funcs->dpms(crtc, DPMSModeOff); } -/* Compute n/d with rounding */ -static int radeon_div(int n, int d) +/* compute PLL registers values for requested video mode */ +static int radeon_pll1_constraint(int clock, int rdiv, + int fdiv, int pdiv, + int rfrq, int pfrq) { - return (n + (d / 2)) / d; + int dfrq; + + if (rdiv < 2 || fdiv < 4) { + return 0; + } + dfrq = rfrq / rdiv; + if (dfrq < 2000 || dfrq > 3300) { + return 0; + } + if (pfrq < 125000 || pfrq > 250000) { + return 0; + } + return 1; } -/* compute PLL registers values for requested video mode */ static void radeon_pll1_compute(struct drm_crtc *crtc, struct drm_display_mode *mode) { @@ -410,65 +423,73 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, }; struct drm_radeon_private *dev_priv = crtc->dev->dev_private; struct radeon_state *state = &dev_priv->driver_state; - unsigned long freq = mode->clock / 10; - int pll_output_freq; - int min_rcenter_dist; - int rcenter_dist; - int post_divider; - int post_divider_id; - int ref_div; - int fb_div; + int clock = mode->clock; + int rfrq = dev_priv->properties->pll_reference_freq; + int pdiv = 1; + int pdiv_id = 0; + int rdiv_best = 2; + int fdiv_best = 4; + int tfrq_best = 0; + int pfrq_best = 0; + int diff_cpfrq_best = 350000; int vco_freq; int vco_gain; + int rdiv = 0; + int fdiv = 0; + int tfrq = 35000; + int pfrq = 35000; + int diff_cpfrq = 350000; /* clamp frequency into pll [min; max] frequency range */ - if (freq > dev_priv->properties->pll_max_pll_freq) { - freq = dev_priv->properties->pll_max_pll_freq; + if (clock > dev_priv->properties->pll_max_pll_freq) { + clock = dev_priv->properties->pll_max_pll_freq; } - if (freq < dev_priv->properties->pll_min_pll_freq) { - freq = dev_priv->properties->pll_min_pll_freq; + if ((clock * 12) < dev_priv->properties->pll_min_pll_freq) { + clock = dev_priv->properties->pll_min_pll_freq / 12; } - /* select divider so that pll output frequency is the nearest to - * the center of [350; 125]Mhz range */ - min_rcenter_dist = 350 * 100; - post_divider = post_divs[0].divider; - post_divider_id = post_divs[0].divider_id; + + /* maximize pll_ref_div while staying in boundary and minimizing + * the difference btw target frequency and programmed frequency */ for (post_div = &post_divs[0]; post_div->divider; ++post_div) { - if (post_div->divider == 0) + if (post_div->divider == 0) { break; - /* pll output frequency (before post divider) */ - pll_output_freq = post_div->divider * freq; - /* compute distance to [350; 125] range center*/ - rcenter_dist = abs(pll_output_freq - 11250); - if (rcenter_dist < min_rcenter_dist) { - min_rcenter_dist = rcenter_dist; - post_divider = post_div->divider; - post_divider_id = post_div->divider_id; + } + tfrq = clock * post_div->divider; + for (fdiv = 1023; fdiv >= 4; fdiv--) { + rdiv = (fdiv * rfrq) / tfrq; + if (radeon_pll1_constraint(clock, rdiv, fdiv, + pdiv, rfrq, tfrq)) { + pfrq = (fdiv * rfrq) / rdiv; + diff_cpfrq = pfrq - tfrq; + if ((diff_cpfrq >= 0 && + diff_cpfrq < diff_cpfrq_best) || + (diff_cpfrq == diff_cpfrq_best && + rdiv > rdiv_best)) { + rdiv_best = rdiv; + fdiv_best = fdiv; + tfrq_best = tfrq; + pfrq_best = pfrq; + pdiv = post_div->divider; + pdiv_id = post_div->divider_id; + diff_cpfrq_best = diff_cpfrq; + } + } } } - pll_output_freq = post_divider * freq; - /* select first feedback */ - state->clock_cntl_index = REG_S(CLOCK_CNTL_INDEX, PPLL_DIV_SEL, 0); - /* set ref div so that ref_freq/ref_div is in middle of [2; 3.3]Mhz */ - ref_div = dev_priv->properties->pll_reference_freq / 265; - state->ppll_ref_div = REG_S(PPLL_REF_DIV, PPLL_REF_DIV, ref_div) | - REG_S(PPLL_REF_DIV, PPLL_REF_DIV_ACC, ref_div); - fb_div = radeon_div(pll_output_freq * ref_div, - dev_priv->properties->pll_reference_freq); - state->ppll_div_0 = REG_S(PPLL_DIV_0, PPLL_FB0_DIV, fb_div) | - REG_S(PPLL_DIV_0, PPLL_POST0_DIV, post_divider_id); - /* configure vco gain */ - state->ppll_cntl = PPLL_R(PPLL_CNTL); - vco_gain = REG_G(PPLL_CNTL, PPLL_PVG, state->ppll_cntl); - vco_freq = (fb_div * dev_priv->properties->pll_reference_freq) / - ref_div; + state->ppll_ref_div = + REG_S(PPLL_REF_DIV, PPLL_REF_DIV, rdiv_best) | + REG_S(PPLL_REF_DIV, PPLL_REF_DIV_ACC, rdiv_best); + state->ppll_div_0 = REG_S(PPLL_DIV_0, PPLL_FB0_DIV, fdiv_best) | + REG_S(PPLL_DIV_0, PPLL_POST0_DIV, pdiv_id); + + vco_freq = (fdiv_best * rfrq) / rdiv_best; /* This is horribly crude: the VCO frequency range is divided into * 3 parts, each part having a fixed PLL gain value. */ - if (vco_freq >= 30000) { + if (vco_freq >= 300000) { /* [300..max] MHz : 7 */ vco_gain = 7; - } else if (vco_freq >= 18000) { + } else if (vco_freq >= 180000) { /* [180..300) MHz : 4 */ vco_gain = 4; } else { @@ -479,6 +500,16 @@ static void radeon_pll1_compute(struct drm_crtc *crtc, state->vclk_ecp_cntl |= REG_S(VCLK_ECP_CNTL, VCLK_SRC_SEL, VCLK_SRC_SEL__PPLLCLK); state->htotal_cntl = 0; + DRM_INFO("rdiv: %d\n", rdiv_best); + DRM_INFO("fdiv: %d\n", fdiv_best); + DRM_INFO("pdiv: %d\n", pdiv); + DRM_INFO("pdiv: %d\n", pdiv_id); + DRM_INFO("tfrq: %d\n", tfrq_best); + DRM_INFO("pfrq: %d\n", pfrq_best); + DRM_INFO("PPLL_REF_DIV: 0x%08X\n", state->ppll_ref_div); + DRM_INFO("PPLL_DIV_0: 0x%08X\n", state->ppll_div_0); + DRM_INFO("PPLL_CNTL: 0x%08X\n", state->ppll_cntl); + DRM_INFO("VCLK_ECP_CNTL: 0x%08X\n", state->vclk_ecp_cntl); } static void radeon_ms_crtc1_mode_set(struct drm_crtc *crtc, diff --git a/shared-core/radeon_ms_family.c b/shared-core/radeon_ms_family.c index ea5f6ca..779595d 100644 --- a/shared-core/radeon_ms_family.c +++ b/shared-core/radeon_ms_family.c @@ -76,7 +76,7 @@ static struct radeon_ms_connector radeon_ms_dvi_i_2 = { static struct radeon_ms_properties properties[] = { /* default only one VGA connector */ { - 0, 0, 2700, 2500, 20000, 1, 1, 1, 1, + 0, 0, 27000, 25000, 200000, 1, 1, 1, 1, { &radeon_ms_dac1, NULL, NULL, NULL, NULL, NULL, NULL, NULL @@ -87,7 +87,7 @@ static struct radeon_ms_properties properties[] = { } }, { - 0x1043, 0x176, 2700, 2500, 20000, 1, 1, 1, 1, + 0x1043, 0x176, 27000, 25000, 200000, 1, 1, 1, 1, { &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, NULL, NULL, NULL @@ -98,7 +98,7 @@ static struct radeon_ms_properties properties[] = { } }, { - 0x1002, 0x4150, 2700, 2500, 20000, 1, 1, 1, 1, + 0x1002, 0x4150, 27000, 25000, 200000, 1, 1, 1, 1, { &radeon_ms_dac1, &radeon_ms_dac2, NULL, NULL, NULL, NULL, NULL, NULL commit a693e8ab12432787a3c02fa5b8f7649a08122012 Author: Jerome Glisse <gl...@fr...> Date: Thu Dec 6 23:36:58 2007 +0100 radeon_ms: fix fbcon by fixing palette diff --git a/linux-core/radeon_ms_fb.c b/linux-core/radeon_ms_fb.c index b629b9e..fc9e99e 100644 --- a/linux-core/radeon_ms_fb.c +++ b/linux-core/radeon_ms_fb.c @@ -52,12 +52,35 @@ static int radeonfb_setcolreg(unsigned regno, unsigned red, unsigned transp, struct fb_info *info) { struct radeonfb_par *par = info->par; + struct drm_framebuffer *fb = par->crtc->fb; struct drm_crtc *crtc = par->crtc; - if (regno > 255) + if (regno > 255) { return 1; - if (crtc->funcs->gamma_set) + } + if (crtc->funcs->gamma_set) { crtc->funcs->gamma_set(crtc, red, green, blue, regno); + } + if (regno < 16) { + switch (fb->depth) { + case 15: + fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | + ((green & 0xf800) >> 6) | + ((blue & 0xf800) >> 11); + break; + case 16: + fb->pseudo_palette[regno] = (red & 0xf800) | + ((green & 0xfc00) >> 5) | + ((blue & 0xf800) >> 11); + break; + case 24: + case 32: + fb->pseudo_palette[regno] = ((red & 0xff00) << 8) | + (green & 0xff00) | + ((blue & 0xff00) >> 8); + break; + } + } return 0; } commit a39560e767f8d66508f7cf98222199b2cc96fcaf Author: Jerome Glisse <gl...@fr...> Date: Thu Dec 6 23:19:52 2007 +0100 radeon_ms: update to lastest fb change diff --git a/linux-core/radeon_ms_fb.c b/linux-core/radeon_ms_fb.c index ef7c5cf..b629b9e 100644 --- a/linux-core/radeon_ms_fb.c +++ b/linux-core/radeon_ms_fb.c @@ -42,8 +42,9 @@ #include "radeon_ms.h" struct radeonfb_par { - struct drm_device *dev; - struct drm_crtc *crtc; + struct drm_device *dev; + struct drm_crtc *crtc; + struct drm_display_mode *fb_mode; }; static int radeonfb_setcolreg(unsigned regno, unsigned red, @@ -127,13 +128,38 @@ static int radeonfb_check_var(struct fb_var_screeninfo *var, return 0; } +static bool radeonfb_mode_equal(struct drm_display_mode *mode1, + struct drm_display_mode *mode2) +{ + if (mode1->hdisplay == mode2->hdisplay && + mode1->hsync_start == mode2->hsync_start && + mode1->hsync_end == mode2->hsync_end && + mode1->htotal == mode2->htotal && + mode1->hskew == mode2->hskew && + mode1->vdisplay == mode2->vdisplay && + mode1->vsync_start == mode2->vsync_start && + mode1->vsync_end == mode2->vsync_end && + mode1->vtotal == mode2->vtotal && + mode1->vscan == mode2->vscan && + mode1->flags == mode2->flags) { + /* FIXME: what about adding a margin for clock ? */ + if (mode1->clock == mode2->clock) + return true; + return false; + } + + return false; +} + static int radeonfb_set_par(struct fb_info *info) { struct radeonfb_par *par = info->par; struct drm_framebuffer *fb = par->crtc->fb; struct drm_device *dev = par->dev; - struct drm_display_mode *drm_mode; + struct drm_display_mode *drm_mode, *search_mode; + struct drm_output *output; struct fb_var_screeninfo *var = &info->var; + int found = 0; switch (var->bits_per_pixel) { case 16: @@ -171,15 +197,39 @@ static int radeonfb_set_par(struct fb_info *info) drm_mode_set_name(drm_mode); drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V); - drm_mode_debug_printmodeline(dev, drm_mode); + list_for_each_entry(output, &dev->mode_config.output_list, head) { + if (output->crtc == par->crtc) + break; + } - if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0)) - return -EINVAL; + drm_mode_debug_printmodeline(dev, drm_mode); + list_for_each_entry(search_mode, &output->modes, head) { + drm_mode_debug_printmodeline(dev, search_mode); + if (radeonfb_mode_equal(drm_mode, search_mode)) { + drm_mode_destroy(dev, drm_mode); + drm_mode = search_mode; + found = 1; + break; + } + } - /* Have to destroy our created mode if we're not searching the mode - * list for it. - */ - drm_mode_destroy(dev, drm_mode); + if (!found) { + if (par->fb_mode) { + drm_mode_detachmode_crtc(dev, par->fb_mode); + } + par->fb_mode = drm_mode; + drm_mode_debug_printmodeline(dev, drm_mode); + /* attach mode */ + drm_mode_attachmode_crtc(dev, par->crtc, par->fb_mode); + } + + if (par->crtc->enabled) { + if (!drm_mode_equal(&par->crtc->mode, drm_mode)) { + if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0)) { + return -EINVAL; + } + } + } return 0; } diff --git a/shared-core/radeon_ms_output.c b/shared-core/radeon_ms_output.c index 4d6cb01..35e5c37 100644 --- a/shared-core/radeon_ms_output.c +++ b/shared-core/radeon_ms_output.c @@ -164,6 +164,10 @@ static int radeon_ms_output_get_modes(struct drm_output *output) if (connector == NULL || connector->i2c == NULL) { return 0; } + if (connector->edid == NULL) { + return 0; + } + drm_mode_output_update_edid_property(output, connector->edid); ret = drm_add_edid_modes(output, connector->edid); kfree(connector->edid); connector->edid = NULL; commit 931b4a84a09e29570dfef1da96acc5b894529bc3 Merge: 3a51a80... 9814e87... Author: Jerome Glisse <gl...@fr...> Date: Thu Dec 6 22:42:17 2007 +0100 Merge commit 'origin/modesetting-101' into modesetting-radeon commit 3a51a8077bf55ba9d18805f2f03b78eb980fa982 Author: Jerome Glisse <gl...@fr...> Date: Thu Dec 6 22:38:44 2007 +0100 radeon_ms: avoid to unintialize things which haven't been initialized diff --git a/shared-core/radeon_ms_bus.c b/shared-core/radeon_ms_bus.c index 6a782b1..d50c9fb 100644 --- a/shared-core/radeon_ms_bus.c +++ b/shared-core/radeon_ms_bus.c @@ -205,6 +205,12 @@ static int pcie_ttm_unbind(struct drm_ttm_backend *backend) int radeon_ms_agp_finish(struct drm_device *dev) { + struct drm_radeon_private *dev_priv = dev->dev_private; + + if (!dev_priv->bus_ready) { + return 0; + } + dev_priv->bus_ready = 0; drm_agp_release(dev); return 0; } @@ -217,6 +223,7 @@ int radeon_ms_agp_init(struct drm_device *dev) uint32_t agp_status; int ret; + dev_priv->bus_ready = -1; if (dev->agp == NULL) { DRM_ERROR("[radeon_ms] can't initialize AGP\n"); return -EINVAL; @@ -256,6 +263,7 @@ int radeon_ms_agp_init(struct drm_device *dev) DRM_INFO("[radeon_ms] gpu agp location 0x%08X\n", state->mc_agp_location); DRM_INFO("[radeon_ms] bus ready\n"); + dev_priv->bus_ready = 1; return 0; } @@ -328,6 +336,7 @@ int radeon_ms_pcie_init(struct drm_device *dev) struct radeon_pcie *pcie; int ret = 0; + dev_priv->bus_ready = -1; /* allocate and clear device private structure */ pcie = drm_alloc(sizeof(struct radeon_pcie), DRM_MEM_DRIVER); if (pcie == NULL) { @@ -401,6 +410,7 @@ int radeon_ms_pcie_init(struct drm_device *dev) DRM_INFO("[radeon_ms] gpu gart end 0x%08X\n", PCIE_R(PCIE_TX_GART_END_LO)); DRM_INFO("[radeon_ms] bus ready\n"); + dev_priv->bus_ready = 1; return 0; } diff --git a/shared-core/radeon_ms_cp.c b/shared-core/radeon_ms_cp.c index 7426fac..c01769b 100644 --- a/shared-core/radeon_ms_cp.c +++ b/shared-core/radeon_ms_cp.c @@ -101,6 +101,9 @@ int radeon_ms_cp_finish(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; + if (!dev_priv->cp_ready) { + return 0; + } dev_priv->cp_ready = 0; radeon_ms_wait_for_idle(dev); DRM_INFO("[radeon_ms] cp idle\n"); @@ -126,6 +129,7 @@ int radeon_ms_cp_init(struct drm_device *dev) struct radeon_state *state = &dev_priv->driver_state; int ret = 0; + dev_priv->cp_ready = -1; if (dev_priv->microcode == NULL) { DRM_INFO("[radeon_ms] no microcode not starting cp"); return 0; diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c index b22c83a..8d0481e 100644 --- a/shared-core/radeon_ms_drm.c +++ b/shared-core/radeon_ms_drm.c @@ -173,7 +173,6 @@ int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags) return ret; } radeon_ms_gpu_restore(dev, &dev_priv->driver_state); - dev_priv->bus_ready = 1; /* initialize ttm */ ret = drm_bo_init_mm(dev, DRM_BO_MEM_TT, 0, diff --git a/shared-core/radeon_ms_fence.c b/shared-core/radeon_ms_fence.c index 96bb085..6fcf543 100644 --- a/shared-core/radeon_ms_fence.c +++ b/shared-core/radeon_ms_fence.c @@ -54,7 +54,7 @@ int radeon_ms_fence_emit_sequence(struct drm_device *dev, uint32_t class, struct drm_radeon_private *dev_priv = dev->dev_private; uint32_t fence_id, cmd[2], i, ret; - if (!dev_priv || !dev_priv->cp_ready) { + if (!dev_priv || dev_priv->cp_ready != 1) { return -EINVAL; } fence_id = (++dev_priv->fence_id_last); commit 34797ff67c16beb9c331920f663bdf8387c14c78 Author: Jerome Glisse <gl...@fr...> Date: Sun Dec 2 23:48:45 2007 +0100 radeon_ms: radeon modesetting first commit. This should work on all radeon but there is still many things todo: - add crtc2 - tmds - lvds - add bios data table so we don't need to hardcode dac/crtc infos - separate clock control to make power saving easier & cleaner - tiling (warning tiling shouldn't be enable in double scan or interlace) - surface reg manager (this goes along with tiling) - suspend/resume hook - avivo & r500 family support - atom bios support (for posting card mostly) - finish superioctl skeleton - what else ? :) diff --git a/linux-core/Makefile b/linux-core/Makefile index 7f6b123..76ed3e3 100644 --- a/linux-core/Makefile +++ b/linux-core/Makefile @@ -58,7 +58,7 @@ endif # Modules for all architectures MODULE_LIST := drm.o tdfx.o r128.o radeon.o mga.o sis.o savage.o via.o \ - mach64.o nv.o nouveau.o xgi.o + mach64.o nv.o nouveau.o xgi.o radeon_ms.o # Modules only for ix86 architectures ifneq (,$(findstring 86,$(MACHINE))) @@ -92,6 +92,7 @@ NVHEADERS = nv_drv.h $(DRMHEADERS) FFBHEADERS = ffb_drv.h $(DRMHEADERS) NOUVEAUHEADERS = nouveau_drv.h nouveau_drm.h nouveau_reg.h $(DRMHEADERS) XGIHEADERS = xgi_cmdlist.h xgi_drv.h xgi_misc.h xgi_regs.h $(DRMHEADERS) +RADEONMSHEADERS = radeon_ms_driver.h $(DRMHEADERS) PROGS = dristat drmstat @@ -286,6 +287,7 @@ CONFIG_DRM_MACH64 := n CONFIG_DRM_NV := n CONFIG_DRM_NOUVEAU := n CONFIG_DRM_XGI := n +CONFIG_DRM_RADEON_MS := m # Enable module builds for the modules requested/supported. diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 63c93f0..7ef504a 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -34,6 +34,12 @@ nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \ nv40_graph.o nv50_graph.o \ nv04_instmem.o nv50_instmem.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o radeon_fence.o radeon_buffer.o +radeon_ms-objs := radeon_ms_drv.o radeon_ms_drm.o radeon_ms_family.o \ + radeon_ms_state.o radeon_ms_bo.o radeon_ms_irq.o \ + radeon_ms_bus.o radeon_ms_fence.o \ + radeon_ms_cp.o radeon_ms_cp_mc.o radeon_ms_i2c.o \ + radeon_ms_output.o radeon_ms_crtc.o radeon_ms_fb.o \ + radeon_ms_exec.o radeon_ms_gpu.o radeon_ms_dac.o sis-objs := sis_drv.o sis_mm.o ffb-objs := ffb_drv.o ffb_context.o savage-objs := savage_drv.o savage_bci.o savage_state.o @@ -47,6 +53,7 @@ xgi-objs := xgi_cmdlist.o xgi_drv.o xgi_fb.o xgi_misc.o xgi_pcie.o \ ifeq ($(CONFIG_COMPAT),y) drm-objs += drm_ioc32.o radeon-objs += radeon_ioc32.o +radeon_ms-objs += radeon_ms_compat.o mga-objs += mga_ioc32.o r128-objs += r128_ioc32.o i915-objs += i915_ioc32.o @@ -69,3 +76,4 @@ obj-$(CONFIG_DRM_MACH64)+= mach64.o obj-$(CONFIG_DRM_NV) += nv.o obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o obj-$(CONFIG_DRM_XGI) += xgi.o +obj-$(CONFIG_DRM_RADEON_MS) += radeon_ms.o diff --git a/linux-core/radeon_ms.h b/linux-core/radeon_ms.h new file mode 120000 index 0000000..da340c5 --- /dev/null +++ b/linux-core/radeon_ms.h @@ -0,0 +1 @@ +../shared-core/radeon_ms.h \ No newline at end of file diff --git a/linux-core/radeon_ms_bo.c b/linux-core/radeon_ms_bo.c new file mode 120000 index 0000000..d05df59 --- /dev/null +++ b/linux-core/radeon_ms_bo.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_bo.c \ No newline at end of file diff --git a/linux-core/radeon_ms_bus.c b/linux-core/radeon_ms_bus.c new file mode 120000 index 0000000..50f649d --- /dev/null +++ b/linux-core/radeon_ms_bus.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_bus.c \ No newline at end of file diff --git a/linux-core/radeon_ms_compat.c b/linux-core/radeon_ms_compat.c new file mode 100644 index 0000000..6efdc78 --- /dev/null +++ b/linux-core/radeon_ms_compat.c @@ -0,0 +1,67 @@ +/* + * Copyright 2007 Dave Airlie + * Copyright 2007 Alex Deucher + * Copyright 2007 Michel Dänzer + * Copyright 2007 Roland Scheidegger + * Copyright 2007 Vladimir Dergachev + * Copyright 2007 Nicolai Haehnle + * Copyright 2007 Aapo Tahkola + * Copyright 2007 Ben Skeggs + * Copyright 2007 Jérôme Glisse + * All Rights Reserved. + * + * 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 + * PRECISION INSIGHT 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: + * Jerome Glisse <gl...@fr...> + */ +#include "drmP.h" +#include "drm.h" +#include "radeon_ms.h" + +/** + * Called whenever a 32-bit process running under a 64-bit kernel + * performs an ioctl on /dev/dri/card<n>. + + * \param filp file pointer. + * \param cmd command. + * \param arg user argument. + * \return zero on success or negative number on failure. + */ +long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + unsigned int nr = DRM_IOCTL_NR(cmd); + drm_ioctl_compat_t *fn = NULL; + int ret; + + if (nr < DRM_COMMAND_BASE) + return drm_compat_ioctl(filp, cmd, arg); + + lock_kernel(); + if (fn != NULL) + ret = (*fn)(filp, cmd, arg); + else + ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); + unlock_kernel(); + + return ret; +} diff --git a/linux-core/radeon_ms_cp.c b/linux-core/radeon_ms_cp.c new file mode 120000 index 0000000..6aee3e6 --- /dev/null +++ b/linux-core/radeon_ms_cp.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_cp.c \ No newline at end of file diff --git a/linux-core/radeon_ms_cp_mc.c b/linux-core/radeon_ms_cp_mc.c new file mode 120000 index 0000000..0ae1a64 --- /dev/null +++ b/linux-core/radeon_ms_cp_mc.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_cp_mc.c \ No newline at end of file diff --git a/linux-core/radeon_ms_crtc.c b/linux-core/radeon_ms_crtc.c new file mode 120000 index 0000000..31f1144 --- /dev/null +++ b/linux-core/radeon_ms_crtc.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_crtc.c \ No newline at end of file diff --git a/linux-core/radeon_ms_dac.c b/linux-core/radeon_ms_dac.c new file mode 120000 index 0000000..cb523cf --- /dev/null +++ b/linux-core/radeon_ms_dac.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_dac.c \ No newline at end of file diff --git a/linux-core/radeon_ms_drm.c b/linux-core/radeon_ms_drm.c new file mode 120000 index 0000000..8bbf19a --- /dev/null +++ b/linux-core/radeon_ms_drm.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_drm.c \ No newline at end of file diff --git a/linux-core/radeon_ms_drm.h b/linux-core/radeon_ms_drm.h new file mode 120000 index 0000000..5d9d731 --- /dev/null +++ b/linux-core/radeon_ms_drm.h @@ -0,0 +1 @@ +../shared-core/radeon_ms_drm.h \ No newline at end of file diff --git a/linux-core/radeon_ms_drv.c b/linux-core/radeon_ms_drv.c new file mode 100644 index 0000000..4b52a7d --- /dev/null +++ b/linux-core/radeon_ms_drv.c @@ -0,0 +1,146 @@ +/* + * Copyright 2007 Jerome Glisse. + * All Rights Reserved. + * + * 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 + * PRECISION INSIGHT 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: + * Jerome Glisse <gl...@fr...> + */ +#include "drm_pciids.h" +#include "radeon_ms.h" + +extern struct drm_fence_driver radeon_ms_fence_driver; +extern struct drm_bo_driver radeon_ms_bo_driver; +extern struct drm_ioctl_desc radeon_ms_ioctls[]; +extern int radeon_ms_num_ioctls; + +static int radeon_ms_driver_dri_library_name(struct drm_device * dev, + char * buf); +static int radeon_ms_driver_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); + +static struct pci_device_id pciidlist[] = { + radeon_ms_PCI_IDS +}; + +static struct drm_driver driver = { + .load = radeon_ms_driver_load, + .firstopen = NULL, + .open = radeon_ms_driver_open, + .preclose = NULL, + .postclose = NULL, + .lastclose = radeon_ms_driver_lastclose, + .unload = radeon_ms_driver_unload, + .dma_ioctl = radeon_ms_driver_dma_ioctl, + .dma_ready = NULL, + .dma_quiescent = NULL, + .context_ctor = NULL, + .context_dtor = NULL, + .kernel_context_switch = NULL, + .kernel_context_switch_unlock = NULL, + .vblank_wait = NULL, + .vblank_wait2 = NULL, + .dri_library_name = radeon_ms_driver_dri_library_name, + .device_is_agp = NULL, + .irq_handler = radeon_ms_irq_handler, + .irq_preinstall = radeon_ms_irq_preinstall, + .irq_postinstall = radeon_ms_irq_postinstall, + .irq_uninstall = radeon_ms_irq_uninstall, + .reclaim_buffers = drm_core_reclaim_buffers, + .reclaim_buffers_locked = NULL, + .reclaim_buffers_idlelocked = NULL, + .get_map_ofs = drm_core_get_map_ofs, + .get_reg_ofs = drm_core_get_reg_ofs, + .set_version = NULL, + .fb_probe = radeonfb_probe, + .fb_remove = radeonfb_remove, + .fence_driver = &radeon_ms_fence_driver, + .bo_driver = &radeon_ms_bo_driver, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .driver_features = + DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | + DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | + DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2, + .dev_priv_size = 0, + .ioctls = radeon_ms_ioctls, + .num_ioctls = 0, + .fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, +#if defined(CONFIG_COMPAT) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) + .compat_ioctl = radeon_ms_compat_ioctl, +#endif + }, + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, + .probe = radeon_ms_driver_probe, + .remove = __devexit_p(drm_cleanup_pci), + }, +}; + +static int radeon_ms_driver_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + return drm_get_dev(pdev, ent, &driver); +} + +static int radeon_ms_driver_dri_library_name(struct drm_device * dev, + char * buf) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + int ret; + + switch (dev_priv->family) { + default: + ret = snprintf(buf, PAGE_SIZE, "\n"); + } + return ret; +} + +static void __exit radeon_ms_driver_exit(void) +{ + drm_exit(&driver); +} + +static int __init radeon_ms_driver_init(void) +{ + driver.num_ioctls = radeon_ms_num_ioctls; + return drm_init(&driver, pciidlist); +} + +module_init(radeon_ms_driver_init); +module_exit(radeon_ms_driver_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL and additional rights"); diff --git a/linux-core/radeon_ms_drv.h b/linux-core/radeon_ms_drv.h new file mode 100644 index 0000000..529f9c4 --- /dev/null +++ b/linux-core/radeon_ms_drv.h @@ -0,0 +1,45 @@ +/* + * Copyright 2007 Dave Airlie + * Copyright 2007 Alex Deucher + * Copyright 2007 Michel Dänzer + * Copyright 2007 Roland Scheidegger + * Copyright 2007 Vladimir Dergachev + * Copyright 2007 Nicolai Haehnle + * Copyright 2007 Aapo Tahkola + * Copyright 2007 Ben Skeggs + * Copyright 2007 Jérôme Glisse + * All Rights Reserved. + * + * 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 + * PRECISION INSIGHT 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: + * Jérôme Glisse <gl...@fr...> + */ +#ifndef __RADEON_MS_DRV_H__ +#define __RADEON_MS_DRV_H__ + +#include <linux/i2c.h> +#include <linux/i2c-id.h> +#include <linux/i2c-algo-bit.h> +#include "drm.h" +#include "drmP.h" + +#endif diff --git a/linux-core/radeon_ms_exec.c b/linux-core/radeon_ms_exec.c new file mode 120000 index 0000000..cb397fb --- /dev/null +++ b/linux-core/radeon_ms_exec.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_exec.c \ No newline at end of file diff --git a/linux-core/radeon_ms_family.c b/linux-core/radeon_ms_family.c new file mode 120000 index 0000000..1f12e09 --- /dev/null +++ b/linux-core/radeon_ms_family.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_family.c \ No newline at end of file diff --git a/linux-core/radeon_ms_fb.c b/linux-core/radeon_ms_fb.c new file mode 100644 index 0000000..ef7c5cf --- /dev/null +++ b/linux-core/radeon_ms_fb.c @@ -0,0 +1,384 @@ +/* + * Copyright © 2007 David Airlie + * Copyright © 2007 Jerome Glisse + * + * All Rights Reserved. + * + * 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 on 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR + * THEIR 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. + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/fb.h> +#include <linux/init.h> + +#include "drmP.h" +#include "drm.h" +#include "drm_crtc.h" +#include "radeon_ms.h" + +struct radeonfb_par { + struct drm_device *dev; + struct drm_crtc *crtc; +}; + +static int radeonfb_setcolreg(unsigned regno, unsigned red, + unsigned green, unsigned blue, + unsigned transp, struct fb_info *info) +{ + struct radeonfb_par *par = info->par; + struct drm_crtc *crtc = par->crtc; + + if (regno > 255) + return 1; + if (crtc->funcs->gamma_set) + crtc->funcs->gamma_set(crtc, red, green, blue, regno); + return 0; +} + +static int radeonfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + struct radeonfb_par *par = info->par; + struct drm_framebuffer *fb = par->crtc->fb; + + if (!var->pixclock) + return -EINVAL; + + /* Need to resize the fb object !!! */ + if (var->xres > fb->width || var->yres > fb->height) { + DRM_ERROR("Requested width/height is greater than " + "current fb object %dx%d > %dx%d\n", + var->xres, var->yres, fb->width, fb->height); + DRM_ERROR("Need resizing code.\n"); + return -EINVAL; + } + + switch (var->bits_per_pixel) { + case 16: + if (var->green.length == 5) { + var->red.offset = 10; + var->green.offset = 5; + var->blue.offset = 0; + var->red.length = 5; + var->green.length = 5; + var->blue.length = 5; + var->transp.length = 0; + var->transp.offset = 0; + } else { + var->red.offset = 11; + var->green.offset = 6; + var->blue.offset = 0; + var->red.length = 5; + var->green.length = 6; + var->blue.length = 5; + var->transp.length = 0; + var->transp.offset = 0; + } + break; + case 32: + if (var->transp.length) { + var->red.offset = 16; + var->green.offset = 8; + var->blue.offset = 0; + var->red.length = 8; + var->green.length = 8; + var->blue.length = 8; + var->transp.length = 8; + var->transp.offset = 24; + } else { + var->red.offset = 16; + var->green.offset = 8; + var->blue.offset = 0; + var->red.length = 8; + var->green.length = 8; + var->blue.length = 8; + var->transp.length = 0; + var->transp.offset = 0; + } + break; + default: + return -EINVAL; + } + return 0; +} + +static int radeonfb_set_par(struct fb_info *info) +{ + struct radeonfb_par *par = info->par; + struct drm_framebuffer *fb = par->crtc->fb; + struct drm_device *dev = par->dev; + struct drm_display_mode *drm_mode; + struct fb_var_screeninfo *var = &info->var; + + switch (var->bits_per_pixel) { + case 16: + fb->depth = (var->green.length == 6) ? 16 : 15; + break; + case 32: + fb->depth = (var->transp.length > 0) ? 32 : 24; + break; + default: + return -EINVAL; + } + fb->bits_per_pixel = var->bits_per_pixel; + + info->fix.line_length = fb->pitch; + info->fix.smem_len = info->fix.line_length * fb->height; + info->fix.visual = FB_VISUAL_TRUECOLOR; + info->screen_size = info->fix.smem_len; /* ??? */ + + /* Should we walk the output's modelist or just create our own ??? + * For now, we create and destroy a mode based on the incoming + * parameters. But there's commented out code below which scans + * the output list too. + */ + drm_mode = drm_mode_create(dev); + drm_mode->hdisplay = var->xres; + drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin; + drm_mode->hsync_end = drm_mode->hsync_start + var->hsync_len; + drm_mode->htotal = drm_mode->hsync_end + var->left_margin; + drm_mode->vdisplay = var->yres; + drm_mode->vsync_start = drm_mode->vdisplay + var->lower_margin; + drm_mode->vsync_end = drm_mode->vsync_start + var->vsync_len; + drm_mode->vtotal = drm_mode->vsync_end + var->upper_margin; + drm_mode->clock = PICOS2KHZ(var->pixclock); + drm_mode->vrefresh = drm_mode_vrefresh(drm_mode); + drm_mode_set_name(drm_mode); + drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V); + + drm_mode_debug_printmodeline(dev, drm_mode); + + if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0)) + return -EINVAL; + + /* Have to destroy our created mode if we're not searching the mode + * list for it. + */ + drm_mode_destroy(dev, drm_mode); + + return 0; +} + +static struct fb_ops radeonfb_ops = { + .owner = THIS_MODULE, + // .fb_open = radeonfb_open, + // .fb_read = radeonfb_read, + // .fb_write = radeonfb_write, + // .fb_release = radeonfb_release, + // .fb_ioctl = radeonfb_ioctl, + .fb_check_var = radeonfb_check_var, + .fb_set_par = radeonfb_set_par, + .fb_setcolreg = radeonfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + +int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc) +{ + struct fb_info *info; + struct radeonfb_par *par; + struct device *device = &dev->pdev->dev; + struct drm_framebuffer *fb; + struct drm_display_mode *mode = crtc->desired_mode; + int ret; + + info = framebuffer_alloc(sizeof(struct radeonfb_par), device); + if (!info){ + DRM_INFO("[radeon_ms] framebuffer_alloc failed\n"); + return -EINVAL; + } + + fb = drm_framebuffer_create(dev); + if (!fb) { + framebuffer_release(info); + DRM_ERROR("[radeon_ms] failed to allocate fb.\n"); + return -EINVAL; + } + crtc->fb = fb; + + fb->width = crtc->desired_mode->hdisplay; + fb->height = crtc->desired_mode->vdisplay; + fb->bits_per_pixel = 32; + fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8); + fb->depth = 24; + /* one page alignment should be fine for constraint (micro|macro tiling, + * bit depth, color buffer offset, ...) */ + ret = drm_buffer_object_create(dev, fb->width * fb->height * 4, + drm_bo_type_kernel, + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_NO_EVICT | + DRM_BO_FLAG_MEM_VRAM, + DRM_BO_HINT_DONT_FENCE, + 1, + 0, + &fb->bo); + if (ret || fb->bo == NULL) { + DRM_ERROR("[radeon_ms] failed to allocate framebuffer\n"); + drm_framebuffer_destroy(fb); + framebuffer_release(info); + return -EINVAL; + } + + fb->offset = fb->bo->offset; + DRM_INFO("[radeon_ms] framebuffer %dx%d at 0x%08lX\n", + fb->width, fb->height, fb->bo->offset); + + fb->fbdev = info; + par = info->par; + par->dev = dev; + par->crtc = crtc; + info->fbops = &radeonfb_ops; + strcpy(info->fix.id, "radeonfb"); + info->fix.type = FB_TYPE_PACKED_PIXELS; + info->fix.visual = FB_VISUAL_TRUECOLOR; + info->fix.type_aux = 0; + info->fix.xpanstep = 8; + info->fix.ypanstep = 1; + info->fix.ywrapstep = 0; + info->fix.accel = FB_ACCEL_ATI_RADEON; + info->fix.type_aux = 0; + info->fix.mmio_start = 0; + info->fix.mmio_len = 0; + info->fix.line_length = fb->pitch; + info->fix.smem_start = fb->offset + dev->mode_config.fb_base; + info->fix.smem_len = info->fix.line_length * fb->height; + info->flags = FBINFO_DEFAULT; + DRM_INFO("[radeon_ms] fb physical start : 0x%lX\n", info->fix.smem_start); + DRM_INFO("[radeon_ms] fb physical size : %d\n", info->fix.smem_len); + + ret = drm_mem_reg_ioremap(dev, &fb->bo->mem, &fb->virtual_base); + if (ret) { + DRM_ERROR("error mapping fb: %d\n", ret); + } + + info->screen_base = fb->virtual_base; + info->screen_size = info->fix.smem_len; /* FIXME */ + info->pseudo_palette = fb->pseudo_palette; + info->var.xres_virtual = fb->width; + info->var.yres_virtual = fb->height; + info->var.bits_per_pixel = fb->bits_per_pixel; + info->var.xoffset = 0; + info->var.yoffset = 0; + info->var.activate = FB_ACTIVATE_NOW; + info->var.height = -1; + info->var.width = -1; + info->var.vmode = FB_VMODE_NONINTERLACED; + + info->var.xres = mode->hdisplay; + info->var.right_margin = mode->hsync_start - mode->hdisplay; + info->var.hsync_len = mode->hsync_end - mode->hsync_start; + info->var.left_margin = mode->htotal - mode->hsync_end; + info->var.yres = mode->vdisplay; + info->var.lower_margin = mode->vsync_start - mode->vdisplay; + info->var.vsync_len = mode->vsync_end - mode->vsync_start; + info->var.upper_margin = mode->vtotal - mode->vsync_end; + info->var.pixclock = 10000000 / mode->htotal * 1000 / + mode->vtotal * 100; + /* avoid overflow */ + info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh; + + info->pixmap.size = 64*1024; + info->pixmap.buf_align = 8; + info->pixmap.access_align = 32; + info->pixmap.flags = FB_PIXMAP_SYSTEM; + info->pixmap.scan_align = 1; + + DRM_DEBUG("fb depth is %d\n", fb->depth); + DRM_DEBUG(" pitch is %d\n", fb->pitch); + switch(fb->depth) { + case 15: + info->var.red.offset = 10; + info->var.green.offset = 5; + info->var.blue.offset = 0; + info->var.red.length = info->var.green.length = + info->var.blue.length = 5; + info->var.transp.offset = 15; + info->var.transp.length = 1; + break; + case 16: + info->var.red.offset = 11; + info->var.green.offset = 5; + info->var.blue.offset = 0; + info->var.red.length = 5; + info->var.green.length = 6; + info->var.blue.length = 5; + info->var.transp.offset = 0; + break; + case 24: + info->var.red.offset = 16; + info->var.green.offset = 8; + info->var.blue.offset = 0; + info->var.red.length = info->var.green.length = + info->var.blue.length = 8; + info->var.transp.offset = 0; + info->var.transp.length = 0; + break; + case 32: + info->var.red.offset = 16; + info->var.green.offset = 8; + info->var.blue.offset = 0; + info->var.red.length = info->var.green.length = + info->var.blue.length = 8; + info->var.transp.offset = 24; + info->var.transp.length = 8; + break; + default: + DRM_ERROR("only support 15, 16, 24 or 32bits per pixel " + "got %d\n", fb->depth); + return -EINVAL; + break; + } + + if (register_framebuffer(info) < 0) { + return -EINVAL; + } + + DRM_INFO("[radeon_ms] fb%d: %s frame buffer device\n", info->node, + info->fix.id); + return 0; +} +EXPORT_SYMBOL(radeonfb_probe); + +int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc) +{ + struct drm_framebuffer *fb = crtc->fb; + struct fb_info *info = fb->fbdev; + + if (info) { + unregister_framebuffer(info); + framebuffer_release(info); + drm_mem_reg_iounmap(dev, &fb->bo->mem, fb->virtual_base); + drm_bo_usage_deref_unlocked(&fb->bo); + drm_framebuffer_destroy(fb); + } + return 0; +} +EXPORT_SYMBOL(radeonfb_remove); +MODULE_LICENSE("GPL"); diff --git a/linux-core/radeon_ms_fence.c b/linux-core/radeon_ms_fence.c new file mode 120000 index 0000000..383cc07 --- /dev/null +++ b/linux-core/radeon_ms_fence.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_fence.c \ No newline at end of file diff --git a/linux-core/radeon_ms_gpu.c b/linux-core/radeon_ms_gpu.c new file mode 120000 index 0000000..fa5e05b --- /dev/null +++ b/linux-core/radeon_ms_gpu.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_gpu.c \ No newline at end of file diff --git a/linux-core/radeon_ms_i2c.c b/linux-core/radeon_ms_i2c.c new file mode 120000 index 0000000..1863e6d --- /dev/null +++ b/linux-core/radeon_ms_i2c.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_i2c.c \ No newline at end of file diff --git a/linux-core/radeon_ms_irq.c b/linux-core/radeon_ms_irq.c new file mode 120000 index 0000000..c4e60ba --- /dev/null +++ b/linux-core/radeon_ms_irq.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_irq.c \ No newline at end of file diff --git a/linux-core/radeon_ms_output.c b/linux-core/radeon_ms_output.c new file mode 120000 index 0000000..6a38b67 --- /dev/null +++ b/linux-core/radeon_ms_output.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_output.c \ No newline at end of file diff --git a/linux-core/radeon_ms_reg.h b/linux-core/radeon_ms_reg.h new file mode 120000 index 0000000..24b01b4 --- /dev/null +++ b/linux-core/radeon_ms_reg.h @@ -0,0 +1 @@ +../shared-core/radeon_ms_reg.h \ No newline at end of file diff --git a/linux-core/radeon_ms_state.c b/linux-core/radeon_ms_state.c new file mode 120000 index 0000000..2d2e2ef --- /dev/null +++ b/linux-core/radeon_ms_state.c @@ -0,0 +1 @@ +../shared-core/radeon_ms_state.c \ No newline at end of file diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt index 05d32f2..a76413d 100644 --- a/shared-core/drm_pciids.txt +++ b/shared-core/drm_pciids.txt @@ -1,3 +1,7 @@ +[radeon_ms] +0x1002 0x4150 CHIP_RV350|RADEON_AGP "ATI Radeon RV350 9600" +0x1002 0x5b63 CHIP_RV370|RADEON_PCIE "ATI Radeon RV370 X550" + [radeon] 0x1002 0x3150 CHIP_RV380|RADEON_IS_MOBILITY "ATI Radeon Mobility X600 M24" 0x1002 0x3152 CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon Mobility X300 M24" diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h new file mode 100644 index 0000000..ee795f3 --- /dev/null +++ b/shared-core/radeon_ms.h @@ -0,0 +1,607 @@ +/* + * Copyright 2007 Jérôme Glisse + * Copyright 2007 Dave Airlie + * Copyright 2007 Alex Deucher + * All Rights Reserved. + * + * 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 + * PRECISION INSIGHT 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: + * Jérôme Glisse <gl...@fr...> + */ +#ifndef __RADEON_MS_H__ +#define __RADEON_MS_H__ + +#include "radeon_ms_drv.h" +#include "radeon_ms_reg.h" +#include "radeon_ms_drm.h" + +#define DRIVER_AUTHOR "Jerome Glisse, Dave Airlie, Gareth Hughes, "\ + "Keith Whitwell, others." +#define DRIVER_NAME "radeon_ms" +#define DRIVER_DESC "radeon kernel modesetting" +#define DRIVER_DATE "20071108" +#define DRIVER_MAJOR 1 +#define DRIVER_MINOR 0 +#define DRIVER_PATCHLEVEL 0 + +#define RADEON_PAGE_SIZE 4096 +#define RADEON_MAX_CONNECTORS 8 +#define RADEON_MAX_OUTPUTS 8 + +enum radeon_bus_type { + RADEON_PCI = 0x10000, + RADEON_AGP = 0x20000, + RADEON_PCIE = 0x30000, +}; + +enum radeon_family { + CHIP_R100, + CHIP_RV100, + CHIP_RS100, + CHIP_RV200, + CHIP_RS200, + CHIP_R200, + CHIP_RV250, + CHIP_RS300, + CHIP_RV280, + CHIP_R300, + CHIP_R350, + CHIP_R360, + CHIP_RV350, + CHIP_RV370, + CHIP_RV380, + CHIP_RS400, + CHIP_RV410, + CHIP_R420, + CHIP_R430, + CHIP_R480, + CHIP_LAST, +}; + +enum radeon_monitor_type { + MT_UNKNOWN = -1, + MT_NONE = 0, + MT_CRT = 1, + MT_LCD = 2, + MT_DFP = 3, + MT_CTV = 4, + MT_STV = 5 +}; + +enum radeon_connector_type { + CONNECTOR_NONE, + CONNECTOR_PROPRIETARY, + CONNECTOR_VGA, + CONNECTOR_DVI_I, + CONNECTOR_DVI_D, + CONNECTOR_CTV, + CONNECTOR_STV, + CONNECTOR_UNSUPPORTED +}; + +enum radeon_output_type { + OUTPUT_NONE, + OUTPUT_DAC1, + OUTPUT_DAC2, + OUTPUT_TMDS, + OUTPUT_LVDS +}; + +struct radeon_state; + +struct radeon_ms_crtc { + int crtc; + uint16_t lut_r[256]; + uint16_t lut_g[256]; + uint16_t lut_b[256]; +}; + +struct radeon_ms_i2c { + struct drm_device *drm_dev; + uint32_t reg; + struct i2c_adapter adapter; + struct i2c_algo_bit_data algo; +}; + +struct radeon_ms_connector { + struct radeon_ms_i2c *i2c; + struct edid *edid; + struct drm_output *output; + int type; + int monitor_type; + int crtc; + uint32_t i2c_reg; + char outputs[RADEON_MAX_OUTPUTS]; + char name[32]; +}; + +struct radeon_ms_output { + int type; + struct drm_device *dev; + struct radeon_ms_connector *connector; + int (*initialize)(struct radeon_ms_output *output); + enum drm_output_status (*detect)(struct radeon_ms_output *output); + void (*dpms)(struct radeon_ms_output *output, int mode); + int (*get_modes)(struct radeon_ms_output *output); + bool (*mode_fixup)(struct radeon_ms_output *output, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + int (*mode_set)(struct radeon_ms_output *output, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + void (*restore)(struct radeon_ms_output *output, + struct radeon_state *state); + void (*save)(struct radeon_ms_output *output, + struct radeon_state *state); +}; + +struct radeon_ms_properties { + uint16_t subvendor; + uint16_t subdevice; + int16_t pll_reference_freq; + int32_t pll_min_pll_freq; + int32_t pll_max_pll_freq; + char pll_use_bios; + char pll_dummy_reads; + char pll_delay; + char pll_r300_errata; + struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS]; + struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS]; +}; + +struct radeon_state { + /* memory */ + uint32_t config_aper_0_base; + uint32_t config_aper_1_base; + uint32_t config_aper_size; + uint32_t mc_fb_location; + uint32_t display_base_addr; + /* irq */ + uint32_t gen_int_cntl; + /* pci */ + uint32_t aic_ctrl; + uint32_t aic_pt_base; + uint32_t aic_pt_base_lo; + uint32_t aic_pt_base_hi; + uint32_t aic_lo_addr; + uint32_t aic_hi_addr; + /* agp */ + uint32_t agp_cntl; + uint32_t agp_command; + uint32_t agp_base; + uint32_t agp_base_2; + uint32_t bus_cntl; + uint32_t mc_agp_location; + /* cp */ + uint32_t cp_rb_cntl; + uint32_t cp_rb_base; + uint32_t cp_rb_rptr_addr; + uint32_t cp_rb_wptr; + uint32_t cp_rb_wptr_delay; + uint32_t scratch_umsk; + uint32_t scratch_addr; + /* pcie */ + uint32_t pcie_tx_gart_cntl; + uint32_t pcie_tx_gart_discard_rd_addr_lo; + uint32_t pcie_tx_gart_discard_rd_addr_hi; + uint32_t pcie_tx_gart_base; + uint32_t pcie_tx_gart_start_lo; + uint32_t pcie_tx_gart_start_hi; + uint32_t pcie_tx_gart_end_lo; + uint32_t pcie_tx_gart_end_hi; + /* surface */ + uint32_t surface_cntl; + uint32_t surface0_info; + uint32_t surface0_lower_bound; + uint32_t surface0_upper_bound; + uint32_t surface1_info; + uint32_t surface1_lower_bound; + uint32_t surface1_upper_bound; + uint32_t surface2_info; + uint32_t surface2_lower_bound; + uint32_t surface2_upper_bound; + uint32_t surface3_info; + uint32_t surface3_lower_bound; + uint32_t surface3_upper_bound; + uint32_t surface4_info; + uint32_t surface4_lower_bound; + uint32_t surface4_upper_bound; + uint32_t surface5_info; + uint32_t surface5_lower_bound; + uint32_t surface5_upper_bound; + uint32_t surface6_info; + uint32_t surface6_lower_bound; + uint32_t surface6_upper_bound; + uint32_t surface7_info; + uint32_t surface7_lower_bound; + uint32_t surface7_upper_bound; + /* crtc */ + uint32_t crtc_gen_cntl; + uint32_t crtc_ext_cntl; + uint32_t crtc_h_total_disp; + uint32_t crtc_h_sync_strt_wid; + uint32_t crtc_v_total_disp; + uint32_t crtc_v_sync_strt_wid; + uint32_t crtc_offset; + uint32_t crtc_offset_cntl; + uint32_t crtc_pitch; + uint32_t crtc_more_cntl; + uint32_t crtc_tile_x0_y0; + uint32_t fp_h_sync_strt_wid; + uint32_t fp_v_sync_strt_wid; + uint32_t fp_crtc_h_total_disp; + uint32_t fp_crtc_v_total_disp; + /* pll */ + uint32_t clock_cntl_index; + uint32_t ppll_cntl; + uint32_t ppll_ref_div; + uint32_t ppll_div_0; + uint32_t ppll_div_1; + uint32_t ppll_div_2; + uint32_t ppll_div_3; + uint32_t vclk_ecp_cntl; + uint32_t htotal_cntl; + /* dac */ + uint32_t dac_cntl; + uint32_t dac_cntl2; + uint32_t dac_ext_cntl; + uint32_t disp_misc_cntl; + uint32_t dac_macro_cntl; + uint32_t disp_pwr_man; + uint32_t disp_merge_cntl; + uint32_t disp_output_cntl; + uint32_t disp2_merge_cntl; + uint32_t dac_embedded_sync_cntl; + uint32_t dac_broad_pulse; + uint32_t dac_skew_clks; + uint32_t dac_incr; + uint32_t dac_neg_sync_level; + uint32_t dac_pos_sync_level; + uint32_t dac_blank_level; + uint32_t dac_sync_equalization; + uint32_t tv_dac_cntl; + uint32_t tv_master_cntl; +}; + +struct drm_radeon_private { + /* driver family specific functions */ + int (*bus_finish)(struct drm_device *dev); + int (*bus_init)(struct drm_device *dev); + void (*bus_restore)(struct drm_device *dev, struct radeon_state *state); + void (*bus_save)(struct drm_device *dev, struct radeon_state *state); + struct drm_ttm_backend *(*create_ttm)(struct drm_device *dev); + void (*irq_emit)(struct drm_device *dev); + void (*flush_cache)(struct drm_device *dev); + /* bus informations */ + void *bus; + uint32_t bus_type; + /* cp */ + uint32_t ring_buffer_size; + uint32_t ring_rptr; + uint32_t ring_wptr; + uint32_t ring_mask; + int ring_free; + uint32_t ring_tail_mask; + uint32_t write_back_area_size; + struct drm_buffer_object *ring_buffer_object; + struct drm_bo_kmap_obj ring_buffer_map; + uint32_t *ring_buffer; + uint32_t *write_back_area; + const uint32_t *microcode; + /* card family */ + uint32_t usec_timeout; + uint32_t family; + struct radeon_ms_properties *properties; + struct radeon_ms_output *outputs[RADEON_MAX_OUTPUTS]; + struct radeon_ms_connector *connectors[RADEON_MAX_CONNECTORS]; + /* drm map (MMIO, FB) */ + struct drm_map mmio; + struct drm_map vram; + /* gpu address space */ + uint32_t gpu_vram_size; + uint32_t gpu_vram_start; + uint32_t gpu_vram_end; + uint32_t gpu_gart_size; + uint32_t gpu_gart_start; + uint32_t gpu_gart_end; + /* state of the card when module was loaded */ + struct radeon_state load_state; + /* state the driver wants */ + struct radeon_state driver_state; + /* last emitted fence */ + uint32_t fence_id_last; + uint32_t fence_reg; + /* when doing gpu stop we save here current state */ + uint32_t crtc_ext_cntl; + uint32_t crtc_gen_cntl; + uint32_t crtc2_gen_cntl; + uint32_t ov0_scale_cntl; + /* bool & type on the hw */ + uint8_t crtc1_dpms; + uint8_t crtc2_dpms; + uint8_t restore_state; + uint8_t cp_ready; + uint8_t bus_ready; + uint8_t write_back; +}; + + +/* radeon_ms_bo.c */ +int radeon_ms_bo_get_gpu_addr(struct drm_device *dev, + struct drm_bo_mem_reg *mem, + uint32_t *gpu_addr); +int radeon_ms_bo_move(struct drm_buffer_object * bo, int evict, + int no_wait, struct drm_bo_mem_reg * new_mem); +struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev); +uint32_t radeon_ms_evict_mask(struct drm_buffer_object *bo); +int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type, + struct drm_mem_type_manager * man); +int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags); +void radeon_ms_ttm_flush(struct drm_ttm *ttm); + +/* radeon_ms_bus.c */ +int radeon_ms_agp_finish(struct drm_device *dev); +int radeon_ms_agp_init(struct drm_device *dev); +void radeon_ms_agp_restore(struct drm_device *dev, struct radeon_state *state); +void radeon_ms_agp_save(struct drm_device *dev, struct radeon_state *state); +struct drm_ttm_backend *radeon_ms_pcie_create_ttm(struct drm_device *dev); +int radeon_ms_pcie_finish(struct drm_device *dev); +int radeon_ms_pcie_init(struct drm_device *dev); +void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state); +void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state); + +/* radeon_ms_compat.c */ +long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); + +/* radeon_ms_cp.c */ +int radeon_ms_cp_finish(struct drm_device *dev); +int radeon_ms_cp_init(struct drm_device *dev); +void radeon_ms_cp_restore(struct drm_device *dev, struct radeon_state *state); +void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state); +void radeon_ms_cp_stop(struct drm_device *dev); +int radeon_ms_cp_wait(struct drm_device *dev, int n); +int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count); + +/* radeon_ms_crtc.c */ +int radeon_ms_crtc_create(struct drm_device *dev, int crtc); +void radeon_ms_crtc1_restore(struct drm_device *dev, + struct radeon_state *state); +void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state); + +/* radeon_ms_dac.c */ +int radeo... [truncated message content] |
From: <al...@ke...> - 2007-12-13 10:41:34
|
linux-core/drm_bo.c | 2 - shared-core/drm.h | 2 + shared-core/i915_dma.c | 85 ++++++++++++++++++++++++++++++++++++++++--------- shared-core/i915_drv.h | 3 + 4 files changed, 76 insertions(+), 16 deletions(-) New commits: commit f62a300547b1f495472f773587cd20c6c9da06aa Merge: 8d2da20... 35a8b61... Author: Alan Hourihane <al...@tu...> Date: Thu Dec 13 10:41:23 2007 +0000 Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/drm into modesetting-101 commit 35a8b61317b57fcaaf5f7df06b0e2b532eddb9cb Author: Alan Hourihane <al...@tu...> Date: Thu Dec 13 10:40:36 2007 +0000 catch an out of memory condition diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 2b8ef1b..d308dcf 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -925,7 +925,7 @@ int drm_bo_mem_space(struct drm_buffer_object *bo, ret = drm_bo_mem_force_space(dev, mem, mem_type, no_wait); - if (ret == 0) { + if (ret == 0 && mem->mm_node) { mem->flags = cur_flags; return 0; } commit 7dcaf0cdbb57dcf85aa8798736948c280d3966b2 Author: Keith Packard <ke...@ke...> Date: Tue Dec 11 20:21:23 2007 -0800 Make relocation validate client computed values when debugging diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 18d2482..8041672 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -702,7 +702,14 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, return 0; } +#if DRM_DEBUG_CODE +#define DRM_DEBUG_RELOCATION (drm_debug != 0) +#else +#define DRM_DEBUG_RELOCATION 0 +#endif + #ifdef I915_HAVE_BUFFER + struct i915_relocatee_info { struct drm_buffer_object *buf; unsigned long offset; @@ -743,7 +750,7 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, * Short-circuit relocations that were correctly * guessed by the client */ - if (buffers[reloc[2]].presumed_offset_correct) + if (buffers[reloc[2]].presumed_offset_correct && !DRM_DEBUG_RELOCATION) return 0; new_cmd_offset = reloc[0]; @@ -776,6 +783,13 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, /* add in validate */ val = val + reloc[1]; + if (DRM_DEBUG_RELOCATION) { + if (buffers[reloc[2]].presumed_offset_correct && + relocatee->data_page[index] != val) { + DRM_DEBUG ("Relocation mismatch source %d target %d buffer %d user %08x kernel %08x\n", + reloc[0], reloc[1], reloc[2], relocatee->data_page[index], val); + } + } relocatee->data_page[index] = val; return 0; } @@ -883,12 +897,14 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, * buffers offsets were correctly guessed by * the client */ - for (b = 0; b < buf_count; b++) - if (!buffers[b].presumed_offset_correct) - break; - - if (b == buf_count) - return 0; + if (!DRM_DEBUG_RELOCATION) { + for (b = 0; b < buf_count; b++) + if (!buffers[b].presumed_offset_correct) + break; + + if (b == buf_count) + return 0; + } memset(&relocatee, 0, sizeof(relocatee)); commit 4ec8f58d042d7fe0dab570fed35a438759645ca8 Author: Keith Packard <ke...@ke...> Date: Thu Dec 6 15:12:21 2007 -0800 i915: wait for buffer idle before writing relocations When writing a relocation entry, make sure the target buffer is idle, otherwise the GPU may see inconsistent data. diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 090ac80..18d2482 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -751,6 +751,13 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, !drm_bo_same_page(relocatee->offset, new_cmd_offset)) { drm_bo_kunmap(&relocatee->kmap); relocatee->offset = new_cmd_offset; + mutex_lock (&relocatee->buf->mutex); + ret = drm_bo_wait (relocatee->buf, 0, 0, FALSE); + mutex_unlock (&relocatee->buf->mutex); + if (ret) { + DRM_ERROR("Could not wait for buffer to apply relocs\n %08lx", new_cmd_offset); + return ret; + } ret = drm_bo_kmap(relocatee->buf, new_cmd_offset >> PAGE_SHIFT, 1, &relocatee->kmap); if (ret) { commit 9ee511d786b1a87944f043c1a16057e8dfc48668 Author: Keith Packard <ke...@ke...> Date: Tue Dec 4 20:54:53 2007 -0800 Bump driver minor for relocation optimzations diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index cb33665..bdc7841 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -57,10 +57,11 @@ * 1.9: Usable page flipping and triple buffering * 1.10: Plane/pipe disentangling * 1.11: TTM superioctl + * 1.12: TTM relocation optimization */ #define DRIVER_MAJOR 1 #if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER) -#define DRIVER_MINOR 11 +#define DRIVER_MINOR 12 #else #define DRIVER_MINOR 6 #endif commit 57b9a54eb668477407c8be54c041d7a9f92c1f51 Author: Keith Packard <ke...@ke...> Date: Tue Dec 4 12:22:30 2007 -0800 Allow relocation to be skipped when buffers don't move. One of the costs of superioctl has been the need to perform relocations inside the kernel. The cost of mapping the buffers to the CPU and writing data is fairly high, especially if those buffers have been mapped and read by the GPU. If we assume that buffers don't move around very often, we can have the client compute the relocations itself using the previous GPU address. When that object doesn't move, the kernel can skip computing and writing the updated data. Here's a patch which adds a new field to struct drm_bo_info_req called 'presumed_offset', and a new DRM_BO_HINT_PRESUMED_OFFSET that is set when this field has been filled in by the client. There are two separate optimizations performed when the presumed_offset is correct: 1. i915_exec_reloc checks to see if all previous buffer offsets were guessed correctly. If so, there's no need for it to look at *any* of the relocations for a buffer. When this happens, it skips the whole relocation process, simply returning success. 2. i915_apply_reloc checks to see if the target buffer offset was guessed correctly. If so, it skips mapping the relocatee, computing the relocation and writing the value. If no relocations are needed, the relocatee should never be mapped to the CPU, and so the kernel shouldn't need to wait for any fences to pass. diff --git a/shared-core/drm.h b/shared-core/drm.h index ec07b89..70a25b2 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -753,6 +753,7 @@ struct drm_fence_arg { /* Don't place this buffer on the unfenced list.*/ #define DRM_BO_HINT_DONT_FENCE 0x00000004 #define DRM_BO_HINT_WAIT_LAZY 0x00000008 +#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010 #define DRM_BO_INIT_MAGIC 0xfe769812 #define DRM_BO_INIT_MAJOR 1 @@ -769,6 +770,7 @@ struct drm_bo_info_req { unsigned int desired_tile_stride; unsigned int tile_info; unsigned int pad64; + uint64_t presumed_offset; }; struct drm_bo_create_req { diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 42114be..090ac80 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -712,15 +712,20 @@ struct i915_relocatee_info { int is_iomem; }; -static void i915_dereference_buffers_locked(struct drm_buffer_object **buffers, +struct drm_i915_validate_buffer { + struct drm_buffer_object *buffer; + int presumed_offset_correct; +}; + +static void i915_dereference_buffers_locked(struct drm_i915_validate_buffer *buffers, unsigned num_buffers) { while (num_buffers--) - drm_bo_usage_deref_locked(&buffers[num_buffers]); + drm_bo_usage_deref_locked(&buffers[num_buffers].buffer); } int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, - struct drm_buffer_object **buffers, + struct drm_i915_validate_buffer *buffers, struct i915_relocatee_info *relocatee, uint32_t *reloc) { @@ -734,6 +739,13 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, return -EINVAL; } + /* + * Short-circuit relocations that were correctly + * guessed by the client + */ + if (buffers[reloc[2]].presumed_offset_correct) + return 0; + new_cmd_offset = reloc[0]; if (!relocatee->data_page || !drm_bo_same_page(relocatee->offset, new_cmd_offset)) { @@ -751,7 +763,7 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers, relocatee->page_offset = (relocatee->offset & PAGE_MASK); } - val = buffers[reloc[2]]->offset; + val = buffers[reloc[2]].buffer->offset; index = (reloc[0] - relocatee->page_offset) >> 2; /* add in validate */ @@ -765,7 +777,7 @@ int i915_process_relocs(struct drm_file *file_priv, uint32_t buf_handle, uint32_t *reloc_buf_handle, struct i915_relocatee_info *relocatee, - struct drm_buffer_object **buffers, + struct drm_i915_validate_buffer *buffers, uint32_t num_buffers) { struct drm_device *dev = file_priv->head->dev; @@ -851,12 +863,25 @@ out: static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle, drm_handle_t buf_reloc_handle, - struct drm_buffer_object **buffers, + struct drm_i915_validate_buffer *buffers, uint32_t buf_count) { struct drm_device *dev = file_priv->head->dev; struct i915_relocatee_info relocatee; int ret = 0; + int b; + + /* + * Short circuit relocations when all previous + * buffers offsets were correctly guessed by + * the client + */ + for (b = 0; b < buf_count; b++) + if (!buffers[b].presumed_offset_correct) + break; + + if (b == buf_count) + return 0; memset(&relocatee, 0, sizeof(relocatee)); @@ -890,7 +915,7 @@ out_err: */ int i915_validate_buffer_list(struct drm_file *file_priv, unsigned int fence_class, uint64_t data, - struct drm_buffer_object **buffers, + struct drm_i915_validate_buffer *buffers, uint32_t *num_buffers) { struct drm_i915_op_arg arg; @@ -910,7 +935,8 @@ int i915_validate_buffer_list(struct drm_file *file_priv, goto out_err; } - buffers[buf_count] = NULL; + buffers[buf_count].buffer = NULL; + buffers[buf_count].presumed_offset_correct = 0; if (copy_from_user(&arg, (void __user *)(unsigned long)data, sizeof(arg))) { ret = -EFAULT; @@ -920,7 +946,7 @@ int i915_validate_buffer_list(struct drm_file *file_priv, if (arg.handled) { data = arg.next; mutex_lock(&dev->struct_mutex); - buffers[buf_count] = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); + buffers[buf_count].buffer = drm_lookup_buffer_object(file_priv, req->arg_handle, 1); mutex_unlock(&dev->struct_mutex); buf_count++; continue; @@ -951,13 +977,21 @@ int i915_validate_buffer_list(struct drm_file *file_priv, req->bo_req.hint, 0, &rep.bo_info, - &buffers[buf_count]); + &buffers[buf_count].buffer); if (rep.ret) { DRM_ERROR("error on handle validate %d\n", rep.ret); goto out_err; } - + /* + * If the user provided a presumed offset hint, check whether + * the buffer is in the same place, if so, relocations relative to + * this buffer need not be performed + */ + if ((req->bo_req.hint & DRM_BO_HINT_PRESUMED_OFFSET) && + buffers[buf_count].buffer->offset == req->bo_req.presumed_offset) { + buffers[buf_count].presumed_offset_correct = 1; + } next = arg.next; arg.handled = 1; @@ -991,7 +1025,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data, struct drm_fence_arg *fence_arg = &exec_buf->fence_arg; int num_buffers; int ret; - struct drm_buffer_object **buffers; + struct drm_i915_validate_buffer *buffers; struct drm_fence_object *fence; if (!dev_priv->allow_batchbuffer) { @@ -1026,7 +1060,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data, num_buffers = exec_buf->num_buffers; - buffers = drm_calloc(num_buffers, sizeof(struct drm_buffer_object *), DRM_MEM_DRIVER); + buffers = drm_calloc(num_buffers, sizeof(struct drm_i915_validate_buffer), DRM_MEM_DRIVER); if (!buffers) { drm_bo_read_unlock(&dev->bm.bm_lock); mutex_unlock(&dev_priv->cmdbuf_mutex); @@ -1044,7 +1078,7 @@ static int i915_execbuffer(struct drm_device *dev, void *data, drm_agp_chipset_flush(dev); /* submit buffer */ - batch->start = buffers[num_buffers-1]->offset; + batch->start = buffers[num_buffers-1].buffer->offset; DRM_DEBUG("i915 exec batchbuffer, start %x used %d cliprects %d\n", batch->start, batch->used, batch->num_cliprects); |
From: <ai...@ke...> - 2008-01-09 07:11:51
|
libdrm/xf86drm.c | 25 ++++++++++++++++--------- libdrm/xf86drm.h | 2 ++ linux-core/drmP.h | 1 + linux-core/drm_crtc.c | 1 + linux-core/drm_drv.c | 32 +++++++++++++++++--------------- linux-core/drm_sysfs.c | 12 +++++++----- tests/dristat.c | 2 +- 7 files changed, 45 insertions(+), 30 deletions(-) New commits: commit e04d942ee8e74fce90e332446e740a100d782033 Author: Dave Airlie <ai...@re...> Date: Wed Jan 9 18:11:17 2008 +1100 fixup crtcinfo on modes from userspace diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index b49fa69..0b71b13 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1548,6 +1548,7 @@ int drm_mode_setcrtc(struct drm_device *dev, mode = drm_mode_create(dev); drm_crtc_convert_umode(mode, &crtc_req->mode); + drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); } if (crtc_req->count_outputs == 0 && mode) { commit 87a32efcdde124df59656e00a402ba50a0ba1e45 Author: Dave Airlie <ai...@re...> Date: Wed Jan 9 18:11:04 2008 +1100 add control node open diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 2d7d85c..3cc54f1 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -579,6 +579,10 @@ int drmOpen(const char *name, const char *busid) return -1; } +int drmOpenControl(int minor) +{ + return drmOpenMinor(minor, 0, DRM_NODE_CONTROL); +} /** * Free the version information returned by drmGetVersion(). diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index d6e9882..7b41860 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -509,6 +509,7 @@ do { register unsigned int __old __asm("o0"); \ /* General user-level programmer's API: unprivileged */ extern int drmAvailable(void); extern int drmOpen(const char *name, const char *busid); +extern int drmOpenControl(int minor); extern int drmClose(int fd); extern drmVersionPtr drmGetVersion(int fd); extern drmVersionPtr drmGetLibVersion(int fd); commit 73bf5e867089b58b2c4baaa833d15a2b1fb268a4 Author: Dave Airlie <ai...@re...> Date: Wed Jan 9 16:44:31 2008 +1100 add internals for opening a control node diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 4265c32..2d7d85c 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -87,6 +87,9 @@ #define DRM_MSG_VERBOSITY 3 +#define DRM_NODE_CONTROL 0 +#define DRM_NODE_RENDER 1 + static drmServerInfoPtr drm_server_info; void drmSetServerInfo(drmServerInfoPtr info) @@ -264,7 +267,7 @@ static int drmMatchBusID(const char *id1, const char *id2) * special file node with the major and minor numbers specified by \p dev and * parent directory if necessary and was called by root. */ -static int drmOpenDevice(long dev, int minor) +static int drmOpenDevice(long dev, int minor, int type) { stat_t st; char buf[64]; @@ -274,7 +277,7 @@ static int drmOpenDevice(long dev, int minor) uid_t user = DRM_DEV_UID; gid_t group = DRM_DEV_GID, serv_group; - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); + sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor); drmMsg("drmOpenDevice: node name is %s\n", buf); if (drm_server_info) { @@ -348,15 +351,15 @@ static int drmOpenDevice(long dev, int minor) * Calls drmOpenDevice() if \p create is set, otherwise assembles the device * name from \p minor and opens it. */ -static int drmOpenMinor(int minor, int create) +static int drmOpenMinor(int minor, int create, int type) { int fd; char buf[64]; if (create) - return drmOpenDevice(makedev(DRM_MAJOR, minor), minor); + return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type); - sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); + sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor); if ((fd = open(buf, O_RDWR, 0)) >= 0) return fd; return -errno; @@ -379,7 +382,7 @@ int drmAvailable(void) int retval = 0; int fd; - if ((fd = drmOpenMinor(0, 1)) < 0) { + if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) { #ifdef __linux__ /* Try proc for backward Linux compatibility */ if (!access("/proc/dri/0", R_OK)) @@ -420,7 +423,7 @@ static int drmOpenByBusid(const char *busid) drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid); for (i = 0; i < DRM_MAX_MINOR; i++) { - fd = drmOpenMinor(i, 1); + fd = drmOpenMinor(i, 1, DRM_NODE_RENDER); drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); if (fd >= 0) { sv.drm_di_major = 1; @@ -482,7 +485,7 @@ static int drmOpenByName(const char *name) * already in use. If it's in use it will have a busid assigned already. */ for (i = 0; i < DRM_MAX_MINOR; i++) { - if ((fd = drmOpenMinor(i, 1)) >= 0) { + if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) { if ((version = drmGetVersion(fd))) { if (!strcmp(version->name, name)) { drmFreeVersion(version); @@ -526,7 +529,7 @@ static int drmOpenByName(const char *name) if (*pt) { /* Found busid */ return drmOpenByBusid(++pt); } else { /* No busid */ - return drmOpenDevice(strtol(devstring, NULL, 0),i); + return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER); } } } diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 230f54c..d6e9882 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -49,6 +49,7 @@ #define DRM_DIR_NAME "/dev/dri" #define DRM_DEV_NAME "%s/card%d" +#define DRM_CONTROL_DEV_NAME "%s/controlD%d" #define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */ #define DRM_ERR_NO_DEVICE (-1001) diff --git a/tests/dristat.c b/tests/dristat.c index 8985316..48c3b51 100644 --- a/tests/dristat.c +++ b/tests/dristat.c @@ -263,7 +263,7 @@ int main(int argc, char **argv) for (i = 0; i < 16; i++) if (!minor || i == minor) { sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i); - fd = drmOpenMinor(i, 1); + fd = drmOpenMinor(i, 1, DRM_NODE_RENDER); if (fd >= 0) { printf("%s\n", buf); if (mask & DRM_BUSID) getbusid(fd); commit 8d6e3c208f8090ccc32ef3a38c58f2aca7f4be2a Author: Dave Airlie <ai...@re...> Date: Wed Jan 9 16:43:51 2008 +1100 allow control getversion diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index bba4d62..4ecea67 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -56,7 +56,7 @@ static int drm_version(struct drm_device *dev, void *data, /** Ioctl table */ static struct drm_ioctl_desc drm_ioctls[] = { - DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), + DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), commit ebbc2e0a2e19f5e0fdc06af0951d7fc2cc9ddcbe Author: Dave Airlie <ai...@re...> Date: Wed Jan 9 16:31:37 2008 +1100 add control ioctls diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 5bc4887..2f0791c 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -302,6 +302,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, #define DRM_AUTH 0x1 #define DRM_MASTER 0x2 #define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 // allow ioctl to operate on control node struct drm_ioctl_desc { unsigned int cmd; diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 58beec6..bba4d62 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -117,19 +117,19 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0), DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETOUTPUT, drm_mode_getoutput, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY), - - DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_output_property_set_ioctl, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETOUTPUT, drm_mode_getoutput, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + + DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_output_property_set_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY | DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), @@ -628,6 +628,7 @@ long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retcode = -EINVAL; goto err_i1; } + #if 0 /* * This check is disabled, because driver private ioctl->cmd @@ -658,7 +659,8 @@ long drm_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retcode = -EINVAL; } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) || - ((ioctl->flags & DRM_MASTER) && !file_priv->master)) { + ((ioctl->flags & DRM_MASTER) && !file_priv->master) || + ((!(ioctl->flags & DRM_CONTROL_ALLOW)) && (file_priv->minor->type == DRM_MINOR_CONTROL)) ) { retcode = -EACCES; } else { retcode = func(dev, kdata, file_priv); commit 135f51306b08f9863d77ac85b69989288c62f147 Author: Dave Airlie <ai...@re...> Date: Wed Jan 9 16:21:56 2008 +1100 drm: only call suspend/resume on control node diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c index a56e995..114e355 100644 --- a/linux-core/drm_sysfs.c +++ b/linux-core/drm_sysfs.c @@ -36,8 +36,9 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state) printk(KERN_ERR "%s\n", __FUNCTION__); - if (drm_dev->driver->suspend) - return drm_dev->driver->suspend(drm_dev); + if (drm_minor->type == DRM_MINOR_CONTROL) + if (drm_dev->driver->suspend) + return drm_dev->driver->suspend(drm_dev); return 0; } @@ -54,8 +55,9 @@ static int drm_sysfs_resume(struct device *dev) struct drm_minor *drm_minor = to_drm_minor(dev); struct drm_device *drm_dev = drm_minor->dev; - if (drm_dev->driver->resume) - return drm_dev->driver->resume(drm_dev); + if (drm_minor->type == DRM_MINOR_CONTROL) + if (drm_dev->driver->resume) + return drm_dev->driver->resume(drm_dev); return 0; } @@ -168,7 +170,7 @@ int drm_sysfs_device_add(struct drm_minor *minor) minor->kdev.release = drm_sysfs_device_release; minor->kdev.devt = minor->device; if (minor->type == DRM_MINOR_CONTROL) - minor_str = "controlD%d"; + minor_str = "controlD%d"; else minor_str = "card%d"; |
From: <al...@ke...> - 2008-03-05 17:09:12
|
linux-core/drm_crtc.c | 28 +++++++++++++++++----------- linux-core/drm_edid.c | 28 ++++++++++++++++++---------- tests/modedemo/demo.c | 16 +++++++++++++--- 3 files changed, 48 insertions(+), 24 deletions(-) New commits: commit fef1c93aa87a1ccbc473749a7e42557fc90a1fca Author: Alan Hourihane <alanh@localhost.(none)> Date: Wed Mar 5 10:33:57 2008 +0000 build fix diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index dfa0987..be49190 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -420,14 +420,14 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, int saved_x, saved_y; bool didLock = false; struct drm_output *output; + bool ret = true; adjusted_mode = drm_mode_duplicate(dev, mode); crtc->enabled = drm_crtc_in_use(crtc); - if (!crtc->enabled) { + if (!crtc->enabled) return true; - } didLock = crtc->funcs->lock(crtc); commit b87c7ff79ee88ec39a285bc17bd2996252b9fd48 Author: Alan Hourihane <alanh@localhost.(none)> Date: Wed Mar 5 10:33:16 2008 +0000 Add property info. fix bo handle diff --git a/tests/modedemo/demo.c b/tests/modedemo/demo.c index 00020bd..83a33aa 100644 --- a/tests/modedemo/demo.c +++ b/tests/modedemo/demo.c @@ -429,7 +429,7 @@ void demoUpdateRes(struct demo_driver *driver) int demoFindConnectedOutputs(struct demo_driver *driver, drmModeOutputPtr *out, size_t max_out) { int count = 0; - int i; + int i,j; int fd = driver->fd; drmModeResPtr res = driver->res; @@ -441,10 +441,20 @@ int demoFindConnectedOutputs(struct demo_driver *driver, drmModeOutputPtr *out, if (!output) continue; - if (output->connection != DRM_MODE_CONNECTED) { + if (output->connection == DRM_MODE_DISCONNECTED) { drmModeFreeOutput(output); continue; } + + for (j = 0; j < output->count_props; j++) { + drmModePropertyPtr prop; + + prop = drmModeGetProperty(fd, output->props[j]); + + printf("Property: %s\n",prop->name); + if (prop->count_enums) + printf("%s\n",prop->enums[output->prop_values[j]].name); + } out[count++] = output; } @@ -483,7 +493,7 @@ drmModeFBPtr createFB(int fd, drmModeResPtr res) goto err; } - ret = drmModeAddFB(fd, SIZE_X, SIZE_Y, 32, 32, PITCH * 4, bo->handle, &fb); + ret = drmModeAddFB(fd, SIZE_X, SIZE_Y, 32, 32, PITCH * 4, bo.handle, &fb); if (ret) goto err_bo; commit 1a959a2095aef397ea14a6f6cbdf2a035ec0eb5c Author: Alan Hourihane <alanh@localhost.(none)> Date: Tue Mar 4 17:53:04 2008 +0000 Check mode before adding to EDID diff --git a/linux-core/drm_edid.c b/linux-core/drm_edid.c index 41aa8f5..9762567 100644 --- a/linux-core/drm_edid.c +++ b/linux-core/drm_edid.c @@ -223,8 +223,10 @@ static int add_established_modes(struct drm_output *output, struct edid *edid) if (est_bits & (1<<i)) { struct drm_display_mode *newmode; newmode = drm_mode_duplicate(dev, &edid_est_modes[i]); - drm_mode_probed_add(output, newmode); - modes++; + if (newmode) { + drm_mode_probed_add(output, newmode); + modes++; + } } return modes; @@ -251,8 +253,10 @@ static int add_standard_modes(struct drm_output *output, struct edid *edid) continue; newmode = drm_mode_std(dev, &edid->standard_timings[i]); - drm_mode_probed_add(output, newmode); - modes++; + if (newmode) { + drm_mode_probed_add(output, newmode); + modes++; + } } return modes; @@ -283,11 +287,13 @@ static int add_detailed_info(struct drm_output *output, struct edid *edid) if (timing->pixel_clock) { newmode = drm_mode_detailed(dev, timing); /* First detailed mode is preferred */ - if (i == 0 && edid->preferred_timing) - newmode->type |= DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(output, newmode); + if (newmode) { + if (i == 0 && edid->preferred_timing) + newmode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(output, newmode); - modes++; + modes++; + } continue; } @@ -312,8 +318,10 @@ static int add_detailed_info(struct drm_output *output, struct edid *edid) std = &data->data.timings[j]; newmode = drm_mode_std(dev, std); - drm_mode_probed_add(output, newmode); - modes++; + if (newmode) { + drm_mode_probed_add(output, newmode); + modes++; + } } break; default: commit 8bfe29d9e44690a3896406acb25ca654dfad054d Author: Alan Hourihane <alanh@localhost.(none)> Date: Tue Mar 4 17:52:37 2008 +0000 Use ARRAY_SIZE diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 5f93275..dfa0987 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -735,20 +735,20 @@ static int drm_mode_create_standard_output_properties(struct drm_device *dev) "EDID", 0); dev->mode_config.dpms_property = - drm_property_create(dev, DRM_MODE_PROP_ENUM, "DPMS", 4); - + drm_property_create(dev, DRM_MODE_PROP_ENUM, + "DPMS", ARRAY_SIZE(drm_dpms_enum_list)); for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++) drm_property_add_enum(dev->mode_config.dpms_property, i, drm_dpms_enum_list[i].type, drm_dpms_enum_list[i].name); dev->mode_config.connector_type_property = drm_property_create(dev, DRM_MODE_PROP_ENUM | DRM_MODE_PROP_IMMUTABLE, - "Connector Type", 10); + "Connector Type", ARRAY_SIZE(drm_conn_enum_list)); for (i = 0; i < ARRAY_SIZE(drm_conn_enum_list); i++) drm_property_add_enum(dev->mode_config.connector_type_property, i, drm_conn_enum_list[i].type, drm_conn_enum_list[i].name); dev->mode_config.connector_num_property = drm_property_create(dev, DRM_MODE_PROP_RANGE | DRM_MODE_PROP_IMMUTABLE, - "Connector ID", 2); + "Connector ID", 2); dev->mode_config.connector_num_property->values[0] = 0; dev->mode_config.connector_num_property->values[1] = 20; @@ -783,7 +783,6 @@ static int drm_mode_create_standard_output_properties(struct drm_device *dev) dev->mode_config.tv_bottom_margin_property->values[0] = 0; dev->mode_config.tv_bottom_margin_property->values[1] = 100; - return 0; } commit 3ea1902be993e88c068ce67355e2b3d253d1c9f2 Author: Alan Hourihane <alanh@localhost.(none)> Date: Tue Mar 4 17:51:56 2008 +0000 propogate failed fixups back up diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 345569b..5f93275 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -458,12 +458,12 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, if (output->crtc != crtc) continue; - if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) { + if (!(ret = output->funcs->mode_fixup(output, mode, adjusted_mode))) { goto done; } } - if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) { + if (!(ret = crtc->funcs->mode_fixup(crtc, mode, adjusted_mode))) { goto done; } @@ -517,10 +517,16 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, // drm_crtc_set_screen_sub_pixel_order(dev); done: + if (!ret) { + crtc->mode = saved_mode; + crtc->x = saved_x; + crtc->y = saved_y; + } + if (didLock) crtc->funcs->unlock (crtc); - return true; + return ret; } EXPORT_SYMBOL(drm_crtc_set_mode); commit 5662934ee467c3a29f9551a40fc7b2f6ee16280a Author: Alan Hourihane <alanh@localhost.(none)> Date: Tue Mar 4 17:50:59 2008 +0000 Fix connector description table diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 1a4624c..345569b 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -48,7 +48,8 @@ static struct drm_prop_enum_list drm_dpms_enum_list[] = { DPMSModeOff, "Off" } }; static struct drm_prop_enum_list drm_conn_enum_list[] = -{ { ConnectorVGA, "VGA" }, +{ { ConnectorUnknown, "Unknown" }, + { ConnectorVGA, "VGA" }, { ConnectorDVII, "DVI-I" }, { ConnectorDVID, "DVI-D" }, { ConnectorDVIA, "DVI-A" }, |
From: <ai...@ke...> - 2008-05-08 06:19:14
|
libdrm/xf86drmMode.c | 21 +++++++++++++++ libdrm/xf86drmMode.h | 6 ++++ linux-core/drm_crtc.c | 60 +++++++++++++++++++++++++++++++++++++++++++-- linux-core/drm_crtc.h | 3 +- linux-core/drm_drv.c | 2 + linux-core/intel_display.c | 9 +++++- linux-core/intel_fb.c | 8 +++++- shared-core/drm.h | 1 shared-core/i915_irq.c | 37 ++++++++++++++++----------- 9 files changed, 126 insertions(+), 21 deletions(-) New commits: commit 2a78ad22647933aa8842d534bce6495ff93fbf76 Author: Dave Airlie <ai...@li...> Date: Thu May 8 16:14:33 2008 +1000 i915: fix vbl swap for multi-master patch from F9 tree diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 0ee0c44..ea2c88a 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -198,9 +198,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) continue; - master_priv = vbl_swap->minor->master->driver_priv; - sarea_priv = master_priv->sarea_priv; - list_del(list); dev_priv->swaps_pending--; drm_vblank_put(dev, pipe); @@ -249,16 +246,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) i915_kernel_lost_context(dev); - upper[0] = upper[1] = 0; - slice[0] = max(sarea_priv->planeA_h / nhits, 1); - slice[1] = max(sarea_priv->planeB_h / nhits, 1); - lower[0] = sarea_priv->planeA_y + slice[0]; - lower[1] = sarea_priv->planeB_y + slice[0]; - - offsets[0] = sarea_priv->front_offset; - offsets[1] = sarea_priv->back_offset; - offsets[2] = sarea_priv->third_offset; - num_pages = sarea_priv->third_handle ? 3 : 2; DRM_SPINLOCK(&dev->drw_lock); @@ -272,8 +259,6 @@ static void i915_vblank_tasklet(struct drm_device *dev) upper[1] = lower[1], lower[1] += slice[1]) { int init_drawrect = 1; - if (i == nhits) - lower[0] = lower[1] = sarea_priv->height; list_for_each(hit, &hits) { struct drm_i915_vbl_swap *swap_hit = @@ -282,6 +267,24 @@ static void i915_vblank_tasklet(struct drm_device *dev) int num_rects, plane, front, back; unsigned short top, bottom; + sarea_priv = master_priv->sarea_priv; + + upper[0] = upper[1] = 0; + slice[0] = max(sarea_priv->planeA_h / nhits, 1); + slice[1] = max(sarea_priv->planeB_h / nhits, 1); + lower[0] = sarea_priv->planeA_y + slice[0]; + lower[1] = sarea_priv->planeB_y + slice[0]; + + offsets[0] = sarea_priv->front_offset; + offsets[1] = sarea_priv->back_offset; + offsets[2] = sarea_priv->third_offset; + num_pages = sarea_priv->third_handle ? 3 : 2; + if (i == nhits) + lower[0] = lower[1] = sarea_priv->height; + + pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) | + (cpp << 23) | (1 << 24); + drw = drm_get_drawable_info(dev, swap_hit->drw_id); if (!drw) @@ -294,6 +297,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) continue; } + master_priv = swap_hit->minor->master->driver_priv; + if (init_drawrect) { int width = sarea_priv->width; int height = sarea_priv->height; @@ -332,6 +337,8 @@ static void i915_vblank_tasklet(struct drm_device *dev) (2 * plane)) & 0x3; back = (front + 1) % num_pages; + + for (num_rects = drw->num_rects; num_rects--; rect++) { int y1 = max(rect->y1, top); int y2 = min(rect->y2, bottom); commit 442e12412396280eb5164d7b8f6792969c2cf6a0 Author: Dave Airlie <ai...@li...> Date: Thu May 8 16:11:25 2008 +1000 drm: check for NULL fb here, shouldn't happen but avoid oops for now diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 63491b6..7df1525 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -754,7 +754,12 @@ EXPORT_SYMBOL(intelfb_probe); int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc) { struct drm_framebuffer *fb = crtc->fb; - struct fb_info *info = fb->fbdev; + struct fb_info *info; + + if (!fb) + return -EINVAL; + + info = fb->fbdev; if (info) { unregister_framebuffer(info); commit 19abd5c1ac3456e67241fbd2d8cd08148d6de9f9 Author: Dave Airlie <ai...@li...> Date: Thu May 8 16:10:26 2008 +1000 drm: set crtc->fb to NULL diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 7c4b063..63491b6 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -763,6 +763,7 @@ int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc) drm_framebuffer_destroy(fb); framebuffer_release(info); } + crtc->fb = NULL; return 0; } EXPORT_SYMBOL(intelfb_remove); commit 74a49aea6104ebea7525a04760ef21646a3ffaf4 Author: Dave Airlie <ai...@li...> Date: Thu May 8 16:10:06 2008 +1000 intel: set correct limits on screen width/height from DDX diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 46abb90..f66570c 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -1448,8 +1448,13 @@ void intel_modeset_init(struct drm_device *dev) dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; - dev->mode_config.max_width = 4096; - dev->mode_config.max_height = 4096; + if (IS_I965G(dev)) { + dev->mode_config.max_width = 8192; + dev->mode_config.max_height = 8192; + } else { + dev->mode_config.max_width = 2048; + dev->mode_config.max_height = 2048; + } /* set memory base */ if (IS_I9XX(dev)) commit 576cba86b704c0de484ba852b8dce5b24d683f7e Author: Dave Airlie <ai...@li...> Date: Thu May 8 16:09:45 2008 +1000 drm: fix replacefb to change fb properties diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 60255f5..2d1c806 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -2551,6 +2551,11 @@ int drm_mode_replacefb(struct drm_device *dev, if (fb->bo->type == drm_bo_type_kernel) DRM_ERROR("the bo should not be a kernel bo\n"); + fb->width = r->width; + fb->height = r->height; + fb->pitch = r->pitch; + fb->bits_per_pixel = r->bpp; + fb->depth = r->depth; fb->bo = bo; /* find all crtcs connected to this fb */ commit ed072ed075ec431b0746ac1aa8bad5f687d75d8c Author: Dave Airlie <ai...@li...> Date: Thu May 8 14:01:24 2008 +1000 drm_mode: initial replacefb implemenation diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index 605377d..ae15fd6 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -608,3 +608,24 @@ int drmCheckModesettingSupported(const char *busid) return -ENOSYS; } + +int drmModeReplaceFB(int fd, uint32_t buffer_id, + uint32_t width, uint32_t height, uint8_t depth, + uint8_t bpp, uint32_t pitch, uint32_t bo_handle) +{ + struct drm_mode_fb_cmd f; + int ret; + + f.width = width; + f.height = height; + f.pitch = pitch; + f.bpp = bpp; + f.depth = depth; + f.handle = bo_handle; + f.buffer_id = buffer_id; + + if ((ret = ioctl(fd, DRM_IOCTL_MODE_REPLACEFB, &f))) + return ret; + + return 0; +} diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h index e5a6ee9..5171b59 100644 --- a/libdrm/xf86drmMode.h +++ b/libdrm/xf86drmMode.h @@ -184,6 +184,12 @@ extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, */ extern int drmModeRmFB(int fd, uint32_t bufferId); +/** + * Replace a framebuffer object with a new one - for resizing the screen. + */ +extern int drmModeReplaceFB(int fd, uint32_t buffer_id, + uint32_t width, uint32_t height, uint8_t depth, + uint8_t bpp, uint32_t pitch, uint32_t bo_handle); /* * Crtc functions diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 1e5195d..60255f5 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1879,8 +1879,8 @@ out: int drm_mode_rmfb(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_framebuffer *fb = 0; - struct drm_framebuffer *fbl = 0; + struct drm_framebuffer *fb = NULL; + struct drm_framebuffer *fbl = NULL; uint32_t *id = data; int ret = 0; int found = 0; @@ -2513,3 +2513,54 @@ out: return ret; } + +int drm_mode_replacefb(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_fb_cmd *r = data; + struct drm_framebuffer *fb; + struct drm_crtc *crtc; + struct drm_buffer_object *bo; + int found = 0; + struct drm_framebuffer *fbl = NULL; + int ret = 0; + /* right replace the current bo attached to this fb with a new bo */ + mutex_lock(&dev->mode_config.mutex); + ret = drm_get_buffer_object(dev, &bo, r->handle); + if (ret || !bo) { + ret = -EINVAL; + goto out; + } + + fb = idr_find(&dev->mode_config.crtc_idr, r->buffer_id); + if (!fb || (r->buffer_id != fb->id)) { + ret = -EINVAL; + goto out; + } + + list_for_each_entry(fbl, &file_priv->fbs, filp_head) + if (fb == fbl) + found = 1; + + if (!found) { + DRM_ERROR("tried to replace an fb we didn't own\n"); + ret = -EINVAL; + goto out; + } + + if (fb->bo->type == drm_bo_type_kernel) + DRM_ERROR("the bo should not be a kernel bo\n"); + + fb->bo = bo; + + /* find all crtcs connected to this fb */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (crtc->fb->id == r->buffer_id) { + crtc->funcs->mode_set_base(crtc, crtc->x, crtc->y); + } + } +out: + mutex_unlock(&dev->mode_config.mutex); + return ret; + +} diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 20b1ea0..64e7e51 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -649,6 +649,7 @@ extern int drm_mode_output_property_set_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_hotplug_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); - +extern int drm_mode_replacefb(struct drm_device *dev, + void *data, struct drm_file *file_priv); #endif /* __DRM_CRTC_H__ */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 649d4ca..82a9c19 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -141,6 +141,8 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_HOTPLUG, drm_mode_hotplug_ioctl, DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_WAIT_HOTPLUG, drm_wait_hotplug, 0), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_REPLACEFB, drm_mode_replacefb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl, diff --git a/shared-core/drm.h b/shared-core/drm.h index c847b4e..eb2033c 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1276,6 +1276,7 @@ struct drm_mode_hotplug { #define DRM_IOCTL_MODE_HOTPLUG DRM_IOWR(0xAD, struct drm_mode_hotplug) #define DRM_IOCTL_WAIT_HOTPLUG DRM_IOWR(0xAE, union drm_wait_hotplug) +#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xAF, struct drm_mode_fb_cmd) /*@}*/ /** |
From: <mad...@ke...> - 2008-08-14 18:45:06
|
linux-core/drm_agpsupport.c | 4 - linux-core/drm_compat.c | 99 ++++++++++++++++++++++++++++++++++++++++++ linux-core/drm_compat.h | 3 + linux-core/drm_crtc_helper.c | 2 linux-core/drm_ttm.c | 6 ++ linux-core/drm_vm.c | 35 +++++++------- linux-core/nouveau_sgdma.c | 9 +++ linux-core/nv50_kms_wrapper.c | 4 - shared-core/nouveau_object.c | 6 ++ 9 files changed, 144 insertions(+), 24 deletions(-) New commits: commit 9c7137483d1ef47eaff99f98b3c4e552c726e5d9 Author: Maarten Maathuis <mad...@gm...> Date: Thu Aug 14 20:42:28 2008 +0200 nouveau: fix typo diff --git a/linux-core/nouveau_sgdma.c b/linux-core/nouveau_sgdma.c index b967b6a..eeecbc9 100644 --- a/linux-core/nouveau_sgdma.c +++ b/linux-core/nouveau_sgdma.c @@ -49,7 +49,8 @@ nouveau_sgdma_populate(struct drm_ttm_backend *be, unsigned long num_pages, NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) - if (pci_dma_mapping_error(be->dev->pdev, nvbe->pagelist[d])) { + if (pci_dma_mapping_error(nvbe->dev->pdev, +nvbe->pagelist[d])) { #else if (pci_dma_mapping_error(nvbe->pagelist[d])) { #endif commit a8a7106cdae481d9b10e3eed61f928f7e4add344 Author: Maarten Maathuis <mad...@gm...> Date: Thu Aug 14 20:19:28 2008 +0200 nouveau: compile with 2.6.27 diff --git a/linux-core/nouveau_sgdma.c b/linux-core/nouveau_sgdma.c index cc4d5a9..b967b6a 100644 --- a/linux-core/nouveau_sgdma.c +++ b/linux-core/nouveau_sgdma.c @@ -48,7 +48,11 @@ nouveau_sgdma_populate(struct drm_ttm_backend *be, unsigned long num_pages, page, o, NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) + if (pci_dma_mapping_error(be->dev->pdev, nvbe->pagelist[d])) { +#else if (pci_dma_mapping_error(nvbe->pagelist[d])) { +#endif be->func->clear(be); DRM_ERROR("pci_map_page failed\n"); return -EINVAL; @@ -223,7 +227,11 @@ nouveau_sgdma_init(struct drm_device *dev) dev_priv->gart_info.sg_dummy_page = alloc_page(GFP_KERNEL|__GFP_DMA32); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) + set_page_locked(dev_priv->gart_info.sg_dummy_page); +#else SetPageLocked(dev_priv->gart_info.sg_dummy_page); +#endif dev_priv->gart_info.sg_dummy_bus = pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); diff --git a/linux-core/nv50_kms_wrapper.c b/linux-core/nv50_kms_wrapper.c index bf747a4..1320e5e 100644 --- a/linux-core/nv50_kms_wrapper.c +++ b/linux-core/nv50_kms_wrapper.c @@ -944,7 +944,7 @@ static enum drm_connector_status nv50_kms_connector_detect(struct drm_connector hpd_detect = connector->hpd_detect(connector); /* load detect */ - output = connector->to_output(connector, FALSE); /* analog */ + output = connector->to_output(connector, false); /* analog */ if (output && output->detect) load_detect = output->detect(output); @@ -1034,7 +1034,7 @@ static void nv50_kms_connector_fill_modes(struct drm_connector *drm_connector, u rval = drm_add_edid_modes(drm_connector, edid); /* Only update when relevant and when detect couldn't determine type. */ - nv50_kms_connector_set_digital(drm_connector, edid->digital ? 1 : 0, FALSE); + nv50_kms_connector_set_digital(drm_connector, edid->digital ? 1 : 0, false); kfree(edid); } diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 894e733..a49befe 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -738,8 +738,12 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); - +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) + /* Not a 100% sure this is the right kdev in all cases. */ + if (dma_mapping_error(&dev->primary->kdev, dev->sg->busaddr[idx])) { +#else if (dma_mapping_error(dev->sg->busaddr[idx])) { +#endif return -ENOMEM; } } commit 8122872739723422726adaa7e691e95606a6ea22 Author: Maarten Maathuis <mad...@gm...> Date: Thu Aug 14 19:38:21 2008 +0200 s/TRUE/true diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c index ec76aa9..6f16dad 100644 --- a/linux-core/drm_crtc_helper.c +++ b/linux-core/drm_crtc_helper.c @@ -95,7 +95,7 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector, ui } - drm_mode_prune_invalid(dev, &connector->modes, TRUE); + drm_mode_prune_invalid(dev, &connector->modes, true); if (list_empty(&connector->modes)) { struct drm_display_mode *stdmode; commit 05b648c5a4b76f74f5855cd63bc5d3eb2e0ced3a Author: Maarten Maathuis <mad...@gm...> Date: Thu Aug 14 19:35:55 2008 +0200 linux: on_each_cpu has 3 args on 2.6.27 diff --git a/linux-core/drm_ttm.c b/linux-core/drm_ttm.c index 80a8ff5..054a7ce 100644 --- a/linux-core/drm_ttm.c +++ b/linux-core/drm_ttm.c @@ -72,7 +72,11 @@ void drm_ttm_cache_flush(struct page *pages[], unsigned long num_pages) return; } #endif - if (on_each_cpu(drm_ttm_ipi_handler, NULL, 1, 1) != 0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) + if (on_each_cpu(drm_ttm_ipi_handler, NULL, 1)) +#else + if (on_each_cpu(drm_ttm_ipi_handler, NULL, 1, 1) != 0) +#endif DRM_ERROR("Timed out waiting for drm cache flush.\n"); } EXPORT_SYMBOL(drm_ttm_cache_flush); commit 06dd3d5cec08396b706b99e01ff301b36c26ea24 Author: Maarten Maathuis <mad...@gm...> Date: Thu Aug 14 19:34:30 2008 +0200 s/TRUE/true s/FALSE/false diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c index 0aa94a7..8066371 100644 --- a/linux-core/drm_agpsupport.c +++ b/linux-core/drm_agpsupport.c @@ -554,7 +554,7 @@ static int drm_agp_bind_ttm(struct drm_ttm_backend *backend, int snooped = (bo_mem->flags & DRM_BO_FLAG_CACHED) && !(bo_mem->flags & DRM_BO_FLAG_CACHED_MAPPED); DRM_DEBUG("drm_agp_bind_ttm\n"); - mem->is_flushed = TRUE; + mem->is_flushed = true; mem->type = AGP_USER_MEMORY; /* CACHED MAPPED implies not snooped memory */ if (snooped) @@ -653,7 +653,7 @@ struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev) agp_be->mem = NULL; agp_be->bridge = dev->agp->bridge; - agp_be->populated = FALSE; + agp_be->populated = false; agp_be->backend.func = &agp_ttm_backend; agp_be->backend.dev = dev; commit a28516ec936501407a2b140652b885241b0916e5 Author: Dave Airlie <ai...@re...> Date: Thu Jul 31 13:12:36 2008 +1000 drm: add fault handler support so as to be more like possible upstream diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index dbb3157..8d9d8bf 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -808,3 +808,102 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, EXPORT_SYMBOL(kmap_atomic_prot_pfn); #endif +#ifdef DRM_FULL_MM_COMPAT +#ifdef DRM_NO_FAULT +unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma, + unsigned long address) +{ + struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data; + unsigned long page_offset; + struct page *page = NULL; + struct drm_ttm *ttm; + struct drm_device *dev; + unsigned long pfn; + int err; + unsigned long bus_base; + unsigned long bus_offset; + unsigned long bus_size; + unsigned long ret = NOPFN_REFAULT; + + if (address > vma->vm_end) + return NOPFN_SIGBUS; + + dev = bo->dev; + err = drm_bo_read_lock(&dev->bm.bm_lock, 1); + if (err) + return NOPFN_REFAULT; + + err = mutex_lock_interruptible(&bo->mutex); + if (err) { + drm_bo_read_unlock(&dev->bm.bm_lock); + return NOPFN_REFAULT; + } + + err = drm_bo_wait(bo, 0, 1, 0, 1); + if (err) { + ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT; + bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED; + goto out_unlock; + } + + bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED; + + /* + * If buffer happens to be in a non-mappable location, + * move it to a mappable. + */ + + if (!(bo->mem.flags & DRM_BO_FLAG_MAPPABLE)) { + uint32_t new_flags = bo->mem.proposed_flags | + DRM_BO_FLAG_MAPPABLE | + DRM_BO_FLAG_FORCE_MAPPABLE; + err = drm_bo_move_buffer(bo, new_flags, 0, 0); + if (err) { + ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT; + goto out_unlock; + } + } + + err = drm_bo_pci_offset(dev, &bo->mem, &bus_base, &bus_offset, + &bus_size); + + if (err) { + ret = NOPFN_SIGBUS; + goto out_unlock; + } + + page_offset = (address - vma->vm_start) >> PAGE_SHIFT; + + if (bus_size) { + struct drm_mem_type_manager *man = &dev->bm.man[bo->mem.mem_type]; + + pfn = ((bus_base + bus_offset) >> PAGE_SHIFT) + page_offset; + vma->vm_page_prot = drm_io_prot(man->drm_bus_maptype, vma); + } else { + ttm = bo->ttm; + + drm_ttm_fixup_caching(ttm); + page = drm_ttm_get_page(ttm, page_offset); + if (!page) { + ret = NOPFN_OOM; + goto out_unlock; + } + pfn = page_to_pfn(page); + vma->vm_page_prot = (bo->mem.flags & DRM_BO_FLAG_CACHED) ? + vm_get_page_prot(vma->vm_flags) : + drm_io_prot(_DRM_TTM, vma); + } + + err = vm_insert_pfn(vma, address, pfn); + if (err) { + ret = (err != -EAGAIN) ? NOPFN_OOM : NOPFN_REFAULT; + goto out_unlock; + } +out_unlock: + BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED); + mutex_unlock(&bo->mutex); + drm_bo_read_unlock(&dev->bm.bm_lock); + return ret; +} +#endif +#endif diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h index f35821b..679a450 100644 --- a/linux-core/drm_compat.h +++ b/linux-core/drm_compat.h @@ -319,6 +319,9 @@ extern int drm_bo_map_bound(struct vm_area_struct *vma); /* fixme when functions are upstreamed - upstreamed for 2.6.23 */ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) #define DRM_IDR_COMPAT_FN +#define DRM_NO_FAULT +extern unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma, + unsigned long address); #endif #ifdef DRM_IDR_COMPAT_FN int idr_for_each(struct idr *idp, diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c index 6618c0a..0d5242d 100644 --- a/linux-core/drm_vm.c +++ b/linux-core/drm_vm.c @@ -685,8 +685,8 @@ EXPORT_SYMBOL(drm_mmap); * \c Pagefault method for buffer objects. * * \param vma Virtual memory area. - * \param address File offset. - * \return Error or refault. The pfn is manually inserted. + * \param vmf vm fault data + * \return Error or VM_FAULT_NOPAGE:. The pfn is manually inserted. * * It's important that pfns are inserted while holding the bo->mutex lock. * otherwise we might race with unmap_mapping_range() which is always @@ -699,8 +699,8 @@ EXPORT_SYMBOL(drm_mmap); */ #ifdef DRM_FULL_MM_COMPAT -static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma, - unsigned long address) +static int drm_bo_vm_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) { struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data; unsigned long page_offset; @@ -712,25 +712,22 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma, unsigned long bus_base; unsigned long bus_offset; unsigned long bus_size; - unsigned long ret = NOPFN_REFAULT; - - if (address > vma->vm_end) - return NOPFN_SIGBUS; + unsigned long ret = VM_FAULT_NOPAGE; dev = bo->dev; err = drm_bo_read_lock(&dev->bm.bm_lock, 1); if (err) - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; err = mutex_lock_interruptible(&bo->mutex); if (err) { drm_bo_read_unlock(&dev->bm.bm_lock); - return NOPFN_REFAULT; + return VM_FAULT_NOPAGE; } err = drm_bo_wait(bo, 0, 1, 0, 1); if (err) { - ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT; + ret = (err != -EAGAIN) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE; bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED; goto out_unlock; } @@ -748,7 +745,7 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma, DRM_BO_FLAG_FORCE_MAPPABLE; err = drm_bo_move_buffer(bo, new_flags, 0, 0); if (err) { - ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT; + ret = (err != -EAGAIN) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE; goto out_unlock; } } @@ -757,11 +754,11 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma, &bus_size); if (err) { - ret = NOPFN_SIGBUS; + ret = VM_FAULT_SIGBUS; goto out_unlock; } - page_offset = (address - vma->vm_start) >> PAGE_SHIFT; + page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start) >> PAGE_SHIFT; if (bus_size) { struct drm_mem_type_manager *man = &dev->bm.man[bo->mem.mem_type]; @@ -774,7 +771,7 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma, drm_ttm_fixup_caching(ttm); page = drm_ttm_get_page(ttm, page_offset); if (!page) { - ret = NOPFN_OOM; + ret = VM_FAULT_OOM; goto out_unlock; } pfn = page_to_pfn(page); @@ -783,9 +780,9 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma, drm_io_prot(_DRM_TTM, vma); } - err = vm_insert_pfn(vma, address, pfn); + err = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); if (err) { - ret = (err != -EAGAIN) ? NOPFN_OOM : NOPFN_REFAULT; + ret = (err != -EAGAIN) ? VM_FAULT_OOM : VM_FAULT_NOPAGE; goto out_unlock; } out_unlock: @@ -849,8 +846,12 @@ static void drm_bo_vm_close(struct vm_area_struct *vma) static struct vm_operations_struct drm_bo_vm_ops = { #ifdef DRM_FULL_MM_COMPAT +#ifdef DRM_NO_FAULT .nopfn = drm_bo_vm_nopfn, #else + .fault = drm_bo_vm_fault, +#endif +#else #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) .nopfn = drm_bo_vm_nopfn, #else |