From e6e4946c82ab6f63143df7f49f38fa56f7e8980a Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 16 Apr 2007 16:23:05 +0200 Subject: 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. --- libdrm/xf86drm.c | 14 +++++++------- linux-core/drm_bo.c | 28 ++++++++++++---------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index a815ed7a..2473162b 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2814,7 +2814,7 @@ int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint, } 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, unsigned flags, unsigned mask, } 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, unsigned flags, unsigned fenceHandle) 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, unsigned hint) } 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 17d6fbc0..b08700a3 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1024,30 +1024,23 @@ static int drm_bo_wait_unfenced(drm_buffer_object_t * bo, int no_wait, 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, -- cgit v1.2.3 From e91ceff6c98661bfae5db008e024b71a8a0f5129 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Apr 2007 08:46:45 +0200 Subject: Add a code comment. --- linux-core/drm_bo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index b08700a3..4ecfb79c 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 = -- cgit v1.2.3 From e805ca959dbef85ac7b508639a64832a7995703a Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Apr 2007 08:58:23 +0200 Subject: via: Make sure we flush write-combining using a follow-up read. --- shared-core/via_dma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shared-core/via_dma.c b/shared-core/via_dma.c index 8c5a5c64..c73634e4 100644 --- a/shared-core/via_dma.c +++ b/shared-core/via_dma.c @@ -430,8 +430,10 @@ static int via_hook_segment(drm_via_private_t *dev_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_private_t * dev_priv) &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); -- cgit v1.2.3 From 5432cc4abf672ed3adb10fd5d61a6a5716089a98 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Apr 2007 10:53:19 +0200 Subject: Fix buffer object reference problems. (Reported by Dave Airlie). --- linux-core/drm_bo.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 4ecfb79c..88adfc98 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, -- cgit v1.2.3 From 5a96d59ce9d9ad5816e2d0e195afa9902445f594 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 17 Apr 2007 14:15:37 +0200 Subject: Don't always free up memory space when we unpin buffers. --- linux-core/drm_bo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 88adfc98..450e448c 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -1399,7 +1399,10 @@ static int drm_buffer_object_validate(drm_buffer_object_t * bo, } 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); -- cgit v1.2.3 From 5e6c34539694c58cd7e9dd60541fc6e2bde1a79d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 09:57:08 -0700 Subject: Add prototypes for drm_bo_init_mm and drm_buffer_object_create for use by in-kernel code. --- linux-core/drm_objects.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/linux-core/drm_objects.h b/linux-core/drm_objects.h index b3155af1..cbc0e610 100644 --- a/linux-core/drm_objects.h +++ b/linux-core/drm_objects.h @@ -423,7 +423,13 @@ typedef struct drm_bo_driver { /* * buffer objects (drm_bo.c) */ - +extern int drm_bo_init_mm(struct drm_device * dev, unsigned type, + unsigned long p_offset, unsigned long p_size); +extern int drm_buffer_object_create(struct drm_device *dev, unsigned long size, + drm_bo_type_t type, uint32_t mask, + uint32_t hint, uint32_t page_alignment, + unsigned long buffer_start, + drm_buffer_object_t ** buf_obj); extern int drm_bo_ioctl(DRM_IOCTL_ARGS); extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS); extern int drm_bo_driver_finish(struct drm_device *dev); -- cgit v1.2.3 From eeb5de059401361871e34e29c456a1feebac0b1e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 09:59:21 -0700 Subject: Cleanup whitespace, rename macro argument. --- shared-core/i915_drv.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f4343014..b0d70124 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -908,8 +908,8 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define IS_I855(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82855GM_IG) #define IS_I865G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82865_IG) -#define IS_I915G(pI810) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/ -#define IS_I915GM(pI810) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG) +#define IS_I915G(dev) (dev->pci_device == PCI_DEVICE_ID_INTEL_82915G_IG)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/ +#define IS_I915GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82915GM_IG) #define IS_I945G(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945G_IG) #define IS_I945GM(dev) ((dev)->pci_device == PCI_DEVICE_ID_INTEL_82945GM_IG) @@ -919,9 +919,11 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); (dev)->pci_device == 0x29A2) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810) || IS_I965G(pI810)) +#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \ + IS_I945GM(dev) || IS_I965G(dev)) -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) +#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \ + IS_I945GM(dev)) #define PRIMARY_RINGBUFFER_SIZE (128*1024) -- cgit v1.2.3 From 4e4d9cbeb3f52b605e46aad8ae1a947ca236079f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 10:00:37 -0700 Subject: Move initial framebuffer allocation and configuration to drm_initial_config, remove i915_driver_load fb related stuff. Add a small helper for setting up outputs. --- linux-core/drm_crtc.c | 73 +++++++++++++++++++++++++++++++++++-------------- linux-core/drm_crtc.h | 3 +- shared-core/i915_init.c | 48 ++++++-------------------------- 3 files changed, 61 insertions(+), 63 deletions(-) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index adea0309..ff989265 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1,6 +1,6 @@ #include -#include "drmP.h" #include "drm.h" +#include "drmP.h" #include "drm_crtc.h" int drm_mode_idr_get(struct drm_device *dev, void *ptr) @@ -500,6 +500,15 @@ out_err: return ret; } +static void drm_setup_output(struct drm_output *output, struct drm_crtc *crtc, + struct drm_display_mode *mode) +{ + output->crtc = crtc; + output->crtc->desired_mode = mode; + output->initial_x = 0; + output->initial_y = 0; +} + /** * drm_initial_config - setup a sane initial output configuration * @dev: DRM device @@ -510,13 +519,21 @@ out_err: * At the moment, this is a cloned configuration across all heads with * @fb as the backing store. */ -bool drm_initial_config(drm_device_t *dev, struct drm_framebuffer *fb, - bool can_grow) +bool drm_initial_config(drm_device_t *dev, bool can_grow) { /* do a hardcoded initial configuration here */ - struct drm_crtc *crtc, *vga_crtc = NULL, *dvi_crtc = NULL, + struct drm_crtc *crtc, *vga_crtc = NULL, *tmds_crtc = NULL, *lvds_crtc = NULL; - struct drm_output *output, *use_output = NULL; + struct drm_output *output; + struct drm_framebuffer *fb; + drm_buffer_object_t *fbo; + unsigned long size, bytes_per_pixel; + + fb = drm_framebuffer_create(dev); + if (!fb) { + DRM_ERROR("failed to allocate fb.\n"); + return true; + } /* bind both CRTCs to this fb */ /* only initialise one crtc to enabled state */ @@ -532,8 +549,8 @@ bool drm_initial_config(drm_device_t *dev, struct drm_framebuffer *fb, crtc->enabled = 1; crtc->desired_x = 0; crtc->desired_y = 0; - } else if (!dvi_crtc) { - dvi_crtc = crtc; + } else if (!tmds_crtc) { + tmds_crtc = crtc; crtc->enabled = 1; crtc->desired_x = 0; crtc->desired_y = 0; @@ -557,29 +574,43 @@ bool drm_initial_config(drm_device_t *dev, struct drm_framebuffer *fb, break; } if (!strncmp(output->name, "VGA", 3)) { - output->crtc = vga_crtc; DRM_DEBUG("VGA preferred mode: %s\n", des_mode->name); - output->crtc->desired_mode = des_mode; - output->initial_x = 0; - output->initial_y = 0; - use_output = output; + drm_setup_output(output, vga_crtc, des_mode); } else if (!strncmp(output->name, "TMDS", 4)) { - output->crtc = vga_crtc; DRM_DEBUG("TMDS preferred mode: %s\n", des_mode->name); - output->crtc->desired_mode = des_mode; - output->initial_x = 0; - output->initial_y = 0; + drm_setup_output(output, tmds_crtc, des_mode); } else if (!strncmp(output->name, "LVDS", 3)) { - output->crtc = lvds_crtc; DRM_DEBUG("LVDS preferred mode: %s\n", des_mode->name); - output->crtc->desired_mode = des_mode; - output->initial_x = 0; - output->initial_y = 0; + drm_setup_output(output, lvds_crtc, des_mode); } else output->crtc = NULL; - + + /* FB config is max of above desired resolutions */ + /* FIXME: per-output FBs/CRTCs */ + if (des_mode->hdisplay > fb->width) { + fb->width = des_mode->hdisplay; + fb->pitch = fb->width; + } + if (des_mode->vdisplay > fb->height) + fb->height = des_mode->vdisplay; } + /* FIXME: multiple depths */ + bytes_per_pixel = 4; + fb->bits_per_pixel = bytes_per_pixel * 8; + fb->depth = bytes_per_pixel * 8; + size = fb->width * fb->height * bytes_per_pixel; + drm_buffer_object_create(dev, size, drm_bo_type_kernel, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, + 0, 0, 0, + &fbo); + DRM_DEBUG("allocated %dx%d fb: 0x%08lx\n", fb->width, fb->height, + fbo->offset); + fb->offset = fbo->offset; + fb->bo = fbo; + drmfb_probe(dev, fb); + return false; } EXPORT_SYMBOL(drm_initial_config); diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index c02dcedc..560c38f4 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -452,8 +452,7 @@ extern int drm_mode_vrefresh(struct drm_display_mode *mode); extern void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags); extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev); -extern bool drm_initial_config(struct drm_device *dev, - struct drm_framebuffer *fb, bool cangrow); +extern bool drm_initial_config(struct drm_device *dev, bool cangrow); extern void drm_framebuffer_set_object(struct drm_device *dev, unsigned long handle); extern bool drm_set_desired_modes(struct drm_device *dev); diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 273a1116..b98f155b 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -112,13 +112,9 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size, int i915_driver_load(drm_device_t *dev, unsigned long flags) { drm_i915_private_t *dev_priv; - drm_i915_init_t init; - drm_buffer_object_t *entry; - drm_local_map_t *map; - struct drm_framebuffer *fb; unsigned long agp_size, prealloc_size; unsigned long sareapage; - int hsize, vsize, bytes_per_pixel, size, ret; + int size, ret; dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) @@ -150,6 +146,8 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) return -ENODEV; } + DRM_DEBUG("fb_base: 0x%08lx\n", dev_priv->baseaddr); + ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen, _DRM_REGISTERS, _DRM_READ_ONLY|_DRM_DRIVER, &dev_priv->mmio_map); if (ret != 0) { @@ -177,7 +175,7 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) drm_bo_driver_init(dev); i915_probe_agp(dev->pdev, &agp_size, &prealloc_size); - DRM_DEBUG("setting up %d bytes of PRIV0 space\n", prealloc_size); + DRM_DEBUG("setting up %ld bytes of PRIV0 space\n", prealloc_size); drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev_priv->baseaddr, prealloc_size >> PAGE_SHIFT); @@ -199,13 +197,14 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) dev_priv->ring.Size = size; dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - + /* FIXME: need wrapper with PCI mem checks */ ret = drm_mem_reg_ioremap(dev, &dev_priv->ring_buffer->mem, &dev_priv->ring.virtual_start); if (ret) DRM_ERROR("error mapping ring buffer: %d\n", ret); - DRM_DEBUG("ring start %08X, %08X, %08X\n", dev_priv->ring.Start, dev_priv->ring.virtual_start, dev_priv->ring.Size); + DRM_DEBUG("ring start %08lX, %p, %08lX\n", dev_priv->ring.Start, + dev_priv->ring.virtual_start, dev_priv->ring.Size); I915_WRITE(LP_RING + RING_HEAD, 0); I915_WRITE(LP_RING + RING_TAIL, 0); I915_WRITE(LP_RING + RING_START, dev_priv->ring.Start); @@ -242,46 +241,15 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); -#if 1 - /* Allocate scanout buffer and command ring */ - /* FIXME: types and other args correct? */ - hsize = 1280; - vsize = 800; - bytes_per_pixel = 4; - size = hsize * vsize * bytes_per_pixel; - drm_buffer_object_create(dev, size, drm_bo_type_kernel, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, - 0, 0, 0, - &entry); -#endif intel_modeset_init(dev); + drm_initial_config(dev, false); -#if 1 - fb = drm_framebuffer_create(dev); - if (!fb) { - DRM_ERROR("failed to allocate fb\n"); - return -EINVAL; - } - - fb->width = hsize; - fb->height = vsize; - fb->pitch = hsize; - fb->bits_per_pixel = bytes_per_pixel * 8; - fb->depth = bytes_per_pixel * 8; - fb->offset = entry->offset; - fb->bo = entry; - - drm_initial_config(dev, fb, false); - drmfb_probe(dev, fb); -#endif return 0; } int i915_driver_unload(drm_device_t *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_framebuffer *fb; if (dev_priv->status_page_dmah) { drm_pci_free(dev, dev_priv->status_page_dmah); -- cgit v1.2.3 From a45fa264f2b60185ae797f85d2084d57de49bbca Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 17 Apr 2007 22:27:46 +0200 Subject: Lvds now power up backlight on commit Now saves previous power level in prepare and sets that power level in commit, should power level be 0 it will set maximum level. --- linux-core/intel_display.c | 2 ++ linux-core/intel_lvds.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 48239329..d0a3a465 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -539,11 +539,13 @@ static void intel_crtc_commit (struct drm_crtc *crtc) void intel_output_prepare (struct drm_output *output) { + /* lvds has its own version of prepare see intel_lvds_prepare */ output->funcs->dpms(output, DPMSModeOff); } void intel_output_commit (struct drm_output *output) { + /* lvds has its own version of commit see intel_lvds_commit */ output->funcs->dpms(output, DPMSModeOn); } diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index db025417..8454bbcf 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -209,6 +209,30 @@ static bool intel_lvds_mode_fixup(struct drm_output *output, return true; } +static void intel_lvds_prepare(struct drm_output *output) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL); + dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); + + intel_lvds_set_power(dev, false); +} + +static void intel_lvds_commit( struct drm_output *output) +{ + struct drm_device *dev = output->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + if (dev_priv->backlight_duty_cycle == 0) + dev_priv->backlight_duty_cycle = + intel_lvds_get_max_backlight(dev); + + intel_lvds_set_power(dev, true); +} + static void intel_lvds_mode_set(struct drm_output *output, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -321,9 +345,9 @@ static const struct drm_output_funcs intel_lvds_output_funcs = { .restore = intel_lvds_restore, .mode_valid = intel_lvds_mode_valid, .mode_fixup = intel_lvds_mode_fixup, - .prepare = intel_output_prepare, + .prepare = intel_lvds_prepare, .mode_set = intel_lvds_mode_set, - .commit = intel_output_commit, + .commit = intel_lvds_commit, .detect = intel_lvds_detect, .get_modes = intel_lvds_get_modes, .cleanup = intel_lvds_destroy -- cgit v1.2.3 From 73b031df613b58c4462a65818b88200bed0a97de Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 17:30:46 -0700 Subject: Add framebuffer bo freeing to drm_mode_config_cleanup (seems like the best place for now). --- linux-core/drm_crtc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 1adae0d2..0fb5b9ae 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -614,8 +614,8 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, 0, 0, 0, &fbo); - DRM_DEBUG("allocated %dx%d fb: 0x%08lx\n", fb->width, fb->height, - fbo->offset); + DRM_DEBUG("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width, + fb->height, fbo->offset, fbo); fb->offset = fbo->offset; fb->bo = fbo; drmfb_probe(dev, fb); @@ -639,6 +639,12 @@ void drm_mode_config_cleanup(drm_device_t *dev) list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { drmfb_remove(dev, fb); + /* If this FB was the kernel one, free it */ + if (fb->bo->type == drm_bo_type_kernel) { + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(fb->bo); + mutex_unlock(&dev->struct_mutex); + } drm_framebuffer_destroy(fb); } } -- cgit v1.2.3 From 7c9e19ba55dcdf212845253648194115639fe7b6 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Fri, 13 Apr 2007 16:43:55 +1000 Subject: clean up ring buffer and TTM in i915_driver_unload I've commented out the framebuffer for now --- linux-core/drm_drv.c | 15 ++++++++------- shared-core/i915_init.c | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index 7bb8c659..5aa7137b 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -375,9 +375,6 @@ static void drm_cleanup(drm_device_t * dev) drm_lastclose(dev); drm_fence_manager_takedown(dev); - if (!drm_fb_loaded) - pci_disable_device(dev->pdev); - drm_ctxbitmap_cleanup(dev); if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp @@ -389,15 +386,16 @@ static void drm_cleanup(drm_device_t * dev) DRM_DEBUG("mtrr_del=%d\n", retval); } - // drm_bo_driver_finish(dev); - + if (dev->driver->unload) + dev->driver->unload(dev); + if (drm_core_has_AGP(dev) && dev->agp) { drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); dev->agp = NULL; } - if (dev->driver->unload) - dev->driver->unload(dev); + + // drm_bo_driver_finish(dev); if (dev->maplist) { drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); dev->maplist = NULL; @@ -406,6 +404,9 @@ static void drm_cleanup(drm_device_t * dev) drm_ht_remove(&dev->object_hash); } + if (!drm_fb_loaded) + pci_disable_device(dev->pdev); + drm_put_head(&dev->primary); if (drm_put_dev(dev)) DRM_ERROR("Cannot unload module\n"); diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 3e44dd54..0c9ef4d4 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -265,6 +265,7 @@ int i915_driver_unload(drm_device_t *dev) drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem, dev_priv->ring.virtual_start); + DRM_DEBUG("usage is %d\n", dev_priv->ring_buffer->usage); mutex_lock(&dev->struct_mutex); drm_bo_usage_deref_locked(dev_priv->ring_buffer); mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From 2352ec9bfab20761cc898ea40db2a7c6d53e81f3 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 18 Apr 2007 10:39:58 +1000 Subject: backout alanh's broken commit --- linux-core/intel_sdvo.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index 6f592f8a..5dbfb8eb 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -70,10 +70,9 @@ static void intel_sdvo_write_sdvox(struct drm_output *output, u32 val) int i; if (sdvo_priv->output_device == SDVOB) - bval = I915_READ(SDVOB); - else cval = I915_READ(SDVOC); - + else + bval = I915_READ(SDVOB); /* * Write the registers twice for luck. Sometimes, * writing them only once doesn't appear to 'stick'. -- cgit v1.2.3 From d20aaf485893ed11dd0d68daf63ccadd77b02213 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 18 Apr 2007 10:41:39 +1000 Subject: don't crash if no desired mode --- linux-core/drm_crtc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 0fb5b9ae..437259d5 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -572,7 +572,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) /* bind analog output to one crtc */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - struct drm_display_mode *des_mode; + struct drm_display_mode *des_mode = NULL; if (list_empty(&output->modes)) continue; @@ -582,6 +582,10 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) if (des_mode->flags & DRM_MODE_TYPE_PREFERRED) break; } + + if (!des_mode) + continue; + if (!strncmp(output->name, "VGA", 3)) { DRM_DEBUG("VGA preferred mode: %s\n", des_mode->name); drm_setup_output(output, vga_crtc, des_mode); -- cgit v1.2.3 From 4f0841a31cbed315a3e891557eadc55cab0dfd23 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 18:03:14 -0700 Subject: Just use drm_output_destroy to cleanup LVDS failures. It'll call our cleanup routine, which will take care of freeing our dev_priv and i2c ddc bus. --- linux-core/intel_lvds.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c index 8454bbcf..34ed6a9d 100644 --- a/linux-core/intel_lvds.c +++ b/linux-core/intel_lvds.c @@ -501,6 +501,5 @@ out: failed: DRM_DEBUG("No LVDS modes found, disabling.\n"); - // intel_lvds_destroy(output); - // drm_output_destroy(output); + drm_output_destroy(output); /* calls intel_lvds_destroy above */ } -- cgit v1.2.3 From 20b2949e3738bc900407d6aeddc6338f05b0b169 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 18 Apr 2007 14:55:43 +1000 Subject: make sure TMDS gets a crtc --- linux-core/drm_crtc.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 437259d5..e8f42feb 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -553,16 +553,19 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) crtc->enabled = 1; crtc->desired_x = 0; crtc->desired_y = 0; - } else if (!lvds_crtc) { - lvds_crtc = crtc; - crtc->enabled = 1; - crtc->desired_x = 0; - crtc->desired_y = 0; - } else if (!tmds_crtc) { - tmds_crtc = crtc; - crtc->enabled = 1; - crtc->desired_x = 0; - crtc->desired_y = 0; + } else { + if (!lvds_crtc) { + lvds_crtc = crtc; + crtc->enabled = 1; + crtc->desired_x = 0; + crtc->desired_y = 0; + } + if (!tmds_crtc) { + tmds_crtc = crtc; + crtc->enabled = 1; + crtc->desired_x = 0; + crtc->desired_y = 0; + } } } -- cgit v1.2.3