// SPDX-License-Identifier: MIT
/*
 * Copyright © 2018 Intel Corporation
 */

#include "intel_combo_phy.h"
#include "intel_display_types.h"

#define for_each_combo_phy(__dev_priv, __phy) \
	for ((__phy) = PHY_A; (__phy) < I915_MAX_PHYS; (__phy)++)	\
		for_each_if(intel_phy_is_combo(__dev_priv, __phy))

#define for_each_combo_phy_reverse(__dev_priv, __phy) \
	for ((__phy) = I915_MAX_PHYS; (__phy)-- > PHY_A;) \
		for_each_if(intel_phy_is_combo(__dev_priv, __phy))

enum {
	PROCMON_0_85V_DOT_0,
	PROCMON_0_95V_DOT_0,
	PROCMON_0_95V_DOT_1,
	PROCMON_1_05V_DOT_0,
	PROCMON_1_05V_DOT_1,
};

static const struct cnl_procmon {
	u32 dw1, dw9, dw10;
} cnl_procmon_values[] = {
	[PROCMON_0_85V_DOT_0] =
		{ .dw1 = 0x00000000, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96, },
	[PROCMON_0_95V_DOT_0] =
		{ .dw1 = 0x00000000, .dw9 = 0x86E172C7, .dw10 = 0x77CA5EAB, },
	[PROCMON_0_95V_DOT_1] =
		{ .dw1 = 0x00000000, .dw9 = 0x93F87FE1, .dw10 = 0x8AE871C5, },
	[PROCMON_1_05V_DOT_0] =
		{ .dw1 = 0x00000000, .dw9 = 0x98FA82DD, .dw10 = 0x89E46DC1, },
	[PROCMON_1_05V_DOT_1] =
		{ .dw1 = 0x00440000, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1, },
};

/*
 * CNL has just one set of registers, while gen11 has a set for each combo PHY.
 * The CNL registers are equivalent to the gen11 PHY A registers, that's why we
 * call the ICL macros even though the function has CNL on its name.
 */
static const struct cnl_procmon *
cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
{
	const struct cnl_procmon *procmon;
	u32 val;

	val = intel_de_read(dev_priv, ICL_PORT_COMP_DW3(phy));
	switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) {
	default:
		MISSING_CASE(val);
		fallthrough;
	case VOLTAGE_INFO_0_85V | PROCESS_INFO_DOT_0:
		procmon = &cnl_procmon_values[PROCMON_0_85V_DOT_0];
		break;
	case VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_0:
		procmon = &cnl_procmon_values[PROCMON_0_95V_DOT_0];
		break;
	case VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_1:
		procmon = &cnl_procmon_values[PROCMON_0_95V_DOT_1];
		break;
	case VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_0:
		procmon = &cnl_procmon_values[PROCMON_1_05V_DOT_0];
		break;
	case VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_1:
		procmon = &cnl_procmon_values[PROCMON_1_05V_DOT_1];
		break;
	}

	return procmon;
}

static void cnl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
				       enum phy phy)
{
	const struct cnl_procmon *procmon;
	u32 val;

	procmon = cnl_get_procmon_ref_values(dev_priv, phy);

	val = intel_de_read(dev_priv, ICL_PORT_COMP_DW1(phy));
	val &= ~((0xff << 16) | 0xff);
	val |= procmon->dw1;
	intel_de_write(dev_priv, ICL_PORT_COMP_DW1(phy), val);

	intel_de_write(dev_priv, ICL_PORT_COMP_DW9(phy), procmon->dw9);
	intel_de_write(dev_priv, ICL_PORT_COMP_DW10(phy), procmon->dw10);
}

static bool check_phy_reg(struct drm_i915_private *dev_priv,
			  enum phy phy, i915_reg_t reg, u32 mask,
			  u32 expected_val)
{
	u32 val = intel_de_read(dev_priv, reg);

	if ((val & mask) != expected_val) {
		drm_dbg(&dev_priv->drm,
			"Combo PHY %c reg %08x state mismatch: "
			"current %08x mask %08x expected %08x\n",
			phy_name(phy),
			reg.reg, val, mask, expected_val);
		return false;
	}

	return true;
}

static bool cnl_verify_procmon_ref_values(struct drm_i915_private *dev_priv,
					  enum phy phy)
{
	const struct cnl_procmon *procmon;
	bool ret;

	procmon = cnl_get_procmon_ref_values(dev_priv, phy);

	ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
			    (0xff << 16) | 0xff, procmon->dw1);
	ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
			     -1U, procmon->dw9);
	ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW10(phy),
			     -1U, procmon->dw10);

	return ret;
}

static bool cnl_combo_phy_enabled(struct drm_i915_private *dev_priv)
{
	return !(intel_de_read(dev_priv, CHICKEN_MISC_2) & CNL_COMP_PWR_DOWN) &&
		(intel_de_read(dev_priv, CNL_PORT_COMP_DW0) & COMP_INIT);
}

static bool cnl_combo_phy_verify_state(struct drm_i915_private *dev_priv)
{
	enum phy phy = PHY_A;
	bool ret;

	if (!cnl_combo_phy_enabled(dev_priv))
		return false;

	ret = cnl_verify_procmon_ref_values(dev_priv, phy);

	ret &= check_phy_reg(dev_priv, phy, CNL_PORT_CL1CM_DW5,
			     CL_POWER_DOWN_ENABLE, CL_POWER_DOWN_ENABLE);

	return ret;
}

static void cnl_combo_phys_init(struct drm_i915_private *dev_priv)
{
	u32 val;

	val = intel_de_read(dev_priv, CHICKEN_MISC_2);
	val &= ~CNL_COMP_PWR_DOWN;
	intel_de_write(dev_priv, CHICKEN_MISC_2, val);

	/* Dummy PORT_A to get the correct CNL register from the ICL macro */
	cnl_set_procmon_ref_values(dev_priv, PHY_A);

	val = intel_de_read(dev_priv, CNL_PORT_COMP_DW0);
	val |= COMP_INIT;
	intel_de_write(dev_priv, CNL_PORT_COMP_DW0, val);

	val = intel_de_read(dev_priv, CNL_PORT_CL1CM_DW5);
	val |= CL_POWER_DOWN_ENABLE;
	intel_de_write(dev_priv, CNL_PORT_CL1CM_DW5, val);
}

static void cnl_combo_phys_uninit(struct drm_i915_private *dev_priv)
{
	u32 val;

	if (!cnl_combo_phy_verify_state(dev_priv))
		drm_warn(&dev_priv->drm,
			 "Combo PHY HW state changed unexpectedly.\n");

	val = intel_de_read(dev_priv, CHICKEN_MISC_2);
	val |= CNL_COMP_PWR_DOWN;
	intel_de_write(dev_priv, CHICKEN_MISC_2, val);
}

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.
	 */
	if (IS_ELKHARTLAKE(i915) ||
	    IS_ROCKETLAKE(i915))
		return phy < PHY_C;

	return true;
}

static bool icl_combo_phy_enabled(struct drm_i915_private *dev_priv,
				  enum phy phy)
{
	/* The PHY C added by EHL has no PHY_MISC register */
	if (!has_phy_misc(dev_priv, phy))
		return intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy)) & COMP_INIT;
	else
		return !(intel_de_read(dev_priv, ICL_PHY_MISC(phy)) &
			 ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN) &&
			(intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy)) & COMP_INIT);
}

static bool ehl_vbt_ddi_d_present(struct drm_i915_private *i915)
{
	bool ddi_a_present = intel_bios_is_port_present(i915, PORT_A);
	bool ddi_d_present = intel_bios_is_port_present(i915, PORT_D);
	bool dsi_present = intel_bios_is_dsi_present(i915, NULL);

	/*
	 * VBT's 'dvo port' field for child devices references the DDI, not
	 * the PHY.  So if combo PHY A is wired up to drive an external
	 * display, we should see a child device present on PORT_D and
	 * nothing on PORT_A and no DSI.
	 */
	if (ddi_d_present && !ddi_a_present && !dsi_present)
		return true;

	/*
	 * If we encounter a VBT that claims to have an external display on
	 * DDI-D _and_ an internal display on DDI-A/DSI leave an error message
	 * in the log and let the internal display win.
	 */
	if (ddi_d_present)
		drm_err(&i915->drm,
			"VBT claims to have both internal and external displays on PHY A.  Configuring for internal.\n");

	return false;
}

static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy)
{
	/*
	 * Certain PHYs are connected to compensation resistors and act
	 * as masters to other PHYs.
	 *
	 * ICL,TGL:
	 *   A(master) -> B(slave), C(slave)
	 * RKL:
	 *   A(master) -> B(slave)
	 *   C(master) -> D(slave)
	 *
	 * We must set the IREFGEN bit for any PHY acting as a master
	 * to another PHY.
	 */
	if (IS_ROCKETLAKE(dev_priv) && phy == PHY_C)
		return true;

	return phy == PHY_A;
}

static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
				       enum phy phy)
{
	bool ret = true;
	u32 expected_val = 0;

	if (!icl_combo_phy_enabled(dev_priv, phy))
		return false;

	if (INTEL_GEN(dev_priv) >= 12) {
		ret &= check_phy_reg(dev_priv, phy, ICL_PORT_TX_DW8_LN0(phy),
				     ICL_PORT_TX_DW8_ODCC_CLK_SEL |
				     ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK,
				     ICL_PORT_TX_DW8_ODCC_CLK_SEL |
				     ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2);

		ret &= check_phy_reg(dev_priv, phy, ICL_PORT_PCS_DW1_LN0(phy),
				     DCC_MODE_SELECT_MASK,
				     DCC_MODE_SELECT_CONTINUOSLY);
	}

	ret &= cnl_verify_procmon_ref_values(dev_priv, phy);

	if (phy_is_master(dev_priv, phy)) {
		ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW8(phy),
				     IREFGEN, IREFGEN);

		if (IS_ELKHARTLAKE(dev_priv)) {
			if (ehl_vbt_ddi_d_present(dev_priv))
				expected_val = ICL_PHY_MISC_MUX_DDID;

			ret &= check_phy_reg(dev_priv, phy, ICL_PHY_MISC(phy),
					     ICL_PHY_MISC_MUX_DDID,
					     expected_val);
		}
	}

	ret &= check_phy_reg(dev_priv, phy, ICL_PORT_CL_DW5(phy),
			     CL_POWER_DOWN_ENABLE, CL_POWER_DOWN_ENABLE);

	return ret;
}

void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
				    enum phy phy, bool is_dsi,
				    int lane_count, bool lane_reversal)
{
	u8 lane_mask;
	u32 val;

	if (is_dsi) {
		drm_WARN_ON(&dev_priv->drm, lane_reversal);

		switch (lane_count) {
		case 1:
			lane_mask = PWR_DOWN_LN_3_1_0;
			break;
		case 2:
			lane_mask = PWR_DOWN_LN_3_1;
			break;
		case 3:
			lane_mask = PWR_DOWN_LN_3;
			break;
		default:
			MISSING_CASE(lane_count);
			fallthrough;
		case 4:
			lane_mask = PWR_UP_ALL_LANES;
			break;
		}
	} else {
		switch (lane_count) {
		case 1:
			lane_mask = lane_reversal ? PWR_DOWN_LN_2_1_0 :
						    PWR_DOWN_LN_3_2_1;
			break;
		case 2:
			lane_mask = lane_reversal ? PWR_DOWN_LN_1_0 :
						    PWR_DOWN_LN_3_2;
			break;
		default:
			MISSING_CASE(lane_count);
			fallthrough;
		case 4:
			lane_mask = PWR_UP_ALL_LANES;
			break;
		}
	}

	val = intel_de_read(dev_priv, ICL_PORT_CL_DW10(phy));
	val &= ~PWR_DOWN_LN_MASK;
	val |= lane_mask << PWR_DOWN_LN_SHIFT;
	intel_de_write(dev_priv, ICL_PORT_CL_DW10(phy), val);
}

static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
{
	enum phy phy;

	for_each_combo_phy(dev_priv, phy) {
		u32 val;

		if (icl_combo_phy_verify_state(dev_priv, phy)) {
			drm_dbg(&dev_priv->drm,
				"Combo PHY %c already enabled, won't reprogram it.\n",
				phy_name(phy));
			continue;
		}

		if (!has_phy_misc(dev_priv, phy))
			goto skip_phy_misc;

		/*
		 * EHL's combo PHY A can be hooked up to either an external
		 * display (via DDI-D) or an internal display (via DDI-A or
		 * the DSI DPHY).  This is a motherboard design decision that
		 * can't be changed on the fly, so initialize the PHY's mux
		 * based on whether our VBT indicates the presence of any
		 * "internal" child devices.
		 */
		val = intel_de_read(dev_priv, ICL_PHY_MISC(phy));
		if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_A) {
			val &= ~ICL_PHY_MISC_MUX_DDID;

			if (ehl_vbt_ddi_d_present(dev_priv))
				val |= ICL_PHY_MISC_MUX_DDID;
		}

		val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
		intel_de_write(dev_priv, ICL_PHY_MISC(phy), val);

skip_phy_misc:
		if (INTEL_GEN(dev_priv) >= 12) {
			val = intel_de_read(dev_priv, ICL_PORT_TX_DW8_LN0(phy));
			val &= ~ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_MASK;
			val |= ICL_PORT_TX_DW8_ODCC_CLK_SEL;
			val |= ICL_PORT_TX_DW8_ODCC_CLK_DIV_SEL_DIV2;
			intel_de_write(dev_priv, ICL_PORT_TX_DW8_GRP(phy), val);

			val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy));
			val &= ~DCC_MODE_SELECT_MASK;
			val |= DCC_MODE_SELECT_CONTINUOSLY;
			intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), val);
		}

		cnl_set_procmon_ref_values(dev_priv, phy);

		if (phy_is_master(dev_priv, phy)) {
			val = intel_de_read(dev_priv, ICL_PORT_COMP_DW8(phy));
			val |= IREFGEN;
			intel_de_write(dev_priv, ICL_PORT_COMP_DW8(phy), val);
		}

		val = intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy));
		val |= COMP_INIT;
		intel_de_write(dev_priv, ICL_PORT_COMP_DW0(phy), val);

		val = intel_de_read(dev_priv, ICL_PORT_CL_DW5(phy));
		val |= CL_POWER_DOWN_ENABLE;
		intel_de_write(dev_priv, ICL_PORT_CL_DW5(phy), val);
	}
}

static void icl_combo_phys_uninit(struct drm_i915_private *dev_priv)
{
	enum phy phy;

	for_each_combo_phy_reverse(dev_priv, phy) {
		u32 val;

		if (phy == PHY_A &&
		    !icl_combo_phy_verify_state(dev_priv, phy))
			drm_warn(&dev_priv->drm,
				 "Combo PHY %c HW state changed unexpectedly\n",
				 phy_name(phy));

		if (!has_phy_misc(dev_priv, phy))
			goto skip_phy_misc;

		val = intel_de_read(dev_priv, ICL_PHY_MISC(phy));
		val |= ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
		intel_de_write(dev_priv, ICL_PHY_MISC(phy), val);

skip_phy_misc:
		val = intel_de_read(dev_priv, ICL_PORT_COMP_DW0(phy));
		val &= ~COMP_INIT;
		intel_de_write(dev_priv, ICL_PORT_COMP_DW0(phy), val);
	}
}

void intel_combo_phy_init(struct drm_i915_private *i915)
{
	if (INTEL_GEN(i915) >= 11)
		icl_combo_phys_init(i915);
	else if (IS_CANNONLAKE(i915))
		cnl_combo_phys_init(i915);
}

void intel_combo_phy_uninit(struct drm_i915_private *i915)
{
	if (INTEL_GEN(i915) >= 11)
		icl_combo_phys_uninit(i915);
	else if (IS_CANNONLAKE(i915))
		cnl_combo_phys_uninit(i915);
}
