From 4e4d9cbeb3f52b605e46aad8ae1a947ca236079f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 10:00:37 -0700 Subject: Move initial framebuffer allocation and configuration to drm_initial_config, remove i915_driver_load fb related stuff. Add a small helper for setting up outputs. --- linux-core/drm_crtc.c | 73 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 21 deletions(-) (limited to 'linux-core/drm_crtc.c') diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index adea0309..ff989265 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1,6 +1,6 @@ #include -#include "drmP.h" #include "drm.h" +#include "drmP.h" #include "drm_crtc.h" int drm_mode_idr_get(struct drm_device *dev, void *ptr) @@ -500,6 +500,15 @@ out_err: return ret; } +static void drm_setup_output(struct drm_output *output, struct drm_crtc *crtc, + struct drm_display_mode *mode) +{ + output->crtc = crtc; + output->crtc->desired_mode = mode; + output->initial_x = 0; + output->initial_y = 0; +} + /** * drm_initial_config - setup a sane initial output configuration * @dev: DRM device @@ -510,13 +519,21 @@ out_err: * At the moment, this is a cloned configuration across all heads with * @fb as the backing store. */ -bool drm_initial_config(drm_device_t *dev, struct drm_framebuffer *fb, - bool can_grow) +bool drm_initial_config(drm_device_t *dev, bool can_grow) { /* do a hardcoded initial configuration here */ - struct drm_crtc *crtc, *vga_crtc = NULL, *dvi_crtc = NULL, + struct drm_crtc *crtc, *vga_crtc = NULL, *tmds_crtc = NULL, *lvds_crtc = NULL; - struct drm_output *output, *use_output = NULL; + struct drm_output *output; + struct drm_framebuffer *fb; + drm_buffer_object_t *fbo; + unsigned long size, bytes_per_pixel; + + fb = drm_framebuffer_create(dev); + if (!fb) { + DRM_ERROR("failed to allocate fb.\n"); + return true; + } /* bind both CRTCs to this fb */ /* only initialise one crtc to enabled state */ @@ -532,8 +549,8 @@ bool drm_initial_config(drm_device_t *dev, struct drm_framebuffer *fb, crtc->enabled = 1; crtc->desired_x = 0; crtc->desired_y = 0; - } else if (!dvi_crtc) { - dvi_crtc = crtc; + } else if (!tmds_crtc) { + tmds_crtc = crtc; crtc->enabled = 1; crtc->desired_x = 0; crtc->desired_y = 0; @@ -557,29 +574,43 @@ bool drm_initial_config(drm_device_t *dev, struct drm_framebuffer *fb, break; } if (!strncmp(output->name, "VGA", 3)) { - output->crtc = vga_crtc; DRM_DEBUG("VGA preferred mode: %s\n", des_mode->name); - output->crtc->desired_mode = des_mode; - output->initial_x = 0; - output->initial_y = 0; - use_output = output; + drm_setup_output(output, vga_crtc, des_mode); } else if (!strncmp(output->name, "TMDS", 4)) { - output->crtc = vga_crtc; DRM_DEBUG("TMDS preferred mode: %s\n", des_mode->name); - output->crtc->desired_mode = des_mode; - output->initial_x = 0; - output->initial_y = 0; + drm_setup_output(output, tmds_crtc, des_mode); } else if (!strncmp(output->name, "LVDS", 3)) { - output->crtc = lvds_crtc; DRM_DEBUG("LVDS preferred mode: %s\n", des_mode->name); - output->crtc->desired_mode = des_mode; - output->initial_x = 0; - output->initial_y = 0; + drm_setup_output(output, lvds_crtc, des_mode); } else output->crtc = NULL; - + + /* FB config is max of above desired resolutions */ + /* FIXME: per-output FBs/CRTCs */ + if (des_mode->hdisplay > fb->width) { + fb->width = des_mode->hdisplay; + fb->pitch = fb->width; + } + if (des_mode->vdisplay > fb->height) + fb->height = des_mode->vdisplay; } + /* FIXME: multiple depths */ + bytes_per_pixel = 4; + fb->bits_per_pixel = bytes_per_pixel * 8; + fb->depth = bytes_per_pixel * 8; + size = fb->width * fb->height * bytes_per_pixel; + drm_buffer_object_create(dev, size, drm_bo_type_kernel, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, + 0, 0, 0, + &fbo); + DRM_DEBUG("allocated %dx%d fb: 0x%08lx\n", fb->width, fb->height, + fbo->offset); + fb->offset = fbo->offset; + fb->bo = fbo; + drmfb_probe(dev, fb); + return false; } EXPORT_SYMBOL(drm_initial_config); -- cgit v1.2.3 From 73b031df613b58c4462a65818b88200bed0a97de Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 17 Apr 2007 17:30:46 -0700 Subject: Add framebuffer bo freeing to drm_mode_config_cleanup (seems like the best place for now). --- linux-core/drm_crtc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'linux-core/drm_crtc.c') diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 1adae0d2..0fb5b9ae 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -614,8 +614,8 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE, 0, 0, 0, &fbo); - DRM_DEBUG("allocated %dx%d fb: 0x%08lx\n", fb->width, fb->height, - fbo->offset); + DRM_DEBUG("allocated %dx%d fb: 0x%08lx, bo %p\n", fb->width, + fb->height, fbo->offset, fbo); fb->offset = fbo->offset; fb->bo = fbo; drmfb_probe(dev, fb); @@ -639,6 +639,12 @@ void drm_mode_config_cleanup(drm_device_t *dev) list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { drmfb_remove(dev, fb); + /* If this FB was the kernel one, free it */ + if (fb->bo->type == drm_bo_type_kernel) { + mutex_lock(&dev->struct_mutex); + drm_bo_usage_deref_locked(fb->bo); + mutex_unlock(&dev->struct_mutex); + } drm_framebuffer_destroy(fb); } } -- cgit v1.2.3 From d20aaf485893ed11dd0d68daf63ccadd77b02213 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 18 Apr 2007 10:41:39 +1000 Subject: don't crash if no desired mode --- linux-core/drm_crtc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'linux-core/drm_crtc.c') diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 0fb5b9ae..437259d5 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -572,7 +572,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) /* bind analog output to one crtc */ list_for_each_entry(output, &dev->mode_config.output_list, head) { - struct drm_display_mode *des_mode; + struct drm_display_mode *des_mode = NULL; if (list_empty(&output->modes)) continue; @@ -582,6 +582,10 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) if (des_mode->flags & DRM_MODE_TYPE_PREFERRED) break; } + + if (!des_mode) + continue; + if (!strncmp(output->name, "VGA", 3)) { DRM_DEBUG("VGA preferred mode: %s\n", des_mode->name); drm_setup_output(output, vga_crtc, des_mode); -- cgit v1.2.3 From 20b2949e3738bc900407d6aeddc6338f05b0b169 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 18 Apr 2007 14:55:43 +1000 Subject: make sure TMDS gets a crtc --- linux-core/drm_crtc.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'linux-core/drm_crtc.c') diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 437259d5..e8f42feb 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -553,16 +553,19 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow) crtc->enabled = 1; crtc->desired_x = 0; crtc->desired_y = 0; - } else if (!lvds_crtc) { - lvds_crtc = crtc; - crtc->enabled = 1; - crtc->desired_x = 0; - crtc->desired_y = 0; - } else if (!tmds_crtc) { - tmds_crtc = crtc; - crtc->enabled = 1; - crtc->desired_x = 0; - crtc->desired_y = 0; + } else { + if (!lvds_crtc) { + lvds_crtc = crtc; + crtc->enabled = 1; + crtc->desired_x = 0; + crtc->desired_y = 0; + } + if (!tmds_crtc) { + tmds_crtc = crtc; + crtc->enabled = 1; + crtc->desired_x = 0; + crtc->desired_y = 0; + } } } -- cgit v1.2.3