summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/media/uapi/v4l/buffer.rst3
-rw-r--r--Documentation/media/uapi/v4l/dev-meta.rst33
-rw-r--r--Documentation/media/uapi/v4l/meta-formats.rst1
-rw-r--r--Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst178
-rw-r--r--Documentation/media/uapi/v4l/vidioc-querycap.rst3
-rw-r--r--Documentation/media/v4l-drivers/index.rst1
-rw-r--r--Documentation/media/v4l-drivers/ipu3.rst369
-rw-r--r--Documentation/media/videodev2.h.rst.exceptions2
-rw-r--r--MAINTAINERS8
-rw-r--r--drivers/media/common/videobuf2/videobuf2-v4l2.c1
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c12
-rw-r--r--drivers/media/v4l2-core/v4l2-fwnode.c4
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c23
-rw-r--r--drivers/staging/media/Kconfig2
-rw-r--r--drivers/staging/media/Makefile1
-rw-r--r--drivers/staging/media/ipu3/Kconfig14
-rw-r--r--drivers/staging/media/ipu3/Makefile11
-rw-r--r--drivers/staging/media/ipu3/TODO34
-rw-r--r--drivers/staging/media/ipu3/include/intel-ipu3.h2785
-rw-r--r--drivers/staging/media/ipu3/ipu3-abi.h2011
-rw-r--r--drivers/staging/media/ipu3/ipu3-css-fw.c265
-rw-r--r--drivers/staging/media/ipu3/ipu3-css-fw.h188
-rw-r--r--drivers/staging/media/ipu3/ipu3-css-params.c2943
-rw-r--r--drivers/staging/media/ipu3/ipu3-css-params.h28
-rw-r--r--drivers/staging/media/ipu3/ipu3-css-pool.c100
-rw-r--r--drivers/staging/media/ipu3/ipu3-css-pool.h55
-rw-r--r--drivers/staging/media/ipu3/ipu3-css.c2391
-rw-r--r--drivers/staging/media/ipu3/ipu3-css.h213
-rw-r--r--drivers/staging/media/ipu3/ipu3-dmamap.c270
-rw-r--r--drivers/staging/media/ipu3/ipu3-dmamap.h22
-rw-r--r--drivers/staging/media/ipu3/ipu3-mmu.c561
-rw-r--r--drivers/staging/media/ipu3/ipu3-mmu.h35
-rw-r--r--drivers/staging/media/ipu3/ipu3-tables.c9609
-rw-r--r--drivers/staging/media/ipu3/ipu3-tables.h66
-rw-r--r--drivers/staging/media/ipu3/ipu3-v4l2.c1419
-rw-r--r--drivers/staging/media/ipu3/ipu3.c830
-rw-r--r--drivers/staging/media/ipu3/ipu3.h168
-rw-r--r--include/media/v4l2-ioctl.h17
-rw-r--r--include/uapi/linux/videodev2.h2
40 files changed, 24661 insertions, 19 deletions
diff --git a/Documentation/media/uapi/v4l/buffer.rst b/Documentation/media/uapi/v4l/buffer.rst
index c5013adaa44d..86878bb0087f 100644
--- a/Documentation/media/uapi/v4l/buffer.rst
+++ b/Documentation/media/uapi/v4l/buffer.rst
@@ -472,6 +472,9 @@ enum v4l2_buf_type
* - ``V4L2_BUF_TYPE_META_CAPTURE``
- 13
- Buffer for metadata capture, see :ref:`metadata`.
+ * - ``V4L2_BUF_TYPE_META_OUTPUT``
+ - 14
+ - Buffer for metadata output, see :ref:`metadata`.
diff --git a/Documentation/media/uapi/v4l/dev-meta.rst b/Documentation/media/uapi/v4l/dev-meta.rst
index edccb9bd8858..c5dbe882be65 100644
--- a/Documentation/media/uapi/v4l/dev-meta.rst
+++ b/Documentation/media/uapi/v4l/dev-meta.rst
@@ -14,21 +14,27 @@ Metadata Interface
******************
Metadata refers to any non-image data that supplements video frames with
-additional information. This may include statistics computed over the image
-or frame capture parameters supplied by the image source. This interface is
-intended for transfer of metadata to userspace and control of that operation.
+additional information. This may include statistics computed over the image,
+frame capture parameters supplied by the image source or device specific
+parameters for specifying how the device processes images. This interface is
+intended for transfer of metadata between the userspace and the hardware and
+control of that operation.
-The metadata interface is implemented on video capture device nodes. The device
-can be dedicated to metadata or can implement both video and metadata capture
-as specified in its reported capabilities.
+The metadata interface is implemented on video device nodes. The device can be
+dedicated to metadata or can support both video and metadata as specified in its
+reported capabilities.
Querying Capabilities
=====================
-Device nodes supporting the metadata interface set the ``V4L2_CAP_META_CAPTURE``
-flag in the ``device_caps`` field of the
+Device nodes supporting the metadata capture interface set the
+``V4L2_CAP_META_CAPTURE`` flag in the ``device_caps`` field of the
:c:type:`v4l2_capability` structure returned by the :c:func:`VIDIOC_QUERYCAP`
-ioctl. That flag means the device can capture metadata to memory.
+ioctl. That flag means the device can capture metadata to memory. Similarly,
+device nodes supporting metadata output interface set the
+``V4L2_CAP_META_OUTPUT`` flag in the ``device_caps`` field of
+:c:type:`v4l2_capability` structure. That flag means the device can read
+metadata from memory.
At least one of the read/write or streaming I/O methods must be supported.
@@ -42,10 +48,11 @@ to the basic :ref:`format` ioctls, the :c:func:`VIDIOC_ENUM_FMT` ioctl must be
supported as well.
To use the :ref:`format` ioctls applications set the ``type`` field of the
-:c:type:`v4l2_format` structure to ``V4L2_BUF_TYPE_META_CAPTURE`` and use the
-:c:type:`v4l2_meta_format` ``meta`` member of the ``fmt`` union as needed per
-the desired operation. Both drivers and applications must set the remainder of
-the :c:type:`v4l2_format` structure to 0.
+:c:type:`v4l2_format` structure to ``V4L2_BUF_TYPE_META_CAPTURE`` or to
+``V4L2_BUF_TYPE_META_OUTPUT`` and use the :c:type:`v4l2_meta_format` ``meta``
+member of the ``fmt`` union as needed per the desired operation. Both drivers
+and applications must set the remainder of the :c:type:`v4l2_format` structure
+to 0.
.. c:type:: v4l2_meta_format
diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst
index 438bd244bd2f..5f956fa784b7 100644
--- a/Documentation/media/uapi/v4l/meta-formats.rst
+++ b/Documentation/media/uapi/v4l/meta-formats.rst
@@ -19,6 +19,7 @@ These formats are used for the :ref:`metadata` interface only.
.. toctree::
:maxdepth: 1
+ pixfmt-meta-intel-ipu3
pixfmt-meta-d4xx
pixfmt-meta-uvc
pixfmt-meta-vsp1-hgo
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst b/Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst
new file mode 100644
index 000000000000..dc871006b41a
--- /dev/null
+++ b/Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst
@@ -0,0 +1,178 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _v4l2-meta-fmt-params:
+.. _v4l2-meta-fmt-stat-3a:
+
+******************************************************************
+V4L2_META_FMT_IPU3_PARAMS ('ip3p'), V4L2_META_FMT_IPU3_3A ('ip3s')
+******************************************************************
+
+.. c:type:: ipu3_uapi_stats_3a
+
+3A statistics
+=============
+
+For IPU3 ImgU, the 3A statistics accelerators collect different statistics over
+an input bayer frame. Those statistics, defined in data struct :c:type:`ipu3_uapi_stats_3a`,
+are obtained from "ipu3-imgu 3a stat" metadata capture video node, which are then
+passed to user space for statistics analysis using :c:type:`v4l2_meta_format` interface.
+
+The statistics collected are AWB (Auto-white balance) RGBS (Red, Green, Blue and
+Saturation measure) cells, AWB filter response, AF (Auto-focus) filter response,
+and AE (Auto-exposure) histogram.
+
+struct :c:type:`ipu3_uapi_4a_config` saves configurable parameters for all above.
+
+.. code-block:: c
+
+ struct ipu3_uapi_stats_3a {
+ struct ipu3_uapi_awb_raw_buffer awb_raw_buffer;
+ struct ipu3_uapi_ae_raw_buffer_aligned ae_raw_buffer[IPU3_UAPI_MAX_STRIPES];
+ struct ipu3_uapi_af_raw_buffer af_raw_buffer;
+ struct ipu3_uapi_awb_fr_raw_buffer awb_fr_raw_buffer;
+ struct ipu3_uapi_4a_config stats_4a_config;
+ __u32 ae_join_buffers;
+ __u8 padding[28];
+ struct ipu3_uapi_stats_3a_bubble_info_per_stripe stats_3a_bubble_per_stripe;
+ struct ipu3_uapi_ff_status stats_3a_status;
+ };
+
+.. c:type:: ipu3_uapi_params
+
+Pipeline parameters
+===================
+
+IPU3 pipeline has a number of image processing stages, each of which takes a
+set of parameters as input. The major stages of pipelines are shown here:
+
+Raw pixels -> Bayer Downscaling -> Optical Black Correction ->
+
+Linearization -> Lens Shading Correction -> White Balance / Exposure /
+
+Focus Apply -> Bayer Noise Reduction -> ANR -> Demosaicing -> Color
+
+Correction Matrix -> Gamma correction -> Color Space Conversion ->
+
+Chroma Down Scaling -> Chromatic Noise Reduction -> Total Color
+
+Correction -> XNR3 -> TNR -> DDR
+
+The table below presents a description of the above algorithms.
+
+======================== =======================================================
+Name Description
+======================== =======================================================
+Optical Black Correction Optical Black Correction block subtracts a pre-defined
+ value from the respective pixel values to obtain better
+ image quality.
+ Defined in :c:type:`ipu3_uapi_obgrid_param`.
+Linearization This algo block uses linearization parameters to
+ address non-linearity sensor effects. The Lookup table
+ table is defined in
+ :c:type:`ipu3_uapi_isp_lin_vmem_params`.
+SHD Lens shading correction is used to correct spatial
+ non-uniformity of the pixel response due to optical
+ lens shading. This is done by applying a different gain
+ for each pixel. The gain, black level etc are
+ configured in :c:type:`ipu3_uapi_shd_config_static`.
+BNR Bayer noise reduction block removes image noise by
+ applying a bilateral filter.
+ See :c:type:`ipu3_uapi_bnr_static_config` for details.
+ANR Advanced Noise Reduction is a block based algorithm
+ that performs noise reduction in the Bayer domain. The
+ convolution matrix etc can be found in
+ :c:type:`ipu3_uapi_anr_config`.
+Demosaicing Demosaicing converts raw sensor data in Bayer format
+ into RGB (Red, Green, Blue) presentation. Then add
+ outputs of estimation of Y channel for following stream
+ processing by Firmware. The struct is defined as
+ :c:type:`ipu3_uapi_dm_config`. (TODO)
+Color Correction Color Correction algo transforms sensor specific color
+ space to the standard "sRGB" color space. This is done
+ by applying 3x3 matrix defined in
+ :c:type:`ipu3_uapi_ccm_mat_config`.
+Gamma correction Gamma correction :c:type:`ipu3_uapi_gamma_config` is a
+ basic non-linear tone mapping correction that is
+ applied per pixel for each pixel component.
+CSC Color space conversion transforms each pixel from the
+ RGB primary presentation to YUV (Y: brightness,
+ UV: Luminance) presentation. This is done by applying
+ a 3x3 matrix defined in
+ :c:type:`ipu3_uapi_csc_mat_config`
+CDS Chroma down sampling
+ After the CSC is performed, the Chroma Down Sampling
+ is applied for a UV plane down sampling by a factor
+ of 2 in each direction for YUV 4:2:0 using a 4x2
+ configurable filter :c:type:`ipu3_uapi_cds_params`.
+CHNR Chroma noise reduction
+ This block processes only the chrominance pixels and
+ performs noise reduction by cleaning the high
+ frequency noise.
+ See struct :c:type:`ipu3_uapi_yuvp1_chnr_config`.
+TCC Total color correction as defined in struct
+ :c:type:`ipu3_uapi_yuvp2_tcc_static_config`.
+XNR3 eXtreme Noise Reduction V3 is the third revision of
+ noise reduction algorithm used to improve image
+ quality. This removes the low frequency noise in the
+ captured image. Two related structs are being defined,
+ :c:type:`ipu3_uapi_isp_xnr3_params` for ISP data memory
+ and :c:type:`ipu3_uapi_isp_xnr3_vmem_params` for vector
+ memory.
+TNR Temporal Noise Reduction block compares successive
+ frames in time to remove anomalies / noise in pixel
+ values. :c:type:`ipu3_uapi_isp_tnr3_vmem_params` and
+ :c:type:`ipu3_uapi_isp_tnr3_params` are defined for ISP
+ vector and data memory respectively.
+======================== =======================================================
+
+A few stages of the pipeline will be executed by firmware running on the ISP
+processor, while many others will use a set of fixed hardware blocks also
+called accelerator cluster (ACC) to crunch pixel data and produce statistics.
+
+ACC parameters of individual algorithms, as defined by
+:c:type:`ipu3_uapi_acc_param`, can be chosen to be applied by the user
+space through struct :c:type:`ipu3_uapi_flags` embedded in
+:c:type:`ipu3_uapi_params` structure. For parameters that are configured as
+not enabled by the user space, the corresponding structs are ignored by the
+driver, in which case the existing configuration of the algorithm will be
+preserved.
+
+Both 3A statistics and pipeline parameters described here are closely tied to
+the underlying camera sub-system (CSS) APIs. They are usually consumed and
+produced by dedicated user space libraries that comprise the important tuning
+tools, thus freeing the developers from being bothered with the low level
+hardware and algorithm details.
+
+It should be noted that IPU3 DMA operations require the addresses of all data
+structures (that includes both input and output) to be aligned on 32 byte
+boundaries.
+
+The meta data :c:type:`ipu3_uapi_params` will be sent to "ipu3-imgu parameters"
+video node in ``V4L2_BUF_TYPE_META_CAPTURE`` format.
+
+.. code-block:: c
+
+ struct ipu3_uapi_params {
+ /* Flags which of the settings below are to be applied */
+ struct ipu3_uapi_flags use;
+
+ /* Accelerator cluster parameters */
+ struct ipu3_uapi_acc_param acc_param;
+
+ /* ISP vector address space parameters */
+ struct ipu3_uapi_isp_lin_vmem_params lin_vmem_params;
+ struct ipu3_uapi_isp_tnr3_vmem_params tnr3_vmem_params;
+ struct ipu3_uapi_isp_xnr3_vmem_params xnr3_vmem_params;
+
+ /* ISP data memory (DMEM) parameters */
+ struct ipu3_uapi_isp_tnr3_params tnr3_dmem_params;
+ struct ipu3_uapi_isp_xnr3_params xnr3_dmem_params;
+
+ /* Optical black level compensation */
+ struct ipu3_uapi_obgrid_param obgrid_param;
+ };
+
+Intel IPU3 ImgU uAPI data types
+===============================
+
+.. kernel-doc:: drivers/staging/media/ipu3/include/intel-ipu3.h
diff --git a/Documentation/media/uapi/v4l/vidioc-querycap.rst b/Documentation/media/uapi/v4l/vidioc-querycap.rst
index 0c7bc9568453..5f9930195d62 100644
--- a/Documentation/media/uapi/v4l/vidioc-querycap.rst
+++ b/Documentation/media/uapi/v4l/vidioc-querycap.rst
@@ -258,6 +258,9 @@ specification the ioctl returns an ``EINVAL`` error code.
* - ``V4L2_CAP_STREAMING``
- 0x04000000
- The device supports the :ref:`streaming <mmap>` I/O method.
+ * - ``V4L2_CAP_META_OUTPUT``
+ - 0x08000000
+ - The device supports the :ref:`metadata` output interface.
* - ``V4L2_CAP_TOUCH``
- 0x10000000
- This is a touch device.
diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst
index 6cdd3bc98202..f28570ec9e42 100644
--- a/Documentation/media/v4l-drivers/index.rst
+++ b/Documentation/media/v4l-drivers/index.rst
@@ -44,6 +44,7 @@ For more details see the file COPYING in the source distribution of Linux.
davinci-vpbe
fimc
imx
+ ipu3
ivtv
max2175
meye
diff --git a/Documentation/media/v4l-drivers/ipu3.rst b/Documentation/media/v4l-drivers/ipu3.rst
new file mode 100644
index 000000000000..f89b51dafadd
--- /dev/null
+++ b/Documentation/media/v4l-drivers/ipu3.rst
@@ -0,0 +1,369 @@
+.. include:: <isonum.txt>
+
+===============================================================
+Intel Image Processing Unit 3 (IPU3) Imaging Unit (ImgU) driver
+===============================================================
+
+Copyright |copy| 2018 Intel Corporation
+
+Introduction
+============
+
+This file documents the Intel IPU3 (3rd generation Image Processing Unit)
+Imaging Unit drivers located under drivers/media/pci/intel/ipu3 (CIO2) as well
+as under drivers/staging/media/ipu3 (ImgU).
+
+The Intel IPU3 found in certain Kaby Lake (as well as certain Sky Lake)
+platforms (U/Y processor lines) is made up of two parts namely the Imaging Unit
+(ImgU) and the CIO2 device (MIPI CSI2 receiver).
+
+The CIO2 device receives the raw Bayer data from the sensors and outputs the
+frames in a format that is specific to the IPU3 (for consumption by the IPU3
+ImgU). The CIO2 driver is available as drivers/media/pci/intel/ipu3/ipu3-cio2*
+and is enabled through the CONFIG_VIDEO_IPU3_CIO2 config option.
+
+The Imaging Unit (ImgU) is responsible for processing images captured
+by the IPU3 CIO2 device. The ImgU driver sources can be found under
+drivers/staging/media/ipu3 directory. The driver is enabled through the
+CONFIG_VIDEO_IPU3_IMGU config option.
+
+The two driver modules are named ipu3_csi2 and ipu3_imgu, respectively.
+
+The drivers has been tested on Kaby Lake platforms (U/Y processor lines).
+
+Both of the drivers implement V4L2, Media Controller and V4L2 sub-device
+interfaces. The IPU3 CIO2 driver supports camera sensors connected to the CIO2
+MIPI CSI-2 interfaces through V4L2 sub-device sensor drivers.
+
+CIO2
+====
+
+The CIO2 is represented as a single V4L2 subdev, which provides a V4L2 subdev
+interface to the user space. There is a video node for each CSI-2 receiver,
+with a single media controller interface for the entire device.
+
+The CIO2 contains four independent capture channel, each with its own MIPI CSI-2
+receiver and DMA engine. Each channel is modelled as a V4L2 sub-device exposed
+to userspace as a V4L2 sub-device node and has two pads:
+
+.. tabularcolumns:: |p{0.8cm}|p{4.0cm}|p{4.0cm}|
+
+.. flat-table::
+
+ * - pad
+ - direction
+ - purpose
+
+ * - 0
+ - sink
+ - MIPI CSI-2 input, connected to the sensor subdev
+
+ * - 1
+ - source
+ - Raw video capture, connected to the V4L2 video interface
+
+The V4L2 video interfaces model the DMA engines. They are exposed to userspace
+as V4L2 video device nodes.
+
+Capturing frames in raw Bayer format
+------------------------------------
+
+CIO2 MIPI CSI2 receiver is used to capture frames (in packed raw Bayer format)
+from the raw sensors connected to the CSI2 ports. The captured frames are used
+as input to the ImgU driver.
+
+Image processing using IPU3 ImgU requires tools such as raw2pnm [#f1]_, and
+yavta [#f2]_ due to the following unique requirements and / or features specific
+to IPU3.
+
+-- The IPU3 CSI2 receiver outputs the captured frames from the sensor in packed
+raw Bayer format that is specific to IPU3.
+
+-- Multiple video nodes have to be operated simultaneously.
+
+Let us take the example of ov5670 sensor connected to CSI2 port 0, for a
+2592x1944 image capture.
+
+Using the media contorller APIs, the ov5670 sensor is configured to send
+frames in packed raw Bayer format to IPU3 CSI2 receiver.
+
+# This example assumes /dev/media0 as the CIO2 media device
+
+export MDEV=/dev/media0
+
+# and that ov5670 sensor is connected to i2c bus 10 with address 0x36
+
+export SDEV=$(media-ctl -d $MDEV -e "ov5670 10-0036")
+
+# Establish the link for the media devices using media-ctl [#f3]_
+media-ctl -d $MDEV -l "ov5670:0 -> ipu3-csi2 0:0[1]"
+
+# Set the format for the media devices
+media-ctl -d $MDEV -V "ov5670:0 [fmt:SGRBG10/2592x1944]"
+
+media-ctl -d $MDEV -V "ipu3-csi2 0:0 [fmt:SGRBG10/2592x1944]"
+
+media-ctl -d $MDEV -V "ipu3-csi2 0:1 [fmt:SGRBG10/2592x1944]"
+
+Once the media pipeline is configured, desired sensor specific settings
+(such as exposure and gain settings) can be set, using the yavta tool.
+
+e.g
+
+yavta -w 0x009e0903 444 $SDEV
+
+yavta -w 0x009e0913 1024 $SDEV
+
+yavta -w 0x009e0911 2046 $SDEV
+
+Once the desired sensor settings are set, frame captures can be done as below.
+
+e.g
+
+yavta --data-prefix -u -c10 -n5 -I -s2592x1944 --file=/tmp/frame-#.bin \
+ -f IPU3_SGRBG10 $(media-ctl -d $MDEV -e "ipu3-cio2 0")
+
+With the above command, 10 frames are captured at 2592x1944 resolution, with
+sGRBG10 format and output as IPU3_SGRBG10 format.
+
+The captured frames are available as /tmp/frame-#.bin files.
+
+ImgU
+====
+
+The ImgU is represented as two V4L2 subdevs, each of which provides a V4L2
+subdev interface to the user space.
+
+Each V4L2 subdev represents a pipe, which can support a maximum of 2 streams.
+This helps to support advanced camera features like Continuous View Finder (CVF)
+and Snapshot During Video(SDV).
+
+The ImgU contains two independent pipes, each modelled as a V4L2 sub-device
+exposed to userspace as a V4L2 sub-device node.
+
+Each pipe has two sink pads and three source pads for the following purpose:
+
+.. tabularcolumns:: |p{0.8cm}|p{4.0cm}|p{4.0cm}|
+
+.. flat-table::
+
+ * - pad
+ - direction
+ - purpose
+
+ * - 0
+ - sink
+ - Input raw video stream
+
+ * - 1
+ - sink
+ - Processing parameters
+
+ * - 2
+ - source
+ - Output processed video stream
+
+ * - 3
+ - source
+ - Output viewfinder video stream
+
+ * - 4
+ - source
+ - 3A statistics
+
+Each pad is connected to a corresponding V4L2 video interface, exposed to
+userspace as a V4L2 video device node.
+
+Device operation
+----------------
+
+With ImgU, once the input video node ("ipu3-imgu 0/1":0, in
+<entity>:<pad-number> format) is queued with buffer (in packed raw Bayer
+format), ImgU starts processing the buffer and produces the video output in YUV
+format and statistics output on respective output nodes. The driver is expected
+to have buffers ready for all of parameter, output and statistics nodes, when
+input video node is queued with buffer.
+
+At a minimum, all of input, main output, 3A statistics and viewfinder
+video nodes should be enabled for IPU3 to start image processing.
+
+Each ImgU V4L2 subdev has the following set of video nodes.
+
+input, output and viewfinder video nodes
+----------------------------------------
+
+The frames (in packed raw Bayer format specific to the IPU3) received by the
+input video node is processed by the IPU3 Imaging Unit and are output to 2 video
+nodes, with each targeting a different purpose (main output and viewfinder
+output).
+
+Details onand the Bayer format specific to the IPU3 can be found in
+:ref:`v4l2-pix-fmt-ipu3-sbggr10`.
+
+The driver supports V4L2 Video Capture Interface as defined at :ref:`devices`.
+
+Only the multi-planar API is supported. More details can be found at
+:ref:`planar-apis`.
+
+Parameters video node
+---------------------
+
+The parameters video node receives the ImgU algorithm parameters that are used
+to configure how the ImgU algorithms process the image.
+
+Details on processing parameters specific to the IPU3 can be found in
+:ref:`v4l2-meta-fmt-params`.
+
+3A statistics video node
+------------------------
+
+3A statistics video node is used by the ImgU driver to output the 3A (auto
+focus, auto exposure and auto white balance) statistics for the frames that are
+being processed by the ImgU to user space applications. User space applications
+can use this statistics data to compute the desired algorithm parameters for
+the ImgU.
+
+Configuring the Intel IPU3
+==========================
+
+The IPU3 ImgU pipelines can be configured using the Media Controller, defined at
+:ref:`media_controller`.
+
+Firmware binary selection
+-------------------------
+
+The firmware binary is selected using the V4L2_CID_INTEL_IPU3_MODE, currently
+defined in drivers/staging/media/ipu3/include/intel-ipu3.h . "VIDEO" and "STILL"
+modes are available.
+
+Processing the image in raw Bayer format
+----------------------------------------
+
+Configuring ImgU V4L2 subdev for image processing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ImgU V4L2 subdevs have to be configured with media controller APIs to have
+all the video nodes setup correctly.
+
+Let us take "ipu3-imgu 0" subdev as an example.
+
+media-ctl -d $MDEV -r
+
+media-ctl -d $MDEV -l "ipu3-imgu 0 input":0 -> "ipu3-imgu 0":0[1]
+
+media-ctl -d $MDEV -l "ipu3-imgu 0":2 -> "ipu3-imgu 0 output":0[1]
+
+media-ctl -d $MDEV -l "ipu3-imgu 0":3 -> "ipu3-imgu 0 viewfinder":0[1]
+
+media-ctl -d $MDEV -l "ipu3-imgu 0":4 -> "ipu3-imgu 0 3a stat":0[1]
+
+Also the pipe mode of the corresponding V4L2 subdev should be set as desired
+(e.g 0 for video mode or 1 for still mode) through the control id 0x009819a1 as
+below.
+
+yavta -w "0x009819A1 1" /dev/v4l-subdev7
+
+RAW Bayer frames go through the following ImgU pipeline HW blocks to have the
+processed image output to the DDR memory.
+
+RAW Bayer frame -> Input Feeder -> Bayer Down Scaling (BDS) -> Geometric
+Distortion Correction (GDC) -> DDR
+
+The ImgU V4L2 subdev has to be configured with the supported resolutions in all
+the above HW blocks, for a given input resolution.
+
+For a given supported resolution for an input frame, the Input Feeder, Bayer
+Down Scaling and GDC blocks should be configured with the supported resolutions.
+This information can be obtained by looking at the following IPU3 ImgU
+configuration table.
+
+https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/master
+
+Under baseboard-poppy/media-libs/cros-camera-hal-configs-poppy/files/gcss
+directory, graph_settings_ov5670.xml can be used as an example.
+
+The following steps prepare the ImgU pipeline for the image processing.
+
+1. The ImgU V4L2 subdev data format should be set by using the
+VIDIOC_SUBDEV_S_FMT on pad 0, using the GDC width and height obtained above.
+
+2. The ImgU V4L2 subdev cropping should be set by using the
+VIDIOC_SUBDEV_S_SELECTION on pad 0, with V4L2_SEL_TGT_CROP as the target,
+using the input feeder height and width.
+
+3. The ImgU V4L2 subdev composing should be set by using the
+VIDIOC_SUBDEV_S_SELECTION on pad 0, with V4L2_SEL_TGT_COMPOSE as the target,
+using the BDS height and width.
+
+For the ov5670 example, for an input frame with a resolution of 2592x1944
+(which is input to the ImgU subdev pad 0), the corresponding resolutions
+for input feeder, BDS and GDC are 2592x1944, 2592x1944 and 2560x1920
+respectively.
+
+Once this is done, the received raw Bayer frames can be input to the ImgU
+V4L2 subdev as below, using the open source application v4l2n [#f1]_.
+
+For an image captured with 2592x1944 [#f4]_ resolution, with desired output
+resolution as 2560x1920 and viewfinder resolution as 2560x1920, the following
+v4l2n command can be used. This helps process the raw Bayer frames and produces
+the desired results for the main output image and the viewfinder output, in NV12
+format.
+
+v4l2n --pipe=4 --load=/tmp/frame-#.bin --open=/dev/video4
+--fmt=type:VIDEO_OUTPUT_MPLANE,width=2592,height=1944,pixelformat=0X47337069
+--reqbufs=type:VIDEO_OUTPUT_MPLANE,count:1 --pipe=1 --output=/tmp/frames.out
+--open=/dev/video5
+--fmt=type:VIDEO_CAPTURE_MPLANE,width=2560,height=1920,pixelformat=NV12
+--reqbufs=type:VIDEO_CAPTURE_MPLANE,count:1 --pipe=2 --output=/tmp/frames.vf
+--open=/dev/video6
+--fmt=type:VIDEO_CAPTURE_MPLANE,width=2560,height=1920,pixelformat=NV12
+--reqbufs=type:VIDEO_CAPTURE_MPLANE,count:1 --pipe=3 --open=/dev/video7
+--output=/tmp/frames.3A --fmt=type:META_CAPTURE,?
+--reqbufs=count:1,type:META_CAPTURE --pipe=1,2,3,4 --stream=5
+
+where /dev/video4, /dev/video5, /dev/video6 and /dev/video7 devices point to
+input, output, viewfinder and 3A statistics video nodes respectively.
+
+Converting the raw Bayer image into YUV domain
+----------------------------------------------
+
+The processed images after the above step, can be converted to YUV domain
+as below.
+
+Main output frames
+~~~~~~~~~~~~~~~~~~
+
+raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.out /tmp/frames.out.ppm
+
+where 2560x1920 is output resolution, NV12 is the video format, followed
+by input frame and output PNM file.
+
+Viewfinder output frames
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+raw2pnm -x2560 -y1920 -fNV12 /tmp/frames.vf /tmp/frames.vf.ppm
+
+where 2560x1920 is output resolution, NV12 is the video format, followed
+by input frame and output PNM file.
+
+Example user space code for IPU3
+================================
+
+User space code that configures and uses IPU3 is available here.
+
+https://chromium.googlesource.com/chromiumos/platform/arc-camera/+/master/
+
+The source can be located under hal/intel directory.
+
+References
+==========
+
+.. [#f5] include/uapi/linux/intel-ipu3.h
+
+.. [#f1] https://github.com/intel/nvt
+
+.. [#f2] http://git.ideasonboard.org/yavta.git
+
+.. [#f3] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
+
+.. [#f4] ImgU limitation requires an additional 16x16 for all input resolutions
diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
index 4c4bcba0f307..64d348e67df9 100644
--- a/Documentation/media/videodev2.h.rst.exceptions
+++ b/Documentation/media/videodev2.h.rst.exceptions
@@ -30,6 +30,7 @@ replace symbol V4L2_FIELD_TOP :c:type:`v4l2_field`
# Documented enum v4l2_buf_type
replace symbol V4L2_BUF_TYPE_META_CAPTURE :c:type:`v4l2_buf_type`
+replace symbol V4L2_BUF_TYPE_META_OUTPUT :c:type:`v4l2_buf_type`
replace symbol V4L2_BUF_TYPE_SDR_CAPTURE :c:type:`v4l2_buf_type`
replace symbol V4L2_BUF_TYPE_SDR_OUTPUT :c:type:`v4l2_buf_type`
replace symbol V4L2_BUF_TYPE_SLICED_VBI_CAPTURE :c:type:`v4l2_buf_type`
@@ -163,6 +164,7 @@ replace define V4L2_CAP_META_CAPTURE device-capabilities
replace define V4L2_CAP_READWRITE device-capabilities
replace define V4L2_CAP_ASYNCIO device-capabilities
replace define V4L2_CAP_STREAMING device-capabilities
+replace define V4L2_CAP_META_OUTPUT device-capabilities
replace define V4L2_CAP_DEVICE_CAPS device-capabilities
replace define V4L2_CAP_TOUCH device-capabilities
diff --git a/MAINTAINERS b/MAINTAINERS
index e48ad31987ed..e3bf2cbeba04 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7645,6 +7645,14 @@ S: Maintained
F: drivers/media/pci/intel/ipu3/
F: Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
+INTEL IPU3 CSI-2 IMGU DRIVER
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/staging/media/ipu3/
+F: Documentation/media/uapi/v4l/pixfmt-meta-intel-ipu3.rst
+F: Documentation/media/v4l-drivers/ipu3.rst
+
INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
M: Krzysztof Halasa <khalasa@piap.pl>
S: Maintained
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 78a841b83d41..3a0ca2f9854f 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -709,6 +709,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
requested_sizes[0] = f->fmt.sdr.buffersize;
break;
case V4L2_BUF_TYPE_META_CAPTURE:
+ case V4L2_BUF_TYPE_META_OUTPUT:
requested_sizes[0] = f->fmt.meta.buffersize;
break;
default:
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index f4325329fbd6..fe4577a46869 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -323,6 +323,7 @@ static int __get_v4l2_format32(struct v4l2_format __user *p64,
return copy_in_user(&p64->fmt.sdr, &p32->fmt.sdr,
sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_META_CAPTURE:
+ case V4L2_BUF_TYPE_META_OUTPUT:
return copy_in_user(&p64->fmt.meta, &p32->fmt.meta,
sizeof(p64->fmt.meta)) ? -EFAULT : 0;
default:
@@ -392,6 +393,7 @@ static int __put_v4l2_format32(struct v4l2_format __user *p64,
return copy_in_user(&p32->fmt.sdr, &p64->fmt.sdr,
sizeof(p64->fmt.sdr)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_META_CAPTURE:
+ case V4L2_BUF_TYPE_META_OUTPUT:
return copy_in_user(&p32->fmt.meta, &p64->fmt.meta,
sizeof(p64->fmt.meta)) ? -EFAULT : 0;
default:
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 2130e3a0f4da..d7528f82a66a 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -597,7 +597,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_enum_fmt_vid_overlay ||
ops->vidioc_enum_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_enum_fmt_vid_out ||
- ops->vidioc_enum_fmt_vid_out_mplane)))
+ ops->vidioc_enum_fmt_vid_out_mplane ||
+ ops->vidioc_enum_fmt_meta_out)))
set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_g_fmt_vid_cap ||
ops->vidioc_g_fmt_vid_cap_mplane ||
@@ -605,7 +606,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_g_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_g_fmt_vid_out ||
ops->vidioc_g_fmt_vid_out_mplane ||
- ops->vidioc_g_fmt_vid_out_overlay)))
+ ops->vidioc_g_fmt_vid_out_overlay ||
+ ops->vidioc_g_fmt_meta_out)))
set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_s_fmt_vid_cap ||
ops->vidioc_s_fmt_vid_cap_mplane ||
@@ -613,7 +615,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_s_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_s_fmt_vid_out ||
ops->vidioc_s_fmt_vid_out_mplane ||
- ops->vidioc_s_fmt_vid_out_overlay)))
+ ops->vidioc_s_fmt_vid_out_overlay ||
+ ops->vidioc_s_fmt_meta_out)))
set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls);
if ((is_rx && (ops->vidioc_try_fmt_vid_cap ||
ops->vidioc_try_fmt_vid_cap_mplane ||
@@ -621,7 +624,8 @@ static void determine_valid_ioctls(struct video_device *vdev)
ops->vidioc_try_fmt_meta_cap)) ||
(is_tx && (ops->vidioc_try_fmt_vid_out ||
ops->vidioc_try_fmt_vid_out_mplane ||
- ops->vidioc_try_fmt_vid_out_overlay)))
+ ops->vidioc_try_fmt_vid_out_overlay ||
+ ops->vidioc_try_fmt_meta_out)))
set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls);
SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index f0a6c0c6f162..9bfedd7596a1 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -310,8 +310,8 @@ v4l2_fwnode_endpoint_parse_parallel_bus(struct fwnode_handle *fwnode,
}
if (!fwnode_property_read_u32(fwnode, "data-active", &v)) {
- flags &= ~(V4L2_MBUS_PCLK_SAMPLE_RISING |
- V4L2_MBUS_PCLK_SAMPLE_FALLING);
+ flags &= ~(V4L2_MBUS_DATA_ACTIVE_HIGH |
+ V4L2_MBUS_DATA_ACTIVE_LOW);
flags |= v ? V4L2_MBUS_DATA_ACTIVE_HIGH :
V4L2_MBUS_DATA_ACTIVE_LOW;
pr_debug("data-active %s\n", v ? "high" : "low");
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index ef58bc31bfde..1441a73ce64c 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -194,6 +194,7 @@ const char *v4l2_type_names[] = {
[V4L2_BUF_TYPE_SDR_CAPTURE] = "sdr-cap",
[V4L2_BUF_TYPE_SDR_OUTPUT] = "sdr-out",
[V4L2_BUF_TYPE_META_CAPTURE] = "meta-cap",
+ [V4L2_BUF_TYPE_META_OUTPUT] = "meta-out",
};
EXPORT_SYMBOL(v4l2_type_names);
@@ -366,6 +367,7 @@ static void v4l_print_format(const void *arg, bool write_only)
(sdr->pixelformat >> 24) & 0xff);
break;
case V4L2_BUF_TYPE_META_CAPTURE:
+ case V4L2_BUF_TYPE_META_OUTPUT:
meta = &p->fmt.meta;
pr_cont(", dataformat=%c%c%c%c, buffersize=%u\n",
(meta->dataformat >> 0) & 0xff,
@@ -999,6 +1001,10 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap)
return 0;
break;
+ case V4L2_BUF_TYPE_META_OUTPUT:
+ if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out)
+ return 0;
+ break;
default:
break;
}
@@ -1410,6 +1416,11 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
break;
ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
break;
+ case V4L2_BUF_TYPE_META_OUTPUT:
+ if (unlikely(!ops->vidioc_enum_fmt_meta_out))
+ break;
+ ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
+ break;
}
if (ret == 0)
v4l_fill_fmtdesc(p);
@@ -1488,6 +1499,8 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
case V4L2_BUF_TYPE_META_CAPTURE:
return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_META_OUTPUT:
+ return ops->vidioc_g_fmt_meta_out(file, fh, arg);
}
return -EINVAL;
}
@@ -1601,6 +1614,11 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.meta);
return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_META_OUTPUT:
+ if (unlikely(!ops->vidioc_s_fmt_meta_out))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.meta);
+ return ops->vidioc_s_fmt_meta_out(file, fh, arg);
}
return -EINVAL;
}
@@ -1693,6 +1711,11 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
break;
CLEAR_AFTER_FIELD(p, fmt.meta);
return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
+ case V4L2_BUF_TYPE_META_OUTPUT:
+ if (unlikely(!ops->vidioc_try_fmt_meta_out))
+ break;
+ CLEAR_AFTER_FIELD(p, fmt.meta);
+ return ops->vidioc_try_fmt_meta_out(file, fh, arg);
}
return -EINVAL;
}
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index c6f3404dea43..19cadd17e542 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -39,4 +39,6 @@ source "drivers/staging/media/tegra-vde/Kconfig"
source "drivers/staging/media/zoran/Kconfig"
+source "drivers/staging/media/ipu3/Kconfig"
+
endif
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 43c7bee1fc8c..edde1960b030 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_VIDEO_SUNXI) += sunxi/
obj-$(CONFIG_TEGRA_VDE) += tegra-vde/
obj-$(CONFIG_VIDEO_ZORAN) += zoran/
obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip/vpu/
+obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3/
diff --git a/drivers/staging/media/ipu3/Kconfig b/drivers/staging/media/ipu3/Kconfig
new file mode 100644
index 000000000000..75cd889f18f7
--- /dev/null
+++ b/drivers/staging/media/ipu3/Kconfig
@@ -0,0 +1,14 @@
+config VIDEO_IPU3_IMGU
+ tristate "Intel ipu3-imgu driver"
+ depends on PCI && VIDEO_V4L2
+ depends on MEDIA_CONTROLLER && VIDEO_V4L2_SUBDEV_API
+ depends on X86
+ select IOMMU_IOVA
+ select VIDEOBUF2_DMA_SG
+ ---help---
+ This is the Video4Linux2 driver for Intel IPU3 image processing unit,
+ found in Intel Skylake and Kaby Lake SoCs and used for processing
+ images and video.
+
+ Say Y or M here if you have a Skylake/Kaby Lake SoC with a MIPI
+ camera. The module will be called ipu3-imgu.
diff --git a/drivers/staging/media/ipu3/Makefile b/drivers/staging/media/ipu3/Makefile
new file mode 100644
index 000000000000..fb146d178bd4
--- /dev/null
+++ b/drivers/staging/media/ipu3/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the IPU3 ImgU drivers
+#
+
+ipu3-imgu-objs += \
+ ipu3-mmu.o ipu3-dmamap.o \
+ ipu3-tables.o ipu3-css-pool.o \
+ ipu3-css-fw.o ipu3-css-params.o \
+ ipu3-css.o ipu3-v4l2.o ipu3.o
+
+obj-$(CONFIG_VIDEO_IPU3_IMGU) += ipu3-imgu.o
diff --git a/drivers/staging/media/ipu3/TODO b/drivers/staging/media/ipu3/TODO
new file mode 100644
index 000000000000..905bbb190217
--- /dev/null
+++ b/drivers/staging/media/ipu3/TODO
@@ -0,0 +1,34 @@
+This is a list of things that need to be done to get this driver out of the
+staging directory.
+
+- Request API conversion. Remove of the dual pipeline and associate buffers
+ as well as formats and the binary used to a request. Remove the
+ opportunistic buffer management. (Sakari)
+
+- Using ENABLED and IMMUTABLE link flags for the links where those are
+ relevant. (Sakari)
+
+- Prefix imgu for all public APIs, i.e. change ipu3_v4l2_register() to
+ imgu_v4l2_register(). (Sakari)
+
+- Use V4L2_CTRL_TYPE_MENU for dual-pipe mode control. (Sakari)
+
+- IPU3 driver documentation (Laurent)
+ Add diagram in driver rst to describe output capability.
+ Comments on configuring v4l2 subdevs for CIO2 and ImgU.
+
+- uAPI documentation:
+ Further clarification on some ambiguities such as data type conversion of
+ IEFD CU inputs. (Sakari)
+ Move acronyms to doc-rst file. (Mauro)
+
+- Switch to yavta from v4l2n in driver docs.
+
+- Elaborate the functionality of different selection rectangles in driver
+ documentation. This may require driver changes as well.
+
+- More detailed documentation on calculating BDS, GCD etc. sizes needed.
+
+- Document different operation modes, and which buffer queues are relevant
+ in each mode. To process an image, which queues require a buffer an in
+ which ones is it optional?
diff --git a/drivers/staging/media/ipu3/include/intel-ipu3.h b/drivers/staging/media/ipu3/include/intel-ipu3.h
new file mode 100644
index 000000000000..ec0b74829351
--- /dev/null
+++ b/drivers/staging/media/ipu3/include/intel-ipu3.h
@@ -0,0 +1,2785 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2017 - 2018 Intel Corporation */
+
+#ifndef __IPU3_UAPI_H
+#define __IPU3_UAPI_H
+
+#include <linux/types.h>
+
+/* from /drivers/staging/media/ipu3/include/videodev2.h */
+
+/* Vendor specific - used for IPU3 camera sub-system */
+#define V4L2_META_FMT_IPU3_PARAMS v4l2_fourcc('i', 'p', '3', 'p') /* IPU3 processing parameters */
+#define V4L2_META_FMT_IPU3_STAT_3A v4l2_fourcc('i', 'p', '3', 's') /* IPU3 3A statistics */
+
+/* from include/uapi/linux/v4l2-controls.h */
+#define V4L2_CID_INTEL_IPU3_BASE (V4L2_CID_USER_BASE + 0x10c0)
+#define V4L2_CID_INTEL_IPU3_MODE (V4L2_CID_INTEL_IPU3_BASE + 1)
+
+/* custom ctrl to set pipe mode */
+enum ipu3_running_mode {
+ IPU3_RUNNING_MODE_VIDEO = 0,
+ IPU3_RUNNING_MODE_STILL = 1,
+};
+
+/******************* ipu3_uapi_stats_3a *******************/
+
+#define IPU3_UAPI_MAX_STRIPES 2
+#define IPU3_UAPI_MAX_BUBBLE_SIZE 10
+
+#define IPU3_UAPI_GRID_START_MASK ((1 << 12) - 1)
+#define IPU3_UAPI_GRID_Y_START_EN (1 << 15)
+
+/* controls generation of meta_data (like FF enable/disable) */
+#define IPU3_UAPI_AWB_RGBS_THR_B_EN (1 << 14)
+#define IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT (1 << 15)
+
+/**
+ * struct ipu3_uapi_grid_config - Grid plane config
+ *
+ * @width: Grid horizontal dimensions, in number of grid blocks(cells).
+ * @height: Grid vertical dimensions, in number of grid cells.
+ * @block_width_log2: Log2 of the width of each cell in pixels.
+ * for (2^3, 2^4, 2^5, 2^6, 2^7), values [3, 7].
+ * @block_height_log2: Log2 of the height of each cell in pixels.
+ * for (2^3, 2^4, 2^5, 2^6, 2^7), values [3, 7].
+ * @height_per_slice: The number of blocks in vertical axis per slice.
+ * Default 2.
+ * @x_start: X value of top left corner of Region of Interest(ROI).
+ * @y_start: Y value of top left corner of ROI
+ * @x_end: X value of bottom right corner of ROI
+ * @y_end: Y value of bottom right corner of ROI
+ *
+ * Due to the size of total amount of collected data, most statistics
+ * create a grid-based output, and the data is then divided into "slices".
+ */
+struct ipu3_uapi_grid_config {
+ __u8 width;
+ __u8 height;
+ __u16 block_width_log2:3;
+ __u16 block_height_log2:3;
+ __u16 height_per_slice:8;
+ __u16 x_start;
+ __u16 y_start;
+ __u16 x_end;
+ __u16 y_end;
+} __packed;
+
+/*
+ * The grid based data is divided into "slices" called set, each slice of setX
+ * refers to ipu3_uapi_grid_config width * height_per_slice.
+ */
+#define IPU3_UAPI_AWB_MAX_SETS 60
+/* Based on grid size 80 * 60 and cell size 16 x 16 */
+#define IPU3_UAPI_AWB_SET_SIZE 1280
+#define IPU3_UAPI_AWB_MD_ITEM_SIZE 8
+#define IPU3_UAPI_AWB_SPARE_FOR_BUBBLES \
+ (IPU3_UAPI_MAX_BUBBLE_SIZE * IPU3_UAPI_MAX_STRIPES * \
+ IPU3_UAPI_AWB_MD_ITEM_SIZE)
+#define IPU3_UAPI_AWB_MAX_BUFFER_SIZE \
+ (IPU3_UAPI_AWB_MAX_SETS * \
+ (IPU3_UAPI_AWB_SET_SIZE + IPU3_UAPI_AWB_SPARE_FOR_BUBBLES))
+
+
+/**
+ * struct ipu3_uapi_awb_raw_buffer - AWB raw buffer
+ *
+ * @meta_data: buffer to hold auto white balance meta data which is
+ * the average values for each color channel.
+ */
+struct ipu3_uapi_awb_raw_buffer {
+ __u8 meta_data[IPU3_UAPI_AWB_MAX_BUFFER_SIZE]
+ __attribute__((aligned(32)));
+} __packed;
+
+/**
+ * struct ipu3_uapi_awb_config_s - AWB config
+ *
+ * @rgbs_thr_gr: gr threshold value.
+ * @rgbs_thr_r: Red threshold value.
+ * @rgbs_thr_gb: gb threshold value.
+ * @rgbs_thr_b: Blue threshold value.
+ * @grid: &ipu3_uapi_grid_config, the default grid resolution is 16x16 cells.
+ *
+ * The threshold is a saturation measure range [0, 8191], 8191 is default.
+ * Values over threshold may be optionally rejected for averaging.
+ */
+struct ipu3_uapi_awb_config_s {
+ __u16 rgbs_thr_gr;
+ __u16 rgbs_thr_r;
+ __u16 rgbs_thr_gb;
+ __u16 rgbs_thr_b;
+ struct ipu3_uapi_grid_config grid;
+} __attribute__((aligned(32))) __packed;
+
+/**
+ * struct ipu3_uapi_awb_config - AWB config wrapper
+ *
+ * @config: config for auto white balance as defined by &ipu3_uapi_awb_config_s
+ */
+struct ipu3_uapi_awb_config {
+ struct ipu3_uapi_awb_config_s config __attribute__((aligned(32)));
+} __packed;
+
+#define IPU3_UAPI_AE_COLORS 4 /* R, G, B, Y */
+#define IPU3_UAPI_AE_BINS 256
+#define IPU3_UAPI_AE_WEIGHTS 96
+
+/**
+ + * struct ipu3_uapi_ae_raw_buffer - AE global weighted histogram
+ + *
+ + * @vals: Sum of IPU3_UAPI_AE_COLORS in cell
+ + *
+ + * Each histogram contains IPU3_UAPI_AE_BINS bins. Each bin has 24 bit unsigned
+ + * for counting the number of the pixel.
+ + */
+struct ipu3_uapi_ae_raw_buffer {
+ __u32 vals[IPU3_UAPI_AE_BINS * IPU3_UAPI_AE_COLORS];
+} __packed;
+
+/**
+ * struct ipu3_uapi_ae_raw_buffer_aligned - AE raw buffer
+ *
+ * @buff: &ipu3_uapi_ae_raw_buffer to hold full frame meta data.
+ */
+struct ipu3_uapi_ae_raw_buffer_aligned {
+ struct ipu3_uapi_ae_raw_buffer buff __attribute__((aligned(32)));
+} __packed;
+
+/**
+ * struct ipu3_uapi_ae_grid_config - AE weight grid
+ *
+ * @width: Grid horizontal dimensions. Value: [16, 32], default 16.
+ * @height: Grid vertical dimensions. Value: [16, 24], default 16.
+ * @block_width_log2: Log2 of the width of the grid cell, value: [3, 7].
+ * @block_height_log2: Log2 of the height of the grid cell, value: [3, 7].
+ * default is 3 (cell size 8x8), 4 cell per grid.
+ * @reserved0: reserved
+ * @ae_en: 0: does not write to &ipu3_uapi_ae_raw_buffer_aligned array,
+ * 1: write normally.
+ * @rst_hist_array: write 1 to trigger histogram array reset.
+ * @done_rst_hist_array: flag for histogram array reset done.
+ * @x_start: X value of top left corner of ROI, default 0.
+ * @y_start: Y value of top left corner of ROI, default 0.
+ * @x_end: X value of bottom right corner of ROI
+ * @y_end: Y value of bottom right corner of ROI
+ *
+ * The AE block accumulates 4 global weighted histograms(R, G, B, Y) over
+ * a defined ROI within the frame. The contribution of each pixel into the
+ * histogram, defined by &ipu3_uapi_ae_weight_elem LUT, is indexed by a grid.
+ */
+struct ipu3_uapi_ae_grid_config {
+ __u8 width;
+ __u8 height;
+ __u8 block_width_log2:4;
+ __u8 block_height_log2:4;
+ __u8 reserved0:5;
+ __u8 ae_en:1;
+ __u8 rst_hist_array:1;
+ __u8 done_rst_hist_array:1;
+ __u16 x_start;
+ __u16 y_start;
+ __u16 x_end;
+ __u16 y_end;
+} __packed;
+
+/**
+ * struct ipu3_uapi_ae_weight_elem - AE weights LUT
+ *
+ * @cell0: weighted histogram grid value.
+ * @cell1: weighted histogram grid value.
+ * @cell2: weighted histogram grid value.
+ * @cell3: weighted histogram grid value.
+ * @cell4: weighted histogram grid value.
+ * @cell5: weighted histogram grid value.
+ * @cell6: weighted histogram grid value.
+ * @cell7: weighted histogram grid value.
+ *
+ * Use weighted grid value to give a different contribution factor to each cell.
+ * Precision u4, range [0, 15].
+ */
+struct ipu3_uapi_ae_weight_elem {
+ __u32 cell0:4;
+ __u32 cell1:4;
+ __u32 cell2:4;
+ __u32 cell3:4;
+ __u32 cell4:4;
+ __u32 cell5:4;
+ __u32 cell6:4;
+ __u32 cell7:4;
+} __packed;
+
+/**
+ * struct ipu3_uapi_ae_ccm - AE coefficients for WB and CCM
+ *
+ * @gain_gr: WB gain factor for the gr channels. Default 256.
+ * @gain_r: WB gain factor for the r channel. Default 256.
+ * @gain_b: WB gain factor for the b channel. Default 256.
+ * @gain_gb: WB gain factor for the gb channels. Default 256.
+ * @mat: 4x4 matrix that transforms Bayer quad output from WB to RGB+Y.
+ *
+ * Default:
+ * 128, 0, 0, 0,
+ * 0, 128, 0, 0,
+ * 0, 0, 128, 0,
+ * 0, 0, 0, 128,
+ *
+ * As part of the raw frame pre-process stage, the WB and color conversion need
+ * to be applied to expose the impact of these gain operations.
+ */
+struct ipu3_uapi_ae_ccm {
+ __u16 gain_gr;
+ __u16 gain_r;
+ __u16 gain_b;
+ __u16 gain_gb;
+ __s16 mat[16];
+} __packed;
+
+/**
+ * struct ipu3_uapi_ae_config - AE config
+ *
+ * @grid_cfg: config for auto exposure statistics grid. See struct
+ * &ipu3_uapi_ae_grid_config
+ * @weights: &IPU3_UAPI_AE_WEIGHTS is based on 32x24 blocks in the grid.
+ * Each grid cell has a corresponding value in weights LUT called
+ * grid value, global histogram is updated based on grid value and
+ * pixel value.
+ * @ae_ccm: Color convert matrix pre-processing block.
+ *
+ * Calculate AE grid from image resolution, resample ae weights.
+ */
+struct ipu3_uapi_ae_config {
+ struct ipu3_uapi_ae_grid_config grid_cfg __attribute__((aligned(32)));
+ struct ipu3_uapi_ae_weight_elem weights[
+ IPU3_UAPI_AE_WEIGHTS] __attribute__((aligned(32)));
+ struct ipu3_uapi_ae_ccm ae_ccm __attribute__((aligned(32)));
+} __packed;
+
+/**
+ * struct ipu3_uapi_af_filter_config - AF 2D filter for contrast measurements
+ *
+ * @y1_coeff_0: filter Y1, structure: 3x11, support both symmetry and
+ * anti-symmetry type. A12 is center, A1-A11 are neighbours.
+ * for analyzing low frequency content, used to calculate sum
+ * of gradients in x direction.
+ * @y1_coeff_0.a1: filter1 coefficients A1, u8, default 0.
+ * @y1_coeff_0.a2: filter1 coefficients A2, u8, default 0.
+ * @y1_coeff_0.a3: filter1 coefficients A3, u8, default 0.
+ * @y1_coeff_0.a4: filter1 coefficients A4, u8, default 0.
+ * @y1_coeff_1: Struct
+ * @y1_coeff_1.a5: filter1 coefficients A5, u8, default 0.
+ * @y1_coeff_1.a6: filter1 coefficients A6, u8, default 0.
+ * @y1_coeff_1.a7: filter1 coefficients A7, u8, default 0.
+ * @y1_coeff_1.a8: filter1 coefficients A8, u8, default 0.
+ * @y1_coeff_2: Struct
+ * @y1_coeff_2.a9: filter1 coefficients A9, u8, default 0.
+ * @y1_coeff_2.a10: filter1 coefficients A10, u8, default 0.
+ * @y1_coeff_2.a11: filter1 coefficients A11, u8, default 0.
+ * @y1_coeff_2.a12: filter1 coefficients A12, u8, default 128.
+ * @y1_sign_vec: Each bit corresponds to one coefficient sign bit,
+ * 0: positive, 1: negative, default 0.
+ * @y2_coeff_0: Y2, same structure as Y1. For analyzing high frequency content.
+ * @y2_coeff_0.a1: filter2 coefficients A1, u8, default 0.
+ * @y2_coeff_0.a2: filter2 coefficients A2, u8, default 0.
+ * @y2_coeff_0.a3: filter2 coefficients A3, u8, default 0.
+ * @y2_coeff_0.a4: filter2 coefficients A4, u8, default 0.
+ * @y2_coeff_1: Struct
+ * @y2_coeff_1.a5: filter2 coefficients A5, u8, default 0.
+ * @y2_coeff_1.a6: filter2 coefficients A6, u8, default 0.
+ * @y2_coeff_1.a7: filter2 coefficients A7, u8, default 0.
+ * @y2_coeff_1.a8: filter2 coefficients A8, u8, default 0.
+ * @y2_coeff_2: Struct
+ * @y2_coeff_2.a9: filter1 coefficients A9, u8, default 0.
+ * @y2_coeff_2.a10: filter1 coefficients A10, u8, default 0.
+ * @y2_coeff_2.a11: filter1 coefficients A11, u8, default 0.
+ * @y2_coeff_2.a12: filter1 coefficients A12, u8, default 128.
+ * @y2_sign_vec: Each bit corresponds to one coefficient sign bit,
+ * 0: positive, 1: negative, default 0.
+ * @y_calc: Pre-processing that converts Bayer quad to RGB+Y values to be
+ * used for building histogram. Range [0, 32], default 8.
+ * Rule:
+ * y_gen_rate_gr + y_gen_rate_r + y_gen_rate_b + y_gen_rate_gb = 32
+ * A single Y is calculated based on sum of Gr/R/B/Gb based on
+ * their contribution ratio.
+ * @y_calc.y_gen_rate_gr: Contribution ratio Gr for Y
+ * @y_calc.y_gen_rate_r: Contribution ratio R for Y
+ * @y_calc.y_gen_rate_b: Contribution ratio B for Y
+ * @y_calc.y_gen_rate_gb: Contribution ratio Gb for Y
+ * @nf: The shift right value that should be applied during the Y1/Y2 filter to
+ * make sure the total memory needed is 2 bytes per grid cell.
+ * @nf.reserved0: reserved
+ * @nf.y1_nf: Normalization factor for the convolution coeffs of y1,
+ * should be log2 of the sum of the abs values of the filter
+ * coeffs, default 7 (2^7 = 128).
+ * @nf.reserved1: reserved
+ * @nf.y2_nf: Normalization factor for y2, should be log2 of the sum of the
+ * abs values of the filter coeffs.
+ * @nf.reserved2: reserved
+ */
+struct ipu3_uapi_af_filter_config {
+ struct {
+ __u8 a1;
+ __u8 a2;
+ __u8 a3;
+ __u8 a4;
+ } y1_coeff_0;
+ struct {
+ __u8 a5;
+ __u8 a6;
+ __u8 a7;
+ __u8 a8;
+ } y1_coeff_1;
+ struct {
+ __u8 a9;
+ __u8 a10;
+ __u8 a11;
+ __u8 a12;
+ } y1_coeff_2;
+
+ __u32 y1_sign_vec;
+
+ struct {
+ __u8 a1;
+ __u8 a2;
+ __u8 a3;
+ __u8 a4;
+ } y2_coeff_0;
+ struct {
+ __u8 a5;
+ __u8 a6;
+ __u8 a7;
+ __u8 a8;
+ } y2_coeff_1;
+ struct {
+ __u8 a9;
+ __u8 a10;
+ __u8 a11;
+ __u8 a12;
+ } y2_coeff_2;
+
+ __u32 y2_sign_vec;
+
+ struct {
+ __u8 y_gen_rate_gr;
+ __u8 y_gen_rate_r;
+ __u8 y_gen_rate_b;
+ __u8 y_gen_rate_gb;
+ } y_calc;
+
+ struct {
+ __u32 reserved0:8;
+ __u32 y1_nf:4;
+ __u32 reserved1:4;
+ __u32 y2_nf:4;
+ __u32 reserved2:12;
+ } nf;
+} __packed;
+
+#define IPU3_UAPI_AF_MAX_SETS 24
+#define IPU3_UAPI_AF_MD_ITEM_SIZE 4
+#define IPU3_UAPI_AF_SPARE_FOR_BUBBLES \
+ (IPU3_UAPI_MAX_BUBBLE_SIZE * IPU3_UAPI_MAX_STRIPES * \
+ IPU3_UAPI_AF_MD_ITEM_SIZE)
+#define IPU3_UAPI_AF_Y_TABLE_SET_SIZE 128
+#define IPU3_UAPI_AF_Y_TABLE_MAX_SIZE \
+ (IPU3_UAPI_AF_MAX_SETS * \
+ (IPU3_UAPI_AF_Y_TABLE_SET_SIZE + IPU3_UAPI_AF_SPARE_FOR_BUBBLES) * \
+ IPU3_UAPI_MAX_STRIPES)
+
+/**
+ * struct ipu3_uapi_af_raw_buffer - AF meta data
+ *
+ * @y_table: Each color component will be convolved separately with filter1
+ * and filter2 and the result will be summed out and averaged for
+ * each cell.
+ */
+struct ipu3_uapi_af_raw_buffer {
+ __u8 y_table[IPU3_UAPI_AF_Y_TABLE_MAX_SIZE] __attribute__((aligned(32)));
+} __packed;
+
+/**
+ * struct ipu3_uapi_af_config_s - AF config
+ *
+ * @filter_config: AF uses Y1 and Y2 filters as configured in
+ * &ipu3_uapi_af_filter_config
+ * @padding: paddings
+ * @grid_cfg: See &ipu3_uapi_grid_config, default resolution 16x16. Use large
+ * grid size for large image and vice versa.
+ */
+struct ipu3_uapi_af_config_s {
+ struct ipu3_uapi_af_filter_config filter_config __attribute__((aligned(32)));
+ __u8 padding[4];
+ struct ipu3_uapi_grid_config grid_cfg __attribute__((aligned(32)));
+} __packed;
+
+#define IPU3_UAPI_AWB_FR_MAX_SETS 24
+#define IPU3_UAPI_AWB_FR_MD_ITEM_SIZE 8
+#define IPU3_UAPI_AWB_FR_BAYER_TBL_SIZE 256
+#define IPU3_UAPI_AWB_FR_SPARE_FOR_BUBBLES \
+ (IPU3_UAPI_MAX_BUBBLE_SIZE * IPU3_UAPI_MAX_STRIPES * \
+ IPU3_UAPI_AWB_FR_MD_ITEM_SIZE)
+#define IPU3_UAPI_AWB_FR_BAYER_TABLE_MAX_SIZE \
+ (IPU3_UAPI_AWB_FR_MAX_SETS * \
+ (IPU3_UAPI_AWB_FR_BAYER_TBL_SIZE + \
+ IPU3_UAPI_AWB_FR_SPARE_FOR_BUBBLES) * IPU3_UAPI_MAX_STRIPES)
+
+/**
+ * struct ipu3_uapi_awb_fr_meta_data - AWB filter response meta data
+ *
+ * @meta_data: Statistics output on the grid after convolving with 1D filter.
+ */
+struct ipu3_uapi_awb_fr_raw_buffer {
+ __u8 meta_data[IPU3_UAPI_AWB_FR_BAYER_TABLE_MAX_SIZE]
+ __attribute__((aligned(32)));
+} __packed;
+
+/**
+ * struct ipu3_uapi_awb_fr_config_s - AWB filter response config
+ *
+ * @grid_cfg: grid config, default 16x16.
+ * @bayer_coeff: 1D Filter 1x11 center symmetry/anti-symmetry.
+ * coeffcients defaults { 0, 0, 0, 0, 0, 128 }.
+ * Applied on whole image for each Bayer channel separately
+ * by a weighted sum of its 11x1 neighbors.
+ * @reserved1: reserved
+ * @bayer_sign: sign of filter coeffcients, default 0.
+ * @bayer_nf: normalization factor for the convolution coeffs, to make sure
+ * total memory needed is within pre-determined range.
+ * NF should be the log2 of the sum of the abs values of the
+ * filter coeffs, range [7, 14], default 7.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_awb_fr_config_s {
+ struct ipu3_uapi_grid_config grid_cfg;
+ __u8 bayer_coeff[6];
+ __u16 reserved1;
+ __u32 bayer_sign;
+ __u8 bayer_nf;
+ __u8 reserved2[3];
+} __attribute__((aligned(32))) __packed;
+
+/**
+ * struct ipu3_uapi_4a_config - 4A config
+ *
+ * @awb_config: &ipu3_uapi_awb_config_s, default resolution 16x16
+ * @ae_grd_config: auto exposure statistics &ipu3_uapi_ae_grid_config
+ * @padding: paddings
+ * @af_config: auto focus config &ipu3_uapi_af_config_s
+ * @awb_fr_config: &ipu3_uapi_awb_fr_config_s, default resolution 16x16
+ */
+struct ipu3_uapi_4a_config {
+ struct ipu3_uapi_awb_config_s awb_config __attribute__((aligned(32)));
+ struct ipu3_uapi_ae_grid_config ae_grd_config;
+ __u8 padding[20];
+ struct ipu3_uapi_af_config_s af_config;
+ struct ipu3_uapi_awb_fr_config_s awb_fr_config;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bubble_info - Bubble info for host side debugging
+ *
+ * @num_of_stripes: A single frame is divided into several parts called stripes
+ * due to limitation on line buffer memory.
+ * The separation between the stripes is vertical. Each such
+ * stripe is processed as a single frame by the ISP pipe.
+ * @padding: padding bytes.
+ * @num_sets: number of sets.
+ * @padding1: padding bytes.
+ * @size_of_set: set size.
+ * @padding2: padding bytes.
+ * @bubble_size: is the amount of padding in the bubble expressed in "sets".
+ * @padding3: padding bytes.
+ */
+struct ipu3_uapi_bubble_info {
+ __u32 num_of_stripes __attribute__((aligned(32)));
+ __u8 padding[28];
+ __u32 num_sets;
+ __u8 padding1[28];
+ __u32 size_of_set;
+ __u8 padding2[28];
+ __u32 bubble_size;
+ __u8 padding3[28];
+} __packed;
+
+/*
+ * struct ipu3_uapi_stats_3a_bubble_info_per_stripe
+ */
+struct ipu3_uapi_stats_3a_bubble_info_per_stripe {
+ struct ipu3_uapi_bubble_info awb[IPU3_UAPI_MAX_STRIPES];
+ struct ipu3_uapi_bubble_info af[IPU3_UAPI_MAX_STRIPES];
+ struct ipu3_uapi_bubble_info awb_fr[IPU3_UAPI_MAX_STRIPES];
+} __packed;
+
+/**
+ * struct ipu3_uapi_ff_status - Enable bits for each 3A fixed function
+ *
+ * @awb_en: auto white balance enable
+ * @padding: padding config
+ * @ae_en: auto exposure enable
+ * @padding1: padding config
+ * @af_en: auto focus enable
+ * @padding2: padding config
+ * @awb_fr_en: awb filter response enable bit
+ * @padding3: padding config
+ */
+struct ipu3_uapi_ff_status {
+ __u32 awb_en __attribute__((aligned(32)));
+ __u8 padding[28];
+ __u32 ae_en;
+ __u8 padding1[28];
+ __u32 af_en;
+ __u8 padding2[28];
+ __u32 awb_fr_en;
+ __u8 padding3[28];
+} __packed;
+
+/**
+ * struct ipu3_uapi_stats_3a - 3A statistics
+ *
+ * @awb_raw_buffer: auto white balance meta data &ipu3_uapi_awb_raw_buffer
+ * @ae_raw_buffer: auto exposure raw data &ipu3_uapi_ae_raw_buffer_aligned
+ * @af_raw_buffer: &ipu3_uapi_af_raw_buffer for auto focus meta data
+ * @awb_fr_raw_buffer: value as specified by &ipu3_uapi_awb_fr_raw_buffer
+ * @stats_4a_config: 4a statistics config as defined by &ipu3_uapi_4a_config.
+ * @ae_join_buffers: 1 to use ae_raw_buffer.
+ * @padding: padding config
+ * @stats_3a_bubble_per_stripe: a &ipu3_uapi_stats_3a_bubble_info_per_stripe
+ * @stats_3a_status: 3a statistics status set in &ipu3_uapi_ff_status
+ */
+struct ipu3_uapi_stats_3a {
+ struct ipu3_uapi_awb_raw_buffer awb_raw_buffer;
+ struct ipu3_uapi_ae_raw_buffer_aligned
+ ae_raw_buffer[IPU3_UAPI_MAX_STRIPES];
+ struct ipu3_uapi_af_raw_buffer af_raw_buffer;
+ struct ipu3_uapi_awb_fr_raw_buffer awb_fr_raw_buffer;
+ struct ipu3_uapi_4a_config stats_4a_config;
+ __u32 ae_join_buffers;
+ __u8 padding[28];
+ struct ipu3_uapi_stats_3a_bubble_info_per_stripe
+ stats_3a_bubble_per_stripe;
+ struct ipu3_uapi_ff_status stats_3a_status;
+} __packed;
+
+/******************* ipu3_uapi_acc_param *******************/
+
+#define IPU3_UAPI_ISP_VEC_ELEMS 64
+#define IPU3_UAPI_ISP_TNR3_VMEM_LEN 9
+
+#define IPU3_UAPI_BNR_LUT_SIZE 32
+
+/* number of elements in gamma correction LUT */
+#define IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES 256
+
+/* largest grid is 73x56, for grid_height_per_slice of 2, 73x2 = 146 */
+#define IPU3_UAPI_SHD_MAX_CELLS_PER_SET 146
+#define IPU3_UAPI_SHD_MAX_CFG_SETS 28
+/* Normalization shift aka nf */
+#define IPU3_UAPI_SHD_BLGR_NF_SHIFT 13
+#define IPU3_UAPI_SHD_BLGR_NF_MASK 7
+
+#define IPU3_UAPI_YUVP2_TCC_MACC_TABLE_ELEMENTS 16
+#define IPU3_UAPI_YUVP2_TCC_INV_Y_LUT_ELEMENTS 14
+#define IPU3_UAPI_YUVP2_TCC_GAIN_PCWL_LUT_ELEMENTS 258
+#define IPU3_UAPI_YUVP2_TCC_R_SQR_LUT_ELEMENTS 24
+
+#define IPU3_UAPI_ANR_LUT_SIZE 26
+#define IPU3_UAPI_ANR_PYRAMID_SIZE 22
+
+#define IPU3_UAPI_LIN_LUT_SIZE 64
+
+/* Bayer Noise Reduction related structs */
+
+/**
+ * struct ipu3_uapi_bnr_static_config_wb_gains_config - White balance gains
+ *
+ * @gr: white balance gain for Gr channel.
+ * @r: white balance gain for R channel.
+ * @b: white balance gain for B channel.
+ * @gb: white balance gain for Gb channel.
+ *
+ * Precision u3.13, range [0, 8). White balance correction is done by applying
+ * a multiplicative gain to each color channels prior to BNR.
+ */
+struct ipu3_uapi_bnr_static_config_wb_gains_config {
+ __u16 gr;
+ __u16 r;
+ __u16 b;
+ __u16 gb;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_wb_gains_thr_config - Threshold config
+ *
+ * @gr: white balance threshold gain for Gr channel.
+ * @r: white balance threshold gain for R channel.
+ * @b: white balance threshold gain for B channel.
+ * @gb: white balance threshold gain for Gb channel.
+ *
+ * Defines the threshold that specifies how different a defect pixel can be from
+ * its neighbors.(used by dynamic defect pixel correction sub block)
+ * Precision u4.4 range [0, 8].
+ */
+struct ipu3_uapi_bnr_static_config_wb_gains_thr_config {
+ __u8 gr;
+ __u8 r;
+ __u8 b;
+ __u8 gb;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_thr_coeffs_config - Noise model
+ * coefficients that controls noise threshold
+ *
+ * @cf: Free coefficient for threshold calculation, range [0, 8191], default 0.
+ * @reserved0: reserved
+ * @cg: Gain coefficient for threshold calculation, [0, 31], default 8.
+ * @ci: Intensity coefficient for threshold calculation. range [0, 0x1f]
+ * default 6.
+ * format: u3.2 (3 most significant bits represent whole number,
+ * 2 least significant bits represent the fractional part
+ * with each count representing 0.25)
+ * e.g. 6 in binary format is 00110, that translates to 1.5
+ * @reserved1: reserved
+ * @r_nf: Normalization shift value for r^2 calculation, range [12, 20]
+ * where r is a radius of pixel [row, col] from centor of sensor.
+ * default 14.
+ *
+ * Threshold used to distinguish between noise and details.
+ */
+struct ipu3_uapi_bnr_static_config_thr_coeffs_config {
+ __u32 cf:13;
+ __u32 reserved0:3;
+ __u32 cg:5;
+ __u32 ci:5;
+ __u32 reserved1:1;
+ __u32 r_nf:5;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_thr_ctrl_shd_config - Shading config
+ *
+ * @gr: Coefficient defines lens shading gain approximation for gr channel
+ * @r: Coefficient defines lens shading gain approximation for r channel
+ * @b: Coefficient defines lens shading gain approximation for b channel
+ * @gb: Coefficient defines lens shading gain approximation for gb channel
+ *
+ * Parameters for noise model (NM) adaptation of BNR due to shading correction.
+ * All above have precision of u3.3, default to 0.
+ */
+struct ipu3_uapi_bnr_static_config_thr_ctrl_shd_config {
+ __u8 gr;
+ __u8 r;
+ __u8 b;
+ __u8 gb;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_opt_center_config - Optical center config
+ *
+ * @x_reset: Reset value of X (col start - X center). Precision s12.0.
+ * @reserved0: reserved
+ * @y_reset: Reset value of Y (row start - Y center). Precision s12.0.
+ * @reserved2: reserved
+ *
+ * Distance from corner to optical center for NM adaptation due to shading
+ * correction (should be calculated based on shading tables)
+ */
+struct ipu3_uapi_bnr_static_config_opt_center_config {
+ __s32 x_reset:13;
+ __u32 reserved0:3;
+ __s32 y_reset:13;
+ __u32 reserved2:3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_lut_config - BNR square root lookup table
+ *
+ * @values: pre-calculated values of square root function.
+ *
+ * LUT implementation of square root operation.
+ */
+struct ipu3_uapi_bnr_static_config_lut_config {
+ __u8 values[IPU3_UAPI_BNR_LUT_SIZE];
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_bp_ctrl_config - Detect bad pixels (bp)
+ *
+ * @bp_thr_gain: Defines the threshold that specifies how different a
+ * defect pixel can be from its neighbors. Threshold is
+ * dependent on de-noise threshold calculated by algorithm.
+ * Range [4, 31], default 4.
+ * @reserved0: reserved
+ * @defect_mode: Mode of addressed defect pixels,
+ * 0 - single defect pixel is expected,
+ * 1 - 2 adjacent defect pixels are expected, default 1.
+ * @bp_gain: Defines how 2nd derivation that passes through a defect pixel
+ * is different from 2nd derivations that pass through
+ * neighbor pixels. u4.2, range [0, 256], default 8.
+ * @reserved1: reserved
+ * @w0_coeff: Blending coefficient of defect pixel correction.
+ * Precision u4, range [0, 8], default 8.
+ * @reserved2: reserved
+ * @w1_coeff: Enable influence of incorrect defect pixel correction to be
+ * avoided. Precision u4, range [1, 8], default 8.
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_bnr_static_config_bp_ctrl_config {
+ __u32 bp_thr_gain:5;
+ __u32 reserved0:2;
+ __u32 defect_mode:1;
+ __u32 bp_gain:6;
+ __u32 reserved1:18;
+ __u32 w0_coeff:4;
+ __u32 reserved2:4;
+ __u32 w1_coeff:4;
+ __u32 reserved3:20;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_dn_detect_ctrl_config - Denoising config
+ *
+ * @alpha: Weight of central element of smoothing filter.
+ * @beta: Weight of peripheral elements of smoothing filter, default 4.
+ * @gamma: Weight of diagonal elements of smoothing filter, default 4.
+ *
+ * beta and gamma parameter define the strength of the noise removal filter.
+ * All above has precision u0.4, range [0, 0xf]
+ * format: u0.4 (no / zero bits represent whole number,
+ * 4 bits represent the fractional part
+ * with each count representing 0.0625)
+ * e.g. 0xf translates to 0.0625x15 = 0.9375
+ *
+ * @reserved0: reserved
+ * @max_inf: Maximum increase of peripheral or diagonal element influence
+ * relative to the pre-defined value range: [0x5, 0xa]
+ * @reserved1: reserved
+ * @gd_enable: Green disparity enable control, 0 - disable, 1 - enable.
+ * @bpc_enable: Bad pixel correction enable control, 0 - disable, 1 - enable.
+ * @bnr_enable: Bayer noise removal enable control, 0 - disable, 1 - enable.
+ * @ff_enable: Fixed function enable, 0 - disable, 1 - enable.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_bnr_static_config_dn_detect_ctrl_config {
+ __u32 alpha:4;
+ __u32 beta:4;
+ __u32 gamma:4;
+ __u32 reserved0:4;
+ __u32 max_inf:4;
+ __u32 reserved1:7;
+ __u32 gd_enable:1;
+ __u32 bpc_enable:1;
+ __u32 bnr_enable:1;
+ __u32 ff_enable:1;
+ __u32 reserved2:1;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_opt_center_sqr_config - BNR optical square
+ *
+ * @x_sqr_reset: Reset value of X^2.
+ * @y_sqr_reset: Reset value of Y^2.
+ *
+ * Please note:
+ *
+ * #. X and Y ref to
+ * &ipu3_uapi_bnr_static_config_opt_center_config
+ * #. Both structs are used in threshold formula to calculate r^2, where r
+ * is a radius of pixel [row, col] from centor of sensor.
+ */
+struct ipu3_uapi_bnr_static_config_opt_center_sqr_config {
+ __u32 x_sqr_reset;
+ __u32 y_sqr_reset;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config - BNR static config
+ *
+ * @wb_gains: white balance gains &ipu3_uapi_bnr_static_config_wb_gains_config
+ * @wb_gains_thr: white balance gains threshold as defined by
+ * &ipu3_uapi_bnr_static_config_wb_gains_thr_config
+ * @thr_coeffs: coefficients of threshold
+ * &ipu3_uapi_bnr_static_config_thr_coeffs_config
+ * @thr_ctrl_shd: control of shading threshold
+ * &ipu3_uapi_bnr_static_config_thr_ctrl_shd_config
+ * @opt_center: optical center &ipu3_uapi_bnr_static_config_opt_center_config
+ *
+ * Above parameters and opt_center_sqr are used for white balance and shading.
+ *
+ * @lut: lookup table &ipu3_uapi_bnr_static_config_lut_config
+ * @bp_ctrl: detect and remove bad pixels as defined in struct
+ * &ipu3_uapi_bnr_static_config_bp_ctrl_config
+ * @dn_detect_ctrl: detect and remove noise.
+ * &ipu3_uapi_bnr_static_config_dn_detect_ctrl_config
+ * @column_size: The number of pixels in column.
+ * @opt_center_sqr: Reset value of r^2 to optical center, see
+ * &ipu3_uapi_bnr_static_config_opt_center_sqr_config.
+ */
+struct ipu3_uapi_bnr_static_config {
+ struct ipu3_uapi_bnr_static_config_wb_gains_config wb_gains;
+ struct ipu3_uapi_bnr_static_config_wb_gains_thr_config wb_gains_thr;
+ struct ipu3_uapi_bnr_static_config_thr_coeffs_config thr_coeffs;
+ struct ipu3_uapi_bnr_static_config_thr_ctrl_shd_config thr_ctrl_shd;
+ struct ipu3_uapi_bnr_static_config_opt_center_config opt_center;
+ struct ipu3_uapi_bnr_static_config_lut_config lut;
+ struct ipu3_uapi_bnr_static_config_bp_ctrl_config bp_ctrl;
+ struct ipu3_uapi_bnr_static_config_dn_detect_ctrl_config dn_detect_ctrl;
+ __u32 column_size;
+ struct ipu3_uapi_bnr_static_config_opt_center_sqr_config opt_center_sqr;
+} __packed;
+
+/**
+ * struct ipu3_uapi_bnr_static_config_green_disparity - Correct green disparity
+ *
+ * @gd_red: Shading gain coeff for gr disparity level in bright red region.
+ * Precision u0.6, default 4(0.0625).
+ * @reserved0: reserved
+ * @gd_green: Shading gain coeff for gr disparity level in bright green
+ * region. Precision u0.6, default 4(0.0625).
+ * @reserved1: reserved
+ * @gd_blue: Shading gain coeff for gr disparity level in bright blue region.
+ * Precision u0.6, default 4(0.0625).
+ * @reserved2: reserved
+ * @gd_black: Maximal green disparity level in dark region (stronger disparity
+ * assumed to be image detail). Precision u14, default 80.
+ * @reserved3: reserved
+ * @gd_shading: Change maximal green disparity level according to square
+ * distance from image center.
+ * @reserved4: reserved
+ * @gd_support: Lower bound for the number of second green color pixels in
+ * current pixel neighborhood with less than threshold difference
+ * from it.
+ *
+ * The shading gain coeff of red, green, blue and black are used to calculate
+ * threshold given a pixel's color value and its coordinates in the image.
+ *
+ * @reserved5: reserved
+ * @gd_clip: Turn green disparity clip on/off, [0, 1], default 1.
+ * @gd_central_weight: Central pixel weight in 9 pixels weighted sum.
+ */
+struct ipu3_uapi_bnr_static_config_green_disparity {
+ __u32 gd_red:6;
+ __u32 reserved0:2;
+ __u32 gd_green:6;
+ __u32 reserved1:2;
+ __u32 gd_blue:6;
+ __u32 reserved2:10;
+ __u32 gd_black:14;
+ __u32 reserved3:2;
+ __u32 gd_shading:7;
+ __u32 reserved4:1;
+ __u32 gd_support:2;
+ __u32 reserved5:1;
+ __u32 gd_clip:1;
+ __u32 gd_central_weight:4;
+} __packed;
+
+/**
+ * struct ipu3_uapi_dm_config - De-mosaic parameters
+ *
+ * @dm_en: de-mosaic enable.
+ * @ch_ar_en: Checker artifacts removal enable flag. Default 0.
+ * @fcc_en: False color correction (FCC) enable flag. Default 0.
+ * @reserved0: reserved
+ * @frame_width: do not care
+ * @gamma_sc: Sharpening coefficient (coefficient of 2-d derivation of
+ * complementary color in Hamilton-Adams interpolation).
+ * u5, range [0, 31], default 8.
+ * @reserved1: reserved
+ * @lc_ctrl: Parameter that controls weights of Chroma Homogeneity metric
+ * in calculation of final homogeneity metric.
+ * u5, range [0, 31], default 7.
+ * @reserved2: reserved
+ * @cr_param1: First parameter that defines Checker artifact removal
+ * feature gain. Precision u5, range [0, 31], default 8.
+ * @reserved3: reserved
+ * @cr_param2: Second parameter that defines Checker artifact removal
+ * feature gain. Precision u5, range [0, 31], default 8.
+ * @reserved4: reserved
+ * @coring_param: Defines power of false color correction operation.
+ * low for preserving edge colors, high for preserving gray
+ * edge artifacts.
+ * Precision u1.4, range [0, 1.9375], default 4 (0.25).
+ * @reserved5: reserved
+ *
+ * The demosaic fixed function block is responsible to covert Bayer(mosaiced)
+ * images into color images based on demosaicing algorithm.
+ */
+struct ipu3_uapi_dm_config {
+ __u32 dm_en:1;
+ __u32 ch_ar_en:1;
+ __u32 fcc_en:1;
+ __u32 reserved0:13;
+ __u32 frame_width:16;
+
+ __u32 gamma_sc:5;
+ __u32 reserved1:3;
+ __u32 lc_ctrl:5;
+ __u32 reserved2:3;
+ __u32 cr_param1:5;
+ __u32 reserved3:3;
+ __u32 cr_param2:5;
+ __u32 reserved4:3;
+
+ __u32 coring_param:5;
+ __u32 reserved5:27;
+} __packed;
+
+/**
+ * struct ipu3_uapi_ccm_mat_config - Color correction matrix
+ *
+ * @coeff_m11: CCM 3x3 coefficient, range [-65536, 65535]
+ * @coeff_m12: CCM 3x3 coefficient, range [-8192, 8191]
+ * @coeff_m13: CCM 3x3 coefficient, range [-32768, 32767]
+ * @coeff_o_r: Bias 3x1 coefficient, range [-8191, 8181]
+ * @coeff_m21: CCM 3x3 coefficient, range [-32767, 32767]
+ * @coeff_m22: CCM 3x3 coefficient, range [-8192, 8191]
+ * @coeff_m23: CCM 3x3 coefficient, range [-32768, 32767]
+ * @coeff_o_g: Bias 3x1 coefficient, range [-8191, 8181]
+ * @coeff_m31: CCM 3x3 coefficient, range [-32768, 32767]
+ * @coeff_m32: CCM 3x3 coefficient, range [-8192, 8191]
+ * @coeff_m33: CCM 3x3 coefficient, range [-32768, 32767]
+ * @coeff_o_b: Bias 3x1 coefficient, range [-8191, 8181]
+ *
+ * Transform sensor specific color space to standard sRGB by applying 3x3 matrix
+ * and adding a bias vector O. The transformation is basically a rotation and
+ * translation in the 3-dimensional color spaces. Here are the defaults:
+ *
+ * 9775, -2671, 1087, 0
+ * -1071, 8303, 815, 0
+ * -23, -7887, 16103, 0
+ */
+struct ipu3_uapi_ccm_mat_config {
+ __s16 coeff_m11;
+ __s16 coeff_m12;
+ __s16 coeff_m13;
+ __s16 coeff_o_r;
+ __s16 coeff_m21;
+ __s16 coeff_m22;
+ __s16 coeff_m23;
+ __s16 coeff_o_g;
+ __s16 coeff_m31;
+ __s16 coeff_m32;
+ __s16 coeff_m33;
+ __s16 coeff_o_b;
+} __packed;
+
+/**
+ * struct ipu3_uapi_gamma_corr_ctrl - Gamma correction
+ *
+ * @enable: gamma correction enable.
+ * @reserved: reserved
+ */
+struct ipu3_uapi_gamma_corr_ctrl {
+ __u32 enable:1;
+ __u32 reserved:31;
+} __packed;
+
+/**
+ * struct ipu3_uapi_gamma_corr_lut - Per-pixel tone mapping implemented as LUT.
+ *
+ * @lut: 256 tabulated values of the gamma function. LUT[1].. LUT[256]
+ * format u13.0, range [0, 8191].
+ *
+ * The tone mapping operation is done by a Piece wise linear graph
+ * that is implemented as a lookup table(LUT). The pixel component input
+ * intensity is the X-axis of the graph which is the table entry.
+ */
+struct ipu3_uapi_gamma_corr_lut {
+ __u16 lut[IPU3_UAPI_GAMMA_CORR_LUT_ENTRIES];
+} __packed;
+
+/**
+ * struct ipu3_uapi_gamma_config - Gamma config
+ *
+ * @gc_ctrl: control of gamma correction &ipu3_uapi_gamma_corr_ctrl
+ * @gc_lut: lookup table of gamma correction &ipu3_uapi_gamma_corr_lut
+ */
+struct ipu3_uapi_gamma_config {
+ struct ipu3_uapi_gamma_corr_ctrl gc_ctrl __attribute__((aligned(32)));
+ struct ipu3_uapi_gamma_corr_lut gc_lut __attribute__((aligned(32)));
+} __packed;
+
+/**
+ * struct ipu3_uapi_csc_mat_config - Color space conversion matrix config
+ *
+ * @coeff_c11: Conversion matrix value, format s0.14, range [-16384, 16383].
+ * @coeff_c12: Conversion matrix value, format s0.14, range [-8192, 8191].
+ * @coeff_c13: Conversion matrix value, format s0.14, range [-16384, 16383].
+ * @coeff_b1: Bias 3x1 coefficient, s13.0 range [-8192, 8191].
+ * @coeff_c21: Conversion matrix value, format s0.14, range [-16384, 16383].
+ * @coeff_c22: Conversion matrix value, format s0.14, range [-8192, 8191].
+ * @coeff_c23: Conversion matrix value, format s0.14, range [-16384, 16383].
+ * @coeff_b2: Bias 3x1 coefficient, s13.0 range [-8192, 8191].
+ * @coeff_c31: Conversion matrix value, format s0.14, range [-16384, 16383].
+ * @coeff_c32: Conversion matrix value, format s0.14, range [-8192, 8191].
+ * @coeff_c33: Conversion matrix value, format s0.14, range [-16384, 16383].
+ * @coeff_b3: Bias 3x1 coefficient, s13.0 range [-8192, 8191].
+ *
+ * To transform each pixel from RGB to YUV (Y - brightness/luminance,
+ * UV -chroma) by applying the pixel's values by a 3x3 matrix and adding an
+ * optional bias 3x1 vector. Here are the default values for the matrix:
+ *
+ * 4898, 9617, 1867, 0,
+ * -2410, -4732, 7143, 0,
+ * 10076, -8437, -1638, 0,
+ *
+ * (i.e. for real number 0.299, 0.299 * 2^14 becomes 4898.)
+ */
+struct ipu3_uapi_csc_mat_config {
+ __s16 coeff_c11;
+ __s16 coeff_c12;
+ __s16 coeff_c13;
+ __s16 coeff_b1;
+ __s16 coeff_c21;
+ __s16 coeff_c22;
+ __s16 coeff_c23;
+ __s16 coeff_b2;
+ __s16 coeff_c31;
+ __s16 coeff_c32;
+ __s16 coeff_c33;
+ __s16 coeff_b3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_cds_params - Chroma down-scaling
+ *
+ * @ds_c00: range [0, 3]
+ * @ds_c01: range [0, 3]
+ * @ds_c02: range [0, 3]
+ * @ds_c03: range [0, 3]
+ * @ds_c10: range [0, 3]
+ * @ds_c11: range [0, 3]
+ * @ds_c12: range [0, 3]
+ * @ds_c13: range [0, 3]
+ *
+ * In case user does not provide, above 4x2 filter will use following defaults:
+ * 1, 3, 3, 1,
+ * 1, 3, 3, 1,
+ *
+ * @ds_nf: Normalization factor for Chroma output downscaling filter,
+ * range 0,4, default 2.
+ * @reserved0: reserved
+ * @csc_en: Color space conversion enable
+ * @uv_bin_output: 0: output YUV 4.2.0, 1: output YUV 4.2.2(default).
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_cds_params {
+ __u32 ds_c00:2;
+ __u32 ds_c01:2;
+ __u32 ds_c02:2;
+ __u32 ds_c03:2;
+ __u32 ds_c10:2;
+ __u32 ds_c11:2;
+ __u32 ds_c12:2;
+ __u32 ds_c13:2;
+ __u32 ds_nf:5;
+ __u32 reserved0:3;
+ __u32 csc_en:1;
+ __u32 uv_bin_output:1;
+ __u32 reserved1:6;
+} __packed;
+
+/**
+ * struct ipu3_uapi_shd_grid_config - Bayer shading(darkening) correction
+ *
+ * @width: Grid horizontal dimensions, u8, [8, 128], default 73
+ * @height: Grid vertical dimensions, u8, [8, 128], default 56
+ * @block_width_log2: Log2 of the width of the grid cell in pixel count
+ * u4, [0, 15], default value 5.
+ * @reserved0: reserved
+ * @block_height_log2: Log2 of the height of the grid cell in pixel count
+ * u4, [0, 15], default value 6.
+ * @reserved1: reserved
+ * @grid_height_per_slice: SHD_MAX_CELLS_PER_SET/width.
+ * (with SHD_MAX_CELLS_PER_SET = 146).
+ * @x_start: X value of top left corner of sensor relative to ROI
+ * s13, [-4096, 0], default 0, only negative values.
+ * @y_start: Y value of top left corner of sensor relative to ROI
+ * s13, [-4096, 0], default 0, only negative values.
+ */
+struct ipu3_uapi_shd_grid_config {
+ /* reg 0 */
+ __u8 width;
+ __u8 height;
+ __u8 block_width_log2:3;
+ __u8 reserved0:1;
+ __u8 block_height_log2:3;
+ __u8 reserved1:1;
+ __u8 grid_height_per_slice;
+ /* reg 1 */
+ __s16 x_start;
+ __s16 y_start;
+} __packed;
+
+/**
+ * struct ipu3_uapi_shd_general_config - Shading general config
+ *
+ * @init_set_vrt_offst_ul: set vertical offset,
+ * y_start >> block_height_log2 % grid_height_per_slice.
+ * @shd_enable: shading enable.
+ * @gain_factor: Gain factor. Shift calculated anti shading value. Precision u2.
+ * 0x0 - gain factor [1, 5], means no shift interpolated value.
+ * 0x1 - gain factor [1, 9], means shift interpolated by 1.
+ * 0x2 - gain factor [1, 17], means shift interpolated by 2.
+ * @reserved: reserved
+ *
+ * Correction is performed by multiplying a gain factor for each of the 4 Bayer
+ * channels as a function of the pixel location in the sensor.
+ */
+struct ipu3_uapi_shd_general_config {
+ __u32 init_set_vrt_offst_ul:8;
+ __u32 shd_enable:1;
+ __u32 gain_factor:2;
+ __u32 reserved:21;
+} __packed;
+
+/**
+ * struct ipu3_uapi_shd_black_level_config - Black level correction
+ *
+ * @bl_r: Bios values for green red. s11 range [-2048, 2047].
+ * @bl_gr: Bios values for green blue. s11 range [-2048, 2047].
+ * @bl_gb: Bios values for red. s11 range [-2048, 2047].
+ * @bl_b: Bios values for blue. s11 range [-2048, 2047].
+ */
+struct ipu3_uapi_shd_black_level_config {
+ __s16 bl_r;
+ __s16 bl_gr;
+ __s16 bl_gb;
+ __s16 bl_b;
+} __packed;
+
+/**
+ * struct ipu3_uapi_shd_config_static - Shading config static
+ *
+ * @grid: shading grid config &ipu3_uapi_shd_grid_config
+ * @general: shading general config &ipu3_uapi_shd_general_config
+ * @black_level: black level config for shading correction as defined by
+ * &ipu3_uapi_shd_black_level_config
+ */
+struct ipu3_uapi_shd_config_static {
+ struct ipu3_uapi_shd_grid_config grid;
+ struct ipu3_uapi_shd_general_config general;
+ struct ipu3_uapi_shd_black_level_config black_level;
+} __packed;
+
+/**
+ * struct ipu3_uapi_shd_lut - Shading gain factor lookup table.
+ *
+ * @sets: array
+ * @sets.r_and_gr: Red and GreenR Lookup table.
+ * @sets.r_and_gr.r: Red shading factor.
+ * @sets.r_and_gr.gr: GreenR shading factor.
+ * @sets.reserved1: reserved
+ * @sets.gb_and_b: GreenB and Blue Lookup table.
+ * @sets.gb_and_b.gb: GreenB shading factor.
+ * @sets.gb_and_b.b: Blue shading factor.
+ * @sets.reserved2: reserved
+ *
+ * Map to shading correction LUT register set.
+ */
+struct ipu3_uapi_shd_lut {
+ struct {
+ struct {
+ __u16 r;
+ __u16 gr;
+ } r_and_gr[IPU3_UAPI_SHD_MAX_CELLS_PER_SET];
+ __u8 reserved1[24];
+ struct {
+ __u16 gb;
+ __u16 b;
+ } gb_and_b[IPU3_UAPI_SHD_MAX_CELLS_PER_SET];
+ __u8 reserved2[24];
+ } sets[IPU3_UAPI_SHD_MAX_CFG_SETS];
+} __packed;
+
+/**
+ * struct ipu3_uapi_shd_config - Shading config
+ *
+ * @shd: shading static config, see &ipu3_uapi_shd_config_static
+ * @shd_lut: shading lookup table &ipu3_uapi_shd_lut
+ */
+struct ipu3_uapi_shd_config {
+ struct ipu3_uapi_shd_config_static shd __attribute__((aligned(32)));
+ struct ipu3_uapi_shd_lut shd_lut __attribute__((aligned(32)));
+} __packed;
+
+/* Image Enhancement Filter directed */
+
+/**
+ * struct ipu3_uapi_iefd_cux2 - IEFd Config Unit 2 parameters
+ *
+ * @x0: X0 point of Config Unit, u9.0, default 0.
+ * @x1: X1 point of Config Unit, u9.0, default 0.
+ * @a01: Slope A of Config Unit, s4.4, default 0.
+ * @b01: Slope B, always 0.
+ *
+ * Calculate weight for blending directed and non-directed denoise elements
+ *
+ * Note:
+ * Each instance of Config Unit needs X coordinate of n points and
+ * slope A factor between points calculated by driver based on calibration
+ * parameters.
+ *
+ * All CU inputs are unsigned, they will be converted to signed when written
+ * to register, i.e. a01 will be written to 9 bit register in s4.4 format.
+ * This applies to &ipu3_uapi_iefd_cux6_ed, &ipu3_uapi_iefd_cux2_1,
+ * &ipu3_uapi_iefd_cux2_1, &ipu3_uapi_iefd_cux4 and &ipu3_uapi_iefd_cux6_rad.
+ */
+struct ipu3_uapi_iefd_cux2 {
+ __u32 x0:9;
+ __u32 x1:9;
+ __u32 a01:9;
+ __u32 b01:5;
+} __packed;
+
+/**
+ * struct ipu3_uapi_iefd_cux6_ed - Calculate power of non-directed sharpening
+ * element, Config Unit 6 for edge detail (ED).
+ *
+ * @x0: X coordinate of point 0, u9.0, default 0.
+ * @x1: X coordinate of point 1, u9.0, default 0.
+ * @x2: X coordinate of point 2, u9.0, default 0.
+ * @reserved0: reserved
+ * @x3: X coordinate of point 3, u9.0, default 0.
+ * @x4: X coordinate of point 4, u9.0, default 0.
+ * @x5: X coordinate of point 5, u9.0, default 0.
+ * @reserved1: reserved
+ * @a01: slope A points 01, s4.4, default 0.
+ * @a12: slope A points 12, s4.4, default 0.
+ * @a23: slope A points 23, s4.4, default 0.
+ * @reserved2: reserved
+ * @a34: slope A points 34, s4.4, default 0.
+ * @a45: slope A points 45, s4.4, default 0.
+ * @reserved3: reserved
+ * @b01: slope B points 01, s4.4, default 0.
+ * @b12: slope B points 12, s4.4, default 0.
+ * @b23: slope B points 23, s4.4, default 0.
+ * @reserved4: reserved
+ * @b34: slope B points 34, s4.4, default 0.
+ * @b45: slope B points 45, s4.4, default 0.
+ * @reserved5: reserved.
+ */
+struct ipu3_uapi_iefd_cux6_ed {
+ __u32 x0:9;
+ __u32 x1:9;
+ __u32 x2:9;
+ __u32 reserved0:5;
+
+ __u32 x3:9;
+ __u32 x4:9;
+ __u32 x5:9;
+ __u32 reserved1:5;
+
+ __u32 a01:9;
+ __u32 a12:9;
+ __u32 a23:9;
+ __u32 reserved2:5;
+
+ __u32 a34:9;
+ __u32 a45:9;
+ __u32 reserved3:14;
+
+ __u32 b01:9;
+ __u32 b12:9;
+ __u32 b23:9;
+ __u32 reserved4:5;
+
+ __u32 b34:9;
+ __u32 b45:9;
+ __u32 reserved5:14;
+} __packed;
+
+/**
+ * struct ipu3_uapi_iefd_cux2_1 - Calculate power of non-directed denoise
+ * element apply.
+ * @x0: X0 point of Config Unit, u9.0, default 0.
+ * @x1: X1 point of Config Unit, u9.0, default 0.
+ * @a01: Slope A of Config Unit, s4.4, default 0.
+ * @reserved1: reserved
+ * @b01: offset B0 of Config Unit, u7.0, default 0.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_iefd_cux2_1 {
+ __u32 x0:9;
+ __u32 x1:9;
+ __u32 a01:9;
+ __u32 reserved1:5;
+
+ __u32 b01:8;
+ __u32 reserved2:24;
+} __packed;
+
+/**
+ * struct ipu3_uapi_iefd_cux4 - Calculate power of non-directed sharpening
+ * element.
+ *
+ * @x0: X0 point of Config Unit, u9.0, default 0.
+ * @x1: X1 point of Config Unit, u9.0, default 0.
+ * @x2: X2 point of Config Unit, u9.0, default 0.
+ * @reserved0: reserved
+ * @x3: X3 point of Config Unit, u9.0, default 0.
+ * @a01: Slope A0 of Config Unit, s4.4, default 0.
+ * @a12: Slope A1 of Config Unit, s4.4, default 0.
+ * @reserved1: reserved
+ * @a23: Slope A2 of Config Unit, s4.4, default 0.
+ * @b01: Offset B0 of Config Unit, s7.0, default 0.
+ * @b12: Offset B1 of Config Unit, s7.0, default 0.
+ * @reserved2: reserved
+ * @b23: Offset B2 of Config Unit, s7.0, default 0.
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_iefd_cux4 {
+ __u32 x0:9;
+ __u32 x1:9;
+ __u32 x2:9;
+ __u32 reserved0:5;
+
+ __u32 x3:9;
+ __u32 a01:9;
+ __u32 a12:9;
+ __u32 reserved1:5;
+
+ __u32 a23:9;
+ __u32 b01:8;
+ __u32 b12:8;
+ __u32 reserved2:7;
+
+ __u32 b23:8;
+ __u32 reserved3:24;
+} __packed;
+
+/**
+ * struct ipu3_uapi_iefd_cux6_rad - Radial Config Unit (CU)
+ *
+ * @x0: x0 points of Config Unit radial, u8.0
+ * @x1: x1 points of Config Unit radial, u8.0
+ * @x2: x2 points of Config Unit radial, u8.0
+ * @x3: x3 points of Config Unit radial, u8.0
+ * @x4: x4 points of Config Unit radial, u8.0
+ * @x5: x5 points of Config Unit radial, u8.0
+ * @reserved1: reserved
+ * @a01: Slope A of Config Unit radial, s7.8
+ * @a12: Slope A of Config Unit radial, s7.8
+ * @a23: Slope A of Config Unit radial, s7.8
+ * @a34: Slope A of Config Unit radial, s7.8
+ * @a45: Slope A of Config Unit radial, s7.8
+ * @reserved2: reserved
+ * @b01: Slope B of Config Unit radial, s9.0
+ * @b12: Slope B of Config Unit radial, s9.0
+ * @b23: Slope B of Config Unit radial, s9.0
+ * @reserved4: reserved
+ * @b34: Slope B of Config Unit radial, s9.0
+ * @b45: Slope B of Config Unit radial, s9.0
+ * @reserved5: reserved
+ */
+struct ipu3_uapi_iefd_cux6_rad {
+ __u32 x0:8;
+ __u32 x1:8;
+ __u32 x2:8;
+ __u32 x3:8;
+
+ __u32 x4:8;
+ __u32 x5:8;
+ __u32 reserved1:16;
+
+ __u32 a01:16;
+ __u32 a12:16;
+
+ __u32 a23:16;
+ __u32 a34:16;
+
+ __u32 a45:16;
+ __u32 reserved2:16;
+
+ __u32 b01:10;
+ __u32 b12:10;
+ __u32 b23:10;
+ __u32 reserved4:2;
+
+ __u32 b34:10;
+ __u32 b45:10;
+ __u32 reserved5:12;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_iefd_cfg_units - IEFd Config Units parameters
+ *
+ * @cu_1: calculate weight for blending directed and
+ * non-directed denoise elements. See &ipu3_uapi_iefd_cux2
+ * @cu_ed: calculate power of non-directed sharpening element, see
+ * &ipu3_uapi_iefd_cux6_ed
+ * @cu_3: calculate weight for blending directed and
+ * non-directed denoise elements. A &ipu3_uapi_iefd_cux2
+ * @cu_5: calculate power of non-directed denoise element apply, use
+ * &ipu3_uapi_iefd_cux2_1
+ * @cu_6: calculate power of non-directed sharpening element. See
+ * &ipu3_uapi_iefd_cux4
+ * @cu_7: calculate weight for blending directed and
+ * non-directed denoise elements. Use &ipu3_uapi_iefd_cux2
+ * @cu_unsharp: Config Unit of unsharp &ipu3_uapi_iefd_cux4
+ * @cu_radial: Config Unit of radial &ipu3_uapi_iefd_cux6_rad
+ * @cu_vssnlm: Config Unit of vssnlm &ipu3_uapi_iefd_cux2
+ */
+struct ipu3_uapi_yuvp1_iefd_cfg_units {
+ struct ipu3_uapi_iefd_cux2 cu_1;
+ struct ipu3_uapi_iefd_cux6_ed cu_ed;
+ struct ipu3_uapi_iefd_cux2 cu_3;
+ struct ipu3_uapi_iefd_cux2_1 cu_5;
+ struct ipu3_uapi_iefd_cux4 cu_6;
+ struct ipu3_uapi_iefd_cux2 cu_7;
+ struct ipu3_uapi_iefd_cux4 cu_unsharp;
+ struct ipu3_uapi_iefd_cux6_rad cu_radial;
+ struct ipu3_uapi_iefd_cux2 cu_vssnlm;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_iefd_config_s - IEFd config
+ *
+ * @horver_diag_coeff: Gradient compensation. Compared with vertical /
+ * horizontal (0 / 90 degree), coefficient of diagonal (45 /
+ * 135 degree) direction should be corrected by approx.
+ * 1/sqrt(2).
+ * @reserved0: reserved
+ * @clamp_stitch: Slope to stitch between clamped and unclamped edge values
+ * @reserved1: reserved
+ * @direct_metric_update: Update coeff for direction metric
+ * @reserved2: reserved
+ * @ed_horver_diag_coeff: Radial Coefficient that compensates for
+ * different distance for vertical/horizontal and
+ * diagonal gradient calculation (approx. 1/sqrt(2))
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_yuvp1_iefd_config_s {
+ __u32 horver_diag_coeff:7;
+ __u32 reserved0:1;
+ __u32 clamp_stitch:6;
+ __u32 reserved1:2;
+ __u32 direct_metric_update:5;
+ __u32 reserved2:3;
+ __u32 ed_horver_diag_coeff:7;
+ __u32 reserved3:1;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_iefd_control - IEFd control
+ *
+ * @iefd_en: Enable IEFd
+ * @denoise_en: Enable denoise
+ * @direct_smooth_en: Enable directional smooth
+ * @rad_en: Enable radial update
+ * @vssnlm_en: Enable VSSNLM output filter
+ * @reserved: reserved
+ */
+struct ipu3_uapi_yuvp1_iefd_control {
+ __u32 iefd_en:1;
+ __u32 denoise_en:1;
+ __u32 direct_smooth_en:1;
+ __u32 rad_en:1;
+ __u32 vssnlm_en:1;
+ __u32 reserved:27;
+} __packed;
+
+/**
+ * struct ipu3_uapi_sharp_cfg - Sharpening config
+ *
+ * @nega_lmt_txt: Sharpening limit for negative overshoots for texture.
+ * @reserved0: reserved
+ * @posi_lmt_txt: Sharpening limit for positive overshoots for texture.
+ * @reserved1: reserved
+ * @nega_lmt_dir: Sharpening limit for negative overshoots for direction (edge).
+ * @reserved2: reserved
+ * @posi_lmt_dir: Sharpening limit for positive overshoots for direction (edge).
+ * @reserved3: reserved
+ *
+ * Fixed point type u13.0, range [0, 8191].
+ */
+struct ipu3_uapi_sharp_cfg {
+ __u32 nega_lmt_txt:13;
+ __u32 reserved0:19;
+ __u32 posi_lmt_txt:13;
+ __u32 reserved1:19;
+ __u32 nega_lmt_dir:13;
+ __u32 reserved2:19;
+ __u32 posi_lmt_dir:13;
+ __u32 reserved3:19;
+} __packed;
+
+/**
+ * struct struct ipu3_uapi_far_w - Sharpening config for far sub-group
+ *
+ * @dir_shrp: Weight of wide direct sharpening, u1.6, range [0, 64], default 64.
+ * @reserved0: reserved
+ * @dir_dns: Weight of wide direct denoising, u1.6, range [0, 64], default 0.
+ * @reserved1: reserved
+ * @ndir_dns_powr: Power of non-direct denoising,
+ * Precision u1.6, range [0, 64], default 64.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_far_w {
+ __u32 dir_shrp:7;
+ __u32 reserved0:1;
+ __u32 dir_dns:7;
+ __u32 reserved1:1;
+ __u32 ndir_dns_powr:7;
+ __u32 reserved2:9;
+} __packed;
+
+/**
+ * struct struct ipu3_uapi_unsharp_cfg - Unsharp config
+ *
+ * @unsharp_weight: Unsharp mask blending weight.
+ * u1.6, range [0, 64], default 16.
+ * 0 - disabled, 64 - use only unsharp.
+ * @reserved0: reserved
+ * @unsharp_amount: Unsharp mask amount, u4.5, range [0, 511], default 0.
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_unsharp_cfg {
+ __u32 unsharp_weight:7;
+ __u32 reserved0:1;
+ __u32 unsharp_amount:9;
+ __u32 reserved1:15;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_iefd_shrp_cfg - IEFd sharpness config
+ *
+ * @cfg: sharpness config &ipu3_uapi_sharp_cfg
+ * @far_w: wide range config, value as specified by &ipu3_uapi_far_w:
+ * The 5x5 environment is separated into 2 sub-groups, the 3x3 nearest
+ * neighbors (8 pixels called Near), and the second order neighborhood
+ * around them (16 pixels called Far).
+ * @unshrp_cfg: unsharpness config. &ipu3_uapi_unsharp_cfg
+ */
+struct ipu3_uapi_yuvp1_iefd_shrp_cfg {
+ struct ipu3_uapi_sharp_cfg cfg;
+ struct ipu3_uapi_far_w far_w;
+ struct ipu3_uapi_unsharp_cfg unshrp_cfg;
+} __packed;
+
+/**
+ * struct ipu3_uapi_unsharp_coef0 - Unsharp mask coefficients
+ *
+ * @c00: Coeff11, s0.8, range [-255, 255], default 1.
+ * @c01: Coeff12, s0.8, range [-255, 255], default 5.
+ * @c02: Coeff13, s0.8, range [-255, 255], default 9.
+ * @reserved: reserved
+ *
+ * Configurable registers for common sharpening support.
+ */
+struct ipu3_uapi_unsharp_coef0 {
+ __u32 c00:9;
+ __u32 c01:9;
+ __u32 c02:9;
+ __u32 reserved:5;
+} __packed;
+
+/**
+ * struct ipu3_uapi_unsharp_coef1 - Unsharp mask coefficients
+ *
+ * @c11: Coeff22, s0.8, range [-255, 255], default 29.
+ * @c12: Coeff23, s0.8, range [-255, 255], default 55.
+ * @c22: Coeff33, s0.8, range [-255, 255], default 96.
+ * @reserved: reserved
+ */
+struct ipu3_uapi_unsharp_coef1 {
+ __u32 c11:9;
+ __u32 c12:9;
+ __u32 c22:9;
+ __u32 reserved:5;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_iefd_unshrp_cfg - Unsharp mask config
+ *
+ * @unsharp_coef0: unsharp coefficient 0 config. See &ipu3_uapi_unsharp_coef0
+ * @unsharp_coef1: unsharp coefficient 1 config. See &ipu3_uapi_unsharp_coef1
+ */
+struct ipu3_uapi_yuvp1_iefd_unshrp_cfg {
+ struct ipu3_uapi_unsharp_coef0 unsharp_coef0;
+ struct ipu3_uapi_unsharp_coef1 unsharp_coef1;
+} __packed;
+
+/**
+ * struct ipu3_uapi_radial_reset_xy - Radial coordinate reset
+ *
+ * @x: Radial reset of x coordinate. Precision s12, [-4095, 4095], default 0.
+ * @reserved0: reserved
+ * @y: Radial center y coordinate. Precision s12, [-4095, 4095], default 0.
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_radial_reset_xy {
+ __s32 x:13;
+ __u32 reserved0:3;
+ __s32 y:13;
+ __u32 reserved1:3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_radial_reset_x2 - Radial X^2 reset
+ *
+ * @x2: Radial reset of x^2 coordinate. Precision u24, default 0.
+ * @reserved: reserved
+ */
+struct ipu3_uapi_radial_reset_x2 {
+ __u32 x2:24;
+ __u32 reserved:8;
+} __packed;
+
+/**
+ * struct ipu3_uapi_radial_reset_y2 - Radial Y^2 reset
+ *
+ * @y2: Radial reset of y^2 coordinate. Precision u24, default 0.
+ * @reserved: reserved
+ */
+struct ipu3_uapi_radial_reset_y2 {
+ __u32 y2:24;
+ __u32 reserved:8;
+} __packed;
+
+/**
+ * struct ipu3_uapi_radial_cfg - Radial config
+ *
+ * @rad_nf: Radial. R^2 normalization factor is scale down by 2^ - (15 + scale)
+ * @reserved0: reserved
+ * @rad_inv_r2: Radial R^-2 normelized to (0.5..1).
+ * Precision u7, range [0, 127].
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_radial_cfg {
+ __u32 rad_nf:4;
+ __u32 reserved0:4;
+ __u32 rad_inv_r2:7;
+ __u32 reserved1:17;
+} __packed;
+
+/**
+ * struct ipu3_uapi_rad_far_w - Radial FAR sub-group
+ *
+ * @rad_dir_far_sharp_w: Weight of wide direct sharpening, u1.6, range [0, 64],
+ * default 64.
+ * @rad_dir_far_dns_w: Weight of wide direct denoising, u1.6, range [0, 64],
+ * default 0.
+ * @rad_ndir_far_dns_power: power of non-direct sharpening, u1.6, range [0, 64],
+ * default 0.
+ * @reserved: reserved
+ */
+struct ipu3_uapi_rad_far_w {
+ __u32 rad_dir_far_sharp_w:8;
+ __u32 rad_dir_far_dns_w:8;
+ __u32 rad_ndir_far_dns_power:8;
+ __u32 reserved:8;
+} __packed;
+
+/**
+ * struct ipu3_uapi_cu_cfg0 - Radius Config Unit cfg0 register
+ *
+ * @cu6_pow: Power of CU6. Power of non-direct sharpening, u3.4.
+ * @reserved0: reserved
+ * @cu_unsharp_pow: Power of unsharp mask, u2.4.
+ * @reserved1: reserved
+ * @rad_cu6_pow: Radial/corner CU6. Directed sharpening power, u3.4.
+ * @reserved2: reserved
+ * @rad_cu_unsharp_pow: Radial power of unsharp mask, u2.4.
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_cu_cfg0 {
+ __u32 cu6_pow:7;
+ __u32 reserved0:1;
+ __u32 cu_unsharp_pow:7;
+ __u32 reserved1:1;
+ __u32 rad_cu6_pow:7;
+ __u32 reserved2:1;
+ __u32 rad_cu_unsharp_pow:6;
+ __u32 reserved3:2;
+} __packed;
+
+/**
+ * struct ipu3_uapi_cu_cfg1 - Radius Config Unit cfg1 register
+ *
+ * @rad_cu6_x1: X1 point of Config Unit 6, precision u9.0.
+ * @reserved0: reserved
+ * @rad_cu_unsharp_x1: X1 point for Config Unit unsharp for radial/corner point
+ * precision u9.0.
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_cu_cfg1 {
+ __u32 rad_cu6_x1:9;
+ __u32 reserved0:1;
+ __u32 rad_cu_unsharp_x1:9;
+ __u32 reserved1:13;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_iefd_rad_cfg - IEFd parameters changed radially over
+ * the picture plane.
+ *
+ * @reset_xy: reset xy value in radial calculation. &ipu3_uapi_radial_reset_xy
+ * @reset_x2: reset x square value in radial calculation. See struct
+ * &ipu3_uapi_radial_reset_x2
+ * @reset_y2: reset y square value in radial calculation. See struct
+ * &ipu3_uapi_radial_reset_y2
+ * @cfg: radial config defined in &ipu3_uapi_radial_cfg
+ * @rad_far_w: weight for wide range radial. &ipu3_uapi_rad_far_w
+ * @cu_cfg0: configuration unit 0. See &ipu3_uapi_cu_cfg0
+ * @cu_cfg1: configuration unit 1. See &ipu3_uapi_cu_cfg1
+ */
+struct ipu3_uapi_yuvp1_iefd_rad_cfg {
+ struct ipu3_uapi_radial_reset_xy reset_xy;
+ struct ipu3_uapi_radial_reset_x2 reset_x2;
+ struct ipu3_uapi_radial_reset_y2 reset_y2;
+ struct ipu3_uapi_radial_cfg cfg;
+ struct ipu3_uapi_rad_far_w rad_far_w;
+ struct ipu3_uapi_cu_cfg0 cu_cfg0;
+ struct ipu3_uapi_cu_cfg1 cu_cfg1;
+} __packed;
+
+/* Vssnlm - Very small scale non-local mean algorithm */
+
+/**
+ * struct ipu3_uapi_vss_lut_x - Vssnlm LUT x0/x1/x2
+ *
+ * @vs_x0: Vssnlm LUT x0, precision u8, range [0, 255], default 16.
+ * @vs_x1: Vssnlm LUT x1, precision u8, range [0, 255], default 32.
+ * @vs_x2: Vssnlm LUT x2, precision u8, range [0, 255], default 64.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_vss_lut_x {
+ __u32 vs_x0:8;
+ __u32 vs_x1:8;
+ __u32 vs_x2:8;
+ __u32 reserved2:8;
+} __packed;
+
+/**
+ * struct ipu3_uapi_vss_lut_y - Vssnlm LUT y0/y1/y2
+ *
+ * @vs_y1: Vssnlm LUT y1, precision u4, range [0, 8], default 1.
+ * @reserved0: reserved
+ * @vs_y2: Vssnlm LUT y2, precision u4, range [0, 8], default 3.
+ * @reserved1: reserved
+ * @vs_y3: Vssnlm LUT y3, precision u4, range [0, 8], default 8.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_vss_lut_y {
+ __u32 vs_y1:4;
+ __u32 reserved0:4;
+ __u32 vs_y2:4;
+ __u32 reserved1:4;
+ __u32 vs_y3:4;
+ __u32 reserved2:12;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_iefd_vssnlm_cf - IEFd Vssnlm Lookup table
+ *
+ * @vss_lut_x: vss lookup table. See &ipu3_uapi_vss_lut_x description
+ * @vss_lut_y: vss lookup table. See &ipu3_uapi_vss_lut_y description
+ */
+struct ipu3_uapi_yuvp1_iefd_vssnlm_cfg {
+ struct ipu3_uapi_vss_lut_x vss_lut_x;
+ struct ipu3_uapi_vss_lut_y vss_lut_y;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_iefd_config - IEFd config
+ *
+ * @units: configuration unit setting, &ipu3_uapi_yuvp1_iefd_cfg_units
+ * @config: configuration, as defined by &ipu3_uapi_yuvp1_iefd_config_s
+ * @control: control setting, as defined by &ipu3_uapi_yuvp1_iefd_control
+ * @sharp: sharpness setting, as defined by &ipu3_uapi_yuvp1_iefd_shrp_cfg
+ * @unsharp: unsharpness setting, as defined by &ipu3_uapi_yuvp1_iefd_unshrp_cfg
+ * @rad: radial setting, as defined by &ipu3_uapi_yuvp1_iefd_rad_cfg
+ * @vsslnm: vsslnm setting, as defined by &ipu3_uapi_yuvp1_iefd_vssnlm_cfg
+ */
+struct ipu3_uapi_yuvp1_iefd_config {
+ struct ipu3_uapi_yuvp1_iefd_cfg_units units;
+ struct ipu3_uapi_yuvp1_iefd_config_s config;
+ struct ipu3_uapi_yuvp1_iefd_control control;
+ struct ipu3_uapi_yuvp1_iefd_shrp_cfg sharp;
+ struct ipu3_uapi_yuvp1_iefd_unshrp_cfg unsharp;
+ struct ipu3_uapi_yuvp1_iefd_rad_cfg rad;
+ struct ipu3_uapi_yuvp1_iefd_vssnlm_cfg vsslnm;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_yds_config - Y Down-Sampling config
+ *
+ * @c00: range [0, 3], default 0x0
+ * @c01: range [0, 3], default 0x1
+ * @c02: range [0, 3], default 0x1
+ * @c03: range [0, 3], default 0x0
+ * @c10: range [0, 3], default 0x0
+ * @c11: range [0, 3], default 0x1
+ * @c12: range [0, 3], default 0x1
+ * @c13: range [0, 3], default 0x0
+ *
+ * Above are 4x2 filter coefficients for chroma output downscaling.
+ *
+ * @norm_factor: Normalization factor, range [0, 4], default 2
+ * 0 - divide by 1
+ * 1 - divide by 2
+ * 2 - divide by 4
+ * 3 - divide by 8
+ * 4 - divide by 16
+ * @reserved0: reserved
+ * @bin_output: Down sampling on Luma channel in two optional modes
+ * 0 - Bin output 4.2.0 (default), 1 output 4.2.2.
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_yuvp1_yds_config {
+ __u32 c00:2;
+ __u32 c01:2;
+ __u32 c02:2;
+ __u32 c03:2;
+ __u32 c10:2;
+ __u32 c11:2;
+ __u32 c12:2;
+ __u32 c13:2;
+ __u32 norm_factor:5;
+ __u32 reserved0:4;
+ __u32 bin_output:1;
+ __u32 reserved1:6;
+} __packed;
+
+/* Chroma Noise Reduction */
+
+/**
+ * struct ipu3_uapi_yuvp1_chnr_enable_config - Chroma noise reduction enable
+ *
+ * @enable: enable/disable chroma noise reduction
+ * @yuv_mode: 0 - YUV420, 1 - YUV422
+ * @reserved0: reserved
+ * @col_size: number of columns in the frame, max width is 2560
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_yuvp1_chnr_enable_config {
+ __u32 enable:1;
+ __u32 yuv_mode:1;
+ __u32 reserved0:14;
+ __u32 col_size:12;
+ __u32 reserved1:4;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_chnr_coring_config - Coring thresholds for UV
+ *
+ * @u: U coring level, u0.13, range [0.0, 1.0], default 0.0
+ * @reserved0: reserved
+ * @v: V coring level, u0.13, range [0.0, 1.0], default 0.0
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_yuvp1_chnr_coring_config {
+ __u32 u:13;
+ __u32 reserved0:3;
+ __u32 v:13;
+ __u32 reserved1:3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_chnr_sense_gain_config - Chroma noise reduction gains
+ *
+ * All sensitivity gain parameters have precision u13.0, range [0, 8191].
+ *
+ * @vy: Sensitivity of horizontal edge of Y, default 100
+ * @vu: Sensitivity of horizontal edge of U, default 100
+ * @vv: Sensitivity of horizontal edge of V, default 100
+ * @reserved0: reserved
+ * @hy: Sensitivity of vertical edge of Y, default 50
+ * @hu: Sensitivity of vertical edge of U, default 50
+ * @hv: Sensitivity of vertical edge of V, default 50
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_yuvp1_chnr_sense_gain_config {
+ __u32 vy:8;
+ __u32 vu:8;
+ __u32 vv:8;
+ __u32 reserved0:8;
+
+ __u32 hy:8;
+ __u32 hu:8;
+ __u32 hv:8;
+ __u32 reserved1:8;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_chnr_iir_fir_config - Chroma IIR/FIR filter config
+ *
+ * @fir_0h: Value of center tap in horizontal FIR, range [0, 32], default 8.
+ * @reserved0: reserved
+ * @fir_1h: Value of distance 1 in horizontal FIR, range [0, 32], default 12.
+ * @reserved1: reserved
+ * @fir_2h: Value of distance 2 tap in horizontal FIR, range [0, 32], default 0.
+ * @dalpha_clip_val: weight for previous row in IIR, range [1, 256], default 0.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_yuvp1_chnr_iir_fir_config {
+ __u32 fir_0h:6;
+ __u32 reserved0:2;
+ __u32 fir_1h:6;
+ __u32 reserved1:2;
+ __u32 fir_2h:6;
+ __u32 dalpha_clip_val:9;
+ __u32 reserved2:1;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_chnr_config - Chroma noise reduction config
+ *
+ * @enable: chroma noise reduction enable, see
+ * &ipu3_uapi_yuvp1_chnr_enable_config
+ * @coring: coring config for chroma noise reduction, see
+ * &ipu3_uapi_yuvp1_chnr_coring_config
+ * @sense_gain: sensitivity config for chroma noise reduction, see
+ * ipu3_uapi_yuvp1_chnr_sense_gain_config
+ * @iir_fir: iir and fir config for chroma noise reduction, see
+ * ipu3_uapi_yuvp1_chnr_iir_fir_config
+ */
+struct ipu3_uapi_yuvp1_chnr_config {
+ struct ipu3_uapi_yuvp1_chnr_enable_config enable;
+ struct ipu3_uapi_yuvp1_chnr_coring_config coring;
+ struct ipu3_uapi_yuvp1_chnr_sense_gain_config sense_gain;
+ struct ipu3_uapi_yuvp1_chnr_iir_fir_config iir_fir;
+} __packed;
+
+/* Edge Enhancement and Noise Reduction */
+
+/**
+ * struct ipu3_uapi_yuvp1_y_ee_nr_lpf_config - Luma(Y) edge enhancement low-pass
+ * filter coefficients
+ *
+ * @a_diag: Smoothing diagonal coefficient, u5.0.
+ * @reserved0: reserved
+ * @a_periph: Image smoothing perpherial, u5.0.
+ * @reserved1: reserved
+ * @a_cent: Image Smoothing center coefficient, u5.0.
+ * @reserved2: reserved
+ * @enable: 0: Y_EE_NR disabled, output = input; 1: Y_EE_NR enabled.
+ */
+struct ipu3_uapi_yuvp1_y_ee_nr_lpf_config {
+ __u32 a_diag:5;
+ __u32 reserved0:3;
+ __u32 a_periph:5;
+ __u32 reserved1:3;
+ __u32 a_cent:5;
+ __u32 reserved2:9;
+ __u32 enable:1;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_y_ee_nr_sense_config - Luma(Y) edge enhancement
+ * noise reduction sensitivity gains
+ *
+ * @edge_sense_0: Sensitivity of edge in dark area. u13.0, default 8191.
+ * @reserved0: reserved
+ * @delta_edge_sense: Difference in the sensitivity of edges between
+ * the bright and dark areas. u13.0, default 0.
+ * @reserved1: reserved
+ * @corner_sense_0: Sensitivity of corner in dark area. u13.0, default 0.
+ * @reserved2: reserved
+ * @delta_corner_sense: Difference in the sensitivity of corners between
+ * the bright and dark areas. u13.0, default 8191.
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_yuvp1_y_ee_nr_sense_config {
+ __u32 edge_sense_0:13;
+ __u32 reserved0:3;
+ __u32 delta_edge_sense:13;
+ __u32 reserved1:3;
+ __u32 corner_sense_0:13;
+ __u32 reserved2:3;
+ __u32 delta_corner_sense:13;
+ __u32 reserved3:3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_y_ee_nr_gain_config - Luma(Y) edge enhancement
+ * noise reduction gain config
+ *
+ * @gain_pos_0: Gain for positive edge in dark area. u5.0, [0, 16], default 2.
+ * @reserved0: reserved
+ * @delta_gain_posi: Difference in the gain of edges between the bright and
+ * dark areas for positive edges. u5.0, [0, 16], default 0.
+ * @reserved1: reserved
+ * @gain_neg_0: Gain for negative edge in dark area. u5.0, [0, 16], default 8.
+ * @reserved2: reserved
+ * @delta_gain_neg: Difference in the gain of edges between the bright and
+ * dark areas for negative edges. u5.0, [0, 16], default 0.
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_yuvp1_y_ee_nr_gain_config {
+ __u32 gain_pos_0:5;
+ __u32 reserved0:3;
+ __u32 delta_gain_posi:5;
+ __u32 reserved1:3;
+ __u32 gain_neg_0:5;
+ __u32 reserved2:3;
+ __u32 delta_gain_neg:5;
+ __u32 reserved3:3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_y_ee_nr_clip_config - Luma(Y) edge enhancement
+ * noise reduction clipping config
+ *
+ * @clip_pos_0: Limit of positive edge in dark area
+ * u5, value [0, 16], default 8.
+ * @reserved0: reserved
+ * @delta_clip_posi: Difference in the limit of edges between the bright
+ * and dark areas for positive edges.
+ * u5, value [0, 16], default 8.
+ * @reserved1: reserved
+ * @clip_neg_0: Limit of negative edge in dark area
+ * u5, value [0, 16], default 8.
+ * @reserved2: reserved
+ * @delta_clip_neg: Difference in the limit of edges between the bright
+ * and dark areas for negative edges.
+ * u5, value [0, 16], default 8.
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_yuvp1_y_ee_nr_clip_config {
+ __u32 clip_pos_0:5;
+ __u32 reserved0:3;
+ __u32 delta_clip_posi:5;
+ __u32 reserved1:3;
+ __u32 clip_neg_0:5;
+ __u32 reserved2:3;
+ __u32 delta_clip_neg:5;
+ __u32 reserved3:3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_y_ee_nr_frng_config - Luma(Y) edge enhancement
+ * noise reduction fringe config
+ *
+ * @gain_exp: Common exponent of gains, u4, [0, 8], default 2.
+ * @reserved0: reserved
+ * @min_edge: Threshold for edge and smooth stitching, u13.
+ * @reserved1: reserved
+ * @lin_seg_param: Power of LinSeg, u4.
+ * @reserved2: reserved
+ * @t1: Parameter for enabling/disabling the edge enhancement, u1.0, [0, 1],
+ * default 1.
+ * @t2: Parameter for enabling/disabling the smoothing, u1.0, [0, 1],
+ * default 1.
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_yuvp1_y_ee_nr_frng_config {
+ __u32 gain_exp:4;
+ __u32 reserved0:28;
+ __u32 min_edge:13;
+ __u32 reserved1:3;
+ __u32 lin_seg_param:4;
+ __u32 reserved2:4;
+ __u32 t1:1;
+ __u32 t2:1;
+ __u32 reserved3:6;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_y_ee_nr_diag_config - Luma(Y) edge enhancement
+ * noise reduction diagonal config
+ *
+ * @diag_disc_g: Coefficient that prioritize diagonal edge direction on
+ * horizontal or vertical for final enhancement.
+ * u4.0, [1, 15], default 1.
+ * @reserved0: reserved
+ * @hvw_hor: Weight of horizontal/vertical edge enhancement for hv edge.
+ * u2.2, [1, 15], default 4.
+ * @dw_hor: Weight of diagonal edge enhancement for hv edge.
+ * u2.2, [1, 15], default 1.
+ * @hvw_diag: Weight of horizontal/vertical edge enhancement for diagonal edge.
+ * u2.2, [1, 15], default 1.
+ * @dw_diag: Weight of diagonal edge enhancement for diagonal edge.
+ * u2.2, [1, 15], default 4.
+ * @reserved1: reserved
+ */
+struct ipu3_uapi_yuvp1_y_ee_nr_diag_config {
+ __u32 diag_disc_g:4;
+ __u32 reserved0:4;
+ __u32 hvw_hor:4;
+ __u32 dw_hor:4;
+ __u32 hvw_diag:4;
+ __u32 dw_diag:4;
+ __u32 reserved1:8;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_y_ee_nr_fc_coring_config - Luma(Y) edge enhancement
+ * noise reduction false color correction (FCC) coring config
+ *
+ * @pos_0: Gain for positive edge in dark, u13.0, [0, 16], default 0.
+ * @reserved0: reserved
+ * @pos_delta: Gain for positive edge in bright, value: pos_0 + pos_delta <=16
+ * u13.0, default 0.
+ * @reserved1: reserved
+ * @neg_0: Gain for negative edge in dark area, u13.0, range [0, 16], default 0.
+ * @reserved2: reserved
+ * @neg_delta: Gain for negative edge in bright area. neg_0 + neg_delta <=16
+ * u13.0, default 0.
+ * @reserved3: reserved
+ *
+ * Coring is a simple soft thresholding technique.
+ */
+struct ipu3_uapi_yuvp1_y_ee_nr_fc_coring_config {
+ __u32 pos_0:13;
+ __u32 reserved0:3;
+ __u32 pos_delta:13;
+ __u32 reserved1:3;
+ __u32 neg_0:13;
+ __u32 reserved2:3;
+ __u32 neg_delta:13;
+ __u32 reserved3:3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp1_y_ee_nr_config - Edge enhancement and noise reduction
+ *
+ * @lpf: low-pass filter config. See &ipu3_uapi_yuvp1_y_ee_nr_lpf_config
+ * @sense: sensitivity config. See &ipu3_uapi_yuvp1_y_ee_nr_sense_config
+ * @gain: gain config as defined in &ipu3_uapi_yuvp1_y_ee_nr_gain_config
+ * @clip: clip config as defined in &ipu3_uapi_yuvp1_y_ee_nr_clip_config
+ * @frng: fringe config as defined in &ipu3_uapi_yuvp1_y_ee_nr_frng_config
+ * @diag: diagonal edge config. See &ipu3_uapi_yuvp1_y_ee_nr_diag_config
+ * @fc_coring: coring config for fringe control. See
+ * &ipu3_uapi_yuvp1_y_ee_nr_fc_coring_config
+ */
+struct ipu3_uapi_yuvp1_y_ee_nr_config {
+ struct ipu3_uapi_yuvp1_y_ee_nr_lpf_config lpf;
+ struct ipu3_uapi_yuvp1_y_ee_nr_sense_config sense;
+ struct ipu3_uapi_yuvp1_y_ee_nr_gain_config gain;
+ struct ipu3_uapi_yuvp1_y_ee_nr_clip_config clip;
+ struct ipu3_uapi_yuvp1_y_ee_nr_frng_config frng;
+ struct ipu3_uapi_yuvp1_y_ee_nr_diag_config diag;
+ struct ipu3_uapi_yuvp1_y_ee_nr_fc_coring_config fc_coring;
+} __packed;
+
+/* Total Color Correction */
+
+/**
+ * struct ipu3_uapi_yuvp2_tcc_gen_control_static_config - Total color correction
+ * general control config
+ *
+ * @en: 0 - TCC disabled. Output = input 1 - TCC enabled.
+ * @blend_shift: blend shift, Range[3, 4], default NA.
+ * @gain_according_to_y_only: 0: Gain is calculated according to YUV,
+ * 1: Gain is calculated according to Y only
+ * @reserved0: reserved
+ * @gamma: Final blending coefficients. Values[-16, 16], default NA.
+ * @reserved1: reserved
+ * @delta: Final blending coefficients. Values[-16, 16], default NA.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_yuvp2_tcc_gen_control_static_config {
+ __u32 en:1;
+ __u32 blend_shift:3;
+ __u32 gain_according_to_y_only:1;
+ __u32 reserved0:11;
+ __s32 gamma:5;
+ __u32 reserved1:3;
+ __s32 delta:5;
+ __u32 reserved2:3;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp2_tcc_macc_elem_static_config - Total color correction
+ * multi-axis color control (MACC) config
+ *
+ * @a: a coefficient for 2x2 MACC conversion matrix.
+ * @reserved0: reserved
+ * @b: b coefficient 2x2 MACC conversion matrix.
+ * @reserved1: reserved
+ * @c: c coefficient for 2x2 MACC conversion matrix.
+ * @reserved2: reserved
+ * @d: d coefficient for 2x2 MACC conversion matrix.
+ * @reserved3: reserved
+ */
+struct ipu3_uapi_yuvp2_tcc_macc_elem_static_config {
+ __s32 a:12;
+ __u32 reserved0:4;
+ __s32 b:12;
+ __u32 reserved1:4;
+ __s32 c:12;
+ __u32 reserved2:4;
+ __s32 d:12;
+ __u32 reserved3:4;
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp2_tcc_macc_table_static_config - Total color correction
+ * multi-axis color control (MACC) table array
+ *
+ * @entries: config for multi axis color correction, as specified by
+ * &ipu3_uapi_yuvp2_tcc_macc_elem_static_config
+ */
+struct ipu3_uapi_yuvp2_tcc_macc_table_static_config {
+ struct ipu3_uapi_yuvp2_tcc_macc_elem_static_config
+ entries[IPU3_UAPI_YUVP2_TCC_MACC_TABLE_ELEMENTS];
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp2_tcc_inv_y_lut_static_config - Total color correction
+ * inverse y lookup table
+ *
+ * @entries: lookup table for inverse y estimation, and use it to estimate the
+ * ratio between luma and chroma. Chroma by approximate the absolute
+ * value of the radius on the chroma plane (R = sqrt(u^2+v^2) ) and
+ * luma by approximate by 1/Y.
+ */
+struct ipu3_uapi_yuvp2_tcc_inv_y_lut_static_config {
+ __u16 entries[IPU3_UAPI_YUVP2_TCC_INV_Y_LUT_ELEMENTS];
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp2_tcc_gain_pcwl_lut_static_config - Total color
+ * correction lookup table for PCWL
+ *
+ * @entries: lookup table for gain piece wise linear transformation (PCWL)
+ */
+struct ipu3_uapi_yuvp2_tcc_gain_pcwl_lut_static_config {
+ __u16 entries[IPU3_UAPI_YUVP2_TCC_GAIN_PCWL_LUT_ELEMENTS];
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp2_tcc_r_sqr_lut_static_config - Total color correction
+ * lookup table for r square root
+ *
+ * @entries: lookup table for r square root estimation
+ */
+struct ipu3_uapi_yuvp2_tcc_r_sqr_lut_static_config {
+ __s16 entries[IPU3_UAPI_YUVP2_TCC_R_SQR_LUT_ELEMENTS];
+} __packed;
+
+/**
+ * struct ipu3_uapi_yuvp2_tcc_static_config- Total color correction static
+ *
+ * @gen_control: general config for Total Color Correction
+ * @macc_table: config for multi axis color correction
+ * @inv_y_lut: lookup table for inverse y estimation
+ * @gain_pcwl: lookup table for gain PCWL
+ * @r_sqr_lut: lookup table for r square root estimation.
+ */
+struct ipu3_uapi_yuvp2_tcc_static_config {
+ struct ipu3_uapi_yuvp2_tcc_gen_control_static_config gen_control;
+ struct ipu3_uapi_yuvp2_tcc_macc_table_static_config macc_table;
+ struct ipu3_uapi_yuvp2_tcc_inv_y_lut_static_config inv_y_lut;
+ struct ipu3_uapi_yuvp2_tcc_gain_pcwl_lut_static_config gain_pcwl;
+ struct ipu3_uapi_yuvp2_tcc_r_sqr_lut_static_config r_sqr_lut;
+} __packed;
+
+/* Advanced Noise Reduction related structs */
+
+/*
+ * struct ipu3_uapi_anr_alpha - Advanced noise reduction alpha
+ *
+ * Tunable parameters that are subject to modification according to the
+ * total gain used.
+ */
+struct ipu3_uapi_anr_alpha {
+ __u16 gr;
+ __u16 r;
+ __u16 b;
+ __u16 gb;
+ __u16 dc_gr;
+ __u16 dc_r;
+ __u16 dc_b;
+ __u16 dc_gb;
+} __packed;
+
+/*
+ * struct ipu3_uapi_anr_beta - Advanced noise reduction beta
+ *
+ * Tunable parameters that are subject to modification according to the
+ * total gain used.
+ */
+struct ipu3_uapi_anr_beta {
+ __u16 beta_gr;
+ __u16 beta_r;
+ __u16 beta_b;
+ __u16 beta_gb;
+} __packed;
+
+/*
+ * struct ipu3_uapi_anr_plane_color - Advanced noise reduction per plane R, Gr,
+ * Gb and B register settings
+ *
+ * Tunable parameters that are subject to modification according to the
+ * total gain used.
+ */
+struct ipu3_uapi_anr_plane_color {
+ __u16 reg_w_gr[16];
+ __u16 reg_w_r[16];
+ __u16 reg_w_b[16];
+ __u16 reg_w_gb[16];
+} __packed;
+
+/**
+ * struct ipu3_uapi_anr_transform_config - Advanced noise reduction transform
+ *
+ * @enable: advanced noise reduction enabled.
+ * @adaptive_treshhold_en: On IPU3, adaptive threshold is always enabled.
+ * @reserved1: reserved
+ * @reserved2: reserved
+ * @alpha: using following defaults:
+ * 13, 13, 13, 13, 0, 0, 0, 0
+ * 11, 11, 11, 11, 0, 0, 0, 0
+ * 14, 14, 14, 14, 0, 0, 0, 0
+ * @beta: use following defaults:
+ * 24, 24, 24, 24
+ * 21, 20, 20, 21
+ * 25, 25, 25, 25
+ * @color: use defaults defined in driver/media/pci/intel/ipu3-tables.c
+ * @sqrt_lut: 11 bits per element, values =
+ * [724 768 810 849 887
+ * 923 958 991 1024 1056
+ * 1116 1145 1173 1201 1086
+ * 1228 1254 1280 1305 1330
+ * 1355 1379 1402 1425 1448]
+ * @xreset: Reset value of X for r^2 calculation Value: col_start-X_center
+ * Constraint: Xreset + FrameWdith=4095 Xreset= -4095, default -1632.
+ * @reserved3: reserved
+ * @yreset: Reset value of Y for r^2 calculation Value: row_start-Y_center
+ * Constraint: Yreset + FrameHeight=4095 Yreset= -4095, default -1224.
+ * @reserved4: reserved
+ * @x_sqr_reset: Reset value of X^2 for r^2 calculation Value = (Xreset)^2
+ * @r_normfactor: Normalization factor for R. Default 14.
+ * @reserved5: reserved
+ * @y_sqr_reset: Reset value of Y^2 for r^2 calculation Value = (Yreset)^2
+ * @gain_scale: Parameter describing shading gain as a function of distance
+ * from the image center.
+ * A single value per frame, loaded by the driver. Default 115.
+ */
+struct ipu3_uapi_anr_transform_config {
+ __u32 enable:1; /* 0 or 1, disabled or enabled */
+ __u32 adaptive_treshhold_en:1; /* On IPU3, always enabled */
+
+ __u32 reserved1:30;
+ __u8 reserved2[44];
+
+ struct ipu3_uapi_anr_alpha alpha[3];
+ struct ipu3_uapi_anr_beta beta[3];
+ struct ipu3_uapi_anr_plane_color color[3];
+
+ __u16 sqrt_lut[IPU3_UAPI_ANR_LUT_SIZE]; /* 11 bits per element */
+
+ __s16 xreset:13;
+ __u16 reserved3:3;
+ __s16 yreset:13;
+ __u16 reserved4:3;
+
+ __u32 x_sqr_reset:24;
+ __u32 r_normfactor:5;
+ __u32 reserved5:3;
+
+ __u32 y_sqr_reset:24;
+ __u32 gain_scale:8;
+} __packed;
+
+/**
+ * struct ipu3_uapi_anr_stitch_pyramid - ANR stitch pyramid
+ *
+ * @entry0: pyramid LUT entry0, range [0x0, 0x3f]
+ * @entry1: pyramid LUT entry1, range [0x0, 0x3f]
+ * @entry2: pyramid LUT entry2, range [0x0, 0x3f]
+ * @reserved: reserved
+ */
+struct ipu3_uapi_anr_stitch_pyramid {
+ __u32 entry0:6;
+ __u32 entry1:6;
+ __u32 entry2:6;
+ __u32 reserved:14;
+} __packed;
+
+/**
+ * struct ipu3_uapi_anr_stitch_config - ANR stitch config
+ *
+ * @anr_stitch_en: enable stitch. Enabled with 1.
+ * @reserved: reserved
+ * @pyramid: pyramid table as defined by &ipu3_uapi_anr_stitch_pyramid
+ * default values:
+ * { 1, 3, 5 }, { 7, 7, 5 }, { 3, 1, 3 },
+ * { 9, 15, 21 }, { 21, 15, 9 }, { 3, 5, 15 },
+ * { 25, 35, 35 }, { 25, 15, 5 }, { 7, 21, 35 },
+ * { 49, 49, 35 }, { 21, 7, 7 }, { 21, 35, 49 },
+ * { 49, 35, 21 }, { 7, 5, 15 }, { 25, 35, 35 },
+ * { 25, 15, 5 }, { 3, 9, 15 }, { 21, 21, 15 },
+ * { 9, 3, 1 }, { 3, 5, 7 }, { 7, 5, 3}, { 1 }
+ */
+struct ipu3_uapi_anr_stitch_config {
+ __u32 anr_stitch_en;
+ __u8 reserved[44];
+ struct ipu3_uapi_anr_stitch_pyramid pyramid[IPU3_UAPI_ANR_PYRAMID_SIZE];
+} __packed;
+
+/**
+ * struct ipu3_uapi_anr_config - ANR config
+ *
+ * @transform: advanced noise reduction transform config as specified by
+ * &ipu3_uapi_anr_transform_config
+ * @stitch: create 4x4 patch from 4 surrounding 8x8 patches.
+ */
+struct ipu3_uapi_anr_config {
+ struct ipu3_uapi_anr_transform_config transform __attribute__((aligned(32)));
+ struct ipu3_uapi_anr_stitch_config stitch __attribute__((aligned(32)));
+} __packed;
+
+/**
+ * struct ipu3_uapi_acc_param - Accelerator cluster parameters
+ *
+ * ACC refers to the HW cluster containing all Fixed Functions (FFs). Each FF
+ * implements a specific algorithm.
+ *
+ * @bnr: parameters for bayer noise reduction static config. See
+ * &ipu3_uapi_bnr_static_config
+ * @green_disparity: disparity static config between gr and gb channel.
+ * See &ipu3_uapi_bnr_static_config_green_disparity
+ * @dm: de-mosaic config. See &ipu3_uapi_dm_config
+ * @ccm: color correction matrix. See &ipu3_uapi_ccm_mat_config
+ * @gamma: gamma correction config. See &ipu3_uapi_gamma_config
+ * @csc: color space conversion matrix. See &ipu3_uapi_csc_mat_config
+ * @cds: color down sample config. See &ipu3_uapi_cds_params
+ * @shd: lens shading correction config. See &ipu3_uapi_shd_config
+ * @iefd: Image enhancement filter and denoise config.
+ * &ipu3_uapi_yuvp1_iefd_config
+ * @yds_c0: y down scaler config. &ipu3_uapi_yuvp1_yds_config
+ * @chnr_c0: chroma noise reduction config. &ipu3_uapi_yuvp1_chnr_config
+ * @y_ee_nr: y edge enhancement and noise reduction config.
+ * &ipu3_uapi_yuvp1_y_ee_nr_config
+ * @yds: y down scaler config. See &ipu3_uapi_yuvp1_yds_config
+ * @chnr: chroma noise reduction config. See &ipu3_uapi_yuvp1_chnr_config
+ * @reserved1: reserved
+ * @yds2: y channel down scaler config. See &ipu3_uapi_yuvp1_yds_config
+ * @tcc: total color correction config as defined in struct
+ * &ipu3_uapi_yuvp2_tcc_static_config
+ * @reserved2: reserved
+ * @anr: advanced noise reduction config.See &ipu3_uapi_anr_config
+ * @awb_fr: AWB filter response config. See ipu3_uapi_awb_fr_config
+ * @ae: auto exposure config As specified by &ipu3_uapi_ae_config
+ * @af: auto focus config. As specified by &ipu3_uapi_af_config
+ * @awb: auto white balance config. As specified by &ipu3_uapi_awb_config
+ */
+struct ipu3_uapi_acc_param {
+ struct ipu3_uapi_bnr_static_config bnr;
+ struct ipu3_uapi_bnr_static_config_green_disparity
+ green_disparity __attribute__((aligned(32)));
+ struct ipu3_uapi_dm_config dm __attribute__((aligned(32)));
+ struct ipu3_uapi_ccm_mat_config ccm __attribute__((aligned(32)));
+ struct ipu3_uapi_gamma_config gamma __attribute__((aligned(32)));
+ struct ipu3_uapi_csc_mat_config csc __attribute__((aligned(32)));
+ struct ipu3_uapi_cds_params cds __attribute__((aligned(32)));
+ struct ipu3_uapi_shd_config shd __attribute__((aligned(32)));
+ struct ipu3_uapi_yuvp1_iefd_config iefd __attribute__((aligned(32)));
+ struct ipu3_uapi_yuvp1_yds_config yds_c0 __attribute__((aligned(32)));
+ struct ipu3_uapi_yuvp1_chnr_config chnr_c0 __attribute__((aligned(32)));
+ struct ipu3_uapi_yuvp1_y_ee_nr_config y_ee_nr __attribute__((aligned(32)));
+ struct ipu3_uapi_yuvp1_yds_config yds __attribute__((aligned(32)));
+ struct ipu3_uapi_yuvp1_chnr_config chnr __attribute__((aligned(32)));
+ struct ipu3_uapi_yuvp1_yds_config yds2 __attribute__((aligned(32)));
+ struct ipu3_uapi_yuvp2_tcc_static_config tcc __attribute__((aligned(32)));
+ struct ipu3_uapi_anr_config anr;
+ struct ipu3_uapi_awb_fr_config_s awb_fr;
+ struct ipu3_uapi_ae_config ae;
+ struct ipu3_uapi_af_config_s af;
+ struct ipu3_uapi_awb_config awb;
+} __packed;
+
+/**
+ * struct ipu3_uapi_isp_lin_vmem_params - Linearization parameters
+ *
+ * @lin_lutlow_gr: linearization look-up table for GR channel interpolation.
+ * @lin_lutlow_r: linearization look-up table for R channel interpolation.
+ * @lin_lutlow_b: linearization look-up table for B channel interpolation.
+ * @lin_lutlow_gb: linearization look-up table for GB channel interpolation.
+ * lin_lutlow_gr / lin_lutlow_r / lin_lutlow_b /
+ * lin_lutlow_gb <= LIN_MAX_VALUE - 1.
+ * @lin_lutdif_gr: lin_lutlow_gr[i+1] - lin_lutlow_gr[i].
+ * @lin_lutdif_r: lin_lutlow_r[i+1] - lin_lutlow_r[i].
+ * @lin_lutdif_b: lin_lutlow_b[i+1] - lin_lutlow_b[i].
+ * @lin_lutdif_gb: lin_lutlow_gb[i+1] - lin_lutlow_gb[i].
+ */
+struct ipu3_uapi_isp_lin_vmem_params {
+ __s16 lin_lutlow_gr[IPU3_UAPI_LIN_LUT_SIZE];
+ __s16 lin_lutlow_r[IPU3_UAPI_LIN_LUT_SIZE];
+ __s16 lin_lutlow_b[IPU3_UAPI_LIN_LUT_SIZE];
+ __s16 lin_lutlow_gb[IPU3_UAPI_LIN_LUT_SIZE];
+ __s16 lin_lutdif_gr[IPU3_UAPI_LIN_LUT_SIZE];
+ __s16 lin_lutdif_r[IPU3_UAPI_LIN_LUT_SIZE];
+ __s16 lin_lutdif_b[IPU3_UAPI_LIN_LUT_SIZE];
+ __s16 lin_lutdif_gb[IPU3_UAPI_LIN_LUT_SIZE];
+} __packed;
+
+/* Temporal Noise Reduction */
+
+/**
+ * struct ipu3_uapi_isp_tnr3_vmem_params - Temporal noise reduction vector
+ * memory parameters
+ *
+ * @slope: slope setting in interpolation curve for temporal noise reduction.
+ * @reserved1: reserved
+ * @sigma: knee point setting in interpolation curve for temporal
+ * noise reduction.
+ * @reserved2: reserved
+ */
+struct ipu3_uapi_isp_tnr3_vmem_params {
+ __u16 slope[IPU3_UAPI_ISP_TNR3_VMEM_LEN];
+ __u16 reserved1[IPU3_UAPI_ISP_VEC_ELEMS
+ - IPU3_UAPI_ISP_TNR3_VMEM_LEN];
+ __u16 sigma[IPU3_UAPI_ISP_TNR3_VMEM_LEN];
+ __u16 reserved2[IPU3_UAPI_ISP_VEC_ELEMS
+ - IPU3_UAPI_ISP_TNR3_VMEM_LEN];
+} __packed;
+
+/**
+ * struct ipu3_uapi_isp_tnr3_params - Temporal noise reduction v3 parameters
+ *
+ * @knee_y1: Knee point TNR3 assumes standard deviation of Y,U and
+ * V at Y1 are TnrY1_Sigma_Y, U and V.
+ * @knee_y2: Knee point TNR3 assumes standard deviation of Y,U and
+ * V at Y2 are TnrY2_Sigma_Y, U and V.
+ * @maxfb_y: Max feedback gain for Y
+ * @maxfb_u: Max feedback gain for U
+ * @maxfb_v: Max feedback gain for V
+ * @round_adj_y: rounding Adjust for Y
+ * @round_adj_u: rounding Adjust for U
+ * @round_adj_v: rounding Adjust for V
+ * @ref_buf_select: selection of the reference frame buffer to be used.
+ */
+struct ipu3_uapi_isp_tnr3_params {
+ __u32 knee_y1;
+ __u32 knee_y2;
+ __u32 maxfb_y;
+ __u32 maxfb_u;
+ __u32 maxfb_v;
+ __u32 round_adj_y;
+ __u32 round_adj_u;
+ __u32 round_adj_v;
+ __u32 ref_buf_select;
+} __packed;
+
+/* Extreme Noise Reduction version 3 */
+
+/**
+ * struct ipu3_uapi_isp_xnr3_vmem_params - Extreme noise reduction v3
+ * vector memory parameters
+ *
+ * @x: xnr3 parameters.
+ * @a: xnr3 parameters.
+ * @b: xnr3 parameters.
+ * @c: xnr3 parameters.
+ */
+struct ipu3_uapi_isp_xnr3_vmem_params {
+ __u16 x[IPU3_UAPI_ISP_VEC_ELEMS];
+ __u16 a[IPU3_UAPI_ISP_VEC_ELEMS];
+ __u16 b[IPU3_UAPI_ISP_VEC_ELEMS];
+ __u16 c[IPU3_UAPI_ISP_VEC_ELEMS];
+} __packed;
+
+/**
+ * struct ipu3_uapi_xnr3_alpha_params - Extreme noise reduction v3
+ * alpha tuning parameters
+ *
+ * @y0: Sigma for Y range similarity in dark area.
+ * @u0: Sigma for U range similarity in dark area.
+ * @v0: Sigma for V range similarity in dark area.
+ * @ydiff: Sigma difference for Y between bright area and dark area.
+ * @udiff: Sigma difference for U between bright area and dark area.
+ * @vdiff: Sigma difference for V between bright area and dark area.
+ */
+struct ipu3_uapi_xnr3_alpha_params {
+ __u32 y0;
+ __u32 u0;
+ __u32 v0;
+ __u32 ydiff;
+ __u32 udiff;
+ __u32 vdiff;
+} __packed;
+
+/**
+ * struct ipu3_uapi_xnr3_coring_params - Extreme noise reduction v3
+ * coring parameters
+ *
+ * @u0: Coring Threshold of U channel in dark area.
+ * @v0: Coring Threshold of V channel in dark area.
+ * @udiff: Threshold difference of U channel between bright and dark area.
+ * @vdiff: Threshold difference of V channel between bright and dark area.
+ */
+struct ipu3_uapi_xnr3_coring_params {
+ __u32 u0;
+ __u32 v0;
+ __u32 udiff;
+ __u32 vdiff;
+} __packed;
+
+/**
+ * struct ipu3_uapi_xnr3_blending_params - Blending factor
+ *
+ * @strength: The factor for blending output with input. This is tuning
+ * parameterHigher values lead to more aggressive XNR operation.
+ */
+struct ipu3_uapi_xnr3_blending_params {
+ __u32 strength;
+} __packed;
+
+/**
+ * struct ipu3_uapi_isp_xnr3_params - Extreme noise reduction v3 parameters
+ *
+ * @alpha: parameters for xnr3 alpha. See &ipu3_uapi_xnr3_alpha_params
+ * @coring: parameters for xnr3 coring. See &ipu3_uapi_xnr3_coring_params
+ * @blending: parameters for xnr3 blending. See &ipu3_uapi_xnr3_blending_params
+ */
+struct ipu3_uapi_isp_xnr3_params {
+ struct ipu3_uapi_xnr3_alpha_params alpha;
+ struct ipu3_uapi_xnr3_coring_params coring;
+ struct ipu3_uapi_xnr3_blending_params blending;
+} __packed;
+
+/***** Obgrid (optical black level compensation) table entry *****/
+
+/**
+ * struct ipu3_uapi_obgrid_param - Optical black level compensation parameters
+ *
+ * @gr: Grid table values for color GR
+ * @r: Grid table values for color R
+ * @b: Grid table values for color B
+ * @gb: Grid table values for color GB
+ *
+ * Black level is different for red, green, and blue channels. So black level
+ * compensation is different per channel.
+ */
+struct ipu3_uapi_obgrid_param {
+ __u16 gr;
+ __u16 r;
+ __u16 b;
+ __u16 gb;
+} __packed;
+
+/******************* V4L2_META_FMT_IPU3_PARAMS *******************/
+
+/**
+ * struct ipu3_uapi_flags - bits to indicate which pipeline needs update
+ *
+ * @gdc: 0 = no update, 1 = update.
+ * @obgrid: 0 = no update, 1 = update.
+ * @reserved1: Not used.
+ * @acc_bnr: 0 = no update, 1 = update.
+ * @acc_green_disparity: 0 = no update, 1 = update.
+ * @acc_dm: 0 = no update, 1 = update.
+ * @acc_ccm: 0 = no update, 1 = update.
+ * @acc_gamma: 0 = no update, 1 = update.
+ * @acc_csc: 0 = no update, 1 = update.
+ * @acc_cds: 0 = no update, 1 = update.
+ * @acc_shd: 0 = no update, 1 = update.
+ * @reserved2: Not used.
+ * @acc_iefd: 0 = no update, 1 = update.
+ * @acc_yds_c0: 0 = no update, 1 = update.
+ * @acc_chnr_c0: 0 = no update, 1 = update.
+ * @acc_y_ee_nr: 0 = no update, 1 = update.
+ * @acc_yds: 0 = no update, 1 = update.
+ * @acc_chnr: 0 = no update, 1 = update.
+ * @acc_ytm: 0 = no update, 1 = update.
+ * @acc_yds2: 0 = no update, 1 = update.
+ * @acc_tcc: 0 = no update, 1 = update.
+ * @acc_dpc: 0 = no update, 1 = update.
+ * @acc_bds: 0 = no update, 1 = update.
+ * @acc_anr: 0 = no update, 1 = update.
+ * @acc_awb_fr: 0 = no update, 1 = update.
+ * @acc_ae: 0 = no update, 1 = update.
+ * @acc_af: 0 = no update, 1 = update.
+ * @acc_awb: 0 = no update, 1 = update.
+ * @__acc_osys: 0 = no update, 1 = update.
+ * @reserved3: Not used.
+ * @lin_vmem_params: 0 = no update, 1 = update.
+ * @tnr3_vmem_params: 0 = no update, 1 = update.
+ * @xnr3_vmem_params: 0 = no update, 1 = update.
+ * @tnr3_dmem_params: 0 = no update, 1 = update.
+ * @xnr3_dmem_params: 0 = no update, 1 = update.
+ * @reserved4: Not used.
+ * @obgrid_param: 0 = no update, 1 = update.
+ * @reserved5: Not used.
+ */
+struct ipu3_uapi_flags {
+ __u32 gdc:1;
+ __u32 obgrid:1;
+ __u32 reserved1:30;
+
+ __u32 acc_bnr:1;
+ __u32 acc_green_disparity:1;
+ __u32 acc_dm:1;
+ __u32 acc_ccm:1;
+ __u32 acc_gamma:1;
+ __u32 acc_csc:1;
+ __u32 acc_cds:1;
+ __u32 acc_shd:1;
+ __u32 reserved2:2;
+ __u32 acc_iefd:1;
+ __u32 acc_yds_c0:1;
+ __u32 acc_chnr_c0:1;
+ __u32 acc_y_ee_nr:1;
+ __u32 acc_yds:1;
+ __u32 acc_chnr:1;
+ __u32 acc_ytm:1;
+ __u32 acc_yds2:1;
+ __u32 acc_tcc:1;
+ __u32 acc_dpc:1;
+ __u32 acc_bds:1;
+ __u32 acc_anr:1;
+ __u32 acc_awb_fr:1;
+ __u32 acc_ae:1;
+ __u32 acc_af:1;
+ __u32 acc_awb:1;
+ __u32 reserved3:4;
+
+ __u32 lin_vmem_params:1;
+ __u32 tnr3_vmem_params:1;
+ __u32 xnr3_vmem_params:1;
+ __u32 tnr3_dmem_params:1;
+ __u32 xnr3_dmem_params:1;
+ __u32 reserved4:1;
+ __u32 obgrid_param:1;
+ __u32 reserved5:25;
+} __packed;
+
+/**
+ * struct ipu3_uapi_params - V4L2_META_FMT_IPU3_PARAMS
+ *
+ * @use: select which parameters to apply, see &ipu3_uapi_flags
+ * @acc_param: ACC parameters, as specified by &ipu3_uapi_acc_param
+ * @lin_vmem_params: linearization VMEM, as specified by
+ * &ipu3_uapi_isp_lin_vmem_params
+ * @tnr3_vmem_params: tnr3 VMEM as specified by
+ * &ipu3_uapi_isp_tnr3_vmem_params
+ * @xnr3_vmem_params: xnr3 VMEM as specified by
+ * &ipu3_uapi_isp_xnr3_vmem_params
+ * @tnr3_dmem_params: tnr3 DMEM as specified by &ipu3_uapi_isp_tnr3_params
+ * @xnr3_dmem_params: xnr3 DMEM as specified by &ipu3_uapi_isp_xnr3_params
+ * @obgrid_param: obgrid parameters as specified by
+ * &ipu3_uapi_obgrid_param
+ *
+ * The video queue "parameters" is of format V4L2_META_FMT_IPU3_PARAMS.
+ * This is a "single plane" v4l2_meta_format using V4L2_BUF_TYPE_META_OUTPUT.
+ *
+ * struct ipu3_uapi_params as defined below contains a lot of parameters and
+ * ipu3_uapi_flags selects which parameters to apply.
+ */
+struct ipu3_uapi_params {
+ /* Flags which of the settings below are to be applied */
+ struct ipu3_uapi_flags use __attribute__((aligned(32)));
+
+ /* Accelerator cluster parameters */
+ struct ipu3_uapi_acc_param acc_param;
+
+ /* ISP vector address space parameters */
+ struct ipu3_uapi_isp_lin_vmem_params lin_vmem_params;
+ struct ipu3_uapi_isp_tnr3_vmem_params tnr3_vmem_params;
+ struct ipu3_uapi_isp_xnr3_vmem_params xnr3_vmem_params;
+
+ /* ISP data memory (DMEM) parameters */
+ struct ipu3_uapi_isp_tnr3_params tnr3_dmem_params;
+ struct ipu3_uapi_isp_xnr3_params xnr3_dmem_params;
+
+ /* Optical black level compensation */
+ struct ipu3_uapi_obgrid_param obgrid_param;
+} __packed;
+
+#endif /* __IPU3_UAPI_H */
diff --git a/drivers/staging/media/ipu3/ipu3-abi.h b/drivers/staging/media/ipu3/ipu3-abi.h
new file mode 100644
index 000000000000..25be56ff01c8
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-abi.h
@@ -0,0 +1,2011 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 Intel Corporation */
+
+#ifndef __IPU3_ABI_H
+#define __IPU3_ABI_H
+
+#include "include/intel-ipu3.h"
+
+/******************* IMGU Hardware information *******************/
+
+typedef u32 imgu_addr_t;
+
+#define IMGU_ISP_VMEM_ALIGN 128
+#define IMGU_DVS_BLOCK_W 64
+#define IMGU_DVS_BLOCK_H 32
+#define IMGU_GDC_BUF_X (2 * IMGU_DVS_BLOCK_W)
+#define IMGU_GDC_BUF_Y IMGU_DVS_BLOCK_H
+/* n = 0..1 */
+#define IMGU_SP_PMEM_BASE(n) (0x20000 + (n) * 0x4000)
+#define IMGU_MAX_BQ_GRID_WIDTH 80
+#define IMGU_MAX_BQ_GRID_HEIGHT 60
+#define IMGU_OBGRID_TILE_SIZE 16
+#define IMGU_PIXELS_PER_WORD 50
+#define IMGU_BYTES_PER_WORD 64
+#define IMGU_STRIPE_FIXED_HALF_OVERLAP 2
+#define IMGU_SHD_SETS 3
+#define IMGU_BDS_MIN_CLIP_VAL 0
+#define IMGU_BDS_MAX_CLIP_VAL 2
+
+#define IMGU_ABI_AWB_MAX_CELLS_PER_SET 160
+#define IMGU_ABI_AF_MAX_CELLS_PER_SET 32
+#define IMGU_ABI_AWB_FR_MAX_CELLS_PER_SET 32
+
+#define IMGU_ABI_ACC_OP_IDLE 0
+#define IMGU_ABI_ACC_OP_END_OF_ACK 1
+#define IMGU_ABI_ACC_OP_END_OF_OPS 2
+#define IMGU_ABI_ACC_OP_NO_OPS 3
+
+#define IMGU_ABI_ACC_OPTYPE_PROCESS_LINES 0
+#define IMGU_ABI_ACC_OPTYPE_TRANSFER_DATA 1
+
+/* Register definitions */
+
+/* PM_CTRL_0_5_0_IMGHMMADR */
+#define IMGU_REG_PM_CTRL 0x0
+#define IMGU_PM_CTRL_START BIT(0)
+#define IMGU_PM_CTRL_CFG_DONE BIT(1)
+#define IMGU_PM_CTRL_RACE_TO_HALT BIT(2)
+#define IMGU_PM_CTRL_NACK_ALL BIT(3)
+#define IMGU_PM_CTRL_CSS_PWRDN BIT(4)
+#define IMGU_PM_CTRL_RST_AT_EOF BIT(5)
+#define IMGU_PM_CTRL_FORCE_HALT BIT(6)
+#define IMGU_PM_CTRL_FORCE_UNHALT BIT(7)
+#define IMGU_PM_CTRL_FORCE_PWRDN BIT(8)
+#define IMGU_PM_CTRL_FORCE_RESET BIT(9)
+
+/* SYSTEM_REQ_0_5_0_IMGHMMADR */
+#define IMGU_REG_SYSTEM_REQ 0x18
+#define IMGU_SYSTEM_REQ_FREQ_MASK 0x3f
+#define IMGU_SYSTEM_REQ_FREQ_DIVIDER 25
+#define IMGU_REG_INT_STATUS 0x30
+#define IMGU_REG_INT_ENABLE 0x34
+#define IMGU_REG_INT_CSS_IRQ BIT(31)
+/* STATE_0_5_0_IMGHMMADR */
+#define IMGU_REG_STATE 0x130
+#define IMGU_STATE_HALT_STS BIT(0)
+#define IMGU_STATE_IDLE_STS BIT(1)
+#define IMGU_STATE_POWER_UP BIT(2)
+#define IMGU_STATE_POWER_DOWN BIT(3)
+#define IMGU_STATE_CSS_BUSY_MASK 0xc0
+#define IMGU_STATE_PM_FSM_MASK 0x180
+#define IMGU_STATE_PWRDNM_FSM_MASK 0x1E00000
+/* PM_STS_0_5_0_IMGHMMADR */
+#define IMGU_REG_PM_STS 0x140
+
+#define IMGU_REG_BASE 0x4000
+
+#define IMGU_REG_ISP_CTRL (IMGU_REG_BASE + 0x00)
+#define IMGU_CTRL_RST BIT(0)
+#define IMGU_CTRL_START BIT(1)
+#define IMGU_CTRL_BREAK BIT(2)
+#define IMGU_CTRL_RUN BIT(3)
+#define IMGU_CTRL_BROKEN BIT(4)
+#define IMGU_CTRL_IDLE BIT(5)
+#define IMGU_CTRL_SLEEPING BIT(6)
+#define IMGU_CTRL_STALLING BIT(7)
+#define IMGU_CTRL_IRQ_CLEAR BIT(8)
+#define IMGU_CTRL_IRQ_READY BIT(10)
+#define IMGU_CTRL_IRQ_SLEEPING BIT(11)
+#define IMGU_CTRL_ICACHE_INV BIT(12)
+#define IMGU_CTRL_IPREFETCH_EN BIT(13)
+#define IMGU_REG_ISP_START_ADDR (IMGU_REG_BASE + 0x04)
+#define IMGU_REG_ISP_ICACHE_ADDR (IMGU_REG_BASE + 0x10)
+#define IMGU_REG_ISP_PC (IMGU_REG_BASE + 0x1c)
+
+/* SP Registers, sp = 0:SP0; 1:SP1 */
+#define IMGU_REG_SP_CTRL(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x100)
+ /* For bits in IMGU_REG_SP_CTRL, see IMGU_CTRL_* */
+#define IMGU_REG_SP_START_ADDR(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x104)
+#define IMGU_REG_SP_ICACHE_ADDR(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x11c)
+#define IMGU_REG_SP_CTRL_SINK(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x130)
+#define IMGU_REG_SP_PC(sp) (IMGU_REG_BASE + (sp) * 0x100 + 0x134)
+
+#define IMGU_REG_TLB_INVALIDATE (IMGU_REG_BASE + 0x300)
+#define IMGU_TLB_INVALIDATE 1
+#define IMGU_REG_L1_PHYS (IMGU_REG_BASE + 0x304) /* 27-bit pfn */
+
+#define IMGU_REG_CIO_GATE_BURST_STATE (IMGU_REG_BASE + 0x404)
+#define IMGU_CIO_GATE_BURST_MASK 0x80
+
+#define IMGU_REG_GP_BUSY (IMGU_REG_BASE + 0x500)
+#define IMGU_REG_GP_STARVING (IMGU_REG_BASE + 0x504)
+#define IMGU_REG_GP_WORKLOAD (IMGU_REG_BASE + 0x508)
+#define IMGU_REG_GP_IRQ(n) (IMGU_REG_BASE + (n) * 4 + 0x50c) /* n = 0..4 */
+#define IMGU_REG_GP_SP1_STRMON_STAT (IMGU_REG_BASE + 0x520)
+#define IMGU_REG_GP_SP2_STRMON_STAT (IMGU_REG_BASE + 0x524)
+#define IMGU_REG_GP_ISP_STRMON_STAT (IMGU_REG_BASE + 0x528)
+#define IMGU_REG_GP_MOD_STRMON_STAT (IMGU_REG_BASE + 0x52c)
+
+/* Port definitions for the streaming monitors. */
+/* For each definition there is signal pair : valid [bit 0]- accept [bit 1] */
+#define IMGU_GP_STRMON_STAT_SP1_PORT_SP12DMA BIT(0)
+#define IMGU_GP_STRMON_STAT_SP1_PORT_DMA2SP1 BIT(2)
+#define IMGU_GP_STRMON_STAT_SP1_PORT_SP12SP2 BIT(4)
+#define IMGU_GP_STRMON_STAT_SP1_PORT_SP22SP1 BIT(6)
+#define IMGU_GP_STRMON_STAT_SP1_PORT_SP12ISP BIT(8)
+#define IMGU_GP_STRMON_STAT_SP1_PORT_ISP2SP1 BIT(10)
+
+#define IMGU_GP_STRMON_STAT_SP2_PORT_SP22DMA BIT(0)
+#define IMGU_GP_STRMON_STAT_SP2_PORT_DMA2SP2 BIT(2)
+#define IMGU_GP_STRMON_STAT_SP2_PORT_SP22SP1 BIT(4)
+#define IMGU_GP_STRMON_STAT_SP2_PORT_SP12SP2 BIT(6)
+
+#define IMGU_GP_STRMON_STAT_ISP_PORT_ISP2DMA BIT(0)
+#define IMGU_GP_STRMON_STAT_ISP_PORT_DMA2ISP BIT(2)
+#define IMGU_GP_STRMON_STAT_ISP_PORT_ISP2SP1 BIT(4)
+#define IMGU_GP_STRMON_STAT_ISP_PORT_SP12ISP BIT(6)
+
+/* Between the devices and the fifo */
+#define IMGU_GP_STRMON_STAT_MOD_PORT_SP12DMA BIT(0)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_DMA2SP1 BIT(2)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_SP22DMA BIT(4)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_DMA2SP2 BIT(6)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_ISP2DMA BIT(8)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_DMA2ISP BIT(10)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_CELLS2GDC BIT(12)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_GDC2CELLS BIT(14)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_CELLS2DECOMP BIT(16)
+#define IMGU_GP_STRMON_STAT_MOD_PORT_DECOMP2CELLS BIT(18)
+/* n = 1..6 */
+#define IMGU_GP_STRMON_STAT_MOD_PORT_S2V(n) (1 << (((n) - 1) * 2 + 20))
+
+/* n = 1..15 */
+#define IMGU_GP_STRMON_STAT_ACCS_PORT_ACC(n) (1 << (((n) - 1) * 2))
+
+/* After FIFO and demux before SP1, n = 1..15 */
+#define IMGU_GP_STRMON_STAT_ACCS2SP1_MON_PORT_ACC(n) (1 << (((n) - 1) * 2))
+
+/* After FIFO and demux before SP2, n = 1..15 */
+#define IMGU_GP_STRMON_STAT_ACCS2SP2_MON_PORT_ACC(n) (1 << (((n) - 1) * 2))
+
+#define IMGU_REG_GP_HALT (IMGU_REG_BASE + 0x5dc)
+
+ /* n = 0..2 (main ctrl, SP0, SP1) */
+#define IMGU_REG_IRQCTRL_BASE(n) (IMGU_REG_BASE + (n) * 0x100 + 0x700)
+#define IMGU_IRQCTRL_MAIN 0
+#define IMGU_IRQCTRL_SP0 1
+#define IMGU_IRQCTRL_SP1 2
+#define IMGU_IRQCTRL_NUM 3
+#define IMGU_IRQCTRL_IRQ_SP1 BIT(0)
+#define IMGU_IRQCTRL_IRQ_SP2 BIT(1)
+#define IMGU_IRQCTRL_IRQ_ISP BIT(2)
+#define IMGU_IRQCTRL_IRQ_SP1_STREAM_MON BIT(3)
+#define IMGU_IRQCTRL_IRQ_SP2_STREAM_MON BIT(4)
+#define IMGU_IRQCTRL_IRQ_ISP_STREAM_MON BIT(5)
+#define IMGU_IRQCTRL_IRQ_MOD_STREAM_MON BIT(6)
+#define IMGU_IRQCTRL_IRQ_MOD_ISP_STREAM_MON BIT(7)
+#define IMGU_IRQCTRL_IRQ_ACCS_STREAM_MON BIT(8)
+#define IMGU_IRQCTRL_IRQ_ACCS_SP1_STREAM_MON BIT(9)
+#define IMGU_IRQCTRL_IRQ_ACCS_SP2_STREAM_MON BIT(10)
+#define IMGU_IRQCTRL_IRQ_ISP_PMEM_ERROR BIT(11)
+#define IMGU_IRQCTRL_IRQ_ISP_BAMEM_ERROR BIT(12)
+#define IMGU_IRQCTRL_IRQ_ISP_VMEM_ERROR BIT(13)
+#define IMGU_IRQCTRL_IRQ_ISP_DMEM_ERROR BIT(14)
+#define IMGU_IRQCTRL_IRQ_SP1_ICACHE_MEM_ERROR BIT(15)
+#define IMGU_IRQCTRL_IRQ_SP1_DMEM_ERROR BIT(16)
+#define IMGU_IRQCTRL_IRQ_SP2_ICACHE_MEM_ERROR BIT(17)
+#define IMGU_IRQCTRL_IRQ_SP2_DMEM_ERROR BIT(18)
+#define IMGU_IRQCTRL_IRQ_ACCS_SCRATCH_MEM_ERROR BIT(19)
+#define IMGU_IRQCTRL_IRQ_GP_TIMER(n) BIT(20 + (n)) /* n=0..1 */
+#define IMGU_IRQCTRL_IRQ_DMA BIT(22)
+#define IMGU_IRQCTRL_IRQ_SW_PIN(n) BIT(23 + (n)) /* n=0..4 */
+#define IMGU_IRQCTRL_IRQ_ACC_SYS BIT(28)
+#define IMGU_IRQCTRL_IRQ_OUT_FORM_IRQ_CTRL BIT(29)
+#define IMGU_IRQCTRL_IRQ_SP1_IRQ_CTRL BIT(30)
+#define IMGU_IRQCTRL_IRQ_SP2_IRQ_CTRL BIT(31)
+#define IMGU_REG_IRQCTRL_EDGE(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x00)
+#define IMGU_REG_IRQCTRL_MASK(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x04)
+#define IMGU_REG_IRQCTRL_STATUS(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x08)
+#define IMGU_REG_IRQCTRL_CLEAR(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x0c)
+#define IMGU_REG_IRQCTRL_ENABLE(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x10)
+#define IMGU_REG_IRQCTRL_EDGE_NOT_PULSE(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x14)
+#define IMGU_REG_IRQCTRL_STR_OUT_ENABLE(n) (IMGU_REG_IRQCTRL_BASE(n) + 0x18)
+
+#define IMGU_REG_GP_TIMER (IMGU_REG_BASE + 0xa34)
+
+#define IMGU_REG_SP_DMEM_BASE(n) (IMGU_REG_BASE + (n) * 0x4000 + 0x4000)
+#define IMGU_REG_ISP_DMEM_BASE (IMGU_REG_BASE + 0xc000)
+
+#define IMGU_REG_GDC_BASE (IMGU_REG_BASE + 0x18000)
+#define IMGU_REG_GDC_LUT_BASE (IMGU_REG_GDC_BASE + 0x140)
+#define IMGU_GDC_LUT_MASK ((1 << 12) - 1) /* Range -1024..+1024 */
+
+#define IMGU_SCALER_PHASES 32
+#define IMGU_SCALER_COEFF_BITS 24
+#define IMGU_SCALER_PHASE_COUNTER_PREC_REF 6
+#define IMGU_SCALER_MAX_EXPONENT_SHIFT 3
+#define IMGU_SCALER_FILTER_TAPS 4
+#define IMGU_SCALER_TAPS_Y IMGU_SCALER_FILTER_TAPS
+#define IMGU_SCALER_TAPS_UV (IMGU_SCALER_FILTER_TAPS / 2)
+#define IMGU_SCALER_FIR_PHASES \
+ (IMGU_SCALER_PHASES << IMGU_SCALER_PHASE_COUNTER_PREC_REF)
+
+/******************* imgu_abi_acc_param *******************/
+
+#define IMGU_ABI_SHD_MAX_PROCESS_LINES 31
+#define IMGU_ABI_SHD_MAX_TRANSFERS 31
+#define IMGU_ABI_SHD_MAX_OPERATIONS \
+ (IMGU_ABI_SHD_MAX_PROCESS_LINES + IMGU_ABI_SHD_MAX_TRANSFERS)
+#define IMGU_ABI_SHD_MAX_CELLS_PER_SET 146
+/* largest grid is 73x56 */
+#define IMGU_ABI_SHD_MAX_CFG_SETS (2 * 28)
+
+#define IMGU_ABI_DVS_STAT_MAX_OPERATIONS 100
+#define IMGU_ABI_DVS_STAT_MAX_PROCESS_LINES 52
+#define IMGU_ABI_DVS_STAT_MAX_TRANSFERS 52
+
+#define IMGU_ABI_BDS_SAMPLE_PATTERN_ARRAY_SIZE 8
+#define IMGU_ABI_BDS_PHASE_COEFFS_ARRAY_SIZE 32
+
+#define IMGU_ABI_AWB_FR_MAX_TRANSFERS 30
+#define IMGU_ABI_AWB_FR_MAX_PROCESS_LINES 30
+#define IMGU_ABI_AWB_FR_MAX_OPERATIONS \
+ (IMGU_ABI_AWB_FR_MAX_TRANSFERS + IMGU_ABI_AWB_FR_MAX_PROCESS_LINES)
+
+#define IMGU_ABI_AF_MAX_TRANSFERS 30
+#define IMGU_ABI_AF_MAX_PROCESS_LINES 30
+#define IMGU_ABI_AF_MAX_OPERATIONS \
+ (IMGU_ABI_AF_MAX_TRANSFERS + IMGU_ABI_AF_MAX_PROCESS_LINES)
+
+#define IMGU_ABI_AWB_MAX_PROCESS_LINES 68
+#define IMGU_ABI_AWB_MAX_TRANSFERS 68
+#define IMGU_ABI_AWB_MAX_OPERATIONS \
+ (IMGU_ABI_AWB_MAX_PROCESS_LINES + IMGU_ABI_AWB_MAX_TRANSFERS)
+
+#define IMGU_ABI_OSYS_PIN_VF 0
+#define IMGU_ABI_OSYS_PIN_OUT 1
+#define IMGU_ABI_OSYS_PINS 2
+
+#define IMGU_ABI_DVS_STAT_LEVELS 3
+#define IMGU_ABI_YUVP2_YTM_LUT_ENTRIES 256
+#define IMGU_ABI_GDC_FRAC_BITS 8
+#define IMGU_ABI_BINARY_MAX_OUTPUT_PORTS 2
+#define IMGU_ABI_MAX_BINARY_NAME 64
+#define IMGU_ABI_ISP_DDR_WORD_BITS 256
+#define IMGU_ABI_ISP_DDR_WORD_BYTES (IMGU_ABI_ISP_DDR_WORD_BITS / 8)
+#define IMGU_ABI_MAX_STAGES 3
+#define IMGU_ABI_MAX_IF_CONFIGS 3
+#define IMGU_ABI_PIPE_CONFIG_ACQUIRE_ISP BIT(31)
+#define IMGU_ABI_PORT_CONFIG_TYPE_INPUT_HOST BIT(0)
+#define IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_HOST BIT(4)
+#define IMGU_ABI_MAX_SP_THREADS 4
+#define IMGU_ABI_FRAMES_REF 3
+#define IMGU_ABI_FRAMES_TNR 4
+#define IMGU_ABI_BUF_SETS_TNR 1
+
+#define IMGU_ABI_EVENT_BUFFER_ENQUEUED(thread, queue) \
+ (0 << 24 | (thread) << 16 | (queue) << 8)
+#define IMGU_ABI_EVENT_BUFFER_DEQUEUED(queue) (1 << 24 | (queue) << 8)
+#define IMGU_ABI_EVENT_EVENT_DEQUEUED (2 << 24)
+#define IMGU_ABI_EVENT_START_STREAM (3 << 24)
+#define IMGU_ABI_EVENT_STOP_STREAM (4 << 24)
+#define IMGU_ABI_EVENT_MIPI_BUFFERS_READY (5 << 24)
+#define IMGU_ABI_EVENT_UNLOCK_RAW_BUFFER (6 << 24)
+#define IMGU_ABI_EVENT_STAGE_ENABLE_DISABLE (7 << 24)
+
+#define IMGU_ABI_HOST2SP_BUFQ_SIZE 3
+#define IMGU_ABI_SP2HOST_BUFQ_SIZE (2 * IMGU_ABI_MAX_SP_THREADS)
+#define IMGU_ABI_HOST2SP_EVTQ_SIZE (IMGU_ABI_QUEUE_NUM * \
+ IMGU_ABI_MAX_SP_THREADS * 2 + IMGU_ABI_MAX_SP_THREADS * 4)
+#define IMGU_ABI_SP2HOST_EVTQ_SIZE (6 * IMGU_ABI_MAX_SP_THREADS)
+
+#define IMGU_ABI_EVTTYPE_EVENT_SHIFT 0
+#define IMGU_ABI_EVTTYPE_EVENT_MASK (0xff << IMGU_ABI_EVTTYPE_EVENT_SHIFT)
+#define IMGU_ABI_EVTTYPE_PIPE_SHIFT 8
+#define IMGU_ABI_EVTTYPE_PIPE_MASK (0xff << IMGU_ABI_EVTTYPE_PIPE_SHIFT)
+#define IMGU_ABI_EVTTYPE_PIPEID_SHIFT 16
+#define IMGU_ABI_EVTTYPE_PIPEID_MASK (0xff << IMGU_ABI_EVTTYPE_PIPEID_SHIFT)
+#define IMGU_ABI_EVTTYPE_MODULEID_SHIFT 8
+#define IMGU_ABI_EVTTYPE_MODULEID_MASK (0xff << IMGU_ABI_EVTTYPE_MODULEID_SHIFT)
+#define IMGU_ABI_EVTTYPE_LINENO_SHIFT 16
+#define IMGU_ABI_EVTTYPE_LINENO_MASK (0xffff << IMGU_ABI_EVTTYPE_LINENO_SHIFT)
+
+/* Output frame ready */
+#define IMGU_ABI_EVTTYPE_OUT_FRAME_DONE 0
+/* Second output frame ready */
+#define IMGU_ABI_EVTTYPE_2ND_OUT_FRAME_DONE 1
+/* Viewfinder Output frame ready */
+#define IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE 2
+/* Second viewfinder Output frame ready */
+#define IMGU_ABI_EVTTYPE_2ND_VF_OUT_FRAME_DONE 3
+/* Indication that 3A statistics are available */
+#define IMGU_ABI_EVTTYPE_3A_STATS_DONE 4
+/* Indication that DIS statistics are available */
+#define IMGU_ABI_EVTTYPE_DIS_STATS_DONE 5
+/* Pipeline Done event, sent after last pipeline stage */
+#define IMGU_ABI_EVTTYPE_PIPELINE_DONE 6
+/* Frame tagged */
+#define IMGU_ABI_EVTTYPE_FRAME_TAGGED 7
+/* Input frame ready */
+#define IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE 8
+/* Metadata ready */
+#define IMGU_ABI_EVTTYPE_METADATA_DONE 9
+/* Indication that LACE statistics are available */
+#define IMGU_ABI_EVTTYPE_LACE_STATS_DONE 10
+/* Extension stage executed */
+#define IMGU_ABI_EVTTYPE_ACC_STAGE_COMPLETE 11
+/* Timing measurement data */
+#define IMGU_ABI_EVTTYPE_TIMER 12
+/* End Of Frame event, sent when in buffered sensor mode */
+#define IMGU_ABI_EVTTYPE_PORT_EOF 13
+/* Performance warning encountered by FW */
+#define IMGU_ABI_EVTTYPE_FW_WARNING 14
+/* Assertion hit by FW */
+#define IMGU_ABI_EVTTYPE_FW_ASSERT 15
+
+#define IMGU_ABI_NUM_CONTINUOUS_FRAMES 10
+#define IMGU_ABI_SP_COMM_COMMAND 0x00
+
+/*
+ * The host2sp_cmd_ready command is the only command written by the SP
+ * It acknowledges that is previous command has been received.
+ * (this does not mean that the command has been executed)
+ * It also indicates that a new command can be send (it is a queue
+ * with depth 1).
+ */
+#define IMGU_ABI_SP_COMM_COMMAND_READY 1
+/* Command written by the Host */
+#define IMGU_ABI_SP_COMM_COMMAND_DUMMY 2 /* No action */
+#define IMGU_ABI_SP_COMM_COMMAND_START_FLASH 3 /* Start the flash */
+#define IMGU_ABI_SP_COMM_COMMAND_TERMINATE 4 /* Terminate */
+
+/* n = 0..IPU3_CSS_PIPE_ID_NUM-1 */
+#define IMGU_ABI_SP_COMM_EVENT_IRQ_MASK(n) ((n) * 4 + 0x60)
+#define IMGU_ABI_SP_COMM_EVENT_IRQ_MASK_OR_SHIFT 0
+#define IMGU_ABI_SP_COMM_EVENT_IRQ_MASK_AND_SHIFT 16
+
+#define IMGU_ABI_BL_DMACMD_TYPE_SP_PMEM 1 /* sp_pmem */
+
+/***** For parameter computation *****/
+
+#define IMGU_HIVE_OF_SYS_SCALER_TO_FA_OFFSET 0xC
+#define IMGU_HIVE_OF_SYS_OF_TO_FA_OFFSET 0x8
+#define IMGU_HIVE_OF_SYS_OF_SYSTEM_NWAYS 32
+
+#define IMGU_SCALER_ELEMS_PER_VEC 0x10
+#define IMGU_SCALER_FILTER_TAPS_Y 0x4
+#define IMGU_SCALER_OUT_BPP 0x8
+
+#define IMGU_SCALER_MS_TO_OUTFORMACC_SL_ADDR 0x400
+#define IMGU_SCALER_TO_OF_ACK_FA_ADDR \
+ (0xC00 + IMGU_HIVE_OF_SYS_SCALER_TO_FA_OFFSET)
+#define IMGU_OF_TO_ACK_FA_ADDR (0xC00 + IMGU_HIVE_OF_SYS_OF_TO_FA_OFFSET)
+#define IMGU_OUTFORMACC_MS_TO_SCALER_SL_ADDR 0
+#define IMGU_SCALER_INTR_BPP 10
+
+#define IMGU_PS_SNR_PRESERVE_BITS 3
+#define IMGU_CNTX_BPP 11
+#define IMGU_SCALER_FILTER_TAPS_UV (IMGU_SCALER_FILTER_TAPS_Y / 2)
+
+#define IMGU_VMEM2_ELEMS_PER_VEC (IMGU_SCALER_ELEMS_PER_VEC)
+#define IMGU_STRIDE_Y (IMGU_SCALER_FILTER_TAPS_Y + 1)
+#define IMGU_MAX_FRAME_WIDTH 3840
+#define IMGU_VMEM3_ELEMS_PER_VEC (IMGU_SCALER_ELEMS_PER_VEC)
+
+#define IMGU_VER_CNTX_WORDS DIV_ROUND_UP((IMGU_SCALER_OUT_BPP + \
+ IMGU_PS_SNR_PRESERVE_BITS), IMGU_CNTX_BPP) /* 1 */
+#define IMGU_MAX_INPUT_BLOCK_HEIGHT 64
+#define IMGU_HOR_CNTX_WORDS DIV_ROUND_UP((IMGU_SCALER_INTR_BPP + \
+ IMGU_PS_SNR_PRESERVE_BITS), IMGU_CNTX_BPP) /* 2 */
+#define IMGU_MAX_OUTPUT_BLOCK_WIDTH 128
+#define IMGU_CNTX_STRIDE_UV (IMGU_SCALER_FILTER_TAPS_UV + 1)
+
+#define IMGU_OSYS_DMA_CROP_W_LIMIT 64
+#define IMGU_OSYS_DMA_CROP_H_LIMIT 4
+#define IMGU_OSYS_BLOCK_WIDTH (2 * IPU3_UAPI_ISP_VEC_ELEMS)
+#define IMGU_OSYS_BLOCK_HEIGHT 32
+#define IMGU_OSYS_PHASES 0x20
+#define IMGU_OSYS_FILTER_TAPS 0x4
+#define IMGU_OSYS_PHASE_COUNTER_PREC_REF 6
+#define IMGU_OSYS_NUM_INPUT_BUFFERS 2
+#define IMGU_OSYS_FIR_PHASES \
+ (IMGU_OSYS_PHASES << IMGU_OSYS_PHASE_COUNTER_PREC_REF)
+#define IMGU_OSYS_TAPS_UV (IMGU_OSYS_FILTER_TAPS / 2)
+#define IMGU_OSYS_TAPS_Y (IMGU_OSYS_FILTER_TAPS)
+#define IMGU_OSYS_NUM_INTERM_BUFFERS 2
+
+#define IMGU_VMEM1_Y_SIZE \
+ (IMGU_OSYS_BLOCK_HEIGHT * IMGU_VMEM1_Y_STRIDE)
+#define IMGU_VMEM1_UV_SIZE (IMGU_VMEM1_Y_SIZE / 4)
+#define IMGU_VMEM1_OUT_BUF_ADDR (IMGU_VMEM1_INP_BUF_ADDR + \
+ (IMGU_OSYS_NUM_INPUT_BUFFERS * IMGU_VMEM1_BUF_SIZE))
+#define IMGU_OSYS_NUM_OUTPUT_BUFFERS 2
+
+/* transpose of input height */
+#define IMGU_VMEM2_VECS_PER_LINE \
+ (DIV_ROUND_UP(IMGU_OSYS_BLOCK_HEIGHT, IMGU_VMEM2_ELEMS_PER_VEC))
+/* size in words (vectors) */
+#define IMGU_VMEM2_BUF_SIZE \
+ (IMGU_VMEM2_VECS_PER_LINE * IMGU_VMEM2_LINES_PER_BLOCK)
+#define IMGU_VMEM3_VER_Y_SIZE \
+ ((IMGU_STRIDE_Y * IMGU_MAX_FRAME_WIDTH \
+ / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS)
+#define IMGU_VMEM3_HOR_Y_SIZE \
+ ((IMGU_STRIDE_Y * IMGU_MAX_INPUT_BLOCK_HEIGHT \
+ / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_HOR_CNTX_WORDS)
+#define IMGU_VMEM3_VER_Y_EXTRA \
+ ((IMGU_STRIDE_Y * IMGU_MAX_OUTPUT_BLOCK_WIDTH \
+ / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS)
+#define IMGU_VMEM3_VER_U_SIZE \
+ (((IMGU_CNTX_STRIDE_UV * IMGU_MAX_FRAME_WIDTH \
+ / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS) / 2)
+#define IMGU_VMEM3_HOR_U_SIZE \
+ (((IMGU_STRIDE_Y * IMGU_MAX_INPUT_BLOCK_HEIGHT \
+ / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_HOR_CNTX_WORDS) / 2)
+#define IMGU_VMEM3_VER_U_EXTRA \
+ (((IMGU_CNTX_STRIDE_UV * IMGU_MAX_OUTPUT_BLOCK_WIDTH \
+ / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS) / 2)
+#define IMGU_VMEM3_VER_V_SIZE \
+ (((IMGU_CNTX_STRIDE_UV * IMGU_MAX_FRAME_WIDTH \
+ / IMGU_VMEM3_ELEMS_PER_VEC) * IMGU_VER_CNTX_WORDS) / 2)
+
+#define IMGU_ISP_VEC_NELEMS 64
+#define IMGU_LUMA_TO_CHROMA_RATIO 2
+#define IMGU_INPUT_BLOCK_WIDTH (128)
+#define IMGU_FIFO_ADDR_SCALER_TO_FMT \
+ (IMGU_SCALER_MS_TO_OUTFORMACC_SL_ADDR >> 2)
+#define IMGU_FIFO_ADDR_SCALER_TO_SP (IMGU_SCALER_TO_OF_ACK_FA_ADDR >> 2)
+#define IMGU_VMEM1_INP_BUF_ADDR 0
+#define IMGU_VMEM1_Y_STRIDE \
+ (IMGU_OSYS_BLOCK_WIDTH / IMGU_VMEM1_ELEMS_PER_VEC)
+#define IMGU_VMEM1_BUF_SIZE (IMGU_VMEM1_V_OFFSET + IMGU_VMEM1_UV_SIZE)
+
+#define IMGU_VMEM1_U_OFFSET (IMGU_VMEM1_Y_SIZE)
+#define IMGU_VMEM1_V_OFFSET (IMGU_VMEM1_U_OFFSET + IMGU_VMEM1_UV_SIZE)
+#define IMGU_VMEM1_UV_STRIDE (IMGU_VMEM1_Y_STRIDE / 2)
+#define IMGU_VMEM1_INT_BUF_ADDR (IMGU_VMEM1_OUT_BUF_ADDR + \
+ (IMGU_OSYS_NUM_OUTPUT_BUFFERS * IMGU_VMEM1_BUF_SIZE))
+
+#define IMGU_VMEM1_ELEMS_PER_VEC (IMGU_HIVE_OF_SYS_OF_SYSTEM_NWAYS)
+#define IMGU_VMEM2_BUF_Y_ADDR 0
+#define IMGU_VMEM2_BUF_Y_STRIDE (IMGU_VMEM2_VECS_PER_LINE)
+#define IMGU_VMEM2_BUF_U_ADDR \
+ (IMGU_VMEM2_BUF_Y_ADDR + IMGU_VMEM2_BUF_SIZE)
+#define IMGU_VMEM2_BUF_V_ADDR \
+ (IMGU_VMEM2_BUF_U_ADDR + IMGU_VMEM2_BUF_SIZE / 4)
+#define IMGU_VMEM2_BUF_UV_STRIDE (IMGU_VMEM2_VECS_PER_LINE / 2)
+/* 1.5 x depth of intermediate buffer */
+#define IMGU_VMEM2_LINES_PER_BLOCK 192
+#define IMGU_VMEM3_HOR_Y_ADDR \
+ (IMGU_VMEM3_VER_Y_ADDR + IMGU_VMEM3_VER_Y_SIZE)
+#define IMGU_VMEM3_HOR_U_ADDR \
+ (IMGU_VMEM3_VER_U_ADDR + IMGU_VMEM3_VER_U_SIZE)
+#define IMGU_VMEM3_HOR_V_ADDR \
+ (IMGU_VMEM3_VER_V_ADDR + IMGU_VMEM3_VER_V_SIZE)
+#define IMGU_VMEM3_VER_Y_ADDR 0
+#define IMGU_VMEM3_VER_U_ADDR \
+ (IMGU_VMEM3_VER_Y_ADDR + IMGU_VMEM3_VER_Y_SIZE + \
+ max(IMGU_VMEM3_HOR_Y_SIZE, IMGU_VMEM3_VER_Y_EXTRA))
+#define IMGU_VMEM3_VER_V_ADDR \
+ (IMGU_VMEM3_VER_U_ADDR + IMGU_VMEM3_VER_U_SIZE + \
+ max(IMGU_VMEM3_HOR_U_SIZE, IMGU_VMEM3_VER_U_EXTRA))
+#define IMGU_FIFO_ADDR_FMT_TO_SP (IMGU_OF_TO_ACK_FA_ADDR >> 2)
+#define IMGU_FIFO_ADDR_FMT_TO_SCALER (IMGU_OUTFORMACC_MS_TO_SCALER_SL_ADDR >> 2)
+#define IMGU_VMEM1_HST_BUF_ADDR (IMGU_VMEM1_INT_BUF_ADDR + \
+ (IMGU_OSYS_NUM_INTERM_BUFFERS * IMGU_VMEM1_BUF_SIZE))
+#define IMGU_VMEM1_HST_BUF_STRIDE 120
+#define IMGU_VMEM1_HST_BUF_NLINES 3
+
+enum imgu_abi_frame_format {
+ IMGU_ABI_FRAME_FORMAT_NV11, /* 12 bit YUV 411, Y, UV plane */
+ IMGU_ABI_FRAME_FORMAT_NV12, /* 12 bit YUV 420, Y, UV plane */
+ IMGU_ABI_FRAME_FORMAT_NV12_16, /* 16 bit YUV 420, Y, UV plane */
+ IMGU_ABI_FRAME_FORMAT_NV12_TILEY,/* 12 bit YUV 420,Intel tiled format */
+ IMGU_ABI_FRAME_FORMAT_NV16, /* 16 bit YUV 422, Y, UV plane */
+ IMGU_ABI_FRAME_FORMAT_NV21, /* 12 bit YUV 420, Y, VU plane */
+ IMGU_ABI_FRAME_FORMAT_NV61, /* 16 bit YUV 422, Y, VU plane */
+ IMGU_ABI_FRAME_FORMAT_YV12, /* 12 bit YUV 420, Y, V, U plane */
+ IMGU_ABI_FRAME_FORMAT_YV16, /* 16 bit YUV 422, Y, V, U plane */
+ IMGU_ABI_FRAME_FORMAT_YUV420, /* 12 bit YUV 420, Y, U, V plane */
+ IMGU_ABI_FRAME_FORMAT_YUV420_16,/* yuv420, 16 bits per subpixel */
+ IMGU_ABI_FRAME_FORMAT_YUV422, /* 16 bit YUV 422, Y, U, V plane */
+ IMGU_ABI_FRAME_FORMAT_YUV422_16,/* yuv422, 16 bits per subpixel */
+ IMGU_ABI_FRAME_FORMAT_UYVY, /* 16 bit YUV 422, UYVY interleaved */
+ IMGU_ABI_FRAME_FORMAT_YUYV, /* 16 bit YUV 422, YUYV interleaved */
+ IMGU_ABI_FRAME_FORMAT_YUV444, /* 24 bit YUV 444, Y, U, V plane */
+ IMGU_ABI_FRAME_FORMAT_YUV_LINE, /* Internal format, 2 y lines */
+ /* followed by a uv-interleaved line */
+ IMGU_ABI_FRAME_FORMAT_RAW, /* RAW, 1 plane */
+ IMGU_ABI_FRAME_FORMAT_RGB565, /* 16 bit RGB, 1 plane. Each 3 sub
+ * pixels are packed into one 16 bit
+ * value, 5 bits for R, 6 bits for G
+ * and 5 bits for B.
+ */
+ IMGU_ABI_FRAME_FORMAT_PLANAR_RGB888, /* 24 bit RGB, 3 planes */
+ IMGU_ABI_FRAME_FORMAT_RGBA888, /* 32 bit RGBA, 1 plane, A=Alpha
+ * (alpha is unused)
+ */
+ IMGU_ABI_FRAME_FORMAT_QPLANE6, /* Internal, for advanced ISP */
+ IMGU_ABI_FRAME_FORMAT_BINARY_8, /* byte stream, used for jpeg. For
+ * frames of this type, we set the
+ * height to 1 and the width to the
+ * number of allocated bytes.
+ */
+ IMGU_ABI_FRAME_FORMAT_MIPI, /* MIPI frame, 1 plane */
+ IMGU_ABI_FRAME_FORMAT_RAW_PACKED, /* RAW, 1 plane, packed */
+ IMGU_ABI_FRAME_FORMAT_CSI_MIPI_YUV420_8, /* 8 bit per Y/U/V. Y odd line
+ * UYVY interleaved even line
+ */
+ IMGU_ABI_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8, /* Legacy YUV420.
+ * UY odd line;
+ * VY even line
+ */
+ IMGU_ABI_FRAME_FORMAT_CSI_MIPI_YUV420_10,/* 10 bit per Y/U/V. Y odd
+ * line; UYVY interleaved
+ * even line
+ */
+ IMGU_ABI_FRAME_FORMAT_YCGCO444_16, /* Internal format for ISP2.7,
+ * 16 bits per plane YUV 444,
+ * Y, U, V plane
+ */
+ IMGU_ABI_FRAME_FORMAT_NUM
+};
+
+enum imgu_abi_bayer_order {
+ IMGU_ABI_BAYER_ORDER_GRBG,
+ IMGU_ABI_BAYER_ORDER_RGGB,
+ IMGU_ABI_BAYER_ORDER_BGGR,
+ IMGU_ABI_BAYER_ORDER_GBRG
+};
+
+enum imgu_abi_osys_format {
+ IMGU_ABI_OSYS_FORMAT_YUV420,
+ IMGU_ABI_OSYS_FORMAT_YV12,
+ IMGU_ABI_OSYS_FORMAT_NV12,
+ IMGU_ABI_OSYS_FORMAT_NV21,
+ IMGU_ABI_OSYS_FORMAT_YUV_LINE,
+ IMGU_ABI_OSYS_FORMAT_YUY2, /* = IMGU_ABI_OSYS_FORMAT_YUYV */
+ IMGU_ABI_OSYS_FORMAT_NV16,
+ IMGU_ABI_OSYS_FORMAT_RGBA,
+ IMGU_ABI_OSYS_FORMAT_BGRA
+};
+
+enum imgu_abi_osys_tiling {
+ IMGU_ABI_OSYS_TILING_NONE,
+ IMGU_ABI_OSYS_TILING_Y,
+ IMGU_ABI_OSYS_TILING_YF,
+};
+
+enum imgu_abi_osys_procmode {
+ IMGU_ABI_OSYS_PROCMODE_BYPASS,
+ IMGU_ABI_OSYS_PROCMODE_UPSCALE,
+ IMGU_ABI_OSYS_PROCMODE_DOWNSCALE,
+};
+
+enum imgu_abi_queue_id {
+ IMGU_ABI_QUEUE_EVENT_ID = -1,
+ IMGU_ABI_QUEUE_A_ID = 0,
+ IMGU_ABI_QUEUE_B_ID,
+ IMGU_ABI_QUEUE_C_ID,
+ IMGU_ABI_QUEUE_D_ID,
+ IMGU_ABI_QUEUE_E_ID,
+ IMGU_ABI_QUEUE_F_ID,
+ IMGU_ABI_QUEUE_G_ID,
+ IMGU_ABI_QUEUE_H_ID, /* input frame queue for skycam */
+ IMGU_ABI_QUEUE_NUM
+};
+
+enum imgu_abi_buffer_type {
+ IMGU_ABI_BUFFER_TYPE_INVALID = -1,
+ IMGU_ABI_BUFFER_TYPE_3A_STATISTICS = 0,
+ IMGU_ABI_BUFFER_TYPE_DIS_STATISTICS,
+ IMGU_ABI_BUFFER_TYPE_LACE_STATISTICS,
+ IMGU_ABI_BUFFER_TYPE_INPUT_FRAME,
+ IMGU_ABI_BUFFER_TYPE_OUTPUT_FRAME,
+ IMGU_ABI_BUFFER_TYPE_SEC_OUTPUT_FRAME,
+ IMGU_ABI_BUFFER_TYPE_VF_OUTPUT_FRAME,
+ IMGU_ABI_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME,
+ IMGU_ABI_BUFFER_TYPE_RAW_OUTPUT_FRAME,
+ IMGU_ABI_BUFFER_TYPE_CUSTOM_INPUT,
+ IMGU_ABI_BUFFER_TYPE_CUSTOM_OUTPUT,
+ IMGU_ABI_BUFFER_TYPE_METADATA,
+ IMGU_ABI_BUFFER_TYPE_PARAMETER_SET,
+ IMGU_ABI_BUFFER_TYPE_PER_FRAME_PARAMETER_SET,
+ IMGU_ABI_NUM_DYNAMIC_BUFFER_TYPE,
+ IMGU_ABI_NUM_BUFFER_TYPE
+};
+
+enum imgu_abi_raw_type {
+ IMGU_ABI_RAW_TYPE_BAYER,
+ IMGU_ABI_RAW_TYPE_IR_ON_GR,
+ IMGU_ABI_RAW_TYPE_IR_ON_GB
+};
+
+enum imgu_abi_memories {
+ IMGU_ABI_MEM_ISP_PMEM0 = 0,
+ IMGU_ABI_MEM_ISP_DMEM0,
+ IMGU_ABI_MEM_ISP_VMEM0,
+ IMGU_ABI_MEM_ISP_VAMEM0,
+ IMGU_ABI_MEM_ISP_VAMEM1,
+ IMGU_ABI_MEM_ISP_VAMEM2,
+ IMGU_ABI_MEM_ISP_HMEM0,
+ IMGU_ABI_MEM_SP0_DMEM0,
+ IMGU_ABI_MEM_SP1_DMEM0,
+ IMGU_ABI_MEM_DDR,
+ IMGU_ABI_NUM_MEMORIES
+};
+
+enum imgu_abi_param_class {
+ IMGU_ABI_PARAM_CLASS_PARAM, /* Late binding parameters, like 3A */
+ IMGU_ABI_PARAM_CLASS_CONFIG, /* Pipe config time parameters */
+ IMGU_ABI_PARAM_CLASS_STATE, /* State parameters, eg. buffer index */
+ IMGU_ABI_PARAM_CLASS_NUM
+};
+
+enum imgu_abi_bin_input_src {
+ IMGU_ABI_BINARY_INPUT_SOURCE_SENSOR,
+ IMGU_ABI_BINARY_INPUT_SOURCE_MEMORY,
+ IMGU_ABI_BINARY_INPUT_SOURCE_VARIABLE,
+};
+
+enum imgu_abi_sp_swstate {
+ IMGU_ABI_SP_SWSTATE_TERMINATED,
+ IMGU_ABI_SP_SWSTATE_INITIALIZED,
+ IMGU_ABI_SP_SWSTATE_CONNECTED,
+ IMGU_ABI_SP_SWSTATE_RUNNING,
+};
+
+enum imgu_abi_bl_swstate {
+ IMGU_ABI_BL_SWSTATE_OK = 0x100,
+ IMGU_ABI_BL_SWSTATE_BUSY,
+ IMGU_ABI_BL_SWSTATE_ERR,
+};
+
+/* The type of pipe stage */
+enum imgu_abi_stage_type {
+ IMGU_ABI_STAGE_TYPE_SP,
+ IMGU_ABI_STAGE_TYPE_ISP,
+};
+
+struct imgu_abi_acc_operation {
+ /*
+ * zero means on init,
+ * others mean upon receiving an ack signal from the BC acc.
+ */
+ u8 op_indicator;
+ u8 op_type;
+} __packed;
+
+struct imgu_abi_acc_process_lines_cmd_data {
+ u16 lines;
+ u8 cfg_set;
+ u8 reserved; /* Align to 4 bytes */
+} __packed;
+
+/* Bayer shading definitions */
+
+struct imgu_abi_shd_transfer_luts_set_data {
+ u8 set_number;
+ u8 padding[3];
+ imgu_addr_t rg_lut_ddr_addr;
+ imgu_addr_t bg_lut_ddr_addr;
+ u32 align_dummy;
+} __packed;
+
+struct imgu_abi_shd_grid_config {
+ /* reg 0 */
+ u32 grid_width:8;
+ u32 grid_height:8;
+ u32 block_width:3;
+ u32 reserved0:1;
+ u32 block_height:3;
+ u32 reserved1:1;
+ u32 grid_height_per_slice:8;
+ /* reg 1 */
+ s32 x_start:13;
+ s32 reserved2:3;
+ s32 y_start:13;
+ s32 reserved3:3;
+} __packed;
+
+struct imgu_abi_shd_general_config {
+ u32 init_set_vrt_offst_ul:8;
+ u32 shd_enable:1;
+ /* aka 'gf' */
+ u32 gain_factor:2;
+ u32 reserved:21;
+} __packed;
+
+struct imgu_abi_shd_black_level_config {
+ /* reg 0 */
+ s32 bl_r:12;
+ s32 reserved0:4;
+ s32 bl_gr:12;
+ u32 reserved1:1;
+ /* aka 'nf' */
+ u32 normalization_shift:3;
+ /* reg 1 */
+ s32 bl_gb:12;
+ s32 reserved2:4;
+ s32 bl_b:12;
+ s32 reserved3:4;
+} __packed;
+
+struct imgu_abi_shd_intra_frame_operations_data {
+ struct imgu_abi_acc_operation
+ operation_list[IMGU_ABI_SHD_MAX_OPERATIONS] __aligned(32);
+ struct imgu_abi_acc_process_lines_cmd_data
+ process_lines_data[IMGU_ABI_SHD_MAX_PROCESS_LINES] __aligned(32);
+ struct imgu_abi_shd_transfer_luts_set_data
+ transfer_data[IMGU_ABI_SHD_MAX_TRANSFERS] __aligned(32);
+} __packed;
+
+struct imgu_abi_shd_config {
+ struct ipu3_uapi_shd_config_static shd __aligned(32);
+ struct imgu_abi_shd_intra_frame_operations_data shd_ops __aligned(32);
+ struct ipu3_uapi_shd_lut shd_lut __aligned(32);
+} __packed;
+
+struct imgu_abi_stripe_input_frame_resolution {
+ u16 width;
+ u16 height;
+ u32 bayer_order; /* enum ipu3_uapi_bayer_order */
+ u32 raw_bit_depth;
+} __packed;
+
+/* Stripe-based processing */
+
+struct imgu_abi_stripes {
+ /* offset from start of frame - measured in pixels */
+ u16 offset;
+ /* stripe width - measured in pixels */
+ u16 width;
+ /* stripe width - measured in pixels */
+ u16 height;
+} __packed;
+
+struct imgu_abi_stripe_data {
+ /*
+ * number of stripes for current processing source
+ * - VLIW binary parameter we currently support 1 or 2 stripes
+ */
+ u16 num_of_stripes;
+
+ u8 padding[2];
+
+ /*
+ * the following data is derived from resolution-related
+ * pipe config and from num_of_stripes
+ */
+
+ /*
+ *'input-stripes' - before input cropping
+ * used by input feeder
+ */
+ struct imgu_abi_stripe_input_frame_resolution input_frame;
+
+ /*'effective-stripes' - after input cropping used dpc, bds */
+ struct imgu_abi_stripes effective_stripes[IPU3_UAPI_MAX_STRIPES];
+
+ /* 'down-scaled-stripes' - after down-scaling ONLY. used by BDS */
+ struct imgu_abi_stripes down_scaled_stripes[IPU3_UAPI_MAX_STRIPES];
+
+ /*
+ *'bds-out-stripes' - after bayer down-scaling and padding.
+ * used by all algos starting with norm up to the ref-frame for GDC
+ * (currently up to the output kernel)
+ */
+ struct imgu_abi_stripes bds_out_stripes[IPU3_UAPI_MAX_STRIPES];
+
+ /* 'bds-out-stripes (no overlap)' - used for ref kernel */
+ struct imgu_abi_stripes
+ bds_out_stripes_no_overlap[IPU3_UAPI_MAX_STRIPES];
+
+ /*
+ * input resolution for output system (equal to bds_out - envelope)
+ * output-system input frame width as configured by user
+ */
+ u16 output_system_in_frame_width;
+ /* output-system input frame height as configured by user */
+ u16 output_system_in_frame_height;
+
+ /*
+ * 'output-stripes' - accounts for stiching on the output (no overlap)
+ * used by the output kernel
+ */
+ struct imgu_abi_stripes output_stripes[IPU3_UAPI_MAX_STRIPES];
+
+ /*
+ * 'block-stripes' - accounts for stiching by the output system
+ * (1 or more blocks overlap)
+ * used by DVS, TNR and the output system kernel
+ */
+ struct imgu_abi_stripes block_stripes[IPU3_UAPI_MAX_STRIPES];
+
+ u16 effective_frame_width; /* Needed for vertical cropping */
+ u16 bds_frame_width;
+ u16 out_frame_width; /* Output frame width as configured by user */
+ u16 out_frame_height; /* Output frame height as configured by user */
+
+ /* GDC in buffer (A.K.A delay frame,ref buffer) info */
+ u16 gdc_in_buffer_width; /* GDC in buffer width */
+ u16 gdc_in_buffer_height; /* GDC in buffer height */
+ /* GDC in buffer first valid pixel x offset */
+ u16 gdc_in_buffer_offset_x;
+ /* GDC in buffer first valid pixel y offset */
+ u16 gdc_in_buffer_offset_y;
+
+ /* Display frame width as configured by user */
+ u16 display_frame_width;
+ /* Display frame height as configured by user */
+ u16 display_frame_height;
+ u16 bds_aligned_frame_width;
+ /* Number of vectors to left-crop when writing stripes (not stripe 0) */
+ u16 half_overlap_vectors;
+ /* Decimate ISP and fixed func resolutions after BDS (ir_extraction) */
+ u16 ir_ext_decimation;
+ u8 padding1[2];
+} __packed;
+
+/* Input feeder related structs */
+
+struct imgu_abi_input_feeder_data {
+ u32 row_stride; /* row stride */
+ u32 start_row_address; /* start row address */
+ u32 start_pixel; /* start pixel */
+} __packed;
+
+struct imgu_abi_input_feeder_data_aligned {
+ struct imgu_abi_input_feeder_data data __aligned(32);
+} __packed;
+
+struct imgu_abi_input_feeder_data_per_stripe {
+ struct imgu_abi_input_feeder_data_aligned
+ input_feeder_data[IPU3_UAPI_MAX_STRIPES];
+} __packed;
+
+struct imgu_abi_input_feeder_config {
+ struct imgu_abi_input_feeder_data data;
+ struct imgu_abi_input_feeder_data_per_stripe data_per_stripe
+ __aligned(32);
+} __packed;
+
+/* DVS related definitions */
+
+struct imgu_abi_dvs_stat_grd_config {
+ u8 grid_width;
+ u8 grid_height;
+ u8 block_width;
+ u8 block_height;
+ u16 x_start;
+ u16 y_start;
+ u16 enable;
+ u16 x_end;
+ u16 y_end;
+} __packed;
+
+struct imgu_abi_dvs_stat_cfg {
+ u8 reserved0[4];
+ struct imgu_abi_dvs_stat_grd_config
+ grd_config[IMGU_ABI_DVS_STAT_LEVELS];
+ u8 reserved1[18];
+} __packed;
+
+struct imgu_abi_dvs_stat_transfer_op_data {
+ u8 set_number;
+} __packed;
+
+struct imgu_abi_dvs_stat_intra_frame_operations_data {
+ struct imgu_abi_acc_operation
+ ops[IMGU_ABI_DVS_STAT_MAX_OPERATIONS] __aligned(32);
+ struct imgu_abi_acc_process_lines_cmd_data
+ process_lines_data[IMGU_ABI_DVS_STAT_MAX_PROCESS_LINES]
+ __aligned(32);
+ struct imgu_abi_dvs_stat_transfer_op_data
+ transfer_data[IMGU_ABI_DVS_STAT_MAX_TRANSFERS] __aligned(32);
+} __packed;
+
+struct imgu_abi_dvs_stat_config {
+ struct imgu_abi_dvs_stat_cfg cfg __aligned(32);
+ u8 reserved0[128];
+ struct imgu_abi_dvs_stat_intra_frame_operations_data operations_data;
+ u8 reserved1[64];
+} __packed;
+
+/* Y-tone Mapping */
+
+struct imgu_abi_yuvp2_y_tm_lut_static_config {
+ u16 entries[IMGU_ABI_YUVP2_YTM_LUT_ENTRIES];
+ u32 enable;
+} __packed;
+
+/* Output formatter related structs */
+
+struct imgu_abi_osys_formatter_params {
+ u32 format;
+ u32 flip;
+ u32 mirror;
+ u32 tiling;
+ u32 reduce_range;
+ u32 alpha_blending;
+ u32 release_inp_addr;
+ u32 release_inp_en;
+ u32 process_out_buf_addr;
+ u32 image_width_vecs;
+ u32 image_height_lines;
+ u32 inp_buff_y_st_addr;
+ u32 inp_buff_y_line_stride;
+ u32 inp_buff_y_buffer_stride;
+ u32 int_buff_u_st_addr;
+ u32 int_buff_v_st_addr;
+ u32 inp_buff_uv_line_stride;
+ u32 inp_buff_uv_buffer_stride;
+ u32 out_buff_level;
+ u32 out_buff_nr_y_lines;
+ u32 out_buff_u_st_offset;
+ u32 out_buff_v_st_offset;
+ u32 out_buff_y_line_stride;
+ u32 out_buff_uv_line_stride;
+ u32 hist_buff_st_addr;
+ u32 hist_buff_line_stride;
+ u32 hist_buff_nr_lines;
+} __packed;
+
+struct imgu_abi_osys_formatter {
+ struct imgu_abi_osys_formatter_params param __aligned(32);
+} __packed;
+
+struct imgu_abi_osys_scaler_params {
+ u32 inp_buf_y_st_addr;
+ u32 inp_buf_y_line_stride;
+ u32 inp_buf_y_buffer_stride;
+ u32 inp_buf_u_st_addr;
+ u32 inp_buf_v_st_addr;
+ u32 inp_buf_uv_line_stride;
+ u32 inp_buf_uv_buffer_stride;
+ u32 inp_buf_chunk_width;
+ u32 inp_buf_nr_buffers;
+ /* Output buffers */
+ u32 out_buf_y_st_addr;
+ u32 out_buf_y_line_stride;
+ u32 out_buf_y_buffer_stride;
+ u32 out_buf_u_st_addr;
+ u32 out_buf_v_st_addr;
+ u32 out_buf_uv_line_stride;
+ u32 out_buf_uv_buffer_stride;
+ u32 out_buf_nr_buffers;
+ /* Intermediate buffers */
+ u32 int_buf_y_st_addr;
+ u32 int_buf_y_line_stride;
+ u32 int_buf_u_st_addr;
+ u32 int_buf_v_st_addr;
+ u32 int_buf_uv_line_stride;
+ u32 int_buf_height;
+ u32 int_buf_chunk_width;
+ u32 int_buf_chunk_height;
+ /* Context buffers */
+ u32 ctx_buf_hor_y_st_addr;
+ u32 ctx_buf_hor_u_st_addr;
+ u32 ctx_buf_hor_v_st_addr;
+ u32 ctx_buf_ver_y_st_addr;
+ u32 ctx_buf_ver_u_st_addr;
+ u32 ctx_buf_ver_v_st_addr;
+ /* Addresses for release-input and process-output tokens */
+ u32 release_inp_buf_addr;
+ u32 release_inp_buf_en;
+ u32 release_out_buf_en;
+ u32 process_out_buf_addr;
+ /* Settings dimensions, padding, cropping */
+ u32 input_image_y_width;
+ u32 input_image_y_height;
+ u32 input_image_y_start_column;
+ u32 input_image_uv_start_column;
+ u32 input_image_y_left_pad;
+ u32 input_image_uv_left_pad;
+ u32 input_image_y_right_pad;
+ u32 input_image_uv_right_pad;
+ u32 input_image_y_top_pad;
+ u32 input_image_uv_top_pad;
+ u32 input_image_y_bottom_pad;
+ u32 input_image_uv_bottom_pad;
+ u32 processing_mode; /* enum imgu_abi_osys_procmode */
+ u32 scaling_ratio;
+ u32 y_left_phase_init;
+ u32 uv_left_phase_init;
+ u32 y_top_phase_init;
+ u32 uv_top_phase_init;
+ u32 coeffs_exp_shift;
+ u32 out_y_left_crop;
+ u32 out_uv_left_crop;
+ u32 out_y_top_crop;
+ u32 out_uv_top_crop;
+} __packed;
+
+struct imgu_abi_osys_scaler {
+ struct imgu_abi_osys_scaler_params param __aligned(32);
+} __packed;
+
+struct imgu_abi_osys_frame_params {
+ /* Output pins */
+ u32 enable;
+ u32 format; /* enum imgu_abi_osys_format */
+ u32 flip;
+ u32 mirror;
+ u32 tiling; /* enum imgu_abi_osys_tiling */
+ u32 width;
+ u32 height;
+ u32 stride;
+ u32 scaled;
+} __packed;
+
+struct imgu_abi_osys_frame {
+ struct imgu_abi_osys_frame_params param __aligned(32);
+} __packed;
+
+struct imgu_abi_osys_stripe {
+ /* Input resolution */
+ u32 input_width;
+ u32 input_height;
+ /* Output Stripe */
+ u32 output_width[IMGU_ABI_OSYS_PINS];
+ u32 output_height[IMGU_ABI_OSYS_PINS];
+ u32 output_offset[IMGU_ABI_OSYS_PINS];
+ u32 buf_stride[IMGU_ABI_OSYS_PINS];
+ /* Scaler params */
+ u32 block_width;
+ u32 block_height;
+ /* Output Crop factor */
+ u32 crop_top[IMGU_ABI_OSYS_PINS];
+ u32 crop_left[IMGU_ABI_OSYS_PINS];
+} __packed;
+
+struct imgu_abi_osys_config {
+ struct imgu_abi_osys_formatter
+ formatter[IPU3_UAPI_MAX_STRIPES][IMGU_ABI_OSYS_PINS];
+ struct imgu_abi_osys_scaler scaler[IPU3_UAPI_MAX_STRIPES];
+ struct imgu_abi_osys_frame frame[IMGU_ABI_OSYS_PINS];
+ struct imgu_abi_osys_stripe stripe[IPU3_UAPI_MAX_STRIPES];
+ /* 32 packed coefficients for luma and chroma */
+ s8 scaler_coeffs_chroma[128];
+ s8 scaler_coeffs_luma[128];
+} __packed;
+
+/* BDS */
+
+struct imgu_abi_bds_hor_ctrl0 {
+ u32 sample_patrn_length:9;
+ u32 reserved0:3;
+ u32 hor_ds_en:1;
+ u32 min_clip_val:1;
+ u32 max_clip_val:2;
+ u32 out_frame_width:13;
+ u32 reserved1:3;
+} __packed;
+
+struct imgu_abi_bds_ptrn_arr {
+ u32 elems[IMGU_ABI_BDS_SAMPLE_PATTERN_ARRAY_SIZE];
+} __packed;
+
+struct imgu_abi_bds_phase_entry {
+ s8 coeff_min2;
+ s8 coeff_min1;
+ s8 coeff_0;
+ s8 nf;
+ s8 coeff_pls1;
+ s8 coeff_pls2;
+ s8 coeff_pls3;
+ u8 reserved;
+} __packed;
+
+struct imgu_abi_bds_phase_arr {
+ struct imgu_abi_bds_phase_entry
+ even[IMGU_ABI_BDS_PHASE_COEFFS_ARRAY_SIZE];
+ struct imgu_abi_bds_phase_entry
+ odd[IMGU_ABI_BDS_PHASE_COEFFS_ARRAY_SIZE];
+} __packed;
+
+struct imgu_abi_bds_hor_ctrl1 {
+ u32 hor_crop_start:13;
+ u32 reserved0:3;
+ u32 hor_crop_end:13;
+ u32 reserved1:1;
+ u32 hor_crop_en:1;
+ u32 reserved2:1;
+} __packed;
+
+struct imgu_abi_bds_hor_ctrl2 {
+ u32 input_frame_height:13;
+ u32 reserved0:19;
+} __packed;
+
+struct imgu_abi_bds_hor {
+ struct imgu_abi_bds_hor_ctrl0 hor_ctrl0;
+ struct imgu_abi_bds_ptrn_arr hor_ptrn_arr;
+ struct imgu_abi_bds_phase_arr hor_phase_arr;
+ struct imgu_abi_bds_hor_ctrl1 hor_ctrl1;
+ struct imgu_abi_bds_hor_ctrl2 hor_ctrl2;
+} __packed;
+
+struct imgu_abi_bds_ver_ctrl0 {
+ u32 sample_patrn_length:9;
+ u32 reserved0:3;
+ u32 ver_ds_en:1;
+ u32 min_clip_val:1;
+ u32 max_clip_val:2;
+ u32 reserved1:16;
+} __packed;
+
+struct imgu_abi_bds_ver_ctrl1 {
+ u32 out_frame_width:13;
+ u32 reserved0:3;
+ u32 out_frame_height:13;
+ u32 reserved1:3;
+} __packed;
+
+struct imgu_abi_bds_ver {
+ struct imgu_abi_bds_ver_ctrl0 ver_ctrl0;
+ struct imgu_abi_bds_ptrn_arr ver_ptrn_arr;
+ struct imgu_abi_bds_phase_arr ver_phase_arr;
+ struct imgu_abi_bds_ver_ctrl1 ver_ctrl1;
+} __packed;
+
+struct imgu_abi_bds_per_stripe_data {
+ struct imgu_abi_bds_hor_ctrl0 hor_ctrl0;
+ struct imgu_abi_bds_ver_ctrl1 ver_ctrl1;
+ struct imgu_abi_bds_hor_ctrl1 crop;
+} __packed;
+
+struct imgu_abi_bds_per_stripe_data_aligned {
+ struct imgu_abi_bds_per_stripe_data data __aligned(32);
+} __packed;
+
+struct imgu_abi_bds_per_stripe {
+ struct imgu_abi_bds_per_stripe_data_aligned
+ aligned_data[IPU3_UAPI_MAX_STRIPES];
+} __packed;
+
+struct imgu_abi_bds_config {
+ struct imgu_abi_bds_hor hor __aligned(32);
+ struct imgu_abi_bds_ver ver __aligned(32);
+ struct imgu_abi_bds_per_stripe per_stripe __aligned(32);
+ u32 enabled;
+} __packed;
+
+/* ANR */
+
+struct imgu_abi_anr_search_config {
+ u32 enable;
+ u16 frame_width;
+ u16 frame_height;
+} __packed;
+
+struct imgu_abi_anr_stitch_config {
+ u32 anr_stitch_en;
+ u16 frame_width;
+ u16 frame_height;
+ u8 reserved[40];
+ struct ipu3_uapi_anr_stitch_pyramid pyramid[IPU3_UAPI_ANR_PYRAMID_SIZE];
+} __packed;
+
+struct imgu_abi_anr_tile2strm_config {
+ u32 enable;
+ u16 frame_width;
+ u16 frame_height;
+} __packed;
+
+struct imgu_abi_anr_config {
+ struct imgu_abi_anr_search_config search __aligned(32);
+ struct ipu3_uapi_anr_transform_config transform __aligned(32);
+ struct imgu_abi_anr_stitch_config stitch __aligned(32);
+ struct imgu_abi_anr_tile2strm_config tile2strm __aligned(32);
+} __packed;
+
+/* AF */
+
+struct imgu_abi_af_frame_size {
+ u16 width;
+ u16 height;
+} __packed;
+
+struct imgu_abi_af_config_s {
+ struct ipu3_uapi_af_filter_config filter_config __aligned(32);
+ struct imgu_abi_af_frame_size frame_size;
+ struct ipu3_uapi_grid_config grid_cfg __aligned(32);
+} __packed;
+
+struct imgu_abi_af_intra_frame_operations_data {
+ struct imgu_abi_acc_operation ops[IMGU_ABI_AF_MAX_OPERATIONS]
+ __aligned(32);
+ struct imgu_abi_acc_process_lines_cmd_data
+ process_lines_data[IMGU_ABI_AF_MAX_PROCESS_LINES] __aligned(32);
+} __packed;
+
+struct imgu_abi_af_stripe_config {
+ struct imgu_abi_af_frame_size frame_size __aligned(32);
+ struct ipu3_uapi_grid_config grid_cfg __aligned(32);
+} __packed;
+
+struct imgu_abi_af_config {
+ struct imgu_abi_af_config_s config;
+ struct imgu_abi_af_intra_frame_operations_data operations_data;
+ struct imgu_abi_af_stripe_config stripes[IPU3_UAPI_MAX_STRIPES];
+} __packed;
+
+/* AE */
+
+struct imgu_abi_ae_config {
+ struct ipu3_uapi_ae_grid_config grid_cfg __aligned(32);
+ struct ipu3_uapi_ae_weight_elem weights[IPU3_UAPI_AE_WEIGHTS]
+ __aligned(32);
+ struct ipu3_uapi_ae_ccm ae_ccm __aligned(32);
+ struct {
+ struct ipu3_uapi_ae_grid_config grid __aligned(32);
+ } stripes[IPU3_UAPI_MAX_STRIPES];
+} __packed;
+
+/* AWB_FR */
+
+struct imgu_abi_awb_fr_intra_frame_operations_data {
+ struct imgu_abi_acc_operation ops[IMGU_ABI_AWB_FR_MAX_OPERATIONS]
+ __aligned(32);
+ struct imgu_abi_acc_process_lines_cmd_data
+ process_lines_data[IMGU_ABI_AWB_FR_MAX_PROCESS_LINES] __aligned(32);
+} __packed;
+
+struct imgu_abi_awb_fr_config {
+ struct ipu3_uapi_awb_fr_config_s config;
+ struct imgu_abi_awb_fr_intra_frame_operations_data operations_data;
+ struct ipu3_uapi_awb_fr_config_s stripes[IPU3_UAPI_MAX_STRIPES];
+} __packed;
+
+struct imgu_abi_acc_transfer_op_data {
+ u8 set_number;
+} __packed;
+
+struct imgu_abi_awb_intra_frame_operations_data {
+ struct imgu_abi_acc_operation ops[IMGU_ABI_AWB_MAX_OPERATIONS]
+ __aligned(32);
+ struct imgu_abi_acc_process_lines_cmd_data
+ process_lines_data[IMGU_ABI_AWB_MAX_PROCESS_LINES] __aligned(32);
+ struct imgu_abi_acc_transfer_op_data
+ transfer_data[IMGU_ABI_AWB_MAX_TRANSFERS] __aligned(32);
+} __aligned(32) __packed;
+
+struct imgu_abi_awb_config {
+ struct ipu3_uapi_awb_config_s config __aligned(32);
+ struct imgu_abi_awb_intra_frame_operations_data operations_data;
+ struct ipu3_uapi_awb_config_s stripes[IPU3_UAPI_MAX_STRIPES];
+} __packed;
+
+struct imgu_abi_acc_param {
+ struct imgu_abi_stripe_data stripe;
+ u8 padding[8];
+ struct imgu_abi_input_feeder_config input_feeder;
+ struct ipu3_uapi_bnr_static_config bnr;
+ struct ipu3_uapi_bnr_static_config_green_disparity green_disparity
+ __aligned(32);
+ struct ipu3_uapi_dm_config dm __aligned(32);
+ struct ipu3_uapi_ccm_mat_config ccm __aligned(32);
+ struct ipu3_uapi_gamma_config gamma __aligned(32);
+ struct ipu3_uapi_csc_mat_config csc __aligned(32);
+ struct ipu3_uapi_cds_params cds __aligned(32);
+ struct imgu_abi_shd_config shd __aligned(32);
+ struct imgu_abi_dvs_stat_config dvs_stat;
+ u8 padding1[224]; /* reserved for lace_stat */
+ struct ipu3_uapi_yuvp1_iefd_config iefd __aligned(32);
+ struct ipu3_uapi_yuvp1_yds_config yds_c0 __aligned(32);
+ struct ipu3_uapi_yuvp1_chnr_config chnr_c0 __aligned(32);
+ struct ipu3_uapi_yuvp1_y_ee_nr_config y_ee_nr __aligned(32);
+ struct ipu3_uapi_yuvp1_yds_config yds __aligned(32);
+ struct ipu3_uapi_yuvp1_chnr_config chnr __aligned(32);
+ struct imgu_abi_yuvp2_y_tm_lut_static_config ytm __aligned(32);
+ struct ipu3_uapi_yuvp1_yds_config yds2 __aligned(32);
+ struct ipu3_uapi_yuvp2_tcc_static_config tcc __aligned(32);
+ /* reserved for defect pixel correction */
+ u8 dpc[240832] __aligned(32);
+ struct imgu_abi_bds_config bds;
+ struct imgu_abi_anr_config anr;
+ struct imgu_abi_awb_fr_config awb_fr;
+ struct imgu_abi_ae_config ae;
+ struct imgu_abi_af_config af;
+ struct imgu_abi_awb_config awb;
+ struct imgu_abi_osys_config osys;
+} __packed;
+
+/***** Morphing table entry *****/
+
+struct imgu_abi_gdc_warp_param {
+ u32 origin_x;
+ u32 origin_y;
+ u32 in_addr_offset;
+ u32 in_block_width;
+ u32 in_block_height;
+ u32 p0_x;
+ u32 p0_y;
+ u32 p1_x;
+ u32 p1_y;
+ u32 p2_x;
+ u32 p2_y;
+ u32 p3_x;
+ u32 p3_y;
+ u32 in_block_width_a;
+ u32 in_block_width_b;
+ u32 padding; /* struct size multiple of DDR word */
+} __packed;
+
+/******************* Firmware ABI definitions *******************/
+
+/***** struct imgu_abi_sp_stage *****/
+
+struct imgu_abi_crop_pos {
+ u16 x;
+ u16 y;
+} __packed;
+
+struct imgu_abi_sp_resolution {
+ u16 width; /* Width of valid data in pixels */
+ u16 height; /* Height of valid data in lines */
+} __packed;
+
+/*
+ * Frame info struct. This describes the contents of an image frame buffer.
+ */
+struct imgu_abi_frame_sp_info {
+ struct imgu_abi_sp_resolution res;
+ u16 padded_width; /* stride of line in memory
+ * (in pixels)
+ */
+ u8 format; /* format of the frame data */
+ u8 raw_bit_depth; /* number of valid bits per pixel,
+ * only valid for RAW bayer frames
+ */
+ u8 raw_bayer_order; /* bayer order, only valid
+ * for RAW bayer frames
+ */
+ u8 raw_type; /* To choose the proper raw frame type. for
+ * Legacy SKC pipes/Default is set to
+ * IMGU_ABI_RAW_TYPE_BAYER. For RGB IR sensor -
+ * driver should set it to:
+ * IronGr case - IMGU_ABI_RAW_TYPE_IR_ON_GR
+ * IronGb case - IMGU_ABI_RAW_TYPE_IR_ON_GB
+ */
+ u8 padding[2]; /* Extend to 32 bit multiple */
+} __packed;
+
+struct imgu_abi_buffer_sp {
+ union {
+ imgu_addr_t xmem_addr;
+ s32 queue_id; /* enum imgu_abi_queue_id */
+ } buf_src;
+ s32 buf_type; /* enum imgu_abi_buffer_type */
+} __packed;
+
+struct imgu_abi_frame_sp_plane {
+ u32 offset; /* offset in bytes to start of frame data */
+ /* offset is wrt data in imgu_abi_sp_sp_frame */
+} __packed;
+
+struct imgu_abi_frame_sp_rgb_planes {
+ struct imgu_abi_frame_sp_plane r;
+ struct imgu_abi_frame_sp_plane g;
+ struct imgu_abi_frame_sp_plane b;
+} __packed;
+
+struct imgu_abi_frame_sp_yuv_planes {
+ struct imgu_abi_frame_sp_plane y;
+ struct imgu_abi_frame_sp_plane u;
+ struct imgu_abi_frame_sp_plane v;
+} __packed;
+
+struct imgu_abi_frame_sp_nv_planes {
+ struct imgu_abi_frame_sp_plane y;
+ struct imgu_abi_frame_sp_plane uv;
+} __packed;
+
+struct imgu_abi_frame_sp_plane6 {
+ struct imgu_abi_frame_sp_plane r;
+ struct imgu_abi_frame_sp_plane r_at_b;
+ struct imgu_abi_frame_sp_plane gr;
+ struct imgu_abi_frame_sp_plane gb;
+ struct imgu_abi_frame_sp_plane b;
+ struct imgu_abi_frame_sp_plane b_at_r;
+} __packed;
+
+struct imgu_abi_frame_sp_binary_plane {
+ u32 size;
+ struct imgu_abi_frame_sp_plane data;
+} __packed;
+
+struct imgu_abi_frame_sp {
+ struct imgu_abi_frame_sp_info info;
+ struct imgu_abi_buffer_sp buf_attr;
+ union {
+ struct imgu_abi_frame_sp_plane raw;
+ struct imgu_abi_frame_sp_plane rgb;
+ struct imgu_abi_frame_sp_rgb_planes planar_rgb;
+ struct imgu_abi_frame_sp_plane yuyv;
+ struct imgu_abi_frame_sp_yuv_planes yuv;
+ struct imgu_abi_frame_sp_nv_planes nv;
+ struct imgu_abi_frame_sp_plane6 plane6;
+ struct imgu_abi_frame_sp_binary_plane binary;
+ } planes;
+} __packed;
+
+struct imgu_abi_resolution {
+ u32 width;
+ u32 height;
+} __packed;
+
+struct imgu_abi_frames_sp {
+ struct imgu_abi_frame_sp in;
+ struct imgu_abi_frame_sp out[IMGU_ABI_BINARY_MAX_OUTPUT_PORTS];
+ struct imgu_abi_resolution effective_in_res;
+ struct imgu_abi_frame_sp out_vf;
+ struct imgu_abi_frame_sp_info internal_frame_info;
+ struct imgu_abi_buffer_sp s3a_buf;
+ struct imgu_abi_buffer_sp dvs_buf;
+ struct imgu_abi_buffer_sp lace_buf;
+} __packed;
+
+struct imgu_abi_uds_info {
+ u16 curr_dx;
+ u16 curr_dy;
+ u16 xc;
+ u16 yc;
+} __packed;
+
+/* Information for a single pipeline stage */
+struct imgu_abi_sp_stage {
+ /* Multiple boolean flags can be stored in an integer */
+ u8 num; /* Stage number */
+ u8 isp_online;
+ u8 isp_copy_vf;
+ u8 isp_copy_output;
+ u8 sp_enable_xnr;
+ u8 isp_deci_log_factor;
+ u8 isp_vf_downscale_bits;
+ u8 deinterleaved;
+ /*
+ * NOTE: Programming the input circuit can only be done at the
+ * start of a session. It is illegal to program it during execution
+ * The input circuit defines the connectivity
+ */
+ u8 program_input_circuit;
+ u8 func;
+ u8 stage_type; /* enum imgu_abi_stage_type */
+ u8 num_stripes;
+ u8 isp_pipe_version;
+ struct {
+ u8 vf_output;
+ u8 s3a;
+ u8 sdis;
+ u8 dvs_stats;
+ u8 lace_stats;
+ } enable;
+
+ struct imgu_abi_crop_pos sp_out_crop_pos;
+ u8 padding[2];
+ struct imgu_abi_frames_sp frames;
+ struct imgu_abi_resolution dvs_envelope;
+ struct imgu_abi_uds_info uds;
+ imgu_addr_t isp_stage_addr;
+ imgu_addr_t xmem_bin_addr;
+ imgu_addr_t xmem_map_addr;
+
+ u16 top_cropping;
+ u16 row_stripes_height;
+ u16 row_stripes_overlap_lines;
+ u8 if_config_index; /* Which should be applied by this stage. */
+ u8 padding2;
+} __packed;
+
+/***** struct imgu_abi_isp_stage *****/
+
+struct imgu_abi_isp_param_memory_offsets {
+ u32 offsets[IMGU_ABI_PARAM_CLASS_NUM]; /* offset wrt hdr in bytes */
+} __packed;
+
+/*
+ * Blob descriptor.
+ * This structure describes an SP or ISP blob.
+ * It describes the test, data and bss sections as well as position in a
+ * firmware file.
+ * For convenience, it contains dynamic data after loading.
+ */
+struct imgu_abi_blob_info {
+ /* Static blob data */
+ u32 offset; /* Blob offset in fw file */
+ struct imgu_abi_isp_param_memory_offsets memory_offsets;
+ /* offset wrt hdr in bytes */
+ u32 prog_name_offset; /* offset wrt hdr in bytes */
+ u32 size; /* Size of blob */
+ u32 padding_size; /* total cummulative of bytes added
+ * due to section alignment
+ */
+ u32 icache_source; /* Position of icache in blob */
+ u32 icache_size; /* Size of icache section */
+ u32 icache_padding; /* added due to icache section alignment */
+ u32 text_source; /* Position of text in blob */
+ u32 text_size; /* Size of text section */
+ u32 text_padding; /* bytes added due to text section alignment */
+ u32 data_source; /* Position of data in blob */
+ u32 data_target; /* Start of data in SP dmem */
+ u32 data_size; /* Size of text section */
+ u32 data_padding; /* bytes added due to data section alignment */
+ u32 bss_target; /* Start position of bss in SP dmem */
+ u32 bss_size; /* Size of bss section
+ * Dynamic data filled by loader
+ */
+ u64 code __aligned(8); /* Code section absolute pointer */
+ /* within fw, code = icache + text */
+ u64 data __aligned(8); /* Data section absolute pointer */
+ /* within fw, data = data + bss */
+} __packed;
+
+struct imgu_abi_binary_pipeline_info {
+ u32 mode;
+ u32 isp_pipe_version;
+ u32 pipelining;
+ u32 c_subsampling;
+ u32 top_cropping;
+ u32 left_cropping;
+ u32 variable_resolution;
+} __packed;
+
+struct imgu_abi_binary_input_info {
+ u32 min_width;
+ u32 min_height;
+ u32 max_width;
+ u32 max_height;
+ u32 source; /* enum imgu_abi_bin_input_src */
+} __packed;
+
+struct imgu_abi_binary_output_info {
+ u32 min_width;
+ u32 min_height;
+ u32 max_width;
+ u32 max_height;
+ u32 num_chunks;
+ u32 variable_format;
+} __packed;
+
+struct imgu_abi_binary_internal_info {
+ u32 max_width;
+ u32 max_height;
+} __packed;
+
+struct imgu_abi_binary_bds_info {
+ u32 supported_bds_factors;
+} __packed;
+
+struct imgu_abi_binary_dvs_info {
+ u32 max_envelope_width;
+ u32 max_envelope_height;
+} __packed;
+
+struct imgu_abi_binary_vf_dec_info {
+ u32 is_variable;
+ u32 max_log_downscale;
+} __packed;
+
+struct imgu_abi_binary_s3a_info {
+ u32 s3atbl_use_dmem;
+ u32 fixed_s3a_deci_log;
+} __packed;
+
+struct imgu_abi_binary_dpc_info {
+ u32 bnr_lite; /* bnr lite enable flag */
+} __packed;
+
+struct imgu_abi_binary_iterator_info {
+ u32 num_stripes;
+ u32 row_stripes_height;
+ u32 row_stripes_overlap_lines;
+} __packed;
+
+struct imgu_abi_binary_address_info {
+ u32 isp_addresses; /* Address in ISP dmem */
+ u32 main_entry; /* Address of entry fct */
+ u32 in_frame; /* Address in ISP dmem */
+ u32 out_frame; /* Address in ISP dmem */
+ u32 in_data; /* Address in ISP dmem */
+ u32 out_data; /* Address in ISP dmem */
+ u32 sh_dma_cmd_ptr; /* In ISP dmem */
+} __packed;
+
+struct imgu_abi_binary_uds_info {
+ u16 bpp;
+ u16 use_bci;
+ u16 use_str;
+ u16 woix;
+ u16 woiy;
+ u16 extra_out_vecs;
+ u16 vectors_per_line_in;
+ u16 vectors_per_line_out;
+ u16 vectors_c_per_line_in;
+ u16 vectors_c_per_line_out;
+ u16 vmem_gdc_in_block_height_y;
+ u16 vmem_gdc_in_block_height_c;
+} __packed;
+
+struct imgu_abi_binary_block_info {
+ u32 block_width;
+ u32 block_height;
+ u32 output_block_height;
+} __packed;
+
+struct imgu_abi_isp_data {
+ imgu_addr_t address; /* ISP address */
+ u32 size; /* Disabled if 0 */
+} __packed;
+
+struct imgu_abi_isp_param_segments {
+ struct imgu_abi_isp_data
+ params[IMGU_ABI_PARAM_CLASS_NUM][IMGU_ABI_NUM_MEMORIES];
+} __packed;
+
+struct imgu_abi_binary_info {
+ u32 id __aligned(8); /* IMGU_ABI_BINARY_ID_* */
+ struct imgu_abi_binary_pipeline_info pipeline;
+ struct imgu_abi_binary_input_info input;
+ struct imgu_abi_binary_output_info output;
+ struct imgu_abi_binary_internal_info internal;
+ struct imgu_abi_binary_bds_info bds;
+ struct imgu_abi_binary_dvs_info dvs;
+ struct imgu_abi_binary_vf_dec_info vf_dec;
+ struct imgu_abi_binary_s3a_info s3a;
+ struct imgu_abi_binary_dpc_info dpc_bnr; /* DPC related binary info */
+ struct imgu_abi_binary_iterator_info iterator;
+ struct imgu_abi_binary_address_info addresses;
+ struct imgu_abi_binary_uds_info uds;
+ struct imgu_abi_binary_block_info block;
+ struct imgu_abi_isp_param_segments mem_initializers;
+ struct {
+ u8 input_feeder;
+ u8 output_system;
+ u8 obgrid;
+ u8 lin;
+ u8 dpc_acc;
+ u8 bds_acc;
+ u8 shd_acc;
+ u8 shd_ff;
+ u8 stats_3a_raw_buffer;
+ u8 acc_bayer_denoise;
+ u8 bnr_ff;
+ u8 awb_acc;
+ u8 awb_fr_acc;
+ u8 anr_acc;
+ u8 rgbpp_acc;
+ u8 rgbpp_ff;
+ u8 demosaic_acc;
+ u8 demosaic_ff;
+ u8 dvs_stats;
+ u8 lace_stats;
+ u8 yuvp1_b0_acc;
+ u8 yuvp1_c0_acc;
+ u8 yuvp2_acc;
+ u8 ae;
+ u8 af;
+ u8 dergb;
+ u8 rgb2yuv;
+ u8 high_quality;
+ u8 kerneltest;
+ u8 routing_shd_to_bnr; /* connect SHD with BNR ACCs */
+ u8 routing_bnr_to_anr; /* connect BNR with ANR ACCs */
+ u8 routing_anr_to_de; /* connect ANR with DE ACCs */
+ u8 routing_rgb_to_yuvp1; /* connect RGB with YUVP1 */
+ u8 routing_yuvp1_to_yuvp2; /* connect YUVP1 with YUVP2 */
+ u8 luma_only;
+ u8 input_yuv;
+ u8 input_raw;
+ u8 reduced_pipe;
+ u8 vf_veceven;
+ u8 dis;
+ u8 dvs_envelope;
+ u8 uds;
+ u8 dvs_6axis;
+ u8 block_output;
+ u8 streaming_dma;
+ u8 ds;
+ u8 bayer_fir_6db;
+ u8 raw_binning;
+ u8 continuous;
+ u8 s3a;
+ u8 fpnr;
+ u8 sc;
+ u8 macc;
+ u8 output;
+ u8 ref_frame;
+ u8 tnr;
+ u8 xnr;
+ u8 params;
+ u8 ca_gdc;
+ u8 isp_addresses;
+ u8 in_frame;
+ u8 out_frame;
+ u8 high_speed;
+ u8 dpc;
+ u8 padding[2];
+ u8 rgbir;
+ } enable;
+ struct {
+ u8 ref_y_channel;
+ u8 ref_c_channel;
+ u8 tnr_channel;
+ u8 tnr_out_channel;
+ u8 dvs_coords_channel;
+ u8 output_channel;
+ u8 c_channel;
+ u8 vfout_channel;
+ u8 vfout_c_channel;
+ u8 vfdec_bits_per_pixel;
+ u8 claimed_by_isp;
+ u8 padding[2];
+ } dma;
+} __packed;
+
+struct imgu_abi_isp_stage {
+ struct imgu_abi_blob_info blob_info;
+ struct imgu_abi_binary_info binary_info;
+ char binary_name[IMGU_ABI_MAX_BINARY_NAME];
+ struct imgu_abi_isp_param_segments mem_initializers;
+} __packed;
+
+/***** struct imgu_abi_ddr_address_map and parameter set *****/
+
+/* xmem address map allocation */
+struct imgu_abi_ddr_address_map {
+ imgu_addr_t isp_mem_param[IMGU_ABI_MAX_STAGES][IMGU_ABI_NUM_MEMORIES];
+ imgu_addr_t obgrid_tbl[IPU3_UAPI_MAX_STRIPES];
+ imgu_addr_t acc_cluster_params_for_sp;
+ imgu_addr_t dvs_6axis_params_y;
+} __packed;
+
+struct imgu_abi_parameter_set_info {
+ /* Pointers to Parameters in ISP format IMPT */
+ struct imgu_abi_ddr_address_map mem_map;
+ /* Unique ID to track per-frame configurations */
+ u32 isp_parameters_id;
+ /* Output frame to which this config has to be applied (optional) */
+ imgu_addr_t output_frame_ptr;
+} __packed;
+
+/***** struct imgu_abi_sp_group *****/
+
+/* SP configuration information */
+struct imgu_abi_sp_config {
+ u8 no_isp_sync; /* Signal host immediately after start */
+ u8 enable_raw_pool_locking; /* Enable Raw Buffer Locking for HALv3 */
+ u8 lock_all;
+ u8 disable_cont_vf;
+ u8 disable_preview_on_capture;
+ u8 padding[3];
+} __packed;
+
+/* Information for a pipeline */
+struct imgu_abi_sp_pipeline {
+ u32 pipe_id; /* the pipe ID */
+ u32 pipe_num; /* the dynamic pipe number */
+ u32 thread_id; /* the sp thread ID */
+ u32 pipe_config; /* the pipe config */
+ u32 pipe_qos_config; /* Bitmap of multiple QOS extension fw
+ * state, 0xffffffff indicates non
+ * QOS pipe.
+ */
+ u32 inout_port_config;
+ u32 required_bds_factor;
+ u32 dvs_frame_delay;
+ u32 num_stages; /* the pipe config */
+ u32 running; /* needed for pipe termination */
+ imgu_addr_t sp_stage_addr[IMGU_ABI_MAX_STAGES];
+ imgu_addr_t scaler_pp_lut; /* Early bound LUT */
+ u32 stage; /* stage ptr is only used on sp */
+ s32 num_execs; /* number of times to run if this is
+ * an acceleration pipe.
+ */
+ union {
+ struct {
+ u32 bytes_available;
+ } bin;
+ struct {
+ u32 height;
+ u32 width;
+ u32 padded_width;
+ u32 max_input_width;
+ u32 raw_bit_depth;
+ } raw;
+ } copy;
+
+ /* Parameters passed to Shading Correction kernel. */
+ struct {
+ /* Origin X (bqs) of internal frame on shading table */
+ u32 internal_frame_origin_x_bqs_on_sctbl;
+ /* Origin Y (bqs) of internal frame on shading table */
+ u32 internal_frame_origin_y_bqs_on_sctbl;
+ } shading;
+} __packed;
+
+struct imgu_abi_sp_debug_command {
+ /*
+ * The DMA software-mask,
+ * Bit 31...24: unused.
+ * Bit 23...16: unused.
+ * Bit 15...08: reading-request enabling bits for DMA channel 7..0
+ * Bit 07...00: writing-request enabling bits for DMA channel 7..0
+ *
+ * For example, "0...0 0...0 11111011 11111101" indicates that the
+ * writing request through DMA Channel 1 and the reading request
+ * through DMA channel 2 are both disabled. The others are enabled.
+ */
+ u32 dma_sw_reg;
+} __packed;
+
+/*
+ * Group all host initialized SP variables into this struct.
+ * This is initialized every stage through dma.
+ * The stage part itself is transferred through imgu_abi_sp_stage.
+ */
+struct imgu_abi_sp_group {
+ struct imgu_abi_sp_config config;
+ struct imgu_abi_sp_pipeline pipe[IMGU_ABI_MAX_SP_THREADS];
+ struct imgu_abi_sp_debug_command debug;
+} __packed;
+
+/***** parameter and state class binary configurations *****/
+
+struct imgu_abi_isp_iterator_config {
+ struct imgu_abi_frame_sp_info input_info;
+ struct imgu_abi_frame_sp_info internal_info;
+ struct imgu_abi_frame_sp_info output_info;
+ struct imgu_abi_frame_sp_info vf_info;
+ struct imgu_abi_sp_resolution dvs_envelope;
+} __packed;
+
+struct imgu_abi_dma_port_config {
+ u8 crop, elems;
+ u16 width;
+ u32 stride;
+} __packed;
+
+struct imgu_abi_isp_ref_config {
+ u32 width_a_over_b;
+ struct imgu_abi_dma_port_config port_b;
+ u32 ref_frame_addr_y[IMGU_ABI_FRAMES_REF];
+ u32 ref_frame_addr_c[IMGU_ABI_FRAMES_REF];
+ u32 dvs_frame_delay;
+} __packed;
+
+struct imgu_abi_isp_ref_dmem_state {
+ u32 ref_in_buf_idx;
+ u32 ref_out_buf_idx;
+} __packed;
+
+struct imgu_abi_isp_dvs_config {
+ u32 num_horizontal_blocks;
+ u32 num_vertical_blocks;
+} __packed;
+
+struct imgu_abi_isp_tnr3_config {
+ u32 width_a_over_b;
+ u32 frame_height;
+ struct imgu_abi_dma_port_config port_b;
+ u32 delay_frame;
+ u32 frame_addr[IMGU_ABI_FRAMES_TNR];
+} __packed;
+
+struct imgu_abi_isp_tnr3_dmem_state {
+ u32 in_bufidx;
+ u32 out_bufidx;
+ u32 total_frame_counter;
+ u32 buffer_frame_counter[IMGU_ABI_BUF_SETS_TNR];
+ u32 bypass_filter;
+} __packed;
+
+/***** Queues *****/
+
+struct imgu_abi_queue_info {
+ u8 size; /* the maximum number of elements*/
+ u8 step; /* number of bytes per element */
+ u8 start; /* index of the oldest element */
+ u8 end; /* index at which to write the new element */
+} __packed;
+
+struct imgu_abi_queues {
+ /*
+ * Queues for the dynamic frame information,
+ * i.e. the "in_frame" buffer, the "out_frame"
+ * buffer and the "vf_out_frame" buffer.
+ */
+ struct imgu_abi_queue_info host2sp_bufq_info
+ [IMGU_ABI_MAX_SP_THREADS][IMGU_ABI_QUEUE_NUM];
+ u32 host2sp_bufq[IMGU_ABI_MAX_SP_THREADS][IMGU_ABI_QUEUE_NUM]
+ [IMGU_ABI_HOST2SP_BUFQ_SIZE];
+ struct imgu_abi_queue_info sp2host_bufq_info[IMGU_ABI_QUEUE_NUM];
+ u32 sp2host_bufq[IMGU_ABI_QUEUE_NUM][IMGU_ABI_SP2HOST_BUFQ_SIZE];
+
+ /*
+ * The queues for the events.
+ */
+ struct imgu_abi_queue_info host2sp_evtq_info;
+ u32 host2sp_evtq[IMGU_ABI_HOST2SP_EVTQ_SIZE];
+ struct imgu_abi_queue_info sp2host_evtq_info;
+ u32 sp2host_evtq[IMGU_ABI_SP2HOST_EVTQ_SIZE];
+} __packed;
+
+/***** Buffer descriptor *****/
+
+struct imgu_abi_metadata_info {
+ struct imgu_abi_resolution resolution; /* Resolution */
+ u32 stride; /* Stride in bytes */
+ u32 size; /* Total size in bytes */
+} __packed;
+
+struct imgu_abi_isp_3a_statistics {
+ union {
+ struct {
+ imgu_addr_t s3a_tbl;
+ } dmem;
+ struct {
+ imgu_addr_t s3a_tbl_hi;
+ imgu_addr_t s3a_tbl_lo;
+ } vmem;
+ } data;
+ struct {
+ imgu_addr_t rgby_tbl;
+ } data_hmem;
+ u32 exp_id; /* exposure id, to match statistics to a frame, */
+ u32 isp_config_id; /* Tracks per-frame configs */
+ imgu_addr_t data_ptr; /* pointer to base of all data */
+ u32 size; /* total size of all data */
+ u32 dmem_size;
+ u32 vmem_size; /* both lo and hi have this size */
+ u32 hmem_size;
+} __packed;
+
+struct imgu_abi_metadata {
+ struct imgu_abi_metadata_info info; /* Layout info */
+ imgu_addr_t address; /* CSS virtual address */
+ u32 exp_id; /* Exposure ID */
+} __packed;
+
+struct imgu_abi_time_meas {
+ u32 start_timer_value; /* measured time in ticks */
+ u32 end_timer_value; /* measured time in ticks */
+} __packed;
+
+struct imgu_abi_buffer {
+ union {
+ struct imgu_abi_isp_3a_statistics s3a;
+ u8 reserved[28];
+ imgu_addr_t skc_dvs_statistics;
+ imgu_addr_t lace_stat;
+ struct imgu_abi_metadata metadata;
+ struct {
+ imgu_addr_t frame_data;
+ u32 flashed;
+ u32 exp_id;
+ u32 isp_parameters_id; /* Tracks per-frame configs */
+ u32 padded_width;
+ } frame;
+ imgu_addr_t ddr_ptrs;
+ } payload;
+ /*
+ * kernel_ptr is present for host administration purposes only.
+ * type is uint64_t in order to be 64-bit host compatible.
+ * uint64_t does not exist on SP/ISP.
+ * Size of the struct is checked by sp.hive.c.
+ */
+ u64 cookie_ptr __aligned(8);
+ u64 kernel_ptr;
+ struct imgu_abi_time_meas timing_data;
+ u32 isys_eof_clock_tick;
+} __packed;
+
+struct imgu_abi_bl_dma_cmd_entry {
+ u32 src_addr; /* virtual DDR address */
+ u32 size; /* number of bytes to transferred */
+ u32 dst_type;
+ u32 dst_addr; /* hmm address of xMEM or MMIO */
+} __packed;
+
+struct imgu_abi_sp_init_dmem_cfg {
+ u32 ddr_data_addr; /* data segment address in ddr */
+ u32 dmem_data_addr; /* data segment address in dmem */
+ u32 dmem_bss_addr; /* bss segment address in dmem */
+ u32 data_size; /* data segment size */
+ u32 bss_size; /* bss segment size */
+ u32 sp_id; /* sp id */
+} __packed;
+
+#endif
diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.c b/drivers/staging/media/ipu3/ipu3-css-fw.c
new file mode 100644
index 000000000000..55861aa8fb03
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-css-fw.c
@@ -0,0 +1,265 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Intel Corporation
+
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include "ipu3-css.h"
+#include "ipu3-css-fw.h"
+#include "ipu3-dmamap.h"
+
+static void ipu3_css_fw_show_binary(struct device *dev, struct imgu_fw_info *bi,
+ const char *name)
+{
+ unsigned int i;
+
+ dev_dbg(dev, "found firmware binary type %i size %i name %s\n",
+ bi->type, bi->blob.size, name);
+ if (bi->type != IMGU_FW_ISP_FIRMWARE)
+ return;
+
+ dev_dbg(dev, " id %i mode %i bds 0x%x veceven %i/%i out_pins %i\n",
+ bi->info.isp.sp.id, bi->info.isp.sp.pipeline.mode,
+ bi->info.isp.sp.bds.supported_bds_factors,
+ bi->info.isp.sp.enable.vf_veceven,
+ bi->info.isp.sp.vf_dec.is_variable,
+ bi->info.isp.num_output_pins);
+
+ dev_dbg(dev, " input (%i,%i)-(%i,%i) formats %s%s%s\n",
+ bi->info.isp.sp.input.min_width,
+ bi->info.isp.sp.input.min_height,
+ bi->info.isp.sp.input.max_width,
+ bi->info.isp.sp.input.max_height,
+ bi->info.isp.sp.enable.input_yuv ? "yuv420 " : "",
+ bi->info.isp.sp.enable.input_feeder ||
+ bi->info.isp.sp.enable.input_raw ? "raw8 raw10 " : "",
+ bi->info.isp.sp.enable.input_raw ? "raw12" : "");
+
+ dev_dbg(dev, " internal (%i,%i)\n",
+ bi->info.isp.sp.internal.max_width,
+ bi->info.isp.sp.internal.max_height);
+
+ dev_dbg(dev, " output (%i,%i)-(%i,%i) formats",
+ bi->info.isp.sp.output.min_width,
+ bi->info.isp.sp.output.min_height,
+ bi->info.isp.sp.output.max_width,
+ bi->info.isp.sp.output.max_height);
+ for (i = 0; i < bi->info.isp.num_output_formats; i++)
+ dev_dbg(dev, " %i", bi->info.isp.output_formats[i]);
+ dev_dbg(dev, " vf");
+ for (i = 0; i < bi->info.isp.num_vf_formats; i++)
+ dev_dbg(dev, " %i", bi->info.isp.vf_formats[i]);
+ dev_dbg(dev, "\n");
+}
+
+unsigned int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi)
+{
+ unsigned int width = DIV_ROUND_UP(bi->info.isp.sp.internal.max_width,
+ IMGU_OBGRID_TILE_SIZE * 2) + 1;
+ unsigned int height = DIV_ROUND_UP(bi->info.isp.sp.internal.max_height,
+ IMGU_OBGRID_TILE_SIZE * 2) + 1;
+ unsigned int obgrid_size;
+
+ width = ALIGN(width, IPU3_UAPI_ISP_VEC_ELEMS / 4);
+ obgrid_size = PAGE_ALIGN(width * height *
+ sizeof(struct ipu3_uapi_obgrid_param)) *
+ bi->info.isp.sp.iterator.num_stripes;
+ return obgrid_size;
+}
+
+void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, unsigned int pipe,
+ enum imgu_abi_param_class cls,
+ enum imgu_abi_memories mem,
+ struct imgu_fw_isp_parameter *par,
+ size_t par_size, void *binary_params)
+{
+ struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css->pipes[pipe].bindex];
+
+ if (par->offset + par->size >
+ bi->info.isp.sp.mem_initializers.params[cls][mem].size)
+ return NULL;
+
+ if (par->size != par_size)
+ pr_warn("parameter size doesn't match defined size\n");
+
+ if (par->size < par_size)
+ return NULL;
+
+ return binary_params + par->offset;
+}
+
+void ipu3_css_fw_cleanup(struct ipu3_css *css)
+{
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+
+ if (css->binary) {
+ unsigned int i;
+
+ for (i = 0; i < css->fwp->file_header.binary_nr; i++)
+ ipu3_dmamap_free(imgu, &css->binary[i]);
+ kfree(css->binary);
+ }
+ if (css->fw)
+ release_firmware(css->fw);
+
+ css->binary = NULL;
+ css->fw = NULL;
+}
+
+int ipu3_css_fw_init(struct ipu3_css *css)
+{
+ static const u32 BLOCK_MAX = 65536;
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+ struct device *dev = css->dev;
+ unsigned int i, j, binary_nr;
+ int r;
+
+ r = request_firmware(&css->fw, IMGU_FW_NAME, css->dev);
+ if (r)
+ return r;
+
+ /* Check and display fw header info */
+
+ css->fwp = (struct imgu_fw_header *)css->fw->data;
+ if (css->fw->size < sizeof(struct imgu_fw_header *) ||
+ css->fwp->file_header.h_size != sizeof(struct imgu_fw_bi_file_h))
+ goto bad_fw;
+ if (sizeof(struct imgu_fw_bi_file_h) +
+ css->fwp->file_header.binary_nr * sizeof(struct imgu_fw_info) >
+ css->fw->size)
+ goto bad_fw;
+
+ dev_info(dev, "loaded firmware version %.64s, %u binaries, %zu bytes\n",
+ css->fwp->file_header.version, css->fwp->file_header.binary_nr,
+ css->fw->size);
+
+ /* Validate and display info on fw binaries */
+
+ binary_nr = css->fwp->file_header.binary_nr;
+
+ css->fw_bl = -1;
+ css->fw_sp[0] = -1;
+ css->fw_sp[1] = -1;
+
+ for (i = 0; i < binary_nr; i++) {
+ struct imgu_fw_info *bi = &css->fwp->binary_header[i];
+ const char *name = (void *)css->fwp + bi->blob.prog_name_offset;
+ size_t len;
+
+ if (bi->blob.prog_name_offset >= css->fw->size)
+ goto bad_fw;
+ len = strnlen(name, css->fw->size - bi->blob.prog_name_offset);
+ if (len + 1 > css->fw->size - bi->blob.prog_name_offset ||
+ len + 1 >= IMGU_ABI_MAX_BINARY_NAME)
+ goto bad_fw;
+
+ if (bi->blob.size != bi->blob.text_size + bi->blob.icache_size
+ + bi->blob.data_size + bi->blob.padding_size)
+ goto bad_fw;
+ if (bi->blob.offset + bi->blob.size > css->fw->size)
+ goto bad_fw;
+
+ if (bi->type == IMGU_FW_BOOTLOADER_FIRMWARE) {
+ css->fw_bl = i;
+ if (bi->info.bl.sw_state >= css->iomem_length ||
+ bi->info.bl.num_dma_cmds >= css->iomem_length ||
+ bi->info.bl.dma_cmd_list >= css->iomem_length)
+ goto bad_fw;
+ }
+ if (bi->type == IMGU_FW_SP_FIRMWARE ||
+ bi->type == IMGU_FW_SP1_FIRMWARE) {
+ css->fw_sp[bi->type == IMGU_FW_SP_FIRMWARE ? 0 : 1] = i;
+ if (bi->info.sp.per_frame_data >= css->iomem_length ||
+ bi->info.sp.init_dmem_data >= css->iomem_length ||
+ bi->info.sp.host_sp_queue >= css->iomem_length ||
+ bi->info.sp.isp_started >= css->iomem_length ||
+ bi->info.sp.sw_state >= css->iomem_length ||
+ bi->info.sp.sleep_mode >= css->iomem_length ||
+ bi->info.sp.invalidate_tlb >= css->iomem_length ||
+ bi->info.sp.host_sp_com >= css->iomem_length ||
+ bi->info.sp.output + 12 >= css->iomem_length ||
+ bi->info.sp.host_sp_queues_initialized >=
+ css->iomem_length)
+ goto bad_fw;
+ }
+ if (bi->type != IMGU_FW_ISP_FIRMWARE)
+ continue;
+
+ if (bi->info.isp.sp.pipeline.mode >= IPU3_CSS_PIPE_ID_NUM)
+ goto bad_fw;
+
+ if (bi->info.isp.sp.iterator.num_stripes >
+ IPU3_UAPI_MAX_STRIPES)
+ goto bad_fw;
+
+ if (bi->info.isp.num_vf_formats > IMGU_ABI_FRAME_FORMAT_NUM ||
+ bi->info.isp.num_output_formats > IMGU_ABI_FRAME_FORMAT_NUM)
+ goto bad_fw;
+
+ for (j = 0; j < bi->info.isp.num_output_formats; j++)
+ if (bi->info.isp.output_formats[j] < 0 ||
+ bi->info.isp.output_formats[j] >=
+ IMGU_ABI_FRAME_FORMAT_NUM)
+ goto bad_fw;
+ for (j = 0; j < bi->info.isp.num_vf_formats; j++)
+ if (bi->info.isp.vf_formats[j] < 0 ||
+ bi->info.isp.vf_formats[j] >=
+ IMGU_ABI_FRAME_FORMAT_NUM)
+ goto bad_fw;
+
+ if (bi->info.isp.sp.block.block_width <= 0 ||
+ bi->info.isp.sp.block.block_width > BLOCK_MAX ||
+ bi->info.isp.sp.block.output_block_height <= 0 ||
+ bi->info.isp.sp.block.output_block_height > BLOCK_MAX)
+ goto bad_fw;
+
+ if (bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_PARAM]
+ + sizeof(struct imgu_fw_param_memory_offsets) >
+ css->fw->size ||
+ bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_CONFIG]
+ + sizeof(struct imgu_fw_config_memory_offsets) >
+ css->fw->size ||
+ bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_STATE]
+ + sizeof(struct imgu_fw_state_memory_offsets) >
+ css->fw->size)
+ goto bad_fw;
+
+ ipu3_css_fw_show_binary(dev, bi, name);
+ }
+
+ if (css->fw_bl == -1 || css->fw_sp[0] == -1 || css->fw_sp[1] == -1)
+ goto bad_fw;
+
+ /* Allocate and map fw binaries into IMGU */
+
+ css->binary = kcalloc(binary_nr, sizeof(*css->binary), GFP_KERNEL);
+ if (!css->binary) {
+ r = -ENOMEM;
+ goto error_out;
+ }
+
+ for (i = 0; i < css->fwp->file_header.binary_nr; i++) {
+ struct imgu_fw_info *bi = &css->fwp->binary_header[i];
+ void *blob = (void *)css->fwp + bi->blob.offset;
+ size_t size = bi->blob.size;
+
+ if (!ipu3_dmamap_alloc(imgu, &css->binary[i], size)) {
+ r = -ENOMEM;
+ goto error_out;
+ }
+ memcpy(css->binary[i].vaddr, blob, size);
+ }
+
+ return 0;
+
+bad_fw:
+ dev_err(dev, "invalid firmware binary, size %u\n", (int)css->fw->size);
+ r = -ENODEV;
+
+error_out:
+ ipu3_css_fw_cleanup(css);
+ return r;
+}
diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.h b/drivers/staging/media/ipu3/ipu3-css-fw.h
new file mode 100644
index 000000000000..07d8bb8b25f3
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-css-fw.h
@@ -0,0 +1,188 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 Intel Corporation */
+
+#ifndef __IPU3_CSS_FW_H
+#define __IPU3_CSS_FW_H
+
+/******************* Firmware file definitions *******************/
+
+#define IMGU_FW_NAME "intel/ipu3-fw.bin"
+
+typedef u32 imgu_fw_ptr;
+
+enum imgu_fw_type {
+ IMGU_FW_SP_FIRMWARE, /* Firmware for the SP */
+ IMGU_FW_SP1_FIRMWARE, /* Firmware for the SP1 */
+ IMGU_FW_ISP_FIRMWARE, /* Firmware for the ISP */
+ IMGU_FW_BOOTLOADER_FIRMWARE, /* Firmware for the BootLoader */
+ IMGU_FW_ACC_FIRMWARE /* Firmware for accelerations */
+};
+
+enum imgu_fw_acc_type {
+ IMGU_FW_ACC_NONE, /* Normal binary */
+ IMGU_FW_ACC_OUTPUT, /* Accelerator stage on output frame */
+ IMGU_FW_ACC_VIEWFINDER, /* Accelerator stage on viewfinder frame */
+ IMGU_FW_ACC_STANDALONE, /* Stand-alone acceleration */
+};
+
+struct imgu_fw_isp_parameter {
+ u32 offset; /* Offset in isp_<mem> config, params, etc. */
+ u32 size; /* Disabled if 0 */
+};
+
+struct imgu_fw_param_memory_offsets {
+ struct {
+ struct imgu_fw_isp_parameter lin; /* lin_vmem_params */
+ struct imgu_fw_isp_parameter tnr3; /* tnr3_vmem_params */
+ struct imgu_fw_isp_parameter xnr3; /* xnr3_vmem_params */
+ } vmem;
+ struct {
+ struct imgu_fw_isp_parameter tnr;
+ struct imgu_fw_isp_parameter tnr3; /* tnr3_params */
+ struct imgu_fw_isp_parameter xnr3; /* xnr3_params */
+ struct imgu_fw_isp_parameter plane_io_config; /* 192 bytes */
+ struct imgu_fw_isp_parameter rgbir; /* rgbir_params */
+ } dmem;
+};
+
+struct imgu_fw_config_memory_offsets {
+ struct {
+ struct imgu_fw_isp_parameter iterator;
+ struct imgu_fw_isp_parameter dvs;
+ struct imgu_fw_isp_parameter output;
+ struct imgu_fw_isp_parameter raw;
+ struct imgu_fw_isp_parameter input_yuv;
+ struct imgu_fw_isp_parameter tnr;
+ struct imgu_fw_isp_parameter tnr3;
+ struct imgu_fw_isp_parameter ref;
+ } dmem;
+};
+
+struct imgu_fw_state_memory_offsets {
+ struct {
+ struct imgu_fw_isp_parameter tnr;
+ struct imgu_fw_isp_parameter tnr3;
+ struct imgu_fw_isp_parameter ref;
+ } dmem;
+};
+
+union imgu_fw_all_memory_offsets {
+ struct {
+ u64 imgu_fw_mem_offsets[3]; /* params, config, state */
+ } offsets;
+ struct {
+ u64 ptr;
+ } array[IMGU_ABI_PARAM_CLASS_NUM];
+};
+
+struct imgu_fw_binary_xinfo {
+ /* Part that is of interest to the SP. */
+ struct imgu_abi_binary_info sp;
+
+ /* Rest of the binary info, only interesting to the host. */
+ u32 type; /* enum imgu_fw_acc_type */
+
+ u32 num_output_formats __aligned(8);
+ u32 output_formats[IMGU_ABI_FRAME_FORMAT_NUM]; /* enum frame_format */
+
+ /* number of supported vf formats */
+ u32 num_vf_formats __aligned(8);
+ /* types of supported vf formats */
+ u32 vf_formats[IMGU_ABI_FRAME_FORMAT_NUM]; /* enum frame_format */
+ u8 num_output_pins;
+ imgu_fw_ptr xmem_addr;
+
+ u64 imgu_fw_blob_descr_ptr __aligned(8);
+ u32 blob_index __aligned(8);
+ union imgu_fw_all_memory_offsets mem_offsets __aligned(8);
+ struct imgu_fw_binary_xinfo *next __aligned(8);
+};
+
+struct imgu_fw_sp_info {
+ u32 init_dmem_data; /* data sect config, stored to dmem */
+ u32 per_frame_data; /* Per frame data, stored to dmem */
+ u32 group; /* Per pipeline data, loaded by dma */
+ u32 output; /* SP output data, loaded by dmem */
+ u32 host_sp_queue; /* Host <-> SP queues */
+ u32 host_sp_com; /* Host <-> SP commands */
+ u32 isp_started; /* P'ed from sensor thread, csim only */
+ u32 sw_state; /* Polled from css, enum imgu_abi_sp_swstate */
+ u32 host_sp_queues_initialized; /* Polled from the SP */
+ u32 sleep_mode; /* different mode to halt SP */
+ u32 invalidate_tlb; /* inform SP to invalidate mmu TLB */
+ u32 debug_buffer_ddr_address; /* the addr of DDR debug queue */
+
+ /* input system perf count array */
+ u32 perf_counter_input_system_error;
+ u32 threads_stack; /* sp thread's stack pointers */
+ u32 threads_stack_size; /* sp thread's stack sizes */
+ u32 curr_binary_id; /* current binary id */
+ u32 raw_copy_line_count; /* raw copy line counter */
+ u32 ddr_parameter_address; /* acc param ddrptr, sp dmem */
+ u32 ddr_parameter_size; /* acc param size, sp dmem */
+ /* Entry functions */
+ u32 sp_entry; /* The SP entry function */
+ u32 tagger_frames_addr; /* Base address of tagger state */
+};
+
+struct imgu_fw_bl_info {
+ u32 num_dma_cmds; /* Number of cmds sent by CSS */
+ u32 dma_cmd_list; /* Dma command list sent by CSS */
+ u32 sw_state; /* Polled from css, enum imgu_abi_bl_swstate */
+ /* Entry functions */
+ u32 bl_entry; /* The SP entry function */
+};
+
+struct imgu_fw_acc_info {
+ u32 per_frame_data; /* Dummy for now */
+};
+
+union imgu_fw_union {
+ struct imgu_fw_binary_xinfo isp; /* ISP info */
+ struct imgu_fw_sp_info sp; /* SP info */
+ struct imgu_fw_sp_info sp1; /* SP1 info */
+ struct imgu_fw_bl_info bl; /* Bootloader info */
+ struct imgu_fw_acc_info acc; /* Accelerator info */
+};
+
+struct imgu_fw_info {
+ size_t header_size; /* size of fw header */
+ u32 type __aligned(8); /* enum imgu_fw_type */
+ union imgu_fw_union info; /* Binary info */
+ struct imgu_abi_blob_info blob; /* Blob info */
+ /* Dynamic part */
+ u64 next;
+
+ u32 loaded __aligned(8); /* Firmware has been loaded */
+ const u64 isp_code __aligned(8); /* ISP pointer to code */
+ /* Firmware handle between user space and kernel */
+ u32 handle __aligned(8);
+ /* Sections to copy from/to ISP */
+ struct imgu_abi_isp_param_segments mem_initializers;
+ /* Initializer for local ISP memories */
+};
+
+struct imgu_fw_bi_file_h {
+ char version[64]; /* branch tag + week day + time */
+ int binary_nr; /* Number of binaries */
+ unsigned int h_size; /* sizeof(struct imgu_fw_bi_file_h) */
+};
+
+struct imgu_fw_header {
+ struct imgu_fw_bi_file_h file_header;
+ struct imgu_fw_info binary_header[1]; /* binary_nr items */
+};
+
+/******************* Firmware functions *******************/
+
+int ipu3_css_fw_init(struct ipu3_css *css);
+void ipu3_css_fw_cleanup(struct ipu3_css *css);
+
+unsigned int ipu3_css_fw_obgrid_size(const struct imgu_fw_info *bi);
+void *ipu3_css_fw_pipeline_params(struct ipu3_css *css, unsigned int pipe,
+ enum imgu_abi_param_class cls,
+ enum imgu_abi_memories mem,
+ struct imgu_fw_isp_parameter *par,
+ size_t par_size, void *binary_params);
+
+#endif
diff --git a/drivers/staging/media/ipu3/ipu3-css-params.c b/drivers/staging/media/ipu3/ipu3-css-params.c
new file mode 100644
index 000000000000..776206ded83b
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-css-params.c
@@ -0,0 +1,2943 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Intel Corporation
+
+#include <linux/device.h>
+
+#include "ipu3-css.h"
+#include "ipu3-css-fw.h"
+#include "ipu3-tables.h"
+
+#define DIV_ROUND_CLOSEST_DOWN(a, b) (((a) + ((b) / 2) - 1) / (b))
+#define roundclosest_down(a, b) (DIV_ROUND_CLOSEST_DOWN(a, b) * (b))
+
+#define IPU3_UAPI_ANR_MAX_RESET ((1 << 12) - 1)
+#define IPU3_UAPI_ANR_MIN_RESET (((-1) << 12) + 1)
+
+struct ipu3_css_scaler_info {
+ unsigned int phase_step; /* Same for luma/chroma */
+ int exp_shift;
+
+ unsigned int phase_init; /* luma/chroma dependent */
+ int pad_left;
+ int pad_right;
+ int crop_left;
+ int crop_top;
+};
+
+static unsigned int ipu3_css_scaler_get_exp(unsigned int counter,
+ unsigned int divider)
+{
+ int i = fls(divider) - fls(counter);
+
+ if (i <= 0)
+ return 0;
+
+ if (divider >> i < counter)
+ i = i - 1;
+
+ return i;
+}
+
+/* Set up the CSS scaler look up table */
+static void
+ipu3_css_scaler_setup_lut(unsigned int taps, unsigned int input_width,
+ unsigned int output_width, int phase_step_correction,
+ const int *coeffs, unsigned int coeffs_size,
+ s8 coeff_lut[], struct ipu3_css_scaler_info *info)
+{
+ int tap, phase, phase_sum_left, phase_sum_right;
+ int exponent = ipu3_css_scaler_get_exp(output_width, input_width);
+ int mantissa = (1 << exponent) * output_width;
+ unsigned int phase_step;
+
+ if (input_width == output_width) {
+ for (phase = 0; phase < IMGU_SCALER_PHASES; phase++) {
+ for (tap = 0; tap < taps; tap++) {
+ coeff_lut[phase * IMGU_SCALER_FILTER_TAPS + tap]
+ = 0;
+ }
+ }
+
+ info->phase_step = IMGU_SCALER_PHASES *
+ (1 << IMGU_SCALER_PHASE_COUNTER_PREC_REF);
+ info->exp_shift = 0;
+ info->pad_left = 0;
+ info->pad_right = 0;
+ info->phase_init = 0;
+ info->crop_left = 0;
+ info->crop_top = 0;
+ return;
+ }
+
+ for (phase = 0; phase < IMGU_SCALER_PHASES; phase++) {
+ for (tap = 0; tap < taps; tap++) {
+ /* flip table to for convolution reverse indexing */
+ s64 coeff = coeffs[coeffs_size -
+ ((tap * (coeffs_size / taps)) + phase) - 1];
+ coeff *= mantissa;
+ coeff = div64_long(coeff, input_width);
+
+ /* Add +"0.5" */
+ coeff += 1 << (IMGU_SCALER_COEFF_BITS - 1);
+ coeff >>= IMGU_SCALER_COEFF_BITS;
+
+ coeff_lut[phase * IMGU_SCALER_FILTER_TAPS + tap] =
+ coeff;
+ }
+ }
+
+ phase_step = IMGU_SCALER_PHASES *
+ (1 << IMGU_SCALER_PHASE_COUNTER_PREC_REF) *
+ output_width / input_width;
+ phase_step += phase_step_correction;
+ phase_sum_left = (taps / 2 * IMGU_SCALER_PHASES *
+ (1 << IMGU_SCALER_PHASE_COUNTER_PREC_REF)) -
+ (1 << (IMGU_SCALER_PHASE_COUNTER_PREC_REF - 1));
+ phase_sum_right = (taps / 2 * IMGU_SCALER_PHASES *
+ (1 << IMGU_SCALER_PHASE_COUNTER_PREC_REF)) +
+ (1 << (IMGU_SCALER_PHASE_COUNTER_PREC_REF - 1));
+
+ info->exp_shift = IMGU_SCALER_MAX_EXPONENT_SHIFT - exponent;
+ info->pad_left = (phase_sum_left % phase_step == 0) ?
+ phase_sum_left / phase_step - 1 : phase_sum_left / phase_step;
+ info->pad_right = (phase_sum_right % phase_step == 0) ?
+ phase_sum_right / phase_step - 1 : phase_sum_right / phase_step;
+ info->phase_init = phase_sum_left - phase_step * info->pad_left;
+ info->phase_step = phase_step;
+ info->crop_left = taps - 1;
+ info->crop_top = taps - 1;
+}
+
+/*
+ * Calculates the exact output image width/height, based on phase_step setting
+ * (must be perfectly aligned with hardware).
+ */
+static unsigned int
+ipu3_css_scaler_calc_scaled_output(unsigned int input,
+ struct ipu3_css_scaler_info *info)
+{
+ unsigned int arg1 = input * info->phase_step +
+ (1 - IMGU_SCALER_TAPS_Y / 2) * IMGU_SCALER_FIR_PHASES -
+ IMGU_SCALER_FIR_PHASES / (2 * IMGU_SCALER_PHASES);
+ unsigned int arg2 = ((IMGU_SCALER_TAPS_Y / 2) * IMGU_SCALER_FIR_PHASES +
+ IMGU_SCALER_FIR_PHASES / (2 * IMGU_SCALER_PHASES)) *
+ IMGU_SCALER_FIR_PHASES + info->phase_step / 2;
+
+ return ((arg1 + (arg2 - IMGU_SCALER_FIR_PHASES * info->phase_step) /
+ IMGU_SCALER_FIR_PHASES) / (2 * IMGU_SCALER_FIR_PHASES)) * 2;
+}
+
+/*
+ * Calculate the output width and height, given the luma
+ * and chroma details of a scaler
+ */
+static void
+ipu3_css_scaler_calc(u32 input_width, u32 input_height, u32 target_width,
+ u32 target_height, struct imgu_abi_osys_config *cfg,
+ struct ipu3_css_scaler_info *info_luma,
+ struct ipu3_css_scaler_info *info_chroma,
+ unsigned int *output_width, unsigned int *output_height,
+ unsigned int *procmode)
+{
+ u32 out_width = target_width;
+ u32 out_height = target_height;
+ const unsigned int height_alignment = 2;
+ int phase_step_correction = -1;
+
+ /*
+ * Calculate scaled output width. If the horizontal and vertical scaling
+ * factor is different, then choose the biggest and crop off excess
+ * lines or columns after formatting.
+ */
+ if (target_height * input_width > target_width * input_height)
+ target_width = DIV_ROUND_UP(target_height * input_width,
+ input_height);
+
+ if (input_width == target_width)
+ *procmode = IMGU_ABI_OSYS_PROCMODE_BYPASS;
+ else
+ *procmode = IMGU_ABI_OSYS_PROCMODE_DOWNSCALE;
+
+ memset(&cfg->scaler_coeffs_chroma, 0,
+ sizeof(cfg->scaler_coeffs_chroma));
+ memset(&cfg->scaler_coeffs_luma, 0, sizeof(*cfg->scaler_coeffs_luma));
+ do {
+ phase_step_correction++;
+
+ ipu3_css_scaler_setup_lut(IMGU_SCALER_TAPS_Y,
+ input_width, target_width,
+ phase_step_correction,
+ ipu3_css_downscale_4taps,
+ IMGU_SCALER_DOWNSCALE_4TAPS_LEN,
+ cfg->scaler_coeffs_luma, info_luma);
+
+ ipu3_css_scaler_setup_lut(IMGU_SCALER_TAPS_UV,
+ input_width, target_width,
+ phase_step_correction,
+ ipu3_css_downscale_2taps,
+ IMGU_SCALER_DOWNSCALE_2TAPS_LEN,
+ cfg->scaler_coeffs_chroma,
+ info_chroma);
+
+ out_width = ipu3_css_scaler_calc_scaled_output(input_width,
+ info_luma);
+ out_height = ipu3_css_scaler_calc_scaled_output(input_height,
+ info_luma);
+ } while ((out_width < target_width || out_height < target_height ||
+ !IS_ALIGNED(out_height, height_alignment)) &&
+ phase_step_correction <= 5);
+
+ *output_width = out_width;
+ *output_height = out_height;
+}
+
+/********************** Osys routines for scaler****************************/
+
+static void ipu3_css_osys_set_format(enum imgu_abi_frame_format host_format,
+ unsigned int *osys_format,
+ unsigned int *osys_tiling)
+{
+ *osys_format = IMGU_ABI_OSYS_FORMAT_YUV420;
+ *osys_tiling = IMGU_ABI_OSYS_TILING_NONE;
+
+ switch (host_format) {
+ case IMGU_ABI_FRAME_FORMAT_YUV420:
+ *osys_format = IMGU_ABI_OSYS_FORMAT_YUV420;
+ break;
+ case IMGU_ABI_FRAME_FORMAT_YV12:
+ *osys_format = IMGU_ABI_OSYS_FORMAT_YV12;
+ break;
+ case IMGU_ABI_FRAME_FORMAT_NV12:
+ *osys_format = IMGU_ABI_OSYS_FORMAT_NV12;
+ break;
+ case IMGU_ABI_FRAME_FORMAT_NV16:
+ *osys_format = IMGU_ABI_OSYS_FORMAT_NV16;
+ break;
+ case IMGU_ABI_FRAME_FORMAT_NV21:
+ *osys_format = IMGU_ABI_OSYS_FORMAT_NV21;
+ break;
+ case IMGU_ABI_FRAME_FORMAT_NV12_TILEY:
+ *osys_format = IMGU_ABI_OSYS_FORMAT_NV12;
+ *osys_tiling = IMGU_ABI_OSYS_TILING_Y;
+ break;
+ default:
+ /* For now, assume use default values */
+ break;
+ }
+}
+
+/*
+ * Function calculates input frame stripe offset, based
+ * on output frame stripe offset and filter parameters.
+ */
+static int ipu3_css_osys_calc_stripe_offset(int stripe_offset_out,
+ int fir_phases, int phase_init,
+ int phase_step, int pad_left)
+{
+ int stripe_offset_inp = stripe_offset_out * fir_phases -
+ pad_left * phase_step;
+
+ return DIV_ROUND_UP(stripe_offset_inp - phase_init, phase_step);
+}
+
+/*
+ * Calculate input frame phase, given the output frame
+ * stripe offset and filter parameters
+ */
+static int ipu3_css_osys_calc_stripe_phase_init(int stripe_offset_out,
+ int fir_phases, int phase_init,
+ int phase_step, int pad_left)
+{
+ int stripe_offset_inp =
+ ipu3_css_osys_calc_stripe_offset(stripe_offset_out,
+ fir_phases, phase_init,
+ phase_step, pad_left);
+
+ return phase_init + ((pad_left + stripe_offset_inp) * phase_step) -
+ stripe_offset_out * fir_phases;
+}
+
+/*
+ * This function calculates input frame stripe width,
+ * based on output frame stripe offset and filter parameters
+ */
+static int ipu3_css_osys_calc_inp_stripe_width(int stripe_width_out,
+ int fir_phases, int phase_init,
+ int phase_step, int fir_taps,
+ int pad_left, int pad_right)
+{
+ int stripe_width_inp = (stripe_width_out + fir_taps - 1) * fir_phases;
+
+ stripe_width_inp = DIV_ROUND_UP(stripe_width_inp - phase_init,
+ phase_step);
+
+ return stripe_width_inp - pad_left - pad_right;
+}
+
+/*
+ * This function calculates output frame stripe width, basedi
+ * on output frame stripe offset and filter parameters
+ */
+static int ipu3_css_osys_out_stripe_width(int stripe_width_inp, int fir_phases,
+ int phase_init, int phase_step,
+ int fir_taps, int pad_left,
+ int pad_right, int column_offset)
+{
+ int stripe_width_out = (pad_left + stripe_width_inp +
+ pad_right - column_offset) * phase_step;
+
+ stripe_width_out = (stripe_width_out + phase_init) / fir_phases;
+
+ return stripe_width_out - (fir_taps - 1);
+}
+
+struct ipu3_css_reso {
+ unsigned int input_width;
+ unsigned int input_height;
+ enum imgu_abi_frame_format input_format;
+ unsigned int pin_width[IMGU_ABI_OSYS_PINS];
+ unsigned int pin_height[IMGU_ABI_OSYS_PINS];
+ unsigned int pin_stride[IMGU_ABI_OSYS_PINS];
+ enum imgu_abi_frame_format pin_format[IMGU_ABI_OSYS_PINS];
+ int chunk_width;
+ int chunk_height;
+ int block_height;
+ int block_width;
+};
+
+struct ipu3_css_frame_params {
+ /* Output pins */
+ unsigned int enable;
+ unsigned int format;
+ unsigned int flip;
+ unsigned int mirror;
+ unsigned int tiling;
+ unsigned int reduce_range;
+ unsigned int width;
+ unsigned int height;
+ unsigned int stride;
+ unsigned int scaled;
+ unsigned int crop_left;
+ unsigned int crop_top;
+};
+
+struct ipu3_css_stripe_params {
+ unsigned int processing_mode;
+ unsigned int phase_step;
+ unsigned int exp_shift;
+ unsigned int phase_init_left_y;
+ unsigned int phase_init_left_uv;
+ unsigned int phase_init_top_y;
+ unsigned int phase_init_top_uv;
+ unsigned int pad_left_y;
+ unsigned int pad_left_uv;
+ unsigned int pad_right_y;
+ unsigned int pad_right_uv;
+ unsigned int pad_top_y;
+ unsigned int pad_top_uv;
+ unsigned int pad_bottom_y;
+ unsigned int pad_bottom_uv;
+ unsigned int crop_left_y;
+ unsigned int crop_top_y;
+ unsigned int crop_left_uv;
+ unsigned int crop_top_uv;
+ unsigned int start_column_y;
+ unsigned int start_column_uv;
+ unsigned int chunk_width;
+ unsigned int chunk_height;
+ unsigned int block_width;
+ unsigned int block_height;
+ unsigned int input_width;
+ unsigned int input_height;
+ int output_width[IMGU_ABI_OSYS_PINS];
+ int output_height[IMGU_ABI_OSYS_PINS];
+ int output_offset[IMGU_ABI_OSYS_PINS];
+};
+
+/*
+ * frame_params - size IMGU_ABI_OSYS_PINS
+ * stripe_params - size IPU3_UAPI_MAX_STRIPES
+ */
+static int ipu3_css_osys_calc_frame_and_stripe_params(
+ struct ipu3_css *css, unsigned int stripes,
+ struct imgu_abi_osys_config *osys,
+ struct ipu3_css_scaler_info *scaler_luma,
+ struct ipu3_css_scaler_info *scaler_chroma,
+ struct ipu3_css_frame_params frame_params[],
+ struct ipu3_css_stripe_params stripe_params[],
+ unsigned int pipe)
+{
+ struct ipu3_css_reso reso;
+ unsigned int output_width, pin, s;
+ u32 input_width, input_height, target_width, target_height;
+ unsigned int procmode = 0;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ input_width = css_pipe->rect[IPU3_CSS_RECT_GDC].width;
+ input_height = css_pipe->rect[IPU3_CSS_RECT_GDC].height;
+ target_width = css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.width;
+ target_height = css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.height;
+
+ /* Frame parameters */
+
+ /* Input width for Output System is output width of DVS (with GDC) */
+ reso.input_width = css_pipe->rect[IPU3_CSS_RECT_GDC].width;
+
+ /* Input height for Output System is output height of DVS (with GDC) */
+ reso.input_height = css_pipe->rect[IPU3_CSS_RECT_GDC].height;
+
+ reso.input_format =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->frame_format;
+
+ reso.pin_width[IMGU_ABI_OSYS_PIN_OUT] =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.width;
+ reso.pin_height[IMGU_ABI_OSYS_PIN_OUT] =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.height;
+ reso.pin_stride[IMGU_ABI_OSYS_PIN_OUT] =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].width_pad;
+ reso.pin_format[IMGU_ABI_OSYS_PIN_OUT] =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->frame_format;
+
+ reso.pin_width[IMGU_ABI_OSYS_PIN_VF] =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.width;
+ reso.pin_height[IMGU_ABI_OSYS_PIN_VF] =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.height;
+ reso.pin_stride[IMGU_ABI_OSYS_PIN_VF] =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].width_pad;
+ reso.pin_format[IMGU_ABI_OSYS_PIN_VF] =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].css_fmt->frame_format;
+
+ /* Configure the frame parameters for all output pins */
+
+ frame_params[IMGU_ABI_OSYS_PIN_OUT].width =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.width;
+ frame_params[IMGU_ABI_OSYS_PIN_OUT].height =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.height;
+ frame_params[IMGU_ABI_OSYS_PIN_VF].width =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.width;
+ frame_params[IMGU_ABI_OSYS_PIN_VF].height =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.height;
+ frame_params[IMGU_ABI_OSYS_PIN_VF].crop_top = 0;
+ frame_params[IMGU_ABI_OSYS_PIN_VF].crop_left = 0;
+
+ for (pin = 0; pin < IMGU_ABI_OSYS_PINS; pin++) {
+ int enable = 0;
+ int scaled = 0;
+ unsigned int format = 0;
+ unsigned int tiling = 0;
+
+ frame_params[pin].flip = 0;
+ frame_params[pin].mirror = 0;
+ frame_params[pin].reduce_range = 0;
+ if (reso.pin_width[pin] != 0 && reso.pin_height[pin] != 0) {
+ enable = 1;
+ if (pin == IMGU_ABI_OSYS_PIN_OUT) {
+ if (reso.input_width < reso.pin_width[pin] ||
+ reso.input_height < reso.pin_height[pin])
+ return -EINVAL;
+ /*
+ * When input and output resolution is
+ * different instead of scaling, cropping
+ * should happen. Determine the crop factor
+ * to do the symmetric cropping
+ */
+ frame_params[pin].crop_left = roundclosest_down(
+ (reso.input_width -
+ reso.pin_width[pin]) / 2,
+ IMGU_OSYS_DMA_CROP_W_LIMIT);
+ frame_params[pin].crop_top = roundclosest_down(
+ (reso.input_height -
+ reso.pin_height[pin]) / 2,
+ IMGU_OSYS_DMA_CROP_H_LIMIT);
+ } else {
+ if (reso.pin_width[pin] != reso.input_width ||
+ reso.pin_height[pin] != reso.input_height) {
+ /*
+ * If resolution is different at input
+ * and output of OSYS, scaling is
+ * considered except when pin is MAIN.
+ * Later it will be decide whether
+ * scaler factor is 1 or other
+ * and cropping has to be done or not.
+ */
+ scaled = 1;
+ }
+ }
+ ipu3_css_osys_set_format(reso.pin_format[pin], &format,
+ &tiling);
+ } else {
+ enable = 0;
+ }
+ frame_params[pin].enable = enable;
+ frame_params[pin].format = format;
+ frame_params[pin].tiling = tiling;
+ frame_params[pin].stride = reso.pin_stride[pin];
+ frame_params[pin].scaled = scaled;
+ }
+
+ ipu3_css_scaler_calc(input_width, input_height, target_width,
+ target_height, osys, scaler_luma, scaler_chroma,
+ &reso.pin_width[IMGU_ABI_OSYS_PIN_VF],
+ &reso.pin_height[IMGU_ABI_OSYS_PIN_VF], &procmode);
+ dev_dbg(css->dev, "osys scaler procmode is %u", procmode);
+ output_width = reso.pin_width[IMGU_ABI_OSYS_PIN_VF];
+
+ if (output_width < reso.input_width / 2) {
+ /* Scaling factor <= 0.5 */
+ reso.chunk_width = IMGU_OSYS_BLOCK_WIDTH;
+ reso.block_width = IMGU_OSYS_BLOCK_WIDTH;
+ } else { /* 0.5 <= Scaling factor <= 1.0 */
+ reso.chunk_width = IMGU_OSYS_BLOCK_WIDTH / 2;
+ reso.block_width = IMGU_OSYS_BLOCK_WIDTH;
+ }
+
+ if (output_width <= reso.input_width * 7 / 8) {
+ /* Scaling factor <= 0.875 */
+ reso.chunk_height = IMGU_OSYS_BLOCK_HEIGHT;
+ reso.block_height = IMGU_OSYS_BLOCK_HEIGHT;
+ } else { /* 1.0 <= Scaling factor <= 1.75 */
+ reso.chunk_height = IMGU_OSYS_BLOCK_HEIGHT / 2;
+ reso.block_height = IMGU_OSYS_BLOCK_HEIGHT;
+ }
+
+ /*
+ * Calculate scaler configuration parameters based on input and output
+ * resolution.
+ */
+
+ if (frame_params[IMGU_ABI_OSYS_PIN_VF].enable) {
+ /*
+ * When aspect ratio is different between target resolution and
+ * required resolution, determine the crop factor to do
+ * symmetric cropping
+ */
+ u32 w = reso.pin_width[IMGU_ABI_OSYS_PIN_VF] -
+ frame_params[IMGU_ABI_OSYS_PIN_VF].width;
+ u32 h = reso.pin_height[IMGU_ABI_OSYS_PIN_VF] -
+ frame_params[IMGU_ABI_OSYS_PIN_VF].height;
+
+ frame_params[IMGU_ABI_OSYS_PIN_VF].crop_left =
+ roundclosest_down(w / 2, IMGU_OSYS_DMA_CROP_W_LIMIT);
+ frame_params[IMGU_ABI_OSYS_PIN_VF].crop_top =
+ roundclosest_down(h / 2, IMGU_OSYS_DMA_CROP_H_LIMIT);
+
+ if (reso.input_height % 4 || reso.input_width % 8) {
+ dev_err(css->dev, "OSYS input width is not multiple of 8 or\n");
+ dev_err(css->dev, "height is not multiple of 4\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Stripe parameters */
+
+ if (frame_params[IMGU_ABI_OSYS_PIN_VF].enable) {
+ output_width = reso.pin_width[IMGU_ABI_OSYS_PIN_VF];
+ } else {
+ /*
+ * in case scaler output is not enabled
+ * take output width as input width since
+ * there is no scaling at main pin.
+ * Due to the fact that main pin can be different
+ * from input resolution to osys in the case of cropping,
+ * main pin resolution is not taken.
+ */
+ output_width = reso.input_width;
+ }
+
+ for (s = 0; s < stripes; s++) {
+ int stripe_offset_inp_y = 0;
+ int stripe_offset_inp_uv = 0;
+ int stripe_offset_out_y = 0;
+ int stripe_offset_out_uv = 0;
+ int stripe_phase_init_y = scaler_luma->phase_init;
+ int stripe_phase_init_uv = scaler_chroma->phase_init;
+ int stripe_offset_blk_y = 0;
+ int stripe_offset_blk_uv = 0;
+ int stripe_offset_col_y = 0;
+ int stripe_offset_col_uv = 0;
+ int stripe_pad_left_y = scaler_luma->pad_left;
+ int stripe_pad_left_uv = scaler_chroma->pad_left;
+ int stripe_pad_right_y = scaler_luma->pad_right;
+ int stripe_pad_right_uv = scaler_chroma->pad_right;
+ int stripe_crop_left_y = scaler_luma->crop_left;
+ int stripe_crop_left_uv = scaler_chroma->crop_left;
+ int stripe_input_width_y = reso.input_width;
+ int stripe_input_width_uv = 0;
+ int stripe_output_width_y = output_width;
+ int stripe_output_width_uv = 0;
+ int chunk_floor_y = 0;
+ int chunk_floor_uv = 0;
+ int chunk_ceil_uv = 0;
+
+ if (stripes > 1) {
+ if (s > 0) {
+ /* Calculate stripe offsets */
+ stripe_offset_out_y =
+ output_width * s / stripes;
+ stripe_offset_out_y =
+ rounddown(stripe_offset_out_y,
+ IPU3_UAPI_ISP_VEC_ELEMS);
+ stripe_offset_out_uv = stripe_offset_out_y /
+ IMGU_LUMA_TO_CHROMA_RATIO;
+ stripe_offset_inp_y =
+ ipu3_css_osys_calc_stripe_offset(
+ stripe_offset_out_y,
+ IMGU_OSYS_FIR_PHASES,
+ scaler_luma->phase_init,
+ scaler_luma->phase_step,
+ scaler_luma->pad_left);
+ stripe_offset_inp_uv =
+ ipu3_css_osys_calc_stripe_offset(
+ stripe_offset_out_uv,
+ IMGU_OSYS_FIR_PHASES,
+ scaler_chroma->phase_init,
+ scaler_chroma->phase_step,
+ scaler_chroma->pad_left);
+
+ /* Calculate stripe phase init */
+ stripe_phase_init_y =
+ ipu3_css_osys_calc_stripe_phase_init(
+ stripe_offset_out_y,
+ IMGU_OSYS_FIR_PHASES,
+ scaler_luma->phase_init,
+ scaler_luma->phase_step,
+ scaler_luma->pad_left);
+ stripe_phase_init_uv =
+ ipu3_css_osys_calc_stripe_phase_init(
+ stripe_offset_out_uv,
+ IMGU_OSYS_FIR_PHASES,
+ scaler_chroma->phase_init,
+ scaler_chroma->phase_step,
+ scaler_chroma->pad_left);
+
+ /*
+ * Chunk boundary corner case - luma and chroma
+ * start from different input chunks.
+ */
+ chunk_floor_y = rounddown(stripe_offset_inp_y,
+ reso.chunk_width);
+ chunk_floor_uv =
+ rounddown(stripe_offset_inp_uv,
+ reso.chunk_width /
+ IMGU_LUMA_TO_CHROMA_RATIO);
+
+ if (chunk_floor_y != chunk_floor_uv *
+ IMGU_LUMA_TO_CHROMA_RATIO) {
+ /*
+ * Match starting luma/chroma chunks.
+ * Decrease offset for UV and add output
+ * cropping.
+ */
+ stripe_offset_inp_uv -= 1;
+ stripe_crop_left_uv += 1;
+ stripe_phase_init_uv -=
+ scaler_luma->phase_step;
+ if (stripe_phase_init_uv < 0)
+ stripe_phase_init_uv =
+ stripe_phase_init_uv +
+ IMGU_OSYS_FIR_PHASES;
+ }
+ /*
+ * FW workaround for a HW bug: if the first
+ * chroma pixel is generated exactly at the end
+ * of chunck scaler HW may not output the pixel
+ * for downscale factors smaller than 1.5
+ * (timing issue).
+ */
+ chunk_ceil_uv =
+ roundup(stripe_offset_inp_uv,
+ reso.chunk_width /
+ IMGU_LUMA_TO_CHROMA_RATIO);
+
+ if (stripe_offset_inp_uv ==
+ chunk_ceil_uv - IMGU_OSYS_TAPS_UV) {
+ /*
+ * Decrease input offset and add
+ * output cropping
+ */
+ stripe_offset_inp_uv -= 1;
+ stripe_phase_init_uv -=
+ scaler_luma->phase_step;
+ if (stripe_phase_init_uv < 0) {
+ stripe_phase_init_uv +=
+ IMGU_OSYS_FIR_PHASES;
+ stripe_crop_left_uv += 1;
+ }
+ }
+
+ /*
+ * Calculate block and column offsets for the
+ * input stripe
+ */
+ stripe_offset_blk_y =
+ rounddown(stripe_offset_inp_y,
+ IMGU_INPUT_BLOCK_WIDTH);
+ stripe_offset_blk_uv =
+ rounddown(stripe_offset_inp_uv,
+ IMGU_INPUT_BLOCK_WIDTH /
+ IMGU_LUMA_TO_CHROMA_RATIO);
+ stripe_offset_col_y = stripe_offset_inp_y -
+ stripe_offset_blk_y;
+ stripe_offset_col_uv = stripe_offset_inp_uv -
+ stripe_offset_blk_uv;
+
+ /* Left padding is only for the first stripe */
+ stripe_pad_left_y = 0;
+ stripe_pad_left_uv = 0;
+ }
+
+ /* Right padding is only for the last stripe */
+ if (s < stripes - 1) {
+ int next_offset;
+
+ stripe_pad_right_y = 0;
+ stripe_pad_right_uv = 0;
+
+ next_offset = output_width * (s + 1) / stripes;
+ next_offset = rounddown(next_offset, 64);
+ stripe_output_width_y = next_offset -
+ stripe_offset_out_y;
+ } else {
+ stripe_output_width_y = output_width -
+ stripe_offset_out_y;
+ }
+
+ /* Calculate target output stripe width */
+ stripe_output_width_uv = stripe_output_width_y /
+ IMGU_LUMA_TO_CHROMA_RATIO;
+ /* Calculate input stripe width */
+ stripe_input_width_y = stripe_offset_col_y +
+ ipu3_css_osys_calc_inp_stripe_width(
+ stripe_output_width_y,
+ IMGU_OSYS_FIR_PHASES,
+ stripe_phase_init_y,
+ scaler_luma->phase_step,
+ IMGU_OSYS_TAPS_Y,
+ stripe_pad_left_y,
+ stripe_pad_right_y);
+
+ stripe_input_width_uv = stripe_offset_col_uv +
+ ipu3_css_osys_calc_inp_stripe_width(
+ stripe_output_width_uv,
+ IMGU_OSYS_FIR_PHASES,
+ stripe_phase_init_uv,
+ scaler_chroma->phase_step,
+ IMGU_OSYS_TAPS_UV,
+ stripe_pad_left_uv,
+ stripe_pad_right_uv);
+
+ stripe_input_width_uv = max(DIV_ROUND_UP(
+ stripe_input_width_y,
+ IMGU_LUMA_TO_CHROMA_RATIO),
+ stripe_input_width_uv);
+
+ stripe_input_width_y = stripe_input_width_uv *
+ IMGU_LUMA_TO_CHROMA_RATIO;
+
+ if (s >= stripes - 1) {
+ stripe_input_width_y = reso.input_width -
+ stripe_offset_blk_y;
+ /*
+ * The scaler requires that the last stripe
+ * spans at least two input blocks.
+ */
+ }
+
+ /*
+ * Spec: input stripe width must be a multiple of 8.
+ * Increase the input width and recalculate the output
+ * width. This may produce an extra column of junk
+ * blocks which will be overwritten by the
+ * next stripe.
+ */
+ stripe_input_width_y = ALIGN(stripe_input_width_y, 8);
+ stripe_output_width_y =
+ ipu3_css_osys_out_stripe_width(
+ stripe_input_width_y,
+ IMGU_OSYS_FIR_PHASES,
+ stripe_phase_init_y,
+ scaler_luma->phase_step,
+ IMGU_OSYS_TAPS_Y,
+ stripe_pad_left_y,
+ stripe_pad_right_y,
+ stripe_offset_col_y);
+
+ stripe_output_width_y =
+ rounddown(stripe_output_width_y,
+ IMGU_LUMA_TO_CHROMA_RATIO);
+ }
+ /*
+ * Following section executes and process parameters
+ * for both cases - Striping or No Striping.
+ */
+ {
+ unsigned int i;
+ int pin_scale = 0;
+ /*Input resolution */
+
+ stripe_params[s].input_width = stripe_input_width_y;
+ stripe_params[s].input_height = reso.input_height;
+
+ for (i = 0; i < IMGU_ABI_OSYS_PINS; i++) {
+ if (frame_params[i].scaled) {
+ /*
+ * Output stripe resolution and offset
+ * as produced by the scaler; actual
+ * output resolution may be slightly
+ * smaller.
+ */
+ stripe_params[s].output_width[i] =
+ stripe_output_width_y;
+ stripe_params[s].output_height[i] =
+ reso.pin_height[i];
+ stripe_params[s].output_offset[i] =
+ stripe_offset_out_y;
+
+ pin_scale += frame_params[i].scaled;
+ } else {
+ /* Unscaled pin */
+ stripe_params[s].output_width[i] =
+ stripe_params[s].input_width;
+ stripe_params[s].output_height[i] =
+ stripe_params[s].input_height;
+ stripe_params[s].output_offset[i] =
+ stripe_offset_blk_y;
+ }
+ }
+
+ /* If no pin use scale, we use BYPASS mode */
+ stripe_params[s].processing_mode = procmode;
+ stripe_params[s].phase_step = scaler_luma->phase_step;
+ stripe_params[s].exp_shift = scaler_luma->exp_shift;
+ stripe_params[s].phase_init_left_y =
+ stripe_phase_init_y;
+ stripe_params[s].phase_init_left_uv =
+ stripe_phase_init_uv;
+ stripe_params[s].phase_init_top_y =
+ scaler_luma->phase_init;
+ stripe_params[s].phase_init_top_uv =
+ scaler_chroma->phase_init;
+ stripe_params[s].pad_left_y = stripe_pad_left_y;
+ stripe_params[s].pad_left_uv = stripe_pad_left_uv;
+ stripe_params[s].pad_right_y = stripe_pad_right_y;
+ stripe_params[s].pad_right_uv = stripe_pad_right_uv;
+ stripe_params[s].pad_top_y = scaler_luma->pad_left;
+ stripe_params[s].pad_top_uv = scaler_chroma->pad_left;
+ stripe_params[s].pad_bottom_y = scaler_luma->pad_right;
+ stripe_params[s].pad_bottom_uv =
+ scaler_chroma->pad_right;
+ stripe_params[s].crop_left_y = stripe_crop_left_y;
+ stripe_params[s].crop_top_y = scaler_luma->crop_top;
+ stripe_params[s].crop_left_uv = stripe_crop_left_uv;
+ stripe_params[s].crop_top_uv = scaler_chroma->crop_top;
+ stripe_params[s].start_column_y = stripe_offset_col_y;
+ stripe_params[s].start_column_uv = stripe_offset_col_uv;
+ stripe_params[s].chunk_width = reso.chunk_width;
+ stripe_params[s].chunk_height = reso.chunk_height;
+ stripe_params[s].block_width = reso.block_width;
+ stripe_params[s].block_height = reso.block_height;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function configures the Output Formatter System, given the number of
+ * stripes, scaler luma and chrome parameters
+ */
+static int ipu3_css_osys_calc(struct ipu3_css *css, unsigned int pipe,
+ unsigned int stripes,
+ struct imgu_abi_osys_config *osys,
+ struct ipu3_css_scaler_info *scaler_luma,
+ struct ipu3_css_scaler_info *scaler_chroma,
+ struct imgu_abi_stripes block_stripes[])
+{
+ struct ipu3_css_frame_params frame_params[IMGU_ABI_OSYS_PINS];
+ struct ipu3_css_stripe_params stripe_params[IPU3_UAPI_MAX_STRIPES];
+ struct imgu_abi_osys_formatter_params *param;
+ unsigned int pin, s;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ memset(osys, 0, sizeof(*osys));
+
+ /* Compute the frame and stripe params */
+ if (ipu3_css_osys_calc_frame_and_stripe_params(css, stripes, osys,
+ scaler_luma,
+ scaler_chroma,
+ frame_params,
+ stripe_params, pipe))
+ return -EINVAL;
+
+ /* Output formatter system parameters */
+
+ for (s = 0; s < stripes; s++) {
+ struct imgu_abi_osys_scaler_params *scaler =
+ &osys->scaler[s].param;
+ int fifo_addr_fmt = IMGU_FIFO_ADDR_SCALER_TO_FMT;
+ int fifo_addr_ack = IMGU_FIFO_ADDR_SCALER_TO_SP;
+
+ /* OUTPUT 0 / PIN 0 is only Scaler output */
+ scaler->inp_buf_y_st_addr = IMGU_VMEM1_INP_BUF_ADDR;
+
+ /*
+ * = (IMGU_OSYS_BLOCK_WIDTH / IMGU_VMEM1_ELEMS_PER_VEC)
+ * = (2 * IPU3_UAPI_ISP_VEC_ELEMS) /
+ * (IMGU_HIVE_OF_SYS_OF_SYSTEM_NWAYS)
+ * = 2 * 64 / 32 = 4
+ */
+ scaler->inp_buf_y_line_stride = IMGU_VMEM1_Y_STRIDE;
+ /*
+ * = (IMGU_VMEM1_V_OFFSET + VMEM1_uv_size)
+ * = (IMGU_VMEM1_U_OFFSET + VMEM1_uv_size) +
+ * (VMEM1_y_size / 4)
+ * = (VMEM1_y_size) + (VMEM1_y_size / 4) +
+ * (IMGU_OSYS_BLOCK_HEIGHT * IMGU_VMEM1_Y_STRIDE)/4
+ * = (IMGU_OSYS_BLOCK_HEIGHT * IMGU_VMEM1_Y_STRIDE)
+ */
+ scaler->inp_buf_y_buffer_stride = IMGU_VMEM1_BUF_SIZE;
+ scaler->inp_buf_u_st_addr = IMGU_VMEM1_INP_BUF_ADDR +
+ IMGU_VMEM1_U_OFFSET;
+ scaler->inp_buf_v_st_addr = IMGU_VMEM1_INP_BUF_ADDR +
+ IMGU_VMEM1_V_OFFSET;
+ scaler->inp_buf_uv_line_stride = IMGU_VMEM1_UV_STRIDE;
+ scaler->inp_buf_uv_buffer_stride = IMGU_VMEM1_BUF_SIZE;
+ scaler->inp_buf_chunk_width = stripe_params[s].chunk_width;
+ scaler->inp_buf_nr_buffers = IMGU_OSYS_NUM_INPUT_BUFFERS;
+
+ /* Output buffers */
+ scaler->out_buf_y_st_addr = IMGU_VMEM1_INT_BUF_ADDR;
+ scaler->out_buf_y_line_stride = stripe_params[s].block_width /
+ IMGU_VMEM1_ELEMS_PER_VEC;
+ scaler->out_buf_y_buffer_stride = IMGU_VMEM1_BUF_SIZE;
+ scaler->out_buf_u_st_addr = IMGU_VMEM1_INT_BUF_ADDR +
+ IMGU_VMEM1_U_OFFSET;
+ scaler->out_buf_v_st_addr = IMGU_VMEM1_INT_BUF_ADDR +
+ IMGU_VMEM1_V_OFFSET;
+ scaler->out_buf_uv_line_stride = stripe_params[s].block_width /
+ IMGU_VMEM1_ELEMS_PER_VEC / 2;
+ scaler->out_buf_uv_buffer_stride = IMGU_VMEM1_BUF_SIZE;
+ scaler->out_buf_nr_buffers = IMGU_OSYS_NUM_INTERM_BUFFERS;
+
+ /* Intermediate buffers */
+ scaler->int_buf_y_st_addr = IMGU_VMEM2_BUF_Y_ADDR;
+ scaler->int_buf_y_line_stride = IMGU_VMEM2_BUF_Y_STRIDE;
+ scaler->int_buf_u_st_addr = IMGU_VMEM2_BUF_U_ADDR;
+ scaler->int_buf_v_st_addr = IMGU_VMEM2_BUF_V_ADDR;
+ scaler->int_buf_uv_line_stride = IMGU_VMEM2_BUF_UV_STRIDE;
+ scaler->int_buf_height = IMGU_VMEM2_LINES_PER_BLOCK;
+ scaler->int_buf_chunk_width = stripe_params[s].chunk_height;
+ scaler->int_buf_chunk_height = stripe_params[s].block_width;
+
+ /* Context buffers */
+ scaler->ctx_buf_hor_y_st_addr = IMGU_VMEM3_HOR_Y_ADDR;
+ scaler->ctx_buf_hor_u_st_addr = IMGU_VMEM3_HOR_U_ADDR;
+ scaler->ctx_buf_hor_v_st_addr = IMGU_VMEM3_HOR_V_ADDR;
+ scaler->ctx_buf_ver_y_st_addr = IMGU_VMEM3_VER_Y_ADDR;
+ scaler->ctx_buf_ver_u_st_addr = IMGU_VMEM3_VER_U_ADDR;
+ scaler->ctx_buf_ver_v_st_addr = IMGU_VMEM3_VER_V_ADDR;
+
+ /* Addresses for release-input and process-output tokens */
+ scaler->release_inp_buf_addr = fifo_addr_ack;
+ scaler->release_inp_buf_en = 1;
+ scaler->release_out_buf_en = 1;
+ scaler->process_out_buf_addr = fifo_addr_fmt;
+
+ /* Settings dimensions, padding, cropping */
+ scaler->input_image_y_width = stripe_params[s].input_width;
+ scaler->input_image_y_height = stripe_params[s].input_height;
+ scaler->input_image_y_start_column =
+ stripe_params[s].start_column_y;
+ scaler->input_image_uv_start_column =
+ stripe_params[s].start_column_uv;
+ scaler->input_image_y_left_pad = stripe_params[s].pad_left_y;
+ scaler->input_image_uv_left_pad = stripe_params[s].pad_left_uv;
+ scaler->input_image_y_right_pad = stripe_params[s].pad_right_y;
+ scaler->input_image_uv_right_pad =
+ stripe_params[s].pad_right_uv;
+ scaler->input_image_y_top_pad = stripe_params[s].pad_top_y;
+ scaler->input_image_uv_top_pad = stripe_params[s].pad_top_uv;
+ scaler->input_image_y_bottom_pad =
+ stripe_params[s].pad_bottom_y;
+ scaler->input_image_uv_bottom_pad =
+ stripe_params[s].pad_bottom_uv;
+ scaler->processing_mode = stripe_params[s].processing_mode;
+ scaler->scaling_ratio = stripe_params[s].phase_step;
+ scaler->y_left_phase_init = stripe_params[s].phase_init_left_y;
+ scaler->uv_left_phase_init =
+ stripe_params[s].phase_init_left_uv;
+ scaler->y_top_phase_init = stripe_params[s].phase_init_top_y;
+ scaler->uv_top_phase_init = stripe_params[s].phase_init_top_uv;
+ scaler->coeffs_exp_shift = stripe_params[s].exp_shift;
+ scaler->out_y_left_crop = stripe_params[s].crop_left_y;
+ scaler->out_uv_left_crop = stripe_params[s].crop_left_uv;
+ scaler->out_y_top_crop = stripe_params[s].crop_top_y;
+ scaler->out_uv_top_crop = stripe_params[s].crop_top_uv;
+
+ for (pin = 0; pin < IMGU_ABI_OSYS_PINS; pin++) {
+ int in_fifo_addr;
+ int out_fifo_addr;
+ int block_width_vecs;
+ int input_width_s;
+ int input_width_vecs;
+ int input_buf_y_st_addr;
+ int input_buf_u_st_addr;
+ int input_buf_v_st_addr;
+ int input_buf_y_line_stride;
+ int input_buf_uv_line_stride;
+ int output_buf_y_line_stride;
+ int output_buf_uv_line_stride;
+ int output_buf_nr_y_lines;
+ int block_height;
+ int block_width;
+ struct imgu_abi_osys_frame_params *fr_pr;
+
+ fr_pr = &osys->frame[pin].param;
+
+ /* Frame parameters */
+ fr_pr->enable = frame_params[pin].enable;
+ fr_pr->format = frame_params[pin].format;
+ fr_pr->mirror = frame_params[pin].mirror;
+ fr_pr->flip = frame_params[pin].flip;
+ fr_pr->tiling = frame_params[pin].tiling;
+ fr_pr->width = frame_params[pin].width;
+ fr_pr->height = frame_params[pin].height;
+ fr_pr->stride = frame_params[pin].stride;
+ fr_pr->scaled = frame_params[pin].scaled;
+
+ /* Stripe parameters */
+ osys->stripe[s].crop_top[pin] =
+ frame_params[pin].crop_top;
+ osys->stripe[s].input_width =
+ stripe_params[s].input_width;
+ osys->stripe[s].input_height =
+ stripe_params[s].input_height;
+ osys->stripe[s].block_height =
+ stripe_params[s].block_height;
+ osys->stripe[s].block_width =
+ stripe_params[s].block_width;
+ osys->stripe[s].output_width[pin] =
+ stripe_params[s].output_width[pin];
+ osys->stripe[s].output_height[pin] =
+ stripe_params[s].output_height[pin];
+
+ if (s == 0) {
+ /* Only first stripe should do left cropping */
+ osys->stripe[s].crop_left[pin] =
+ frame_params[pin].crop_left;
+ osys->stripe[s].output_offset[pin] =
+ stripe_params[s].output_offset[pin];
+ } else {
+ /*
+ * Stripe offset for other strips should be
+ * adjusted according to the cropping done
+ * at the first strip
+ */
+ osys->stripe[s].crop_left[pin] = 0;
+ osys->stripe[s].output_offset[pin] =
+ (stripe_params[s].output_offset[pin] -
+ osys->stripe[0].crop_left[pin]);
+ }
+
+ if (!frame_params[pin].enable)
+ continue;
+
+ /* Formatter: configurations */
+
+ /*
+ * Get the dimensions of the input blocks of the
+ * formatter, which is the same as the output
+ * blocks of the scaler.
+ */
+ if (frame_params[pin].scaled) {
+ block_height = stripe_params[s].block_height;
+ block_width = stripe_params[s].block_width;
+ } else {
+ block_height = IMGU_OSYS_BLOCK_HEIGHT;
+ block_width = IMGU_OSYS_BLOCK_WIDTH;
+ }
+ block_width_vecs =
+ block_width / IMGU_VMEM1_ELEMS_PER_VEC;
+ /*
+ * The input/output line stride depends on the
+ * block size.
+ */
+ input_buf_y_line_stride = block_width_vecs;
+ input_buf_uv_line_stride = block_width_vecs / 2;
+ output_buf_y_line_stride = block_width_vecs;
+ output_buf_uv_line_stride = block_width_vecs / 2;
+ output_buf_nr_y_lines = block_height;
+ if (frame_params[pin].format ==
+ IMGU_ABI_OSYS_FORMAT_NV12 ||
+ frame_params[pin].format ==
+ IMGU_ABI_OSYS_FORMAT_NV21)
+ output_buf_uv_line_stride =
+ output_buf_y_line_stride;
+
+ /*
+ * Tiled outputs use a different output buffer
+ * configuration. The input (= scaler output) block
+ * width translates to a tile height, and the block
+ * height to the tile width. The default block size of
+ * 128x32 maps exactly onto a 4kB tile (512x8) for Y.
+ * For UV, the tile width is always half.
+ */
+ if (frame_params[pin].tiling) {
+ output_buf_nr_y_lines = 8;
+ output_buf_y_line_stride = 512 /
+ IMGU_VMEM1_ELEMS_PER_VEC;
+ output_buf_uv_line_stride = 256 /
+ IMGU_VMEM1_ELEMS_PER_VEC;
+ }
+
+ /*
+ * Store the output buffer line stride. Will be
+ * used to compute buffer offsets in boundary
+ * conditions when output blocks are partially
+ * outside the image.
+ */
+ osys->stripe[s].buf_stride[pin] =
+ output_buf_y_line_stride *
+ IMGU_HIVE_OF_SYS_OF_SYSTEM_NWAYS;
+ if (frame_params[pin].scaled) {
+ /*
+ * The input buffs are the intermediate
+ * buffers (scalers' output)
+ */
+ input_buf_y_st_addr = IMGU_VMEM1_INT_BUF_ADDR;
+ input_buf_u_st_addr = IMGU_VMEM1_INT_BUF_ADDR +
+ IMGU_VMEM1_U_OFFSET;
+ input_buf_v_st_addr = IMGU_VMEM1_INT_BUF_ADDR +
+ IMGU_VMEM1_V_OFFSET;
+ } else {
+ /*
+ * The input bufferss are the buffers
+ * filled by the SP
+ */
+ input_buf_y_st_addr = IMGU_VMEM1_INP_BUF_ADDR;
+ input_buf_u_st_addr = IMGU_VMEM1_INP_BUF_ADDR +
+ IMGU_VMEM1_U_OFFSET;
+ input_buf_v_st_addr = IMGU_VMEM1_INP_BUF_ADDR +
+ IMGU_VMEM1_V_OFFSET;
+ }
+
+ /*
+ * The formatter input width must be rounded to
+ * the block width. Otherwise the formatter will
+ * not recognize the end of the line, resulting
+ * in incorrect tiling (system may hang!) and
+ * possibly other problems.
+ */
+ input_width_s =
+ roundup(stripe_params[s].output_width[pin],
+ block_width);
+ input_width_vecs = input_width_s /
+ IMGU_VMEM1_ELEMS_PER_VEC;
+ out_fifo_addr = IMGU_FIFO_ADDR_FMT_TO_SP;
+ /*
+ * Process-output tokens must be sent to the SP.
+ * When scaling, the release-input tokens can be
+ * sent directly to the scaler, otherwise the
+ * formatter should send them to the SP.
+ */
+ if (frame_params[pin].scaled)
+ in_fifo_addr = IMGU_FIFO_ADDR_FMT_TO_SCALER;
+ else
+ in_fifo_addr = IMGU_FIFO_ADDR_FMT_TO_SP;
+
+ /* Formatter */
+ param = &osys->formatter[s][pin].param;
+
+ param->format = frame_params[pin].format;
+ param->flip = frame_params[pin].flip;
+ param->mirror = frame_params[pin].mirror;
+ param->tiling = frame_params[pin].tiling;
+ param->reduce_range = frame_params[pin].reduce_range;
+ param->alpha_blending = 0;
+ param->release_inp_addr = in_fifo_addr;
+ param->release_inp_en = 1;
+ param->process_out_buf_addr = out_fifo_addr;
+ param->image_width_vecs = input_width_vecs;
+ param->image_height_lines =
+ stripe_params[s].output_height[pin];
+ param->inp_buff_y_st_addr = input_buf_y_st_addr;
+ param->inp_buff_y_line_stride = input_buf_y_line_stride;
+ param->inp_buff_y_buffer_stride = IMGU_VMEM1_BUF_SIZE;
+ param->int_buff_u_st_addr = input_buf_u_st_addr;
+ param->int_buff_v_st_addr = input_buf_v_st_addr;
+ param->inp_buff_uv_line_stride =
+ input_buf_uv_line_stride;
+ param->inp_buff_uv_buffer_stride = IMGU_VMEM1_BUF_SIZE;
+ param->out_buff_level = 0;
+ param->out_buff_nr_y_lines = output_buf_nr_y_lines;
+ param->out_buff_u_st_offset = IMGU_VMEM1_U_OFFSET;
+ param->out_buff_v_st_offset = IMGU_VMEM1_V_OFFSET;
+ param->out_buff_y_line_stride =
+ output_buf_y_line_stride;
+ param->out_buff_uv_line_stride =
+ output_buf_uv_line_stride;
+ param->hist_buff_st_addr = IMGU_VMEM1_HST_BUF_ADDR;
+ param->hist_buff_line_stride =
+ IMGU_VMEM1_HST_BUF_STRIDE;
+ param->hist_buff_nr_lines = IMGU_VMEM1_HST_BUF_NLINES;
+ }
+ }
+
+ block_stripes[0].offset = 0;
+ if (stripes <= 1) {
+ block_stripes[0].width = stripe_params[0].input_width;
+ block_stripes[0].height = stripe_params[0].input_height;
+ } else {
+ struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css_pipe->bindex];
+ unsigned int sp_block_width =
+ bi->info.isp.sp.block.block_width *
+ IPU3_UAPI_ISP_VEC_ELEMS;
+
+ block_stripes[0].width = roundup(stripe_params[0].input_width,
+ sp_block_width);
+ block_stripes[1].offset =
+ rounddown(css_pipe->rect[IPU3_CSS_RECT_GDC].width -
+ stripe_params[1].input_width, sp_block_width);
+ block_stripes[1].width =
+ roundup(css_pipe->rect[IPU3_CSS_RECT_GDC].width -
+ block_stripes[1].offset, sp_block_width);
+ block_stripes[0].height = css_pipe->rect[IPU3_CSS_RECT_GDC].height;
+ block_stripes[1].height = block_stripes[0].height;
+ }
+
+ return 0;
+}
+
+/*********************** Mostly 3A operations ******************************/
+
+/*
+ * This function creates a "TO-DO list" (operations) for the sp code.
+ *
+ * There are 2 types of operations:
+ * 1. Transfer: Issue DMA transfer request for copying grid cells from DDR to
+ * accelerator space (NOTE that this space is limited) associated data:
+ * DDR address + accelerator's config set index(acc's address).
+ *
+ * 2. Issue "Process Lines Command" to shd accelerator
+ * associated data: #lines + which config set to use (actually, accelerator
+ * will use x AND (x+1)%num_of_sets - NOTE that this implies the restriction
+ * of not touching config sets x & (x+1)%num_of_sets when process_lines(x)
+ * is active).
+ *
+ * Basically there are 2 types of operations "chunks":
+ * 1. "initial chunk": Initially, we do as much transfers as we can (and need)
+ * [0 - max sets(3) ] followed by 1 or 2 "process lines" operations.
+ *
+ * 2. "regular chunk" - 1 transfer followed by 1 process line operation.
+ * (in some cases we might need additional transfer ate the last chunk).
+ *
+ * for some case:
+ * --> init
+ * tr (0)
+ * tr (1)
+ * tr (2)
+ * pl (0)
+ * pl (1)
+ * --> ack (0)
+ * tr (3)
+ * pl (2)
+ * --> ack (1)
+ * pl (3)
+ * --> ack (2)
+ * do nothing
+ * --> ack (3)
+ * do nothing
+ */
+
+static int
+ipu3_css_shd_ops_calc(struct imgu_abi_shd_intra_frame_operations_data *ops,
+ const struct ipu3_uapi_shd_grid_config *grid,
+ unsigned int image_height)
+{
+ unsigned int block_height = 1 << grid->block_height_log2;
+ unsigned int grid_height_per_slice = grid->grid_height_per_slice;
+ unsigned int set_height = grid_height_per_slice * block_height;
+
+ /* We currently support only abs(y_start) > grid_height_per_slice */
+ unsigned int positive_y_start = (unsigned int)-grid->y_start;
+ unsigned int first_process_lines =
+ set_height - (positive_y_start % set_height);
+ unsigned int last_set_height;
+ unsigned int num_of_sets;
+
+ struct imgu_abi_acc_operation *p_op;
+ struct imgu_abi_acc_process_lines_cmd_data *p_pl;
+ struct imgu_abi_shd_transfer_luts_set_data *p_tr;
+
+ unsigned int op_idx, pl_idx, tr_idx;
+ unsigned char tr_set_num, pl_cfg_set;
+
+ /*
+ * When the number of lines for the last process lines command
+ * is equal to a set height, we need another line of grid cell -
+ * additional transfer is required.
+ */
+ unsigned char last_tr = 0;
+
+ /* Add "process lines" command to the list of operations */
+ bool add_pl;
+ /* Add DMA xfer (config set) command to the list of ops */
+ bool add_tr;
+
+ /*
+ * Available partial grid (the part that fits into #IMGU_SHD_SETS sets)
+ * doesn't cover whole frame - need to process in chunks
+ */
+ if (image_height > first_process_lines) {
+ last_set_height =
+ (image_height - first_process_lines) % set_height;
+ num_of_sets = last_set_height > 0 ?
+ (image_height - first_process_lines) / set_height + 2 :
+ (image_height - first_process_lines) / set_height + 1;
+ last_tr = (set_height - last_set_height <= block_height ||
+ last_set_height == 0) ? 1 : 0;
+ } else { /* partial grid covers whole frame */
+ last_set_height = 0;
+ num_of_sets = 1;
+ first_process_lines = image_height;
+ last_tr = set_height - image_height <= block_height ? 1 : 0;
+ }
+
+ /* Init operations lists and counters */
+ p_op = ops->operation_list;
+ op_idx = 0;
+ p_pl = ops->process_lines_data;
+ pl_idx = 0;
+ p_tr = ops->transfer_data;
+ tr_idx = 0;
+
+ memset(ops, 0, sizeof(*ops));
+
+ /* Cyclic counters that holds config set number [0,IMGU_SHD_SETS) */
+ tr_set_num = 0;
+ pl_cfg_set = 0;
+
+ /*
+ * Always start with a transfer - process lines command must be
+ * initiated only after appropriate config sets are in place
+ * (2 configuration sets per process line command, except for last one).
+ */
+ add_pl = false;
+ add_tr = true;
+
+ while (add_pl || add_tr) {
+ /* Transfer ops */
+ if (add_tr) {
+ if (op_idx >= IMGU_ABI_SHD_MAX_OPERATIONS ||
+ tr_idx >= IMGU_ABI_SHD_MAX_TRANSFERS)
+ return -EINVAL;
+ p_op[op_idx].op_type =
+ IMGU_ABI_ACC_OPTYPE_TRANSFER_DATA;
+ p_op[op_idx].op_indicator = IMGU_ABI_ACC_OP_IDLE;
+ op_idx++;
+ p_tr[tr_idx].set_number = tr_set_num;
+ tr_idx++;
+ tr_set_num = (tr_set_num + 1) % IMGU_SHD_SETS;
+ }
+
+ /* Process-lines ops */
+ if (add_pl) {
+ if (op_idx >= IMGU_ABI_SHD_MAX_OPERATIONS ||
+ pl_idx >= IMGU_ABI_SHD_MAX_PROCESS_LINES)
+ return -EINVAL;
+ p_op[op_idx].op_type =
+ IMGU_ABI_ACC_OPTYPE_PROCESS_LINES;
+
+ /*
+ * In case we have 2 process lines commands -
+ * don't stop after the first one
+ */
+ if (pl_idx == 0 && num_of_sets != 1)
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_IDLE;
+ /*
+ * Initiate last process lines command -
+ * end of operation list.
+ */
+ else if (pl_idx == num_of_sets - 1)
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_END_OF_OPS;
+ /*
+ * Intermediate process line command - end of operation
+ * "chunk" (meaning few "transfers" followed by few
+ * "process lines" commands).
+ */
+ else
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_END_OF_ACK;
+
+ op_idx++;
+
+ /* first process line operation */
+ if (pl_idx == 0)
+ p_pl[pl_idx].lines = first_process_lines;
+ /* Last process line operation */
+ else if (pl_idx == num_of_sets - 1 &&
+ last_set_height > 0)
+ p_pl[pl_idx].lines = last_set_height;
+ else /* "regular" process lines operation */
+ p_pl[pl_idx].lines = set_height;
+
+ p_pl[pl_idx].cfg_set = pl_cfg_set;
+ pl_idx++;
+ pl_cfg_set = (pl_cfg_set + 1) % IMGU_SHD_SETS;
+ }
+
+ /*
+ * Initially, we always transfer
+ * min(IMGU_SHD_SETS, num_of_sets) - after that we fill in the
+ * corresponding process lines commands.
+ */
+ if (tr_idx == IMGU_SHD_SETS ||
+ tr_idx == num_of_sets + last_tr) {
+ add_tr = false;
+ add_pl = true;
+ }
+
+ /*
+ * We have finished the "initial" operations chunk -
+ * be ready to get more chunks.
+ */
+ if (pl_idx == 2) {
+ add_tr = true;
+ add_pl = true;
+ }
+
+ /* Stop conditions for each operation type */
+ if (tr_idx == num_of_sets + last_tr)
+ add_tr = false;
+ if (pl_idx == num_of_sets)
+ add_pl = false;
+ }
+
+ return 0;
+}
+
+/*
+ * The follow handshake procotol is the same for AF, AWB and AWB FR.
+ *
+ * for n sets of meta-data, the flow is:
+ * --> init
+ * process-lines (0)
+ * process-lines (1) eoc
+ * --> ack (0)
+ * read-meta-data (0)
+ * process-lines (2) eoc
+ * --> ack (1)
+ * read-meta-data (1)
+ * process-lines (3) eoc
+ * ...
+ *
+ * --> ack (n-3)
+ * read-meta-data (n-3)
+ * process-lines (n-1) eoc
+ * --> ack (n-2)
+ * read-meta-data (n-2) eoc
+ * --> ack (n-1)
+ * read-meta-data (n-1) eof
+ *
+ * for 2 sets we get:
+ * --> init
+ * pl (0)
+ * pl (1) eoc
+ * --> ack (0)
+ * pl (2) - rest of image, if applicable)
+ * rmd (0) eoc
+ * --> ack (1)
+ * rmd (1) eof
+ * --> (ack (2))
+ * do nothing
+ *
+ * for only one set:
+ *
+ * --> init
+ * pl(0) eoc
+ * --> ack (0)
+ * rmd (0) eof
+ *
+ * grid smaller than image case
+ * for example 128x128 grid (block size 8x8, 16x16 num of blocks)
+ * start at (0,0)
+ * 1st set holds 160 cells - 10 blocks vertical, 16 horizontal
+ * => 1st process lines = 80
+ * we're left with 128-80=48 lines (6 blocks vertical)
+ * => 2nd process lines = 48
+ * last process lines to cover the image - image_height - 128
+ *
+ * --> init
+ * pl (0) first
+ * pl (1) last-in-grid
+ * --> ack (0)
+ * rmd (0)
+ * pl (2) after-grid
+ * --> ack (1)
+ * rmd (1) eof
+ * --> ack (2)
+ * do nothing
+ */
+struct process_lines {
+ unsigned int image_height;
+ unsigned short grid_height;
+ unsigned short block_height;
+ unsigned short y_start;
+ unsigned char grid_height_per_slice;
+
+ unsigned short max_op; /* max operation */
+ unsigned short max_tr; /* max transaction */
+ unsigned char acc_enable;
+};
+
+/* Helper to config intra_frame_operations_data. */
+static int
+ipu3_css_acc_process_lines(const struct process_lines *pl,
+ struct imgu_abi_acc_operation *p_op,
+ struct imgu_abi_acc_process_lines_cmd_data *p_pl,
+ struct imgu_abi_acc_transfer_op_data *p_tr)
+{
+ unsigned short op_idx = 0, pl_idx = 0, tr_idx = 0;
+ unsigned char tr_set_num = 0, pl_cfg_set = 0;
+ const unsigned short grid_last_line =
+ pl->y_start + pl->grid_height * pl->block_height;
+ const unsigned short process_lines =
+ pl->grid_height_per_slice * pl->block_height;
+
+ unsigned int process_lines_after_grid;
+ unsigned short first_process_lines;
+ unsigned short last_process_lines_in_grid;
+
+ unsigned short num_of_process_lines;
+ unsigned short num_of_sets;
+
+ if (pl->grid_height_per_slice == 0)
+ return -EINVAL;
+
+ if (pl->acc_enable && grid_last_line > pl->image_height)
+ return -EINVAL;
+
+ num_of_sets = pl->grid_height / pl->grid_height_per_slice;
+ if (num_of_sets * pl->grid_height_per_slice < pl->grid_height)
+ num_of_sets++;
+
+ /* Account for two line delay inside the FF */
+ if (pl->max_op == IMGU_ABI_AF_MAX_OPERATIONS) {
+ first_process_lines = process_lines + pl->y_start + 2;
+ last_process_lines_in_grid =
+ (grid_last_line - first_process_lines) -
+ ((num_of_sets - 2) * process_lines) + 4;
+ process_lines_after_grid =
+ pl->image_height - grid_last_line - 4;
+ } else {
+ first_process_lines = process_lines + pl->y_start;
+ last_process_lines_in_grid =
+ (grid_last_line - first_process_lines) -
+ ((num_of_sets - 2) * process_lines);
+ process_lines_after_grid = pl->image_height - grid_last_line;
+ }
+
+ num_of_process_lines = num_of_sets;
+ if (process_lines_after_grid > 0)
+ num_of_process_lines++;
+
+ while (tr_idx < num_of_sets || pl_idx < num_of_process_lines) {
+ /* Read meta-data */
+ if (pl_idx >= 2 || (pl_idx == 1 && num_of_sets == 1)) {
+ if (op_idx >= pl->max_op || tr_idx >= pl->max_tr)
+ return -EINVAL;
+
+ p_op[op_idx].op_type =
+ IMGU_ABI_ACC_OPTYPE_TRANSFER_DATA;
+
+ if (tr_idx == num_of_sets - 1)
+ /* The last operation is always a tr */
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_END_OF_OPS;
+ else if (tr_idx == num_of_sets - 2)
+ if (process_lines_after_grid == 0)
+ /*
+ * No additional pl op left -
+ * this op is left as lats of cycle
+ */
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_END_OF_ACK;
+ else
+ /*
+ * We still have to process-lines after
+ * the grid so have one more pl op
+ */
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_IDLE;
+ else
+ /* Default - usually there's a pl after a tr */
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_IDLE;
+
+ op_idx++;
+ if (p_tr) {
+ p_tr[tr_idx].set_number = tr_set_num;
+ tr_set_num = 1 - tr_set_num;
+ }
+ tr_idx++;
+ }
+
+ /* process_lines */
+ if (pl_idx < num_of_process_lines) {
+ if (op_idx >= pl->max_op || pl_idx >= pl->max_tr)
+ return -EINVAL;
+
+ p_op[op_idx].op_type =
+ IMGU_ABI_ACC_OPTYPE_PROCESS_LINES;
+ if (pl_idx == 0)
+ if (num_of_process_lines == 1)
+ /* Only one pl op */
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_END_OF_ACK;
+ else
+ /* On init - do two pl ops */
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_IDLE;
+ else
+ /* Usually pl is the end of the ack cycle */
+ p_op[op_idx].op_indicator =
+ IMGU_ABI_ACC_OP_END_OF_ACK;
+
+ op_idx++;
+
+ if (pl_idx == 0)
+ /* First process line */
+ p_pl[pl_idx].lines = first_process_lines;
+ else if (pl_idx == num_of_sets - 1)
+ /* Last in grid */
+ p_pl[pl_idx].lines = last_process_lines_in_grid;
+ else if (pl_idx == num_of_process_lines - 1)
+ /* After the grid */
+ p_pl[pl_idx].lines = process_lines_after_grid;
+ else
+ /* Inside the grid */
+ p_pl[pl_idx].lines = process_lines;
+
+ if (p_tr) {
+ p_pl[pl_idx].cfg_set = pl_cfg_set;
+ pl_cfg_set = 1 - pl_cfg_set;
+ }
+ pl_idx++;
+ }
+ }
+
+ return 0;
+}
+
+static int ipu3_css_af_ops_calc(struct ipu3_css *css, unsigned int pipe,
+ struct imgu_abi_af_config *af_config)
+{
+ struct imgu_abi_af_intra_frame_operations_data *to =
+ &af_config->operations_data;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css_pipe->bindex];
+
+ struct process_lines pl = {
+ .image_height = css_pipe->rect[IPU3_CSS_RECT_BDS].height,
+ .grid_height = af_config->config.grid_cfg.height,
+ .block_height =
+ 1 << af_config->config.grid_cfg.block_height_log2,
+ .y_start = af_config->config.grid_cfg.y_start &
+ IPU3_UAPI_GRID_START_MASK,
+ .grid_height_per_slice =
+ af_config->stripes[0].grid_cfg.height_per_slice,
+ .max_op = IMGU_ABI_AF_MAX_OPERATIONS,
+ .max_tr = IMGU_ABI_AF_MAX_TRANSFERS,
+ .acc_enable = bi->info.isp.sp.enable.af,
+ };
+
+ return ipu3_css_acc_process_lines(&pl, to->ops, to->process_lines_data,
+ NULL);
+}
+
+static int
+ipu3_css_awb_fr_ops_calc(struct ipu3_css *css, unsigned int pipe,
+ struct imgu_abi_awb_fr_config *awb_fr_config)
+{
+ struct imgu_abi_awb_fr_intra_frame_operations_data *to =
+ &awb_fr_config->operations_data;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css_pipe->bindex];
+ struct process_lines pl = {
+ .image_height = css_pipe->rect[IPU3_CSS_RECT_BDS].height,
+ .grid_height = awb_fr_config->config.grid_cfg.height,
+ .block_height =
+ 1 << awb_fr_config->config.grid_cfg.block_height_log2,
+ .y_start = awb_fr_config->config.grid_cfg.y_start &
+ IPU3_UAPI_GRID_START_MASK,
+ .grid_height_per_slice =
+ awb_fr_config->stripes[0].grid_cfg.height_per_slice,
+ .max_op = IMGU_ABI_AWB_FR_MAX_OPERATIONS,
+ .max_tr = IMGU_ABI_AWB_FR_MAX_PROCESS_LINES,
+ .acc_enable = bi->info.isp.sp.enable.awb_fr_acc,
+ };
+
+ return ipu3_css_acc_process_lines(&pl, to->ops, to->process_lines_data,
+ NULL);
+}
+
+static int ipu3_css_awb_ops_calc(struct ipu3_css *css, unsigned int pipe,
+ struct imgu_abi_awb_config *awb_config)
+{
+ struct imgu_abi_awb_intra_frame_operations_data *to =
+ &awb_config->operations_data;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css_pipe->bindex];
+
+ struct process_lines pl = {
+ .image_height = css_pipe->rect[IPU3_CSS_RECT_BDS].height,
+ .grid_height = awb_config->config.grid.height,
+ .block_height =
+ 1 << awb_config->config.grid.block_height_log2,
+ .y_start = awb_config->config.grid.y_start,
+ .grid_height_per_slice =
+ awb_config->stripes[0].grid.height_per_slice,
+ .max_op = IMGU_ABI_AWB_MAX_OPERATIONS,
+ .max_tr = IMGU_ABI_AWB_MAX_TRANSFERS,
+ .acc_enable = bi->info.isp.sp.enable.awb_acc,
+ };
+
+ return ipu3_css_acc_process_lines(&pl, to->ops, to->process_lines_data,
+ to->transfer_data);
+}
+
+static u16 ipu3_css_grid_end(u16 start, u8 width, u8 block_width_log2)
+{
+ return (start & IPU3_UAPI_GRID_START_MASK) +
+ (width << block_width_log2) - 1;
+}
+
+static void ipu3_css_grid_end_calc(struct ipu3_uapi_grid_config *grid_cfg)
+{
+ grid_cfg->x_end = ipu3_css_grid_end(grid_cfg->x_start, grid_cfg->width,
+ grid_cfg->block_width_log2);
+ grid_cfg->y_end = ipu3_css_grid_end(grid_cfg->y_start, grid_cfg->height,
+ grid_cfg->block_height_log2);
+}
+
+/****************** config computation *****************************/
+
+static int ipu3_css_cfg_acc_stripe(struct ipu3_css *css, unsigned int pipe,
+ struct imgu_abi_acc_param *acc)
+{
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ const struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css_pipe->bindex];
+ struct ipu3_css_scaler_info scaler_luma, scaler_chroma;
+ const unsigned int stripes = bi->info.isp.sp.iterator.num_stripes;
+ const unsigned int f = IPU3_UAPI_ISP_VEC_ELEMS * 2;
+ unsigned int bds_ds, i;
+
+ memset(acc, 0, sizeof(*acc));
+
+ /* acc_param: osys_config */
+
+ if (ipu3_css_osys_calc(css, pipe, stripes, &acc->osys, &scaler_luma,
+ &scaler_chroma, acc->stripe.block_stripes))
+ return -EINVAL;
+
+ /* acc_param: stripe data */
+
+ /*
+ * For the striped case the approach is as follows:
+ * 1. down-scaled stripes are calculated - with 128 overlap
+ * (this is the main limiter therefore it's first)
+ * 2. input stripes are derived by up-scaling the down-scaled stripes
+ * (there are no alignment requirements on input stripes)
+ * 3. output stripes are derived from down-scaled stripes too
+ */
+
+ acc->stripe.num_of_stripes = stripes;
+ acc->stripe.input_frame.width =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].fmt.mpix.width;
+ acc->stripe.input_frame.height =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].fmt.mpix.height;
+ acc->stripe.input_frame.bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bayer_order;
+
+ for (i = 0; i < stripes; i++)
+ acc->stripe.bds_out_stripes[i].height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ acc->stripe.bds_out_stripes[0].offset = 0;
+ if (stripes <= 1) {
+ acc->stripe.bds_out_stripes[0].width =
+ ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width, f);
+ } else {
+ /* Image processing is divided into two stripes */
+ acc->stripe.bds_out_stripes[0].width =
+ acc->stripe.bds_out_stripes[1].width =
+ (css_pipe->rect[IPU3_CSS_RECT_BDS].width / 2 & ~(f - 1)) + f;
+ /*
+ * Sum of width of the two stripes should not be smaller
+ * than output width and must be even times of overlapping
+ * unit f.
+ */
+ if ((css_pipe->rect[IPU3_CSS_RECT_BDS].width / f & 1) !=
+ !!(css_pipe->rect[IPU3_CSS_RECT_BDS].width & (f - 1)))
+ acc->stripe.bds_out_stripes[0].width += f;
+ if ((css_pipe->rect[IPU3_CSS_RECT_BDS].width / f & 1) &&
+ (css_pipe->rect[IPU3_CSS_RECT_BDS].width & (f - 1))) {
+ acc->stripe.bds_out_stripes[0].width += f;
+ acc->stripe.bds_out_stripes[1].width += f;
+ }
+ /* Overlap between stripes is IPU3_UAPI_ISP_VEC_ELEMS * 4 */
+ acc->stripe.bds_out_stripes[1].offset =
+ acc->stripe.bds_out_stripes[0].width - 2 * f;
+ }
+
+ acc->stripe.effective_stripes[0].height =
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].height;
+ acc->stripe.effective_stripes[0].offset = 0;
+ acc->stripe.bds_out_stripes_no_overlap[0].height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ acc->stripe.bds_out_stripes_no_overlap[0].offset = 0;
+ acc->stripe.output_stripes[0].height =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.height;
+ acc->stripe.output_stripes[0].offset = 0;
+ if (stripes <= 1) {
+ acc->stripe.down_scaled_stripes[0].width =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].width;
+ acc->stripe.down_scaled_stripes[0].height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ acc->stripe.down_scaled_stripes[0].offset = 0;
+
+ acc->stripe.effective_stripes[0].width =
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].width;
+ acc->stripe.bds_out_stripes_no_overlap[0].width =
+ ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width, f);
+
+ acc->stripe.output_stripes[0].width =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.width;
+ } else { /* Two stripes */
+ bds_ds = css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].width *
+ IMGU_BDS_GRANULARITY /
+ css_pipe->rect[IPU3_CSS_RECT_BDS].width;
+
+ acc->stripe.down_scaled_stripes[0] =
+ acc->stripe.bds_out_stripes[0];
+ acc->stripe.down_scaled_stripes[1] =
+ acc->stripe.bds_out_stripes[1];
+ if (!IS_ALIGNED(css_pipe->rect[IPU3_CSS_RECT_BDS].width, f))
+ acc->stripe.down_scaled_stripes[1].width +=
+ (css_pipe->rect[IPU3_CSS_RECT_BDS].width
+ & (f - 1)) - f;
+
+ acc->stripe.effective_stripes[0].width = bds_ds *
+ acc->stripe.down_scaled_stripes[0].width /
+ IMGU_BDS_GRANULARITY;
+ acc->stripe.effective_stripes[1].width = bds_ds *
+ acc->stripe.down_scaled_stripes[1].width /
+ IMGU_BDS_GRANULARITY;
+ acc->stripe.effective_stripes[1].height =
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].height;
+ acc->stripe.effective_stripes[1].offset = bds_ds *
+ acc->stripe.down_scaled_stripes[1].offset /
+ IMGU_BDS_GRANULARITY;
+
+ acc->stripe.bds_out_stripes_no_overlap[0].width =
+ acc->stripe.bds_out_stripes_no_overlap[1].offset =
+ ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width, 2 * f) / 2;
+ acc->stripe.bds_out_stripes_no_overlap[1].width =
+ DIV_ROUND_UP(css_pipe->rect[IPU3_CSS_RECT_BDS].width, f)
+ / 2 * f;
+ acc->stripe.bds_out_stripes_no_overlap[1].height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+
+ acc->stripe.output_stripes[0].width =
+ acc->stripe.down_scaled_stripes[0].width - f;
+ acc->stripe.output_stripes[1].width =
+ acc->stripe.down_scaled_stripes[1].width - f;
+ acc->stripe.output_stripes[1].height =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.height;
+ acc->stripe.output_stripes[1].offset =
+ acc->stripe.output_stripes[0].width;
+ }
+
+ acc->stripe.output_system_in_frame_width =
+ css_pipe->rect[IPU3_CSS_RECT_GDC].width;
+ acc->stripe.output_system_in_frame_height =
+ css_pipe->rect[IPU3_CSS_RECT_GDC].height;
+
+ acc->stripe.effective_frame_width =
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].width;
+ acc->stripe.bds_frame_width = css_pipe->rect[IPU3_CSS_RECT_BDS].width;
+ acc->stripe.out_frame_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.width;
+ acc->stripe.out_frame_height =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.height;
+ acc->stripe.gdc_in_buffer_width =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperline /
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperpixel;
+ acc->stripe.gdc_in_buffer_height =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].height;
+ acc->stripe.gdc_in_buffer_offset_x = IMGU_GDC_BUF_X;
+ acc->stripe.gdc_in_buffer_offset_y = IMGU_GDC_BUF_Y;
+ acc->stripe.display_frame_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.width;
+ acc->stripe.display_frame_height =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.height;
+ acc->stripe.bds_aligned_frame_width =
+ roundup(css_pipe->rect[IPU3_CSS_RECT_BDS].width,
+ 2 * IPU3_UAPI_ISP_VEC_ELEMS);
+
+ if (stripes > 1)
+ acc->stripe.half_overlap_vectors =
+ IMGU_STRIPE_FIXED_HALF_OVERLAP;
+ else
+ acc->stripe.half_overlap_vectors = 0;
+
+ return 0;
+}
+
+static void ipu3_css_cfg_acc_dvs(struct ipu3_css *css,
+ struct imgu_abi_acc_param *acc,
+ unsigned int pipe)
+{
+ unsigned int i;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ /* Disable DVS statistics */
+ acc->dvs_stat.operations_data.process_lines_data[0].lines =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ acc->dvs_stat.operations_data.process_lines_data[0].cfg_set = 0;
+ acc->dvs_stat.operations_data.ops[0].op_type =
+ IMGU_ABI_ACC_OPTYPE_PROCESS_LINES;
+ acc->dvs_stat.operations_data.ops[0].op_indicator =
+ IMGU_ABI_ACC_OP_NO_OPS;
+ for (i = 0; i < IMGU_ABI_DVS_STAT_LEVELS; i++)
+ acc->dvs_stat.cfg.grd_config[i].enable = 0;
+}
+
+static void acc_bds_per_stripe_data(struct ipu3_css *css,
+ struct imgu_abi_acc_param *acc,
+ const int i, unsigned int pipe)
+{
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ acc->bds.per_stripe.aligned_data[i].data.crop.hor_crop_en = 0;
+ acc->bds.per_stripe.aligned_data[i].data.crop.hor_crop_start = 0;
+ acc->bds.per_stripe.aligned_data[i].data.crop.hor_crop_end = 0;
+ acc->bds.per_stripe.aligned_data[i].data.hor_ctrl0 =
+ acc->bds.hor.hor_ctrl0;
+ acc->bds.per_stripe.aligned_data[i].data.hor_ctrl0.out_frame_width =
+ acc->stripe.down_scaled_stripes[i].width;
+ acc->bds.per_stripe.aligned_data[i].data.ver_ctrl1.out_frame_width =
+ acc->stripe.down_scaled_stripes[i].width;
+ acc->bds.per_stripe.aligned_data[i].data.ver_ctrl1.out_frame_height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+}
+
+/*
+ * Configure `acc' parameters. `acc_old' contains the old values (or is NULL)
+ * and `acc_user' contains new prospective values. `use' contains flags
+ * telling which fields to take from the old values (or generate if it is NULL)
+ * and which to take from the new user values.
+ */
+int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_uapi_flags *use,
+ struct imgu_abi_acc_param *acc,
+ struct imgu_abi_acc_param *acc_old,
+ struct ipu3_uapi_acc_param *acc_user)
+{
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ const struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css_pipe->bindex];
+ const unsigned int stripes = bi->info.isp.sp.iterator.num_stripes;
+ const unsigned int tnr_frame_width =
+ acc->stripe.bds_aligned_frame_width;
+ const unsigned int min_overlap = 10;
+ const struct v4l2_pix_format_mplane *pixm =
+ &css_pipe->queue[IPU3_CSS_QUEUE_IN].fmt.mpix;
+ const struct ipu3_css_bds_config *cfg_bds;
+ struct imgu_abi_input_feeder_data *feeder_data;
+
+ unsigned int bds_ds, ofs_x, ofs_y, i, width, height;
+ u8 b_w_log2; /* Block width log2 */
+
+ /* Update stripe using chroma and luma */
+
+ if (ipu3_css_cfg_acc_stripe(css, pipe, acc))
+ return -EINVAL;
+
+ /* acc_param: input_feeder_config */
+
+ ofs_x = ((pixm->width -
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].width) >> 1) & ~1;
+ ofs_x += css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bayer_order ==
+ IMGU_ABI_BAYER_ORDER_RGGB ||
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bayer_order ==
+ IMGU_ABI_BAYER_ORDER_GBRG ? 1 : 0;
+ ofs_y = ((pixm->height -
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].height) >> 1) & ~1;
+ ofs_y += css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bayer_order ==
+ IMGU_ABI_BAYER_ORDER_BGGR ||
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bayer_order ==
+ IMGU_ABI_BAYER_ORDER_GBRG ? 1 : 0;
+ acc->input_feeder.data.row_stride = pixm->plane_fmt[0].bytesperline;
+ acc->input_feeder.data.start_row_address =
+ ofs_x / IMGU_PIXELS_PER_WORD * IMGU_BYTES_PER_WORD +
+ ofs_y * acc->input_feeder.data.row_stride;
+ acc->input_feeder.data.start_pixel = ofs_x % IMGU_PIXELS_PER_WORD;
+
+ acc->input_feeder.data_per_stripe.input_feeder_data[0].data =
+ acc->input_feeder.data;
+
+ ofs_x += acc->stripe.effective_stripes[1].offset;
+
+ feeder_data =
+ &acc->input_feeder.data_per_stripe.input_feeder_data[1].data;
+ feeder_data->row_stride = acc->input_feeder.data.row_stride;
+ feeder_data->start_row_address =
+ ofs_x / IMGU_PIXELS_PER_WORD * IMGU_BYTES_PER_WORD +
+ ofs_y * acc->input_feeder.data.row_stride;
+ feeder_data->start_pixel = ofs_x % IMGU_PIXELS_PER_WORD;
+
+ /* acc_param: bnr_static_config */
+
+ /*
+ * Originate from user or be the original default values if user has
+ * never set them before, when user gives a new set of parameters,
+ * for each chunk in the parameter structure there is a flag use->xxx
+ * whether to use the user-provided parameter or not. If not, the
+ * parameter remains unchanged in the driver:
+ * it's value is taken from acc_old.
+ */
+ if (use && use->acc_bnr) {
+ /* Take values from user */
+ acc->bnr = acc_user->bnr;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->bnr = acc_old->bnr;
+ } else {
+ /* Calculate from scratch */
+ acc->bnr = ipu3_css_bnr_defaults;
+ }
+
+ acc->bnr.column_size = tnr_frame_width;
+
+ /* acc_param: bnr_static_config_green_disparity */
+
+ if (use && use->acc_green_disparity) {
+ /* Take values from user */
+ acc->green_disparity = acc_user->green_disparity;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->green_disparity = acc_old->green_disparity;
+ } else {
+ /* Calculate from scratch */
+ memset(&acc->green_disparity, 0, sizeof(acc->green_disparity));
+ }
+
+ /* acc_param: dm_config */
+
+ if (use && use->acc_dm) {
+ /* Take values from user */
+ acc->dm = acc_user->dm;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->dm = acc_old->dm;
+ } else {
+ /* Calculate from scratch */
+ acc->dm = ipu3_css_dm_defaults;
+ }
+
+ acc->dm.frame_width = tnr_frame_width;
+
+ /* acc_param: ccm_mat_config */
+
+ if (use && use->acc_ccm) {
+ /* Take values from user */
+ acc->ccm = acc_user->ccm;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->ccm = acc_old->ccm;
+ } else {
+ /* Calculate from scratch */
+ acc->ccm = ipu3_css_ccm_defaults;
+ }
+
+ /* acc_param: gamma_config */
+
+ if (use && use->acc_gamma) {
+ /* Take values from user */
+ acc->gamma = acc_user->gamma;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->gamma = acc_old->gamma;
+ } else {
+ /* Calculate from scratch */
+ acc->gamma.gc_ctrl.enable = 1;
+ acc->gamma.gc_lut = ipu3_css_gamma_lut;
+ }
+
+ /* acc_param: csc_mat_config */
+
+ if (use && use->acc_csc) {
+ /* Take values from user */
+ acc->csc = acc_user->csc;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->csc = acc_old->csc;
+ } else {
+ /* Calculate from scratch */
+ acc->csc = ipu3_css_csc_defaults;
+ }
+
+ /* acc_param: cds_params */
+
+ if (use && use->acc_cds) {
+ /* Take values from user */
+ acc->cds = acc_user->cds;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->cds = acc_old->cds;
+ } else {
+ /* Calculate from scratch */
+ acc->cds = ipu3_css_cds_defaults;
+ }
+
+ /* acc_param: shd_config */
+
+ if (use && use->acc_shd) {
+ /* Take values from user */
+ acc->shd.shd = acc_user->shd.shd;
+ acc->shd.shd_lut = acc_user->shd.shd_lut;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->shd.shd = acc_old->shd.shd;
+ acc->shd.shd_lut = acc_old->shd.shd_lut;
+ } else {
+ /* Calculate from scratch */
+ acc->shd.shd = ipu3_css_shd_defaults;
+ memset(&acc->shd.shd_lut, 0, sizeof(acc->shd.shd_lut));
+ }
+
+ if (acc->shd.shd.grid.width <= 0)
+ return -EINVAL;
+
+ acc->shd.shd.grid.grid_height_per_slice =
+ IMGU_ABI_SHD_MAX_CELLS_PER_SET / acc->shd.shd.grid.width;
+
+ if (acc->shd.shd.grid.grid_height_per_slice <= 0)
+ return -EINVAL;
+
+ acc->shd.shd.general.init_set_vrt_offst_ul =
+ (-acc->shd.shd.grid.y_start >>
+ acc->shd.shd.grid.block_height_log2) %
+ acc->shd.shd.grid.grid_height_per_slice;
+
+ if (ipu3_css_shd_ops_calc(&acc->shd.shd_ops, &acc->shd.shd.grid,
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height))
+ return -EINVAL;
+
+ /* acc_param: dvs_stat_config */
+ ipu3_css_cfg_acc_dvs(css, acc, pipe);
+
+ /* acc_param: yuvp1_iefd_config */
+
+ if (use && use->acc_iefd) {
+ /* Take values from user */
+ acc->iefd = acc_user->iefd;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->iefd = acc_old->iefd;
+ } else {
+ /* Calculate from scratch */
+ acc->iefd = ipu3_css_iefd_defaults;
+ }
+
+ /* acc_param: yuvp1_yds_config yds_c0 */
+
+ if (use && use->acc_yds_c0) {
+ /* Take values from user */
+ acc->yds_c0 = acc_user->yds_c0;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->yds_c0 = acc_old->yds_c0;
+ } else {
+ /* Calculate from scratch */
+ acc->yds_c0 = ipu3_css_yds_defaults;
+ }
+
+ /* acc_param: yuvp1_chnr_config chnr_c0 */
+
+ if (use && use->acc_chnr_c0) {
+ /* Take values from user */
+ acc->chnr_c0 = acc_user->chnr_c0;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->chnr_c0 = acc_old->chnr_c0;
+ } else {
+ /* Calculate from scratch */
+ acc->chnr_c0 = ipu3_css_chnr_defaults;
+ }
+
+ /* acc_param: yuvp1_y_ee_nr_config */
+
+ if (use && use->acc_y_ee_nr) {
+ /* Take values from user */
+ acc->y_ee_nr = acc_user->y_ee_nr;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->y_ee_nr = acc_old->y_ee_nr;
+ } else {
+ /* Calculate from scratch */
+ acc->y_ee_nr = ipu3_css_y_ee_nr_defaults;
+ }
+
+ /* acc_param: yuvp1_yds_config yds */
+
+ if (use && use->acc_yds) {
+ /* Take values from user */
+ acc->yds = acc_user->yds;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->yds = acc_old->yds;
+ } else {
+ /* Calculate from scratch */
+ acc->yds = ipu3_css_yds_defaults;
+ }
+
+ /* acc_param: yuvp1_chnr_config chnr */
+
+ if (use && use->acc_chnr) {
+ /* Take values from user */
+ acc->chnr = acc_user->chnr;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->chnr = acc_old->chnr;
+ } else {
+ /* Calculate from scratch */
+ acc->chnr = ipu3_css_chnr_defaults;
+ }
+
+ /* acc_param: yuvp2_y_tm_lut_static_config */
+
+ for (i = 0; i < IMGU_ABI_YUVP2_YTM_LUT_ENTRIES; i++)
+ acc->ytm.entries[i] = i * 32;
+ acc->ytm.enable = 0; /* Always disabled on IPU3 */
+
+ /* acc_param: yuvp1_yds_config yds2 */
+
+ if (use && use->acc_yds2) {
+ /* Take values from user */
+ acc->yds2 = acc_user->yds2;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->yds2 = acc_old->yds2;
+ } else {
+ /* Calculate from scratch */
+ acc->yds2 = ipu3_css_yds_defaults;
+ }
+
+ /* acc_param: yuvp2_tcc_static_config */
+
+ if (use && use->acc_tcc) {
+ /* Take values from user */
+ acc->tcc = acc_user->tcc;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->tcc = acc_old->tcc;
+ } else {
+ /* Calculate from scratch */
+ memset(&acc->tcc, 0, sizeof(acc->tcc));
+
+ acc->tcc.gen_control.en = 1;
+ acc->tcc.gen_control.blend_shift = 3;
+ acc->tcc.gen_control.gain_according_to_y_only = 1;
+ acc->tcc.gen_control.gamma = 8;
+ acc->tcc.gen_control.delta = 0;
+
+ for (i = 0; i < IPU3_UAPI_YUVP2_TCC_MACC_TABLE_ELEMENTS; i++) {
+ acc->tcc.macc_table.entries[i].a = 1024;
+ acc->tcc.macc_table.entries[i].b = 0;
+ acc->tcc.macc_table.entries[i].c = 0;
+ acc->tcc.macc_table.entries[i].d = 1024;
+ }
+
+ acc->tcc.inv_y_lut.entries[6] = 1023;
+ for (i = 7; i < IPU3_UAPI_YUVP2_TCC_INV_Y_LUT_ELEMENTS; i++)
+ acc->tcc.inv_y_lut.entries[i] = 1024 >> (i - 6);
+
+ acc->tcc.gain_pcwl = ipu3_css_tcc_gain_pcwl_lut;
+ acc->tcc.r_sqr_lut = ipu3_css_tcc_r_sqr_lut;
+ }
+
+ /* acc_param: dpc_config */
+
+ if (use && use->acc_dpc)
+ return -EINVAL; /* Not supported yet */
+
+ /* Just disable by default */
+ memset(&acc->dpc, 0, sizeof(acc->dpc));
+
+ /* acc_param: bds_config */
+
+ bds_ds = (css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].height *
+ IMGU_BDS_GRANULARITY) / css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ if (bds_ds < IMGU_BDS_MIN_SF_INV ||
+ bds_ds - IMGU_BDS_MIN_SF_INV >= ARRAY_SIZE(ipu3_css_bds_configs))
+ return -EINVAL;
+
+ cfg_bds = &ipu3_css_bds_configs[bds_ds - IMGU_BDS_MIN_SF_INV];
+ acc->bds.hor.hor_ctrl1.hor_crop_en = 0;
+ acc->bds.hor.hor_ctrl1.hor_crop_start = 0;
+ acc->bds.hor.hor_ctrl1.hor_crop_end = 0;
+ acc->bds.hor.hor_ctrl0.sample_patrn_length =
+ cfg_bds->sample_patrn_length;
+ acc->bds.hor.hor_ctrl0.hor_ds_en = cfg_bds->hor_ds_en;
+ acc->bds.hor.hor_ctrl0.min_clip_val = IMGU_BDS_MIN_CLIP_VAL;
+ acc->bds.hor.hor_ctrl0.max_clip_val = IMGU_BDS_MAX_CLIP_VAL;
+ acc->bds.hor.hor_ctrl0.out_frame_width =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].width;
+ acc->bds.hor.hor_ptrn_arr = cfg_bds->ptrn_arr;
+ acc->bds.hor.hor_phase_arr = cfg_bds->hor_phase_arr;
+ acc->bds.hor.hor_ctrl2.input_frame_height =
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].height;
+ acc->bds.ver.ver_ctrl0.min_clip_val = IMGU_BDS_MIN_CLIP_VAL;
+ acc->bds.ver.ver_ctrl0.max_clip_val = IMGU_BDS_MAX_CLIP_VAL;
+ acc->bds.ver.ver_ctrl0.sample_patrn_length =
+ cfg_bds->sample_patrn_length;
+ acc->bds.ver.ver_ctrl0.ver_ds_en = cfg_bds->ver_ds_en;
+ acc->bds.ver.ver_ptrn_arr = cfg_bds->ptrn_arr;
+ acc->bds.ver.ver_phase_arr = cfg_bds->ver_phase_arr;
+ acc->bds.ver.ver_ctrl1.out_frame_width =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].width;
+ acc->bds.ver.ver_ctrl1.out_frame_height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ for (i = 0; i < stripes; i++)
+ acc_bds_per_stripe_data(css, acc, i, pipe);
+
+ acc->bds.enabled = cfg_bds->hor_ds_en || cfg_bds->ver_ds_en;
+
+ /* acc_param: anr_config */
+
+ if (use && use->acc_anr) {
+ /* Take values from user */
+ acc->anr.transform = acc_user->anr.transform;
+ acc->anr.stitch.anr_stitch_en =
+ acc_user->anr.stitch.anr_stitch_en;
+ memcpy(acc->anr.stitch.pyramid, acc_user->anr.stitch.pyramid,
+ sizeof(acc->anr.stitch.pyramid));
+ } else if (acc_old) {
+ /* Use old value */
+ acc->anr.transform = acc_old->anr.transform;
+ acc->anr.stitch.anr_stitch_en =
+ acc_old->anr.stitch.anr_stitch_en;
+ memcpy(acc->anr.stitch.pyramid, acc_old->anr.stitch.pyramid,
+ sizeof(acc->anr.stitch.pyramid));
+ } else {
+ /* Calculate from scratch */
+ acc->anr = ipu3_css_anr_defaults;
+ }
+
+ /* Always enabled */
+ acc->anr.search.enable = 1;
+ acc->anr.transform.enable = 1;
+ acc->anr.tile2strm.enable = 1;
+ acc->anr.tile2strm.frame_width =
+ ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width, IMGU_ISP_VMEM_ALIGN);
+ acc->anr.search.frame_width = acc->anr.tile2strm.frame_width;
+ acc->anr.stitch.frame_width = acc->anr.tile2strm.frame_width;
+ acc->anr.tile2strm.frame_height = css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ acc->anr.search.frame_height = acc->anr.tile2strm.frame_height;
+ acc->anr.stitch.frame_height = acc->anr.tile2strm.frame_height;
+
+ width = ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width, IMGU_ISP_VMEM_ALIGN);
+ height = css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+
+ if (acc->anr.transform.xreset + width > IPU3_UAPI_ANR_MAX_RESET)
+ acc->anr.transform.xreset = IPU3_UAPI_ANR_MAX_RESET - width;
+ if (acc->anr.transform.xreset < IPU3_UAPI_ANR_MIN_RESET)
+ acc->anr.transform.xreset = IPU3_UAPI_ANR_MIN_RESET;
+
+ if (acc->anr.transform.yreset + height > IPU3_UAPI_ANR_MAX_RESET)
+ acc->anr.transform.yreset = IPU3_UAPI_ANR_MAX_RESET - height;
+ if (acc->anr.transform.yreset < IPU3_UAPI_ANR_MIN_RESET)
+ acc->anr.transform.yreset = IPU3_UAPI_ANR_MIN_RESET;
+
+ /* acc_param: awb_fr_config */
+
+ if (use && use->acc_awb_fr) {
+ /* Take values from user */
+ acc->awb_fr.config = acc_user->awb_fr;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->awb_fr.config = acc_old->awb_fr.config;
+ } else {
+ /* Set from scratch */
+ acc->awb_fr.config = ipu3_css_awb_fr_defaults;
+ }
+
+ ipu3_css_grid_end_calc(&acc->awb_fr.config.grid_cfg);
+
+ if (acc->awb_fr.config.grid_cfg.width <= 0)
+ return -EINVAL;
+
+ acc->awb_fr.config.grid_cfg.height_per_slice =
+ IMGU_ABI_AWB_FR_MAX_CELLS_PER_SET /
+ acc->awb_fr.config.grid_cfg.width;
+
+ for (i = 0; i < stripes; i++)
+ acc->awb_fr.stripes[i] = acc->awb_fr.config;
+
+ if (acc->awb_fr.config.grid_cfg.x_start >=
+ acc->stripe.down_scaled_stripes[1].offset + min_overlap) {
+ /* Enable only for rightmost stripe, disable left */
+ acc->awb_fr.stripes[0].grid_cfg.y_start &=
+ ~IPU3_UAPI_GRID_Y_START_EN;
+ } else if (acc->awb_fr.config.grid_cfg.x_end <=
+ acc->stripe.bds_out_stripes[0].width - min_overlap) {
+ /* Enable only for leftmost stripe, disable right */
+ acc->awb_fr.stripes[1].grid_cfg.y_start &=
+ ~IPU3_UAPI_GRID_Y_START_EN;
+ } else {
+ /* Enable for both stripes */
+ u16 end; /* width for grid end */
+
+ acc->awb_fr.stripes[0].grid_cfg.width =
+ (acc->stripe.bds_out_stripes[0].width - min_overlap -
+ acc->awb_fr.config.grid_cfg.x_start + 1) >>
+ acc->awb_fr.config.grid_cfg.block_width_log2;
+ acc->awb_fr.stripes[1].grid_cfg.width =
+ acc->awb_fr.config.grid_cfg.width -
+ acc->awb_fr.stripes[0].grid_cfg.width;
+
+ b_w_log2 = acc->awb_fr.stripes[0].grid_cfg.block_width_log2;
+ end = ipu3_css_grid_end(acc->awb_fr.stripes[0].grid_cfg.x_start,
+ acc->awb_fr.stripes[0].grid_cfg.width,
+ b_w_log2);
+ acc->awb_fr.stripes[0].grid_cfg.x_end = end;
+
+ acc->awb_fr.stripes[1].grid_cfg.x_start =
+ (acc->awb_fr.stripes[0].grid_cfg.x_end + 1 -
+ acc->stripe.down_scaled_stripes[1].offset) &
+ IPU3_UAPI_GRID_START_MASK;
+ b_w_log2 = acc->awb_fr.stripes[1].grid_cfg.block_width_log2;
+ end = ipu3_css_grid_end(acc->awb_fr.stripes[1].grid_cfg.x_start,
+ acc->awb_fr.stripes[1].grid_cfg.width,
+ b_w_log2);
+ acc->awb_fr.stripes[1].grid_cfg.x_end = end;
+
+ /*
+ * To reduce complexity of debubbling and loading
+ * statistics fix grid_height_per_slice to 1 for both
+ * stripes.
+ */
+ for (i = 0; i < stripes; i++)
+ acc->awb_fr.stripes[i].grid_cfg.height_per_slice = 1;
+ }
+
+ if (ipu3_css_awb_fr_ops_calc(css, pipe, &acc->awb_fr))
+ return -EINVAL;
+
+ /* acc_param: ae_config */
+
+ if (use && use->acc_ae) {
+ /* Take values from user */
+ acc->ae.grid_cfg = acc_user->ae.grid_cfg;
+ acc->ae.ae_ccm = acc_user->ae.ae_ccm;
+ for (i = 0; i < IPU3_UAPI_AE_WEIGHTS; i++)
+ acc->ae.weights[i] = acc_user->ae.weights[i];
+ } else if (acc_old) {
+ /* Use old value */
+ acc->ae.grid_cfg = acc_old->ae.grid_cfg;
+ acc->ae.ae_ccm = acc_old->ae.ae_ccm;
+ for (i = 0; i < IPU3_UAPI_AE_WEIGHTS; i++)
+ acc->ae.weights[i] = acc_old->ae.weights[i];
+ } else {
+ /* Set from scratch */
+ static const struct ipu3_uapi_ae_weight_elem
+ weight_def = { 1, 1, 1, 1, 1, 1, 1, 1 };
+
+ acc->ae.grid_cfg = ipu3_css_ae_grid_defaults;
+ acc->ae.ae_ccm = ipu3_css_ae_ccm_defaults;
+ for (i = 0; i < IPU3_UAPI_AE_WEIGHTS; i++)
+ acc->ae.weights[i] = weight_def;
+ }
+
+ b_w_log2 = acc->ae.grid_cfg.block_width_log2;
+ acc->ae.grid_cfg.x_end = ipu3_css_grid_end(acc->ae.grid_cfg.x_start,
+ acc->ae.grid_cfg.width,
+ b_w_log2);
+ b_w_log2 = acc->ae.grid_cfg.block_height_log2;
+ acc->ae.grid_cfg.y_end = ipu3_css_grid_end(acc->ae.grid_cfg.y_start,
+ acc->ae.grid_cfg.height,
+ b_w_log2);
+
+ for (i = 0; i < stripes; i++)
+ acc->ae.stripes[i].grid = acc->ae.grid_cfg;
+
+ if (acc->ae.grid_cfg.x_start >=
+ acc->stripe.down_scaled_stripes[1].offset) {
+ /* Enable only for rightmost stripe, disable left */
+ acc->ae.stripes[0].grid.ae_en = 0;
+ } else if (acc->ae.grid_cfg.x_end <=
+ acc->stripe.bds_out_stripes[0].width) {
+ /* Enable only for leftmost stripe, disable right */
+ acc->ae.stripes[1].grid.ae_en = 0;
+ } else {
+ /* Enable for both stripes */
+ u8 b_w_log2;
+
+ acc->ae.stripes[0].grid.width =
+ (acc->stripe.bds_out_stripes[0].width -
+ acc->ae.grid_cfg.x_start + 1) >>
+ acc->ae.grid_cfg.block_width_log2;
+
+ acc->ae.stripes[1].grid.width =
+ acc->ae.grid_cfg.width - acc->ae.stripes[0].grid.width;
+
+ b_w_log2 = acc->ae.stripes[0].grid.block_width_log2;
+ acc->ae.stripes[0].grid.x_end =
+ ipu3_css_grid_end(acc->ae.stripes[0].grid.x_start,
+ acc->ae.stripes[0].grid.width,
+ b_w_log2);
+
+ acc->ae.stripes[1].grid.x_start =
+ (acc->ae.stripes[0].grid.x_end + 1 -
+ acc->stripe.down_scaled_stripes[1].offset) &
+ IPU3_UAPI_GRID_START_MASK;
+ b_w_log2 = acc->ae.stripes[1].grid.block_width_log2;
+ acc->ae.stripes[1].grid.x_end =
+ ipu3_css_grid_end(acc->ae.stripes[1].grid.x_start,
+ acc->ae.stripes[1].grid.width,
+ b_w_log2);
+ }
+
+ /* acc_param: af_config */
+
+ if (use && use->acc_af) {
+ /* Take values from user */
+ acc->af.config.filter_config = acc_user->af.filter_config;
+ acc->af.config.grid_cfg = acc_user->af.grid_cfg;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->af.config = acc_old->af.config;
+ } else {
+ /* Set from scratch */
+ acc->af.config.filter_config =
+ ipu3_css_af_defaults.filter_config;
+ acc->af.config.grid_cfg = ipu3_css_af_defaults.grid_cfg;
+ }
+
+ ipu3_css_grid_end_calc(&acc->af.config.grid_cfg);
+
+ if (acc->af.config.grid_cfg.width <= 0)
+ return -EINVAL;
+
+ acc->af.config.grid_cfg.height_per_slice =
+ IMGU_ABI_AF_MAX_CELLS_PER_SET / acc->af.config.grid_cfg.width;
+ acc->af.config.frame_size.width =
+ ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width, IMGU_ISP_VMEM_ALIGN);
+ acc->af.config.frame_size.height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+
+ if (acc->stripe.bds_out_stripes[0].width <= min_overlap)
+ return -EINVAL;
+
+ for (i = 0; i < stripes; i++) {
+ acc->af.stripes[i].grid_cfg = acc->af.config.grid_cfg;
+ acc->af.stripes[i].frame_size.height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ acc->af.stripes[i].frame_size.width =
+ acc->stripe.bds_out_stripes[i].width;
+ }
+
+ if (acc->af.config.grid_cfg.x_start >=
+ acc->stripe.down_scaled_stripes[1].offset + min_overlap) {
+ /* Enable only for rightmost stripe, disable left */
+ acc->af.stripes[0].grid_cfg.y_start &=
+ ~IPU3_UAPI_GRID_Y_START_EN;
+ } else if (acc->af.config.grid_cfg.x_end <=
+ acc->stripe.bds_out_stripes[0].width - min_overlap) {
+ /* Enable only for leftmost stripe, disable right */
+ acc->af.stripes[1].grid_cfg.y_start &=
+ ~IPU3_UAPI_GRID_Y_START_EN;
+ } else {
+ /* Enable for both stripes */
+
+ acc->af.stripes[0].grid_cfg.width =
+ (acc->stripe.bds_out_stripes[0].width - min_overlap -
+ acc->af.config.grid_cfg.x_start + 1) >>
+ acc->af.config.grid_cfg.block_width_log2;
+ acc->af.stripes[1].grid_cfg.width =
+ acc->af.config.grid_cfg.width -
+ acc->af.stripes[0].grid_cfg.width;
+
+ b_w_log2 = acc->af.stripes[0].grid_cfg.block_width_log2;
+ acc->af.stripes[0].grid_cfg.x_end =
+ ipu3_css_grid_end(acc->af.stripes[0].grid_cfg.x_start,
+ acc->af.stripes[0].grid_cfg.width,
+ b_w_log2);
+
+ acc->af.stripes[1].grid_cfg.x_start =
+ (acc->af.stripes[0].grid_cfg.x_end + 1 -
+ acc->stripe.down_scaled_stripes[1].offset) &
+ IPU3_UAPI_GRID_START_MASK;
+
+ b_w_log2 = acc->af.stripes[1].grid_cfg.block_width_log2;
+ acc->af.stripes[1].grid_cfg.x_end =
+ ipu3_css_grid_end(acc->af.stripes[1].grid_cfg.x_start,
+ acc->af.stripes[1].grid_cfg.width,
+ b_w_log2);
+
+ /*
+ * To reduce complexity of debubbling and loading statistics
+ * fix grid_height_per_slice to 1 for both stripes
+ */
+ for (i = 0; i < stripes; i++)
+ acc->af.stripes[i].grid_cfg.height_per_slice = 1;
+ }
+
+ if (ipu3_css_af_ops_calc(css, pipe, &acc->af))
+ return -EINVAL;
+
+ /* acc_param: awb_config */
+
+ if (use && use->acc_awb) {
+ /* Take values from user */
+ acc->awb.config = acc_user->awb.config;
+ } else if (acc_old) {
+ /* Use old value */
+ acc->awb.config = acc_old->awb.config;
+ } else {
+ /* Set from scratch */
+ acc->awb.config = ipu3_css_awb_defaults;
+ }
+
+ if (acc->awb.config.grid.width <= 0)
+ return -EINVAL;
+
+ acc->awb.config.grid.height_per_slice =
+ IMGU_ABI_AWB_MAX_CELLS_PER_SET / acc->awb.config.grid.width,
+ ipu3_css_grid_end_calc(&acc->awb.config.grid);
+
+ for (i = 0; i < stripes; i++)
+ acc->awb.stripes[i] = acc->awb.config;
+
+ if (acc->awb.config.grid.x_start >=
+ acc->stripe.down_scaled_stripes[1].offset + min_overlap) {
+ /* Enable only for rightmost stripe, disable left */
+ acc->awb.stripes[0].rgbs_thr_b &= ~IPU3_UAPI_AWB_RGBS_THR_B_EN;
+ } else if (acc->awb.config.grid.x_end <=
+ acc->stripe.bds_out_stripes[0].width - min_overlap) {
+ /* Enable only for leftmost stripe, disable right */
+ acc->awb.stripes[1].rgbs_thr_b &= ~IPU3_UAPI_AWB_RGBS_THR_B_EN;
+ } else {
+ /* Enable for both stripes */
+
+ acc->awb.stripes[0].grid.width =
+ (acc->stripe.bds_out_stripes[0].width -
+ acc->awb.config.grid.x_start + 1) >>
+ acc->awb.config.grid.block_width_log2;
+ acc->awb.stripes[1].grid.width = acc->awb.config.grid.width -
+ acc->awb.stripes[0].grid.width;
+
+ b_w_log2 = acc->awb.stripes[0].grid.block_width_log2;
+ acc->awb.stripes[0].grid.x_end =
+ ipu3_css_grid_end(acc->awb.stripes[0].grid.x_start,
+ acc->awb.stripes[0].grid.width,
+ b_w_log2);
+
+ acc->awb.stripes[1].grid.x_start =
+ (acc->awb.stripes[0].grid.x_end + 1 -
+ acc->stripe.down_scaled_stripes[1].offset) &
+ IPU3_UAPI_GRID_START_MASK;
+
+ b_w_log2 = acc->awb.stripes[1].grid.block_width_log2;
+ acc->awb.stripes[1].grid.x_end =
+ ipu3_css_grid_end(acc->awb.stripes[1].grid.x_start,
+ acc->awb.stripes[1].grid.width,
+ b_w_log2);
+
+ /*
+ * To reduce complexity of debubbling and loading statistics
+ * fix grid_height_per_slice to 1 for both stripes
+ */
+ for (i = 0; i < stripes; i++)
+ acc->awb.stripes[i].grid.height_per_slice = 1;
+ }
+
+ if (ipu3_css_awb_ops_calc(css, pipe, &acc->awb))
+ return -EINVAL;
+
+ return 0;
+}
+
+/*
+ * Fill the indicated structure in `new_binary_params' from the possible
+ * sources based on `use_user' flag: if the flag is false, copy from
+ * `old_binary_params', or if the flag is true, copy from `user_setting'
+ * and return NULL (or error pointer on error).
+ * If the flag is false and `old_binary_params' is NULL, return pointer
+ * to the structure inside `new_binary_params'. In that case the caller
+ * should calculate and fill the structure from scratch.
+ */
+static void *ipu3_css_cfg_copy(struct ipu3_css *css,
+ unsigned int pipe, bool use_user,
+ void *user_setting, void *old_binary_params,
+ void *new_binary_params,
+ enum imgu_abi_memories m,
+ struct imgu_fw_isp_parameter *par,
+ size_t par_size)
+{
+ const enum imgu_abi_param_class c = IMGU_ABI_PARAM_CLASS_PARAM;
+ void *new_setting, *old_setting;
+
+ new_setting = ipu3_css_fw_pipeline_params(css, pipe, c, m, par,
+ par_size, new_binary_params);
+ if (!new_setting)
+ return ERR_PTR(-EPROTO); /* Corrupted firmware */
+
+ if (use_user) {
+ /* Take new user parameters */
+ memcpy(new_setting, user_setting, par_size);
+ } else if (old_binary_params) {
+ /* Take previous value */
+ old_setting = ipu3_css_fw_pipeline_params(css, pipe, c, m, par,
+ par_size,
+ old_binary_params);
+ if (!old_setting)
+ return ERR_PTR(-EPROTO);
+ memcpy(new_setting, old_setting, par_size);
+ } else {
+ return new_setting; /* Need to calculate */
+ }
+
+ return NULL; /* Copied from other value */
+}
+
+/*
+ * Configure VMEM0 parameters (late binding parameters).
+ */
+int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_uapi_flags *use,
+ void *vmem0, void *vmem0_old,
+ struct ipu3_uapi_params *user)
+{
+ const struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css->pipes[pipe].bindex];
+ struct imgu_fw_param_memory_offsets *pofs = (void *)css->fwp +
+ bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_PARAM];
+ struct ipu3_uapi_isp_lin_vmem_params *lin_vmem = NULL;
+ struct ipu3_uapi_isp_tnr3_vmem_params *tnr_vmem = NULL;
+ struct ipu3_uapi_isp_xnr3_vmem_params *xnr_vmem = NULL;
+ const enum imgu_abi_param_class c = IMGU_ABI_PARAM_CLASS_PARAM;
+ const enum imgu_abi_memories m = IMGU_ABI_MEM_ISP_VMEM0;
+ unsigned int i;
+
+ /* Configure VMEM0 */
+
+ memset(vmem0, 0, bi->info.isp.sp.mem_initializers.params[c][m].size);
+
+ /* Configure Linearization VMEM0 parameters */
+
+ lin_vmem = ipu3_css_cfg_copy(css, pipe, use && use->lin_vmem_params,
+ &user->lin_vmem_params, vmem0_old, vmem0,
+ m, &pofs->vmem.lin, sizeof(*lin_vmem));
+ if (!IS_ERR_OR_NULL(lin_vmem)) {
+ /* Generate parameter from scratch */
+ for (i = 0; i < IPU3_UAPI_LIN_LUT_SIZE; i++) {
+ lin_vmem->lin_lutlow_gr[i] = 32 * i;
+ lin_vmem->lin_lutlow_r[i] = 32 * i;
+ lin_vmem->lin_lutlow_b[i] = 32 * i;
+ lin_vmem->lin_lutlow_gb[i] = 32 * i;
+
+ lin_vmem->lin_lutdif_gr[i] = 32;
+ lin_vmem->lin_lutdif_r[i] = 32;
+ lin_vmem->lin_lutdif_b[i] = 32;
+ lin_vmem->lin_lutdif_gb[i] = 32;
+ }
+ }
+
+ /* Configure TNR3 VMEM parameters */
+ if (css->pipes[pipe].pipe_id == IPU3_CSS_PIPE_ID_VIDEO) {
+ tnr_vmem = ipu3_css_cfg_copy(css, pipe,
+ use && use->tnr3_vmem_params,
+ &user->tnr3_vmem_params,
+ vmem0_old, vmem0, m,
+ &pofs->vmem.tnr3,
+ sizeof(*tnr_vmem));
+ if (!IS_ERR_OR_NULL(tnr_vmem)) {
+ /* Generate parameter from scratch */
+ for (i = 0; i < IPU3_UAPI_ISP_TNR3_VMEM_LEN; i++)
+ tnr_vmem->sigma[i] = 256;
+ }
+ }
+ i = IPU3_UAPI_ISP_TNR3_VMEM_LEN;
+
+ /* Configure XNR3 VMEM parameters */
+
+ xnr_vmem = ipu3_css_cfg_copy(css, pipe, use && use->xnr3_vmem_params,
+ &user->xnr3_vmem_params, vmem0_old, vmem0,
+ m, &pofs->vmem.xnr3, sizeof(*xnr_vmem));
+ if (!IS_ERR_OR_NULL(xnr_vmem)) {
+ xnr_vmem->x[i] = ipu3_css_xnr3_vmem_defaults.x
+ [i % IMGU_XNR3_VMEM_LUT_LEN];
+ xnr_vmem->a[i] = ipu3_css_xnr3_vmem_defaults.a
+ [i % IMGU_XNR3_VMEM_LUT_LEN];
+ xnr_vmem->b[i] = ipu3_css_xnr3_vmem_defaults.b
+ [i % IMGU_XNR3_VMEM_LUT_LEN];
+ xnr_vmem->c[i] = ipu3_css_xnr3_vmem_defaults.c
+ [i % IMGU_XNR3_VMEM_LUT_LEN];
+ }
+
+ return IS_ERR(lin_vmem) || IS_ERR(tnr_vmem) || IS_ERR(xnr_vmem) ?
+ -EPROTO : 0;
+}
+
+/*
+ * Configure DMEM0 parameters (late binding parameters).
+ */
+int ipu3_css_cfg_dmem0(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_uapi_flags *use,
+ void *dmem0, void *dmem0_old,
+ struct ipu3_uapi_params *user)
+{
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ const struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css_pipe->bindex];
+ struct imgu_fw_param_memory_offsets *pofs = (void *)css->fwp +
+ bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_PARAM];
+
+ struct ipu3_uapi_isp_tnr3_params *tnr_dmem = NULL;
+ struct ipu3_uapi_isp_xnr3_params *xnr_dmem;
+
+ const enum imgu_abi_param_class c = IMGU_ABI_PARAM_CLASS_PARAM;
+ const enum imgu_abi_memories m = IMGU_ABI_MEM_ISP_DMEM0;
+
+ /* Configure DMEM0 */
+
+ memset(dmem0, 0, bi->info.isp.sp.mem_initializers.params[c][m].size);
+
+ /* Configure TNR3 DMEM0 parameters */
+ if (css_pipe->pipe_id == IPU3_CSS_PIPE_ID_VIDEO) {
+ tnr_dmem = ipu3_css_cfg_copy(css, pipe,
+ use && use->tnr3_dmem_params,
+ &user->tnr3_dmem_params,
+ dmem0_old, dmem0, m,
+ &pofs->dmem.tnr3,
+ sizeof(*tnr_dmem));
+ if (!IS_ERR_OR_NULL(tnr_dmem)) {
+ /* Generate parameter from scratch */
+ tnr_dmem->knee_y1 = 768;
+ tnr_dmem->knee_y2 = 1280;
+ }
+ }
+
+ /* Configure XNR3 DMEM0 parameters */
+
+ xnr_dmem = ipu3_css_cfg_copy(css, pipe, use && use->xnr3_dmem_params,
+ &user->xnr3_dmem_params, dmem0_old, dmem0,
+ m, &pofs->dmem.xnr3, sizeof(*xnr_dmem));
+ if (!IS_ERR_OR_NULL(xnr_dmem)) {
+ /* Generate parameter from scratch */
+ xnr_dmem->alpha.y0 = 2047;
+ xnr_dmem->alpha.u0 = 2047;
+ xnr_dmem->alpha.v0 = 2047;
+ }
+
+ return IS_ERR(tnr_dmem) || IS_ERR(xnr_dmem) ? -EPROTO : 0;
+}
+
+/* Generate unity morphing table without morphing effect */
+void ipu3_css_cfg_gdc_table(struct imgu_abi_gdc_warp_param *gdc,
+ int frame_in_x, int frame_in_y,
+ int frame_out_x, int frame_out_y,
+ int env_w, int env_h)
+{
+ static const unsigned int FRAC_BITS = IMGU_ABI_GDC_FRAC_BITS;
+ static const unsigned int XMEM_ALIGN = 1 << 4;
+ const unsigned int XMEM_ALIGN_MASK = ~(XMEM_ALIGN - 1);
+ static const unsigned int BCI_ENV = 4;
+ static const unsigned int BYP = 2; /* Bytes per pixel */
+ const unsigned int OFFSET_X = 2 * IMGU_DVS_BLOCK_W + env_w + 1;
+ const unsigned int OFFSET_Y = IMGU_DVS_BLOCK_H + env_h + 1;
+
+ struct imgu_abi_gdc_warp_param gdc_luma, gdc_chroma;
+
+ unsigned int blocks_x = ALIGN(DIV_ROUND_UP(frame_out_x,
+ IMGU_DVS_BLOCK_W), 2);
+ unsigned int blocks_y = DIV_ROUND_UP(frame_out_y, IMGU_DVS_BLOCK_H);
+ unsigned int y0, x0, x1, x, y;
+
+ /* Global luma settings */
+ gdc_luma.origin_x = 0;
+ gdc_luma.origin_y = 0;
+ gdc_luma.p0_x = (OFFSET_X - (OFFSET_X & XMEM_ALIGN_MASK)) << FRAC_BITS;
+ gdc_luma.p0_y = 0;
+ gdc_luma.p1_x = gdc_luma.p0_x + (IMGU_DVS_BLOCK_W << FRAC_BITS);
+ gdc_luma.p1_y = gdc_luma.p0_y;
+ gdc_luma.p2_x = gdc_luma.p0_x;
+ gdc_luma.p2_y = gdc_luma.p0_y + (IMGU_DVS_BLOCK_H << FRAC_BITS);
+ gdc_luma.p3_x = gdc_luma.p1_x;
+ gdc_luma.p3_y = gdc_luma.p2_y;
+
+ gdc_luma.in_block_width = IMGU_DVS_BLOCK_W + BCI_ENV +
+ OFFSET_X - (OFFSET_X & XMEM_ALIGN_MASK);
+ gdc_luma.in_block_width_a = DIV_ROUND_UP(gdc_luma.in_block_width,
+ IPU3_UAPI_ISP_VEC_ELEMS);
+ gdc_luma.in_block_width_b = DIV_ROUND_UP(gdc_luma.in_block_width,
+ IMGU_ABI_ISP_DDR_WORD_BYTES /
+ BYP);
+ gdc_luma.in_block_height = IMGU_DVS_BLOCK_H + BCI_ENV;
+ gdc_luma.padding = 0;
+
+ /* Global chroma settings */
+ gdc_chroma.origin_x = 0;
+ gdc_chroma.origin_y = 0;
+ gdc_chroma.p0_x = (OFFSET_X / 2 - (OFFSET_X / 2 & XMEM_ALIGN_MASK)) <<
+ FRAC_BITS;
+ gdc_chroma.p0_y = 0;
+ gdc_chroma.p1_x = gdc_chroma.p0_x + (IMGU_DVS_BLOCK_W << FRAC_BITS);
+ gdc_chroma.p1_y = gdc_chroma.p0_y;
+ gdc_chroma.p2_x = gdc_chroma.p0_x;
+ gdc_chroma.p2_y = gdc_chroma.p0_y + (IMGU_DVS_BLOCK_H / 2 << FRAC_BITS);
+ gdc_chroma.p3_x = gdc_chroma.p1_x;
+ gdc_chroma.p3_y = gdc_chroma.p2_y;
+
+ gdc_chroma.in_block_width = IMGU_DVS_BLOCK_W + BCI_ENV;
+ gdc_chroma.in_block_width_a = DIV_ROUND_UP(gdc_chroma.in_block_width,
+ IPU3_UAPI_ISP_VEC_ELEMS);
+ gdc_chroma.in_block_width_b = DIV_ROUND_UP(gdc_chroma.in_block_width,
+ IMGU_ABI_ISP_DDR_WORD_BYTES /
+ BYP);
+ gdc_chroma.in_block_height = IMGU_DVS_BLOCK_H / 2 + BCI_ENV;
+ gdc_chroma.padding = 0;
+
+ /* Calculate block offsets for luma and chroma */
+ for (y0 = 0; y0 < blocks_y; y0++) {
+ for (x0 = 0; x0 < blocks_x / 2; x0++) {
+ for (x1 = 0; x1 < 2; x1++) {
+ /* Luma blocks */
+ x = (x0 * 2 + x1) * IMGU_DVS_BLOCK_W + OFFSET_X;
+ x &= XMEM_ALIGN_MASK;
+ y = y0 * IMGU_DVS_BLOCK_H + OFFSET_Y;
+ *gdc = gdc_luma;
+ gdc->in_addr_offset =
+ (y * frame_in_x + x) * BYP;
+ gdc++;
+ }
+
+ /* Chroma block */
+ x = x0 * IMGU_DVS_BLOCK_W + OFFSET_X / 2;
+ x &= XMEM_ALIGN_MASK;
+ y = y0 * (IMGU_DVS_BLOCK_H / 2) + OFFSET_Y / 2;
+ *gdc = gdc_chroma;
+ gdc->in_addr_offset = (y * frame_in_x + x) * BYP;
+ gdc++;
+ }
+ }
+}
diff --git a/drivers/staging/media/ipu3/ipu3-css-params.h b/drivers/staging/media/ipu3/ipu3-css-params.h
new file mode 100644
index 000000000000..f3a0a47117a4
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-css-params.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 Intel Corporation */
+
+#ifndef __IPU3_PARAMS_H
+#define __IPU3_PARAMS_H
+
+int ipu3_css_cfg_acc(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_uapi_flags *use,
+ struct imgu_abi_acc_param *acc,
+ struct imgu_abi_acc_param *acc_old,
+ struct ipu3_uapi_acc_param *acc_user);
+
+int ipu3_css_cfg_vmem0(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_uapi_flags *use,
+ void *vmem0, void *vmem0_old,
+ struct ipu3_uapi_params *user);
+
+int ipu3_css_cfg_dmem0(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_uapi_flags *use,
+ void *dmem0, void *dmem0_old,
+ struct ipu3_uapi_params *user);
+
+void ipu3_css_cfg_gdc_table(struct imgu_abi_gdc_warp_param *gdc,
+ int frame_in_x, int frame_in_y,
+ int frame_out_x, int frame_out_y,
+ int env_w, int env_h);
+
+#endif /*__IPU3_PARAMS_H */
diff --git a/drivers/staging/media/ipu3/ipu3-css-pool.c b/drivers/staging/media/ipu3/ipu3-css-pool.c
new file mode 100644
index 000000000000..6f271f81669b
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-css-pool.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Intel Corporation
+
+#include <linux/device.h>
+
+#include "ipu3.h"
+#include "ipu3-css-pool.h"
+#include "ipu3-dmamap.h"
+
+int ipu3_css_dma_buffer_resize(struct imgu_device *imgu,
+ struct ipu3_css_map *map, size_t size)
+{
+ if (map->size < size && map->vaddr) {
+ dev_warn(&imgu->pci_dev->dev, "dma buf resized from %zu to %zu",
+ map->size, size);
+
+ ipu3_dmamap_free(imgu, map);
+ if (!ipu3_dmamap_alloc(imgu, map, size))
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void ipu3_css_pool_cleanup(struct imgu_device *imgu, struct ipu3_css_pool *pool)
+{
+ unsigned int i;
+
+ for (i = 0; i < IPU3_CSS_POOL_SIZE; i++)
+ ipu3_dmamap_free(imgu, &pool->entry[i].param);
+}
+
+int ipu3_css_pool_init(struct imgu_device *imgu, struct ipu3_css_pool *pool,
+ size_t size)
+{
+ unsigned int i;
+
+ for (i = 0; i < IPU3_CSS_POOL_SIZE; i++) {
+ pool->entry[i].valid = false;
+ if (size == 0) {
+ pool->entry[i].param.vaddr = NULL;
+ continue;
+ }
+
+ if (!ipu3_dmamap_alloc(imgu, &pool->entry[i].param, size))
+ goto fail;
+ }
+
+ pool->last = IPU3_CSS_POOL_SIZE;
+
+ return 0;
+
+fail:
+ ipu3_css_pool_cleanup(imgu, pool);
+ return -ENOMEM;
+}
+
+/*
+ * Allocate a new parameter via recycling the oldest entry in the pool.
+ */
+void ipu3_css_pool_get(struct ipu3_css_pool *pool)
+{
+ /* Get the oldest entry */
+ u32 n = (pool->last + 1) % IPU3_CSS_POOL_SIZE;
+
+ pool->entry[n].valid = true;
+ pool->last = n;
+}
+
+/*
+ * Undo, for all practical purposes, the effect of pool_get().
+ */
+void ipu3_css_pool_put(struct ipu3_css_pool *pool)
+{
+ pool->entry[pool->last].valid = false;
+ pool->last = (pool->last + IPU3_CSS_POOL_SIZE - 1) % IPU3_CSS_POOL_SIZE;
+}
+
+/**
+ * ipu3_css_pool_last - Retrieve the nth pool entry from last
+ *
+ * @pool: a pointer to &struct ipu3_css_pool.
+ * @n: the distance to the last index.
+ *
+ * Returns:
+ * The nth entry from last or null map to indicate no frame stored.
+ */
+const struct ipu3_css_map *
+ipu3_css_pool_last(struct ipu3_css_pool *pool, unsigned int n)
+{
+ static const struct ipu3_css_map null_map = { 0 };
+ int i = (pool->last + IPU3_CSS_POOL_SIZE - n) % IPU3_CSS_POOL_SIZE;
+
+ WARN_ON(n >= IPU3_CSS_POOL_SIZE);
+
+ if (!pool->entry[i].valid)
+ return &null_map;
+
+ return &pool->entry[i].param;
+}
diff --git a/drivers/staging/media/ipu3/ipu3-css-pool.h b/drivers/staging/media/ipu3/ipu3-css-pool.h
new file mode 100644
index 000000000000..2657c39a4d71
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-css-pool.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 Intel Corporation */
+
+#ifndef __IPU3_UTIL_H
+#define __IPU3_UTIL_H
+
+struct device;
+struct imgu_device;
+
+#define IPU3_CSS_POOL_SIZE 4
+
+/**
+ * ipu3_css_map - store DMA mapping info for buffer
+ *
+ * @size: size of the buffer in bytes.
+ * @vaddr: kernel virtual address.
+ * @daddr: iova dma address to access IPU3.
+ * @vma: private, a pointer to &struct vm_struct,
+ * used for ipu3_dmamap_free.
+ */
+struct ipu3_css_map {
+ size_t size;
+ void *vaddr;
+ dma_addr_t daddr;
+ struct vm_struct *vma;
+};
+
+/**
+ * ipu3_css_pool - circular buffer pool definition
+ *
+ * @entry: array with IPU3_CSS_POOL_SIZE elements.
+ * @entry.param: a &struct ipu3_css_map for storing the mem mapping.
+ * @entry.valid: used to mark if the entry has valid data.
+ * @last: write pointer, initialized to IPU3_CSS_POOL_SIZE.
+ */
+struct ipu3_css_pool {
+ struct {
+ struct ipu3_css_map param;
+ bool valid;
+ } entry[IPU3_CSS_POOL_SIZE];
+ u32 last;
+};
+
+int ipu3_css_dma_buffer_resize(struct imgu_device *imgu,
+ struct ipu3_css_map *map, size_t size);
+void ipu3_css_pool_cleanup(struct imgu_device *imgu,
+ struct ipu3_css_pool *pool);
+int ipu3_css_pool_init(struct imgu_device *imgu, struct ipu3_css_pool *pool,
+ size_t size);
+void ipu3_css_pool_get(struct ipu3_css_pool *pool);
+void ipu3_css_pool_put(struct ipu3_css_pool *pool);
+const struct ipu3_css_map *ipu3_css_pool_last(struct ipu3_css_pool *pool,
+ u32 last);
+
+#endif
diff --git a/drivers/staging/media/ipu3/ipu3-css.c b/drivers/staging/media/ipu3/ipu3-css.c
new file mode 100644
index 000000000000..44c55639389a
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-css.c
@@ -0,0 +1,2391 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Intel Corporation
+
+#include <linux/device.h>
+#include <linux/iopoll.h>
+
+#include "ipu3-css.h"
+#include "ipu3-css-fw.h"
+#include "ipu3-css-params.h"
+#include "ipu3-dmamap.h"
+#include "ipu3-tables.h"
+
+/* IRQ configuration */
+#define IMGU_IRQCTRL_IRQ_MASK (IMGU_IRQCTRL_IRQ_SP1 | \
+ IMGU_IRQCTRL_IRQ_SP2 | \
+ IMGU_IRQCTRL_IRQ_SW_PIN(0) | \
+ IMGU_IRQCTRL_IRQ_SW_PIN(1))
+
+#define IPU3_CSS_FORMAT_BPP_DEN 50 /* Denominator */
+
+/* Some sane limits for resolutions */
+#define IPU3_CSS_MIN_RES 32
+#define IPU3_CSS_MAX_H 3136
+#define IPU3_CSS_MAX_W 4224
+
+/* filter size from graph settings is fixed as 4 */
+#define FILTER_SIZE 4
+#define MIN_ENVELOPE 8
+
+/*
+ * pre-allocated buffer size for CSS ABI, auxiliary frames
+ * after BDS and before GDC. Those values should be tuned
+ * to big enough to avoid buffer re-allocation when
+ * streaming to lower streaming latency.
+ */
+#define CSS_ABI_SIZE 136
+#define CSS_BDS_SIZE (4480 * 3200 * 3)
+#define CSS_GDC_SIZE (4224 * 3200 * 12 / 8)
+
+#define IPU3_CSS_QUEUE_TO_FLAGS(q) (1 << (q))
+#define IPU3_CSS_FORMAT_FL_IN \
+ IPU3_CSS_QUEUE_TO_FLAGS(IPU3_CSS_QUEUE_IN)
+#define IPU3_CSS_FORMAT_FL_OUT \
+ IPU3_CSS_QUEUE_TO_FLAGS(IPU3_CSS_QUEUE_OUT)
+#define IPU3_CSS_FORMAT_FL_VF \
+ IPU3_CSS_QUEUE_TO_FLAGS(IPU3_CSS_QUEUE_VF)
+
+/* Formats supported by IPU3 Camera Sub System */
+static const struct ipu3_css_format ipu3_css_formats[] = {
+ {
+ .pixelformat = V4L2_PIX_FMT_NV12,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .frame_format = IMGU_ABI_FRAME_FORMAT_NV12,
+ .osys_format = IMGU_ABI_OSYS_FORMAT_NV12,
+ .osys_tiling = IMGU_ABI_OSYS_TILING_NONE,
+ .bytesperpixel_num = 1 * IPU3_CSS_FORMAT_BPP_DEN,
+ .chroma_decim = 4,
+ .width_align = IPU3_UAPI_ISP_VEC_ELEMS,
+ .flags = IPU3_CSS_FORMAT_FL_OUT | IPU3_CSS_FORMAT_FL_VF,
+ }, {
+ /* Each 32 bytes contains 25 10-bit pixels */
+ .pixelformat = V4L2_PIX_FMT_IPU3_SBGGR10,
+ .colorspace = V4L2_COLORSPACE_RAW,
+ .frame_format = IMGU_ABI_FRAME_FORMAT_RAW_PACKED,
+ .bayer_order = IMGU_ABI_BAYER_ORDER_BGGR,
+ .bit_depth = 10,
+ .bytesperpixel_num = 64,
+ .width_align = 2 * IPU3_UAPI_ISP_VEC_ELEMS,
+ .flags = IPU3_CSS_FORMAT_FL_IN,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_IPU3_SGBRG10,
+ .colorspace = V4L2_COLORSPACE_RAW,
+ .frame_format = IMGU_ABI_FRAME_FORMAT_RAW_PACKED,
+ .bayer_order = IMGU_ABI_BAYER_ORDER_GBRG,
+ .bit_depth = 10,
+ .bytesperpixel_num = 64,
+ .width_align = 2 * IPU3_UAPI_ISP_VEC_ELEMS,
+ .flags = IPU3_CSS_FORMAT_FL_IN,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_IPU3_SGRBG10,
+ .colorspace = V4L2_COLORSPACE_RAW,
+ .frame_format = IMGU_ABI_FRAME_FORMAT_RAW_PACKED,
+ .bayer_order = IMGU_ABI_BAYER_ORDER_GRBG,
+ .bit_depth = 10,
+ .bytesperpixel_num = 64,
+ .width_align = 2 * IPU3_UAPI_ISP_VEC_ELEMS,
+ .flags = IPU3_CSS_FORMAT_FL_IN,
+ }, {
+ .pixelformat = V4L2_PIX_FMT_IPU3_SRGGB10,
+ .colorspace = V4L2_COLORSPACE_RAW,
+ .frame_format = IMGU_ABI_FRAME_FORMAT_RAW_PACKED,
+ .bayer_order = IMGU_ABI_BAYER_ORDER_RGGB,
+ .bit_depth = 10,
+ .bytesperpixel_num = 64,
+ .width_align = 2 * IPU3_UAPI_ISP_VEC_ELEMS,
+ .flags = IPU3_CSS_FORMAT_FL_IN,
+ },
+};
+
+static const struct {
+ enum imgu_abi_queue_id qid;
+ size_t ptr_ofs;
+} ipu3_css_queues[IPU3_CSS_QUEUES] = {
+ [IPU3_CSS_QUEUE_IN] = {
+ IMGU_ABI_QUEUE_C_ID,
+ offsetof(struct imgu_abi_buffer, payload.frame.frame_data)
+ },
+ [IPU3_CSS_QUEUE_OUT] = {
+ IMGU_ABI_QUEUE_D_ID,
+ offsetof(struct imgu_abi_buffer, payload.frame.frame_data)
+ },
+ [IPU3_CSS_QUEUE_VF] = {
+ IMGU_ABI_QUEUE_E_ID,
+ offsetof(struct imgu_abi_buffer, payload.frame.frame_data)
+ },
+ [IPU3_CSS_QUEUE_STAT_3A] = {
+ IMGU_ABI_QUEUE_F_ID,
+ offsetof(struct imgu_abi_buffer, payload.s3a.data_ptr)
+ },
+};
+
+/* Initialize queue based on given format, adjust format as needed */
+static int ipu3_css_queue_init(struct ipu3_css_queue *queue,
+ struct v4l2_pix_format_mplane *fmt, u32 flags)
+{
+ struct v4l2_pix_format_mplane *const f = &queue->fmt.mpix;
+ unsigned int i;
+ u32 sizeimage;
+
+ INIT_LIST_HEAD(&queue->bufs);
+
+ queue->css_fmt = NULL; /* Disable */
+ if (!fmt)
+ return 0;
+
+ for (i = 0; i < ARRAY_SIZE(ipu3_css_formats); i++) {
+ if (!(ipu3_css_formats[i].flags & flags))
+ continue;
+ queue->css_fmt = &ipu3_css_formats[i];
+ if (ipu3_css_formats[i].pixelformat == fmt->pixelformat)
+ break;
+ }
+ if (!queue->css_fmt)
+ return -EINVAL; /* Could not find any suitable format */
+
+ queue->fmt.mpix = *fmt;
+
+ f->width = ALIGN(clamp_t(u32, f->width,
+ IPU3_CSS_MIN_RES, IPU3_CSS_MAX_W), 2);
+ f->height = ALIGN(clamp_t(u32, f->height,
+ IPU3_CSS_MIN_RES, IPU3_CSS_MAX_H), 2);
+ queue->width_pad = ALIGN(f->width, queue->css_fmt->width_align);
+ if (queue->css_fmt->frame_format != IMGU_ABI_FRAME_FORMAT_RAW_PACKED)
+ f->plane_fmt[0].bytesperline = DIV_ROUND_UP(queue->width_pad *
+ queue->css_fmt->bytesperpixel_num,
+ IPU3_CSS_FORMAT_BPP_DEN);
+ else
+ /* For packed raw, alignment for bpl is by 50 to the width */
+ f->plane_fmt[0].bytesperline =
+ DIV_ROUND_UP(f->width,
+ IPU3_CSS_FORMAT_BPP_DEN) *
+ queue->css_fmt->bytesperpixel_num;
+
+ sizeimage = f->height * f->plane_fmt[0].bytesperline;
+ if (queue->css_fmt->chroma_decim)
+ sizeimage += 2 * sizeimage / queue->css_fmt->chroma_decim;
+
+ f->plane_fmt[0].sizeimage = sizeimage;
+ f->field = V4L2_FIELD_NONE;
+ f->num_planes = 1;
+ f->colorspace = queue->css_fmt->colorspace;
+ f->flags = 0;
+ f->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ f->quantization = V4L2_QUANTIZATION_DEFAULT;
+ f->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+ memset(f->reserved, 0, sizeof(f->reserved));
+
+ return 0;
+}
+
+static bool ipu3_css_queue_enabled(struct ipu3_css_queue *q)
+{
+ return q->css_fmt;
+}
+
+/******************* css hw *******************/
+
+/* In the style of writesl() defined in include/asm-generic/io.h */
+static inline void writes(const void *mem, ssize_t count, void __iomem *addr)
+{
+ if (count >= 4) {
+ const u32 *buf = mem;
+
+ count /= 4;
+ do {
+ writel(*buf++, addr);
+ addr += 4;
+ } while (--count);
+ }
+}
+
+/* Wait until register `reg', masked with `mask', becomes `cmp' */
+static int ipu3_hw_wait(void __iomem *base, int reg, u32 mask, u32 cmp)
+{
+ u32 val;
+
+ return readl_poll_timeout(base + reg, val, (val & mask) == cmp,
+ 1000, 100 * 1000);
+}
+
+/* Initialize the IPU3 CSS hardware and associated h/w blocks */
+
+int ipu3_css_set_powerup(struct device *dev, void __iomem *base)
+{
+ static const unsigned int freq = 450;
+ u32 pm_ctrl, state, val;
+
+ dev_dbg(dev, "%s\n", __func__);
+ /* Clear the CSS busy signal */
+ readl(base + IMGU_REG_GP_BUSY);
+ writel(0, base + IMGU_REG_GP_BUSY);
+
+ /* Wait for idle signal */
+ if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS,
+ IMGU_STATE_IDLE_STS)) {
+ dev_err(dev, "failed to set CSS idle\n");
+ goto fail;
+ }
+
+ /* Reset the css */
+ writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_RESET,
+ base + IMGU_REG_PM_CTRL);
+
+ usleep_range(200, 300);
+
+ /** Prepare CSS */
+
+ pm_ctrl = readl(base + IMGU_REG_PM_CTRL);
+ state = readl(base + IMGU_REG_STATE);
+
+ dev_dbg(dev, "CSS pm_ctrl 0x%x state 0x%x (power %s)\n",
+ pm_ctrl, state, state & IMGU_STATE_POWER_DOWN ? "down" : "up");
+
+ /* Power up CSS using wrapper */
+ if (state & IMGU_STATE_POWER_DOWN) {
+ writel(IMGU_PM_CTRL_RACE_TO_HALT | IMGU_PM_CTRL_START,
+ base + IMGU_REG_PM_CTRL);
+ if (ipu3_hw_wait(base, IMGU_REG_PM_CTRL,
+ IMGU_PM_CTRL_START, 0)) {
+ dev_err(dev, "failed to power up CSS\n");
+ goto fail;
+ }
+ usleep_range(2000, 3000);
+ } else {
+ writel(IMGU_PM_CTRL_RACE_TO_HALT, base + IMGU_REG_PM_CTRL);
+ }
+
+ /* Set the busy bit */
+ writel(readl(base + IMGU_REG_GP_BUSY) | 1, base + IMGU_REG_GP_BUSY);
+
+ /* Set CSS clock frequency */
+ pm_ctrl = readl(base + IMGU_REG_PM_CTRL);
+ val = pm_ctrl & ~(IMGU_PM_CTRL_CSS_PWRDN | IMGU_PM_CTRL_RST_AT_EOF);
+ writel(val, base + IMGU_REG_PM_CTRL);
+ writel(0, base + IMGU_REG_GP_BUSY);
+ if (ipu3_hw_wait(base, IMGU_REG_STATE,
+ IMGU_STATE_PWRDNM_FSM_MASK, 0)) {
+ dev_err(dev, "failed to pwrdn CSS\n");
+ goto fail;
+ }
+ val = (freq / IMGU_SYSTEM_REQ_FREQ_DIVIDER) & IMGU_SYSTEM_REQ_FREQ_MASK;
+ writel(val, base + IMGU_REG_SYSTEM_REQ);
+ writel(1, base + IMGU_REG_GP_BUSY);
+ writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_HALT,
+ base + IMGU_REG_PM_CTRL);
+ if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS,
+ IMGU_STATE_HALT_STS)) {
+ dev_err(dev, "failed to halt CSS\n");
+ goto fail;
+ }
+
+ writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_START,
+ base + IMGU_REG_PM_CTRL);
+ if (ipu3_hw_wait(base, IMGU_REG_PM_CTRL, IMGU_PM_CTRL_START, 0)) {
+ dev_err(dev, "failed to start CSS\n");
+ goto fail;
+ }
+ writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_UNHALT,
+ base + IMGU_REG_PM_CTRL);
+
+ val = readl(base + IMGU_REG_PM_CTRL); /* get pm_ctrl */
+ val &= ~(IMGU_PM_CTRL_CSS_PWRDN | IMGU_PM_CTRL_RST_AT_EOF);
+ val |= pm_ctrl & (IMGU_PM_CTRL_CSS_PWRDN | IMGU_PM_CTRL_RST_AT_EOF);
+ writel(val, base + IMGU_REG_PM_CTRL);
+
+ return 0;
+
+fail:
+ ipu3_css_set_powerdown(dev, base);
+ return -EIO;
+}
+
+void ipu3_css_set_powerdown(struct device *dev, void __iomem *base)
+{
+ dev_dbg(dev, "%s\n", __func__);
+ /* wait for cio idle signal */
+ if (ipu3_hw_wait(base, IMGU_REG_CIO_GATE_BURST_STATE,
+ IMGU_CIO_GATE_BURST_MASK, 0))
+ dev_warn(dev, "wait cio gate idle timeout");
+
+ /* wait for css idle signal */
+ if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS,
+ IMGU_STATE_IDLE_STS))
+ dev_warn(dev, "wait css idle timeout\n");
+
+ /* do halt-halted handshake with css */
+ writel(1, base + IMGU_REG_GP_HALT);
+ if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS,
+ IMGU_STATE_HALT_STS))
+ dev_warn(dev, "failed to halt css");
+
+ /* de-assert the busy bit */
+ writel(0, base + IMGU_REG_GP_BUSY);
+}
+
+static void ipu3_css_hw_enable_irq(struct ipu3_css *css)
+{
+ void __iomem *const base = css->base;
+ u32 val, i;
+
+ /* Set up interrupts */
+
+ /*
+ * Enable IRQ on the SP which signals that SP goes to idle
+ * (aka ready state) and set trigger to pulse
+ */
+ val = readl(base + IMGU_REG_SP_CTRL(0)) | IMGU_CTRL_IRQ_READY;
+ writel(val, base + IMGU_REG_SP_CTRL(0));
+ writel(val | IMGU_CTRL_IRQ_CLEAR, base + IMGU_REG_SP_CTRL(0));
+
+ /* Enable IRQs from the IMGU wrapper */
+ writel(IMGU_REG_INT_CSS_IRQ, base + IMGU_REG_INT_ENABLE);
+ /* Clear */
+ writel(IMGU_REG_INT_CSS_IRQ, base + IMGU_REG_INT_STATUS);
+
+ /* Enable IRQs from main IRQ controller */
+ writel(~0, base + IMGU_REG_IRQCTRL_EDGE_NOT_PULSE(IMGU_IRQCTRL_MAIN));
+ writel(0, base + IMGU_REG_IRQCTRL_MASK(IMGU_IRQCTRL_MAIN));
+ writel(IMGU_IRQCTRL_IRQ_MASK,
+ base + IMGU_REG_IRQCTRL_EDGE(IMGU_IRQCTRL_MAIN));
+ writel(IMGU_IRQCTRL_IRQ_MASK,
+ base + IMGU_REG_IRQCTRL_ENABLE(IMGU_IRQCTRL_MAIN));
+ writel(IMGU_IRQCTRL_IRQ_MASK,
+ base + IMGU_REG_IRQCTRL_CLEAR(IMGU_IRQCTRL_MAIN));
+ writel(IMGU_IRQCTRL_IRQ_MASK,
+ base + IMGU_REG_IRQCTRL_MASK(IMGU_IRQCTRL_MAIN));
+ /* Wait for write complete */
+ readl(base + IMGU_REG_IRQCTRL_ENABLE(IMGU_IRQCTRL_MAIN));
+
+ /* Enable IRQs from SP0 and SP1 controllers */
+ for (i = IMGU_IRQCTRL_SP0; i <= IMGU_IRQCTRL_SP1; i++) {
+ writel(~0, base + IMGU_REG_IRQCTRL_EDGE_NOT_PULSE(i));
+ writel(0, base + IMGU_REG_IRQCTRL_MASK(i));
+ writel(IMGU_IRQCTRL_IRQ_MASK, base + IMGU_REG_IRQCTRL_EDGE(i));
+ writel(IMGU_IRQCTRL_IRQ_MASK,
+ base + IMGU_REG_IRQCTRL_ENABLE(i));
+ writel(IMGU_IRQCTRL_IRQ_MASK, base + IMGU_REG_IRQCTRL_CLEAR(i));
+ writel(IMGU_IRQCTRL_IRQ_MASK, base + IMGU_REG_IRQCTRL_MASK(i));
+ /* Wait for write complete */
+ readl(base + IMGU_REG_IRQCTRL_ENABLE(i));
+ }
+}
+
+static int ipu3_css_hw_init(struct ipu3_css *css)
+{
+ /* For checking that streaming monitor statuses are valid */
+ static const struct {
+ u32 reg;
+ u32 mask;
+ const char *name;
+ } stream_monitors[] = {
+ {
+ IMGU_REG_GP_SP1_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_ISP_PORT_SP12ISP,
+ "ISP0 to SP0"
+ }, {
+ IMGU_REG_GP_ISP_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_SP1_PORT_ISP2SP1,
+ "SP0 to ISP0"
+ }, {
+ IMGU_REG_GP_MOD_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_MOD_PORT_ISP2DMA,
+ "ISP0 to DMA0"
+ }, {
+ IMGU_REG_GP_ISP_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_ISP_PORT_DMA2ISP,
+ "DMA0 to ISP0"
+ }, {
+ IMGU_REG_GP_MOD_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_MOD_PORT_CELLS2GDC,
+ "ISP0 to GDC0"
+ }, {
+ IMGU_REG_GP_MOD_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_MOD_PORT_GDC2CELLS,
+ "GDC0 to ISP0"
+ }, {
+ IMGU_REG_GP_MOD_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_MOD_PORT_SP12DMA,
+ "SP0 to DMA0"
+ }, {
+ IMGU_REG_GP_SP1_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_SP1_PORT_DMA2SP1,
+ "DMA0 to SP0"
+ }, {
+ IMGU_REG_GP_MOD_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_MOD_PORT_CELLS2GDC,
+ "SP0 to GDC0"
+ }, {
+ IMGU_REG_GP_MOD_STRMON_STAT,
+ IMGU_GP_STRMON_STAT_MOD_PORT_GDC2CELLS,
+ "GDC0 to SP0"
+ },
+ };
+
+ struct device *dev = css->dev;
+ void __iomem *const base = css->base;
+ u32 val, i;
+
+ /* Set instruction cache address and inv bit for ISP, SP, and SP1 */
+ for (i = 0; i < IMGU_NUM_SP; i++) {
+ struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css->fw_sp[i]];
+
+ writel(css->binary[css->fw_sp[i]].daddr,
+ base + IMGU_REG_SP_ICACHE_ADDR(bi->type));
+ writel(readl(base + IMGU_REG_SP_CTRL(bi->type)) |
+ IMGU_CTRL_ICACHE_INV,
+ base + IMGU_REG_SP_CTRL(bi->type));
+ }
+ writel(css->binary[css->fw_bl].daddr, base + IMGU_REG_ISP_ICACHE_ADDR);
+ writel(readl(base + IMGU_REG_ISP_CTRL) | IMGU_CTRL_ICACHE_INV,
+ base + IMGU_REG_ISP_CTRL);
+
+ /* Check that IMGU hardware is ready */
+
+ if (!(readl(base + IMGU_REG_SP_CTRL(0)) & IMGU_CTRL_IDLE)) {
+ dev_err(dev, "SP is not idle\n");
+ return -EIO;
+ }
+ if (!(readl(base + IMGU_REG_ISP_CTRL) & IMGU_CTRL_IDLE)) {
+ dev_err(dev, "ISP is not idle\n");
+ return -EIO;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(stream_monitors); i++) {
+ val = readl(base + stream_monitors[i].reg);
+ if (val & stream_monitors[i].mask) {
+ dev_err(dev, "error: Stream monitor %s is valid\n",
+ stream_monitors[i].name);
+ return -EIO;
+ }
+ }
+
+ /* Initialize GDC with default values */
+
+ for (i = 0; i < ARRAY_SIZE(ipu3_css_gdc_lut[0]); i++) {
+ u32 val0 = ipu3_css_gdc_lut[0][i] & IMGU_GDC_LUT_MASK;
+ u32 val1 = ipu3_css_gdc_lut[1][i] & IMGU_GDC_LUT_MASK;
+ u32 val2 = ipu3_css_gdc_lut[2][i] & IMGU_GDC_LUT_MASK;
+ u32 val3 = ipu3_css_gdc_lut[3][i] & IMGU_GDC_LUT_MASK;
+
+ writel(val0 | (val1 << 16),
+ base + IMGU_REG_GDC_LUT_BASE + i * 8);
+ writel(val2 | (val3 << 16),
+ base + IMGU_REG_GDC_LUT_BASE + i * 8 + 4);
+ }
+
+ return 0;
+}
+
+/* Boot the given IPU3 CSS SP */
+static int ipu3_css_hw_start_sp(struct ipu3_css *css, int sp)
+{
+ void __iomem *const base = css->base;
+ struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]];
+ struct imgu_abi_sp_init_dmem_cfg dmem_cfg = {
+ .ddr_data_addr = css->binary[css->fw_sp[sp]].daddr
+ + bi->blob.data_source,
+ .dmem_data_addr = bi->blob.data_target,
+ .dmem_bss_addr = bi->blob.bss_target,
+ .data_size = bi->blob.data_size,
+ .bss_size = bi->blob.bss_size,
+ .sp_id = sp,
+ };
+
+ writes(&dmem_cfg, sizeof(dmem_cfg), base +
+ IMGU_REG_SP_DMEM_BASE(sp) + bi->info.sp.init_dmem_data);
+
+ writel(bi->info.sp.sp_entry, base + IMGU_REG_SP_START_ADDR(sp));
+
+ writel(readl(base + IMGU_REG_SP_CTRL(sp))
+ | IMGU_CTRL_START | IMGU_CTRL_RUN, base + IMGU_REG_SP_CTRL(sp));
+
+ if (ipu3_hw_wait(css->base, IMGU_REG_SP_DMEM_BASE(sp)
+ + bi->info.sp.sw_state,
+ ~0, IMGU_ABI_SP_SWSTATE_INITIALIZED))
+ return -EIO;
+
+ return 0;
+}
+
+/* Start the IPU3 CSS ImgU (Imaging Unit) and all the SPs */
+static int ipu3_css_hw_start(struct ipu3_css *css)
+{
+ static const u32 event_mask =
+ ((1 << IMGU_ABI_EVTTYPE_OUT_FRAME_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_2ND_OUT_FRAME_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_2ND_VF_OUT_FRAME_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_3A_STATS_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_DIS_STATS_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_PIPELINE_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_FRAME_TAGGED) |
+ (1 << IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_METADATA_DONE) |
+ (1 << IMGU_ABI_EVTTYPE_ACC_STAGE_COMPLETE))
+ << IMGU_ABI_SP_COMM_EVENT_IRQ_MASK_OR_SHIFT;
+
+ void __iomem *const base = css->base;
+ struct imgu_fw_info *bi, *bl = &css->fwp->binary_header[css->fw_bl];
+ unsigned int i;
+
+ writel(IMGU_TLB_INVALIDATE, base + IMGU_REG_TLB_INVALIDATE);
+
+ /* Start bootloader */
+
+ writel(IMGU_ABI_BL_SWSTATE_BUSY,
+ base + IMGU_REG_ISP_DMEM_BASE + bl->info.bl.sw_state);
+ writel(IMGU_NUM_SP,
+ base + IMGU_REG_ISP_DMEM_BASE + bl->info.bl.num_dma_cmds);
+
+ for (i = 0; i < IMGU_NUM_SP; i++) {
+ int j = IMGU_NUM_SP - i - 1; /* load sp1 first, then sp0 */
+ struct imgu_fw_info *sp =
+ &css->fwp->binary_header[css->fw_sp[j]];
+ struct imgu_abi_bl_dma_cmd_entry dma_cmd = {
+ .src_addr = css->binary[css->fw_sp[j]].daddr
+ + sp->blob.text_source,
+ .size = sp->blob.text_size,
+ .dst_type = IMGU_ABI_BL_DMACMD_TYPE_SP_PMEM,
+ .dst_addr = IMGU_SP_PMEM_BASE(j),
+ };
+
+ writes(&dma_cmd, sizeof(dma_cmd),
+ base + IMGU_REG_ISP_DMEM_BASE + i * sizeof(dma_cmd) +
+ bl->info.bl.dma_cmd_list);
+ }
+
+ writel(bl->info.bl.bl_entry, base + IMGU_REG_ISP_START_ADDR);
+
+ writel(readl(base + IMGU_REG_ISP_CTRL)
+ | IMGU_CTRL_START | IMGU_CTRL_RUN, base + IMGU_REG_ISP_CTRL);
+ if (ipu3_hw_wait(css->base, IMGU_REG_ISP_DMEM_BASE
+ + bl->info.bl.sw_state, ~0,
+ IMGU_ABI_BL_SWSTATE_OK)) {
+ dev_err(css->dev, "failed to start bootloader\n");
+ return -EIO;
+ }
+
+ /* Start ISP */
+
+ memset(css->xmem_sp_group_ptrs.vaddr, 0,
+ sizeof(struct imgu_abi_sp_group));
+
+ bi = &css->fwp->binary_header[css->fw_sp[0]];
+
+ writel(css->xmem_sp_group_ptrs.daddr,
+ base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.per_frame_data);
+
+ writel(IMGU_ABI_SP_SWSTATE_TERMINATED,
+ base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.sw_state);
+ writel(1, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.invalidate_tlb);
+
+ if (ipu3_css_hw_start_sp(css, 0))
+ return -EIO;
+
+ writel(0, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.isp_started);
+ writel(0, base + IMGU_REG_SP_DMEM_BASE(0) +
+ bi->info.sp.host_sp_queues_initialized);
+ writel(0, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.sleep_mode);
+ writel(0, base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.invalidate_tlb);
+ writel(IMGU_ABI_SP_COMM_COMMAND_READY, base + IMGU_REG_SP_DMEM_BASE(0)
+ + bi->info.sp.host_sp_com + IMGU_ABI_SP_COMM_COMMAND);
+
+ /* Enable all events for all queues */
+
+ for (i = 0; i < IPU3_CSS_PIPE_ID_NUM; i++)
+ writel(event_mask, base + IMGU_REG_SP_DMEM_BASE(0)
+ + bi->info.sp.host_sp_com
+ + IMGU_ABI_SP_COMM_EVENT_IRQ_MASK(i));
+ writel(1, base + IMGU_REG_SP_DMEM_BASE(0) +
+ bi->info.sp.host_sp_queues_initialized);
+
+ /* Start SP1 */
+
+ bi = &css->fwp->binary_header[css->fw_sp[1]];
+
+ writel(IMGU_ABI_SP_SWSTATE_TERMINATED,
+ base + IMGU_REG_SP_DMEM_BASE(1) + bi->info.sp.sw_state);
+
+ if (ipu3_css_hw_start_sp(css, 1))
+ return -EIO;
+
+ writel(IMGU_ABI_SP_COMM_COMMAND_READY, base + IMGU_REG_SP_DMEM_BASE(1)
+ + bi->info.sp.host_sp_com + IMGU_ABI_SP_COMM_COMMAND);
+
+ return 0;
+}
+
+static void ipu3_css_hw_stop(struct ipu3_css *css)
+{
+ void __iomem *const base = css->base;
+ struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[0]];
+
+ /* Stop fw */
+ writel(IMGU_ABI_SP_COMM_COMMAND_TERMINATE,
+ base + IMGU_REG_SP_DMEM_BASE(0) +
+ bi->info.sp.host_sp_com + IMGU_ABI_SP_COMM_COMMAND);
+ if (ipu3_hw_wait(css->base, IMGU_REG_SP_CTRL(0),
+ IMGU_CTRL_IDLE, IMGU_CTRL_IDLE))
+ dev_err(css->dev, "wait sp0 idle timeout.\n");
+ if (readl(base + IMGU_REG_SP_DMEM_BASE(0) + bi->info.sp.sw_state) !=
+ IMGU_ABI_SP_SWSTATE_TERMINATED)
+ dev_err(css->dev, "sp0 is not terminated.\n");
+ if (ipu3_hw_wait(css->base, IMGU_REG_ISP_CTRL,
+ IMGU_CTRL_IDLE, IMGU_CTRL_IDLE))
+ dev_err(css->dev, "wait isp idle timeout\n");
+}
+
+static void ipu3_css_hw_cleanup(struct ipu3_css *css)
+{
+ void __iomem *const base = css->base;
+
+ /** Reset CSS **/
+
+ /* Clear the CSS busy signal */
+ readl(base + IMGU_REG_GP_BUSY);
+ writel(0, base + IMGU_REG_GP_BUSY);
+
+ /* Wait for idle signal */
+ if (ipu3_hw_wait(css->base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS,
+ IMGU_STATE_IDLE_STS))
+ dev_err(css->dev, "failed to shut down hw cleanly\n");
+
+ /* Reset the css */
+ writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_RESET,
+ base + IMGU_REG_PM_CTRL);
+
+ usleep_range(200, 300);
+}
+
+static void ipu3_css_pipeline_cleanup(struct ipu3_css *css, unsigned int pipe)
+{
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+ unsigned int i;
+
+ ipu3_css_pool_cleanup(imgu,
+ &css->pipes[pipe].pool.parameter_set_info);
+ ipu3_css_pool_cleanup(imgu, &css->pipes[pipe].pool.acc);
+ ipu3_css_pool_cleanup(imgu, &css->pipes[pipe].pool.gdc);
+ ipu3_css_pool_cleanup(imgu, &css->pipes[pipe].pool.obgrid);
+
+ for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++)
+ ipu3_css_pool_cleanup(imgu,
+ &css->pipes[pipe].pool.binary_params_p[i]);
+}
+
+/*
+ * This function initializes various stages of the
+ * IPU3 CSS ISP pipeline
+ */
+static int ipu3_css_pipeline_init(struct ipu3_css *css, unsigned int pipe)
+{
+ static const int BYPC = 2; /* Bytes per component */
+ static const struct imgu_abi_buffer_sp buffer_sp_init = {
+ .buf_src = {.queue_id = IMGU_ABI_QUEUE_EVENT_ID},
+ .buf_type = IMGU_ABI_BUFFER_TYPE_INVALID,
+ };
+
+ struct imgu_abi_isp_iterator_config *cfg_iter;
+ struct imgu_abi_isp_ref_config *cfg_ref;
+ struct imgu_abi_isp_dvs_config *cfg_dvs;
+ struct imgu_abi_isp_tnr3_config *cfg_tnr;
+ struct imgu_abi_isp_ref_dmem_state *cfg_ref_state;
+ struct imgu_abi_isp_tnr3_dmem_state *cfg_tnr_state;
+
+ const int stage = 0;
+ unsigned int i, j;
+
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ const struct imgu_fw_info *bi =
+ &css->fwp->binary_header[css_pipe->bindex];
+ const unsigned int stripes = bi->info.isp.sp.iterator.num_stripes;
+
+ struct imgu_fw_config_memory_offsets *cofs = (void *)css->fwp +
+ bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_CONFIG];
+ struct imgu_fw_state_memory_offsets *sofs = (void *)css->fwp +
+ bi->blob.memory_offsets.offsets[IMGU_ABI_PARAM_CLASS_STATE];
+
+ struct imgu_abi_isp_stage *isp_stage;
+ struct imgu_abi_sp_stage *sp_stage;
+ struct imgu_abi_sp_group *sp_group;
+
+ const unsigned int bds_width_pad =
+ ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width,
+ 2 * IPU3_UAPI_ISP_VEC_ELEMS);
+
+ const enum imgu_abi_memories m0 = IMGU_ABI_MEM_ISP_DMEM0;
+ enum imgu_abi_param_class cfg = IMGU_ABI_PARAM_CLASS_CONFIG;
+ void *vaddr = css_pipe->binary_params_cs[cfg - 1][m0].vaddr;
+
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+
+ dev_dbg(css->dev, "%s for pipe %d", __func__, pipe);
+
+ /* Configure iterator */
+
+ cfg_iter = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0,
+ &cofs->dmem.iterator,
+ sizeof(*cfg_iter), vaddr);
+ if (!cfg_iter)
+ goto bad_firmware;
+
+ cfg_iter->input_info.res.width =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].fmt.mpix.width;
+ cfg_iter->input_info.res.height =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].fmt.mpix.height;
+ cfg_iter->input_info.padded_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].width_pad;
+ cfg_iter->input_info.format =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->frame_format;
+ cfg_iter->input_info.raw_bit_depth =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bit_depth;
+ cfg_iter->input_info.raw_bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bayer_order;
+ cfg_iter->input_info.raw_type = IMGU_ABI_RAW_TYPE_BAYER;
+
+ cfg_iter->internal_info.res.width = css_pipe->rect[IPU3_CSS_RECT_BDS].width;
+ cfg_iter->internal_info.res.height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ cfg_iter->internal_info.padded_width = bds_width_pad;
+ cfg_iter->internal_info.format =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->frame_format;
+ cfg_iter->internal_info.raw_bit_depth =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->bit_depth;
+ cfg_iter->internal_info.raw_bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->bayer_order;
+ cfg_iter->internal_info.raw_type = IMGU_ABI_RAW_TYPE_BAYER;
+
+ cfg_iter->output_info.res.width =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.width;
+ cfg_iter->output_info.res.height =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.height;
+ cfg_iter->output_info.padded_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].width_pad;
+ cfg_iter->output_info.format =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->frame_format;
+ cfg_iter->output_info.raw_bit_depth =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->bit_depth;
+ cfg_iter->output_info.raw_bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->bayer_order;
+ cfg_iter->output_info.raw_type = IMGU_ABI_RAW_TYPE_BAYER;
+
+ cfg_iter->vf_info.res.width =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.width;
+ cfg_iter->vf_info.res.height =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.height;
+ cfg_iter->vf_info.padded_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].width_pad;
+ cfg_iter->vf_info.format =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].css_fmt->frame_format;
+ cfg_iter->vf_info.raw_bit_depth =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].css_fmt->bit_depth;
+ cfg_iter->vf_info.raw_bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].css_fmt->bayer_order;
+ cfg_iter->vf_info.raw_type = IMGU_ABI_RAW_TYPE_BAYER;
+
+ cfg_iter->dvs_envelope.width = css_pipe->rect[IPU3_CSS_RECT_ENVELOPE].width;
+ cfg_iter->dvs_envelope.height =
+ css_pipe->rect[IPU3_CSS_RECT_ENVELOPE].height;
+
+ /* Configure reference (delay) frames */
+
+ cfg_ref = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0,
+ &cofs->dmem.ref,
+ sizeof(*cfg_ref), vaddr);
+ if (!cfg_ref)
+ goto bad_firmware;
+
+ cfg_ref->port_b.crop = 0;
+ cfg_ref->port_b.elems = IMGU_ABI_ISP_DDR_WORD_BYTES / BYPC;
+ cfg_ref->port_b.width =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].width;
+ cfg_ref->port_b.stride =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperline;
+ cfg_ref->width_a_over_b =
+ IPU3_UAPI_ISP_VEC_ELEMS / cfg_ref->port_b.elems;
+ cfg_ref->dvs_frame_delay = IPU3_CSS_AUX_FRAMES - 1;
+ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++) {
+ cfg_ref->ref_frame_addr_y[i] =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].mem[i].daddr;
+ cfg_ref->ref_frame_addr_c[i] =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].mem[i].daddr +
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperline *
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].height;
+ }
+ for (; i < IMGU_ABI_FRAMES_REF; i++) {
+ cfg_ref->ref_frame_addr_y[i] = 0;
+ cfg_ref->ref_frame_addr_c[i] = 0;
+ }
+
+ /* Configure DVS (digital video stabilization) */
+
+ cfg_dvs = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0,
+ &cofs->dmem.dvs, sizeof(*cfg_dvs),
+ vaddr);
+ if (!cfg_dvs)
+ goto bad_firmware;
+
+ cfg_dvs->num_horizontal_blocks =
+ ALIGN(DIV_ROUND_UP(css_pipe->rect[IPU3_CSS_RECT_GDC].width,
+ IMGU_DVS_BLOCK_W), 2);
+ cfg_dvs->num_vertical_blocks =
+ DIV_ROUND_UP(css_pipe->rect[IPU3_CSS_RECT_GDC].height,
+ IMGU_DVS_BLOCK_H);
+
+ /* Configure TNR (temporal noise reduction) */
+
+ if (css_pipe->pipe_id == IPU3_CSS_PIPE_ID_VIDEO) {
+ cfg_tnr = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0,
+ &cofs->dmem.tnr3,
+ sizeof(*cfg_tnr),
+ vaddr);
+ if (!cfg_tnr)
+ goto bad_firmware;
+
+ cfg_tnr->port_b.crop = 0;
+ cfg_tnr->port_b.elems = IMGU_ABI_ISP_DDR_WORD_BYTES;
+ cfg_tnr->port_b.width =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].width;
+ cfg_tnr->port_b.stride =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].bytesperline;
+ cfg_tnr->width_a_over_b =
+ IPU3_UAPI_ISP_VEC_ELEMS / cfg_tnr->port_b.elems;
+ cfg_tnr->frame_height =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].height;
+ cfg_tnr->delay_frame = IPU3_CSS_AUX_FRAMES - 1;
+ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
+ cfg_tnr->frame_addr[i] =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR]
+ .mem[i].daddr;
+ for (; i < IMGU_ABI_FRAMES_TNR; i++)
+ cfg_tnr->frame_addr[i] = 0;
+ }
+
+ /* Configure ref dmem state parameters */
+
+ cfg = IMGU_ABI_PARAM_CLASS_STATE;
+ vaddr = css_pipe->binary_params_cs[cfg - 1][m0].vaddr;
+
+ cfg_ref_state = ipu3_css_fw_pipeline_params(css, pipe, cfg, m0,
+ &sofs->dmem.ref,
+ sizeof(*cfg_ref_state),
+ vaddr);
+ if (!cfg_ref_state)
+ goto bad_firmware;
+
+ cfg_ref_state->ref_in_buf_idx = 0;
+ cfg_ref_state->ref_out_buf_idx = 1;
+
+ /* Configure tnr dmem state parameters */
+ if (css_pipe->pipe_id == IPU3_CSS_PIPE_ID_VIDEO) {
+ cfg_tnr_state =
+ ipu3_css_fw_pipeline_params(css, pipe, cfg, m0,
+ &sofs->dmem.tnr3,
+ sizeof(*cfg_tnr_state),
+ vaddr);
+ if (!cfg_tnr_state)
+ goto bad_firmware;
+
+ cfg_tnr_state->in_bufidx = 0;
+ cfg_tnr_state->out_bufidx = 1;
+ cfg_tnr_state->bypass_filter = 0;
+ cfg_tnr_state->total_frame_counter = 0;
+ for (i = 0; i < IMGU_ABI_BUF_SETS_TNR; i++)
+ cfg_tnr_state->buffer_frame_counter[i] = 0;
+ }
+
+ /* Configure ISP stage */
+
+ isp_stage = css_pipe->xmem_isp_stage_ptrs[pipe][stage].vaddr;
+ memset(isp_stage, 0, sizeof(*isp_stage));
+ isp_stage->blob_info = bi->blob;
+ isp_stage->binary_info = bi->info.isp.sp;
+ strscpy(isp_stage->binary_name,
+ (char *)css->fwp + bi->blob.prog_name_offset,
+ sizeof(isp_stage->binary_name));
+ isp_stage->mem_initializers = bi->info.isp.sp.mem_initializers;
+ for (i = IMGU_ABI_PARAM_CLASS_CONFIG; i < IMGU_ABI_PARAM_CLASS_NUM; i++)
+ for (j = 0; j < IMGU_ABI_NUM_MEMORIES; j++)
+ isp_stage->mem_initializers.params[i][j].address =
+ css_pipe->binary_params_cs[i - 1][j].daddr;
+
+ /* Configure SP stage */
+
+ sp_stage = css_pipe->xmem_sp_stage_ptrs[pipe][stage].vaddr;
+ memset(sp_stage, 0, sizeof(*sp_stage));
+
+ sp_stage->frames.in.buf_attr = buffer_sp_init;
+ for (i = 0; i < IMGU_ABI_BINARY_MAX_OUTPUT_PORTS; i++)
+ sp_stage->frames.out[i].buf_attr = buffer_sp_init;
+ sp_stage->frames.out_vf.buf_attr = buffer_sp_init;
+ sp_stage->frames.s3a_buf = buffer_sp_init;
+ sp_stage->frames.dvs_buf = buffer_sp_init;
+
+ sp_stage->stage_type = IMGU_ABI_STAGE_TYPE_ISP;
+ sp_stage->num = stage;
+ sp_stage->isp_online = 0;
+ sp_stage->isp_copy_vf = 0;
+ sp_stage->isp_copy_output = 0;
+
+ sp_stage->enable.vf_output = css_pipe->vf_output_en;
+
+ sp_stage->frames.effective_in_res.width =
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].width;
+ sp_stage->frames.effective_in_res.height =
+ css_pipe->rect[IPU3_CSS_RECT_EFFECTIVE].height;
+ sp_stage->frames.in.info.res.width =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].fmt.mpix.width;
+ sp_stage->frames.in.info.res.height =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].fmt.mpix.height;
+ sp_stage->frames.in.info.padded_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].width_pad;
+ sp_stage->frames.in.info.format =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->frame_format;
+ sp_stage->frames.in.info.raw_bit_depth =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bit_depth;
+ sp_stage->frames.in.info.raw_bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_IN].css_fmt->bayer_order;
+ sp_stage->frames.in.info.raw_type = IMGU_ABI_RAW_TYPE_BAYER;
+ sp_stage->frames.in.buf_attr.buf_src.queue_id = IMGU_ABI_QUEUE_C_ID;
+ sp_stage->frames.in.buf_attr.buf_type =
+ IMGU_ABI_BUFFER_TYPE_INPUT_FRAME;
+
+ sp_stage->frames.out[0].info.res.width =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.width;
+ sp_stage->frames.out[0].info.res.height =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.height;
+ sp_stage->frames.out[0].info.padded_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].width_pad;
+ sp_stage->frames.out[0].info.format =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->frame_format;
+ sp_stage->frames.out[0].info.raw_bit_depth =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->bit_depth;
+ sp_stage->frames.out[0].info.raw_bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->bayer_order;
+ sp_stage->frames.out[0].info.raw_type = IMGU_ABI_RAW_TYPE_BAYER;
+ sp_stage->frames.out[0].planes.nv.uv.offset =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].width_pad *
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].fmt.mpix.height;
+ sp_stage->frames.out[0].buf_attr.buf_src.queue_id = IMGU_ABI_QUEUE_D_ID;
+ sp_stage->frames.out[0].buf_attr.buf_type =
+ IMGU_ABI_BUFFER_TYPE_OUTPUT_FRAME;
+
+ sp_stage->frames.out[1].buf_attr.buf_src.queue_id =
+ IMGU_ABI_QUEUE_EVENT_ID;
+
+ sp_stage->frames.internal_frame_info.res.width =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].width;
+ sp_stage->frames.internal_frame_info.res.height =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].height;
+ sp_stage->frames.internal_frame_info.padded_width = bds_width_pad;
+
+ sp_stage->frames.internal_frame_info.format =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->frame_format;
+ sp_stage->frames.internal_frame_info.raw_bit_depth =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->bit_depth;
+ sp_stage->frames.internal_frame_info.raw_bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].css_fmt->bayer_order;
+ sp_stage->frames.internal_frame_info.raw_type = IMGU_ABI_RAW_TYPE_BAYER;
+
+ sp_stage->frames.out_vf.info.res.width =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.width;
+ sp_stage->frames.out_vf.info.res.height =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.height;
+ sp_stage->frames.out_vf.info.padded_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].width_pad;
+ sp_stage->frames.out_vf.info.format =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].css_fmt->frame_format;
+ sp_stage->frames.out_vf.info.raw_bit_depth =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].css_fmt->bit_depth;
+ sp_stage->frames.out_vf.info.raw_bayer_order =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].css_fmt->bayer_order;
+ sp_stage->frames.out_vf.info.raw_type = IMGU_ABI_RAW_TYPE_BAYER;
+ sp_stage->frames.out_vf.planes.yuv.u.offset =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].width_pad *
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.height;
+ sp_stage->frames.out_vf.planes.yuv.v.offset =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].width_pad *
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].fmt.mpix.height * 5 / 4;
+ sp_stage->frames.out_vf.buf_attr.buf_src.queue_id = IMGU_ABI_QUEUE_E_ID;
+ sp_stage->frames.out_vf.buf_attr.buf_type =
+ IMGU_ABI_BUFFER_TYPE_VF_OUTPUT_FRAME;
+
+ sp_stage->frames.s3a_buf.buf_src.queue_id = IMGU_ABI_QUEUE_F_ID;
+ sp_stage->frames.s3a_buf.buf_type = IMGU_ABI_BUFFER_TYPE_3A_STATISTICS;
+
+ sp_stage->frames.dvs_buf.buf_src.queue_id = IMGU_ABI_QUEUE_G_ID;
+ sp_stage->frames.dvs_buf.buf_type = IMGU_ABI_BUFFER_TYPE_DIS_STATISTICS;
+
+ sp_stage->dvs_envelope.width = css_pipe->rect[IPU3_CSS_RECT_ENVELOPE].width;
+ sp_stage->dvs_envelope.height =
+ css_pipe->rect[IPU3_CSS_RECT_ENVELOPE].height;
+
+ sp_stage->isp_pipe_version =
+ bi->info.isp.sp.pipeline.isp_pipe_version;
+ sp_stage->isp_deci_log_factor =
+ clamp(max(fls(css_pipe->rect[IPU3_CSS_RECT_BDS].width /
+ IMGU_MAX_BQ_GRID_WIDTH),
+ fls(css_pipe->rect[IPU3_CSS_RECT_BDS].height /
+ IMGU_MAX_BQ_GRID_HEIGHT)) - 1, 3, 5);
+ sp_stage->isp_vf_downscale_bits = 0;
+ sp_stage->if_config_index = 255;
+ sp_stage->sp_enable_xnr = 0;
+ sp_stage->num_stripes = stripes;
+ sp_stage->enable.s3a = 1;
+ sp_stage->enable.dvs_stats = 0;
+
+ sp_stage->xmem_bin_addr = css->binary[css_pipe->bindex].daddr;
+ sp_stage->xmem_map_addr = css_pipe->sp_ddr_ptrs.daddr;
+ sp_stage->isp_stage_addr =
+ css_pipe->xmem_isp_stage_ptrs[pipe][stage].daddr;
+
+ /* Configure SP group */
+
+ sp_group = css->xmem_sp_group_ptrs.vaddr;
+ memset(&sp_group->pipe[pipe], 0, sizeof(struct imgu_abi_sp_pipeline));
+
+ sp_group->pipe[pipe].num_stages = 1;
+ sp_group->pipe[pipe].pipe_id = css_pipe->pipe_id;
+ sp_group->pipe[pipe].thread_id = pipe;
+ sp_group->pipe[pipe].pipe_num = pipe;
+ sp_group->pipe[pipe].num_execs = -1;
+ sp_group->pipe[pipe].pipe_qos_config = -1;
+ sp_group->pipe[pipe].required_bds_factor = 0;
+ sp_group->pipe[pipe].dvs_frame_delay = IPU3_CSS_AUX_FRAMES - 1;
+ sp_group->pipe[pipe].inout_port_config =
+ IMGU_ABI_PORT_CONFIG_TYPE_INPUT_HOST |
+ IMGU_ABI_PORT_CONFIG_TYPE_OUTPUT_HOST;
+ sp_group->pipe[pipe].scaler_pp_lut = 0;
+ sp_group->pipe[pipe].shading.internal_frame_origin_x_bqs_on_sctbl = 0;
+ sp_group->pipe[pipe].shading.internal_frame_origin_y_bqs_on_sctbl = 0;
+ sp_group->pipe[pipe].sp_stage_addr[stage] =
+ css_pipe->xmem_sp_stage_ptrs[pipe][stage].daddr;
+ sp_group->pipe[pipe].pipe_config =
+ bi->info.isp.sp.enable.params ? (1 << pipe) : 0;
+ sp_group->pipe[pipe].pipe_config |= IMGU_ABI_PIPE_CONFIG_ACQUIRE_ISP;
+
+ /* Initialize parameter pools */
+
+ if (ipu3_css_pool_init(imgu, &css_pipe->pool.parameter_set_info,
+ sizeof(struct imgu_abi_parameter_set_info)) ||
+ ipu3_css_pool_init(imgu, &css_pipe->pool.acc,
+ sizeof(struct imgu_abi_acc_param)) ||
+ ipu3_css_pool_init(imgu, &css_pipe->pool.gdc,
+ sizeof(struct imgu_abi_gdc_warp_param) *
+ 3 * cfg_dvs->num_horizontal_blocks / 2 *
+ cfg_dvs->num_vertical_blocks) ||
+ ipu3_css_pool_init(imgu, &css_pipe->pool.obgrid,
+ ipu3_css_fw_obgrid_size(
+ &css->fwp->binary_header[css_pipe->bindex])))
+ goto out_of_memory;
+
+ for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++)
+ if (ipu3_css_pool_init(imgu,
+ &css_pipe->pool.binary_params_p[i],
+ bi->info.isp.sp.mem_initializers.params
+ [IMGU_ABI_PARAM_CLASS_PARAM][i].size))
+ goto out_of_memory;
+
+ return 0;
+
+bad_firmware:
+ ipu3_css_pipeline_cleanup(css, pipe);
+ return -EPROTO;
+
+out_of_memory:
+ ipu3_css_pipeline_cleanup(css, pipe);
+ return -ENOMEM;
+}
+
+static u8 ipu3_css_queue_pos(struct ipu3_css *css, int queue, int thread)
+{
+ static const unsigned int sp;
+ void __iomem *const base = css->base;
+ struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]];
+ struct imgu_abi_queues __iomem *q = base + IMGU_REG_SP_DMEM_BASE(sp) +
+ bi->info.sp.host_sp_queue;
+
+ return queue >= 0 ? readb(&q->host2sp_bufq_info[thread][queue].end) :
+ readb(&q->host2sp_evtq_info.end);
+}
+
+/* Sent data to sp using given buffer queue, or if queue < 0, event queue. */
+static int ipu3_css_queue_data(struct ipu3_css *css,
+ int queue, int thread, u32 data)
+{
+ static const unsigned int sp;
+ void __iomem *const base = css->base;
+ struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]];
+ struct imgu_abi_queues __iomem *q = base + IMGU_REG_SP_DMEM_BASE(sp) +
+ bi->info.sp.host_sp_queue;
+ u8 size, start, end, end2;
+
+ if (queue >= 0) {
+ size = readb(&q->host2sp_bufq_info[thread][queue].size);
+ start = readb(&q->host2sp_bufq_info[thread][queue].start);
+ end = readb(&q->host2sp_bufq_info[thread][queue].end);
+ } else {
+ size = readb(&q->host2sp_evtq_info.size);
+ start = readb(&q->host2sp_evtq_info.start);
+ end = readb(&q->host2sp_evtq_info.end);
+ }
+
+ if (size == 0)
+ return -EIO;
+
+ end2 = (end + 1) % size;
+ if (end2 == start)
+ return -EBUSY; /* Queue full */
+
+ if (queue >= 0) {
+ writel(data, &q->host2sp_bufq[thread][queue][end]);
+ writeb(end2, &q->host2sp_bufq_info[thread][queue].end);
+ } else {
+ writel(data, &q->host2sp_evtq[end]);
+ writeb(end2, &q->host2sp_evtq_info.end);
+ }
+
+ return 0;
+}
+
+/* Receive data using given buffer queue, or if queue < 0, event queue. */
+static int ipu3_css_dequeue_data(struct ipu3_css *css, int queue, u32 *data)
+{
+ static const unsigned int sp;
+ void __iomem *const base = css->base;
+ struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[sp]];
+ struct imgu_abi_queues __iomem *q = base + IMGU_REG_SP_DMEM_BASE(sp) +
+ bi->info.sp.host_sp_queue;
+ u8 size, start, end, start2;
+
+ if (queue >= 0) {
+ size = readb(&q->sp2host_bufq_info[queue].size);
+ start = readb(&q->sp2host_bufq_info[queue].start);
+ end = readb(&q->sp2host_bufq_info[queue].end);
+ } else {
+ size = readb(&q->sp2host_evtq_info.size);
+ start = readb(&q->sp2host_evtq_info.start);
+ end = readb(&q->sp2host_evtq_info.end);
+ }
+
+ if (size == 0)
+ return -EIO;
+
+ if (end == start)
+ return -EBUSY; /* Queue empty */
+
+ start2 = (start + 1) % size;
+
+ if (queue >= 0) {
+ *data = readl(&q->sp2host_bufq[queue][start]);
+ writeb(start2, &q->sp2host_bufq_info[queue].start);
+ } else {
+ int r;
+
+ *data = readl(&q->sp2host_evtq[start]);
+ writeb(start2, &q->sp2host_evtq_info.start);
+
+ /* Acknowledge events dequeued from event queue */
+ r = ipu3_css_queue_data(css, queue, 0,
+ IMGU_ABI_EVENT_EVENT_DEQUEUED);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+/* Free binary-specific resources */
+static void ipu3_css_binary_cleanup(struct ipu3_css *css, unsigned int pipe)
+{
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+ unsigned int i, j;
+
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ for (j = 0; j < IMGU_ABI_PARAM_CLASS_NUM - 1; j++)
+ for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++)
+ ipu3_dmamap_free(imgu,
+ &css_pipe->binary_params_cs[j][i]);
+
+ j = IPU3_CSS_AUX_FRAME_REF;
+ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
+ ipu3_dmamap_free(imgu,
+ &css_pipe->aux_frames[j].mem[i]);
+
+ j = IPU3_CSS_AUX_FRAME_TNR;
+ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
+ ipu3_dmamap_free(imgu,
+ &css_pipe->aux_frames[j].mem[i]);
+}
+
+static int ipu3_css_binary_preallocate(struct ipu3_css *css, unsigned int pipe)
+{
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+ unsigned int i, j;
+
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ for (j = IMGU_ABI_PARAM_CLASS_CONFIG;
+ j < IMGU_ABI_PARAM_CLASS_NUM; j++)
+ for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++)
+ if (!ipu3_dmamap_alloc(imgu,
+ &css_pipe->binary_params_cs[j - 1][i],
+ CSS_ABI_SIZE))
+ goto out_of_memory;
+
+ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
+ if (!ipu3_dmamap_alloc(imgu,
+ &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].
+ mem[i], CSS_BDS_SIZE))
+ goto out_of_memory;
+
+ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
+ if (!ipu3_dmamap_alloc(imgu,
+ &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].
+ mem[i], CSS_GDC_SIZE))
+ goto out_of_memory;
+
+ return 0;
+
+out_of_memory:
+ ipu3_css_binary_cleanup(css, pipe);
+ return -ENOMEM;
+}
+
+/* allocate binary-specific resources */
+static int ipu3_css_binary_setup(struct ipu3_css *css, unsigned int pipe)
+{
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ struct imgu_fw_info *bi = &css->fwp->binary_header[css_pipe->bindex];
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+ int i, j, size;
+ static const int BYPC = 2; /* Bytes per component */
+ unsigned int w, h;
+
+ /* Allocate parameter memory blocks for this binary */
+
+ for (j = IMGU_ABI_PARAM_CLASS_CONFIG; j < IMGU_ABI_PARAM_CLASS_NUM; j++)
+ for (i = 0; i < IMGU_ABI_NUM_MEMORIES; i++) {
+ if (ipu3_css_dma_buffer_resize(
+ imgu,
+ &css_pipe->binary_params_cs[j - 1][i],
+ bi->info.isp.sp.mem_initializers.params[j][i].size))
+ goto out_of_memory;
+ }
+
+ /* Allocate internal frame buffers */
+
+ /* Reference frames for DVS, FRAME_FORMAT_YUV420_16 */
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperpixel = BYPC;
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].width =
+ css_pipe->rect[IPU3_CSS_RECT_BDS].width;
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].height =
+ ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].height,
+ IMGU_DVS_BLOCK_H) + 2 * IMGU_GDC_BUF_Y;
+ h = css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].height;
+ w = ALIGN(css_pipe->rect[IPU3_CSS_RECT_BDS].width,
+ 2 * IPU3_UAPI_ISP_VEC_ELEMS) + 2 * IMGU_GDC_BUF_X;
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperline =
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].bytesperpixel * w;
+ size = w * h * BYPC + (w / 2) * (h / 2) * BYPC * 2;
+ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
+ if (ipu3_css_dma_buffer_resize(
+ imgu,
+ &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_REF].mem[i],
+ size))
+ goto out_of_memory;
+
+ /* TNR frames for temporal noise reduction, FRAME_FORMAT_YUV_LINE */
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].bytesperpixel = 1;
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].width =
+ roundup(css_pipe->rect[IPU3_CSS_RECT_GDC].width,
+ bi->info.isp.sp.block.block_width *
+ IPU3_UAPI_ISP_VEC_ELEMS);
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].height =
+ roundup(css_pipe->rect[IPU3_CSS_RECT_GDC].height,
+ bi->info.isp.sp.block.output_block_height);
+
+ w = css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].width;
+ css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].bytesperline = w;
+ h = css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].height;
+ size = w * ALIGN(h * 3 / 2 + 3, 2); /* +3 for vf_pp prefetch */
+ for (i = 0; i < IPU3_CSS_AUX_FRAMES; i++)
+ if (ipu3_css_dma_buffer_resize(
+ imgu,
+ &css_pipe->aux_frames[IPU3_CSS_AUX_FRAME_TNR].mem[i],
+ size))
+ goto out_of_memory;
+
+ return 0;
+
+out_of_memory:
+ ipu3_css_binary_cleanup(css, pipe);
+ return -ENOMEM;
+}
+
+int ipu3_css_start_streaming(struct ipu3_css *css)
+{
+ u32 data;
+ int r, pipe;
+
+ if (css->streaming)
+ return -EPROTO;
+
+ for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
+ r = ipu3_css_binary_setup(css, pipe);
+ if (r < 0)
+ return r;
+ }
+
+ r = ipu3_css_hw_init(css);
+ if (r < 0)
+ return r;
+
+ r = ipu3_css_hw_start(css);
+ if (r < 0)
+ goto fail;
+
+ for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
+ r = ipu3_css_pipeline_init(css, pipe);
+ if (r < 0)
+ goto fail;
+ }
+
+ css->streaming = true;
+
+ ipu3_css_hw_enable_irq(css);
+
+ /* Initialize parameters to default */
+ for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
+ r = ipu3_css_set_parameters(css, pipe, NULL);
+ if (r < 0)
+ goto fail;
+ }
+
+ while (!(r = ipu3_css_dequeue_data(css, IMGU_ABI_QUEUE_A_ID, &data)))
+ ;
+ if (r != -EBUSY)
+ goto fail;
+
+ while (!(r = ipu3_css_dequeue_data(css, IMGU_ABI_QUEUE_B_ID, &data)))
+ ;
+ if (r != -EBUSY)
+ goto fail;
+
+ for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
+ r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
+ IMGU_ABI_EVENT_START_STREAM |
+ pipe << 16);
+ if (r < 0)
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ css->streaming = false;
+ ipu3_css_hw_cleanup(css);
+ for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
+ ipu3_css_pipeline_cleanup(css, pipe);
+ ipu3_css_binary_cleanup(css, pipe);
+ }
+
+ return r;
+}
+
+void ipu3_css_stop_streaming(struct ipu3_css *css)
+{
+ struct ipu3_css_buffer *b, *b0;
+ int q, r, pipe;
+
+ for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
+ r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
+ IMGU_ABI_EVENT_STOP_STREAM);
+ if (r < 0)
+ dev_warn(css->dev, "failed on stop stream event\n");
+ }
+
+ if (!css->streaming)
+ return;
+
+ ipu3_css_hw_stop(css);
+
+ ipu3_css_hw_cleanup(css);
+
+ for_each_set_bit(pipe, css->enabled_pipes, IMGU_MAX_PIPE_NUM) {
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ ipu3_css_pipeline_cleanup(css, pipe);
+
+ spin_lock(&css_pipe->qlock);
+ for (q = 0; q < IPU3_CSS_QUEUES; q++)
+ list_for_each_entry_safe(b, b0,
+ &css_pipe->queue[q].bufs,
+ list) {
+ b->state = IPU3_CSS_BUFFER_FAILED;
+ list_del(&b->list);
+ }
+ spin_unlock(&css_pipe->qlock);
+ }
+
+ css->streaming = false;
+}
+
+bool ipu3_css_pipe_queue_empty(struct ipu3_css *css, unsigned int pipe)
+{
+ int q;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ spin_lock(&css_pipe->qlock);
+ for (q = 0; q < IPU3_CSS_QUEUES; q++)
+ if (!list_empty(&css_pipe->queue[q].bufs))
+ break;
+ spin_unlock(&css_pipe->qlock);
+ return (q == IPU3_CSS_QUEUES);
+}
+
+bool ipu3_css_queue_empty(struct ipu3_css *css)
+{
+ unsigned int pipe;
+ bool ret = 0;
+
+ for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++)
+ ret &= ipu3_css_pipe_queue_empty(css, pipe);
+
+ return ret;
+}
+
+bool ipu3_css_is_streaming(struct ipu3_css *css)
+{
+ return css->streaming;
+}
+
+static int ipu3_css_map_init(struct ipu3_css *css, unsigned int pipe)
+{
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ unsigned int p, q, i;
+
+ /* Allocate and map common structures with imgu hardware */
+ for (p = 0; p < IPU3_CSS_PIPE_ID_NUM; p++)
+ for (i = 0; i < IMGU_ABI_MAX_STAGES; i++) {
+ if (!ipu3_dmamap_alloc(imgu,
+ &css_pipe->
+ xmem_sp_stage_ptrs[p][i],
+ sizeof(struct imgu_abi_sp_stage)))
+ return -ENOMEM;
+ if (!ipu3_dmamap_alloc(imgu,
+ &css_pipe->
+ xmem_isp_stage_ptrs[p][i],
+ sizeof(struct imgu_abi_isp_stage)))
+ return -ENOMEM;
+ }
+
+ if (!ipu3_dmamap_alloc(imgu, &css_pipe->sp_ddr_ptrs,
+ ALIGN(sizeof(struct imgu_abi_ddr_address_map),
+ IMGU_ABI_ISP_DDR_WORD_BYTES)))
+ return -ENOMEM;
+
+ for (q = 0; q < IPU3_CSS_QUEUES; q++) {
+ unsigned int abi_buf_num = ARRAY_SIZE(css_pipe->abi_buffers[q]);
+
+ for (i = 0; i < abi_buf_num; i++)
+ if (!ipu3_dmamap_alloc(imgu,
+ &css_pipe->abi_buffers[q][i],
+ sizeof(struct imgu_abi_buffer)))
+ return -ENOMEM;
+ }
+
+ if (ipu3_css_binary_preallocate(css, pipe)) {
+ ipu3_css_binary_cleanup(css, pipe);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void ipu3_css_pipe_cleanup(struct ipu3_css *css, unsigned int pipe)
+{
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ unsigned int p, q, i, abi_buf_num;
+
+ ipu3_css_binary_cleanup(css, pipe);
+
+ for (q = 0; q < IPU3_CSS_QUEUES; q++) {
+ abi_buf_num = ARRAY_SIZE(css_pipe->abi_buffers[q]);
+ for (i = 0; i < abi_buf_num; i++)
+ ipu3_dmamap_free(imgu, &css_pipe->abi_buffers[q][i]);
+ }
+
+ for (p = 0; p < IPU3_CSS_PIPE_ID_NUM; p++)
+ for (i = 0; i < IMGU_ABI_MAX_STAGES; i++) {
+ ipu3_dmamap_free(imgu,
+ &css_pipe->xmem_sp_stage_ptrs[p][i]);
+ ipu3_dmamap_free(imgu,
+ &css_pipe->xmem_isp_stage_ptrs[p][i]);
+ }
+
+ ipu3_dmamap_free(imgu, &css_pipe->sp_ddr_ptrs);
+}
+
+void ipu3_css_cleanup(struct ipu3_css *css)
+{
+ struct imgu_device *imgu = dev_get_drvdata(css->dev);
+ unsigned int pipe;
+
+ ipu3_css_stop_streaming(css);
+ for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++)
+ ipu3_css_pipe_cleanup(css, pipe);
+ ipu3_dmamap_free(imgu, &css->xmem_sp_group_ptrs);
+ ipu3_css_fw_cleanup(css);
+}
+
+int ipu3_css_init(struct device *dev, struct ipu3_css *css,
+ void __iomem *base, int length)
+{
+ struct imgu_device *imgu = dev_get_drvdata(dev);
+ int r, q, pipe;
+
+ /* Initialize main data structure */
+ css->dev = dev;
+ css->base = base;
+ css->iomem_length = length;
+
+ for (pipe = 0; pipe < IMGU_MAX_PIPE_NUM; pipe++) {
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ css_pipe->vf_output_en = false;
+ spin_lock_init(&css_pipe->qlock);
+ css_pipe->bindex = IPU3_CSS_DEFAULT_BINARY;
+ css_pipe->pipe_id = IPU3_CSS_PIPE_ID_VIDEO;
+ for (q = 0; q < IPU3_CSS_QUEUES; q++) {
+ r = ipu3_css_queue_init(&css_pipe->queue[q], NULL, 0);
+ if (r)
+ return r;
+ }
+ r = ipu3_css_map_init(css, pipe);
+ if (r) {
+ ipu3_css_cleanup(css);
+ return r;
+ }
+ }
+ if (!ipu3_dmamap_alloc(imgu, &css->xmem_sp_group_ptrs,
+ sizeof(struct imgu_abi_sp_group)))
+ return -ENOMEM;
+
+ r = ipu3_css_fw_init(css);
+ if (r)
+ return r;
+
+ return 0;
+}
+
+static u32 ipu3_css_adjust(u32 res, u32 align)
+{
+ u32 val = max_t(u32, IPU3_CSS_MIN_RES, res);
+
+ return DIV_ROUND_CLOSEST(val, align) * align;
+}
+
+/* Select a binary matching the required resolutions and formats */
+static int ipu3_css_find_binary(struct ipu3_css *css,
+ unsigned int pipe,
+ struct ipu3_css_queue queue[IPU3_CSS_QUEUES],
+ struct v4l2_rect rects[IPU3_CSS_RECTS])
+{
+ const int binary_nr = css->fwp->file_header.binary_nr;
+ unsigned int binary_mode =
+ (css->pipes[pipe].pipe_id == IPU3_CSS_PIPE_ID_CAPTURE) ?
+ IA_CSS_BINARY_MODE_PRIMARY : IA_CSS_BINARY_MODE_VIDEO;
+ const struct v4l2_pix_format_mplane *in =
+ &queue[IPU3_CSS_QUEUE_IN].fmt.mpix;
+ const struct v4l2_pix_format_mplane *out =
+ &queue[IPU3_CSS_QUEUE_OUT].fmt.mpix;
+ const struct v4l2_pix_format_mplane *vf =
+ &queue[IPU3_CSS_QUEUE_VF].fmt.mpix;
+ u32 stripe_w = 0, stripe_h = 0;
+ const char *name;
+ int i, j;
+
+ if (!ipu3_css_queue_enabled(&queue[IPU3_CSS_QUEUE_IN]))
+ return -EINVAL;
+
+ /* Find out the strip size boundary */
+ for (i = 0; i < binary_nr; i++) {
+ struct imgu_fw_info *bi = &css->fwp->binary_header[i];
+
+ u32 max_width = bi->info.isp.sp.output.max_width;
+ u32 max_height = bi->info.isp.sp.output.max_height;
+
+ if (bi->info.isp.sp.iterator.num_stripes <= 1) {
+ stripe_w = stripe_w ?
+ min(stripe_w, max_width) : max_width;
+ stripe_h = stripe_h ?
+ min(stripe_h, max_height) : max_height;
+ }
+ }
+
+ for (i = 0; i < binary_nr; i++) {
+ struct imgu_fw_info *bi = &css->fwp->binary_header[i];
+ enum imgu_abi_frame_format q_fmt;
+
+ name = (void *)css->fwp + bi->blob.prog_name_offset;
+
+ /* Check that binary supports memory-to-memory processing */
+ if (bi->info.isp.sp.input.source !=
+ IMGU_ABI_BINARY_INPUT_SOURCE_MEMORY)
+ continue;
+
+ /* Check that binary supports raw10 input */
+ if (!bi->info.isp.sp.enable.input_feeder &&
+ !bi->info.isp.sp.enable.input_raw)
+ continue;
+
+ /* Check binary mode */
+ if (bi->info.isp.sp.pipeline.mode != binary_mode)
+ continue;
+
+ /* Since input is RGGB bayer, need to process colors */
+ if (bi->info.isp.sp.enable.luma_only)
+ continue;
+
+ if (in->width < bi->info.isp.sp.input.min_width ||
+ in->width > bi->info.isp.sp.input.max_width ||
+ in->height < bi->info.isp.sp.input.min_height ||
+ in->height > bi->info.isp.sp.input.max_height)
+ continue;
+
+ if (ipu3_css_queue_enabled(&queue[IPU3_CSS_QUEUE_OUT])) {
+ if (bi->info.isp.num_output_pins <= 0)
+ continue;
+
+ q_fmt = queue[IPU3_CSS_QUEUE_OUT].css_fmt->frame_format;
+ for (j = 0; j < bi->info.isp.num_output_formats; j++)
+ if (bi->info.isp.output_formats[j] == q_fmt)
+ break;
+ if (j >= bi->info.isp.num_output_formats)
+ continue;
+
+ if (out->width < bi->info.isp.sp.output.min_width ||
+ out->width > bi->info.isp.sp.output.max_width ||
+ out->height < bi->info.isp.sp.output.min_height ||
+ out->height > bi->info.isp.sp.output.max_height)
+ continue;
+
+ if (out->width > bi->info.isp.sp.internal.max_width ||
+ out->height > bi->info.isp.sp.internal.max_height)
+ continue;
+ }
+
+ if (ipu3_css_queue_enabled(&queue[IPU3_CSS_QUEUE_VF])) {
+ if (bi->info.isp.num_output_pins <= 1)
+ continue;
+
+ q_fmt = queue[IPU3_CSS_QUEUE_VF].css_fmt->frame_format;
+ for (j = 0; j < bi->info.isp.num_output_formats; j++)
+ if (bi->info.isp.output_formats[j] == q_fmt)
+ break;
+ if (j >= bi->info.isp.num_output_formats)
+ continue;
+
+ if (vf->width < bi->info.isp.sp.output.min_width ||
+ vf->width > bi->info.isp.sp.output.max_width ||
+ vf->height < bi->info.isp.sp.output.min_height ||
+ vf->height > bi->info.isp.sp.output.max_height)
+ continue;
+ }
+
+ /* All checks passed, select the binary */
+ dev_dbg(css->dev, "using binary %s id = %u\n", name,
+ bi->info.isp.sp.id);
+ return i;
+ }
+
+ /* Can not find suitable binary for these parameters */
+ return -EINVAL;
+}
+
+/*
+ * Check that there is a binary matching requirements. Parameters may be
+ * NULL indicating disabled input/output. Return negative if given
+ * parameters can not be supported or on error, zero or positive indicating
+ * found binary number. May modify the given parameters if not exact match
+ * is found.
+ */
+int ipu3_css_fmt_try(struct ipu3_css *css,
+ struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES],
+ struct v4l2_rect *rects[IPU3_CSS_RECTS],
+ unsigned int pipe)
+{
+ static const u32 EFF_ALIGN_W = 2;
+ static const u32 BDS_ALIGN_W = 4;
+ static const u32 OUT_ALIGN_W = 8;
+ static const u32 OUT_ALIGN_H = 4;
+ static const u32 VF_ALIGN_W = 2;
+ static const char *qnames[IPU3_CSS_QUEUES] = {
+ [IPU3_CSS_QUEUE_IN] = "in",
+ [IPU3_CSS_QUEUE_PARAMS] = "params",
+ [IPU3_CSS_QUEUE_OUT] = "out",
+ [IPU3_CSS_QUEUE_VF] = "vf",
+ [IPU3_CSS_QUEUE_STAT_3A] = "3a",
+ };
+ static const char *rnames[IPU3_CSS_RECTS] = {
+ [IPU3_CSS_RECT_EFFECTIVE] = "effective resolution",
+ [IPU3_CSS_RECT_BDS] = "bayer-domain scaled resolution",
+ [IPU3_CSS_RECT_ENVELOPE] = "DVS envelope size",
+ [IPU3_CSS_RECT_GDC] = "GDC output res",
+ };
+ struct v4l2_rect r[IPU3_CSS_RECTS] = { };
+ struct v4l2_rect *const eff = &r[IPU3_CSS_RECT_EFFECTIVE];
+ struct v4l2_rect *const bds = &r[IPU3_CSS_RECT_BDS];
+ struct v4l2_rect *const env = &r[IPU3_CSS_RECT_ENVELOPE];
+ struct v4l2_rect *const gdc = &r[IPU3_CSS_RECT_GDC];
+ struct ipu3_css_queue q[IPU3_CSS_QUEUES];
+ struct v4l2_pix_format_mplane *const in =
+ &q[IPU3_CSS_QUEUE_IN].fmt.mpix;
+ struct v4l2_pix_format_mplane *const out =
+ &q[IPU3_CSS_QUEUE_OUT].fmt.mpix;
+ struct v4l2_pix_format_mplane *const vf =
+ &q[IPU3_CSS_QUEUE_VF].fmt.mpix;
+ int i, s;
+
+ /* Adjust all formats, get statistics buffer sizes and formats */
+ for (i = 0; i < IPU3_CSS_QUEUES; i++) {
+ if (fmts[i])
+ dev_dbg(css->dev, "%s %s: (%i,%i) fmt 0x%x\n", __func__,
+ qnames[i], fmts[i]->width, fmts[i]->height,
+ fmts[i]->pixelformat);
+ else
+ dev_dbg(css->dev, "%s %s: (not set)\n", __func__,
+ qnames[i]);
+ if (ipu3_css_queue_init(&q[i], fmts[i],
+ IPU3_CSS_QUEUE_TO_FLAGS(i))) {
+ dev_notice(css->dev, "can not initialize queue %s\n",
+ qnames[i]);
+ return -EINVAL;
+ }
+ }
+ for (i = 0; i < IPU3_CSS_RECTS; i++) {
+ if (rects[i]) {
+ dev_dbg(css->dev, "%s %s: (%i,%i)\n", __func__,
+ rnames[i], rects[i]->width, rects[i]->height);
+ r[i].width = rects[i]->width;
+ r[i].height = rects[i]->height;
+ } else {
+ dev_dbg(css->dev, "%s %s: (not set)\n", __func__,
+ rnames[i]);
+ }
+ /* For now, force known good resolutions */
+ r[i].left = 0;
+ r[i].top = 0;
+ }
+
+ /* Always require one input and vf only if out is also enabled */
+ if (!ipu3_css_queue_enabled(&q[IPU3_CSS_QUEUE_IN]) ||
+ !ipu3_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) {
+ dev_warn(css->dev, "required queues are disabled\n");
+ return -EINVAL;
+ }
+
+ if (!ipu3_css_queue_enabled(&q[IPU3_CSS_QUEUE_OUT])) {
+ out->width = in->width;
+ out->height = in->height;
+ }
+ if (eff->width <= 0 || eff->height <= 0) {
+ eff->width = in->width;
+ eff->height = in->height;
+ }
+ if (bds->width <= 0 || bds->height <= 0) {
+ bds->width = out->width;
+ bds->height = out->height;
+ }
+ if (gdc->width <= 0 || gdc->height <= 0) {
+ gdc->width = out->width;
+ gdc->height = out->height;
+ }
+
+ in->width = ipu3_css_adjust(in->width, 1);
+ in->height = ipu3_css_adjust(in->height, 1);
+ eff->width = ipu3_css_adjust(eff->width, EFF_ALIGN_W);
+ eff->height = ipu3_css_adjust(eff->height, 1);
+ bds->width = ipu3_css_adjust(bds->width, BDS_ALIGN_W);
+ bds->height = ipu3_css_adjust(bds->height, 1);
+ gdc->width = ipu3_css_adjust(gdc->width, OUT_ALIGN_W);
+ gdc->height = ipu3_css_adjust(gdc->height, OUT_ALIGN_H);
+ out->width = ipu3_css_adjust(out->width, OUT_ALIGN_W);
+ out->height = ipu3_css_adjust(out->height, OUT_ALIGN_H);
+ vf->width = ipu3_css_adjust(vf->width, VF_ALIGN_W);
+ vf->height = ipu3_css_adjust(vf->height, 1);
+
+ s = (bds->width - gdc->width) / 2 - FILTER_SIZE;
+ env->width = s < MIN_ENVELOPE ? MIN_ENVELOPE : s;
+ s = (bds->height - gdc->height) / 2 - FILTER_SIZE;
+ env->height = s < MIN_ENVELOPE ? MIN_ENVELOPE : s;
+
+ css->pipes[pipe].bindex =
+ ipu3_css_find_binary(css, pipe, q, r);
+ if (css->pipes[pipe].bindex < 0) {
+ dev_err(css->dev, "failed to find suitable binary\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(css->dev, "Binary index %d for pipe %d found.",
+ css->pipes[pipe].bindex, pipe);
+
+ /* Final adjustment and set back the queried formats */
+ for (i = 0; i < IPU3_CSS_QUEUES; i++) {
+ if (fmts[i]) {
+ if (ipu3_css_queue_init(&q[i], &q[i].fmt.mpix,
+ IPU3_CSS_QUEUE_TO_FLAGS(i))) {
+ dev_err(css->dev,
+ "final resolution adjustment failed\n");
+ return -EINVAL;
+ }
+ *fmts[i] = q[i].fmt.mpix;
+ }
+ }
+
+ for (i = 0; i < IPU3_CSS_RECTS; i++)
+ if (rects[i])
+ *rects[i] = r[i];
+
+ dev_dbg(css->dev,
+ "in(%u,%u) if(%u,%u) ds(%u,%u) gdc(%u,%u) out(%u,%u) vf(%u,%u)",
+ in->width, in->height, eff->width, eff->height,
+ bds->width, bds->height, gdc->width, gdc->height,
+ out->width, out->height, vf->width, vf->height);
+
+ return 0;
+}
+
+int ipu3_css_fmt_set(struct ipu3_css *css,
+ struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES],
+ struct v4l2_rect *rects[IPU3_CSS_RECTS],
+ unsigned int pipe)
+{
+ struct v4l2_rect rect_data[IPU3_CSS_RECTS];
+ struct v4l2_rect *all_rects[IPU3_CSS_RECTS];
+ int i, r;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ for (i = 0; i < IPU3_CSS_RECTS; i++) {
+ if (rects[i])
+ rect_data[i] = *rects[i];
+ else
+ memset(&rect_data[i], 0, sizeof(rect_data[i]));
+ all_rects[i] = &rect_data[i];
+ }
+ r = ipu3_css_fmt_try(css, fmts, all_rects, pipe);
+ if (r < 0)
+ return r;
+
+ for (i = 0; i < IPU3_CSS_QUEUES; i++)
+ if (ipu3_css_queue_init(&css_pipe->queue[i], fmts[i],
+ IPU3_CSS_QUEUE_TO_FLAGS(i)))
+ return -EINVAL;
+ for (i = 0; i < IPU3_CSS_RECTS; i++) {
+ css_pipe->rect[i] = rect_data[i];
+ if (rects[i])
+ *rects[i] = rect_data[i];
+ }
+
+ return 0;
+}
+
+int ipu3_css_meta_fmt_set(struct v4l2_meta_format *fmt)
+{
+ switch (fmt->dataformat) {
+ case V4L2_META_FMT_IPU3_PARAMS:
+ fmt->buffersize = sizeof(struct ipu3_uapi_params);
+ break;
+ case V4L2_META_FMT_IPU3_STAT_3A:
+ fmt->buffersize = sizeof(struct ipu3_uapi_stats_3a);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * Queue given buffer to CSS. ipu3_css_buf_prepare() must have been first
+ * called for the buffer. May be called from interrupt context.
+ * Returns 0 on success, -EBUSY if the buffer queue is full, or some other
+ * code on error conditions.
+ */
+int ipu3_css_buf_queue(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_css_buffer *b)
+{
+ struct imgu_abi_buffer *abi_buf;
+ struct imgu_addr_t *buf_addr;
+ u32 data;
+ int r;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+
+ if (!css->streaming)
+ return -EPROTO; /* CSS or buffer in wrong state */
+
+ if (b->queue >= IPU3_CSS_QUEUES || !ipu3_css_queues[b->queue].qid)
+ return -EINVAL;
+
+ b->queue_pos = ipu3_css_queue_pos(css, ipu3_css_queues[b->queue].qid,
+ pipe);
+
+ if (b->queue_pos >= ARRAY_SIZE(css->pipes[pipe].abi_buffers[b->queue]))
+ return -EIO;
+ abi_buf = css->pipes[pipe].abi_buffers[b->queue][b->queue_pos].vaddr;
+
+ /* Fill struct abi_buffer for firmware */
+ memset(abi_buf, 0, sizeof(*abi_buf));
+
+ buf_addr = (void *)abi_buf + ipu3_css_queues[b->queue].ptr_ofs;
+ *(imgu_addr_t *)buf_addr = b->daddr;
+
+ if (b->queue == IPU3_CSS_QUEUE_STAT_3A)
+ abi_buf->payload.s3a.data.dmem.s3a_tbl = b->daddr;
+
+ if (b->queue == IPU3_CSS_QUEUE_OUT)
+ abi_buf->payload.frame.padded_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_OUT].width_pad;
+
+ if (b->queue == IPU3_CSS_QUEUE_VF)
+ abi_buf->payload.frame.padded_width =
+ css_pipe->queue[IPU3_CSS_QUEUE_VF].width_pad;
+
+ spin_lock(&css_pipe->qlock);
+ list_add_tail(&b->list, &css_pipe->queue[b->queue].bufs);
+ spin_unlock(&css_pipe->qlock);
+ b->state = IPU3_CSS_BUFFER_QUEUED;
+
+ data = css->pipes[pipe].abi_buffers[b->queue][b->queue_pos].daddr;
+ r = ipu3_css_queue_data(css, ipu3_css_queues[b->queue].qid,
+ pipe, data);
+ if (r < 0)
+ goto queueing_failed;
+
+ data = IMGU_ABI_EVENT_BUFFER_ENQUEUED(pipe,
+ ipu3_css_queues[b->queue].qid);
+ r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe, data);
+ if (r < 0)
+ goto queueing_failed;
+
+ dev_dbg(css->dev, "queued buffer %p to css queue %i in pipe %d\n",
+ b, b->queue, pipe);
+
+ return 0;
+
+queueing_failed:
+ b->state = (r == -EBUSY || r == -EAGAIN) ?
+ IPU3_CSS_BUFFER_NEW : IPU3_CSS_BUFFER_FAILED;
+ list_del(&b->list);
+
+ return r;
+}
+
+/*
+ * Get next ready CSS buffer. Returns -EAGAIN in which case the function
+ * should be called again, or -EBUSY which means that there are no more
+ * buffers available. May be called from interrupt context.
+ */
+struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css)
+{
+ static const unsigned char evtype_to_queue[] = {
+ [IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE] = IPU3_CSS_QUEUE_IN,
+ [IMGU_ABI_EVTTYPE_OUT_FRAME_DONE] = IPU3_CSS_QUEUE_OUT,
+ [IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE] = IPU3_CSS_QUEUE_VF,
+ [IMGU_ABI_EVTTYPE_3A_STATS_DONE] = IPU3_CSS_QUEUE_STAT_3A,
+ };
+ struct ipu3_css_buffer *b = ERR_PTR(-EAGAIN);
+ u32 event, daddr;
+ int evtype, pipe, pipeid, queue, qid, r;
+ struct ipu3_css_pipe *css_pipe;
+
+ if (!css->streaming)
+ return ERR_PTR(-EPROTO);
+
+ r = ipu3_css_dequeue_data(css, IMGU_ABI_QUEUE_EVENT_ID, &event);
+ if (r < 0)
+ return ERR_PTR(r);
+
+ evtype = (event & IMGU_ABI_EVTTYPE_EVENT_MASK) >>
+ IMGU_ABI_EVTTYPE_EVENT_SHIFT;
+
+ switch (evtype) {
+ case IMGU_ABI_EVTTYPE_OUT_FRAME_DONE:
+ case IMGU_ABI_EVTTYPE_VF_OUT_FRAME_DONE:
+ case IMGU_ABI_EVTTYPE_3A_STATS_DONE:
+ case IMGU_ABI_EVTTYPE_INPUT_FRAME_DONE:
+ pipe = (event & IMGU_ABI_EVTTYPE_PIPE_MASK) >>
+ IMGU_ABI_EVTTYPE_PIPE_SHIFT;
+ pipeid = (event & IMGU_ABI_EVTTYPE_PIPEID_MASK) >>
+ IMGU_ABI_EVTTYPE_PIPEID_SHIFT;
+ queue = evtype_to_queue[evtype];
+ qid = ipu3_css_queues[queue].qid;
+
+ if (pipe >= IMGU_MAX_PIPE_NUM) {
+ dev_err(css->dev, "Invalid pipe: %i\n", pipe);
+ return ERR_PTR(-EIO);
+ }
+
+ if (qid >= IMGU_ABI_QUEUE_NUM) {
+ dev_err(css->dev, "Invalid qid: %i\n", qid);
+ return ERR_PTR(-EIO);
+ }
+ css_pipe = &css->pipes[pipe];
+ dev_dbg(css->dev,
+ "event: buffer done 0x%x queue %i pipe %i pipeid %i\n",
+ event, queue, pipe, pipeid);
+
+ r = ipu3_css_dequeue_data(css, qid, &daddr);
+ if (r < 0) {
+ dev_err(css->dev, "failed to dequeue buffer\n");
+ /* Force real error, not -EBUSY */
+ return ERR_PTR(-EIO);
+ }
+
+ r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
+ IMGU_ABI_EVENT_BUFFER_DEQUEUED(qid));
+ if (r < 0) {
+ dev_err(css->dev, "failed to queue event\n");
+ return ERR_PTR(-EIO);
+ }
+
+ spin_lock(&css_pipe->qlock);
+ if (list_empty(&css_pipe->queue[queue].bufs)) {
+ spin_unlock(&css_pipe->qlock);
+ dev_err(css->dev, "event on empty queue\n");
+ return ERR_PTR(-EIO);
+ }
+ b = list_first_entry(&css_pipe->queue[queue].bufs,
+ struct ipu3_css_buffer, list);
+ if (queue != b->queue ||
+ daddr != css_pipe->abi_buffers
+ [b->queue][b->queue_pos].daddr) {
+ spin_unlock(&css_pipe->qlock);
+ dev_err(css->dev, "dequeued bad buffer 0x%x\n", daddr);
+ return ERR_PTR(-EIO);
+ }
+
+ dev_dbg(css->dev, "buffer 0x%8x done from pipe %d\n", daddr, pipe);
+ b->pipe = pipe;
+ b->state = IPU3_CSS_BUFFER_DONE;
+ list_del(&b->list);
+ spin_unlock(&css_pipe->qlock);
+ break;
+ case IMGU_ABI_EVTTYPE_PIPELINE_DONE:
+ pipe = (event & IMGU_ABI_EVTTYPE_PIPE_MASK) >>
+ IMGU_ABI_EVTTYPE_PIPE_SHIFT;
+ if (pipe >= IMGU_MAX_PIPE_NUM) {
+ dev_err(css->dev, "Invalid pipe: %i\n", pipe);
+ return ERR_PTR(-EIO);
+ }
+
+ css_pipe = &css->pipes[pipe];
+ dev_dbg(css->dev, "event: pipeline done 0x%8x for pipe %d\n",
+ event, pipe);
+ break;
+ case IMGU_ABI_EVTTYPE_TIMER:
+ r = ipu3_css_dequeue_data(css, IMGU_ABI_QUEUE_EVENT_ID, &event);
+ if (r < 0)
+ return ERR_PTR(r);
+
+ if ((event & IMGU_ABI_EVTTYPE_EVENT_MASK) >>
+ IMGU_ABI_EVTTYPE_EVENT_SHIFT == IMGU_ABI_EVTTYPE_TIMER)
+ dev_dbg(css->dev, "event: timer\n");
+ else
+ dev_warn(css->dev, "half of timer event missing\n");
+ break;
+ case IMGU_ABI_EVTTYPE_FW_WARNING:
+ dev_warn(css->dev, "event: firmware warning 0x%x\n", event);
+ break;
+ case IMGU_ABI_EVTTYPE_FW_ASSERT:
+ dev_err(css->dev,
+ "event: firmware assert 0x%x module_id %i line_no %i\n",
+ event,
+ (event & IMGU_ABI_EVTTYPE_MODULEID_MASK) >>
+ IMGU_ABI_EVTTYPE_MODULEID_SHIFT,
+ swab16((event & IMGU_ABI_EVTTYPE_LINENO_MASK) >>
+ IMGU_ABI_EVTTYPE_LINENO_SHIFT));
+ break;
+ default:
+ dev_warn(css->dev, "received unknown event 0x%x\n", event);
+ }
+
+ return b;
+}
+
+/*
+ * Get a new set of parameters from pool and initialize them based on
+ * the parameters params, gdc, and obgrid. Any of these may be NULL,
+ * in which case the previously set parameters are used.
+ * If parameters haven't been set previously, initialize from scratch.
+ *
+ * Return index to css->parameter_set_info which has the newly created
+ * parameters or negative value on error.
+ */
+int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_uapi_params *set_params)
+{
+ static const unsigned int queue_id = IMGU_ABI_QUEUE_A_ID;
+ struct ipu3_css_pipe *css_pipe = &css->pipes[pipe];
+ const int stage = 0;
+ const struct imgu_fw_info *bi;
+ int obgrid_size;
+ unsigned int stripes, i;
+ struct ipu3_uapi_flags *use = set_params ? &set_params->use : NULL;
+
+ /* Destination buffers which are filled here */
+ struct imgu_abi_parameter_set_info *param_set;
+ struct imgu_abi_acc_param *acc = NULL;
+ struct imgu_abi_gdc_warp_param *gdc = NULL;
+ struct ipu3_uapi_obgrid_param *obgrid = NULL;
+ const struct ipu3_css_map *map;
+ void *vmem0 = NULL;
+ void *dmem0 = NULL;
+
+ enum imgu_abi_memories m;
+ int r = -EBUSY;
+
+ if (!css->streaming)
+ return -EPROTO;
+
+ dev_dbg(css->dev, "%s for pipe %d", __func__, pipe);
+
+ bi = &css->fwp->binary_header[css_pipe->bindex];
+ obgrid_size = ipu3_css_fw_obgrid_size(bi);
+ stripes = bi->info.isp.sp.iterator.num_stripes ? : 1;
+
+ /*
+ * TODO(b/118782861): If userspace queues more than 4 buffers, the
+ * parameters from previous buffers will be overwritten. Fix the driver
+ * not to allow this.
+ */
+ ipu3_css_pool_get(&css_pipe->pool.parameter_set_info);
+ param_set = ipu3_css_pool_last(&css_pipe->pool.parameter_set_info,
+ 0)->vaddr;
+
+ /* Get a new acc only if new parameters given, or none yet */
+ map = ipu3_css_pool_last(&css_pipe->pool.acc, 0);
+ if (set_params || !map->vaddr) {
+ ipu3_css_pool_get(&css_pipe->pool.acc);
+ map = ipu3_css_pool_last(&css_pipe->pool.acc, 0);
+ acc = map->vaddr;
+ }
+
+ /* Get new VMEM0 only if needed, or none yet */
+ m = IMGU_ABI_MEM_ISP_VMEM0;
+ map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
+ if (!map->vaddr || (set_params && (set_params->use.lin_vmem_params ||
+ set_params->use.tnr3_vmem_params ||
+ set_params->use.xnr3_vmem_params))) {
+ ipu3_css_pool_get(&css_pipe->pool.binary_params_p[m]);
+ map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
+ vmem0 = map->vaddr;
+ }
+
+ /* Get new DMEM0 only if needed, or none yet */
+ m = IMGU_ABI_MEM_ISP_DMEM0;
+ map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
+ if (!map->vaddr || (set_params && (set_params->use.tnr3_dmem_params ||
+ set_params->use.xnr3_dmem_params))) {
+ ipu3_css_pool_get(&css_pipe->pool.binary_params_p[m]);
+ map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
+ dmem0 = map->vaddr;
+ }
+
+ /* Configure acc parameter cluster */
+ if (acc) {
+ /* get acc_old */
+ map = ipu3_css_pool_last(&css_pipe->pool.acc, 1);
+ /* user acc */
+ r = ipu3_css_cfg_acc(css, pipe, use, acc, map->vaddr,
+ set_params ? &set_params->acc_param : NULL);
+ if (r < 0)
+ goto fail;
+ }
+
+ /* Configure late binding parameters */
+ if (vmem0) {
+ m = IMGU_ABI_MEM_ISP_VMEM0;
+ map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 1);
+ r = ipu3_css_cfg_vmem0(css, pipe, use, vmem0,
+ map->vaddr, set_params);
+ if (r < 0)
+ goto fail;
+ }
+
+ if (dmem0) {
+ m = IMGU_ABI_MEM_ISP_DMEM0;
+ map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 1);
+ r = ipu3_css_cfg_dmem0(css, pipe, use, dmem0,
+ map->vaddr, set_params);
+ if (r < 0)
+ goto fail;
+ }
+
+ /* Get a new gdc only if a new gdc is given, or none yet */
+ if (bi->info.isp.sp.enable.dvs_6axis) {
+ unsigned int a = IPU3_CSS_AUX_FRAME_REF;
+ unsigned int g = IPU3_CSS_RECT_GDC;
+ unsigned int e = IPU3_CSS_RECT_ENVELOPE;
+
+ map = ipu3_css_pool_last(&css_pipe->pool.gdc, 0);
+ if (!map->vaddr) {
+ ipu3_css_pool_get(&css_pipe->pool.gdc);
+ map = ipu3_css_pool_last(&css_pipe->pool.gdc, 0);
+ gdc = map->vaddr;
+ ipu3_css_cfg_gdc_table(map->vaddr,
+ css_pipe->aux_frames[a].bytesperline /
+ css_pipe->aux_frames[a].bytesperpixel,
+ css_pipe->aux_frames[a].height,
+ css_pipe->rect[g].width,
+ css_pipe->rect[g].height,
+ css_pipe->rect[e].width + FILTER_SIZE,
+ css_pipe->rect[e].height +
+ FILTER_SIZE);
+ }
+ }
+
+ /* Get a new obgrid only if a new obgrid is given, or none yet */
+ map = ipu3_css_pool_last(&css_pipe->pool.obgrid, 0);
+ if (!map->vaddr || (set_params && set_params->use.obgrid_param)) {
+ ipu3_css_pool_get(&css_pipe->pool.obgrid);
+ map = ipu3_css_pool_last(&css_pipe->pool.obgrid, 0);
+ obgrid = map->vaddr;
+
+ /* Configure optical black level grid (obgrid) */
+ if (set_params && set_params->use.obgrid_param)
+ for (i = 0; i < obgrid_size / sizeof(*obgrid); i++)
+ obgrid[i] = set_params->obgrid_param;
+ else
+ memset(obgrid, 0, obgrid_size);
+ }
+
+ /* Configure parameter set info, queued to `queue_id' */
+
+ memset(param_set, 0, sizeof(*param_set));
+ map = ipu3_css_pool_last(&css_pipe->pool.acc, 0);
+ param_set->mem_map.acc_cluster_params_for_sp = map->daddr;
+
+ map = ipu3_css_pool_last(&css_pipe->pool.gdc, 0);
+ param_set->mem_map.dvs_6axis_params_y = map->daddr;
+
+ for (i = 0; i < stripes; i++) {
+ map = ipu3_css_pool_last(&css_pipe->pool.obgrid, 0);
+ param_set->mem_map.obgrid_tbl[i] =
+ map->daddr + (obgrid_size / stripes) * i;
+ }
+
+ for (m = 0; m < IMGU_ABI_NUM_MEMORIES; m++) {
+ map = ipu3_css_pool_last(&css_pipe->pool.binary_params_p[m], 0);
+ param_set->mem_map.isp_mem_param[stage][m] = map->daddr;
+ }
+
+ /* Then queue the new parameter buffer */
+ map = ipu3_css_pool_last(&css_pipe->pool.parameter_set_info, 0);
+ r = ipu3_css_queue_data(css, queue_id, pipe, map->daddr);
+ if (r < 0)
+ goto fail;
+
+ r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
+ IMGU_ABI_EVENT_BUFFER_ENQUEUED(pipe,
+ queue_id));
+ if (r < 0)
+ goto fail_no_put;
+
+ /* Finally dequeue all old parameter buffers */
+
+ do {
+ u32 daddr;
+
+ r = ipu3_css_dequeue_data(css, queue_id, &daddr);
+ if (r == -EBUSY)
+ break;
+ if (r)
+ goto fail_no_put;
+ r = ipu3_css_queue_data(css, IMGU_ABI_QUEUE_EVENT_ID, pipe,
+ IMGU_ABI_EVENT_BUFFER_DEQUEUED
+ (queue_id));
+ if (r < 0) {
+ dev_err(css->dev, "failed to queue parameter event\n");
+ goto fail_no_put;
+ }
+ } while (1);
+
+ return 0;
+
+fail:
+ /*
+ * A failure, most likely the parameter queue was full.
+ * Return error but continue streaming. User can try submitting new
+ * parameters again later.
+ */
+
+ ipu3_css_pool_put(&css_pipe->pool.parameter_set_info);
+ if (acc)
+ ipu3_css_pool_put(&css_pipe->pool.acc);
+ if (gdc)
+ ipu3_css_pool_put(&css_pipe->pool.gdc);
+ if (obgrid)
+ ipu3_css_pool_put(&css_pipe->pool.obgrid);
+ if (vmem0)
+ ipu3_css_pool_put(
+ &css_pipe->pool.binary_params_p
+ [IMGU_ABI_MEM_ISP_VMEM0]);
+ if (dmem0)
+ ipu3_css_pool_put(
+ &css_pipe->pool.binary_params_p
+ [IMGU_ABI_MEM_ISP_DMEM0]);
+
+fail_no_put:
+ return r;
+}
+
+int ipu3_css_irq_ack(struct ipu3_css *css)
+{
+ static const int NUM_SWIRQS = 3;
+ struct imgu_fw_info *bi = &css->fwp->binary_header[css->fw_sp[0]];
+ void __iomem *const base = css->base;
+ u32 irq_status[IMGU_IRQCTRL_NUM];
+ int i;
+
+ u32 imgu_status = readl(base + IMGU_REG_INT_STATUS);
+
+ writel(imgu_status, base + IMGU_REG_INT_STATUS);
+ for (i = 0; i < IMGU_IRQCTRL_NUM; i++)
+ irq_status[i] = readl(base + IMGU_REG_IRQCTRL_STATUS(i));
+
+ for (i = 0; i < NUM_SWIRQS; i++) {
+ if (irq_status[IMGU_IRQCTRL_SP0] & IMGU_IRQCTRL_IRQ_SW_PIN(i)) {
+ /* SP SW interrupt */
+ u32 cnt = readl(base + IMGU_REG_SP_DMEM_BASE(0) +
+ bi->info.sp.output);
+ u32 val = readl(base + IMGU_REG_SP_DMEM_BASE(0) +
+ bi->info.sp.output + 4 + 4 * i);
+
+ dev_dbg(css->dev, "%s: swirq %i cnt %i val 0x%x\n",
+ __func__, i, cnt, val);
+ }
+ }
+
+ for (i = IMGU_IRQCTRL_NUM - 1; i >= 0; i--)
+ if (irq_status[i]) {
+ writel(irq_status[i], base + IMGU_REG_IRQCTRL_CLEAR(i));
+ /* Wait for write to complete */
+ readl(base + IMGU_REG_IRQCTRL_ENABLE(i));
+ }
+
+ dev_dbg(css->dev, "%s: imgu 0x%x main 0x%x sp0 0x%x sp1 0x%x\n",
+ __func__, imgu_status, irq_status[IMGU_IRQCTRL_MAIN],
+ irq_status[IMGU_IRQCTRL_SP0], irq_status[IMGU_IRQCTRL_SP1]);
+
+ if (!imgu_status && !irq_status[IMGU_IRQCTRL_MAIN])
+ return -ENOMSG;
+
+ return 0;
+}
diff --git a/drivers/staging/media/ipu3/ipu3-css.h b/drivers/staging/media/ipu3/ipu3-css.h
new file mode 100644
index 000000000000..e88d60f1a0c3
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-css.h
@@ -0,0 +1,213 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 Intel Corporation */
+
+#ifndef __IPU3_CSS_H
+#define __IPU3_CSS_H
+
+#include <linux/videodev2.h>
+#include <linux/types.h>
+
+#include "ipu3-abi.h"
+#include "ipu3-css-pool.h"
+
+/* 2 stages for split isp pipeline, 1 for scaling */
+#define IMGU_NUM_SP 2
+#define IMGU_MAX_PIPELINE_NUM 20
+#define IMGU_MAX_PIPE_NUM 2
+
+/* For DVS etc., format FRAME_FMT_YUV420_16 */
+#define IPU3_CSS_AUX_FRAME_REF 0
+/* For temporal noise reduction DVS etc., format FRAME_FMT_YUV_LINE */
+#define IPU3_CSS_AUX_FRAME_TNR 1
+#define IPU3_CSS_AUX_FRAME_TYPES 2 /* REF and TNR */
+#define IPU3_CSS_AUX_FRAMES 2 /* 2 for REF and 2 for TNR */
+
+#define IPU3_CSS_QUEUE_IN 0
+#define IPU3_CSS_QUEUE_PARAMS 1
+#define IPU3_CSS_QUEUE_OUT 2
+#define IPU3_CSS_QUEUE_VF 3
+#define IPU3_CSS_QUEUE_STAT_3A 4
+#define IPU3_CSS_QUEUES 5
+
+#define IPU3_CSS_RECT_EFFECTIVE 0 /* Effective resolution */
+#define IPU3_CSS_RECT_BDS 1 /* Resolution after BDS */
+#define IPU3_CSS_RECT_ENVELOPE 2 /* DVS envelope size */
+#define IPU3_CSS_RECT_GDC 3 /* gdc output res */
+#define IPU3_CSS_RECTS 4 /* number of rects */
+
+#define IA_CSS_BINARY_MODE_PRIMARY 2
+#define IA_CSS_BINARY_MODE_VIDEO 3
+#define IPU3_CSS_DEFAULT_BINARY 3 /* default binary index */
+
+/*
+ * The pipe id type, distinguishes the kind of pipes that
+ * can be run in parallel.
+ */
+enum ipu3_css_pipe_id {
+ IPU3_CSS_PIPE_ID_PREVIEW,
+ IPU3_CSS_PIPE_ID_COPY,
+ IPU3_CSS_PIPE_ID_VIDEO,
+ IPU3_CSS_PIPE_ID_CAPTURE,
+ IPU3_CSS_PIPE_ID_YUVPP,
+ IPU3_CSS_PIPE_ID_ACC,
+ IPU3_CSS_PIPE_ID_NUM
+};
+
+struct ipu3_css_resolution {
+ u32 w;
+ u32 h;
+};
+
+enum ipu3_css_buffer_state {
+ IPU3_CSS_BUFFER_NEW, /* Not yet queued */
+ IPU3_CSS_BUFFER_QUEUED, /* Queued, waiting to be filled */
+ IPU3_CSS_BUFFER_DONE, /* Finished processing, removed from queue */
+ IPU3_CSS_BUFFER_FAILED, /* Was not processed, removed from queue */
+};
+
+struct ipu3_css_buffer {
+ /* Private fields: user doesn't touch */
+ dma_addr_t daddr;
+ unsigned int queue;
+ enum ipu3_css_buffer_state state;
+ struct list_head list;
+ u8 queue_pos;
+ unsigned int pipe;
+};
+
+struct ipu3_css_format {
+ u32 pixelformat;
+ enum v4l2_colorspace colorspace;
+ enum imgu_abi_frame_format frame_format;
+ enum imgu_abi_bayer_order bayer_order;
+ enum imgu_abi_osys_format osys_format;
+ enum imgu_abi_osys_tiling osys_tiling;
+ u32 bytesperpixel_num; /* Bytes per pixel in first plane * 50 */
+ u8 bit_depth; /* Effective bits per pixel */
+ u8 chroma_decim; /* Chroma plane decimation, 0=no chroma plane */
+ u8 width_align; /* Alignment requirement for width_pad */
+ u8 flags;
+};
+
+struct ipu3_css_queue {
+ union {
+ struct v4l2_pix_format_mplane mpix;
+ struct v4l2_meta_format meta;
+
+ } fmt;
+ const struct ipu3_css_format *css_fmt;
+ unsigned int width_pad;
+ struct list_head bufs;
+};
+
+struct ipu3_css_pipe {
+ enum ipu3_css_pipe_id pipe_id;
+ unsigned int bindex;
+
+ struct ipu3_css_queue queue[IPU3_CSS_QUEUES];
+ struct v4l2_rect rect[IPU3_CSS_RECTS];
+
+ bool vf_output_en;
+ /* Protect access to queue[IPU3_CSS_QUEUES] */
+ spinlock_t qlock;
+
+ /* Data structures shared with IMGU and driver, always allocated */
+ struct ipu3_css_map sp_ddr_ptrs;
+ struct ipu3_css_map xmem_sp_stage_ptrs[IPU3_CSS_PIPE_ID_NUM]
+ [IMGU_ABI_MAX_STAGES];
+ struct ipu3_css_map xmem_isp_stage_ptrs[IPU3_CSS_PIPE_ID_NUM]
+ [IMGU_ABI_MAX_STAGES];
+
+ /*
+ * Data structures shared with IMGU and driver, binary specific.
+ * PARAM_CLASS_CONFIG and PARAM_CLASS_STATE parameters.
+ */
+ struct ipu3_css_map binary_params_cs[IMGU_ABI_PARAM_CLASS_NUM - 1]
+ [IMGU_ABI_NUM_MEMORIES];
+
+ struct {
+ struct ipu3_css_map mem[IPU3_CSS_AUX_FRAMES];
+ unsigned int width;
+ unsigned int height;
+ unsigned int bytesperline;
+ unsigned int bytesperpixel;
+ } aux_frames[IPU3_CSS_AUX_FRAME_TYPES];
+
+ struct {
+ struct ipu3_css_pool parameter_set_info;
+ struct ipu3_css_pool acc;
+ struct ipu3_css_pool gdc;
+ struct ipu3_css_pool obgrid;
+ /* PARAM_CLASS_PARAM parameters for binding while streaming */
+ struct ipu3_css_pool binary_params_p[IMGU_ABI_NUM_MEMORIES];
+ } pool;
+
+ struct ipu3_css_map abi_buffers[IPU3_CSS_QUEUES]
+ [IMGU_ABI_HOST2SP_BUFQ_SIZE];
+};
+
+/* IPU3 Camera Sub System structure */
+struct ipu3_css {
+ struct device *dev;
+ void __iomem *base;
+ const struct firmware *fw;
+ struct imgu_fw_header *fwp;
+ int iomem_length;
+ int fw_bl, fw_sp[IMGU_NUM_SP]; /* Indices of bl and SP binaries */
+ struct ipu3_css_map *binary; /* fw binaries mapped to device */
+ bool streaming; /* true when streaming is enabled */
+
+ struct ipu3_css_pipe pipes[IMGU_MAX_PIPE_NUM];
+ struct ipu3_css_map xmem_sp_group_ptrs;
+
+ /* enabled pipe(s) */
+ DECLARE_BITMAP(enabled_pipes, IMGU_MAX_PIPE_NUM);
+};
+
+/******************* css v4l *******************/
+int ipu3_css_init(struct device *dev, struct ipu3_css *css,
+ void __iomem *base, int length);
+void ipu3_css_cleanup(struct ipu3_css *css);
+int ipu3_css_fmt_try(struct ipu3_css *css,
+ struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES],
+ struct v4l2_rect *rects[IPU3_CSS_RECTS],
+ unsigned int pipe);
+int ipu3_css_fmt_set(struct ipu3_css *css,
+ struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES],
+ struct v4l2_rect *rects[IPU3_CSS_RECTS],
+ unsigned int pipe);
+int ipu3_css_meta_fmt_set(struct v4l2_meta_format *fmt);
+int ipu3_css_buf_queue(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_css_buffer *b);
+struct ipu3_css_buffer *ipu3_css_buf_dequeue(struct ipu3_css *css);
+int ipu3_css_start_streaming(struct ipu3_css *css);
+void ipu3_css_stop_streaming(struct ipu3_css *css);
+bool ipu3_css_queue_empty(struct ipu3_css *css);
+bool ipu3_css_is_streaming(struct ipu3_css *css);
+bool ipu3_css_pipe_queue_empty(struct ipu3_css *css, unsigned int pipe);
+
+/******************* css hw *******************/
+int ipu3_css_set_powerup(struct device *dev, void __iomem *base);
+void ipu3_css_set_powerdown(struct device *dev, void __iomem *base);
+int ipu3_css_irq_ack(struct ipu3_css *css);
+
+/******************* set parameters ************/
+int ipu3_css_set_parameters(struct ipu3_css *css, unsigned int pipe,
+ struct ipu3_uapi_params *set_params);
+
+/******************* auxiliary helpers *******************/
+static inline enum ipu3_css_buffer_state
+ipu3_css_buf_state(struct ipu3_css_buffer *b)
+{
+ return b->state;
+}
+
+/* Initialize given buffer. May be called several times. */
+static inline void ipu3_css_buf_init(struct ipu3_css_buffer *b,
+ unsigned int queue, dma_addr_t daddr)
+{
+ b->state = IPU3_CSS_BUFFER_NEW;
+ b->queue = queue;
+ b->daddr = daddr;
+}
+#endif
diff --git a/drivers/staging/media/ipu3/ipu3-dmamap.c b/drivers/staging/media/ipu3/ipu3-dmamap.c
new file mode 100644
index 000000000000..93a393d4e15e
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-dmamap.c
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Intel Corporation
+ * Copyright 2018 Google LLC.
+ *
+ * Author: Tomasz Figa <tfiga@chromium.org>
+ * Author: Yong Zhi <yong.zhi@intel.com>
+ */
+
+#include <linux/vmalloc.h>
+
+#include "ipu3.h"
+#include "ipu3-css-pool.h"
+#include "ipu3-mmu.h"
+
+/*
+ * Free a buffer allocated by ipu3_dmamap_alloc_buffer()
+ */
+static void ipu3_dmamap_free_buffer(struct page **pages,
+ size_t size)
+{
+ int count = size >> PAGE_SHIFT;
+
+ while (count--)
+ __free_page(pages[count]);
+ kvfree(pages);
+}
+
+/*
+ * Based on the implementation of __iommu_dma_alloc_pages()
+ * defined in drivers/iommu/dma-iommu.c
+ */
+static struct page **ipu3_dmamap_alloc_buffer(size_t size,
+ unsigned long order_mask,
+ gfp_t gfp)
+{
+ struct page **pages;
+ unsigned int i = 0, count = size >> PAGE_SHIFT;
+ const gfp_t high_order_gfp = __GFP_NOWARN | __GFP_NORETRY;
+
+ /* Allocate mem for array of page ptrs */
+ pages = kvmalloc_array(count, sizeof(*pages), GFP_KERNEL);
+
+ if (!pages)
+ return NULL;
+
+ order_mask &= (2U << MAX_ORDER) - 1;
+ if (!order_mask)
+ return NULL;
+
+ gfp |= __GFP_HIGHMEM | __GFP_ZERO;
+
+ while (count) {
+ struct page *page = NULL;
+ unsigned int order_size;
+
+ for (order_mask &= (2U << __fls(count)) - 1;
+ order_mask; order_mask &= ~order_size) {
+ unsigned int order = __fls(order_mask);
+
+ order_size = 1U << order;
+ page = alloc_pages((order_mask - order_size) ?
+ gfp | high_order_gfp : gfp, order);
+ if (!page)
+ continue;
+ if (!order)
+ break;
+ if (!PageCompound(page)) {
+ split_page(page, order);
+ break;
+ }
+
+ __free_pages(page, order);
+ }
+ if (!page) {
+ ipu3_dmamap_free_buffer(pages, i << PAGE_SHIFT);
+ return NULL;
+ }
+ count -= order_size;
+ while (order_size--)
+ pages[i++] = page++;
+ }
+
+ return pages;
+}
+
+/**
+ * ipu3_dmamap_alloc - allocate and map a buffer into KVA
+ * @imgu: struct device pointer
+ * @map: struct to store mapping variables
+ * @len: size required
+ *
+ * Returns:
+ * KVA on success
+ * %NULL on failure
+ */
+void *ipu3_dmamap_alloc(struct imgu_device *imgu, struct ipu3_css_map *map,
+ size_t len)
+{
+ unsigned long shift = iova_shift(&imgu->iova_domain);
+ unsigned int alloc_sizes = imgu->mmu->pgsize_bitmap;
+ struct device *dev = &imgu->pci_dev->dev;
+ size_t size = PAGE_ALIGN(len);
+ struct page **pages;
+ dma_addr_t iovaddr;
+ struct iova *iova;
+ int i, rval;
+
+ dev_dbg(dev, "%s: allocating %zu\n", __func__, size);
+
+ iova = alloc_iova(&imgu->iova_domain, size >> shift,
+ imgu->mmu->aperture_end >> shift, 0);
+ if (!iova)
+ return NULL;
+
+ pages = ipu3_dmamap_alloc_buffer(size, alloc_sizes >> PAGE_SHIFT,
+ GFP_KERNEL);
+ if (!pages)
+ goto out_free_iova;
+
+ /* Call IOMMU driver to setup pgt */
+ iovaddr = iova_dma_addr(&imgu->iova_domain, iova);
+ for (i = 0; i < size / PAGE_SIZE; ++i) {
+ rval = ipu3_mmu_map(imgu->mmu, iovaddr,
+ page_to_phys(pages[i]), PAGE_SIZE);
+ if (rval)
+ goto out_unmap;
+
+ iovaddr += PAGE_SIZE;
+ }
+
+ /* Now grab a virtual region */
+ map->vma = __get_vm_area(size, VM_USERMAP, VMALLOC_START, VMALLOC_END);
+ if (!map->vma)
+ goto out_unmap;
+
+ map->vma->pages = pages;
+ /* And map it in KVA */
+ if (map_vm_area(map->vma, PAGE_KERNEL, pages))
+ goto out_vunmap;
+
+ map->size = size;
+ map->daddr = iova_dma_addr(&imgu->iova_domain, iova);
+ map->vaddr = map->vma->addr;
+
+ dev_dbg(dev, "%s: allocated %zu @ IOVA %pad @ VA %p\n", __func__,
+ size, &map->daddr, map->vma->addr);
+
+ return map->vma->addr;
+
+out_vunmap:
+ vunmap(map->vma->addr);
+
+out_unmap:
+ ipu3_dmamap_free_buffer(pages, size);
+ ipu3_mmu_unmap(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova),
+ i * PAGE_SIZE);
+ map->vma = NULL;
+
+out_free_iova:
+ __free_iova(&imgu->iova_domain, iova);
+
+ return NULL;
+}
+
+void ipu3_dmamap_unmap(struct imgu_device *imgu, struct ipu3_css_map *map)
+{
+ struct iova *iova;
+
+ iova = find_iova(&imgu->iova_domain,
+ iova_pfn(&imgu->iova_domain, map->daddr));
+ if (WARN_ON(!iova))
+ return;
+
+ ipu3_mmu_unmap(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova),
+ iova_size(iova) << iova_shift(&imgu->iova_domain));
+
+ __free_iova(&imgu->iova_domain, iova);
+}
+
+/*
+ * Counterpart of ipu3_dmamap_alloc
+ */
+void ipu3_dmamap_free(struct imgu_device *imgu, struct ipu3_css_map *map)
+{
+ struct vm_struct *area = map->vma;
+
+ dev_dbg(&imgu->pci_dev->dev, "%s: freeing %zu @ IOVA %pad @ VA %p\n",
+ __func__, map->size, &map->daddr, map->vaddr);
+
+ if (!map->vaddr)
+ return;
+
+ ipu3_dmamap_unmap(imgu, map);
+
+ if (WARN_ON(!area) || WARN_ON(!area->pages))
+ return;
+
+ ipu3_dmamap_free_buffer(area->pages, map->size);
+ vunmap(map->vaddr);
+ map->vaddr = NULL;
+}
+
+int ipu3_dmamap_map_sg(struct imgu_device *imgu, struct scatterlist *sglist,
+ int nents, struct ipu3_css_map *map)
+{
+ unsigned long shift = iova_shift(&imgu->iova_domain);
+ struct scatterlist *sg;
+ struct iova *iova;
+ size_t size = 0;
+ int i;
+
+ for_each_sg(sglist, sg, nents, i) {
+ if (sg->offset)
+ return -EINVAL;
+
+ if (i != nents - 1 && !PAGE_ALIGNED(sg->length))
+ return -EINVAL;
+
+ size += sg->length;
+ }
+
+ size = iova_align(&imgu->iova_domain, size);
+ dev_dbg(&imgu->pci_dev->dev, "dmamap: mapping sg %d entries, %zu pages\n",
+ nents, size >> shift);
+
+ iova = alloc_iova(&imgu->iova_domain, size >> shift,
+ imgu->mmu->aperture_end >> shift, 0);
+ if (!iova)
+ return -ENOMEM;
+
+ dev_dbg(&imgu->pci_dev->dev, "dmamap: iova low pfn %lu, high pfn %lu\n",
+ iova->pfn_lo, iova->pfn_hi);
+
+ if (ipu3_mmu_map_sg(imgu->mmu, iova_dma_addr(&imgu->iova_domain, iova),
+ sglist, nents) < size)
+ goto out_fail;
+
+ memset(map, 0, sizeof(*map));
+ map->daddr = iova_dma_addr(&imgu->iova_domain, iova);
+ map->size = size;
+
+ return 0;
+
+out_fail:
+ __free_iova(&imgu->iova_domain, iova);
+
+ return -EFAULT;
+}
+
+int ipu3_dmamap_init(struct imgu_device *imgu)
+{
+ unsigned long order, base_pfn;
+ int ret = iova_cache_get();
+
+ if (ret)
+ return ret;
+
+ order = __ffs(imgu->mmu->pgsize_bitmap);
+ base_pfn = max_t(unsigned long, 1, imgu->mmu->aperture_start >> order);
+ init_iova_domain(&imgu->iova_domain, 1UL << order, base_pfn);
+
+ return 0;
+}
+
+void ipu3_dmamap_exit(struct imgu_device *imgu)
+{
+ put_iova_domain(&imgu->iova_domain);
+ iova_cache_put();
+}
diff --git a/drivers/staging/media/ipu3/ipu3-dmamap.h b/drivers/staging/media/ipu3/ipu3-dmamap.h
new file mode 100644
index 000000000000..b9d224a33273
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-dmamap.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 Intel Corporation */
+/* Copyright 2018 Google LLC. */
+
+#ifndef __IPU3_DMAMAP_H
+#define __IPU3_DMAMAP_H
+
+struct imgu_device;
+struct scatterlist;
+
+void *ipu3_dmamap_alloc(struct imgu_device *imgu, struct ipu3_css_map *map,
+ size_t len);
+void ipu3_dmamap_free(struct imgu_device *imgu, struct ipu3_css_map *map);
+
+int ipu3_dmamap_map_sg(struct imgu_device *imgu, struct scatterlist *sglist,
+ int nents, struct ipu3_css_map *map);
+void ipu3_dmamap_unmap(struct imgu_device *imgu, struct ipu3_css_map *map);
+
+int ipu3_dmamap_init(struct imgu_device *imgu);
+void ipu3_dmamap_exit(struct imgu_device *imgu);
+
+#endif
diff --git a/drivers/staging/media/ipu3/ipu3-mmu.c b/drivers/staging/media/ipu3/ipu3-mmu.c
new file mode 100644
index 000000000000..b9f209541f78
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-mmu.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Intel Corporation.
+ * Copyright 2018 Google LLC.
+ *
+ * Author: Tuukka Toivonen <tuukka.toivonen@intel.com>
+ * Author: Sakari Ailus <sakari.ailus@linux.intel.com>
+ * Author: Samu Onkalo <samu.onkalo@intel.com>
+ * Author: Tomasz Figa <tfiga@chromium.org>
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <asm/set_memory.h>
+
+#include "ipu3-mmu.h"
+
+#define IPU3_PAGE_SHIFT 12
+#define IPU3_PAGE_SIZE (1UL << IPU3_PAGE_SHIFT)
+
+#define IPU3_PT_BITS 10
+#define IPU3_PT_PTES (1UL << IPU3_PT_BITS)
+#define IPU3_PT_SIZE (IPU3_PT_PTES << 2)
+#define IPU3_PT_ORDER (IPU3_PT_SIZE >> PAGE_SHIFT)
+
+#define IPU3_ADDR2PTE(addr) ((addr) >> IPU3_PAGE_SHIFT)
+#define IPU3_PTE2ADDR(pte) ((phys_addr_t)(pte) << IPU3_PAGE_SHIFT)
+
+#define IPU3_L2PT_SHIFT IPU3_PT_BITS
+#define IPU3_L2PT_MASK ((1UL << IPU3_L2PT_SHIFT) - 1)
+
+#define IPU3_L1PT_SHIFT IPU3_PT_BITS
+#define IPU3_L1PT_MASK ((1UL << IPU3_L1PT_SHIFT) - 1)
+
+#define IPU3_MMU_ADDRESS_BITS (IPU3_PAGE_SHIFT + \
+ IPU3_L2PT_SHIFT + \
+ IPU3_L1PT_SHIFT)
+
+#define IMGU_REG_BASE 0x4000
+#define REG_TLB_INVALIDATE (IMGU_REG_BASE + 0x300)
+#define TLB_INVALIDATE 1
+#define REG_L1_PHYS (IMGU_REG_BASE + 0x304) /* 27-bit pfn */
+#define REG_GP_HALT (IMGU_REG_BASE + 0x5dc)
+#define REG_GP_HALTED (IMGU_REG_BASE + 0x5e0)
+
+struct ipu3_mmu {
+ struct device *dev;
+ void __iomem *base;
+ /* protect access to l2pts, l1pt */
+ spinlock_t lock;
+
+ void *dummy_page;
+ u32 dummy_page_pteval;
+
+ u32 *dummy_l2pt;
+ u32 dummy_l2pt_pteval;
+
+ u32 **l2pts;
+ u32 *l1pt;
+
+ struct ipu3_mmu_info geometry;
+};
+
+static inline struct ipu3_mmu *to_ipu3_mmu(struct ipu3_mmu_info *info)
+{
+ return container_of(info, struct ipu3_mmu, geometry);
+}
+
+/**
+ * ipu3_mmu_tlb_invalidate - invalidate translation look-aside buffer
+ * @mmu: MMU to perform the invalidate operation on
+ *
+ * This function invalidates the whole TLB. Must be called when the hardware
+ * is powered on.
+ */
+static void ipu3_mmu_tlb_invalidate(struct ipu3_mmu *mmu)
+{
+ writel(TLB_INVALIDATE, mmu->base + REG_TLB_INVALIDATE);
+}
+
+static void call_if_ipu3_is_powered(struct ipu3_mmu *mmu,
+ void (*func)(struct ipu3_mmu *mmu))
+{
+ if (!pm_runtime_get_if_in_use(mmu->dev))
+ return;
+
+ func(mmu);
+ pm_runtime_put(mmu->dev);
+}
+
+/**
+ * ipu3_mmu_set_halt - set CIO gate halt bit
+ * @mmu: MMU to set the CIO gate bit in.
+ * @halt: Desired state of the gate bit.
+ *
+ * This function sets the CIO gate bit that controls whether external memory
+ * accesses are allowed. Must be called when the hardware is powered on.
+ */
+static void ipu3_mmu_set_halt(struct ipu3_mmu *mmu, bool halt)
+{
+ int ret;
+ u32 val;
+
+ writel(halt, mmu->base + REG_GP_HALT);
+ ret = readl_poll_timeout(mmu->base + REG_GP_HALTED,
+ val, (val & 1) == halt, 1000, 100000);
+
+ if (ret)
+ dev_err(mmu->dev, "failed to %s CIO gate halt\n",
+ halt ? "set" : "clear");
+}
+
+/**
+ * ipu3_mmu_alloc_page_table - allocate a pre-filled page table
+ * @pteval: Value to initialize for page table entries with.
+ *
+ * Return: Pointer to allocated page table or NULL on failure.
+ */
+static u32 *ipu3_mmu_alloc_page_table(u32 pteval)
+{
+ u32 *pt;
+ int pte;
+
+ pt = (u32 *)__get_free_page(GFP_KERNEL);
+ if (!pt)
+ return NULL;
+
+ for (pte = 0; pte < IPU3_PT_PTES; pte++)
+ pt[pte] = pteval;
+
+ set_memory_uc((unsigned long int)pt, IPU3_PT_ORDER);
+
+ return pt;
+}
+
+/**
+ * ipu3_mmu_free_page_table - free page table
+ * @pt: Page table to free.
+ */
+static void ipu3_mmu_free_page_table(u32 *pt)
+{
+ set_memory_wb((unsigned long int)pt, IPU3_PT_ORDER);
+ free_page((unsigned long)pt);
+}
+
+/**
+ * address_to_pte_idx - split IOVA into L1 and L2 page table indices
+ * @iova: IOVA to split.
+ * @l1pt_idx: Output for the L1 page table index.
+ * @l2pt_idx: Output for the L2 page index.
+ */
+static inline void address_to_pte_idx(unsigned long iova, u32 *l1pt_idx,
+ u32 *l2pt_idx)
+{
+ iova >>= IPU3_PAGE_SHIFT;
+
+ if (l2pt_idx)
+ *l2pt_idx = iova & IPU3_L2PT_MASK;
+
+ iova >>= IPU3_L2PT_SHIFT;
+
+ if (l1pt_idx)
+ *l1pt_idx = iova & IPU3_L1PT_MASK;
+}
+
+static u32 *ipu3_mmu_get_l2pt(struct ipu3_mmu *mmu, u32 l1pt_idx)
+{
+ unsigned long flags;
+ u32 *l2pt, *new_l2pt;
+ u32 pteval;
+
+ spin_lock_irqsave(&mmu->lock, flags);
+
+ l2pt = mmu->l2pts[l1pt_idx];
+ if (l2pt)
+ goto done;
+
+ spin_unlock_irqrestore(&mmu->lock, flags);
+
+ new_l2pt = ipu3_mmu_alloc_page_table(mmu->dummy_page_pteval);
+ if (!new_l2pt)
+ return NULL;
+
+ spin_lock_irqsave(&mmu->lock, flags);
+
+ dev_dbg(mmu->dev, "allocated page table %p for l1pt_idx %u\n",
+ new_l2pt, l1pt_idx);
+
+ l2pt = mmu->l2pts[l1pt_idx];
+ if (l2pt) {
+ ipu3_mmu_free_page_table(new_l2pt);
+ goto done;
+ }
+
+ l2pt = new_l2pt;
+ mmu->l2pts[l1pt_idx] = new_l2pt;
+
+ pteval = IPU3_ADDR2PTE(virt_to_phys(new_l2pt));
+ mmu->l1pt[l1pt_idx] = pteval;
+
+done:
+ spin_unlock_irqrestore(&mmu->lock, flags);
+ return l2pt;
+}
+
+static int __ipu3_mmu_map(struct ipu3_mmu *mmu, unsigned long iova,
+ phys_addr_t paddr)
+{
+ u32 l1pt_idx, l2pt_idx;
+ unsigned long flags;
+ u32 *l2pt;
+
+ if (!mmu)
+ return -ENODEV;
+
+ address_to_pte_idx(iova, &l1pt_idx, &l2pt_idx);
+
+ l2pt = ipu3_mmu_get_l2pt(mmu, l1pt_idx);
+ if (!l2pt)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&mmu->lock, flags);
+
+ if (l2pt[l2pt_idx] != mmu->dummy_page_pteval) {
+ spin_unlock_irqrestore(&mmu->lock, flags);
+ return -EBUSY;
+ }
+
+ l2pt[l2pt_idx] = IPU3_ADDR2PTE(paddr);
+
+ spin_unlock_irqrestore(&mmu->lock, flags);
+
+ return 0;
+}
+
+/**
+ * The following four functions are implemented based on iommu.c
+ * drivers/iommu/iommu.c/iommu_pgsize().
+ */
+static size_t ipu3_mmu_pgsize(unsigned long pgsize_bitmap,
+ unsigned long addr_merge, size_t size)
+{
+ unsigned int pgsize_idx;
+ size_t pgsize;
+
+ /* Max page size that still fits into 'size' */
+ pgsize_idx = __fls(size);
+
+ /* need to consider alignment requirements ? */
+ if (likely(addr_merge)) {
+ /* Max page size allowed by address */
+ unsigned int align_pgsize_idx = __ffs(addr_merge);
+
+ pgsize_idx = min(pgsize_idx, align_pgsize_idx);
+ }
+
+ /* build a mask of acceptable page sizes */
+ pgsize = (1UL << (pgsize_idx + 1)) - 1;
+
+ /* throw away page sizes not supported by the hardware */
+ pgsize &= pgsize_bitmap;
+
+ /* make sure we're still sane */
+ WARN_ON(!pgsize);
+
+ /* pick the biggest page */
+ pgsize_idx = __fls(pgsize);
+ pgsize = 1UL << pgsize_idx;
+
+ return pgsize;
+}
+
+/* drivers/iommu/iommu.c/iommu_map() */
+int ipu3_mmu_map(struct ipu3_mmu_info *info, unsigned long iova,
+ phys_addr_t paddr, size_t size)
+{
+ struct ipu3_mmu *mmu = to_ipu3_mmu(info);
+ unsigned int min_pagesz;
+ int ret = 0;
+
+ /* find out the minimum page size supported */
+ min_pagesz = 1 << __ffs(mmu->geometry.pgsize_bitmap);
+
+ /*
+ * both the virtual address and the physical one, as well as
+ * the size of the mapping, must be aligned (at least) to the
+ * size of the smallest page supported by the hardware
+ */
+ if (!IS_ALIGNED(iova | paddr | size, min_pagesz)) {
+ dev_err(mmu->dev, "unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%x\n",
+ iova, &paddr, size, min_pagesz);
+ return -EINVAL;
+ }
+
+ dev_dbg(mmu->dev, "map: iova 0x%lx pa %pa size 0x%zx\n",
+ iova, &paddr, size);
+
+ while (size) {
+ size_t pgsize = ipu3_mmu_pgsize(mmu->geometry.pgsize_bitmap,
+ iova | paddr, size);
+
+ dev_dbg(mmu->dev, "mapping: iova 0x%lx pa %pa pgsize 0x%zx\n",
+ iova, &paddr, pgsize);
+
+ ret = __ipu3_mmu_map(mmu, iova, paddr);
+ if (ret)
+ break;
+
+ iova += pgsize;
+ paddr += pgsize;
+ size -= pgsize;
+ }
+
+ call_if_ipu3_is_powered(mmu, ipu3_mmu_tlb_invalidate);
+
+ return ret;
+}
+
+/* drivers/iommu/iommu.c/default_iommu_map_sg() */
+size_t ipu3_mmu_map_sg(struct ipu3_mmu_info *info, unsigned long iova,
+ struct scatterlist *sg, unsigned int nents)
+{
+ struct ipu3_mmu *mmu = to_ipu3_mmu(info);
+ struct scatterlist *s;
+ size_t s_length, mapped = 0;
+ unsigned int i, min_pagesz;
+ int ret;
+
+ min_pagesz = 1 << __ffs(mmu->geometry.pgsize_bitmap);
+
+ for_each_sg(sg, s, nents, i) {
+ phys_addr_t phys = page_to_phys(sg_page(s)) + s->offset;
+
+ s_length = s->length;
+
+ if (!IS_ALIGNED(s->offset, min_pagesz))
+ goto out_err;
+
+ /* must be min_pagesz aligned to be mapped singlely */
+ if (i == nents - 1 && !IS_ALIGNED(s->length, min_pagesz))
+ s_length = PAGE_ALIGN(s->length);
+
+ ret = ipu3_mmu_map(info, iova + mapped, phys, s_length);
+ if (ret)
+ goto out_err;
+
+ mapped += s_length;
+ }
+
+ call_if_ipu3_is_powered(mmu, ipu3_mmu_tlb_invalidate);
+
+ return mapped;
+
+out_err:
+ /* undo mappings already done */
+ ipu3_mmu_unmap(info, iova, mapped);
+
+ return 0;
+}
+
+static size_t __ipu3_mmu_unmap(struct ipu3_mmu *mmu,
+ unsigned long iova, size_t size)
+{
+ u32 l1pt_idx, l2pt_idx;
+ unsigned long flags;
+ size_t unmap = size;
+ u32 *l2pt;
+
+ if (!mmu)
+ return 0;
+
+ address_to_pte_idx(iova, &l1pt_idx, &l2pt_idx);
+
+ spin_lock_irqsave(&mmu->lock, flags);
+
+ l2pt = mmu->l2pts[l1pt_idx];
+ if (!l2pt) {
+ spin_unlock_irqrestore(&mmu->lock, flags);
+ return 0;
+ }
+
+ if (l2pt[l2pt_idx] == mmu->dummy_page_pteval)
+ unmap = 0;
+
+ l2pt[l2pt_idx] = mmu->dummy_page_pteval;
+
+ spin_unlock_irqrestore(&mmu->lock, flags);
+
+ return unmap;
+}
+
+/* drivers/iommu/iommu.c/iommu_unmap() */
+size_t ipu3_mmu_unmap(struct ipu3_mmu_info *info, unsigned long iova,
+ size_t size)
+{
+ struct ipu3_mmu *mmu = to_ipu3_mmu(info);
+ size_t unmapped_page, unmapped = 0;
+ unsigned int min_pagesz;
+
+ /* find out the minimum page size supported */
+ min_pagesz = 1 << __ffs(mmu->geometry.pgsize_bitmap);
+
+ /*
+ * The virtual address, as well as the size of the mapping, must be
+ * aligned (at least) to the size of the smallest page supported
+ * by the hardware
+ */
+ if (!IS_ALIGNED(iova | size, min_pagesz)) {
+ dev_err(mmu->dev, "unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%x\n",
+ iova, size, min_pagesz);
+ return -EINVAL;
+ }
+
+ dev_dbg(mmu->dev, "unmap this: iova 0x%lx size 0x%zx\n", iova, size);
+
+ /*
+ * Keep iterating until we either unmap 'size' bytes (or more)
+ * or we hit an area that isn't mapped.
+ */
+ while (unmapped < size) {
+ size_t pgsize = ipu3_mmu_pgsize(mmu->geometry.pgsize_bitmap,
+ iova, size - unmapped);
+
+ unmapped_page = __ipu3_mmu_unmap(mmu, iova, pgsize);
+ if (!unmapped_page)
+ break;
+
+ dev_dbg(mmu->dev, "unmapped: iova 0x%lx size 0x%zx\n",
+ iova, unmapped_page);
+
+ iova += unmapped_page;
+ unmapped += unmapped_page;
+ }
+
+ call_if_ipu3_is_powered(mmu, ipu3_mmu_tlb_invalidate);
+
+ return unmapped;
+}
+
+/**
+ * ipu3_mmu_init() - initialize IPU3 MMU block
+ * @base: IOMEM base of hardware registers.
+ *
+ * Return: Pointer to IPU3 MMU private data pointer or ERR_PTR() on error.
+ */
+struct ipu3_mmu_info *ipu3_mmu_init(struct device *parent, void __iomem *base)
+{
+ struct ipu3_mmu *mmu;
+ u32 pteval;
+
+ mmu = kzalloc(sizeof(*mmu), GFP_KERNEL);
+ if (!mmu)
+ return ERR_PTR(-ENOMEM);
+
+ mmu->dev = parent;
+ mmu->base = base;
+ spin_lock_init(&mmu->lock);
+
+ /* Disallow external memory access when having no valid page tables. */
+ ipu3_mmu_set_halt(mmu, true);
+
+ /*
+ * The MMU does not have a "valid" bit, so we have to use a dummy
+ * page for invalid entries.
+ */
+ mmu->dummy_page = (void *)__get_free_page(GFP_KERNEL);
+ if (!mmu->dummy_page)
+ goto fail_group;
+ pteval = IPU3_ADDR2PTE(virt_to_phys(mmu->dummy_page));
+ mmu->dummy_page_pteval = pteval;
+
+ /*
+ * Allocate a dummy L2 page table with all entries pointing to
+ * the dummy page.
+ */
+ mmu->dummy_l2pt = ipu3_mmu_alloc_page_table(pteval);
+ if (!mmu->dummy_l2pt)
+ goto fail_dummy_page;
+ pteval = IPU3_ADDR2PTE(virt_to_phys(mmu->dummy_l2pt));
+ mmu->dummy_l2pt_pteval = pteval;
+
+ /*
+ * Allocate the array of L2PT CPU pointers, initialized to zero,
+ * which means the dummy L2PT allocated above.
+ */
+ mmu->l2pts = vzalloc(IPU3_PT_PTES * sizeof(*mmu->l2pts));
+ if (!mmu->l2pts)
+ goto fail_l2pt;
+
+ /* Allocate the L1 page table. */
+ mmu->l1pt = ipu3_mmu_alloc_page_table(mmu->dummy_l2pt_pteval);
+ if (!mmu->l1pt)
+ goto fail_l2pts;
+
+ pteval = IPU3_ADDR2PTE(virt_to_phys(mmu->l1pt));
+ writel(pteval, mmu->base + REG_L1_PHYS);
+ ipu3_mmu_tlb_invalidate(mmu);
+ ipu3_mmu_set_halt(mmu, false);
+
+ mmu->geometry.aperture_start = 0;
+ mmu->geometry.aperture_end = DMA_BIT_MASK(IPU3_MMU_ADDRESS_BITS);
+ mmu->geometry.pgsize_bitmap = IPU3_PAGE_SIZE;
+
+ return &mmu->geometry;
+
+fail_l2pts:
+ vfree(mmu->l2pts);
+fail_l2pt:
+ ipu3_mmu_free_page_table(mmu->dummy_l2pt);
+fail_dummy_page:
+ free_page((unsigned long)mmu->dummy_page);
+fail_group:
+ kfree(mmu);
+
+ return ERR_PTR(-ENOMEM);
+}
+
+/**
+ * ipu3_mmu_exit() - clean up IPU3 MMU block
+ * @mmu: IPU3 MMU private data
+ */
+void ipu3_mmu_exit(struct ipu3_mmu_info *info)
+{
+ struct ipu3_mmu *mmu = to_ipu3_mmu(info);
+
+ /* We are going to free our page tables, no more memory access. */
+ ipu3_mmu_set_halt(mmu, true);
+ ipu3_mmu_tlb_invalidate(mmu);
+
+ ipu3_mmu_free_page_table(mmu->l1pt);
+ vfree(mmu->l2pts);
+ ipu3_mmu_free_page_table(mmu->dummy_l2pt);
+ free_page((unsigned long)mmu->dummy_page);
+ kfree(mmu);
+}
+
+void ipu3_mmu_suspend(struct ipu3_mmu_info *info)
+{
+ struct ipu3_mmu *mmu = to_ipu3_mmu(info);
+
+ ipu3_mmu_set_halt(mmu, true);
+}
+
+void ipu3_mmu_resume(struct ipu3_mmu_info *info)
+{
+ struct ipu3_mmu *mmu = to_ipu3_mmu(info);
+ u32 pteval;
+
+ ipu3_mmu_set_halt(mmu, true);
+
+ pteval = IPU3_ADDR2PTE(virt_to_phys(mmu->l1pt));
+ writel(pteval, mmu->base + REG_L1_PHYS);
+
+ ipu3_mmu_tlb_invalidate(mmu);
+ ipu3_mmu_set_halt(mmu, false);
+}
diff --git a/drivers/staging/media/ipu3/ipu3-mmu.h b/drivers/staging/media/ipu3/ipu3-mmu.h
new file mode 100644
index 000000000000..8fe63b4c6e1c
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-mmu.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2018 Intel Corporation */
+/* Copyright 2018 Google LLC. */
+
+#ifndef __IPU3_MMU_H
+#define __IPU3_MMU_H
+
+/**
+ * struct ipu3_mmu_info - Describes mmu geometry
+ *
+ * @aperture_start: First address that can be mapped
+ * @aperture_end: Last address that can be mapped
+ * @pgsize_bitmap: Bitmap of page sizes in use
+ */
+struct ipu3_mmu_info {
+ dma_addr_t aperture_start;
+ dma_addr_t aperture_end;
+ unsigned long pgsize_bitmap;
+};
+
+struct device;
+struct scatterlist;
+
+struct ipu3_mmu_info *ipu3_mmu_init(struct device *parent, void __iomem *base);
+void ipu3_mmu_exit(struct ipu3_mmu_info *info);
+void ipu3_mmu_suspend(struct ipu3_mmu_info *info);
+void ipu3_mmu_resume(struct ipu3_mmu_info *info);
+
+int ipu3_mmu_map(struct ipu3_mmu_info *info, unsigned long iova,
+ phys_addr_t paddr, size_t size);
+size_t ipu3_mmu_unmap(struct ipu3_mmu_info *info, unsigned long iova,
+ size_t size);
+size_t ipu3_mmu_map_sg(struct ipu3_mmu_info *info, unsigned long iova,
+ struct scatterlist *sg, unsigned int nents);
+#endif
diff --git a/drivers/staging/media/ipu3/ipu3-tables.c b/drivers/staging/media/ipu3/ipu3-tables.c
new file mode 100644
index 000000000000..334517987eba
--- /dev/null
+++ b/drivers/staging/media/ipu3/ipu3-tables.c
@@ -0,0 +1,9609 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Intel Corporation
+
+#include "ipu3-tables.h"
+
+#define X 0 /* Don't care value */
+
+const struct ipu3_css_bds_config
+ ipu3_css_bds_configs[IMGU_BDS_CONFIG_LEN] = { {
+ /* Scale factor 32 / (32 + 0) = 1 */
+ .hor_phase_arr = {
+ .even = { { 0, 0, 64, 6, 0, 0, 0 } },
+ .odd = { { 0, 0, 64, 6, 0, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 0, 64, 6, 0, 0, 0 } },
+ .odd = { { 0, 0, 64, 6, 0, 0, 0 } } },
+ .ptrn_arr = { { 0x3 } },
+ .sample_patrn_length = 2,
+ .hor_ds_en = 0,
+ .ver_ds_en = 0
+}, {
+ /* Scale factor 32 / (32 + 1) = 0.969697 */
+ .hor_phase_arr = {
+ .even = { { 0, 3, 122, 7, 3, 0, 0 },
+ { 0, 0, 122, 7, 7, -1, 0 },
+ { 0, -3, 122, 7, 10, -1, 0 },
+ { 0, -5, 121, 7, 14, -2, 0 },
+ { 0, -7, 120, 7, 18, -3, 0 },
+ { 0, -9, 118, 7, 23, -4, 0 },
+ { 0, -11, 116, 7, 27, -4, 0 },
+ { 0, -12, 113, 7, 32, -5, 0 },
+ { 0, -13, 110, 7, 37, -6, 0 },
+ { 0, -14, 107, 7, 42, -7, 0 },
+ { 0, -14, 103, 7, 47, -8, 0 },
+ { 0, -15, 100, 7, 52, -9, 0 },
+ { 0, -15, 96, 7, 57, -10, 0 },
+ { 0, -15, 92, 7, 62, -11, 0 },
+ { 0, -14, 86, 7, 68, -12, 0 },
+ { 0, -14, 82, 7, 73, -13, 0 },
+ { 0, -14, 78, 7, 78, -14, 0 },
+ { 0, -13, 73, 7, 82, -14, 0 },
+ { 0, -12, 68, 7, 86, -14, 0 },
+ { 0, -11, 62, 7, 92, -15, 0 },
+ { 0, -10, 57, 7, 96, -15, 0 },
+ { 0, -9, 52, 7, 100, -15, 0 },
+ { 0, -8, 47, 7, 103, -14, 0 },
+ { 0, -7, 42, 7, 107, -14, 0 },
+ { 0, -6, 37, 7, 110, -13, 0 },
+ { 0, -5, 32, 7, 113, -12, 0 },
+ { 0, -4, 27, 7, 116, -11, 0 },
+ { 0, -4, 23, 7, 118, -9, 0 },
+ { 0, -3, 18, 7, 120, -7, 0 },
+ { 0, -2, 14, 7, 121, -5, 0 },
+ { 0, -1, 10, 7, 122, -3, 0 },
+ { 0, -1, 7, 7, 122, 0, 0 } },
+ .odd = { { 0, 2, 122, 7, 5, -1, 0 },
+ { 0, -1, 122, 7, 8, -1, 0 },
+ { 0, -4, 122, 7, 12, -2, 0 },
+ { 0, -6, 120, 7, 16, -2, 0 },
+ { 0, -8, 118, 7, 21, -3, 0 },
+ { 0, -10, 117, 7, 25, -4, 0 },
+ { 0, -11, 114, 7, 30, -5, 0 },
+ { 0, -13, 112, 7, 35, -6, 0 },
+ { 0, -14, 109, 7, 40, -7, 0 },
+ { 0, -14, 105, 7, 45, -8, 0 },
+ { 0, -15, 102, 7, 50, -9, 0 },
+ { 0, -15, 98, 7, 55, -10, 0 },
+ { 0, -15, 94, 7, 60, -11, 0 },
+ { 0, -15, 90, 7, 65, -12, 0 },
+ { 0, -14, 85, 7, 70, -13, 0 },
+ { 0, -14, 80, 7, 75, -13, 0 },
+ { 0, -13, 75, 7, 80, -14, 0 },
+ { 0, -13, 70, 7, 85, -14, 0 },
+ { 0, -12, 65, 7, 90, -15, 0 },
+ { 0, -11, 60, 7, 94, -15, 0 },
+ { 0, -10, 55, 7, 98, -15, 0 },
+ { 0, -9, 50, 7, 102, -15, 0 },
+ { 0, -8, 45, 7, 105, -14, 0 },
+ { 0, -7, 40, 7, 109, -14, 0 },
+ { 0, -6, 35, 7, 112, -13, 0 },
+ { 0, -5, 30, 7, 114, -11, 0 },
+ { 0, -4, 25, 7, 117, -10, 0 },
+ { 0, -3, 21, 7, 118, -8, 0 },
+ { 0, -2, 16, 7, 120, -6, 0 },
+ { 0, -2, 12, 7, 122, -4, 0 },
+ { 0, -1, 8, 7, 122, -1, 0 },
+ { 0, -1, 5, 7, 122, 2, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 3, 122, 7, 3, 0, 0 },
+ { 0, 0, 122, 7, 7, -1, 0 },
+ { 0, -3, 122, 7, 10, -1, 0 },
+ { 0, -5, 121, 7, 14, -2, 0 },
+ { 0, -7, 120, 7, 18, -3, 0 },
+ { 0, -9, 118, 7, 23, -4, 0 },
+ { 0, -11, 116, 7, 27, -4, 0 },
+ { 0, -12, 113, 7, 32, -5, 0 },
+ { 0, -13, 110, 7, 37, -6, 0 },
+ { 0, -14, 107, 7, 42, -7, 0 },
+ { 0, -14, 103, 7, 47, -8, 0 },
+ { 0, -15, 100, 7, 52, -9, 0 },
+ { 0, -15, 96, 7, 57, -10, 0 },
+ { 0, -15, 92, 7, 62, -11, 0 },
+ { 0, -14, 86, 7, 68, -12, 0 },
+ { 0, -14, 82, 7, 73, -13, 0 },
+ { 0, -14, 78, 7, 78, -14, 0 },
+ { 0, -13, 73, 7, 82, -14, 0 },
+ { 0, -12, 68, 7, 86, -14, 0 },
+ { 0, -11, 62, 7, 92, -15, 0 },
+ { 0, -10, 57, 7, 96, -15, 0 },
+ { 0, -9, 52, 7, 100, -15, 0 },
+ { 0, -8, 47, 7, 103, -14, 0 },
+ { 0, -7, 42, 7, 107, -14, 0 },
+ { 0, -6, 37, 7, 110, -13, 0 },
+ { 0, -5, 32, 7, 113, -12, 0 },
+ { 0, -4, 27, 7, 116, -11, 0 },
+ { 0, -4, 23, 7, 118, -9, 0 },
+ { 0, -3, 18, 7, 120, -7, 0 },
+ { 0, -2, 14, 7, 121, -5, 0 },
+ { 0, -1, 10, 7, 122, -3, 0 },
+ { 0, -1, 7, 7, 122, 0, 0 } },
+ .odd = { { 0, 2, 122, 7, 5, -1, 0 },
+ { 0, -1, 122, 7, 8, -1, 0 },
+ { 0, -4, 122, 7, 12, -2, 0 },
+ { 0, -6, 120, 7, 16, -2, 0 },
+ { 0, -8, 118, 7, 21, -3, 0 },
+ { 0, -10, 117, 7, 25, -4, 0 },
+ { 0, -11, 114, 7, 30, -5, 0 },
+ { 0, -13, 112, 7, 35, -6, 0 },
+ { 0, -14, 109, 7, 40, -7, 0 },
+ { 0, -14, 105, 7, 45, -8, 0 },
+ { 0, -15, 102, 7, 50, -9, 0 },
+ { 0, -15, 98, 7, 55, -10, 0 },
+ { 0, -15, 94, 7, 60, -11, 0 },
+ { 0, -15, 90, 7, 65, -12, 0 },
+ { 0, -14, 85, 7, 70, -13, 0 },
+ { 0, -14, 80, 7, 75, -13, 0 },
+ { 0, -13, 75, 7, 80, -14, 0 },
+ { 0, -13, 70, 7, 85, -14, 0 },
+ { 0, -12, 65, 7, 90, -15, 0 },
+ { 0, -11, 60, 7, 94, -15, 0 },
+ { 0, -10, 55, 7, 98, -15, 0 },
+ { 0, -9, 50, 7, 102, -15, 0 },
+ { 0, -8, 45, 7, 105, -14, 0 },
+ { 0, -7, 40, 7, 109, -14, 0 },
+ { 0, -6, 35, 7, 112, -13, 0 },
+ { 0, -5, 30, 7, 114, -11, 0 },
+ { 0, -4, 25, 7, 117, -10, 0 },
+ { 0, -3, 21, 7, 118, -8, 0 },
+ { 0, -2, 16, 7, 120, -6, 0 },
+ { 0, -2, 12, 7, 122, -4, 0 },
+ { 0, -1, 8, 7, 122, -1, 0 },
+ { 0, -1, 5, 7, 122, 2, 0 } } },
+ .ptrn_arr = { { 0xffffffff, 0xffffffff } },
+ .sample_patrn_length = 66,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 2) = 0.941176 */
+ .hor_phase_arr = {
+ .even = { { -1, 6, 118, 7, 6, -1, 0 },
+ { 0, 0, 117, 7, 13, -2, 0 },
+ { 0, -5, 116, 7, 21, -4, 0 },
+ { 0, -9, 113, 7, 30, -6, 0 },
+ { 0, -12, 109, 7, 39, -8, 0 },
+ { 0, -13, 102, 7, 49, -10, 0 },
+ { 0, -14, 94, 7, 59, -11, 0 },
+ { 0, -14, 86, 7, 69, -13, 0 },
+ { 0, -14, 78, 7, 78, -14, 0 },
+ { 0, -13, 69, 7, 86, -14, 0 },
+ { 0, -11, 59, 7, 94, -14, 0 },
+ { 0, -10, 49, 7, 102, -13, 0 },
+ { 0, -8, 39, 7, 109, -12, 0 },
+ { 0, -6, 30, 7, 113, -9, 0 },
+ { 0, -4, 21, 7, 116, -5, 0 },
+ { 0, -2, 13, 7, 117, 0, 0 } },
+ .odd = { { -1, 3, 118, 7, 10, -2, 0 },
+ { 0, -3, 117, 7, 17, -3, 0 },
+ { 0, -7, 114, 7, 26, -5, 0 },
+ { 0, -10, 110, 7, 35, -7, 0 },
+ { 0, -13, 106, 7, 44, -9, 0 },
+ { 0, -14, 99, 7, 54, -11, 0 },
+ { 0, -14, 90, 7, 64, -12, 0 },
+ { 0, -14, 82, 7, 73, -13, 0 },
+ { 0, -13, 73, 7, 82, -14, 0 },
+ { 0, -12, 64, 7, 90, -14, 0 },
+ { 0, -11, 54, 7, 99, -14, 0 },
+ { 0, -9, 44, 7, 106, -13, 0 },
+ { 0, -7, 35, 7, 110, -10, 0 },
+ { 0, -5, 26, 7, 114, -7, 0 },
+ { 0, -3, 17, 7, 117, -3, 0 },
+ { 0, -2, 10, 7, 118, 3, -1 } } },
+ .ver_phase_arr = {
+ .even = { { -1, 6, 118, 7, 6, -1, 0 },
+ { 0, 0, 117, 7, 13, -2, 0 },
+ { 0, -5, 116, 7, 21, -4, 0 },
+ { 0, -9, 113, 7, 30, -6, 0 },
+ { 0, -12, 109, 7, 39, -8, 0 },
+ { 0, -13, 102, 7, 49, -10, 0 },
+ { 0, -14, 94, 7, 59, -11, 0 },
+ { 0, -14, 86, 7, 69, -13, 0 },
+ { 0, -14, 78, 7, 78, -14, 0 },
+ { 0, -13, 69, 7, 86, -14, 0 },
+ { 0, -11, 59, 7, 94, -14, 0 },
+ { 0, -10, 49, 7, 102, -13, 0 },
+ { 0, -8, 39, 7, 109, -12, 0 },
+ { 0, -6, 30, 7, 113, -9, 0 },
+ { 0, -4, 21, 7, 116, -5, 0 },
+ { 0, -2, 13, 7, 117, 0, 0 } },
+ .odd = { { -1, 3, 118, 7, 10, -2, 0 },
+ { 0, -3, 117, 7, 17, -3, 0 },
+ { 0, -7, 114, 7, 26, -5, 0 },
+ { 0, -10, 110, 7, 35, -7, 0 },
+ { 0, -13, 106, 7, 44, -9, 0 },
+ { 0, -14, 99, 7, 54, -11, 0 },
+ { 0, -14, 90, 7, 64, -12, 0 },
+ { 0, -14, 82, 7, 73, -13, 0 },
+ { 0, -13, 73, 7, 82, -14, 0 },
+ { 0, -12, 64, 7, 90, -14, 0 },
+ { 0, -11, 54, 7, 99, -14, 0 },
+ { 0, -9, 44, 7, 106, -13, 0 },
+ { 0, -7, 35, 7, 110, -10, 0 },
+ { 0, -5, 26, 7, 114, -7, 0 },
+ { 0, -3, 17, 7, 117, -3, 0 },
+ { 0, -2, 10, 7, 118, 3, -1 } } },
+ .ptrn_arr = { { 0xffffffff } },
+ .sample_patrn_length = 34,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 3) = 0.914286 */
+ .hor_phase_arr = {
+ .even = { { -2, 9, 114, 7, 9, -2, 0 },
+ { -1, 0, 114, 7, 20, -5, 0 },
+ { 0, -7, 110, 7, 32, -7, 0 },
+ { 0, -11, 103, 7, 46, -10, 0 },
+ { 0, -13, 93, 7, 60, -12, 0 },
+ { 0, -14, 82, 7, 74, -14, 0 },
+ { 0, -13, 69, 7, 86, -14, 0 },
+ { 0, -11, 55, 7, 97, -13, 0 },
+ { 0, -9, 41, 7, 106, -10, 0 },
+ { 0, -6, 28, 7, 111, -5, 0 },
+ { 0, -4, 16, 7, 114, 3, -1 },
+ { -2, 6, 115, 7, 12, -3, 0 },
+ { 0, -2, 111, 7, 24, -5, 0 },
+ { 0, -8, 107, 7, 37, -8, 0 },
+ { 0, -12, 100, 7, 51, -11, 0 },
+ { 0, -14, 90, 7, 65, -13, 0 },
+ { 0, -14, 78, 7, 78, -14, 0 },
+ { 0, -13, 65, 7, 90, -14, 0 },
+ { 0, -11, 51, 7, 100, -12, 0 },
+ { 0, -8, 37, 7, 107, -8, 0 },
+ { 0, -5, 24, 7, 111, -2, 0 },
+ { 0, -3, 12, 7, 115, 6, -2 },
+ { -1, 3, 114, 7, 16, -4, 0 },
+ { 0, -5, 111, 7, 28, -6, 0 },
+ { 0, -10, 106, 7, 41, -9, 0 },
+ { 0, -13, 97, 7, 55, -11, 0 },
+ { 0, -14, 86, 7, 69, -13, 0 },
+ { 0, -14, 74, 7, 82, -14, 0 },
+ { 0, -12, 60, 7, 93, -13, 0 },
+ { 0, -10, 46, 7, 103, -11, 0 },
+ { 0, -7, 32, 7, 110, -7, 0 },
+ { 0, -5, 20, 7, 114, 0, -1 } },
+ .odd = { { -1, 4, 114, 7, 14, -3, 0 },
+ { 0, -4, 112, 7, 26, -6, 0 },
+ { 0, -9, 107, 7, 39, -9, 0 },
+ { 0, -13, 99, 7, 53, -11, 0 },
+ { 0, -14, 88, 7, 67, -13, 0 },
+ { 0, -14, 76, 7, 80, -14, 0 },
+ { 0, -13, 62, 7, 93, -14, 0 },
+ { 0, -10, 48, 7, 102, -12, 0 },
+ { 0, -8, 35, 7, 109, -8, 0 },
+ { 0, -5, 22, 7, 112, -1, 0 },
+ { 0, -3, 11, 7, 115, 7, -2 },
+ { -1, 1, 114, 7, 18, -4, 0 },
+ { 0, -6, 111, 7, 30, -7, 0 },
+ { 0, -10, 103, 7, 44, -9, 0 },
+ { 0, -13, 95, 7, 58, -12, 0 },
+ { 0, -14, 85, 7, 71, -14, 0 },
+ { 0, -14, 71, 7, 85, -14, 0 },
+ { 0, -12, 58, 7, 95, -13, 0 },
+ { 0, -9, 44, 7, 103, -10, 0 },
+ { 0, -7, 30, 7, 111, -6, 0 },
+ { 0, -4, 18, 7, 114, 1, -1 },
+ { -2, 7, 115, 7, 11, -3, 0 },
+ { 0, -1, 112, 7, 22, -5, 0 },
+ { 0, -8, 109, 7, 35, -8, 0 },
+ { 0, -12, 102, 7, 48, -10, 0 },
+ { 0, -14, 93, 7, 62, -13, 0 },
+ { 0, -14, 80, 7, 76, -14, 0 },
+ { 0, -13, 67, 7, 88, -14, 0 },
+ { 0, -11, 53, 7, 99, -13, 0 },
+ { 0, -9, 39, 7, 107, -9, 0 },
+ { 0, -6, 26, 7, 112, -4, 0 },
+ { 0, -3, 14, 7, 114, 4, -1 } } },
+ .ver_phase_arr = {
+ .even = { { -2, 9, 114, 7, 9, -2, 0 },
+ { -1, 0, 114, 7, 20, -5, 0 },
+ { 0, -7, 110, 7, 32, -7, 0 },
+ { 0, -11, 103, 7, 46, -10, 0 },
+ { 0, -13, 93, 7, 60, -12, 0 },
+ { 0, -14, 82, 7, 74, -14, 0 },
+ { 0, -13, 69, 7, 86, -14, 0 },
+ { 0, -11, 55, 7, 97, -13, 0 },
+ { 0, -9, 41, 7, 106, -10, 0 },
+ { 0, -6, 28, 7, 111, -5, 0 },
+ { 0, -4, 16, 7, 114, 3, -1 },
+ { -2, 6, 115, 7, 12, -3, 0 },
+ { 0, -2, 111, 7, 24, -5, 0 },
+ { 0, -8, 107, 7, 37, -8, 0 },
+ { 0, -12, 100, 7, 51, -11, 0 },
+ { 0, -14, 90, 7, 65, -13, 0 },
+ { 0, -14, 78, 7, 78, -14, 0 },
+ { 0, -13, 65, 7, 90, -14, 0 },
+ { 0, -11, 51, 7, 100, -12, 0 },
+ { 0, -8, 37, 7, 107, -8, 0 },
+ { 0, -5, 24, 7, 111, -2, 0 },
+ { 0, -3, 12, 7, 115, 6, -2 },
+ { -1, 3, 114, 7, 16, -4, 0 },
+ { 0, -5, 111, 7, 28, -6, 0 },
+ { 0, -10, 106, 7, 41, -9, 0 },
+ { 0, -13, 97, 7, 55, -11, 0 },
+ { 0, -14, 86, 7, 69, -13, 0 },
+ { 0, -14, 74, 7, 82, -14, 0 },
+ { 0, -12, 60, 7, 93, -13, 0 },
+ { 0, -10, 46, 7, 103, -11, 0 },
+ { 0, -7, 32, 7, 110, -7, 0 },
+ { 0, -5, 20, 7, 114, 0, -1 } },
+ .odd = { { -1, 4, 114, 7, 14, -3, 0 },
+ { 0, -4, 112, 7, 26, -6, 0 },
+ { 0, -9, 107, 7, 39, -9, 0 },
+ { 0, -13, 99, 7, 53, -11, 0 },
+ { 0, -14, 88, 7, 67, -13, 0 },
+ { 0, -14, 76, 7, 80, -14, 0 },
+ { 0, -13, 62, 7, 93, -14, 0 },
+ { 0, -10, 48, 7, 102, -12, 0 },
+ { 0, -8, 35, 7, 109, -8, 0 },
+ { 0, -5, 22, 7, 112, -1, 0 },
+ { 0, -3, 11, 7, 115, 7, -2 },
+ { -1, 1, 114, 7, 18, -4, 0 },
+ { 0, -6, 111, 7, 30, -7, 0 },
+ { 0, -10, 103, 7, 44, -9, 0 },
+ { 0, -13, 95, 7, 58, -12, 0 },
+ { 0, -14, 85, 7, 71, -14, 0 },
+ { 0, -14, 71, 7, 85, -14, 0 },
+ { 0, -12, 58, 7, 95, -13, 0 },
+ { 0, -9, 44, 7, 103, -10, 0 },
+ { 0, -7, 30, 7, 111, -6, 0 },
+ { 0, -4, 18, 7, 114, 1, -1 },
+ { -2, 7, 115, 7, 11, -3, 0 },
+ { 0, -1, 112, 7, 22, -5, 0 },
+ { 0, -8, 109, 7, 35, -8, 0 },
+ { 0, -12, 102, 7, 48, -10, 0 },
+ { 0, -14, 93, 7, 62, -13, 0 },
+ { 0, -14, 80, 7, 76, -14, 0 },
+ { 0, -13, 67, 7, 88, -14, 0 },
+ { 0, -11, 53, 7, 99, -13, 0 },
+ { 0, -9, 39, 7, 107, -9, 0 },
+ { 0, -6, 26, 7, 112, -4, 0 },
+ { 0, -3, 14, 7, 114, 4, -1 } } },
+ .ptrn_arr = { { 0xff3fffff, 0xffff9fff, 0xf } },
+ .sample_patrn_length = 70,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 4) = 0.888889 */
+ .hor_phase_arr = {
+ .even = { { -3, 12, 110, 7, 12, -3, 0 },
+ { -1, 0, 110, 7, 26, -7, 0 },
+ { 0, -8, 103, 7, 43, -10, 0 },
+ { 0, -12, 92, 7, 61, -13, 0 },
+ { 0, -14, 78, 7, 78, -14, 0 },
+ { 0, -13, 61, 7, 92, -12, 0 },
+ { 0, -10, 43, 7, 103, -8, 0 },
+ { 0, -7, 26, 7, 110, 0, -1 } },
+ .odd = { { -2, 5, 111, 7, 19, -5, 0 },
+ { 0, -4, 106, 7, 34, -8, 0 },
+ { 0, -11, 98, 7, 52, -11, 0 },
+ { 0, -13, 85, 7, 69, -13, 0 },
+ { 0, -13, 69, 7, 85, -13, 0 },
+ { 0, -11, 52, 7, 98, -11, 0 },
+ { 0, -8, 34, 7, 106, -4, 0 },
+ { 0, -5, 19, 7, 111, 5, -2 } } },
+ .ver_phase_arr = {
+ .even = { { -3, 12, 110, 7, 12, -3, 0 },
+ { -1, 0, 110, 7, 26, -7, 0 },
+ { 0, -8, 103, 7, 43, -10, 0 },
+ { 0, -12, 92, 7, 61, -13, 0 },
+ { 0, -14, 78, 7, 78, -14, 0 },
+ { 0, -13, 61, 7, 92, -12, 0 },
+ { 0, -10, 43, 7, 103, -8, 0 },
+ { 0, -7, 26, 7, 110, 0, -1 } },
+ .odd = { { -2, 5, 111, 7, 19, -5, 0 },
+ { 0, -4, 106, 7, 34, -8, 0 },
+ { 0, -11, 98, 7, 52, -11, 0 },
+ { 0, -13, 85, 7, 69, -13, 0 },
+ { 0, -13, 69, 7, 85, -13, 0 },
+ { 0, -11, 52, 7, 98, -11, 0 },
+ { 0, -8, 34, 7, 106, -4, 0 },
+ { 0, -5, 19, 7, 111, 5, -2 } } },
+ .ptrn_arr = { { 0xffff } },
+ .sample_patrn_length = 18,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 5) = 0.864865 */
+ .hor_phase_arr = {
+ .even = { { -5, 14, 110, 7, 14, -5, 0 },
+ { -1, 0, 106, 7, 32, -9, 0 },
+ { 0, -9, 96, 7, 53, -12, 0 },
+ { 0, -13, 81, 7, 73, -13, 0 },
+ { 0, -13, 61, 7, 91, -11, 0 },
+ { 0, -10, 40, 7, 103, -4, -1 },
+ { 0, -6, 21, 7, 108, 8, -3 },
+ { -3, 5, 108, 7, 25, -7, 0 },
+ { 0, -6, 101, 7, 44, -11, 0 },
+ { 0, -12, 88, 7, 65, -13, 0 },
+ { 0, -13, 69, 7, 85, -13, 0 },
+ { 0, -11, 49, 7, 98, -8, 0 },
+ { 0, -8, 28, 7, 108, 2, -2 },
+ { -4, 11, 108, 7, 18, -5, 0 },
+ { -1, -2, 104, 7, 36, -9, 0 },
+ { 0, -10, 93, 7, 57, -12, 0 },
+ { 0, -13, 77, 7, 77, -13, 0 },
+ { 0, -12, 57, 7, 93, -10, 0 },
+ { 0, -9, 36, 7, 104, -2, -1 },
+ { 0, -5, 18, 7, 108, 11, -4 },
+ { -2, 2, 108, 7, 28, -8, 0 },
+ { 0, -8, 98, 7, 49, -11, 0 },
+ { 0, -13, 85, 7, 69, -13, 0 },
+ { 0, -13, 65, 7, 88, -12, 0 },
+ { 0, -11, 44, 7, 101, -6, 0 },
+ { 0, -7, 25, 7, 108, 5, -3 },
+ { -3, 8, 108, 7, 21, -6, 0 },
+ { -1, -4, 103, 7, 40, -10, 0 },
+ { 0, -11, 91, 7, 61, -13, 0 },
+ { 0, -13, 73, 7, 81, -13, 0 },
+ { 0, -12, 53, 7, 96, -9, 0 },
+ { 0, -9, 32, 7, 106, 0, -1 } },
+ .odd = { { -3, 7, 108, 7, 23, -7, 0 },
+ { 0, -5, 101, 7, 42, -10, 0 },
+ { 0, -12, 90, 7, 63, -13, 0 },
+ { 0, -13, 71, 7, 83, -13, 0 },
+ { 0, -12, 51, 7, 97, -8, 0 },
+ { 0, -8, 30, 7, 107, 1, -2 },
+ { -4, 13, 108, 7, 16, -5, 0 },
+ { -1, -1, 105, 7, 34, -9, 0 },
+ { 0, -10, 95, 7, 55, -12, 0 },
+ { 0, -13, 79, 7, 75, -13, 0 },
+ { 0, -13, 59, 7, 93, -11, 0 },
+ { 0, -10, 38, 7, 104, -3, -1 },
+ { 0, -6, 19, 7, 110, 9, -4 },
+ { -2, 4, 106, 7, 27, -7, 0 },
+ { 0, -7, 99, 7, 47, -11, 0 },
+ { 0, -12, 86, 7, 67, -13, 0 },
+ { 0, -13, 67, 7, 86, -12, 0 },
+ { 0, -11, 47, 7, 99, -7, 0 },
+ { 0, -7, 27, 7, 106, 4, -2 },
+ { -4, 9, 110, 7, 19, -6, 0 },
+ { -1, -3, 104, 7, 38, -10, 0 },
+ { 0, -11, 93, 7, 59, -13, 0 },
+ { 0, -13, 75, 7, 79, -13, 0 },
+ { 0, -12, 55, 7, 95, -10, 0 },
+ { 0, -9, 34, 7, 105, -1, -1 },
+ { 0, -5, 16, 7, 108, 13, -4 },
+ { -2, 1, 107, 7, 30, -8, 0 },
+ { 0, -8, 97, 7, 51, -12, 0 },
+ { 0, -13, 83, 7, 71, -13, 0 },
+ { 0, -13, 63, 7, 90, -12, 0 },
+ { 0, -10, 42, 7, 101, -5, 0 },
+ { 0, -7, 23, 7, 108, 7, -3 } } },
+ .ver_phase_arr = {
+ .even = { { -5, 14, 110, 7, 14, -5, 0 },
+ { -1, 0, 106, 7, 32, -9, 0 },
+ { 0, -9, 96, 7, 53, -12, 0 },
+ { 0, -13, 81, 7, 73, -13, 0 },
+ { 0, -13, 61, 7, 91, -11, 0 },
+ { 0, -10, 40, 7, 103, -4, -1 },
+ { 0, -6, 21, 7, 108, 8, -3 },
+ { -3, 5, 108, 7, 25, -7, 0 },
+ { 0, -6, 101, 7, 44, -11, 0 },
+ { 0, -12, 88, 7, 65, -13, 0 },
+ { 0, -13, 69, 7, 85, -13, 0 },
+ { 0, -11, 49, 7, 98, -8, 0 },
+ { 0, -8, 28, 7, 108, 2, -2 },
+ { -4, 11, 108, 7, 18, -5, 0 },
+ { -1, -2, 104, 7, 36, -9, 0 },
+ { 0, -10, 93, 7, 57, -12, 0 },
+ { 0, -13, 77, 7, 77, -13, 0 },
+ { 0, -12, 57, 7, 93, -10, 0 },
+ { 0, -9, 36, 7, 104, -2, -1 },
+ { 0, -5, 18, 7, 108, 11, -4 },
+ { -2, 2, 108, 7, 28, -8, 0 },
+ { 0, -8, 98, 7, 49, -11, 0 },
+ { 0, -13, 85, 7, 69, -13, 0 },
+ { 0, -13, 65, 7, 88, -12, 0 },
+ { 0, -11, 44, 7, 101, -6, 0 },
+ { 0, -7, 25, 7, 108, 5, -3 },
+ { -3, 8, 108, 7, 21, -6, 0 },
+ { -1, -4, 103, 7, 40, -10, 0 },
+ { 0, -11, 91, 7, 61, -13, 0 },
+ { 0, -13, 73, 7, 81, -13, 0 },
+ { 0, -12, 53, 7, 96, -9, 0 },
+ { 0, -9, 32, 7, 106, 0, -1 } },
+ .odd = { { -3, 7, 108, 7, 23, -7, 0 },
+ { 0, -5, 101, 7, 42, -10, 0 },
+ { 0, -12, 90, 7, 63, -13, 0 },
+ { 0, -13, 71, 7, 83, -13, 0 },
+ { 0, -12, 51, 7, 97, -8, 0 },
+ { 0, -8, 30, 7, 107, 1, -2 },
+ { -4, 13, 108, 7, 16, -5, 0 },
+ { -1, -1, 105, 7, 34, -9, 0 },
+ { 0, -10, 95, 7, 55, -12, 0 },
+ { 0, -13, 79, 7, 75, -13, 0 },
+ { 0, -13, 59, 7, 93, -11, 0 },
+ { 0, -10, 38, 7, 104, -3, -1 },
+ { 0, -6, 19, 7, 110, 9, -4 },
+ { -2, 4, 106, 7, 27, -7, 0 },
+ { 0, -7, 99, 7, 47, -11, 0 },
+ { 0, -12, 86, 7, 67, -13, 0 },
+ { 0, -13, 67, 7, 86, -12, 0 },
+ { 0, -11, 47, 7, 99, -7, 0 },
+ { 0, -7, 27, 7, 106, 4, -2 },
+ { -4, 9, 110, 7, 19, -6, 0 },
+ { -1, -3, 104, 7, 38, -10, 0 },
+ { 0, -11, 93, 7, 59, -13, 0 },
+ { 0, -13, 75, 7, 79, -13, 0 },
+ { 0, -12, 55, 7, 95, -10, 0 },
+ { 0, -9, 34, 7, 105, -1, -1 },
+ { 0, -5, 16, 7, 108, 13, -4 },
+ { -2, 1, 107, 7, 30, -8, 0 },
+ { 0, -8, 97, 7, 51, -12, 0 },
+ { 0, -13, 83, 7, 71, -13, 0 },
+ { 0, -13, 63, 7, 90, -12, 0 },
+ { 0, -10, 42, 7, 101, -5, 0 },
+ { 0, -7, 23, 7, 108, 7, -3 } } },
+ .ptrn_arr = { { 0xcfff9fff, 0xf3ffe7ff, 0xff } },
+ .sample_patrn_length = 74,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 6) = 0.842105 */
+ .hor_phase_arr = {
+ .even = { { -6, 17, 106, 7, 17, -6, 0 },
+ { -2, 0, 102, 7, 38, -10, 0 },
+ { 0, -10, 89, 7, 62, -13, 0 },
+ { 0, -13, 69, 7, 83, -11, 0 },
+ { 0, -11, 46, 7, 98, -4, -1 },
+ { 0, -7, 23, 7, 106, 10, -4 },
+ { -3, 5, 104, 7, 31, -9, 0 },
+ { 0, -7, 93, 7, 54, -12, 0 },
+ { 0, -12, 76, 7, 76, -12, 0 },
+ { 0, -12, 54, 7, 93, -7, 0 },
+ { 0, -9, 31, 7, 104, 5, -3 },
+ { -4, 10, 106, 7, 23, -7, 0 },
+ { -1, -4, 98, 7, 46, -11, 0 },
+ { 0, -11, 83, 7, 69, -13, 0 },
+ { 0, -13, 62, 7, 89, -10, 0 },
+ { 0, -10, 38, 7, 102, 0, -2 } },
+ .odd = { { -4, 8, 105, 7, 27, -8, 0 },
+ { 0, -6, 96, 7, 50, -12, 0 },
+ { 0, -12, 80, 7, 73, -13, 0 },
+ { 0, -13, 58, 7, 92, -9, 0 },
+ { 0, -9, 34, 7, 103, 2, -2 },
+ { -5, 13, 107, 7, 20, -7, 0 },
+ { -1, -2, 100, 7, 42, -11, 0 },
+ { 0, -11, 87, 7, 65, -13, 0 },
+ { 0, -13, 65, 7, 87, -11, 0 },
+ { 0, -11, 42, 7, 100, -2, -1 },
+ { 0, -7, 20, 7, 107, 13, -5 },
+ { -2, 2, 103, 7, 34, -9, 0 },
+ { 0, -9, 92, 7, 58, -13, 0 },
+ { 0, -13, 73, 7, 80, -12, 0 },
+ { 0, -12, 50, 7, 96, -6, 0 },
+ { 0, -8, 27, 7, 105, 8, -4 } } },
+ .ver_phase_arr = {
+ .even = { { -6, 17, 106, 7, 17, -6, 0 },
+ { -2, 0, 102, 7, 38, -10, 0 },
+ { 0, -10, 89, 7, 62, -13, 0 },
+ { 0, -13, 69, 7, 83, -11, 0 },
+ { 0, -11, 46, 7, 98, -4, -1 },
+ { 0, -7, 23, 7, 106, 10, -4 },
+ { -3, 5, 104, 7, 31, -9, 0 },
+ { 0, -7, 93, 7, 54, -12, 0 },
+ { 0, -12, 76, 7, 76, -12, 0 },
+ { 0, -12, 54, 7, 93, -7, 0 },
+ { 0, -9, 31, 7, 104, 5, -3 },
+ { -4, 10, 106, 7, 23, -7, 0 },
+ { -1, -4, 98, 7, 46, -11, 0 },
+ { 0, -11, 83, 7, 69, -13, 0 },
+ { 0, -13, 62, 7, 89, -10, 0 },
+ { 0, -10, 38, 7, 102, 0, -2 } },
+ .odd = { { -4, 8, 105, 7, 27, -8, 0 },
+ { 0, -6, 96, 7, 50, -12, 0 },
+ { 0, -12, 80, 7, 73, -13, 0 },
+ { 0, -13, 58, 7, 92, -9, 0 },
+ { 0, -9, 34, 7, 103, 2, -2 },
+ { -5, 13, 107, 7, 20, -7, 0 },
+ { -1, -2, 100, 7, 42, -11, 0 },
+ { 0, -11, 87, 7, 65, -13, 0 },
+ { 0, -13, 65, 7, 87, -11, 0 },
+ { 0, -11, 42, 7, 100, -2, -1 },
+ { 0, -7, 20, 7, 107, 13, -5 },
+ { -2, 2, 103, 7, 34, -9, 0 },
+ { 0, -9, 92, 7, 58, -13, 0 },
+ { 0, -13, 73, 7, 80, -12, 0 },
+ { 0, -12, 50, 7, 96, -6, 0 },
+ { 0, -8, 27, 7, 105, 8, -4 } } },
+ .ptrn_arr = { { 0xfcffe7ff, 0xf } },
+ .sample_patrn_length = 38,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 7) = 0.820513 */
+ .hor_phase_arr = {
+ .even = { { -7, 19, 104, 7, 19, -7, 0 },
+ { -2, 0, 98, 7, 43, -11, 0 },
+ { 0, -10, 81, 7, 69, -12, 0 },
+ { 0, -12, 58, 7, 89, -7, 0 },
+ { 0, -10, 32, 7, 103, 7, -4 },
+ { -5, 10, 103, 7, 29, -9, 0 },
+ { -1, -6, 93, 7, 54, -12, 0 },
+ { 0, -12, 72, 7, 79, -11, 0 },
+ { 0, -12, 47, 7, 97, -2, -2 },
+ { 0, -8, 22, 7, 104, 16, -6 },
+ { -3, 2, 100, 7, 40, -11, 0 },
+ { 0, -9, 84, 7, 65, -12, 0 },
+ { 0, -13, 62, 7, 87, -8, 0 },
+ { 0, -10, 36, 7, 100, 5, -3 },
+ { -5, 13, 103, 7, 25, -8, 0 },
+ { -1, -4, 94, 7, 51, -12, 0 },
+ { 0, -12, 76, 7, 76, -12, 0 },
+ { 0, -12, 51, 7, 94, -4, -1 },
+ { 0, -8, 25, 7, 103, 13, -5 },
+ { -3, 5, 100, 7, 36, -10, 0 },
+ { 0, -8, 87, 7, 62, -13, 0 },
+ { 0, -12, 65, 7, 84, -9, 0 },
+ { 0, -11, 40, 7, 100, 2, -3 },
+ { -6, 16, 104, 7, 22, -8, 0 },
+ { -2, -2, 97, 7, 47, -12, 0 },
+ { 0, -11, 79, 7, 72, -12, 0 },
+ { 0, -12, 54, 7, 93, -6, -1 },
+ { 0, -9, 29, 7, 103, 10, -5 },
+ { -4, 7, 103, 7, 32, -10, 0 },
+ { 0, -7, 89, 7, 58, -12, 0 },
+ { 0, -12, 69, 7, 81, -10, 0 },
+ { 0, -11, 43, 7, 98, 0, -2 } },
+ .odd = { { -4, 9, 101, 7, 31, -9, 0 },
+ { -1, -6, 91, 7, 56, -12, 0 },
+ { 0, -12, 71, 7, 80, -11, 0 },
+ { 0, -11, 45, 7, 97, -1, -2 },
+ { 0, -7, 20, 7, 105, 17, -7 },
+ { -3, 1, 100, 7, 41, -11, 0 },
+ { 0, -10, 83, 7, 67, -12, 0 },
+ { 0, -13, 60, 7, 89, -8, 0 },
+ { 0, -10, 34, 7, 102, 6, -4 },
+ { -5, 11, 104, 7, 27, -9, 0 },
+ { -1, -5, 94, 7, 52, -12, 0 },
+ { 0, -12, 74, 7, 77, -11, 0 },
+ { 0, -12, 49, 7, 95, -3, -1 },
+ { 0, -8, 24, 7, 104, 14, -6 },
+ { -3, 3, 100, 7, 38, -10, 0 },
+ { 0, -9, 87, 7, 63, -13, 0 },
+ { 0, -13, 63, 7, 87, -9, 0 },
+ { 0, -10, 38, 7, 100, 3, -3 },
+ { -6, 14, 104, 7, 24, -8, 0 },
+ { -1, -3, 95, 7, 49, -12, 0 },
+ { 0, -11, 77, 7, 74, -12, 0 },
+ { 0, -12, 52, 7, 94, -5, -1 },
+ { 0, -9, 27, 7, 104, 11, -5 },
+ { -4, 6, 102, 7, 34, -10, 0 },
+ { 0, -8, 89, 7, 60, -13, 0 },
+ { 0, -12, 67, 7, 83, -10, 0 },
+ { 0, -11, 41, 7, 100, 1, -3 },
+ { -7, 17, 105, 7, 20, -7, 0 },
+ { -2, -1, 97, 7, 45, -11, 0 },
+ { 0, -11, 80, 7, 71, -12, 0 },
+ { 0, -12, 56, 7, 91, -6, -1 },
+ { 0, -9, 31, 7, 101, 9, -4 } } },
+ .ver_phase_arr = {
+ .even = { { -7, 19, 104, 7, 19, -7, 0 },
+ { -2, 0, 98, 7, 43, -11, 0 },
+ { 0, -10, 81, 7, 69, -12, 0 },
+ { 0, -12, 58, 7, 89, -7, 0 },
+ { 0, -10, 32, 7, 103, 7, -4 },
+ { -5, 10, 103, 7, 29, -9, 0 },
+ { -1, -6, 93, 7, 54, -12, 0 },
+ { 0, -12, 72, 7, 79, -11, 0 },
+ { 0, -12, 47, 7, 97, -2, -2 },
+ { 0, -8, 22, 7, 104, 16, -6 },
+ { -3, 2, 100, 7, 40, -11, 0 },
+ { 0, -9, 84, 7, 65, -12, 0 },
+ { 0, -13, 62, 7, 87, -8, 0 },
+ { 0, -10, 36, 7, 100, 5, -3 },
+ { -5, 13, 103, 7, 25, -8, 0 },
+ { -1, -4, 94, 7, 51, -12, 0 },
+ { 0, -12, 76, 7, 76, -12, 0 },
+ { 0, -12, 51, 7, 94, -4, -1 },
+ { 0, -8, 25, 7, 103, 13, -5 },
+ { -3, 5, 100, 7, 36, -10, 0 },
+ { 0, -8, 87, 7, 62, -13, 0 },
+ { 0, -12, 65, 7, 84, -9, 0 },
+ { 0, -11, 40, 7, 100, 2, -3 },
+ { -6, 16, 104, 7, 22, -8, 0 },
+ { -2, -2, 97, 7, 47, -12, 0 },
+ { 0, -11, 79, 7, 72, -12, 0 },
+ { 0, -12, 54, 7, 93, -6, -1 },
+ { 0, -9, 29, 7, 103, 10, -5 },
+ { -4, 7, 103, 7, 32, -10, 0 },
+ { 0, -7, 89, 7, 58, -12, 0 },
+ { 0, -12, 69, 7, 81, -10, 0 },
+ { 0, -11, 43, 7, 98, 0, -2 } },
+ .odd = { { -4, 9, 101, 7, 31, -9, 0 },
+ { -1, -6, 91, 7, 56, -12, 0 },
+ { 0, -12, 71, 7, 80, -11, 0 },
+ { 0, -11, 45, 7, 97, -1, -2 },
+ { 0, -7, 20, 7, 105, 17, -7 },
+ { -3, 1, 100, 7, 41, -11, 0 },
+ { 0, -10, 83, 7, 67, -12, 0 },
+ { 0, -13, 60, 7, 89, -8, 0 },
+ { 0, -10, 34, 7, 102, 6, -4 },
+ { -5, 11, 104, 7, 27, -9, 0 },
+ { -1, -5, 94, 7, 52, -12, 0 },
+ { 0, -12, 74, 7, 77, -11, 0 },
+ { 0, -12, 49, 7, 95, -3, -1 },
+ { 0, -8, 24, 7, 104, 14, -6 },
+ { -3, 3, 100, 7, 38, -10, 0 },
+ { 0, -9, 87, 7, 63, -13, 0 },
+ { 0, -13, 63, 7, 87, -9, 0 },
+ { 0, -10, 38, 7, 100, 3, -3 },
+ { -6, 14, 104, 7, 24, -8, 0 },
+ { -1, -3, 95, 7, 49, -12, 0 },
+ { 0, -11, 77, 7, 74, -12, 0 },
+ { 0, -12, 52, 7, 94, -5, -1 },
+ { 0, -9, 27, 7, 104, 11, -5 },
+ { -4, 6, 102, 7, 34, -10, 0 },
+ { 0, -8, 89, 7, 60, -13, 0 },
+ { 0, -12, 67, 7, 83, -10, 0 },
+ { 0, -11, 41, 7, 100, 1, -3 },
+ { -7, 17, 105, 7, 20, -7, 0 },
+ { -2, -1, 97, 7, 45, -11, 0 },
+ { 0, -11, 80, 7, 71, -12, 0 },
+ { 0, -12, 56, 7, 91, -6, -1 },
+ { 0, -9, 31, 7, 101, 9, -4 } } },
+ .ptrn_arr = { { 0xff9ff3ff, 0xff3fe7fc, 0xff9 } },
+ .sample_patrn_length = 78,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 8) = 0.8 */
+ .hor_phase_arr = {
+ .even = { { -8, 21, 102, 7, 21, -8, 0 },
+ { -3, 0, 95, 7, 48, -12, 0 },
+ { 0, -11, 75, 7, 75, -11, 0 },
+ { 0, -12, 48, 7, 95, 0, -3 } },
+ .odd = { { -5, 9, 100, 7, 34, -10, 0 },
+ { -1, -7, 86, 7, 62, -12, 0 },
+ { 0, -12, 62, 7, 86, -7, -1 },
+ { 0, -10, 34, 7, 100, 9, -5 } } },
+ .ver_phase_arr = {
+ .even = { { -8, 21, 102, 7, 21, -8, 0 },
+ { -3, 0, 95, 7, 48, -12, 0 },
+ { 0, -11, 75, 7, 75, -11, 0 },
+ { 0, -12, 48, 7, 95, 0, -3 } },
+ .odd = { { -5, 9, 100, 7, 34, -10, 0 },
+ { -1, -7, 86, 7, 62, -12, 0 },
+ { 0, -12, 62, 7, 86, -7, -1 },
+ { 0, -10, 34, 7, 100, 9, -5 } } },
+ .ptrn_arr = { { 0xff } },
+ .sample_patrn_length = 10,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 9) = 0.780488 */
+ .hor_phase_arr = {
+ .even = { { -9, 23, 100, 7, 23, -9, 0 },
+ { -3, 0, 91, 7, 52, -12, 0 },
+ { 0, -11, 68, 7, 80, -8, -1 },
+ { 0, -11, 39, 7, 96, 9, -5 },
+ { -6, 12, 98, 7, 35, -11, 0 },
+ { -1, -6, 81, 7, 65, -11, 0 },
+ { 0, -12, 55, 7, 89, -2, -2 },
+ { 0, -9, 26, 7, 99, 20, -8 },
+ { -4, 2, 93, 7, 49, -12, 0 },
+ { 0, -10, 71, 7, 76, -9, 0 },
+ { 0, -11, 42, 7, 95, 7, -5 },
+ { -7, 14, 99, 7, 32, -10, 0 },
+ { -1, -5, 84, 7, 62, -12, 0 },
+ { 0, -12, 59, 7, 87, -4, -2 },
+ { 0, -10, 29, 7, 99, 17, -7 },
+ { -4, 4, 95, 7, 45, -12, 0 },
+ { 0, -9, 72, 7, 74, -9, 0 },
+ { 0, -12, 45, 7, 95, 4, -4 },
+ { -7, 17, 99, 7, 29, -10, 0 },
+ { -2, -4, 87, 7, 59, -12, 0 },
+ { 0, -12, 62, 7, 84, -5, -1 },
+ { 0, -10, 32, 7, 99, 14, -7 },
+ { -5, 7, 95, 7, 42, -11, 0 },
+ { 0, -9, 76, 7, 71, -10, 0 },
+ { 0, -12, 49, 7, 93, 2, -4 },
+ { -8, 20, 99, 7, 26, -9, 0 },
+ { -2, -2, 89, 7, 55, -12, 0 },
+ { 0, -11, 65, 7, 81, -6, -1 },
+ { 0, -11, 35, 7, 98, 12, -6 },
+ { -5, 9, 96, 7, 39, -11, 0 },
+ { -1, -8, 80, 7, 68, -11, 0 },
+ { 0, -12, 52, 7, 91, 0, -3 } },
+ .odd = { { -6, 10, 98, 7, 37, -11, 0 },
+ { -1, -7, 81, 7, 66, -11, 0 },
+ { 0, -12, 54, 7, 90, -1, -3 },
+ { 0, -9, 24, 7, 100, 21, -8 },
+ { -3, 1, 92, 7, 50, -12, 0 },
+ { 0, -10, 69, 7, 78, -8, -1 },
+ { 0, -11, 40, 7, 96, 8, -5 },
+ { -6, 13, 97, 7, 34, -10, 0 },
+ { -1, -6, 83, 7, 63, -11, 0 },
+ { 0, -12, 57, 7, 88, -3, -2 },
+ { 0, -9, 27, 7, 100, 18, -8 },
+ { -4, 3, 94, 7, 47, -12, 0 },
+ { 0, -10, 72, 7, 75, -9, 0 },
+ { 0, -11, 44, 7, 95, 5, -5 },
+ { -7, 16, 98, 7, 31, -10, 0 },
+ { -2, -4, 86, 7, 60, -12, 0 },
+ { 0, -12, 60, 7, 86, -4, -2 },
+ { 0, -10, 31, 7, 98, 16, -7 },
+ { -5, 5, 95, 7, 44, -11, 0 },
+ { 0, -9, 75, 7, 72, -10, 0 },
+ { 0, -12, 47, 7, 94, 3, -4 },
+ { -8, 18, 100, 7, 27, -9, 0 },
+ { -2, -3, 88, 7, 57, -12, 0 },
+ { 0, -11, 63, 7, 83, -6, -1 },
+ { 0, -10, 34, 7, 97, 13, -6 },
+ { -5, 8, 96, 7, 40, -11, 0 },
+ { -1, -8, 78, 7, 69, -10, 0 },
+ { 0, -12, 50, 7, 92, 1, -3 },
+ { -8, 21, 100, 7, 24, -9, 0 },
+ { -3, -1, 90, 7, 54, -12, 0 },
+ { 0, -11, 66, 7, 81, -7, -1 },
+ { 0, -11, 37, 7, 98, 10, -6 } } },
+ .ver_phase_arr = {
+ .even = { { -9, 23, 100, 7, 23, -9, 0 },
+ { -3, 0, 91, 7, 52, -12, 0 },
+ { 0, -11, 68, 7, 80, -8, -1 },
+ { 0, -11, 39, 7, 96, 9, -5 },
+ { -6, 12, 98, 7, 35, -11, 0 },
+ { -1, -6, 81, 7, 65, -11, 0 },
+ { 0, -12, 55, 7, 89, -2, -2 },
+ { 0, -9, 26, 7, 99, 20, -8 },
+ { -4, 2, 93, 7, 49, -12, 0 },
+ { 0, -10, 71, 7, 76, -9, 0 },
+ { 0, -11, 42, 7, 95, 7, -5 },
+ { -7, 14, 99, 7, 32, -10, 0 },
+ { -1, -5, 84, 7, 62, -12, 0 },
+ { 0, -12, 59, 7, 87, -4, -2 },
+ { 0, -10, 29, 7, 99, 17, -7 },
+ { -4, 4, 95, 7, 45, -12, 0 },
+ { 0, -9, 72, 7, 74, -9, 0 },
+ { 0, -12, 45, 7, 95, 4, -4 },
+ { -7, 17, 99, 7, 29, -10, 0 },
+ { -2, -4, 87, 7, 59, -12, 0 },
+ { 0, -12, 62, 7, 84, -5, -1 },
+ { 0, -10, 32, 7, 99, 14, -7 },
+ { -5, 7, 95, 7, 42, -11, 0 },
+ { 0, -9, 76, 7, 71, -10, 0 },
+ { 0, -12, 49, 7, 93, 2, -4 },
+ { -8, 20, 99, 7, 26, -9, 0 },
+ { -2, -2, 89, 7, 55, -12, 0 },
+ { 0, -11, 65, 7, 81, -6, -1 },
+ { 0, -11, 35, 7, 98, 12, -6 },
+ { -5, 9, 96, 7, 39, -11, 0 },
+ { -1, -8, 80, 7, 68, -11, 0 },
+ { 0, -12, 52, 7, 91, 0, -3 } },
+ .odd = { { -6, 10, 98, 7, 37, -11, 0 },
+ { -1, -7, 81, 7, 66, -11, 0 },
+ { 0, -12, 54, 7, 90, -1, -3 },
+ { 0, -9, 24, 7, 100, 21, -8 },
+ { -3, 1, 92, 7, 50, -12, 0 },
+ { 0, -10, 69, 7, 78, -8, -1 },
+ { 0, -11, 40, 7, 96, 8, -5 },
+ { -6, 13, 97, 7, 34, -10, 0 },
+ { -1, -6, 83, 7, 63, -11, 0 },
+ { 0, -12, 57, 7, 88, -3, -2 },
+ { 0, -9, 27, 7, 100, 18, -8 },
+ { -4, 3, 94, 7, 47, -12, 0 },
+ { 0, -10, 72, 7, 75, -9, 0 },
+ { 0, -11, 44, 7, 95, 5, -5 },
+ { -7, 16, 98, 7, 31, -10, 0 },
+ { -2, -4, 86, 7, 60, -12, 0 },
+ { 0, -12, 60, 7, 86, -4, -2 },
+ { 0, -10, 31, 7, 98, 16, -7 },
+ { -5, 5, 95, 7, 44, -11, 0 },
+ { 0, -9, 75, 7, 72, -10, 0 },
+ { 0, -12, 47, 7, 94, 3, -4 },
+ { -8, 18, 100, 7, 27, -9, 0 },
+ { -2, -3, 88, 7, 57, -12, 0 },
+ { 0, -11, 63, 7, 83, -6, -1 },
+ { 0, -10, 34, 7, 97, 13, -6 },
+ { -5, 8, 96, 7, 40, -11, 0 },
+ { -1, -8, 78, 7, 69, -10, 0 },
+ { 0, -12, 50, 7, 92, 1, -3 },
+ { -8, 21, 100, 7, 24, -9, 0 },
+ { -3, -1, 90, 7, 54, -12, 0 },
+ { 0, -11, 66, 7, 81, -7, -1 },
+ { 0, -11, 37, 7, 98, 10, -6 } } },
+ .ptrn_arr = { { 0xf3f9fcff, 0x3f9fcfe7, 0xfe7f } },
+ .sample_patrn_length = 82,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 10) = 0.761905 */
+ .hor_phase_arr = {
+ .even = { { -9, 25, 96, 7, 25, -9, 0 },
+ { -3, 0, 86, 7, 56, -11, 0 },
+ { 0, -11, 62, 7, 82, -3, -2 },
+ { 0, -10, 31, 7, 96, 19, -8 },
+ { -5, 4, 92, 7, 49, -12, 0 },
+ { 0, -10, 67, 7, 78, -6, -1 },
+ { 0, -11, 37, 7, 95, 14, -7 },
+ { -6, 9, 93, 7, 43, -11, 0 },
+ { -1, -8, 73, 7, 73, -8, -1 },
+ { 0, -11, 43, 7, 93, 9, -6 },
+ { -7, 14, 95, 7, 37, -11, 0 },
+ { -1, -6, 78, 7, 67, -10, 0 },
+ { 0, -12, 49, 7, 92, 4, -5 },
+ { -8, 19, 96, 7, 31, -10, 0 },
+ { -2, -3, 82, 7, 62, -11, 0 },
+ { 0, -11, 56, 7, 86, 0, -3 } },
+ .odd = { { -6, 11, 94, 7, 40, -11, 0 },
+ { -1, -7, 75, 7, 70, -9, 0 },
+ { 0, -12, 46, 7, 93, 6, -5 },
+ { -8, 16, 97, 7, 34, -11, 0 },
+ { -2, -5, 81, 7, 64, -10, 0 },
+ { 0, -12, 53, 7, 89, 2, -4 },
+ { -9, 22, 97, 7, 28, -10, 0 },
+ { -3, -2, 85, 7, 59, -11, 0 },
+ { 0, -11, 59, 7, 85, -2, -3 },
+ { 0, -10, 28, 7, 97, 22, -9 },
+ { -4, 2, 89, 7, 53, -12, 0 },
+ { 0, -10, 64, 7, 81, -5, -2 },
+ { 0, -11, 34, 7, 97, 16, -8 },
+ { -5, 6, 93, 7, 46, -12, 0 },
+ { 0, -9, 70, 7, 75, -7, -1 },
+ { 0, -11, 40, 7, 94, 11, -6 } } },
+ .ver_phase_arr = {
+ .even = { { -9, 25, 96, 7, 25, -9, 0 },
+ { -3, 0, 86, 7, 56, -11, 0 },
+ { 0, -11, 62, 7, 82, -3, -2 },
+ { 0, -10, 31, 7, 96, 19, -8 },
+ { -5, 4, 92, 7, 49, -12, 0 },
+ { 0, -10, 67, 7, 78, -6, -1 },
+ { 0, -11, 37, 7, 95, 14, -7 },
+ { -6, 9, 93, 7, 43, -11, 0 },
+ { -1, -8, 73, 7, 73, -8, -1 },
+ { 0, -11, 43, 7, 93, 9, -6 },
+ { -7, 14, 95, 7, 37, -11, 0 },
+ { -1, -6, 78, 7, 67, -10, 0 },
+ { 0, -12, 49, 7, 92, 4, -5 },
+ { -8, 19, 96, 7, 31, -10, 0 },
+ { -2, -3, 82, 7, 62, -11, 0 },
+ { 0, -11, 56, 7, 86, 0, -3 } },
+ .odd = { { -6, 11, 94, 7, 40, -11, 0 },
+ { -1, -7, 75, 7, 70, -9, 0 },
+ { 0, -12, 46, 7, 93, 6, -5 },
+ { -8, 16, 97, 7, 34, -11, 0 },
+ { -2, -5, 81, 7, 64, -10, 0 },
+ { 0, -12, 53, 7, 89, 2, -4 },
+ { -9, 22, 97, 7, 28, -10, 0 },
+ { -3, -2, 85, 7, 59, -11, 0 },
+ { 0, -11, 59, 7, 85, -2, -3 },
+ { 0, -10, 28, 7, 97, 22, -9 },
+ { -4, 2, 89, 7, 53, -12, 0 },
+ { 0, -10, 64, 7, 81, -5, -2 },
+ { 0, -11, 34, 7, 97, 16, -8 },
+ { -5, 6, 93, 7, 46, -12, 0 },
+ { 0, -9, 70, 7, 75, -7, -1 },
+ { 0, -11, 40, 7, 94, 11, -6 } } },
+ .ptrn_arr = { { 0xfcfe7e7f, 0xfc } },
+ .sample_patrn_length = 42,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 11) = 0.744186 */
+ .hor_phase_arr = {
+ .even = { { -10, 26, 96, 7, 26, -10, 0 },
+ { -4, 0, 83, 7, 59, -10, 0 },
+ { 0, -11, 56, 7, 85, 2, -4 },
+ { -9, 23, 95, 7, 29, -10, 0 },
+ { -3, -2, 82, 7, 61, -10, 0 },
+ { 0, -11, 53, 7, 87, 4, -5 },
+ { -9, 21, 94, 7, 32, -10, 0 },
+ { -3, -3, 79, 7, 64, -9, 0 },
+ { 0, -11, 50, 7, 88, 6, -5 },
+ { -8, 18, 94, 7, 35, -11, 0 },
+ { -2, -5, 78, 7, 67, -9, -1 },
+ { 0, -11, 47, 7, 90, 8, -6 },
+ { -8, 15, 94, 7, 38, -11, 0 },
+ { -2, -6, 75, 7, 70, -8, -1 },
+ { 0, -11, 44, 7, 92, 10, -7 },
+ { -7, 13, 92, 7, 41, -11, 0 },
+ { -1, -7, 72, 7, 72, -7, -1 },
+ { 0, -11, 41, 7, 92, 13, -7 },
+ { -7, 10, 92, 7, 44, -11, 0 },
+ { -1, -8, 70, 7, 75, -6, -2 },
+ { 0, -11, 38, 7, 94, 15, -8 },
+ { -6, 8, 90, 7, 47, -11, 0 },
+ { -1, -9, 67, 7, 78, -5, -2 },
+ { 0, -11, 35, 7, 94, 18, -8 },
+ { -5, 6, 88, 7, 50, -11, 0 },
+ { 0, -9, 64, 7, 79, -3, -3 },
+ { 0, -10, 32, 7, 94, 21, -9 },
+ { -5, 4, 87, 7, 53, -11, 0 },
+ { 0, -10, 61, 7, 82, -2, -3 },
+ { 0, -10, 29, 7, 95, 23, -9 },
+ { -4, 2, 85, 7, 56, -11, 0 },
+ { 0, -10, 59, 7, 83, 0, -4 } },
+ .odd = { { -7, 12, 92, 7, 42, -11, 0 },
+ { -1, -7, 71, 7, 72, -6, -1 },
+ { 0, -11, 39, 7, 93, 14, -7 },
+ { -6, 9, 91, 7, 45, -11, 0 },
+ { -1, -8, 68, 7, 76, -5, -2 },
+ { 0, -11, 36, 7, 94, 17, -8 },
+ { -6, 7, 90, 7, 48, -11, 0 },
+ { 0, -9, 66, 7, 77, -4, -2 },
+ { 0, -11, 33, 7, 96, 19, -9 },
+ { -5, 5, 88, 7, 51, -11, 0 },
+ { 0, -10, 63, 7, 80, -2, -3 },
+ { 0, -10, 31, 7, 94, 22, -9 },
+ { -5, 3, 87, 7, 54, -11, 0 },
+ { 0, -10, 60, 7, 82, -1, -3 },
+ { 0, -10, 28, 7, 94, 25, -9 },
+ { -4, 1, 85, 7, 57, -11, 0 },
+ { 0, -11, 57, 7, 85, 1, -4 },
+ { -9, 25, 94, 7, 28, -10, 0 },
+ { -3, -1, 82, 7, 60, -10, 0 },
+ { 0, -11, 54, 7, 87, 3, -5 },
+ { -9, 22, 94, 7, 31, -10, 0 },
+ { -3, -2, 80, 7, 63, -10, 0 },
+ { 0, -11, 51, 7, 88, 5, -5 },
+ { -9, 19, 96, 7, 33, -11, 0 },
+ { -2, -4, 77, 7, 66, -9, 0 },
+ { 0, -11, 48, 7, 90, 7, -6 },
+ { -8, 17, 94, 7, 36, -11, 0 },
+ { -2, -5, 76, 7, 68, -8, -1 },
+ { 0, -11, 45, 7, 91, 9, -6 },
+ { -7, 14, 93, 7, 39, -11, 0 },
+ { -1, -6, 72, 7, 71, -7, -1 },
+ { 0, -11, 42, 7, 92, 12, -7 } } },
+ .ver_phase_arr = {
+ .even = { { -10, 26, 96, 7, 26, -10, 0 },
+ { -4, 0, 83, 7, 59, -10, 0 },
+ { 0, -11, 56, 7, 85, 2, -4 },
+ { -9, 23, 95, 7, 29, -10, 0 },
+ { -3, -2, 82, 7, 61, -10, 0 },
+ { 0, -11, 53, 7, 87, 4, -5 },
+ { -9, 21, 94, 7, 32, -10, 0 },
+ { -3, -3, 79, 7, 64, -9, 0 },
+ { 0, -11, 50, 7, 88, 6, -5 },
+ { -8, 18, 94, 7, 35, -11, 0 },
+ { -2, -5, 78, 7, 67, -9, -1 },
+ { 0, -11, 47, 7, 90, 8, -6 },
+ { -8, 15, 94, 7, 38, -11, 0 },
+ { -2, -6, 75, 7, 70, -8, -1 },
+ { 0, -11, 44, 7, 92, 10, -7 },
+ { -7, 13, 92, 7, 41, -11, 0 },
+ { -1, -7, 72, 7, 72, -7, -1 },
+ { 0, -11, 41, 7, 92, 13, -7 },
+ { -7, 10, 92, 7, 44, -11, 0 },
+ { -1, -8, 70, 7, 75, -6, -2 },
+ { 0, -11, 38, 7, 94, 15, -8 },
+ { -6, 8, 90, 7, 47, -11, 0 },
+ { -1, -9, 67, 7, 78, -5, -2 },
+ { 0, -11, 35, 7, 94, 18, -8 },
+ { -5, 6, 88, 7, 50, -11, 0 },
+ { 0, -9, 64, 7, 79, -3, -3 },
+ { 0, -10, 32, 7, 94, 21, -9 },
+ { -5, 4, 87, 7, 53, -11, 0 },
+ { 0, -10, 61, 7, 82, -2, -3 },
+ { 0, -10, 29, 7, 95, 23, -9 },
+ { -4, 2, 85, 7, 56, -11, 0 },
+ { 0, -10, 59, 7, 83, 0, -4 } },
+ .odd = { { -7, 12, 92, 7, 42, -11, 0 },
+ { -1, -7, 71, 7, 72, -6, -1 },
+ { 0, -11, 39, 7, 93, 14, -7 },
+ { -6, 9, 91, 7, 45, -11, 0 },
+ { -1, -8, 68, 7, 76, -5, -2 },
+ { 0, -11, 36, 7, 94, 17, -8 },
+ { -6, 7, 90, 7, 48, -11, 0 },
+ { 0, -9, 66, 7, 77, -4, -2 },
+ { 0, -11, 33, 7, 96, 19, -9 },
+ { -5, 5, 88, 7, 51, -11, 0 },
+ { 0, -10, 63, 7, 80, -2, -3 },
+ { 0, -10, 31, 7, 94, 22, -9 },
+ { -5, 3, 87, 7, 54, -11, 0 },
+ { 0, -10, 60, 7, 82, -1, -3 },
+ { 0, -10, 28, 7, 94, 25, -9 },
+ { -4, 1, 85, 7, 57, -11, 0 },
+ { 0, -11, 57, 7, 85, 1, -4 },
+ { -9, 25, 94, 7, 28, -10, 0 },
+ { -3, -1, 82, 7, 60, -10, 0 },
+ { 0, -11, 54, 7, 87, 3, -5 },
+ { -9, 22, 94, 7, 31, -10, 0 },
+ { -3, -2, 80, 7, 63, -10, 0 },
+ { 0, -11, 51, 7, 88, 5, -5 },
+ { -9, 19, 96, 7, 33, -11, 0 },
+ { -2, -4, 77, 7, 66, -9, 0 },
+ { 0, -11, 48, 7, 90, 7, -6 },
+ { -8, 17, 94, 7, 36, -11, 0 },
+ { -2, -5, 76, 7, 68, -8, -1 },
+ { 0, -11, 45, 7, 91, 9, -6 },
+ { -7, 14, 93, 7, 39, -11, 0 },
+ { -1, -6, 72, 7, 71, -7, -1 },
+ { 0, -11, 42, 7, 92, 12, -7 } } },
+ .ptrn_arr = { { 0x3f3f3f3f, 0x9f9f9f3f, 0xf9f9f } },
+ .sample_patrn_length = 86,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 12) = 0.727273 */
+ .hor_phase_arr = {
+ .even = { { -10, 28, 92, 7, 28, -10, 0 },
+ { -4, 0, 81, 7, 61, -9, -1 },
+ { 0, -11, 50, 7, 87, 8, -6 },
+ { -8, 17, 91, 7, 39, -11, 0 },
+ { -2, -6, 72, 7, 72, -6, -2 },
+ { 0, -11, 39, 7, 91, 17, -8 },
+ { -6, 8, 87, 7, 50, -11, 0 },
+ { -1, -9, 61, 7, 81, 0, -4 } },
+ .odd = { { -7, 12, 89, 7, 45, -11, 0 },
+ { -1, -8, 67, 7, 76, -3, -3 },
+ { 0, -11, 33, 7, 93, 22, -9 },
+ { -5, 4, 83, 7, 56, -10, 0 },
+ { 0, -10, 56, 7, 83, 4, -5 },
+ { -9, 22, 93, 7, 33, -11, 0 },
+ { -3, -3, 76, 7, 67, -8, -1 },
+ { 0, -11, 45, 7, 89, 12, -7 } } },
+ .ver_phase_arr = {
+ .even = { { -10, 28, 92, 7, 28, -10, 0 },
+ { -4, 0, 81, 7, 61, -9, -1 },
+ { 0, -11, 50, 7, 87, 8, -6 },
+ { -8, 17, 91, 7, 39, -11, 0 },
+ { -2, -6, 72, 7, 72, -6, -2 },
+ { 0, -11, 39, 7, 91, 17, -8 },
+ { -6, 8, 87, 7, 50, -11, 0 },
+ { -1, -9, 61, 7, 81, 0, -4 } },
+ .odd = { { -7, 12, 89, 7, 45, -11, 0 },
+ { -1, -8, 67, 7, 76, -3, -3 },
+ { 0, -11, 33, 7, 93, 22, -9 },
+ { -5, 4, 83, 7, 56, -10, 0 },
+ { 0, -10, 56, 7, 83, 4, -5 },
+ { -9, 22, 93, 7, 33, -11, 0 },
+ { -3, -3, 76, 7, 67, -8, -1 },
+ { 0, -11, 45, 7, 89, 12, -7 } } },
+ .ptrn_arr = { { 0xf9f3f } },
+ .sample_patrn_length = 22,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 13) = 0.711111 */
+ .hor_phase_arr = {
+ .even = { { -10, 29, 90, 7, 29, -10, 0 },
+ { -4, 0, 76, 7, 64, -7, -1 },
+ { 0, -11, 45, 7, 88, 14, -8 },
+ { -7, 12, 85, 7, 48, -10, 0 },
+ { -1, -8, 61, 7, 79, 2, -5 },
+ { -10, 26, 90, 7, 32, -10, 0 },
+ { -4, -2, 76, 7, 66, -6, -2 },
+ { 0, -11, 42, 7, 89, 16, -8 },
+ { -7, 10, 84, 7, 51, -10, 0 },
+ { -1, -9, 59, 7, 81, 3, -5 },
+ { -10, 24, 91, 7, 34, -11, 0 },
+ { -3, -3, 72, 7, 69, -5, -2 },
+ { 0, -11, 40, 7, 89, 19, -9 },
+ { -6, 7, 84, 7, 53, -10, 0 },
+ { -1, -9, 56, 7, 83, 5, -6 },
+ { -9, 21, 90, 7, 37, -11, 0 },
+ { -3, -4, 71, 7, 71, -4, -3 },
+ { 0, -11, 37, 7, 90, 21, -9 },
+ { -6, 5, 83, 7, 56, -9, -1 },
+ { 0, -10, 53, 7, 84, 7, -6 },
+ { -9, 19, 89, 7, 40, -11, 0 },
+ { -2, -5, 69, 7, 72, -3, -3 },
+ { 0, -11, 34, 7, 91, 24, -10 },
+ { -5, 3, 81, 7, 59, -9, -1 },
+ { 0, -10, 51, 7, 84, 10, -7 },
+ { -8, 16, 89, 7, 42, -11, 0 },
+ { -2, -6, 66, 7, 76, -2, -4 },
+ { 0, -10, 32, 7, 90, 26, -10 },
+ { -5, 2, 79, 7, 61, -8, -1 },
+ { 0, -10, 48, 7, 85, 12, -7 },
+ { -8, 14, 88, 7, 45, -11, 0 },
+ { -1, -7, 64, 7, 76, 0, -4 } },
+ .odd = { { -8, 13, 88, 7, 46, -11, 0 },
+ { -1, -8, 63, 7, 78, 1, -5 },
+ { -10, 28, 90, 7, 30, -10, 0 },
+ { -4, -1, 77, 7, 65, -7, -2 },
+ { 0, -11, 44, 7, 88, 15, -8 },
+ { -7, 11, 85, 7, 49, -10, 0 },
+ { -1, -8, 60, 7, 79, 3, -5 },
+ { -10, 25, 91, 7, 33, -11, 0 },
+ { -4, -2, 74, 7, 68, -6, -2 },
+ { 0, -11, 41, 7, 89, 18, -9 },
+ { -7, 8, 85, 7, 52, -10, 0 },
+ { -1, -9, 57, 7, 83, 4, -6 },
+ { -9, 22, 90, 7, 36, -11, 0 },
+ { -3, -4, 73, 7, 70, -5, -3 },
+ { 0, -11, 38, 7, 90, 20, -9 },
+ { -6, 6, 83, 7, 55, -10, 0 },
+ { 0, -10, 55, 7, 83, 6, -6 },
+ { -9, 20, 90, 7, 38, -11, 0 },
+ { -3, -5, 70, 7, 73, -4, -3 },
+ { 0, -11, 36, 7, 90, 22, -9 },
+ { -6, 4, 83, 7, 57, -9, -1 },
+ { 0, -10, 52, 7, 85, 8, -7 },
+ { -9, 18, 89, 7, 41, -11, 0 },
+ { -2, -6, 68, 7, 74, -2, -4 },
+ { 0, -11, 33, 7, 91, 25, -10 },
+ { -5, 3, 79, 7, 60, -8, -1 },
+ { 0, -10, 49, 7, 85, 11, -7 },
+ { -8, 15, 88, 7, 44, -11, 0 },
+ { -2, -7, 65, 7, 77, -1, -4 },
+ { 0, -10, 30, 7, 90, 28, -10 },
+ { -5, 1, 78, 7, 63, -8, -1 },
+ { 0, -11, 46, 7, 88, 13, -8 } } },
+ .ver_phase_arr = {
+ .even = { { -10, 29, 90, 7, 29, -10, 0 },
+ { -4, 0, 76, 7, 64, -7, -1 },
+ { 0, -11, 45, 7, 88, 14, -8 },
+ { -7, 12, 85, 7, 48, -10, 0 },
+ { -1, -8, 61, 7, 79, 2, -5 },
+ { -10, 26, 90, 7, 32, -10, 0 },
+ { -4, -2, 76, 7, 66, -6, -2 },
+ { 0, -11, 42, 7, 89, 16, -8 },
+ { -7, 10, 84, 7, 51, -10, 0 },
+ { -1, -9, 59, 7, 81, 3, -5 },
+ { -10, 24, 91, 7, 34, -11, 0 },
+ { -3, -3, 72, 7, 69, -5, -2 },
+ { 0, -11, 40, 7, 89, 19, -9 },
+ { -6, 7, 84, 7, 53, -10, 0 },
+ { -1, -9, 56, 7, 83, 5, -6 },
+ { -9, 21, 90, 7, 37, -11, 0 },
+ { -3, -4, 71, 7, 71, -4, -3 },
+ { 0, -11, 37, 7, 90, 21, -9 },
+ { -6, 5, 83, 7, 56, -9, -1 },
+ { 0, -10, 53, 7, 84, 7, -6 },
+ { -9, 19, 89, 7, 40, -11, 0 },
+ { -2, -5, 69, 7, 72, -3, -3 },
+ { 0, -11, 34, 7, 91, 24, -10 },
+ { -5, 3, 81, 7, 59, -9, -1 },
+ { 0, -10, 51, 7, 84, 10, -7 },
+ { -8, 16, 89, 7, 42, -11, 0 },
+ { -2, -6, 66, 7, 76, -2, -4 },
+ { 0, -10, 32, 7, 90, 26, -10 },
+ { -5, 2, 79, 7, 61, -8, -1 },
+ { 0, -10, 48, 7, 85, 12, -7 },
+ { -8, 14, 88, 7, 45, -11, 0 },
+ { -1, -7, 64, 7, 76, 0, -4 } },
+ .odd = { { -8, 13, 88, 7, 46, -11, 0 },
+ { -1, -8, 63, 7, 78, 1, -5 },
+ { -10, 28, 90, 7, 30, -10, 0 },
+ { -4, -1, 77, 7, 65, -7, -2 },
+ { 0, -11, 44, 7, 88, 15, -8 },
+ { -7, 11, 85, 7, 49, -10, 0 },
+ { -1, -8, 60, 7, 79, 3, -5 },
+ { -10, 25, 91, 7, 33, -11, 0 },
+ { -4, -2, 74, 7, 68, -6, -2 },
+ { 0, -11, 41, 7, 89, 18, -9 },
+ { -7, 8, 85, 7, 52, -10, 0 },
+ { -1, -9, 57, 7, 83, 4, -6 },
+ { -9, 22, 90, 7, 36, -11, 0 },
+ { -3, -4, 73, 7, 70, -5, -3 },
+ { 0, -11, 38, 7, 90, 20, -9 },
+ { -6, 6, 83, 7, 55, -10, 0 },
+ { 0, -10, 55, 7, 83, 6, -6 },
+ { -9, 20, 90, 7, 38, -11, 0 },
+ { -3, -5, 70, 7, 73, -4, -3 },
+ { 0, -11, 36, 7, 90, 22, -9 },
+ { -6, 4, 83, 7, 57, -9, -1 },
+ { 0, -10, 52, 7, 85, 8, -7 },
+ { -9, 18, 89, 7, 41, -11, 0 },
+ { -2, -6, 68, 7, 74, -2, -4 },
+ { 0, -11, 33, 7, 91, 25, -10 },
+ { -5, 3, 79, 7, 60, -8, -1 },
+ { 0, -10, 49, 7, 85, 11, -7 },
+ { -8, 15, 88, 7, 44, -11, 0 },
+ { -2, -7, 65, 7, 77, -1, -4 },
+ { 0, -10, 30, 7, 90, 28, -10 },
+ { -5, 1, 78, 7, 63, -8, -1 },
+ { 0, -11, 46, 7, 88, 13, -8 } } },
+ .ptrn_arr = { { 0xf3e7cf9f, 0x9f3e7cf9, 0xf3e7cf } },
+ .sample_patrn_length = 90,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 14) = 0.695652 */
+ .hor_phase_arr = {
+ .even = { { -10, 30, 88, 7, 30, -10, 0 },
+ { -5, 0, 75, 7, 66, -5, -3 },
+ { 0, -10, 40, 7, 87, 20, -9 },
+ { -7, 7, 81, 7, 56, -8, -1 },
+ { 0, -9, 51, 7, 83, 11, -8 },
+ { -8, 16, 84, 7, 46, -10, 0 },
+ { -2, -7, 61, 7, 79, 3, -6 },
+ { -10, 25, 88, 7, 35, -10, 0 },
+ { -4, -3, 72, 7, 70, -3, -4 },
+ { 0, -10, 35, 7, 88, 25, -10 },
+ { -6, 3, 79, 7, 61, -7, -2 },
+ { 0, -10, 46, 7, 84, 16, -8 },
+ { -8, 11, 83, 7, 51, -9, 0 },
+ { -1, -8, 56, 7, 81, 7, -7 },
+ { -9, 20, 87, 7, 40, -10, 0 },
+ { -3, -5, 66, 7, 75, 0, -5 } },
+ .odd = { { -8, 13, 85, 7, 48, -10, 0 },
+ { -1, -8, 59, 7, 79, 5, -6 },
+ { -10, 23, 87, 7, 38, -10, 0 },
+ { -3, -4, 68, 7, 72, -1, -4 },
+ { 0, -10, 33, 7, 87, 28, -10 },
+ { -5, 2, 75, 7, 64, -6, -2 },
+ { 0, -10, 43, 7, 86, 18, -9 },
+ { -7, 9, 83, 7, 53, -9, -1 },
+ { -1, -9, 53, 7, 83, 9, -7 },
+ { -9, 18, 86, 7, 43, -10, 0 },
+ { -2, -6, 64, 7, 75, 2, -5 },
+ { -10, 28, 87, 7, 33, -10, 0 },
+ { -4, -1, 72, 7, 68, -4, -3 },
+ { 0, -10, 38, 7, 87, 23, -10 },
+ { -6, 5, 79, 7, 59, -8, -1 },
+ { 0, -10, 48, 7, 85, 13, -8 } } },
+ .ver_phase_arr = {
+ .even = { { -10, 30, 88, 7, 30, -10, 0 },
+ { -5, 0, 75, 7, 66, -5, -3 },
+ { 0, -10, 40, 7, 87, 20, -9 },
+ { -7, 7, 81, 7, 56, -8, -1 },
+ { 0, -9, 51, 7, 83, 11, -8 },
+ { -8, 16, 84, 7, 46, -10, 0 },
+ { -2, -7, 61, 7, 79, 3, -6 },
+ { -10, 25, 88, 7, 35, -10, 0 },
+ { -4, -3, 72, 7, 70, -3, -4 },
+ { 0, -10, 35, 7, 88, 25, -10 },
+ { -6, 3, 79, 7, 61, -7, -2 },
+ { 0, -10, 46, 7, 84, 16, -8 },
+ { -8, 11, 83, 7, 51, -9, 0 },
+ { -1, -8, 56, 7, 81, 7, -7 },
+ { -9, 20, 87, 7, 40, -10, 0 },
+ { -3, -5, 66, 7, 75, 0, -5 } },
+ .odd = { { -8, 13, 85, 7, 48, -10, 0 },
+ { -1, -8, 59, 7, 79, 5, -6 },
+ { -10, 23, 87, 7, 38, -10, 0 },
+ { -3, -4, 68, 7, 72, -1, -4 },
+ { 0, -10, 33, 7, 87, 28, -10 },
+ { -5, 2, 75, 7, 64, -6, -2 },
+ { 0, -10, 43, 7, 86, 18, -9 },
+ { -7, 9, 83, 7, 53, -9, -1 },
+ { -1, -9, 53, 7, 83, 9, -7 },
+ { -9, 18, 86, 7, 43, -10, 0 },
+ { -2, -6, 64, 7, 75, 2, -5 },
+ { -10, 28, 87, 7, 33, -10, 0 },
+ { -4, -1, 72, 7, 68, -4, -3 },
+ { 0, -10, 38, 7, 87, 23, -10 },
+ { -6, 5, 79, 7, 59, -8, -1 },
+ { 0, -10, 48, 7, 85, 13, -8 } } },
+ .ptrn_arr = { { 0x79f3cf9f, 0xf3e } },
+ .sample_patrn_length = 46,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 15) = 0.680851 */
+ .hor_phase_arr = {
+ .even = { { -10, 31, 86, 7, 31, -10, 0 },
+ { -5, 0, 72, 7, 68, -3, -4 },
+ { 0, -10, 36, 7, 86, 26, -10 },
+ { -6, 3, 76, 7, 63, -5, -3 },
+ { 0, -10, 41, 7, 85, 21, -9 },
+ { -7, 7, 78, 7, 59, -7, -2 },
+ { 0, -10, 46, 7, 84, 17, -9 },
+ { -8, 11, 80, 7, 54, -8, -1 },
+ { -1, -9, 51, 7, 82, 13, -8 },
+ { -9, 15, 83, 7, 49, -9, -1 },
+ { -2, -8, 56, 7, 80, 9, -7 },
+ { -9, 19, 85, 7, 43, -10, 0 },
+ { -3, -6, 61, 7, 77, 5, -6 },
+ { -10, 24, 86, 7, 38, -10, 0 },
+ { -3, -4, 66, 7, 72, 2, -5 },
+ { -10, 29, 86, 7, 33, -10, 0 },
+ { -4, -1, 68, 7, 70, -1, -4 },
+ { 0, -10, 33, 7, 86, 29, -10 },
+ { -5, 2, 72, 7, 66, -4, -3 },
+ { 0, -10, 38, 7, 86, 24, -10 },
+ { -6, 5, 77, 7, 61, -6, -3 },
+ { 0, -10, 43, 7, 85, 19, -9 },
+ { -7, 9, 80, 7, 56, -8, -2 },
+ { -1, -9, 49, 7, 83, 15, -9 },
+ { -8, 13, 82, 7, 51, -9, -1 },
+ { -1, -8, 54, 7, 80, 11, -8 },
+ { -9, 17, 84, 7, 46, -10, 0 },
+ { -2, -7, 59, 7, 78, 7, -7 },
+ { -9, 21, 85, 7, 41, -10, 0 },
+ { -3, -5, 63, 7, 76, 3, -6 },
+ { -10, 26, 86, 7, 36, -10, 0 },
+ { -4, -3, 68, 7, 72, 0, -5 } },
+ .odd = { { -8, 14, 82, 7, 50, -9, -1 },
+ { -1, -8, 55, 7, 79, 10, -7 },
+ { -9, 18, 84, 7, 45, -10, 0 },
+ { -2, -6, 60, 7, 77, 6, -7 },
+ { -10, 23, 85, 7, 40, -10, 0 },
+ { -3, -4, 64, 7, 75, 2, -6 },
+ { -10, 27, 86, 7, 35, -10, 0 },
+ { -4, -2, 69, 7, 71, -1, -5 },
+ { 0, -10, 32, 7, 86, 30, -10 },
+ { -5, 1, 72, 7, 67, -3, -4 },
+ { 0, -10, 37, 7, 86, 25, -10 },
+ { -6, 4, 77, 7, 62, -6, -3 },
+ { 0, -10, 42, 7, 85, 20, -9 },
+ { -7, 8, 79, 7, 57, -7, -2 },
+ { -1, -9, 47, 7, 84, 16, -9 },
+ { -8, 12, 81, 7, 52, -8, -1 },
+ { -1, -8, 52, 7, 81, 12, -8 },
+ { -9, 16, 84, 7, 47, -9, -1 },
+ { -2, -7, 57, 7, 79, 8, -7 },
+ { -9, 20, 85, 7, 42, -10, 0 },
+ { -3, -6, 62, 7, 77, 4, -6 },
+ { -10, 25, 86, 7, 37, -10, 0 },
+ { -4, -3, 67, 7, 72, 1, -5 },
+ { -10, 30, 86, 7, 32, -10, 0 },
+ { -5, -1, 71, 7, 69, -2, -4 },
+ { 0, -10, 35, 7, 86, 27, -10 },
+ { -6, 2, 75, 7, 64, -4, -3 },
+ { 0, -10, 40, 7, 85, 23, -10 },
+ { -7, 6, 77, 7, 60, -6, -2 },
+ { 0, -10, 45, 7, 84, 18, -9 },
+ { -7, 10, 79, 7, 55, -8, -1 },
+ { -1, -9, 50, 7, 82, 14, -8 } } },
+ .ver_phase_arr = {
+ .even = { { -10, 31, 86, 7, 31, -10, 0 },
+ { -5, 0, 72, 7, 68, -3, -4 },
+ { 0, -10, 36, 7, 86, 26, -10 },
+ { -6, 3, 76, 7, 63, -5, -3 },
+ { 0, -10, 41, 7, 85, 21, -9 },
+ { -7, 7, 78, 7, 59, -7, -2 },
+ { 0, -10, 46, 7, 84, 17, -9 },
+ { -8, 11, 80, 7, 54, -8, -1 },
+ { -1, -9, 51, 7, 82, 13, -8 },
+ { -9, 15, 83, 7, 49, -9, -1 },
+ { -2, -8, 56, 7, 80, 9, -7 },
+ { -9, 19, 85, 7, 43, -10, 0 },
+ { -3, -6, 61, 7, 77, 5, -6 },
+ { -10, 24, 86, 7, 38, -10, 0 },
+ { -3, -4, 66, 7, 72, 2, -5 },
+ { -10, 29, 86, 7, 33, -10, 0 },
+ { -4, -1, 68, 7, 70, -1, -4 },
+ { 0, -10, 33, 7, 86, 29, -10 },
+ { -5, 2, 72, 7, 66, -4, -3 },
+ { 0, -10, 38, 7, 86, 24, -10 },
+ { -6, 5, 77, 7, 61, -6, -3 },
+ { 0, -10, 43, 7, 85, 19, -9 },
+ { -7, 9, 80, 7, 56, -8, -2 },
+ { -1, -9, 49, 7, 83, 15, -9 },
+ { -8, 13, 82, 7, 51, -9, -1 },
+ { -1, -8, 54, 7, 80, 11, -8 },
+ { -9, 17, 84, 7, 46, -10, 0 },
+ { -2, -7, 59, 7, 78, 7, -7 },
+ { -9, 21, 85, 7, 41, -10, 0 },
+ { -3, -5, 63, 7, 76, 3, -6 },
+ { -10, 26, 86, 7, 36, -10, 0 },
+ { -4, -3, 68, 7, 72, 0, -5 } },
+ .odd = { { -8, 14, 82, 7, 50, -9, -1 },
+ { -1, -8, 55, 7, 79, 10, -7 },
+ { -9, 18, 84, 7, 45, -10, 0 },
+ { -2, -6, 60, 7, 77, 6, -7 },
+ { -10, 23, 85, 7, 40, -10, 0 },
+ { -3, -4, 64, 7, 75, 2, -6 },
+ { -10, 27, 86, 7, 35, -10, 0 },
+ { -4, -2, 69, 7, 71, -1, -5 },
+ { 0, -10, 32, 7, 86, 30, -10 },
+ { -5, 1, 72, 7, 67, -3, -4 },
+ { 0, -10, 37, 7, 86, 25, -10 },
+ { -6, 4, 77, 7, 62, -6, -3 },
+ { 0, -10, 42, 7, 85, 20, -9 },
+ { -7, 8, 79, 7, 57, -7, -2 },
+ { -1, -9, 47, 7, 84, 16, -9 },
+ { -8, 12, 81, 7, 52, -8, -1 },
+ { -1, -8, 52, 7, 81, 12, -8 },
+ { -9, 16, 84, 7, 47, -9, -1 },
+ { -2, -7, 57, 7, 79, 8, -7 },
+ { -9, 20, 85, 7, 42, -10, 0 },
+ { -3, -6, 62, 7, 77, 4, -6 },
+ { -10, 25, 86, 7, 37, -10, 0 },
+ { -4, -3, 67, 7, 72, 1, -5 },
+ { -10, 30, 86, 7, 32, -10, 0 },
+ { -5, -1, 71, 7, 69, -2, -4 },
+ { 0, -10, 35, 7, 86, 27, -10 },
+ { -6, 2, 75, 7, 64, -4, -3 },
+ { 0, -10, 40, 7, 85, 23, -10 },
+ { -7, 6, 77, 7, 60, -6, -2 },
+ { 0, -10, 45, 7, 84, 18, -9 },
+ { -7, 10, 79, 7, 55, -8, -1 },
+ { -1, -9, 50, 7, 82, 14, -8 } } },
+ .ptrn_arr = { { 0x3cf9e79f, 0x9e79f3cf, 0xf3cf3e7 } },
+ .sample_patrn_length = 94,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 16) = 0.666667 */
+ .hor_phase_arr = {
+ .even = { { -10, 32, 84, 7, 32, -10, 0 },
+ { -5, 0, 69, 7, 69, 0, -5 } },
+ .odd = { { -9, 14, 82, 7, 51, -8, -2 },
+ { -2, -8, 51, 7, 82, 14, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -10, 32, 84, 7, 32, -10, 0 },
+ { -5, 0, 69, 7, 69, 0, -5 } },
+ .odd = { { -9, 14, 82, 7, 51, -8, -2 },
+ { -2, -8, 51, 7, 82, 14, -9 } } },
+ .ptrn_arr = { { 0xf } },
+ .sample_patrn_length = 6,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 17) = 0.653061 */
+ .hor_phase_arr = {
+ .even = { { -10, 33, 82, 7, 33, -10, 0 },
+ { -5, 0, 66, 7, 70, 3, -6 },
+ { -10, 28, 82, 7, 37, -9, 0 },
+ { -4, -3, 62, 7, 74, 6, -7 },
+ { -10, 24, 82, 7, 42, -9, -1 },
+ { -3, -5, 58, 7, 76, 10, -8 },
+ { -9, 20, 79, 7, 47, -8, -1 },
+ { -3, -6, 54, 7, 78, 14, -9 },
+ { -9, 16, 79, 7, 51, -7, -2 },
+ { -2, -8, 49, 7, 80, 18, -9 },
+ { -8, 12, 77, 7, 56, -6, -3 },
+ { -1, -9, 44, 7, 81, 22, -9 },
+ { -7, 8, 75, 7, 60, -4, -4 },
+ { -1, -9, 40, 7, 82, 26, -10 },
+ { -7, 5, 71, 7, 65, -1, -5 },
+ { 0, -10, 35, 7, 83, 30, -10 },
+ { -6, 1, 70, 7, 68, 1, -6 },
+ { -10, 30, 83, 7, 35, -10, 0 },
+ { -5, -1, 65, 7, 71, 5, -7 },
+ { -10, 26, 82, 7, 40, -9, -1 },
+ { -4, -4, 60, 7, 75, 8, -7 },
+ { -9, 22, 81, 7, 44, -9, -1 },
+ { -3, -6, 56, 7, 77, 12, -8 },
+ { -9, 18, 80, 7, 49, -8, -2 },
+ { -2, -7, 51, 7, 79, 16, -9 },
+ { -9, 14, 78, 7, 54, -6, -3 },
+ { -1, -8, 47, 7, 79, 20, -9 },
+ { -8, 10, 76, 7, 58, -5, -3 },
+ { -1, -9, 42, 7, 82, 24, -10 },
+ { -7, 6, 74, 7, 62, -3, -4 },
+ { 0, -9, 37, 7, 82, 28, -10 },
+ { -6, 3, 70, 7, 66, 0, -5 } },
+ .odd = { { -9, 15, 79, 7, 52, -7, -2 },
+ { -2, -8, 48, 7, 80, 19, -9 },
+ { -8, 11, 76, 7, 57, -5, -3 },
+ { -1, -9, 43, 7, 82, 23, -10 },
+ { -7, 7, 74, 7, 61, -3, -4 },
+ { -1, -9, 38, 7, 83, 27, -10 },
+ { -6, 4, 70, 7, 66, -1, -5 },
+ { 0, -10, 34, 7, 83, 31, -10 },
+ { -6, 1, 67, 7, 70, 2, -6 },
+ { -10, 29, 83, 7, 36, -10, 0 },
+ { -5, -2, 64, 7, 73, 5, -7 },
+ { -10, 25, 82, 7, 41, -9, -1 },
+ { -4, -4, 59, 7, 76, 9, -8 },
+ { -9, 21, 80, 7, 45, -8, -1 },
+ { -3, -6, 55, 7, 77, 13, -8 },
+ { -9, 17, 79, 7, 50, -7, -2 },
+ { -2, -7, 50, 7, 79, 17, -9 },
+ { -8, 13, 77, 7, 55, -6, -3 },
+ { -1, -8, 45, 7, 80, 21, -9 },
+ { -8, 9, 76, 7, 59, -4, -4 },
+ { -1, -9, 41, 7, 82, 25, -10 },
+ { -7, 5, 73, 7, 64, -2, -5 },
+ { 0, -10, 36, 7, 83, 29, -10 },
+ { -6, 2, 70, 7, 67, 1, -6 },
+ { -10, 31, 83, 7, 34, -10, 0 },
+ { -5, -1, 66, 7, 70, 4, -6 },
+ { -10, 27, 83, 7, 38, -9, -1 },
+ { -4, -3, 61, 7, 74, 7, -7 },
+ { -10, 23, 82, 7, 43, -9, -1 },
+ { -3, -5, 57, 7, 76, 11, -8 },
+ { -9, 19, 80, 7, 48, -8, -2 },
+ { -2, -7, 52, 7, 79, 15, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -10, 33, 82, 7, 33, -10, 0 },
+ { -5, 0, 66, 7, 70, 3, -6 },
+ { -10, 28, 82, 7, 37, -9, 0 },
+ { -4, -3, 62, 7, 74, 6, -7 },
+ { -10, 24, 82, 7, 42, -9, -1 },
+ { -3, -5, 58, 7, 76, 10, -8 },
+ { -9, 20, 79, 7, 47, -8, -1 },
+ { -3, -6, 54, 7, 78, 14, -9 },
+ { -9, 16, 79, 7, 51, -7, -2 },
+ { -2, -8, 49, 7, 80, 18, -9 },
+ { -8, 12, 77, 7, 56, -6, -3 },
+ { -1, -9, 44, 7, 81, 22, -9 },
+ { -7, 8, 75, 7, 60, -4, -4 },
+ { -1, -9, 40, 7, 82, 26, -10 },
+ { -7, 5, 71, 7, 65, -1, -5 },
+ { 0, -10, 35, 7, 83, 30, -10 },
+ { -6, 1, 70, 7, 68, 1, -6 },
+ { -10, 30, 83, 7, 35, -10, 0 },
+ { -5, -1, 65, 7, 71, 5, -7 },
+ { -10, 26, 82, 7, 40, -9, -1 },
+ { -4, -4, 60, 7, 75, 8, -7 },
+ { -9, 22, 81, 7, 44, -9, -1 },
+ { -3, -6, 56, 7, 77, 12, -8 },
+ { -9, 18, 80, 7, 49, -8, -2 },
+ { -2, -7, 51, 7, 79, 16, -9 },
+ { -9, 14, 78, 7, 54, -6, -3 },
+ { -1, -8, 47, 7, 79, 20, -9 },
+ { -8, 10, 76, 7, 58, -5, -3 },
+ { -1, -9, 42, 7, 82, 24, -10 },
+ { -7, 6, 74, 7, 62, -3, -4 },
+ { 0, -9, 37, 7, 82, 28, -10 },
+ { -6, 3, 70, 7, 66, 0, -5 } },
+ .odd = { { -9, 15, 79, 7, 52, -7, -2 },
+ { -2, -8, 48, 7, 80, 19, -9 },
+ { -8, 11, 76, 7, 57, -5, -3 },
+ { -1, -9, 43, 7, 82, 23, -10 },
+ { -7, 7, 74, 7, 61, -3, -4 },
+ { -1, -9, 38, 7, 83, 27, -10 },
+ { -6, 4, 70, 7, 66, -1, -5 },
+ { 0, -10, 34, 7, 83, 31, -10 },
+ { -6, 1, 67, 7, 70, 2, -6 },
+ { -10, 29, 83, 7, 36, -10, 0 },
+ { -5, -2, 64, 7, 73, 5, -7 },
+ { -10, 25, 82, 7, 41, -9, -1 },
+ { -4, -4, 59, 7, 76, 9, -8 },
+ { -9, 21, 80, 7, 45, -8, -1 },
+ { -3, -6, 55, 7, 77, 13, -8 },
+ { -9, 17, 79, 7, 50, -7, -2 },
+ { -2, -7, 50, 7, 79, 17, -9 },
+ { -8, 13, 77, 7, 55, -6, -3 },
+ { -1, -8, 45, 7, 80, 21, -9 },
+ { -8, 9, 76, 7, 59, -4, -4 },
+ { -1, -9, 41, 7, 82, 25, -10 },
+ { -7, 5, 73, 7, 64, -2, -5 },
+ { 0, -10, 36, 7, 83, 29, -10 },
+ { -6, 2, 70, 7, 67, 1, -6 },
+ { -10, 31, 83, 7, 34, -10, 0 },
+ { -5, -1, 66, 7, 70, 4, -6 },
+ { -10, 27, 83, 7, 38, -9, -1 },
+ { -4, -3, 61, 7, 74, 7, -7 },
+ { -10, 23, 82, 7, 43, -9, -1 },
+ { -3, -5, 57, 7, 76, 11, -8 },
+ { -9, 19, 80, 7, 48, -8, -2 },
+ { -2, -7, 52, 7, 79, 15, -9 } } },
+ .ptrn_arr = { { 0xe73cf3cf, 0x3cf39e79, 0xe79e79cf } },
+ .sample_patrn_length = 98,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 18) = 0.64 */
+ .hor_phase_arr = {
+ .even = { { -9, 33, 80, 7, 33, -9, 0 },
+ { -6, 0, 64, 7, 71, 6, -7 },
+ { -10, 25, 80, 7, 42, -8, -1 },
+ { -4, -4, 56, 7, 76, 13, -9 },
+ { -9, 17, 78, 7, 51, -6, -3 },
+ { -2, -7, 47, 7, 78, 21, -9 },
+ { -8, 9, 74, 7, 60, -2, -5 },
+ { -1, -9, 38, 7, 81, 29, -10 },
+ { -6, 3, 66, 7, 68, 3, -6 },
+ { -10, 29, 81, 7, 38, -9, -1 },
+ { -5, -2, 60, 7, 74, 9, -8 },
+ { -9, 21, 78, 7, 47, -7, -2 },
+ { -3, -6, 51, 7, 78, 17, -9 },
+ { -9, 13, 76, 7, 56, -4, -4 },
+ { -1, -8, 42, 7, 80, 25, -10 },
+ { -7, 6, 71, 7, 64, 0, -6 } },
+ .odd = { { -9, 15, 76, 7, 54, -5, -3 },
+ { -2, -8, 45, 7, 80, 23, -10 },
+ { -8, 8, 72, 7, 62, -1, -5 },
+ { -1, -9, 36, 7, 80, 31, -9 },
+ { -6, 1, 66, 7, 70, 4, -7 },
+ { -10, 27, 81, 7, 40, -9, -1 },
+ { -4, -4, 58, 7, 75, 11, -8 },
+ { -9, 19, 78, 7, 49, -7, -2 },
+ { -2, -7, 49, 7, 78, 19, -9 },
+ { -8, 11, 75, 7, 58, -4, -4 },
+ { -1, -9, 40, 7, 81, 27, -10 },
+ { -7, 4, 70, 7, 66, 1, -6 },
+ { -9, 31, 80, 7, 36, -9, -1 },
+ { -5, -1, 62, 7, 72, 8, -8 },
+ { -10, 23, 80, 7, 45, -8, -2 },
+ { -3, -5, 54, 7, 76, 15, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -9, 33, 80, 7, 33, -9, 0 },
+ { -6, 0, 64, 7, 71, 6, -7 },
+ { -10, 25, 80, 7, 42, -8, -1 },
+ { -4, -4, 56, 7, 76, 13, -9 },
+ { -9, 17, 78, 7, 51, -6, -3 },
+ { -2, -7, 47, 7, 78, 21, -9 },
+ { -8, 9, 74, 7, 60, -2, -5 },
+ { -1, -9, 38, 7, 81, 29, -10 },
+ { -6, 3, 66, 7, 68, 3, -6 },
+ { -10, 29, 81, 7, 38, -9, -1 },
+ { -5, -2, 60, 7, 74, 9, -8 },
+ { -9, 21, 78, 7, 47, -7, -2 },
+ { -3, -6, 51, 7, 78, 17, -9 },
+ { -9, 13, 76, 7, 56, -4, -4 },
+ { -1, -8, 42, 7, 80, 25, -10 },
+ { -7, 6, 71, 7, 64, 0, -6 } },
+ .odd = { { -9, 15, 76, 7, 54, -5, -3 },
+ { -2, -8, 45, 7, 80, 23, -10 },
+ { -8, 8, 72, 7, 62, -1, -5 },
+ { -1, -9, 36, 7, 80, 31, -9 },
+ { -6, 1, 66, 7, 70, 4, -7 },
+ { -10, 27, 81, 7, 40, -9, -1 },
+ { -4, -4, 58, 7, 75, 11, -8 },
+ { -9, 19, 78, 7, 49, -7, -2 },
+ { -2, -7, 49, 7, 78, 19, -9 },
+ { -8, 11, 75, 7, 58, -4, -4 },
+ { -1, -9, 40, 7, 81, 27, -10 },
+ { -7, 4, 70, 7, 66, 1, -6 },
+ { -9, 31, 80, 7, 36, -9, -1 },
+ { -5, -1, 62, 7, 72, 8, -8 },
+ { -10, 23, 80, 7, 45, -8, -2 },
+ { -3, -5, 54, 7, 76, 15, -9 } } },
+ .ptrn_arr = { { 0xf39e73cf, 0xe79c } },
+ .sample_patrn_length = 50,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 19) = 0.627451 */
+ .hor_phase_arr = {
+ .even = { { -9, 34, 79, 7, 34, -9, -1 },
+ { -6, 0, 61, 7, 72, 9, -8 },
+ { -9, 22, 78, 7, 47, -7, -3 },
+ { -3, -6, 49, 7, 77, 20, -9 },
+ { -8, 11, 72, 7, 59, -1, -5 },
+ { -1, -9, 36, 7, 79, 32, -9 },
+ { -6, 1, 63, 7, 71, 7, -8 },
+ { -9, 24, 77, 7, 45, -7, -2 },
+ { -4, -5, 51, 7, 77, 18, -9 },
+ { -9, 13, 73, 7, 58, -2, -5 },
+ { -1, -8, 38, 7, 78, 30, -9 },
+ { -6, 3, 65, 7, 67, 6, -7 },
+ { -9, 26, 78, 7, 43, -8, -2 },
+ { -4, -4, 53, 7, 76, 16, -9 },
+ { -9, 14, 75, 7, 55, -3, -4 },
+ { -2, -8, 40, 7, 79, 28, -9 },
+ { -7, 4, 67, 7, 67, 4, -7 },
+ { -9, 28, 79, 7, 40, -8, -2 },
+ { -4, -3, 55, 7, 75, 14, -9 },
+ { -9, 16, 76, 7, 53, -4, -4 },
+ { -2, -8, 43, 7, 78, 26, -9 },
+ { -7, 6, 67, 7, 65, 3, -6 },
+ { -9, 30, 78, 7, 38, -8, -1 },
+ { -5, -2, 58, 7, 73, 13, -9 },
+ { -9, 18, 77, 7, 51, -5, -4 },
+ { -2, -7, 45, 7, 77, 24, -9 },
+ { -8, 7, 71, 7, 63, 1, -6 },
+ { -9, 32, 79, 7, 36, -9, -1 },
+ { -5, -1, 59, 7, 72, 11, -8 },
+ { -9, 20, 77, 7, 49, -6, -3 },
+ { -3, -7, 47, 7, 78, 22, -9 },
+ { -8, 9, 72, 7, 61, 0, -6 } },
+ .odd = { { -9, 15, 76, 7, 54, -4, -4 },
+ { -2, -8, 41, 7, 79, 27, -9 },
+ { -7, 5, 68, 7, 66, 3, -7 },
+ { -9, 29, 78, 7, 39, -8, -1 },
+ { -5, -3, 56, 7, 76, 13, -9 },
+ { -9, 17, 77, 7, 52, -5, -4 },
+ { -2, -7, 44, 7, 77, 25, -9 },
+ { -7, 7, 68, 7, 64, 2, -6 },
+ { -9, 31, 79, 7, 37, -9, -1 },
+ { -5, -2, 59, 7, 72, 12, -8 },
+ { -9, 19, 77, 7, 50, -6, -3 },
+ { -3, -7, 46, 7, 78, 23, -9 },
+ { -8, 8, 71, 7, 62, 1, -6 },
+ { -9, 33, 79, 7, 35, -9, -1 },
+ { -5, -1, 60, 7, 72, 10, -8 },
+ { -9, 21, 77, 7, 48, -6, -3 },
+ { -3, -6, 48, 7, 77, 21, -9 },
+ { -8, 10, 72, 7, 60, -1, -5 },
+ { -1, -9, 35, 7, 79, 33, -9 },
+ { -6, 1, 62, 7, 71, 8, -8 },
+ { -9, 23, 78, 7, 46, -7, -3 },
+ { -3, -6, 50, 7, 77, 19, -9 },
+ { -8, 12, 72, 7, 59, -2, -5 },
+ { -1, -9, 37, 7, 79, 31, -9 },
+ { -6, 2, 64, 7, 68, 7, -7 },
+ { -9, 25, 77, 7, 44, -7, -2 },
+ { -4, -5, 52, 7, 77, 17, -9 },
+ { -9, 13, 76, 7, 56, -3, -5 },
+ { -1, -8, 39, 7, 78, 29, -9 },
+ { -7, 3, 66, 7, 68, 5, -7 },
+ { -9, 27, 79, 7, 41, -8, -2 },
+ { -4, -4, 54, 7, 76, 15, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -9, 34, 79, 7, 34, -9, -1 },
+ { -6, 0, 61, 7, 72, 9, -8 },
+ { -9, 22, 78, 7, 47, -7, -3 },
+ { -3, -6, 49, 7, 77, 20, -9 },
+ { -8, 11, 72, 7, 59, -1, -5 },
+ { -1, -9, 36, 7, 79, 32, -9 },
+ { -6, 1, 63, 7, 71, 7, -8 },
+ { -9, 24, 77, 7, 45, -7, -2 },
+ { -4, -5, 51, 7, 77, 18, -9 },
+ { -9, 13, 73, 7, 58, -2, -5 },
+ { -1, -8, 38, 7, 78, 30, -9 },
+ { -6, 3, 65, 7, 67, 6, -7 },
+ { -9, 26, 78, 7, 43, -8, -2 },
+ { -4, -4, 53, 7, 76, 16, -9 },
+ { -9, 14, 75, 7, 55, -3, -4 },
+ { -2, -8, 40, 7, 79, 28, -9 },
+ { -7, 4, 67, 7, 67, 4, -7 },
+ { -9, 28, 79, 7, 40, -8, -2 },
+ { -4, -3, 55, 7, 75, 14, -9 },
+ { -9, 16, 76, 7, 53, -4, -4 },
+ { -2, -8, 43, 7, 78, 26, -9 },
+ { -7, 6, 67, 7, 65, 3, -6 },
+ { -9, 30, 78, 7, 38, -8, -1 },
+ { -5, -2, 58, 7, 73, 13, -9 },
+ { -9, 18, 77, 7, 51, -5, -4 },
+ { -2, -7, 45, 7, 77, 24, -9 },
+ { -8, 7, 71, 7, 63, 1, -6 },
+ { -9, 32, 79, 7, 36, -9, -1 },
+ { -5, -1, 59, 7, 72, 11, -8 },
+ { -9, 20, 77, 7, 49, -6, -3 },
+ { -3, -7, 47, 7, 78, 22, -9 },
+ { -8, 9, 72, 7, 61, 0, -6 } },
+ .odd = { { -9, 15, 76, 7, 54, -4, -4 },
+ { -2, -8, 41, 7, 79, 27, -9 },
+ { -7, 5, 68, 7, 66, 3, -7 },
+ { -9, 29, 78, 7, 39, -8, -1 },
+ { -5, -3, 56, 7, 76, 13, -9 },
+ { -9, 17, 77, 7, 52, -5, -4 },
+ { -2, -7, 44, 7, 77, 25, -9 },
+ { -7, 7, 68, 7, 64, 2, -6 },
+ { -9, 31, 79, 7, 37, -9, -1 },
+ { -5, -2, 59, 7, 72, 12, -8 },
+ { -9, 19, 77, 7, 50, -6, -3 },
+ { -3, -7, 46, 7, 78, 23, -9 },
+ { -8, 8, 71, 7, 62, 1, -6 },
+ { -9, 33, 79, 7, 35, -9, -1 },
+ { -5, -1, 60, 7, 72, 10, -8 },
+ { -9, 21, 77, 7, 48, -6, -3 },
+ { -3, -6, 48, 7, 77, 21, -9 },
+ { -8, 10, 72, 7, 60, -1, -5 },
+ { -1, -9, 35, 7, 79, 33, -9 },
+ { -6, 1, 62, 7, 71, 8, -8 },
+ { -9, 23, 78, 7, 46, -7, -3 },
+ { -3, -6, 50, 7, 77, 19, -9 },
+ { -8, 12, 72, 7, 59, -2, -5 },
+ { -1, -9, 37, 7, 79, 31, -9 },
+ { -6, 2, 64, 7, 68, 7, -7 },
+ { -9, 25, 77, 7, 44, -7, -2 },
+ { -4, -5, 52, 7, 77, 17, -9 },
+ { -9, 13, 76, 7, 56, -3, -5 },
+ { -1, -8, 39, 7, 78, 29, -9 },
+ { -7, 3, 66, 7, 68, 5, -7 },
+ { -9, 27, 79, 7, 41, -8, -2 },
+ { -4, -4, 54, 7, 76, 15, -9 } } },
+ .ptrn_arr = { { 0x79ce79cf, 0x73ce79ce, 0x73ce73ce, 0xe } },
+ .sample_patrn_length = 102,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 20) = 0.615385 */
+ .hor_phase_arr = {
+ .even = { { -8, 34, 77, 7, 34, -8, -1 },
+ { -6, 0, 59, 7, 71, 12, -8 },
+ { -9, 19, 75, 7, 51, -4, -4 },
+ { -3, -7, 43, 7, 77, 27, -9 },
+ { -7, 6, 64, 7, 66, 6, -7 },
+ { -9, 27, 77, 7, 43, -7, -3 },
+ { -4, -4, 51, 7, 75, 19, -9 },
+ { -8, 12, 71, 7, 59, 0, -6 } },
+ .odd = { { -9, 16, 73, 7, 55, -2, -5 },
+ { -2, -8, 39, 7, 77, 31, -9 },
+ { -7, 3, 63, 7, 68, 9, -8 },
+ { -9, 23, 76, 7, 47, -6, -3 },
+ { -3, -6, 47, 7, 76, 23, -9 },
+ { -8, 9, 68, 7, 63, 3, -7 },
+ { -9, 31, 77, 7, 39, -8, -2 },
+ { -5, -2, 55, 7, 73, 16, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -8, 34, 77, 7, 34, -8, -1 },
+ { -6, 0, 59, 7, 71, 12, -8 },
+ { -9, 19, 75, 7, 51, -4, -4 },
+ { -3, -7, 43, 7, 77, 27, -9 },
+ { -7, 6, 64, 7, 66, 6, -7 },
+ { -9, 27, 77, 7, 43, -7, -3 },
+ { -4, -4, 51, 7, 75, 19, -9 },
+ { -8, 12, 71, 7, 59, 0, -6 } },
+ .odd = { { -9, 16, 73, 7, 55, -2, -5 },
+ { -2, -8, 39, 7, 77, 31, -9 },
+ { -7, 3, 63, 7, 68, 9, -8 },
+ { -9, 23, 76, 7, 47, -6, -3 },
+ { -3, -6, 47, 7, 76, 23, -9 },
+ { -8, 9, 68, 7, 63, 3, -7 },
+ { -9, 31, 77, 7, 39, -8, -2 },
+ { -5, -2, 55, 7, 73, 16, -9 } } },
+ .ptrn_arr = { { 0xe739cf } },
+ .sample_patrn_length = 26,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 21) = 0.603774 */
+ .hor_phase_arr = {
+ .even = { { -8, 35, 76, 7, 35, -8, -2 },
+ { -6, 0, 57, 7, 71, 15, -9 },
+ { -9, 17, 71, 7, 55, -1, -5 },
+ { -2, -8, 37, 7, 76, 33, -8 },
+ { -6, 1, 58, 7, 71, 13, -9 },
+ { -9, 18, 73, 7, 53, -2, -5 },
+ { -2, -7, 39, 7, 75, 31, -8 },
+ { -7, 2, 60, 7, 69, 12, -8 },
+ { -9, 20, 74, 7, 51, -3, -5 },
+ { -3, -7, 41, 7, 77, 29, -9 },
+ { -7, 4, 62, 7, 67, 10, -8 },
+ { -9, 22, 74, 7, 49, -4, -4 },
+ { -3, -6, 43, 7, 75, 28, -9 },
+ { -7, 5, 63, 7, 67, 8, -8 },
+ { -9, 24, 75, 7, 47, -5, -4 },
+ { -4, -5, 45, 7, 75, 26, -9 },
+ { -8, 7, 65, 7, 65, 7, -8 },
+ { -9, 26, 75, 7, 45, -5, -4 },
+ { -4, -5, 47, 7, 75, 24, -9 },
+ { -8, 8, 67, 7, 63, 5, -7 },
+ { -9, 28, 75, 7, 43, -6, -3 },
+ { -4, -4, 49, 7, 74, 22, -9 },
+ { -8, 10, 67, 7, 62, 4, -7 },
+ { -9, 29, 77, 7, 41, -7, -3 },
+ { -5, -3, 51, 7, 74, 20, -9 },
+ { -8, 12, 69, 7, 60, 2, -7 },
+ { -8, 31, 75, 7, 39, -7, -2 },
+ { -5, -2, 53, 7, 73, 18, -9 },
+ { -9, 13, 71, 7, 58, 1, -6 },
+ { -8, 33, 76, 7, 37, -8, -2 },
+ { -5, -1, 55, 7, 71, 17, -9 },
+ { -9, 15, 71, 7, 57, 0, -6 } },
+ .odd = { { -9, 16, 72, 7, 56, -1, -6 },
+ { -2, -8, 36, 7, 76, 34, -8 },
+ { -6, 1, 58, 7, 70, 14, -9 },
+ { -9, 18, 72, 7, 54, -2, -5 },
+ { -2, -7, 38, 7, 75, 32, -8 },
+ { -6, 2, 59, 7, 70, 12, -9 },
+ { -9, 19, 74, 7, 52, -3, -5 },
+ { -3, -7, 40, 7, 77, 30, -9 },
+ { -7, 3, 61, 7, 68, 11, -8 },
+ { -9, 21, 75, 7, 50, -4, -5 },
+ { -3, -6, 42, 7, 75, 29, -9 },
+ { -7, 5, 63, 7, 66, 9, -8 },
+ { -9, 23, 74, 7, 48, -4, -4 },
+ { -3, -6, 44, 7, 75, 27, -9 },
+ { -7, 6, 64, 7, 65, 8, -8 },
+ { -9, 25, 75, 7, 46, -5, -4 },
+ { -4, -5, 46, 7, 75, 25, -9 },
+ { -8, 8, 65, 7, 64, 6, -7 },
+ { -9, 27, 75, 7, 44, -6, -3 },
+ { -4, -4, 48, 7, 74, 23, -9 },
+ { -8, 9, 66, 7, 63, 5, -7 },
+ { -9, 29, 75, 7, 42, -6, -3 },
+ { -5, -4, 50, 7, 75, 21, -9 },
+ { -8, 11, 68, 7, 61, 3, -7 },
+ { -9, 30, 77, 7, 40, -7, -3 },
+ { -5, -3, 52, 7, 74, 19, -9 },
+ { -9, 12, 70, 7, 59, 2, -6 },
+ { -8, 32, 75, 7, 38, -7, -2 },
+ { -5, -2, 54, 7, 72, 18, -9 },
+ { -9, 14, 70, 7, 58, 1, -6 },
+ { -8, 34, 76, 7, 36, -8, -2 },
+ { -6, -1, 56, 7, 72, 16, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -8, 35, 76, 7, 35, -8, -2 },
+ { -6, 0, 57, 7, 71, 15, -9 },
+ { -9, 17, 71, 7, 55, -1, -5 },
+ { -2, -8, 37, 7, 76, 33, -8 },
+ { -6, 1, 58, 7, 71, 13, -9 },
+ { -9, 18, 73, 7, 53, -2, -5 },
+ { -2, -7, 39, 7, 75, 31, -8 },
+ { -7, 2, 60, 7, 69, 12, -8 },
+ { -9, 20, 74, 7, 51, -3, -5 },
+ { -3, -7, 41, 7, 77, 29, -9 },
+ { -7, 4, 62, 7, 67, 10, -8 },
+ { -9, 22, 74, 7, 49, -4, -4 },
+ { -3, -6, 43, 7, 75, 28, -9 },
+ { -7, 5, 63, 7, 67, 8, -8 },
+ { -9, 24, 75, 7, 47, -5, -4 },
+ { -4, -5, 45, 7, 75, 26, -9 },
+ { -8, 7, 65, 7, 65, 7, -8 },
+ { -9, 26, 75, 7, 45, -5, -4 },
+ { -4, -5, 47, 7, 75, 24, -9 },
+ { -8, 8, 67, 7, 63, 5, -7 },
+ { -9, 28, 75, 7, 43, -6, -3 },
+ { -4, -4, 49, 7, 74, 22, -9 },
+ { -8, 10, 67, 7, 62, 4, -7 },
+ { -9, 29, 77, 7, 41, -7, -3 },
+ { -5, -3, 51, 7, 74, 20, -9 },
+ { -8, 12, 69, 7, 60, 2, -7 },
+ { -8, 31, 75, 7, 39, -7, -2 },
+ { -5, -2, 53, 7, 73, 18, -9 },
+ { -9, 13, 71, 7, 58, 1, -6 },
+ { -8, 33, 76, 7, 37, -8, -2 },
+ { -5, -1, 55, 7, 71, 17, -9 },
+ { -9, 15, 71, 7, 57, 0, -6 } },
+ .odd = { { -9, 16, 72, 7, 56, -1, -6 },
+ { -2, -8, 36, 7, 76, 34, -8 },
+ { -6, 1, 58, 7, 70, 14, -9 },
+ { -9, 18, 72, 7, 54, -2, -5 },
+ { -2, -7, 38, 7, 75, 32, -8 },
+ { -6, 2, 59, 7, 70, 12, -9 },
+ { -9, 19, 74, 7, 52, -3, -5 },
+ { -3, -7, 40, 7, 77, 30, -9 },
+ { -7, 3, 61, 7, 68, 11, -8 },
+ { -9, 21, 75, 7, 50, -4, -5 },
+ { -3, -6, 42, 7, 75, 29, -9 },
+ { -7, 5, 63, 7, 66, 9, -8 },
+ { -9, 23, 74, 7, 48, -4, -4 },
+ { -3, -6, 44, 7, 75, 27, -9 },
+ { -7, 6, 64, 7, 65, 8, -8 },
+ { -9, 25, 75, 7, 46, -5, -4 },
+ { -4, -5, 46, 7, 75, 25, -9 },
+ { -8, 8, 65, 7, 64, 6, -7 },
+ { -9, 27, 75, 7, 44, -6, -3 },
+ { -4, -4, 48, 7, 74, 23, -9 },
+ { -8, 9, 66, 7, 63, 5, -7 },
+ { -9, 29, 75, 7, 42, -6, -3 },
+ { -5, -4, 50, 7, 75, 21, -9 },
+ { -8, 11, 68, 7, 61, 3, -7 },
+ { -9, 30, 77, 7, 40, -7, -3 },
+ { -5, -3, 52, 7, 74, 19, -9 },
+ { -9, 12, 70, 7, 59, 2, -6 },
+ { -8, 32, 75, 7, 38, -7, -2 },
+ { -5, -2, 54, 7, 72, 18, -9 },
+ { -9, 14, 70, 7, 58, 1, -6 },
+ { -8, 34, 76, 7, 36, -8, -2 },
+ { -6, -1, 56, 7, 72, 16, -9 } } },
+ .ptrn_arr = { { 0x9ce739cf, 0xe739ce73, 0x39ce739c, 0xe7 } },
+ .sample_patrn_length = 106,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 22) = 0.592593 */
+ .hor_phase_arr = {
+ .even = { { -7, 35, 74, 7, 35, -7, -2 },
+ { -6, 0, 54, 7, 71, 18, -9 },
+ { -9, 14, 70, 7, 58, 2, -7 },
+ { -8, 32, 74, 7, 39, -6, -3 },
+ { -5, -2, 51, 7, 72, 21, -9 },
+ { -8, 11, 66, 7, 61, 5, -7 },
+ { -9, 28, 75, 7, 43, -5, -4 },
+ { -4, -4, 47, 7, 73, 25, -9 },
+ { -8, 8, 64, 7, 64, 8, -8 },
+ { -9, 25, 73, 7, 47, -4, -4 },
+ { -4, -5, 43, 7, 75, 28, -9 },
+ { -7, 5, 61, 7, 66, 11, -8 },
+ { -9, 21, 72, 7, 51, -2, -5 },
+ { -3, -6, 39, 7, 74, 32, -8 },
+ { -7, 2, 58, 7, 70, 14, -9 },
+ { -9, 18, 71, 7, 54, 0, -6 } },
+ .odd = { { -9, 16, 70, 7, 56, 1, -6 },
+ { -8, 34, 75, 7, 37, -7, -3 },
+ { -6, -1, 53, 7, 72, 19, -9 },
+ { -9, 13, 68, 7, 59, 4, -7 },
+ { -8, 30, 74, 7, 41, -6, -3 },
+ { -5, -3, 49, 7, 73, 23, -9 },
+ { -8, 10, 66, 7, 62, 6, -8 },
+ { -9, 27, 74, 7, 45, -5, -4 },
+ { -4, -5, 45, 7, 74, 27, -9 },
+ { -8, 6, 62, 7, 66, 10, -8 },
+ { -9, 23, 73, 7, 49, -3, -5 },
+ { -3, -6, 41, 7, 74, 30, -8 },
+ { -7, 4, 59, 7, 68, 13, -9 },
+ { -9, 19, 72, 7, 53, -1, -6 },
+ { -3, -7, 37, 7, 75, 34, -8 },
+ { -6, 1, 56, 7, 70, 16, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -7, 35, 74, 7, 35, -7, -2 },
+ { -6, 0, 54, 7, 71, 18, -9 },
+ { -9, 14, 70, 7, 58, 2, -7 },
+ { -8, 32, 74, 7, 39, -6, -3 },
+ { -5, -2, 51, 7, 72, 21, -9 },
+ { -8, 11, 66, 7, 61, 5, -7 },
+ { -9, 28, 75, 7, 43, -5, -4 },
+ { -4, -4, 47, 7, 73, 25, -9 },
+ { -8, 8, 64, 7, 64, 8, -8 },
+ { -9, 25, 73, 7, 47, -4, -4 },
+ { -4, -5, 43, 7, 75, 28, -9 },
+ { -7, 5, 61, 7, 66, 11, -8 },
+ { -9, 21, 72, 7, 51, -2, -5 },
+ { -3, -6, 39, 7, 74, 32, -8 },
+ { -7, 2, 58, 7, 70, 14, -9 },
+ { -9, 18, 71, 7, 54, 0, -6 } },
+ .odd = { { -9, 16, 70, 7, 56, 1, -6 },
+ { -8, 34, 75, 7, 37, -7, -3 },
+ { -6, -1, 53, 7, 72, 19, -9 },
+ { -9, 13, 68, 7, 59, 4, -7 },
+ { -8, 30, 74, 7, 41, -6, -3 },
+ { -5, -3, 49, 7, 73, 23, -9 },
+ { -8, 10, 66, 7, 62, 6, -8 },
+ { -9, 27, 74, 7, 45, -5, -4 },
+ { -4, -5, 45, 7, 74, 27, -9 },
+ { -8, 6, 62, 7, 66, 10, -8 },
+ { -9, 23, 73, 7, 49, -3, -5 },
+ { -3, -6, 41, 7, 74, 30, -8 },
+ { -7, 4, 59, 7, 68, 13, -9 },
+ { -9, 19, 72, 7, 53, -1, -6 },
+ { -3, -7, 37, 7, 75, 34, -8 },
+ { -6, 1, 56, 7, 70, 16, -9 } } },
+ .ptrn_arr = { { 0xce739ce7, 0xce739 } },
+ .sample_patrn_length = 54,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 23) = 0.581818 */
+ .hor_phase_arr = {
+ .even = { { -7, 36, 73, 7, 36, -7, -3 },
+ { -6, 0, 52, 7, 71, 20, -9 },
+ { -8, 12, 66, 7, 60, 6, -8 },
+ { -8, 27, 73, 7, 45, -4, -5 },
+ { -4, -4, 43, 7, 72, 29, -8 },
+ { -7, 5, 59, 7, 66, 14, -9 },
+ { -9, 19, 69, 7, 54, 1, -6 },
+ { -7, 34, 72, 7, 38, -6, -3 },
+ { -6, -1, 50, 7, 72, 22, -9 },
+ { -8, 11, 63, 7, 62, 8, -8 },
+ { -9, 26, 72, 7, 47, -3, -5 },
+ { -4, -5, 41, 7, 73, 31, -8 },
+ { -7, 4, 57, 7, 68, 15, -9 },
+ { -9, 17, 69, 7, 56, 2, -7 },
+ { -7, 32, 74, 7, 39, -6, -4 },
+ { -5, -2, 49, 7, 71, 24, -9 },
+ { -8, 9, 63, 7, 63, 9, -8 },
+ { -9, 24, 71, 7, 49, -2, -5 },
+ { -4, -6, 39, 7, 74, 32, -7 },
+ { -7, 2, 56, 7, 69, 17, -9 },
+ { -9, 15, 68, 7, 57, 4, -7 },
+ { -8, 31, 73, 7, 41, -5, -4 },
+ { -5, -3, 47, 7, 72, 26, -9 },
+ { -8, 8, 62, 7, 63, 11, -8 },
+ { -9, 22, 72, 7, 50, -1, -6 },
+ { -3, -6, 38, 7, 72, 34, -7 },
+ { -6, 1, 54, 7, 69, 19, -9 },
+ { -9, 14, 66, 7, 59, 5, -7 },
+ { -8, 29, 72, 7, 43, -4, -4 },
+ { -5, -4, 45, 7, 73, 27, -8 },
+ { -8, 6, 60, 7, 66, 12, -8 },
+ { -9, 20, 71, 7, 52, 0, -6 } },
+ .odd = { { -9, 16, 69, 7, 56, 3, -7 },
+ { -8, 31, 74, 7, 40, -5, -4 },
+ { -5, -2, 48, 7, 71, 25, -9 },
+ { -8, 8, 62, 7, 64, 10, -8 },
+ { -9, 23, 72, 7, 50, -2, -6 },
+ { -3, -6, 39, 7, 72, 33, -7 },
+ { -7, 2, 55, 7, 69, 18, -9 },
+ { -9, 15, 67, 7, 58, 4, -7 },
+ { -8, 30, 73, 7, 42, -5, -4 },
+ { -5, -3, 46, 7, 72, 26, -8 },
+ { -8, 7, 61, 7, 65, 11, -8 },
+ { -9, 21, 72, 7, 51, -1, -6 },
+ { -3, -6, 37, 7, 72, 35, -7 },
+ { -6, 1, 53, 7, 69, 20, -9 },
+ { -9, 13, 66, 7, 59, 6, -7 },
+ { -8, 28, 72, 7, 44, -4, -4 },
+ { -4, -4, 44, 7, 72, 28, -8 },
+ { -7, 6, 59, 7, 66, 13, -9 },
+ { -9, 20, 69, 7, 53, 1, -6 },
+ { -7, 35, 72, 7, 37, -6, -3 },
+ { -6, -1, 51, 7, 72, 21, -9 },
+ { -8, 11, 65, 7, 61, 7, -8 },
+ { -8, 26, 72, 7, 46, -3, -5 },
+ { -4, -5, 42, 7, 73, 30, -8 },
+ { -7, 4, 58, 7, 67, 15, -9 },
+ { -9, 18, 69, 7, 55, 2, -7 },
+ { -7, 33, 72, 7, 39, -6, -3 },
+ { -6, -2, 50, 7, 72, 23, -9 },
+ { -8, 10, 64, 7, 62, 8, -8 },
+ { -9, 25, 71, 7, 48, -2, -5 },
+ { -4, -5, 40, 7, 74, 31, -8 },
+ { -7, 3, 56, 7, 69, 16, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -7, 36, 73, 7, 36, -7, -3 },
+ { -6, 0, 52, 7, 71, 20, -9 },
+ { -8, 12, 66, 7, 60, 6, -8 },
+ { -8, 27, 73, 7, 45, -4, -5 },
+ { -4, -4, 43, 7, 72, 29, -8 },
+ { -7, 5, 59, 7, 66, 14, -9 },
+ { -9, 19, 69, 7, 54, 1, -6 },
+ { -7, 34, 72, 7, 38, -6, -3 },
+ { -6, -1, 50, 7, 72, 22, -9 },
+ { -8, 11, 63, 7, 62, 8, -8 },
+ { -9, 26, 72, 7, 47, -3, -5 },
+ { -4, -5, 41, 7, 73, 31, -8 },
+ { -7, 4, 57, 7, 68, 15, -9 },
+ { -9, 17, 69, 7, 56, 2, -7 },
+ { -7, 32, 74, 7, 39, -6, -4 },
+ { -5, -2, 49, 7, 71, 24, -9 },
+ { -8, 9, 63, 7, 63, 9, -8 },
+ { -9, 24, 71, 7, 49, -2, -5 },
+ { -4, -6, 39, 7, 74, 32, -7 },
+ { -7, 2, 56, 7, 69, 17, -9 },
+ { -9, 15, 68, 7, 57, 4, -7 },
+ { -8, 31, 73, 7, 41, -5, -4 },
+ { -5, -3, 47, 7, 72, 26, -9 },
+ { -8, 8, 62, 7, 63, 11, -8 },
+ { -9, 22, 72, 7, 50, -1, -6 },
+ { -3, -6, 38, 7, 72, 34, -7 },
+ { -6, 1, 54, 7, 69, 19, -9 },
+ { -9, 14, 66, 7, 59, 5, -7 },
+ { -8, 29, 72, 7, 43, -4, -4 },
+ { -5, -4, 45, 7, 73, 27, -8 },
+ { -8, 6, 60, 7, 66, 12, -8 },
+ { -9, 20, 71, 7, 52, 0, -6 } },
+ .odd = { { -9, 16, 69, 7, 56, 3, -7 },
+ { -8, 31, 74, 7, 40, -5, -4 },
+ { -5, -2, 48, 7, 71, 25, -9 },
+ { -8, 8, 62, 7, 64, 10, -8 },
+ { -9, 23, 72, 7, 50, -2, -6 },
+ { -3, -6, 39, 7, 72, 33, -7 },
+ { -7, 2, 55, 7, 69, 18, -9 },
+ { -9, 15, 67, 7, 58, 4, -7 },
+ { -8, 30, 73, 7, 42, -5, -4 },
+ { -5, -3, 46, 7, 72, 26, -8 },
+ { -8, 7, 61, 7, 65, 11, -8 },
+ { -9, 21, 72, 7, 51, -1, -6 },
+ { -3, -6, 37, 7, 72, 35, -7 },
+ { -6, 1, 53, 7, 69, 20, -9 },
+ { -9, 13, 66, 7, 59, 6, -7 },
+ { -8, 28, 72, 7, 44, -4, -4 },
+ { -4, -4, 44, 7, 72, 28, -8 },
+ { -7, 6, 59, 7, 66, 13, -9 },
+ { -9, 20, 69, 7, 53, 1, -6 },
+ { -7, 35, 72, 7, 37, -6, -3 },
+ { -6, -1, 51, 7, 72, 21, -9 },
+ { -8, 11, 65, 7, 61, 7, -8 },
+ { -8, 26, 72, 7, 46, -3, -5 },
+ { -4, -5, 42, 7, 73, 30, -8 },
+ { -7, 4, 58, 7, 67, 15, -9 },
+ { -9, 18, 69, 7, 55, 2, -7 },
+ { -7, 33, 72, 7, 39, -6, -3 },
+ { -6, -2, 50, 7, 72, 23, -9 },
+ { -8, 10, 64, 7, 62, 8, -8 },
+ { -9, 25, 71, 7, 48, -2, -5 },
+ { -4, -5, 40, 7, 74, 31, -8 },
+ { -7, 3, 56, 7, 69, 16, -9 } } },
+ .ptrn_arr = { { 0xe7339ce7, 0x9ce7339c, 0x399ce739, 0xce7 } },
+ .sample_patrn_length = 110,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 24) = 0.571429 */
+ .hor_phase_arr = {
+ .even = { { -6, 36, 71, 7, 36, -6, -3 },
+ { -6, 0, 50, 7, 69, 23, -8 },
+ { -8, 10, 62, 7, 62, 10, -8 },
+ { -8, 23, 69, 7, 50, 0, -6 } },
+ .odd = { { -9, 16, 67, 7, 56, 5, -7 },
+ { -8, 29, 73, 7, 43, -4, -5 },
+ { -5, -4, 43, 7, 73, 29, -8 },
+ { -7, 5, 56, 7, 67, 16, -9 } } },
+ .ver_phase_arr = {
+ .even = { { -6, 36, 71, 7, 36, -6, -3 },
+ { -6, 0, 50, 7, 69, 23, -8 },
+ { -8, 10, 62, 7, 62, 10, -8 },
+ { -8, 23, 69, 7, 50, 0, -6 } },
+ .odd = { { -9, 16, 67, 7, 56, 5, -7 },
+ { -8, 29, 73, 7, 43, -4, -5 },
+ { -5, -4, 43, 7, 73, 29, -8 },
+ { -7, 5, 56, 7, 67, 16, -9 } } },
+ .ptrn_arr = { { 0xce7 } },
+ .sample_patrn_length = 14,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 25) = 0.561404 */
+ .hor_phase_arr = {
+ .even = { { -5, 36, 70, 7, 36, -5, -4 },
+ { -6, 0, 48, 7, 69, 25, -8 },
+ { -8, 8, 59, 7, 63, 14, -8 },
+ { -8, 19, 66, 7, 54, 4, -7 },
+ { -7, 30, 70, 7, 43, -3, -5 },
+ { -5, -3, 41, 7, 70, 32, -7 },
+ { -7, 3, 53, 7, 67, 20, -8 },
+ { -8, 13, 61, 7, 60, 10, -8 },
+ { -8, 24, 67, 7, 50, 1, -6 },
+ { -6, 35, 70, 7, 38, -5, -4 },
+ { -6, -1, 46, 7, 70, 27, -8 },
+ { -8, 7, 57, 7, 64, 16, -8 },
+ { -8, 17, 64, 7, 56, 6, -7 },
+ { -7, 28, 69, 7, 45, -2, -5 },
+ { -4, -4, 40, 7, 69, 33, -6 },
+ { -7, 2, 51, 7, 68, 22, -8 },
+ { -8, 11, 61, 7, 61, 11, -8 },
+ { -8, 22, 68, 7, 51, 2, -7 },
+ { -6, 33, 69, 7, 40, -4, -4 },
+ { -5, -2, 45, 7, 69, 28, -7 },
+ { -7, 6, 56, 7, 64, 17, -8 },
+ { -8, 16, 64, 7, 57, 7, -8 },
+ { -8, 27, 70, 7, 46, -1, -6 },
+ { -4, -5, 38, 7, 70, 35, -6 },
+ { -6, 1, 50, 7, 67, 24, -8 },
+ { -8, 10, 60, 7, 61, 13, -8 },
+ { -8, 20, 67, 7, 53, 3, -7 },
+ { -7, 32, 70, 7, 41, -3, -5 },
+ { -5, -3, 43, 7, 70, 30, -7 },
+ { -7, 4, 54, 7, 66, 19, -8 },
+ { -8, 14, 63, 7, 59, 8, -8 },
+ { -8, 25, 69, 7, 48, 0, -6 } },
+ .odd = { { -8, 16, 66, 7, 56, 6, -8 },
+ { -8, 28, 69, 7, 46, -1, -6 },
+ { -4, -4, 39, 7, 69, 34, -6 },
+ { -7, 2, 51, 7, 67, 23, -8 },
+ { -8, 10, 60, 7, 62, 12, -8 },
+ { -8, 21, 67, 7, 52, 3, -7 },
+ { -7, 32, 71, 7, 41, -4, -5 },
+ { -5, -2, 44, 7, 69, 29, -7 },
+ { -7, 5, 55, 7, 65, 18, -8 },
+ { -8, 15, 63, 7, 58, 8, -8 },
+ { -8, 26, 69, 7, 47, 0, -6 },
+ { -4, -5, 37, 7, 71, 35, -6 },
+ { -6, 1, 49, 7, 68, 24, -8 },
+ { -8, 9, 59, 7, 63, 13, -8 },
+ { -8, 20, 65, 7, 54, 4, -7 },
+ { -7, 31, 70, 7, 42, -3, -5 },
+ { -5, -3, 42, 7, 70, 31, -7 },
+ { -7, 4, 54, 7, 65, 20, -8 },
+ { -8, 13, 63, 7, 59, 9, -8 },
+ { -8, 24, 68, 7, 49, 1, -6 },
+ { -6, 35, 71, 7, 37, -5, -4 },
+ { -6, 0, 47, 7, 69, 26, -8 },
+ { -8, 8, 58, 7, 63, 15, -8 },
+ { -8, 18, 65, 7, 55, 5, -7 },
+ { -7, 29, 69, 7, 44, -2, -5 },
+ { -5, -4, 41, 7, 71, 32, -7 },
+ { -7, 3, 52, 7, 67, 21, -8 },
+ { -8, 12, 62, 7, 60, 10, -8 },
+ { -8, 23, 67, 7, 51, 2, -7 },
+ { -6, 34, 69, 7, 39, -4, -4 },
+ { -6, -1, 46, 7, 69, 28, -8 },
+ { -8, 6, 56, 7, 66, 16, -8 } } },
+ .ver_phase_arr = {
+ .even = { { -5, 36, 70, 7, 36, -5, -4 },
+ { -6, 0, 48, 7, 69, 25, -8 },
+ { -8, 8, 59, 7, 63, 14, -8 },
+ { -8, 19, 66, 7, 54, 4, -7 },
+ { -7, 30, 70, 7, 43, -3, -5 },
+ { -5, -3, 41, 7, 70, 32, -7 },
+ { -7, 3, 53, 7, 67, 20, -8 },
+ { -8, 13, 61, 7, 60, 10, -8 },
+ { -8, 24, 67, 7, 50, 1, -6 },
+ { -6, 35, 70, 7, 38, -5, -4 },
+ { -6, -1, 46, 7, 70, 27, -8 },
+ { -8, 7, 57, 7, 64, 16, -8 },
+ { -8, 17, 64, 7, 56, 6, -7 },
+ { -7, 28, 69, 7, 45, -2, -5 },
+ { -4, -4, 40, 7, 69, 33, -6 },
+ { -7, 2, 51, 7, 68, 22, -8 },
+ { -8, 11, 61, 7, 61, 11, -8 },
+ { -8, 22, 68, 7, 51, 2, -7 },
+ { -6, 33, 69, 7, 40, -4, -4 },
+ { -5, -2, 45, 7, 69, 28, -7 },
+ { -7, 6, 56, 7, 64, 17, -8 },
+ { -8, 16, 64, 7, 57, 7, -8 },
+ { -8, 27, 70, 7, 46, -1, -6 },
+ { -4, -5, 38, 7, 70, 35, -6 },
+ { -6, 1, 50, 7, 67, 24, -8 },
+ { -8, 10, 60, 7, 61, 13, -8 },
+ { -8, 20, 67, 7, 53, 3, -7 },
+ { -7, 32, 70, 7, 41, -3, -5 },
+ { -5, -3, 43, 7, 70, 30, -7 },
+ { -7, 4, 54, 7, 66, 19, -8 },
+ { -8, 14, 63, 7, 59, 8, -8 },
+ { -8, 25, 69, 7, 48, 0, -6 } },
+ .odd = { { -8, 16, 66, 7, 56, 6, -8 },
+ { -8, 28, 69, 7, 46, -1, -6 },
+ { -4, -4, 39, 7, 69, 34, -6 },
+ { -7, 2, 51, 7, 67, 23, -8 },
+ { -8, 10, 60, 7, 62, 12, -8 },
+ { -8, 21, 67, 7, 52, 3, -7 },
+ { -7, 32, 71, 7, 41, -4, -5 },
+ { -5, -2, 44, 7, 69, 29, -7 },
+ { -7, 5, 55, 7, 65, 18, -8 },
+ { -8, 15, 63, 7, 58, 8, -8 },
+ { -8, 26, 69, 7, 47, 0, -6 },
+ { -4, -5, 37, 7, 71, 35, -6 },
+ { -6, 1, 49, 7, 68, 24, -8 },
+ { -8, 9, 59, 7, 63, 13, -8 },
+ { -8, 20, 65, 7, 54, 4, -7 },
+ { -7, 31, 70, 7, 42, -3, -5 },
+ { -5, -3, 42, 7, 70, 31, -7 },
+ { -7, 4, 54, 7, 65, 20, -8 },
+ { -8, 13, 63, 7, 59, 9, -8 },
+ { -8, 24, 68, 7, 49, 1, -6 },
+ { -6, 35, 71, 7, 37, -5, -4 },
+ { -6, 0, 47, 7, 69, 26, -8 },
+ { -8, 8, 58, 7, 63, 15, -8 },
+ { -8, 18, 65, 7, 55, 5, -7 },
+ { -7, 29, 69, 7, 44, -2, -5 },
+ { -5, -4, 41, 7, 71, 32, -7 },
+ { -7, 3, 52, 7, 67, 21, -8 },
+ { -8, 12, 62, 7, 60, 10, -8 },
+ { -8, 23, 67, 7, 51, 2, -7 },
+ { -6, 34, 69, 7, 39, -4, -4 },
+ { -6, -1, 46, 7, 69, 28, -8 },
+ { -8, 6, 56, 7, 66, 16, -8 } } },
+ .ptrn_arr = { { 0x3399cce7, 0x3399cce7, 0x3399ce67, 0xce67 } },
+ .sample_patrn_length = 114,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 26) = 0.551724 */
+ .hor_phase_arr = {
+ .even = { { -5, 36, 70, 7, 36, -5, -4 },
+ { -6, 0, 46, 7, 68, 27, -7 },
+ { -8, 7, 55, 7, 64, 18, -8 },
+ { -8, 15, 62, 7, 58, 9, -8 },
+ { -8, 24, 68, 7, 49, 2, -7 },
+ { -6, 33, 69, 7, 40, -3, -5 },
+ { -6, -2, 43, 7, 70, 30, -7 },
+ { -7, 4, 52, 7, 66, 21, -8 },
+ { -8, 12, 60, 7, 60, 12, -8 },
+ { -8, 21, 66, 7, 52, 4, -7 },
+ { -7, 30, 70, 7, 43, -2, -6 },
+ { -5, -3, 40, 7, 69, 33, -6 },
+ { -7, 2, 49, 7, 68, 24, -8 },
+ { -8, 9, 58, 7, 62, 15, -8 },
+ { -8, 18, 64, 7, 55, 7, -8 },
+ { -7, 27, 68, 7, 46, 0, -6 } },
+ .odd = { { -8, 17, 63, 7, 56, 8, -8 },
+ { -8, 26, 67, 7, 48, 1, -6 },
+ { -5, 35, 69, 7, 38, -4, -5 },
+ { -6, -1, 45, 7, 68, 29, -7 },
+ { -7, 5, 54, 7, 64, 20, -8 },
+ { -8, 14, 60, 7, 59, 11, -8 },
+ { -8, 23, 66, 7, 51, 3, -7 },
+ { -6, 32, 69, 7, 41, -3, -5 },
+ { -5, -3, 41, 7, 69, 32, -6 },
+ { -7, 3, 51, 7, 66, 23, -8 },
+ { -8, 11, 59, 7, 60, 14, -8 },
+ { -8, 20, 64, 7, 54, 5, -7 },
+ { -7, 29, 68, 7, 45, -1, -6 },
+ { -5, -4, 38, 7, 69, 35, -5 },
+ { -6, 1, 48, 7, 67, 26, -8 },
+ { -8, 8, 56, 7, 63, 17, -8 } } },
+ .ver_phase_arr = {
+ .even = { { -5, 36, 70, 7, 36, -5, -4 },
+ { -6, 0, 46, 7, 68, 27, -7 },
+ { -8, 7, 55, 7, 64, 18, -8 },
+ { -8, 15, 62, 7, 58, 9, -8 },
+ { -8, 24, 68, 7, 49, 2, -7 },
+ { -6, 33, 69, 7, 40, -3, -5 },
+ { -6, -2, 43, 7, 70, 30, -7 },
+ { -7, 4, 52, 7, 66, 21, -8 },
+ { -8, 12, 60, 7, 60, 12, -8 },
+ { -8, 21, 66, 7, 52, 4, -7 },
+ { -7, 30, 70, 7, 43, -2, -6 },
+ { -5, -3, 40, 7, 69, 33, -6 },
+ { -7, 2, 49, 7, 68, 24, -8 },
+ { -8, 9, 58, 7, 62, 15, -8 },
+ { -8, 18, 64, 7, 55, 7, -8 },
+ { -7, 27, 68, 7, 46, 0, -6 } },
+ .odd = { { -8, 17, 63, 7, 56, 8, -8 },
+ { -8, 26, 67, 7, 48, 1, -6 },
+ { -5, 35, 69, 7, 38, -4, -5 },
+ { -6, -1, 45, 7, 68, 29, -7 },
+ { -7, 5, 54, 7, 64, 20, -8 },
+ { -8, 14, 60, 7, 59, 11, -8 },
+ { -8, 23, 66, 7, 51, 3, -7 },
+ { -6, 32, 69, 7, 41, -3, -5 },
+ { -5, -3, 41, 7, 69, 32, -6 },
+ { -7, 3, 51, 7, 66, 23, -8 },
+ { -8, 11, 59, 7, 60, 14, -8 },
+ { -8, 20, 64, 7, 54, 5, -7 },
+ { -7, 29, 68, 7, 45, -1, -6 },
+ { -5, -4, 38, 7, 69, 35, -5 },
+ { -6, 1, 48, 7, 67, 26, -8 },
+ { -8, 8, 56, 7, 63, 17, -8 } } },
+ .ptrn_arr = { { 0x399cce67, 0xcce673 } },
+ .sample_patrn_length = 58,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 27) = 0.542373 */
+ .hor_phase_arr = {
+ .even = { { -4, 37, 67, 7, 37, -4, -5 },
+ { -6, 0, 44, 7, 67, 29, -6 },
+ { -7, 5, 52, 7, 64, 22, -8 },
+ { -8, 12, 58, 7, 60, 14, -8 },
+ { -8, 19, 63, 7, 54, 8, -8 },
+ { -7, 26, 67, 7, 47, 2, -7 },
+ { -5, 34, 66, 7, 40, -2, -5 },
+ { -6, -2, 41, 7, 68, 32, -5 },
+ { -7, 3, 49, 7, 65, 25, -7 },
+ { -8, 9, 56, 7, 62, 17, -8 },
+ { -8, 16, 61, 7, 57, 10, -8 },
+ { -8, 23, 66, 7, 50, 4, -7 },
+ { -6, 31, 67, 7, 43, -1, -6 },
+ { -5, -3, 38, 7, 67, 35, -4 },
+ { -6, 1, 46, 7, 66, 28, -7 },
+ { -8, 6, 53, 7, 65, 20, -8 },
+ { -8, 13, 59, 7, 59, 13, -8 },
+ { -8, 20, 65, 7, 53, 6, -8 },
+ { -7, 28, 66, 7, 46, 1, -6 },
+ { -4, 35, 67, 7, 38, -3, -5 },
+ { -6, -1, 43, 7, 67, 31, -6 },
+ { -7, 4, 50, 7, 66, 23, -8 },
+ { -8, 10, 57, 7, 61, 16, -8 },
+ { -8, 17, 62, 7, 56, 9, -8 },
+ { -7, 25, 65, 7, 49, 3, -7 },
+ { -5, 32, 68, 7, 41, -2, -6 },
+ { -5, -2, 40, 7, 66, 34, -5 },
+ { -7, 2, 47, 7, 67, 26, -7 },
+ { -8, 8, 54, 7, 63, 19, -8 },
+ { -8, 14, 60, 7, 58, 12, -8 },
+ { -8, 22, 64, 7, 52, 5, -7 },
+ { -6, 29, 67, 7, 44, 0, -6 } },
+ .odd = { { -8, 17, 61, 7, 56, 10, -8 },
+ { -7, 24, 64, 7, 50, 4, -7 },
+ { -6, 31, 68, 7, 42, -1, -6 },
+ { -5, -3, 39, 7, 68, 34, -5 },
+ { -7, 1, 47, 7, 67, 27, -7 },
+ { -8, 7, 54, 7, 64, 19, -8 },
+ { -8, 14, 59, 7, 59, 12, -8 },
+ { -8, 21, 64, 7, 52, 6, -7 },
+ { -7, 28, 68, 7, 45, 0, -6 },
+ { -4, 36, 68, 7, 37, -4, -5 },
+ { -6, 0, 44, 7, 66, 30, -6 },
+ { -7, 5, 51, 7, 65, 22, -8 },
+ { -8, 11, 57, 7, 61, 15, -8 },
+ { -8, 18, 63, 7, 55, 8, -8 },
+ { -7, 25, 67, 7, 48, 2, -7 },
+ { -5, 33, 66, 7, 41, -2, -5 },
+ { -5, -2, 41, 7, 66, 33, -5 },
+ { -7, 2, 48, 7, 67, 25, -7 },
+ { -8, 8, 55, 7, 63, 18, -8 },
+ { -8, 15, 61, 7, 57, 11, -8 },
+ { -8, 22, 65, 7, 51, 5, -7 },
+ { -6, 30, 66, 7, 44, 0, -6 },
+ { -5, -4, 37, 7, 68, 36, -4 },
+ { -6, 0, 45, 7, 68, 28, -7 },
+ { -7, 6, 52, 7, 64, 21, -8 },
+ { -8, 12, 59, 7, 59, 14, -8 },
+ { -8, 19, 64, 7, 54, 7, -8 },
+ { -7, 27, 67, 7, 47, 1, -7 },
+ { -5, 34, 68, 7, 39, -3, -5 },
+ { -6, -1, 42, 7, 68, 31, -6 },
+ { -7, 4, 50, 7, 64, 24, -7 },
+ { -8, 10, 56, 7, 61, 17, -8 } } },
+ .ver_phase_arr = {
+ .even = { { -4, 37, 67, 7, 37, -4, -5 },
+ { -6, 0, 44, 7, 67, 29, -6 },
+ { -7, 5, 52, 7, 64, 22, -8 },
+ { -8, 12, 58, 7, 60, 14, -8 },
+ { -8, 19, 63, 7, 54, 8, -8 },
+ { -7, 26, 67, 7, 47, 2, -7 },
+ { -5, 34, 66, 7, 40, -2, -5 },
+ { -6, -2, 41, 7, 68, 32, -5 },
+ { -7, 3, 49, 7, 65, 25, -7 },
+ { -8, 9, 56, 7, 62, 17, -8 },
+ { -8, 16, 61, 7, 57, 10, -8 },
+ { -8, 23, 66, 7, 50, 4, -7 },
+ { -6, 31, 67, 7, 43, -1, -6 },
+ { -5, -3, 38, 7, 67, 35, -4 },
+ { -6, 1, 46, 7, 66, 28, -7 },
+ { -8, 6, 53, 7, 65, 20, -8 },
+ { -8, 13, 59, 7, 59, 13, -8 },
+ { -8, 20, 65, 7, 53, 6, -8 },
+ { -7, 28, 66, 7, 46, 1, -6 },
+ { -4, 35, 67, 7, 38, -3, -5 },
+ { -6, -1, 43, 7, 67, 31, -6 },
+ { -7, 4, 50, 7, 66, 23, -8 },
+ { -8, 10, 57, 7, 61, 16, -8 },
+ { -8, 17, 62, 7, 56, 9, -8 },
+ { -7, 25, 65, 7, 49, 3, -7 },
+ { -5, 32, 68, 7, 41, -2, -6 },
+ { -5, -2, 40, 7, 66, 34, -5 },
+ { -7, 2, 47, 7, 67, 26, -7 },
+ { -8, 8, 54, 7, 63, 19, -8 },
+ { -8, 14, 60, 7, 58, 12, -8 },
+ { -8, 22, 64, 7, 52, 5, -7 },
+ { -6, 29, 67, 7, 44, 0, -6 } },
+ .odd = { { -8, 17, 61, 7, 56, 10, -8 },
+ { -7, 24, 64, 7, 50, 4, -7 },
+ { -6, 31, 68, 7, 42, -1, -6 },
+ { -5, -3, 39, 7, 68, 34, -5 },
+ { -7, 1, 47, 7, 67, 27, -7 },
+ { -8, 7, 54, 7, 64, 19, -8 },
+ { -8, 14, 59, 7, 59, 12, -8 },
+ { -8, 21, 64, 7, 52, 6, -7 },
+ { -7, 28, 68, 7, 45, 0, -6 },
+ { -4, 36, 68, 7, 37, -4, -5 },
+ { -6, 0, 44, 7, 66, 30, -6 },
+ { -7, 5, 51, 7, 65, 22, -8 },
+ { -8, 11, 57, 7, 61, 15, -8 },
+ { -8, 18, 63, 7, 55, 8, -8 },
+ { -7, 25, 67, 7, 48, 2, -7 },
+ { -5, 33, 66, 7, 41, -2, -5 },
+ { -5, -2, 41, 7, 66, 33, -5 },
+ { -7, 2, 48, 7, 67, 25, -7 },
+ { -8, 8, 55, 7, 63, 18, -8 },
+ { -8, 15, 61, 7, 57, 11, -8 },
+ { -8, 22, 65, 7, 51, 5, -7 },
+ { -6, 30, 66, 7, 44, 0, -6 },
+ { -5, -4, 37, 7, 68, 36, -4 },
+ { -6, 0, 45, 7, 68, 28, -7 },
+ { -7, 6, 52, 7, 64, 21, -8 },
+ { -8, 12, 59, 7, 59, 14, -8 },
+ { -8, 19, 64, 7, 54, 7, -8 },
+ { -7, 27, 67, 7, 47, 1, -7 },
+ { -5, 34, 68, 7, 39, -3, -5 },
+ { -6, -1, 42, 7, 68, 31, -6 },
+ { -7, 4, 50, 7, 64, 24, -7 },
+ { -8, 10, 56, 7, 61, 17, -8 } } },
+ .ptrn_arr = { { 0x99ccce67, 0xce667339, 0x733399cc, 0xcce66 } },
+ .sample_patrn_length = 118,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 28) = 0.533333 */
+ .hor_phase_arr = {
+ .even = { { -3, 37, 65, 7, 37, -3, -5 },
+ { -6, 0, 43, 7, 65, 31, -5 },
+ { -7, 4, 48, 7, 65, 25, -7 },
+ { -8, 9, 54, 7, 62, 19, -8 },
+ { -8, 14, 58, 7, 58, 14, -8 },
+ { -8, 19, 62, 7, 54, 9, -8 },
+ { -7, 25, 65, 7, 48, 4, -7 },
+ { -5, 31, 65, 7, 43, 0, -6 } },
+ .odd = { { -8, 17, 60, 7, 56, 11, -8 },
+ { -7, 22, 63, 7, 51, 6, -7 },
+ { -6, 28, 65, 7, 46, 2, -7 },
+ { -4, 34, 66, 7, 40, -2, -6 },
+ { -6, -2, 40, 7, 66, 34, -4 },
+ { -7, 2, 46, 7, 65, 28, -6 },
+ { -7, 6, 51, 7, 63, 22, -7 },
+ { -8, 11, 56, 7, 60, 17, -8 } } },
+ .ver_phase_arr = {
+ .even = { { -3, 37, 65, 7, 37, -3, -5 },
+ { -6, 0, 43, 7, 65, 31, -5 },
+ { -7, 4, 48, 7, 65, 25, -7 },
+ { -8, 9, 54, 7, 62, 19, -8 },
+ { -8, 14, 58, 7, 58, 14, -8 },
+ { -8, 19, 62, 7, 54, 9, -8 },
+ { -7, 25, 65, 7, 48, 4, -7 },
+ { -5, 31, 65, 7, 43, 0, -6 } },
+ .odd = { { -8, 17, 60, 7, 56, 11, -8 },
+ { -7, 22, 63, 7, 51, 6, -7 },
+ { -6, 28, 65, 7, 46, 2, -7 },
+ { -4, 34, 66, 7, 40, -2, -6 },
+ { -6, -2, 40, 7, 66, 34, -4 },
+ { -7, 2, 46, 7, 65, 28, -6 },
+ { -7, 6, 51, 7, 63, 22, -7 },
+ { -8, 11, 56, 7, 60, 17, -8 } } },
+ .ptrn_arr = { { 0xccce667 } },
+ .sample_patrn_length = 30,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 29) = 0.52459 */
+ .hor_phase_arr = {
+ .even = { { -2, 37, 63, 7, 37, -2, -5 },
+ { -6, 0, 41, 7, 64, 33, -4 },
+ { -7, 3, 45, 7, 65, 28, -6 },
+ { -7, 6, 49, 7, 63, 24, -7 },
+ { -8, 9, 53, 7, 61, 20, -7 },
+ { -8, 13, 56, 7, 59, 16, -8 },
+ { -8, 17, 60, 7, 55, 12, -8 },
+ { -7, 21, 62, 7, 52, 8, -8 },
+ { -6, 26, 62, 7, 48, 5, -7 },
+ { -5, 30, 64, 7, 44, 2, -7 },
+ { -4, 34, 65, 7, 40, -1, -6 },
+ { -6, -2, 38, 7, 66, 35, -3 },
+ { -6, 1, 42, 7, 65, 31, -5 },
+ { -7, 4, 47, 7, 63, 27, -6 },
+ { -7, 7, 50, 7, 62, 23, -7 },
+ { -8, 11, 54, 7, 59, 19, -7 },
+ { -8, 15, 57, 7, 57, 15, -8 },
+ { -7, 19, 59, 7, 54, 11, -8 },
+ { -7, 23, 62, 7, 50, 7, -7 },
+ { -6, 27, 63, 7, 47, 4, -7 },
+ { -5, 31, 65, 7, 42, 1, -6 },
+ { -3, 35, 66, 7, 38, -2, -6 },
+ { -6, -1, 40, 7, 65, 34, -4 },
+ { -7, 2, 44, 7, 64, 30, -5 },
+ { -7, 5, 48, 7, 62, 26, -6 },
+ { -8, 8, 52, 7, 62, 21, -7 },
+ { -8, 12, 55, 7, 60, 17, -8 },
+ { -8, 16, 59, 7, 56, 13, -8 },
+ { -7, 20, 61, 7, 53, 9, -8 },
+ { -7, 24, 63, 7, 49, 6, -7 },
+ { -6, 28, 65, 7, 45, 3, -7 },
+ { -4, 33, 64, 7, 41, 0, -6 } },
+ .odd = { { -8, 17, 58, 7, 56, 13, -8 },
+ { -7, 21, 61, 7, 52, 9, -8 },
+ { -6, 25, 62, 7, 49, 5, -7 },
+ { -5, 29, 64, 7, 45, 2, -7 },
+ { -4, 33, 65, 7, 40, 0, -6 },
+ { -6, -2, 37, 7, 66, 36, -3 },
+ { -6, 0, 42, 7, 64, 32, -4 },
+ { -7, 3, 46, 7, 64, 28, -6 },
+ { -7, 7, 50, 7, 61, 24, -7 },
+ { -8, 10, 53, 7, 61, 19, -7 },
+ { -8, 14, 57, 7, 58, 15, -8 },
+ { -8, 18, 60, 7, 55, 11, -8 },
+ { -7, 22, 62, 7, 51, 8, -8 },
+ { -6, 26, 64, 7, 47, 4, -7 },
+ { -5, 31, 65, 7, 43, 1, -7 },
+ { -3, 35, 64, 7, 39, -1, -6 },
+ { -6, -1, 39, 7, 64, 35, -3 },
+ { -7, 1, 43, 7, 65, 31, -5 },
+ { -7, 4, 47, 7, 64, 26, -6 },
+ { -8, 8, 51, 7, 62, 22, -7 },
+ { -8, 11, 55, 7, 60, 18, -8 },
+ { -8, 15, 58, 7, 57, 14, -8 },
+ { -7, 19, 61, 7, 53, 10, -8 },
+ { -7, 24, 61, 7, 50, 7, -7 },
+ { -6, 28, 64, 7, 46, 3, -7 },
+ { -4, 32, 64, 7, 42, 0, -6 },
+ { -3, 36, 66, 7, 37, -2, -6 },
+ { -6, 0, 40, 7, 65, 33, -4 },
+ { -7, 2, 45, 7, 64, 29, -5 },
+ { -7, 5, 49, 7, 62, 25, -6 },
+ { -8, 9, 52, 7, 61, 21, -7 },
+ { -8, 13, 56, 7, 58, 17, -8 } } },
+ .ver_phase_arr = {
+ .even = { { -2, 37, 63, 7, 37, -2, -5 },
+ { -6, 0, 41, 7, 64, 33, -4 },
+ { -7, 3, 45, 7, 65, 28, -6 },
+ { -7, 6, 49, 7, 63, 24, -7 },
+ { -8, 9, 53, 7, 61, 20, -7 },
+ { -8, 13, 56, 7, 59, 16, -8 },
+ { -8, 17, 60, 7, 55, 12, -8 },
+ { -7, 21, 62, 7, 52, 8, -8 },
+ { -6, 26, 62, 7, 48, 5, -7 },
+ { -5, 30, 64, 7, 44, 2, -7 },
+ { -4, 34, 65, 7, 40, -1, -6 },
+ { -6, -2, 38, 7, 66, 35, -3 },
+ { -6, 1, 42, 7, 65, 31, -5 },
+ { -7, 4, 47, 7, 63, 27, -6 },
+ { -7, 7, 50, 7, 62, 23, -7 },
+ { -8, 11, 54, 7, 59, 19, -7 },
+ { -8, 15, 57, 7, 57, 15, -8 },
+ { -7, 19, 59, 7, 54, 11, -8 },
+ { -7, 23, 62, 7, 50, 7, -7 },
+ { -6, 27, 63, 7, 47, 4, -7 },
+ { -5, 31, 65, 7, 42, 1, -6 },
+ { -3, 35, 66, 7, 38, -2, -6 },
+ { -6, -1, 40, 7, 65, 34, -4 },
+ { -7, 2, 44, 7, 64, 30, -5 },
+ { -7, 5, 48, 7, 62, 26, -6 },
+ { -8, 8, 52, 7, 62, 21, -7 },
+ { -8, 12, 55, 7, 60, 17, -8 },
+ { -8, 16, 59, 7, 56, 13, -8 },
+ { -7, 20, 61, 7, 53, 9, -8 },
+ { -7, 24, 63, 7, 49, 6, -7 },
+ { -6, 28, 65, 7, 45, 3, -7 },
+ { -4, 33, 64, 7, 41, 0, -6 } },
+ .odd = { { -8, 17, 58, 7, 56, 13, -8 },
+ { -7, 21, 61, 7, 52, 9, -8 },
+ { -6, 25, 62, 7, 49, 5, -7 },
+ { -5, 29, 64, 7, 45, 2, -7 },
+ { -4, 33, 65, 7, 40, 0, -6 },
+ { -6, -2, 37, 7, 66, 36, -3 },
+ { -6, 0, 42, 7, 64, 32, -4 },
+ { -7, 3, 46, 7, 64, 28, -6 },
+ { -7, 7, 50, 7, 61, 24, -7 },
+ { -8, 10, 53, 7, 61, 19, -7 },
+ { -8, 14, 57, 7, 58, 15, -8 },
+ { -8, 18, 60, 7, 55, 11, -8 },
+ { -7, 22, 62, 7, 51, 8, -8 },
+ { -6, 26, 64, 7, 47, 4, -7 },
+ { -5, 31, 65, 7, 43, 1, -7 },
+ { -3, 35, 64, 7, 39, -1, -6 },
+ { -6, -1, 39, 7, 64, 35, -3 },
+ { -7, 1, 43, 7, 65, 31, -5 },
+ { -7, 4, 47, 7, 64, 26, -6 },
+ { -8, 8, 51, 7, 62, 22, -7 },
+ { -8, 11, 55, 7, 60, 18, -8 },
+ { -8, 15, 58, 7, 57, 14, -8 },
+ { -7, 19, 61, 7, 53, 10, -8 },
+ { -7, 24, 61, 7, 50, 7, -7 },
+ { -6, 28, 64, 7, 46, 3, -7 },
+ { -4, 32, 64, 7, 42, 0, -6 },
+ { -3, 36, 66, 7, 37, -2, -6 },
+ { -6, 0, 40, 7, 65, 33, -4 },
+ { -7, 2, 45, 7, 64, 29, -5 },
+ { -7, 5, 49, 7, 62, 25, -6 },
+ { -8, 9, 52, 7, 61, 21, -7 },
+ { -8, 13, 56, 7, 58, 17, -8 } } },
+ .ptrn_arr = { { 0xccce6667, 0x399999cc, 0x66673333, 0xcccce6 } },
+ .sample_patrn_length = 122,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 30) = 0.516129 */
+ .hor_phase_arr = {
+ .even = { { -2, 37, 64, 7, 37, -2, -6 },
+ { -6, 0, 39, 7, 64, 34, -3 },
+ { -7, 2, 42, 7, 64, 31, -4 },
+ { -7, 4, 45, 7, 62, 29, -5 },
+ { -7, 6, 47, 7, 62, 26, -6 },
+ { -7, 8, 50, 7, 60, 23, -6 },
+ { -8, 10, 52, 7, 60, 21, -7 },
+ { -8, 13, 54, 7, 58, 18, -7 },
+ { -8, 15, 58, 7, 56, 15, -8 },
+ { -7, 18, 58, 7, 54, 13, -8 },
+ { -7, 21, 60, 7, 52, 10, -8 },
+ { -6, 23, 60, 7, 50, 8, -7 },
+ { -6, 26, 62, 7, 47, 6, -7 },
+ { -5, 29, 62, 7, 45, 4, -7 },
+ { -4, 31, 64, 7, 42, 2, -7 },
+ { -3, 34, 64, 7, 39, 0, -6 } },
+ .odd = { { -7, 17, 57, 7, 55, 14, -8 },
+ { -7, 19, 59, 7, 53, 12, -8 },
+ { -7, 22, 61, 7, 51, 9, -8 },
+ { -6, 25, 60, 7, 49, 7, -7 },
+ { -5, 27, 62, 7, 46, 5, -7 },
+ { -5, 30, 63, 7, 44, 3, -7 },
+ { -3, 33, 62, 7, 41, 1, -6 },
+ { -2, 35, 64, 7, 38, -1, -6 },
+ { -6, -1, 38, 7, 64, 35, -2 },
+ { -6, 1, 41, 7, 62, 33, -3 },
+ { -7, 3, 44, 7, 63, 30, -5 },
+ { -7, 5, 46, 7, 62, 27, -5 },
+ { -7, 7, 49, 7, 60, 25, -6 },
+ { -8, 9, 51, 7, 61, 22, -7 },
+ { -8, 12, 53, 7, 59, 19, -7 },
+ { -8, 14, 55, 7, 57, 17, -7 } } },
+ .ver_phase_arr = {
+ .even = { { -2, 37, 64, 7, 37, -2, -6 },
+ { -6, 0, 39, 7, 64, 34, -3 },
+ { -7, 2, 42, 7, 64, 31, -4 },
+ { -7, 4, 45, 7, 62, 29, -5 },
+ { -7, 6, 47, 7, 62, 26, -6 },
+ { -7, 8, 50, 7, 60, 23, -6 },
+ { -8, 10, 52, 7, 60, 21, -7 },
+ { -8, 13, 54, 7, 58, 18, -7 },
+ { -8, 15, 58, 7, 56, 15, -8 },
+ { -7, 18, 58, 7, 54, 13, -8 },
+ { -7, 21, 60, 7, 52, 10, -8 },
+ { -6, 23, 60, 7, 50, 8, -7 },
+ { -6, 26, 62, 7, 47, 6, -7 },
+ { -5, 29, 62, 7, 45, 4, -7 },
+ { -4, 31, 64, 7, 42, 2, -7 },
+ { -3, 34, 64, 7, 39, 0, -6 } },
+ .odd = { { -7, 17, 57, 7, 55, 14, -8 },
+ { -7, 19, 59, 7, 53, 12, -8 },
+ { -7, 22, 61, 7, 51, 9, -8 },
+ { -6, 25, 60, 7, 49, 7, -7 },
+ { -5, 27, 62, 7, 46, 5, -7 },
+ { -5, 30, 63, 7, 44, 3, -7 },
+ { -3, 33, 62, 7, 41, 1, -6 },
+ { -2, 35, 64, 7, 38, -1, -6 },
+ { -6, -1, 38, 7, 64, 35, -2 },
+ { -6, 1, 41, 7, 62, 33, -3 },
+ { -7, 3, 44, 7, 63, 30, -5 },
+ { -7, 5, 46, 7, 62, 27, -5 },
+ { -7, 7, 49, 7, 60, 25, -6 },
+ { -8, 9, 51, 7, 61, 22, -7 },
+ { -8, 12, 53, 7, 59, 19, -7 },
+ { -8, 14, 55, 7, 57, 17, -7 } } },
+ .ptrn_arr = { { 0xe6666667, 0xccccccc } },
+ .sample_patrn_length = 62,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 31) = 0.507937 */
+ .hor_phase_arr = {
+ .even = { { -1, 37, 62, 7, 37, -1, -6 },
+ { -6, 0, 38, 7, 62, 35, -1 },
+ { -6, 1, 39, 7, 62, 34, -2 },
+ { -7, 2, 41, 7, 62, 33, -3 },
+ { -7, 3, 42, 7, 61, 32, -3 },
+ { -7, 4, 43, 7, 62, 30, -4 },
+ { -7, 4, 44, 7, 62, 29, -4 },
+ { -7, 6, 46, 7, 60, 28, -5 },
+ { -7, 7, 47, 7, 60, 26, -5 },
+ { -7, 8, 48, 7, 60, 25, -6 },
+ { -7, 9, 49, 7, 59, 24, -6 },
+ { -7, 10, 50, 7, 59, 22, -6 },
+ { -7, 11, 51, 7, 59, 21, -7 },
+ { -7, 12, 52, 7, 58, 20, -7 },
+ { -7, 13, 53, 7, 57, 19, -7 },
+ { -7, 15, 54, 7, 56, 17, -7 },
+ { -7, 16, 55, 7, 55, 16, -7 },
+ { -7, 17, 56, 7, 54, 15, -7 },
+ { -7, 19, 57, 7, 53, 13, -7 },
+ { -7, 20, 58, 7, 52, 12, -7 },
+ { -7, 21, 59, 7, 51, 11, -7 },
+ { -6, 22, 59, 7, 50, 10, -7 },
+ { -6, 24, 59, 7, 49, 9, -7 },
+ { -6, 25, 60, 7, 48, 8, -7 },
+ { -5, 26, 60, 7, 47, 7, -7 },
+ { -5, 28, 60, 7, 46, 6, -7 },
+ { -4, 29, 62, 7, 44, 4, -7 },
+ { -4, 30, 62, 7, 43, 4, -7 },
+ { -3, 32, 61, 7, 42, 3, -7 },
+ { -3, 33, 62, 7, 41, 2, -7 },
+ { -2, 34, 62, 7, 39, 1, -6 },
+ { -1, 35, 62, 7, 38, 0, -6 } },
+ .odd = { { -7, 17, 55, 7, 55, 15, -7 },
+ { -7, 18, 56, 7, 54, 14, -7 },
+ { -7, 19, 57, 7, 53, 13, -7 },
+ { -7, 20, 58, 7, 52, 12, -7 },
+ { -6, 22, 58, 7, 51, 10, -7 },
+ { -6, 23, 59, 7, 50, 9, -7 },
+ { -6, 24, 60, 7, 49, 8, -7 },
+ { -5, 26, 60, 7, 47, 7, -7 },
+ { -5, 27, 61, 7, 46, 6, -7 },
+ { -5, 28, 62, 7, 45, 5, -7 },
+ { -4, 30, 61, 7, 44, 4, -7 },
+ { -4, 31, 62, 7, 43, 3, -7 },
+ { -3, 32, 63, 7, 41, 2, -7 },
+ { -2, 34, 61, 7, 40, 1, -6 },
+ { -2, 35, 62, 7, 39, 0, -6 },
+ { -1, 36, 62, 7, 37, 0, -6 },
+ { -6, 0, 37, 7, 62, 36, -1 },
+ { -6, 0, 39, 7, 62, 35, -2 },
+ { -6, 1, 40, 7, 61, 34, -2 },
+ { -7, 2, 41, 7, 63, 32, -3 },
+ { -7, 3, 43, 7, 62, 31, -4 },
+ { -7, 4, 44, 7, 61, 30, -4 },
+ { -7, 5, 45, 7, 62, 28, -5 },
+ { -7, 6, 46, 7, 61, 27, -5 },
+ { -7, 7, 47, 7, 60, 26, -5 },
+ { -7, 8, 49, 7, 60, 24, -6 },
+ { -7, 9, 50, 7, 59, 23, -6 },
+ { -7, 10, 51, 7, 58, 22, -6 },
+ { -7, 12, 52, 7, 58, 20, -7 },
+ { -7, 13, 53, 7, 57, 19, -7 },
+ { -7, 14, 54, 7, 56, 18, -7 },
+ { -7, 15, 55, 7, 55, 17, -7 } } },
+ .ver_phase_arr = {
+ .even = { { -1, 37, 62, 7, 37, -1, -6 },
+ { -6, 0, 38, 7, 62, 35, -1 },
+ { -6, 1, 39, 7, 62, 34, -2 },
+ { -7, 2, 41, 7, 62, 33, -3 },
+ { -7, 3, 42, 7, 61, 32, -3 },
+ { -7, 4, 43, 7, 62, 30, -4 },
+ { -7, 4, 44, 7, 62, 29, -4 },
+ { -7, 6, 46, 7, 60, 28, -5 },
+ { -7, 7, 47, 7, 60, 26, -5 },
+ { -7, 8, 48, 7, 60, 25, -6 },
+ { -7, 9, 49, 7, 59, 24, -6 },
+ { -7, 10, 50, 7, 59, 22, -6 },
+ { -7, 11, 51, 7, 59, 21, -7 },
+ { -7, 12, 52, 7, 58, 20, -7 },
+ { -7, 13, 53, 7, 57, 19, -7 },
+ { -7, 15, 54, 7, 56, 17, -7 },
+ { -7, 16, 55, 7, 55, 16, -7 },
+ { -7, 17, 56, 7, 54, 15, -7 },
+ { -7, 19, 57, 7, 53, 13, -7 },
+ { -7, 20, 58, 7, 52, 12, -7 },
+ { -7, 21, 59, 7, 51, 11, -7 },
+ { -6, 22, 59, 7, 50, 10, -7 },
+ { -6, 24, 59, 7, 49, 9, -7 },
+ { -6, 25, 60, 7, 48, 8, -7 },
+ { -5, 26, 60, 7, 47, 7, -7 },
+ { -5, 28, 60, 7, 46, 6, -7 },
+ { -4, 29, 62, 7, 44, 4, -7 },
+ { -4, 30, 62, 7, 43, 4, -7 },
+ { -3, 32, 61, 7, 42, 3, -7 },
+ { -3, 33, 62, 7, 41, 2, -7 },
+ { -2, 34, 62, 7, 39, 1, -6 },
+ { -1, 35, 62, 7, 38, 0, -6 } },
+ .odd = { { -7, 17, 55, 7, 55, 15, -7 },
+ { -7, 18, 56, 7, 54, 14, -7 },
+ { -7, 19, 57, 7, 53, 13, -7 },
+ { -7, 20, 58, 7, 52, 12, -7 },
+ { -6, 22, 58, 7, 51, 10, -7 },
+ { -6, 23, 59, 7, 50, 9, -7 },
+ { -6, 24, 60, 7, 49, 8, -7 },
+ { -5, 26, 60, 7, 47, 7, -7 },
+ { -5, 27, 61, 7, 46, 6, -7 },
+ { -5, 28, 62, 7, 45, 5, -7 },
+ { -4, 30, 61, 7, 44, 4, -7 },
+ { -4, 31, 62, 7, 43, 3, -7 },
+ { -3, 32, 63, 7, 41, 2, -7 },
+ { -2, 34, 61, 7, 40, 1, -6 },
+ { -2, 35, 62, 7, 39, 0, -6 },
+ { -1, 36, 62, 7, 37, 0, -6 },
+ { -6, 0, 37, 7, 62, 36, -1 },
+ { -6, 0, 39, 7, 62, 35, -2 },
+ { -6, 1, 40, 7, 61, 34, -2 },
+ { -7, 2, 41, 7, 63, 32, -3 },
+ { -7, 3, 43, 7, 62, 31, -4 },
+ { -7, 4, 44, 7, 61, 30, -4 },
+ { -7, 5, 45, 7, 62, 28, -5 },
+ { -7, 6, 46, 7, 61, 27, -5 },
+ { -7, 7, 47, 7, 60, 26, -5 },
+ { -7, 8, 49, 7, 60, 24, -6 },
+ { -7, 9, 50, 7, 59, 23, -6 },
+ { -7, 10, 51, 7, 58, 22, -6 },
+ { -7, 12, 52, 7, 58, 20, -7 },
+ { -7, 13, 53, 7, 57, 19, -7 },
+ { -7, 14, 54, 7, 56, 18, -7 },
+ { -7, 15, 55, 7, 55, 17, -7 } } },
+ .ptrn_arr = { { 0x66666667, 0xe6666666, 0xcccccccc, 0xccccccc } },
+ .sample_patrn_length = 126,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 32) = 0.5 */
+ .hor_phase_arr = {
+ .even = { { 0, 8, 112, 7, 8, 0, 0 } },
+ .odd = { { 0, 0, 64, 7, 64, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 8, 112, 7, 8, 0, 0 } },
+ .odd = { { 0, 0, 64, 7, 64, 0, 0 } } },
+ .ptrn_arr = { { 0x3 } },
+ .sample_patrn_length = 4,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 33) = 0.492308 */
+ .hor_phase_arr = {
+ .even = { { 0, 9, 110, 7, 9, 0, 0 },
+ { 0, 8, 109, 7, 11, 0, 0 },
+ { 0, 7, 109, 7, 12, 0, 0 },
+ { 0, 6, 108, 7, 14, 0, 0 },
+ { 0, 5, 107, 7, 16, 0, 0 },
+ { 0, 4, 105, 7, 19, 0, 0 },
+ { 0, 3, 103, 7, 22, 0, 0 },
+ { 0, 3, 100, 7, 25, 0, 0 },
+ { 0, 2, 98, 7, 28, 0, 0 },
+ { 0, 2, 94, 7, 32, 0, 0 },
+ { 0, 2, 90, 7, 36, 0, 0 },
+ { 0, 1, 87, 7, 40, 0, 0 },
+ { 0, 1, 83, 7, 44, 0, 0 },
+ { 0, 1, 78, 7, 49, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 },
+ { 0, 1, 68, 7, 59, 0, 0 },
+ { 0, 0, 64, 7, 64, 0, 0 },
+ { 0, 0, 59, 7, 68, 1, 0 },
+ { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 49, 7, 78, 1, 0 },
+ { 0, 0, 44, 7, 83, 1, 0 },
+ { 0, 0, 40, 7, 87, 1, 0 },
+ { 0, 0, 36, 7, 90, 2, 0 },
+ { 0, 0, 32, 7, 94, 2, 0 },
+ { 0, 0, 28, 7, 98, 2, 0 },
+ { 0, 0, 25, 7, 100, 3, 0 },
+ { 0, 0, 22, 7, 103, 3, 0 },
+ { 0, 0, 19, 7, 105, 4, 0 },
+ { 0, 0, 16, 7, 107, 5, 0 },
+ { 0, 0, 14, 7, 108, 6, 0 },
+ { 0, 0, 12, 7, 109, 7, 0 },
+ { 0, 0, 11, 7, 109, 8, 0 } },
+ .odd = { { 0, 0, 61, 7, 67, 0, 0 },
+ { 0, 0, 56, 7, 71, 1, 0 },
+ { 0, 0, 51, 7, 76, 1, 0 },
+ { 0, 0, 46, 7, 81, 1, 0 },
+ { 0, 0, 42, 7, 85, 1, 0 },
+ { 0, 0, 38, 7, 89, 1, 0 },
+ { 0, 0, 34, 7, 92, 2, 0 },
+ { 0, 0, 30, 7, 96, 2, 0 },
+ { 0, 0, 26, 7, 99, 3, 0 },
+ { 0, 0, 23, 7, 102, 3, 0 },
+ { 0, 0, 20, 7, 104, 4, 0 },
+ { 0, 0, 18, 7, 106, 4, 0 },
+ { 0, 0, 15, 7, 108, 5, 0 },
+ { 0, 0, 13, 7, 109, 6, 0 },
+ { 0, 0, 11, 7, 110, 7, 0 },
+ { 0, 0, 10, 7, 110, 8, 0 },
+ { 0, 8, 110, 7, 10, 0, 0 },
+ { 0, 7, 110, 7, 11, 0, 0 },
+ { 0, 6, 109, 7, 13, 0, 0 },
+ { 0, 5, 108, 7, 15, 0, 0 },
+ { 0, 4, 106, 7, 18, 0, 0 },
+ { 0, 4, 104, 7, 20, 0, 0 },
+ { 0, 3, 102, 7, 23, 0, 0 },
+ { 0, 3, 99, 7, 26, 0, 0 },
+ { 0, 2, 96, 7, 30, 0, 0 },
+ { 0, 2, 92, 7, 34, 0, 0 },
+ { 0, 1, 89, 7, 38, 0, 0 },
+ { 0, 1, 85, 7, 42, 0, 0 },
+ { 0, 1, 81, 7, 46, 0, 0 },
+ { 0, 1, 76, 7, 51, 0, 0 },
+ { 0, 1, 71, 7, 56, 0, 0 },
+ { 0, 0, 67, 7, 61, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 9, 110, 7, 9, 0, 0 },
+ { 0, 8, 109, 7, 11, 0, 0 },
+ { 0, 7, 109, 7, 12, 0, 0 },
+ { 0, 6, 108, 7, 14, 0, 0 },
+ { 0, 5, 107, 7, 16, 0, 0 },
+ { 0, 4, 105, 7, 19, 0, 0 },
+ { 0, 3, 103, 7, 22, 0, 0 },
+ { 0, 3, 100, 7, 25, 0, 0 },
+ { 0, 2, 98, 7, 28, 0, 0 },
+ { 0, 2, 94, 7, 32, 0, 0 },
+ { 0, 2, 90, 7, 36, 0, 0 },
+ { 0, 1, 87, 7, 40, 0, 0 },
+ { 0, 1, 83, 7, 44, 0, 0 },
+ { 0, 1, 78, 7, 49, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 },
+ { 0, 1, 68, 7, 59, 0, 0 },
+ { 0, 0, 64, 7, 64, 0, 0 },
+ { 0, 0, 59, 7, 68, 1, 0 },
+ { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 49, 7, 78, 1, 0 },
+ { 0, 0, 44, 7, 83, 1, 0 },
+ { 0, 0, 40, 7, 87, 1, 0 },
+ { 0, 0, 36, 7, 90, 2, 0 },
+ { 0, 0, 32, 7, 94, 2, 0 },
+ { 0, 0, 28, 7, 98, 2, 0 },
+ { 0, 0, 25, 7, 100, 3, 0 },
+ { 0, 0, 22, 7, 103, 3, 0 },
+ { 0, 0, 19, 7, 105, 4, 0 },
+ { 0, 0, 16, 7, 107, 5, 0 },
+ { 0, 0, 14, 7, 108, 6, 0 },
+ { 0, 0, 12, 7, 109, 7, 0 },
+ { 0, 0, 11, 7, 109, 8, 0 } },
+ .odd = { { 0, 0, 61, 7, 67, 0, 0 },
+ { 0, 0, 56, 7, 71, 1, 0 },
+ { 0, 0, 51, 7, 76, 1, 0 },
+ { 0, 0, 46, 7, 81, 1, 0 },
+ { 0, 0, 42, 7, 85, 1, 0 },
+ { 0, 0, 38, 7, 89, 1, 0 },
+ { 0, 0, 34, 7, 92, 2, 0 },
+ { 0, 0, 30, 7, 96, 2, 0 },
+ { 0, 0, 26, 7, 99, 3, 0 },
+ { 0, 0, 23, 7, 102, 3, 0 },
+ { 0, 0, 20, 7, 104, 4, 0 },
+ { 0, 0, 18, 7, 106, 4, 0 },
+ { 0, 0, 15, 7, 108, 5, 0 },
+ { 0, 0, 13, 7, 109, 6, 0 },
+ { 0, 0, 11, 7, 110, 7, 0 },
+ { 0, 0, 10, 7, 110, 8, 0 },
+ { 0, 8, 110, 7, 10, 0, 0 },
+ { 0, 7, 110, 7, 11, 0, 0 },
+ { 0, 6, 109, 7, 13, 0, 0 },
+ { 0, 5, 108, 7, 15, 0, 0 },
+ { 0, 4, 106, 7, 18, 0, 0 },
+ { 0, 4, 104, 7, 20, 0, 0 },
+ { 0, 3, 102, 7, 23, 0, 0 },
+ { 0, 3, 99, 7, 26, 0, 0 },
+ { 0, 2, 96, 7, 30, 0, 0 },
+ { 0, 2, 92, 7, 34, 0, 0 },
+ { 0, 1, 89, 7, 38, 0, 0 },
+ { 0, 1, 85, 7, 42, 0, 0 },
+ { 0, 1, 81, 7, 46, 0, 0 },
+ { 0, 1, 76, 7, 51, 0, 0 },
+ { 0, 1, 71, 7, 56, 0, 0 },
+ { 0, 0, 67, 7, 61, 0, 0 } } },
+ .ptrn_arr = { { 0x33333333, 0x33333333, 0x99999999, 0x99999999 } },
+ .sample_patrn_length = 130,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 34) = 0.484848 */
+ .hor_phase_arr = {
+ .even = { { 0, 10, 108, 7, 10, 0, 0 },
+ { 0, 7, 108, 7, 13, 0, 0 },
+ { 0, 5, 106, 7, 17, 0, 0 },
+ { 0, 4, 102, 7, 22, 0, 0 },
+ { 0, 3, 96, 7, 29, 0, 0 },
+ { 0, 2, 90, 7, 36, 0, 0 },
+ { 0, 1, 82, 7, 45, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 },
+ { 0, 0, 64, 7, 64, 0, 0 },
+ { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 45, 7, 82, 1, 0 },
+ { 0, 0, 36, 7, 90, 2, 0 },
+ { 0, 0, 29, 7, 96, 3, 0 },
+ { 0, 0, 22, 7, 102, 4, 0 },
+ { 0, 0, 17, 7, 106, 5, 0 },
+ { 0, 0, 13, 7, 108, 7, 0 } },
+ .odd = { { 0, 0, 59, 7, 68, 1, 0 },
+ { 0, 0, 49, 7, 78, 1, 0 },
+ { 0, 0, 40, 7, 87, 1, 0 },
+ { 0, 0, 32, 7, 94, 2, 0 },
+ { 0, 0, 25, 7, 100, 3, 0 },
+ { 0, 0, 20, 7, 104, 4, 0 },
+ { 0, 0, 15, 7, 107, 6, 0 },
+ { 0, 0, 11, 7, 109, 8, 0 },
+ { 0, 8, 109, 7, 11, 0, 0 },
+ { 0, 6, 107, 7, 15, 0, 0 },
+ { 0, 4, 104, 7, 20, 0, 0 },
+ { 0, 3, 100, 7, 25, 0, 0 },
+ { 0, 2, 94, 7, 32, 0, 0 },
+ { 0, 1, 87, 7, 40, 0, 0 },
+ { 0, 1, 78, 7, 49, 0, 0 },
+ { 0, 1, 68, 7, 59, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 10, 108, 7, 10, 0, 0 },
+ { 0, 7, 108, 7, 13, 0, 0 },
+ { 0, 5, 106, 7, 17, 0, 0 },
+ { 0, 4, 102, 7, 22, 0, 0 },
+ { 0, 3, 96, 7, 29, 0, 0 },
+ { 0, 2, 90, 7, 36, 0, 0 },
+ { 0, 1, 82, 7, 45, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 },
+ { 0, 0, 64, 7, 64, 0, 0 },
+ { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 45, 7, 82, 1, 0 },
+ { 0, 0, 36, 7, 90, 2, 0 },
+ { 0, 0, 29, 7, 96, 3, 0 },
+ { 0, 0, 22, 7, 102, 4, 0 },
+ { 0, 0, 17, 7, 106, 5, 0 },
+ { 0, 0, 13, 7, 108, 7, 0 } },
+ .odd = { { 0, 0, 59, 7, 68, 1, 0 },
+ { 0, 0, 49, 7, 78, 1, 0 },
+ { 0, 0, 40, 7, 87, 1, 0 },
+ { 0, 0, 32, 7, 94, 2, 0 },
+ { 0, 0, 25, 7, 100, 3, 0 },
+ { 0, 0, 20, 7, 104, 4, 0 },
+ { 0, 0, 15, 7, 107, 6, 0 },
+ { 0, 0, 11, 7, 109, 8, 0 },
+ { 0, 8, 109, 7, 11, 0, 0 },
+ { 0, 6, 107, 7, 15, 0, 0 },
+ { 0, 4, 104, 7, 20, 0, 0 },
+ { 0, 3, 100, 7, 25, 0, 0 },
+ { 0, 2, 94, 7, 32, 0, 0 },
+ { 0, 1, 87, 7, 40, 0, 0 },
+ { 0, 1, 78, 7, 49, 0, 0 },
+ { 0, 1, 68, 7, 59, 0, 0 } } },
+ .ptrn_arr = { { 0x33333333, 0x99999999 } },
+ .sample_patrn_length = 66,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 35) = 0.477612 */
+ .hor_phase_arr = {
+ .even = { { 0, 10, 108, 7, 10, 0, 0 },
+ { 0, 6, 106, 7, 16, 0, 0 },
+ { 0, 4, 101, 7, 23, 0, 0 },
+ { 0, 2, 93, 7, 33, 0, 0 },
+ { 0, 1, 82, 7, 45, 0, 0 },
+ { 0, 1, 68, 7, 59, 0, 0 },
+ { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 41, 7, 85, 2, 0 },
+ { 0, 0, 29, 7, 96, 3, 0 },
+ { 0, 0, 20, 7, 103, 5, 0 },
+ { 0, 0, 14, 7, 106, 8, 0 },
+ { 0, 9, 107, 7, 12, 0, 0 },
+ { 0, 5, 105, 7, 18, 0, 0 },
+ { 0, 3, 99, 7, 26, 0, 0 },
+ { 0, 2, 89, 7, 37, 0, 0 },
+ { 0, 1, 77, 7, 50, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 50, 7, 77, 1, 0 },
+ { 0, 0, 37, 7, 89, 2, 0 },
+ { 0, 0, 26, 7, 99, 3, 0 },
+ { 0, 0, 18, 7, 105, 5, 0 },
+ { 0, 0, 12, 7, 107, 9, 0 },
+ { 0, 8, 106, 7, 14, 0, 0 },
+ { 0, 5, 103, 7, 20, 0, 0 },
+ { 0, 3, 96, 7, 29, 0, 0 },
+ { 0, 2, 85, 7, 41, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 },
+ { 0, 0, 59, 7, 68, 1, 0 },
+ { 0, 0, 45, 7, 82, 1, 0 },
+ { 0, 0, 33, 7, 93, 2, 0 },
+ { 0, 0, 23, 7, 101, 4, 0 },
+ { 0, 0, 16, 7, 106, 6, 0 } },
+ .odd = { { 0, 0, 56, 7, 71, 1, 0 },
+ { 0, 0, 43, 7, 84, 1, 0 },
+ { 0, 0, 31, 7, 94, 3, 0 },
+ { 0, 0, 22, 7, 102, 4, 0 },
+ { 0, 0, 15, 7, 106, 7, 0 },
+ { 0, 9, 108, 7, 11, 0, 0 },
+ { 0, 6, 105, 7, 17, 0, 0 },
+ { 0, 4, 99, 7, 25, 0, 0 },
+ { 0, 2, 91, 7, 35, 0, 0 },
+ { 0, 1, 80, 7, 47, 0, 0 },
+ { 0, 1, 65, 7, 61, 1, 0 },
+ { 0, 0, 52, 7, 75, 1, 0 },
+ { 0, 0, 39, 7, 87, 2, 0 },
+ { 0, 0, 28, 7, 97, 3, 0 },
+ { 0, 0, 19, 7, 104, 5, 0 },
+ { 0, 0, 13, 7, 107, 8, 0 },
+ { 0, 8, 107, 7, 13, 0, 0 },
+ { 0, 5, 104, 7, 19, 0, 0 },
+ { 0, 3, 97, 7, 28, 0, 0 },
+ { 0, 2, 87, 7, 39, 0, 0 },
+ { 0, 1, 75, 7, 52, 0, 0 },
+ { 0, 1, 61, 7, 65, 1, 0 },
+ { 0, 0, 47, 7, 80, 1, 0 },
+ { 0, 0, 35, 7, 91, 2, 0 },
+ { 0, 0, 25, 7, 99, 4, 0 },
+ { 0, 0, 17, 7, 105, 6, 0 },
+ { 0, 0, 11, 7, 108, 9, 0 },
+ { 0, 7, 106, 7, 15, 0, 0 },
+ { 0, 4, 102, 7, 22, 0, 0 },
+ { 0, 3, 94, 7, 31, 0, 0 },
+ { 0, 1, 84, 7, 43, 0, 0 },
+ { 0, 1, 71, 7, 56, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 10, 108, 7, 10, 0, 0 },
+ { 0, 6, 106, 7, 16, 0, 0 },
+ { 0, 4, 101, 7, 23, 0, 0 },
+ { 0, 2, 93, 7, 33, 0, 0 },
+ { 0, 1, 82, 7, 45, 0, 0 },
+ { 0, 1, 68, 7, 59, 0, 0 },
+ { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 41, 7, 85, 2, 0 },
+ { 0, 0, 29, 7, 96, 3, 0 },
+ { 0, 0, 20, 7, 103, 5, 0 },
+ { 0, 0, 14, 7, 106, 8, 0 },
+ { 0, 9, 107, 7, 12, 0, 0 },
+ { 0, 5, 105, 7, 18, 0, 0 },
+ { 0, 3, 99, 7, 26, 0, 0 },
+ { 0, 2, 89, 7, 37, 0, 0 },
+ { 0, 1, 77, 7, 50, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 50, 7, 77, 1, 0 },
+ { 0, 0, 37, 7, 89, 2, 0 },
+ { 0, 0, 26, 7, 99, 3, 0 },
+ { 0, 0, 18, 7, 105, 5, 0 },
+ { 0, 0, 12, 7, 107, 9, 0 },
+ { 0, 8, 106, 7, 14, 0, 0 },
+ { 0, 5, 103, 7, 20, 0, 0 },
+ { 0, 3, 96, 7, 29, 0, 0 },
+ { 0, 2, 85, 7, 41, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 },
+ { 0, 0, 59, 7, 68, 1, 0 },
+ { 0, 0, 45, 7, 82, 1, 0 },
+ { 0, 0, 33, 7, 93, 2, 0 },
+ { 0, 0, 23, 7, 101, 4, 0 },
+ { 0, 0, 16, 7, 106, 6, 0 } },
+ .odd = { { 0, 0, 56, 7, 71, 1, 0 },
+ { 0, 0, 43, 7, 84, 1, 0 },
+ { 0, 0, 31, 7, 94, 3, 0 },
+ { 0, 0, 22, 7, 102, 4, 0 },
+ { 0, 0, 15, 7, 106, 7, 0 },
+ { 0, 9, 108, 7, 11, 0, 0 },
+ { 0, 6, 105, 7, 17, 0, 0 },
+ { 0, 4, 99, 7, 25, 0, 0 },
+ { 0, 2, 91, 7, 35, 0, 0 },
+ { 0, 1, 80, 7, 47, 0, 0 },
+ { 0, 1, 65, 7, 61, 1, 0 },
+ { 0, 0, 52, 7, 75, 1, 0 },
+ { 0, 0, 39, 7, 87, 2, 0 },
+ { 0, 0, 28, 7, 97, 3, 0 },
+ { 0, 0, 19, 7, 104, 5, 0 },
+ { 0, 0, 13, 7, 107, 8, 0 },
+ { 0, 8, 107, 7, 13, 0, 0 },
+ { 0, 5, 104, 7, 19, 0, 0 },
+ { 0, 3, 97, 7, 28, 0, 0 },
+ { 0, 2, 87, 7, 39, 0, 0 },
+ { 0, 1, 75, 7, 52, 0, 0 },
+ { 0, 1, 61, 7, 65, 1, 0 },
+ { 0, 0, 47, 7, 80, 1, 0 },
+ { 0, 0, 35, 7, 91, 2, 0 },
+ { 0, 0, 25, 7, 99, 4, 0 },
+ { 0, 0, 17, 7, 105, 6, 0 },
+ { 0, 0, 11, 7, 108, 9, 0 },
+ { 0, 7, 106, 7, 15, 0, 0 },
+ { 0, 4, 102, 7, 22, 0, 0 },
+ { 0, 3, 94, 7, 31, 0, 0 },
+ { 0, 1, 84, 7, 43, 0, 0 },
+ { 0, 1, 71, 7, 56, 0, 0 } } },
+ .ptrn_arr = { { 0x99933333, 0xccccc999, 0x32666664, 0x99993333,
+ 0x9 } },
+ .sample_patrn_length = 134,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 36) = 0.470588 */
+ .hor_phase_arr = {
+ .even = { { 0, 11, 106, 7, 11, 0, 0 },
+ { 0, 6, 103, 7, 19, 0, 0 },
+ { 0, 3, 95, 7, 30, 0, 0 },
+ { 0, 1, 81, 7, 46, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 46, 7, 81, 1, 0 },
+ { 0, 0, 30, 7, 95, 3, 0 },
+ { 0, 0, 19, 7, 103, 6, 0 } },
+ .odd = { { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 37, 7, 89, 2, 0 },
+ { 0, 0, 24, 7, 100, 4, 0 },
+ { 0, 0, 14, 7, 106, 8, 0 },
+ { 0, 8, 106, 7, 14, 0, 0 },
+ { 0, 4, 100, 7, 24, 0, 0 },
+ { 0, 2, 89, 7, 37, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 11, 106, 7, 11, 0, 0 },
+ { 0, 6, 103, 7, 19, 0, 0 },
+ { 0, 3, 95, 7, 30, 0, 0 },
+ { 0, 1, 81, 7, 46, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 46, 7, 81, 1, 0 },
+ { 0, 0, 30, 7, 95, 3, 0 },
+ { 0, 0, 19, 7, 103, 6, 0 } },
+ .odd = { { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 37, 7, 89, 2, 0 },
+ { 0, 0, 24, 7, 100, 4, 0 },
+ { 0, 0, 14, 7, 106, 8, 0 },
+ { 0, 8, 106, 7, 14, 0, 0 },
+ { 0, 4, 100, 7, 24, 0, 0 },
+ { 0, 2, 89, 7, 37, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 } } },
+ .ptrn_arr = { { 0x99993333 } },
+ .sample_patrn_length = 34,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 37) = 0.463768 */
+ .hor_phase_arr = {
+ .even = { { 0, 11, 106, 7, 11, 0, 0 },
+ { 0, 5, 101, 7, 22, 0, 0 },
+ { 0, 2, 88, 7, 38, 0, 0 },
+ { 0, 1, 67, 7, 59, 1, 0 },
+ { 0, 0, 46, 7, 80, 2, 0 },
+ { 0, 0, 28, 7, 96, 4, 0 },
+ { 0, 0, 15, 7, 104, 9, 0 },
+ { 0, 7, 104, 7, 17, 0, 0 },
+ { 0, 3, 94, 7, 31, 0, 0 },
+ { 0, 1, 77, 7, 50, 0, 0 },
+ { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 34, 7, 91, 3, 0 },
+ { 0, 0, 19, 7, 103, 6, 0 },
+ { 0, 10, 105, 7, 13, 0, 0 },
+ { 0, 5, 98, 7, 25, 0, 0 },
+ { 0, 2, 84, 7, 42, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 42, 7, 84, 2, 0 },
+ { 0, 0, 25, 7, 98, 5, 0 },
+ { 0, 0, 13, 7, 105, 10, 0 },
+ { 0, 6, 103, 7, 19, 0, 0 },
+ { 0, 3, 91, 7, 34, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 },
+ { 0, 0, 50, 7, 77, 1, 0 },
+ { 0, 0, 31, 7, 94, 3, 0 },
+ { 0, 0, 17, 7, 104, 7, 0 },
+ { 0, 9, 104, 7, 15, 0, 0 },
+ { 0, 4, 96, 7, 28, 0, 0 },
+ { 0, 2, 80, 7, 46, 0, 0 },
+ { 0, 1, 59, 7, 67, 1, 0 },
+ { 0, 0, 38, 7, 88, 2, 0 },
+ { 0, 0, 22, 7, 101, 5, 0 } },
+ .odd = { { 0, 0, 52, 7, 75, 1, 0 },
+ { 0, 0, 33, 7, 92, 3, 0 },
+ { 0, 0, 18, 7, 103, 7, 0 },
+ { 0, 9, 105, 7, 14, 0, 0 },
+ { 0, 4, 98, 7, 26, 0, 0 },
+ { 0, 2, 82, 7, 44, 0, 0 },
+ { 0, 1, 61, 7, 65, 1, 0 },
+ { 0, 0, 40, 7, 86, 2, 0 },
+ { 0, 0, 23, 7, 100, 5, 0 },
+ { 0, 0, 12, 7, 105, 11, 0 },
+ { 0, 6, 101, 7, 21, 0, 0 },
+ { 0, 3, 89, 7, 36, 0, 0 },
+ { 0, 1, 69, 7, 57, 1, 0 },
+ { 0, 0, 48, 7, 79, 1, 0 },
+ { 0, 0, 29, 7, 95, 4, 0 },
+ { 0, 0, 16, 7, 104, 8, 0 },
+ { 0, 8, 104, 7, 16, 0, 0 },
+ { 0, 4, 95, 7, 29, 0, 0 },
+ { 0, 1, 79, 7, 48, 0, 0 },
+ { 0, 1, 57, 7, 69, 1, 0 },
+ { 0, 0, 36, 7, 89, 3, 0 },
+ { 0, 0, 21, 7, 101, 6, 0 },
+ { 0, 11, 105, 7, 12, 0, 0 },
+ { 0, 5, 100, 7, 23, 0, 0 },
+ { 0, 2, 86, 7, 40, 0, 0 },
+ { 0, 1, 65, 7, 61, 1, 0 },
+ { 0, 0, 44, 7, 82, 2, 0 },
+ { 0, 0, 26, 7, 98, 4, 0 },
+ { 0, 0, 14, 7, 105, 9, 0 },
+ { 0, 7, 103, 7, 18, 0, 0 },
+ { 0, 3, 92, 7, 33, 0, 0 },
+ { 0, 1, 75, 7, 52, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 11, 106, 7, 11, 0, 0 },
+ { 0, 5, 101, 7, 22, 0, 0 },
+ { 0, 2, 88, 7, 38, 0, 0 },
+ { 0, 1, 67, 7, 59, 1, 0 },
+ { 0, 0, 46, 7, 80, 2, 0 },
+ { 0, 0, 28, 7, 96, 4, 0 },
+ { 0, 0, 15, 7, 104, 9, 0 },
+ { 0, 7, 104, 7, 17, 0, 0 },
+ { 0, 3, 94, 7, 31, 0, 0 },
+ { 0, 1, 77, 7, 50, 0, 0 },
+ { 0, 0, 54, 7, 73, 1, 0 },
+ { 0, 0, 34, 7, 91, 3, 0 },
+ { 0, 0, 19, 7, 103, 6, 0 },
+ { 0, 10, 105, 7, 13, 0, 0 },
+ { 0, 5, 98, 7, 25, 0, 0 },
+ { 0, 2, 84, 7, 42, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 42, 7, 84, 2, 0 },
+ { 0, 0, 25, 7, 98, 5, 0 },
+ { 0, 0, 13, 7, 105, 10, 0 },
+ { 0, 6, 103, 7, 19, 0, 0 },
+ { 0, 3, 91, 7, 34, 0, 0 },
+ { 0, 1, 73, 7, 54, 0, 0 },
+ { 0, 0, 50, 7, 77, 1, 0 },
+ { 0, 0, 31, 7, 94, 3, 0 },
+ { 0, 0, 17, 7, 104, 7, 0 },
+ { 0, 9, 104, 7, 15, 0, 0 },
+ { 0, 4, 96, 7, 28, 0, 0 },
+ { 0, 2, 80, 7, 46, 0, 0 },
+ { 0, 1, 59, 7, 67, 1, 0 },
+ { 0, 0, 38, 7, 88, 2, 0 },
+ { 0, 0, 22, 7, 101, 5, 0 } },
+ .odd = { { 0, 0, 52, 7, 75, 1, 0 },
+ { 0, 0, 33, 7, 92, 3, 0 },
+ { 0, 0, 18, 7, 103, 7, 0 },
+ { 0, 9, 105, 7, 14, 0, 0 },
+ { 0, 4, 98, 7, 26, 0, 0 },
+ { 0, 2, 82, 7, 44, 0, 0 },
+ { 0, 1, 61, 7, 65, 1, 0 },
+ { 0, 0, 40, 7, 86, 2, 0 },
+ { 0, 0, 23, 7, 100, 5, 0 },
+ { 0, 0, 12, 7, 105, 11, 0 },
+ { 0, 6, 101, 7, 21, 0, 0 },
+ { 0, 3, 89, 7, 36, 0, 0 },
+ { 0, 1, 69, 7, 57, 1, 0 },
+ { 0, 0, 48, 7, 79, 1, 0 },
+ { 0, 0, 29, 7, 95, 4, 0 },
+ { 0, 0, 16, 7, 104, 8, 0 },
+ { 0, 8, 104, 7, 16, 0, 0 },
+ { 0, 4, 95, 7, 29, 0, 0 },
+ { 0, 1, 79, 7, 48, 0, 0 },
+ { 0, 1, 57, 7, 69, 1, 0 },
+ { 0, 0, 36, 7, 89, 3, 0 },
+ { 0, 0, 21, 7, 101, 6, 0 },
+ { 0, 11, 105, 7, 12, 0, 0 },
+ { 0, 5, 100, 7, 23, 0, 0 },
+ { 0, 2, 86, 7, 40, 0, 0 },
+ { 0, 1, 65, 7, 61, 1, 0 },
+ { 0, 0, 44, 7, 82, 2, 0 },
+ { 0, 0, 26, 7, 98, 4, 0 },
+ { 0, 0, 14, 7, 105, 9, 0 },
+ { 0, 7, 103, 7, 18, 0, 0 },
+ { 0, 3, 92, 7, 33, 0, 0 },
+ { 0, 1, 75, 7, 52, 0, 0 } } },
+ .ptrn_arr = { { 0xc9999333, 0x332664cc, 0x4cc99993, 0x93332666,
+ 0x99 } },
+ .sample_patrn_length = 138,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 38) = 0.457143 */
+ .hor_phase_arr = {
+ .even = { { 0, 12, 104, 7, 12, 0, 0 },
+ { 0, 5, 98, 7, 25, 0, 0 },
+ { 0, 2, 80, 7, 46, 0, 0 },
+ { 0, 1, 55, 7, 71, 1, 0 },
+ { 0, 0, 32, 7, 92, 4, 0 },
+ { 0, 0, 16, 7, 103, 9, 0 },
+ { 0, 7, 101, 7, 20, 0, 0 },
+ { 0, 3, 86, 7, 39, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 39, 7, 86, 3, 0 },
+ { 0, 0, 20, 7, 101, 7, 0 },
+ { 0, 9, 103, 7, 16, 0, 0 },
+ { 0, 4, 92, 7, 32, 0, 0 },
+ { 0, 1, 71, 7, 55, 1, 0 },
+ { 0, 0, 46, 7, 80, 2, 0 },
+ { 0, 0, 25, 7, 98, 5, 0 } },
+ .odd = { { 0, 0, 50, 7, 76, 2, 0 },
+ { 0, 0, 28, 7, 96, 4, 0 },
+ { 0, 0, 14, 7, 104, 10, 0 },
+ { 0, 6, 99, 7, 23, 0, 0 },
+ { 0, 2, 84, 7, 42, 0, 0 },
+ { 0, 1, 59, 7, 67, 1, 0 },
+ { 0, 0, 35, 7, 90, 3, 0 },
+ { 0, 0, 18, 7, 102, 8, 0 },
+ { 0, 8, 102, 7, 18, 0, 0 },
+ { 0, 3, 90, 7, 35, 0, 0 },
+ { 0, 1, 67, 7, 59, 1, 0 },
+ { 0, 0, 42, 7, 84, 2, 0 },
+ { 0, 0, 23, 7, 99, 6, 0 },
+ { 0, 10, 104, 7, 14, 0, 0 },
+ { 0, 4, 96, 7, 28, 0, 0 },
+ { 0, 2, 76, 7, 50, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 12, 104, 7, 12, 0, 0 },
+ { 0, 5, 98, 7, 25, 0, 0 },
+ { 0, 2, 80, 7, 46, 0, 0 },
+ { 0, 1, 55, 7, 71, 1, 0 },
+ { 0, 0, 32, 7, 92, 4, 0 },
+ { 0, 0, 16, 7, 103, 9, 0 },
+ { 0, 7, 101, 7, 20, 0, 0 },
+ { 0, 3, 86, 7, 39, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 39, 7, 86, 3, 0 },
+ { 0, 0, 20, 7, 101, 7, 0 },
+ { 0, 9, 103, 7, 16, 0, 0 },
+ { 0, 4, 92, 7, 32, 0, 0 },
+ { 0, 1, 71, 7, 55, 1, 0 },
+ { 0, 0, 46, 7, 80, 2, 0 },
+ { 0, 0, 25, 7, 98, 5, 0 } },
+ .odd = { { 0, 0, 50, 7, 76, 2, 0 },
+ { 0, 0, 28, 7, 96, 4, 0 },
+ { 0, 0, 14, 7, 104, 10, 0 },
+ { 0, 6, 99, 7, 23, 0, 0 },
+ { 0, 2, 84, 7, 42, 0, 0 },
+ { 0, 1, 59, 7, 67, 1, 0 },
+ { 0, 0, 35, 7, 90, 3, 0 },
+ { 0, 0, 18, 7, 102, 8, 0 },
+ { 0, 8, 102, 7, 18, 0, 0 },
+ { 0, 3, 90, 7, 35, 0, 0 },
+ { 0, 1, 67, 7, 59, 1, 0 },
+ { 0, 0, 42, 7, 84, 2, 0 },
+ { 0, 0, 23, 7, 99, 6, 0 },
+ { 0, 10, 104, 7, 14, 0, 0 },
+ { 0, 4, 96, 7, 28, 0, 0 },
+ { 0, 2, 76, 7, 50, 0, 0 } } },
+ .ptrn_arr = { { 0xcc999333, 0x99332664, 0x9 } },
+ .sample_patrn_length = 70,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 39) = 0.450704 */
+ .hor_phase_arr = {
+ .even = { { 0, 13, 102, 7, 13, 0, 0 },
+ { 0, 5, 94, 7, 29, 0, 0 },
+ { 0, 1, 71, 7, 55, 1, 0 },
+ { 0, 0, 43, 7, 83, 2, 0 },
+ { 0, 0, 21, 7, 100, 7, 0 },
+ { 0, 8, 102, 7, 18, 0, 0 },
+ { 0, 3, 86, 7, 39, 0, 0 },
+ { 0, 1, 59, 7, 67, 1, 0 },
+ { 0, 0, 32, 7, 92, 4, 0 },
+ { 0, 0, 14, 7, 103, 11, 0 },
+ { 0, 5, 97, 7, 26, 0, 0 },
+ { 0, 2, 74, 7, 51, 1, 0 },
+ { 0, 0, 47, 7, 79, 2, 0 },
+ { 0, 0, 23, 7, 99, 6, 0 },
+ { 0, 10, 102, 7, 16, 0, 0 },
+ { 0, 3, 89, 7, 36, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 36, 7, 89, 3, 0 },
+ { 0, 0, 16, 7, 102, 10, 0 },
+ { 0, 6, 99, 7, 23, 0, 0 },
+ { 0, 2, 79, 7, 47, 0, 0 },
+ { 0, 1, 51, 7, 74, 2, 0 },
+ { 0, 0, 26, 7, 97, 5, 0 },
+ { 0, 11, 103, 7, 14, 0, 0 },
+ { 0, 4, 92, 7, 32, 0, 0 },
+ { 0, 1, 67, 7, 59, 1, 0 },
+ { 0, 0, 39, 7, 86, 3, 0 },
+ { 0, 0, 18, 7, 102, 8, 0 },
+ { 0, 7, 100, 7, 21, 0, 0 },
+ { 0, 2, 83, 7, 43, 0, 0 },
+ { 0, 1, 55, 7, 71, 1, 0 },
+ { 0, 0, 29, 7, 94, 5, 0 } },
+ .odd = { { 0, 0, 49, 7, 77, 2, 0 },
+ { 0, 0, 25, 7, 97, 6, 0 },
+ { 0, 10, 103, 7, 15, 0, 0 },
+ { 0, 4, 90, 7, 34, 0, 0 },
+ { 0, 1, 65, 7, 61, 1, 0 },
+ { 0, 0, 37, 7, 88, 3, 0 },
+ { 0, 0, 17, 7, 102, 9, 0 },
+ { 0, 7, 99, 7, 22, 0, 0 },
+ { 0, 2, 81, 7, 45, 0, 0 },
+ { 0, 1, 53, 7, 72, 2, 0 },
+ { 0, 0, 27, 7, 96, 5, 0 },
+ { 0, 12, 103, 7, 13, 0, 0 },
+ { 0, 4, 93, 7, 31, 0, 0 },
+ { 0, 1, 69, 7, 57, 1, 0 },
+ { 0, 0, 41, 7, 84, 3, 0 },
+ { 0, 0, 20, 7, 100, 8, 0 },
+ { 0, 8, 100, 7, 20, 0, 0 },
+ { 0, 3, 84, 7, 41, 0, 0 },
+ { 0, 1, 57, 7, 69, 1, 0 },
+ { 0, 0, 31, 7, 93, 4, 0 },
+ { 0, 0, 13, 7, 103, 12, 0 },
+ { 0, 5, 96, 7, 27, 0, 0 },
+ { 0, 2, 72, 7, 53, 1, 0 },
+ { 0, 0, 45, 7, 81, 2, 0 },
+ { 0, 0, 22, 7, 99, 7, 0 },
+ { 0, 9, 102, 7, 17, 0, 0 },
+ { 0, 3, 88, 7, 37, 0, 0 },
+ { 0, 1, 61, 7, 65, 1, 0 },
+ { 0, 0, 34, 7, 90, 4, 0 },
+ { 0, 0, 15, 7, 103, 10, 0 },
+ { 0, 6, 97, 7, 25, 0, 0 },
+ { 0, 2, 77, 7, 49, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 13, 102, 7, 13, 0, 0 },
+ { 0, 5, 94, 7, 29, 0, 0 },
+ { 0, 1, 71, 7, 55, 1, 0 },
+ { 0, 0, 43, 7, 83, 2, 0 },
+ { 0, 0, 21, 7, 100, 7, 0 },
+ { 0, 8, 102, 7, 18, 0, 0 },
+ { 0, 3, 86, 7, 39, 0, 0 },
+ { 0, 1, 59, 7, 67, 1, 0 },
+ { 0, 0, 32, 7, 92, 4, 0 },
+ { 0, 0, 14, 7, 103, 11, 0 },
+ { 0, 5, 97, 7, 26, 0, 0 },
+ { 0, 2, 74, 7, 51, 1, 0 },
+ { 0, 0, 47, 7, 79, 2, 0 },
+ { 0, 0, 23, 7, 99, 6, 0 },
+ { 0, 10, 102, 7, 16, 0, 0 },
+ { 0, 3, 89, 7, 36, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 36, 7, 89, 3, 0 },
+ { 0, 0, 16, 7, 102, 10, 0 },
+ { 0, 6, 99, 7, 23, 0, 0 },
+ { 0, 2, 79, 7, 47, 0, 0 },
+ { 0, 1, 51, 7, 74, 2, 0 },
+ { 0, 0, 26, 7, 97, 5, 0 },
+ { 0, 11, 103, 7, 14, 0, 0 },
+ { 0, 4, 92, 7, 32, 0, 0 },
+ { 0, 1, 67, 7, 59, 1, 0 },
+ { 0, 0, 39, 7, 86, 3, 0 },
+ { 0, 0, 18, 7, 102, 8, 0 },
+ { 0, 7, 100, 7, 21, 0, 0 },
+ { 0, 2, 83, 7, 43, 0, 0 },
+ { 0, 1, 55, 7, 71, 1, 0 },
+ { 0, 0, 29, 7, 94, 5, 0 } },
+ .odd = { { 0, 0, 49, 7, 77, 2, 0 },
+ { 0, 0, 25, 7, 97, 6, 0 },
+ { 0, 10, 103, 7, 15, 0, 0 },
+ { 0, 4, 90, 7, 34, 0, 0 },
+ { 0, 1, 65, 7, 61, 1, 0 },
+ { 0, 0, 37, 7, 88, 3, 0 },
+ { 0, 0, 17, 7, 102, 9, 0 },
+ { 0, 7, 99, 7, 22, 0, 0 },
+ { 0, 2, 81, 7, 45, 0, 0 },
+ { 0, 1, 53, 7, 72, 2, 0 },
+ { 0, 0, 27, 7, 96, 5, 0 },
+ { 0, 12, 103, 7, 13, 0, 0 },
+ { 0, 4, 93, 7, 31, 0, 0 },
+ { 0, 1, 69, 7, 57, 1, 0 },
+ { 0, 0, 41, 7, 84, 3, 0 },
+ { 0, 0, 20, 7, 100, 8, 0 },
+ { 0, 8, 100, 7, 20, 0, 0 },
+ { 0, 3, 84, 7, 41, 0, 0 },
+ { 0, 1, 57, 7, 69, 1, 0 },
+ { 0, 0, 31, 7, 93, 4, 0 },
+ { 0, 0, 13, 7, 103, 12, 0 },
+ { 0, 5, 96, 7, 27, 0, 0 },
+ { 0, 2, 72, 7, 53, 1, 0 },
+ { 0, 0, 45, 7, 81, 2, 0 },
+ { 0, 0, 22, 7, 99, 7, 0 },
+ { 0, 9, 102, 7, 17, 0, 0 },
+ { 0, 3, 88, 7, 37, 0, 0 },
+ { 0, 1, 61, 7, 65, 1, 0 },
+ { 0, 0, 34, 7, 90, 4, 0 },
+ { 0, 0, 15, 7, 103, 10, 0 },
+ { 0, 6, 97, 7, 25, 0, 0 },
+ { 0, 2, 77, 7, 49, 0, 0 } } },
+ .ptrn_arr = { { 0x4cc99933, 0xc9993266, 0x9332664c, 0x32664cc9,
+ 0x993 } },
+ .sample_patrn_length = 142,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 40) = 0.444444 */
+ .hor_phase_arr = {
+ .even = { { 0, 13, 102, 7, 13, 0, 0 },
+ { 0, 4, 91, 7, 33, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 33, 7, 91, 4, 0 } },
+ .odd = { { 0, 0, 47, 7, 79, 2, 0 },
+ { 0, 0, 21, 7, 99, 8, 0 },
+ { 0, 8, 99, 7, 21, 0, 0 },
+ { 0, 2, 79, 7, 47, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 13, 102, 7, 13, 0, 0 },
+ { 0, 4, 91, 7, 33, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 33, 7, 91, 4, 0 } },
+ .odd = { { 0, 0, 47, 7, 79, 2, 0 },
+ { 0, 0, 21, 7, 99, 8, 0 },
+ { 0, 8, 99, 7, 21, 0, 0 },
+ { 0, 2, 79, 7, 47, 0, 0 } } },
+ .ptrn_arr = { { 0x9933 } },
+ .sample_patrn_length = 18,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 41) = 0.438356 */
+ .hor_phase_arr = {
+ .even = { { 0, 14, 100, 7, 14, 0, 0 },
+ { 0, 4, 87, 7, 37, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 25, 7, 96, 7, 0 },
+ { 0, 8, 98, 7, 22, 0, 0 },
+ { 0, 2, 74, 7, 51, 1, 0 },
+ { 0, 0, 40, 7, 85, 3, 0 },
+ { 0, 0, 16, 7, 100, 12, 0 },
+ { 0, 5, 90, 7, 33, 0, 0 },
+ { 0, 1, 59, 7, 67, 1, 0 },
+ { 0, 0, 27, 7, 95, 6, 0 },
+ { 0, 9, 99, 7, 20, 0, 0 },
+ { 0, 2, 78, 7, 47, 1, 0 },
+ { 0, 0, 44, 7, 81, 3, 0 },
+ { 0, 0, 18, 7, 99, 11, 0 },
+ { 0, 5, 93, 7, 30, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 30, 7, 93, 5, 0 },
+ { 0, 11, 99, 7, 18, 0, 0 },
+ { 0, 3, 81, 7, 44, 0, 0 },
+ { 0, 1, 47, 7, 78, 2, 0 },
+ { 0, 0, 20, 7, 99, 9, 0 },
+ { 0, 6, 95, 7, 27, 0, 0 },
+ { 0, 1, 67, 7, 59, 1, 0 },
+ { 0, 0, 33, 7, 90, 5, 0 },
+ { 0, 12, 100, 7, 16, 0, 0 },
+ { 0, 3, 85, 7, 40, 0, 0 },
+ { 0, 1, 51, 7, 74, 2, 0 },
+ { 0, 0, 22, 7, 98, 8, 0 },
+ { 0, 7, 96, 7, 25, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 37, 7, 87, 4, 0 } },
+ .odd = { { 0, 0, 45, 7, 80, 3, 0 },
+ { 0, 0, 19, 7, 99, 10, 0 },
+ { 0, 6, 93, 7, 29, 0, 0 },
+ { 0, 1, 65, 7, 61, 1, 0 },
+ { 0, 0, 32, 7, 91, 5, 0 },
+ { 0, 11, 100, 7, 17, 0, 0 },
+ { 0, 3, 83, 7, 42, 0, 0 },
+ { 0, 1, 49, 7, 76, 2, 0 },
+ { 0, 0, 21, 7, 98, 9, 0 },
+ { 0, 7, 95, 7, 26, 0, 0 },
+ { 0, 2, 68, 7, 57, 1, 0 },
+ { 0, 0, 35, 7, 89, 4, 0 },
+ { 0, 13, 100, 7, 15, 0, 0 },
+ { 0, 4, 86, 7, 38, 0, 0 },
+ { 0, 1, 53, 7, 72, 2, 0 },
+ { 0, 0, 23, 7, 97, 8, 0 },
+ { 0, 8, 97, 7, 23, 0, 0 },
+ { 0, 2, 72, 7, 53, 1, 0 },
+ { 0, 0, 38, 7, 86, 4, 0 },
+ { 0, 0, 15, 7, 100, 13, 0 },
+ { 0, 4, 89, 7, 35, 0, 0 },
+ { 0, 1, 57, 7, 68, 2, 0 },
+ { 0, 0, 26, 7, 95, 7, 0 },
+ { 0, 9, 98, 7, 21, 0, 0 },
+ { 0, 2, 76, 7, 49, 1, 0 },
+ { 0, 0, 42, 7, 83, 3, 0 },
+ { 0, 0, 17, 7, 100, 11, 0 },
+ { 0, 5, 91, 7, 32, 0, 0 },
+ { 0, 1, 61, 7, 65, 1, 0 },
+ { 0, 0, 29, 7, 93, 6, 0 },
+ { 0, 10, 99, 7, 19, 0, 0 },
+ { 0, 3, 80, 7, 45, 0, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 14, 100, 7, 14, 0, 0 },
+ { 0, 4, 87, 7, 37, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 25, 7, 96, 7, 0 },
+ { 0, 8, 98, 7, 22, 0, 0 },
+ { 0, 2, 74, 7, 51, 1, 0 },
+ { 0, 0, 40, 7, 85, 3, 0 },
+ { 0, 0, 16, 7, 100, 12, 0 },
+ { 0, 5, 90, 7, 33, 0, 0 },
+ { 0, 1, 59, 7, 67, 1, 0 },
+ { 0, 0, 27, 7, 95, 6, 0 },
+ { 0, 9, 99, 7, 20, 0, 0 },
+ { 0, 2, 78, 7, 47, 1, 0 },
+ { 0, 0, 44, 7, 81, 3, 0 },
+ { 0, 0, 18, 7, 99, 11, 0 },
+ { 0, 5, 93, 7, 30, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 30, 7, 93, 5, 0 },
+ { 0, 11, 99, 7, 18, 0, 0 },
+ { 0, 3, 81, 7, 44, 0, 0 },
+ { 0, 1, 47, 7, 78, 2, 0 },
+ { 0, 0, 20, 7, 99, 9, 0 },
+ { 0, 6, 95, 7, 27, 0, 0 },
+ { 0, 1, 67, 7, 59, 1, 0 },
+ { 0, 0, 33, 7, 90, 5, 0 },
+ { 0, 12, 100, 7, 16, 0, 0 },
+ { 0, 3, 85, 7, 40, 0, 0 },
+ { 0, 1, 51, 7, 74, 2, 0 },
+ { 0, 0, 22, 7, 98, 8, 0 },
+ { 0, 7, 96, 7, 25, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 37, 7, 87, 4, 0 } },
+ .odd = { { 0, 0, 45, 7, 80, 3, 0 },
+ { 0, 0, 19, 7, 99, 10, 0 },
+ { 0, 6, 93, 7, 29, 0, 0 },
+ { 0, 1, 65, 7, 61, 1, 0 },
+ { 0, 0, 32, 7, 91, 5, 0 },
+ { 0, 11, 100, 7, 17, 0, 0 },
+ { 0, 3, 83, 7, 42, 0, 0 },
+ { 0, 1, 49, 7, 76, 2, 0 },
+ { 0, 0, 21, 7, 98, 9, 0 },
+ { 0, 7, 95, 7, 26, 0, 0 },
+ { 0, 2, 68, 7, 57, 1, 0 },
+ { 0, 0, 35, 7, 89, 4, 0 },
+ { 0, 13, 100, 7, 15, 0, 0 },
+ { 0, 4, 86, 7, 38, 0, 0 },
+ { 0, 1, 53, 7, 72, 2, 0 },
+ { 0, 0, 23, 7, 97, 8, 0 },
+ { 0, 8, 97, 7, 23, 0, 0 },
+ { 0, 2, 72, 7, 53, 1, 0 },
+ { 0, 0, 38, 7, 86, 4, 0 },
+ { 0, 0, 15, 7, 100, 13, 0 },
+ { 0, 4, 89, 7, 35, 0, 0 },
+ { 0, 1, 57, 7, 68, 2, 0 },
+ { 0, 0, 26, 7, 95, 7, 0 },
+ { 0, 9, 98, 7, 21, 0, 0 },
+ { 0, 2, 76, 7, 49, 1, 0 },
+ { 0, 0, 42, 7, 83, 3, 0 },
+ { 0, 0, 17, 7, 100, 11, 0 },
+ { 0, 5, 91, 7, 32, 0, 0 },
+ { 0, 1, 61, 7, 65, 1, 0 },
+ { 0, 0, 29, 7, 93, 6, 0 },
+ { 0, 10, 99, 7, 19, 0, 0 },
+ { 0, 3, 80, 7, 45, 0, 0 } } },
+ .ptrn_arr = { { 0x664c9933, 0x664c9932, 0x64cc9932, 0x64cc9932,
+ 0x9932 } },
+ .sample_patrn_length = 146,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 42) = 0.432432 */
+ .hor_phase_arr = {
+ .even = { { 0, 14, 100, 7, 14, 0, 0 },
+ { 0, 4, 84, 7, 40, 0, 0 },
+ { 0, 1, 48, 7, 76, 3, 0 },
+ { 0, 0, 18, 7, 99, 11, 0 },
+ { 0, 5, 89, 7, 34, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 23, 7, 96, 9, 0 },
+ { 0, 7, 93, 7, 28, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 28, 7, 93, 7, 0 },
+ { 0, 9, 96, 7, 23, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 34, 7, 89, 5, 0 },
+ { 0, 11, 99, 7, 18, 0, 0 },
+ { 0, 3, 76, 7, 48, 1, 0 },
+ { 0, 0, 40, 7, 84, 4, 0 } },
+ .odd = { { 0, 1, 44, 7, 80, 3, 0 },
+ { 0, 0, 16, 7, 99, 13, 0 },
+ { 0, 4, 87, 7, 37, 0, 0 },
+ { 0, 1, 51, 7, 74, 2, 0 },
+ { 0, 0, 20, 7, 98, 10, 0 },
+ { 0, 6, 91, 7, 31, 0, 0 },
+ { 0, 1, 59, 7, 66, 2, 0 },
+ { 0, 0, 25, 7, 95, 8, 0 },
+ { 0, 8, 95, 7, 25, 0, 0 },
+ { 0, 2, 66, 7, 59, 1, 0 },
+ { 0, 0, 31, 7, 91, 6, 0 },
+ { 0, 10, 98, 7, 20, 0, 0 },
+ { 0, 2, 74, 7, 51, 1, 0 },
+ { 0, 0, 37, 7, 87, 4, 0 },
+ { 0, 13, 99, 7, 16, 0, 0 },
+ { 0, 3, 80, 7, 44, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 14, 100, 7, 14, 0, 0 },
+ { 0, 4, 84, 7, 40, 0, 0 },
+ { 0, 1, 48, 7, 76, 3, 0 },
+ { 0, 0, 18, 7, 99, 11, 0 },
+ { 0, 5, 89, 7, 34, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 23, 7, 96, 9, 0 },
+ { 0, 7, 93, 7, 28, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 28, 7, 93, 7, 0 },
+ { 0, 9, 96, 7, 23, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 34, 7, 89, 5, 0 },
+ { 0, 11, 99, 7, 18, 0, 0 },
+ { 0, 3, 76, 7, 48, 1, 0 },
+ { 0, 0, 40, 7, 84, 4, 0 } },
+ .odd = { { 0, 1, 44, 7, 80, 3, 0 },
+ { 0, 0, 16, 7, 99, 13, 0 },
+ { 0, 4, 87, 7, 37, 0, 0 },
+ { 0, 1, 51, 7, 74, 2, 0 },
+ { 0, 0, 20, 7, 98, 10, 0 },
+ { 0, 6, 91, 7, 31, 0, 0 },
+ { 0, 1, 59, 7, 66, 2, 0 },
+ { 0, 0, 25, 7, 95, 8, 0 },
+ { 0, 8, 95, 7, 25, 0, 0 },
+ { 0, 2, 66, 7, 59, 1, 0 },
+ { 0, 0, 31, 7, 91, 6, 0 },
+ { 0, 10, 98, 7, 20, 0, 0 },
+ { 0, 2, 74, 7, 51, 1, 0 },
+ { 0, 0, 37, 7, 87, 4, 0 },
+ { 0, 13, 99, 7, 16, 0, 0 },
+ { 0, 3, 80, 7, 44, 1, 0 } } },
+ .ptrn_arr = { { 0x264c9933, 0x3264c993, 0x99 } },
+ .sample_patrn_length = 74,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 43) = 0.426667 */
+ .hor_phase_arr = {
+ .even = { { 0, 15, 98, 7, 15, 0, 0 },
+ { 0, 3, 80, 7, 44, 1, 0 },
+ { 0, 0, 41, 7, 83, 4, 0 },
+ { 0, 13, 98, 7, 17, 0, 0 },
+ { 0, 3, 76, 7, 48, 1, 0 },
+ { 0, 0, 38, 7, 85, 5, 0 },
+ { 0, 12, 97, 7, 19, 0, 0 },
+ { 0, 2, 74, 7, 51, 1, 0 },
+ { 0, 0, 34, 7, 89, 5, 0 },
+ { 0, 10, 97, 7, 21, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 31, 7, 91, 6, 0 },
+ { 0, 9, 96, 7, 23, 0, 0 },
+ { 0, 2, 66, 7, 59, 1, 0 },
+ { 0, 0, 29, 7, 92, 7, 0 },
+ { 0, 8, 94, 7, 26, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 26, 7, 94, 8, 0 },
+ { 0, 7, 92, 7, 29, 0, 0 },
+ { 0, 1, 59, 7, 66, 2, 0 },
+ { 0, 0, 23, 7, 96, 9, 0 },
+ { 0, 6, 91, 7, 31, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 21, 7, 97, 10, 0 },
+ { 0, 5, 89, 7, 34, 0, 0 },
+ { 0, 1, 51, 7, 74, 2, 0 },
+ { 0, 0, 19, 7, 97, 12, 0 },
+ { 0, 5, 85, 7, 38, 0, 0 },
+ { 0, 1, 48, 7, 76, 3, 0 },
+ { 0, 0, 17, 7, 98, 13, 0 },
+ { 0, 4, 83, 7, 41, 0, 0 },
+ { 0, 1, 44, 7, 80, 3, 0 } },
+ .odd = { { 0, 1, 43, 7, 80, 4, 0 },
+ { 0, 14, 98, 7, 16, 0, 0 },
+ { 0, 3, 78, 7, 46, 1, 0 },
+ { 0, 0, 39, 7, 85, 4, 0 },
+ { 0, 12, 98, 7, 18, 0, 0 },
+ { 0, 3, 74, 7, 50, 1, 0 },
+ { 0, 0, 36, 7, 87, 5, 0 },
+ { 0, 11, 97, 7, 20, 0, 0 },
+ { 0, 2, 72, 7, 53, 1, 0 },
+ { 0, 0, 33, 7, 89, 6, 0 },
+ { 0, 10, 96, 7, 22, 0, 0 },
+ { 0, 2, 68, 7, 57, 1, 0 },
+ { 0, 0, 30, 7, 92, 6, 0 },
+ { 0, 9, 94, 7, 25, 0, 0 },
+ { 0, 2, 64, 7, 61, 1, 0 },
+ { 0, 0, 27, 7, 94, 7, 0 },
+ { 0, 7, 94, 7, 27, 0, 0 },
+ { 0, 1, 61, 7, 64, 2, 0 },
+ { 0, 0, 25, 7, 94, 9, 0 },
+ { 0, 6, 92, 7, 30, 0, 0 },
+ { 0, 1, 57, 7, 68, 2, 0 },
+ { 0, 0, 22, 7, 96, 10, 0 },
+ { 0, 6, 89, 7, 33, 0, 0 },
+ { 0, 1, 53, 7, 72, 2, 0 },
+ { 0, 0, 20, 7, 97, 11, 0 },
+ { 0, 5, 87, 7, 36, 0, 0 },
+ { 0, 1, 50, 7, 74, 3, 0 },
+ { 0, 0, 18, 7, 98, 12, 0 },
+ { 0, 4, 85, 7, 39, 0, 0 },
+ { 0, 1, 46, 7, 78, 3, 0 },
+ { 0, 0, 16, 7, 98, 14, 0 },
+ { 0, 4, 80, 7, 43, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 15, 98, 7, 15, 0, 0 },
+ { 0, 3, 80, 7, 44, 1, 0 },
+ { 0, 0, 41, 7, 83, 4, 0 },
+ { 0, 13, 98, 7, 17, 0, 0 },
+ { 0, 3, 76, 7, 48, 1, 0 },
+ { 0, 0, 38, 7, 85, 5, 0 },
+ { 0, 12, 97, 7, 19, 0, 0 },
+ { 0, 2, 74, 7, 51, 1, 0 },
+ { 0, 0, 34, 7, 89, 5, 0 },
+ { 0, 10, 97, 7, 21, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 31, 7, 91, 6, 0 },
+ { 0, 9, 96, 7, 23, 0, 0 },
+ { 0, 2, 66, 7, 59, 1, 0 },
+ { 0, 0, 29, 7, 92, 7, 0 },
+ { 0, 8, 94, 7, 26, 0, 0 },
+ { 0, 1, 63, 7, 63, 1, 0 },
+ { 0, 0, 26, 7, 94, 8, 0 },
+ { 0, 7, 92, 7, 29, 0, 0 },
+ { 0, 1, 59, 7, 66, 2, 0 },
+ { 0, 0, 23, 7, 96, 9, 0 },
+ { 0, 6, 91, 7, 31, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 21, 7, 97, 10, 0 },
+ { 0, 5, 89, 7, 34, 0, 0 },
+ { 0, 1, 51, 7, 74, 2, 0 },
+ { 0, 0, 19, 7, 97, 12, 0 },
+ { 0, 5, 85, 7, 38, 0, 0 },
+ { 0, 1, 48, 7, 76, 3, 0 },
+ { 0, 0, 17, 7, 98, 13, 0 },
+ { 0, 4, 83, 7, 41, 0, 0 },
+ { 0, 1, 44, 7, 80, 3, 0 } },
+ .odd = { { 0, 1, 43, 7, 80, 4, 0 },
+ { 0, 14, 98, 7, 16, 0, 0 },
+ { 0, 3, 78, 7, 46, 1, 0 },
+ { 0, 0, 39, 7, 85, 4, 0 },
+ { 0, 12, 98, 7, 18, 0, 0 },
+ { 0, 3, 74, 7, 50, 1, 0 },
+ { 0, 0, 36, 7, 87, 5, 0 },
+ { 0, 11, 97, 7, 20, 0, 0 },
+ { 0, 2, 72, 7, 53, 1, 0 },
+ { 0, 0, 33, 7, 89, 6, 0 },
+ { 0, 10, 96, 7, 22, 0, 0 },
+ { 0, 2, 68, 7, 57, 1, 0 },
+ { 0, 0, 30, 7, 92, 6, 0 },
+ { 0, 9, 94, 7, 25, 0, 0 },
+ { 0, 2, 64, 7, 61, 1, 0 },
+ { 0, 0, 27, 7, 94, 7, 0 },
+ { 0, 7, 94, 7, 27, 0, 0 },
+ { 0, 1, 61, 7, 64, 2, 0 },
+ { 0, 0, 25, 7, 94, 9, 0 },
+ { 0, 6, 92, 7, 30, 0, 0 },
+ { 0, 1, 57, 7, 68, 2, 0 },
+ { 0, 0, 22, 7, 96, 10, 0 },
+ { 0, 6, 89, 7, 33, 0, 0 },
+ { 0, 1, 53, 7, 72, 2, 0 },
+ { 0, 0, 20, 7, 97, 11, 0 },
+ { 0, 5, 87, 7, 36, 0, 0 },
+ { 0, 1, 50, 7, 74, 3, 0 },
+ { 0, 0, 18, 7, 98, 12, 0 },
+ { 0, 4, 85, 7, 39, 0, 0 },
+ { 0, 1, 46, 7, 78, 3, 0 },
+ { 0, 0, 16, 7, 98, 14, 0 },
+ { 0, 4, 80, 7, 43, 1, 0 } } },
+ .ptrn_arr = { { 0x3264c993, 0x93264c99, 0x993264c9, 0xc993264c,
+ 0x93264 } },
+ .sample_patrn_length = 150,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 44) = 0.421053 */
+ .hor_phase_arr = {
+ .even = { { 0, 16, 96, 7, 16, 0, 0 },
+ { 0, 3, 76, 7, 48, 1, 0 },
+ { 0, 0, 35, 7, 87, 6, 0 },
+ { 0, 10, 94, 7, 24, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 0, 24, 7, 94, 10, 0 },
+ { 0, 6, 87, 7, 35, 0, 0 },
+ { 0, 1, 48, 7, 76, 3, 0 } },
+ .odd = { { 0, 1, 41, 7, 82, 4, 0 },
+ { 0, 12, 97, 7, 19, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 29, 7, 92, 7, 0 },
+ { 0, 7, 92, 7, 29, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 19, 7, 97, 12, 0 },
+ { 0, 4, 82, 7, 41, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 16, 96, 7, 16, 0, 0 },
+ { 0, 3, 76, 7, 48, 1, 0 },
+ { 0, 0, 35, 7, 87, 6, 0 },
+ { 0, 10, 94, 7, 24, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 0, 24, 7, 94, 10, 0 },
+ { 0, 6, 87, 7, 35, 0, 0 },
+ { 0, 1, 48, 7, 76, 3, 0 } },
+ .odd = { { 0, 1, 41, 7, 82, 4, 0 },
+ { 0, 12, 97, 7, 19, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 29, 7, 92, 7, 0 },
+ { 0, 7, 92, 7, 29, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 19, 7, 97, 12, 0 },
+ { 0, 4, 82, 7, 41, 1, 0 } } },
+ .ptrn_arr = { { 0x3264c993, 0x9 } },
+ .sample_patrn_length = 38,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 45) = 0.415584 */
+ .hor_phase_arr = {
+ .even = { { 0, 16, 96, 7, 16, 0, 0 },
+ { 0, 3, 72, 7, 52, 1, 0 },
+ { 0, 0, 30, 7, 90, 8, 0 },
+ { 0, 7, 89, 7, 32, 0, 0 },
+ { 0, 1, 48, 7, 76, 3, 0 },
+ { 0, 14, 96, 7, 18, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 27, 7, 92, 9, 0 },
+ { 0, 6, 87, 7, 35, 0, 0 },
+ { 0, 1, 45, 7, 78, 4, 0 },
+ { 0, 13, 95, 7, 20, 0, 0 },
+ { 0, 2, 66, 7, 59, 1, 0 },
+ { 0, 0, 24, 7, 94, 10, 0 },
+ { 0, 5, 85, 7, 38, 0, 0 },
+ { 0, 1, 42, 7, 81, 4, 0 },
+ { 0, 11, 95, 7, 22, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 0, 22, 7, 95, 11, 0 },
+ { 0, 4, 81, 7, 42, 1, 0 },
+ { 0, 0, 38, 7, 85, 5, 0 },
+ { 0, 10, 94, 7, 24, 0, 0 },
+ { 0, 1, 59, 7, 66, 2, 0 },
+ { 0, 0, 20, 7, 95, 13, 0 },
+ { 0, 4, 78, 7, 45, 1, 0 },
+ { 0, 0, 35, 7, 87, 6, 0 },
+ { 0, 9, 92, 7, 27, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 18, 7, 96, 14, 0 },
+ { 0, 3, 76, 7, 48, 1, 0 },
+ { 0, 0, 32, 7, 89, 7, 0 },
+ { 0, 8, 90, 7, 30, 0, 0 },
+ { 0, 1, 52, 7, 72, 3, 0 } },
+ .odd = { { 0, 1, 40, 7, 82, 5, 0 },
+ { 0, 11, 94, 7, 23, 0, 0 },
+ { 0, 2, 61, 7, 63, 2, 0 },
+ { 0, 0, 21, 7, 95, 12, 0 },
+ { 0, 4, 80, 7, 43, 1, 0 },
+ { 0, 0, 37, 7, 85, 6, 0 },
+ { 0, 9, 93, 7, 26, 0, 0 },
+ { 0, 1, 57, 7, 68, 2, 0 },
+ { 0, 0, 19, 7, 95, 14, 0 },
+ { 0, 4, 76, 7, 47, 1, 0 },
+ { 0, 0, 34, 7, 88, 6, 0 },
+ { 0, 8, 92, 7, 28, 0, 0 },
+ { 0, 1, 54, 7, 70, 3, 0 },
+ { 0, 0, 17, 7, 96, 15, 0 },
+ { 0, 3, 74, 7, 50, 1, 0 },
+ { 0, 0, 31, 7, 90, 7, 0 },
+ { 0, 7, 90, 7, 31, 0, 0 },
+ { 0, 1, 50, 7, 74, 3, 0 },
+ { 0, 15, 96, 7, 17, 0, 0 },
+ { 0, 3, 70, 7, 54, 1, 0 },
+ { 0, 0, 28, 7, 92, 8, 0 },
+ { 0, 6, 88, 7, 34, 0, 0 },
+ { 0, 1, 47, 7, 76, 4, 0 },
+ { 0, 14, 95, 7, 19, 0, 0 },
+ { 0, 2, 68, 7, 57, 1, 0 },
+ { 0, 0, 26, 7, 93, 9, 0 },
+ { 0, 6, 85, 7, 37, 0, 0 },
+ { 0, 1, 43, 7, 80, 4, 0 },
+ { 0, 12, 95, 7, 21, 0, 0 },
+ { 0, 2, 63, 7, 61, 2, 0 },
+ { 0, 0, 23, 7, 94, 11, 0 },
+ { 0, 5, 82, 7, 40, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 16, 96, 7, 16, 0, 0 },
+ { 0, 3, 72, 7, 52, 1, 0 },
+ { 0, 0, 30, 7, 90, 8, 0 },
+ { 0, 7, 89, 7, 32, 0, 0 },
+ { 0, 1, 48, 7, 76, 3, 0 },
+ { 0, 14, 96, 7, 18, 0, 0 },
+ { 0, 2, 70, 7, 55, 1, 0 },
+ { 0, 0, 27, 7, 92, 9, 0 },
+ { 0, 6, 87, 7, 35, 0, 0 },
+ { 0, 1, 45, 7, 78, 4, 0 },
+ { 0, 13, 95, 7, 20, 0, 0 },
+ { 0, 2, 66, 7, 59, 1, 0 },
+ { 0, 0, 24, 7, 94, 10, 0 },
+ { 0, 5, 85, 7, 38, 0, 0 },
+ { 0, 1, 42, 7, 81, 4, 0 },
+ { 0, 11, 95, 7, 22, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 0, 22, 7, 95, 11, 0 },
+ { 0, 4, 81, 7, 42, 1, 0 },
+ { 0, 0, 38, 7, 85, 5, 0 },
+ { 0, 10, 94, 7, 24, 0, 0 },
+ { 0, 1, 59, 7, 66, 2, 0 },
+ { 0, 0, 20, 7, 95, 13, 0 },
+ { 0, 4, 78, 7, 45, 1, 0 },
+ { 0, 0, 35, 7, 87, 6, 0 },
+ { 0, 9, 92, 7, 27, 0, 0 },
+ { 0, 1, 55, 7, 70, 2, 0 },
+ { 0, 0, 18, 7, 96, 14, 0 },
+ { 0, 3, 76, 7, 48, 1, 0 },
+ { 0, 0, 32, 7, 89, 7, 0 },
+ { 0, 8, 90, 7, 30, 0, 0 },
+ { 0, 1, 52, 7, 72, 3, 0 } },
+ .odd = { { 0, 1, 40, 7, 82, 5, 0 },
+ { 0, 11, 94, 7, 23, 0, 0 },
+ { 0, 2, 61, 7, 63, 2, 0 },
+ { 0, 0, 21, 7, 95, 12, 0 },
+ { 0, 4, 80, 7, 43, 1, 0 },
+ { 0, 0, 37, 7, 85, 6, 0 },
+ { 0, 9, 93, 7, 26, 0, 0 },
+ { 0, 1, 57, 7, 68, 2, 0 },
+ { 0, 0, 19, 7, 95, 14, 0 },
+ { 0, 4, 76, 7, 47, 1, 0 },
+ { 0, 0, 34, 7, 88, 6, 0 },
+ { 0, 8, 92, 7, 28, 0, 0 },
+ { 0, 1, 54, 7, 70, 3, 0 },
+ { 0, 0, 17, 7, 96, 15, 0 },
+ { 0, 3, 74, 7, 50, 1, 0 },
+ { 0, 0, 31, 7, 90, 7, 0 },
+ { 0, 7, 90, 7, 31, 0, 0 },
+ { 0, 1, 50, 7, 74, 3, 0 },
+ { 0, 15, 96, 7, 17, 0, 0 },
+ { 0, 3, 70, 7, 54, 1, 0 },
+ { 0, 0, 28, 7, 92, 8, 0 },
+ { 0, 6, 88, 7, 34, 0, 0 },
+ { 0, 1, 47, 7, 76, 4, 0 },
+ { 0, 14, 95, 7, 19, 0, 0 },
+ { 0, 2, 68, 7, 57, 1, 0 },
+ { 0, 0, 26, 7, 93, 9, 0 },
+ { 0, 6, 85, 7, 37, 0, 0 },
+ { 0, 1, 43, 7, 80, 4, 0 },
+ { 0, 12, 95, 7, 21, 0, 0 },
+ { 0, 2, 63, 7, 61, 2, 0 },
+ { 0, 0, 23, 7, 94, 11, 0 },
+ { 0, 5, 82, 7, 40, 1, 0 } } },
+ .ptrn_arr = { { 0x9324c993, 0xc99324c9, 0x26499324, 0x93264993,
+ 0x932649 } },
+ .sample_patrn_length = 154,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 46) = 0.410256 */
+ .hor_phase_arr = {
+ .even = { { 0, 17, 94, 7, 17, 0, 0 },
+ { 0, 3, 69, 7, 55, 1, 0 },
+ { 0, 0, 25, 7, 93, 10, 0 },
+ { 0, 5, 80, 7, 42, 1, 0 },
+ { 0, 0, 36, 7, 86, 6, 0 },
+ { 0, 8, 90, 7, 30, 0, 0 },
+ { 0, 1, 49, 7, 74, 4, 0 },
+ { 0, 13, 94, 7, 21, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 0, 21, 7, 94, 13, 0 },
+ { 0, 4, 74, 7, 49, 1, 0 },
+ { 0, 0, 30, 7, 90, 8, 0 },
+ { 0, 6, 86, 7, 36, 0, 0 },
+ { 0, 1, 42, 7, 80, 5, 0 },
+ { 0, 10, 93, 7, 25, 0, 0 },
+ { 0, 1, 55, 7, 69, 3, 0 } },
+ .odd = { { 0, 1, 39, 7, 83, 5, 0 },
+ { 0, 9, 91, 7, 28, 0, 0 },
+ { 0, 1, 52, 7, 72, 3, 0 },
+ { 0, 15, 94, 7, 19, 0, 0 },
+ { 0, 2, 65, 7, 59, 2, 0 },
+ { 0, 0, 23, 7, 93, 12, 0 },
+ { 0, 4, 78, 7, 45, 1, 0 },
+ { 0, 0, 33, 7, 88, 7, 0 },
+ { 0, 7, 88, 7, 33, 0, 0 },
+ { 0, 1, 45, 7, 78, 4, 0 },
+ { 0, 12, 93, 7, 23, 0, 0 },
+ { 0, 2, 59, 7, 65, 2, 0 },
+ { 0, 0, 19, 7, 94, 15, 0 },
+ { 0, 3, 72, 7, 52, 1, 0 },
+ { 0, 0, 28, 7, 91, 9, 0 },
+ { 0, 5, 83, 7, 39, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 17, 94, 7, 17, 0, 0 },
+ { 0, 3, 69, 7, 55, 1, 0 },
+ { 0, 0, 25, 7, 93, 10, 0 },
+ { 0, 5, 80, 7, 42, 1, 0 },
+ { 0, 0, 36, 7, 86, 6, 0 },
+ { 0, 8, 90, 7, 30, 0, 0 },
+ { 0, 1, 49, 7, 74, 4, 0 },
+ { 0, 13, 94, 7, 21, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 0, 21, 7, 94, 13, 0 },
+ { 0, 4, 74, 7, 49, 1, 0 },
+ { 0, 0, 30, 7, 90, 8, 0 },
+ { 0, 6, 86, 7, 36, 0, 0 },
+ { 0, 1, 42, 7, 80, 5, 0 },
+ { 0, 10, 93, 7, 25, 0, 0 },
+ { 0, 1, 55, 7, 69, 3, 0 } },
+ .odd = { { 0, 1, 39, 7, 83, 5, 0 },
+ { 0, 9, 91, 7, 28, 0, 0 },
+ { 0, 1, 52, 7, 72, 3, 0 },
+ { 0, 15, 94, 7, 19, 0, 0 },
+ { 0, 2, 65, 7, 59, 2, 0 },
+ { 0, 0, 23, 7, 93, 12, 0 },
+ { 0, 4, 78, 7, 45, 1, 0 },
+ { 0, 0, 33, 7, 88, 7, 0 },
+ { 0, 7, 88, 7, 33, 0, 0 },
+ { 0, 1, 45, 7, 78, 4, 0 },
+ { 0, 12, 93, 7, 23, 0, 0 },
+ { 0, 2, 59, 7, 65, 2, 0 },
+ { 0, 0, 19, 7, 94, 15, 0 },
+ { 0, 3, 72, 7, 52, 1, 0 },
+ { 0, 0, 28, 7, 91, 9, 0 },
+ { 0, 5, 83, 7, 39, 1, 0 } } },
+ .ptrn_arr = { { 0x93264993, 0x4c99264c, 0x932 } },
+ .sample_patrn_length = 78,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 47) = 0.405063 */
+ .hor_phase_arr = {
+ .even = { { 0, 17, 94, 7, 17, 0, 0 },
+ { 0, 2, 65, 7, 59, 2, 0 },
+ { 0, 0, 21, 7, 93, 14, 0 },
+ { 0, 3, 72, 7, 52, 1, 0 },
+ { 0, 0, 26, 7, 91, 11, 0 },
+ { 0, 4, 78, 7, 45, 1, 0 },
+ { 0, 0, 31, 7, 88, 9, 0 },
+ { 0, 6, 82, 7, 39, 1, 0 },
+ { 0, 1, 36, 7, 84, 7, 0 },
+ { 0, 8, 87, 7, 33, 0, 0 },
+ { 0, 1, 42, 7, 80, 5, 0 },
+ { 0, 10, 90, 7, 28, 0, 0 },
+ { 0, 1, 49, 7, 74, 4, 0 },
+ { 0, 12, 93, 7, 23, 0, 0 },
+ { 0, 2, 55, 7, 68, 3, 0 },
+ { 0, 15, 94, 7, 19, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 0, 19, 7, 94, 15, 0 },
+ { 0, 3, 68, 7, 55, 2, 0 },
+ { 0, 0, 23, 7, 93, 12, 0 },
+ { 0, 4, 74, 7, 49, 1, 0 },
+ { 0, 0, 28, 7, 90, 10, 0 },
+ { 0, 5, 80, 7, 42, 1, 0 },
+ { 0, 0, 33, 7, 87, 8, 0 },
+ { 0, 7, 84, 7, 36, 1, 0 },
+ { 0, 1, 39, 7, 82, 6, 0 },
+ { 0, 9, 88, 7, 31, 0, 0 },
+ { 0, 1, 45, 7, 78, 4, 0 },
+ { 0, 11, 91, 7, 26, 0, 0 },
+ { 0, 1, 52, 7, 72, 3, 0 },
+ { 0, 14, 93, 7, 21, 0, 0 },
+ { 0, 2, 59, 7, 65, 2, 0 } },
+ .odd = { { 0, 1, 38, 7, 83, 6, 0 },
+ { 0, 8, 88, 7, 32, 0, 0 },
+ { 0, 1, 44, 7, 78, 5, 0 },
+ { 0, 10, 91, 7, 27, 0, 0 },
+ { 0, 1, 50, 7, 73, 4, 0 },
+ { 0, 13, 93, 7, 22, 0, 0 },
+ { 0, 2, 57, 7, 66, 3, 0 },
+ { 0, 16, 94, 7, 18, 0, 0 },
+ { 0, 2, 64, 7, 60, 2, 0 },
+ { 0, 0, 20, 7, 93, 15, 0 },
+ { 0, 3, 70, 7, 54, 1, 0 },
+ { 0, 0, 24, 7, 92, 12, 0 },
+ { 0, 4, 76, 7, 47, 1, 0 },
+ { 0, 0, 29, 7, 90, 9, 0 },
+ { 0, 5, 81, 7, 41, 1, 0 },
+ { 0, 0, 35, 7, 86, 7, 0 },
+ { 0, 7, 86, 7, 35, 0, 0 },
+ { 0, 1, 41, 7, 81, 5, 0 },
+ { 0, 9, 90, 7, 29, 0, 0 },
+ { 0, 1, 47, 7, 76, 4, 0 },
+ { 0, 12, 92, 7, 24, 0, 0 },
+ { 0, 1, 54, 7, 70, 3, 0 },
+ { 0, 15, 93, 7, 20, 0, 0 },
+ { 0, 2, 60, 7, 64, 2, 0 },
+ { 0, 0, 18, 7, 94, 16, 0 },
+ { 0, 3, 66, 7, 57, 2, 0 },
+ { 0, 0, 22, 7, 93, 13, 0 },
+ { 0, 4, 73, 7, 50, 1, 0 },
+ { 0, 0, 27, 7, 91, 10, 0 },
+ { 0, 5, 78, 7, 44, 1, 0 },
+ { 0, 0, 32, 7, 88, 8, 0 },
+ { 0, 6, 83, 7, 38, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 17, 94, 7, 17, 0, 0 },
+ { 0, 2, 65, 7, 59, 2, 0 },
+ { 0, 0, 21, 7, 93, 14, 0 },
+ { 0, 3, 72, 7, 52, 1, 0 },
+ { 0, 0, 26, 7, 91, 11, 0 },
+ { 0, 4, 78, 7, 45, 1, 0 },
+ { 0, 0, 31, 7, 88, 9, 0 },
+ { 0, 6, 82, 7, 39, 1, 0 },
+ { 0, 1, 36, 7, 84, 7, 0 },
+ { 0, 8, 87, 7, 33, 0, 0 },
+ { 0, 1, 42, 7, 80, 5, 0 },
+ { 0, 10, 90, 7, 28, 0, 0 },
+ { 0, 1, 49, 7, 74, 4, 0 },
+ { 0, 12, 93, 7, 23, 0, 0 },
+ { 0, 2, 55, 7, 68, 3, 0 },
+ { 0, 15, 94, 7, 19, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 0, 19, 7, 94, 15, 0 },
+ { 0, 3, 68, 7, 55, 2, 0 },
+ { 0, 0, 23, 7, 93, 12, 0 },
+ { 0, 4, 74, 7, 49, 1, 0 },
+ { 0, 0, 28, 7, 90, 10, 0 },
+ { 0, 5, 80, 7, 42, 1, 0 },
+ { 0, 0, 33, 7, 87, 8, 0 },
+ { 0, 7, 84, 7, 36, 1, 0 },
+ { 0, 1, 39, 7, 82, 6, 0 },
+ { 0, 9, 88, 7, 31, 0, 0 },
+ { 0, 1, 45, 7, 78, 4, 0 },
+ { 0, 11, 91, 7, 26, 0, 0 },
+ { 0, 1, 52, 7, 72, 3, 0 },
+ { 0, 14, 93, 7, 21, 0, 0 },
+ { 0, 2, 59, 7, 65, 2, 0 } },
+ .odd = { { 0, 1, 38, 7, 83, 6, 0 },
+ { 0, 8, 88, 7, 32, 0, 0 },
+ { 0, 1, 44, 7, 78, 5, 0 },
+ { 0, 10, 91, 7, 27, 0, 0 },
+ { 0, 1, 50, 7, 73, 4, 0 },
+ { 0, 13, 93, 7, 22, 0, 0 },
+ { 0, 2, 57, 7, 66, 3, 0 },
+ { 0, 16, 94, 7, 18, 0, 0 },
+ { 0, 2, 64, 7, 60, 2, 0 },
+ { 0, 0, 20, 7, 93, 15, 0 },
+ { 0, 3, 70, 7, 54, 1, 0 },
+ { 0, 0, 24, 7, 92, 12, 0 },
+ { 0, 4, 76, 7, 47, 1, 0 },
+ { 0, 0, 29, 7, 90, 9, 0 },
+ { 0, 5, 81, 7, 41, 1, 0 },
+ { 0, 0, 35, 7, 86, 7, 0 },
+ { 0, 7, 86, 7, 35, 0, 0 },
+ { 0, 1, 41, 7, 81, 5, 0 },
+ { 0, 9, 90, 7, 29, 0, 0 },
+ { 0, 1, 47, 7, 76, 4, 0 },
+ { 0, 12, 92, 7, 24, 0, 0 },
+ { 0, 1, 54, 7, 70, 3, 0 },
+ { 0, 15, 93, 7, 20, 0, 0 },
+ { 0, 2, 60, 7, 64, 2, 0 },
+ { 0, 0, 18, 7, 94, 16, 0 },
+ { 0, 3, 66, 7, 57, 2, 0 },
+ { 0, 0, 22, 7, 93, 13, 0 },
+ { 0, 4, 73, 7, 50, 1, 0 },
+ { 0, 0, 27, 7, 91, 10, 0 },
+ { 0, 5, 78, 7, 44, 1, 0 },
+ { 0, 0, 32, 7, 88, 8, 0 },
+ { 0, 6, 83, 7, 38, 1, 0 } } },
+ .ptrn_arr = { { 0x99264993, 0x24c93264, 0x99264c93, 0x24c99264,
+ 0x9324c93 } },
+ .sample_patrn_length = 158,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 48) = 0.4 */
+ .hor_phase_arr = {
+ .even = { { 0, 18, 92, 7, 18, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 } },
+ .odd = { { 0, 1, 37, 7, 83, 7, 0 },
+ { 0, 7, 83, 7, 37, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 18, 92, 7, 18, 0, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 } },
+ .odd = { { 0, 1, 37, 7, 83, 7, 0 },
+ { 0, 7, 83, 7, 37, 1, 0 } } },
+ .ptrn_arr = { { 0x93 } },
+ .sample_patrn_length = 10,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 49) = 0.395062 */
+ .hor_phase_arr = {
+ .even = { { 0, 18, 92, 7, 18, 0, 0 },
+ { 0, 2, 58, 7, 65, 3, 0 },
+ { 0, 15, 91, 7, 22, 0, 0 },
+ { 0, 2, 52, 7, 70, 4, 0 },
+ { 0, 12, 89, 7, 27, 0, 0 },
+ { 0, 1, 46, 7, 76, 5, 0 },
+ { 0, 9, 87, 7, 32, 0, 0 },
+ { 0, 1, 40, 7, 80, 7, 0 },
+ { 0, 7, 83, 7, 37, 1, 0 },
+ { 0, 1, 34, 7, 85, 8, 0 },
+ { 0, 6, 78, 7, 43, 1, 0 },
+ { 0, 0, 29, 7, 88, 11, 0 },
+ { 0, 4, 74, 7, 49, 1, 0 },
+ { 0, 0, 24, 7, 91, 13, 0 },
+ { 0, 3, 68, 7, 55, 2, 0 },
+ { 0, 0, 20, 7, 92, 16, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 16, 92, 7, 20, 0, 0 },
+ { 0, 2, 55, 7, 68, 3, 0 },
+ { 0, 13, 91, 7, 24, 0, 0 },
+ { 0, 1, 49, 7, 74, 4, 0 },
+ { 0, 11, 88, 7, 29, 0, 0 },
+ { 0, 1, 43, 7, 78, 6, 0 },
+ { 0, 8, 85, 7, 34, 1, 0 },
+ { 0, 1, 37, 7, 83, 7, 0 },
+ { 0, 7, 80, 7, 40, 1, 0 },
+ { 0, 0, 32, 7, 87, 9, 0 },
+ { 0, 5, 76, 7, 46, 1, 0 },
+ { 0, 0, 27, 7, 89, 12, 0 },
+ { 0, 4, 70, 7, 52, 2, 0 },
+ { 0, 0, 22, 7, 91, 15, 0 },
+ { 0, 3, 65, 7, 58, 2, 0 } },
+ .odd = { { 0, 1, 36, 7, 83, 8, 0 },
+ { 0, 6, 80, 7, 41, 1, 0 },
+ { 0, 0, 30, 7, 88, 10, 0 },
+ { 0, 5, 75, 7, 47, 1, 0 },
+ { 0, 0, 25, 7, 90, 13, 0 },
+ { 0, 4, 68, 7, 54, 2, 0 },
+ { 0, 0, 21, 7, 91, 16, 0 },
+ { 0, 3, 63, 7, 60, 2, 0 },
+ { 0, 17, 92, 7, 19, 0, 0 },
+ { 0, 2, 57, 7, 66, 3, 0 },
+ { 0, 14, 91, 7, 23, 0, 0 },
+ { 0, 1, 51, 7, 72, 4, 0 },
+ { 0, 11, 89, 7, 28, 0, 0 },
+ { 0, 1, 44, 7, 78, 5, 0 },
+ { 0, 9, 85, 7, 33, 1, 0 },
+ { 0, 1, 38, 7, 82, 7, 0 },
+ { 0, 7, 82, 7, 38, 1, 0 },
+ { 0, 1, 33, 7, 85, 9, 0 },
+ { 0, 5, 78, 7, 44, 1, 0 },
+ { 0, 0, 28, 7, 89, 11, 0 },
+ { 0, 4, 72, 7, 51, 1, 0 },
+ { 0, 0, 23, 7, 91, 14, 0 },
+ { 0, 3, 66, 7, 57, 2, 0 },
+ { 0, 0, 19, 7, 92, 17, 0 },
+ { 0, 2, 60, 7, 63, 3, 0 },
+ { 0, 16, 91, 7, 21, 0, 0 },
+ { 0, 2, 54, 7, 68, 4, 0 },
+ { 0, 13, 90, 7, 25, 0, 0 },
+ { 0, 1, 47, 7, 75, 5, 0 },
+ { 0, 10, 88, 7, 30, 0, 0 },
+ { 0, 1, 41, 7, 80, 6, 0 },
+ { 0, 8, 83, 7, 36, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 18, 92, 7, 18, 0, 0 },
+ { 0, 2, 58, 7, 65, 3, 0 },
+ { 0, 15, 91, 7, 22, 0, 0 },
+ { 0, 2, 52, 7, 70, 4, 0 },
+ { 0, 12, 89, 7, 27, 0, 0 },
+ { 0, 1, 46, 7, 76, 5, 0 },
+ { 0, 9, 87, 7, 32, 0, 0 },
+ { 0, 1, 40, 7, 80, 7, 0 },
+ { 0, 7, 83, 7, 37, 1, 0 },
+ { 0, 1, 34, 7, 85, 8, 0 },
+ { 0, 6, 78, 7, 43, 1, 0 },
+ { 0, 0, 29, 7, 88, 11, 0 },
+ { 0, 4, 74, 7, 49, 1, 0 },
+ { 0, 0, 24, 7, 91, 13, 0 },
+ { 0, 3, 68, 7, 55, 2, 0 },
+ { 0, 0, 20, 7, 92, 16, 0 },
+ { 0, 2, 62, 7, 62, 2, 0 },
+ { 0, 16, 92, 7, 20, 0, 0 },
+ { 0, 2, 55, 7, 68, 3, 0 },
+ { 0, 13, 91, 7, 24, 0, 0 },
+ { 0, 1, 49, 7, 74, 4, 0 },
+ { 0, 11, 88, 7, 29, 0, 0 },
+ { 0, 1, 43, 7, 78, 6, 0 },
+ { 0, 8, 85, 7, 34, 1, 0 },
+ { 0, 1, 37, 7, 83, 7, 0 },
+ { 0, 7, 80, 7, 40, 1, 0 },
+ { 0, 0, 32, 7, 87, 9, 0 },
+ { 0, 5, 76, 7, 46, 1, 0 },
+ { 0, 0, 27, 7, 89, 12, 0 },
+ { 0, 4, 70, 7, 52, 2, 0 },
+ { 0, 0, 22, 7, 91, 15, 0 },
+ { 0, 3, 65, 7, 58, 2, 0 } },
+ .odd = { { 0, 1, 36, 7, 83, 8, 0 },
+ { 0, 6, 80, 7, 41, 1, 0 },
+ { 0, 0, 30, 7, 88, 10, 0 },
+ { 0, 5, 75, 7, 47, 1, 0 },
+ { 0, 0, 25, 7, 90, 13, 0 },
+ { 0, 4, 68, 7, 54, 2, 0 },
+ { 0, 0, 21, 7, 91, 16, 0 },
+ { 0, 3, 63, 7, 60, 2, 0 },
+ { 0, 17, 92, 7, 19, 0, 0 },
+ { 0, 2, 57, 7, 66, 3, 0 },
+ { 0, 14, 91, 7, 23, 0, 0 },
+ { 0, 1, 51, 7, 72, 4, 0 },
+ { 0, 11, 89, 7, 28, 0, 0 },
+ { 0, 1, 44, 7, 78, 5, 0 },
+ { 0, 9, 85, 7, 33, 1, 0 },
+ { 0, 1, 38, 7, 82, 7, 0 },
+ { 0, 7, 82, 7, 38, 1, 0 },
+ { 0, 1, 33, 7, 85, 9, 0 },
+ { 0, 5, 78, 7, 44, 1, 0 },
+ { 0, 0, 28, 7, 89, 11, 0 },
+ { 0, 4, 72, 7, 51, 1, 0 },
+ { 0, 0, 23, 7, 91, 14, 0 },
+ { 0, 3, 66, 7, 57, 2, 0 },
+ { 0, 0, 19, 7, 92, 17, 0 },
+ { 0, 2, 60, 7, 63, 3, 0 },
+ { 0, 16, 91, 7, 21, 0, 0 },
+ { 0, 2, 54, 7, 68, 4, 0 },
+ { 0, 13, 90, 7, 25, 0, 0 },
+ { 0, 1, 47, 7, 75, 5, 0 },
+ { 0, 10, 88, 7, 30, 0, 0 },
+ { 0, 1, 41, 7, 80, 6, 0 },
+ { 0, 8, 83, 7, 36, 1, 0 } } },
+ .ptrn_arr = { { 0xc9324c93, 0x92649924, 0x24c92649, 0x49324c93,
+ 0x92649926 } },
+ .sample_patrn_length = 162,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 50) = 0.390244 */
+ .hor_phase_arr = {
+ .even = { { 0, 19, 90, 7, 19, 0, 0 },
+ { 0, 2, 55, 7, 67, 4, 0 },
+ { 0, 12, 89, 7, 27, 0, 0 },
+ { 0, 1, 43, 7, 78, 6, 0 },
+ { 0, 8, 82, 7, 37, 1, 0 },
+ { 0, 1, 32, 7, 85, 10, 0 },
+ { 0, 5, 73, 7, 49, 1, 0 },
+ { 0, 0, 23, 7, 90, 15, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 15, 90, 7, 23, 0, 0 },
+ { 0, 1, 49, 7, 73, 5, 0 },
+ { 0, 10, 85, 7, 32, 1, 0 },
+ { 0, 1, 37, 7, 82, 8, 0 },
+ { 0, 6, 78, 7, 43, 1, 0 },
+ { 0, 0, 27, 7, 89, 12, 0 },
+ { 0, 4, 67, 7, 55, 2, 0 } },
+ .odd = { { 0, 1, 35, 7, 83, 9, 0 },
+ { 0, 5, 76, 7, 46, 1, 0 },
+ { 0, 0, 25, 7, 89, 14, 0 },
+ { 0, 3, 65, 7, 58, 2, 0 },
+ { 0, 17, 90, 7, 21, 0, 0 },
+ { 0, 2, 52, 7, 70, 4, 0 },
+ { 0, 11, 88, 7, 29, 0, 0 },
+ { 0, 1, 40, 7, 80, 7, 0 },
+ { 0, 7, 80, 7, 40, 1, 0 },
+ { 0, 0, 29, 7, 88, 11, 0 },
+ { 0, 4, 70, 7, 52, 2, 0 },
+ { 0, 0, 21, 7, 90, 17, 0 },
+ { 0, 2, 58, 7, 65, 3, 0 },
+ { 0, 14, 89, 7, 25, 0, 0 },
+ { 0, 1, 46, 7, 76, 5, 0 },
+ { 0, 9, 83, 7, 35, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 19, 90, 7, 19, 0, 0 },
+ { 0, 2, 55, 7, 67, 4, 0 },
+ { 0, 12, 89, 7, 27, 0, 0 },
+ { 0, 1, 43, 7, 78, 6, 0 },
+ { 0, 8, 82, 7, 37, 1, 0 },
+ { 0, 1, 32, 7, 85, 10, 0 },
+ { 0, 5, 73, 7, 49, 1, 0 },
+ { 0, 0, 23, 7, 90, 15, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 15, 90, 7, 23, 0, 0 },
+ { 0, 1, 49, 7, 73, 5, 0 },
+ { 0, 10, 85, 7, 32, 1, 0 },
+ { 0, 1, 37, 7, 82, 8, 0 },
+ { 0, 6, 78, 7, 43, 1, 0 },
+ { 0, 0, 27, 7, 89, 12, 0 },
+ { 0, 4, 67, 7, 55, 2, 0 } },
+ .odd = { { 0, 1, 35, 7, 83, 9, 0 },
+ { 0, 5, 76, 7, 46, 1, 0 },
+ { 0, 0, 25, 7, 89, 14, 0 },
+ { 0, 3, 65, 7, 58, 2, 0 },
+ { 0, 17, 90, 7, 21, 0, 0 },
+ { 0, 2, 52, 7, 70, 4, 0 },
+ { 0, 11, 88, 7, 29, 0, 0 },
+ { 0, 1, 40, 7, 80, 7, 0 },
+ { 0, 7, 80, 7, 40, 1, 0 },
+ { 0, 0, 29, 7, 88, 11, 0 },
+ { 0, 4, 70, 7, 52, 2, 0 },
+ { 0, 0, 21, 7, 90, 17, 0 },
+ { 0, 2, 58, 7, 65, 3, 0 },
+ { 0, 14, 89, 7, 25, 0, 0 },
+ { 0, 1, 46, 7, 76, 5, 0 },
+ { 0, 9, 83, 7, 35, 1, 0 } } },
+ .ptrn_arr = { { 0x49924c93, 0x9324c926, 0x9264 } },
+ .sample_patrn_length = 82,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 51) = 0.385542 */
+ .hor_phase_arr = {
+ .even = { { 0, 19, 90, 7, 19, 0, 0 },
+ { 0, 2, 52, 7, 70, 4, 0 },
+ { 0, 10, 85, 7, 32, 1, 0 },
+ { 0, 1, 35, 7, 83, 9, 0 },
+ { 0, 5, 72, 7, 49, 2, 0 },
+ { 0, 0, 21, 7, 90, 17, 0 },
+ { 0, 2, 55, 7, 67, 4, 0 },
+ { 0, 11, 87, 7, 30, 0, 0 },
+ { 0, 1, 38, 7, 81, 8, 0 },
+ { 0, 6, 75, 7, 46, 1, 0 },
+ { 0, 0, 23, 7, 89, 16, 0 },
+ { 0, 2, 58, 7, 65, 3, 0 },
+ { 0, 13, 87, 7, 28, 0, 0 },
+ { 0, 1, 41, 7, 79, 7, 0 },
+ { 0, 6, 78, 7, 43, 1, 0 },
+ { 0, 0, 25, 7, 89, 14, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 14, 89, 7, 25, 0, 0 },
+ { 0, 1, 43, 7, 78, 6, 0 },
+ { 0, 7, 79, 7, 41, 1, 0 },
+ { 0, 0, 28, 7, 87, 13, 0 },
+ { 0, 3, 65, 7, 58, 2, 0 },
+ { 0, 16, 89, 7, 23, 0, 0 },
+ { 0, 1, 46, 7, 75, 6, 0 },
+ { 0, 8, 81, 7, 38, 1, 0 },
+ { 0, 0, 30, 7, 87, 11, 0 },
+ { 0, 4, 67, 7, 55, 2, 0 },
+ { 0, 17, 90, 7, 21, 0, 0 },
+ { 0, 2, 49, 7, 72, 5, 0 },
+ { 0, 9, 83, 7, 35, 1, 0 },
+ { 0, 1, 32, 7, 85, 10, 0 },
+ { 0, 4, 70, 7, 52, 2, 0 } },
+ .odd = { { 0, 1, 34, 7, 83, 10, 0 },
+ { 0, 5, 70, 7, 51, 2, 0 },
+ { 0, 0, 20, 7, 90, 18, 0 },
+ { 0, 2, 54, 7, 68, 4, 0 },
+ { 0, 11, 85, 7, 31, 1, 0 },
+ { 0, 1, 36, 7, 82, 9, 0 },
+ { 0, 5, 74, 7, 48, 1, 0 },
+ { 0, 0, 22, 7, 89, 17, 0 },
+ { 0, 2, 57, 7, 65, 4, 0 },
+ { 0, 12, 87, 7, 29, 0, 0 },
+ { 0, 1, 39, 7, 80, 8, 0 },
+ { 0, 6, 76, 7, 45, 1, 0 },
+ { 0, 0, 24, 7, 89, 15, 0 },
+ { 0, 3, 60, 7, 62, 3, 0 },
+ { 0, 13, 89, 7, 26, 0, 0 },
+ { 0, 1, 42, 7, 78, 7, 0 },
+ { 0, 7, 78, 7, 42, 1, 0 },
+ { 0, 0, 26, 7, 89, 13, 0 },
+ { 0, 3, 62, 7, 60, 3, 0 },
+ { 0, 15, 89, 7, 24, 0, 0 },
+ { 0, 1, 45, 7, 76, 6, 0 },
+ { 0, 8, 80, 7, 39, 1, 0 },
+ { 0, 0, 29, 7, 87, 12, 0 },
+ { 0, 4, 65, 7, 57, 2, 0 },
+ { 0, 17, 89, 7, 22, 0, 0 },
+ { 0, 1, 48, 7, 74, 5, 0 },
+ { 0, 9, 82, 7, 36, 1, 0 },
+ { 0, 1, 31, 7, 85, 11, 0 },
+ { 0, 4, 68, 7, 54, 2, 0 },
+ { 0, 18, 90, 7, 20, 0, 0 },
+ { 0, 2, 51, 7, 70, 5, 0 },
+ { 0, 10, 83, 7, 34, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 19, 90, 7, 19, 0, 0 },
+ { 0, 2, 52, 7, 70, 4, 0 },
+ { 0, 10, 85, 7, 32, 1, 0 },
+ { 0, 1, 35, 7, 83, 9, 0 },
+ { 0, 5, 72, 7, 49, 2, 0 },
+ { 0, 0, 21, 7, 90, 17, 0 },
+ { 0, 2, 55, 7, 67, 4, 0 },
+ { 0, 11, 87, 7, 30, 0, 0 },
+ { 0, 1, 38, 7, 81, 8, 0 },
+ { 0, 6, 75, 7, 46, 1, 0 },
+ { 0, 0, 23, 7, 89, 16, 0 },
+ { 0, 2, 58, 7, 65, 3, 0 },
+ { 0, 13, 87, 7, 28, 0, 0 },
+ { 0, 1, 41, 7, 79, 7, 0 },
+ { 0, 6, 78, 7, 43, 1, 0 },
+ { 0, 0, 25, 7, 89, 14, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 14, 89, 7, 25, 0, 0 },
+ { 0, 1, 43, 7, 78, 6, 0 },
+ { 0, 7, 79, 7, 41, 1, 0 },
+ { 0, 0, 28, 7, 87, 13, 0 },
+ { 0, 3, 65, 7, 58, 2, 0 },
+ { 0, 16, 89, 7, 23, 0, 0 },
+ { 0, 1, 46, 7, 75, 6, 0 },
+ { 0, 8, 81, 7, 38, 1, 0 },
+ { 0, 0, 30, 7, 87, 11, 0 },
+ { 0, 4, 67, 7, 55, 2, 0 },
+ { 0, 17, 90, 7, 21, 0, 0 },
+ { 0, 2, 49, 7, 72, 5, 0 },
+ { 0, 9, 83, 7, 35, 1, 0 },
+ { 0, 1, 32, 7, 85, 10, 0 },
+ { 0, 4, 70, 7, 52, 2, 0 } },
+ .odd = { { 0, 1, 34, 7, 83, 10, 0 },
+ { 0, 5, 70, 7, 51, 2, 0 },
+ { 0, 0, 20, 7, 90, 18, 0 },
+ { 0, 2, 54, 7, 68, 4, 0 },
+ { 0, 11, 85, 7, 31, 1, 0 },
+ { 0, 1, 36, 7, 82, 9, 0 },
+ { 0, 5, 74, 7, 48, 1, 0 },
+ { 0, 0, 22, 7, 89, 17, 0 },
+ { 0, 2, 57, 7, 65, 4, 0 },
+ { 0, 12, 87, 7, 29, 0, 0 },
+ { 0, 1, 39, 7, 80, 8, 0 },
+ { 0, 6, 76, 7, 45, 1, 0 },
+ { 0, 0, 24, 7, 89, 15, 0 },
+ { 0, 3, 60, 7, 62, 3, 0 },
+ { 0, 13, 89, 7, 26, 0, 0 },
+ { 0, 1, 42, 7, 78, 7, 0 },
+ { 0, 7, 78, 7, 42, 1, 0 },
+ { 0, 0, 26, 7, 89, 13, 0 },
+ { 0, 3, 62, 7, 60, 3, 0 },
+ { 0, 15, 89, 7, 24, 0, 0 },
+ { 0, 1, 45, 7, 76, 6, 0 },
+ { 0, 8, 80, 7, 39, 1, 0 },
+ { 0, 0, 29, 7, 87, 12, 0 },
+ { 0, 4, 65, 7, 57, 2, 0 },
+ { 0, 17, 89, 7, 22, 0, 0 },
+ { 0, 1, 48, 7, 74, 5, 0 },
+ { 0, 9, 82, 7, 36, 1, 0 },
+ { 0, 1, 31, 7, 85, 11, 0 },
+ { 0, 4, 68, 7, 54, 2, 0 },
+ { 0, 18, 90, 7, 20, 0, 0 },
+ { 0, 2, 51, 7, 70, 5, 0 },
+ { 0, 10, 83, 7, 34, 1, 0 } } },
+ .ptrn_arr = { { 0x49924c93, 0xc9264932, 0x93249924, 0x924c9264,
+ 0x26493249, 0x9 } },
+ .sample_patrn_length = 166,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 52) = 0.380952 */
+ .hor_phase_arr = {
+ .even = { { 0, 20, 88, 7, 20, 0, 0 },
+ { 0, 2, 49, 7, 72, 5, 0 },
+ { 0, 8, 81, 7, 38, 1, 0 },
+ { 0, 0, 28, 7, 87, 13, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 13, 87, 7, 28, 0, 0 },
+ { 0, 1, 38, 7, 81, 8, 0 },
+ { 0, 5, 72, 7, 49, 2, 0 } },
+ .odd = { { 0, 1, 33, 7, 83, 11, 0 },
+ { 0, 4, 67, 7, 55, 2, 0 },
+ { 0, 16, 88, 7, 24, 0, 0 },
+ { 0, 1, 44, 7, 76, 7, 0 },
+ { 0, 7, 76, 7, 44, 1, 0 },
+ { 0, 0, 24, 7, 88, 16, 0 },
+ { 0, 2, 55, 7, 67, 4, 0 },
+ { 0, 11, 83, 7, 33, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 20, 88, 7, 20, 0, 0 },
+ { 0, 2, 49, 7, 72, 5, 0 },
+ { 0, 8, 81, 7, 38, 1, 0 },
+ { 0, 0, 28, 7, 87, 13, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 13, 87, 7, 28, 0, 0 },
+ { 0, 1, 38, 7, 81, 8, 0 },
+ { 0, 5, 72, 7, 49, 2, 0 } },
+ .odd = { { 0, 1, 33, 7, 83, 11, 0 },
+ { 0, 4, 67, 7, 55, 2, 0 },
+ { 0, 16, 88, 7, 24, 0, 0 },
+ { 0, 1, 44, 7, 76, 7, 0 },
+ { 0, 7, 76, 7, 44, 1, 0 },
+ { 0, 0, 24, 7, 88, 16, 0 },
+ { 0, 2, 55, 7, 67, 4, 0 },
+ { 0, 11, 83, 7, 33, 1, 0 } } },
+ .ptrn_arr = { { 0x4c926493, 0x92 } },
+ .sample_patrn_length = 42,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 53) = 0.376471 */
+ .hor_phase_arr = {
+ .even = { { 0, 20, 88, 7, 20, 0, 0 },
+ { 0, 2, 47, 7, 73, 6, 0 },
+ { 0, 7, 76, 7, 44, 1, 0 },
+ { 0, 0, 22, 7, 88, 18, 0 },
+ { 0, 2, 49, 7, 72, 5, 0 },
+ { 0, 8, 78, 7, 41, 1, 0 },
+ { 0, 0, 24, 7, 87, 17, 0 },
+ { 0, 2, 52, 7, 69, 5, 0 },
+ { 0, 9, 80, 7, 38, 1, 0 },
+ { 0, 0, 26, 7, 87, 15, 0 },
+ { 0, 2, 55, 7, 67, 4, 0 },
+ { 0, 10, 81, 7, 36, 1, 0 },
+ { 0, 1, 28, 7, 85, 14, 0 },
+ { 0, 3, 58, 7, 63, 4, 0 },
+ { 0, 11, 83, 7, 33, 1, 0 },
+ { 0, 1, 31, 7, 84, 12, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 12, 84, 7, 31, 1, 0 },
+ { 0, 1, 33, 7, 83, 11, 0 },
+ { 0, 4, 63, 7, 58, 3, 0 },
+ { 0, 14, 85, 7, 28, 1, 0 },
+ { 0, 1, 36, 7, 81, 10, 0 },
+ { 0, 4, 67, 7, 55, 2, 0 },
+ { 0, 15, 87, 7, 26, 0, 0 },
+ { 0, 1, 38, 7, 80, 9, 0 },
+ { 0, 5, 69, 7, 52, 2, 0 },
+ { 0, 17, 87, 7, 24, 0, 0 },
+ { 0, 1, 41, 7, 78, 8, 0 },
+ { 0, 5, 72, 7, 49, 2, 0 },
+ { 0, 18, 88, 7, 22, 0, 0 },
+ { 0, 1, 44, 7, 76, 7, 0 },
+ { 0, 6, 73, 7, 47, 2, 0 } },
+ .odd = { { 0, 1, 32, 7, 83, 12, 0 },
+ { 0, 3, 63, 7, 59, 3, 0 },
+ { 0, 13, 84, 7, 30, 1, 0 },
+ { 0, 1, 34, 7, 83, 10, 0 },
+ { 0, 4, 64, 7, 57, 3, 0 },
+ { 0, 14, 87, 7, 27, 0, 0 },
+ { 0, 1, 37, 7, 81, 9, 0 },
+ { 0, 5, 67, 7, 54, 2, 0 },
+ { 0, 16, 87, 7, 25, 0, 0 },
+ { 0, 1, 40, 7, 79, 8, 0 },
+ { 0, 5, 70, 7, 51, 2, 0 },
+ { 0, 18, 87, 7, 23, 0, 0 },
+ { 0, 1, 42, 7, 78, 7, 0 },
+ { 0, 6, 72, 7, 48, 2, 0 },
+ { 0, 19, 88, 7, 21, 0, 0 },
+ { 0, 1, 45, 7, 75, 7, 0 },
+ { 0, 7, 75, 7, 45, 1, 0 },
+ { 0, 0, 21, 7, 88, 19, 0 },
+ { 0, 2, 48, 7, 72, 6, 0 },
+ { 0, 7, 78, 7, 42, 1, 0 },
+ { 0, 0, 23, 7, 87, 18, 0 },
+ { 0, 2, 51, 7, 70, 5, 0 },
+ { 0, 8, 79, 7, 40, 1, 0 },
+ { 0, 0, 25, 7, 87, 16, 0 },
+ { 0, 2, 54, 7, 67, 5, 0 },
+ { 0, 9, 81, 7, 37, 1, 0 },
+ { 0, 0, 27, 7, 87, 14, 0 },
+ { 0, 3, 57, 7, 64, 4, 0 },
+ { 0, 10, 83, 7, 34, 1, 0 },
+ { 0, 1, 30, 7, 84, 13, 0 },
+ { 0, 3, 59, 7, 63, 3, 0 },
+ { 0, 12, 83, 7, 32, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 20, 88, 7, 20, 0, 0 },
+ { 0, 2, 47, 7, 73, 6, 0 },
+ { 0, 7, 76, 7, 44, 1, 0 },
+ { 0, 0, 22, 7, 88, 18, 0 },
+ { 0, 2, 49, 7, 72, 5, 0 },
+ { 0, 8, 78, 7, 41, 1, 0 },
+ { 0, 0, 24, 7, 87, 17, 0 },
+ { 0, 2, 52, 7, 69, 5, 0 },
+ { 0, 9, 80, 7, 38, 1, 0 },
+ { 0, 0, 26, 7, 87, 15, 0 },
+ { 0, 2, 55, 7, 67, 4, 0 },
+ { 0, 10, 81, 7, 36, 1, 0 },
+ { 0, 1, 28, 7, 85, 14, 0 },
+ { 0, 3, 58, 7, 63, 4, 0 },
+ { 0, 11, 83, 7, 33, 1, 0 },
+ { 0, 1, 31, 7, 84, 12, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 12, 84, 7, 31, 1, 0 },
+ { 0, 1, 33, 7, 83, 11, 0 },
+ { 0, 4, 63, 7, 58, 3, 0 },
+ { 0, 14, 85, 7, 28, 1, 0 },
+ { 0, 1, 36, 7, 81, 10, 0 },
+ { 0, 4, 67, 7, 55, 2, 0 },
+ { 0, 15, 87, 7, 26, 0, 0 },
+ { 0, 1, 38, 7, 80, 9, 0 },
+ { 0, 5, 69, 7, 52, 2, 0 },
+ { 0, 17, 87, 7, 24, 0, 0 },
+ { 0, 1, 41, 7, 78, 8, 0 },
+ { 0, 5, 72, 7, 49, 2, 0 },
+ { 0, 18, 88, 7, 22, 0, 0 },
+ { 0, 1, 44, 7, 76, 7, 0 },
+ { 0, 6, 73, 7, 47, 2, 0 } },
+ .odd = { { 0, 1, 32, 7, 83, 12, 0 },
+ { 0, 3, 63, 7, 59, 3, 0 },
+ { 0, 13, 84, 7, 30, 1, 0 },
+ { 0, 1, 34, 7, 83, 10, 0 },
+ { 0, 4, 64, 7, 57, 3, 0 },
+ { 0, 14, 87, 7, 27, 0, 0 },
+ { 0, 1, 37, 7, 81, 9, 0 },
+ { 0, 5, 67, 7, 54, 2, 0 },
+ { 0, 16, 87, 7, 25, 0, 0 },
+ { 0, 1, 40, 7, 79, 8, 0 },
+ { 0, 5, 70, 7, 51, 2, 0 },
+ { 0, 18, 87, 7, 23, 0, 0 },
+ { 0, 1, 42, 7, 78, 7, 0 },
+ { 0, 6, 72, 7, 48, 2, 0 },
+ { 0, 19, 88, 7, 21, 0, 0 },
+ { 0, 1, 45, 7, 75, 7, 0 },
+ { 0, 7, 75, 7, 45, 1, 0 },
+ { 0, 0, 21, 7, 88, 19, 0 },
+ { 0, 2, 48, 7, 72, 6, 0 },
+ { 0, 7, 78, 7, 42, 1, 0 },
+ { 0, 0, 23, 7, 87, 18, 0 },
+ { 0, 2, 51, 7, 70, 5, 0 },
+ { 0, 8, 79, 7, 40, 1, 0 },
+ { 0, 0, 25, 7, 87, 16, 0 },
+ { 0, 2, 54, 7, 67, 5, 0 },
+ { 0, 9, 81, 7, 37, 1, 0 },
+ { 0, 0, 27, 7, 87, 14, 0 },
+ { 0, 3, 57, 7, 64, 4, 0 },
+ { 0, 10, 83, 7, 34, 1, 0 },
+ { 0, 1, 30, 7, 84, 13, 0 },
+ { 0, 3, 59, 7, 63, 3, 0 },
+ { 0, 12, 83, 7, 32, 1, 0 } } },
+ .ptrn_arr = { { 0x64926493, 0x64926492, 0x4c926492, 0x4c924c92,
+ 0x4c924c92, 0x92 } },
+ .sample_patrn_length = 170,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 54) = 0.372093 */
+ .hor_phase_arr = {
+ .even = { { 0, 21, 86, 7, 21, 0, 0 },
+ { 0, 1, 44, 7, 76, 7, 0 },
+ { 0, 6, 71, 7, 49, 2, 0 },
+ { 0, 17, 86, 7, 25, 0, 0 },
+ { 0, 1, 39, 7, 79, 9, 0 },
+ { 0, 5, 65, 7, 55, 3, 0 },
+ { 0, 14, 84, 7, 29, 1, 0 },
+ { 0, 1, 34, 7, 82, 11, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 11, 82, 7, 34, 1, 0 },
+ { 0, 1, 29, 7, 84, 14, 0 },
+ { 0, 3, 55, 7, 65, 5, 0 },
+ { 0, 9, 79, 7, 39, 1, 0 },
+ { 0, 0, 25, 7, 86, 17, 0 },
+ { 0, 2, 49, 7, 71, 6, 0 },
+ { 0, 7, 76, 7, 44, 1, 0 } },
+ .odd = { { 0, 1, 31, 7, 83, 13, 0 },
+ { 0, 3, 58, 7, 63, 4, 0 },
+ { 0, 10, 81, 7, 36, 1, 0 },
+ { 0, 0, 27, 7, 85, 16, 0 },
+ { 0, 2, 52, 7, 69, 5, 0 },
+ { 0, 8, 78, 7, 41, 1, 0 },
+ { 0, 0, 23, 7, 86, 19, 0 },
+ { 0, 2, 47, 7, 72, 7, 0 },
+ { 0, 7, 72, 7, 47, 2, 0 },
+ { 0, 19, 86, 7, 23, 0, 0 },
+ { 0, 1, 41, 7, 78, 8, 0 },
+ { 0, 5, 69, 7, 52, 2, 0 },
+ { 0, 16, 85, 7, 27, 0, 0 },
+ { 0, 1, 36, 7, 81, 10, 0 },
+ { 0, 4, 63, 7, 58, 3, 0 },
+ { 0, 13, 83, 7, 31, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 21, 86, 7, 21, 0, 0 },
+ { 0, 1, 44, 7, 76, 7, 0 },
+ { 0, 6, 71, 7, 49, 2, 0 },
+ { 0, 17, 86, 7, 25, 0, 0 },
+ { 0, 1, 39, 7, 79, 9, 0 },
+ { 0, 5, 65, 7, 55, 3, 0 },
+ { 0, 14, 84, 7, 29, 1, 0 },
+ { 0, 1, 34, 7, 82, 11, 0 },
+ { 0, 3, 61, 7, 61, 3, 0 },
+ { 0, 11, 82, 7, 34, 1, 0 },
+ { 0, 1, 29, 7, 84, 14, 0 },
+ { 0, 3, 55, 7, 65, 5, 0 },
+ { 0, 9, 79, 7, 39, 1, 0 },
+ { 0, 0, 25, 7, 86, 17, 0 },
+ { 0, 2, 49, 7, 71, 6, 0 },
+ { 0, 7, 76, 7, 44, 1, 0 } },
+ .odd = { { 0, 1, 31, 7, 83, 13, 0 },
+ { 0, 3, 58, 7, 63, 4, 0 },
+ { 0, 10, 81, 7, 36, 1, 0 },
+ { 0, 0, 27, 7, 85, 16, 0 },
+ { 0, 2, 52, 7, 69, 5, 0 },
+ { 0, 8, 78, 7, 41, 1, 0 },
+ { 0, 0, 23, 7, 86, 19, 0 },
+ { 0, 2, 47, 7, 72, 7, 0 },
+ { 0, 7, 72, 7, 47, 2, 0 },
+ { 0, 19, 86, 7, 23, 0, 0 },
+ { 0, 1, 41, 7, 78, 8, 0 },
+ { 0, 5, 69, 7, 52, 2, 0 },
+ { 0, 16, 85, 7, 27, 0, 0 },
+ { 0, 1, 36, 7, 81, 10, 0 },
+ { 0, 4, 63, 7, 58, 3, 0 },
+ { 0, 13, 83, 7, 31, 1, 0 } } },
+ .ptrn_arr = { { 0x24932493, 0x24992493, 0x92499 } },
+ .sample_patrn_length = 86,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 55) = 0.367816 */
+ .hor_phase_arr = {
+ .even = { { 0, 21, 86, 7, 21, 0, 0 },
+ { 0, 1, 41, 7, 77, 9, 0 },
+ { 0, 5, 65, 7, 55, 3, 0 },
+ { 0, 13, 82, 7, 32, 1, 0 },
+ { 0, 1, 29, 7, 83, 15, 0 },
+ { 0, 2, 52, 7, 69, 5, 0 },
+ { 0, 8, 74, 7, 44, 2, 0 },
+ { 0, 19, 86, 7, 23, 0, 0 },
+ { 0, 1, 39, 7, 78, 10, 0 },
+ { 0, 4, 63, 7, 58, 3, 0 },
+ { 0, 12, 81, 7, 34, 1, 0 },
+ { 0, 1, 27, 7, 84, 16, 0 },
+ { 0, 2, 50, 7, 70, 6, 0 },
+ { 0, 7, 72, 7, 47, 2, 0 },
+ { 0, 18, 85, 7, 25, 0, 0 },
+ { 0, 1, 36, 7, 80, 11, 0 },
+ { 0, 4, 60, 7, 60, 4, 0 },
+ { 0, 11, 80, 7, 36, 1, 0 },
+ { 0, 0, 25, 7, 85, 18, 0 },
+ { 0, 2, 47, 7, 72, 7, 0 },
+ { 0, 6, 70, 7, 50, 2, 0 },
+ { 0, 16, 84, 7, 27, 1, 0 },
+ { 0, 1, 34, 7, 81, 12, 0 },
+ { 0, 3, 58, 7, 63, 4, 0 },
+ { 0, 10, 78, 7, 39, 1, 0 },
+ { 0, 0, 23, 7, 86, 19, 0 },
+ { 0, 2, 44, 7, 74, 8, 0 },
+ { 0, 5, 69, 7, 52, 2, 0 },
+ { 0, 15, 83, 7, 29, 1, 0 },
+ { 0, 1, 32, 7, 82, 13, 0 },
+ { 0, 3, 55, 7, 65, 5, 0 },
+ { 0, 9, 77, 7, 41, 1, 0 } },
+ .odd = { { 0, 1, 30, 7, 83, 14, 0 },
+ { 0, 3, 54, 7, 66, 5, 0 },
+ { 0, 8, 76, 7, 43, 1, 0 },
+ { 0, 20, 86, 7, 22, 0, 0 },
+ { 0, 1, 40, 7, 78, 9, 0 },
+ { 0, 4, 65, 7, 56, 3, 0 },
+ { 0, 13, 81, 7, 33, 1, 0 },
+ { 0, 1, 28, 7, 84, 15, 0 },
+ { 0, 2, 51, 7, 69, 6, 0 },
+ { 0, 7, 74, 7, 45, 2, 0 },
+ { 0, 18, 86, 7, 24, 0, 0 },
+ { 0, 1, 38, 7, 79, 10, 0 },
+ { 0, 4, 62, 7, 59, 3, 0 },
+ { 0, 11, 81, 7, 35, 1, 0 },
+ { 0, 0, 26, 7, 85, 17, 0 },
+ { 0, 2, 48, 7, 72, 6, 0 },
+ { 0, 6, 72, 7, 48, 2, 0 },
+ { 0, 17, 85, 7, 26, 0, 0 },
+ { 0, 1, 35, 7, 81, 11, 0 },
+ { 0, 3, 59, 7, 62, 4, 0 },
+ { 0, 10, 79, 7, 38, 1, 0 },
+ { 0, 0, 24, 7, 86, 18, 0 },
+ { 0, 2, 45, 7, 74, 7, 0 },
+ { 0, 6, 69, 7, 51, 2, 0 },
+ { 0, 15, 84, 7, 28, 1, 0 },
+ { 0, 1, 33, 7, 81, 13, 0 },
+ { 0, 3, 56, 7, 65, 4, 0 },
+ { 0, 9, 78, 7, 40, 1, 0 },
+ { 0, 0, 22, 7, 86, 20, 0 },
+ { 0, 1, 43, 7, 76, 8, 0 },
+ { 0, 5, 66, 7, 54, 3, 0 },
+ { 0, 14, 83, 7, 30, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 21, 86, 7, 21, 0, 0 },
+ { 0, 1, 41, 7, 77, 9, 0 },
+ { 0, 5, 65, 7, 55, 3, 0 },
+ { 0, 13, 82, 7, 32, 1, 0 },
+ { 0, 1, 29, 7, 83, 15, 0 },
+ { 0, 2, 52, 7, 69, 5, 0 },
+ { 0, 8, 74, 7, 44, 2, 0 },
+ { 0, 19, 86, 7, 23, 0, 0 },
+ { 0, 1, 39, 7, 78, 10, 0 },
+ { 0, 4, 63, 7, 58, 3, 0 },
+ { 0, 12, 81, 7, 34, 1, 0 },
+ { 0, 1, 27, 7, 84, 16, 0 },
+ { 0, 2, 50, 7, 70, 6, 0 },
+ { 0, 7, 72, 7, 47, 2, 0 },
+ { 0, 18, 85, 7, 25, 0, 0 },
+ { 0, 1, 36, 7, 80, 11, 0 },
+ { 0, 4, 60, 7, 60, 4, 0 },
+ { 0, 11, 80, 7, 36, 1, 0 },
+ { 0, 0, 25, 7, 85, 18, 0 },
+ { 0, 2, 47, 7, 72, 7, 0 },
+ { 0, 6, 70, 7, 50, 2, 0 },
+ { 0, 16, 84, 7, 27, 1, 0 },
+ { 0, 1, 34, 7, 81, 12, 0 },
+ { 0, 3, 58, 7, 63, 4, 0 },
+ { 0, 10, 78, 7, 39, 1, 0 },
+ { 0, 0, 23, 7, 86, 19, 0 },
+ { 0, 2, 44, 7, 74, 8, 0 },
+ { 0, 5, 69, 7, 52, 2, 0 },
+ { 0, 15, 83, 7, 29, 1, 0 },
+ { 0, 1, 32, 7, 82, 13, 0 },
+ { 0, 3, 55, 7, 65, 5, 0 },
+ { 0, 9, 77, 7, 41, 1, 0 } },
+ .odd = { { 0, 1, 30, 7, 83, 14, 0 },
+ { 0, 3, 54, 7, 66, 5, 0 },
+ { 0, 8, 76, 7, 43, 1, 0 },
+ { 0, 20, 86, 7, 22, 0, 0 },
+ { 0, 1, 40, 7, 78, 9, 0 },
+ { 0, 4, 65, 7, 56, 3, 0 },
+ { 0, 13, 81, 7, 33, 1, 0 },
+ { 0, 1, 28, 7, 84, 15, 0 },
+ { 0, 2, 51, 7, 69, 6, 0 },
+ { 0, 7, 74, 7, 45, 2, 0 },
+ { 0, 18, 86, 7, 24, 0, 0 },
+ { 0, 1, 38, 7, 79, 10, 0 },
+ { 0, 4, 62, 7, 59, 3, 0 },
+ { 0, 11, 81, 7, 35, 1, 0 },
+ { 0, 0, 26, 7, 85, 17, 0 },
+ { 0, 2, 48, 7, 72, 6, 0 },
+ { 0, 6, 72, 7, 48, 2, 0 },
+ { 0, 17, 85, 7, 26, 0, 0 },
+ { 0, 1, 35, 7, 81, 11, 0 },
+ { 0, 3, 59, 7, 62, 4, 0 },
+ { 0, 10, 79, 7, 38, 1, 0 },
+ { 0, 0, 24, 7, 86, 18, 0 },
+ { 0, 2, 45, 7, 74, 7, 0 },
+ { 0, 6, 69, 7, 51, 2, 0 },
+ { 0, 15, 84, 7, 28, 1, 0 },
+ { 0, 1, 33, 7, 81, 13, 0 },
+ { 0, 3, 56, 7, 65, 4, 0 },
+ { 0, 9, 78, 7, 40, 1, 0 },
+ { 0, 0, 22, 7, 86, 20, 0 },
+ { 0, 1, 43, 7, 76, 8, 0 },
+ { 0, 5, 66, 7, 54, 3, 0 },
+ { 0, 14, 83, 7, 30, 1, 0 } } },
+ .ptrn_arr = { { 0x24992493, 0x264924c9, 0x92493249, 0x924c9249,
+ 0x93249264, 0x924 } },
+ .sample_patrn_length = 174,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 56) = 0.363636 */
+ .hor_phase_arr = {
+ .even = { { 0, 22, 84, 7, 22, 0, 0 },
+ { 0, 1, 39, 7, 78, 10, 0 },
+ { 0, 4, 60, 7, 60, 4, 0 },
+ { 0, 10, 78, 7, 39, 1, 0 } },
+ .odd = { { 0, 1, 30, 7, 82, 15, 0 },
+ { 0, 2, 50, 7, 70, 6, 0 },
+ { 0, 6, 70, 7, 50, 2, 0 },
+ { 0, 15, 82, 7, 30, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 22, 84, 7, 22, 0, 0 },
+ { 0, 1, 39, 7, 78, 10, 0 },
+ { 0, 4, 60, 7, 60, 4, 0 },
+ { 0, 10, 78, 7, 39, 1, 0 } },
+ .odd = { { 0, 1, 30, 7, 82, 15, 0 },
+ { 0, 2, 50, 7, 70, 6, 0 },
+ { 0, 6, 70, 7, 50, 2, 0 },
+ { 0, 15, 82, 7, 30, 1, 0 } } },
+ .ptrn_arr = { { 0x92493 } },
+ .sample_patrn_length = 22,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 57) = 0.359551 */
+ .hor_phase_arr = {
+ .even = { { 0, 22, 84, 7, 22, 0, 0 },
+ { 0, 1, 37, 7, 79, 11, 0 },
+ { 0, 3, 55, 7, 65, 5, 0 },
+ { 0, 7, 72, 7, 47, 2, 0 },
+ { 0, 15, 82, 7, 30, 1, 0 },
+ { 0, 1, 28, 7, 82, 17, 0 },
+ { 0, 2, 44, 7, 74, 8, 0 },
+ { 0, 5, 62, 7, 57, 4, 0 },
+ { 0, 10, 78, 7, 39, 1, 0 },
+ { 0, 20, 84, 7, 24, 0, 0 },
+ { 0, 1, 35, 7, 79, 13, 0 },
+ { 0, 3, 52, 7, 67, 6, 0 },
+ { 0, 7, 69, 7, 50, 2, 0 },
+ { 0, 14, 81, 7, 32, 1, 0 },
+ { 0, 1, 26, 7, 83, 18, 0 },
+ { 0, 2, 42, 7, 75, 9, 0 },
+ { 0, 4, 60, 7, 60, 4, 0 },
+ { 0, 9, 75, 7, 42, 2, 0 },
+ { 0, 18, 83, 7, 26, 1, 0 },
+ { 0, 1, 32, 7, 81, 14, 0 },
+ { 0, 2, 50, 7, 69, 7, 0 },
+ { 0, 6, 67, 7, 52, 3, 0 },
+ { 0, 13, 79, 7, 35, 1, 0 },
+ { 0, 0, 24, 7, 84, 20, 0 },
+ { 0, 1, 39, 7, 78, 10, 0 },
+ { 0, 4, 57, 7, 62, 5, 0 },
+ { 0, 8, 74, 7, 44, 2, 0 },
+ { 0, 17, 82, 7, 28, 1, 0 },
+ { 0, 1, 30, 7, 82, 15, 0 },
+ { 0, 2, 47, 7, 72, 7, 0 },
+ { 0, 5, 65, 7, 55, 3, 0 },
+ { 0, 11, 79, 7, 37, 1, 0 } },
+ .odd = { { 0, 1, 29, 7, 82, 16, 0 },
+ { 0, 2, 46, 7, 72, 8, 0 },
+ { 0, 5, 64, 7, 56, 3, 0 },
+ { 0, 11, 78, 7, 38, 1, 0 },
+ { 0, 21, 84, 7, 23, 0, 0 },
+ { 0, 1, 36, 7, 79, 12, 0 },
+ { 0, 3, 53, 7, 66, 6, 0 },
+ { 0, 7, 71, 7, 48, 2, 0 },
+ { 0, 15, 81, 7, 31, 1, 0 },
+ { 0, 1, 27, 7, 82, 18, 0 },
+ { 0, 2, 43, 7, 74, 9, 0 },
+ { 0, 4, 61, 7, 59, 4, 0 },
+ { 0, 10, 75, 7, 41, 2, 0 },
+ { 0, 19, 83, 7, 25, 1, 0 },
+ { 0, 1, 33, 7, 81, 13, 0 },
+ { 0, 3, 51, 7, 68, 6, 0 },
+ { 0, 6, 68, 7, 51, 3, 0 },
+ { 0, 13, 81, 7, 33, 1, 0 },
+ { 0, 1, 25, 7, 83, 19, 0 },
+ { 0, 2, 41, 7, 75, 10, 0 },
+ { 0, 4, 59, 7, 61, 4, 0 },
+ { 0, 9, 74, 7, 43, 2, 0 },
+ { 0, 18, 82, 7, 27, 1, 0 },
+ { 0, 1, 31, 7, 81, 15, 0 },
+ { 0, 2, 48, 7, 71, 7, 0 },
+ { 0, 6, 66, 7, 53, 3, 0 },
+ { 0, 12, 79, 7, 36, 1, 0 },
+ { 0, 0, 23, 7, 84, 21, 0 },
+ { 0, 1, 38, 7, 78, 11, 0 },
+ { 0, 3, 56, 7, 64, 5, 0 },
+ { 0, 8, 72, 7, 46, 2, 0 },
+ { 0, 16, 82, 7, 29, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 22, 84, 7, 22, 0, 0 },
+ { 0, 1, 37, 7, 79, 11, 0 },
+ { 0, 3, 55, 7, 65, 5, 0 },
+ { 0, 7, 72, 7, 47, 2, 0 },
+ { 0, 15, 82, 7, 30, 1, 0 },
+ { 0, 1, 28, 7, 82, 17, 0 },
+ { 0, 2, 44, 7, 74, 8, 0 },
+ { 0, 5, 62, 7, 57, 4, 0 },
+ { 0, 10, 78, 7, 39, 1, 0 },
+ { 0, 20, 84, 7, 24, 0, 0 },
+ { 0, 1, 35, 7, 79, 13, 0 },
+ { 0, 3, 52, 7, 67, 6, 0 },
+ { 0, 7, 69, 7, 50, 2, 0 },
+ { 0, 14, 81, 7, 32, 1, 0 },
+ { 0, 1, 26, 7, 83, 18, 0 },
+ { 0, 2, 42, 7, 75, 9, 0 },
+ { 0, 4, 60, 7, 60, 4, 0 },
+ { 0, 9, 75, 7, 42, 2, 0 },
+ { 0, 18, 83, 7, 26, 1, 0 },
+ { 0, 1, 32, 7, 81, 14, 0 },
+ { 0, 2, 50, 7, 69, 7, 0 },
+ { 0, 6, 67, 7, 52, 3, 0 },
+ { 0, 13, 79, 7, 35, 1, 0 },
+ { 0, 0, 24, 7, 84, 20, 0 },
+ { 0, 1, 39, 7, 78, 10, 0 },
+ { 0, 4, 57, 7, 62, 5, 0 },
+ { 0, 8, 74, 7, 44, 2, 0 },
+ { 0, 17, 82, 7, 28, 1, 0 },
+ { 0, 1, 30, 7, 82, 15, 0 },
+ { 0, 2, 47, 7, 72, 7, 0 },
+ { 0, 5, 65, 7, 55, 3, 0 },
+ { 0, 11, 79, 7, 37, 1, 0 } },
+ .odd = { { 0, 1, 29, 7, 82, 16, 0 },
+ { 0, 2, 46, 7, 72, 8, 0 },
+ { 0, 5, 64, 7, 56, 3, 0 },
+ { 0, 11, 78, 7, 38, 1, 0 },
+ { 0, 21, 84, 7, 23, 0, 0 },
+ { 0, 1, 36, 7, 79, 12, 0 },
+ { 0, 3, 53, 7, 66, 6, 0 },
+ { 0, 7, 71, 7, 48, 2, 0 },
+ { 0, 15, 81, 7, 31, 1, 0 },
+ { 0, 1, 27, 7, 82, 18, 0 },
+ { 0, 2, 43, 7, 74, 9, 0 },
+ { 0, 4, 61, 7, 59, 4, 0 },
+ { 0, 10, 75, 7, 41, 2, 0 },
+ { 0, 19, 83, 7, 25, 1, 0 },
+ { 0, 1, 33, 7, 81, 13, 0 },
+ { 0, 3, 51, 7, 68, 6, 0 },
+ { 0, 6, 68, 7, 51, 3, 0 },
+ { 0, 13, 81, 7, 33, 1, 0 },
+ { 0, 1, 25, 7, 83, 19, 0 },
+ { 0, 2, 41, 7, 75, 10, 0 },
+ { 0, 4, 59, 7, 61, 4, 0 },
+ { 0, 9, 74, 7, 43, 2, 0 },
+ { 0, 18, 82, 7, 27, 1, 0 },
+ { 0, 1, 31, 7, 81, 15, 0 },
+ { 0, 2, 48, 7, 71, 7, 0 },
+ { 0, 6, 66, 7, 53, 3, 0 },
+ { 0, 12, 79, 7, 36, 1, 0 },
+ { 0, 0, 23, 7, 84, 21, 0 },
+ { 0, 1, 38, 7, 78, 11, 0 },
+ { 0, 3, 56, 7, 64, 5, 0 },
+ { 0, 8, 72, 7, 46, 2, 0 },
+ { 0, 16, 82, 7, 29, 1, 0 } } },
+ .ptrn_arr = { { 0x26492493, 0x924c9249, 0x49249924, 0x64924932,
+ 0x24c92492, 0x9249 } },
+ .sample_patrn_length = 178,
+ .hor_ds_en = 1,
+ .ver_ds_en = 1
+}, {
+ /* Scale factor 32 / (32 + 58) = 0.355556 */
+ .hor_phase_arr = {
+ .even = { { 0, 22, 84, 7, 22, 0, 0 },
+ { 0, 1, 35, 7, 79, 13, 0 },
+ { 0, 3, 50, 7, 68, 7, 0 },
+ { 0, 6, 64, 7, 55, 3, 0 },
+ { 0, 11, 75, 7, 40, 2, 0 },
+ { 0, 19, 82, 7, 26, 1, 0 },
+ { 0, 1, 30, 7, 81, 16, 0 },
+ { 0, 2, 45, 7, 72, 9, 0 },
+ { 0, 4, 60, 7, 60, 4, 0 },
+ { 0, 9, 72, 7, 45, 2, 0 },
+ { 0, 16, 81, 7, 30, 1, 0 },
+ { 0, 1, 26, 7, 82, 19, 0 },
+ { 0, 2, 40, 7, 75, 11, 0 },
+ { 0, 3, 55, 7, 64, 6, 0 },
+ { 0, 7, 68, 7, 50, 3, 0 },
+ { 0, 13, 79, 7, 35, 1, 0 } },
+ .odd = { { 0, 1, 28, 7, 82, 17, 0 },
+ { 0, 2, 42, 7, 74, 10, 0 },
+ { 0, 4, 57, 7, 62, 5, 0 },
+ { 0, 8, 71, 7, 47, 2, 0 },
+ { 0, 14, 80, 7, 33, 1, 0 },
+ { 0, 1, 24, 7, 82, 21, 0 },
+ { 0, 1, 37, 7, 78, 12, 0 },
+ { 0, 3, 52, 7, 67, 6, 0 },
+ { 0, 6, 67, 7, 52, 3, 0 },
+ { 0, 12, 78, 7, 37, 1, 0 },
+ { 0, 21, 82, 7, 24, 1, 0 },
+ { 0, 1, 33, 7, 80, 14, 0 },
+ { 0, 2, 47, 7, 71, 8, 0 },
+ { 0, 5, 62, 7, 57, 4, 0 },
+ { 0, 10, 74, 7, 42, 2, 0 },
+ { 0, 17, 82, 7, 28, 1, 0 } } },
+ .ver_phase_arr = {
+ .even = { { 0, 22, 84, 7, 22, 0, 0 },
+ { 0, 1, 35, 7, 79, 13, 0 },
+ { 0, 3, 50, 7, 68, 7, 0 },
+ { 0, 6, 64, 7, 55, 3, 0 },
+ { 0, 11, 75, 7, 40, 2, 0 },
+ { 0, 19, 82, 7, 26, 1, 0 },
+ { 0, 1, 30, 7, 81, 16, 0 },
+ { 0, 2, 45, 7, 72, 9, 0 },
+ { 0, 4, 60, 7, 60, 4, 0 },
+ { 0, 9, 72, 7, 45, 2, 0 },
+ { 0, 16, 81, 7, 30, 1, 0 },
+ { 0, 1, 26, 7, 82, 19, 0 },
+ { 0, 2, 40, 7, 75, 11, 0 },
+ { 0, 3, 55, 7, 64, 6, 0 },
+ { 0, 7, 68, 7, 50, 3, 0 },
+ { 0, 13, 79, 7, 35, 1, 0 } },
+ .odd = { { 0, 1, 28, 7, 82, 17, 0 },
+ { 0, 2, 42, 7, 74, 10, 0 },
+ { 0, 4, 57, 7, 62, 5, 0 },
+ { 0, 8, 71, 7, 47, 2, 0 },
+ { 0, 14, 80, 7, 33, 1, 0 },
+ { 0, 1, 24, 7, 82, 21, 0 },
+ { 0, 1, 37, 7, 78, 12, 0 },
+ { 0, 3, 52, 7, 67, 6, 0 },
+ { 0, 6, 67, 7, 52, 3, 0 },
+ { 0, 12, 78, 7, 37, 1, 0 },
+ { 0, 21, 82, 7, 24, 1, 0 },
+ { 0, 1, 33, 7, 80, 14, 0 },
+ { 0, 2, 47, 7, 71, 8, 0 },
+ { 0, 5, 62, 7, 57,