Merge branch 'modesetting-101' of git+ssh://git.freedesktop.org/git/mesa/drm into...
authorJesse Barnes <jbarnes@hobbes.virtuousgeek.org>
Tue, 10 Apr 2007 17:45:55 +0000 (10:45 -0700)
committerJesse Barnes <jbarnes@hobbes.virtuousgeek.org>
Tue, 10 Apr 2007 17:45:55 +0000 (10:45 -0700)
Conflicts:

linux-core/drm_crtc.c - trivial merge
linux-core/drm_crtc.h - trivial merge
linux-core/intel_display.c - crtc_config -> mode_config
shared-core/i915_dma.c - accommodate new init code in i915_init.c

1  2 
linux-core/Makefile.kernel
linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/intel_display.c
linux-core/intel_lvds.c
shared-core/i915_dma.c
shared-core/i915_drv.h
shared-core/i915_init.c

@@@ -21,7 -21,7 +21,7 @@@ mga-objs    := mga_drv.o mga_dma.o mga_
  i810-objs   := i810_drv.o i810_dma.o
  i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o \
                i915_buffer.o intel_display.o intel_crt.o intel_lvds.o \
--              intel_sdvo.o intel_modes.o intel_i2c.o
++              intel_sdvo.o intel_modes.o intel_i2c.o i915_init.o
  nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
                nouveau_object.o nouveau_irq.o \
                nv04_timer.o \
@@@ -116,8 -116,7 +116,8 @@@ bool drm_crtc_in_use(struct drm_crtc *c
  {
        struct drm_output *output;
        drm_device_t *dev = crtc->dev;
-       list_for_each_entry(output, &dev->crtc_config.output_list, head)
 +      /* FIXME: Locking around list access? */
+       list_for_each_entry(output, &dev->mode_config.output_list, head)
                if (output->crtc == crtc)
                        return true;
        return false;
@@@ -518,11 -512,12 +513,12 @@@ bool drm_initial_config(drm_device_t *d
        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->crtc_config.crtc_list, head) {
-               crtc->fb = fb;
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               //              crtc->fb = fb;
                if (!vga_crtc) {
                        vga_crtc = crtc;
                        crtc->enabled = 1;
@@@ -455,11 -444,20 +445,25 @@@ extern void drm_mode_sort(struct list_h
  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 void drm_framebuffer_set_object(struct drm_device *dev,
 +                                     unsigned long handle);
 +extern bool drm_set_desired_modes(struct drm_device *dev);
  
+ /* IOCTLs */
+ extern int drm_mode_getresources(struct inode *inode, struct file *filp,
+                                unsigned int cmd, unsigned long arg);
+ extern int drm_mode_getcrtc(struct inode *inode, struct file *filp,
+                           unsigned int cmd, unsigned long arg);
+ extern int drm_mode_getoutput(struct inode *inode, struct file *filp,
+                             unsigned int cmd, unsigned long arg);
+ extern int drm_mode_setcrtc(struct inode *inode, struct file *filp,
+                           unsigned int cmd, unsigned long arg);
+ extern int drm_mode_addfb(struct inode *inode, struct file *filp,
+                         unsigned int cmd, unsigned long arg);
+ extern int drm_mode_rmfb(struct inode *inode, struct file *filp,
+                        unsigned int cmd, unsigned long arg);
  #endif /* __DRM_CRTC_H__ */
  
@@@ -349,9 -351,10 +349,10 @@@ intel_pipe_set_base(struct drm_crtc *cr
        int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
        int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
        
-       Start = crtc->fb->offset;
+       Start = crtc->fb->offset + dev_priv->baseaddr;
        Offset = ((y * crtc->fb->width + x) * (crtc->fb->bits_per_pixel / 8));
  
 -      DRM_DEBUG("Writing base %08X %08X %d %d\n", Start, Offset, x, y);
++      DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
        if (IS_I965G(dev)) {
                I915_WRITE(dspbase, Offset);
                I915_READ(dspbase);
@@@ -1209,8 -1097,7 +1202,8 @@@ void intel_modeset_init(drm_device_t *d
  
        intel_setup_outputs(dev);
  
-       drm_initial_config(dev, false);
-       drm_set_desired_modes(dev);
+       //drm_initial_config(dev, false);
++      //drm_set_desired_modes(dev);
  }
  
  void intel_modeset_cleanup(drm_device_t *dev)
@@@ -62,251 -63,25 +62,251 @@@ static u32 intel_lvds_get_max_backlight
                BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
  }
  
 -int lvds_backlight(DRM_IOCTL_ARGS)
 +/**
 + * Sets the power state for the panel.
 + */
 +static void intel_lvds_set_power(struct drm_device *dev, bool on)
 +{
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +      u32 pp_status;
 +
 +      if (on) {
 +              I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) |
 +                         POWER_TARGET_ON);
 +              do {
 +                      pp_status = I915_READ(PP_STATUS);
 +              } while ((pp_status & PP_ON) == 0);
 +
 +              intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
 +      } else {
 +              intel_lvds_set_backlight(dev, 0);
 +
 +              I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) &
 +                         ~POWER_TARGET_ON);
 +              do {
 +                      pp_status = I915_READ(PP_STATUS);
 +              } while (pp_status & PP_ON);
 +      }
 +}
 +
 +static void intel_lvds_dpms(struct drm_output *output, int mode)
 +{
 +      struct drm_device *dev = output->dev;
 +
 +      if (mode == DPMSModeOn)
 +              intel_lvds_set_power(dev, true);
 +      else
 +              intel_lvds_set_power(dev, false);
 +
 +      /* XXX: We never power down the LVDS pairs. */
 +}
 +
 +static void intel_lvds_save(struct drm_output *output)
 +{
 +      struct drm_device *dev = output->dev;
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +
 +      dev_priv->savePP_ON = I915_READ(LVDSPP_ON);
 +      dev_priv->savePP_OFF = I915_READ(LVDSPP_OFF);
 +      dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
 +      dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
 +      dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
 +      dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
 +                                     BACKLIGHT_DUTY_CYCLE_MASK);
 +
 +      /*
 +       * If the light is off at server startup, just make it full brightness
 +       */
 +      if (dev_priv->backlight_duty_cycle == 0)
 +              dev_priv->backlight_duty_cycle =
 +                      intel_lvds_get_max_backlight(dev);
 +}
 +
 +static void intel_lvds_restore(struct drm_output *output)
 +{
 +      struct drm_device *dev = output->dev;
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +
 +      I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
 +      I915_WRITE(LVDSPP_ON, dev_priv->savePP_ON);
 +      I915_WRITE(LVDSPP_OFF, dev_priv->savePP_OFF);
 +      I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
 +      I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
 +      if (dev_priv->savePP_CONTROL & POWER_TARGET_ON)
 +              intel_lvds_set_power(dev, true);
 +      else
 +              intel_lvds_set_power(dev, false);
 +}
 +
 +static int intel_lvds_mode_valid(struct drm_output *output,
 +                               struct drm_display_mode *mode)
 +{
 +      struct drm_device *dev = output->dev;
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
 +
 +      if (fixed_mode) {
 +              if (mode->hdisplay > fixed_mode->hdisplay)
 +                      return MODE_PANEL;
 +              if (mode->vdisplay > fixed_mode->vdisplay)
 +                      return MODE_PANEL;
 +      }
 +
 +      return MODE_OK;
 +}
 +
 +static bool intel_lvds_mode_fixup(struct drm_output *output,
 +                                struct drm_display_mode *mode,
 +                                struct drm_display_mode *adjusted_mode)
 +{
 +      struct drm_device *dev = output->dev;
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = output->crtc->driver_private;
 +      struct drm_output *tmp_output;
 +
-       spin_lock(&dev->crtc_config.config_lock);
-       list_for_each_entry(tmp_output, &dev->crtc_config.output_list, head) {
++      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) {
 +                      printk(KERN_ERR "Can't enable LVDS and another "
 +                             "output on the same pipe\n");
 +                      return false;
 +              }
 +      }
-       spin_lock(&dev->crtc_config.config_lock);
++      spin_lock(&dev->mode_config.config_lock);
 +
 +      if (intel_crtc->pipe == 0) {
 +              printk(KERN_ERR "Can't support LVDS on pipe A\n");
 +              return false;
 +      }
 +
 +      /*
 +       * If we have timings from the BIOS for the panel, put them in
 +       * to the adjusted mode.  The CRTC will be set up for this mode,
 +       * with the panel scaling set up to source from the H/VDisplay
 +       * of the original mode.
 +       */
 +      if (dev_priv->panel_fixed_mode != NULL) {
 +              adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
 +              adjusted_mode->hsync_start =
 +                      dev_priv->panel_fixed_mode->hsync_start;
 +              adjusted_mode->hsync_end =
 +                      dev_priv->panel_fixed_mode->hsync_end;
 +              adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
 +              adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
 +              adjusted_mode->vsync_start =
 +                      dev_priv->panel_fixed_mode->vsync_start;
 +              adjusted_mode->vsync_end =
 +                      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);
 +      }
 +
 +      /*
 +       * XXX: It would be nice to support lower refresh rates on the
 +       * panels to reduce power consumption, and perhaps match the
 +       * user's requested refresh rate.
 +       */
 +
 +      return true;
 +}
 +
 +static void intel_lvds_mode_set(struct drm_output *output,
 +                              struct drm_display_mode *mode,
 +                              struct drm_display_mode *adjusted_mode)
 +{
 +      struct drm_device *dev = output->dev;
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct intel_crtc *intel_crtc = output->crtc->driver_private;
 +      u32 pfit_control;
 +
 +      /*
 +       * The LVDS pin pair will already have been turned on in the
 +       * intel_crtc_mode_set since it has a large impact on the DPLL
 +       * settings.
 +       */
 +
 +      /*
 +       * Enable automatic panel scaling so that non-native modes fill the
 +       * screen.  Should be enabled before the pipe is enabled, according to
 +       * register description and PRM.
 +       */
 +      pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
 +                      VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
 +
 +      if (!IS_I965G(dev)) {
 +              if (dev_priv->panel_wants_dither)
 +                      pfit_control |= PANEL_8TO6_DITHER_ENABLE;
 +      }
 +      else
 +              pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
 +
 +      I915_WRITE(PFIT_CONTROL, pfit_control);
 +}
 +
 +/**
 + * Detect the LVDS connection.
 + *
 + * This always returns OUTPUT_STATUS_CONNECTED.  This output should only have
 + * been set up if the LVDS was actually connected anyway.
 + */
 +static enum drm_output_status intel_lvds_detect(struct drm_output *output)
 +{
 +      return output_status_connected;
 +}
 +
 +/**
 + * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
 + */
 +static int intel_lvds_get_modes(struct drm_output *output)
  {
 -      DRM_DEVICE;
 -      unsigned long dvoa_enabled, dvob_enabled, dvoc_enabled, lvds_enabled;
 +      struct intel_output *intel_output = output->driver_private;
 +      struct drm_device *dev = output->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
 +      struct edid *edid_info;
 +      int ret = 0;
 +
 +      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 0;
 +      }
 +      intel_i2c_destroy(intel_output->ddc_bus);
 +
 +      ret = intel_ddc_get_modes(output);
 +      if (ret)
 +              return ret;
 +
 +      /* Didn't get an EDID */
 +      if (!output->monitor_info) {
 +              struct detailed_data_monitor_range *edid_range;
 +              edid_info = kzalloc(sizeof(*output->monitor_info), GFP_KERNEL);
 +              if (!edid_info)
 +                      goto out;
 +
 +              edid_info->detailed_timings[0].data.other_data.type =
 +                      EDID_DETAIL_MONITOR_RANGE;
 +              edid_range = &edid_info->detailed_timings[0].data.other_data.data.range;
 +
 +              /* Set wide sync ranges so we get all modes
 +               * handed to valid_mode for checking
 +               */
 +              edid_range->min_vfreq = 0;
 +              edid_range->max_vfreq = 200;
 +              edid_range->min_hfreq_khz = 0;
 +              edid_range->max_hfreq_khz = 200;
 +              output->monitor_info = edid_info;
 +      }
 +
 +out:
 +      if (dev_priv->panel_fixed_mode != NULL) {
 +              struct drm_display_mode *mode =
 +                      drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
 +              drm_mode_probed_add(output, mode);
 +              return 1;
 +      }
  
 -      printk(KERN_ERR "max backlight value: %d\n",
 -             lvds_get_max_backlight(dev));
 -      dvoa_enabled = I915_READ(DVOA);
 -      dvob_enabled = I915_READ(DVOB);
 -      dvoc_enabled = I915_READ(DVOC);
 -      lvds_enabled = I915_READ(LVDS);
 -
 -      printk(KERN_ERR "dvoa_enabled: 0x%08lx\n", dvoa_enabled);
 -      printk(KERN_ERR "dvob_enabled: 0x%08lx\n", dvob_enabled);
 -      printk(KERN_ERR "dvoc_enabled: 0x%08lx\n", dvoc_enabled);
 -      printk(KERN_ERR "lvds_enabled: 0x%08lx\n", lvds_enabled);
 -      printk(KERN_ERR "BLC_PWM_CTL: 0x%08x\n", I915_READ(BLC_PWM_CTL));
 -      
        return 0;
  }
  
@@@ -356,105 -113,18 +356,105 @@@ void intel_lvds_init(struct drm_device 
        intel_output->type = INTEL_OUTPUT_LVDS;
        output->driver_private = intel_output;
        output->subpixel_order = SubPixelHorizontalRGB;
 -      output->interlace_allowed = 0;
 -      output->doublescan_allowed = 0;
 +      output->interlace_allowed = FALSE;
 +      output->doublescan_allowed = FALSE;
  
 -      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);
 +      list_for_each_entry(scan, &output->probed_modes, head) {
 +              if (scan->type & DRM_MODE_TYPE_PREFERRED)
 +                      break;
        }
  
 -      modes = intel_ddc_get_modes(output);
 -      intel_i2c_destroy(intel_output->ddc_bus);
 -      drm_output_destroy(output);
 -}
 +      if (scan)
 +              dev_priv->panel_fixed_mode = scan;
 +
 +      /*
 +       * 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
 +       * correct mode.
 +       */
 +      if (!dev_priv->panel_fixed_mode) {
 +              u32 lvds = I915_READ(LVDS);
 +              int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
-               struct drm_crtc_config *crtc_config = &dev->crtc_config;
++              struct drm_mode_config *mode_config = &dev->mode_config;
 +              struct drm_crtc *crtc;
 +              /* FIXME: need drm_crtc_from_pipe */
-               //crtc = drm_crtc_from_pipe(crtc_config, pipe);
++              //crtc = drm_crtc_from_pipe(mode_config, pipe);
 +              
 +              if (lvds & LVDS_PORT_EN && 0) {
 +                      dev_priv->panel_fixed_mode =
 +                              intel_crtc_mode_get(dev, crtc);
 +                      if (dev_priv->panel_fixed_mode)
 +                              dev_priv->panel_fixed_mode->type |=
 +                                      DRM_MODE_TYPE_PREFERRED;
 +              }
 +      }
 +
 +/* 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.
 +       */
 +      bios_mode = intel_bios_get_panel_mode(pScrn);
 +      if (bios_mode != NULL) {
 +              if (dev_priv->panel_fixed_mode != NULL) {
 +                      if (dev_priv->debug_modes &&
 +                          !xf86ModesEqual(dev_priv->panel_fixed_mode,
 +                                          bios_mode))
 +                      {
 +                              xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +                                         "BIOS panel mode data doesn't match probed data, "
 +                                         "continuing with probed.\n");
 +                              xf86DrvMsg(pScrn->scrnIndex, X_INFO, "BIOS mode:\n");
 +                              xf86PrintModeline(pScrn->scrnIndex, bios_mode);
 +                              xf86DrvMsg(pScrn->scrnIndex, X_INFO, "probed mode:\n");
 +                              xf86PrintModeline(pScrn->scrnIndex, dev_priv->panel_fixed_mode);
 +                              xfree(bios_mode->name);
 +                              xfree(bios_mode);
 +                      }
 +              }  else {
 +                      dev_priv->panel_fixed_mode = bios_mode;
 +              }
 +      } else {
 +              xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 +                         "Couldn't detect panel mode.  Disabling panel\n");
 +              goto disable_exit;
 +      }
 +
 +      /* Blacklist machines with BIOSes that list an LVDS panel without actually
 +       * having one.
 +       */
 +      if (dev_priv->PciInfo->chipType == PCI_CHIP_I945_GM) {
 +              if (dev_priv->PciInfo->subsysVendor == 0xa0a0)  /* aopen mini pc */
 +                      goto disable_exit;
 +
 +              if ((dev_priv->PciInfo->subsysVendor == 0x8086) &&
 +                  (dev_priv->PciInfo->subsysCard == 0x7270)) {
 +                      /* It's a Mac Mini or Macbook Pro.
 +                       *
 +                       * Apple hardware is out to get us.  The macbook pro has a real
 +                       * LVDS panel, but the mac mini does not, and they have the same
 +                       * device IDs.  We'll distinguish by panel size, on the assumption
 +                       * that Apple isn't about to make any machines with an 800x600
 +                       * display.
 +                       */
  
 +                      if (dev_priv->panel_fixed_mode != NULL &&
 +                          dev_priv->panel_fixed_mode->HDisplay == 800 &&
 +                          dev_priv->panel_fixed_mode->VDisplay == 600)
 +                      {
 +                              xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 +                                         "Suspected Mac Mini, ignoring the LVDS\n");
 +                              goto disable_exit;
 +                      }
 +              }
 +      }
 +
 +#endif
 +      return;
 +}
Simple merge
Simple merge
index e03ed42,0000000..e454c9f
mode 100644,000000..100644
--- /dev/null
@@@ -1,157 -1,0 +1,159 @@@
-       drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle);
 +#include "drmP.h"
 +#include "drm.h"
 +#include "drm_sarea.h"
 +#include "i915_drm.h"
 +#include "i915_drv.h"
 +
 +int i915_driver_load(drm_device_t *dev, unsigned long flags)
 +{
 +      drm_i915_private_t *dev_priv;
 +      drm_i915_init_t init;
 +      int ret;
 +
 +      dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
 +      if (dev_priv == NULL)
 +              return DRM_ERR(ENOMEM);
 +
 +      memset(dev_priv, 0, sizeof(drm_i915_private_t));
 +      dev->dev_private = (void *)dev_priv;
 +//    dev_priv->flags = flags;
 +
 +      /* i915 has 4 more counters */
 +      dev->counters += 4;
 +      dev->types[6] = _DRM_STAT_IRQ;
 +      dev->types[7] = _DRM_STAT_PRIMARY;
 +      dev->types[8] = _DRM_STAT_SECONDARY;
 +      dev->types[9] = _DRM_STAT_DMA;
 +
 +      if (IS_I9XX(dev)) {
 +              dev_priv->mmiobase = drm_get_resource_start(dev, 0);
 +              dev_priv->mmiolen = drm_get_resource_len(dev, 0);
++              dev_priv->baseaddr = drm_get_resource_start(dev, 2) & 0xff000000;
 +      } else if (drm_get_resource_start(dev, 1)) {
 +              dev_priv->mmiobase = drm_get_resource_start(dev, 1);
 +              dev_priv->mmiolen = drm_get_resource_len(dev, 1);
++              dev_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000;
 +      } else {
 +              DRM_ERROR("Unable to find MMIO registers\n");
 +              return -ENODEV;
 +      }
 +
 +      ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen,
 +                       _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map);
 +      if (ret != 0) {
 +              DRM_ERROR("Cannot add mapping for MMIO registers\n");
 +              return ret;
 +      }
 +
 +      
 +      ret = drm_setup(dev);
 +      if (ret) {
 +              DRM_ERROR("drm_setup failed\n");
 +              return ret;
 +      }
 +
 +      DRM_GETSAREA();
 +      if (!dev_priv->sarea) {
 +              DRM_ERROR("can not find sarea!\n");
 +              dev->dev_private = (void *)dev_priv;
 +              i915_dma_cleanup(dev);
 +              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: need real front buffer offset */
 +      dev_priv->sarea_priv->front_handle = 0xa0000000 + 1024*1024;
 +
 +      drm_bo_driver_init(dev);
 +      /* this probably doesn't belong here - TODO */
++      //drm_framebuffer_set_object(dev, dev_priv->sarea_priv->front_handle);
 +      intel_modeset_init(dev);
 +      drm_set_desired_modes(dev);
 +
 +      /* FIXME: command ring needs AGP space, do we own it at this point? */
 +      dev_priv->ring.Start = 0xa0000000;
 +      dev_priv->ring.End = 128*1024;
 +      dev_priv->ring.Size = 128*1024;
 +      dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
 +
 +      dev_priv->ring.map.offset = dev_priv->ring.Start;
 +      dev_priv->ring.map.size = dev_priv->ring.Size;
 +      dev_priv->ring.map.type = 0;
 +      dev_priv->ring.map.flags = 0;
 +      dev_priv->ring.map.mtrr = 0;
 +
 +      drm_core_ioremap(&dev_priv->ring.map, dev);
 +
 +      if (dev_priv->ring.map.handle == NULL) {
 +              dev->dev_private = (void *)dev_priv;
 +              i915_dma_cleanup(dev);
 +              DRM_ERROR("can not ioremap virtual address for"
 +                        " ring buffer\n");
 +              return DRM_ERR(ENOMEM);
 +      }
 +
 +      dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
 +      dev_priv->cpp = 4;
 +      dev_priv->sarea_priv->pf_current_page = 0;
 +
 +      /* We are using separate values as placeholders for mechanisms for
 +       * private backbuffer/depthbuffer usage.
 +       */
 +      dev_priv->use_mi_batchbuffer_start = 0;
 +
 +      /* Allow hardware batchbuffers unless told otherwise.
 +       */
 +      dev_priv->allow_batchbuffer = 1;
 +
 +      /* Program Hardware Status Page */
 +      dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 
 +          0xffffffff);
 +
 +      if (!dev_priv->status_page_dmah) {
 +              dev->dev_private = (void *)dev_priv;
 +              i915_dma_cleanup(dev);
 +              DRM_ERROR("Can not allocate hardware status page\n");
 +              return DRM_ERR(ENOMEM);
 +      }
 +      dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
 +      dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
 +      
 +      memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 +      DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
 +
 +      I915_WRITE(0x02080, dev_priv->dma_status_page);
 +      DRM_DEBUG("Enabled hardware status page\n");
 +
 +      return 0;
 +}
 +
 +int i915_driver_unload(drm_device_t *dev)
 +{
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +
 +      intel_modeset_cleanup(dev);
 +      drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
 +
 +      dev->dev_private = NULL;
 +      return 0;
 +}
 +
 +void i915_driver_lastclose(drm_device_t * dev)
 +{
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +      
 +      i915_mem_takedown(&(dev_priv->agp_heap));
 +
 +      i915_dma_cleanup(dev);
 +
 +      dev_priv->mmio_map = NULL;
 +}
 +
 +void i915_driver_preclose(drm_device_t * dev, DRMFILE filp)
 +{
 +      drm_i915_private_t *dev_priv = dev->dev_private;
 +      i915_mem_release(dev, filp, dev_priv->agp_heap);
 +}
 +