summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-04-12 08:54:31 +1000
committerDave Airlie <airlied@linux.ie>2007-04-12 08:54:31 +1000
commit981f8156de0c5ec6387f659fbcac031d663d943c (patch)
treec5fae4b0bbe0970c9cc617d818080764c79d36ae
parenta81558d8b3ee17fbf46e32b10732e22fcd997858 (diff)
allow framebuffer changes on the crtc setup
-rw-r--r--libdrm/xf86drmMode.c2
-rw-r--r--libdrm/xf86drmMode.h2
-rw-r--r--linux-core/drm_crtc.c22
3 files changed, 20 insertions, 6 deletions
diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c
index 6070ec6f..cb534678 100644
--- a/libdrm/xf86drmMode.c
+++ b/libdrm/xf86drmMode.c
@@ -276,7 +276,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
r->mode = crtc.mode;
// r->width = crtc.width;
// r->height = crtc.height;
- r->bufferId = crtc.fb_id;
+ r->buffer_id = crtc.fb_id;
r->gamma_size = crtc.gamma_size;
r->count_outputs = crtc.count_outputs;
r->count_possibles = crtc.count_possibles;
diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h
index 6a566c4d..c87a95da 100644
--- a/libdrm/xf86drmMode.h
+++ b/libdrm/xf86drmMode.h
@@ -80,7 +80,7 @@ typedef struct drm_mode_fb_cmd drmModeFrameBuffer, *drmModeFrameBufferPtr;
typedef struct _drmModeCrtc {
- unsigned int bufferId; /**< Buffer currently connected to */
+ unsigned int buffer_id; /**< FB id to connect to 0 = disconnect*/
uint32_t x, y; /**< Position on the frameuffer */
uint32_t width, height;
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index d1f3c077..21d7012e 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -590,7 +590,7 @@ void drm_mode_config_cleanup(drm_device_t *dev)
}
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)
+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, struct drm_framebuffer *fb)
{
drm_device_t *dev = crtc->dev;
struct drm_crtc **save_crtcs, *new_crtc;
@@ -603,6 +603,9 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
if (!save_crtcs)
return -ENOMEM;
+ if (crtc->fb != fb)
+ changed = true;
+
if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
changed = true;
@@ -629,6 +632,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
}
if (changed) {
+ crtc->fb = fb;
crtc->enabled = (new_mode != NULL);
if (new_mode != NULL) {
DRM_DEBUG("attempting to set mode from userspace\n");
@@ -897,6 +901,7 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
struct drm_crtc *crtc;
struct drm_output **output_set = NULL, *output;
struct drm_display_mode *mode;
+ struct drm_framebuffer *fb = NULL;
int retcode = 0;
int i;
@@ -911,6 +916,15 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
}
if (crtc_req.mode) {
+
+ /* if we have a mode we need a framebuffer */
+ if (crtc_req.fb_id) {
+ fb = idr_find(&dev->mode_config.crtc_idr, crtc_req.fb_id);
+ if (!fb || (fb->id != crtc_req.fb_id)) {
+ DRM_DEBUG("Unknown FB ID%d\n", crtc_req.fb_id);
+ return -EINVAL;
+ }
+ }
mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode);
if (!mode || (mode->mode_id != crtc_req.mode))
{
@@ -935,8 +949,8 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
return -EINVAL;
}
- if (crtc_req.count_outputs > 0 && !mode) {
- DRM_DEBUG("Count outputs is %d but no mode set\n", crtc_req.count_outputs);
+ if (crtc_req.count_outputs > 0 && !mode && !fb) {
+ DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req.count_outputs);
return -EINVAL;
}
@@ -960,7 +974,7 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
}
}
- retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set);
+ retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb);
return retcode;
}