/*
 * 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>
#include <linux/kernel.h>
#include <drm/drm_dp_helper.h>

#ifdef DEBUG_FW_LOAD
#include "mhdp_firmware.h"
#endif

#include "imx-hdp.h"
#include "imx-hdmi.h"
#include "imx-dp.h"

int dp_phy_init(state_struct *state, struct drm_display_mode *mode, 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, NULL, 0);

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

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

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

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

	return true;
}

#ifdef DEBUG

void print_header(void)
{
	/*       "0x00000000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f"*/
	DRM_INFO("          : 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"
		 );
	DRM_INFO("-----------------------------------------------------------\n"
		 );
}

static void print_bytes(unsigned int addr, unsigned char *buf, unsigned int size)
{
	int i, index = 0;
	char line[160];

	if (((size + 11) * 3) > sizeof(line))
		return;

	index += sprintf(line, "0x%08x:", addr);
	for (i = 0; i < size; i++)
		index += sprintf(&line[index], " %02x", buf[i]);
	DRM_INFO("%s\n", line);

}

static int dump_dpcd(state_struct *state)
{
	int ret;

	DPTX_Read_DPCD_response resp_dpcd;

	print_header();

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x0, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x100, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x110, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x200, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x210, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x220, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x700, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x710, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x720, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}
	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);

	ret = CDN_API_DPTX_Read_DPCD_blocking(state, 0x10, 0x730, &resp_dpcd,
					      CDN_BUS_TYPE_APB);
	if (ret) {
		DRM_INFO("_debug: function returned with status %d\n", ret);
		return -1;
	}

	print_bytes(resp_dpcd.addr, resp_dpcd.buff, resp_dpcd.size);
	return 0;
}
#endif

static bool dp_check_link_status(state_struct *state, u8 num_lanes)
{
	u8 link_status[DP_LINK_STATUS_SIZE];
	DPTX_Read_DPCD_response read_resp;
	CDN_API_STATUS status;

	status = CDN_API_DPTX_Read_DPCD_blocking(state,
					      DP_LINK_STATUS_SIZE,
					      DP_LANE0_1_STATUS,
					      &read_resp,
					      CDN_BUS_TYPE_APB);

	memcpy(link_status, read_resp.buff, DP_LINK_STATUS_SIZE);

	if (status != CDN_OK) {
		return false;
	}

	DRM_DEBUG("link status 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
		 link_status[0],link_status[1],link_status[2],
		 link_status[3],link_status[4],link_status[5]);

	/* if link training is requested we should perform it always */
	return drm_dp_channel_eq_ok(link_status, num_lanes);
}

static int dp_get_training_status(state_struct *state)
{
	uint32_t evt;
	uint8_t eventId;
	uint8_t HPDevents;

	do {
		do {
			CDN_API_Get_Event(state, &evt);
			if (evt != 0)
				DRM_DEBUG("_Get_Event %d\n", evt);
		} while ((evt & 2) == 0);
		CDN_API_DPTX_ReadEvent_blocking(state, &eventId, &HPDevents);
		DRM_DEBUG("ReadEvent  ID = %d HPD = %d\n", eventId, HPDevents);

		switch (eventId) {
		case 0x01:
			DRM_INFO("INFO: Full link training started\n");
			break;
		case 0x02:
			DRM_INFO("INFO: Fast link training started\n");
			break;
		case 0x04:
			DRM_INFO("INFO: Clock recovery phase finished\n");
			break;
		case 0x08:
			DRM_INFO("INFO: Channel equalization phase finished (this is last part meaning training finished)\n");
			break;
		case 0x10:
			DRM_INFO("INFO: Fast link training finished\n");
			break;
		case 0x20:
			DRM_INFO("ERROR: Clock recovery phase failed\n");
			return -1;
		case 0x40:
			DRM_INFO("ERROR: Channel equalization phase failed\n");
			return -1;
		case 0x80:
			DRM_INFO("ERROR: Fast link training failed\n");
			return -1;
		default:
			DRM_INFO("ERROR: Invalid ID:%x\n", eventId);
			return -1;
		}
	} while (eventId != 0x08 && eventId != 0x10);

	return 0;
}

#define aux_to_hdp(x) container_of(x, struct imx_hdp, aux)

/*
 * This function only implements native DPDC reads and writes
 */
static ssize_t dp_aux_transfer(struct drm_dp_aux *aux,
		struct drm_dp_aux_msg *msg)
{
	struct imx_hdp *hdp = aux_to_hdp(aux);
	bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
	CDN_API_STATUS status;

	DRM_DEBUG("\n");
	DRM_INFO("%s() msg->request 0x%x msg->size 0x%x\n",
	       __func__, msg->request, (unsigned int)msg->size);


	/* Ignore address only message */
	if ((msg->size == 0) || (msg->buffer == NULL)) {
		msg->reply = native ?
			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
		return msg->size;
	}

	if (!native) {
		pr_err("%s: only native messages supported\n",
			__func__);
		return -EINVAL;
	}

	/* msg sanity check */
	if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) {
		pr_err("%s: invalid msg: size(%zu), request(%x)\n",
			__func__, msg->size, (unsigned int)msg->request);
		return -EINVAL;
	}

	if (msg->request == DP_AUX_NATIVE_WRITE) {
		DPTX_Write_DPCD_response write_resp;

		status = CDN_API_DPTX_Write_DPCD_blocking(&hdp->state,
							  msg->size,
							  msg->address,
							  (u8 *)msg->buffer,
							  &write_resp,
							  CDN_BUS_TYPE_APB);

		if (status != CDN_OK)
			return -EIO;
		/* fixme: is this right? */
		//return  msg->size;
	}

	if (msg->request == DP_AUX_NATIVE_READ) {
		DPTX_Read_DPCD_response read_resp;

		status = CDN_API_DPTX_Read_DPCD_blocking(&hdp->state,
						      msg->size,
						      msg->address,
						      &read_resp,
						      CDN_BUS_TYPE_APB);
		if (status != CDN_OK)
			return -EIO;
		memcpy(msg->buffer, read_resp.buff, read_resp.size);
		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
#ifdef DEBUG
		print_bytes(read_resp.addr, read_resp.buff, read_resp.size);
#endif
		return read_resp.size;
	}
	return 0;
}

/* Max Link Rate: 06h (1.62Gbps), 0Ah (2.7Gbps), 14h (5.4Gbps),
 * 1Eh (8.1Gbps)--N/A
 */
void dp_mode_set(state_struct *state,
			struct drm_display_mode *mode,
			int format,
			int color_depth,
			int max_link_rate)
{
	struct imx_hdp *hdp = state_to_imx_hdp(state);
	int ret;
	u8 training_retries = 10, training_restarts = 10;
	/* 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 = hdp->dp_lane_mapping;
	/* 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;
	u8 link_rate = RATE_1_6;
	struct drm_dp_link link;

#ifdef DEBUG
	S_LINK_STAT rls;
#endif
	char linkid[6];

	DRM_INFO("dp_mode_set()\n");

	ret = drm_dp_downstream_id(&hdp->aux, linkid);
	if (ret < 0) {
		DRM_INFO("Failed to Get DP link ID: %d\n", ret);
		return;
	}
	DRM_INFO("DP link id: %s, 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
		 linkid, linkid[0], linkid[1], linkid[2], linkid[3], linkid[4],
		 linkid[5]);

	/* Check dp link */
	ret = drm_dp_link_probe(&hdp->aux, &link);
	if (ret < 0) {
		DRM_INFO("Failed to probe DP link: %d\n", ret);
		return;
	}
	DRM_INFO("DP revision: 0x%x\n", link.revision);
	DRM_INFO("DP rate: %d Mbps\n", link.rate/100);
	DRM_INFO("DP number of lanes: %d\n", link.num_lanes);
	DRM_INFO("DP capabilities: 0x%lx\n", link.capabilities);

	/* always use the number of lanes from the display*/
	num_lanes = link.num_lanes;

	/* Use the lower link rate if dp_link_rate is set */
	if (hdp->dp_link_rate != 0) {
		link_rate = min(hdp->dp_link_rate,
			(u32)(drm_dp_link_rate_to_bw_code(link.rate)));
		DRM_INFO("DP actual link rate:  0x%x\n", link_rate);
		hdp->link_rate = link_rate;

		/* need change the link rate */
		hdp->ops->phy_init(state,
				   mode,
				   format,
				   color_depth);
	}

	if (hdp->is_edp) {
		/* use the eDP supported rates */
		switch (link_rate) {
		case AFE_LINK_RATE_1_6:
			sym_rate = RATE_1_6;
			break;
		case AFE_LINK_RATE_2_1:
			sym_rate = RATE_2_1;
			break;
		case AFE_LINK_RATE_2_4:
			sym_rate = RATE_2_4;
			break;
		case AFE_LINK_RATE_2_7:
			sym_rate = RATE_2_7;
			break;
		case AFE_LINK_RATE_3_2:
			sym_rate = RATE_3_2;
			break;
		case AFE_LINK_RATE_4_3:
			sym_rate = RATE_4_3;
			break;
		case AFE_LINK_RATE_5_4:
			sym_rate = RATE_5_4;
			break;
			/*case AFE_LINK_RATE_8_1: sym_rate = RATE_8_1; break; */
		default:
			sym_rate = RATE_1_6;
		}
	} else {
		switch (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_SetHostCap_blocking(state,
		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
		);
	DRM_INFO("CDN_API_DPTX_SetHostCap_blocking (ret = %d)\n", ret);

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

	training_restarts=5;
	do {

		do {
			ret = CDN_API_DPTX_TrainingControl_blocking(state, 1);
			DRM_INFO("CDN_API_DPTX_TrainingControl_* (ret = %d) start\n",
				   ret);
			if ((dp_get_training_status(state) == 0) /*&&
			     dp_check_link_status(state, num_lanes)*/)
				break;
			training_retries--;

			ret = CDN_API_DPTX_TrainingControl_blocking(state, 0);
			DRM_INFO("CDN_API_DPTX_TrainingControl_* (ret = %d) stop\n",
				   ret);
			udelay(1000);

		} while (training_retries > 0);

		udelay(1000);

		if (dp_check_link_status(state, num_lanes) == true) {
		        DRM_INFO("Link is good - Training complete\n");
		        break;
		} else {
			DRM_INFO("Link is bad - need to restart training\n");
			training_restarts--;
			training_retries = 20;

			ret = CDN_API_DPTX_TrainingControl_blocking(state, 0);
			DRM_INFO("CDN_API_DPTX_TrainingControl_* (ret = %d) stop\n",
				   ret);
			udelay(1000);
		}


	} while (training_restarts > 0);

	DRM_INFO("dp_check_link_status %d\n", dp_check_link_status(state, num_lanes));

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

	udelay(1000);

#ifdef DEBUG
	ret = CDN_API_DPTX_ReadLinkStat_blocking(state, &rls);
	DRM_INFO("INFO: Get Read Link Status (ret = %d resp: rate: %d, lanes: %d, vswing 0..3: %d %d %d, preemp 0..3: %d %d %d\n",
		 ret, rls.rate, rls.lanes,
		 rls.swing[0], rls.swing[1], rls.swing[2],
		 rls.preemphasis[0], rls.preemphasis[1],
		 rls.preemphasis[2]);
	dump_dpcd(state);
#endif
}

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 = CDN_ERROR_NOT_SUPPORTED;

	if (buf == NULL) {
		return -EINVAL;
	}

	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:
		DRM_WARN("EDID block %x read not support\n", block);
	}

	DRM_INFO("dp_get_edid_block (ret = %d) block %d\n", ret, block);
	if (ret == CDN_OK) {
		memcpy(buf, edidResp.buff, 128);
		return 0;
	}

	memset(buf, 0, 128);
	return -EIO;
}

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

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

void dp_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);
}


int dp_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 max_link_rate = hdp->link_rate;
	int num_lanes = 4;
	int ret;
	u8 lane_mapping = hdp->dp_lane_mapping;

	/* reset phy */
	imx_hdp_call(hdp, phy_reset, 0, &hdp->mem, 0);
	DRM_INFO("asserted HDP PHY reset\n");

	dp_phy_pix_engine_reset_t28hpc(state);
	DRM_INFO("pixel engine reset\n");

	/* Line swaping */
	CDN_API_General_Write_Register_blocking(state,
						ADDR_SOURCD_PHY +
						(LANES_CONFIG << 2),
						0x00400000 | lane_mapping);
	DRM_INFO("CDN_*_Write_Register_blocking ... setting LANES_CONFIG %x\n",
		 lane_mapping);

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

	/* In this point the phy reset should be deactivated */
	imx_hdp_call(hdp, phy_reset, 0, &hdp->mem, 1);
	DRM_INFO("deasserted HDP PHY reset\n");

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

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

	return true;
}


int dp_aux_init(state_struct *state,
		  struct device *dev)
{
	struct imx_hdp *hdp = state_to_imx_hdp(state);
	int ret;

	hdp->aux.name = "imx_dp_aux";
	hdp->aux.dev = dev;
	hdp->aux.transfer = dp_aux_transfer;

	ret = drm_dp_aux_register(&hdp->aux);

	return ret;
}

int dp_aux_destroy(state_struct *state)
{
	struct imx_hdp *hdp = state_to_imx_hdp(state);

	drm_dp_aux_unregister(&hdp->aux);

	return 0;
}
