/******************************************************************************
 *
 * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
 * All rights reserved worldwide.
 *
 * Copyright 2017-2018 NXP
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE SOFTWARE IS PROVIDED "AS IS",
 * WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 ******************************************************************************
 *
 * API_HDMITX.c
 *
 ******************************************************************************
 */

#include "API_HDMITX.h"
#include "util.h"
#include "opcodes.h"
#ifndef __UBOOT__
#include "string.h"
#include "stdio.h"
#endif
#include "mhl_hdtx_top.h"
#include "source_phy.h"
#include "address.h"
#include "source_car.h"
#include "source_vif.h"
#include "general_handler.h"

CDN_API_STATUS CDN_API_HDMITX_DDC_READ(HDMITX_TRANS_DATA *data_in,
				       HDMITX_TRANS_DATA *data_out)
{
	internal_macro_command_txrx(MB_MODULE_ID_HDMI_TX, HDMI_TX_READ,
				    CDN_BUS_TYPE_APB, 3,
				    1, data_in->slave,
				    1, data_in->offset,
				    2, data_in->len
				   );
	internal_readmsg(5,
			 1, &data_out->status,
			 1, &data_out->slave,
			 1, &data_out->offset,
			 2, &data_out->len,
			 0, &data_out->buff
			);
	return CDN_OK;
}

CDN_API_STATUS CDN_API_HDMITX_DDC_READ_blocking(HDMITX_TRANS_DATA *data_in,
						HDMITX_TRANS_DATA *data_out)
{
	internal_block_function(CDN_API_HDMITX_DDC_READ(data_in, data_out));
}

CDN_API_STATUS CDN_API_HDMITX_DDC_WRITE(HDMITX_TRANS_DATA *data_in,
					HDMITX_TRANS_DATA *data_out)
{
	printf("foo: %x\n", data_in->buff[0]);
	internal_macro_command_txrx(MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE,
				    CDN_BUS_TYPE_APB, 4,
				    1, data_in->slave,
				    1, data_in->offset,
				    2, data_in->len,
				    -data_in->len, data_in->buff
				   );
	internal_readmsg(4,
			 1, &data_out->status,
			 1, &data_out->slave,
			 1, &data_out->offset,
			 2, &data_out->len
			);
	return CDN_OK;
}

CDN_API_STATUS CDN_API_HDMITX_DDC_WRITE_blocking(HDMITX_TRANS_DATA *data_in,
						 HDMITX_TRANS_DATA *data_out)
{
	internal_block_function(CDN_API_HDMITX_DDC_WRITE(data_in, data_out));
}

CDN_API_STATUS CDN_API_HDMITX_DDC_UPDATE_READ(HDMITX_TRANS_DATA *data_out)
{
	internal_macro_command_txrx(MB_MODULE_ID_HDMI_TX, HDMI_TX_UPDATE_READ,
				    CDN_BUS_TYPE_APB, 0);
	internal_readmsg(2,
			 1, &data_out->status,
			 0, &data_out->buff
			);
	return CDN_OK;
}

CDN_API_STATUS CDN_API_HDMITX_DDC_UPDATE_READ_blocking(HDMITX_TRANS_DATA
						       *data_out)
{
	internal_block_function(CDN_API_HDMITX_DDC_UPDATE_READ(data_out));
}

CDN_API_STATUS CDN_API_HDMITX_READ_EDID(unsigned char block,
					unsigned char segment,
					HDMITX_TRANS_DATA *data_out)
{
	internal_macro_command_txrx(MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID,
				    CDN_BUS_TYPE_APB, 2,
				    1, block,
				    1, segment
				   );
	internal_readmsg(5,
			 1, &data_out->status,
			 1, &data_out->slave,
			 1, &data_out->offset,
			 2, &data_out->len,
			 0, &data_out->buff
			);
	return CDN_OK;
}

CDN_API_STATUS CDN_API_HDMITX_READ_EDID_blocking(unsigned char block,
						 unsigned char segment,
						 HDMITX_TRANS_DATA *data_out)
{
	internal_block_function(CDN_API_HDMITX_READ_EDID(block, segment,
							 data_out));
}

CDN_API_STATUS
CDN_API_HDMITX_Set_Mode_blocking(HDMI_TX_MAIL_HANDLER_PROTOCOL_TYPE protocol,
				 unsigned int character_rate)
{
	CDN_API_STATUS ret;
	GENERAL_READ_REGISTER_RESPONSE resp;
	HDMITX_TRANS_DATA data_in;
	HDMITX_TRANS_DATA data_out;
	unsigned char buff = 1;

	/*enable/disable  scrambler; */
	if (protocol == HDMI_TX_MODE_HDMI_2_0) {
		if (character_rate > 340000)
			buff = 3; /*enable scrambling + TMDS_Bit_Clock_Ratio */
		else
			buff = 1; /*enable scrambling */
	} else {
		buff = 0; /*disable scrambling */
	}

	data_in.buff = &buff;
	data_in.len = 1;
	data_in.slave = 0x54;
	data_in.offset = 0x20; /*TMDS config */
#if 1
	if (protocol == HDMI_TX_MODE_HDMI_2_0)
		ret =  CDN_API_HDMITX_DDC_WRITE_blocking(&data_in, &data_out);

#endif
	ret = cdn_api_general_read_register_blocking(ADDR_SOURCE_MHL_HD +
						     (HDTX_CONTROLLER << 2),
						     &resp);

	/*remove data enable */
	resp.val = resp.val & (~(F_DATA_EN(1)));
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_CONTROLLER << 2),
						      resp.val);

	if (protocol == HDMI_TX_MODE_HDMI_2_0) {
		if (character_rate > 3400000) {
			/* Set TMDS clock ratio */
			ret = cdn_api_general_write_register_blocking
				(ADDR_SOURCE_MHL_HD +
				 (HDTX_CLOCK_REG_0 << 2),
				 F_DATA_REGISTER_VAL_0(0x00000));
			ret = cdn_api_general_write_register_blocking
				(ADDR_SOURCE_MHL_HD +
				 (HDTX_CLOCK_REG_1 << 2),
				 F_DATA_REGISTER_VAL_1(0xFFFFF));
		}
	}

	/*set hdmi mode and preemble mode */
	resp.val = resp.val & (~(F_HDMI_MODE(3)));
	resp.val = resp.val & (~(F_HDMI2_PREAMBLE_EN(1)));

	resp.val = (resp.val) | (F_HDMI_MODE(protocol)) |
		(F_HDMI2_PREAMBLE_EN(1));
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_CONTROLLER << 2),
						      resp.val);

	/*data enable */
	resp.val |= F_DATA_EN(1);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_CONTROLLER << 2),
						      resp.val);

	return ret;
}

CDN_API_STATUS CDN_API_HDMITX_Init_blocking(void)
{
	CDN_API_STATUS ret;

	/*init phy and CAR and HDMI TX */
/*	ret = cdn_api_general_write_register_blocking
		(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)); */

	ret = cdn_api_general_write_register_blocking(ADDR_SOURCD_PHY +
						      (PHY_DATA_SEL << 2),
						      F_SOURCE_PHY_MHDP_SEL(1));
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_HPD << 2),
						      F_HPD_VALID_WIDTH(4) |
						      F_HPD_GLITCH_WIDTH(0));
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_CONTROLLER << 2),
						      F_HDMI_MODE(1) |
						      F_AUTO_MODE(0) |
						      F_GCP_EN(1) |
						      F_DATA_EN(1) |
						      F_CLEAR_AVMUTE(1) |
						      F_HDMI2_PREAMBLE_EN(1) |
						      F_HDMI2_CTRL_IL_MODE(1) |
						      F_PIC_3D(0XF) |
						      F_BCH_EN(1));
	/* open CARS */
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR +
						      (SOURCE_PHY_CAR << 2),
						      0xF);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR +
						      (SOURCE_HDTX_CAR << 2),
						      0xFF);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR +
						      (SOURCE_PKT_CAR << 2),
						      0xF);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR +
						      (SOURCE_AIF_CAR << 2),
						      0xF);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR +
						      (SOURCE_CIPHER_CAR << 2),
						      0xF);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR +
						      (SOURCE_CRYPTO_CAR << 2),
						      0xF);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_CAR +
						      (SOURCE_CEC_CAR << 2), 3);

	/*init vif */
	/*ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_VIF
	  +(HSYNC2VSYNC_POL_CTRL<<2), F_HPOL(0) | F_VPOL(0)); */

	return ret;
}


CDN_API_STATUS CDN_API_HDMITX_SetVic_blocking(VIC_MODES vicMode, int bpp,
					      VIC_PXL_ENCODING_FORMAT format)
{
	CDN_API_STATUS ret;
	GENERAL_READ_REGISTER_RESPONSE resp;
	unsigned int vsync_lines = vic_table[vicMode][VSYNC];
	unsigned int eof_lines = vic_table[vicMode][TYPE_EOF];
	unsigned int sof_lines = vic_table[vicMode][SOF];
	unsigned int hblank = vic_table[vicMode][H_BLANK];
	unsigned int hactive = vic_table[vicMode][H_TOTAL] - hblank;
	unsigned int vblank = vsync_lines + eof_lines + sof_lines;
	unsigned int vactive = vic_table[vicMode][V_TOTAL] - vblank;
	unsigned int hfront = vic_table[vicMode][FRONT_PORCH];
	unsigned int hback = vic_table[vicMode][BACK_PORCH];
	unsigned int vfront = eof_lines;
	unsigned int hsync = hblank - hfront - hback;
	unsigned int vsync = vsync_lines;
	unsigned int vback = sof_lines;
	unsigned int v_h_polarity = ((vic_table[vicMode][HSYNC_POL] ==
				      ACTIVE_LOW) ? 0 : 1) +
		((vic_table[vicMode][VSYNC_POL] == ACTIVE_LOW) ? 0 : 2);

	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (SCHEDULER_H_SIZE << 2),
						      (hactive << 16) + hblank);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (SCHEDULER_V_SIZE << 2),
						      (vactive << 16) + vblank);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_SIGNAL_FRONT_WIDTH
						       << 2),
						      (vfront << 16) + hfront);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_SIGNAL_SYNC_WIDTH
						       << 2),
						      (vsync << 16) + hsync);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_SIGNAL_BACK_WIDTH
						       << 2),
						      (vback << 16) + hback);
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_VIF +
						      (HSYNC2VSYNC_POL_CTRL
						       << 2),
						      v_h_polarity);

	/*  Data Enable is 1 */

	/*Reset Data Enable */
	cdn_api_general_read_register_blocking(ADDR_SOURCE_MHL_HD +
					       (HDTX_CONTROLLER << 2), &resp);

	/*reset data enable */
	resp.val = resp.val & (~(F_DATA_EN(1)));
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_CONTROLLER << 2),
						      resp.val);

	/*set bpp */
	resp.val = resp.val &  (~(F_VIF_DATA_WIDTH(3)));
	switch (bpp) {
	case 8:
		resp.val = resp.val | (F_VIF_DATA_WIDTH(0));
		break;

	case 10:
		resp.val = resp.val | (F_VIF_DATA_WIDTH(1));
		break;

	case 12:
		resp.val = resp.val | (F_VIF_DATA_WIDTH(2));
		break;

	case 16:
		resp.val = resp.val | (F_VIF_DATA_WIDTH(3));
		break;
	}

	/*select color encoding */
	resp.val = resp.val &  (~(F_HDMI_ENCODING(3)));
	switch (format) {
	case PXL_RGB:

		resp.val = resp.val | (F_HDMI_ENCODING(0));
		break;

	case YCBCR_4_4_4:
		resp.val = resp.val | (F_HDMI_ENCODING(2));
		break;

	case YCBCR_4_2_2:
		resp.val = resp.val | (F_HDMI_ENCODING(1));
		break;

	case YCBCR_4_2_0:
		resp.val = resp.val | (F_HDMI_ENCODING(3));
		break;
	case Y_ONLY:
		/*not exist in hdmi */
		break;
	}

	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_CONTROLLER << 2),
						      resp.val);

	/*set data enable */
	resp.val = resp.val  | (F_DATA_EN(1));
	ret = cdn_api_general_write_register_blocking(ADDR_SOURCE_MHL_HD +
						      (HDTX_CONTROLLER << 2),
						      resp.val);

	return ret;
}

CDN_API_STATUS CDN_API_HDMITX_ForceColorDepth_blocking(unsigned char force,
						       unsigned char val)
{
	unsigned int valToWrite = F_COLOR_DEPTH_VAL(val) |
		F_COLOR_DEPTH_FORCE(force);

	return cdn_api_general_write_register_blocking
		(ADDR_SOURCE_MHL_HD +
		 (GCP_FORCE_COLOR_DEPTH_CODING << 2),
		 valToWrite);
}

CDN_API_STATUS CDN_API_HDMITX_ReadEvents(uint32_t *events)
{
	CDN_API_STATUS ret;

	if (!state.running) {
		if (!internal_apb_available())
			return CDN_BSY;

		internal_tx_mkfullmsg(MB_MODULE_ID_HDMI_TX, HDMI_TX_EVENTS, 0);
		state.rxenable = 1;
		state.bus_type = CDN_BUS_TYPE_APB;

		return CDN_STARTED;
	}

	INTERNAL_PROCESS_MESSAGES;

	ret = internal_test_rx_head(MB_MODULE_ID_HDMI_TX, HDMI_TX_EVENTS);

	if (ret != CDN_OK)
		return ret;

	internal_readmsg(1, 4, events);

	return CDN_OK;
}

CDN_API_STATUS CDN_API_HDMITX_ReadEvents_blocking(uint32_t *events)
{
	internal_block_function(CDN_API_HDMITX_ReadEvents(events));
}

CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus(uint8_t *hpd_sts)
{
	CDN_API_STATUS ret;

	if (!state.running) {
		if (!internal_apb_available())
			return CDN_BSY;

		/*
		 * General Module is used here for obtaining HPD State because
		 * HDMI TX Module is inactive in stand-by mode, thus cannot
		 * return it.
		 */
		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL,
				      GENERAL_GET_HPD_STATE, 0);
		state.rxenable = 1;
		state.bus_type = CDN_BUS_TYPE_APB;

		return CDN_STARTED;
	}

	INTERNAL_PROCESS_MESSAGES;

	ret = internal_test_rx_head(MB_MODULE_ID_GENERAL,
				    GENERAL_GET_HPD_STATE);

	if (ret != CDN_OK)
		return ret;

	internal_readmsg(1, 1, hpd_sts);

	return CDN_OK;
}

CDN_API_STATUS CDN_API_HDMITX_GetHpdStatus_blocking(uint8_t *hpd_sts)
{
	internal_block_function(CDN_API_HDMITX_GetHpdStatus(hpd_sts));
}

