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

Commit 09fa3022 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-radeon-sitn-support' of git://people.freedesktop.org/~airlied/linux

Pull radeon southern islands / trinity support from Dave Airlie:
 "This is support from AMD for their newest GPU and APUs.  The products
  called RadeonHD 7xxx, and the Trinity APU series.

  This did come in a bit late, due to some over-complicated AMD internal
  review process, which from the outside seems unnecessary once the
  company has decided it wants to support open source.  However as I
  said previously I'd rather not put the people who've got this hw for 3
  months now being forced to use fglrx on it if there is open code.

  Its pretty well self contained and just plugs into the driver in
  various places."

* 'drm-radeon-sitn-support' of git://people.freedesktop.org/~airlied/linux: (48 commits)
  drm/radeon/kms: update duallink checks for DCE6
  drm/radeon/kms: add trinity pci ids
  drm/radeon/kms: add radeon_asic struct for trinity
  drm/radeon/kms: add support for ucode loading on trinity (v2)
  drm/radeon/kms/vm: set vram base offset properly for TN
  drm/radeon/kms: Update evergreen functions for trinity
  drm/radeon/kms: cayman gpu init updates for trinity
  drm/radeon/kms: Add checks for TN in the DP bridge code
  drm/radeon/kms/DCE6.1: ss is not supported on the internal pplls
  drm/radeon/kms: disable PPLL0 on DCE6.1 when not in use
  drm/radeon/kms: Adjust pll picker for DCE6.1
  drm/radeon/kms: DCE6.1 disp eng pll updates
  drm/radeon/kms: DCE6.1 watermark updates for TN
  drm/radeon/kms: no support for internal thermal sensor on TN yet
  drm/radeon/kms: add trinity (TN) chip family
  drm/radeon/kms: Add SI pci ids
  drm/radeon: Update radeon_info_ioctl for SI. (v2)
  drm/radeon/kms: add radeon_asic struct for SI
  drm/radeon/kms: add support for compute rings in CS ioctl on SI
  drm/radeon/kms: fill in startup/shutdown callbacks for SI
  ...
parents be53bfdb 1b2681ba
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
	r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
	evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
	radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \
	radeon_semaphore.o radeon_sa.o atombios_i2c.o
	radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o si_blit_shaders.o

radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
+5 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@
#define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA   0x1F
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1        0x20
#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2        0x21
#define ENCODER_OBJECT_ID_INTERNAL_VCE            0x24

#define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO    0xFF

@@ -387,6 +388,10 @@
                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                  ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT)

#define ENCODER_VCE_ENUM_ID1                     ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                  ENCODER_OBJECT_ID_INTERNAL_VCE << OBJECT_ID_SHIFT)

/****************************************************/
/* Connector Object ID definition - Shared with BIOS */
/****************************************************/
+1048 −61

File changed.

Preview size limit exceeded, changes collapsed.

+91 −9
Original line number Diff line number Diff line
@@ -231,6 +231,22 @@ static void atombios_blank_crtc(struct drm_crtc *crtc, int state)
	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}

static void atombios_powergate_crtc(struct drm_crtc *crtc, int state)
{
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
	struct drm_device *dev = crtc->dev;
	struct radeon_device *rdev = dev->dev_private;
	int index = GetIndexIntoMasterTable(COMMAND, EnableDispPowerGating);
	ENABLE_DISP_POWER_GATING_PARAMETERS_V2_1 args;

	memset(&args, 0, sizeof(args));

	args.ucDispPipeId = radeon_crtc->crtc_id;
	args.ucEnable = state;

	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
}

void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
{
	struct drm_device *dev = crtc->dev;
@@ -242,8 +258,11 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
		radeon_crtc->enabled = true;
		/* adjust pm to dpms changes BEFORE enabling crtcs */
		radeon_pm_compute_clocks(rdev);
		/* disable crtc pair power gating before programming */
		if (ASIC_IS_DCE6(rdev))
			atombios_powergate_crtc(crtc, ATOM_DISABLE);
		atombios_enable_crtc(crtc, ATOM_ENABLE);
		if (ASIC_IS_DCE3(rdev))
		if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
			atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
		atombios_blank_crtc(crtc, ATOM_DISABLE);
		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
@@ -255,10 +274,29 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
		drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
		if (radeon_crtc->enabled)
			atombios_blank_crtc(crtc, ATOM_ENABLE);
		if (ASIC_IS_DCE3(rdev))
		if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev))
			atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
		atombios_enable_crtc(crtc, ATOM_DISABLE);
		radeon_crtc->enabled = false;
		/* power gating is per-pair */
		if (ASIC_IS_DCE6(rdev)) {
			struct drm_crtc *other_crtc;
			struct radeon_crtc *other_radeon_crtc;
			list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) {
				other_radeon_crtc = to_radeon_crtc(other_crtc);
				if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) ||
				    ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) ||
				    ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) ||
				    ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) ||
				    ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) ||
				    ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) {
					/* if both crtcs in the pair are off, enable power gating */
					if (other_radeon_crtc->enabled == false)
						atombios_powergate_crtc(crtc, ATOM_ENABLE);
					break;
				}
			}
		}
		/* adjust pm to dpms changes AFTER disabling crtcs */
		radeon_pm_compute_clocks(rdev);
		break;
@@ -436,7 +474,7 @@ static void atombios_crtc_program_ss(struct radeon_device *rdev,
			return;
		}
		args.v3.ucEnable = enable;
		if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK))
		if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE61(rdev))
			args.v3.ucEnable = ATOM_DISABLE;
	} else if (ASIC_IS_DCE4(rdev)) {
		args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
@@ -699,7 +737,7 @@ union set_pixel_clock {
/* on DCE5, make sure the voltage is high enough to support the
 * required disp clk.
 */
static void atombios_crtc_set_dcpll(struct radeon_device *rdev,
static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev,
				    u32 dispclk)
{
	u8 frev, crev;
@@ -729,6 +767,11 @@ static void atombios_crtc_set_dcpll(struct radeon_device *rdev,
			 * SetPixelClock provides the dividers
			 */
			args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
			if (ASIC_IS_DCE61(rdev))
				args.v6.ucPpll = ATOM_EXT_PLL1;
			else if (ASIC_IS_DCE6(rdev))
				args.v6.ucPpll = ATOM_PPLL0;
			else
				args.v6.ucPpll = ATOM_DCPLL;
			break;
		default:
@@ -1444,7 +1487,36 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
	struct drm_crtc *test_crtc;
	uint32_t pll_in_use = 0;

	if (ASIC_IS_DCE4(rdev)) {
	if (ASIC_IS_DCE61(rdev)) {
		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
				struct radeon_encoder *test_radeon_encoder =
					to_radeon_encoder(test_encoder);
				struct radeon_encoder_atom_dig *dig =
					test_radeon_encoder->enc_priv;

				if ((test_radeon_encoder->encoder_id ==
				     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
				    (dig->linkb == false)) /* UNIPHY A uses PPLL2 */
					return ATOM_PPLL2;
			}
		}
		/* UNIPHY B/C/D/E/F */
		list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
			struct radeon_crtc *radeon_test_crtc;

			if (crtc == test_crtc)
				continue;

			radeon_test_crtc = to_radeon_crtc(test_crtc);
			if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
			    (radeon_test_crtc->pll_id == ATOM_PPLL1))
				pll_in_use |= (1 << radeon_test_crtc->pll_id);
		}
		if (!(pll_in_use & 4))
			return ATOM_PPLL0;
		return ATOM_PPLL1;
	} else if (ASIC_IS_DCE4(rdev)) {
		list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
			if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
				/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
@@ -1483,10 +1555,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)

}

void radeon_atom_dcpll_init(struct radeon_device *rdev)
void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev)
{
	/* always set DCPLL */
	if (ASIC_IS_DCE4(rdev)) {
	if (ASIC_IS_DCE6(rdev))
		atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
	else if (ASIC_IS_DCE4(rdev)) {
		struct radeon_atom_ss ss;
		bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss,
								   ASIC_INTERNAL_SS_ON_DCPLL,
@@ -1494,7 +1568,7 @@ void radeon_atom_dcpll_init(struct radeon_device *rdev)
		if (ss_enabled)
			atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss);
		/* XXX: DCE5, make sure voltage, dispclk is high enough */
		atombios_crtc_set_dcpll(rdev, rdev->clock.default_dispclk);
		atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk);
		if (ss_enabled)
			atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss);
	}
@@ -1572,6 +1646,8 @@ static void atombios_crtc_commit(struct drm_crtc *crtc)
static void atombios_crtc_disable(struct drm_crtc *crtc)
{
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
	struct drm_device *dev = crtc->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_atom_ss ss;

	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
@@ -1583,6 +1659,12 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
		atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
					  0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
		break;
	case ATOM_PPLL0:
		/* disable the ppll */
		if (ASIC_IS_DCE61(rdev))
			atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
						  0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
		break;
	default:
		break;
	}
+3 −3
Original line number Diff line number Diff line
@@ -63,12 +63,12 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,

	memset(&args, 0, sizeof(args));

	base = (unsigned char *)rdev->mode_info.atom_context->scratch;
	base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);

	memcpy(base, send, send_bytes);

	args.v1.lpAuxRequest = 0;
	args.v1.lpDataOut = 16;
	args.v1.lpAuxRequest = 0 + 4;
	args.v1.lpDataOut = 16 + 4;
	args.v1.ucDataOutLen = 0;
	args.v1.ucChannelID = chan->rec.i2c_id;
	args.v1.ucDelay = delay / 10;
Loading