diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-25 22:11:30 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-12-25 22:11:30 +0100 |
commit | 996680d461f8f759082e64f2395c1f7c25d9d549 (patch) | |
tree | f38e2b134849049c13f1011353917f2d8703d6b4 | |
parent | Merge tag 'media/v4.20-6' of git://git.kernel.org/pub/scm/linux/kernel/git/mc... (diff) | |
parent | media: staging/ipu3-imgu: Add MAINTAINERS entry (diff) | |
download | linux-996680d461f8f759082e64f2395c1f7c25d9d549.tar.xz linux-996680d461f8f759082e64f2395c1f7c25d9d549.zip |
Merge tag 'media/v4.20-7' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull more media updates from Mauro Carvalho Chehab:
"The Intel IPU3 camera driver"
* tag 'media/v4.20-7' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (23 commits)
media: staging/ipu3-imgu: Add MAINTAINERS entry
media: staging/ipu3-imgu: Address documentation comments
media: v4l: Add Intel IPU3 meta buffer formats
media: doc-rst: Add Intel IPU3 documentation
media: ipu3-imgu: Fix firmware binary location
media: ipu3-imgu: Fix compiler warnings
media: staging/intel-ipu3: Add dual pipe support
media: staging/intel-ipu3: Add Intel IPU3 meta data uAPI
media: staging/intel-ipu3: Add imgu top level pci device driver
media: staging/intel-ipu3: Add v4l2 driver based on media framework
media: staging/intel-ipu3: Add css pipeline programming
media: staging/intel-ipu3: css: Initialize css hardware
media: staging/intel-ipu3: css: Compute and program ccs
media: staging/intel-ipu3: css: Add static settings for image pipeline
media: staging/intel-ipu3: css: Add support for firmware management
media: staging/intel-ipu3: css: Add dma buff pool utility functions
media: staging/intel-ipu3: Implement DMA mapping functions
media: staging/intel-ipu3: mmu: Implement driver
media: staging/intel-ipu3: abi: Add structs
media: staging/intel-ipu3: abi: Add register definitions and enum
...
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, 4, 0 }, + { 0, 10, 74, 7, 42, 2, 0 }, + { 0, 17, 82, 7, 28, 1, 0 } } }, + .ptrn_arr = { { 0x32492493, 0x99249249, 0x924924 } }, + .sample_patrn_length = 90, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 59) = 0.351648 */ + .hor_phase_arr = { + .even = { { 0, 23, 82, 7, 23, 0, 0 }, + { 0, 1, 33, 7, 79, 15, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 4, 57, 7, 62, 5, 0 }, + { 0, 7, 68, 7, 50, 3, 0 }, + { 0, 12, 78, 7, 37, 1, 0 }, + { 0, 19, 81, 7, 27, 1, 0 }, + { 0, 1, 29, 7, 80, 18, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 3, 52, 7, 66, 7, 0 }, + { 0, 6, 63, 7, 55, 4, 0 }, + { 0, 10, 74, 7, 42, 2, 0 }, + { 0, 16, 80, 7, 31, 1, 0 }, + { 0, 1, 25, 7, 81, 21, 0 }, + { 0, 1, 35, 7, 79, 13, 0 }, + { 0, 2, 47, 7, 71, 8, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 8, 71, 7, 47, 2, 0 }, + { 0, 13, 79, 7, 35, 1, 0 }, + { 0, 21, 81, 7, 25, 1, 0 }, + { 0, 1, 31, 7, 80, 16, 0 }, + { 0, 2, 42, 7, 74, 10, 0 }, + { 0, 4, 55, 7, 63, 6, 0 }, + { 0, 7, 66, 7, 52, 3, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 18, 80, 7, 29, 1, 0 }, + { 0, 1, 27, 7, 81, 19, 0 }, + { 0, 1, 37, 7, 78, 12, 0 }, + { 0, 3, 50, 7, 68, 7, 0 }, + { 0, 5, 62, 7, 57, 4, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 15, 79, 7, 33, 1, 0 } }, + .odd = { { 0, 1, 28, 7, 81, 18, 0 }, + { 0, 2, 39, 7, 75, 12, 0 }, + { 0, 3, 51, 7, 67, 7, 0 }, + { 0, 6, 62, 7, 56, 4, 0 }, + { 0, 10, 73, 7, 43, 2, 0 }, + { 0, 15, 80, 7, 32, 1, 0 }, + { 0, 1, 24, 7, 81, 22, 0 }, + { 0, 1, 34, 7, 79, 14, 0 }, + { 0, 2, 46, 7, 71, 9, 0 }, + { 0, 4, 58, 7, 61, 5, 0 }, + { 0, 8, 69, 7, 48, 3, 0 }, + { 0, 13, 78, 7, 36, 1, 0 }, + { 0, 20, 81, 7, 26, 1, 0 }, + { 0, 1, 30, 7, 80, 17, 0 }, + { 0, 2, 41, 7, 74, 11, 0 }, + { 0, 3, 53, 7, 66, 6, 0 }, + { 0, 6, 66, 7, 53, 3, 0 }, + { 0, 11, 74, 7, 41, 2, 0 }, + { 0, 17, 80, 7, 30, 1, 0 }, + { 0, 1, 26, 7, 81, 20, 0 }, + { 0, 1, 36, 7, 78, 13, 0 }, + { 0, 3, 48, 7, 69, 8, 0 }, + { 0, 5, 61, 7, 58, 4, 0 }, + { 0, 9, 71, 7, 46, 2, 0 }, + { 0, 14, 79, 7, 34, 1, 0 }, + { 0, 22, 81, 7, 24, 1, 0 }, + { 0, 1, 32, 7, 80, 15, 0 }, + { 0, 2, 43, 7, 73, 10, 0 }, + { 0, 4, 56, 7, 62, 6, 0 }, + { 0, 7, 67, 7, 51, 3, 0 }, + { 0, 12, 75, 7, 39, 2, 0 }, + { 0, 18, 81, 7, 28, 1, 0 } } }, + .ver_phase_arr = { + .even = { { 0, 23, 82, 7, 23, 0, 0 }, + { 0, 1, 33, 7, 79, 15, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 4, 57, 7, 62, 5, 0 }, + { 0, 7, 68, 7, 50, 3, 0 }, + { 0, 12, 78, 7, 37, 1, 0 }, + { 0, 19, 81, 7, 27, 1, 0 }, + { 0, 1, 29, 7, 80, 18, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 3, 52, 7, 66, 7, 0 }, + { 0, 6, 63, 7, 55, 4, 0 }, + { 0, 10, 74, 7, 42, 2, 0 }, + { 0, 16, 80, 7, 31, 1, 0 }, + { 0, 1, 25, 7, 81, 21, 0 }, + { 0, 1, 35, 7, 79, 13, 0 }, + { 0, 2, 47, 7, 71, 8, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 8, 71, 7, 47, 2, 0 }, + { 0, 13, 79, 7, 35, 1, 0 }, + { 0, 21, 81, 7, 25, 1, 0 }, + { 0, 1, 31, 7, 80, 16, 0 }, + { 0, 2, 42, 7, 74, 10, 0 }, + { 0, 4, 55, 7, 63, 6, 0 }, + { 0, 7, 66, 7, 52, 3, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 18, 80, 7, 29, 1, 0 }, + { 0, 1, 27, 7, 81, 19, 0 }, + { 0, 1, 37, 7, 78, 12, 0 }, + { 0, 3, 50, 7, 68, 7, 0 }, + { 0, 5, 62, 7, 57, 4, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 15, 79, 7, 33, 1, 0 } }, + .odd = { { 0, 1, 28, 7, 81, 18, 0 }, + { 0, 2, 39, 7, 75, 12, 0 }, + { 0, 3, 51, 7, 67, 7, 0 }, + { 0, 6, 62, 7, 56, 4, 0 }, + { 0, 10, 73, 7, 43, 2, 0 }, + { 0, 15, 80, 7, 32, 1, 0 }, + { 0, 1, 24, 7, 81, 22, 0 }, + { 0, 1, 34, 7, 79, 14, 0 }, + { 0, 2, 46, 7, 71, 9, 0 }, + { 0, 4, 58, 7, 61, 5, 0 }, + { 0, 8, 69, 7, 48, 3, 0 }, + { 0, 13, 78, 7, 36, 1, 0 }, + { 0, 20, 81, 7, 26, 1, 0 }, + { 0, 1, 30, 7, 80, 17, 0 }, + { 0, 2, 41, 7, 74, 11, 0 }, + { 0, 3, 53, 7, 66, 6, 0 }, + { 0, 6, 66, 7, 53, 3, 0 }, + { 0, 11, 74, 7, 41, 2, 0 }, + { 0, 17, 80, 7, 30, 1, 0 }, + { 0, 1, 26, 7, 81, 20, 0 }, + { 0, 1, 36, 7, 78, 13, 0 }, + { 0, 3, 48, 7, 69, 8, 0 }, + { 0, 5, 61, 7, 58, 4, 0 }, + { 0, 9, 71, 7, 46, 2, 0 }, + { 0, 14, 79, 7, 34, 1, 0 }, + { 0, 22, 81, 7, 24, 1, 0 }, + { 0, 1, 32, 7, 80, 15, 0 }, + { 0, 2, 43, 7, 73, 10, 0 }, + { 0, 4, 56, 7, 62, 6, 0 }, + { 0, 7, 67, 7, 51, 3, 0 }, + { 0, 12, 75, 7, 39, 2, 0 }, + { 0, 18, 81, 7, 28, 1, 0 } } }, + .ptrn_arr = { { 0x92492493, 0x4924924c, 0x24924992, 0x92493249, + 0x49264924, 0x92492 } }, + .sample_patrn_length = 182, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 60) = 0.347826 */ + .hor_phase_arr = { + .even = { { 1, 23, 80, 7, 23, 1, 0 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 17, 79, 7, 31, 1, 0 } }, + .odd = { { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 1, 35, 7, 78, 14, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 4, 54, 7, 64, 6, 0 }, + { 0, 6, 64, 7, 54, 4, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 14, 78, 7, 35, 1, 0 }, + { 0, 20, 80, 7, 27, 1, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 23, 80, 7, 23, 1, 0 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 17, 79, 7, 31, 1, 0 } }, + .odd = { { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 1, 35, 7, 78, 14, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 4, 54, 7, 64, 6, 0 }, + { 0, 6, 64, 7, 54, 4, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 14, 78, 7, 35, 1, 0 }, + { 0, 20, 80, 7, 27, 1, 0 } } }, + .ptrn_arr = { { 0x92492493, 0x924 } }, + .sample_patrn_length = 46, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 61) = 0.344086 */ + .hor_phase_arr = { + .even = { { 1, 23, 80, 7, 23, 1, 0 }, + { 0, 1, 29, 7, 80, 18, 0 }, + { 0, 1, 36, 7, 77, 14, 0 }, + { 0, 2, 42, 7, 73, 11, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 5, 57, 7, 60, 6, 0 }, + { 0, 6, 64, 7, 54, 4, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 16, 78, 7, 33, 1, 0 }, + { 0, 20, 80, 7, 27, 1, 0 }, + { 0, 1, 25, 7, 79, 22, 1 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 2, 38, 7, 75, 13, 0 }, + { 0, 2, 45, 7, 71, 10, 0 }, + { 0, 4, 52, 7, 65, 7, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 7, 65, 7, 52, 4, 0 }, + { 0, 10, 71, 7, 45, 2, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 17, 79, 7, 31, 1, 0 }, + { 1, 22, 79, 7, 25, 1, 0 }, + { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 1, 33, 7, 78, 16, 0 }, + { 0, 2, 40, 7, 74, 12, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 4, 54, 7, 64, 6, 0 }, + { 0, 6, 60, 7, 57, 5, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 11, 73, 7, 42, 2, 0 }, + { 0, 14, 77, 7, 36, 1, 0 }, + { 0, 18, 80, 7, 29, 1, 0 } }, + .odd = { { 0, 1, 26, 7, 80, 21, 0 }, + { 0, 1, 32, 7, 79, 16, 0 }, + { 0, 2, 39, 7, 75, 12, 0 }, + { 0, 3, 46, 7, 70, 9, 0 }, + { 0, 4, 53, 7, 64, 7, 0 }, + { 0, 5, 60, 7, 58, 5, 0 }, + { 0, 8, 66, 7, 51, 3, 0 }, + { 0, 10, 72, 7, 44, 2, 0 }, + { 0, 14, 75, 7, 37, 2, 0 }, + { 0, 18, 79, 7, 30, 1, 0 }, + { 1, 23, 79, 7, 24, 1, 0 }, + { 0, 1, 28, 7, 80, 19, 0 }, + { 0, 1, 35, 7, 77, 15, 0 }, + { 0, 2, 41, 7, 74, 11, 0 }, + { 0, 3, 48, 7, 69, 8, 0 }, + { 0, 4, 55, 7, 63, 6, 0 }, + { 0, 6, 63, 7, 55, 4, 0 }, + { 0, 8, 69, 7, 48, 3, 0 }, + { 0, 11, 74, 7, 41, 2, 0 }, + { 0, 15, 77, 7, 35, 1, 0 }, + { 0, 19, 80, 7, 28, 1, 0 }, + { 0, 1, 24, 7, 79, 23, 1 }, + { 0, 1, 30, 7, 79, 18, 0 }, + { 0, 2, 37, 7, 75, 14, 0 }, + { 0, 2, 44, 7, 72, 10, 0 }, + { 0, 3, 51, 7, 66, 8, 0 }, + { 0, 5, 58, 7, 60, 5, 0 }, + { 0, 7, 64, 7, 53, 4, 0 }, + { 0, 9, 70, 7, 46, 3, 0 }, + { 0, 12, 75, 7, 39, 2, 0 }, + { 0, 16, 79, 7, 32, 1, 0 }, + { 0, 21, 80, 7, 26, 1, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 23, 80, 7, 23, 1, 0 }, + { 0, 1, 29, 7, 80, 18, 0 }, + { 0, 1, 36, 7, 77, 14, 0 }, + { 0, 2, 42, 7, 73, 11, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 5, 57, 7, 60, 6, 0 }, + { 0, 6, 64, 7, 54, 4, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 16, 78, 7, 33, 1, 0 }, + { 0, 20, 80, 7, 27, 1, 0 }, + { 0, 1, 25, 7, 79, 22, 1 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 2, 38, 7, 75, 13, 0 }, + { 0, 2, 45, 7, 71, 10, 0 }, + { 0, 4, 52, 7, 65, 7, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 7, 65, 7, 52, 4, 0 }, + { 0, 10, 71, 7, 45, 2, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 17, 79, 7, 31, 1, 0 }, + { 1, 22, 79, 7, 25, 1, 0 }, + { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 1, 33, 7, 78, 16, 0 }, + { 0, 2, 40, 7, 74, 12, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 4, 54, 7, 64, 6, 0 }, + { 0, 6, 60, 7, 57, 5, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 11, 73, 7, 42, 2, 0 }, + { 0, 14, 77, 7, 36, 1, 0 }, + { 0, 18, 80, 7, 29, 1, 0 } }, + .odd = { { 0, 1, 26, 7, 80, 21, 0 }, + { 0, 1, 32, 7, 79, 16, 0 }, + { 0, 2, 39, 7, 75, 12, 0 }, + { 0, 3, 46, 7, 70, 9, 0 }, + { 0, 4, 53, 7, 64, 7, 0 }, + { 0, 5, 60, 7, 58, 5, 0 }, + { 0, 8, 66, 7, 51, 3, 0 }, + { 0, 10, 72, 7, 44, 2, 0 }, + { 0, 14, 75, 7, 37, 2, 0 }, + { 0, 18, 79, 7, 30, 1, 0 }, + { 1, 23, 79, 7, 24, 1, 0 }, + { 0, 1, 28, 7, 80, 19, 0 }, + { 0, 1, 35, 7, 77, 15, 0 }, + { 0, 2, 41, 7, 74, 11, 0 }, + { 0, 3, 48, 7, 69, 8, 0 }, + { 0, 4, 55, 7, 63, 6, 0 }, + { 0, 6, 63, 7, 55, 4, 0 }, + { 0, 8, 69, 7, 48, 3, 0 }, + { 0, 11, 74, 7, 41, 2, 0 }, + { 0, 15, 77, 7, 35, 1, 0 }, + { 0, 19, 80, 7, 28, 1, 0 }, + { 0, 1, 24, 7, 79, 23, 1 }, + { 0, 1, 30, 7, 79, 18, 0 }, + { 0, 2, 37, 7, 75, 14, 0 }, + { 0, 2, 44, 7, 72, 10, 0 }, + { 0, 3, 51, 7, 66, 8, 0 }, + { 0, 5, 58, 7, 60, 5, 0 }, + { 0, 7, 64, 7, 53, 4, 0 }, + { 0, 9, 70, 7, 46, 3, 0 }, + { 0, 12, 75, 7, 39, 2, 0 }, + { 0, 16, 79, 7, 32, 1, 0 }, + { 0, 21, 80, 7, 26, 1, 0 } } }, + .ptrn_arr = { { 0x92492493, 0x64924924, 0x92492492, 0x4c924924, + 0x92492492, 0x924924 } }, + .sample_patrn_length = 186, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 62) = 0.340426 */ + .hor_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 1, 28, 7, 79, 20, 0 }, + { 0, 1, 32, 7, 78, 17, 0 }, + { 0, 2, 36, 7, 75, 15, 0 }, + { 0, 2, 40, 7, 74, 12, 0 }, + { 0, 3, 45, 7, 70, 10, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 4, 54, 7, 63, 7, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 7, 63, 7, 54, 4, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 10, 70, 7, 45, 3, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 15, 75, 7, 36, 2, 0 }, + { 0, 17, 78, 7, 32, 1, 0 }, + { 0, 20, 79, 7, 28, 1, 0 } }, + .odd = { { 0, 1, 26, 7, 78, 22, 1 }, + { 0, 1, 30, 7, 78, 19, 0 }, + { 0, 1, 34, 7, 77, 16, 0 }, + { 0, 2, 38, 7, 75, 13, 0 }, + { 0, 2, 43, 7, 72, 11, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 4, 52, 7, 65, 7, 0 }, + { 0, 5, 56, 7, 61, 6, 0 }, + { 0, 6, 61, 7, 56, 5, 0 }, + { 0, 7, 65, 7, 52, 4, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 11, 72, 7, 43, 2, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 16, 77, 7, 34, 1, 0 }, + { 0, 19, 78, 7, 30, 1, 0 }, + { 1, 22, 78, 7, 26, 1, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 1, 28, 7, 79, 20, 0 }, + { 0, 1, 32, 7, 78, 17, 0 }, + { 0, 2, 36, 7, 75, 15, 0 }, + { 0, 2, 40, 7, 74, 12, 0 }, + { 0, 3, 45, 7, 70, 10, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 4, 54, 7, 63, 7, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 7, 63, 7, 54, 4, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 10, 70, 7, 45, 3, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 15, 75, 7, 36, 2, 0 }, + { 0, 17, 78, 7, 32, 1, 0 }, + { 0, 20, 79, 7, 28, 1, 0 } }, + .odd = { { 0, 1, 26, 7, 78, 22, 1 }, + { 0, 1, 30, 7, 78, 19, 0 }, + { 0, 1, 34, 7, 77, 16, 0 }, + { 0, 2, 38, 7, 75, 13, 0 }, + { 0, 2, 43, 7, 72, 11, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 4, 52, 7, 65, 7, 0 }, + { 0, 5, 56, 7, 61, 6, 0 }, + { 0, 6, 61, 7, 56, 5, 0 }, + { 0, 7, 65, 7, 52, 4, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 11, 72, 7, 43, 2, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 16, 77, 7, 34, 1, 0 }, + { 0, 19, 78, 7, 30, 1, 0 }, + { 1, 22, 78, 7, 26, 1, 0 } } }, + .ptrn_arr = { { 0x92492493, 0x24924924, 0x9249249 } }, + .sample_patrn_length = 94, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 63) = 0.336842 */ + .hor_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 1, 26, 7, 78, 22, 1 }, + { 0, 1, 28, 7, 77, 21, 1 }, + { 0, 1, 30, 7, 78, 19, 0 }, + { 0, 1, 32, 7, 77, 18, 0 }, + { 0, 1, 34, 7, 77, 16, 0 }, + { 0, 2, 36, 7, 75, 15, 0 }, + { 0, 2, 38, 7, 74, 14, 0 }, + { 0, 2, 40, 7, 73, 13, 0 }, + { 0, 2, 43, 7, 72, 11, 0 }, + { 0, 3, 45, 7, 70, 10, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 4, 49, 7, 66, 9, 0 }, + { 0, 4, 52, 7, 64, 8, 0 }, + { 0, 4, 54, 7, 63, 7, 0 }, + { 0, 5, 56, 7, 61, 6, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 6, 61, 7, 56, 5, 0 }, + { 0, 7, 63, 7, 54, 4, 0 }, + { 0, 8, 64, 7, 52, 4, 0 }, + { 0, 9, 66, 7, 49, 4, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 10, 70, 7, 45, 3, 0 }, + { 0, 11, 72, 7, 43, 2, 0 }, + { 0, 13, 73, 7, 40, 2, 0 }, + { 0, 14, 74, 7, 38, 2, 0 }, + { 0, 15, 75, 7, 36, 2, 0 }, + { 0, 16, 77, 7, 34, 1, 0 }, + { 0, 18, 77, 7, 32, 1, 0 }, + { 0, 19, 78, 7, 30, 1, 0 }, + { 1, 21, 77, 7, 28, 1, 0 }, + { 1, 22, 78, 7, 26, 1, 0 } }, + .odd = { { 0, 1, 25, 7, 78, 23, 1 }, + { 0, 1, 27, 7, 77, 22, 1 }, + { 0, 1, 29, 7, 78, 20, 0 }, + { 0, 1, 31, 7, 78, 18, 0 }, + { 0, 1, 33, 7, 77, 17, 0 }, + { 0, 2, 35, 7, 75, 16, 0 }, + { 0, 2, 37, 7, 75, 14, 0 }, + { 0, 2, 39, 7, 74, 13, 0 }, + { 0, 2, 42, 7, 72, 12, 0 }, + { 0, 3, 44, 7, 70, 11, 0 }, + { 0, 3, 46, 7, 69, 10, 0 }, + { 0, 3, 48, 7, 68, 9, 0 }, + { 0, 4, 51, 7, 65, 8, 0 }, + { 0, 4, 53, 7, 64, 7, 0 }, + { 0, 5, 55, 7, 61, 7, 0 }, + { 0, 5, 57, 7, 60, 6, 0 }, + { 0, 6, 60, 7, 57, 5, 0 }, + { 0, 7, 61, 7, 55, 5, 0 }, + { 0, 7, 64, 7, 53, 4, 0 }, + { 0, 8, 65, 7, 51, 4, 0 }, + { 0, 9, 68, 7, 48, 3, 0 }, + { 0, 10, 69, 7, 46, 3, 0 }, + { 0, 11, 70, 7, 44, 3, 0 }, + { 0, 12, 72, 7, 42, 2, 0 }, + { 0, 13, 74, 7, 39, 2, 0 }, + { 0, 14, 75, 7, 37, 2, 0 }, + { 0, 16, 75, 7, 35, 2, 0 }, + { 0, 17, 77, 7, 33, 1, 0 }, + { 0, 18, 78, 7, 31, 1, 0 }, + { 0, 20, 78, 7, 29, 1, 0 }, + { 1, 22, 77, 7, 27, 1, 0 }, + { 1, 23, 78, 7, 25, 1, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 1, 26, 7, 78, 22, 1 }, + { 0, 1, 28, 7, 77, 21, 1 }, + { 0, 1, 30, 7, 78, 19, 0 }, + { 0, 1, 32, 7, 77, 18, 0 }, + { 0, 1, 34, 7, 77, 16, 0 }, + { 0, 2, 36, 7, 75, 15, 0 }, + { 0, 2, 38, 7, 74, 14, 0 }, + { 0, 2, 40, 7, 73, 13, 0 }, + { 0, 2, 43, 7, 72, 11, 0 }, + { 0, 3, 45, 7, 70, 10, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 4, 49, 7, 66, 9, 0 }, + { 0, 4, 52, 7, 64, 8, 0 }, + { 0, 4, 54, 7, 63, 7, 0 }, + { 0, 5, 56, 7, 61, 6, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 6, 61, 7, 56, 5, 0 }, + { 0, 7, 63, 7, 54, 4, 0 }, + { 0, 8, 64, 7, 52, 4, 0 }, + { 0, 9, 66, 7, 49, 4, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 10, 70, 7, 45, 3, 0 }, + { 0, 11, 72, 7, 43, 2, 0 }, + { 0, 13, 73, 7, 40, 2, 0 }, + { 0, 14, 74, 7, 38, 2, 0 }, + { 0, 15, 75, 7, 36, 2, 0 }, + { 0, 16, 77, 7, 34, 1, 0 }, + { 0, 18, 77, 7, 32, 1, 0 }, + { 0, 19, 78, 7, 30, 1, 0 }, + { 1, 21, 77, 7, 28, 1, 0 }, + { 1, 22, 78, 7, 26, 1, 0 } }, + .odd = { { 0, 1, 25, 7, 78, 23, 1 }, + { 0, 1, 27, 7, 77, 22, 1 }, + { 0, 1, 29, 7, 78, 20, 0 }, + { 0, 1, 31, 7, 78, 18, 0 }, + { 0, 1, 33, 7, 77, 17, 0 }, + { 0, 2, 35, 7, 75, 16, 0 }, + { 0, 2, 37, 7, 75, 14, 0 }, + { 0, 2, 39, 7, 74, 13, 0 }, + { 0, 2, 42, 7, 72, 12, 0 }, + { 0, 3, 44, 7, 70, 11, 0 }, + { 0, 3, 46, 7, 69, 10, 0 }, + { 0, 3, 48, 7, 68, 9, 0 }, + { 0, 4, 51, 7, 65, 8, 0 }, + { 0, 4, 53, 7, 64, 7, 0 }, + { 0, 5, 55, 7, 61, 7, 0 }, + { 0, 5, 57, 7, 60, 6, 0 }, + { 0, 6, 60, 7, 57, 5, 0 }, + { 0, 7, 61, 7, 55, 5, 0 }, + { 0, 7, 64, 7, 53, 4, 0 }, + { 0, 8, 65, 7, 51, 4, 0 }, + { 0, 9, 68, 7, 48, 3, 0 }, + { 0, 10, 69, 7, 46, 3, 0 }, + { 0, 11, 70, 7, 44, 3, 0 }, + { 0, 12, 72, 7, 42, 2, 0 }, + { 0, 13, 74, 7, 39, 2, 0 }, + { 0, 14, 75, 7, 37, 2, 0 }, + { 0, 16, 75, 7, 35, 2, 0 }, + { 0, 17, 77, 7, 33, 1, 0 }, + { 0, 18, 78, 7, 31, 1, 0 }, + { 0, 20, 78, 7, 29, 1, 0 }, + { 1, 22, 77, 7, 27, 1, 0 }, + { 1, 23, 78, 7, 25, 1, 0 } } }, + .ptrn_arr = { { 0x92492493, 0x24924924, 0x49249249, 0x92492492, + 0x24924924, 0x9249249 } }, + .sample_patrn_length = 190, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 64) = 0.333333 */ + .hor_phase_arr = { + .even = { { 0, 21, 86, 7, 21, 0, 0 } }, + .odd = { { 0, 4, 60, 7, 60, 4, 0 } } }, + .ver_phase_arr = { + .even = { { 0, 21, 86, 7, 21, 0, 0 } }, + .odd = { { 0, 4, 60, 7, 60, 4, 0 } } }, + .ptrn_arr = { { 0x9 } }, + .sample_patrn_length = 6, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 65) = 0.329897 */ + .hor_phase_arr = { + .even = { { 0, 22, 84, 7, 22, 0, 0 }, + { 0, 20, 85, 7, 23, 0, 0 }, + { 0, 18, 84, 7, 25, 1, 0 }, + { 0, 17, 82, 7, 28, 1, 0 }, + { 0, 15, 82, 7, 30, 1, 0 }, + { 0, 14, 81, 7, 32, 1, 0 }, + { 0, 12, 81, 7, 34, 1, 0 }, + { 0, 11, 79, 7, 37, 1, 0 }, + { 0, 10, 78, 7, 39, 1, 0 }, + { 0, 9, 75, 7, 42, 2, 0 }, + { 0, 8, 74, 7, 44, 2, 0 }, + { 0, 7, 72, 7, 47, 2, 0 }, + { 0, 6, 70, 7, 50, 2, 0 }, + { 0, 6, 67, 7, 52, 3, 0 }, + { 0, 5, 65, 7, 55, 3, 0 }, + { 0, 4, 64, 7, 57, 3, 0 }, + { 0, 4, 60, 7, 60, 4, 0 }, + { 0, 3, 57, 7, 64, 4, 0 }, + { 0, 3, 55, 7, 65, 5, 0 }, + { 0, 3, 52, 7, 67, 6, 0 }, + { 0, 2, 50, 7, 70, 6, 0 }, + { 0, 2, 47, 7, 72, 7, 0 }, + { 0, 2, 44, 7, 74, 8, 0 }, + { 0, 2, 42, 7, 75, 9, 0 }, + { 0, 1, 39, 7, 78, 10, 0 }, + { 0, 1, 37, 7, 79, 11, 0 }, + { 0, 1, 34, 7, 81, 12, 0 }, + { 0, 1, 32, 7, 81, 14, 0 }, + { 0, 1, 30, 7, 82, 15, 0 }, + { 0, 1, 28, 7, 82, 17, 0 }, + { 0, 1, 25, 7, 84, 18, 0 }, + { 0, 0, 23, 7, 85, 20, 0 } }, + .odd = { { 0, 21, 84, 7, 23, 0, 0 }, + { 0, 19, 85, 7, 24, 0, 0 }, + { 0, 17, 84, 7, 26, 1, 0 }, + { 0, 16, 82, 7, 29, 1, 0 }, + { 0, 14, 82, 7, 31, 1, 0 }, + { 0, 13, 81, 7, 33, 1, 0 }, + { 0, 12, 80, 7, 35, 1, 0 }, + { 0, 11, 78, 7, 38, 1, 0 }, + { 0, 10, 77, 7, 40, 1, 0 }, + { 0, 9, 74, 7, 43, 2, 0 }, + { 0, 8, 72, 7, 46, 2, 0 }, + { 0, 7, 71, 7, 48, 2, 0 }, + { 0, 6, 69, 7, 51, 2, 0 }, + { 0, 5, 66, 7, 54, 3, 0 }, + { 0, 5, 64, 7, 56, 3, 0 }, + { 0, 4, 61, 7, 59, 4, 0 }, + { 0, 4, 59, 7, 61, 4, 0 }, + { 0, 3, 56, 7, 64, 5, 0 }, + { 0, 3, 54, 7, 66, 5, 0 }, + { 0, 2, 51, 7, 69, 6, 0 }, + { 0, 2, 48, 7, 71, 7, 0 }, + { 0, 2, 46, 7, 72, 8, 0 }, + { 0, 2, 43, 7, 74, 9, 0 }, + { 0, 1, 40, 7, 77, 10, 0 }, + { 0, 1, 38, 7, 78, 11, 0 }, + { 0, 1, 35, 7, 80, 12, 0 }, + { 0, 1, 33, 7, 81, 13, 0 }, + { 0, 1, 31, 7, 82, 14, 0 }, + { 0, 1, 29, 7, 82, 16, 0 }, + { 0, 1, 26, 7, 84, 17, 0 }, + { 0, 0, 24, 7, 85, 19, 0 }, + { 0, 0, 23, 7, 84, 21, 0 } } }, + .ver_phase_arr = { + .even = { { 0, 22, 84, 7, 22, 0, 0 }, + { 0, 20, 85, 7, 23, 0, 0 }, + { 0, 18, 84, 7, 25, 1, 0 }, + { 0, 17, 82, 7, 28, 1, 0 }, + { 0, 15, 82, 7, 30, 1, 0 }, + { 0, 14, 81, 7, 32, 1, 0 }, + { 0, 12, 81, 7, 34, 1, 0 }, + { 0, 11, 79, 7, 37, 1, 0 }, + { 0, 10, 78, 7, 39, 1, 0 }, + { 0, 9, 75, 7, 42, 2, 0 }, + { 0, 8, 74, 7, 44, 2, 0 }, + { 0, 7, 72, 7, 47, 2, 0 }, + { 0, 6, 70, 7, 50, 2, 0 }, + { 0, 6, 67, 7, 52, 3, 0 }, + { 0, 5, 65, 7, 55, 3, 0 }, + { 0, 4, 64, 7, 57, 3, 0 }, + { 0, 4, 60, 7, 60, 4, 0 }, + { 0, 3, 57, 7, 64, 4, 0 }, + { 0, 3, 55, 7, 65, 5, 0 }, + { 0, 3, 52, 7, 67, 6, 0 }, + { 0, 2, 50, 7, 70, 6, 0 }, + { 0, 2, 47, 7, 72, 7, 0 }, + { 0, 2, 44, 7, 74, 8, 0 }, + { 0, 2, 42, 7, 75, 9, 0 }, + { 0, 1, 39, 7, 78, 10, 0 }, + { 0, 1, 37, 7, 79, 11, 0 }, + { 0, 1, 34, 7, 81, 12, 0 }, + { 0, 1, 32, 7, 81, 14, 0 }, + { 0, 1, 30, 7, 82, 15, 0 }, + { 0, 1, 28, 7, 82, 17, 0 }, + { 0, 1, 25, 7, 84, 18, 0 }, + { 0, 0, 23, 7, 85, 20, 0 } }, + .odd = { { 0, 21, 84, 7, 23, 0, 0 }, + { 0, 19, 85, 7, 24, 0, 0 }, + { 0, 17, 84, 7, 26, 1, 0 }, + { 0, 16, 82, 7, 29, 1, 0 }, + { 0, 14, 82, 7, 31, 1, 0 }, + { 0, 13, 81, 7, 33, 1, 0 }, + { 0, 12, 80, 7, 35, 1, 0 }, + { 0, 11, 78, 7, 38, 1, 0 }, + { 0, 10, 77, 7, 40, 1, 0 }, + { 0, 9, 74, 7, 43, 2, 0 }, + { 0, 8, 72, 7, 46, 2, 0 }, + { 0, 7, 71, 7, 48, 2, 0 }, + { 0, 6, 69, 7, 51, 2, 0 }, + { 0, 5, 66, 7, 54, 3, 0 }, + { 0, 5, 64, 7, 56, 3, 0 }, + { 0, 4, 61, 7, 59, 4, 0 }, + { 0, 4, 59, 7, 61, 4, 0 }, + { 0, 3, 56, 7, 64, 5, 0 }, + { 0, 3, 54, 7, 66, 5, 0 }, + { 0, 2, 51, 7, 69, 6, 0 }, + { 0, 2, 48, 7, 71, 7, 0 }, + { 0, 2, 46, 7, 72, 8, 0 }, + { 0, 2, 43, 7, 74, 9, 0 }, + { 0, 1, 40, 7, 77, 10, 0 }, + { 0, 1, 38, 7, 78, 11, 0 }, + { 0, 1, 35, 7, 80, 12, 0 }, + { 0, 1, 33, 7, 81, 13, 0 }, + { 0, 1, 31, 7, 82, 14, 0 }, + { 0, 1, 29, 7, 82, 16, 0 }, + { 0, 1, 26, 7, 84, 17, 0 }, + { 0, 0, 24, 7, 85, 19, 0 }, + { 0, 0, 23, 7, 84, 21, 0 } } }, + .ptrn_arr = { { 0x49249249, 0x92492492, 0x24924924, 0x49249249, + 0x92492492, 0x24924924 } }, + .sample_patrn_length = 194, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 66) = 0.326531 */ + .hor_phase_arr = { + .even = { { 0, 22, 84, 7, 22, 0, 0 }, + { 0, 18, 83, 7, 26, 1, 0 }, + { 0, 15, 82, 7, 30, 1, 0 }, + { 0, 13, 79, 7, 35, 1, 0 }, + { 0, 10, 78, 7, 39, 1, 0 }, + { 0, 8, 74, 7, 44, 2, 0 }, + { 0, 7, 69, 7, 50, 2, 0 }, + { 0, 5, 65, 7, 55, 3, 0 }, + { 0, 4, 60, 7, 60, 4, 0 }, + { 0, 3, 55, 7, 65, 5, 0 }, + { 0, 2, 50, 7, 69, 7, 0 }, + { 0, 2, 44, 7, 74, 8, 0 }, + { 0, 1, 39, 7, 78, 10, 0 }, + { 0, 1, 35, 7, 79, 13, 0 }, + { 0, 1, 30, 7, 82, 15, 0 }, + { 0, 1, 26, 7, 83, 18, 0 } }, + .odd = { { 0, 20, 84, 7, 24, 0, 0 }, + { 0, 17, 82, 7, 28, 1, 0 }, + { 0, 14, 81, 7, 32, 1, 0 }, + { 0, 12, 78, 7, 37, 1, 0 }, + { 0, 9, 75, 7, 42, 2, 0 }, + { 0, 8, 71, 7, 47, 2, 0 }, + { 0, 6, 67, 7, 52, 3, 0 }, + { 0, 5, 62, 7, 57, 4, 0 }, + { 0, 4, 57, 7, 62, 5, 0 }, + { 0, 3, 52, 7, 67, 6, 0 }, + { 0, 2, 47, 7, 71, 8, 0 }, + { 0, 2, 42, 7, 75, 9, 0 }, + { 0, 1, 37, 7, 78, 12, 0 }, + { 0, 1, 32, 7, 81, 14, 0 }, + { 0, 1, 28, 7, 82, 17, 0 }, + { 0, 0, 24, 7, 84, 20, 0 } } }, + .ver_phase_arr = { + .even = { { 0, 22, 84, 7, 22, 0, 0 }, + { 0, 18, 83, 7, 26, 1, 0 }, + { 0, 15, 82, 7, 30, 1, 0 }, + { 0, 13, 79, 7, 35, 1, 0 }, + { 0, 10, 78, 7, 39, 1, 0 }, + { 0, 8, 74, 7, 44, 2, 0 }, + { 0, 7, 69, 7, 50, 2, 0 }, + { 0, 5, 65, 7, 55, 3, 0 }, + { 0, 4, 60, 7, 60, 4, 0 }, + { 0, 3, 55, 7, 65, 5, 0 }, + { 0, 2, 50, 7, 69, 7, 0 }, + { 0, 2, 44, 7, 74, 8, 0 }, + { 0, 1, 39, 7, 78, 10, 0 }, + { 0, 1, 35, 7, 79, 13, 0 }, + { 0, 1, 30, 7, 82, 15, 0 }, + { 0, 1, 26, 7, 83, 18, 0 } }, + .odd = { { 0, 20, 84, 7, 24, 0, 0 }, + { 0, 17, 82, 7, 28, 1, 0 }, + { 0, 14, 81, 7, 32, 1, 0 }, + { 0, 12, 78, 7, 37, 1, 0 }, + { 0, 9, 75, 7, 42, 2, 0 }, + { 0, 8, 71, 7, 47, 2, 0 }, + { 0, 6, 67, 7, 52, 3, 0 }, + { 0, 5, 62, 7, 57, 4, 0 }, + { 0, 4, 57, 7, 62, 5, 0 }, + { 0, 3, 52, 7, 67, 6, 0 }, + { 0, 2, 47, 7, 71, 8, 0 }, + { 0, 2, 42, 7, 75, 9, 0 }, + { 0, 1, 37, 7, 78, 12, 0 }, + { 0, 1, 32, 7, 81, 14, 0 }, + { 0, 1, 28, 7, 82, 17, 0 }, + { 0, 0, 24, 7, 84, 20, 0 } } }, + .ptrn_arr = { { 0x49249249, 0x92492492, 0x24924924 } }, + .sample_patrn_length = 98, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 67) = 0.323232 */ + .hor_phase_arr = { + .even = { { 0, 22, 84, 7, 22, 0, 0 }, + { 0, 17, 82, 7, 28, 1, 0 }, + { 0, 13, 79, 7, 35, 1, 0 }, + { 0, 10, 74, 7, 42, 2, 0 }, + { 0, 7, 68, 7, 50, 3, 0 }, + { 0, 5, 62, 7, 57, 4, 0 }, + { 0, 3, 55, 7, 64, 6, 0 }, + { 0, 2, 47, 7, 71, 8, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 1, 33, 7, 80, 14, 0 }, + { 0, 1, 26, 7, 82, 19, 0 }, + { 0, 21, 82, 7, 24, 1, 0 }, + { 0, 16, 81, 7, 30, 1, 0 }, + { 0, 12, 78, 7, 37, 1, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 6, 67, 7, 52, 3, 0 }, + { 0, 4, 60, 7, 60, 4, 0 }, + { 0, 3, 52, 7, 67, 6, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 1, 37, 7, 78, 12, 0 }, + { 0, 1, 30, 7, 81, 16, 0 }, + { 0, 1, 24, 7, 82, 21, 0 }, + { 0, 19, 82, 7, 26, 1, 0 }, + { 0, 14, 80, 7, 33, 1, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 8, 71, 7, 47, 2, 0 }, + { 0, 6, 64, 7, 55, 3, 0 }, + { 0, 4, 57, 7, 62, 5, 0 }, + { 0, 3, 50, 7, 68, 7, 0 }, + { 0, 2, 42, 7, 74, 10, 0 }, + { 0, 1, 35, 7, 79, 13, 0 }, + { 0, 1, 28, 7, 82, 17, 0 } }, + .odd = { { 0, 20, 82, 7, 25, 1, 0 }, + { 0, 15, 81, 7, 31, 1, 0 }, + { 0, 11, 78, 7, 38, 1, 0 }, + { 0, 8, 72, 7, 46, 2, 0 }, + { 0, 6, 66, 7, 53, 3, 0 }, + { 0, 4, 58, 7, 61, 5, 0 }, + { 0, 3, 51, 7, 67, 7, 0 }, + { 0, 2, 43, 7, 74, 9, 0 }, + { 0, 1, 36, 7, 79, 12, 0 }, + { 0, 1, 29, 7, 81, 17, 0 }, + { 0, 0, 23, 7, 84, 21, 0 }, + { 0, 18, 82, 7, 27, 1, 0 }, + { 0, 14, 79, 7, 34, 1, 0 }, + { 0, 10, 75, 7, 41, 2, 0 }, + { 0, 7, 71, 7, 48, 2, 0 }, + { 0, 5, 63, 7, 56, 4, 0 }, + { 0, 4, 56, 7, 63, 5, 0 }, + { 0, 2, 48, 7, 71, 7, 0 }, + { 0, 2, 41, 7, 75, 10, 0 }, + { 0, 1, 34, 7, 79, 14, 0 }, + { 0, 1, 27, 7, 82, 18, 0 }, + { 0, 21, 84, 7, 23, 0, 0 }, + { 0, 17, 81, 7, 29, 1, 0 }, + { 0, 12, 79, 7, 36, 1, 0 }, + { 0, 9, 74, 7, 43, 2, 0 }, + { 0, 7, 67, 7, 51, 3, 0 }, + { 0, 5, 61, 7, 58, 4, 0 }, + { 0, 3, 53, 7, 66, 6, 0 }, + { 0, 2, 46, 7, 72, 8, 0 }, + { 0, 1, 38, 7, 78, 11, 0 }, + { 0, 1, 31, 7, 81, 15, 0 }, + { 0, 1, 25, 7, 82, 20, 0 } } }, + .ver_phase_arr = { + .even = { { 0, 22, 84, 7, 22, 0, 0 }, + { 0, 17, 82, 7, 28, 1, 0 }, + { 0, 13, 79, 7, 35, 1, 0 }, + { 0, 10, 74, 7, 42, 2, 0 }, + { 0, 7, 68, 7, 50, 3, 0 }, + { 0, 5, 62, 7, 57, 4, 0 }, + { 0, 3, 55, 7, 64, 6, 0 }, + { 0, 2, 47, 7, 71, 8, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 1, 33, 7, 80, 14, 0 }, + { 0, 1, 26, 7, 82, 19, 0 }, + { 0, 21, 82, 7, 24, 1, 0 }, + { 0, 16, 81, 7, 30, 1, 0 }, + { 0, 12, 78, 7, 37, 1, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 6, 67, 7, 52, 3, 0 }, + { 0, 4, 60, 7, 60, 4, 0 }, + { 0, 3, 52, 7, 67, 6, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 1, 37, 7, 78, 12, 0 }, + { 0, 1, 30, 7, 81, 16, 0 }, + { 0, 1, 24, 7, 82, 21, 0 }, + { 0, 19, 82, 7, 26, 1, 0 }, + { 0, 14, 80, 7, 33, 1, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 8, 71, 7, 47, 2, 0 }, + { 0, 6, 64, 7, 55, 3, 0 }, + { 0, 4, 57, 7, 62, 5, 0 }, + { 0, 3, 50, 7, 68, 7, 0 }, + { 0, 2, 42, 7, 74, 10, 0 }, + { 0, 1, 35, 7, 79, 13, 0 }, + { 0, 1, 28, 7, 82, 17, 0 } }, + .odd = { { 0, 20, 82, 7, 25, 1, 0 }, + { 0, 15, 81, 7, 31, 1, 0 }, + { 0, 11, 78, 7, 38, 1, 0 }, + { 0, 8, 72, 7, 46, 2, 0 }, + { 0, 6, 66, 7, 53, 3, 0 }, + { 0, 4, 58, 7, 61, 5, 0 }, + { 0, 3, 51, 7, 67, 7, 0 }, + { 0, 2, 43, 7, 74, 9, 0 }, + { 0, 1, 36, 7, 79, 12, 0 }, + { 0, 1, 29, 7, 81, 17, 0 }, + { 0, 0, 23, 7, 84, 21, 0 }, + { 0, 18, 82, 7, 27, 1, 0 }, + { 0, 14, 79, 7, 34, 1, 0 }, + { 0, 10, 75, 7, 41, 2, 0 }, + { 0, 7, 71, 7, 48, 2, 0 }, + { 0, 5, 63, 7, 56, 4, 0 }, + { 0, 4, 56, 7, 63, 5, 0 }, + { 0, 2, 48, 7, 71, 7, 0 }, + { 0, 2, 41, 7, 75, 10, 0 }, + { 0, 1, 34, 7, 79, 14, 0 }, + { 0, 1, 27, 7, 82, 18, 0 }, + { 0, 21, 84, 7, 23, 0, 0 }, + { 0, 17, 81, 7, 29, 1, 0 }, + { 0, 12, 79, 7, 36, 1, 0 }, + { 0, 9, 74, 7, 43, 2, 0 }, + { 0, 7, 67, 7, 51, 3, 0 }, + { 0, 5, 61, 7, 58, 4, 0 }, + { 0, 3, 53, 7, 66, 6, 0 }, + { 0, 2, 46, 7, 72, 8, 0 }, + { 0, 1, 38, 7, 78, 11, 0 }, + { 0, 1, 31, 7, 81, 15, 0 }, + { 0, 1, 25, 7, 82, 20, 0 } } }, + .ptrn_arr = { { 0x49249249, 0x92492492, 0x92492490, 0x24924924, + 0x24924921, 0x49249249, 0x2 } }, + .sample_patrn_length = 198, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 68) = 0.32 */ + .hor_phase_arr = { + .even = { { 0, 23, 82, 7, 23, 0, 0 }, + { 0, 16, 80, 7, 31, 1, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 7, 68, 7, 50, 3, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 3, 50, 7, 68, 7, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 1, 31, 7, 80, 16, 0 } }, + .odd = { { 0, 19, 81, 7, 27, 1, 0 }, + { 0, 13, 79, 7, 35, 1, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 6, 63, 7, 55, 4, 0 }, + { 0, 4, 55, 7, 63, 6, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 1, 35, 7, 79, 13, 0 }, + { 0, 1, 27, 7, 81, 19, 0 } } }, + .ver_phase_arr = { + .even = { { 0, 23, 82, 7, 23, 0, 0 }, + { 0, 16, 80, 7, 31, 1, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 7, 68, 7, 50, 3, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 3, 50, 7, 68, 7, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 1, 31, 7, 80, 16, 0 } }, + .odd = { { 0, 19, 81, 7, 27, 1, 0 }, + { 0, 13, 79, 7, 35, 1, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 6, 63, 7, 55, 4, 0 }, + { 0, 4, 55, 7, 63, 6, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 1, 35, 7, 79, 13, 0 }, + { 0, 1, 27, 7, 81, 19, 0 } } }, + .ptrn_arr = { { 0x49249249, 0x2492 } }, + .sample_patrn_length = 50, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 69) = 0.316832 */ + .hor_phase_arr = { + .even = { { 1, 23, 80, 7, 23, 1, 0 }, + { 0, 15, 79, 7, 33, 1, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 5, 62, 7, 57, 4, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 2, 38, 7, 75, 13, 0 }, + { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 18, 80, 7, 29, 1, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 7, 66, 7, 52, 3, 0 }, + { 0, 4, 54, 7, 64, 6, 0 }, + { 0, 2, 42, 7, 74, 10, 0 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 21, 81, 7, 25, 1, 0 }, + { 0, 14, 78, 7, 35, 1, 0 }, + { 0, 8, 70, 7, 47, 3, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 3, 47, 7, 70, 8, 0 }, + { 0, 1, 35, 7, 78, 14, 0 }, + { 0, 1, 25, 7, 81, 21, 0 }, + { 0, 17, 79, 7, 31, 1, 0 }, + { 0, 10, 74, 7, 42, 2, 0 }, + { 0, 6, 64, 7, 54, 4, 0 }, + { 0, 3, 52, 7, 66, 7, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 1, 29, 7, 80, 18, 0 }, + { 0, 20, 80, 7, 27, 1, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 4, 57, 7, 62, 5, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 1, 33, 7, 79, 15, 0 } }, + .odd = { { 0, 19, 80, 7, 28, 1, 0 }, + { 0, 12, 75, 7, 39, 2, 0 }, + { 0, 7, 67, 7, 51, 3, 0 }, + { 0, 4, 56, 7, 62, 6, 0 }, + { 0, 2, 44, 7, 72, 10, 0 }, + { 0, 1, 32, 7, 79, 16, 0 }, + { 0, 22, 81, 7, 24, 1, 0 }, + { 0, 14, 79, 7, 34, 1, 0 }, + { 0, 9, 71, 7, 46, 2, 0 }, + { 0, 5, 60, 7, 58, 5, 0 }, + { 0, 3, 48, 7, 69, 8, 0 }, + { 0, 1, 36, 7, 78, 13, 0 }, + { 0, 1, 26, 7, 81, 20, 0 }, + { 0, 17, 80, 7, 30, 1, 0 }, + { 0, 11, 74, 7, 41, 2, 0 }, + { 0, 6, 65, 7, 53, 4, 0 }, + { 0, 4, 53, 7, 65, 6, 0 }, + { 0, 2, 41, 7, 74, 11, 0 }, + { 0, 1, 30, 7, 80, 17, 0 }, + { 0, 20, 81, 7, 26, 1, 0 }, + { 0, 13, 78, 7, 36, 1, 0 }, + { 0, 8, 69, 7, 48, 3, 0 }, + { 0, 5, 58, 7, 60, 5, 0 }, + { 0, 2, 46, 7, 71, 9, 0 }, + { 0, 1, 34, 7, 79, 14, 0 }, + { 0, 1, 24, 7, 81, 22, 0 }, + { 0, 16, 79, 7, 32, 1, 0 }, + { 0, 10, 72, 7, 44, 2, 0 }, + { 0, 6, 62, 7, 56, 4, 0 }, + { 0, 3, 51, 7, 67, 7, 0 }, + { 0, 2, 39, 7, 75, 12, 0 }, + { 0, 1, 28, 7, 80, 19, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 23, 80, 7, 23, 1, 0 }, + { 0, 15, 79, 7, 33, 1, 0 }, + { 0, 9, 72, 7, 45, 2, 0 }, + { 0, 5, 62, 7, 57, 4, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 2, 38, 7, 75, 13, 0 }, + { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 18, 80, 7, 29, 1, 0 }, + { 0, 11, 75, 7, 40, 2, 0 }, + { 0, 7, 66, 7, 52, 3, 0 }, + { 0, 4, 54, 7, 64, 6, 0 }, + { 0, 2, 42, 7, 74, 10, 0 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 21, 81, 7, 25, 1, 0 }, + { 0, 14, 78, 7, 35, 1, 0 }, + { 0, 8, 70, 7, 47, 3, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 3, 47, 7, 70, 8, 0 }, + { 0, 1, 35, 7, 78, 14, 0 }, + { 0, 1, 25, 7, 81, 21, 0 }, + { 0, 17, 79, 7, 31, 1, 0 }, + { 0, 10, 74, 7, 42, 2, 0 }, + { 0, 6, 64, 7, 54, 4, 0 }, + { 0, 3, 52, 7, 66, 7, 0 }, + { 0, 2, 40, 7, 75, 11, 0 }, + { 0, 1, 29, 7, 80, 18, 0 }, + { 0, 20, 80, 7, 27, 1, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 4, 57, 7, 62, 5, 0 }, + { 0, 2, 45, 7, 72, 9, 0 }, + { 0, 1, 33, 7, 79, 15, 0 } }, + .odd = { { 0, 19, 80, 7, 28, 1, 0 }, + { 0, 12, 75, 7, 39, 2, 0 }, + { 0, 7, 67, 7, 51, 3, 0 }, + { 0, 4, 56, 7, 62, 6, 0 }, + { 0, 2, 44, 7, 72, 10, 0 }, + { 0, 1, 32, 7, 79, 16, 0 }, + { 0, 22, 81, 7, 24, 1, 0 }, + { 0, 14, 79, 7, 34, 1, 0 }, + { 0, 9, 71, 7, 46, 2, 0 }, + { 0, 5, 60, 7, 58, 5, 0 }, + { 0, 3, 48, 7, 69, 8, 0 }, + { 0, 1, 36, 7, 78, 13, 0 }, + { 0, 1, 26, 7, 81, 20, 0 }, + { 0, 17, 80, 7, 30, 1, 0 }, + { 0, 11, 74, 7, 41, 2, 0 }, + { 0, 6, 65, 7, 53, 4, 0 }, + { 0, 4, 53, 7, 65, 6, 0 }, + { 0, 2, 41, 7, 74, 11, 0 }, + { 0, 1, 30, 7, 80, 17, 0 }, + { 0, 20, 81, 7, 26, 1, 0 }, + { 0, 13, 78, 7, 36, 1, 0 }, + { 0, 8, 69, 7, 48, 3, 0 }, + { 0, 5, 58, 7, 60, 5, 0 }, + { 0, 2, 46, 7, 71, 9, 0 }, + { 0, 1, 34, 7, 79, 14, 0 }, + { 0, 1, 24, 7, 81, 22, 0 }, + { 0, 16, 79, 7, 32, 1, 0 }, + { 0, 10, 72, 7, 44, 2, 0 }, + { 0, 6, 62, 7, 56, 4, 0 }, + { 0, 3, 51, 7, 67, 7, 0 }, + { 0, 2, 39, 7, 75, 12, 0 }, + { 0, 1, 28, 7, 80, 19, 0 } } }, + .ptrn_arr = { { 0x49249249, 0x49249212, 0x49242492, 0x48492492, + 0x92492492, 0x92492490, 0x24 } }, + .sample_patrn_length = 202, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 70) = 0.313725 */ + .hor_phase_arr = { + .even = { { 1, 23, 80, 7, 23, 1, 0 }, + { 0, 14, 77, 7, 36, 1, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 4, 54, 7, 64, 6, 0 }, + { 0, 2, 40, 7, 74, 12, 0 }, + { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 17, 79, 7, 31, 1, 0 }, + { 0, 10, 71, 7, 45, 2, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 2, 45, 7, 71, 10, 0 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 20, 80, 7, 27, 1, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 6, 64, 7, 54, 4, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 1, 36, 7, 77, 14, 0 } }, + .odd = { { 0, 18, 80, 7, 29, 1, 0 }, + { 0, 11, 73, 7, 42, 2, 0 }, + { 0, 6, 61, 7, 57, 4, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 1, 33, 7, 79, 15, 0 }, + { 0, 22, 80, 7, 25, 1, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 7, 65, 7, 52, 4, 0 }, + { 0, 4, 52, 7, 65, 7, 0 }, + { 0, 2, 38, 7, 75, 13, 0 }, + { 0, 1, 25, 7, 80, 22, 0 }, + { 0, 15, 79, 7, 33, 1, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 4, 57, 7, 61, 6, 0 }, + { 0, 2, 42, 7, 73, 11, 0 }, + { 0, 1, 29, 7, 80, 18, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 23, 80, 7, 23, 1, 0 }, + { 0, 14, 77, 7, 36, 1, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 4, 54, 7, 64, 6, 0 }, + { 0, 2, 40, 7, 74, 12, 0 }, + { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 17, 79, 7, 31, 1, 0 }, + { 0, 10, 71, 7, 45, 2, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 2, 45, 7, 71, 10, 0 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 20, 80, 7, 27, 1, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 6, 64, 7, 54, 4, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 1, 36, 7, 77, 14, 0 } }, + .odd = { { 0, 18, 80, 7, 29, 1, 0 }, + { 0, 11, 73, 7, 42, 2, 0 }, + { 0, 6, 61, 7, 57, 4, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 1, 33, 7, 79, 15, 0 }, + { 0, 22, 80, 7, 25, 1, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 7, 65, 7, 52, 4, 0 }, + { 0, 4, 52, 7, 65, 7, 0 }, + { 0, 2, 38, 7, 75, 13, 0 }, + { 0, 1, 25, 7, 80, 22, 0 }, + { 0, 15, 79, 7, 33, 1, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 4, 57, 7, 61, 6, 0 }, + { 0, 2, 42, 7, 73, 11, 0 }, + { 0, 1, 29, 7, 80, 18, 0 } } }, + .ptrn_arr = { { 0x49249249, 0x49249248, 0x49249242, 0x2 } }, + .sample_patrn_length = 102, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 71) = 0.31068 */ + .hor_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 7, 63, 7, 54, 4, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 19, 79, 7, 29, 1, 0 }, + { 0, 10, 70, 7, 45, 3, 0 }, + { 0, 5, 56, 7, 61, 6, 0 }, + { 0, 2, 40, 7, 74, 12, 0 }, + { 0, 1, 26, 7, 78, 22, 1 }, + { 0, 14, 76, 7, 36, 2, 0 }, + { 0, 7, 65, 7, 52, 4, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 1, 34, 7, 77, 16, 0 }, + { 0, 20, 80, 7, 27, 1, 0 }, + { 0, 11, 72, 7, 43, 2, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 2, 43, 7, 72, 11, 0 }, + { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 16, 77, 7, 34, 1, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 4, 52, 7, 65, 7, 0 }, + { 0, 2, 36, 7, 76, 14, 0 }, + { 1, 22, 78, 7, 26, 1, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 6, 61, 7, 56, 5, 0 }, + { 0, 3, 45, 7, 70, 10, 0 }, + { 0, 1, 29, 7, 79, 19, 0 }, + { 0, 17, 79, 7, 31, 1, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 4, 54, 7, 63, 7, 0 }, + { 0, 2, 38, 7, 75, 13, 0 } }, + .odd = { { 0, 18, 79, 7, 30, 1, 0 }, + { 0, 9, 70, 7, 46, 3, 0 }, + { 0, 4, 55, 7, 63, 6, 0 }, + { 0, 2, 39, 7, 74, 13, 0 }, + { 0, 1, 25, 7, 78, 23, 1 }, + { 0, 14, 75, 7, 37, 2, 0 }, + { 0, 7, 64, 7, 53, 4, 0 }, + { 0, 3, 48, 7, 68, 9, 0 }, + { 0, 1, 33, 7, 77, 17, 0 }, + { 0, 20, 79, 7, 28, 1, 0 }, + { 0, 10, 72, 7, 44, 2, 0 }, + { 0, 5, 58, 7, 59, 6, 0 }, + { 0, 2, 41, 7, 74, 11, 0 }, + { 0, 1, 26, 7, 79, 21, 1 }, + { 0, 15, 77, 7, 35, 1, 0 }, + { 0, 8, 66, 7, 51, 3, 0 }, + { 0, 3, 51, 7, 66, 8, 0 }, + { 0, 1, 35, 7, 77, 15, 0 }, + { 1, 21, 79, 7, 26, 1, 0 }, + { 0, 11, 74, 7, 41, 2, 0 }, + { 0, 6, 59, 7, 58, 5, 0 }, + { 0, 2, 44, 7, 72, 10, 0 }, + { 0, 1, 28, 7, 79, 20, 0 }, + { 0, 17, 77, 7, 33, 1, 0 }, + { 0, 9, 68, 7, 48, 3, 0 }, + { 0, 4, 53, 7, 64, 7, 0 }, + { 0, 2, 37, 7, 75, 14, 0 }, + { 1, 23, 78, 7, 25, 1, 0 }, + { 0, 13, 74, 7, 39, 2, 0 }, + { 0, 6, 63, 7, 55, 4, 0 }, + { 0, 3, 46, 7, 70, 9, 0 }, + { 0, 1, 30, 7, 79, 18, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 13, 75, 7, 38, 2, 0 }, + { 0, 7, 63, 7, 54, 4, 0 }, + { 0, 3, 47, 7, 69, 9, 0 }, + { 0, 1, 31, 7, 79, 17, 0 }, + { 0, 19, 79, 7, 29, 1, 0 }, + { 0, 10, 70, 7, 45, 3, 0 }, + { 0, 5, 56, 7, 61, 6, 0 }, + { 0, 2, 40, 7, 74, 12, 0 }, + { 0, 1, 26, 7, 78, 22, 1 }, + { 0, 14, 76, 7, 36, 2, 0 }, + { 0, 7, 65, 7, 52, 4, 0 }, + { 0, 3, 50, 7, 67, 8, 0 }, + { 0, 1, 34, 7, 77, 16, 0 }, + { 0, 20, 80, 7, 27, 1, 0 }, + { 0, 11, 72, 7, 43, 2, 0 }, + { 0, 5, 59, 7, 59, 5, 0 }, + { 0, 2, 43, 7, 72, 11, 0 }, + { 0, 1, 27, 7, 80, 20, 0 }, + { 0, 16, 77, 7, 34, 1, 0 }, + { 0, 8, 67, 7, 50, 3, 0 }, + { 0, 4, 52, 7, 65, 7, 0 }, + { 0, 2, 36, 7, 76, 14, 0 }, + { 1, 22, 78, 7, 26, 1, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 6, 61, 7, 56, 5, 0 }, + { 0, 3, 45, 7, 70, 10, 0 }, + { 0, 1, 29, 7, 79, 19, 0 }, + { 0, 17, 79, 7, 31, 1, 0 }, + { 0, 9, 69, 7, 47, 3, 0 }, + { 0, 4, 54, 7, 63, 7, 0 }, + { 0, 2, 38, 7, 75, 13, 0 } }, + .odd = { { 0, 18, 79, 7, 30, 1, 0 }, + { 0, 9, 70, 7, 46, 3, 0 }, + { 0, 4, 55, 7, 63, 6, 0 }, + { 0, 2, 39, 7, 74, 13, 0 }, + { 0, 1, 25, 7, 78, 23, 1 }, + { 0, 14, 75, 7, 37, 2, 0 }, + { 0, 7, 64, 7, 53, 4, 0 }, + { 0, 3, 48, 7, 68, 9, 0 }, + { 0, 1, 33, 7, 77, 17, 0 }, + { 0, 20, 79, 7, 28, 1, 0 }, + { 0, 10, 72, 7, 44, 2, 0 }, + { 0, 5, 58, 7, 59, 6, 0 }, + { 0, 2, 41, 7, 74, 11, 0 }, + { 0, 1, 26, 7, 79, 21, 1 }, + { 0, 15, 77, 7, 35, 1, 0 }, + { 0, 8, 66, 7, 51, 3, 0 }, + { 0, 3, 51, 7, 66, 8, 0 }, + { 0, 1, 35, 7, 77, 15, 0 }, + { 1, 21, 79, 7, 26, 1, 0 }, + { 0, 11, 74, 7, 41, 2, 0 }, + { 0, 6, 59, 7, 58, 5, 0 }, + { 0, 2, 44, 7, 72, 10, 0 }, + { 0, 1, 28, 7, 79, 20, 0 }, + { 0, 17, 77, 7, 33, 1, 0 }, + { 0, 9, 68, 7, 48, 3, 0 }, + { 0, 4, 53, 7, 64, 7, 0 }, + { 0, 2, 37, 7, 75, 14, 0 }, + { 1, 23, 78, 7, 25, 1, 0 }, + { 0, 13, 74, 7, 39, 2, 0 }, + { 0, 6, 63, 7, 55, 4, 0 }, + { 0, 3, 46, 7, 70, 9, 0 }, + { 0, 1, 30, 7, 79, 18, 0 } } }, + .ptrn_arr = { { 0x9249249, 0x21249249, 0x24249249, 0x24849249, + 0x24909249, 0x24921249, 0x249 } }, + .sample_patrn_length = 206, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 72) = 0.307692 */ + .hor_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 5, 60, 7, 58, 5, 0 }, + { 0, 2, 40, 7, 74, 12, 0 } }, + .odd = { { 0, 18, 77, 7, 32, 1, 0 }, + { 0, 8, 68, 7, 49, 3, 0 }, + { 0, 3, 49, 7, 68, 8, 0 }, + { 0, 1, 32, 7, 77, 18, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 12, 74, 7, 40, 2, 0 }, + { 0, 5, 60, 7, 58, 5, 0 }, + { 0, 2, 40, 7, 74, 12, 0 } }, + .odd = { { 0, 18, 77, 7, 32, 1, 0 }, + { 0, 8, 68, 7, 49, 3, 0 }, + { 0, 3, 49, 7, 68, 8, 0 }, + { 0, 1, 32, 7, 77, 18, 0 } } }, + .ptrn_arr = { { 0x249249 } }, + .sample_patrn_length = 26, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 73) = 0.304762 */ + .hor_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 12, 70, 7, 43, 3, 0 }, + { 0, 5, 54, 7, 62, 7, 0 }, + { 0, 2, 34, 7, 76, 16, 0 }, + { 0, 18, 77, 7, 32, 1, 0 }, + { 0, 8, 64, 7, 52, 4, 0 }, + { 0, 3, 45, 7, 69, 11, 0 }, + { 0, 1, 26, 7, 77, 23, 1 }, + { 0, 13, 73, 7, 40, 2, 0 }, + { 0, 5, 56, 7, 61, 6, 0 }, + { 0, 2, 36, 7, 75, 15, 0 }, + { 0, 19, 78, 7, 30, 1, 0 }, + { 0, 9, 66, 7, 49, 4, 0 }, + { 0, 3, 47, 7, 68, 10, 0 }, + { 0, 1, 28, 7, 77, 21, 1 }, + { 0, 14, 74, 7, 38, 2, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 2, 38, 7, 74, 14, 0 }, + { 1, 21, 77, 7, 28, 1, 0 }, + { 0, 10, 68, 7, 47, 3, 0 }, + { 0, 4, 49, 7, 66, 9, 0 }, + { 0, 1, 30, 7, 78, 19, 0 }, + { 0, 15, 75, 7, 36, 2, 0 }, + { 0, 6, 61, 7, 56, 5, 0 }, + { 0, 2, 40, 7, 73, 13, 0 }, + { 1, 23, 77, 7, 26, 1, 0 }, + { 0, 11, 69, 7, 45, 3, 0 }, + { 0, 4, 52, 7, 64, 8, 0 }, + { 0, 1, 32, 7, 77, 18, 0 }, + { 0, 16, 76, 7, 34, 2, 0 }, + { 0, 7, 62, 7, 54, 5, 0 }, + { 0, 3, 43, 7, 70, 12, 0 } }, + .odd = { { 0, 17, 77, 7, 33, 1, 0 }, + { 0, 7, 64, 7, 53, 4, 0 }, + { 0, 3, 44, 7, 70, 11, 0 }, + { 0, 1, 25, 7, 78, 23, 1 }, + { 0, 12, 72, 7, 42, 2, 0 }, + { 0, 5, 55, 7, 61, 7, 0 }, + { 0, 2, 35, 7, 75, 16, 0 }, + { 0, 19, 77, 7, 31, 1, 0 }, + { 0, 8, 65, 7, 51, 4, 0 }, + { 0, 3, 46, 7, 69, 10, 0 }, + { 0, 1, 27, 7, 77, 22, 1 }, + { 0, 13, 74, 7, 39, 2, 0 }, + { 0, 5, 57, 7, 60, 6, 0 }, + { 0, 2, 37, 7, 75, 14, 0 }, + { 1, 20, 77, 7, 29, 1, 0 }, + { 0, 9, 68, 7, 48, 3, 0 }, + { 0, 3, 48, 7, 68, 9, 0 }, + { 0, 1, 29, 7, 77, 20, 1 }, + { 0, 14, 75, 7, 37, 2, 0 }, + { 0, 6, 60, 7, 57, 5, 0 }, + { 0, 2, 39, 7, 74, 13, 0 }, + { 1, 22, 77, 7, 27, 1, 0 }, + { 0, 10, 69, 7, 46, 3, 0 }, + { 0, 4, 51, 7, 65, 8, 0 }, + { 0, 1, 31, 7, 77, 19, 0 }, + { 0, 16, 75, 7, 35, 2, 0 }, + { 0, 7, 61, 7, 55, 5, 0 }, + { 0, 2, 42, 7, 72, 12, 0 }, + { 1, 23, 78, 7, 25, 1, 0 }, + { 0, 11, 70, 7, 44, 3, 0 }, + { 0, 4, 53, 7, 64, 7, 0 }, + { 0, 1, 33, 7, 77, 17, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 24, 78, 7, 24, 1, 0 }, + { 0, 12, 70, 7, 43, 3, 0 }, + { 0, 5, 54, 7, 62, 7, 0 }, + { 0, 2, 34, 7, 76, 16, 0 }, + { 0, 18, 77, 7, 32, 1, 0 }, + { 0, 8, 64, 7, 52, 4, 0 }, + { 0, 3, 45, 7, 69, 11, 0 }, + { 0, 1, 26, 7, 77, 23, 1 }, + { 0, 13, 73, 7, 40, 2, 0 }, + { 0, 5, 56, 7, 61, 6, 0 }, + { 0, 2, 36, 7, 75, 15, 0 }, + { 0, 19, 78, 7, 30, 1, 0 }, + { 0, 9, 66, 7, 49, 4, 0 }, + { 0, 3, 47, 7, 68, 10, 0 }, + { 0, 1, 28, 7, 77, 21, 1 }, + { 0, 14, 74, 7, 38, 2, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 2, 38, 7, 74, 14, 0 }, + { 1, 21, 77, 7, 28, 1, 0 }, + { 0, 10, 68, 7, 47, 3, 0 }, + { 0, 4, 49, 7, 66, 9, 0 }, + { 0, 1, 30, 7, 78, 19, 0 }, + { 0, 15, 75, 7, 36, 2, 0 }, + { 0, 6, 61, 7, 56, 5, 0 }, + { 0, 2, 40, 7, 73, 13, 0 }, + { 1, 23, 77, 7, 26, 1, 0 }, + { 0, 11, 69, 7, 45, 3, 0 }, + { 0, 4, 52, 7, 64, 8, 0 }, + { 0, 1, 32, 7, 77, 18, 0 }, + { 0, 16, 76, 7, 34, 2, 0 }, + { 0, 7, 62, 7, 54, 5, 0 }, + { 0, 3, 43, 7, 70, 12, 0 } }, + .odd = { { 0, 17, 77, 7, 33, 1, 0 }, + { 0, 7, 64, 7, 53, 4, 0 }, + { 0, 3, 44, 7, 70, 11, 0 }, + { 0, 1, 25, 7, 78, 23, 1 }, + { 0, 12, 72, 7, 42, 2, 0 }, + { 0, 5, 55, 7, 61, 7, 0 }, + { 0, 2, 35, 7, 75, 16, 0 }, + { 0, 19, 77, 7, 31, 1, 0 }, + { 0, 8, 65, 7, 51, 4, 0 }, + { 0, 3, 46, 7, 69, 10, 0 }, + { 0, 1, 27, 7, 77, 22, 1 }, + { 0, 13, 74, 7, 39, 2, 0 }, + { 0, 5, 57, 7, 60, 6, 0 }, + { 0, 2, 37, 7, 75, 14, 0 }, + { 1, 20, 77, 7, 29, 1, 0 }, + { 0, 9, 68, 7, 48, 3, 0 }, + { 0, 3, 48, 7, 68, 9, 0 }, + { 0, 1, 29, 7, 77, 20, 1 }, + { 0, 14, 75, 7, 37, 2, 0 }, + { 0, 6, 60, 7, 57, 5, 0 }, + { 0, 2, 39, 7, 74, 13, 0 }, + { 1, 22, 77, 7, 27, 1, 0 }, + { 0, 10, 69, 7, 46, 3, 0 }, + { 0, 4, 51, 7, 65, 8, 0 }, + { 0, 1, 31, 7, 77, 19, 0 }, + { 0, 16, 75, 7, 35, 2, 0 }, + { 0, 7, 61, 7, 55, 5, 0 }, + { 0, 2, 42, 7, 72, 12, 0 }, + { 1, 23, 78, 7, 25, 1, 0 }, + { 0, 11, 70, 7, 44, 3, 0 }, + { 0, 4, 53, 7, 64, 7, 0 }, + { 0, 1, 33, 7, 77, 17, 0 } } }, + .ptrn_arr = { { 0x24249249, 0x24921249, 0x84924909, 0x92424924, + 0x92492124, 0x48492490, 0x2492 } }, + .sample_patrn_length = 210, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 74) = 0.301887 */ + .hor_phase_arr = { + .even = { { 1, 25, 76, 7, 25, 1, 0 }, + { 0, 11, 69, 7, 45, 3, 0 }, + { 0, 4, 49, 7, 66, 9, 0 }, + { 0, 1, 28, 7, 77, 21, 1 }, + { 0, 13, 72, 7, 41, 2, 0 }, + { 0, 5, 54, 7, 62, 7, 0 }, + { 0, 1, 32, 7, 77, 18, 0 }, + { 0, 15, 75, 7, 36, 2, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 2, 36, 7, 75, 15, 0 }, + { 0, 18, 77, 7, 32, 1, 0 }, + { 0, 7, 62, 7, 54, 5, 0 }, + { 0, 2, 41, 7, 72, 13, 0 }, + { 1, 21, 77, 7, 28, 1, 0 }, + { 0, 9, 66, 7, 49, 4, 0 }, + { 0, 3, 45, 7, 69, 11, 0 } }, + .odd = { { 0, 17, 75, 7, 34, 2, 0 }, + { 0, 7, 60, 7, 56, 5, 0 }, + { 0, 2, 38, 7, 74, 14, 0 }, + { 1, 20, 76, 7, 30, 1, 0 }, + { 0, 8, 64, 7, 52, 4, 0 }, + { 0, 3, 43, 7, 70, 12, 0 }, + { 1, 23, 77, 7, 26, 1, 0 }, + { 0, 10, 68, 7, 47, 3, 0 }, + { 0, 3, 47, 7, 68, 10, 0 }, + { 0, 1, 26, 7, 77, 23, 1 }, + { 0, 12, 70, 7, 43, 3, 0 }, + { 0, 4, 52, 7, 64, 8, 0 }, + { 0, 1, 30, 7, 76, 20, 1 }, + { 0, 14, 74, 7, 38, 2, 0 }, + { 0, 5, 56, 7, 60, 7, 0 }, + { 0, 2, 34, 7, 75, 17, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 25, 76, 7, 25, 1, 0 }, + { 0, 11, 69, 7, 45, 3, 0 }, + { 0, 4, 49, 7, 66, 9, 0 }, + { 0, 1, 28, 7, 77, 21, 1 }, + { 0, 13, 72, 7, 41, 2, 0 }, + { 0, 5, 54, 7, 62, 7, 0 }, + { 0, 1, 32, 7, 77, 18, 0 }, + { 0, 15, 75, 7, 36, 2, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 2, 36, 7, 75, 15, 0 }, + { 0, 18, 77, 7, 32, 1, 0 }, + { 0, 7, 62, 7, 54, 5, 0 }, + { 0, 2, 41, 7, 72, 13, 0 }, + { 1, 21, 77, 7, 28, 1, 0 }, + { 0, 9, 66, 7, 49, 4, 0 }, + { 0, 3, 45, 7, 69, 11, 0 } }, + .odd = { { 0, 17, 75, 7, 34, 2, 0 }, + { 0, 7, 60, 7, 56, 5, 0 }, + { 0, 2, 38, 7, 74, 14, 0 }, + { 1, 20, 76, 7, 30, 1, 0 }, + { 0, 8, 64, 7, 52, 4, 0 }, + { 0, 3, 43, 7, 70, 12, 0 }, + { 1, 23, 77, 7, 26, 1, 0 }, + { 0, 10, 68, 7, 47, 3, 0 }, + { 0, 3, 47, 7, 68, 10, 0 }, + { 0, 1, 26, 7, 77, 23, 1 }, + { 0, 12, 70, 7, 43, 3, 0 }, + { 0, 4, 52, 7, 64, 8, 0 }, + { 0, 1, 30, 7, 76, 20, 1 }, + { 0, 14, 74, 7, 38, 2, 0 }, + { 0, 5, 56, 7, 60, 7, 0 }, + { 0, 2, 34, 7, 75, 17, 0 } } }, + .ptrn_arr = { { 0x24849249, 0x24924849, 0x92424924, 0x24 } }, + .sample_patrn_length = 106, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 75) = 0.299065 */ + .hor_phase_arr = { + .even = { { 1, 25, 76, 7, 25, 1, 0 }, + { 0, 10, 67, 7, 47, 4, 0 }, + { 0, 3, 45, 7, 69, 11, 0 }, + { 1, 23, 76, 7, 27, 1, 0 }, + { 0, 9, 66, 7, 49, 4, 0 }, + { 0, 3, 43, 7, 70, 12, 0 }, + { 1, 22, 75, 7, 29, 1, 0 }, + { 0, 8, 65, 7, 51, 4, 0 }, + { 0, 2, 41, 7, 72, 13, 0 }, + { 1, 20, 76, 7, 30, 1, 0 }, + { 0, 8, 61, 7, 54, 5, 0 }, + { 0, 2, 39, 7, 72, 15, 0 }, + { 0, 19, 76, 7, 32, 1, 0 }, + { 0, 7, 59, 7, 56, 6, 0 }, + { 0, 2, 36, 7, 74, 16, 0 }, + { 0, 17, 75, 7, 34, 2, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 2, 34, 7, 75, 17, 0 }, + { 0, 16, 74, 7, 36, 2, 0 }, + { 0, 6, 56, 7, 59, 7, 0 }, + { 0, 1, 32, 7, 76, 19, 0 }, + { 0, 15, 72, 7, 39, 2, 0 }, + { 0, 5, 54, 7, 61, 8, 0 }, + { 0, 1, 30, 7, 76, 20, 1 }, + { 0, 13, 72, 7, 41, 2, 0 }, + { 0, 4, 51, 7, 65, 8, 0 }, + { 0, 1, 29, 7, 75, 22, 1 }, + { 0, 12, 70, 7, 43, 3, 0 }, + { 0, 4, 49, 7, 66, 9, 0 }, + { 0, 1, 27, 7, 76, 23, 1 }, + { 0, 11, 69, 7, 45, 3, 0 }, + { 0, 4, 47, 7, 67, 10, 0 } }, + .odd = { { 0, 16, 75, 7, 35, 2, 0 }, + { 0, 6, 57, 7, 58, 7, 0 }, + { 0, 2, 33, 7, 75, 18, 0 }, + { 0, 15, 73, 7, 38, 2, 0 }, + { 0, 5, 55, 7, 61, 7, 0 }, + { 0, 1, 31, 7, 76, 19, 1 }, + { 0, 14, 72, 7, 40, 2, 0 }, + { 0, 5, 53, 7, 62, 8, 0 }, + { 0, 1, 30, 7, 75, 21, 1 }, + { 0, 13, 70, 7, 42, 3, 0 }, + { 0, 4, 50, 7, 65, 9, 0 }, + { 0, 1, 28, 7, 76, 22, 1 }, + { 0, 12, 69, 7, 44, 3, 0 }, + { 0, 4, 48, 7, 66, 10, 0 }, + { 0, 1, 26, 7, 76, 24, 1 }, + { 0, 11, 68, 7, 46, 3, 0 }, + { 0, 3, 46, 7, 68, 11, 0 }, + { 1, 24, 76, 7, 26, 1, 0 }, + { 0, 10, 66, 7, 48, 4, 0 }, + { 0, 3, 44, 7, 69, 12, 0 }, + { 1, 22, 76, 7, 28, 1, 0 }, + { 0, 9, 65, 7, 50, 4, 0 }, + { 0, 3, 42, 7, 70, 13, 0 }, + { 1, 21, 75, 7, 30, 1, 0 }, + { 0, 8, 62, 7, 53, 5, 0 }, + { 0, 2, 40, 7, 72, 14, 0 }, + { 1, 19, 76, 7, 31, 1, 0 }, + { 0, 7, 61, 7, 55, 5, 0 }, + { 0, 2, 38, 7, 73, 15, 0 }, + { 0, 18, 75, 7, 33, 2, 0 }, + { 0, 7, 58, 7, 57, 6, 0 }, + { 0, 2, 35, 7, 75, 16, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 25, 76, 7, 25, 1, 0 }, + { 0, 10, 67, 7, 47, 4, 0 }, + { 0, 3, 45, 7, 69, 11, 0 }, + { 1, 23, 76, 7, 27, 1, 0 }, + { 0, 9, 66, 7, 49, 4, 0 }, + { 0, 3, 43, 7, 70, 12, 0 }, + { 1, 22, 75, 7, 29, 1, 0 }, + { 0, 8, 65, 7, 51, 4, 0 }, + { 0, 2, 41, 7, 72, 13, 0 }, + { 1, 20, 76, 7, 30, 1, 0 }, + { 0, 8, 61, 7, 54, 5, 0 }, + { 0, 2, 39, 7, 72, 15, 0 }, + { 0, 19, 76, 7, 32, 1, 0 }, + { 0, 7, 59, 7, 56, 6, 0 }, + { 0, 2, 36, 7, 74, 16, 0 }, + { 0, 17, 75, 7, 34, 2, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 2, 34, 7, 75, 17, 0 }, + { 0, 16, 74, 7, 36, 2, 0 }, + { 0, 6, 56, 7, 59, 7, 0 }, + { 0, 1, 32, 7, 76, 19, 0 }, + { 0, 15, 72, 7, 39, 2, 0 }, + { 0, 5, 54, 7, 61, 8, 0 }, + { 0, 1, 30, 7, 76, 20, 1 }, + { 0, 13, 72, 7, 41, 2, 0 }, + { 0, 4, 51, 7, 65, 8, 0 }, + { 0, 1, 29, 7, 75, 22, 1 }, + { 0, 12, 70, 7, 43, 3, 0 }, + { 0, 4, 49, 7, 66, 9, 0 }, + { 0, 1, 27, 7, 76, 23, 1 }, + { 0, 11, 69, 7, 45, 3, 0 }, + { 0, 4, 47, 7, 67, 10, 0 } }, + .odd = { { 0, 16, 75, 7, 35, 2, 0 }, + { 0, 6, 57, 7, 58, 7, 0 }, + { 0, 2, 33, 7, 75, 18, 0 }, + { 0, 15, 73, 7, 38, 2, 0 }, + { 0, 5, 55, 7, 61, 7, 0 }, + { 0, 1, 31, 7, 76, 19, 1 }, + { 0, 14, 72, 7, 40, 2, 0 }, + { 0, 5, 53, 7, 62, 8, 0 }, + { 0, 1, 30, 7, 75, 21, 1 }, + { 0, 13, 70, 7, 42, 3, 0 }, + { 0, 4, 50, 7, 65, 9, 0 }, + { 0, 1, 28, 7, 76, 22, 1 }, + { 0, 12, 69, 7, 44, 3, 0 }, + { 0, 4, 48, 7, 66, 10, 0 }, + { 0, 1, 26, 7, 76, 24, 1 }, + { 0, 11, 68, 7, 46, 3, 0 }, + { 0, 3, 46, 7, 68, 11, 0 }, + { 1, 24, 76, 7, 26, 1, 0 }, + { 0, 10, 66, 7, 48, 4, 0 }, + { 0, 3, 44, 7, 69, 12, 0 }, + { 1, 22, 76, 7, 28, 1, 0 }, + { 0, 9, 65, 7, 50, 4, 0 }, + { 0, 3, 42, 7, 70, 13, 0 }, + { 1, 21, 75, 7, 30, 1, 0 }, + { 0, 8, 62, 7, 53, 5, 0 }, + { 0, 2, 40, 7, 72, 14, 0 }, + { 1, 19, 76, 7, 31, 1, 0 }, + { 0, 7, 61, 7, 55, 5, 0 }, + { 0, 2, 38, 7, 73, 15, 0 }, + { 0, 18, 75, 7, 33, 2, 0 }, + { 0, 7, 58, 7, 57, 6, 0 }, + { 0, 2, 35, 7, 75, 16, 0 } } }, + .ptrn_arr = { { 0x24909249, 0x90924909, 0x92490924, 0x49212490, + 0x21249212, 0x24921249, 0x24921 } }, + .sample_patrn_length = 214, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 76) = 0.296296 */ + .hor_phase_arr = { + .even = { { 1, 25, 76, 7, 25, 1, 0 }, + { 0, 10, 65, 7, 49, 4, 0 }, + { 0, 3, 41, 7, 70, 14, 0 }, + { 1, 19, 73, 7, 33, 2, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 2, 33, 7, 73, 19, 1 }, + { 0, 14, 70, 7, 41, 3, 0 }, + { 0, 4, 49, 7, 65, 10, 0 } }, + .odd = { { 0, 16, 73, 7, 37, 2, 0 }, + { 0, 5, 53, 7, 62, 8, 0 }, + { 0, 1, 29, 7, 75, 22, 1 }, + { 0, 11, 69, 7, 45, 3, 0 }, + { 0, 3, 45, 7, 69, 11, 0 }, + { 1, 22, 75, 7, 29, 1, 0 }, + { 0, 8, 62, 7, 53, 5, 0 }, + { 0, 2, 37, 7, 73, 16, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 25, 76, 7, 25, 1, 0 }, + { 0, 10, 65, 7, 49, 4, 0 }, + { 0, 3, 41, 7, 70, 14, 0 }, + { 1, 19, 73, 7, 33, 2, 0 }, + { 0, 6, 58, 7, 58, 6, 0 }, + { 0, 2, 33, 7, 73, 19, 1 }, + { 0, 14, 70, 7, 41, 3, 0 }, + { 0, 4, 49, 7, 65, 10, 0 } }, + .odd = { { 0, 16, 73, 7, 37, 2, 0 }, + { 0, 5, 53, 7, 62, 8, 0 }, + { 0, 1, 29, 7, 75, 22, 1 }, + { 0, 11, 69, 7, 45, 3, 0 }, + { 0, 3, 45, 7, 69, 11, 0 }, + { 1, 22, 75, 7, 29, 1, 0 }, + { 0, 8, 62, 7, 53, 5, 0 }, + { 0, 2, 37, 7, 73, 16, 0 } } }, + .ptrn_arr = { { 0x24909249, 0x24921 } }, + .sample_patrn_length = 54, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 77) = 0.293578 */ + .hor_phase_arr = { + .even = { { 1, 26, 74, 7, 26, 1, 0 }, + { 0, 9, 63, 7, 51, 5, 0 }, + { 0, 2, 37, 7, 73, 16, 0 }, + { 0, 15, 72, 7, 39, 2, 0 }, + { 0, 4, 49, 7, 65, 10, 0 }, + { 1, 24, 75, 7, 27, 1, 0 }, + { 0, 8, 62, 7, 53, 5, 0 }, + { 0, 2, 35, 7, 72, 18, 1 }, + { 0, 14, 70, 7, 41, 3, 0 }, + { 0, 4, 47, 7, 66, 11, 0 }, + { 1, 22, 75, 7, 29, 1, 0 }, + { 0, 7, 60, 7, 55, 6, 0 }, + { 0, 2, 33, 7, 73, 19, 1 }, + { 0, 13, 69, 7, 43, 3, 0 }, + { 0, 3, 45, 7, 68, 12, 0 }, + { 1, 21, 74, 7, 31, 1, 0 }, + { 0, 7, 57, 7, 57, 7, 0 }, + { 0, 1, 31, 7, 74, 21, 1 }, + { 0, 12, 68, 7, 45, 3, 0 }, + { 0, 3, 43, 7, 69, 13, 0 }, + { 1, 19, 73, 7, 33, 2, 0 }, + { 0, 6, 55, 7, 60, 7, 0 }, + { 0, 1, 29, 7, 75, 22, 1 }, + { 0, 11, 66, 7, 47, 4, 0 }, + { 0, 3, 41, 7, 70, 14, 0 }, + { 1, 18, 72, 7, 35, 2, 0 }, + { 0, 5, 53, 7, 62, 8, 0 }, + { 0, 1, 27, 7, 75, 24, 1 }, + { 0, 10, 65, 7, 49, 4, 0 }, + { 0, 2, 39, 7, 72, 15, 0 }, + { 0, 16, 73, 7, 37, 2, 0 }, + { 0, 5, 51, 7, 63, 9, 0 } }, + .odd = { { 0, 16, 72, 7, 38, 2, 0 }, + { 0, 5, 50, 7, 64, 9, 0 }, + { 1, 25, 75, 7, 26, 1, 0 }, + { 0, 8, 63, 7, 52, 5, 0 }, + { 0, 2, 36, 7, 73, 17, 0 }, + { 0, 15, 70, 7, 40, 3, 0 }, + { 0, 4, 48, 7, 66, 10, 0 }, + { 1, 23, 75, 7, 28, 1, 0 }, + { 0, 8, 60, 7, 54, 6, 0 }, + { 0, 2, 34, 7, 73, 18, 1 }, + { 0, 13, 70, 7, 42, 3, 0 }, + { 0, 4, 46, 7, 67, 11, 0 }, + { 1, 21, 75, 7, 30, 1, 0 }, + { 0, 7, 59, 7, 56, 6, 0 }, + { 0, 2, 32, 7, 73, 20, 1 }, + { 0, 12, 69, 7, 44, 3, 0 }, + { 0, 3, 44, 7, 69, 12, 0 }, + { 1, 20, 73, 7, 32, 2, 0 }, + { 0, 6, 56, 7, 59, 7, 0 }, + { 0, 1, 30, 7, 75, 21, 1 }, + { 0, 11, 67, 7, 46, 4, 0 }, + { 0, 3, 42, 7, 70, 13, 0 }, + { 1, 18, 73, 7, 34, 2, 0 }, + { 0, 6, 54, 7, 60, 8, 0 }, + { 0, 1, 28, 7, 75, 23, 1 }, + { 0, 10, 66, 7, 48, 4, 0 }, + { 0, 3, 40, 7, 70, 15, 0 }, + { 0, 17, 73, 7, 36, 2, 0 }, + { 0, 5, 52, 7, 63, 8, 0 }, + { 0, 1, 26, 7, 75, 25, 1 }, + { 0, 9, 64, 7, 50, 5, 0 }, + { 0, 2, 38, 7, 72, 16, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 26, 74, 7, 26, 1, 0 }, + { 0, 9, 63, 7, 51, 5, 0 }, + { 0, 2, 37, 7, 73, 16, 0 }, + { 0, 15, 72, 7, 39, 2, 0 }, + { 0, 4, 49, 7, 65, 10, 0 }, + { 1, 24, 75, 7, 27, 1, 0 }, + { 0, 8, 62, 7, 53, 5, 0 }, + { 0, 2, 35, 7, 72, 18, 1 }, + { 0, 14, 70, 7, 41, 3, 0 }, + { 0, 4, 47, 7, 66, 11, 0 }, + { 1, 22, 75, 7, 29, 1, 0 }, + { 0, 7, 60, 7, 55, 6, 0 }, + { 0, 2, 33, 7, 73, 19, 1 }, + { 0, 13, 69, 7, 43, 3, 0 }, + { 0, 3, 45, 7, 68, 12, 0 }, + { 1, 21, 74, 7, 31, 1, 0 }, + { 0, 7, 57, 7, 57, 7, 0 }, + { 0, 1, 31, 7, 74, 21, 1 }, + { 0, 12, 68, 7, 45, 3, 0 }, + { 0, 3, 43, 7, 69, 13, 0 }, + { 1, 19, 73, 7, 33, 2, 0 }, + { 0, 6, 55, 7, 60, 7, 0 }, + { 0, 1, 29, 7, 75, 22, 1 }, + { 0, 11, 66, 7, 47, 4, 0 }, + { 0, 3, 41, 7, 70, 14, 0 }, + { 1, 18, 72, 7, 35, 2, 0 }, + { 0, 5, 53, 7, 62, 8, 0 }, + { 0, 1, 27, 7, 75, 24, 1 }, + { 0, 10, 65, 7, 49, 4, 0 }, + { 0, 2, 39, 7, 72, 15, 0 }, + { 0, 16, 73, 7, 37, 2, 0 }, + { 0, 5, 51, 7, 63, 9, 0 } }, + .odd = { { 0, 16, 72, 7, 38, 2, 0 }, + { 0, 5, 50, 7, 64, 9, 0 }, + { 1, 25, 75, 7, 26, 1, 0 }, + { 0, 8, 63, 7, 52, 5, 0 }, + { 0, 2, 36, 7, 73, 17, 0 }, + { 0, 15, 70, 7, 40, 3, 0 }, + { 0, 4, 48, 7, 66, 10, 0 }, + { 1, 23, 75, 7, 28, 1, 0 }, + { 0, 8, 60, 7, 54, 6, 0 }, + { 0, 2, 34, 7, 73, 18, 1 }, + { 0, 13, 70, 7, 42, 3, 0 }, + { 0, 4, 46, 7, 67, 11, 0 }, + { 1, 21, 75, 7, 30, 1, 0 }, + { 0, 7, 59, 7, 56, 6, 0 }, + { 0, 2, 32, 7, 73, 20, 1 }, + { 0, 12, 69, 7, 44, 3, 0 }, + { 0, 3, 44, 7, 69, 12, 0 }, + { 1, 20, 73, 7, 32, 2, 0 }, + { 0, 6, 56, 7, 59, 7, 0 }, + { 0, 1, 30, 7, 75, 21, 1 }, + { 0, 11, 67, 7, 46, 4, 0 }, + { 0, 3, 42, 7, 70, 13, 0 }, + { 1, 18, 73, 7, 34, 2, 0 }, + { 0, 6, 54, 7, 60, 8, 0 }, + { 0, 1, 28, 7, 75, 23, 1 }, + { 0, 10, 66, 7, 48, 4, 0 }, + { 0, 3, 40, 7, 70, 15, 0 }, + { 0, 17, 73, 7, 36, 2, 0 }, + { 0, 5, 52, 7, 63, 8, 0 }, + { 0, 1, 26, 7, 75, 25, 1 }, + { 0, 9, 64, 7, 50, 5, 0 }, + { 0, 2, 38, 7, 72, 16, 0 } } }, + .ptrn_arr = { { 0x24921249, 0x92484924, 0x49212490, 0x24849242, + 0x92124909, 0x48492424, 0x249092 } }, + .sample_patrn_length = 218, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 78) = 0.290909 */ + .hor_phase_arr = { + .even = { { 1, 26, 74, 7, 26, 1, 0 }, + { 0, 8, 61, 7, 53, 6, 0 }, + { 0, 2, 33, 7, 73, 19, 1 }, + { 0, 12, 67, 7, 45, 4, 0 }, + { 0, 3, 41, 7, 70, 14, 0 }, + { 0, 17, 72, 7, 37, 2, 0 }, + { 0, 5, 49, 7, 64, 10, 0 }, + { 1, 22, 75, 7, 29, 1, 0 }, + { 0, 7, 57, 7, 57, 7, 0 }, + { 0, 1, 29, 7, 75, 22, 1 }, + { 0, 10, 64, 7, 49, 5, 0 }, + { 0, 2, 37, 7, 72, 17, 0 }, + { 0, 14, 70, 7, 41, 3, 0 }, + { 0, 4, 45, 7, 67, 12, 0 }, + { 1, 19, 73, 7, 33, 2, 0 }, + { 0, 6, 53, 7, 61, 8, 0 } }, + .odd = { { 0, 15, 71, 7, 39, 3, 0 }, + { 0, 4, 47, 7, 66, 11, 0 }, + { 1, 21, 73, 7, 31, 2, 0 }, + { 0, 6, 55, 7, 59, 8, 0 }, + { 0, 1, 28, 7, 74, 24, 1 }, + { 0, 9, 63, 7, 51, 5, 0 }, + { 0, 2, 35, 7, 72, 18, 1 }, + { 0, 13, 69, 7, 43, 3, 0 }, + { 0, 3, 43, 7, 69, 13, 0 }, + { 1, 18, 72, 7, 35, 2, 0 }, + { 0, 5, 51, 7, 63, 9, 0 }, + { 1, 24, 74, 7, 28, 1, 0 }, + { 0, 8, 59, 7, 55, 6, 0 }, + { 0, 2, 31, 7, 73, 21, 1 }, + { 0, 11, 66, 7, 47, 4, 0 }, + { 0, 3, 39, 7, 71, 15, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 26, 74, 7, 26, 1, 0 }, + { 0, 8, 61, 7, 53, 6, 0 }, + { 0, 2, 33, 7, 73, 19, 1 }, + { 0, 12, 67, 7, 45, 4, 0 }, + { 0, 3, 41, 7, 70, 14, 0 }, + { 0, 17, 72, 7, 37, 2, 0 }, + { 0, 5, 49, 7, 64, 10, 0 }, + { 1, 22, 75, 7, 29, 1, 0 }, + { 0, 7, 57, 7, 57, 7, 0 }, + { 0, 1, 29, 7, 75, 22, 1 }, + { 0, 10, 64, 7, 49, 5, 0 }, + { 0, 2, 37, 7, 72, 17, 0 }, + { 0, 14, 70, 7, 41, 3, 0 }, + { 0, 4, 45, 7, 67, 12, 0 }, + { 1, 19, 73, 7, 33, 2, 0 }, + { 0, 6, 53, 7, 61, 8, 0 } }, + .odd = { { 0, 15, 71, 7, 39, 3, 0 }, + { 0, 4, 47, 7, 66, 11, 0 }, + { 1, 21, 73, 7, 31, 2, 0 }, + { 0, 6, 55, 7, 59, 8, 0 }, + { 0, 1, 28, 7, 74, 24, 1 }, + { 0, 9, 63, 7, 51, 5, 0 }, + { 0, 2, 35, 7, 72, 18, 1 }, + { 0, 13, 69, 7, 43, 3, 0 }, + { 0, 3, 43, 7, 69, 13, 0 }, + { 1, 18, 72, 7, 35, 2, 0 }, + { 0, 5, 51, 7, 63, 9, 0 }, + { 1, 24, 74, 7, 28, 1, 0 }, + { 0, 8, 59, 7, 55, 6, 0 }, + { 0, 2, 31, 7, 73, 21, 1 }, + { 0, 11, 66, 7, 47, 4, 0 }, + { 0, 3, 39, 7, 71, 15, 0 } } }, + .ptrn_arr = { { 0x24921249, 0x12490924, 0x9248492, 0x249 } }, + .sample_patrn_length = 110, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 79) = 0.288288 */ + .hor_phase_arr = { + .even = { { 1, 26, 74, 7, 26, 1, 0 }, + { 0, 8, 59, 7, 55, 6, 0 }, + { 0, 1, 30, 7, 73, 23, 1 }, + { 0, 9, 63, 7, 51, 5, 0 }, + { 0, 2, 33, 7, 72, 20, 1 }, + { 0, 11, 66, 7, 47, 4, 0 }, + { 0, 2, 37, 7, 71, 17, 1 }, + { 0, 13, 69, 7, 43, 3, 0 }, + { 0, 3, 41, 7, 69, 15, 0 }, + { 0, 16, 70, 7, 39, 3, 0 }, + { 0, 4, 45, 7, 67, 12, 0 }, + { 1, 18, 72, 7, 35, 2, 0 }, + { 0, 5, 49, 7, 64, 10, 0 }, + { 1, 21, 73, 7, 31, 2, 0 }, + { 0, 6, 53, 7, 60, 9, 0 }, + { 1, 24, 74, 7, 28, 1, 0 }, + { 0, 7, 57, 7, 57, 7, 0 }, + { 0, 1, 28, 7, 74, 24, 1 }, + { 0, 9, 60, 7, 53, 6, 0 }, + { 0, 2, 31, 7, 73, 21, 1 }, + { 0, 10, 64, 7, 49, 5, 0 }, + { 0, 2, 35, 7, 72, 18, 1 }, + { 0, 12, 67, 7, 45, 4, 0 }, + { 0, 3, 39, 7, 70, 16, 0 }, + { 0, 15, 69, 7, 41, 3, 0 }, + { 0, 3, 43, 7, 69, 13, 0 }, + { 1, 17, 71, 7, 37, 2, 0 }, + { 0, 4, 47, 7, 66, 11, 0 }, + { 1, 20, 72, 7, 33, 2, 0 }, + { 0, 5, 51, 7, 63, 9, 0 }, + { 1, 23, 73, 7, 30, 1, 0 }, + { 0, 6, 55, 7, 59, 8, 0 } }, + .odd = { { 0, 15, 70, 7, 40, 3, 0 }, + { 0, 4, 44, 7, 67, 13, 0 }, + { 1, 18, 71, 7, 36, 2, 0 }, + { 0, 4, 48, 7, 65, 11, 0 }, + { 1, 20, 73, 7, 32, 2, 0 }, + { 0, 6, 52, 7, 61, 9, 0 }, + { 1, 24, 73, 7, 29, 1, 0 }, + { 0, 7, 56, 7, 58, 7, 0 }, + { 0, 1, 27, 7, 74, 25, 1 }, + { 0, 8, 60, 7, 54, 6, 0 }, + { 0, 2, 30, 7, 73, 22, 1 }, + { 0, 10, 63, 7, 50, 5, 0 }, + { 0, 2, 34, 7, 72, 19, 1 }, + { 0, 12, 66, 7, 46, 4, 0 }, + { 0, 3, 38, 7, 71, 16, 0 }, + { 0, 14, 69, 7, 42, 3, 0 }, + { 0, 3, 42, 7, 69, 14, 0 }, + { 0, 16, 71, 7, 38, 3, 0 }, + { 0, 4, 46, 7, 66, 12, 0 }, + { 1, 19, 72, 7, 34, 2, 0 }, + { 0, 5, 50, 7, 63, 10, 0 }, + { 1, 22, 73, 7, 30, 2, 0 }, + { 0, 6, 54, 7, 60, 8, 0 }, + { 1, 25, 74, 7, 27, 1, 0 }, + { 0, 7, 58, 7, 56, 7, 0 }, + { 0, 1, 29, 7, 73, 24, 1 }, + { 0, 9, 61, 7, 52, 6, 0 }, + { 0, 2, 32, 7, 73, 20, 1 }, + { 0, 11, 65, 7, 48, 4, 0 }, + { 0, 2, 36, 7, 71, 18, 1 }, + { 0, 13, 67, 7, 44, 4, 0 }, + { 0, 3, 40, 7, 70, 15, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 26, 74, 7, 26, 1, 0 }, + { 0, 8, 59, 7, 55, 6, 0 }, + { 0, 1, 30, 7, 73, 23, 1 }, + { 0, 9, 63, 7, 51, 5, 0 }, + { 0, 2, 33, 7, 72, 20, 1 }, + { 0, 11, 66, 7, 47, 4, 0 }, + { 0, 2, 37, 7, 71, 17, 1 }, + { 0, 13, 69, 7, 43, 3, 0 }, + { 0, 3, 41, 7, 69, 15, 0 }, + { 0, 16, 70, 7, 39, 3, 0 }, + { 0, 4, 45, 7, 67, 12, 0 }, + { 1, 18, 72, 7, 35, 2, 0 }, + { 0, 5, 49, 7, 64, 10, 0 }, + { 1, 21, 73, 7, 31, 2, 0 }, + { 0, 6, 53, 7, 60, 9, 0 }, + { 1, 24, 74, 7, 28, 1, 0 }, + { 0, 7, 57, 7, 57, 7, 0 }, + { 0, 1, 28, 7, 74, 24, 1 }, + { 0, 9, 60, 7, 53, 6, 0 }, + { 0, 2, 31, 7, 73, 21, 1 }, + { 0, 10, 64, 7, 49, 5, 0 }, + { 0, 2, 35, 7, 72, 18, 1 }, + { 0, 12, 67, 7, 45, 4, 0 }, + { 0, 3, 39, 7, 70, 16, 0 }, + { 0, 15, 69, 7, 41, 3, 0 }, + { 0, 3, 43, 7, 69, 13, 0 }, + { 1, 17, 71, 7, 37, 2, 0 }, + { 0, 4, 47, 7, 66, 11, 0 }, + { 1, 20, 72, 7, 33, 2, 0 }, + { 0, 5, 51, 7, 63, 9, 0 }, + { 1, 23, 73, 7, 30, 1, 0 }, + { 0, 6, 55, 7, 59, 8, 0 } }, + .odd = { { 0, 15, 70, 7, 40, 3, 0 }, + { 0, 4, 44, 7, 67, 13, 0 }, + { 1, 18, 71, 7, 36, 2, 0 }, + { 0, 4, 48, 7, 65, 11, 0 }, + { 1, 20, 73, 7, 32, 2, 0 }, + { 0, 6, 52, 7, 61, 9, 0 }, + { 1, 24, 73, 7, 29, 1, 0 }, + { 0, 7, 56, 7, 58, 7, 0 }, + { 0, 1, 27, 7, 74, 25, 1 }, + { 0, 8, 60, 7, 54, 6, 0 }, + { 0, 2, 30, 7, 73, 22, 1 }, + { 0, 10, 63, 7, 50, 5, 0 }, + { 0, 2, 34, 7, 72, 19, 1 }, + { 0, 12, 66, 7, 46, 4, 0 }, + { 0, 3, 38, 7, 71, 16, 0 }, + { 0, 14, 69, 7, 42, 3, 0 }, + { 0, 3, 42, 7, 69, 14, 0 }, + { 0, 16, 71, 7, 38, 3, 0 }, + { 0, 4, 46, 7, 66, 12, 0 }, + { 1, 19, 72, 7, 34, 2, 0 }, + { 0, 5, 50, 7, 63, 10, 0 }, + { 1, 22, 73, 7, 30, 2, 0 }, + { 0, 6, 54, 7, 60, 8, 0 }, + { 1, 25, 74, 7, 27, 1, 0 }, + { 0, 7, 58, 7, 56, 7, 0 }, + { 0, 1, 29, 7, 73, 24, 1 }, + { 0, 9, 61, 7, 52, 6, 0 }, + { 0, 2, 32, 7, 73, 20, 1 }, + { 0, 11, 65, 7, 48, 4, 0 }, + { 0, 2, 36, 7, 71, 18, 1 }, + { 0, 13, 67, 7, 44, 4, 0 }, + { 0, 3, 40, 7, 70, 15, 0 } } }, + .ptrn_arr = { { 0x84921249, 0x42492124, 0x24249092, 0x92124909, + 0x49212484, 0x24909248, 0x2490924 } }, + .sample_patrn_length = 222, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 80) = 0.285714 */ + .hor_phase_arr = { + .even = { { 1, 26, 74, 7, 26, 1, 0 }, + { 0, 7, 57, 7, 57, 7, 0 } }, + .odd = { { 0, 15, 69, 7, 41, 3, 0 }, + { 0, 3, 41, 7, 69, 15, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 26, 74, 7, 26, 1, 0 }, + { 0, 7, 57, 7, 57, 7, 0 } }, + .odd = { { 0, 15, 69, 7, 41, 3, 0 }, + { 0, 3, 41, 7, 69, 15, 0 } } }, + .ptrn_arr = { { 0x249 } }, + .sample_patrn_length = 14, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 81) = 0.283186 */ + .hor_phase_arr = { + .even = { { 1, 27, 72, 7, 27, 1, 0 }, + { 0, 7, 54, 7, 59, 8, 0 }, + { 1, 23, 72, 7, 30, 2, 0 }, + { 0, 6, 51, 7, 61, 10, 0 }, + { 1, 20, 71, 7, 34, 2, 0 }, + { 0, 5, 47, 7, 64, 12, 0 }, + { 1, 18, 69, 7, 37, 3, 0 }, + { 0, 4, 43, 7, 67, 14, 0 }, + { 0, 15, 69, 7, 41, 3, 0 }, + { 0, 3, 39, 7, 69, 16, 1 }, + { 0, 13, 66, 7, 45, 4, 0 }, + { 0, 2, 35, 7, 71, 19, 1 }, + { 0, 11, 63, 7, 49, 5, 0 }, + { 0, 2, 32, 7, 71, 22, 1 }, + { 0, 9, 60, 7, 53, 6, 0 }, + { 0, 1, 28, 7, 73, 25, 1 }, + { 0, 8, 56, 7, 56, 8, 0 }, + { 1, 25, 73, 7, 28, 1, 0 }, + { 0, 6, 53, 7, 60, 9, 0 }, + { 1, 22, 71, 7, 32, 2, 0 }, + { 0, 5, 49, 7, 63, 11, 0 }, + { 1, 19, 71, 7, 35, 2, 0 }, + { 0, 4, 45, 7, 66, 13, 0 }, + { 1, 16, 69, 7, 39, 3, 0 }, + { 0, 3, 41, 7, 69, 15, 0 }, + { 0, 14, 67, 7, 43, 4, 0 }, + { 0, 3, 37, 7, 69, 18, 1 }, + { 0, 12, 64, 7, 47, 5, 0 }, + { 0, 2, 34, 7, 71, 20, 1 }, + { 0, 10, 61, 7, 51, 6, 0 }, + { 0, 2, 30, 7, 72, 23, 1 }, + { 0, 8, 59, 7, 54, 7, 0 } }, + .odd = { { 0, 15, 67, 7, 42, 4, 0 }, + { 0, 3, 38, 7, 69, 17, 1 }, + { 0, 12, 66, 7, 46, 4, 0 }, + { 0, 2, 34, 7, 71, 20, 1 }, + { 0, 10, 63, 7, 50, 5, 0 }, + { 0, 2, 31, 7, 71, 23, 1 }, + { 0, 9, 58, 7, 54, 7, 0 }, + { 0, 1, 27, 7, 73, 26, 1 }, + { 0, 7, 55, 7, 58, 8, 0 }, + { 1, 24, 72, 7, 29, 2, 0 }, + { 0, 6, 52, 7, 60, 10, 0 }, + { 1, 21, 71, 7, 33, 2, 0 }, + { 0, 5, 48, 7, 64, 11, 0 }, + { 1, 18, 70, 7, 36, 3, 0 }, + { 0, 4, 44, 7, 67, 13, 0 }, + { 0, 16, 69, 7, 40, 3, 0 }, + { 0, 3, 40, 7, 69, 16, 0 }, + { 0, 13, 67, 7, 44, 4, 0 }, + { 0, 3, 36, 7, 70, 18, 1 }, + { 0, 11, 64, 7, 48, 5, 0 }, + { 0, 2, 33, 7, 71, 21, 1 }, + { 0, 10, 60, 7, 52, 6, 0 }, + { 0, 2, 29, 7, 72, 24, 1 }, + { 0, 8, 58, 7, 55, 7, 0 }, + { 1, 26, 73, 7, 27, 1, 0 }, + { 0, 7, 54, 7, 58, 9, 0 }, + { 1, 23, 71, 7, 31, 2, 0 }, + { 0, 5, 50, 7, 63, 10, 0 }, + { 1, 20, 71, 7, 34, 2, 0 }, + { 0, 4, 46, 7, 66, 12, 0 }, + { 1, 17, 69, 7, 38, 3, 0 }, + { 0, 4, 42, 7, 67, 15, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 27, 72, 7, 27, 1, 0 }, + { 0, 7, 54, 7, 59, 8, 0 }, + { 1, 23, 72, 7, 30, 2, 0 }, + { 0, 6, 51, 7, 61, 10, 0 }, + { 1, 20, 71, 7, 34, 2, 0 }, + { 0, 5, 47, 7, 64, 12, 0 }, + { 1, 18, 69, 7, 37, 3, 0 }, + { 0, 4, 43, 7, 67, 14, 0 }, + { 0, 15, 69, 7, 41, 3, 0 }, + { 0, 3, 39, 7, 69, 16, 1 }, + { 0, 13, 66, 7, 45, 4, 0 }, + { 0, 2, 35, 7, 71, 19, 1 }, + { 0, 11, 63, 7, 49, 5, 0 }, + { 0, 2, 32, 7, 71, 22, 1 }, + { 0, 9, 60, 7, 53, 6, 0 }, + { 0, 1, 28, 7, 73, 25, 1 }, + { 0, 8, 56, 7, 56, 8, 0 }, + { 1, 25, 73, 7, 28, 1, 0 }, + { 0, 6, 53, 7, 60, 9, 0 }, + { 1, 22, 71, 7, 32, 2, 0 }, + { 0, 5, 49, 7, 63, 11, 0 }, + { 1, 19, 71, 7, 35, 2, 0 }, + { 0, 4, 45, 7, 66, 13, 0 }, + { 1, 16, 69, 7, 39, 3, 0 }, + { 0, 3, 41, 7, 69, 15, 0 }, + { 0, 14, 67, 7, 43, 4, 0 }, + { 0, 3, 37, 7, 69, 18, 1 }, + { 0, 12, 64, 7, 47, 5, 0 }, + { 0, 2, 34, 7, 71, 20, 1 }, + { 0, 10, 61, 7, 51, 6, 0 }, + { 0, 2, 30, 7, 72, 23, 1 }, + { 0, 8, 59, 7, 54, 7, 0 } }, + .odd = { { 0, 15, 67, 7, 42, 4, 0 }, + { 0, 3, 38, 7, 69, 17, 1 }, + { 0, 12, 66, 7, 46, 4, 0 }, + { 0, 2, 34, 7, 71, 20, 1 }, + { 0, 10, 63, 7, 50, 5, 0 }, + { 0, 2, 31, 7, 71, 23, 1 }, + { 0, 9, 58, 7, 54, 7, 0 }, + { 0, 1, 27, 7, 73, 26, 1 }, + { 0, 7, 55, 7, 58, 8, 0 }, + { 1, 24, 72, 7, 29, 2, 0 }, + { 0, 6, 52, 7, 60, 10, 0 }, + { 1, 21, 71, 7, 33, 2, 0 }, + { 0, 5, 48, 7, 64, 11, 0 }, + { 1, 18, 70, 7, 36, 3, 0 }, + { 0, 4, 44, 7, 67, 13, 0 }, + { 0, 16, 69, 7, 40, 3, 0 }, + { 0, 3, 40, 7, 69, 16, 0 }, + { 0, 13, 67, 7, 44, 4, 0 }, + { 0, 3, 36, 7, 70, 18, 1 }, + { 0, 11, 64, 7, 48, 5, 0 }, + { 0, 2, 33, 7, 71, 21, 1 }, + { 0, 10, 60, 7, 52, 6, 0 }, + { 0, 2, 29, 7, 72, 24, 1 }, + { 0, 8, 58, 7, 55, 7, 0 }, + { 1, 26, 73, 7, 27, 1, 0 }, + { 0, 7, 54, 7, 58, 9, 0 }, + { 1, 23, 71, 7, 31, 2, 0 }, + { 0, 5, 50, 7, 63, 10, 0 }, + { 1, 20, 71, 7, 34, 2, 0 }, + { 0, 4, 46, 7, 66, 12, 0 }, + { 1, 17, 69, 7, 38, 3, 0 }, + { 0, 4, 42, 7, 67, 15, 0 } } }, + .ptrn_arr = { { 0x90924249, 0x49092424, 0x84921248, 0x49092124, + 0x24909242, 0x48492124, 0x24849212 } }, + .sample_patrn_length = 226, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 82) = 0.280702 */ + .hor_phase_arr = { + .even = { { 1, 27, 72, 7, 27, 1, 0 }, + { 0, 6, 52, 7, 61, 9, 0 }, + { 1, 21, 70, 7, 34, 2, 0 }, + { 0, 4, 45, 7, 66, 13, 0 }, + { 0, 15, 68, 7, 41, 4, 0 }, + { 0, 3, 37, 7, 69, 18, 1 }, + { 0, 11, 63, 7, 49, 5, 0 }, + { 0, 2, 30, 7, 71, 24, 1 }, + { 0, 8, 56, 7, 56, 8, 0 }, + { 1, 24, 71, 7, 30, 2, 0 }, + { 0, 5, 49, 7, 63, 11, 0 }, + { 1, 18, 69, 7, 37, 3, 0 }, + { 0, 4, 41, 7, 68, 15, 0 }, + { 0, 13, 66, 7, 45, 4, 0 }, + { 0, 2, 34, 7, 70, 21, 1 }, + { 0, 9, 61, 7, 52, 6, 0 } }, + .odd = { { 0, 14, 67, 7, 43, 4, 0 }, + { 0, 3, 36, 7, 69, 19, 1 }, + { 0, 10, 61, 7, 51, 6, 0 }, + { 0, 2, 28, 7, 72, 25, 1 }, + { 0, 7, 54, 7, 58, 9, 0 }, + { 1, 22, 71, 7, 32, 2, 0 }, + { 0, 5, 47, 7, 64, 12, 0 }, + { 1, 17, 68, 7, 39, 3, 0 }, + { 0, 3, 39, 7, 68, 17, 1 }, + { 0, 12, 64, 7, 47, 5, 0 }, + { 0, 2, 32, 7, 71, 22, 1 }, + { 0, 9, 58, 7, 54, 7, 0 }, + { 1, 25, 72, 7, 28, 2, 0 }, + { 0, 6, 51, 7, 61, 10, 0 }, + { 1, 19, 69, 7, 36, 3, 0 }, + { 0, 4, 43, 7, 67, 14, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 27, 72, 7, 27, 1, 0 }, + { 0, 6, 52, 7, 61, 9, 0 }, + { 1, 21, 70, 7, 34, 2, 0 }, + { 0, 4, 45, 7, 66, 13, 0 }, + { 0, 15, 68, 7, 41, 4, 0 }, + { 0, 3, 37, 7, 69, 18, 1 }, + { 0, 11, 63, 7, 49, 5, 0 }, + { 0, 2, 30, 7, 71, 24, 1 }, + { 0, 8, 56, 7, 56, 8, 0 }, + { 1, 24, 71, 7, 30, 2, 0 }, + { 0, 5, 49, 7, 63, 11, 0 }, + { 1, 18, 69, 7, 37, 3, 0 }, + { 0, 4, 41, 7, 68, 15, 0 }, + { 0, 13, 66, 7, 45, 4, 0 }, + { 0, 2, 34, 7, 70, 21, 1 }, + { 0, 9, 61, 7, 52, 6, 0 } }, + .odd = { { 0, 14, 67, 7, 43, 4, 0 }, + { 0, 3, 36, 7, 69, 19, 1 }, + { 0, 10, 61, 7, 51, 6, 0 }, + { 0, 2, 28, 7, 72, 25, 1 }, + { 0, 7, 54, 7, 58, 9, 0 }, + { 1, 22, 71, 7, 32, 2, 0 }, + { 0, 5, 47, 7, 64, 12, 0 }, + { 1, 17, 68, 7, 39, 3, 0 }, + { 0, 3, 39, 7, 68, 17, 1 }, + { 0, 12, 64, 7, 47, 5, 0 }, + { 0, 2, 32, 7, 71, 22, 1 }, + { 0, 9, 58, 7, 54, 7, 0 }, + { 1, 25, 72, 7, 28, 2, 0 }, + { 0, 6, 51, 7, 61, 10, 0 }, + { 1, 19, 69, 7, 36, 3, 0 }, + { 0, 4, 43, 7, 67, 14, 0 } } }, + .ptrn_arr = { { 0x90924249, 0x9212484, 0x92124249, 0x2484 } }, + .sample_patrn_length = 114, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 83) = 0.278261 */ + .hor_phase_arr = { + .even = { { 1, 27, 72, 7, 27, 1, 0 }, + { 0, 6, 51, 7, 61, 10, 0 }, + { 1, 18, 68, 7, 38, 3, 0 }, + { 0, 3, 39, 7, 68, 17, 1 }, + { 0, 11, 62, 7, 49, 6, 0 }, + { 0, 2, 29, 7, 71, 25, 1 }, + { 0, 7, 52, 7, 59, 10, 0 }, + { 1, 19, 69, 7, 36, 3, 0 }, + { 0, 4, 41, 7, 66, 16, 1 }, + { 0, 12, 64, 7, 47, 5, 0 }, + { 0, 2, 30, 7, 71, 24, 1 }, + { 0, 7, 54, 7, 58, 9, 0 }, + { 1, 21, 70, 7, 34, 2, 0 }, + { 0, 4, 43, 7, 66, 15, 0 }, + { 0, 13, 65, 7, 45, 5, 0 }, + { 0, 2, 32, 7, 71, 22, 1 }, + { 0, 8, 56, 7, 56, 8, 0 }, + { 1, 22, 71, 7, 32, 2, 0 }, + { 0, 5, 45, 7, 65, 13, 0 }, + { 0, 15, 66, 7, 43, 4, 0 }, + { 0, 2, 34, 7, 70, 21, 1 }, + { 0, 9, 58, 7, 54, 7, 0 }, + { 1, 24, 71, 7, 30, 2, 0 }, + { 0, 5, 47, 7, 64, 12, 0 }, + { 1, 16, 66, 7, 41, 4, 0 }, + { 0, 3, 36, 7, 69, 19, 1 }, + { 0, 10, 59, 7, 52, 7, 0 }, + { 1, 25, 71, 7, 29, 2, 0 }, + { 0, 6, 49, 7, 62, 11, 0 }, + { 1, 17, 68, 7, 39, 3, 0 }, + { 0, 3, 38, 7, 68, 18, 1 }, + { 0, 10, 61, 7, 51, 6, 0 } }, + .odd = { { 0, 14, 66, 7, 44, 4, 0 }, + { 0, 2, 33, 7, 70, 22, 1 }, + { 0, 8, 57, 7, 55, 8, 0 }, + { 1, 23, 71, 7, 31, 2, 0 }, + { 0, 5, 46, 7, 64, 13, 0 }, + { 0, 15, 67, 7, 42, 4, 0 }, + { 0, 3, 35, 7, 69, 20, 1 }, + { 0, 9, 59, 7, 53, 7, 0 }, + { 1, 25, 71, 7, 29, 2, 0 }, + { 0, 5, 48, 7, 63, 12, 0 }, + { 1, 16, 68, 7, 40, 3, 0 }, + { 0, 3, 37, 7, 68, 19, 1 }, + { 0, 10, 61, 7, 51, 6, 0 }, + { 1, 26, 71, 7, 28, 2, 0 }, + { 0, 6, 50, 7, 61, 11, 0 }, + { 1, 18, 68, 7, 38, 3, 0 }, + { 0, 3, 38, 7, 68, 18, 1 }, + { 0, 11, 61, 7, 50, 6, 0 }, + { 0, 2, 28, 7, 71, 26, 1 }, + { 0, 6, 51, 7, 61, 10, 0 }, + { 1, 19, 68, 7, 37, 3, 0 }, + { 0, 3, 40, 7, 68, 16, 1 }, + { 0, 12, 63, 7, 48, 5, 0 }, + { 0, 2, 29, 7, 71, 25, 1 }, + { 0, 7, 53, 7, 59, 9, 0 }, + { 1, 20, 69, 7, 35, 3, 0 }, + { 0, 4, 42, 7, 67, 15, 0 }, + { 0, 13, 64, 7, 46, 5, 0 }, + { 0, 2, 31, 7, 71, 23, 1 }, + { 0, 8, 55, 7, 57, 8, 0 }, + { 1, 22, 70, 7, 33, 2, 0 }, + { 0, 4, 44, 7, 66, 14, 0 } } }, + .ver_phase_arr = { + .even = { { 1, 27, 72, 7, 27, 1, 0 }, + { 0, 6, 51, 7, 61, 10, 0 }, + { 1, 18, 68, 7, 38, 3, 0 }, + { 0, 3, 39, 7, 68, 17, 1 }, + { 0, 11, 62, 7, 49, 6, 0 }, + { 0, 2, 29, 7, 71, 25, 1 }, + { 0, 7, 52, 7, 59, 10, 0 }, + { 1, 19, 69, 7, 36, 3, 0 }, + { 0, 4, 41, 7, 66, 16, 1 }, + { 0, 12, 64, 7, 47, 5, 0 }, + { 0, 2, 30, 7, 71, 24, 1 }, + { 0, 7, 54, 7, 58, 9, 0 }, + { 1, 21, 70, 7, 34, 2, 0 }, + { 0, 4, 43, 7, 66, 15, 0 }, + { 0, 13, 65, 7, 45, 5, 0 }, + { 0, 2, 32, 7, 71, 22, 1 }, + { 0, 8, 56, 7, 56, 8, 0 }, + { 1, 22, 71, 7, 32, 2, 0 }, + { 0, 5, 45, 7, 65, 13, 0 }, + { 0, 15, 66, 7, 43, 4, 0 }, + { 0, 2, 34, 7, 70, 21, 1 }, + { 0, 9, 58, 7, 54, 7, 0 }, + { 1, 24, 71, 7, 30, 2, 0 }, + { 0, 5, 47, 7, 64, 12, 0 }, + { 1, 16, 66, 7, 41, 4, 0 }, + { 0, 3, 36, 7, 69, 19, 1 }, + { 0, 10, 59, 7, 52, 7, 0 }, + { 1, 25, 71, 7, 29, 2, 0 }, + { 0, 6, 49, 7, 62, 11, 0 }, + { 1, 17, 68, 7, 39, 3, 0 }, + { 0, 3, 38, 7, 68, 18, 1 }, + { 0, 10, 61, 7, 51, 6, 0 } }, + .odd = { { 0, 14, 66, 7, 44, 4, 0 }, + { 0, 2, 33, 7, 70, 22, 1 }, + { 0, 8, 57, 7, 55, 8, 0 }, + { 1, 23, 71, 7, 31, 2, 0 }, + { 0, 5, 46, 7, 64, 13, 0 }, + { 0, 15, 67, 7, 42, 4, 0 }, + { 0, 3, 35, 7, 69, 20, 1 }, + { 0, 9, 59, 7, 53, 7, 0 }, + { 1, 25, 71, 7, 29, 2, 0 }, + { 0, 5, 48, 7, 63, 12, 0 }, + { 1, 16, 68, 7, 40, 3, 0 }, + { 0, 3, 37, 7, 68, 19, 1 }, + { 0, 10, 61, 7, 51, 6, 0 }, + { 1, 26, 71, 7, 28, 2, 0 }, + { 0, 6, 50, 7, 61, 11, 0 }, + { 1, 18, 68, 7, 38, 3, 0 }, + { 0, 3, 38, 7, 68, 18, 1 }, + { 0, 11, 61, 7, 50, 6, 0 }, + { 0, 2, 28, 7, 71, 26, 1 }, + { 0, 6, 51, 7, 61, 10, 0 }, + { 1, 19, 68, 7, 37, 3, 0 }, + { 0, 3, 40, 7, 68, 16, 1 }, + { 0, 12, 63, 7, 48, 5, 0 }, + { 0, 2, 29, 7, 71, 25, 1 }, + { 0, 7, 53, 7, 59, 9, 0 }, + { 1, 20, 69, 7, 35, 3, 0 }, + { 0, 4, 42, 7, 67, 15, 0 }, + { 0, 13, 64, 7, 46, 5, 0 }, + { 0, 2, 31, 7, 71, 23, 1 }, + { 0, 8, 55, 7, 57, 8, 0 }, + { 1, 22, 70, 7, 33, 2, 0 }, + { 0, 4, 44, 7, 66, 14, 0 } } }, + .ptrn_arr = { { 0x92124249, 0x21242484, 0x12424849, 0x24248492, + 0x42484909, 0x24849092, 0x48490924, 0x2 } }, + .sample_patrn_length = 230, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 84) = 0.275862 */ + .hor_phase_arr = { + .even = { { 2, 27, 70, 7, 27, 2, 0 }, + { 0, 6, 49, 7, 61, 12, 0 }, + { 1, 16, 66, 7, 41, 4, 0 }, + { 0, 2, 34, 7, 70, 21, 1 }, + { 0, 8, 56, 7, 56, 8, 0 }, + { 1, 21, 70, 7, 34, 2, 0 }, + { 0, 4, 41, 7, 66, 16, 1 }, + { 0, 12, 61, 7, 49, 6, 0 } }, + .odd = { { 0, 14, 64, 7, 45, 5, 0 }, + { 0, 2, 31, 7, 70, 24, 1 }, + { 0, 7, 52, 7, 59, 10, 0 }, + { 1, 18, 68, 7, 38, 3, 0 }, + { 0, 3, 38, 7, 68, 18, 1 }, + { 0, 10, 59, 7, 52, 7, 0 }, + { 1, 24, 70, 7, 31, 2, 0 }, + { 0, 5, 45, 7, 64, 14, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 27, 70, 7, 27, 2, 0 }, + { 0, 6, 49, 7, 61, 12, 0 }, + { 1, 16, 66, 7, 41, 4, 0 }, + { 0, 2, 34, 7, 70, 21, 1 }, + { 0, 8, 56, 7, 56, 8, 0 }, + { 1, 21, 70, 7, 34, 2, 0 }, + { 0, 4, 41, 7, 66, 16, 1 }, + { 0, 12, 61, 7, 49, 6, 0 } }, + .odd = { { 0, 14, 64, 7, 45, 5, 0 }, + { 0, 2, 31, 7, 70, 24, 1 }, + { 0, 7, 52, 7, 59, 10, 0 }, + { 1, 18, 68, 7, 38, 3, 0 }, + { 0, 3, 38, 7, 68, 18, 1 }, + { 0, 10, 59, 7, 52, 7, 0 }, + { 1, 24, 70, 7, 31, 2, 0 }, + { 0, 5, 45, 7, 64, 14, 0 } } }, + .ptrn_arr = { { 0x92124249, 0x248490 } }, + .sample_patrn_length = 58, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 85) = 0.273504 */ + .hor_phase_arr = { + .even = { { 2, 27, 70, 7, 27, 2, 0 }, + { 0, 5, 47, 7, 63, 13, 0 }, + { 0, 14, 64, 7, 45, 5, 0 }, + { 0, 2, 29, 7, 70, 26, 1 }, + { 0, 6, 48, 7, 62, 12, 0 }, + { 1, 15, 65, 7, 43, 4, 0 }, + { 0, 2, 31, 7, 70, 24, 1 }, + { 0, 6, 50, 7, 61, 11, 0 }, + { 1, 16, 66, 7, 41, 4, 0 }, + { 0, 2, 32, 7, 70, 23, 1 }, + { 0, 7, 52, 7, 59, 10, 0 }, + { 1, 17, 67, 7, 39, 4, 0 }, + { 0, 3, 34, 7, 69, 21, 1 }, + { 0, 8, 54, 7, 57, 9, 0 }, + { 1, 19, 67, 7, 38, 3, 0 }, + { 0, 3, 36, 7, 68, 20, 1 }, + { 0, 9, 55, 7, 55, 9, 0 }, + { 1, 20, 68, 7, 36, 3, 0 }, + { 0, 3, 38, 7, 67, 19, 1 }, + { 0, 9, 57, 7, 54, 8, 0 }, + { 1, 21, 69, 7, 34, 3, 0 }, + { 0, 4, 39, 7, 67, 17, 1 }, + { 0, 10, 59, 7, 52, 7, 0 }, + { 1, 23, 70, 7, 32, 2, 0 }, + { 0, 4, 41, 7, 66, 16, 1 }, + { 0, 11, 61, 7, 50, 6, 0 }, + { 1, 24, 70, 7, 31, 2, 0 }, + { 0, 4, 43, 7, 65, 15, 1 }, + { 0, 12, 62, 7, 48, 6, 0 }, + { 1, 26, 70, 7, 29, 2, 0 }, + { 0, 5, 45, 7, 64, 14, 0 }, + { 0, 13, 63, 7, 47, 5, 0 } }, + .odd = { { 0, 13, 64, 7, 46, 5, 0 }, + { 0, 2, 28, 7, 69, 27, 2 }, + { 0, 6, 48, 7, 62, 12, 0 }, + { 1, 14, 64, 7, 44, 5, 0 }, + { 0, 2, 30, 7, 70, 25, 1 }, + { 0, 6, 49, 7, 62, 11, 0 }, + { 1, 16, 65, 7, 42, 4, 0 }, + { 0, 2, 32, 7, 69, 24, 1 }, + { 0, 7, 51, 7, 59, 11, 0 }, + { 1, 17, 66, 7, 40, 4, 0 }, + { 0, 2, 33, 7, 70, 22, 1 }, + { 0, 7, 53, 7, 58, 10, 0 }, + { 1, 18, 67, 7, 39, 3, 0 }, + { 0, 3, 35, 7, 68, 21, 1 }, + { 0, 8, 54, 7, 57, 9, 0 }, + { 1, 19, 68, 7, 37, 3, 0 }, + { 0, 3, 37, 7, 68, 19, 1 }, + { 0, 9, 57, 7, 54, 8, 0 }, + { 1, 21, 68, 7, 35, 3, 0 }, + { 0, 3, 39, 7, 67, 18, 1 }, + { 0, 10, 58, 7, 53, 7, 0 }, + { 1, 22, 70, 7, 33, 2, 0 }, + { 0, 4, 40, 7, 66, 17, 1 }, + { 0, 11, 59, 7, 51, 7, 0 }, + { 1, 24, 69, 7, 32, 2, 0 }, + { 0, 4, 42, 7, 65, 16, 1 }, + { 0, 11, 62, 7, 49, 6, 0 }, + { 1, 25, 70, 7, 30, 2, 0 }, + { 0, 5, 44, 7, 64, 14, 1 }, + { 0, 12, 62, 7, 48, 6, 0 }, + { 2, 27, 69, 7, 28, 2, 0 }, + { 0, 5, 46, 7, 64, 13, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 27, 70, 7, 27, 2, 0 }, + { 0, 5, 47, 7, 63, 13, 0 }, + { 0, 14, 64, 7, 45, 5, 0 }, + { 0, 2, 29, 7, 70, 26, 1 }, + { 0, 6, 48, 7, 62, 12, 0 }, + { 1, 15, 65, 7, 43, 4, 0 }, + { 0, 2, 31, 7, 70, 24, 1 }, + { 0, 6, 50, 7, 61, 11, 0 }, + { 1, 16, 66, 7, 41, 4, 0 }, + { 0, 2, 32, 7, 70, 23, 1 }, + { 0, 7, 52, 7, 59, 10, 0 }, + { 1, 17, 67, 7, 39, 4, 0 }, + { 0, 3, 34, 7, 69, 21, 1 }, + { 0, 8, 54, 7, 57, 9, 0 }, + { 1, 19, 67, 7, 38, 3, 0 }, + { 0, 3, 36, 7, 68, 20, 1 }, + { 0, 9, 55, 7, 55, 9, 0 }, + { 1, 20, 68, 7, 36, 3, 0 }, + { 0, 3, 38, 7, 67, 19, 1 }, + { 0, 9, 57, 7, 54, 8, 0 }, + { 1, 21, 69, 7, 34, 3, 0 }, + { 0, 4, 39, 7, 67, 17, 1 }, + { 0, 10, 59, 7, 52, 7, 0 }, + { 1, 23, 70, 7, 32, 2, 0 }, + { 0, 4, 41, 7, 66, 16, 1 }, + { 0, 11, 61, 7, 50, 6, 0 }, + { 1, 24, 70, 7, 31, 2, 0 }, + { 0, 4, 43, 7, 65, 15, 1 }, + { 0, 12, 62, 7, 48, 6, 0 }, + { 1, 26, 70, 7, 29, 2, 0 }, + { 0, 5, 45, 7, 64, 14, 0 }, + { 0, 13, 63, 7, 47, 5, 0 } }, + .odd = { { 0, 13, 64, 7, 46, 5, 0 }, + { 0, 2, 28, 7, 69, 27, 2 }, + { 0, 6, 48, 7, 62, 12, 0 }, + { 1, 14, 64, 7, 44, 5, 0 }, + { 0, 2, 30, 7, 70, 25, 1 }, + { 0, 6, 49, 7, 62, 11, 0 }, + { 1, 16, 65, 7, 42, 4, 0 }, + { 0, 2, 32, 7, 69, 24, 1 }, + { 0, 7, 51, 7, 59, 11, 0 }, + { 1, 17, 66, 7, 40, 4, 0 }, + { 0, 2, 33, 7, 70, 22, 1 }, + { 0, 7, 53, 7, 58, 10, 0 }, + { 1, 18, 67, 7, 39, 3, 0 }, + { 0, 3, 35, 7, 68, 21, 1 }, + { 0, 8, 54, 7, 57, 9, 0 }, + { 1, 19, 68, 7, 37, 3, 0 }, + { 0, 3, 37, 7, 68, 19, 1 }, + { 0, 9, 57, 7, 54, 8, 0 }, + { 1, 21, 68, 7, 35, 3, 0 }, + { 0, 3, 39, 7, 67, 18, 1 }, + { 0, 10, 58, 7, 53, 7, 0 }, + { 1, 22, 70, 7, 33, 2, 0 }, + { 0, 4, 40, 7, 66, 17, 1 }, + { 0, 11, 59, 7, 51, 7, 0 }, + { 1, 24, 69, 7, 32, 2, 0 }, + { 0, 4, 42, 7, 65, 16, 1 }, + { 0, 11, 62, 7, 49, 6, 0 }, + { 1, 25, 70, 7, 30, 2, 0 }, + { 0, 5, 44, 7, 64, 14, 1 }, + { 0, 12, 62, 7, 48, 6, 0 }, + { 2, 27, 69, 7, 28, 2, 0 }, + { 0, 5, 46, 7, 64, 13, 0 } } }, + .ptrn_arr = { { 0x92124249, 0x24248490, 0x48490921, 0x90921242, + 0x21242484, 0x42484909, 0x84909212, 0x24 } }, + .sample_patrn_length = 234, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 86) = 0.271186 */ + .hor_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 5, 45, 7, 63, 14, 1 }, + { 0, 12, 62, 7, 48, 6, 0 }, + { 1, 25, 69, 7, 31, 2, 0 }, + { 0, 4, 41, 7, 66, 16, 1 }, + { 0, 10, 59, 7, 52, 7, 0 }, + { 1, 22, 68, 7, 34, 3, 0 }, + { 0, 3, 38, 7, 67, 19, 1 }, + { 0, 9, 55, 7, 55, 9, 0 }, + { 1, 19, 67, 7, 38, 3, 0 }, + { 0, 3, 34, 7, 68, 22, 1 }, + { 0, 7, 52, 7, 59, 10, 0 }, + { 1, 16, 66, 7, 41, 4, 0 }, + { 0, 2, 31, 7, 69, 25, 1 }, + { 0, 6, 48, 7, 62, 12, 0 }, + { 1, 14, 63, 7, 45, 5, 0 } }, + .odd = { { 0, 13, 62, 7, 47, 6, 0 }, + { 2, 26, 69, 7, 29, 2, 0 }, + { 0, 5, 43, 7, 64, 15, 1 }, + { 0, 11, 60, 7, 50, 7, 0 }, + { 1, 23, 69, 7, 33, 2, 0 }, + { 0, 4, 40, 7, 65, 18, 1 }, + { 0, 10, 57, 7, 53, 8, 0 }, + { 1, 20, 68, 7, 36, 3, 0 }, + { 0, 3, 36, 7, 68, 20, 1 }, + { 0, 8, 53, 7, 57, 10, 0 }, + { 1, 18, 65, 7, 40, 4, 0 }, + { 0, 2, 33, 7, 69, 23, 1 }, + { 0, 7, 50, 7, 60, 11, 0 }, + { 1, 15, 64, 7, 43, 5, 0 }, + { 0, 2, 29, 7, 69, 26, 2 }, + { 0, 6, 47, 7, 62, 13, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 5, 45, 7, 63, 14, 1 }, + { 0, 12, 62, 7, 48, 6, 0 }, + { 1, 25, 69, 7, 31, 2, 0 }, + { 0, 4, 41, 7, 66, 16, 1 }, + { 0, 10, 59, 7, 52, 7, 0 }, + { 1, 22, 68, 7, 34, 3, 0 }, + { 0, 3, 38, 7, 67, 19, 1 }, + { 0, 9, 55, 7, 55, 9, 0 }, + { 1, 19, 67, 7, 38, 3, 0 }, + { 0, 3, 34, 7, 68, 22, 1 }, + { 0, 7, 52, 7, 59, 10, 0 }, + { 1, 16, 66, 7, 41, 4, 0 }, + { 0, 2, 31, 7, 69, 25, 1 }, + { 0, 6, 48, 7, 62, 12, 0 }, + { 1, 14, 63, 7, 45, 5, 0 } }, + .odd = { { 0, 13, 62, 7, 47, 6, 0 }, + { 2, 26, 69, 7, 29, 2, 0 }, + { 0, 5, 43, 7, 64, 15, 1 }, + { 0, 11, 60, 7, 50, 7, 0 }, + { 1, 23, 69, 7, 33, 2, 0 }, + { 0, 4, 40, 7, 65, 18, 1 }, + { 0, 10, 57, 7, 53, 8, 0 }, + { 1, 20, 68, 7, 36, 3, 0 }, + { 0, 3, 36, 7, 68, 20, 1 }, + { 0, 8, 53, 7, 57, 10, 0 }, + { 1, 18, 65, 7, 40, 4, 0 }, + { 0, 2, 33, 7, 69, 23, 1 }, + { 0, 7, 50, 7, 60, 11, 0 }, + { 1, 15, 64, 7, 43, 5, 0 }, + { 0, 2, 29, 7, 69, 26, 2 }, + { 0, 6, 47, 7, 62, 13, 0 } } }, + .ptrn_arr = { { 0x12424849, 0x24849092, 0x49092124, 0x24248 } }, + .sample_patrn_length = 118, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 87) = 0.268908 */ + .hor_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 5, 43, 7, 63, 16, 1 }, + { 0, 11, 57, 7, 52, 8, 0 }, + { 1, 21, 67, 7, 36, 3, 0 }, + { 0, 3, 34, 7, 68, 22, 1 }, + { 0, 7, 50, 7, 60, 11, 0 }, + { 1, 14, 63, 7, 45, 5, 0 }, + { 2, 26, 69, 7, 29, 2, 0 }, + { 0, 4, 41, 7, 65, 17, 1 }, + { 0, 10, 57, 7, 53, 8, 0 }, + { 1, 19, 66, 7, 38, 4, 0 }, + { 0, 3, 33, 7, 68, 23, 1 }, + { 0, 6, 48, 7, 62, 12, 0 }, + { 0, 13, 62, 7, 47, 6, 0 }, + { 1, 25, 69, 7, 31, 2, 0 }, + { 0, 4, 40, 7, 65, 18, 1 }, + { 0, 9, 55, 7, 55, 9, 0 }, + { 1, 18, 65, 7, 40, 4, 0 }, + { 0, 2, 31, 7, 69, 25, 1 }, + { 0, 6, 47, 7, 62, 13, 0 }, + { 0, 12, 62, 7, 48, 6, 0 }, + { 1, 23, 68, 7, 33, 3, 0 }, + { 0, 4, 38, 7, 66, 19, 1 }, + { 0, 8, 53, 7, 57, 10, 0 }, + { 1, 17, 65, 7, 41, 4, 0 }, + { 0, 2, 29, 7, 69, 26, 2 }, + { 0, 5, 45, 7, 63, 14, 1 }, + { 0, 11, 60, 7, 50, 7, 0 }, + { 1, 22, 68, 7, 34, 3, 0 }, + { 0, 3, 36, 7, 67, 21, 1 }, + { 0, 8, 52, 7, 57, 11, 0 }, + { 1, 16, 63, 7, 43, 5, 0 } }, + .odd = { { 0, 13, 62, 7, 47, 6, 0 }, + { 1, 24, 69, 7, 32, 2, 0 }, + { 0, 4, 39, 7, 65, 19, 1 }, + { 0, 9, 54, 7, 56, 9, 0 }, + { 1, 17, 66, 7, 40, 4, 0 }, + { 0, 2, 30, 7, 69, 25, 2 }, + { 0, 5, 46, 7, 62, 14, 1 }, + { 0, 12, 60, 7, 49, 7, 0 }, + { 1, 23, 67, 7, 34, 3, 0 }, + { 0, 3, 37, 7, 67, 20, 1 }, + { 0, 8, 52, 7, 58, 10, 0 }, + { 1, 16, 64, 7, 42, 5, 0 }, + { 0, 2, 29, 7, 68, 27, 2 }, + { 0, 5, 44, 7, 63, 15, 1 }, + { 0, 11, 59, 7, 51, 7, 0 }, + { 1, 21, 68, 7, 35, 3, 0 }, + { 0, 3, 35, 7, 68, 21, 1 }, + { 0, 7, 51, 7, 59, 11, 0 }, + { 1, 15, 63, 7, 44, 5, 0 }, + { 2, 27, 68, 7, 29, 2, 0 }, + { 0, 5, 42, 7, 64, 16, 1 }, + { 0, 10, 58, 7, 52, 8, 0 }, + { 1, 20, 67, 7, 37, 3, 0 }, + { 0, 3, 34, 7, 67, 23, 1 }, + { 0, 7, 49, 7, 60, 12, 0 }, + { 1, 14, 62, 7, 46, 5, 0 }, + { 2, 25, 69, 7, 30, 2, 0 }, + { 0, 4, 40, 7, 66, 17, 1 }, + { 0, 9, 56, 7, 54, 9, 0 }, + { 1, 19, 65, 7, 39, 4, 0 }, + { 0, 2, 32, 7, 69, 24, 1 }, + { 0, 6, 47, 7, 62, 13, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 5, 43, 7, 63, 16, 1 }, + { 0, 11, 57, 7, 52, 8, 0 }, + { 1, 21, 67, 7, 36, 3, 0 }, + { 0, 3, 34, 7, 68, 22, 1 }, + { 0, 7, 50, 7, 60, 11, 0 }, + { 1, 14, 63, 7, 45, 5, 0 }, + { 2, 26, 69, 7, 29, 2, 0 }, + { 0, 4, 41, 7, 65, 17, 1 }, + { 0, 10, 57, 7, 53, 8, 0 }, + { 1, 19, 66, 7, 38, 4, 0 }, + { 0, 3, 33, 7, 68, 23, 1 }, + { 0, 6, 48, 7, 62, 12, 0 }, + { 0, 13, 62, 7, 47, 6, 0 }, + { 1, 25, 69, 7, 31, 2, 0 }, + { 0, 4, 40, 7, 65, 18, 1 }, + { 0, 9, 55, 7, 55, 9, 0 }, + { 1, 18, 65, 7, 40, 4, 0 }, + { 0, 2, 31, 7, 69, 25, 1 }, + { 0, 6, 47, 7, 62, 13, 0 }, + { 0, 12, 62, 7, 48, 6, 0 }, + { 1, 23, 68, 7, 33, 3, 0 }, + { 0, 4, 38, 7, 66, 19, 1 }, + { 0, 8, 53, 7, 57, 10, 0 }, + { 1, 17, 65, 7, 41, 4, 0 }, + { 0, 2, 29, 7, 69, 26, 2 }, + { 0, 5, 45, 7, 63, 14, 1 }, + { 0, 11, 60, 7, 50, 7, 0 }, + { 1, 22, 68, 7, 34, 3, 0 }, + { 0, 3, 36, 7, 67, 21, 1 }, + { 0, 8, 52, 7, 57, 11, 0 }, + { 1, 16, 63, 7, 43, 5, 0 } }, + .odd = { { 0, 13, 62, 7, 47, 6, 0 }, + { 1, 24, 69, 7, 32, 2, 0 }, + { 0, 4, 39, 7, 65, 19, 1 }, + { 0, 9, 54, 7, 56, 9, 0 }, + { 1, 17, 66, 7, 40, 4, 0 }, + { 0, 2, 30, 7, 69, 25, 2 }, + { 0, 5, 46, 7, 62, 14, 1 }, + { 0, 12, 60, 7, 49, 7, 0 }, + { 1, 23, 67, 7, 34, 3, 0 }, + { 0, 3, 37, 7, 67, 20, 1 }, + { 0, 8, 52, 7, 58, 10, 0 }, + { 1, 16, 64, 7, 42, 5, 0 }, + { 0, 2, 29, 7, 68, 27, 2 }, + { 0, 5, 44, 7, 63, 15, 1 }, + { 0, 11, 59, 7, 51, 7, 0 }, + { 1, 21, 68, 7, 35, 3, 0 }, + { 0, 3, 35, 7, 68, 21, 1 }, + { 0, 7, 51, 7, 59, 11, 0 }, + { 1, 15, 63, 7, 44, 5, 0 }, + { 2, 27, 68, 7, 29, 2, 0 }, + { 0, 5, 42, 7, 64, 16, 1 }, + { 0, 10, 58, 7, 52, 8, 0 }, + { 1, 20, 67, 7, 37, 3, 0 }, + { 0, 3, 34, 7, 67, 23, 1 }, + { 0, 7, 49, 7, 60, 12, 0 }, + { 1, 14, 62, 7, 46, 5, 0 }, + { 2, 25, 69, 7, 30, 2, 0 }, + { 0, 4, 40, 7, 66, 17, 1 }, + { 0, 9, 56, 7, 54, 9, 0 }, + { 1, 19, 65, 7, 39, 4, 0 }, + { 0, 2, 32, 7, 69, 24, 1 }, + { 0, 6, 47, 7, 62, 13, 0 } } }, + .ptrn_arr = { { 0x12424849, 0x84909092, 0x9212424, 0x42484909, + 0x90921212, 0x21242484, 0x48490921, 0x242 } }, + .sample_patrn_length = 238, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 88) = 0.266667 */ + .hor_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 4, 41, 7, 65, 17, 1 }, + { 0, 9, 55, 7, 55, 9, 0 }, + { 1, 17, 65, 7, 41, 4, 0 } }, + .odd = { { 0, 13, 60, 7, 48, 7, 0 }, + { 1, 22, 68, 7, 34, 3, 0 }, + { 0, 3, 34, 7, 68, 22, 1 }, + { 0, 7, 48, 7, 60, 13, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 4, 41, 7, 65, 17, 1 }, + { 0, 9, 55, 7, 55, 9, 0 }, + { 1, 17, 65, 7, 41, 4, 0 } }, + .odd = { { 0, 13, 60, 7, 48, 7, 0 }, + { 1, 22, 68, 7, 34, 3, 0 }, + { 0, 3, 34, 7, 68, 22, 1 }, + { 0, 7, 48, 7, 60, 13, 0 } } }, + .ptrn_arr = { { 0x2424849 } }, + .sample_patrn_length = 30, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 89) = 0.264463 */ + .hor_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 4, 40, 7, 65, 18, 1 }, + { 0, 8, 51, 7, 58, 11, 0 }, + { 1, 14, 61, 7, 46, 6, 0 }, + { 1, 22, 67, 7, 35, 3, 0 }, + { 0, 3, 33, 7, 67, 24, 1 }, + { 0, 6, 45, 7, 61, 15, 1 }, + { 0, 10, 56, 7, 53, 9, 0 }, + { 1, 17, 64, 7, 41, 5, 0 }, + { 2, 27, 67, 7, 30, 2, 0 }, + { 0, 4, 38, 7, 65, 20, 1 }, + { 0, 7, 50, 7, 59, 12, 0 }, + { 0, 13, 60, 7, 48, 7, 0 }, + { 1, 21, 67, 7, 36, 3, 0 }, + { 0, 3, 31, 7, 67, 25, 2 }, + { 0, 5, 43, 7, 63, 16, 1 }, + { 0, 9, 56, 7, 54, 9, 0 }, + { 1, 16, 63, 7, 43, 5, 0 }, + { 2, 25, 67, 7, 31, 3, 0 }, + { 0, 3, 36, 7, 67, 21, 1 }, + { 0, 7, 48, 7, 60, 13, 0 }, + { 0, 12, 59, 7, 50, 7, 0 }, + { 1, 20, 65, 7, 38, 4, 0 }, + { 0, 2, 30, 7, 67, 27, 2 }, + { 0, 5, 41, 7, 64, 17, 1 }, + { 0, 9, 53, 7, 56, 10, 0 }, + { 1, 15, 61, 7, 45, 6, 0 }, + { 1, 24, 67, 7, 33, 3, 0 }, + { 0, 3, 35, 7, 67, 22, 1 }, + { 0, 6, 46, 7, 61, 14, 1 }, + { 0, 11, 58, 7, 51, 8, 0 }, + { 1, 18, 65, 7, 40, 4, 0 } }, + .odd = { { 0, 12, 60, 7, 49, 7, 0 }, + { 1, 20, 66, 7, 37, 4, 0 }, + { 0, 2, 31, 7, 67, 26, 2 }, + { 0, 5, 42, 7, 63, 17, 1 }, + { 0, 9, 54, 7, 55, 10, 0 }, + { 1, 16, 62, 7, 44, 5, 0 }, + { 2, 24, 67, 7, 32, 3, 0 }, + { 0, 3, 35, 7, 67, 22, 1 }, + { 0, 6, 47, 7, 61, 13, 1 }, + { 0, 12, 58, 7, 50, 8, 0 }, + { 1, 19, 65, 7, 39, 4, 0 }, + { 0, 2, 29, 7, 68, 27, 2 }, + { 0, 4, 40, 7, 65, 18, 1 }, + { 0, 8, 52, 7, 57, 11, 0 }, + { 1, 14, 61, 7, 46, 6, 0 }, + { 1, 23, 67, 7, 34, 3, 0 }, + { 0, 3, 34, 7, 67, 23, 1 }, + { 0, 6, 46, 7, 61, 14, 1 }, + { 0, 11, 57, 7, 52, 8, 0 }, + { 1, 18, 65, 7, 40, 4, 0 }, + { 2, 27, 68, 7, 29, 2, 0 }, + { 0, 4, 39, 7, 65, 19, 1 }, + { 0, 8, 50, 7, 58, 12, 0 }, + { 1, 13, 61, 7, 47, 6, 0 }, + { 1, 22, 67, 7, 35, 3, 0 }, + { 0, 3, 32, 7, 67, 24, 2 }, + { 0, 5, 44, 7, 62, 16, 1 }, + { 0, 10, 55, 7, 54, 9, 0 }, + { 1, 17, 63, 7, 42, 5, 0 }, + { 2, 26, 67, 7, 31, 2, 0 }, + { 0, 4, 37, 7, 66, 20, 1 }, + { 0, 7, 49, 7, 60, 12, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 4, 40, 7, 65, 18, 1 }, + { 0, 8, 51, 7, 58, 11, 0 }, + { 1, 14, 61, 7, 46, 6, 0 }, + { 1, 22, 67, 7, 35, 3, 0 }, + { 0, 3, 33, 7, 67, 24, 1 }, + { 0, 6, 45, 7, 61, 15, 1 }, + { 0, 10, 56, 7, 53, 9, 0 }, + { 1, 17, 64, 7, 41, 5, 0 }, + { 2, 27, 67, 7, 30, 2, 0 }, + { 0, 4, 38, 7, 65, 20, 1 }, + { 0, 7, 50, 7, 59, 12, 0 }, + { 0, 13, 60, 7, 48, 7, 0 }, + { 1, 21, 67, 7, 36, 3, 0 }, + { 0, 3, 31, 7, 67, 25, 2 }, + { 0, 5, 43, 7, 63, 16, 1 }, + { 0, 9, 56, 7, 54, 9, 0 }, + { 1, 16, 63, 7, 43, 5, 0 }, + { 2, 25, 67, 7, 31, 3, 0 }, + { 0, 3, 36, 7, 67, 21, 1 }, + { 0, 7, 48, 7, 60, 13, 0 }, + { 0, 12, 59, 7, 50, 7, 0 }, + { 1, 20, 65, 7, 38, 4, 0 }, + { 0, 2, 30, 7, 67, 27, 2 }, + { 0, 5, 41, 7, 64, 17, 1 }, + { 0, 9, 53, 7, 56, 10, 0 }, + { 1, 15, 61, 7, 45, 6, 0 }, + { 1, 24, 67, 7, 33, 3, 0 }, + { 0, 3, 35, 7, 67, 22, 1 }, + { 0, 6, 46, 7, 61, 14, 1 }, + { 0, 11, 58, 7, 51, 8, 0 }, + { 1, 18, 65, 7, 40, 4, 0 } }, + .odd = { { 0, 12, 60, 7, 49, 7, 0 }, + { 1, 20, 66, 7, 37, 4, 0 }, + { 0, 2, 31, 7, 67, 26, 2 }, + { 0, 5, 42, 7, 63, 17, 1 }, + { 0, 9, 54, 7, 55, 10, 0 }, + { 1, 16, 62, 7, 44, 5, 0 }, + { 2, 24, 67, 7, 32, 3, 0 }, + { 0, 3, 35, 7, 67, 22, 1 }, + { 0, 6, 47, 7, 61, 13, 1 }, + { 0, 12, 58, 7, 50, 8, 0 }, + { 1, 19, 65, 7, 39, 4, 0 }, + { 0, 2, 29, 7, 68, 27, 2 }, + { 0, 4, 40, 7, 65, 18, 1 }, + { 0, 8, 52, 7, 57, 11, 0 }, + { 1, 14, 61, 7, 46, 6, 0 }, + { 1, 23, 67, 7, 34, 3, 0 }, + { 0, 3, 34, 7, 67, 23, 1 }, + { 0, 6, 46, 7, 61, 14, 1 }, + { 0, 11, 57, 7, 52, 8, 0 }, + { 1, 18, 65, 7, 40, 4, 0 }, + { 2, 27, 68, 7, 29, 2, 0 }, + { 0, 4, 39, 7, 65, 19, 1 }, + { 0, 8, 50, 7, 58, 12, 0 }, + { 1, 13, 61, 7, 47, 6, 0 }, + { 1, 22, 67, 7, 35, 3, 0 }, + { 0, 3, 32, 7, 67, 24, 2 }, + { 0, 5, 44, 7, 62, 16, 1 }, + { 0, 10, 55, 7, 54, 9, 0 }, + { 1, 17, 63, 7, 42, 5, 0 }, + { 2, 26, 67, 7, 31, 2, 0 }, + { 0, 4, 37, 7, 66, 20, 1 }, + { 0, 7, 49, 7, 60, 12, 0 } } }, + .ptrn_arr = { { 0x42424849, 0x90921212, 0x24248490, 0x9212124, + 0x48484909, 0x92121242, 0x84849090, 0x2424 } }, + .sample_patrn_length = 242, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 90) = 0.262295 */ + .hor_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 4, 38, 7, 65, 20, 1 }, + { 0, 7, 48, 7, 59, 13, 1 }, + { 0, 11, 58, 7, 51, 8, 0 }, + { 1, 17, 64, 7, 41, 5, 0 }, + { 2, 25, 67, 7, 31, 3, 0 }, + { 0, 3, 35, 7, 66, 23, 1 }, + { 0, 6, 45, 7, 61, 15, 1 }, + { 0, 10, 54, 7, 54, 10, 0 }, + { 1, 15, 61, 7, 45, 6, 0 }, + { 1, 23, 66, 7, 35, 3, 0 }, + { 0, 3, 31, 7, 67, 25, 2 }, + { 0, 5, 41, 7, 64, 17, 1 }, + { 0, 8, 51, 7, 58, 11, 0 }, + { 1, 13, 59, 7, 48, 7, 0 }, + { 1, 20, 65, 7, 38, 4, 0 } }, + .odd = { { 0, 12, 59, 7, 49, 8, 0 }, + { 1, 19, 64, 7, 40, 4, 0 }, + { 2, 27, 67, 7, 30, 2, 0 }, + { 0, 4, 36, 7, 66, 21, 1 }, + { 0, 6, 46, 7, 61, 14, 1 }, + { 0, 10, 56, 7, 53, 9, 0 }, + { 1, 16, 63, 7, 43, 5, 0 }, + { 2, 24, 66, 7, 33, 3, 0 }, + { 0, 3, 33, 7, 66, 24, 2 }, + { 0, 5, 43, 7, 63, 16, 1 }, + { 0, 9, 53, 7, 56, 10, 0 }, + { 1, 14, 61, 7, 46, 6, 0 }, + { 1, 21, 66, 7, 36, 4, 0 }, + { 0, 2, 30, 7, 67, 27, 2 }, + { 0, 4, 40, 7, 64, 19, 1 }, + { 0, 8, 49, 7, 59, 12, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 28, 68, 7, 28, 2, 0 }, + { 0, 4, 38, 7, 65, 20, 1 }, + { 0, 7, 48, 7, 59, 13, 1 }, + { 0, 11, 58, 7, 51, 8, 0 }, + { 1, 17, 64, 7, 41, 5, 0 }, + { 2, 25, 67, 7, 31, 3, 0 }, + { 0, 3, 35, 7, 66, 23, 1 }, + { 0, 6, 45, 7, 61, 15, 1 }, + { 0, 10, 54, 7, 54, 10, 0 }, + { 1, 15, 61, 7, 45, 6, 0 }, + { 1, 23, 66, 7, 35, 3, 0 }, + { 0, 3, 31, 7, 67, 25, 2 }, + { 0, 5, 41, 7, 64, 17, 1 }, + { 0, 8, 51, 7, 58, 11, 0 }, + { 1, 13, 59, 7, 48, 7, 0 }, + { 1, 20, 65, 7, 38, 4, 0 } }, + .odd = { { 0, 12, 59, 7, 49, 8, 0 }, + { 1, 19, 64, 7, 40, 4, 0 }, + { 2, 27, 67, 7, 30, 2, 0 }, + { 0, 4, 36, 7, 66, 21, 1 }, + { 0, 6, 46, 7, 61, 14, 1 }, + { 0, 10, 56, 7, 53, 9, 0 }, + { 1, 16, 63, 7, 43, 5, 0 }, + { 2, 24, 66, 7, 33, 3, 0 }, + { 0, 3, 33, 7, 66, 24, 2 }, + { 0, 5, 43, 7, 63, 16, 1 }, + { 0, 9, 53, 7, 56, 10, 0 }, + { 1, 14, 61, 7, 46, 6, 0 }, + { 1, 21, 66, 7, 36, 4, 0 }, + { 0, 2, 30, 7, 67, 27, 2 }, + { 0, 4, 40, 7, 64, 19, 1 }, + { 0, 8, 49, 7, 59, 12, 0 } } }, + .ptrn_arr = { { 0x42484849, 0x92121242, 0x84849090, 0x242424 } }, + .sample_patrn_length = 122, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 91) = 0.260163 */ + .hor_phase_arr = { + .even = { { 2, 29, 66, 7, 29, 2, 0 }, + { 0, 4, 36, 7, 66, 21, 1 }, + { 0, 6, 45, 7, 61, 15, 1 }, + { 0, 9, 52, 7, 56, 11, 0 }, + { 1, 13, 59, 7, 48, 7, 0 }, + { 1, 19, 63, 7, 40, 5, 0 }, + { 2, 26, 65, 7, 32, 3, 0 }, + { 0, 3, 33, 7, 66, 24, 2 }, + { 0, 5, 41, 7, 63, 18, 1 }, + { 0, 8, 49, 7, 59, 12, 0 }, + { 0, 12, 57, 7, 51, 8, 0 }, + { 1, 17, 62, 7, 43, 5, 0 }, + { 1, 23, 66, 7, 35, 3, 0 }, + { 0, 3, 30, 7, 66, 27, 2 }, + { 0, 4, 38, 7, 65, 20, 1 }, + { 0, 7, 46, 7, 60, 14, 1 }, + { 0, 10, 54, 7, 54, 10, 0 }, + { 1, 14, 60, 7, 46, 7, 0 }, + { 1, 20, 65, 7, 38, 4, 0 }, + { 2, 27, 66, 7, 30, 3, 0 }, + { 0, 3, 35, 7, 66, 23, 1 }, + { 0, 5, 43, 7, 62, 17, 1 }, + { 0, 8, 51, 7, 57, 12, 0 }, + { 0, 12, 59, 7, 49, 8, 0 }, + { 1, 18, 63, 7, 41, 5, 0 }, + { 2, 24, 66, 7, 33, 3, 0 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 5, 40, 7, 63, 19, 1 }, + { 0, 7, 48, 7, 59, 13, 1 }, + { 0, 11, 56, 7, 52, 9, 0 }, + { 1, 15, 61, 7, 45, 6, 0 }, + { 1, 21, 66, 7, 36, 4, 0 } }, + .odd = { { 0, 12, 58, 7, 50, 8, 0 }, + { 1, 17, 63, 7, 42, 5, 0 }, + { 2, 23, 66, 7, 34, 3, 0 }, + { 0, 3, 31, 7, 66, 26, 2 }, + { 0, 4, 39, 7, 64, 20, 1 }, + { 0, 7, 47, 7, 59, 14, 1 }, + { 0, 10, 55, 7, 53, 10, 0 }, + { 1, 15, 61, 7, 45, 6, 0 }, + { 1, 21, 65, 7, 37, 4, 0 }, + { 2, 28, 67, 7, 29, 2, 0 }, + { 0, 4, 36, 7, 65, 22, 1 }, + { 0, 6, 44, 7, 61, 16, 1 }, + { 0, 9, 52, 7, 56, 11, 0 }, + { 1, 13, 58, 7, 49, 7, 0 }, + { 1, 18, 64, 7, 40, 5, 0 }, + { 2, 25, 66, 7, 32, 3, 0 }, + { 0, 3, 32, 7, 66, 25, 2 }, + { 0, 5, 40, 7, 64, 18, 1 }, + { 0, 7, 49, 7, 58, 13, 1 }, + { 0, 11, 56, 7, 52, 9, 0 }, + { 1, 16, 61, 7, 44, 6, 0 }, + { 1, 22, 65, 7, 36, 4, 0 }, + { 0, 2, 29, 7, 67, 28, 2 }, + { 0, 4, 37, 7, 65, 21, 1 }, + { 0, 6, 45, 7, 61, 15, 1 }, + { 0, 10, 53, 7, 55, 10, 0 }, + { 1, 14, 59, 7, 47, 7, 0 }, + { 1, 20, 64, 7, 39, 4, 0 }, + { 2, 26, 66, 7, 31, 3, 0 }, + { 0, 3, 34, 7, 66, 23, 2 }, + { 0, 5, 42, 7, 63, 17, 1 }, + { 0, 8, 50, 7, 58, 12, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 29, 66, 7, 29, 2, 0 }, + { 0, 4, 36, 7, 66, 21, 1 }, + { 0, 6, 45, 7, 61, 15, 1 }, + { 0, 9, 52, 7, 56, 11, 0 }, + { 1, 13, 59, 7, 48, 7, 0 }, + { 1, 19, 63, 7, 40, 5, 0 }, + { 2, 26, 65, 7, 32, 3, 0 }, + { 0, 3, 33, 7, 66, 24, 2 }, + { 0, 5, 41, 7, 63, 18, 1 }, + { 0, 8, 49, 7, 59, 12, 0 }, + { 0, 12, 57, 7, 51, 8, 0 }, + { 1, 17, 62, 7, 43, 5, 0 }, + { 1, 23, 66, 7, 35, 3, 0 }, + { 0, 3, 30, 7, 66, 27, 2 }, + { 0, 4, 38, 7, 65, 20, 1 }, + { 0, 7, 46, 7, 60, 14, 1 }, + { 0, 10, 54, 7, 54, 10, 0 }, + { 1, 14, 60, 7, 46, 7, 0 }, + { 1, 20, 65, 7, 38, 4, 0 }, + { 2, 27, 66, 7, 30, 3, 0 }, + { 0, 3, 35, 7, 66, 23, 1 }, + { 0, 5, 43, 7, 62, 17, 1 }, + { 0, 8, 51, 7, 57, 12, 0 }, + { 0, 12, 59, 7, 49, 8, 0 }, + { 1, 18, 63, 7, 41, 5, 0 }, + { 2, 24, 66, 7, 33, 3, 0 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 5, 40, 7, 63, 19, 1 }, + { 0, 7, 48, 7, 59, 13, 1 }, + { 0, 11, 56, 7, 52, 9, 0 }, + { 1, 15, 61, 7, 45, 6, 0 }, + { 1, 21, 66, 7, 36, 4, 0 } }, + .odd = { { 0, 12, 58, 7, 50, 8, 0 }, + { 1, 17, 63, 7, 42, 5, 0 }, + { 2, 23, 66, 7, 34, 3, 0 }, + { 0, 3, 31, 7, 66, 26, 2 }, + { 0, 4, 39, 7, 64, 20, 1 }, + { 0, 7, 47, 7, 59, 14, 1 }, + { 0, 10, 55, 7, 53, 10, 0 }, + { 1, 15, 61, 7, 45, 6, 0 }, + { 1, 21, 65, 7, 37, 4, 0 }, + { 2, 28, 67, 7, 29, 2, 0 }, + { 0, 4, 36, 7, 65, 22, 1 }, + { 0, 6, 44, 7, 61, 16, 1 }, + { 0, 9, 52, 7, 56, 11, 0 }, + { 1, 13, 58, 7, 49, 7, 0 }, + { 1, 18, 64, 7, 40, 5, 0 }, + { 2, 25, 66, 7, 32, 3, 0 }, + { 0, 3, 32, 7, 66, 25, 2 }, + { 0, 5, 40, 7, 64, 18, 1 }, + { 0, 7, 49, 7, 58, 13, 1 }, + { 0, 11, 56, 7, 52, 9, 0 }, + { 1, 16, 61, 7, 44, 6, 0 }, + { 1, 22, 65, 7, 36, 4, 0 }, + { 0, 2, 29, 7, 67, 28, 2 }, + { 0, 4, 37, 7, 65, 21, 1 }, + { 0, 6, 45, 7, 61, 15, 1 }, + { 0, 10, 53, 7, 55, 10, 0 }, + { 1, 14, 59, 7, 47, 7, 0 }, + { 1, 20, 64, 7, 39, 4, 0 }, + { 2, 26, 66, 7, 31, 3, 0 }, + { 0, 3, 34, 7, 66, 23, 2 }, + { 0, 5, 42, 7, 63, 17, 1 }, + { 0, 8, 50, 7, 58, 12, 0 } } }, + .ptrn_arr = { { 0x42484849, 0x12124242, 0x90909212, 0x24848484, + 0x21242424, 0x9090921, 0x48484849, 0x24242 } }, + .sample_patrn_length = 246, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 92) = 0.258065 */ + .hor_phase_arr = { + .even = { { 2, 29, 66, 7, 29, 2, 0 }, + { 0, 4, 35, 7, 64, 23, 2 }, + { 0, 5, 41, 7, 63, 18, 1 }, + { 0, 7, 48, 7, 58, 14, 1 }, + { 0, 10, 54, 7, 54, 10, 0 }, + { 1, 14, 58, 7, 48, 7, 0 }, + { 1, 18, 63, 7, 41, 5, 0 }, + { 2, 23, 64, 7, 35, 4, 0 } }, + .odd = { { 0, 12, 56, 7, 51, 9, 0 }, + { 1, 16, 61, 7, 44, 6, 0 }, + { 1, 20, 65, 7, 38, 4, 0 }, + { 2, 26, 65, 7, 32, 3, 0 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 4, 38, 7, 65, 20, 1 }, + { 0, 6, 44, 7, 61, 16, 1 }, + { 0, 9, 51, 7, 56, 12, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 29, 66, 7, 29, 2, 0 }, + { 0, 4, 35, 7, 64, 23, 2 }, + { 0, 5, 41, 7, 63, 18, 1 }, + { 0, 7, 48, 7, 58, 14, 1 }, + { 0, 10, 54, 7, 54, 10, 0 }, + { 1, 14, 58, 7, 48, 7, 0 }, + { 1, 18, 63, 7, 41, 5, 0 }, + { 2, 23, 64, 7, 35, 4, 0 } }, + .odd = { { 0, 12, 56, 7, 51, 9, 0 }, + { 1, 16, 61, 7, 44, 6, 0 }, + { 1, 20, 65, 7, 38, 4, 0 }, + { 2, 26, 65, 7, 32, 3, 0 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 4, 38, 7, 65, 20, 1 }, + { 0, 6, 44, 7, 61, 16, 1 }, + { 0, 9, 51, 7, 56, 12, 0 } } }, + .ptrn_arr = { { 0x48484849, 0x2424242 } }, + .sample_patrn_length = 62, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 93) = 0.256 */ + .hor_phase_arr = { + .even = { { 2, 29, 66, 7, 29, 2, 0 }, + { 0, 3, 33, 7, 65, 25, 2 }, + { 0, 4, 38, 7, 64, 21, 1 }, + { 0, 6, 43, 7, 61, 17, 1 }, + { 0, 8, 47, 7, 58, 14, 1 }, + { 0, 10, 52, 7, 55, 11, 0 }, + { 1, 12, 56, 7, 50, 9, 0 }, + { 1, 15, 59, 7, 46, 7, 0 }, + { 1, 18, 63, 7, 41, 5, 0 }, + { 1, 22, 65, 7, 36, 4, 0 }, + { 2, 26, 65, 7, 32, 3, 0 }, + { 0, 3, 30, 7, 66, 27, 2 }, + { 0, 4, 35, 7, 64, 23, 2 }, + { 0, 5, 40, 7, 63, 19, 1 }, + { 0, 6, 44, 7, 61, 16, 1 }, + { 0, 8, 49, 7, 57, 13, 1 }, + { 0, 10, 55, 7, 53, 10, 0 }, + { 1, 13, 57, 7, 49, 8, 0 }, + { 1, 16, 61, 7, 44, 6, 0 }, + { 1, 19, 63, 7, 40, 5, 0 }, + { 2, 23, 64, 7, 35, 4, 0 }, + { 2, 27, 66, 7, 30, 3, 0 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 4, 36, 7, 65, 22, 1 }, + { 0, 5, 41, 7, 63, 18, 1 }, + { 0, 7, 46, 7, 59, 15, 1 }, + { 0, 9, 50, 7, 56, 12, 1 }, + { 0, 11, 55, 7, 52, 10, 0 }, + { 1, 14, 58, 7, 47, 8, 0 }, + { 1, 17, 61, 7, 43, 6, 0 }, + { 1, 21, 64, 7, 38, 4, 0 }, + { 2, 25, 65, 7, 33, 3, 0 } }, + .odd = { { 0, 12, 56, 7, 51, 9, 0 }, + { 1, 14, 59, 7, 47, 7, 0 }, + { 1, 18, 61, 7, 42, 6, 0 }, + { 1, 21, 65, 7, 37, 4, 0 }, + { 2, 25, 65, 7, 33, 3, 0 }, + { 0, 3, 30, 7, 65, 28, 2 }, + { 0, 3, 34, 7, 65, 24, 2 }, + { 0, 5, 39, 7, 63, 20, 1 }, + { 0, 6, 44, 7, 61, 16, 1 }, + { 0, 8, 48, 7, 58, 13, 1 }, + { 0, 10, 53, 7, 54, 11, 0 }, + { 1, 12, 57, 7, 50, 8, 0 }, + { 1, 15, 60, 7, 45, 7, 0 }, + { 1, 19, 63, 7, 40, 5, 0 }, + { 2, 23, 63, 7, 36, 4, 0 }, + { 2, 27, 65, 7, 31, 3, 0 }, + { 0, 3, 31, 7, 65, 27, 2 }, + { 0, 4, 36, 7, 63, 23, 2 }, + { 0, 5, 40, 7, 63, 19, 1 }, + { 0, 7, 45, 7, 60, 15, 1 }, + { 0, 8, 50, 7, 57, 12, 1 }, + { 0, 11, 54, 7, 53, 10, 0 }, + { 1, 13, 58, 7, 48, 8, 0 }, + { 1, 16, 61, 7, 44, 6, 0 }, + { 1, 20, 63, 7, 39, 5, 0 }, + { 2, 24, 65, 7, 34, 3, 0 }, + { 2, 28, 65, 7, 30, 3, 0 }, + { 0, 3, 33, 7, 65, 25, 2 }, + { 0, 4, 37, 7, 65, 21, 1 }, + { 0, 6, 42, 7, 61, 18, 1 }, + { 0, 7, 47, 7, 59, 14, 1 }, + { 0, 9, 51, 7, 56, 12, 0 } } }, + .ver_phase_arr = { + .even = { { 2, 29, 66, 7, 29, 2, 0 }, + { 0, 3, 33, 7, 65, 25, 2 }, + { 0, 4, 38, 7, 64, 21, 1 }, + { 0, 6, 43, 7, 61, 17, 1 }, + { 0, 8, 47, 7, 58, 14, 1 }, + { 0, 10, 52, 7, 55, 11, 0 }, + { 1, 12, 56, 7, 50, 9, 0 }, + { 1, 15, 59, 7, 46, 7, 0 }, + { 1, 18, 63, 7, 41, 5, 0 }, + { 1, 22, 65, 7, 36, 4, 0 }, + { 2, 26, 65, 7, 32, 3, 0 }, + { 0, 3, 30, 7, 66, 27, 2 }, + { 0, 4, 35, 7, 64, 23, 2 }, + { 0, 5, 40, 7, 63, 19, 1 }, + { 0, 6, 44, 7, 61, 16, 1 }, + { 0, 8, 49, 7, 57, 13, 1 }, + { 0, 10, 55, 7, 53, 10, 0 }, + { 1, 13, 57, 7, 49, 8, 0 }, + { 1, 16, 61, 7, 44, 6, 0 }, + { 1, 19, 63, 7, 40, 5, 0 }, + { 2, 23, 64, 7, 35, 4, 0 }, + { 2, 27, 66, 7, 30, 3, 0 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 4, 36, 7, 65, 22, 1 }, + { 0, 5, 41, 7, 63, 18, 1 }, + { 0, 7, 46, 7, 59, 15, 1 }, + { 0, 9, 50, 7, 56, 12, 1 }, + { 0, 11, 55, 7, 52, 10, 0 }, + { 1, 14, 58, 7, 47, 8, 0 }, + { 1, 17, 61, 7, 43, 6, 0 }, + { 1, 21, 64, 7, 38, 4, 0 }, + { 2, 25, 65, 7, 33, 3, 0 } }, + .odd = { { 0, 12, 56, 7, 51, 9, 0 }, + { 1, 14, 59, 7, 47, 7, 0 }, + { 1, 18, 61, 7, 42, 6, 0 }, + { 1, 21, 65, 7, 37, 4, 0 }, + { 2, 25, 65, 7, 33, 3, 0 }, + { 0, 3, 30, 7, 65, 28, 2 }, + { 0, 3, 34, 7, 65, 24, 2 }, + { 0, 5, 39, 7, 63, 20, 1 }, + { 0, 6, 44, 7, 61, 16, 1 }, + { 0, 8, 48, 7, 58, 13, 1 }, + { 0, 10, 53, 7, 54, 11, 0 }, + { 1, 12, 57, 7, 50, 8, 0 }, + { 1, 15, 60, 7, 45, 7, 0 }, + { 1, 19, 63, 7, 40, 5, 0 }, + { 2, 23, 63, 7, 36, 4, 0 }, + { 2, 27, 65, 7, 31, 3, 0 }, + { 0, 3, 31, 7, 65, 27, 2 }, + { 0, 4, 36, 7, 63, 23, 2 }, + { 0, 5, 40, 7, 63, 19, 1 }, + { 0, 7, 45, 7, 60, 15, 1 }, + { 0, 8, 50, 7, 57, 12, 1 }, + { 0, 11, 54, 7, 53, 10, 0 }, + { 1, 13, 58, 7, 48, 8, 0 }, + { 1, 16, 61, 7, 44, 6, 0 }, + { 1, 20, 63, 7, 39, 5, 0 }, + { 2, 24, 65, 7, 34, 3, 0 }, + { 2, 28, 65, 7, 30, 3, 0 }, + { 0, 3, 33, 7, 65, 25, 2 }, + { 0, 4, 37, 7, 65, 21, 1 }, + { 0, 6, 42, 7, 61, 18, 1 }, + { 0, 7, 47, 7, 59, 14, 1 }, + { 0, 9, 51, 7, 56, 12, 0 } } }, + .ptrn_arr = { { 0x48484849, 0x42424248, 0x12124242, 0x92121212, + 0x90909090, 0x84848490, 0x24248484, 0x242424 } }, + .sample_patrn_length = 250, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 94) = 0.253968 */ + .hor_phase_arr = { + .even = { { 3, 29, 64, 7, 29, 3, 0 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 4, 35, 7, 64, 23, 2 }, + { 0, 5, 38, 7, 63, 21, 1 }, + { 0, 5, 41, 7, 63, 18, 1 }, + { 0, 7, 44, 7, 60, 16, 1 }, + { 0, 8, 47, 7, 58, 14, 1 }, + { 0, 9, 50, 7, 56, 12, 1 }, + { 0, 11, 53, 7, 53, 11, 0 }, + { 1, 12, 56, 7, 50, 9, 0 }, + { 1, 14, 58, 7, 47, 8, 0 }, + { 1, 16, 60, 7, 44, 7, 0 }, + { 1, 18, 63, 7, 41, 5, 0 }, + { 1, 21, 63, 7, 38, 5, 0 }, + { 2, 23, 64, 7, 35, 4, 0 }, + { 2, 26, 65, 7, 32, 3, 0 } }, + .odd = { { 0, 11, 55, 7, 52, 10, 0 }, + { 1, 13, 57, 7, 49, 8, 0 }, + { 1, 15, 59, 7, 46, 7, 0 }, + { 1, 17, 61, 7, 43, 6, 0 }, + { 1, 20, 62, 7, 40, 5, 0 }, + { 2, 22, 63, 7, 37, 4, 0 }, + { 2, 25, 65, 7, 33, 3, 0 }, + { 2, 28, 65, 7, 30, 3, 0 }, + { 0, 3, 30, 7, 65, 28, 2 }, + { 0, 3, 33, 7, 65, 25, 2 }, + { 0, 4, 37, 7, 63, 22, 2 }, + { 0, 5, 40, 7, 62, 20, 1 }, + { 0, 6, 43, 7, 61, 17, 1 }, + { 0, 7, 46, 7, 59, 15, 1 }, + { 0, 8, 49, 7, 57, 13, 1 }, + { 0, 10, 52, 7, 55, 11, 0 } } }, + .ver_phase_arr = { + .even = { { 3, 29, 64, 7, 29, 3, 0 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 4, 35, 7, 64, 23, 2 }, + { 0, 5, 38, 7, 63, 21, 1 }, + { 0, 5, 41, 7, 63, 18, 1 }, + { 0, 7, 44, 7, 60, 16, 1 }, + { 0, 8, 47, 7, 58, 14, 1 }, + { 0, 9, 50, 7, 56, 12, 1 }, + { 0, 11, 53, 7, 53, 11, 0 }, + { 1, 12, 56, 7, 50, 9, 0 }, + { 1, 14, 58, 7, 47, 8, 0 }, + { 1, 16, 60, 7, 44, 7, 0 }, + { 1, 18, 63, 7, 41, 5, 0 }, + { 1, 21, 63, 7, 38, 5, 0 }, + { 2, 23, 64, 7, 35, 4, 0 }, + { 2, 26, 65, 7, 32, 3, 0 } }, + .odd = { { 0, 11, 55, 7, 52, 10, 0 }, + { 1, 13, 57, 7, 49, 8, 0 }, + { 1, 15, 59, 7, 46, 7, 0 }, + { 1, 17, 61, 7, 43, 6, 0 }, + { 1, 20, 62, 7, 40, 5, 0 }, + { 2, 22, 63, 7, 37, 4, 0 }, + { 2, 25, 65, 7, 33, 3, 0 }, + { 2, 28, 65, 7, 30, 3, 0 }, + { 0, 3, 30, 7, 65, 28, 2 }, + { 0, 3, 33, 7, 65, 25, 2 }, + { 0, 4, 37, 7, 63, 22, 2 }, + { 0, 5, 40, 7, 62, 20, 1 }, + { 0, 6, 43, 7, 61, 17, 1 }, + { 0, 7, 46, 7, 59, 15, 1 }, + { 0, 8, 49, 7, 57, 13, 1 }, + { 0, 10, 52, 7, 55, 11, 0 } } }, + .ptrn_arr = { { 0x48484849, 0x48484848, 0x42424242, 0x2424242 } }, + .sample_patrn_length = 126, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 95) = 0.251969 */ + .hor_phase_arr = { + .even = { { 3, 29, 64, 7, 29, 3, 0 }, + { 0, 3, 31, 7, 64, 28, 2 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 4, 34, 7, 63, 25, 2 }, + { 0, 4, 35, 7, 63, 24, 2 }, + { 0, 4, 37, 7, 63, 22, 2 }, + { 0, 5, 38, 7, 63, 21, 1 }, + { 0, 5, 40, 7, 62, 20, 1 }, + { 0, 6, 41, 7, 61, 19, 1 }, + { 0, 6, 43, 7, 61, 17, 1 }, + { 0, 7, 44, 7, 60, 16, 1 }, + { 0, 7, 46, 7, 59, 15, 1 }, + { 0, 8, 47, 7, 58, 14, 1 }, + { 0, 9, 49, 7, 56, 13, 1 }, + { 0, 9, 50, 7, 56, 12, 1 }, + { 0, 10, 51, 7, 54, 12, 1 }, + { 0, 11, 53, 7, 53, 11, 0 }, + { 1, 12, 54, 7, 51, 10, 0 }, + { 1, 12, 56, 7, 50, 9, 0 }, + { 1, 13, 56, 7, 49, 9, 0 }, + { 1, 14, 58, 7, 47, 8, 0 }, + { 1, 15, 59, 7, 46, 7, 0 }, + { 1, 16, 60, 7, 44, 7, 0 }, + { 1, 17, 61, 7, 43, 6, 0 }, + { 1, 19, 61, 7, 41, 6, 0 }, + { 1, 20, 62, 7, 40, 5, 0 }, + { 1, 21, 63, 7, 38, 5, 0 }, + { 2, 22, 63, 7, 37, 4, 0 }, + { 2, 24, 63, 7, 35, 4, 0 }, + { 2, 25, 63, 7, 34, 4, 0 }, + { 2, 26, 65, 7, 32, 3, 0 }, + { 2, 28, 64, 7, 31, 3, 0 } }, + .odd = { { 0, 11, 55, 7, 52, 10, 0 }, + { 1, 12, 54, 7, 51, 10, 0 }, + { 1, 13, 56, 7, 49, 9, 0 }, + { 1, 14, 57, 7, 48, 8, 0 }, + { 1, 15, 58, 7, 46, 8, 0 }, + { 1, 16, 59, 7, 45, 7, 0 }, + { 1, 17, 61, 7, 43, 6, 0 }, + { 1, 18, 61, 7, 42, 6, 0 }, + { 1, 19, 63, 7, 40, 5, 0 }, + { 1, 20, 63, 7, 39, 5, 0 }, + { 2, 22, 62, 7, 37, 5, 0 }, + { 2, 23, 63, 7, 36, 4, 0 }, + { 2, 24, 64, 7, 34, 4, 0 }, + { 2, 26, 64, 7, 33, 3, 0 }, + { 2, 27, 65, 7, 31, 3, 0 }, + { 3, 28, 64, 7, 30, 3, 0 }, + { 0, 3, 30, 7, 64, 28, 3 }, + { 0, 3, 31, 7, 65, 27, 2 }, + { 0, 3, 33, 7, 64, 26, 2 }, + { 0, 4, 34, 7, 64, 24, 2 }, + { 0, 4, 36, 7, 63, 23, 2 }, + { 0, 5, 37, 7, 62, 22, 2 }, + { 0, 5, 39, 7, 63, 20, 1 }, + { 0, 5, 40, 7, 63, 19, 1 }, + { 0, 6, 42, 7, 61, 18, 1 }, + { 0, 6, 43, 7, 61, 17, 1 }, + { 0, 7, 45, 7, 59, 16, 1 }, + { 0, 8, 46, 7, 58, 15, 1 }, + { 0, 8, 48, 7, 57, 14, 1 }, + { 0, 9, 49, 7, 56, 13, 1 }, + { 0, 10, 51, 7, 54, 12, 1 }, + { 0, 10, 52, 7, 55, 11, 0 } } }, + .ver_phase_arr = { + .even = { { 3, 29, 64, 7, 29, 3, 0 }, + { 0, 3, 31, 7, 64, 28, 2 }, + { 0, 3, 32, 7, 65, 26, 2 }, + { 0, 4, 34, 7, 63, 25, 2 }, + { 0, 4, 35, 7, 63, 24, 2 }, + { 0, 4, 37, 7, 63, 22, 2 }, + { 0, 5, 38, 7, 63, 21, 1 }, + { 0, 5, 40, 7, 62, 20, 1 }, + { 0, 6, 41, 7, 61, 19, 1 }, + { 0, 6, 43, 7, 61, 17, 1 }, + { 0, 7, 44, 7, 60, 16, 1 }, + { 0, 7, 46, 7, 59, 15, 1 }, + { 0, 8, 47, 7, 58, 14, 1 }, + { 0, 9, 49, 7, 56, 13, 1 }, + { 0, 9, 50, 7, 56, 12, 1 }, + { 0, 10, 51, 7, 54, 12, 1 }, + { 0, 11, 53, 7, 53, 11, 0 }, + { 1, 12, 54, 7, 51, 10, 0 }, + { 1, 12, 56, 7, 50, 9, 0 }, + { 1, 13, 56, 7, 49, 9, 0 }, + { 1, 14, 58, 7, 47, 8, 0 }, + { 1, 15, 59, 7, 46, 7, 0 }, + { 1, 16, 60, 7, 44, 7, 0 }, + { 1, 17, 61, 7, 43, 6, 0 }, + { 1, 19, 61, 7, 41, 6, 0 }, + { 1, 20, 62, 7, 40, 5, 0 }, + { 1, 21, 63, 7, 38, 5, 0 }, + { 2, 22, 63, 7, 37, 4, 0 }, + { 2, 24, 63, 7, 35, 4, 0 }, + { 2, 25, 63, 7, 34, 4, 0 }, + { 2, 26, 65, 7, 32, 3, 0 }, + { 2, 28, 64, 7, 31, 3, 0 } }, + .odd = { { 0, 11, 55, 7, 52, 10, 0 }, + { 1, 12, 54, 7, 51, 10, 0 }, + { 1, 13, 56, 7, 49, 9, 0 }, + { 1, 14, 57, 7, 48, 8, 0 }, + { 1, 15, 58, 7, 46, 8, 0 }, + { 1, 16, 59, 7, 45, 7, 0 }, + { 1, 17, 61, 7, 43, 6, 0 }, + { 1, 18, 61, 7, 42, 6, 0 }, + { 1, 19, 63, 7, 40, 5, 0 }, + { 1, 20, 63, 7, 39, 5, 0 }, + { 2, 22, 62, 7, 37, 5, 0 }, + { 2, 23, 63, 7, 36, 4, 0 }, + { 2, 24, 64, 7, 34, 4, 0 }, + { 2, 26, 64, 7, 33, 3, 0 }, + { 2, 27, 65, 7, 31, 3, 0 }, + { 3, 28, 64, 7, 30, 3, 0 }, + { 0, 3, 30, 7, 64, 28, 3 }, + { 0, 3, 31, 7, 65, 27, 2 }, + { 0, 3, 33, 7, 64, 26, 2 }, + { 0, 4, 34, 7, 64, 24, 2 }, + { 0, 4, 36, 7, 63, 23, 2 }, + { 0, 5, 37, 7, 62, 22, 2 }, + { 0, 5, 39, 7, 63, 20, 1 }, + { 0, 5, 40, 7, 63, 19, 1 }, + { 0, 6, 42, 7, 61, 18, 1 }, + { 0, 6, 43, 7, 61, 17, 1 }, + { 0, 7, 45, 7, 59, 16, 1 }, + { 0, 8, 46, 7, 58, 15, 1 }, + { 0, 8, 48, 7, 57, 14, 1 }, + { 0, 9, 49, 7, 56, 13, 1 }, + { 0, 10, 51, 7, 54, 12, 1 }, + { 0, 10, 52, 7, 55, 11, 0 } } }, + .ptrn_arr = { { 0x48484849, 0x48484848, 0x48484848, 0x48484848, + 0x42424242, 0x42424242, 0x42424242, 0x2424242 } }, + .sample_patrn_length = 254, + .hor_ds_en = 1, + .ver_ds_en = 1 +}, { + /* Scale factor 32 / (32 + 96) = 0.25 */ + .hor_phase_arr = { + .even = { { 3, 29, 64, 7, 29, 3, 0 } }, + .odd = { { 0, 11, 53, 7, 53, 11, 0 } } }, + .ver_phase_arr = { + .even = { { 3, 29, 64, 7, 29, 3, 0 } }, + .odd = { { 0, 11, 53, 7, 53, 11, 0 } } }, + .ptrn_arr = { { 0x9 } }, + .sample_patrn_length = 8, + .hor_ds_en = 1, + .ver_ds_en = 1 +} }; + +const s32 ipu3_css_downscale_4taps[IMGU_SCALER_DOWNSCALE_4TAPS_LEN] = { + IMGU_SCALER_FP * -0.000000000000000, + IMGU_SCALER_FP * -0.000249009327023, + IMGU_SCALER_FP * -0.001022241683322, + IMGU_SCALER_FP * -0.002352252699175, + IMGU_SCALER_FP * -0.004261594242362, + IMGU_SCALER_FP * -0.006761648795689, + IMGU_SCALER_FP * -0.009851589454154, + IMGU_SCALER_FP * -0.013517488475013, + IMGU_SCALER_FP * -0.017731595701026, + IMGU_SCALER_FP * -0.022451806160682, + IMGU_SCALER_FP * -0.027621333752351, + IMGU_SCALER_FP * -0.033168605172067, + IMGU_SCALER_FP * -0.039007385183627, + IMGU_SCALER_FP * -0.045037140997445, + IMGU_SCALER_FP * -0.051143649969349, + IMGU_SCALER_FP * -0.057199851105019, + IMGU_SCALER_FP * -0.063066937016941, + IMGU_SCALER_FP * -0.068595679088417, + IMGU_SCALER_FP * -0.073627974715370, + IMGU_SCALER_FP * -0.077998601684588, + IMGU_SCALER_FP * -0.081537161069780, + IMGU_SCALER_FP * -0.084070186546763, + IMGU_SCALER_FP * -0.085423394806327, + IMGU_SCALER_FP * -0.085424048835192, + IMGU_SCALER_FP * -0.083903403294908, + IMGU_SCALER_FP * -0.080699199103829, + IMGU_SCALER_FP * -0.075658172660608, + IMGU_SCALER_FP * -0.068638543974523, + IMGU_SCALER_FP * -0.059512447316781, + IMGU_SCALER_FP * -0.048168267897836, + IMGU_SCALER_FP * -0.034512848520921, + IMGU_SCALER_FP * -0.018473531164409, + IMGU_SCALER_FP * 0.000000000000000, + IMGU_SCALER_FP * 0.020934105554674, + IMGU_SCALER_FP * 0.044329836544650, + IMGU_SCALER_FP * 0.070161864654994, + IMGU_SCALER_FP * 0.098377719033862, + IMGU_SCALER_FP * 0.128897348012514, + IMGU_SCALER_FP * 0.161613019706978, + IMGU_SCALER_FP * 0.196389570939079, + IMGU_SCALER_FP * 0.233065009152522, + IMGU_SCALER_FP * 0.271451467092549, + IMGU_SCALER_FP * 0.311336505037934, + IMGU_SCALER_FP * 0.352484750396743, + IMGU_SCALER_FP * 0.394639859577736, + IMGU_SCALER_FP * 0.437526782302744, + IMGU_SCALER_FP * 0.480854304005320, + IMGU_SCALER_FP * 0.524317837738108, + IMGU_SCALER_FP * 0.567602433152471, + IMGU_SCALER_FP * 0.610385966680669, + IMGU_SCALER_FP * 0.652342474098843, + IMGU_SCALER_FP * 0.693145584226952, + IMGU_SCALER_FP * 0.732472010670320, + IMGU_SCALER_FP * 0.770005057258970, + IMGU_SCALER_FP * 0.805438092218553, + IMGU_SCALER_FP * 0.838477946124244, + IMGU_SCALER_FP * 0.868848189350256, + IMGU_SCALER_FP * 0.896292246026874, + IMGU_SCALER_FP * 0.920576303438191, + IMGU_SCALER_FP * 0.941491978311745, + IMGU_SCALER_FP * 0.958858704531378, + IMGU_SCALER_FP * 0.972525810403401, + IMGU_SCALER_FP * 0.982374257672165, + IMGU_SCALER_FP * 0.988318018955586, + IMGU_SCALER_FP * 0.990305075088925, + IMGU_SCALER_FP * 0.988318018955586, + IMGU_SCALER_FP * 0.982374257672165, + IMGU_SCALER_FP * 0.972525810403401, + IMGU_SCALER_FP * 0.958858704531378, + IMGU_SCALER_FP * 0.941491978311745, + IMGU_SCALER_FP * 0.920576303438191, + IMGU_SCALER_FP * 0.896292246026874, + IMGU_SCALER_FP * 0.868848189350256, + IMGU_SCALER_FP * 0.838477946124244, + IMGU_SCALER_FP * 0.805438092218553, + IMGU_SCALER_FP * 0.770005057258970, + IMGU_SCALER_FP * 0.732472010670320, + IMGU_SCALER_FP * 0.693145584226952, + IMGU_SCALER_FP * 0.652342474098843, + IMGU_SCALER_FP * 0.610385966680669, + IMGU_SCALER_FP * 0.567602433152471, + IMGU_SCALER_FP * 0.524317837738108, + IMGU_SCALER_FP * 0.480854304005320, + IMGU_SCALER_FP * 0.437526782302744, + IMGU_SCALER_FP * 0.394639859577736, + IMGU_SCALER_FP * 0.352484750396743, + IMGU_SCALER_FP * 0.311336505037934, + IMGU_SCALER_FP * 0.271451467092549, + IMGU_SCALER_FP * 0.233065009152522, + IMGU_SCALER_FP * 0.196389570939079, + IMGU_SCALER_FP * 0.161613019706978, + IMGU_SCALER_FP * 0.128897348012514, + IMGU_SCALER_FP * 0.098377719033862, + IMGU_SCALER_FP * 0.070161864654994, + IMGU_SCALER_FP * 0.044329836544650, + IMGU_SCALER_FP * 0.020934105554674, + IMGU_SCALER_FP * 0.000000000000000, + IMGU_SCALER_FP * -0.018473531164409, + IMGU_SCALER_FP * -0.034512848520921, + IMGU_SCALER_FP * -0.048168267897836, + IMGU_SCALER_FP * -0.059512447316781, + IMGU_SCALER_FP * -0.068638543974523, + IMGU_SCALER_FP * -0.075658172660608, + IMGU_SCALER_FP * -0.080699199103829, + IMGU_SCALER_FP * -0.083903403294908, + IMGU_SCALER_FP * -0.085424048835192, + IMGU_SCALER_FP * -0.085423394806327, + IMGU_SCALER_FP * -0.084070186546763, + IMGU_SCALER_FP * -0.081537161069780, + IMGU_SCALER_FP * -0.077998601684588, + IMGU_SCALER_FP * -0.073627974715370, + IMGU_SCALER_FP * -0.068595679088417, + IMGU_SCALER_FP * -0.063066937016941, + IMGU_SCALER_FP * -0.057199851105019, + IMGU_SCALER_FP * -0.051143649969349, + IMGU_SCALER_FP * -0.045037140997445, + IMGU_SCALER_FP * -0.039007385183627, + IMGU_SCALER_FP * -0.033168605172067, + IMGU_SCALER_FP * -0.027621333752351, + IMGU_SCALER_FP * -0.022451806160682, + IMGU_SCALER_FP * -0.017731595701026, + IMGU_SCALER_FP * -0.013517488475013, + IMGU_SCALER_FP * -0.009851589454154, + IMGU_SCALER_FP * -0.006761648795689, + IMGU_SCALER_FP * -0.004261594242362, + IMGU_SCALER_FP * -0.002352252699175, + IMGU_SCALER_FP * -0.001022241683322, + IMGU_SCALER_FP * -0.000249009327023 +}; + +const s32 ipu3_css_downscale_2taps[IMGU_SCALER_DOWNSCALE_2TAPS_LEN] = { + IMGU_SCALER_FP * 0.074300676367033, + IMGU_SCALER_FP * 0.094030234498392, + IMGU_SCALER_FP * 0.115522859526596, + IMGU_SCALER_FP * 0.138778551451644, + IMGU_SCALER_FP * 0.163629399140505, + IMGU_SCALER_FP * 0.190075402593178, + IMGU_SCALER_FP * 0.217864695110113, + IMGU_SCALER_FP * 0.247081232257828, + IMGU_SCALER_FP * 0.277389191770256, + IMGU_SCALER_FP * 0.308704618080881, + IMGU_SCALER_FP * 0.340859600056670, + IMGU_SCALER_FP * 0.373602270998074, + IMGU_SCALER_FP * 0.406848675338577, + IMGU_SCALER_FP * 0.440346946378629, + IMGU_SCALER_FP * 0.473845217418681, + IMGU_SCALER_FP * 0.507091621759184, + IMGU_SCALER_FP * 0.540002203833621, + IMGU_SCALER_FP * 0.572157185809410, + IMGU_SCALER_FP * 0.603472612120036, + IMGU_SCALER_FP * 0.633612660499431, + IMGU_SCALER_FP * 0.662493375381080, + IMGU_SCALER_FP * 0.689778934498917, + IMGU_SCALER_FP * 0.715301426719909, + IMGU_SCALER_FP * 0.738892940911023, + IMGU_SCALER_FP * 0.760385565939227, + IMGU_SCALER_FP * 0.779527435104971, + IMGU_SCALER_FP * 0.796234592841739, + IMGU_SCALER_FP * 0.810339128016497, + IMGU_SCALER_FP * 0.821841040629247, + IMGU_SCALER_FP * 0.830488463980438, + IMGU_SCALER_FP * 0.836281398070072, + IMGU_SCALER_FP * 0.839219842898146, + IMGU_SCALER_FP * 0.839219842898146, + IMGU_SCALER_FP * 0.836281398070072, + IMGU_SCALER_FP * 0.830488463980438, + IMGU_SCALER_FP * 0.821841040629247, + IMGU_SCALER_FP * 0.810339128016497, + IMGU_SCALER_FP * 0.796234592841739, + IMGU_SCALER_FP * 0.779527435104971, + IMGU_SCALER_FP * 0.760385565939227, + IMGU_SCALER_FP * 0.738892940911023, + IMGU_SCALER_FP * 0.715301426719909, + IMGU_SCALER_FP * 0.689778934498917, + IMGU_SCALER_FP * 0.662493375381080, + IMGU_SCALER_FP * 0.633612660499431, + IMGU_SCALER_FP * 0.603472612120036, + IMGU_SCALER_FP * 0.572157185809410, + IMGU_SCALER_FP * 0.540002203833621, + IMGU_SCALER_FP * 0.507091621759184, + IMGU_SCALER_FP * 0.473845217418681, + IMGU_SCALER_FP * 0.440346946378629, + IMGU_SCALER_FP * 0.406848675338577, + IMGU_SCALER_FP * 0.373602270998074, + IMGU_SCALER_FP * 0.340859600056670, + IMGU_SCALER_FP * 0.308704618080881, + IMGU_SCALER_FP * 0.277389191770256, + IMGU_SCALER_FP * 0.247081232257828, + IMGU_SCALER_FP * 0.217864695110113, + IMGU_SCALER_FP * 0.190075402593178, + IMGU_SCALER_FP * 0.163629399140505, + IMGU_SCALER_FP * 0.138778551451644, + IMGU_SCALER_FP * 0.115522859526596, + IMGU_SCALER_FP * 0.094030234498392, + IMGU_SCALER_FP * 0.074300676367033 +}; + +/* settings for Geometric Distortion Correction */ +const s16 ipu3_css_gdc_lut[4][256] = { { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -2, -2, -2, + -2, -3, -3, -3, -4, -4, -4, -5, -5, -5, -6, -6, -7, -7, -7, -8, -8, + -9, -9, -10, -10, -11, -11, -12, -12, -13, -13, -14, -14, -15, -15, + -16, -16, -17, -17, -18, -19, -19, -20, -20, -21, -22, -22, -23, -24, + -24, -25, -25, -26, -27, -27, -28, -29, -29, -30, -31, -31, -32, -33, + -33, -34, -35, -35, -36, -37, -37, -38, -39, -39, -40, -41, -41, -42, + -43, -43, -44, -45, -45, -46, -46, -47, -48, -48, -49, -50, -50, -51, + -52, -52, -53, -53, -54, -55, -55, -56, -56, -57, -58, -58, -59, -59, + -60, -60, -61, -61, -62, -62, -63, -64, -64, -64, -65, -65, -66, -66, + -67, -67, -68, -68, -68, -69, -69, -70, -70, -70, -71, -71, -71, -72, + -72, -72, -73, -73, -73, -73, -74, -74, -74, -74, -74, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -74, -74, -74, -74, -74, -73, -73, -73, -73, -72, + -72, -72, -71, -71, -70, -70, -69, -69, -68, -68, -67, -67, -66, -66, + -65, -64, -64, -63, -62, -61, -61, -60, -59, -58, -57, -56, -56, -55, + -54, -53, -52, -51, -50, -49, -47, -46, -45, -44, -43, -41, -40, -39, + -38, -36, -35, -33, -32, -31, -29, -28, -26, -25, -23, -21, -20, -18, + -16, -15, -13, -11, -9, -7, -5, -3, -1 +}, { + 0, 2, 4, 6, 8, 10, 13, 15, 17, 20, 23, 25, 28, 31, 33, 36, 39, 42, 45, + 48, 51, 54, 58, 61, 64, 68, 71, 74, 78, 82, 85, 89, 93, 96, 100, 104, + 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 162, + 166, 171, 175, 180, 184, 189, 193, 198, 203, 207, 212, 217, 222, 227, + 232, 236, 241, 246, 251, 256, 261, 266, 271, 276, 282, 287, 292, 297, + 302, 307, 313, 318, 323, 328, 334, 339, 344, 350, 355, 360, 366, 371, + 377, 382, 388, 393, 399, 404, 409, 415, 420, 426, 431, 437, 443, 448, + 454, 459, 465, 470, 476, 481, 487, 492, 498, 504, 509, 515, 520, 526, + 531, 537, 542, 548, 553, 559, 564, 570, 576, 581, 586, 592, 597, 603, + 608, 614, 619, 625, 630, 635, 641, 646, 651, 657, 662, 667, 673, 678, + 683, 688, 694, 699, 704, 709, 714, 719, 724, 729, 735, 740, 745, 749, + 754, 759, 764, 769, 774, 779, 783, 788, 793, 797, 802, 807, 811, 816, + 820, 825, 829, 834, 838, 842, 847, 851, 855, 859, 863, 868, 872, 876, + 880, 884, 888, 891, 895, 899, 903, 906, 910, 914, 917, 921, 924, 927, + 931, 934, 937, 940, 944, 947, 950, 953, 956, 959, 961, 964, 967, 970, + 972, 975, 977, 980, 982, 984, 987, 989, 991, 993, 995, 997, 999, 1001, + 1002, 1004, 1006, 1007, 1009, 1010, 1011, 1013, 1014, 1015, 1016, 1017, + 1018, 1019, 1020, 1020, 1021, 1022, 1022, 1023, 1023, 1023, 1023, 1023 +}, { + 1024, 1023, 1023, 1023, 1023, 1023, 1022, 1022, 1021, 1020, 1020, 1019, + 1018, 1017, 1016, 1015, 1014, 1013, 1011, 1010, 1009, 1007, 1006, 1004, + 1002, 1001, 999, 997, 995, 993, 991, 989, 987, 984, 982, 980, 977, 975, + 972, 970, 967, 964, 961, 959, 956, 953, 950, 947, 944, 940, 937, 934, + 931, 927, 924, 921, 917, 914, 910, 906, 903, 899, 895, 891, 888, 884, + 880, 876, 872, 868, 863, 859, 855, 851, 847, 842, 838, 834, 829, 825, + 820, 816, 811, 807, 802, 797, 793, 788, 783, 779, 774, 769, 764, 759, + 754, 749, 745, 740, 735, 729, 724, 719, 714, 709, 704, 699, 694, 688, + 683, 678, 673, 667, 662, 657, 651, 646, 641, 635, 630, 625, 619, 614, + 608, 603, 597, 592, 586, 581, 576, 570, 564, 559, 553, 548, 542, 537, + 531, 526, 520, 515, 509, 504, 498, 492, 487, 481, 476, 470, 465, 459, + 454, 448, 443, 437, 431, 426, 420, 415, 409, 404, 399, 393, 388, 382, + 377, 371, 366, 360, 355, 350, 344, 339, 334, 328, 323, 318, 313, 307, + 302, 297, 292, 287, 282, 276, 271, 266, 261, 256, 251, 246, 241, 236, + 232, 227, 222, 217, 212, 207, 203, 198, 193, 189, 184, 180, 175, 171, + 166, 162, 157, 153, 149, 144, 140, 136, 132, 128, 124, 120, 116, 112, + 108, 104, 100, 96, 93, 89, 85, 82, 78, 74, 71, 68, 64, 61, 58, 54, 51, + 48, 45, 42, 39, 36, 33, 31, 28, 25, 23, 20, 17, 15, 13, 10, 8, 6, 4, 2 +}, { + 0, -1, -3, -5, -7, -9, -11, -13, -14, -16, -19, -20, -21, -23, -24, -26, + -28, -29, -30, -32, -34, -34, -37, -38, -38, -41, -42, -42, -44, -46, + -46, -48, -49, -49, -51, -52, -53, -54, -55, -56, -57, -57, -58, -59, + -60, -60, -62, -62, -63, -63, -64, -65, -66, -66, -67, -68, -67, -69, + -69, -69, -70, -70, -71, -71, -72, -72, -72, -73, -73, -73, -73, -73, + -73, -74, -75, -74, -75, -75, -74, -75, -75, -75, -75, -75, -75, -75, + -75, -75, -75, -75, -75, -75, -75, -74, -75, -74, -75, -75, -74, -74, + -73, -73, -73, -73, -73, -73, -73, -71, -72, -71, -72, -70, -70, -70, + -69, -70, -69, -68, -68, -68, -67, -67, -66, -66, -65, -65, -64, -64, + -64, -63, -62, -62, -61, -61, -60, -60, -59, -59, -58, -58, -57, -57, + -55, -55, -55, -53, -54, -53, -52, -51, -52, -50, -50, -49, -48, -47, + -46, -46, -46, -46, -45, -43, -43, -42, -42, -41, -41, -40, -39, -39, + -38, -37, -37, -36, -35, -35, -34, -33, -32, -32, -31, -31, -31, -29, + -28, -27, -27, -27, -26, -25, -25, -24, -24, -23, -22, -22, -21, -20, + -20, -20, -18, -19, -17, -17, -16, -16, -15, -14, -14, -14, -14, -12, + -12, -12, -11, -11, -11, -10, -9, -9, -8, -8, -7, -6, -7, -7, -6, -6, + -5, -4, -5, -5, -3, -3, -4, -2, -3, -2, -1, -2, -1, -1, 0, -1, -1, 0, + -1, 0, 1, 0, 0, 0, 0, 0, 0, 0 +} }; + +const struct ipu3_css_xnr3_vmem_defaults ipu3_css_xnr3_vmem_defaults = { + .x = { + 1024, 1164, 1320, 1492, 1680, 1884, 2108, 2352, + 2616, 2900, 3208, 3540, 3896, 4276, 4684, 5120 + }, + .a = { + -7213, -5580, -4371, -3421, -2722, -2159, -6950, -5585, + -4529, -3697, -3010, -2485, -2070, -1727, -1428, 0 + }, + .b = { + 4096, 3603, 3178, 2811, 2497, 2226, 1990, 1783, + 1603, 1446, 1307, 1185, 1077, 981, 895, 819 + }, + .c = { + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, +}; + +/* settings for Bayer Noise Reduction */ +const struct ipu3_uapi_bnr_static_config ipu3_css_bnr_defaults = { + { 16, 16, 16, 16 }, /* wb_gains */ + { 16, 16, 16, 16 }, /* wb_gains_thr */ + { 0, X, 8, 6, X, 14 }, /* thr_coeffs */ + { 0, 0, 0, 0 }, /* thr_ctrl_shd */ + { -128, X, -128, X }, /* opt_center */ + { /* lut */ + { 17, 23, 28, 32, 36, 39, 42, 45, + 48, 51, 53, 55, 58, 60, 62, 64, + 66, 68, 70, 72, 73, 75, 77, 78, + 80, 82, 83, 85, 86, 88, 89, 90 } + }, + { 4, X, 1, 8, X, 8, X, 8, X }, /* bp_ctrl */ + { 8, 4, 4, X, 8, X, 1, 1, 1, 1 }, /* dn_detect_ctrl */ +}; + +const struct ipu3_uapi_dm_config ipu3_css_dm_defaults = { + 1, 1, 1, X, X, 8, X, 7, X, 8, X, 8, X, 4, X +}; + +const struct ipu3_uapi_ccm_mat_config ipu3_css_ccm_defaults = { + 9775, -2671, 1087, 0, + -1071, 8303, 815, 0, + -23, -7887, 16103, 0 +}; + +/* settings for Gamma correction */ +const struct ipu3_uapi_gamma_corr_lut ipu3_css_gamma_lut = { { + 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287, + 303, 319, 335, 351, 367, 383, 399, 415, 431, 447, 463, 479, 495, 511, + 527, 543, 559, 575, 591, 607, 623, 639, 655, 671, 687, 703, 719, 735, + 751, 767, 783, 799, 815, 831, 847, 863, 879, 895, 911, 927, 943, 959, + 975, 991, 1007, 1023, 1039, 1055, 1071, 1087, 1103, 1119, 1135, 1151, + 1167, 1183, 1199, 1215, 1231, 1247, 1263, 1279, 1295, 1311, 1327, 1343, + 1359, 1375, 1391, 1407, 1423, 1439, 1455, 1471, 1487, 1503, 1519, 1535, + 1551, 1567, 1583, 1599, 1615, 1631, 1647, 1663, 1679, 1695, 1711, 1727, + 1743, 1759, 1775, 1791, 1807, 1823, 1839, 1855, 1871, 1887, 1903, 1919, + 1935, 1951, 1967, 1983, 1999, 2015, 2031, 2047, 2063, 2079, 2095, 2111, + 2143, 2175, 2207, 2239, 2271, 2303, 2335, 2367, 2399, 2431, 2463, 2495, + 2527, 2559, 2591, 2623, 2655, 2687, 2719, 2751, 2783, 2815, 2847, 2879, + 2911, 2943, 2975, 3007, 3039, 3071, 3103, 3135, 3167, 3199, 3231, 3263, + 3295, 3327, 3359, 3391, 3423, 3455, 3487, 3519, 3551, 3583, 3615, 3647, + 3679, 3711, 3743, 3775, 3807, 3839, 3871, 3903, 3935, 3967, 3999, 4031, + 4063, 4095, 4127, 4159, 4223, 4287, 4351, 4415, 4479, 4543, 4607, 4671, + 4735, 4799, 4863, 4927, 4991, 5055, 5119, 5183, 5247, 5311, 5375, 5439, + 5503, 5567, 5631, 5695, 5759, 5823, 5887, 5951, 6015, 6079, 6143, 6207, + 6271, 6335, 6399, 6463, 6527, 6591, 6655, 6719, 6783, 6847, 6911, 6975, + 7039, 7103, 7167, 7231, 7295, 7359, 7423, 7487, 7551, 7615, 7679, 7743, + 7807, 7871, 7935, 7999, 8063, 8127, 8191 +} }; + +const struct ipu3_uapi_csc_mat_config ipu3_css_csc_defaults = { + 4898, 9617, 1867, 0, + -2410, -4732, 7143, 0, + 10076, -8437, -1638, 0 +}; + +const struct ipu3_uapi_cds_params ipu3_css_cds_defaults = { + 1, 3, 3, 1, + 1, 3, 3, 1, + 4, X, /* ds_nf */ + 1, /* csc_en */ + 0, X /* uv_bin_output */ +}; + +const struct ipu3_uapi_shd_config_static ipu3_css_shd_defaults = { + .grid = { + .width = 73, + .height = 55, + .block_width_log2 = 7, + .block_height_log2 = 7, + .x_start = 0, + .y_start = 0, + }, + .general = { + .shd_enable = 1, + .gain_factor = 0, + }, + .black_level = { + .bl_r = 0, + .bl_gr = 0 | (0 << IPU3_UAPI_SHD_BLGR_NF_SHIFT), + .bl_gb = 0, + .bl_b = 0, + }, +}; + +const struct ipu3_uapi_yuvp1_iefd_config ipu3_css_iefd_defaults = { + .units = { + .cu_1 = { 0, 150, 7, 0 }, + .cu_ed = { 7, 110, 244, X, 307, 409, 511, X, + 184, 255, 255, X, 0, 0, X, + 7, 81, 255, X, 255, 255, X }, + .cu_3 = { 148, 251, 10, 0 }, + .cu_5 = { 25, 70, 501, X, 32, X }, + .cu_6 = { 32, 63, 183, X, 397, + 33, 0, X, 0, + 0, 64, X, 64, X }, + .cu_7 = { 200, 303, + 10, 0 }, + .cu_unsharp = { 10, 64, 110, X, 511, + 66, 12, X, 0, + 0, 56, X, 64, X }, + .cu_radial = { 6, 203, 255, 255, 255, 255, X, + 84, 444, 397, 288, 300, X, + 4, 69, 207, X, 369, 448, X }, + .cu_vssnlm = { 61, 100, 25, 0} + }, + .config = { 45, X, 0, X, 16, X, 45, X }, + .control = { 1, 1, 1, 1, 1, X }, + .sharp = { { 50, X, 511, X, 50, X, 50, X }, + { 64, X, 0, X, 0, X}, + { 56, X, 56, X } }, + .unsharp = { { 36, 17, 8, X }, + { 13, 7, 3, X } }, + .rad = { { -2104, X, -1559, X }, + { 4426816, X }, + { 2430481, X }, + { 6, X, 79, X }, + { 64, 0, 0, X }, + { 1, X, 2, X, 0, X, 0, X }, + { 40, X, 62, X } }, + .vsslnm = { { 16, 32, 64, X }, + { 1, X, 2, X, 8, X } }, +}; + +const struct ipu3_uapi_yuvp1_yds_config ipu3_css_yds_defaults = { + 0, 1, 1, 0, 0, 1, 1, 0, 2, X, 0, X +}; + +const struct ipu3_uapi_yuvp1_chnr_config ipu3_css_chnr_defaults = { + .coring = { 0, X, 0, X }, + .sense_gain = { 6, 6, 6, X, 4, 4, 4, X }, + .iir_fir = { 8, X, 12, X, 0, 256 - 127, X }, +}; + +const struct ipu3_uapi_yuvp1_y_ee_nr_config ipu3_css_y_ee_nr_defaults = { + .lpf = { 4, X, 8, X, 16, X, 0 }, + .sense = { 8191, X, 0, X, 8191, X, 0, X }, + .gain = { 8, X, 0, X, 8, X, 0, X }, + .clip = { 8, X, 0, X, 8, X, 0, X }, + .frng = { 2, X, 200, X, 2, X, 1, 1, X }, + .diag = { 1, X, 4, 1, 1, 4, X }, + .fc_coring = { 0, X, 0, X, 0, X, 0, X } +}; + +const struct ipu3_uapi_yuvp2_tcc_gain_pcwl_lut_static_config + ipu3_css_tcc_gain_pcwl_lut = { { + 1024, 1032, 1040, 1048, 1057, 1065, 1073, 1081, 1089, 1097, 1105, 1113, + 1122, 1130, 1138, 1146, 1154, 1162, 1170, 1178, 1187, 1195, 1203, 1211, + 1219, 1227, 1235, 1243, 1252, 1260, 1268, 1276, 1284, 1292, 1300, 1308, + 1317, 1325, 1333, 1341, 1349, 1357, 1365, 1373, 1382, 1390, 1398, 1406, + 1414, 1422, 1430, 1438, 1447, 1455, 1463, 1471, 1479, 1487, 1495, 1503, + 1512, 1520, 1528, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, + 1536, 1536, 1528, 1520, 1512, 1503, 1495, 1487, 1479, 1471, 1463, 1455, + 1447, 1438, 1430, 1422, 1414, 1406, 1398, 1390, 1382, 1373, 1365, 1357, + 1349, 1341, 1333, 1325, 1317, 1308, 1300, 1292, 1284, 1276, 1268, 1260, + 1252, 1243, 1235, 1227, 1219, 1211, 1203, 1195, 1187, 1178, 1170, 1162, + 1154, 1146, 1138, 1130, 1122, 1113, 1105, 1097, 1089, 1081, 1073, 1065, + 1057, 1048, 1040, 1032, 1024 +} }; + +const struct ipu3_uapi_yuvp2_tcc_r_sqr_lut_static_config + ipu3_css_tcc_r_sqr_lut = { { + 32, 44, 64, 92, 128, 180, 256, 364, 512, 628, 724, 808, 888, + 956, 1024, 1088, 1144, 1200, 1256, 1304, 1356, 1404, 1448 +} }; + +const struct imgu_abi_anr_config ipu3_css_anr_defaults = { + .transform = { + .adaptive_treshhold_en = 1, + .alpha = { { 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 = { { 24, 24, 24, 24}, + { 21, 20, 20, 21}, + { 25, 25, 25, 25} }, + .color = { { { 166, 173, 149, 166, 161, 146, 145, 173, + 145, 150, 141, 149, 145, 141, 142 }, + { 166, 173, 149, 165, 161, 145, 145, 173, + 145, 150, 141, 149, 145, 141, 142 }, + { 166, 174, 149, 166, 162, 146, 146, 173, + 145, 150, 141, 149, 145, 141, 142 }, + { 166, 173, 149, 165, 161, 145, 145, 173, + 146, 150, 141, 149, 145, 141, 142 } }, + { { 141, 131, 140, 141, 144, 143, 144, 131, + 143, 137, 140, 140, 144, 140, 141 }, + { 141, 131, 140, 141, 143, 143, 144, 131, + 143, 137, 140, 140, 144, 140, 141 }, + { 141, 131, 141, 141, 144, 144, 144, 131, + 143, 137, 140, 140, 144, 140, 141 }, + { 140, 131, 140, 141, 143, 143, 144, 131, + 143, 137, 140, 140, 144, 140, 141 } }, + { { 184, 173, 188, 184, 182, 182, 181, 173, + 182, 179, 182, 188, 181, 182, 180 }, + { 184, 173, 188, 184, 183, 182, 181, 173, + 182, 178, 182, 188, 181, 182, 180 }, + { 184, 173, 188, 184, 182, 182, 181, 173, + 182, 178, 182, 188, 181, 182, 181 }, + { 184, 172, 188, 184, 182, 182, 181, 173, + 182, 178, 182, 188, 182, 182, 180 } } }, + .sqrt_lut = { 724, 768, 810, 849, 887, 923, 958, 991, 1024, + 1056, 1086, 1116, 1145, 1173, 1201, 1228, 1254, + 1280, 1305, 1330, 1355, 1379, 1402, 1425, 1448 }, + .xreset = -1632, + .yreset = -1224, + .x_sqr_reset = 2663424, + .r_normfactor = 14, + .y_sqr_reset = 1498176, + .gain_scale = 115 + }, + .stitch = { + .anr_stitch_en = 1, + .pyramid = { { 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 } + } + } +}; + +/* frame settings for Auto White Balance */ +const struct ipu3_uapi_awb_fr_config_s ipu3_css_awb_fr_defaults = { + .grid_cfg = { + .width = 16, + .height = 16, + .block_width_log2 = 3, + .block_height_log2 = 3, + .x_start = 10, + .y_start = 2 | IPU3_UAPI_GRID_Y_START_EN, + }, + .bayer_coeff = { 0, 0, 0, 0, 0, 128 }, + .bayer_sign = 0, + .bayer_nf = 7 +}; + +/* settings for Auto Exposure */ +const struct ipu3_uapi_ae_grid_config ipu3_css_ae_grid_defaults = { + .width = 16, + .height = 16, + .block_width_log2 = 3, + .block_height_log2 = 3, + .ae_en = 1, + .x_start = 0, + .y_start = 0, +}; + +/* settings for Auto Exposure color correction matrix */ +const struct ipu3_uapi_ae_ccm ipu3_css_ae_ccm_defaults = { + 256, 256, 256, 256, /* gain_gr/r/b/gb */ + .mat = { 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, 128, 0, 0, 0, 0, 128 }, +}; + +/* settings for Auto Focus */ +const struct ipu3_uapi_af_config_s ipu3_css_af_defaults = { + .filter_config = { + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 128 }, 0, + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 128 }, 0, + .y_calc = { 8, 8, 8, 8 }, + .nf = { X, 7, X, 7 }, + }, + .grid_cfg = { + .width = 16, + .height = 16, + .block_width_log2 = 3, + .block_height_log2 = 3, + .x_start = 10, + .y_start = 2 | IPU3_UAPI_GRID_Y_START_EN, + }, +}; + +/* settings for Auto White Balance */ +const struct ipu3_uapi_awb_config_s ipu3_css_awb_defaults = { + 8191, 8191, 8191, 8191 | /* rgbs_thr_gr/r/gb/b */ + IPU3_UAPI_AWB_RGBS_THR_B_EN | IPU3_UAPI_AWB_RGBS_THR_B_INCL_SAT, + .grid = { + .width = 16, + .height = 16, + .block_width_log2 = 3, + .block_height_log2 = 3, + .x_start = 0, + .y_start = 0, + }, +}; diff --git a/drivers/staging/media/ipu3/ipu3-tables.h b/drivers/staging/media/ipu3/ipu3-tables.h new file mode 100644 index 000000000000..6563782cbd22 --- /dev/null +++ b/drivers/staging/media/ipu3/ipu3-tables.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2018 Intel Corporation */ + +#ifndef __IPU3_TABLES_H +#define __IPU3_TABLES_H + +#include "ipu3-abi.h" + +#define IMGU_BDS_GRANULARITY 32 /* Downscaling granularity */ +#define IMGU_BDS_MIN_SF_INV IMGU_BDS_GRANULARITY +#define IMGU_BDS_CONFIG_LEN 97 + +#define IMGU_SCALER_DOWNSCALE_4TAPS_LEN 128 +#define IMGU_SCALER_DOWNSCALE_2TAPS_LEN 64 +#define IMGU_SCALER_FP ((u32)1 << 31) /* 1.0 in fixed point */ + +#define IMGU_XNR3_VMEM_LUT_LEN 16 + +#define IMGU_GDC_LUT_UNIT 4 +#define IMGU_GDC_LUT_LEN 256 + +struct ipu3_css_bds_config { + struct imgu_abi_bds_phase_arr hor_phase_arr; + struct imgu_abi_bds_phase_arr ver_phase_arr; + struct imgu_abi_bds_ptrn_arr ptrn_arr; + u16 sample_patrn_length; + u8 hor_ds_en; + u8 ver_ds_en; +}; + +struct ipu3_css_xnr3_vmem_defaults { + s16 x[IMGU_XNR3_VMEM_LUT_LEN]; + s16 a[IMGU_XNR3_VMEM_LUT_LEN]; + s16 b[IMGU_XNR3_VMEM_LUT_LEN]; + s16 c[IMGU_XNR3_VMEM_LUT_LEN]; +}; + +extern const struct ipu3_css_bds_config + ipu3_css_bds_configs[IMGU_BDS_CONFIG_LEN]; +extern const s32 ipu3_css_downscale_4taps[IMGU_SCALER_DOWNSCALE_4TAPS_LEN]; +extern const s32 ipu3_css_downscale_2taps[IMGU_SCALER_DOWNSCALE_2TAPS_LEN]; +extern const s16 ipu3_css_gdc_lut[IMGU_GDC_LUT_UNIT][IMGU_GDC_LUT_LEN]; +extern const struct ipu3_css_xnr3_vmem_defaults ipu3_css_xnr3_vmem_defaults; +extern const struct ipu3_uapi_bnr_static_config ipu3_css_bnr_defaults; +extern const struct ipu3_uapi_dm_config ipu3_css_dm_defaults; +extern const struct ipu3_uapi_ccm_mat_config ipu3_css_ccm_defaults; +extern const struct ipu3_uapi_gamma_corr_lut ipu3_css_gamma_lut; +extern const struct ipu3_uapi_csc_mat_config ipu3_css_csc_defaults; +extern const struct ipu3_uapi_cds_params ipu3_css_cds_defaults; +extern const struct ipu3_uapi_shd_config_static ipu3_css_shd_defaults; +extern const struct ipu3_uapi_yuvp1_iefd_config ipu3_css_iefd_defaults; +extern const struct ipu3_uapi_yuvp1_yds_config ipu3_css_yds_defaults; +extern const struct ipu3_uapi_yuvp1_chnr_config ipu3_css_chnr_defaults; +extern const struct ipu3_uapi_yuvp1_y_ee_nr_config ipu3_css_y_ee_nr_defaults; +extern const struct ipu3_uapi_yuvp2_tcc_gain_pcwl_lut_static_config + ipu3_css_tcc_gain_pcwl_lut; +extern const struct ipu3_uapi_yuvp2_tcc_r_sqr_lut_static_config + ipu3_css_tcc_r_sqr_lut; +extern const struct imgu_abi_anr_config ipu3_css_anr_defaults; +extern const struct ipu3_uapi_awb_fr_config_s ipu3_css_awb_fr_defaults; +extern const struct ipu3_uapi_ae_grid_config ipu3_css_ae_grid_defaults; +extern const struct ipu3_uapi_ae_ccm ipu3_css_ae_ccm_defaults; +extern const struct ipu3_uapi_af_config_s ipu3_css_af_defaults; +extern const struct ipu3_uapi_awb_config_s ipu3_css_awb_defaults; + +#endif diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c new file mode 100644 index 000000000000..c7936032beb9 --- /dev/null +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -0,0 +1,1419 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Intel Corporation + +#include <linux/module.h> +#include <linux/pm_runtime.h> + +#include <media/v4l2-event.h> +#include <media/v4l2-ioctl.h> + +#include "ipu3.h" +#include "ipu3-dmamap.h" + +/******************** v4l2_subdev_ops ********************/ + +static int ipu3_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct imgu_v4l2_subdev *imgu_sd = container_of(sd, + struct imgu_v4l2_subdev, + subdev); + struct imgu_device *imgu = v4l2_get_subdevdata(sd); + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[imgu_sd->pipe]; + struct v4l2_rect try_crop = { + .top = 0, + .left = 0, + }; + unsigned int i; + + try_crop.width = + imgu_pipe->nodes[IMGU_NODE_IN].vdev_fmt.fmt.pix_mp.width; + try_crop.height = + imgu_pipe->nodes[IMGU_NODE_IN].vdev_fmt.fmt.pix_mp.height; + + /* Initialize try_fmt */ + for (i = 0; i < IMGU_NODE_NUM; i++) { + struct v4l2_mbus_framefmt *try_fmt = + v4l2_subdev_get_try_format(sd, fh->pad, i); + + try_fmt->width = try_crop.width; + try_fmt->height = try_crop.height; + try_fmt->code = imgu_pipe->nodes[i].pad_fmt.code; + try_fmt->field = V4L2_FIELD_NONE; + } + + *v4l2_subdev_get_try_crop(sd, fh->pad, IMGU_NODE_IN) = try_crop; + *v4l2_subdev_get_try_compose(sd, fh->pad, IMGU_NODE_IN) = try_crop; + + return 0; +} + +static int ipu3_subdev_s_stream(struct v4l2_subdev *sd, int enable) +{ + int i; + unsigned int node; + int r = 0; + struct imgu_device *imgu = v4l2_get_subdevdata(sd); + struct imgu_v4l2_subdev *imgu_sd = container_of(sd, + struct imgu_v4l2_subdev, + subdev); + unsigned int pipe = imgu_sd->pipe; + struct device *dev = &imgu->pci_dev->dev; + struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL }; + struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL }; + struct ipu3_css_pipe *css_pipe = &imgu->css.pipes[pipe]; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + dev_dbg(dev, "%s %d for pipe %d", __func__, enable, pipe); + /* grab ctrl after streamon and return after off */ + v4l2_ctrl_grab(imgu_sd->ctrl, enable); + + if (!enable) { + imgu_sd->active = false; + return 0; + } + + for (i = 0; i < IMGU_NODE_NUM; i++) + imgu_pipe->queue_enabled[i] = imgu_pipe->nodes[i].enabled; + + /* This is handled specially */ + imgu_pipe->queue_enabled[IPU3_CSS_QUEUE_PARAMS] = false; + + /* Initialize CSS formats */ + for (i = 0; i < IPU3_CSS_QUEUES; i++) { + node = imgu_map_node(imgu, i); + /* No need to reconfig meta nodes */ + if (node == IMGU_NODE_STAT_3A || node == IMGU_NODE_PARAMS) + continue; + fmts[i] = imgu_pipe->queue_enabled[node] ? + &imgu_pipe->nodes[node].vdev_fmt.fmt.pix_mp : NULL; + } + + /* Enable VF output only when VF queue requested by user */ + css_pipe->vf_output_en = false; + if (imgu_pipe->nodes[IMGU_NODE_VF].enabled) + css_pipe->vf_output_en = true; + + if (atomic_read(&imgu_sd->running_mode) == IPU3_RUNNING_MODE_VIDEO) + css_pipe->pipe_id = IPU3_CSS_PIPE_ID_VIDEO; + else + css_pipe->pipe_id = IPU3_CSS_PIPE_ID_CAPTURE; + + dev_dbg(dev, "IPU3 pipe %d pipe_id %d", pipe, css_pipe->pipe_id); + + rects[IPU3_CSS_RECT_EFFECTIVE] = &imgu_sd->rect.eff; + rects[IPU3_CSS_RECT_BDS] = &imgu_sd->rect.bds; + rects[IPU3_CSS_RECT_GDC] = &imgu_sd->rect.gdc; + + r = ipu3_css_fmt_set(&imgu->css, fmts, rects, pipe); + if (r) { + dev_err(dev, "failed to set initial formats pipe %d with (%d)", + pipe, r); + return r; + } + + imgu_sd->active = true; + + return 0; +} + +static int ipu3_subdev_get_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct imgu_device *imgu = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *mf; + struct imgu_media_pipe *imgu_pipe; + u32 pad = fmt->pad; + struct imgu_v4l2_subdev *imgu_sd = container_of(sd, + struct imgu_v4l2_subdev, + subdev); + unsigned int pipe = imgu_sd->pipe; + + imgu_pipe = &imgu->imgu_pipe[pipe]; + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + fmt->format = imgu_pipe->nodes[pad].pad_fmt; + } else { + mf = v4l2_subdev_get_try_format(sd, cfg, pad); + fmt->format = *mf; + } + + return 0; +} + +static int ipu3_subdev_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct imgu_media_pipe *imgu_pipe; + struct imgu_device *imgu = v4l2_get_subdevdata(sd); + struct imgu_v4l2_subdev *imgu_sd = container_of(sd, + struct imgu_v4l2_subdev, + subdev); + + struct v4l2_mbus_framefmt *mf; + u32 pad = fmt->pad; + unsigned int pipe = imgu_sd->pipe; + + dev_dbg(&imgu->pci_dev->dev, "set subdev %d pad %d fmt to [%dx%d]", + pipe, pad, fmt->format.width, fmt->format.height); + + imgu_pipe = &imgu->imgu_pipe[pipe]; + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + mf = v4l2_subdev_get_try_format(sd, cfg, pad); + else + mf = &imgu_pipe->nodes[pad].pad_fmt; + + fmt->format.code = mf->code; + /* Clamp the w and h based on the hardware capabilities */ + if (imgu_sd->subdev_pads[pad].flags & MEDIA_PAD_FL_SOURCE) { + fmt->format.width = clamp(fmt->format.width, + IPU3_OUTPUT_MIN_WIDTH, + IPU3_OUTPUT_MAX_WIDTH); + fmt->format.height = clamp(fmt->format.height, + IPU3_OUTPUT_MIN_HEIGHT, + IPU3_OUTPUT_MAX_HEIGHT); + } else { + fmt->format.width = clamp(fmt->format.width, + IPU3_INPUT_MIN_WIDTH, + IPU3_INPUT_MAX_WIDTH); + fmt->format.height = clamp(fmt->format.height, + IPU3_INPUT_MIN_HEIGHT, + IPU3_INPUT_MAX_HEIGHT); + } + + *mf = fmt->format; + + return 0; +} + +static int ipu3_subdev_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct v4l2_rect *try_sel, *r; + struct imgu_v4l2_subdev *imgu_sd = container_of(sd, + struct imgu_v4l2_subdev, + subdev); + + if (sel->pad != IMGU_NODE_IN) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + r = &imgu_sd->rect.eff; + break; + case V4L2_SEL_TGT_COMPOSE: + try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad); + r = &imgu_sd->rect.bds; + break; + default: + return -EINVAL; + } + + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) + sel->r = *try_sel; + else + sel->r = *r; + + return 0; +} + +static int ipu3_subdev_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) +{ + struct imgu_device *imgu = v4l2_get_subdevdata(sd); + struct imgu_v4l2_subdev *imgu_sd = container_of(sd, + struct imgu_v4l2_subdev, + subdev); + struct v4l2_rect *rect, *try_sel; + + dev_dbg(&imgu->pci_dev->dev, + "set subdev %d sel which %d target 0x%4x rect [%dx%d]", + imgu_sd->pipe, sel->which, sel->target, + sel->r.width, sel->r.height); + + if (sel->pad != IMGU_NODE_IN) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad); + rect = &imgu_sd->rect.eff; + break; + case V4L2_SEL_TGT_COMPOSE: + try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad); + rect = &imgu_sd->rect.bds; + break; + default: + return -EINVAL; + } + + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) + *try_sel = sel->r; + else + *rect = sel->r; + + return 0; +} + +/******************** media_entity_operations ********************/ + +static int ipu3_link_setup(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags) +{ + struct imgu_media_pipe *imgu_pipe; + struct v4l2_subdev *sd = container_of(entity, struct v4l2_subdev, + entity); + struct imgu_device *imgu = v4l2_get_subdevdata(sd); + struct imgu_v4l2_subdev *imgu_sd = container_of(sd, + struct imgu_v4l2_subdev, + subdev); + unsigned int pipe = imgu_sd->pipe; + u32 pad = local->index; + + WARN_ON(pad >= IMGU_NODE_NUM); + + dev_dbg(&imgu->pci_dev->dev, "pipe %d pad %d is %s", pipe, pad, + flags & MEDIA_LNK_FL_ENABLED ? "enabled" : "disabled"); + + imgu_pipe = &imgu->imgu_pipe[pipe]; + imgu_pipe->nodes[pad].enabled = flags & MEDIA_LNK_FL_ENABLED; + + /* enable input node to enable the pipe */ + if (pad != IMGU_NODE_IN) + return 0; + + if (flags & MEDIA_LNK_FL_ENABLED) + __set_bit(pipe, imgu->css.enabled_pipes); + else + __clear_bit(pipe, imgu->css.enabled_pipes); + + dev_dbg(&imgu->pci_dev->dev, "pipe %d is %s", pipe, + flags & MEDIA_LNK_FL_ENABLED ? "enabled" : "disabled"); + + return 0; +} + +/******************** vb2_ops ********************/ + +static int ipu3_vb2_buf_init(struct vb2_buffer *vb) +{ + struct sg_table *sg = vb2_dma_sg_plane_desc(vb, 0); + struct imgu_device *imgu = vb2_get_drv_priv(vb->vb2_queue); + struct imgu_buffer *buf = container_of(vb, + struct imgu_buffer, vid_buf.vbb.vb2_buf); + struct imgu_video_device *node = + container_of(vb->vb2_queue, struct imgu_video_device, vbq); + unsigned int queue = imgu_node_to_queue(node->id); + + if (queue == IPU3_CSS_QUEUE_PARAMS) + return 0; + + return ipu3_dmamap_map_sg(imgu, sg->sgl, sg->nents, &buf->map); +} + +/* Called when each buffer is freed */ +static void ipu3_vb2_buf_cleanup(struct vb2_buffer *vb) +{ + struct imgu_device *imgu = vb2_get_drv_priv(vb->vb2_queue); + struct imgu_buffer *buf = container_of(vb, + struct imgu_buffer, vid_buf.vbb.vb2_buf); + struct imgu_video_device *node = + container_of(vb->vb2_queue, struct imgu_video_device, vbq); + unsigned int queue = imgu_node_to_queue(node->id); + + if (queue == IPU3_CSS_QUEUE_PARAMS) + return; + + ipu3_dmamap_unmap(imgu, &buf->map); +} + +/* Transfer buffer ownership to me */ +static void ipu3_vb2_buf_queue(struct vb2_buffer *vb) +{ + struct imgu_device *imgu = vb2_get_drv_priv(vb->vb2_queue); + struct imgu_video_device *node = + container_of(vb->vb2_queue, struct imgu_video_device, vbq); + unsigned int queue = imgu_node_to_queue(node->id); + unsigned long need_bytes; + unsigned int pipe = node->pipe; + + if (vb->vb2_queue->type == V4L2_BUF_TYPE_META_CAPTURE || + vb->vb2_queue->type == V4L2_BUF_TYPE_META_OUTPUT) + need_bytes = node->vdev_fmt.fmt.meta.buffersize; + else + need_bytes = node->vdev_fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + + if (queue == IPU3_CSS_QUEUE_PARAMS) { + unsigned long payload = vb2_get_plane_payload(vb, 0); + struct vb2_v4l2_buffer *buf = + container_of(vb, struct vb2_v4l2_buffer, vb2_buf); + int r = -EINVAL; + + if (payload == 0) { + payload = need_bytes; + vb2_set_plane_payload(vb, 0, payload); + } + if (payload >= need_bytes) + r = ipu3_css_set_parameters(&imgu->css, pipe, + vb2_plane_vaddr(vb, 0)); + buf->flags = V4L2_BUF_FLAG_DONE; + vb2_buffer_done(vb, r == 0 ? VB2_BUF_STATE_DONE + : VB2_BUF_STATE_ERROR); + + } else { + struct imgu_buffer *buf = container_of(vb, struct imgu_buffer, + vid_buf.vbb.vb2_buf); + + mutex_lock(&imgu->lock); + ipu3_css_buf_init(&buf->css_buf, queue, buf->map.daddr); + list_add_tail(&buf->vid_buf.list, + &node->buffers); + mutex_unlock(&imgu->lock); + + vb2_set_plane_payload(&buf->vid_buf.vbb.vb2_buf, 0, need_bytes); + + if (imgu->streaming) + imgu_queue_buffers(imgu, false, pipe); + } + + dev_dbg(&imgu->pci_dev->dev, "%s for pipe %d node %d", __func__, + node->pipe, node->id); + +} + +static int ipu3_vb2_queue_setup(struct vb2_queue *vq, + unsigned int *num_buffers, + unsigned int *num_planes, + unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct imgu_device *imgu = vb2_get_drv_priv(vq); + struct imgu_video_device *node = + container_of(vq, struct imgu_video_device, vbq); + const struct v4l2_format *fmt = &node->vdev_fmt; + unsigned int size; + + *num_buffers = clamp_val(*num_buffers, 1, VB2_MAX_FRAME); + alloc_devs[0] = &imgu->pci_dev->dev; + + if (vq->type == V4L2_BUF_TYPE_META_CAPTURE || + vq->type == V4L2_BUF_TYPE_META_OUTPUT) + size = fmt->fmt.meta.buffersize; + else + size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage; + + if (*num_planes) { + if (sizes[0] < size) + return -EINVAL; + size = sizes[0]; + } + + *num_planes = 1; + sizes[0] = size; + + /* Initialize buffer queue */ + INIT_LIST_HEAD(&node->buffers); + + return 0; +} + +/* Check if all enabled video nodes are streaming, exception ignored */ +static bool ipu3_all_nodes_streaming(struct imgu_device *imgu, + struct imgu_video_device *except) +{ + unsigned int i, pipe, p; + struct imgu_video_device *node; + struct device *dev = &imgu->pci_dev->dev; + + pipe = except->pipe; + if (!test_bit(pipe, imgu->css.enabled_pipes)) { + dev_warn(&imgu->pci_dev->dev, + "pipe %d link is not ready yet", pipe); + return false; + } + + for_each_set_bit(p, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) { + for (i = 0; i < IMGU_NODE_NUM; i++) { + node = &imgu->imgu_pipe[p].nodes[i]; + dev_dbg(dev, "%s pipe %u queue %u name %s enabled = %u", + __func__, p, i, node->name, node->enabled); + if (node == except) + continue; + if (node->enabled && !vb2_start_streaming_called(&node->vbq)) + return false; + } + } + + return true; +} + +static void ipu3_return_all_buffers(struct imgu_device *imgu, + struct imgu_video_device *node, + enum vb2_buffer_state state) +{ + struct ipu3_vb2_buffer *b, *b0; + + /* Return all buffers */ + mutex_lock(&imgu->lock); + list_for_each_entry_safe(b, b0, &node->buffers, list) { + list_del(&b->list); + vb2_buffer_done(&b->vbb.vb2_buf, state); + } + mutex_unlock(&imgu->lock); +} + +static int ipu3_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct imgu_media_pipe *imgu_pipe; + struct imgu_device *imgu = vb2_get_drv_priv(vq); + struct device *dev = &imgu->pci_dev->dev; + struct imgu_video_device *node = + container_of(vq, struct imgu_video_device, vbq); + int r; + unsigned int pipe; + + dev_dbg(dev, "%s node name %s pipe %d id %u", __func__, + node->name, node->pipe, node->id); + + if (imgu->streaming) { + r = -EBUSY; + goto fail_return_bufs; + } + + if (!node->enabled) { + dev_err(dev, "IMGU node is not enabled"); + r = -EINVAL; + goto fail_return_bufs; + } + + pipe = node->pipe; + imgu_pipe = &imgu->imgu_pipe[pipe]; + r = media_pipeline_start(&node->vdev.entity, &imgu_pipe->pipeline); + if (r < 0) + goto fail_return_bufs; + + + if (!ipu3_all_nodes_streaming(imgu, node)) + return 0; + + for_each_set_bit(pipe, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) { + r = v4l2_subdev_call(&imgu->imgu_pipe[pipe].imgu_sd.subdev, + video, s_stream, 1); + if (r < 0) + goto fail_stop_pipeline; + } + + /* Start streaming of the whole pipeline now */ + dev_dbg(dev, "IMGU streaming is ready to start"); + r = imgu_s_stream(imgu, true); + if (!r) + imgu->streaming = true; + + return 0; + +fail_stop_pipeline: + media_pipeline_stop(&node->vdev.entity); +fail_return_bufs: + ipu3_return_all_buffers(imgu, node, VB2_BUF_STATE_QUEUED); + + return r; +} + +static void ipu3_vb2_stop_streaming(struct vb2_queue *vq) +{ + struct imgu_media_pipe *imgu_pipe; + struct imgu_device *imgu = vb2_get_drv_priv(vq); + struct device *dev = &imgu->pci_dev->dev; + struct imgu_video_device *node = + container_of(vq, struct imgu_video_device, vbq); + int r; + unsigned int pipe; + + WARN_ON(!node->enabled); + + pipe = node->pipe; + dev_dbg(dev, "Try to stream off node [%d][%d]", pipe, node->id); + imgu_pipe = &imgu->imgu_pipe[pipe]; + r = v4l2_subdev_call(&imgu_pipe->imgu_sd.subdev, video, s_stream, 0); + if (r) + dev_err(&imgu->pci_dev->dev, + "failed to stop subdev streaming\n"); + + /* Was this the first node with streaming disabled? */ + if (imgu->streaming && ipu3_all_nodes_streaming(imgu, node)) { + /* Yes, really stop streaming now */ + dev_dbg(dev, "IMGU streaming is ready to stop"); + r = imgu_s_stream(imgu, false); + if (!r) + imgu->streaming = false; + } + + ipu3_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR); + media_pipeline_stop(&node->vdev.entity); +} + +/******************** v4l2_ioctl_ops ********************/ + +#define VID_CAPTURE 0 +#define VID_OUTPUT 1 +#define DEF_VID_CAPTURE 0 +#define DEF_VID_OUTPUT 1 + +struct ipu3_fmt { + u32 fourcc; + u16 type; /* VID_CAPTURE or VID_OUTPUT not both */ +}; + +/* format descriptions for capture and preview */ +static const struct ipu3_fmt formats[] = { + { V4L2_PIX_FMT_NV12, VID_CAPTURE }, + { V4L2_PIX_FMT_IPU3_SGRBG10, VID_OUTPUT }, + { V4L2_PIX_FMT_IPU3_SBGGR10, VID_OUTPUT }, + { V4L2_PIX_FMT_IPU3_SGBRG10, VID_OUTPUT }, + { V4L2_PIX_FMT_IPU3_SRGGB10, VID_OUTPUT }, +}; + +/* Find the first matched format, return default if not found */ +static const struct ipu3_fmt *find_format(struct v4l2_format *f, u32 type) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(formats); i++) { + if (formats[i].fourcc == f->fmt.pix_mp.pixelformat && + formats[i].type == type) + return &formats[i]; + } + + return type == VID_CAPTURE ? &formats[DEF_VID_CAPTURE] : + &formats[DEF_VID_OUTPUT]; +} + +static int ipu3_vidioc_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct imgu_video_device *node = file_to_intel_ipu3_node(file); + + strscpy(cap->driver, IMGU_NAME, sizeof(cap->driver)); + strscpy(cap->card, IMGU_NAME, sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", node->name); + + return 0; +} + +static int enum_fmts(struct v4l2_fmtdesc *f, u32 type) +{ + unsigned int i, j; + + for (i = j = 0; i < ARRAY_SIZE(formats); ++i) { + if (formats[i].type == type) { + if (j == f->index) + break; + ++j; + } + } + + if (i < ARRAY_SIZE(formats)) { + f->pixelformat = formats[i].fourcc; + return 0; + } + + return -EINVAL; +} + +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + return -EINVAL; + + return enum_fmts(f, VID_CAPTURE); +} + +static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return -EINVAL; + + return enum_fmts(f, VID_OUTPUT); +} + +/* Propagate forward always the format from the CIO2 subdev */ +static int ipu3_vidioc_g_fmt(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct imgu_video_device *node = file_to_intel_ipu3_node(file); + + f->fmt = node->vdev_fmt.fmt; + + return 0; +} + +/* + * Set input/output format. Unless it is just a try, this also resets + * selections (ie. effective and BDS resolutions) to defaults. + */ +static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, + struct v4l2_format *f, bool try) +{ + struct device *dev = &imgu->pci_dev->dev; + struct v4l2_pix_format_mplane try_fmts[IPU3_CSS_QUEUES]; + struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL }; + struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL }; + struct v4l2_mbus_framefmt pad_fmt; + unsigned int i, css_q; + int r; + struct ipu3_css_pipe *css_pipe = &imgu->css.pipes[pipe]; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; + + dev_dbg(dev, "set fmt node [%u][%u](try = %d)", pipe, node, try); + + for (i = 0; i < IMGU_NODE_NUM; i++) + dev_dbg(dev, "IMGU pipe %d node %d enabled = %d", + pipe, i, imgu_pipe->nodes[i].enabled); + + if (imgu_pipe->nodes[IMGU_NODE_VF].enabled) + css_pipe->vf_output_en = true; + + if (atomic_read(&imgu_sd->running_mode) == IPU3_RUNNING_MODE_VIDEO) + css_pipe->pipe_id = IPU3_CSS_PIPE_ID_VIDEO; + else + css_pipe->pipe_id = IPU3_CSS_PIPE_ID_CAPTURE; + + dev_dbg(dev, "IPU3 pipe %d pipe_id = %d", pipe, css_pipe->pipe_id); + + for (i = 0; i < IPU3_CSS_QUEUES; i++) { + unsigned int inode = imgu_map_node(imgu, i); + + /* Skip the meta node */ + if (inode == IMGU_NODE_STAT_3A || inode == IMGU_NODE_PARAMS) + continue; + + if (try) { + try_fmts[i] = + imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; + fmts[i] = &try_fmts[i]; + } else { + fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; + } + + /* CSS expects some format on OUT queue */ + if (i != IPU3_CSS_QUEUE_OUT && + !imgu_pipe->nodes[inode].enabled) + fmts[i] = NULL; + } + + if (!try) { + /* eff and bds res got by imgu_s_sel */ + struct imgu_v4l2_subdev *imgu_sd = &imgu_pipe->imgu_sd; + + rects[IPU3_CSS_RECT_EFFECTIVE] = &imgu_sd->rect.eff; + rects[IPU3_CSS_RECT_BDS] = &imgu_sd->rect.bds; + rects[IPU3_CSS_RECT_GDC] = &imgu_sd->rect.gdc; + + /* suppose that pad fmt was set by subdev s_fmt before */ + pad_fmt = imgu_pipe->nodes[IMGU_NODE_IN].pad_fmt; + rects[IPU3_CSS_RECT_GDC]->width = pad_fmt.width; + rects[IPU3_CSS_RECT_GDC]->height = pad_fmt.height; + } + + /* + * imgu doesn't set the node to the value given by user + * before we return success from this function, so set it here. + */ + css_q = imgu_node_to_queue(node); + if (fmts[css_q]) + *fmts[css_q] = f->fmt.pix_mp; + else + return -EINVAL; + + if (try) + r = ipu3_css_fmt_try(&imgu->css, fmts, rects, pipe); + else + r = ipu3_css_fmt_set(&imgu->css, fmts, rects, pipe); + + /* r is the binary number in the firmware blob */ + if (r < 0) + return r; + + if (try) + f->fmt.pix_mp = *fmts[css_q]; + else + f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; + + return 0; +} + +static int ipu3_try_fmt(struct file *file, void *fh, struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; + const struct ipu3_fmt *fmt; + + if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + fmt = find_format(f, VID_CAPTURE); + else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + fmt = find_format(f, VID_OUTPUT); + else + return -EINVAL; + + pixm->pixelformat = fmt->fourcc; + + memset(pixm->plane_fmt[0].reserved, 0, + sizeof(pixm->plane_fmt[0].reserved)); + + return 0; +} + +static int ipu3_vidioc_try_fmt(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct imgu_device *imgu = video_drvdata(file); + struct device *dev = &imgu->pci_dev->dev; + struct imgu_video_device *node = file_to_intel_ipu3_node(file); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + int r; + + dev_dbg(dev, "%s [%ux%u] for node %d\n", __func__, + pix_mp->width, pix_mp->height, node->id); + + r = ipu3_try_fmt(file, fh, f); + if (r) + return r; + + return imgu_fmt(imgu, node->pipe, node->id, f, true); +} + +static int ipu3_vidioc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) +{ + struct imgu_device *imgu = video_drvdata(file); + struct device *dev = &imgu->pci_dev->dev; + struct imgu_video_device *node = file_to_intel_ipu3_node(file); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + int r; + + dev_dbg(dev, "%s [%ux%u] for node %d\n", __func__, + pix_mp->width, pix_mp->height, node->id); + + r = ipu3_try_fmt(file, fh, f); + if (r) + return r; + + return imgu_fmt(imgu, node->pipe, node->id, f, false); +} + +struct ipu3_meta_fmt { + __u32 fourcc; + char *name; +}; + +/* From drivers/media/v4l2-core/v4l2-ioctl.c */ +static const struct ipu3_meta_fmt meta_fmts[] = { + { V4L2_META_FMT_IPU3_PARAMS, "IPU3 processing parameters" }, + { V4L2_META_FMT_IPU3_STAT_3A, "IPU3 3A statistics" }, +}; + +static int ipu3_meta_enum_format(struct file *file, void *fh, + struct v4l2_fmtdesc *fmt) +{ + struct imgu_video_device *node = file_to_intel_ipu3_node(file); + unsigned int i = fmt->type == V4L2_BUF_TYPE_META_OUTPUT ? 0 : 1; + + /* Each node is dedicated to only one meta format */ + if (fmt->index > 0 || fmt->type != node->vbq.type) + return -EINVAL; + + strscpy(fmt->description, meta_fmts[i].name, sizeof(fmt->description)); + fmt->pixelformat = meta_fmts[i].fourcc; + + return 0; +} + +static int ipu3_vidioc_g_meta_fmt(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct imgu_video_device *node = file_to_intel_ipu3_node(file); + + if (f->type != node->vbq.type) + return -EINVAL; + + f->fmt = node->vdev_fmt.fmt; + + return 0; +} + +static int ipu3_vidioc_enum_input(struct file *file, void *fh, + struct v4l2_input *input) +{ + if (input->index > 0) + return -EINVAL; + strscpy(input->name, "camera", sizeof(input->name)); + input->type = V4L2_INPUT_TYPE_CAMERA; + + return 0; +} + +static int ipu3_vidioc_g_input(struct file *file, void *fh, unsigned int *input) +{ + *input = 0; + + return 0; +} + +static int ipu3_vidioc_s_input(struct file *file, void *fh, unsigned int input) +{ + return input == 0 ? 0 : -EINVAL; +} + +static int ipu3_vidioc_enum_output(struct file *file, void *fh, + struct v4l2_output *output) +{ + if (output->index > 0) + return -EINVAL; + strscpy(output->name, "camera", sizeof(output->name)); + output->type = V4L2_INPUT_TYPE_CAMERA; + + return 0; +} + +static int ipu3_vidioc_g_output(struct file *file, void *fh, + unsigned int *output) +{ + *output = 0; + + return 0; +} + +static int ipu3_vidioc_s_output(struct file *file, void *fh, + unsigned int output) +{ + return output == 0 ? 0 : -EINVAL; +} + +/******************** function pointers ********************/ + +static struct v4l2_subdev_internal_ops ipu3_subdev_internal_ops = { + .open = ipu3_subdev_open, +}; + +static const struct v4l2_subdev_core_ops ipu3_subdev_core_ops = { + .subscribe_event = v4l2_ctrl_subdev_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, +}; + +static const struct v4l2_subdev_video_ops ipu3_subdev_video_ops = { + .s_stream = ipu3_subdev_s_stream, +}; + +static const struct v4l2_subdev_pad_ops ipu3_subdev_pad_ops = { + .link_validate = v4l2_subdev_link_validate_default, + .get_fmt = ipu3_subdev_get_fmt, + .set_fmt = ipu3_subdev_set_fmt, + .get_selection = ipu3_subdev_get_selection, + .set_selection = ipu3_subdev_set_selection, +}; + +static const struct v4l2_subdev_ops ipu3_subdev_ops = { + .core = &ipu3_subdev_core_ops, + .video = &ipu3_subdev_video_ops, + .pad = &ipu3_subdev_pad_ops, +}; + +static const struct media_entity_operations ipu3_media_ops = { + .link_setup = ipu3_link_setup, + .link_validate = v4l2_subdev_link_validate, +}; + +/****************** vb2_ops of the Q ********************/ + +static const struct vb2_ops ipu3_vb2_ops = { + .buf_init = ipu3_vb2_buf_init, + .buf_cleanup = ipu3_vb2_buf_cleanup, + .buf_queue = ipu3_vb2_buf_queue, + .queue_setup = ipu3_vb2_queue_setup, + .start_streaming = ipu3_vb2_start_streaming, + .stop_streaming = ipu3_vb2_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; + +/****************** v4l2_file_operations *****************/ + +static const struct v4l2_file_operations ipu3_v4l2_fops = { + .unlocked_ioctl = video_ioctl2, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, +}; + +/******************** v4l2_ioctl_ops ********************/ + +static const struct v4l2_ioctl_ops ipu3_v4l2_ioctl_ops = { + .vidioc_querycap = ipu3_vidioc_querycap, + + .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap_mplane = ipu3_vidioc_g_fmt, + .vidioc_s_fmt_vid_cap_mplane = ipu3_vidioc_s_fmt, + .vidioc_try_fmt_vid_cap_mplane = ipu3_vidioc_try_fmt, + + .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out, + .vidioc_g_fmt_vid_out_mplane = ipu3_vidioc_g_fmt, + .vidioc_s_fmt_vid_out_mplane = ipu3_vidioc_s_fmt, + .vidioc_try_fmt_vid_out_mplane = ipu3_vidioc_try_fmt, + + .vidioc_enum_output = ipu3_vidioc_enum_output, + .vidioc_g_output = ipu3_vidioc_g_output, + .vidioc_s_output = ipu3_vidioc_s_output, + + .vidioc_enum_input = ipu3_vidioc_enum_input, + .vidioc_g_input = ipu3_vidioc_g_input, + .vidioc_s_input = ipu3_vidioc_s_input, + + /* buffer queue management */ + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_expbuf = vb2_ioctl_expbuf, +}; + +static const struct v4l2_ioctl_ops ipu3_v4l2_meta_ioctl_ops = { + .vidioc_querycap = ipu3_vidioc_querycap, + + /* meta capture */ + .vidioc_enum_fmt_meta_cap = ipu3_meta_enum_format, + .vidioc_g_fmt_meta_cap = ipu3_vidioc_g_meta_fmt, + .vidioc_s_fmt_meta_cap = ipu3_vidioc_g_meta_fmt, + .vidioc_try_fmt_meta_cap = ipu3_vidioc_g_meta_fmt, + + /* meta output */ + .vidioc_enum_fmt_meta_out = ipu3_meta_enum_format, + .vidioc_g_fmt_meta_out = ipu3_vidioc_g_meta_fmt, + .vidioc_s_fmt_meta_out = ipu3_vidioc_g_meta_fmt, + .vidioc_try_fmt_meta_out = ipu3_vidioc_g_meta_fmt, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_expbuf = vb2_ioctl_expbuf, +}; + +static int ipu3_sd_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct imgu_v4l2_subdev *imgu_sd = + container_of(ctrl->handler, struct imgu_v4l2_subdev, ctrl_handler); + struct imgu_device *imgu = v4l2_get_subdevdata(&imgu_sd->subdev); + struct device *dev = &imgu->pci_dev->dev; + + dev_dbg(dev, "set val %d to ctrl 0x%8x for subdev %d", + ctrl->val, ctrl->id, imgu_sd->pipe); + + switch (ctrl->id) { + case V4L2_CID_INTEL_IPU3_MODE: + atomic_set(&imgu_sd->running_mode, ctrl->val); + return 0; + default: + return -EINVAL; + } +} + +static const struct v4l2_ctrl_ops ipu3_subdev_ctrl_ops = { + .s_ctrl = ipu3_sd_s_ctrl, +}; + +static const struct v4l2_ctrl_config ipu3_subdev_ctrl_mode = { + .ops = &ipu3_subdev_ctrl_ops, + .id = V4L2_CID_INTEL_IPU3_MODE, + .name = "IPU3 Pipe Mode", + .type = V4L2_CTRL_TYPE_INTEGER, + .min = IPU3_RUNNING_MODE_VIDEO, + .max = IPU3_RUNNING_MODE_STILL, + .step = 1, + .def = IPU3_RUNNING_MODE_VIDEO, +}; + +/******************** Framework registration ********************/ + +/* helper function to config node's video properties */ +static void ipu3_node_to_v4l2(u32 node, struct video_device *vdev, + struct v4l2_format *f) +{ + u32 cap; + + /* Should not happen */ + WARN_ON(node >= IMGU_NODE_NUM); + + switch (node) { + case IMGU_NODE_IN: + cap = V4L2_CAP_VIDEO_OUTPUT_MPLANE; + f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + vdev->ioctl_ops = &ipu3_v4l2_ioctl_ops; + break; + case IMGU_NODE_PARAMS: + cap = V4L2_CAP_META_OUTPUT; + f->type = V4L2_BUF_TYPE_META_OUTPUT; + f->fmt.meta.dataformat = V4L2_META_FMT_IPU3_PARAMS; + vdev->ioctl_ops = &ipu3_v4l2_meta_ioctl_ops; + ipu3_css_meta_fmt_set(&f->fmt.meta); + break; + case IMGU_NODE_STAT_3A: + cap = V4L2_CAP_META_CAPTURE; + f->type = V4L2_BUF_TYPE_META_CAPTURE; + f->fmt.meta.dataformat = V4L2_META_FMT_IPU3_STAT_3A; + vdev->ioctl_ops = &ipu3_v4l2_meta_ioctl_ops; + ipu3_css_meta_fmt_set(&f->fmt.meta); + break; + default: + cap = V4L2_CAP_VIDEO_CAPTURE_MPLANE; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + vdev->ioctl_ops = &ipu3_v4l2_ioctl_ops; + } + + vdev->device_caps = V4L2_CAP_STREAMING | cap; +} + +static int ipu3_v4l2_subdev_register(struct imgu_device *imgu, + struct imgu_v4l2_subdev *imgu_sd, + unsigned int pipe) +{ + int i, r; + struct v4l2_ctrl_handler *hdl = &imgu_sd->ctrl_handler; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + /* Initialize subdev media entity */ + r = media_entity_pads_init(&imgu_sd->subdev.entity, IMGU_NODE_NUM, + imgu_sd->subdev_pads); + if (r) { + dev_err(&imgu->pci_dev->dev, + "failed initialize subdev media entity (%d)\n", r); + return r; + } + imgu_sd->subdev.entity.ops = &ipu3_media_ops; + for (i = 0; i < IMGU_NODE_NUM; i++) { + imgu_sd->subdev_pads[i].flags = imgu_pipe->nodes[i].output ? + MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; + } + + /* Initialize subdev */ + v4l2_subdev_init(&imgu_sd->subdev, &ipu3_subdev_ops); + imgu_sd->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_STATISTICS; + imgu_sd->subdev.internal_ops = &ipu3_subdev_internal_ops; + imgu_sd->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | + V4L2_SUBDEV_FL_HAS_EVENTS; + snprintf(imgu_sd->subdev.name, sizeof(imgu_sd->subdev.name), + "%s %d", IMGU_NAME, pipe); + v4l2_set_subdevdata(&imgu_sd->subdev, imgu); + atomic_set(&imgu_sd->running_mode, IPU3_RUNNING_MODE_VIDEO); + v4l2_ctrl_handler_init(hdl, 1); + imgu_sd->subdev.ctrl_handler = hdl; + imgu_sd->ctrl = v4l2_ctrl_new_custom(hdl, &ipu3_subdev_ctrl_mode, NULL); + if (hdl->error) { + r = hdl->error; + dev_err(&imgu->pci_dev->dev, + "failed to create subdev v4l2 ctrl with err %d", r); + goto fail_subdev; + } + r = v4l2_device_register_subdev(&imgu->v4l2_dev, &imgu_sd->subdev); + if (r) { + dev_err(&imgu->pci_dev->dev, + "failed initialize subdev (%d)\n", r); + goto fail_subdev; + } + + imgu_sd->pipe = pipe; + return 0; + +fail_subdev: + v4l2_ctrl_handler_free(imgu_sd->subdev.ctrl_handler); + media_entity_cleanup(&imgu_sd->subdev.entity); + + return r; +} + +static int ipu3_v4l2_node_setup(struct imgu_device *imgu, unsigned int pipe, + int node_num) +{ + int r; + u32 flags; + struct v4l2_mbus_framefmt def_bus_fmt = { 0 }; + struct v4l2_pix_format_mplane def_pix_fmt = { 0 }; + struct device *dev = &imgu->pci_dev->dev; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + struct v4l2_subdev *sd = &imgu_pipe->imgu_sd.subdev; + struct imgu_video_device *node = &imgu_pipe->nodes[node_num]; + struct video_device *vdev = &node->vdev; + struct vb2_queue *vbq = &node->vbq; + + /* Initialize formats to default values */ + def_bus_fmt.width = 1920; + def_bus_fmt.height = 1080; + def_bus_fmt.code = MEDIA_BUS_FMT_FIXED; + def_bus_fmt.field = V4L2_FIELD_NONE; + def_bus_fmt.colorspace = V4L2_COLORSPACE_RAW; + def_bus_fmt.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + def_bus_fmt.quantization = V4L2_QUANTIZATION_DEFAULT; + def_bus_fmt.xfer_func = V4L2_XFER_FUNC_DEFAULT; + + def_pix_fmt.width = def_bus_fmt.width; + def_pix_fmt.height = def_bus_fmt.height; + def_pix_fmt.field = def_bus_fmt.field; + def_pix_fmt.num_planes = 1; + def_pix_fmt.plane_fmt[0].bytesperline = def_pix_fmt.width * 2; + def_pix_fmt.plane_fmt[0].sizeimage = + def_pix_fmt.height * def_pix_fmt.plane_fmt[0].bytesperline; + def_pix_fmt.flags = 0; + def_pix_fmt.colorspace = def_bus_fmt.colorspace; + def_pix_fmt.ycbcr_enc = def_bus_fmt.ycbcr_enc; + def_pix_fmt.quantization = def_bus_fmt.quantization; + def_pix_fmt.xfer_func = def_bus_fmt.xfer_func; + + /* Initialize miscellaneous variables */ + mutex_init(&node->lock); + INIT_LIST_HEAD(&node->buffers); + + /* Initialize formats to default values */ + node->pad_fmt = def_bus_fmt; + node->id = node_num; + node->pipe = pipe; + ipu3_node_to_v4l2(node_num, vdev, &node->vdev_fmt); + if (node->vdev_fmt.type == + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || + node->vdev_fmt.type == + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + def_pix_fmt.pixelformat = node->output ? + V4L2_PIX_FMT_IPU3_SGRBG10 : + V4L2_PIX_FMT_NV12; + node->vdev_fmt.fmt.pix_mp = def_pix_fmt; + } + + /* Initialize media entities */ + r = media_entity_pads_init(&vdev->entity, 1, &node->vdev_pad); + if (r) { + dev_err(dev, "failed initialize media entity (%d)\n", r); + mutex_destroy(&node->lock); + return r; + } + node->vdev_pad.flags = node->output ? + MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK; + vdev->entity.ops = NULL; + + /* Initialize vbq */ + vbq->type = node->vdev_fmt.type; + vbq->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF; + vbq->ops = &ipu3_vb2_ops; + vbq->mem_ops = &vb2_dma_sg_memops; + if (imgu->buf_struct_size <= 0) + imgu->buf_struct_size = + sizeof(struct ipu3_vb2_buffer); + vbq->buf_struct_size = imgu->buf_struct_size; + vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + /* can streamon w/o buffers */ + vbq->min_buffers_needed = 0; + vbq->drv_priv = imgu; + vbq->lock = &node->lock; + r = vb2_queue_init(vbq); + if (r) { + dev_err(dev, "failed to initialize video queue (%d)", r); + media_entity_cleanup(&vdev->entity); + return r; + } + + /* Initialize vdev */ + snprintf(vdev->name, sizeof(vdev->name), "%s %d %s", + IMGU_NAME, pipe, node->name); + vdev->release = video_device_release_empty; + vdev->fops = &ipu3_v4l2_fops; + vdev->lock = &node->lock; + vdev->v4l2_dev = &imgu->v4l2_dev; + vdev->queue = &node->vbq; + vdev->vfl_dir = node->output ? VFL_DIR_TX : VFL_DIR_RX; + video_set_drvdata(vdev, imgu); + r = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + if (r) { + dev_err(dev, "failed to register video device (%d)", r); + media_entity_cleanup(&vdev->entity); + return r; + } + + /* Create link between video node and the subdev pad */ + flags = 0; + if (node->enabled) + flags |= MEDIA_LNK_FL_ENABLED; + if (node->output) { + r = media_create_pad_link(&vdev->entity, 0, &sd->entity, + node_num, flags); + } else { + r = media_create_pad_link(&sd->entity, node_num, &vdev->entity, + 0, flags); + } + if (r) { + dev_err(dev, "failed to create pad link (%d)", r); + video_unregister_device(vdev); + return r; + } + + return 0; +} + +static void ipu3_v4l2_nodes_cleanup_pipe(struct imgu_device *imgu, + unsigned int pipe, int node) +{ + int i; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + for (i = 0; i < node; i++) { + video_unregister_device(&imgu_pipe->nodes[i].vdev); + media_entity_cleanup(&imgu_pipe->nodes[i].vdev.entity); + mutex_destroy(&imgu_pipe->nodes[i].lock); + } +} + +static int ipu3_v4l2_nodes_setup_pipe(struct imgu_device *imgu, int pipe) +{ + int i, r; + + for (i = 0; i < IMGU_NODE_NUM; i++) { + r = ipu3_v4l2_node_setup(imgu, pipe, i); + if (r) + goto cleanup; + } + + return 0; + +cleanup: + ipu3_v4l2_nodes_cleanup_pipe(imgu, pipe, i); + return r; +} + +static void ipu3_v4l2_subdev_cleanup(struct imgu_device *imgu, unsigned int i) +{ + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[i]; + + v4l2_device_unregister_subdev(&imgu_pipe->imgu_sd.subdev); + v4l2_ctrl_handler_free(imgu_pipe->imgu_sd.subdev.ctrl_handler); + media_entity_cleanup(&imgu_pipe->imgu_sd.subdev.entity); +} + +static void ipu3_v4l2_cleanup_pipes(struct imgu_device *imgu, unsigned int pipe) +{ + int i; + + for (i = 0; i < pipe; i++) { + ipu3_v4l2_nodes_cleanup_pipe(imgu, i, IMGU_NODE_NUM); + ipu3_v4l2_subdev_cleanup(imgu, i); + } +} + +static int imgu_v4l2_register_pipes(struct imgu_device *imgu) +{ + struct imgu_media_pipe *imgu_pipe; + int i, r; + + for (i = 0; i < IMGU_MAX_PIPE_NUM; i++) { + imgu_pipe = &imgu->imgu_pipe[i]; + r = ipu3_v4l2_subdev_register(imgu, &imgu_pipe->imgu_sd, i); + if (r) { + dev_err(&imgu->pci_dev->dev, + "failed to register subdev%d ret (%d)\n", i, r); + goto pipes_cleanup; + } + r = ipu3_v4l2_nodes_setup_pipe(imgu, i); + if (r) { + ipu3_v4l2_subdev_cleanup(imgu, i); + goto pipes_cleanup; + } + } + + return 0; + +pipes_cleanup: + ipu3_v4l2_cleanup_pipes(imgu, i); + return r; +} + +int imgu_v4l2_register(struct imgu_device *imgu) +{ + int r; + + /* Initialize miscellaneous variables */ + imgu->streaming = false; + + /* Set up media device */ + media_device_pci_init(&imgu->media_dev, imgu->pci_dev, IMGU_NAME); + + /* Set up v4l2 device */ + imgu->v4l2_dev.mdev = &imgu->media_dev; + imgu->v4l2_dev.ctrl_handler = NULL; + r = v4l2_device_register(&imgu->pci_dev->dev, &imgu->v4l2_dev); + if (r) { + dev_err(&imgu->pci_dev->dev, + "failed to register V4L2 device (%d)\n", r); + goto fail_v4l2_dev; + } + + r = imgu_v4l2_register_pipes(imgu); + if (r) { + dev_err(&imgu->pci_dev->dev, + "failed to register pipes (%d)\n", r); + goto fail_v4l2_pipes; + } + + r = v4l2_device_register_subdev_nodes(&imgu->v4l2_dev); + if (r) { + dev_err(&imgu->pci_dev->dev, + "failed to register subdevs (%d)\n", r); + goto fail_subdevs; + } + + r = media_device_register(&imgu->media_dev); + if (r) { + dev_err(&imgu->pci_dev->dev, + "failed to register media device (%d)\n", r); + goto fail_subdevs; + } + + return 0; + +fail_subdevs: + ipu3_v4l2_cleanup_pipes(imgu, IMGU_MAX_PIPE_NUM); +fail_v4l2_pipes: + v4l2_device_unregister(&imgu->v4l2_dev); +fail_v4l2_dev: + media_device_cleanup(&imgu->media_dev); + + return r; +} + +int imgu_v4l2_unregister(struct imgu_device *imgu) +{ + media_device_unregister(&imgu->media_dev); + ipu3_v4l2_cleanup_pipes(imgu, IMGU_MAX_PIPE_NUM); + v4l2_device_unregister(&imgu->v4l2_dev); + media_device_cleanup(&imgu->media_dev); + + return 0; +} + +void imgu_v4l2_buffer_done(struct vb2_buffer *vb, + enum vb2_buffer_state state) +{ + struct ipu3_vb2_buffer *b = + container_of(vb, struct ipu3_vb2_buffer, vbb.vb2_buf); + + list_del(&b->list); + vb2_buffer_done(&b->vbb.vb2_buf, state); +} diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c new file mode 100644 index 000000000000..d521b3afb8b1 --- /dev/null +++ b/drivers/staging/media/ipu3/ipu3.c @@ -0,0 +1,830 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017 - 2018 Intel Corporation + * Copyright 2017 Google LLC + * + * Based on Intel IPU4 driver. + * + */ + +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> + +#include "ipu3.h" +#include "ipu3-dmamap.h" +#include "ipu3-mmu.h" + +#define IMGU_PCI_ID 0x1919 +#define IMGU_PCI_BAR 0 +#define IMGU_DMA_MASK DMA_BIT_MASK(39) +#define IMGU_MAX_QUEUE_DEPTH (2 + 2) + +/* + * pre-allocated buffer size for IMGU dummy buffers. Those + * values should be tuned to big enough to avoid buffer + * re-allocation when streaming to lower streaming latency. + */ +#define CSS_QUEUE_IN_BUF_SIZE 0 +#define CSS_QUEUE_PARAMS_BUF_SIZE 0 +#define CSS_QUEUE_OUT_BUF_SIZE (4160 * 3120 * 12 / 8) +#define CSS_QUEUE_VF_BUF_SIZE (1920 * 1080 * 12 / 8) +#define CSS_QUEUE_STAT_3A_BUF_SIZE sizeof(struct ipu3_uapi_stats_3a) + +static const size_t css_queue_buf_size_map[IPU3_CSS_QUEUES] = { + [IPU3_CSS_QUEUE_IN] = CSS_QUEUE_IN_BUF_SIZE, + [IPU3_CSS_QUEUE_PARAMS] = CSS_QUEUE_PARAMS_BUF_SIZE, + [IPU3_CSS_QUEUE_OUT] = CSS_QUEUE_OUT_BUF_SIZE, + [IPU3_CSS_QUEUE_VF] = CSS_QUEUE_VF_BUF_SIZE, + [IPU3_CSS_QUEUE_STAT_3A] = CSS_QUEUE_STAT_3A_BUF_SIZE, +}; + +static const struct imgu_node_mapping imgu_node_map[IMGU_NODE_NUM] = { + [IMGU_NODE_IN] = {IPU3_CSS_QUEUE_IN, "input"}, + [IMGU_NODE_PARAMS] = {IPU3_CSS_QUEUE_PARAMS, "parameters"}, + [IMGU_NODE_OUT] = {IPU3_CSS_QUEUE_OUT, "output"}, + [IMGU_NODE_VF] = {IPU3_CSS_QUEUE_VF, "viewfinder"}, + [IMGU_NODE_STAT_3A] = {IPU3_CSS_QUEUE_STAT_3A, "3a stat"}, +}; + +unsigned int imgu_node_to_queue(unsigned int node) +{ + return imgu_node_map[node].css_queue; +} + +unsigned int imgu_map_node(struct imgu_device *imgu, unsigned int css_queue) +{ + unsigned int i; + + for (i = 0; i < IMGU_NODE_NUM; i++) + if (imgu_node_map[i].css_queue == css_queue) + break; + + return i; +} + +/**************** Dummy buffers ****************/ + +static void imgu_dummybufs_cleanup(struct imgu_device *imgu, unsigned int pipe) +{ + unsigned int i; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + for (i = 0; i < IPU3_CSS_QUEUES; i++) + ipu3_dmamap_free(imgu, + &imgu_pipe->queues[i].dmap); +} + +static int imgu_dummybufs_preallocate(struct imgu_device *imgu, + unsigned int pipe) +{ + unsigned int i; + size_t size; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + for (i = 0; i < IPU3_CSS_QUEUES; i++) { + size = css_queue_buf_size_map[i]; + /* + * Do not enable dummy buffers for master queue, + * always require that real buffers from user are + * available. + */ + if (i == IMGU_QUEUE_MASTER || size == 0) + continue; + + if (!ipu3_dmamap_alloc(imgu, + &imgu_pipe->queues[i].dmap, size)) { + imgu_dummybufs_cleanup(imgu, pipe); + return -ENOMEM; + } + } + + return 0; +} + +static int imgu_dummybufs_init(struct imgu_device *imgu, unsigned int pipe) +{ + const struct v4l2_pix_format_mplane *mpix; + const struct v4l2_meta_format *meta; + unsigned int i, k, node; + size_t size; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + /* Allocate a dummy buffer for each queue where buffer is optional */ + for (i = 0; i < IPU3_CSS_QUEUES; i++) { + node = imgu_map_node(imgu, i); + if (!imgu_pipe->queue_enabled[node] || i == IMGU_QUEUE_MASTER) + continue; + + if (!imgu_pipe->nodes[IMGU_NODE_VF].enabled && + i == IPU3_CSS_QUEUE_VF) + /* + * Do not enable dummy buffers for VF if it is not + * requested by the user. + */ + continue; + + meta = &imgu_pipe->nodes[node].vdev_fmt.fmt.meta; + mpix = &imgu_pipe->nodes[node].vdev_fmt.fmt.pix_mp; + + if (node == IMGU_NODE_STAT_3A || node == IMGU_NODE_PARAMS) + size = meta->buffersize; + else + size = mpix->plane_fmt[0].sizeimage; + + if (ipu3_css_dma_buffer_resize(imgu, + &imgu_pipe->queues[i].dmap, + size)) { + imgu_dummybufs_cleanup(imgu, pipe); + return -ENOMEM; + } + + for (k = 0; k < IMGU_MAX_QUEUE_DEPTH; k++) + ipu3_css_buf_init(&imgu_pipe->queues[i].dummybufs[k], i, + imgu_pipe->queues[i].dmap.daddr); + } + + return 0; +} + +/* May be called from atomic context */ +static struct ipu3_css_buffer *imgu_dummybufs_get(struct imgu_device *imgu, + int queue, unsigned int pipe) +{ + unsigned int i; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + /* dummybufs are not allocated for master q */ + if (queue == IPU3_CSS_QUEUE_IN) + return NULL; + + if (WARN_ON(!imgu_pipe->queues[queue].dmap.vaddr)) + /* Buffer should not be allocated here */ + return NULL; + + for (i = 0; i < IMGU_MAX_QUEUE_DEPTH; i++) + if (ipu3_css_buf_state(&imgu_pipe->queues[queue].dummybufs[i]) != + IPU3_CSS_BUFFER_QUEUED) + break; + + if (i == IMGU_MAX_QUEUE_DEPTH) + return NULL; + + ipu3_css_buf_init(&imgu_pipe->queues[queue].dummybufs[i], queue, + imgu_pipe->queues[queue].dmap.daddr); + + return &imgu_pipe->queues[queue].dummybufs[i]; +} + +/* Check if given buffer is a dummy buffer */ +static bool imgu_dummybufs_check(struct imgu_device *imgu, + struct ipu3_css_buffer *buf, + unsigned int pipe) +{ + unsigned int i; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + for (i = 0; i < IMGU_MAX_QUEUE_DEPTH; i++) + if (buf == &imgu_pipe->queues[buf->queue].dummybufs[i]) + break; + + return i < IMGU_MAX_QUEUE_DEPTH; +} + +static void imgu_buffer_done(struct imgu_device *imgu, struct vb2_buffer *vb, + enum vb2_buffer_state state) +{ + mutex_lock(&imgu->lock); + imgu_v4l2_buffer_done(vb, state); + mutex_unlock(&imgu->lock); +} + +static struct ipu3_css_buffer *imgu_queue_getbuf(struct imgu_device *imgu, + unsigned int node, + unsigned int pipe) +{ + struct imgu_buffer *buf; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + if (WARN_ON(node >= IMGU_NODE_NUM)) + return NULL; + + /* Find first free buffer from the node */ + list_for_each_entry(buf, &imgu_pipe->nodes[node].buffers, vid_buf.list) { + if (ipu3_css_buf_state(&buf->css_buf) == IPU3_CSS_BUFFER_NEW) + return &buf->css_buf; + } + + /* There were no free buffers, try to return a dummy buffer */ + return imgu_dummybufs_get(imgu, imgu_node_map[node].css_queue, pipe); +} + +/* + * Queue as many buffers to CSS as possible. If all buffers don't fit into + * CSS buffer queues, they remain unqueued and will be queued later. + */ +int imgu_queue_buffers(struct imgu_device *imgu, bool initial, unsigned int pipe) +{ + unsigned int node; + int r = 0; + struct imgu_media_pipe *imgu_pipe = &imgu->imgu_pipe[pipe]; + + if (!ipu3_css_is_streaming(&imgu->css)) + return 0; + + dev_dbg(&imgu->pci_dev->dev, "Queue buffers to pipe %d", pipe); + mutex_lock(&imgu->lock); + + /* Buffer set is queued to FW only when input buffer is ready */ + for (node = IMGU_NODE_NUM - 1; + imgu_queue_getbuf(imgu, IMGU_NODE_IN, pipe); + node = node ? node - 1 : IMGU_NODE_NUM - 1) { + + if (node == IMGU_NODE_VF && + !imgu_pipe->nodes[IMGU_NODE_VF].enabled) { + dev_warn(&imgu->pci_dev->dev, + "Vf not enabled, ignore queue"); + continue; + } else if (imgu_pipe->queue_enabled[node]) { + struct ipu3_css_buffer *buf = + imgu_queue_getbuf(imgu, node, pipe); + struct imgu_buffer *ibuf = NULL; + bool dummy; + + if (!buf) + break; + + r = ipu3_css_buf_queue(&imgu->css, pipe, buf); + if (r) + break; + dummy = imgu_dummybufs_check(imgu, buf, pipe); + if (!dummy) + ibuf = container_of(buf, struct imgu_buffer, + css_buf); + dev_dbg(&imgu->pci_dev->dev, + "queue %s %s buffer %u to css da: 0x%08x\n", + dummy ? "dummy" : "user", + imgu_node_map[node].name, + dummy ? 0 : ibuf->vid_buf.vbb.vb2_buf.index, + (u32)buf->daddr); + } + } + mutex_unlock(&imgu->lock); + + if (r && r != -EBUSY) + goto failed; + + return 0; + +failed: + /* + * On error, mark all buffers as failed which are not + * yet queued to CSS + */ + dev_err(&imgu->pci_dev->dev, + "failed to queue buffer to CSS on queue %i (%d)\n", + node, r); + + if (initial) + /* If we were called from streamon(), no need to finish bufs */ + return r; + + for (node = 0; node < IMGU_NODE_NUM; node++) { + struct imgu_buffer *buf, *buf0; + + if (!imgu_pipe->queue_enabled[node]) + continue; /* Skip disabled queues */ + + mutex_lock(&imgu->lock); + list_for_each_entry_safe(buf, buf0, + &imgu_pipe->nodes[node].buffers, + vid_buf.list) { + if (ipu3_css_buf_state(&buf->css_buf) == + IPU3_CSS_BUFFER_QUEUED) + continue; /* Was already queued, skip */ + + imgu_v4l2_buffer_done(&buf->vid_buf.vbb.vb2_buf, + VB2_BUF_STATE_ERROR); + } + mutex_unlock(&imgu->lock); + } + + return r; +} + +static int imgu_powerup(struct imgu_device *imgu) +{ + int r; + + r = ipu3_css_set_powerup(&imgu->pci_dev->dev, imgu->base); + if (r) + return r; + + ipu3_mmu_resume(imgu->mmu); + return 0; +} + +static void imgu_powerdown(struct imgu_device *imgu) +{ + ipu3_mmu_suspend(imgu->mmu); + ipu3_css_set_powerdown(&imgu->pci_dev->dev, imgu->base); +} + +int imgu_s_stream(struct imgu_device *imgu, int enable) +{ + struct device *dev = &imgu->pci_dev->dev; + int r, pipe; + + if (!enable) { + /* Stop streaming */ + dev_dbg(dev, "stream off\n"); + /* Block new buffers to be queued to CSS. */ + atomic_set(&imgu->qbuf_barrier, 1); + ipu3_css_stop_streaming(&imgu->css); + synchronize_irq(imgu->pci_dev->irq); + atomic_set(&imgu->qbuf_barrier, 0); + imgu_powerdown(imgu); + pm_runtime_put(&imgu->pci_dev->dev); + + return 0; + } + + /* Set Power */ + r = pm_runtime_get_sync(dev); + if (r < 0) { + dev_err(dev, "failed to set imgu power\n"); + pm_runtime_put(dev); + return r; + } + + r = imgu_powerup(imgu); + if (r) { + dev_err(dev, "failed to power up imgu\n"); + pm_runtime_put(dev); + return r; + } + + /* Start CSS streaming */ + r = ipu3_css_start_streaming(&imgu->css); + if (r) { + dev_err(dev, "failed to start css streaming (%d)", r); + goto fail_start_streaming; + } + + for_each_set_bit(pipe, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) { + /* Initialize dummy buffers */ + r = imgu_dummybufs_init(imgu, pipe); + if (r) { + dev_err(dev, "failed to initialize dummy buffers (%d)", r); + goto fail_dummybufs; + } + + /* Queue as many buffers from queue as possible */ + r = imgu_queue_buffers(imgu, true, pipe); + if (r) { + dev_err(dev, "failed to queue initial buffers (%d)", r); + goto fail_queueing; + } + } + + return 0; +fail_queueing: + for_each_set_bit(pipe, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) + imgu_dummybufs_cleanup(imgu, pipe); +fail_dummybufs: + ipu3_css_stop_streaming(&imgu->css); +fail_start_streaming: + pm_runtime_put(dev); + + return r; +} + +static int imgu_video_nodes_init(struct imgu_device *imgu) +{ + struct v4l2_pix_format_mplane *fmts[IPU3_CSS_QUEUES] = { NULL }; + struct v4l2_rect *rects[IPU3_CSS_RECTS] = { NULL }; + struct imgu_media_pipe *imgu_pipe; + unsigned int i, j; + int r; + + imgu->buf_struct_size = sizeof(struct imgu_buffer); + + for (j = 0; j < IMGU_MAX_PIPE_NUM; j++) { + imgu_pipe = &imgu->imgu_pipe[j]; + + for (i = 0; i < IMGU_NODE_NUM; i++) { + imgu_pipe->nodes[i].name = imgu_node_map[i].name; + imgu_pipe->nodes[i].output = i < IMGU_QUEUE_FIRST_INPUT; + imgu_pipe->nodes[i].enabled = false; + + if (i != IMGU_NODE_PARAMS && i != IMGU_NODE_STAT_3A) + fmts[imgu_node_map[i].css_queue] = + &imgu_pipe->nodes[i].vdev_fmt.fmt.pix_mp; + atomic_set(&imgu_pipe->nodes[i].sequence, 0); + } + } + + r = imgu_v4l2_register(imgu); + if (r) + return r; + + /* Set initial formats and initialize formats of video nodes */ + for (j = 0; j < IMGU_MAX_PIPE_NUM; j++) { + imgu_pipe = &imgu->imgu_pipe[j]; + + rects[IPU3_CSS_RECT_EFFECTIVE] = &imgu_pipe->imgu_sd.rect.eff; + rects[IPU3_CSS_RECT_BDS] = &imgu_pipe->imgu_sd.rect.bds; + ipu3_css_fmt_set(&imgu->css, fmts, rects, j); + + /* Pre-allocate dummy buffers */ + r = imgu_dummybufs_preallocate(imgu, j); + if (r) { + dev_err(&imgu->pci_dev->dev, + "failed to pre-allocate dummy buffers (%d)", r); + goto out_cleanup; + } + } + + return 0; + +out_cleanup: + for (j = 0; j < IMGU_MAX_PIPE_NUM; j++) + imgu_dummybufs_cleanup(imgu, j); + + imgu_v4l2_unregister(imgu); + + return r; +} + +static void imgu_video_nodes_exit(struct imgu_device *imgu) +{ + int i; + + for (i = 0; i < IMGU_MAX_PIPE_NUM; i++) + imgu_dummybufs_cleanup(imgu, i); + + imgu_v4l2_unregister(imgu); +} + +/**************** PCI interface ****************/ + +static irqreturn_t imgu_isr_threaded(int irq, void *imgu_ptr) +{ + struct imgu_device *imgu = imgu_ptr; + struct imgu_media_pipe *imgu_pipe; + int p; + + /* Dequeue / queue buffers */ + do { + u64 ns = ktime_get_ns(); + struct ipu3_css_buffer *b; + struct imgu_buffer *buf = NULL; + unsigned int node, pipe; + bool dummy; + + do { + mutex_lock(&imgu->lock); + b = ipu3_css_buf_dequeue(&imgu->css); + mutex_unlock(&imgu->lock); + } while (PTR_ERR(b) == -EAGAIN); + + if (IS_ERR_OR_NULL(b)) { + if (!b || PTR_ERR(b) == -EBUSY) /* All done */ + break; + dev_err(&imgu->pci_dev->dev, + "failed to dequeue buffers (%ld)\n", + PTR_ERR(b)); + break; + } + + node = imgu_map_node(imgu, b->queue); + pipe = b->pipe; + dummy = imgu_dummybufs_check(imgu, b, pipe); + if (!dummy) + buf = container_of(b, struct imgu_buffer, css_buf); + dev_dbg(&imgu->pci_dev->dev, + "dequeue %s %s buffer %d daddr 0x%x from css\n", + dummy ? "dummy" : "user", + imgu_node_map[node].name, + dummy ? 0 : buf->vid_buf.vbb.vb2_buf.index, + (u32)b->daddr); + + if (dummy) + /* It was a dummy buffer, skip it */ + continue; + + /* Fill vb2 buffer entries and tell it's ready */ + imgu_pipe = &imgu->imgu_pipe[pipe]; + if (!imgu_pipe->nodes[node].output) { + buf->vid_buf.vbb.vb2_buf.timestamp = ns; + buf->vid_buf.vbb.field = V4L2_FIELD_NONE; + buf->vid_buf.vbb.sequence = + atomic_inc_return( + &imgu_pipe->nodes[node].sequence); + dev_dbg(&imgu->pci_dev->dev, "vb2 buffer sequence %d", + buf->vid_buf.vbb.sequence); + } + imgu_buffer_done(imgu, &buf->vid_buf.vbb.vb2_buf, + ipu3_css_buf_state(&buf->css_buf) == + IPU3_CSS_BUFFER_DONE ? + VB2_BUF_STATE_DONE : + VB2_BUF_STATE_ERROR); + mutex_lock(&imgu->lock); + if (ipu3_css_queue_empty(&imgu->css)) + wake_up_all(&imgu->buf_drain_wq); + mutex_unlock(&imgu->lock); + } while (1); + + /* + * Try to queue more buffers for CSS. + * qbuf_barrier is used to disable new buffers + * to be queued to CSS. + */ + if (!atomic_read(&imgu->qbuf_barrier)) + for_each_set_bit(p, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) + imgu_queue_buffers(imgu, false, p); + + return IRQ_HANDLED; +} + +static irqreturn_t imgu_isr(int irq, void *imgu_ptr) +{ + struct imgu_device *imgu = imgu_ptr; + + /* acknowledge interruption */ + if (ipu3_css_irq_ack(&imgu->css) < 0) + return IRQ_NONE; + + return IRQ_WAKE_THREAD; +} + +static int imgu_pci_config_setup(struct pci_dev *dev) +{ + u16 pci_command; + int r = pci_enable_msi(dev); + + if (r) { + dev_err(&dev->dev, "failed to enable MSI (%d)\n", r); + return r; + } + + pci_read_config_word(dev, PCI_COMMAND, &pci_command); + pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(dev, PCI_COMMAND, pci_command); + + return 0; +} + +static int imgu_pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *id) +{ + struct imgu_device *imgu; + phys_addr_t phys; + unsigned long phys_len; + void __iomem *const *iomap; + int r; + + imgu = devm_kzalloc(&pci_dev->dev, sizeof(*imgu), GFP_KERNEL); + if (!imgu) + return -ENOMEM; + + imgu->pci_dev = pci_dev; + + r = pcim_enable_device(pci_dev); + if (r) { + dev_err(&pci_dev->dev, "failed to enable device (%d)\n", r); + return r; + } + + dev_info(&pci_dev->dev, "device 0x%x (rev: 0x%x)\n", + pci_dev->device, pci_dev->revision); + + phys = pci_resource_start(pci_dev, IMGU_PCI_BAR); + phys_len = pci_resource_len(pci_dev, IMGU_PCI_BAR); + + r = pcim_iomap_regions(pci_dev, 1 << IMGU_PCI_BAR, pci_name(pci_dev)); + if (r) { + dev_err(&pci_dev->dev, "failed to remap I/O memory (%d)\n", r); + return r; + } + dev_info(&pci_dev->dev, "physical base address %pap, %lu bytes\n", + &phys, phys_len); + + iomap = pcim_iomap_table(pci_dev); + if (!iomap) { + dev_err(&pci_dev->dev, "failed to iomap table\n"); + return -ENODEV; + } + + imgu->base = iomap[IMGU_PCI_BAR]; + + pci_set_drvdata(pci_dev, imgu); + + pci_set_master(pci_dev); + + r = dma_coerce_mask_and_coherent(&pci_dev->dev, IMGU_DMA_MASK); + if (r) { + dev_err(&pci_dev->dev, "failed to set DMA mask (%d)\n", r); + return -ENODEV; + } + + r = imgu_pci_config_setup(pci_dev); + if (r) + return r; + + mutex_init(&imgu->lock); + atomic_set(&imgu->qbuf_barrier, 0); + init_waitqueue_head(&imgu->buf_drain_wq); + + r = ipu3_css_set_powerup(&pci_dev->dev, imgu->base); + if (r) { + dev_err(&pci_dev->dev, + "failed to power up CSS (%d)\n", r); + goto out_mutex_destroy; + } + + imgu->mmu = ipu3_mmu_init(&pci_dev->dev, imgu->base); + if (IS_ERR(imgu->mmu)) { + r = PTR_ERR(imgu->mmu); + dev_err(&pci_dev->dev, "failed to initialize MMU (%d)\n", r); + goto out_css_powerdown; + } + + r = ipu3_dmamap_init(imgu); + if (r) { + dev_err(&pci_dev->dev, + "failed to initialize DMA mapping (%d)\n", r); + goto out_mmu_exit; + } + + /* ISP programming */ + r = ipu3_css_init(&pci_dev->dev, &imgu->css, imgu->base, phys_len); + if (r) { + dev_err(&pci_dev->dev, "failed to initialize CSS (%d)\n", r); + goto out_dmamap_exit; + } + + /* v4l2 sub-device registration */ + r = imgu_video_nodes_init(imgu); + if (r) { + dev_err(&pci_dev->dev, "failed to create V4L2 devices (%d)\n", + r); + goto out_css_cleanup; + } + + r = devm_request_threaded_irq(&pci_dev->dev, pci_dev->irq, + imgu_isr, imgu_isr_threaded, + IRQF_SHARED, IMGU_NAME, imgu); + if (r) { + dev_err(&pci_dev->dev, "failed to request IRQ (%d)\n", r); + goto out_video_exit; + } + + pm_runtime_put_noidle(&pci_dev->dev); + pm_runtime_allow(&pci_dev->dev); + + return 0; + +out_video_exit: + imgu_video_nodes_exit(imgu); +out_css_cleanup: + ipu3_css_cleanup(&imgu->css); +out_dmamap_exit: + ipu3_dmamap_exit(imgu); +out_mmu_exit: + ipu3_mmu_exit(imgu->mmu); +out_css_powerdown: + ipu3_css_set_powerdown(&pci_dev->dev, imgu->base); +out_mutex_destroy: + mutex_destroy(&imgu->lock); + + return r; +} + +static void imgu_pci_remove(struct pci_dev *pci_dev) +{ + struct imgu_device *imgu = pci_get_drvdata(pci_dev); + + pm_runtime_forbid(&pci_dev->dev); + pm_runtime_get_noresume(&pci_dev->dev); + + imgu_video_nodes_exit(imgu); + ipu3_css_cleanup(&imgu->css); + ipu3_css_set_powerdown(&pci_dev->dev, imgu->base); + ipu3_dmamap_exit(imgu); + ipu3_mmu_exit(imgu->mmu); + mutex_destroy(&imgu->lock); +} + +static int __maybe_unused imgu_suspend(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + struct imgu_device *imgu = pci_get_drvdata(pci_dev); + + dev_dbg(dev, "enter %s\n", __func__); + imgu->suspend_in_stream = ipu3_css_is_streaming(&imgu->css); + if (!imgu->suspend_in_stream) + goto out; + /* Block new buffers to be queued to CSS. */ + atomic_set(&imgu->qbuf_barrier, 1); + /* + * Wait for currently running irq handler to be done so that + * no new buffers will be queued to fw later. + */ + synchronize_irq(pci_dev->irq); + /* Wait until all buffers in CSS are done. */ + if (!wait_event_timeout(imgu->buf_drain_wq, + ipu3_css_queue_empty(&imgu->css), msecs_to_jiffies(1000))) + dev_err(dev, "wait buffer drain timeout.\n"); + + ipu3_css_stop_streaming(&imgu->css); + atomic_set(&imgu->qbuf_barrier, 0); + imgu_powerdown(imgu); + pm_runtime_force_suspend(dev); +out: + dev_dbg(dev, "leave %s\n", __func__); + return 0; +} + +static int __maybe_unused imgu_resume(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + struct imgu_device *imgu = pci_get_drvdata(pci_dev); + int r = 0; + unsigned int pipe; + + dev_dbg(dev, "enter %s\n", __func__); + + if (!imgu->suspend_in_stream) + goto out; + + pm_runtime_force_resume(dev); + + r = imgu_powerup(imgu); + if (r) { + dev_err(dev, "failed to power up imgu\n"); + goto out; + } + + /* Start CSS streaming */ + r = ipu3_css_start_streaming(&imgu->css); + if (r) { + dev_err(dev, "failed to resume css streaming (%d)", r); + goto out; + } + + for_each_set_bit(pipe, imgu->css.enabled_pipes, IMGU_MAX_PIPE_NUM) { + r = imgu_queue_buffers(imgu, true, pipe); + if (r) + dev_err(dev, "failed to queue buffers to pipe %d (%d)", + pipe, r); + } + +out: + dev_dbg(dev, "leave %s\n", __func__); + + return r; +} + +/* + * PCI rpm framework checks the existence of driver rpm callbacks. + * Place a dummy callback here to avoid rpm going into error state. + */ +static int imgu_rpm_dummy_cb(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops imgu_pm_ops = { + SET_RUNTIME_PM_OPS(&imgu_rpm_dummy_cb, &imgu_rpm_dummy_cb, NULL) + SET_SYSTEM_SLEEP_PM_OPS(&imgu_suspend, &imgu_resume) +}; + +static const struct pci_device_id imgu_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, IMGU_PCI_ID) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, imgu_pci_tbl); + +static struct pci_driver imgu_pci_driver = { + .name = IMGU_NAME, + .id_table = imgu_pci_tbl, + .probe = imgu_pci_probe, + .remove = imgu_pci_remove, + .driver = { + .pm = &imgu_pm_ops, + }, +}; + +module_pci_driver(imgu_pci_driver); + +MODULE_AUTHOR("Tuukka Toivonen <tuukka.toivonen@intel.com>"); +MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>"); +MODULE_AUTHOR("Jian Xu Zheng <jian.xu.zheng@intel.com>"); +MODULE_AUTHOR("Yuning Pu <yuning.pu@intel.com>"); +MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Intel ipu3_imgu PCI driver"); diff --git a/drivers/staging/media/ipu3/ipu3.h b/drivers/staging/media/ipu3/ipu3.h new file mode 100644 index 000000000000..04fc99f47ebb --- /dev/null +++ b/drivers/staging/media/ipu3/ipu3.h @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2018 Intel Corporation */ + +#ifndef __IPU3_H +#define __IPU3_H + +#include <linux/iova.h> +#include <linux/pci.h> + +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/videobuf2-dma-sg.h> + +#include "ipu3-css.h" + +#define IMGU_NAME "ipu3-imgu" + +/* + * The semantics of the driver is that whenever there is a buffer available in + * master queue, the driver queues a buffer also to all other active nodes. + * If user space hasn't provided a buffer to all other video nodes first, + * the driver gets an internal dummy buffer and queues it. + */ +#define IMGU_QUEUE_MASTER IPU3_CSS_QUEUE_IN +#define IMGU_QUEUE_FIRST_INPUT IPU3_CSS_QUEUE_OUT +#define IMGU_MAX_QUEUE_DEPTH (2 + 2) + +#define IMGU_NODE_IN 0 /* Input RAW image */ +#define IMGU_NODE_PARAMS 1 /* Input parameters */ +#define IMGU_NODE_OUT 2 /* Main output for still or video */ +#define IMGU_NODE_VF 3 /* Preview */ +#define IMGU_NODE_STAT_3A 4 /* 3A statistics */ +#define IMGU_NODE_NUM 5 + +#define file_to_intel_ipu3_node(__file) \ + container_of(video_devdata(__file), struct imgu_video_device, vdev) + +#define IPU3_INPUT_MIN_WIDTH 0U +#define IPU3_INPUT_MIN_HEIGHT 0U +#define IPU3_INPUT_MAX_WIDTH 5120U +#define IPU3_INPUT_MAX_HEIGHT 38404U +#define IPU3_OUTPUT_MIN_WIDTH 2U +#define IPU3_OUTPUT_MIN_HEIGHT 2U +#define IPU3_OUTPUT_MAX_WIDTH 4480U +#define IPU3_OUTPUT_MAX_HEIGHT 34004U + +struct ipu3_vb2_buffer { + /* Public fields */ + struct vb2_v4l2_buffer vbb; /* Must be the first field */ + + /* Private fields */ + struct list_head list; +}; + +struct imgu_buffer { + struct ipu3_vb2_buffer vid_buf; /* Must be the first field */ + struct ipu3_css_buffer css_buf; + struct ipu3_css_map map; +}; + +struct imgu_node_mapping { + unsigned int css_queue; + const char *name; +}; + +/** + * struct imgu_video_device + * each node registers as video device and maintains its + * own vb2_queue. + */ +struct imgu_video_device { + const char *name; + bool output; + bool enabled; + struct v4l2_format vdev_fmt; /* Currently set format */ + + /* Private fields */ + struct video_device vdev; + struct media_pad vdev_pad; + struct v4l2_mbus_framefmt pad_fmt; + struct vb2_queue vbq; + struct list_head buffers; + /* Protect vb2_queue and vdev structs*/ + struct mutex lock; + atomic_t sequence; + unsigned int id; + unsigned int pipe; +}; + +struct imgu_v4l2_subdev { + unsigned int pipe; + struct v4l2_subdev subdev; + struct media_pad subdev_pads[IMGU_NODE_NUM]; + struct { + struct v4l2_rect eff; /* effective resolution */ + struct v4l2_rect bds; /* bayer-domain scaled resolution*/ + struct v4l2_rect gdc; /* gdc output resolution */ + } rect; + struct v4l2_ctrl_handler ctrl_handler; + struct v4l2_ctrl *ctrl; + atomic_t running_mode; + bool active; +}; + +struct imgu_media_pipe { + unsigned int pipe; + + /* Internally enabled queues */ + struct { + struct ipu3_css_map dmap; + struct ipu3_css_buffer dummybufs[IMGU_MAX_QUEUE_DEPTH]; + } queues[IPU3_CSS_QUEUES]; + struct imgu_video_device nodes[IMGU_NODE_NUM]; + bool queue_enabled[IMGU_NODE_NUM]; + struct media_pipeline pipeline; + struct imgu_v4l2_subdev imgu_sd; +}; + +/* + * imgu_device -- ImgU (Imaging Unit) driver + */ +struct imgu_device { + struct pci_dev *pci_dev; + void __iomem *base; + + /* Public fields, fill before registering */ + unsigned int buf_struct_size; + bool streaming; /* Public read only */ + + struct imgu_media_pipe imgu_pipe[IMGU_MAX_PIPE_NUM]; + + /* Private fields */ + struct v4l2_device v4l2_dev; + struct media_device media_dev; + struct v4l2_file_operations v4l2_file_ops; + + /* MMU driver for css */ + struct ipu3_mmu_info *mmu; + struct iova_domain iova_domain; + + /* css - Camera Sub-System */ + struct ipu3_css css; + + /* + * Coarse-grained lock to protect + * vid_buf.list and css->queue + */ + struct mutex lock; + /* Forbit streaming and buffer queuing during system suspend. */ + atomic_t qbuf_barrier; + /* Indicate if system suspend take place while imgu is streaming. */ + bool suspend_in_stream; + /* Used to wait for FW buffer queue drain. */ + wait_queue_head_t buf_drain_wq; +}; + +unsigned int imgu_node_to_queue(unsigned int node); +unsigned int imgu_map_node(struct imgu_device *imgu, unsigned int css_queue); +int imgu_queue_buffers(struct imgu_device *imgu, bool initial, + unsigned int pipe); + +int imgu_v4l2_register(struct imgu_device *dev); +int imgu_v4l2_unregister(struct imgu_device *dev); +void imgu_v4l2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); + +int imgu_s_stream(struct imgu_device *imgu, int enable); + +#endif diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index aa4511aa5ffc..8533ece5026e 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -48,6 +48,9 @@ struct v4l2_fh; * @vidioc_enum_fmt_meta_cap: pointer to the function that implements * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic * for metadata capture + * @vidioc_enum_fmt_meta_out: pointer to the function that implements + * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic + * for metadata output * @vidioc_g_fmt_vid_cap: pointer to the function that implements * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture * in single plane mode @@ -80,6 +83,8 @@ struct v4l2_fh; * Radio output * @vidioc_g_fmt_meta_cap: pointer to the function that implements * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata capture + * @vidioc_g_fmt_meta_out: pointer to the function that implements + * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata output * @vidioc_s_fmt_vid_cap: pointer to the function that implements * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture * in single plane mode @@ -112,6 +117,8 @@ struct v4l2_fh; * Radio output * @vidioc_s_fmt_meta_cap: pointer to the function that implements * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata capture + * @vidioc_s_fmt_meta_out: pointer to the function that implements + * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata output * @vidioc_try_fmt_vid_cap: pointer to the function that implements * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture * in single plane mode @@ -146,6 +153,8 @@ struct v4l2_fh; * Radio output * @vidioc_try_fmt_meta_cap: pointer to the function that implements * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata capture + * @vidioc_try_fmt_meta_out: pointer to the function that implements + * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata output * @vidioc_reqbufs: pointer to the function that implements * :ref:`VIDIOC_REQBUFS <vidioc_reqbufs>` ioctl * @vidioc_querybuf: pointer to the function that implements @@ -314,6 +323,8 @@ struct v4l2_ioctl_ops { struct v4l2_fmtdesc *f); int (*vidioc_enum_fmt_meta_cap)(struct file *file, void *fh, struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_meta_out)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); /* VIDIOC_G_FMT handlers */ int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh, @@ -342,6 +353,8 @@ struct v4l2_ioctl_ops { struct v4l2_format *f); int (*vidioc_g_fmt_meta_cap)(struct file *file, void *fh, struct v4l2_format *f); + int (*vidioc_g_fmt_meta_out)(struct file *file, void *fh, + struct v4l2_format *f); /* VIDIOC_S_FMT handlers */ int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh, @@ -370,6 +383,8 @@ struct v4l2_ioctl_ops { struct v4l2_format *f); int (*vidioc_s_fmt_meta_cap)(struct file *file, void *fh, struct v4l2_format *f); + int (*vidioc_s_fmt_meta_out)(struct file *file, void *fh, + struct v4l2_format *f); /* VIDIOC_TRY_FMT handlers */ int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh, @@ -398,6 +413,8 @@ struct v4l2_ioctl_ops { struct v4l2_format *f); int (*vidioc_try_fmt_meta_cap)(struct file *file, void *fh, struct v4l2_format *f); + int (*vidioc_try_fmt_meta_out)(struct file *file, void *fh, + struct v4l2_format *f); /* Buffer handlers */ int (*vidioc_reqbufs)(struct file *file, void *fh, diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index d2e8b756e04d..b5671ce2724f 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -145,6 +145,7 @@ enum v4l2_buf_type { V4L2_BUF_TYPE_SDR_CAPTURE = 11, V4L2_BUF_TYPE_SDR_OUTPUT = 12, V4L2_BUF_TYPE_META_CAPTURE = 13, + V4L2_BUF_TYPE_META_OUTPUT = 14, /* Deprecated, do not use */ V4L2_BUF_TYPE_PRIVATE = 0x80, }; @@ -469,6 +470,7 @@ struct v4l2_capability { #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ +#define V4L2_CAP_META_OUTPUT 0x08000000 /* Is a metadata output device */ #define V4L2_CAP_TOUCH 0x10000000 /* Is a touch device */ |