/******************************************************************************
 *
 * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
 * All rights reserved worldwide.
 *
 * 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.
 *
 * Copyright 2017-2018 NXP
 *
 ******************************************************************************
 *
 * API_General.c
 *
 ******************************************************************************
 */

#include "API_General.h"
#include "util.h"
#ifndef __UBOOT__
#include <string.h>
#endif
#include "address.h"
#include "apb_cfg.h"
#include "opcodes.h"
#include "general_handler.h"
#include "externs.h"
#ifndef __UBOOT__
#include <stdio.h>
#endif

extern state_struct state;

void cdn_api_init(void)
{
	memset(&state, 0, sizeof(state_struct));
}

CDN_API_STATUS hdp_rx_loadfirmware(unsigned char *imem, int imemsize,
				    unsigned char *dmem, int dmemsize)
{
	int i;
	for (i = 0; i < imemsize; i += 4)
		if (hdp_rx_apb_write(ADDR_IMEM + i,
				  (unsigned int)imem[i] << 0 |
				  (unsigned int)imem[i + 1] << 8 |
				  (unsigned int)imem[i + 2] << 16 |
				  (unsigned int)imem[i + 3] << 24))
			return CDN_ERR;
	for (i = 0; i < dmemsize; i += 4)
		if (hdp_rx_apb_write(ADDR_DMEM + i,
				  (unsigned int)dmem[i] << 0 |
				  (unsigned int)dmem[i + 1] << 8 |
				  (unsigned int)dmem[i + 2] << 16 |
				  (unsigned int)dmem[i + 3] << 24))
			return CDN_ERR;
	return CDN_OK;
}

CDN_API_STATUS cdn_api_loadfirmware(unsigned char *imem, int imemsize,
				    unsigned char *dmem, int dmemsize)
{
	int i;
	for (i = 0; i < imemsize; i += 4)
		if (cdn_apb_write(ADDR_IMEM + i,
				  (unsigned int)imem[i] << 0 |
				  (unsigned int)imem[i + 1] << 8 |
				  (unsigned int)imem[i + 2] << 16 |
				  (unsigned int)imem[i + 3] << 24))
			return CDN_ERR;
	for (i = 0; i < dmemsize; i += 4)
		if (cdn_apb_write(ADDR_DMEM + i,
				  (unsigned int)dmem[i] << 0 |
				  (unsigned int)dmem[i + 1] << 8 |
				  (unsigned int)dmem[i + 2] << 16 |
				  (unsigned int)dmem[i + 3] << 24))
			return CDN_ERR;
	return CDN_OK;
}

CDN_API_STATUS cdn_api_general_test_echo(unsigned int val,
					 CDN_BUS_TYPE bus_type)
{
	CDN_API_STATUS ret;
	if (!state.running) {
		if (!internal_apb_available())
			return CDN_BSY;
		state.bus_type = bus_type;
		state.rxenable = 1;
		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL, GENERAL_TEST_ECHO,
				      1, 4, val);
		return CDN_STARTED;
	}
	if (state.txenable && !internal_mbox_tx_process().txend)
		return CDN_BSY;
	if (state.rxenable && !internal_mbox_rx_process().rxend)
		return CDN_BSY;
	ret = internal_test_rx_head(MB_MODULE_ID_GENERAL, GENERAL_TEST_ECHO);
	if (ret != CDN_OK) {
		state.running = 0;
		return ret;
	}
	state.running = 0;
	if (val != internal_betoi(state.rxbuffer + INTERNAL_CMD_HEAD_SIZE, 4))
		return CDN_ERR;
	return CDN_OK;
}

CDN_API_STATUS cdn_api_general_test_echo_blocking(unsigned int val,
						  CDN_BUS_TYPE bus_type)
{
	internal_block_function(cdn_api_general_test_echo(val, bus_type));
}

CDN_API_STATUS cdn_api_general_test_echo_ext(uint8_t const *msg, uint8_t *resp,
					     uint16_t num_bytes,
					     CDN_BUS_TYPE bus_type)
{
	CDN_API_STATUS ret;

	if (!msg || !resp)
		return CDN_ERR;

	if ((num_bytes > GENERAL_TEST_ECHO_MAX_PAYLOAD) ||
	    (num_bytes < GENERAL_TEST_ECHO_MIN_PAYLOAD))
		return CDN_ERR;

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

		state.bus_type = bus_type;
		state.rxenable = 1;

		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL, GENERAL_TEST_ECHO,
				      1, -num_bytes, msg);

		return CDN_STARTED;
	}

	if (state.txenable && !internal_mbox_tx_process().txend)
		return CDN_BSY;

	if (state.rxenable && !internal_mbox_rx_process().rxend)
		return CDN_BSY;

	ret = internal_test_rx_head(MB_MODULE_ID_GENERAL, GENERAL_TEST_ECHO);

	if (ret != CDN_OK) {
		state.running = 0;
		return ret;
	}

	state.running = 0;

	memcpy(resp, state.rxbuffer + INTERNAL_CMD_HEAD_SIZE, num_bytes);

	if (memcmp(msg, resp, num_bytes) != 0)
		return CDN_ERR;

	return CDN_OK;
}

CDN_API_STATUS cdn_api_general_test_echo_ext_blocking(uint8_t const *msg,
						      uint8_t *resp,
						      uint16_t num_bytes,
						      CDN_BUS_TYPE bus_type)
{
	internal_block_function(cdn_api_general_test_echo_ext
				(msg, resp, num_bytes, bus_type)
	    );
}

CDN_API_STATUS cdn_api_general_getcurversion(unsigned short *ver,
					     unsigned short *verlib)
{
	unsigned int vh, vl, vlh, vll;
	if (cdn_apb_read(VER_L << 2, &vl))
		return CDN_ERR;
	if (cdn_apb_read(VER_H << 2, &vh))
		return CDN_ERR;
	if (cdn_apb_read(VER_LIB_L_ADDR << 2, &vll))
		return CDN_ERR;
	if (cdn_apb_read(VER_LIB_H_ADDR << 2, &vlh))
		return CDN_ERR;
	*ver = F_VER_MSB_RD(vh) << 8 | F_VER_LSB_RD(vl);
	*verlib = F_SW_LIB_VER_H_RD(vlh) << 8 | F_SW_LIB_VER_L_RD(vll);
	return CDN_OK;
}

CDN_API_STATUS cdn_api_get_event(uint32_t *events)
{
	uint32_t evt[4] = { 0 };

	if (!events) {
		printf("events pointer is NULL!\n");
		return CDN_ERR;
	}

	if (cdn_apb_read(SW_EVENTS0 << 2, &evt[0]) ||
	    cdn_apb_read(SW_EVENTS1 << 2, &evt[1]) ||
	    cdn_apb_read(SW_EVENTS2 << 2, &evt[2]) ||
	    cdn_apb_read(SW_EVENTS3 << 2, &evt[3])) {
		printf("Failed to read events registers.\n");
		return CDN_ERR;
	}

	*events = (evt[0] & 0xFF)
	    | ((evt[1] & 0xFF) << 8)
	    | ((evt[2] & 0xFF) << 16)
	    | ((evt[3] & 0xFF) << 24);

	return CDN_OK;
}

CDN_API_STATUS cdn_api_get_debug_reg_val(uint16_t *val)
{
	uint32_t dbg[2] = { 0 };

	if (!val) {
		printf("val pointer is NULL!\n");
		return CDN_ERR;
	}

	if (cdn_apb_read(SW_DEBUG_L << 2, &dbg[0]) ||
	    cdn_apb_read(SW_DEBUG_H << 2, &dbg[1])) {
		printf("Failed to read debug registers.\n");
		return CDN_ERR;
	}

	*val = (uint16_t) ((dbg[0] & 0xFF) | ((dbg[1] & 0xFF) << 8));

	return CDN_OK;
}

CDN_API_STATUS cdn_api_checkalive(void)
{
	unsigned int alive, newalive;
	uint8_t retries_left = 10;

	if (cdn_apb_read(KEEP_ALIVE << 2, &alive))
		return CDN_ERR;

	while (retries_left--) {
		udelay(1);

		if (cdn_apb_read(KEEP_ALIVE << 2, &newalive))
			return CDN_ERR;

		if (alive == newalive)
			continue;

		return CDN_OK;
	}

	printf("%s: keep-alive counter did not increment for 10us...\n", __func__);

	return CDN_BSY;
}

CDN_API_STATUS cdn_api_checkalive_blocking(void)
{
	internal_block_function(cdn_api_checkalive());
}

CDN_API_STATUS cdn_api_maincontrol(unsigned char mode, unsigned char *resp)
{
	if (!state.running) {
		if (!internal_apb_available())
			return CDN_BSY;
		state.bus_type = CDN_BUS_TYPE_APB;
		state.rxenable = 1;
		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL,
				      GENERAL_MAIN_CONTROL, 1, 1, mode);
		return CDN_STARTED;
	}
	INTERNAL_PROCESS_MESSAGES;
	internal_opcode_ok_or_return(MB_MODULE_ID_GENERAL,
				     GENERAL_MAIN_CONTROL_RESP);
	internal_readmsg(1, 1, resp);
	return CDN_OK;
}

CDN_API_STATUS cdn_api_maincontrol_blocking(unsigned char mode,
					    unsigned char *resp)
{
	internal_block_function(cdn_api_maincontrol(mode, resp));
}

CDN_API_STATUS cdn_api_apbconf(uint8_t dpcd_bus_sel, uint8_t dpcd_bus_lock,
			       uint8_t hdcp_bus_sel, uint8_t hdcp_bus_lock,
			       uint8_t capb_bus_sel, uint8_t capb_bus_lock,
			       uint8_t *dpcd_resp, uint8_t *hdcp_resp,
			       uint8_t *capb_resp)
{
	uint8_t resp;
	uint8_t set = 0;

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

		state.bus_type = CDN_BUS_TYPE_APB;
		state.rxenable = 1;

		set |= (dpcd_bus_sel)
		    ? (1 << GENERAL_BUS_SETTINGS_DPCD_BUS_BIT)
		    : 0;
		set |= (dpcd_bus_lock)
		    ? (1 << GENERAL_BUS_SETTINGS_DPCD_BUS_LOCK_BIT)
		    : 0;
		set |= (hdcp_bus_sel)
		    ? (1 << GENERAL_BUS_SETTINGS_HDCP_BUS_BIT)
		    : 0;
		set |= (hdcp_bus_lock)
		    ? (1 << GENERAL_BUS_SETTINGS_HDCP_BUS_LOCK_BIT)
		    : 0;
		set |= (capb_bus_sel)
		    ? (1 << GENERAL_BUS_SETTINGS_CAPB_OWNER_BIT)
		    : 0;
		set |= (capb_bus_lock)
		    ? (1 << GENERAL_BUS_SETTINGS_CAPB_OWNER_LOCK_BIT)
		    : 0;

		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL,
				      GENERAL_BUS_SETTINGS, 1, 1, set);

		return CDN_STARTED;
	}

	INTERNAL_PROCESS_MESSAGES;
	internal_opcode_ok_or_return(MB_MODULE_ID_GENERAL,
				     GENERAL_BUS_SETTINGS_RESP);

	/* Read one one-byte response */
	internal_readmsg(1, 1, &resp);

	*dpcd_resp =
	    (resp & (1 << GENERAL_BUS_SETTINGS_RESP_DPCD_BUS_BIT)) ? 1 : 0;
	*hdcp_resp =
	    (resp & (1 << GENERAL_BUS_SETTINGS_RESP_HDCP_BUS_BIT)) ? 1 : 0;
	*capb_resp =
	    (resp & (1 << GENERAL_BUS_SETTINGS_RESP_CAPB_OWNER_BIT)) ? 1 : 0;

	return CDN_OK;
}

CDN_API_STATUS cdn_api_apbconf_blocking(uint8_t dpcd_bus_sel,
					uint8_t dpcd_bus_lock,
					uint8_t hdcp_bus_sel,
					uint8_t hdcp_bus_lock,
					uint8_t capb_bus_sel,
					uint8_t capb_bus_lock,
					uint8_t *dpcd_resp,
					uint8_t *hdcp_resp,
					uint8_t *capb_resp)
{
	internal_block_function(cdn_api_apbconf(dpcd_bus_sel, dpcd_bus_lock,
						hdcp_bus_sel, hdcp_bus_lock,
						capb_bus_sel, capb_bus_lock,
						dpcd_resp, hdcp_resp,
						capb_resp));
}

CDN_API_STATUS cdn_api_setclock(unsigned char mhz)
{
	return cdn_apb_write(SW_CLK_H << 2, mhz);
}

CDN_API_STATUS cdn_api_general_read_register(unsigned int addr,
					     GENERAL_READ_REGISTER_RESPONSE
					     *resp)
{
	CDN_API_STATUS ret;
	if (!state.running) {
		if (!internal_apb_available())
			return CDN_BSY;
		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL,
				      GENERAL_READ_REGISTER, 1, 4, addr);
		state.bus_type = CDN_BUS_TYPE_APB;
		state.rxenable = 1;
		return CDN_STARTED;
	}
	INTERNAL_PROCESS_MESSAGES;
	ret = internal_test_rx_head(MB_MODULE_ID_GENERAL,
				    GENERAL_READ_REGISTER_RESP);
	if (ret != CDN_OK)
		return ret;
	internal_readmsg(2, 4, &resp->addr, 4, &resp->val);
	return CDN_OK;
}

CDN_API_STATUS
cdn_api_general_read_register_blocking(unsigned int addr,
				       GENERAL_READ_REGISTER_RESPONSE *resp)
{
	internal_block_function(cdn_api_general_read_register(addr, resp));
}

CDN_API_STATUS cdn_api_general_write_register(unsigned int addr,
					      unsigned int val)
{
	if (!state.running) {
		if (!internal_apb_available())
			return CDN_BSY;
		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL,
				      GENERAL_WRITE_REGISTER, 2, 4, addr, 4,
				      val);
		state.bus_type = CDN_BUS_TYPE_APB;
		return CDN_STARTED;
	}
	INTERNAL_PROCESS_MESSAGES;
	return CDN_OK;
}

CDN_API_STATUS cdn_api_general_write_register_blocking(unsigned int addr,
						       unsigned int val)
{
	internal_block_function(cdn_api_general_write_register(addr, val));
}

CDN_API_STATUS cdn_api_general_write_field(unsigned int addr,
					   unsigned char startbit,
					   unsigned char bitsno,
					   unsigned int val)
{
	if (!state.running) {
		if (!internal_apb_available())
			return CDN_BSY;
		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL, GENERAL_WRITE_FIELD,
				      4, 4, addr, 1, startbit, 1, bitsno, 4,
				      val);
		state.bus_type = CDN_BUS_TYPE_APB;
		return CDN_STARTED;
	}
	INTERNAL_PROCESS_MESSAGES;
	return CDN_OK;
}

CDN_API_STATUS cdn_api_general_write_field_blocking(unsigned int addr,
						    unsigned char startbit,
						    unsigned char bitsno,
						    unsigned int val)
{
	internal_block_function(cdn_api_general_write_field
				(addr, startbit, bitsno, val));
}

CDN_API_STATUS cdn_api_general_phy_test_access(uint8_t *resp)
{
	CDN_API_STATUS ret;

	*resp = 0;

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

		internal_tx_mkfullmsg(MB_MODULE_ID_GENERAL, GENERAL_TEST_ACCESS,
				      0);
		state.bus_type = CDN_BUS_TYPE_APB;
		state.rxenable = 1;

		return CDN_STARTED;
	}

	INTERNAL_PROCESS_MESSAGES;

	ret = internal_test_rx_head(MB_MODULE_ID_GENERAL, GENERAL_TEST_ACCESS);

	if (ret != CDN_OK)
		return ret;

	internal_readmsg(1, 1, resp);

	return CDN_OK;
}

CDN_API_STATUS cdn_api_general_phy_test_access_blocking(uint8_t *resp)
{
	internal_block_function(cdn_api_general_phy_test_access(resp));
}
