]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Nov 2009 19:32:04 +0000 (11:32 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Nov 2009 19:32:04 +0000 (11:32 -0800)
* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (52 commits)
  drm/kms: Init the CRTC info fields for modes forced from the command line.
  drm/radeon/r600: CS parser updates
  drm/radeon/kms: add debugfs for power management for AtomBIOS devices
  drm/radeon/kms: initial mode validation support
  drm/radeon/kms/atom/dce3: call transmitter init on mode set
  drm/radeon/kms: store detailed connector info
  drm/radeon/kms/atom/dce3: fix up usPixelClock calculation for Transmitter tables
  drm/radeon/kms/r600: fix rs880 support v2
  drm/radeon/kms/r700: fix some typos in chip init
  drm/radeon/kms: remove some misleading debugging output
  drm/radeon/kms: stop putting VRAM at 0 in MC space on r600s.
  drm/radeon/kms: disable D1VGA and D2VGA if enabled
  drm/radeon/kms: Don't RMW CP_RB_CNTL
  drm/radeon/kms: fix coherency issues on AGP cards.
  drm/radeon/kms: fix rc410 suspend/resume.
  drm/radeon/kms: add quirk for hp dc5750
  drm/radeon/kms/atom: fix potential oops in spread spectrum code
  drm/kms: typo fix
  drm/radeon/kms/atom: Make card_info per device
  drm/radeon/kms/atom: Fix DVO support
  ...

1  2 
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
drivers/gpu/drm/radeon/radeon_ttm.c

index 161094c07d9443957b8f193386e28db258244620,5e821a313a8ce81e7dd28c83a885255bb46bda79..c9e93eabcf16a7c877b9064e7fa86c2f4010cb2b
@@@ -186,7 -186,7 +186,7 @@@ static inline uint32_t r100_irq_ack(str
  
  int r100_irq_process(struct radeon_device *rdev)
  {
-       uint32_t status;
+       uint32_t status, msi_rearm;
  
        status = r100_irq_ack(rdev);
        if (!status) {
                }
                status = r100_irq_ack(rdev);
        }
+       if (rdev->msi_enabled) {
+               switch (rdev->family) {
+               case CHIP_RS400:
+               case CHIP_RS480:
+                       msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM;
+                       WREG32(RADEON_AIC_CNTL, msi_rearm);
+                       WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM);
+                       break;
+               default:
+                       msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
+                       WREG32(RADEON_MSI_REARM_EN, msi_rearm);
+                       WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
+                       break;
+               }
+       }
        return IRQ_HANDLED;
  }
  
@@@ -240,7 -255,7 +255,7 @@@ int r100_wb_init(struct radeon_device *
        int r;
  
        if (rdev->wb.wb_obj == NULL) {
-               r = radeon_object_create(rdev, NULL, 4096,
+               r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
                                         true,
                                         RADEON_GEM_DOMAIN_GTT,
                                         false, &rdev->wb.wb_obj);
@@@ -563,19 -578,19 +578,19 @@@ int r100_cp_init(struct radeon_device *
        indirect1_start = 16;
        /* cp setup */
        WREG32(0x718, pre_write_timer | (pre_write_limit << 28));
-       WREG32(RADEON_CP_RB_CNTL,
- #ifdef __BIG_ENDIAN
-              RADEON_BUF_SWAP_32BIT |
- #endif
-              REG_SET(RADEON_RB_BUFSZ, rb_bufsz) |
+       tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) |
               REG_SET(RADEON_RB_BLKSZ, rb_blksz) |
               REG_SET(RADEON_MAX_FETCH, max_fetch) |
               RADEON_RB_NO_UPDATE);
+ #ifdef __BIG_ENDIAN
+       tmp |= RADEON_BUF_SWAP_32BIT;
+ #endif
+       WREG32(RADEON_CP_RB_CNTL, tmp);
        /* Set ring address */
        DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr);
        WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr);
        /* Force read & write ptr to 0 */
-       tmp = RREG32(RADEON_CP_RB_CNTL);
        WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
        WREG32(RADEON_CP_RB_RPTR_WR, 0);
        WREG32(RADEON_CP_RB_WPTR, 0);
@@@ -1763,20 -1778,6 +1778,20 @@@ void r100_vram_init_sizes(struct radeon
                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)
  {
        r100_vram_get_type(rdev);
@@@ -2364,7 -2365,7 +2379,7 @@@ void r100_bandwidth_update(struct radeo
        /*
          Find the total latency for the display data.
        */
-       disp_latency_overhead.full = rfixed_const(80);
+       disp_latency_overhead.full = rfixed_const(8);
        disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff);
        mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full;
        mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full;
  static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
  {
        DRM_ERROR("pitch                      %d\n", t->pitch);
+       DRM_ERROR("use_pitch                  %d\n", t->use_pitch);
        DRM_ERROR("width                      %d\n", t->width);
+       DRM_ERROR("width_11                   %d\n", t->width_11);
        DRM_ERROR("height                     %d\n", t->height);
+       DRM_ERROR("height_11                  %d\n", t->height_11);
        DRM_ERROR("num levels                 %d\n", t->num_levels);
        DRM_ERROR("depth                      %d\n", t->txdepth);
        DRM_ERROR("bpp                        %d\n", t->cpp);
@@@ -2623,15 -2627,17 +2641,17 @@@ static int r100_cs_track_texture_check(
                                else
                                        w = track->textures[u].pitch / (1 << i);
                        } else {
-                               w = track->textures[u].width / (1 << i);
+                               w = track->textures[u].width;
                                if (rdev->family >= CHIP_RV515)
                                        w |= track->textures[u].width_11;
+                               w = w / (1 << i);
                                if (track->textures[u].roundup_w)
                                        w = roundup_pow_of_two(w);
                        }
-                       h = track->textures[u].height / (1 << i);
+                       h = track->textures[u].height;
                        if (rdev->family >= CHIP_RV515)
                                h |= track->textures[u].height_11;
+                       h = h / (1 << i);
                        if (track->textures[u].roundup_h)
                                h = roundup_pow_of_two(h);
                        size += w * h;
index 609719490ec28c26b064df9d43eb642954fbb442,8d6bc12192d2dd208d047e4d5aa193932ad352be..278f646bc18ef7dd0d027499f11b49d898b247fe
@@@ -339,11 -339,10 +339,10 @@@ int r600_mc_init(struct radeon_device *
  {
        fixed20_12 a;
        u32 tmp;
-       int chansize;
+       int chansize, numchan;
        int r;
  
        /* Get VRAM informations */
-       rdev->mc.vram_width = 128;
        rdev->mc.vram_is_ddr = true;
        tmp = RREG32(RAMCFG);
        if (tmp & CHANSIZE_OVERRIDE) {
        } else {
                chansize = 32;
        }
-       if (rdev->family == CHIP_R600) {
-               rdev->mc.vram_width = 8 * chansize;
-       } else if (rdev->family == CHIP_RV670) {
-               rdev->mc.vram_width = 4 * chansize;
-       } else if ((rdev->family == CHIP_RV610) ||
-                       (rdev->family == CHIP_RV620)) {
-               rdev->mc.vram_width = chansize;
-       } else if ((rdev->family == CHIP_RV630) ||
-                       (rdev->family == CHIP_RV635)) {
-               rdev->mc.vram_width = 2 * chansize;
+       tmp = RREG32(CHMAP);
+       switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
+       case 0:
+       default:
+               numchan = 1;
+               break;
+       case 1:
+               numchan = 2;
+               break;
+       case 2:
+               numchan = 4;
+               break;
+       case 3:
+               numchan = 8;
+               break;
        }
+       rdev->mc.vram_width = numchan * chansize;
        /* Could aper size report 0 ? */
        rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
        rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
                        rdev->mc.gtt_location = rdev->mc.mc_vram_size;
                }
        } else {
-               if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
-                       rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
-                                                               0xFFFF) << 24;
-                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
-                       tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
-                       if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
-                               /* Enough place after vram */
-                               rdev->mc.gtt_location = tmp;
-                       } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
-                               /* Enough place before vram */
+               rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+               rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
+                                                       0xFFFF) << 24;
+               tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+               if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
+                       /* Enough place after vram */
+                       rdev->mc.gtt_location = tmp;
+               } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
+                       /* Enough place before vram */
+                       rdev->mc.gtt_location = 0;
+               } else {
+                       /* Not enough place after or before shrink
+                        * gart size
+                        */
+                       if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
                                rdev->mc.gtt_location = 0;
+                               rdev->mc.gtt_size = rdev->mc.vram_location;
                        } else {
-                               /* Not enough place after or before shrink
-                                * gart size
-                                */
-                               if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
-                                       rdev->mc.gtt_location = 0;
-                                       rdev->mc.gtt_size = rdev->mc.vram_location;
-                               } else {
-                                       rdev->mc.gtt_location = tmp;
-                                       rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
-                               }
+                               rdev->mc.gtt_location = tmp;
+                               rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
                        }
-                       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-               } else {
-                       rdev->mc.vram_location = 0x00000000UL;
-                       rdev->mc.gtt_location = rdev->mc.mc_vram_size;
-                       rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
                }
+               rdev->mc.gtt_location = rdev->mc.mc_vram_size;
        }
        rdev->mc.vram_start = rdev->mc.vram_location;
        rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
@@@ -859,7 -858,8 +858,8 @@@ void r600_gpu_init(struct radeon_devic
            ((rdev->family) == CHIP_RV630) ||
            ((rdev->family) == CHIP_RV610) ||
            ((rdev->family) == CHIP_RV620) ||
-           ((rdev->family) == CHIP_RS780)) {
+           ((rdev->family) == CHIP_RS780) ||
+           ((rdev->family) == CHIP_RS880)) {
                WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE);
        } else {
                WREG32(DB_DEBUG, 0);
        tmp = RREG32(SQ_MS_FIFO_SIZES);
        if (((rdev->family) == CHIP_RV610) ||
            ((rdev->family) == CHIP_RV620) ||
-           ((rdev->family) == CHIP_RS780)) {
+           ((rdev->family) == CHIP_RS780) ||
+           ((rdev->family) == CHIP_RS880)) {
                tmp = (CACHE_FIFO_SIZE(0xa) |
                       FETCH_FIFO_HIWATER(0xa) |
                       DONE_FIFO_HIWATER(0xe0) |
                                            NUM_ES_STACK_ENTRIES(0));
        } else if (((rdev->family) == CHIP_RV610) ||
                   ((rdev->family) == CHIP_RV620) ||
-                  ((rdev->family) == CHIP_RS780)) {
+                  ((rdev->family) == CHIP_RS780) ||
+                  ((rdev->family) == CHIP_RS880)) {
                /* no vertex cache */
                sq_config &= ~VC_ENABLE;
  
  
        if (((rdev->family) == CHIP_RV610) ||
            ((rdev->family) == CHIP_RV620) ||
-           ((rdev->family) == CHIP_RS780)) {
+           ((rdev->family) == CHIP_RS780) ||
+           ((rdev->family) == CHIP_RS880)) {
                WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY));
        } else {
                WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC));
        tmp = rdev->config.r600.max_pipes * 16;
        switch (rdev->family) {
        case CHIP_RV610:
-       case CHIP_RS780:
        case CHIP_RV620:
+       case CHIP_RS780:
+       case CHIP_RS880:
                tmp += 32;
                break;
        case CHIP_RV670:
  
        switch (rdev->family) {
        case CHIP_RV610:
-       case CHIP_RS780:
        case CHIP_RV620:
+       case CHIP_RS780:
+       case CHIP_RS880:
                tmp = TC_L2_SIZE(8);
                break;
        case CHIP_RV630:
@@@ -1267,19 -1272,17 +1272,17 @@@ int r600_cp_resume(struct radeon_devic
  
        /* Set ring buffer size */
        rb_bufsz = drm_order(rdev->cp.ring_size / 8);
+       tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
  #ifdef __BIG_ENDIAN
-       WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE |
-               (drm_order(4096/8) << 8) | rb_bufsz);
- #else
-       WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz);
+       tmp |= BUF_SWAP_32BIT;
  #endif
+       WREG32(CP_RB_CNTL, tmp);
        WREG32(CP_SEM_WAIT_TIMER, 0x4);
  
        /* Set the write pointer delay */
        WREG32(CP_RB_WPTR_DELAY, 0);
  
        /* Initialize the ring buffer's read and write pointers */
-       tmp = RREG32(CP_RB_CNTL);
        WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
        WREG32(CP_RB_RPTR_WR, 0);
        WREG32(CP_RB_WPTR, 0);
@@@ -1400,7 -1403,7 +1403,7 @@@ int r600_wb_enable(struct radeon_devic
        int r;
  
        if (rdev->wb.wb_obj == NULL) {
-               r = radeon_object_create(rdev, NULL, 4096, true,
+               r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
                                RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
                if (r) {
                        dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
@@@ -1450,8 -1453,8 +1453,8 @@@ int r600_copy_blit(struct radeon_devic
                   uint64_t src_offset, uint64_t dst_offset,
                   unsigned num_pages, struct radeon_fence *fence)
  {
-       r600_blit_prepare_copy(rdev, num_pages * 4096);
-       r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096);
+       r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
+       r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
        r600_blit_done_copy(rdev, fence);
        return 0;
  }
@@@ -1534,20 -1537,6 +1537,20 @@@ int r600_startup(struct radeon_device *
        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;
@@@ -1632,10 -1621,13 +1635,13 @@@ int r600_init(struct radeon_device *rde
        r600_scratch_init(rdev);
        /* Initialize surface registers */
        radeon_surface_init(rdev);
+       /* Initialize clocks */
        radeon_get_clock_info(rdev->ddev);
        r = radeon_clocks_init(rdev);
        if (r)
                return r;
+       /* Initialize power management */
+       radeon_pm_init(rdev);
        /* Fence driver */
        r = radeon_fence_driver_init(rdev);
        if (r)
index 9b64d47f1f82ff4116f0c8b25872730843f92c0a,b99f45d85d8855226bb8b7f5d8f850ff9431d8d6..27ab428b149bbccc6c077e6a648c991ebaddcd2a
@@@ -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       DB_DEBUG                                        0x9830
  #define               PREZ_MUST_WAIT_FOR_POSTZ_DONE                   (1 << 31)
  #define       DB_DEPTH_BASE                                   0x2800C
+ #define       DB_HTILE_DATA_BASE                              0x28014
  #define       DB_WATERMARKS                                   0x9838
  #define               DEPTH_FREE(x)                                   ((x) << 0)
  #define               DEPTH_FLUSH(x)                                  ((x) << 5)
  #define SQ_STACK_RESOURCE_MGMT_2                          0x8c14
  #       define NUM_GS_STACK_ENTRIES(x)                    ((x) << 0)
  #       define NUM_ES_STACK_ENTRIES(x)                    ((x) << 16)
+ #define SQ_ESGS_RING_BASE                               0x8c40
+ #define SQ_GSVS_RING_BASE                               0x8c48
+ #define SQ_ESTMP_RING_BASE                              0x8c50
+ #define SQ_GSTMP_RING_BASE                              0x8c58
+ #define SQ_VSTMP_RING_BASE                              0x8c60
+ #define SQ_PSTMP_RING_BASE                              0x8c68
+ #define SQ_FBUF_RING_BASE                               0x8c70
+ #define SQ_REDUC_RING_BASE                              0x8c78
  
  #define GRBM_CNTL                                       0x8000
  #       define GRBM_READ_TIMEOUT(x)                     ((x) << 0)
  #define       PCIE_PORT_INDEX                                 0x0038
  #define       PCIE_PORT_DATA                                  0x003C
  
+ #define CHMAP                                         0x2004
+ #define               NOOFCHAN_SHIFT                                  12
+ #define               NOOFCHAN_MASK                                   0x00003000
  #define RAMCFG                                                0x2408
  #define               NOOFBANK_SHIFT                                  0
  #define               NOOFBANK_MASK                                   0x00000001
  
  
  #define       SX_MISC                                         0x28350
+ #define       SX_MEMORY_EXPORT_BASE                           0x9010
  #define       SX_DEBUG_1                                      0x9054
  #define               SMX_EVENT_RELEASE                               (1 << 0)
  #define               ENABLE_NEW_SMX_ADDRESS                          (1 << 16)
index 5ab35b81c86bfdeedf71ec6ff2b03e114bcfb4ec,9f0bd98478847956e03cda881c2bdaecfc8f9906..757f5cd37744cc40163338a121c7ae2b4abc6467
@@@ -139,6 -139,10 +139,10 @@@ struct radeon_clock 
        uint32_t default_sclk;
  };
  
+ /*
+  * Power management
+  */
+ int radeon_pm_init(struct radeon_device *rdev);
  
  /*
   * Fences.
@@@ -276,6 -280,8 +280,8 @@@ union radeon_gart_table 
        struct radeon_gart_table_vram   vram;
  };
  
+ #define RADEON_GPU_PAGE_SIZE 4096
  struct radeon_gart {
        dma_addr_t                      table_addr;
        unsigned                        num_gpu_pages;
@@@ -590,7 -596,6 +596,7 @@@ struct radeon_asic 
        void (*fini)(struct radeon_device *rdev);
        int (*resume)(struct radeon_device *rdev);
        int (*suspend)(struct radeon_device *rdev);
 +      void (*vga_set_state)(struct radeon_device *rdev, bool state);
        int (*gpu_reset)(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);
                    uint64_t dst_offset,
                    unsigned num_pages,
                    struct radeon_fence *fence);
+       uint32_t (*get_engine_clock)(struct radeon_device *rdev);
        void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock);
+       uint32_t (*get_memory_clock)(struct radeon_device *rdev);
        void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock);
        void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
        void (*set_clock_gating)(struct radeon_device *rdev, int enable);
@@@ -783,6 -790,7 +791,7 @@@ struct radeon_device 
        const struct firmware *me_fw;   /* all family ME firmware */
        const struct firmware *pfp_fw;  /* r6/700 PFP firmware */
        struct r600_blit r600_blit;
+       int msi_enabled; /* msi enabled */
  };
  
  int radeon_device_init(struct radeon_device *rdev,
@@@ -937,7 -945,6 +946,7 @@@ 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_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
  #define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((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_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f))
  #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f))
  #define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f))
+ #define radeon_get_engine_clock(rdev) (rdev)->asic->get_engine_clock((rdev))
  #define radeon_set_engine_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
+ #define radeon_get_memory_clock(rdev) (rdev)->asic->get_memory_clock((rdev))
  #define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
  #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
  #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
index c3532c7a6f3f04f74d26d6ef97ece8fea7da053e,94991edc839f274379f8717080b683bc571ea871..c18fbee387d7c1efb0e6c905fc7550b4a907c45a
  /*
   * common functions
   */
+ uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev);
  void radeon_legacy_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock);
  void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
  
+ uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev);
  void radeon_atom_set_engine_clock(struct radeon_device *rdev, uint32_t eng_clock);
+ uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev);
  void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock);
  void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
  
@@@ -47,7 -50,6 +50,7 @@@ extern int r100_suspend(struct radeon_d
  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_vga_set_state(struct radeon_device *rdev, bool state);
  int r100_gpu_reset(struct radeon_device *rdev);
  u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
  void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
@@@ -79,7 -81,6 +82,7 @@@ static struct radeon_asic r100_asic = 
        .fini = &r100_fini,
        .suspend = &r100_suspend,
        .resume = &r100_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r100_gpu_reset,
        .gart_tlb_flush = &r100_pci_gart_tlb_flush,
        .gart_set_page = &r100_pci_gart_set_page,
@@@ -95,7 -96,9 +98,9 @@@
        .copy_blit = &r100_copy_blit,
        .copy_dma = NULL,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_legacy_get_engine_clock,
        .set_engine_clock = &radeon_legacy_set_engine_clock,
+       .get_memory_clock = NULL,
        .set_memory_clock = NULL,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_legacy_set_clock_gating,
@@@ -132,7 -135,6 +137,7 @@@ static struct radeon_asic r300_asic = 
        .fini = &r300_fini,
        .suspend = &r300_suspend,
        .resume = &r300_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
        .gart_tlb_flush = &r100_pci_gart_tlb_flush,
        .gart_set_page = &r100_pci_gart_set_page,
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_legacy_get_engine_clock,
        .set_engine_clock = &radeon_legacy_set_engine_clock,
+       .get_memory_clock = NULL,
        .set_memory_clock = NULL,
        .set_pcie_lanes = &rv370_set_pcie_lanes,
        .set_clock_gating = &radeon_legacy_set_clock_gating,
@@@ -169,7 -173,6 +176,7 @@@ static struct radeon_asic r420_asic = 
        .fini = &r420_fini,
        .suspend = &r420_suspend,
        .resume = &r420_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = &rv370_set_pcie_lanes,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@@ -211,7 -216,6 +220,7 @@@ static struct radeon_asic rs400_asic = 
        .fini = &rs400_fini,
        .suspend = &rs400_suspend,
        .resume = &rs400_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
        .gart_tlb_flush = &rs400_gart_tlb_flush,
        .gart_set_page = &rs400_gart_set_page,
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_legacy_get_engine_clock,
        .set_engine_clock = &radeon_legacy_set_engine_clock,
+       .get_memory_clock = NULL,
        .set_memory_clock = NULL,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_legacy_set_clock_gating,
@@@ -257,7 -263,6 +268,7 @@@ static struct radeon_asic rs600_asic = 
        .fini = &rs600_fini,
        .suspend = &rs600_suspend,
        .resume = &rs600_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
        .gart_tlb_flush = &rs600_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@@ -296,7 -303,6 +309,7 @@@ static struct radeon_asic rs690_asic = 
        .fini = &rs690_fini,
        .suspend = &rs690_suspend,
        .resume = &rs690_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &r300_gpu_reset,
        .gart_tlb_flush = &rs400_gart_tlb_flush,
        .gart_set_page = &rs400_gart_set_page,
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r300_copy_dma,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@@ -341,7 -349,6 +356,7 @@@ static struct radeon_asic rv515_asic = 
        .fini = &rv515_fini,
        .suspend = &rv515_suspend,
        .resume = &rv515_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &rv515_gpu_reset,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = &rv370_set_pcie_lanes,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@@ -377,7 -386,6 +394,7 @@@ static struct radeon_asic r520_asic = 
        .fini = &rv515_fini,
        .suspend = &rv515_suspend,
        .resume = &r520_resume,
 +      .vga_set_state = &r100_vga_set_state,
        .gpu_reset = &rv515_gpu_reset,
        .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
        .gart_set_page = &rv370_pcie_gart_set_page,
        .copy_blit = &r100_copy_blit,
        .copy_dma = &r300_copy_dma,
        .copy = &r100_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = &rv370_set_pcie_lanes,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@@ -409,7 -419,6 +428,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);
@@@ -443,7 -452,6 +462,7 @@@ static struct radeon_asic r600_asic = 
        .suspend = &r600_suspend,
        .resume = &r600_resume,
        .cp_commit = &r600_cp_commit,
 +      .vga_set_state = &r600_vga_set_state,
        .gpu_reset = &r600_gpu_reset,
        .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
        .copy_blit = &r600_copy_blit,
        .copy_dma = &r600_copy_blit,
        .copy = &r600_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
@@@ -481,7 -491,6 +502,7 @@@ static struct radeon_asic rv770_asic = 
        .resume = &rv770_resume,
        .cp_commit = &r600_cp_commit,
        .gpu_reset = &rv770_gpu_reset,
 +      .vga_set_state = &r600_vga_set_state,
        .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
        .gart_set_page = &rs600_gart_set_page,
        .ring_test = &r600_ring_test,
        .copy_blit = &r600_copy_blit,
        .copy_dma = &r600_copy_blit,
        .copy = &r600_copy_blit,
+       .get_engine_clock = &radeon_atom_get_engine_clock,
        .set_engine_clock = &radeon_atom_set_engine_clock,
+       .get_memory_clock = &radeon_atom_get_memory_clock,
        .set_memory_clock = &radeon_atom_set_memory_clock,
        .set_pcie_lanes = NULL,
        .set_clock_gating = &radeon_atom_set_clock_gating,
index df988142e6b0f8fc01d981859fc07dd71d2f27d2,88c19070247f5ebbc56fbfa9482bea0631e37bdf..e3f9edfa40fe8a5d63b64eee70e91345c4a1bd7b
@@@ -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"
@@@ -444,20 -443,24 +444,24 @@@ static uint32_t cail_reg_read(struct ca
        return r;
  }
  
- static struct card_info atom_card_info = {
-       .dev = NULL,
-       .reg_read = cail_reg_read,
-       .reg_write = cail_reg_write,
-       .mc_read = cail_mc_read,
-       .mc_write = cail_mc_write,
-       .pll_read = cail_pll_read,
-       .pll_write = cail_pll_write,
- };
  int radeon_atombios_init(struct radeon_device *rdev)
  {
-       atom_card_info.dev = rdev->ddev;
-       rdev->mode_info.atom_context = atom_parse(&atom_card_info, rdev->bios);
+       struct card_info *atom_card_info =
+           kzalloc(sizeof(struct card_info), GFP_KERNEL);
+       if (!atom_card_info)
+               return -ENOMEM;
+       rdev->mode_info.atom_card_info = atom_card_info;
+       atom_card_info->dev = rdev->ddev;
+       atom_card_info->reg_read = cail_reg_read;
+       atom_card_info->reg_write = cail_reg_write;
+       atom_card_info->mc_read = cail_mc_read;
+       atom_card_info->mc_write = cail_mc_write;
+       atom_card_info->pll_read = cail_pll_read;
+       atom_card_info->pll_write = cail_pll_write;
+       rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
        radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
        return 0;
  }
  void radeon_atombios_fini(struct radeon_device *rdev)
  {
        kfree(rdev->mode_info.atom_context);
+       kfree(rdev->mode_info.atom_card_info);
  }
  
  int radeon_combios_init(struct radeon_device *rdev)
@@@ -477,18 -481,6 +482,18 @@@ 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;
@@@ -581,15 -573,9 +586,15 @@@ int radeon_device_init(struct radeon_de
        DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
        DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
  
 +      /* if we have > 1 VGA cards, then disable the radeon VGA resources */
 +      /* this will fail for cards that aren't VGA class devices, just
 +       * ignore it */
 +      vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
 +
        r = radeon_init(rdev);
        if (r)
                return r;
 +
        if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
                /* Acceleration not working on AGP card try again
                 * with fallback to PCI or PCIE GART
@@@ -614,8 -600,8 +619,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 */
        radeon_fini(rdev);
 +      vga_client_register(rdev->pdev, NULL, NULL, NULL);
        iounmap(rdev->rmmio);
        rdev->rmmio = NULL;
  }
index 765bd184b6fc15382fc10b2dfaadd91414709054,f489c0de6f1330ed3596f1d06d8a99461f1f483e..1381e06d6af3ff317521aba0952ab5b2e1a397a9
@@@ -295,6 -295,12 +295,12 @@@ static int radeon_move_vram_ram(struct 
        if (unlikely(r)) {
                return r;
        }
+       r = ttm_tt_set_placement_caching(bo->ttm, tmp_mem.placement);
+       if (unlikely(r)) {
+               goto out_cleanup;
+       }
        r = ttm_tt_bind(bo->ttm, &tmp_mem);
        if (unlikely(r)) {
                goto out_cleanup;
@@@ -530,7 -536,7 +536,7 @@@ void radeon_ttm_fini(struct radeon_devi
  }
  
  static struct vm_operations_struct radeon_ttm_vm_ops;
 -static struct vm_operations_struct *ttm_vm_ops = NULL;
 +static const struct vm_operations_struct *ttm_vm_ops = NULL;
  
  static int radeon_ttm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
  {