// 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 = I915_READ(ICL_PORT_COMP_DW3(phy));
	switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) {
	default:
		MISSING_CASE(val);
		/* fall through */
	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 = I915_READ(ICL_PORT_COMP_DW1(phy));
	val &= ~((0xff << 16) | 0xff);
	val |= procmon->dw1;
	I915_WRITE(ICL_PORT_COMP_DW1(phy), val);

	I915_WRITE(ICL_PORT_COMP_DW9(phy), procmon->dw9);
	I915_WRITE(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 = I915_READ(reg);

	if ((val & mask) != expected_val) {
		DRM_DEBUG_DRIVER("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 !(I915_READ(CHICKEN_MISC_2) & CNL_COMP_PWR_DOWN) &&
		(I915_READ(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 = I915_READ(CHICKEN_MISC_2);
	val &= ~CNL_COMP_PWR_DOWN;
	I915_WRITE(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 = I915_READ(CNL_PORT_COMP_DW0);
	val |= COMP_INIT;
	I915_WRITE(CNL_PORT_COMP_DW0, val);

	val = I915_READ(CNL_PORT_CL1CM_DW5);
	val |= CL_POWER_DOWN_ENABLE;
	I915_WRITE(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("Combo PHY HW state changed unexpectedly.\n");

	val = I915_READ(CHICKEN_MISC_2);
	val |= CNL_COMP_PWR_DOWN;
	I915_WRITE(CHICKEN_MISC_2, val);
}

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 (IS_ELKHARTLAKE(dev_priv) && phy == PHY_C)
		return I915_READ(ICL_PORT_COMP_DW0(phy)) & COMP_INIT;
	else
		return !(I915_READ(ICL_PHY_MISC(phy)) &
			 ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN) &&
			(I915_READ(ICL_PORT_COMP_DW0(phy)) & COMP_INIT);
}

static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
				       enum phy phy)
{
	bool ret;

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

	ret = cnl_verify_procmon_ref_values(dev_priv, phy);

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

	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) {
		WARN_ON(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);
			/* fall-through */
		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);
			/* fall-through */
		case 4:
			lane_mask = PWR_UP_ALL_LANES;
			break;
		}
	}

	val = I915_READ(ICL_PORT_CL_DW10(phy));
	val &= ~PWR_DOWN_LN_MASK;
	val |= lane_mask << PWR_DOWN_LN_SHIFT;
	I915_WRITE(ICL_PORT_CL_DW10(phy), val);
}

static u32 ehl_combo_phy_a_mux(struct drm_i915_private *i915, u32 val)
{
	bool ddi_a_present = i915->vbt.ddi_port_info[PORT_A].child != NULL;
	bool ddi_d_present = i915->vbt.ddi_port_info[PORT_D].child != NULL;
	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 val | ICL_PHY_MISC_MUX_DDID;

	/*
	 * 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_ERROR("VBT claims to have both internal and external displays on PHY A.  Configuring for internal.\n");

	return val & ~ICL_PHY_MISC_MUX_DDID;
}

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_DEBUG_DRIVER("Combo PHY %c already enabled, won't reprogram it.\n",
					 phy_name(phy));
			continue;
		}

		/*
		 * Although EHL adds a combo PHY C, there's no PHY_MISC
		 * register for it and no need to program the
		 * DE_IO_COMP_PWR_DOWN setting on PHY C.
		 */
		if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_C)
			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 = I915_READ(ICL_PHY_MISC(phy));
		if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_A)
			val = ehl_combo_phy_a_mux(dev_priv, val);
		val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
		I915_WRITE(ICL_PHY_MISC(phy), val);

skip_phy_misc:
		cnl_set_procmon_ref_values(dev_priv, phy);

		if (phy == PHY_A) {
			val = I915_READ(ICL_PORT_COMP_DW8(phy));
			val |= IREFGEN;
			I915_WRITE(ICL_PORT_COMP_DW8(phy), val);
		}

		val = I915_READ(ICL_PORT_COMP_DW0(phy));
		val |= COMP_INIT;
		I915_WRITE(ICL_PORT_COMP_DW0(phy), val);

		val = I915_READ(ICL_PORT_CL_DW5(phy));
		val |= CL_POWER_DOWN_ENABLE;
		I915_WRITE(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("Combo PHY %c HW state changed unexpectedly\n",
				 phy_name(phy));

		/*
		 * Although EHL adds a combo PHY C, there's no PHY_MISC
		 * register for it and no need to program the
		 * DE_IO_COMP_PWR_DOWN setting on PHY C.
		 */
		if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_C)
			goto skip_phy_misc;

		val = I915_READ(ICL_PHY_MISC(phy));
		val |= ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
		I915_WRITE(ICL_PHY_MISC(phy), val);

skip_phy_misc:
		val = I915_READ(ICL_PORT_COMP_DW0(phy));
		val &= ~COMP_INIT;
		I915_WRITE(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);
}
