crtc->mode = saved_mode;
crtc->x = saved_x;
crtc->y = saved_y;
- }
-
+ }
+
return ret;
}
EXPORT_SYMBOL(drm_crtc_set_mode);
drm_pick_crtcs(dev);
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-
- /* can't setup the crtc if there's no assigned mode */
- if (!crtc->desired_mode)
- continue;
-
- /* Now setup the fbdev for attached crtcs */
- dev->driver->fb_probe(dev, crtc);
- }
-
/* This is a little screwy, as we've already walked the outputs
* above, but it's a little bit of magic too. There's the potential
* for things not to get setup above if an existing device gets
if (!output->crtc || !output->crtc->desired_mode)
continue;
+ dev->driver->fb_probe(dev, output->crtc, output);
+
/* and needs an attached fb */
if (output->crtc->fb)
drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0);
struct drm_output *output;
int count = 0, ro;
+ DRM_DEBUG("\n");
+
if (!set)
return -EINVAL;
if (!set->crtc)
return -EINVAL;
+ DRM_DEBUG("crtc: %p fb: %p outputs: %p num_outputs: %i (x, y) (%i, %i)\n", set->crtc, set->fb, set->outputs, set->num_outputs, set->x, set->y);
dev = set->crtc->dev;
/* save previous config */
kfree(save_crtcs);
return 0;
}
+EXPORT_SYMBOL(drm_crtc_set_config);
/**
* drm_hotplug_stage_two
/* We should really check if there is a fb using this crtc */
if (!has_config)
- dev->driver->fb_probe(dev, output->crtc);
+ dev->driver->fb_probe(dev, output->crtc, output);
else {
dev->driver->fb_resize(dev, output->crtc);
struct intelfb_par {
struct drm_device *dev;
+/*
struct drm_crtc *crtc;
struct drm_display_mode *fb_mode;
struct drm_framebuffer *fb;
+*/
+ struct drm_display_mode *our_mode;
struct drm_mode_set set;
+ struct drm_output *hack;
};
/*
static int
struct fb_info *info)
{
struct intelfb_par *par = info->par;
- struct drm_framebuffer *fb = par->fb;
- struct drm_crtc *crtc = par->crtc;
+ struct drm_framebuffer *fb = par->set.fb;
+ struct drm_crtc *crtc = par->set.crtc;
if (regno > 255)
return 1;
{
struct intelfb_par *par = info->par;
/*struct drm_device *dev = par->dev;*/
- struct drm_framebuffer *fb = par->fb;
+ struct drm_framebuffer *fb = par->set.fb;
/*struct drm_output *output;*/
int depth/*, found = 0*/;
static int intelfb_set_par(struct fb_info *info)
{
struct intelfb_par *par = info->par;
- struct drm_framebuffer *fb = par->fb;
+ struct drm_framebuffer *fb = par->set.fb;
struct drm_device *dev = par->dev;
struct drm_display_mode *drm_mode, *search_mode;
struct drm_output *output = NULL;
struct fb_var_screeninfo *var = &info->var;
int found = 0;
- int changed = 0;
DRM_DEBUG("\n");
found = 0;
list_for_each_entry(output, &dev->mode_config.output_list, head) {
- if (output->crtc == par->crtc){
+ if (output->crtc == par->set.crtc){
found = 1;
break;
}
* create a new attachment for the incoming user specified mode
*/
if (!found) {
- if (par->fb_mode) {
+ if (par->our_mode) {
/* this also destroys the mode */
- drm_mode_detachmode_crtc(dev, par->fb_mode);
+ drm_mode_detachmode_crtc(dev, par->our_mode);
}
- par->fb_mode = drm_mode;
+ par->set.mode = drm_mode;
+ par->our_mode = drm_mode;
drm_mode_debug_printmodeline(dev, drm_mode);
/* attach mode */
- drm_mode_attachmode_crtc(dev, par->crtc, par->fb_mode);
+ drm_mode_attachmode_crtc(dev, par->set.crtc, par->set.mode);
+ } else {
+ par->set.mode = drm_mode;
+ if (par->our_mode)
+ drm_mode_detachmode_crtc(dev, par->our_mode);
+ par->our_mode = NULL;
}
+#if 0
/* re-attach fb */
if (!par->crtc->fb) {
par->crtc->fb = par->fb;
return -EINVAL;
return 0;
+#else
+ return drm_crtc_set_config(&par->set);
+#endif
}
#if 0
struct fb_info *info)
{
struct intelfb_par *par = info->par;
- struct drm_crtc *crtc = par->crtc;
- int changed = 0;
+ int ret;
DRM_DEBUG("\n");
- /* TODO add check size and pos*/
- if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset)
- changed = 1;
-
- /* re-attach fb */
- if (!crtc->fb) {
- crtc->fb = par->fb;
- changed = 1;
- }
+ par->set.x = var->xoffset;
+ par->set.y = var->yoffset;
- if (changed)
- drm_crtc_set_mode(crtc, &crtc->mode, var->xoffset, var->yoffset);
+ ret = drm_crtc_set_config(&par->set);
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
+ if (!ret) {
+ info->var.xoffset = var->xoffset;
+ info->var.yoffset = var->yoffset;
+ }
- return 0;
+ return ret;
}
static struct fb_ops intelfb_ops = {
}
EXPORT_SYMBOL(intelfb_resize);
-int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
+int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output)
{
struct fb_info *info;
struct intelfb_par *par;
return -EINVAL;
}
+ if (!output)
+ return -EINVAL;
+
fb = drm_framebuffer_create(dev);
if (!fb) {
framebuffer_release(info);
par = info->par;
par->dev = dev;
- par->crtc = crtc;
- par->fb = fb;
+ par->set.crtc = crtc;
+ par->set.fb = fb;
+ par->hack = output;
+ par->set.outputs = &par->hack;
+ par->set.num_outputs = 1;
info->fbops = &intelfb_ops;