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