// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) STMicroelectronics SA 2014
 * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
 */

#include <drm/drm_print.h>

#include "sti_hdmi_tx3g4c28phy.h"

#define HDMI_SRZ_CFG                             0x504
#define HDMI_SRZ_PLL_CFG                         0x510
#define HDMI_SRZ_ICNTL                           0x518
#define HDMI_SRZ_CALCODE_EXT                     0x520

#define HDMI_SRZ_CFG_EN                          BIT(0)
#define HDMI_SRZ_CFG_DISABLE_BYPASS_SINK_CURRENT BIT(1)
#define HDMI_SRZ_CFG_EXTERNAL_DATA               BIT(16)
#define HDMI_SRZ_CFG_RBIAS_EXT                   BIT(17)
#define HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION      BIT(18)
#define HDMI_SRZ_CFG_EN_BIASRES_DETECTION        BIT(19)
#define HDMI_SRZ_CFG_EN_SRC_TERMINATION          BIT(24)

#define HDMI_SRZ_CFG_INTERNAL_MASK  (HDMI_SRZ_CFG_EN     | \
		HDMI_SRZ_CFG_DISABLE_BYPASS_SINK_CURRENT | \
		HDMI_SRZ_CFG_EXTERNAL_DATA               | \
		HDMI_SRZ_CFG_RBIAS_EXT                   | \
		HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION      | \
		HDMI_SRZ_CFG_EN_BIASRES_DETECTION        | \
		HDMI_SRZ_CFG_EN_SRC_TERMINATION)

#define PLL_CFG_EN                               BIT(0)
#define PLL_CFG_NDIV_SHIFT                       (8)
#define PLL_CFG_IDF_SHIFT                        (16)
#define PLL_CFG_ODF_SHIFT                        (24)

#define ODF_DIV_1                                (0)
#define ODF_DIV_2                                (1)
#define ODF_DIV_4                                (2)
#define ODF_DIV_8                                (3)

#define HDMI_TIMEOUT_PLL_LOCK  50  /*milliseconds */

struct plldividers_s {
	uint32_t min;
	uint32_t max;
	uint32_t idf;
	uint32_t odf;
};

/*
 * Functional specification recommended values
 */
#define NB_PLL_MODE 5
static struct plldividers_s plldividers[NB_PLL_MODE] = {
	{0, 20000000, 1, ODF_DIV_8},
	{20000000, 42500000, 2, ODF_DIV_8},
	{42500000, 85000000, 4, ODF_DIV_4},
	{85000000, 170000000, 8, ODF_DIV_2},
	{170000000, 340000000, 16, ODF_DIV_1}
};

#define NB_HDMI_PHY_CONFIG 2
static struct hdmi_phy_config hdmiphy_config[NB_HDMI_PHY_CONFIG] = {
	{0, 250000000, {0x0, 0x0, 0x0, 0x0} },
	{250000000, 300000000, {0x1110, 0x0, 0x0, 0x0} },
};

/**
 * sti_hdmi_tx3g4c28phy_start - Start hdmi phy macro cell tx3g4c28
 *
 * @hdmi: pointer on the hdmi internal structure
 *
 * Return false if an error occur
 */
static bool sti_hdmi_tx3g4c28phy_start(struct sti_hdmi *hdmi)
{
	u32 ckpxpll = hdmi->mode.clock * 1000;
	u32 val, tmdsck, idf, odf, pllctrl = 0;
	bool foundplldivides = false;
	int i;

	DRM_DEBUG_DRIVER("ckpxpll = %dHz\n", ckpxpll);

	for (i = 0; i < NB_PLL_MODE; i++) {
		if (ckpxpll >= plldividers[i].min &&
		    ckpxpll < plldividers[i].max) {
			idf = plldividers[i].idf;
			odf = plldividers[i].odf;
			foundplldivides = true;
			break;
		}
	}

	if (!foundplldivides) {
		DRM_ERROR("input TMDS clock speed (%d) not supported\n",
			  ckpxpll);
		goto err;
	}

	/* Assuming no pixel repetition and 24bits color */
	tmdsck = ckpxpll;
	pllctrl |= 40 << PLL_CFG_NDIV_SHIFT;

	if (tmdsck > 340000000) {
		DRM_ERROR("output TMDS clock (%d) out of range\n", tmdsck);
		goto err;
	}

	pllctrl |= idf << PLL_CFG_IDF_SHIFT;
	pllctrl |= odf << PLL_CFG_ODF_SHIFT;

	/*
	 * Configure and power up the PHY PLL
	 */
	hdmi->event_received = false;
	DRM_DEBUG_DRIVER("pllctrl = 0x%x\n", pllctrl);
	hdmi_write(hdmi, (pllctrl | PLL_CFG_EN), HDMI_SRZ_PLL_CFG);

	/* wait PLL interrupt */
	wait_event_interruptible_timeout(hdmi->wait_event,
					 hdmi->event_received == true,
					 msecs_to_jiffies
					 (HDMI_TIMEOUT_PLL_LOCK));

	if ((hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK) == 0) {
		DRM_ERROR("hdmi phy pll not locked\n");
		goto err;
	}

	DRM_DEBUG_DRIVER("got PHY PLL Lock\n");

	val = (HDMI_SRZ_CFG_EN |
	       HDMI_SRZ_CFG_EXTERNAL_DATA |
	       HDMI_SRZ_CFG_EN_BIASRES_DETECTION |
	       HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION);

	if (tmdsck > 165000000)
		val |= HDMI_SRZ_CFG_EN_SRC_TERMINATION;

	/*
	 * To configure the source termination and pre-emphasis appropriately
	 * for different high speed TMDS clock frequencies a phy configuration
	 * table must be provided, tailored to the SoC and board combination.
	 */
	for (i = 0; i < NB_HDMI_PHY_CONFIG; i++) {
		if ((hdmiphy_config[i].min_tmds_freq <= tmdsck) &&
		    (hdmiphy_config[i].max_tmds_freq >= tmdsck)) {
			val |= (hdmiphy_config[i].config[0]
				& ~HDMI_SRZ_CFG_INTERNAL_MASK);
			hdmi_write(hdmi, val, HDMI_SRZ_CFG);

			val = hdmiphy_config[i].config[1];
			hdmi_write(hdmi, val, HDMI_SRZ_ICNTL);

			val = hdmiphy_config[i].config[2];
			hdmi_write(hdmi, val, HDMI_SRZ_CALCODE_EXT);

			DRM_DEBUG_DRIVER("serializer cfg 0x%x 0x%x 0x%x\n",
					 hdmiphy_config[i].config[0],
					 hdmiphy_config[i].config[1],
					 hdmiphy_config[i].config[2]);
			return true;
		}
	}

	/*
	 * Default, power up the serializer with no pre-emphasis or
	 * output swing correction
	 */
	hdmi_write(hdmi, val,  HDMI_SRZ_CFG);
	hdmi_write(hdmi, 0x0, HDMI_SRZ_ICNTL);
	hdmi_write(hdmi, 0x0, HDMI_SRZ_CALCODE_EXT);

	return true;

err:
	return false;
}

/**
 * sti_hdmi_tx3g4c28phy_stop - Stop hdmi phy macro cell tx3g4c28
 *
 * @hdmi: pointer on the hdmi internal structure
 */
static void sti_hdmi_tx3g4c28phy_stop(struct sti_hdmi *hdmi)
{
	int val = 0;

	DRM_DEBUG_DRIVER("\n");

	hdmi->event_received = false;

	val = HDMI_SRZ_CFG_EN_SINK_TERM_DETECTION;
	val |= HDMI_SRZ_CFG_EN_BIASRES_DETECTION;

	hdmi_write(hdmi, val, HDMI_SRZ_CFG);
	hdmi_write(hdmi, 0, HDMI_SRZ_PLL_CFG);

	/* wait PLL interrupt */
	wait_event_interruptible_timeout(hdmi->wait_event,
					 hdmi->event_received == true,
					 msecs_to_jiffies
					 (HDMI_TIMEOUT_PLL_LOCK));

	if (hdmi_read(hdmi, HDMI_STA) & HDMI_STA_DLL_LCK)
		DRM_ERROR("hdmi phy pll not well disabled\n");
}

struct hdmi_phy_ops tx3g4c28phy_ops = {
	.start = sti_hdmi_tx3g4c28phy_start,
	.stop = sti_hdmi_tx3g4c28phy_stop,
};
