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

Commit ea996978 authored by Dave Airlie's avatar Dave Airlie
Browse files

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

A few fixes for 4.6.
- revert amdgpu PX commit that was previously reverted on the radeon side
- cleaned up version of the NI+ MC update display fix for radeon
- TTM kref fix

* 'drm-fixes-4.6' of git://people.freedesktop.org/~agd5f/linux:
  drm/amdgpu: disable vm interrupts with vm_fault_stop=2
  drm/amdgpu: print a message if ATPX dGPU power control is missing
  Revert "drm/amdgpu: disable runtime pm on PX laptops without dGPU power control"
  drm/radeon: fix vertical bars appear on monitor (v2)
  drm/ttm: fix kref count mess in ttm_bo_move_to_lru_tail
parents d8ba5d60 afc45421
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -63,10 +63,6 @@ bool amdgpu_has_atpx(void) {
	return amdgpu_atpx_priv.atpx_detected;
}

bool amdgpu_has_atpx_dgpu_power_cntl(void) {
	return amdgpu_atpx_priv.atpx.functions.power_cntl;
}

/**
 * amdgpu_atpx_call - call an ATPX method
 *
@@ -146,6 +142,13 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas
 */
static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
{
	/* make sure required functions are enabled */
	/* dGPU power control is required */
	if (atpx->functions.power_cntl == false) {
		printk("ATPX dGPU power cntl not present, forcing\n");
		atpx->functions.power_cntl = true;
	}

	if (atpx->functions.px_params) {
		union acpi_object *info;
		struct atpx_px_params output;
+1 −7
Original line number Diff line number Diff line
@@ -62,12 +62,6 @@ static const char *amdgpu_asic_name[] = {
	"LAST",
};

#if defined(CONFIG_VGA_SWITCHEROO)
bool amdgpu_has_atpx_dgpu_power_cntl(void);
#else
static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; }
#endif

bool amdgpu_device_is_px(struct drm_device *dev)
{
	struct amdgpu_device *adev = dev->dev_private;
@@ -1485,7 +1479,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,

	if (amdgpu_runtime_pm == 1)
		runtime = true;
	if (amdgpu_device_is_px(ddev) && amdgpu_has_atpx_dgpu_power_cntl())
	if (amdgpu_device_is_px(ddev))
		runtime = true;
	vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime);
	if (runtime)
+4 −1
Original line number Diff line number Diff line
@@ -910,7 +910,10 @@ static int gmc_v7_0_late_init(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
		return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
	else
		return 0;
}

static int gmc_v7_0_sw_init(void *handle)
+4 −1
Original line number Diff line number Diff line
@@ -870,7 +870,10 @@ static int gmc_v8_0_late_init(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (amdgpu_vm_fault_stop != AMDGPU_VM_FAULT_STOP_ALWAYS)
		return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0);
	else
		return 0;
}

#define mmMC_SEQ_MISC0_FIJI 0xA71
+153 −1
Original line number Diff line number Diff line
@@ -2608,10 +2608,152 @@ static void evergreen_agp_enable(struct radeon_device *rdev)
	WREG32(VM_CONTEXT1_CNTL, 0);
}

static const unsigned ni_dig_offsets[] =
{
	NI_DIG0_REGISTER_OFFSET,
	NI_DIG1_REGISTER_OFFSET,
	NI_DIG2_REGISTER_OFFSET,
	NI_DIG3_REGISTER_OFFSET,
	NI_DIG4_REGISTER_OFFSET,
	NI_DIG5_REGISTER_OFFSET
};

static const unsigned ni_tx_offsets[] =
{
	NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1,
	NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1,
	NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1,
	NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1,
	NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1,
	NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1
};

static const unsigned evergreen_dp_offsets[] =
{
	EVERGREEN_DP0_REGISTER_OFFSET,
	EVERGREEN_DP1_REGISTER_OFFSET,
	EVERGREEN_DP2_REGISTER_OFFSET,
	EVERGREEN_DP3_REGISTER_OFFSET,
	EVERGREEN_DP4_REGISTER_OFFSET,
	EVERGREEN_DP5_REGISTER_OFFSET
};


/*
 * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc
 * We go from crtc to connector and it is not relible  since it
 * should be an opposite direction .If crtc is enable then
 * find the dig_fe which selects this crtc and insure that it enable.
 * if such dig_fe is found then find dig_be which selects found dig_be and
 * insure that it enable and in DP_SST mode.
 * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing
 * from dp symbols clocks .
 */
static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev,
					       unsigned crtc_id, unsigned *ret_dig_fe)
{
	unsigned i;
	unsigned dig_fe;
	unsigned dig_be;
	unsigned dig_en_be;
	unsigned uniphy_pll;
	unsigned digs_fe_selected;
	unsigned dig_be_mode;
	unsigned dig_fe_mask;
	bool is_enabled = false;
	bool found_crtc = false;

	/* loop through all running dig_fe to find selected crtc */
	for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
		dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]);
		if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON &&
		    crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) {
			/* found running pipe */
			found_crtc = true;
			dig_fe_mask = 1 << i;
			dig_fe = i;
			break;
		}
	}

	if (found_crtc) {
		/* loop through all running dig_be to find selected dig_fe */
		for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
			dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]);
			/* if dig_fe_selected by dig_be? */
			digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be);
			dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be);
			if (dig_fe_mask &  digs_fe_selected &&
			    /* if dig_be in sst mode? */
			    dig_be_mode == NI_DIG_BE_DPSST) {
				dig_en_be = RREG32(NI_DIG_BE_EN_CNTL +
						   ni_dig_offsets[i]);
				uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 +
						    ni_tx_offsets[i]);
				/* dig_be enable and tx is running */
				if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE &&
				    dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON &&
				    uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) {
					is_enabled = true;
					*ret_dig_fe = dig_fe;
					break;
				}
			}
		}
	}

	return is_enabled;
}

/*
 * Blank dig when in dp sst mode
 * Dig ignores crtc timing
 */
static void evergreen_blank_dp_output(struct radeon_device *rdev,
				      unsigned dig_fe)
{
	unsigned stream_ctrl;
	unsigned fifo_ctrl;
	unsigned counter = 0;

	if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) {
		DRM_ERROR("invalid dig_fe %d\n", dig_fe);
		return;
	}

	stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
			     evergreen_dp_offsets[dig_fe]);
	if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) {
		DRM_ERROR("dig %d , should be enable\n", dig_fe);
		return;
	}

	stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE;
	WREG32(EVERGREEN_DP_VID_STREAM_CNTL +
	       evergreen_dp_offsets[dig_fe], stream_ctrl);

	stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
			     evergreen_dp_offsets[dig_fe]);
	while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) {
		msleep(1);
		counter++;
		stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
				     evergreen_dp_offsets[dig_fe]);
	}
	if (counter >= 32 )
		DRM_ERROR("counter exceeds %d\n", counter);

	fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]);
	fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET;
	WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl);

}

void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
{
	u32 crtc_enabled, tmp, frame_count, blackout;
	int i, j;
	unsigned dig_fe;

	if (!ASIC_IS_NODCE(rdev)) {
		save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
@@ -2651,7 +2793,17 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
					break;
				udelay(1);
			}

			/*we should disable dig if it drives dp sst*/
			/*but we are in radeon_device_init and the topology is unknown*/
			/*and it is available after radeon_modeset_init*/
			/*the following method radeon_atom_encoder_dpms_dig*/
			/*does the job if we initialize it properly*/
			/*for now we do it this manually*/
			/**/
			if (ASIC_IS_DCE5(rdev) &&
			    evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe))
				evergreen_blank_dp_output(rdev, dig_fe);
			/*we could remove 6 lines below*/
			/* XXX this is a hack to avoid strange behavior with EFI on certain systems */
			WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
			tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
Loading