Skip to content

Commit

Permalink
drm/radeon/kms: Rework radeon object handling
Browse files Browse the repository at this point in the history
The locking & protection of radeon object was somewhat messy.
This patch completely rework it to now use ttm reserve as a
protection for the radeon object structure member. It also
shrink down the various radeon object structure by removing
field which were redondant with the ttm information. Last it
converts few simple functions to inline which should with
performances.

airlied: rebase on top of r600 and other changes.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Jerome Glisse authored and Dave Airlie committed Dec 2, 2009
1 parent 1614f8b commit 4c78867
Show file tree
Hide file tree
Showing 26 changed files with 901 additions and 701 deletions.
30 changes: 20 additions & 10 deletions drivers/gpu/drm/radeon/atombios_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,9 +574,10 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
struct radeon_device *rdev = dev->dev_private;
struct radeon_framebuffer *radeon_fb;
struct drm_gem_object *obj;
struct drm_radeon_gem_object *obj_priv;
struct radeon_bo *rbo;
uint64_t fb_location;
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
int r;

/* no fb bound */
if (!crtc->fb) {
Expand All @@ -586,12 +587,21 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,

radeon_fb = to_radeon_framebuffer(crtc->fb);

/* Pin framebuffer & get tilling informations */
obj = radeon_fb->obj;
obj_priv = obj->driver_private;

if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &fb_location)) {
rbo = obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
if (unlikely(r != 0)) {
radeon_bo_unreserve(rbo);
return -EINVAL;
}
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
radeon_bo_unreserve(rbo);
if (tiling_flags & RADEON_TILING_MACRO)
fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;

switch (crtc->fb->bits_per_pixel) {
case 8:
Expand Down Expand Up @@ -621,11 +631,6 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
return -EINVAL;
}

radeon_object_get_tiling_flags(obj->driver_private,
&tiling_flags, NULL);
if (tiling_flags & RADEON_TILING_MACRO)
fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;

if (tiling_flags & RADEON_TILING_MICRO)
fb_format |= AVIVO_D1GRPH_TILED;

Expand Down Expand Up @@ -677,7 +682,12 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,

if (old_fb && old_fb != crtc->fb) {
radeon_fb = to_radeon_framebuffer(old_fb);
radeon_gem_object_unpin(radeon_fb->obj);
rbo = radeon_fb->obj->driver_private;
r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0))
return r;
radeon_bo_unpin(rbo);
radeon_bo_unreserve(rbo);
}

/* Bytes per pixel may have changed */
Expand Down
90 changes: 52 additions & 38 deletions drivers/gpu/drm/radeon/r100.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,24 +261,27 @@ int r100_wb_init(struct radeon_device *rdev)
int r;

if (rdev->wb.wb_obj == NULL) {
r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE,
true,
RADEON_GEM_DOMAIN_GTT,
false, &rdev->wb.wb_obj);
r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
RADEON_GEM_DOMAIN_GTT,
&rdev->wb.wb_obj);
if (r) {
DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
dev_err(rdev->dev, "(%d) create WB buffer failed\n", r);
return r;
}
r = radeon_object_pin(rdev->wb.wb_obj,
RADEON_GEM_DOMAIN_GTT,
&rdev->wb.gpu_addr);
r = radeon_bo_reserve(rdev->wb.wb_obj, false);
if (unlikely(r != 0))
return r;
r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
&rdev->wb.gpu_addr);
if (r) {
DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
dev_err(rdev->dev, "(%d) pin WB buffer failed\n", r);
radeon_bo_unreserve(rdev->wb.wb_obj);
return r;
}
r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
radeon_bo_unreserve(rdev->wb.wb_obj);
if (r) {
DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
dev_err(rdev->dev, "(%d) map WB buffer failed\n", r);
return r;
}
}
Expand All @@ -296,11 +299,19 @@ void r100_wb_disable(struct radeon_device *rdev)

void r100_wb_fini(struct radeon_device *rdev)
{
int r;

r100_wb_disable(rdev);
if (rdev->wb.wb_obj) {
radeon_object_kunmap(rdev->wb.wb_obj);
radeon_object_unpin(rdev->wb.wb_obj);
radeon_object_unref(&rdev->wb.wb_obj);
r = radeon_bo_reserve(rdev->wb.wb_obj, false);
if (unlikely(r != 0)) {
dev_err(rdev->dev, "(%d) can't finish WB\n", r);
return;
}
radeon_bo_kunmap(rdev->wb.wb_obj);
radeon_bo_unpin(rdev->wb.wb_obj);
radeon_bo_unreserve(rdev->wb.wb_obj);
radeon_bo_unref(&rdev->wb.wb_obj);
rdev->wb.wb = NULL;
rdev->wb.wb_obj = NULL;
}
Expand Down Expand Up @@ -1294,17 +1305,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p,

int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
struct radeon_object *robj)
struct radeon_bo *robj)
{
unsigned idx;
u32 value;
idx = pkt->idx + 1;
value = radeon_get_ib_value(p, idx + 2);
if ((value + 1) > radeon_object_size(robj)) {
if ((value + 1) > radeon_bo_size(robj)) {
DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER "
"(need %u have %lu) !\n",
value + 1,
radeon_object_size(robj));
radeon_bo_size(robj));
return -EINVAL;
}
return 0;
Expand Down Expand Up @@ -2608,7 +2619,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
struct r100_cs_track *track, unsigned idx)
{
unsigned face, w, h;
struct radeon_object *cube_robj;
struct radeon_bo *cube_robj;
unsigned long size;

for (face = 0; face < 5; face++) {
Expand All @@ -2621,9 +2632,9 @@ static int r100_cs_track_cube(struct radeon_device *rdev,

size += track->textures[idx].cube_info[face].offset;

if (size > radeon_object_size(cube_robj)) {
if (size > radeon_bo_size(cube_robj)) {
DRM_ERROR("Cube texture offset greater than object size %lu %lu\n",
size, radeon_object_size(cube_robj));
size, radeon_bo_size(cube_robj));
r100_cs_track_texture_print(&track->textures[idx]);
return -1;
}
Expand All @@ -2634,7 +2645,7 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
static int r100_cs_track_texture_check(struct radeon_device *rdev,
struct r100_cs_track *track)
{
struct radeon_object *robj;
struct radeon_bo *robj;
unsigned long size;
unsigned u, i, w, h;
int ret;
Expand Down Expand Up @@ -2690,9 +2701,9 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
"%u\n", track->textures[u].tex_coord_type, u);
return -EINVAL;
}
if (size > radeon_object_size(robj)) {
if (size > radeon_bo_size(robj)) {
DRM_ERROR("Texture of unit %u needs %lu bytes but is "
"%lu\n", u, size, radeon_object_size(robj));
"%lu\n", u, size, radeon_bo_size(robj));
r100_cs_track_texture_print(&track->textures[u]);
return -EINVAL;
}
Expand All @@ -2714,10 +2725,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
}
size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
size += track->cb[i].offset;
if (size > radeon_object_size(track->cb[i].robj)) {
if (size > radeon_bo_size(track->cb[i].robj)) {
DRM_ERROR("[drm] Buffer too small for color buffer %d "
"(need %lu have %lu) !\n", i, size,
radeon_object_size(track->cb[i].robj));
radeon_bo_size(track->cb[i].robj));
DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
i, track->cb[i].pitch, track->cb[i].cpp,
track->cb[i].offset, track->maxy);
Expand All @@ -2731,10 +2742,10 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
}
size = track->zb.pitch * track->zb.cpp * track->maxy;
size += track->zb.offset;
if (size > radeon_object_size(track->zb.robj)) {
if (size > radeon_bo_size(track->zb.robj)) {
DRM_ERROR("[drm] Buffer too small for z buffer "
"(need %lu have %lu) !\n", size,
radeon_object_size(track->zb.robj));
radeon_bo_size(track->zb.robj));
DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n",
track->zb.pitch, track->zb.cpp,
track->zb.offset, track->maxy);
Expand All @@ -2752,11 +2763,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
"bound\n", prim_walk, i);
return -EINVAL;
}
if (size > radeon_object_size(track->arrays[i].robj)) {
DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
"have %lu dwords\n", prim_walk, i,
size >> 2,
radeon_object_size(track->arrays[i].robj) >> 2);
if (size > radeon_bo_size(track->arrays[i].robj)) {
dev_err(rdev->dev, "(PW %u) Vertex array %u "
"need %lu dwords have %lu dwords\n",
prim_walk, i, size >> 2,
radeon_bo_size(track->arrays[i].robj)
>> 2);
DRM_ERROR("Max indices %u\n", track->max_indx);
return -EINVAL;
}
Expand All @@ -2770,10 +2782,12 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
"bound\n", prim_walk, i);
return -EINVAL;
}
if (size > radeon_object_size(track->arrays[i].robj)) {
DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
"have %lu dwords\n", prim_walk, i, size >> 2,
radeon_object_size(track->arrays[i].robj) >> 2);
if (size > radeon_bo_size(track->arrays[i].robj)) {
dev_err(rdev->dev, "(PW %u) Vertex array %u "
"need %lu dwords have %lu dwords\n",
prim_walk, i, size >> 2,
radeon_bo_size(track->arrays[i].robj)
>> 2);
return -EINVAL;
}
}
Expand Down Expand Up @@ -3188,7 +3202,7 @@ void r100_fini(struct radeon_device *rdev)
r100_pci_gart_fini(rdev);
radeon_irq_kms_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_object_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
kfree(rdev->bios);
rdev->bios = NULL;
Expand Down Expand Up @@ -3276,7 +3290,7 @@ int r100_init(struct radeon_device *rdev)
if (r)
return r;
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r)
return r;
if (rdev->flags & RADEON_IS_PCI) {
Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/radeon/r100_track.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,26 @@
* CS functions
*/
struct r100_cs_track_cb {
struct radeon_object *robj;
struct radeon_bo *robj;
unsigned pitch;
unsigned cpp;
unsigned offset;
};

struct r100_cs_track_array {
struct radeon_object *robj;
struct radeon_bo *robj;
unsigned esize;
};

struct r100_cs_cube_info {
struct radeon_object *robj;
unsigned offset;
struct radeon_bo *robj;
unsigned offset;
unsigned width;
unsigned height;
};

struct r100_cs_track_texture {
struct radeon_object *robj;
struct radeon_bo *robj;
struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
unsigned pitch;
unsigned width;
Expand Down
15 changes: 10 additions & 5 deletions drivers/gpu/drm/radeon/r300.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,19 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)

void rv370_pcie_gart_disable(struct radeon_device *rdev)
{
uint32_t tmp;
u32 tmp;
int r;

tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp & ~RADEON_PCIE_TX_GART_EN);
if (rdev->gart.table.vram.robj) {
radeon_object_kunmap(rdev->gart.table.vram.robj);
radeon_object_unpin(rdev->gart.table.vram.robj);
r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
if (likely(r == 0)) {
radeon_bo_kunmap(rdev->gart.table.vram.robj);
radeon_bo_unpin(rdev->gart.table.vram.robj);
radeon_bo_unreserve(rdev->gart.table.vram.robj);
}
}
}

Expand Down Expand Up @@ -1270,7 +1275,7 @@ void r300_fini(struct radeon_device *rdev)
r100_pci_gart_fini(rdev);
radeon_irq_kms_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_object_fini(rdev);
radeon_bo_fini(rdev);
radeon_atombios_fini(rdev);
kfree(rdev->bios);
rdev->bios = NULL;
Expand Down Expand Up @@ -1328,7 +1333,7 @@ int r300_init(struct radeon_device *rdev)
if (r)
return r;
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r)
return r;
if (rdev->flags & RADEON_IS_PCIE) {
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/radeon/r420.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ void r420_fini(struct radeon_device *rdev)
radeon_agp_fini(rdev);
radeon_irq_kms_fini(rdev);
radeon_fence_driver_fini(rdev);
radeon_object_fini(rdev);
radeon_bo_fini(rdev);
if (rdev->is_atom_bios) {
radeon_atombios_fini(rdev);
} else {
Expand Down Expand Up @@ -325,7 +325,7 @@ int r420_init(struct radeon_device *rdev)
return r;
}
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r) {
return r;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/radeon/r520.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ int r520_init(struct radeon_device *rdev)
if (r)
return r;
/* Memory manager */
r = radeon_object_init(rdev);
r = radeon_bo_init(rdev);
if (r)
return r;
r = rv370_pcie_gart_init(rdev);
Expand Down
Loading

0 comments on commit 4c78867

Please sign in to comment.