Various changes for in-kernel modesetting:
authorJesse Barnes <jbarnes@hobbes.virtuousgeek.org>
Wed, 11 Apr 2007 14:07:54 +0000 (07:07 -0700)
committerJesse Barnes <jbarnes@hobbes.virtuousgeek.org>
Wed, 11 Apr 2007 14:07:54 +0000 (07:07 -0700)
  - allow drm_buffer_object_create to be called w/o dev_mapping
  - fixup i915 init code to allocate memory, fb and set modes right
  - pass fb to drm_initial_config for setup
  - change some debug output to make it easier to spot
  - fixup lvds code to use DDC probing correctly

linux-core/drm_bo.c
linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/intel_display.c
linux-core/intel_lvds.c
shared-core/i915_init.c

index 17d6fbc..2107a3a 100644 (file)
@@ -1530,7 +1530,7 @@ static int drm_bo_handle_wait(drm_file_t * priv, uint32_t handle,
        return ret;
 }
 
-int drm_buffer_object_create(drm_file_t * priv,
+int drm_buffer_object_create(drm_device_t *dev,
                             unsigned long size,
                             drm_bo_type_t type,
                             uint32_t mask,
@@ -1539,7 +1539,6 @@ int drm_buffer_object_create(drm_file_t * priv,
                             unsigned long buffer_start,
                             drm_buffer_object_t ** buf_obj)
 {
-       drm_device_t *dev = priv->head->dev;
        drm_buffer_manager_t *bm = &dev->bm;
        drm_buffer_object_t *bo;
        int ret = 0;
@@ -1615,6 +1614,7 @@ int drm_buffer_object_create(drm_file_t * priv,
        drm_bo_usage_deref_unlocked(bo);
        return ret;
 }
+EXPORT_SYMBOL(drm_buffer_object_create);
 
 static int drm_bo_add_user_object(drm_file_t * priv, drm_buffer_object_t * bo,
                                  int shareable)
@@ -1670,7 +1670,8 @@ int drm_bo_ioctl(DRM_IOCTL_ARGS)
                switch (req->op) {
                case drm_bo_create:
                        rep.ret =
-                           drm_buffer_object_create(priv, req->size,
+                           drm_buffer_object_create(priv->head->dev,
+                                                    req->size,
                                                     req->type,
                                                     req->mask,
                                                     req->hint,
@@ -2301,6 +2302,9 @@ void drm_bo_unmap_virtual(drm_buffer_object_t * bo)
        loff_t offset = ((loff_t) bo->map_list.hash.key) << PAGE_SHIFT;
        loff_t holelen = ((loff_t) bo->mem.num_pages) << PAGE_SHIFT;
 
+       if (!dev->dev_mapping)
+               return;
+
        unmap_mapping_range(dev->dev_mapping, offset, holelen, 1);
 }
 
index 1c1c300..b349527 100644 (file)
@@ -57,6 +57,7 @@ struct drm_framebuffer *drm_framebuffer_create(drm_device_t *dev)
 
        return fb;
 }
+EXPORT_SYMBOL(drm_framebuffer_create);
 
 void drm_framebuffer_destroy(struct drm_framebuffer *fb)
 {
@@ -493,30 +494,28 @@ out_err:
        return ret;
 }
 
-bool drm_initial_config(drm_device_t *dev, bool can_grow)
+/**
+ * drm_initial_config - setup a sane initial output configuration
+ * @dev: DRM device
+ * @fb: framebuffer backing for new setup
+ * @can_grow: this configuration is growable
+ *
+ * Scan the CRTCs and outputs and try to put together an initial setup.
+ * 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)
 {
        /* do a hardcoded initial configuration here */
        struct drm_crtc *crtc, *vga_crtc = NULL, *dvi_crtc = NULL,
                *lvds_crtc = NULL;
-       struct drm_framebuffer *fb;
        struct drm_output *output, *use_output = NULL;
 
-#if 0
-       fb = drm_framebuffer_create(dev);
-       if (!fb)
-               return false;
-
-       fb->pitch = 1024;
-       fb->width = 1024;
-       fb->height = 768;
-       fb->depth = 24;
-       fb->bits_per_pixel = 32;
-#endif
-
        /* bind both CRTCs to this fb */
        /* only initialise one crtc to enabled state */
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-               //              crtc->fb = fb;
+               crtc->fb = fb;
                if (!vga_crtc) {
                        vga_crtc = crtc;
                        crtc->enabled = 1;
@@ -527,8 +526,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow)
                        crtc->enabled = 1;
                        crtc->desired_x = 0;
                        crtc->desired_y = 0;
-               }
-               else if (!dvi_crtc) {
+               } else if (!dvi_crtc) {
                        dvi_crtc = crtc;
                        crtc->enabled = 1;
                        crtc->desired_x = 0;
@@ -536,7 +534,7 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow)
                }
        }
 
-       drm_crtc_probe_output_modes(dev, 1024, 768);
+       drm_crtc_probe_output_modes(dev, 2048, 2048);
 
        /* hard bind the CRTCS */
 
@@ -551,20 +549,20 @@ bool drm_initial_config(drm_device_t *dev, bool can_grow)
                }
                if (!strncmp(output->name, "VGA", 3)) {
                        output->crtc = vga_crtc;
-                       drm_mode_debug_printmodeline(dev, des_mode);
+                       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;
                } else if (!strncmp(output->name, "TMDS", 4)) {
                        output->crtc = vga_crtc;
-                       drm_mode_debug_printmodeline(dev, des_mode);
+                       DRM_DEBUG("TMDS preferred mode: %s\n", des_mode->name);
                        output->crtc->desired_mode = des_mode;
                        output->initial_x = 0;
                        output->initial_y = 0;
                } else  if (!strncmp(output->name, "LVDS", 3)) {
                        output->crtc = lvds_crtc;
-                       drm_mode_debug_printmodeline(dev, des_mode);
+                       DRM_DEBUG("LVDS preferred mode: %s\n", des_mode->name);
                        output->crtc->desired_mode = des_mode;
                        output->initial_x = 0;
                        output->initial_y = 0;
index d5d256d..54c508c 100644 (file)
@@ -452,10 +452,13 @@ extern int drm_mode_vrefresh(struct drm_display_mode *mode);
 extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
                                  int adjust_flags);
 extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
-extern bool drm_initial_config(struct drm_device *dev, bool cangrow);
+extern bool drm_initial_config(struct drm_device *dev,
+                              struct drm_framebuffer *fb, bool cangrow);
 extern void drm_framebuffer_set_object(struct drm_device *dev,
                                       unsigned long handle);
 extern bool drm_set_desired_modes(struct drm_device *dev);
+extern int drmfb_probe(struct drm_device *dev, struct drm_framebuffer *fb);
+extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
 
 /* IOCTLs */
 extern int drm_mode_getresources(struct inode *inode, struct file *filp,
index 04a6e08..bb6f7f2 100644 (file)
@@ -1128,11 +1128,9 @@ static void intel_setup_outputs(drm_device_t *dev)
 
        intel_crt_init(dev);
 
-#if 0
        /* Set up integrated LVDS */
        if (IS_MOBILE(dev) && !IS_I830(dev))
                intel_lvds_init(dev);
-#endif
 
        if (IS_I9XX(dev)) {
                intel_sdvo_init(dev, SDVOB);
index 90a2610..8ecb204 100644 (file)
@@ -164,6 +164,7 @@ static bool intel_lvds_mode_fixup(struct drm_output *output,
        struct intel_crtc *intel_crtc = output->crtc->driver_private;
        struct drm_output *tmp_output;
 
+#if 0
        spin_lock(&dev->mode_config.config_lock);
        list_for_each_entry(tmp_output, &dev->mode_config.output_list, head) {
                if (tmp_output != output && tmp_output->crtc == output->crtc) {
@@ -173,6 +174,7 @@ static bool intel_lvds_mode_fixup(struct drm_output *output,
                }
        }
        spin_lock(&dev->mode_config.config_lock);
+#endif
 
        if (intel_crtc->pipe == 0) {
                printk(KERN_ERR "Can't support LVDS on pipe A\n");
@@ -199,7 +201,7 @@ static bool intel_lvds_mode_fixup(struct drm_output *output,
                        dev_priv->panel_fixed_mode->vsync_end;
                adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
                adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
-//             xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
+               drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
        }
 
        /*
@@ -272,11 +274,11 @@ static int intel_lvds_get_modes(struct drm_output *output)
                           "failed.\n");
                return 0;
        }
-       intel_i2c_destroy(intel_output->ddc_bus);
 
        ret = intel_ddc_get_modes(output);
        if (ret)
                return ret;
+       intel_i2c_destroy(intel_output->ddc_bus);
 
        /* Didn't get an EDID */
        if (!output->monitor_info) {
@@ -359,19 +361,31 @@ void intel_lvds_init(struct drm_device *dev)
        output->interlace_allowed = FALSE;
        output->doublescan_allowed = FALSE;
 
+       /* Set up the DDC bus. */
+       intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
+       if (!intel_output->ddc_bus) {
+               dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
+                          "failed.\n");
+               return;
+       }
+
        /*
         * Attempt to get the fixed panel mode from DDC.  Assume that the
         * preferred mode is the right one.
         */
        intel_ddc_get_modes(output);
+       intel_i2c_destroy(intel_output->ddc_bus);
        list_for_each_entry(scan, &output->probed_modes, head) {
                if (scan->type & DRM_MODE_TYPE_PREFERRED)
                        break;
        }
 
-       if (scan)
+       if (scan) {
                dev_priv->panel_fixed_mode = scan;
+               DRM_DEBUG("LVDS panel_fixed: %s\n", scan->name);
+       }
 
+#if 0
        /*
         * If we didn't get EDID, try checking if the panel is already turned
         * on.  If so, assume that whatever is currently programmed is the
@@ -395,7 +409,6 @@ void intel_lvds_init(struct drm_device *dev)
        }
 
 /* No BIOS poking yet... */
-#if 0
        /* Get the LVDS fixed mode out of the BIOS.  We should support LVDS
         * with the BIOS being unavailable or broken, but lack the
         * configuration options for now.
index 5af86f8..d9fb485 100644 (file)
@@ -4,10 +4,23 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 
+/**
+ * i915_driver_load - setup chip and create an initial config
+ * @dev: DRM device
+ * @flags: startup flags
+ *
+ * The driver load routine has to do several things:
+ *   - drive output discovery via intel_modeset_init()
+ *   - initialize the memory manager
+ *   - allocate initial config memory
+ *   - setup the DRM framebuffer with the allocated memory
+ */
 int i915_driver_load(drm_device_t *dev, unsigned long flags)
 {
        drm_i915_private_t *dev_priv;
        drm_i915_init_t init;
+       drm_buffer_object_t *entry;
+       struct drm_framebuffer *fb;
        int ret;
 
        dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
@@ -45,7 +58,6 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags)
                return ret;
        }
 
-#if 0  
        ret = drm_setup(dev);
        if (ret) {
                DRM_ERROR("drm_setup failed\n");
@@ -60,17 +72,48 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags)
                return DRM_ERR(EINVAL);
        }
 
-       /* FIXME: where does the sarea_priv really go? */
-        //     dev_priv->sarea_priv = kmalloc(sizeof(drm_i915_sarea_t), GFP_KERNEL);
+       /* FIXME: assume sarea_priv is right after SAREA */
+        dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(drm_sarea_t);
 
-       /* FIXME: need real front buffer offset */
-        ///    dev_priv->sarea_priv->front_handle = dev_priv->baseaddr + 1024*1024;
-#endif
+       /*
+        * Initialize the memory manager for local and AGP space
+        */
        drm_bo_driver_init(dev);
-       /* this probably doesn't belong here - TODO */
-       //drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle);
+       /* FIXME: initial stolen area 8M init */
+#define SCANOUT_SIZE 1024*1024*8 /* big enough for 2048x1024 32bpp */
+       drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev->mode_config.fb_base,
+                      SCANOUT_SIZE);
+
+       /* Allocate scanout buffer and command ring */
+       /* FIXME: types and other args correct? */
+       drm_buffer_object_create(dev, SCANOUT_SIZE, drm_bo_type_dc,
+                                DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
+                                DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE,
+                                0, PAGE_SIZE, 0,
+                                &entry);
+
+       DRM_DEBUG("allocated bo, start: 0x%lx, offset: 0x%lx\n",
+                 entry->buffer_start, entry->offset);
        intel_modeset_init(dev);
-        //     drm_set_desired_modes(dev);
+
+       fb = drm_framebuffer_create(dev);
+       if (!fb) {
+               DRM_ERROR("failed to allocate fb\n");
+               return -EINVAL;
+       }
+
+       fb->width = 1024;
+       fb->height = 768;
+       fb->pitch = 1024;
+       fb->bits_per_pixel = 32;
+       fb->depth = 32;
+       fb->offset = entry->offset;
+       fb->bo = entry;
+
+       drm_initial_config(dev, fb, false);
+       drmfb_probe(dev, fb);
+        drm_set_desired_modes(dev);
+
 #if 0
        /* FIXME: command ring needs AGP space, do we own it at this point? */
        dev_priv->ring.Start = dev_priv->baseaddr;
@@ -133,8 +176,10 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags)
 int i915_driver_unload(drm_device_t *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_framebuffer *fb;
 
-       intel_modeset_cleanup(dev);
+       /* FIXME: remove framebuffer */
+       //intel_modeset_cleanup(dev);
        drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
 
        dev->dev_private = NULL;