Commit 29e92559 authored by Jani Nikula's avatar Jani Nikula
Browse files

Merge tag 'topic/adl-s-enabling-2021-02-01-1' of...

Merge tag 'topic/adl-s-enabling-2021-02-01-1' of git://anongit.freedesktop.org/drm/drm-intel

 into drm-intel-next

Driver Changes:
  - Add basic support for Alder Lake S, to be shared between
  drm-intel-next and drm-intel-gt-next

Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>

# Conflicts:
#	drivers/gpu/drm/i915/i915_drv.h
From: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210202025620.2212559-1-lucas.demarchi@intel.com
parents 6ee8d381 4043277a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -551,6 +551,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = {
	INTEL_EHL_IDS(&gen11_early_ops),
	INTEL_TGL_12_IDS(&gen11_early_ops),
	INTEL_RKL_IDS(&gen11_early_ops),
	INTEL_ADLS_IDS(&gen11_early_ops),
};

struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0);
+58 −12
Original line number Diff line number Diff line
@@ -1630,12 +1630,23 @@ static const u8 rkl_pch_tgp_ddc_pin_map[] = {
	[RKL_DDC_BUS_DDI_E] = GMBUS_PIN_10_TC2_ICP,
};

static const u8 adls_ddc_pin_map[] = {
	[ICL_DDC_BUS_DDI_A] = GMBUS_PIN_1_BXT,
	[ADLS_DDC_BUS_PORT_TC1] = GMBUS_PIN_9_TC1_ICP,
	[ADLS_DDC_BUS_PORT_TC2] = GMBUS_PIN_10_TC2_ICP,
	[ADLS_DDC_BUS_PORT_TC3] = GMBUS_PIN_11_TC3_ICP,
	[ADLS_DDC_BUS_PORT_TC4] = GMBUS_PIN_12_TC4_ICP,
};

static u8 map_ddc_pin(struct drm_i915_private *dev_priv, u8 vbt_pin)
{
	const u8 *ddc_pin_map;
	int n_entries;

	if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) {
	if (HAS_PCH_ADP(dev_priv)) {
		ddc_pin_map = adls_ddc_pin_map;
		n_entries = ARRAY_SIZE(adls_ddc_pin_map);
	} else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) {
		return vbt_pin;
	} else if (IS_ROCKETLAKE(dev_priv) && INTEL_PCH_TYPE(dev_priv) == PCH_TGP) {
		ddc_pin_map = rkl_pch_tgp_ddc_pin_map;
@@ -1708,8 +1719,26 @@ static enum port dvo_port_to_port(struct drm_i915_private *dev_priv,
		[PORT_TC1] = { DVO_PORT_HDMIC, DVO_PORT_DPC, -1 },
		[PORT_TC2] = { DVO_PORT_HDMID, DVO_PORT_DPD, -1 },
	};
	/*
	 * Alderlake S ports used in the driver are PORT_A, PORT_D, PORT_E,
	 * PORT_F and PORT_G, we need to map that to correct VBT sections.
	 */
	static const int adls_port_mapping[][3] = {
		[PORT_A] = { DVO_PORT_HDMIA, DVO_PORT_DPA, -1 },
		[PORT_B] = { -1 },
		[PORT_C] = { -1 },
		[PORT_TC1] = { DVO_PORT_HDMIB, DVO_PORT_DPB, -1 },
		[PORT_TC2] = { DVO_PORT_HDMIC, DVO_PORT_DPC, -1 },
		[PORT_TC3] = { DVO_PORT_HDMID, DVO_PORT_DPD, -1 },
		[PORT_TC4] = { DVO_PORT_HDMIE, DVO_PORT_DPE, -1 },
	};

	if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
	if (IS_ALDERLAKE_S(dev_priv))
		return __dvo_port_to_port(ARRAY_SIZE(adls_port_mapping),
					  ARRAY_SIZE(adls_port_mapping[0]),
					  adls_port_mapping,
					  dvo_port);
	else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
		return __dvo_port_to_port(ARRAY_SIZE(rkl_port_mapping),
					  ARRAY_SIZE(rkl_port_mapping[0]),
					  rkl_port_mapping,
@@ -2661,26 +2690,43 @@ enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *dev_priv,
		return aux_ch;
	}

	/*
	 * RKL/DG1 VBT uses PHY based mapping. Combo PHYs A,B,C,D
	 * map to DDI A,B,TC1,TC2 respectively.
	 *
	 * ADL-S VBT uses PHY based mapping. Combo PHYs A,B,C,D,E
	 * map to DDI A,TC1,TC2,TC3,TC4 respectively.
	 */
	switch (info->alternate_aux_channel) {
	case DP_AUX_A:
		aux_ch = AUX_CH_A;
		break;
	case DP_AUX_B:
		if (IS_ALDERLAKE_S(dev_priv))
			aux_ch = AUX_CH_USBC1;
		else
			aux_ch = AUX_CH_B;
		break;
	case DP_AUX_C:
		/*
		 * RKL/DG1 VBT uses PHY based mapping. Combo PHYs A,B,C,D
		 * map to DDI A,B,TC1,TC2 respectively.
		 */
		aux_ch = (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) ?
			AUX_CH_USBC1 : AUX_CH_C;
		if (IS_ALDERLAKE_S(dev_priv))
			aux_ch = AUX_CH_USBC2;
		else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
			aux_ch = AUX_CH_USBC1;
		else
			aux_ch = AUX_CH_C;
		break;
	case DP_AUX_D:
		aux_ch = (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) ?
			AUX_CH_USBC2 : AUX_CH_D;
		if (IS_ALDERLAKE_S(dev_priv))
			aux_ch = AUX_CH_USBC3;
		else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
			aux_ch = AUX_CH_USBC2;
		else
			aux_ch = AUX_CH_D;
		break;
	case DP_AUX_E:
		if (IS_ALDERLAKE_S(dev_priv))
			aux_ch = AUX_CH_USBC4;
		else
			aux_ch = AUX_CH_E;
		break;
	case DP_AUX_F:
+9 −1
Original line number Diff line number Diff line
@@ -142,6 +142,12 @@ static const struct intel_sa_info rkl_sa_info = {
	.displayrtids = 128,
};

static const struct intel_sa_info adls_sa_info = {
	.deburst = 16,
	.deprogbwlimit = 38, /* GB/s */
	.displayrtids = 256,
};

static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa)
{
	struct intel_qgv_info qi = {};
@@ -251,7 +257,9 @@ void intel_bw_init_hw(struct drm_i915_private *dev_priv)
	if (!HAS_DISPLAY(dev_priv))
		return;

	if (IS_ROCKETLAKE(dev_priv))
	if (IS_ALDERLAKE_S(dev_priv))
		icl_get_bw_info(dev_priv, &adls_sa_info);
	else if (IS_ROCKETLAKE(dev_priv))
		icl_get_bw_info(dev_priv, &rkl_sa_info);
	else if (IS_GEN(dev_priv, 12))
		icl_get_bw_info(dev_priv, &tgl_sa_info);
+18 −5
Original line number Diff line number Diff line
@@ -187,8 +187,14 @@ static bool has_phy_misc(struct drm_i915_private *i915, enum phy phy)
	 * Some platforms only expect PHY_MISC to be programmed for PHY-A and
	 * PHY-B and may not even have instances of the register for the
	 * other combo PHY's.
	 *
	 * ADL-S technically has three instances of PHY_MISC, but only requires
	 * that we program it for PHY A.
	 */
	if (IS_JSL_EHL(i915) ||

	if (IS_ALDERLAKE_S(i915))
		return phy == PHY_A;
	else if (IS_JSL_EHL(i915) ||
		 IS_ROCKETLAKE(i915) ||
		 IS_DG1(i915))
		return phy < PHY_C;
@@ -246,14 +252,21 @@ static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy)
	 * RKL,DG1:
	 *   A(master) -> B(slave)
	 *   C(master) -> D(slave)
	 * ADL-S:
	 *   A(master) -> B(slave), C(slave)
	 *   D(master) -> E(slave)
	 *
	 * We must set the IREFGEN bit for any PHY acting as a master
	 * to another PHY.
	 */
	if ((IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv)) && phy == PHY_C)
	if (phy == PHY_A)
		return true;
	else if (IS_ALDERLAKE_S(dev_priv))
		return phy == PHY_D;
	else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
		return phy == PHY_C;

	return phy == PHY_A;
	return false;
}

static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
+9 −1
Original line number Diff line number Diff line
@@ -40,6 +40,10 @@

#define GEN12_CSR_MAX_FW_SIZE		ICL_CSR_MAX_FW_SIZE

#define ADLS_CSR_PATH			"i915/adls_dmc_ver2_01.bin"
#define ADLS_CSR_VERSION_REQUIRED	CSR_VERSION(2, 1)
MODULE_FIRMWARE(ADLS_CSR_PATH);

#define DG1_CSR_PATH			"i915/dg1_dmc_ver2_02.bin"
#define DG1_CSR_VERSION_REQUIRED	CSR_VERSION(2, 2)
MODULE_FIRMWARE(DG1_CSR_PATH);
@@ -689,7 +693,11 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv)
	 */
	intel_csr_runtime_pm_get(dev_priv);

	if (IS_DG1(dev_priv)) {
	if (IS_ALDERLAKE_S(dev_priv)) {
		csr->fw_path = ADLS_CSR_PATH;
		csr->required_version = ADLS_CSR_VERSION_REQUIRED;
		csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
	} else if (IS_DG1(dev_priv)) {
		csr->fw_path = DG1_CSR_PATH;
		csr->required_version = DG1_CSR_VERSION_REQUIRED;
		csr->max_fw_size = GEN12_CSR_MAX_FW_SIZE;
Loading