]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'drm-next' of ../drm-next into drm-linus
authorDave Airlie <airlied@redhat.com>
Thu, 8 Oct 2009 04:03:05 +0000 (14:03 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 8 Oct 2009 04:03:05 +0000 (14:03 +1000)
conflict in radeon since new init path merged with vga arb code.

Conflicts:
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_device.c

1  2 
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_device.c
include/drm/drm_pciids.h

index 93ff6c03733e6359b69e720dc48f3193272ce04f,893903962e54d976558342b731cf0b2c53810472..ffa39671751fab815e76ef164cf860eccaae8549
@@@ -24,8 -24,6 +24,8 @@@
   *    Eric Anholt <eric@anholt.net>
   */
  
 +#include <linux/module.h>
 +#include <linux/input.h>
  #include <linux/i2c.h>
  #include <linux/kernel.h>
  #include "drmP.h"
@@@ -877,7 -875,7 +877,7 @@@ intel_igdng_find_best_PLL(const intel_l
                                               refclk, best_clock);
  
        if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
 -              if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
 +              if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) ==
                    LVDS_CLKB_POWER_UP)
                        clock.p2 = limit->p2.p2_fast;
                else
@@@ -954,241 -952,6 +954,241 @@@ intel_wait_for_vblank(struct drm_devic
        mdelay(20);
  }
  
 +/* Parameters have changed, update FBC info */
 +static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
 +{
 +      struct drm_device *dev = crtc->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_framebuffer *fb = crtc->fb;
 +      struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
 +      struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
 +      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      int plane, i;
 +      u32 fbc_ctl, fbc_ctl2;
 +
 +      dev_priv->cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE;
 +
 +      if (fb->pitch < dev_priv->cfb_pitch)
 +              dev_priv->cfb_pitch = fb->pitch;
 +
 +      /* FBC_CTL wants 64B units */
 +      dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1;
 +      dev_priv->cfb_fence = obj_priv->fence_reg;
 +      dev_priv->cfb_plane = intel_crtc->plane;
 +      plane = dev_priv->cfb_plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB;
 +
 +      /* Clear old tags */
 +      for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++)
 +              I915_WRITE(FBC_TAG + (i * 4), 0);
 +
 +      /* Set it up... */
 +      fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | plane;
 +      if (obj_priv->tiling_mode != I915_TILING_NONE)
 +              fbc_ctl2 |= FBC_CTL_CPU_FENCE;
 +      I915_WRITE(FBC_CONTROL2, fbc_ctl2);
 +      I915_WRITE(FBC_FENCE_OFF, crtc->y);
 +
 +      /* enable it... */
 +      fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC;
 +      fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT;
 +      fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT;
 +      if (obj_priv->tiling_mode != I915_TILING_NONE)
 +              fbc_ctl |= dev_priv->cfb_fence;
 +      I915_WRITE(FBC_CONTROL, fbc_ctl);
 +
 +      DRM_DEBUG("enabled FBC, pitch %ld, yoff %d, plane %d, ",
 +                dev_priv->cfb_pitch, crtc->y, dev_priv->cfb_plane);
 +}
 +
 +void i8xx_disable_fbc(struct drm_device *dev)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 fbc_ctl;
 +
 +      if (!I915_HAS_FBC(dev))
 +              return;
 +
 +      /* Disable compression */
 +      fbc_ctl = I915_READ(FBC_CONTROL);
 +      fbc_ctl &= ~FBC_CTL_EN;
 +      I915_WRITE(FBC_CONTROL, fbc_ctl);
 +
 +      /* Wait for compressing bit to clear */
 +      while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING)
 +              ; /* nothing */
 +
 +      intel_wait_for_vblank(dev);
 +
 +      DRM_DEBUG("disabled FBC\n");
 +}
 +
 +static bool i8xx_fbc_enabled(struct drm_crtc *crtc)
 +{
 +      struct drm_device *dev = crtc->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      return I915_READ(FBC_CONTROL) & FBC_CTL_EN;
 +}
 +
 +static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
 +{
 +      struct drm_device *dev = crtc->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_framebuffer *fb = crtc->fb;
 +      struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
 +      struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
 +      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA :
 +                   DPFC_CTL_PLANEB);
 +      unsigned long stall_watermark = 200;
 +      u32 dpfc_ctl;
 +
 +      dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1;
 +      dev_priv->cfb_fence = obj_priv->fence_reg;
 +      dev_priv->cfb_plane = intel_crtc->plane;
 +
 +      dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X;
 +      if (obj_priv->tiling_mode != I915_TILING_NONE) {
 +              dpfc_ctl |= DPFC_CTL_FENCE_EN | dev_priv->cfb_fence;
 +              I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY);
 +      } else {
 +              I915_WRITE(DPFC_CHICKEN, ~DPFC_HT_MODIFY);
 +      }
 +
 +      I915_WRITE(DPFC_CONTROL, dpfc_ctl);
 +      I915_WRITE(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN |
 +                 (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) |
 +                 (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT));
 +      I915_WRITE(DPFC_FENCE_YOFF, crtc->y);
 +
 +      /* enable it... */
 +      I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN);
 +
 +      DRM_DEBUG("enabled fbc on plane %d\n", intel_crtc->plane);
 +}
 +
 +void g4x_disable_fbc(struct drm_device *dev)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u32 dpfc_ctl;
 +
 +      /* Disable compression */
 +      dpfc_ctl = I915_READ(DPFC_CONTROL);
 +      dpfc_ctl &= ~DPFC_CTL_EN;
 +      I915_WRITE(DPFC_CONTROL, dpfc_ctl);
 +      intel_wait_for_vblank(dev);
 +
 +      DRM_DEBUG("disabled FBC\n");
 +}
 +
 +static bool g4x_fbc_enabled(struct drm_crtc *crtc)
 +{
 +      struct drm_device *dev = crtc->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
 +}
 +
 +/**
 + * intel_update_fbc - enable/disable FBC as needed
 + * @crtc: CRTC to point the compressor at
 + * @mode: mode in use
 + *
 + * Set up the framebuffer compression hardware at mode set time.  We
 + * enable it if possible:
 + *   - plane A only (on pre-965)
 + *   - no pixel mulitply/line duplication
 + *   - no alpha buffer discard
 + *   - no dual wide
 + *   - framebuffer <= 2048 in width, 1536 in height
 + *
 + * We can't assume that any compression will take place (worst case),
 + * so the compressed buffer has to be the same size as the uncompressed
 + * one.  It also must reside (along with the line length buffer) in
 + * stolen memory.
 + *
 + * We need to enable/disable FBC on a global basis.
 + */
 +static void intel_update_fbc(struct drm_crtc *crtc,
 +                           struct drm_display_mode *mode)
 +{
 +      struct drm_device *dev = crtc->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct drm_framebuffer *fb = crtc->fb;
 +      struct intel_framebuffer *intel_fb;
 +      struct drm_i915_gem_object *obj_priv;
 +      struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 +      int plane = intel_crtc->plane;
 +
 +      if (!i915_powersave)
 +              return;
 +
 +      if (!dev_priv->display.fbc_enabled ||
 +          !dev_priv->display.enable_fbc ||
 +          !dev_priv->display.disable_fbc)
 +              return;
 +
 +      if (!crtc->fb)
 +              return;
 +
 +      intel_fb = to_intel_framebuffer(fb);
 +      obj_priv = intel_fb->obj->driver_private;
 +
 +      /*
 +       * If FBC is already on, we just have to verify that we can
 +       * keep it that way...
 +       * Need to disable if:
 +       *   - changing FBC params (stride, fence, mode)
 +       *   - new fb is too large to fit in compressed buffer
 +       *   - going to an unsupported config (interlace, pixel multiply, etc.)
 +       */
 +      if (intel_fb->obj->size > dev_priv->cfb_size) {
 +              DRM_DEBUG("framebuffer too large, disabling compression\n");
 +              goto out_disable;
 +      }
 +      if ((mode->flags & DRM_MODE_FLAG_INTERLACE) ||
 +          (mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
 +              DRM_DEBUG("mode incompatible with compression, disabling\n");
 +              goto out_disable;
 +      }
 +      if ((mode->hdisplay > 2048) ||
 +          (mode->vdisplay > 1536)) {
 +              DRM_DEBUG("mode too large for compression, disabling\n");
 +              goto out_disable;
 +      }
 +      if ((IS_I915GM(dev) || IS_I945GM(dev)) && plane != 0) {
 +              DRM_DEBUG("plane not 0, disabling compression\n");
 +              goto out_disable;
 +      }
 +      if (obj_priv->tiling_mode != I915_TILING_X) {
 +              DRM_DEBUG("framebuffer not tiled, disabling compression\n");
 +              goto out_disable;
 +      }
 +
 +      if (dev_priv->display.fbc_enabled(crtc)) {
 +              /* We can re-enable it in this case, but need to update pitch */
 +              if (fb->pitch > dev_priv->cfb_pitch)
 +                      dev_priv->display.disable_fbc(dev);
 +              if (obj_priv->fence_reg != dev_priv->cfb_fence)
 +                      dev_priv->display.disable_fbc(dev);
 +              if (plane != dev_priv->cfb_plane)
 +                      dev_priv->display.disable_fbc(dev);
 +      }
 +
 +      if (!dev_priv->display.fbc_enabled(crtc)) {
 +              /* Now try to turn it back on if possible */
 +              dev_priv->display.enable_fbc(crtc, 500);
 +      }
 +
 +      return;
 +
 +out_disable:
 +      DRM_DEBUG("unsupported config, disabling FBC\n");
 +      /* Multiple disables should be harmless */
 +      if (dev_priv->display.fbc_enabled(crtc))
 +              dev_priv->display.disable_fbc(dev);
 +}
 +
  static int
  intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
                    struct drm_framebuffer *old_fb)
        struct drm_i915_gem_object *obj_priv;
        struct drm_gem_object *obj;
        int pipe = intel_crtc->pipe;
 +      int plane = intel_crtc->plane;
        unsigned long Start, Offset;
 -      int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
 -      int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
 -      int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
 -      int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF);
 -      int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 +      int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR);
 +      int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF);
 +      int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE;
 +      int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF);
 +      int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
        u32 dspcntr, alignment;
        int ret;
  
                return 0;
        }
  
 -      switch (pipe) {
 +      switch (plane) {
        case 0:
        case 1:
                break;
        default:
 -              DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
 +              DRM_ERROR("Can't update plane %d in SAREA\n", plane);
                return -EINVAL;
        }
  
                I915_READ(dspbase);
        }
  
 +      if ((IS_I965G(dev) || plane == 0))
 +              intel_update_fbc(crtc, &crtc->mode);
 +
        intel_wait_for_vblank(dev);
  
        if (old_fb) {
@@@ -1458,7 -1217,6 +1458,7 @@@ static void igdng_crtc_dpms(struct drm_
        int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF;
        int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1;
        int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ;
 +      int pf_win_pos = (pipe == 0) ? PFA_WIN_POS : PFB_WIN_POS;
        int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
        int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
        int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
                        }
                }
  
 +              /* Enable panel fitting for LVDS */
 +              if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
 +                      temp = I915_READ(pf_ctl_reg);
 +                      I915_WRITE(pf_ctl_reg, temp | PF_ENABLE);
 +
 +                      /* currently full aspect */
 +                      I915_WRITE(pf_win_pos, 0);
 +
 +                      I915_WRITE(pf_win_size,
 +                                 (dev_priv->panel_fixed_mode->hdisplay << 16) |
 +                                 (dev_priv->panel_fixed_mode->vdisplay));
 +              }
 +
                /* Enable CPU pipe */
                temp = I915_READ(pipeconf_reg);
                if ((temp & PIPEACONF_ENABLE) == 0) {
@@@ -1787,10 -1532,9 +1787,10 @@@ static void i9xx_crtc_dpms(struct drm_c
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 +      int plane = intel_crtc->plane;
        int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 -      int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 -      int dspbase_reg = (pipe == 0) ? DSPAADDR : DSPBADDR;
 +      int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
 +      int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR;
        int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
        u32 temp;
  
  
                intel_crtc_load_lut(crtc);
  
 +              if ((IS_I965G(dev) || plane == 0))
 +                      intel_update_fbc(crtc, &crtc->mode);
 +
                /* Give the overlay scaler a chance to enable if it's on this pipe */
                //intel_crtc_dpms_video(crtc, true); TODO
                intel_update_watermarks(dev);
                /* Give the overlay scaler a chance to disable if it's on this pipe */
                //intel_crtc_dpms_video(crtc, FALSE); TODO
  
 +              if (dev_priv->cfb_plane == plane &&
 +                  dev_priv->display.disable_fbc)
 +                      dev_priv->display.disable_fbc(dev);
 +
                /* Disable the VGA plane that we never use */
                i915_disable_vga(dev);
  
  static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
  {
        struct drm_device *dev = crtc->dev;
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
        bool enabled;
  
 -      if (IS_IGDNG(dev))
 -              igdng_crtc_dpms(crtc, mode);
 -      else
 -              i9xx_crtc_dpms(crtc, mode);
 +      dev_priv->display.dpms(crtc, mode);
  
        intel_crtc->dpms_mode = mode;
  
@@@ -1970,68 -1709,56 +1970,68 @@@ static bool intel_crtc_mode_fixup(struc
        return true;
  }
  
 +static int i945_get_display_clock_speed(struct drm_device *dev)
 +{
 +      return 400000;
 +}
  
 -/** Returns the core display clock speed for i830 - i945 */
 -static int intel_get_core_clock_speed(struct drm_device *dev)
 +static int i915_get_display_clock_speed(struct drm_device *dev)
  {
 +      return 333000;
 +}
  
 -      /* Core clock values taken from the published datasheets.
 -       * The 830 may go up to 166 Mhz, which we should check.
 -       */
 -      if (IS_I945G(dev))
 -              return 400000;
 -      else if (IS_I915G(dev))
 -              return 333000;
 -      else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
 -              return 200000;
 -      else if (IS_I915GM(dev)) {
 -              u16 gcfgc = 0;
 +static int i9xx_misc_get_display_clock_speed(struct drm_device *dev)
 +{
 +      return 200000;
 +}
  
 -              pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
 +static int i915gm_get_display_clock_speed(struct drm_device *dev)
 +{
 +      u16 gcfgc = 0;
  
 -              if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
 -                      return 133000;
 -              else {
 -                      switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
 -                      case GC_DISPLAY_CLOCK_333_MHZ:
 -                              return 333000;
 -                      default:
 -                      case GC_DISPLAY_CLOCK_190_200_MHZ:
 -                              return 190000;
 -                      }
 -              }
 -      } else if (IS_I865G(dev))
 -              return 266000;
 -      else if (IS_I855(dev)) {
 -              u16 hpllcc = 0;
 -              /* Assume that the hardware is in the high speed state.  This
 -               * should be the default.
 -               */
 -              switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
 -              case GC_CLOCK_133_200:
 -              case GC_CLOCK_100_200:
 -                      return 200000;
 -              case GC_CLOCK_166_250:
 -                      return 250000;
 -              case GC_CLOCK_100_133:
 -                      return 133000;
 +      pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
 +
 +      if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
 +              return 133000;
 +      else {
 +              switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
 +              case GC_DISPLAY_CLOCK_333_MHZ:
 +                      return 333000;
 +              default:
 +              case GC_DISPLAY_CLOCK_190_200_MHZ:
 +                      return 190000;
                }
 -      } else /* 852, 830 */
 +      }
 +}
 +
 +static int i865_get_display_clock_speed(struct drm_device *dev)
 +{
 +      return 266000;
 +}
 +
 +static int i855_get_display_clock_speed(struct drm_device *dev)
 +{
 +      u16 hpllcc = 0;
 +      /* Assume that the hardware is in the high speed state.  This
 +       * should be the default.
 +       */
 +      switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
 +      case GC_CLOCK_133_200:
 +      case GC_CLOCK_100_200:
 +              return 200000;
 +      case GC_CLOCK_166_250:
 +              return 250000;
 +      case GC_CLOCK_100_133:
                return 133000;
 +      }
  
 -      return 0; /* Silence gcc warning */
 +      /* Shouldn't happen */
 +      return 0;
 +}
 +
 +static int i830_get_display_clock_speed(struct drm_device *dev)
 +{
 +      return 133000;
  }
  
  /**
@@@ -2194,14 -1921,7 +2194,14 @@@ static unsigned long intel_calculate_wm
  {
        long entries_required, wm_size;
  
 -      entries_required = (clock_in_khz * pixel_size * latency_ns) / 1000000;
 +      /*
 +       * Note: we need to make sure we don't overflow for various clock &
 +       * latency values.
 +       * clocks go from a few thousand to several hundred thousand.
 +       * latency is usually a few thousand
 +       */
 +      entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) /
 +              1000;
        entries_required /= wm->cacheline_size;
  
        DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required);
@@@ -2266,13 -1986,14 +2266,13 @@@ static struct cxsr_latency *intel_get_c
        for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) {
                latency = &cxsr_latency_table[i];
                if (is_desktop == latency->is_desktop &&
 -                      fsb == latency->fsb_freq && mem == latency->mem_freq)
 -                      break;
 +                  fsb == latency->fsb_freq && mem == latency->mem_freq)
 +                      return latency;
        }
 -      if (i >= ARRAY_SIZE(cxsr_latency_table)) {
 -              DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n");
 -              return NULL;
 -      }
 -      return latency;
 +
 +      DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n");
 +
 +      return NULL;
  }
  
  static void igd_disable_cxsr(struct drm_device *dev)
@@@ -2363,17 -2084,32 +2363,17 @@@ static void igd_enable_cxsr(struct drm_
   */
  const static int latency_ns = 5000;
  
 -static int intel_get_fifo_size(struct drm_device *dev, int plane)
 +static int i9xx_get_fifo_size(struct drm_device *dev, int plane)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t dsparb = I915_READ(DSPARB);
        int size;
  
 -      if (IS_I9XX(dev)) {
 -              if (plane == 0)
 -                      size = dsparb & 0x7f;
 -              else
 -                      size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) -
 -                              (dsparb & 0x7f);
 -      } else if (IS_I85X(dev)) {
 -              if (plane == 0)
 -                      size = dsparb & 0x1ff;
 -              else
 -                      size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) -
 -                              (dsparb & 0x1ff);
 -              size >>= 1; /* Convert to cachelines */
 -      } else if (IS_845G(dev)) {
 -              size = dsparb & 0x7f;
 -              size >>= 2; /* Convert to cachelines */
 -      } else {
 +      if (plane == 0)
                size = dsparb & 0x7f;
 -              size >>= 1; /* Convert to cachelines */
 -      }
 +      else
 +              size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) -
 +                      (dsparb & 0x7f);
  
        DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
                  size);
        return size;
  }
  
 -static void g4x_update_wm(struct drm_device *dev)
 +static int i85x_get_fifo_size(struct drm_device *dev, int plane)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      uint32_t dsparb = I915_READ(DSPARB);
 +      int size;
 +
 +      if (plane == 0)
 +              size = dsparb & 0x1ff;
 +      else
 +              size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) -
 +                      (dsparb & 0x1ff);
 +      size >>= 1; /* Convert to cachelines */
 +
 +      DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
 +                size);
 +
 +      return size;
 +}
 +
 +static int i845_get_fifo_size(struct drm_device *dev, int plane)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      uint32_t dsparb = I915_READ(DSPARB);
 +      int size;
 +
 +      size = dsparb & 0x7f;
 +      size >>= 2; /* Convert to cachelines */
 +
 +      DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
 +                size);
 +
 +      return size;
 +}
 +
 +static int i830_get_fifo_size(struct drm_device *dev, int plane)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      uint32_t dsparb = I915_READ(DSPARB);
 +      int size;
 +
 +      size = dsparb & 0x7f;
 +      size >>= 1; /* Convert to cachelines */
 +
 +      DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A",
 +                size);
 +
 +      return size;
 +}
 +
 +static void g4x_update_wm(struct drm_device *dev, int unused, int unused2,
 +                        int unused3, int unused4)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 fw_blc_self = I915_READ(FW_BLC_SELF);
        I915_WRITE(FW_BLC_SELF, fw_blc_self);
  }
  
 -static void i965_update_wm(struct drm_device *dev)
 +static void i965_update_wm(struct drm_device *dev, int unused, int unused2,
 +                         int unused3, int unused4)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
@@@ -2480,8 -2165,8 +2480,8 @@@ static void i9xx_update_wm(struct drm_d
        cacheline_size = planea_params.cacheline_size;
  
        /* Update per-plane FIFO sizes */
 -      planea_params.fifo_size = intel_get_fifo_size(dev, 0);
 -      planeb_params.fifo_size = intel_get_fifo_size(dev, 1);
 +      planea_params.fifo_size = dev_priv->display.get_fifo_size(dev, 0);
 +      planeb_params.fifo_size = dev_priv->display.get_fifo_size(dev, 1);
  
        planea_wm = intel_calculate_wm(planea_clock, &planea_params,
                                       pixel_size, latency_ns);
        I915_WRITE(FW_BLC2, fwater_hi);
  }
  
 -static void i830_update_wm(struct drm_device *dev, int planea_clock,
 -                         int pixel_size)
 +static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused,
 +                         int unused2, int pixel_size)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff;
        int planea_wm;
  
 -      i830_wm_info.fifo_size = intel_get_fifo_size(dev, 0);
 +      i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0);
  
        planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info,
                                       pixel_size, latency_ns);
    */
  static void intel_update_watermarks(struct drm_device *dev)
  {
 +      struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc;
        struct intel_crtc *intel_crtc;
        int sr_hdisplay = 0;
        else if (IS_IGD(dev))
                igd_disable_cxsr(dev);
  
 -      if (IS_G4X(dev))
 -              g4x_update_wm(dev);
 -      else if (IS_I965G(dev))
 -              i965_update_wm(dev);
 -      else if (IS_I9XX(dev) || IS_MOBILE(dev))
 -              i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay,
 -                             pixel_size);
 -      else
 -              i830_update_wm(dev, planea_clock, pixel_size);
 +      dev_priv->display.update_wm(dev, planea_clock, planeb_clock,
 +                                  sr_hdisplay, pixel_size);
  }
  
  static int intel_crtc_mode_set(struct drm_crtc *crtc,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
 +      int plane = intel_crtc->plane;
        int fp_reg = (pipe == 0) ? FPA0 : FPB0;
        int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
        int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
 -      int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 +      int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
        int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
        int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
        int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
        int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
        int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
        int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
 -      int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
 -      int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
 +      int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
 +      int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
        int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
        int refclk, num_outputs = 0;
        intel_clock_t clock, reduced_clock;
           enable color space conversion */
        if (!IS_IGDNG(dev)) {
                if (pipe == 0)
 -                      dspcntr |= DISPPLANE_SEL_PIPE_A;
 +                      dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
                else
                        dspcntr |= DISPPLANE_SEL_PIPE_B;
        }
                 * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
                 * pipe == 0 check?
                 */
 -              if (mode->clock > intel_get_core_clock_speed(dev) * 9 / 10)
 +              if (mode->clock >
 +                  dev_priv->display.get_display_clock_speed(dev) * 9 / 10)
                        pipeconf |= PIPEACONF_DOUBLE_WIDE;
                else
                        pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
                udelay(150);
  
                if (IS_I965G(dev) && !IS_IGDNG(dev)) {
 -                      sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 -                      I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
 +                      if (is_sdvo) {
 +                              sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
 +                              I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
                                        ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
 +                      } else
 +                              I915_WRITE(dpll_md_reg, 0);
                } else {
                        /* write it again -- the BIOS does, after all */
                        I915_WRITE(dpll_reg, dpll);
        /* Flush the plane changes */
        ret = intel_pipe_set_base(crtc, x, y, old_fb);
  
 +      if ((IS_I965G(dev) || plane == 0))
 +              intel_update_fbc(crtc, &crtc->mode);
 +
        intel_update_watermarks(dev);
  
        drm_vblank_post_modeset(dev, pipe);
@@@ -3095,7 -2778,6 +3095,7 @@@ static int intel_crtc_cursor_set(struc
        struct drm_gem_object *bo;
        struct drm_i915_gem_object *obj_priv;
        int pipe = intel_crtc->pipe;
 +      int plane = intel_crtc->plane;
        uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
        uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
        uint32_t temp = I915_READ(control);
                        i915_gem_object_unpin(intel_crtc->cursor_bo);
                drm_gem_object_unreference(intel_crtc->cursor_bo);
        }
 +
 +      if ((IS_I965G(dev) || plane == 0))
 +              intel_update_fbc(crtc, &crtc->mode);
 +
        mutex_unlock(&dev->struct_mutex);
  
        intel_crtc->cursor_addr = addr;
@@@ -3244,6 -2922,16 +3244,16 @@@ void intel_crtc_fb_gamma_set(struct drm
        intel_crtc->lut_b[regno] = blue >> 8;
  }
  
+ void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+                            u16 *blue, int regno)
+ {
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       *red = intel_crtc->lut_r[regno] << 8;
+       *green = intel_crtc->lut_g[regno] << 8;
+       *blue = intel_crtc->lut_b[regno] << 8;
+ }
  static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
                                 u16 *blue, uint32_t size)
  {
@@@ -3835,6 -3523,7 +3845,7 @@@ static const struct drm_crtc_helper_fun
        .mode_set_base = intel_pipe_set_base,
        .prepare = intel_crtc_prepare,
        .commit = intel_crtc_commit,
+       .load_lut = intel_crtc_load_lut,
  };
  
  static const struct drm_crtc_funcs intel_crtc_funcs = {
@@@ -3866,14 -3555,6 +3877,14 @@@ static void intel_crtc_init(struct drm_
                intel_crtc->lut_b[i] = i;
        }
  
 +      /* Swap pipes & planes for FBC on pre-965 */
 +      intel_crtc->pipe = pipe;
 +      intel_crtc->plane = pipe;
 +      if (IS_MOBILE(dev) && (IS_I9XX(dev) && !IS_I965G(dev))) {
 +              DRM_DEBUG("swapping pipes & planes for FBC\n");
 +              intel_crtc->plane = ((pipe == 0) ? 1 : 0);
 +      }
 +
        intel_crtc->cursor_addr = 0;
        intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
        drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
@@@ -4156,73 -3837,6 +4167,73 @@@ void intel_init_clock_gating(struct drm
        }
  }
  
 +/* Set up chip specific display functions */
 +static void intel_init_display(struct drm_device *dev)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      /* We always want a DPMS function */
 +      if (IS_IGDNG(dev))
 +              dev_priv->display.dpms = igdng_crtc_dpms;
 +      else
 +              dev_priv->display.dpms = i9xx_crtc_dpms;
 +
 +      /* Only mobile has FBC, leave pointers NULL for other chips */
 +      if (IS_MOBILE(dev)) {
 +              if (IS_GM45(dev)) {
 +                      dev_priv->display.fbc_enabled = g4x_fbc_enabled;
 +                      dev_priv->display.enable_fbc = g4x_enable_fbc;
 +                      dev_priv->display.disable_fbc = g4x_disable_fbc;
 +              } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) {
 +                      dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
 +                      dev_priv->display.enable_fbc = i8xx_enable_fbc;
 +                      dev_priv->display.disable_fbc = i8xx_disable_fbc;
 +              }
 +              /* 855GM needs testing */
 +      }
 +
 +      /* Returns the core display clock speed */
 +      if (IS_I945G(dev))
 +              dev_priv->display.get_display_clock_speed =
 +                      i945_get_display_clock_speed;
 +      else if (IS_I915G(dev))
 +              dev_priv->display.get_display_clock_speed =
 +                      i915_get_display_clock_speed;
 +      else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
 +              dev_priv->display.get_display_clock_speed =
 +                      i9xx_misc_get_display_clock_speed;
 +      else if (IS_I915GM(dev))
 +              dev_priv->display.get_display_clock_speed =
 +                      i915gm_get_display_clock_speed;
 +      else if (IS_I865G(dev))
 +              dev_priv->display.get_display_clock_speed =
 +                      i865_get_display_clock_speed;
 +      else if (IS_I855(dev))
 +              dev_priv->display.get_display_clock_speed =
 +                      i855_get_display_clock_speed;
 +      else /* 852, 830 */
 +              dev_priv->display.get_display_clock_speed =
 +                      i830_get_display_clock_speed;
 +
 +      /* For FIFO watermark updates */
 +      if (IS_G4X(dev))
 +              dev_priv->display.update_wm = g4x_update_wm;
 +      else if (IS_I965G(dev))
 +              dev_priv->display.update_wm = i965_update_wm;
 +      else if (IS_I9XX(dev) || IS_MOBILE(dev)) {
 +              dev_priv->display.update_wm = i9xx_update_wm;
 +              dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
 +      } else {
 +              if (IS_I85X(dev))
 +                      dev_priv->display.get_fifo_size = i85x_get_fifo_size;
 +              else if (IS_845G(dev))
 +                      dev_priv->display.get_fifo_size = i845_get_fifo_size;
 +              else
 +                      dev_priv->display.get_fifo_size = i830_get_fifo_size;
 +              dev_priv->display.update_wm = i830_update_wm;
 +      }
 +}
 +
  void intel_modeset_init(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
        dev->mode_config.funcs = (void *)&intel_mode_funcs;
  
 +      intel_init_display(dev);
 +
        if (IS_I965G(dev)) {
                dev->mode_config.max_width = 8192;
                dev->mode_config.max_height = 8192;
@@@ -4303,9 -3915,6 +4314,9 @@@ void intel_modeset_cleanup(struct drm_d
  
        mutex_unlock(&dev->struct_mutex);
  
 +      if (dev_priv->display.disable_fbc)
 +              dev_priv->display.disable_fbc(dev);
 +
        drm_mode_config_cleanup(dev);
  }
  
@@@ -4319,20 -3928,3 +4330,20 @@@ struct drm_encoder *intel_best_encoder(
  
        return &intel_output->enc;
  }
 +
 +/*
 + * set vga decode state - true == enable VGA decode
 + */
 +int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      u16 gmch_ctrl;
 +
 +      pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl);
 +      if (state)
 +              gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
 +      else
 +              gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
 +      pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl);
 +      return 0;
 +}
index 8aa4b7f30daa58bea5280bc9569041e4dc25c157,aa96b522135831620899471deadb55f7363baccf..ef61fe9507e2e86a67ffc2dea1503ac409dbc855
@@@ -28,7 -28,6 +28,7 @@@
  #include <linux/i2c.h>
  #include <linux/i2c-id.h>
  #include <linux/i2c-algo-bit.h>
 +#include "i915_drv.h"
  #include "drm_crtc.h"
  
  #include "drm_crtc_helper.h"
@@@ -75,7 -74,6 +75,7 @@@
  #define INTEL_LVDS_CLONE_BIT 14
  #define INTEL_DVO_TMDS_CLONE_BIT 15
  #define INTEL_DVO_LVDS_CLONE_BIT 16
 +#define INTEL_EDP_CLONE_BIT 17
  
  #define INTEL_DVO_CHIP_NONE 0
  #define INTEL_DVO_CHIP_LVDS 1
@@@ -112,8 -110,8 +112,8 @@@ struct intel_output 
  
  struct intel_crtc {
        struct drm_crtc base;
 -      int pipe;
 -      int plane;
 +      enum pipe pipe;
 +      enum plane plane;
        struct drm_gem_object *cursor_bo;
        uint32_t cursor_addr;
        u8 lut_r[256], lut_g[256], lut_b[256];
@@@ -175,10 -173,11 +175,12 @@@ extern int intelfb_resize(struct drm_de
  extern void intelfb_restore(void);
  extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
                                    u16 blue, int regno);
+ extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+                                   u16 *blue, int regno);
  
  extern int intel_framebuffer_create(struct drm_device *dev,
                                    struct drm_mode_fb_cmd *mode_cmd,
                                    struct drm_framebuffer **fb,
                                    struct drm_gem_object *obj);
 +
  #endif /* __INTEL_DRV_H__ */
index e6cce24de8020a2830a5d675e5ffc2d99e1b2dc8,374ecacc6183704344e00ce152b1bbdade5c0c71..161094c07d9443957b8f193386e28db258244620
@@@ -32,6 -32,9 +32,9 @@@
  #include "radeon_reg.h"
  #include "radeon.h"
  #include "r100d.h"
+ #include "rs100d.h"
+ #include "rv200d.h"
+ #include "rv250d.h"
  
  #include <linux/firmware.h>
  #include <linux/platform_device.h>
@@@ -60,18 -63,7 +63,7 @@@ MODULE_FIRMWARE(FIRMWARE_R520)
  
  /* This files gather functions specifics to:
   * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
-  *
-  * Some of these functions might be used by newer ASICs.
   */
- int r200_init(struct radeon_device *rdev);
- void r100_hdp_reset(struct radeon_device *rdev);
- void r100_gpu_init(struct radeon_device *rdev);
- int r100_gui_wait_for_idle(struct radeon_device *rdev);
- int r100_mc_wait_for_idle(struct radeon_device *rdev);
- void r100_gpu_wait_for_vsync(struct radeon_device *rdev);
- void r100_gpu_wait_for_vsync2(struct radeon_device *rdev);
- int r100_debugfs_mc_info_init(struct radeon_device *rdev);
  
  /*
   * PCI GART
@@@ -152,136 -144,6 +144,6 @@@ void r100_pci_gart_fini(struct radeon_d
        radeon_gart_fini(rdev);
  }
  
- /*
-  * MC
-  */
- void r100_mc_disable_clients(struct radeon_device *rdev)
- {
-       uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl;
-       /* FIXME: is this function correct for rs100,rs200,rs300 ? */
-       if (r100_gui_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "Failed to wait GUI idle while "
-                      "programming pipes. Bad things might happen.\n");
-       }
-       /* stop display and memory access */
-       ov0_scale_cntl = RREG32(RADEON_OV0_SCALE_CNTL);
-       WREG32(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
-       crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
-       WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
-       crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL);
-       r100_gpu_wait_for_vsync(rdev);
-       WREG32(RADEON_CRTC_GEN_CNTL,
-              (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) |
-              RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
-       if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
-               crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
-               r100_gpu_wait_for_vsync2(rdev);
-               WREG32(RADEON_CRTC2_GEN_CNTL,
-                      (crtc2_gen_cntl &
-                       ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) |
-                      RADEON_CRTC2_DISP_REQ_EN_B);
-       }
-       udelay(500);
- }
- void r100_mc_setup(struct radeon_device *rdev)
- {
-       uint32_t tmp;
-       int r;
-       r = r100_debugfs_mc_info_init(rdev);
-       if (r) {
-               DRM_ERROR("Failed to register debugfs file for R100 MC !\n");
-       }
-       /* Write VRAM size in case we are limiting it */
-       WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
-       /* Novell bug 204882 for RN50/M6/M7 with 8/16/32MB VRAM,
-        * if the aperture is 64MB but we have 32MB VRAM
-        * we report only 32MB VRAM but we have to set MC_FB_LOCATION
-        * to 64MB, otherwise the gpu accidentially dies */
-       tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-       tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
-       tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
-       WREG32(RADEON_MC_FB_LOCATION, tmp);
-       /* Enable bus mastering */
-       tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
-       WREG32(RADEON_BUS_CNTL, tmp);
-       if (rdev->flags & RADEON_IS_AGP) {
-               tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-               tmp = REG_SET(RADEON_MC_AGP_TOP, tmp >> 16);
-               tmp |= REG_SET(RADEON_MC_AGP_START, rdev->mc.gtt_location >> 16);
-               WREG32(RADEON_MC_AGP_LOCATION, tmp);
-               WREG32(RADEON_AGP_BASE, rdev->mc.agp_base);
-       } else {
-               WREG32(RADEON_MC_AGP_LOCATION, 0x0FFFFFFF);
-               WREG32(RADEON_AGP_BASE, 0);
-       }
-       tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL;
-       tmp |= (7 << 28);
-       WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
-       (void)RREG32(RADEON_HOST_PATH_CNTL);
-       WREG32(RADEON_HOST_PATH_CNTL, tmp);
-       (void)RREG32(RADEON_HOST_PATH_CNTL);
- }
- int r100_mc_init(struct radeon_device *rdev)
- {
-       int r;
-       if (r100_debugfs_rbbm_init(rdev)) {
-               DRM_ERROR("Failed to register debugfs file for RBBM !\n");
-       }
-       r100_gpu_init(rdev);
-       /* Disable gart which also disable out of gart access */
-       r100_pci_gart_disable(rdev);
-       /* Setup GPU memory space */
-       rdev->mc.gtt_location = 0xFFFFFFFFUL;
-       if (rdev->flags & RADEON_IS_AGP) {
-               r = radeon_agp_init(rdev);
-               if (r) {
-                       printk(KERN_WARNING "[drm] Disabling AGP\n");
-                       rdev->flags &= ~RADEON_IS_AGP;
-                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-               } else {
-                       rdev->mc.gtt_location = rdev->mc.agp_base;
-               }
-       }
-       r = radeon_mc_setup(rdev);
-       if (r) {
-               return r;
-       }
-       r100_mc_disable_clients(rdev);
-       if (r100_mc_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "Failed to wait MC idle while "
-                      "programming pipes. Bad things might happen.\n");
-       }
-       r100_mc_setup(rdev);
-       return 0;
- }
- void r100_mc_fini(struct radeon_device *rdev)
- {
- }
- /*
-  * Interrupts
-  */
  int r100_irq_set(struct radeon_device *rdev)
  {
        uint32_t tmp = 0;
@@@ -358,10 -220,6 +220,6 @@@ u32 r100_get_vblank_counter(struct rade
                return RREG32(RADEON_CRTC2_CRNT_FRAME);
  }
  
- /*
-  * Fence emission
-  */
  void r100_fence_ring_emit(struct radeon_device *rdev,
                          struct radeon_fence *fence)
  {
        radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
  }
  
- /*
-  * Writeback
-  */
  int r100_wb_init(struct radeon_device *rdev)
  {
        int r;
@@@ -504,10 -358,6 +358,6 @@@ int r100_copy_blit(struct radeon_devic
        return r;
  }
  
- /*
-  * CP
-  */
  static int r100_cp_wait_for_idle(struct radeon_device *rdev)
  {
        unsigned i;
@@@ -612,6 -462,7 +462,7 @@@ static int r100_cp_init_microcode(struc
        }
        return err;
  }
  static void r100_cp_load_microcode(struct radeon_device *rdev)
  {
        const __be32 *fw_data;
@@@ -978,7 -829,7 +829,7 @@@ int r100_cs_packet_parse_vline(struct r
  
        header = radeon_get_ib_value(p, h_idx);
        crtc_id = radeon_get_ib_value(p, h_idx + 5);
-       reg = header >> 2;
+       reg = CP_PACKET0_GET_REG(header);
        mutex_lock(&p->rdev->ddev->mode_config.mutex);
        obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
        if (!obj) {
@@@ -1911,20 -1762,6 +1762,20 @@@ void r100_vram_init_sizes(struct radeon
        if (rdev->mc.real_vram_size > rdev->mc.aper_size)
                rdev->mc.real_vram_size = rdev->mc.aper_size;
  }
 +
 +void r100_vga_set_state(struct radeon_device *rdev, bool state)
 +{
 +      uint32_t temp;
 +
 +      temp = RREG32(RADEON_CONFIG_CNTL);
 +      if (state == false) {
 +              temp &= ~(1<<8);
 +              temp |= (1<<9);
 +      } else {
 +              temp &= ~(1<<9);
 +      }
 +      WREG32(RADEON_CONFIG_CNTL, temp);
 +}
  
  void r100_vram_info(struct radeon_device *rdev)
  {
@@@ -1990,7 -1827,7 +1841,7 @@@ void r100_pll_wreg(struct radeon_devic
        r100_pll_errata_after_data(rdev);
  }
  
int r100_init(struct radeon_device *rdev)
void r100_set_safe_registers(struct radeon_device *rdev)
  {
        if (ASIC_IS_RN50(rdev)) {
                rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
                rdev->config.r100.reg_safe_bm = r100_reg_safe_bm;
                rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm);
        } else {
-               return r200_init(rdev);
+               r200_set_safe_registers(rdev);
        }
-       return 0;
  }
  
  /*
@@@ -2299,9 -2135,11 +2149,11 @@@ void r100_bandwidth_update(struct radeo
                mode1 = &rdev->mode_info.crtcs[0]->base.mode;
                pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
        }
-       if (rdev->mode_info.crtcs[1]->base.enabled) {
-               mode2 = &rdev->mode_info.crtcs[1]->base.mode;
-               pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
+       if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
+               if (rdev->mode_info.crtcs[1]->base.enabled) {
+                       mode2 = &rdev->mode_info.crtcs[1]->base.mode;
+                       pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
+               }
        }
  
        min_mem_eff.full = rfixed_const_8(0);
@@@ -3114,7 -2952,7 +2966,7 @@@ void r100_mc_stop(struct radeon_device 
        WREG32(R_000740_CP_CSQ_CNTL, 0);
  
        /* Save few CRTC registers */
-       save->GENMO_WT = RREG32(R_0003C0_GENMO_WT);
+       save->GENMO_WT = RREG8(R_0003C2_GENMO_WT);
        save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL);
        save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL);
        save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET);
        }
  
        /* Disable VGA aperture access */
-       WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT);
+       WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & save->GENMO_WT);
        /* Disable cursor, overlay, crtc */
        WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1));
        WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL |
@@@ -3156,10 -2994,264 +3008,264 @@@ void r100_mc_resume(struct radeon_devic
                                rdev->mc.vram_location);
        }
        /* Restore CRTC registers */
-       WREG32(R_0003C0_GENMO_WT, save->GENMO_WT);
+       WREG8(R_0003C2_GENMO_WT, save->GENMO_WT);
        WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL);
        WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL);
        if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
                WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL);
        }
  }
+ void r100_vga_render_disable(struct radeon_device *rdev)
+ {
+       u32 tmp;
+       tmp = RREG8(R_0003C2_GENMO_WT);
+       WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp);
+ }
+ static void r100_debugfs(struct radeon_device *rdev)
+ {
+       int r;
+       r = r100_debugfs_mc_info_init(rdev);
+       if (r)
+               dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n");
+ }
+ static void r100_mc_program(struct radeon_device *rdev)
+ {
+       struct r100_mc_save save;
+       /* Stops all mc clients */
+       r100_mc_stop(rdev, &save);
+       if (rdev->flags & RADEON_IS_AGP) {
+               WREG32(R_00014C_MC_AGP_LOCATION,
+                       S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) |
+                       S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
+               WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
+               if (rdev->family > CHIP_RV200)
+                       WREG32(R_00015C_AGP_BASE_2,
+                               upper_32_bits(rdev->mc.agp_base) & 0xff);
+       } else {
+               WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF);
+               WREG32(R_000170_AGP_BASE, 0);
+               if (rdev->family > CHIP_RV200)
+                       WREG32(R_00015C_AGP_BASE_2, 0);
+       }
+       /* Wait for mc idle */
+       if (r100_mc_wait_for_idle(rdev))
+               dev_warn(rdev->dev, "Wait for MC idle timeout.\n");
+       /* Program MC, should be a 32bits limited address space */
+       WREG32(R_000148_MC_FB_LOCATION,
+               S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
+               S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
+       r100_mc_resume(rdev, &save);
+ }
+ void r100_clock_startup(struct radeon_device *rdev)
+ {
+       u32 tmp;
+       if (radeon_dynclks != -1 && radeon_dynclks)
+               radeon_legacy_set_clock_gating(rdev, 1);
+       /* We need to force on some of the block */
+       tmp = RREG32_PLL(R_00000D_SCLK_CNTL);
+       tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
+       if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280))
+               tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1);
+       WREG32_PLL(R_00000D_SCLK_CNTL, tmp);
+ }
+ static int r100_startup(struct radeon_device *rdev)
+ {
+       int r;
+       r100_mc_program(rdev);
+       /* Resume clock */
+       r100_clock_startup(rdev);
+       /* Initialize GPU configuration (# pipes, ...) */
+       r100_gpu_init(rdev);
+       /* Initialize GART (initialize after TTM so we can allocate
+        * memory through TTM but finalize after TTM) */
+       if (rdev->flags & RADEON_IS_PCI) {
+               r = r100_pci_gart_enable(rdev);
+               if (r)
+                       return r;
+       }
+       /* Enable IRQ */
+       rdev->irq.sw_int = true;
+       r100_irq_set(rdev);
+       /* 1M ring buffer */
+       r = r100_cp_init(rdev, 1024 * 1024);
+       if (r) {
+               dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+               return r;
+       }
+       r = r100_wb_init(rdev);
+       if (r)
+               dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+       r = r100_ib_init(rdev);
+       if (r) {
+               dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+               return r;
+       }
+       return 0;
+ }
+ int r100_resume(struct radeon_device *rdev)
+ {
+       /* Make sur GART are not working */
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_disable(rdev);
+       /* Resume clock before doing reset */
+       r100_clock_startup(rdev);
+       /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+       if (radeon_gpu_reset(rdev)) {
+               dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+                       RREG32(R_000E40_RBBM_STATUS),
+                       RREG32(R_0007C0_CP_STAT));
+       }
+       /* post */
+       radeon_combios_asic_init(rdev->ddev);
+       /* Resume clock after posting */
+       r100_clock_startup(rdev);
+       return r100_startup(rdev);
+ }
+ int r100_suspend(struct radeon_device *rdev)
+ {
+       r100_cp_disable(rdev);
+       r100_wb_disable(rdev);
+       r100_irq_disable(rdev);
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_disable(rdev);
+       return 0;
+ }
+ void r100_fini(struct radeon_device *rdev)
+ {
+       r100_suspend(rdev);
+       r100_cp_fini(rdev);
+       r100_wb_fini(rdev);
+       r100_ib_fini(rdev);
+       radeon_gem_fini(rdev);
+       if (rdev->flags & RADEON_IS_PCI)
+               r100_pci_gart_fini(rdev);
+       radeon_irq_kms_fini(rdev);
+       radeon_fence_driver_fini(rdev);
+       radeon_object_fini(rdev);
+       radeon_atombios_fini(rdev);
+       kfree(rdev->bios);
+       rdev->bios = NULL;
+ }
+ int r100_mc_init(struct radeon_device *rdev)
+ {
+       int r;
+       u32 tmp;
+       /* Setup GPU memory space */
+       rdev->mc.vram_location = 0xFFFFFFFFUL;
+       rdev->mc.gtt_location = 0xFFFFFFFFUL;
+       if (rdev->flags & RADEON_IS_IGP) {
+               tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
+               rdev->mc.vram_location = tmp << 16;
+       }
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r) {
+                       printk(KERN_WARNING "[drm] Disabling AGP\n");
+                       rdev->flags &= ~RADEON_IS_AGP;
+                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+               } else {
+                       rdev->mc.gtt_location = rdev->mc.agp_base;
+               }
+       }
+       r = radeon_mc_setup(rdev);
+       if (r)
+               return r;
+       return 0;
+ }
+ int r100_init(struct radeon_device *rdev)
+ {
+       int r;
+       /* Register debugfs file specific to this group of asics */
+       r100_debugfs(rdev);
+       /* Disable VGA */
+       r100_vga_render_disable(rdev);
+       /* Initialize scratch registers */
+       radeon_scratch_init(rdev);
+       /* Initialize surface registers */
+       radeon_surface_init(rdev);
+       /* TODO: disable VGA need to use VGA request */
+       /* BIOS*/
+       if (!radeon_get_bios(rdev)) {
+               if (ASIC_IS_AVIVO(rdev))
+                       return -EINVAL;
+       }
+       if (rdev->is_atom_bios) {
+               dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
+               return -EINVAL;
+       } else {
+               r = radeon_combios_init(rdev);
+               if (r)
+                       return r;
+       }
+       /* Reset gpu before posting otherwise ATOM will enter infinite loop */
+       if (radeon_gpu_reset(rdev)) {
+               dev_warn(rdev->dev,
+                       "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+                       RREG32(R_000E40_RBBM_STATUS),
+                       RREG32(R_0007C0_CP_STAT));
+       }
+       /* check if cards are posted or not */
+       if (!radeon_card_posted(rdev) && rdev->bios) {
+               DRM_INFO("GPU not posted. posting now...\n");
+               radeon_combios_asic_init(rdev->ddev);
+       }
+       /* Set asic errata */
+       r100_errata(rdev);
+       /* Initialize clocks */
+       radeon_get_clock_info(rdev->ddev);
+       /* Get vram informations */
+       r100_vram_info(rdev);
+       /* Initialize memory controller (also test AGP) */
+       r = r100_mc_init(rdev);
+       if (r)
+               return r;
+       /* Fence driver */
+       r = radeon_fence_driver_init(rdev);
+       if (r)
+               return r;
+       r = radeon_irq_kms_init(rdev);
+       if (r)
+               return r;
+       /* Memory manager */
+       r = radeon_object_init(rdev);
+       if (r)
+               return r;
+       if (rdev->flags & RADEON_IS_PCI) {
+               r = r100_pci_gart_init(rdev);
+               if (r)
+                       return r;
+       }
+       r100_set_safe_registers(rdev);
+       rdev->accel_working = true;
+       r = r100_startup(rdev);
+       if (r) {
+               /* Somethings want wront with the accel init stop accel */
+               dev_err(rdev->dev, "Disabling GPU acceleration\n");
+               r100_suspend(rdev);
+               r100_cp_fini(rdev);
+               r100_wb_fini(rdev);
+               r100_ib_fini(rdev);
+               if (rdev->flags & RADEON_IS_PCI)
+                       r100_pci_gart_fini(rdev);
+               radeon_irq_kms_fini(rdev);
+               rdev->accel_working = false;
+       }
+       return 0;
+ }
index 2e4e60edbff4e3a08fb80b727b617a18164af5e9,6b43a95a5fb2df7c79e3096122a7f97dbbfc67fb..609719490ec28c26b064df9d43eb642954fbb442
@@@ -65,16 -65,11 +65,11 @@@ MODULE_FIRMWARE("radeon/RV710_me.bin")
  
  int r600_debugfs_mc_info_init(struct radeon_device *rdev);
  
- /* This files gather functions specifics to:
-  * r600,rv610,rv630,rv620,rv635,rv670
-  *
-  * Some of these functions might be used by newer ASICs.
-  */
+ /* r600,rv610,rv630,rv620,rv635,rv670 */
  int r600_mc_wait_for_idle(struct radeon_device *rdev);
  void r600_gpu_init(struct radeon_device *rdev);
  void r600_fini(struct radeon_device *rdev);
  
  /*
   * R600 PCIE GART
   */
@@@ -168,7 -163,7 +163,7 @@@ int r600_pcie_gart_enable(struct radeon
        WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
        WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
        WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
-       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12);
+       WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
        WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
        WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
                                RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
@@@ -225,6 -220,40 +220,40 @@@ void r600_pcie_gart_fini(struct radeon_
        radeon_gart_fini(rdev);
  }
  
+ void r600_agp_enable(struct radeon_device *rdev)
+ {
+       u32 tmp;
+       int i;
+       /* Setup L2 cache */
+       WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
+                               ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+                               EFFECTIVE_L2_QUEUE_SIZE(7));
+       WREG32(VM_L2_CNTL2, 0);
+       WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
+       /* Setup TLB control */
+       tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
+               SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+               EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
+               ENABLE_WAIT_L2_QUERY;
+       WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
+       WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
+       WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
+       WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
+       for (i = 0; i < 7; i++)
+               WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+ }
  int r600_mc_wait_for_idle(struct radeon_device *rdev)
  {
        unsigned i;
        return -1;
  }
  
- static void r600_mc_resume(struct radeon_device *rdev)
+ static void r600_mc_program(struct radeon_device *rdev)
  {
-       u32 d1vga_control, d2vga_control;
-       u32 vga_render_control, vga_hdp_control;
-       u32 d1crtc_control, d2crtc_control;
-       u32 new_d1grph_primary, new_d1grph_secondary;
-       u32 new_d2grph_primary, new_d2grph_secondary;
-       u64 old_vram_start;
+       struct rv515_mc_save save;
        u32 tmp;
        int i, j;
  
        }
        WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
  
-       d1vga_control = RREG32(D1VGA_CONTROL);
-       d2vga_control = RREG32(D2VGA_CONTROL);
-       vga_render_control = RREG32(VGA_RENDER_CONTROL);
-       vga_hdp_control = RREG32(VGA_HDP_CONTROL);
-       d1crtc_control = RREG32(D1CRTC_CONTROL);
-       d2crtc_control = RREG32(D2CRTC_CONTROL);
-       old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
-       new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
-       new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
-       new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
-       new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
-       new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
-       new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
-       new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
-       new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
-       /* Stop all video */
-       WREG32(D1VGA_CONTROL, 0);
-       WREG32(D2VGA_CONTROL, 0);
-       WREG32(VGA_RENDER_CONTROL, 0);
-       WREG32(D1CRTC_UPDATE_LOCK, 1);
-       WREG32(D2CRTC_UPDATE_LOCK, 1);
-       WREG32(D1CRTC_CONTROL, 0);
-       WREG32(D2CRTC_CONTROL, 0);
-       WREG32(D1CRTC_UPDATE_LOCK, 0);
-       WREG32(D2CRTC_UPDATE_LOCK, 0);
-       mdelay(1);
+       rv515_mc_stop(rdev, &save);
        if (r600_mc_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "[drm] MC not idle !\n");
+               dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
-       /* Lockout access through VGA aperture*/
+       /* Lockout access through VGA aperture (doesn't exist before R600) */
        WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
        /* Update configuration */
-       WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
-       WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
+       if (rdev->flags & RADEON_IS_AGP) {
+               if (rdev->mc.vram_start < rdev->mc.gtt_start) {
+                       /* VRAM before AGP */
+                       WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+                               rdev->mc.vram_start >> 12);
+                       WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+                               rdev->mc.gtt_end >> 12);
+               } else {
+                       /* VRAM after AGP */
+                       WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
+                               rdev->mc.gtt_start >> 12);
+                       WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
+                               rdev->mc.vram_end >> 12);
+               }
+       } else {
+               WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
+               WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12);
+       }
        WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
-       tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16;
+       tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
        tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
        WREG32(MC_VM_FB_LOCATION, tmp);
        WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
        WREG32(HDP_NONSURFACE_INFO, (2 << 7));
-       WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
+       WREG32(HDP_NONSURFACE_SIZE, rdev->mc.mc_vram_size | 0x3FF);
        if (rdev->flags & RADEON_IS_AGP) {
-               WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16);
-               WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
+               WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22);
+               WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22);
                WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
        } else {
                WREG32(MC_VM_AGP_BASE, 0);
                WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
                WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
        }
-       WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
-       WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
-       WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
-       WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
-       WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
-       /* Unlock host access */
-       WREG32(VGA_HDP_CONTROL, vga_hdp_control);
-       mdelay(1);
        if (r600_mc_wait_for_idle(rdev)) {
-               printk(KERN_WARNING "[drm] MC not idle !\n");
+               dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
        }
-       /* Restore video state */
-       WREG32(D1CRTC_UPDATE_LOCK, 1);
-       WREG32(D2CRTC_UPDATE_LOCK, 1);
-       WREG32(D1CRTC_CONTROL, d1crtc_control);
-       WREG32(D2CRTC_CONTROL, d2crtc_control);
-       WREG32(D1CRTC_UPDATE_LOCK, 0);
-       WREG32(D2CRTC_UPDATE_LOCK, 0);
-       WREG32(D1VGA_CONTROL, d1vga_control);
-       WREG32(D2VGA_CONTROL, d2vga_control);
-       WREG32(VGA_RENDER_CONTROL, vga_render_control);
+       rv515_mc_resume(rdev, &save);
        /* we need to own VRAM, so turn off the VGA renderer here
         * to stop it overwriting our objects */
        rv515_vga_render_disable(rdev);
@@@ -445,9 -435,9 +435,9 @@@ int r600_mc_init(struct radeon_device *
                }
        }
        rdev->mc.vram_start = rdev->mc.vram_location;
-       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+       rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
        rdev->mc.gtt_start = rdev->mc.gtt_location;
-       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size;
+       rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
        /* FIXME: we should enforce default clock in case GPU is not in
         * default setup
         */
   */
  int r600_gpu_soft_reset(struct radeon_device *rdev)
  {
+       struct rv515_mc_save save;
        u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
                                S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
                                S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
                        S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
                        S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
        u32 srbm_reset = 0;
+       u32 tmp;
  
+       dev_info(rdev->dev, "GPU softreset \n");
+       dev_info(rdev->dev, "  R_008010_GRBM_STATUS=0x%08X\n",
+               RREG32(R_008010_GRBM_STATUS));
+       dev_info(rdev->dev, "  R_008014_GRBM_STATUS2=0x%08X\n",
+               RREG32(R_008014_GRBM_STATUS2));
+       dev_info(rdev->dev, "  R_000E50_SRBM_STATUS=0x%08X\n",
+               RREG32(R_000E50_SRBM_STATUS));
+       rv515_mc_stop(rdev, &save);
+       if (r600_mc_wait_for_idle(rdev)) {
+               dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+       }
        /* Disable CP parsing/prefetching */
        WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
        /* Check if any of the rendering block is busy and reset it */
        if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
            (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
-               WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) |
+               tmp = S_008020_SOFT_RESET_CR(1) |
                        S_008020_SOFT_RESET_DB(1) |
                        S_008020_SOFT_RESET_CB(1) |
                        S_008020_SOFT_RESET_PA(1) |
                        S_008020_SOFT_RESET_TC(1) |
                        S_008020_SOFT_RESET_TA(1) |
                        S_008020_SOFT_RESET_VC(1) |
-                       S_008020_SOFT_RESET_VGT(1));
+                       S_008020_SOFT_RESET_VGT(1);
+               dev_info(rdev->dev, "  R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
+               WREG32(R_008020_GRBM_SOFT_RESET, tmp);
                (void)RREG32(R_008020_GRBM_SOFT_RESET);
                udelay(50);
                WREG32(R_008020_GRBM_SOFT_RESET, 0);
                (void)RREG32(R_008020_GRBM_SOFT_RESET);
        }
        /* Reset CP (we always reset CP) */
-       WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1));
+       tmp = S_008020_SOFT_RESET_CP(1);
+       dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
+       WREG32(R_008020_GRBM_SOFT_RESET, tmp);
        (void)RREG32(R_008020_GRBM_SOFT_RESET);
        udelay(50);
        WREG32(R_008020_GRBM_SOFT_RESET, 0);
                srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
        if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
                srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
+       if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+               srbm_reset |= S_000E60_SOFT_RESET_BIF(1);
+       dev_info(rdev->dev, "  R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
+       WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
+       (void)RREG32(R_000E60_SRBM_SOFT_RESET);
+       udelay(50);
+       WREG32(R_000E60_SRBM_SOFT_RESET, 0);
+       (void)RREG32(R_000E60_SRBM_SOFT_RESET);
        WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
        (void)RREG32(R_000E60_SRBM_SOFT_RESET);
        udelay(50);
        (void)RREG32(R_000E60_SRBM_SOFT_RESET);
        /* Wait a little for things to settle down */
        udelay(50);
+       dev_info(rdev->dev, "  R_008010_GRBM_STATUS=0x%08X\n",
+               RREG32(R_008010_GRBM_STATUS));
+       dev_info(rdev->dev, "  R_008014_GRBM_STATUS2=0x%08X\n",
+               RREG32(R_008014_GRBM_STATUS2));
+       dev_info(rdev->dev, "  R_000E50_SRBM_STATUS=0x%08X\n",
+               RREG32(R_000E50_SRBM_STATUS));
+       /* After reset we need to reinit the asic as GPU often endup in an
+        * incoherent state.
+        */
+       atom_asic_init(rdev->mode_info.atom_context);
+       rv515_mc_resume(rdev, &save);
        return 0;
  }
  
@@@ -1350,32 -1376,47 +1376,47 @@@ int r600_ring_test(struct radeon_devic
        return r;
  }
  
- /*
-  * Writeback
-  */
- int r600_wb_init(struct radeon_device *rdev)
+ void r600_wb_disable(struct radeon_device *rdev)
+ {
+       WREG32(SCRATCH_UMSK, 0);
+       if (rdev->wb.wb_obj) {
+               radeon_object_kunmap(rdev->wb.wb_obj);
+               radeon_object_unpin(rdev->wb.wb_obj);
+       }
+ }
+ void r600_wb_fini(struct radeon_device *rdev)
+ {
+       r600_wb_disable(rdev);
+       if (rdev->wb.wb_obj) {
+               radeon_object_unref(&rdev->wb.wb_obj);
+               rdev->wb.wb = NULL;
+               rdev->wb.wb_obj = NULL;
+       }
+ }
+ int r600_wb_enable(struct radeon_device *rdev)
  {
        int r;
  
        if (rdev->wb.wb_obj == NULL) {
-               r = radeon_object_create(rdev, NULL, 4096,
-                                        true,
-                                        RADEON_GEM_DOMAIN_GTT,
-                                        false, &rdev->wb.wb_obj);
+               r = radeon_object_create(rdev, NULL, 4096, true,
+                               RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
                if (r) {
-                       DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
+                       dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
                        return r;
                }
-               r = radeon_object_pin(rdev->wb.wb_obj,
-                                     RADEON_GEM_DOMAIN_GTT,
-                                     &rdev->wb.gpu_addr);
+               r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
+                               &rdev->wb.gpu_addr);
                if (r) {
-                       DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
+                       dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r);
+                       r600_wb_fini(rdev);
                        return r;
                }
                r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
                if (r) {
-                       DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
+                       dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r);
+                       r600_wb_fini(rdev);
                        return r;
                }
        }
        return 0;
  }
  
- void r600_wb_fini(struct radeon_device *rdev)
- {
-       if (rdev->wb.wb_obj) {
-               radeon_object_kunmap(rdev->wb.wb_obj);
-               radeon_object_unpin(rdev->wb.wb_obj);
-               radeon_object_unref(&rdev->wb.wb_obj);
-               rdev->wb.wb = NULL;
-               rdev->wb.wb_obj = NULL;
-       }
- }
- /*
-  * CS
-  */
  void r600_fence_ring_emit(struct radeon_device *rdev,
                          struct radeon_fence *fence)
  {
@@@ -1477,11 -1503,14 +1503,14 @@@ int r600_startup(struct radeon_device *
  {
        int r;
  
-       r600_gpu_reset(rdev);
-       r600_mc_resume(rdev);
-       r = r600_pcie_gart_enable(rdev);
-       if (r)
-               return r;
+       r600_mc_program(rdev);
+       if (rdev->flags & RADEON_IS_AGP) {
+               r600_agp_enable(rdev);
+       } else {
+               r = r600_pcie_gart_enable(rdev);
+               if (r)
+                       return r;
+       }
        r600_gpu_init(rdev);
  
        r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
        r = r600_cp_resume(rdev);
        if (r)
                return r;
-       r = r600_wb_init(rdev);
-       if (r)
-               return r;
+       /* write back buffer are not vital so don't worry about failure */
+       r600_wb_enable(rdev);
        return 0;
  }
  
 +void r600_vga_set_state(struct radeon_device *rdev, bool state)
 +{
 +      uint32_t temp;
 +
 +      temp = RREG32(CONFIG_CNTL);
 +      if (state == false) {
 +              temp &= ~(1<<0);
 +              temp |= (1<<1);
 +      } else {
 +              temp &= ~(1<<1);
 +      }
 +      WREG32(CONFIG_CNTL, temp);
 +}
 +
  int r600_resume(struct radeon_device *rdev)
  {
        int r;
  
-       if (radeon_gpu_reset(rdev)) {
-               /* FIXME: what do we want to do here ? */
-       }
+       /* Do not reset GPU before posting, on r600 hw unlike on r500 hw,
+        * posting will perform necessary task to bring back GPU into good
+        * shape.
+        */
        /* post card */
-       if (rdev->is_atom_bios) {
-               atom_asic_init(rdev->mode_info.atom_context);
-       } else {
-               radeon_combios_asic_init(rdev->ddev);
-       }
+       atom_asic_init(rdev->mode_info.atom_context);
        /* Initialize clocks */
        r = radeon_clocks_init(rdev);
        if (r) {
                return r;
        }
  
-       r = radeon_ib_test(rdev);
+       r = r600_ib_test(rdev);
        if (r) {
                DRM_ERROR("radeon: failled testing IB (%d).\n", r);
                return r;
        return r;
  }
  
  int r600_suspend(struct radeon_device *rdev)
  {
        /* FIXME: we should wait for ring to be empty */
        r600_cp_stop(rdev);
        rdev->cp.ready = false;
+       r600_wb_disable(rdev);
        r600_pcie_gart_disable(rdev);
        /* unpin shaders bo */
        radeon_object_unpin(rdev->r600_blit.shader_obj);
@@@ -1576,7 -1586,6 +1600,6 @@@ int r600_init(struct radeon_device *rde
  {
        int r;
  
-       rdev->new_init_path = true;
        r = radeon_dummy_page_init(rdev);
        if (r)
                return r;
                        return -EINVAL;
        }
        /* Must be an ATOMBIOS */
-       if (!rdev->is_atom_bios)
+       if (!rdev->is_atom_bios) {
+               dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
                return -EINVAL;
+       }
        r = radeon_atombios_init(rdev);
        if (r)
                return r;
        if (r)
                return r;
        r = r600_mc_init(rdev);
-       if (r) {
-               if (rdev->flags & RADEON_IS_AGP) {
-                       /* Retry with disabling AGP */
-                       r600_fini(rdev);
-                       rdev->flags &= ~RADEON_IS_AGP;
-                       return r600_init(rdev);
-               }
+       if (r)
                return r;
-       }
        /* Memory manager */
        r = radeon_object_init(rdev);
        if (r)
  
        r = r600_startup(rdev);
        if (r) {
-               if (rdev->flags & RADEON_IS_AGP) {
-                       /* Retry with disabling AGP */
-                       r600_fini(rdev);
-                       rdev->flags &= ~RADEON_IS_AGP;
-                       return r600_init(rdev);
-               }
+               r600_suspend(rdev);
+               r600_wb_fini(rdev);
+               radeon_ring_fini(rdev);
+               r600_pcie_gart_fini(rdev);
                rdev->accel_working = false;
        }
        if (rdev->accel_working) {
                        DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
                        rdev->accel_working = false;
                }
-               r = radeon_ib_test(rdev);
+               r = r600_ib_test(rdev);
                if (r) {
                        DRM_ERROR("radeon: failled testing IB (%d).\n", r);
                        rdev->accel_working = false;
@@@ -1683,19 -1685,15 +1699,15 @@@ void r600_fini(struct radeon_device *rd
  
        r600_blit_fini(rdev);
        radeon_ring_fini(rdev);
+       r600_wb_fini(rdev);
        r600_pcie_gart_fini(rdev);
        radeon_gem_fini(rdev);
        radeon_fence_driver_fini(rdev);
        radeon_clocks_fini(rdev);
- #if __OS_HAS_AGP
        if (rdev->flags & RADEON_IS_AGP)
                radeon_agp_fini(rdev);
- #endif
        radeon_object_fini(rdev);
-       if (rdev->is_atom_bios)
-               radeon_atombios_fini(rdev);
-       else
-               radeon_combios_fini(rdev);
+       radeon_atombios_fini(rdev);
        kfree(rdev->bios);
        rdev->bios = NULL;
        radeon_dummy_page_fini(rdev);
index 4a9028a85c9b225ce4cda0ccf8e82a77fa03fa26,5084595eb919e540ac5c2ca893326e869eb4182a..9b64d47f1f82ff4116f0c8b25872730843f92c0a
@@@ -78,7 -78,6 +78,7 @@@
  #define CB_COLOR0_MASK                                  0x28100
  
  #define       CONFIG_MEMSIZE                                  0x5428
 +#define CONFIG_CNTL                                   0x5424
  #define       CP_STAT                                         0x8680
  #define       CP_COHER_BASE                                   0x85F8
  #define       CP_DEBUG                                        0xC1FC
  #define               G_000E50_MCDW_BUSY(x)                   (((x) >> 13) & 1)
  #define               G_000E50_SEM_BUSY(x)                    (((x) >> 14) & 1)
  #define               G_000E50_RLC_BUSY(x)                    (((x) >> 15) & 1)
+ #define               G_000E50_BIF_BUSY(x)                    (((x) >> 29) & 1)
  #define       R_000E60_SRBM_SOFT_RESET                        0x0E60
  #define               S_000E60_SOFT_RESET_BIF(x)              (((x) & 1) << 1)
  #define               S_000E60_SOFT_RESET_CG(x)               (((x) & 1) << 2)
index 950b346e343ff5a66dd8ae438e588782409e4bf9,3598adca034ae71e1b1f5a5bfd698e30e397b16b..5ab35b81c86bfdeedf71ec6ff2b03e114bcfb4ec
@@@ -590,18 -590,7 +590,8 @@@ struct radeon_asic 
        void (*fini)(struct radeon_device *rdev);
        int (*resume)(struct radeon_device *rdev);
        int (*suspend)(struct radeon_device *rdev);
-       void (*errata)(struct radeon_device *rdev);
-       void (*vram_info)(struct radeon_device *rdev);
 +      void (*vga_set_state)(struct radeon_device *rdev, bool state);
        int (*gpu_reset)(struct radeon_device *rdev);
-       int (*mc_init)(struct radeon_device *rdev);
-       void (*mc_fini)(struct radeon_device *rdev);
-       int (*wb_init)(struct radeon_device *rdev);
-       void (*wb_fini)(struct radeon_device *rdev);
-       int (*gart_init)(struct radeon_device *rdev);
-       void (*gart_fini)(struct radeon_device *rdev);
-       int (*gart_enable)(struct radeon_device *rdev);
-       void (*gart_disable)(struct radeon_device *rdev);
        void (*gart_tlb_flush)(struct radeon_device *rdev);
        int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr);
        int (*cp_init)(struct radeon_device *rdev, unsigned ring_size);
        void (*ring_start)(struct radeon_device *rdev);
        int (*ring_test)(struct radeon_device *rdev);
        void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
-       int (*ib_test)(struct radeon_device *rdev);
        int (*irq_set)(struct radeon_device *rdev);
        int (*irq_process)(struct radeon_device *rdev);
        u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc);
@@@ -789,7 -777,6 +778,6 @@@ struct radeon_device 
        bool                            shutdown;
        bool                            suspend;
        bool                            need_dma32;
-       bool                            new_init_path;
        bool                            accel_working;
        struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
        const struct firmware *me_fw;   /* all family ME firmware */
@@@ -949,28 -936,13 +937,14 @@@ static inline void radeon_ring_write(st
  #define radeon_resume(rdev) (rdev)->asic->resume((rdev))
  #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev))
  #define radeon_cs_parse(p) rdev->asic->cs_parse((p))
- #define radeon_errata(rdev) (rdev)->asic->errata((rdev))
- #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev))
 +#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
  #define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev))
- #define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev))
- #define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
- #define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev))
- #define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev))
- #define radeon_gpu_gart_init(rdev) (rdev)->asic->gart_init((rdev))
- #define radeon_gpu_gart_fini(rdev) (rdev)->asic->gart_fini((rdev))
- #define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev))
- #define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev))
  #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev))
  #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p))
- #define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize))
- #define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev))
- #define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev))
  #define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev))
  #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev))
  #define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev))
  #define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib))
- #define radeon_ib_test(rdev) (rdev)->asic->ib_test((rdev))
  #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev))
  #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev))
  #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc))
@@@ -996,6 -968,7 +970,7 @@@ extern void radeon_clocks_fini(struct r
  extern void radeon_scratch_init(struct radeon_device *rdev);
  extern void radeon_surface_init(struct radeon_device *rdev);
  extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
+ extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
  extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
  
  /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
@@@ -1031,11 -1004,27 +1006,27 @@@ extern int r100_wb_init(struct radeon_d
  extern void r100_hdp_reset(struct radeon_device *rdev);
  extern int r100_rb2d_reset(struct radeon_device *rdev);
  extern int r100_cp_reset(struct radeon_device *rdev);
+ extern void r100_vga_render_disable(struct radeon_device *rdev);
+ extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
+                                               struct radeon_cs_packet *pkt,
+                                               struct radeon_object *robj);
+ extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
+                               struct radeon_cs_packet *pkt,
+                               const unsigned *auth, unsigned n,
+                               radeon_packet0_check_t check);
+ extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
+                               struct radeon_cs_packet *pkt,
+                               unsigned idx);
+ /* rv200,rv250,rv280 */
+ extern void r200_set_safe_registers(struct radeon_device *rdev);
  
  /* r300,r350,rv350,rv370,rv380 */
  extern void r300_set_reg_safe(struct radeon_device *rdev);
  extern void r300_mc_program(struct radeon_device *rdev);
  extern void r300_vram_info(struct radeon_device *rdev);
+ extern void r300_clock_startup(struct radeon_device *rdev);
+ extern int r300_mc_wait_for_idle(struct radeon_device *rdev);
  extern int rv370_pcie_gart_init(struct radeon_device *rdev);
  extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
  extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
@@@ -1066,6 -1055,18 +1057,18 @@@ extern void rv515_clock_startup(struct 
  extern void rv515_debugfs(struct radeon_device *rdev);
  extern int rv515_suspend(struct radeon_device *rdev);
  
+ /* rs400 */
+ extern int rs400_gart_init(struct radeon_device *rdev);
+ extern int rs400_gart_enable(struct radeon_device *rdev);
+ extern void rs400_gart_adjust_size(struct radeon_device *rdev);
+ extern void rs400_gart_disable(struct radeon_device *rdev);
+ extern void rs400_gart_fini(struct radeon_device *rdev);
+ /* rs600 */
+ extern void rs600_set_safe_registers(struct radeon_device *rdev);
+ extern int rs600_irq_set(struct radeon_device *rdev);
+ extern void rs600_irq_disable(struct radeon_device *rdev);
  /* rs690, rs740 */
  extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
                                        struct drm_display_mode *mode1,
@@@ -1083,8 -1084,9 +1086,9 @@@ extern int r600_pcie_gart_init(struct r
  extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
  extern int r600_ib_test(struct radeon_device *rdev);
  extern int r600_ring_test(struct radeon_device *rdev);
- extern int r600_wb_init(struct radeon_device *rdev);
  extern void r600_wb_fini(struct radeon_device *rdev);
+ extern int r600_wb_enable(struct radeon_device *rdev);
+ extern void r600_wb_disable(struct radeon_device *rdev);
  extern void r600_scratch_init(struct radeon_device *rdev);
  extern int r600_blit_init(struct radeon_device *rdev);
  extern void r600_blit_fini(struct radeon_device *rdev);
index c8a4e7b5663dfcfe38d07730b104fa18d4e57a4d,d38f996328270e88ced365c50aedc895c538ce17..c3532c7a6f3f04f74d26d6ef97ece8fea7da053e
@@@ -41,28 -41,16 +41,17 @@@ void radeon_atom_set_clock_gating(struc
  /*
   * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
   */
- int r100_init(struct radeon_device *rdev);
- int r200_init(struct radeon_device *rdev);
+ extern int r100_init(struct radeon_device *rdev);
+ extern void r100_fini(struct radeon_device *rdev);
+ extern int r100_suspend(struct radeon_device *rdev);
+ extern int r100_resume(struct radeon_device *rdev);
  uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
  void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
- void r100_errata(struct radeon_device *rdev);
- void r100_vram_info(struct radeon_device *rdev);
 +void r100_vga_set_state(struct radeon_device *rdev, bool state);
  int r100_gpu_reset(struct radeon_device *rdev);
- int r100_mc_init(struct radeon_device *rdev);
- void r100_mc_fini(struct radeon_device *rdev);
  u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
- int r100_wb_init(struct radeon_device *rdev);
- void r100_wb_fini(struct radeon_device *rdev);
- int r100_pci_gart_init(struct radeon_device *rdev);
- void r100_pci_gart_fini(struct radeon_device *rdev);
- int r100_pci_gart_enable(struct radeon_device *rdev);
- void r100_pci_gart_disable(struct radeon_device *rdev);
  void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
  int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
- int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
- void r100_cp_fini(struct radeon_device *rdev);
- void r100_cp_disable(struct radeon_device *rdev);
  void r100_cp_commit(struct radeon_device *rdev);
  void r100_ring_start(struct radeon_device *rdev);
  int r100_irq_set(struct radeon_device *rdev);
@@@ -83,33 -71,20 +72,21 @@@ int r100_set_surface_reg(struct radeon_
  int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
  void r100_bandwidth_update(struct radeon_device *rdev);
  void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
- int r100_ib_test(struct radeon_device *rdev);
  int r100_ring_test(struct radeon_device *rdev);
  
  static struct radeon_asic r100_asic = {
        .init = &r100_init,
-       .errata = &r100_errata,
-       .vram_info = &r100_vram_info,
+       .fini = &r100_fini,
+       .suspend = &r100_suspend,
+       .resume = &r100_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r100_gpu_reset,
-       .mc_init = &r100_mc_init,
-       .mc_fini = &r100_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &r100_pci_gart_init,
-       .gart_fini = &r100_pci_gart_fini,
-       .gart_enable = &r100_pci_gart_enable,
-       .gart_disable = &r100_pci_gart_disable,
        .gart_tlb_flush = &r100_pci_gart_tlb_flush,
        .gart_set_page = &r100_pci_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r100_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &r100_irq_set,
        .irq_process = &r100_irq_process,
        .get_vblank_counter = &r100_get_vblank_counter,
  /*
   * r300,r350,rv350,rv380
   */
- int r300_init(struct radeon_device *rdev);
- void r300_errata(struct radeon_device *rdev);
- void r300_vram_info(struct radeon_device *rdev);
- int r300_gpu_reset(struct radeon_device *rdev);
- int r300_mc_init(struct radeon_device *rdev);
- void r300_mc_fini(struct radeon_device *rdev);
- void r300_ring_start(struct radeon_device *rdev);
- void r300_fence_ring_emit(struct radeon_device *rdev,
-                         struct radeon_fence *fence);
- int r300_cs_parse(struct radeon_cs_parser *p);
- int rv370_pcie_gart_init(struct radeon_device *rdev);
- void rv370_pcie_gart_fini(struct radeon_device *rdev);
- int rv370_pcie_gart_enable(struct radeon_device *rdev);
- void rv370_pcie_gart_disable(struct radeon_device *rdev);
- void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
- int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
- uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
- void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
- void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
- int r300_copy_dma(struct radeon_device *rdev,
-                 uint64_t src_offset,
-                 uint64_t dst_offset,
-                 unsigned num_pages,
-                 struct radeon_fence *fence);
+ extern int r300_init(struct radeon_device *rdev);
+ extern void r300_fini(struct radeon_device *rdev);
+ extern int r300_suspend(struct radeon_device *rdev);
+ extern int r300_resume(struct radeon_device *rdev);
+ extern int r300_gpu_reset(struct radeon_device *rdev);
+ extern void r300_ring_start(struct radeon_device *rdev);
+ extern void r300_fence_ring_emit(struct radeon_device *rdev,
+                               struct radeon_fence *fence);
+ extern int r300_cs_parse(struct radeon_cs_parser *p);
+ extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
+ extern int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
+ extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
+ extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
+ extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
+ extern int r300_copy_dma(struct radeon_device *rdev,
+                       uint64_t src_offset,
+                       uint64_t dst_offset,
+                       unsigned num_pages,
+                       struct radeon_fence *fence);
  static struct radeon_asic r300_asic = {
        .init = &r300_init,
-       .errata = &r300_errata,
-       .vram_info = &r300_vram_info,
+       .fini = &r300_fini,
+       .suspend = &r300_suspend,
+       .resume = &r300_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = &r300_mc_init,
-       .mc_fini = &r300_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &r100_pci_gart_init,
-       .gart_fini = &r100_pci_gart_fini,
-       .gart_enable = &r100_pci_gart_enable,
-       .gart_disable = &r100_pci_gart_disable,
        .gart_tlb_flush = &r100_pci_gart_tlb_flush,
        .gart_set_page = &r100_pci_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &r100_irq_set,
        .irq_process = &r100_irq_process,
        .get_vblank_counter = &r100_get_vblank_counter,
@@@ -209,26 -166,13 +169,14 @@@ static struct radeon_asic r420_asic = 
        .fini = &r420_fini,
        .suspend = &r420_suspend,
        .resume = &r420_resume,
-       .errata = NULL,
-       .vram_info = NULL,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = NULL,
-       .wb_fini = NULL,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = NULL,
        .irq_set = &r100_irq_set,
        .irq_process = &r100_irq_process,
        .get_vblank_counter = &r100_get_vblank_counter,
  /*
   * rs400,rs480
   */
- void rs400_errata(struct radeon_device *rdev);
- void rs400_vram_info(struct radeon_device *rdev);
- int rs400_mc_init(struct radeon_device *rdev);
- void rs400_mc_fini(struct radeon_device *rdev);
- int rs400_gart_init(struct radeon_device *rdev);
- void rs400_gart_fini(struct radeon_device *rdev);
- int rs400_gart_enable(struct radeon_device *rdev);
- void rs400_gart_disable(struct radeon_device *rdev);
+ extern int rs400_init(struct radeon_device *rdev);
+ extern void rs400_fini(struct radeon_device *rdev);
+ extern int rs400_suspend(struct radeon_device *rdev);
+ extern int rs400_resume(struct radeon_device *rdev);
  void rs400_gart_tlb_flush(struct radeon_device *rdev);
  int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
  uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
  void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
  static struct radeon_asic rs400_asic = {
-       .init = &r300_init,
-       .errata = &rs400_errata,
-       .vram_info = &rs400_vram_info,
+       .init = &rs400_init,
+       .fini = &rs400_fini,
+       .suspend = &rs400_suspend,
+       .resume = &rs400_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = &rs400_mc_init,
-       .mc_fini = &rs400_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &rs400_gart_init,
-       .gart_fini = &rs400_gart_fini,
-       .gart_enable = &rs400_gart_enable,
-       .gart_disable = &rs400_gart_disable,
        .gart_tlb_flush = &rs400_gart_tlb_flush,
        .gart_set_page = &rs400_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &r100_irq_set,
        .irq_process = &r100_irq_process,
        .get_vblank_counter = &r100_get_vblank_counter,
  /*
   * rs600.
   */
- int rs600_init(struct radeon_device *rdev);
- void rs600_errata(struct radeon_device *rdev);
- void rs600_vram_info(struct radeon_device *rdev);
- int rs600_mc_init(struct radeon_device *rdev);
- void rs600_mc_fini(struct radeon_device *rdev);
+ extern int rs600_init(struct radeon_device *rdev);
+ extern void rs600_fini(struct radeon_device *rdev);
+ extern int rs600_suspend(struct radeon_device *rdev);
+ extern int rs600_resume(struct radeon_device *rdev);
  int rs600_irq_set(struct radeon_device *rdev);
  int rs600_irq_process(struct radeon_device *rdev);
  u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
- int rs600_gart_init(struct radeon_device *rdev);
- void rs600_gart_fini(struct radeon_device *rdev);
- int rs600_gart_enable(struct radeon_device *rdev);
- void rs600_gart_disable(struct radeon_device *rdev);
  void rs600_gart_tlb_flush(struct radeon_device *rdev);
  int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
  uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
@@@ -326,28 -249,16 +254,17 @@@ void rs600_mc_wreg(struct radeon_devic
  void rs600_bandwidth_update(struct radeon_device *rdev);
  static struct radeon_asic rs600_asic = {
        .init = &rs600_init,
-       .errata = &rs600_errata,
-       .vram_info = &rs600_vram_info,
+       .fini = &rs600_fini,
+       .suspend = &rs600_suspend,
+       .resume = &rs600_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = &rs600_mc_init,
-       .mc_fini = &rs600_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &rs600_gart_init,
-       .gart_fini = &rs600_gart_fini,
-       .gart_enable = &rs600_gart_enable,
-       .gart_disable = &rs600_gart_disable,
        .gart_tlb_flush = &rs600_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &rs600_irq_set,
        .irq_process = &rs600_irq_process,
        .get_vblank_counter = &rs600_get_vblank_counter,
  /*
   * rs690,rs740
   */
void rs690_errata(struct radeon_device *rdev);
- void rs690_vram_info(struct radeon_device *rdev);
- int rs690_mc_init(struct radeon_device *rdev);
void rs690_mc_fini(struct radeon_device *rdev);
int rs690_init(struct radeon_device *rdev);
+ void rs690_fini(struct radeon_device *rdev);
+ int rs690_resume(struct radeon_device *rdev);
int rs690_suspend(struct radeon_device *rdev);
  uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
  void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
  void rs690_bandwidth_update(struct radeon_device *rdev);
  static struct radeon_asic rs690_asic = {
-       .init = &rs600_init,
-       .errata = &rs690_errata,
-       .vram_info = &rs690_vram_info,
+       .init = &rs690_init,
+       .fini = &rs690_fini,
+       .suspend = &rs690_suspend,
+       .resume = &rs690_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
-       .mc_init = &rs690_mc_init,
-       .mc_fini = &rs690_mc_fini,
-       .wb_init = &r100_wb_init,
-       .wb_fini = &r100_wb_fini,
-       .gart_init = &rs400_gart_init,
-       .gart_fini = &rs400_gart_fini,
-       .gart_enable = &rs400_gart_enable,
-       .gart_disable = &rs400_gart_disable,
        .gart_tlb_flush = &rs400_gart_tlb_flush,
        .gart_set_page = &rs400_gart_set_page,
-       .cp_init = &r100_cp_init,
-       .cp_fini = &r100_cp_fini,
-       .cp_disable = &r100_cp_disable,
        .cp_commit = &r100_cp_commit,
        .ring_start = &r300_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = &r100_ib_test,
        .irq_set = &rs600_irq_set,
        .irq_process = &rs600_irq_process,
        .get_vblank_counter = &rs600_get_vblank_counter,
@@@ -435,28 -334,13 +341,14 @@@ static struct radeon_asic rv515_asic = 
        .fini = &rv515_fini,
        .suspend = &rv515_suspend,
        .resume = &rv515_resume,
-       .errata = NULL,
-       .vram_info = NULL,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &rv515_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = NULL,
-       .wb_fini = NULL,
-       .gart_init = &rv370_pcie_gart_init,
-       .gart_fini = &rv370_pcie_gart_fini,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
        .cp_commit = &r100_cp_commit,
        .ring_start = &rv515_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = NULL,
        .irq_set = &rs600_irq_set,
        .irq_process = &rs600_irq_process,
        .get_vblank_counter = &rs600_get_vblank_counter,
@@@ -485,28 -369,13 +377,14 @@@ static struct radeon_asic r520_asic = 
        .fini = &rv515_fini,
        .suspend = &rv515_suspend,
        .resume = &r520_resume,
-       .errata = NULL,
-       .vram_info = NULL,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &rv515_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = NULL,
-       .wb_fini = NULL,
-       .gart_init = NULL,
-       .gart_fini = NULL,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
        .cp_commit = &r100_cp_commit,
        .ring_start = &rv515_ring_start,
        .ring_test = &r100_ring_test,
        .ring_ib_execute = &r100_ring_ib_execute,
-       .ib_test = NULL,
        .irq_set = &rs600_irq_set,
        .irq_process = &rs600_irq_process,
        .get_vblank_counter = &rs600_get_vblank_counter,
@@@ -531,7 -400,6 +409,7 @@@ int r600_init(struct radeon_device *rde
  void r600_fini(struct radeon_device *rdev);
  int r600_suspend(struct radeon_device *rdev);
  int r600_resume(struct radeon_device *rdev);
 +void r600_vga_set_state(struct radeon_device *rdev, bool state);
  int r600_wb_init(struct radeon_device *rdev);
  void r600_wb_fini(struct radeon_device *rdev);
  void r600_cp_commit(struct radeon_device *rdev);
@@@ -554,37 -422,22 +432,23 @@@ int r600_set_surface_reg(struct radeon_
                         uint32_t offset, uint32_t obj_size);
  int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
  void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
- int r600_ib_test(struct radeon_device *rdev);
  int r600_ring_test(struct radeon_device *rdev);
  int r600_copy_blit(struct radeon_device *rdev,
                   uint64_t src_offset, uint64_t dst_offset,
                   unsigned num_pages, struct radeon_fence *fence);
  
  static struct radeon_asic r600_asic = {
-       .errata = NULL,
        .init = &r600_init,
        .fini = &r600_fini,
        .suspend = &r600_suspend,
        .resume = &r600_resume,
        .cp_commit = &r600_cp_commit,
-       .vram_info = NULL,
 +      .vga_set_state = &r600_vga_set_state,
        .gpu_reset = &r600_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = &r600_wb_init,
-       .wb_fini = &r600_wb_fini,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
        .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
-       .ring_start = NULL,
        .ring_test = &r600_ring_test,
        .ring_ib_execute = &r600_ring_ib_execute,
-       .ib_test = &r600_ib_test,
        .irq_set = &r600_irq_set,
        .irq_process = &r600_irq_process,
        .fence_ring_emit = &r600_fence_ring_emit,
@@@ -611,30 -464,16 +475,17 @@@ int rv770_resume(struct radeon_device *
  int rv770_gpu_reset(struct radeon_device *rdev);
  
  static struct radeon_asic rv770_asic = {
-       .errata = NULL,
        .init = &rv770_init,
        .fini = &rv770_fini,
        .suspend = &rv770_suspend,
        .resume = &rv770_resume,
        .cp_commit = &r600_cp_commit,
-       .vram_info = NULL,
        .gpu_reset = &rv770_gpu_reset,
-       .mc_init = NULL,
-       .mc_fini = NULL,
-       .wb_init = &r600_wb_init,
-       .wb_fini = &r600_wb_fini,
-       .gart_enable = NULL,
-       .gart_disable = NULL,
 +      .vga_set_state = &r600_vga_set_state,
        .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
-       .cp_init = NULL,
-       .cp_fini = NULL,
-       .cp_disable = NULL,
-       .ring_start = NULL,
        .ring_test = &r600_ring_test,
        .ring_ib_execute = &r600_ring_ib_execute,
-       .ib_test = &r600_ib_test,
        .irq_set = &r600_irq_set,
        .irq_process = &r600_irq_process,
        .fence_ring_emit = &r600_fence_ring_emit,
index ec835d56d30ab97b7b7b00e2a002d4daa396aeaf,d1cdda9b55863ff98e14d4223e2a7d7228e6e097..3d667031de6ea17e23ff08d0d50ee66d3ae1d47f
@@@ -29,7 -29,6 +29,7 @@@
  #include <drm/drmP.h>
  #include <drm/drm_crtc_helper.h>
  #include <drm/radeon_drm.h>
 +#include <linux/vgaarb.h>
  #include "radeon_reg.h"
  #include "radeon.h"
  #include "radeon_asic.h"
@@@ -322,10 -321,6 +322,6 @@@ int radeon_asic_init(struct radeon_devi
        case CHIP_RV380:
                rdev->asic = &r300_asic;
                if (rdev->flags & RADEON_IS_PCIE) {
-                       rdev->asic->gart_init = &rv370_pcie_gart_init;
-                       rdev->asic->gart_fini = &rv370_pcie_gart_fini;
-                       rdev->asic->gart_enable = &rv370_pcie_gart_enable;
-                       rdev->asic->gart_disable = &rv370_pcie_gart_disable;
                        rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
                        rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
                }
@@@ -481,18 -476,28 +477,40 @@@ void radeon_combios_fini(struct radeon_
  {
  }
  
 +/* if we get transitioned to only one device, tak VGA back */
 +static unsigned int radeon_vga_set_decode(void *cookie, bool state)
 +{
 +      struct radeon_device *rdev = cookie;
 +      radeon_vga_set_state(rdev, state);
 +      if (state)
 +              return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
 +                     VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 +      else
 +              return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 +}
++
+ void radeon_agp_disable(struct radeon_device *rdev)
+ {
+       rdev->flags &= ~RADEON_IS_AGP;
+       if (rdev->family >= CHIP_R600) {
+               DRM_INFO("Forcing AGP to PCIE mode\n");
+               rdev->flags |= RADEON_IS_PCIE;
+       } else if (rdev->family >= CHIP_RV515 ||
+                       rdev->family == CHIP_RV380 ||
+                       rdev->family == CHIP_RV410 ||
+                       rdev->family == CHIP_R423) {
+               DRM_INFO("Forcing AGP to PCIE mode\n");
+               rdev->flags |= RADEON_IS_PCIE;
+               rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+               rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
+       } else {
+               DRM_INFO("Forcing AGP to PCI mode\n");
+               rdev->flags |= RADEON_IS_PCI;
+               rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
+               rdev->asic->gart_set_page = &r100_pci_gart_set_page;
+       }
+ }
  /*
   * Radeon device.
   */
@@@ -531,32 -536,7 +549,7 @@@ int radeon_device_init(struct radeon_de
        }
  
        if (radeon_agpmode == -1) {
-               rdev->flags &= ~RADEON_IS_AGP;
-               if (rdev->family >= CHIP_R600) {
-                       DRM_INFO("Forcing AGP to PCIE mode\n");
-                       rdev->flags |= RADEON_IS_PCIE;
-               } else if (rdev->family >= CHIP_RV515 ||
-                          rdev->family == CHIP_RV380 ||
-                          rdev->family == CHIP_RV410 ||
-                          rdev->family == CHIP_R423) {
-                       DRM_INFO("Forcing AGP to PCIE mode\n");
-                       rdev->flags |= RADEON_IS_PCIE;
-                       rdev->asic->gart_init = &rv370_pcie_gart_init;
-                       rdev->asic->gart_fini = &rv370_pcie_gart_fini;
-                       rdev->asic->gart_enable = &rv370_pcie_gart_enable;
-                       rdev->asic->gart_disable = &rv370_pcie_gart_disable;
-                       rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
-                       rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
-               } else {
-                       DRM_INFO("Forcing AGP to PCI mode\n");
-                       rdev->flags |= RADEON_IS_PCI;
-                       rdev->asic->gart_init = &r100_pci_gart_init;
-                       rdev->asic->gart_fini = &r100_pci_gart_fini;
-                       rdev->asic->gart_enable = &r100_pci_gart_enable;
-                       rdev->asic->gart_disable = &r100_pci_gart_disable;
-                       rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
-                       rdev->asic->gart_set_page = &r100_pci_gart_set_page;
-               }
+               radeon_agp_disable(rdev);
        }
  
        /* set DMA mask + need_dma32 flags.
        DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
        DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
  
-       rdev->new_init_path = false;
-       r = radeon_init(rdev);
-       if (r) {
-               return r;
-       }
 +      /* if we have > 1 VGA cards, then disable the radeon VGA resources */
 +      r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
 +      if (r) {
 +              return -EINVAL;
 +      }
 +
-       if (!rdev->new_init_path) {
-               /* Setup errata flags */
-               radeon_errata(rdev);
-               /* Initialize scratch registers */
-               radeon_scratch_init(rdev);
-               /* Initialize surface registers */
-               radeon_surface_init(rdev);
-               /* BIOS*/
-               if (!radeon_get_bios(rdev)) {
-                       if (ASIC_IS_AVIVO(rdev))
-                               return -EINVAL;
-               }
-               if (rdev->is_atom_bios) {
-                       r = radeon_atombios_init(rdev);
-                       if (r) {
-                               return r;
-                       }
-               } else {
-                       r = radeon_combios_init(rdev);
-                       if (r) {
-                               return r;
-                       }
-               }
-               /* Reset gpu before posting otherwise ATOM will enter infinite loop */
-               if (radeon_gpu_reset(rdev)) {
-                       /* FIXME: what do we want to do here ? */
-               }
-               /* check if cards are posted or not */
-               if (!radeon_card_posted(rdev) && rdev->bios) {
-                       DRM_INFO("GPU not posted. posting now...\n");
-                       if (rdev->is_atom_bios) {
-                               atom_asic_init(rdev->mode_info.atom_context);
-                       } else {
-                               radeon_combios_asic_init(rdev->ddev);
-                       }
-               }
-               /* Get clock & vram information */
-               radeon_get_clock_info(rdev->ddev);
-               radeon_vram_info(rdev);
-               /* Initialize clocks */
-               r = radeon_clocks_init(rdev);
-               if (r) {
-                       return r;
-               }
+       r = radeon_init(rdev);
+       if (r)
+               return r;
 +
-               /* Initialize memory controller (also test AGP) */
-               r = radeon_mc_init(rdev);
-               if (r) {
-                       return r;
-               }
-               /* Fence driver */
-               r = radeon_fence_driver_init(rdev);
-               if (r) {
-                       return r;
-               }
-               r = radeon_irq_kms_init(rdev);
-               if (r) {
-                       return r;
-               }
-               /* Memory manager */
-               r = radeon_object_init(rdev);
-               if (r) {
-                       return r;
-               }
-               r = radeon_gpu_gart_init(rdev);
+       if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
+               /* Acceleration not working on AGP card try again
+                * with fallback to PCI or PCIE GART
+                */
+               radeon_gpu_reset(rdev);
+               radeon_fini(rdev);
+               radeon_agp_disable(rdev);
+               r = radeon_init(rdev);
                if (r)
                        return r;
-               /* Initialize GART (initialize after TTM so we can allocate
-                * memory through TTM but finalize after TTM) */
-               r = radeon_gart_enable(rdev);
-               if (r)
-                       return 0;
-                       r = radeon_gem_init(rdev);
-               if (r)
-                       return 0;
-               /* 1M ring buffer */
-               r = radeon_cp_init(rdev, 1024 * 1024);
-               if (r)
-                       return 0;
-               r = radeon_wb_init(rdev);
-               if (r)
-                       DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
-               r = radeon_ib_pool_init(rdev);
-               if (r)
-                       return 0;
-               r = radeon_ib_test(rdev);
-               if (r)
-                       return 0;
-               rdev->accel_working = true;
        }
-       DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
        if (radeon_testing) {
                radeon_test_moves(rdev);
        }
@@@ -706,32 -595,8 +615,8 @@@ void radeon_device_fini(struct radeon_d
  {
        DRM_INFO("radeon: finishing device.\n");
        rdev->shutdown = true;
--      /* Order matter so becarefull if you rearrange anythings */
-       if (!rdev->new_init_path) {
-               radeon_ib_pool_fini(rdev);
-               radeon_cp_fini(rdev);
-               radeon_wb_fini(rdev);
-               radeon_gpu_gart_fini(rdev);
-               radeon_gem_fini(rdev);
-               radeon_mc_fini(rdev);
- #if __OS_HAS_AGP
-               radeon_agp_fini(rdev);
- #endif
-               radeon_irq_kms_fini(rdev);
-               vga_client_register(rdev->pdev, NULL, NULL, NULL);
-               radeon_fence_driver_fini(rdev);
-               radeon_clocks_fini(rdev);
-               radeon_object_fini(rdev);
-               if (rdev->is_atom_bios) {
-                       radeon_atombios_fini(rdev);
-               } else {
-                       radeon_combios_fini(rdev);
-               }
-               kfree(rdev->bios);
-               rdev->bios = NULL;
-       } else {
-               radeon_fini(rdev);
-       }
+       radeon_fini(rdev);
++      vga_client_register(rdev->pdev, NULL, NULL, NULL);
        iounmap(rdev->rmmio);
        rdev->rmmio = NULL;
  }
@@@ -771,14 -636,7 +656,7 @@@ int radeon_suspend_kms(struct drm_devic
  
        radeon_save_bios_scratch_regs(rdev);
  
-       if (!rdev->new_init_path) {
-               radeon_cp_disable(rdev);
-               radeon_gart_disable(rdev);
-               rdev->irq.sw_int = false;
-               radeon_irq_set(rdev);
-       } else {
-               radeon_suspend(rdev);
-       }
+       radeon_suspend(rdev);
        /* evict remaining vram memory */
        radeon_object_evict_vram(rdev);
  
  int radeon_resume_kms(struct drm_device *dev)
  {
        struct radeon_device *rdev = dev->dev_private;
-       int r;
  
        acquire_console_sem();
        pci_set_power_state(dev->pdev, PCI_D0);
                return -1;
        }
        pci_set_master(dev->pdev);
-       /* Reset gpu before posting otherwise ATOM will enter infinite loop */
-       if (!rdev->new_init_path) {
-               if (radeon_gpu_reset(rdev)) {
-                       /* FIXME: what do we want to do here ? */
-               }
-               /* post card */
-               if (rdev->is_atom_bios) {
-                       atom_asic_init(rdev->mode_info.atom_context);
-               } else {
-                       radeon_combios_asic_init(rdev->ddev);
-               }
-               /* Initialize clocks */
-               r = radeon_clocks_init(rdev);
-               if (r) {
-                       release_console_sem();
-                       return r;
-               }
-               /* Enable IRQ */
-               rdev->irq.sw_int = true;
-               radeon_irq_set(rdev);
-               /* Initialize GPU Memory Controller */
-               r = radeon_mc_init(rdev);
-               if (r) {
-                       goto out;
-               }
-               r = radeon_gart_enable(rdev);
-               if (r) {
-                       goto out;
-               }
-               r = radeon_cp_init(rdev, rdev->cp.ring_size);
-               if (r) {
-                       goto out;
-               }
-       } else {
-               radeon_resume(rdev);
-       }
- out:
+       radeon_resume(rdev);
        radeon_restore_bios_scratch_regs(rdev);
        fb_set_suspend(rdev->fbdev_info, 0);
        release_console_sem();
diff --combined include/drm/drm_pciids.h
index 3f6e545609be892f79374033d79a851372d1e2fd,923361b220f28214d30d5fb41b1c7b86bbcf3a1d..e6f3b120f51a5e4f9d51bf694b8ecba0b8d7503c
@@@ -80,7 -80,7 +80,7 @@@
        {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
        {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
        {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
-       {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+       {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_SINGLE_CRTC}, \
        {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
        {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
        {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
        {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
-       {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
+       {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_SINGLE_CRTC}, \
        {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \
        {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
        {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \
        {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
        {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
        {0x8086, 0x2e32, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
 +      {0x8086, 0x2e42, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
        {0x8086, 0xa001, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
        {0x8086, 0xa011, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \
        {0x8086, 0x35e8, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \