/*
 * HDMI CEC
 *
 * Based on the CEC code from hdmi_ti_4xxx_ip.c from Android.
 *
 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
 * Authors: Yong Zhi
 *	Mythri pk <mythripk@ti.com>
 *
 * Heavily modified to use the linux CEC framework:
 *
 * Copyright 2016-2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
 *
 * This program is free software; you may redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * 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.
 */

#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "dss.h"
#include "hdmi.h"
#include "hdmi4_core.h"
#include "hdmi4_cec.h"

/* HDMI CEC */
#define HDMI_CEC_DEV_ID                         0x900
#define HDMI_CEC_SPEC                           0x904

/* Not really a debug register, more a low-level control register */
#define HDMI_CEC_DBG_3                          0x91C
#define HDMI_CEC_TX_INIT                        0x920
#define HDMI_CEC_TX_DEST                        0x924
#define HDMI_CEC_SETUP                          0x938
#define HDMI_CEC_TX_COMMAND                     0x93C
#define HDMI_CEC_TX_OPERAND                     0x940
#define HDMI_CEC_TRANSMIT_DATA                  0x97C
#define HDMI_CEC_CA_7_0                         0x988
#define HDMI_CEC_CA_15_8                        0x98C
#define HDMI_CEC_INT_STATUS_0                   0x998
#define HDMI_CEC_INT_STATUS_1                   0x99C
#define HDMI_CEC_INT_ENABLE_0                   0x990
#define HDMI_CEC_INT_ENABLE_1                   0x994
#define HDMI_CEC_RX_CONTROL                     0x9B0
#define HDMI_CEC_RX_COUNT                       0x9B4
#define HDMI_CEC_RX_CMD_HEADER                  0x9B8
#define HDMI_CEC_RX_COMMAND                     0x9BC
#define HDMI_CEC_RX_OPERAND                     0x9C0

#define HDMI_CEC_TX_FIFO_INT_MASK		0x64
#define HDMI_CEC_RETRANSMIT_CNT_INT_MASK	0x2

#define HDMI_CORE_CEC_RETRY    200

static void hdmi_cec_received_msg(struct hdmi_core_data *core)
{
	u32 cnt = hdmi_read_reg(core->base, HDMI_CEC_RX_COUNT) & 0xff;

	/* While there are CEC frames in the FIFO */
	while (cnt & 0x70) {
		/* and the frame doesn't have an error */
		if (!(cnt & 0x80)) {
			struct cec_msg msg = {};
			unsigned int i;

			/* then read the message */
			msg.len = cnt & 0xf;
			msg.msg[0] = hdmi_read_reg(core->base,
						   HDMI_CEC_RX_CMD_HEADER);
			msg.msg[1] = hdmi_read_reg(core->base,
						   HDMI_CEC_RX_COMMAND);
			for (i = 0; i < msg.len; i++) {
				unsigned int reg = HDMI_CEC_RX_OPERAND + i * 4;

				msg.msg[2 + i] =
					hdmi_read_reg(core->base, reg);
			}
			msg.len += 2;
			cec_received_msg(core->adap, &msg);
		}
		/* Clear the current frame from the FIFO */
		hdmi_write_reg(core->base, HDMI_CEC_RX_CONTROL, 1);
		/* Wait until the current frame is cleared */
		while (hdmi_read_reg(core->base, HDMI_CEC_RX_CONTROL) & 1)
			udelay(1);
		/*
		 * Re-read the count register and loop to see if there are
		 * more messages in the FIFO.
		 */
		cnt = hdmi_read_reg(core->base, HDMI_CEC_RX_COUNT) & 0xff;
	}
}

static void hdmi_cec_transmit_fifo_empty(struct hdmi_core_data *core, u32 stat1)
{
	if (stat1 & 2) {
		u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);

		cec_transmit_done(core->adap,
				  CEC_TX_STATUS_NACK |
				  CEC_TX_STATUS_MAX_RETRIES,
				  0, (dbg3 >> 4) & 7, 0, 0);
	} else if (stat1 & 1) {
		cec_transmit_done(core->adap,
				  CEC_TX_STATUS_ARB_LOST |
				  CEC_TX_STATUS_MAX_RETRIES,
				  0, 0, 0, 0);
	} else if (stat1 == 0) {
		cec_transmit_done(core->adap, CEC_TX_STATUS_OK,
				  0, 0, 0, 0);
	}
}

void hdmi4_cec_irq(struct hdmi_core_data *core)
{
	u32 stat0 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0);
	u32 stat1 = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_1);

	hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0, stat0);
	hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, stat1);

	if (stat0 & 0x40)
		REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
	else if (stat0 & 0x24)
		hdmi_cec_transmit_fifo_empty(core, stat1);
	if (stat1 & 2) {
		u32 dbg3 = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);

		cec_transmit_done(core->adap,
				  CEC_TX_STATUS_NACK |
				  CEC_TX_STATUS_MAX_RETRIES,
				  0, (dbg3 >> 4) & 7, 0, 0);
	} else if (stat1 & 1) {
		cec_transmit_done(core->adap,
				  CEC_TX_STATUS_ARB_LOST |
				  CEC_TX_STATUS_MAX_RETRIES,
				  0, 0, 0, 0);
	}
	if (stat0 & 0x02)
		hdmi_cec_received_msg(core);
	if (stat1 & 0x3)
		REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
}

static bool hdmi_cec_clear_tx_fifo(struct cec_adapter *adap)
{
	struct hdmi_core_data *core = cec_get_drvdata(adap);
	int retry = HDMI_CORE_CEC_RETRY;
	int temp;

	REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, 0x1, 7, 7);
	while (retry) {
		temp = hdmi_read_reg(core->base, HDMI_CEC_DBG_3);
		if (FLD_GET(temp, 7, 7) == 0)
			break;
		retry--;
	}
	return retry != 0;
}

static bool hdmi_cec_clear_rx_fifo(struct cec_adapter *adap)
{
	struct hdmi_core_data *core = cec_get_drvdata(adap);
	int retry = HDMI_CORE_CEC_RETRY;
	int temp;

	hdmi_write_reg(core->base, HDMI_CEC_RX_CONTROL, 0x3);
	retry = HDMI_CORE_CEC_RETRY;
	while (retry) {
		temp = hdmi_read_reg(core->base, HDMI_CEC_RX_CONTROL);
		if (FLD_GET(temp, 1, 0) == 0)
			break;
		retry--;
	}
	return retry != 0;
}

static int hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable)
{
	struct hdmi_core_data *core = cec_get_drvdata(adap);
	int temp, err;

	if (!enable) {
		hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0);
		hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0);
		REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0, 3, 3);
		hdmi_wp_clear_irqenable(core->wp, HDMI_IRQ_CORE);
		hdmi_wp_set_irqstatus(core->wp, HDMI_IRQ_CORE);
		hdmi4_core_disable(NULL);
		return 0;
	}
	err = hdmi4_core_enable(NULL);
	if (err)
		return err;

	/* Clear TX FIFO */
	if (!hdmi_cec_clear_tx_fifo(adap)) {
		pr_err("cec-%s: could not clear TX FIFO\n", adap->name);
		return -EIO;
	}

	/* Clear RX FIFO */
	if (!hdmi_cec_clear_rx_fifo(adap)) {
		pr_err("cec-%s: could not clear RX FIFO\n", adap->name);
		return -EIO;
	}

	/* Clear CEC interrupts */
	hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1,
		hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_1));
	hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0,
		hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_0));

	/* Enable HDMI core interrupts */
	hdmi_wp_set_irqenable(core->wp, HDMI_IRQ_CORE);
	/* Unmask CEC interrupt */
	REG_FLD_MOD(core->base, HDMI_CORE_SYS_INTR_UNMASK4, 0x1, 3, 3);
	/*
	 * Enable CEC interrupts:
	 * Transmit Buffer Full/Empty Change event
	 * Transmitter FIFO Empty event
	 * Receiver FIFO Not Empty event
	 */
	hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_0, 0x26);
	/*
	 * Enable CEC interrupts:
	 * RX FIFO Overrun Error event
	 * Short Pulse Detected event
	 * Frame Retransmit Count Exceeded event
	 * Start Bit Irregularity event
	 */
	hdmi_write_reg(core->base, HDMI_CEC_INT_ENABLE_1, 0x0f);

	/* cec calibration enable (self clearing) */
	hdmi_write_reg(core->base, HDMI_CEC_SETUP, 0x03);
	msleep(20);
	hdmi_write_reg(core->base, HDMI_CEC_SETUP, 0x04);

	temp = hdmi_read_reg(core->base, HDMI_CEC_SETUP);
	if (FLD_GET(temp, 4, 4) != 0) {
		temp = FLD_MOD(temp, 0, 4, 4);
		hdmi_write_reg(core->base, HDMI_CEC_SETUP, temp);

		/*
		 * If we enabled CEC in middle of a CEC message on the bus,
		 * we could have start bit irregularity and/or short
		 * pulse event. Clear them now.
		 */
		temp = hdmi_read_reg(core->base, HDMI_CEC_INT_STATUS_1);
		temp = FLD_MOD(0x0, 0x5, 2, 0);
		hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1, temp);
	}
	return 0;
}

static int hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
{
	struct hdmi_core_data *core = cec_get_drvdata(adap);
	u32 v;

	if (log_addr == CEC_LOG_ADDR_INVALID) {
		hdmi_write_reg(core->base, HDMI_CEC_CA_7_0, 0);
		hdmi_write_reg(core->base, HDMI_CEC_CA_15_8, 0);
		return 0;
	}
	if (log_addr <= 7) {
		v = hdmi_read_reg(core->base, HDMI_CEC_CA_7_0);
		v |= 1 << log_addr;
		hdmi_write_reg(core->base, HDMI_CEC_CA_7_0, v);
	} else {
		v = hdmi_read_reg(core->base, HDMI_CEC_CA_15_8);
		v |= 1 << (log_addr - 8);
		hdmi_write_reg(core->base, HDMI_CEC_CA_15_8, v);
	}
	return 0;
}

static int hdmi_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
				   u32 signal_free_time, struct cec_msg *msg)
{
	struct hdmi_core_data *core = cec_get_drvdata(adap);
	int temp;
	u32 i;

	/* Clear TX FIFO */
	if (!hdmi_cec_clear_tx_fifo(adap)) {
		pr_err("cec-%s: could not clear TX FIFO for transmit\n",
		       adap->name);
		return -EIO;
	}

	/* Clear TX interrupts */
	hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_0,
		       HDMI_CEC_TX_FIFO_INT_MASK);

	hdmi_write_reg(core->base, HDMI_CEC_INT_STATUS_1,
		       HDMI_CEC_RETRANSMIT_CNT_INT_MASK);

	/* Set the retry count */
	REG_FLD_MOD(core->base, HDMI_CEC_DBG_3, attempts - 1, 6, 4);

	/* Set the initiator addresses */
	hdmi_write_reg(core->base, HDMI_CEC_TX_INIT, cec_msg_initiator(msg));

	/* Set destination id */
	temp = cec_msg_destination(msg);
	if (msg->len == 1)
		temp |= 0x80;
	hdmi_write_reg(core->base, HDMI_CEC_TX_DEST, temp);
	if (msg->len == 1)
		return 0;

	/* Setup command and arguments for the command */
	hdmi_write_reg(core->base, HDMI_CEC_TX_COMMAND, msg->msg[1]);

	for (i = 0; i < msg->len - 2; i++)
		hdmi_write_reg(core->base, HDMI_CEC_TX_OPERAND + i * 4,
			       msg->msg[2 + i]);

	/* Operand count */
	hdmi_write_reg(core->base, HDMI_CEC_TRANSMIT_DATA,
		       (msg->len - 2) | 0x10);
	return 0;
}

static const struct cec_adap_ops hdmi_cec_adap_ops = {
	.adap_enable = hdmi_cec_adap_enable,
	.adap_log_addr = hdmi_cec_adap_log_addr,
	.adap_transmit = hdmi_cec_adap_transmit,
};

void hdmi4_cec_set_phys_addr(struct hdmi_core_data *core, u16 pa)
{
	cec_s_phys_addr(core->adap, pa, false);
}

int hdmi4_cec_init(struct platform_device *pdev, struct hdmi_core_data *core,
		  struct hdmi_wp_data *wp)
{
	const u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS |
			 CEC_CAP_PASSTHROUGH | CEC_CAP_RC;
	int ret;

	core->adap = cec_allocate_adapter(&hdmi_cec_adap_ops, core,
		"omap4", caps, CEC_MAX_LOG_ADDRS);
	ret = PTR_ERR_OR_ZERO(core->adap);
	if (ret < 0)
		return ret;
	core->wp = wp;

	/*
	 * Initialize CEC clock divider: CEC needs 2MHz clock hence
	 * set the devider to 24 to get 48/24=2MHz clock
	 */
	REG_FLD_MOD(core->wp->base, HDMI_WP_CLK, 0x18, 5, 0);

	ret = cec_register_adapter(core->adap, &pdev->dev);
	if (ret < 0) {
		cec_delete_adapter(core->adap);
		return ret;
	}
	return 0;
}

void hdmi4_cec_uninit(struct hdmi_core_data *core)
{
	cec_unregister_adapter(core->adap);
}
