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

Commit 1b37078b authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie
Browse files

drm/radeon/kms: add support for per-ring fence interrupts

parent b40e7e16
Loading
Loading
Loading
Loading
+51 −7
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@
static void evergreen_gpu_init(struct radeon_device *rdev);
void evergreen_fini(struct radeon_device *rdev);
void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
				     int ring, u32 cp_int_cntl);

void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
{
@@ -2474,6 +2476,12 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev)
{
	u32 tmp;

	if (rdev->family >= CHIP_CAYMAN) {
		cayman_cp_int_cntl_setup(rdev, 0,
					 CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
		cayman_cp_int_cntl_setup(rdev, 1, 0);
		cayman_cp_int_cntl_setup(rdev, 2, 0);
	} else
		WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
	WREG32(GRBM_INT_CNTL, 0);
	WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
@@ -2519,6 +2527,7 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev)
int evergreen_irq_set(struct radeon_device *rdev)
{
	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
	u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
	u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
	u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
	u32 grbm_int_cntl = 0;
@@ -2543,11 +2552,28 @@ int evergreen_irq_set(struct radeon_device *rdev)
	hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
	hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;

	if (rdev->irq.sw_int) {
		DRM_DEBUG("evergreen_irq_set: sw int\n");
	if (rdev->family >= CHIP_CAYMAN) {
		/* enable CP interrupts on all rings */
		if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) {
			DRM_DEBUG("evergreen_irq_set: sw int gfx\n");
			cp_int_cntl |= TIME_STAMP_INT_ENABLE;
		}
		if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP1_INDEX]) {
			DRM_DEBUG("evergreen_irq_set: sw int cp1\n");
			cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
		}
		if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP2_INDEX]) {
			DRM_DEBUG("evergreen_irq_set: sw int cp2\n");
			cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
		}
	} else {
		if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) {
			DRM_DEBUG("evergreen_irq_set: sw int gfx\n");
			cp_int_cntl |= RB_INT_ENABLE;
			cp_int_cntl |= TIME_STAMP_INT_ENABLE;
		}
	}

	if (rdev->irq.crtc_vblank_int[0] ||
	    rdev->irq.pflip[0]) {
		DRM_DEBUG("evergreen_irq_set: vblank 0\n");
@@ -2607,6 +2633,11 @@ int evergreen_irq_set(struct radeon_device *rdev)
		grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
	}

	if (rdev->family >= CHIP_CAYMAN) {
		cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl);
		cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1);
		cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2);
	} else
		WREG32(CP_INT_CNTL, cp_int_cntl);
	WREG32(GRBM_INT_CNTL, grbm_int_cntl);

@@ -3026,6 +3057,19 @@ restart_ih:
			break;
		case 181: /* CP EOP event */
			DRM_DEBUG("IH: CP EOP\n");
			if (rdev->family >= CHIP_CAYMAN) {
				switch (src_data) {
				case 0:
					radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
					break;
				case 1:
					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
					break;
				case 2:
					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
					break;
				}
			} else
				radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
			break;
		case 233: /* GUI IDLE */
+9 −0
Original line number Diff line number Diff line
@@ -1006,6 +1006,15 @@ void cayman_pcie_gart_fini(struct radeon_device *rdev)
	radeon_gart_fini(rdev);
}

void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
			      int ring, u32 cp_int_cntl)
{
	u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3;

	WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3));
	WREG32(CP_INT_CNTL, cp_int_cntl);
}

/*
 * CP.
 */
+9 −0
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@
#define CAYMAN_MAX_TCC_MASK          0xFF

#define DMIF_ADDR_CONFIG  				0xBD4
#define	SRBM_GFX_CNTL				        0x0E44
#define		RINGID(x)					(((x) & 0x3) << 0)
#define		VMID(x)						(((x) & 0x7) << 0)
#define	SRBM_STATUS				        0x0E50

#define VM_CONTEXT0_REQUEST_RESPONSE			0x1470
@@ -394,6 +397,12 @@
#define	CP_RB0_RPTR_ADDR				0xC10C
#define	CP_RB0_RPTR_ADDR_HI				0xC110
#define	CP_RB0_WPTR					0xC114

#define CP_INT_CNTL                                     0xC124
#       define CNTX_BUSY_INT_ENABLE                     (1 << 19)
#       define CNTX_EMPTY_INT_ENABLE                    (1 << 20)
#       define TIME_STAMP_INT_ENABLE                    (1 << 26)

#define	CP_RB1_BASE					0xC180
#define	CP_RB1_CNTL					0xC184
#define	CP_RB1_RPTR_ADDR				0xC188
+1 −1
Original line number Diff line number Diff line
@@ -667,7 +667,7 @@ int r100_irq_set(struct radeon_device *rdev)
		WREG32(R_000040_GEN_INT_CNTL, 0);
		return -EINVAL;
	}
	if (rdev->irq.sw_int) {
	if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) {
		tmp |= RADEON_SW_INT_ENABLE;
	}
	if (rdev->irq.gui_idle) {
+1 −1
Original line number Diff line number Diff line
@@ -3098,7 +3098,7 @@ int r600_irq_set(struct radeon_device *rdev)
		hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN;
	}

	if (rdev->irq.sw_int) {
	if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) {
		DRM_DEBUG("r600_irq_set: sw int\n");
		cp_int_cntl |= RB_INT_ENABLE;
		cp_int_cntl |= TIME_STAMP_INT_ENABLE;
Loading