summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2007-11-26 14:05:49 +1100
committerDave Airlie <airlied@redhat.com>2007-11-26 14:05:49 +1100
commit53b4e0cb789151164a0a43b55058319667847aaf (patch)
treeb2e3e1cdce58d1897085e26f09e16058bcedaa66
parenta20587e3950f849deb1e723a0b4455a19f7b3fb8 (diff)
drm: make fb modes use usermode add/remove interface
this stops usermode from getting a mode in the crtc it can't make sense off.
-rw-r--r--linux-core/drm_crtc.c62
-rw-r--r--linux-core/drm_crtc.h11
-rw-r--r--linux-core/drm_drv.c4
-rw-r--r--linux-core/intel_fb.c15
4 files changed, 54 insertions, 38 deletions
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index df934841..87302555 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -439,7 +439,7 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
if (output->crtc != crtc)
continue;
- DRM_INFO("%s: set mode %s\n", output->name, mode->name);
+ DRM_INFO("%s: set mode %s %x\n", output->name, mode->name, mode->mode_id);
output->funcs->mode_set(output, mode, adjusted_mode);
}
@@ -858,7 +858,7 @@ clone:
output->crtc->desired_mode = des_mode;
output->initial_x = 0;
output->initial_y = 0;
- DRM_DEBUG("Desired mode for CRTC %d is %s\n",c,des_mode->name);
+ DRM_DEBUG("Desired mode for CRTC %d is 0x%x:%s\n",c,des_mode->mode_id, des_mode->name);
break;
}
}
@@ -1694,8 +1694,36 @@ void drm_fb_release(struct file *filp)
mutex_unlock(&dev->mode_config.mutex);
}
+/*
+ *
+ */
+void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode)
+{
+ user_mode->type |= DRM_MODE_TYPE_USERDEF;
+
+ user_mode->output_count = 0;
+ list_add(&user_mode->head, &dev->mode_config.usermode_list);
+}
+EXPORT_SYMBOL(drm_mode_addmode);
+
+int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode)
+{
+ struct drm_display_mode *t;
+ int ret = -EINVAL;
+ list_for_each_entry(t, &dev->mode_config.usermode_list, head) {
+ if (t == mode) {
+ list_del(&mode->head);
+ drm_mode_destroy(dev, mode);
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+EXPORT_SYMBOL(drm_mode_rmmode);
+
/**
- * drm_fb_newmode - adds a user defined mode
+ * drm_fb_addmode - adds a user defined mode
* @inode: inode from the ioctl
* @filp: file * from the ioctl
* @cmd: cmd from ioctl
@@ -1709,8 +1737,8 @@ void drm_fb_release(struct file *filp)
* writes new mode id into arg.
* Zero on success, errno on failure.
*/
-int drm_mode_addmode(struct drm_device *dev,
- void *data, struct drm_file *file_priv)
+int drm_mode_addmode_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
{
struct drm_mode_modeinfo *new_mode = data;
struct drm_display_mode *user_mode;
@@ -1724,12 +1752,8 @@ int drm_mode_addmode(struct drm_device *dev,
}
drm_crtc_convert_umode(user_mode, new_mode);
- user_mode->type |= DRM_MODE_TYPE_USERDEF;
-
- user_mode->output_count = 0;
-
- list_add(&user_mode->head, &dev->mode_config.usermode_list);
+ drm_mode_addmode(dev, user_mode);
new_mode->id = user_mode->mode_id;
out:
@@ -1751,38 +1775,28 @@ out:
* RETURNS:
* Zero on success, errno on failure.
*/
-int drm_mode_rmmode(struct drm_device *dev,
- void *data, struct drm_file *file_priv)
+int drm_mode_rmmode_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
{
uint32_t *id = data;
- struct drm_display_mode *mode, *t;
+ struct drm_display_mode *mode;
int ret = -EINVAL;
mutex_lock(&dev->mode_config.mutex);
mode = idr_find(&dev->mode_config.crtc_idr, *id);
if (!mode || (*id != mode->mode_id)) {
- ret = -EINVAL;
goto out;
}
if (!(mode->type & DRM_MODE_TYPE_USERDEF)) {
- ret = -EINVAL;
goto out;
}
if (mode->output_count) {
- ret = -EINVAL;
goto out;
}
- list_for_each_entry(t, &dev->mode_config.usermode_list, head) {
- if (t == mode) {
- list_del(&mode->head);
- drm_mode_destroy(dev, mode);
- ret = 0;
- break;
- }
- }
+ ret = drm_mode_rmmode(dev, mode);
out:
mutex_unlock(&dev->mode_config.mutex);
diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h
index 0645dd6a..f555b6bb 100644
--- a/linux-core/drm_crtc.h
+++ b/linux-core/drm_crtc.h
@@ -494,6 +494,9 @@ extern void drm_mode_set_name(struct drm_display_mode *mode);
extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2);
extern void drm_disable_unused_functions(struct drm_device *dev);
+extern void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode);
+extern int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode);
+
extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
extern void drm_mode_list_concat(struct list_head *head,
@@ -536,10 +539,10 @@ extern int drm_mode_rmfb(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern int drm_mode_getfb(struct drm_device *dev,
void *data, struct drm_file *file_priv);
-extern int drm_mode_addmode(struct drm_device *dev,
- void *data, struct drm_file *file_priv);
-extern int drm_mode_rmmode(struct drm_device *dev,
- void *data, struct drm_file *file_priv);
+extern int drm_mode_addmode_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
+extern int drm_mode_rmmode_ioctl(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
extern int drm_mode_attachmode(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern int drm_mode_detachmode(struct drm_device *dev,
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index 8cd7afb1..5156d15d 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -124,8 +124,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode, DRM_MASTER|DRM_ROOT_ONLY),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode, DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode, DRM_MASTER|DRM_ROOT_ONLY),
diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c
index 564a913e..3a4ffc7f 100644
--- a/linux-core/intel_fb.c
+++ b/linux-core/intel_fb.c
@@ -47,6 +47,7 @@
struct intelfb_par {
struct drm_device *dev;
struct drm_crtc *crtc;
+ struct drm_display_mode *fb_mode;
};
static int
@@ -107,7 +108,6 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
struct intelfb_par *par = info->par;
struct drm_device *dev = par->dev;
struct drm_framebuffer *fb = par->crtc->fb;
- struct drm_display_mode *drm_mode;
struct drm_output *output;
int depth, found = 0;
@@ -275,6 +275,7 @@ static int intelfb_set_par(struct fb_info *info)
return -EINVAL;
}
#else
+
drm_mode = drm_mode_create(dev);
drm_mode->hdisplay = var->xres;
drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin;
@@ -290,18 +291,16 @@ static int intelfb_set_par(struct fb_info *info)
drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);
#endif
+ drm_mode_addmode(dev, drm_mode);
+ if (par->fb_mode)
+ drm_mode_rmmode(dev, par->fb_mode);
+
+ par->fb_mode = drm_mode;
drm_mode_debug_printmodeline(dev, drm_mode);
if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0))
return -EINVAL;
- /* Have to destroy our created mode if we're not searching the mode
- * list for it.
- */
-#if 1
- drm_mode_destroy(dev, drm_mode);
-#endif
-
return 0;
}