// SPDX-License-Identifier: GPL-2.0-only
/*
 *  cobalt interrupt handling
 *
 *  Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates.
 *  All rights reserved.
 */

#include <media/i2c/adv7604.h>

#include "cobalt-driver.h"
#include "cobalt-irq.h"
#include "cobalt-omnitek.h"

static void cobalt_dma_stream_queue_handler(struct cobalt_stream *s)
{
	struct cobalt *cobalt = s->cobalt;
	int rx = s->video_channel;
	struct m00473_freewheel_regmap __iomem *fw =
		COBALT_CVI_FREEWHEEL(s->cobalt, rx);
	struct m00233_video_measure_regmap __iomem *vmr =
		COBALT_CVI_VMR(s->cobalt, rx);
	struct m00389_cvi_regmap __iomem *cvi =
		COBALT_CVI(s->cobalt, rx);
	struct m00479_clk_loss_detector_regmap __iomem *clkloss =
		COBALT_CVI_CLK_LOSS(s->cobalt, rx);
	struct cobalt_buffer *cb;
	bool skip = false;

	spin_lock(&s->irqlock);

	if (list_empty(&s->bufs)) {
		pr_err("no buffers!\n");
		spin_unlock(&s->irqlock);
		return;
	}

	/* Give the fresh filled up buffer to the user.
	 * Note that the interrupt is only sent if the DMA can continue
	 * with a new buffer, so it is always safe to return this buffer
	 * to userspace. */
	cb = list_first_entry(&s->bufs, struct cobalt_buffer, list);
	list_del(&cb->list);
	spin_unlock(&s->irqlock);

	if (s->is_audio || s->is_output)
		goto done;

	if (s->unstable_frame) {
		uint32_t stat = ioread32(&vmr->irq_status);

		iowrite32(stat, &vmr->irq_status);
		if (!(ioread32(&vmr->status) &
		      M00233_STATUS_BITMAP_INIT_DONE_MSK)) {
			cobalt_dbg(1, "!init_done\n");
			if (s->enable_freewheel)
				goto restart_fw;
			goto done;
		}

		if (ioread32(&clkloss->status) &
		    M00479_STATUS_BITMAP_CLOCK_MISSING_MSK) {
			iowrite32(0, &clkloss->ctrl);
			iowrite32(M00479_CTRL_BITMAP_ENABLE_MSK, &clkloss->ctrl);
			cobalt_dbg(1, "no clock\n");
			if (s->enable_freewheel)
				goto restart_fw;
			goto done;
		}
		if ((stat & (M00233_IRQ_STATUS_BITMAP_VACTIVE_AREA_MSK |
			     M00233_IRQ_STATUS_BITMAP_HACTIVE_AREA_MSK)) ||
				ioread32(&vmr->vactive_area) != s->timings.bt.height ||
				ioread32(&vmr->hactive_area) != s->timings.bt.width) {
			cobalt_dbg(1, "unstable\n");
			if (s->enable_freewheel)
				goto restart_fw;
			goto done;
		}
		if (!s->enable_cvi) {
			s->enable_cvi = true;
			iowrite32(M00389_CONTROL_BITMAP_ENABLE_MSK, &cvi->control);
			goto done;
		}
		if (!(ioread32(&cvi->status) & M00389_STATUS_BITMAP_LOCK_MSK)) {
			cobalt_dbg(1, "cvi no lock\n");
			if (s->enable_freewheel)
				goto restart_fw;
			goto done;
		}
		if (!s->enable_freewheel) {
			cobalt_dbg(1, "stable\n");
			s->enable_freewheel = true;
			iowrite32(0, &fw->ctrl);
			goto done;
		}
		cobalt_dbg(1, "enabled fw\n");
		iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK |
			  M00233_CONTROL_BITMAP_ENABLE_INTERRUPT_MSK,
			  &vmr->control);
		iowrite32(M00473_CTRL_BITMAP_ENABLE_MSK, &fw->ctrl);
		s->enable_freewheel = false;
		s->unstable_frame = false;
		s->skip_first_frames = 2;
		skip = true;
		goto done;
	}
	if (ioread32(&fw->status) & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) {
restart_fw:
		cobalt_dbg(1, "lost lock\n");
		iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK,
			  &vmr->control);
		iowrite32(M00473_CTRL_BITMAP_ENABLE_MSK |
			  M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK,
			  &fw->ctrl);
		iowrite32(0, &cvi->control);
		s->unstable_frame = true;
		s->enable_freewheel = false;
		s->enable_cvi = false;
	}
done:
	if (s->skip_first_frames) {
		skip = true;
		s->skip_first_frames--;
	}
	cb->vb.vb2_buf.timestamp = ktime_get_ns();
	/* TODO: the sequence number should be read from the FPGA so we
	   also know about dropped frames. */
	cb->vb.sequence = s->sequence++;
	vb2_buffer_done(&cb->vb.vb2_buf,
			(skip || s->unstable_frame) ?
			VB2_BUF_STATE_REQUEUEING : VB2_BUF_STATE_DONE);
}

irqreturn_t cobalt_irq_handler(int irq, void *dev_id)
{
	struct cobalt *cobalt = (struct cobalt *)dev_id;
	u32 dma_interrupt =
		cobalt_read_bar0(cobalt, DMA_INTERRUPT_STATUS_REG) & 0xffff;
	u32 mask = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_MASK);
	u32 edge = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_EDGE);
	int i;

	/* Clear DMA interrupt */
	cobalt_write_bar0(cobalt, DMA_INTERRUPT_STATUS_REG, dma_interrupt);
	cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK, mask & ~edge);
	cobalt_write_bar1(cobalt, COBALT_SYS_STAT_EDGE, edge);

	for (i = 0; i < COBALT_NUM_STREAMS; i++) {
		struct cobalt_stream *s = &cobalt->streams[i];
		unsigned dma_fifo_mask = s->dma_fifo_mask;

		if (dma_interrupt & (1 << s->dma_channel)) {
			cobalt->irq_dma[i]++;
			/* Give fresh buffer to user and chain newly
			 * queued buffers */
			cobalt_dma_stream_queue_handler(s);
			if (!s->is_audio) {
				edge &= ~dma_fifo_mask;
				cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK,
						  mask & ~edge);
			}
		}
		if (s->is_audio)
			continue;
		if (edge & s->adv_irq_mask)
			set_bit(COBALT_STREAM_FL_ADV_IRQ, &s->flags);
		if ((edge & mask & dma_fifo_mask) && vb2_is_streaming(&s->q)) {
			cobalt_info("full rx FIFO %d\n", i);
			cobalt->irq_full_fifo++;
		}
	}

	queue_work(cobalt->irq_work_queues, &cobalt->irq_work_queue);

	if (edge & mask & (COBALT_SYSSTAT_VI0_INT1_MSK |
			   COBALT_SYSSTAT_VI1_INT1_MSK |
			   COBALT_SYSSTAT_VI2_INT1_MSK |
			   COBALT_SYSSTAT_VI3_INT1_MSK |
			   COBALT_SYSSTAT_VIHSMA_INT1_MSK |
			   COBALT_SYSSTAT_VOHSMA_INT1_MSK))
		cobalt->irq_adv1++;
	if (edge & mask & (COBALT_SYSSTAT_VI0_INT2_MSK |
			   COBALT_SYSSTAT_VI1_INT2_MSK |
			   COBALT_SYSSTAT_VI2_INT2_MSK |
			   COBALT_SYSSTAT_VI3_INT2_MSK |
			   COBALT_SYSSTAT_VIHSMA_INT2_MSK))
		cobalt->irq_adv2++;
	if (edge & mask & COBALT_SYSSTAT_VOHSMA_INT1_MSK)
		cobalt->irq_advout++;
	if (dma_interrupt)
		cobalt->irq_dma_tot++;
	if (!(edge & mask) && !dma_interrupt)
		cobalt->irq_none++;
	dma_interrupt = cobalt_read_bar0(cobalt, DMA_INTERRUPT_STATUS_REG);

	return IRQ_HANDLED;
}

void cobalt_irq_work_handler(struct work_struct *work)
{
	struct cobalt *cobalt =
		container_of(work, struct cobalt, irq_work_queue);
	int i;

	for (i = 0; i < COBALT_NUM_NODES; i++) {
		struct cobalt_stream *s = &cobalt->streams[i];

		if (test_and_clear_bit(COBALT_STREAM_FL_ADV_IRQ, &s->flags)) {
			u32 mask;

			v4l2_subdev_call(cobalt->streams[i].sd, core,
					interrupt_service_routine, 0, NULL);
			mask = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_MASK);
			cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK,
				mask | s->adv_irq_mask);
		}
	}
}

void cobalt_irq_log_status(struct cobalt *cobalt)
{
	u32 mask;
	int i;

	cobalt_info("irq: adv1=%u adv2=%u advout=%u none=%u full=%u\n",
		    cobalt->irq_adv1, cobalt->irq_adv2, cobalt->irq_advout,
		    cobalt->irq_none, cobalt->irq_full_fifo);
	cobalt_info("irq: dma_tot=%u (", cobalt->irq_dma_tot);
	for (i = 0; i < COBALT_NUM_STREAMS; i++)
		pr_cont("%s%u", i ? "/" : "", cobalt->irq_dma[i]);
	pr_cont(")\n");
	cobalt->irq_dma_tot = cobalt->irq_adv1 = cobalt->irq_adv2 = 0;
	cobalt->irq_advout = cobalt->irq_none = cobalt->irq_full_fifo = 0;
	memset(cobalt->irq_dma, 0, sizeof(cobalt->irq_dma));

	mask = cobalt_read_bar1(cobalt, COBALT_SYS_STAT_MASK);
	cobalt_write_bar1(cobalt, COBALT_SYS_STAT_MASK,
			mask |
			COBALT_SYSSTAT_VI0_LOST_DATA_MSK |
			COBALT_SYSSTAT_VI1_LOST_DATA_MSK |
			COBALT_SYSSTAT_VI2_LOST_DATA_MSK |
			COBALT_SYSSTAT_VI3_LOST_DATA_MSK |
			COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK |
			COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK |
			COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK |
			COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK);
}
