/*
 * Copyright 2017-2018 NXP
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/clk.h>
#ifdef DEBUG_FW_LOAD
#include "hdmitx_firmware.h"
#endif
#include "imx-hdp.h"
#include "imx-hdmi.h"
#include "API_AFE_ss28fdsoi_kiran_hdmitx.h"
#include "API_AFE_t28hpc_hdmitx.h"

#define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
				 BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB))
#define YCC_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
				 BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM) |\
				 BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601) |\
				 BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601) |\
				 BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709) |\
				 BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601))

#define B0_SILICON_ID			0x11

static int hdmi_avi_info_set(struct imx_hdp *hdp,
				struct drm_display_mode *mode,
				int format)
{
	struct hdmi_avi_infoframe frame;
	struct drm_display_info *di = &hdp->connector.display_info;
	enum hdmi_extended_colorimetry ext_colorimetry;
	u32 sink_colorimetry;
	u32 allowed_colorimetry;
	u8 buf[32];
	int ret;

	/* Initialise info frame from DRM mode */
	drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, true);

	/* Set up colorimetry */
	allowed_colorimetry = format == PXL_RGB ? RGB_ALLOWED_COLORIMETRY :
						  YCC_ALLOWED_COLORIMETRY;

	if (hdp->bpc == 8)
		allowed_colorimetry &= ~(BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |
			      BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM));

	sink_colorimetry = di->hdmi.colorimetry & allowed_colorimetry;

	if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020))
		ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020;
	else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM))
		ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM;
	else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB))
		ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB;
	else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709))
		ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
	else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601))
		ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601;
	else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601))
		ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_S_YCC_601;
	else if (sink_colorimetry & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601))
		ext_colorimetry = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
	else
		ext_colorimetry = 0;

	frame.colorimetry = sink_colorimetry ? HDMI_COLORIMETRY_EXTENDED :
					  HDMI_COLORIMETRY_NONE;
	frame.extended_colorimetry = ext_colorimetry;

	switch (format) {
	case YCBCR_4_4_4:
		frame.colorspace = HDMI_COLORSPACE_YUV444;
		break;
	case YCBCR_4_2_2:
		frame.colorspace = HDMI_COLORSPACE_YUV422;
		break;
	case YCBCR_4_2_0:
		frame.colorspace = HDMI_COLORSPACE_YUV420;
		break;
	default:
		frame.colorspace = HDMI_COLORSPACE_RGB;
		break;
	}

	ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
	if (ret < 0) {
		DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
		return -1;
	}

	buf[0] = 0;
	return CDN_API_InfoframeSet(&hdp->state, 0, sizeof(buf),
				    buf, HDMI_INFOFRAME_TYPE_AVI);

}

static int hdmi_vendor_info_set(struct imx_hdp *hdp,
				struct drm_display_mode *mode,
				int format)
{
	struct hdmi_vendor_infoframe frame;
	u8 buf[32];
	int ret;

	/* Initialise vendor frame from DRM mode */
	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode);
	if (ret < 0) {
		DRM_DEBUG("Unable to init vendor infoframe: %d\n", ret);
		return -1;
	}

	ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
	if (ret < 0) {
		DRM_DEBUG("Unable to pack vendor infoframe: %d\n", ret);
		return -1;
	}

	buf[0] = 0;
	return CDN_API_InfoframeSet(&hdp->state, 3, sizeof(buf),
				    buf, HDMI_INFOFRAME_TYPE_VENDOR);

}

static void hdmi_mode_set_vswing(state_struct *state)
{
	GENERAL_Read_Register_response regresp[12];

	Afe_write(state, 0x41e1, 0x7c0);
	Afe_write(state, 0x43e1, 0x7c0);
	Afe_write(state, 0x45e1, 0x7c0);
	Afe_write(state, 0x47e1, 0x7c0);

	Afe_write(state, 0x404C, 0x0);
	Afe_write(state, 0x424C, 0x0);
	Afe_write(state, 0x444C, 0x0);
	Afe_write(state, 0x464C, 0x0);

	Afe_write(state, 0x4047, 0x120);
	Afe_write(state, 0x4247, 0x120);
	Afe_write(state, 0x4447, 0x120);
	Afe_write(state, 0x4647, 0x120);

	regresp[0].val = Afe_read(state, 0x41e1);
	regresp[1].val = Afe_read(state, 0x43e1);
	regresp[2].val = Afe_read(state, 0x45e1);
	regresp[3].val = Afe_read(state, 0x47e1);

	regresp[4].val = Afe_read(state, 0x404C);
	regresp[5].val = Afe_read(state, 0x424C);
	regresp[6].val = Afe_read(state, 0x444C);
	regresp[7].val = Afe_read(state, 0x464C);

	regresp[8].val = Afe_read(state, 0x4047);
	regresp[9].val = Afe_read(state, 0x4247);
	regresp[10].val = Afe_read(state, 0x4447);
	regresp[11].val = Afe_read(state, 0x4647);

	DRM_DEBUG("LANE0_TX_DIAG_TX_DRV 0x%x \n"
		  "LANE1_TX_DIAG_TX_DRV 0x%x \n"
		  "LANE2_TX_DIAG_TX_DRV 0x%x \n"
		  "LANE3_TX_DIAG_TX_DRV 0x%x \n"
		  "Lane0_TX_TXCC_CPOST_MULT_00 0x%x \n"
		  "Lane1_TX_TXCC_CPOST_MULT_00 0x%x \n"
		  "Lane2_TX_TXCC_CPOST_MULT_00 0x%x \n"
		  "Lane3_TX_TXCC_CPOST_MULT_00 0x%x \n"
		  "Lane0_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
		  "Lane1_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
		  "Lane2_TX_TXCC_CAL_SCLR_MULT 0x%x \n"
		  "Lane3_TX_TXCC_CAL_SCLR_MULT 0x%x \n",
		  regresp[0].val,
		  regresp[1].val,
		  regresp[2].val,
		  regresp[3].val,
		  regresp[4].val,
		  regresp[5].val,
		  regresp[6].val,
		  regresp[7].val,
		  regresp[8].val,
		  regresp[9].val,
		  regresp[10].val,
		  regresp[11].val
		  );
}

static int hdmi_scdc_tmds_config(struct imx_hdp *hdp)
{
	struct drm_scdc *scdc = &hdp->connector.display_info.hdmi.scdc;
	HDMITX_TRANS_DATA data_in;
	HDMITX_TRANS_DATA data_out;
	u8 buff;
	int ret = 0;

	if (hdp->character_freq_khz > 340000) {
		/*
		 * TMDS Character Rate above 340MHz should working in HDMI2.0
		 * Enable scrambling and TMDS_Bit_Clock_Ratio
		 */
		buff = 3;
		hdp->hdmi_type = HDMI_TX_MODE_HDMI_2_0;
	} else  if (scdc->scrambling.low_rates) {
		/*
		 * Enable scrambling and work in HDMI2.0 when scrambling capability of sink
		 * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
		 */
		buff = 1;
		hdp->hdmi_type = HDMI_TX_MODE_HDMI_2_0;
	} else {
		/* Default work in HDMI1.4 */
		buff = 0;
		hdp->hdmi_type = HDMI_TX_MODE_HDMI_1_4;
	 }

	data_in.buff = &buff;
	data_in.len = 1;
	data_in.slave = 0x54;
	/* TMDS config */
	data_in.offset = 0x20;

	/* Workaround for imx8qm A0 SOC DDC R/W failed issue */
	if (cpu_is_imx8qm() && (imx8_get_soc_revision() < B0_SILICON_ID))
		pr_info("Skip DDC Write for iMX8QM A0 SOC\n");
	else {
		ret = CDN_API_HDMITX_DDC_WRITE_blocking(&hdp->state, &data_in, &data_out);
		if (ret != CDN_OK)
			pr_warn("CDN_API_HDMITX_DDC_WRITE_blocking ret = %d\n", ret);
	}
	return ret;
}

int hdmi_phy_init_ss28fdsoi(state_struct *state, struct drm_display_mode *mode, int format, int color_depth)
{
	struct imx_hdp *hdp = state_to_imx_hdp(state);
	int ret;

	/* reset phy */
	imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 0);

	/* Configure PHY */
	hdp->character_freq_khz = phy_cfg_hdp_ss28fdsoi(state, 4, mode, color_depth, format);
	if (hdp->character_freq_khz == 0) {
		DRM_ERROR("failed to set phy pclock\n");
		return -EINVAL;
	}

	imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, NULL, 1);

	hdmi_tx_kiran_power_configuration_seq(state, 4);

	/* Set the lane swapping */
	ret = CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY + (LANES_CONFIG << 2),
		F_SOURCE_PHY_LANE0_SWAP(3) | F_SOURCE_PHY_LANE1_SWAP(0) |
		F_SOURCE_PHY_LANE2_SWAP(1) | F_SOURCE_PHY_LANE3_SWAP(2) |
		F_SOURCE_PHY_COMB_BYPASS(0) | F_SOURCE_PHY_20_10(1));
	DRM_INFO("CDN_API_General_Write_Register_blocking LANES_CONFIG ret = %d\n", ret);

	return true;
}

void hdmi_mode_set_ss28fdsoi(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int temp)
{
	struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
	int ret;

	/* config SCDC TMDS & HDMI type */
	hdmi_scdc_tmds_config(hdp);

	ret = CDN_API_HDMITX_Init_blocking(state);
	if (ret != CDN_OK) {
		DRM_INFO("CDN_API_STATUS CDN_API_HDMITX_Init_blocking  ret = %d\n", ret);
		return;
	}

	/* force GCP CD to 0 when bpp=24 for pass CTS 7-19 */
	if (color_depth == 8)
		CDN_API_HDMITX_Disable_GCP(state);

	/* Set HDMI TX Mode */
	ret = CDN_API_HDMITX_Set_Mode_blocking(state, hdp->hdmi_type, hdp->character_freq_khz);
	if (ret != CDN_OK) {
		DRM_INFO("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret);
		return;
	}

	ret = hdmi_avi_info_set(hdp, mode, format);
	if (ret < 0) {
		DRM_ERROR("hdmi avi info set ret = %d\n", ret);
		return;
	}

	/* vendor info frame is enable only when HDMI1.4 4K mode */
	hdmi_vendor_info_set(hdp, mode, format);

	ret =  CDN_API_HDMITX_SetVic_blocking(state, mode, color_depth, format);
	if (ret != CDN_OK) {
		DRM_INFO("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
		return;
	}

	hdmi_mode_set_vswing(state);
}

int hdmi_phy_init_t28hpc(state_struct *state, struct drm_display_mode *mode, int format, int color_depth)
{
	struct imx_hdp *hdp = state_to_imx_hdp(state);
	int ret;
	/* 0- pixel clock from phy */
	u32	pixel_clk_from_phy = 1;
	char echo_msg[] = "echo test";
	char echo_resp[sizeof(echo_msg) + 1];

	/* Parameterization done */

	ret = CDN_API_CheckAlive_blocking(state);
	if (ret != 0) {
		DRM_ERROR("NO HDMI FW running\n");
		return -ENXIO;
	}

	ret = CDN_API_General_Test_Echo_Ext_blocking(state, echo_msg, echo_resp,
						     sizeof(echo_msg),
						     CDN_BUS_TYPE_APB);
	if (ret != 0) {
		DRM_ERROR("HDMI mailbox access failed\n");
		return -ENXIO;
	}

	/* Configure PHY */
	hdp->character_freq_khz =
	    phy_cfg_hdp_t28hpc(state, 4, mode, color_depth, format, pixel_clk_from_phy);
	if (hdp->character_freq_khz == 0) {
		DRM_ERROR("failed to set phy pclock\n");
		return -EINVAL;
	}

	hdmi_tx_t28hpc_power_config_seq(state, 4);

	/* Set the lane swapping */
	ret =
	    CDN_API_General_Write_Register_blocking(state, ADDR_SOURCD_PHY +
						    (LANES_CONFIG << 2),
						    F_SOURCE_PHY_LANE0_SWAP(0) |
						    F_SOURCE_PHY_LANE1_SWAP(1) |
						    F_SOURCE_PHY_LANE2_SWAP(2) |
						    F_SOURCE_PHY_LANE3_SWAP(3) |
						    F_SOURCE_PHY_COMB_BYPASS(0)
						    | F_SOURCE_PHY_20_10(1));
	DRM_INFO
	    ("CDN_API_General_Write_Register_blocking LANES_CONFIG ret = %d\n",
	     ret);

	return true;
}

void hdmi_phy_pix_engine_reset_t28hpc(state_struct *state)
{
	GENERAL_Read_Register_response regresp;

	CDN_API_General_Read_Register_blocking(state, ADDR_SOURCE_CAR +
					       (SOURCE_HDTX_CAR << 2),
					       &regresp);
	CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
						(SOURCE_HDTX_CAR << 2),
						regresp.val & 0xFD);
	CDN_API_General_Write_Register_blocking(state, ADDR_SOURCE_CAR +
						(SOURCE_HDTX_CAR << 2),
						regresp.val);
}

void hdmi_mode_set_t28hpc(state_struct *state, struct drm_display_mode *mode, int format, int color_depth, int temp)
{
	struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
	int ret;

	/* config SCDC TMDS & HDMI type */
	hdmi_scdc_tmds_config(hdp);

	ret = CDN_API_HDMITX_Init_blocking(state);
	if (ret != CDN_OK) {
		DRM_ERROR("CDN_API_STATUS CDN_API_HDMITX_Init_blocking  ret = %d\n", ret);
		return;
	}

	/* force GCP CD to 0 when bpp=24 for pass CTS 7-19 */
	if (color_depth == 8)
		CDN_API_HDMITX_Disable_GCP(state);

	/* Set HDMI TX Mode */
	ret = CDN_API_HDMITX_Set_Mode_blocking(state, hdp->hdmi_type, hdp->character_freq_khz);
	if (ret != CDN_OK) {
		DRM_ERROR("CDN_API_HDMITX_Set_Mode_blocking ret = %d\n", ret);
		return;
	}

	ret = hdmi_avi_info_set(hdp, mode, format);
	if (ret < 0) {
		DRM_ERROR("hdmi avi info set ret = %d\n", ret);
		return;
	}

	/* vendor info frame is enable only when HDMI1.4 4K mode */
	hdmi_vendor_info_set(hdp, mode, format);

	ret = CDN_API_HDMITX_SetVic_blocking(state, mode, color_depth, format);
	if (ret != CDN_OK) {
		DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret);
		return;
	}

	hdmi_mode_set_vswing(state);

	msleep(50);
}

#define YUV_MODE		BIT(0)

bool hdmi_mode_fixup_t28hpc(state_struct *state,
			    const struct drm_display_mode *mode,
			    struct drm_display_mode *adjusted_mode)
{
	struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
	int vic = drm_match_cea_mode(mode);
	struct drm_display_info *di = &hdp->connector.display_info;
	u32 max_clock = di->max_tmds_clock;

	hdp->bpc = 8;
	hdp->format = PXL_RGB;

	if ((vic == VIC_MODE_97_60Hz || vic == VIC_MODE_96_50Hz)) {
		if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36)
			hdp->bpc = 12;
		else if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30)
			hdp->bpc = 10;

		if (drm_mode_is_420_only(di, mode) ||
		    (drm_mode_is_420_also(di, mode) && hdp->bpc > 8)) {
			hdp->format = YCBCR_4_2_0;

			adjusted_mode->private_flags = YUV_MODE;
		} else {
			hdp->bpc = 8;
		}

		return true;
	}

	/* Any defined maximum tmds clock limit we must not exceed*/
	if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) &&
			 (mode->clock * 3/2 <= max_clock))
		hdp->bpc = 12;
	else if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) &&
			(mode->clock * 5/4 <= max_clock))
		hdp->bpc = 10;

	/* 10-bit color depth for the following modes is not supported */
	if ((vic == VIC_MODE_95_30Hz || vic == VIC_MODE_94_25Hz ||
	     vic == VIC_MODE_93_24Hz) && hdp->bpc == 10)
		hdp->bpc = 8;

	return true;
}

int hdmi_get_edid_block(void *data, u8 *buf, u32 block, size_t len)
{
	HDMITX_TRANS_DATA edidResp;
	state_struct *state = data;
	CDN_API_STATUS ret = 0;

	memset(&edidResp, 0, sizeof(edidResp));
	switch (block) {
	case 0:
		ret = CDN_API_HDMITX_READ_EDID_blocking(state, 0, 0, &edidResp);
		break;
	case 1:
		ret = CDN_API_HDMITX_READ_EDID_blocking(state, 0, 1, &edidResp);
		break;
	case 2:
		ret = CDN_API_HDMITX_READ_EDID_blocking(state, 1, 0, &edidResp);
		break;
	case 3:
		ret = CDN_API_HDMITX_READ_EDID_blocking(state, 1, 1, &edidResp);
		break;
	default:
		pr_warn("EDID block %x read not support\n", block);
	}

	if (ret == CDN_OK)
		memcpy(buf, edidResp.buff, 128);

	return ret;
}

int hdmi_get_hpd_state(state_struct *state, u8 *hpd)
{
	int ret;

	ret = CDN_API_HDMITX_GetHpdStatus_blocking(state, hpd);
	return ret;
}

int hdmi_write_hdr_metadata(state_struct *state,
			    union hdmi_infoframe *hdr_infoframe)
{
	struct imx_hdp *hdp = container_of(state, struct imx_hdp, state);
	u8 buffer[40];
	int infoframe_size;

	infoframe_size = hdmi_infoframe_pack(hdr_infoframe,
					     buffer + 1, sizeof(buffer) - 1);
	if (infoframe_size < 0) {
		dev_err(hdp->dev, "Wrong metadata infoframe: %d\n",
			infoframe_size);
		return infoframe_size;
	}

	buffer[0] = 0;
	infoframe_size++;

	return CDN_API_InfoframeSet(state, 2, infoframe_size,
				    buffer, HDMI_INFOFRAME_TYPE_DRM);
}
