1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Support for Intel Camera Imaging ISP subsystem.
4   * Copyright (c) 2015, Intel Corporation.
5   *
6   * This program is free software; you can redistribute it and/or modify it
7   * under the terms and conditions of the GNU General Public License,
8   * version 2, as published by the Free Software Foundation.
9   *
10   * This program is distributed in the hope it will be useful, but WITHOUT
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13   * more details.
14   */
15  
16  #include <linux/bitops.h>
17  #include <linux/math.h>
18  #include <linux/string.h> /* for memcpy() */
19  
20  #include "system_global.h"
21  
22  
23  #include "ia_css_isys.h"
24  #include "ia_css_debug.h"
25  #include "virtual_isys.h"
26  #include "isp.h"
27  #include "sh_css_defs.h"
28  
29  /*************************************************
30   *
31   * Forwarded Declaration
32   *
33   *************************************************/
34  
35  static bool create_input_system_channel(
36      isp2401_input_system_cfg_t	*cfg,
37      bool			metadata,
38      input_system_channel_t	*channel);
39  
40  static void destroy_input_system_channel(
41      input_system_channel_t	*channel);
42  
43  static bool create_input_system_input_port(
44      isp2401_input_system_cfg_t		*cfg,
45      input_system_input_port_t	*input_port);
46  
47  static void destroy_input_system_input_port(
48      input_system_input_port_t	*input_port);
49  
50  static bool calculate_input_system_channel_cfg(
51      input_system_channel_t		*channel,
52      input_system_input_port_t	*input_port,
53      isp2401_input_system_cfg_t		*isys_cfg,
54      input_system_channel_cfg_t	*channel_cfg,
55      bool metadata);
56  
57  static bool calculate_input_system_input_port_cfg(
58      input_system_channel_t		*channel,
59      input_system_input_port_t	*input_port,
60      isp2401_input_system_cfg_t		*isys_cfg,
61      input_system_input_port_cfg_t	*input_port_cfg);
62  
63  static bool acquire_sid(
64      stream2mmio_ID_t	stream2mmio,
65      stream2mmio_sid_ID_t	*sid);
66  
67  static void release_sid(
68      stream2mmio_ID_t	stream2mmio,
69      stream2mmio_sid_ID_t	*sid);
70  
71  static bool acquire_ib_buffer(
72      s32 bits_per_pixel,
73      s32 pixels_per_line,
74      s32 lines_per_frame,
75      s32 align_in_bytes,
76      bool online,
77      isp2401_ib_buffer_t *buf);
78  
79  static void release_ib_buffer(
80      isp2401_ib_buffer_t *buf);
81  
82  static bool acquire_dma_channel(
83      isys2401_dma_ID_t	dma_id,
84      isys2401_dma_channel	*channel);
85  
86  static void release_dma_channel(
87      isys2401_dma_ID_t	dma_id,
88      isys2401_dma_channel	*channel);
89  
90  static bool acquire_be_lut_entry(
91      csi_rx_backend_ID_t		backend,
92      csi_mipi_packet_type_t		packet_type,
93      csi_rx_backend_lut_entry_t	*entry);
94  
95  static void release_be_lut_entry(
96      csi_rx_backend_ID_t		backend,
97      csi_mipi_packet_type_t		packet_type,
98      csi_rx_backend_lut_entry_t	*entry);
99  
100  static bool calculate_prbs_cfg(
101      input_system_channel_t		*channel,
102      input_system_input_port_t	*input_port,
103      isp2401_input_system_cfg_t		*isys_cfg,
104      pixelgen_prbs_cfg_t		*cfg);
105  
106  static bool calculate_fe_cfg(
107      const isp2401_input_system_cfg_t	*isys_cfg,
108      csi_rx_frontend_cfg_t		*cfg);
109  
110  static bool calculate_be_cfg(
111      const input_system_input_port_t	*input_port,
112      const isp2401_input_system_cfg_t	*isys_cfg,
113      bool				metadata,
114      csi_rx_backend_cfg_t		*cfg);
115  
116  static bool calculate_stream2mmio_cfg(
117      const isp2401_input_system_cfg_t	*isys_cfg,
118      bool				metadata,
119      stream2mmio_cfg_t		*cfg);
120  
121  static bool calculate_ibuf_ctrl_cfg(
122      const input_system_channel_t	*channel,
123      const input_system_input_port_t	*input_port,
124      const isp2401_input_system_cfg_t	*isys_cfg,
125      ibuf_ctrl_cfg_t			*cfg);
126  
127  static bool calculate_isys2401_dma_cfg(
128      const input_system_channel_t	*channel,
129      const isp2401_input_system_cfg_t	*isys_cfg,
130      isys2401_dma_cfg_t		*cfg);
131  
132  static bool calculate_isys2401_dma_port_cfg(
133      const isp2401_input_system_cfg_t	*isys_cfg,
134      bool				raw_packed,
135      bool				metadata,
136      isys2401_dma_port_cfg_t		*cfg);
137  
138  static csi_mipi_packet_type_t get_csi_mipi_packet_type(
139      int32_t data_type);
140  
141  static int32_t calculate_stride(
142      s32 bits_per_pixel,
143      s32 pixels_per_line,
144      bool	raw_packed,
145      int32_t	align_in_bytes);
146  
147  /* end of Forwarded Declaration */
148  
149  /**************************************************
150   *
151   * Public Methods
152   *
153   **************************************************/
ia_css_isys_stream_create(ia_css_isys_descr_t * isys_stream_descr,ia_css_isys_stream_h isys_stream,uint32_t isys_stream_id)154  ia_css_isys_error_t ia_css_isys_stream_create(
155      ia_css_isys_descr_t	*isys_stream_descr,
156      ia_css_isys_stream_h	isys_stream,
157      uint32_t isys_stream_id)
158  {
159  	ia_css_isys_error_t rc;
160  
161  	if (!isys_stream_descr || !isys_stream ||
162  	    isys_stream_id >= SH_CSS_MAX_ISYS_CHANNEL_NODES)
163  		return	false;
164  
165  	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
166  			    "ia_css_isys_stream_create() enter:\n");
167  
168  	/*Reset isys_stream to 0*/
169  	memset(isys_stream, 0, sizeof(*isys_stream));
170  	isys_stream->enable_metadata = isys_stream_descr->metadata.enable;
171  	isys_stream->id = isys_stream_id;
172  
173  	isys_stream->linked_isys_stream_id = isys_stream_descr->linked_isys_stream_id;
174  	rc = create_input_system_input_port(isys_stream_descr,
175  					    &isys_stream->input_port);
176  	if (!rc)
177  		return false;
178  
179  	rc = create_input_system_channel(isys_stream_descr, false,
180  					 &isys_stream->channel);
181  	if (!rc) {
182  		destroy_input_system_input_port(&isys_stream->input_port);
183  		return false;
184  	}
185  
186  	/* create metadata channel */
187  	if (isys_stream_descr->metadata.enable) {
188  		rc = create_input_system_channel(isys_stream_descr, true,
189  						 &isys_stream->md_channel);
190  		if (!rc) {
191  			destroy_input_system_input_port(&isys_stream->input_port);
192  			destroy_input_system_channel(&isys_stream->channel);
193  			return false;
194  		}
195  	}
196  	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
197  			    "ia_css_isys_stream_create() leave:\n");
198  
199  	return true;
200  }
201  
ia_css_isys_stream_destroy(ia_css_isys_stream_h isys_stream)202  void ia_css_isys_stream_destroy(
203      ia_css_isys_stream_h	isys_stream)
204  {
205  	destroy_input_system_input_port(&isys_stream->input_port);
206  	destroy_input_system_channel(&isys_stream->channel);
207  	if (isys_stream->enable_metadata) {
208  		/* Destroy metadata channel only if its allocated*/
209  		destroy_input_system_channel(&isys_stream->md_channel);
210  	}
211  }
212  
ia_css_isys_stream_calculate_cfg(ia_css_isys_stream_h isys_stream,ia_css_isys_descr_t * isys_stream_descr,ia_css_isys_stream_cfg_t * isys_stream_cfg)213  ia_css_isys_error_t ia_css_isys_stream_calculate_cfg(
214      ia_css_isys_stream_h		isys_stream,
215      ia_css_isys_descr_t		*isys_stream_descr,
216      ia_css_isys_stream_cfg_t	*isys_stream_cfg)
217  {
218  	ia_css_isys_error_t rc;
219  
220  	if (!isys_stream_cfg		||
221  	    !isys_stream_descr	||
222  	    !isys_stream)
223  		return false;
224  
225  	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
226  			    "ia_css_isys_stream_calculate_cfg() enter:\n");
227  
228  	rc  = calculate_input_system_channel_cfg(
229  		  &isys_stream->channel,
230  		  &isys_stream->input_port,
231  		  isys_stream_descr,
232  		  &isys_stream_cfg->channel_cfg,
233  		  false);
234  	if (!rc)
235  		return false;
236  
237  	/* configure metadata channel */
238  	if (isys_stream_descr->metadata.enable) {
239  		isys_stream_cfg->enable_metadata = true;
240  		rc  = calculate_input_system_channel_cfg(
241  			  &isys_stream->md_channel,
242  			  &isys_stream->input_port,
243  			  isys_stream_descr,
244  			  &isys_stream_cfg->md_channel_cfg,
245  			  true);
246  		if (!rc)
247  			return false;
248  	}
249  
250  	rc = calculate_input_system_input_port_cfg(
251  		 &isys_stream->channel,
252  		 &isys_stream->input_port,
253  		 isys_stream_descr,
254  		 &isys_stream_cfg->input_port_cfg);
255  	if (!rc)
256  		return false;
257  
258  	isys_stream->valid = 1;
259  	isys_stream_cfg->valid = 1;
260  	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
261  			    "ia_css_isys_stream_calculate_cfg() leave:\n");
262  	return rc;
263  }
264  
265  /* end of Public Methods */
266  
267  /**************************************************
268   *
269   * Private Methods
270   *
271   **************************************************/
create_input_system_channel(isp2401_input_system_cfg_t * cfg,bool metadata,input_system_channel_t * me)272  static bool create_input_system_channel(
273      isp2401_input_system_cfg_t	*cfg,
274      bool			metadata,
275      input_system_channel_t	*me)
276  {
277  	bool rc = true;
278  
279  	me->dma_id = ISYS2401_DMA0_ID;
280  
281  	switch (cfg->input_port_id) {
282  	case INPUT_SYSTEM_CSI_PORT0_ID:
283  	case INPUT_SYSTEM_PIXELGEN_PORT0_ID:
284  		me->stream2mmio_id = STREAM2MMIO0_ID;
285  		me->ibuf_ctrl_id = IBUF_CTRL0_ID;
286  		break;
287  
288  	case INPUT_SYSTEM_CSI_PORT1_ID:
289  	case INPUT_SYSTEM_PIXELGEN_PORT1_ID:
290  		me->stream2mmio_id = STREAM2MMIO1_ID;
291  		me->ibuf_ctrl_id = IBUF_CTRL1_ID;
292  		break;
293  
294  	case INPUT_SYSTEM_CSI_PORT2_ID:
295  	case INPUT_SYSTEM_PIXELGEN_PORT2_ID:
296  		me->stream2mmio_id = STREAM2MMIO2_ID;
297  		me->ibuf_ctrl_id = IBUF_CTRL2_ID;
298  		break;
299  	default:
300  		rc = false;
301  		break;
302  	}
303  
304  	if (!rc)
305  		return false;
306  
307  	if (!acquire_sid(me->stream2mmio_id, &me->stream2mmio_sid_id)) {
308  		return false;
309  	}
310  
311  	if (!acquire_ib_buffer(
312  		metadata ? cfg->metadata.bits_per_pixel :
313  		cfg->input_port_resolution.bits_per_pixel,
314  		metadata ? cfg->metadata.pixels_per_line :
315  		cfg->input_port_resolution.pixels_per_line,
316  		metadata ? cfg->metadata.lines_per_frame :
317  		cfg->input_port_resolution.lines_per_frame,
318  		metadata ? cfg->metadata.align_req_in_bytes :
319  		cfg->input_port_resolution.align_req_in_bytes,
320  		cfg->online,
321  		&me->ib_buffer)) {
322  		release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id);
323  		return false;
324  	}
325  
326  	if (!acquire_dma_channel(me->dma_id, &me->dma_channel)) {
327  		release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id);
328  		release_ib_buffer(&me->ib_buffer);
329  		return false;
330  	}
331  
332  	return true;
333  }
334  
destroy_input_system_channel(input_system_channel_t * me)335  static void destroy_input_system_channel(
336      input_system_channel_t	*me)
337  {
338  	release_sid(me->stream2mmio_id,
339  		    &me->stream2mmio_sid_id);
340  
341  	release_ib_buffer(&me->ib_buffer);
342  
343  	release_dma_channel(me->dma_id, &me->dma_channel);
344  }
345  
create_input_system_input_port(isp2401_input_system_cfg_t * cfg,input_system_input_port_t * me)346  static bool create_input_system_input_port(
347      isp2401_input_system_cfg_t		*cfg,
348      input_system_input_port_t	*me)
349  {
350  	csi_mipi_packet_type_t packet_type;
351  	bool rc = true;
352  
353  	switch (cfg->input_port_id) {
354  	case INPUT_SYSTEM_CSI_PORT0_ID:
355  		me->csi_rx.frontend_id = CSI_RX_FRONTEND0_ID;
356  		me->csi_rx.backend_id = CSI_RX_BACKEND0_ID;
357  
358  		packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
359  		me->csi_rx.packet_type = packet_type;
360  
361  		rc = acquire_be_lut_entry(
362  			 me->csi_rx.backend_id,
363  			 packet_type,
364  			 &me->csi_rx.backend_lut_entry);
365  		break;
366  	case INPUT_SYSTEM_PIXELGEN_PORT0_ID:
367  		me->pixelgen.pixelgen_id = PIXELGEN0_ID;
368  		break;
369  	case INPUT_SYSTEM_CSI_PORT1_ID:
370  		me->csi_rx.frontend_id = CSI_RX_FRONTEND1_ID;
371  		me->csi_rx.backend_id = CSI_RX_BACKEND1_ID;
372  
373  		packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
374  		me->csi_rx.packet_type = packet_type;
375  
376  		rc = acquire_be_lut_entry(
377  			 me->csi_rx.backend_id,
378  			 packet_type,
379  			 &me->csi_rx.backend_lut_entry);
380  		break;
381  	case INPUT_SYSTEM_PIXELGEN_PORT1_ID:
382  		me->pixelgen.pixelgen_id = PIXELGEN1_ID;
383  
384  		break;
385  	case INPUT_SYSTEM_CSI_PORT2_ID:
386  		me->csi_rx.frontend_id = CSI_RX_FRONTEND2_ID;
387  		me->csi_rx.backend_id = CSI_RX_BACKEND2_ID;
388  
389  		packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
390  		me->csi_rx.packet_type = packet_type;
391  
392  		rc = acquire_be_lut_entry(
393  			 me->csi_rx.backend_id,
394  			 packet_type,
395  			 &me->csi_rx.backend_lut_entry);
396  		break;
397  	case INPUT_SYSTEM_PIXELGEN_PORT2_ID:
398  		me->pixelgen.pixelgen_id = PIXELGEN2_ID;
399  		break;
400  	default:
401  		rc = false;
402  		break;
403  	}
404  
405  	me->source_type = cfg->mode;
406  
407  	/* for metadata */
408  	me->metadata.packet_type = CSI_MIPI_PACKET_TYPE_UNDEFINED;
409  	if (rc && cfg->metadata.enable) {
410  		me->metadata.packet_type = get_csi_mipi_packet_type(
411  					       cfg->metadata.fmt_type);
412  		rc = acquire_be_lut_entry(
413  			 me->csi_rx.backend_id,
414  			 me->metadata.packet_type,
415  			 &me->metadata.backend_lut_entry);
416  	}
417  
418  	return rc;
419  }
420  
destroy_input_system_input_port(input_system_input_port_t * me)421  static void destroy_input_system_input_port(
422      input_system_input_port_t	*me)
423  {
424  	if (me->source_type == INPUT_SYSTEM_SOURCE_TYPE_SENSOR) {
425  		release_be_lut_entry(
426  		    me->csi_rx.backend_id,
427  		    me->csi_rx.packet_type,
428  		    &me->csi_rx.backend_lut_entry);
429  	}
430  
431  	if (me->metadata.packet_type != CSI_MIPI_PACKET_TYPE_UNDEFINED) {
432  		/*Free the backend lut allocated for metadata*/
433  		release_be_lut_entry(
434  		    me->csi_rx.backend_id,
435  		    me->metadata.packet_type,
436  		    &me->metadata.backend_lut_entry);
437  	}
438  }
439  
calculate_input_system_channel_cfg(input_system_channel_t * channel,input_system_input_port_t * input_port,isp2401_input_system_cfg_t * isys_cfg,input_system_channel_cfg_t * channel_cfg,bool metadata)440  static bool calculate_input_system_channel_cfg(
441      input_system_channel_t		*channel,
442      input_system_input_port_t	*input_port,
443      isp2401_input_system_cfg_t		*isys_cfg,
444      input_system_channel_cfg_t	*channel_cfg,
445      bool metadata)
446  {
447  	bool rc;
448  
449  	rc = calculate_stream2mmio_cfg(isys_cfg, metadata,
450  				       &channel_cfg->stream2mmio_cfg);
451  	if (!rc)
452  		return false;
453  
454  	rc = calculate_ibuf_ctrl_cfg(
455  		 channel,
456  		 input_port,
457  		 isys_cfg,
458  		 &channel_cfg->ibuf_ctrl_cfg);
459  	if (!rc)
460  		return false;
461  	if (metadata)
462  		channel_cfg->ibuf_ctrl_cfg.stores_per_frame =
463  		    isys_cfg->metadata.lines_per_frame;
464  
465  	rc = calculate_isys2401_dma_cfg(
466  		 channel,
467  		 isys_cfg,
468  		 &channel_cfg->dma_cfg);
469  	if (!rc)
470  		return false;
471  
472  	rc = calculate_isys2401_dma_port_cfg(
473  		 isys_cfg,
474  		 false,
475  		 metadata,
476  		 &channel_cfg->dma_src_port_cfg);
477  	if (!rc)
478  		return false;
479  
480  	rc = calculate_isys2401_dma_port_cfg(
481  		 isys_cfg,
482  		 isys_cfg->raw_packed,
483  		 metadata,
484  		 &channel_cfg->dma_dest_port_cfg);
485  	if (!rc)
486  		return false;
487  
488  	return true;
489  }
490  
calculate_input_system_input_port_cfg(input_system_channel_t * channel,input_system_input_port_t * input_port,isp2401_input_system_cfg_t * isys_cfg,input_system_input_port_cfg_t * input_port_cfg)491  static bool calculate_input_system_input_port_cfg(
492      input_system_channel_t		*channel,
493      input_system_input_port_t	*input_port,
494      isp2401_input_system_cfg_t		*isys_cfg,
495      input_system_input_port_cfg_t	*input_port_cfg)
496  {
497  	bool rc;
498  
499  	switch (input_port->source_type) {
500  	case INPUT_SYSTEM_SOURCE_TYPE_SENSOR:
501  		rc  = calculate_fe_cfg(
502  			  isys_cfg,
503  			  &input_port_cfg->csi_rx_cfg.frontend_cfg);
504  
505  		rc &= calculate_be_cfg(
506  			  input_port,
507  			  isys_cfg,
508  			  false,
509  			  &input_port_cfg->csi_rx_cfg.backend_cfg);
510  
511  		if (rc && isys_cfg->metadata.enable)
512  			rc &= calculate_be_cfg(input_port, isys_cfg, true,
513  					       &input_port_cfg->csi_rx_cfg.md_backend_cfg);
514  		break;
515  	case INPUT_SYSTEM_SOURCE_TYPE_PRBS:
516  		rc = calculate_prbs_cfg(
517  			 channel,
518  			 input_port,
519  			 isys_cfg,
520  			 &input_port_cfg->pixelgen_cfg.prbs_cfg);
521  		break;
522  	default:
523  		rc = false;
524  		break;
525  	}
526  
527  	return rc;
528  }
529  
acquire_sid(stream2mmio_ID_t stream2mmio,stream2mmio_sid_ID_t * sid)530  static bool acquire_sid(
531      stream2mmio_ID_t	stream2mmio,
532      stream2mmio_sid_ID_t	*sid)
533  {
534  	return ia_css_isys_stream2mmio_sid_rmgr_acquire(stream2mmio, sid);
535  }
536  
release_sid(stream2mmio_ID_t stream2mmio,stream2mmio_sid_ID_t * sid)537  static void release_sid(
538      stream2mmio_ID_t	stream2mmio,
539      stream2mmio_sid_ID_t	*sid)
540  {
541  	ia_css_isys_stream2mmio_sid_rmgr_release(stream2mmio, sid);
542  }
543  
544  /* See also: ia_css_dma_configure_from_info() */
calculate_stride(s32 bits_per_pixel,s32 pixels_per_line,bool raw_packed,int32_t align_in_bytes)545  static int32_t calculate_stride(
546      s32 bits_per_pixel,
547      s32 pixels_per_line,
548      bool	raw_packed,
549      int32_t align_in_bytes)
550  {
551  	s32 bytes_per_line;
552  	s32 pixels_per_word;
553  	s32 words_per_line;
554  	s32 pixels_per_line_padded;
555  
556  	pixels_per_line_padded = CEIL_MUL(pixels_per_line, align_in_bytes);
557  
558  	if (!raw_packed)
559  		bits_per_pixel = CEIL_MUL(bits_per_pixel, 8);
560  
561  	pixels_per_word = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
562  	words_per_line  = DIV_ROUND_UP(pixels_per_line_padded, pixels_per_word);
563  	bytes_per_line  = HIVE_ISP_DDR_WORD_BYTES * words_per_line;
564  
565  	return bytes_per_line;
566  }
567  
acquire_ib_buffer(s32 bits_per_pixel,s32 pixels_per_line,s32 lines_per_frame,s32 align_in_bytes,bool online,isp2401_ib_buffer_t * buf)568  static bool acquire_ib_buffer(
569      s32 bits_per_pixel,
570      s32 pixels_per_line,
571      s32 lines_per_frame,
572      s32 align_in_bytes,
573      bool online,
574      isp2401_ib_buffer_t *buf)
575  {
576  	buf->stride = calculate_stride(bits_per_pixel, pixels_per_line, false,
577  				       align_in_bytes);
578  	if (online)
579  		buf->lines = 4; /* use double buffering for online usecases */
580  	else
581  		buf->lines = 2;
582  
583  	(void)(lines_per_frame);
584  	return ia_css_isys_ibuf_rmgr_acquire(buf->stride * buf->lines,
585  					     &buf->start_addr);
586  }
587  
release_ib_buffer(isp2401_ib_buffer_t * buf)588  static void release_ib_buffer(
589      isp2401_ib_buffer_t *buf)
590  {
591  	ia_css_isys_ibuf_rmgr_release(&buf->start_addr);
592  }
593  
acquire_dma_channel(isys2401_dma_ID_t dma_id,isys2401_dma_channel * channel)594  static bool acquire_dma_channel(
595      isys2401_dma_ID_t	dma_id,
596      isys2401_dma_channel	*channel)
597  {
598  	return ia_css_isys_dma_channel_rmgr_acquire(dma_id, channel);
599  }
600  
release_dma_channel(isys2401_dma_ID_t dma_id,isys2401_dma_channel * channel)601  static void release_dma_channel(
602      isys2401_dma_ID_t	dma_id,
603      isys2401_dma_channel	*channel)
604  {
605  	ia_css_isys_dma_channel_rmgr_release(dma_id, channel);
606  }
607  
acquire_be_lut_entry(csi_rx_backend_ID_t backend,csi_mipi_packet_type_t packet_type,csi_rx_backend_lut_entry_t * entry)608  static bool acquire_be_lut_entry(
609      csi_rx_backend_ID_t		backend,
610      csi_mipi_packet_type_t		packet_type,
611      csi_rx_backend_lut_entry_t	*entry)
612  {
613  	return ia_css_isys_csi_rx_lut_rmgr_acquire(backend, packet_type, entry);
614  }
615  
release_be_lut_entry(csi_rx_backend_ID_t backend,csi_mipi_packet_type_t packet_type,csi_rx_backend_lut_entry_t * entry)616  static void release_be_lut_entry(
617      csi_rx_backend_ID_t		backend,
618      csi_mipi_packet_type_t		packet_type,
619      csi_rx_backend_lut_entry_t	*entry)
620  {
621  	ia_css_isys_csi_rx_lut_rmgr_release(backend, packet_type, entry);
622  }
623  
calculate_prbs_cfg(input_system_channel_t * channel,input_system_input_port_t * input_port,isp2401_input_system_cfg_t * isys_cfg,pixelgen_prbs_cfg_t * cfg)624  static bool calculate_prbs_cfg(
625      input_system_channel_t		*channel,
626      input_system_input_port_t	*input_port,
627      isp2401_input_system_cfg_t		*isys_cfg,
628      pixelgen_prbs_cfg_t		*cfg)
629  {
630  	memcpy(cfg, &isys_cfg->prbs_port_attr, sizeof(pixelgen_prbs_cfg_t));
631  
632  	return true;
633  }
634  
calculate_fe_cfg(const isp2401_input_system_cfg_t * isys_cfg,csi_rx_frontend_cfg_t * cfg)635  static bool calculate_fe_cfg(
636      const isp2401_input_system_cfg_t	*isys_cfg,
637      csi_rx_frontend_cfg_t		*cfg)
638  {
639  	cfg->active_lanes = isys_cfg->csi_port_attr.active_lanes;
640  	return true;
641  }
642  
calculate_be_cfg(const input_system_input_port_t * input_port,const isp2401_input_system_cfg_t * isys_cfg,bool metadata,csi_rx_backend_cfg_t * cfg)643  static bool calculate_be_cfg(
644      const input_system_input_port_t	*input_port,
645      const isp2401_input_system_cfg_t	*isys_cfg,
646      bool				metadata,
647      csi_rx_backend_cfg_t		*cfg)
648  {
649  	memcpy(&cfg->lut_entry,
650  	      metadata ? &input_port->metadata.backend_lut_entry :
651  			 &input_port->csi_rx.backend_lut_entry,
652  	      sizeof(csi_rx_backend_lut_entry_t));
653  
654  	cfg->csi_mipi_cfg.virtual_channel = isys_cfg->csi_port_attr.ch_id;
655  	if (metadata) {
656  		cfg->csi_mipi_packet_type = get_csi_mipi_packet_type(
657  						isys_cfg->metadata.fmt_type);
658  		cfg->csi_mipi_cfg.comp_enable = false;
659  		cfg->csi_mipi_cfg.data_type = isys_cfg->metadata.fmt_type;
660  	} else {
661  		cfg->csi_mipi_packet_type = get_csi_mipi_packet_type(
662  						isys_cfg->csi_port_attr.fmt_type);
663  		cfg->csi_mipi_cfg.data_type = isys_cfg->csi_port_attr.fmt_type;
664  		cfg->csi_mipi_cfg.comp_enable = isys_cfg->csi_port_attr.comp_enable;
665  		cfg->csi_mipi_cfg.comp_scheme = isys_cfg->csi_port_attr.comp_scheme;
666  		cfg->csi_mipi_cfg.comp_predictor = isys_cfg->csi_port_attr.comp_predictor;
667  		cfg->csi_mipi_cfg.comp_bit_idx = cfg->csi_mipi_cfg.data_type -
668  						 MIPI_FORMAT_2401_CUSTOM0;
669  	}
670  
671  	return true;
672  }
673  
calculate_stream2mmio_cfg(const isp2401_input_system_cfg_t * isys_cfg,bool metadata,stream2mmio_cfg_t * cfg)674  static bool calculate_stream2mmio_cfg(
675      const isp2401_input_system_cfg_t	*isys_cfg,
676      bool				metadata,
677      stream2mmio_cfg_t		*cfg
678  )
679  {
680  	cfg->bits_per_pixel = metadata ? isys_cfg->metadata.bits_per_pixel :
681  			      isys_cfg->input_port_resolution.bits_per_pixel;
682  
683  	cfg->enable_blocking = isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS;
684  
685  	return true;
686  }
687  
calculate_ibuf_ctrl_cfg(const input_system_channel_t * channel,const input_system_input_port_t * input_port,const isp2401_input_system_cfg_t * isys_cfg,ibuf_ctrl_cfg_t * cfg)688  static bool calculate_ibuf_ctrl_cfg(
689      const input_system_channel_t	*channel,
690      const input_system_input_port_t	*input_port,
691      const isp2401_input_system_cfg_t	*isys_cfg,
692      ibuf_ctrl_cfg_t			*cfg)
693  {
694  	s32 bits_per_pixel;
695  	s32 bytes_per_pixel;
696  	s32 left_padding;
697  
698  	(void)input_port;
699  
700  	bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel;
701  	bytes_per_pixel = BITS_TO_BYTES(bits_per_pixel);
702  
703  	left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS)
704  		       * bytes_per_pixel;
705  
706  	cfg->online	= isys_cfg->online;
707  
708  	cfg->dma_cfg.channel	= channel->dma_channel;
709  	cfg->dma_cfg.cmd	= _DMA_V2_MOVE_A2B_NO_SYNC_CHK_COMMAND;
710  
711  	cfg->dma_cfg.shift_returned_items	= 0;
712  	cfg->dma_cfg.elems_per_word_in_ibuf	= 0;
713  	cfg->dma_cfg.elems_per_word_in_dest	= 0;
714  
715  	cfg->ib_buffer.start_addr		= channel->ib_buffer.start_addr;
716  	cfg->ib_buffer.stride			= channel->ib_buffer.stride;
717  	cfg->ib_buffer.lines			= channel->ib_buffer.lines;
718  
719  	/*
720  	#ifndef ISP2401
721  	 * zhengjie.lu@intel.com:
722  	#endif
723  	 * "dest_buf_cfg" should be part of the input system output
724  	 * port configuration.
725  	 *
726  	 * TODO: move "dest_buf_cfg" to the input system output
727  	 * port configuration.
728  	 */
729  
730  	/* input_buf addr only available in sched mode;
731  	   this buffer is allocated in isp, crun mode addr
732  	   can be passed by after ISP allocation */
733  	if (cfg->online) {
734  		cfg->dest_buf_cfg.start_addr	= ISP_INPUT_BUF_START_ADDR + left_padding;
735  		cfg->dest_buf_cfg.stride	= bytes_per_pixel
736  					      * isys_cfg->output_port_attr.max_isp_input_width;
737  		cfg->dest_buf_cfg.lines		= LINES_OF_ISP_INPUT_BUF;
738  	} else if (isys_cfg->raw_packed) {
739  		cfg->dest_buf_cfg.stride	= calculate_stride(bits_per_pixel,
740  					      isys_cfg->input_port_resolution.pixels_per_line,
741  					      isys_cfg->raw_packed,
742  					      isys_cfg->input_port_resolution.align_req_in_bytes);
743  	} else {
744  		cfg->dest_buf_cfg.stride	= channel->ib_buffer.stride;
745  	}
746  
747  	/*
748  	#ifndef ISP2401
749  	 * zhengjie.lu@intel.com:
750  	#endif
751  	 * "items_per_store" is hard coded as "1", which is ONLY valid
752  	 * when the CSI-MIPI long packet is transferred.
753  	 *
754  	 * TODO: After the 1st stage of MERR+,  make the proper solution to
755  	 * configure "items_per_store" so that it can also handle the CSI-MIPI
756  	 * short packet.
757  	 */
758  	cfg->items_per_store		= 1;
759  
760  	cfg->stores_per_frame		= isys_cfg->input_port_resolution.lines_per_frame;
761  
762  	cfg->stream2mmio_cfg.sync_cmd	= _STREAM2MMIO_CMD_TOKEN_SYNC_FRAME;
763  
764  	/* TODO: Define conditions as when to use store words vs store packets */
765  	cfg->stream2mmio_cfg.store_cmd	= _STREAM2MMIO_CMD_TOKEN_STORE_PACKETS;
766  
767  	return true;
768  }
769  
calculate_isys2401_dma_cfg(const input_system_channel_t * channel,const isp2401_input_system_cfg_t * isys_cfg,isys2401_dma_cfg_t * cfg)770  static bool calculate_isys2401_dma_cfg(
771      const input_system_channel_t	*channel,
772      const isp2401_input_system_cfg_t	*isys_cfg,
773      isys2401_dma_cfg_t		*cfg)
774  {
775  	cfg->channel	= channel->dma_channel;
776  
777  	/* only online/sensor mode goto vmem
778  	   offline/buffered_sensor, tpg and prbs will go to ddr */
779  	if (isys_cfg->online)
780  		cfg->connection = isys2401_dma_ibuf_to_vmem_connection;
781  	else
782  		cfg->connection = isys2401_dma_ibuf_to_ddr_connection;
783  
784  	cfg->extension	= isys2401_dma_zero_extension;
785  	cfg->height	= 1;
786  
787  	return true;
788  }
789  
790  /* See also: ia_css_dma_configure_from_info() */
calculate_isys2401_dma_port_cfg(const isp2401_input_system_cfg_t * isys_cfg,bool raw_packed,bool metadata,isys2401_dma_port_cfg_t * cfg)791  static bool calculate_isys2401_dma_port_cfg(
792      const isp2401_input_system_cfg_t	*isys_cfg,
793      bool				raw_packed,
794      bool				metadata,
795      isys2401_dma_port_cfg_t		*cfg)
796  {
797  	s32 bits_per_pixel;
798  	s32 pixels_per_line;
799  	s32 align_req_in_bytes;
800  
801  	/* TODO: Move metadata away from isys_cfg to application layer */
802  	if (metadata) {
803  		bits_per_pixel = isys_cfg->metadata.bits_per_pixel;
804  		pixels_per_line = isys_cfg->metadata.pixels_per_line;
805  		align_req_in_bytes = isys_cfg->metadata.align_req_in_bytes;
806  	} else {
807  		bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel;
808  		pixels_per_line = isys_cfg->input_port_resolution.pixels_per_line;
809  		align_req_in_bytes = isys_cfg->input_port_resolution.align_req_in_bytes;
810  	}
811  
812  	cfg->stride	= calculate_stride(bits_per_pixel, pixels_per_line, raw_packed,
813  				       align_req_in_bytes);
814  
815  	if (!raw_packed)
816  		bits_per_pixel = CEIL_MUL(bits_per_pixel, 8);
817  
818  	cfg->elements	= HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
819  	cfg->cropping	= 0;
820  	cfg->width	= CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES);
821  
822  	return true;
823  }
824  
get_csi_mipi_packet_type(int32_t data_type)825  static csi_mipi_packet_type_t get_csi_mipi_packet_type(
826      int32_t data_type)
827  {
828  	csi_mipi_packet_type_t packet_type;
829  
830  	packet_type = CSI_MIPI_PACKET_TYPE_RESERVED;
831  
832  	if (data_type >= 0 && data_type <= MIPI_FORMAT_2401_SHORT8)
833  		packet_type = CSI_MIPI_PACKET_TYPE_SHORT;
834  
835  	if (data_type > MIPI_FORMAT_2401_SHORT8 && data_type <= N_MIPI_FORMAT_2401)
836  		packet_type = CSI_MIPI_PACKET_TYPE_LONG;
837  
838  	return packet_type;
839  }
840  
841  /* end of Private Methods */
842