aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorPauli Nieminen <suokkos@gmail.com>2010-02-11 12:25:47 -0500
committerDave Airlie <airlied@redhat.com>2010-02-17 23:47:54 -0500
commit44ca7478d46aaad488d916f7262253e000ee60f9 (patch)
tree112f20f173526a087f3a9e8c419f0ad1875bd1cb /drivers/gpu
parentd80eeb0f347b6effa06e11e7cbcb2e6c559bf404 (diff)
drm/radeon: Add asic hook for dma copy to r200 cards.
r200 cards have dma engine which can be used to tranfer data between vram and system memory. r300 dma engine registers match r200 dma engine. Enabling dma copy for r200 is simple as hooking r200 asic to already existing function r300_copy_dma. Rename r300_dma_copy to r200_dma_copyto reflect that supports starts from r200 cards. v2: Created a new asic object for r200 cards. Signed-off-by: Pauli Nieminen <suokkos@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/r200.c46
-rw-r--r--drivers/gpu/drm/radeon/r300.c44
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h69
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c4
4 files changed, 104 insertions, 59 deletions
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index ff1e0cd608bf..1146c9909c2c 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -31,6 +31,7 @@
31#include "radeon_reg.h" 31#include "radeon_reg.h"
32#include "radeon.h" 32#include "radeon.h"
33 33
34#include "r100d.h"
34#include "r200_reg_safe.h" 35#include "r200_reg_safe.h"
35 36
36#include "r100_track.h" 37#include "r100_track.h"
@@ -79,6 +80,51 @@ static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
79 return vtx_size; 80 return vtx_size;
80} 81}
81 82
83int r200_copy_dma(struct radeon_device *rdev,
84 uint64_t src_offset,
85 uint64_t dst_offset,
86 unsigned num_pages,
87 struct radeon_fence *fence)
88{
89 uint32_t size;
90 uint32_t cur_size;
91 int i, num_loops;
92 int r = 0;
93
94 /* radeon pitch is /64 */
95 size = num_pages << PAGE_SHIFT;
96 num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
97 r = radeon_ring_lock(rdev, num_loops * 4 + 64);
98 if (r) {
99 DRM_ERROR("radeon: moving bo (%d).\n", r);
100 return r;
101 }
102 /* Must wait for 2D idle & clean before DMA or hangs might happen */
103 radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
104 radeon_ring_write(rdev, (1 << 16));
105 for (i = 0; i < num_loops; i++) {
106 cur_size = size;
107 if (cur_size > 0x1FFFFF) {
108 cur_size = 0x1FFFFF;
109 }
110 size -= cur_size;
111 radeon_ring_write(rdev, PACKET0(0x720, 2));
112 radeon_ring_write(rdev, src_offset);
113 radeon_ring_write(rdev, dst_offset);
114 radeon_ring_write(rdev, cur_size | (1 << 31) | (1 << 30));
115 src_offset += cur_size;
116 dst_offset += cur_size;
117 }
118 radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
119 radeon_ring_write(rdev, RADEON_WAIT_DMA_GUI_IDLE);
120 if (fence) {
121 r = radeon_fence_emit(rdev, fence);
122 }
123 radeon_ring_unlock_commit(rdev);
124 return r;
125}
126
127
82static int r200_get_vtx_size_1(uint32_t vtx_fmt_1) 128static int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
83{ 129{
84 int vtx_size, i, tex_size; 130 int vtx_size, i, tex_size;
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 654aca1cdf05..a4f395226b34 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -201,50 +201,6 @@ void r300_fence_ring_emit(struct radeon_device *rdev,
201 radeon_ring_write(rdev, RADEON_SW_INT_FIRE); 201 radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
202} 202}
203 203
204int r300_copy_dma(struct radeon_device *rdev,
205 uint64_t src_offset,
206 uint64_t dst_offset,
207 unsigned num_pages,
208 struct radeon_fence *fence)
209{
210 uint32_t size;
211 uint32_t cur_size;
212 int i, num_loops;
213 int r = 0;
214
215 /* radeon pitch is /64 */
216 size = num_pages << PAGE_SHIFT;
217 num_loops = DIV_ROUND_UP(size, 0x1FFFFF);
218 r = radeon_ring_lock(rdev, num_loops * 4 + 64);
219 if (r) {
220 DRM_ERROR("radeon: moving bo (%d).\n", r);
221 return r;
222 }
223 /* Must wait for 2D idle & clean before DMA or hangs might happen */
224 radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0 ));
225 radeon_ring_write(rdev, RADEON_WAIT_2D_IDLECLEAN);
226 for (i = 0; i < num_loops; i++) {
227 cur_size = size;
228 if (cur_size > 0x1FFFFF) {
229 cur_size = 0x1FFFFF;
230 }
231 size -= cur_size;
232 radeon_ring_write(rdev, PACKET0(0x720, 2));
233 radeon_ring_write(rdev, src_offset);
234 radeon_ring_write(rdev, dst_offset);
235 radeon_ring_write(rdev, cur_size | (1 << 31) | (1 << 30));
236 src_offset += cur_size;
237 dst_offset += cur_size;
238 }
239 radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
240 radeon_ring_write(rdev, RADEON_WAIT_DMA_GUI_IDLE);
241 if (fence) {
242 r = radeon_fence_emit(rdev, fence);
243 }
244 radeon_ring_unlock_commit(rdev);
245 return r;
246}
247
248void r300_ring_start(struct radeon_device *rdev) 204void r300_ring_start(struct radeon_device *rdev)
249{ 205{
250 unsigned gb_tile_config; 206 unsigned gb_tile_config;
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 9d2a113f78eb..b7030d7c0396 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -43,7 +43,7 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, uint32_t mem_clock
43void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); 43void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
44 44
45/* 45/*
46 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 46 * r100,rv100,rs100,rv200,rs200
47 */ 47 */
48extern int r100_init(struct radeon_device *rdev); 48extern int r100_init(struct radeon_device *rdev);
49extern void r100_fini(struct radeon_device *rdev); 49extern void r100_fini(struct radeon_device *rdev);
@@ -121,6 +121,51 @@ static struct radeon_asic r100_asic = {
121 .ioctl_wait_idle = NULL, 121 .ioctl_wait_idle = NULL,
122}; 122};
123 123
124/*
125 * r200,rv250,rs300,rv280
126 */
127extern int r200_copy_dma(struct radeon_device *rdev,
128 uint64_t src_offset,
129 uint64_t dst_offset,
130 unsigned num_pages,
131 struct radeon_fence *fence);
132static struct radeon_asic r200_asic = {
133 .init = &r100_init,
134 .fini = &r100_fini,
135 .suspend = &r100_suspend,
136 .resume = &r100_resume,
137 .vga_set_state = &r100_vga_set_state,
138 .gpu_reset = &r100_gpu_reset,
139 .gart_tlb_flush = &r100_pci_gart_tlb_flush,
140 .gart_set_page = &r100_pci_gart_set_page,
141 .cp_commit = &r100_cp_commit,
142 .ring_start = &r100_ring_start,
143 .ring_test = &r100_ring_test,
144 .ring_ib_execute = &r100_ring_ib_execute,
145 .irq_set = &r100_irq_set,
146 .irq_process = &r100_irq_process,
147 .get_vblank_counter = &r100_get_vblank_counter,
148 .fence_ring_emit = &r100_fence_ring_emit,
149 .cs_parse = &r100_cs_parse,
150 .copy_blit = &r100_copy_blit,
151 .copy_dma = &r200_copy_dma,
152 .copy = &r100_copy_blit,
153 .get_engine_clock = &radeon_legacy_get_engine_clock,
154 .set_engine_clock = &radeon_legacy_set_engine_clock,
155 .get_memory_clock = &radeon_legacy_get_memory_clock,
156 .set_memory_clock = NULL,
157 .set_pcie_lanes = NULL,
158 .set_clock_gating = &radeon_legacy_set_clock_gating,
159 .set_surface_reg = r100_set_surface_reg,
160 .clear_surface_reg = r100_clear_surface_reg,
161 .bandwidth_update = &r100_bandwidth_update,
162 .hpd_init = &r100_hpd_init,
163 .hpd_fini = &r100_hpd_fini,
164 .hpd_sense = &r100_hpd_sense,
165 .hpd_set_polarity = &r100_hpd_set_polarity,
166 .ioctl_wait_idle = NULL,
167};
168
124 169
125/* 170/*
126 * r300,r350,rv350,rv380 171 * r300,r350,rv350,rv380
@@ -140,11 +185,7 @@ extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
140extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 185extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
141extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); 186extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
142extern int rv370_get_pcie_lanes(struct radeon_device *rdev); 187extern int rv370_get_pcie_lanes(struct radeon_device *rdev);
143extern int r300_copy_dma(struct radeon_device *rdev, 188
144 uint64_t src_offset,
145 uint64_t dst_offset,
146 unsigned num_pages,
147 struct radeon_fence *fence);
148static struct radeon_asic r300_asic = { 189static struct radeon_asic r300_asic = {
149 .init = &r300_init, 190 .init = &r300_init,
150 .fini = &r300_fini, 191 .fini = &r300_fini,
@@ -164,7 +205,7 @@ static struct radeon_asic r300_asic = {
164 .fence_ring_emit = &r300_fence_ring_emit, 205 .fence_ring_emit = &r300_fence_ring_emit,
165 .cs_parse = &r300_cs_parse, 206 .cs_parse = &r300_cs_parse,
166 .copy_blit = &r100_copy_blit, 207 .copy_blit = &r100_copy_blit,
167 .copy_dma = &r300_copy_dma, 208 .copy_dma = &r200_copy_dma,
168 .copy = &r100_copy_blit, 209 .copy = &r100_copy_blit,
169 .get_engine_clock = &radeon_legacy_get_engine_clock, 210 .get_engine_clock = &radeon_legacy_get_engine_clock,
170 .set_engine_clock = &radeon_legacy_set_engine_clock, 211 .set_engine_clock = &radeon_legacy_set_engine_clock,
@@ -247,7 +288,7 @@ static struct radeon_asic r420_asic = {
247 .fence_ring_emit = &r300_fence_ring_emit, 288 .fence_ring_emit = &r300_fence_ring_emit,
248 .cs_parse = &r300_cs_parse, 289 .cs_parse = &r300_cs_parse,
249 .copy_blit = &r100_copy_blit, 290 .copy_blit = &r100_copy_blit,
250 .copy_dma = &r300_copy_dma, 291 .copy_dma = &r200_copy_dma,
251 .copy = &r100_copy_blit, 292 .copy = &r100_copy_blit,
252 .get_engine_clock = &radeon_atom_get_engine_clock, 293 .get_engine_clock = &radeon_atom_get_engine_clock,
253 .set_engine_clock = &radeon_atom_set_engine_clock, 294 .set_engine_clock = &radeon_atom_set_engine_clock,
@@ -297,7 +338,7 @@ static struct radeon_asic rs400_asic = {
297 .fence_ring_emit = &r300_fence_ring_emit, 338 .fence_ring_emit = &r300_fence_ring_emit,
298 .cs_parse = &r300_cs_parse, 339 .cs_parse = &r300_cs_parse,
299 .copy_blit = &r100_copy_blit, 340 .copy_blit = &r100_copy_blit,
300 .copy_dma = &r300_copy_dma, 341 .copy_dma = &r200_copy_dma,
301 .copy = &r100_copy_blit, 342 .copy = &r100_copy_blit,
302 .get_engine_clock = &radeon_legacy_get_engine_clock, 343 .get_engine_clock = &radeon_legacy_get_engine_clock,
303 .set_engine_clock = &radeon_legacy_set_engine_clock, 344 .set_engine_clock = &radeon_legacy_set_engine_clock,
@@ -357,7 +398,7 @@ static struct radeon_asic rs600_asic = {
357 .fence_ring_emit = &r300_fence_ring_emit, 398 .fence_ring_emit = &r300_fence_ring_emit,
358 .cs_parse = &r300_cs_parse, 399 .cs_parse = &r300_cs_parse,
359 .copy_blit = &r100_copy_blit, 400 .copy_blit = &r100_copy_blit,
360 .copy_dma = &r300_copy_dma, 401 .copy_dma = &r200_copy_dma,
361 .copy = &r100_copy_blit, 402 .copy = &r100_copy_blit,
362 .get_engine_clock = &radeon_atom_get_engine_clock, 403 .get_engine_clock = &radeon_atom_get_engine_clock,
363 .set_engine_clock = &radeon_atom_set_engine_clock, 404 .set_engine_clock = &radeon_atom_set_engine_clock,
@@ -404,8 +445,8 @@ static struct radeon_asic rs690_asic = {
404 .fence_ring_emit = &r300_fence_ring_emit, 445 .fence_ring_emit = &r300_fence_ring_emit,
405 .cs_parse = &r300_cs_parse, 446 .cs_parse = &r300_cs_parse,
406 .copy_blit = &r100_copy_blit, 447 .copy_blit = &r100_copy_blit,
407 .copy_dma = &r300_copy_dma, 448 .copy_dma = &r200_copy_dma,
408 .copy = &r300_copy_dma, 449 .copy = &r200_copy_dma,
409 .get_engine_clock = &radeon_atom_get_engine_clock, 450 .get_engine_clock = &radeon_atom_get_engine_clock,
410 .set_engine_clock = &radeon_atom_set_engine_clock, 451 .set_engine_clock = &radeon_atom_set_engine_clock,
411 .get_memory_clock = &radeon_atom_get_memory_clock, 452 .get_memory_clock = &radeon_atom_get_memory_clock,
@@ -457,7 +498,7 @@ static struct radeon_asic rv515_asic = {
457 .fence_ring_emit = &r300_fence_ring_emit, 498 .fence_ring_emit = &r300_fence_ring_emit,
458 .cs_parse = &r300_cs_parse, 499 .cs_parse = &r300_cs_parse,
459 .copy_blit = &r100_copy_blit, 500 .copy_blit = &r100_copy_blit,
460 .copy_dma = &r300_copy_dma, 501 .copy_dma = &r200_copy_dma,
461 .copy = &r100_copy_blit, 502 .copy = &r100_copy_blit,
462 .get_engine_clock = &radeon_atom_get_engine_clock, 503 .get_engine_clock = &radeon_atom_get_engine_clock,
463 .set_engine_clock = &radeon_atom_set_engine_clock, 504 .set_engine_clock = &radeon_atom_set_engine_clock,
@@ -501,7 +542,7 @@ static struct radeon_asic r520_asic = {
501 .fence_ring_emit = &r300_fence_ring_emit, 542 .fence_ring_emit = &r300_fence_ring_emit,
502 .cs_parse = &r300_cs_parse, 543 .cs_parse = &r300_cs_parse,
503 .copy_blit = &r100_copy_blit, 544 .copy_blit = &r100_copy_blit,
504 .copy_dma = &r300_copy_dma, 545 .copy_dma = &r200_copy_dma,
505 .copy = &r100_copy_blit, 546 .copy = &r100_copy_blit,
506 .get_engine_clock = &radeon_atom_get_engine_clock, 547 .get_engine_clock = &radeon_atom_get_engine_clock,
507 .set_engine_clock = &radeon_atom_set_engine_clock, 548 .set_engine_clock = &radeon_atom_set_engine_clock,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 7a30f6955e41..7be3a6968463 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -340,11 +340,13 @@ int radeon_asic_init(struct radeon_device *rdev)
340 case CHIP_RS100: 340 case CHIP_RS100:
341 case CHIP_RV200: 341 case CHIP_RV200:
342 case CHIP_RS200: 342 case CHIP_RS200:
343 rdev->asic = &r100_asic;
344 break;
343 case CHIP_R200: 345 case CHIP_R200:
344 case CHIP_RV250: 346 case CHIP_RV250:
345 case CHIP_RS300: 347 case CHIP_RS300:
346 case CHIP_RV280: 348 case CHIP_RV280:
347 rdev->asic = &r100_asic; 349 rdev->asic = &r200_asic;
348 break; 350 break;
349 case CHIP_R300: 351 case CHIP_R300:
350 case CHIP_R350: 352 case CHIP_R350: