aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon.h
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-09-23 02:56:27 -0400
committerDave Airlie <airlied@linux.ie>2009-09-24 23:08:18 -0400
commit513bcb4655e68706594e45dfa1d4b181500110ba (patch)
treeed457db4cfb202015866a131ad4e742503728fad /drivers/gpu/drm/radeon/radeon.h
parent35e4b7af21d77933abda3d41d1672589eb6c960c (diff)
drm/radeon/kms: don't require up to 64k allocations. (v2)
This avoids needing to do a kmalloc > PAGE_SIZE for the main indirect buffer chunk, it adds an accessor for all reads from the chunk and caches a single page at a time for subsequent reads. changes since v1: Use a two page pool which should be the most common case a single packet spanning > PAGE_SIZE will be hit, but I'm having trouble seeing anywhere we currently generate anything like that. hopefully proper short page copying at end added parser_error flag to set deep errors instead of having to test every ib value fetch. fixed bug in patch that went to list. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon.h')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h37
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index d5de53e06cec..7e34e4376f95 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -342,7 +342,7 @@ struct radeon_ib {
342 unsigned long idx; 342 unsigned long idx;
343 uint64_t gpu_addr; 343 uint64_t gpu_addr;
344 struct radeon_fence *fence; 344 struct radeon_fence *fence;
345 volatile uint32_t *ptr; 345 uint32_t *ptr;
346 uint32_t length_dw; 346 uint32_t length_dw;
347}; 347};
348 348
@@ -415,7 +415,12 @@ struct radeon_cs_reloc {
415struct radeon_cs_chunk { 415struct radeon_cs_chunk {
416 uint32_t chunk_id; 416 uint32_t chunk_id;
417 uint32_t length_dw; 417 uint32_t length_dw;
418 int kpage_idx[2];
419 uint32_t *kpage[2];
418 uint32_t *kdata; 420 uint32_t *kdata;
421 void __user *user_ptr;
422 int last_copied_page;
423 int last_page_index;
419}; 424};
420 425
421struct radeon_cs_parser { 426struct radeon_cs_parser {
@@ -438,8 +443,38 @@ struct radeon_cs_parser {
438 struct radeon_ib *ib; 443 struct radeon_ib *ib;
439 void *track; 444 void *track;
440 unsigned family; 445 unsigned family;
446 int parser_error;
441}; 447};
442 448
449extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx);
450extern int radeon_cs_finish_pages(struct radeon_cs_parser *p);
451
452
453static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
454{
455 struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
456 u32 pg_idx, pg_offset;
457 u32 idx_value = 0;
458 int new_page;
459
460 pg_idx = (idx * 4) / PAGE_SIZE;
461 pg_offset = (idx * 4) % PAGE_SIZE;
462
463 if (ibc->kpage_idx[0] == pg_idx)
464 return ibc->kpage[0][pg_offset/4];
465 if (ibc->kpage_idx[1] == pg_idx)
466 return ibc->kpage[1][pg_offset/4];
467
468 new_page = radeon_cs_update_pages(p, pg_idx);
469 if (new_page < 0) {
470 p->parser_error = new_page;
471 return 0;
472 }
473
474 idx_value = ibc->kpage[new_page][pg_offset/4];
475 return idx_value;
476}
477
443struct radeon_cs_packet { 478struct radeon_cs_packet {
444 unsigned idx; 479 unsigned idx;
445 unsigned type; 480 unsigned type;