this stops usermode from getting a mode in the crtc it can't make sense off.
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);
}
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;
}
}
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
* 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;
}
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:
* 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);
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,
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,
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),
struct intelfb_par {
struct drm_device *dev;
struct drm_crtc *crtc;
+ struct drm_display_mode *fb_mode;
};
static int
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;
return -EINVAL;
}
#else
+
drm_mode = drm_mode_create(dev);
drm_mode->hdisplay = var->xres;
drm_mode->hsync_start = drm_mode->hdisplay + var->right_margin;
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;
}