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

Commit 6adae108 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-next-3.18' of git://people.freedesktop.org/~agd5f/linux into drm-next

More radeon changes for drm-next.  Highlights:
- UVD support for older asics
- Reset rework in preparation for Maarten's fence patches
I have a few more patches which depend on Christian's ttm changes,
I'll send them out separately once you've merged the ttm changes.

* 'drm-next-3.18' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: drop doing resets in a work item
  drm/radeon: drop RADEON_FENCE_SIGNALED_SEQ v2
  drm/radeon: add timeout argument to radeon_fence_wait_seq v2
  drm/radeon: handle lockup in delayed work, v5
  drm/radeon: take exclusive_lock in read mode during ring tests, v5
  drm/radeon: force fence completion only on problematic rings (v2)
  drm/radeon: wake up all fences on manual reset
  drm/radeon: add UVD fw names for older asic
  drm/radeon: enable RB_ARB before resetting the VCPU
  drm/radeon: 760G/780V/880V don't have UVD
  drm/radeon: implement UVD hw workarounds for R6xx v3
  drm/radeon: add UVD support for older asics v4
  drm/radeon: add set_uvd_clocks callback for r6xx v4
  drm/radeon: properly init UVD MC bits on R600
  drm/radeon: force UVD buffers into VRAM on RS[78]80 v2
  drm/radeon: move the IB test after the AGP fallback
parents fb1aacae 3c036389
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -8246,8 +8246,10 @@ int cik_irq_process(struct radeon_device *rdev)
	}
	if (queue_hotplug)
		schedule_work(&rdev->hotplug_work);
	if (queue_reset)
		schedule_work(&rdev->reset_work);
	if (queue_reset) {
		rdev->needs_reset = true;
		wake_up_all(&rdev->fence_queue);
	}
	if (queue_thermal)
		schedule_work(&rdev->pm.dpm.thermal.work);
	rdev->ih.rptr = rptr;
+132 −0
Original line number Diff line number Diff line
@@ -122,6 +122,94 @@ u32 r600_get_xclk(struct radeon_device *rdev)

int r600_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
{
	unsigned fb_div = 0, ref_div, vclk_div = 0, dclk_div = 0;
	int r;

	/* bypass vclk and dclk with bclk */
	WREG32_P(CG_UPLL_FUNC_CNTL_2,
		 VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
		 ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));

	/* assert BYPASS_EN, deassert UPLL_RESET, UPLL_SLEEP and UPLL_CTLREQ */
	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~(
		 UPLL_RESET_MASK | UPLL_SLEEP_MASK | UPLL_CTLREQ_MASK));

	if (rdev->family >= CHIP_RS780)
		WREG32_P(GFX_MACRO_BYPASS_CNTL, UPLL_BYPASS_CNTL,
			 ~UPLL_BYPASS_CNTL);

	if (!vclk || !dclk) {
		/* keep the Bypass mode, put PLL to sleep */
		WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
		return 0;
	}

	if (rdev->clock.spll.reference_freq == 10000)
		ref_div = 34;
	else
		ref_div = 4;

	r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 50000, 160000,
					  ref_div + 1, 0xFFF, 2, 30, ~0,
					  &fb_div, &vclk_div, &dclk_div);
	if (r)
		return r;

	if (rdev->family >= CHIP_RV670 && rdev->family < CHIP_RS780)
		fb_div >>= 1;
	else
		fb_div |= 1;

	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
        if (r)
                return r;

	/* assert PLL_RESET */
	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);

	/* For RS780 we have to choose ref clk */
	if (rdev->family >= CHIP_RS780)
		WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_REFCLK_SRC_SEL_MASK,
			 ~UPLL_REFCLK_SRC_SEL_MASK);

	/* set the required fb, ref and post divder values */
	WREG32_P(CG_UPLL_FUNC_CNTL,
		 UPLL_FB_DIV(fb_div) |
		 UPLL_REF_DIV(ref_div),
		 ~(UPLL_FB_DIV_MASK | UPLL_REF_DIV_MASK));
	WREG32_P(CG_UPLL_FUNC_CNTL_2,
		 UPLL_SW_HILEN(vclk_div >> 1) |
		 UPLL_SW_LOLEN((vclk_div >> 1) + (vclk_div & 1)) |
		 UPLL_SW_HILEN2(dclk_div >> 1) |
		 UPLL_SW_LOLEN2((dclk_div >> 1) + (dclk_div & 1)) |
		 UPLL_DIVEN_MASK | UPLL_DIVEN2_MASK,
		 ~UPLL_SW_MASK);

	/* give the PLL some time to settle */
	mdelay(15);

	/* deassert PLL_RESET */
	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);

	mdelay(15);

	/* deassert BYPASS EN */
	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);

	if (rdev->family >= CHIP_RS780)
		WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~UPLL_BYPASS_CNTL);

	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
	if (r)
		return r;

	/* switch VCLK and DCLK selection */
	WREG32_P(CG_UPLL_FUNC_CNTL_2,
		 VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
		 ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));

	mdelay(100);

	return 0;
}

@@ -992,6 +1080,8 @@ static int r600_pcie_gart_enable(struct radeon_device *rdev)
	WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_RD_UVD_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_WR_UVD_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
	WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
@@ -1042,6 +1132,8 @@ static void r600_pcie_gart_disable(struct radeon_device *rdev)
	WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_RD_UVD_CNTL, tmp);
	WREG32(MC_VM_L1_TLB_MCB_WR_UVD_CNTL, tmp);
	radeon_gart_table_vram_unpin(rdev);
}

@@ -2917,6 +3009,18 @@ static int r600_startup(struct radeon_device *rdev)
		return r;
	}

	if (rdev->has_uvd) {
		r = uvd_v1_0_resume(rdev);
		if (!r) {
			r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
			if (r) {
				dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
			}
		}
		if (r)
			rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
	}

	/* Enable IRQ */
	if (!rdev->irq.installed) {
		r = radeon_irq_kms_init(rdev);
@@ -2945,6 +3049,18 @@ static int r600_startup(struct radeon_device *rdev)
	if (r)
		return r;

	if (rdev->has_uvd) {
		ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
		if (ring->ring_size) {
			r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
					     RADEON_CP_PACKET2);
			if (!r)
				r = uvd_v1_0_init(rdev);
			if (r)
				DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
		}
	}

	r = radeon_ib_pool_init(rdev);
	if (r) {
		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
@@ -3004,6 +3120,10 @@ int r600_suspend(struct radeon_device *rdev)
	radeon_pm_suspend(rdev);
	r600_audio_fini(rdev);
	r600_cp_stop(rdev);
	if (rdev->has_uvd) {
		uvd_v1_0_fini(rdev);
		radeon_uvd_suspend(rdev);
	}
	r600_irq_suspend(rdev);
	radeon_wb_disable(rdev);
	r600_pcie_gart_disable(rdev);
@@ -3083,6 +3203,14 @@ int r600_init(struct radeon_device *rdev)
	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);

	if (rdev->has_uvd) {
		r = radeon_uvd_init(rdev);
		if (!r) {
			rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
			r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
		}
	}

	rdev->ih.ring_obj = NULL;
	r600_ih_ring_init(rdev, 64 * 1024);

@@ -3112,6 +3240,10 @@ void r600_fini(struct radeon_device *rdev)
	r600_audio_fini(rdev);
	r600_cp_fini(rdev);
	r600_irq_fini(rdev);
	if (rdev->has_uvd) {
		uvd_v1_0_fini(rdev);
		radeon_uvd_fini(rdev);
	}
	radeon_wb_fini(rdev);
	radeon_ib_pool_fini(rdev);
	radeon_irq_kms_fini(rdev);
+40 −1
Original line number Diff line number Diff line
@@ -330,11 +330,12 @@
#define	HDP_TILING_CONFIG				0x2F3C
#define HDP_DEBUG1                                      0x2F34

#define MC_CONFIG					0x2000
#define MC_VM_AGP_TOP					0x2184
#define MC_VM_AGP_BOT					0x2188
#define	MC_VM_AGP_BASE					0x218C
#define MC_VM_FB_LOCATION				0x2180
#define MC_VM_L1_TLB_MCD_RD_A_CNTL			0x219C
#define MC_VM_L1_TLB_MCB_RD_UVD_CNTL			0x2124
#define 	ENABLE_L1_TLB					(1 << 0)
#define		ENABLE_L1_FRAGMENT_PROCESSING			(1 << 1)
#define		ENABLE_L1_STRICT_ORDERING			(1 << 2)
@@ -354,12 +355,14 @@
#define		EFFECTIVE_L1_QUEUE_SIZE(x)			(((x) & 7) << 15)
#define		EFFECTIVE_L1_QUEUE_SIZE_MASK			0x00038000
#define		EFFECTIVE_L1_QUEUE_SIZE_SHIFT			15
#define MC_VM_L1_TLB_MCD_RD_A_CNTL			0x219C
#define MC_VM_L1_TLB_MCD_RD_B_CNTL			0x21A0
#define MC_VM_L1_TLB_MCB_RD_GFX_CNTL			0x21FC
#define MC_VM_L1_TLB_MCB_RD_HDP_CNTL			0x2204
#define MC_VM_L1_TLB_MCB_RD_PDMA_CNTL			0x2208
#define MC_VM_L1_TLB_MCB_RD_SEM_CNTL			0x220C
#define	MC_VM_L1_TLB_MCB_RD_SYS_CNTL			0x2200
#define MC_VM_L1_TLB_MCB_WR_UVD_CNTL			0x212c
#define MC_VM_L1_TLB_MCD_WR_A_CNTL			0x21A4
#define MC_VM_L1_TLB_MCD_WR_B_CNTL			0x21A8
#define MC_VM_L1_TLB_MCB_WR_GFX_CNTL			0x2210
@@ -373,6 +376,8 @@
#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR			0x2194
#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR		0x2198

#define RS_DQ_RD_RET_CONF				0x2348

#define	PA_CL_ENHANCE					0x8A14
#define		CLIP_VTX_REORDER_ENA				(1 << 0)
#define		NUM_CLIP_SEQ(x)					((x) << 1)
@@ -1483,6 +1488,7 @@
#define UVD_CGC_GATE					0xf4a8
#define UVD_LMI_CTRL2					0xf4f4
#define UVD_MASTINT_EN					0xf500
#define UVD_FW_START					0xf51C
#define UVD_LMI_ADDR_EXT				0xf594
#define UVD_LMI_CTRL					0xf598
#define UVD_LMI_SWAP_CNTL				0xf5b4
@@ -1495,6 +1501,13 @@
#define UVD_MPC_SET_MUX					0xf5f4
#define UVD_MPC_SET_ALU					0xf5f8

#define UVD_VCPU_CACHE_OFFSET0				0xf608
#define UVD_VCPU_CACHE_SIZE0				0xf60c
#define UVD_VCPU_CACHE_OFFSET1				0xf610
#define UVD_VCPU_CACHE_SIZE1				0xf614
#define UVD_VCPU_CACHE_OFFSET2				0xf618
#define UVD_VCPU_CACHE_SIZE2				0xf61c

#define UVD_VCPU_CNTL					0xf660
#define UVD_SOFT_RESET					0xf680
#define		RBC_SOFT_RESET					(1<<0)
@@ -1524,9 +1537,35 @@

#define UVD_CONTEXT_ID					0xf6f4

/* rs780 only */
#define	GFX_MACRO_BYPASS_CNTL				0x30c0
#define		SPLL_BYPASS_CNTL			(1 << 0)
#define		UPLL_BYPASS_CNTL			(1 << 1)

#define CG_UPLL_FUNC_CNTL				0x7e0
#	define UPLL_RESET_MASK				0x00000001
#	define UPLL_SLEEP_MASK				0x00000002
#	define UPLL_BYPASS_EN_MASK			0x00000004
#	define UPLL_CTLREQ_MASK				0x00000008
#	define UPLL_FB_DIV(x)				((x) << 4)
#	define UPLL_FB_DIV_MASK				0x0000FFF0
#	define UPLL_REF_DIV(x)				((x) << 16)
#	define UPLL_REF_DIV_MASK			0x003F0000
#	define UPLL_REFCLK_SRC_SEL_MASK			0x20000000
#	define UPLL_CTLACK_MASK				0x40000000
#	define UPLL_CTLACK2_MASK			0x80000000
#define CG_UPLL_FUNC_CNTL_2				0x7e4
#	define UPLL_SW_HILEN(x)				((x) << 0)
#	define UPLL_SW_LOLEN(x)				((x) << 4)
#	define UPLL_SW_HILEN2(x)			((x) << 8)
#	define UPLL_SW_LOLEN2(x)			((x) << 12)
#	define UPLL_DIVEN_MASK				0x00010000
#	define UPLL_DIVEN2_MASK				0x00020000
#	define UPLL_SW_MASK				0x0003FFFF
#	define VCLK_SRC_SEL(x)				((x) << 20)
#	define VCLK_SRC_SEL_MASK			0x01F00000
#	define DCLK_SRC_SEL(x)				((x) << 25)
#	define DCLK_SRC_SEL_MASK			0x3E000000

/*
 * PM4
+4 −6
Original line number Diff line number Diff line
@@ -120,9 +120,6 @@ extern int radeon_bapm;
#define RADEONFB_CONN_LIMIT			4
#define RADEON_BIOS_NUM_SCRATCH			8

/* fence seq are set to this number when signaled */
#define RADEON_FENCE_SIGNALED_SEQ		0LL

/* internal ring indices */
/* r1xx+ has gfx CP ring */
#define RADEON_RING_TYPE_GFX_INDEX		0
@@ -350,6 +347,7 @@ extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
 * Fences.
 */
struct radeon_fence_driver {
	struct radeon_device		*rdev;
	uint32_t			scratch_reg;
	uint64_t			gpu_addr;
	volatile uint32_t		*cpu_addr;
@@ -357,6 +355,7 @@ struct radeon_fence_driver {
	uint64_t			sync_seq[RADEON_NUM_RINGS];
	atomic64_t			last_seq;
	bool				initialized;
	struct delayed_work		lockup_work;
};

struct radeon_fence {
@@ -371,7 +370,7 @@ struct radeon_fence {
int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
int radeon_fence_driver_init(struct radeon_device *rdev);
void radeon_fence_driver_fini(struct radeon_device *rdev);
void radeon_fence_driver_force_completion(struct radeon_device *rdev);
void radeon_fence_driver_force_completion(struct radeon_device *rdev, int ring);
int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, int ring);
void radeon_fence_process(struct radeon_device *rdev, int ring);
bool radeon_fence_signaled(struct radeon_fence *fence);
@@ -2326,7 +2325,7 @@ struct radeon_device {
	bool				need_dma32;
	bool				accel_working;
	bool				fastfb_working; /* IGP feature*/
	bool				needs_reset;
	bool				needs_reset, in_reset;
	struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
	const struct firmware *me_fw;	/* all family ME firmware */
	const struct firmware *pfp_fw;	/* r6/700 PFP firmware */
@@ -2347,7 +2346,6 @@ struct radeon_device {
	struct radeon_mec mec;
	struct work_struct hotplug_work;
	struct work_struct audio_work;
	struct work_struct reset_work;
	int num_crtc; /* number of crtcs */
	struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */
	bool has_uvd;
+24 −1
Original line number Diff line number Diff line
@@ -965,6 +965,19 @@ static struct radeon_asic r600_asic = {
	},
};

static struct radeon_asic_ring rv6xx_uvd_ring = {
	.ib_execute = &uvd_v1_0_ib_execute,
	.emit_fence = &uvd_v1_0_fence_emit,
	.emit_semaphore = &uvd_v1_0_semaphore_emit,
	.cs_parse = &radeon_uvd_cs_parse,
	.ring_test = &uvd_v1_0_ring_test,
	.ib_test = &uvd_v1_0_ib_test,
	.is_lockup = &radeon_ring_test_lockup,
	.get_rptr = &uvd_v1_0_get_rptr,
	.get_wptr = &uvd_v1_0_get_wptr,
	.set_wptr = &uvd_v1_0_set_wptr,
};

static struct radeon_asic rv6xx_asic = {
	.init = &r600_init,
	.fini = &r600_fini,
@@ -984,6 +997,7 @@ static struct radeon_asic rv6xx_asic = {
	.ring = {
		[RADEON_RING_TYPE_GFX_INDEX] = &r600_gfx_ring,
		[R600_RING_TYPE_DMA_INDEX] = &r600_dma_ring,
		[R600_RING_TYPE_UVD_INDEX] = &rv6xx_uvd_ring,
	},
	.irq = {
		.set = &r600_irq_set,
@@ -1074,6 +1088,7 @@ static struct radeon_asic rs780_asic = {
	.ring = {
		[RADEON_RING_TYPE_GFX_INDEX] = &r600_gfx_ring,
		[R600_RING_TYPE_DMA_INDEX] = &r600_dma_ring,
		[R600_RING_TYPE_UVD_INDEX] = &rv6xx_uvd_ring,
	},
	.irq = {
		.set = &r600_irq_set,
@@ -2298,6 +2313,14 @@ int radeon_asic_init(struct radeon_device *rdev)
	case CHIP_RS780:
	case CHIP_RS880:
		rdev->asic = &rs780_asic;
		/* 760G/780V/880V don't have UVD */
		if ((rdev->pdev->device == 0x9616)||
		    (rdev->pdev->device == 0x9611)||
		    (rdev->pdev->device == 0x9613)||
		    (rdev->pdev->device == 0x9711)||
		    (rdev->pdev->device == 0x9713))
			rdev->has_uvd = false;
		else
			rdev->has_uvd = true;
		break;
	case CHIP_RV770:
Loading