/*
 * Copyright 2017 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 "mhdp_firmware.h"
#endif
#include "imx-hdp.h"
#include "imx-hdmi.h"
#include "imx-dp.h"

#ifdef DEBUG_FW_LOAD
void dp_fw_load(state_struct *state)
{
	pr_info("loading hdmi firmware\n");
	CDN_API_LoadFirmware(state,
		(u8 *)mhdp_iram0_get_ptr(),
		mhdp_iram0_get_size(),
		(u8 *)mhdp_dram0_get_ptr(),
		mhdp_dram0_get_size());
}
#endif
int dp_fw_init(state_struct *state)
{
	u8 echo_msg[] = "echo test";
	u8 echo_resp[sizeof(echo_msg) + 1];
	struct imx_hdp *hdp = state_to_imx_hdp(state);
	u32 core_rate;
	int ret;
	u8 resp;

	core_rate = clk_get_rate(hdp->clks.clk_core);

	/* configure the clock */
	CDN_API_SetClock(state, core_rate/1000000);
	pr_info("CDN_API_SetClock completed\n");

	cdn_apb_write(state, APB_CTRL << 2, 0);
	pr_info("Started firmware!\n");

	ret = CDN_API_CheckAlive_blocking(state);
	if (ret != 0) {
		pr_err("CDN_API_CheckAlive failed - check firmware!\n");
		return -ENXIO;
	} else
		pr_info("CDN_API_CheckAlive returned ret = %d\n", ret);

	/* turn on IP activity */
	ret = CDN_API_MainControl_blocking(state, 1, &resp);
	pr_info("CDN_API_MainControl_blocking (ret = %d resp = %u)\n",
		ret, resp);

	ret = CDN_API_General_Test_Echo_Ext_blocking(state, echo_msg, echo_resp,
		sizeof(echo_msg), CDN_BUS_TYPE_APB);
	if (0 != strncmp(echo_msg, echo_resp, sizeof(echo_msg))) {
		pr_err("CDN_API_General_Test_Echo_Ext_blocking - echo test failed, check firmware!");
		return -ENXIO;
	}
	pr_info("CDN_API_General_Test_Echo_Ext_blocking (ret = %d echo_resp = %s)\n",
		ret, echo_resp);

	/* Line swaping */
	CDN_API_General_Write_Register_blocking(state,
		ADDR_SOURCD_PHY + (LANES_CONFIG << 2), 0x0040001b);
	pr_info("CDN_API_General_Write_Register_blockin ... setting LANES_CONFIG\n");

	return 0;
}

int dp_phy_init(state_struct *state, int vic, int format, int color_depth)
{
	struct imx_hdp *hdp = state_to_imx_hdp(state);
	int max_link_rate = hdp->link_rate;
	int num_lanes = 4;
	int ret;

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

	/* PHY initialization while phy reset pin is active */
	AFE_init(state, num_lanes, (ENUM_AFE_LINK_RATE)max_link_rate);
	pr_info("AFE_init\n");

	/* In this point the phy reset should be deactivated */
	imx_hdp_call(hdp, phy_reset, hdp->ipcHndl, 1);
	pr_info("deasserted reset\n");

	/* PHY power set */
	AFE_power(state, num_lanes, (ENUM_AFE_LINK_RATE)max_link_rate);
	pr_info("AFE_power exit\n");

	/* Video off */
	ret = CDN_API_DPTX_SetVideo_blocking(state, 0);
	pr_info("CDN_API_DPTX_SetVideo_blocking (ret = %d)\n", ret);

	return true;
}

/* Max Link Rate: 06h (1.62Gbps), 0Ah (2.7Gbps), 14h (5.4Gbps), 1Eh (8.1Gbps)--N/A */
void dp_mode_set(state_struct *state, int vic, int format, int color_depth, int max_link_rate)
{
	int ret;

	/* Set Host capabilities */
	/* Number of lanes and SSC */
	u8 num_lanes = 4;
	u8 ssc = 0;
	u8 scrambler = 0;
	/* Max voltage swing */
	u8 max_vswing = 3;
	u8 force_max_vswing = 0;
	/* Max pre-emphasis */
	u8 max_preemph = 2;
	u8 force_max_preemph = 0;
	/* Supported test patterns mask */
	u8 supp_test_patterns = 0x0F;
	/* AUX training? */
	u8 no_aux_training = 0;
	/* Lane mapping */
	u8 lane_mapping = 0x1B; /*  we have 4 lane, so it's OK */
	/* Extended Host capabilities */
	u8 ext_host_cap = 1;
	/* Bits per sub-pixel */
	u8 bits_per_subpixel = 8;
	/* Stereoscopic video */
	STEREO_VIDEO_ATTR stereo = 0;
	/* B/W Balance Type: 0 no data, 1 IT601, 2 ITU709 */
	BT_TYPE bt_type = 0;
	/* Transfer Unit */
	u8 transfer_unit = 64;
	VIC_SYMBOL_RATE sym_rate;

	ret = CDN_API_DPTX_SetHostCap_blocking(state,
		max_link_rate,
		(num_lanes & 0x7) | ((ssc & 1) << 3) | ((scrambler & 1) << 4),
		(max_vswing & 0x3) | ((force_max_vswing & 1) << 4),
		(max_preemph & 0x3) | ((force_max_preemph & 1) << 4),
		supp_test_patterns,
		no_aux_training, //fast link training
		lane_mapping,
		ext_host_cap
		);
	pr_info("CDN_API_DPTX_SetHostCap_blocking (ret = %d)\n", ret);

	switch (max_link_rate) {
	case 0x0a:
		sym_rate = RATE_2_7;
		break;
	case 0x14:
		sym_rate = RATE_5_4;
		break;
	default:
		sym_rate = RATE_1_6;
	}

	ret = CDN_API_DPTX_Set_VIC_blocking(state,
		vic,
		bits_per_subpixel,
		num_lanes,
		sym_rate,
		format,
		stereo,
		bt_type,
		transfer_unit
		);
	pr_info("CDN_API_DPTX_Set_VIC_blocking (ret = %d)\n", ret);

	ret = CDN_API_DPTX_TrainingControl_blocking(state, 1);
	pr_info("CDN_API_DPTX_TrainingControl_blocking (ret = %d)\n", ret);

	/* Set video on */
	ret = CDN_API_DPTX_SetVideo_blocking(state, 1);
	pr_info("CDN_API_DPTX_SetVideo_blocking (ret = %d)\n", ret);

	udelay(1000);
}

int dp_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
{
    DPTX_Read_EDID_response edidResp;
	state_struct *state = data;
	CDN_API_STATUS ret = 0;

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

	memcpy(buf, edidResp.buff, 128);

	return ret;
}

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

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