]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/gpu/drm/radeon/r600_blit_kms.c
drm/radeon: disable compute rings on cayman for now
[mv-sheeva.git] / drivers / gpu / drm / radeon / r600_blit_kms.c
index 3940be619af7df05a80342a27bdb392c87fb64c2..62dd1c281c76b456f87974d5ee934ebed99b5f5b 100644 (file)
 
 #define RECT_UNIT_H           32
 #define RECT_UNIT_W           (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
-#define MAX_RECT_DIM          8192
 
 /* emits 21 on rv770+, 23 on r600 */
 static void
 set_render_target(struct radeon_device *rdev, int format,
                  int w, int h, u64 gpu_addr)
 {
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
        u32 cb_color_info;
        int pitch, slice;
 
@@ -58,42 +58,44 @@ set_render_target(struct radeon_device *rdev, int format,
        if (h < 8)
                h = 8;
 
-       cb_color_info = ((format << 2) | (1 << 27) | (1 << 8));
+       cb_color_info = CB_FORMAT(format) |
+               CB_SOURCE_FORMAT(CB_SF_EXPORT_NORM) |
+               CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
        pitch = (w / 8) - 1;
        slice = ((w * h) / 64) - 1;
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, gpu_addr >> 8);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, gpu_addr >> 8);
 
        if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) {
-               radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0));
-               radeon_ring_write(rdev, 2 << 0);
+               radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0));
+               radeon_ring_write(cp, 2 << 0);
        }
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, (pitch << 0) | (slice << 10));
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, (pitch << 0) | (slice << 10));
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, 0);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, 0);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, cb_color_info);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, cb_color_info);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, 0);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, 0);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, 0);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, 0);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, 0);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, 0);
 }
 
 /* emits 5dw */
@@ -102,6 +104,7 @@ cp_set_surface_sync(struct radeon_device *rdev,
                    u32 sync_type, u32 size,
                    u64 mc_addr)
 {
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
        u32 cp_coher_size;
 
        if (size == 0xffffffff)
@@ -109,17 +112,18 @@ cp_set_surface_sync(struct radeon_device *rdev,
        else
                cp_coher_size = ((size + 255) >> 8);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
-       radeon_ring_write(rdev, sync_type);
-       radeon_ring_write(rdev, cp_coher_size);
-       radeon_ring_write(rdev, mc_addr >> 8);
-       radeon_ring_write(rdev, 10); /* poll interval */
+       radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3));
+       radeon_ring_write(cp, sync_type);
+       radeon_ring_write(cp, cp_coher_size);
+       radeon_ring_write(cp, mc_addr >> 8);
+       radeon_ring_write(cp, 10); /* poll interval */
 }
 
 /* emits 21dw + 1 surface sync = 26dw */
 static void
 set_shaders(struct radeon_device *rdev)
 {
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
        u64 gpu_addr;
        u32 sq_pgm_resources;
 
@@ -128,35 +132,35 @@ set_shaders(struct radeon_device *rdev)
 
        /* VS */
        gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset;
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, gpu_addr >> 8);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, gpu_addr >> 8);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, sq_pgm_resources);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, sq_pgm_resources);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, 0);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, 0);
 
        /* PS */
        gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset;
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, gpu_addr >> 8);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, gpu_addr >> 8);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, sq_pgm_resources | (1 << 28));
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, sq_pgm_resources | (1 << 28));
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, 2);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, 2);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
-       radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, 0);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+       radeon_ring_write(cp, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, 0);
 
        gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset;
        cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr);
@@ -166,22 +170,24 @@ set_shaders(struct radeon_device *rdev)
 static void
 set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
 {
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
        u32 sq_vtx_constant_word2;
 
-       sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8));
+       sq_vtx_constant_word2 = SQ_VTXC_BASE_ADDR_HI(upper_32_bits(gpu_addr) & 0xff) |
+               SQ_VTXC_STRIDE(16);
 #ifdef __BIG_ENDIAN
-       sq_vtx_constant_word2 |= (2 << 30);
+       sq_vtx_constant_word2 |=  SQ_VTXC_ENDIAN_SWAP(SQ_ENDIAN_8IN32);
 #endif
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
-       radeon_ring_write(rdev, 0x460);
-       radeon_ring_write(rdev, gpu_addr & 0xffffffff);
-       radeon_ring_write(rdev, 48 - 1);
-       radeon_ring_write(rdev, sq_vtx_constant_word2);
-       radeon_ring_write(rdev, 1 << 0);
-       radeon_ring_write(rdev, 0);
-       radeon_ring_write(rdev, 0);
-       radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 7));
+       radeon_ring_write(cp, 0x460);
+       radeon_ring_write(cp, gpu_addr & 0xffffffff);
+       radeon_ring_write(cp, 48 - 1);
+       radeon_ring_write(cp, sq_vtx_constant_word2);
+       radeon_ring_write(cp, 1 << 0);
+       radeon_ring_write(cp, 0);
+       radeon_ring_write(cp, 0);
+       radeon_ring_write(cp, SQ_TEX_VTX_VALID_BUFFER << 30);
 
        if ((rdev->family == CHIP_RV610) ||
            (rdev->family == CHIP_RV620) ||
@@ -199,35 +205,40 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
 static void
 set_tex_resource(struct radeon_device *rdev,
                 int format, int w, int h, int pitch,
-                u64 gpu_addr)
+                u64 gpu_addr, u32 size)
 {
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
        uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;
 
        if (h < 1)
                h = 1;
 
-       sq_tex_resource_word0 = (1 << 0) | (1 << 3);
-       sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
-                                 ((w - 1) << 19));
-
-       sq_tex_resource_word1 = (format << 26);
-       sq_tex_resource_word1 |= ((h - 1) << 0);
-
-       sq_tex_resource_word4 = ((1 << 14) |
-                                (0 << 16) |
-                                (1 << 19) |
-                                (2 << 22) |
-                                (3 << 25));
-
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
-       radeon_ring_write(rdev, 0);
-       radeon_ring_write(rdev, sq_tex_resource_word0);
-       radeon_ring_write(rdev, sq_tex_resource_word1);
-       radeon_ring_write(rdev, gpu_addr >> 8);
-       radeon_ring_write(rdev, gpu_addr >> 8);
-       radeon_ring_write(rdev, sq_tex_resource_word4);
-       radeon_ring_write(rdev, 0);
-       radeon_ring_write(rdev, SQ_TEX_VTX_VALID_TEXTURE << 30);
+       sq_tex_resource_word0 = S_038000_DIM(V_038000_SQ_TEX_DIM_2D) |
+               S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+       sq_tex_resource_word0 |= S_038000_PITCH((pitch >> 3) - 1) |
+               S_038000_TEX_WIDTH(w - 1);
+
+       sq_tex_resource_word1 = S_038004_DATA_FORMAT(format);
+       sq_tex_resource_word1 |= S_038004_TEX_HEIGHT(h - 1);
+
+       sq_tex_resource_word4 = S_038010_REQUEST_SIZE(1) |
+               S_038010_DST_SEL_X(SQ_SEL_X) |
+               S_038010_DST_SEL_Y(SQ_SEL_Y) |
+               S_038010_DST_SEL_Z(SQ_SEL_Z) |
+               S_038010_DST_SEL_W(SQ_SEL_W);
+
+       cp_set_surface_sync(rdev,
+                           PACKET3_TC_ACTION_ENA, size, gpu_addr);
+
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 7));
+       radeon_ring_write(cp, 0);
+       radeon_ring_write(cp, sq_tex_resource_word0);
+       radeon_ring_write(cp, sq_tex_resource_word1);
+       radeon_ring_write(cp, gpu_addr >> 8);
+       radeon_ring_write(cp, gpu_addr >> 8);
+       radeon_ring_write(cp, sq_tex_resource_word4);
+       radeon_ring_write(cp, 0);
+       radeon_ring_write(cp, SQ_TEX_VTX_VALID_TEXTURE << 30);
 }
 
 /* emits 12 */
@@ -235,43 +246,45 @@ static void
 set_scissors(struct radeon_device *rdev, int x1, int y1,
             int x2, int y2)
 {
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
-       radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, (x1 << 0) | (y1 << 16));
-       radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
-
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
-       radeon_ring_write(rdev, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31));
-       radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
-
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
-       radeon_ring_write(rdev, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31));
-       radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
+       radeon_ring_write(cp, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, (x1 << 0) | (y1 << 16));
+       radeon_ring_write(cp, (x2 << 0) | (y2 << 16));
+
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
+       radeon_ring_write(cp, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31));
+       radeon_ring_write(cp, (x2 << 0) | (y2 << 16));
+
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
+       radeon_ring_write(cp, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31));
+       radeon_ring_write(cp, (x2 << 0) | (y2 << 16));
 }
 
 /* emits 10 */
 static void
 draw_auto(struct radeon_device *rdev)
 {
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
-       radeon_ring_write(rdev, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, DI_PT_RECTLIST);
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+       radeon_ring_write(cp, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, DI_PT_RECTLIST);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0));
-       radeon_ring_write(rdev,
+       radeon_ring_write(cp, PACKET3(PACKET3_INDEX_TYPE, 0));
+       radeon_ring_write(cp,
 #ifdef __BIG_ENDIAN
                          (2 << 2) |
 #endif
                          DI_INDEX_SIZE_16_BIT);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0));
-       radeon_ring_write(rdev, 1);
+       radeon_ring_write(cp, PACKET3(PACKET3_NUM_INSTANCES, 0));
+       radeon_ring_write(cp, 1);
 
-       radeon_ring_write(rdev, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1));
-       radeon_ring_write(rdev, 3);
-       radeon_ring_write(rdev, DI_SRC_SEL_AUTO_INDEX);
+       radeon_ring_write(cp, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1));
+       radeon_ring_write(cp, 3);
+       radeon_ring_write(cp, DI_SRC_SEL_AUTO_INDEX);
 
 }
 
@@ -279,6 +292,7 @@ draw_auto(struct radeon_device *rdev)
 static void
 set_default_state(struct radeon_device *rdev)
 {
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
        u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2;
        u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2;
        int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs;
@@ -434,24 +448,24 @@ set_default_state(struct radeon_device *rdev)
        /* emit an IB pointing at default state */
        dwords = ALIGN(rdev->r600_blit.state_len, 0x10);
        gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;
-       radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
-       radeon_ring_write(rdev,
+       radeon_ring_write(cp, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
+       radeon_ring_write(cp,
 #ifdef __BIG_ENDIAN
                          (2 << 0) |
 #endif
                          (gpu_addr & 0xFFFFFFFC));
-       radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF);
-       radeon_ring_write(rdev, dwords);
+       radeon_ring_write(cp, upper_32_bits(gpu_addr) & 0xFF);
+       radeon_ring_write(cp, dwords);
 
        /* SQ config */
-       radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 6));
-       radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
-       radeon_ring_write(rdev, sq_config);
-       radeon_ring_write(rdev, sq_gpr_resource_mgmt_1);
-       radeon_ring_write(rdev, sq_gpr_resource_mgmt_2);
-       radeon_ring_write(rdev, sq_thread_resource_mgmt);
-       radeon_ring_write(rdev, sq_stack_resource_mgmt_1);
-       radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
+       radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 6));
+       radeon_ring_write(cp, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+       radeon_ring_write(cp, sq_config);
+       radeon_ring_write(cp, sq_gpr_resource_mgmt_1);
+       radeon_ring_write(cp, sq_gpr_resource_mgmt_2);
+       radeon_ring_write(cp, sq_thread_resource_mgmt);
+       radeon_ring_write(cp, sq_stack_resource_mgmt_1);
+       radeon_ring_write(cp, sq_stack_resource_mgmt_2);
 }
 
 static uint32_t i2f(uint32_t input)
@@ -487,6 +501,27 @@ int r600_blit_init(struct radeon_device *rdev)
        u32 packet2s[16];
        int num_packet2s = 0;
 
+       rdev->r600_blit.primitives.set_render_target = set_render_target;
+       rdev->r600_blit.primitives.cp_set_surface_sync = cp_set_surface_sync;
+       rdev->r600_blit.primitives.set_shaders = set_shaders;
+       rdev->r600_blit.primitives.set_vtx_resource = set_vtx_resource;
+       rdev->r600_blit.primitives.set_tex_resource = set_tex_resource;
+       rdev->r600_blit.primitives.set_scissors = set_scissors;
+       rdev->r600_blit.primitives.draw_auto = draw_auto;
+       rdev->r600_blit.primitives.set_default_state = set_default_state;
+
+       rdev->r600_blit.ring_size_common = 40; /* shaders + def state */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */
+       rdev->r600_blit.ring_size_common += 5; /* done copy */
+       rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */
+
+       rdev->r600_blit.ring_size_per_loop = 76;
+       /* set_render_target emits 2 extra dwords on rv6xx */
+       if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
+               rdev->r600_blit.ring_size_per_loop += 2;
+
+       rdev->r600_blit.max_dim = 8192;
+
        /* pin copy shader into vram if already initialized */
        if (rdev->r600_blit.shader_obj)
                goto done;
@@ -587,7 +622,7 @@ void r600_blit_fini(struct radeon_device *rdev)
 static int r600_vb_ib_get(struct radeon_device *rdev)
 {
        int r;
-       r = radeon_ib_get(rdev, &rdev->r600_blit.vb_ib);
+       r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->r600_blit.vb_ib);
        if (r) {
                DRM_ERROR("failed to get IB for vertex buffer\n");
                return r;
@@ -604,15 +639,14 @@ static void r600_vb_ib_put(struct radeon_device *rdev)
        radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
 }
 
-/* FIXME: the function is very similar to evergreen_blit_create_rect, except
-   that it different predefined constants; consider commonizing */
-static unsigned r600_blit_create_rect(unsigned num_pages, int *width, int *height)
+static unsigned r600_blit_create_rect(unsigned num_gpu_pages,
+                                     int *width, int *height, int max_dim)
 {
        unsigned max_pages;
-       unsigned pages = num_pages;
+       unsigned pages = num_gpu_pages;
        int w, h;
 
-       if (num_pages == 0) {
+       if (num_gpu_pages == 0) {
                /* not supposed to be called with no pages, but just in case */
                h = 0;
                w = 0;
@@ -621,15 +655,15 @@ static unsigned r600_blit_create_rect(unsigned num_pages, int *width, int *heigh
        } else {
                int rect_order = 2;
                h = RECT_UNIT_H;
-               while (num_pages / rect_order) {
+               while (num_gpu_pages / rect_order) {
                        h *= 2;
                        rect_order *= 4;
-                       if (h >= MAX_RECT_DIM) {
-                               h = MAX_RECT_DIM;
+                       if (h >= max_dim) {
+                               h = max_dim;
                                break;
                        }
                }
-               max_pages = (MAX_RECT_DIM * h) / (RECT_UNIT_W * RECT_UNIT_H);
+               max_pages = (max_dim * h) / (RECT_UNIT_W * RECT_UNIT_H);
                if (pages > max_pages)
                        pages = max_pages;
                w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h;
@@ -651,40 +685,35 @@ static unsigned r600_blit_create_rect(unsigned num_pages, int *width, int *heigh
 }
 
 
-int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_pages)
+int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages)
 {
+       struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX];
        int r;
        int ring_size;
-       /* loops of emits 64 + fence emit possible */
-       int dwords_per_loop = 76, num_loops = 0;
+       int num_loops = 0;
+       int dwords_per_loop = rdev->r600_blit.ring_size_per_loop;
 
        r = r600_vb_ib_get(rdev);
        if (r)
                return r;
 
-       /* set_render_target emits 2 extra dwords on rv6xx */
-       if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
-               dwords_per_loop += 2;
-
        /* num loops */
-       while (num_pages) {
-               num_pages -= r600_blit_create_rect(num_pages, NULL, NULL);
+       while (num_gpu_pages) {
+               num_gpu_pages -=
+                       r600_blit_create_rect(num_gpu_pages, NULL, NULL,
+                                             rdev->r600_blit.max_dim);
                num_loops++;
        }
 
        /* calculate number of loops correctly */
        ring_size = num_loops * dwords_per_loop;
-       /* set default  + shaders */
-       ring_size += 40; /* shaders + def state */
-       ring_size += 10; /* fence emit for VB IB */
-       ring_size += 5; /* done copy */
-       ring_size += 10; /* fence emit for done copy */
-       r = radeon_ring_lock(rdev, ring_size);
+       ring_size += rdev->r600_blit.ring_size_common;
+       r = radeon_ring_lock(rdev, cp, ring_size);
        if (r)
                return r;
 
-       set_default_state(rdev); /* 14 */
-       set_shaders(rdev); /* 26 */
+       rdev->r600_blit.primitives.set_default_state(rdev);
+       rdev->r600_blit.primitives.set_shaders(rdev);
        return 0;
 }
 
@@ -698,24 +727,27 @@ void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence)
        if (fence)
                r = radeon_fence_emit(rdev, fence);
 
-       radeon_ring_unlock_commit(rdev);
+       radeon_ring_unlock_commit(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]);
 }
 
 void r600_kms_blit_copy(struct radeon_device *rdev,
                        u64 src_gpu_addr, u64 dst_gpu_addr,
-                       unsigned num_pages)
+                       unsigned num_gpu_pages)
 {
        u64 vb_gpu_addr;
        u32 *vb;
 
-       DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
-                 num_pages, rdev->r600_blit.vb_used);
+       DRM_DEBUG("emitting copy %16llx %16llx %d %d\n",
+                 src_gpu_addr, dst_gpu_addr,
+                 num_gpu_pages, rdev->r600_blit.vb_used);
        vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
 
-       while (num_pages) {
+       while (num_gpu_pages) {
                int w, h;
                unsigned size_in_bytes;
-               unsigned pages_per_loop = r600_blit_create_rect(num_pages, &w, &h);
+               unsigned pages_per_loop =
+                       r600_blit_create_rect(num_gpu_pages, &w, &h,
+                                             rdev->r600_blit.max_dim);
 
                size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE;
                DRM_DEBUG("rectangle w=%d h=%d\n", w, h);
@@ -739,36 +771,22 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
                vb[10] = i2f(w);
                vb[11] = i2f(h);
 
-               /* src 9 */
-               set_tex_resource(rdev, FMT_8_8_8_8, w, h, w, src_gpu_addr);
-
-               /* 5 */
-               cp_set_surface_sync(rdev,
-                                   PACKET3_TC_ACTION_ENA, size_in_bytes, src_gpu_addr);
-
-               /* dst 23 */
-               set_render_target(rdev, COLOR_8_8_8_8, w, h, dst_gpu_addr);
-
-               /* scissors 12  */
-               set_scissors(rdev, 0, 0, w, h);
-
-               /* Vertex buffer setup 14 */
+               rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8,
+                                                           w, h, w, src_gpu_addr, size_in_bytes);
+               rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8,
+                                                            w, h, dst_gpu_addr);
+               rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h);
                vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
-               set_vtx_resource(rdev, vb_gpu_addr);
-
-               /* draw 10 */
-               draw_auto(rdev);
-
-               /* 5 */
-               cp_set_surface_sync(rdev,
+               rdev->r600_blit.primitives.set_vtx_resource(rdev, vb_gpu_addr);
+               rdev->r600_blit.primitives.draw_auto(rdev);
+               rdev->r600_blit.primitives.cp_set_surface_sync(rdev,
                                    PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
                                    size_in_bytes, dst_gpu_addr);
 
-               /* 78 ring dwords per loop */
                vb += 12;
                rdev->r600_blit.vb_used += 4*12;
                src_gpu_addr += size_in_bytes;
                dst_gpu_addr += size_in_bytes;
-               num_pages -= pages_per_loop;
+               num_gpu_pages -= pages_per_loop;
        }
 }