From b50bda002b824efb24e18e8d514ff0ca763c15b9 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Tue, 10 Apr 2007 18:44:47 +1000 Subject: add addfb/rmfb ioctls Originally from Jakob, cleaned up by airlied. --- libdrm/xf86drmMode.c | 22 ++++++++++++ libdrm/xf86drmMode.h | 6 ++-- linux-core/drm_crtc.c | 95 +++++++++++++++++++++++++++++++++++++++++++------- linux-core/drm_crtc.h | 27 +++++++------- linux-core/drm_drv.c | 2 ++ shared-core/drm.h | 10 ++++++ shared-core/i915_dma.c | 2 -- 7 files changed, 135 insertions(+), 29 deletions(-) diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index c4403b1c..55a9d91c 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -192,6 +192,28 @@ err_allocs: return 0; } +uint32_t drmModeAddFB(int fd, uint32_t width, uint32_t height, + uint8_t bpp, uint32_t pitch, drmBO *bo) +{ + struct drm_mode_fb_cmd f; + + f.width = width; + f.height = height; + f.pitch = pitch; + f.bpp = bpp; + f.handle = bo->handle; + + if (ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f)) + return 0; + + return f.buffer_id; +} + +int drmModeRmFB(int fd, uint32_t bufferId) +{ + return ioctl(fd, DRM_IOCTL_MODE_RMFB, bufferId); +} + #if 0 int drmModeForceProbe(int fd, uint32_t outputId) { diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h index c027a16d..45b157a8 100644 --- a/libdrm/xf86drmMode.h +++ b/libdrm/xf86drmMode.h @@ -77,8 +77,10 @@ typedef struct _drmModeRes { typedef struct _drmModeFrameBuffer { - uint32_t minWidth, maxWidth; - uint32_t minHeight, maxHeight; + uint32_t width; + uint32_t height; + uint32_t pitch; + uint8_t bpp; } drmModeFrameBuffer, *drmModeFrameBufferPtr; diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index fe27e386..a02124f3 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -465,18 +465,19 @@ void drm_crtc_config_init(drm_device_t *dev) } EXPORT_SYMBOL(drm_crtc_config_init); -void drm_framebuffer_set_object(drm_device_t *dev, unsigned long handle) +static int drm_get_buffer_object(drm_device_t *dev, struct drm_buffer_object **bo, unsigned long handle) { - struct drm_framebuffer *fb; drm_user_object_t *uo; drm_hash_item_t *hash; - drm_buffer_object_t *bo; int ret; + *bo = NULL; + mutex_lock(&dev->struct_mutex); ret = drm_ht_find_item(&dev->object_hash, handle, &hash); if (ret) { DRM_ERROR("Couldn't find handle.\n"); + ret = -EINVAL; goto out_err; } @@ -485,20 +486,13 @@ void drm_framebuffer_set_object(drm_device_t *dev, unsigned long handle) ret = -EINVAL; goto out_err; } - - bo = drm_user_object_entry(uo, drm_buffer_object_t, base); - - /* get the first fb */ - list_for_each_entry(fb, &dev->crtc_config.fb_list, head) { - fb->offset = bo->offset; - break; - } + + *bo = drm_user_object_entry(uo, drm_buffer_object_t, base); ret = 0; out_err: mutex_unlock(&dev->struct_mutex); - return; + return ret; } -EXPORT_SYMBOL(drm_framebuffer_set_object); bool drm_initial_config(drm_device_t *dev, bool can_grow) { @@ -923,3 +917,78 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp, retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set); return retcode; } + +/* Add framebuffer ioctl */ +int drm_mode_addfb(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct drm_file *priv = filp->private_data; + struct drm_device *dev = priv->head->dev; + struct drm_mode_fb_cmd __user *argp = (void __user *)arg; + struct drm_mode_fb_cmd r; + struct drm_crtc_config *config = &dev->crtc_config; + struct drm_framebuffer *fb; + struct drm_buffer_object *bo; + int ret; + + if (!copy_from_user(&r, argp, sizeof(r))) + return -EFAULT; + + if (config->min_width > r.width || r.width > config->max_width) { + DRM_ERROR("mode new framebuffer width not within limits"); + return -EINVAL; + } + if (config->min_height > r.height || r.height > config->min_height) { + DRM_ERROR("mode new framebuffer height not within limits"); + return -EINVAL; + } + + /* TODO check limits are okay */ + ret = drm_get_buffer_object(dev, &bo, r.handle); + if (ret || !bo) + return -EINVAL; + + /* TODO check buffer is sufficently large */ + /* TODO setup destructor callback */ + + fb = drm_framebuffer_create(dev); + if(!fb) + return -EINVAL;; + + fb->width = r.width; + fb->height = r.height; + fb->pitch = r.pitch; + fb->bits_per_pixel = r.bpp; + fb->offset = bo->offset; + fb->bo = bo; + + r.buffer_id = fb->id; + if (!copy_to_user(argp, &r, sizeof(r))) + return -EFAULT; + + return 0; +} + +int drm_mode_rmfb(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->head->dev; + struct drm_framebuffer *fb = 0; + uint32_t id = arg; + + fb = idr_find(&dev->crtc_config.crtc_idr, id); + /* TODO check that we realy get a framebuffer back. */ + if (!fb || (id != fb->id)) { + DRM_ERROR("mode invalid framebuffer id\n"); + return -EINVAL; + } + + /* TODO check if we own the buffer */ + /* TODO release all crtc connected to the framebuffer */ + /* TODO unhock the destructor from the buffer object */ + + drm_framebuffer_destroy(fb); + + return 0; +} diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 21908f0c..36d5f316 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -178,6 +178,7 @@ struct drm_framebuffer { unsigned int depth; int bits_per_pixel; int flags; + struct drm_buffer_object *bo; }; struct drm_crtc; struct drm_output; @@ -432,17 +433,6 @@ extern void drm_disable_unused_functions(struct drm_device *dev); extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev); extern void drm_crtc_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); - -/* IOCTLs */ -extern int drm_mode_getresources(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); - -extern int drm_mode_getcrtc(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_mode_getoutput(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern int drm_mode_setcrtc(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); extern void drm_mode_list_concat(struct list_head *head, struct list_head *new); extern void drm_mode_validate_size(struct drm_device *dev, @@ -454,7 +444,20 @@ extern void drm_mode_sort(struct list_head *mode_list); 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); +/* IOCTLs */ +extern int drm_mode_getresources(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int drm_mode_getcrtc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_mode_getoutput(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_mode_setcrtc(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_mode_addfb(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int drm_mode_rmfb(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); #endif /* __DRM_CRTC_H__ */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index c8ee054f..80007170 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -127,6 +127,8 @@ static drm_ioctl_desc_t drm_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_MODE_GETCRTC)] = {drm_mode_getcrtc, DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_IOCTL_MODE_GETOUTPUT)] = {drm_mode_getoutput, DRM_MASTER|DRM_ROOT_ONLY}, [DRM_IOCTL_NR(DRM_IOCTL_MODE_SETCRTC)] = {drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB)] = {drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY}, + [DRM_IOCTL_NR(DRM_IOCTL_MODE_RMFB)] = {drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY}, }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/shared-core/drm.h b/shared-core/drm.h index 49bc41bc..8329609f 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -962,6 +962,14 @@ struct drm_mode_get_output { }; +struct drm_mode_fb_cmd { + unsigned int buffer_id; + unsigned int width, height; + unsigned int pitch; + unsigned int bpp; + unsigned int handle; +}; + /** * \name Ioctls Definitions */ @@ -1037,6 +1045,8 @@ struct drm_mode_get_output { #define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) #define DRM_IOCTL_MODE_GETOUTPUT DRM_IOWR(0xA2, struct drm_mode_get_output) #define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA3, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xA4, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xA5, unsigned int) /*@}*/ /** diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index a5f1473a..811e4bb9 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -171,8 +171,6 @@ static int i915_initialize(drm_device_t * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); - /* this probably doesn't belong here - TODO */ - drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle); drm_set_desired_modes(dev); return 0; -- cgit v1.2.3 From ed0ebd9d3da2e5c4e8053b6e7a7d2898b184f857 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 10 Apr 2007 18:56:02 +1000 Subject: make crtc_config be named mode_config X.org calls this crtc_config but this is a bad name and will confuse ppl later (and me now :-) --- linux-core/drmP.h | 2 +- linux-core/drm_crtc.c | 136 ++++++++++++++++++++++----------------------- linux-core/drm_crtc.h | 14 ++--- linux-core/intel_display.c | 16 +++--- 4 files changed, 84 insertions(+), 84 deletions(-) diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 74f52854..25fc8733 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -832,7 +832,7 @@ typedef struct drm_device { /*@} */ /* DRM mode setting */ - struct drm_crtc_config crtc_config; + struct drm_mode_config mode_config; } drm_device_t; #if __OS_HAS_AGP diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index a02124f3..4f8af001 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -8,39 +8,39 @@ int drm_mode_idr_get(struct drm_device *dev, void *ptr) int new_id = 0; int ret; again: - if (idr_pre_get(&dev->crtc_config.crtc_idr, GFP_KERNEL) == 0) { + if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) { DRM_ERROR("Ran out memory getting a mode number\n"); return 0; } - spin_lock(&dev->crtc_config.config_lock); + spin_lock(&dev->mode_config.config_lock); - ret = idr_get_new_above(&dev->crtc_config.crtc_idr, ptr, 1, &new_id); + ret = idr_get_new_above(&dev->mode_config.crtc_idr, ptr, 1, &new_id); if (ret == -EAGAIN) { - spin_unlock(&dev->crtc_config.config_lock); + spin_unlock(&dev->mode_config.config_lock); goto again; } - spin_unlock(&dev->crtc_config.config_lock); + spin_unlock(&dev->mode_config.config_lock); return new_id; } void drm_mode_idr_put(struct drm_device *dev, int id) { - idr_remove(&dev->crtc_config.crtc_idr, id); + idr_remove(&dev->mode_config.crtc_idr, id); } struct drm_framebuffer *drm_framebuffer_create(drm_device_t *dev) { struct drm_framebuffer *fb; - spin_lock(&dev->crtc_config.config_lock); + spin_lock(&dev->mode_config.config_lock); /* Limit to single framebuffer for now */ - if (dev->crtc_config.num_fb > 1) { + if (dev->mode_config.num_fb > 1) { DRM_ERROR("Attempt to add multiple framebuffers failed\n"); return NULL; } - spin_unlock(&dev->crtc_config.config_lock); + spin_unlock(&dev->mode_config.config_lock); fb = kzalloc(sizeof(struct drm_framebuffer), GFP_KERNEL); if (!fb) { @@ -50,10 +50,10 @@ struct drm_framebuffer *drm_framebuffer_create(drm_device_t *dev) fb->id = drm_mode_idr_get(dev, fb); fb->dev = dev; - spin_lock(&dev->crtc_config.config_lock); - dev->crtc_config.num_fb++; - list_add(&fb->head, &dev->crtc_config.fb_list); - spin_unlock(&dev->crtc_config.config_lock); + spin_lock(&dev->mode_config.config_lock); + dev->mode_config.num_fb++; + list_add(&fb->head, &dev->mode_config.fb_list); + spin_unlock(&dev->mode_config.config_lock); return fb; } @@ -62,11 +62,11 @@ void drm_framebuffer_destroy(struct drm_framebuffer *fb) { drm_device_t *dev = fb->dev; - spin_lock(&dev->crtc_config.config_lock); + spin_lock(&dev->mode_config.config_lock); drm_mode_idr_put(dev, fb->id); list_del(&fb->head); - dev->crtc_config.num_fb--; - spin_unlock(&dev->crtc_config.config_lock); + dev->mode_config.num_fb--; + spin_unlock(&dev->mode_config.config_lock); kfree(fb); } @@ -86,10 +86,10 @@ struct drm_crtc *drm_crtc_create(drm_device_t *dev, crtc->id = drm_mode_idr_get(dev, crtc); DRM_DEBUG("crtc %p got id %d\n", crtc, crtc->id); - spin_lock(&dev->crtc_config.config_lock); - list_add_tail(&crtc->head, &dev->crtc_config.crtc_list); - dev->crtc_config.num_crtc++; - spin_unlock(&dev->crtc_config.config_lock); + spin_lock(&dev->mode_config.config_lock); + list_add_tail(&crtc->head, &dev->mode_config.crtc_list); + dev->mode_config.num_crtc++; + spin_unlock(&dev->mode_config.config_lock); return crtc; } @@ -103,11 +103,11 @@ void drm_crtc_destroy(struct drm_crtc *crtc) (*crtc->funcs->cleanup)(crtc); - spin_lock(&dev->crtc_config.config_lock); + spin_lock(&dev->mode_config.config_lock); drm_mode_idr_put(dev, crtc->id); list_del(&crtc->head); - dev->crtc_config.num_crtc--; - spin_unlock(&dev->crtc_config.config_lock); + dev->mode_config.num_crtc--; + spin_unlock(&dev->mode_config.config_lock); kfree(crtc); } EXPORT_SYMBOL(drm_crtc_destroy); @@ -116,7 +116,7 @@ bool drm_crtc_in_use(struct drm_crtc *crtc) { struct drm_output *output; drm_device_t *dev = crtc->dev; - list_for_each_entry(output, &dev->crtc_config.output_list, head) + list_for_each_entry(output, &dev->mode_config.output_list, head) if (output->crtc == crtc) return true; return false; @@ -131,7 +131,7 @@ void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY) //if (maxX == 0 || maxY == 0) // TODO - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { list_for_each_entry_safe(mode, t, &output->modes, head) drm_mode_remove(output, mode); @@ -214,7 +214,7 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, * adjust it according to limitations or output properties, and also * a chance to reject the mode entirely. */ - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { if (output->crtc != crtc) continue; @@ -229,7 +229,7 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, } /* Prepare the outputs and CRTCs before setting the mode. */ - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { if (output->crtc != crtc) continue; @@ -244,14 +244,14 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, * on the DPLL. */ crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y); - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { if (output->crtc == crtc) output->funcs->mode_set(output, mode, adjusted_mode); } /* Now, enable the clocks, plane, pipe, and outputs that we set up. */ crtc->funcs->commit(crtc); - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { if (output->crtc == crtc) { output->funcs->commit(output); @@ -287,11 +287,11 @@ bool drm_set_desired_modes(struct drm_device *dev) struct drm_crtc *crtc; struct drm_output *output, *list_output; - list_for_each_entry(crtc, &dev->crtc_config.crtc_list, head) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { output = NULL; DRM_DEBUG("crtc is %d\n", crtc->id); - list_for_each_entry(list_output, &dev->crtc_config.output_list, head) { + list_for_each_entry(list_output, &dev->mode_config.output_list, head) { if (list_output->crtc == crtc) { output = list_output; break; @@ -320,12 +320,12 @@ void drm_disable_unused_functions(struct drm_device *dev) struct drm_output *output; struct drm_crtc *crtc; - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { if (!output->crtc) (*output->funcs->dpms)(output, DPMSModeOff); } - list_for_each_entry(crtc, &dev->crtc_config.crtc_list, head) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (!crtc->enabled) crtc->funcs->dpms(crtc, DPMSModeOff); } @@ -389,11 +389,11 @@ struct drm_output *drm_output_create(drm_device_t *dev, /* output_set_monitor(output)? */ /* check for output_ignored(output)? */ - spin_lock(&dev->crtc_config.config_lock); - list_add_tail(&output->head, &dev->crtc_config.output_list); - dev->crtc_config.num_output++; + spin_lock(&dev->mode_config.config_lock); + list_add_tail(&output->head, &dev->mode_config.output_list); + dev->mode_config.num_output++; - spin_unlock(&dev->crtc_config.config_lock); + spin_unlock(&dev->mode_config.config_lock); return output; @@ -414,10 +414,10 @@ void drm_output_destroy(struct drm_output *output) list_for_each_entry_safe(mode, t, &output->modes, head) drm_mode_remove(output, mode); - spin_lock(&dev->crtc_config.config_lock); + spin_lock(&dev->mode_config.config_lock); drm_mode_idr_put(dev, output->id); list_del(&output->head); - spin_unlock(&dev->crtc_config.config_lock); + spin_unlock(&dev->mode_config.config_lock); kfree(output); } EXPORT_SYMBOL(drm_output_destroy); @@ -455,15 +455,15 @@ void drm_crtc_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode kfree(mode); } -void drm_crtc_config_init(drm_device_t *dev) +void drm_mode_config_init(drm_device_t *dev) { - spin_lock_init(&dev->crtc_config.config_lock); - INIT_LIST_HEAD(&dev->crtc_config.fb_list); - INIT_LIST_HEAD(&dev->crtc_config.crtc_list); - INIT_LIST_HEAD(&dev->crtc_config.output_list); - idr_init(&dev->crtc_config.crtc_idr); + spin_lock_init(&dev->mode_config.config_lock); + INIT_LIST_HEAD(&dev->mode_config.fb_list); + INIT_LIST_HEAD(&dev->mode_config.crtc_list); + INIT_LIST_HEAD(&dev->mode_config.output_list); + idr_init(&dev->mode_config.crtc_idr); } -EXPORT_SYMBOL(drm_crtc_config_init); +EXPORT_SYMBOL(drm_mode_config_init); static int drm_get_buffer_object(drm_device_t *dev, struct drm_buffer_object **bo, unsigned long handle) { @@ -514,7 +514,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) /* bind both CRTCs to this fb */ /* only initialise one crtc to enabled state */ - list_for_each_entry(crtc, &dev->crtc_config.crtc_list, head) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { crtc->fb = fb; if (!vga_crtc) { vga_crtc = crtc; @@ -542,7 +542,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) /* hard bind the CRTCS */ /* bind analog output to one crtc */ - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { struct drm_display_mode *des_mode; /* Get the first preferred moded */ @@ -580,20 +580,20 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) } EXPORT_SYMBOL(drm_initial_config); -void drm_crtc_config_cleanup(drm_device_t *dev) +void drm_mode_config_cleanup(drm_device_t *dev) { struct drm_output *output, *ot; struct drm_crtc *crtc, *ct; - list_for_each_entry_safe(output, ot, &dev->crtc_config.output_list, head) { + list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) { drm_output_destroy(output); } - list_for_each_entry_safe(crtc, ct, &dev->crtc_config.crtc_list, head) { + list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) { drm_crtc_destroy(crtc); } } -EXPORT_SYMBOL(drm_crtc_config_cleanup); +EXPORT_SYMBOL(drm_mode_config_cleanup); int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_display_mode *new_mode, struct drm_output **output_set) { @@ -604,7 +604,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_output *output; int count = 0, ro; - save_crtcs = kzalloc(dev->crtc_config.num_crtc * sizeof(struct drm_crtc *), GFP_KERNEL); + save_crtcs = kzalloc(dev->mode_config.num_crtc * sizeof(struct drm_crtc *), GFP_KERNEL); if (!save_crtcs) return -ENOMEM; @@ -614,7 +614,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, if (crtc->mode.mode_id != new_mode->mode_id) changed = true; - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { save_crtcs[count++] = output->crtc; if (output->crtc == crtc) @@ -642,7 +642,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, crtc_info->y)) { crtc->enabled = save_enabled; count = 0; - list_for_each_entry(output, &dev->crtc_config.output_list, head) + list_for_each_entry(output, &dev->mode_config.output_list, head) output->crtc = save_crtcs[count++]; kfree(save_crtcs); return -EINVAL; @@ -700,10 +700,10 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); - list_for_each(lh, &dev->crtc_config.crtc_list) + list_for_each(lh, &dev->mode_config.crtc_list) crtc_count++; - list_for_each_entry(output, &dev->crtc_config.output_list, + list_for_each_entry(output, &dev->mode_config.output_list, head) { output_count++; @@ -718,7 +718,7 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, /* CRTCs */ if (card_res.count_crtcs >= crtc_count) { copied = 0; - list_for_each_entry(crtc, &dev->crtc_config.crtc_list, head){ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head){ DRM_DEBUG("CRTC ID is %d\n", crtc->id); if (put_user(crtc->id, &card_res.crtc_id[copied++])) { retcode = -EFAULT; @@ -732,7 +732,7 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, /* Outputs */ if (card_res.count_outputs >= output_count) { copied = 0; - list_for_each_entry(output, &dev->crtc_config.output_list, + list_for_each_entry(output, &dev->mode_config.output_list, head) { DRM_DEBUG("OUTPUT ID is %d\n", output->id); if (put_user(output->id, &card_res.output_id[copied++])) { @@ -746,7 +746,7 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, /* Modes */ if (card_res.count_modes >= mode_count) { copied = 0; - list_for_each_entry(output, &dev->crtc_config.output_list, + list_for_each_entry(output, &dev->mode_config.output_list, head) { list_for_each_entry(mode, &output->modes, head) { drm_crtc_convert_to_umode(&u_mode, mode); @@ -785,7 +785,7 @@ int drm_mode_getcrtc(struct inode *inode, struct file *filp, if (copy_from_user(&crtc_resp, argp, sizeof(crtc_resp))) return -EFAULT; - crtc = idr_find(&dev->crtc_config.crtc_idr, crtc_resp.crtc_id); + crtc = idr_find(&dev->mode_config.crtc_idr, crtc_resp.crtc_id); if (!crtc || (crtc->id != crtc_resp.crtc_id)) return -EINVAL; crtc_resp.x = crtc->x; @@ -797,7 +797,7 @@ int drm_mode_getcrtc(struct inode *inode, struct file *filp, crtc_resp.mode = crtc->mode.mode_id; ocount = 0; - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { if (output->crtc == crtc) crtc_resp.outputs |= 1 << (ocount++); } @@ -827,7 +827,7 @@ int drm_mode_getoutput(struct inode *inode, struct file *filp, if (copy_from_user(&out_resp, argp, sizeof(out_resp))) return -EFAULT; - output= idr_find(&dev->crtc_config.crtc_idr, out_resp.output); + output= idr_find(&dev->mode_config.crtc_idr, out_resp.output); if (!output || (output->id != out_resp.output)) return -EINVAL; @@ -878,12 +878,12 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp, if (copy_from_user(&crtc_req, argp, sizeof(crtc_req))) return -EFAULT; - crtc = idr_find(&dev->crtc_config.crtc_idr, crtc_req.crtc_id); + crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req.crtc_id); if (!crtc || (crtc->id != crtc_req.crtc_id)) return -EINVAL; if (crtc_req.mode) { - mode = idr_find(&dev->crtc_config.crtc_idr, crtc_req.mode); + mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode); if (!mode || (mode->mode_id != crtc_req.mode)) return -EINVAL; } else @@ -906,7 +906,7 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp, if (get_user(out_id, &crtc_req.set_outputs[i])) return -EFAULT; - output = idr_find(&dev->crtc_config.crtc_idr, out_id); + output = idr_find(&dev->mode_config.crtc_idr, out_id); if (!output || (out_id != output->id)) return -EINVAL; @@ -926,7 +926,7 @@ int drm_mode_addfb(struct inode *inode, struct file *filp, struct drm_device *dev = priv->head->dev; struct drm_mode_fb_cmd __user *argp = (void __user *)arg; struct drm_mode_fb_cmd r; - struct drm_crtc_config *config = &dev->crtc_config; + struct drm_mode_config *config = &dev->mode_config; struct drm_framebuffer *fb; struct drm_buffer_object *bo; int ret; @@ -977,7 +977,7 @@ int drm_mode_rmfb(struct inode *inode, struct file *filp, struct drm_framebuffer *fb = 0; uint32_t id = arg; - fb = idr_find(&dev->crtc_config.crtc_idr, id); + fb = idr_find(&dev->mode_config.crtc_idr, id); /* TODO check that we realy get a framebuffer back. */ if (!fb || (id != fb->id)) { DRM_ERROR("mode invalid framebuffer id\n"); diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 36d5f316..19d7cf51 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -377,7 +377,7 @@ struct drm_output { }; /** - * struct drm_crtc_config_funcs - configure CRTCs for a given screen layout + * struct drm_mode_config_funcs - configure CRTCs for a given screen layout * @resize: adjust CRTCs as necessary for the proposed layout * * Currently only a resize hook is available. DRM will call back into the @@ -385,15 +385,15 @@ struct drm_output { * the proposed size, it can return false. Otherwise it should adjust * the CRTC<->output mappings as needed and update its view of the screen. */ -struct drm_crtc_config_funcs { +struct drm_mode_config_funcs { bool (*resize)(struct drm_device *dev, int width, int height); }; /** - * drm_crtc_config - CRTC configuration control structure + * drm_mode_config - Mode configuration control structure * */ -struct drm_crtc_config { +struct drm_mode_config { spinlock_t config_lock; struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, output, modes - just makes life easier */ /* this is limited to one for now */ @@ -410,7 +410,7 @@ struct drm_crtc_config { int max_width, max_height; /* DamagePtr rotationDamage? */ /* DGA stuff? */ - struct drm_crtc_config_funcs *funcs; + struct drm_mode_config_funcs *funcs; }; struct drm_output *drm_output_create(struct drm_device *dev, @@ -427,8 +427,8 @@ extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, struct drm_display_mode *mode); extern void drm_mode_debug_printmodeline(struct drm_device *dev, struct drm_display_mode *mode); -extern void drm_crtc_config_init(struct drm_device *dev); -extern void drm_crtc_config_cleanup(struct drm_device *dev); +extern void drm_mode_config_init(struct drm_device *dev); +extern void drm_mode_config_cleanup(struct drm_device *dev); extern void drm_disable_unused_functions(struct drm_device *dev); extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev); diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 58d66987..e8d15ce5 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -224,10 +224,10 @@ static void intel_clock(struct drm_device *dev, int refclk, bool intel_pipe_has_type (struct drm_crtc *crtc, int type) { struct drm_device *dev = crtc->dev; - struct drm_crtc_config *crtc_config = &dev->crtc_config; + struct drm_mode_config *mode_config = &dev->mode_config; struct drm_output *l_entry; - list_for_each_entry(l_entry, &crtc_config->output_list, head) { + list_for_each_entry(l_entry, &mode_config->output_list, head) { if (l_entry->crtc == crtc) { struct intel_output *intel_output = l_entry->driver_private; if (intel_output->type == type) @@ -681,10 +681,10 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, u32 dpll = 0, fp = 0, dspcntr, pipeconf; bool ok, is_sdvo = false, is_dvo = false; bool is_crt = false, is_lvds = false, is_tv = false; - struct drm_crtc_config *crtc_config = &dev->crtc_config; + struct drm_mode_config *mode_config = &dev->mode_config; struct drm_output *output; - list_for_each_entry(output, &crtc_config->output_list, head) { + list_for_each_entry(output, &mode_config->output_list, head) { struct intel_output *intel_output = output->driver_private; if (output->crtc != crtc) @@ -1023,7 +1023,7 @@ int intel_output_clones (drm_device_t *dev, int type_mask) struct drm_output *output; int entry = 0; - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { struct intel_output *intel_output = output->driver_private; if (type_mask & (1 << intel_output->type)) index_mask |= (1 << entry); @@ -1048,7 +1048,7 @@ static void intel_setup_outputs(drm_device_t *dev) intel_sdvo_init(dev, SDVOC); } - list_for_each_entry(output, &dev->crtc_config.output_list, head) { + list_for_each_entry(output, &dev->mode_config.output_list, head) { struct intel_output *intel_output = output->driver_private; int crtc_mask = 0, clone_mask = 0; @@ -1088,7 +1088,7 @@ void intel_modeset_init(drm_device_t *dev) int num_pipe; int i; - drm_crtc_config_init(dev); + drm_mode_config_init(dev); if (IS_MOBILE(dev) || IS_I9XX(dev)) @@ -1109,5 +1109,5 @@ void intel_modeset_init(drm_device_t *dev) void intel_modeset_cleanup(drm_device_t *dev) { - drm_crtc_config_cleanup(dev); + drm_mode_config_cleanup(dev); } -- cgit v1.2.3 From eb9bdc27879d1aa307b234bbdb0f81494dcf7095 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 11:51:31 +1000 Subject: mode: fixup problems with framebuffer add function --- libdrm/xf86drmMode.c | 12 +++++++----- linux-core/drm_crtc.c | 14 ++++++++------ linux-core/intel_display.c | 7 ++++++- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index 55a9d91c..5f480890 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -192,10 +192,11 @@ err_allocs: return 0; } -uint32_t drmModeAddFB(int fd, uint32_t width, uint32_t height, - uint8_t bpp, uint32_t pitch, drmBO *bo) +int drmModeAddFB(int fd, uint32_t width, uint32_t height, + uint8_t bpp, uint32_t pitch, drmBO *bo, uint32_t *buf_id) { struct drm_mode_fb_cmd f; + int ret; f.width = width; f.height = height; @@ -203,10 +204,11 @@ uint32_t drmModeAddFB(int fd, uint32_t width, uint32_t height, f.bpp = bpp; f.handle = bo->handle; - if (ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f)) - return 0; + if (ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f)) + return ret; - return f.buffer_id; + *buf_id = f.buffer_id; + return 0; } int drmModeRmFB(int fd, uint32_t bufferId) diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 4f8af001..ce2073d1 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -502,6 +502,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) struct drm_framebuffer *fb; struct drm_output *output, *use_output = NULL; +#if 0 fb = drm_framebuffer_create(dev); if (!fb) return false; @@ -512,6 +513,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) fb->depth = 24; fb->bits_per_pixel = 32; +#endif /* bind both CRTCs to this fb */ /* only initialise one crtc to enabled state */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { @@ -931,15 +933,15 @@ int drm_mode_addfb(struct inode *inode, struct file *filp, struct drm_buffer_object *bo; int ret; - if (!copy_from_user(&r, argp, sizeof(r))) + if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; - if (config->min_width > r.width || r.width > config->max_width) { - DRM_ERROR("mode new framebuffer width not within limits"); + if ((config->min_width > r.width) || (r.width > config->max_width)) { + DRM_ERROR("mode new framebuffer width not within limits\n"); return -EINVAL; } - if (config->min_height > r.height || r.height > config->min_height) { - DRM_ERROR("mode new framebuffer height not within limits"); + if ((config->min_height > r.height) || (r.height > config->max_height)) { + DRM_ERROR("mode new framebuffer height not within limits\n"); return -EINVAL; } @@ -963,7 +965,7 @@ int drm_mode_addfb(struct inode *inode, struct file *filp, fb->bo = bo; r.buffer_id = fb->id; - if (!copy_to_user(argp, &r, sizeof(r))) + if (copy_to_user(argp, &r, sizeof(r))) return -EFAULT; return 0; diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index e8d15ce5..fce0fafd 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -1090,6 +1090,11 @@ void intel_modeset_init(drm_device_t *dev) drm_mode_config_init(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_MOBILE(dev) || IS_I9XX(dev)) num_pipe = 2; @@ -1104,7 +1109,7 @@ void intel_modeset_init(drm_device_t *dev) intel_setup_outputs(dev); - drm_initial_config(dev, false); + //drm_initial_config(dev, false); } void intel_modeset_cleanup(drm_device_t *dev) -- cgit v1.2.3 From 65f465ed5ad3caf773658bb2832785c963b987f6 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 14:49:49 +1000 Subject: fixup numerous issues with adding framebuffer support This still isn't perfect but it fixes a few oopses and cleans up some of the tabs and bugs in the original fb limit code --- libdrm/xf86drmMode.c | 8 ++-- libdrm/xf86drmMode.h | 8 ++-- linux-core/drm_crtc.c | 101 ++++++++++++++++++++++++++++++++++--------------- linux-core/drm_crtc.h | 6 +-- linux-core/drm_modes.c | 4 +- shared-core/i915_dma.c | 2 +- 6 files changed, 83 insertions(+), 46 deletions(-) diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index 5f480890..df8ea8ee 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -311,11 +311,9 @@ err_allocs: } -int drmModeSetCrtc( - int fd, uint32_t crtcId, uint32_t bufferId, - uint32_t x, uint32_t y, uint32_t modeId, - uint32_t *outputs, int count - ) +int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, + uint32_t x, uint32_t y, uint32_t modeId, + uint32_t *outputs, int count) { struct drm_mode_crtc crtc; diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h index 45b157a8..fadfdc5d 100644 --- a/libdrm/xf86drmMode.h +++ b/libdrm/xf86drmMode.h @@ -214,14 +214,12 @@ extern drmModeFrameBufferPtr drmModeGetFramebuffer(int fd, /** * Creates a new framebuffer with an buffer object as its scanout buffer. */ -extern uint32_t drmModeNewFrameBuffer(int fd, - uint32_t width, uint32_t height, - uint8_t bbp, uint32_t pitch, drmBO *bo); - +extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, + uint8_t bpp, uint32_t pitch, drmBO *bo, uint32_t *buf_id); /** * Destroies the given framebuffer. */ -extern int drmModeDesFrameBuffer(int fd, uint32_t bufferId); +extern int drmModeRmFB(int fd, uint32_t bufferId); /** * Changes the scanout buffer to the given buffer object. diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index ce2073d1..46b7f7ae 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -371,7 +371,7 @@ struct drm_output *drm_output_create(drm_device_t *dev, { struct drm_output *output = NULL; - output = kmalloc(sizeof(struct drm_output), GFP_KERNEL); + output = kzalloc(sizeof(struct drm_output), GFP_KERNEL); if (!output) return NULL; @@ -471,13 +471,13 @@ static int drm_get_buffer_object(drm_device_t *dev, struct drm_buffer_object **b drm_hash_item_t *hash; int ret; - *bo = NULL; + *bo = NULL; mutex_lock(&dev->struct_mutex); ret = drm_ht_find_item(&dev->object_hash, handle, &hash); if (ret) { DRM_ERROR("Couldn't find handle.\n"); - ret = -EINVAL; + ret = -EINVAL; goto out_err; } @@ -486,7 +486,7 @@ static int drm_get_buffer_object(drm_device_t *dev, struct drm_buffer_object **b ret = -EINVAL; goto out_err; } - + *bo = drm_user_object_entry(uo, drm_buffer_object_t, base); ret = 0; out_err: @@ -517,7 +517,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) /* bind both CRTCs to this fb */ /* only initialise one crtc to enabled state */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - crtc->fb = fb; + // crtc->fb = fb; if (!vga_crtc) { vga_crtc = crtc; crtc->enabled = 1; @@ -699,15 +699,14 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, int output_count = 0; int crtc_count = 0; int copied = 0; - + memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); list_for_each(lh, &dev->mode_config.crtc_list) crtc_count++; list_for_each_entry(output, &dev->mode_config.output_list, - head) - { + head) { output_count++; list_for_each(lh, &output->modes) mode_count++; @@ -716,6 +715,16 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, if (copy_from_user(&card_res, argp, sizeof(card_res))) return -EFAULT; + if (card_res.count_modes == 0) { + DRM_DEBUG("probing modes %dx%d\n", dev->mode_config.max_width, dev->mode_config.max_height); + drm_crtc_probe_output_modes(dev, dev->mode_config.max_width, dev->mode_config.max_height); + mode_count = 0; + list_for_each_entry(output, &dev->mode_config.output_list, head) { + list_for_each(lh, &output->modes) + mode_count++; + } + } + /* handle this in 3 parts */ /* CRTCs */ if (card_res.count_crtcs >= crtc_count) { @@ -829,13 +838,16 @@ int drm_mode_getoutput(struct inode *inode, struct file *filp, if (copy_from_user(&out_resp, argp, sizeof(out_resp))) return -EFAULT; + DRM_DEBUG("output id %d\n", out_resp.output); output= idr_find(&dev->mode_config.crtc_idr, out_resp.output); if (!output || (output->id != out_resp.output)) return -EINVAL; + DRM_DEBUG("about to count modes\n"); list_for_each_entry(mode, &output->modes, head) mode_count++; + DRM_DEBUG("about to count modes %d %d %p\n", mode_count, out_resp.count_modes, output->crtc); out_resp.mm_width = output->mm_width; out_resp.mm_height = output->mm_height; out_resp.subpixel = output->subpixel_order; @@ -845,7 +857,7 @@ int drm_mode_getoutput(struct inode *inode, struct file *filp, else out_resp.crtc = 0; - if (out_resp.count_modes >= mode_count) { + if ((out_resp.count_modes >= mode_count) && mode_count) { copied = 0; list_for_each_entry(mode, &output->modes, head) { if (put_user(mode->mode_id, &out_resp.modes[copied++])) { @@ -882,20 +894,40 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp, crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req.crtc_id); if (!crtc || (crtc->id != crtc_req.crtc_id)) + { + DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req.crtc_id); return -EINVAL; + } if (crtc_req.mode) { mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode); if (!mode || (mode->mode_id != crtc_req.mode)) + { + { + struct drm_output *output; + + list_for_each_entry(output, &dev->mode_config.output_list, head) { + list_for_each_entry(mode, &output->modes, head) { + drm_mode_debug_printmodeline(dev, mode); + } + } + } + + DRM_DEBUG("Unknown mode id %d, %p\n", crtc_req.mode, mode); return -EINVAL; + } } else mode = NULL; - if (crtc_req.count_outputs == 0 && mode) + if (crtc_req.count_outputs == 0 && mode) { + DRM_DEBUG("Count outputs is 0 but mode set\n"); return -EINVAL; + } - if (crtc_req.count_outputs > 0 && !mode) + if (crtc_req.count_outputs > 0 && !mode) { + DRM_DEBUG("Count outputs is %d but no mode set\n", crtc_req.count_outputs); return -EINVAL; + } if (crtc_req.count_outputs > 0) { u32 out_id; @@ -903,14 +935,15 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp, if (!output_set) return -ENOMEM; - for (i = 0; i < crtc_req.count_outputs; i++) - { + for (i = 0; i < crtc_req.count_outputs; i++) { if (get_user(out_id, &crtc_req.set_outputs[i])) return -EFAULT; output = idr_find(&dev->mode_config.crtc_idr, out_id); - if (!output || (out_id != output->id)) + if (!output || (out_id != output->id)) { + DRM_DEBUG("Output id %d unknown\n", out_id); return -EINVAL; + } output_set[i] = output; } @@ -922,16 +955,16 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp, /* Add framebuffer ioctl */ int drm_mode_addfb(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { struct drm_file *priv = filp->private_data; struct drm_device *dev = priv->head->dev; struct drm_mode_fb_cmd __user *argp = (void __user *)arg; struct drm_mode_fb_cmd r; - struct drm_mode_config *config = &dev->mode_config; + struct drm_mode_config *config = &dev->mode_config; struct drm_framebuffer *fb; struct drm_buffer_object *bo; - int ret; + int ret; if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; @@ -939,16 +972,16 @@ int drm_mode_addfb(struct inode *inode, struct file *filp, if ((config->min_width > r.width) || (r.width > config->max_width)) { DRM_ERROR("mode new framebuffer width not within limits\n"); return -EINVAL; - } + } if ((config->min_height > r.height) || (r.height > config->max_height)) { DRM_ERROR("mode new framebuffer height not within limits\n"); return -EINVAL; } /* TODO check limits are okay */ - ret = drm_get_buffer_object(dev, &bo, r.handle); - if (ret || !bo) - return -EINVAL; + ret = drm_get_buffer_object(dev, &bo, r.handle); + if (ret || !bo) + return -EINVAL; /* TODO check buffer is sufficently large */ /* TODO setup destructor callback */ @@ -957,22 +990,30 @@ int drm_mode_addfb(struct inode *inode, struct file *filp, if(!fb) return -EINVAL;; - fb->width = r.width; - fb->height = r.height; - fb->pitch = r.pitch; + fb->width = r.width; + fb->height = r.height; + fb->pitch = r.pitch; fb->bits_per_pixel = r.bpp; - fb->offset = bo->offset; - fb->bo = bo; + fb->offset = bo->offset; + fb->bo = bo; - r.buffer_id = fb->id; - if (copy_to_user(argp, &r, sizeof(r))) - return -EFAULT; + r.buffer_id = fb->id; + + /* bind the fb to the crtc for now */ + { + struct drm_crtc *crtc; + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + crtc->fb = fb; + } + } + if (copy_to_user(argp, &r, sizeof(r))) + return -EFAULT; return 0; } int drm_mode_rmfb(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 19d7cf51..142e0ecb 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -178,7 +178,7 @@ struct drm_framebuffer { unsigned int depth; int bits_per_pixel; int flags; - struct drm_buffer_object *bo; + struct drm_buffer_object *bo; }; struct drm_crtc; struct drm_output; @@ -456,8 +456,8 @@ extern int drm_mode_getoutput(struct inode *inode, struct file *filp, extern int drm_mode_setcrtc(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_mode_addfb(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); + unsigned int cmd, unsigned long arg); extern int drm_mode_rmfb(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); + unsigned int cmd, unsigned long arg); #endif /* __DRM_CRTC_H__ */ diff --git a/linux-core/drm_modes.c b/linux-core/drm_modes.c index bedef163..0f2a612a 100644 --- a/linux-core/drm_modes.c +++ b/linux-core/drm_modes.c @@ -36,8 +36,8 @@ void drm_mode_debug_printmodeline(struct drm_device *dev, struct drm_display_mode *mode) { - DRM_DEBUG("Modeline \"%s\" %d %d %d %d %d %d %d %d %d %d\n", - mode->name, mode->vrefresh / 1000, mode->clock, + DRM_DEBUG("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d\n", + mode->mode_id, mode->name, mode->vrefresh / 1000, mode->clock, mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, mode->vdisplay, mode->vsync_start, diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 811e4bb9..2c14cb5d 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -171,7 +171,7 @@ static int i915_initialize(drm_device_t * dev, I915_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); - drm_set_desired_modes(dev); +//drm_set_desired_modes(dev); return 0; } -- cgit v1.2.3 From 40bd6dcd86d554ca426deccd4fbada693c4be8a6 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 15:20:50 +1000 Subject: set the base address of the CRTC correctly --- linux-core/intel_display.c | 3 ++- shared-core/i915_dma.c | 4 +++- shared-core/i915_drv.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index fce0fafd..92b39406 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -351,9 +351,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y) int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); - Start = crtc->fb->offset; + Start = crtc->fb->offset + dev_priv->baseaddr; Offset = ((y * crtc->fb->width + x) * (crtc->fb->bits_per_pixel / 8)); + DRM_DEBUG("Writing base %08X %08X %d %d\n", Start, Offset, x, y); if (IS_I965G(dev)) { I915_WRITE(dspbase, Offset); I915_READ(dspbase); diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c index 2c14cb5d..c2a6d863 100644 --- a/shared-core/i915_dma.c +++ b/shared-core/i915_dma.c @@ -877,11 +877,13 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags) if (IS_I9XX(dev)) { dev_priv->mmiobase = drm_get_resource_start(dev, 0); dev_priv->mmiolen = drm_get_resource_len(dev, 0); + dev_priv->baseaddr = drm_get_resource_start(dev, 2) & 0xff000000; } else if (drm_get_resource_start(dev, 1)) { dev_priv->mmiobase = drm_get_resource_start(dev, 1); dev_priv->mmiolen = drm_get_resource_len(dev, 1); + dev_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000; } else { - DRM_ERROR("Unable to find MMIO registers\n"); + DRM_ERROR("Unable to find MMIO registers or FB\n"); return -ENODEV; } diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index f37f5873..517d0bf6 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -92,6 +92,7 @@ typedef struct drm_i915_private { drm_local_map_t *sarea; drm_local_map_t *mmio_map; + unsigned long baseaddr; unsigned long mmiobase; unsigned long mmiolen; -- cgit v1.2.3 From 1e39dc43230ba1827eedc29ab422464281ec3e1b Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 16:25:31 +1000 Subject: export output name to userspace --- libdrm/xf86drmMode.c | 4 +++- libdrm/xf86drmMode.h | 2 +- linux-core/drm_crtc.c | 7 +++++-- shared-core/drm.h | 3 ++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index df8ea8ee..c0444e65 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -40,6 +40,7 @@ #include "xf86drmMode.h" #include "xf86drm.h" #include +#include /* * Util functions @@ -385,7 +386,8 @@ drmModeOutputPtr drmModeGetOutput(int fd, uint32_t output_id) r->crtcs = out.crtcs; r->clones = out.clones; r->modes = drmAllocCpy(out.modes, out.count_modes, sizeof(uint32_t)); - + strncpy(r->name, out.name, DRM_OUTPUT_NAME_LEN); + r->name[DRM_OUTPUT_NAME_LEN-1] = 0; return r; err_allocs: diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h index fadfdc5d..594eb487 100644 --- a/libdrm/xf86drmMode.h +++ b/libdrm/xf86drmMode.h @@ -120,7 +120,7 @@ typedef enum { typedef struct _drmModeOutput { unsigned int crtc; /**< Crtc currently connected to */ - + unsigned char name[DRM_OUTPUT_NAME_LEN]; drmModeConnection connection; uint32_t mmWidth, mmHeight; /**< HxW in millimeters */ drmModeSubPixel subpixel; diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 46b7f7ae..cc082d91 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -838,16 +838,19 @@ int drm_mode_getoutput(struct inode *inode, struct file *filp, if (copy_from_user(&out_resp, argp, sizeof(out_resp))) return -EFAULT; - DRM_DEBUG("output id %d\n", out_resp.output); + DRM_DEBUG("output id %d:\n", out_resp.output); output= idr_find(&dev->mode_config.crtc_idr, out_resp.output); if (!output || (output->id != out_resp.output)) return -EINVAL; - DRM_DEBUG("about to count modes\n"); + DRM_DEBUG("about to count modes: %s\n", output->name); list_for_each_entry(mode, &output->modes, head) mode_count++; DRM_DEBUG("about to count modes %d %d %p\n", mode_count, out_resp.count_modes, output->crtc); + strncpy(out_resp.name, output->name, DRM_OUTPUT_NAME_LEN); + out_resp.name[DRM_OUTPUT_NAME_LEN-1] = 0; + out_resp.mm_width = output->mm_width; out_resp.mm_height = output->mm_height; out_resp.subpixel = output->subpixel_order; diff --git a/shared-core/drm.h b/shared-core/drm.h index 8329609f..f1afc049 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -891,7 +891,7 @@ typedef union drm_mm_init_arg{ /* * Drm mode setting */ - +#define DRM_OUTPUT_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 struct drm_mode_modeinfo { @@ -946,6 +946,7 @@ struct drm_mode_get_output { unsigned int output; /**< Id */ unsigned int crtc; /**< Id of crtc */ + unsigned char name[DRM_OUTPUT_NAME_LEN]; unsigned int connection; unsigned int mm_width, mm_height; /**< HxW in millimeters */ -- cgit v1.2.3 From f1476e4e5cefd4aa8c487b4e651a26056110e2f0 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 16:25:52 +1000 Subject: re-tab and fixup the i915GM get core clock function to actually work --- linux-core/intel_display.c | 186 ++++++++++++++++++++++----------------------- 1 file changed, 91 insertions(+), 95 deletions(-) diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 92b39406..75d7359f 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -583,8 +583,9 @@ static int intel_get_core_clock_speed(drm_device_t *dev) else if (IS_I945GM(dev) || IS_845G(dev)) return 200000; else if (IS_I915GM(dev)) { -#if 0 - u16 gcfgc = pciReadWord(dev->PciTag, I915_GCFGC); + u16 gcfgc = 0; + + pci_read_config_word(dev->pdev, I915_GCFGC, &gcfgc); if (gcfgc & I915_LOW_FREQUENCY_ENABLE) return 133000; @@ -597,7 +598,6 @@ static int intel_get_core_clock_speed(drm_device_t *dev) return 190000; } } -#endif } else if (IS_I865G(dev)) return 266000; else if (IS_I855(dev)) { @@ -835,106 +835,102 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc, if (intel_panel_fitter_pipe(dev) == pipe) I915_WRITE(PFIT_CONTROL, 0); + DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); + drm_mode_debug_printmodeline(dev, mode); + #if 0 - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - xf86PrintModeline(pScrn->scrnIndex, mode); - if (!xf86ModesEqual(mode, adjusted_mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - xf86PrintModeline(pScrn->scrnIndex, mode); - } - i830PrintPll("chosen", &clock); + if (!xf86ModesEqual(mode, adjusted_mode)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); + xf86PrintModeline(pScrn->scrnIndex, mode); + } + i830PrintPll("chosen", &clock); #endif - if (dpll & DPLL_VCO_ENABLE) - { + if (dpll & DPLL_VCO_ENABLE) { + I915_WRITE(fp_reg, fp); + I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + I915_READ(dpll_reg); + udelay(150); + } + + /* The LVDS pin pair needs to be on before the DPLLs are enabled. + * This is an exception to the general rule that mode_set doesn't turn + * things on. + */ + if (is_lvds) { + u32 lvds = I915_READ(LVDS); + + lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; + /* Set the B0-B3 data pairs corresponding to whether we're going to + * set the DPLLs for dual-channel mode or not. + */ + if (clock.p2 == 7) + lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; + else + lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); + + /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) + * appropriately here, but we need to look more thoroughly into how + * panels behave in the two modes. + */ + + I915_WRITE(LVDS, lvds); + I915_READ(LVDS); + } + I915_WRITE(fp_reg, fp); - I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + I915_WRITE(dpll_reg, dpll); I915_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ udelay(150); - } - - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) - { - u32 lvds = I915_READ(LVDS); - - lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; - /* Set the B0-B3 data pairs corresponding to whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - if (clock.p2 == 7) - lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - - /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) - * appropriately here, but we need to look more thoroughly into how - * panels behave in the two modes. - */ - - I915_WRITE(LVDS, lvds); - I915_READ(LVDS); - } - - I915_WRITE(fp_reg, fp); - I915_WRITE(dpll_reg, dpll); - I915_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - if (IS_I965G(dev)) { - int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; - I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | - ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); - } else { - /* write it again -- the BIOS does, after all */ - I915_WRITE(dpll_reg, dpll); - } - I915_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - udelay(150); - - I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | - ((adjusted_mode->crtc_hblank_end - 1) << 16)); - I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | - ((adjusted_mode->crtc_hsync_end - 1) << 16)); - I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | - ((adjusted_mode->crtc_vtotal - 1) << 16)); - I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | - ((adjusted_mode->crtc_vblank_end - 1) << 16)); - I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | - ((adjusted_mode->crtc_vsync_end - 1) << 16)); - I915_WRITE(dspstride_reg, crtc->fb->pitch * (crtc->fb->bits_per_pixel / 8)); - /* pipesrc and dspsize control the size that is scaled from, which should - * always be the user's requested size. - */ - I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); - I915_WRITE(dsppos_reg, 0); - I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - I915_WRITE(pipeconf_reg, pipeconf); - I915_READ(pipeconf_reg); - - intel_wait_for_vblank(dev); - - I915_WRITE(dspcntr_reg, dspcntr); - - /* Flush the plane changes */ - intel_pipe_set_base(crtc, x, y); - + + if (IS_I965G(dev)) { + int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; + I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | + ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); + } else { + /* write it again -- the BIOS does, after all */ + I915_WRITE(dpll_reg, dpll); + } + I915_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + + I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | + ((adjusted_mode->crtc_htotal - 1) << 16)); + I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | + ((adjusted_mode->crtc_hblank_end - 1) << 16)); + I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | + ((adjusted_mode->crtc_hsync_end - 1) << 16)); + I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | + ((adjusted_mode->crtc_vtotal - 1) << 16)); + I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | + ((adjusted_mode->crtc_vblank_end - 1) << 16)); + I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | + ((adjusted_mode->crtc_vsync_end - 1) << 16)); + I915_WRITE(dspstride_reg, crtc->fb->pitch * (crtc->fb->bits_per_pixel / 8)); + /* pipesrc and dspsize control the size that is scaled from, which should + * always be the user's requested size. + */ + I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); + I915_WRITE(dsppos_reg, 0); + I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); + I915_WRITE(pipeconf_reg, pipeconf); + I915_READ(pipeconf_reg); + + intel_wait_for_vblank(dev); + + I915_WRITE(dspcntr_reg, dspcntr); + + /* Flush the plane changes */ + intel_pipe_set_base(crtc, x, y); + #ifdef XF86DRI // TODO // I830DRISetVBlankInterrupt (pScrn, TRUE); #endif - - intel_wait_for_vblank(dev); - - + + intel_wait_for_vblank(dev); } /** Loads the palette/gamma unit for the CRTC with the prepared values */ @@ -1002,7 +998,7 @@ void intel_crtc_init(drm_device_t *dev, int pipe) if (crtc == NULL) return; - intel_crtc = kmalloc(sizeof(struct intel_crtc), GFP_KERNEL); + intel_crtc = kzalloc(sizeof(struct intel_crtc), GFP_KERNEL); if (intel_crtc == NULL) { kfree(crtc); return; -- cgit v1.2.3 From 23a66fd506e71fdfde906d1679fb07c0df8bec4c Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 16:26:07 +1000 Subject: fixup true/false in intel_sdvo.c --- linux-core/intel_sdvo.c | 72 ++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index 0e870d15..4a954f9e 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -298,7 +298,7 @@ static bool intel_sdvo_get_trained_inputs(struct drm_output *output, bool *input *input_1 = response.input0_trained; *input_2 = response.input1_trained; - return TRUE; + return true; } static bool intel_sdvo_get_active_outputs(struct drm_output *output, @@ -363,13 +363,13 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct drm_output *output, status = intel_sdvo_read_response(output, &clocks, sizeof(clocks)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; /* Convert the values from units of 10 kHz to kHz. */ *clock_min = clocks.min * 10; *clock_max = clocks.max * 10; - return TRUE; + return true; } static bool intel_sdvo_set_target_output(struct drm_output *output, @@ -393,15 +393,15 @@ static bool intel_sdvo_get_timing(struct drm_output *output, u8 cmd, status = intel_sdvo_read_response(output, &dtd->part1, sizeof(dtd->part1)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; intel_sdvo_write_cmd(output, cmd + 1, NULL, 0); status = intel_sdvo_read_response(output, &dtd->part2, sizeof(dtd->part2)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } static bool intel_sdvo_get_input_timing(struct drm_output *output, @@ -426,14 +426,14 @@ static bool intel_sdvo_set_timing(struct drm_output *output, u8 cmd, intel_sdvo_write_cmd(output, cmd, &dtd->part1, sizeof(dtd->part1)); status = intel_sdvo_read_response(output, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; intel_sdvo_write_cmd(output, cmd + 1, &dtd->part2, sizeof(dtd->part2)); status = intel_sdvo_read_response(output, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } static bool intel_sdvo_set_input_timing(struct drm_output *output, @@ -464,16 +464,16 @@ static bool intel_sdvo_get_preferred_input_timing(struct drm_output *output, status = intel_sdvo_read_response(output, &dtd->part1, sizeof(dtd->part1)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, NULL, 0); status = intel_sdvo_read_response(output, &dtd->part2, sizeof(dtd->part2)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } #endif @@ -502,9 +502,9 @@ static bool intel_sdvo_set_clock_rate_mult(struct drm_output *output, u8 val) intel_sdvo_write_cmd(output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); status = intel_sdvo_read_response(output, NULL, 0); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } static bool intel_sdvo_mode_fixup(struct drm_output *output, @@ -515,7 +515,7 @@ static bool intel_sdvo_mode_fixup(struct drm_output *output, * device will be told of the multiplier during mode_set. */ adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); - return TRUE; + return true; } static void intel_sdvo_mode_set(struct drm_output *output, @@ -584,7 +584,7 @@ static void intel_sdvo_mode_set(struct drm_output *output, intel_sdvo_set_output_timing(output, &output_dtd); /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, TRUE, FALSE); + intel_sdvo_set_target_input(output, true, false); /* We would like to use i830_sdvo_create_preferred_input_timing() to * provide the device with a timing it can support, if it supports that @@ -620,16 +620,20 @@ static void intel_sdvo_mode_set(struct drm_output *output, } /* Set the SDVO control regs. */ - sdvox = I915_READ(sdvo_priv->output_device); - switch (sdvo_priv->output_device) { - case SDVOB: - sdvox &= SDVOB_PRESERVE_MASK; - break; - case SDVOC: - sdvox &= SDVOC_PRESERVE_MASK; - break; - } - sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; + if (0/*IS_I965GM(dev)*/) { + sdvox = SDVO_BORDER_ENABLE; + } else { + sdvox = I915_READ(sdvo_priv->output_device); + switch (sdvo_priv->output_device) { + case SDVOB: + sdvox &= SDVOB_PRESERVE_MASK; + break; + case SDVOC: + sdvox &= SDVOC_PRESERVE_MASK; + break; + } + sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; + } if (intel_crtc->pipe == 1) sdvox |= SDVO_PIPE_B_SELECT; @@ -706,13 +710,13 @@ static void intel_sdvo_save(struct drm_output *output) intel_sdvo_get_active_outputs(output, &sdvo_priv->save_active_outputs); if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - intel_sdvo_set_target_input(output, TRUE, FALSE); + intel_sdvo_set_target_input(output, true, false); intel_sdvo_get_input_timing(output, &sdvo_priv->save_input_dtd_1); } if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - intel_sdvo_set_target_input(output, FALSE, TRUE); + intel_sdvo_set_target_input(output, false, true); intel_sdvo_get_input_timing(output, &sdvo_priv->save_input_dtd_2); } @@ -754,12 +758,12 @@ static void intel_sdvo_restore(struct drm_output *output) } if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { - intel_sdvo_set_target_input(output, TRUE, FALSE); + intel_sdvo_set_target_input(output, true, false); intel_sdvo_set_input_timing(output, &sdvo_priv->save_input_dtd_1); } if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { - intel_sdvo_set_target_input(output, FALSE, TRUE); + intel_sdvo_set_target_input(output, false, true); intel_sdvo_set_input_timing(output, &sdvo_priv->save_input_dtd_2); } @@ -805,9 +809,9 @@ static bool intel_sdvo_get_capabilities(struct drm_output *output, struct intel_ intel_sdvo_write_cmd(output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); status = intel_sdvo_read_response(output, caps, sizeof(*caps)); if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; + return false; - return TRUE; + return true; } @@ -980,7 +984,7 @@ void intel_sdvo_init(drm_device_t *dev, int output_device) } else { - unsigned char bytes[2]; + unsigned char bytes[2]; memcpy (bytes, &sdvo_priv->caps.output_flags, 2); DRM_DEBUG("%s: No active TMDS outputs (0x%02x%02x)\n", @@ -997,7 +1001,7 @@ void intel_sdvo_init(drm_device_t *dev, int output_device) /* Set the input timing to the screen. Assume always input 0. */ - intel_sdvo_set_target_input(output, TRUE, FALSE); + intel_sdvo_set_target_input(output, true, false); intel_sdvo_get_input_pixel_clock_range(output, &sdvo_priv->pixel_clock_min, -- cgit v1.2.3 From b9c7fa55e2c6685c4c533613ab14f305f033c353 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 16:32:17 +1000 Subject: fixup sarea writes for set pipe base and dpms --- linux-core/intel_display.c | 63 ++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 75d7359f..9fb497dd 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -366,27 +366,22 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y) } -#if 0 - drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen); - - if (!sPriv) + if (!dev_priv->sarea_priv) return; switch (pipe) { - case 0: - sPriv->pipeA_x = x; - sPriv->pipeA_y = y; - break; + case 0: + dev_priv->sarea_priv->pipeA_x = x; + dev_priv->sarea_priv->pipeA_y = y; + break; case 1: - sPriv->pipeB_x = x; - sPriv->pipeB_y = y; + dev_priv->sarea_priv->pipeB_x = x; + dev_priv->sarea_priv->pipeB_y = y; break; default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Can't update pipe %d in SAREA\n", pipe); + DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); break; } -#endif } /** @@ -406,6 +401,7 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; u32 temp; + bool enabled; /* XXX: When our outputs are all unaware of DPMS modes other than off * and on, we should map those modes to DPMSModeOff in the CRTC. @@ -494,30 +490,25 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) break; } -#if 0 //TODO - if (pI830->directRenderingEnabled) { - drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScrn->pScreen); - Bool enabled = crtc->enabled && mode != DPMSModeOff; - - if (!sPriv) - return; - - switch (pipe) { - case 0: - sPriv->pipeA_w = enabled ? crtc->mode.HDisplay : 0; - sPriv->pipeA_h = enabled ? crtc->mode.VDisplay : 0; - break; - case 1: - sPriv->pipeB_w = enabled ? crtc->mode.HDisplay : 0; - sPriv->pipeB_h = enabled ? crtc->mode.VDisplay : 0; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Can't update pipe %d in SAREA\n", pipe); - break; - } + + if (!dev_priv->sarea_priv) + return; + + enabled = crtc->enabled && mode != DPMSModeOff; + + switch (pipe) { + case 0: + dev_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0; + dev_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0; + break; + case 1: + dev_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0; + dev_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0; + break; + default: + DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); + break; } -#endif } static bool intel_crtc_lock(struct drm_crtc *crtc) -- cgit v1.2.3 From 50672adb3142abca743535a8e60c360ef47b2a08 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Tue, 10 Apr 2007 16:49:36 +1000 Subject: add sdvo debugging output --- linux-core/intel_sdvo.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index 4a954f9e..1b45afdb 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -209,11 +209,30 @@ static void intel_sdvo_write_cmd(struct drm_output *output, u8 cmd, void *args, int args_len) { struct intel_output *intel_output = output->driver_private; + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int i; + if (1) { + printk("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); + for (i = 0; i < args_len; i++) + printk("%02X ", ((u8 *)args)[i]); + for (; i < 8; i++) + printk(" "); + for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) { + if (cmd == sdvo_cmd_names[i].cmd) { + printk("(%s)", sdvo_cmd_names[i].name); + break; + } + } + if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0])) + printk("(%02X)",cmd); + printk("\n"); + } + for (i = 0; i < args_len; i++) { intel_sdvo_write_byte(output, SDVO_I2C_ARG_0 - i, ((u8*)args)[i]); } + intel_sdvo_write_byte(output, SDVO_I2C_OPCODE, cmd); } @@ -230,6 +249,8 @@ static const char *cmd_status_names[] = { static u8 intel_sdvo_read_response(struct drm_output *output, void *response, int response_len) { + struct intel_output *intel_output = output->driver_private; + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int i; u8 status; @@ -242,6 +263,18 @@ static u8 intel_sdvo_read_response(struct drm_output *output, void *response, /* read the return status */ intel_sdvo_read_byte(output, SDVO_I2C_CMD_STATUS, &status); + if (1) { + printk("%s: R: ", SDVO_NAME(sdvo_priv)); + for (i = 0; i < response_len; i++) + printk("%02X ", ((u8 *)response)[i]); + for (; i < 8; i++) + printk(" "); + if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) + printk("(%s)", cmd_status_names[status]); + else + printk("(??? %d)", status); + printk("\n"); + } return status; } -- cgit v1.2.3