diff options
Diffstat (limited to 'drivers/staging')
68 files changed, 27772 insertions, 1356 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 7c015536360d..e4f608815c05 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -78,8 +78,6 @@ source "drivers/staging/goldfish/Kconfig" source "drivers/staging/netlogic/Kconfig" -source "drivers/staging/mt29f_spinand/Kconfig" - source "drivers/staging/gs_fpgaboot/Kconfig" source "drivers/staging/unisys/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index a79b3fe20cf0..5868631e8f1b 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_STAGING_BOARD) += board/ obj-$(CONFIG_LTE_GDM724X) += gdm724x/ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ obj-$(CONFIG_GOLDFISH) += goldfish/ -obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand/ obj-$(CONFIG_GS_FPGABOOT) += gs_fpgaboot/ obj-$(CONFIG_UNISYSSPAR) += unisys/ obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/ diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 9ce2c0d7ac17..0383f7548d48 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -109,7 +109,7 @@ static int ion_system_heap_allocate(struct ion_heap *heap, unsigned long size_remaining = PAGE_ALIGN(size); unsigned int max_order = orders[0]; - if (size / PAGE_SIZE > totalram_pages / 2) + if (size / PAGE_SIZE > totalram_pages() / 2) return -ENOMEM; INIT_LIST_HEAD(&pages); diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c index 7a7ca67822c5..daabaceeea52 100644 --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c @@ -719,9 +719,6 @@ static int port_vlans_add(struct net_device *netdev, struct ethsw_port_priv *port_priv = netdev_priv(netdev); int vid, err = 0; - if (netif_is_bridge_master(vlan->obj.orig_dev)) - return -EOPNOTSUPP; - if (switchdev_trans_ph_prepare(trans)) return 0; @@ -930,8 +927,6 @@ static int swdev_port_obj_del(struct net_device *netdev, static const struct switchdev_ops ethsw_port_switchdev_ops = { .switchdev_port_attr_get = swdev_port_attr_get, .switchdev_port_attr_set = swdev_port_attr_set, - .switchdev_port_obj_add = swdev_port_obj_add, - .switchdev_port_obj_del = swdev_port_obj_del, }; /* For the moment, only flood setting needs to be updated */ @@ -972,6 +967,11 @@ static int port_bridge_leave(struct net_device *netdev) return err; } +static bool ethsw_port_dev_check(const struct net_device *netdev) +{ + return netdev->netdev_ops == ðsw_port_ops; +} + static int port_netdevice_event(struct notifier_block *unused, unsigned long event, void *ptr) { @@ -980,7 +980,7 @@ static int port_netdevice_event(struct notifier_block *unused, struct net_device *upper_dev; int err = 0; - if (netdev->netdev_ops != ðsw_port_ops) + if (!ethsw_port_dev_check(netdev)) return NOTIFY_DONE; /* Handle just upper dev link/unlink for the moment */ @@ -1083,10 +1083,51 @@ err_addr_alloc: return NOTIFY_BAD; } +static int +ethsw_switchdev_port_obj_event(unsigned long event, struct net_device *netdev, + struct switchdev_notifier_port_obj_info *port_obj_info) +{ + int err = -EOPNOTSUPP; + + switch (event) { + case SWITCHDEV_PORT_OBJ_ADD: + err = swdev_port_obj_add(netdev, port_obj_info->obj, + port_obj_info->trans); + break; + case SWITCHDEV_PORT_OBJ_DEL: + err = swdev_port_obj_del(netdev, port_obj_info->obj); + break; + } + + port_obj_info->handled = true; + return notifier_from_errno(err); +} + +static int port_switchdev_blocking_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = switchdev_notifier_info_to_dev(ptr); + + if (!ethsw_port_dev_check(dev)) + return NOTIFY_DONE; + + switch (event) { + case SWITCHDEV_PORT_OBJ_ADD: /* fall through */ + case SWITCHDEV_PORT_OBJ_DEL: + return ethsw_switchdev_port_obj_event(event, dev, ptr); + } + + return NOTIFY_DONE; +} + static struct notifier_block port_switchdev_nb = { .notifier_call = port_switchdev_event, }; +static struct notifier_block port_switchdev_blocking_nb = { + .notifier_call = port_switchdev_blocking_event, +}; + static int ethsw_register_notifier(struct device *dev) { int err; @@ -1103,8 +1144,16 @@ static int ethsw_register_notifier(struct device *dev) goto err_switchdev_nb; } + err = register_switchdev_blocking_notifier(&port_switchdev_blocking_nb); + if (err) { + dev_err(dev, "Failed to register switchdev blocking notifier\n"); + goto err_switchdev_blocking_nb; + } + return 0; +err_switchdev_blocking_nb: + unregister_switchdev_notifier(&port_switchdev_nb); err_switchdev_nb: unregister_netdevice_notifier(&port_nb); return err; @@ -1123,7 +1172,7 @@ static int ethsw_open(struct ethsw_core *ethsw) for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { port_priv = ethsw->ports[i]; - err = dev_open(port_priv->netdev); + err = dev_open(port_priv->netdev, NULL); if (err) { netdev_err(port_priv->netdev, "dev_open err %d\n", err); return err; @@ -1291,8 +1340,15 @@ static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port) static void ethsw_unregister_notifier(struct device *dev) { + struct notifier_block *nb; int err; + nb = &port_switchdev_blocking_nb; + err = unregister_switchdev_blocking_notifier(nb); + if (err) + dev_err(dev, + "Failed to unregister switchdev blocking notifier (%d)\n", err); + err = unregister_switchdev_notifier(&port_switchdev_nb); if (err) dev_err(dev, diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index b3620a8f2d9f..19cadd17e542 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -31,10 +31,14 @@ source "drivers/staging/media/mt9t031/Kconfig" source "drivers/staging/media/omap4iss/Kconfig" +source "drivers/staging/media/rockchip/vpu/Kconfig" + source "drivers/staging/media/sunxi/Kconfig" 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 42948f805548..edde1960b030 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -8,3 +8,5 @@ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ 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/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c index fe87d0a90687..d9b02ff66259 100644 --- a/drivers/staging/media/bcm2048/radio-bcm2048.c +++ b/drivers/staging/media/bcm2048/radio-bcm2048.c @@ -2575,8 +2575,7 @@ static const struct video_device bcm2048_viddev_template = { /* * I2C driver interface */ -static int bcm2048_i2c_driver_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int bcm2048_i2c_driver_probe(struct i2c_client *client) { struct bcm2048_device *bdev; int err; @@ -2680,7 +2679,7 @@ static struct i2c_driver bcm2048_i2c_driver = { .driver = { .name = BCM2048_DRIVER_NAME, }, - .probe = bcm2048_i2c_driver_probe, + .probe_new = bcm2048_i2c_driver_probe, .remove = bcm2048_i2c_driver_remove, .id_table = bcm2048_id, }; diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c index b2e840f96c50..a01327f6e045 100644 --- a/drivers/staging/media/imx/imx-media-of.c +++ b/drivers/staging/media/imx/imx-media-of.c @@ -162,7 +162,7 @@ int imx_media_create_csi_of_links(struct imx_media_dev *imxmd, fwnode_property_read_u32(fwnode, "reg", &link.remote_port); fwnode = fwnode_get_next_parent(fwnode); if (is_of_node(fwnode) && - of_node_cmp(to_of_node(fwnode)->name, "ports") == 0) + of_node_name_eq(to_of_node(fwnode), "ports")) fwnode = fwnode_get_next_parent(fwnode); link.remote_node = fwnode; 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/drivers/staging/media/rockchip/vpu/Kconfig b/drivers/staging/media/rockchip/vpu/Kconfig new file mode 100644 index 000000000000..9a6fc1378242 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/Kconfig @@ -0,0 +1,13 @@ +config VIDEO_ROCKCHIP_VPU + tristate "Rockchip VPU driver" + depends on ARCH_ROCKCHIP || COMPILE_TEST + depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER + select VIDEOBUF2_DMA_CONTIG + select VIDEOBUF2_VMALLOC + select V4L2_MEM2MEM_DEV + default n + help + Support for the Video Processing Unit present on Rockchip SoC, + which accelerates video and image encoding and decoding. + To compile this driver as a module, choose M here: the module + will be called rockchip-vpu. diff --git a/drivers/staging/media/rockchip/vpu/Makefile b/drivers/staging/media/rockchip/vpu/Makefile new file mode 100644 index 000000000000..e9d733bb7632 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/Makefile @@ -0,0 +1,10 @@ +obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip-vpu.o + +rockchip-vpu-y += \ + rockchip_vpu_drv.o \ + rockchip_vpu_enc.o \ + rk3288_vpu_hw.o \ + rk3288_vpu_hw_jpeg_enc.o \ + rk3399_vpu_hw.o \ + rk3399_vpu_hw_jpeg_enc.o \ + rockchip_vpu_jpeg.o diff --git a/drivers/staging/media/rockchip/vpu/TODO b/drivers/staging/media/rockchip/vpu/TODO new file mode 100644 index 000000000000..fa0c94057007 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/TODO @@ -0,0 +1,13 @@ +* Support for VP8, VP9 and H264 is planned for this driver. + + Given the V4L controls for those CODECs will be part of + the uABI, it will be required to have the driver in staging. + + For this reason, we are keeping this driver in staging for now. + +* Add support for the S_SELECTION API. + See the comment for VEPU_REG_ENC_OVER_FILL_STRM_OFFSET. + +* Instead of having a DMA bounce buffer, it could be possible to use a + normal buffer and memmove() the payload to make space for the header. + This might need to use extra JPEG markers for padding reasons. diff --git a/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw.c b/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw.c new file mode 100644 index 000000000000..a5e9d183fffd --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip VPU codec driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Jeffy Chen <jeffy.chen@rock-chips.com> + */ + +#include <linux/clk.h> + +#include "rockchip_vpu.h" +#include "rockchip_vpu_jpeg.h" +#include "rk3288_vpu_regs.h" + +#define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000) + +/* + * Supported formats. + */ + +static const struct rockchip_vpu_fmt rk3288_vpu_enc_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_YUV420M, + .codec_mode = RK_VPU_MODE_NONE, + .enc_fmt = RK3288_VPU_ENC_FMT_YUV420P, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .codec_mode = RK_VPU_MODE_NONE, + .enc_fmt = RK3288_VPU_ENC_FMT_YUV420SP, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .codec_mode = RK_VPU_MODE_NONE, + .enc_fmt = RK3288_VPU_ENC_FMT_YUYV422, + }, + { + .fourcc = V4L2_PIX_FMT_UYVY, + .codec_mode = RK_VPU_MODE_NONE, + .enc_fmt = RK3288_VPU_ENC_FMT_UYVY422, + }, + { + .fourcc = V4L2_PIX_FMT_JPEG, + .codec_mode = RK_VPU_MODE_JPEG_ENC, + .max_depth = 2, + .header_size = JPEG_HEADER_SIZE, + .frmsize = { + .min_width = 96, + .max_width = 8192, + .step_width = JPEG_MB_DIM, + .min_height = 32, + .max_height = 8192, + .step_height = JPEG_MB_DIM, + }, + }, +}; + +static irqreturn_t rk3288_vepu_irq(int irq, void *dev_id) +{ + struct rockchip_vpu_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status, bytesused; + + status = vepu_read(vpu, VEPU_REG_INTERRUPT); + bytesused = vepu_read(vpu, VEPU_REG_STR_BUF_LIMIT) / 8; + state = (status & VEPU_REG_INTERRUPT_FRAME_RDY) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vepu_write(vpu, 0, VEPU_REG_INTERRUPT); + vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); + + rockchip_vpu_irq_done(vpu, bytesused, state); + + return IRQ_HANDLED; +} + +static int rk3288_vpu_hw_init(struct rockchip_vpu_dev *vpu) +{ + /* Bump ACLK to max. possible freq. to improve performance. */ + clk_set_rate(vpu->clocks[0].clk, RK3288_ACLK_MAX_FREQ); + return 0; +} + +static void rk3288_vpu_enc_reset(struct rockchip_vpu_ctx *ctx) +{ + struct rockchip_vpu_dev *vpu = ctx->dev; + + vepu_write(vpu, VEPU_REG_INTERRUPT_DIS_BIT, VEPU_REG_INTERRUPT); + vepu_write(vpu, 0, VEPU_REG_ENC_CTRL); + vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); +} + +/* + * Supported codec ops. + */ + +static const struct rockchip_vpu_codec_ops rk3288_vpu_codec_ops[] = { + [RK_VPU_MODE_JPEG_ENC] = { + .run = rk3288_vpu_jpeg_enc_run, + .reset = rk3288_vpu_enc_reset, + }, +}; + +/* + * VPU variant. + */ + +const struct rockchip_vpu_variant rk3288_vpu_variant = { + .enc_offset = 0x0, + .enc_fmts = rk3288_vpu_enc_fmts, + .num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts), + .codec_ops = rk3288_vpu_codec_ops, + .codec = RK_VPU_CODEC_JPEG, + .vepu_irq = rk3288_vepu_irq, + .init = rk3288_vpu_hw_init, + .clk_names = {"aclk", "hclk"}, + .num_clocks = 2 +}; diff --git a/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw_jpeg_enc.c b/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw_jpeg_enc.c new file mode 100644 index 000000000000..5282236d1bb1 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rk3288_vpu_hw_jpeg_enc.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip VPU codec driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + */ + +#include <asm/unaligned.h> +#include <media/v4l2-mem2mem.h> +#include "rockchip_vpu_jpeg.h" +#include "rockchip_vpu.h" +#include "rockchip_vpu_common.h" +#include "rockchip_vpu_hw.h" +#include "rk3288_vpu_regs.h" + +#define VEPU_JPEG_QUANT_TABLE_COUNT 16 + +static void rk3288_vpu_set_src_img_ctrl(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx) +{ + struct v4l2_pix_format_mplane *pix_fmt = &ctx->src_fmt; + u32 reg; + + reg = VEPU_REG_IN_IMG_CTRL_ROW_LEN(pix_fmt->width) + | VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(0) + | VEPU_REG_IN_IMG_CTRL_OVRFLB_D4(0) + | VEPU_REG_IN_IMG_CTRL_FMT(ctx->vpu_src_fmt->enc_fmt); + vepu_write_relaxed(vpu, reg, VEPU_REG_IN_IMG_CTRL); +} + +static void rk3288_vpu_jpeg_enc_set_buffers(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx, + struct vb2_buffer *src_buf) +{ + struct v4l2_pix_format_mplane *pix_fmt = &ctx->src_fmt; + dma_addr_t src[3]; + + WARN_ON(pix_fmt->num_planes > 3); + + vepu_write_relaxed(vpu, ctx->bounce_dma_addr, + VEPU_REG_ADDR_OUTPUT_STREAM); + vepu_write_relaxed(vpu, ctx->bounce_size, + VEPU_REG_STR_BUF_LIMIT); + + if (pix_fmt->num_planes == 1) { + src[0] = vb2_dma_contig_plane_dma_addr(src_buf, 0); + /* single plane formats we supported are all interlaced */ + vepu_write_relaxed(vpu, src[0], VEPU_REG_ADDR_IN_PLANE_0); + } else if (pix_fmt->num_planes == 2) { + src[0] = vb2_dma_contig_plane_dma_addr(src_buf, 0); + src[1] = vb2_dma_contig_plane_dma_addr(src_buf, 1); + vepu_write_relaxed(vpu, src[0], VEPU_REG_ADDR_IN_PLANE_0); + vepu_write_relaxed(vpu, src[1], VEPU_REG_ADDR_IN_PLANE_1); + } else { + src[0] = vb2_dma_contig_plane_dma_addr(src_buf, 0); + src[1] = vb2_dma_contig_plane_dma_addr(src_buf, 1); + src[2] = vb2_dma_contig_plane_dma_addr(src_buf, 2); + vepu_write_relaxed(vpu, src[0], VEPU_REG_ADDR_IN_PLANE_0); + vepu_write_relaxed(vpu, src[1], VEPU_REG_ADDR_IN_PLANE_1); + vepu_write_relaxed(vpu, src[2], VEPU_REG_ADDR_IN_PLANE_2); + } +} + +static void +rk3288_vpu_jpeg_enc_set_qtable(struct rockchip_vpu_dev *vpu, + unsigned char *luma_qtable, + unsigned char *chroma_qtable) +{ + u32 reg, i; + + for (i = 0; i < VEPU_JPEG_QUANT_TABLE_COUNT; i++) { + reg = get_unaligned_be32(&luma_qtable[i]); + vepu_write_relaxed(vpu, reg, VEPU_REG_JPEG_LUMA_QUAT(i)); + + reg = get_unaligned_be32(&chroma_qtable[i]); + vepu_write_relaxed(vpu, reg, VEPU_REG_JPEG_CHROMA_QUAT(i)); + } +} + +void rk3288_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx) +{ + struct rockchip_vpu_dev *vpu = ctx->dev; + struct vb2_buffer *src_buf, *dst_buf; + struct rockchip_vpu_jpeg_ctx jpeg_ctx; + u32 reg; + + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + + memset(&jpeg_ctx, 0, sizeof(jpeg_ctx)); + jpeg_ctx.buffer = vb2_plane_vaddr(dst_buf, 0); + jpeg_ctx.width = ctx->dst_fmt.width; + jpeg_ctx.height = ctx->dst_fmt.height; + jpeg_ctx.quality = ctx->jpeg_quality; + rockchip_vpu_jpeg_header_assemble(&jpeg_ctx); + + /* Switch to JPEG encoder mode before writing registers */ + vepu_write_relaxed(vpu, VEPU_REG_ENC_CTRL_ENC_MODE_JPEG, + VEPU_REG_ENC_CTRL); + + rk3288_vpu_set_src_img_ctrl(vpu, ctx); + rk3288_vpu_jpeg_enc_set_buffers(vpu, ctx, src_buf); + rk3288_vpu_jpeg_enc_set_qtable(vpu, + rockchip_vpu_jpeg_get_qtable(&jpeg_ctx, 0), + rockchip_vpu_jpeg_get_qtable(&jpeg_ctx, 1)); + + reg = VEPU_REG_AXI_CTRL_OUTPUT_SWAP16 + | VEPU_REG_AXI_CTRL_INPUT_SWAP16 + | VEPU_REG_AXI_CTRL_BURST_LEN(16) + | VEPU_REG_AXI_CTRL_OUTPUT_SWAP32 + | VEPU_REG_AXI_CTRL_INPUT_SWAP32 + | VEPU_REG_AXI_CTRL_OUTPUT_SWAP8 + | VEPU_REG_AXI_CTRL_INPUT_SWAP8; + /* Make sure that all registers are written at this point. */ + vepu_write(vpu, reg, VEPU_REG_AXI_CTRL); + + reg = VEPU_REG_ENC_CTRL_WIDTH(JPEG_MB_WIDTH(ctx->src_fmt.width)) + | VEPU_REG_ENC_CTRL_HEIGHT(JPEG_MB_HEIGHT(ctx->src_fmt.height)) + | VEPU_REG_ENC_CTRL_ENC_MODE_JPEG + | VEPU_REG_ENC_PIC_INTRA + | VEPU_REG_ENC_CTRL_EN_BIT; + /* Kick the watchdog and start encoding */ + schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000)); + vepu_write(vpu, reg, VEPU_REG_ENC_CTRL); +} diff --git a/drivers/staging/media/rockchip/vpu/rk3288_vpu_regs.h b/drivers/staging/media/rockchip/vpu/rk3288_vpu_regs.h new file mode 100644 index 000000000000..9d0b9bdf3297 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rk3288_vpu_regs.h @@ -0,0 +1,442 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip VPU codec driver + * + * Copyright 2018 Google LLC. + * Tomasz Figa <tfiga@chromium.org> + */ + +#ifndef RK3288_VPU_REGS_H_ +#define RK3288_VPU_REGS_H_ + +/* Encoder registers. */ +#define VEPU_REG_INTERRUPT 0x004 +#define VEPU_REG_INTERRUPT_FRAME_RDY BIT(2) +#define VEPU_REG_INTERRUPT_DIS_BIT BIT(1) +#define VEPU_REG_INTERRUPT_BIT BIT(0) +#define VEPU_REG_AXI_CTRL 0x008 +#define VEPU_REG_AXI_CTRL_OUTPUT_SWAP16 BIT(15) +#define VEPU_REG_AXI_CTRL_INPUT_SWAP16 BIT(14) +#define VEPU_REG_AXI_CTRL_BURST_LEN(x) ((x) << 8) +#define VEPU_REG_AXI_CTRL_GATE_BIT BIT(4) +#define VEPU_REG_AXI_CTRL_OUTPUT_SWAP32 BIT(3) +#define VEPU_REG_AXI_CTRL_INPUT_SWAP32 BIT(2) +#define VEPU_REG_AXI_CTRL_OUTPUT_SWAP8 BIT(1) +#define VEPU_REG_AXI_CTRL_INPUT_SWAP8 BIT(0) +#define VEPU_REG_ADDR_OUTPUT_STREAM 0x014 +#define VEPU_REG_ADDR_OUTPUT_CTRL 0x018 +#define VEPU_REG_ADDR_REF_LUMA 0x01c +#define VEPU_REG_ADDR_REF_CHROMA 0x020 +#define VEPU_REG_ADDR_REC_LUMA 0x024 +#define VEPU_REG_ADDR_REC_CHROMA 0x028 +#define VEPU_REG_ADDR_IN_PLANE_0 0x02c +#define VEPU_REG_ADDR_IN_PLANE_1 0x030 +#define VEPU_REG_ADDR_IN_PLANE_2 0x034 +#define VEPU_REG_ENC_CTRL 0x038 +#define VEPU_REG_ENC_CTRL_TIMEOUT_EN BIT(31) +#define VEPU_REG_ENC_CTRL_NAL_MODE_BIT BIT(29) +#define VEPU_REG_ENC_CTRL_WIDTH(w) ((w) << 19) +#define VEPU_REG_ENC_CTRL_HEIGHT(h) ((h) << 10) +#define VEPU_REG_ENC_PIC_INTER (0x0 << 3) +#define VEPU_REG_ENC_PIC_INTRA (0x1 << 3) +#define VEPU_REG_ENC_PIC_MVCINTER (0x2 << 3) +#define VEPU_REG_ENC_CTRL_ENC_MODE_H264 (0x3 << 1) +#define VEPU_REG_ENC_CTRL_ENC_MODE_JPEG (0x2 << 1) +#define VEPU_REG_ENC_CTRL_ENC_MODE_VP8 (0x1 << 1) +#define VEPU_REG_ENC_CTRL_EN_BIT BIT(0) +#define VEPU_REG_IN_IMG_CTRL 0x03c +#define VEPU_REG_IN_IMG_CTRL_ROW_LEN(x) ((x) << 12) +#define VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(x) ((x) << 10) +#define VEPU_REG_IN_IMG_CTRL_OVRFLB_D4(x) ((x) << 6) +#define VEPU_REG_IN_IMG_CTRL_FMT(x) ((x) << 2) +#define VEPU_REG_ENC_CTRL0 0x040 +#define VEPU_REG_ENC_CTRL0_INIT_QP(x) ((x) << 26) +#define VEPU_REG_ENC_CTRL0_SLICE_ALPHA(x) ((x) << 22) +#define VEPU_REG_ENC_CTRL0_SLICE_BETA(x) ((x) << 18) +#define VEPU_REG_ENC_CTRL0_CHROMA_QP_OFFSET(x) ((x) << 13) +#define VEPU_REG_ENC_CTRL0_FILTER_DIS(x) ((x) << 5) +#define VEPU_REG_ENC_CTRL0_IDR_PICID(x) ((x) << 1) +#define VEPU_REG_ENC_CTRL0_CONSTR_INTRA_PRED BIT(0) +#define VEPU_REG_ENC_CTRL1 0x044 +#define VEPU_REG_ENC_CTRL1_PPS_ID(x) ((x) << 24) +#define VEPU_REG_ENC_CTRL1_INTRA_PRED_MODE(x) ((x) << 16) +#define VEPU_REG_ENC_CTRL1_FRAME_NUM(x) ((x)) +#define VEPU_REG_ENC_CTRL2 0x048 +#define VEPU_REG_ENC_CTRL2_DEBLOCKING_FILETER_MODE(x) ((x) << 30) +#define VEPU_REG_ENC_CTRL2_H264_SLICE_SIZE(x) ((x) << 23) +#define VEPU_REG_ENC_CTRL2_DISABLE_QUARTER_PIXMV BIT(22) +#define VEPU_REG_ENC_CTRL2_TRANS8X8_MODE_EN BIT(21) +#define VEPU_REG_ENC_CTRL2_CABAC_INIT_IDC(x) ((x) << 19) +#define VEPU_REG_ENC_CTRL2_ENTROPY_CODING_MODE BIT(18) +#define VEPU_REG_ENC_CTRL2_H264_INTER4X4_MODE BIT(17) +#define VEPU_REG_ENC_CTRL2_H264_STREAM_MODE BIT(16) +#define VEPU_REG_ENC_CTRL2_INTRA16X16_MODE(x) ((x)) +#define VEPU_REG_ENC_CTRL3 0x04c +#define VEPU_REG_ENC_CTRL3_MUTIMV_EN BIT(30) +#define VEPU_REG_ENC_CTRL3_MV_PENALTY_1_4P(x) ((x) << 20) +#define VEPU_REG_ENC_CTRL3_MV_PENALTY_4P(x) ((x) << 10) +#define VEPU_REG_ENC_CTRL3_MV_PENALTY_1P(x) ((x)) +#define VEPU_REG_ENC_CTRL4 0x050 +#define VEPU_REG_ENC_CTRL4_MV_PENALTY_16X8_8X16(x) ((x) << 20) +#define VEPU_REG_ENC_CTRL4_MV_PENALTY_8X8(x) ((x) << 10) +#define VEPU_REG_ENC_CTRL4_8X4_4X8(x) ((x)) +#define VEPU_REG_ENC_CTRL5 0x054 +#define VEPU_REG_ENC_CTRL5_MACROBLOCK_PENALTY(x) ((x) << 24) +#define VEPU_REG_ENC_CTRL5_COMPLETE_SLICES(x) ((x) << 16) +#define VEPU_REG_ENC_CTRL5_INTER_MODE(x) ((x)) +#define VEPU_REG_STR_HDR_REM_MSB 0x058 +#define VEPU_REG_STR_HDR_REM_LSB 0x05c +#define VEPU_REG_STR_BUF_LIMIT 0x060 +#define VEPU_REG_MAD_CTRL 0x064 +#define VEPU_REG_MAD_CTRL_QP_ADJUST(x) ((x) << 28) +#define VEPU_REG_MAD_CTRL_MAD_THREDHOLD(x) ((x) << 22) +#define VEPU_REG_MAD_CTRL_QP_SUM_DIV2(x) ((x)) +#define VEPU_REG_ADDR_VP8_PROB_CNT 0x068 +#define VEPU_REG_QP_VAL 0x06c +#define VEPU_REG_QP_VAL_LUM(x) ((x) << 26) +#define VEPU_REG_QP_VAL_MAX(x) ((x) << 20) +#define VEPU_REG_QP_VAL_MIN(x) ((x) << 14) +#define VEPU_REG_QP_VAL_CHECKPOINT_DISTAN(x) ((x)) +#define VEPU_REG_VP8_QP_VAL(i) (0x06c + ((i) * 0x4)) +#define VEPU_REG_CHECKPOINT(i) (0x070 + ((i) * 0x4)) +#define VEPU_REG_CHECKPOINT_CHECK0(x) (((x) & 0xffff)) +#define VEPU_REG_CHECKPOINT_CHECK1(x) (((x) & 0xffff) << 16) +#define VEPU_REG_CHECKPOINT_RESULT(x) ((((x) >> (16 - 16 \ + * (i & 1))) & 0xffff) \ + * 32) +#define VEPU_REG_CHKPT_WORD_ERR(i) (0x084 + ((i) * 0x4)) +#define VEPU_REG_CHKPT_WORD_ERR_CHK0(x) (((x) & 0xffff)) +#define VEPU_REG_CHKPT_WORD_ERR_CHK1(x) (((x) & 0xffff) << 16) +#define VEPU_REG_VP8_BOOL_ENC 0x08c +#define VEPU_REG_CHKPT_DELTA_QP 0x090 +#define VEPU_REG_CHKPT_DELTA_QP_CHK0(x) (((x) & 0x0f) << 0) +#define VEPU_REG_CHKPT_DELTA_QP_CHK1(x) (((x) & 0x0f) << 4) +#define VEPU_REG_CHKPT_DELTA_QP_CHK2(x) (((x) & 0x0f) << 8) +#define VEPU_REG_CHKPT_DELTA_QP_CHK3(x) (((x) & 0x0f) << 12) +#define VEPU_REG_CHKPT_DELTA_QP_CHK4(x) (((x) & 0x0f) << 16) +#define VEPU_REG_CHKPT_DELTA_QP_CHK5(x) (((x) & 0x0f) << 20) +#define VEPU_REG_CHKPT_DELTA_QP_CHK6(x) (((x) & 0x0f) << 24) +#define VEPU_REG_VP8_CTRL0 0x090 +#define VEPU_REG_RLC_CTRL 0x094 +#define VEPU_REG_RLC_CTRL_STR_OFFS_SHIFT 23 +#define VEPU_REG_RLC_CTRL_STR_OFFS_MASK (0x3f << 23) +#define VEPU_REG_RLC_CTRL_RLC_SUM(x) ((x)) +#define VEPU_REG_MB_CTRL 0x098 +#define VEPU_REG_MB_CNT_OUT(x) (((x) & 0xffff)) +#define VEPU_REG_MB_CNT_SET(x) (((x) & 0xffff) << 16) +#define VEPU_REG_ADDR_NEXT_PIC 0x09c +#define VEPU_REG_JPEG_LUMA_QUAT(i) (0x100 + ((i) * 0x4)) +#define VEPU_REG_JPEG_CHROMA_QUAT(i) (0x140 + ((i) * 0x4)) +#define VEPU_REG_STABILIZATION_OUTPUT 0x0A0 +#define VEPU_REG_ADDR_CABAC_TBL 0x0cc +#define VEPU_REG_ADDR_MV_OUT 0x0d0 +#define VEPU_REG_RGB_YUV_COEFF(i) (0x0d4 + ((i) * 0x4)) +#define VEPU_REG_RGB_MASK_MSB 0x0dc +#define VEPU_REG_INTRA_AREA_CTRL 0x0e0 +#define VEPU_REG_CIR_INTRA_CTRL 0x0e4 +#define VEPU_REG_INTRA_SLICE_BITMAP(i) (0x0e8 + ((i) * 0x4)) +#define VEPU_REG_ADDR_VP8_DCT_PART(i) (0x0e8 + ((i) * 0x4)) +#define VEPU_REG_FIRST_ROI_AREA 0x0f0 +#define VEPU_REG_SECOND_ROI_AREA 0x0f4 +#define VEPU_REG_MVC_CTRL 0x0f8 +#define VEPU_REG_MVC_CTRL_MV16X16_FAVOR(x) ((x) << 28) +#define VEPU_REG_VP8_INTRA_PENALTY(i) (0x100 + ((i) * 0x4)) +#define VEPU_REG_ADDR_VP8_SEG_MAP 0x11c +#define VEPU_REG_VP8_SEG_QP(i) (0x120 + ((i) * 0x4)) +#define VEPU_REG_DMV_4P_1P_PENALTY(i) (0x180 + ((i) * 0x4)) +#define VEPU_REG_DMV_4P_1P_PENALTY_BIT(x, i) ((x) << (i) * 8) +#define VEPU_REG_DMV_QPEL_PENALTY(i) (0x200 + ((i) * 0x4)) +#define VEPU_REG_DMV_QPEL_PENALTY_BIT(x, i) ((x) << (i) * 8) +#define VEPU_REG_VP8_CTRL1 0x280 +#define VEPU_REG_VP8_BIT_COST_GOLDEN 0x284 +#define VEPU_REG_VP8_LOOP_FLT_DELTA(i) (0x288 + ((i) * 0x4)) + +/* Decoder registers. */ +#define VDPU_REG_INTERRUPT 0x004 +#define VDPU_REG_INTERRUPT_DEC_PIC_INF BIT(24) +#define VDPU_REG_INTERRUPT_DEC_TIMEOUT BIT(18) +#define VDPU_REG_INTERRUPT_DEC_SLICE_INT BIT(17) +#define VDPU_REG_INTERRUPT_DEC_ERROR_INT BIT(16) +#define VDPU_REG_INTERRUPT_DEC_ASO_INT BIT(15) +#define VDPU_REG_INTERRUPT_DEC_BUFFER_INT BIT(14) +#define VDPU_REG_INTERRUPT_DEC_BUS_INT BIT(13) +#define VDPU_REG_INTERRUPT_DEC_RDY_INT BIT(12) +#define VDPU_REG_INTERRUPT_DEC_IRQ BIT(8) +#define VDPU_REG_INTERRUPT_DEC_IRQ_DIS BIT(4) +#define VDPU_REG_INTERRUPT_DEC_E BIT(0) +#define VDPU_REG_CONFIG 0x008 +#define VDPU_REG_CONFIG_DEC_AXI_RD_ID(x) (((x) & 0xff) << 24) +#define VDPU_REG_CONFIG_DEC_TIMEOUT_E BIT(23) +#define VDPU_REG_CONFIG_DEC_STRSWAP32_E BIT(22) +#define VDPU_REG_CONFIG_DEC_STRENDIAN_E BIT(21) +#define VDPU_REG_CONFIG_DEC_INSWAP32_E BIT(20) +#define VDPU_REG_CONFIG_DEC_OUTSWAP32_E BIT(19) +#define VDPU_REG_CONFIG_DEC_DATA_DISC_E BIT(18) +#define VDPU_REG_CONFIG_TILED_MODE_MSB BIT(17) +#define VDPU_REG_CONFIG_DEC_OUT_TILED_E BIT(17) +#define VDPU_REG_CONFIG_DEC_LATENCY(x) (((x) & 0x3f) << 11) +#define VDPU_REG_CONFIG_DEC_CLK_GATE_E BIT(10) +#define VDPU_REG_CONFIG_DEC_IN_ENDIAN BIT(9) +#define VDPU_REG_CONFIG_DEC_OUT_ENDIAN BIT(8) +#define VDPU_REG_CONFIG_PRIORITY_MODE(x) (((x) & 0x7) << 5) +#define VDPU_REG_CONFIG_TILED_MODE_LSB BIT(7) +#define VDPU_REG_CONFIG_DEC_ADV_PRE_DIS BIT(6) +#define VDPU_REG_CONFIG_DEC_SCMD_DIS BIT(5) +#define VDPU_REG_CONFIG_DEC_MAX_BURST(x) (((x) & 0x1f) << 0) +#define VDPU_REG_DEC_CTRL0 0x00c +#define VDPU_REG_DEC_CTRL0_DEC_MODE(x) (((x) & 0xf) << 28) +#define VDPU_REG_DEC_CTRL0_RLC_MODE_E BIT(27) +#define VDPU_REG_DEC_CTRL0_SKIP_MODE BIT(26) +#define VDPU_REG_DEC_CTRL0_DIVX3_E BIT(25) +#define VDPU_REG_DEC_CTRL0_PJPEG_E BIT(24) +#define VDPU_REG_DEC_CTRL0_PIC_INTERLACE_E BIT(23) +#define VDPU_REG_DEC_CTRL0_PIC_FIELDMODE_E BIT(22) +#define VDPU_REG_DEC_CTRL0_PIC_B_E BIT(21) +#define VDPU_REG_DEC_CTRL0_PIC_INTER_E BIT(20) +#define VDPU_REG_DEC_CTRL0_PIC_TOPFIELD_E BIT(19) +#define VDPU_REG_DEC_CTRL0_FWD_INTERLACE_E BIT(18) +#define VDPU_REG_DEC_CTRL0_SORENSON_E BIT(17) +#define VDPU_REG_DEC_CTRL0_REF_TOPFIELD_E BIT(16) +#define VDPU_REG_DEC_CTRL0_DEC_OUT_DIS BIT(15) +#define VDPU_REG_DEC_CTRL0_FILTERING_DIS BIT(14) +#define VDPU_REG_DEC_CTRL0_WEBP_E BIT(13) +#define VDPU_REG_DEC_CTRL0_MVC_E BIT(13) +#define VDPU_REG_DEC_CTRL0_PIC_FIXED_QUANT BIT(13) +#define VDPU_REG_DEC_CTRL0_WRITE_MVS_E BIT(12) +#define VDPU_REG_DEC_CTRL0_REFTOPFIRST_E BIT(11) +#define VDPU_REG_DEC_CTRL0_SEQ_MBAFF_E BIT(10) +#define VDPU_REG_DEC_CTRL0_PICORD_COUNT_E BIT(9) +#define VDPU_REG_DEC_CTRL0_DEC_AHB_HLOCK_E BIT(8) +#define VDPU_REG_DEC_CTRL0_DEC_AXI_WR_ID(x) (((x) & 0xff) << 0) +#define VDPU_REG_DEC_CTRL1 0x010 +#define VDPU_REG_DEC_CTRL1_PIC_MB_WIDTH(x) (((x) & 0x1ff) << 23) +#define VDPU_REG_DEC_CTRL1_MB_WIDTH_OFF(x) (((x) & 0xf) << 19) +#define VDPU_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(x) (((x) & 0xff) << 11) +#define VDPU_REG_DEC_CTRL1_MB_HEIGHT_OFF(x) (((x) & 0xf) << 7) +#define VDPU_REG_DEC_CTRL1_ALT_SCAN_E BIT(6) +#define VDPU_REG_DEC_CTRL1_TOPFIELDFIRST_E BIT(5) +#define VDPU_REG_DEC_CTRL1_REF_FRAMES(x) (((x) & 0x1f) << 0) +#define VDPU_REG_DEC_CTRL1_PIC_MB_W_EXT(x) (((x) & 0x7) << 3) +#define VDPU_REG_DEC_CTRL1_PIC_MB_H_EXT(x) (((x) & 0x7) << 0) +#define VDPU_REG_DEC_CTRL1_PIC_REFER_FLAG BIT(0) +#define VDPU_REG_DEC_CTRL2 0x014 +#define VDPU_REG_DEC_CTRL2_STRM_START_BIT(x) (((x) & 0x3f) << 26) +#define VDPU_REG_DEC_CTRL2_SYNC_MARKER_E BIT(25) +#define VDPU_REG_DEC_CTRL2_TYPE1_QUANT_E BIT(24) +#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET(x) (((x) & 0x1f) << 19) +#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET2(x) (((x) & 0x1f) << 14) +#define VDPU_REG_DEC_CTRL2_FIELDPIC_FLAG_E BIT(0) +#define VDPU_REG_DEC_CTRL2_INTRADC_VLC_THR(x) (((x) & 0x7) << 16) +#define VDPU_REG_DEC_CTRL2_VOP_TIME_INCR(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL2_DQ_PROFILE BIT(24) +#define VDPU_REG_DEC_CTRL2_DQBI_LEVEL BIT(23) +#define VDPU_REG_DEC_CTRL2_RANGE_RED_FRM_E BIT(22) +#define VDPU_REG_DEC_CTRL2_FAST_UVMC_E BIT(20) +#define VDPU_REG_DEC_CTRL2_TRANSDCTAB BIT(17) +#define VDPU_REG_DEC_CTRL2_TRANSACFRM(x) (((x) & 0x3) << 15) +#define VDPU_REG_DEC_CTRL2_TRANSACFRM2(x) (((x) & 0x3) << 13) +#define VDPU_REG_DEC_CTRL2_MB_MODE_TAB(x) (((x) & 0x7) << 10) +#define VDPU_REG_DEC_CTRL2_MVTAB(x) (((x) & 0x7) << 7) +#define VDPU_REG_DEC_CTRL2_CBPTAB(x) (((x) & 0x7) << 4) +#define VDPU_REG_DEC_CTRL2_2MV_BLK_PAT_TAB(x) (((x) & 0x3) << 2) +#define VDPU_REG_DEC_CTRL2_4MV_BLK_PAT_TAB(x) (((x) & 0x3) << 0) +#define VDPU_REG_DEC_CTRL2_QSCALE_TYPE BIT(24) +#define VDPU_REG_DEC_CTRL2_CON_MV_E BIT(4) +#define VDPU_REG_DEC_CTRL2_INTRA_DC_PREC(x) (((x) & 0x3) << 2) +#define VDPU_REG_DEC_CTRL2_INTRA_VLC_TAB BIT(1) +#define VDPU_REG_DEC_CTRL2_FRAME_PRED_DCT BIT(0) +#define VDPU_REG_DEC_CTRL2_JPEG_QTABLES(x) (((x) & 0x3) << 11) +#define VDPU_REG_DEC_CTRL2_JPEG_MODE(x) (((x) & 0x7) << 8) +#define VDPU_REG_DEC_CTRL2_JPEG_FILRIGHT_E BIT(7) +#define VDPU_REG_DEC_CTRL2_JPEG_STREAM_ALL BIT(6) +#define VDPU_REG_DEC_CTRL2_CR_AC_VLCTABLE BIT(5) +#define VDPU_REG_DEC_CTRL2_CB_AC_VLCTABLE BIT(4) +#define VDPU_REG_DEC_CTRL2_CR_DC_VLCTABLE BIT(3) +#define VDPU_REG_DEC_CTRL2_CB_DC_VLCTABLE BIT(2) +#define VDPU_REG_DEC_CTRL2_CR_DC_VLCTABLE3 BIT(1) +#define VDPU_REG_DEC_CTRL2_CB_DC_VLCTABLE3 BIT(0) +#define VDPU_REG_DEC_CTRL2_STRM1_START_BIT(x) (((x) & 0x3f) << 18) +#define VDPU_REG_DEC_CTRL2_HUFFMAN_E BIT(17) +#define VDPU_REG_DEC_CTRL2_MULTISTREAM_E BIT(16) +#define VDPU_REG_DEC_CTRL2_BOOLEAN_VALUE(x) (((x) & 0xff) << 8) +#define VDPU_REG_DEC_CTRL2_BOOLEAN_RANGE(x) (((x) & 0xff) << 0) +#define VDPU_REG_DEC_CTRL2_ALPHA_OFFSET(x) (((x) & 0x1f) << 5) +#define VDPU_REG_DEC_CTRL2_BETA_OFFSET(x) (((x) & 0x1f) << 0) +#define VDPU_REG_DEC_CTRL3 0x018 +#define VDPU_REG_DEC_CTRL3_START_CODE_E BIT(31) +#define VDPU_REG_DEC_CTRL3_INIT_QP(x) (((x) & 0x3f) << 25) +#define VDPU_REG_DEC_CTRL3_CH_8PIX_ILEAV_E BIT(24) +#define VDPU_REG_DEC_CTRL3_STREAM_LEN_EXT(x) (((x) & 0xff) << 24) +#define VDPU_REG_DEC_CTRL3_STREAM_LEN(x) (((x) & 0xffffff) << 0) +#define VDPU_REG_DEC_CTRL4 0x01c +#define VDPU_REG_DEC_CTRL4_CABAC_E BIT(31) +#define VDPU_REG_DEC_CTRL4_BLACKWHITE_E BIT(30) +#define VDPU_REG_DEC_CTRL4_DIR_8X8_INFER_E BIT(29) +#define VDPU_REG_DEC_CTRL4_WEIGHT_PRED_E BIT(28) +#define VDPU_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(x) (((x) & 0x3) << 26) +#define VDPU_REG_DEC_CTRL4_AVS_H264_H_EXT BIT(25) +#define VDPU_REG_DEC_CTRL4_FRAMENUM_LEN(x) (((x) & 0x1f) << 16) +#define VDPU_REG_DEC_CTRL4_FRAMENUM(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL4_BITPLANE0_E BIT(31) +#define VDPU_REG_DEC_CTRL4_BITPLANE1_E BIT(30) +#define VDPU_REG_DEC_CTRL4_BITPLANE2_E BIT(29) +#define VDPU_REG_DEC_CTRL4_ALT_PQUANT(x) (((x) & 0x1f) << 24) +#define VDPU_REG_DEC_CTRL4_DQ_EDGES(x) (((x) & 0xf) << 20) +#define VDPU_REG_DEC_CTRL4_TTMBF BIT(19) +#define VDPU_REG_DEC_CTRL4_PQINDEX(x) (((x) & 0x1f) << 14) +#define VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT BIT(13) +#define VDPU_REG_DEC_CTRL4_BILIN_MC_E BIT(12) +#define VDPU_REG_DEC_CTRL4_UNIQP_E BIT(11) +#define VDPU_REG_DEC_CTRL4_HALFQP_E BIT(10) +#define VDPU_REG_DEC_CTRL4_TTFRM(x) (((x) & 0x3) << 8) +#define VDPU_REG_DEC_CTRL4_2ND_BYTE_EMUL_E BIT(7) +#define VDPU_REG_DEC_CTRL4_DQUANT_E BIT(6) +#define VDPU_REG_DEC_CTRL4_VC1_ADV_E BIT(5) +#define VDPU_REG_DEC_CTRL4_PJPEG_FILDOWN_E BIT(26) +#define VDPU_REG_DEC_CTRL4_PJPEG_WDIV8 BIT(25) +#define VDPU_REG_DEC_CTRL4_PJPEG_HDIV8 BIT(24) +#define VDPU_REG_DEC_CTRL4_PJPEG_AH(x) (((x) & 0xf) << 20) +#define VDPU_REG_DEC_CTRL4_PJPEG_AL(x) (((x) & 0xf) << 16) +#define VDPU_REG_DEC_CTRL4_PJPEG_SS(x) (((x) & 0xff) << 8) +#define VDPU_REG_DEC_CTRL4_PJPEG_SE(x) (((x) & 0xff) << 0) +#define VDPU_REG_DEC_CTRL4_DCT1_START_BIT(x) (((x) & 0x3f) << 26) +#define VDPU_REG_DEC_CTRL4_DCT2_START_BIT(x) (((x) & 0x3f) << 20) +#define VDPU_REG_DEC_CTRL4_CH_MV_RES BIT(13) +#define VDPU_REG_DEC_CTRL4_INIT_DC_MATCH0(x) (((x) & 0x7) << 9) +#define VDPU_REG_DEC_CTRL4_INIT_DC_MATCH1(x) (((x) & 0x7) << 6) +#define VDPU_REG_DEC_CTRL4_VP7_VERSION BIT(5) +#define VDPU_REG_DEC_CTRL5 0x020 +#define VDPU_REG_DEC_CTRL5_CONST_INTRA_E BIT(31) +#define VDPU_REG_DEC_CTRL5_FILT_CTRL_PRES BIT(30) +#define VDPU_REG_DEC_CTRL5_RDPIC_CNT_PRES BIT(29) +#define VDPU_REG_DEC_CTRL5_8X8TRANS_FLAG_E BIT(28) +#define VDPU_REG_DEC_CTRL5_REFPIC_MK_LEN(x) (((x) & 0x7ff) << 17) +#define VDPU_REG_DEC_CTRL5_IDR_PIC_E BIT(16) +#define VDPU_REG_DEC_CTRL5_IDR_PIC_ID(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL5_MV_SCALEFACTOR(x) (((x) & 0xff) << 24) +#define VDPU_REG_DEC_CTRL5_REF_DIST_FWD(x) (((x) & 0x1f) << 19) +#define VDPU_REG_DEC_CTRL5_REF_DIST_BWD(x) (((x) & 0x1f) << 14) +#define VDPU_REG_DEC_CTRL5_LOOP_FILT_LIMIT(x) (((x) & 0xf) << 14) +#define VDPU_REG_DEC_CTRL5_VARIANCE_TEST_E BIT(13) +#define VDPU_REG_DEC_CTRL5_MV_THRESHOLD(x) (((x) & 0x7) << 10) +#define VDPU_REG_DEC_CTRL5_VAR_THRESHOLD(x) (((x) & 0x3ff) << 0) +#define VDPU_REG_DEC_CTRL5_DIVX_IDCT_E BIT(8) +#define VDPU_REG_DEC_CTRL5_DIVX3_SLICE_SIZE(x) (((x) & 0xff) << 0) +#define VDPU_REG_DEC_CTRL5_PJPEG_REST_FREQ(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL5_RV_PROFILE(x) (((x) & 0x3) << 30) +#define VDPU_REG_DEC_CTRL5_RV_OSV_QUANT(x) (((x) & 0x3) << 28) +#define VDPU_REG_DEC_CTRL5_RV_FWD_SCALE(x) (((x) & 0x3fff) << 14) +#define VDPU_REG_DEC_CTRL5_RV_BWD_SCALE(x) (((x) & 0x3fff) << 0) +#define VDPU_REG_DEC_CTRL5_INIT_DC_COMP0(x) (((x) & 0xffff) << 16) +#define VDPU_REG_DEC_CTRL5_INIT_DC_COMP1(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL6 0x024 +#define VDPU_REG_DEC_CTRL6_PPS_ID(x) (((x) & 0xff) << 24) +#define VDPU_REG_DEC_CTRL6_REFIDX1_ACTIVE(x) (((x) & 0x1f) << 19) +#define VDPU_REG_DEC_CTRL6_REFIDX0_ACTIVE(x) (((x) & 0x1f) << 14) +#define VDPU_REG_DEC_CTRL6_POC_LENGTH(x) (((x) & 0xff) << 0) +#define VDPU_REG_DEC_CTRL6_ICOMP0_E BIT(24) +#define VDPU_REG_DEC_CTRL6_ISCALE0(x) (((x) & 0xff) << 16) +#define VDPU_REG_DEC_CTRL6_ISHIFT0(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL6_STREAM1_LEN(x) (((x) & 0xffffff) << 0) +#define VDPU_REG_DEC_CTRL6_PIC_SLICE_AM(x) (((x) & 0x1fff) << 0) +#define VDPU_REG_DEC_CTRL6_COEFFS_PART_AM(x) (((x) & 0xf) << 24) +#define VDPU_REG_FWD_PIC(i) (0x028 + ((i) * 0x4)) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F5(x) (((x) & 0x1f) << 25) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F4(x) (((x) & 0x1f) << 20) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_FWD_PIC1_ICOMP1_E BIT(24) +#define VDPU_REG_FWD_PIC1_ISCALE1(x) (((x) & 0xff) << 16) +#define VDPU_REG_FWD_PIC1_ISHIFT1(x) (((x) & 0xffff) << 0) +#define VDPU_REG_FWD_PIC1_SEGMENT_BASE(x) ((x) << 0) +#define VDPU_REG_FWD_PIC1_SEGMENT_UPD_E BIT(1) +#define VDPU_REG_FWD_PIC1_SEGMENT_E BIT(0) +#define VDPU_REG_DEC_CTRL7 0x02c +#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F15(x) (((x) & 0x1f) << 25) +#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F14(x) (((x) & 0x1f) << 20) +#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F13(x) (((x) & 0x1f) << 15) +#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F12(x) (((x) & 0x1f) << 10) +#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F11(x) (((x) & 0x1f) << 5) +#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F10(x) (((x) & 0x1f) << 0) +#define VDPU_REG_DEC_CTRL7_ICOMP2_E BIT(24) +#define VDPU_REG_DEC_CTRL7_ISCALE2(x) (((x) & 0xff) << 16) +#define VDPU_REG_DEC_CTRL7_ISHIFT2(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL7_DCT3_START_BIT(x) (((x) & 0x3f) << 24) +#define VDPU_REG_DEC_CTRL7_DCT4_START_BIT(x) (((x) & 0x3f) << 18) +#define VDPU_REG_DEC_CTRL7_DCT5_START_BIT(x) (((x) & 0x3f) << 12) +#define VDPU_REG_DEC_CTRL7_DCT6_START_BIT(x) (((x) & 0x3f) << 6) +#define VDPU_REG_DEC_CTRL7_DCT7_START_BIT(x) (((x) & 0x3f) << 0) +#define VDPU_REG_ADDR_STR 0x030 +#define VDPU_REG_ADDR_DST 0x034 +#define VDPU_REG_ADDR_REF(i) (0x038 + ((i) * 0x4)) +#define VDPU_REG_ADDR_REF_FIELD_E BIT(1) +#define VDPU_REG_ADDR_REF_TOPC_E BIT(0) +#define VDPU_REG_REF_PIC(i) (0x078 + ((i) * 0x4)) +#define VDPU_REG_REF_PIC_FILT_TYPE_E BIT(31) +#define VDPU_REG_REF_PIC_FILT_SHARPNESS(x) (((x) & 0x7) << 28) +#define VDPU_REG_REF_PIC_MB_ADJ_0(x) (((x) & 0x7f) << 21) +#define VDPU_REG_REF_PIC_MB_ADJ_1(x) (((x) & 0x7f) << 14) +#define VDPU_REG_REF_PIC_MB_ADJ_2(x) (((x) & 0x7f) << 7) +#define VDPU_REG_REF_PIC_MB_ADJ_3(x) (((x) & 0x7f) << 0) +#define VDPU_REG_REF_PIC_REFER1_NBR(x) (((x) & 0xffff) << 16) +#define VDPU_REG_REF_PIC_REFER0_NBR(x) (((x) & 0xffff) << 0) +#define VDPU_REG_REF_PIC_LF_LEVEL_0(x) (((x) & 0x3f) << 18) +#define VDPU_REG_REF_PIC_LF_LEVEL_1(x) (((x) & 0x3f) << 12) +#define VDPU_REG_REF_PIC_LF_LEVEL_2(x) (((x) & 0x3f) << 6) +#define VDPU_REG_REF_PIC_LF_LEVEL_3(x) (((x) & 0x3f) << 0) +#define VDPU_REG_REF_PIC_QUANT_DELTA_0(x) (((x) & 0x1f) << 27) +#define VDPU_REG_REF_PIC_QUANT_DELTA_1(x) (((x) & 0x1f) << 22) +#define VDPU_REG_REF_PIC_QUANT_0(x) (((x) & 0x7ff) << 11) +#define VDPU_REG_REF_PIC_QUANT_1(x) (((x) & 0x7ff) << 0) +#define VDPU_REG_LT_REF 0x098 +#define VDPU_REG_VALID_REF 0x09c +#define VDPU_REG_ADDR_QTABLE 0x0a0 +#define VDPU_REG_ADDR_DIR_MV 0x0a4 +#define VDPU_REG_BD_REF_PIC(i) (0x0a8 + ((i) * 0x4)) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B2(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F2(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B1(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F1(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B0(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_M1(x) (((x) & 0x3) << 10) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_4(x) (((x) & 0x3) << 8) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_M1(x) (((x) & 0x3) << 6) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_4(x) (((x) & 0x3) << 4) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_M1(x) (((x) & 0x3) << 2) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_4(x) (((x) & 0x3) << 0) +#define VDPU_REG_BD_REF_PIC_QUANT_DELTA_2(x) (((x) & 0x1f) << 27) +#define VDPU_REG_BD_REF_PIC_QUANT_DELTA_3(x) (((x) & 0x1f) << 22) +#define VDPU_REG_BD_REF_PIC_QUANT_2(x) (((x) & 0x7ff) << 11) +#define VDPU_REG_BD_REF_PIC_QUANT_3(x) (((x) & 0x7ff) << 0) +#define VDPU_REG_BD_P_REF_PIC 0x0bc +#define VDPU_REG_BD_P_REF_PIC_QUANT_DELTA_4(x) (((x) & 0x1f) << 27) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_P_REF_PIC_BINIT_RLIST_B15(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_P_REF_PIC_BINIT_RLIST_F15(x) (((x) & 0x1f) << 0) +#define VDPU_REG_ERR_CONC 0x0c0 +#define VDPU_REG_ERR_CONC_STARTMB_X(x) (((x) & 0x1ff) << 23) +#define VDPU_REG_ERR_CONC_STARTMB_Y(x) (((x) & 0xff) << 15) +#define VDPU_REG_PRED_FLT 0x0c4 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_0(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_1(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_2(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_REF_BUF_CTRL 0x0cc +#define VDPU_REG_REF_BUF_CTRL_REFBU_E BIT(31) +#define VDPU_REG_REF_BUF_CTRL_REFBU_THR(x) (((x) & 0xfff) << 19) +#define VDPU_REG_REF_BUF_CTRL_REFBU_PICID(x) (((x) & 0x1f) << 14) +#define VDPU_REG_REF_BUF_CTRL_REFBU_EVAL_E BIT(13) +#define VDPU_REG_REF_BUF_CTRL_REFBU_FPARMOD_E BIT(12) +#define VDPU_REG_REF_BUF_CTRL_REFBU_Y_OFFSET(x) (((x) & 0x1ff) << 0) +#define VDPU_REG_REF_BUF_CTRL2 0x0dc +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_BUF_E BIT(31) +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_THR(x) (((x) & 0xfff) << 19) +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_PICID(x) (((x) & 0x1f) << 14) +#define VDPU_REG_REF_BUF_CTRL2_APF_THRESHOLD(x) (((x) & 0x3fff) << 0) + +#endif /* RK3288_VPU_REGS_H_ */ diff --git a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c new file mode 100644 index 000000000000..6fdef61e2127 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip VPU codec driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Jeffy Chen <jeffy.chen@rock-chips.com> + */ + +#include <linux/clk.h> + +#include "rockchip_vpu.h" +#include "rockchip_vpu_jpeg.h" +#include "rk3399_vpu_regs.h" + +#define RK3399_ACLK_MAX_FREQ (400 * 1000 * 1000) + +/* + * Supported formats. + */ + +static const struct rockchip_vpu_fmt rk3399_vpu_enc_fmts[] = { + { + .fourcc = V4L2_PIX_FMT_YUV420M, + .codec_mode = RK_VPU_MODE_NONE, + .enc_fmt = RK3288_VPU_ENC_FMT_YUV420P, + }, + { + .fourcc = V4L2_PIX_FMT_NV12M, + .codec_mode = RK_VPU_MODE_NONE, + .enc_fmt = RK3288_VPU_ENC_FMT_YUV420SP, + }, + { + .fourcc = V4L2_PIX_FMT_YUYV, + .codec_mode = RK_VPU_MODE_NONE, + .enc_fmt = RK3288_VPU_ENC_FMT_YUYV422, + }, + { + .fourcc = V4L2_PIX_FMT_UYVY, + .codec_mode = RK_VPU_MODE_NONE, + .enc_fmt = RK3288_VPU_ENC_FMT_UYVY422, + }, + { + .fourcc = V4L2_PIX_FMT_JPEG, + .codec_mode = RK_VPU_MODE_JPEG_ENC, + .max_depth = 2, + .header_size = JPEG_HEADER_SIZE, + .frmsize = { + .min_width = 96, + .max_width = 8192, + .step_width = JPEG_MB_DIM, + .min_height = 32, + .max_height = 8192, + .step_height = JPEG_MB_DIM, + }, + }, +}; + +static irqreturn_t rk3399_vepu_irq(int irq, void *dev_id) +{ + struct rockchip_vpu_dev *vpu = dev_id; + enum vb2_buffer_state state; + u32 status, bytesused; + + status = vepu_read(vpu, VEPU_REG_INTERRUPT); + bytesused = vepu_read(vpu, VEPU_REG_STR_BUF_LIMIT) / 8; + state = (status & VEPU_REG_INTERRUPT_FRAME_READY) ? + VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + + vepu_write(vpu, 0, VEPU_REG_INTERRUPT); + vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); + + rockchip_vpu_irq_done(vpu, bytesused, state); + + return IRQ_HANDLED; +} + +static int rk3399_vpu_hw_init(struct rockchip_vpu_dev *vpu) +{ + /* Bump ACLK to max. possible freq. to improve performance. */ + clk_set_rate(vpu->clocks[0].clk, RK3399_ACLK_MAX_FREQ); + return 0; +} + +static void rk3399_vpu_enc_reset(struct rockchip_vpu_ctx *ctx) +{ + struct rockchip_vpu_dev *vpu = ctx->dev; + + vepu_write(vpu, VEPU_REG_INTERRUPT_DIS_BIT, VEPU_REG_INTERRUPT); + vepu_write(vpu, 0, VEPU_REG_ENCODE_START); + vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); +} + +/* + * Supported codec ops. + */ + +static const struct rockchip_vpu_codec_ops rk3399_vpu_codec_ops[] = { + [RK_VPU_MODE_JPEG_ENC] = { + .run = rk3399_vpu_jpeg_enc_run, + .reset = rk3399_vpu_enc_reset, + }, +}; + +/* + * VPU variant. + */ + +const struct rockchip_vpu_variant rk3399_vpu_variant = { + .enc_offset = 0x0, + .enc_fmts = rk3399_vpu_enc_fmts, + .num_enc_fmts = ARRAY_SIZE(rk3399_vpu_enc_fmts), + .codec = RK_VPU_CODEC_JPEG, + .codec_ops = rk3399_vpu_codec_ops, + .vepu_irq = rk3399_vepu_irq, + .init = rk3399_vpu_hw_init, + .clk_names = {"aclk", "hclk"}, + .num_clocks = 2 +}; diff --git a/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_jpeg_enc.c b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_jpeg_enc.c new file mode 100644 index 000000000000..dbc86d95fe3b --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rk3399_vpu_hw_jpeg_enc.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip VPU codec driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * + * JPEG encoder + * ------------ + * The VPU JPEG encoder produces JPEG baseline sequential format. + * The quantization coefficients are 8-bit values, complying with + * the baseline specification. Therefore, it requires + * luma and chroma quantization tables. The hardware does entropy + * encoding using internal Huffman tables, as specified in the JPEG + * specification. + * + * In other words, only the luma and chroma quantization tables are + * required for the encoding operation. + * + * Quantization luma table values are written to registers + * VEPU_swreg_0-VEPU_swreg_15, and chroma table values to + * VEPU_swreg_16-VEPU_swreg_31. + * + * JPEG zigzag order is expected on the quantization tables. + */ + +#include <asm/unaligned.h> +#include <media/v4l2-mem2mem.h> +#include "rockchip_vpu_jpeg.h" +#include "rockchip_vpu.h" +#include "rockchip_vpu_common.h" +#include "rockchip_vpu_hw.h" +#include "rk3399_vpu_regs.h" + +#define VEPU_JPEG_QUANT_TABLE_COUNT 16 + +static void rk3399_vpu_set_src_img_ctrl(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx) +{ + struct v4l2_pix_format_mplane *pix_fmt = &ctx->src_fmt; + u32 reg; + + /* + * The pix fmt width/height are already macroblock aligned + * by .vidioc_s_fmt_vid_cap_mplane() callback + */ + reg = VEPU_REG_IN_IMG_CTRL_ROW_LEN(pix_fmt->width); + vepu_write_relaxed(vpu, reg, VEPU_REG_INPUT_LUMA_INFO); + + reg = VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(0) | + VEPU_REG_IN_IMG_CTRL_OVRFLB(0); + /* + * This register controls the input crop, as the offset + * from the right/bottom within the last macroblock. The offset from the + * right must be divided by 4 and so the crop must be aligned to 4 pixels + * horizontally. + */ + vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_OVER_FILL_STRM_OFFSET); + + reg = VEPU_REG_IN_IMG_CTRL_FMT(ctx->vpu_src_fmt->enc_fmt); + vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_CTRL1); +} + +static void rk3399_vpu_jpeg_enc_set_buffers(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx, + struct vb2_buffer *src_buf) +{ + struct v4l2_pix_format_mplane *pix_fmt = &ctx->src_fmt; + dma_addr_t src[3]; + + WARN_ON(pix_fmt->num_planes > 3); + + vepu_write_relaxed(vpu, ctx->bounce_dma_addr, + VEPU_REG_ADDR_OUTPUT_STREAM); + vepu_write_relaxed(vpu, ctx->bounce_size, + VEPU_REG_STR_BUF_LIMIT); + + if (pix_fmt->num_planes == 1) { + src[0] = vb2_dma_contig_plane_dma_addr(src_buf, 0); + vepu_write_relaxed(vpu, src[0], VEPU_REG_ADDR_IN_PLANE_0); + } else if (pix_fmt->num_planes == 2) { + src[0] = vb2_dma_contig_plane_dma_addr(src_buf, 0); + src[1] = vb2_dma_contig_plane_dma_addr(src_buf, 1); + vepu_write_relaxed(vpu, src[0], VEPU_REG_ADDR_IN_PLANE_0); + vepu_write_relaxed(vpu, src[1], VEPU_REG_ADDR_IN_PLANE_1); + } else { + src[0] = vb2_dma_contig_plane_dma_addr(src_buf, 0); + src[1] = vb2_dma_contig_plane_dma_addr(src_buf, 1); + src[2] = vb2_dma_contig_plane_dma_addr(src_buf, 2); + vepu_write_relaxed(vpu, src[0], VEPU_REG_ADDR_IN_PLANE_0); + vepu_write_relaxed(vpu, src[1], VEPU_REG_ADDR_IN_PLANE_1); + vepu_write_relaxed(vpu, src[2], VEPU_REG_ADDR_IN_PLANE_2); + } +} + +static void +rk3399_vpu_jpeg_enc_set_qtable(struct rockchip_vpu_dev *vpu, + unsigned char *luma_qtable, + unsigned char *chroma_qtable) +{ + u32 reg, i; + + for (i = 0; i < VEPU_JPEG_QUANT_TABLE_COUNT; i++) { + reg = get_unaligned_be32(&luma_qtable[i]); + vepu_write_relaxed(vpu, reg, VEPU_REG_JPEG_LUMA_QUAT(i)); + + reg = get_unaligned_be32(&chroma_qtable[i]); + vepu_write_relaxed(vpu, reg, VEPU_REG_JPEG_CHROMA_QUAT(i)); + } +} + +void rk3399_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx) +{ + struct rockchip_vpu_dev *vpu = ctx->dev; + struct vb2_buffer *src_buf, *dst_buf; + struct rockchip_vpu_jpeg_ctx jpeg_ctx; + u32 reg; + + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); + + memset(&jpeg_ctx, 0, sizeof(jpeg_ctx)); + jpeg_ctx.buffer = vb2_plane_vaddr(dst_buf, 0); + jpeg_ctx.width = ctx->dst_fmt.width; + jpeg_ctx.height = ctx->dst_fmt.height; + jpeg_ctx.quality = ctx->jpeg_quality; + rockchip_vpu_jpeg_header_assemble(&jpeg_ctx); + + /* Switch to JPEG encoder mode before writing registers */ + vepu_write_relaxed(vpu, VEPU_REG_ENCODE_FORMAT_JPEG, + VEPU_REG_ENCODE_START); + + rk3399_vpu_set_src_img_ctrl(vpu, ctx); + rk3399_vpu_jpeg_enc_set_buffers(vpu, ctx, src_buf); + rk3399_vpu_jpeg_enc_set_qtable(vpu, + rockchip_vpu_jpeg_get_qtable(&jpeg_ctx, 0), + rockchip_vpu_jpeg_get_qtable(&jpeg_ctx, 1)); + + reg = VEPU_REG_OUTPUT_SWAP32 + | VEPU_REG_OUTPUT_SWAP16 + | VEPU_REG_OUTPUT_SWAP8 + | VEPU_REG_INPUT_SWAP8 + | VEPU_REG_INPUT_SWAP16 + | VEPU_REG_INPUT_SWAP32; + /* Make sure that all registers are written at this point. */ + vepu_write(vpu, reg, VEPU_REG_DATA_ENDIAN); + + reg = VEPU_REG_AXI_CTRL_BURST_LEN(16); + vepu_write_relaxed(vpu, reg, VEPU_REG_AXI_CTRL); + + reg = VEPU_REG_MB_WIDTH(JPEG_MB_WIDTH(ctx->src_fmt.width)) + | VEPU_REG_MB_HEIGHT(JPEG_MB_HEIGHT(ctx->src_fmt.height)) + | VEPU_REG_FRAME_TYPE_INTRA + | VEPU_REG_ENCODE_FORMAT_JPEG + | VEPU_REG_ENCODE_ENABLE; + + /* Kick the watchdog and start encoding */ + schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000)); + vepu_write(vpu, reg, VEPU_REG_ENCODE_START); +} diff --git a/drivers/staging/media/rockchip/vpu/rk3399_vpu_regs.h b/drivers/staging/media/rockchip/vpu/rk3399_vpu_regs.h new file mode 100644 index 000000000000..fbe294177ec9 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rk3399_vpu_regs.h @@ -0,0 +1,600 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip VPU codec driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Alpha Lin <alpha.lin@rock-chips.com> + */ + +#ifndef RK3399_VPU_REGS_H_ +#define RK3399_VPU_REGS_H_ + +/* Encoder registers. */ +#define VEPU_REG_VP8_QUT_1ST(i) (0x000 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_DC_Y2(x) (((x) & 0x3fff) << 16) +#define VEPU_REG_VP8_QUT_DC_Y1(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_QUT_2ND(i) (0x004 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_AC_Y1(x) (((x) & 0x3fff) << 16) +#define VEPU_REG_VP8_QUT_DC_CHR(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_QUT_3RD(i) (0x008 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_AC_CHR(x) (((x) & 0x3fff) << 16) +#define VEPU_REG_VP8_QUT_AC_Y2(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_QUT_4TH(i) (0x00c + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_ZB_DC_CHR(x) (((x) & 0x1ff) << 18) +#define VEPU_REG_VP8_QUT_ZB_DC_Y2(x) (((x) & 0x1ff) << 9) +#define VEPU_REG_VP8_QUT_ZB_DC_Y1(x) (((x) & 0x1ff) << 0) +#define VEPU_REG_VP8_QUT_5TH(i) (0x010 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_ZB_AC_CHR(x) (((x) & 0x1ff) << 18) +#define VEPU_REG_VP8_QUT_ZB_AC_Y2(x) (((x) & 0x1ff) << 9) +#define VEPU_REG_VP8_QUT_ZB_AC_Y1(x) (((x) & 0x1ff) << 0) +#define VEPU_REG_VP8_QUT_6TH(i) (0x014 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_RND_DC_CHR(x) (((x) & 0xff) << 16) +#define VEPU_REG_VP8_QUT_RND_DC_Y2(x) (((x) & 0xff) << 8) +#define VEPU_REG_VP8_QUT_RND_DC_Y1(x) (((x) & 0xff) << 0) +#define VEPU_REG_VP8_QUT_7TH(i) (0x018 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_RND_AC_CHR(x) (((x) & 0xff) << 16) +#define VEPU_REG_VP8_QUT_RND_AC_Y2(x) (((x) & 0xff) << 8) +#define VEPU_REG_VP8_QUT_RND_AC_Y1(x) (((x) & 0xff) << 0) +#define VEPU_REG_VP8_QUT_8TH(i) (0x01c + ((i) * 0x24)) +#define VEPU_REG_VP8_SEG_FILTER_LEVEL(x) (((x) & 0x3f) << 25) +#define VEPU_REG_VP8_DEQUT_DC_CHR(x) (((x) & 0xff) << 17) +#define VEPU_REG_VP8_DEQUT_DC_Y2(x) (((x) & 0x1ff) << 8) +#define VEPU_REG_VP8_DEQUT_DC_Y1(x) (((x) & 0xff) << 0) +#define VEPU_REG_VP8_QUT_9TH(i) (0x020 + ((i) * 0x24)) +#define VEPU_REG_VP8_DEQUT_AC_CHR(x) (((x) & 0x1ff) << 18) +#define VEPU_REG_VP8_DEQUT_AC_Y2(x) (((x) & 0x1ff) << 9) +#define VEPU_REG_VP8_DEQUT_AC_Y1(x) (((x) & 0x1ff) << 0) +#define VEPU_REG_ADDR_VP8_SEG_MAP 0x06c +#define VEPU_REG_VP8_INTRA_4X4_PENALTY(i) (0x070 + ((i) * 0x4)) +#define VEPU_REG_VP8_INTRA_4X4_PENALTY_0(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_INTRA_4x4_PENALTY_1(x) (((x) & 0xfff) << 16) +#define VEPU_REG_VP8_INTRA_16X16_PENALTY(i) (0x084 + ((i) * 0x4)) +#define VEPU_REG_VP8_INTRA_16X16_PENALTY_0(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_INTRA_16X16_PENALTY_1(x) (((x) & 0xfff) << 16) +#define VEPU_REG_VP8_CONTROL 0x0a0 +#define VEPU_REG_VP8_LF_MODE_DELTA_BPRED(x) (((x) & 0x1f) << 24) +#define VEPU_REG_VP8_LF_REF_DELTA_INTRA_MB(x) (((x) & 0x7f) << 16) +#define VEPU_REG_VP8_INTER_TYPE_BIT_COST(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_REF_FRAME_VAL 0x0a4 +#define VEPU_REG_VP8_COEF_DMV_PENALTY(x) (((x) & 0xfff) << 16) +#define VEPU_REG_VP8_REF_FRAME(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_LOOP_FILTER_REF_DELTA 0x0a8 +#define VEPU_REG_VP8_LF_REF_DELTA_ALT_REF(x) (((x) & 0x7f) << 16) +#define VEPU_REG_VP8_LF_REF_DELTA_LAST_REF(x) (((x) & 0x7f) << 8) +#define VEPU_REG_VP8_LF_REF_DELTA_GOLDEN(x) (((x) & 0x7f) << 0) +#define VEPU_REG_VP8_LOOP_FILTER_MODE_DELTA 0x0ac +#define VEPU_REG_VP8_LF_MODE_DELTA_SPLITMV(x) (((x) & 0x7f) << 16) +#define VEPU_REG_VP8_LF_MODE_DELTA_ZEROMV(x) (((x) & 0x7f) << 8) +#define VEPU_REG_VP8_LF_MODE_DELTA_NEWMV(x) (((x) & 0x7f) << 0) +#define VEPU_REG_JPEG_LUMA_QUAT(i) (0x000 + ((i) * 0x4)) +#define VEPU_REG_JPEG_CHROMA_QUAT(i) (0x040 + ((i) * 0x4)) +#define VEPU_REG_INTRA_SLICE_BITMAP(i) (0x0b0 + ((i) * 0x4)) +#define VEPU_REG_ADDR_VP8_DCT_PART(i) (0x0b0 + ((i) * 0x4)) +#define VEPU_REG_INTRA_AREA_CTRL 0x0b8 +#define VEPU_REG_INTRA_AREA_TOP(x) (((x) & 0xff) << 24) +#define VEPU_REG_INTRA_AREA_BOTTOM(x) (((x) & 0xff) << 16) +#define VEPU_REG_INTRA_AREA_LEFT(x) (((x) & 0xff) << 8) +#define VEPU_REG_INTRA_AREA_RIGHT(x) (((x) & 0xff) << 0) +#define VEPU_REG_CIR_INTRA_CTRL 0x0bc +#define VEPU_REG_CIR_INTRA_FIRST_MB(x) (((x) & 0xffff) << 16) +#define VEPU_REG_CIR_INTRA_INTERVAL(x) (((x) & 0xffff) << 0) +#define VEPU_REG_ADDR_IN_PLANE_0 0x0c0 +#define VEPU_REG_ADDR_IN_PLANE_1 0x0c4 +#define VEPU_REG_ADDR_IN_PLANE_2 0x0c8 +#define VEPU_REG_STR_HDR_REM_MSB 0x0cc +#define VEPU_REG_STR_HDR_REM_LSB 0x0d0 +#define VEPU_REG_STR_BUF_LIMIT 0x0d4 +#define VEPU_REG_AXI_CTRL 0x0d8 +#define VEPU_REG_AXI_CTRL_READ_ID(x) (((x) & 0xff) << 24) +#define VEPU_REG_AXI_CTRL_WRITE_ID(x) (((x) & 0xff) << 16) +#define VEPU_REG_AXI_CTRL_BURST_LEN(x) (((x) & 0x3f) << 8) +#define VEPU_REG_AXI_CTRL_INCREMENT_MODE(x) (((x) & 0x01) << 2) +#define VEPU_REG_AXI_CTRL_BIRST_DISCARD(x) (((x) & 0x01) << 1) +#define VEPU_REG_AXI_CTRL_BIRST_DISABLE BIT(0) +#define VEPU_QP_ADJUST_MAD_DELTA_ROI 0x0dc +#define VEPU_REG_ROI_QP_DELTA_1 (((x) & 0xf) << 12) +#define VEPU_REG_ROI_QP_DELTA_2 (((x) & 0xf) << 8) +#define VEPU_REG_MAD_QP_ADJUSTMENT (((x) & 0xf) << 0) +#define VEPU_REG_ADDR_REF_LUMA 0x0e0 +#define VEPU_REG_ADDR_REF_CHROMA 0x0e4 +#define VEPU_REG_QP_SUM_DIV2 0x0e8 +#define VEPU_REG_QP_SUM(x) (((x) & 0x001fffff) * 2) +#define VEPU_REG_ENC_CTRL0 0x0ec +#define VEPU_REG_DISABLE_QUARTER_PIXEL_MV BIT(28) +#define VEPU_REG_DEBLOCKING_FILTER_MODE(x) (((x) & 0x3) << 24) +#define VEPU_REG_CABAC_INIT_IDC(x) (((x) & 0x3) << 21) +#define VEPU_REG_ENTROPY_CODING_MODE BIT(20) +#define VEPU_REG_H264_TRANS8X8_MODE BIT(17) +#define VEPU_REG_H264_INTER4X4_MODE BIT(16) +#define VEPU_REG_H264_STREAM_MODE BIT(15) +#define VEPU_REG_H264_SLICE_SIZE(x) (((x) & 0x7f) << 8) +#define VEPU_REG_ENC_OVER_FILL_STRM_OFFSET 0x0f0 +#define VEPU_REG_STREAM_START_OFFSET(x) (((x) & 0x3f) << 16) +#define VEPU_REG_SKIP_MACROBLOCK_PENALTY(x) (((x) & 0xff) << 8) +#define VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(x) (((x) & 0x3) << 4) +#define VEPU_REG_IN_IMG_CTRL_OVRFLB(x) (((x) & 0xf) << 0) +#define VEPU_REG_INPUT_LUMA_INFO 0x0f4 +#define VEPU_REG_IN_IMG_CHROMA_OFFSET(x) (((x) & 0x7) << 20) +#define VEPU_REG_IN_IMG_LUMA_OFFSET(x) (((x) & 0x7) << 16) +#define VEPU_REG_IN_IMG_CTRL_ROW_LEN(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_RLC_SUM 0x0f8 +#define VEPU_REG_RLC_SUM_OUT(x) (((x) & 0x007fffff) * 4) +#define VEPU_REG_SPLIT_PENALTY_4X4 0x0f8 +#define VEPU_REG_VP8_SPLIT_PENALTY_4X4 (((x) & 0x1ff) << 19) +#define VEPU_REG_ADDR_REC_LUMA 0x0fc +#define VEPU_REG_ADDR_REC_CHROMA 0x100 +#define VEPU_REG_CHECKPOINT(i) (0x104 + ((i) * 0x4)) +#define VEPU_REG_CHECKPOINT_CHECK0(x) (((x) & 0xffff)) +#define VEPU_REG_CHECKPOINT_CHECK1(x) (((x) & 0xffff) << 16) +#define VEPU_REG_CHECKPOINT_RESULT(x) \ + ((((x) >> (16 - 16 * ((i) & 1))) & 0xffff) * 32) +#define VEPU_REG_VP8_SEG0_QUANT_AC_Y1 0x104 +#define VEPU_REG_VP8_SEG0_RND_AC_Y1(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_AC_Y1(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_AC_Y1(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_DC_Y2 0x108 +#define VEPU_REG_VP8_SEG0_RND_DC_Y2(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_DC_Y2(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_DC_Y2(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_AC_Y2 0x10c +#define VEPU_REG_VP8_SEG0_RND_AC_Y2(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_AC_Y2(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_AC_Y2(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_DC_CHR 0x110 +#define VEPU_REG_VP8_SEG0_RND_DC_CHR(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_DC_CHR(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_DC_CHR(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_AC_CHR 0x114 +#define VEPU_REG_VP8_SEG0_RND_AC_CHR(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_AC_CHR(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_AC_CHR(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_DQUT 0x118 +#define VEPU_REG_VP8_MV_REF_IDX1(x) (((x) & 0x03) << 26) +#define VEPU_REG_VP8_SEG0_DQUT_DC_Y2(x) (((x) & 0x1ff) << 17) +#define VEPU_REG_VP8_SEG0_DQUT_AC_Y1(x) (((x) & 0x1ff) << 8) +#define VEPU_REG_VP8_SEG0_DQUT_DC_Y1(x) (((x) & 0xff) << 0) +#define VEPU_REG_CHKPT_WORD_ERR(i) (0x118 + ((i) * 0x4)) +#define VEPU_REG_CHKPT_WORD_ERR_CHK0(x) (((x) & 0xffff)) +#define VEPU_REG_CHKPT_WORD_ERR_CHK1(x) (((x) & 0xffff) << 16) +#define VEPU_REG_VP8_SEG0_QUANT_DQUT_1 0x11c +#define VEPU_REG_VP8_SEGMENT_MAP_UPDATE BIT(30) +#define VEPU_REG_VP8_SEGMENT_EN BIT(29) +#define VEPU_REG_VP8_MV_REF_IDX2_EN BIT(28) +#define VEPU_REG_VP8_MV_REF_IDX2(x) (((x) & 0x03) << 26) +#define VEPU_REG_VP8_SEG0_DQUT_AC_CHR(x) (((x) & 0x1ff) << 17) +#define VEPU_REG_VP8_SEG0_DQUT_DC_CHR(x) (((x) & 0xff) << 9) +#define VEPU_REG_VP8_SEG0_DQUT_AC_Y2(x) (((x) & 0x1ff) << 0) +#define VEPU_REG_VP8_BOOL_ENC_VALUE 0x120 +#define VEPU_REG_CHKPT_DELTA_QP 0x124 +#define VEPU_REG_CHKPT_DELTA_QP_CHK0(x) (((x) & 0x0f) << 0) +#define VEPU_REG_CHKPT_DELTA_QP_CHK1(x) (((x) & 0x0f) << 4) +#define VEPU_REG_CHKPT_DELTA_QP_CHK2(x) (((x) & 0x0f) << 8) +#define VEPU_REG_CHKPT_DELTA_QP_CHK3(x) (((x) & 0x0f) << 12) +#define VEPU_REG_CHKPT_DELTA_QP_CHK4(x) (((x) & 0x0f) << 16) +#define VEPU_REG_CHKPT_DELTA_QP_CHK5(x) (((x) & 0x0f) << 20) +#define VEPU_REG_CHKPT_DELTA_QP_CHK6(x) (((x) & 0x0f) << 24) +#define VEPU_REG_VP8_ENC_CTRL2 0x124 +#define VEPU_REG_VP8_ZERO_MV_PENALTY_FOR_REF2(x) (((x) & 0xff) << 24) +#define VEPU_REG_VP8_FILTER_SHARPNESS(x) (((x) & 0x07) << 21) +#define VEPU_REG_VP8_FILTER_LEVEL(x) (((x) & 0x3f) << 15) +#define VEPU_REG_VP8_DCT_PARTITION_CNT(x) (((x) & 0x03) << 13) +#define VEPU_REG_VP8_BOOL_ENC_VALUE_BITS(x) (((x) & 0x1f) << 8) +#define VEPU_REG_VP8_BOOL_ENC_RANGE(x) (((x) & 0xff) << 0) +#define VEPU_REG_ENC_CTRL1 0x128 +#define VEPU_REG_MAD_THRESHOLD(x) (((x) & 0x3f) << 24) +#define VEPU_REG_COMPLETED_SLICES(x) (((x) & 0xff) << 16) +#define VEPU_REG_IN_IMG_CTRL_FMT(x) (((x) & 0xf) << 4) +#define VEPU_REG_IN_IMG_ROTATE_MODE(x) (((x) & 0x3) << 2) +#define VEPU_REG_SIZE_TABLE_PRESENT BIT(0) +#define VEPU_REG_INTRA_INTER_MODE 0x12c +#define VEPU_REG_INTRA16X16_MODE(x) (((x) & 0xffff) << 16) +#define VEPU_REG_INTER_MODE(x) (((x) & 0xffff) << 0) +#define VEPU_REG_ENC_CTRL2 0x130 +#define VEPU_REG_PPS_INIT_QP(x) (((x) & 0x3f) << 26) +#define VEPU_REG_SLICE_FILTER_ALPHA(x) (((x) & 0xf) << 22) +#define VEPU_REG_SLICE_FILTER_BETA(x) (((x) & 0xf) << 18) +#define VEPU_REG_CHROMA_QP_OFFSET(x) (((x) & 0x1f) << 13) +#define VEPU_REG_FILTER_DISABLE BIT(5) +#define VEPU_REG_IDR_PIC_ID(x) (((x) & 0xf) << 1) +#define VEPU_REG_CONSTRAINED_INTRA_PREDICTION BIT(0) +#define VEPU_REG_ADDR_OUTPUT_STREAM 0x134 +#define VEPU_REG_ADDR_OUTPUT_CTRL 0x138 +#define VEPU_REG_ADDR_NEXT_PIC 0x13c +#define VEPU_REG_ADDR_MV_OUT 0x140 +#define VEPU_REG_ADDR_CABAC_TBL 0x144 +#define VEPU_REG_ROI1 0x148 +#define VEPU_REG_ROI1_TOP_MB(x) (((x) & 0xff) << 24) +#define VEPU_REG_ROI1_BOTTOM_MB(x) (((x) & 0xff) << 16) +#define VEPU_REG_ROI1_LEFT_MB(x) (((x) & 0xff) << 8) +#define VEPU_REG_ROI1_RIGHT_MB(x) (((x) & 0xff) << 0) +#define VEPU_REG_ROI2 0x14c +#define VEPU_REG_ROI2_TOP_MB(x) (((x) & 0xff) << 24) +#define VEPU_REG_ROI2_BOTTOM_MB(x) (((x) & 0xff) << 16) +#define VEPU_REG_ROI2_LEFT_MB(x) (((x) & 0xff) << 8) +#define VEPU_REG_ROI2_RIGHT_MB(x) (((x) & 0xff) << 0) +#define VEPU_REG_STABLE_MATRIX(i) (0x150 + ((i) * 0x4)) +#define VEPU_REG_STABLE_MOTION_SUM 0x174 +#define VEPU_REG_STABILIZATION_OUTPUT 0x178 +#define VEPU_REG_STABLE_MIN_VALUE(x) (((x) & 0xffffff) << 8) +#define VEPU_REG_STABLE_MODE_SEL(x) (((x) & 0x3) << 6) +#define VEPU_REG_STABLE_HOR_GMV(x) (((x) & 0x3f) << 0) +#define VEPU_REG_RGB2YUV_CONVERSION_COEF1 0x17c +#define VEPU_REG_RGB2YUV_CONVERSION_COEFB(x) (((x) & 0xffff) << 16) +#define VEPU_REG_RGB2YUV_CONVERSION_COEFA(x) (((x) & 0xffff) << 0) +#define VEPU_REG_RGB2YUV_CONVERSION_COEF2 0x180 +#define VEPU_REG_RGB2YUV_CONVERSION_COEFE(x) (((x) & 0xffff) << 16) +#define VEPU_REG_RGB2YUV_CONVERSION_COEFC(x) (((x) & 0xffff) << 0) +#define VEPU_REG_RGB2YUV_CONVERSION_COEF3 0x184 +#define VEPU_REG_RGB2YUV_CONVERSION_COEFF(x) (((x) & 0xffff) << 0) +#define VEPU_REG_RGB_MASK_MSB 0x188 +#define VEPU_REG_RGB_MASK_B_MSB(x) (((x) & 0x1f) << 16) +#define VEPU_REG_RGB_MASK_G_MSB(x) (((x) & 0x1f) << 8) +#define VEPU_REG_RGB_MASK_R_MSB(x) (((x) & 0x1f) << 0) +#define VEPU_REG_MV_PENALTY 0x18c +#define VEPU_REG_1MV_PENALTY(x) (((x) & 0x3ff) << 21) +#define VEPU_REG_QMV_PENALTY(x) (((x) & 0x3ff) << 11) +#define VEPU_REG_4MV_PENALTY(x) (((x) & 0x3ff) << 1) +#define VEPU_REG_SPLIT_MV_MODE_EN BIT(0) +#define VEPU_REG_QP_VAL 0x190 +#define VEPU_REG_H264_LUMA_INIT_QP(x) (((x) & 0x3f) << 26) +#define VEPU_REG_H264_QP_MAX(x) (((x) & 0x3f) << 20) +#define VEPU_REG_H264_QP_MIN(x) (((x) & 0x3f) << 14) +#define VEPU_REG_H264_CHKPT_DISTANCE(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_DC_Y1 0x190 +#define VEPU_REG_VP8_SEG0_RND_DC_Y1(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_DC_Y1(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_DC_Y1(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_MVC_RELATE 0x198 +#define VEPU_REG_ZERO_MV_FAVOR_D2(x) (((x) & 0xf) << 20) +#define VEPU_REG_PENALTY_4X4MV(x) (((x) & 0x1ff) << 11) +#define VEPU_REG_MVC_VIEW_ID(x) (((x) & 0x7) << 8) +#define VEPU_REG_MVC_ANCHOR_PIC_FLAG BIT(7) +#define VEPU_REG_MVC_PRIORITY_ID(x) (((x) & 0x7) << 4) +#define VEPU_REG_MVC_TEMPORAL_ID(x) (((x) & 0x7) << 1) +#define VEPU_REG_MVC_INTER_VIEW_FLAG BIT(0) +#define VEPU_REG_ENCODE_START 0x19c +#define VEPU_REG_MB_HEIGHT(x) (((x) & 0x1ff) << 20) +#define VEPU_REG_MB_WIDTH(x) (((x) & 0x1ff) << 8) +#define VEPU_REG_FRAME_TYPE_INTER (0x0 << 6) +#define VEPU_REG_FRAME_TYPE_INTRA (0x1 << 6) +#define VEPU_REG_FRAME_TYPE_MVCINTER (0x2 << 6) +#define VEPU_REG_ENCODE_FORMAT_JPEG (0x2 << 4) +#define VEPU_REG_ENCODE_FORMAT_H264 (0x3 << 4) +#define VEPU_REG_ENCODE_ENABLE BIT(0) +#define VEPU_REG_MB_CTRL 0x1a0 +#define VEPU_REG_MB_CNT_OUT(x) (((x) & 0xffff) << 16) +#define VEPU_REG_MB_CNT_SET(x) (((x) & 0xffff) << 0) +#define VEPU_REG_DATA_ENDIAN 0x1a4 +#define VEPU_REG_INPUT_SWAP8 BIT(31) +#define VEPU_REG_INPUT_SWAP16 BIT(30) +#define VEPU_REG_INPUT_SWAP32 BIT(29) +#define VEPU_REG_OUTPUT_SWAP8 BIT(28) +#define VEPU_REG_OUTPUT_SWAP16 BIT(27) +#define VEPU_REG_OUTPUT_SWAP32 BIT(26) +#define VEPU_REG_TEST_IRQ BIT(24) +#define VEPU_REG_TEST_COUNTER(x) (((x) & 0xf) << 20) +#define VEPU_REG_TEST_REG BIT(19) +#define VEPU_REG_TEST_MEMORY BIT(18) +#define VEPU_REG_TEST_LEN(x) (((x) & 0x3ffff) << 0) +#define VEPU_REG_ENC_CTRL3 0x1a8 +#define VEPU_REG_PPS_ID(x) (((x) & 0xff) << 24) +#define VEPU_REG_INTRA_PRED_MODE(x) (((x) & 0xff) << 16) +#define VEPU_REG_FRAME_NUM(x) (((x) & 0xffff) << 0) +#define VEPU_REG_ENC_CTRL4 0x1ac +#define VEPU_REG_MV_PENALTY_16X8_8X16(x) (((x) & 0x3ff) << 20) +#define VEPU_REG_MV_PENALTY_8X8(x) (((x) & 0x3ff) << 10) +#define VEPU_REG_MV_PENALTY_8X4_4X8(x) (((x) & 0x3ff) << 0) +#define VEPU_REG_ADDR_VP8_PROB_CNT 0x1b0 +#define VEPU_REG_INTERRUPT 0x1b4 +#define VEPU_REG_INTERRUPT_NON BIT(28) +#define VEPU_REG_MV_WRITE_EN BIT(24) +#define VEPU_REG_RECON_WRITE_DIS BIT(20) +#define VEPU_REG_INTERRUPT_SLICE_READY_EN BIT(16) +#define VEPU_REG_CLK_GATING_EN BIT(12) +#define VEPU_REG_INTERRUPT_TIMEOUT_EN BIT(10) +#define VEPU_REG_INTERRUPT_RESET BIT(9) +#define VEPU_REG_INTERRUPT_DIS_BIT BIT(8) +#define VEPU_REG_INTERRUPT_TIMEOUT BIT(6) +#define VEPU_REG_INTERRUPT_BUFFER_FULL BIT(5) +#define VEPU_REG_INTERRUPT_BUS_ERROR BIT(4) +#define VEPU_REG_INTERRUPT_FUSE BIT(3) +#define VEPU_REG_INTERRUPT_SLICE_READY BIT(2) +#define VEPU_REG_INTERRUPT_FRAME_READY BIT(1) +#define VEPU_REG_INTERRUPT_BIT BIT(0) +#define VEPU_REG_DMV_PENALTY_TBL(i) (0x1E0 + ((i) * 0x4)) +#define VEPU_REG_DMV_PENALTY_TABLE_BIT(x, i) ((x) << (i) * 8) +#define VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i) (0x260 + ((i) * 0x4)) +#define VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(x, i) ((x) << (i) * 8) + +/* vpu decoder register */ +#define VDPU_REG_DEC_CTRL0 0x0c8 // 50 +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_PICID(x) (((x) & 0x1f) << 25) +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_THR(x) (((x) & 0xfff) << 13) +#define VDPU_REG_CONFIG_TILED_MODE_LSB BIT(12) +#define VDPU_REG_CONFIG_DEC_ADV_PRE_DIS BIT(11) +#define VDPU_REG_CONFIG_DEC_SCMD_DIS BIT(10) +#define VDPU_REG_DEC_CTRL0_SKIP_MODE BIT(9) +#define VDPU_REG_DEC_CTRL0_FILTERING_DIS BIT(8) +#define VDPU_REG_DEC_CTRL0_PIC_FIXED_QUANT BIT(7) +#define VDPU_REG_CONFIG_DEC_LATENCY(x) (((x) & 0x3f) << 1) +#define VDPU_REG_CONFIG_TILED_MODE_MSB(x) BIT(0) +#define VDPU_REG_CONFIG_DEC_OUT_TILED_E BIT(0) +#define VDPU_REG_STREAM_LEN 0x0cc +#define VDPU_REG_DEC_CTRL3_INIT_QP(x) (((x) & 0x3f) << 25) +#define VDPU_REG_DEC_STREAM_LEN_HI BIT(24) +#define VDPU_REG_DEC_CTRL3_STREAM_LEN(x) (((x) & 0xffffff) << 0) +#define VDPU_REG_ERROR_CONCEALMENT 0x0d0 +#define VDPU_REG_REF_BUF_CTRL2_APF_THRESHOLD(x) (((x) & 0x3fff) << 17) +#define VDPU_REG_ERR_CONC_STARTMB_X(x) (((x) & 0x1ff) << 8) +#define VDPU_REG_ERR_CONC_STARTMB_Y(x) (((x) & 0xff) << 0) +#define VDPU_REG_DEC_FORMAT 0x0d4 +#define VDPU_REG_DEC_CTRL0_DEC_MODE(x) (((x) & 0xf) << 0) +#define VDPU_REG_DATA_ENDIAN 0x0d8 +#define VDPU_REG_CONFIG_DEC_STRENDIAN_E BIT(5) +#define VDPU_REG_CONFIG_DEC_STRSWAP32_E BIT(4) +#define VDPU_REG_CONFIG_DEC_OUTSWAP32_E BIT(3) +#define VDPU_REG_CONFIG_DEC_INSWAP32_E BIT(2) +#define VDPU_REG_CONFIG_DEC_OUT_ENDIAN BIT(1) +#define VDPU_REG_CONFIG_DEC_IN_ENDIAN BIT(0) +#define VDPU_REG_INTERRUPT 0x0dc +#define VDPU_REG_INTERRUPT_DEC_TIMEOUT BIT(13) +#define VDPU_REG_INTERRUPT_DEC_ERROR_INT BIT(12) +#define VDPU_REG_INTERRUPT_DEC_PIC_INF BIT(10) +#define VDPU_REG_INTERRUPT_DEC_SLICE_INT BIT(9) +#define VDPU_REG_INTERRUPT_DEC_ASO_INT BIT(8) +#define VDPU_REG_INTERRUPT_DEC_BUFFER_INT BIT(6) +#define VDPU_REG_INTERRUPT_DEC_BUS_INT BIT(5) +#define VDPU_REG_INTERRUPT_DEC_RDY_INT BIT(4) +#define VDPU_REG_INTERRUPT_DEC_IRQ_DIS BIT(1) +#define VDPU_REG_INTERRUPT_DEC_IRQ BIT(0) +#define VDPU_REG_AXI_CTRL 0x0e0 +#define VDPU_REG_AXI_DEC_SEL BIT(23) +#define VDPU_REG_CONFIG_DEC_DATA_DISC_E BIT(22) +#define VDPU_REG_PARAL_BUS_E(x) BIT(21) +#define VDPU_REG_CONFIG_DEC_MAX_BURST(x) (((x) & 0x1f) << 16) +#define VDPU_REG_DEC_CTRL0_DEC_AXI_WR_ID(x) (((x) & 0xff) << 8) +#define VDPU_REG_CONFIG_DEC_AXI_RD_ID(x) (((x) & 0xff) << 0) +#define VDPU_REG_EN_FLAGS 0x0e4 +#define VDPU_REG_AHB_HLOCK_E BIT(31) +#define VDPU_REG_CACHE_E BIT(29) +#define VDPU_REG_PREFETCH_SINGLE_CHANNEL_E BIT(28) +#define VDPU_REG_INTRA_3_CYCLE_ENHANCE BIT(27) +#define VDPU_REG_INTRA_DOUBLE_SPEED BIT(26) +#define VDPU_REG_INTER_DOUBLE_SPEED BIT(25) +#define VDPU_REG_DEC_CTRL3_START_CODE_E BIT(22) +#define VDPU_REG_DEC_CTRL3_CH_8PIX_ILEAV_E BIT(21) +#define VDPU_REG_DEC_CTRL0_RLC_MODE_E BIT(20) +#define VDPU_REG_DEC_CTRL0_DIVX3_E BIT(19) +#define VDPU_REG_DEC_CTRL0_PJPEG_E BIT(18) +#define VDPU_REG_DEC_CTRL0_PIC_INTERLACE_E BIT(17) +#define VDPU_REG_DEC_CTRL0_PIC_FIELDMODE_E BIT(16) +#define VDPU_REG_DEC_CTRL0_PIC_B_E BIT(15) +#define VDPU_REG_DEC_CTRL0_PIC_INTER_E BIT(14) +#define VDPU_REG_DEC_CTRL0_PIC_TOPFIELD_E BIT(13) +#define VDPU_REG_DEC_CTRL0_FWD_INTERLACE_E BIT(12) +#define VDPU_REG_DEC_CTRL0_SORENSON_E BIT(11) +#define VDPU_REG_DEC_CTRL0_WRITE_MVS_E BIT(10) +#define VDPU_REG_DEC_CTRL0_REF_TOPFIELD_E BIT(9) +#define VDPU_REG_DEC_CTRL0_REFTOPFIRST_E BIT(8) +#define VDPU_REG_DEC_CTRL0_SEQ_MBAFF_E BIT(7) +#define VDPU_REG_DEC_CTRL0_PICORD_COUNT_E BIT(6) +#define VDPU_REG_CONFIG_DEC_TIMEOUT_E BIT(5) +#define VDPU_REG_CONFIG_DEC_CLK_GATE_E BIT(4) +#define VDPU_REG_DEC_CTRL0_DEC_OUT_DIS BIT(2) +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_BUF_E BIT(1) +#define VDPU_REG_INTERRUPT_DEC_E BIT(0) +#define VDPU_REG_SOFT_RESET 0x0e8 +#define VDPU_REG_PRED_FLT 0x0ec +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_0(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_1(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_2(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_ADDITIONAL_CHROMA_ADDRESS 0x0f0 +#define VDPU_REG_ADDR_QTABLE 0x0f4 +#define VDPU_REG_DIRECT_MV_ADDR 0x0f8 +#define VDPU_REG_ADDR_DST 0x0fc +#define VDPU_REG_ADDR_STR 0x100 +#define VDPU_REG_REFBUF_RELATED 0x104 +#define VDPU_REG_FWD_PIC(i) (0x128 + ((i) * 0x4)) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F5(x) (((x) & 0x1f) << 25) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F4(x) (((x) & 0x1f) << 20) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_REF_PIC(i) (0x130 + ((i) * 0x4)) +#define VDPU_REG_REF_PIC_REFER1_NBR(x) (((x) & 0xffff) << 16) +#define VDPU_REG_REF_PIC_REFER0_NBR(x) (((x) & 0xffff) << 0) +#define VDPU_REG_H264_ADDR_REF(i) (0x150 + ((i) * 0x4)) +#define VDPU_REG_ADDR_REF_FIELD_E BIT(1) +#define VDPU_REG_ADDR_REF_TOPC_E BIT(0) +#define VDPU_REG_INITIAL_REF_PIC_LIST0 0x190 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F5(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F4(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST1 0x194 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F11(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F10(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F9(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F8(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F7(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F6(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST2 0x198 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F15(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F14(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F13(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F12(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST3 0x19c +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B5(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B4(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST4 0x1a0 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B11(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B10(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B9(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B8(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B7(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B6(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST5 0x1a4 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B15(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B14(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B13(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B12(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST6 0x1a8 +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_LT_REF 0x1ac +#define VDPU_REG_VALID_REF 0x1b0 +#define VDPU_REG_H264_PIC_MB_SIZE 0x1b8 +#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET2(x) (((x) & 0x1f) << 22) +#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET(x) (((x) & 0x1f) << 17) +#define VDPU_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(x) (((x) & 0xff) << 9) +#define VDPU_REG_DEC_CTRL1_PIC_MB_WIDTH(x) (((x) & 0x1ff) << 0) +#define VDPU_REG_H264_CTRL 0x1bc +#define VDPU_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(x) (((x) & 0x3) << 16) +#define VDPU_REG_DEC_CTRL1_REF_FRAMES(x) (((x) & 0x1f) << 0) +#define VDPU_REG_CURRENT_FRAME 0x1c0 +#define VDPU_REG_DEC_CTRL5_FILT_CTRL_PRES BIT(31) +#define VDPU_REG_DEC_CTRL5_RDPIC_CNT_PRES BIT(30) +#define VDPU_REG_DEC_CTRL4_FRAMENUM_LEN(x) (((x) & 0x1f) << 16) +#define VDPU_REG_DEC_CTRL4_FRAMENUM(x) (((x) & 0xffff) << 0) +#define VDPU_REG_REF_FRAME 0x1c4 +#define VDPU_REG_DEC_CTRL5_REFPIC_MK_LEN(x) (((x) & 0x7ff) << 16) +#define VDPU_REG_DEC_CTRL5_IDR_PIC_ID(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL6 0x1c8 +#define VDPU_REG_DEC_CTRL6_PPS_ID(x) (((x) & 0xff) << 24) +#define VDPU_REG_DEC_CTRL6_REFIDX1_ACTIVE(x) (((x) & 0x1f) << 19) +#define VDPU_REG_DEC_CTRL6_REFIDX0_ACTIVE(x) (((x) & 0x1f) << 14) +#define VDPU_REG_DEC_CTRL6_POC_LENGTH(x) (((x) & 0xff) << 0) +#define VDPU_REG_ENABLE_FLAG 0x1cc +#define VDPU_REG_DEC_CTRL5_IDR_PIC_E BIT(8) +#define VDPU_REG_DEC_CTRL4_DIR_8X8_INFER_E BIT(7) +#define VDPU_REG_DEC_CTRL4_BLACKWHITE_E BIT(6) +#define VDPU_REG_DEC_CTRL4_CABAC_E BIT(5) +#define VDPU_REG_DEC_CTRL4_WEIGHT_PRED_E BIT(4) +#define VDPU_REG_DEC_CTRL5_CONST_INTRA_E BIT(3) +#define VDPU_REG_DEC_CTRL5_8X8TRANS_FLAG_E BIT(2) +#define VDPU_REG_DEC_CTRL2_TYPE1_QUANT_E BIT(1) +#define VDPU_REG_DEC_CTRL2_FIELDPIC_FLAG_E BIT(0) +#define VDPU_REG_VP8_PIC_MB_SIZE 0x1e0 +#define VDPU_REG_DEC_PIC_MB_WIDTH(x) (((x) & 0x1ff) << 23) +#define VDPU_REG_DEC_MB_WIDTH_OFF(x) (((x) & 0xf) << 19) +#define VDPU_REG_DEC_PIC_MB_HEIGHT_P(x) (((x) & 0xff) << 11) +#define VDPU_REG_DEC_MB_HEIGHT_OFF(x) (((x) & 0xf) << 7) +#define VDPU_REG_DEC_CTRL1_PIC_MB_W_EXT(x) (((x) & 0x7) << 3) +#define VDPU_REG_DEC_CTRL1_PIC_MB_H_EXT(x) (((x) & 0x7) << 0) +#define VDPU_REG_VP8_DCT_START_BIT 0x1e4 +#define VDPU_REG_DEC_CTRL4_DCT1_START_BIT(x) (((x) & 0x3f) << 26) +#define VDPU_REG_DEC_CTRL4_DCT2_START_BIT(x) (((x) & 0x3f) << 20) +#define VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT BIT(13) +#define VDPU_REG_DEC_CTRL4_BILIN_MC_E BIT(12) +#define VDPU_REG_VP8_CTRL0 0x1e8 +#define VDPU_REG_DEC_CTRL2_STRM_START_BIT(x) (((x) & 0x3f) << 26) +#define VDPU_REG_DEC_CTRL2_STRM1_START_BIT(x) (((x) & 0x3f) << 18) +#define VDPU_REG_DEC_CTRL2_BOOLEAN_VALUE(x) (((x) & 0xff) << 8) +#define VDPU_REG_DEC_CTRL2_BOOLEAN_RANGE(x) (((x) & 0xff) << 0) +#define VDPU_REG_VP8_DATA_VAL 0x1f0 +#define VDPU_REG_DEC_CTRL6_COEFFS_PART_AM(x) (((x) & 0xf) << 24) +#define VDPU_REG_DEC_CTRL6_STREAM1_LEN(x) (((x) & 0xffffff) << 0) +#define VDPU_REG_PRED_FLT7 0x1f4 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_1(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_2(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_3(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT8 0x1f8 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_0(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_1(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_2(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT9 0x1fc +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_3(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_0(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_1(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT10 0x200 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_2(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_3(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_M1(x) (((x) & 0x3) << 10) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_4(x) (((x) & 0x3) << 8) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_M1(x) (((x) & 0x3) << 6) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_4(x) (((x) & 0x3) << 4) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_M1(x) (((x) & 0x3) << 2) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_4(x) (((x) & 0x3) << 0) +#define VDPU_REG_FILTER_LEVEL 0x204 +#define VDPU_REG_REF_PIC_LF_LEVEL_0(x) (((x) & 0x3f) << 18) +#define VDPU_REG_REF_PIC_LF_LEVEL_1(x) (((x) & 0x3f) << 12) +#define VDPU_REG_REF_PIC_LF_LEVEL_2(x) (((x) & 0x3f) << 6) +#define VDPU_REG_REF_PIC_LF_LEVEL_3(x) (((x) & 0x3f) << 0) +#define VDPU_REG_VP8_QUANTER0 0x208 +#define VDPU_REG_REF_PIC_QUANT_DELTA_0(x) (((x) & 0x1f) << 27) +#define VDPU_REG_REF_PIC_QUANT_DELTA_1(x) (((x) & 0x1f) << 22) +#define VDPU_REG_REF_PIC_QUANT_0(x) (((x) & 0x7ff) << 11) +#define VDPU_REG_REF_PIC_QUANT_1(x) (((x) & 0x7ff) << 0) +#define VDPU_REG_VP8_ADDR_REF0 0x20c +#define VDPU_REG_FILTER_MB_ADJ 0x210 +#define VDPU_REG_REF_PIC_FILT_TYPE_E BIT(31) +#define VDPU_REG_REF_PIC_FILT_SHARPNESS(x) (((x) & 0x7) << 28) +#define VDPU_REG_FILT_MB_ADJ_0(x) (((x) & 0x7f) << 21) +#define VDPU_REG_FILT_MB_ADJ_1(x) (((x) & 0x7f) << 14) +#define VDPU_REG_FILT_MB_ADJ_2(x) (((x) & 0x7f) << 7) +#define VDPU_REG_FILT_MB_ADJ_3(x) (((x) & 0x7f) << 0) +#define VDPU_REG_FILTER_REF_ADJ 0x214 +#define VDPU_REG_REF_PIC_ADJ_0(x) (((x) & 0x7f) << 21) +#define VDPU_REG_REF_PIC_ADJ_1(x) (((x) & 0x7f) << 14) +#define VDPU_REG_REF_PIC_ADJ_2(x) (((x) & 0x7f) << 7) +#define VDPU_REG_REF_PIC_ADJ_3(x) (((x) & 0x7f) << 0) +#define VDPU_REG_VP8_ADDR_REF2_5(i) (0x218 + ((i) * 0x4)) +#define VDPU_REG_VP8_GREF_SIGN_BIAS BIT(0) +#define VDPU_REG_VP8_AREF_SIGN_BIAS BIT(0) +#define VDPU_REG_VP8_DCT_BASE(i) (0x230 + ((i) * 0x4)) +#define VDPU_REG_VP8_ADDR_CTRL_PART 0x244 +#define VDPU_REG_VP8_ADDR_REF1 0x250 +#define VDPU_REG_VP8_SEGMENT_VAL 0x254 +#define VDPU_REG_FWD_PIC1_SEGMENT_BASE(x) ((x) << 0) +#define VDPU_REG_FWD_PIC1_SEGMENT_UPD_E BIT(1) +#define VDPU_REG_FWD_PIC1_SEGMENT_E BIT(0) +#define VDPU_REG_VP8_DCT_START_BIT2 0x258 +#define VDPU_REG_DEC_CTRL7_DCT3_START_BIT(x) (((x) & 0x3f) << 24) +#define VDPU_REG_DEC_CTRL7_DCT4_START_BIT(x) (((x) & 0x3f) << 18) +#define VDPU_REG_DEC_CTRL7_DCT5_START_BIT(x) (((x) & 0x3f) << 12) +#define VDPU_REG_DEC_CTRL7_DCT6_START_BIT(x) (((x) & 0x3f) << 6) +#define VDPU_REG_DEC_CTRL7_DCT7_START_BIT(x) (((x) & 0x3f) << 0) +#define VDPU_REG_VP8_QUANTER1 0x25c +#define VDPU_REG_REF_PIC_QUANT_DELTA_2(x) (((x) & 0x1f) << 27) +#define VDPU_REG_REF_PIC_QUANT_DELTA_3(x) (((x) & 0x1f) << 22) +#define VDPU_REG_REF_PIC_QUANT_2(x) (((x) & 0x7ff) << 11) +#define VDPU_REG_REF_PIC_QUANT_3(x) (((x) & 0x7ff) << 0) +#define VDPU_REG_VP8_QUANTER2 0x260 +#define VDPU_REG_REF_PIC_QUANT_DELTA_4(x) (((x) & 0x1f) << 27) +#define VDPU_REG_REF_PIC_QUANT_4(x) (((x) & 0x7ff) << 11) +#define VDPU_REG_REF_PIC_QUANT_5(x) (((x) & 0x7ff) << 0) +#define VDPU_REG_PRED_FLT1 0x264 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_3(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_0(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_1(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT2 0x268 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_2(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_3(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_0(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT3 0x26c +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_1(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_2(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_3(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT4 0x270 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_0(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_1(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_2(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT5 0x274 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_3(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_0(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_1(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT6 0x278 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_2(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_3(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_0(x) (((x) & 0x3ff) << 2) + +#endif /* RK3399_VPU_REGS_H_ */ diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu.h b/drivers/staging/media/rockchip/vpu/rockchip_vpu.h new file mode 100644 index 000000000000..1ec2be483e27 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu.h @@ -0,0 +1,232 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip VPU codec driver + * + * Copyright 2018 Google LLC. + * Tomasz Figa <tfiga@chromium.org> + * + * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. + * Copyright (C) 2011 Samsung Electronics Co., Ltd. + */ + +#ifndef ROCKCHIP_VPU_H_ +#define ROCKCHIP_VPU_H_ + +#include <linux/platform_device.h> +#include <linux/videodev2.h> +#include <linux/wait.h> +#include <linux/clk.h> + +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-ioctl.h> +#include <media/videobuf2-core.h> +#include <media/videobuf2-dma-contig.h> + +#include "rockchip_vpu_hw.h" + +#define ROCKCHIP_VPU_MAX_CLOCKS 4 + +#define JPEG_MB_DIM 16 +#define JPEG_MB_WIDTH(w) DIV_ROUND_UP(w, JPEG_MB_DIM) +#define JPEG_MB_HEIGHT(h) DIV_ROUND_UP(h, JPEG_MB_DIM) + +struct rockchip_vpu_ctx; +struct rockchip_vpu_codec_ops; + +#define RK_VPU_CODEC_JPEG BIT(0) + +/** + * struct rockchip_vpu_variant - information about VPU hardware variant + * + * @enc_offset: Offset from VPU base to encoder registers. + * @enc_fmts: Encoder formats. + * @num_enc_fmts: Number of encoder formats. + * @codec: Supported codecs + * @codec_ops: Codec ops. + * @init: Initialize hardware. + * @vepu_irq: encoder interrupt handler + * @clk_names: array of clock names + * @num_clocks: number of clocks in the array + */ +struct rockchip_vpu_variant { + unsigned int enc_offset; + const struct rockchip_vpu_fmt *enc_fmts; + unsigned int num_enc_fmts; + unsigned int codec; + const struct rockchip_vpu_codec_ops *codec_ops; + int (*init)(struct rockchip_vpu_dev *vpu); + irqreturn_t (*vepu_irq)(int irq, void *priv); + const char *clk_names[ROCKCHIP_VPU_MAX_CLOCKS]; + int num_clocks; +}; + +/** + * enum rockchip_vpu_codec_mode - codec operating mode. + * @RK_VPU_MODE_NONE: No operating mode. Used for RAW video formats. + * @RK_VPU_MODE_JPEG_ENC: JPEG encoder. + */ +enum rockchip_vpu_codec_mode { + RK_VPU_MODE_NONE = -1, + RK_VPU_MODE_JPEG_ENC, +}; + +/** + * struct rockchip_vpu_dev - driver data + * @v4l2_dev: V4L2 device to register video devices for. + * @m2m_dev: mem2mem device associated to this device. + * @mdev: media device associated to this device. + * @vfd_enc: Video device for encoder. + * @pdev: Pointer to VPU platform device. + * @dev: Pointer to device for convenient logging using + * dev_ macros. + * @clocks: Array of clock handles. + * @base: Mapped address of VPU registers. + * @enc_base: Mapped address of VPU encoder register for convenience. + * @vpu_mutex: Mutex to synchronize V4L2 calls. + * @irqlock: Spinlock to synchronize access to data structures + * shared with interrupt handlers. + * @variant: Hardware variant-specific parameters. + * @watchdog_work: Delayed work for hardware timeout handling. + */ +struct rockchip_vpu_dev { + struct v4l2_device v4l2_dev; + struct v4l2_m2m_dev *m2m_dev; + struct media_device mdev; + struct video_device *vfd_enc; + struct platform_device *pdev; + struct device *dev; + struct clk_bulk_data clocks[ROCKCHIP_VPU_MAX_CLOCKS]; + void __iomem *base; + void __iomem *enc_base; + + struct mutex vpu_mutex; /* video_device lock */ + spinlock_t irqlock; + const struct rockchip_vpu_variant *variant; + struct delayed_work watchdog_work; +}; + +/** + * struct rockchip_vpu_ctx - Context (instance) private data. + * + * @dev: VPU driver data to which the context belongs. + * @fh: V4L2 file handler. + * + * @sequence_cap: Sequence counter for capture queue + * @sequence_out: Sequence counter for output queue + * + * @vpu_src_fmt: Descriptor of active source format. + * @src_fmt: V4L2 pixel format of active source format. + * @vpu_dst_fmt: Descriptor of active destination format. + * @dst_fmt: V4L2 pixel format of active destination format. + * + * @ctrl_handler: Control handler used to register controls. + * @jpeg_quality: User-specified JPEG compression quality. + * + * @codec_ops: Set of operations related to codec mode. + * + * @bounce_dma_addr: Bounce buffer bus address. + * @bounce_buf: Bounce buffer pointer. + * @bounce_size: Bounce buffer size. + */ +struct rockchip_vpu_ctx { + struct rockchip_vpu_dev *dev; + struct v4l2_fh fh; + + u32 sequence_cap; + u32 sequence_out; + + const struct rockchip_vpu_fmt *vpu_src_fmt; + struct v4l2_pix_format_mplane src_fmt; + const struct rockchip_vpu_fmt *vpu_dst_fmt; + struct v4l2_pix_format_mplane dst_fmt; + + struct v4l2_ctrl_handler ctrl_handler; + int jpeg_quality; + + const struct rockchip_vpu_codec_ops *codec_ops; + + dma_addr_t bounce_dma_addr; + void *bounce_buf; + size_t bounce_size; +}; + +/** + * struct rockchip_vpu_fmt - information about supported video formats. + * @name: Human readable name of the format. + * @fourcc: FourCC code of the format. See V4L2_PIX_FMT_*. + * @codec_mode: Codec mode related to this format. See + * enum rockchip_vpu_codec_mode. + * @header_size: Optional header size. Currently used by JPEG encoder. + * @max_depth: Maximum depth, for bitstream formats + * @enc_fmt: Format identifier for encoder registers. + * @frmsize: Supported range of frame sizes (only for bitstream formats). + */ +struct rockchip_vpu_fmt { + char *name; + u32 fourcc; + enum rockchip_vpu_codec_mode codec_mode; + int header_size; + int max_depth; + enum rockchip_vpu_enc_fmt enc_fmt; + struct v4l2_frmsize_stepwise frmsize; +}; + +/* Logging helpers */ + +/** + * debug - Module parameter to control level of debugging messages. + * + * Level of debugging messages can be controlled by bits of + * module parameter called "debug". Meaning of particular + * bits is as follows: + * + * bit 0 - global information: mode, size, init, release + * bit 1 - each run start/result information + * bit 2 - contents of small controls from userspace + * bit 3 - contents of big controls from userspace + * bit 4 - detail fmt, ctrl, buffer q/dq information + * bit 5 - detail function enter/leave trace information + * bit 6 - register write/read information + */ +extern int rockchip_vpu_debug; + +#define vpu_debug(level, fmt, args...) \ + do { \ + if (rockchip_vpu_debug & BIT(level)) \ + pr_info("%s:%d: " fmt, \ + __func__, __LINE__, ##args); \ + } while (0) + +#define vpu_err(fmt, args...) \ + pr_err("%s:%d: " fmt, __func__, __LINE__, ##args) + +/* Structure access helpers. */ +static inline struct rockchip_vpu_ctx *fh_to_ctx(struct v4l2_fh *fh) +{ + return container_of(fh, struct rockchip_vpu_ctx, fh); +} + +/* Register accessors. */ +static inline void vepu_write_relaxed(struct rockchip_vpu_dev *vpu, + u32 val, u32 reg) +{ + vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); + writel_relaxed(val, vpu->enc_base + reg); +} + +static inline void vepu_write(struct rockchip_vpu_dev *vpu, u32 val, u32 reg) +{ + vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); + writel(val, vpu->enc_base + reg); +} + +static inline u32 vepu_read(struct rockchip_vpu_dev *vpu, u32 reg) +{ + u32 val = readl(vpu->enc_base + reg); + + vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); + return val; +} + +#endif /* ROCKCHIP_VPU_H_ */ diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_common.h b/drivers/staging/media/rockchip/vpu/rockchip_vpu_common.h new file mode 100644 index 000000000000..ca77668d9579 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_common.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip VPU codec driver + * + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Alpha Lin <Alpha.Lin@rock-chips.com> + * Jeffy Chen <jeffy.chen@rock-chips.com> + * + * Copyright 2018 Google LLC. + * Tomasz Figa <tfiga@chromium.org> + * + * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. + * Copyright (C) 2011 Samsung Electronics Co., Ltd. + */ + +#ifndef ROCKCHIP_VPU_COMMON_H_ +#define ROCKCHIP_VPU_COMMON_H_ + +#include "rockchip_vpu.h" + +extern const struct v4l2_ioctl_ops rockchip_vpu_enc_ioctl_ops; +extern const struct vb2_ops rockchip_vpu_enc_queue_ops; + +void rockchip_vpu_enc_reset_src_fmt(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx); +void rockchip_vpu_enc_reset_dst_fmt(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx); + +#endif /* ROCKCHIP_VPU_COMMON_H_ */ diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c b/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c new file mode 100644 index 000000000000..962412c79b91 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_drv.c @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip VPU codec driver + * + * Copyright (C) 2018 Collabora, Ltd. + * Copyright 2018 Google LLC. + * Tomasz Figa <tfiga@chromium.org> + * + * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. + * Copyright (C) 2011 Samsung Electronics Co., Ltd. + */ + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/pm_runtime.h> +#include <linux/slab.h> +#include <linux/videodev2.h> +#include <linux/workqueue.h> +#include <media/v4l2-event.h> +#include <media/v4l2-mem2mem.h> +#include <media/videobuf2-core.h> +#include <media/videobuf2-core.h> +#include <media/videobuf2-vmalloc.h> + +#include "rockchip_vpu_common.h" +#include "rockchip_vpu.h" +#include "rockchip_vpu_hw.h" + +#define DRIVER_NAME "rockchip-vpu" + +int rockchip_vpu_debug; +module_param_named(debug, rockchip_vpu_debug, int, 0644); +MODULE_PARM_DESC(debug, + "Debug level - higher value produces more verbose messages"); + +static void rockchip_vpu_job_finish(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx, + unsigned int bytesused, + enum vb2_buffer_state result) +{ + struct vb2_v4l2_buffer *src, *dst; + size_t avail_size; + + pm_runtime_mark_last_busy(vpu->dev); + pm_runtime_put_autosuspend(vpu->dev); + clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks); + + src = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + + if (WARN_ON(!src)) + return; + if (WARN_ON(!dst)) + return; + + src->sequence = ctx->sequence_out++; + dst->sequence = ctx->sequence_cap++; + + dst->field = src->field; + if (src->flags & V4L2_BUF_FLAG_TIMECODE) + dst->timecode = src->timecode; + dst->vb2_buf.timestamp = src->vb2_buf.timestamp; + dst->flags &= ~(V4L2_BUF_FLAG_TSTAMP_SRC_MASK | + V4L2_BUF_FLAG_TIMECODE); + dst->flags |= src->flags & (V4L2_BUF_FLAG_TSTAMP_SRC_MASK | + V4L2_BUF_FLAG_TIMECODE); + + avail_size = vb2_plane_size(&dst->vb2_buf, 0) - + ctx->vpu_dst_fmt->header_size; + if (bytesused <= avail_size) { + if (ctx->bounce_buf) { + memcpy(vb2_plane_vaddr(&dst->vb2_buf, 0) + + ctx->vpu_dst_fmt->header_size, + ctx->bounce_buf, bytesused); + } + dst->vb2_buf.planes[0].bytesused = + ctx->vpu_dst_fmt->header_size + bytesused; + } else { + result = VB2_BUF_STATE_ERROR; + } + + v4l2_m2m_buf_done(src, result); + v4l2_m2m_buf_done(dst, result); + + v4l2_m2m_job_finish(vpu->m2m_dev, ctx->fh.m2m_ctx); +} + +void rockchip_vpu_irq_done(struct rockchip_vpu_dev *vpu, + unsigned int bytesused, + enum vb2_buffer_state result) +{ + struct rockchip_vpu_ctx *ctx = + v4l2_m2m_get_curr_priv(vpu->m2m_dev); + + /* + * If cancel_delayed_work returns false + * the timeout expired. The watchdog is running, + * and will take care of finishing the job. + */ + if (cancel_delayed_work(&vpu->watchdog_work)) + rockchip_vpu_job_finish(vpu, ctx, bytesused, result); +} + +void rockchip_vpu_watchdog(struct work_struct *work) +{ + struct rockchip_vpu_dev *vpu; + struct rockchip_vpu_ctx *ctx; + + vpu = container_of(to_delayed_work(work), + struct rockchip_vpu_dev, watchdog_work); + ctx = v4l2_m2m_get_curr_priv(vpu->m2m_dev); + if (ctx) { + vpu_err("frame processing timed out!\n"); + ctx->codec_ops->reset(ctx); + rockchip_vpu_job_finish(vpu, ctx, 0, VB2_BUF_STATE_ERROR); + } +} + +static void device_run(void *priv) +{ + struct rockchip_vpu_ctx *ctx = priv; + int ret; + + ret = clk_bulk_enable(ctx->dev->variant->num_clocks, ctx->dev->clocks); + if (ret) + goto err_cancel_job; + ret = pm_runtime_get_sync(ctx->dev->dev); + if (ret < 0) + goto err_cancel_job; + + ctx->codec_ops->run(ctx); + return; + +err_cancel_job: + rockchip_vpu_job_finish(ctx->dev, ctx, 0, VB2_BUF_STATE_ERROR); +} + +static struct v4l2_m2m_ops vpu_m2m_ops = { + .device_run = device_run, +}; + +static int +enc_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) +{ + struct rockchip_vpu_ctx *ctx = priv; + int ret; + + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + src_vq->io_modes = VB2_MMAP | VB2_DMABUF; + src_vq->drv_priv = ctx; + src_vq->ops = &rockchip_vpu_enc_queue_ops; + src_vq->mem_ops = &vb2_dma_contig_memops; + + /* + * Driver does mostly sequential access, so sacrifice TLB efficiency + * for faster allocation. Also, no CPU access on the source queue, + * so no kernel mapping needed. + */ + src_vq->dma_attrs = DMA_ATTR_ALLOC_SINGLE_PAGES | + DMA_ATTR_NO_KERNEL_MAPPING; + src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + src_vq->lock = &ctx->dev->vpu_mutex; + src_vq->dev = ctx->dev->v4l2_dev.dev; + + ret = vb2_queue_init(src_vq); + if (ret) + return ret; + + /* + * The CAPTURE queue doesn't need dma memory, + * as the CPU needs to create the JPEG frames, + * from the hardware-produced JPEG payload. + * + * For the DMA destination buffer, we use + * a bounce buffer. + */ + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; + dst_vq->drv_priv = ctx; + dst_vq->ops = &rockchip_vpu_enc_queue_ops; + dst_vq->mem_ops = &vb2_vmalloc_memops; + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; + dst_vq->lock = &ctx->dev->vpu_mutex; + dst_vq->dev = ctx->dev->v4l2_dev.dev; + + return vb2_queue_init(dst_vq); +} + +static int rockchip_vpu_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct rockchip_vpu_ctx *ctx; + + ctx = container_of(ctrl->handler, + struct rockchip_vpu_ctx, ctrl_handler); + + vpu_debug(1, "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val); + + switch (ctrl->id) { + case V4L2_CID_JPEG_COMPRESSION_QUALITY: + ctx->jpeg_quality = ctrl->val; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct v4l2_ctrl_ops rockchip_vpu_ctrl_ops = { + .s_ctrl = rockchip_vpu_s_ctrl, +}; + +static int rockchip_vpu_ctrls_setup(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx) +{ + v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1); + if (vpu->variant->codec & RK_VPU_CODEC_JPEG) { + v4l2_ctrl_new_std(&ctx->ctrl_handler, &rockchip_vpu_ctrl_ops, + V4L2_CID_JPEG_COMPRESSION_QUALITY, + 5, 100, 1, 50); + if (ctx->ctrl_handler.error) { + vpu_err("Adding JPEG control failed %d\n", + ctx->ctrl_handler.error); + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + return ctx->ctrl_handler.error; + } + } + + return v4l2_ctrl_handler_setup(&ctx->ctrl_handler); +} + +/* + * V4L2 file operations. + */ + +static int rockchip_vpu_open(struct file *filp) +{ + struct rockchip_vpu_dev *vpu = video_drvdata(filp); + struct video_device *vdev = video_devdata(filp); + struct rockchip_vpu_ctx *ctx; + int ret; + + /* + * We do not need any extra locking here, because we operate only + * on local data here, except reading few fields from dev, which + * do not change through device's lifetime (which is guaranteed by + * reference on module from open()) and V4L2 internal objects (such + * as vdev and ctx->fh), which have proper locking done in respective + * helper functions used here. + */ + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->dev = vpu; + if (vdev == vpu->vfd_enc) + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(vpu->m2m_dev, ctx, + &enc_queue_init); + else + ctx->fh.m2m_ctx = ERR_PTR(-ENODEV); + if (IS_ERR(ctx->fh.m2m_ctx)) { + ret = PTR_ERR(ctx->fh.m2m_ctx); + kfree(ctx); + return ret; + } + + v4l2_fh_init(&ctx->fh, vdev); + filp->private_data = &ctx->fh; + v4l2_fh_add(&ctx->fh); + + if (vdev == vpu->vfd_enc) { + rockchip_vpu_enc_reset_dst_fmt(vpu, ctx); + rockchip_vpu_enc_reset_src_fmt(vpu, ctx); + } + + ret = rockchip_vpu_ctrls_setup(vpu, ctx); + if (ret) { + vpu_err("Failed to set up controls\n"); + goto err_fh_free; + } + ctx->fh.ctrl_handler = &ctx->ctrl_handler; + + return 0; + +err_fh_free: + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + kfree(ctx); + return ret; +} + +static int rockchip_vpu_release(struct file *filp) +{ + struct rockchip_vpu_ctx *ctx = + container_of(filp->private_data, struct rockchip_vpu_ctx, fh); + + /* + * No need for extra locking because this was the last reference + * to this file. + */ + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + kfree(ctx); + + return 0; +} + +static const struct v4l2_file_operations rockchip_vpu_fops = { + .owner = THIS_MODULE, + .open = rockchip_vpu_open, + .release = rockchip_vpu_release, + .poll = v4l2_m2m_fop_poll, + .unlocked_ioctl = video_ioctl2, + .mmap = v4l2_m2m_fop_mmap, +}; + +static const struct of_device_id of_rockchip_vpu_match[] = { + { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, + { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_rockchip_vpu_match); + +static int rockchip_vpu_video_device_register(struct rockchip_vpu_dev *vpu) +{ + const struct of_device_id *match; + struct video_device *vfd; + int function, ret; + + match = of_match_node(of_rockchip_vpu_match, vpu->dev->of_node); + vfd = video_device_alloc(); + if (!vfd) { + v4l2_err(&vpu->v4l2_dev, "Failed to allocate video device\n"); + return -ENOMEM; + } + + vfd->fops = &rockchip_vpu_fops; + vfd->release = video_device_release; + vfd->lock = &vpu->vpu_mutex; + vfd->v4l2_dev = &vpu->v4l2_dev; + vfd->vfl_dir = VFL_DIR_M2M; + vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; + vfd->ioctl_ops = &rockchip_vpu_enc_ioctl_ops; + snprintf(vfd->name, sizeof(vfd->name), "%s-enc", match->compatible); + vpu->vfd_enc = vfd; + video_set_drvdata(vfd, vpu); + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); + if (ret) { + v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n"); + goto err_free_dev; + } + v4l2_info(&vpu->v4l2_dev, "registered as /dev/video%d\n", vfd->num); + + function = MEDIA_ENT_F_PROC_VIDEO_ENCODER; + ret = v4l2_m2m_register_media_controller(vpu->m2m_dev, vfd, function); + if (ret) { + v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem media controller\n"); + goto err_unreg_video; + } + return 0; + +err_unreg_video: + video_unregister_device(vfd); +err_free_dev: + video_device_release(vfd); + return ret; +} + +static int rockchip_vpu_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + struct rockchip_vpu_dev *vpu; + struct resource *res; + int i, ret; + + vpu = devm_kzalloc(&pdev->dev, sizeof(*vpu), GFP_KERNEL); + if (!vpu) + return -ENOMEM; + + vpu->dev = &pdev->dev; + vpu->pdev = pdev; + mutex_init(&vpu->vpu_mutex); + spin_lock_init(&vpu->irqlock); + + match = of_match_node(of_rockchip_vpu_match, pdev->dev.of_node); + vpu->variant = match->data; + + INIT_DELAYED_WORK(&vpu->watchdog_work, rockchip_vpu_watchdog); + + for (i = 0; i < vpu->variant->num_clocks; i++) + vpu->clocks[i].id = vpu->variant->clk_names[i]; + ret = devm_clk_bulk_get(&pdev->dev, vpu->variant->num_clocks, + vpu->clocks); + if (ret) + return ret; + + res = platform_get_resource(vpu->pdev, IORESOURCE_MEM, 0); + vpu->base = devm_ioremap_resource(vpu->dev, res); + if (IS_ERR(vpu->base)) + return PTR_ERR(vpu->base); + vpu->enc_base = vpu->base + vpu->variant->enc_offset; + + ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(vpu->dev, "Could not set DMA coherent mask.\n"); + return ret; + } + + if (vpu->variant->vepu_irq) { + int irq; + + irq = platform_get_irq_byname(vpu->pdev, "vepu"); + if (irq <= 0) { + dev_err(vpu->dev, "Could not get vepu IRQ.\n"); + return -ENXIO; + } + + ret = devm_request_irq(vpu->dev, irq, vpu->variant->vepu_irq, + 0, dev_name(vpu->dev), vpu); + if (ret) { + dev_err(vpu->dev, "Could not request vepu IRQ.\n"); + return ret; + } + } + + ret = vpu->variant->init(vpu); + if (ret) { + dev_err(&pdev->dev, "Failed to init VPU hardware\n"); + return ret; + } + + pm_runtime_set_autosuspend_delay(vpu->dev, 100); + pm_runtime_use_autosuspend(vpu->dev); + pm_runtime_enable(vpu->dev); + + ret = clk_bulk_prepare(vpu->variant->num_clocks, vpu->clocks); + if (ret) { + dev_err(&pdev->dev, "Failed to prepare clocks\n"); + return ret; + } + + ret = v4l2_device_register(&pdev->dev, &vpu->v4l2_dev); + if (ret) { + dev_err(&pdev->dev, "Failed to register v4l2 device\n"); + goto err_clk_unprepare; + } + platform_set_drvdata(pdev, vpu); + + vpu->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops); + if (IS_ERR(vpu->m2m_dev)) { + v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem device\n"); + ret = PTR_ERR(vpu->m2m_dev); + goto err_v4l2_unreg; + } + + vpu->mdev.dev = vpu->dev; + strlcpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model)); + media_device_init(&vpu->mdev); + vpu->v4l2_dev.mdev = &vpu->mdev; + + ret = rockchip_vpu_video_device_register(vpu); + if (ret) { + dev_err(&pdev->dev, "Failed to register encoder\n"); + goto err_m2m_rel; + } + + ret = media_device_register(&vpu->mdev); + if (ret) { + v4l2_err(&vpu->v4l2_dev, "Failed to register mem2mem media device\n"); + goto err_video_dev_unreg; + } + return 0; +err_video_dev_unreg: + if (vpu->vfd_enc) { + video_unregister_device(vpu->vfd_enc); + video_device_release(vpu->vfd_enc); + } +err_m2m_rel: + v4l2_m2m_release(vpu->m2m_dev); +err_v4l2_unreg: + v4l2_device_unregister(&vpu->v4l2_dev); +err_clk_unprepare: + clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); + pm_runtime_disable(vpu->dev); + return ret; +} + +static int rockchip_vpu_remove(struct platform_device *pdev) +{ + struct rockchip_vpu_dev *vpu = platform_get_drvdata(pdev); + + v4l2_info(&vpu->v4l2_dev, "Removing %s\n", pdev->name); + + media_device_unregister(&vpu->mdev); + v4l2_m2m_unregister_media_controller(vpu->m2m_dev); + v4l2_m2m_release(vpu->m2m_dev); + media_device_cleanup(&vpu->mdev); + if (vpu->vfd_enc) { + video_unregister_device(vpu->vfd_enc); + video_device_release(vpu->vfd_enc); + } + v4l2_device_unregister(&vpu->v4l2_dev); + clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); + pm_runtime_disable(vpu->dev); + return 0; +} + +static const struct dev_pm_ops rockchip_vpu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +static struct platform_driver rockchip_vpu_driver = { + .probe = rockchip_vpu_probe, + .remove = rockchip_vpu_remove, + .driver = { + .name = DRIVER_NAME, + .of_match_table = of_match_ptr(of_rockchip_vpu_match), + .pm = &rockchip_vpu_pm_ops, + }, +}; +module_platform_driver(rockchip_vpu_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Alpha Lin <Alpha.Lin@Rock-Chips.com>"); +MODULE_AUTHOR("Tomasz Figa <tfiga@chromium.org>"); +MODULE_AUTHOR("Ezequiel Garcia <ezequiel@collabora.com>"); +MODULE_DESCRIPTION("Rockchip VPU codec driver"); diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c b/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c new file mode 100644 index 000000000000..ab0fb2053620 --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_enc.c @@ -0,0 +1,670 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip VPU codec driver + * + * Copyright (C) 2018 Collabora, Ltd. + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + * Alpha Lin <Alpha.Lin@rock-chips.com> + * Jeffy Chen <jeffy.chen@rock-chips.com> + * + * Copyright 2018 Google LLC. + * Tomasz Figa <tfiga@chromium.org> + * + * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. + * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. + */ + +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> +#include <linux/videodev2.h> +#include <linux/workqueue.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-event.h> +#include <media/v4l2-mem2mem.h> +#include <media/videobuf2-core.h> +#include <media/videobuf2-dma-sg.h> + +#include "rockchip_vpu.h" +#include "rockchip_vpu_hw.h" +#include "rockchip_vpu_common.h" + +/** + * struct v4l2_format_info - information about a V4L2 format + * @format: 4CC format identifier (V4L2_PIX_FMT_*) + * @header_size: Size of header, optional and used by compressed formats + * @num_planes: Number of planes (1 to 3) + * @cpp: Number of bytes per pixel (per plane) + * @hsub: Horizontal chroma subsampling factor + * @vsub: Vertical chroma subsampling factor + * @is_compressed: Is it a compressed format? + * @multiplanar: Is it a multiplanar variant format? (e.g. NV12M) + */ +struct v4l2_format_info { + u32 format; + u32 header_size; + u8 num_planes; + u8 cpp[3]; + u8 hsub; + u8 vsub; + u8 is_compressed; + u8 multiplanar; +}; + +static const struct v4l2_format_info * +v4l2_format_info(u32 format) +{ + static const struct v4l2_format_info formats[] = { + { .format = V4L2_PIX_FMT_YUV420M, .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .multiplanar = 1 }, + { .format = V4L2_PIX_FMT_NV12M, .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .multiplanar = 1 }, + { .format = V4L2_PIX_FMT_YUYV, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 }, + { .format = V4L2_PIX_FMT_UYVY, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1 }, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(formats); ++i) { + if (formats[i].format == format) + return &formats[i]; + } + + vpu_err("Unsupported V4L 4CC format (%08x)\n", format); + return NULL; +} + +static void +fill_pixfmt_mp(struct v4l2_pix_format_mplane *pixfmt, + int pixelformat, int width, int height) +{ + const struct v4l2_format_info *info; + struct v4l2_plane_pix_format *plane; + int i; + + info = v4l2_format_info(pixelformat); + if (!info) + return; + + pixfmt->width = width; + pixfmt->height = height; + pixfmt->pixelformat = pixelformat; + + if (!info->multiplanar) { + pixfmt->num_planes = 1; + plane = &pixfmt->plane_fmt[0]; + plane->bytesperline = info->is_compressed ? + 0 : width * info->cpp[0]; + plane->sizeimage = info->header_size; + for (i = 0; i < info->num_planes; i++) { + unsigned int hsub = (i == 0) ? 1 : info->hsub; + unsigned int vsub = (i == 0) ? 1 : info->vsub; + + plane->sizeimage += info->cpp[i] * + DIV_ROUND_UP(width, hsub) * + DIV_ROUND_UP(height, vsub); + } + } else { + pixfmt->num_planes = info->num_planes; + for (i = 0; i < info->num_planes; i++) { + unsigned int hsub = (i == 0) ? 1 : info->hsub; + unsigned int vsub = (i == 0) ? 1 : info->vsub; + + plane = &pixfmt->plane_fmt[i]; + plane->bytesperline = + info->cpp[i] * DIV_ROUND_UP(width, hsub); + plane->sizeimage = + plane->bytesperline * DIV_ROUND_UP(height, vsub); + } + } +} + +static const struct rockchip_vpu_fmt * +rockchip_vpu_find_format(struct rockchip_vpu_ctx *ctx, u32 fourcc) +{ + struct rockchip_vpu_dev *dev = ctx->dev; + const struct rockchip_vpu_fmt *formats; + unsigned int num_fmts, i; + + formats = dev->variant->enc_fmts; + num_fmts = dev->variant->num_enc_fmts; + for (i = 0; i < num_fmts; i++) + if (formats[i].fourcc == fourcc) + return &formats[i]; + return NULL; +} + +static const struct rockchip_vpu_fmt * +rockchip_vpu_get_default_fmt(struct rockchip_vpu_ctx *ctx, bool bitstream) +{ + struct rockchip_vpu_dev *dev = ctx->dev; + const struct rockchip_vpu_fmt *formats; + unsigned int num_fmts, i; + + formats = dev->variant->enc_fmts; + num_fmts = dev->variant->num_enc_fmts; + for (i = 0; i < num_fmts; i++) { + if (bitstream == (formats[i].codec_mode != RK_VPU_MODE_NONE)) + return &formats[i]; + } + return NULL; +} + +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct rockchip_vpu_dev *vpu = video_drvdata(file); + + strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver)); + strscpy(cap->card, vpu->vfd_enc->name, sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s", + vpu->dev->driver->name); + return 0; +} + +static int vidioc_enum_framesizes(struct file *file, void *priv, + struct v4l2_frmsizeenum *fsize) +{ + struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); + const struct rockchip_vpu_fmt *fmt; + + if (fsize->index != 0) { + vpu_debug(0, "invalid frame size index (expected 0, got %d)\n", + fsize->index); + return -EINVAL; + } + + fmt = rockchip_vpu_find_format(ctx, fsize->pixel_format); + if (!fmt) { + vpu_debug(0, "unsupported bitstream format (%08x)\n", + fsize->pixel_format); + return -EINVAL; + } + + /* This only makes sense for coded formats */ + if (fmt->codec_mode == RK_VPU_MODE_NONE) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; + fsize->stepwise = fmt->frmsize; + + return 0; +} + +static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct rockchip_vpu_dev *dev = video_drvdata(file); + const struct rockchip_vpu_fmt *fmt; + const struct rockchip_vpu_fmt *formats; + int num_fmts, i, j = 0; + + formats = dev->variant->enc_fmts; + num_fmts = dev->variant->num_enc_fmts; + for (i = 0; i < num_fmts; i++) { + /* Skip uncompressed formats */ + if (formats[i].codec_mode == RK_VPU_MODE_NONE) + continue; + if (j == f->index) { + fmt = &formats[i]; + f->pixelformat = fmt->fourcc; + return 0; + } + ++j; + } + return -EINVAL; +} + +static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + struct rockchip_vpu_dev *dev = video_drvdata(file); + const struct rockchip_vpu_fmt *formats; + const struct rockchip_vpu_fmt *fmt; + int num_fmts, i, j = 0; + + formats = dev->variant->enc_fmts; + num_fmts = dev->variant->num_enc_fmts; + for (i = 0; i < num_fmts; i++) { + if (formats[i].codec_mode != RK_VPU_MODE_NONE) + continue; + if (j == f->index) { + fmt = &formats[i]; + f->pixelformat = fmt->fourcc; + return 0; + } + ++j; + } + return -EINVAL; +} + +static int vidioc_g_fmt_out_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); + + vpu_debug(4, "f->type = %d\n", f->type); + + *pix_mp = ctx->src_fmt; + + return 0; +} + +static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); + + vpu_debug(4, "f->type = %d\n", f->type); + + *pix_mp = ctx->dst_fmt; + + return 0; +} + +static int +vidioc_try_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f) +{ + struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + const struct rockchip_vpu_fmt *fmt; + + vpu_debug(4, "%c%c%c%c\n", + (pix_mp->pixelformat & 0x7f), + (pix_mp->pixelformat >> 8) & 0x7f, + (pix_mp->pixelformat >> 16) & 0x7f, + (pix_mp->pixelformat >> 24) & 0x7f); + + fmt = rockchip_vpu_find_format(ctx, pix_mp->pixelformat); + if (!fmt) { + fmt = rockchip_vpu_get_default_fmt(ctx, true); + f->fmt.pix.pixelformat = fmt->fourcc; + } + + pix_mp->num_planes = 1; + pix_mp->field = V4L2_FIELD_NONE; + pix_mp->width = clamp(pix_mp->width, + fmt->frmsize.min_width, + fmt->frmsize.max_width); + pix_mp->height = clamp(pix_mp->height, + fmt->frmsize.min_height, + fmt->frmsize.max_height); + /* Round up to macroblocks. */ + pix_mp->width = round_up(pix_mp->width, JPEG_MB_DIM); + pix_mp->height = round_up(pix_mp->height, JPEG_MB_DIM); + + /* + * For compressed formats the application can specify + * sizeimage. If the application passes a zero sizeimage, + * let's default to the maximum frame size. + */ + if (!pix_mp->plane_fmt[0].sizeimage) + pix_mp->plane_fmt[0].sizeimage = fmt->header_size + + pix_mp->width * pix_mp->height * fmt->max_depth; + memset(pix_mp->plane_fmt[0].reserved, 0, + sizeof(pix_mp->plane_fmt[0].reserved)); + return 0; +} + +static int +vidioc_try_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f) +{ + struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + const struct rockchip_vpu_fmt *fmt; + unsigned int width, height; + int i; + + vpu_debug(4, "%c%c%c%c\n", + (pix_mp->pixelformat & 0x7f), + (pix_mp->pixelformat >> 8) & 0x7f, + (pix_mp->pixelformat >> 16) & 0x7f, + (pix_mp->pixelformat >> 24) & 0x7f); + + fmt = rockchip_vpu_find_format(ctx, pix_mp->pixelformat); + if (!fmt) { + fmt = rockchip_vpu_get_default_fmt(ctx, false); + f->fmt.pix.pixelformat = fmt->fourcc; + } + + pix_mp->field = V4L2_FIELD_NONE; + width = clamp(pix_mp->width, + ctx->vpu_dst_fmt->frmsize.min_width, + ctx->vpu_dst_fmt->frmsize.max_width); + height = clamp(pix_mp->height, + ctx->vpu_dst_fmt->frmsize.min_height, + ctx->vpu_dst_fmt->frmsize.max_height); + /* Round up to macroblocks. */ + width = round_up(width, JPEG_MB_DIM); + height = round_up(height, JPEG_MB_DIM); + + /* Fill remaining fields */ + fill_pixfmt_mp(pix_mp, fmt->fourcc, width, height); + + for (i = 0; i < pix_mp->num_planes; i++) { + memset(pix_mp->plane_fmt[i].reserved, 0, + sizeof(pix_mp->plane_fmt[i].reserved)); + } + return 0; +} + +void rockchip_vpu_enc_reset_dst_fmt(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx) +{ + struct v4l2_pix_format_mplane *fmt = &ctx->dst_fmt; + + ctx->vpu_dst_fmt = rockchip_vpu_get_default_fmt(ctx, true); + + memset(fmt, 0, sizeof(*fmt)); + + fmt->num_planes = 1; + fmt->width = clamp(fmt->width, ctx->vpu_dst_fmt->frmsize.min_width, + ctx->vpu_dst_fmt->frmsize.max_width); + fmt->height = clamp(fmt->height, ctx->vpu_dst_fmt->frmsize.min_height, + ctx->vpu_dst_fmt->frmsize.max_height); + fmt->pixelformat = ctx->vpu_dst_fmt->fourcc; + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_JPEG, + fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + fmt->quantization = V4L2_QUANTIZATION_DEFAULT; + fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; + + fmt->plane_fmt[0].sizeimage = ctx->vpu_dst_fmt->header_size + + fmt->width * fmt->height * ctx->vpu_dst_fmt->max_depth; +} + +void rockchip_vpu_enc_reset_src_fmt(struct rockchip_vpu_dev *vpu, + struct rockchip_vpu_ctx *ctx) +{ + struct v4l2_pix_format_mplane *fmt = &ctx->src_fmt; + unsigned int width, height; + + ctx->vpu_src_fmt = rockchip_vpu_get_default_fmt(ctx, false); + + memset(fmt, 0, sizeof(*fmt)); + + width = clamp(fmt->width, ctx->vpu_dst_fmt->frmsize.min_width, + ctx->vpu_dst_fmt->frmsize.max_width); + height = clamp(fmt->height, ctx->vpu_dst_fmt->frmsize.min_height, + ctx->vpu_dst_fmt->frmsize.max_height); + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_JPEG, + fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + fmt->quantization = V4L2_QUANTIZATION_DEFAULT; + fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; + + fill_pixfmt_mp(fmt, ctx->vpu_src_fmt->fourcc, width, height); +} + +static int +vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); + struct vb2_queue *vq; + int ret; + + /* Change not allowed if queue is streaming. */ + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (vb2_is_streaming(vq)) + return -EBUSY; + + ret = vidioc_try_fmt_out_mplane(file, priv, f); + if (ret) + return ret; + + ctx->vpu_src_fmt = rockchip_vpu_find_format(ctx, pix_mp->pixelformat); + ctx->src_fmt = *pix_mp; + + /* Propagate to the CAPTURE format */ + ctx->dst_fmt.colorspace = pix_mp->colorspace; + ctx->dst_fmt.ycbcr_enc = pix_mp->ycbcr_enc; + ctx->dst_fmt.xfer_func = pix_mp->xfer_func; + ctx->dst_fmt.quantization = pix_mp->quantization; + ctx->dst_fmt.width = pix_mp->width; + ctx->dst_fmt.height = pix_mp->height; + + vpu_debug(0, "OUTPUT codec mode: %d\n", ctx->vpu_src_fmt->codec_mode); + vpu_debug(0, "fmt - w: %d, h: %d, mb - w: %d, h: %d\n", + pix_mp->width, pix_mp->height, + JPEG_MB_WIDTH(pix_mp->width), + JPEG_MB_HEIGHT(pix_mp->height)); + return 0; +} + +static int +vidioc_s_fmt_cap_mplane(struct file *file, void *priv, struct v4l2_format *f) +{ + struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; + struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); + struct rockchip_vpu_dev *vpu = ctx->dev; + struct vb2_queue *vq, *peer_vq; + int ret; + + /* Change not allowed if queue is streaming. */ + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + if (vb2_is_streaming(vq)) + return -EBUSY; + + /* + * Since format change on the CAPTURE queue will reset + * the OUTPUT queue, we can't allow doing so + * when the OUTPUT queue has buffers allocated. + */ + peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (vb2_is_busy(peer_vq) && + (pix_mp->pixelformat != ctx->dst_fmt.pixelformat || + pix_mp->height != ctx->dst_fmt.height || + pix_mp->width != ctx->dst_fmt.width)) + return -EBUSY; + + ret = vidioc_try_fmt_cap_mplane(file, priv, f); + if (ret) + return ret; + + ctx->vpu_dst_fmt = rockchip_vpu_find_format(ctx, pix_mp->pixelformat); + ctx->dst_fmt = *pix_mp; + + vpu_debug(0, "CAPTURE codec mode: %d\n", ctx->vpu_dst_fmt->codec_mode); + vpu_debug(0, "fmt - w: %d, h: %d, mb - w: %d, h: %d\n", + pix_mp->width, pix_mp->height, + JPEG_MB_WIDTH(pix_mp->width), + JPEG_MB_HEIGHT(pix_mp->height)); + + /* + * Current raw format might have become invalid with newly + * selected codec, so reset it to default just to be safe and + * keep internal driver state sane. User is mandated to set + * the raw format again after we return, so we don't need + * anything smarter. + */ + rockchip_vpu_enc_reset_src_fmt(vpu, ctx); + return 0; +} + +const struct v4l2_ioctl_ops rockchip_vpu_enc_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_framesizes = vidioc_enum_framesizes, + + .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_cap_mplane, + .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_out_mplane, + .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt_out_mplane, + .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_cap_mplane, + .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt_out_mplane, + .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_cap_mplane, + .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane, + .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane, + + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, +}; + +static int +rockchip_vpu_queue_setup(struct vb2_queue *vq, + unsigned int *num_buffers, + unsigned int *num_planes, + unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(vq); + struct v4l2_pix_format_mplane *pixfmt; + int i; + + switch (vq->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + pixfmt = &ctx->dst_fmt; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + pixfmt = &ctx->src_fmt; + break; + default: + vpu_err("invalid queue type: %d\n", vq->type); + return -EINVAL; + } + + if (*num_planes) { + if (*num_planes != pixfmt->num_planes) + return -EINVAL; + for (i = 0; i < pixfmt->num_planes; ++i) + if (sizes[i] < pixfmt->plane_fmt[i].sizeimage) + return -EINVAL; + return 0; + } + + *num_planes = pixfmt->num_planes; + for (i = 0; i < pixfmt->num_planes; ++i) + sizes[i] = pixfmt->plane_fmt[i].sizeimage; + return 0; +} + +static int rockchip_vpu_buf_prepare(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct vb2_queue *vq = vb->vb2_queue; + struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(vq); + struct v4l2_pix_format_mplane *pixfmt; + unsigned int sz; + int ret = 0; + int i; + + switch (vq->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + pixfmt = &ctx->dst_fmt; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + pixfmt = &ctx->src_fmt; + + if (vbuf->field == V4L2_FIELD_ANY) + vbuf->field = V4L2_FIELD_NONE; + if (vbuf->field != V4L2_FIELD_NONE) { + vpu_debug(4, "field %d not supported\n", + vbuf->field); + return -EINVAL; + } + break; + default: + vpu_err("invalid queue type: %d\n", vq->type); + return -EINVAL; + } + + for (i = 0; i < pixfmt->num_planes; ++i) { + sz = pixfmt->plane_fmt[i].sizeimage; + vpu_debug(4, "plane %d size: %ld, sizeimage: %u\n", + i, vb2_plane_size(vb, i), sz); + if (vb2_plane_size(vb, i) < sz) { + vpu_err("plane %d is too small\n", i); + ret = -EINVAL; + break; + } + } + + return ret; +} + +static void rockchip_vpu_buf_queue(struct vb2_buffer *vb) +{ + struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); +} + +static int rockchip_vpu_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(q); + enum rockchip_vpu_codec_mode codec_mode; + + if (V4L2_TYPE_IS_OUTPUT(q->type)) + ctx->sequence_out = 0; + else + ctx->sequence_cap = 0; + + /* Set codec_ops for the chosen destination format */ + codec_mode = ctx->vpu_dst_fmt->codec_mode; + + vpu_debug(4, "Codec mode = %d\n", codec_mode); + ctx->codec_ops = &ctx->dev->variant->codec_ops[codec_mode]; + + /* A bounce buffer is needed for the JPEG payload */ + if (!V4L2_TYPE_IS_OUTPUT(q->type)) { + ctx->bounce_size = ctx->dst_fmt.plane_fmt[0].sizeimage - + ctx->vpu_dst_fmt->header_size; + ctx->bounce_buf = dma_alloc_attrs(ctx->dev->dev, + ctx->bounce_size, + &ctx->bounce_dma_addr, + GFP_KERNEL, + DMA_ATTR_ALLOC_SINGLE_PAGES); + } + return 0; +} + +static void rockchip_vpu_stop_streaming(struct vb2_queue *q) +{ + struct rockchip_vpu_ctx *ctx = vb2_get_drv_priv(q); + + if (!V4L2_TYPE_IS_OUTPUT(q->type)) + dma_free_attrs(ctx->dev->dev, + ctx->bounce_size, + ctx->bounce_buf, + ctx->bounce_dma_addr, + DMA_ATTR_ALLOC_SINGLE_PAGES); + + /* + * The mem2mem framework calls v4l2_m2m_cancel_job before + * .stop_streaming, so there isn't any job running and + * it is safe to return all the buffers. + */ + for (;;) { + struct vb2_v4l2_buffer *vbuf; + + if (V4L2_TYPE_IS_OUTPUT(q->type)) + vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + else + vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + if (!vbuf) + break; + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); + } +} + +const struct vb2_ops rockchip_vpu_enc_queue_ops = { + .queue_setup = rockchip_vpu_queue_setup, + .buf_prepare = rockchip_vpu_buf_prepare, + .buf_queue = rockchip_vpu_buf_queue, + .start_streaming = rockchip_vpu_start_streaming, + .stop_streaming = rockchip_vpu_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h b/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h new file mode 100644 index 000000000000..2b955da1be1a --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_hw.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Rockchip VPU codec driver + * + * Copyright 2018 Google LLC. + * Tomasz Figa <tfiga@chromium.org> + */ + +#ifndef ROCKCHIP_VPU_HW_H_ +#define ROCKCHIP_VPU_HW_H_ + +#include <linux/interrupt.h> +#include <linux/v4l2-controls.h> +#include <media/videobuf2-core.h> + +struct rockchip_vpu_dev; +struct rockchip_vpu_ctx; +struct rockchip_vpu_buf; +struct rockchip_vpu_variant; + +/** + * struct rockchip_vpu_codec_ops - codec mode specific operations + * + * @run: Start single {en,de)coding job. Called from atomic context + * to indicate that a pair of buffers is ready and the hardware + * should be programmed and started. + * @done: Read back processing results and additional data from hardware. + * @reset: Reset the hardware in case of a timeout. + */ +struct rockchip_vpu_codec_ops { + void (*run)(struct rockchip_vpu_ctx *ctx); + void (*done)(struct rockchip_vpu_ctx *ctx, enum vb2_buffer_state); + void (*reset)(struct rockchip_vpu_ctx *ctx); +}; + +/** + * enum rockchip_vpu_enc_fmt - source format ID for hardware registers. + */ +enum rockchip_vpu_enc_fmt { + RK3288_VPU_ENC_FMT_YUV420P = 0, + RK3288_VPU_ENC_FMT_YUV420SP = 1, + RK3288_VPU_ENC_FMT_YUYV422 = 2, + RK3288_VPU_ENC_FMT_UYVY422 = 3, +}; + +extern const struct rockchip_vpu_variant rk3399_vpu_variant; +extern const struct rockchip_vpu_variant rk3288_vpu_variant; + +void rockchip_vpu_watchdog(struct work_struct *work); +void rockchip_vpu_run(struct rockchip_vpu_ctx *ctx); +void rockchip_vpu_irq_done(struct rockchip_vpu_dev *vpu, + unsigned int bytesused, + enum vb2_buffer_state result); + +void rk3288_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx); +void rk3399_vpu_jpeg_enc_run(struct rockchip_vpu_ctx *ctx); + +#endif /* ROCKCHIP_VPU_HW_H_ */ diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_jpeg.c b/drivers/staging/media/rockchip/vpu/rockchip_vpu_jpeg.c new file mode 100644 index 000000000000..0ff0badc1f7a --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_jpeg.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) Collabora, Ltd. + * + * Based on GSPCA and CODA drivers: + * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr) + * Copyright (C) 2014 Philipp Zabel, Pengutronix + */ +#include <linux/kernel.h> +#include <linux/string.h> +#include "rockchip_vpu_jpeg.h" + +#define LUMA_QUANT_OFF 7 +#define CHROMA_QUANT_OFF 72 +#define HEIGHT_OFF 141 +#define WIDTH_OFF 143 + +#define HUFF_LUMA_DC_OFF 160 +#define HUFF_LUMA_AC_OFF 193 +#define HUFF_CHROMA_DC_OFF 376 +#define HUFF_CHROMA_AC_OFF 409 + +/* Default tables from JPEG ITU-T.81 + * (ISO/IEC 10918-1) Annex K.3, I + */ +static const unsigned char luma_q_table[] = { + 0x10, 0x0b, 0x0a, 0x10, 0x7c, 0x8c, 0x97, 0xa1, + 0x0c, 0x0c, 0x0e, 0x13, 0x7e, 0x9e, 0xa0, 0x9b, + 0x0e, 0x0d, 0x10, 0x18, 0x8c, 0x9d, 0xa9, 0x9c, + 0x0e, 0x11, 0x16, 0x1d, 0x97, 0xbb, 0xb4, 0xa2, + 0x12, 0x16, 0x25, 0x38, 0xa8, 0x6d, 0x67, 0xb1, + 0x18, 0x23, 0x37, 0x40, 0xb5, 0x68, 0x71, 0xc0, + 0x31, 0x40, 0x4e, 0x57, 0x67, 0x79, 0x78, 0x65, + 0x48, 0x5c, 0x5f, 0x62, 0x70, 0x64, 0x67, 0xc7, +}; + +static const unsigned char chroma_q_table[] = { + 0x11, 0x12, 0x18, 0x2f, 0x63, 0x63, 0x63, 0x63, + 0x12, 0x15, 0x1a, 0x42, 0x63, 0x63, 0x63, 0x63, + 0x18, 0x1a, 0x38, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x2f, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63 +}; + +/* Huffman tables are shared with CODA */ +static const unsigned char luma_dc_table[] = { + 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, +}; + +static const unsigned char chroma_dc_table[] = { + 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, +}; + +static const unsigned char luma_ac_table[] = { + 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, +}; + +static const unsigned char chroma_ac_table[] = { + 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, +}; + +/* For simplicity, we keep a pre-formatted JPEG header, + * and we'll use fixed offsets to change the width, height + * quantization tables, etc. + */ +static const unsigned char rockchip_vpu_jpeg_header[JPEG_HEADER_SIZE] = { + /* SOI */ + 0xff, 0xd8, + + /* DQT */ + 0xff, 0xdb, 0x00, 0x84, + + 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* SOF */ + 0xff, 0xc0, 0x00, 0x11, 0x08, 0x00, 0xf0, 0x01, + 0x40, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, + 0x03, 0x11, 0x01, + + /* DHT */ + 0xff, 0xc4, 0x00, 0x1f, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + /* DHT */ + 0xff, 0xc4, 0x00, 0xb5, 0x10, + + 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* DHT */ + 0xff, 0xc4, 0x00, 0x1f, 0x01, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + + /* DHT */ + 0xff, 0xc4, 0x00, 0xb5, 0x11, + + 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* SOS */ + 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, + 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, +}; + +static void +jpeg_scale_quant_table(unsigned char *q_tab, + const unsigned char *tab, int scale) +{ + unsigned int temp; + int i; + + for (i = 0; i < 64; i++) { + temp = DIV_ROUND_CLOSEST((unsigned int)tab[i] * scale, 100); + if (temp <= 0) + temp = 1; + if (temp > 255) + temp = 255; + q_tab[i] = (unsigned char)temp; + } +} + +static void jpeg_set_quality(unsigned char *buffer, int quality) +{ + int scale; + + /* + * Non-linear scaling factor: + * [5,50] -> [1000..100], [51,100] -> [98..0] + */ + if (quality < 50) + scale = 5000 / quality; + else + scale = 200 - 2 * quality; + + jpeg_scale_quant_table(buffer + LUMA_QUANT_OFF, + luma_q_table, scale); + jpeg_scale_quant_table(buffer + CHROMA_QUANT_OFF, + chroma_q_table, scale); +} + +unsigned char * +rockchip_vpu_jpeg_get_qtable(struct rockchip_vpu_jpeg_ctx *ctx, int index) +{ + if (index == 0) + return ctx->buffer + LUMA_QUANT_OFF; + return ctx->buffer + CHROMA_QUANT_OFF; +} + +void rockchip_vpu_jpeg_header_assemble(struct rockchip_vpu_jpeg_ctx *ctx) +{ + char *buf = ctx->buffer; + + memcpy(buf, rockchip_vpu_jpeg_header, + sizeof(rockchip_vpu_jpeg_header)); + + buf[HEIGHT_OFF + 0] = ctx->height >> 8; + buf[HEIGHT_OFF + 1] = ctx->height; + buf[WIDTH_OFF + 0] = ctx->width >> 8; + buf[WIDTH_OFF + 1] = ctx->width; + + memcpy(buf + HUFF_LUMA_DC_OFF, luma_dc_table, sizeof(luma_dc_table)); + memcpy(buf + HUFF_LUMA_AC_OFF, luma_ac_table, sizeof(luma_ac_table)); + memcpy(buf + HUFF_CHROMA_DC_OFF, chroma_dc_table, + sizeof(chroma_dc_table)); + memcpy(buf + HUFF_CHROMA_AC_OFF, chroma_ac_table, + sizeof(chroma_ac_table)); + + jpeg_set_quality(buf, ctx->quality); +} diff --git a/drivers/staging/media/rockchip/vpu/rockchip_vpu_jpeg.h b/drivers/staging/media/rockchip/vpu/rockchip_vpu_jpeg.h new file mode 100644 index 000000000000..72645d8e2ade --- /dev/null +++ b/drivers/staging/media/rockchip/vpu/rockchip_vpu_jpeg.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#define JPEG_HEADER_SIZE 601 + +struct rockchip_vpu_jpeg_ctx { + int width; + int height; + int quality; + unsigned char *buffer; +}; + +unsigned char * +rockchip_vpu_jpeg_get_qtable(struct rockchip_vpu_jpeg_ctx *ctx, int index); +void rockchip_vpu_jpeg_header_assemble(struct rockchip_vpu_jpeg_ctx *ctx); diff --git a/drivers/staging/media/sunxi/cedrus/Kconfig b/drivers/staging/media/sunxi/cedrus/Kconfig index a7a34e89c42d..3252efa422f9 100644 --- a/drivers/staging/media/sunxi/cedrus/Kconfig +++ b/drivers/staging/media/sunxi/cedrus/Kconfig @@ -3,6 +3,7 @@ config VIDEO_SUNXI_CEDRUS depends on VIDEO_DEV && VIDEO_V4L2 && MEDIA_CONTROLLER depends on HAS_DMA depends on OF + depends on MEDIA_CONTROLLER_REQUEST_API select SUNXI_SRAM select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index c912c70b3ef7..ff11cbeba205 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -72,10 +72,11 @@ static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx) ctrl_size = sizeof(ctrl) * CEDRUS_CONTROLS_COUNT + 1; ctx->ctrls = kzalloc(ctrl_size, GFP_KERNEL); - memset(ctx->ctrls, 0, ctrl_size); + if (!ctx->ctrls) + return -ENOMEM; for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) { - struct v4l2_ctrl_config cfg = { 0 }; + struct v4l2_ctrl_config cfg = {}; cfg.elem_size = cedrus_controls[i].elem_size; cfg.id = cedrus_controls[i].id; @@ -279,7 +280,6 @@ static int cedrus_probe(struct platform_device *pdev) dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2; mutex_init(&dev->dev_mutex); - spin_lock_init(&dev->irq_lock); ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) { @@ -388,6 +388,14 @@ static const struct cedrus_variant sun8i_h3_cedrus_variant = { .capabilities = CEDRUS_CAPABILITY_UNTILED, }; +static const struct cedrus_variant sun50i_a64_cedrus_variant = { + .capabilities = CEDRUS_CAPABILITY_UNTILED, +}; + +static const struct cedrus_variant sun50i_h5_cedrus_variant = { + .capabilities = CEDRUS_CAPABILITY_UNTILED, +}; + static const struct of_device_id cedrus_dt_match[] = { { .compatible = "allwinner,sun4i-a10-video-engine", @@ -409,6 +417,14 @@ static const struct of_device_id cedrus_dt_match[] = { .compatible = "allwinner,sun8i-h3-video-engine", .data = &sun8i_h3_cedrus_variant, }, + { + .compatible = "allwinner,sun50i-a64-video-engine", + .data = &sun50i_a64_cedrus_variant, + }, + { + .compatible = "allwinner,sun50i-h5-video-engine", + .data = &sun50i_h5_cedrus_variant, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, cedrus_dt_match); @@ -418,7 +434,6 @@ static struct platform_driver cedrus_driver = { .remove = cedrus_remove, .driver = { .name = CEDRUS_NAME, - .owner = THIS_MODULE, .of_match_table = of_match_ptr(cedrus_dt_match), }, }; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index 3f61248c57ac..3acfdcf83691 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -105,8 +105,6 @@ struct cedrus_dev { /* Device file mutex */ struct mutex dev_mutex; - /* Interrupt spinlock */ - spinlock_t irq_lock; void __iomem *base; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index e40180a33951..591d191d4286 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -26,9 +26,8 @@ void cedrus_device_run(void *priv) { struct cedrus_ctx *ctx = priv; struct cedrus_dev *dev = ctx->dev; - struct cedrus_run run = { 0 }; + struct cedrus_run run = {}; struct media_request *src_req; - unsigned long flags; run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); @@ -39,8 +38,6 @@ void cedrus_device_run(void *priv) if (src_req) v4l2_ctrl_request_setup(src_req, &ctx->hdl); - spin_lock_irqsave(&ctx->dev->irq_lock, flags); - switch (ctx->src_fmt.pixelformat) { case V4L2_PIX_FMT_MPEG2_SLICE: run.mpeg2.slice_params = cedrus_find_control_data(ctx, @@ -55,16 +52,10 @@ void cedrus_device_run(void *priv) dev->dec_ops[ctx->current_codec]->setup(ctx, &run); - spin_unlock_irqrestore(&ctx->dev->irq_lock, flags); - /* Complete request(s) controls if needed. */ if (src_req) v4l2_ctrl_request_complete(src_req, &ctx->hdl); - spin_lock_irqsave(&ctx->dev->irq_lock, flags); - dev->dec_ops[ctx->current_codec]->trigger(ctx); - - spin_unlock_irqrestore(&ctx->dev->irq_lock, flags); } diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c index 32adbcbe6175..300339fee1bc 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c @@ -98,23 +98,6 @@ void cedrus_dst_format_set(struct cedrus_dev *dev, } } -static irqreturn_t cedrus_bh(int irq, void *data) -{ - struct cedrus_dev *dev = data; - struct cedrus_ctx *ctx; - - ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); - if (!ctx) { - v4l2_err(&dev->v4l2_dev, - "Instance released before the end of transaction\n"); - return IRQ_HANDLED; - } - - v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); - - return IRQ_HANDLED; -} - static irqreturn_t cedrus_irq(int irq, void *data) { struct cedrus_dev *dev = data; @@ -122,24 +105,17 @@ static irqreturn_t cedrus_irq(int irq, void *data) struct vb2_v4l2_buffer *src_buf, *dst_buf; enum vb2_buffer_state state; enum cedrus_irq_status status; - unsigned long flags; - - spin_lock_irqsave(&dev->irq_lock, flags); ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev); if (!ctx) { v4l2_err(&dev->v4l2_dev, "Instance released before the end of transaction\n"); - spin_unlock_irqrestore(&dev->irq_lock, flags); - return IRQ_NONE; } status = dev->dec_ops[ctx->current_codec]->irq_status(ctx); - if (status == CEDRUS_IRQ_NONE) { - spin_unlock_irqrestore(&dev->irq_lock, flags); + if (status == CEDRUS_IRQ_NONE) return IRQ_NONE; - } dev->dec_ops[ctx->current_codec]->irq_disable(ctx); dev->dec_ops[ctx->current_codec]->irq_clear(ctx); @@ -150,8 +126,6 @@ static irqreturn_t cedrus_irq(int irq, void *data) if (!src_buf || !dst_buf) { v4l2_err(&dev->v4l2_dev, "Missing source and/or destination buffers\n"); - spin_unlock_irqrestore(&dev->irq_lock, flags); - return IRQ_HANDLED; } @@ -163,9 +137,9 @@ static irqreturn_t cedrus_irq(int irq, void *data) v4l2_m2m_buf_done(src_buf, state); v4l2_m2m_buf_done(dst_buf, state); - spin_unlock_irqrestore(&dev->irq_lock, flags); + v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx); - return IRQ_WAKE_THREAD; + return IRQ_HANDLED; } int cedrus_hw_probe(struct cedrus_dev *dev) @@ -187,9 +161,8 @@ int cedrus_hw_probe(struct cedrus_dev *dev) return irq_dec; } - ret = devm_request_threaded_irq(dev->dev, irq_dec, cedrus_irq, - cedrus_bh, 0, dev_name(dev->dev), - dev); + ret = devm_request_irq(dev->dev, irq_dec, cedrus_irq, + 0, dev_name(dev->dev), dev); if (ret) { v4l2_err(&dev->v4l2_dev, "Failed to request IRQ\n"); @@ -255,10 +228,10 @@ int cedrus_hw_probe(struct cedrus_dev *dev) res = platform_get_resource(dev->pdev, IORESOURCE_MEM, 0); dev->base = devm_ioremap_resource(dev->dev, res); - if (!dev->base) { + if (IS_ERR(dev->base)) { v4l2_err(&dev->v4l2_dev, "Failed to map registers\n"); - ret = -ENOMEM; + ret = PTR_ERR(dev->base); goto err_sram; } diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c index 5c5fce678b93..8721b4a7d496 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c @@ -380,18 +380,13 @@ static void cedrus_queue_cleanup(struct vb2_queue *vq, u32 state) { struct cedrus_ctx *ctx = vb2_get_drv_priv(vq); struct vb2_v4l2_buffer *vbuf; - unsigned long flags; for (;;) { - spin_lock_irqsave(&ctx->dev->irq_lock, flags); - if (V4L2_TYPE_IS_OUTPUT(vq->type)) vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); else vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - spin_unlock_irqrestore(&ctx->dev->irq_lock, flags); - if (!vbuf) return; diff --git a/drivers/staging/media/tegra-vde/tegra-vde.c b/drivers/staging/media/tegra-vde/tegra-vde.c index 66cf14212c14..aa6c6bba961e 100644 --- a/drivers/staging/media/tegra-vde/tegra-vde.c +++ b/drivers/staging/media/tegra-vde/tegra-vde.c @@ -35,14 +35,6 @@ #define BSE_ICMDQUE_EMPTY BIT(3) #define BSE_DMA_BUSY BIT(23) -#define VDE_WR(__data, __addr) \ -do { \ - dev_dbg(vde->miscdev.parent, \ - "%s: %d: 0x%08X => " #__addr ")\n", \ - __func__, __LINE__, (u32)(__data)); \ - writel_relaxed(__data, __addr); \ -} while (0) - struct video_frame { struct dma_buf_attachment *y_dmabuf_attachment; struct dma_buf_attachment *cb_dmabuf_attachment; @@ -81,12 +73,66 @@ struct tegra_vde { u32 *iram; }; +static __maybe_unused char const * +tegra_vde_reg_base_name(struct tegra_vde *vde, void __iomem *base) +{ + if (vde->sxe == base) + return "SXE"; + + if (vde->bsev == base) + return "BSEV"; + + if (vde->mbe == base) + return "MBE"; + + if (vde->ppe == base) + return "PPE"; + + if (vde->mce == base) + return "MCE"; + + if (vde->tfe == base) + return "TFE"; + + if (vde->ppb == base) + return "PPB"; + + if (vde->vdma == base) + return "VDMA"; + + if (vde->frameid == base) + return "FRAMEID"; + + return "???"; +} + +#define CREATE_TRACE_POINTS +#include "trace.h" + +static void tegra_vde_writel(struct tegra_vde *vde, + u32 value, void __iomem *base, u32 offset) +{ + trace_vde_writel(vde, base, offset, value); + + writel_relaxed(value, base + offset); +} + +static u32 tegra_vde_readl(struct tegra_vde *vde, + void __iomem *base, u32 offset) +{ + u32 value = readl_relaxed(base + offset); + + trace_vde_readl(vde, base, offset, value); + + return value; +} + static void tegra_vde_set_bits(struct tegra_vde *vde, - u32 mask, void __iomem *regs) + u32 mask, void __iomem *base, u32 offset) { - u32 value = readl_relaxed(regs); + u32 value = tegra_vde_readl(vde, base, offset); - VDE_WR(value | mask, regs); + tegra_vde_writel(vde, value | mask, base, offset); } static int tegra_vde_wait_mbe(struct tegra_vde *vde) @@ -107,8 +153,8 @@ static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde, unsigned int idx; int err; - VDE_WR(0xD0000000 | (0 << 23), vde->mbe + 0x80); - VDE_WR(0xD0200000 | (0 << 23), vde->mbe + 0x80); + tegra_vde_writel(vde, 0xD0000000 | (0 << 23), vde->mbe, 0x80); + tegra_vde_writel(vde, 0xD0200000 | (0 << 23), vde->mbe, 0x80); err = tegra_vde_wait_mbe(vde); if (err) @@ -118,8 +164,10 @@ static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde, return 0; for (idx = 0, frame_idx = 1; idx < refs_nb; idx++, frame_idx++) { - VDE_WR(0xD0000000 | (frame_idx << 23), vde->mbe + 0x80); - VDE_WR(0xD0200000 | (frame_idx << 23), vde->mbe + 0x80); + tegra_vde_writel(vde, 0xD0000000 | (frame_idx << 23), + vde->mbe, 0x80); + tegra_vde_writel(vde, 0xD0200000 | (frame_idx << 23), + vde->mbe, 0x80); frame_idx_enb_mask |= frame_idx << (6 * (idx % 4)); @@ -128,7 +176,7 @@ static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde, value |= (idx >> 2) << 24; value |= frame_idx_enb_mask; - VDE_WR(value, vde->mbe + 0x80); + tegra_vde_writel(vde, value, vde->mbe, 0x80); err = tegra_vde_wait_mbe(vde); if (err) @@ -143,8 +191,10 @@ static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde, static void tegra_vde_mbe_set_0xa_reg(struct tegra_vde *vde, int reg, u32 val) { - VDE_WR(0xA0000000 | (reg << 24) | (val & 0xFFFF), vde->mbe + 0x80); - VDE_WR(0xA0000000 | ((reg + 1) << 24) | (val >> 16), vde->mbe + 0x80); + tegra_vde_writel(vde, 0xA0000000 | (reg << 24) | (val & 0xFFFF), + vde->mbe, 0x80); + tegra_vde_writel(vde, 0xA0000000 | ((reg + 1) << 24) | (val >> 16), + vde->mbe, 0x80); } static int tegra_vde_wait_bsev(struct tegra_vde *vde, bool wait_dma) @@ -183,7 +233,7 @@ static int tegra_vde_wait_bsev(struct tegra_vde *vde, bool wait_dma) static int tegra_vde_push_to_bsev_icmdqueue(struct tegra_vde *vde, u32 value, bool wait_dma) { - VDE_WR(value, vde->bsev + ICMDQUE_WR); + tegra_vde_writel(vde, value, vde->bsev, ICMDQUE_WR); return tegra_vde_wait_bsev(vde, wait_dma); } @@ -199,11 +249,11 @@ static void tegra_vde_setup_frameid(struct tegra_vde *vde, u32 value1 = frame ? ((mbs_width << 16) | mbs_height) : 0; u32 value2 = frame ? ((((mbs_width + 1) >> 1) << 6) | 1) : 0; - VDE_WR(y_addr >> 8, vde->frameid + 0x000 + frameid * 4); - VDE_WR(cb_addr >> 8, vde->frameid + 0x100 + frameid * 4); - VDE_WR(cr_addr >> 8, vde->frameid + 0x180 + frameid * 4); - VDE_WR(value1, vde->frameid + 0x080 + frameid * 4); - VDE_WR(value2, vde->frameid + 0x280 + frameid * 4); + tegra_vde_writel(vde, y_addr >> 8, vde->frameid, 0x000 + frameid * 4); + tegra_vde_writel(vde, cb_addr >> 8, vde->frameid, 0x100 + frameid * 4); + tegra_vde_writel(vde, cr_addr >> 8, vde->frameid, 0x180 + frameid * 4); + tegra_vde_writel(vde, value1, vde->frameid, 0x080 + frameid * 4); + tegra_vde_writel(vde, value2, vde->frameid, 0x280 + frameid * 4); } static void tegra_setup_frameidx(struct tegra_vde *vde, @@ -228,8 +278,7 @@ static void tegra_vde_setup_iram_entry(struct tegra_vde *vde, { u32 *iram_tables = vde->iram; - dev_dbg(vde->miscdev.parent, "IRAM table %u: row %u: 0x%08X 0x%08X\n", - table, row, value1, value2); + trace_vde_setup_iram_entry(table, row, value1, value2); iram_tables[0x20 * table + row * 2] = value1; iram_tables[0x20 * table + row * 2 + 1] = value2; @@ -245,10 +294,7 @@ static void tegra_vde_setup_iram_tables(struct tegra_vde *vde, int with_later_poc_nb; unsigned int i, k; - dev_dbg(vde->miscdev.parent, "DPB: Frame 0: frame_num = %d\n", - dpb_frames[0].frame_num); - - dev_dbg(vde->miscdev.parent, "REF L0:\n"); + trace_vde_ref_l0(dpb_frames[0].frame_num); for (i = 0; i < 16; i++) { if (i < ref_frames_nb) { @@ -260,11 +306,6 @@ static void tegra_vde_setup_iram_tables(struct tegra_vde *vde, value |= !(frame->flags & FLAG_B_FRAME) << 25; value |= 1 << 24; value |= frame->frame_num; - - dev_dbg(vde->miscdev.parent, - "\tFrame %d: frame_num = %d B_frame = %lu\n", - i + 1, frame->frame_num, - (frame->flags & FLAG_B_FRAME)); } else { aux_addr = 0x6ADEAD00; value = 0; @@ -284,9 +325,7 @@ static void tegra_vde_setup_iram_tables(struct tegra_vde *vde, with_later_poc_nb = ref_frames_nb - with_earlier_poc_nb; - dev_dbg(vde->miscdev.parent, - "REF L1: with_later_poc_nb %d with_earlier_poc_nb %d\n", - with_later_poc_nb, with_earlier_poc_nb); + trace_vde_ref_l1(with_later_poc_nb, with_earlier_poc_nb); for (i = 0, k = with_earlier_poc_nb; i < with_later_poc_nb; i++, k++) { frame = &dpb_frames[k + 1]; @@ -298,10 +337,6 @@ static void tegra_vde_setup_iram_tables(struct tegra_vde *vde, value |= 1 << 24; value |= frame->frame_num; - dev_dbg(vde->miscdev.parent, - "\tFrame %d: frame_num = %d\n", - k + 1, frame->frame_num); - tegra_vde_setup_iram_entry(vde, 2, i, value, aux_addr); } @@ -315,10 +350,6 @@ static void tegra_vde_setup_iram_tables(struct tegra_vde *vde, value |= 1 << 24; value |= frame->frame_num; - dev_dbg(vde->miscdev.parent, - "\tFrame %d: frame_num = %d\n", - k + 1, frame->frame_num); - tegra_vde_setup_iram_entry(vde, 2, i, value, aux_addr); } } @@ -334,32 +365,32 @@ static int tegra_vde_setup_hw_context(struct tegra_vde *vde, u32 value; int err; - tegra_vde_set_bits(vde, 0x000A, vde->sxe + 0xF0); - tegra_vde_set_bits(vde, 0x000B, vde->bsev + CMDQUE_CONTROL); - tegra_vde_set_bits(vde, 0x8002, vde->mbe + 0x50); - tegra_vde_set_bits(vde, 0x000A, vde->mbe + 0xA0); - tegra_vde_set_bits(vde, 0x000A, vde->ppe + 0x14); - tegra_vde_set_bits(vde, 0x000A, vde->ppe + 0x28); - tegra_vde_set_bits(vde, 0x0A00, vde->mce + 0x08); - tegra_vde_set_bits(vde, 0x000A, vde->tfe + 0x00); - tegra_vde_set_bits(vde, 0x0005, vde->vdma + 0x04); - - VDE_WR(0x00000000, vde->vdma + 0x1C); - VDE_WR(0x00000000, vde->vdma + 0x00); - VDE_WR(0x00000007, vde->vdma + 0x04); - VDE_WR(0x00000007, vde->frameid + 0x200); - VDE_WR(0x00000005, vde->tfe + 0x04); - VDE_WR(0x00000000, vde->mbe + 0x84); - VDE_WR(0x00000010, vde->sxe + 0x08); - VDE_WR(0x00000150, vde->sxe + 0x54); - VDE_WR(0x0000054C, vde->sxe + 0x58); - VDE_WR(0x00000E34, vde->sxe + 0x5C); - VDE_WR(0x063C063C, vde->mce + 0x10); - VDE_WR(0x0003FC00, vde->bsev + INTR_STATUS); - VDE_WR(0x0000150D, vde->bsev + BSE_CONFIG); - VDE_WR(0x00000100, vde->bsev + BSE_INT_ENB); - VDE_WR(0x00000000, vde->bsev + 0x98); - VDE_WR(0x00000060, vde->bsev + 0x9C); + tegra_vde_set_bits(vde, 0x000A, vde->sxe, 0xF0); + tegra_vde_set_bits(vde, 0x000B, vde->bsev, CMDQUE_CONTROL); + tegra_vde_set_bits(vde, 0x8002, vde->mbe, 0x50); + tegra_vde_set_bits(vde, 0x000A, vde->mbe, 0xA0); + tegra_vde_set_bits(vde, 0x000A, vde->ppe, 0x14); + tegra_vde_set_bits(vde, 0x000A, vde->ppe, 0x28); + tegra_vde_set_bits(vde, 0x0A00, vde->mce, 0x08); + tegra_vde_set_bits(vde, 0x000A, vde->tfe, 0x00); + tegra_vde_set_bits(vde, 0x0005, vde->vdma, 0x04); + + tegra_vde_writel(vde, 0x00000000, vde->vdma, 0x1C); + tegra_vde_writel(vde, 0x00000000, vde->vdma, 0x00); + tegra_vde_writel(vde, 0x00000007, vde->vdma, 0x04); + tegra_vde_writel(vde, 0x00000007, vde->frameid, 0x200); + tegra_vde_writel(vde, 0x00000005, vde->tfe, 0x04); + tegra_vde_writel(vde, 0x00000000, vde->mbe, 0x84); + tegra_vde_writel(vde, 0x00000010, vde->sxe, 0x08); + tegra_vde_writel(vde, 0x00000150, vde->sxe, 0x54); + tegra_vde_writel(vde, 0x0000054C, vde->sxe, 0x58); + tegra_vde_writel(vde, 0x00000E34, vde->sxe, 0x5C); + tegra_vde_writel(vde, 0x063C063C, vde->mce, 0x10); + tegra_vde_writel(vde, 0x0003FC00, vde->bsev, INTR_STATUS); + tegra_vde_writel(vde, 0x0000150D, vde->bsev, BSE_CONFIG); + tegra_vde_writel(vde, 0x00000100, vde->bsev, BSE_INT_ENB); + tegra_vde_writel(vde, 0x00000000, vde->bsev, 0x98); + tegra_vde_writel(vde, 0x00000060, vde->bsev, 0x9C); memset(vde->iram + 128, 0, macroblocks_nb / 2); @@ -376,13 +407,13 @@ static int tegra_vde_setup_hw_context(struct tegra_vde *vde, */ wmb(); - VDE_WR(0x00000000, vde->bsev + 0x8C); - VDE_WR(bitstream_data_addr + bitstream_data_size, - vde->bsev + 0x54); + tegra_vde_writel(vde, 0x00000000, vde->bsev, 0x8C); + tegra_vde_writel(vde, bitstream_data_addr + bitstream_data_size, + vde->bsev, 0x54); value = ctx->pic_width_in_mbs << 11 | ctx->pic_height_in_mbs << 3; - VDE_WR(value, vde->bsev + 0x88); + tegra_vde_writel(vde, value, vde->bsev, 0x88); err = tegra_vde_wait_bsev(vde, false); if (err) @@ -417,7 +448,7 @@ static int tegra_vde_setup_hw_context(struct tegra_vde *vde, value |= ctx->pic_width_in_mbs << 11; value |= ctx->pic_height_in_mbs << 3; - VDE_WR(value, vde->sxe + 0x10); + tegra_vde_writel(vde, value, vde->sxe, 0x10); value = !ctx->baseline_profile << 17; value |= ctx->level_idc << 13; @@ -425,54 +456,54 @@ static int tegra_vde_setup_hw_context(struct tegra_vde *vde, value |= ctx->pic_order_cnt_type << 5; value |= ctx->log2_max_frame_num; - VDE_WR(value, vde->sxe + 0x40); + tegra_vde_writel(vde, value, vde->sxe, 0x40); value = ctx->pic_init_qp << 25; value |= !!(ctx->deblocking_filter_control_present_flag) << 2; value |= !!ctx->pic_order_present_flag; - VDE_WR(value, vde->sxe + 0x44); + tegra_vde_writel(vde, value, vde->sxe, 0x44); value = ctx->chroma_qp_index_offset; value |= ctx->num_ref_idx_l0_active_minus1 << 5; value |= ctx->num_ref_idx_l1_active_minus1 << 10; value |= !!ctx->constrained_intra_pred_flag << 15; - VDE_WR(value, vde->sxe + 0x48); + tegra_vde_writel(vde, value, vde->sxe, 0x48); value = 0x0C000000; value |= !!(dpb_frames[0].flags & FLAG_B_FRAME) << 24; - VDE_WR(value, vde->sxe + 0x4C); + tegra_vde_writel(vde, value, vde->sxe, 0x4C); value = 0x03800000; value |= bitstream_data_size & GENMASK(19, 15); - VDE_WR(value, vde->sxe + 0x68); + tegra_vde_writel(vde, value, vde->sxe, 0x68); - VDE_WR(bitstream_data_addr, vde->sxe + 0x6C); + tegra_vde_writel(vde, bitstream_data_addr, vde->sxe, 0x6C); value = 0x10000005; value |= ctx->pic_width_in_mbs << 11; value |= ctx->pic_height_in_mbs << 3; - VDE_WR(value, vde->mbe + 0x80); + tegra_vde_writel(vde, value, vde->mbe, 0x80); value = 0x26800000; value |= ctx->level_idc << 4; value |= !ctx->baseline_profile << 1; value |= !!ctx->direct_8x8_inference_flag; - VDE_WR(value, vde->mbe + 0x80); + tegra_vde_writel(vde, value, vde->mbe, 0x80); - VDE_WR(0xF4000001, vde->mbe + 0x80); - VDE_WR(0x20000000, vde->mbe + 0x80); - VDE_WR(0xF4000101, vde->mbe + 0x80); + tegra_vde_writel(vde, 0xF4000001, vde->mbe, 0x80); + tegra_vde_writel(vde, 0x20000000, vde->mbe, 0x80); + tegra_vde_writel(vde, 0xF4000101, vde->mbe, 0x80); value = 0x20000000; value |= ctx->chroma_qp_index_offset << 8; - VDE_WR(value, vde->mbe + 0x80); + tegra_vde_writel(vde, value, vde->mbe, 0x80); err = tegra_vde_setup_mbe_frame_idx(vde, ctx->dpb_frames_nb - 1, @@ -494,7 +525,7 @@ static int tegra_vde_setup_hw_context(struct tegra_vde *vde, if (!ctx->baseline_profile) value |= !!(dpb_frames[0].flags & FLAG_REFERENCE) << 1; - VDE_WR(value, vde->mbe + 0x80); + tegra_vde_writel(vde, value, vde->mbe, 0x80); err = tegra_vde_wait_mbe(vde); if (err) { @@ -510,8 +541,9 @@ static void tegra_vde_decode_frame(struct tegra_vde *vde, { reinit_completion(&vde->decode_completion); - VDE_WR(0x00000001, vde->bsev + 0x8C); - VDE_WR(0x20000000 | (macroblocks_nb - 1), vde->sxe + 0x00); + tegra_vde_writel(vde, 0x00000001, vde->bsev, 0x8C); + tegra_vde_writel(vde, 0x20000000 | (macroblocks_nb - 1), + vde->sxe, 0x00); } static void tegra_vde_detach_and_put_dmabuf(struct dma_buf_attachment *a, @@ -883,8 +915,8 @@ static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde, timeout = wait_for_completion_interruptible_timeout( &vde->decode_completion, msecs_to_jiffies(1000)); if (timeout == 0) { - bsev_ptr = readl_relaxed(vde->bsev + 0x10); - macroblocks_nb = readl_relaxed(vde->sxe + 0xC8) & 0x1FFF; + bsev_ptr = tegra_vde_readl(vde, vde->bsev, 0x10); + macroblocks_nb = tegra_vde_readl(vde, vde->sxe, 0xC8) & 0x1FFF; read_bytes = bsev_ptr ? bsev_ptr - bitstream_data_addr : 0; dev_err(dev, "Decoding failed: read 0x%X bytes, %u macroblocks parsed\n", @@ -962,7 +994,7 @@ static irqreturn_t tegra_vde_isr(int irq, void *data) if (completion_done(&vde->decode_completion)) return IRQ_NONE; - tegra_vde_set_bits(vde, 0, vde->frameid + 0x208); + tegra_vde_set_bits(vde, 0, vde->frameid, 0x208); complete(&vde->decode_completion); return IRQ_HANDLED; diff --git a/drivers/staging/media/tegra-vde/trace.h b/drivers/staging/media/tegra-vde/trace.h new file mode 100644 index 000000000000..85e2f7e2d4d0 --- /dev/null +++ b/drivers/staging/media/tegra-vde/trace.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM tegra_vde + +#if !defined(TEGRA_VDE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define TEGRA_VDE_TRACE_H + +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(register_access, + TP_PROTO(struct tegra_vde *vde, void __iomem *base, + u32 offset, u32 value), + TP_ARGS(vde, base, offset, value), + TP_STRUCT__entry( + __string(hw_name, tegra_vde_reg_base_name(vde, base)) + __field(u32, offset) + __field(u32, value) + ), + TP_fast_assign( + __assign_str(hw_name, tegra_vde_reg_base_name(vde, base)); + __entry->offset = offset; + __entry->value = value; + ), + TP_printk("%s:0x%03x 0x%08x", __get_str(hw_name), __entry->offset, + __entry->value) +); + +DEFINE_EVENT(register_access, vde_writel, + TP_PROTO(struct tegra_vde *vde, void __iomem *base, + u32 offset, u32 value), + TP_ARGS(vde, base, offset, value)); +DEFINE_EVENT(register_access, vde_readl, + TP_PROTO(struct tegra_vde *vde, void __iomem *base, + u32 offset, u32 value), + TP_ARGS(vde, base, offset, value)); + +TRACE_EVENT(vde_setup_iram_entry, + TP_PROTO(unsigned int table, unsigned int row, u32 value, u32 aux_addr), + TP_ARGS(table, row, value, aux_addr), + TP_STRUCT__entry( + __field(unsigned int, table) + __field(unsigned int, row) + __field(u32, value) + __field(u32, aux_addr) + ), + TP_fast_assign( + __entry->table = table; + __entry->row = row; + __entry->value = value; + __entry->aux_addr = aux_addr; + ), + TP_printk("[%u][%u] = { 0x%08x (flags = \"%s\", frame_num = %u); 0x%08x }", + __entry->table, __entry->row, __entry->value, + __print_flags(__entry->value, " ", { (1 << 25), "B" }), + __entry->value & 0x7FFFFF, __entry->aux_addr) +); + +TRACE_EVENT(vde_ref_l0, + TP_PROTO(unsigned int frame_num), + TP_ARGS(frame_num), + TP_STRUCT__entry( + __field(unsigned int, frame_num) + ), + TP_fast_assign( + __entry->frame_num = frame_num; + ), + TP_printk("REF L0: DPB: Frame 0: frame_num = %u", __entry->frame_num) +); + +TRACE_EVENT(vde_ref_l1, + TP_PROTO(unsigned int with_later_poc_nb, + unsigned int with_earlier_poc_nb), + TP_ARGS(with_later_poc_nb, with_earlier_poc_nb), + TP_STRUCT__entry( + __field(unsigned int, with_later_poc_nb) + __field(unsigned int, with_earlier_poc_nb) + ), + TP_fast_assign( + __entry->with_later_poc_nb = with_later_poc_nb; + __entry->with_earlier_poc_nb = with_earlier_poc_nb; + ), + TP_printk("REF L1: with_later_poc_nb %u, with_earlier_poc_nb %u", + __entry->with_later_poc_nb, __entry->with_earlier_poc_nb) +); + +#endif /* TEGRA_VDE_TRACE_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH ../../drivers/staging/media/tegra-vde +#define TRACE_INCLUDE_FILE trace +#include <trace/define_trace.h> diff --git a/drivers/staging/mt29f_spinand/Kconfig b/drivers/staging/mt29f_spinand/Kconfig deleted file mode 100644 index f3f9cb3b5c35..000000000000 --- a/drivers/staging/mt29f_spinand/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -config MTD_SPINAND_MT29F - tristate "SPINAND Device Support for Micron" - depends on MTD_NAND && SPI - help - This enables support for accessing Micron SPI NAND flash - devices. - If you have Micron SPI NAND chip say yes. - - If unsure, say no here. - -config MTD_SPINAND_ONDIEECC - bool "Use SPINAND internal ECC" - depends on MTD_SPINAND_MT29F - help - Internal ECC. - Enables Hardware ECC support for Micron SPI NAND. diff --git a/drivers/staging/mt29f_spinand/Makefile b/drivers/staging/mt29f_spinand/Makefile deleted file mode 100644 index e47af0f7fda9..000000000000 --- a/drivers/staging/mt29f_spinand/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand.o diff --git a/drivers/staging/mt29f_spinand/TODO b/drivers/staging/mt29f_spinand/TODO deleted file mode 100644 index a2209b72d371..000000000000 --- a/drivers/staging/mt29f_spinand/TODO +++ /dev/null @@ -1,13 +0,0 @@ -TODO: - - Tested on XLP platform, needs to be tested on other platforms. - - Checkpatch.pl cleanups - - Sparce fixes. - - Clean up coding style to meet kernel standard. - -Please send patches -To: -Kamlakant Patel <kamlakant.patel@broadcom.com> -Cc: -Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Mona Anonuevo <manonuevo@micron.com> -linux-mtd@lists.infradead.org diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c deleted file mode 100644 index def8a1f57d1c..000000000000 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ /dev/null @@ -1,980 +0,0 @@ -/* - * Copyright (c) 2003-2013 Broadcom Corporation - * - * Copyright (c) 2009-2010 Micron Technology, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/rawnand.h> -#include <linux/spi/spi.h> - -#include "mt29f_spinand.h" - -#define BUFSIZE (10 * 64 * 2048) -#define CACHE_BUF 2112 -/* - * OOB area specification layout: Total 32 available free bytes. - */ - -static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct spinand_info *info = nand_get_controller_data(chip); - struct spinand_state *state = info->priv; - - return state; -} - -#ifdef CONFIG_MTD_SPINAND_ONDIEECC -static int enable_hw_ecc; -static int enable_read_hw_ecc; - -static int spinand_ooblayout_64_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - if (section > 3) - return -ERANGE; - - oobregion->offset = (section * 16) + 1; - oobregion->length = 6; - - return 0; -} - -static int spinand_ooblayout_64_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - if (section > 3) - return -ERANGE; - - oobregion->offset = (section * 16) + 8; - oobregion->length = 8; - - return 0; -} - -static const struct mtd_ooblayout_ops spinand_oob_64_ops = { - .ecc = spinand_ooblayout_64_ecc, - .free = spinand_ooblayout_64_free, -}; -#endif - -/** - * spinand_cmd - process a command to send to the SPI Nand - * Description: - * Set up the command buffer to send to the SPI controller. - * The command buffer has to initialized to 0. - */ - -static int spinand_cmd(struct spi_device *spi, struct spinand_cmd *cmd) -{ - struct spi_message message; - struct spi_transfer x[4]; - u8 dummy = 0xff; - - spi_message_init(&message); - memset(x, 0, sizeof(x)); - - x[0].len = 1; - x[0].tx_buf = &cmd->cmd; - spi_message_add_tail(&x[0], &message); - - if (cmd->n_addr) { - x[1].len = cmd->n_addr; - x[1].tx_buf = cmd->addr; - spi_message_add_tail(&x[1], &message); - } - - if (cmd->n_dummy) { - x[2].len = cmd->n_dummy; - x[2].tx_buf = &dummy; - spi_message_add_tail(&x[2], &message); - } - - if (cmd->n_tx) { - x[3].len = cmd->n_tx; - x[3].tx_buf = cmd->tx_buf; - spi_message_add_tail(&x[3], &message); - } - - if (cmd->n_rx) { - x[3].len = cmd->n_rx; - x[3].rx_buf = cmd->rx_buf; - spi_message_add_tail(&x[3], &message); - } - - return spi_sync(spi, &message); -} - -/** - * spinand_read_id - Read SPI Nand ID - * Description: - * read two ID bytes from the SPI Nand device - */ -static int spinand_read_id(struct spi_device *spi_nand, u8 *id) -{ - int retval; - u8 nand_id[3]; - struct spinand_cmd cmd = {0}; - - cmd.cmd = CMD_READ_ID; - cmd.n_rx = 3; - cmd.rx_buf = &nand_id[0]; - - retval = spinand_cmd(spi_nand, &cmd); - if (retval < 0) { - dev_err(&spi_nand->dev, "error %d reading id\n", retval); - return retval; - } - id[0] = nand_id[1]; - id[1] = nand_id[2]; - return retval; -} - -/** - * spinand_read_status - send command 0xf to the SPI Nand status register - * Description: - * After read, write, or erase, the Nand device is expected to set the - * busy status. - * This function is to allow reading the status of the command: read, - * write, and erase. - * Once the status turns to be ready, the other status bits also are - * valid status bits. - */ -static int spinand_read_status(struct spi_device *spi_nand, u8 *status) -{ - struct spinand_cmd cmd = {0}; - int ret; - - cmd.cmd = CMD_READ_REG; - cmd.n_addr = 1; - cmd.addr[0] = REG_STATUS; - cmd.n_rx = 1; - cmd.rx_buf = status; - - ret = spinand_cmd(spi_nand, &cmd); - if (ret < 0) - dev_err(&spi_nand->dev, "err: %d read status register\n", ret); - - return ret; -} - -#define MAX_WAIT_JIFFIES (40 * HZ) -static int wait_till_ready(struct spi_device *spi_nand) -{ - unsigned long deadline; - int retval; - u8 stat = 0; - - deadline = jiffies + MAX_WAIT_JIFFIES; - do { - retval = spinand_read_status(spi_nand, &stat); - if (retval < 0) - return -1; - if (!(stat & 0x1)) - break; - - cond_resched(); - } while (!time_after_eq(jiffies, deadline)); - - if ((stat & 0x1) == 0) - return 0; - - return -1; -} - -/** - * spinand_get_otp - send command 0xf to read the SPI Nand OTP register - * Description: - * There is one bit( bit 0x10 ) to set or to clear the internal ECC. - * Enable chip internal ECC, set the bit to 1 - * Disable chip internal ECC, clear the bit to 0 - */ -static int spinand_get_otp(struct spi_device *spi_nand, u8 *otp) -{ - struct spinand_cmd cmd = {0}; - int retval; - - cmd.cmd = CMD_READ_REG; - cmd.n_addr = 1; - cmd.addr[0] = REG_OTP; - cmd.n_rx = 1; - cmd.rx_buf = otp; - - retval = spinand_cmd(spi_nand, &cmd); - if (retval < 0) - dev_err(&spi_nand->dev, "error %d get otp\n", retval); - return retval; -} - -/** - * spinand_set_otp - send command 0x1f to write the SPI Nand OTP register - * Description: - * There is one bit( bit 0x10 ) to set or to clear the internal ECC. - * Enable chip internal ECC, set the bit to 1 - * Disable chip internal ECC, clear the bit to 0 - */ -static int spinand_set_otp(struct spi_device *spi_nand, u8 *otp) -{ - int retval; - struct spinand_cmd cmd = {0}; - - cmd.cmd = CMD_WRITE_REG; - cmd.n_addr = 1; - cmd.addr[0] = REG_OTP; - cmd.n_tx = 1; - cmd.tx_buf = otp; - - retval = spinand_cmd(spi_nand, &cmd); - if (retval < 0) - dev_err(&spi_nand->dev, "error %d set otp\n", retval); - - return retval; -} - -#ifdef CONFIG_MTD_SPINAND_ONDIEECC -/** - * spinand_enable_ecc - send command 0x1f to write the SPI Nand OTP register - * Description: - * There is one bit( bit 0x10 ) to set or to clear the internal ECC. - * Enable chip internal ECC, set the bit to 1 - * Disable chip internal ECC, clear the bit to 0 - */ -static int spinand_enable_ecc(struct spi_device *spi_nand) -{ - int retval; - u8 otp = 0; - - retval = spinand_get_otp(spi_nand, &otp); - if (retval < 0) - return retval; - - if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) - return 0; - otp |= OTP_ECC_MASK; - retval = spinand_set_otp(spi_nand, &otp); - if (retval < 0) - return retval; - return spinand_get_otp(spi_nand, &otp); -} -#endif - -static int spinand_disable_ecc(struct spi_device *spi_nand) -{ - int retval; - u8 otp = 0; - - retval = spinand_get_otp(spi_nand, &otp); - if (retval < 0) - return retval; - - if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) { - otp &= ~OTP_ECC_MASK; - retval = spinand_set_otp(spi_nand, &otp); - if (retval < 0) - return retval; - return spinand_get_otp(spi_nand, &otp); - } - return 0; -} - -/** - * spinand_write_enable - send command 0x06 to enable write or erase the - * Nand cells - * Description: - * Before write and erase the Nand cells, the write enable has to be set. - * After the write or erase, the write enable bit is automatically - * cleared (status register bit 2) - * Set the bit 2 of the status register has the same effect - */ -static int spinand_write_enable(struct spi_device *spi_nand) -{ - struct spinand_cmd cmd = {0}; - - cmd.cmd = CMD_WR_ENABLE; - return spinand_cmd(spi_nand, &cmd); -} - -static int spinand_read_page_to_cache(struct spi_device *spi_nand, u16 page_id) -{ - struct spinand_cmd cmd = {0}; - u16 row; - - row = page_id; - cmd.cmd = CMD_READ; - cmd.n_addr = 3; - cmd.addr[0] = (u8)((row & 0xff0000) >> 16); - cmd.addr[1] = (u8)((row & 0xff00) >> 8); - cmd.addr[2] = (u8)(row & 0x00ff); - - return spinand_cmd(spi_nand, &cmd); -} - -/** - * spinand_read_from_cache - send command 0x03 to read out the data from the - * cache register (2112 bytes max) - * Description: - * The read can specify 1 to 2112 bytes of data read at the corresponding - * locations. - * No tRd delay. - */ -static int spinand_read_from_cache(struct spi_device *spi_nand, u16 page_id, - u16 byte_id, u16 len, u8 *rbuf) -{ - struct spinand_cmd cmd = {0}; - u16 column; - - column = byte_id; - cmd.cmd = CMD_READ_RDM; - cmd.n_addr = 3; - cmd.addr[0] = (u8)((column & 0xff00) >> 8); - cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4); - cmd.addr[1] = (u8)(column & 0x00ff); - cmd.addr[2] = (u8)(0xff); - cmd.n_dummy = 0; - cmd.n_rx = len; - cmd.rx_buf = rbuf; - - return spinand_cmd(spi_nand, &cmd); -} - -/** - * spinand_read_page - read a page - * @page_id: the physical page number - * @offset: the location from 0 to 2111 - * @len: number of bytes to read - * @rbuf: read buffer to hold @len bytes - * - * Description: - * The read includes two commands to the Nand - 0x13 and 0x03 commands - * Poll to read status to wait for tRD time. - */ -static int spinand_read_page(struct spi_device *spi_nand, u16 page_id, - u16 offset, u16 len, u8 *rbuf) -{ - int ret; - u8 status = 0; - -#ifdef CONFIG_MTD_SPINAND_ONDIEECC - if (enable_read_hw_ecc) { - if (spinand_enable_ecc(spi_nand) < 0) - dev_err(&spi_nand->dev, "enable HW ECC failed!"); - } -#endif - ret = spinand_read_page_to_cache(spi_nand, page_id); - if (ret < 0) - return ret; - - if (wait_till_ready(spi_nand)) - dev_err(&spi_nand->dev, "WAIT timedout!!!\n"); - - while (1) { - ret = spinand_read_status(spi_nand, &status); - if (ret < 0) { - dev_err(&spi_nand->dev, - "err %d read status register\n", ret); - return ret; - } - - if ((status & STATUS_OIP_MASK) == STATUS_READY) { - if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) { - dev_err(&spi_nand->dev, "ecc error, page=%d\n", - page_id); - return 0; - } - break; - } - } - - ret = spinand_read_from_cache(spi_nand, page_id, offset, len, rbuf); - if (ret < 0) { - dev_err(&spi_nand->dev, "read from cache failed!!\n"); - return ret; - } - -#ifdef CONFIG_MTD_SPINAND_ONDIEECC - if (enable_read_hw_ecc) { - ret = spinand_disable_ecc(spi_nand); - if (ret < 0) { - dev_err(&spi_nand->dev, "disable ecc failed!!\n"); - return ret; - } - enable_read_hw_ecc = 0; - } -#endif - return ret; -} - -/** - * spinand_program_data_to_cache - write a page to cache - * @byte_id: the location to write to the cache - * @len: number of bytes to write - * @wbuf: write buffer holding @len bytes - * - * Description: - * The write command used here is 0x84--indicating that the cache is - * not cleared first. - * Since it is writing the data to cache, there is no tPROG time. - */ -static int spinand_program_data_to_cache(struct spi_device *spi_nand, - u16 page_id, u16 byte_id, - u16 len, u8 *wbuf) -{ - struct spinand_cmd cmd = {0}; - u16 column; - - column = byte_id; - cmd.cmd = CMD_PROG_PAGE_CLRCACHE; - cmd.n_addr = 2; - cmd.addr[0] = (u8)((column & 0xff00) >> 8); - cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4); - cmd.addr[1] = (u8)(column & 0x00ff); - cmd.n_tx = len; - cmd.tx_buf = wbuf; - - return spinand_cmd(spi_nand, &cmd); -} - -/** - * spinand_program_execute - write a page from cache to the Nand array - * @page_id: the physical page location to write the page. - * - * Description: - * The write command used here is 0x10--indicating the cache is writing to - * the Nand array. - * Need to wait for tPROG time to finish the transaction. - */ -static int spinand_program_execute(struct spi_device *spi_nand, u16 page_id) -{ - struct spinand_cmd cmd = {0}; - u16 row; - - row = page_id; - cmd.cmd = CMD_PROG_PAGE_EXC; - cmd.n_addr = 3; - cmd.addr[0] = (u8)((row & 0xff0000) >> 16); - cmd.addr[1] = (u8)((row & 0xff00) >> 8); - cmd.addr[2] = (u8)(row & 0x00ff); - - return spinand_cmd(spi_nand, &cmd); -} - -/** - * spinand_program_page - write a page - * @page_id: the physical page location to write the page. - * @offset: the location from the cache starting from 0 to 2111 - * @len: the number of bytes to write - * @buf: the buffer holding @len bytes - * - * Description: - * The commands used here are 0x06, 0x84, and 0x10--indicating that - * the write enable is first sent, the write cache command, and the - * write execute command. - * Poll to wait for the tPROG time to finish the transaction. - */ -static int spinand_program_page(struct spi_device *spi_nand, - u16 page_id, u16 offset, u16 len, u8 *buf) -{ - int retval; - u8 status = 0; - u8 *wbuf; -#ifdef CONFIG_MTD_SPINAND_ONDIEECC - unsigned int i, j; - - wbuf = devm_kzalloc(&spi_nand->dev, CACHE_BUF, GFP_KERNEL); - if (!wbuf) - return -ENOMEM; - - enable_read_hw_ecc = 1; - retval = spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf); - if (retval < 0) { - dev_err(&spi_nand->dev, "ecc error on read page!!!\n"); - return retval; - } - - for (i = offset, j = 0; i < len; i++, j++) - wbuf[i] &= buf[j]; - - if (enable_hw_ecc) { - retval = spinand_enable_ecc(spi_nand); - if (retval < 0) { - dev_err(&spi_nand->dev, "enable ecc failed!!\n"); - return retval; - } - } -#else - wbuf = buf; -#endif - retval = spinand_write_enable(spi_nand); - if (retval < 0) { - dev_err(&spi_nand->dev, "write enable failed!!\n"); - return retval; - } - if (wait_till_ready(spi_nand)) - dev_err(&spi_nand->dev, "wait timedout!!!\n"); - - retval = spinand_program_data_to_cache(spi_nand, page_id, - offset, len, wbuf); - if (retval < 0) - return retval; - retval = spinand_program_execute(spi_nand, page_id); - if (retval < 0) - return retval; - while (1) { - retval = spinand_read_status(spi_nand, &status); - if (retval < 0) { - dev_err(&spi_nand->dev, - "error %d reading status register\n", retval); - return retval; - } - - if ((status & STATUS_OIP_MASK) == STATUS_READY) { - if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL) { - dev_err(&spi_nand->dev, - "program error, page %d\n", page_id); - return -1; - } - break; - } - } -#ifdef CONFIG_MTD_SPINAND_ONDIEECC - if (enable_hw_ecc) { - retval = spinand_disable_ecc(spi_nand); - if (retval < 0) { - dev_err(&spi_nand->dev, "disable ecc failed!!\n"); - return retval; - } - enable_hw_ecc = 0; - } -#endif - - return 0; -} - -/** - * spinand_erase_block_erase - erase a page - * @block_id: the physical block location to erase. - * - * Description: - * The command used here is 0xd8--indicating an erase command to erase - * one block--64 pages - * Need to wait for tERS. - */ -static int spinand_erase_block_erase(struct spi_device *spi_nand, u16 block_id) -{ - struct spinand_cmd cmd = {0}; - u16 row; - - row = block_id; - cmd.cmd = CMD_ERASE_BLK; - cmd.n_addr = 3; - cmd.addr[0] = (u8)((row & 0xff0000) >> 16); - cmd.addr[1] = (u8)((row & 0xff00) >> 8); - cmd.addr[2] = (u8)(row & 0x00ff); - - return spinand_cmd(spi_nand, &cmd); -} - -/** - * spinand_erase_block - erase a page - * @block_id: the physical block location to erase. - * - * Description: - * The commands used here are 0x06 and 0xd8--indicating an erase - * command to erase one block--64 pages - * It will first to enable the write enable bit (0x06 command), - * and then send the 0xd8 erase command - * Poll to wait for the tERS time to complete the tranaction. - */ -static int spinand_erase_block(struct spi_device *spi_nand, u16 block_id) -{ - int retval; - u8 status = 0; - - retval = spinand_write_enable(spi_nand); - if (wait_till_ready(spi_nand)) - dev_err(&spi_nand->dev, "wait timedout!!!\n"); - - retval = spinand_erase_block_erase(spi_nand, block_id); - while (1) { - retval = spinand_read_status(spi_nand, &status); - if (retval < 0) { - dev_err(&spi_nand->dev, - "error %d reading status register\n", retval); - return retval; - } - - if ((status & STATUS_OIP_MASK) == STATUS_READY) { - if ((status & STATUS_E_FAIL_MASK) == STATUS_E_FAIL) { - dev_err(&spi_nand->dev, - "erase error, block %d\n", block_id); - return -1; - } - break; - } - } - return 0; -} - -#ifdef CONFIG_MTD_SPINAND_ONDIEECC -static int spinand_write_page_hwecc(struct nand_chip *chip, - const u8 *buf, int oob_required, - int page) -{ - const u8 *p = buf; - int eccsize = chip->ecc.size; - int eccsteps = chip->ecc.steps; - - enable_hw_ecc = 1; - return nand_prog_page_op(chip, page, 0, p, eccsize * eccsteps); -} - -static int spinand_read_page_hwecc(struct nand_chip *chip, u8 *buf, - int oob_required, int page) -{ - int retval; - u8 status; - u8 *p = buf; - int eccsize = chip->ecc.size; - int eccsteps = chip->ecc.steps; - struct mtd_info *mtd = nand_to_mtd(chip); - struct spinand_info *info = nand_get_controller_data(chip); - - enable_read_hw_ecc = 1; - - nand_read_page_op(chip, page, 0, p, eccsize * eccsteps); - if (oob_required) - chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize); - - while (1) { - retval = spinand_read_status(info->spi, &status); - if (retval < 0) { - dev_err(&mtd->dev, - "error %d reading status register\n", retval); - return retval; - } - - if ((status & STATUS_OIP_MASK) == STATUS_READY) { - if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) { - pr_info("spinand: ECC error\n"); - mtd->ecc_stats.failed++; - } else if ((status & STATUS_ECC_MASK) == - STATUS_ECC_1BIT_CORRECTED) - mtd->ecc_stats.corrected++; - break; - } - } - return 0; -} -#endif - -static void spinand_select_chip(struct nand_chip *chip, int dev) -{ -} - -static u8 spinand_read_byte(struct nand_chip *chip) -{ - struct spinand_state *state = mtd_to_state(nand_to_mtd(chip)); - u8 data; - - data = state->buf[state->buf_ptr]; - state->buf_ptr++; - return data; -} - -static int spinand_wait(struct nand_chip *chip) -{ - struct mtd_info *mtd = nand_to_mtd(chip); - struct spinand_info *info = nand_get_controller_data(chip); - - unsigned long timeo = jiffies; - int retval, state = chip->state; - u8 status; - - if (state == FL_ERASING) - timeo += (HZ * 400) / 1000; - else - timeo += (HZ * 20) / 1000; - - while (time_before(jiffies, timeo)) { - retval = spinand_read_status(info->spi, &status); - if (retval < 0) { - dev_err(&mtd->dev, - "error %d reading status register\n", retval); - return retval; - } - - if ((status & STATUS_OIP_MASK) == STATUS_READY) - return 0; - - cond_resched(); - } - return 0; -} - -static void spinand_write_buf(struct nand_chip *chip, const u8 *buf, int len) -{ - struct spinand_state *state = mtd_to_state(nand_to_mtd(chip)); - - memcpy(state->buf + state->buf_ptr, buf, len); - state->buf_ptr += len; -} - -static void spinand_read_buf(struct nand_chip *chip, u8 *buf, int len) -{ - struct spinand_state *state = mtd_to_state(nand_to_mtd(chip)); - - memcpy(buf, state->buf + state->buf_ptr, len); - state->buf_ptr += len; -} - -/* - * spinand_reset- send RESET command "0xff" to the Nand device. - */ -static void spinand_reset(struct spi_device *spi_nand) -{ - struct spinand_cmd cmd = {0}; - - cmd.cmd = CMD_RESET; - - if (spinand_cmd(spi_nand, &cmd) < 0) - pr_info("spinand reset failed!\n"); - - /* elapse 1ms before issuing any other command */ - usleep_range(1000, 2000); - - if (wait_till_ready(spi_nand)) - dev_err(&spi_nand->dev, "wait timedout!\n"); -} - -static void spinand_cmdfunc(struct nand_chip *chip, unsigned int command, - int column, int page) -{ - struct mtd_info *mtd = nand_to_mtd(chip); - struct spinand_info *info = nand_get_controller_data(chip); - struct spinand_state *state = info->priv; - - switch (command) { - /* - * READ0 - read in first 0x800 bytes - */ - case NAND_CMD_READ1: - case NAND_CMD_READ0: - state->buf_ptr = 0; - spinand_read_page(info->spi, page, 0x0, 0x840, state->buf); - break; - /* READOOB reads only the OOB because no ECC is performed. */ - case NAND_CMD_READOOB: - state->buf_ptr = 0; - spinand_read_page(info->spi, page, 0x800, 0x40, state->buf); - break; - case NAND_CMD_RNDOUT: - state->buf_ptr = column; - break; - case NAND_CMD_READID: - state->buf_ptr = 0; - spinand_read_id(info->spi, state->buf); - break; - case NAND_CMD_PARAM: - state->buf_ptr = 0; - break; - /* ERASE1 stores the block and page address */ - case NAND_CMD_ERASE1: - spinand_erase_block(info->spi, page); - break; - /* ERASE2 uses the block and page address from ERASE1 */ - case NAND_CMD_ERASE2: - break; - /* SEQIN sets up the addr buffer and all registers except the length */ - case NAND_CMD_SEQIN: - state->col = column; - state->row = page; - state->buf_ptr = 0; - break; - /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ - case NAND_CMD_PAGEPROG: - spinand_program_page(info->spi, state->row, state->col, - state->buf_ptr, state->buf); - break; - case NAND_CMD_STATUS: - spinand_get_otp(info->spi, state->buf); - if (!(state->buf[0] & 0x80)) - state->buf[0] = 0x80; - state->buf_ptr = 0; - break; - /* RESET command */ - case NAND_CMD_RESET: - if (wait_till_ready(info->spi)) - dev_err(&info->spi->dev, "WAIT timedout!!!\n"); - /* a minimum of 250us must elapse before issuing RESET cmd*/ - usleep_range(250, 1000); - spinand_reset(info->spi); - break; - default: - dev_err(&mtd->dev, "Unknown CMD: 0x%x\n", command); - } -} - -/** - * spinand_lock_block - send write register 0x1f command to the Nand device - * - * Description: - * After power up, all the Nand blocks are locked. This function allows - * one to unlock the blocks, and so it can be written or erased. - */ -static int spinand_lock_block(struct spi_device *spi_nand, u8 lock) -{ - struct spinand_cmd cmd = {0}; - int ret; - u8 otp = 0; - - ret = spinand_get_otp(spi_nand, &otp); - - cmd.cmd = CMD_WRITE_REG; - cmd.n_addr = 1; - cmd.addr[0] = REG_BLOCK_LOCK; - cmd.n_tx = 1; - cmd.tx_buf = &lock; - - ret = spinand_cmd(spi_nand, &cmd); - if (ret < 0) - dev_err(&spi_nand->dev, "error %d lock block\n", ret); - - return ret; -} - -/** - * spinand_probe - [spinand Interface] - * @spi_nand: registered device driver. - * - * Description: - * Set up the device driver parameters to make the device available. - */ -static int spinand_probe(struct spi_device *spi_nand) -{ - struct mtd_info *mtd; - struct nand_chip *chip; - struct spinand_info *info; - struct spinand_state *state; - - info = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info), - GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->spi = spi_nand; - - spinand_lock_block(spi_nand, BL_ALL_UNLOCKED); - - state = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_state), - GFP_KERNEL); - if (!state) - return -ENOMEM; - - info->priv = state; - state->buf_ptr = 0; - state->buf = devm_kzalloc(&spi_nand->dev, BUFSIZE, GFP_KERNEL); - if (!state->buf) - return -ENOMEM; - - chip = devm_kzalloc(&spi_nand->dev, sizeof(struct nand_chip), - GFP_KERNEL); - if (!chip) - return -ENOMEM; - -#ifdef CONFIG_MTD_SPINAND_ONDIEECC - chip->ecc.mode = NAND_ECC_HW; - chip->ecc.size = 0x200; - chip->ecc.bytes = 0x6; - chip->ecc.steps = 0x4; - - chip->ecc.strength = 1; - chip->ecc.total = chip->ecc.steps * chip->ecc.bytes; - chip->ecc.read_page = spinand_read_page_hwecc; - chip->ecc.write_page = spinand_write_page_hwecc; -#else - chip->ecc.mode = NAND_ECC_SOFT; - chip->ecc.algo = NAND_ECC_HAMMING; - if (spinand_disable_ecc(spi_nand) < 0) - dev_info(&spi_nand->dev, "%s: disable ecc failed!\n", - __func__); -#endif - - nand_set_flash_node(chip, spi_nand->dev.of_node); - nand_set_controller_data(chip, info); - chip->legacy.read_buf = spinand_read_buf; - chip->legacy.write_buf = spinand_write_buf; - chip->legacy.read_byte = spinand_read_byte; - chip->legacy.cmdfunc = spinand_cmdfunc; - chip->legacy.waitfunc = spinand_wait; - chip->options |= NAND_CACHEPRG; - chip->select_chip = spinand_select_chip; - chip->legacy.set_features = nand_get_set_features_notsupp; - chip->legacy.get_features = nand_get_set_features_notsupp; - - mtd = nand_to_mtd(chip); - - dev_set_drvdata(&spi_nand->dev, mtd); - - mtd->dev.parent = &spi_nand->dev; - mtd->oobsize = 64; -#ifdef CONFIG_MTD_SPINAND_ONDIEECC - mtd_set_ooblayout(mtd, &spinand_oob_64_ops); -#endif - - if (nand_scan(chip, 1)) - return -ENXIO; - - return mtd_device_register(mtd, NULL, 0); -} - -/** - * spinand_remove - remove the device driver - * @spi: the spi device. - * - * Description: - * Remove the device driver parameters and free up allocated memories. - */ -static int spinand_remove(struct spi_device *spi) -{ - mtd_device_unregister(dev_get_drvdata(&spi->dev)); - - return 0; -} - -static const struct of_device_id spinand_dt[] = { - { .compatible = "spinand,mt29f", }, - {} -}; -MODULE_DEVICE_TABLE(of, spinand_dt); - -/* - * Device name structure description - */ -static struct spi_driver spinand_driver = { - .driver = { - .name = "mt29f", - .of_match_table = spinand_dt, - }, - .probe = spinand_probe, - .remove = spinand_remove, -}; - -module_spi_driver(spinand_driver); - -MODULE_DESCRIPTION("SPI NAND driver for Micron"); -MODULE_AUTHOR("Henry Pan <hspan@micron.com>, Kamlakant Patel <kamlakant.patel@broadcom.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.h b/drivers/staging/mt29f_spinand/mt29f_spinand.h deleted file mode 100644 index 457dc7ffdaf1..000000000000 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.h +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * Copyright 2013 Broadcom Corporation - * - * Copyright (c) 2009-2010 Micron Technology, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Henry Pan <hspan@micron.com> - * - * based on nand.h - */ -#ifndef __LINUX_MTD_SPI_NAND_H -#define __LINUX_MTD_SPI_NAND_H - -#include <linux/wait.h> -#include <linux/spinlock.h> -#include <linux/mtd/mtd.h> - -/* cmd */ -#define CMD_READ 0x13 -#define CMD_READ_RDM 0x03 -#define CMD_PROG_PAGE_CLRCACHE 0x02 -#define CMD_PROG_PAGE 0x84 -#define CMD_PROG_PAGE_EXC 0x10 -#define CMD_ERASE_BLK 0xd8 -#define CMD_WR_ENABLE 0x06 -#define CMD_WR_DISABLE 0x04 -#define CMD_READ_ID 0x9f -#define CMD_RESET 0xff -#define CMD_READ_REG 0x0f -#define CMD_WRITE_REG 0x1f - -/* feature/ status reg */ -#define REG_BLOCK_LOCK 0xa0 -#define REG_OTP 0xb0 -#define REG_STATUS 0xc0/* timing */ - -/* status */ -#define STATUS_OIP_MASK 0x01 -#define STATUS_READY 0 -#define STATUS_BUSY BIT(0) - -#define STATUS_E_FAIL_MASK 0x04 -#define STATUS_E_FAIL BIT(2) - -#define STATUS_P_FAIL_MASK 0x08 -#define STATUS_P_FAIL BIT(3) - -#define STATUS_ECC_MASK 0x30 -#define STATUS_ECC_1BIT_CORRECTED BIT(4) -#define STATUS_ECC_ERROR BIT(5) -#define STATUS_ECC_RESERVED (BIT(5) | BIT(4)) - -/*ECC enable defines*/ -#define OTP_ECC_MASK 0x10 -#define OTP_ECC_OFF 0 -#define OTP_ECC_ON 1 - -#define ECC_DISABLED -#define ECC_IN_NAND -#define ECC_SOFT - -/* block lock */ -#define BL_ALL_LOCKED 0x38 -#define BL_1_2_LOCKED 0x30 -#define BL_1_4_LOCKED 0x28 -#define BL_1_8_LOCKED 0x20 -#define BL_1_16_LOCKED 0x18 -#define BL_1_32_LOCKED 0x10 -#define BL_1_64_LOCKED 0x08 -#define BL_ALL_UNLOCKED 0 - -struct spinand_info { - struct spi_device *spi; - void *priv; -}; - -struct spinand_state { - u32 col; - u32 row; - int buf_ptr; - u8 *buf; -}; - -struct spinand_cmd { - u8 cmd; - u32 n_addr; /* Number of address */ - u8 addr[3]; /* Reg Offset */ - u32 n_dummy; /* Dummy use */ - u32 n_tx; /* Number of tx bytes */ - u8 *tx_buf; /* Tx buf */ - u32 n_rx; /* Number of rx bytes */ - u8 *rx_buf; /* Rx buf */ -}; - -int spinand_mtd(struct mtd_info *mtd); -void spinand_mtd_release(struct mtd_info *mtd); - -#endif /* __LINUX_MTD_SPI_NAND_H */ diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index df3441b815bb..317c9720467c 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -359,8 +359,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) dst_release(skb_dst(skb)); skb_dst_set(skb, NULL); #ifdef CONFIG_XFRM - secpath_put(skb->sp); - skb->sp = NULL; + secpath_reset(skb); #endif nf_reset(skb); diff --git a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c index 9a4d56ec5e0c..2581ed6d14fa 100644 --- a/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c @@ -62,7 +62,7 @@ static void *rtllib_ccmp_init(int key_idx) goto fail; priv->key_idx = key_idx; - priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + priv->tfm = (void *)crypto_alloc_cipher("aes", 0, 0); if (IS_ERR(priv->tfm)) { pr_debug("Could not allocate crypto API aes\n"); priv->tfm = NULL; diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c index 041f1b123888..3534ddb900d1 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c @@ -71,7 +71,7 @@ static void *ieee80211_ccmp_init(int key_idx) goto fail; priv->key_idx = key_idx; - priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + priv->tfm = (void *)crypto_alloc_cipher("aes", 0, 0); if (IS_ERR(priv->tfm)) { pr_debug("ieee80211_crypt_ccmp: could not allocate crypto API aes\n"); priv->tfm = NULL; diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index e27687719d1d..fa597953e9a0 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -226,12 +226,6 @@ static struct scsi_host_template rtsx_host_template = { /* limit the total size of a transfer to 120 KB */ .max_sectors = 240, - /* merge commands... this seems to help performance, but - * periodically someone should test to see which setting is more - * optimal. - */ - .use_clustering = 1, - /* emulated HBA */ .emulated = 1, diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index d0fed63c13a2..2dad36a05518 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -645,7 +645,6 @@ static struct scsi_host_template visorhba_driver_template = { .this_id = -1, .slave_alloc = visorhba_slave_alloc, .slave_destroy = visorhba_slave_destroy, - .use_clustering = ENABLE_CLUSTERING, }; /* diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 3647b8f1ed28..5eeb4b93b45b 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -2095,7 +2095,7 @@ static int visornic_resume(struct visor_device *dev, mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2)); rtnl_lock(); - dev_open(netdev); + dev_open(netdev, NULL); rtnl_unlock(); complete_func(dev, 0); diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c index 80d7395e48dc..cc6532d8c2fa 100644 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ b/drivers/staging/vboxvideo/vbox_drv.c @@ -241,7 +241,6 @@ static struct drm_driver driver = { .gem_free_object_unlocked = vbox_gem_free_object, .dumb_create = vbox_dumb_create, .dumb_map_offset = vbox_dumb_mmap_offset, - .dumb_destroy = drm_gem_dumb_destroy, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = drm_gem_prime_export, diff --git a/drivers/staging/vboxvideo/vbox_drv.h b/drivers/staging/vboxvideo/vbox_drv.h index e2a6b2b5bfc3..aa40e5cc2861 100644 --- a/drivers/staging/vboxvideo/vbox_drv.h +++ b/drivers/staging/vboxvideo/vbox_drv.h @@ -79,8 +79,6 @@ struct vbox_private { int fb_mtrr; struct { - struct drm_global_reference mem_global_ref; - struct ttm_bo_global_ref bo_global_ref; struct ttm_bo_device bdev; } ttm; diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c index edc8686454bf..30f270027acf 100644 --- a/drivers/staging/vboxvideo/vbox_ttm.c +++ b/drivers/staging/vboxvideo/vbox_ttm.c @@ -16,57 +16,6 @@ static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd) return container_of(bd, struct vbox_private, ttm.bdev); } -static int vbox_ttm_mem_global_init(struct drm_global_reference *ref) -{ - return ttm_mem_global_init(ref->object); -} - -static void vbox_ttm_mem_global_release(struct drm_global_reference *ref) -{ - ttm_mem_global_release(ref->object); -} - -/* Add the vbox memory manager object/structures to the global memory manager */ -static int vbox_ttm_global_init(struct vbox_private *vbox) -{ - struct drm_global_reference *global_ref; - int ret; - - global_ref = &vbox->ttm.mem_global_ref; - global_ref->global_type = DRM_GLOBAL_TTM_MEM; - global_ref->size = sizeof(struct ttm_mem_global); - global_ref->init = &vbox_ttm_mem_global_init; - global_ref->release = &vbox_ttm_mem_global_release; - ret = drm_global_item_ref(global_ref); - if (ret) { - DRM_ERROR("Failed setting up TTM memory subsystem.\n"); - return ret; - } - - vbox->ttm.bo_global_ref.mem_glob = vbox->ttm.mem_global_ref.object; - global_ref = &vbox->ttm.bo_global_ref.ref; - global_ref->global_type = DRM_GLOBAL_TTM_BO; - global_ref->size = sizeof(struct ttm_bo_global); - global_ref->init = &ttm_bo_global_init; - global_ref->release = &ttm_bo_global_release; - - ret = drm_global_item_ref(global_ref); - if (ret) { - DRM_ERROR("Failed setting up TTM BO subsystem.\n"); - drm_global_item_unref(&vbox->ttm.mem_global_ref); - return ret; - } - - return 0; -} - -/* Remove the vbox memory manager object from the global memory manager */ -static void vbox_ttm_global_release(struct vbox_private *vbox) -{ - drm_global_item_unref(&vbox->ttm.bo_global_ref.ref); - drm_global_item_unref(&vbox->ttm.mem_global_ref); -} - static void vbox_bo_ttm_destroy(struct ttm_buffer_object *tbo) { struct vbox_bo *bo; @@ -204,18 +153,13 @@ int vbox_mm_init(struct vbox_private *vbox) struct drm_device *dev = &vbox->ddev; struct ttm_bo_device *bdev = &vbox->ttm.bdev; - ret = vbox_ttm_global_init(vbox); - if (ret) - return ret; - ret = ttm_bo_device_init(&vbox->ttm.bdev, - vbox->ttm.bo_global_ref.ref.object, &vbox_bo_driver, dev->anon_inode->i_mapping, DRM_FILE_PAGE_OFFSET, true); if (ret) { DRM_ERROR("Error initialising bo driver; %d\n", ret); - goto err_ttm_global_release; + return ret; } ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, @@ -237,8 +181,6 @@ int vbox_mm_init(struct vbox_private *vbox) err_device_release: ttm_bo_device_release(&vbox->ttm.bdev); -err_ttm_global_release: - vbox_ttm_global_release(vbox); return ret; } @@ -252,7 +194,6 @@ void vbox_mm_fini(struct vbox_private *vbox) arch_phys_wc_del(vbox->fb_mtrr); #endif ttm_bo_device_release(&vbox->ttm.bdev); - vbox_ttm_global_release(vbox); } void vbox_ttm_placement(struct vbox_bo *bo, int domain) |