]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/radeon/evergreen.c
drm/radeon: separate UVD code v3
[~andy/linux] / drivers / gpu / drm / radeon / evergreen.c
index d5b49e33315e299aa4b2a2085d0fdd3d1c8a99bc..52ed22333f0d94c1946f176fc0f36995c3cbb244 100644 (file)
@@ -47,7 +47,7 @@ static const u32 crtc_offsets[6] =
 
 #include "clearstate_evergreen.h"
 
-static u32 sumo_rlc_save_restore_register_list[] =
+static const u32 sumo_rlc_save_restore_register_list[] =
 {
        0x98fc,
        0x9830,
@@ -131,7 +131,6 @@ static u32 sumo_rlc_save_restore_register_list[] =
        0x9150,
        0x802c,
 };
-static u32 sumo_rlc_save_restore_register_list_size = ARRAY_SIZE(sumo_rlc_save_restore_register_list);
 
 static void evergreen_gpu_init(struct radeon_device *rdev);
 void evergreen_fini(struct radeon_device *rdev);
@@ -141,6 +140,7 @@ extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
                                     int ring, u32 cp_int_cntl);
 extern void cayman_vm_decode_fault(struct radeon_device *rdev,
                                   u32 status, u32 addr);
+void cik_init_cp_pg_table(struct radeon_device *rdev);
 
 static const u32 evergreen_golden_registers[] =
 {
@@ -3894,147 +3894,212 @@ void sumo_rlc_fini(struct radeon_device *rdev)
                radeon_bo_unref(&rdev->rlc.clear_state_obj);
                rdev->rlc.clear_state_obj = NULL;
        }
+
+       /* clear state block */
+       if (rdev->rlc.cp_table_obj) {
+               r = radeon_bo_reserve(rdev->rlc.cp_table_obj, false);
+               if (unlikely(r != 0))
+                       dev_warn(rdev->dev, "(%d) reserve RLC cp table bo failed\n", r);
+               radeon_bo_unpin(rdev->rlc.cp_table_obj);
+               radeon_bo_unreserve(rdev->rlc.cp_table_obj);
+
+               radeon_bo_unref(&rdev->rlc.cp_table_obj);
+               rdev->rlc.cp_table_obj = NULL;
+       }
 }
 
+#define CP_ME_TABLE_SIZE    96
+
 int sumo_rlc_init(struct radeon_device *rdev)
 {
-       u32 *src_ptr;
+       const u32 *src_ptr;
        volatile u32 *dst_ptr;
        u32 dws, data, i, j, k, reg_num;
        u32 reg_list_num, reg_list_hdr_blk_index, reg_list_blk_index;
        u64 reg_list_mc_addr;
-       struct cs_section_def *cs_data;
+       const struct cs_section_def *cs_data;
        int r;
 
        src_ptr = rdev->rlc.reg_list;
        dws = rdev->rlc.reg_list_size;
        cs_data = rdev->rlc.cs_data;
 
-       /* save restore block */
-       if (rdev->rlc.save_restore_obj == NULL) {
-               r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
-                                    RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.save_restore_obj);
+       if (src_ptr) {
+               /* save restore block */
+               if (rdev->rlc.save_restore_obj == NULL) {
+                       r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
+                                            RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.save_restore_obj);
+                       if (r) {
+                               dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
+                               return r;
+                       }
+               }
+
+               r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
+               if (unlikely(r != 0)) {
+                       sumo_rlc_fini(rdev);
+                       return r;
+               }
+               r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
+                                 &rdev->rlc.save_restore_gpu_addr);
                if (r) {
-                       dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
+                       radeon_bo_unreserve(rdev->rlc.save_restore_obj);
+                       dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
+                       sumo_rlc_fini(rdev);
                        return r;
                }
-       }
 
-       r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
-       if (unlikely(r != 0)) {
-               sumo_rlc_fini(rdev);
-               return r;
-       }
-       r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
-                         &rdev->rlc.save_restore_gpu_addr);
-       if (r) {
+               r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr);
+               if (r) {
+                       dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r);
+                       sumo_rlc_fini(rdev);
+                       return r;
+               }
+               /* write the sr buffer */
+               dst_ptr = rdev->rlc.sr_ptr;
+               if (rdev->family >= CHIP_TAHITI) {
+                       /* SI */
+                       for (i = 0; i < dws; i++)
+                               dst_ptr[i] = src_ptr[i];
+               } else {
+                       /* ON/LN/TN */
+                       /* format:
+                        * dw0: (reg2 << 16) | reg1
+                        * dw1: reg1 save space
+                        * dw2: reg2 save space
+                        */
+                       for (i = 0; i < dws; i++) {
+                               data = src_ptr[i] >> 2;
+                               i++;
+                               if (i < dws)
+                                       data |= (src_ptr[i] >> 2) << 16;
+                               j = (((i - 1) * 3) / 2);
+                               dst_ptr[j] = data;
+                       }
+                       j = ((i * 3) / 2);
+                       dst_ptr[j] = RLC_SAVE_RESTORE_LIST_END_MARKER;
+               }
+               radeon_bo_kunmap(rdev->rlc.save_restore_obj);
                radeon_bo_unreserve(rdev->rlc.save_restore_obj);
-               dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
-               sumo_rlc_fini(rdev);
-               return r;
-       }
-       r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr);
-       if (r) {
-               dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r);
-               sumo_rlc_fini(rdev);
-               return r;
-       }
-       /* write the sr buffer */
-       dst_ptr = rdev->rlc.sr_ptr;
-       /* format:
-        * dw0: (reg2 << 16) | reg1
-        * dw1: reg1 save space
-        * dw2: reg2 save space
-        */
-       for (i = 0; i < dws; i++) {
-               data = src_ptr[i] >> 2;
-               i++;
-               if (i < dws)
-                       data |= (src_ptr[i] >> 2) << 16;
-               j = (((i - 1) * 3) / 2);
-               dst_ptr[j] = data;
        }
-       j = ((i * 3) / 2);
-       dst_ptr[j] = RLC_SAVE_RESTORE_LIST_END_MARKER;
 
-       radeon_bo_kunmap(rdev->rlc.save_restore_obj);
-       radeon_bo_unreserve(rdev->rlc.save_restore_obj);
+       if (cs_data) {
+               /* clear state block */
+               reg_list_num = 0;
+               dws = 0;
+               for (i = 0; cs_data[i].section != NULL; i++) {
+                       for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
+                               reg_list_num++;
+                               dws += cs_data[i].section[j].reg_count;
+                       }
+               }
+               reg_list_blk_index = (3 * reg_list_num + 2);
+               dws += reg_list_blk_index;
+               rdev->rlc.clear_state_size = dws;
 
-       /* clear state block */
-       reg_list_num = 0;
-       dws = 0;
-       for (i = 0; cs_data[i].section != NULL; i++) {
-               for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
-                       reg_list_num++;
-                       dws += cs_data[i].section[j].reg_count;
+               if (rdev->rlc.clear_state_obj == NULL) {
+                       r = radeon_bo_create(rdev, rdev->rlc.clear_state_size * 4, PAGE_SIZE, true,
+                                            RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.clear_state_obj);
+                       if (r) {
+                               dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
+                               sumo_rlc_fini(rdev);
+                               return r;
+                       }
+               }
+               r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
+               if (unlikely(r != 0)) {
+                       sumo_rlc_fini(rdev);
+                       return r;
+               }
+               r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
+                                 &rdev->rlc.clear_state_gpu_addr);
+               if (r) {
+                       radeon_bo_unreserve(rdev->rlc.clear_state_obj);
+                       dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
+                       sumo_rlc_fini(rdev);
+                       return r;
                }
-       }
-       reg_list_blk_index = (3 * reg_list_num + 2);
-       dws += reg_list_blk_index;
 
-       if (rdev->rlc.clear_state_obj == NULL) {
-               r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
-                                    RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.clear_state_obj);
+               r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr);
                if (r) {
-                       dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
+                       dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r);
                        sumo_rlc_fini(rdev);
                        return r;
                }
-       }
-       r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
-       if (unlikely(r != 0)) {
-               sumo_rlc_fini(rdev);
-               return r;
-       }
-       r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
-                         &rdev->rlc.clear_state_gpu_addr);
-       if (r) {
+               /* set up the cs buffer */
+               dst_ptr = rdev->rlc.cs_ptr;
+               reg_list_hdr_blk_index = 0;
+               reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
+               data = upper_32_bits(reg_list_mc_addr);
+               dst_ptr[reg_list_hdr_blk_index] = data;
+               reg_list_hdr_blk_index++;
+               for (i = 0; cs_data[i].section != NULL; i++) {
+                       for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
+                               reg_num = cs_data[i].section[j].reg_count;
+                               data = reg_list_mc_addr & 0xffffffff;
+                               dst_ptr[reg_list_hdr_blk_index] = data;
+                               reg_list_hdr_blk_index++;
+
+                               data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
+                               dst_ptr[reg_list_hdr_blk_index] = data;
+                               reg_list_hdr_blk_index++;
+
+                               data = 0x08000000 | (reg_num * 4);
+                               dst_ptr[reg_list_hdr_blk_index] = data;
+                               reg_list_hdr_blk_index++;
+
+                               for (k = 0; k < reg_num; k++) {
+                                       data = cs_data[i].section[j].extent[k];
+                                       dst_ptr[reg_list_blk_index + k] = data;
+                               }
+                               reg_list_mc_addr += reg_num * 4;
+                               reg_list_blk_index += reg_num;
+                       }
+               }
+               dst_ptr[reg_list_hdr_blk_index] = RLC_CLEAR_STATE_END_MARKER;
 
+               radeon_bo_kunmap(rdev->rlc.clear_state_obj);
                radeon_bo_unreserve(rdev->rlc.clear_state_obj);
-               dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
-               sumo_rlc_fini(rdev);
-               return r;
-       }
-       r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr);
-       if (r) {
-               dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r);
-               sumo_rlc_fini(rdev);
-               return r;
        }
-       /* set up the cs buffer */
-       dst_ptr = rdev->rlc.cs_ptr;
-       reg_list_hdr_blk_index = 0;
-       reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
-       data = upper_32_bits(reg_list_mc_addr);
-       dst_ptr[reg_list_hdr_blk_index] = data;
-       reg_list_hdr_blk_index++;
-       for (i = 0; cs_data[i].section != NULL; i++) {
-               for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
-                       reg_num = cs_data[i].section[j].reg_count;
-                       data = reg_list_mc_addr & 0xffffffff;
-                       dst_ptr[reg_list_hdr_blk_index] = data;
-                       reg_list_hdr_blk_index++;
-
-                       data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
-                       dst_ptr[reg_list_hdr_blk_index] = data;
-                       reg_list_hdr_blk_index++;
-
-                       data = 0x08000000 | (reg_num * 4);
-                       dst_ptr[reg_list_hdr_blk_index] = data;
-                       reg_list_hdr_blk_index++;
-
-                       for (k = 0; k < reg_num; k++) {
-                               data = cs_data[i].section[j].extent[k];
-                               dst_ptr[reg_list_blk_index + k] = data;
+
+       if (rdev->rlc.cp_table_size) {
+               if (rdev->rlc.cp_table_obj == NULL) {
+                       r = radeon_bo_create(rdev, rdev->rlc.cp_table_size, PAGE_SIZE, true,
+                                            RADEON_GEM_DOMAIN_VRAM, NULL, &rdev->rlc.cp_table_obj);
+                       if (r) {
+                               dev_warn(rdev->dev, "(%d) create RLC cp table bo failed\n", r);
+                               sumo_rlc_fini(rdev);
+                               return r;
                        }
-                       reg_list_mc_addr += reg_num * 4;
-                       reg_list_blk_index += reg_num;
                }
-       }
-       dst_ptr[reg_list_hdr_blk_index] = RLC_CLEAR_STATE_END_MARKER;
 
-       radeon_bo_kunmap(rdev->rlc.clear_state_obj);
-       radeon_bo_unreserve(rdev->rlc.clear_state_obj);
+               r = radeon_bo_reserve(rdev->rlc.cp_table_obj, false);
+               if (unlikely(r != 0)) {
+                       dev_warn(rdev->dev, "(%d) reserve RLC cp table bo failed\n", r);
+                       sumo_rlc_fini(rdev);
+                       return r;
+               }
+               r = radeon_bo_pin(rdev->rlc.cp_table_obj, RADEON_GEM_DOMAIN_VRAM,
+                                 &rdev->rlc.cp_table_gpu_addr);
+               if (r) {
+                       radeon_bo_unreserve(rdev->rlc.cp_table_obj);
+                       dev_warn(rdev->dev, "(%d) pin RLC cp_table bo failed\n", r);
+                       sumo_rlc_fini(rdev);
+                       return r;
+               }
+               r = radeon_bo_kmap(rdev->rlc.cp_table_obj, (void **)&rdev->rlc.cp_table_ptr);
+               if (r) {
+                       dev_warn(rdev->dev, "(%d) map RLC cp table bo failed\n", r);
+                       sumo_rlc_fini(rdev);
+                       return r;
+               }
+
+               cik_init_cp_pg_table(rdev);
+
+               radeon_bo_kunmap(rdev->rlc.cp_table_obj);
+               radeon_bo_unreserve(rdev->rlc.cp_table_obj);
+
+       }
 
        return 0;
 }
@@ -5144,17 +5209,11 @@ static int evergreen_startup(struct radeon_device *rdev)
        }
        evergreen_gpu_init(rdev);
 
-       r = evergreen_blit_init(rdev);
-       if (r) {
-               r600_blit_fini(rdev);
-               rdev->asic->copy.copy = NULL;
-               dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
-       }
-
        /* allocate rlc buffers */
        if (rdev->flags & RADEON_IS_IGP) {
                rdev->rlc.reg_list = sumo_rlc_save_restore_register_list;
-               rdev->rlc.reg_list_size = sumo_rlc_save_restore_register_list_size;
+               rdev->rlc.reg_list_size =
+                       (u32)ARRAY_SIZE(sumo_rlc_save_restore_register_list);
                rdev->rlc.cs_data = evergreen_cs_data;
                r = sumo_rlc_init(rdev);
                if (r) {
@@ -5180,7 +5239,7 @@ static int evergreen_startup(struct radeon_device *rdev)
                return r;
        }
 
-       r = rv770_uvd_resume(rdev);
+       r = uvd_v2_2_resume(rdev);
        if (!r) {
                r = radeon_fence_driver_start_ring(rdev,
                                                   R600_RING_TYPE_UVD_INDEX);
@@ -5209,14 +5268,14 @@ static int evergreen_startup(struct radeon_device *rdev)
        ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
                             R600_CP_RB_RPTR, R600_CP_RB_WPTR,
-                            0, 0xfffff, RADEON_CP_PACKET2);
+                            RADEON_CP_PACKET2);
        if (r)
                return r;
 
        ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
        r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
                             DMA_RB_RPTR, DMA_RB_WPTR,
-                            2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0));
+                            DMA_PACKET(DMA_PACKET_NOP, 0, 0));
        if (r)
                return r;
 
@@ -5232,12 +5291,11 @@ static int evergreen_startup(struct radeon_device *rdev)
 
        ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
        if (ring->ring_size) {
-               r = radeon_ring_init(rdev, ring, ring->ring_size,
-                                    R600_WB_UVD_RPTR_OFFSET,
+               r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
                                     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
-                                    0, 0xfffff, RADEON_CP_PACKET2);
+                                    RADEON_CP_PACKET2);
                if (!r)
-                       r = r600_uvd_init(rdev);
+                       r = uvd_v1_0_init(rdev);
 
                if (r)
                        DRM_ERROR("radeon: error initializing UVD (%d).\n", r);
@@ -5292,7 +5350,7 @@ int evergreen_resume(struct radeon_device *rdev)
 int evergreen_suspend(struct radeon_device *rdev)
 {
        r600_audio_fini(rdev);
-       r600_uvd_stop(rdev);
+       uvd_v1_0_fini(rdev);
        radeon_uvd_suspend(rdev);
        r700_cp_stop(rdev);
        r600_dma_stop(rdev);
@@ -5420,7 +5478,6 @@ int evergreen_init(struct radeon_device *rdev)
 void evergreen_fini(struct radeon_device *rdev)
 {
        r600_audio_fini(rdev);
-       r600_blit_fini(rdev);
        r700_cp_fini(rdev);
        r600_dma_fini(rdev);
        r600_irq_fini(rdev);
@@ -5430,7 +5487,7 @@ void evergreen_fini(struct radeon_device *rdev)
        radeon_ib_pool_fini(rdev);
        radeon_irq_kms_fini(rdev);
        evergreen_pcie_gart_fini(rdev);
-       r600_uvd_stop(rdev);
+       uvd_v1_0_fini(rdev);
        radeon_uvd_fini(rdev);
        r600_vram_scratch_fini(rdev);
        radeon_gem_fini(rdev);