Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c788679 authored by Jerome Glisse's avatar Jerome Glisse Committed by Dave Airlie
Browse files

drm/radeon/kms: Rework radeon object handling



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: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 1614f8b1
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -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) {
@@ -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:
@@ -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;

@@ -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 */
+52 −38
Original line number Diff line number Diff line
@@ -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,
		r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
					RADEON_GEM_DOMAIN_GTT,
					 false, &rdev->wb.wb_obj);
					&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,
		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;
		}
	}
@@ -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;
	}
@@ -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;
@@ -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++) {
@@ -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;
		}
@@ -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;
@@ -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;
		}
@@ -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);
@@ -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);
@@ -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;
			}
@@ -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;
			}
		}
@@ -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;
@@ -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) {
+5 −5
Original line number Diff line number Diff line
@@ -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;
	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;
+10 −5
Original line number Diff line number Diff line
@@ -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);
		}
	}
}

@@ -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;
@@ -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) {
+2 −2
Original line number Diff line number Diff line
@@ -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 {
@@ -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;
	}
Loading