/*
 * Copyright (C) STMicroelectronics SA 2014
 * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
 * License terms:  GNU General Public License (GPL), version 2
 */

#include <linux/delay.h>

#include "bdisp.h"
#include "bdisp-filter.h"
#include "bdisp-reg.h"

/* Max width of the source frame in a single node */
#define MAX_SRC_WIDTH           2048

/* Reset & boot poll config */
#define POLL_RST_MAX            50
#define POLL_RST_DELAY_MS       20

enum bdisp_target_plan {
	BDISP_RGB,
	BDISP_Y,
	BDISP_CBCR
};

struct bdisp_op_cfg {
	bool cconv;          /* RGB - YUV conversion */
	bool hflip;          /* Horizontal flip */
	bool vflip;          /* Vertical flip */
	bool wide;           /* Wide (>MAX_SRC_WIDTH) */
	bool scale;          /* Scale */
	u16  h_inc;          /* Horizontal increment in 6.10 format */
	u16  v_inc;          /* Vertical increment in 6.10 format */
	bool src_interlaced; /* is the src an interlaced buffer */
	u8   src_nbp;        /* nb of planes of the src */
	bool src_yuv;        /* is the src a YUV color format */
	bool src_420;        /* is the src 4:2:0 chroma subsampled */
	u8   dst_nbp;        /* nb of planes of the dst */
	bool dst_yuv;        /* is the dst a YUV color format */
	bool dst_420;        /* is the dst 4:2:0 chroma subsampled */
};

struct bdisp_filter_addr {
	u16 min;             /* Filter min scale factor (6.10 fixed point) */
	u16 max;             /* Filter max scale factor (6.10 fixed point) */
	void *virt;          /* Virtual address for filter table */
	dma_addr_t paddr;    /* Physical address for filter table */
};

static struct bdisp_filter_addr bdisp_h_filter[NB_H_FILTER];
static struct bdisp_filter_addr bdisp_v_filter[NB_V_FILTER];

/**
 * bdisp_hw_reset
 * @bdisp:      bdisp entity
 *
 * Resets HW
 *
 * RETURNS:
 * 0 on success.
 */
int bdisp_hw_reset(struct bdisp_dev *bdisp)
{
	unsigned int i;

	dev_dbg(bdisp->dev, "%s\n", __func__);

	/* Mask Interrupt */
	writel(0, bdisp->regs + BLT_ITM0);

	/* Reset */
	writel(readl(bdisp->regs + BLT_CTL) | BLT_CTL_RESET,
	       bdisp->regs + BLT_CTL);
	writel(0, bdisp->regs + BLT_CTL);

	/* Wait for reset done */
	for (i = 0; i < POLL_RST_MAX; i++) {
		if (readl(bdisp->regs + BLT_STA1) & BLT_STA1_IDLE)
			break;
		msleep(POLL_RST_DELAY_MS);
	}
	if (i == POLL_RST_MAX)
		dev_err(bdisp->dev, "Reset timeout\n");

	return (i == POLL_RST_MAX) ? -EAGAIN : 0;
}

/**
 * bdisp_hw_get_and_clear_irq
 * @bdisp:      bdisp entity
 *
 * Read then reset interrupt status
 *
 * RETURNS:
 * 0 if expected interrupt was raised.
 */
int bdisp_hw_get_and_clear_irq(struct bdisp_dev *bdisp)
{
	u32 its;

	its = readl(bdisp->regs + BLT_ITS);

	/* Check for the only expected IT: LastNode of AQ1 */
	if (!(its & BLT_ITS_AQ1_LNA)) {
		dev_dbg(bdisp->dev, "Unexpected IT status: 0x%08X\n", its);
		writel(its, bdisp->regs + BLT_ITS);
		return -1;
	}

	/* Clear and mask */
	writel(its, bdisp->regs + BLT_ITS);
	writel(0, bdisp->regs + BLT_ITM0);

	return 0;
}

/**
 * bdisp_hw_free_nodes
 * @ctx:        bdisp context
 *
 * Free node memory
 *
 * RETURNS:
 * None
 */
void bdisp_hw_free_nodes(struct bdisp_ctx *ctx)
{
	if (ctx && ctx->node[0]) {
		DEFINE_DMA_ATTRS(attrs);

		dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
		dma_free_attrs(ctx->bdisp_dev->dev,
			       sizeof(struct bdisp_node) * MAX_NB_NODE,
			       ctx->node[0], ctx->node_paddr[0], &attrs);
	}
}

/**
 * bdisp_hw_alloc_nodes
 * @ctx:        bdisp context
 *
 * Allocate dma memory for nodes
 *
 * RETURNS:
 * 0 on success
 */
int bdisp_hw_alloc_nodes(struct bdisp_ctx *ctx)
{
	struct device *dev = ctx->bdisp_dev->dev;
	unsigned int i, node_size = sizeof(struct bdisp_node);
	void *base;
	dma_addr_t paddr;
	DEFINE_DMA_ATTRS(attrs);

	/* Allocate all the nodes within a single memory page */
	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
	base = dma_alloc_attrs(dev, node_size * MAX_NB_NODE, &paddr,
			       GFP_KERNEL | GFP_DMA, &attrs);
	if (!base) {
		dev_err(dev, "%s no mem\n", __func__);
		return -ENOMEM;
	}

	memset(base, 0, node_size * MAX_NB_NODE);

	for (i = 0; i < MAX_NB_NODE; i++) {
		ctx->node[i] = base;
		ctx->node_paddr[i] = paddr;
		dev_dbg(dev, "node[%d]=0x%p (paddr=%pad)\n", i, ctx->node[i],
			&paddr);
		base += node_size;
		paddr += node_size;
	}

	return 0;
}

/**
 * bdisp_hw_free_filters
 * @dev:        device
 *
 * Free filters memory
 *
 * RETURNS:
 * None
 */
void bdisp_hw_free_filters(struct device *dev)
{
	int size = (BDISP_HF_NB * NB_H_FILTER) + (BDISP_VF_NB * NB_V_FILTER);

	if (bdisp_h_filter[0].virt) {
		DEFINE_DMA_ATTRS(attrs);

		dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
		dma_free_attrs(dev, size, bdisp_h_filter[0].virt,
			       bdisp_h_filter[0].paddr, &attrs);
	}
}

/**
 * bdisp_hw_alloc_filters
 * @dev:        device
 *
 * Allocate dma memory for filters
 *
 * RETURNS:
 * 0 on success
 */
int bdisp_hw_alloc_filters(struct device *dev)
{
	unsigned int i, size;
	void *base;
	dma_addr_t paddr;
	DEFINE_DMA_ATTRS(attrs);

	/* Allocate all the filters within a single memory page */
	size = (BDISP_HF_NB * NB_H_FILTER) + (BDISP_VF_NB * NB_V_FILTER);
	dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
	base = dma_alloc_attrs(dev, size, &paddr, GFP_KERNEL | GFP_DMA, &attrs);
	if (!base)
		return -ENOMEM;

	/* Setup filter addresses */
	for (i = 0; i < NB_H_FILTER; i++) {
		bdisp_h_filter[i].min = bdisp_h_spec[i].min;
		bdisp_h_filter[i].max = bdisp_h_spec[i].max;
		memcpy(base, bdisp_h_spec[i].coef, BDISP_HF_NB);
		bdisp_h_filter[i].virt = base;
		bdisp_h_filter[i].paddr = paddr;
		base += BDISP_HF_NB;
		paddr += BDISP_HF_NB;
	}

	for (i = 0; i < NB_V_FILTER; i++) {
		bdisp_v_filter[i].min = bdisp_v_spec[i].min;
		bdisp_v_filter[i].max = bdisp_v_spec[i].max;
		memcpy(base, bdisp_v_spec[i].coef, BDISP_VF_NB);
		bdisp_v_filter[i].virt = base;
		bdisp_v_filter[i].paddr = paddr;
		base += BDISP_VF_NB;
		paddr += BDISP_VF_NB;
	}

	return 0;
}

/**
 * bdisp_hw_get_hf_addr
 * @inc:        resize increment
 *
 * Find the horizontal filter table that fits the resize increment
 *
 * RETURNS:
 * table physical address
 */
static dma_addr_t bdisp_hw_get_hf_addr(u16 inc)
{
	unsigned int i;

	for (i = NB_H_FILTER - 1; i > 0; i--)
		if ((bdisp_h_filter[i].min < inc) &&
		    (inc <= bdisp_h_filter[i].max))
			break;

	return bdisp_h_filter[i].paddr;
}

/**
 * bdisp_hw_get_vf_addr
 * @inc:        resize increment
 *
 * Find the vertical filter table that fits the resize increment
 *
 * RETURNS:
 * table physical address
 */
static dma_addr_t bdisp_hw_get_vf_addr(u16 inc)
{
	unsigned int i;

	for (i = NB_V_FILTER - 1; i > 0; i--)
		if ((bdisp_v_filter[i].min < inc) &&
		    (inc <= bdisp_v_filter[i].max))
			break;

	return bdisp_v_filter[i].paddr;
}

/**
 * bdisp_hw_get_inc
 * @from:       input size
 * @to:         output size
 * @inc:        resize increment in 6.10 format
 *
 * Computes the increment (inverse of scale) in 6.10 format
 *
 * RETURNS:
 * 0 on success
 */
static int bdisp_hw_get_inc(u32 from, u32 to, u16 *inc)
{
	u32 tmp;

	if (!to)
		return -EINVAL;

	if (to == from) {
		*inc = 1 << 10;
		return 0;
	}

	tmp = (from << 10) / to;
	if ((tmp > 0xFFFF) || (!tmp))
		/* overflow (downscale x 63) or too small (upscale x 1024) */
		return -EINVAL;

	*inc = (u16)tmp;

	return 0;
}

/**
 * bdisp_hw_get_hv_inc
 * @ctx:        device context
 * @h_inc:      horizontal increment
 * @v_inc:      vertical increment
 *
 * Computes the horizontal & vertical increments (inverse of scale)
 *
 * RETURNS:
 * 0 on success
 */
static int bdisp_hw_get_hv_inc(struct bdisp_ctx *ctx, u16 *h_inc, u16 *v_inc)
{
	u32 src_w, src_h, dst_w, dst_h;

	src_w = ctx->src.crop.width;
	src_h = ctx->src.crop.height;
	dst_w = ctx->dst.crop.width;
	dst_h = ctx->dst.crop.height;

	if (bdisp_hw_get_inc(src_w, dst_w, h_inc) ||
	    bdisp_hw_get_inc(src_h, dst_h, v_inc)) {
		dev_err(ctx->bdisp_dev->dev,
			"scale factors failed (%dx%d)->(%dx%d)\n",
			src_w, src_h, dst_w, dst_h);
		return -EINVAL;
	}

	return 0;
}

/**
 * bdisp_hw_get_op_cfg
 * @ctx:        device context
 * @c:          operation configuration
 *
 * Check which blitter operations are expected and sets the scaling increments
 *
 * RETURNS:
 * 0 on success
 */
static int bdisp_hw_get_op_cfg(struct bdisp_ctx *ctx, struct bdisp_op_cfg *c)
{
	struct device *dev = ctx->bdisp_dev->dev;
	struct bdisp_frame *src = &ctx->src;
	struct bdisp_frame *dst = &ctx->dst;

	if (src->width > MAX_SRC_WIDTH * MAX_VERTICAL_STRIDES) {
		dev_err(dev, "Image width out of HW caps\n");
		return -EINVAL;
	}

	c->wide = src->width > MAX_SRC_WIDTH;

	c->hflip = ctx->hflip;
	c->vflip = ctx->vflip;

	c->src_interlaced = (src->field == V4L2_FIELD_INTERLACED);

	c->src_nbp = src->fmt->nb_planes;
	c->src_yuv = (src->fmt->pixelformat == V4L2_PIX_FMT_NV12) ||
			(src->fmt->pixelformat == V4L2_PIX_FMT_YUV420);
	c->src_420 = c->src_yuv;

	c->dst_nbp = dst->fmt->nb_planes;
	c->dst_yuv = (dst->fmt->pixelformat == V4L2_PIX_FMT_NV12) ||
			(dst->fmt->pixelformat == V4L2_PIX_FMT_YUV420);
	c->dst_420 = c->dst_yuv;

	c->cconv = (c->src_yuv != c->dst_yuv);

	if (bdisp_hw_get_hv_inc(ctx, &c->h_inc, &c->v_inc)) {
		dev_err(dev, "Scale factor out of HW caps\n");
		return -EINVAL;
	}

	/* Deinterlacing adjustment : stretch a field to a frame */
	if (c->src_interlaced)
		c->v_inc /= 2;

	if ((c->h_inc != (1 << 10)) || (c->v_inc != (1 << 10)))
		c->scale = true;
	else
		c->scale = false;

	return 0;
}

/**
 * bdisp_hw_color_format
 * @pixelformat: v4l2 pixel format
 *
 * v4l2 to bdisp pixel format convert
 *
 * RETURNS:
 * bdisp pixel format
 */
static u32 bdisp_hw_color_format(u32 pixelformat)
{
	u32 ret;

	switch (pixelformat) {
	case V4L2_PIX_FMT_YUV420:
		ret = (BDISP_YUV_3B << BLT_TTY_COL_SHIFT);
		break;
	case V4L2_PIX_FMT_NV12:
		ret = (BDISP_NV12 << BLT_TTY_COL_SHIFT) | BLT_TTY_BIG_END;
		break;
	case V4L2_PIX_FMT_RGB565:
		ret = (BDISP_RGB565 << BLT_TTY_COL_SHIFT);
		break;
	case V4L2_PIX_FMT_XBGR32: /* This V4L format actually refers to xRGB */
		ret = (BDISP_XRGB8888 << BLT_TTY_COL_SHIFT);
		break;
	case V4L2_PIX_FMT_RGB24:  /* RGB888 format */
		ret = (BDISP_RGB888 << BLT_TTY_COL_SHIFT) | BLT_TTY_BIG_END;
		break;
	case V4L2_PIX_FMT_ABGR32: /* This V4L format actually refers to ARGB */

	default:
		ret = (BDISP_ARGB8888 << BLT_TTY_COL_SHIFT) | BLT_TTY_ALPHA_R;
		break;
	}

	return ret;
}

/**
 * bdisp_hw_build_node
 * @ctx:        device context
 * @cfg:        operation configuration
 * @node:       node to be set
 * @t_plan:     whether the node refers to a RGB/Y or a CbCr plane
 * @src_x_offset: x offset in the source image
 *
 * Build a node
 *
 * RETURNS:
 * None
 */
static void bdisp_hw_build_node(struct bdisp_ctx *ctx,
				struct bdisp_op_cfg *cfg,
				struct bdisp_node *node,
				enum bdisp_target_plan t_plan, int src_x_offset)
{
	struct bdisp_frame *src = &ctx->src;
	struct bdisp_frame *dst = &ctx->dst;
	u16 h_inc, v_inc, yh_inc, yv_inc;
	struct v4l2_rect src_rect = src->crop;
	struct v4l2_rect dst_rect = dst->crop;
	int dst_x_offset;
	s32 dst_width = dst->crop.width;
	u32 src_fmt, dst_fmt;
	const u32 *ivmx;

	dev_dbg(ctx->bdisp_dev->dev, "%s\n", __func__);

	memset(node, 0, sizeof(*node));

	/* Adjust src and dst areas wrt src_x_offset */
	src_rect.left += src_x_offset;
	src_rect.width -= src_x_offset;
	src_rect.width = min_t(__s32, MAX_SRC_WIDTH, src_rect.width);

	dst_x_offset = (src_x_offset * dst_width) / ctx->src.crop.width;
	dst_rect.left += dst_x_offset;
	dst_rect.width = (src_rect.width * dst_width) / ctx->src.crop.width;

	/* General */
	src_fmt = src->fmt->pixelformat;
	dst_fmt = dst->fmt->pixelformat;

	node->nip = 0;
	node->cic = BLT_CIC_ALL_GRP;
	node->ack = BLT_ACK_BYPASS_S2S3;

	switch (cfg->src_nbp) {
	case 1:
		/* Src2 = RGB / Src1 = Src3 = off */
		node->ins = BLT_INS_S1_OFF | BLT_INS_S2_MEM | BLT_INS_S3_OFF;
		break;
	case 2:
		/* Src3 = Y
		 * Src2 = CbCr or ColorFill if writing the Y plane
		 * Src1 = off */
		node->ins = BLT_INS_S1_OFF | BLT_INS_S3_MEM;
		if (t_plan == BDISP_Y)
			node->ins |= BLT_INS_S2_CF;
		else
			node->ins |= BLT_INS_S2_MEM;
		break;
	case 3:
	default:
		/* Src3 = Y
		 * Src2 = Cb or ColorFill if writing the Y plane
		 * Src1 = Cr or ColorFill if writing the Y plane */
		node->ins = BLT_INS_S3_MEM;
		if (t_plan == BDISP_Y)
			node->ins |= BLT_INS_S2_CF | BLT_INS_S1_CF;
		else
			node->ins |= BLT_INS_S2_MEM | BLT_INS_S1_MEM;
		break;
	}

	/* Color convert */
	node->ins |= cfg->cconv ? BLT_INS_IVMX : 0;
	/* Scale needed if scaling OR 4:2:0 up/downsampling */
	node->ins |= (cfg->scale || cfg->src_420 || cfg->dst_420) ?
			BLT_INS_SCALE : 0;

	/* Target */
	node->tba = (t_plan == BDISP_CBCR) ? dst->paddr[1] : dst->paddr[0];

	node->tty = dst->bytesperline;
	node->tty |= bdisp_hw_color_format(dst_fmt);
	node->tty |= BLT_TTY_DITHER;
	node->tty |= (t_plan == BDISP_CBCR) ? BLT_TTY_CHROMA : 0;
	node->tty |= cfg->hflip ? BLT_TTY_HSO : 0;
	node->tty |= cfg->vflip ? BLT_TTY_VSO : 0;

	if (cfg->dst_420 && (t_plan == BDISP_CBCR)) {
		/* 420 chroma downsampling */
		dst_rect.height /= 2;
		dst_rect.width /= 2;
		dst_rect.left /= 2;
		dst_rect.top /= 2;
		dst_x_offset /= 2;
		dst_width /= 2;
	}

	node->txy = cfg->vflip ? (dst_rect.height - 1) : dst_rect.top;
	node->txy <<= 16;
	node->txy |= cfg->hflip ? (dst_width - dst_x_offset - 1) :
			dst_rect.left;

	node->tsz = dst_rect.height << 16 | dst_rect.width;

	if (cfg->src_interlaced) {
		/* handle only the top field which is half height of a frame */
		src_rect.top /= 2;
		src_rect.height /= 2;
	}

	if (cfg->src_nbp == 1) {
		/* Src 2 : RGB */
		node->s2ba = src->paddr[0];

		node->s2ty = src->bytesperline;
		if (cfg->src_interlaced)
			node->s2ty *= 2;

		node->s2ty |= bdisp_hw_color_format(src_fmt);

		node->s2xy = src_rect.top << 16 | src_rect.left;
		node->s2sz = src_rect.height << 16 | src_rect.width;
	} else {
		/* Src 2 : Cb or CbCr */
		if (cfg->src_420) {
			/* 420 chroma upsampling */
			src_rect.top /= 2;
			src_rect.left /= 2;
			src_rect.width /= 2;
			src_rect.height /= 2;
		}

		node->s2ba = src->paddr[1];

		node->s2ty = src->bytesperline;
		if (cfg->src_nbp == 3)
			node->s2ty /= 2;
		if (cfg->src_interlaced)
			node->s2ty *= 2;

		node->s2ty |= bdisp_hw_color_format(src_fmt);

		node->s2xy = src_rect.top << 16 | src_rect.left;
		node->s2sz = src_rect.height << 16 | src_rect.width;

		if (cfg->src_nbp == 3) {
			/* Src 1 : Cr */
			node->s1ba = src->paddr[2];

			node->s1ty = node->s2ty;
			node->s1xy = node->s2xy;
		}

		/* Src 3 : Y */
		node->s3ba = src->paddr[0];

		node->s3ty = src->bytesperline;
		if (cfg->src_interlaced)
			node->s3ty *= 2;
		node->s3ty |= bdisp_hw_color_format(src_fmt);

		if ((t_plan != BDISP_CBCR) && cfg->src_420) {
			/* No chroma upsampling for output RGB / Y plane */
			node->s3xy = node->s2xy * 2;
			node->s3sz = node->s2sz * 2;
		} else {
			/* No need to read Y (Src3) when writing Chroma */
			node->s3ty |= BLT_S3TY_BLANK_ACC;
			node->s3xy = node->s2xy;
			node->s3sz = node->s2sz;
		}
	}

	/* Resize (scale OR 4:2:0: chroma up/downsampling) */
	if (node->ins & BLT_INS_SCALE) {
		/* no need to compute Y when writing CbCr from RGB input */
		bool skip_y = (t_plan == BDISP_CBCR) && !cfg->src_yuv;

		/* FCTL */
		if (cfg->scale) {
			node->fctl = BLT_FCTL_HV_SCALE;
			if (!skip_y)
				node->fctl |= BLT_FCTL_Y_HV_SCALE;
		} else {
			node->fctl = BLT_FCTL_HV_SAMPLE;
			if (!skip_y)
				node->fctl |= BLT_FCTL_Y_HV_SAMPLE;
		}

		/* RSF - Chroma may need to be up/downsampled */
		h_inc = cfg->h_inc;
		v_inc = cfg->v_inc;
		if (!cfg->src_420 && cfg->dst_420 && (t_plan == BDISP_CBCR)) {
			/* RGB to 4:2:0 for Chroma: downsample */
			h_inc *= 2;
			v_inc *= 2;
		} else if (cfg->src_420 && !cfg->dst_420) {
			/* 4:2:0: to RGB: upsample*/
			h_inc /= 2;
			v_inc /= 2;
		}
		node->rsf = v_inc << 16 | h_inc;

		/* RZI */
		node->rzi = BLT_RZI_DEFAULT;

		/* Filter table physical addr */
		node->hfp = bdisp_hw_get_hf_addr(h_inc);
		node->vfp = bdisp_hw_get_vf_addr(v_inc);

		/* Y version */
		if (!skip_y) {
			yh_inc = cfg->h_inc;
			yv_inc = cfg->v_inc;

			node->y_rsf = yv_inc << 16 | yh_inc;
			node->y_rzi = BLT_RZI_DEFAULT;
			node->y_hfp = bdisp_hw_get_hf_addr(yh_inc);
			node->y_vfp = bdisp_hw_get_vf_addr(yv_inc);
		}
	}

	/* Versatile matrix for RGB / YUV conversion */
	if (cfg->cconv) {
		ivmx = cfg->src_yuv ? bdisp_yuv_to_rgb : bdisp_rgb_to_yuv;

		node->ivmx0 = ivmx[0];
		node->ivmx1 = ivmx[1];
		node->ivmx2 = ivmx[2];
		node->ivmx3 = ivmx[3];
	}
}

/**
 * bdisp_hw_build_all_nodes
 * @ctx:        device context
 *
 * Build all the nodes for the blitter operation
 *
 * RETURNS:
 * 0 on success
 */
static int bdisp_hw_build_all_nodes(struct bdisp_ctx *ctx)
{
	struct bdisp_op_cfg cfg;
	unsigned int i, nid = 0;
	int src_x_offset = 0;

	for (i = 0; i < MAX_NB_NODE; i++)
		if (!ctx->node[i]) {
			dev_err(ctx->bdisp_dev->dev, "node %d is null\n", i);
			return -EINVAL;
		}

	/* Get configuration (scale, flip, ...) */
	if (bdisp_hw_get_op_cfg(ctx, &cfg))
		return -EINVAL;

	/* Split source in vertical strides (HW constraint) */
	for (i = 0; i < MAX_VERTICAL_STRIDES; i++) {
		/* Build RGB/Y node and link it to the previous node */
		bdisp_hw_build_node(ctx, &cfg, ctx->node[nid],
				    cfg.dst_nbp == 1 ? BDISP_RGB : BDISP_Y,
				    src_x_offset);
		if (nid)
			ctx->node[nid - 1]->nip = ctx->node_paddr[nid];
		nid++;

		/* Build additional Cb(Cr) node, link it to the previous one */
		if (cfg.dst_nbp > 1) {
			bdisp_hw_build_node(ctx, &cfg, ctx->node[nid],
					    BDISP_CBCR, src_x_offset);
			ctx->node[nid - 1]->nip = ctx->node_paddr[nid];
			nid++;
		}

		/* Next stride until full width covered */
		src_x_offset += MAX_SRC_WIDTH;
		if (src_x_offset >= ctx->src.crop.width)
			break;
	}

	/* Mark last node as the last */
	ctx->node[nid - 1]->nip = 0;

	return 0;
}

/**
 * bdisp_hw_save_request
 * @ctx:        device context
 *
 * Save a copy of the request and of the built nodes
 *
 * RETURNS:
 * None
 */
static void bdisp_hw_save_request(struct bdisp_ctx *ctx)
{
	struct bdisp_node **copy_node = ctx->bdisp_dev->dbg.copy_node;
	struct bdisp_request *request = &ctx->bdisp_dev->dbg.copy_request;
	struct bdisp_node **node = ctx->node;
	int i;

	/* Request copy */
	request->src = ctx->src;
	request->dst = ctx->dst;
	request->hflip = ctx->hflip;
	request->vflip = ctx->vflip;
	request->nb_req++;

	/* Nodes copy */
	for (i = 0; i < MAX_NB_NODE; i++) {
		/* Allocate memory if not done yet */
		if (!copy_node[i]) {
			copy_node[i] = devm_kzalloc(ctx->bdisp_dev->dev,
						    sizeof(*copy_node[i]),
						    GFP_KERNEL);
			if (!copy_node[i])
				return;
		}
		*copy_node[i] = *node[i];
	}
}

/**
 * bdisp_hw_update
 * @ctx:        device context
 *
 * Send the request to the HW
 *
 * RETURNS:
 * 0 on success
 */
int bdisp_hw_update(struct bdisp_ctx *ctx)
{
	int ret;
	struct bdisp_dev *bdisp = ctx->bdisp_dev;
	struct device *dev = bdisp->dev;
	unsigned int node_id;

	dev_dbg(dev, "%s\n", __func__);

	/* build nodes */
	ret = bdisp_hw_build_all_nodes(ctx);
	if (ret) {
		dev_err(dev, "cannot build nodes (%d)\n", ret);
		return ret;
	}

	/* Save a copy of the request */
	bdisp_hw_save_request(ctx);

	/* Configure interrupt to 'Last Node Reached for AQ1' */
	writel(BLT_AQ1_CTL_CFG, bdisp->regs + BLT_AQ1_CTL);
	writel(BLT_ITS_AQ1_LNA, bdisp->regs + BLT_ITM0);

	/* Write first node addr */
	writel(ctx->node_paddr[0], bdisp->regs + BLT_AQ1_IP);

	/* Find and write last node addr : this starts the HW processing */
	for (node_id = 0; node_id < MAX_NB_NODE - 1; node_id++) {
		if (!ctx->node[node_id]->nip)
			break;
	}
	writel(ctx->node_paddr[node_id], bdisp->regs + BLT_AQ1_LNA);

	return 0;
}
