151852Sbp// SPDX-License-Identifier: GPL-2.0
274060Sbp// Copyright (C) 2018 Intel Corporation
351852Sbp
451852Sbp#include <linux/device.h>
551852Sbp#include <linux/iopoll.h>
651852Sbp#include <linux/slab.h>
751852Sbp
851852Sbp#include "ipu3.h"
951852Sbp#include "ipu3-css.h"
1051852Sbp#include "ipu3-css-fw.h"
1151852Sbp#include "ipu3-css-params.h"
1251852Sbp#include "ipu3-dmamap.h"
1351852Sbp#include "ipu3-tables.h"
1451852Sbp
1551852Sbp/* IRQ configuration */
1651852Sbp#define IMGU_IRQCTRL_IRQ_MASK	(IMGU_IRQCTRL_IRQ_SP1 | \
1751852Sbp				 IMGU_IRQCTRL_IRQ_SP2 | \
1851852Sbp				 IMGU_IRQCTRL_IRQ_SW_PIN(0) | \
1951852Sbp				 IMGU_IRQCTRL_IRQ_SW_PIN(1))
2051852Sbp
2151852Sbp#define IPU3_CSS_FORMAT_BPP_DEN	50	/* Denominator */
2251852Sbp
2351852Sbp/* Some sane limits for resolutions */
2451852Sbp#define IPU3_CSS_MIN_RES	32
2551852Sbp#define IPU3_CSS_MAX_H		3136
2651852Sbp#define IPU3_CSS_MAX_W		4224
2751852Sbp
2851852Sbp/* minimal envelope size(GDC in - out) should be 4 */
2951852Sbp#define MIN_ENVELOPE            4
3051852Sbp
3151852Sbp/*
3251852Sbp * pre-allocated buffer size for CSS ABI, auxiliary frames
3351852Sbp * after BDS and before GDC. Those values should be tuned
3454477Sbp * to big enough to avoid buffer re-allocation when
3554477Sbp * streaming to lower streaming latency.
3651852Sbp */
3751852Sbp#define CSS_ABI_SIZE    136
3851852Sbp#define CSS_BDS_SIZE    (4480 * 3200 * 3)
3951852Sbp#define CSS_GDC_SIZE    (4224 * 3200 * 12 / 8)
4051852Sbp
4151852Sbp#define IPU3_CSS_QUEUE_TO_FLAGS(q)	(1 << (q))
4251852Sbp#define IPU3_CSS_FORMAT_FL_IN		\
4351852Sbp			IPU3_CSS_QUEUE_TO_FLAGS(IPU3_CSS_QUEUE_IN)
4451852Sbp#define IPU3_CSS_FORMAT_FL_OUT		\
4551852Sbp			IPU3_CSS_QUEUE_TO_FLAGS(IPU3_CSS_QUEUE_OUT)
4651852Sbp#define IPU3_CSS_FORMAT_FL_VF		\
4751852Sbp			IPU3_CSS_QUEUE_TO_FLAGS(IPU3_CSS_QUEUE_VF)
4851852Sbp
4951852Sbp/* Formats supported by IPU3 Camera Sub System */
5051852Sbpstatic const struct imgu_css_format imgu_css_formats[] = {
5151852Sbp	{
5251852Sbp		.pixelformat = V4L2_PIX_FMT_NV12,
5351852Sbp		.colorspace = V4L2_COLORSPACE_SRGB,
5451852Sbp		.frame_format = IMGU_ABI_FRAME_FORMAT_NV12,
5551852Sbp		.osys_format = IMGU_ABI_OSYS_FORMAT_NV12,
5651852Sbp		.osys_tiling = IMGU_ABI_OSYS_TILING_NONE,
5751852Sbp		.chroma_decim = 4,
5851852Sbp		.width_align = IPU3_UAPI_ISP_VEC_ELEMS,
5951852Sbp		.flags = IPU3_CSS_FORMAT_FL_OUT | IPU3_CSS_FORMAT_FL_VF,
6051852Sbp	}, {
6151852Sbp		/* Each 32 bytes contains 25 10-bit pixels */
6251852Sbp		.pixelformat = V4L2_PIX_FMT_IPU3_SBGGR10,
6351852Sbp		.colorspace = V4L2_COLORSPACE_RAW,
6451852Sbp		.frame_format = IMGU_ABI_FRAME_FORMAT_RAW_PACKED,
6551852Sbp		.bayer_order = IMGU_ABI_BAYER_ORDER_BGGR,
6651852Sbp		.bit_depth = 10,
6751852Sbp		.width_align = 2 * IPU3_UAPI_ISP_VEC_ELEMS,
6851852Sbp		.flags = IPU3_CSS_FORMAT_FL_IN,
6951852Sbp	}, {
7051852Sbp		.pixelformat = V4L2_PIX_FMT_IPU3_SGBRG10,
7151852Sbp		.colorspace = V4L2_COLORSPACE_RAW,
7251852Sbp		.frame_format = IMGU_ABI_FRAME_FORMAT_RAW_PACKED,
7351852Sbp		.bayer_order = IMGU_ABI_BAYER_ORDER_GBRG,
7451852Sbp		.bit_depth = 10,
7551852Sbp		.width_align = 2 * IPU3_UAPI_ISP_VEC_ELEMS,
7651852Sbp		.flags = IPU3_CSS_FORMAT_FL_IN,
7751852Sbp	}, {
7851852Sbp		.pixelformat = V4L2_PIX_FMT_IPU3_SGRBG10,
7951852Sbp		.colorspace = V4L2_COLORSPACE_RAW,
8051852Sbp		.frame_format = IMGU_ABI_FRAME_FORMAT_RAW_PACKED,
8151852Sbp		.bayer_order = IMGU_ABI_BAYER_ORDER_GRBG,
8251852Sbp		.bit_depth = 10,
8351852Sbp		.width_align = 2 * IPU3_UAPI_ISP_VEC_ELEMS,
8455205Speter		.flags = IPU3_CSS_FORMAT_FL_IN,
8574060Sbp	}, {
8674060Sbp		.pixelformat = V4L2_PIX_FMT_IPU3_SRGGB10,
8774060Sbp		.colorspace = V4L2_COLORSPACE_RAW,
8874060Sbp		.frame_format = IMGU_ABI_FRAME_FORMAT_RAW_PACKED,
8974060Sbp		.bayer_order = IMGU_ABI_BAYER_ORDER_RGGB,
9074060Sbp		.bit_depth = 10,
9151852Sbp		.width_align = 2 * IPU3_UAPI_ISP_VEC_ELEMS,
9251852Sbp		.flags = IPU3_CSS_FORMAT_FL_IN,
9351852Sbp	},
9451852Sbp};
9574060Sbp
9674060Sbpstatic const struct {
9774060Sbp	enum imgu_abi_queue_id qid;
9874060Sbp	size_t ptr_ofs;
9974060Sbp} imgu_css_queues[IPU3_CSS_QUEUES] = {
10074060Sbp	[IPU3_CSS_QUEUE_IN] = {
10174060Sbp		IMGU_ABI_QUEUE_C_ID,
10283366Sjulian		offsetof(struct imgu_abi_buffer, payload.frame.frame_data)
10374060Sbp	},
10451852Sbp	[IPU3_CSS_QUEUE_OUT] = {
10574060Sbp		IMGU_ABI_QUEUE_D_ID,
10651852Sbp		offsetof(struct imgu_abi_buffer, payload.frame.frame_data)
10751852Sbp	},
10883366Sjulian	[IPU3_CSS_QUEUE_VF] = {
10974060Sbp		IMGU_ABI_QUEUE_E_ID,
11074060Sbp		offsetof(struct imgu_abi_buffer, payload.frame.frame_data)
11183366Sjulian	},
11274060Sbp	[IPU3_CSS_QUEUE_STAT_3A] = {
11383366Sjulian		IMGU_ABI_QUEUE_F_ID,
11474060Sbp		offsetof(struct imgu_abi_buffer, payload.s3a.data_ptr)
11574060Sbp	},
11683366Sjulian};
11774060Sbp
11874060Sbp/* Initialize queue based on given format, adjust format as needed */
11974060Sbpstatic int imgu_css_queue_init(struct imgu_css_queue *queue,
12051852Sbp			       struct v4l2_pix_format_mplane *fmt, u32 flags)
12174060Sbp{
12251852Sbp	struct v4l2_pix_format_mplane *const f = &queue->fmt.mpix;
12374060Sbp	unsigned int i;
12474060Sbp	u32 sizeimage;
12551852Sbp
12674060Sbp	INIT_LIST_HEAD(&queue->bufs);
12751852Sbp
12851852Sbp	queue->css_fmt = NULL;	/* Disable */
12951852Sbp	if (!fmt)
13055205Speter		return 0;
13151852Sbp
13251852Sbp	for (i = 0; i < ARRAY_SIZE(imgu_css_formats); i++) {
13351852Sbp		if (!(imgu_css_formats[i].flags & flags))
13451852Sbp			continue;
13551852Sbp		queue->css_fmt = &imgu_css_formats[i];
13655991Sbde		if (imgu_css_formats[i].pixelformat == fmt->pixelformat)
13755991Sbde			break;
13854477Sbp	}
13951852Sbp	if (!queue->css_fmt)
14054477Sbp		return -EINVAL;	/* Could not find any suitable format */
14154477Sbp
14254477Sbp	queue->fmt.mpix = *fmt;
14354477Sbp
14454477Sbp	f->width = ALIGN(clamp_t(u32, f->width,
14554477Sbp				 IPU3_CSS_MIN_RES, IPU3_CSS_MAX_W), 2);
14654477Sbp	f->height = ALIGN(clamp_t(u32, f->height,
14754477Sbp				  IPU3_CSS_MIN_RES, IPU3_CSS_MAX_H), 2);
14854477Sbp	queue->width_pad = ALIGN(f->width, queue->css_fmt->width_align);
14954477Sbp	f->plane_fmt[0].bytesperline =
15054477Sbp		imgu_bytesperline(f->width, queue->css_fmt->frame_format);
15151852Sbp	sizeimage = f->height * f->plane_fmt[0].bytesperline;
15251852Sbp	if (queue->css_fmt->chroma_decim)
15351852Sbp		sizeimage += 2 * sizeimage / queue->css_fmt->chroma_decim;
15454477Sbp
15554477Sbp	f->plane_fmt[0].sizeimage = sizeimage;
15654477Sbp	f->field = V4L2_FIELD_NONE;
15754477Sbp	f->num_planes = 1;
15851852Sbp	f->colorspace = queue->css_fmt->colorspace;
15951852Sbp	f->flags = 0;
16051852Sbp	f->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
16151852Sbp	f->quantization = V4L2_QUANTIZATION_DEFAULT;
16251852Sbp	f->xfer_func = V4L2_XFER_FUNC_DEFAULT;
16351852Sbp	memset(f->reserved, 0, sizeof(f->reserved));
16451852Sbp
16554477Sbp	return 0;
16654477Sbp}
16755205Speter
16851852Sbpstatic bool imgu_css_queue_enabled(struct imgu_css_queue *q)
16954477Sbp{
170	return q->css_fmt;
171}
172
173/******************* css hw *******************/
174
175/* In the style of writesl() defined in include/asm-generic/io.h */
176static inline void writes(const void *mem, ssize_t count, void __iomem *addr)
177{
178	if (count >= 4) {
179		const u32 *buf = mem;
180
181		count /= 4;
182		do {
183			writel(*buf++, addr);
184			addr += 4;
185		} while (--count);
186	}
187}
188
189/* Wait until register `reg', masked with `mask', becomes `cmp' */
190static int imgu_hw_wait(void __iomem *base, int reg, u32 mask, u32 cmp)
191{
192	u32 val;
193
194	return readl_poll_timeout(base + reg, val, (val & mask) == cmp,
195				  1000, 100 * 1000);
196}
197
198/* Initialize the IPU3 CSS hardware and associated h/w blocks */
199
200int imgu_css_set_powerup(struct device *dev, void __iomem *base,
201			 unsigned int freq)
202{
203	u32 pm_ctrl, state, val;
204
205	dev_dbg(dev, "%s with freq %u\n", __func__, freq);
206	/* Clear the CSS busy signal */
207	readl(base + IMGU_REG_GP_BUSY);
208	writel(0, base + IMGU_REG_GP_BUSY);
209
210	/* Wait for idle signal */
211	if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS,
212			 IMGU_STATE_IDLE_STS)) {
213		dev_err(dev, "failed to set CSS idle\n");
214		goto fail;
215	}
216
217	/* Reset the css */
218	writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_RESET,
219	       base + IMGU_REG_PM_CTRL);
220
221	usleep_range(200, 300);
222
223	/** Prepare CSS */
224
225	pm_ctrl = readl(base + IMGU_REG_PM_CTRL);
226	state = readl(base + IMGU_REG_STATE);
227
228	dev_dbg(dev, "CSS pm_ctrl 0x%x state 0x%x (power %s)\n",
229		pm_ctrl, state, state & IMGU_STATE_POWER_DOWN ? "down" : "up");
230
231	/* Power up CSS using wrapper */
232	if (state & IMGU_STATE_POWER_DOWN) {
233		writel(IMGU_PM_CTRL_RACE_TO_HALT | IMGU_PM_CTRL_START,
234		       base + IMGU_REG_PM_CTRL);
235		if (imgu_hw_wait(base, IMGU_REG_PM_CTRL,
236				 IMGU_PM_CTRL_START, 0)) {
237			dev_err(dev, "failed to power up CSS\n");
238			goto fail;
239		}
240		usleep_range(2000, 3000);
241	} else {
242		writel(IMGU_PM_CTRL_RACE_TO_HALT, base + IMGU_REG_PM_CTRL);
243	}
244
245	/* Set the busy bit */
246	writel(readl(base + IMGU_REG_GP_BUSY) | 1, base + IMGU_REG_GP_BUSY);
247
248	/* Set CSS clock frequency */
249	pm_ctrl = readl(base + IMGU_REG_PM_CTRL);
250	val = pm_ctrl & ~(IMGU_PM_CTRL_CSS_PWRDN | IMGU_PM_CTRL_RST_AT_EOF);
251	writel(val, base + IMGU_REG_PM_CTRL);
252	writel(0, base + IMGU_REG_GP_BUSY);
253	if (imgu_hw_wait(base, IMGU_REG_STATE,
254			 IMGU_STATE_PWRDNM_FSM_MASK, 0)) {
255		dev_err(dev, "failed to pwrdn CSS\n");
256		goto fail;
257	}
258	val = (freq / IMGU_SYSTEM_REQ_FREQ_DIVIDER) & IMGU_SYSTEM_REQ_FREQ_MASK;
259	writel(val, base + IMGU_REG_SYSTEM_REQ);
260	writel(1, base + IMGU_REG_GP_BUSY);
261	writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_HALT,
262	       base + IMGU_REG_PM_CTRL);
263	if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS,
264			 IMGU_STATE_HALT_STS)) {
265		dev_err(dev, "failed to halt CSS\n");
266		goto fail;
267	}
268
269	writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_START,
270	       base + IMGU_REG_PM_CTRL);
271	if (imgu_hw_wait(base, IMGU_REG_PM_CTRL, IMGU_PM_CTRL_START, 0)) {
272		dev_err(dev, "failed to start CSS\n");
273		goto fail;
274	}
275	writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_UNHALT,
276	       base + IMGU_REG_PM_CTRL);
277
278	val = readl(base + IMGU_REG_PM_CTRL);	/* get pm_ctrl */
279	val &= ~(IMGU_PM_CTRL_CSS_PWRDN | IMGU_PM_CTRL_RST_AT_EOF);
280	val |= pm_ctrl & (IMGU_PM_CTRL_CSS_PWRDN | IMGU_PM_CTRL_RST_AT_EOF);
281	writel(val, base + IMGU_REG_PM_CTRL);
282
283	return 0;
284
285fail:
286	imgu_css_set_powerdown(dev, base);
287	return -EIO;
288}
289
290void imgu_css_set_powerdown(struct device *dev, void __iomem *base)
291{
292	dev_dbg(dev, "%s\n", __func__);
293	/* wait for cio idle signal */
294	if (imgu_hw_wait(base, IMGU_REG_CIO_GATE_BURST_STATE,
295			 IMGU_CIO_GATE_BURST_MASK, 0))
296		dev_warn(dev, "wait cio gate idle timeout");
297
298	/* wait for css idle signal */
299	if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS,
300			 IMGU_STATE_IDLE_STS))
301		dev_warn(dev, "wait css idle timeout\n");
302
303	/* do halt-halted handshake with css */
304	writel(1, base + IMGU_REG_GP_HALT);
305	if (imgu_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS,
306			 IMGU_STATE_HALT_STS))
307		dev_warn(dev, "failed to halt css");
308
309	/* de-assert the busy bit */
310	writel(0, base + IMGU_REG_GP_BUSY);
311}
312
313static void imgu_css_hw_enable_irq(struct imgu_css *css)
314{
315	void __iomem *const base = css->base;
316	u32 val, i;
317
318	/* Set up interrupts */
319
320	/*
321	 * Enable IRQ on the SP which signals that SP goes to idle
322	 * (aka ready state) and set trigger to pulse
323	 */
324	val = readl(base + IMGU_REG_SP_CTRL(0)) | IMGU_CTRL_IRQ_READY;
325	writel(val, base + IMGU_REG_SP_CTRL(0));
326	writel(val | IMGU_CTRL_IRQ_CLEAR, base + IMGU_REG_SP_CTRL(0));
327
328	/* Enable IRQs from the IMGU wrapper */
329	writel(IMGU_REG_INT_CSS_IRQ, base + IMGU_REG_INT_ENABLE);
330	/* Clear */
331	writel(IMGU_REG_INT_CSS_IRQ, base + IMGU_REG_INT_STATUS);
332
333	/* Enable IRQs from main IRQ controller */
334	writel(~0, base + IMGU_REG_IRQCTRL_EDGE_NOT_PULSE(IMGU_IRQCTRL_MAIN));
335	writel(0, base + IMGU_REG_IRQCTRL_MASK(IMGU_IRQCTRL_MAIN));
336	writel(IMGU_IRQCTRL_IRQ_MASK,
337	       base + IMGU_REG_IRQCTRL_EDGE(IMGU_IRQCTRL_MAIN));
338	writel(IMGU_IRQCTRL_IRQ_MASK,
339	       base + IMGU_REG_IRQCTRL_ENABLE(IMGU_IRQCTRL_MAIN));
340	writel(IMGU_IRQCTRL_IRQ_MASK,
341	       base + IMGU_REG_IRQCTRL_CLEAR(IMGU_IRQCTRL_MAIN));
342	writel(IMGU_IRQCTRL_IRQ_MASK,
343	       base + IMGU_REG_IRQCTRL_MASK(IMGU_IRQCTRL_MAIN));
344	/* Wait for write complete */
345	readl(base + IMGU_REG_IRQCTRL_ENABLE(IMGU_IRQCTRL_MAIN));
346
347	/* Enable IRQs from SP0 and SP1 controllers */
348	for (i = IMGU_IRQCTRL_SP0; i <= IMGU_IRQCTRL_SP1; i++) {
349		writel(~0, base + IMGU_REG_IRQCTRL_EDGE_NOT_PULSE(i));
350		writel(0, base + IMGU_REG_IRQCTRL_MASK(i));
351		writel(IMGU_IRQCTRL_IRQ_MASK, base + IMGU_REG_IRQCTRL_EDGE(i));
352		writel(IMGU_IRQCTRL_IRQ_MASK,
353		       base + IMGU_REG_IRQCTRL_ENABLE(i));
354		writel(IMGU_IRQCTRL_IRQ_MASK, base + IMGU_REG_IRQCTRL_CLEAR(i));
355		writel(IMGU_IRQCTRL_IRQ_MASK, base + IMGU_REG_IRQCTRL_MASK(i));
356		/* Wait for write complete */
357		readl(base + IMGU_REG_IRQCTRL_ENABLE(i));
358	}
359}
360
361static int imgu_css_hw_init(struct imgu_css *css)
362{
363	/* For checking that streaming monitor statuses are valid */
364	static const struct {
365		u32 reg;
366		u32 mask;
367		const char *name;
368	} stream_monitors[] = {
369		{
370			IMGU_REG_GP_SP1_STRMON_STAT,
371			IMGU_GP_STRMON_STAT_ISP_PORT_SP12ISP,
372			"ISP0 to SP0"
373		}, {
374			IMGU_REG_GP_ISP_STRMON_STAT,
375			IMGU_GP_STRMON_STAT_SP1_PORT_ISP2SP1,
376			"SP0 to ISP0"
377		}, {
378			IMGU_REG_GP_MOD_STRMON_STAT,
379			IMGU_GP_STRMON_STAT_MOD_PORT_ISP2DMA,
380			"ISP0 to DMA0"
381		}, {
382			IMGU_REG_GP_ISP_STRMON_STAT,
383			IMGU_GP_STRMON_STAT_ISP_PORT_DMA2ISP,
384			"DMA0 to ISP0"
385		}, {
386			IMGU_REG_GP_MOD_STRMON_STAT,
387			IMGU_GP_STRMON_STAT_MOD_PORT_CELLS2GDC,
388			"ISP0 to GDC0"
389		}, {
390			IMGU_REG_GP_MOD_STRMON_STAT,
391			IMGU_GP_STRMON_STAT_MOD_PORT_GDC2CELLS,
392			"GDC0 to ISP0"
393		}, {
394			IMGU_REG_GP_MOD_STRMON_STAT,
395			IMGU_GP_STRMON_STAT_MOD_PORT_SP12DMA,
396			"SP0 to DMA0"
397		}, {
398			IMGU_REG_GP_SP1_STRMON_STAT,
399			IMGU_GP_STRMON_STAT_SP1_PORT_DMA2SP1,
400			"DMA0 to SP0"
401		}, {
402			IMGU_REG_GP_MOD_STRMON_STAT,
403			IMGU_GP_STRMON_STAT_MOD_PORT_CELLS2GDC,
404			"SP0 to GDC0"
405		}, {
406			IMGU_REG_GP_MOD_STRMON_STAT,
407			IMGU_GP_STRMON_STAT_MOD_PORT_GDC2CELLS,
408			"GDC0 to SP0"
409		},
410	};
411
412	struct device *dev = css->dev;
413	void __iomem *const base = css->base;
414	u32 val, i;
415
416	/* Set instruction cache address and inv bit for ISP, SP, and SP1 */
417	for (i = 0; i < IMGU_NUM_SP; i++) {
418		struct imgu_fw_info *bi =
419					&css->fwp->binary_header[css->fw_sp[i]];
420
421		writel(css->binary[css->fw_sp[i]].daddr,
422		       base + IMGU_REG_SP_ICACHE_ADDR(bi->type));
423		writel(readl(base + IMGU_REG_SP_CTRL(bi->type)) |
424		       IMGU_CTRL_ICACHE_INV,
425		       base + IMGU_REG_SP_CTRL(bi->type));
426	}
427	writel(css->binary[css->fw_bl].daddr, base + IMGU_REG_ISP_ICACHE_ADDR);
428	writel(readl(base + IMGU_REG_ISP_CTRL) | IMGU_CTRL_ICACHE_INV,
429	       base + IMGU_REG_ISP_CTRL);
430
431	/* Check that IMGU hardware is ready */
432
433	if (!(readl(base + IMGU_REG_SP_CTRL(0)) & IMGU_CTRL_IDLE)) {
434		dev_err(dev, "SP is not idle\n");
435		return -EIO;
436	}
437	if (!(readl(base + IMGU_REG_ISP_CTRL) & IMGU_CTRL_IDLE)) {
438		dev_err(dev, "ISP is not idle\n");
439		return -EIO;
440	}
441
442	for (i = 0; i < ARRAY_SIZE(stream_monitors); i++) {
443		val = readl(base + stream_monitors[i].reg);
444		if (val & stream_monitors[i].mask) {
445			dev_err(dev, "error: Stream monitor %s is valid\n",
446				stream_monitors[i].name);
447			return -EIO;
448		}
449	}
450
451	/* Initialize GDC with default values */
452
453	for (i = 0; i < ARRAY_SIZE(imgu_css_gdc_lut[0]); i++) {
454		u32 val0 = imgu_css_gdc_lut[0][i] & IMGU_GDC_LUT_MASK;
455		u32 val1 = imgu_css_gdc_lut[1][i] & IMGU_GDC_LUT_MASK;
456		u32 val2 = imgu_css_gdc_lut[2][i] & IMGU_GDC_LUT_MASK;
457		u32 val3 = imgu_css_gdc_lut[3][i] & IMGU_GDC_LUT_MASK;
458
459		writel(val0 | (val1 << 16),
460		       base + IMGU_REG_GDC_LUT_BASE + i * 8);
461		writel(val2 | (val3 << 16),
462		       base + IMGU_REG_GDC_LUT_BASE + i * 8 + 4);
463	}
464
465	return 0;
466}
467
468/* Boot the given IPU3 CSS SP */
469static int imgu_css_hw_start_sp(struct imgu_css *css, int sp)
470{
471	void __iomem *const base = css->base;
472	struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]];
473	struct imgu_abi_sp_init_dmem_cfg dmem_cfg = {
474		.ddr_data_addr = css->binary[css->fw_sp[sp]].daddr
475			+ bi->blob.data_source,
476		.dmem_data_addr = bi->blob.data_target,
477		.dmem_bss_addr = bi->blob.bss_target,
478		.data_size = bi->blob.data_size,
479		.bss_size = bi->blob.bss_size,
480		.sp_id = sp,
481	};
482
483	writes(&dmem_cfg, sizeof(dmem_cfg), base +
484	       IMGU_REG_SP_DMEM_BASE(sp) + bi->info.sp.init_dmem_data);
485
486	writel(bi->info.sp.sp_entry, base + IMGU_REG_SP_START_ADDR(sp));
487
488	writel(readl(base + IMGU_REG_SP_CTRL(sp))
489		| IMGU_CTRL_START | IMGU_CTRL_RUN, base + IMGU_REG_SP_CTRL(sp));
490
491	if (imgu_hw_wait(css->base, IMGU_REG_SP_DMEM_BASE(sp)
492			 + bi->info.sp.sw_state,
493			 ~0, IMGU_ABI_SP_SWSTATE_INITIALIZED))
494		return -EIO;
495
496	return 0;
497}
498
499/* Start the IPU3 CSS ImgU (Imaging Unit) and all the SPs */
500static int imgu_css_hw_start(struct imgu_css *css)
501{
502	static const u32 event_mask =
503		((1 << IMGU_ABI_EVTTYPE_OUT_FRAME_DONE) |
504		(1 << IMGU_ABI_EVTTYPE_2ND_OUT_FRAME_DONE) |
505		(1 << IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE) |
506		(1 << IMGU_ABI_EVTTYPE_2ND_VF_OUT_FRAME_DONE) |
507		(1 << IMGU_ABI_EVTTYPE_3A_STATS_DONE) |
508		(1 << IMGU_ABI_EVTTYPE_DIS_STATS_DONE) |
509		(1 << IMGU_ABI_EVTTYPE_PIPELINE_DONE) |
510		(1 << IMGU_ABI_EVTTYPE_FRAME_TAGGED) |
511		(1 << IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE) |
512		(1 << IMGU_ABI_EVTTYPE_METADATA_DONE) |
513		(1 << IMGU_ABI_EVTTYPE_ACC_STAGE_COMPLETE))
514		<< IMGU_ABI_SP_COMM_EVENT_IRQ_MASK_OR_SHIFT;
515
516	void __iomem *const base = css->base;
517	struct imgu_fw_info *bi, *bl = &css->fwp->binary_header[css->fw_bl];
518	unsigned int i;
519
520	writel(IMGU_TLB_INVALIDATE, base + IMGU_REG_TLB_INVALIDATE);
521
522	/* Start bootloader */
523
524	writel(IMGU_ABI_BL_SWSTATE_BUSY,
525	       base + IMGU_REG_ISP_DMEM_BASE + bl->info.bl.sw_state);
526	writel(IMGU_NUM_SP,
527	       base + IMGU_REG_ISP_DMEM_BASE + bl->info.bl.num_dma_cmds);
528
529	for (i = 0; i < IMGU_NUM_SP; i++) {
530		int j = IMGU_NUM_SP - i - 1;	/* load sp1 first, then sp0 */
531		struct imgu_fw_info *sp =
532					&css->fwp->binary_header[css->fw_sp[j]];
533		struct imgu_abi_bl_dma_cmd_entry dma_cmd = {
534			.src_addr = css->binary[css->fw_sp[j]].daddr
535				+ sp->blob.text_source,
536			.size = sp->blob.text_size,
537			.dst_type = IMGU_ABI_BL_DMACMD_TYPE_SP_PMEM,
538			.dst_addr = IMGU_SP_PMEM_BASE(j),
539		};
540
541		writes(&dma_cmd, sizeof(dma_cmd),
542		       base + IMGU_REG_ISP_DMEM_BASE + i * sizeof(dma_cmd) +
543		       bl->info.bl.dma_cmd_list);
544	}
545
546	writel(bl->info.bl.bl_entry, base + IMGU_REG_ISP_START_ADDR);
547
548	writel(readl(base + IMGU_REG_ISP_CTRL)
549		| IMGU_CTRL_START | IMGU_CTRL_RUN, base + IMGU_REG_ISP_CTRL);
550	if (imgu_hw_wait(css->base, IMGU_REG_ISP_DMEM_BASE
551			 + bl->info.bl.sw_state, ~0,
552			 IMGU_ABI_BL_SWSTATE_OK)) {
553		dev_err(css->dev, "failed to start bootloader\n");
554		return -EIO;
555	}
556
557	/* Start ISP */
558
559	memset(css->xmem_sp_group_ptrs.vaddr, 0,
560	       sizeof(struct imgu_abi_sp_group));
561
562	bi = &css->fwp->binary_header[css->fw_sp[0]];
563
564	writel(css->xmem_sp_group_ptrs.daddr,
565	       base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.per_frame_data);
566
567	writel(IMGU_ABI_SP_SWSTATE_TERMINATED,
568	       base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.sw_state);
569	writel(1, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.invalidate_tlb);
570
571	if (imgu_css_hw_start_sp(css, 0))
572		return -EIO;
573
574	writel(0, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.isp_started);
575	writel(0, base + IMGU_REG_SP_DMEM_BASE(0) +
576		bi->info.sp.host_sp_queues_initialized);
577	writel(0, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.sleep_mode);
578	writel(0, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.invalidate_tlb);
579	writel(IMGU_ABI_SP_COMM_COMMAND_READY, base + IMGU_REG_SP_DMEM_BASE(0)
580		+ bi->info.sp.host_sp_com + IMGU_ABI_SP_COMM_COMMAND);
581
582	/* Enable all events for all queues */
583
584	for (i = 0; i < IPU3_CSS_PIPE_ID_NUM; i++)
585		writel(event_mask, base + IMGU_REG_SP_DMEM_BASE(0)
586			+ bi->info.sp.host_sp_com
587			+ IMGU_ABI_SP_COMM_EVENT_IRQ_MASK(i));
588	writel(1, base + IMGU_REG_SP_DMEM_BASE(0) +
589		bi->info.sp.host_sp_queues_initialized);
590
591	/* Start SP1 */
592
593	bi = &css->fwp->binary_header[css->fw_sp[1]];
594
595	writel(IMGU_ABI_SP_SWSTATE_TERMINATED,
596	       base + IMGU_REG_SP_DMEM_BASE(1) + bi->info.sp.sw_state);
597
598	if (imgu_css_hw_start_sp(css, 1))
599		return -EIO;
600
601	writel(IMGU_ABI_SP_COMM_COMMAND_READY, base + IMGU_REG_SP_DMEM_BASE(1)
602		+ bi->info.sp.host_sp_com + IMGU_ABI_SP_COMM_COMMAND);
603
604	return 0;
605}
606
607static void imgu_css_hw_stop(struct imgu_css *css)
608{
609	void __iomem *const base = css->base;
610	struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[0]];
611
612	/* Stop fw */
613	writel(IMGU_ABI_SP_COMM_COMMAND_TERMINATE,
614	       base + IMGU_REG_SP_DMEM_BASE(0) +
615	       bi->info.sp.host_sp_com + IMGU_ABI_SP_COMM_COMMAND);
616	if (imgu_hw_wait(css->base, IMGU_REG_SP_CTRL(0),
617			 IMGU_CTRL_IDLE, IMGU_CTRL_IDLE))
618		dev_err(css->dev, "wait sp0 idle timeout.\n");
619	if (readl(base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.sw_state) !=
620		  IMGU_ABI_SP_SWSTATE_TERMINATED)
621		dev_err(css->dev, "sp0 is not terminated.\n");
622	if (imgu_hw_wait(css->base, IMGU_REG_ISP_CTRL,
623			 IMGU_CTRL_IDLE, IMGU_CTRL_IDLE))
624		dev_err(css->dev, "wait isp idle timeout\n");
625}
626
627static void imgu_css_hw_cleanup(struct imgu_css *css)
628{
629	void __iomem *const base = css->base;
630
631	/** Reset CSS **/
632
633	/* Clear the CSS busy signal */
634	readl(base + IMGU_REG_GP_BUSY);
635	writel(0, base + IMGU_REG_GP_BUSY);
636
637	/* Wait for idle signal */
638	if (imgu_hw_wait(css->base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS,
639			 IMGU_STATE_IDLE_STS))
640		dev_err(css->dev, "failed to shut down hw cleanly\n");
641
642	/* Reset the css */
643	writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_RESET,
644	       base + IMGU_REG_PM_CTRL);
645
646	usleep_range(200, 300);
647}
648
649static void imgu_css_pipeline_cleanup(struct imgu_css *css, unsigned int pipe)
650{
651	struct imgu_device *imgu = dev_get_drvdata(css->dev);
652	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
653	unsigned int i;
654
655	imgu_css_pool_cleanup(imgu, &css_pipe->pool.parameter_set_info);
656	imgu_css_pool_cleanup(imgu, &css_pipe->pool.acc);
657	imgu_css_pool_cleanup(imgu, &css_pipe->pool.gdc);
658	imgu_css_pool_cleanup(imgu, &css_pipe->pool.obgrid);
659
660	for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++)
661		imgu_css_pool_cleanup(imgu, &css_pipe->pool.binary_params_p[i]);
662}
663
664/*
665 * This function initializes various stages of the
666 * IPU3 CSS ISP pipeline
667 */
668static int imgu_css_pipeline_init(struct imgu_css *css, unsigned int pipe)
669{
670	static const int BYPC = 2;	/* Bytes per component */
671	static const struct imgu_abi_buffer_sp buffer_sp_init = {
672		.buf_src = {.queue_id = IMGU_ABI_QUEUE_EVENT_ID},
673		.buf_type = IMGU_ABI_BUFFER_TYPE_INVALID,
674	};
675
676	struct imgu_abi_isp_iterator_config *cfg_iter;
677	struct imgu_abi_isp_ref_config *cfg_ref;
678	struct imgu_abi_isp_dvs_config *cfg_dvs;
679	struct imgu_abi_isp_tnr3_config *cfg_tnr;
680	struct imgu_abi_isp_ref_dmem_state *cfg_ref_state;
681	struct imgu_abi_isp_tnr3_dmem_state *cfg_tnr_state;
682
683	const int stage = 0;
684	unsigned int i, j;
685
686	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
687	struct imgu_css_queue *css_queue_in =
688			&css_pipe->queue[IPU3_CSS_QUEUE_IN];
689	struct imgu_css_queue *css_queue_out =
690			&css_pipe->queue[IPU3_CSS_QUEUE_OUT];
691	struct imgu_css_queue *css_queue_vf =
692			&css_pipe->queue[IPU3_CSS_QUEUE_VF];
693	const struct imgu_fw_info *bi =
694			&css->fwp->binary_header[css_pipe->bindex];
695	const unsigned int stripes = bi->info.isp.sp.iterator.num_stripes;
696
697	struct imgu_fw_config_memory_offsets *cofs = (void *)css->fwp +
698		bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_CONFIG];
699	struct imgu_fw_state_memory_offsets *sofs = (void *)css->fwp +
700		bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_STATE];
701
702	struct imgu_abi_isp_stage *isp_stage;
703	struct imgu_abi_sp_stage *sp_stage;
704	struct imgu_abi_sp_group *sp_group;
705	struct imgu_abi_frames_sp *frames_sp;
706	struct imgu_abi_frame_sp *frame_sp;
707	struct imgu_abi_frame_sp_info *frame_sp_info;
708
709	const unsigned int bds_width_pad =
710				ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width,
711				      2 * IPU3_UAPI_ISP_VEC_ELEMS);
712
713	const enum imgu_abi_memories m0 = IMGU_ABI_MEM_ISP_DMEM0;
714	enum imgu_abi_param_class cfg = IMGU_ABI_PARAM_CLASS_CONFIG;
715	void *vaddr = css_pipe->binary_params_cs[cfg - 1][m0].vaddr;
716
717	struct imgu_device *imgu = dev_get_drvdata(css->dev);
718
719	dev_dbg(css->dev, "%s for pipe %d", __func__, pipe);
720
721	/* Configure iterator */
722
723	cfg_iter = imgu_css_fw_pipeline_params(css, pipe, cfg, m0,
724					       &cofs->dmem.iterator,
725					       sizeof(*cfg_iter), vaddr);
726	if (!cfg_iter)
727		goto bad_firmware;
728
729	frame_sp_info = &cfg_iter->input_info;
730	frame_sp_info->res.width	= css_queue_in->fmt.mpix.width;
731	frame_sp_info->res.height	= css_queue_in->fmt.mpix.height;
732	frame_sp_info->padded_width	= css_queue_in->width_pad;
733	frame_sp_info->format		= css_queue_in->css_fmt->frame_format;
734	frame_sp_info->raw_bit_depth	= css_queue_in->css_fmt->bit_depth;
735	frame_sp_info->raw_bayer_order	= css_queue_in->css_fmt->bayer_order;
736	frame_sp_info->raw_type		= IMGU_ABI_RAW_TYPE_BAYER;
737
738	frame_sp_info = &cfg_iter->internal_info;
739	frame_sp_info->res.width = css_pipe->rect[IPU3_CSS_RECT_BDS].width;
740	frame_sp_info->res.height = css_pipe->rect[IPU3_CSS_RECT_BDS].height;
741	frame_sp_info->padded_width	= bds_width_pad;
742	frame_sp_info->format		= css_queue_out->css_fmt->frame_format;
743	frame_sp_info->raw_bit_depth	= css_queue_out->css_fmt->bit_depth;
744	frame_sp_info->raw_bayer_order	= css_queue_out->css_fmt->bayer_order;
745	frame_sp_info->raw_type		= IMGU_ABI_RAW_TYPE_BAYER;
746
747	frame_sp_info = &cfg_iter->output_info;
748	frame_sp_info->res.width	= css_queue_out->fmt.mpix.width;
749	frame_sp_info->res.height	= css_queue_out->fmt.mpix.height;
750	frame_sp_info->padded_width	= css_queue_out->width_pad;
751	frame_sp_info->format		= css_queue_out->css_fmt->frame_format;
752	frame_sp_info->raw_bit_depth	= css_queue_out->css_fmt->bit_depth;
753	frame_sp_info->raw_bayer_order	= css_queue_out->css_fmt->bayer_order;
754	frame_sp_info->raw_type		= IMGU_ABI_RAW_TYPE_BAYER;
755
756	frame_sp_info = &cfg_iter->vf_info;
757	frame_sp_info->res.width	= css_queue_vf->fmt.mpix.width;
758	frame_sp_info->res.height	= css_queue_vf->fmt.mpix.height;
759	frame_sp_info->padded_width	= css_queue_vf->width_pad;
760	frame_sp_info->format		= css_queue_vf->css_fmt->frame_format;
761	frame_sp_info->raw_bit_depth	= css_queue_vf->css_fmt->bit_depth;
762	frame_sp_info->raw_bayer_order	= css_queue_vf->css_fmt->bayer_order;
763	frame_sp_info->raw_type		= IMGU_ABI_RAW_TYPE_BAYER;
764
765	cfg_iter->dvs_envelope.width =
766				css_pipe->rect[IPU3_CSS_RECT_ENVELOPE].width;
767	cfg_iter->dvs_envelope.height =
768				css_pipe->rect[IPU3_CSS_RECT_ENVELOPE].height;
769
770	/* Configure reference (delay) frames */
771
772	cfg_ref = imgu_css_fw_pipeline_params(css, pipe, cfg, m0,
773					      &cofs->dmem.ref,
774					      sizeof(*cfg_ref), vaddr);
775	if (!cfg_ref)
776		goto bad_firmware;
777
778	cfg_ref->port_b.crop = 0;
779	cfg_ref->port_b.elems = IMGU_ABI_ISP_DDR_WORD_BYTES / BYPC;
780	cfg_ref->port_b.width =
781		css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].width;
782	cfg_ref->port_b.stride =
783		css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperline;
784	cfg_ref->width_a_over_b =
785				IPU3_UAPI_ISP_VEC_ELEMS / cfg_ref->port_b.elems;
786	cfg_ref->dvs_frame_delay = IPU3_CSS_AUX_FRAMES - 1;
787	for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++) {
788		cfg_ref->ref_frame_addr_y[i] =
789			css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].mem[i].daddr;
790		cfg_ref->ref_frame_addr_c[i] =
791			css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].mem[i].daddr +
792			css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperline *
793			css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].height;
794	}
795	for (; i < IMGU_ABI_FRAMES_REF; i++) {
796		cfg_ref->ref_frame_addr_y[i] = 0;
797		cfg_ref->ref_frame_addr_c[i] = 0;
798	}
799
800	/* Configure DVS (digital video stabilization) */
801
802	cfg_dvs = imgu_css_fw_pipeline_params(css, pipe, cfg, m0,
803					      &cofs->dmem.dvs, sizeof(*cfg_dvs),
804					      vaddr);
805	if (!cfg_dvs)
806		goto bad_firmware;
807
808	cfg_dvs->num_horizontal_blocks =
809			ALIGN(DIV_ROUND_UP(css_pipe->rect[IPU3_CSS_RECT_GDC].width,
810					   IMGU_DVS_BLOCK_W), 2);
811	cfg_dvs->num_vertical_blocks =
812			DIV_ROUND_UP(css_pipe->rect[IPU3_CSS_RECT_GDC].height,
813				     IMGU_DVS_BLOCK_H);
814
815	/* Configure TNR (temporal noise reduction) */
816
817	if (css_pipe->pipe_id == IPU3_CSS_PIPE_ID_VIDEO) {
818		cfg_tnr = imgu_css_fw_pipeline_params(css, pipe, cfg, m0,
819						      &cofs->dmem.tnr3,
820						      sizeof(*cfg_tnr),
821						      vaddr);
822		if (!cfg_tnr)
823			goto bad_firmware;
824
825		cfg_tnr->port_b.crop = 0;
826		cfg_tnr->port_b.elems = IMGU_ABI_ISP_DDR_WORD_BYTES;
827		cfg_tnr->port_b.width =
828			css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].width;
829		cfg_tnr->port_b.stride =
830			css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].bytesperline;
831		cfg_tnr->width_a_over_b =
832			IPU3_UAPI_ISP_VEC_ELEMS / cfg_tnr->port_b.elems;
833		cfg_tnr->frame_height =
834			css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].height;
835		cfg_tnr->delay_frame = IPU3_CSS_AUX_FRAMES - 1;
836		for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
837			cfg_tnr->frame_addr[i] =
838				css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR]
839					.mem[i].daddr;
840		for (; i < IMGU_ABI_FRAMES_TNR; i++)
841			cfg_tnr->frame_addr[i] = 0;
842	}
843
844	/* Configure ref dmem state parameters */
845
846	cfg = IMGU_ABI_PARAM_CLASS_STATE;
847	vaddr = css_pipe->binary_params_cs[cfg - 1][m0].vaddr;
848
849	cfg_ref_state = imgu_css_fw_pipeline_params(css, pipe, cfg, m0,
850						    &sofs->dmem.ref,
851						    sizeof(*cfg_ref_state),
852						    vaddr);
853	if (!cfg_ref_state)
854		goto bad_firmware;
855
856	cfg_ref_state->ref_in_buf_idx = 0;
857	cfg_ref_state->ref_out_buf_idx = 1;
858
859	/* Configure tnr dmem state parameters */
860	if (css_pipe->pipe_id == IPU3_CSS_PIPE_ID_VIDEO) {
861		cfg_tnr_state =
862			imgu_css_fw_pipeline_params(css, pipe, cfg, m0,
863						    &sofs->dmem.tnr3,
864						    sizeof(*cfg_tnr_state),
865						    vaddr);
866		if (!cfg_tnr_state)
867			goto bad_firmware;
868
869		cfg_tnr_state->in_bufidx = 0;
870		cfg_tnr_state->out_bufidx = 1;
871		cfg_tnr_state->bypass_filter = 0;
872		cfg_tnr_state->total_frame_counter = 0;
873		for (i = 0; i < IMGU_ABI_BUF_SETS_TNR; i++)
874			cfg_tnr_state->buffer_frame_counter[i] = 0;
875	}
876
877	/* Configure ISP stage */
878
879	isp_stage = css_pipe->xmem_isp_stage_ptrs[pipe][stage].vaddr;
880	memset(isp_stage, 0, sizeof(*isp_stage));
881	isp_stage->blob_info = bi->blob;
882	isp_stage->binary_info = bi->info.isp.sp;
883	strscpy(isp_stage->binary_name,
884		(char *)css->fwp + bi->blob.prog_name_offset,
885		sizeof(isp_stage->binary_name));
886	isp_stage->mem_initializers = bi->info.isp.sp.mem_initializers;
887	for (i = IMGU_ABI_PARAM_CLASS_CONFIG; i < IMGU_ABI_PARAM_CLASS_NUM; i++)
888		for (j = 0; j < IMGU_ABI_NUM_MEMORIES; j++)
889			isp_stage->mem_initializers.params[i][j].address =
890					css_pipe->binary_params_cs[i - 1][j].daddr;
891
892	/* Configure SP stage */
893
894	sp_stage = css_pipe->xmem_sp_stage_ptrs[pipe][stage].vaddr;
895	memset(sp_stage, 0, sizeof(*sp_stage));
896
897	frames_sp = &sp_stage->frames;
898	frames_sp->in.buf_attr = buffer_sp_init;
899	for (i = 0; i < IMGU_ABI_BINARY_MAX_OUTPUT_PORTS; i++)
900		frames_sp->out[i].buf_attr = buffer_sp_init;
901	frames_sp->out_vf.buf_attr = buffer_sp_init;
902	frames_sp->s3a_buf = buffer_sp_init;
903	frames_sp->dvs_buf = buffer_sp_init;
904
905	sp_stage->stage_type = IMGU_ABI_STAGE_TYPE_ISP;
906	sp_stage->num = stage;
907	sp_stage->isp_online = 0;
908	sp_stage->isp_copy_vf = 0;
909	sp_stage->isp_copy_output = 0;
910
911	sp_stage->enable.vf_output = css_pipe->vf_output_en;
912
913	frames_sp->effective_in_res.width =
914				css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].width;
915	frames_sp->effective_in_res.height =
916				css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].height;
917
918	frame_sp = &frames_sp->in;
919	frame_sp->info.res.width	= css_queue_in->fmt.mpix.width;
920	frame_sp->info.res.height	= css_queue_in->fmt.mpix.height;
921	frame_sp->info.padded_width	= css_queue_in->width_pad;
922	frame_sp->info.format		= css_queue_in->css_fmt->frame_format;
923	frame_sp->info.raw_bit_depth	= css_queue_in->css_fmt->bit_depth;
924	frame_sp->info.raw_bayer_order	= css_queue_in->css_fmt->bayer_order;
925	frame_sp->info.raw_type		= IMGU_ABI_RAW_TYPE_BAYER;
926	frame_sp->buf_attr.buf_src.queue_id = IMGU_ABI_QUEUE_C_ID;
927	frame_sp->buf_attr.buf_type	= IMGU_ABI_BUFFER_TYPE_INPUT_FRAME;
928
929	frame_sp = &frames_sp->out[0];
930	frame_sp->info.res.width	= css_queue_out->fmt.mpix.width;
931	frame_sp->info.res.height	= css_queue_out->fmt.mpix.height;
932	frame_sp->info.padded_width	= css_queue_out->width_pad;
933	frame_sp->info.format		= css_queue_out->css_fmt->frame_format;
934	frame_sp->info.raw_bit_depth	= css_queue_out->css_fmt->bit_depth;
935	frame_sp->info.raw_bayer_order	= css_queue_out->css_fmt->bayer_order;
936	frame_sp->info.raw_type		= IMGU_ABI_RAW_TYPE_BAYER;
937	frame_sp->planes.nv.uv.offset	= css_queue_out->width_pad *
938					  css_queue_out->fmt.mpix.height;
939	frame_sp->buf_attr.buf_src.queue_id = IMGU_ABI_QUEUE_D_ID;
940	frame_sp->buf_attr.buf_type	= IMGU_ABI_BUFFER_TYPE_OUTPUT_FRAME;
941
942	frame_sp = &frames_sp->out[1];
943	frame_sp->buf_attr.buf_src.queue_id = IMGU_ABI_QUEUE_EVENT_ID;
944
945	frame_sp_info = &frames_sp->internal_frame_info;
946	frame_sp_info->res.width = css_pipe->rect[IPU3_CSS_RECT_BDS].width;
947	frame_sp_info->res.height = css_pipe->rect[IPU3_CSS_RECT_BDS].height;
948	frame_sp_info->padded_width	= bds_width_pad;
949	frame_sp_info->format		= css_queue_out->css_fmt->frame_format;
950	frame_sp_info->raw_bit_depth	= css_queue_out->css_fmt->bit_depth;
951	frame_sp_info->raw_bayer_order	= css_queue_out->css_fmt->bayer_order;
952	frame_sp_info->raw_type		= IMGU_ABI_RAW_TYPE_BAYER;
953
954	frame_sp = &frames_sp->out_vf;
955	frame_sp->info.res.width	= css_queue_vf->fmt.mpix.width;
956	frame_sp->info.res.height	= css_queue_vf->fmt.mpix.height;
957	frame_sp->info.padded_width	= css_queue_vf->width_pad;
958	frame_sp->info.format		= css_queue_vf->css_fmt->frame_format;
959	frame_sp->info.raw_bit_depth	= css_queue_vf->css_fmt->bit_depth;
960	frame_sp->info.raw_bayer_order	= css_queue_vf->css_fmt->bayer_order;
961	frame_sp->info.raw_type		= IMGU_ABI_RAW_TYPE_BAYER;
962	frame_sp->planes.yuv.u.offset	= css_queue_vf->width_pad *
963					  css_queue_vf->fmt.mpix.height;
964	frame_sp->planes.yuv.v.offset	= css_queue_vf->width_pad *
965					  css_queue_vf->fmt.mpix.height * 5 / 4;
966	frame_sp->buf_attr.buf_src.queue_id = IMGU_ABI_QUEUE_E_ID;
967	frame_sp->buf_attr.buf_type	= IMGU_ABI_BUFFER_TYPE_VF_OUTPUT_FRAME;
968
969	frames_sp->s3a_buf.buf_src.queue_id = IMGU_ABI_QUEUE_F_ID;
970	frames_sp->s3a_buf.buf_type	= IMGU_ABI_BUFFER_TYPE_3A_STATISTICS;
971
972	frames_sp->dvs_buf.buf_src.queue_id = IMGU_ABI_QUEUE_G_ID;
973	frames_sp->dvs_buf.buf_type	= IMGU_ABI_BUFFER_TYPE_DIS_STATISTICS;
974
975	sp_stage->dvs_envelope.width =
976				css_pipe->rect[IPU3_CSS_RECT_ENVELOPE].width;
977	sp_stage->dvs_envelope.height =
978				css_pipe->rect[IPU3_CSS_RECT_ENVELOPE].height;
979
980	sp_stage->isp_pipe_version =
981				bi->info.isp.sp.pipeline.isp_pipe_version;
982	sp_stage->isp_deci_log_factor =
983			clamp(max(fls(css_pipe->rect[IPU3_CSS_RECT_BDS].width /
984				      IMGU_MAX_BQ_GRID_WIDTH),
985				  fls(css_pipe->rect[IPU3_CSS_RECT_BDS].height /
986				      IMGU_MAX_BQ_GRID_HEIGHT)) - 1, 3, 5);
987	sp_stage->isp_vf_downscale_bits = 0;
988	sp_stage->if_config_index = 255;
989	sp_stage->sp_enable_xnr = 0;
990	sp_stage->num_stripes = stripes;
991	sp_stage->enable.s3a = 1;
992	sp_stage->enable.dvs_stats = 0;
993
994	sp_stage->xmem_bin_addr = css->binary[css_pipe->bindex].daddr;
995	sp_stage->xmem_map_addr = css_pipe->sp_ddr_ptrs.daddr;
996	sp_stage->isp_stage_addr =
997		css_pipe->xmem_isp_stage_ptrs[pipe][stage].daddr;
998
999	/* Configure SP group */
1000
1001	sp_group = css->xmem_sp_group_ptrs.vaddr;
1002	memset(&sp_group->pipe[pipe], 0, sizeof(struct imgu_abi_sp_pipeline));
1003
1004	sp_group->pipe[pipe].num_stages = 1;
1005	sp_group->pipe[pipe].pipe_id = css_pipe->pipe_id;
1006	sp_group->pipe[pipe].thread_id = pipe;
1007	sp_group->pipe[pipe].pipe_num = pipe;
1008	sp_group->pipe[pipe].num_execs = -1;
1009	sp_group->pipe[pipe].pipe_qos_config = -1;
1010	sp_group->pipe[pipe].required_bds_factor = 0;
1011	sp_group->pipe[pipe].dvs_frame_delay = IPU3_CSS_AUX_FRAMES - 1;
1012	sp_group->pipe[pipe].inout_port_config =
1013					IMGU_ABI_PORT_CONFIG_TYPE_INPUT_HOST |
1014					IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_HOST;
1015	sp_group->pipe[pipe].scaler_pp_lut = 0;
1016	sp_group->pipe[pipe].shading.internal_frame_origin_x_bqs_on_sctbl = 0;
1017	sp_group->pipe[pipe].shading.internal_frame_origin_y_bqs_on_sctbl = 0;
1018	sp_group->pipe[pipe].sp_stage_addr[stage] =
1019			css_pipe->xmem_sp_stage_ptrs[pipe][stage].daddr;
1020	sp_group->pipe[pipe].pipe_config =
1021			bi->info.isp.sp.enable.params ? (1 << pipe) : 0;
1022	sp_group->pipe[pipe].pipe_config |= IMGU_ABI_PIPE_CONFIG_ACQUIRE_ISP;
1023
1024	/* Initialize parameter pools */
1025
1026	if (imgu_css_pool_init(imgu, &css_pipe->pool.parameter_set_info,
1027			       sizeof(struct imgu_abi_parameter_set_info)) ||
1028	    imgu_css_pool_init(imgu, &css_pipe->pool.acc,
1029			       sizeof(struct imgu_abi_acc_param)) ||
1030	    imgu_css_pool_init(imgu, &css_pipe->pool.gdc,
1031			       sizeof(struct imgu_abi_gdc_warp_param) *
1032			       3 * cfg_dvs->num_horizontal_blocks / 2 *
1033			       cfg_dvs->num_vertical_blocks) ||
1034	    imgu_css_pool_init(imgu, &css_pipe->pool.obgrid,
1035			       imgu_css_fw_obgrid_size(
1036			       &css->fwp->binary_header[css_pipe->bindex])))
1037		goto out_of_memory;
1038
1039	for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++)
1040		if (imgu_css_pool_init(imgu,
1041				       &css_pipe->pool.binary_params_p[i],
1042				       bi->info.isp.sp.mem_initializers.params
1043				       [IMGU_ABI_PARAM_CLASS_PARAM][i].size))
1044			goto out_of_memory;
1045
1046	return 0;
1047
1048bad_firmware:
1049	imgu_css_pipeline_cleanup(css, pipe);
1050	return -EPROTO;
1051
1052out_of_memory:
1053	imgu_css_pipeline_cleanup(css, pipe);
1054	return -ENOMEM;
1055}
1056
1057static u8 imgu_css_queue_pos(struct imgu_css *css, int queue, int thread)
1058{
1059	static const unsigned int sp;
1060	void __iomem *const base = css->base;
1061	struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]];
1062	struct imgu_abi_queues __iomem *q = base + IMGU_REG_SP_DMEM_BASE(sp) +
1063						bi->info.sp.host_sp_queue;
1064
1065	return queue >= 0 ? readb(&q->host2sp_bufq_info[thread][queue].end) :
1066			    readb(&q->host2sp_evtq_info.end);
1067}
1068
1069/* Sent data to sp using given buffer queue, or if queue < 0, event queue. */
1070static int imgu_css_queue_data(struct imgu_css *css,
1071			       int queue, int thread, u32 data)
1072{
1073	static const unsigned int sp;
1074	void __iomem *const base = css->base;
1075	struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]];
1076	struct imgu_abi_queues __iomem *q = base + IMGU_REG_SP_DMEM_BASE(sp) +
1077						bi->info.sp.host_sp_queue;
1078	u8 size, start, end, end2;
1079
1080	if (queue >= 0) {
1081		size = readb(&q->host2sp_bufq_info[thread][queue].size);
1082		start = readb(&q->host2sp_bufq_info[thread][queue].start);
1083		end = readb(&q->host2sp_bufq_info[thread][queue].end);
1084	} else {
1085		size = readb(&q->host2sp_evtq_info.size);
1086		start = readb(&q->host2sp_evtq_info.start);
1087		end = readb(&q->host2sp_evtq_info.end);
1088	}
1089
1090	if (size == 0)
1091		return -EIO;
1092
1093	end2 = (end + 1) % size;
1094	if (end2 == start)
1095		return -EBUSY;	/* Queue full */
1096
1097	if (queue >= 0) {
1098		writel(data, &q->host2sp_bufq[thread][queue][end]);
1099		writeb(end2, &q->host2sp_bufq_info[thread][queue].end);
1100	} else {
1101		writel(data, &q->host2sp_evtq[end]);
1102		writeb(end2, &q->host2sp_evtq_info.end);
1103	}
1104
1105	return 0;
1106}
1107
1108/* Receive data using given buffer queue, or if queue < 0, event queue. */
1109static int imgu_css_dequeue_data(struct imgu_css *css, int queue, u32 *data)
1110{
1111	static const unsigned int sp;
1112	void __iomem *const base = css->base;
1113	struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]];
1114	struct imgu_abi_queues __iomem *q = base + IMGU_REG_SP_DMEM_BASE(sp) +
1115						bi->info.sp.host_sp_queue;
1116	u8 size, start, end, start2;
1117
1118	if (queue >= 0) {
1119		size = readb(&q->sp2host_bufq_info[queue].size);
1120		start = readb(&q->sp2host_bufq_info[queue].start);
1121		end = readb(&q->sp2host_bufq_info[queue].end);
1122	} else {
1123		size = readb(&q->sp2host_evtq_info.size);
1124		start = readb(&q->sp2host_evtq_info.start);
1125		end = readb(&q->sp2host_evtq_info.end);
1126	}
1127
1128	if (size == 0)
1129		return -EIO;
1130
1131	if (end == start)
1132		return -EBUSY;	/* Queue empty */
1133
1134	start2 = (start + 1) % size;
1135
1136	if (queue >= 0) {
1137		*data = readl(&q->sp2host_bufq[queue][start]);
1138		writeb(start2, &q->sp2host_bufq_info[queue].start);
1139	} else {
1140		int r;
1141
1142		*data = readl(&q->sp2host_evtq[start]);
1143		writeb(start2, &q->sp2host_evtq_info.start);
1144
1145		/* Acknowledge events dequeued from event queue */
1146		r = imgu_css_queue_data(css, queue, 0,
1147					IMGU_ABI_EVENT_EVENT_DEQUEUED);
1148		if (r < 0)
1149			return r;
1150	}
1151
1152	return 0;
1153}
1154
1155/* Free binary-specific resources */
1156static void imgu_css_binary_cleanup(struct imgu_css *css, unsigned int pipe)
1157{
1158	struct imgu_device *imgu = dev_get_drvdata(css->dev);
1159	unsigned int i, j;
1160
1161	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1162
1163	for (j = 0; j < IMGU_ABI_PARAM_CLASS_NUM - 1; j++)
1164		for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++)
1165			imgu_dmamap_free(imgu,
1166					 &css_pipe->binary_params_cs[j][i]);
1167
1168	j = IPU3_CSS_AUX_FRAME_REF;
1169	for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
1170		imgu_dmamap_free(imgu,
1171				 &css_pipe->aux_frames[j].mem[i]);
1172
1173	j = IPU3_CSS_AUX_FRAME_TNR;
1174	for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
1175		imgu_dmamap_free(imgu,
1176				 &css_pipe->aux_frames[j].mem[i]);
1177}
1178
1179static int imgu_css_binary_preallocate(struct imgu_css *css, unsigned int pipe)
1180{
1181	struct imgu_device *imgu = dev_get_drvdata(css->dev);
1182	unsigned int i, j;
1183
1184	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1185
1186	for (j = IMGU_ABI_PARAM_CLASS_CONFIG;
1187	     j < IMGU_ABI_PARAM_CLASS_NUM; j++)
1188		for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++)
1189			if (!imgu_dmamap_alloc(imgu,
1190					       &css_pipe->binary_params_cs[j - 1][i],
1191					       CSS_ABI_SIZE))
1192				goto out_of_memory;
1193
1194	for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
1195		if (!imgu_dmamap_alloc(imgu,
1196				       &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].mem[i],
1197				       CSS_BDS_SIZE))
1198			goto out_of_memory;
1199
1200	for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
1201		if (!imgu_dmamap_alloc(imgu,
1202				       &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].mem[i],
1203				       CSS_GDC_SIZE))
1204			goto out_of_memory;
1205
1206	return 0;
1207
1208out_of_memory:
1209	imgu_css_binary_cleanup(css, pipe);
1210	return -ENOMEM;
1211}
1212
1213/* allocate binary-specific resources */
1214static int imgu_css_binary_setup(struct imgu_css *css, unsigned int pipe)
1215{
1216	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1217	struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex];
1218	struct imgu_device *imgu = dev_get_drvdata(css->dev);
1219	int i, j, size;
1220	static const int BYPC = 2;	/* Bytes per component */
1221	unsigned int w, h;
1222
1223	/* Allocate parameter memory blocks for this binary */
1224
1225	for (j = IMGU_ABI_PARAM_CLASS_CONFIG; j < IMGU_ABI_PARAM_CLASS_NUM; j++)
1226		for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++) {
1227			if (imgu_css_dma_buffer_resize(
1228			    imgu,
1229			    &css_pipe->binary_params_cs[j - 1][i],
1230			    bi->info.isp.sp.mem_initializers.params[j][i].size))
1231				goto out_of_memory;
1232		}
1233
1234	/* Allocate internal frame buffers */
1235
1236	/* Reference frames for DVS, FRAME_FORMAT_YUV420_16 */
1237	css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperpixel = BYPC;
1238	css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].width =
1239					css_pipe->rect[IPU3_CSS_RECT_BDS].width;
1240	css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].height =
1241				ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].height,
1242				      IMGU_DVS_BLOCK_H) + 2 * IMGU_GDC_BUF_Y;
1243	h = css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].height;
1244	w = ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width,
1245		  2 * IPU3_UAPI_ISP_VEC_ELEMS) + 2 * IMGU_GDC_BUF_X;
1246	css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperline =
1247		css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperpixel * w;
1248	size = w * h * BYPC + (w / 2) * (h / 2) * BYPC * 2;
1249	for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
1250		if (imgu_css_dma_buffer_resize(
1251			imgu,
1252			&css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].mem[i],
1253			size))
1254			goto out_of_memory;
1255
1256	/* TNR frames for temporal noise reduction, FRAME_FORMAT_YUV_LINE */
1257	css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].bytesperpixel = 1;
1258	css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].width =
1259			roundup(css_pipe->rect[IPU3_CSS_RECT_GDC].width,
1260				bi->info.isp.sp.block.block_width *
1261				IPU3_UAPI_ISP_VEC_ELEMS);
1262	css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].height =
1263			roundup(css_pipe->rect[IPU3_CSS_RECT_GDC].height,
1264				bi->info.isp.sp.block.output_block_height);
1265
1266	w = css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].width;
1267	css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].bytesperline = w;
1268	h = css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].height;
1269	size = w * ALIGN(h * 3 / 2 + 3, 2);	/* +3 for vf_pp prefetch */
1270	for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
1271		if (imgu_css_dma_buffer_resize(
1272			imgu,
1273			&css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].mem[i],
1274			size))
1275			goto out_of_memory;
1276
1277	return 0;
1278
1279out_of_memory:
1280	imgu_css_binary_cleanup(css, pipe);
1281	return -ENOMEM;
1282}
1283
1284int imgu_css_start_streaming(struct imgu_css *css)
1285{
1286	u32 data;
1287	int r, pipe;
1288
1289	if (css->streaming)
1290		return -EPROTO;
1291
1292	for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
1293		r = imgu_css_binary_setup(css, pipe);
1294		if (r < 0)
1295			return r;
1296	}
1297
1298	r = imgu_css_hw_init(css);
1299	if (r < 0)
1300		return r;
1301
1302	r = imgu_css_hw_start(css);
1303	if (r < 0)
1304		goto fail;
1305
1306	for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
1307		r = imgu_css_pipeline_init(css, pipe);
1308		if (r < 0)
1309			goto fail;
1310	}
1311
1312	css->streaming = true;
1313
1314	imgu_css_hw_enable_irq(css);
1315
1316	/* Initialize parameters to default */
1317	for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
1318		r = imgu_css_set_parameters(css, pipe, NULL);
1319		if (r < 0)
1320			goto fail;
1321	}
1322
1323	while (!(r = imgu_css_dequeue_data(css, IMGU_ABI_QUEUE_A_ID, &data)))
1324		;
1325	if (r != -EBUSY)
1326		goto fail;
1327
1328	while (!(r = imgu_css_dequeue_data(css, IMGU_ABI_QUEUE_B_ID, &data)))
1329		;
1330	if (r != -EBUSY)
1331		goto fail;
1332
1333	for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
1334		r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
1335					IMGU_ABI_EVENT_START_STREAM |
1336					pipe << 16);
1337		if (r < 0)
1338			goto fail;
1339	}
1340
1341	return 0;
1342
1343fail:
1344	css->streaming = false;
1345	imgu_css_hw_cleanup(css);
1346	for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
1347		imgu_css_pipeline_cleanup(css, pipe);
1348		imgu_css_binary_cleanup(css, pipe);
1349	}
1350
1351	return r;
1352}
1353
1354void imgu_css_stop_streaming(struct imgu_css *css)
1355{
1356	struct imgu_css_buffer *b, *b0;
1357	int q, r, pipe;
1358
1359	for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
1360		r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
1361					IMGU_ABI_EVENT_STOP_STREAM);
1362		if (r < 0)
1363			dev_warn(css->dev, "failed on stop stream event\n");
1364	}
1365
1366	if (!css->streaming)
1367		return;
1368
1369	imgu_css_hw_stop(css);
1370
1371	imgu_css_hw_cleanup(css);
1372
1373	for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
1374		struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1375
1376		imgu_css_pipeline_cleanup(css, pipe);
1377
1378		spin_lock(&css_pipe->qlock);
1379		for (q = 0; q < IPU3_CSS_QUEUES; q++)
1380			list_for_each_entry_safe(b, b0,
1381						 &css_pipe->queue[q].bufs,
1382						 list) {
1383				b->state = IPU3_CSS_BUFFER_FAILED;
1384				list_del(&b->list);
1385			}
1386		spin_unlock(&css_pipe->qlock);
1387	}
1388
1389	css->streaming = false;
1390}
1391
1392bool imgu_css_pipe_queue_empty(struct imgu_css *css, unsigned int pipe)
1393{
1394	int q;
1395	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1396
1397	spin_lock(&css_pipe->qlock);
1398	for (q = 0; q < IPU3_CSS_QUEUES; q++)
1399		if (!list_empty(&css_pipe->queue[q].bufs))
1400			break;
1401	spin_unlock(&css_pipe->qlock);
1402	return (q == IPU3_CSS_QUEUES);
1403}
1404
1405bool imgu_css_queue_empty(struct imgu_css *css)
1406{
1407	unsigned int pipe;
1408	bool ret = false;
1409
1410	for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++)
1411		ret &= imgu_css_pipe_queue_empty(css, pipe);
1412
1413	return ret;
1414}
1415
1416bool imgu_css_is_streaming(struct imgu_css *css)
1417{
1418	return css->streaming;
1419}
1420
1421static int imgu_css_map_init(struct imgu_css *css, unsigned int pipe)
1422{
1423	struct imgu_device *imgu = dev_get_drvdata(css->dev);
1424	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1425	unsigned int p, q, i;
1426
1427	/* Allocate and map common structures with imgu hardware */
1428	for (p = 0; p < IPU3_CSS_PIPE_ID_NUM; p++)
1429		for (i = 0; i < IMGU_ABI_MAX_STAGES; i++) {
1430			if (!imgu_dmamap_alloc(imgu,
1431					       &css_pipe->xmem_sp_stage_ptrs[p][i],
1432					       sizeof(struct imgu_abi_sp_stage)))
1433				return -ENOMEM;
1434			if (!imgu_dmamap_alloc(imgu,
1435					       &css_pipe->xmem_isp_stage_ptrs[p][i],
1436					       sizeof(struct imgu_abi_isp_stage)))
1437				return -ENOMEM;
1438		}
1439
1440	if (!imgu_dmamap_alloc(imgu, &css_pipe->sp_ddr_ptrs,
1441			       ALIGN(sizeof(struct imgu_abi_ddr_address_map),
1442				     IMGU_ABI_ISP_DDR_WORD_BYTES)))
1443		return -ENOMEM;
1444
1445	for (q = 0; q < IPU3_CSS_QUEUES; q++) {
1446		unsigned int abi_buf_num = ARRAY_SIZE(css_pipe->abi_buffers[q]);
1447
1448		for (i = 0; i < abi_buf_num; i++)
1449			if (!imgu_dmamap_alloc(imgu,
1450					       &css_pipe->abi_buffers[q][i],
1451					       sizeof(struct imgu_abi_buffer)))
1452				return -ENOMEM;
1453	}
1454
1455	if (imgu_css_binary_preallocate(css, pipe)) {
1456		imgu_css_binary_cleanup(css, pipe);
1457		return -ENOMEM;
1458	}
1459
1460	return 0;
1461}
1462
1463static void imgu_css_pipe_cleanup(struct imgu_css *css, unsigned int pipe)
1464{
1465	struct imgu_device *imgu = dev_get_drvdata(css->dev);
1466	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1467	unsigned int p, q, i, abi_buf_num;
1468
1469	imgu_css_binary_cleanup(css, pipe);
1470
1471	for (q = 0; q < IPU3_CSS_QUEUES; q++) {
1472		abi_buf_num = ARRAY_SIZE(css_pipe->abi_buffers[q]);
1473		for (i = 0; i < abi_buf_num; i++)
1474			imgu_dmamap_free(imgu, &css_pipe->abi_buffers[q][i]);
1475	}
1476
1477	for (p = 0; p < IPU3_CSS_PIPE_ID_NUM; p++)
1478		for (i = 0; i < IMGU_ABI_MAX_STAGES; i++) {
1479			imgu_dmamap_free(imgu,
1480					 &css_pipe->xmem_sp_stage_ptrs[p][i]);
1481			imgu_dmamap_free(imgu,
1482					 &css_pipe->xmem_isp_stage_ptrs[p][i]);
1483		}
1484
1485	imgu_dmamap_free(imgu, &css_pipe->sp_ddr_ptrs);
1486}
1487
1488void imgu_css_cleanup(struct imgu_css *css)
1489{
1490	struct imgu_device *imgu = dev_get_drvdata(css->dev);
1491	unsigned int pipe;
1492
1493	imgu_css_stop_streaming(css);
1494	for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++)
1495		imgu_css_pipe_cleanup(css, pipe);
1496	imgu_dmamap_free(imgu, &css->xmem_sp_group_ptrs);
1497	imgu_css_fw_cleanup(css);
1498}
1499
1500int imgu_css_init(struct device *dev, struct imgu_css *css,
1501		  void __iomem *base, int length)
1502{
1503	struct imgu_device *imgu = dev_get_drvdata(dev);
1504	int r, q, pipe;
1505
1506	/* Initialize main data structure */
1507	css->dev = dev;
1508	css->base = base;
1509	css->iomem_length = length;
1510
1511	for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++) {
1512		struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1513
1514		css_pipe->vf_output_en = false;
1515		spin_lock_init(&css_pipe->qlock);
1516		css_pipe->bindex = IPU3_CSS_DEFAULT_BINARY;
1517		css_pipe->pipe_id = IPU3_CSS_PIPE_ID_VIDEO;
1518		for (q = 0; q < IPU3_CSS_QUEUES; q++) {
1519			r = imgu_css_queue_init(&css_pipe->queue[q], NULL, 0);
1520			if (r)
1521				return r;
1522		}
1523		r = imgu_css_map_init(css, pipe);
1524		if (r) {
1525			imgu_css_cleanup(css);
1526			return r;
1527		}
1528	}
1529	if (!imgu_dmamap_alloc(imgu, &css->xmem_sp_group_ptrs,
1530			       sizeof(struct imgu_abi_sp_group)))
1531		return -ENOMEM;
1532
1533	r = imgu_css_fw_init(css);
1534	if (r)
1535		return r;
1536
1537	return 0;
1538}
1539
1540static u32 imgu_css_adjust(u32 res, u32 align)
1541{
1542	u32 val = max_t(u32, IPU3_CSS_MIN_RES, res);
1543
1544	return DIV_ROUND_CLOSEST(val, align) * align;
1545}
1546
1547/* Select a binary matching the required resolutions and formats */
1548static int imgu_css_find_binary(struct imgu_css *css,
1549				unsigned int pipe,
1550				struct imgu_css_queue queue[IPU3_CSS_QUEUES],
1551				struct v4l2_rect rects[IPU3_CSS_RECTS])
1552{
1553	const int binary_nr = css->fwp->file_header.binary_nr;
1554	unsigned int binary_mode =
1555		(css->pipes[pipe].pipe_id == IPU3_CSS_PIPE_ID_CAPTURE) ?
1556		IA_CSS_BINARY_MODE_PRIMARY : IA_CSS_BINARY_MODE_VIDEO;
1557	const struct v4l2_pix_format_mplane *in =
1558					&queue[IPU3_CSS_QUEUE_IN].fmt.mpix;
1559	const struct v4l2_pix_format_mplane *out =
1560					&queue[IPU3_CSS_QUEUE_OUT].fmt.mpix;
1561	const struct v4l2_pix_format_mplane *vf =
1562					&queue[IPU3_CSS_QUEUE_VF].fmt.mpix;
1563	u32 stripe_w = 0, stripe_h = 0;
1564	const char *name;
1565	int i, j;
1566
1567	if (!imgu_css_queue_enabled(&queue[IPU3_CSS_QUEUE_IN]))
1568		return -EINVAL;
1569
1570	/* Find out the strip size boundary */
1571	for (i = 0; i < binary_nr; i++) {
1572		struct imgu_fw_info *bi = &css->fwp->binary_header[i];
1573
1574		u32 max_width = bi->info.isp.sp.output.max_width;
1575		u32 max_height = bi->info.isp.sp.output.max_height;
1576
1577		if (bi->info.isp.sp.iterator.num_stripes <= 1) {
1578			stripe_w = stripe_w ?
1579				min(stripe_w, max_width) : max_width;
1580			stripe_h = stripe_h ?
1581				min(stripe_h, max_height) : max_height;
1582		}
1583	}
1584
1585	for (i = 0; i < binary_nr; i++) {
1586		struct imgu_fw_info *bi = &css->fwp->binary_header[i];
1587		enum imgu_abi_frame_format q_fmt;
1588
1589		name = (void *)css->fwp + bi->blob.prog_name_offset;
1590
1591		/* Check that binary supports memory-to-memory processing */
1592		if (bi->info.isp.sp.input.source !=
1593		    IMGU_ABI_BINARY_INPUT_SOURCE_MEMORY)
1594			continue;
1595
1596		/* Check that binary supports raw10 input */
1597		if (!bi->info.isp.sp.enable.input_feeder &&
1598		    !bi->info.isp.sp.enable.input_raw)
1599			continue;
1600
1601		/* Check binary mode */
1602		if (bi->info.isp.sp.pipeline.mode != binary_mode)
1603			continue;
1604
1605		/* Since input is RGGB bayer, need to process colors */
1606		if (bi->info.isp.sp.enable.luma_only)
1607			continue;
1608
1609		if (in->width < bi->info.isp.sp.input.min_width ||
1610		    in->width > bi->info.isp.sp.input.max_width ||
1611		    in->height < bi->info.isp.sp.input.min_height ||
1612		    in->height > bi->info.isp.sp.input.max_height)
1613			continue;
1614
1615		if (imgu_css_queue_enabled(&queue[IPU3_CSS_QUEUE_OUT])) {
1616			if (bi->info.isp.num_output_pins <= 0)
1617				continue;
1618
1619			q_fmt = queue[IPU3_CSS_QUEUE_OUT].css_fmt->frame_format;
1620			for (j = 0; j < bi->info.isp.num_output_formats; j++)
1621				if (bi->info.isp.output_formats[j] == q_fmt)
1622					break;
1623			if (j >= bi->info.isp.num_output_formats)
1624				continue;
1625
1626			if (out->width < bi->info.isp.sp.output.min_width ||
1627			    out->width > bi->info.isp.sp.output.max_width ||
1628			    out->height < bi->info.isp.sp.output.min_height ||
1629			    out->height > bi->info.isp.sp.output.max_height)
1630				continue;
1631
1632			if (out->width > bi->info.isp.sp.internal.max_width ||
1633			    out->height > bi->info.isp.sp.internal.max_height)
1634				continue;
1635		}
1636
1637		if (imgu_css_queue_enabled(&queue[IPU3_CSS_QUEUE_VF])) {
1638			if (bi->info.isp.num_output_pins <= 1)
1639				continue;
1640
1641			q_fmt = queue[IPU3_CSS_QUEUE_VF].css_fmt->frame_format;
1642			for (j = 0; j < bi->info.isp.num_output_formats; j++)
1643				if (bi->info.isp.output_formats[j] == q_fmt)
1644					break;
1645			if (j >= bi->info.isp.num_output_formats)
1646				continue;
1647
1648			if (vf->width < bi->info.isp.sp.output.min_width ||
1649			    vf->width > bi->info.isp.sp.output.max_width ||
1650			    vf->height < bi->info.isp.sp.output.min_height ||
1651			    vf->height > bi->info.isp.sp.output.max_height)
1652				continue;
1653		}
1654
1655		/* All checks passed, select the binary */
1656		dev_dbg(css->dev, "using binary %s id = %u\n", name,
1657			bi->info.isp.sp.id);
1658		return i;
1659	}
1660
1661	/* Can not find suitable binary for these parameters */
1662	return -EINVAL;
1663}
1664
1665/*
1666 * Check that there is a binary matching requirements. Parameters may be
1667 * NULL indicating disabled input/output. Return negative if given
1668 * parameters can not be supported or on error, zero or positive indicating
1669 * found binary number. May modify the given parameters if not exact match
1670 * is found.
1671 */
1672int imgu_css_fmt_try(struct imgu_css *css,
1673		     struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES],
1674		     struct v4l2_rect *rects[IPU3_CSS_RECTS],
1675		     unsigned int pipe)
1676{
1677	static const u32 EFF_ALIGN_W = 2;
1678	static const u32 BDS_ALIGN_W = 4;
1679	static const u32 OUT_ALIGN_W = 8;
1680	static const u32 OUT_ALIGN_H = 4;
1681	static const u32 VF_ALIGN_W  = 2;
1682	static const char *qnames[IPU3_CSS_QUEUES] = {
1683		[IPU3_CSS_QUEUE_IN] = "in",
1684		[IPU3_CSS_QUEUE_PARAMS]    = "params",
1685		[IPU3_CSS_QUEUE_OUT] = "out",
1686		[IPU3_CSS_QUEUE_VF] = "vf",
1687		[IPU3_CSS_QUEUE_STAT_3A]   = "3a",
1688	};
1689	static const char *rnames[IPU3_CSS_RECTS] = {
1690		[IPU3_CSS_RECT_EFFECTIVE] = "effective resolution",
1691		[IPU3_CSS_RECT_BDS]       = "bayer-domain scaled resolution",
1692		[IPU3_CSS_RECT_ENVELOPE]  = "DVS envelope size",
1693		[IPU3_CSS_RECT_GDC]  = "GDC output res",
1694	};
1695	struct v4l2_rect r[IPU3_CSS_RECTS] = { };
1696	struct v4l2_rect *const eff = &r[IPU3_CSS_RECT_EFFECTIVE];
1697	struct v4l2_rect *const bds = &r[IPU3_CSS_RECT_BDS];
1698	struct v4l2_rect *const env = &r[IPU3_CSS_RECT_ENVELOPE];
1699	struct v4l2_rect *const gdc = &r[IPU3_CSS_RECT_GDC];
1700	struct imgu_css_queue *q;
1701	struct v4l2_pix_format_mplane *in, *out, *vf;
1702	int i, s, ret;
1703
1704	q = kcalloc(IPU3_CSS_QUEUES, sizeof(struct imgu_css_queue), GFP_KERNEL);
1705	if (!q)
1706		return -ENOMEM;
1707
1708	in  = &q[IPU3_CSS_QUEUE_IN].fmt.mpix;
1709	out = &q[IPU3_CSS_QUEUE_OUT].fmt.mpix;
1710	vf  = &q[IPU3_CSS_QUEUE_VF].fmt.mpix;
1711
1712	/* Adjust all formats, get statistics buffer sizes and formats */
1713	for (i = 0; i < IPU3_CSS_QUEUES; i++) {
1714		if (fmts[i])
1715			dev_dbg(css->dev, "%s %s: (%i,%i) fmt 0x%x\n", __func__,
1716				qnames[i], fmts[i]->width, fmts[i]->height,
1717				fmts[i]->pixelformat);
1718		else
1719			dev_dbg(css->dev, "%s %s: (not set)\n", __func__,
1720				qnames[i]);
1721		if (imgu_css_queue_init(&q[i], fmts[i],
1722					IPU3_CSS_QUEUE_TO_FLAGS(i))) {
1723			dev_notice(css->dev, "can not initialize queue %s\n",
1724				   qnames[i]);
1725			ret = -EINVAL;
1726			goto out;
1727		}
1728	}
1729	for (i = 0; i < IPU3_CSS_RECTS; i++) {
1730		if (rects[i]) {
1731			dev_dbg(css->dev, "%s %s: (%i,%i)\n", __func__,
1732				rnames[i], rects[i]->width, rects[i]->height);
1733			r[i].width  = rects[i]->width;
1734			r[i].height = rects[i]->height;
1735		} else {
1736			dev_dbg(css->dev, "%s %s: (not set)\n", __func__,
1737				rnames[i]);
1738		}
1739		/* For now, force known good resolutions */
1740		r[i].left = 0;
1741		r[i].top  = 0;
1742	}
1743
1744	/* Always require one input and vf only if out is also enabled */
1745	if (!imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_IN]) ||
1746	    !imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) {
1747		dev_warn(css->dev, "required queues are disabled\n");
1748		ret = -EINVAL;
1749		goto out;
1750	}
1751
1752	if (!imgu_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) {
1753		out->width = in->width;
1754		out->height = in->height;
1755	}
1756	if (eff->width <= 0 || eff->height <= 0) {
1757		eff->width = in->width;
1758		eff->height = in->height;
1759	}
1760	if (bds->width <= 0 || bds->height <= 0) {
1761		bds->width = out->width;
1762		bds->height = out->height;
1763	}
1764	if (gdc->width <= 0 || gdc->height <= 0) {
1765		gdc->width = out->width;
1766		gdc->height = out->height;
1767	}
1768
1769	in->width   = imgu_css_adjust(in->width, 1);
1770	in->height  = imgu_css_adjust(in->height, 1);
1771	eff->width  = imgu_css_adjust(eff->width, EFF_ALIGN_W);
1772	eff->height = imgu_css_adjust(eff->height, 1);
1773	bds->width  = imgu_css_adjust(bds->width, BDS_ALIGN_W);
1774	bds->height = imgu_css_adjust(bds->height, 1);
1775	gdc->width  = imgu_css_adjust(gdc->width, OUT_ALIGN_W);
1776	gdc->height = imgu_css_adjust(gdc->height, OUT_ALIGN_H);
1777	out->width  = imgu_css_adjust(out->width, OUT_ALIGN_W);
1778	out->height = imgu_css_adjust(out->height, OUT_ALIGN_H);
1779	vf->width   = imgu_css_adjust(vf->width, VF_ALIGN_W);
1780	vf->height  = imgu_css_adjust(vf->height, 1);
1781
1782	s = (bds->width - gdc->width) / 2;
1783	env->width = s < MIN_ENVELOPE ? MIN_ENVELOPE : s;
1784	s = (bds->height - gdc->height) / 2;
1785	env->height = s < MIN_ENVELOPE ? MIN_ENVELOPE : s;
1786
1787	ret = imgu_css_find_binary(css, pipe, q, r);
1788	if (ret < 0) {
1789		dev_err(css->dev, "failed to find suitable binary\n");
1790		ret = -EINVAL;
1791		goto out;
1792	}
1793	css->pipes[pipe].bindex = ret;
1794
1795	dev_dbg(css->dev, "Binary index %d for pipe %d found.",
1796		css->pipes[pipe].bindex, pipe);
1797
1798	/* Final adjustment and set back the queried formats */
1799	for (i = 0; i < IPU3_CSS_QUEUES; i++) {
1800		if (fmts[i]) {
1801			if (imgu_css_queue_init(&q[i], &q[i].fmt.mpix,
1802						IPU3_CSS_QUEUE_TO_FLAGS(i))) {
1803				dev_err(css->dev,
1804					"final resolution adjustment failed\n");
1805				ret = -EINVAL;
1806				goto out;
1807			}
1808			*fmts[i] = q[i].fmt.mpix;
1809		}
1810	}
1811
1812	for (i = 0; i < IPU3_CSS_RECTS; i++)
1813		if (rects[i])
1814			*rects[i] = r[i];
1815
1816	dev_dbg(css->dev,
1817		"in(%u,%u) if(%u,%u) ds(%u,%u) gdc(%u,%u) out(%u,%u) vf(%u,%u)",
1818		 in->width, in->height, eff->width, eff->height,
1819		 bds->width, bds->height, gdc->width, gdc->height,
1820		 out->width, out->height, vf->width, vf->height);
1821
1822	ret = 0;
1823out:
1824	kfree(q);
1825	return ret;
1826}
1827
1828int imgu_css_fmt_set(struct imgu_css *css,
1829		     struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES],
1830		     struct v4l2_rect *rects[IPU3_CSS_RECTS],
1831		     unsigned int pipe)
1832{
1833	struct v4l2_rect rect_data[IPU3_CSS_RECTS];
1834	struct v4l2_rect *all_rects[IPU3_CSS_RECTS];
1835	int i, r;
1836	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1837
1838	for (i = 0; i < IPU3_CSS_RECTS; i++) {
1839		if (rects[i])
1840			rect_data[i] = *rects[i];
1841		else
1842			memset(&rect_data[i], 0, sizeof(rect_data[i]));
1843		all_rects[i] = &rect_data[i];
1844	}
1845	r = imgu_css_fmt_try(css, fmts, all_rects, pipe);
1846	if (r < 0)
1847		return r;
1848
1849	for (i = 0; i < IPU3_CSS_QUEUES; i++)
1850		if (imgu_css_queue_init(&css_pipe->queue[i], fmts[i],
1851					IPU3_CSS_QUEUE_TO_FLAGS(i)))
1852			return -EINVAL;
1853	for (i = 0; i < IPU3_CSS_RECTS; i++) {
1854		css_pipe->rect[i] = rect_data[i];
1855		if (rects[i])
1856			*rects[i] = rect_data[i];
1857	}
1858
1859	return 0;
1860}
1861
1862int imgu_css_meta_fmt_set(struct v4l2_meta_format *fmt)
1863{
1864	switch (fmt->dataformat) {
1865	case V4L2_META_FMT_IPU3_PARAMS:
1866		fmt->buffersize = sizeof(struct ipu3_uapi_params);
1867
1868		/*
1869		 * Sanity check for the parameter struct size. This must
1870		 * not change!
1871		 */
1872		BUILD_BUG_ON(sizeof(struct ipu3_uapi_params) != 39328);
1873
1874		break;
1875	case V4L2_META_FMT_IPU3_STAT_3A:
1876		fmt->buffersize = sizeof(struct ipu3_uapi_stats_3a);
1877		break;
1878	default:
1879		return -EINVAL;
1880	}
1881
1882	return 0;
1883}
1884
1885/*
1886 * Queue given buffer to CSS. imgu_css_buf_prepare() must have been first
1887 * called for the buffer. May be called from interrupt context.
1888 * Returns 0 on success, -EBUSY if the buffer queue is full, or some other
1889 * code on error conditions.
1890 */
1891int imgu_css_buf_queue(struct imgu_css *css, unsigned int pipe,
1892		       struct imgu_css_buffer *b)
1893{
1894	struct imgu_abi_buffer *abi_buf;
1895	struct imgu_addr_t *buf_addr;
1896	u32 data;
1897	int r;
1898	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
1899
1900	if (!css->streaming)
1901		return -EPROTO;	/* CSS or buffer in wrong state */
1902
1903	if (b->queue >= IPU3_CSS_QUEUES || !imgu_css_queues[b->queue].qid)
1904		return -EINVAL;
1905
1906	b->queue_pos = imgu_css_queue_pos(css, imgu_css_queues[b->queue].qid,
1907					  pipe);
1908
1909	if (b->queue_pos >= ARRAY_SIZE(css->pipes[pipe].abi_buffers[b->queue]))
1910		return -EIO;
1911	abi_buf = css->pipes[pipe].abi_buffers[b->queue][b->queue_pos].vaddr;
1912
1913	/* Fill struct abi_buffer for firmware */
1914	memset(abi_buf, 0, sizeof(*abi_buf));
1915
1916	buf_addr = (void *)abi_buf + imgu_css_queues[b->queue].ptr_ofs;
1917	*(imgu_addr_t *)buf_addr = b->daddr;
1918
1919	if (b->queue == IPU3_CSS_QUEUE_STAT_3A)
1920		abi_buf->payload.s3a.data.dmem.s3a_tbl = b->daddr;
1921
1922	if (b->queue == IPU3_CSS_QUEUE_OUT)
1923		abi_buf->payload.frame.padded_width =
1924				css_pipe->queue[IPU3_CSS_QUEUE_OUT].width_pad;
1925
1926	if (b->queue == IPU3_CSS_QUEUE_VF)
1927		abi_buf->payload.frame.padded_width =
1928					css_pipe->queue[IPU3_CSS_QUEUE_VF].width_pad;
1929
1930	spin_lock(&css_pipe->qlock);
1931	list_add_tail(&b->list, &css_pipe->queue[b->queue].bufs);
1932	spin_unlock(&css_pipe->qlock);
1933	b->state = IPU3_CSS_BUFFER_QUEUED;
1934
1935	data = css->pipes[pipe].abi_buffers[b->queue][b->queue_pos].daddr;
1936	r = imgu_css_queue_data(css, imgu_css_queues[b->queue].qid,
1937				pipe, data);
1938	if (r < 0)
1939		goto queueing_failed;
1940
1941	data = IMGU_ABI_EVENT_BUFFER_ENQUEUED(pipe,
1942					      imgu_css_queues[b->queue].qid);
1943	r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, data);
1944	if (r < 0)
1945		goto queueing_failed;
1946
1947	dev_dbg(css->dev, "queued buffer %p to css queue %i in pipe %d\n",
1948		b, b->queue, pipe);
1949
1950	return 0;
1951
1952queueing_failed:
1953	b->state = (r == -EBUSY || r == -EAGAIN) ?
1954		IPU3_CSS_BUFFER_NEW : IPU3_CSS_BUFFER_FAILED;
1955	list_del(&b->list);
1956
1957	return r;
1958}
1959
1960/*
1961 * Get next ready CSS buffer. Returns -EAGAIN in which case the function
1962 * should be called again, or -EBUSY which means that there are no more
1963 * buffers available. May be called from interrupt context.
1964 */
1965struct imgu_css_buffer *imgu_css_buf_dequeue(struct imgu_css *css)
1966{
1967	static const unsigned char evtype_to_queue[] = {
1968		[IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE] = IPU3_CSS_QUEUE_IN,
1969		[IMGU_ABI_EVTTYPE_OUT_FRAME_DONE] = IPU3_CSS_QUEUE_OUT,
1970		[IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE] = IPU3_CSS_QUEUE_VF,
1971		[IMGU_ABI_EVTTYPE_3A_STATS_DONE] = IPU3_CSS_QUEUE_STAT_3A,
1972	};
1973	struct imgu_css_buffer *b = ERR_PTR(-EAGAIN);
1974	u32 event, daddr;
1975	int evtype, pipe, pipeid, queue, qid, r;
1976	struct imgu_css_pipe *css_pipe;
1977
1978	if (!css->streaming)
1979		return ERR_PTR(-EPROTO);
1980
1981	r = imgu_css_dequeue_data(css, IMGU_ABI_QUEUE_EVENT_ID, &event);
1982	if (r < 0)
1983		return ERR_PTR(r);
1984
1985	evtype = (event & IMGU_ABI_EVTTYPE_EVENT_MASK) >>
1986		  IMGU_ABI_EVTTYPE_EVENT_SHIFT;
1987
1988	switch (evtype) {
1989	case IMGU_ABI_EVTTYPE_OUT_FRAME_DONE:
1990	case IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE:
1991	case IMGU_ABI_EVTTYPE_3A_STATS_DONE:
1992	case IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE:
1993		pipe = (event & IMGU_ABI_EVTTYPE_PIPE_MASK) >>
1994			IMGU_ABI_EVTTYPE_PIPE_SHIFT;
1995		pipeid = (event & IMGU_ABI_EVTTYPE_PIPEID_MASK) >>
1996			IMGU_ABI_EVTTYPE_PIPEID_SHIFT;
1997		queue = evtype_to_queue[evtype];
1998		qid = imgu_css_queues[queue].qid;
1999
2000		if (pipe >= IMGU_MAX_PIPE_NUM) {
2001			dev_err(css->dev, "Invalid pipe: %i\n", pipe);
2002			return ERR_PTR(-EIO);
2003		}
2004
2005		if (qid >= IMGU_ABI_QUEUE_NUM) {
2006			dev_err(css->dev, "Invalid qid: %i\n", qid);
2007			return ERR_PTR(-EIO);
2008		}
2009		css_pipe = &css->pipes[pipe];
2010		dev_dbg(css->dev,
2011			"event: buffer done 0x%x queue %i pipe %i pipeid %i\n",
2012			event, queue, pipe, pipeid);
2013
2014		r = imgu_css_dequeue_data(css, qid, &daddr);
2015		if (r < 0) {
2016			dev_err(css->dev, "failed to dequeue buffer\n");
2017			/* Force real error, not -EBUSY */
2018			return ERR_PTR(-EIO);
2019		}
2020
2021		r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
2022					IMGU_ABI_EVENT_BUFFER_DEQUEUED(qid));
2023		if (r < 0) {
2024			dev_err(css->dev, "failed to queue event\n");
2025			return ERR_PTR(-EIO);
2026		}
2027
2028		spin_lock(&css_pipe->qlock);
2029		if (list_empty(&css_pipe->queue[queue].bufs)) {
2030			spin_unlock(&css_pipe->qlock);
2031			dev_err(css->dev, "event on empty queue\n");
2032			return ERR_PTR(-EIO);
2033		}
2034		b = list_first_entry(&css_pipe->queue[queue].bufs,
2035				     struct imgu_css_buffer, list);
2036		if (queue != b->queue ||
2037		    daddr != css_pipe->abi_buffers
2038			[b->queue][b->queue_pos].daddr) {
2039			spin_unlock(&css_pipe->qlock);
2040			dev_err(css->dev, "dequeued bad buffer 0x%x\n", daddr);
2041			return ERR_PTR(-EIO);
2042		}
2043
2044		dev_dbg(css->dev, "buffer 0x%8x done from pipe %d\n", daddr, pipe);
2045		b->pipe = pipe;
2046		b->state = IPU3_CSS_BUFFER_DONE;
2047		list_del(&b->list);
2048		spin_unlock(&css_pipe->qlock);
2049		break;
2050	case IMGU_ABI_EVTTYPE_PIPELINE_DONE:
2051		pipe = (event & IMGU_ABI_EVTTYPE_PIPE_MASK) >>
2052			IMGU_ABI_EVTTYPE_PIPE_SHIFT;
2053		if (pipe >= IMGU_MAX_PIPE_NUM) {
2054			dev_err(css->dev, "Invalid pipe: %i\n", pipe);
2055			return ERR_PTR(-EIO);
2056		}
2057
2058		css_pipe = &css->pipes[pipe];
2059		dev_dbg(css->dev, "event: pipeline done 0x%8x for pipe %d\n",
2060			event, pipe);
2061		break;
2062	case IMGU_ABI_EVTTYPE_TIMER:
2063		r = imgu_css_dequeue_data(css, IMGU_ABI_QUEUE_EVENT_ID, &event);
2064		if (r < 0)
2065			return ERR_PTR(r);
2066
2067		if ((event & IMGU_ABI_EVTTYPE_EVENT_MASK) >>
2068		    IMGU_ABI_EVTTYPE_EVENT_SHIFT == IMGU_ABI_EVTTYPE_TIMER)
2069			dev_dbg(css->dev, "event: timer\n");
2070		else
2071			dev_warn(css->dev, "half of timer event missing\n");
2072		break;
2073	case IMGU_ABI_EVTTYPE_FW_WARNING:
2074		dev_warn(css->dev, "event: firmware warning 0x%x\n", event);
2075		break;
2076	case IMGU_ABI_EVTTYPE_FW_ASSERT:
2077		dev_err(css->dev,
2078			"event: firmware assert 0x%x module_id %i line_no %i\n",
2079			event,
2080			(event & IMGU_ABI_EVTTYPE_MODULEID_MASK) >>
2081			IMGU_ABI_EVTTYPE_MODULEID_SHIFT,
2082			swab16((event & IMGU_ABI_EVTTYPE_LINENO_MASK) >>
2083			       IMGU_ABI_EVTTYPE_LINENO_SHIFT));
2084		break;
2085	default:
2086		dev_warn(css->dev, "received unknown event 0x%x\n", event);
2087	}
2088
2089	return b;
2090}
2091
2092/*
2093 * Get a new set of parameters from pool and initialize them based on
2094 * the parameters params, gdc, and obgrid. Any of these may be NULL,
2095 * in which case the previously set parameters are used.
2096 * If parameters haven't been set previously, initialize from scratch.
2097 *
2098 * Return index to css->parameter_set_info which has the newly created
2099 * parameters or negative value on error.
2100 */
2101int imgu_css_set_parameters(struct imgu_css *css, unsigned int pipe,
2102			    struct ipu3_uapi_params *set_params)
2103{
2104	static const unsigned int queue_id = IMGU_ABI_QUEUE_A_ID;
2105	struct imgu_css_pipe *css_pipe = &css->pipes[pipe];
2106	const int stage = 0;
2107	const struct imgu_fw_info *bi;
2108	int obgrid_size;
2109	unsigned int stripes, i;
2110	struct ipu3_uapi_flags *use = set_params ? &set_params->use : NULL;
2111
2112	/* Destination buffers which are filled here */
2113	struct imgu_abi_parameter_set_info *param_set;
2114	struct imgu_abi_acc_param *acc = NULL;
2115	struct imgu_abi_gdc_warp_param *gdc = NULL;
2116	struct ipu3_uapi_obgrid_param *obgrid = NULL;
2117	const struct imgu_css_map *map;
2118	void *vmem0 = NULL;
2119	void *dmem0 = NULL;
2120
2121	enum imgu_abi_memories m;
2122	int r = -EBUSY;
2123
2124	if (!css->streaming)
2125		return -EPROTO;
2126
2127	dev_dbg(css->dev, "%s for pipe %d", __func__, pipe);
2128
2129	bi = &css->fwp->binary_header[css_pipe->bindex];
2130	obgrid_size = imgu_css_fw_obgrid_size(bi);
2131	stripes = bi->info.isp.sp.iterator.num_stripes ? : 1;
2132
2133	imgu_css_pool_get(&css_pipe->pool.parameter_set_info);
2134	param_set = imgu_css_pool_last(&css_pipe->pool.parameter_set_info,
2135				       0)->vaddr;
2136
2137	/* Get a new acc only if new parameters given, or none yet */
2138	map = imgu_css_pool_last(&css_pipe->pool.acc, 0);
2139	if (set_params || !map->vaddr) {
2140		imgu_css_pool_get(&css_pipe->pool.acc);
2141		map = imgu_css_pool_last(&css_pipe->pool.acc, 0);
2142		acc = map->vaddr;
2143	}
2144
2145	/* Get new VMEM0 only if needed, or none yet */
2146	m = IMGU_ABI_MEM_ISP_VMEM0;
2147	map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
2148	if (!map->vaddr || (set_params && (set_params->use.lin_vmem_params ||
2149					   set_params->use.tnr3_vmem_params ||
2150					   set_params->use.xnr3_vmem_params))) {
2151		imgu_css_pool_get(&css_pipe->pool.binary_params_p[m]);
2152		map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
2153		vmem0 = map->vaddr;
2154	}
2155
2156	/* Get new DMEM0 only if needed, or none yet */
2157	m = IMGU_ABI_MEM_ISP_DMEM0;
2158	map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
2159	if (!map->vaddr || (set_params && (set_params->use.tnr3_dmem_params ||
2160					   set_params->use.xnr3_dmem_params))) {
2161		imgu_css_pool_get(&css_pipe->pool.binary_params_p[m]);
2162		map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
2163		dmem0 = map->vaddr;
2164	}
2165
2166	/* Configure acc parameter cluster */
2167	if (acc) {
2168		/* get acc_old */
2169		map = imgu_css_pool_last(&css_pipe->pool.acc, 1);
2170		/* user acc */
2171		r = imgu_css_cfg_acc(css, pipe, use, acc, map->vaddr,
2172			set_params ? &set_params->acc_param : NULL);
2173		if (r < 0)
2174			goto fail;
2175	}
2176
2177	/* Configure late binding parameters */
2178	if (vmem0) {
2179		m = IMGU_ABI_MEM_ISP_VMEM0;
2180		map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 1);
2181		r = imgu_css_cfg_vmem0(css, pipe, use, vmem0,
2182				       map->vaddr, set_params);
2183		if (r < 0)
2184			goto fail;
2185	}
2186
2187	if (dmem0) {
2188		m = IMGU_ABI_MEM_ISP_DMEM0;
2189		map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 1);
2190		r = imgu_css_cfg_dmem0(css, pipe, use, dmem0,
2191				       map->vaddr, set_params);
2192		if (r < 0)
2193			goto fail;
2194	}
2195
2196	/* Get a new gdc only if a new gdc is given, or none yet */
2197	if (bi->info.isp.sp.enable.dvs_6axis) {
2198		unsigned int a = IPU3_CSS_AUX_FRAME_REF;
2199		unsigned int g = IPU3_CSS_RECT_GDC;
2200		unsigned int e = IPU3_CSS_RECT_ENVELOPE;
2201
2202		map = imgu_css_pool_last(&css_pipe->pool.gdc, 0);
2203		if (!map->vaddr) {
2204			imgu_css_pool_get(&css_pipe->pool.gdc);
2205			map = imgu_css_pool_last(&css_pipe->pool.gdc, 0);
2206			gdc = map->vaddr;
2207			imgu_css_cfg_gdc_table(map->vaddr,
2208				css_pipe->aux_frames[a].bytesperline /
2209				css_pipe->aux_frames[a].bytesperpixel,
2210				css_pipe->aux_frames[a].height,
2211				css_pipe->rect[g].width,
2212				css_pipe->rect[g].height,
2213				css_pipe->rect[e].width,
2214				css_pipe->rect[e].height);
2215		}
2216	}
2217
2218	/* Get a new obgrid only if a new obgrid is given, or none yet */
2219	map = imgu_css_pool_last(&css_pipe->pool.obgrid, 0);
2220	if (!map->vaddr || (set_params && set_params->use.obgrid_param)) {
2221		imgu_css_pool_get(&css_pipe->pool.obgrid);
2222		map = imgu_css_pool_last(&css_pipe->pool.obgrid, 0);
2223		obgrid = map->vaddr;
2224
2225		/* Configure optical black level grid (obgrid) */
2226		if (set_params && set_params->use.obgrid_param)
2227			for (i = 0; i < obgrid_size / sizeof(*obgrid); i++)
2228				obgrid[i] = set_params->obgrid_param;
2229		else
2230			memset(obgrid, 0, obgrid_size);
2231	}
2232
2233	/* Configure parameter set info, queued to `queue_id' */
2234
2235	memset(param_set, 0, sizeof(*param_set));
2236	map = imgu_css_pool_last(&css_pipe->pool.acc, 0);
2237	param_set->mem_map.acc_cluster_params_for_sp = map->daddr;
2238
2239	map = imgu_css_pool_last(&css_pipe->pool.gdc, 0);
2240	param_set->mem_map.dvs_6axis_params_y = map->daddr;
2241
2242	for (i = 0; i < stripes; i++) {
2243		map = imgu_css_pool_last(&css_pipe->pool.obgrid, 0);
2244		param_set->mem_map.obgrid_tbl[i] =
2245			map->daddr + (obgrid_size / stripes) * i;
2246	}
2247
2248	for (m = 0; m < IMGU_ABI_NUM_MEMORIES; m++) {
2249		map = imgu_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
2250		param_set->mem_map.isp_mem_param[stage][m] = map->daddr;
2251	}
2252
2253	/* Then queue the new parameter buffer */
2254	map = imgu_css_pool_last(&css_pipe->pool.parameter_set_info, 0);
2255	r = imgu_css_queue_data(css, queue_id, pipe, map->daddr);
2256	if (r < 0)
2257		goto fail;
2258
2259	r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
2260				IMGU_ABI_EVENT_BUFFER_ENQUEUED(pipe,
2261							       queue_id));
2262	if (r < 0)
2263		goto fail_no_put;
2264
2265	/* Finally dequeue all old parameter buffers */
2266
2267	do {
2268		u32 daddr;
2269
2270		r = imgu_css_dequeue_data(css, queue_id, &daddr);
2271		if (r == -EBUSY)
2272			break;
2273		if (r)
2274			goto fail_no_put;
2275		r = imgu_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
2276					IMGU_ABI_EVENT_BUFFER_DEQUEUED
2277					(queue_id));
2278		if (r < 0) {
2279			dev_err(css->dev, "failed to queue parameter event\n");
2280			goto fail_no_put;
2281		}
2282	} while (1);
2283
2284	return 0;
2285
2286fail:
2287	/*
2288	 * A failure, most likely the parameter queue was full.
2289	 * Return error but continue streaming. User can try submitting new
2290	 * parameters again later.
2291	 */
2292
2293	imgu_css_pool_put(&css_pipe->pool.parameter_set_info);
2294	if (acc)
2295		imgu_css_pool_put(&css_pipe->pool.acc);
2296	if (gdc)
2297		imgu_css_pool_put(&css_pipe->pool.gdc);
2298	if (obgrid)
2299		imgu_css_pool_put(&css_pipe->pool.obgrid);
2300	if (vmem0)
2301		imgu_css_pool_put(
2302			&css_pipe->pool.binary_params_p
2303			[IMGU_ABI_MEM_ISP_VMEM0]);
2304	if (dmem0)
2305		imgu_css_pool_put(
2306			&css_pipe->pool.binary_params_p
2307			[IMGU_ABI_MEM_ISP_DMEM0]);
2308
2309fail_no_put:
2310	return r;
2311}
2312
2313int imgu_css_irq_ack(struct imgu_css *css)
2314{
2315	static const int NUM_SWIRQS = 3;
2316	struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[0]];
2317	void __iomem *const base = css->base;
2318	u32 irq_status[IMGU_IRQCTRL_NUM];
2319	int i;
2320
2321	u32 imgu_status = readl(base + IMGU_REG_INT_STATUS);
2322
2323	writel(imgu_status, base + IMGU_REG_INT_STATUS);
2324	for (i = 0; i < IMGU_IRQCTRL_NUM; i++)
2325		irq_status[i] = readl(base + IMGU_REG_IRQCTRL_STATUS(i));
2326
2327	for (i = 0; i < NUM_SWIRQS; i++) {
2328		if (irq_status[IMGU_IRQCTRL_SP0] & IMGU_IRQCTRL_IRQ_SW_PIN(i)) {
2329			/* SP SW interrupt */
2330			u32 cnt = readl(base + IMGU_REG_SP_DMEM_BASE(0) +
2331					bi->info.sp.output);
2332			u32 val = readl(base + IMGU_REG_SP_DMEM_BASE(0) +
2333					bi->info.sp.output + 4 + 4 * i);
2334
2335			dev_dbg(css->dev, "%s: swirq %i cnt %i val 0x%x\n",
2336				__func__, i, cnt, val);
2337		}
2338	}
2339
2340	for (i = IMGU_IRQCTRL_NUM - 1; i >= 0; i--)
2341		if (irq_status[i]) {
2342			writel(irq_status[i], base + IMGU_REG_IRQCTRL_CLEAR(i));
2343			/* Wait for write to complete */
2344			readl(base + IMGU_REG_IRQCTRL_ENABLE(i));
2345		}
2346
2347	dev_dbg(css->dev, "%s: imgu 0x%x main 0x%x sp0 0x%x sp1 0x%x\n",
2348		__func__, imgu_status, irq_status[IMGU_IRQCTRL_MAIN],
2349		irq_status[IMGU_IRQCTRL_SP0], irq_status[IMGU_IRQCTRL_SP1]);
2350
2351	if (!imgu_status && !irq_status[IMGU_IRQCTRL_MAIN])
2352		return -ENOMSG;
2353
2354	return 0;
2355}
2356