summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drm_crtc.c74
-rw-r--r--linux-core/drm_crtc.h6
2 files changed, 53 insertions, 27 deletions
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index 2d1c8064..bdcf5f9b 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -1130,16 +1130,27 @@ EXPORT_SYMBOL(drm_mode_config_cleanup);
* RETURNS:
* Zero. (FIXME)
*/
-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)
+int drm_crtc_set_config(struct drm_mode_set *set)
{
- struct drm_device *dev = crtc->dev;
+ struct drm_device *dev;
struct drm_crtc **save_crtcs, *new_crtc;
- bool save_enabled = crtc->enabled;
+ bool save_enabled;
bool changed = false;
bool flip_or_move = false;
struct drm_output *output;
int count = 0, ro;
+ if (!set)
+ return -EINVAL;
+
+ if (!set->crtc)
+ return -EINVAL;
+
+ dev = set->crtc->dev;
+
+ /* save previous config */
+ save_enabled = set->crtc->enabled;
+
/* this is meant to be num_output not num_crtc */
save_crtcs = kzalloc(dev->mode_config.num_output * sizeof(struct drm_crtc *), GFP_KERNEL);
if (!save_crtcs)
@@ -1147,30 +1158,30 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
/* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */
- if (crtc->fb != fb)
+ if (set->crtc->fb != set->fb)
flip_or_move = true;
- if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
+ if (set->x != set->crtc->x || set->y != set->crtc->y)
flip_or_move = true;
- if (new_mode && !drm_mode_equal(new_mode, &crtc->mode)) {
+ if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
DRM_DEBUG("modes are different\n");
- drm_mode_debug_printmodeline(dev, &crtc->mode);
- drm_mode_debug_printmodeline(dev, new_mode);
+ drm_mode_debug_printmodeline(dev, &set->crtc->mode);
+ drm_mode_debug_printmodeline(dev, set->mode);
changed = true;
}
list_for_each_entry(output, &dev->mode_config.output_list, head) {
save_crtcs[count++] = output->crtc;
- if (output->crtc == crtc)
+ if (output->crtc == set->crtc)
new_crtc = NULL;
else
new_crtc = output->crtc;
- for (ro = 0; ro < crtc_info->count_outputs; ro++) {
- if (output_set[ro] == output)
- new_crtc = crtc;
+ for (ro = 0; ro < set->num_outputs; ro++) {
+ if (set->outputs[ro] == output)
+ new_crtc = set->crtc;
}
if (new_crtc != output->crtc) {
changed = true;
@@ -1179,33 +1190,34 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
}
/* mode_set_base is not a required function */
- if (flip_or_move && !crtc->funcs->mode_set_base)
+ if (flip_or_move && !set->crtc->funcs->mode_set_base)
changed = true;
if (changed) {
- crtc->fb = fb;
- crtc->enabled = (new_mode != NULL);
- if (new_mode != NULL) {
+ set->crtc->fb = set->fb;
+ set->crtc->enabled = (set->mode != NULL);
+ if (set->mode != NULL) {
DRM_DEBUG("attempting to set mode from userspace\n");
- drm_mode_debug_printmodeline(dev, new_mode);
- if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x,
- crtc_info->y)) {
- crtc->enabled = save_enabled;
+ drm_mode_debug_printmodeline(dev, set->mode);
+ if (!drm_crtc_set_mode(set->crtc, set->mode, set->x,
+ set->y)) {
+ set->crtc->enabled = save_enabled;
count = 0;
list_for_each_entry(output, &dev->mode_config.output_list, head)
output->crtc = save_crtcs[count++];
kfree(save_crtcs);
return -EINVAL;
}
- crtc->desired_x = crtc_info->x;
- crtc->desired_y = crtc_info->y;
- crtc->desired_mode = new_mode;
+ /* TODO are these needed? */
+ set->crtc->desired_x = set->x;
+ set->crtc->desired_y = set->y;
+ set->crtc->desired_mode = set->mode;
}
drm_disable_unused_functions(dev);
} else if (flip_or_move) {
- if (crtc->fb != fb)
- crtc->fb = fb;
- crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y);
+ if (set->crtc->fb != set->fb)
+ set->crtc->fb = set->fb;
+ set->crtc->funcs->mode_set_base(set->crtc, set->x, set->y);
}
kfree(save_crtcs);
@@ -1648,6 +1660,7 @@ int drm_mode_setcrtc(struct drm_device *dev,
struct drm_output **output_set = NULL, *output;
struct drm_framebuffer *fb = NULL;
struct drm_display_mode *mode = NULL;
+ struct drm_mode_set set;
uint32_t __user *set_outputs_ptr;
int ret = 0;
int i;
@@ -1724,7 +1737,14 @@ int drm_mode_setcrtc(struct drm_device *dev,
}
}
- ret = drm_crtc_set_config(crtc, crtc_req, mode, output_set, fb);
+ set.crtc = crtc;
+ set.x = crtc_req->x;
+ set.y = crtc_req->y;
+ set.mode = mode;
+ set.outputs = output_set;
+ set.num_outputs = crtc_req->count_outputs;
+ set.fb =fb;
+ ret = drm_crtc_set_config(&set);
out:
kfree(output_set);
diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h
index 64e7e519..abe8f3f3 100644
--- a/linux-core/drm_crtc.h
+++ b/linux-core/drm_crtc.h
@@ -475,11 +475,17 @@ struct drm_output {
*
* Represents a single crtc the outputs that it drives with what mode
* and from which framebuffer it scans out from.
+ *
+ * This is used to set modes.
*/
struct drm_mode_set
{
struct drm_framebuffer *fb;
struct drm_crtc *crtc;
+ struct drm_display_mode *mode;
+
+ uint32_t x;
+ uint32_t y;
struct drm_output **outputs;
size_t num_outputs;