// 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} },
};

/**
 * 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;
}

/**
 * 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,
};
