From 8148baabd1c4b02c0af3002d59a1c92975d2e719 Mon Sep 17 00:00:00 2001
From: Pratyush Yadav
Date: Fri, 21 Jan 2022 19:59:00 +0530
Subject: media: platform: re-structure TI drivers
The ti-vpe/ sub-directory does not only contain the VPE-specific things.
It also contains the CAL driver, which is a completely different
subsystem. This is also not a good place to add new drivers for other TI
platforms since they will all get mixed up.
Separate the VPE and CAL parts into different sub-directories and rename
the ti-vpe/ sub-directory to ti/. This is now the place where new TI
platform drivers can be added.
[mchehab: rebased to apple on the top of media/platform/Kconfig series]
Signed-off-by: Pratyush Yadav
Reviewed-by: Tomi Valkeinen
Reviewed-by: Laurent Pinchart
Signed-off-by: Mauro Carvalho Chehab
---
drivers/media/platform/Makefile | 6 +-
drivers/media/platform/ti-vpe/Makefile | 16 -
drivers/media/platform/ti-vpe/cal-camerarx.c | 915 ---------
drivers/media/platform/ti-vpe/cal-video.c | 1049 ----------
drivers/media/platform/ti-vpe/cal.c | 1263 ------------
drivers/media/platform/ti-vpe/cal.h | 343 ----
drivers/media/platform/ti-vpe/cal_regs.h | 463 -----
drivers/media/platform/ti-vpe/csc.c | 279 ---
drivers/media/platform/ti-vpe/csc.h | 65 -
drivers/media/platform/ti-vpe/sc.c | 306 ---
drivers/media/platform/ti-vpe/sc.h | 208 --
drivers/media/platform/ti-vpe/sc_coeff.h | 1339 -------------
drivers/media/platform/ti-vpe/vpdma.c | 1176 ------------
drivers/media/platform/ti-vpe/vpdma.h | 284 ---
drivers/media/platform/ti-vpe/vpdma_priv.h | 639 ------
drivers/media/platform/ti-vpe/vpe.c | 2665 --------------------------
drivers/media/platform/ti-vpe/vpe_regs.h | 306 ---
drivers/media/platform/ti/Makefile | 3 +
drivers/media/platform/ti/cal/Makefile | 3 +
drivers/media/platform/ti/cal/cal-camerarx.c | 915 +++++++++
drivers/media/platform/ti/cal/cal-video.c | 1049 ++++++++++
drivers/media/platform/ti/cal/cal.c | 1263 ++++++++++++
drivers/media/platform/ti/cal/cal.h | 343 ++++
drivers/media/platform/ti/cal/cal_regs.h | 463 +++++
drivers/media/platform/ti/vpe/Makefile | 12 +
drivers/media/platform/ti/vpe/csc.c | 279 +++
drivers/media/platform/ti/vpe/csc.h | 65 +
drivers/media/platform/ti/vpe/sc.c | 306 +++
drivers/media/platform/ti/vpe/sc.h | 208 ++
drivers/media/platform/ti/vpe/sc_coeff.h | 1339 +++++++++++++
drivers/media/platform/ti/vpe/vpdma.c | 1176 ++++++++++++
drivers/media/platform/ti/vpe/vpdma.h | 284 +++
drivers/media/platform/ti/vpe/vpdma_priv.h | 639 ++++++
drivers/media/platform/ti/vpe/vpe.c | 2665 ++++++++++++++++++++++++++
drivers/media/platform/ti/vpe/vpe_regs.h | 306 +++
35 files changed, 11319 insertions(+), 11321 deletions(-)
delete mode 100644 drivers/media/platform/ti-vpe/Makefile
delete mode 100644 drivers/media/platform/ti-vpe/cal-camerarx.c
delete mode 100644 drivers/media/platform/ti-vpe/cal-video.c
delete mode 100644 drivers/media/platform/ti-vpe/cal.c
delete mode 100644 drivers/media/platform/ti-vpe/cal.h
delete mode 100644 drivers/media/platform/ti-vpe/cal_regs.h
delete mode 100644 drivers/media/platform/ti-vpe/csc.c
delete mode 100644 drivers/media/platform/ti-vpe/csc.h
delete mode 100644 drivers/media/platform/ti-vpe/sc.c
delete mode 100644 drivers/media/platform/ti-vpe/sc.h
delete mode 100644 drivers/media/platform/ti-vpe/sc_coeff.h
delete mode 100644 drivers/media/platform/ti-vpe/vpdma.c
delete mode 100644 drivers/media/platform/ti-vpe/vpdma.h
delete mode 100644 drivers/media/platform/ti-vpe/vpdma_priv.h
delete mode 100644 drivers/media/platform/ti-vpe/vpe.c
delete mode 100644 drivers/media/platform/ti-vpe/vpe_regs.h
create mode 100644 drivers/media/platform/ti/Makefile
create mode 100644 drivers/media/platform/ti/cal/Makefile
create mode 100644 drivers/media/platform/ti/cal/cal-camerarx.c
create mode 100644 drivers/media/platform/ti/cal/cal-video.c
create mode 100644 drivers/media/platform/ti/cal/cal.c
create mode 100644 drivers/media/platform/ti/cal/cal.h
create mode 100644 drivers/media/platform/ti/cal/cal_regs.h
create mode 100644 drivers/media/platform/ti/vpe/Makefile
create mode 100644 drivers/media/platform/ti/vpe/csc.c
create mode 100644 drivers/media/platform/ti/vpe/csc.h
create mode 100644 drivers/media/platform/ti/vpe/sc.c
create mode 100644 drivers/media/platform/ti/vpe/sc.h
create mode 100644 drivers/media/platform/ti/vpe/sc_coeff.h
create mode 100644 drivers/media/platform/ti/vpe/vpdma.c
create mode 100644 drivers/media/platform/ti/vpe/vpdma.h
create mode 100644 drivers/media/platform/ti/vpe/vpdma_priv.h
create mode 100644 drivers/media/platform/ti/vpe/vpe.c
create mode 100644 drivers/media/platform/ti/vpe/vpe_regs.h
(limited to 'drivers/media')
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 9c532bd4f96f..8d109ae9e039 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -38,11 +38,7 @@ obj-y += st/sti/c8sectpfe/
obj-y += st/sti/delta/
obj-y += st/sti/hva/
obj-y += st/stm32/
-obj-y += ti-vpe/
-obj-y += ti/am437x/
-obj-y += ti/davinci/
-obj-y += ti/omap/
-obj-y += ti/omap3isp/
+obj-y += ti/
obj-y += via/
obj-y += xilinx/
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti-vpe/Makefile
deleted file mode 100644
index ad624056e039..000000000000
--- a/drivers/media/platform/ti-vpe/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
-obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o
-obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o
-obj-$(CONFIG_VIDEO_TI_CSC) += ti-csc.o
-
-ti-vpe-y := vpe.o
-ti-vpdma-y := vpdma.o
-ti-sc-y := sc.o
-ti-csc-y := csc.o
-
-ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
-
-obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o
-
-ti-cal-y := cal.o cal-camerarx.o cal-video.o
diff --git a/drivers/media/platform/ti-vpe/cal-camerarx.c b/drivers/media/platform/ti-vpe/cal-camerarx.c
deleted file mode 100644
index 6b43a1525b45..000000000000
--- a/drivers/media/platform/ti-vpe/cal-camerarx.c
+++ /dev/null
@@ -1,915 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI Camera Access Layer (CAL) - CAMERARX
- *
- * Copyright (c) 2015-2020 Texas Instruments Inc.
- *
- * Authors:
- * Benoit Parrot
- * Laurent Pinchart
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include "cal.h"
-#include "cal_regs.h"
-
-/* ------------------------------------------------------------------
- * I/O Register Accessors
- * ------------------------------------------------------------------
- */
-
-static inline u32 camerarx_read(struct cal_camerarx *phy, u32 offset)
-{
- return ioread32(phy->base + offset);
-}
-
-static inline void camerarx_write(struct cal_camerarx *phy, u32 offset, u32 val)
-{
- iowrite32(val, phy->base + offset);
-}
-
-/* ------------------------------------------------------------------
- * CAMERARX Management
- * ------------------------------------------------------------------
- */
-
-static s64 cal_camerarx_get_ext_link_freq(struct cal_camerarx *phy)
-{
- struct v4l2_mbus_config_mipi_csi2 *mipi_csi2 = &phy->endpoint.bus.mipi_csi2;
- u32 num_lanes = mipi_csi2->num_data_lanes;
- const struct cal_format_info *fmtinfo;
- u32 bpp;
- s64 freq;
-
- fmtinfo = cal_format_by_code(phy->formats[CAL_CAMERARX_PAD_SINK].code);
- if (!fmtinfo)
- return -EINVAL;
-
- bpp = fmtinfo->bpp;
-
- freq = v4l2_get_link_freq(phy->source->ctrl_handler, bpp, 2 * num_lanes);
- if (freq < 0) {
- phy_err(phy, "failed to get link freq for subdev '%s'\n",
- phy->source->name);
- return freq;
- }
-
- phy_dbg(3, phy, "Source Link Freq: %llu\n", freq);
-
- return freq;
-}
-
-static void cal_camerarx_lane_config(struct cal_camerarx *phy)
-{
- u32 val = cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance));
- u32 lane_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK;
- u32 polarity_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK;
- struct v4l2_mbus_config_mipi_csi2 *mipi_csi2 =
- &phy->endpoint.bus.mipi_csi2;
- int lane;
-
- cal_set_field(&val, mipi_csi2->clock_lane + 1, lane_mask);
- cal_set_field(&val, mipi_csi2->lane_polarities[0], polarity_mask);
- for (lane = 0; lane < mipi_csi2->num_data_lanes; lane++) {
- /*
- * Every lane are one nibble apart starting with the
- * clock followed by the data lanes so shift masks by 4.
- */
- lane_mask <<= 4;
- polarity_mask <<= 4;
- cal_set_field(&val, mipi_csi2->data_lanes[lane] + 1, lane_mask);
- cal_set_field(&val, mipi_csi2->lane_polarities[lane + 1],
- polarity_mask);
- }
-
- cal_write(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), val);
- phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x\n",
- phy->instance, val);
-}
-
-static void cal_camerarx_enable(struct cal_camerarx *phy)
-{
- u32 num_lanes = phy->cal->data->camerarx[phy->instance].num_lanes;
-
- regmap_field_write(phy->fields[F_CAMMODE], 0);
- /* Always enable all lanes at the phy control level */
- regmap_field_write(phy->fields[F_LANEENABLE], (1 << num_lanes) - 1);
- /* F_CSI_MODE is not present on every architecture */
- if (phy->fields[F_CSI_MODE])
- regmap_field_write(phy->fields[F_CSI_MODE], 1);
- regmap_field_write(phy->fields[F_CTRLCLKEN], 1);
-}
-
-void cal_camerarx_disable(struct cal_camerarx *phy)
-{
- regmap_field_write(phy->fields[F_CTRLCLKEN], 0);
-}
-
-/*
- * TCLK values are OK at their reset values
- */
-#define TCLK_TERM 0
-#define TCLK_MISS 1
-#define TCLK_SETTLE 14
-
-static void cal_camerarx_config(struct cal_camerarx *phy, s64 link_freq)
-{
- unsigned int reg0, reg1;
- unsigned int ths_term, ths_settle;
-
- /* DPHY timing configuration */
-
- /* THS_TERM: Programmed value = floor(20 ns/DDRClk period) */
- ths_term = div_s64(20 * link_freq, 1000 * 1000 * 1000);
- phy_dbg(1, phy, "ths_term: %d (0x%02x)\n", ths_term, ths_term);
-
- /* THS_SETTLE: Programmed value = floor(105 ns/DDRClk period) + 4 */
- ths_settle = div_s64(105 * link_freq, 1000 * 1000 * 1000) + 4;
- phy_dbg(1, phy, "ths_settle: %d (0x%02x)\n", ths_settle, ths_settle);
-
- reg0 = camerarx_read(phy, CAL_CSI2_PHY_REG0);
- cal_set_field(®0, CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE,
- CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_MASK);
- cal_set_field(®0, ths_term, CAL_CSI2_PHY_REG0_THS_TERM_MASK);
- cal_set_field(®0, ths_settle, CAL_CSI2_PHY_REG0_THS_SETTLE_MASK);
-
- phy_dbg(1, phy, "CSI2_%d_REG0 = 0x%08x\n", phy->instance, reg0);
- camerarx_write(phy, CAL_CSI2_PHY_REG0, reg0);
-
- reg1 = camerarx_read(phy, CAL_CSI2_PHY_REG1);
- cal_set_field(®1, TCLK_TERM, CAL_CSI2_PHY_REG1_TCLK_TERM_MASK);
- cal_set_field(®1, 0xb8, CAL_CSI2_PHY_REG1_DPHY_HS_SYNC_PATTERN_MASK);
- cal_set_field(®1, TCLK_MISS,
- CAL_CSI2_PHY_REG1_CTRLCLK_DIV_FACTOR_MASK);
- cal_set_field(®1, TCLK_SETTLE, CAL_CSI2_PHY_REG1_TCLK_SETTLE_MASK);
-
- phy_dbg(1, phy, "CSI2_%d_REG1 = 0x%08x\n", phy->instance, reg1);
- camerarx_write(phy, CAL_CSI2_PHY_REG1, reg1);
-}
-
-static void cal_camerarx_power(struct cal_camerarx *phy, bool enable)
-{
- u32 target_state;
- unsigned int i;
-
- target_state = enable ? CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON :
- CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF;
-
- cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
- target_state, CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK);
-
- for (i = 0; i < 10; i++) {
- u32 current_state;
-
- current_state = cal_read_field(phy->cal,
- CAL_CSI2_COMPLEXIO_CFG(phy->instance),
- CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK);
-
- if (current_state == target_state)
- break;
-
- usleep_range(1000, 1100);
- }
-
- if (i == 10)
- phy_err(phy, "Failed to power %s complexio\n",
- enable ? "up" : "down");
-}
-
-static void cal_camerarx_wait_reset(struct cal_camerarx *phy)
-{
- unsigned long timeout;
-
- timeout = jiffies + msecs_to_jiffies(750);
- while (time_before(jiffies, timeout)) {
- if (cal_read_field(phy->cal,
- CAL_CSI2_COMPLEXIO_CFG(phy->instance),
- CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
- CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
- break;
- usleep_range(500, 5000);
- }
-
- if (cal_read_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
- CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) !=
- CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
- phy_err(phy, "Timeout waiting for Complex IO reset done\n");
-}
-
-static void cal_camerarx_wait_stop_state(struct cal_camerarx *phy)
-{
- unsigned long timeout;
-
- timeout = jiffies + msecs_to_jiffies(750);
- while (time_before(jiffies, timeout)) {
- if (cal_read_field(phy->cal,
- CAL_CSI2_TIMING(phy->instance),
- CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) == 0)
- break;
- usleep_range(500, 5000);
- }
-
- if (cal_read_field(phy->cal, CAL_CSI2_TIMING(phy->instance),
- CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) != 0)
- phy_err(phy, "Timeout waiting for stop state\n");
-}
-
-static void cal_camerarx_enable_irqs(struct cal_camerarx *phy)
-{
- const u32 cio_err_mask =
- CAL_CSI2_COMPLEXIO_IRQ_LANE_ERRORS_MASK |
- CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK |
- CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK |
- CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK;
- const u32 vc_err_mask =
- CAL_CSI2_VC_IRQ_CS_IRQ_MASK(0) |
- CAL_CSI2_VC_IRQ_CS_IRQ_MASK(1) |
- CAL_CSI2_VC_IRQ_CS_IRQ_MASK(2) |
- CAL_CSI2_VC_IRQ_CS_IRQ_MASK(3) |
- CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(0) |
- CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(1) |
- CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(2) |
- CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(3);
-
- /* Enable CIO & VC error IRQs. */
- cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0),
- CAL_HL_IRQ_CIO_MASK(phy->instance) |
- CAL_HL_IRQ_VC_MASK(phy->instance));
- cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance),
- cio_err_mask);
- cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(phy->instance),
- vc_err_mask);
-}
-
-static void cal_camerarx_disable_irqs(struct cal_camerarx *phy)
-{
- /* Disable CIO error irqs */
- cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(0),
- CAL_HL_IRQ_CIO_MASK(phy->instance) |
- CAL_HL_IRQ_VC_MASK(phy->instance));
- cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), 0);
- cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(phy->instance), 0);
-}
-
-static void cal_camerarx_ppi_enable(struct cal_camerarx *phy)
-{
- cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
- 1, CAL_CSI2_PPI_CTRL_ECC_EN_MASK);
-
- cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
- 1, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
-}
-
-static void cal_camerarx_ppi_disable(struct cal_camerarx *phy)
-{
- cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
- 0, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
-}
-
-static int cal_camerarx_start(struct cal_camerarx *phy)
-{
- s64 link_freq;
- u32 sscounter;
- u32 val;
- int ret;
-
- if (phy->enable_count > 0) {
- phy->enable_count++;
- return 0;
- }
-
- link_freq = cal_camerarx_get_ext_link_freq(phy);
- if (link_freq < 0)
- return link_freq;
-
- ret = v4l2_subdev_call(phy->source, core, s_power, 1);
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
- phy_err(phy, "power on failed in subdev\n");
- return ret;
- }
-
- cal_camerarx_enable_irqs(phy);
-
- /*
- * CSI-2 PHY Link Initialization Sequence, according to the DRA74xP /
- * DRA75xP / DRA76xP / DRA77xP TRM. The DRA71x / DRA72x and the AM65x /
- * DRA80xM TRMs have a a slightly simplified sequence.
- */
-
- /*
- * 1. Configure all CSI-2 low level protocol registers to be ready to
- * receive signals/data from the CSI-2 PHY.
- *
- * i.-v. Configure the lanes position and polarity.
- */
- cal_camerarx_lane_config(phy);
-
- /*
- * vi.-vii. Configure D-PHY mode, enable the required lanes and
- * enable the CAMERARX clock.
- */
- cal_camerarx_enable(phy);
-
- /*
- * 2. CSI PHY and link initialization sequence.
- *
- * a. Deassert the CSI-2 PHY reset. Do not wait for reset completion
- * at this point, as it requires the external source to send the
- * CSI-2 HS clock.
- */
- cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
- CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL,
- CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
- phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x De-assert Complex IO Reset\n",
- phy->instance,
- cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)));
-
- /* Dummy read to allow SCP reset to complete. */
- camerarx_read(phy, CAL_CSI2_PHY_REG0);
-
- /* Program the PHY timing parameters. */
- cal_camerarx_config(phy, link_freq);
-
- /*
- * b. Assert the FORCERXMODE signal.
- *
- * The stop-state-counter is based on fclk cycles, and we always use
- * the x16 and x4 settings, so stop-state-timeout =
- * fclk-cycle * 16 * 4 * counter.
- *
- * Stop-state-timeout must be more than 100us as per CSI-2 spec, so we
- * calculate a timeout that's 100us (rounding up).
- */
- sscounter = DIV_ROUND_UP(clk_get_rate(phy->cal->fclk), 10000 * 16 * 4);
-
- val = cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance));
- cal_set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK);
- cal_set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK);
- cal_set_field(&val, sscounter,
- CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK);
- cal_write(phy->cal, CAL_CSI2_TIMING(phy->instance), val);
- phy_dbg(3, phy, "CAL_CSI2_TIMING(%d) = 0x%08x Stop States\n",
- phy->instance,
- cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance)));
-
- /* Assert the FORCERXMODE signal. */
- cal_write_field(phy->cal, CAL_CSI2_TIMING(phy->instance),
- 1, CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK);
- phy_dbg(3, phy, "CAL_CSI2_TIMING(%d) = 0x%08x Force RXMODE\n",
- phy->instance,
- cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance)));
-
- /*
- * c. Connect pull-down on CSI-2 PHY link (using pad control).
- *
- * This is not required on DRA71x, DRA72x, AM65x and DRA80xM. Not
- * implemented.
- */
-
- /*
- * d. Power up the CSI-2 PHY.
- * e. Check whether the state status reaches the ON state.
- */
- cal_camerarx_power(phy, true);
-
- /*
- * Start the source to enable the CSI-2 HS clock. We can now wait for
- * CSI-2 PHY reset to complete.
- */
- ret = v4l2_subdev_call(phy->source, video, s_stream, 1);
- if (ret) {
- v4l2_subdev_call(phy->source, core, s_power, 0);
- cal_camerarx_disable_irqs(phy);
- phy_err(phy, "stream on failed in subdev\n");
- return ret;
- }
-
- cal_camerarx_wait_reset(phy);
-
- /* f. Wait for STOPSTATE=1 for all enabled lane modules. */
- cal_camerarx_wait_stop_state(phy);
-
- phy_dbg(1, phy, "CSI2_%u_REG1 = 0x%08x (bits 31-28 should be set)\n",
- phy->instance, camerarx_read(phy, CAL_CSI2_PHY_REG1));
-
- /*
- * g. Disable pull-down on CSI-2 PHY link (using pad control).
- *
- * This is not required on DRA71x, DRA72x, AM65x and DRA80xM. Not
- * implemented.
- */
-
- /* Finally, enable the PHY Protocol Interface (PPI). */
- cal_camerarx_ppi_enable(phy);
-
- phy->enable_count++;
-
- return 0;
-}
-
-static void cal_camerarx_stop(struct cal_camerarx *phy)
-{
- int ret;
-
- if (--phy->enable_count > 0)
- return;
-
- cal_camerarx_ppi_disable(phy);
-
- cal_camerarx_disable_irqs(phy);
-
- cal_camerarx_power(phy, false);
-
- /* Assert Complex IO Reset */
- cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
- CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL,
- CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
-
- phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Complex IO in Reset\n",
- phy->instance,
- cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)));
-
- /* Disable the phy */
- cal_camerarx_disable(phy);
-
- if (v4l2_subdev_call(phy->source, video, s_stream, 0))
- phy_err(phy, "stream off failed in subdev\n");
-
- ret = v4l2_subdev_call(phy->source, core, s_power, 0);
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
- phy_err(phy, "power off failed in subdev\n");
-}
-
-/*
- * Errata i913: CSI2 LDO Needs to be disabled when module is powered on
- *
- * Enabling CSI2 LDO shorts it to core supply. It is crucial the 2 CSI2
- * LDOs on the device are disabled if CSI-2 module is powered on
- * (0x4845 B304 | 0x4845 B384 [28:27] = 0x1) or in ULPS (0x4845 B304
- * | 0x4845 B384 [28:27] = 0x2) mode. Common concerns include: high
- * current draw on the module supply in active mode.
- *
- * Errata does not apply when CSI-2 module is powered off
- * (0x4845 B304 | 0x4845 B384 [28:27] = 0x0).
- *
- * SW Workaround:
- * Set the following register bits to disable the LDO,
- * which is essentially CSI2 REG10 bit 6:
- *
- * Core 0: 0x4845 B828 = 0x0000 0040
- * Core 1: 0x4845 B928 = 0x0000 0040
- */
-void cal_camerarx_i913_errata(struct cal_camerarx *phy)
-{
- u32 reg10 = camerarx_read(phy, CAL_CSI2_PHY_REG10);
-
- cal_set_field(®10, 1, CAL_CSI2_PHY_REG10_I933_LDO_DISABLE_MASK);
-
- phy_dbg(1, phy, "CSI2_%d_REG10 = 0x%08x\n", phy->instance, reg10);
- camerarx_write(phy, CAL_CSI2_PHY_REG10, reg10);
-}
-
-static int cal_camerarx_regmap_init(struct cal_dev *cal,
- struct cal_camerarx *phy)
-{
- const struct cal_camerarx_data *phy_data;
- unsigned int i;
-
- if (!cal->data)
- return -EINVAL;
-
- phy_data = &cal->data->camerarx[phy->instance];
-
- for (i = 0; i < F_MAX_FIELDS; i++) {
- struct reg_field field = {
- .reg = cal->syscon_camerrx_offset,
- .lsb = phy_data->fields[i].lsb,
- .msb = phy_data->fields[i].msb,
- };
-
- /*
- * Here we update the reg offset with the
- * value found in DT
- */
- phy->fields[i] = devm_regmap_field_alloc(cal->dev,
- cal->syscon_camerrx,
- field);
- if (IS_ERR(phy->fields[i])) {
- cal_err(cal, "Unable to allocate regmap fields\n");
- return PTR_ERR(phy->fields[i]);
- }
- }
-
- return 0;
-}
-
-static int cal_camerarx_parse_dt(struct cal_camerarx *phy)
-{
- struct v4l2_fwnode_endpoint *endpoint = &phy->endpoint;
- char data_lanes[V4L2_MBUS_CSI2_MAX_DATA_LANES * 2];
- struct device_node *ep_node;
- unsigned int i;
- int ret;
-
- /*
- * Find the endpoint node for the port corresponding to the PHY
- * instance, and parse its CSI-2-related properties.
- */
- ep_node = of_graph_get_endpoint_by_regs(phy->cal->dev->of_node,
- phy->instance, 0);
- if (!ep_node) {
- /*
- * The endpoint is not mandatory, not all PHY instances need to
- * be connected in DT.
- */
- phy_dbg(3, phy, "Port has no endpoint\n");
- return 0;
- }
-
- endpoint->bus_type = V4L2_MBUS_CSI2_DPHY;
- ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), endpoint);
- if (ret < 0) {
- phy_err(phy, "Failed to parse endpoint\n");
- goto done;
- }
-
- for (i = 0; i < endpoint->bus.mipi_csi2.num_data_lanes; i++) {
- unsigned int lane = endpoint->bus.mipi_csi2.data_lanes[i];
-
- if (lane > 4) {
- phy_err(phy, "Invalid position %u for data lane %u\n",
- lane, i);
- ret = -EINVAL;
- goto done;
- }
-
- data_lanes[i*2] = '0' + lane;
- data_lanes[i*2+1] = ' ';
- }
-
- data_lanes[i*2-1] = '\0';
-
- phy_dbg(3, phy,
- "CSI-2 bus: clock lane <%u>, data lanes <%s>, flags 0x%08x\n",
- endpoint->bus.mipi_csi2.clock_lane, data_lanes,
- endpoint->bus.mipi_csi2.flags);
-
- /* Retrieve the connected device and store it for later use. */
- phy->source_ep_node = of_graph_get_remote_endpoint(ep_node);
- phy->source_node = of_graph_get_port_parent(phy->source_ep_node);
- if (!phy->source_node) {
- phy_dbg(3, phy, "Can't get remote parent\n");
- of_node_put(phy->source_ep_node);
- ret = -EINVAL;
- goto done;
- }
-
- phy_dbg(1, phy, "Found connected device %pOFn\n", phy->source_node);
-
-done:
- of_node_put(ep_node);
- return ret;
-}
-
-/* ------------------------------------------------------------------
- * V4L2 Subdev Operations
- * ------------------------------------------------------------------
- */
-
-static inline struct cal_camerarx *to_cal_camerarx(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct cal_camerarx, subdev);
-}
-
-static struct v4l2_mbus_framefmt *
-cal_camerarx_get_pad_format(struct cal_camerarx *phy,
- struct v4l2_subdev_state *sd_state,
- unsigned int pad, u32 which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_get_try_format(&phy->subdev, sd_state, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &phy->formats[pad];
- default:
- return NULL;
- }
-}
-
-static int cal_camerarx_sd_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct cal_camerarx *phy = to_cal_camerarx(sd);
- int ret = 0;
-
- mutex_lock(&phy->mutex);
-
- if (enable)
- ret = cal_camerarx_start(phy);
- else
- cal_camerarx_stop(phy);
-
- mutex_unlock(&phy->mutex);
-
- return ret;
-}
-
-static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct cal_camerarx *phy = to_cal_camerarx(sd);
- int ret = 0;
-
- mutex_lock(&phy->mutex);
-
- /* No transcoding, source and sink codes must match. */
- if (cal_rx_pad_is_source(code->pad)) {
- struct v4l2_mbus_framefmt *fmt;
-
- if (code->index > 0) {
- ret = -EINVAL;
- goto out;
- }
-
- fmt = cal_camerarx_get_pad_format(phy, sd_state,
- CAL_CAMERARX_PAD_SINK,
- code->which);
- code->code = fmt->code;
- } else {
- if (code->index >= cal_num_formats) {
- ret = -EINVAL;
- goto out;
- }
-
- code->code = cal_formats[code->index].code;
- }
-
-out:
- mutex_unlock(&phy->mutex);
-
- return ret;
-}
-
-static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_frame_size_enum *fse)
-{
- struct cal_camerarx *phy = to_cal_camerarx(sd);
- const struct cal_format_info *fmtinfo;
- int ret = 0;
-
- if (fse->index > 0)
- return -EINVAL;
-
- mutex_lock(&phy->mutex);
-
- /* No transcoding, source and sink formats must match. */
- if (cal_rx_pad_is_source(fse->pad)) {
- struct v4l2_mbus_framefmt *fmt;
-
- fmt = cal_camerarx_get_pad_format(phy, sd_state,
- CAL_CAMERARX_PAD_SINK,
- fse->which);
- if (fse->code != fmt->code) {
- ret = -EINVAL;
- goto out;
- }
-
- fse->min_width = fmt->width;
- fse->max_width = fmt->width;
- fse->min_height = fmt->height;
- fse->max_height = fmt->height;
- } else {
- fmtinfo = cal_format_by_code(fse->code);
- if (!fmtinfo) {
- ret = -EINVAL;
- goto out;
- }
-
- fse->min_width = CAL_MIN_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8);
- fse->max_width = CAL_MAX_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8);
- fse->min_height = CAL_MIN_HEIGHT_LINES;
- fse->max_height = CAL_MAX_HEIGHT_LINES;
- }
-
-out:
- mutex_unlock(&phy->mutex);
-
- return ret;
-}
-
-static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *format)
-{
- struct cal_camerarx *phy = to_cal_camerarx(sd);
- struct v4l2_mbus_framefmt *fmt;
-
- mutex_lock(&phy->mutex);
-
- fmt = cal_camerarx_get_pad_format(phy, sd_state, format->pad,
- format->which);
- format->format = *fmt;
-
- mutex_unlock(&phy->mutex);
-
- return 0;
-}
-
-static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *format)
-{
- struct cal_camerarx *phy = to_cal_camerarx(sd);
- const struct cal_format_info *fmtinfo;
- struct v4l2_mbus_framefmt *fmt;
- unsigned int bpp;
-
- /* No transcoding, source and sink formats must match. */
- if (cal_rx_pad_is_source(format->pad))
- return cal_camerarx_sd_get_fmt(sd, sd_state, format);
-
- /*
- * Default to the first format if the requested media bus code isn't
- * supported.
- */
- fmtinfo = cal_format_by_code(format->format.code);
- if (!fmtinfo)
- fmtinfo = &cal_formats[0];
-
- /* Clamp the size, update the code. The colorspace is accepted as-is. */
- bpp = ALIGN(fmtinfo->bpp, 8);
-
- format->format.width = clamp_t(unsigned int, format->format.width,
- CAL_MIN_WIDTH_BYTES * 8 / bpp,
- CAL_MAX_WIDTH_BYTES * 8 / bpp);
- format->format.height = clamp_t(unsigned int, format->format.height,
- CAL_MIN_HEIGHT_LINES,
- CAL_MAX_HEIGHT_LINES);
- format->format.code = fmtinfo->code;
- format->format.field = V4L2_FIELD_NONE;
-
- /* Store the format and propagate it to the source pad. */
-
- mutex_lock(&phy->mutex);
-
- fmt = cal_camerarx_get_pad_format(phy, sd_state,
- CAL_CAMERARX_PAD_SINK,
- format->which);
- *fmt = format->format;
-
- fmt = cal_camerarx_get_pad_format(phy, sd_state,
- CAL_CAMERARX_PAD_FIRST_SOURCE,
- format->which);
- *fmt = format->format;
-
- mutex_unlock(&phy->mutex);
-
- return 0;
-}
-
-static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state)
-{
- struct v4l2_subdev_format format = {
- .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
- : V4L2_SUBDEV_FORMAT_ACTIVE,
- .pad = CAL_CAMERARX_PAD_SINK,
- .format = {
- .width = 640,
- .height = 480,
- .code = MEDIA_BUS_FMT_UYVY8_2X8,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .ycbcr_enc = V4L2_YCBCR_ENC_601,
- .quantization = V4L2_QUANTIZATION_LIM_RANGE,
- .xfer_func = V4L2_XFER_FUNC_SRGB,
- },
- };
-
- return cal_camerarx_sd_set_fmt(sd, sd_state, &format);
-}
-
-static const struct v4l2_subdev_video_ops cal_camerarx_video_ops = {
- .s_stream = cal_camerarx_sd_s_stream,
-};
-
-static const struct v4l2_subdev_pad_ops cal_camerarx_pad_ops = {
- .init_cfg = cal_camerarx_sd_init_cfg,
- .enum_mbus_code = cal_camerarx_sd_enum_mbus_code,
- .enum_frame_size = cal_camerarx_sd_enum_frame_size,
- .get_fmt = cal_camerarx_sd_get_fmt,
- .set_fmt = cal_camerarx_sd_set_fmt,
-};
-
-static const struct v4l2_subdev_ops cal_camerarx_subdev_ops = {
- .video = &cal_camerarx_video_ops,
- .pad = &cal_camerarx_pad_ops,
-};
-
-static struct media_entity_operations cal_camerarx_media_ops = {
- .link_validate = v4l2_subdev_link_validate,
-};
-
-/* ------------------------------------------------------------------
- * Create and Destroy
- * ------------------------------------------------------------------
- */
-
-struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
- unsigned int instance)
-{
- struct platform_device *pdev = to_platform_device(cal->dev);
- struct cal_camerarx *phy;
- struct v4l2_subdev *sd;
- unsigned int i;
- int ret;
-
- phy = kzalloc(sizeof(*phy), GFP_KERNEL);
- if (!phy)
- return ERR_PTR(-ENOMEM);
-
- phy->cal = cal;
- phy->instance = instance;
-
- mutex_init(&phy->mutex);
-
- phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- (instance == 0) ?
- "cal_rx_core0" :
- "cal_rx_core1");
- phy->base = devm_ioremap_resource(cal->dev, phy->res);
- if (IS_ERR(phy->base)) {
- cal_err(cal, "failed to ioremap\n");
- ret = PTR_ERR(phy->base);
- goto error;
- }
-
- cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
- phy->res->name, &phy->res->start, &phy->res->end);
-
- ret = cal_camerarx_regmap_init(cal, phy);
- if (ret)
- goto error;
-
- ret = cal_camerarx_parse_dt(phy);
- if (ret)
- goto error;
-
- /* Initialize the V4L2 subdev and media entity. */
- sd = &phy->subdev;
- v4l2_subdev_init(sd, &cal_camerarx_subdev_ops);
- sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
- sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
- snprintf(sd->name, sizeof(sd->name), "CAMERARX%u", instance);
- sd->dev = cal->dev;
-
- phy->pads[CAL_CAMERARX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- for (i = CAL_CAMERARX_PAD_FIRST_SOURCE; i < CAL_CAMERARX_NUM_PADS; ++i)
- phy->pads[i].flags = MEDIA_PAD_FL_SOURCE;
- sd->entity.ops = &cal_camerarx_media_ops;
- ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(phy->pads),
- phy->pads);
- if (ret)
- goto error;
-
- ret = cal_camerarx_sd_init_cfg(sd, NULL);
- if (ret)
- goto error;
-
- ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd);
- if (ret)
- goto error;
-
- return phy;
-
-error:
- media_entity_cleanup(&phy->subdev.entity);
- kfree(phy);
- return ERR_PTR(ret);
-}
-
-void cal_camerarx_destroy(struct cal_camerarx *phy)
-{
- if (!phy)
- return;
-
- v4l2_device_unregister_subdev(&phy->subdev);
- media_entity_cleanup(&phy->subdev.entity);
- of_node_put(phy->source_ep_node);
- of_node_put(phy->source_node);
- mutex_destroy(&phy->mutex);
- kfree(phy);
-}
diff --git a/drivers/media/platform/ti-vpe/cal-video.c b/drivers/media/platform/ti-vpe/cal-video.c
deleted file mode 100644
index 3e936a2ca36c..000000000000
--- a/drivers/media/platform/ti-vpe/cal-video.c
+++ /dev/null
@@ -1,1049 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI Camera Access Layer (CAL) - Video Device
- *
- * Copyright (c) 2015-2020 Texas Instruments Inc.
- *
- * Authors:
- * Benoit Parrot
- * Laurent Pinchart
- */
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "cal.h"
-
-/* Print Four-character-code (FOURCC) */
-static char *fourcc_to_str(u32 fmt)
-{
- static char code[5];
-
- code[0] = (unsigned char)(fmt & 0xff);
- code[1] = (unsigned char)((fmt >> 8) & 0xff);
- code[2] = (unsigned char)((fmt >> 16) & 0xff);
- code[3] = (unsigned char)((fmt >> 24) & 0xff);
- code[4] = '\0';
-
- return code;
-}
-
-/* ------------------------------------------------------------------
- * V4L2 Common IOCTLs
- * ------------------------------------------------------------------
- */
-
-static int cal_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct cal_ctx *ctx = video_drvdata(file);
-
- strscpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver));
- strscpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card));
-
- snprintf(cap->bus_info, sizeof(cap->bus_info),
- "platform:%s", dev_name(ctx->cal->dev));
- return 0;
-}
-
-static int cal_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cal_ctx *ctx = video_drvdata(file);
-
- *f = ctx->v_fmt;
-
- return 0;
-}
-
-/* ------------------------------------------------------------------
- * V4L2 Video Node Centric IOCTLs
- * ------------------------------------------------------------------
- */
-
-static const struct cal_format_info *find_format_by_pix(struct cal_ctx *ctx,
- u32 pixelformat)
-{
- const struct cal_format_info *fmtinfo;
- unsigned int k;
-
- for (k = 0; k < ctx->num_active_fmt; k++) {
- fmtinfo = ctx->active_fmt[k];
- if (fmtinfo->fourcc == pixelformat)
- return fmtinfo;
- }
-
- return NULL;
-}
-
-static const struct cal_format_info *find_format_by_code(struct cal_ctx *ctx,
- u32 code)
-{
- const struct cal_format_info *fmtinfo;
- unsigned int k;
-
- for (k = 0; k < ctx->num_active_fmt; k++) {
- fmtinfo = ctx->active_fmt[k];
- if (fmtinfo->code == code)
- return fmtinfo;
- }
-
- return NULL;
-}
-
-static int cal_legacy_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct cal_ctx *ctx = video_drvdata(file);
- const struct cal_format_info *fmtinfo;
-
- if (f->index >= ctx->num_active_fmt)
- return -EINVAL;
-
- fmtinfo = ctx->active_fmt[f->index];
-
- f->pixelformat = fmtinfo->fourcc;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- return 0;
-}
-
-static int __subdev_get_format(struct cal_ctx *ctx,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct v4l2_subdev_format sd_fmt;
- struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
- int ret;
-
- sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- sd_fmt.pad = 0;
-
- ret = v4l2_subdev_call(ctx->phy->source, pad, get_fmt, NULL, &sd_fmt);
- if (ret)
- return ret;
-
- *fmt = *mbus_fmt;
-
- ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
- fmt->width, fmt->height, fmt->code);
-
- return 0;
-}
-
-static int __subdev_set_format(struct cal_ctx *ctx,
- struct v4l2_mbus_framefmt *fmt)
-{
- struct v4l2_subdev_format sd_fmt;
- struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
- int ret;
-
- sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- sd_fmt.pad = 0;
- *mbus_fmt = *fmt;
-
- ret = v4l2_subdev_call(ctx->phy->source, pad, set_fmt, NULL, &sd_fmt);
- if (ret)
- return ret;
-
- ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
- fmt->width, fmt->height, fmt->code);
-
- return 0;
-}
-
-static void cal_calc_format_size(struct cal_ctx *ctx,
- const struct cal_format_info *fmtinfo,
- struct v4l2_format *f)
-{
- u32 bpl, max_width;
-
- /*
- * Maximum width is bound by the DMA max width in bytes.
- * We need to recalculate the actual maxi width depending on the
- * number of bytes per pixels required.
- */
- max_width = CAL_MAX_WIDTH_BYTES / (ALIGN(fmtinfo->bpp, 8) >> 3);
- v4l_bound_align_image(&f->fmt.pix.width, 48, max_width, 2,
- &f->fmt.pix.height, 32, CAL_MAX_HEIGHT_LINES,
- 0, 0);
-
- bpl = (f->fmt.pix.width * ALIGN(fmtinfo->bpp, 8)) >> 3;
- f->fmt.pix.bytesperline = ALIGN(bpl, 16);
-
- f->fmt.pix.sizeimage = f->fmt.pix.height *
- f->fmt.pix.bytesperline;
-
- ctx_dbg(3, ctx, "%s: fourcc: %s size: %dx%d bpl:%d img_size:%d\n",
- __func__, fourcc_to_str(f->fmt.pix.pixelformat),
- f->fmt.pix.width, f->fmt.pix.height,
- f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
-}
-
-static int cal_legacy_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cal_ctx *ctx = video_drvdata(file);
- const struct cal_format_info *fmtinfo;
- struct v4l2_subdev_frame_size_enum fse;
- int ret, found;
-
- fmtinfo = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
- if (!fmtinfo) {
- ctx_dbg(3, ctx, "Fourcc format (0x%08x) not found.\n",
- f->fmt.pix.pixelformat);
-
- /* Just get the first one enumerated */
- fmtinfo = ctx->active_fmt[0];
- f->fmt.pix.pixelformat = fmtinfo->fourcc;
- }
-
- f->fmt.pix.field = ctx->v_fmt.fmt.pix.field;
-
- /* check for/find a valid width/height */
- ret = 0;
- found = false;
- fse.pad = 0;
- fse.code = fmtinfo->code;
- fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- for (fse.index = 0; ; fse.index++) {
- ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_size,
- NULL, &fse);
- if (ret)
- break;
-
- if ((f->fmt.pix.width == fse.max_width) &&
- (f->fmt.pix.height == fse.max_height)) {
- found = true;
- break;
- } else if ((f->fmt.pix.width >= fse.min_width) &&
- (f->fmt.pix.width <= fse.max_width) &&
- (f->fmt.pix.height >= fse.min_height) &&
- (f->fmt.pix.height <= fse.max_height)) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- /* use existing values as default */
- f->fmt.pix.width = ctx->v_fmt.fmt.pix.width;
- f->fmt.pix.height = ctx->v_fmt.fmt.pix.height;
- }
-
- /*
- * Use current colorspace for now, it will get
- * updated properly during s_fmt
- */
- f->fmt.pix.colorspace = ctx->v_fmt.fmt.pix.colorspace;
- cal_calc_format_size(ctx, fmtinfo, f);
- return 0;
-}
-
-static int cal_legacy_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cal_ctx *ctx = video_drvdata(file);
- struct vb2_queue *q = &ctx->vb_vidq;
- struct v4l2_subdev_format sd_fmt = {
- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
- .pad = CAL_CAMERARX_PAD_SINK,
- };
- const struct cal_format_info *fmtinfo;
- int ret;
-
- if (vb2_is_busy(q)) {
- ctx_dbg(3, ctx, "%s device busy\n", __func__);
- return -EBUSY;
- }
-
- ret = cal_legacy_try_fmt_vid_cap(file, priv, f);
- if (ret < 0)
- return ret;
-
- fmtinfo = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
-
- v4l2_fill_mbus_format(&sd_fmt.format, &f->fmt.pix, fmtinfo->code);
-
- ret = __subdev_set_format(ctx, &sd_fmt.format);
- if (ret)
- return ret;
-
- /* Just double check nothing has gone wrong */
- if (sd_fmt.format.code != fmtinfo->code) {
- ctx_dbg(3, ctx,
- "%s subdev changed format on us, this should not happen\n",
- __func__);
- return -EINVAL;
- }
-
- v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &sd_fmt.format);
- ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- ctx->v_fmt.fmt.pix.pixelformat = fmtinfo->fourcc;
- ctx->v_fmt.fmt.pix.field = sd_fmt.format.field;
- cal_calc_format_size(ctx, fmtinfo, &ctx->v_fmt);
-
- v4l2_subdev_call(&ctx->phy->subdev, pad, set_fmt, NULL, &sd_fmt);
-
- ctx->fmtinfo = fmtinfo;
- *f = ctx->v_fmt;
-
- return 0;
-}
-
-static int cal_legacy_enum_framesizes(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
- struct cal_ctx *ctx = video_drvdata(file);
- const struct cal_format_info *fmtinfo;
- struct v4l2_subdev_frame_size_enum fse;
- int ret;
-
- /* check for valid format */
- fmtinfo = find_format_by_pix(ctx, fsize->pixel_format);
- if (!fmtinfo) {
- ctx_dbg(3, ctx, "Invalid pixel code: %x\n",
- fsize->pixel_format);
- return -EINVAL;
- }
-
- fse.index = fsize->index;
- fse.pad = 0;
- fse.code = fmtinfo->code;
- fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-
- ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_size, NULL,
- &fse);
- if (ret)
- return ret;
-
- ctx_dbg(1, ctx, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
- __func__, fse.index, fse.code, fse.min_width, fse.max_width,
- fse.min_height, fse.max_height);
-
- fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- fsize->discrete.width = fse.max_width;
- fsize->discrete.height = fse.max_height;
-
- return 0;
-}
-
-static int cal_legacy_enum_input(struct file *file, void *priv,
- struct v4l2_input *inp)
-{
- if (inp->index > 0)
- return -EINVAL;
-
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- sprintf(inp->name, "Camera %u", inp->index);
- return 0;
-}
-
-static int cal_legacy_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int cal_legacy_s_input(struct file *file, void *priv, unsigned int i)
-{
- return i > 0 ? -EINVAL : 0;
-}
-
-/* timeperframe is arbitrary and continuous */
-static int cal_legacy_enum_frameintervals(struct file *file, void *priv,
- struct v4l2_frmivalenum *fival)
-{
- struct cal_ctx *ctx = video_drvdata(file);
- const struct cal_format_info *fmtinfo;
- struct v4l2_subdev_frame_interval_enum fie = {
- .index = fival->index,
- .width = fival->width,
- .height = fival->height,
- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
- };
- int ret;
-
- fmtinfo = find_format_by_pix(ctx, fival->pixel_format);
- if (!fmtinfo)
- return -EINVAL;
-
- fie.code = fmtinfo->code;
- ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_interval,
- NULL, &fie);
- if (ret)
- return ret;
- fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
- fival->discrete = fie.interval;
-
- return 0;
-}
-
-static int cal_legacy_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
-{
- struct cal_ctx *ctx = video_drvdata(file);
-
- return v4l2_g_parm_cap(video_devdata(file), ctx->phy->source, a);
-}
-
-static int cal_legacy_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
-{
- struct cal_ctx *ctx = video_drvdata(file);
-
- return v4l2_s_parm_cap(video_devdata(file), ctx->phy->source, a);
-}
-
-static const struct v4l2_ioctl_ops cal_ioctl_legacy_ops = {
- .vidioc_querycap = cal_querycap,
- .vidioc_enum_fmt_vid_cap = cal_legacy_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cal_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cal_legacy_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = cal_legacy_s_fmt_vid_cap,
- .vidioc_enum_framesizes = cal_legacy_enum_framesizes,
- .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_expbuf = vb2_ioctl_expbuf,
- .vidioc_enum_input = cal_legacy_enum_input,
- .vidioc_g_input = cal_legacy_g_input,
- .vidioc_s_input = cal_legacy_s_input,
- .vidioc_enum_frameintervals = cal_legacy_enum_frameintervals,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_log_status = v4l2_ctrl_log_status,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
- .vidioc_g_parm = cal_legacy_g_parm,
- .vidioc_s_parm = cal_legacy_s_parm,
-};
-
-/* ------------------------------------------------------------------
- * V4L2 Media Controller Centric IOCTLs
- * ------------------------------------------------------------------
- */
-
-static int cal_mc_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- unsigned int i;
- unsigned int idx;
-
- if (f->index >= cal_num_formats)
- return -EINVAL;
-
- idx = 0;
-
- for (i = 0; i < cal_num_formats; ++i) {
- if (f->mbus_code && cal_formats[i].code != f->mbus_code)
- continue;
-
- if (idx == f->index) {
- f->pixelformat = cal_formats[i].fourcc;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- return 0;
- }
-
- idx++;
- }
-
- return -EINVAL;
-}
-
-static void cal_mc_try_fmt(struct cal_ctx *ctx, struct v4l2_format *f,
- const struct cal_format_info **info)
-{
- struct v4l2_pix_format *format = &f->fmt.pix;
- const struct cal_format_info *fmtinfo;
- unsigned int bpp;
-
- /*
- * Default to the first format if the requested pixel format code isn't
- * supported.
- */
- fmtinfo = cal_format_by_fourcc(f->fmt.pix.pixelformat);
- if (!fmtinfo)
- fmtinfo = &cal_formats[0];
-
- /*
- * Clamp the size, update the pixel format. The field and colorspace are
- * accepted as-is, except for V4L2_FIELD_ANY that is turned into
- * V4L2_FIELD_NONE.
- */
- bpp = ALIGN(fmtinfo->bpp, 8);
-
- format->width = clamp_t(unsigned int, format->width,
- CAL_MIN_WIDTH_BYTES * 8 / bpp,
- CAL_MAX_WIDTH_BYTES * 8 / bpp);
- format->height = clamp_t(unsigned int, format->height,
- CAL_MIN_HEIGHT_LINES, CAL_MAX_HEIGHT_LINES);
- format->pixelformat = fmtinfo->fourcc;
-
- if (format->field == V4L2_FIELD_ANY)
- format->field = V4L2_FIELD_NONE;
-
- /*
- * Calculate the number of bytes per line and the image size. The
- * hardware stores the stride as a number of 16 bytes words, in a
- * signed 15-bit value. Only 14 bits are thus usable.
- */
- format->bytesperline = ALIGN(clamp(format->bytesperline,
- format->width * bpp / 8,
- ((1U << 14) - 1) * 16), 16);
-
- format->sizeimage = format->height * format->bytesperline;
-
- format->colorspace = ctx->v_fmt.fmt.pix.colorspace;
-
- if (info)
- *info = fmtinfo;
-
- ctx_dbg(3, ctx, "%s: %s %ux%u (bytesperline %u sizeimage %u)\n",
- __func__, fourcc_to_str(format->pixelformat),
- format->width, format->height,
- format->bytesperline, format->sizeimage);
-}
-
-static int cal_mc_try_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cal_ctx *ctx = video_drvdata(file);
-
- cal_mc_try_fmt(ctx, f, NULL);
- return 0;
-}
-
-static int cal_mc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cal_ctx *ctx = video_drvdata(file);
- const struct cal_format_info *fmtinfo;
-
- if (vb2_is_busy(&ctx->vb_vidq)) {
- ctx_dbg(3, ctx, "%s device busy\n", __func__);
- return -EBUSY;
- }
-
- cal_mc_try_fmt(ctx, f, &fmtinfo);
-
- ctx->v_fmt = *f;
- ctx->fmtinfo = fmtinfo;
-
- return 0;
-}
-
-static int cal_mc_enum_framesizes(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
- struct cal_ctx *ctx = video_drvdata(file);
- const struct cal_format_info *fmtinfo;
- unsigned int bpp;
-
- if (fsize->index > 0)
- return -EINVAL;
-
- fmtinfo = cal_format_by_fourcc(fsize->pixel_format);
- if (!fmtinfo) {
- ctx_dbg(3, ctx, "Invalid pixel format 0x%08x\n",
- fsize->pixel_format);
- return -EINVAL;
- }
-
- bpp = ALIGN(fmtinfo->bpp, 8);
-
- fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
- fsize->stepwise.min_width = CAL_MIN_WIDTH_BYTES * 8 / bpp;
- fsize->stepwise.max_width = CAL_MAX_WIDTH_BYTES * 8 / bpp;
- fsize->stepwise.step_width = 64 / bpp;
- fsize->stepwise.min_height = CAL_MIN_HEIGHT_LINES;
- fsize->stepwise.max_height = CAL_MAX_HEIGHT_LINES;
- fsize->stepwise.step_height = 1;
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops cal_ioctl_mc_ops = {
- .vidioc_querycap = cal_querycap,
- .vidioc_enum_fmt_vid_cap = cal_mc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cal_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cal_mc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = cal_mc_s_fmt_vid_cap,
- .vidioc_enum_framesizes = cal_mc_enum_framesizes,
- .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_expbuf = vb2_ioctl_expbuf,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
- .vidioc_log_status = v4l2_ctrl_log_status,
-};
-
-/* ------------------------------------------------------------------
- * videobuf2 Common Operations
- * ------------------------------------------------------------------
- */
-
-static int cal_queue_setup(struct vb2_queue *vq,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- struct cal_ctx *ctx = vb2_get_drv_priv(vq);
- unsigned int size = ctx->v_fmt.fmt.pix.sizeimage;
-
- if (vq->num_buffers + *nbuffers < 3)
- *nbuffers = 3 - vq->num_buffers;
-
- if (*nplanes) {
- if (sizes[0] < size)
- return -EINVAL;
- size = sizes[0];
- }
-
- *nplanes = 1;
- sizes[0] = size;
-
- ctx_dbg(3, ctx, "nbuffers=%d, size=%d\n", *nbuffers, sizes[0]);
-
- return 0;
-}
-
-static int cal_buffer_prepare(struct vb2_buffer *vb)
-{
- struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct cal_buffer *buf = container_of(vb, struct cal_buffer,
- vb.vb2_buf);
- unsigned long size;
-
- size = ctx->v_fmt.fmt.pix.sizeimage;
- if (vb2_plane_size(vb, 0) < size) {
- ctx_err(ctx,
- "data will not fit into plane (%lu < %lu)\n",
- vb2_plane_size(vb, 0), size);
- return -EINVAL;
- }
-
- vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
- return 0;
-}
-
-static void cal_buffer_queue(struct vb2_buffer *vb)
-{
- struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct cal_buffer *buf = container_of(vb, struct cal_buffer,
- vb.vb2_buf);
- unsigned long flags;
-
- /* recheck locking */
- spin_lock_irqsave(&ctx->dma.lock, flags);
- list_add_tail(&buf->list, &ctx->dma.queue);
- spin_unlock_irqrestore(&ctx->dma.lock, flags);
-}
-
-static void cal_release_buffers(struct cal_ctx *ctx,
- enum vb2_buffer_state state)
-{
- struct cal_buffer *buf, *tmp;
-
- /* Release all queued buffers. */
- spin_lock_irq(&ctx->dma.lock);
-
- list_for_each_entry_safe(buf, tmp, &ctx->dma.queue, list) {
- list_del(&buf->list);
- vb2_buffer_done(&buf->vb.vb2_buf, state);
- }
-
- if (ctx->dma.pending) {
- vb2_buffer_done(&ctx->dma.pending->vb.vb2_buf, state);
- ctx->dma.pending = NULL;
- }
-
- if (ctx->dma.active) {
- vb2_buffer_done(&ctx->dma.active->vb.vb2_buf, state);
- ctx->dma.active = NULL;
- }
-
- spin_unlock_irq(&ctx->dma.lock);
-}
-
-/* ------------------------------------------------------------------
- * videobuf2 Operations
- * ------------------------------------------------------------------
- */
-
-static int cal_video_check_format(struct cal_ctx *ctx)
-{
- const struct v4l2_mbus_framefmt *format;
- struct media_pad *remote_pad;
-
- remote_pad = media_entity_remote_pad(&ctx->pad);
- if (!remote_pad)
- return -ENODEV;
-
- format = &ctx->phy->formats[remote_pad->index];
-
- if (ctx->fmtinfo->code != format->code ||
- ctx->v_fmt.fmt.pix.height != format->height ||
- ctx->v_fmt.fmt.pix.width != format->width ||
- ctx->v_fmt.fmt.pix.field != format->field)
- return -EPIPE;
-
- return 0;
-}
-
-static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct cal_ctx *ctx = vb2_get_drv_priv(vq);
- struct cal_buffer *buf;
- dma_addr_t addr;
- int ret;
-
- ret = media_pipeline_start(&ctx->vdev.entity, &ctx->phy->pipe);
- if (ret < 0) {
- ctx_err(ctx, "Failed to start media pipeline: %d\n", ret);
- goto error_release_buffers;
- }
-
- /*
- * Verify that the currently configured format matches the output of
- * the connected CAMERARX.
- */
- ret = cal_video_check_format(ctx);
- if (ret < 0) {
- ctx_dbg(3, ctx,
- "Format mismatch between CAMERARX and video node\n");
- goto error_pipeline;
- }
-
- ret = cal_ctx_prepare(ctx);
- if (ret) {
- ctx_err(ctx, "Failed to prepare context: %d\n", ret);
- goto error_pipeline;
- }
-
- spin_lock_irq(&ctx->dma.lock);
- buf = list_first_entry(&ctx->dma.queue, struct cal_buffer, list);
- ctx->dma.active = buf;
- list_del(&buf->list);
- spin_unlock_irq(&ctx->dma.lock);
-
- addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
-
- ret = pm_runtime_resume_and_get(ctx->cal->dev);
- if (ret < 0)
- goto error_pipeline;
-
- cal_ctx_set_dma_addr(ctx, addr);
- cal_ctx_start(ctx);
-
- ret = v4l2_subdev_call(&ctx->phy->subdev, video, s_stream, 1);
- if (ret)
- goto error_stop;
-
- if (cal_debug >= 4)
- cal_quickdump_regs(ctx->cal);
-
- return 0;
-
-error_stop:
- cal_ctx_stop(ctx);
- pm_runtime_put_sync(ctx->cal->dev);
- cal_ctx_unprepare(ctx);
-
-error_pipeline:
- media_pipeline_stop(&ctx->vdev.entity);
-error_release_buffers:
- cal_release_buffers(ctx, VB2_BUF_STATE_QUEUED);
-
- return ret;
-}
-
-static void cal_stop_streaming(struct vb2_queue *vq)
-{
- struct cal_ctx *ctx = vb2_get_drv_priv(vq);
-
- cal_ctx_stop(ctx);
-
- v4l2_subdev_call(&ctx->phy->subdev, video, s_stream, 0);
-
- pm_runtime_put_sync(ctx->cal->dev);
-
- cal_ctx_unprepare(ctx);
-
- cal_release_buffers(ctx, VB2_BUF_STATE_ERROR);
-
- media_pipeline_stop(&ctx->vdev.entity);
-}
-
-static const struct vb2_ops cal_video_qops = {
- .queue_setup = cal_queue_setup,
- .buf_prepare = cal_buffer_prepare,
- .buf_queue = cal_buffer_queue,
- .start_streaming = cal_start_streaming,
- .stop_streaming = cal_stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
-};
-
-/* ------------------------------------------------------------------
- * V4L2 Initialization and Registration
- * ------------------------------------------------------------------
- */
-
-static const struct v4l2_file_operations cal_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .poll = vb2_fop_poll,
- .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
- .mmap = vb2_fop_mmap,
-};
-
-static int cal_ctx_v4l2_init_formats(struct cal_ctx *ctx)
-{
- struct v4l2_subdev_mbus_code_enum mbus_code;
- struct v4l2_mbus_framefmt mbus_fmt;
- const struct cal_format_info *fmtinfo;
- unsigned int i, j, k;
- int ret = 0;
-
- /* Enumerate sub device formats and enable all matching local formats */
- ctx->active_fmt = devm_kcalloc(ctx->cal->dev, cal_num_formats,
- sizeof(*ctx->active_fmt), GFP_KERNEL);
- if (!ctx->active_fmt)
- return -ENOMEM;
-
- ctx->num_active_fmt = 0;
-
- for (j = 0, i = 0; ; ++j) {
-
- memset(&mbus_code, 0, sizeof(mbus_code));
- mbus_code.index = j;
- mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(ctx->phy->source, pad, enum_mbus_code,
- NULL, &mbus_code);
- if (ret == -EINVAL)
- break;
-
- if (ret) {
- ctx_err(ctx, "Error enumerating mbus codes in subdev %s: %d\n",
- ctx->phy->source->name, ret);
- return ret;
- }
-
- ctx_dbg(2, ctx,
- "subdev %s: code: %04x idx: %u\n",
- ctx->phy->source->name, mbus_code.code, j);
-
- for (k = 0; k < cal_num_formats; k++) {
- fmtinfo = &cal_formats[k];
-
- if (mbus_code.code == fmtinfo->code) {
- ctx->active_fmt[i] = fmtinfo;
- ctx_dbg(2, ctx,
- "matched fourcc: %s: code: %04x idx: %u\n",
- fourcc_to_str(fmtinfo->fourcc),
- fmtinfo->code, i);
- ctx->num_active_fmt = ++i;
- }
- }
- }
-
- if (i == 0) {
- ctx_err(ctx, "No suitable format reported by subdev %s\n",
- ctx->phy->source->name);
- return -EINVAL;
- }
-
- ret = __subdev_get_format(ctx, &mbus_fmt);
- if (ret)
- return ret;
-
- fmtinfo = find_format_by_code(ctx, mbus_fmt.code);
- if (!fmtinfo) {
- ctx_dbg(3, ctx, "mbus code format (0x%08x) not found.\n",
- mbus_fmt.code);
- return -EINVAL;
- }
-
- /* Save current format */
- v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &mbus_fmt);
- ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- ctx->v_fmt.fmt.pix.pixelformat = fmtinfo->fourcc;
- cal_calc_format_size(ctx, fmtinfo, &ctx->v_fmt);
- ctx->fmtinfo = fmtinfo;
-
- return 0;
-}
-
-static int cal_ctx_v4l2_init_mc_format(struct cal_ctx *ctx)
-{
- const struct cal_format_info *fmtinfo;
- struct v4l2_pix_format *pix_fmt = &ctx->v_fmt.fmt.pix;
-
- fmtinfo = cal_format_by_code(MEDIA_BUS_FMT_UYVY8_2X8);
- if (!fmtinfo)
- return -EINVAL;
-
- pix_fmt->width = 640;
- pix_fmt->height = 480;
- pix_fmt->field = V4L2_FIELD_NONE;
- pix_fmt->colorspace = V4L2_COLORSPACE_SRGB;
- pix_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
- pix_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
- pix_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
- pix_fmt->pixelformat = fmtinfo->fourcc;
-
- ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- /* Save current format */
- cal_calc_format_size(ctx, fmtinfo, &ctx->v_fmt);
- ctx->fmtinfo = fmtinfo;
-
- return 0;
-}
-
-int cal_ctx_v4l2_register(struct cal_ctx *ctx)
-{
- struct video_device *vfd = &ctx->vdev;
- int ret;
-
- if (!cal_mc_api) {
- struct v4l2_ctrl_handler *hdl = &ctx->ctrl_handler;
-
- ret = cal_ctx_v4l2_init_formats(ctx);
- if (ret) {
- ctx_err(ctx, "Failed to init formats: %d\n", ret);
- return ret;
- }
-
- ret = v4l2_ctrl_add_handler(hdl, ctx->phy->source->ctrl_handler,
- NULL, true);
- if (ret < 0) {
- ctx_err(ctx, "Failed to add source ctrl handler\n");
- return ret;
- }
- } else {
- ret = cal_ctx_v4l2_init_mc_format(ctx);
- if (ret) {
- ctx_err(ctx, "Failed to init format: %d\n", ret);
- return ret;
- }
- }
-
- ret = video_register_device(vfd, VFL_TYPE_VIDEO, cal_video_nr);
- if (ret < 0) {
- ctx_err(ctx, "Failed to register video device\n");
- return ret;
- }
-
- ret = media_create_pad_link(&ctx->phy->subdev.entity,
- CAL_CAMERARX_PAD_FIRST_SOURCE,
- &vfd->entity, 0,
- MEDIA_LNK_FL_IMMUTABLE |
- MEDIA_LNK_FL_ENABLED);
- if (ret) {
- ctx_err(ctx, "Failed to create media link for context %u\n",
- ctx->dma_ctx);
- video_unregister_device(vfd);
- return ret;
- }
-
- ctx_info(ctx, "V4L2 device registered as %s\n",
- video_device_node_name(vfd));
-
- return 0;
-}
-
-void cal_ctx_v4l2_unregister(struct cal_ctx *ctx)
-{
- ctx_dbg(1, ctx, "unregistering %s\n",
- video_device_node_name(&ctx->vdev));
-
- video_unregister_device(&ctx->vdev);
-}
-
-int cal_ctx_v4l2_init(struct cal_ctx *ctx)
-{
- struct video_device *vfd = &ctx->vdev;
- struct vb2_queue *q = &ctx->vb_vidq;
- int ret;
-
- INIT_LIST_HEAD(&ctx->dma.queue);
- spin_lock_init(&ctx->dma.lock);
- mutex_init(&ctx->mutex);
- init_waitqueue_head(&ctx->dma.wait);
-
- /* Initialize the vb2 queue. */
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_DMABUF;
- q->drv_priv = ctx;
- q->buf_struct_size = sizeof(struct cal_buffer);
- q->ops = &cal_video_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->lock = &ctx->mutex;
- q->min_buffers_needed = 3;
- q->dev = ctx->cal->dev;
-
- ret = vb2_queue_init(q);
- if (ret)
- return ret;
-
- /* Initialize the video device and media entity. */
- vfd->fops = &cal_fops;
- vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING
- | (cal_mc_api ? V4L2_CAP_IO_MC : 0);
- vfd->v4l2_dev = &ctx->cal->v4l2_dev;
- vfd->queue = q;
- snprintf(vfd->name, sizeof(vfd->name), "CAL output %u", ctx->dma_ctx);
- vfd->release = video_device_release_empty;
- vfd->ioctl_ops = cal_mc_api ? &cal_ioctl_mc_ops : &cal_ioctl_legacy_ops;
- vfd->lock = &ctx->mutex;
- video_set_drvdata(vfd, ctx);
-
- ctx->pad.flags = MEDIA_PAD_FL_SINK;
- ret = media_entity_pads_init(&vfd->entity, 1, &ctx->pad);
- if (ret < 0)
- return ret;
-
- if (!cal_mc_api) {
- /* Initialize the control handler. */
- struct v4l2_ctrl_handler *hdl = &ctx->ctrl_handler;
-
- ret = v4l2_ctrl_handler_init(hdl, 11);
- if (ret < 0) {
- ctx_err(ctx, "Failed to init ctrl handler\n");
- goto error;
- }
-
- vfd->ctrl_handler = hdl;
- }
-
- return 0;
-
-error:
- media_entity_cleanup(&vfd->entity);
- return ret;
-}
-
-void cal_ctx_v4l2_cleanup(struct cal_ctx *ctx)
-{
- if (!cal_mc_api)
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
-
- media_entity_cleanup(&ctx->vdev.entity);
-}
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
deleted file mode 100644
index 4a4a6c5983f7..000000000000
--- a/drivers/media/platform/ti-vpe/cal.c
+++ /dev/null
@@ -1,1263 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI Camera Access Layer (CAL) - Driver
- *
- * Copyright (c) 2015-2020 Texas Instruments Inc.
- *
- * Authors:
- * Benoit Parrot
- * Laurent Pinchart
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "cal.h"
-#include "cal_regs.h"
-
-MODULE_DESCRIPTION("TI CAL driver");
-MODULE_AUTHOR("Benoit Parrot, ");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION("0.1.0");
-
-int cal_video_nr = -1;
-module_param_named(video_nr, cal_video_nr, uint, 0644);
-MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
-
-unsigned int cal_debug;
-module_param_named(debug, cal_debug, uint, 0644);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-#ifdef CONFIG_VIDEO_TI_CAL_MC
-#define CAL_MC_API_DEFAULT 1
-#else
-#define CAL_MC_API_DEFAULT 0
-#endif
-
-bool cal_mc_api = CAL_MC_API_DEFAULT;
-module_param_named(mc_api, cal_mc_api, bool, 0444);
-MODULE_PARM_DESC(mc_api, "activates the MC API");
-
-/* ------------------------------------------------------------------
- * Format Handling
- * ------------------------------------------------------------------
- */
-
-const struct cal_format_info cal_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .code = MEDIA_BUS_FMT_YUYV8_2X8,
- .bpp = 16,
- }, {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .code = MEDIA_BUS_FMT_UYVY8_2X8,
- .bpp = 16,
- }, {
- .fourcc = V4L2_PIX_FMT_YVYU,
- .code = MEDIA_BUS_FMT_YVYU8_2X8,
- .bpp = 16,
- }, {
- .fourcc = V4L2_PIX_FMT_VYUY,
- .code = MEDIA_BUS_FMT_VYUY8_2X8,
- .bpp = 16,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
- .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
- .bpp = 16,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
- .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
- .bpp = 16,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
- .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
- .bpp = 16,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
- .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
- .bpp = 16,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
- .code = MEDIA_BUS_FMT_RGB888_2X12_LE,
- .bpp = 24,
- }, {
- .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
- .code = MEDIA_BUS_FMT_RGB888_2X12_BE,
- .bpp = 24,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
- .code = MEDIA_BUS_FMT_ARGB8888_1X32,
- .bpp = 32,
- }, {
- .fourcc = V4L2_PIX_FMT_SBGGR8,
- .code = MEDIA_BUS_FMT_SBGGR8_1X8,
- .bpp = 8,
- }, {
- .fourcc = V4L2_PIX_FMT_SGBRG8,
- .code = MEDIA_BUS_FMT_SGBRG8_1X8,
- .bpp = 8,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG8,
- .code = MEDIA_BUS_FMT_SGRBG8_1X8,
- .bpp = 8,
- }, {
- .fourcc = V4L2_PIX_FMT_SRGGB8,
- .code = MEDIA_BUS_FMT_SRGGB8_1X8,
- .bpp = 8,
- }, {
- .fourcc = V4L2_PIX_FMT_SBGGR10,
- .code = MEDIA_BUS_FMT_SBGGR10_1X10,
- .bpp = 10,
- }, {
- .fourcc = V4L2_PIX_FMT_SGBRG10,
- .code = MEDIA_BUS_FMT_SGBRG10_1X10,
- .bpp = 10,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG10,
- .code = MEDIA_BUS_FMT_SGRBG10_1X10,
- .bpp = 10,
- }, {
- .fourcc = V4L2_PIX_FMT_SRGGB10,
- .code = MEDIA_BUS_FMT_SRGGB10_1X10,
- .bpp = 10,
- }, {
- .fourcc = V4L2_PIX_FMT_SBGGR12,
- .code = MEDIA_BUS_FMT_SBGGR12_1X12,
- .bpp = 12,
- }, {
- .fourcc = V4L2_PIX_FMT_SGBRG12,
- .code = MEDIA_BUS_FMT_SGBRG12_1X12,
- .bpp = 12,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG12,
- .code = MEDIA_BUS_FMT_SGRBG12_1X12,
- .bpp = 12,
- }, {
- .fourcc = V4L2_PIX_FMT_SRGGB12,
- .code = MEDIA_BUS_FMT_SRGGB12_1X12,
- .bpp = 12,
- },
-};
-
-const unsigned int cal_num_formats = ARRAY_SIZE(cal_formats);
-
-const struct cal_format_info *cal_format_by_fourcc(u32 fourcc)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(cal_formats); ++i) {
- if (cal_formats[i].fourcc == fourcc)
- return &cal_formats[i];
- }
-
- return NULL;
-}
-
-const struct cal_format_info *cal_format_by_code(u32 code)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(cal_formats); ++i) {
- if (cal_formats[i].code == code)
- return &cal_formats[i];
- }
-
- return NULL;
-}
-
-/* ------------------------------------------------------------------
- * Platform Data
- * ------------------------------------------------------------------
- */
-
-static const struct cal_camerarx_data dra72x_cal_camerarx[] = {
- {
- .fields = {
- [F_CTRLCLKEN] = { 10, 10 },
- [F_CAMMODE] = { 11, 12 },
- [F_LANEENABLE] = { 13, 16 },
- [F_CSI_MODE] = { 17, 17 },
- },
- .num_lanes = 4,
- },
- {
- .fields = {
- [F_CTRLCLKEN] = { 0, 0 },
- [F_CAMMODE] = { 1, 2 },
- [F_LANEENABLE] = { 3, 4 },
- [F_CSI_MODE] = { 5, 5 },
- },
- .num_lanes = 2,
- },
-};
-
-static const struct cal_data dra72x_cal_data = {
- .camerarx = dra72x_cal_camerarx,
- .num_csi2_phy = ARRAY_SIZE(dra72x_cal_camerarx),
-};
-
-static const struct cal_data dra72x_es1_cal_data = {
- .camerarx = dra72x_cal_camerarx,
- .num_csi2_phy = ARRAY_SIZE(dra72x_cal_camerarx),
- .flags = DRA72_CAL_PRE_ES2_LDO_DISABLE,
-};
-
-static const struct cal_camerarx_data dra76x_cal_csi_phy[] = {
- {
- .fields = {
- [F_CTRLCLKEN] = { 8, 8 },
- [F_CAMMODE] = { 9, 10 },
- [F_CSI_MODE] = { 11, 11 },
- [F_LANEENABLE] = { 27, 31 },
- },
- .num_lanes = 5,
- },
- {
- .fields = {
- [F_CTRLCLKEN] = { 0, 0 },
- [F_CAMMODE] = { 1, 2 },
- [F_CSI_MODE] = { 3, 3 },
- [F_LANEENABLE] = { 24, 26 },
- },
- .num_lanes = 3,
- },
-};
-
-static const struct cal_data dra76x_cal_data = {
- .camerarx = dra76x_cal_csi_phy,
- .num_csi2_phy = ARRAY_SIZE(dra76x_cal_csi_phy),
-};
-
-static const struct cal_camerarx_data am654_cal_csi_phy[] = {
- {
- .fields = {
- [F_CTRLCLKEN] = { 15, 15 },
- [F_CAMMODE] = { 24, 25 },
- [F_LANEENABLE] = { 0, 4 },
- },
- .num_lanes = 5,
- },
-};
-
-static const struct cal_data am654_cal_data = {
- .camerarx = am654_cal_csi_phy,
- .num_csi2_phy = ARRAY_SIZE(am654_cal_csi_phy),
-};
-
-/* ------------------------------------------------------------------
- * I/O Register Accessors
- * ------------------------------------------------------------------
- */
-
-void cal_quickdump_regs(struct cal_dev *cal)
-{
- unsigned int i;
-
- cal_info(cal, "CAL Registers @ 0x%pa:\n", &cal->res->start);
- print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
- (__force const void *)cal->base,
- resource_size(cal->res), false);
-
- for (i = 0; i < cal->data->num_csi2_phy; ++i) {
- struct cal_camerarx *phy = cal->phy[i];
-
- cal_info(cal, "CSI2 Core %u Registers @ %pa:\n", i,
- &phy->res->start);
- print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
- (__force const void *)phy->base,
- resource_size(phy->res),
- false);
- }
-}
-
-/* ------------------------------------------------------------------
- * Context Management
- * ------------------------------------------------------------------
- */
-
-#define CAL_MAX_PIX_PROC 4
-
-static int cal_reserve_pix_proc(struct cal_dev *cal)
-{
- unsigned long ret;
-
- spin_lock(&cal->v4l2_dev.lock);
-
- ret = find_first_zero_bit(&cal->reserved_pix_proc_mask, CAL_MAX_PIX_PROC);
-
- if (ret == CAL_MAX_PIX_PROC) {
- spin_unlock(&cal->v4l2_dev.lock);
- return -ENOSPC;
- }
-
- cal->reserved_pix_proc_mask |= BIT(ret);
-
- spin_unlock(&cal->v4l2_dev.lock);
-
- return ret;
-}
-
-static void cal_release_pix_proc(struct cal_dev *cal, unsigned int pix_proc_num)
-{
- spin_lock(&cal->v4l2_dev.lock);
-
- cal->reserved_pix_proc_mask &= ~BIT(pix_proc_num);
-
- spin_unlock(&cal->v4l2_dev.lock);
-}
-
-static void cal_ctx_csi2_config(struct cal_ctx *ctx)
-{
- u32 val;
-
- val = cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx));
- cal_set_field(&val, ctx->cport, CAL_CSI2_CTX_CPORT_MASK);
- /*
- * DT type: MIPI CSI-2 Specs
- * 0x1: All - DT filter is disabled
- * 0x24: RGB888 1 pixel = 3 bytes
- * 0x2B: RAW10 4 pixels = 5 bytes
- * 0x2A: RAW8 1 pixel = 1 byte
- * 0x1E: YUV422 2 pixels = 4 bytes
- */
- cal_set_field(&val, ctx->datatype, CAL_CSI2_CTX_DT_MASK);
- cal_set_field(&val, ctx->vc, CAL_CSI2_CTX_VC_MASK);
- cal_set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK);
- cal_set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK);
- cal_set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE,
- CAL_CSI2_CTX_PACK_MODE_MASK);
- cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), val);
- ctx_dbg(3, ctx, "CAL_CSI2_CTX(%u, %u) = 0x%08x\n",
- ctx->phy->instance, ctx->csi2_ctx,
- cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx)));
-}
-
-static void cal_ctx_pix_proc_config(struct cal_ctx *ctx)
-{
- u32 val, extract, pack;
-
- switch (ctx->fmtinfo->bpp) {
- case 8:
- extract = CAL_PIX_PROC_EXTRACT_B8;
- pack = CAL_PIX_PROC_PACK_B8;
- break;
- case 10:
- extract = CAL_PIX_PROC_EXTRACT_B10_MIPI;
- pack = CAL_PIX_PROC_PACK_B16;
- break;
- case 12:
- extract = CAL_PIX_PROC_EXTRACT_B12_MIPI;
- pack = CAL_PIX_PROC_PACK_B16;
- break;
- case 16:
- extract = CAL_PIX_PROC_EXTRACT_B16_LE;
- pack = CAL_PIX_PROC_PACK_B16;
- break;
- default:
- /*
- * If you see this warning then it means that you added
- * some new entry in the cal_formats[] array with a different
- * bit per pixel values then the one supported below.
- * Either add support for the new bpp value below or adjust
- * the new entry to use one of the value below.
- *
- * Instead of failing here just use 8 bpp as a default.
- */
- dev_warn_once(ctx->cal->dev,
- "%s:%d:%s: bpp:%d unsupported! Overwritten with 8.\n",
- __FILE__, __LINE__, __func__, ctx->fmtinfo->bpp);
- extract = CAL_PIX_PROC_EXTRACT_B8;
- pack = CAL_PIX_PROC_PACK_B8;
- break;
- }
-
- val = cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc));
- cal_set_field(&val, extract, CAL_PIX_PROC_EXTRACT_MASK);
- cal_set_field(&val, CAL_PIX_PROC_DPCMD_BYPASS, CAL_PIX_PROC_DPCMD_MASK);
- cal_set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK);
- cal_set_field(&val, pack, CAL_PIX_PROC_PACK_MASK);
- cal_set_field(&val, ctx->cport, CAL_PIX_PROC_CPORT_MASK);
- cal_set_field(&val, 1, CAL_PIX_PROC_EN_MASK);
- cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), val);
- ctx_dbg(3, ctx, "CAL_PIX_PROC(%u) = 0x%08x\n", ctx->pix_proc,
- cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc)));
-}
-
-static void cal_ctx_wr_dma_config(struct cal_ctx *ctx)
-{
- unsigned int stride = ctx->v_fmt.fmt.pix.bytesperline;
- u32 val;
-
- val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
- cal_set_field(&val, ctx->cport, CAL_WR_DMA_CTRL_CPORT_MASK);
- cal_set_field(&val, ctx->v_fmt.fmt.pix.height,
- CAL_WR_DMA_CTRL_YSIZE_MASK);
- cal_set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT,
- CAL_WR_DMA_CTRL_DTAG_MASK);
- cal_set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR,
- CAL_WR_DMA_CTRL_PATTERN_MASK);
- cal_set_field(&val, 1, CAL_WR_DMA_CTRL_STALL_RD_MASK);
- cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
- ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->dma_ctx,
- cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx)));
-
- cal_write_field(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx),
- stride / 16, CAL_WR_DMA_OFST_MASK);
- ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->dma_ctx,
- cal_read(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx)));
-
- val = cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx));
- /* 64 bit word means no skipping */
- cal_set_field(&val, 0, CAL_WR_DMA_XSIZE_XSKIP_MASK);
- /*
- * The XSIZE field is expressed in 64-bit units and prevents overflows
- * in case of synchronization issues by limiting the number of bytes
- * written per line.
- */
- cal_set_field(&val, stride / 8, CAL_WR_DMA_XSIZE_MASK);
- cal_write(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx), val);
- ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->dma_ctx,
- cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx)));
-}
-
-void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr)
-{
- cal_write(ctx->cal, CAL_WR_DMA_ADDR(ctx->dma_ctx), addr);
-}
-
-static void cal_ctx_wr_dma_enable(struct cal_ctx *ctx)
-{
- u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
-
- cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST,
- CAL_WR_DMA_CTRL_MODE_MASK);
- cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
-}
-
-static void cal_ctx_wr_dma_disable(struct cal_ctx *ctx)
-{
- u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
-
- cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_DIS,
- CAL_WR_DMA_CTRL_MODE_MASK);
- cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
-}
-
-static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx)
-{
- bool stopped;
-
- spin_lock_irq(&ctx->dma.lock);
- stopped = ctx->dma.state == CAL_DMA_STOPPED;
- spin_unlock_irq(&ctx->dma.lock);
-
- return stopped;
-}
-
-int cal_ctx_prepare(struct cal_ctx *ctx)
-{
- int ret;
-
- ctx->use_pix_proc = !ctx->fmtinfo->meta;
-
- if (ctx->use_pix_proc) {
- ret = cal_reserve_pix_proc(ctx->cal);
- if (ret < 0) {
- ctx_err(ctx, "Failed to reserve pix proc: %d\n", ret);
- return ret;
- }
-
- ctx->pix_proc = ret;
- }
-
- return 0;
-}
-
-void cal_ctx_unprepare(struct cal_ctx *ctx)
-{
- if (ctx->use_pix_proc)
- cal_release_pix_proc(ctx->cal, ctx->pix_proc);
-}
-
-void cal_ctx_start(struct cal_ctx *ctx)
-{
- ctx->sequence = 0;
- ctx->dma.state = CAL_DMA_RUNNING;
-
- /* Configure the CSI-2, pixel processing and write DMA contexts. */
- cal_ctx_csi2_config(ctx);
- if (ctx->use_pix_proc)
- cal_ctx_pix_proc_config(ctx);
- cal_ctx_wr_dma_config(ctx);
-
- /* Enable IRQ_WDMA_END and IRQ_WDMA_START. */
- cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(1),
- CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx));
- cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(2),
- CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx));
-
- cal_ctx_wr_dma_enable(ctx);
-}
-
-void cal_ctx_stop(struct cal_ctx *ctx)
-{
- long timeout;
-
- /*
- * Request DMA stop and wait until it completes. If completion times
- * out, forcefully disable the DMA.
- */
- spin_lock_irq(&ctx->dma.lock);
- ctx->dma.state = CAL_DMA_STOP_REQUESTED;
- spin_unlock_irq(&ctx->dma.lock);
-
- timeout = wait_event_timeout(ctx->dma.wait, cal_ctx_wr_dma_stopped(ctx),
- msecs_to_jiffies(500));
- if (!timeout) {
- ctx_err(ctx, "failed to disable dma cleanly\n");
- cal_ctx_wr_dma_disable(ctx);
- }
-
- /* Disable IRQ_WDMA_END and IRQ_WDMA_START. */
- cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(1),
- CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx));
- cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(2),
- CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx));
-
- ctx->dma.state = CAL_DMA_STOPPED;
-
- /* Disable CSI2 context */
- cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), 0);
-
- /* Disable pix proc */
- if (ctx->use_pix_proc)
- cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), 0);
-}
-
-/* ------------------------------------------------------------------
- * IRQ Handling
- * ------------------------------------------------------------------
- */
-
-static inline void cal_irq_wdma_start(struct cal_ctx *ctx)
-{
- spin_lock(&ctx->dma.lock);
-
- if (ctx->dma.state == CAL_DMA_STOP_REQUESTED) {
- /*
- * If a stop is requested, disable the write DMA context
- * immediately. The CAL_WR_DMA_CTRL_j.MODE field is shadowed,
- * the current frame will complete and the DMA will then stop.
- */
- cal_ctx_wr_dma_disable(ctx);
- ctx->dma.state = CAL_DMA_STOP_PENDING;
- } else if (!list_empty(&ctx->dma.queue) && !ctx->dma.pending) {
- /*
- * Otherwise, if a new buffer is available, queue it to the
- * hardware.
- */
- struct cal_buffer *buf;
- dma_addr_t addr;
-
- buf = list_first_entry(&ctx->dma.queue, struct cal_buffer,
- list);
- addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
- cal_ctx_set_dma_addr(ctx, addr);
-
- ctx->dma.pending = buf;
- list_del(&buf->list);
- }
-
- spin_unlock(&ctx->dma.lock);
-}
-
-static inline void cal_irq_wdma_end(struct cal_ctx *ctx)
-{
- struct cal_buffer *buf = NULL;
-
- spin_lock(&ctx->dma.lock);
-
- /* If the DMA context was stopping, it is now stopped. */
- if (ctx->dma.state == CAL_DMA_STOP_PENDING) {
- ctx->dma.state = CAL_DMA_STOPPED;
- wake_up(&ctx->dma.wait);
- }
-
- /* If a new buffer was queued, complete the current buffer. */
- if (ctx->dma.pending) {
- buf = ctx->dma.active;
- ctx->dma.active = ctx->dma.pending;
- ctx->dma.pending = NULL;
- }
-
- spin_unlock(&ctx->dma.lock);
-
- if (buf) {
- buf->vb.vb2_buf.timestamp = ktime_get_ns();
- buf->vb.field = ctx->v_fmt.fmt.pix.field;
- buf->vb.sequence = ctx->sequence++;
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
- }
-}
-
-static irqreturn_t cal_irq(int irq_cal, void *data)
-{
- struct cal_dev *cal = data;
- u32 status;
-
- status = cal_read(cal, CAL_HL_IRQSTATUS(0));
- if (status) {
- unsigned int i;
-
- cal_write(cal, CAL_HL_IRQSTATUS(0), status);
-
- if (status & CAL_HL_IRQ_OCPO_ERR_MASK)
- dev_err_ratelimited(cal->dev, "OCPO ERROR\n");
-
- for (i = 0; i < cal->data->num_csi2_phy; ++i) {
- if (status & CAL_HL_IRQ_CIO_MASK(i)) {
- u32 cio_stat = cal_read(cal,
- CAL_CSI2_COMPLEXIO_IRQSTATUS(i));
-
- dev_err_ratelimited(cal->dev,
- "CIO%u error: %#08x\n", i, cio_stat);
-
- cal_write(cal, CAL_CSI2_COMPLEXIO_IRQSTATUS(i),
- cio_stat);
- }
-
- if (status & CAL_HL_IRQ_VC_MASK(i)) {
- u32 vc_stat = cal_read(cal, CAL_CSI2_VC_IRQSTATUS(i));
-
- dev_err_ratelimited(cal->dev,
- "CIO%u VC error: %#08x\n",
- i, vc_stat);
-
- cal_write(cal, CAL_CSI2_VC_IRQSTATUS(i), vc_stat);
- }
- }
- }
-
- /* Check which DMA just finished */
- status = cal_read(cal, CAL_HL_IRQSTATUS(1));
- if (status) {
- unsigned int i;
-
- /* Clear Interrupt status */
- cal_write(cal, CAL_HL_IRQSTATUS(1), status);
-
- for (i = 0; i < cal->num_contexts; ++i) {
- if (status & CAL_HL_IRQ_WDMA_END_MASK(i))
- cal_irq_wdma_end(cal->ctx[i]);
- }
- }
-
- /* Check which DMA just started */
- status = cal_read(cal, CAL_HL_IRQSTATUS(2));
- if (status) {
- unsigned int i;
-
- /* Clear Interrupt status */
- cal_write(cal, CAL_HL_IRQSTATUS(2), status);
-
- for (i = 0; i < cal->num_contexts; ++i) {
- if (status & CAL_HL_IRQ_WDMA_START_MASK(i))
- cal_irq_wdma_start(cal->ctx[i]);
- }
- }
-
- return IRQ_HANDLED;
-}
-
-/* ------------------------------------------------------------------
- * Asynchronous V4L2 subdev binding
- * ------------------------------------------------------------------
- */
-
-struct cal_v4l2_async_subdev {
- struct v4l2_async_subdev asd; /* Must be first */
- struct cal_camerarx *phy;
-};
-
-static inline struct cal_v4l2_async_subdev *
-to_cal_asd(struct v4l2_async_subdev *asd)
-{
- return container_of(asd, struct cal_v4l2_async_subdev, asd);
-}
-
-static int cal_async_notifier_bound(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *subdev,
- struct v4l2_async_subdev *asd)
-{
- struct cal_camerarx *phy = to_cal_asd(asd)->phy;
- int pad;
- int ret;
-
- if (phy->source) {
- phy_info(phy, "Rejecting subdev %s (Already set!!)",
- subdev->name);
- return 0;
- }
-
- phy->source = subdev;
- phy_dbg(1, phy, "Using source %s for capture\n", subdev->name);
-
- pad = media_entity_get_fwnode_pad(&subdev->entity,
- of_fwnode_handle(phy->source_ep_node),
- MEDIA_PAD_FL_SOURCE);
- if (pad < 0) {
- phy_err(phy, "Source %s has no connected source pad\n",
- subdev->name);
- return pad;
- }
-
- ret = media_create_pad_link(&subdev->entity, pad,
- &phy->subdev.entity, CAL_CAMERARX_PAD_SINK,
- MEDIA_LNK_FL_IMMUTABLE |
- MEDIA_LNK_FL_ENABLED);
- if (ret) {
- phy_err(phy, "Failed to create media link for source %s\n",
- subdev->name);
- return ret;
- }
-
- return 0;
-}
-
-static int cal_async_notifier_complete(struct v4l2_async_notifier *notifier)
-{
- struct cal_dev *cal = container_of(notifier, struct cal_dev, notifier);
- unsigned int i;
- int ret;
-
- for (i = 0; i < cal->num_contexts; ++i) {
- ret = cal_ctx_v4l2_register(cal->ctx[i]);
- if (ret)
- goto err_ctx_unreg;
- }
-
- if (!cal_mc_api)
- return 0;
-
- ret = v4l2_device_register_subdev_nodes(&cal->v4l2_dev);
- if (ret)
- goto err_ctx_unreg;
-
- return 0;
-
-err_ctx_unreg:
- for (; i > 0; --i) {
- if (!cal->ctx[i - 1])
- continue;
-
- cal_ctx_v4l2_unregister(cal->ctx[i - 1]);
- }
-
- return ret;
-}
-
-static const struct v4l2_async_notifier_operations cal_async_notifier_ops = {
- .bound = cal_async_notifier_bound,
- .complete = cal_async_notifier_complete,
-};
-
-static int cal_async_notifier_register(struct cal_dev *cal)
-{
- unsigned int i;
- int ret;
-
- v4l2_async_nf_init(&cal->notifier);
- cal->notifier.ops = &cal_async_notifier_ops;
-
- for (i = 0; i < cal->data->num_csi2_phy; ++i) {
- struct cal_camerarx *phy = cal->phy[i];
- struct cal_v4l2_async_subdev *casd;
- struct fwnode_handle *fwnode;
-
- if (!phy->source_node)
- continue;
-
- fwnode = of_fwnode_handle(phy->source_node);
- casd = v4l2_async_nf_add_fwnode(&cal->notifier,
- fwnode,
- struct cal_v4l2_async_subdev);
- if (IS_ERR(casd)) {
- phy_err(phy, "Failed to add subdev to notifier\n");
- ret = PTR_ERR(casd);
- goto error;
- }
-
- casd->phy = phy;
- }
-
- ret = v4l2_async_nf_register(&cal->v4l2_dev, &cal->notifier);
- if (ret) {
- cal_err(cal, "Error registering async notifier\n");
- goto error;
- }
-
- return 0;
-
-error:
- v4l2_async_nf_cleanup(&cal->notifier);
- return ret;
-}
-
-static void cal_async_notifier_unregister(struct cal_dev *cal)
-{
- v4l2_async_nf_unregister(&cal->notifier);
- v4l2_async_nf_cleanup(&cal->notifier);
-}
-
-/* ------------------------------------------------------------------
- * Media and V4L2 device handling
- * ------------------------------------------------------------------
- */
-
-/*
- * Register user-facing devices. To be called at the end of the probe function
- * when all resources are initialized and ready.
- */
-static int cal_media_register(struct cal_dev *cal)
-{
- int ret;
-
- ret = media_device_register(&cal->mdev);
- if (ret) {
- cal_err(cal, "Failed to register media device\n");
- return ret;
- }
-
- /*
- * Register the async notifier. This may trigger registration of the
- * V4L2 video devices if all subdevs are ready.
- */
- ret = cal_async_notifier_register(cal);
- if (ret) {
- media_device_unregister(&cal->mdev);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * Unregister the user-facing devices, but don't free memory yet. To be called
- * at the beginning of the remove function, to disallow access from userspace.
- */
-static void cal_media_unregister(struct cal_dev *cal)
-{
- unsigned int i;
-
- /* Unregister all the V4L2 video devices. */
- for (i = 0; i < cal->num_contexts; i++)
- cal_ctx_v4l2_unregister(cal->ctx[i]);
-
- cal_async_notifier_unregister(cal);
- media_device_unregister(&cal->mdev);
-}
-
-/*
- * Initialize the in-kernel objects. To be called at the beginning of the probe
- * function, before the V4L2 device is used by the driver.
- */
-static int cal_media_init(struct cal_dev *cal)
-{
- struct media_device *mdev = &cal->mdev;
- int ret;
-
- mdev->dev = cal->dev;
- mdev->hw_revision = cal->revision;
- strscpy(mdev->model, "CAL", sizeof(mdev->model));
- snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
- dev_name(mdev->dev));
- media_device_init(mdev);
-
- /*
- * Initialize the V4L2 device (despite the function name, this performs
- * initialization, not registration).
- */
- cal->v4l2_dev.mdev = mdev;
- ret = v4l2_device_register(cal->dev, &cal->v4l2_dev);
- if (ret) {
- cal_err(cal, "Failed to register V4L2 device\n");
- return ret;
- }
-
- vb2_dma_contig_set_max_seg_size(cal->dev, DMA_BIT_MASK(32));
-
- return 0;
-}
-
-/*
- * Cleanup the in-kernel objects, freeing memory. To be called at the very end
- * of the remove sequence, when nothing (including userspace) can access the
- * objects anymore.
- */
-static void cal_media_cleanup(struct cal_dev *cal)
-{
- v4l2_device_unregister(&cal->v4l2_dev);
- media_device_cleanup(&cal->mdev);
-
- vb2_dma_contig_clear_max_seg_size(cal->dev);
-}
-
-/* ------------------------------------------------------------------
- * Initialization and module stuff
- * ------------------------------------------------------------------
- */
-
-static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst)
-{
- struct cal_ctx *ctx;
- int ret;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return NULL;
-
- ctx->cal = cal;
- ctx->phy = cal->phy[inst];
- ctx->dma_ctx = inst;
- ctx->csi2_ctx = inst;
- ctx->cport = inst;
- ctx->vc = 0;
- ctx->datatype = CAL_CSI2_CTX_DT_ANY;
-
- ret = cal_ctx_v4l2_init(ctx);
- if (ret)
- return NULL;
-
- return ctx;
-}
-
-static void cal_ctx_destroy(struct cal_ctx *ctx)
-{
- cal_ctx_v4l2_cleanup(ctx);
-
- kfree(ctx);
-}
-
-static const struct of_device_id cal_of_match[] = {
- {
- .compatible = "ti,dra72-cal",
- .data = (void *)&dra72x_cal_data,
- },
- {
- .compatible = "ti,dra72-pre-es2-cal",
- .data = (void *)&dra72x_es1_cal_data,
- },
- {
- .compatible = "ti,dra76-cal",
- .data = (void *)&dra76x_cal_data,
- },
- {
- .compatible = "ti,am654-cal",
- .data = (void *)&am654_cal_data,
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, cal_of_match);
-
-/* Get hardware revision and info. */
-
-#define CAL_HL_HWINFO_VALUE 0xa3c90469
-
-static void cal_get_hwinfo(struct cal_dev *cal)
-{
- u32 hwinfo;
-
- cal->revision = cal_read(cal, CAL_HL_REVISION);
- switch (FIELD_GET(CAL_HL_REVISION_SCHEME_MASK, cal->revision)) {
- case CAL_HL_REVISION_SCHEME_H08:
- cal_dbg(3, cal, "CAL HW revision %lu.%lu.%lu (0x%08x)\n",
- FIELD_GET(CAL_HL_REVISION_MAJOR_MASK, cal->revision),
- FIELD_GET(CAL_HL_REVISION_MINOR_MASK, cal->revision),
- FIELD_GET(CAL_HL_REVISION_RTL_MASK, cal->revision),
- cal->revision);
- break;
-
- case CAL_HL_REVISION_SCHEME_LEGACY:
- default:
- cal_info(cal, "Unexpected CAL HW revision 0x%08x\n",
- cal->revision);
- break;
- }
-
- hwinfo = cal_read(cal, CAL_HL_HWINFO);
- if (hwinfo != CAL_HL_HWINFO_VALUE)
- cal_info(cal, "CAL_HL_HWINFO = 0x%08x, expected 0x%08x\n",
- hwinfo, CAL_HL_HWINFO_VALUE);
-}
-
-static int cal_init_camerarx_regmap(struct cal_dev *cal)
-{
- struct platform_device *pdev = to_platform_device(cal->dev);
- struct device_node *np = cal->dev->of_node;
- struct regmap_config config = { };
- struct regmap *syscon;
- struct resource *res;
- unsigned int offset;
- void __iomem *base;
-
- syscon = syscon_regmap_lookup_by_phandle_args(np, "ti,camerrx-control",
- 1, &offset);
- if (!IS_ERR(syscon)) {
- cal->syscon_camerrx = syscon;
- cal->syscon_camerrx_offset = offset;
- return 0;
- }
-
- dev_warn(cal->dev, "failed to get ti,camerrx-control: %ld\n",
- PTR_ERR(syscon));
-
- /*
- * Backward DTS compatibility. If syscon entry is not present then
- * check if the camerrx_control resource is present.
- */
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "camerrx_control");
- base = devm_ioremap_resource(cal->dev, res);
- if (IS_ERR(base)) {
- cal_err(cal, "failed to ioremap camerrx_control\n");
- return PTR_ERR(base);
- }
-
- cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
- res->name, &res->start, &res->end);
-
- config.reg_bits = 32;
- config.reg_stride = 4;
- config.val_bits = 32;
- config.max_register = resource_size(res) - 4;
-
- syscon = regmap_init_mmio(NULL, base, &config);
- if (IS_ERR(syscon)) {
- pr_err("regmap init failed\n");
- return PTR_ERR(syscon);
- }
-
- /*
- * In this case the base already point to the direct CM register so no
- * need for an offset.
- */
- cal->syscon_camerrx = syscon;
- cal->syscon_camerrx_offset = 0;
-
- return 0;
-}
-
-static int cal_probe(struct platform_device *pdev)
-{
- struct cal_dev *cal;
- bool connected = false;
- unsigned int i;
- int ret;
- int irq;
-
- cal = devm_kzalloc(&pdev->dev, sizeof(*cal), GFP_KERNEL);
- if (!cal)
- return -ENOMEM;
-
- cal->data = of_device_get_match_data(&pdev->dev);
- if (!cal->data) {
- dev_err(&pdev->dev, "Could not get feature data based on compatible version\n");
- return -ENODEV;
- }
-
- cal->dev = &pdev->dev;
- platform_set_drvdata(pdev, cal);
-
- /* Acquire resources: clocks, CAMERARX regmap, I/O memory and IRQ. */
- cal->fclk = devm_clk_get(&pdev->dev, "fck");
- if (IS_ERR(cal->fclk)) {
- dev_err(&pdev->dev, "cannot get CAL fclk\n");
- return PTR_ERR(cal->fclk);
- }
-
- ret = cal_init_camerarx_regmap(cal);
- if (ret < 0)
- return ret;
-
- cal->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "cal_top");
- cal->base = devm_ioremap_resource(&pdev->dev, cal->res);
- if (IS_ERR(cal->base))
- return PTR_ERR(cal->base);
-
- cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
- cal->res->name, &cal->res->start, &cal->res->end);
-
- irq = platform_get_irq(pdev, 0);
- cal_dbg(1, cal, "got irq# %d\n", irq);
- ret = devm_request_irq(&pdev->dev, irq, cal_irq, 0, CAL_MODULE_NAME,
- cal);
- if (ret)
- return ret;
-
- /* Read the revision and hardware info to verify hardware access. */
- pm_runtime_enable(&pdev->dev);
- ret = pm_runtime_resume_and_get(&pdev->dev);
- if (ret)
- goto error_pm_runtime;
-
- cal_get_hwinfo(cal);
- pm_runtime_put_sync(&pdev->dev);
-
- /* Initialize the media device. */
- ret = cal_media_init(cal);
- if (ret < 0)
- goto error_pm_runtime;
-
- /* Create CAMERARX PHYs. */
- for (i = 0; i < cal->data->num_csi2_phy; ++i) {
- cal->phy[i] = cal_camerarx_create(cal, i);
- if (IS_ERR(cal->phy[i])) {
- ret = PTR_ERR(cal->phy[i]);
- cal->phy[i] = NULL;
- goto error_camerarx;
- }
-
- if (cal->phy[i]->source_node)
- connected = true;
- }
-
- if (!connected) {
- cal_err(cal, "Neither port is configured, no point in staying up\n");
- ret = -ENODEV;
- goto error_camerarx;
- }
-
- /* Create contexts. */
- for (i = 0; i < cal->data->num_csi2_phy; ++i) {
- if (!cal->phy[i]->source_node)
- continue;
-
- cal->ctx[cal->num_contexts] = cal_ctx_create(cal, i);
- if (!cal->ctx[cal->num_contexts]) {
- cal_err(cal, "Failed to create context %u\n", cal->num_contexts);
- ret = -ENODEV;
- goto error_context;
- }
-
- cal->num_contexts++;
- }
-
- /* Register the media device. */
- ret = cal_media_register(cal);
- if (ret)
- goto error_context;
-
- return 0;
-
-error_context:
- for (i = 0; i < cal->num_contexts; i++)
- cal_ctx_destroy(cal->ctx[i]);
-
-error_camerarx:
- for (i = 0; i < cal->data->num_csi2_phy; i++)
- cal_camerarx_destroy(cal->phy[i]);
-
- cal_media_cleanup(cal);
-
-error_pm_runtime:
- pm_runtime_disable(&pdev->dev);
-
- return ret;
-}
-
-static int cal_remove(struct platform_device *pdev)
-{
- struct cal_dev *cal = platform_get_drvdata(pdev);
- unsigned int i;
- int ret;
-
- cal_dbg(1, cal, "Removing %s\n", CAL_MODULE_NAME);
-
- ret = pm_runtime_resume_and_get(&pdev->dev);
-
- cal_media_unregister(cal);
-
- for (i = 0; i < cal->data->num_csi2_phy; i++)
- cal_camerarx_disable(cal->phy[i]);
-
- for (i = 0; i < cal->num_contexts; i++)
- cal_ctx_destroy(cal->ctx[i]);
-
- for (i = 0; i < cal->data->num_csi2_phy; i++)
- cal_camerarx_destroy(cal->phy[i]);
-
- cal_media_cleanup(cal);
-
- if (ret >= 0)
- pm_runtime_put_sync(&pdev->dev);
- pm_runtime_disable(&pdev->dev);
-
- return 0;
-}
-
-static int cal_runtime_resume(struct device *dev)
-{
- struct cal_dev *cal = dev_get_drvdata(dev);
- unsigned int i;
- u32 val;
-
- if (cal->data->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {
- /*
- * Apply errata on both port everytime we (re-)enable
- * the clock
- */
- for (i = 0; i < cal->data->num_csi2_phy; i++)
- cal_camerarx_i913_errata(cal->phy[i]);
- }
-
- /*
- * Enable global interrupts that are not related to a particular
- * CAMERARAX or context.
- */
- cal_write(cal, CAL_HL_IRQENABLE_SET(0), CAL_HL_IRQ_OCPO_ERR_MASK);
-
- val = cal_read(cal, CAL_CTRL);
- cal_set_field(&val, CAL_CTRL_BURSTSIZE_BURST128,
- CAL_CTRL_BURSTSIZE_MASK);
- cal_set_field(&val, 0xf, CAL_CTRL_TAGCNT_MASK);
- cal_set_field(&val, CAL_CTRL_POSTED_WRITES_NONPOSTED,
- CAL_CTRL_POSTED_WRITES_MASK);
- cal_set_field(&val, 0xff, CAL_CTRL_MFLAGL_MASK);
- cal_set_field(&val, 0xff, CAL_CTRL_MFLAGH_MASK);
- cal_write(cal, CAL_CTRL, val);
- cal_dbg(3, cal, "CAL_CTRL = 0x%08x\n", cal_read(cal, CAL_CTRL));
-
- return 0;
-}
-
-static const struct dev_pm_ops cal_pm_ops = {
- .runtime_resume = cal_runtime_resume,
-};
-
-static struct platform_driver cal_pdrv = {
- .probe = cal_probe,
- .remove = cal_remove,
- .driver = {
- .name = CAL_MODULE_NAME,
- .pm = &cal_pm_ops,
- .of_match_table = cal_of_match,
- },
-};
-
-module_platform_driver(cal_pdrv);
diff --git a/drivers/media/platform/ti-vpe/cal.h b/drivers/media/platform/ti-vpe/cal.h
deleted file mode 100644
index 527e22d022f3..000000000000
--- a/drivers/media/platform/ti-vpe/cal.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * TI Camera Access Layer (CAL)
- *
- * Copyright (c) 2015-2020 Texas Instruments Inc.
- *
- * Authors:
- * Benoit Parrot
- * Laurent Pinchart
- */
-#ifndef __TI_CAL_H__
-#define __TI_CAL_H__
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define CAL_MODULE_NAME "cal"
-#define CAL_MAX_NUM_CONTEXT 8
-#define CAL_NUM_CSI2_PORTS 2
-
-/*
- * The width is limited by the size of the CAL_WR_DMA_XSIZE_j.XSIZE field,
- * expressed in multiples of 64 bits. The height is limited by the size of the
- * CAL_CSI2_CTXi_j.CTXi_LINES and CAL_WR_DMA_CTRL_j.YSIZE fields, expressed in
- * lines.
- */
-#define CAL_MIN_WIDTH_BYTES 16
-#define CAL_MAX_WIDTH_BYTES (8192 * 8)
-#define CAL_MIN_HEIGHT_LINES 1
-#define CAL_MAX_HEIGHT_LINES 16383
-
-#define CAL_CAMERARX_PAD_SINK 0
-#define CAL_CAMERARX_PAD_FIRST_SOURCE 1
-#define CAL_CAMERARX_NUM_SOURCE_PADS 1
-#define CAL_CAMERARX_NUM_PADS (1 + CAL_CAMERARX_NUM_SOURCE_PADS)
-
-static inline bool cal_rx_pad_is_sink(u32 pad)
-{
- /* Camera RX has 1 sink pad, and N source pads */
- return pad == 0;
-}
-
-static inline bool cal_rx_pad_is_source(u32 pad)
-{
- /* Camera RX has 1 sink pad, and N source pads */
- return pad >= CAL_CAMERARX_PAD_FIRST_SOURCE &&
- pad <= CAL_CAMERARX_NUM_SOURCE_PADS;
-}
-
-struct device;
-struct device_node;
-struct resource;
-struct regmap;
-struct regmap_fied;
-
-/* CTRL_CORE_CAMERRX_CONTROL register field id */
-enum cal_camerarx_field {
- F_CTRLCLKEN,
- F_CAMMODE,
- F_LANEENABLE,
- F_CSI_MODE,
- F_MAX_FIELDS,
-};
-
-enum cal_dma_state {
- CAL_DMA_RUNNING,
- CAL_DMA_STOP_REQUESTED,
- CAL_DMA_STOP_PENDING,
- CAL_DMA_STOPPED,
-};
-
-struct cal_format_info {
- u32 fourcc;
- u32 code;
- /* Bits per pixel */
- u8 bpp;
- bool meta;
-};
-
-/* buffer for one video frame */
-struct cal_buffer {
- /* common v4l buffer stuff -- must be first */
- struct vb2_v4l2_buffer vb;
- struct list_head list;
-};
-
-/**
- * struct cal_dmaqueue - Queue of DMA buffers
- */
-struct cal_dmaqueue {
- /**
- * @lock: Protects all fields in the cal_dmaqueue.
- */
- spinlock_t lock;
-
- /**
- * @queue: Buffers queued to the driver and waiting for DMA processing.
- * Buffers are added to the list by the vb2 .buffer_queue() operation,
- * and move to @pending when they are scheduled for the next frame.
- */
- struct list_head queue;
- /**
- * @pending: Buffer provided to the hardware to DMA the next frame.
- * Will move to @active at the end of the current frame.
- */
- struct cal_buffer *pending;
- /**
- * @active: Buffer being DMA'ed to for the current frame. Will be
- * retired and given back to vb2 at the end of the current frame if
- * a @pending buffer has been scheduled to replace it.
- */
- struct cal_buffer *active;
-
- /** @state: State of the DMA engine. */
- enum cal_dma_state state;
- /** @wait: Wait queue to signal a @state transition to CAL_DMA_STOPPED. */
- struct wait_queue_head wait;
-};
-
-struct cal_camerarx_data {
- struct {
- unsigned int lsb;
- unsigned int msb;
- } fields[F_MAX_FIELDS];
- unsigned int num_lanes;
-};
-
-struct cal_data {
- const struct cal_camerarx_data *camerarx;
- unsigned int num_csi2_phy;
- unsigned int flags;
-};
-
-/*
- * The Camera Adaptation Layer (CAL) module is paired with one or more complex
- * I/O PHYs (CAMERARX). It contains multiple instances of CSI-2, processing and
- * DMA contexts.
- *
- * The cal_dev structure represents the whole subsystem, including the CAL and
- * the CAMERARX instances. Instances of struct cal_dev are named cal through the
- * driver.
- *
- * The cal_camerarx structure represents one CAMERARX instance. Instances of
- * cal_camerarx are named phy through the driver.
- *
- * The cal_ctx structure represents the combination of one CSI-2 context, one
- * processing context and one DMA context. Instance of struct cal_ctx are named
- * ctx through the driver.
- */
-
-struct cal_camerarx {
- void __iomem *base;
- struct resource *res;
- struct regmap_field *fields[F_MAX_FIELDS];
-
- struct cal_dev *cal;
- unsigned int instance;
-
- struct v4l2_fwnode_endpoint endpoint;
- struct device_node *source_ep_node;
- struct device_node *source_node;
- struct v4l2_subdev *source;
- struct media_pipeline pipe;
-
- struct v4l2_subdev subdev;
- struct media_pad pads[CAL_CAMERARX_NUM_PADS];
- struct v4l2_mbus_framefmt formats[CAL_CAMERARX_NUM_PADS];
-
- /*
- * Lock for camerarx ops. Protects:
- * - formats
- * - enable_count
- */
- struct mutex mutex;
-
- unsigned int enable_count;
-};
-
-struct cal_dev {
- struct clk *fclk;
- int irq;
- void __iomem *base;
- struct resource *res;
- struct device *dev;
-
- const struct cal_data *data;
- u32 revision;
-
- /* Control Module handle */
- struct regmap *syscon_camerrx;
- u32 syscon_camerrx_offset;
-
- /* Camera Core Module handle */
- struct cal_camerarx *phy[CAL_NUM_CSI2_PORTS];
-
- u32 num_contexts;
- struct cal_ctx *ctx[CAL_MAX_NUM_CONTEXT];
-
- struct media_device mdev;
- struct v4l2_device v4l2_dev;
- struct v4l2_async_notifier notifier;
-
- unsigned long reserved_pix_proc_mask;
-};
-
-/*
- * There is one cal_ctx structure for each camera core context.
- */
-struct cal_ctx {
- struct v4l2_ctrl_handler ctrl_handler;
- struct video_device vdev;
- struct media_pad pad;
-
- struct cal_dev *cal;
- struct cal_camerarx *phy;
-
- /* v4l2_ioctl mutex */
- struct mutex mutex;
-
- struct cal_dmaqueue dma;
-
- /* video capture */
- const struct cal_format_info *fmtinfo;
- /* Used to store current pixel format */
- struct v4l2_format v_fmt;
-
- /* Current subdev enumerated format (legacy) */
- const struct cal_format_info **active_fmt;
- unsigned int num_active_fmt;
-
- unsigned int sequence;
- struct vb2_queue vb_vidq;
- u8 dma_ctx;
- u8 cport;
- u8 csi2_ctx;
- u8 pix_proc;
- u8 vc;
- u8 datatype;
-
- bool use_pix_proc;
-};
-
-extern unsigned int cal_debug;
-extern int cal_video_nr;
-extern bool cal_mc_api;
-
-#define cal_dbg(level, cal, fmt, arg...) \
- do { \
- if (cal_debug >= (level)) \
- dev_printk(KERN_DEBUG, (cal)->dev, fmt, ##arg); \
- } while (0)
-#define cal_info(cal, fmt, arg...) \
- dev_info((cal)->dev, fmt, ##arg)
-#define cal_err(cal, fmt, arg...) \
- dev_err((cal)->dev, fmt, ##arg)
-
-#define ctx_dbg(level, ctx, fmt, arg...) \
- cal_dbg(level, (ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
-#define ctx_info(ctx, fmt, arg...) \
- cal_info((ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
-#define ctx_err(ctx, fmt, arg...) \
- cal_err((ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
-
-#define phy_dbg(level, phy, fmt, arg...) \
- cal_dbg(level, (phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
-#define phy_info(phy, fmt, arg...) \
- cal_info((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
-#define phy_err(phy, fmt, arg...) \
- cal_err((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
-
-static inline u32 cal_read(struct cal_dev *cal, u32 offset)
-{
- return ioread32(cal->base + offset);
-}
-
-static inline void cal_write(struct cal_dev *cal, u32 offset, u32 val)
-{
- iowrite32(val, cal->base + offset);
-}
-
-static __always_inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask)
-{
- return FIELD_GET(mask, cal_read(cal, offset));
-}
-
-static inline void cal_write_field(struct cal_dev *cal, u32 offset, u32 value,
- u32 mask)
-{
- u32 val = cal_read(cal, offset);
-
- val &= ~mask;
- val |= (value << __ffs(mask)) & mask;
- cal_write(cal, offset, val);
-}
-
-static inline void cal_set_field(u32 *valp, u32 field, u32 mask)
-{
- u32 val = *valp;
-
- val &= ~mask;
- val |= (field << __ffs(mask)) & mask;
- *valp = val;
-}
-
-extern const struct cal_format_info cal_formats[];
-extern const unsigned int cal_num_formats;
-const struct cal_format_info *cal_format_by_fourcc(u32 fourcc);
-const struct cal_format_info *cal_format_by_code(u32 code);
-
-void cal_quickdump_regs(struct cal_dev *cal);
-
-void cal_camerarx_disable(struct cal_camerarx *phy);
-void cal_camerarx_i913_errata(struct cal_camerarx *phy);
-struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
- unsigned int instance);
-void cal_camerarx_destroy(struct cal_camerarx *phy);
-
-int cal_ctx_prepare(struct cal_ctx *ctx);
-void cal_ctx_unprepare(struct cal_ctx *ctx);
-void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr);
-void cal_ctx_start(struct cal_ctx *ctx);
-void cal_ctx_stop(struct cal_ctx *ctx);
-
-int cal_ctx_v4l2_register(struct cal_ctx *ctx);
-void cal_ctx_v4l2_unregister(struct cal_ctx *ctx);
-int cal_ctx_v4l2_init(struct cal_ctx *ctx);
-void cal_ctx_v4l2_cleanup(struct cal_ctx *ctx);
-
-#endif /* __TI_CAL_H__ */
diff --git a/drivers/media/platform/ti-vpe/cal_regs.h b/drivers/media/platform/ti-vpe/cal_regs.h
deleted file mode 100644
index 40e4f972fcb7..000000000000
--- a/drivers/media/platform/ti-vpe/cal_regs.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * TI CAL camera interface driver
- *
- * Copyright (c) 2015 Texas Instruments Inc.
- *
- * Benoit Parrot,
- */
-
-#ifndef __TI_CAL_REGS_H
-#define __TI_CAL_REGS_H
-
-/*
- * struct cal_dev.flags possibilities
- *
- * DRA72_CAL_PRE_ES2_LDO_DISABLE:
- * Errata i913: CSI2 LDO Needs to be disabled when module is powered on
- *
- * Enabling CSI2 LDO shorts it to core supply. It is crucial the 2 CSI2
- * LDOs on the device are disabled if CSI-2 module is powered on
- * (0x4845 B304 | 0x4845 B384 [28:27] = 0x1) or in ULPS (0x4845 B304
- * | 0x4845 B384 [28:27] = 0x2) mode. Common concerns include: high
- * current draw on the module supply in active mode.
- *
- * Errata does not apply when CSI-2 module is powered off
- * (0x4845 B304 | 0x4845 B384 [28:27] = 0x0).
- *
- * SW Workaround:
- * Set the following register bits to disable the LDO,
- * which is essentially CSI2 REG10 bit 6:
- *
- * Core 0: 0x4845 B828 = 0x0000 0040
- * Core 1: 0x4845 B928 = 0x0000 0040
- */
-#define DRA72_CAL_PRE_ES2_LDO_DISABLE BIT(0)
-
-/* CAL register offsets */
-
-#define CAL_HL_REVISION 0x0000
-#define CAL_HL_HWINFO 0x0004
-#define CAL_HL_SYSCONFIG 0x0010
-#define CAL_HL_IRQ_EOI 0x001c
-#define CAL_HL_IRQSTATUS_RAW(m) (0x20U + (m) * 0x10U)
-#define CAL_HL_IRQSTATUS(m) (0x24U + (m) * 0x10U)
-#define CAL_HL_IRQENABLE_SET(m) (0x28U + (m) * 0x10U)
-#define CAL_HL_IRQENABLE_CLR(m) (0x2cU + (m) * 0x10U)
-#define CAL_PIX_PROC(m) (0xc0U + (m) * 0x4U)
-#define CAL_CTRL 0x100
-#define CAL_CTRL1 0x104
-#define CAL_LINE_NUMBER_EVT 0x108
-#define CAL_VPORT_CTRL1 0x120
-#define CAL_VPORT_CTRL2 0x124
-#define CAL_BYS_CTRL1 0x130
-#define CAL_BYS_CTRL2 0x134
-#define CAL_RD_DMA_CTRL 0x140
-#define CAL_RD_DMA_PIX_ADDR 0x144
-#define CAL_RD_DMA_PIX_OFST 0x148
-#define CAL_RD_DMA_XSIZE 0x14c
-#define CAL_RD_DMA_YSIZE 0x150
-#define CAL_RD_DMA_INIT_ADDR 0x154
-#define CAL_RD_DMA_INIT_OFST 0x168
-#define CAL_RD_DMA_CTRL2 0x16c
-#define CAL_WR_DMA_CTRL(m) (0x200U + (m) * 0x10U)
-#define CAL_WR_DMA_ADDR(m) (0x204U + (m) * 0x10U)
-#define CAL_WR_DMA_OFST(m) (0x208U + (m) * 0x10U)
-#define CAL_WR_DMA_XSIZE(m) (0x20cU + (m) * 0x10U)
-#define CAL_CSI2_PPI_CTRL(m) (0x300U + (m) * 0x80U)
-#define CAL_CSI2_COMPLEXIO_CFG(m) (0x304U + (m) * 0x80U)
-#define CAL_CSI2_COMPLEXIO_IRQSTATUS(m) (0x308U + (m) * 0x80U)
-#define CAL_CSI2_SHORT_PACKET(m) (0x30cU + (m) * 0x80U)
-#define CAL_CSI2_COMPLEXIO_IRQENABLE(m) (0x310U + (m) * 0x80U)
-#define CAL_CSI2_TIMING(m) (0x314U + (m) * 0x80U)
-#define CAL_CSI2_VC_IRQENABLE(m) (0x318U + (m) * 0x80U)
-#define CAL_CSI2_VC_IRQSTATUS(m) (0x328U + (m) * 0x80U)
-#define CAL_CSI2_CTX(phy, csi2_ctx) (0x330U + (phy) * 0x80U + (csi2_ctx) * 4)
-#define CAL_CSI2_STATUS(phy, csi2_ctx) (0x350U + (phy) * 0x80U + (csi2_ctx) * 4)
-
-/* CAL CSI2 PHY register offsets */
-#define CAL_CSI2_PHY_REG0 0x000
-#define CAL_CSI2_PHY_REG1 0x004
-#define CAL_CSI2_PHY_REG2 0x008
-#define CAL_CSI2_PHY_REG10 0x028
-
-/* CAL Control Module Core Camerrx Control register offsets */
-#define CM_CTRL_CORE_CAMERRX_CONTROL 0x000
-
-/*********************************************************************
-* Field Definition Macros
-*********************************************************************/
-
-#define CAL_HL_REVISION_MINOR_MASK GENMASK(5, 0)
-#define CAL_HL_REVISION_CUSTOM_MASK GENMASK(7, 6)
-#define CAL_HL_REVISION_MAJOR_MASK GENMASK(10, 8)
-#define CAL_HL_REVISION_RTL_MASK GENMASK(15, 11)
-#define CAL_HL_REVISION_FUNC_MASK GENMASK(27, 16)
-#define CAL_HL_REVISION_SCHEME_MASK GENMASK(31, 30)
-#define CAL_HL_REVISION_SCHEME_H08 1
-#define CAL_HL_REVISION_SCHEME_LEGACY 0
-
-#define CAL_HL_HWINFO_WFIFO_MASK GENMASK(3, 0)
-#define CAL_HL_HWINFO_RFIFO_MASK GENMASK(7, 4)
-#define CAL_HL_HWINFO_PCTX_MASK GENMASK(12, 8)
-#define CAL_HL_HWINFO_WCTX_MASK GENMASK(18, 13)
-#define CAL_HL_HWINFO_VFIFO_MASK GENMASK(22, 19)
-#define CAL_HL_HWINFO_NCPORT_MASK GENMASK(27, 23)
-#define CAL_HL_HWINFO_NPPI_CTXS0_MASK GENMASK(29, 28)
-#define CAL_HL_HWINFO_NPPI_CTXS1_MASK GENMASK(31, 30)
-#define CAL_HL_HWINFO_NPPI_CONTEXTS_ZERO 0
-#define CAL_HL_HWINFO_NPPI_CONTEXTS_FOUR 1
-#define CAL_HL_HWINFO_NPPI_CONTEXTS_EIGHT 2
-#define CAL_HL_HWINFO_NPPI_CONTEXTS_RESERVED 3
-
-#define CAL_HL_SYSCONFIG_SOFTRESET_MASK BIT(0)
-#define CAL_HL_SYSCONFIG_SOFTRESET_DONE 0x0
-#define CAL_HL_SYSCONFIG_SOFTRESET_PENDING 0x1
-#define CAL_HL_SYSCONFIG_SOFTRESET_NOACTION 0x0
-#define CAL_HL_SYSCONFIG_SOFTRESET_RESET 0x1
-#define CAL_HL_SYSCONFIG_IDLE_MASK GENMASK(3, 2)
-#define CAL_HL_SYSCONFIG_IDLEMODE_FORCE 0
-#define CAL_HL_SYSCONFIG_IDLEMODE_NO 1
-#define CAL_HL_SYSCONFIG_IDLEMODE_SMART1 2
-#define CAL_HL_SYSCONFIG_IDLEMODE_SMART2 3
-
-#define CAL_HL_IRQ_EOI_LINE_NUMBER_MASK BIT(0)
-#define CAL_HL_IRQ_EOI_LINE_NUMBER_READ0 0
-#define CAL_HL_IRQ_EOI_LINE_NUMBER_EOI0 0
-
-#define CAL_HL_IRQ_WDMA_END_MASK(m) BIT(m)
-#define CAL_HL_IRQ_WDMA_START_MASK(m) BIT(m)
-
-#define CAL_HL_IRQ_OCPO_ERR_MASK BIT(6)
-
-#define CAL_HL_IRQ_CIO_MASK(i) BIT(16 + (i) * 8)
-#define CAL_HL_IRQ_VC_MASK(i) BIT(17 + (i) * 8)
-
-#define CAL_PIX_PROC_EN_MASK BIT(0)
-#define CAL_PIX_PROC_EXTRACT_MASK GENMASK(4, 1)
-#define CAL_PIX_PROC_EXTRACT_B6 0x0
-#define CAL_PIX_PROC_EXTRACT_B7 0x1
-#define CAL_PIX_PROC_EXTRACT_B8 0x2
-#define CAL_PIX_PROC_EXTRACT_B10 0x3
-#define CAL_PIX_PROC_EXTRACT_B10_MIPI 0x4
-#define CAL_PIX_PROC_EXTRACT_B12 0x5
-#define CAL_PIX_PROC_EXTRACT_B12_MIPI 0x6
-#define CAL_PIX_PROC_EXTRACT_B14 0x7
-#define CAL_PIX_PROC_EXTRACT_B14_MIPI 0x8
-#define CAL_PIX_PROC_EXTRACT_B16_BE 0x9
-#define CAL_PIX_PROC_EXTRACT_B16_LE 0xa
-#define CAL_PIX_PROC_DPCMD_MASK GENMASK(9, 5)
-#define CAL_PIX_PROC_DPCMD_BYPASS 0x0
-#define CAL_PIX_PROC_DPCMD_DPCM_10_8_1 0x2
-#define CAL_PIX_PROC_DPCMD_DPCM_12_8_1 0x8
-#define CAL_PIX_PROC_DPCMD_DPCM_10_7_1 0x4
-#define CAL_PIX_PROC_DPCMD_DPCM_10_7_2 0x5
-#define CAL_PIX_PROC_DPCMD_DPCM_10_6_1 0x6
-#define CAL_PIX_PROC_DPCMD_DPCM_10_6_2 0x7
-#define CAL_PIX_PROC_DPCMD_DPCM_12_7_1 0xa
-#define CAL_PIX_PROC_DPCMD_DPCM_12_6_1 0xc
-#define CAL_PIX_PROC_DPCMD_DPCM_14_10 0xe
-#define CAL_PIX_PROC_DPCMD_DPCM_14_8_1 0x10
-#define CAL_PIX_PROC_DPCMD_DPCM_16_12_1 0x12
-#define CAL_PIX_PROC_DPCMD_DPCM_16_10_1 0x14
-#define CAL_PIX_PROC_DPCMD_DPCM_16_8_1 0x16
-#define CAL_PIX_PROC_DPCME_MASK GENMASK(15, 11)
-#define CAL_PIX_PROC_DPCME_BYPASS 0x0
-#define CAL_PIX_PROC_DPCME_DPCM_10_8_1 0x2
-#define CAL_PIX_PROC_DPCME_DPCM_12_8_1 0x8
-#define CAL_PIX_PROC_DPCME_DPCM_14_10 0xe
-#define CAL_PIX_PROC_DPCME_DPCM_14_8_1 0x10
-#define CAL_PIX_PROC_DPCME_DPCM_16_12_1 0x12
-#define CAL_PIX_PROC_DPCME_DPCM_16_10_1 0x14
-#define CAL_PIX_PROC_DPCME_DPCM_16_8_1 0x16
-#define CAL_PIX_PROC_PACK_MASK GENMASK(18, 16)
-#define CAL_PIX_PROC_PACK_B8 0x0
-#define CAL_PIX_PROC_PACK_B10_MIPI 0x2
-#define CAL_PIX_PROC_PACK_B12 0x3
-#define CAL_PIX_PROC_PACK_B12_MIPI 0x4
-#define CAL_PIX_PROC_PACK_B16 0x5
-#define CAL_PIX_PROC_PACK_ARGB 0x6
-#define CAL_PIX_PROC_CPORT_MASK GENMASK(23, 19)
-
-#define CAL_CTRL_POSTED_WRITES_MASK BIT(0)
-#define CAL_CTRL_POSTED_WRITES_NONPOSTED 0
-#define CAL_CTRL_POSTED_WRITES 1
-#define CAL_CTRL_TAGCNT_MASK GENMASK(4, 1)
-#define CAL_CTRL_BURSTSIZE_MASK GENMASK(6, 5)
-#define CAL_CTRL_BURSTSIZE_BURST16 0x0
-#define CAL_CTRL_BURSTSIZE_BURST32 0x1
-#define CAL_CTRL_BURSTSIZE_BURST64 0x2
-#define CAL_CTRL_BURSTSIZE_BURST128 0x3
-#define CAL_CTRL_LL_FORCE_STATE_MASK GENMASK(12, 7)
-#define CAL_CTRL_MFLAGL_MASK GENMASK(20, 13)
-#define CAL_CTRL_PWRSCPCLK_MASK BIT(21)
-#define CAL_CTRL_PWRSCPCLK_AUTO 0
-#define CAL_CTRL_PWRSCPCLK_FORCE 1
-#define CAL_CTRL_RD_DMA_STALL_MASK BIT(22)
-#define CAL_CTRL_MFLAGH_MASK GENMASK(31, 24)
-
-#define CAL_CTRL1_PPI_GROUPING_MASK GENMASK(1, 0)
-#define CAL_CTRL1_PPI_GROUPING_DISABLED 0
-#define CAL_CTRL1_PPI_GROUPING_RESERVED 1
-#define CAL_CTRL1_PPI_GROUPING_0 2
-#define CAL_CTRL1_PPI_GROUPING_1 3
-#define CAL_CTRL1_INTERLEAVE01_MASK GENMASK(3, 2)
-#define CAL_CTRL1_INTERLEAVE01_DISABLED 0
-#define CAL_CTRL1_INTERLEAVE01_PIX1 1
-#define CAL_CTRL1_INTERLEAVE01_PIX4 2
-#define CAL_CTRL1_INTERLEAVE01_RESERVED 3
-#define CAL_CTRL1_INTERLEAVE23_MASK GENMASK(5, 4)
-#define CAL_CTRL1_INTERLEAVE23_DISABLED 0
-#define CAL_CTRL1_INTERLEAVE23_PIX1 1
-#define CAL_CTRL1_INTERLEAVE23_PIX4 2
-#define CAL_CTRL1_INTERLEAVE23_RESERVED 3
-
-#define CAL_LINE_NUMBER_EVT_CPORT_MASK GENMASK(4, 0)
-#define CAL_LINE_NUMBER_EVT_MASK GENMASK(29, 16)
-
-#define CAL_VPORT_CTRL1_PCLK_MASK GENMASK(16, 0)
-#define CAL_VPORT_CTRL1_XBLK_MASK GENMASK(24, 17)
-#define CAL_VPORT_CTRL1_YBLK_MASK GENMASK(30, 25)
-#define CAL_VPORT_CTRL1_WIDTH_MASK BIT(31)
-#define CAL_VPORT_CTRL1_WIDTH_ONE 0
-#define CAL_VPORT_CTRL1_WIDTH_TWO 1
-
-#define CAL_VPORT_CTRL2_CPORT_MASK GENMASK(4, 0)
-#define CAL_VPORT_CTRL2_FREERUNNING_MASK BIT(15)
-#define CAL_VPORT_CTRL2_FREERUNNING_GATED 0
-#define CAL_VPORT_CTRL2_FREERUNNING_FREE 1
-#define CAL_VPORT_CTRL2_FS_RESETS_MASK BIT(16)
-#define CAL_VPORT_CTRL2_FS_RESETS_NO 0
-#define CAL_VPORT_CTRL2_FS_RESETS_YES 1
-#define CAL_VPORT_CTRL2_FSM_RESET_MASK BIT(17)
-#define CAL_VPORT_CTRL2_FSM_RESET_NOEFFECT 0
-#define CAL_VPORT_CTRL2_FSM_RESET 1
-#define CAL_VPORT_CTRL2_RDY_THR_MASK GENMASK(31, 18)
-
-#define CAL_BYS_CTRL1_PCLK_MASK GENMASK(16, 0)
-#define CAL_BYS_CTRL1_XBLK_MASK GENMASK(24, 17)
-#define CAL_BYS_CTRL1_YBLK_MASK GENMASK(30, 25)
-#define CAL_BYS_CTRL1_BYSINEN_MASK BIT(31)
-
-#define CAL_BYS_CTRL2_CPORTIN_MASK GENMASK(4, 0)
-#define CAL_BYS_CTRL2_CPORTOUT_MASK GENMASK(9, 5)
-#define CAL_BYS_CTRL2_DUPLICATEDDATA_MASK BIT(10)
-#define CAL_BYS_CTRL2_DUPLICATEDDATA_NO 0
-#define CAL_BYS_CTRL2_DUPLICATEDDATA_YES 1
-#define CAL_BYS_CTRL2_FREERUNNING_MASK BIT(11)
-#define CAL_BYS_CTRL2_FREERUNNING_NO 0
-#define CAL_BYS_CTRL2_FREERUNNING_YES 1
-
-#define CAL_RD_DMA_CTRL_GO_MASK BIT(0)
-#define CAL_RD_DMA_CTRL_GO_DIS 0
-#define CAL_RD_DMA_CTRL_GO_EN 1
-#define CAL_RD_DMA_CTRL_GO_IDLE 0
-#define CAL_RD_DMA_CTRL_GO_BUSY 1
-#define CAL_RD_DMA_CTRL_INIT_MASK BIT(1)
-#define CAL_RD_DMA_CTRL_BW_LIMITER_MASK GENMASK(10, 2)
-#define CAL_RD_DMA_CTRL_OCP_TAG_CNT_MASK GENMASK(14, 11)
-#define CAL_RD_DMA_CTRL_PCLK_MASK GENMASK(31, 15)
-
-#define CAL_RD_DMA_PIX_ADDR_MASK GENMASK(31, 3)
-
-#define CAL_RD_DMA_PIX_OFST_MASK GENMASK(31, 4)
-
-#define CAL_RD_DMA_XSIZE_MASK GENMASK(31, 19)
-
-#define CAL_RD_DMA_YSIZE_MASK GENMASK(29, 16)
-
-#define CAL_RD_DMA_INIT_ADDR_MASK GENMASK(31, 3)
-
-#define CAL_RD_DMA_INIT_OFST_MASK GENMASK(31, 3)
-
-#define CAL_RD_DMA_CTRL2_CIRC_MODE_MASK GENMASK(2, 0)
-#define CAL_RD_DMA_CTRL2_CIRC_MODE_DIS 0
-#define CAL_RD_DMA_CTRL2_CIRC_MODE_ONE 1
-#define CAL_RD_DMA_CTRL2_CIRC_MODE_FOUR 2
-#define CAL_RD_DMA_CTRL2_CIRC_MODE_SIXTEEN 3
-#define CAL_RD_DMA_CTRL2_CIRC_MODE_SIXTYFOUR 4
-#define CAL_RD_DMA_CTRL2_CIRC_MODE_RESERVED 5
-#define CAL_RD_DMA_CTRL2_ICM_CSTART_MASK BIT(3)
-#define CAL_RD_DMA_CTRL2_PATTERN_MASK GENMASK(5, 4)
-#define CAL_RD_DMA_CTRL2_PATTERN_LINEAR 0
-#define CAL_RD_DMA_CTRL2_PATTERN_YUV420 1
-#define CAL_RD_DMA_CTRL2_PATTERN_RD2SKIP2 2
-#define CAL_RD_DMA_CTRL2_PATTERN_RD2SKIP4 3
-#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_MASK BIT(6)
-#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_FREERUNNING 0
-#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_WAITFORBYSOUT 1
-#define CAL_RD_DMA_CTRL2_CIRC_SIZE_MASK GENMASK(29, 16)
-
-#define CAL_WR_DMA_CTRL_MODE_MASK GENMASK(2, 0)
-#define CAL_WR_DMA_CTRL_MODE_DIS 0
-#define CAL_WR_DMA_CTRL_MODE_SHD 1
-#define CAL_WR_DMA_CTRL_MODE_CNT 2
-#define CAL_WR_DMA_CTRL_MODE_CNT_INIT 3
-#define CAL_WR_DMA_CTRL_MODE_CONST 4
-#define CAL_WR_DMA_CTRL_MODE_RESERVED 5
-#define CAL_WR_DMA_CTRL_PATTERN_MASK GENMASK(4, 3)
-#define CAL_WR_DMA_CTRL_PATTERN_LINEAR 0
-#define CAL_WR_DMA_CTRL_PATTERN_WR2SKIP2 2
-#define CAL_WR_DMA_CTRL_PATTERN_WR2SKIP4 3
-#define CAL_WR_DMA_CTRL_PATTERN_RESERVED 1
-#define CAL_WR_DMA_CTRL_ICM_PSTART_MASK BIT(5)
-#define CAL_WR_DMA_CTRL_DTAG_MASK GENMASK(8, 6)
-#define CAL_WR_DMA_CTRL_DTAG_ATT_HDR 0
-#define CAL_WR_DMA_CTRL_DTAG_ATT_DAT 1
-#define CAL_WR_DMA_CTRL_DTAG 2
-#define CAL_WR_DMA_CTRL_DTAG_PIX_HDR 3
-#define CAL_WR_DMA_CTRL_DTAG_PIX_DAT 4
-#define CAL_WR_DMA_CTRL_DTAG_D5 5
-#define CAL_WR_DMA_CTRL_DTAG_D6 6
-#define CAL_WR_DMA_CTRL_DTAG_D7 7
-#define CAL_WR_DMA_CTRL_CPORT_MASK GENMASK(13, 9)
-#define CAL_WR_DMA_CTRL_STALL_RD_MASK BIT(14)
-#define CAL_WR_DMA_CTRL_YSIZE_MASK GENMASK(31, 18)
-
-#define CAL_WR_DMA_ADDR_MASK GENMASK(31, 4)
-
-#define CAL_WR_DMA_OFST_MASK GENMASK(18, 4)
-#define CAL_WR_DMA_OFST_CIRC_MODE_MASK GENMASK(23, 22)
-#define CAL_WR_DMA_OFST_CIRC_MODE_ONE 1
-#define CAL_WR_DMA_OFST_CIRC_MODE_FOUR 2
-#define CAL_WR_DMA_OFST_CIRC_MODE_SIXTYFOUR 3
-#define CAL_WR_DMA_OFST_CIRC_MODE_DISABLED 0
-#define CAL_WR_DMA_OFST_CIRC_SIZE_MASK GENMASK(31, 24)
-
-#define CAL_WR_DMA_XSIZE_XSKIP_MASK GENMASK(15, 3)
-#define CAL_WR_DMA_XSIZE_MASK GENMASK(31, 19)
-
-#define CAL_CSI2_PPI_CTRL_IF_EN_MASK BIT(0)
-#define CAL_CSI2_PPI_CTRL_ECC_EN_MASK BIT(2)
-#define CAL_CSI2_PPI_CTRL_FRAME_MASK BIT(3)
-#define CAL_CSI2_PPI_CTRL_FRAME_IMMEDIATE 0
-#define CAL_CSI2_PPI_CTRL_FRAME 1
-
-#define CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK GENMASK(2, 0)
-#define CAL_CSI2_COMPLEXIO_CFG_POSITION_5 5
-#define CAL_CSI2_COMPLEXIO_CFG_POSITION_4 4
-#define CAL_CSI2_COMPLEXIO_CFG_POSITION_3 3
-#define CAL_CSI2_COMPLEXIO_CFG_POSITION_2 2
-#define CAL_CSI2_COMPLEXIO_CFG_POSITION_1 1
-#define CAL_CSI2_COMPLEXIO_CFG_POSITION_NOT_USED 0
-#define CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK BIT(3)
-#define CAL_CSI2_COMPLEXIO_CFG_POL_PLUSMINUS 0
-#define CAL_CSI2_COMPLEXIO_CFG_POL_MINUSPLUS 1
-#define CAL_CSI2_COMPLEXIO_CFG_DATA1_POSITION_MASK GENMASK(6, 4)
-#define CAL_CSI2_COMPLEXIO_CFG_DATA1_POL_MASK BIT(7)
-#define CAL_CSI2_COMPLEXIO_CFG_DATA2_POSITION_MASK GENMASK(10, 8)
-#define CAL_CSI2_COMPLEXIO_CFG_DATA2_POL_MASK BIT(11)
-#define CAL_CSI2_COMPLEXIO_CFG_DATA3_POSITION_MASK GENMASK(14, 12)
-#define CAL_CSI2_COMPLEXIO_CFG_DATA3_POL_MASK BIT(15)
-#define CAL_CSI2_COMPLEXIO_CFG_DATA4_POSITION_MASK GENMASK(18, 16)
-#define CAL_CSI2_COMPLEXIO_CFG_DATA4_POL_MASK BIT(19)
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_AUTO_MASK BIT(24)
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK GENMASK(26, 25)
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_OFF 0
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_ON 1
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_ULP 2
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK GENMASK(28, 27)
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF 0
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON 1
-#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ULP 2
-#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK BIT(29)
-#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED 1
-#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETONGOING 0
-#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK BIT(30)
-#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL 0
-#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL 1
-
-#define CAL_CSI2_SHORT_PACKET_MASK GENMASK(23, 0)
-
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS1_MASK BIT(0)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS2_MASK BIT(1)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS3_MASK BIT(2)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS4_MASK BIT(3)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS5_MASK BIT(4)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS1_MASK BIT(5)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS2_MASK BIT(6)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS3_MASK BIT(7)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS4_MASK BIT(8)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS5_MASK BIT(9)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC1_MASK BIT(10)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC2_MASK BIT(11)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC3_MASK BIT(12)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC4_MASK BIT(13)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC5_MASK BIT(14)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL1_MASK BIT(15)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL2_MASK BIT(16)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL3_MASK BIT(17)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL4_MASK BIT(18)
-#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL5_MASK BIT(19)
-#define CAL_CSI2_COMPLEXIO_IRQ_LANE_ERRORS_MASK GENMASK(19, 0)
-#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM1_MASK BIT(20)
-#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM2_MASK BIT(21)
-#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM3_MASK BIT(22)
-#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM4_MASK BIT(23)
-#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM5_MASK BIT(24)
-#define CAL_CSI2_COMPLEXIO_IRQ_STATEALLULPMENTER_MASK BIT(25)
-#define CAL_CSI2_COMPLEXIO_IRQ_STATEALLULPMEXIT_MASK BIT(26)
-#define CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK BIT(27)
-#define CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK BIT(28)
-#define CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK BIT(30)
-
-#define CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK GENMASK(12, 0)
-#define CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK BIT(13)
-#define CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK BIT(14)
-#define CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK BIT(15)
-
-#define CAL_CSI2_VC_IRQ_FS_IRQ_MASK(n) BIT(0 + ((n) * 8))
-#define CAL_CSI2_VC_IRQ_FE_IRQ_MASK(n) BIT(1 + ((n) * 8))
-#define CAL_CSI2_VC_IRQ_LS_IRQ_MASK(n) BIT(2 + ((n) * 8))
-#define CAL_CSI2_VC_IRQ_LE_IRQ_MASK(n) BIT(3 + ((n) * 8))
-#define CAL_CSI2_VC_IRQ_CS_IRQ_MASK(n) BIT(4 + ((n) * 8))
-#define CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(n) BIT(5 + ((n) * 8))
-
-#define CAL_CSI2_CTX_DT_MASK GENMASK(5, 0)
-#define CAL_CSI2_CTX_DT_DISABLED 0
-#define CAL_CSI2_CTX_DT_ANY 1
-#define CAL_CSI2_CTX_VC_MASK GENMASK(7, 6)
-#define CAL_CSI2_CTX_CPORT_MASK GENMASK(12, 8)
-#define CAL_CSI2_CTX_ATT_MASK BIT(13)
-#define CAL_CSI2_CTX_ATT_PIX 0
-#define CAL_CSI2_CTX_ATT 1
-#define CAL_CSI2_CTX_PACK_MODE_MASK BIT(14)
-#define CAL_CSI2_CTX_PACK_MODE_LINE 0
-#define CAL_CSI2_CTX_PACK_MODE_FRAME 1
-#define CAL_CSI2_CTX_LINES_MASK GENMASK(29, 16)
-
-#define CAL_CSI2_STATUS_FRAME_MASK GENMASK(15, 0)
-
-#define CAL_CSI2_PHY_REG0_THS_SETTLE_MASK GENMASK(7, 0)
-#define CAL_CSI2_PHY_REG0_THS_TERM_MASK GENMASK(15, 8)
-#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_MASK BIT(24)
-#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE 1
-#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_ENABLE 0
-
-#define CAL_CSI2_PHY_REG1_TCLK_SETTLE_MASK GENMASK(7, 0)
-#define CAL_CSI2_PHY_REG1_CTRLCLK_DIV_FACTOR_MASK GENMASK(9, 8)
-#define CAL_CSI2_PHY_REG1_DPHY_HS_SYNC_PATTERN_MASK GENMASK(17, 10)
-#define CAL_CSI2_PHY_REG1_TCLK_TERM_MASK GENMASK(24, 18)
-#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_MASK BIT(25)
-#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_ERROR 1
-#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_SUCCESS 0
-#define CAL_CSI2_PHY_REG1_RESET_DONE_STATUS_MASK GENMASK(29, 28)
-
-#define CAL_CSI2_PHY_REG10_I933_LDO_DISABLE_MASK BIT(6)
-
-#define CAL_CSI2_PHY_REG2_CCP2_SYNC_PATTERN_MASK GENMASK(23, 0)
-#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC3_MASK GENMASK(25, 24)
-#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC2_MASK GENMASK(27, 26)
-#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC1_MASK GENMASK(29, 28)
-#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC0_MASK GENMASK(31, 30)
-
-#define CM_CAMERRX_CTRL_CSI1_CTRLCLKEN_MASK BIT(0)
-#define CM_CAMERRX_CTRL_CSI1_CAMMODE_MASK GENMASK(2, 1)
-#define CM_CAMERRX_CTRL_CSI1_LANEENABLE_MASK GENMASK(4, 3)
-#define CM_CAMERRX_CTRL_CSI1_MODE_MASK BIT(5)
-#define CM_CAMERRX_CTRL_CSI0_CTRLCLKEN_MASK BIT(10)
-#define CM_CAMERRX_CTRL_CSI0_CAMMODE_MASK GENMASK(12, 11)
-#define CM_CAMERRX_CTRL_CSI0_LANEENABLE_MASK GENMASK(16, 13)
-#define CM_CAMERRX_CTRL_CSI0_MODE_MASK BIT(17)
-
-#endif
diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c
deleted file mode 100644
index ff15bc589f1b..000000000000
--- a/drivers/media/platform/ti-vpe/csc.c
+++ /dev/null
@@ -1,279 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Color space converter library
- *
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "csc.h"
-
-/*
- * 12 coefficients in the order:
- * a0, b0, c0, a1, b1, c1, a2, b2, c2, d0, d1, d2
- */
-struct quantization {
- u16 coeff[12];
-};
-
-struct colorspace {
- struct quantization limited;
- struct quantization full;
-};
-
-struct encoding_direction {
- struct colorspace r601;
- struct colorspace r709;
-};
-
-struct csc_coeffs {
- struct encoding_direction y2r;
- struct encoding_direction r2y;
-};
-
-/* default colorspace coefficients */
-static struct csc_coeffs csc_coeffs = {
- .y2r = {
- .r601 = {
- .limited = {
- { /* SDTV */
- 0x0400, 0x0000, 0x057D, 0x0400, 0x1EA7, 0x1D35,
- 0x0400, 0x06EF, 0x1FFE, 0x0D40, 0x0210, 0x0C88,
- }
- },
- .full = {
- { /* SDTV */
- 0x04A8, 0x1FFE, 0x0662, 0x04A8, 0x1E6F, 0x1CBF,
- 0x04A8, 0x0812, 0x1FFF, 0x0C84, 0x0220, 0x0BAC,
- }
- },
- },
- .r709 = {
- .limited = {
- { /* HDTV */
- 0x0400, 0x0000, 0x0629, 0x0400, 0x1F45, 0x1E2B,
- 0x0400, 0x0742, 0x0000, 0x0CEC, 0x0148, 0x0C60,
- }
- },
- .full = {
- { /* HDTV */
- 0x04A8, 0x0000, 0x072C, 0x04A8, 0x1F26, 0x1DDE,
- 0x04A8, 0x0873, 0x0000, 0x0C20, 0x0134, 0x0B7C,
- }
- },
- },
- },
- .r2y = {
- .r601 = {
- .limited = {
- { /* SDTV */
- 0x0132, 0x0259, 0x0075, 0x1F50, 0x1EA5, 0x020B,
- 0x020B, 0x1E4A, 0x1FAB, 0x0000, 0x0200, 0x0200,
- }
- },
- .full = {
- { /* SDTV */
- 0x0107, 0x0204, 0x0064, 0x1F68, 0x1ED6, 0x01C2,
- 0x01C2, 0x1E87, 0x1FB7, 0x0040, 0x0200, 0x0200,
- }
- },
- },
- .r709 = {
- .limited = {
- { /* HDTV */
- 0x00DA, 0x02DC, 0x004A, 0x1F88, 0x1E6C, 0x020C,
- 0x020C, 0x1E24, 0x1FD0, 0x0000, 0x0200, 0x0200,
- }
- },
- .full = {
- { /* HDTV */
- 0x00bb, 0x0275, 0x003f, 0x1f99, 0x1ea5, 0x01c2,
- 0x01c2, 0x1e67, 0x1fd7, 0x0040, 0x0200, 0x0200,
- }
- },
- },
- },
-
-};
-
-void csc_dump_regs(struct csc_data *csc)
-{
- struct device *dev = &csc->pdev->dev;
-
-#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \
- ioread32(csc->base + CSC_##r))
-
- dev_dbg(dev, "CSC Registers @ %pa:\n", &csc->res->start);
-
- DUMPREG(CSC00);
- DUMPREG(CSC01);
- DUMPREG(CSC02);
- DUMPREG(CSC03);
- DUMPREG(CSC04);
- DUMPREG(CSC05);
-
-#undef DUMPREG
-}
-EXPORT_SYMBOL(csc_dump_regs);
-
-void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5)
-{
- *csc_reg5 |= CSC_BYPASS;
-}
-EXPORT_SYMBOL(csc_set_coeff_bypass);
-
-/*
- * set the color space converter coefficient shadow register values
- */
-void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
- struct v4l2_format *src_fmt, struct v4l2_format *dst_fmt)
-{
- u32 *csc_reg5 = csc_reg0 + 5;
- u32 *shadow_csc = csc_reg0;
- u16 *coeff, *end_coeff;
- const struct v4l2_pix_format *pix;
- const struct v4l2_pix_format_mplane *mp;
- const struct v4l2_format_info *src_finfo, *dst_finfo;
- enum v4l2_ycbcr_encoding src_ycbcr_enc, dst_ycbcr_enc;
- enum v4l2_quantization src_quantization, dst_quantization;
- u32 src_pixelformat, dst_pixelformat;
-
- if (V4L2_TYPE_IS_MULTIPLANAR(src_fmt->type)) {
- mp = &src_fmt->fmt.pix_mp;
- src_pixelformat = mp->pixelformat;
- src_ycbcr_enc = mp->ycbcr_enc;
- src_quantization = mp->quantization;
- } else {
- pix = &src_fmt->fmt.pix;
- src_pixelformat = pix->pixelformat;
- src_ycbcr_enc = pix->ycbcr_enc;
- src_quantization = pix->quantization;
- }
-
- if (V4L2_TYPE_IS_MULTIPLANAR(dst_fmt->type)) {
- mp = &dst_fmt->fmt.pix_mp;
- dst_pixelformat = mp->pixelformat;
- dst_ycbcr_enc = mp->ycbcr_enc;
- dst_quantization = mp->quantization;
- } else {
- pix = &dst_fmt->fmt.pix;
- dst_pixelformat = pix->pixelformat;
- dst_ycbcr_enc = pix->ycbcr_enc;
- dst_quantization = pix->quantization;
- }
-
- src_finfo = v4l2_format_info(src_pixelformat);
- dst_finfo = v4l2_format_info(dst_pixelformat);
-
- if (v4l2_is_format_yuv(src_finfo) &&
- v4l2_is_format_rgb(dst_finfo)) {
- /* Y2R */
-
- /*
- * These are not the standard default values but are
- * set this way for historical compatibility
- */
- if (src_ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
- src_ycbcr_enc = V4L2_YCBCR_ENC_601;
-
- if (src_quantization == V4L2_QUANTIZATION_DEFAULT)
- src_quantization = V4L2_QUANTIZATION_FULL_RANGE;
-
- if (src_ycbcr_enc == V4L2_YCBCR_ENC_601) {
- if (src_quantization == V4L2_QUANTIZATION_FULL_RANGE)
- coeff = csc_coeffs.y2r.r601.full.coeff;
- else
- coeff = csc_coeffs.y2r.r601.limited.coeff;
- } else if (src_ycbcr_enc == V4L2_YCBCR_ENC_709) {
- if (src_quantization == V4L2_QUANTIZATION_FULL_RANGE)
- coeff = csc_coeffs.y2r.r709.full.coeff;
- else
- coeff = csc_coeffs.y2r.r709.limited.coeff;
- } else {
- /* Should never reach this, but it keeps gcc happy */
- coeff = csc_coeffs.y2r.r601.full.coeff;
- }
- } else if (v4l2_is_format_rgb(src_finfo) &&
- v4l2_is_format_yuv(dst_finfo)) {
- /* R2Y */
-
- /*
- * These are not the standard default values but are
- * set this way for historical compatibility
- */
- if (dst_ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
- dst_ycbcr_enc = V4L2_YCBCR_ENC_601;
-
- if (dst_quantization == V4L2_QUANTIZATION_DEFAULT)
- dst_quantization = V4L2_QUANTIZATION_FULL_RANGE;
-
- if (dst_ycbcr_enc == V4L2_YCBCR_ENC_601) {
- if (dst_quantization == V4L2_QUANTIZATION_FULL_RANGE)
- coeff = csc_coeffs.r2y.r601.full.coeff;
- else
- coeff = csc_coeffs.r2y.r601.limited.coeff;
- } else if (dst_ycbcr_enc == V4L2_YCBCR_ENC_709) {
- if (dst_quantization == V4L2_QUANTIZATION_FULL_RANGE)
- coeff = csc_coeffs.r2y.r709.full.coeff;
- else
- coeff = csc_coeffs.r2y.r709.limited.coeff;
- } else {
- /* Should never reach this, but it keeps gcc happy */
- coeff = csc_coeffs.r2y.r601.full.coeff;
- }
- } else {
- *csc_reg5 |= CSC_BYPASS;
- return;
- }
-
- end_coeff = coeff + 12;
-
- for (; coeff < end_coeff; coeff += 2)
- *shadow_csc++ = (*(coeff + 1) << 16) | *coeff;
-}
-EXPORT_SYMBOL(csc_set_coeff);
-
-struct csc_data *csc_create(struct platform_device *pdev, const char *res_name)
-{
- struct csc_data *csc;
-
- dev_dbg(&pdev->dev, "csc_create\n");
-
- csc = devm_kzalloc(&pdev->dev, sizeof(*csc), GFP_KERNEL);
- if (!csc) {
- dev_err(&pdev->dev, "couldn't alloc csc_data\n");
- return ERR_PTR(-ENOMEM);
- }
-
- csc->pdev = pdev;
-
- csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- res_name);
- if (csc->res == NULL) {
- dev_err(&pdev->dev, "missing '%s' platform resources data\n",
- res_name);
- return ERR_PTR(-ENODEV);
- }
-
- csc->base = devm_ioremap_resource(&pdev->dev, csc->res);
- if (IS_ERR(csc->base))
- return ERR_CAST(csc->base);
-
- return csc;
-}
-EXPORT_SYMBOL(csc_create);
-
-MODULE_DESCRIPTION("TI VIP/VPE Color Space Converter");
-MODULE_AUTHOR("Texas Instruments Inc.");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti-vpe/csc.h b/drivers/media/platform/ti-vpe/csc.h
deleted file mode 100644
index af2e86bccf57..000000000000
--- a/drivers/media/platform/ti-vpe/csc.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-#ifndef TI_CSC_H
-#define TI_CSC_H
-
-/* VPE color space converter regs */
-#define CSC_CSC00 0x00
-#define CSC_A0_MASK 0x1fff
-#define CSC_A0_SHIFT 0
-#define CSC_B0_MASK 0x1fff
-#define CSC_B0_SHIFT 16
-
-#define CSC_CSC01 0x04
-#define CSC_C0_MASK 0x1fff
-#define CSC_C0_SHIFT 0
-#define CSC_A1_MASK 0x1fff
-#define CSC_A1_SHIFT 16
-
-#define CSC_CSC02 0x08
-#define CSC_B1_MASK 0x1fff
-#define CSC_B1_SHIFT 0
-#define CSC_C1_MASK 0x1fff
-#define CSC_C1_SHIFT 16
-
-#define CSC_CSC03 0x0c
-#define CSC_A2_MASK 0x1fff
-#define CSC_A2_SHIFT 0
-#define CSC_B2_MASK 0x1fff
-#define CSC_B2_SHIFT 16
-
-#define CSC_CSC04 0x10
-#define CSC_C2_MASK 0x1fff
-#define CSC_C2_SHIFT 0
-#define CSC_D0_MASK 0x0fff
-#define CSC_D0_SHIFT 16
-
-#define CSC_CSC05 0x14
-#define CSC_D1_MASK 0x0fff
-#define CSC_D1_SHIFT 0
-#define CSC_D2_MASK 0x0fff
-#define CSC_D2_SHIFT 16
-
-#define CSC_BYPASS (1 << 28)
-
-struct csc_data {
- void __iomem *base;
- struct resource *res;
-
- struct platform_device *pdev;
-};
-
-void csc_dump_regs(struct csc_data *csc);
-void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5);
-void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
- struct v4l2_format *src_fmt, struct v4l2_format *dst_fmt);
-
-struct csc_data *csc_create(struct platform_device *pdev, const char *res_name);
-
-#endif
diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti-vpe/sc.c
deleted file mode 100644
index 0202d278523f..000000000000
--- a/drivers/media/platform/ti-vpe/sc.c
+++ /dev/null
@@ -1,306 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Scaler library
- *
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-
-#include
-#include
-#include
-#include
-#include
-
-#include "sc.h"
-#include "sc_coeff.h"
-
-void sc_dump_regs(struct sc_data *sc)
-{
- struct device *dev = &sc->pdev->dev;
-
-#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \
- ioread32(sc->base + CFG_##r))
-
- dev_dbg(dev, "SC Registers @ %pa:\n", &sc->res->start);
-
- DUMPREG(SC0);
- DUMPREG(SC1);
- DUMPREG(SC2);
- DUMPREG(SC3);
- DUMPREG(SC4);
- DUMPREG(SC5);
- DUMPREG(SC6);
- DUMPREG(SC8);
- DUMPREG(SC9);
- DUMPREG(SC10);
- DUMPREG(SC11);
- DUMPREG(SC12);
- DUMPREG(SC13);
- DUMPREG(SC17);
- DUMPREG(SC18);
- DUMPREG(SC19);
- DUMPREG(SC20);
- DUMPREG(SC21);
- DUMPREG(SC22);
- DUMPREG(SC23);
- DUMPREG(SC24);
- DUMPREG(SC25);
-
-#undef DUMPREG
-}
-EXPORT_SYMBOL(sc_dump_regs);
-
-/*
- * set the horizontal scaler coefficients according to the ratio of output to
- * input widths, after accounting for up to two levels of decimation
- */
-void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
- unsigned int dst_w)
-{
- int sixteenths;
- int idx;
- int i, j;
- u16 *coeff_h = addr;
- const u16 *cp;
-
- if (dst_w > src_w) {
- idx = HS_UP_SCALE;
- } else {
- if ((dst_w << 1) < src_w)
- dst_w <<= 1; /* first level decimation */
- if ((dst_w << 1) < src_w)
- dst_w <<= 1; /* second level decimation */
-
- if (dst_w == src_w) {
- idx = HS_LE_16_16_SCALE;
- } else {
- sixteenths = (dst_w << 4) / src_w;
- if (sixteenths < 8)
- sixteenths = 8;
- idx = HS_LT_9_16_SCALE + sixteenths - 8;
- }
- }
-
- cp = scaler_hs_coeffs[idx];
-
- for (i = 0; i < SC_NUM_PHASES * 2; i++) {
- for (j = 0; j < SC_H_NUM_TAPS; j++)
- *coeff_h++ = *cp++;
- /*
- * for each phase, the scaler expects space for 8 coefficients
- * in it's memory. For the horizontal scaler, we copy the first
- * 7 coefficients and skip the last slot to move to the next
- * row to hold coefficients for the next phase
- */
- coeff_h += SC_NUM_TAPS_MEM_ALIGN - SC_H_NUM_TAPS;
- }
-
- sc->load_coeff_h = true;
-}
-EXPORT_SYMBOL(sc_set_hs_coeffs);
-
-/*
- * set the vertical scaler coefficients according to the ratio of output to
- * input heights
- */
-void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
- unsigned int dst_h)
-{
- int sixteenths;
- int idx;
- int i, j;
- u16 *coeff_v = addr;
- const u16 *cp;
-
- if (dst_h > src_h) {
- idx = VS_UP_SCALE;
- } else if (dst_h == src_h) {
- idx = VS_1_TO_1_SCALE;
- } else {
- sixteenths = (dst_h << 4) / src_h;
- if (sixteenths < 8)
- sixteenths = 8;
- idx = VS_LT_9_16_SCALE + sixteenths - 8;
- }
-
- cp = scaler_vs_coeffs[idx];
-
- for (i = 0; i < SC_NUM_PHASES * 2; i++) {
- for (j = 0; j < SC_V_NUM_TAPS; j++)
- *coeff_v++ = *cp++;
- /*
- * for the vertical scaler, we copy the first 5 coefficients and
- * skip the last 3 slots to move to the next row to hold
- * coefficients for the next phase
- */
- coeff_v += SC_NUM_TAPS_MEM_ALIGN - SC_V_NUM_TAPS;
- }
-
- sc->load_coeff_v = true;
-}
-EXPORT_SYMBOL(sc_set_vs_coeffs);
-
-void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
- u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
- unsigned int dst_w, unsigned int dst_h)
-{
- struct device *dev = &sc->pdev->dev;
- u32 val;
- int dcm_x, dcm_shift;
- bool use_rav;
- unsigned long lltmp;
- u32 lin_acc_inc, lin_acc_inc_u;
- u32 col_acc_offset;
- u16 factor = 0;
- int row_acc_init_rav = 0, row_acc_init_rav_b = 0;
- u32 row_acc_inc = 0, row_acc_offset = 0, row_acc_offset_b = 0;
- /*
- * location of SC register in payload memory with respect to the first
- * register in the mmr address data block
- */
- u32 *sc_reg9 = sc_reg8 + 1;
- u32 *sc_reg12 = sc_reg8 + 4;
- u32 *sc_reg13 = sc_reg8 + 5;
- u32 *sc_reg24 = sc_reg17 + 7;
-
- val = sc_reg0[0];
-
- /* clear all the features(they may get enabled elsewhere later) */
- val &= ~(CFG_SELFGEN_FID | CFG_TRIM | CFG_ENABLE_SIN2_VER_INTP |
- CFG_INTERLACE_I | CFG_DCM_4X | CFG_DCM_2X | CFG_AUTO_HS |
- CFG_ENABLE_EV | CFG_USE_RAV | CFG_INVT_FID | CFG_SC_BYPASS |
- CFG_INTERLACE_O | CFG_Y_PK_EN | CFG_HP_BYPASS | CFG_LINEAR);
-
- if (src_w == dst_w && src_h == dst_h) {
- val |= CFG_SC_BYPASS;
- sc_reg0[0] = val;
- return;
- }
-
- /* we only support linear scaling for now */
- val |= CFG_LINEAR;
-
- /* configure horizontal scaler */
-
- /* enable 2X or 4X decimation */
- dcm_x = src_w / dst_w;
- if (dcm_x > 4) {
- val |= CFG_DCM_4X;
- dcm_shift = 2;
- } else if (dcm_x > 2) {
- val |= CFG_DCM_2X;
- dcm_shift = 1;
- } else {
- dcm_shift = 0;
- }
-
- lltmp = dst_w - 1;
- lin_acc_inc = div64_u64(((u64)(src_w >> dcm_shift) - 1) << 24, lltmp);
- lin_acc_inc_u = 0;
- col_acc_offset = 0;
-
- dev_dbg(dev, "hs config: src_w = %d, dst_w = %d, decimation = %s, lin_acc_inc = %08x\n",
- src_w, dst_w, dcm_shift == 2 ? "4x" :
- (dcm_shift == 1 ? "2x" : "none"), lin_acc_inc);
-
- /* configure vertical scaler */
-
- /* use RAV for vertical scaler if vertical downscaling is > 4x */
- if (dst_h < (src_h >> 2)) {
- use_rav = true;
- val |= CFG_USE_RAV;
- } else {
- use_rav = false;
- }
-
- if (use_rav) {
- /* use RAV */
- factor = (u16) ((dst_h << 10) / src_h);
-
- row_acc_init_rav = factor + ((1 + factor) >> 1);
- if (row_acc_init_rav >= 1024)
- row_acc_init_rav -= 1024;
-
- row_acc_init_rav_b = row_acc_init_rav +
- (1 + (row_acc_init_rav >> 1)) -
- (1024 >> 1);
-
- if (row_acc_init_rav_b < 0) {
- row_acc_init_rav_b += row_acc_init_rav;
- row_acc_init_rav *= 2;
- }
-
- dev_dbg(dev, "vs config(RAV): src_h = %d, dst_h = %d, factor = %d, acc_init = %08x, acc_init_b = %08x\n",
- src_h, dst_h, factor, row_acc_init_rav,
- row_acc_init_rav_b);
- } else {
- /* use polyphase */
- row_acc_inc = ((src_h - 1) << 16) / (dst_h - 1);
- row_acc_offset = 0;
- row_acc_offset_b = 0;
-
- dev_dbg(dev, "vs config(POLY): src_h = %d, dst_h = %d,row_acc_inc = %08x\n",
- src_h, dst_h, row_acc_inc);
- }
-
-
- sc_reg0[0] = val;
- sc_reg0[1] = row_acc_inc;
- sc_reg0[2] = row_acc_offset;
- sc_reg0[3] = row_acc_offset_b;
-
- sc_reg0[4] = ((lin_acc_inc_u & CFG_LIN_ACC_INC_U_MASK) <<
- CFG_LIN_ACC_INC_U_SHIFT) | (dst_w << CFG_TAR_W_SHIFT) |
- (dst_h << CFG_TAR_H_SHIFT);
-
- sc_reg0[5] = (src_w << CFG_SRC_W_SHIFT) | (src_h << CFG_SRC_H_SHIFT);
-
- sc_reg0[6] = (row_acc_init_rav_b << CFG_ROW_ACC_INIT_RAV_B_SHIFT) |
- (row_acc_init_rav << CFG_ROW_ACC_INIT_RAV_SHIFT);
-
- *sc_reg9 = lin_acc_inc;
-
- *sc_reg12 = col_acc_offset << CFG_COL_ACC_OFFSET_SHIFT;
-
- *sc_reg13 = factor;
-
- *sc_reg24 = (src_w << CFG_ORG_W_SHIFT) | (src_h << CFG_ORG_H_SHIFT);
-}
-EXPORT_SYMBOL(sc_config_scaler);
-
-struct sc_data *sc_create(struct platform_device *pdev, const char *res_name)
-{
- struct sc_data *sc;
-
- dev_dbg(&pdev->dev, "sc_create\n");
-
- sc = devm_kzalloc(&pdev->dev, sizeof(*sc), GFP_KERNEL);
- if (!sc) {
- dev_err(&pdev->dev, "couldn't alloc sc_data\n");
- return ERR_PTR(-ENOMEM);
- }
-
- sc->pdev = pdev;
-
- sc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
- if (!sc->res) {
- dev_err(&pdev->dev, "missing '%s' platform resources data\n",
- res_name);
- return ERR_PTR(-ENODEV);
- }
-
- sc->base = devm_ioremap_resource(&pdev->dev, sc->res);
- if (IS_ERR(sc->base))
- return ERR_CAST(sc->base);
-
- return sc;
-}
-EXPORT_SYMBOL(sc_create);
-
-MODULE_DESCRIPTION("TI VIP/VPE Scaler");
-MODULE_AUTHOR("Texas Instruments Inc.");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti-vpe/sc.h
deleted file mode 100644
index d55de44d5257..000000000000
--- a/drivers/media/platform/ti-vpe/sc.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-#ifndef TI_SC_H
-#define TI_SC_H
-
-/* Scaler regs */
-#define CFG_SC0 0x0
-#define CFG_INTERLACE_O (1 << 0)
-#define CFG_LINEAR (1 << 1)
-#define CFG_SC_BYPASS (1 << 2)
-#define CFG_INVT_FID (1 << 3)
-#define CFG_USE_RAV (1 << 4)
-#define CFG_ENABLE_EV (1 << 5)
-#define CFG_AUTO_HS (1 << 6)
-#define CFG_DCM_2X (1 << 7)
-#define CFG_DCM_4X (1 << 8)
-#define CFG_HP_BYPASS (1 << 9)
-#define CFG_INTERLACE_I (1 << 10)
-#define CFG_ENABLE_SIN2_VER_INTP (1 << 11)
-#define CFG_Y_PK_EN (1 << 14)
-#define CFG_TRIM (1 << 15)
-#define CFG_SELFGEN_FID (1 << 16)
-
-#define CFG_SC1 0x4
-#define CFG_ROW_ACC_INC_MASK 0x07ffffff
-#define CFG_ROW_ACC_INC_SHIFT 0
-
-#define CFG_SC2 0x08
-#define CFG_ROW_ACC_OFFSET_MASK 0x0fffffff
-#define CFG_ROW_ACC_OFFSET_SHIFT 0
-
-#define CFG_SC3 0x0c
-#define CFG_ROW_ACC_OFFSET_B_MASK 0x0fffffff
-#define CFG_ROW_ACC_OFFSET_B_SHIFT 0
-
-#define CFG_SC4 0x10
-#define CFG_TAR_H_MASK 0x07ff
-#define CFG_TAR_H_SHIFT 0
-#define CFG_TAR_W_MASK 0x07ff
-#define CFG_TAR_W_SHIFT 12
-#define CFG_LIN_ACC_INC_U_MASK 0x07
-#define CFG_LIN_ACC_INC_U_SHIFT 24
-#define CFG_NLIN_ACC_INIT_U_MASK 0x07
-#define CFG_NLIN_ACC_INIT_U_SHIFT 28
-
-#define CFG_SC5 0x14
-#define CFG_SRC_H_MASK 0x07ff
-#define CFG_SRC_H_SHIFT 0
-#define CFG_SRC_W_MASK 0x07ff
-#define CFG_SRC_W_SHIFT 12
-#define CFG_NLIN_ACC_INC_U_MASK 0x07
-#define CFG_NLIN_ACC_INC_U_SHIFT 24
-
-#define CFG_SC6 0x18
-#define CFG_ROW_ACC_INIT_RAV_MASK 0x03ff
-#define CFG_ROW_ACC_INIT_RAV_SHIFT 0
-#define CFG_ROW_ACC_INIT_RAV_B_MASK 0x03ff
-#define CFG_ROW_ACC_INIT_RAV_B_SHIFT 10
-
-#define CFG_SC8 0x20
-#define CFG_NLIN_LEFT_MASK 0x07ff
-#define CFG_NLIN_LEFT_SHIFT 0
-#define CFG_NLIN_RIGHT_MASK 0x07ff
-#define CFG_NLIN_RIGHT_SHIFT 12
-
-#define CFG_SC9 0x24
-#define CFG_LIN_ACC_INC CFG_SC9
-
-#define CFG_SC10 0x28
-#define CFG_NLIN_ACC_INIT CFG_SC10
-
-#define CFG_SC11 0x2c
-#define CFG_NLIN_ACC_INC CFG_SC11
-
-#define CFG_SC12 0x30
-#define CFG_COL_ACC_OFFSET_MASK 0x01ffffff
-#define CFG_COL_ACC_OFFSET_SHIFT 0
-
-#define CFG_SC13 0x34
-#define CFG_SC_FACTOR_RAV_MASK 0xff
-#define CFG_SC_FACTOR_RAV_SHIFT 0
-#define CFG_CHROMA_INTP_THR_MASK 0x03ff
-#define CFG_CHROMA_INTP_THR_SHIFT 12
-#define CFG_DELTA_CHROMA_THR_MASK 0x0f
-#define CFG_DELTA_CHROMA_THR_SHIFT 24
-
-#define CFG_SC17 0x44
-#define CFG_EV_THR_MASK 0x03ff
-#define CFG_EV_THR_SHIFT 12
-#define CFG_DELTA_LUMA_THR_MASK 0x0f
-#define CFG_DELTA_LUMA_THR_SHIFT 24
-#define CFG_DELTA_EV_THR_MASK 0x0f
-#define CFG_DELTA_EV_THR_SHIFT 28
-
-#define CFG_SC18 0x48
-#define CFG_HS_FACTOR_MASK 0x03ff
-#define CFG_HS_FACTOR_SHIFT 0
-#define CFG_CONF_DEFAULT_MASK 0x01ff
-#define CFG_CONF_DEFAULT_SHIFT 16
-
-#define CFG_SC19 0x4c
-#define CFG_HPF_COEFF0_MASK 0xff
-#define CFG_HPF_COEFF0_SHIFT 0
-#define CFG_HPF_COEFF1_MASK 0xff
-#define CFG_HPF_COEFF1_SHIFT 8
-#define CFG_HPF_COEFF2_MASK 0xff
-#define CFG_HPF_COEFF2_SHIFT 16
-#define CFG_HPF_COEFF3_MASK 0xff
-#define CFG_HPF_COEFF3_SHIFT 23
-
-#define CFG_SC20 0x50
-#define CFG_HPF_COEFF4_MASK 0xff
-#define CFG_HPF_COEFF4_SHIFT 0
-#define CFG_HPF_COEFF5_MASK 0xff
-#define CFG_HPF_COEFF5_SHIFT 8
-#define CFG_HPF_NORM_SHIFT_MASK 0x07
-#define CFG_HPF_NORM_SHIFT_SHIFT 16
-#define CFG_NL_LIMIT_MASK 0x1ff
-#define CFG_NL_LIMIT_SHIFT 20
-
-#define CFG_SC21 0x54
-#define CFG_NL_LO_THR_MASK 0x01ff
-#define CFG_NL_LO_THR_SHIFT 0
-#define CFG_NL_LO_SLOPE_MASK 0xff
-#define CFG_NL_LO_SLOPE_SHIFT 16
-
-#define CFG_SC22 0x58
-#define CFG_NL_HI_THR_MASK 0x01ff
-#define CFG_NL_HI_THR_SHIFT 0
-#define CFG_NL_HI_SLOPE_SH_MASK 0x07
-#define CFG_NL_HI_SLOPE_SH_SHIFT 16
-
-#define CFG_SC23 0x5c
-#define CFG_GRADIENT_THR_MASK 0x07ff
-#define CFG_GRADIENT_THR_SHIFT 0
-#define CFG_GRADIENT_THR_RANGE_MASK 0x0f
-#define CFG_GRADIENT_THR_RANGE_SHIFT 12
-#define CFG_MIN_GY_THR_MASK 0xff
-#define CFG_MIN_GY_THR_SHIFT 16
-#define CFG_MIN_GY_THR_RANGE_MASK 0x0f
-#define CFG_MIN_GY_THR_RANGE_SHIFT 28
-
-#define CFG_SC24 0x60
-#define CFG_ORG_H_MASK 0x07ff
-#define CFG_ORG_H_SHIFT 0
-#define CFG_ORG_W_MASK 0x07ff
-#define CFG_ORG_W_SHIFT 16
-
-#define CFG_SC25 0x64
-#define CFG_OFF_H_MASK 0x07ff
-#define CFG_OFF_H_SHIFT 0
-#define CFG_OFF_W_MASK 0x07ff
-#define CFG_OFF_W_SHIFT 16
-
-/* number of phases supported by the polyphase scalers */
-#define SC_NUM_PHASES 32
-
-/* number of taps used by horizontal polyphase scaler */
-#define SC_H_NUM_TAPS 7
-
-/* number of taps used by vertical polyphase scaler */
-#define SC_V_NUM_TAPS 5
-
-/* number of taps expected by the scaler in it's coefficient memory */
-#define SC_NUM_TAPS_MEM_ALIGN 8
-
-/* Maximum frame width the scaler can handle (in pixels) */
-#define SC_MAX_PIXEL_WIDTH 2047
-
-/* Maximum frame height the scaler can handle (in lines) */
-#define SC_MAX_PIXEL_HEIGHT 2047
-
-/*
- * coefficient memory size in bytes:
- * num phases x num sets(luma and chroma) x num taps(aligned) x coeff size
- */
-#define SC_COEF_SRAM_SIZE (SC_NUM_PHASES * 2 * SC_NUM_TAPS_MEM_ALIGN * 2)
-
-struct sc_data {
- void __iomem *base;
- struct resource *res;
-
- dma_addr_t loaded_coeff_h; /* loaded h coeffs in SC */
- dma_addr_t loaded_coeff_v; /* loaded v coeffs in SC */
-
- bool load_coeff_h; /* have new h SC coeffs */
- bool load_coeff_v; /* have new v SC coeffs */
-
- struct platform_device *pdev;
-};
-
-void sc_dump_regs(struct sc_data *sc);
-void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
- unsigned int dst_w);
-void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
- unsigned int dst_h);
-void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
- u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
- unsigned int dst_w, unsigned int dst_h);
-struct sc_data *sc_create(struct platform_device *pdev, const char *res_name);
-
-#endif
diff --git a/drivers/media/platform/ti-vpe/sc_coeff.h b/drivers/media/platform/ti-vpe/sc_coeff.h
deleted file mode 100644
index c525d1764099..000000000000
--- a/drivers/media/platform/ti-vpe/sc_coeff.h
+++ /dev/null
@@ -1,1339 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * VPE SC coefs
- *
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-
-#ifndef __TI_SC_COEFF_H
-#define __TI_SC_COEFF_H
-
-/* horizontal scaler coefficients */
-enum {
- HS_UP_SCALE = 0,
- HS_LT_9_16_SCALE,
- HS_LT_10_16_SCALE,
- HS_LT_11_16_SCALE,
- HS_LT_12_16_SCALE,
- HS_LT_13_16_SCALE,
- HS_LT_14_16_SCALE,
- HS_LT_15_16_SCALE,
- HS_LE_16_16_SCALE,
-};
-
-static const u16 scaler_hs_coeffs[13][SC_NUM_PHASES * 2 * SC_H_NUM_TAPS] = {
- [HS_UP_SCALE] = {
- /* Luma */
- 0x001F, 0x1F90, 0x00D2, 0x06FE, 0x00D2, 0x1F90, 0x001F,
- 0x001C, 0x1F9E, 0x009F, 0x06FB, 0x0108, 0x1F82, 0x0022,
- 0x0019, 0x1FAC, 0x006F, 0x06F3, 0x0140, 0x1F74, 0x0025,
- 0x0016, 0x1FB9, 0x0041, 0x06E7, 0x017B, 0x1F66, 0x0028,
- 0x0013, 0x1FC6, 0x0017, 0x06D6, 0x01B7, 0x1F58, 0x002B,
- 0x0010, 0x1FD3, 0x1FEF, 0x06C0, 0x01F6, 0x1F4B, 0x002D,
- 0x000E, 0x1FDF, 0x1FCB, 0x06A5, 0x0235, 0x1F3F, 0x002F,
- 0x000B, 0x1FEA, 0x1FAA, 0x0686, 0x0277, 0x1F33, 0x0031,
- 0x0009, 0x1FF5, 0x1F8C, 0x0663, 0x02B8, 0x1F28, 0x0033,
- 0x0007, 0x1FFF, 0x1F72, 0x063A, 0x02FB, 0x1F1F, 0x0034,
- 0x0005, 0x0008, 0x1F5A, 0x060F, 0x033E, 0x1F17, 0x0035,
- 0x0003, 0x0010, 0x1F46, 0x05E0, 0x0382, 0x1F10, 0x0035,
- 0x0002, 0x0017, 0x1F34, 0x05AF, 0x03C5, 0x1F0B, 0x0034,
- 0x0001, 0x001E, 0x1F26, 0x0579, 0x0407, 0x1F08, 0x0033,
- 0x0000, 0x0023, 0x1F1A, 0x0541, 0x0449, 0x1F07, 0x0032,
- 0x1FFF, 0x0028, 0x1F12, 0x0506, 0x048A, 0x1F08, 0x002F,
- 0x002C, 0x1F0C, 0x04C8, 0x04C8, 0x1F0C, 0x002C, 0x0000,
- 0x002F, 0x1F08, 0x048A, 0x0506, 0x1F12, 0x0028, 0x1FFF,
- 0x0032, 0x1F07, 0x0449, 0x0541, 0x1F1A, 0x0023, 0x0000,
- 0x0033, 0x1F08, 0x0407, 0x0579, 0x1F26, 0x001E, 0x0001,
- 0x0034, 0x1F0B, 0x03C5, 0x05AF, 0x1F34, 0x0017, 0x0002,
- 0x0035, 0x1F10, 0x0382, 0x05E0, 0x1F46, 0x0010, 0x0003,
- 0x0035, 0x1F17, 0x033E, 0x060F, 0x1F5A, 0x0008, 0x0005,
- 0x0034, 0x1F1F, 0x02FB, 0x063A, 0x1F72, 0x1FFF, 0x0007,
- 0x0033, 0x1F28, 0x02B8, 0x0663, 0x1F8C, 0x1FF5, 0x0009,
- 0x0031, 0x1F33, 0x0277, 0x0686, 0x1FAA, 0x1FEA, 0x000B,
- 0x002F, 0x1F3F, 0x0235, 0x06A5, 0x1FCB, 0x1FDF, 0x000E,
- 0x002D, 0x1F4B, 0x01F6, 0x06C0, 0x1FEF, 0x1FD3, 0x0010,
- 0x002B, 0x1F58, 0x01B7, 0x06D6, 0x0017, 0x1FC6, 0x0013,
- 0x0028, 0x1F66, 0x017B, 0x06E7, 0x0041, 0x1FB9, 0x0016,
- 0x0025, 0x1F74, 0x0140, 0x06F3, 0x006F, 0x1FAC, 0x0019,
- 0x0022, 0x1F82, 0x0108, 0x06FB, 0x009F, 0x1F9E, 0x001C,
- /* Chroma */
- 0x001F, 0x1F90, 0x00D2, 0x06FE, 0x00D2, 0x1F90, 0x001F,
- 0x001C, 0x1F9E, 0x009F, 0x06FB, 0x0108, 0x1F82, 0x0022,
- 0x0019, 0x1FAC, 0x006F, 0x06F3, 0x0140, 0x1F74, 0x0025,
- 0x0016, 0x1FB9, 0x0041, 0x06E7, 0x017B, 0x1F66, 0x0028,
- 0x0013, 0x1FC6, 0x0017, 0x06D6, 0x01B7, 0x1F58, 0x002B,
- 0x0010, 0x1FD3, 0x1FEF, 0x06C0, 0x01F6, 0x1F4B, 0x002D,
- 0x000E, 0x1FDF, 0x1FCB, 0x06A5, 0x0235, 0x1F3F, 0x002F,
- 0x000B, 0x1FEA, 0x1FAA, 0x0686, 0x0277, 0x1F33, 0x0031,
- 0x0009, 0x1FF5, 0x1F8C, 0x0663, 0x02B8, 0x1F28, 0x0033,
- 0x0007, 0x1FFF, 0x1F72, 0x063A, 0x02FB, 0x1F1F, 0x0034,
- 0x0005, 0x0008, 0x1F5A, 0x060F, 0x033E, 0x1F17, 0x0035,
- 0x0003, 0x0010, 0x1F46, 0x05E0, 0x0382, 0x1F10, 0x0035,
- 0x0002, 0x0017, 0x1F34, 0x05AF, 0x03C5, 0x1F0B, 0x0034,
- 0x0001, 0x001E, 0x1F26, 0x0579, 0x0407, 0x1F08, 0x0033,
- 0x0000, 0x0023, 0x1F1A, 0x0541, 0x0449, 0x1F07, 0x0032,
- 0x1FFF, 0x0028, 0x1F12, 0x0506, 0x048A, 0x1F08, 0x002F,
- 0x002C, 0x1F0C, 0x04C8, 0x04C8, 0x1F0C, 0x002C, 0x0000,
- 0x002F, 0x1F08, 0x048A, 0x0506, 0x1F12, 0x0028, 0x1FFF,
- 0x0032, 0x1F07, 0x0449, 0x0541, 0x1F1A, 0x0023, 0x0000,
- 0x0033, 0x1F08, 0x0407, 0x0579, 0x1F26, 0x001E, 0x0001,
- 0x0034, 0x1F0B, 0x03C5, 0x05AF, 0x1F34, 0x0017, 0x0002,
- 0x0035, 0x1F10, 0x0382, 0x05E0, 0x1F46, 0x0010, 0x0003,
- 0x0035, 0x1F17, 0x033E, 0x060F, 0x1F5A, 0x0008, 0x0005,
- 0x0034, 0x1F1F, 0x02FB, 0x063A, 0x1F72, 0x1FFF, 0x0007,
- 0x0033, 0x1F28, 0x02B8, 0x0663, 0x1F8C, 0x1FF5, 0x0009,
- 0x0031, 0x1F33, 0x0277, 0x0686, 0x1FAA, 0x1FEA, 0x000B,
- 0x002F, 0x1F3F, 0x0235, 0x06A5, 0x1FCB, 0x1FDF, 0x000E,
- 0x002D, 0x1F4B, 0x01F6, 0x06C0, 0x1FEF, 0x1FD3, 0x0010,
- 0x002B, 0x1F58, 0x01B7, 0x06D6, 0x0017, 0x1FC6, 0x0013,
- 0x0028, 0x1F66, 0x017B, 0x06E7, 0x0041, 0x1FB9, 0x0016,
- 0x0025, 0x1F74, 0x0140, 0x06F3, 0x006F, 0x1FAC, 0x0019,
- 0x0022, 0x1F82, 0x0108, 0x06FB, 0x009F, 0x1F9E, 0x001C,
- },
- [HS_LT_9_16_SCALE] = {
- /* Luma */
- 0x1FA3, 0x005E, 0x024A, 0x036A, 0x024A, 0x005E, 0x1FA3,
- 0x1FA3, 0x0052, 0x023A, 0x036A, 0x0259, 0x006A, 0x1FA4,
- 0x1FA3, 0x0046, 0x022A, 0x036A, 0x0269, 0x0076, 0x1FA4,
- 0x1FA3, 0x003B, 0x021A, 0x0368, 0x0278, 0x0083, 0x1FA5,
- 0x1FA4, 0x0031, 0x020A, 0x0365, 0x0286, 0x0090, 0x1FA6,
- 0x1FA5, 0x0026, 0x01F9, 0x0362, 0x0294, 0x009E, 0x1FA8,
- 0x1FA6, 0x001C, 0x01E8, 0x035E, 0x02A3, 0x00AB, 0x1FAA,
- 0x1FA7, 0x0013, 0x01D7, 0x035A, 0x02B0, 0x00B9, 0x1FAC,
- 0x1FA9, 0x000A, 0x01C6, 0x0354, 0x02BD, 0x00C7, 0x1FAF,
- 0x1FAA, 0x0001, 0x01B6, 0x034E, 0x02C9, 0x00D6, 0x1FB2,
- 0x1FAC, 0x1FF9, 0x01A5, 0x0347, 0x02D5, 0x00E5, 0x1FB5,
- 0x1FAE, 0x1FF1, 0x0194, 0x0340, 0x02E1, 0x00F3, 0x1FB9,
- 0x1FB0, 0x1FEA, 0x0183, 0x0338, 0x02EC, 0x0102, 0x1FBD,
- 0x1FB2, 0x1FE3, 0x0172, 0x0330, 0x02F6, 0x0112, 0x1FC1,
- 0x1FB4, 0x1FDC, 0x0161, 0x0327, 0x0301, 0x0121, 0x1FC6,
- 0x1FB7, 0x1FD6, 0x0151, 0x031D, 0x030A, 0x0130, 0x1FCB,
- 0x1FD2, 0x0136, 0x02F8, 0x02F8, 0x0136, 0x1FD2, 0x0000,
- 0x1FCB, 0x0130, 0x030A, 0x031D, 0x0151, 0x1FD6, 0x1FB7,
- 0x1FC6, 0x0121, 0x0301, 0x0327, 0x0161, 0x1FDC, 0x1FB4,
- 0x1FC1, 0x0112, 0x02F6, 0x0330, 0x0172, 0x1FE3, 0x1FB2,
- 0x1FBD, 0x0102, 0x02EC, 0x0338, 0x0183, 0x1FEA, 0x1FB0,
- 0x1FB9, 0x00F3, 0x02E1, 0x0340, 0x0194, 0x1FF1, 0x1FAE,
- 0x1FB5, 0x00E5, 0x02D5, 0x0347, 0x01A5, 0x1FF9, 0x1FAC,
- 0x1FB2, 0x00D6, 0x02C9, 0x034E, 0x01B6, 0x0001, 0x1FAA,
- 0x1FAF, 0x00C7, 0x02BD, 0x0354, 0x01C6, 0x000A, 0x1FA9,
- 0x1FAC, 0x00B9, 0x02B0, 0x035A, 0x01D7, 0x0013, 0x1FA7,
- 0x1FAA, 0x00AB, 0x02A3, 0x035E, 0x01E8, 0x001C, 0x1FA6,
- 0x1FA8, 0x009E, 0x0294, 0x0362, 0x01F9, 0x0026, 0x1FA5,
- 0x1FA6, 0x0090, 0x0286, 0x0365, 0x020A, 0x0031, 0x1FA4,
- 0x1FA5, 0x0083, 0x0278, 0x0368, 0x021A, 0x003B, 0x1FA3,
- 0x1FA4, 0x0076, 0x0269, 0x036A, 0x022A, 0x0046, 0x1FA3,
- 0x1FA4, 0x006A, 0x0259, 0x036A, 0x023A, 0x0052, 0x1FA3,
- /* Chroma */
- 0x1FA3, 0x005E, 0x024A, 0x036A, 0x024A, 0x005E, 0x1FA3,
- 0x1FA3, 0x0052, 0x023A, 0x036A, 0x0259, 0x006A, 0x1FA4,
- 0x1FA3, 0x0046, 0x022A, 0x036A, 0x0269, 0x0076, 0x1FA4,
- 0x1FA3, 0x003B, 0x021A, 0x0368, 0x0278, 0x0083, 0x1FA5,
- 0x1FA4, 0x0031, 0x020A, 0x0365, 0x0286, 0x0090, 0x1FA6,
- 0x1FA5, 0x0026, 0x01F9, 0x0362, 0x0294, 0x009E, 0x1FA8,
- 0x1FA6, 0x001C, 0x01E8, 0x035E, 0x02A3, 0x00AB, 0x1FAA,
- 0x1FA7, 0x0013, 0x01D7, 0x035A, 0x02B0, 0x00B9, 0x1FAC,
- 0x1FA9, 0x000A, 0x01C6, 0x0354, 0x02BD, 0x00C7, 0x1FAF,
- 0x1FAA, 0x0001, 0x01B6, 0x034E, 0x02C9, 0x00D6, 0x1FB2,
- 0x1FAC, 0x1FF9, 0x01A5, 0x0347, 0x02D5, 0x00E5, 0x1FB5,
- 0x1FAE, 0x1FF1, 0x0194, 0x0340, 0x02E1, 0x00F3, 0x1FB9,
- 0x1FB0, 0x1FEA, 0x0183, 0x0338, 0x02EC, 0x0102, 0x1FBD,
- 0x1FB2, 0x1FE3, 0x0172, 0x0330, 0x02F6, 0x0112, 0x1FC1,
- 0x1FB4, 0x1FDC, 0x0161, 0x0327, 0x0301, 0x0121, 0x1FC6,
- 0x1FB7, 0x1FD6, 0x0151, 0x031D, 0x030A, 0x0130, 0x1FCB,
- 0x1FD2, 0x0136, 0x02F8, 0x02F8, 0x0136, 0x1FD2, 0x0000,
- 0x1FCB, 0x0130, 0x030A, 0x031D, 0x0151, 0x1FD6, 0x1FB7,
- 0x1FC6, 0x0121, 0x0301, 0x0327, 0x0161, 0x1FDC, 0x1FB4,
- 0x1FC1, 0x0112, 0x02F6, 0x0330, 0x0172, 0x1FE3, 0x1FB2,
- 0x1FBD, 0x0102, 0x02EC, 0x0338, 0x0183, 0x1FEA, 0x1FB0,
- 0x1FB9, 0x00F3, 0x02E1, 0x0340, 0x0194, 0x1FF1, 0x1FAE,
- 0x1FB5, 0x00E5, 0x02D5, 0x0347, 0x01A5, 0x1FF9, 0x1FAC,
- 0x1FB2, 0x00D6, 0x02C9, 0x034E, 0x01B6, 0x0001, 0x1FAA,
- 0x1FAF, 0x00C7, 0x02BD, 0x0354, 0x01C6, 0x000A, 0x1FA9,
- 0x1FAC, 0x00B9, 0x02B0, 0x035A, 0x01D7, 0x0013, 0x1FA7,
- 0x1FAA, 0x00AB, 0x02A3, 0x035E, 0x01E8, 0x001C, 0x1FA6,
- 0x1FA8, 0x009E, 0x0294, 0x0362, 0x01F9, 0x0026, 0x1FA5,
- 0x1FA6, 0x0090, 0x0286, 0x0365, 0x020A, 0x0031, 0x1FA4,
- 0x1FA5, 0x0083, 0x0278, 0x0368, 0x021A, 0x003B, 0x1FA3,
- 0x1FA4, 0x0076, 0x0269, 0x036A, 0x022A, 0x0046, 0x1FA3,
- 0x1FA4, 0x006A, 0x0259, 0x036A, 0x023A, 0x0052, 0x1FA3,
- },
- [HS_LT_10_16_SCALE] = {
- /* Luma */
- 0x1F8D, 0x000C, 0x026A, 0x03FA, 0x026A, 0x000C, 0x1F8D,
- 0x1F8F, 0x0000, 0x0255, 0x03FA, 0x027F, 0x0019, 0x1F8A,
- 0x1F92, 0x1FF5, 0x023F, 0x03F8, 0x0293, 0x0027, 0x1F88,
- 0x1F95, 0x1FEA, 0x022A, 0x03F6, 0x02A7, 0x0034, 0x1F86,
- 0x1F99, 0x1FDF, 0x0213, 0x03F2, 0x02BB, 0x0043, 0x1F85,
- 0x1F9C, 0x1FD5, 0x01FE, 0x03ED, 0x02CF, 0x0052, 0x1F83,
- 0x1FA0, 0x1FCC, 0x01E8, 0x03E7, 0x02E1, 0x0061, 0x1F83,
- 0x1FA4, 0x1FC3, 0x01D2, 0x03E0, 0x02F4, 0x0071, 0x1F82,
- 0x1FA7, 0x1FBB, 0x01BC, 0x03D9, 0x0306, 0x0081, 0x1F82,
- 0x1FAB, 0x1FB4, 0x01A6, 0x03D0, 0x0317, 0x0092, 0x1F82,
- 0x1FAF, 0x1FAD, 0x0190, 0x03C7, 0x0327, 0x00A3, 0x1F83,
- 0x1FB3, 0x1FA7, 0x017A, 0x03BC, 0x0337, 0x00B5, 0x1F84,
- 0x1FB8, 0x1FA1, 0x0165, 0x03B0, 0x0346, 0x00C7, 0x1F85,
- 0x1FBC, 0x1F9C, 0x0150, 0x03A4, 0x0354, 0x00D9, 0x1F87,
- 0x1FC0, 0x1F98, 0x013A, 0x0397, 0x0361, 0x00EC, 0x1F8A,
- 0x1FC4, 0x1F93, 0x0126, 0x0389, 0x036F, 0x00FE, 0x1F8D,
- 0x1F93, 0x010A, 0x0363, 0x0363, 0x010A, 0x1F93, 0x0000,
- 0x1F8D, 0x00FE, 0x036F, 0x0389, 0x0126, 0x1F93, 0x1FC4,
- 0x1F8A, 0x00EC, 0x0361, 0x0397, 0x013A, 0x1F98, 0x1FC0,
- 0x1F87, 0x00D9, 0x0354, 0x03A4, 0x0150, 0x1F9C, 0x1FBC,
- 0x1F85, 0x00C7, 0x0346, 0x03B0, 0x0165, 0x1FA1, 0x1FB8,
- 0x1F84, 0x00B5, 0x0337, 0x03BC, 0x017A, 0x1FA7, 0x1FB3,
- 0x1F83, 0x00A3, 0x0327, 0x03C7, 0x0190, 0x1FAD, 0x1FAF,
- 0x1F82, 0x0092, 0x0317, 0x03D0, 0x01A6, 0x1FB4, 0x1FAB,
- 0x1F82, 0x0081, 0x0306, 0x03D9, 0x01BC, 0x1FBB, 0x1FA7,
- 0x1F82, 0x0071, 0x02F4, 0x03E0, 0x01D2, 0x1FC3, 0x1FA4,
- 0x1F83, 0x0061, 0x02E1, 0x03E7, 0x01E8, 0x1FCC, 0x1FA0,
- 0x1F83, 0x0052, 0x02CF, 0x03ED, 0x01FE, 0x1FD5, 0x1F9C,
- 0x1F85, 0x0043, 0x02BB, 0x03F2, 0x0213, 0x1FDF, 0x1F99,
- 0x1F86, 0x0034, 0x02A7, 0x03F6, 0x022A, 0x1FEA, 0x1F95,
- 0x1F88, 0x0027, 0x0293, 0x03F8, 0x023F, 0x1FF5, 0x1F92,
- 0x1F8A, 0x0019, 0x027F, 0x03FA, 0x0255, 0x0000, 0x1F8F,
- /* Chroma */
- 0x1F8D, 0x000C, 0x026A, 0x03FA, 0x026A, 0x000C, 0x1F8D,
- 0x1F8F, 0x0000, 0x0255, 0x03FA, 0x027F, 0x0019, 0x1F8A,
- 0x1F92, 0x1FF5, 0x023F, 0x03F8, 0x0293, 0x0027, 0x1F88,
- 0x1F95, 0x1FEA, 0x022A, 0x03F6, 0x02A7, 0x0034, 0x1F86,
- 0x1F99, 0x1FDF, 0x0213, 0x03F2, 0x02BB, 0x0043, 0x1F85,
- 0x1F9C, 0x1FD5, 0x01FE, 0x03ED, 0x02CF, 0x0052, 0x1F83,
- 0x1FA0, 0x1FCC, 0x01E8, 0x03E7, 0x02E1, 0x0061, 0x1F83,
- 0x1FA4, 0x1FC3, 0x01D2, 0x03E0, 0x02F4, 0x0071, 0x1F82,
- 0x1FA7, 0x1FBB, 0x01BC, 0x03D9, 0x0306, 0x0081, 0x1F82,
- 0x1FAB, 0x1FB4, 0x01A6, 0x03D0, 0x0317, 0x0092, 0x1F82,
- 0x1FAF, 0x1FAD, 0x0190, 0x03C7, 0x0327, 0x00A3, 0x1F83,
- 0x1FB3, 0x1FA7, 0x017A, 0x03BC, 0x0337, 0x00B5, 0x1F84,
- 0x1FB8, 0x1FA1, 0x0165, 0x03B0, 0x0346, 0x00C7, 0x1F85,
- 0x1FBC, 0x1F9C, 0x0150, 0x03A4, 0x0354, 0x00D9, 0x1F87,
- 0x1FC0, 0x1F98, 0x013A, 0x0397, 0x0361, 0x00EC, 0x1F8A,
- 0x1FC4, 0x1F93, 0x0126, 0x0389, 0x036F, 0x00FE, 0x1F8D,
- 0x1F93, 0x010A, 0x0363, 0x0363, 0x010A, 0x1F93, 0x0000,
- 0x1F8D, 0x00FE, 0x036F, 0x0389, 0x0126, 0x1F93, 0x1FC4,
- 0x1F8A, 0x00EC, 0x0361, 0x0397, 0x013A, 0x1F98, 0x1FC0,
- 0x1F87, 0x00D9, 0x0354, 0x03A4, 0x0150, 0x1F9C, 0x1FBC,
- 0x1F85, 0x00C7, 0x0346, 0x03B0, 0x0165, 0x1FA1, 0x1FB8,
- 0x1F84, 0x00B5, 0x0337, 0x03BC, 0x017A, 0x1FA7, 0x1FB3,
- 0x1F83, 0x00A3, 0x0327, 0x03C7, 0x0190, 0x1FAD, 0x1FAF,
- 0x1F82, 0x0092, 0x0317, 0x03D0, 0x01A6, 0x1FB4, 0x1FAB,
- 0x1F82, 0x0081, 0x0306, 0x03D9, 0x01BC, 0x1FBB, 0x1FA7,
- 0x1F82, 0x0071, 0x02F4, 0x03E0, 0x01D2, 0x1FC3, 0x1FA4,
- 0x1F83, 0x0061, 0x02E1, 0x03E7, 0x01E8, 0x1FCC, 0x1FA0,
- 0x1F83, 0x0052, 0x02CF, 0x03ED, 0x01FE, 0x1FD5, 0x1F9C,
- 0x1F85, 0x0043, 0x02BB, 0x03F2, 0x0213, 0x1FDF, 0x1F99,
- 0x1F86, 0x0034, 0x02A7, 0x03F6, 0x022A, 0x1FEA, 0x1F95,
- 0x1F88, 0x0027, 0x0293, 0x03F8, 0x023F, 0x1FF5, 0x1F92,
- 0x1F8A, 0x0019, 0x027F, 0x03FA, 0x0255, 0x0000, 0x1F8F,
- },
- [HS_LT_11_16_SCALE] = {
- /* Luma */
- 0x1F95, 0x1FB5, 0x0272, 0x0488, 0x0272, 0x1FB5, 0x1F95,
- 0x1F9B, 0x1FAA, 0x0257, 0x0486, 0x028D, 0x1FC1, 0x1F90,
- 0x1FA0, 0x1FA0, 0x023C, 0x0485, 0x02A8, 0x1FCD, 0x1F8A,
- 0x1FA6, 0x1F96, 0x0221, 0x0481, 0x02C2, 0x1FDB, 0x1F85,
- 0x1FAC, 0x1F8E, 0x0205, 0x047C, 0x02DC, 0x1FE9, 0x1F80,
- 0x1FB1, 0x1F86, 0x01E9, 0x0476, 0x02F6, 0x1FF8, 0x1F7C,
- 0x1FB7, 0x1F7F, 0x01CE, 0x046E, 0x030F, 0x0008, 0x1F77,
- 0x1FBD, 0x1F79, 0x01B3, 0x0465, 0x0326, 0x0019, 0x1F73,
- 0x1FC3, 0x1F73, 0x0197, 0x045B, 0x033E, 0x002A, 0x1F70,
- 0x1FC8, 0x1F6F, 0x017D, 0x044E, 0x0355, 0x003C, 0x1F6D,
- 0x1FCE, 0x1F6B, 0x0162, 0x0441, 0x036B, 0x004F, 0x1F6A,
- 0x1FD3, 0x1F68, 0x0148, 0x0433, 0x0380, 0x0063, 0x1F67,
- 0x1FD8, 0x1F65, 0x012E, 0x0424, 0x0395, 0x0077, 0x1F65,
- 0x1FDE, 0x1F63, 0x0115, 0x0413, 0x03A8, 0x008B, 0x1F64,
- 0x1FE3, 0x1F62, 0x00FC, 0x0403, 0x03BA, 0x00A0, 0x1F62,
- 0x1FE7, 0x1F62, 0x00E4, 0x03EF, 0x03CC, 0x00B6, 0x1F62,
- 0x1F63, 0x00CA, 0x03D3, 0x03D3, 0x00CA, 0x1F63, 0x0000,
- 0x1F62, 0x00B6, 0x03CC, 0x03EF, 0x00E4, 0x1F62, 0x1FE7,
- 0x1F62, 0x00A0, 0x03BA, 0x0403, 0x00FC, 0x1F62, 0x1FE3,
- 0x1F64, 0x008B, 0x03A8, 0x0413, 0x0115, 0x1F63, 0x1FDE,
- 0x1F65, 0x0077, 0x0395, 0x0424, 0x012E, 0x1F65, 0x1FD8,
- 0x1F67, 0x0063, 0x0380, 0x0433, 0x0148, 0x1F68, 0x1FD3,
- 0x1F6A, 0x004F, 0x036B, 0x0441, 0x0162, 0x1F6B, 0x1FCE,
- 0x1F6D, 0x003C, 0x0355, 0x044E, 0x017D, 0x1F6F, 0x1FC8,
- 0x1F70, 0x002A, 0x033E, 0x045B, 0x0197, 0x1F73, 0x1FC3,
- 0x1F73, 0x0019, 0x0326, 0x0465, 0x01B3, 0x1F79, 0x1FBD,
- 0x1F77, 0x0008, 0x030F, 0x046E, 0x01CE, 0x1F7F, 0x1FB7,
- 0x1F7C, 0x1FF8, 0x02F6, 0x0476, 0x01E9, 0x1F86, 0x1FB1,
- 0x1F80, 0x1FE9, 0x02DC, 0x047C, 0x0205, 0x1F8E, 0x1FAC,
- 0x1F85, 0x1FDB, 0x02C2, 0x0481, 0x0221, 0x1F96, 0x1FA6,
- 0x1F8A, 0x1FCD, 0x02A8, 0x0485, 0x023C, 0x1FA0, 0x1FA0,
- 0x1F90, 0x1FC1, 0x028D, 0x0486, 0x0257, 0x1FAA, 0x1F9B,
- /* Chroma */
- 0x1F95, 0x1FB5, 0x0272, 0x0488, 0x0272, 0x1FB5, 0x1F95,
- 0x1F9B, 0x1FAA, 0x0257, 0x0486, 0x028D, 0x1FC1, 0x1F90,
- 0x1FA0, 0x1FA0, 0x023C, 0x0485, 0x02A8, 0x1FCD, 0x1F8A,
- 0x1FA6, 0x1F96, 0x0221, 0x0481, 0x02C2, 0x1FDB, 0x1F85,
- 0x1FAC, 0x1F8E, 0x0205, 0x047C, 0x02DC, 0x1FE9, 0x1F80,
- 0x1FB1, 0x1F86, 0x01E9, 0x0476, 0x02F6, 0x1FF8, 0x1F7C,
- 0x1FB7, 0x1F7F, 0x01CE, 0x046E, 0x030F, 0x0008, 0x1F77,
- 0x1FBD, 0x1F79, 0x01B3, 0x0465, 0x0326, 0x0019, 0x1F73,
- 0x1FC3, 0x1F73, 0x0197, 0x045B, 0x033E, 0x002A, 0x1F70,
- 0x1FC8, 0x1F6F, 0x017D, 0x044E, 0x0355, 0x003C, 0x1F6D,
- 0x1FCE, 0x1F6B, 0x0162, 0x0441, 0x036B, 0x004F, 0x1F6A,
- 0x1FD3, 0x1F68, 0x0148, 0x0433, 0x0380, 0x0063, 0x1F67,
- 0x1FD8, 0x1F65, 0x012E, 0x0424, 0x0395, 0x0077, 0x1F65,
- 0x1FDE, 0x1F63, 0x0115, 0x0413, 0x03A8, 0x008B, 0x1F64,
- 0x1FE3, 0x1F62, 0x00FC, 0x0403, 0x03BA, 0x00A0, 0x1F62,
- 0x1FE7, 0x1F62, 0x00E4, 0x03EF, 0x03CC, 0x00B6, 0x1F62,
- 0x1F63, 0x00CA, 0x03D3, 0x03D3, 0x00CA, 0x1F63, 0x0000,
- 0x1F62, 0x00B6, 0x03CC, 0x03EF, 0x00E4, 0x1F62, 0x1FE7,
- 0x1F62, 0x00A0, 0x03BA, 0x0403, 0x00FC, 0x1F62, 0x1FE3,
- 0x1F64, 0x008B, 0x03A8, 0x0413, 0x0115, 0x1F63, 0x1FDE,
- 0x1F65, 0x0077, 0x0395, 0x0424, 0x012E, 0x1F65, 0x1FD8,
- 0x1F67, 0x0063, 0x0380, 0x0433, 0x0148, 0x1F68, 0x1FD3,
- 0x1F6A, 0x004F, 0x036B, 0x0441, 0x0162, 0x1F6B, 0x1FCE,
- 0x1F6D, 0x003C, 0x0355, 0x044E, 0x017D, 0x1F6F, 0x1FC8,
- 0x1F70, 0x002A, 0x033E, 0x045B, 0x0197, 0x1F73, 0x1FC3,
- 0x1F73, 0x0019, 0x0326, 0x0465, 0x01B3, 0x1F79, 0x1FBD,
- 0x1F77, 0x0008, 0x030F, 0x046E, 0x01CE, 0x1F7F, 0x1FB7,
- 0x1F7C, 0x1FF8, 0x02F6, 0x0476, 0x01E9, 0x1F86, 0x1FB1,
- 0x1F80, 0x1FE9, 0x02DC, 0x047C, 0x0205, 0x1F8E, 0x1FAC,
- 0x1F85, 0x1FDB, 0x02C2, 0x0481, 0x0221, 0x1F96, 0x1FA6,
- 0x1F8A, 0x1FCD, 0x02A8, 0x0485, 0x023C, 0x1FA0, 0x1FA0,
- 0x1F90, 0x1FC1, 0x028D, 0x0486, 0x0257, 0x1FAA, 0x1F9B,
- },
- [HS_LT_12_16_SCALE] = {
- /* Luma */
- 0x1FBB, 0x1F65, 0x025E, 0x0504, 0x025E, 0x1F65, 0x1FBB,
- 0x1FC3, 0x1F5D, 0x023C, 0x0503, 0x027F, 0x1F6E, 0x1FB4,
- 0x1FCA, 0x1F56, 0x021B, 0x0501, 0x02A0, 0x1F78, 0x1FAC,
- 0x1FD1, 0x1F50, 0x01FA, 0x04FD, 0x02C0, 0x1F83, 0x1FA5,
- 0x1FD8, 0x1F4B, 0x01D9, 0x04F6, 0x02E1, 0x1F90, 0x1F9D,
- 0x1FDF, 0x1F47, 0x01B8, 0x04EF, 0x0301, 0x1F9D, 0x1F95,
- 0x1FE6, 0x1F43, 0x0198, 0x04E5, 0x0321, 0x1FAB, 0x1F8E,
- 0x1FEC, 0x1F41, 0x0178, 0x04DA, 0x0340, 0x1FBB, 0x1F86,
- 0x1FF2, 0x1F40, 0x0159, 0x04CC, 0x035E, 0x1FCC, 0x1F7F,
- 0x1FF8, 0x1F40, 0x013A, 0x04BE, 0x037B, 0x1FDD, 0x1F78,
- 0x1FFE, 0x1F40, 0x011B, 0x04AD, 0x0398, 0x1FF0, 0x1F72,
- 0x0003, 0x1F41, 0x00FD, 0x049C, 0x03B4, 0x0004, 0x1F6B,
- 0x0008, 0x1F43, 0x00E0, 0x0489, 0x03CE, 0x0019, 0x1F65,
- 0x000D, 0x1F46, 0x00C4, 0x0474, 0x03E8, 0x002E, 0x1F5F,
- 0x0011, 0x1F49, 0x00A9, 0x045E, 0x0400, 0x0045, 0x1F5A,
- 0x0015, 0x1F4D, 0x008E, 0x0447, 0x0418, 0x005C, 0x1F55,
- 0x1F4F, 0x0076, 0x043B, 0x043B, 0x0076, 0x1F4F, 0x0000,
- 0x1F55, 0x005C, 0x0418, 0x0447, 0x008E, 0x1F4D, 0x0015,
- 0x1F5A, 0x0045, 0x0400, 0x045E, 0x00A9, 0x1F49, 0x0011,
- 0x1F5F, 0x002E, 0x03E8, 0x0474, 0x00C4, 0x1F46, 0x000D,
- 0x1F65, 0x0019, 0x03CE, 0x0489, 0x00E0, 0x1F43, 0x0008,
- 0x1F6B, 0x0004, 0x03B4, 0x049C, 0x00FD, 0x1F41, 0x0003,
- 0x1F72, 0x1FF0, 0x0398, 0x04AD, 0x011B, 0x1F40, 0x1FFE,
- 0x1F78, 0x1FDD, 0x037B, 0x04BE, 0x013A, 0x1F40, 0x1FF8,
- 0x1F7F, 0x1FCC, 0x035E, 0x04CC, 0x0159, 0x1F40, 0x1FF2,
- 0x1F86, 0x1FBB, 0x0340, 0x04DA, 0x0178, 0x1F41, 0x1FEC,
- 0x1F8E, 0x1FAB, 0x0321, 0x04E5, 0x0198, 0x1F43, 0x1FE6,
- 0x1F95, 0x1F9D, 0x0301, 0x04EF, 0x01B8, 0x1F47, 0x1FDF,
- 0x1F9D, 0x1F90, 0x02E1, 0x04F6, 0x01D9, 0x1F4B, 0x1FD8,
- 0x1FA5, 0x1F83, 0x02C0, 0x04FD, 0x01FA, 0x1F50, 0x1FD1,
- 0x1FAC, 0x1F78, 0x02A0, 0x0501, 0x021B, 0x1F56, 0x1FCA,
- 0x1FB4, 0x1F6E, 0x027F, 0x0503, 0x023C, 0x1F5D, 0x1FC3,
- /* Chroma */
- 0x1FBB, 0x1F65, 0x025E, 0x0504, 0x025E, 0x1F65, 0x1FBB,
- 0x1FC3, 0x1F5D, 0x023C, 0x0503, 0x027F, 0x1F6E, 0x1FB4,
- 0x1FCA, 0x1F56, 0x021B, 0x0501, 0x02A0, 0x1F78, 0x1FAC,
- 0x1FD1, 0x1F50, 0x01FA, 0x04FD, 0x02C0, 0x1F83, 0x1FA5,
- 0x1FD8, 0x1F4B, 0x01D9, 0x04F6, 0x02E1, 0x1F90, 0x1F9D,
- 0x1FDF, 0x1F47, 0x01B8, 0x04EF, 0x0301, 0x1F9D, 0x1F95,
- 0x1FE6, 0x1F43, 0x0198, 0x04E5, 0x0321, 0x1FAB, 0x1F8E,
- 0x1FEC, 0x1F41, 0x0178, 0x04DA, 0x0340, 0x1FBB, 0x1F86,
- 0x1FF2, 0x1F40, 0x0159, 0x04CC, 0x035E, 0x1FCC, 0x1F7F,
- 0x1FF8, 0x1F40, 0x013A, 0x04BE, 0x037B, 0x1FDD, 0x1F78,
- 0x1FFE, 0x1F40, 0x011B, 0x04AD, 0x0398, 0x1FF0, 0x1F72,
- 0x0003, 0x1F41, 0x00FD, 0x049C, 0x03B4, 0x0004, 0x1F6B,
- 0x0008, 0x1F43, 0x00E0, 0x0489, 0x03CE, 0x0019, 0x1F65,
- 0x000D, 0x1F46, 0x00C4, 0x0474, 0x03E8, 0x002E, 0x1F5F,
- 0x0011, 0x1F49, 0x00A9, 0x045E, 0x0400, 0x0045, 0x1F5A,
- 0x0015, 0x1F4D, 0x008E, 0x0447, 0x0418, 0x005C, 0x1F55,
- 0x1F4F, 0x0076, 0x043B, 0x043B, 0x0076, 0x1F4F, 0x0000,
- 0x1F55, 0x005C, 0x0418, 0x0447, 0x008E, 0x1F4D, 0x0015,
- 0x1F5A, 0x0045, 0x0400, 0x045E, 0x00A9, 0x1F49, 0x0011,
- 0x1F5F, 0x002E, 0x03E8, 0x0474, 0x00C4, 0x1F46, 0x000D,
- 0x1F65, 0x0019, 0x03CE, 0x0489, 0x00E0, 0x1F43, 0x0008,
- 0x1F6B, 0x0004, 0x03B4, 0x049C, 0x00FD, 0x1F41, 0x0003,
- 0x1F72, 0x1FF0, 0x0398, 0x04AD, 0x011B, 0x1F40, 0x1FFE,
- 0x1F78, 0x1FDD, 0x037B, 0x04BE, 0x013A, 0x1F40, 0x1FF8,
- 0x1F7F, 0x1FCC, 0x035E, 0x04CC, 0x0159, 0x1F40, 0x1FF2,
- 0x1F86, 0x1FBB, 0x0340, 0x04DA, 0x0178, 0x1F41, 0x1FEC,
- 0x1F8E, 0x1FAB, 0x0321, 0x04E5, 0x0198, 0x1F43, 0x1FE6,
- 0x1F95, 0x1F9D, 0x0301, 0x04EF, 0x01B8, 0x1F47, 0x1FDF,
- 0x1F9D, 0x1F90, 0x02E1, 0x04F6, 0x01D9, 0x1F4B, 0x1FD8,
- 0x1FA5, 0x1F83, 0x02C0, 0x04FD, 0x01FA, 0x1F50, 0x1FD1,
- 0x1FAC, 0x1F78, 0x02A0, 0x0501, 0x021B, 0x1F56, 0x1FCA,
- 0x1FB4, 0x1F6E, 0x027F, 0x0503, 0x023C, 0x1F5D, 0x1FC3,
- },
- [HS_LT_13_16_SCALE] = {
- /* Luma */
- 0x1FF4, 0x1F29, 0x022D, 0x056C, 0x022D, 0x1F29, 0x1FF4,
- 0x1FFC, 0x1F26, 0x0206, 0x056A, 0x0254, 0x1F2E, 0x1FEC,
- 0x0003, 0x1F24, 0x01E0, 0x0567, 0x027A, 0x1F34, 0x1FE4,
- 0x000A, 0x1F23, 0x01BA, 0x0561, 0x02A2, 0x1F3B, 0x1FDB,
- 0x0011, 0x1F22, 0x0194, 0x055B, 0x02C9, 0x1F43, 0x1FD2,
- 0x0017, 0x1F23, 0x016F, 0x0551, 0x02F0, 0x1F4D, 0x1FC9,
- 0x001D, 0x1F25, 0x014B, 0x0545, 0x0316, 0x1F58, 0x1FC0,
- 0x0022, 0x1F28, 0x0127, 0x0538, 0x033C, 0x1F65, 0x1FB6,
- 0x0027, 0x1F2C, 0x0104, 0x0528, 0x0361, 0x1F73, 0x1FAD,
- 0x002B, 0x1F30, 0x00E2, 0x0518, 0x0386, 0x1F82, 0x1FA3,
- 0x002F, 0x1F36, 0x00C2, 0x0504, 0x03AA, 0x1F92, 0x1F99,
- 0x0032, 0x1F3C, 0x00A2, 0x04EF, 0x03CD, 0x1FA4, 0x1F90,
- 0x0035, 0x1F42, 0x0083, 0x04D9, 0x03EF, 0x1FB8, 0x1F86,
- 0x0038, 0x1F49, 0x0065, 0x04C0, 0x0410, 0x1FCD, 0x1F7D,
- 0x003A, 0x1F51, 0x0048, 0x04A6, 0x0431, 0x1FE3, 0x1F73,
- 0x003C, 0x1F59, 0x002D, 0x048A, 0x0450, 0x1FFA, 0x1F6A,
- 0x1F5D, 0x0014, 0x048F, 0x048F, 0x0014, 0x1F5D, 0x0000,
- 0x1F6A, 0x1FFA, 0x0450, 0x048A, 0x002D, 0x1F59, 0x003C,
- 0x1F73, 0x1FE3, 0x0431, 0x04A6, 0x0048, 0x1F51, 0x003A,
- 0x1F7D, 0x1FCD, 0x0410, 0x04C0, 0x0065, 0x1F49, 0x0038,
- 0x1F86, 0x1FB8, 0x03EF, 0x04D9, 0x0083, 0x1F42, 0x0035,
- 0x1F90, 0x1FA4, 0x03CD, 0x04EF, 0x00A2, 0x1F3C, 0x0032,
- 0x1F99, 0x1F92, 0x03AA, 0x0504, 0x00C2, 0x1F36, 0x002F,
- 0x1FA3, 0x1F82, 0x0386, 0x0518, 0x00E2, 0x1F30, 0x002B,
- 0x1FAD, 0x1F73, 0x0361, 0x0528, 0x0104, 0x1F2C, 0x0027,
- 0x1FB6, 0x1F65, 0x033C, 0x0538, 0x0127, 0x1F28, 0x0022,
- 0x1FC0, 0x1F58, 0x0316, 0x0545, 0x014B, 0x1F25, 0x001D,
- 0x1FC9, 0x1F4D, 0x02F0, 0x0551, 0x016F, 0x1F23, 0x0017,
- 0x1FD2, 0x1F43, 0x02C9, 0x055B, 0x0194, 0x1F22, 0x0011,
- 0x1FDB, 0x1F3B, 0x02A2, 0x0561, 0x01BA, 0x1F23, 0x000A,
- 0x1FE4, 0x1F34, 0x027A, 0x0567, 0x01E0, 0x1F24, 0x0003,
- 0x1FEC, 0x1F2E, 0x0254, 0x056A, 0x0206, 0x1F26, 0x1FFC,
- /* Chroma */
- 0x1FF4, 0x1F29, 0x022D, 0x056C, 0x022D, 0x1F29, 0x1FF4,
- 0x1FFC, 0x1F26, 0x0206, 0x056A, 0x0254, 0x1F2E, 0x1FEC,
- 0x0003, 0x1F24, 0x01E0, 0x0567, 0x027A, 0x1F34, 0x1FE4,
- 0x000A, 0x1F23, 0x01BA, 0x0561, 0x02A2, 0x1F3B, 0x1FDB,
- 0x0011, 0x1F22, 0x0194, 0x055B, 0x02C9, 0x1F43, 0x1FD2,
- 0x0017, 0x1F23, 0x016F, 0x0551, 0x02F0, 0x1F4D, 0x1FC9,
- 0x001D, 0x1F25, 0x014B, 0x0545, 0x0316, 0x1F58, 0x1FC0,
- 0x0022, 0x1F28, 0x0127, 0x0538, 0x033C, 0x1F65, 0x1FB6,
- 0x0027, 0x1F2C, 0x0104, 0x0528, 0x0361, 0x1F73, 0x1FAD,
- 0x002B, 0x1F30, 0x00E2, 0x0518, 0x0386, 0x1F82, 0x1FA3,
- 0x002F, 0x1F36, 0x00C2, 0x0504, 0x03AA, 0x1F92, 0x1F99,
- 0x0032, 0x1F3C, 0x00A2, 0x04EF, 0x03CD, 0x1FA4, 0x1F90,
- 0x0035, 0x1F42, 0x0083, 0x04D9, 0x03EF, 0x1FB8, 0x1F86,
- 0x0038, 0x1F49, 0x0065, 0x04C0, 0x0410, 0x1FCD, 0x1F7D,
- 0x003A, 0x1F51, 0x0048, 0x04A6, 0x0431, 0x1FE3, 0x1F73,
- 0x003C, 0x1F59, 0x002D, 0x048A, 0x0450, 0x1FFA, 0x1F6A,
- 0x1F5D, 0x0014, 0x048F, 0x048F, 0x0014, 0x1F5D, 0x0000,
- 0x1F6A, 0x1FFA, 0x0450, 0x048A, 0x002D, 0x1F59, 0x003C,
- 0x1F73, 0x1FE3, 0x0431, 0x04A6, 0x0048, 0x1F51, 0x003A,
- 0x1F7D, 0x1FCD, 0x0410, 0x04C0, 0x0065, 0x1F49, 0x0038,
- 0x1F86, 0x1FB8, 0x03EF, 0x04D9, 0x0083, 0x1F42, 0x0035,
- 0x1F90, 0x1FA4, 0x03CD, 0x04EF, 0x00A2, 0x1F3C, 0x0032,
- 0x1F99, 0x1F92, 0x03AA, 0x0504, 0x00C2, 0x1F36, 0x002F,
- 0x1FA3, 0x1F82, 0x0386, 0x0518, 0x00E2, 0x1F30, 0x002B,
- 0x1FAD, 0x1F73, 0x0361, 0x0528, 0x0104, 0x1F2C, 0x0027,
- 0x1FB6, 0x1F65, 0x033C, 0x0538, 0x0127, 0x1F28, 0x0022,
- 0x1FC0, 0x1F58, 0x0316, 0x0545, 0x014B, 0x1F25, 0x001D,
- 0x1FC9, 0x1F4D, 0x02F0, 0x0551, 0x016F, 0x1F23, 0x0017,
- 0x1FD2, 0x1F43, 0x02C9, 0x055B, 0x0194, 0x1F22, 0x0011,
- 0x1FDB, 0x1F3B, 0x02A2, 0x0561, 0x01BA, 0x1F23, 0x000A,
- 0x1FE4, 0x1F34, 0x027A, 0x0567, 0x01E0, 0x1F24, 0x0003,
- 0x1FEC, 0x1F2E, 0x0254, 0x056A, 0x0206, 0x1F26, 0x1FFC,
- },
- [HS_LT_14_16_SCALE] = {
- /* Luma */
- 0x002F, 0x1F0B, 0x01E7, 0x05BE, 0x01E7, 0x1F0B, 0x002F,
- 0x0035, 0x1F0D, 0x01BC, 0x05BD, 0x0213, 0x1F0A, 0x0028,
- 0x003A, 0x1F11, 0x0191, 0x05BA, 0x023F, 0x1F0A, 0x0021,
- 0x003F, 0x1F15, 0x0167, 0x05B3, 0x026C, 0x1F0C, 0x001A,
- 0x0043, 0x1F1B, 0x013E, 0x05AA, 0x0299, 0x1F0F, 0x0012,
- 0x0046, 0x1F21, 0x0116, 0x05A1, 0x02C6, 0x1F13, 0x0009,
- 0x0049, 0x1F28, 0x00EF, 0x0593, 0x02F4, 0x1F19, 0x0000,
- 0x004C, 0x1F30, 0x00C9, 0x0584, 0x0321, 0x1F20, 0x1FF6,
- 0x004E, 0x1F39, 0x00A4, 0x0572, 0x034D, 0x1F2A, 0x1FEC,
- 0x004F, 0x1F43, 0x0080, 0x055E, 0x037A, 0x1F34, 0x1FE2,
- 0x0050, 0x1F4D, 0x005E, 0x0548, 0x03A5, 0x1F41, 0x1FD7,
- 0x0050, 0x1F57, 0x003D, 0x0531, 0x03D1, 0x1F4F, 0x1FCB,
- 0x0050, 0x1F62, 0x001E, 0x0516, 0x03FB, 0x1F5F, 0x1FC0,
- 0x004F, 0x1F6D, 0x0000, 0x04FA, 0x0425, 0x1F71, 0x1FB4,
- 0x004E, 0x1F79, 0x1FE4, 0x04DC, 0x044D, 0x1F84, 0x1FA8,
- 0x004D, 0x1F84, 0x1FCA, 0x04BC, 0x0474, 0x1F99, 0x1F9C,
- 0x1F8C, 0x1FAE, 0x04C6, 0x04C6, 0x1FAE, 0x1F8C, 0x0000,
- 0x1F9C, 0x1F99, 0x0474, 0x04BC, 0x1FCA, 0x1F84, 0x004D,
- 0x1FA8, 0x1F84, 0x044D, 0x04DC, 0x1FE4, 0x1F79, 0x004E,
- 0x1FB4, 0x1F71, 0x0425, 0x04FA, 0x0000, 0x1F6D, 0x004F,
- 0x1FC0, 0x1F5F, 0x03FB, 0x0516, 0x001E, 0x1F62, 0x0050,
- 0x1FCB, 0x1F4F, 0x03D1, 0x0531, 0x003D, 0x1F57, 0x0050,
- 0x1FD7, 0x1F41, 0x03A5, 0x0548, 0x005E, 0x1F4D, 0x0050,
- 0x1FE2, 0x1F34, 0x037A, 0x055E, 0x0080, 0x1F43, 0x004F,
- 0x1FEC, 0x1F2A, 0x034D, 0x0572, 0x00A4, 0x1F39, 0x004E,
- 0x1FF6, 0x1F20, 0x0321, 0x0584, 0x00C9, 0x1F30, 0x004C,
- 0x0000, 0x1F19, 0x02F4, 0x0593, 0x00EF, 0x1F28, 0x0049,
- 0x0009, 0x1F13, 0x02C6, 0x05A1, 0x0116, 0x1F21, 0x0046,
- 0x0012, 0x1F0F, 0x0299, 0x05AA, 0x013E, 0x1F1B, 0x0043,
- 0x001A, 0x1F0C, 0x026C, 0x05B3, 0x0167, 0x1F15, 0x003F,
- 0x0021, 0x1F0A, 0x023F, 0x05BA, 0x0191, 0x1F11, 0x003A,
- 0x0028, 0x1F0A, 0x0213, 0x05BD, 0x01BC, 0x1F0D, 0x0035,
- /* Chroma */
- 0x002F, 0x1F0B, 0x01E7, 0x05BE, 0x01E7, 0x1F0B, 0x002F,
- 0x0035, 0x1F0D, 0x01BC, 0x05BD, 0x0213, 0x1F0A, 0x0028,
- 0x003A, 0x1F11, 0x0191, 0x05BA, 0x023F, 0x1F0A, 0x0021,
- 0x003F, 0x1F15, 0x0167, 0x05B3, 0x026C, 0x1F0C, 0x001A,
- 0x0043, 0x1F1B, 0x013E, 0x05AA, 0x0299, 0x1F0F, 0x0012,
- 0x0046, 0x1F21, 0x0116, 0x05A1, 0x02C6, 0x1F13, 0x0009,
- 0x0049, 0x1F28, 0x00EF, 0x0593, 0x02F4, 0x1F19, 0x0000,
- 0x004C, 0x1F30, 0x00C9, 0x0584, 0x0321, 0x1F20, 0x1FF6,
- 0x004E, 0x1F39, 0x00A4, 0x0572, 0x034D, 0x1F2A, 0x1FEC,
- 0x004F, 0x1F43, 0x0080, 0x055E, 0x037A, 0x1F34, 0x1FE2,
- 0x0050, 0x1F4D, 0x005E, 0x0548, 0x03A5, 0x1F41, 0x1FD7,
- 0x0050, 0x1F57, 0x003D, 0x0531, 0x03D1, 0x1F4F, 0x1FCB,
- 0x0050, 0x1F62, 0x001E, 0x0516, 0x03FB, 0x1F5F, 0x1FC0,
- 0x004F, 0x1F6D, 0x0000, 0x04FA, 0x0425, 0x1F71, 0x1FB4,
- 0x004E, 0x1F79, 0x1FE4, 0x04DC, 0x044D, 0x1F84, 0x1FA8,
- 0x004D, 0x1F84, 0x1FCA, 0x04BC, 0x0474, 0x1F99, 0x1F9C,
- 0x1F8C, 0x1FAE, 0x04C6, 0x04C6, 0x1FAE, 0x1F8C, 0x0000,
- 0x1F9C, 0x1F99, 0x0474, 0x04BC, 0x1FCA, 0x1F84, 0x004D,
- 0x1FA8, 0x1F84, 0x044D, 0x04DC, 0x1FE4, 0x1F79, 0x004E,
- 0x1FB4, 0x1F71, 0x0425, 0x04FA, 0x0000, 0x1F6D, 0x004F,
- 0x1FC0, 0x1F5F, 0x03FB, 0x0516, 0x001E, 0x1F62, 0x0050,
- 0x1FCB, 0x1F4F, 0x03D1, 0x0531, 0x003D, 0x1F57, 0x0050,
- 0x1FD7, 0x1F41, 0x03A5, 0x0548, 0x005E, 0x1F4D, 0x0050,
- 0x1FE2, 0x1F34, 0x037A, 0x055E, 0x0080, 0x1F43, 0x004F,
- 0x1FEC, 0x1F2A, 0x034D, 0x0572, 0x00A4, 0x1F39, 0x004E,
- 0x1FF6, 0x1F20, 0x0321, 0x0584, 0x00C9, 0x1F30, 0x004C,
- 0x0000, 0x1F19, 0x02F4, 0x0593, 0x00EF, 0x1F28, 0x0049,
- 0x0009, 0x1F13, 0x02C6, 0x05A1, 0x0116, 0x1F21, 0x0046,
- 0x0012, 0x1F0F, 0x0299, 0x05AA, 0x013E, 0x1F1B, 0x0043,
- 0x001A, 0x1F0C, 0x026C, 0x05B3, 0x0167, 0x1F15, 0x003F,
- 0x0021, 0x1F0A, 0x023F, 0x05BA, 0x0191, 0x1F11, 0x003A,
- 0x0028, 0x1F0A, 0x0213, 0x05BD, 0x01BC, 0x1F0D, 0x0035,
- },
- [HS_LT_15_16_SCALE] = {
- /* Luma */
- 0x005B, 0x1F0A, 0x0195, 0x060C, 0x0195, 0x1F0A, 0x005B,
- 0x005D, 0x1F13, 0x0166, 0x0609, 0x01C6, 0x1F03, 0x0058,
- 0x005F, 0x1F1C, 0x0138, 0x0605, 0x01F7, 0x1EFD, 0x0054,
- 0x0060, 0x1F26, 0x010B, 0x05FF, 0x0229, 0x1EF8, 0x004F,
- 0x0060, 0x1F31, 0x00DF, 0x05F5, 0x025C, 0x1EF5, 0x004A,
- 0x0060, 0x1F3D, 0x00B5, 0x05E8, 0x028F, 0x1EF3, 0x0044,
- 0x005F, 0x1F49, 0x008C, 0x05DA, 0x02C3, 0x1EF2, 0x003D,
- 0x005E, 0x1F56, 0x0065, 0x05C7, 0x02F6, 0x1EF4, 0x0036,
- 0x005C, 0x1F63, 0x003F, 0x05B3, 0x032B, 0x1EF7, 0x002D,
- 0x0059, 0x1F71, 0x001B, 0x059D, 0x035F, 0x1EFB, 0x0024,
- 0x0057, 0x1F7F, 0x1FF9, 0x0583, 0x0392, 0x1F02, 0x001A,
- 0x0053, 0x1F8D, 0x1FD9, 0x0567, 0x03C5, 0x1F0B, 0x0010,
- 0x0050, 0x1F9B, 0x1FBB, 0x0548, 0x03F8, 0x1F15, 0x0005,
- 0x004C, 0x1FA9, 0x1F9E, 0x0528, 0x042A, 0x1F22, 0x1FF9,
- 0x0048, 0x1FB7, 0x1F84, 0x0505, 0x045A, 0x1F31, 0x1FED,
- 0x0043, 0x1FC5, 0x1F6C, 0x04E0, 0x048A, 0x1F42, 0x1FE0,
- 0x1FD1, 0x1F50, 0x04DF, 0x04DF, 0x1F50, 0x1FD1, 0x0000,
- 0x1FE0, 0x1F42, 0x048A, 0x04E0, 0x1F6C, 0x1FC5, 0x0043,
- 0x1FED, 0x1F31, 0x045A, 0x0505, 0x1F84, 0x1FB7, 0x0048,
- 0x1FF9, 0x1F22, 0x042A, 0x0528, 0x1F9E, 0x1FA9, 0x004C,
- 0x0005, 0x1F15, 0x03F8, 0x0548, 0x1FBB, 0x1F9B, 0x0050,
- 0x0010, 0x1F0B, 0x03C5, 0x0567, 0x1FD9, 0x1F8D, 0x0053,
- 0x001A, 0x1F02, 0x0392, 0x0583, 0x1FF9, 0x1F7F, 0x0057,
- 0x0024, 0x1EFB, 0x035F, 0x059D, 0x001B, 0x1F71, 0x0059,
- 0x002D, 0x1EF7, 0x032B, 0x05B3, 0x003F, 0x1F63, 0x005C,
- 0x0036, 0x1EF4, 0x02F6, 0x05C7, 0x0065, 0x1F56, 0x005E,
- 0x003D, 0x1EF2, 0x02C3, 0x05DA, 0x008C, 0x1F49, 0x005F,
- 0x0044, 0x1EF3, 0x028F, 0x05E8, 0x00B5, 0x1F3D, 0x0060,
- 0x004A, 0x1EF5, 0x025C, 0x05F5, 0x00DF, 0x1F31, 0x0060,
- 0x004F, 0x1EF8, 0x0229, 0x05FF, 0x010B, 0x1F26, 0x0060,
- 0x0054, 0x1EFD, 0x01F7, 0x0605, 0x0138, 0x1F1C, 0x005F,
- 0x0058, 0x1F03, 0x01C6, 0x0609, 0x0166, 0x1F13, 0x005D,
- /* Chroma */
- 0x005B, 0x1F0A, 0x0195, 0x060C, 0x0195, 0x1F0A, 0x005B,
- 0x005D, 0x1F13, 0x0166, 0x0609, 0x01C6, 0x1F03, 0x0058,
- 0x005F, 0x1F1C, 0x0138, 0x0605, 0x01F7, 0x1EFD, 0x0054,
- 0x0060, 0x1F26, 0x010B, 0x05FF, 0x0229, 0x1EF8, 0x004F,
- 0x0060, 0x1F31, 0x00DF, 0x05F5, 0x025C, 0x1EF5, 0x004A,
- 0x0060, 0x1F3D, 0x00B5, 0x05E8, 0x028F, 0x1EF3, 0x0044,
- 0x005F, 0x1F49, 0x008C, 0x05DA, 0x02C3, 0x1EF2, 0x003D,
- 0x005E, 0x1F56, 0x0065, 0x05C7, 0x02F6, 0x1EF4, 0x0036,
- 0x005C, 0x1F63, 0x003F, 0x05B3, 0x032B, 0x1EF7, 0x002D,
- 0x0059, 0x1F71, 0x001B, 0x059D, 0x035F, 0x1EFB, 0x0024,
- 0x0057, 0x1F7F, 0x1FF9, 0x0583, 0x0392, 0x1F02, 0x001A,
- 0x0053, 0x1F8D, 0x1FD9, 0x0567, 0x03C5, 0x1F0B, 0x0010,
- 0x0050, 0x1F9B, 0x1FBB, 0x0548, 0x03F8, 0x1F15, 0x0005,
- 0x004C, 0x1FA9, 0x1F9E, 0x0528, 0x042A, 0x1F22, 0x1FF9,
- 0x0048, 0x1FB7, 0x1F84, 0x0505, 0x045A, 0x1F31, 0x1FED,
- 0x0043, 0x1FC5, 0x1F6C, 0x04E0, 0x048A, 0x1F42, 0x1FE0,
- 0x1FD1, 0x1F50, 0x04DF, 0x04DF, 0x1F50, 0x1FD1, 0x0000,
- 0x1FE0, 0x1F42, 0x048A, 0x04E0, 0x1F6C, 0x1FC5, 0x0043,
- 0x1FED, 0x1F31, 0x045A, 0x0505, 0x1F84, 0x1FB7, 0x0048,
- 0x1FF9, 0x1F22, 0x042A, 0x0528, 0x1F9E, 0x1FA9, 0x004C,
- 0x0005, 0x1F15, 0x03F8, 0x0548, 0x1FBB, 0x1F9B, 0x0050,
- 0x0010, 0x1F0B, 0x03C5, 0x0567, 0x1FD9, 0x1F8D, 0x0053,
- 0x001A, 0x1F02, 0x0392, 0x0583, 0x1FF9, 0x1F7F, 0x0057,
- 0x0024, 0x1EFB, 0x035F, 0x059D, 0x001B, 0x1F71, 0x0059,
- 0x002D, 0x1EF7, 0x032B, 0x05B3, 0x003F, 0x1F63, 0x005C,
- 0x0036, 0x1EF4, 0x02F6, 0x05C7, 0x0065, 0x1F56, 0x005E,
- 0x003D, 0x1EF2, 0x02C3, 0x05DA, 0x008C, 0x1F49, 0x005F,
- 0x0044, 0x1EF3, 0x028F, 0x05E8, 0x00B5, 0x1F3D, 0x0060,
- 0x004A, 0x1EF5, 0x025C, 0x05F5, 0x00DF, 0x1F31, 0x0060,
- 0x004F, 0x1EF8, 0x0229, 0x05FF, 0x010B, 0x1F26, 0x0060,
- 0x0054, 0x1EFD, 0x01F7, 0x0605, 0x0138, 0x1F1C, 0x005F,
- 0x0058, 0x1F03, 0x01C6, 0x0609, 0x0166, 0x1F13, 0x005D,
- },
- [HS_LE_16_16_SCALE] = {
- /* Luma */
- 0x006E, 0x1F24, 0x013E, 0x0660, 0x013E, 0x1F24, 0x006E,
- 0x006C, 0x1F33, 0x010B, 0x065D, 0x0172, 0x1F17, 0x0070,
- 0x0069, 0x1F41, 0x00DA, 0x0659, 0x01A8, 0x1F0B, 0x0070,
- 0x0066, 0x1F51, 0x00AA, 0x0650, 0x01DF, 0x1F00, 0x0070,
- 0x0062, 0x1F61, 0x007D, 0x0644, 0x0217, 0x1EF6, 0x006F,
- 0x005E, 0x1F71, 0x0051, 0x0636, 0x0250, 0x1EED, 0x006D,
- 0x0059, 0x1F81, 0x0028, 0x0624, 0x028A, 0x1EE5, 0x006B,
- 0x0054, 0x1F91, 0x0000, 0x060F, 0x02C5, 0x1EE0, 0x0067,
- 0x004E, 0x1FA2, 0x1FDB, 0x05F6, 0x0300, 0x1EDC, 0x0063,
- 0x0049, 0x1FB2, 0x1FB8, 0x05DB, 0x033B, 0x1EDA, 0x005D,
- 0x0043, 0x1FC3, 0x1F98, 0x05BC, 0x0376, 0x1ED9, 0x0057,
- 0x003D, 0x1FD3, 0x1F7A, 0x059B, 0x03B1, 0x1EDB, 0x004F,
- 0x0036, 0x1FE2, 0x1F5E, 0x0578, 0x03EC, 0x1EDF, 0x0047,
- 0x0030, 0x1FF1, 0x1F45, 0x0551, 0x0426, 0x1EE6, 0x003D,
- 0x002A, 0x0000, 0x1F2E, 0x0528, 0x045F, 0x1EEE, 0x0033,
- 0x0023, 0x000E, 0x1F19, 0x04FD, 0x0498, 0x1EFA, 0x0027,
- 0x001B, 0x1F04, 0x04E1, 0x04E1, 0x1F04, 0x001B, 0x0000,
- 0x0027, 0x1EFA, 0x0498, 0x04FD, 0x1F19, 0x000E, 0x0023,
- 0x0033, 0x1EEE, 0x045F, 0x0528, 0x1F2E, 0x0000, 0x002A,
- 0x003D, 0x1EE6, 0x0426, 0x0551, 0x1F45, 0x1FF1, 0x0030,
- 0x0047, 0x1EDF, 0x03EC, 0x0578, 0x1F5E, 0x1FE2, 0x0036,
- 0x004F, 0x1EDB, 0x03B1, 0x059B, 0x1F7A, 0x1FD3, 0x003D,
- 0x0057, 0x1ED9, 0x0376, 0x05BC, 0x1F98, 0x1FC3, 0x0043,
- 0x005D, 0x1EDA, 0x033B, 0x05DB, 0x1FB8, 0x1FB2, 0x0049,
- 0x0063, 0x1EDC, 0x0300, 0x05F6, 0x1FDB, 0x1FA2, 0x004E,
- 0x0067, 0x1EE0, 0x02C5, 0x060F, 0x0000, 0x1F91, 0x0054,
- 0x006B, 0x1EE5, 0x028A, 0x0624, 0x0028, 0x1F81, 0x0059,
- 0x006D, 0x1EED, 0x0250, 0x0636, 0x0051, 0x1F71, 0x005E,
- 0x006F, 0x1EF6, 0x0217, 0x0644, 0x007D, 0x1F61, 0x0062,
- 0x0070, 0x1F00, 0x01DF, 0x0650, 0x00AA, 0x1F51, 0x0066,
- 0x0070, 0x1F0B, 0x01A8, 0x0659, 0x00DA, 0x1F41, 0x0069,
- 0x0070, 0x1F17, 0x0172, 0x065D, 0x010B, 0x1F33, 0x006C,
- /* Chroma */
- 0x006E, 0x1F24, 0x013E, 0x0660, 0x013E, 0x1F24, 0x006E,
- 0x006C, 0x1F33, 0x010B, 0x065D, 0x0172, 0x1F17, 0x0070,
- 0x0069, 0x1F41, 0x00DA, 0x0659, 0x01A8, 0x1F0B, 0x0070,
- 0x0066, 0x1F51, 0x00AA, 0x0650, 0x01DF, 0x1F00, 0x0070,
- 0x0062, 0x1F61, 0x007D, 0x0644, 0x0217, 0x1EF6, 0x006F,
- 0x005E, 0x1F71, 0x0051, 0x0636, 0x0250, 0x1EED, 0x006D,
- 0x0059, 0x1F81, 0x0028, 0x0624, 0x028A, 0x1EE5, 0x006B,
- 0x0054, 0x1F91, 0x0000, 0x060F, 0x02C5, 0x1EE0, 0x0067,
- 0x004E, 0x1FA2, 0x1FDB, 0x05F6, 0x0300, 0x1EDC, 0x0063,
- 0x0049, 0x1FB2, 0x1FB8, 0x05DB, 0x033B, 0x1EDA, 0x005D,
- 0x0043, 0x1FC3, 0x1F98, 0x05BC, 0x0376, 0x1ED9, 0x0057,
- 0x003D, 0x1FD3, 0x1F7A, 0x059B, 0x03B1, 0x1EDB, 0x004F,
- 0x0036, 0x1FE2, 0x1F5E, 0x0578, 0x03EC, 0x1EDF, 0x0047,
- 0x0030, 0x1FF1, 0x1F45, 0x0551, 0x0426, 0x1EE6, 0x003D,
- 0x002A, 0x0000, 0x1F2E, 0x0528, 0x045F, 0x1EEE, 0x0033,
- 0x0023, 0x000E, 0x1F19, 0x04FD, 0x0498, 0x1EFA, 0x0027,
- 0x001B, 0x1F04, 0x04E1, 0x04E1, 0x1F04, 0x001B, 0x0000,
- 0x0027, 0x1EFA, 0x0498, 0x04FD, 0x1F19, 0x000E, 0x0023,
- 0x0033, 0x1EEE, 0x045F, 0x0528, 0x1F2E, 0x0000, 0x002A,
- 0x003D, 0x1EE6, 0x0426, 0x0551, 0x1F45, 0x1FF1, 0x0030,
- 0x0047, 0x1EDF, 0x03EC, 0x0578, 0x1F5E, 0x1FE2, 0x0036,
- 0x004F, 0x1EDB, 0x03B1, 0x059B, 0x1F7A, 0x1FD3, 0x003D,
- 0x0057, 0x1ED9, 0x0376, 0x05BC, 0x1F98, 0x1FC3, 0x0043,
- 0x005D, 0x1EDA, 0x033B, 0x05DB, 0x1FB8, 0x1FB2, 0x0049,
- 0x0063, 0x1EDC, 0x0300, 0x05F6, 0x1FDB, 0x1FA2, 0x004E,
- 0x0067, 0x1EE0, 0x02C5, 0x060F, 0x0000, 0x1F91, 0x0054,
- 0x006B, 0x1EE5, 0x028A, 0x0624, 0x0028, 0x1F81, 0x0059,
- 0x006D, 0x1EED, 0x0250, 0x0636, 0x0051, 0x1F71, 0x005E,
- 0x006F, 0x1EF6, 0x0217, 0x0644, 0x007D, 0x1F61, 0x0062,
- 0x0070, 0x1F00, 0x01DF, 0x0650, 0x00AA, 0x1F51, 0x0066,
- 0x0070, 0x1F0B, 0x01A8, 0x0659, 0x00DA, 0x1F41, 0x0069,
- 0x0070, 0x1F17, 0x0172, 0x065D, 0x010B, 0x1F33, 0x006C,
- },
-};
-
-/* vertical scaler coefficients */
-enum {
- VS_UP_SCALE = 0,
- VS_LT_9_16_SCALE,
- VS_LT_10_16_SCALE,
- VS_LT_11_16_SCALE,
- VS_LT_12_16_SCALE,
- VS_LT_13_16_SCALE,
- VS_LT_14_16_SCALE,
- VS_LT_15_16_SCALE,
- VS_LT_16_16_SCALE,
- VS_1_TO_1_SCALE,
-};
-
-static const u16 scaler_vs_coeffs[15][SC_NUM_PHASES * 2 * SC_V_NUM_TAPS] = {
- [VS_UP_SCALE] = {
- /* Luma */
- 0x1FD1, 0x00B1, 0x06FC, 0x00B1, 0x1FD1,
- 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
- 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
- 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
- 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
- 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
- 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
- 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
- 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
- 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
- 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
- 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
- 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
- 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
- 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
- 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
- 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
- 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
- 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
- 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
- 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
- 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
- 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
- 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
- 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
- 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
- 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
- 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
- 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
- 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
- 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
- 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
- /* Chroma */
- 0x1FD1, 0x00B1, 0x06FC, 0x00B1, 0x1FD1,
- 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
- 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
- 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
- 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
- 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
- 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
- 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
- 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
- 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
- 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
- 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
- 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
- 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
- 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
- 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
- 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
- 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
- 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
- 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
- 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
- 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
- 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
- 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
- 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
- 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
- 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
- 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
- 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
- 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
- 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
- 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
- },
- [VS_LT_9_16_SCALE] = {
- /* Luma */
- 0x001C, 0x01F6, 0x03DC, 0x01F6, 0x001C,
- 0x0018, 0x01DF, 0x03DB, 0x020C, 0x0022,
- 0x0013, 0x01C9, 0x03D9, 0x0223, 0x0028,
- 0x000F, 0x01B3, 0x03D6, 0x023A, 0x002E,
- 0x000C, 0x019D, 0x03D2, 0x0250, 0x0035,
- 0x0009, 0x0188, 0x03CC, 0x0266, 0x003D,
- 0x0006, 0x0173, 0x03C5, 0x027D, 0x0045,
- 0x0004, 0x015E, 0x03BD, 0x0293, 0x004E,
- 0x0002, 0x014A, 0x03B4, 0x02A8, 0x0058,
- 0x0000, 0x0136, 0x03AA, 0x02BE, 0x0062,
- 0x1FFF, 0x0123, 0x039E, 0x02D3, 0x006D,
- 0x1FFE, 0x0110, 0x0392, 0x02E8, 0x0078,
- 0x1FFD, 0x00FE, 0x0384, 0x02FC, 0x0085,
- 0x1FFD, 0x00ED, 0x0376, 0x030F, 0x0091,
- 0x1FFC, 0x00DC, 0x0367, 0x0322, 0x009F,
- 0x1FFC, 0x00CC, 0x0357, 0x0334, 0x00AD,
- 0x00BC, 0x0344, 0x0344, 0x00BC, 0x0000,
- 0x00AD, 0x0334, 0x0357, 0x00CC, 0x1FFC,
- 0x009F, 0x0322, 0x0367, 0x00DC, 0x1FFC,
- 0x0091, 0x030F, 0x0376, 0x00ED, 0x1FFD,
- 0x0085, 0x02FC, 0x0384, 0x00FE, 0x1FFD,
- 0x0078, 0x02E8, 0x0392, 0x0110, 0x1FFE,
- 0x006D, 0x02D3, 0x039E, 0x0123, 0x1FFF,
- 0x0062, 0x02BE, 0x03AA, 0x0136, 0x0000,
- 0x0058, 0x02A8, 0x03B4, 0x014A, 0x0002,
- 0x004E, 0x0293, 0x03BD, 0x015E, 0x0004,
- 0x0045, 0x027D, 0x03C5, 0x0173, 0x0006,
- 0x003D, 0x0266, 0x03CC, 0x0188, 0x0009,
- 0x0035, 0x0250, 0x03D2, 0x019D, 0x000C,
- 0x002E, 0x023A, 0x03D6, 0x01B3, 0x000F,
- 0x0028, 0x0223, 0x03D9, 0x01C9, 0x0013,
- 0x0022, 0x020C, 0x03DB, 0x01DF, 0x0018,
- /* Chroma */
- 0x001C, 0x01F6, 0x03DC, 0x01F6, 0x001C,
- 0x0018, 0x01DF, 0x03DB, 0x020C, 0x0022,
- 0x0013, 0x01C9, 0x03D9, 0x0223, 0x0028,
- 0x000F, 0x01B3, 0x03D6, 0x023A, 0x002E,
- 0x000C, 0x019D, 0x03D2, 0x0250, 0x0035,
- 0x0009, 0x0188, 0x03CC, 0x0266, 0x003D,
- 0x0006, 0x0173, 0x03C5, 0x027D, 0x0045,
- 0x0004, 0x015E, 0x03BD, 0x0293, 0x004E,
- 0x0002, 0x014A, 0x03B4, 0x02A8, 0x0058,
- 0x0000, 0x0136, 0x03AA, 0x02BE, 0x0062,
- 0x1FFF, 0x0123, 0x039E, 0x02D3, 0x006D,
- 0x1FFE, 0x0110, 0x0392, 0x02E8, 0x0078,
- 0x1FFD, 0x00FE, 0x0384, 0x02FC, 0x0085,
- 0x1FFD, 0x00ED, 0x0376, 0x030F, 0x0091,
- 0x1FFC, 0x00DC, 0x0367, 0x0322, 0x009F,
- 0x1FFC, 0x00CC, 0x0357, 0x0334, 0x00AD,
- 0x00BC, 0x0344, 0x0344, 0x00BC, 0x0000,
- 0x00AD, 0x0334, 0x0357, 0x00CC, 0x1FFC,
- 0x009F, 0x0322, 0x0367, 0x00DC, 0x1FFC,
- 0x0091, 0x030F, 0x0376, 0x00ED, 0x1FFD,
- 0x0085, 0x02FC, 0x0384, 0x00FE, 0x1FFD,
- 0x0078, 0x02E8, 0x0392, 0x0110, 0x1FFE,
- 0x006D, 0x02D3, 0x039E, 0x0123, 0x1FFF,
- 0x0062, 0x02BE, 0x03AA, 0x0136, 0x0000,
- 0x0058, 0x02A8, 0x03B4, 0x014A, 0x0002,
- 0x004E, 0x0293, 0x03BD, 0x015E, 0x0004,
- 0x0045, 0x027D, 0x03C5, 0x0173, 0x0006,
- 0x003D, 0x0266, 0x03CC, 0x0188, 0x0009,
- 0x0035, 0x0250, 0x03D2, 0x019D, 0x000C,
- 0x002E, 0x023A, 0x03D6, 0x01B3, 0x000F,
- 0x0028, 0x0223, 0x03D9, 0x01C9, 0x0013,
- 0x0022, 0x020C, 0x03DB, 0x01DF, 0x0018,
- },
- [VS_LT_10_16_SCALE] = {
- /* Luma */
- 0x0003, 0x01E9, 0x0428, 0x01E9, 0x0003,
- 0x0000, 0x01D0, 0x0426, 0x0203, 0x0007,
- 0x1FFD, 0x01B7, 0x0424, 0x021C, 0x000C,
- 0x1FFB, 0x019E, 0x0420, 0x0236, 0x0011,
- 0x1FF9, 0x0186, 0x041A, 0x0250, 0x0017,
- 0x1FF7, 0x016E, 0x0414, 0x026A, 0x001D,
- 0x1FF6, 0x0157, 0x040B, 0x0284, 0x0024,
- 0x1FF5, 0x0140, 0x0401, 0x029E, 0x002C,
- 0x1FF4, 0x012A, 0x03F6, 0x02B7, 0x0035,
- 0x1FF4, 0x0115, 0x03E9, 0x02D0, 0x003E,
- 0x1FF4, 0x0100, 0x03DB, 0x02E9, 0x0048,
- 0x1FF4, 0x00EC, 0x03CC, 0x0301, 0x0053,
- 0x1FF4, 0x00D9, 0x03BC, 0x0318, 0x005F,
- 0x1FF5, 0x00C7, 0x03AA, 0x032F, 0x006B,
- 0x1FF6, 0x00B5, 0x0398, 0x0345, 0x0078,
- 0x1FF6, 0x00A5, 0x0384, 0x035B, 0x0086,
- 0x0094, 0x036C, 0x036C, 0x0094, 0x0000,
- 0x0086, 0x035B, 0x0384, 0x00A5, 0x1FF6,
- 0x0078, 0x0345, 0x0398, 0x00B5, 0x1FF6,
- 0x006B, 0x032F, 0x03AA, 0x00C7, 0x1FF5,
- 0x005F, 0x0318, 0x03BC, 0x00D9, 0x1FF4,
- 0x0053, 0x0301, 0x03CC, 0x00EC, 0x1FF4,
- 0x0048, 0x02E9, 0x03DB, 0x0100, 0x1FF4,
- 0x003E, 0x02D0, 0x03E9, 0x0115, 0x1FF4,
- 0x0035, 0x02B7, 0x03F6, 0x012A, 0x1FF4,
- 0x002C, 0x029E, 0x0401, 0x0140, 0x1FF5,
- 0x0024, 0x0284, 0x040B, 0x0157, 0x1FF6,
- 0x001D, 0x026A, 0x0414, 0x016E, 0x1FF7,
- 0x0017, 0x0250, 0x041A, 0x0186, 0x1FF9,
- 0x0011, 0x0236, 0x0420, 0x019E, 0x1FFB,
- 0x000C, 0x021C, 0x0424, 0x01B7, 0x1FFD,
- 0x0007, 0x0203, 0x0426, 0x01D0, 0x0000,
- /* Chroma */
- 0x0003, 0x01E9, 0x0428, 0x01E9, 0x0003,
- 0x0000, 0x01D0, 0x0426, 0x0203, 0x0007,
- 0x1FFD, 0x01B7, 0x0424, 0x021C, 0x000C,
- 0x1FFB, 0x019E, 0x0420, 0x0236, 0x0011,
- 0x1FF9, 0x0186, 0x041A, 0x0250, 0x0017,
- 0x1FF7, 0x016E, 0x0414, 0x026A, 0x001D,
- 0x1FF6, 0x0157, 0x040B, 0x0284, 0x0024,
- 0x1FF5, 0x0140, 0x0401, 0x029E, 0x002C,
- 0x1FF4, 0x012A, 0x03F6, 0x02B7, 0x0035,
- 0x1FF4, 0x0115, 0x03E9, 0x02D0, 0x003E,
- 0x1FF4, 0x0100, 0x03DB, 0x02E9, 0x0048,
- 0x1FF4, 0x00EC, 0x03CC, 0x0301, 0x0053,
- 0x1FF4, 0x00D9, 0x03BC, 0x0318, 0x005F,
- 0x1FF5, 0x00C7, 0x03AA, 0x032F, 0x006B,
- 0x1FF6, 0x00B5, 0x0398, 0x0345, 0x0078,
- 0x1FF6, 0x00A5, 0x0384, 0x035B, 0x0086,
- 0x0094, 0x036C, 0x036C, 0x0094, 0x0000,
- 0x0086, 0x035B, 0x0384, 0x00A5, 0x1FF6,
- 0x0078, 0x0345, 0x0398, 0x00B5, 0x1FF6,
- 0x006B, 0x032F, 0x03AA, 0x00C7, 0x1FF5,
- 0x005F, 0x0318, 0x03BC, 0x00D9, 0x1FF4,
- 0x0053, 0x0301, 0x03CC, 0x00EC, 0x1FF4,
- 0x0048, 0x02E9, 0x03DB, 0x0100, 0x1FF4,
- 0x003E, 0x02D0, 0x03E9, 0x0115, 0x1FF4,
- 0x0035, 0x02B7, 0x03F6, 0x012A, 0x1FF4,
- 0x002C, 0x029E, 0x0401, 0x0140, 0x1FF5,
- 0x0024, 0x0284, 0x040B, 0x0157, 0x1FF6,
- 0x001D, 0x026A, 0x0414, 0x016E, 0x1FF7,
- 0x0017, 0x0250, 0x041A, 0x0186, 0x1FF9,
- 0x0011, 0x0236, 0x0420, 0x019E, 0x1FFB,
- 0x000C, 0x021C, 0x0424, 0x01B7, 0x1FFD,
- 0x0007, 0x0203, 0x0426, 0x01D0, 0x0000,
- },
- [VS_LT_11_16_SCALE] = {
- /* Luma */
- 0x1FEC, 0x01D6, 0x047C, 0x01D6, 0x1FEC,
- 0x1FEA, 0x01BA, 0x047B, 0x01F3, 0x1FEE,
- 0x1FE9, 0x019D, 0x0478, 0x0211, 0x1FF1,
- 0x1FE8, 0x0182, 0x0473, 0x022E, 0x1FF5,
- 0x1FE8, 0x0167, 0x046C, 0x024C, 0x1FF9,
- 0x1FE8, 0x014D, 0x0464, 0x026A, 0x1FFD,
- 0x1FE8, 0x0134, 0x0459, 0x0288, 0x0003,
- 0x1FE9, 0x011B, 0x044D, 0x02A6, 0x0009,
- 0x1FE9, 0x0104, 0x0440, 0x02C3, 0x0010,
- 0x1FEA, 0x00ED, 0x0430, 0x02E1, 0x0018,
- 0x1FEB, 0x00D7, 0x0420, 0x02FD, 0x0021,
- 0x1FED, 0x00C2, 0x040D, 0x0319, 0x002B,
- 0x1FEE, 0x00AE, 0x03F9, 0x0336, 0x0035,
- 0x1FF0, 0x009C, 0x03E3, 0x0350, 0x0041,
- 0x1FF1, 0x008A, 0x03CD, 0x036B, 0x004D,
- 0x1FF3, 0x0079, 0x03B5, 0x0384, 0x005B,
- 0x0069, 0x0397, 0x0397, 0x0069, 0x0000,
- 0x005B, 0x0384, 0x03B5, 0x0079, 0x1FF3,
- 0x004D, 0x036B, 0x03CD, 0x008A, 0x1FF1,
- 0x0041, 0x0350, 0x03E3, 0x009C, 0x1FF0,
- 0x0035, 0x0336, 0x03F9, 0x00AE, 0x1FEE,
- 0x002B, 0x0319, 0x040D, 0x00C2, 0x1FED,
- 0x0021, 0x02FD, 0x0420, 0x00D7, 0x1FEB,
- 0x0018, 0x02E1, 0x0430, 0x00ED, 0x1FEA,
- 0x0010, 0x02C3, 0x0440, 0x0104, 0x1FE9,
- 0x0009, 0x02A6, 0x044D, 0x011B, 0x1FE9,
- 0x0003, 0x0288, 0x0459, 0x0134, 0x1FE8,
- 0x1FFD, 0x026A, 0x0464, 0x014D, 0x1FE8,
- 0x1FF9, 0x024C, 0x046C, 0x0167, 0x1FE8,
- 0x1FF5, 0x022E, 0x0473, 0x0182, 0x1FE8,
- 0x1FF1, 0x0211, 0x0478, 0x019D, 0x1FE9,
- 0x1FEE, 0x01F3, 0x047B, 0x01BA, 0x1FEA,
- /* Chroma */
- 0x1FEC, 0x01D6, 0x047C, 0x01D6, 0x1FEC,
- 0x1FEA, 0x01BA, 0x047B, 0x01F3, 0x1FEE,
- 0x1FE9, 0x019D, 0x0478, 0x0211, 0x1FF1,
- 0x1FE8, 0x0182, 0x0473, 0x022E, 0x1FF5,
- 0x1FE8, 0x0167, 0x046C, 0x024C, 0x1FF9,
- 0x1FE8, 0x014D, 0x0464, 0x026A, 0x1FFD,
- 0x1FE8, 0x0134, 0x0459, 0x0288, 0x0003,
- 0x1FE9, 0x011B, 0x044D, 0x02A6, 0x0009,
- 0x1FE9, 0x0104, 0x0440, 0x02C3, 0x0010,
- 0x1FEA, 0x00ED, 0x0430, 0x02E1, 0x0018,
- 0x1FEB, 0x00D7, 0x0420, 0x02FD, 0x0021,
- 0x1FED, 0x00C2, 0x040D, 0x0319, 0x002B,
- 0x1FEE, 0x00AE, 0x03F9, 0x0336, 0x0035,
- 0x1FF0, 0x009C, 0x03E3, 0x0350, 0x0041,
- 0x1FF1, 0x008A, 0x03CD, 0x036B, 0x004D,
- 0x1FF3, 0x0079, 0x03B5, 0x0384, 0x005B,
- 0x0069, 0x0397, 0x0397, 0x0069, 0x0000,
- 0x005B, 0x0384, 0x03B5, 0x0079, 0x1FF3,
- 0x004D, 0x036B, 0x03CD, 0x008A, 0x1FF1,
- 0x0041, 0x0350, 0x03E3, 0x009C, 0x1FF0,
- 0x0035, 0x0336, 0x03F9, 0x00AE, 0x1FEE,
- 0x002B, 0x0319, 0x040D, 0x00C2, 0x1FED,
- 0x0021, 0x02FD, 0x0420, 0x00D7, 0x1FEB,
- 0x0018, 0x02E1, 0x0430, 0x00ED, 0x1FEA,
- 0x0010, 0x02C3, 0x0440, 0x0104, 0x1FE9,
- 0x0009, 0x02A6, 0x044D, 0x011B, 0x1FE9,
- 0x0003, 0x0288, 0x0459, 0x0134, 0x1FE8,
- 0x1FFD, 0x026A, 0x0464, 0x014D, 0x1FE8,
- 0x1FF9, 0x024C, 0x046C, 0x0167, 0x1FE8,
- 0x1FF5, 0x022E, 0x0473, 0x0182, 0x1FE8,
- 0x1FF1, 0x0211, 0x0478, 0x019D, 0x1FE9,
- 0x1FEE, 0x01F3, 0x047B, 0x01BA, 0x1FEA,
- },
- [VS_LT_12_16_SCALE] = {
- /* Luma */
- 0x1FD8, 0x01BC, 0x04D8, 0x01BC, 0x1FD8,
- 0x1FD8, 0x019C, 0x04D8, 0x01DC, 0x1FD8,
- 0x1FD8, 0x017D, 0x04D4, 0x01FE, 0x1FD9,
- 0x1FD9, 0x015E, 0x04CF, 0x0220, 0x1FDA,
- 0x1FDB, 0x0141, 0x04C7, 0x0241, 0x1FDC,
- 0x1FDC, 0x0125, 0x04BC, 0x0264, 0x1FDF,
- 0x1FDE, 0x0109, 0x04B0, 0x0286, 0x1FE3,
- 0x1FE0, 0x00EF, 0x04A1, 0x02A9, 0x1FE7,
- 0x1FE2, 0x00D6, 0x0491, 0x02CB, 0x1FEC,
- 0x1FE4, 0x00BE, 0x047E, 0x02EE, 0x1FF2,
- 0x1FE6, 0x00A7, 0x046A, 0x030F, 0x1FFA,
- 0x1FE9, 0x0092, 0x0453, 0x0330, 0x0002,
- 0x1FEB, 0x007E, 0x043B, 0x0351, 0x000B,
- 0x1FED, 0x006B, 0x0421, 0x0372, 0x0015,
- 0x1FEF, 0x005A, 0x0406, 0x0391, 0x0020,
- 0x1FF1, 0x0049, 0x03EA, 0x03AF, 0x002D,
- 0x003A, 0x03C6, 0x03C6, 0x003A, 0x0000,
- 0x002D, 0x03AF, 0x03EA, 0x0049, 0x1FF1,
- 0x0020, 0x0391, 0x0406, 0x005A, 0x1FEF,
- 0x0015, 0x0372, 0x0421, 0x006B, 0x1FED,
- 0x000B, 0x0351, 0x043B, 0x007E, 0x1FEB,
- 0x0002, 0x0330, 0x0453, 0x0092, 0x1FE9,
- 0x1FFA, 0x030F, 0x046A, 0x00A7, 0x1FE6,
- 0x1FF2, 0x02EE, 0x047E, 0x00BE, 0x1FE4,
- 0x1FEC, 0x02CB, 0x0491, 0x00D6, 0x1FE2,
- 0x1FE7, 0x02A9, 0x04A1, 0x00EF, 0x1FE0,
- 0x1FE3, 0x0286, 0x04B0, 0x0109, 0x1FDE,
- 0x1FDF, 0x0264, 0x04BC, 0x0125, 0x1FDC,
- 0x1FDC, 0x0241, 0x04C7, 0x0141, 0x1FDB,
- 0x1FDA, 0x0220, 0x04CF, 0x015E, 0x1FD9,
- 0x1FD9, 0x01FE, 0x04D4, 0x017D, 0x1FD8,
- 0x1FD8, 0x01DC, 0x04D8, 0x019C, 0x1FD8,
- /* Chroma */
- 0x1FD8, 0x01BC, 0x04D8, 0x01BC, 0x1FD8,
- 0x1FD8, 0x019C, 0x04D8, 0x01DC, 0x1FD8,
- 0x1FD8, 0x017D, 0x04D4, 0x01FE, 0x1FD9,
- 0x1FD9, 0x015E, 0x04CF, 0x0220, 0x1FDA,
- 0x1FDB, 0x0141, 0x04C7, 0x0241, 0x1FDC,
- 0x1FDC, 0x0125, 0x04BC, 0x0264, 0x1FDF,
- 0x1FDE, 0x0109, 0x04B0, 0x0286, 0x1FE3,
- 0x1FE0, 0x00EF, 0x04A1, 0x02A9, 0x1FE7,
- 0x1FE2, 0x00D6, 0x0491, 0x02CB, 0x1FEC,
- 0x1FE4, 0x00BE, 0x047E, 0x02EE, 0x1FF2,
- 0x1FE6, 0x00A7, 0x046A, 0x030F, 0x1FFA,
- 0x1FE9, 0x0092, 0x0453, 0x0330, 0x0002,
- 0x1FEB, 0x007E, 0x043B, 0x0351, 0x000B,
- 0x1FED, 0x006B, 0x0421, 0x0372, 0x0015,
- 0x1FEF, 0x005A, 0x0406, 0x0391, 0x0020,
- 0x1FF1, 0x0049, 0x03EA, 0x03AF, 0x002D,
- 0x003A, 0x03C6, 0x03C6, 0x003A, 0x0000,
- 0x002D, 0x03AF, 0x03EA, 0x0049, 0x1FF1,
- 0x0020, 0x0391, 0x0406, 0x005A, 0x1FEF,
- 0x0015, 0x0372, 0x0421, 0x006B, 0x1FED,
- 0x000B, 0x0351, 0x043B, 0x007E, 0x1FEB,
- 0x0002, 0x0330, 0x0453, 0x0092, 0x1FE9,
- 0x1FFA, 0x030F, 0x046A, 0x00A7, 0x1FE6,
- 0x1FF2, 0x02EE, 0x047E, 0x00BE, 0x1FE4,
- 0x1FEC, 0x02CB, 0x0491, 0x00D6, 0x1FE2,
- 0x1FE7, 0x02A9, 0x04A1, 0x00EF, 0x1FE0,
- 0x1FE3, 0x0286, 0x04B0, 0x0109, 0x1FDE,
- 0x1FDF, 0x0264, 0x04BC, 0x0125, 0x1FDC,
- 0x1FDC, 0x0241, 0x04C7, 0x0141, 0x1FDB,
- 0x1FDA, 0x0220, 0x04CF, 0x015E, 0x1FD9,
- 0x1FD9, 0x01FE, 0x04D4, 0x017D, 0x1FD8,
- 0x1FD8, 0x01DC, 0x04D8, 0x019C, 0x1FD8,
- },
- [VS_LT_13_16_SCALE] = {
- /* Luma */
- 0x1FC8, 0x0199, 0x053E, 0x0199, 0x1FC8,
- 0x1FCA, 0x0175, 0x053E, 0x01BD, 0x1FC6,
- 0x1FCD, 0x0153, 0x0539, 0x01E2, 0x1FC5,
- 0x1FCF, 0x0132, 0x0532, 0x0209, 0x1FC4,
- 0x1FD2, 0x0112, 0x0529, 0x022F, 0x1FC4,
- 0x1FD5, 0x00F4, 0x051C, 0x0256, 0x1FC5,
- 0x1FD8, 0x00D7, 0x050D, 0x027E, 0x1FC6,
- 0x1FDC, 0x00BB, 0x04FB, 0x02A6, 0x1FC8,
- 0x1FDF, 0x00A1, 0x04E7, 0x02CE, 0x1FCB,
- 0x1FE2, 0x0089, 0x04D1, 0x02F5, 0x1FCF,
- 0x1FE5, 0x0072, 0x04B8, 0x031D, 0x1FD4,
- 0x1FE8, 0x005D, 0x049E, 0x0344, 0x1FD9,
- 0x1FEB, 0x0049, 0x0480, 0x036B, 0x1FE1,
- 0x1FEE, 0x0037, 0x0462, 0x0390, 0x1FE9,
- 0x1FF0, 0x0026, 0x0442, 0x03B6, 0x1FF2,
- 0x1FF2, 0x0017, 0x0420, 0x03DA, 0x1FFD,
- 0x0009, 0x03F7, 0x03F7, 0x0009, 0x0000,
- 0x1FFD, 0x03DA, 0x0420, 0x0017, 0x1FF2,
- 0x1FF2, 0x03B6, 0x0442, 0x0026, 0x1FF0,
- 0x1FE9, 0x0390, 0x0462, 0x0037, 0x1FEE,
- 0x1FE1, 0x036B, 0x0480, 0x0049, 0x1FEB,
- 0x1FD9, 0x0344, 0x049E, 0x005D, 0x1FE8,
- 0x1FD4, 0x031D, 0x04B8, 0x0072, 0x1FE5,
- 0x1FCF, 0x02F5, 0x04D1, 0x0089, 0x1FE2,
- 0x1FCB, 0x02CE, 0x04E7, 0x00A1, 0x1FDF,
- 0x1FC8, 0x02A6, 0x04FB, 0x00BB, 0x1FDC,
- 0x1FC6, 0x027E, 0x050D, 0x00D7, 0x1FD8,
- 0x1FC5, 0x0256, 0x051C, 0x00F4, 0x1FD5,
- 0x1FC4, 0x022F, 0x0529, 0x0112, 0x1FD2,
- 0x1FC4, 0x0209, 0x0532, 0x0132, 0x1FCF,
- 0x1FC5, 0x01E2, 0x0539, 0x0153, 0x1FCD,
- 0x1FC6, 0x01BD, 0x053E, 0x0175, 0x1FCA,
- /* Chroma */
- 0x1FC8, 0x0199, 0x053E, 0x0199, 0x1FC8,
- 0x1FCA, 0x0175, 0x053E, 0x01BD, 0x1FC6,
- 0x1FCD, 0x0153, 0x0539, 0x01E2, 0x1FC5,
- 0x1FCF, 0x0132, 0x0532, 0x0209, 0x1FC4,
- 0x1FD2, 0x0112, 0x0529, 0x022F, 0x1FC4,
- 0x1FD5, 0x00F4, 0x051C, 0x0256, 0x1FC5,
- 0x1FD8, 0x00D7, 0x050D, 0x027E, 0x1FC6,
- 0x1FDC, 0x00BB, 0x04FB, 0x02A6, 0x1FC8,
- 0x1FDF, 0x00A1, 0x04E7, 0x02CE, 0x1FCB,
- 0x1FE2, 0x0089, 0x04D1, 0x02F5, 0x1FCF,
- 0x1FE5, 0x0072, 0x04B8, 0x031D, 0x1FD4,
- 0x1FE8, 0x005D, 0x049E, 0x0344, 0x1FD9,
- 0x1FEB, 0x0049, 0x0480, 0x036B, 0x1FE1,
- 0x1FEE, 0x0037, 0x0462, 0x0390, 0x1FE9,
- 0x1FF0, 0x0026, 0x0442, 0x03B6, 0x1FF2,
- 0x1FF2, 0x0017, 0x0420, 0x03DA, 0x1FFD,
- 0x0009, 0x03F7, 0x03F7, 0x0009, 0x0000,
- 0x1FFD, 0x03DA, 0x0420, 0x0017, 0x1FF2,
- 0x1FF2, 0x03B6, 0x0442, 0x0026, 0x1FF0,
- 0x1FE9, 0x0390, 0x0462, 0x0037, 0x1FEE,
- 0x1FE1, 0x036B, 0x0480, 0x0049, 0x1FEB,
- 0x1FD9, 0x0344, 0x049E, 0x005D, 0x1FE8,
- 0x1FD4, 0x031D, 0x04B8, 0x0072, 0x1FE5,
- 0x1FCF, 0x02F5, 0x04D1, 0x0089, 0x1FE2,
- 0x1FCB, 0x02CE, 0x04E7, 0x00A1, 0x1FDF,
- 0x1FC8, 0x02A6, 0x04FB, 0x00BB, 0x1FDC,
- 0x1FC6, 0x027E, 0x050D, 0x00D7, 0x1FD8,
- 0x1FC5, 0x0256, 0x051C, 0x00F4, 0x1FD5,
- 0x1FC4, 0x022F, 0x0529, 0x0112, 0x1FD2,
- 0x1FC4, 0x0209, 0x0532, 0x0132, 0x1FCF,
- 0x1FC5, 0x01E2, 0x0539, 0x0153, 0x1FCD,
- 0x1FC6, 0x01BD, 0x053E, 0x0175, 0x1FCA,
- },
- [VS_LT_14_16_SCALE] = {
- /* Luma */
- 0x1FBF, 0x016C, 0x05AA, 0x016C, 0x1FBF,
- 0x1FC3, 0x0146, 0x05A8, 0x0194, 0x1FBB,
- 0x1FC7, 0x0121, 0x05A3, 0x01BD, 0x1FB8,
- 0x1FCB, 0x00FD, 0x059B, 0x01E8, 0x1FB5,
- 0x1FD0, 0x00DC, 0x058F, 0x0213, 0x1FB2,
- 0x1FD4, 0x00BC, 0x0580, 0x0240, 0x1FB0,
- 0x1FD8, 0x009E, 0x056E, 0x026D, 0x1FAF,
- 0x1FDC, 0x0082, 0x055A, 0x029A, 0x1FAE,
- 0x1FE0, 0x0067, 0x0542, 0x02C9, 0x1FAE,
- 0x1FE4, 0x004F, 0x0528, 0x02F6, 0x1FAF,
- 0x1FE8, 0x0038, 0x050A, 0x0325, 0x1FB1,
- 0x1FEB, 0x0024, 0x04EB, 0x0352, 0x1FB4,
- 0x1FEE, 0x0011, 0x04C8, 0x0380, 0x1FB9,
- 0x1FF1, 0x0000, 0x04A4, 0x03AC, 0x1FBF,
- 0x1FF4, 0x1FF1, 0x047D, 0x03D8, 0x1FC6,
- 0x1FF6, 0x1FE4, 0x0455, 0x0403, 0x1FCE,
- 0x1FD8, 0x0428, 0x0428, 0x1FD8, 0x0000,
- 0x1FCE, 0x0403, 0x0455, 0x1FE4, 0x1FF6,
- 0x1FC6, 0x03D8, 0x047D, 0x1FF1, 0x1FF4,
- 0x1FBF, 0x03AC, 0x04A4, 0x0000, 0x1FF1,
- 0x1FB9, 0x0380, 0x04C8, 0x0011, 0x1FEE,
- 0x1FB4, 0x0352, 0x04EB, 0x0024, 0x1FEB,
- 0x1FB1, 0x0325, 0x050A, 0x0038, 0x1FE8,
- 0x1FAF, 0x02F6, 0x0528, 0x004F, 0x1FE4,
- 0x1FAE, 0x02C9, 0x0542, 0x0067, 0x1FE0,
- 0x1FAE, 0x029A, 0x055A, 0x0082, 0x1FDC,
- 0x1FAF, 0x026D, 0x056E, 0x009E, 0x1FD8,
- 0x1FB0, 0x0240, 0x0580, 0x00BC, 0x1FD4,
- 0x1FB2, 0x0213, 0x058F, 0x00DC, 0x1FD0,
- 0x1FB5, 0x01E8, 0x059B, 0x00FD, 0x1FCB,
- 0x1FB8, 0x01BD, 0x05A3, 0x0121, 0x1FC7,
- 0x1FBB, 0x0194, 0x05A8, 0x0146, 0x1FC3,
- /* Chroma */
- 0x1FBF, 0x016C, 0x05AA, 0x016C, 0x1FBF,
- 0x1FC3, 0x0146, 0x05A8, 0x0194, 0x1FBB,
- 0x1FC7, 0x0121, 0x05A3, 0x01BD, 0x1FB8,
- 0x1FCB, 0x00FD, 0x059B, 0x01E8, 0x1FB5,
- 0x1FD0, 0x00DC, 0x058F, 0x0213, 0x1FB2,
- 0x1FD4, 0x00BC, 0x0580, 0x0240, 0x1FB0,
- 0x1FD8, 0x009E, 0x056E, 0x026D, 0x1FAF,
- 0x1FDC, 0x0082, 0x055A, 0x029A, 0x1FAE,
- 0x1FE0, 0x0067, 0x0542, 0x02C9, 0x1FAE,
- 0x1FE4, 0x004F, 0x0528, 0x02F6, 0x1FAF,
- 0x1FE8, 0x0038, 0x050A, 0x0325, 0x1FB1,
- 0x1FEB, 0x0024, 0x04EB, 0x0352, 0x1FB4,
- 0x1FEE, 0x0011, 0x04C8, 0x0380, 0x1FB9,
- 0x1FF1, 0x0000, 0x04A4, 0x03AC, 0x1FBF,
- 0x1FF4, 0x1FF1, 0x047D, 0x03D8, 0x1FC6,
- 0x1FF6, 0x1FE4, 0x0455, 0x0403, 0x1FCE,
- 0x1FD8, 0x0428, 0x0428, 0x1FD8, 0x0000,
- 0x1FCE, 0x0403, 0x0455, 0x1FE4, 0x1FF6,
- 0x1FC6, 0x03D8, 0x047D, 0x1FF1, 0x1FF4,
- 0x1FBF, 0x03AC, 0x04A4, 0x0000, 0x1FF1,
- 0x1FB9, 0x0380, 0x04C8, 0x0011, 0x1FEE,
- 0x1FB4, 0x0352, 0x04EB, 0x0024, 0x1FEB,
- 0x1FB1, 0x0325, 0x050A, 0x0038, 0x1FE8,
- 0x1FAF, 0x02F6, 0x0528, 0x004F, 0x1FE4,
- 0x1FAE, 0x02C9, 0x0542, 0x0067, 0x1FE0,
- 0x1FAE, 0x029A, 0x055A, 0x0082, 0x1FDC,
- 0x1FAF, 0x026D, 0x056E, 0x009E, 0x1FD8,
- 0x1FB0, 0x0240, 0x0580, 0x00BC, 0x1FD4,
- 0x1FB2, 0x0213, 0x058F, 0x00DC, 0x1FD0,
- 0x1FB5, 0x01E8, 0x059B, 0x00FD, 0x1FCB,
- 0x1FB8, 0x01BD, 0x05A3, 0x0121, 0x1FC7,
- 0x1FBB, 0x0194, 0x05A8, 0x0146, 0x1FC3,
- },
- [VS_LT_15_16_SCALE] = {
- /* Luma */
- 0x1FBD, 0x0136, 0x061A, 0x0136, 0x1FBD,
- 0x1FC3, 0x010D, 0x0617, 0x0161, 0x1FB8,
- 0x1FC9, 0x00E6, 0x0611, 0x018E, 0x1FB2,
- 0x1FCE, 0x00C1, 0x0607, 0x01BD, 0x1FAD,
- 0x1FD4, 0x009E, 0x05F9, 0x01ED, 0x1FA8,
- 0x1FD9, 0x007D, 0x05E8, 0x021F, 0x1FA3,
- 0x1FDE, 0x005E, 0x05D3, 0x0252, 0x1F9F,
- 0x1FE2, 0x0042, 0x05BC, 0x0285, 0x1F9B,
- 0x1FE7, 0x0029, 0x059F, 0x02B9, 0x1F98,
- 0x1FEA, 0x0011, 0x0580, 0x02EF, 0x1F96,
- 0x1FEE, 0x1FFC, 0x055D, 0x0324, 0x1F95,
- 0x1FF1, 0x1FE9, 0x0538, 0x0359, 0x1F95,
- 0x1FF4, 0x1FD8, 0x0510, 0x038E, 0x1F96,
- 0x1FF7, 0x1FC9, 0x04E5, 0x03C2, 0x1F99,
- 0x1FF9, 0x1FBD, 0x04B8, 0x03F5, 0x1F9D,
- 0x1FFB, 0x1FB2, 0x0489, 0x0428, 0x1FA2,
- 0x1FAA, 0x0456, 0x0456, 0x1FAA, 0x0000,
- 0x1FA2, 0x0428, 0x0489, 0x1FB2, 0x1FFB,
- 0x1F9D, 0x03F5, 0x04B8, 0x1FBD, 0x1FF9,
- 0x1F99, 0x03C2, 0x04E5, 0x1FC9, 0x1FF7,
- 0x1F96, 0x038E, 0x0510, 0x1FD8, 0x1FF4,
- 0x1F95, 0x0359, 0x0538, 0x1FE9, 0x1FF1,
- 0x1F95, 0x0324, 0x055D, 0x1FFC, 0x1FEE,
- 0x1F96, 0x02EF, 0x0580, 0x0011, 0x1FEA,
- 0x1F98, 0x02B9, 0x059F, 0x0029, 0x1FE7,
- 0x1F9B, 0x0285, 0x05BC, 0x0042, 0x1FE2,
- 0x1F9F, 0x0252, 0x05D3, 0x005E, 0x1FDE,
- 0x1FA3, 0x021F, 0x05E8, 0x007D, 0x1FD9,
- 0x1FA8, 0x01ED, 0x05F9, 0x009E, 0x1FD4,
- 0x1FAD, 0x01BD, 0x0607, 0x00C1, 0x1FCE,
- 0x1FB2, 0x018E, 0x0611, 0x00E6, 0x1FC9,
- 0x1FB8, 0x0161, 0x0617, 0x010D, 0x1FC3,
- /* Chroma */
- 0x1FBD, 0x0136, 0x061A, 0x0136, 0x1FBD,
- 0x1FC3, 0x010D, 0x0617, 0x0161, 0x1FB8,
- 0x1FC9, 0x00E6, 0x0611, 0x018E, 0x1FB2,
- 0x1FCE, 0x00C1, 0x0607, 0x01BD, 0x1FAD,
- 0x1FD4, 0x009E, 0x05F9, 0x01ED, 0x1FA8,
- 0x1FD9, 0x007D, 0x05E8, 0x021F, 0x1FA3,
- 0x1FDE, 0x005E, 0x05D3, 0x0252, 0x1F9F,
- 0x1FE2, 0x0042, 0x05BC, 0x0285, 0x1F9B,
- 0x1FE7, 0x0029, 0x059F, 0x02B9, 0x1F98,
- 0x1FEA, 0x0011, 0x0580, 0x02EF, 0x1F96,
- 0x1FEE, 0x1FFC, 0x055D, 0x0324, 0x1F95,
- 0x1FF1, 0x1FE9, 0x0538, 0x0359, 0x1F95,
- 0x1FF4, 0x1FD8, 0x0510, 0x038E, 0x1F96,
- 0x1FF7, 0x1FC9, 0x04E5, 0x03C2, 0x1F99,
- 0x1FF9, 0x1FBD, 0x04B8, 0x03F5, 0x1F9D,
- 0x1FFB, 0x1FB2, 0x0489, 0x0428, 0x1FA2,
- 0x1FAA, 0x0456, 0x0456, 0x1FAA, 0x0000,
- 0x1FA2, 0x0428, 0x0489, 0x1FB2, 0x1FFB,
- 0x1F9D, 0x03F5, 0x04B8, 0x1FBD, 0x1FF9,
- 0x1F99, 0x03C2, 0x04E5, 0x1FC9, 0x1FF7,
- 0x1F96, 0x038E, 0x0510, 0x1FD8, 0x1FF4,
- 0x1F95, 0x0359, 0x0538, 0x1FE9, 0x1FF1,
- 0x1F95, 0x0324, 0x055D, 0x1FFC, 0x1FEE,
- 0x1F96, 0x02EF, 0x0580, 0x0011, 0x1FEA,
- 0x1F98, 0x02B9, 0x059F, 0x0029, 0x1FE7,
- 0x1F9B, 0x0285, 0x05BC, 0x0042, 0x1FE2,
- 0x1F9F, 0x0252, 0x05D3, 0x005E, 0x1FDE,
- 0x1FA3, 0x021F, 0x05E8, 0x007D, 0x1FD9,
- 0x1FA8, 0x01ED, 0x05F9, 0x009E, 0x1FD4,
- 0x1FAD, 0x01BD, 0x0607, 0x00C1, 0x1FCE,
- 0x1FB2, 0x018E, 0x0611, 0x00E6, 0x1FC9,
- 0x1FB8, 0x0161, 0x0617, 0x010D, 0x1FC3,
- },
- [VS_LT_16_16_SCALE] = {
- /* Luma */
- 0x1FC3, 0x00F8, 0x068A, 0x00F8, 0x1FC3,
- 0x1FCA, 0x00CC, 0x0689, 0x0125, 0x1FBC,
- 0x1FD1, 0x00A3, 0x0681, 0x0156, 0x1FB5,
- 0x1FD7, 0x007D, 0x0676, 0x0188, 0x1FAE,
- 0x1FDD, 0x005A, 0x0666, 0x01BD, 0x1FA6,
- 0x1FE3, 0x0039, 0x0652, 0x01F3, 0x1F9F,
- 0x1FE8, 0x001B, 0x0639, 0x022C, 0x1F98,
- 0x1FEC, 0x0000, 0x061D, 0x0265, 0x1F92,
- 0x1FF0, 0x1FE8, 0x05FC, 0x02A0, 0x1F8C,
- 0x1FF4, 0x1FD2, 0x05D7, 0x02DC, 0x1F87,
- 0x1FF7, 0x1FBF, 0x05AF, 0x0319, 0x1F82,
- 0x1FFA, 0x1FAF, 0x0583, 0x0356, 0x1F7E,
- 0x1FFC, 0x1FA1, 0x0554, 0x0393, 0x1F7C,
- 0x1FFE, 0x1F95, 0x0523, 0x03CF, 0x1F7B,
- 0x0000, 0x1F8C, 0x04EE, 0x040B, 0x1F7B,
- 0x0001, 0x1F85, 0x04B8, 0x0446, 0x1F7C,
- 0x1F80, 0x0480, 0x0480, 0x1F80, 0x0000,
- 0x1F7C, 0x0446, 0x04B8, 0x1F85, 0x0001,
- 0x1F7B, 0x040B, 0x04EE, 0x1F8C, 0x0000,
- 0x1F7B, 0x03CF, 0x0523, 0x1F95, 0x1FFE,
- 0x1F7C, 0x0393, 0x0554, 0x1FA1, 0x1FFC,
- 0x1F7E, 0x0356, 0x0583, 0x1FAF, 0x1FFA,
- 0x1F82, 0x0319, 0x05AF, 0x1FBF, 0x1FF7,
- 0x1F87, 0x02DC, 0x05D7, 0x1FD2, 0x1FF4,
- 0x1F8C, 0x02A0, 0x05FC, 0x1FE8, 0x1FF0,
- 0x1F92, 0x0265, 0x061D, 0x0000, 0x1FEC,
- 0x1F98, 0x022C, 0x0639, 0x001B, 0x1FE8,
- 0x1F9F, 0x01F3, 0x0652, 0x0039, 0x1FE3,
- 0x1FA6, 0x01BD, 0x0666, 0x005A, 0x1FDD,
- 0x1FAE, 0x0188, 0x0676, 0x007D, 0x1FD7,
- 0x1FB5, 0x0156, 0x0681, 0x00A3, 0x1FD1,
- 0x1FBC, 0x0125, 0x0689, 0x00CC, 0x1FCA,
- /* Chroma */
- 0x1FC3, 0x00F8, 0x068A, 0x00F8, 0x1FC3,
- 0x1FCA, 0x00CC, 0x0689, 0x0125, 0x1FBC,
- 0x1FD1, 0x00A3, 0x0681, 0x0156, 0x1FB5,
- 0x1FD7, 0x007D, 0x0676, 0x0188, 0x1FAE,
- 0x1FDD, 0x005A, 0x0666, 0x01BD, 0x1FA6,
- 0x1FE3, 0x0039, 0x0652, 0x01F3, 0x1F9F,
- 0x1FE8, 0x001B, 0x0639, 0x022C, 0x1F98,
- 0x1FEC, 0x0000, 0x061D, 0x0265, 0x1F92,
- 0x1FF0, 0x1FE8, 0x05FC, 0x02A0, 0x1F8C,
- 0x1FF4, 0x1FD2, 0x05D7, 0x02DC, 0x1F87,
- 0x1FF7, 0x1FBF, 0x05AF, 0x0319, 0x1F82,
- 0x1FFA, 0x1FAF, 0x0583, 0x0356, 0x1F7E,
- 0x1FFC, 0x1FA1, 0x0554, 0x0393, 0x1F7C,
- 0x1FFE, 0x1F95, 0x0523, 0x03CF, 0x1F7B,
- 0x0000, 0x1F8C, 0x04EE, 0x040B, 0x1F7B,
- 0x0001, 0x1F85, 0x04B8, 0x0446, 0x1F7C,
- 0x1F80, 0x0480, 0x0480, 0x1F80, 0x0000,
- 0x1F7C, 0x0446, 0x04B8, 0x1F85, 0x0001,
- 0x1F7B, 0x040B, 0x04EE, 0x1F8C, 0x0000,
- 0x1F7B, 0x03CF, 0x0523, 0x1F95, 0x1FFE,
- 0x1F7C, 0x0393, 0x0554, 0x1FA1, 0x1FFC,
- 0x1F7E, 0x0356, 0x0583, 0x1FAF, 0x1FFA,
- 0x1F82, 0x0319, 0x05AF, 0x1FBF, 0x1FF7,
- 0x1F87, 0x02DC, 0x05D7, 0x1FD2, 0x1FF4,
- 0x1F8C, 0x02A0, 0x05FC, 0x1FE8, 0x1FF0,
- 0x1F92, 0x0265, 0x061D, 0x0000, 0x1FEC,
- 0x1F98, 0x022C, 0x0639, 0x001B, 0x1FE8,
- 0x1F9F, 0x01F3, 0x0652, 0x0039, 0x1FE3,
- 0x1FA6, 0x01BD, 0x0666, 0x005A, 0x1FDD,
- 0x1FAE, 0x0188, 0x0676, 0x007D, 0x1FD7,
- 0x1FB5, 0x0156, 0x0681, 0x00A3, 0x1FD1,
- 0x1FBC, 0x0125, 0x0689, 0x00CC, 0x1FCA,
- },
- [VS_1_TO_1_SCALE] = {
- /* Luma */
- 0x0000, 0x0000, 0x0800, 0x0000, 0x0000,
- 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
- 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
- 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
- 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
- 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
- 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
- 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
- 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
- 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
- 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
- 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
- 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
- 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
- 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
- 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
- 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
- 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
- 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
- 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
- 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
- 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
- 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
- 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
- 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
- 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
- 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
- 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
- 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
- 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
- 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
- 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
- /* Chroma */
- 0x0000, 0x0000, 0x0800, 0x0000, 0x0000,
- 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
- 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
- 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
- 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
- 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
- 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
- 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
- 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
- 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
- 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
- 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
- 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
- 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
- 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
- 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
- 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
- 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
- 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
- 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
- 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
- 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
- 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
- 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
- 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
- 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
- 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
- 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
- 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
- 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
- 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
- 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
- },
-};
-#endif
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
deleted file mode 100644
index f8998a8ad371..000000000000
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ /dev/null
@@ -1,1176 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * VPDMA helper library
- *
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "vpdma.h"
-#include "vpdma_priv.h"
-
-#define VPDMA_FIRMWARE "vpdma-1b8.bin"
-
-const struct vpdma_data_format vpdma_yuv_fmts[] = {
- [VPDMA_DATA_FMT_Y444] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_Y444,
- .depth = 8,
- },
- [VPDMA_DATA_FMT_Y422] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_Y422,
- .depth = 8,
- },
- [VPDMA_DATA_FMT_Y420] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_Y420,
- .depth = 8,
- },
- [VPDMA_DATA_FMT_C444] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_C444,
- .depth = 8,
- },
- [VPDMA_DATA_FMT_C422] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_C422,
- .depth = 8,
- },
- [VPDMA_DATA_FMT_C420] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_C420,
- .depth = 4,
- },
- [VPDMA_DATA_FMT_CB420] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_CB420,
- .depth = 4,
- },
- [VPDMA_DATA_FMT_YCR422] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_YCR422,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_YC444] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_YC444,
- .depth = 24,
- },
- [VPDMA_DATA_FMT_CRY422] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_CRY422,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_CBY422] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_CBY422,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_YCB422] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_YCB422,
- .depth = 16,
- },
-};
-EXPORT_SYMBOL(vpdma_yuv_fmts);
-
-const struct vpdma_data_format vpdma_rgb_fmts[] = {
- [VPDMA_DATA_FMT_RGB565] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_RGB16_565,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_ARGB16_1555] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_ARGB_1555,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_ARGB16] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_ARGB_4444,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_RGBA16_5551] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_RGBA_5551,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_RGBA16] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_RGBA_4444,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_ARGB24] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_ARGB24_6666,
- .depth = 24,
- },
- [VPDMA_DATA_FMT_RGB24] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_RGB24_888,
- .depth = 24,
- },
- [VPDMA_DATA_FMT_ARGB32] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_ARGB32_8888,
- .depth = 32,
- },
- [VPDMA_DATA_FMT_RGBA24] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_RGBA24_6666,
- .depth = 24,
- },
- [VPDMA_DATA_FMT_RGBA32] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_RGBA32_8888,
- .depth = 32,
- },
- [VPDMA_DATA_FMT_BGR565] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_BGR16_565,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_ABGR16_1555] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_ABGR_1555,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_ABGR16] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_ABGR_4444,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_BGRA16_5551] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_BGRA_5551,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_BGRA16] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_BGRA_4444,
- .depth = 16,
- },
- [VPDMA_DATA_FMT_ABGR24] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_ABGR24_6666,
- .depth = 24,
- },
- [VPDMA_DATA_FMT_BGR24] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_BGR24_888,
- .depth = 24,
- },
- [VPDMA_DATA_FMT_ABGR32] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_ABGR32_8888,
- .depth = 32,
- },
- [VPDMA_DATA_FMT_BGRA24] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_BGRA24_6666,
- .depth = 24,
- },
- [VPDMA_DATA_FMT_BGRA32] = {
- .type = VPDMA_DATA_FMT_TYPE_RGB,
- .data_type = DATA_TYPE_BGRA32_8888,
- .depth = 32,
- },
-};
-EXPORT_SYMBOL(vpdma_rgb_fmts);
-
-/*
- * To handle RAW format we are re-using the CBY422
- * vpdma data type so that we use the vpdma to re-order
- * the incoming bytes, as the parser assumes that the
- * first byte presented on the bus is the MSB of a 2
- * bytes value.
- * RAW8 handles from 1 to 8 bits
- * RAW16 handles from 9 to 16 bits
- */
-const struct vpdma_data_format vpdma_raw_fmts[] = {
- [VPDMA_DATA_FMT_RAW8] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_CBY422,
- .depth = 8,
- },
- [VPDMA_DATA_FMT_RAW16] = {
- .type = VPDMA_DATA_FMT_TYPE_YUV,
- .data_type = DATA_TYPE_CBY422,
- .depth = 16,
- },
-};
-EXPORT_SYMBOL(vpdma_raw_fmts);
-
-const struct vpdma_data_format vpdma_misc_fmts[] = {
- [VPDMA_DATA_FMT_MV] = {
- .type = VPDMA_DATA_FMT_TYPE_MISC,
- .data_type = DATA_TYPE_MV,
- .depth = 4,
- },
-};
-EXPORT_SYMBOL(vpdma_misc_fmts);
-
-struct vpdma_channel_info {
- int num; /* VPDMA channel number */
- int cstat_offset; /* client CSTAT register offset */
-};
-
-static const struct vpdma_channel_info chan_info[] = {
- [VPE_CHAN_LUMA1_IN] = {
- .num = VPE_CHAN_NUM_LUMA1_IN,
- .cstat_offset = VPDMA_DEI_LUMA1_CSTAT,
- },
- [VPE_CHAN_CHROMA1_IN] = {
- .num = VPE_CHAN_NUM_CHROMA1_IN,
- .cstat_offset = VPDMA_DEI_CHROMA1_CSTAT,
- },
- [VPE_CHAN_LUMA2_IN] = {
- .num = VPE_CHAN_NUM_LUMA2_IN,
- .cstat_offset = VPDMA_DEI_LUMA2_CSTAT,
- },
- [VPE_CHAN_CHROMA2_IN] = {
- .num = VPE_CHAN_NUM_CHROMA2_IN,
- .cstat_offset = VPDMA_DEI_CHROMA2_CSTAT,
- },
- [VPE_CHAN_LUMA3_IN] = {
- .num = VPE_CHAN_NUM_LUMA3_IN,
- .cstat_offset = VPDMA_DEI_LUMA3_CSTAT,
- },
- [VPE_CHAN_CHROMA3_IN] = {
- .num = VPE_CHAN_NUM_CHROMA3_IN,
- .cstat_offset = VPDMA_DEI_CHROMA3_CSTAT,
- },
- [VPE_CHAN_MV_IN] = {
- .num = VPE_CHAN_NUM_MV_IN,
- .cstat_offset = VPDMA_DEI_MV_IN_CSTAT,
- },
- [VPE_CHAN_MV_OUT] = {
- .num = VPE_CHAN_NUM_MV_OUT,
- .cstat_offset = VPDMA_DEI_MV_OUT_CSTAT,
- },
- [VPE_CHAN_LUMA_OUT] = {
- .num = VPE_CHAN_NUM_LUMA_OUT,
- .cstat_offset = VPDMA_VIP_UP_Y_CSTAT,
- },
- [VPE_CHAN_CHROMA_OUT] = {
- .num = VPE_CHAN_NUM_CHROMA_OUT,
- .cstat_offset = VPDMA_VIP_UP_UV_CSTAT,
- },
- [VPE_CHAN_RGB_OUT] = {
- .num = VPE_CHAN_NUM_RGB_OUT,
- .cstat_offset = VPDMA_VIP_UP_Y_CSTAT,
- },
-};
-
-static u32 read_reg(struct vpdma_data *vpdma, int offset)
-{
- return ioread32(vpdma->base + offset);
-}
-
-static void write_reg(struct vpdma_data *vpdma, int offset, u32 value)
-{
- iowrite32(value, vpdma->base + offset);
-}
-
-static int read_field_reg(struct vpdma_data *vpdma, int offset,
- u32 mask, int shift)
-{
- return (read_reg(vpdma, offset) & (mask << shift)) >> shift;
-}
-
-static void write_field_reg(struct vpdma_data *vpdma, int offset, u32 field,
- u32 mask, int shift)
-{
- u32 val = read_reg(vpdma, offset);
-
- val &= ~(mask << shift);
- val |= (field & mask) << shift;
-
- write_reg(vpdma, offset, val);
-}
-
-void vpdma_dump_regs(struct vpdma_data *vpdma)
-{
- struct device *dev = &vpdma->pdev->dev;
-
-#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(vpdma, VPDMA_##r))
-
- dev_dbg(dev, "VPDMA Registers:\n");
-
- DUMPREG(PID);
- DUMPREG(LIST_ADDR);
- DUMPREG(LIST_ATTR);
- DUMPREG(LIST_STAT_SYNC);
- DUMPREG(BG_RGB);
- DUMPREG(BG_YUV);
- DUMPREG(SETUP);
- DUMPREG(MAX_SIZE1);
- DUMPREG(MAX_SIZE2);
- DUMPREG(MAX_SIZE3);
-
- /*
- * dumping registers of only group0 and group3, because VPE channels
- * lie within group0 and group3 registers
- */
- DUMPREG(INT_CHAN_STAT(0));
- DUMPREG(INT_CHAN_MASK(0));
- DUMPREG(INT_CHAN_STAT(3));
- DUMPREG(INT_CHAN_MASK(3));
- DUMPREG(INT_CLIENT0_STAT);
- DUMPREG(INT_CLIENT0_MASK);
- DUMPREG(INT_CLIENT1_STAT);
- DUMPREG(INT_CLIENT1_MASK);
- DUMPREG(INT_LIST0_STAT);
- DUMPREG(INT_LIST0_MASK);
-
- /*
- * these are registers specific to VPE clients, we can make this
- * function dump client registers specific to VPE or VIP based on
- * who is using it
- */
- DUMPREG(DEI_CHROMA1_CSTAT);
- DUMPREG(DEI_LUMA1_CSTAT);
- DUMPREG(DEI_CHROMA2_CSTAT);
- DUMPREG(DEI_LUMA2_CSTAT);
- DUMPREG(DEI_CHROMA3_CSTAT);
- DUMPREG(DEI_LUMA3_CSTAT);
- DUMPREG(DEI_MV_IN_CSTAT);
- DUMPREG(DEI_MV_OUT_CSTAT);
- DUMPREG(VIP_UP_Y_CSTAT);
- DUMPREG(VIP_UP_UV_CSTAT);
- DUMPREG(VPI_CTL_CSTAT);
-}
-EXPORT_SYMBOL(vpdma_dump_regs);
-
-/*
- * Allocate a DMA buffer
- */
-int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size)
-{
- buf->size = size;
- buf->mapped = false;
- buf->addr = kzalloc(size, GFP_KERNEL);
- if (!buf->addr)
- return -ENOMEM;
-
- WARN_ON(((unsigned long)buf->addr & VPDMA_DESC_ALIGN) != 0);
-
- return 0;
-}
-EXPORT_SYMBOL(vpdma_alloc_desc_buf);
-
-void vpdma_free_desc_buf(struct vpdma_buf *buf)
-{
- WARN_ON(buf->mapped);
- kfree(buf->addr);
- buf->addr = NULL;
- buf->size = 0;
-}
-EXPORT_SYMBOL(vpdma_free_desc_buf);
-
-/*
- * map descriptor/payload DMA buffer, enabling DMA access
- */
-int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
-{
- struct device *dev = &vpdma->pdev->dev;
-
- WARN_ON(buf->mapped);
- buf->dma_addr = dma_map_single(dev, buf->addr, buf->size,
- DMA_BIDIRECTIONAL);
- if (dma_mapping_error(dev, buf->dma_addr)) {
- dev_err(dev, "failed to map buffer\n");
- return -EINVAL;
- }
-
- buf->mapped = true;
-
- return 0;
-}
-EXPORT_SYMBOL(vpdma_map_desc_buf);
-
-/*
- * unmap descriptor/payload DMA buffer, disabling DMA access and
- * allowing the main processor to access the data
- */
-void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
-{
- struct device *dev = &vpdma->pdev->dev;
-
- if (buf->mapped)
- dma_unmap_single(dev, buf->dma_addr, buf->size,
- DMA_BIDIRECTIONAL);
-
- buf->mapped = false;
-}
-EXPORT_SYMBOL(vpdma_unmap_desc_buf);
-
-/*
- * Cleanup all pending descriptors of a list
- * First, stop the current list being processed.
- * If the VPDMA was busy, this step makes vpdma to accept post lists.
- * To cleanup the internal FSM, post abort list descriptor for all the
- * channels from @channels array of size @size.
- */
-int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
- int *channels, int size)
-{
- struct vpdma_desc_list abort_list;
- int i, ret, timeout = 500;
-
- write_reg(vpdma, VPDMA_LIST_ATTR,
- (list_num << VPDMA_LIST_NUM_SHFT) |
- (1 << VPDMA_LIST_STOP_SHFT));
-
- if (size <= 0 || !channels)
- return 0;
-
- ret = vpdma_create_desc_list(&abort_list,
- size * sizeof(struct vpdma_dtd), VPDMA_LIST_TYPE_NORMAL);
- if (ret)
- return ret;
-
- for (i = 0; i < size; i++)
- vpdma_add_abort_channel_ctd(&abort_list, channels[i]);
-
- ret = vpdma_map_desc_buf(vpdma, &abort_list.buf);
- if (ret)
- goto free_desc;
- ret = vpdma_submit_descs(vpdma, &abort_list, list_num);
- if (ret)
- goto unmap_desc;
-
- while (vpdma_list_busy(vpdma, list_num) && --timeout)
- ;
-
- if (timeout == 0) {
- dev_err(&vpdma->pdev->dev, "Timed out cleaning up VPDMA list\n");
- ret = -EBUSY;
- }
-
-unmap_desc:
- vpdma_unmap_desc_buf(vpdma, &abort_list.buf);
-free_desc:
- vpdma_free_desc_buf(&abort_list.buf);
-
- return ret;
-}
-EXPORT_SYMBOL(vpdma_list_cleanup);
-
-/*
- * create a descriptor list, the user of this list will append configuration,
- * control and data descriptors to this list, this list will be submitted to
- * VPDMA. VPDMA's list parser will go through each descriptor and perform the
- * required DMA operations
- */
-int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type)
-{
- int r;
-
- r = vpdma_alloc_desc_buf(&list->buf, size);
- if (r)
- return r;
-
- list->next = list->buf.addr;
-
- list->type = type;
-
- return 0;
-}
-EXPORT_SYMBOL(vpdma_create_desc_list);
-
-/*
- * once a descriptor list is parsed by VPDMA, we reset the list by emptying it,
- * to allow new descriptors to be added to the list.
- */
-void vpdma_reset_desc_list(struct vpdma_desc_list *list)
-{
- list->next = list->buf.addr;
-}
-EXPORT_SYMBOL(vpdma_reset_desc_list);
-
-/*
- * free the buffer allocated for the VPDMA descriptor list, this should be
- * called when the user doesn't want to use VPDMA any more.
- */
-void vpdma_free_desc_list(struct vpdma_desc_list *list)
-{
- vpdma_free_desc_buf(&list->buf);
-
- list->next = NULL;
-}
-EXPORT_SYMBOL(vpdma_free_desc_list);
-
-bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num)
-{
- return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16);
-}
-EXPORT_SYMBOL(vpdma_list_busy);
-
-/*
- * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion
- */
-int vpdma_submit_descs(struct vpdma_data *vpdma,
- struct vpdma_desc_list *list, int list_num)
-{
- int list_size;
- unsigned long flags;
-
- if (vpdma_list_busy(vpdma, list_num))
- return -EBUSY;
-
- /* 16-byte granularity */
- list_size = (list->next - list->buf.addr) >> 4;
-
- spin_lock_irqsave(&vpdma->lock, flags);
- write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr);
-
- write_reg(vpdma, VPDMA_LIST_ATTR,
- (list_num << VPDMA_LIST_NUM_SHFT) |
- (list->type << VPDMA_LIST_TYPE_SHFT) |
- list_size);
- spin_unlock_irqrestore(&vpdma->lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL(vpdma_submit_descs);
-
-static void dump_dtd(struct vpdma_dtd *dtd);
-
-void vpdma_update_dma_addr(struct vpdma_data *vpdma,
- struct vpdma_desc_list *list, dma_addr_t dma_addr,
- void *write_dtd, int drop, int idx)
-{
- struct vpdma_dtd *dtd = list->buf.addr;
- dma_addr_t write_desc_addr;
- int offset;
-
- dtd += idx;
- vpdma_unmap_desc_buf(vpdma, &list->buf);
-
- dtd->start_addr = dma_addr;
-
- /* Calculate write address from the offset of write_dtd from start
- * of the list->buf
- */
- offset = (void *)write_dtd - list->buf.addr;
- write_desc_addr = list->buf.dma_addr + offset;
-
- if (drop)
- dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
- 1, 1, 0);
- else
- dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
- 1, 0, 0);
-
- vpdma_map_desc_buf(vpdma, &list->buf);
-
- dump_dtd(dtd);
-}
-EXPORT_SYMBOL(vpdma_update_dma_addr);
-
-void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
- u32 width, u32 height)
-{
- if (reg_addr != VPDMA_MAX_SIZE1 && reg_addr != VPDMA_MAX_SIZE2 &&
- reg_addr != VPDMA_MAX_SIZE3)
- reg_addr = VPDMA_MAX_SIZE1;
-
- write_field_reg(vpdma, reg_addr, width - 1,
- VPDMA_MAX_SIZE_WIDTH_MASK, VPDMA_MAX_SIZE_WIDTH_SHFT);
-
- write_field_reg(vpdma, reg_addr, height - 1,
- VPDMA_MAX_SIZE_HEIGHT_MASK, VPDMA_MAX_SIZE_HEIGHT_SHFT);
-
-}
-EXPORT_SYMBOL(vpdma_set_max_size);
-
-static void dump_cfd(struct vpdma_cfd *cfd)
-{
- int class;
-
- class = cfd_get_class(cfd);
-
- pr_debug("config descriptor of payload class: %s\n",
- class == CFD_CLS_BLOCK ? "simple block" :
- "address data block");
-
- if (class == CFD_CLS_BLOCK)
- pr_debug("word0: dst_addr_offset = 0x%08x\n",
- cfd->dest_addr_offset);
-
- if (class == CFD_CLS_BLOCK)
- pr_debug("word1: num_data_wrds = %d\n", cfd->block_len);
-
- pr_debug("word2: payload_addr = 0x%08x\n", cfd->payload_addr);
-
- pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, payload_len = %d\n",
- cfd_get_pkt_type(cfd),
- cfd_get_direct(cfd), class, cfd_get_dest(cfd),
- cfd_get_payload_len(cfd));
-}
-
-/*
- * append a configuration descriptor to the given descriptor list, where the
- * payload is in the form of a simple data block specified in the descriptor
- * header, this is used to upload scaler coefficients to the scaler module
- */
-void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
- struct vpdma_buf *blk, u32 dest_offset)
-{
- struct vpdma_cfd *cfd;
- int len = blk->size;
-
- WARN_ON(blk->dma_addr & VPDMA_DESC_ALIGN);
-
- cfd = list->next;
- WARN_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
-
- cfd->dest_addr_offset = dest_offset;
- cfd->block_len = len;
- cfd->payload_addr = (u32) blk->dma_addr;
- cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_BLOCK,
- client, len >> 4);
-
- list->next = cfd + 1;
-
- dump_cfd(cfd);
-}
-EXPORT_SYMBOL(vpdma_add_cfd_block);
-
-/*
- * append a configuration descriptor to the given descriptor list, where the
- * payload is in the address data block format, this is used to a configure a
- * discontiguous set of MMRs
- */
-void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
- struct vpdma_buf *adb)
-{
- struct vpdma_cfd *cfd;
- unsigned int len = adb->size;
-
- WARN_ON(len & VPDMA_ADB_SIZE_ALIGN);
- WARN_ON(adb->dma_addr & VPDMA_DESC_ALIGN);
-
- cfd = list->next;
- BUG_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
-
- cfd->w0 = 0;
- cfd->w1 = 0;
- cfd->payload_addr = (u32) adb->dma_addr;
- cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_ADB,
- client, len >> 4);
-
- list->next = cfd + 1;
-
- dump_cfd(cfd);
-};
-EXPORT_SYMBOL(vpdma_add_cfd_adb);
-
-/*
- * control descriptor format change based on what type of control descriptor it
- * is, we only use 'sync on channel' control descriptors for now, so assume it's
- * that
- */
-static void dump_ctd(struct vpdma_ctd *ctd)
-{
- pr_debug("control descriptor\n");
-
- pr_debug("word3: pkt_type = %d, source = %d, ctl_type = %d\n",
- ctd_get_pkt_type(ctd), ctd_get_source(ctd), ctd_get_ctl(ctd));
-}
-
-/*
- * append a 'sync on channel' type control descriptor to the given descriptor
- * list, this descriptor stalls the VPDMA list till the time DMA is completed
- * on the specified channel
- */
-void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
- enum vpdma_channel chan)
-{
- struct vpdma_ctd *ctd;
-
- ctd = list->next;
- WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
-
- ctd->w0 = 0;
- ctd->w1 = 0;
- ctd->w2 = 0;
- ctd->type_source_ctl = ctd_type_source_ctl(chan_info[chan].num,
- CTD_TYPE_SYNC_ON_CHANNEL);
-
- list->next = ctd + 1;
-
- dump_ctd(ctd);
-}
-EXPORT_SYMBOL(vpdma_add_sync_on_channel_ctd);
-
-/*
- * append an 'abort_channel' type control descriptor to the given descriptor
- * list, this descriptor aborts any DMA transaction happening using the
- * specified channel
- */
-void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list,
- int chan_num)
-{
- struct vpdma_ctd *ctd;
-
- ctd = list->next;
- WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
-
- ctd->w0 = 0;
- ctd->w1 = 0;
- ctd->w2 = 0;
- ctd->type_source_ctl = ctd_type_source_ctl(chan_num,
- CTD_TYPE_ABORT_CHANNEL);
-
- list->next = ctd + 1;
-
- dump_ctd(ctd);
-}
-EXPORT_SYMBOL(vpdma_add_abort_channel_ctd);
-
-static void dump_dtd(struct vpdma_dtd *dtd)
-{
- int dir, chan;
-
- dir = dtd_get_dir(dtd);
- chan = dtd_get_chan(dtd);
-
- pr_debug("%s data transfer descriptor for channel %d\n",
- dir == DTD_DIR_OUT ? "outbound" : "inbound", chan);
-
- pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n",
- dtd_get_data_type(dtd), dtd_get_notify(dtd), dtd_get_field(dtd),
- dtd_get_1d(dtd), dtd_get_even_line_skip(dtd),
- dtd_get_odd_line_skip(dtd), dtd_get_line_stride(dtd));
-
- if (dir == DTD_DIR_IN)
- pr_debug("word1: line_length = %d, xfer_height = %d\n",
- dtd_get_line_length(dtd), dtd_get_xfer_height(dtd));
-
- pr_debug("word2: start_addr = %x\n", dtd->start_addr);
-
- pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, pri = %d, next_chan = %d\n",
- dtd_get_pkt_type(dtd),
- dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd),
- dtd_get_next_chan(dtd));
-
- if (dir == DTD_DIR_IN)
- pr_debug("word4: frame_width = %d, frame_height = %d\n",
- dtd_get_frame_width(dtd), dtd_get_frame_height(dtd));
- else
- pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, drp_data = %d, use_desc_reg = %d\n",
- dtd_get_desc_write_addr(dtd), dtd_get_write_desc(dtd),
- dtd_get_drop_data(dtd), dtd_get_use_desc(dtd));
-
- if (dir == DTD_DIR_IN)
- pr_debug("word5: hor_start = %d, ver_start = %d\n",
- dtd_get_h_start(dtd), dtd_get_v_start(dtd));
- else
- pr_debug("word5: max_width %d, max_height %d\n",
- dtd_get_max_width(dtd), dtd_get_max_height(dtd));
-
- pr_debug("word6: client specific attr0 = 0x%08x\n", dtd->client_attr0);
- pr_debug("word7: client specific attr1 = 0x%08x\n", dtd->client_attr1);
-}
-
-/*
- * append an outbound data transfer descriptor to the given descriptor list,
- * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel
- *
- * @list: vpdma desc list to which we add this descriptor
- * @width: width of the image in pixels in memory
- * @c_rect: compose params of output image
- * @fmt: vpdma data format of the buffer
- * dma_addr: dma address as seen by VPDMA
- * max_width: enum for maximum width of data transfer
- * max_height: enum for maximum height of data transfer
- * chan: VPDMA channel
- * flags: VPDMA flags to configure some descriptor fields
- */
-void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
- int stride, const struct v4l2_rect *c_rect,
- const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
- int max_w, int max_h, enum vpdma_channel chan, u32 flags)
-{
- vpdma_rawchan_add_out_dtd(list, width, stride, c_rect, fmt, dma_addr,
- max_w, max_h, chan_info[chan].num, flags);
-}
-EXPORT_SYMBOL(vpdma_add_out_dtd);
-
-void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
- int stride, const struct v4l2_rect *c_rect,
- const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
- int max_w, int max_h, int raw_vpdma_chan, u32 flags)
-{
- int priority = 0;
- int field = 0;
- int notify = 1;
- int channel, next_chan;
- struct v4l2_rect rect = *c_rect;
- int depth = fmt->depth;
- struct vpdma_dtd *dtd;
-
- channel = next_chan = raw_vpdma_chan;
-
- if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
- (fmt->data_type == DATA_TYPE_C420 ||
- fmt->data_type == DATA_TYPE_CB420)) {
- rect.height >>= 1;
- rect.top >>= 1;
- depth = 8;
- }
-
- dma_addr += rect.top * stride + (rect.left * depth >> 3);
-
- dtd = list->next;
- WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
-
- dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
- notify,
- field,
- !!(flags & VPDMA_DATA_FRAME_1D),
- !!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
- !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
- stride);
- dtd->w1 = 0;
- dtd->start_addr = (u32) dma_addr;
- dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
- DTD_DIR_OUT, channel, priority, next_chan);
- dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0);
- dtd->max_width_height = dtd_max_width_height(max_w, max_h);
- dtd->client_attr0 = 0;
- dtd->client_attr1 = 0;
-
- list->next = dtd + 1;
-
- dump_dtd(dtd);
-}
-EXPORT_SYMBOL(vpdma_rawchan_add_out_dtd);
-
-/*
- * append an inbound data transfer descriptor to the given descriptor list,
- * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel
- *
- * @list: vpdma desc list to which we add this descriptor
- * @width: width of the image in pixels in memory(not the cropped width)
- * @c_rect: crop params of input image
- * @fmt: vpdma data format of the buffer
- * dma_addr: dma address as seen by VPDMA
- * chan: VPDMA channel
- * field: top or bottom field info of the input image
- * flags: VPDMA flags to configure some descriptor fields
- * frame_width/height: the complete width/height of the image presented to the
- * client (this makes sense when multiple channels are
- * connected to the same client, forming a larger frame)
- * start_h, start_v: position where the given channel starts providing pixel
- * data to the client (makes sense when multiple channels
- * contribute to the client)
- */
-void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
- int stride, const struct v4l2_rect *c_rect,
- const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
- enum vpdma_channel chan, int field, u32 flags, int frame_width,
- int frame_height, int start_h, int start_v)
-{
- int priority = 0;
- int notify = 1;
- int depth = fmt->depth;
- int channel, next_chan;
- struct v4l2_rect rect = *c_rect;
- struct vpdma_dtd *dtd;
-
- channel = next_chan = chan_info[chan].num;
-
- if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
- (fmt->data_type == DATA_TYPE_C420 ||
- fmt->data_type == DATA_TYPE_CB420)) {
- rect.height >>= 1;
- rect.top >>= 1;
- depth = 8;
- }
-
- dma_addr += rect.top * stride + (rect.left * depth >> 3);
-
- dtd = list->next;
- WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
-
- dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
- notify,
- field,
- !!(flags & VPDMA_DATA_FRAME_1D),
- !!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
- !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
- stride);
-
- dtd->xfer_length_height = dtd_xfer_length_height(rect.width,
- rect.height);
- dtd->start_addr = (u32) dma_addr;
- dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
- DTD_DIR_IN, channel, priority, next_chan);
- dtd->frame_width_height = dtd_frame_width_height(frame_width,
- frame_height);
- dtd->start_h_v = dtd_start_h_v(start_h, start_v);
- dtd->client_attr0 = 0;
- dtd->client_attr1 = 0;
-
- list->next = dtd + 1;
-
- dump_dtd(dtd);
-}
-EXPORT_SYMBOL(vpdma_add_in_dtd);
-
-int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv)
-{
- int i, list_num = -1;
- unsigned long flags;
-
- spin_lock_irqsave(&vpdma->lock, flags);
- for (i = 0; i < VPDMA_MAX_NUM_LIST && vpdma->hwlist_used[i]; i++)
- ;
-
- if (i < VPDMA_MAX_NUM_LIST) {
- list_num = i;
- vpdma->hwlist_used[i] = true;
- vpdma->hwlist_priv[i] = priv;
- }
- spin_unlock_irqrestore(&vpdma->lock, flags);
-
- return list_num;
-}
-EXPORT_SYMBOL(vpdma_hwlist_alloc);
-
-void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num)
-{
- if (!vpdma || list_num >= VPDMA_MAX_NUM_LIST)
- return NULL;
-
- return vpdma->hwlist_priv[list_num];
-}
-EXPORT_SYMBOL(vpdma_hwlist_get_priv);
-
-void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num)
-{
- void *priv;
- unsigned long flags;
-
- spin_lock_irqsave(&vpdma->lock, flags);
- vpdma->hwlist_used[list_num] = false;
- priv = vpdma->hwlist_priv;
- spin_unlock_irqrestore(&vpdma->lock, flags);
-
- return priv;
-}
-EXPORT_SYMBOL(vpdma_hwlist_release);
-
-/* set or clear the mask for list complete interrupt */
-void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
- int list_num, bool enable)
-{
- u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
- u32 val;
-
- val = read_reg(vpdma, reg_addr);
- if (enable)
- val |= (1 << (list_num * 2));
- else
- val &= ~(1 << (list_num * 2));
- write_reg(vpdma, reg_addr, val);
-}
-EXPORT_SYMBOL(vpdma_enable_list_complete_irq);
-
-/* get the LIST_STAT register */
-unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num)
-{
- u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
-
- return read_reg(vpdma, reg_addr);
-}
-EXPORT_SYMBOL(vpdma_get_list_stat);
-
-/* get the LIST_MASK register */
-unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num)
-{
- u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
-
- return read_reg(vpdma, reg_addr);
-}
-EXPORT_SYMBOL(vpdma_get_list_mask);
-
-/* clear previously occurred list interrupts in the LIST_STAT register */
-void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num,
- int list_num)
-{
- u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
-
- write_reg(vpdma, reg_addr, 3 << (list_num * 2));
-}
-EXPORT_SYMBOL(vpdma_clear_list_stat);
-
-void vpdma_set_bg_color(struct vpdma_data *vpdma,
- struct vpdma_data_format *fmt, u32 color)
-{
- if (fmt->type == VPDMA_DATA_FMT_TYPE_RGB)
- write_reg(vpdma, VPDMA_BG_RGB, color);
- else if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV)
- write_reg(vpdma, VPDMA_BG_YUV, color);
-}
-EXPORT_SYMBOL(vpdma_set_bg_color);
-
-/*
- * configures the output mode of the line buffer for the given client, the
- * line buffer content can either be mirrored(each line repeated twice) or
- * passed to the client as is
- */
-void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
- enum vpdma_channel chan)
-{
- int client_cstat = chan_info[chan].cstat_offset;
-
- write_field_reg(vpdma, client_cstat, line_mode,
- VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT);
-}
-EXPORT_SYMBOL(vpdma_set_line_mode);
-
-/*
- * configures the event which should trigger VPDMA transfer for the given
- * client
- */
-void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
- enum vpdma_frame_start_event fs_event,
- enum vpdma_channel chan)
-{
- int client_cstat = chan_info[chan].cstat_offset;
-
- write_field_reg(vpdma, client_cstat, fs_event,
- VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT);
-}
-EXPORT_SYMBOL(vpdma_set_frame_start_event);
-
-static void vpdma_firmware_cb(const struct firmware *f, void *context)
-{
- struct vpdma_data *vpdma = context;
- struct vpdma_buf fw_dma_buf;
- int i, r;
-
- dev_dbg(&vpdma->pdev->dev, "firmware callback\n");
-
- if (!f || !f->data) {
- dev_err(&vpdma->pdev->dev, "couldn't get firmware\n");
- return;
- }
-
- /* already initialized */
- if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
- VPDMA_LIST_RDY_SHFT)) {
- vpdma->cb(vpdma->pdev);
- return;
- }
-
- r = vpdma_alloc_desc_buf(&fw_dma_buf, f->size);
- if (r) {
- dev_err(&vpdma->pdev->dev,
- "failed to allocate dma buffer for firmware\n");
- goto rel_fw;
- }
-
- memcpy(fw_dma_buf.addr, f->data, f->size);
-
- vpdma_map_desc_buf(vpdma, &fw_dma_buf);
-
- write_reg(vpdma, VPDMA_LIST_ADDR, (u32) fw_dma_buf.dma_addr);
-
- for (i = 0; i < 100; i++) { /* max 1 second */
- msleep_interruptible(10);
-
- if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
- VPDMA_LIST_RDY_SHFT))
- break;
- }
-
- if (i == 100) {
- dev_err(&vpdma->pdev->dev, "firmware upload failed\n");
- goto free_buf;
- }
-
- vpdma->cb(vpdma->pdev);
-
-free_buf:
- vpdma_unmap_desc_buf(vpdma, &fw_dma_buf);
-
- vpdma_free_desc_buf(&fw_dma_buf);
-rel_fw:
- release_firmware(f);
-}
-
-static int vpdma_load_firmware(struct vpdma_data *vpdma)
-{
- int r;
- struct device *dev = &vpdma->pdev->dev;
-
- r = request_firmware_nowait(THIS_MODULE, 1,
- (const char *) VPDMA_FIRMWARE, dev, GFP_KERNEL, vpdma,
- vpdma_firmware_cb);
- if (r) {
- dev_err(dev, "firmware not available %s\n", VPDMA_FIRMWARE);
- return r;
- } else {
- dev_info(dev, "loading firmware %s\n", VPDMA_FIRMWARE);
- }
-
- return 0;
-}
-
-int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma,
- void (*cb)(struct platform_device *pdev))
-{
- struct resource *res;
- int r;
-
- dev_dbg(&pdev->dev, "vpdma_create\n");
-
- vpdma->pdev = pdev;
- vpdma->cb = cb;
- spin_lock_init(&vpdma->lock);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma");
- if (res == NULL) {
- dev_err(&pdev->dev, "missing platform resources data\n");
- return -ENODEV;
- }
-
- vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
- if (!vpdma->base) {
- dev_err(&pdev->dev, "failed to ioremap\n");
- return -ENOMEM;
- }
-
- r = vpdma_load_firmware(vpdma);
- if (r) {
- pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE);
- return r;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(vpdma_create);
-
-MODULE_AUTHOR("Texas Instruments Inc.");
-MODULE_FIRMWARE(VPDMA_FIRMWARE);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti-vpe/vpdma.h
deleted file mode 100644
index 393fcbb3cb40..000000000000
--- a/drivers/media/platform/ti-vpe/vpdma.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-
-#ifndef __TI_VPDMA_H_
-#define __TI_VPDMA_H_
-
-#define VPDMA_MAX_NUM_LIST 8
-/*
- * A vpdma_buf tracks the size, DMA address and mapping status of each
- * driver DMA area.
- */
-struct vpdma_buf {
- void *addr;
- dma_addr_t dma_addr;
- size_t size;
- bool mapped;
-};
-
-struct vpdma_desc_list {
- struct vpdma_buf buf;
- void *next;
- int type;
-};
-
-struct vpdma_data {
- void __iomem *base;
-
- struct platform_device *pdev;
-
- spinlock_t lock;
- bool hwlist_used[VPDMA_MAX_NUM_LIST];
- void *hwlist_priv[VPDMA_MAX_NUM_LIST];
- /* callback to VPE driver when the firmware is loaded */
- void (*cb)(struct platform_device *pdev);
-};
-
-enum vpdma_data_format_type {
- VPDMA_DATA_FMT_TYPE_YUV,
- VPDMA_DATA_FMT_TYPE_RGB,
- VPDMA_DATA_FMT_TYPE_MISC,
-};
-
-struct vpdma_data_format {
- enum vpdma_data_format_type type;
- int data_type;
- u8 depth;
-};
-
-#define VPDMA_DESC_ALIGN 16 /* 16-byte descriptor alignment */
-#define VPDMA_STRIDE_ALIGN 16 /*
- * line stride of source and dest
- * buffers should be 16 byte aligned
- */
-#define VPDMA_MAX_STRIDE 65520 /* Max line stride 16 byte aligned */
-#define VPDMA_DTD_DESC_SIZE 32 /* 8 words */
-#define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */
-
-#define VPDMA_LIST_TYPE_NORMAL 0
-#define VPDMA_LIST_TYPE_SELF_MODIFYING 1
-#define VPDMA_LIST_TYPE_DOORBELL 2
-
-enum vpdma_yuv_formats {
- VPDMA_DATA_FMT_Y444 = 0,
- VPDMA_DATA_FMT_Y422,
- VPDMA_DATA_FMT_Y420,
- VPDMA_DATA_FMT_C444,
- VPDMA_DATA_FMT_C422,
- VPDMA_DATA_FMT_C420,
- VPDMA_DATA_FMT_CB420,
- VPDMA_DATA_FMT_YCR422,
- VPDMA_DATA_FMT_YC444,
- VPDMA_DATA_FMT_CRY422,
- VPDMA_DATA_FMT_CBY422,
- VPDMA_DATA_FMT_YCB422,
-};
-
-enum vpdma_rgb_formats {
- VPDMA_DATA_FMT_RGB565 = 0,
- VPDMA_DATA_FMT_ARGB16_1555,
- VPDMA_DATA_FMT_ARGB16,
- VPDMA_DATA_FMT_RGBA16_5551,
- VPDMA_DATA_FMT_RGBA16,
- VPDMA_DATA_FMT_ARGB24,
- VPDMA_DATA_FMT_RGB24,
- VPDMA_DATA_FMT_ARGB32,
- VPDMA_DATA_FMT_RGBA24,
- VPDMA_DATA_FMT_RGBA32,
- VPDMA_DATA_FMT_BGR565,
- VPDMA_DATA_FMT_ABGR16_1555,
- VPDMA_DATA_FMT_ABGR16,
- VPDMA_DATA_FMT_BGRA16_5551,
- VPDMA_DATA_FMT_BGRA16,
- VPDMA_DATA_FMT_ABGR24,
- VPDMA_DATA_FMT_BGR24,
- VPDMA_DATA_FMT_ABGR32,
- VPDMA_DATA_FMT_BGRA24,
- VPDMA_DATA_FMT_BGRA32,
-};
-
-enum vpdma_raw_formats {
- VPDMA_DATA_FMT_RAW8 = 0,
- VPDMA_DATA_FMT_RAW16,
-};
-
-enum vpdma_misc_formats {
- VPDMA_DATA_FMT_MV = 0,
-};
-
-extern const struct vpdma_data_format vpdma_yuv_fmts[];
-extern const struct vpdma_data_format vpdma_rgb_fmts[];
-extern const struct vpdma_data_format vpdma_raw_fmts[];
-extern const struct vpdma_data_format vpdma_misc_fmts[];
-
-enum vpdma_frame_start_event {
- VPDMA_FSEVENT_HDMI_FID = 0,
- VPDMA_FSEVENT_DVO2_FID,
- VPDMA_FSEVENT_HDCOMP_FID,
- VPDMA_FSEVENT_SD_FID,
- VPDMA_FSEVENT_LM_FID0,
- VPDMA_FSEVENT_LM_FID1,
- VPDMA_FSEVENT_LM_FID2,
- VPDMA_FSEVENT_CHANNEL_ACTIVE,
-};
-
-/* max width configurations */
-enum vpdma_max_width {
- MAX_OUT_WIDTH_UNLIMITED = 0,
- MAX_OUT_WIDTH_REG1,
- MAX_OUT_WIDTH_REG2,
- MAX_OUT_WIDTH_REG3,
- MAX_OUT_WIDTH_352,
- MAX_OUT_WIDTH_768,
- MAX_OUT_WIDTH_1280,
- MAX_OUT_WIDTH_1920,
-};
-
-/* max height configurations */
-enum vpdma_max_height {
- MAX_OUT_HEIGHT_UNLIMITED = 0,
- MAX_OUT_HEIGHT_REG1,
- MAX_OUT_HEIGHT_REG2,
- MAX_OUT_HEIGHT_REG3,
- MAX_OUT_HEIGHT_288,
- MAX_OUT_HEIGHT_576,
- MAX_OUT_HEIGHT_720,
- MAX_OUT_HEIGHT_1080,
-};
-
-/*
- * VPDMA channel numbers
- */
-enum vpdma_channel {
- VPE_CHAN_LUMA1_IN,
- VPE_CHAN_CHROMA1_IN,
- VPE_CHAN_LUMA2_IN,
- VPE_CHAN_CHROMA2_IN,
- VPE_CHAN_LUMA3_IN,
- VPE_CHAN_CHROMA3_IN,
- VPE_CHAN_MV_IN,
- VPE_CHAN_MV_OUT,
- VPE_CHAN_LUMA_OUT,
- VPE_CHAN_CHROMA_OUT,
- VPE_CHAN_RGB_OUT,
-};
-
-#define VIP_CHAN_VIP2_OFFSET 70
-#define VIP_CHAN_MULT_PORTB_OFFSET 16
-#define VIP_CHAN_YUV_PORTB_OFFSET 2
-#define VIP_CHAN_RGB_PORTB_OFFSET 1
-
-#define VPDMA_MAX_CHANNELS 256
-
-/* flags for VPDMA data descriptors */
-#define VPDMA_DATA_ODD_LINE_SKIP (1 << 0)
-#define VPDMA_DATA_EVEN_LINE_SKIP (1 << 1)
-#define VPDMA_DATA_FRAME_1D (1 << 2)
-#define VPDMA_DATA_MODE_TILED (1 << 3)
-
-/*
- * client identifiers used for configuration descriptors
- */
-#define CFD_MMR_CLIENT 0
-#define CFD_SC_CLIENT 4
-
-/* Address data block header format */
-struct vpdma_adb_hdr {
- u32 offset;
- u32 nwords;
- u32 reserved0;
- u32 reserved1;
-};
-
-/* helpers for creating ADB headers for config descriptors MMRs as client */
-#define ADB_ADDR(dma_buf, str, fld) ((dma_buf)->addr + offsetof(str, fld))
-#define MMR_ADB_ADDR(buf, str, fld) ADB_ADDR(&(buf), struct str, fld)
-
-#define VPDMA_SET_MMR_ADB_HDR(buf, str, hdr, regs, offset_a) \
- do { \
- struct vpdma_adb_hdr *h; \
- struct str *adb = NULL; \
- h = MMR_ADB_ADDR(buf, str, hdr); \
- h->offset = (offset_a); \
- h->nwords = sizeof(adb->regs) >> 2; \
- } while (0)
-
-/* vpdma descriptor buffer allocation and management */
-int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size);
-void vpdma_free_desc_buf(struct vpdma_buf *buf);
-int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
-void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf);
-
-/* vpdma descriptor list funcs */
-int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type);
-void vpdma_reset_desc_list(struct vpdma_desc_list *list);
-void vpdma_free_desc_list(struct vpdma_desc_list *list);
-int vpdma_submit_descs(struct vpdma_data *vpdma, struct vpdma_desc_list *list,
- int list_num);
-bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num);
-void vpdma_update_dma_addr(struct vpdma_data *vpdma,
- struct vpdma_desc_list *list, dma_addr_t dma_addr,
- void *write_dtd, int drop, int idx);
-
-/* VPDMA hardware list funcs */
-int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv);
-void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num);
-void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num);
-
-/* helpers for creating vpdma descriptors */
-void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
- struct vpdma_buf *blk, u32 dest_offset);
-void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
- struct vpdma_buf *adb);
-void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
- enum vpdma_channel chan);
-void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list,
- int chan_num);
-void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
- int stride, const struct v4l2_rect *c_rect,
- const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
- int max_w, int max_h, enum vpdma_channel chan, u32 flags);
-void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
- int stride, const struct v4l2_rect *c_rect,
- const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
- int max_w, int max_h, int raw_vpdma_chan, u32 flags);
-
-void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
- int stride, const struct v4l2_rect *c_rect,
- const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
- enum vpdma_channel chan, int field, u32 flags, int frame_width,
- int frame_height, int start_h, int start_v);
-int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
- int *channels, int size);
-
-/* vpdma list interrupt management */
-void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
- int list_num, bool enable);
-void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num,
- int list_num);
-unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num);
-unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num);
-
-/* vpdma client configuration */
-void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
- enum vpdma_channel chan);
-void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
- enum vpdma_frame_start_event fs_event, enum vpdma_channel chan);
-void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
- u32 width, u32 height);
-
-void vpdma_set_bg_color(struct vpdma_data *vpdma,
- struct vpdma_data_format *fmt, u32 color);
-void vpdma_dump_regs(struct vpdma_data *vpdma);
-
-/* initialize vpdma, passed with VPE's platform device pointer */
-int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma,
- void (*cb)(struct platform_device *pdev));
-
-#endif
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti-vpe/vpdma_priv.h
deleted file mode 100644
index 0bbee45338bd..000000000000
--- a/drivers/media/platform/ti-vpe/vpdma_priv.h
+++ /dev/null
@@ -1,639 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-
-#ifndef _TI_VPDMA_PRIV_H_
-#define _TI_VPDMA_PRIV_H_
-
-/*
- * VPDMA Register offsets
- */
-
-/* Top level */
-#define VPDMA_PID 0x00
-#define VPDMA_LIST_ADDR 0x04
-#define VPDMA_LIST_ATTR 0x08
-#define VPDMA_LIST_STAT_SYNC 0x0c
-#define VPDMA_BG_RGB 0x18
-#define VPDMA_BG_YUV 0x1c
-#define VPDMA_SETUP 0x30
-#define VPDMA_MAX_SIZE1 0x34
-#define VPDMA_MAX_SIZE2 0x38
-#define VPDMA_MAX_SIZE3 0x3c
-#define VPDMA_MAX_SIZE_WIDTH_MASK 0xffff
-#define VPDMA_MAX_SIZE_WIDTH_SHFT 16
-#define VPDMA_MAX_SIZE_HEIGHT_MASK 0xffff
-#define VPDMA_MAX_SIZE_HEIGHT_SHFT 0
-
-/* Interrupts */
-#define VPDMA_INT_CHAN_STAT(grp) (0x40 + grp * 8)
-#define VPDMA_INT_CHAN_MASK(grp) (VPDMA_INT_CHAN_STAT(grp) + 4)
-#define VPDMA_INT_CLIENT0_STAT 0x78
-#define VPDMA_INT_CLIENT0_MASK 0x7c
-#define VPDMA_INT_CLIENT1_STAT 0x80
-#define VPDMA_INT_CLIENT1_MASK 0x84
-#define VPDMA_INT_LIST0_STAT 0x88
-#define VPDMA_INT_LIST0_MASK 0x8c
-
-#define VPDMA_INTX_OFFSET 0x50
-
-#define VPDMA_PERFMON(i) (0x200 + i * 4)
-
-/* VIP/VPE client registers */
-#define VPDMA_DEI_CHROMA1_CSTAT 0x0300
-#define VPDMA_DEI_LUMA1_CSTAT 0x0304
-#define VPDMA_DEI_LUMA2_CSTAT 0x0308
-#define VPDMA_DEI_CHROMA2_CSTAT 0x030c
-#define VPDMA_DEI_LUMA3_CSTAT 0x0310
-#define VPDMA_DEI_CHROMA3_CSTAT 0x0314
-#define VPDMA_DEI_MV_IN_CSTAT 0x0330
-#define VPDMA_DEI_MV_OUT_CSTAT 0x033c
-#define VPDMA_VIP_LO_Y_CSTAT 0x0388
-#define VPDMA_VIP_LO_UV_CSTAT 0x038c
-#define VPDMA_VIP_UP_Y_CSTAT 0x0390
-#define VPDMA_VIP_UP_UV_CSTAT 0x0394
-#define VPDMA_VPI_CTL_CSTAT 0x03d0
-
-/* Reg field info for VPDMA_CLIENT_CSTAT registers */
-#define VPDMA_CSTAT_LINE_MODE_MASK 0x03
-#define VPDMA_CSTAT_LINE_MODE_SHIFT 8
-#define VPDMA_CSTAT_FRAME_START_MASK 0xf
-#define VPDMA_CSTAT_FRAME_START_SHIFT 10
-
-#define VPDMA_LIST_NUM_MASK 0x07
-#define VPDMA_LIST_NUM_SHFT 24
-#define VPDMA_LIST_STOP_SHFT 20
-#define VPDMA_LIST_RDY_MASK 0x01
-#define VPDMA_LIST_RDY_SHFT 19
-#define VPDMA_LIST_TYPE_MASK 0x03
-#define VPDMA_LIST_TYPE_SHFT 16
-#define VPDMA_LIST_SIZE_MASK 0xffff
-
-/*
- * The YUV data type definition below are taken from
- * both the TRM and i839 Errata information.
- * Use the correct data type considering byte
- * reordering of components.
- *
- * Also since the single use of "C" in the 422 case
- * to mean "Cr" (i.e. V component). It was decided
- * to explicitly label them CR to remove any confusion.
- * Bear in mind that the type label refer to the memory
- * packed order (LSB - MSB).
- */
-#define DATA_TYPE_Y444 0x0
-#define DATA_TYPE_Y422 0x1
-#define DATA_TYPE_Y420 0x2
-#define DATA_TYPE_C444 0x4
-#define DATA_TYPE_C422 0x5
-#define DATA_TYPE_C420 0x6
-#define DATA_TYPE_CB420 0x16
-#define DATA_TYPE_YC444 0x8
-#define DATA_TYPE_YCB422 0x7
-#define DATA_TYPE_YCR422 0x17
-#define DATA_TYPE_CBY422 0x27
-#define DATA_TYPE_CRY422 0x37
-
-/*
- * The RGB data type definition below are defined
- * to follow Errata i819.
- * The initial values were taken from:
- * VPDMA_data_type_mapping_v0.2vayu_c.pdf
- * But some of the ARGB definition appeared to be wrong
- * in the document also. As they would yield RGBA instead.
- * They have been corrected based on experimentation.
- */
-#define DATA_TYPE_RGB16_565 0x10
-#define DATA_TYPE_ARGB_1555 0x13
-#define DATA_TYPE_ARGB_4444 0x14
-#define DATA_TYPE_RGBA_5551 0x11
-#define DATA_TYPE_RGBA_4444 0x12
-#define DATA_TYPE_ARGB24_6666 0x18
-#define DATA_TYPE_RGB24_888 0x16
-#define DATA_TYPE_ARGB32_8888 0x17
-#define DATA_TYPE_RGBA24_6666 0x15
-#define DATA_TYPE_RGBA32_8888 0x19
-#define DATA_TYPE_BGR16_565 0x0
-#define DATA_TYPE_ABGR_1555 0x3
-#define DATA_TYPE_ABGR_4444 0x4
-#define DATA_TYPE_BGRA_5551 0x1
-#define DATA_TYPE_BGRA_4444 0x2
-#define DATA_TYPE_ABGR24_6666 0x8
-#define DATA_TYPE_BGR24_888 0x6
-#define DATA_TYPE_ABGR32_8888 0x7
-#define DATA_TYPE_BGRA24_6666 0x5
-#define DATA_TYPE_BGRA32_8888 0x9
-
-#define DATA_TYPE_MV 0x3
-
-/* VPDMA channel numbers, some are common between VIP/VPE and appear twice */
-#define VPE_CHAN_NUM_LUMA1_IN 0
-#define VPE_CHAN_NUM_CHROMA1_IN 1
-#define VPE_CHAN_NUM_LUMA2_IN 2
-#define VPE_CHAN_NUM_CHROMA2_IN 3
-#define VPE_CHAN_NUM_LUMA3_IN 4
-#define VPE_CHAN_NUM_CHROMA3_IN 5
-#define VPE_CHAN_NUM_MV_IN 12
-#define VPE_CHAN_NUM_MV_OUT 15
-#define VIP1_CHAN_NUM_MULT_PORT_A_SRC0 38
-#define VIP1_CHAN_NUM_MULT_ANC_A_SRC0 70
-#define VPE_CHAN_NUM_LUMA_OUT 102
-#define VPE_CHAN_NUM_CHROMA_OUT 103
-#define VIP1_CHAN_NUM_PORT_A_LUMA 102
-#define VIP1_CHAN_NUM_PORT_A_CHROMA 103
-#define VPE_CHAN_NUM_RGB_OUT 106
-#define VIP1_CHAN_NUM_PORT_A_RGB 106
-#define VIP1_CHAN_NUM_PORT_B_RGB 107
-/*
- * a VPDMA address data block payload for a configuration descriptor needs to
- * have each sub block length as a multiple of 16 bytes. Therefore, the overall
- * size of the payload also needs to be a multiple of 16 bytes. The sub block
- * lengths should be ensured to be aligned by the VPDMA user.
- */
-#define VPDMA_ADB_SIZE_ALIGN 0x0f
-
-/*
- * data transfer descriptor
- */
-struct vpdma_dtd {
- u32 type_ctl_stride;
- union {
- u32 xfer_length_height;
- u32 w1;
- };
- u32 start_addr;
- u32 pkt_ctl;
- union {
- u32 frame_width_height; /* inbound */
- u32 desc_write_addr; /* outbound */
- };
- union {
- u32 start_h_v; /* inbound */
- u32 max_width_height; /* outbound */
- };
- u32 client_attr0;
- u32 client_attr1;
-};
-
-/* Data Transfer Descriptor specifics */
-#define DTD_NO_NOTIFY 0
-#define DTD_NOTIFY 1
-
-#define DTD_PKT_TYPE 0xa
-#define DTD_DIR_IN 0
-#define DTD_DIR_OUT 1
-
-/* type_ctl_stride */
-#define DTD_DATA_TYPE_MASK 0x3f
-#define DTD_DATA_TYPE_SHFT 26
-#define DTD_NOTIFY_MASK 0x01
-#define DTD_NOTIFY_SHFT 25
-#define DTD_FIELD_MASK 0x01
-#define DTD_FIELD_SHFT 24
-#define DTD_1D_MASK 0x01
-#define DTD_1D_SHFT 23
-#define DTD_EVEN_LINE_SKIP_MASK 0x01
-#define DTD_EVEN_LINE_SKIP_SHFT 20
-#define DTD_ODD_LINE_SKIP_MASK 0x01
-#define DTD_ODD_LINE_SKIP_SHFT 16
-#define DTD_LINE_STRIDE_MASK 0xffff
-#define DTD_LINE_STRIDE_SHFT 0
-
-/* xfer_length_height */
-#define DTD_LINE_LENGTH_MASK 0xffff
-#define DTD_LINE_LENGTH_SHFT 16
-#define DTD_XFER_HEIGHT_MASK 0xffff
-#define DTD_XFER_HEIGHT_SHFT 0
-
-/* pkt_ctl */
-#define DTD_PKT_TYPE_MASK 0x1f
-#define DTD_PKT_TYPE_SHFT 27
-#define DTD_MODE_MASK 0x01
-#define DTD_MODE_SHFT 26
-#define DTD_DIR_MASK 0x01
-#define DTD_DIR_SHFT 25
-#define DTD_CHAN_MASK 0x01ff
-#define DTD_CHAN_SHFT 16
-#define DTD_PRI_MASK 0x0f
-#define DTD_PRI_SHFT 9
-#define DTD_NEXT_CHAN_MASK 0x01ff
-#define DTD_NEXT_CHAN_SHFT 0
-
-/* frame_width_height */
-#define DTD_FRAME_WIDTH_MASK 0xffff
-#define DTD_FRAME_WIDTH_SHFT 16
-#define DTD_FRAME_HEIGHT_MASK 0xffff
-#define DTD_FRAME_HEIGHT_SHFT 0
-
-/* start_h_v */
-#define DTD_H_START_MASK 0xffff
-#define DTD_H_START_SHFT 16
-#define DTD_V_START_MASK 0xffff
-#define DTD_V_START_SHFT 0
-
-#define DTD_DESC_START_MASK 0xffffffe0
-#define DTD_DESC_START_SHIFT 5
-#define DTD_WRITE_DESC_MASK 0x01
-#define DTD_WRITE_DESC_SHIFT 2
-#define DTD_DROP_DATA_MASK 0x01
-#define DTD_DROP_DATA_SHIFT 1
-#define DTD_USE_DESC_MASK 0x01
-#define DTD_USE_DESC_SHIFT 0
-
-/* max_width_height */
-#define DTD_MAX_WIDTH_MASK 0x07
-#define DTD_MAX_WIDTH_SHFT 4
-#define DTD_MAX_HEIGHT_MASK 0x07
-#define DTD_MAX_HEIGHT_SHFT 0
-
-static inline u32 dtd_type_ctl_stride(int type, bool notify, int field,
- bool one_d, bool even_line_skip, bool odd_line_skip,
- int line_stride)
-{
- return (type << DTD_DATA_TYPE_SHFT) | (notify << DTD_NOTIFY_SHFT) |
- (field << DTD_FIELD_SHFT) | (one_d << DTD_1D_SHFT) |
- (even_line_skip << DTD_EVEN_LINE_SKIP_SHFT) |
- (odd_line_skip << DTD_ODD_LINE_SKIP_SHFT) |
- line_stride;
-}
-
-static inline u32 dtd_xfer_length_height(int line_length, int xfer_height)
-{
- return (line_length << DTD_LINE_LENGTH_SHFT) | xfer_height;
-}
-
-static inline u32 dtd_pkt_ctl(bool mode, bool dir, int chan, int pri,
- int next_chan)
-{
- return (DTD_PKT_TYPE << DTD_PKT_TYPE_SHFT) | (mode << DTD_MODE_SHFT) |
- (dir << DTD_DIR_SHFT) | (chan << DTD_CHAN_SHFT) |
- (pri << DTD_PRI_SHFT) | next_chan;
-}
-
-static inline u32 dtd_frame_width_height(int width, int height)
-{
- return (width << DTD_FRAME_WIDTH_SHFT) | height;
-}
-
-static inline u32 dtd_desc_write_addr(unsigned int addr, bool write_desc,
- bool drop_data, bool use_desc)
-{
- return (addr & DTD_DESC_START_MASK) |
- (write_desc << DTD_WRITE_DESC_SHIFT) |
- (drop_data << DTD_DROP_DATA_SHIFT) |
- use_desc;
-}
-
-static inline u32 dtd_start_h_v(int h_start, int v_start)
-{
- return (h_start << DTD_H_START_SHFT) | v_start;
-}
-
-static inline u32 dtd_max_width_height(int max_width, int max_height)
-{
- return (max_width << DTD_MAX_WIDTH_SHFT) | max_height;
-}
-
-static inline int dtd_get_data_type(struct vpdma_dtd *dtd)
-{
- return dtd->type_ctl_stride >> DTD_DATA_TYPE_SHFT;
-}
-
-static inline bool dtd_get_notify(struct vpdma_dtd *dtd)
-{
- return (dtd->type_ctl_stride >> DTD_NOTIFY_SHFT) & DTD_NOTIFY_MASK;
-}
-
-static inline int dtd_get_field(struct vpdma_dtd *dtd)
-{
- return (dtd->type_ctl_stride >> DTD_FIELD_SHFT) & DTD_FIELD_MASK;
-}
-
-static inline bool dtd_get_1d(struct vpdma_dtd *dtd)
-{
- return (dtd->type_ctl_stride >> DTD_1D_SHFT) & DTD_1D_MASK;
-}
-
-static inline bool dtd_get_even_line_skip(struct vpdma_dtd *dtd)
-{
- return (dtd->type_ctl_stride >> DTD_EVEN_LINE_SKIP_SHFT)
- & DTD_EVEN_LINE_SKIP_MASK;
-}
-
-static inline bool dtd_get_odd_line_skip(struct vpdma_dtd *dtd)
-{
- return (dtd->type_ctl_stride >> DTD_ODD_LINE_SKIP_SHFT)
- & DTD_ODD_LINE_SKIP_MASK;
-}
-
-static inline int dtd_get_line_stride(struct vpdma_dtd *dtd)
-{
- return dtd->type_ctl_stride & DTD_LINE_STRIDE_MASK;
-}
-
-static inline int dtd_get_line_length(struct vpdma_dtd *dtd)
-{
- return dtd->xfer_length_height >> DTD_LINE_LENGTH_SHFT;
-}
-
-static inline int dtd_get_xfer_height(struct vpdma_dtd *dtd)
-{
- return dtd->xfer_length_height & DTD_XFER_HEIGHT_MASK;
-}
-
-static inline int dtd_get_pkt_type(struct vpdma_dtd *dtd)
-{
- return dtd->pkt_ctl >> DTD_PKT_TYPE_SHFT;
-}
-
-static inline bool dtd_get_mode(struct vpdma_dtd *dtd)
-{
- return (dtd->pkt_ctl >> DTD_MODE_SHFT) & DTD_MODE_MASK;
-}
-
-static inline bool dtd_get_dir(struct vpdma_dtd *dtd)
-{
- return (dtd->pkt_ctl >> DTD_DIR_SHFT) & DTD_DIR_MASK;
-}
-
-static inline int dtd_get_chan(struct vpdma_dtd *dtd)
-{
- return (dtd->pkt_ctl >> DTD_CHAN_SHFT) & DTD_CHAN_MASK;
-}
-
-static inline int dtd_get_priority(struct vpdma_dtd *dtd)
-{
- return (dtd->pkt_ctl >> DTD_PRI_SHFT) & DTD_PRI_MASK;
-}
-
-static inline int dtd_get_next_chan(struct vpdma_dtd *dtd)
-{
- return (dtd->pkt_ctl >> DTD_NEXT_CHAN_SHFT) & DTD_NEXT_CHAN_MASK;
-}
-
-static inline int dtd_get_frame_width(struct vpdma_dtd *dtd)
-{
- return dtd->frame_width_height >> DTD_FRAME_WIDTH_SHFT;
-}
-
-static inline int dtd_get_frame_height(struct vpdma_dtd *dtd)
-{
- return dtd->frame_width_height & DTD_FRAME_HEIGHT_MASK;
-}
-
-static inline int dtd_get_desc_write_addr(struct vpdma_dtd *dtd)
-{
- return dtd->desc_write_addr & DTD_DESC_START_MASK;
-}
-
-static inline bool dtd_get_write_desc(struct vpdma_dtd *dtd)
-{
- return (dtd->desc_write_addr >> DTD_WRITE_DESC_SHIFT) &
- DTD_WRITE_DESC_MASK;
-}
-
-static inline bool dtd_get_drop_data(struct vpdma_dtd *dtd)
-{
- return (dtd->desc_write_addr >> DTD_DROP_DATA_SHIFT) &
- DTD_DROP_DATA_MASK;
-}
-
-static inline bool dtd_get_use_desc(struct vpdma_dtd *dtd)
-{
- return dtd->desc_write_addr & DTD_USE_DESC_MASK;
-}
-
-static inline int dtd_get_h_start(struct vpdma_dtd *dtd)
-{
- return dtd->start_h_v >> DTD_H_START_SHFT;
-}
-
-static inline int dtd_get_v_start(struct vpdma_dtd *dtd)
-{
- return dtd->start_h_v & DTD_V_START_MASK;
-}
-
-static inline int dtd_get_max_width(struct vpdma_dtd *dtd)
-{
- return (dtd->max_width_height >> DTD_MAX_WIDTH_SHFT) &
- DTD_MAX_WIDTH_MASK;
-}
-
-static inline int dtd_get_max_height(struct vpdma_dtd *dtd)
-{
- return (dtd->max_width_height >> DTD_MAX_HEIGHT_SHFT) &
- DTD_MAX_HEIGHT_MASK;
-}
-
-/*
- * configuration descriptor
- */
-struct vpdma_cfd {
- union {
- u32 dest_addr_offset;
- u32 w0;
- };
- union {
- u32 block_len; /* in words */
- u32 w1;
- };
- u32 payload_addr;
- u32 ctl_payload_len; /* in words */
-};
-
-/* Configuration descriptor specifics */
-
-#define CFD_PKT_TYPE 0xb
-
-#define CFD_DIRECT 1
-#define CFD_INDIRECT 0
-#define CFD_CLS_ADB 0
-#define CFD_CLS_BLOCK 1
-
-/* block_len */
-#define CFD__BLOCK_LEN_MASK 0xffff
-#define CFD__BLOCK_LEN_SHFT 0
-
-/* ctl_payload_len */
-#define CFD_PKT_TYPE_MASK 0x1f
-#define CFD_PKT_TYPE_SHFT 27
-#define CFD_DIRECT_MASK 0x01
-#define CFD_DIRECT_SHFT 26
-#define CFD_CLASS_MASK 0x03
-#define CFD_CLASS_SHFT 24
-#define CFD_DEST_MASK 0xff
-#define CFD_DEST_SHFT 16
-#define CFD_PAYLOAD_LEN_MASK 0xffff
-#define CFD_PAYLOAD_LEN_SHFT 0
-
-static inline u32 cfd_pkt_payload_len(bool direct, int cls, int dest,
- int payload_len)
-{
- return (CFD_PKT_TYPE << CFD_PKT_TYPE_SHFT) |
- (direct << CFD_DIRECT_SHFT) |
- (cls << CFD_CLASS_SHFT) |
- (dest << CFD_DEST_SHFT) |
- payload_len;
-}
-
-static inline int cfd_get_pkt_type(struct vpdma_cfd *cfd)
-{
- return cfd->ctl_payload_len >> CFD_PKT_TYPE_SHFT;
-}
-
-static inline bool cfd_get_direct(struct vpdma_cfd *cfd)
-{
- return (cfd->ctl_payload_len >> CFD_DIRECT_SHFT) & CFD_DIRECT_MASK;
-}
-
-static inline bool cfd_get_class(struct vpdma_cfd *cfd)
-{
- return (cfd->ctl_payload_len >> CFD_CLASS_SHFT) & CFD_CLASS_MASK;
-}
-
-static inline int cfd_get_dest(struct vpdma_cfd *cfd)
-{
- return (cfd->ctl_payload_len >> CFD_DEST_SHFT) & CFD_DEST_MASK;
-}
-
-static inline int cfd_get_payload_len(struct vpdma_cfd *cfd)
-{
- return cfd->ctl_payload_len & CFD_PAYLOAD_LEN_MASK;
-}
-
-/*
- * control descriptor
- */
-struct vpdma_ctd {
- union {
- u32 timer_value;
- u32 list_addr;
- u32 w0;
- };
- union {
- u32 pixel_line_count;
- u32 list_size;
- u32 w1;
- };
- union {
- u32 event;
- u32 fid_ctl;
- u32 w2;
- };
- u32 type_source_ctl;
-};
-
-/* control descriptor types */
-#define CTD_TYPE_SYNC_ON_CLIENT 0
-#define CTD_TYPE_SYNC_ON_LIST 1
-#define CTD_TYPE_SYNC_ON_EXT 2
-#define CTD_TYPE_SYNC_ON_LM_TIMER 3
-#define CTD_TYPE_SYNC_ON_CHANNEL 4
-#define CTD_TYPE_CHNG_CLIENT_IRQ 5
-#define CTD_TYPE_SEND_IRQ 6
-#define CTD_TYPE_RELOAD_LIST 7
-#define CTD_TYPE_ABORT_CHANNEL 8
-
-#define CTD_PKT_TYPE 0xc
-
-/* timer_value */
-#define CTD_TIMER_VALUE_MASK 0xffff
-#define CTD_TIMER_VALUE_SHFT 0
-
-/* pixel_line_count */
-#define CTD_PIXEL_COUNT_MASK 0xffff
-#define CTD_PIXEL_COUNT_SHFT 16
-#define CTD_LINE_COUNT_MASK 0xffff
-#define CTD_LINE_COUNT_SHFT 0
-
-/* list_size */
-#define CTD_LIST_SIZE_MASK 0xffff
-#define CTD_LIST_SIZE_SHFT 0
-
-/* event */
-#define CTD_EVENT_MASK 0x0f
-#define CTD_EVENT_SHFT 0
-
-/* fid_ctl */
-#define CTD_FID2_MASK 0x03
-#define CTD_FID2_SHFT 4
-#define CTD_FID1_MASK 0x03
-#define CTD_FID1_SHFT 2
-#define CTD_FID0_MASK 0x03
-#define CTD_FID0_SHFT 0
-
-/* type_source_ctl */
-#define CTD_PKT_TYPE_MASK 0x1f
-#define CTD_PKT_TYPE_SHFT 27
-#define CTD_SOURCE_MASK 0xff
-#define CTD_SOURCE_SHFT 16
-#define CTD_CONTROL_MASK 0x0f
-#define CTD_CONTROL_SHFT 0
-
-static inline u32 ctd_pixel_line_count(int pixel_count, int line_count)
-{
- return (pixel_count << CTD_PIXEL_COUNT_SHFT) | line_count;
-}
-
-static inline u32 ctd_set_fid_ctl(int fid0, int fid1, int fid2)
-{
- return (fid2 << CTD_FID2_SHFT) | (fid1 << CTD_FID1_SHFT) | fid0;
-}
-
-static inline u32 ctd_type_source_ctl(int source, int control)
-{
- return (CTD_PKT_TYPE << CTD_PKT_TYPE_SHFT) |
- (source << CTD_SOURCE_SHFT) | control;
-}
-
-static inline u32 ctd_get_pixel_count(struct vpdma_ctd *ctd)
-{
- return ctd->pixel_line_count >> CTD_PIXEL_COUNT_SHFT;
-}
-
-static inline int ctd_get_line_count(struct vpdma_ctd *ctd)
-{
- return ctd->pixel_line_count & CTD_LINE_COUNT_MASK;
-}
-
-static inline int ctd_get_event(struct vpdma_ctd *ctd)
-{
- return ctd->event & CTD_EVENT_MASK;
-}
-
-static inline int ctd_get_fid2_ctl(struct vpdma_ctd *ctd)
-{
- return (ctd->fid_ctl >> CTD_FID2_SHFT) & CTD_FID2_MASK;
-}
-
-static inline int ctd_get_fid1_ctl(struct vpdma_ctd *ctd)
-{
- return (ctd->fid_ctl >> CTD_FID1_SHFT) & CTD_FID1_MASK;
-}
-
-static inline int ctd_get_fid0_ctl(struct vpdma_ctd *ctd)
-{
- return ctd->fid_ctl & CTD_FID2_MASK;
-}
-
-static inline int ctd_get_pkt_type(struct vpdma_ctd *ctd)
-{
- return ctd->type_source_ctl >> CTD_PKT_TYPE_SHFT;
-}
-
-static inline int ctd_get_source(struct vpdma_ctd *ctd)
-{
- return (ctd->type_source_ctl >> CTD_SOURCE_SHFT) & CTD_SOURCE_MASK;
-}
-
-static inline int ctd_get_ctl(struct vpdma_ctd *ctd)
-{
- return ctd->type_source_ctl & CTD_CONTROL_MASK;
-}
-
-#endif
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
deleted file mode 100644
index 5b1c5d96a407..000000000000
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ /dev/null
@@ -1,2665 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * TI VPE mem2mem driver, based on the virtual v4l2-mem2mem example driver
- *
- * Copyright (c) 2013 Texas Instruments Inc.
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- * Pawel Osciak,
- * Marek Szyprowski,
- *
- * Based on the virtual v4l2-mem2mem example device
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "vpdma.h"
-#include "vpdma_priv.h"
-#include "vpe_regs.h"
-#include "sc.h"
-#include "csc.h"
-
-#define VPE_MODULE_NAME "vpe"
-
-/* minimum and maximum frame sizes */
-#define MIN_W 32
-#define MIN_H 32
-#define MAX_W 2048
-#define MAX_H 2048
-
-/* required alignments */
-#define S_ALIGN 0 /* multiple of 1 */
-#define H_ALIGN 1 /* multiple of 2 */
-
-/* flags that indicate a format can be used for capture/output */
-#define VPE_FMT_TYPE_CAPTURE (1 << 0)
-#define VPE_FMT_TYPE_OUTPUT (1 << 1)
-
-/* used as plane indices */
-#define VPE_MAX_PLANES 2
-#define VPE_LUMA 0
-#define VPE_CHROMA 1
-
-/* per m2m context info */
-#define VPE_MAX_SRC_BUFS 3 /* need 3 src fields to de-interlace */
-
-#define VPE_DEF_BUFS_PER_JOB 1 /* default one buffer per batch job */
-
-/*
- * each VPE context can need up to 3 config descriptors, 7 input descriptors,
- * 3 output descriptors, and 10 control descriptors
- */
-#define VPE_DESC_LIST_SIZE (10 * VPDMA_DTD_DESC_SIZE + \
- 13 * VPDMA_CFD_CTD_DESC_SIZE)
-
-#define vpe_dbg(vpedev, fmt, arg...) \
- dev_dbg((vpedev)->v4l2_dev.dev, fmt, ##arg)
-#define vpe_err(vpedev, fmt, arg...) \
- dev_err((vpedev)->v4l2_dev.dev, fmt, ##arg)
-
-struct vpe_us_coeffs {
- unsigned short anchor_fid0_c0;
- unsigned short anchor_fid0_c1;
- unsigned short anchor_fid0_c2;
- unsigned short anchor_fid0_c3;
- unsigned short interp_fid0_c0;
- unsigned short interp_fid0_c1;
- unsigned short interp_fid0_c2;
- unsigned short interp_fid0_c3;
- unsigned short anchor_fid1_c0;
- unsigned short anchor_fid1_c1;
- unsigned short anchor_fid1_c2;
- unsigned short anchor_fid1_c3;
- unsigned short interp_fid1_c0;
- unsigned short interp_fid1_c1;
- unsigned short interp_fid1_c2;
- unsigned short interp_fid1_c3;
-};
-
-/*
- * Default upsampler coefficients
- */
-static const struct vpe_us_coeffs us_coeffs[] = {
- {
- /* Coefficients for progressive input */
- 0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8,
- 0x00C8, 0x0348, 0x0018, 0x3FD8, 0x3FB8, 0x0378, 0x00E8, 0x3FE8,
- },
- {
- /* Coefficients for Top Field Interlaced input */
- 0x0051, 0x03D5, 0x3FE3, 0x3FF7, 0x3FB5, 0x02E9, 0x018F, 0x3FD3,
- /* Coefficients for Bottom Field Interlaced input */
- 0x016B, 0x0247, 0x00B1, 0x3F9D, 0x3FCF, 0x03DB, 0x005D, 0x3FF9,
- },
-};
-
-/*
- * the following registers are for configuring some of the parameters of the
- * motion and edge detection blocks inside DEI, these generally remain the same,
- * these could be passed later via userspace if some one needs to tweak these.
- */
-struct vpe_dei_regs {
- unsigned long mdt_spacial_freq_thr_reg; /* VPE_DEI_REG2 */
- unsigned long edi_config_reg; /* VPE_DEI_REG3 */
- unsigned long edi_lut_reg0; /* VPE_DEI_REG4 */
- unsigned long edi_lut_reg1; /* VPE_DEI_REG5 */
- unsigned long edi_lut_reg2; /* VPE_DEI_REG6 */
- unsigned long edi_lut_reg3; /* VPE_DEI_REG7 */
-};
-
-/*
- * default expert DEI register values, unlikely to be modified.
- */
-static const struct vpe_dei_regs dei_regs = {
- .mdt_spacial_freq_thr_reg = 0x020C0804u,
- .edi_config_reg = 0x0118100Cu,
- .edi_lut_reg0 = 0x08040200u,
- .edi_lut_reg1 = 0x1010100Cu,
- .edi_lut_reg2 = 0x10101010u,
- .edi_lut_reg3 = 0x10101010u,
-};
-
-/*
- * The port_data structure contains per-port data.
- */
-struct vpe_port_data {
- enum vpdma_channel channel; /* VPDMA channel */
- u8 vb_index; /* input frame f, f-1, f-2 index */
- u8 vb_part; /* plane index for co-panar formats */
-};
-
-/*
- * Define indices into the port_data tables
- */
-#define VPE_PORT_LUMA1_IN 0
-#define VPE_PORT_CHROMA1_IN 1
-#define VPE_PORT_LUMA2_IN 2
-#define VPE_PORT_CHROMA2_IN 3
-#define VPE_PORT_LUMA3_IN 4
-#define VPE_PORT_CHROMA3_IN 5
-#define VPE_PORT_MV_IN 6
-#define VPE_PORT_MV_OUT 7
-#define VPE_PORT_LUMA_OUT 8
-#define VPE_PORT_CHROMA_OUT 9
-#define VPE_PORT_RGB_OUT 10
-
-static const struct vpe_port_data port_data[11] = {
- [VPE_PORT_LUMA1_IN] = {
- .channel = VPE_CHAN_LUMA1_IN,
- .vb_index = 0,
- .vb_part = VPE_LUMA,
- },
- [VPE_PORT_CHROMA1_IN] = {
- .channel = VPE_CHAN_CHROMA1_IN,
- .vb_index = 0,
- .vb_part = VPE_CHROMA,
- },
- [VPE_PORT_LUMA2_IN] = {
- .channel = VPE_CHAN_LUMA2_IN,
- .vb_index = 1,
- .vb_part = VPE_LUMA,
- },
- [VPE_PORT_CHROMA2_IN] = {
- .channel = VPE_CHAN_CHROMA2_IN,
- .vb_index = 1,
- .vb_part = VPE_CHROMA,
- },
- [VPE_PORT_LUMA3_IN] = {
- .channel = VPE_CHAN_LUMA3_IN,
- .vb_index = 2,
- .vb_part = VPE_LUMA,
- },
- [VPE_PORT_CHROMA3_IN] = {
- .channel = VPE_CHAN_CHROMA3_IN,
- .vb_index = 2,
- .vb_part = VPE_CHROMA,
- },
- [VPE_PORT_MV_IN] = {
- .channel = VPE_CHAN_MV_IN,
- },
- [VPE_PORT_MV_OUT] = {
- .channel = VPE_CHAN_MV_OUT,
- },
- [VPE_PORT_LUMA_OUT] = {
- .channel = VPE_CHAN_LUMA_OUT,
- .vb_part = VPE_LUMA,
- },
- [VPE_PORT_CHROMA_OUT] = {
- .channel = VPE_CHAN_CHROMA_OUT,
- .vb_part = VPE_CHROMA,
- },
- [VPE_PORT_RGB_OUT] = {
- .channel = VPE_CHAN_RGB_OUT,
- .vb_part = VPE_LUMA,
- },
-};
-
-
-/* driver info for each of the supported video formats */
-struct vpe_fmt {
- u32 fourcc; /* standard format identifier */
- u8 types; /* CAPTURE and/or OUTPUT */
- u8 coplanar; /* set for unpacked Luma and Chroma */
- /* vpdma format info for each plane */
- struct vpdma_data_format const *vpdma_fmt[VPE_MAX_PLANES];
-};
-
-static struct vpe_fmt vpe_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_NV16,
- .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
- .coplanar = 1,
- .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y444],
- &vpdma_yuv_fmts[VPDMA_DATA_FMT_C444],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_NV12,
- .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
- .coplanar = 1,
- .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y420],
- &vpdma_yuv_fmts[VPDMA_DATA_FMT_C420],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_NV21,
- .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
- .coplanar = 1,
- .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_Y420],
- &vpdma_yuv_fmts[VPDMA_DATA_FMT_CB420],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
- .coplanar = 0,
- .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_YCB422],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
- .coplanar = 0,
- .vpdma_fmt = { &vpdma_yuv_fmts[VPDMA_DATA_FMT_CBY422],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_RGB24,
- .types = VPE_FMT_TYPE_CAPTURE,
- .coplanar = 0,
- .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB24],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_RGB32,
- .types = VPE_FMT_TYPE_CAPTURE,
- .coplanar = 0,
- .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ARGB32],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_BGR24,
- .types = VPE_FMT_TYPE_CAPTURE,
- .coplanar = 0,
- .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_BGR24],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_BGR32,
- .types = VPE_FMT_TYPE_CAPTURE,
- .coplanar = 0,
- .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_ABGR32],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_RGB565,
- .types = VPE_FMT_TYPE_CAPTURE,
- .coplanar = 0,
- .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGB565],
- },
- },
- {
- .fourcc = V4L2_PIX_FMT_RGB555,
- .types = VPE_FMT_TYPE_CAPTURE,
- .coplanar = 0,
- .vpdma_fmt = { &vpdma_rgb_fmts[VPDMA_DATA_FMT_RGBA16_5551],
- },
- },
-};
-
-/*
- * per-queue, driver-specific private data.
- * there is one source queue and one destination queue for each m2m context.
- */
-struct vpe_q_data {
- /* current v4l2 format info */
- struct v4l2_format format;
- unsigned int flags;
- struct v4l2_rect c_rect; /* crop/compose rectangle */
- struct vpe_fmt *fmt; /* format info */
-};
-
-/* vpe_q_data flag bits */
-#define Q_DATA_FRAME_1D BIT(0)
-#define Q_DATA_MODE_TILED BIT(1)
-#define Q_DATA_INTERLACED_ALTERNATE BIT(2)
-#define Q_DATA_INTERLACED_SEQ_TB BIT(3)
-#define Q_DATA_INTERLACED_SEQ_BT BIT(4)
-
-#define Q_IS_SEQ_XX (Q_DATA_INTERLACED_SEQ_TB | \
- Q_DATA_INTERLACED_SEQ_BT)
-
-#define Q_IS_INTERLACED (Q_DATA_INTERLACED_ALTERNATE | \
- Q_DATA_INTERLACED_SEQ_TB | \
- Q_DATA_INTERLACED_SEQ_BT)
-
-enum {
- Q_DATA_SRC = 0,
- Q_DATA_DST = 1,
-};
-
-/* find our format description corresponding to the passed v4l2_format */
-static struct vpe_fmt *__find_format(u32 fourcc)
-{
- struct vpe_fmt *fmt;
- unsigned int k;
-
- for (k = 0; k < ARRAY_SIZE(vpe_formats); k++) {
- fmt = &vpe_formats[k];
- if (fmt->fourcc == fourcc)
- return fmt;
- }
-
- return NULL;
-}
-
-static struct vpe_fmt *find_format(struct v4l2_format *f)
-{
- return __find_format(f->fmt.pix.pixelformat);
-}
-
-/*
- * there is one vpe_dev structure in the driver, it is shared by
- * all instances.
- */
-struct vpe_dev {
- struct v4l2_device v4l2_dev;
- struct video_device vfd;
- struct v4l2_m2m_dev *m2m_dev;
-
- atomic_t num_instances; /* count of driver instances */
- dma_addr_t loaded_mmrs; /* shadow mmrs in device */
- struct mutex dev_mutex;
- spinlock_t lock;
-
- int irq;
- void __iomem *base;
- struct resource *res;
-
- struct vpdma_data vpdma_data;
- struct vpdma_data *vpdma; /* vpdma data handle */
- struct sc_data *sc; /* scaler data handle */
- struct csc_data *csc; /* csc data handle */
-};
-
-/*
- * There is one vpe_ctx structure for each m2m context.
- */
-struct vpe_ctx {
- struct v4l2_fh fh;
- struct vpe_dev *dev;
- struct v4l2_ctrl_handler hdl;
-
- unsigned int field; /* current field */
- unsigned int sequence; /* current frame/field seq */
- unsigned int aborting; /* abort after next irq */
-
- unsigned int bufs_per_job; /* input buffers per batch */
- unsigned int bufs_completed; /* bufs done in this batch */
-
- struct vpe_q_data q_data[2]; /* src & dst queue data */
- struct vb2_v4l2_buffer *src_vbs[VPE_MAX_SRC_BUFS];
- struct vb2_v4l2_buffer *dst_vb;
-
- dma_addr_t mv_buf_dma[2]; /* dma addrs of motion vector in/out bufs */
- void *mv_buf[2]; /* virtual addrs of motion vector bufs */
- size_t mv_buf_size; /* current motion vector buffer size */
- struct vpdma_buf mmr_adb; /* shadow reg addr/data block */
- struct vpdma_buf sc_coeff_h; /* h coeff buffer */
- struct vpdma_buf sc_coeff_v; /* v coeff buffer */
- struct vpdma_desc_list desc_list; /* DMA descriptor list */
-
- bool deinterlacing; /* using de-interlacer */
- bool load_mmrs; /* have new shadow reg values */
-
- unsigned int src_mv_buf_selector;
-};
-
-
-/*
- * M2M devices get 2 queues.
- * Return the queue given the type.
- */
-static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx,
- enum v4l2_buf_type type)
-{
- switch (type) {
- case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- return &ctx->q_data[Q_DATA_SRC];
- case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- return &ctx->q_data[Q_DATA_DST];
- default:
- return NULL;
- }
- return NULL;
-}
-
-static u32 read_reg(struct vpe_dev *dev, int offset)
-{
- return ioread32(dev->base + offset);
-}
-
-static void write_reg(struct vpe_dev *dev, int offset, u32 value)
-{
- iowrite32(value, dev->base + offset);
-}
-
-/* register field read/write helpers */
-static int get_field(u32 value, u32 mask, int shift)
-{
- return (value & (mask << shift)) >> shift;
-}
-
-static int read_field_reg(struct vpe_dev *dev, int offset, u32 mask, int shift)
-{
- return get_field(read_reg(dev, offset), mask, shift);
-}
-
-static void write_field(u32 *valp, u32 field, u32 mask, int shift)
-{
- u32 val = *valp;
-
- val &= ~(mask << shift);
- val |= (field & mask) << shift;
- *valp = val;
-}
-
-static void write_field_reg(struct vpe_dev *dev, int offset, u32 field,
- u32 mask, int shift)
-{
- u32 val = read_reg(dev, offset);
-
- write_field(&val, field, mask, shift);
-
- write_reg(dev, offset, val);
-}
-
-/*
- * DMA address/data block for the shadow registers
- */
-struct vpe_mmr_adb {
- struct vpdma_adb_hdr out_fmt_hdr;
- u32 out_fmt_reg[1];
- u32 out_fmt_pad[3];
- struct vpdma_adb_hdr us1_hdr;
- u32 us1_regs[8];
- struct vpdma_adb_hdr us2_hdr;
- u32 us2_regs[8];
- struct vpdma_adb_hdr us3_hdr;
- u32 us3_regs[8];
- struct vpdma_adb_hdr dei_hdr;
- u32 dei_regs[8];
- struct vpdma_adb_hdr sc_hdr0;
- u32 sc_regs0[7];
- u32 sc_pad0[1];
- struct vpdma_adb_hdr sc_hdr8;
- u32 sc_regs8[6];
- u32 sc_pad8[2];
- struct vpdma_adb_hdr sc_hdr17;
- u32 sc_regs17[9];
- u32 sc_pad17[3];
- struct vpdma_adb_hdr csc_hdr;
- u32 csc_regs[6];
- u32 csc_pad[2];
-};
-
-#define GET_OFFSET_TOP(ctx, obj, reg) \
- ((obj)->res->start - ctx->dev->res->start + reg)
-
-#define VPE_SET_MMR_ADB_HDR(ctx, hdr, regs, offset_a) \
- VPDMA_SET_MMR_ADB_HDR(ctx->mmr_adb, vpe_mmr_adb, hdr, regs, offset_a)
-/*
- * Set the headers for all of the address/data block structures.
- */
-static void init_adb_hdrs(struct vpe_ctx *ctx)
-{
- VPE_SET_MMR_ADB_HDR(ctx, out_fmt_hdr, out_fmt_reg, VPE_CLK_FORMAT_SELECT);
- VPE_SET_MMR_ADB_HDR(ctx, us1_hdr, us1_regs, VPE_US1_R0);
- VPE_SET_MMR_ADB_HDR(ctx, us2_hdr, us2_regs, VPE_US2_R0);
- VPE_SET_MMR_ADB_HDR(ctx, us3_hdr, us3_regs, VPE_US3_R0);
- VPE_SET_MMR_ADB_HDR(ctx, dei_hdr, dei_regs, VPE_DEI_FRAME_SIZE);
- VPE_SET_MMR_ADB_HDR(ctx, sc_hdr0, sc_regs0,
- GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC0));
- VPE_SET_MMR_ADB_HDR(ctx, sc_hdr8, sc_regs8,
- GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC8));
- VPE_SET_MMR_ADB_HDR(ctx, sc_hdr17, sc_regs17,
- GET_OFFSET_TOP(ctx, ctx->dev->sc, CFG_SC17));
- VPE_SET_MMR_ADB_HDR(ctx, csc_hdr, csc_regs,
- GET_OFFSET_TOP(ctx, ctx->dev->csc, CSC_CSC00));
-};
-
-/*
- * Allocate or re-allocate the motion vector DMA buffers
- * There are two buffers, one for input and one for output.
- * However, the roles are reversed after each field is processed.
- * In other words, after each field is processed, the previous
- * output (dst) MV buffer becomes the new input (src) MV buffer.
- */
-static int realloc_mv_buffers(struct vpe_ctx *ctx, size_t size)
-{
- struct device *dev = ctx->dev->v4l2_dev.dev;
-
- if (ctx->mv_buf_size == size)
- return 0;
-
- if (ctx->mv_buf[0])
- dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[0],
- ctx->mv_buf_dma[0]);
-
- if (ctx->mv_buf[1])
- dma_free_coherent(dev, ctx->mv_buf_size, ctx->mv_buf[1],
- ctx->mv_buf_dma[1]);
-
- if (size == 0)
- return 0;
-
- ctx->mv_buf[0] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[0],
- GFP_KERNEL);
- if (!ctx->mv_buf[0]) {
- vpe_err(ctx->dev, "failed to allocate motion vector buffer\n");
- return -ENOMEM;
- }
-
- ctx->mv_buf[1] = dma_alloc_coherent(dev, size, &ctx->mv_buf_dma[1],
- GFP_KERNEL);
- if (!ctx->mv_buf[1]) {
- vpe_err(ctx->dev, "failed to allocate motion vector buffer\n");
- dma_free_coherent(dev, size, ctx->mv_buf[0],
- ctx->mv_buf_dma[0]);
-
- return -ENOMEM;
- }
-
- ctx->mv_buf_size = size;
- ctx->src_mv_buf_selector = 0;
-
- return 0;
-}
-
-static void free_mv_buffers(struct vpe_ctx *ctx)
-{
- realloc_mv_buffers(ctx, 0);
-}
-
-/*
- * While de-interlacing, we keep the two most recent input buffers
- * around. This function frees those two buffers when we have
- * finished processing the current stream.
- */
-static void free_vbs(struct vpe_ctx *ctx)
-{
- struct vpe_dev *dev = ctx->dev;
- unsigned long flags;
-
- if (ctx->src_vbs[2] == NULL)
- return;
-
- spin_lock_irqsave(&dev->lock, flags);
- if (ctx->src_vbs[2]) {
- v4l2_m2m_buf_done(ctx->src_vbs[2], VB2_BUF_STATE_DONE);
- if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2]))
- v4l2_m2m_buf_done(ctx->src_vbs[1], VB2_BUF_STATE_DONE);
- ctx->src_vbs[2] = NULL;
- ctx->src_vbs[1] = NULL;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-}
-
-/*
- * Enable or disable the VPE clocks
- */
-static void vpe_set_clock_enable(struct vpe_dev *dev, bool on)
-{
- u32 val = 0;
-
- if (on)
- val = VPE_DATA_PATH_CLK_ENABLE | VPE_VPEDMA_CLK_ENABLE;
- write_reg(dev, VPE_CLK_ENABLE, val);
-}
-
-static void vpe_top_reset(struct vpe_dev *dev)
-{
-
- write_field_reg(dev, VPE_CLK_RESET, 1, VPE_DATA_PATH_CLK_RESET_MASK,
- VPE_DATA_PATH_CLK_RESET_SHIFT);
-
- usleep_range(100, 150);
-
- write_field_reg(dev, VPE_CLK_RESET, 0, VPE_DATA_PATH_CLK_RESET_MASK,
- VPE_DATA_PATH_CLK_RESET_SHIFT);
-}
-
-static void vpe_top_vpdma_reset(struct vpe_dev *dev)
-{
- write_field_reg(dev, VPE_CLK_RESET, 1, VPE_VPDMA_CLK_RESET_MASK,
- VPE_VPDMA_CLK_RESET_SHIFT);
-
- usleep_range(100, 150);
-
- write_field_reg(dev, VPE_CLK_RESET, 0, VPE_VPDMA_CLK_RESET_MASK,
- VPE_VPDMA_CLK_RESET_SHIFT);
-}
-
-/*
- * Load the correct of upsampler coefficients into the shadow MMRs
- */
-static void set_us_coefficients(struct vpe_ctx *ctx)
-{
- struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
- struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
- u32 *us1_reg = &mmr_adb->us1_regs[0];
- u32 *us2_reg = &mmr_adb->us2_regs[0];
- u32 *us3_reg = &mmr_adb->us3_regs[0];
- const unsigned short *cp, *end_cp;
-
- cp = &us_coeffs[0].anchor_fid0_c0;
-
- if (s_q_data->flags & Q_IS_INTERLACED) /* interlaced */
- cp += sizeof(us_coeffs[0]) / sizeof(*cp);
-
- end_cp = cp + sizeof(us_coeffs[0]) / sizeof(*cp);
-
- while (cp < end_cp) {
- write_field(us1_reg, *cp++, VPE_US_C0_MASK, VPE_US_C0_SHIFT);
- write_field(us1_reg, *cp++, VPE_US_C1_MASK, VPE_US_C1_SHIFT);
- *us2_reg++ = *us1_reg;
- *us3_reg++ = *us1_reg++;
- }
- ctx->load_mmrs = true;
-}
-
-/*
- * Set the upsampler config mode and the VPDMA line mode in the shadow MMRs.
- */
-static void set_cfg_modes(struct vpe_ctx *ctx)
-{
- struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt;
- struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
- u32 *us1_reg0 = &mmr_adb->us1_regs[0];
- u32 *us2_reg0 = &mmr_adb->us2_regs[0];
- u32 *us3_reg0 = &mmr_adb->us3_regs[0];
- int cfg_mode = 1;
-
- /*
- * Cfg Mode 0: YUV420 source, enable upsampler, DEI is de-interlacing.
- * Cfg Mode 1: YUV422 source, disable upsampler, DEI is de-interlacing.
- */
-
- if (fmt->fourcc == V4L2_PIX_FMT_NV12 ||
- fmt->fourcc == V4L2_PIX_FMT_NV21)
- cfg_mode = 0;
-
- write_field(us1_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
- write_field(us2_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
- write_field(us3_reg0, cfg_mode, VPE_US_MODE_MASK, VPE_US_MODE_SHIFT);
-
- ctx->load_mmrs = true;
-}
-
-static void set_line_modes(struct vpe_ctx *ctx)
-{
- struct vpe_fmt *fmt = ctx->q_data[Q_DATA_SRC].fmt;
- int line_mode = 1;
-
- if (fmt->fourcc == V4L2_PIX_FMT_NV12 ||
- fmt->fourcc == V4L2_PIX_FMT_NV21)
- line_mode = 0; /* double lines to line buffer */
-
- /* regs for now */
- vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA1_IN);
- vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA2_IN);
- vpdma_set_line_mode(ctx->dev->vpdma, line_mode, VPE_CHAN_CHROMA3_IN);
-
- /* frame start for input luma */
- vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
- VPE_CHAN_LUMA1_IN);
- vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
- VPE_CHAN_LUMA2_IN);
- vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
- VPE_CHAN_LUMA3_IN);
-
- /* frame start for input chroma */
- vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
- VPE_CHAN_CHROMA1_IN);
- vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
- VPE_CHAN_CHROMA2_IN);
- vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
- VPE_CHAN_CHROMA3_IN);
-
- /* frame start for MV in client */
- vpdma_set_frame_start_event(ctx->dev->vpdma, VPDMA_FSEVENT_CHANNEL_ACTIVE,
- VPE_CHAN_MV_IN);
-}
-
-/*
- * Set the shadow registers that are modified when the source
- * format changes.
- */
-static void set_src_registers(struct vpe_ctx *ctx)
-{
- set_us_coefficients(ctx);
-}
-
-/*
- * Set the shadow registers that are modified when the destination
- * format changes.
- */
-static void set_dst_registers(struct vpe_ctx *ctx)
-{
- struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
- struct vpe_fmt *fmt = ctx->q_data[Q_DATA_DST].fmt;
- const struct v4l2_format_info *finfo;
- u32 val = 0;
-
- finfo = v4l2_format_info(fmt->fourcc);
- if (v4l2_is_format_rgb(finfo)) {
- val |= VPE_RGB_OUT_SELECT;
- vpdma_set_bg_color(ctx->dev->vpdma,
- (struct vpdma_data_format *)fmt->vpdma_fmt[0], 0xff);
- } else if (fmt->fourcc == V4L2_PIX_FMT_NV16)
- val |= VPE_COLOR_SEPARATE_422;
-
- /*
- * the source of CHR_DS and CSC is always the scaler, irrespective of
- * whether it's used or not
- */
- val |= VPE_DS_SRC_DEI_SCALER | VPE_CSC_SRC_DEI_SCALER;
-
- if (fmt->fourcc != V4L2_PIX_FMT_NV12 &&
- fmt->fourcc != V4L2_PIX_FMT_NV21)
- val |= VPE_DS_BYPASS;
-
- mmr_adb->out_fmt_reg[0] = val;
-
- ctx->load_mmrs = true;
-}
-
-/*
- * Set the de-interlacer shadow register values
- */
-static void set_dei_regs(struct vpe_ctx *ctx)
-{
- struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
- struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
- unsigned int src_h = s_q_data->c_rect.height;
- unsigned int src_w = s_q_data->c_rect.width;
- u32 *dei_mmr0 = &mmr_adb->dei_regs[0];
- bool deinterlace = true;
- u32 val = 0;
-
- /*
- * according to TRM, we should set DEI in progressive bypass mode when
- * the input content is progressive, however, DEI is bypassed correctly
- * for both progressive and interlace content in interlace bypass mode.
- * It has been recommended not to use progressive bypass mode.
- */
- if (!(s_q_data->flags & Q_IS_INTERLACED) || !ctx->deinterlacing) {
- deinterlace = false;
- val = VPE_DEI_INTERLACE_BYPASS;
- }
-
- src_h = deinterlace ? src_h * 2 : src_h;
-
- val |= (src_h << VPE_DEI_HEIGHT_SHIFT) |
- (src_w << VPE_DEI_WIDTH_SHIFT) |
- VPE_DEI_FIELD_FLUSH;
-
- *dei_mmr0 = val;
-
- ctx->load_mmrs = true;
-}
-
-static void set_dei_shadow_registers(struct vpe_ctx *ctx)
-{
- struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
- u32 *dei_mmr = &mmr_adb->dei_regs[0];
- const struct vpe_dei_regs *cur = &dei_regs;
-
- dei_mmr[2] = cur->mdt_spacial_freq_thr_reg;
- dei_mmr[3] = cur->edi_config_reg;
- dei_mmr[4] = cur->edi_lut_reg0;
- dei_mmr[5] = cur->edi_lut_reg1;
- dei_mmr[6] = cur->edi_lut_reg2;
- dei_mmr[7] = cur->edi_lut_reg3;
-
- ctx->load_mmrs = true;
-}
-
-static void config_edi_input_mode(struct vpe_ctx *ctx, int mode)
-{
- struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
- u32 *edi_config_reg = &mmr_adb->dei_regs[3];
-
- if (mode & 0x2)
- write_field(edi_config_reg, 1, 1, 2); /* EDI_ENABLE_3D */
-
- if (mode & 0x3)
- write_field(edi_config_reg, 1, 1, 3); /* EDI_CHROMA_3D */
-
- write_field(edi_config_reg, mode, VPE_EDI_INP_MODE_MASK,
- VPE_EDI_INP_MODE_SHIFT);
-
- ctx->load_mmrs = true;
-}
-
-/*
- * Set the shadow registers whose values are modified when either the
- * source or destination format is changed.
- */
-static int set_srcdst_params(struct vpe_ctx *ctx)
-{
- struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
- struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
- struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr;
- unsigned int src_w = s_q_data->c_rect.width;
- unsigned int src_h = s_q_data->c_rect.height;
- unsigned int dst_w = d_q_data->c_rect.width;
- unsigned int dst_h = d_q_data->c_rect.height;
- struct v4l2_pix_format_mplane *spix;
- size_t mv_buf_size;
- int ret;
-
- ctx->sequence = 0;
- ctx->field = V4L2_FIELD_TOP;
- spix = &s_q_data->format.fmt.pix_mp;
-
- if ((s_q_data->flags & Q_IS_INTERLACED) &&
- !(d_q_data->flags & Q_IS_INTERLACED)) {
- int bytes_per_line;
- const struct vpdma_data_format *mv =
- &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
-
- /*
- * we make sure that the source image has a 16 byte aligned
- * stride, we need to do the same for the motion vector buffer
- * by aligning it's stride to the next 16 byte boundary. this
- * extra space will not be used by the de-interlacer, but will
- * ensure that vpdma operates correctly
- */
- bytes_per_line = ALIGN((spix->width * mv->depth) >> 3,
- VPDMA_STRIDE_ALIGN);
- mv_buf_size = bytes_per_line * spix->height;
-
- ctx->deinterlacing = true;
- src_h <<= 1;
- } else {
- ctx->deinterlacing = false;
- mv_buf_size = 0;
- }
-
- free_vbs(ctx);
- ctx->src_vbs[2] = ctx->src_vbs[1] = ctx->src_vbs[0] = NULL;
-
- ret = realloc_mv_buffers(ctx, mv_buf_size);
- if (ret)
- return ret;
-
- set_cfg_modes(ctx);
- set_dei_regs(ctx);
-
- csc_set_coeff(ctx->dev->csc, &mmr_adb->csc_regs[0],
- &s_q_data->format, &d_q_data->format);
-
- sc_set_hs_coeffs(ctx->dev->sc, ctx->sc_coeff_h.addr, src_w, dst_w);
- sc_set_vs_coeffs(ctx->dev->sc, ctx->sc_coeff_v.addr, src_h, dst_h);
-
- sc_config_scaler(ctx->dev->sc, &mmr_adb->sc_regs0[0],
- &mmr_adb->sc_regs8[0], &mmr_adb->sc_regs17[0],
- src_w, src_h, dst_w, dst_h);
-
- return 0;
-}
-
-/*
- * mem2mem callbacks
- */
-
-/*
- * job_ready() - check whether an instance is ready to be scheduled to run
- */
-static int job_ready(void *priv)
-{
- struct vpe_ctx *ctx = priv;
-
- /*
- * This check is needed as this might be called directly from driver
- * When called by m2m framework, this will always satisfy, but when
- * called from vpe_irq, this might fail. (src stream with zero buffers)
- */
- if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) <= 0 ||
- v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) <= 0)
- return 0;
-
- return 1;
-}
-
-static void job_abort(void *priv)
-{
- struct vpe_ctx *ctx = priv;
-
- /* Will cancel the transaction in the next interrupt handler */
- ctx->aborting = 1;
-}
-
-static void vpe_dump_regs(struct vpe_dev *dev)
-{
-#define DUMPREG(r) vpe_dbg(dev, "%-35s %08x\n", #r, read_reg(dev, VPE_##r))
-
- vpe_dbg(dev, "VPE Registers:\n");
-
- DUMPREG(PID);
- DUMPREG(SYSCONFIG);
- DUMPREG(INT0_STATUS0_RAW);
- DUMPREG(INT0_STATUS0);
- DUMPREG(INT0_ENABLE0);
- DUMPREG(INT0_STATUS1_RAW);
- DUMPREG(INT0_STATUS1);
- DUMPREG(INT0_ENABLE1);
- DUMPREG(CLK_ENABLE);
- DUMPREG(CLK_RESET);
- DUMPREG(CLK_FORMAT_SELECT);
- DUMPREG(CLK_RANGE_MAP);
- DUMPREG(US1_R0);
- DUMPREG(US1_R1);
- DUMPREG(US1_R2);
- DUMPREG(US1_R3);
- DUMPREG(US1_R4);
- DUMPREG(US1_R5);
- DUMPREG(US1_R6);
- DUMPREG(US1_R7);
- DUMPREG(US2_R0);
- DUMPREG(US2_R1);
- DUMPREG(US2_R2);
- DUMPREG(US2_R3);
- DUMPREG(US2_R4);
- DUMPREG(US2_R5);
- DUMPREG(US2_R6);
- DUMPREG(US2_R7);
- DUMPREG(US3_R0);
- DUMPREG(US3_R1);
- DUMPREG(US3_R2);
- DUMPREG(US3_R3);
- DUMPREG(US3_R4);
- DUMPREG(US3_R5);
- DUMPREG(US3_R6);
- DUMPREG(US3_R7);
- DUMPREG(DEI_FRAME_SIZE);
- DUMPREG(MDT_BYPASS);
- DUMPREG(MDT_SF_THRESHOLD);
- DUMPREG(EDI_CONFIG);
- DUMPREG(DEI_EDI_LUT_R0);
- DUMPREG(DEI_EDI_LUT_R1);
- DUMPREG(DEI_EDI_LUT_R2);
- DUMPREG(DEI_EDI_LUT_R3);
- DUMPREG(DEI_FMD_WINDOW_R0);
- DUMPREG(DEI_FMD_WINDOW_R1);
- DUMPREG(DEI_FMD_CONTROL_R0);
- DUMPREG(DEI_FMD_CONTROL_R1);
- DUMPREG(DEI_FMD_STATUS_R0);
- DUMPREG(DEI_FMD_STATUS_R1);
- DUMPREG(DEI_FMD_STATUS_R2);
-#undef DUMPREG
-
- sc_dump_regs(dev->sc);
- csc_dump_regs(dev->csc);
-}
-
-static void add_out_dtd(struct vpe_ctx *ctx, int port)
-{
- struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_DST];
- const struct vpe_port_data *p_data = &port_data[port];
- struct vb2_buffer *vb = &ctx->dst_vb->vb2_buf;
- struct vpe_fmt *fmt = q_data->fmt;
- const struct vpdma_data_format *vpdma_fmt;
- int mv_buf_selector = !ctx->src_mv_buf_selector;
- struct v4l2_pix_format_mplane *pix;
- dma_addr_t dma_addr;
- u32 flags = 0;
- u32 offset = 0;
- u32 stride;
-
- if (port == VPE_PORT_MV_OUT) {
- vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
- dma_addr = ctx->mv_buf_dma[mv_buf_selector];
- q_data = &ctx->q_data[Q_DATA_SRC];
- pix = &q_data->format.fmt.pix_mp;
- stride = ALIGN((pix->width * vpdma_fmt->depth) >> 3,
- VPDMA_STRIDE_ALIGN);
- } else {
- /* to incorporate interleaved formats */
- int plane = fmt->coplanar ? p_data->vb_part : 0;
-
- pix = &q_data->format.fmt.pix_mp;
- vpdma_fmt = fmt->vpdma_fmt[plane];
- /*
- * If we are using a single plane buffer and
- * we need to set a separate vpdma chroma channel.
- */
- if (pix->num_planes == 1 && plane) {
- dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
- /* Compute required offset */
- offset = pix->plane_fmt[0].bytesperline * pix->height;
- } else {
- dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane);
- /* Use address as is, no offset */
- offset = 0;
- }
- if (!dma_addr) {
- vpe_err(ctx->dev,
- "acquiring output buffer(%d) dma_addr failed\n",
- port);
- return;
- }
- /* Apply the offset */
- dma_addr += offset;
- stride = pix->plane_fmt[VPE_LUMA].bytesperline;
- }
-
- if (q_data->flags & Q_DATA_FRAME_1D)
- flags |= VPDMA_DATA_FRAME_1D;
- if (q_data->flags & Q_DATA_MODE_TILED)
- flags |= VPDMA_DATA_MODE_TILED;
-
- vpdma_set_max_size(ctx->dev->vpdma, VPDMA_MAX_SIZE1,
- MAX_W, MAX_H);
-
- vpdma_add_out_dtd(&ctx->desc_list, pix->width,
- stride, &q_data->c_rect,
- vpdma_fmt, dma_addr, MAX_OUT_WIDTH_REG1,
- MAX_OUT_HEIGHT_REG1, p_data->channel, flags);
-}
-
-static void add_in_dtd(struct vpe_ctx *ctx, int port)
-{
- struct vpe_q_data *q_data = &ctx->q_data[Q_DATA_SRC];
- const struct vpe_port_data *p_data = &port_data[port];
- struct vb2_buffer *vb = &ctx->src_vbs[p_data->vb_index]->vb2_buf;
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct vpe_fmt *fmt = q_data->fmt;
- struct v4l2_pix_format_mplane *pix;
- const struct vpdma_data_format *vpdma_fmt;
- int mv_buf_selector = ctx->src_mv_buf_selector;
- int field = vbuf->field == V4L2_FIELD_BOTTOM;
- int frame_width, frame_height;
- dma_addr_t dma_addr;
- u32 flags = 0;
- u32 offset = 0;
- u32 stride;
-
- pix = &q_data->format.fmt.pix_mp;
- if (port == VPE_PORT_MV_IN) {
- vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV];
- dma_addr = ctx->mv_buf_dma[mv_buf_selector];
- stride = ALIGN((pix->width * vpdma_fmt->depth) >> 3,
- VPDMA_STRIDE_ALIGN);
- } else {
- /* to incorporate interleaved formats */
- int plane = fmt->coplanar ? p_data->vb_part : 0;
-
- vpdma_fmt = fmt->vpdma_fmt[plane];
- /*
- * If we are using a single plane buffer and
- * we need to set a separate vpdma chroma channel.
- */
- if (pix->num_planes == 1 && plane) {
- dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
- /* Compute required offset */
- offset = pix->plane_fmt[0].bytesperline * pix->height;
- } else {
- dma_addr = vb2_dma_contig_plane_dma_addr(vb, plane);
- /* Use address as is, no offset */
- offset = 0;
- }
- if (!dma_addr) {
- vpe_err(ctx->dev,
- "acquiring output buffer(%d) dma_addr failed\n",
- port);
- return;
- }
- /* Apply the offset */
- dma_addr += offset;
- stride = pix->plane_fmt[VPE_LUMA].bytesperline;
-
- /*
- * field used in VPDMA desc = 0 (top) / 1 (bottom)
- * Use top or bottom field from same vb alternately
- * For each de-interlacing operation, f,f-1,f-2 should be one
- * of TBT or BTB
- */
- if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB ||
- q_data->flags & Q_DATA_INTERLACED_SEQ_BT) {
- /* Select initial value based on format */
- if (q_data->flags & Q_DATA_INTERLACED_SEQ_BT)
- field = 1;
- else
- field = 0;
-
- /* Toggle for each vb_index and each operation */
- field = (field + p_data->vb_index + ctx->sequence) % 2;
-
- if (field) {
- int height = pix->height / 2;
- int bpp;
-
- if (fmt->fourcc == V4L2_PIX_FMT_NV12 ||
- fmt->fourcc == V4L2_PIX_FMT_NV21)
- bpp = 1;
- else
- bpp = vpdma_fmt->depth >> 3;
-
- if (plane)
- height /= 2;
-
- dma_addr += pix->width * height * bpp;
- }
- }
- }
-
- if (q_data->flags & Q_DATA_FRAME_1D)
- flags |= VPDMA_DATA_FRAME_1D;
- if (q_data->flags & Q_DATA_MODE_TILED)
- flags |= VPDMA_DATA_MODE_TILED;
-
- frame_width = q_data->c_rect.width;
- frame_height = q_data->c_rect.height;
-
- if (p_data->vb_part && (fmt->fourcc == V4L2_PIX_FMT_NV12 ||
- fmt->fourcc == V4L2_PIX_FMT_NV21))
- frame_height /= 2;
-
- vpdma_add_in_dtd(&ctx->desc_list, pix->width, stride,
- &q_data->c_rect, vpdma_fmt, dma_addr,
- p_data->channel, field, flags, frame_width,
- frame_height, 0, 0);
-}
-
-/*
- * Enable the expected IRQ sources
- */
-static void enable_irqs(struct vpe_ctx *ctx)
-{
- write_reg(ctx->dev, VPE_INT0_ENABLE0_SET, VPE_INT0_LIST0_COMPLETE);
- write_reg(ctx->dev, VPE_INT0_ENABLE1_SET, VPE_DEI_ERROR_INT |
- VPE_DS1_UV_ERROR_INT);
-
- vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, true);
-}
-
-static void disable_irqs(struct vpe_ctx *ctx)
-{
- write_reg(ctx->dev, VPE_INT0_ENABLE0_CLR, 0xffffffff);
- write_reg(ctx->dev, VPE_INT0_ENABLE1_CLR, 0xffffffff);
-
- vpdma_enable_list_complete_irq(ctx->dev->vpdma, 0, 0, false);
-}
-
-/* device_run() - prepares and starts the device
- *
- * This function is only called when both the source and destination
- * buffers are in place.
- */
-static void device_run(void *priv)
-{
- struct vpe_ctx *ctx = priv;
- struct sc_data *sc = ctx->dev->sc;
- struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
- struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
- const struct v4l2_format_info *d_finfo;
-
- d_finfo = v4l2_format_info(d_q_data->fmt->fourcc);
-
- if (ctx->deinterlacing && s_q_data->flags & Q_IS_SEQ_XX &&
- ctx->sequence % 2 == 0) {
- /* When using SEQ_XX type buffers, each buffer has two fields
- * each buffer has two fields (top & bottom)
- * Removing one buffer is actually getting two fields
- * Alternate between two operations:-
- * Even : consume one field but DO NOT REMOVE from queue
- * Odd : consume other field and REMOVE from queue
- */
- ctx->src_vbs[0] = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
- WARN_ON(ctx->src_vbs[0] == NULL);
- } else {
- ctx->src_vbs[0] = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
- WARN_ON(ctx->src_vbs[0] == NULL);
- }
-
- ctx->dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
- WARN_ON(ctx->dst_vb == NULL);
-
- if (ctx->deinterlacing) {
-
- if (ctx->src_vbs[2] == NULL) {
- ctx->src_vbs[2] = ctx->src_vbs[0];
- WARN_ON(ctx->src_vbs[2] == NULL);
- ctx->src_vbs[1] = ctx->src_vbs[0];
- WARN_ON(ctx->src_vbs[1] == NULL);
- }
-
- /*
- * we have output the first 2 frames through line average, we
- * now switch to EDI de-interlacer
- */
- if (ctx->sequence == 2)
- config_edi_input_mode(ctx, 0x3); /* EDI (Y + UV) */
- }
-
- /* config descriptors */
- if (ctx->dev->loaded_mmrs != ctx->mmr_adb.dma_addr || ctx->load_mmrs) {
- vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->mmr_adb);
- vpdma_add_cfd_adb(&ctx->desc_list, CFD_MMR_CLIENT, &ctx->mmr_adb);
-
- set_line_modes(ctx);
-
- ctx->dev->loaded_mmrs = ctx->mmr_adb.dma_addr;
- ctx->load_mmrs = false;
- }
-
- if (sc->loaded_coeff_h != ctx->sc_coeff_h.dma_addr ||
- sc->load_coeff_h) {
- vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->sc_coeff_h);
- vpdma_add_cfd_block(&ctx->desc_list, CFD_SC_CLIENT,
- &ctx->sc_coeff_h, 0);
-
- sc->loaded_coeff_h = ctx->sc_coeff_h.dma_addr;
- sc->load_coeff_h = false;
- }
-
- if (sc->loaded_coeff_v != ctx->sc_coeff_v.dma_addr ||
- sc->load_coeff_v) {
- vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->sc_coeff_v);
- vpdma_add_cfd_block(&ctx->desc_list, CFD_SC_CLIENT,
- &ctx->sc_coeff_v, SC_COEF_SRAM_SIZE >> 4);
-
- sc->loaded_coeff_v = ctx->sc_coeff_v.dma_addr;
- sc->load_coeff_v = false;
- }
-
- /* output data descriptors */
- if (ctx->deinterlacing)
- add_out_dtd(ctx, VPE_PORT_MV_OUT);
-
- if (v4l2_is_format_rgb(d_finfo)) {
- add_out_dtd(ctx, VPE_PORT_RGB_OUT);
- } else {
- add_out_dtd(ctx, VPE_PORT_LUMA_OUT);
- if (d_q_data->fmt->coplanar)
- add_out_dtd(ctx, VPE_PORT_CHROMA_OUT);
- }
-
- /* input data descriptors */
- if (ctx->deinterlacing) {
- add_in_dtd(ctx, VPE_PORT_LUMA3_IN);
- add_in_dtd(ctx, VPE_PORT_CHROMA3_IN);
-
- add_in_dtd(ctx, VPE_PORT_LUMA2_IN);
- add_in_dtd(ctx, VPE_PORT_CHROMA2_IN);
- }
-
- add_in_dtd(ctx, VPE_PORT_LUMA1_IN);
- add_in_dtd(ctx, VPE_PORT_CHROMA1_IN);
-
- if (ctx->deinterlacing)
- add_in_dtd(ctx, VPE_PORT_MV_IN);
-
- /* sync on channel control descriptors for input ports */
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_LUMA1_IN);
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_CHROMA1_IN);
-
- if (ctx->deinterlacing) {
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
- VPE_CHAN_LUMA2_IN);
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
- VPE_CHAN_CHROMA2_IN);
-
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
- VPE_CHAN_LUMA3_IN);
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
- VPE_CHAN_CHROMA3_IN);
-
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_IN);
- }
-
- /* sync on channel control descriptors for output ports */
- if (v4l2_is_format_rgb(d_finfo)) {
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
- VPE_CHAN_RGB_OUT);
- } else {
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
- VPE_CHAN_LUMA_OUT);
- if (d_q_data->fmt->coplanar)
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list,
- VPE_CHAN_CHROMA_OUT);
- }
-
- if (ctx->deinterlacing)
- vpdma_add_sync_on_channel_ctd(&ctx->desc_list, VPE_CHAN_MV_OUT);
-
- enable_irqs(ctx);
-
- vpdma_map_desc_buf(ctx->dev->vpdma, &ctx->desc_list.buf);
- vpdma_submit_descs(ctx->dev->vpdma, &ctx->desc_list, 0);
-}
-
-static void dei_error(struct vpe_ctx *ctx)
-{
- dev_warn(ctx->dev->v4l2_dev.dev,
- "received DEI error interrupt\n");
-}
-
-static void ds1_uv_error(struct vpe_ctx *ctx)
-{
- dev_warn(ctx->dev->v4l2_dev.dev,
- "received downsampler error interrupt\n");
-}
-
-static irqreturn_t vpe_irq(int irq_vpe, void *data)
-{
- struct vpe_dev *dev = (struct vpe_dev *)data;
- struct vpe_ctx *ctx;
- struct vpe_q_data *d_q_data;
- struct vb2_v4l2_buffer *s_vb, *d_vb;
- unsigned long flags;
- u32 irqst0, irqst1;
- bool list_complete = false;
-
- irqst0 = read_reg(dev, VPE_INT0_STATUS0);
- if (irqst0) {
- write_reg(dev, VPE_INT0_STATUS0_CLR, irqst0);
- vpe_dbg(dev, "INT0_STATUS0 = 0x%08x\n", irqst0);
- }
-
- irqst1 = read_reg(dev, VPE_INT0_STATUS1);
- if (irqst1) {
- write_reg(dev, VPE_INT0_STATUS1_CLR, irqst1);
- vpe_dbg(dev, "INT0_STATUS1 = 0x%08x\n", irqst1);
- }
-
- ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
- if (!ctx) {
- vpe_err(dev, "instance released before end of transaction\n");
- goto handled;
- }
-
- if (irqst1) {
- if (irqst1 & VPE_DEI_ERROR_INT) {
- irqst1 &= ~VPE_DEI_ERROR_INT;
- dei_error(ctx);
- }
- if (irqst1 & VPE_DS1_UV_ERROR_INT) {
- irqst1 &= ~VPE_DS1_UV_ERROR_INT;
- ds1_uv_error(ctx);
- }
- }
-
- if (irqst0) {
- if (irqst0 & VPE_INT0_LIST0_COMPLETE)
- vpdma_clear_list_stat(ctx->dev->vpdma, 0, 0);
-
- irqst0 &= ~(VPE_INT0_LIST0_COMPLETE);
- list_complete = true;
- }
-
- if (irqst0 | irqst1) {
- dev_warn(dev->v4l2_dev.dev, "Unexpected interrupt: INT0_STATUS0 = 0x%08x, INT0_STATUS1 = 0x%08x\n",
- irqst0, irqst1);
- }
-
- /*
- * Setup next operation only when list complete IRQ occurs
- * otherwise, skip the following code
- */
- if (!list_complete)
- goto handled;
-
- disable_irqs(ctx);
-
- vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf);
- vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb);
- vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h);
- vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v);
-
- vpdma_reset_desc_list(&ctx->desc_list);
-
- /* the previous dst mv buffer becomes the next src mv buffer */
- ctx->src_mv_buf_selector = !ctx->src_mv_buf_selector;
-
- s_vb = ctx->src_vbs[0];
- d_vb = ctx->dst_vb;
-
- d_vb->flags = s_vb->flags;
- d_vb->vb2_buf.timestamp = s_vb->vb2_buf.timestamp;
-
- if (s_vb->flags & V4L2_BUF_FLAG_TIMECODE)
- d_vb->timecode = s_vb->timecode;
-
- d_vb->sequence = ctx->sequence;
- s_vb->sequence = ctx->sequence;
-
- d_q_data = &ctx->q_data[Q_DATA_DST];
- if (d_q_data->flags & Q_IS_INTERLACED) {
- d_vb->field = ctx->field;
- if (ctx->field == V4L2_FIELD_BOTTOM) {
- ctx->sequence++;
- ctx->field = V4L2_FIELD_TOP;
- } else {
- WARN_ON(ctx->field != V4L2_FIELD_TOP);
- ctx->field = V4L2_FIELD_BOTTOM;
- }
- } else {
- d_vb->field = V4L2_FIELD_NONE;
- ctx->sequence++;
- }
-
- if (ctx->deinterlacing) {
- /*
- * Allow source buffer to be dequeued only if it won't be used
- * in the next iteration. All vbs are initialized to first
- * buffer and we are shifting buffers every iteration, for the
- * first two iterations, no buffer will be dequeued.
- * This ensures that driver will keep (n-2)th (n-1)th and (n)th
- * field when deinterlacing is enabled
- */
- if (ctx->src_vbs[2] != ctx->src_vbs[1])
- s_vb = ctx->src_vbs[2];
- else
- s_vb = NULL;
- }
-
- spin_lock_irqsave(&dev->lock, flags);
-
- if (s_vb)
- v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_DONE);
-
- v4l2_m2m_buf_done(d_vb, VB2_BUF_STATE_DONE);
-
- spin_unlock_irqrestore(&dev->lock, flags);
-
- if (ctx->deinterlacing) {
- ctx->src_vbs[2] = ctx->src_vbs[1];
- ctx->src_vbs[1] = ctx->src_vbs[0];
- }
-
- /*
- * Since the vb2_buf_done has already been called fir therse
- * buffer we can now NULL them out so that we won't try
- * to clean out stray pointer later on.
- */
- ctx->src_vbs[0] = NULL;
- ctx->dst_vb = NULL;
-
- if (ctx->aborting)
- goto finished;
-
- ctx->bufs_completed++;
- if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) {
- device_run(ctx);
- goto handled;
- }
-
-finished:
- vpe_dbg(ctx->dev, "finishing transaction\n");
- ctx->bufs_completed = 0;
- v4l2_m2m_job_finish(dev->m2m_dev, ctx->fh.m2m_ctx);
-handled:
- return IRQ_HANDLED;
-}
-
-/*
- * video ioctls
- */
-static int vpe_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- strscpy(cap->driver, VPE_MODULE_NAME, sizeof(cap->driver));
- strscpy(cap->card, VPE_MODULE_NAME, sizeof(cap->card));
- snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
- VPE_MODULE_NAME);
- return 0;
-}
-
-static int __enum_fmt(struct v4l2_fmtdesc *f, u32 type)
-{
- int i, index;
- struct vpe_fmt *fmt = NULL;
-
- index = 0;
- for (i = 0; i < ARRAY_SIZE(vpe_formats); ++i) {
- if (vpe_formats[i].types & type) {
- if (index == f->index) {
- fmt = &vpe_formats[i];
- break;
- }
- index++;
- }
- }
-
- if (!fmt)
- return -EINVAL;
-
- f->pixelformat = fmt->fourcc;
- return 0;
-}
-
-static int vpe_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- if (V4L2_TYPE_IS_OUTPUT(f->type))
- return __enum_fmt(f, VPE_FMT_TYPE_OUTPUT);
-
- return __enum_fmt(f, VPE_FMT_TYPE_CAPTURE);
-}
-
-static int vpe_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct vpe_ctx *ctx = file->private_data;
- struct vb2_queue *vq;
- struct vpe_q_data *q_data;
-
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
- q_data = get_q_data(ctx, f->type);
- if (!q_data)
- return -EINVAL;
-
- *f = q_data->format;
-
- if (V4L2_TYPE_IS_CAPTURE(f->type)) {
- struct vpe_q_data *s_q_data;
- struct v4l2_pix_format_mplane *spix;
-
- /* get colorimetry from the source queue */
- s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- spix = &s_q_data->format.fmt.pix_mp;
-
- pix->colorspace = spix->colorspace;
- pix->xfer_func = spix->xfer_func;
- pix->ycbcr_enc = spix->ycbcr_enc;
- pix->quantization = spix->quantization;
- }
-
- return 0;
-}
-
-static int __vpe_try_fmt(struct vpe_ctx *ctx, struct v4l2_format *f,
- struct vpe_fmt *fmt, int type)
-{
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct v4l2_plane_pix_format *plane_fmt;
- unsigned int w_align;
- int i, depth, depth_bytes, height;
- unsigned int stride = 0;
- const struct v4l2_format_info *finfo;
-
- if (!fmt || !(fmt->types & type)) {
- vpe_dbg(ctx->dev, "Fourcc format (0x%08x) invalid.\n",
- pix->pixelformat);
- fmt = __find_format(V4L2_PIX_FMT_YUYV);
- }
-
- if (pix->field != V4L2_FIELD_NONE &&
- pix->field != V4L2_FIELD_ALTERNATE &&
- pix->field != V4L2_FIELD_SEQ_TB &&
- pix->field != V4L2_FIELD_SEQ_BT)
- pix->field = V4L2_FIELD_NONE;
-
- depth = fmt->vpdma_fmt[VPE_LUMA]->depth;
-
- /*
- * the line stride should 16 byte aligned for VPDMA to work, based on
- * the bytes per pixel, figure out how much the width should be aligned
- * to make sure line stride is 16 byte aligned
- */
- depth_bytes = depth >> 3;
-
- if (depth_bytes == 3) {
- /*
- * if bpp is 3(as in some RGB formats), the pixel width doesn't
- * really help in ensuring line stride is 16 byte aligned
- */
- w_align = 4;
- } else {
- /*
- * for the remainder bpp(4, 2 and 1), the pixel width alignment
- * can ensure a line stride alignment of 16 bytes. For example,
- * if bpp is 2, then the line stride can be 16 byte aligned if
- * the width is 8 byte aligned
- */
-
- /*
- * HACK: using order_base_2() here causes lots of asm output
- * errors with smatch, on i386:
- * ./arch/x86/include/asm/bitops.h:457:22:
- * warning: asm output is not an lvalue
- * Perhaps some gcc optimization is doing the wrong thing
- * there.
- * Let's get rid of them by doing the calculus on two steps
- */
- w_align = roundup_pow_of_two(VPDMA_DESC_ALIGN / depth_bytes);
- w_align = ilog2(w_align);
- }
-
- v4l_bound_align_image(&pix->width, MIN_W, MAX_W, w_align,
- &pix->height, MIN_H, MAX_H, H_ALIGN,
- S_ALIGN);
-
- if (!pix->num_planes || pix->num_planes > 2)
- pix->num_planes = fmt->coplanar ? 2 : 1;
- else if (pix->num_planes > 1 && !fmt->coplanar)
- pix->num_planes = 1;
-
- pix->pixelformat = fmt->fourcc;
- finfo = v4l2_format_info(fmt->fourcc);
-
- /*
- * For the actual image parameters, we need to consider the field
- * height of the image for SEQ_XX buffers.
- */
- if (pix->field == V4L2_FIELD_SEQ_TB || pix->field == V4L2_FIELD_SEQ_BT)
- height = pix->height / 2;
- else
- height = pix->height;
-
- if (!pix->colorspace) {
- if (v4l2_is_format_rgb(finfo)) {
- pix->colorspace = V4L2_COLORSPACE_SRGB;
- } else {
- if (height > 1280) /* HD */
- pix->colorspace = V4L2_COLORSPACE_REC709;
- else /* SD */
- pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
- }
- }
-
- for (i = 0; i < pix->num_planes; i++) {
- plane_fmt = &pix->plane_fmt[i];
- depth = fmt->vpdma_fmt[i]->depth;
-
- stride = (pix->width * fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
- if (stride > plane_fmt->bytesperline)
- plane_fmt->bytesperline = stride;
-
- plane_fmt->bytesperline = clamp_t(u32, plane_fmt->bytesperline,
- stride,
- VPDMA_MAX_STRIDE);
-
- plane_fmt->bytesperline = ALIGN(plane_fmt->bytesperline,
- VPDMA_STRIDE_ALIGN);
-
- if (i == VPE_LUMA) {
- plane_fmt->sizeimage = pix->height *
- plane_fmt->bytesperline;
-
- if (pix->num_planes == 1 && fmt->coplanar)
- plane_fmt->sizeimage += pix->height *
- plane_fmt->bytesperline *
- fmt->vpdma_fmt[VPE_CHROMA]->depth >> 3;
-
- } else { /* i == VIP_CHROMA */
- plane_fmt->sizeimage = (pix->height *
- plane_fmt->bytesperline *
- depth) >> 3;
- }
- }
-
- return 0;
-}
-
-static int vpe_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- struct vpe_ctx *ctx = file->private_data;
- struct vpe_fmt *fmt = find_format(f);
-
- if (V4L2_TYPE_IS_OUTPUT(f->type))
- return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_OUTPUT);
- else
- return __vpe_try_fmt(ctx, f, fmt, VPE_FMT_TYPE_CAPTURE);
-}
-
-static int __vpe_s_fmt(struct vpe_ctx *ctx, struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct v4l2_pix_format_mplane *qpix;
- struct vpe_q_data *q_data;
- struct vb2_queue *vq;
-
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
- if (!vq)
- return -EINVAL;
-
- if (vb2_is_busy(vq)) {
- vpe_err(ctx->dev, "queue busy\n");
- return -EBUSY;
- }
-
- q_data = get_q_data(ctx, f->type);
- if (!q_data)
- return -EINVAL;
-
- qpix = &q_data->format.fmt.pix_mp;
- q_data->fmt = find_format(f);
- q_data->format = *f;
-
- q_data->c_rect.left = 0;
- q_data->c_rect.top = 0;
- q_data->c_rect.width = pix->width;
- q_data->c_rect.height = pix->height;
-
- if (qpix->field == V4L2_FIELD_ALTERNATE)
- q_data->flags |= Q_DATA_INTERLACED_ALTERNATE;
- else if (qpix->field == V4L2_FIELD_SEQ_TB)
- q_data->flags |= Q_DATA_INTERLACED_SEQ_TB;
- else if (qpix->field == V4L2_FIELD_SEQ_BT)
- q_data->flags |= Q_DATA_INTERLACED_SEQ_BT;
- else
- q_data->flags &= ~Q_IS_INTERLACED;
-
- /* the crop height is halved for the case of SEQ_XX buffers */
- if (q_data->flags & Q_IS_SEQ_XX)
- q_data->c_rect.height /= 2;
-
- vpe_dbg(ctx->dev, "Setting format for type %d, wxh: %dx%d, fmt: %d bpl_y %d",
- f->type, pix->width, pix->height, pix->pixelformat,
- pix->plane_fmt[0].bytesperline);
- if (pix->num_planes == 2)
- vpe_dbg(ctx->dev, " bpl_uv %d\n",
- pix->plane_fmt[1].bytesperline);
-
- return 0;
-}
-
-static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
-{
- int ret;
- struct vpe_ctx *ctx = file->private_data;
-
- ret = vpe_try_fmt(file, priv, f);
- if (ret)
- return ret;
-
- ret = __vpe_s_fmt(ctx, f);
- if (ret)
- return ret;
-
- if (V4L2_TYPE_IS_OUTPUT(f->type))
- set_src_registers(ctx);
- else
- set_dst_registers(ctx);
-
- return set_srcdst_params(ctx);
-}
-
-static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
-{
- struct vpe_q_data *q_data;
- struct v4l2_pix_format_mplane *pix;
- int height;
-
- if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
- return -EINVAL;
-
- q_data = get_q_data(ctx, s->type);
- if (!q_data)
- return -EINVAL;
-
- pix = &q_data->format.fmt.pix_mp;
-
- switch (s->target) {
- case V4L2_SEL_TGT_COMPOSE:
- /*
- * COMPOSE target is only valid for capture buffer type, return
- * error for output buffer type
- */
- if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- break;
- case V4L2_SEL_TGT_CROP:
- /*
- * CROP target is only valid for output buffer type, return
- * error for capture buffer type
- */
- if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- break;
- /*
- * bound and default crop/compose targets are invalid targets to
- * try/set
- */
- default:
- return -EINVAL;
- }
-
- /*
- * For SEQ_XX buffers, crop height should be less than the height of
- * the field height, not the buffer height
- */
- if (q_data->flags & Q_IS_SEQ_XX)
- height = pix->height / 2;
- else
- height = pix->height;
-
- if (s->r.top < 0 || s->r.left < 0) {
- vpe_err(ctx->dev, "negative values for top and left\n");
- s->r.top = s->r.left = 0;
- }
-
- v4l_bound_align_image(&s->r.width, MIN_W, pix->width, 1,
- &s->r.height, MIN_H, height, H_ALIGN, S_ALIGN);
-
- /* adjust left/top if cropping rectangle is out of bounds */
- if (s->r.left + s->r.width > pix->width)
- s->r.left = pix->width - s->r.width;
- if (s->r.top + s->r.height > pix->height)
- s->r.top = pix->height - s->r.height;
-
- return 0;
-}
-
-static int vpe_g_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct vpe_ctx *ctx = file->private_data;
- struct vpe_q_data *q_data;
- struct v4l2_pix_format_mplane *pix;
- bool use_c_rect = false;
-
- if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
- (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
- return -EINVAL;
-
- q_data = get_q_data(ctx, s->type);
- if (!q_data)
- return -EINVAL;
-
- pix = &q_data->format.fmt.pix_mp;
-
- switch (s->target) {
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- break;
- case V4L2_SEL_TGT_CROP_BOUNDS:
- case V4L2_SEL_TGT_CROP_DEFAULT:
- if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- break;
- case V4L2_SEL_TGT_COMPOSE:
- if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- use_c_rect = true;
- break;
- case V4L2_SEL_TGT_CROP:
- if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- use_c_rect = true;
- break;
- default:
- return -EINVAL;
- }
-
- if (use_c_rect) {
- /*
- * for CROP/COMPOSE target type, return c_rect params from the
- * respective buffer type
- */
- s->r = q_data->c_rect;
- } else {
- /*
- * for DEFAULT/BOUNDS target type, return width and height from
- * S_FMT of the respective buffer type
- */
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = pix->width;
- s->r.height = pix->height;
- }
-
- return 0;
-}
-
-
-static int vpe_s_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct vpe_ctx *ctx = file->private_data;
- struct vpe_q_data *q_data;
- struct v4l2_selection sel = *s;
- int ret;
-
- ret = __vpe_try_selection(ctx, &sel);
- if (ret)
- return ret;
-
- q_data = get_q_data(ctx, sel.type);
- if (!q_data)
- return -EINVAL;
-
- if ((q_data->c_rect.left == sel.r.left) &&
- (q_data->c_rect.top == sel.r.top) &&
- (q_data->c_rect.width == sel.r.width) &&
- (q_data->c_rect.height == sel.r.height)) {
- vpe_dbg(ctx->dev,
- "requested crop/compose values are already set\n");
- return 0;
- }
-
- q_data->c_rect = sel.r;
-
- return set_srcdst_params(ctx);
-}
-
-/*
- * defines number of buffers/frames a context can process with VPE before
- * switching to a different context. default value is 1 buffer per context
- */
-#define V4L2_CID_VPE_BUFS_PER_JOB (V4L2_CID_USER_TI_VPE_BASE + 0)
-
-static int vpe_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct vpe_ctx *ctx =
- container_of(ctrl->handler, struct vpe_ctx, hdl);
-
- switch (ctrl->id) {
- case V4L2_CID_VPE_BUFS_PER_JOB:
- ctx->bufs_per_job = ctrl->val;
- break;
-
- default:
- vpe_err(ctx->dev, "Invalid control\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops vpe_ctrl_ops = {
- .s_ctrl = vpe_s_ctrl,
-};
-
-static const struct v4l2_ioctl_ops vpe_ioctl_ops = {
- .vidioc_querycap = vpe_querycap,
-
- .vidioc_enum_fmt_vid_cap = vpe_enum_fmt,
- .vidioc_g_fmt_vid_cap_mplane = vpe_g_fmt,
- .vidioc_try_fmt_vid_cap_mplane = vpe_try_fmt,
- .vidioc_s_fmt_vid_cap_mplane = vpe_s_fmt,
-
- .vidioc_enum_fmt_vid_out = vpe_enum_fmt,
- .vidioc_g_fmt_vid_out_mplane = vpe_g_fmt,
- .vidioc_try_fmt_vid_out_mplane = vpe_try_fmt,
- .vidioc_s_fmt_vid_out_mplane = vpe_s_fmt,
-
- .vidioc_g_selection = vpe_g_selection,
- .vidioc_s_selection = vpe_s_selection,
-
- .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_expbuf = v4l2_m2m_ioctl_expbuf,
- .vidioc_streamon = v4l2_m2m_ioctl_streamon,
- .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
-
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-/*
- * Queue operations
- */
-static int vpe_queue_setup(struct vb2_queue *vq,
- unsigned int *nbuffers, unsigned int *nplanes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- int i;
- struct vpe_ctx *ctx = vb2_get_drv_priv(vq);
- struct vpe_q_data *q_data;
- struct v4l2_pix_format_mplane *pix;
-
- q_data = get_q_data(ctx, vq->type);
- if (!q_data)
- return -EINVAL;
-
- pix = &q_data->format.fmt.pix_mp;
- *nplanes = pix->num_planes;
-
- for (i = 0; i < *nplanes; i++)
- sizes[i] = pix->plane_fmt[i].sizeimage;
-
- vpe_dbg(ctx->dev, "get %d buffer(s) of size %d", *nbuffers,
- sizes[VPE_LUMA]);
- if (*nplanes == 2)
- vpe_dbg(ctx->dev, " and %d\n", sizes[VPE_CHROMA]);
-
- return 0;
-}
-
-static int vpe_buf_prepare(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vpe_q_data *q_data;
- struct v4l2_pix_format_mplane *pix;
- int i;
-
- vpe_dbg(ctx->dev, "type: %d\n", vb->vb2_queue->type);
-
- q_data = get_q_data(ctx, vb->vb2_queue->type);
- if (!q_data)
- return -EINVAL;
-
- pix = &q_data->format.fmt.pix_mp;
-
- if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- if (!(q_data->flags & Q_IS_INTERLACED)) {
- vbuf->field = V4L2_FIELD_NONE;
- } else {
- if (vbuf->field != V4L2_FIELD_TOP &&
- vbuf->field != V4L2_FIELD_BOTTOM &&
- vbuf->field != V4L2_FIELD_SEQ_TB &&
- vbuf->field != V4L2_FIELD_SEQ_BT)
- return -EINVAL;
- }
- }
-
- for (i = 0; i < pix->num_planes; i++) {
- if (vb2_plane_size(vb, i) < pix->plane_fmt[i].sizeimage) {
- vpe_err(ctx->dev,
- "data will not fit into plane (%lu < %lu)\n",
- vb2_plane_size(vb, i),
- (long)pix->plane_fmt[i].sizeimage);
- return -EINVAL;
- }
- }
-
- for (i = 0; i < pix->num_planes; i++)
- vb2_set_plane_payload(vb, i, pix->plane_fmt[i].sizeimage);
-
- return 0;
-}
-
-static void vpe_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct vpe_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-}
-
-static int check_srcdst_sizes(struct vpe_ctx *ctx)
-{
- struct vpe_q_data *s_q_data = &ctx->q_data[Q_DATA_SRC];
- struct vpe_q_data *d_q_data = &ctx->q_data[Q_DATA_DST];
- unsigned int src_w = s_q_data->c_rect.width;
- unsigned int src_h = s_q_data->c_rect.height;
- unsigned int dst_w = d_q_data->c_rect.width;
- unsigned int dst_h = d_q_data->c_rect.height;
-
- if (src_w == dst_w && src_h == dst_h)
- return 0;
-
- if (src_h <= SC_MAX_PIXEL_HEIGHT &&
- src_w <= SC_MAX_PIXEL_WIDTH &&
- dst_h <= SC_MAX_PIXEL_HEIGHT &&
- dst_w <= SC_MAX_PIXEL_WIDTH)
- return 0;
-
- return -1;
-}
-
-static void vpe_return_all_buffers(struct vpe_ctx *ctx, struct vb2_queue *q,
- enum vb2_buffer_state state)
-{
- struct vb2_v4l2_buffer *vb;
- unsigned long flags;
-
- for (;;) {
- if (V4L2_TYPE_IS_OUTPUT(q->type))
- vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
- else
- vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
- if (!vb)
- break;
- spin_lock_irqsave(&ctx->dev->lock, flags);
- v4l2_m2m_buf_done(vb, state);
- spin_unlock_irqrestore(&ctx->dev->lock, flags);
- }
-
- /*
- * Cleanup the in-transit vb2 buffers that have been
- * removed from their respective queue already but for
- * which procecessing has not been completed yet.
- */
- if (V4L2_TYPE_IS_OUTPUT(q->type)) {
- spin_lock_irqsave(&ctx->dev->lock, flags);
-
- if (ctx->src_vbs[2])
- v4l2_m2m_buf_done(ctx->src_vbs[2], state);
-
- if (ctx->src_vbs[1] && (ctx->src_vbs[1] != ctx->src_vbs[2]))
- v4l2_m2m_buf_done(ctx->src_vbs[1], state);
-
- if (ctx->src_vbs[0] &&
- (ctx->src_vbs[0] != ctx->src_vbs[1]) &&
- (ctx->src_vbs[0] != ctx->src_vbs[2]))
- v4l2_m2m_buf_done(ctx->src_vbs[0], state);
-
- ctx->src_vbs[2] = NULL;
- ctx->src_vbs[1] = NULL;
- ctx->src_vbs[0] = NULL;
-
- spin_unlock_irqrestore(&ctx->dev->lock, flags);
- } else {
- if (ctx->dst_vb) {
- spin_lock_irqsave(&ctx->dev->lock, flags);
-
- v4l2_m2m_buf_done(ctx->dst_vb, state);
- ctx->dst_vb = NULL;
- spin_unlock_irqrestore(&ctx->dev->lock, flags);
- }
- }
-}
-
-static int vpe_start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct vpe_ctx *ctx = vb2_get_drv_priv(q);
-
- /* Check any of the size exceed maximum scaling sizes */
- if (check_srcdst_sizes(ctx)) {
- vpe_err(ctx->dev,
- "Conversion setup failed, check source and destination parameters\n"
- );
- vpe_return_all_buffers(ctx, q, VB2_BUF_STATE_QUEUED);
- return -EINVAL;
- }
-
- if (ctx->deinterlacing)
- config_edi_input_mode(ctx, 0x0);
-
- if (ctx->sequence != 0)
- set_srcdst_params(ctx);
-
- return 0;
-}
-
-static void vpe_stop_streaming(struct vb2_queue *q)
-{
- struct vpe_ctx *ctx = vb2_get_drv_priv(q);
-
- vpe_dump_regs(ctx->dev);
- vpdma_dump_regs(ctx->dev->vpdma);
-
- vpe_return_all_buffers(ctx, q, VB2_BUF_STATE_ERROR);
-}
-
-static const struct vb2_ops vpe_qops = {
- .queue_setup = vpe_queue_setup,
- .buf_prepare = vpe_buf_prepare,
- .buf_queue = vpe_buf_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .start_streaming = vpe_start_streaming,
- .stop_streaming = vpe_stop_streaming,
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct vpe_ctx *ctx = priv;
- struct vpe_dev *dev = ctx->dev;
- int ret;
-
- memset(src_vq, 0, sizeof(*src_vq));
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
- src_vq->drv_priv = ctx;
- src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- src_vq->ops = &vpe_qops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
- src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- src_vq->lock = &dev->dev_mutex;
- src_vq->dev = dev->v4l2_dev.dev;
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- memset(dst_vq, 0, sizeof(*dst_vq));
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
- dst_vq->drv_priv = ctx;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- dst_vq->ops = &vpe_qops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
- dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- dst_vq->lock = &dev->dev_mutex;
- dst_vq->dev = dev->v4l2_dev.dev;
-
- return vb2_queue_init(dst_vq);
-}
-
-static const struct v4l2_ctrl_config vpe_bufs_per_job = {
- .ops = &vpe_ctrl_ops,
- .id = V4L2_CID_VPE_BUFS_PER_JOB,
- .name = "Buffers Per Transaction",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .def = VPE_DEF_BUFS_PER_JOB,
- .min = 1,
- .max = VIDEO_MAX_FRAME,
- .step = 1,
-};
-
-/*
- * File operations
- */
-static int vpe_open(struct file *file)
-{
- struct vpe_dev *dev = video_drvdata(file);
- struct vpe_q_data *s_q_data;
- struct v4l2_ctrl_handler *hdl;
- struct vpe_ctx *ctx;
- struct v4l2_pix_format_mplane *pix;
- int ret;
-
- vpe_dbg(dev, "vpe_open\n");
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- ctx->dev = dev;
-
- if (mutex_lock_interruptible(&dev->dev_mutex)) {
- ret = -ERESTARTSYS;
- goto free_ctx;
- }
-
- ret = vpdma_create_desc_list(&ctx->desc_list, VPE_DESC_LIST_SIZE,
- VPDMA_LIST_TYPE_NORMAL);
- if (ret != 0)
- goto unlock;
-
- ret = vpdma_alloc_desc_buf(&ctx->mmr_adb, sizeof(struct vpe_mmr_adb));
- if (ret != 0)
- goto free_desc_list;
-
- ret = vpdma_alloc_desc_buf(&ctx->sc_coeff_h, SC_COEF_SRAM_SIZE);
- if (ret != 0)
- goto free_mmr_adb;
-
- ret = vpdma_alloc_desc_buf(&ctx->sc_coeff_v, SC_COEF_SRAM_SIZE);
- if (ret != 0)
- goto free_sc_h;
-
- init_adb_hdrs(ctx);
-
- v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = ctx;
-
- hdl = &ctx->hdl;
- v4l2_ctrl_handler_init(hdl, 1);
- v4l2_ctrl_new_custom(hdl, &vpe_bufs_per_job, NULL);
- if (hdl->error) {
- ret = hdl->error;
- goto exit_fh;
- }
- ctx->fh.ctrl_handler = hdl;
- v4l2_ctrl_handler_setup(hdl);
-
- s_q_data = &ctx->q_data[Q_DATA_SRC];
- pix = &s_q_data->format.fmt.pix_mp;
- s_q_data->fmt = __find_format(V4L2_PIX_FMT_YUYV);
- pix->pixelformat = s_q_data->fmt->fourcc;
- s_q_data->format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- pix->width = 1920;
- pix->height = 1080;
- pix->num_planes = 1;
- pix->plane_fmt[VPE_LUMA].bytesperline = (pix->width *
- s_q_data->fmt->vpdma_fmt[VPE_LUMA]->depth) >> 3;
- pix->plane_fmt[VPE_LUMA].sizeimage =
- pix->plane_fmt[VPE_LUMA].bytesperline *
- pix->height;
- pix->colorspace = V4L2_COLORSPACE_REC709;
- pix->xfer_func = V4L2_XFER_FUNC_DEFAULT;
- pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
- pix->quantization = V4L2_QUANTIZATION_DEFAULT;
- pix->field = V4L2_FIELD_NONE;
- s_q_data->c_rect.left = 0;
- s_q_data->c_rect.top = 0;
- s_q_data->c_rect.width = pix->width;
- s_q_data->c_rect.height = pix->height;
- s_q_data->flags = 0;
-
- ctx->q_data[Q_DATA_DST] = *s_q_data;
- ctx->q_data[Q_DATA_DST].format.type =
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-
- set_dei_shadow_registers(ctx);
- set_src_registers(ctx);
- set_dst_registers(ctx);
- ret = set_srcdst_params(ctx);
- if (ret)
- goto exit_fh;
-
- ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
-
- if (IS_ERR(ctx->fh.m2m_ctx)) {
- ret = PTR_ERR(ctx->fh.m2m_ctx);
- goto exit_fh;
- }
-
- v4l2_fh_add(&ctx->fh);
-
- /*
- * for now, just report the creation of the first instance, we can later
- * optimize the driver to enable or disable clocks when the first
- * instance is created or the last instance released
- */
- if (atomic_inc_return(&dev->num_instances) == 1)
- vpe_dbg(dev, "first instance created\n");
-
- ctx->bufs_per_job = VPE_DEF_BUFS_PER_JOB;
-
- ctx->load_mmrs = true;
-
- vpe_dbg(dev, "created instance %p, m2m_ctx: %p\n",
- ctx, ctx->fh.m2m_ctx);
-
- mutex_unlock(&dev->dev_mutex);
-
- return 0;
-exit_fh:
- v4l2_ctrl_handler_free(hdl);
- v4l2_fh_exit(&ctx->fh);
- vpdma_free_desc_buf(&ctx->sc_coeff_v);
-free_sc_h:
- vpdma_free_desc_buf(&ctx->sc_coeff_h);
-free_mmr_adb:
- vpdma_free_desc_buf(&ctx->mmr_adb);
-free_desc_list:
- vpdma_free_desc_list(&ctx->desc_list);
-unlock:
- mutex_unlock(&dev->dev_mutex);
-free_ctx:
- kfree(ctx);
- return ret;
-}
-
-static int vpe_release(struct file *file)
-{
- struct vpe_dev *dev = video_drvdata(file);
- struct vpe_ctx *ctx = file->private_data;
-
- vpe_dbg(dev, "releasing instance %p\n", ctx);
-
- mutex_lock(&dev->dev_mutex);
- free_mv_buffers(ctx);
-
- vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf);
- vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb);
- vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h);
- vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v);
-
- vpdma_free_desc_list(&ctx->desc_list);
- vpdma_free_desc_buf(&ctx->mmr_adb);
-
- vpdma_free_desc_buf(&ctx->sc_coeff_v);
- vpdma_free_desc_buf(&ctx->sc_coeff_h);
-
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- v4l2_ctrl_handler_free(&ctx->hdl);
- v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
-
- kfree(ctx);
-
- /*
- * for now, just report the release of the last instance, we can later
- * optimize the driver to enable or disable clocks when the first
- * instance is created or the last instance released
- */
- if (atomic_dec_return(&dev->num_instances) == 0)
- vpe_dbg(dev, "last instance released\n");
-
- mutex_unlock(&dev->dev_mutex);
-
- return 0;
-}
-
-static const struct v4l2_file_operations vpe_fops = {
- .owner = THIS_MODULE,
- .open = vpe_open,
- .release = vpe_release,
- .poll = v4l2_m2m_fop_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = v4l2_m2m_fop_mmap,
-};
-
-static const struct video_device vpe_videodev = {
- .name = VPE_MODULE_NAME,
- .fops = &vpe_fops,
- .ioctl_ops = &vpe_ioctl_ops,
- .minor = -1,
- .release = video_device_release_empty,
- .vfl_dir = VFL_DIR_M2M,
- .device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
-};
-
-static const struct v4l2_m2m_ops m2m_ops = {
- .device_run = device_run,
- .job_ready = job_ready,
- .job_abort = job_abort,
-};
-
-static int vpe_runtime_get(struct platform_device *pdev)
-{
- int r;
-
- dev_dbg(&pdev->dev, "vpe_runtime_get\n");
-
- r = pm_runtime_resume_and_get(&pdev->dev);
- WARN_ON(r < 0);
- return r;
-}
-
-static void vpe_runtime_put(struct platform_device *pdev)
-{
-
- int r;
-
- dev_dbg(&pdev->dev, "vpe_runtime_put\n");
-
- r = pm_runtime_put_sync(&pdev->dev);
- WARN_ON(r < 0 && r != -ENOSYS);
-}
-
-static void vpe_fw_cb(struct platform_device *pdev)
-{
- struct vpe_dev *dev = platform_get_drvdata(pdev);
- struct video_device *vfd;
- int ret;
-
- vfd = &dev->vfd;
- *vfd = vpe_videodev;
- vfd->lock = &dev->dev_mutex;
- vfd->v4l2_dev = &dev->v4l2_dev;
-
- ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
- if (ret) {
- vpe_err(dev, "Failed to register video device\n");
-
- vpe_set_clock_enable(dev, 0);
- vpe_runtime_put(pdev);
- pm_runtime_disable(&pdev->dev);
- v4l2_m2m_release(dev->m2m_dev);
- v4l2_device_unregister(&dev->v4l2_dev);
-
- return;
- }
-
- video_set_drvdata(vfd, dev);
- dev_info(dev->v4l2_dev.dev, "Device registered as /dev/video%d\n",
- vfd->num);
-}
-
-static int vpe_probe(struct platform_device *pdev)
-{
- struct vpe_dev *dev;
- int ret, irq, func;
-
- ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- if (ret) {
- dev_err(&pdev->dev,
- "32-bit consistent DMA enable failed\n");
- return ret;
- }
-
- dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
- if (!dev)
- return -ENOMEM;
-
- spin_lock_init(&dev->lock);
-
- ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
- if (ret)
- return ret;
-
- atomic_set(&dev->num_instances, 0);
- mutex_init(&dev->dev_mutex);
-
- dev->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "vpe_top");
- if (!dev->res) {
- dev_err(&pdev->dev, "missing 'vpe_top' resources data\n");
- return -ENODEV;
- }
-
- /*
- * HACK: we get resource info from device tree in the form of a list of
- * VPE sub blocks, the driver currently uses only the base of vpe_top
- * for register access, the driver should be changed later to access
- * registers based on the sub block base addresses
- */
- dev->base = devm_ioremap(&pdev->dev, dev->res->start, SZ_32K);
- if (!dev->base) {
- ret = -ENOMEM;
- goto v4l2_dev_unreg;
- }
-
- irq = platform_get_irq(pdev, 0);
- ret = devm_request_irq(&pdev->dev, irq, vpe_irq, 0, VPE_MODULE_NAME,
- dev);
- if (ret)
- goto v4l2_dev_unreg;
-
- platform_set_drvdata(pdev, dev);
-
- dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
- if (IS_ERR(dev->m2m_dev)) {
- vpe_err(dev, "Failed to init mem2mem device\n");
- ret = PTR_ERR(dev->m2m_dev);
- goto v4l2_dev_unreg;
- }
-
- pm_runtime_enable(&pdev->dev);
-
- ret = vpe_runtime_get(pdev);
- if (ret < 0)
- goto rel_m2m;
-
- /* Perform clk enable followed by reset */
- vpe_set_clock_enable(dev, 1);
-
- vpe_top_reset(dev);
-
- func = read_field_reg(dev, VPE_PID, VPE_PID_FUNC_MASK,
- VPE_PID_FUNC_SHIFT);
- vpe_dbg(dev, "VPE PID function %x\n", func);
-
- vpe_top_vpdma_reset(dev);
-
- dev->sc = sc_create(pdev, "sc");
- if (IS_ERR(dev->sc)) {
- ret = PTR_ERR(dev->sc);
- goto runtime_put;
- }
-
- dev->csc = csc_create(pdev, "csc");
- if (IS_ERR(dev->csc)) {
- ret = PTR_ERR(dev->csc);
- goto runtime_put;
- }
-
- dev->vpdma = &dev->vpdma_data;
- ret = vpdma_create(pdev, dev->vpdma, vpe_fw_cb);
- if (ret)
- goto runtime_put;
-
- return 0;
-
-runtime_put:
- vpe_runtime_put(pdev);
-rel_m2m:
- pm_runtime_disable(&pdev->dev);
- v4l2_m2m_release(dev->m2m_dev);
-v4l2_dev_unreg:
- v4l2_device_unregister(&dev->v4l2_dev);
-
- return ret;
-}
-
-static int vpe_remove(struct platform_device *pdev)
-{
- struct vpe_dev *dev = platform_get_drvdata(pdev);
-
- v4l2_info(&dev->v4l2_dev, "Removing " VPE_MODULE_NAME);
-
- v4l2_m2m_release(dev->m2m_dev);
- video_unregister_device(&dev->vfd);
- v4l2_device_unregister(&dev->v4l2_dev);
-
- vpe_set_clock_enable(dev, 0);
- vpe_runtime_put(pdev);
- pm_runtime_disable(&pdev->dev);
-
- return 0;
-}
-
-#if defined(CONFIG_OF)
-static const struct of_device_id vpe_of_match[] = {
- {
- .compatible = "ti,dra7-vpe",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, vpe_of_match);
-#endif
-
-static struct platform_driver vpe_pdrv = {
- .probe = vpe_probe,
- .remove = vpe_remove,
- .driver = {
- .name = VPE_MODULE_NAME,
- .of_match_table = of_match_ptr(vpe_of_match),
- },
-};
-
-module_platform_driver(vpe_pdrv);
-
-MODULE_DESCRIPTION("TI VPE driver");
-MODULE_AUTHOR("Dale Farnsworth, ");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/ti-vpe/vpe_regs.h b/drivers/media/platform/ti-vpe/vpe_regs.h
deleted file mode 100644
index 1a1ad5ae1228..000000000000
--- a/drivers/media/platform/ti-vpe/vpe_regs.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2013 Texas Instruments Inc.
- *
- * David Griego,
- * Dale Farnsworth,
- * Archit Taneja,
- */
-
-#ifndef __TI_VPE_REGS_H
-#define __TI_VPE_REGS_H
-
-/* VPE register offsets and field selectors */
-
-/* VPE top level regs */
-#define VPE_PID 0x0000
-#define VPE_PID_MINOR_MASK 0x3f
-#define VPE_PID_MINOR_SHIFT 0
-#define VPE_PID_CUSTOM_MASK 0x03
-#define VPE_PID_CUSTOM_SHIFT 6
-#define VPE_PID_MAJOR_MASK 0x07
-#define VPE_PID_MAJOR_SHIFT 8
-#define VPE_PID_RTL_MASK 0x1f
-#define VPE_PID_RTL_SHIFT 11
-#define VPE_PID_FUNC_MASK 0xfff
-#define VPE_PID_FUNC_SHIFT 16
-#define VPE_PID_SCHEME_MASK 0x03
-#define VPE_PID_SCHEME_SHIFT 30
-
-#define VPE_SYSCONFIG 0x0010
-#define VPE_SYSCONFIG_IDLE_MASK 0x03
-#define VPE_SYSCONFIG_IDLE_SHIFT 2
-#define VPE_SYSCONFIG_STANDBY_MASK 0x03
-#define VPE_SYSCONFIG_STANDBY_SHIFT 4
-#define VPE_FORCE_IDLE_MODE 0
-#define VPE_NO_IDLE_MODE 1
-#define VPE_SMART_IDLE_MODE 2
-#define VPE_SMART_IDLE_WAKEUP_MODE 3
-#define VPE_FORCE_STANDBY_MODE 0
-#define VPE_NO_STANDBY_MODE 1
-#define VPE_SMART_STANDBY_MODE 2
-#define VPE_SMART_STANDBY_WAKEUP_MODE 3
-
-#define VPE_INT0_STATUS0_RAW_SET 0x0020
-#define VPE_INT0_STATUS0_RAW VPE_INT0_STATUS0_RAW_SET
-#define VPE_INT0_STATUS0_CLR 0x0028
-#define VPE_INT0_STATUS0 VPE_INT0_STATUS0_CLR
-#define VPE_INT0_ENABLE0_SET 0x0030
-#define VPE_INT0_ENABLE0 VPE_INT0_ENABLE0_SET
-#define VPE_INT0_ENABLE0_CLR 0x0038
-#define VPE_INT0_LIST0_COMPLETE BIT(0)
-#define VPE_INT0_LIST0_NOTIFY BIT(1)
-#define VPE_INT0_LIST1_COMPLETE BIT(2)
-#define VPE_INT0_LIST1_NOTIFY BIT(3)
-#define VPE_INT0_LIST2_COMPLETE BIT(4)
-#define VPE_INT0_LIST2_NOTIFY BIT(5)
-#define VPE_INT0_LIST3_COMPLETE BIT(6)
-#define VPE_INT0_LIST3_NOTIFY BIT(7)
-#define VPE_INT0_LIST4_COMPLETE BIT(8)
-#define VPE_INT0_LIST4_NOTIFY BIT(9)
-#define VPE_INT0_LIST5_COMPLETE BIT(10)
-#define VPE_INT0_LIST5_NOTIFY BIT(11)
-#define VPE_INT0_LIST6_COMPLETE BIT(12)
-#define VPE_INT0_LIST6_NOTIFY BIT(13)
-#define VPE_INT0_LIST7_COMPLETE BIT(14)
-#define VPE_INT0_LIST7_NOTIFY BIT(15)
-#define VPE_INT0_DESCRIPTOR BIT(16)
-#define VPE_DEI_FMD_INT BIT(18)
-
-#define VPE_INT0_STATUS1_RAW_SET 0x0024
-#define VPE_INT0_STATUS1_RAW VPE_INT0_STATUS1_RAW_SET
-#define VPE_INT0_STATUS1_CLR 0x002c
-#define VPE_INT0_STATUS1 VPE_INT0_STATUS1_CLR
-#define VPE_INT0_ENABLE1_SET 0x0034
-#define VPE_INT0_ENABLE1 VPE_INT0_ENABLE1_SET
-#define VPE_INT0_ENABLE1_CLR 0x003c
-#define VPE_INT0_CHANNEL_GROUP0 BIT(0)
-#define VPE_INT0_CHANNEL_GROUP1 BIT(1)
-#define VPE_INT0_CHANNEL_GROUP2 BIT(2)
-#define VPE_INT0_CHANNEL_GROUP3 BIT(3)
-#define VPE_INT0_CHANNEL_GROUP4 BIT(4)
-#define VPE_INT0_CHANNEL_GROUP5 BIT(5)
-#define VPE_INT0_CLIENT BIT(7)
-#define VPE_DEI_ERROR_INT BIT(16)
-#define VPE_DS1_UV_ERROR_INT BIT(22)
-
-#define VPE_INTC_EOI 0x00a0
-
-#define VPE_CLK_ENABLE 0x0100
-#define VPE_VPEDMA_CLK_ENABLE BIT(0)
-#define VPE_DATA_PATH_CLK_ENABLE BIT(1)
-
-#define VPE_CLK_RESET 0x0104
-#define VPE_VPDMA_CLK_RESET_MASK 0x1
-#define VPE_VPDMA_CLK_RESET_SHIFT 0
-#define VPE_DATA_PATH_CLK_RESET_MASK 0x1
-#define VPE_DATA_PATH_CLK_RESET_SHIFT 1
-#define VPE_MAIN_RESET_MASK 0x1
-#define VPE_MAIN_RESET_SHIFT 31
-
-#define VPE_CLK_FORMAT_SELECT 0x010c
-#define VPE_CSC_SRC_SELECT_MASK 0x03
-#define VPE_CSC_SRC_SELECT_SHIFT 0
-#define VPE_RGB_OUT_SELECT BIT(8)
-#define VPE_DS_SRC_SELECT_MASK 0x07
-#define VPE_DS_SRC_SELECT_SHIFT 9
-#define VPE_DS_BYPASS BIT(16)
-#define VPE_COLOR_SEPARATE_422 BIT(18)
-
-#define VPE_DS_SRC_DEI_SCALER (5 << VPE_DS_SRC_SELECT_SHIFT)
-#define VPE_CSC_SRC_DEI_SCALER (3 << VPE_CSC_SRC_SELECT_SHIFT)
-
-#define VPE_CLK_RANGE_MAP 0x011c
-#define VPE_RANGE_RANGE_MAP_Y_MASK 0x07
-#define VPE_RANGE_RANGE_MAP_Y_SHIFT 0
-#define VPE_RANGE_RANGE_MAP_UV_MASK 0x07
-#define VPE_RANGE_RANGE_MAP_UV_SHIFT 3
-#define VPE_RANGE_MAP_ON BIT(6)
-#define VPE_RANGE_REDUCTION_ON BIT(28)
-
-/* VPE chrominance upsampler regs */
-#define VPE_US1_R0 0x0304
-#define VPE_US2_R0 0x0404
-#define VPE_US3_R0 0x0504
-#define VPE_US_C1_MASK 0x3fff
-#define VPE_US_C1_SHIFT 2
-#define VPE_US_C0_MASK 0x3fff
-#define VPE_US_C0_SHIFT 18
-#define VPE_US_MODE_MASK 0x03
-#define VPE_US_MODE_SHIFT 16
-#define VPE_ANCHOR_FID0_C1_MASK 0x3fff
-#define VPE_ANCHOR_FID0_C1_SHIFT 2
-#define VPE_ANCHOR_FID0_C0_MASK 0x3fff
-#define VPE_ANCHOR_FID0_C0_SHIFT 18
-
-#define VPE_US1_R1 0x0308
-#define VPE_US2_R1 0x0408
-#define VPE_US3_R1 0x0508
-#define VPE_ANCHOR_FID0_C3_MASK 0x3fff
-#define VPE_ANCHOR_FID0_C3_SHIFT 2
-#define VPE_ANCHOR_FID0_C2_MASK 0x3fff
-#define VPE_ANCHOR_FID0_C2_SHIFT 18
-
-#define VPE_US1_R2 0x030c
-#define VPE_US2_R2 0x040c
-#define VPE_US3_R2 0x050c
-#define VPE_INTERP_FID0_C1_MASK 0x3fff
-#define VPE_INTERP_FID0_C1_SHIFT 2
-#define VPE_INTERP_FID0_C0_MASK 0x3fff
-#define VPE_INTERP_FID0_C0_SHIFT 18
-
-#define VPE_US1_R3 0x0310
-#define VPE_US2_R3 0x0410
-#define VPE_US3_R3 0x0510
-#define VPE_INTERP_FID0_C3_MASK 0x3fff
-#define VPE_INTERP_FID0_C3_SHIFT 2
-#define VPE_INTERP_FID0_C2_MASK 0x3fff
-#define VPE_INTERP_FID0_C2_SHIFT 18
-
-#define VPE_US1_R4 0x0314
-#define VPE_US2_R4 0x0414
-#define VPE_US3_R4 0x0514
-#define VPE_ANCHOR_FID1_C1_MASK 0x3fff
-#define VPE_ANCHOR_FID1_C1_SHIFT 2
-#define VPE_ANCHOR_FID1_C0_MASK 0x3fff
-#define VPE_ANCHOR_FID1_C0_SHIFT 18
-
-#define VPE_US1_R5 0x0318
-#define VPE_US2_R5 0x0418
-#define VPE_US3_R5 0x0518
-#define VPE_ANCHOR_FID1_C3_MASK 0x3fff
-#define VPE_ANCHOR_FID1_C3_SHIFT 2
-#define VPE_ANCHOR_FID1_C2_MASK 0x3fff
-#define VPE_ANCHOR_FID1_C2_SHIFT 18
-
-#define VPE_US1_R6 0x031c
-#define VPE_US2_R6 0x041c
-#define VPE_US3_R6 0x051c
-#define VPE_INTERP_FID1_C1_MASK 0x3fff
-#define VPE_INTERP_FID1_C1_SHIFT 2
-#define VPE_INTERP_FID1_C0_MASK 0x3fff
-#define VPE_INTERP_FID1_C0_SHIFT 18
-
-#define VPE_US1_R7 0x0320
-#define VPE_US2_R7 0x0420
-#define VPE_US3_R7 0x0520
-#define VPE_INTERP_FID0_C3_MASK 0x3fff
-#define VPE_INTERP_FID0_C3_SHIFT 2
-#define VPE_INTERP_FID0_C2_MASK 0x3fff
-#define VPE_INTERP_FID0_C2_SHIFT 18
-
-/* VPE de-interlacer regs */
-#define VPE_DEI_FRAME_SIZE 0x0600
-#define VPE_DEI_WIDTH_MASK 0x07ff
-#define VPE_DEI_WIDTH_SHIFT 0
-#define VPE_DEI_HEIGHT_MASK 0x07ff
-#define VPE_DEI_HEIGHT_SHIFT 16
-#define VPE_DEI_INTERLACE_BYPASS BIT(29)
-#define VPE_DEI_FIELD_FLUSH BIT(30)
-#define VPE_DEI_PROGRESSIVE BIT(31)
-
-#define VPE_MDT_BYPASS 0x0604
-#define VPE_MDT_TEMPMAX_BYPASS BIT(0)
-#define VPE_MDT_SPATMAX_BYPASS BIT(1)
-
-#define VPE_MDT_SF_THRESHOLD 0x0608
-#define VPE_MDT_SF_SC_THR1_MASK 0xff
-#define VPE_MDT_SF_SC_THR1_SHIFT 0
-#define VPE_MDT_SF_SC_THR2_MASK 0xff
-#define VPE_MDT_SF_SC_THR2_SHIFT 0
-#define VPE_MDT_SF_SC_THR3_MASK 0xff
-#define VPE_MDT_SF_SC_THR3_SHIFT 0
-
-#define VPE_EDI_CONFIG 0x060c
-#define VPE_EDI_INP_MODE_MASK 0x03
-#define VPE_EDI_INP_MODE_SHIFT 0
-#define VPE_EDI_ENABLE_3D BIT(2)
-#define VPE_EDI_ENABLE_CHROMA_3D BIT(3)
-#define VPE_EDI_CHROMA3D_COR_THR_MASK 0xff
-#define VPE_EDI_CHROMA3D_COR_THR_SHIFT 8
-#define VPE_EDI_DIR_COR_LOWER_THR_MASK 0xff
-#define VPE_EDI_DIR_COR_LOWER_THR_SHIFT 16
-#define VPE_EDI_COR_SCALE_FACTOR_MASK 0xff
-#define VPE_EDI_COR_SCALE_FACTOR_SHIFT 23
-
-#define VPE_DEI_EDI_LUT_R0 0x0610
-#define VPE_EDI_LUT0_MASK 0x1f
-#define VPE_EDI_LUT0_SHIFT 0
-#define VPE_EDI_LUT1_MASK 0x1f
-#define VPE_EDI_LUT1_SHIFT 8
-#define VPE_EDI_LUT2_MASK 0x1f
-#define VPE_EDI_LUT2_SHIFT 16
-#define VPE_EDI_LUT3_MASK 0x1f
-#define VPE_EDI_LUT3_SHIFT 24
-
-#define VPE_DEI_EDI_LUT_R1 0x0614
-#define VPE_EDI_LUT0_MASK 0x1f
-#define VPE_EDI_LUT0_SHIFT 0
-#define VPE_EDI_LUT1_MASK 0x1f
-#define VPE_EDI_LUT1_SHIFT 8
-#define VPE_EDI_LUT2_MASK 0x1f
-#define VPE_EDI_LUT2_SHIFT 16
-#define VPE_EDI_LUT3_MASK 0x1f
-#define VPE_EDI_LUT3_SHIFT 24
-
-#define VPE_DEI_EDI_LUT_R2 0x0618
-#define VPE_EDI_LUT4_MASK 0x1f
-#define VPE_EDI_LUT4_SHIFT 0
-#define VPE_EDI_LUT5_MASK 0x1f
-#define VPE_EDI_LUT5_SHIFT 8
-#define VPE_EDI_LUT6_MASK 0x1f
-#define VPE_EDI_LUT6_SHIFT 16
-#define VPE_EDI_LUT7_MASK 0x1f
-#define VPE_EDI_LUT7_SHIFT 24
-
-#define VPE_DEI_EDI_LUT_R3 0x061c
-#define VPE_EDI_LUT8_MASK 0x1f
-#define VPE_EDI_LUT8_SHIFT 0
-#define VPE_EDI_LUT9_MASK 0x1f
-#define VPE_EDI_LUT9_SHIFT 8
-#define VPE_EDI_LUT10_MASK 0x1f
-#define VPE_EDI_LUT10_SHIFT 16
-#define VPE_EDI_LUT11_MASK 0x1f
-#define VPE_EDI_LUT11_SHIFT 24
-
-#define VPE_DEI_FMD_WINDOW_R0 0x0620
-#define VPE_FMD_WINDOW_MINX_MASK 0x07ff
-#define VPE_FMD_WINDOW_MINX_SHIFT 0
-#define VPE_FMD_WINDOW_MAXX_MASK 0x07ff
-#define VPE_FMD_WINDOW_MAXX_SHIFT 16
-#define VPE_FMD_WINDOW_ENABLE BIT(31)
-
-#define VPE_DEI_FMD_WINDOW_R1 0x0624
-#define VPE_FMD_WINDOW_MINY_MASK 0x07ff
-#define VPE_FMD_WINDOW_MINY_SHIFT 0
-#define VPE_FMD_WINDOW_MAXY_MASK 0x07ff
-#define VPE_FMD_WINDOW_MAXY_SHIFT 16
-
-#define VPE_DEI_FMD_CONTROL_R0 0x0628
-#define VPE_FMD_ENABLE BIT(0)
-#define VPE_FMD_LOCK BIT(1)
-#define VPE_FMD_JAM_DIR BIT(2)
-#define VPE_FMD_BED_ENABLE BIT(3)
-#define VPE_FMD_CAF_FIELD_THR_MASK 0xff
-#define VPE_FMD_CAF_FIELD_THR_SHIFT 16
-#define VPE_FMD_CAF_LINE_THR_MASK 0xff
-#define VPE_FMD_CAF_LINE_THR_SHIFT 24
-
-#define VPE_DEI_FMD_CONTROL_R1 0x062c
-#define VPE_FMD_CAF_THR_MASK 0x000fffff
-#define VPE_FMD_CAF_THR_SHIFT 0
-
-#define VPE_DEI_FMD_STATUS_R0 0x0630
-#define VPE_FMD_CAF_MASK 0x000fffff
-#define VPE_FMD_CAF_SHIFT 0
-#define VPE_FMD_RESET BIT(24)
-
-#define VPE_DEI_FMD_STATUS_R1 0x0634
-#define VPE_FMD_FIELD_DIFF_MASK 0x0fffffff
-#define VPE_FMD_FIELD_DIFF_SHIFT 0
-
-#define VPE_DEI_FMD_STATUS_R2 0x0638
-#define VPE_FMD_FRAME_DIFF_MASK 0x000fffff
-#define VPE_FMD_FRAME_DIFF_SHIFT 0
-
-#endif
diff --git a/drivers/media/platform/ti/Makefile b/drivers/media/platform/ti/Makefile
new file mode 100644
index 000000000000..bbc737ccbbea
--- /dev/null
+++ b/drivers/media/platform/ti/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y += cal/
+obj-y += vpe/
diff --git a/drivers/media/platform/ti/cal/Makefile b/drivers/media/platform/ti/cal/Makefile
new file mode 100644
index 000000000000..45ac35585f0b
--- /dev/null
+++ b/drivers/media/platform/ti/cal/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o
+ti-cal-y := cal.o cal-camerarx.o cal-video.o
diff --git a/drivers/media/platform/ti/cal/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c
new file mode 100644
index 000000000000..6b43a1525b45
--- /dev/null
+++ b/drivers/media/platform/ti/cal/cal-camerarx.c
@@ -0,0 +1,915 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI Camera Access Layer (CAL) - CAMERARX
+ *
+ * Copyright (c) 2015-2020 Texas Instruments Inc.
+ *
+ * Authors:
+ * Benoit Parrot
+ * Laurent Pinchart
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "cal.h"
+#include "cal_regs.h"
+
+/* ------------------------------------------------------------------
+ * I/O Register Accessors
+ * ------------------------------------------------------------------
+ */
+
+static inline u32 camerarx_read(struct cal_camerarx *phy, u32 offset)
+{
+ return ioread32(phy->base + offset);
+}
+
+static inline void camerarx_write(struct cal_camerarx *phy, u32 offset, u32 val)
+{
+ iowrite32(val, phy->base + offset);
+}
+
+/* ------------------------------------------------------------------
+ * CAMERARX Management
+ * ------------------------------------------------------------------
+ */
+
+static s64 cal_camerarx_get_ext_link_freq(struct cal_camerarx *phy)
+{
+ struct v4l2_mbus_config_mipi_csi2 *mipi_csi2 = &phy->endpoint.bus.mipi_csi2;
+ u32 num_lanes = mipi_csi2->num_data_lanes;
+ const struct cal_format_info *fmtinfo;
+ u32 bpp;
+ s64 freq;
+
+ fmtinfo = cal_format_by_code(phy->formats[CAL_CAMERARX_PAD_SINK].code);
+ if (!fmtinfo)
+ return -EINVAL;
+
+ bpp = fmtinfo->bpp;
+
+ freq = v4l2_get_link_freq(phy->source->ctrl_handler, bpp, 2 * num_lanes);
+ if (freq < 0) {
+ phy_err(phy, "failed to get link freq for subdev '%s'\n",
+ phy->source->name);
+ return freq;
+ }
+
+ phy_dbg(3, phy, "Source Link Freq: %llu\n", freq);
+
+ return freq;
+}
+
+static void cal_camerarx_lane_config(struct cal_camerarx *phy)
+{
+ u32 val = cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance));
+ u32 lane_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK;
+ u32 polarity_mask = CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK;
+ struct v4l2_mbus_config_mipi_csi2 *mipi_csi2 =
+ &phy->endpoint.bus.mipi_csi2;
+ int lane;
+
+ cal_set_field(&val, mipi_csi2->clock_lane + 1, lane_mask);
+ cal_set_field(&val, mipi_csi2->lane_polarities[0], polarity_mask);
+ for (lane = 0; lane < mipi_csi2->num_data_lanes; lane++) {
+ /*
+ * Every lane are one nibble apart starting with the
+ * clock followed by the data lanes so shift masks by 4.
+ */
+ lane_mask <<= 4;
+ polarity_mask <<= 4;
+ cal_set_field(&val, mipi_csi2->data_lanes[lane] + 1, lane_mask);
+ cal_set_field(&val, mipi_csi2->lane_polarities[lane + 1],
+ polarity_mask);
+ }
+
+ cal_write(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), val);
+ phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x\n",
+ phy->instance, val);
+}
+
+static void cal_camerarx_enable(struct cal_camerarx *phy)
+{
+ u32 num_lanes = phy->cal->data->camerarx[phy->instance].num_lanes;
+
+ regmap_field_write(phy->fields[F_CAMMODE], 0);
+ /* Always enable all lanes at the phy control level */
+ regmap_field_write(phy->fields[F_LANEENABLE], (1 << num_lanes) - 1);
+ /* F_CSI_MODE is not present on every architecture */
+ if (phy->fields[F_CSI_MODE])
+ regmap_field_write(phy->fields[F_CSI_MODE], 1);
+ regmap_field_write(phy->fields[F_CTRLCLKEN], 1);
+}
+
+void cal_camerarx_disable(struct cal_camerarx *phy)
+{
+ regmap_field_write(phy->fields[F_CTRLCLKEN], 0);
+}
+
+/*
+ * TCLK values are OK at their reset values
+ */
+#define TCLK_TERM 0
+#define TCLK_MISS 1
+#define TCLK_SETTLE 14
+
+static void cal_camerarx_config(struct cal_camerarx *phy, s64 link_freq)
+{
+ unsigned int reg0, reg1;
+ unsigned int ths_term, ths_settle;
+
+ /* DPHY timing configuration */
+
+ /* THS_TERM: Programmed value = floor(20 ns/DDRClk period) */
+ ths_term = div_s64(20 * link_freq, 1000 * 1000 * 1000);
+ phy_dbg(1, phy, "ths_term: %d (0x%02x)\n", ths_term, ths_term);
+
+ /* THS_SETTLE: Programmed value = floor(105 ns/DDRClk period) + 4 */
+ ths_settle = div_s64(105 * link_freq, 1000 * 1000 * 1000) + 4;
+ phy_dbg(1, phy, "ths_settle: %d (0x%02x)\n", ths_settle, ths_settle);
+
+ reg0 = camerarx_read(phy, CAL_CSI2_PHY_REG0);
+ cal_set_field(®0, CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE,
+ CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_MASK);
+ cal_set_field(®0, ths_term, CAL_CSI2_PHY_REG0_THS_TERM_MASK);
+ cal_set_field(®0, ths_settle, CAL_CSI2_PHY_REG0_THS_SETTLE_MASK);
+
+ phy_dbg(1, phy, "CSI2_%d_REG0 = 0x%08x\n", phy->instance, reg0);
+ camerarx_write(phy, CAL_CSI2_PHY_REG0, reg0);
+
+ reg1 = camerarx_read(phy, CAL_CSI2_PHY_REG1);
+ cal_set_field(®1, TCLK_TERM, CAL_CSI2_PHY_REG1_TCLK_TERM_MASK);
+ cal_set_field(®1, 0xb8, CAL_CSI2_PHY_REG1_DPHY_HS_SYNC_PATTERN_MASK);
+ cal_set_field(®1, TCLK_MISS,
+ CAL_CSI2_PHY_REG1_CTRLCLK_DIV_FACTOR_MASK);
+ cal_set_field(®1, TCLK_SETTLE, CAL_CSI2_PHY_REG1_TCLK_SETTLE_MASK);
+
+ phy_dbg(1, phy, "CSI2_%d_REG1 = 0x%08x\n", phy->instance, reg1);
+ camerarx_write(phy, CAL_CSI2_PHY_REG1, reg1);
+}
+
+static void cal_camerarx_power(struct cal_camerarx *phy, bool enable)
+{
+ u32 target_state;
+ unsigned int i;
+
+ target_state = enable ? CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON :
+ CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF;
+
+ cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
+ target_state, CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK);
+
+ for (i = 0; i < 10; i++) {
+ u32 current_state;
+
+ current_state = cal_read_field(phy->cal,
+ CAL_CSI2_COMPLEXIO_CFG(phy->instance),
+ CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK);
+
+ if (current_state == target_state)
+ break;
+
+ usleep_range(1000, 1100);
+ }
+
+ if (i == 10)
+ phy_err(phy, "Failed to power %s complexio\n",
+ enable ? "up" : "down");
+}
+
+static void cal_camerarx_wait_reset(struct cal_camerarx *phy)
+{
+ unsigned long timeout;
+
+ timeout = jiffies + msecs_to_jiffies(750);
+ while (time_before(jiffies, timeout)) {
+ if (cal_read_field(phy->cal,
+ CAL_CSI2_COMPLEXIO_CFG(phy->instance),
+ CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) ==
+ CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
+ break;
+ usleep_range(500, 5000);
+ }
+
+ if (cal_read_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
+ CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK) !=
+ CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED)
+ phy_err(phy, "Timeout waiting for Complex IO reset done\n");
+}
+
+static void cal_camerarx_wait_stop_state(struct cal_camerarx *phy)
+{
+ unsigned long timeout;
+
+ timeout = jiffies + msecs_to_jiffies(750);
+ while (time_before(jiffies, timeout)) {
+ if (cal_read_field(phy->cal,
+ CAL_CSI2_TIMING(phy->instance),
+ CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) == 0)
+ break;
+ usleep_range(500, 5000);
+ }
+
+ if (cal_read_field(phy->cal, CAL_CSI2_TIMING(phy->instance),
+ CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK) != 0)
+ phy_err(phy, "Timeout waiting for stop state\n");
+}
+
+static void cal_camerarx_enable_irqs(struct cal_camerarx *phy)
+{
+ const u32 cio_err_mask =
+ CAL_CSI2_COMPLEXIO_IRQ_LANE_ERRORS_MASK |
+ CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK |
+ CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK |
+ CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK;
+ const u32 vc_err_mask =
+ CAL_CSI2_VC_IRQ_CS_IRQ_MASK(0) |
+ CAL_CSI2_VC_IRQ_CS_IRQ_MASK(1) |
+ CAL_CSI2_VC_IRQ_CS_IRQ_MASK(2) |
+ CAL_CSI2_VC_IRQ_CS_IRQ_MASK(3) |
+ CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(0) |
+ CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(1) |
+ CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(2) |
+ CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(3);
+
+ /* Enable CIO & VC error IRQs. */
+ cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0),
+ CAL_HL_IRQ_CIO_MASK(phy->instance) |
+ CAL_HL_IRQ_VC_MASK(phy->instance));
+ cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance),
+ cio_err_mask);
+ cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(phy->instance),
+ vc_err_mask);
+}
+
+static void cal_camerarx_disable_irqs(struct cal_camerarx *phy)
+{
+ /* Disable CIO error irqs */
+ cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(0),
+ CAL_HL_IRQ_CIO_MASK(phy->instance) |
+ CAL_HL_IRQ_VC_MASK(phy->instance));
+ cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), 0);
+ cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(phy->instance), 0);
+}
+
+static void cal_camerarx_ppi_enable(struct cal_camerarx *phy)
+{
+ cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
+ 1, CAL_CSI2_PPI_CTRL_ECC_EN_MASK);
+
+ cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
+ 1, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
+}
+
+static void cal_camerarx_ppi_disable(struct cal_camerarx *phy)
+{
+ cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance),
+ 0, CAL_CSI2_PPI_CTRL_IF_EN_MASK);
+}
+
+static int cal_camerarx_start(struct cal_camerarx *phy)
+{
+ s64 link_freq;
+ u32 sscounter;
+ u32 val;
+ int ret;
+
+ if (phy->enable_count > 0) {
+ phy->enable_count++;
+ return 0;
+ }
+
+ link_freq = cal_camerarx_get_ext_link_freq(phy);
+ if (link_freq < 0)
+ return link_freq;
+
+ ret = v4l2_subdev_call(phy->source, core, s_power, 1);
+ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
+ phy_err(phy, "power on failed in subdev\n");
+ return ret;
+ }
+
+ cal_camerarx_enable_irqs(phy);
+
+ /*
+ * CSI-2 PHY Link Initialization Sequence, according to the DRA74xP /
+ * DRA75xP / DRA76xP / DRA77xP TRM. The DRA71x / DRA72x and the AM65x /
+ * DRA80xM TRMs have a a slightly simplified sequence.
+ */
+
+ /*
+ * 1. Configure all CSI-2 low level protocol registers to be ready to
+ * receive signals/data from the CSI-2 PHY.
+ *
+ * i.-v. Configure the lanes position and polarity.
+ */
+ cal_camerarx_lane_config(phy);
+
+ /*
+ * vi.-vii. Configure D-PHY mode, enable the required lanes and
+ * enable the CAMERARX clock.
+ */
+ cal_camerarx_enable(phy);
+
+ /*
+ * 2. CSI PHY and link initialization sequence.
+ *
+ * a. Deassert the CSI-2 PHY reset. Do not wait for reset completion
+ * at this point, as it requires the external source to send the
+ * CSI-2 HS clock.
+ */
+ cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
+ CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL,
+ CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
+ phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x De-assert Complex IO Reset\n",
+ phy->instance,
+ cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)));
+
+ /* Dummy read to allow SCP reset to complete. */
+ camerarx_read(phy, CAL_CSI2_PHY_REG0);
+
+ /* Program the PHY timing parameters. */
+ cal_camerarx_config(phy, link_freq);
+
+ /*
+ * b. Assert the FORCERXMODE signal.
+ *
+ * The stop-state-counter is based on fclk cycles, and we always use
+ * the x16 and x4 settings, so stop-state-timeout =
+ * fclk-cycle * 16 * 4 * counter.
+ *
+ * Stop-state-timeout must be more than 100us as per CSI-2 spec, so we
+ * calculate a timeout that's 100us (rounding up).
+ */
+ sscounter = DIV_ROUND_UP(clk_get_rate(phy->cal->fclk), 10000 * 16 * 4);
+
+ val = cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance));
+ cal_set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK);
+ cal_set_field(&val, 1, CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK);
+ cal_set_field(&val, sscounter,
+ CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK);
+ cal_write(phy->cal, CAL_CSI2_TIMING(phy->instance), val);
+ phy_dbg(3, phy, "CAL_CSI2_TIMING(%d) = 0x%08x Stop States\n",
+ phy->instance,
+ cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance)));
+
+ /* Assert the FORCERXMODE signal. */
+ cal_write_field(phy->cal, CAL_CSI2_TIMING(phy->instance),
+ 1, CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK);
+ phy_dbg(3, phy, "CAL_CSI2_TIMING(%d) = 0x%08x Force RXMODE\n",
+ phy->instance,
+ cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance)));
+
+ /*
+ * c. Connect pull-down on CSI-2 PHY link (using pad control).
+ *
+ * This is not required on DRA71x, DRA72x, AM65x and DRA80xM. Not
+ * implemented.
+ */
+
+ /*
+ * d. Power up the CSI-2 PHY.
+ * e. Check whether the state status reaches the ON state.
+ */
+ cal_camerarx_power(phy, true);
+
+ /*
+ * Start the source to enable the CSI-2 HS clock. We can now wait for
+ * CSI-2 PHY reset to complete.
+ */
+ ret = v4l2_subdev_call(phy->source, video, s_stream, 1);
+ if (ret) {
+ v4l2_subdev_call(phy->source, core, s_power, 0);
+ cal_camerarx_disable_irqs(phy);
+ phy_err(phy, "stream on failed in subdev\n");
+ return ret;
+ }
+
+ cal_camerarx_wait_reset(phy);
+
+ /* f. Wait for STOPSTATE=1 for all enabled lane modules. */
+ cal_camerarx_wait_stop_state(phy);
+
+ phy_dbg(1, phy, "CSI2_%u_REG1 = 0x%08x (bits 31-28 should be set)\n",
+ phy->instance, camerarx_read(phy, CAL_CSI2_PHY_REG1));
+
+ /*
+ * g. Disable pull-down on CSI-2 PHY link (using pad control).
+ *
+ * This is not required on DRA71x, DRA72x, AM65x and DRA80xM. Not
+ * implemented.
+ */
+
+ /* Finally, enable the PHY Protocol Interface (PPI). */
+ cal_camerarx_ppi_enable(phy);
+
+ phy->enable_count++;
+
+ return 0;
+}
+
+static void cal_camerarx_stop(struct cal_camerarx *phy)
+{
+ int ret;
+
+ if (--phy->enable_count > 0)
+ return;
+
+ cal_camerarx_ppi_disable(phy);
+
+ cal_camerarx_disable_irqs(phy);
+
+ cal_camerarx_power(phy, false);
+
+ /* Assert Complex IO Reset */
+ cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance),
+ CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL,
+ CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK);
+
+ phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Complex IO in Reset\n",
+ phy->instance,
+ cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)));
+
+ /* Disable the phy */
+ cal_camerarx_disable(phy);
+
+ if (v4l2_subdev_call(phy->source, video, s_stream, 0))
+ phy_err(phy, "stream off failed in subdev\n");
+
+ ret = v4l2_subdev_call(phy->source, core, s_power, 0);
+ if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+ phy_err(phy, "power off failed in subdev\n");
+}
+
+/*
+ * Errata i913: CSI2 LDO Needs to be disabled when module is powered on
+ *
+ * Enabling CSI2 LDO shorts it to core supply. It is crucial the 2 CSI2
+ * LDOs on the device are disabled if CSI-2 module is powered on
+ * (0x4845 B304 | 0x4845 B384 [28:27] = 0x1) or in ULPS (0x4845 B304
+ * | 0x4845 B384 [28:27] = 0x2) mode. Common concerns include: high
+ * current draw on the module supply in active mode.
+ *
+ * Errata does not apply when CSI-2 module is powered off
+ * (0x4845 B304 | 0x4845 B384 [28:27] = 0x0).
+ *
+ * SW Workaround:
+ * Set the following register bits to disable the LDO,
+ * which is essentially CSI2 REG10 bit 6:
+ *
+ * Core 0: 0x4845 B828 = 0x0000 0040
+ * Core 1: 0x4845 B928 = 0x0000 0040
+ */
+void cal_camerarx_i913_errata(struct cal_camerarx *phy)
+{
+ u32 reg10 = camerarx_read(phy, CAL_CSI2_PHY_REG10);
+
+ cal_set_field(®10, 1, CAL_CSI2_PHY_REG10_I933_LDO_DISABLE_MASK);
+
+ phy_dbg(1, phy, "CSI2_%d_REG10 = 0x%08x\n", phy->instance, reg10);
+ camerarx_write(phy, CAL_CSI2_PHY_REG10, reg10);
+}
+
+static int cal_camerarx_regmap_init(struct cal_dev *cal,
+ struct cal_camerarx *phy)
+{
+ const struct cal_camerarx_data *phy_data;
+ unsigned int i;
+
+ if (!cal->data)
+ return -EINVAL;
+
+ phy_data = &cal->data->camerarx[phy->instance];
+
+ for (i = 0; i < F_MAX_FIELDS; i++) {
+ struct reg_field field = {
+ .reg = cal->syscon_camerrx_offset,
+ .lsb = phy_data->fields[i].lsb,
+ .msb = phy_data->fields[i].msb,
+ };
+
+ /*
+ * Here we update the reg offset with the
+ * value found in DT
+ */
+ phy->fields[i] = devm_regmap_field_alloc(cal->dev,
+ cal->syscon_camerrx,
+ field);
+ if (IS_ERR(phy->fields[i])) {
+ cal_err(cal, "Unable to allocate regmap fields\n");
+ return PTR_ERR(phy->fields[i]);
+ }
+ }
+
+ return 0;
+}
+
+static int cal_camerarx_parse_dt(struct cal_camerarx *phy)
+{
+ struct v4l2_fwnode_endpoint *endpoint = &phy->endpoint;
+ char data_lanes[V4L2_MBUS_CSI2_MAX_DATA_LANES * 2];
+ struct device_node *ep_node;
+ unsigned int i;
+ int ret;
+
+ /*
+ * Find the endpoint node for the port corresponding to the PHY
+ * instance, and parse its CSI-2-related properties.
+ */
+ ep_node = of_graph_get_endpoint_by_regs(phy->cal->dev->of_node,
+ phy->instance, 0);
+ if (!ep_node) {
+ /*
+ * The endpoint is not mandatory, not all PHY instances need to
+ * be connected in DT.
+ */
+ phy_dbg(3, phy, "Port has no endpoint\n");
+ return 0;
+ }
+
+ endpoint->bus_type = V4L2_MBUS_CSI2_DPHY;
+ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), endpoint);
+ if (ret < 0) {
+ phy_err(phy, "Failed to parse endpoint\n");
+ goto done;
+ }
+
+ for (i = 0; i < endpoint->bus.mipi_csi2.num_data_lanes; i++) {
+ unsigned int lane = endpoint->bus.mipi_csi2.data_lanes[i];
+
+ if (lane > 4) {
+ phy_err(phy, "Invalid position %u for data lane %u\n",
+ lane, i);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ data_lanes[i*2] = '0' + lane;
+ data_lanes[i*2+1] = ' ';
+ }
+
+ data_lanes[i*2-1] = '\0';
+
+ phy_dbg(3, phy,
+ "CSI-2 bus: clock lane <%u>, data lanes <%s>, flags 0x%08x\n",
+ endpoint->bus.mipi_csi2.clock_lane, data_lanes,
+ endpoint->bus.mipi_csi2.flags);
+
+ /* Retrieve the connected device and store it for later use. */
+ phy->source_ep_node = of_graph_get_remote_endpoint(ep_node);
+ phy->source_node = of_graph_get_port_parent(phy->source_ep_node);
+ if (!phy->source_node) {
+ phy_dbg(3, phy, "Can't get remote parent\n");
+ of_node_put(phy->source_ep_node);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ phy_dbg(1, phy, "Found connected device %pOFn\n", phy->source_node);
+
+done:
+ of_node_put(ep_node);
+ return ret;
+}
+
+/* ------------------------------------------------------------------
+ * V4L2 Subdev Operations
+ * ------------------------------------------------------------------
+ */
+
+static inline struct cal_camerarx *to_cal_camerarx(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct cal_camerarx, subdev);
+}
+
+static struct v4l2_mbus_framefmt *
+cal_camerarx_get_pad_format(struct cal_camerarx *phy,
+ struct v4l2_subdev_state *sd_state,
+ unsigned int pad, u32 which)
+{
+ switch (which) {
+ case V4L2_SUBDEV_FORMAT_TRY:
+ return v4l2_subdev_get_try_format(&phy->subdev, sd_state, pad);
+ case V4L2_SUBDEV_FORMAT_ACTIVE:
+ return &phy->formats[pad];
+ default:
+ return NULL;
+ }
+}
+
+static int cal_camerarx_sd_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct cal_camerarx *phy = to_cal_camerarx(sd);
+ int ret = 0;
+
+ mutex_lock(&phy->mutex);
+
+ if (enable)
+ ret = cal_camerarx_start(phy);
+ else
+ cal_camerarx_stop(phy);
+
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+
+static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ struct cal_camerarx *phy = to_cal_camerarx(sd);
+ int ret = 0;
+
+ mutex_lock(&phy->mutex);
+
+ /* No transcoding, source and sink codes must match. */
+ if (cal_rx_pad_is_source(code->pad)) {
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (code->index > 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ fmt = cal_camerarx_get_pad_format(phy, sd_state,
+ CAL_CAMERARX_PAD_SINK,
+ code->which);
+ code->code = fmt->code;
+ } else {
+ if (code->index >= cal_num_formats) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ code->code = cal_formats[code->index].code;
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+
+static int cal_camerarx_sd_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ struct cal_camerarx *phy = to_cal_camerarx(sd);
+ const struct cal_format_info *fmtinfo;
+ int ret = 0;
+
+ if (fse->index > 0)
+ return -EINVAL;
+
+ mutex_lock(&phy->mutex);
+
+ /* No transcoding, source and sink formats must match. */
+ if (cal_rx_pad_is_source(fse->pad)) {
+ struct v4l2_mbus_framefmt *fmt;
+
+ fmt = cal_camerarx_get_pad_format(phy, sd_state,
+ CAL_CAMERARX_PAD_SINK,
+ fse->which);
+ if (fse->code != fmt->code) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ fse->min_width = fmt->width;
+ fse->max_width = fmt->width;
+ fse->min_height = fmt->height;
+ fse->max_height = fmt->height;
+ } else {
+ fmtinfo = cal_format_by_code(fse->code);
+ if (!fmtinfo) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ fse->min_width = CAL_MIN_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8);
+ fse->max_width = CAL_MAX_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8);
+ fse->min_height = CAL_MIN_HEIGHT_LINES;
+ fse->max_height = CAL_MAX_HEIGHT_LINES;
+ }
+
+out:
+ mutex_unlock(&phy->mutex);
+
+ return ret;
+}
+
+static int cal_camerarx_sd_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_format *format)
+{
+ struct cal_camerarx *phy = to_cal_camerarx(sd);
+ struct v4l2_mbus_framefmt *fmt;
+
+ mutex_lock(&phy->mutex);
+
+ fmt = cal_camerarx_get_pad_format(phy, sd_state, format->pad,
+ format->which);
+ format->format = *fmt;
+
+ mutex_unlock(&phy->mutex);
+
+ return 0;
+}
+
+static int cal_camerarx_sd_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_format *format)
+{
+ struct cal_camerarx *phy = to_cal_camerarx(sd);
+ const struct cal_format_info *fmtinfo;
+ struct v4l2_mbus_framefmt *fmt;
+ unsigned int bpp;
+
+ /* No transcoding, source and sink formats must match. */
+ if (cal_rx_pad_is_source(format->pad))
+ return cal_camerarx_sd_get_fmt(sd, sd_state, format);
+
+ /*
+ * Default to the first format if the requested media bus code isn't
+ * supported.
+ */
+ fmtinfo = cal_format_by_code(format->format.code);
+ if (!fmtinfo)
+ fmtinfo = &cal_formats[0];
+
+ /* Clamp the size, update the code. The colorspace is accepted as-is. */
+ bpp = ALIGN(fmtinfo->bpp, 8);
+
+ format->format.width = clamp_t(unsigned int, format->format.width,
+ CAL_MIN_WIDTH_BYTES * 8 / bpp,
+ CAL_MAX_WIDTH_BYTES * 8 / bpp);
+ format->format.height = clamp_t(unsigned int, format->format.height,
+ CAL_MIN_HEIGHT_LINES,
+ CAL_MAX_HEIGHT_LINES);
+ format->format.code = fmtinfo->code;
+ format->format.field = V4L2_FIELD_NONE;
+
+ /* Store the format and propagate it to the source pad. */
+
+ mutex_lock(&phy->mutex);
+
+ fmt = cal_camerarx_get_pad_format(phy, sd_state,
+ CAL_CAMERARX_PAD_SINK,
+ format->which);
+ *fmt = format->format;
+
+ fmt = cal_camerarx_get_pad_format(phy, sd_state,
+ CAL_CAMERARX_PAD_FIRST_SOURCE,
+ format->which);
+ *fmt = format->format;
+
+ mutex_unlock(&phy->mutex);
+
+ return 0;
+}
+
+static int cal_camerarx_sd_init_cfg(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
+{
+ struct v4l2_subdev_format format = {
+ .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY
+ : V4L2_SUBDEV_FORMAT_ACTIVE,
+ .pad = CAL_CAMERARX_PAD_SINK,
+ .format = {
+ .width = 640,
+ .height = 480,
+ .code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .field = V4L2_FIELD_NONE,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .ycbcr_enc = V4L2_YCBCR_ENC_601,
+ .quantization = V4L2_QUANTIZATION_LIM_RANGE,
+ .xfer_func = V4L2_XFER_FUNC_SRGB,
+ },
+ };
+
+ return cal_camerarx_sd_set_fmt(sd, sd_state, &format);
+}
+
+static const struct v4l2_subdev_video_ops cal_camerarx_video_ops = {
+ .s_stream = cal_camerarx_sd_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops cal_camerarx_pad_ops = {
+ .init_cfg = cal_camerarx_sd_init_cfg,
+ .enum_mbus_code = cal_camerarx_sd_enum_mbus_code,
+ .enum_frame_size = cal_camerarx_sd_enum_frame_size,
+ .get_fmt = cal_camerarx_sd_get_fmt,
+ .set_fmt = cal_camerarx_sd_set_fmt,
+};
+
+static const struct v4l2_subdev_ops cal_camerarx_subdev_ops = {
+ .video = &cal_camerarx_video_ops,
+ .pad = &cal_camerarx_pad_ops,
+};
+
+static struct media_entity_operations cal_camerarx_media_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+/* ------------------------------------------------------------------
+ * Create and Destroy
+ * ------------------------------------------------------------------
+ */
+
+struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
+ unsigned int instance)
+{
+ struct platform_device *pdev = to_platform_device(cal->dev);
+ struct cal_camerarx *phy;
+ struct v4l2_subdev *sd;
+ unsigned int i;
+ int ret;
+
+ phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return ERR_PTR(-ENOMEM);
+
+ phy->cal = cal;
+ phy->instance = instance;
+
+ mutex_init(&phy->mutex);
+
+ phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ (instance == 0) ?
+ "cal_rx_core0" :
+ "cal_rx_core1");
+ phy->base = devm_ioremap_resource(cal->dev, phy->res);
+ if (IS_ERR(phy->base)) {
+ cal_err(cal, "failed to ioremap\n");
+ ret = PTR_ERR(phy->base);
+ goto error;
+ }
+
+ cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
+ phy->res->name, &phy->res->start, &phy->res->end);
+
+ ret = cal_camerarx_regmap_init(cal, phy);
+ if (ret)
+ goto error;
+
+ ret = cal_camerarx_parse_dt(phy);
+ if (ret)
+ goto error;
+
+ /* Initialize the V4L2 subdev and media entity. */
+ sd = &phy->subdev;
+ v4l2_subdev_init(sd, &cal_camerarx_subdev_ops);
+ sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+ sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
+ snprintf(sd->name, sizeof(sd->name), "CAMERARX%u", instance);
+ sd->dev = cal->dev;
+
+ phy->pads[CAL_CAMERARX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ for (i = CAL_CAMERARX_PAD_FIRST_SOURCE; i < CAL_CAMERARX_NUM_PADS; ++i)
+ phy->pads[i].flags = MEDIA_PAD_FL_SOURCE;
+ sd->entity.ops = &cal_camerarx_media_ops;
+ ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(phy->pads),
+ phy->pads);
+ if (ret)
+ goto error;
+
+ ret = cal_camerarx_sd_init_cfg(sd, NULL);
+ if (ret)
+ goto error;
+
+ ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd);
+ if (ret)
+ goto error;
+
+ return phy;
+
+error:
+ media_entity_cleanup(&phy->subdev.entity);
+ kfree(phy);
+ return ERR_PTR(ret);
+}
+
+void cal_camerarx_destroy(struct cal_camerarx *phy)
+{
+ if (!phy)
+ return;
+
+ v4l2_device_unregister_subdev(&phy->subdev);
+ media_entity_cleanup(&phy->subdev.entity);
+ of_node_put(phy->source_ep_node);
+ of_node_put(phy->source_node);
+ mutex_destroy(&phy->mutex);
+ kfree(phy);
+}
diff --git a/drivers/media/platform/ti/cal/cal-video.c b/drivers/media/platform/ti/cal/cal-video.c
new file mode 100644
index 000000000000..3e936a2ca36c
--- /dev/null
+++ b/drivers/media/platform/ti/cal/cal-video.c
@@ -0,0 +1,1049 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI Camera Access Layer (CAL) - Video Device
+ *
+ * Copyright (c) 2015-2020 Texas Instruments Inc.
+ *
+ * Authors:
+ * Benoit Parrot
+ * Laurent Pinchart
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "cal.h"
+
+/* Print Four-character-code (FOURCC) */
+static char *fourcc_to_str(u32 fmt)
+{
+ static char code[5];
+
+ code[0] = (unsigned char)(fmt & 0xff);
+ code[1] = (unsigned char)((fmt >> 8) & 0xff);
+ code[2] = (unsigned char)((fmt >> 16) & 0xff);
+ code[3] = (unsigned char)((fmt >> 24) & 0xff);
+ code[4] = '\0';
+
+ return code;
+}
+
+/* ------------------------------------------------------------------
+ * V4L2 Common IOCTLs
+ * ------------------------------------------------------------------
+ */
+
+static int cal_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+
+ strscpy(cap->driver, CAL_MODULE_NAME, sizeof(cap->driver));
+ strscpy(cap->card, CAL_MODULE_NAME, sizeof(cap->card));
+
+ snprintf(cap->bus_info, sizeof(cap->bus_info),
+ "platform:%s", dev_name(ctx->cal->dev));
+ return 0;
+}
+
+static int cal_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+
+ *f = ctx->v_fmt;
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------
+ * V4L2 Video Node Centric IOCTLs
+ * ------------------------------------------------------------------
+ */
+
+static const struct cal_format_info *find_format_by_pix(struct cal_ctx *ctx,
+ u32 pixelformat)
+{
+ const struct cal_format_info *fmtinfo;
+ unsigned int k;
+
+ for (k = 0; k < ctx->num_active_fmt; k++) {
+ fmtinfo = ctx->active_fmt[k];
+ if (fmtinfo->fourcc == pixelformat)
+ return fmtinfo;
+ }
+
+ return NULL;
+}
+
+static const struct cal_format_info *find_format_by_code(struct cal_ctx *ctx,
+ u32 code)
+{
+ const struct cal_format_info *fmtinfo;
+ unsigned int k;
+
+ for (k = 0; k < ctx->num_active_fmt; k++) {
+ fmtinfo = ctx->active_fmt[k];
+ if (fmtinfo->code == code)
+ return fmtinfo;
+ }
+
+ return NULL;
+}
+
+static int cal_legacy_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+ const struct cal_format_info *fmtinfo;
+
+ if (f->index >= ctx->num_active_fmt)
+ return -EINVAL;
+
+ fmtinfo = ctx->active_fmt[f->index];
+
+ f->pixelformat = fmtinfo->fourcc;
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ return 0;
+}
+
+static int __subdev_get_format(struct cal_ctx *ctx,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ struct v4l2_subdev_format sd_fmt;
+ struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
+ int ret;
+
+ sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ sd_fmt.pad = 0;
+
+ ret = v4l2_subdev_call(ctx->phy->source, pad, get_fmt, NULL, &sd_fmt);
+ if (ret)
+ return ret;
+
+ *fmt = *mbus_fmt;
+
+ ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
+ fmt->width, fmt->height, fmt->code);
+
+ return 0;
+}
+
+static int __subdev_set_format(struct cal_ctx *ctx,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ struct v4l2_subdev_format sd_fmt;
+ struct v4l2_mbus_framefmt *mbus_fmt = &sd_fmt.format;
+ int ret;
+
+ sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ sd_fmt.pad = 0;
+ *mbus_fmt = *fmt;
+
+ ret = v4l2_subdev_call(ctx->phy->source, pad, set_fmt, NULL, &sd_fmt);
+ if (ret)
+ return ret;
+
+ ctx_dbg(1, ctx, "%s %dx%d code:%04X\n", __func__,
+ fmt->width, fmt->height, fmt->code);
+
+ return 0;
+}
+
+static void cal_calc_format_size(struct cal_ctx *ctx,
+ const struct cal_format_info *fmtinfo,
+ struct v4l2_format *f)
+{
+ u32 bpl, max_width;
+
+ /*
+ * Maximum width is bound by the DMA max width in bytes.
+ * We need to recalculate the actual maxi width depending on the
+ * number of bytes per pixels required.
+ */
+ max_width = CAL_MAX_WIDTH_BYTES / (ALIGN(fmtinfo->bpp, 8) >> 3);
+ v4l_bound_align_image(&f->fmt.pix.width, 48, max_width, 2,
+ &f->fmt.pix.height, 32, CAL_MAX_HEIGHT_LINES,
+ 0, 0);
+
+ bpl = (f->fmt.pix.width * ALIGN(fmtinfo->bpp, 8)) >> 3;
+ f->fmt.pix.bytesperline = ALIGN(bpl, 16);
+
+ f->fmt.pix.sizeimage = f->fmt.pix.height *
+ f->fmt.pix.bytesperline;
+
+ ctx_dbg(3, ctx, "%s: fourcc: %s size: %dx%d bpl:%d img_size:%d\n",
+ __func__, fourcc_to_str(f->fmt.pix.pixelformat),
+ f->fmt.pix.width, f->fmt.pix.height,
+ f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+}
+
+static int cal_legacy_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+ const struct cal_format_info *fmtinfo;
+ struct v4l2_subdev_frame_size_enum fse;
+ int ret, found;
+
+ fmtinfo = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
+ if (!fmtinfo) {
+ ctx_dbg(3, ctx, "Fourcc format (0x%08x) not found.\n",
+ f->fmt.pix.pixelformat);
+
+ /* Just get the first one enumerated */
+ fmtinfo = ctx->active_fmt[0];
+ f->fmt.pix.pixelformat = fmtinfo->fourcc;
+ }
+
+ f->fmt.pix.field = ctx->v_fmt.fmt.pix.field;
+
+ /* check for/find a valid width/height */
+ ret = 0;
+ found = false;
+ fse.pad = 0;
+ fse.code = fmtinfo->code;
+ fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ for (fse.index = 0; ; fse.index++) {
+ ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_size,
+ NULL, &fse);
+ if (ret)
+ break;
+
+ if ((f->fmt.pix.width == fse.max_width) &&
+ (f->fmt.pix.height == fse.max_height)) {
+ found = true;
+ break;
+ } else if ((f->fmt.pix.width >= fse.min_width) &&
+ (f->fmt.pix.width <= fse.max_width) &&
+ (f->fmt.pix.height >= fse.min_height) &&
+ (f->fmt.pix.height <= fse.max_height)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ /* use existing values as default */
+ f->fmt.pix.width = ctx->v_fmt.fmt.pix.width;
+ f->fmt.pix.height = ctx->v_fmt.fmt.pix.height;
+ }
+
+ /*
+ * Use current colorspace for now, it will get
+ * updated properly during s_fmt
+ */
+ f->fmt.pix.colorspace = ctx->v_fmt.fmt.pix.colorspace;
+ cal_calc_format_size(ctx, fmtinfo, f);
+ return 0;
+}
+
+static int cal_legacy_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+ struct vb2_queue *q = &ctx->vb_vidq;
+ struct v4l2_subdev_format sd_fmt = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .pad = CAL_CAMERARX_PAD_SINK,
+ };
+ const struct cal_format_info *fmtinfo;
+ int ret;
+
+ if (vb2_is_busy(q)) {
+ ctx_dbg(3, ctx, "%s device busy\n", __func__);
+ return -EBUSY;
+ }
+
+ ret = cal_legacy_try_fmt_vid_cap(file, priv, f);
+ if (ret < 0)
+ return ret;
+
+ fmtinfo = find_format_by_pix(ctx, f->fmt.pix.pixelformat);
+
+ v4l2_fill_mbus_format(&sd_fmt.format, &f->fmt.pix, fmtinfo->code);
+
+ ret = __subdev_set_format(ctx, &sd_fmt.format);
+ if (ret)
+ return ret;
+
+ /* Just double check nothing has gone wrong */
+ if (sd_fmt.format.code != fmtinfo->code) {
+ ctx_dbg(3, ctx,
+ "%s subdev changed format on us, this should not happen\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &sd_fmt.format);
+ ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ ctx->v_fmt.fmt.pix.pixelformat = fmtinfo->fourcc;
+ ctx->v_fmt.fmt.pix.field = sd_fmt.format.field;
+ cal_calc_format_size(ctx, fmtinfo, &ctx->v_fmt);
+
+ v4l2_subdev_call(&ctx->phy->subdev, pad, set_fmt, NULL, &sd_fmt);
+
+ ctx->fmtinfo = fmtinfo;
+ *f = ctx->v_fmt;
+
+ return 0;
+}
+
+static int cal_legacy_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+ const struct cal_format_info *fmtinfo;
+ struct v4l2_subdev_frame_size_enum fse;
+ int ret;
+
+ /* check for valid format */
+ fmtinfo = find_format_by_pix(ctx, fsize->pixel_format);
+ if (!fmtinfo) {
+ ctx_dbg(3, ctx, "Invalid pixel code: %x\n",
+ fsize->pixel_format);
+ return -EINVAL;
+ }
+
+ fse.index = fsize->index;
+ fse.pad = 0;
+ fse.code = fmtinfo->code;
+ fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+
+ ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_size, NULL,
+ &fse);
+ if (ret)
+ return ret;
+
+ ctx_dbg(1, ctx, "%s: index: %d code: %x W:[%d,%d] H:[%d,%d]\n",
+ __func__, fse.index, fse.code, fse.min_width, fse.max_width,
+ fse.min_height, fse.max_height);
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = fse.max_width;
+ fsize->discrete.height = fse.max_height;
+
+ return 0;
+}
+
+static int cal_legacy_enum_input(struct file *file, void *priv,
+ struct v4l2_input *inp)
+{
+ if (inp->index > 0)
+ return -EINVAL;
+
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+ sprintf(inp->name, "Camera %u", inp->index);
+ return 0;
+}
+
+static int cal_legacy_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int cal_legacy_s_input(struct file *file, void *priv, unsigned int i)
+{
+ return i > 0 ? -EINVAL : 0;
+}
+
+/* timeperframe is arbitrary and continuous */
+static int cal_legacy_enum_frameintervals(struct file *file, void *priv,
+ struct v4l2_frmivalenum *fival)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+ const struct cal_format_info *fmtinfo;
+ struct v4l2_subdev_frame_interval_enum fie = {
+ .index = fival->index,
+ .width = fival->width,
+ .height = fival->height,
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ };
+ int ret;
+
+ fmtinfo = find_format_by_pix(ctx, fival->pixel_format);
+ if (!fmtinfo)
+ return -EINVAL;
+
+ fie.code = fmtinfo->code;
+ ret = v4l2_subdev_call(ctx->phy->source, pad, enum_frame_interval,
+ NULL, &fie);
+ if (ret)
+ return ret;
+ fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fival->discrete = fie.interval;
+
+ return 0;
+}
+
+static int cal_legacy_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+
+ return v4l2_g_parm_cap(video_devdata(file), ctx->phy->source, a);
+}
+
+static int cal_legacy_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+
+ return v4l2_s_parm_cap(video_devdata(file), ctx->phy->source, a);
+}
+
+static const struct v4l2_ioctl_ops cal_ioctl_legacy_ops = {
+ .vidioc_querycap = cal_querycap,
+ .vidioc_enum_fmt_vid_cap = cal_legacy_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = cal_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = cal_legacy_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = cal_legacy_s_fmt_vid_cap,
+ .vidioc_enum_framesizes = cal_legacy_enum_framesizes,
+ .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_expbuf = vb2_ioctl_expbuf,
+ .vidioc_enum_input = cal_legacy_enum_input,
+ .vidioc_g_input = cal_legacy_g_input,
+ .vidioc_s_input = cal_legacy_s_input,
+ .vidioc_enum_frameintervals = cal_legacy_enum_frameintervals,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_g_parm = cal_legacy_g_parm,
+ .vidioc_s_parm = cal_legacy_s_parm,
+};
+
+/* ------------------------------------------------------------------
+ * V4L2 Media Controller Centric IOCTLs
+ * ------------------------------------------------------------------
+ */
+
+static int cal_mc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ unsigned int i;
+ unsigned int idx;
+
+ if (f->index >= cal_num_formats)
+ return -EINVAL;
+
+ idx = 0;
+
+ for (i = 0; i < cal_num_formats; ++i) {
+ if (f->mbus_code && cal_formats[i].code != f->mbus_code)
+ continue;
+
+ if (idx == f->index) {
+ f->pixelformat = cal_formats[i].fourcc;
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ return 0;
+ }
+
+ idx++;
+ }
+
+ return -EINVAL;
+}
+
+static void cal_mc_try_fmt(struct cal_ctx *ctx, struct v4l2_format *f,
+ const struct cal_format_info **info)
+{
+ struct v4l2_pix_format *format = &f->fmt.pix;
+ const struct cal_format_info *fmtinfo;
+ unsigned int bpp;
+
+ /*
+ * Default to the first format if the requested pixel format code isn't
+ * supported.
+ */
+ fmtinfo = cal_format_by_fourcc(f->fmt.pix.pixelformat);
+ if (!fmtinfo)
+ fmtinfo = &cal_formats[0];
+
+ /*
+ * Clamp the size, update the pixel format. The field and colorspace are
+ * accepted as-is, except for V4L2_FIELD_ANY that is turned into
+ * V4L2_FIELD_NONE.
+ */
+ bpp = ALIGN(fmtinfo->bpp, 8);
+
+ format->width = clamp_t(unsigned int, format->width,
+ CAL_MIN_WIDTH_BYTES * 8 / bpp,
+ CAL_MAX_WIDTH_BYTES * 8 / bpp);
+ format->height = clamp_t(unsigned int, format->height,
+ CAL_MIN_HEIGHT_LINES, CAL_MAX_HEIGHT_LINES);
+ format->pixelformat = fmtinfo->fourcc;
+
+ if (format->field == V4L2_FIELD_ANY)
+ format->field = V4L2_FIELD_NONE;
+
+ /*
+ * Calculate the number of bytes per line and the image size. The
+ * hardware stores the stride as a number of 16 bytes words, in a
+ * signed 15-bit value. Only 14 bits are thus usable.
+ */
+ format->bytesperline = ALIGN(clamp(format->bytesperline,
+ format->width * bpp / 8,
+ ((1U << 14) - 1) * 16), 16);
+
+ format->sizeimage = format->height * format->bytesperline;
+
+ format->colorspace = ctx->v_fmt.fmt.pix.colorspace;
+
+ if (info)
+ *info = fmtinfo;
+
+ ctx_dbg(3, ctx, "%s: %s %ux%u (bytesperline %u sizeimage %u)\n",
+ __func__, fourcc_to_str(format->pixelformat),
+ format->width, format->height,
+ format->bytesperline, format->sizeimage);
+}
+
+static int cal_mc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+
+ cal_mc_try_fmt(ctx, f, NULL);
+ return 0;
+}
+
+static int cal_mc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+ const struct cal_format_info *fmtinfo;
+
+ if (vb2_is_busy(&ctx->vb_vidq)) {
+ ctx_dbg(3, ctx, "%s device busy\n", __func__);
+ return -EBUSY;
+ }
+
+ cal_mc_try_fmt(ctx, f, &fmtinfo);
+
+ ctx->v_fmt = *f;
+ ctx->fmtinfo = fmtinfo;
+
+ return 0;
+}
+
+static int cal_mc_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct cal_ctx *ctx = video_drvdata(file);
+ const struct cal_format_info *fmtinfo;
+ unsigned int bpp;
+
+ if (fsize->index > 0)
+ return -EINVAL;
+
+ fmtinfo = cal_format_by_fourcc(fsize->pixel_format);
+ if (!fmtinfo) {
+ ctx_dbg(3, ctx, "Invalid pixel format 0x%08x\n",
+ fsize->pixel_format);
+ return -EINVAL;
+ }
+
+ bpp = ALIGN(fmtinfo->bpp, 8);
+
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ fsize->stepwise.min_width = CAL_MIN_WIDTH_BYTES * 8 / bpp;
+ fsize->stepwise.max_width = CAL_MAX_WIDTH_BYTES * 8 / bpp;
+ fsize->stepwise.step_width = 64 / bpp;
+ fsize->stepwise.min_height = CAL_MIN_HEIGHT_LINES;
+ fsize->stepwise.max_height = CAL_MAX_HEIGHT_LINES;
+ fsize->stepwise.step_height = 1;
+
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops cal_ioctl_mc_ops = {
+ .vidioc_querycap = cal_querycap,
+ .vidioc_enum_fmt_vid_cap = cal_mc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = cal_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = cal_mc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = cal_mc_s_fmt_vid_cap,
+ .vidioc_enum_framesizes = cal_mc_enum_framesizes,
+ .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_expbuf = vb2_ioctl_expbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+};
+
+/* ------------------------------------------------------------------
+ * videobuf2 Common Operations
+ * ------------------------------------------------------------------
+ */
+
+static int cal_queue_setup(struct vb2_queue *vq,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct cal_ctx *ctx = vb2_get_drv_priv(vq);
+ unsigned int size = ctx->v_fmt.fmt.pix.sizeimage;
+
+ if (vq->num_buffers + *nbuffers < 3)
+ *nbuffers = 3 - vq->num_buffers;
+
+ if (*nplanes) {
+ if (sizes[0] < size)
+ return -EINVAL;
+ size = sizes[0];
+ }
+
+ *nplanes = 1;
+ sizes[0] = size;
+
+ ctx_dbg(3, ctx, "nbuffers=%d, size=%d\n", *nbuffers, sizes[0]);
+
+ return 0;
+}
+
+static int cal_buffer_prepare(struct vb2_buffer *vb)
+{
+ struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct cal_buffer *buf = container_of(vb, struct cal_buffer,
+ vb.vb2_buf);
+ unsigned long size;
+
+ size = ctx->v_fmt.fmt.pix.sizeimage;
+ if (vb2_plane_size(vb, 0) < size) {
+ ctx_err(ctx,
+ "data will not fit into plane (%lu < %lu)\n",
+ vb2_plane_size(vb, 0), size);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
+ return 0;
+}
+
+static void cal_buffer_queue(struct vb2_buffer *vb)
+{
+ struct cal_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct cal_buffer *buf = container_of(vb, struct cal_buffer,
+ vb.vb2_buf);
+ unsigned long flags;
+
+ /* recheck locking */
+ spin_lock_irqsave(&ctx->dma.lock, flags);
+ list_add_tail(&buf->list, &ctx->dma.queue);
+ spin_unlock_irqrestore(&ctx->dma.lock, flags);
+}
+
+static void cal_release_buffers(struct cal_ctx *ctx,
+ enum vb2_buffer_state state)
+{
+ struct cal_buffer *buf, *tmp;
+
+ /* Release all queued buffers. */
+ spin_lock_irq(&ctx->dma.lock);
+
+ list_for_each_entry_safe(buf, tmp, &ctx->dma.queue, list) {
+ list_del(&buf->list);
+ vb2_buffer_done(&buf->vb.vb2_buf, state);
+ }
+
+ if (ctx->dma.pending) {
+ vb2_buffer_done(&ctx->dma.pending->vb.vb2_buf, state);
+ ctx->dma.pending = NULL;
+ }
+
+ if (ctx->dma.active) {
+ vb2_buffer_done(&ctx->dma.active->vb.vb2_buf, state);
+ ctx->dma.active = NULL;
+ }
+
+ spin_unlock_irq(&ctx->dma.lock);
+}
+
+/* ------------------------------------------------------------------
+ * videobuf2 Operations
+ * ------------------------------------------------------------------
+ */
+
+static int cal_video_check_format(struct cal_ctx *ctx)
+{
+ const struct v4l2_mbus_framefmt *format;
+ struct media_pad *remote_pad;
+
+ remote_pad = media_entity_remote_pad(&ctx->pad);
+ if (!remote_pad)
+ return -ENODEV;
+
+ format = &ctx->phy->formats[remote_pad->index];
+
+ if (ctx->fmtinfo->code != format->code ||
+ ctx->v_fmt.fmt.pix.height != format->height ||
+ ctx->v_fmt.fmt.pix.width != format->width ||
+ ctx->v_fmt.fmt.pix.field != format->field)
+ return -EPIPE;
+
+ return 0;
+}
+
+static int cal_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+ struct cal_ctx *ctx = vb2_get_drv_priv(vq);
+ struct cal_buffer *buf;
+ dma_addr_t addr;
+ int ret;
+
+ ret = media_pipeline_start(&ctx->vdev.entity, &ctx->phy->pipe);
+ if (ret < 0) {
+ ctx_err(ctx, "Failed to start media pipeline: %d\n", ret);
+ goto error_release_buffers;
+ }
+
+ /*
+ * Verify that the currently configured format matches the output of
+ * the connected CAMERARX.
+ */
+ ret = cal_video_check_format(ctx);
+ if (ret < 0) {
+ ctx_dbg(3, ctx,
+ "Format mismatch between CAMERARX and video node\n");
+ goto error_pipeline;
+ }
+
+ ret = cal_ctx_prepare(ctx);
+ if (ret) {
+ ctx_err(ctx, "Failed to prepare context: %d\n", ret);
+ goto error_pipeline;
+ }
+
+ spin_lock_irq(&ctx->dma.lock);
+ buf = list_first_entry(&ctx->dma.queue, struct cal_buffer, list);
+ ctx->dma.active = buf;
+ list_del(&buf->list);
+ spin_unlock_irq(&ctx->dma.lock);
+
+ addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+
+ ret = pm_runtime_resume_and_get(ctx->cal->dev);
+ if (ret < 0)
+ goto error_pipeline;
+
+ cal_ctx_set_dma_addr(ctx, addr);
+ cal_ctx_start(ctx);
+
+ ret = v4l2_subdev_call(&ctx->phy->subdev, video, s_stream, 1);
+ if (ret)
+ goto error_stop;
+
+ if (cal_debug >= 4)
+ cal_quickdump_regs(ctx->cal);
+
+ return 0;
+
+error_stop:
+ cal_ctx_stop(ctx);
+ pm_runtime_put_sync(ctx->cal->dev);
+ cal_ctx_unprepare(ctx);
+
+error_pipeline:
+ media_pipeline_stop(&ctx->vdev.entity);
+error_release_buffers:
+ cal_release_buffers(ctx, VB2_BUF_STATE_QUEUED);
+
+ return ret;
+}
+
+static void cal_stop_streaming(struct vb2_queue *vq)
+{
+ struct cal_ctx *ctx = vb2_get_drv_priv(vq);
+
+ cal_ctx_stop(ctx);
+
+ v4l2_subdev_call(&ctx->phy->subdev, video, s_stream, 0);
+
+ pm_runtime_put_sync(ctx->cal->dev);
+
+ cal_ctx_unprepare(ctx);
+
+ cal_release_buffers(ctx, VB2_BUF_STATE_ERROR);
+
+ media_pipeline_stop(&ctx->vdev.entity);
+}
+
+static const struct vb2_ops cal_video_qops = {
+ .queue_setup = cal_queue_setup,
+ .buf_prepare = cal_buffer_prepare,
+ .buf_queue = cal_buffer_queue,
+ .start_streaming = cal_start_streaming,
+ .stop_streaming = cal_stop_streaming,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+};
+
+/* ------------------------------------------------------------------
+ * V4L2 Initialization and Registration
+ * ------------------------------------------------------------------
+ */
+
+static const struct v4l2_file_operations cal_fops = {
+ .owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .poll = vb2_fop_poll,
+ .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+ .mmap = vb2_fop_mmap,
+};
+
+static int cal_ctx_v4l2_init_formats(struct cal_ctx *ctx)
+{
+ struct v4l2_subdev_mbus_code_enum mbus_code;
+ struct v4l2_mbus_framefmt mbus_fmt;
+ const struct cal_format_info *fmtinfo;
+ unsigned int i, j, k;
+ int ret = 0;
+
+ /* Enumerate sub device formats and enable all matching local formats */
+ ctx->active_fmt = devm_kcalloc(ctx->cal->dev, cal_num_formats,
+ sizeof(*ctx->active_fmt), GFP_KERNEL);
+ if (!ctx->active_fmt)
+ return -ENOMEM;
+
+ ctx->num_active_fmt = 0;
+
+ for (j = 0, i = 0; ; ++j) {
+
+ memset(&mbus_code, 0, sizeof(mbus_code));
+ mbus_code.index = j;
+ mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(ctx->phy->source, pad, enum_mbus_code,
+ NULL, &mbus_code);
+ if (ret == -EINVAL)
+ break;
+
+ if (ret) {
+ ctx_err(ctx, "Error enumerating mbus codes in subdev %s: %d\n",
+ ctx->phy->source->name, ret);
+ return ret;
+ }
+
+ ctx_dbg(2, ctx,
+ "subdev %s: code: %04x idx: %u\n",
+ ctx->phy->source->name, mbus_code.code, j);
+
+ for (k = 0; k < cal_num_formats; k++) {
+ fmtinfo = &cal_formats[k];
+
+ if (mbus_code.code == fmtinfo->code) {
+ ctx->active_fmt[i] = fmtinfo;
+ ctx_dbg(2, ctx,
+ "matched fourcc: %s: code: %04x idx: %u\n",
+ fourcc_to_str(fmtinfo->fourcc),
+ fmtinfo->code, i);
+ ctx->num_active_fmt = ++i;
+ }
+ }
+ }
+
+ if (i == 0) {
+ ctx_err(ctx, "No suitable format reported by subdev %s\n",
+ ctx->phy->source->name);
+ return -EINVAL;
+ }
+
+ ret = __subdev_get_format(ctx, &mbus_fmt);
+ if (ret)
+ return ret;
+
+ fmtinfo = find_format_by_code(ctx, mbus_fmt.code);
+ if (!fmtinfo) {
+ ctx_dbg(3, ctx, "mbus code format (0x%08x) not found.\n",
+ mbus_fmt.code);
+ return -EINVAL;
+ }
+
+ /* Save current format */
+ v4l2_fill_pix_format(&ctx->v_fmt.fmt.pix, &mbus_fmt);
+ ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ ctx->v_fmt.fmt.pix.pixelformat = fmtinfo->fourcc;
+ cal_calc_format_size(ctx, fmtinfo, &ctx->v_fmt);
+ ctx->fmtinfo = fmtinfo;
+
+ return 0;
+}
+
+static int cal_ctx_v4l2_init_mc_format(struct cal_ctx *ctx)
+{
+ const struct cal_format_info *fmtinfo;
+ struct v4l2_pix_format *pix_fmt = &ctx->v_fmt.fmt.pix;
+
+ fmtinfo = cal_format_by_code(MEDIA_BUS_FMT_UYVY8_2X8);
+ if (!fmtinfo)
+ return -EINVAL;
+
+ pix_fmt->width = 640;
+ pix_fmt->height = 480;
+ pix_fmt->field = V4L2_FIELD_NONE;
+ pix_fmt->colorspace = V4L2_COLORSPACE_SRGB;
+ pix_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
+ pix_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+ pix_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
+ pix_fmt->pixelformat = fmtinfo->fourcc;
+
+ ctx->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ /* Save current format */
+ cal_calc_format_size(ctx, fmtinfo, &ctx->v_fmt);
+ ctx->fmtinfo = fmtinfo;
+
+ return 0;
+}
+
+int cal_ctx_v4l2_register(struct cal_ctx *ctx)
+{
+ struct video_device *vfd = &ctx->vdev;
+ int ret;
+
+ if (!cal_mc_api) {
+ struct v4l2_ctrl_handler *hdl = &ctx->ctrl_handler;
+
+ ret = cal_ctx_v4l2_init_formats(ctx);
+ if (ret) {
+ ctx_err(ctx, "Failed to init formats: %d\n", ret);
+ return ret;
+ }
+
+ ret = v4l2_ctrl_add_handler(hdl, ctx->phy->source->ctrl_handler,
+ NULL, true);
+ if (ret < 0) {
+ ctx_err(ctx, "Failed to add source ctrl handler\n");
+ return ret;
+ }
+ } else {
+ ret = cal_ctx_v4l2_init_mc_format(ctx);
+ if (ret) {
+ ctx_err(ctx, "Failed to init format: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = video_register_device(vfd, VFL_TYPE_VIDEO, cal_video_nr);
+ if (ret < 0) {
+ ctx_err(ctx, "Failed to register video device\n");
+ return ret;
+ }
+
+ ret = media_create_pad_link(&ctx->phy->subdev.entity,
+ CAL_CAMERARX_PAD_FIRST_SOURCE,
+ &vfd->entity, 0,
+ MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret) {
+ ctx_err(ctx, "Failed to create media link for context %u\n",
+ ctx->dma_ctx);
+ video_unregister_device(vfd);
+ return ret;
+ }
+
+ ctx_info(ctx, "V4L2 device registered as %s\n",
+ video_device_node_name(vfd));
+
+ return 0;
+}
+
+void cal_ctx_v4l2_unregister(struct cal_ctx *ctx)
+{
+ ctx_dbg(1, ctx, "unregistering %s\n",
+ video_device_node_name(&ctx->vdev));
+
+ video_unregister_device(&ctx->vdev);
+}
+
+int cal_ctx_v4l2_init(struct cal_ctx *ctx)
+{
+ struct video_device *vfd = &ctx->vdev;
+ struct vb2_queue *q = &ctx->vb_vidq;
+ int ret;
+
+ INIT_LIST_HEAD(&ctx->dma.queue);
+ spin_lock_init(&ctx->dma.lock);
+ mutex_init(&ctx->mutex);
+ init_waitqueue_head(&ctx->dma.wait);
+
+ /* Initialize the vb2 queue. */
+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ q->io_modes = VB2_MMAP | VB2_DMABUF;
+ q->drv_priv = ctx;
+ q->buf_struct_size = sizeof(struct cal_buffer);
+ q->ops = &cal_video_qops;
+ q->mem_ops = &vb2_dma_contig_memops;
+ q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ q->lock = &ctx->mutex;
+ q->min_buffers_needed = 3;
+ q->dev = ctx->cal->dev;
+
+ ret = vb2_queue_init(q);
+ if (ret)
+ return ret;
+
+ /* Initialize the video device and media entity. */
+ vfd->fops = &cal_fops;
+ vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING
+ | (cal_mc_api ? V4L2_CAP_IO_MC : 0);
+ vfd->v4l2_dev = &ctx->cal->v4l2_dev;
+ vfd->queue = q;
+ snprintf(vfd->name, sizeof(vfd->name), "CAL output %u", ctx->dma_ctx);
+ vfd->release = video_device_release_empty;
+ vfd->ioctl_ops = cal_mc_api ? &cal_ioctl_mc_ops : &cal_ioctl_legacy_ops;
+ vfd->lock = &ctx->mutex;
+ video_set_drvdata(vfd, ctx);
+
+ ctx->pad.flags = MEDIA_PAD_FL_SINK;
+ ret = media_entity_pads_init(&vfd->entity, 1, &ctx->pad);
+ if (ret < 0)
+ return ret;
+
+ if (!cal_mc_api) {
+ /* Initialize the control handler. */
+ struct v4l2_ctrl_handler *hdl = &ctx->ctrl_handler;
+
+ ret = v4l2_ctrl_handler_init(hdl, 11);
+ if (ret < 0) {
+ ctx_err(ctx, "Failed to init ctrl handler\n");
+ goto error;
+ }
+
+ vfd->ctrl_handler = hdl;
+ }
+
+ return 0;
+
+error:
+ media_entity_cleanup(&vfd->entity);
+ return ret;
+}
+
+void cal_ctx_v4l2_cleanup(struct cal_ctx *ctx)
+{
+ if (!cal_mc_api)
+ v4l2_ctrl_handler_free(&ctx->ctrl_handler);
+
+ media_entity_cleanup(&ctx->vdev.entity);
+}
diff --git a/drivers/media/platform/ti/cal/cal.c b/drivers/media/platform/ti/cal/cal.c
new file mode 100644
index 000000000000..4a4a6c5983f7
--- /dev/null
+++ b/drivers/media/platform/ti/cal/cal.c
@@ -0,0 +1,1263 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI Camera Access Layer (CAL) - Driver
+ *
+ * Copyright (c) 2015-2020 Texas Instruments Inc.
+ *
+ * Authors:
+ * Benoit Parrot
+ * Laurent Pinchart
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "cal.h"
+#include "cal_regs.h"
+
+MODULE_DESCRIPTION("TI CAL driver");
+MODULE_AUTHOR("Benoit Parrot, ");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1.0");
+
+int cal_video_nr = -1;
+module_param_named(video_nr, cal_video_nr, uint, 0644);
+MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
+
+unsigned int cal_debug;
+module_param_named(debug, cal_debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+#ifdef CONFIG_VIDEO_TI_CAL_MC
+#define CAL_MC_API_DEFAULT 1
+#else
+#define CAL_MC_API_DEFAULT 0
+#endif
+
+bool cal_mc_api = CAL_MC_API_DEFAULT;
+module_param_named(mc_api, cal_mc_api, bool, 0444);
+MODULE_PARM_DESC(mc_api, "activates the MC API");
+
+/* ------------------------------------------------------------------
+ * Format Handling
+ * ------------------------------------------------------------------
+ */
+
+const struct cal_format_info cal_formats[] = {
+ {
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .bpp = 16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .code = MEDIA_BUS_FMT_UYVY8_2X8,
+ .bpp = 16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_YVYU,
+ .code = MEDIA_BUS_FMT_YVYU8_2X8,
+ .bpp = 16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_VYUY,
+ .code = MEDIA_BUS_FMT_VYUY8_2X8,
+ .bpp = 16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+ .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
+ .bpp = 16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
+ .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
+ .bpp = 16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
+ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+ .bpp = 16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
+ .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
+ .bpp = 16,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
+ .code = MEDIA_BUS_FMT_RGB888_2X12_LE,
+ .bpp = 24,
+ }, {
+ .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
+ .code = MEDIA_BUS_FMT_RGB888_2X12_BE,
+ .bpp = 24,
+ }, {
+ .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
+ .code = MEDIA_BUS_FMT_ARGB8888_1X32,
+ .bpp = 32,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .code = MEDIA_BUS_FMT_SBGGR8_1X8,
+ .bpp = 8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGBRG8,
+ .code = MEDIA_BUS_FMT_SGBRG8_1X8,
+ .bpp = 8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGRBG8,
+ .code = MEDIA_BUS_FMT_SGRBG8_1X8,
+ .bpp = 8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SRGGB8,
+ .code = MEDIA_BUS_FMT_SRGGB8_1X8,
+ .bpp = 8,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SBGGR10,
+ .code = MEDIA_BUS_FMT_SBGGR10_1X10,
+ .bpp = 10,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGBRG10,
+ .code = MEDIA_BUS_FMT_SGBRG10_1X10,
+ .bpp = 10,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGRBG10,
+ .code = MEDIA_BUS_FMT_SGRBG10_1X10,
+ .bpp = 10,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SRGGB10,
+ .code = MEDIA_BUS_FMT_SRGGB10_1X10,
+ .bpp = 10,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SBGGR12,
+ .code = MEDIA_BUS_FMT_SBGGR12_1X12,
+ .bpp = 12,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGBRG12,
+ .code = MEDIA_BUS_FMT_SGBRG12_1X12,
+ .bpp = 12,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SGRBG12,
+ .code = MEDIA_BUS_FMT_SGRBG12_1X12,
+ .bpp = 12,
+ }, {
+ .fourcc = V4L2_PIX_FMT_SRGGB12,
+ .code = MEDIA_BUS_FMT_SRGGB12_1X12,
+ .bpp = 12,
+ },
+};
+
+const unsigned int cal_num_formats = ARRAY_SIZE(cal_formats);
+
+const struct cal_format_info *cal_format_by_fourcc(u32 fourcc)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(cal_formats); ++i) {
+ if (cal_formats[i].fourcc == fourcc)
+ return &cal_formats[i];
+ }
+
+ return NULL;
+}
+
+const struct cal_format_info *cal_format_by_code(u32 code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(cal_formats); ++i) {
+ if (cal_formats[i].code == code)
+ return &cal_formats[i];
+ }
+
+ return NULL;
+}
+
+/* ------------------------------------------------------------------
+ * Platform Data
+ * ------------------------------------------------------------------
+ */
+
+static const struct cal_camerarx_data dra72x_cal_camerarx[] = {
+ {
+ .fields = {
+ [F_CTRLCLKEN] = { 10, 10 },
+ [F_CAMMODE] = { 11, 12 },
+ [F_LANEENABLE] = { 13, 16 },
+ [F_CSI_MODE] = { 17, 17 },
+ },
+ .num_lanes = 4,
+ },
+ {
+ .fields = {
+ [F_CTRLCLKEN] = { 0, 0 },
+ [F_CAMMODE] = { 1, 2 },
+ [F_LANEENABLE] = { 3, 4 },
+ [F_CSI_MODE] = { 5, 5 },
+ },
+ .num_lanes = 2,
+ },
+};
+
+static const struct cal_data dra72x_cal_data = {
+ .camerarx = dra72x_cal_camerarx,
+ .num_csi2_phy = ARRAY_SIZE(dra72x_cal_camerarx),
+};
+
+static const struct cal_data dra72x_es1_cal_data = {
+ .camerarx = dra72x_cal_camerarx,
+ .num_csi2_phy = ARRAY_SIZE(dra72x_cal_camerarx),
+ .flags = DRA72_CAL_PRE_ES2_LDO_DISABLE,
+};
+
+static const struct cal_camerarx_data dra76x_cal_csi_phy[] = {
+ {
+ .fields = {
+ [F_CTRLCLKEN] = { 8, 8 },
+ [F_CAMMODE] = { 9, 10 },
+ [F_CSI_MODE] = { 11, 11 },
+ [F_LANEENABLE] = { 27, 31 },
+ },
+ .num_lanes = 5,
+ },
+ {
+ .fields = {
+ [F_CTRLCLKEN] = { 0, 0 },
+ [F_CAMMODE] = { 1, 2 },
+ [F_CSI_MODE] = { 3, 3 },
+ [F_LANEENABLE] = { 24, 26 },
+ },
+ .num_lanes = 3,
+ },
+};
+
+static const struct cal_data dra76x_cal_data = {
+ .camerarx = dra76x_cal_csi_phy,
+ .num_csi2_phy = ARRAY_SIZE(dra76x_cal_csi_phy),
+};
+
+static const struct cal_camerarx_data am654_cal_csi_phy[] = {
+ {
+ .fields = {
+ [F_CTRLCLKEN] = { 15, 15 },
+ [F_CAMMODE] = { 24, 25 },
+ [F_LANEENABLE] = { 0, 4 },
+ },
+ .num_lanes = 5,
+ },
+};
+
+static const struct cal_data am654_cal_data = {
+ .camerarx = am654_cal_csi_phy,
+ .num_csi2_phy = ARRAY_SIZE(am654_cal_csi_phy),
+};
+
+/* ------------------------------------------------------------------
+ * I/O Register Accessors
+ * ------------------------------------------------------------------
+ */
+
+void cal_quickdump_regs(struct cal_dev *cal)
+{
+ unsigned int i;
+
+ cal_info(cal, "CAL Registers @ 0x%pa:\n", &cal->res->start);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
+ (__force const void *)cal->base,
+ resource_size(cal->res), false);
+
+ for (i = 0; i < cal->data->num_csi2_phy; ++i) {
+ struct cal_camerarx *phy = cal->phy[i];
+
+ cal_info(cal, "CSI2 Core %u Registers @ %pa:\n", i,
+ &phy->res->start);
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
+ (__force const void *)phy->base,
+ resource_size(phy->res),
+ false);
+ }
+}
+
+/* ------------------------------------------------------------------
+ * Context Management
+ * ------------------------------------------------------------------
+ */
+
+#define CAL_MAX_PIX_PROC 4
+
+static int cal_reserve_pix_proc(struct cal_dev *cal)
+{
+ unsigned long ret;
+
+ spin_lock(&cal->v4l2_dev.lock);
+
+ ret = find_first_zero_bit(&cal->reserved_pix_proc_mask, CAL_MAX_PIX_PROC);
+
+ if (ret == CAL_MAX_PIX_PROC) {
+ spin_unlock(&cal->v4l2_dev.lock);
+ return -ENOSPC;
+ }
+
+ cal->reserved_pix_proc_mask |= BIT(ret);
+
+ spin_unlock(&cal->v4l2_dev.lock);
+
+ return ret;
+}
+
+static void cal_release_pix_proc(struct cal_dev *cal, unsigned int pix_proc_num)
+{
+ spin_lock(&cal->v4l2_dev.lock);
+
+ cal->reserved_pix_proc_mask &= ~BIT(pix_proc_num);
+
+ spin_unlock(&cal->v4l2_dev.lock);
+}
+
+static void cal_ctx_csi2_config(struct cal_ctx *ctx)
+{
+ u32 val;
+
+ val = cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx));
+ cal_set_field(&val, ctx->cport, CAL_CSI2_CTX_CPORT_MASK);
+ /*
+ * DT type: MIPI CSI-2 Specs
+ * 0x1: All - DT filter is disabled
+ * 0x24: RGB888 1 pixel = 3 bytes
+ * 0x2B: RAW10 4 pixels = 5 bytes
+ * 0x2A: RAW8 1 pixel = 1 byte
+ * 0x1E: YUV422 2 pixels = 4 bytes
+ */
+ cal_set_field(&val, ctx->datatype, CAL_CSI2_CTX_DT_MASK);
+ cal_set_field(&val, ctx->vc, CAL_CSI2_CTX_VC_MASK);
+ cal_set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK);
+ cal_set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK);
+ cal_set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE,
+ CAL_CSI2_CTX_PACK_MODE_MASK);
+ cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), val);
+ ctx_dbg(3, ctx, "CAL_CSI2_CTX(%u, %u) = 0x%08x\n",
+ ctx->phy->instance, ctx->csi2_ctx,
+ cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx)));
+}
+
+static void cal_ctx_pix_proc_config(struct cal_ctx *ctx)
+{
+ u32 val, extract, pack;
+
+ switch (ctx->fmtinfo->bpp) {
+ case 8:
+ extract = CAL_PIX_PROC_EXTRACT_B8;
+ pack = CAL_PIX_PROC_PACK_B8;
+ break;
+ case 10:
+ extract = CAL_PIX_PROC_EXTRACT_B10_MIPI;
+ pack = CAL_PIX_PROC_PACK_B16;
+ break;
+ case 12:
+ extract = CAL_PIX_PROC_EXTRACT_B12_MIPI;
+ pack = CAL_PIX_PROC_PACK_B16;
+ break;
+ case 16:
+ extract = CAL_PIX_PROC_EXTRACT_B16_LE;
+ pack = CAL_PIX_PROC_PACK_B16;
+ break;
+ default:
+ /*
+ * If you see this warning then it means that you added
+ * some new entry in the cal_formats[] array with a different
+ * bit per pixel values then the one supported below.
+ * Either add support for the new bpp value below or adjust
+ * the new entry to use one of the value below.
+ *
+ * Instead of failing here just use 8 bpp as a default.
+ */
+ dev_warn_once(ctx->cal->dev,
+ "%s:%d:%s: bpp:%d unsupported! Overwritten with 8.\n",
+ __FILE__, __LINE__, __func__, ctx->fmtinfo->bpp);
+ extract = CAL_PIX_PROC_EXTRACT_B8;
+ pack = CAL_PIX_PROC_PACK_B8;
+ break;
+ }
+
+ val = cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc));
+ cal_set_field(&val, extract, CAL_PIX_PROC_EXTRACT_MASK);
+ cal_set_field(&val, CAL_PIX_PROC_DPCMD_BYPASS, CAL_PIX_PROC_DPCMD_MASK);
+ cal_set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK);
+ cal_set_field(&val, pack, CAL_PIX_PROC_PACK_MASK);
+ cal_set_field(&val, ctx->cport, CAL_PIX_PROC_CPORT_MASK);
+ cal_set_field(&val, 1, CAL_PIX_PROC_EN_MASK);
+ cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), val);
+ ctx_dbg(3, ctx, "CAL_PIX_PROC(%u) = 0x%08x\n", ctx->pix_proc,
+ cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc)));
+}
+
+static void cal_ctx_wr_dma_config(struct cal_ctx *ctx)
+{
+ unsigned int stride = ctx->v_fmt.fmt.pix.bytesperline;
+ u32 val;
+
+ val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
+ cal_set_field(&val, ctx->cport, CAL_WR_DMA_CTRL_CPORT_MASK);
+ cal_set_field(&val, ctx->v_fmt.fmt.pix.height,
+ CAL_WR_DMA_CTRL_YSIZE_MASK);
+ cal_set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT,
+ CAL_WR_DMA_CTRL_DTAG_MASK);
+ cal_set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR,
+ CAL_WR_DMA_CTRL_PATTERN_MASK);
+ cal_set_field(&val, 1, CAL_WR_DMA_CTRL_STALL_RD_MASK);
+ cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
+ ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->dma_ctx,
+ cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx)));
+
+ cal_write_field(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx),
+ stride / 16, CAL_WR_DMA_OFST_MASK);
+ ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->dma_ctx,
+ cal_read(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx)));
+
+ val = cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx));
+ /* 64 bit word means no skipping */
+ cal_set_field(&val, 0, CAL_WR_DMA_XSIZE_XSKIP_MASK);
+ /*
+ * The XSIZE field is expressed in 64-bit units and prevents overflows
+ * in case of synchronization issues by limiting the number of bytes
+ * written per line.
+ */
+ cal_set_field(&val, stride / 8, CAL_WR_DMA_XSIZE_MASK);
+ cal_write(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx), val);
+ ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->dma_ctx,
+ cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx)));
+}
+
+void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr)
+{
+ cal_write(ctx->cal, CAL_WR_DMA_ADDR(ctx->dma_ctx), addr);
+}
+
+static void cal_ctx_wr_dma_enable(struct cal_ctx *ctx)
+{
+ u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
+
+ cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST,
+ CAL_WR_DMA_CTRL_MODE_MASK);
+ cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
+}
+
+static void cal_ctx_wr_dma_disable(struct cal_ctx *ctx)
+{
+ u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx));
+
+ cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_DIS,
+ CAL_WR_DMA_CTRL_MODE_MASK);
+ cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val);
+}
+
+static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx)
+{
+ bool stopped;
+
+ spin_lock_irq(&ctx->dma.lock);
+ stopped = ctx->dma.state == CAL_DMA_STOPPED;
+ spin_unlock_irq(&ctx->dma.lock);
+
+ return stopped;
+}
+
+int cal_ctx_prepare(struct cal_ctx *ctx)
+{
+ int ret;
+
+ ctx->use_pix_proc = !ctx->fmtinfo->meta;
+
+ if (ctx->use_pix_proc) {
+ ret = cal_reserve_pix_proc(ctx->cal);
+ if (ret < 0) {
+ ctx_err(ctx, "Failed to reserve pix proc: %d\n", ret);
+ return ret;
+ }
+
+ ctx->pix_proc = ret;
+ }
+
+ return 0;
+}
+
+void cal_ctx_unprepare(struct cal_ctx *ctx)
+{
+ if (ctx->use_pix_proc)
+ cal_release_pix_proc(ctx->cal, ctx->pix_proc);
+}
+
+void cal_ctx_start(struct cal_ctx *ctx)
+{
+ ctx->sequence = 0;
+ ctx->dma.state = CAL_DMA_RUNNING;
+
+ /* Configure the CSI-2, pixel processing and write DMA contexts. */
+ cal_ctx_csi2_config(ctx);
+ if (ctx->use_pix_proc)
+ cal_ctx_pix_proc_config(ctx);
+ cal_ctx_wr_dma_config(ctx);
+
+ /* Enable IRQ_WDMA_END and IRQ_WDMA_START. */
+ cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(1),
+ CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx));
+ cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(2),
+ CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx));
+
+ cal_ctx_wr_dma_enable(ctx);
+}
+
+void cal_ctx_stop(struct cal_ctx *ctx)
+{
+ long timeout;
+
+ /*
+ * Request DMA stop and wait until it completes. If completion times
+ * out, forcefully disable the DMA.
+ */
+ spin_lock_irq(&ctx->dma.lock);
+ ctx->dma.state = CAL_DMA_STOP_REQUESTED;
+ spin_unlock_irq(&ctx->dma.lock);
+
+ timeout = wait_event_timeout(ctx->dma.wait, cal_ctx_wr_dma_stopped(ctx),
+ msecs_to_jiffies(500));
+ if (!timeout) {
+ ctx_err(ctx, "failed to disable dma cleanly\n");
+ cal_ctx_wr_dma_disable(ctx);
+ }
+
+ /* Disable IRQ_WDMA_END and IRQ_WDMA_START. */
+ cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(1),
+ CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx));
+ cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(2),
+ CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx));
+
+ ctx->dma.state = CAL_DMA_STOPPED;
+
+ /* Disable CSI2 context */
+ cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), 0);
+
+ /* Disable pix proc */
+ if (ctx->use_pix_proc)
+ cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), 0);
+}
+
+/* ------------------------------------------------------------------
+ * IRQ Handling
+ * ------------------------------------------------------------------
+ */
+
+static inline void cal_irq_wdma_start(struct cal_ctx *ctx)
+{
+ spin_lock(&ctx->dma.lock);
+
+ if (ctx->dma.state == CAL_DMA_STOP_REQUESTED) {
+ /*
+ * If a stop is requested, disable the write DMA context
+ * immediately. The CAL_WR_DMA_CTRL_j.MODE field is shadowed,
+ * the current frame will complete and the DMA will then stop.
+ */
+ cal_ctx_wr_dma_disable(ctx);
+ ctx->dma.state = CAL_DMA_STOP_PENDING;
+ } else if (!list_empty(&ctx->dma.queue) && !ctx->dma.pending) {
+ /*
+ * Otherwise, if a new buffer is available, queue it to the
+ * hardware.
+ */
+ struct cal_buffer *buf;
+ dma_addr_t addr;
+
+ buf = list_first_entry(&ctx->dma.queue, struct cal_buffer,
+ list);
+ addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+ cal_ctx_set_dma_addr(ctx, addr);
+
+ ctx->dma.pending = buf;
+ list_del(&buf->list);
+ }
+
+ spin_unlock(&ctx->dma.lock);
+}
+
+static inline void cal_irq_wdma_end(struct cal_ctx *ctx)
+{
+ struct cal_buffer *buf = NULL;
+
+ spin_lock(&ctx->dma.lock);
+
+ /* If the DMA context was stopping, it is now stopped. */
+ if (ctx->dma.state == CAL_DMA_STOP_PENDING) {
+ ctx->dma.state = CAL_DMA_STOPPED;
+ wake_up(&ctx->dma.wait);
+ }
+
+ /* If a new buffer was queued, complete the current buffer. */
+ if (ctx->dma.pending) {
+ buf = ctx->dma.active;
+ ctx->dma.active = ctx->dma.pending;
+ ctx->dma.pending = NULL;
+ }
+
+ spin_unlock(&ctx->dma.lock);
+
+ if (buf) {
+ buf->vb.vb2_buf.timestamp = ktime_get_ns();
+ buf->vb.field = ctx->v_fmt.fmt.pix.field;
+ buf->vb.sequence = ctx->sequence++;
+ vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+ }
+}
+
+static irqreturn_t cal_irq(int irq_cal, void *data)
+{
+ struct cal_dev *cal = data;
+ u32 status;
+
+ status = cal_read(cal, CAL_HL_IRQSTATUS(0));
+ if (status) {
+ unsigned int i;
+
+ cal_write(cal, CAL_HL_IRQSTATUS(0), status);
+
+ if (status & CAL_HL_IRQ_OCPO_ERR_MASK)
+ dev_err_ratelimited(cal->dev, "OCPO ERROR\n");
+
+ for (i = 0; i < cal->data->num_csi2_phy; ++i) {
+ if (status & CAL_HL_IRQ_CIO_MASK(i)) {
+ u32 cio_stat = cal_read(cal,
+ CAL_CSI2_COMPLEXIO_IRQSTATUS(i));
+
+ dev_err_ratelimited(cal->dev,
+ "CIO%u error: %#08x\n", i, cio_stat);
+
+ cal_write(cal, CAL_CSI2_COMPLEXIO_IRQSTATUS(i),
+ cio_stat);
+ }
+
+ if (status & CAL_HL_IRQ_VC_MASK(i)) {
+ u32 vc_stat = cal_read(cal, CAL_CSI2_VC_IRQSTATUS(i));
+
+ dev_err_ratelimited(cal->dev,
+ "CIO%u VC error: %#08x\n",
+ i, vc_stat);
+
+ cal_write(cal, CAL_CSI2_VC_IRQSTATUS(i), vc_stat);
+ }
+ }
+ }
+
+ /* Check which DMA just finished */
+ status = cal_read(cal, CAL_HL_IRQSTATUS(1));
+ if (status) {
+ unsigned int i;
+
+ /* Clear Interrupt status */
+ cal_write(cal, CAL_HL_IRQSTATUS(1), status);
+
+ for (i = 0; i < cal->num_contexts; ++i) {
+ if (status & CAL_HL_IRQ_WDMA_END_MASK(i))
+ cal_irq_wdma_end(cal->ctx[i]);
+ }
+ }
+
+ /* Check which DMA just started */
+ status = cal_read(cal, CAL_HL_IRQSTATUS(2));
+ if (status) {
+ unsigned int i;
+
+ /* Clear Interrupt status */
+ cal_write(cal, CAL_HL_IRQSTATUS(2), status);
+
+ for (i = 0; i < cal->num_contexts; ++i) {
+ if (status & CAL_HL_IRQ_WDMA_START_MASK(i))
+ cal_irq_wdma_start(cal->ctx[i]);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* ------------------------------------------------------------------
+ * Asynchronous V4L2 subdev binding
+ * ------------------------------------------------------------------
+ */
+
+struct cal_v4l2_async_subdev {
+ struct v4l2_async_subdev asd; /* Must be first */
+ struct cal_camerarx *phy;
+};
+
+static inline struct cal_v4l2_async_subdev *
+to_cal_asd(struct v4l2_async_subdev *asd)
+{
+ return container_of(asd, struct cal_v4l2_async_subdev, asd);
+}
+
+static int cal_async_notifier_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_subdev *asd)
+{
+ struct cal_camerarx *phy = to_cal_asd(asd)->phy;
+ int pad;
+ int ret;
+
+ if (phy->source) {
+ phy_info(phy, "Rejecting subdev %s (Already set!!)",
+ subdev->name);
+ return 0;
+ }
+
+ phy->source = subdev;
+ phy_dbg(1, phy, "Using source %s for capture\n", subdev->name);
+
+ pad = media_entity_get_fwnode_pad(&subdev->entity,
+ of_fwnode_handle(phy->source_ep_node),
+ MEDIA_PAD_FL_SOURCE);
+ if (pad < 0) {
+ phy_err(phy, "Source %s has no connected source pad\n",
+ subdev->name);
+ return pad;
+ }
+
+ ret = media_create_pad_link(&subdev->entity, pad,
+ &phy->subdev.entity, CAL_CAMERARX_PAD_SINK,
+ MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret) {
+ phy_err(phy, "Failed to create media link for source %s\n",
+ subdev->name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cal_async_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+ struct cal_dev *cal = container_of(notifier, struct cal_dev, notifier);
+ unsigned int i;
+ int ret;
+
+ for (i = 0; i < cal->num_contexts; ++i) {
+ ret = cal_ctx_v4l2_register(cal->ctx[i]);
+ if (ret)
+ goto err_ctx_unreg;
+ }
+
+ if (!cal_mc_api)
+ return 0;
+
+ ret = v4l2_device_register_subdev_nodes(&cal->v4l2_dev);
+ if (ret)
+ goto err_ctx_unreg;
+
+ return 0;
+
+err_ctx_unreg:
+ for (; i > 0; --i) {
+ if (!cal->ctx[i - 1])
+ continue;
+
+ cal_ctx_v4l2_unregister(cal->ctx[i - 1]);
+ }
+
+ return ret;
+}
+
+static const struct v4l2_async_notifier_operations cal_async_notifier_ops = {
+ .bound = cal_async_notifier_bound,
+ .complete = cal_async_notifier_complete,
+};
+
+static int cal_async_notifier_register(struct cal_dev *cal)
+{
+ unsigned int i;
+ int ret;
+
+ v4l2_async_nf_init(&cal->notifier);
+ cal->notifier.ops = &cal_async_notifier_ops;
+
+ for (i = 0; i < cal->data->num_csi2_phy; ++i) {
+ struct cal_camerarx *phy = cal->phy[i];
+ struct cal_v4l2_async_subdev *casd;
+ struct fwnode_handle *fwnode;
+
+ if (!phy->source_node)
+ continue;
+
+ fwnode = of_fwnode_handle(phy->source_node);
+ casd = v4l2_async_nf_add_fwnode(&cal->notifier,
+ fwnode,
+ struct cal_v4l2_async_subdev);
+ if (IS_ERR(casd)) {
+ phy_err(phy, "Failed to add subdev to notifier\n");
+ ret = PTR_ERR(casd);
+ goto error;
+ }
+
+ casd->phy = phy;
+ }
+
+ ret = v4l2_async_nf_register(&cal->v4l2_dev, &cal->notifier);
+ if (ret) {
+ cal_err(cal, "Error registering async notifier\n");
+ goto error;
+ }
+
+ return 0;
+
+error:
+ v4l2_async_nf_cleanup(&cal->notifier);
+ return ret;
+}
+
+static void cal_async_notifier_unregister(struct cal_dev *cal)
+{
+ v4l2_async_nf_unregister(&cal->notifier);
+ v4l2_async_nf_cleanup(&cal->notifier);
+}
+
+/* ------------------------------------------------------------------
+ * Media and V4L2 device handling
+ * ------------------------------------------------------------------
+ */
+
+/*
+ * Register user-facing devices. To be called at the end of the probe function
+ * when all resources are initialized and ready.
+ */
+static int cal_media_register(struct cal_dev *cal)
+{
+ int ret;
+
+ ret = media_device_register(&cal->mdev);
+ if (ret) {
+ cal_err(cal, "Failed to register media device\n");
+ return ret;
+ }
+
+ /*
+ * Register the async notifier. This may trigger registration of the
+ * V4L2 video devices if all subdevs are ready.
+ */
+ ret = cal_async_notifier_register(cal);
+ if (ret) {
+ media_device_unregister(&cal->mdev);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Unregister the user-facing devices, but don't free memory yet. To be called
+ * at the beginning of the remove function, to disallow access from userspace.
+ */
+static void cal_media_unregister(struct cal_dev *cal)
+{
+ unsigned int i;
+
+ /* Unregister all the V4L2 video devices. */
+ for (i = 0; i < cal->num_contexts; i++)
+ cal_ctx_v4l2_unregister(cal->ctx[i]);
+
+ cal_async_notifier_unregister(cal);
+ media_device_unregister(&cal->mdev);
+}
+
+/*
+ * Initialize the in-kernel objects. To be called at the beginning of the probe
+ * function, before the V4L2 device is used by the driver.
+ */
+static int cal_media_init(struct cal_dev *cal)
+{
+ struct media_device *mdev = &cal->mdev;
+ int ret;
+
+ mdev->dev = cal->dev;
+ mdev->hw_revision = cal->revision;
+ strscpy(mdev->model, "CAL", sizeof(mdev->model));
+ snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
+ dev_name(mdev->dev));
+ media_device_init(mdev);
+
+ /*
+ * Initialize the V4L2 device (despite the function name, this performs
+ * initialization, not registration).
+ */
+ cal->v4l2_dev.mdev = mdev;
+ ret = v4l2_device_register(cal->dev, &cal->v4l2_dev);
+ if (ret) {
+ cal_err(cal, "Failed to register V4L2 device\n");
+ return ret;
+ }
+
+ vb2_dma_contig_set_max_seg_size(cal->dev, DMA_BIT_MASK(32));
+
+ return 0;
+}
+
+/*
+ * Cleanup the in-kernel objects, freeing memory. To be called at the very end
+ * of the remove sequence, when nothing (including userspace) can access the
+ * objects anymore.
+ */
+static void cal_media_cleanup(struct cal_dev *cal)
+{
+ v4l2_device_unregister(&cal->v4l2_dev);
+ media_device_cleanup(&cal->mdev);
+
+ vb2_dma_contig_clear_max_seg_size(cal->dev);
+}
+
+/* ------------------------------------------------------------------
+ * Initialization and module stuff
+ * ------------------------------------------------------------------
+ */
+
+static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst)
+{
+ struct cal_ctx *ctx;
+ int ret;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return NULL;
+
+ ctx->cal = cal;
+ ctx->phy = cal->phy[inst];
+ ctx->dma_ctx = inst;
+ ctx->csi2_ctx = inst;
+ ctx->cport = inst;
+ ctx->vc = 0;
+ ctx->datatype = CAL_CSI2_CTX_DT_ANY;
+
+ ret = cal_ctx_v4l2_init(ctx);
+ if (ret)
+ return NULL;
+
+ return ctx;
+}
+
+static void cal_ctx_destroy(struct cal_ctx *ctx)
+{
+ cal_ctx_v4l2_cleanup(ctx);
+
+ kfree(ctx);
+}
+
+static const struct of_device_id cal_of_match[] = {
+ {
+ .compatible = "ti,dra72-cal",
+ .data = (void *)&dra72x_cal_data,
+ },
+ {
+ .compatible = "ti,dra72-pre-es2-cal",
+ .data = (void *)&dra72x_es1_cal_data,
+ },
+ {
+ .compatible = "ti,dra76-cal",
+ .data = (void *)&dra76x_cal_data,
+ },
+ {
+ .compatible = "ti,am654-cal",
+ .data = (void *)&am654_cal_data,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, cal_of_match);
+
+/* Get hardware revision and info. */
+
+#define CAL_HL_HWINFO_VALUE 0xa3c90469
+
+static void cal_get_hwinfo(struct cal_dev *cal)
+{
+ u32 hwinfo;
+
+ cal->revision = cal_read(cal, CAL_HL_REVISION);
+ switch (FIELD_GET(CAL_HL_REVISION_SCHEME_MASK, cal->revision)) {
+ case CAL_HL_REVISION_SCHEME_H08:
+ cal_dbg(3, cal, "CAL HW revision %lu.%lu.%lu (0x%08x)\n",
+ FIELD_GET(CAL_HL_REVISION_MAJOR_MASK, cal->revision),
+ FIELD_GET(CAL_HL_REVISION_MINOR_MASK, cal->revision),
+ FIELD_GET(CAL_HL_REVISION_RTL_MASK, cal->revision),
+ cal->revision);
+ break;
+
+ case CAL_HL_REVISION_SCHEME_LEGACY:
+ default:
+ cal_info(cal, "Unexpected CAL HW revision 0x%08x\n",
+ cal->revision);
+ break;
+ }
+
+ hwinfo = cal_read(cal, CAL_HL_HWINFO);
+ if (hwinfo != CAL_HL_HWINFO_VALUE)
+ cal_info(cal, "CAL_HL_HWINFO = 0x%08x, expected 0x%08x\n",
+ hwinfo, CAL_HL_HWINFO_VALUE);
+}
+
+static int cal_init_camerarx_regmap(struct cal_dev *cal)
+{
+ struct platform_device *pdev = to_platform_device(cal->dev);
+ struct device_node *np = cal->dev->of_node;
+ struct regmap_config config = { };
+ struct regmap *syscon;
+ struct resource *res;
+ unsigned int offset;
+ void __iomem *base;
+
+ syscon = syscon_regmap_lookup_by_phandle_args(np, "ti,camerrx-control",
+ 1, &offset);
+ if (!IS_ERR(syscon)) {
+ cal->syscon_camerrx = syscon;
+ cal->syscon_camerrx_offset = offset;
+ return 0;
+ }
+
+ dev_warn(cal->dev, "failed to get ti,camerrx-control: %ld\n",
+ PTR_ERR(syscon));
+
+ /*
+ * Backward DTS compatibility. If syscon entry is not present then
+ * check if the camerrx_control resource is present.
+ */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "camerrx_control");
+ base = devm_ioremap_resource(cal->dev, res);
+ if (IS_ERR(base)) {
+ cal_err(cal, "failed to ioremap camerrx_control\n");
+ return PTR_ERR(base);
+ }
+
+ cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
+ res->name, &res->start, &res->end);
+
+ config.reg_bits = 32;
+ config.reg_stride = 4;
+ config.val_bits = 32;
+ config.max_register = resource_size(res) - 4;
+
+ syscon = regmap_init_mmio(NULL, base, &config);
+ if (IS_ERR(syscon)) {
+ pr_err("regmap init failed\n");
+ return PTR_ERR(syscon);
+ }
+
+ /*
+ * In this case the base already point to the direct CM register so no
+ * need for an offset.
+ */
+ cal->syscon_camerrx = syscon;
+ cal->syscon_camerrx_offset = 0;
+
+ return 0;
+}
+
+static int cal_probe(struct platform_device *pdev)
+{
+ struct cal_dev *cal;
+ bool connected = false;
+ unsigned int i;
+ int ret;
+ int irq;
+
+ cal = devm_kzalloc(&pdev->dev, sizeof(*cal), GFP_KERNEL);
+ if (!cal)
+ return -ENOMEM;
+
+ cal->data = of_device_get_match_data(&pdev->dev);
+ if (!cal->data) {
+ dev_err(&pdev->dev, "Could not get feature data based on compatible version\n");
+ return -ENODEV;
+ }
+
+ cal->dev = &pdev->dev;
+ platform_set_drvdata(pdev, cal);
+
+ /* Acquire resources: clocks, CAMERARX regmap, I/O memory and IRQ. */
+ cal->fclk = devm_clk_get(&pdev->dev, "fck");
+ if (IS_ERR(cal->fclk)) {
+ dev_err(&pdev->dev, "cannot get CAL fclk\n");
+ return PTR_ERR(cal->fclk);
+ }
+
+ ret = cal_init_camerarx_regmap(cal);
+ if (ret < 0)
+ return ret;
+
+ cal->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "cal_top");
+ cal->base = devm_ioremap_resource(&pdev->dev, cal->res);
+ if (IS_ERR(cal->base))
+ return PTR_ERR(cal->base);
+
+ cal_dbg(1, cal, "ioresource %s at %pa - %pa\n",
+ cal->res->name, &cal->res->start, &cal->res->end);
+
+ irq = platform_get_irq(pdev, 0);
+ cal_dbg(1, cal, "got irq# %d\n", irq);
+ ret = devm_request_irq(&pdev->dev, irq, cal_irq, 0, CAL_MODULE_NAME,
+ cal);
+ if (ret)
+ return ret;
+
+ /* Read the revision and hardware info to verify hardware access. */
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret)
+ goto error_pm_runtime;
+
+ cal_get_hwinfo(cal);
+ pm_runtime_put_sync(&pdev->dev);
+
+ /* Initialize the media device. */
+ ret = cal_media_init(cal);
+ if (ret < 0)
+ goto error_pm_runtime;
+
+ /* Create CAMERARX PHYs. */
+ for (i = 0; i < cal->data->num_csi2_phy; ++i) {
+ cal->phy[i] = cal_camerarx_create(cal, i);
+ if (IS_ERR(cal->phy[i])) {
+ ret = PTR_ERR(cal->phy[i]);
+ cal->phy[i] = NULL;
+ goto error_camerarx;
+ }
+
+ if (cal->phy[i]->source_node)
+ connected = true;
+ }
+
+ if (!connected) {
+ cal_err(cal, "Neither port is configured, no point in staying up\n");
+ ret = -ENODEV;
+ goto error_camerarx;
+ }
+
+ /* Create contexts. */
+ for (i = 0; i < cal->data->num_csi2_phy; ++i) {
+ if (!cal->phy[i]->source_node)
+ continue;
+
+ cal->ctx[cal->num_contexts] = cal_ctx_create(cal, i);
+ if (!cal->ctx[cal->num_contexts]) {
+ cal_err(cal, "Failed to create context %u\n", cal->num_contexts);
+ ret = -ENODEV;
+ goto error_context;
+ }
+
+ cal->num_contexts++;
+ }
+
+ /* Register the media device. */
+ ret = cal_media_register(cal);
+ if (ret)
+ goto error_context;
+
+ return 0;
+
+error_context:
+ for (i = 0; i < cal->num_contexts; i++)
+ cal_ctx_destroy(cal->ctx[i]);
+
+error_camerarx:
+ for (i = 0; i < cal->data->num_csi2_phy; i++)
+ cal_camerarx_destroy(cal->phy[i]);
+
+ cal_media_cleanup(cal);
+
+error_pm_runtime:
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static int cal_remove(struct platform_device *pdev)
+{
+ struct cal_dev *cal = platform_get_drvdata(pdev);
+ unsigned int i;
+ int ret;
+
+ cal_dbg(1, cal, "Removing %s\n", CAL_MODULE_NAME);
+
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+
+ cal_media_unregister(cal);
+
+ for (i = 0; i < cal->data->num_csi2_phy; i++)
+ cal_camerarx_disable(cal->phy[i]);
+
+ for (i = 0; i < cal->num_contexts; i++)
+ cal_ctx_destroy(cal->ctx[i]);
+
+ for (i = 0; i < cal->data->num_csi2_phy; i++)
+ cal_camerarx_destroy(cal->phy[i]);
+
+ cal_media_cleanup(cal);
+
+ if (ret >= 0)
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static int cal_runtime_resume(struct device *dev)
+{
+ struct cal_dev *cal = dev_get_drvdata(dev);
+ unsigned int i;
+ u32 val;
+
+ if (cal->data->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) {
+ /*
+ * Apply errata on both port everytime we (re-)enable
+ * the clock
+ */
+ for (i = 0; i < cal->data->num_csi2_phy; i++)
+ cal_camerarx_i913_errata(cal->phy[i]);
+ }
+
+ /*
+ * Enable global interrupts that are not related to a particular
+ * CAMERARAX or context.
+ */
+ cal_write(cal, CAL_HL_IRQENABLE_SET(0), CAL_HL_IRQ_OCPO_ERR_MASK);
+
+ val = cal_read(cal, CAL_CTRL);
+ cal_set_field(&val, CAL_CTRL_BURSTSIZE_BURST128,
+ CAL_CTRL_BURSTSIZE_MASK);
+ cal_set_field(&val, 0xf, CAL_CTRL_TAGCNT_MASK);
+ cal_set_field(&val, CAL_CTRL_POSTED_WRITES_NONPOSTED,
+ CAL_CTRL_POSTED_WRITES_MASK);
+ cal_set_field(&val, 0xff, CAL_CTRL_MFLAGL_MASK);
+ cal_set_field(&val, 0xff, CAL_CTRL_MFLAGH_MASK);
+ cal_write(cal, CAL_CTRL, val);
+ cal_dbg(3, cal, "CAL_CTRL = 0x%08x\n", cal_read(cal, CAL_CTRL));
+
+ return 0;
+}
+
+static const struct dev_pm_ops cal_pm_ops = {
+ .runtime_resume = cal_runtime_resume,
+};
+
+static struct platform_driver cal_pdrv = {
+ .probe = cal_probe,
+ .remove = cal_remove,
+ .driver = {
+ .name = CAL_MODULE_NAME,
+ .pm = &cal_pm_ops,
+ .of_match_table = cal_of_match,
+ },
+};
+
+module_platform_driver(cal_pdrv);
diff --git a/drivers/media/platform/ti/cal/cal.h b/drivers/media/platform/ti/cal/cal.h
new file mode 100644
index 000000000000..527e22d022f3
--- /dev/null
+++ b/drivers/media/platform/ti/cal/cal.h
@@ -0,0 +1,343 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * TI Camera Access Layer (CAL)
+ *
+ * Copyright (c) 2015-2020 Texas Instruments Inc.
+ *
+ * Authors:
+ * Benoit Parrot
+ * Laurent Pinchart
+ */
+#ifndef __TI_CAL_H__
+#define __TI_CAL_H__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define CAL_MODULE_NAME "cal"
+#define CAL_MAX_NUM_CONTEXT 8
+#define CAL_NUM_CSI2_PORTS 2
+
+/*
+ * The width is limited by the size of the CAL_WR_DMA_XSIZE_j.XSIZE field,
+ * expressed in multiples of 64 bits. The height is limited by the size of the
+ * CAL_CSI2_CTXi_j.CTXi_LINES and CAL_WR_DMA_CTRL_j.YSIZE fields, expressed in
+ * lines.
+ */
+#define CAL_MIN_WIDTH_BYTES 16
+#define CAL_MAX_WIDTH_BYTES (8192 * 8)
+#define CAL_MIN_HEIGHT_LINES 1
+#define CAL_MAX_HEIGHT_LINES 16383
+
+#define CAL_CAMERARX_PAD_SINK 0
+#define CAL_CAMERARX_PAD_FIRST_SOURCE 1
+#define CAL_CAMERARX_NUM_SOURCE_PADS 1
+#define CAL_CAMERARX_NUM_PADS (1 + CAL_CAMERARX_NUM_SOURCE_PADS)
+
+static inline bool cal_rx_pad_is_sink(u32 pad)
+{
+ /* Camera RX has 1 sink pad, and N source pads */
+ return pad == 0;
+}
+
+static inline bool cal_rx_pad_is_source(u32 pad)
+{
+ /* Camera RX has 1 sink pad, and N source pads */
+ return pad >= CAL_CAMERARX_PAD_FIRST_SOURCE &&
+ pad <= CAL_CAMERARX_NUM_SOURCE_PADS;
+}
+
+struct device;
+struct device_node;
+struct resource;
+struct regmap;
+struct regmap_fied;
+
+/* CTRL_CORE_CAMERRX_CONTROL register field id */
+enum cal_camerarx_field {
+ F_CTRLCLKEN,
+ F_CAMMODE,
+ F_LANEENABLE,
+ F_CSI_MODE,
+ F_MAX_FIELDS,
+};
+
+enum cal_dma_state {
+ CAL_DMA_RUNNING,
+ CAL_DMA_STOP_REQUESTED,
+ CAL_DMA_STOP_PENDING,
+ CAL_DMA_STOPPED,
+};
+
+struct cal_format_info {
+ u32 fourcc;
+ u32 code;
+ /* Bits per pixel */
+ u8 bpp;
+ bool meta;
+};
+
+/* buffer for one video frame */
+struct cal_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct vb2_v4l2_buffer vb;
+ struct list_head list;
+};
+
+/**
+ * struct cal_dmaqueue - Queue of DMA buffers
+ */
+struct cal_dmaqueue {
+ /**
+ * @lock: Protects all fields in the cal_dmaqueue.
+ */
+ spinlock_t lock;
+
+ /**
+ * @queue: Buffers queued to the driver and waiting for DMA processing.
+ * Buffers are added to the list by the vb2 .buffer_queue() operation,
+ * and move to @pending when they are scheduled for the next frame.
+ */
+ struct list_head queue;
+ /**
+ * @pending: Buffer provided to the hardware to DMA the next frame.
+ * Will move to @active at the end of the current frame.
+ */
+ struct cal_buffer *pending;
+ /**
+ * @active: Buffer being DMA'ed to for the current frame. Will be
+ * retired and given back to vb2 at the end of the current frame if
+ * a @pending buffer has been scheduled to replace it.
+ */
+ struct cal_buffer *active;
+
+ /** @state: State of the DMA engine. */
+ enum cal_dma_state state;
+ /** @wait: Wait queue to signal a @state transition to CAL_DMA_STOPPED. */
+ struct wait_queue_head wait;
+};
+
+struct cal_camerarx_data {
+ struct {
+ unsigned int lsb;
+ unsigned int msb;
+ } fields[F_MAX_FIELDS];
+ unsigned int num_lanes;
+};
+
+struct cal_data {
+ const struct cal_camerarx_data *camerarx;
+ unsigned int num_csi2_phy;
+ unsigned int flags;
+};
+
+/*
+ * The Camera Adaptation Layer (CAL) module is paired with one or more complex
+ * I/O PHYs (CAMERARX). It contains multiple instances of CSI-2, processing and
+ * DMA contexts.
+ *
+ * The cal_dev structure represents the whole subsystem, including the CAL and
+ * the CAMERARX instances. Instances of struct cal_dev are named cal through the
+ * driver.
+ *
+ * The cal_camerarx structure represents one CAMERARX instance. Instances of
+ * cal_camerarx are named phy through the driver.
+ *
+ * The cal_ctx structure represents the combination of one CSI-2 context, one
+ * processing context and one DMA context. Instance of struct cal_ctx are named
+ * ctx through the driver.
+ */
+
+struct cal_camerarx {
+ void __iomem *base;
+ struct resource *res;
+ struct regmap_field *fields[F_MAX_FIELDS];
+
+ struct cal_dev *cal;
+ unsigned int instance;
+
+ struct v4l2_fwnode_endpoint endpoint;
+ struct device_node *source_ep_node;
+ struct device_node *source_node;
+ struct v4l2_subdev *source;
+ struct media_pipeline pipe;
+
+ struct v4l2_subdev subdev;
+ struct media_pad pads[CAL_CAMERARX_NUM_PADS];
+ struct v4l2_mbus_framefmt formats[CAL_CAMERARX_NUM_PADS];
+
+ /*
+ * Lock for camerarx ops. Protects:
+ * - formats
+ * - enable_count
+ */
+ struct mutex mutex;
+
+ unsigned int enable_count;
+};
+
+struct cal_dev {
+ struct clk *fclk;
+ int irq;
+ void __iomem *base;
+ struct resource *res;
+ struct device *dev;
+
+ const struct cal_data *data;
+ u32 revision;
+
+ /* Control Module handle */
+ struct regmap *syscon_camerrx;
+ u32 syscon_camerrx_offset;
+
+ /* Camera Core Module handle */
+ struct cal_camerarx *phy[CAL_NUM_CSI2_PORTS];
+
+ u32 num_contexts;
+ struct cal_ctx *ctx[CAL_MAX_NUM_CONTEXT];
+
+ struct media_device mdev;
+ struct v4l2_device v4l2_dev;
+ struct v4l2_async_notifier notifier;
+
+ unsigned long reserved_pix_proc_mask;
+};
+
+/*
+ * There is one cal_ctx structure for each camera core context.
+ */
+struct cal_ctx {
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct video_device vdev;
+ struct media_pad pad;
+
+ struct cal_dev *cal;
+ struct cal_camerarx *phy;
+
+ /* v4l2_ioctl mutex */
+ struct mutex mutex;
+
+ struct cal_dmaqueue dma;
+
+ /* video capture */
+ const struct cal_format_info *fmtinfo;
+ /* Used to store current pixel format */
+ struct v4l2_format v_fmt;
+
+ /* Current subdev enumerated format (legacy) */
+ const struct cal_format_info **active_fmt;
+ unsigned int num_active_fmt;
+
+ unsigned int sequence;
+ struct vb2_queue vb_vidq;
+ u8 dma_ctx;
+ u8 cport;
+ u8 csi2_ctx;
+ u8 pix_proc;
+ u8 vc;
+ u8 datatype;
+
+ bool use_pix_proc;
+};
+
+extern unsigned int cal_debug;
+extern int cal_video_nr;
+extern bool cal_mc_api;
+
+#define cal_dbg(level, cal, fmt, arg...) \
+ do { \
+ if (cal_debug >= (level)) \
+ dev_printk(KERN_DEBUG, (cal)->dev, fmt, ##arg); \
+ } while (0)
+#define cal_info(cal, fmt, arg...) \
+ dev_info((cal)->dev, fmt, ##arg)
+#define cal_err(cal, fmt, arg...) \
+ dev_err((cal)->dev, fmt, ##arg)
+
+#define ctx_dbg(level, ctx, fmt, arg...) \
+ cal_dbg(level, (ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
+#define ctx_info(ctx, fmt, arg...) \
+ cal_info((ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
+#define ctx_err(ctx, fmt, arg...) \
+ cal_err((ctx)->cal, "ctx%u: " fmt, (ctx)->dma_ctx, ##arg)
+
+#define phy_dbg(level, phy, fmt, arg...) \
+ cal_dbg(level, (phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
+#define phy_info(phy, fmt, arg...) \
+ cal_info((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
+#define phy_err(phy, fmt, arg...) \
+ cal_err((phy)->cal, "phy%u: " fmt, (phy)->instance, ##arg)
+
+static inline u32 cal_read(struct cal_dev *cal, u32 offset)
+{
+ return ioread32(cal->base + offset);
+}
+
+static inline void cal_write(struct cal_dev *cal, u32 offset, u32 val)
+{
+ iowrite32(val, cal->base + offset);
+}
+
+static __always_inline u32 cal_read_field(struct cal_dev *cal, u32 offset, u32 mask)
+{
+ return FIELD_GET(mask, cal_read(cal, offset));
+}
+
+static inline void cal_write_field(struct cal_dev *cal, u32 offset, u32 value,
+ u32 mask)
+{
+ u32 val = cal_read(cal, offset);
+
+ val &= ~mask;
+ val |= (value << __ffs(mask)) & mask;
+ cal_write(cal, offset, val);
+}
+
+static inline void cal_set_field(u32 *valp, u32 field, u32 mask)
+{
+ u32 val = *valp;
+
+ val &= ~mask;
+ val |= (field << __ffs(mask)) & mask;
+ *valp = val;
+}
+
+extern const struct cal_format_info cal_formats[];
+extern const unsigned int cal_num_formats;
+const struct cal_format_info *cal_format_by_fourcc(u32 fourcc);
+const struct cal_format_info *cal_format_by_code(u32 code);
+
+void cal_quickdump_regs(struct cal_dev *cal);
+
+void cal_camerarx_disable(struct cal_camerarx *phy);
+void cal_camerarx_i913_errata(struct cal_camerarx *phy);
+struct cal_camerarx *cal_camerarx_create(struct cal_dev *cal,
+ unsigned int instance);
+void cal_camerarx_destroy(struct cal_camerarx *phy);
+
+int cal_ctx_prepare(struct cal_ctx *ctx);
+void cal_ctx_unprepare(struct cal_ctx *ctx);
+void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr);
+void cal_ctx_start(struct cal_ctx *ctx);
+void cal_ctx_stop(struct cal_ctx *ctx);
+
+int cal_ctx_v4l2_register(struct cal_ctx *ctx);
+void cal_ctx_v4l2_unregister(struct cal_ctx *ctx);
+int cal_ctx_v4l2_init(struct cal_ctx *ctx);
+void cal_ctx_v4l2_cleanup(struct cal_ctx *ctx);
+
+#endif /* __TI_CAL_H__ */
diff --git a/drivers/media/platform/ti/cal/cal_regs.h b/drivers/media/platform/ti/cal/cal_regs.h
new file mode 100644
index 000000000000..40e4f972fcb7
--- /dev/null
+++ b/drivers/media/platform/ti/cal/cal_regs.h
@@ -0,0 +1,463 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * TI CAL camera interface driver
+ *
+ * Copyright (c) 2015 Texas Instruments Inc.
+ *
+ * Benoit Parrot,
+ */
+
+#ifndef __TI_CAL_REGS_H
+#define __TI_CAL_REGS_H
+
+/*
+ * struct cal_dev.flags possibilities
+ *
+ * DRA72_CAL_PRE_ES2_LDO_DISABLE:
+ * Errata i913: CSI2 LDO Needs to be disabled when module is powered on
+ *
+ * Enabling CSI2 LDO shorts it to core supply. It is crucial the 2 CSI2
+ * LDOs on the device are disabled if CSI-2 module is powered on
+ * (0x4845 B304 | 0x4845 B384 [28:27] = 0x1) or in ULPS (0x4845 B304
+ * | 0x4845 B384 [28:27] = 0x2) mode. Common concerns include: high
+ * current draw on the module supply in active mode.
+ *
+ * Errata does not apply when CSI-2 module is powered off
+ * (0x4845 B304 | 0x4845 B384 [28:27] = 0x0).
+ *
+ * SW Workaround:
+ * Set the following register bits to disable the LDO,
+ * which is essentially CSI2 REG10 bit 6:
+ *
+ * Core 0: 0x4845 B828 = 0x0000 0040
+ * Core 1: 0x4845 B928 = 0x0000 0040
+ */
+#define DRA72_CAL_PRE_ES2_LDO_DISABLE BIT(0)
+
+/* CAL register offsets */
+
+#define CAL_HL_REVISION 0x0000
+#define CAL_HL_HWINFO 0x0004
+#define CAL_HL_SYSCONFIG 0x0010
+#define CAL_HL_IRQ_EOI 0x001c
+#define CAL_HL_IRQSTATUS_RAW(m) (0x20U + (m) * 0x10U)
+#define CAL_HL_IRQSTATUS(m) (0x24U + (m) * 0x10U)
+#define CAL_HL_IRQENABLE_SET(m) (0x28U + (m) * 0x10U)
+#define CAL_HL_IRQENABLE_CLR(m) (0x2cU + (m) * 0x10U)
+#define CAL_PIX_PROC(m) (0xc0U + (m) * 0x4U)
+#define CAL_CTRL 0x100
+#define CAL_CTRL1 0x104
+#define CAL_LINE_NUMBER_EVT 0x108
+#define CAL_VPORT_CTRL1 0x120
+#define CAL_VPORT_CTRL2 0x124
+#define CAL_BYS_CTRL1 0x130
+#define CAL_BYS_CTRL2 0x134
+#define CAL_RD_DMA_CTRL 0x140
+#define CAL_RD_DMA_PIX_ADDR 0x144
+#define CAL_RD_DMA_PIX_OFST 0x148
+#define CAL_RD_DMA_XSIZE 0x14c
+#define CAL_RD_DMA_YSIZE 0x150
+#define CAL_RD_DMA_INIT_ADDR 0x154
+#define CAL_RD_DMA_INIT_OFST 0x168
+#define CAL_RD_DMA_CTRL2 0x16c
+#define CAL_WR_DMA_CTRL(m) (0x200U + (m) * 0x10U)
+#define CAL_WR_DMA_ADDR(m) (0x204U + (m) * 0x10U)
+#define CAL_WR_DMA_OFST(m) (0x208U + (m) * 0x10U)
+#define CAL_WR_DMA_XSIZE(m) (0x20cU + (m) * 0x10U)
+#define CAL_CSI2_PPI_CTRL(m) (0x300U + (m) * 0x80U)
+#define CAL_CSI2_COMPLEXIO_CFG(m) (0x304U + (m) * 0x80U)
+#define CAL_CSI2_COMPLEXIO_IRQSTATUS(m) (0x308U + (m) * 0x80U)
+#define CAL_CSI2_SHORT_PACKET(m) (0x30cU + (m) * 0x80U)
+#define CAL_CSI2_COMPLEXIO_IRQENABLE(m) (0x310U + (m) * 0x80U)
+#define CAL_CSI2_TIMING(m) (0x314U + (m) * 0x80U)
+#define CAL_CSI2_VC_IRQENABLE(m) (0x318U + (m) * 0x80U)
+#define CAL_CSI2_VC_IRQSTATUS(m) (0x328U + (m) * 0x80U)
+#define CAL_CSI2_CTX(phy, csi2_ctx) (0x330U + (phy) * 0x80U + (csi2_ctx) * 4)
+#define CAL_CSI2_STATUS(phy, csi2_ctx) (0x350U + (phy) * 0x80U + (csi2_ctx) * 4)
+
+/* CAL CSI2 PHY register offsets */
+#define CAL_CSI2_PHY_REG0 0x000
+#define CAL_CSI2_PHY_REG1 0x004
+#define CAL_CSI2_PHY_REG2 0x008
+#define CAL_CSI2_PHY_REG10 0x028
+
+/* CAL Control Module Core Camerrx Control register offsets */
+#define CM_CTRL_CORE_CAMERRX_CONTROL 0x000
+
+/*********************************************************************
+* Field Definition Macros
+*********************************************************************/
+
+#define CAL_HL_REVISION_MINOR_MASK GENMASK(5, 0)
+#define CAL_HL_REVISION_CUSTOM_MASK GENMASK(7, 6)
+#define CAL_HL_REVISION_MAJOR_MASK GENMASK(10, 8)
+#define CAL_HL_REVISION_RTL_MASK GENMASK(15, 11)
+#define CAL_HL_REVISION_FUNC_MASK GENMASK(27, 16)
+#define CAL_HL_REVISION_SCHEME_MASK GENMASK(31, 30)
+#define CAL_HL_REVISION_SCHEME_H08 1
+#define CAL_HL_REVISION_SCHEME_LEGACY 0
+
+#define CAL_HL_HWINFO_WFIFO_MASK GENMASK(3, 0)
+#define CAL_HL_HWINFO_RFIFO_MASK GENMASK(7, 4)
+#define CAL_HL_HWINFO_PCTX_MASK GENMASK(12, 8)
+#define CAL_HL_HWINFO_WCTX_MASK GENMASK(18, 13)
+#define CAL_HL_HWINFO_VFIFO_MASK GENMASK(22, 19)
+#define CAL_HL_HWINFO_NCPORT_MASK GENMASK(27, 23)
+#define CAL_HL_HWINFO_NPPI_CTXS0_MASK GENMASK(29, 28)
+#define CAL_HL_HWINFO_NPPI_CTXS1_MASK GENMASK(31, 30)
+#define CAL_HL_HWINFO_NPPI_CONTEXTS_ZERO 0
+#define CAL_HL_HWINFO_NPPI_CONTEXTS_FOUR 1
+#define CAL_HL_HWINFO_NPPI_CONTEXTS_EIGHT 2
+#define CAL_HL_HWINFO_NPPI_CONTEXTS_RESERVED 3
+
+#define CAL_HL_SYSCONFIG_SOFTRESET_MASK BIT(0)
+#define CAL_HL_SYSCONFIG_SOFTRESET_DONE 0x0
+#define CAL_HL_SYSCONFIG_SOFTRESET_PENDING 0x1
+#define CAL_HL_SYSCONFIG_SOFTRESET_NOACTION 0x0
+#define CAL_HL_SYSCONFIG_SOFTRESET_RESET 0x1
+#define CAL_HL_SYSCONFIG_IDLE_MASK GENMASK(3, 2)
+#define CAL_HL_SYSCONFIG_IDLEMODE_FORCE 0
+#define CAL_HL_SYSCONFIG_IDLEMODE_NO 1
+#define CAL_HL_SYSCONFIG_IDLEMODE_SMART1 2
+#define CAL_HL_SYSCONFIG_IDLEMODE_SMART2 3
+
+#define CAL_HL_IRQ_EOI_LINE_NUMBER_MASK BIT(0)
+#define CAL_HL_IRQ_EOI_LINE_NUMBER_READ0 0
+#define CAL_HL_IRQ_EOI_LINE_NUMBER_EOI0 0
+
+#define CAL_HL_IRQ_WDMA_END_MASK(m) BIT(m)
+#define CAL_HL_IRQ_WDMA_START_MASK(m) BIT(m)
+
+#define CAL_HL_IRQ_OCPO_ERR_MASK BIT(6)
+
+#define CAL_HL_IRQ_CIO_MASK(i) BIT(16 + (i) * 8)
+#define CAL_HL_IRQ_VC_MASK(i) BIT(17 + (i) * 8)
+
+#define CAL_PIX_PROC_EN_MASK BIT(0)
+#define CAL_PIX_PROC_EXTRACT_MASK GENMASK(4, 1)
+#define CAL_PIX_PROC_EXTRACT_B6 0x0
+#define CAL_PIX_PROC_EXTRACT_B7 0x1
+#define CAL_PIX_PROC_EXTRACT_B8 0x2
+#define CAL_PIX_PROC_EXTRACT_B10 0x3
+#define CAL_PIX_PROC_EXTRACT_B10_MIPI 0x4
+#define CAL_PIX_PROC_EXTRACT_B12 0x5
+#define CAL_PIX_PROC_EXTRACT_B12_MIPI 0x6
+#define CAL_PIX_PROC_EXTRACT_B14 0x7
+#define CAL_PIX_PROC_EXTRACT_B14_MIPI 0x8
+#define CAL_PIX_PROC_EXTRACT_B16_BE 0x9
+#define CAL_PIX_PROC_EXTRACT_B16_LE 0xa
+#define CAL_PIX_PROC_DPCMD_MASK GENMASK(9, 5)
+#define CAL_PIX_PROC_DPCMD_BYPASS 0x0
+#define CAL_PIX_PROC_DPCMD_DPCM_10_8_1 0x2
+#define CAL_PIX_PROC_DPCMD_DPCM_12_8_1 0x8
+#define CAL_PIX_PROC_DPCMD_DPCM_10_7_1 0x4
+#define CAL_PIX_PROC_DPCMD_DPCM_10_7_2 0x5
+#define CAL_PIX_PROC_DPCMD_DPCM_10_6_1 0x6
+#define CAL_PIX_PROC_DPCMD_DPCM_10_6_2 0x7
+#define CAL_PIX_PROC_DPCMD_DPCM_12_7_1 0xa
+#define CAL_PIX_PROC_DPCMD_DPCM_12_6_1 0xc
+#define CAL_PIX_PROC_DPCMD_DPCM_14_10 0xe
+#define CAL_PIX_PROC_DPCMD_DPCM_14_8_1 0x10
+#define CAL_PIX_PROC_DPCMD_DPCM_16_12_1 0x12
+#define CAL_PIX_PROC_DPCMD_DPCM_16_10_1 0x14
+#define CAL_PIX_PROC_DPCMD_DPCM_16_8_1 0x16
+#define CAL_PIX_PROC_DPCME_MASK GENMASK(15, 11)
+#define CAL_PIX_PROC_DPCME_BYPASS 0x0
+#define CAL_PIX_PROC_DPCME_DPCM_10_8_1 0x2
+#define CAL_PIX_PROC_DPCME_DPCM_12_8_1 0x8
+#define CAL_PIX_PROC_DPCME_DPCM_14_10 0xe
+#define CAL_PIX_PROC_DPCME_DPCM_14_8_1 0x10
+#define CAL_PIX_PROC_DPCME_DPCM_16_12_1 0x12
+#define CAL_PIX_PROC_DPCME_DPCM_16_10_1 0x14
+#define CAL_PIX_PROC_DPCME_DPCM_16_8_1 0x16
+#define CAL_PIX_PROC_PACK_MASK GENMASK(18, 16)
+#define CAL_PIX_PROC_PACK_B8 0x0
+#define CAL_PIX_PROC_PACK_B10_MIPI 0x2
+#define CAL_PIX_PROC_PACK_B12 0x3
+#define CAL_PIX_PROC_PACK_B12_MIPI 0x4
+#define CAL_PIX_PROC_PACK_B16 0x5
+#define CAL_PIX_PROC_PACK_ARGB 0x6
+#define CAL_PIX_PROC_CPORT_MASK GENMASK(23, 19)
+
+#define CAL_CTRL_POSTED_WRITES_MASK BIT(0)
+#define CAL_CTRL_POSTED_WRITES_NONPOSTED 0
+#define CAL_CTRL_POSTED_WRITES 1
+#define CAL_CTRL_TAGCNT_MASK GENMASK(4, 1)
+#define CAL_CTRL_BURSTSIZE_MASK GENMASK(6, 5)
+#define CAL_CTRL_BURSTSIZE_BURST16 0x0
+#define CAL_CTRL_BURSTSIZE_BURST32 0x1
+#define CAL_CTRL_BURSTSIZE_BURST64 0x2
+#define CAL_CTRL_BURSTSIZE_BURST128 0x3
+#define CAL_CTRL_LL_FORCE_STATE_MASK GENMASK(12, 7)
+#define CAL_CTRL_MFLAGL_MASK GENMASK(20, 13)
+#define CAL_CTRL_PWRSCPCLK_MASK BIT(21)
+#define CAL_CTRL_PWRSCPCLK_AUTO 0
+#define CAL_CTRL_PWRSCPCLK_FORCE 1
+#define CAL_CTRL_RD_DMA_STALL_MASK BIT(22)
+#define CAL_CTRL_MFLAGH_MASK GENMASK(31, 24)
+
+#define CAL_CTRL1_PPI_GROUPING_MASK GENMASK(1, 0)
+#define CAL_CTRL1_PPI_GROUPING_DISABLED 0
+#define CAL_CTRL1_PPI_GROUPING_RESERVED 1
+#define CAL_CTRL1_PPI_GROUPING_0 2
+#define CAL_CTRL1_PPI_GROUPING_1 3
+#define CAL_CTRL1_INTERLEAVE01_MASK GENMASK(3, 2)
+#define CAL_CTRL1_INTERLEAVE01_DISABLED 0
+#define CAL_CTRL1_INTERLEAVE01_PIX1 1
+#define CAL_CTRL1_INTERLEAVE01_PIX4 2
+#define CAL_CTRL1_INTERLEAVE01_RESERVED 3
+#define CAL_CTRL1_INTERLEAVE23_MASK GENMASK(5, 4)
+#define CAL_CTRL1_INTERLEAVE23_DISABLED 0
+#define CAL_CTRL1_INTERLEAVE23_PIX1 1
+#define CAL_CTRL1_INTERLEAVE23_PIX4 2
+#define CAL_CTRL1_INTERLEAVE23_RESERVED 3
+
+#define CAL_LINE_NUMBER_EVT_CPORT_MASK GENMASK(4, 0)
+#define CAL_LINE_NUMBER_EVT_MASK GENMASK(29, 16)
+
+#define CAL_VPORT_CTRL1_PCLK_MASK GENMASK(16, 0)
+#define CAL_VPORT_CTRL1_XBLK_MASK GENMASK(24, 17)
+#define CAL_VPORT_CTRL1_YBLK_MASK GENMASK(30, 25)
+#define CAL_VPORT_CTRL1_WIDTH_MASK BIT(31)
+#define CAL_VPORT_CTRL1_WIDTH_ONE 0
+#define CAL_VPORT_CTRL1_WIDTH_TWO 1
+
+#define CAL_VPORT_CTRL2_CPORT_MASK GENMASK(4, 0)
+#define CAL_VPORT_CTRL2_FREERUNNING_MASK BIT(15)
+#define CAL_VPORT_CTRL2_FREERUNNING_GATED 0
+#define CAL_VPORT_CTRL2_FREERUNNING_FREE 1
+#define CAL_VPORT_CTRL2_FS_RESETS_MASK BIT(16)
+#define CAL_VPORT_CTRL2_FS_RESETS_NO 0
+#define CAL_VPORT_CTRL2_FS_RESETS_YES 1
+#define CAL_VPORT_CTRL2_FSM_RESET_MASK BIT(17)
+#define CAL_VPORT_CTRL2_FSM_RESET_NOEFFECT 0
+#define CAL_VPORT_CTRL2_FSM_RESET 1
+#define CAL_VPORT_CTRL2_RDY_THR_MASK GENMASK(31, 18)
+
+#define CAL_BYS_CTRL1_PCLK_MASK GENMASK(16, 0)
+#define CAL_BYS_CTRL1_XBLK_MASK GENMASK(24, 17)
+#define CAL_BYS_CTRL1_YBLK_MASK GENMASK(30, 25)
+#define CAL_BYS_CTRL1_BYSINEN_MASK BIT(31)
+
+#define CAL_BYS_CTRL2_CPORTIN_MASK GENMASK(4, 0)
+#define CAL_BYS_CTRL2_CPORTOUT_MASK GENMASK(9, 5)
+#define CAL_BYS_CTRL2_DUPLICATEDDATA_MASK BIT(10)
+#define CAL_BYS_CTRL2_DUPLICATEDDATA_NO 0
+#define CAL_BYS_CTRL2_DUPLICATEDDATA_YES 1
+#define CAL_BYS_CTRL2_FREERUNNING_MASK BIT(11)
+#define CAL_BYS_CTRL2_FREERUNNING_NO 0
+#define CAL_BYS_CTRL2_FREERUNNING_YES 1
+
+#define CAL_RD_DMA_CTRL_GO_MASK BIT(0)
+#define CAL_RD_DMA_CTRL_GO_DIS 0
+#define CAL_RD_DMA_CTRL_GO_EN 1
+#define CAL_RD_DMA_CTRL_GO_IDLE 0
+#define CAL_RD_DMA_CTRL_GO_BUSY 1
+#define CAL_RD_DMA_CTRL_INIT_MASK BIT(1)
+#define CAL_RD_DMA_CTRL_BW_LIMITER_MASK GENMASK(10, 2)
+#define CAL_RD_DMA_CTRL_OCP_TAG_CNT_MASK GENMASK(14, 11)
+#define CAL_RD_DMA_CTRL_PCLK_MASK GENMASK(31, 15)
+
+#define CAL_RD_DMA_PIX_ADDR_MASK GENMASK(31, 3)
+
+#define CAL_RD_DMA_PIX_OFST_MASK GENMASK(31, 4)
+
+#define CAL_RD_DMA_XSIZE_MASK GENMASK(31, 19)
+
+#define CAL_RD_DMA_YSIZE_MASK GENMASK(29, 16)
+
+#define CAL_RD_DMA_INIT_ADDR_MASK GENMASK(31, 3)
+
+#define CAL_RD_DMA_INIT_OFST_MASK GENMASK(31, 3)
+
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_MASK GENMASK(2, 0)
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_DIS 0
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_ONE 1
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_FOUR 2
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_SIXTEEN 3
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_SIXTYFOUR 4
+#define CAL_RD_DMA_CTRL2_CIRC_MODE_RESERVED 5
+#define CAL_RD_DMA_CTRL2_ICM_CSTART_MASK BIT(3)
+#define CAL_RD_DMA_CTRL2_PATTERN_MASK GENMASK(5, 4)
+#define CAL_RD_DMA_CTRL2_PATTERN_LINEAR 0
+#define CAL_RD_DMA_CTRL2_PATTERN_YUV420 1
+#define CAL_RD_DMA_CTRL2_PATTERN_RD2SKIP2 2
+#define CAL_RD_DMA_CTRL2_PATTERN_RD2SKIP4 3
+#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_MASK BIT(6)
+#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_FREERUNNING 0
+#define CAL_RD_DMA_CTRL2_BYSOUT_LE_WAIT_WAITFORBYSOUT 1
+#define CAL_RD_DMA_CTRL2_CIRC_SIZE_MASK GENMASK(29, 16)
+
+#define CAL_WR_DMA_CTRL_MODE_MASK GENMASK(2, 0)
+#define CAL_WR_DMA_CTRL_MODE_DIS 0
+#define CAL_WR_DMA_CTRL_MODE_SHD 1
+#define CAL_WR_DMA_CTRL_MODE_CNT 2
+#define CAL_WR_DMA_CTRL_MODE_CNT_INIT 3
+#define CAL_WR_DMA_CTRL_MODE_CONST 4
+#define CAL_WR_DMA_CTRL_MODE_RESERVED 5
+#define CAL_WR_DMA_CTRL_PATTERN_MASK GENMASK(4, 3)
+#define CAL_WR_DMA_CTRL_PATTERN_LINEAR 0
+#define CAL_WR_DMA_CTRL_PATTERN_WR2SKIP2 2
+#define CAL_WR_DMA_CTRL_PATTERN_WR2SKIP4 3
+#define CAL_WR_DMA_CTRL_PATTERN_RESERVED 1
+#define CAL_WR_DMA_CTRL_ICM_PSTART_MASK BIT(5)
+#define CAL_WR_DMA_CTRL_DTAG_MASK GENMASK(8, 6)
+#define CAL_WR_DMA_CTRL_DTAG_ATT_HDR 0
+#define CAL_WR_DMA_CTRL_DTAG_ATT_DAT 1
+#define CAL_WR_DMA_CTRL_DTAG 2
+#define CAL_WR_DMA_CTRL_DTAG_PIX_HDR 3
+#define CAL_WR_DMA_CTRL_DTAG_PIX_DAT 4
+#define CAL_WR_DMA_CTRL_DTAG_D5 5
+#define CAL_WR_DMA_CTRL_DTAG_D6 6
+#define CAL_WR_DMA_CTRL_DTAG_D7 7
+#define CAL_WR_DMA_CTRL_CPORT_MASK GENMASK(13, 9)
+#define CAL_WR_DMA_CTRL_STALL_RD_MASK BIT(14)
+#define CAL_WR_DMA_CTRL_YSIZE_MASK GENMASK(31, 18)
+
+#define CAL_WR_DMA_ADDR_MASK GENMASK(31, 4)
+
+#define CAL_WR_DMA_OFST_MASK GENMASK(18, 4)
+#define CAL_WR_DMA_OFST_CIRC_MODE_MASK GENMASK(23, 22)
+#define CAL_WR_DMA_OFST_CIRC_MODE_ONE 1
+#define CAL_WR_DMA_OFST_CIRC_MODE_FOUR 2
+#define CAL_WR_DMA_OFST_CIRC_MODE_SIXTYFOUR 3
+#define CAL_WR_DMA_OFST_CIRC_MODE_DISABLED 0
+#define CAL_WR_DMA_OFST_CIRC_SIZE_MASK GENMASK(31, 24)
+
+#define CAL_WR_DMA_XSIZE_XSKIP_MASK GENMASK(15, 3)
+#define CAL_WR_DMA_XSIZE_MASK GENMASK(31, 19)
+
+#define CAL_CSI2_PPI_CTRL_IF_EN_MASK BIT(0)
+#define CAL_CSI2_PPI_CTRL_ECC_EN_MASK BIT(2)
+#define CAL_CSI2_PPI_CTRL_FRAME_MASK BIT(3)
+#define CAL_CSI2_PPI_CTRL_FRAME_IMMEDIATE 0
+#define CAL_CSI2_PPI_CTRL_FRAME 1
+
+#define CAL_CSI2_COMPLEXIO_CFG_CLOCK_POSITION_MASK GENMASK(2, 0)
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_5 5
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_4 4
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_3 3
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_2 2
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_1 1
+#define CAL_CSI2_COMPLEXIO_CFG_POSITION_NOT_USED 0
+#define CAL_CSI2_COMPLEXIO_CFG_CLOCK_POL_MASK BIT(3)
+#define CAL_CSI2_COMPLEXIO_CFG_POL_PLUSMINUS 0
+#define CAL_CSI2_COMPLEXIO_CFG_POL_MINUSPLUS 1
+#define CAL_CSI2_COMPLEXIO_CFG_DATA1_POSITION_MASK GENMASK(6, 4)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA1_POL_MASK BIT(7)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA2_POSITION_MASK GENMASK(10, 8)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA2_POL_MASK BIT(11)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA3_POSITION_MASK GENMASK(14, 12)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA3_POL_MASK BIT(15)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA4_POSITION_MASK GENMASK(18, 16)
+#define CAL_CSI2_COMPLEXIO_CFG_DATA4_POL_MASK BIT(19)
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_AUTO_MASK BIT(24)
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_MASK GENMASK(26, 25)
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_OFF 0
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_ON 1
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_STATUS_STATE_ULP 2
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_MASK GENMASK(28, 27)
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_OFF 0
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ON 1
+#define CAL_CSI2_COMPLEXIO_CFG_PWR_CMD_STATE_ULP 2
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_MASK BIT(29)
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETCOMPLETED 1
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_DONE_RESETONGOING 0
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_MASK BIT(30)
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL 0
+#define CAL_CSI2_COMPLEXIO_CFG_RESET_CTRL_OPERATIONAL 1
+
+#define CAL_CSI2_SHORT_PACKET_MASK GENMASK(23, 0)
+
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS1_MASK BIT(0)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS2_MASK BIT(1)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS3_MASK BIT(2)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS4_MASK BIT(3)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTHS5_MASK BIT(4)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS1_MASK BIT(5)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS2_MASK BIT(6)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS3_MASK BIT(7)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS4_MASK BIT(8)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRSOTSYNCHS5_MASK BIT(9)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC1_MASK BIT(10)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC2_MASK BIT(11)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC3_MASK BIT(12)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC4_MASK BIT(13)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRESC5_MASK BIT(14)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL1_MASK BIT(15)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL2_MASK BIT(16)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL3_MASK BIT(17)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL4_MASK BIT(18)
+#define CAL_CSI2_COMPLEXIO_IRQ_ERRCONTROL5_MASK BIT(19)
+#define CAL_CSI2_COMPLEXIO_IRQ_LANE_ERRORS_MASK GENMASK(19, 0)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM1_MASK BIT(20)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM2_MASK BIT(21)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM3_MASK BIT(22)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM4_MASK BIT(23)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEULPM5_MASK BIT(24)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEALLULPMENTER_MASK BIT(25)
+#define CAL_CSI2_COMPLEXIO_IRQ_STATEALLULPMEXIT_MASK BIT(26)
+#define CAL_CSI2_COMPLEXIO_IRQ_FIFO_OVR_MASK BIT(27)
+#define CAL_CSI2_COMPLEXIO_IRQ_SHORT_PACKET_MASK BIT(28)
+#define CAL_CSI2_COMPLEXIO_IRQ_ECC_NO_CORRECTION_MASK BIT(30)
+
+#define CAL_CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK GENMASK(12, 0)
+#define CAL_CSI2_TIMING_STOP_STATE_X4_IO1_MASK BIT(13)
+#define CAL_CSI2_TIMING_STOP_STATE_X16_IO1_MASK BIT(14)
+#define CAL_CSI2_TIMING_FORCE_RX_MODE_IO1_MASK BIT(15)
+
+#define CAL_CSI2_VC_IRQ_FS_IRQ_MASK(n) BIT(0 + ((n) * 8))
+#define CAL_CSI2_VC_IRQ_FE_IRQ_MASK(n) BIT(1 + ((n) * 8))
+#define CAL_CSI2_VC_IRQ_LS_IRQ_MASK(n) BIT(2 + ((n) * 8))
+#define CAL_CSI2_VC_IRQ_LE_IRQ_MASK(n) BIT(3 + ((n) * 8))
+#define CAL_CSI2_VC_IRQ_CS_IRQ_MASK(n) BIT(4 + ((n) * 8))
+#define CAL_CSI2_VC_IRQ_ECC_CORRECTION_IRQ_MASK(n) BIT(5 + ((n) * 8))
+
+#define CAL_CSI2_CTX_DT_MASK GENMASK(5, 0)
+#define CAL_CSI2_CTX_DT_DISABLED 0
+#define CAL_CSI2_CTX_DT_ANY 1
+#define CAL_CSI2_CTX_VC_MASK GENMASK(7, 6)
+#define CAL_CSI2_CTX_CPORT_MASK GENMASK(12, 8)
+#define CAL_CSI2_CTX_ATT_MASK BIT(13)
+#define CAL_CSI2_CTX_ATT_PIX 0
+#define CAL_CSI2_CTX_ATT 1
+#define CAL_CSI2_CTX_PACK_MODE_MASK BIT(14)
+#define CAL_CSI2_CTX_PACK_MODE_LINE 0
+#define CAL_CSI2_CTX_PACK_MODE_FRAME 1
+#define CAL_CSI2_CTX_LINES_MASK GENMASK(29, 16)
+
+#define CAL_CSI2_STATUS_FRAME_MASK GENMASK(15, 0)
+
+#define CAL_CSI2_PHY_REG0_THS_SETTLE_MASK GENMASK(7, 0)
+#define CAL_CSI2_PHY_REG0_THS_TERM_MASK GENMASK(15, 8)
+#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_MASK BIT(24)
+#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_DISABLE 1
+#define CAL_CSI2_PHY_REG0_HSCLOCKCONFIG_ENABLE 0
+
+#define CAL_CSI2_PHY_REG1_TCLK_SETTLE_MASK GENMASK(7, 0)
+#define CAL_CSI2_PHY_REG1_CTRLCLK_DIV_FACTOR_MASK GENMASK(9, 8)
+#define CAL_CSI2_PHY_REG1_DPHY_HS_SYNC_PATTERN_MASK GENMASK(17, 10)
+#define CAL_CSI2_PHY_REG1_TCLK_TERM_MASK GENMASK(24, 18)
+#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_MASK BIT(25)
+#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_ERROR 1
+#define CAL_CSI2_PHY_REG1_CLOCK_MISS_DETECTOR_STATUS_SUCCESS 0
+#define CAL_CSI2_PHY_REG1_RESET_DONE_STATUS_MASK GENMASK(29, 28)
+
+#define CAL_CSI2_PHY_REG10_I933_LDO_DISABLE_MASK BIT(6)
+
+#define CAL_CSI2_PHY_REG2_CCP2_SYNC_PATTERN_MASK GENMASK(23, 0)
+#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC3_MASK GENMASK(25, 24)
+#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC2_MASK GENMASK(27, 26)
+#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC1_MASK GENMASK(29, 28)
+#define CAL_CSI2_PHY_REG2_TRIGGER_CMD_RXTRIGESC0_MASK GENMASK(31, 30)
+
+#define CM_CAMERRX_CTRL_CSI1_CTRLCLKEN_MASK BIT(0)
+#define CM_CAMERRX_CTRL_CSI1_CAMMODE_MASK GENMASK(2, 1)
+#define CM_CAMERRX_CTRL_CSI1_LANEENABLE_MASK GENMASK(4, 3)
+#define CM_CAMERRX_CTRL_CSI1_MODE_MASK BIT(5)
+#define CM_CAMERRX_CTRL_CSI0_CTRLCLKEN_MASK BIT(10)
+#define CM_CAMERRX_CTRL_CSI0_CAMMODE_MASK GENMASK(12, 11)
+#define CM_CAMERRX_CTRL_CSI0_LANEENABLE_MASK GENMASK(16, 13)
+#define CM_CAMERRX_CTRL_CSI0_MODE_MASK BIT(17)
+
+#endif
diff --git a/drivers/media/platform/ti/vpe/Makefile b/drivers/media/platform/ti/vpe/Makefile
new file mode 100644
index 000000000000..3fadfe084f87
--- /dev/null
+++ b/drivers/media/platform/ti/vpe/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe.o
+obj-$(CONFIG_VIDEO_TI_VPDMA) += ti-vpdma.o
+obj-$(CONFIG_VIDEO_TI_SC) += ti-sc.o
+obj-$(CONFIG_VIDEO_TI_CSC) += ti-csc.o
+
+ti-vpe-y := vpe.o
+ti-vpdma-y := vpdma.o
+ti-sc-y := sc.o
+ti-csc-y := csc.o
+
+ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
diff --git a/drivers/media/platform/ti/vpe/csc.c b/drivers/media/platform/ti/vpe/csc.c
new file mode 100644
index 000000000000..ff15bc589f1b
--- /dev/null
+++ b/drivers/media/platform/ti/vpe/csc.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Color space converter library
+ *
+ * Copyright (c) 2013 Texas Instruments Inc.
+ *
+ * David Griego,
+ * Dale Farnsworth,
+ * Archit Taneja,
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "csc.h"
+
+/*
+ * 12 coefficients in the order:
+ * a0, b0, c0, a1, b1, c1, a2, b2, c2, d0, d1, d2
+ */
+struct quantization {
+ u16 coeff[12];
+};
+
+struct colorspace {
+ struct quantization limited;
+ struct quantization full;
+};
+
+struct encoding_direction {
+ struct colorspace r601;
+ struct colorspace r709;
+};
+
+struct csc_coeffs {
+ struct encoding_direction y2r;
+ struct encoding_direction r2y;
+};
+
+/* default colorspace coefficients */
+static struct csc_coeffs csc_coeffs = {
+ .y2r = {
+ .r601 = {
+ .limited = {
+ { /* SDTV */
+ 0x0400, 0x0000, 0x057D, 0x0400, 0x1EA7, 0x1D35,
+ 0x0400, 0x06EF, 0x1FFE, 0x0D40, 0x0210, 0x0C88,
+ }
+ },
+ .full = {
+ { /* SDTV */
+ 0x04A8, 0x1FFE, 0x0662, 0x04A8, 0x1E6F, 0x1CBF,
+ 0x04A8, 0x0812, 0x1FFF, 0x0C84, 0x0220, 0x0BAC,
+ }
+ },
+ },
+ .r709 = {
+ .limited = {
+ { /* HDTV */
+ 0x0400, 0x0000, 0x0629, 0x0400, 0x1F45, 0x1E2B,
+ 0x0400, 0x0742, 0x0000, 0x0CEC, 0x0148, 0x0C60,
+ }
+ },
+ .full = {
+ { /* HDTV */
+ 0x04A8, 0x0000, 0x072C, 0x04A8, 0x1F26, 0x1DDE,
+ 0x04A8, 0x0873, 0x0000, 0x0C20, 0x0134, 0x0B7C,
+ }
+ },
+ },
+ },
+ .r2y = {
+ .r601 = {
+ .limited = {
+ { /* SDTV */
+ 0x0132, 0x0259, 0x0075, 0x1F50, 0x1EA5, 0x020B,
+ 0x020B, 0x1E4A, 0x1FAB, 0x0000, 0x0200, 0x0200,
+ }
+ },
+ .full = {
+ { /* SDTV */
+ 0x0107, 0x0204, 0x0064, 0x1F68, 0x1ED6, 0x01C2,
+ 0x01C2, 0x1E87, 0x1FB7, 0x0040, 0x0200, 0x0200,
+ }
+ },
+ },
+ .r709 = {
+ .limited = {
+ { /* HDTV */
+ 0x00DA, 0x02DC, 0x004A, 0x1F88, 0x1E6C, 0x020C,
+ 0x020C, 0x1E24, 0x1FD0, 0x0000, 0x0200, 0x0200,
+ }
+ },
+ .full = {
+ { /* HDTV */
+ 0x00bb, 0x0275, 0x003f, 0x1f99, 0x1ea5, 0x01c2,
+ 0x01c2, 0x1e67, 0x1fd7, 0x0040, 0x0200, 0x0200,
+ }
+ },
+ },
+ },
+
+};
+
+void csc_dump_regs(struct csc_data *csc)
+{
+ struct device *dev = &csc->pdev->dev;
+
+#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \
+ ioread32(csc->base + CSC_##r))
+
+ dev_dbg(dev, "CSC Registers @ %pa:\n", &csc->res->start);
+
+ DUMPREG(CSC00);
+ DUMPREG(CSC01);
+ DUMPREG(CSC02);
+ DUMPREG(CSC03);
+ DUMPREG(CSC04);
+ DUMPREG(CSC05);
+
+#undef DUMPREG
+}
+EXPORT_SYMBOL(csc_dump_regs);
+
+void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5)
+{
+ *csc_reg5 |= CSC_BYPASS;
+}
+EXPORT_SYMBOL(csc_set_coeff_bypass);
+
+/*
+ * set the color space converter coefficient shadow register values
+ */
+void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
+ struct v4l2_format *src_fmt, struct v4l2_format *dst_fmt)
+{
+ u32 *csc_reg5 = csc_reg0 + 5;
+ u32 *shadow_csc = csc_reg0;
+ u16 *coeff, *end_coeff;
+ const struct v4l2_pix_format *pix;
+ const struct v4l2_pix_format_mplane *mp;
+ const struct v4l2_format_info *src_finfo, *dst_finfo;
+ enum v4l2_ycbcr_encoding src_ycbcr_enc, dst_ycbcr_enc;
+ enum v4l2_quantization src_quantization, dst_quantization;
+ u32 src_pixelformat, dst_pixelformat;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(src_fmt->type)) {
+ mp = &src_fmt->fmt.pix_mp;
+ src_pixelformat = mp->pixelformat;
+ src_ycbcr_enc = mp->ycbcr_enc;
+ src_quantization = mp->quantization;
+ } else {
+ pix = &src_fmt->fmt.pix;
+ src_pixelformat = pix->pixelformat;
+ src_ycbcr_enc = pix->ycbcr_enc;
+ src_quantization = pix->quantization;
+ }
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(dst_fmt->type)) {
+ mp = &dst_fmt->fmt.pix_mp;
+ dst_pixelformat = mp->pixelformat;
+ dst_ycbcr_enc = mp->ycbcr_enc;
+ dst_quantization = mp->quantization;
+ } else {
+ pix = &dst_fmt->fmt.pix;
+ dst_pixelformat = pix->pixelformat;
+ dst_ycbcr_enc = pix->ycbcr_enc;
+ dst_quantization = pix->quantization;
+ }
+
+ src_finfo = v4l2_format_info(src_pixelformat);
+ dst_finfo = v4l2_format_info(dst_pixelformat);
+
+ if (v4l2_is_format_yuv(src_finfo) &&
+ v4l2_is_format_rgb(dst_finfo)) {
+ /* Y2R */
+
+ /*
+ * These are not the standard default values but are
+ * set this way for historical compatibility
+ */
+ if (src_ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
+ src_ycbcr_enc = V4L2_YCBCR_ENC_601;
+
+ if (src_quantization == V4L2_QUANTIZATION_DEFAULT)
+ src_quantization = V4L2_QUANTIZATION_FULL_RANGE;
+
+ if (src_ycbcr_enc == V4L2_YCBCR_ENC_601) {
+ if (src_quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ coeff = csc_coeffs.y2r.r601.full.coeff;
+ else
+ coeff = csc_coeffs.y2r.r601.limited.coeff;
+ } else if (src_ycbcr_enc == V4L2_YCBCR_ENC_709) {
+ if (src_quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ coeff = csc_coeffs.y2r.r709.full.coeff;
+ else
+ coeff = csc_coeffs.y2r.r709.limited.coeff;
+ } else {
+ /* Should never reach this, but it keeps gcc happy */
+ coeff = csc_coeffs.y2r.r601.full.coeff;
+ }
+ } else if (v4l2_is_format_rgb(src_finfo) &&
+ v4l2_is_format_yuv(dst_finfo)) {
+ /* R2Y */
+
+ /*
+ * These are not the standard default values but are
+ * set this way for historical compatibility
+ */
+ if (dst_ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
+ dst_ycbcr_enc = V4L2_YCBCR_ENC_601;
+
+ if (dst_quantization == V4L2_QUANTIZATION_DEFAULT)
+ dst_quantization = V4L2_QUANTIZATION_FULL_RANGE;
+
+ if (dst_ycbcr_enc == V4L2_YCBCR_ENC_601) {
+ if (dst_quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ coeff = csc_coeffs.r2y.r601.full.coeff;
+ else
+ coeff = csc_coeffs.r2y.r601.limited.coeff;
+ } else if (dst_ycbcr_enc == V4L2_YCBCR_ENC_709) {
+ if (dst_quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ coeff = csc_coeffs.r2y.r709.full.coeff;
+ else
+ coeff = csc_coeffs.r2y.r709.limited.coeff;
+ } else {
+ /* Should never reach this, but it keeps gcc happy */
+ coeff = csc_coeffs.r2y.r601.full.coeff;
+ }
+ } else {
+ *csc_reg5 |= CSC_BYPASS;
+ return;
+ }
+
+ end_coeff = coeff + 12;
+
+ for (; coeff < end_coeff; coeff += 2)
+ *shadow_csc++ = (*(coeff + 1) << 16) | *coeff;
+}
+EXPORT_SYMBOL(csc_set_coeff);
+
+struct csc_data *csc_create(struct platform_device *pdev, const char *res_name)
+{
+ struct csc_data *csc;
+
+ dev_dbg(&pdev->dev, "csc_create\n");
+
+ csc = devm_kzalloc(&pdev->dev, sizeof(*csc), GFP_KERNEL);
+ if (!csc) {
+ dev_err(&pdev->dev, "couldn't alloc csc_data\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ csc->pdev = pdev;
+
+ csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ res_name);
+ if (csc->res == NULL) {
+ dev_err(&pdev->dev, "missing '%s' platform resources data\n",
+ res_name);
+ return ERR_PTR(-ENODEV);
+ }
+
+ csc->base = devm_ioremap_resource(&pdev->dev, csc->res);
+ if (IS_ERR(csc->base))
+ return ERR_CAST(csc->base);
+
+ return csc;
+}
+EXPORT_SYMBOL(csc_create);
+
+MODULE_DESCRIPTION("TI VIP/VPE Color Space Converter");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti/vpe/csc.h b/drivers/media/platform/ti/vpe/csc.h
new file mode 100644
index 000000000000..af2e86bccf57
--- /dev/null
+++ b/drivers/media/platform/ti/vpe/csc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2013 Texas Instruments Inc.
+ *
+ * David Griego,
+ * Dale Farnsworth,
+ * Archit Taneja,
+ */
+#ifndef TI_CSC_H
+#define TI_CSC_H
+
+/* VPE color space converter regs */
+#define CSC_CSC00 0x00
+#define CSC_A0_MASK 0x1fff
+#define CSC_A0_SHIFT 0
+#define CSC_B0_MASK 0x1fff
+#define CSC_B0_SHIFT 16
+
+#define CSC_CSC01 0x04
+#define CSC_C0_MASK 0x1fff
+#define CSC_C0_SHIFT 0
+#define CSC_A1_MASK 0x1fff
+#define CSC_A1_SHIFT 16
+
+#define CSC_CSC02 0x08
+#define CSC_B1_MASK 0x1fff
+#define CSC_B1_SHIFT 0
+#define CSC_C1_MASK 0x1fff
+#define CSC_C1_SHIFT 16
+
+#define CSC_CSC03 0x0c
+#define CSC_A2_MASK 0x1fff
+#define CSC_A2_SHIFT 0
+#define CSC_B2_MASK 0x1fff
+#define CSC_B2_SHIFT 16
+
+#define CSC_CSC04 0x10
+#define CSC_C2_MASK 0x1fff
+#define CSC_C2_SHIFT 0
+#define CSC_D0_MASK 0x0fff
+#define CSC_D0_SHIFT 16
+
+#define CSC_CSC05 0x14
+#define CSC_D1_MASK 0x0fff
+#define CSC_D1_SHIFT 0
+#define CSC_D2_MASK 0x0fff
+#define CSC_D2_SHIFT 16
+
+#define CSC_BYPASS (1 << 28)
+
+struct csc_data {
+ void __iomem *base;
+ struct resource *res;
+
+ struct platform_device *pdev;
+};
+
+void csc_dump_regs(struct csc_data *csc);
+void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5);
+void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
+ struct v4l2_format *src_fmt, struct v4l2_format *dst_fmt);
+
+struct csc_data *csc_create(struct platform_device *pdev, const char *res_name);
+
+#endif
diff --git a/drivers/media/platform/ti/vpe/sc.c b/drivers/media/platform/ti/vpe/sc.c
new file mode 100644
index 000000000000..0202d278523f
--- /dev/null
+++ b/drivers/media/platform/ti/vpe/sc.c
@@ -0,0 +1,306 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Scaler library
+ *
+ * Copyright (c) 2013 Texas Instruments Inc.
+ *
+ * David Griego,
+ * Dale Farnsworth,
+ * Archit Taneja,
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include "sc.h"
+#include "sc_coeff.h"
+
+void sc_dump_regs(struct sc_data *sc)
+{
+ struct device *dev = &sc->pdev->dev;
+
+#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, \
+ ioread32(sc->base + CFG_##r))
+
+ dev_dbg(dev, "SC Registers @ %pa:\n", &sc->res->start);
+
+ DUMPREG(SC0);
+ DUMPREG(SC1);
+ DUMPREG(SC2);
+ DUMPREG(SC3);
+ DUMPREG(SC4);
+ DUMPREG(SC5);
+ DUMPREG(SC6);
+ DUMPREG(SC8);
+ DUMPREG(SC9);
+ DUMPREG(SC10);
+ DUMPREG(SC11);
+ DUMPREG(SC12);
+ DUMPREG(SC13);
+ DUMPREG(SC17);
+ DUMPREG(SC18);
+ DUMPREG(SC19);
+ DUMPREG(SC20);
+ DUMPREG(SC21);
+ DUMPREG(SC22);
+ DUMPREG(SC23);
+ DUMPREG(SC24);
+ DUMPREG(SC25);
+
+#undef DUMPREG
+}
+EXPORT_SYMBOL(sc_dump_regs);
+
+/*
+ * set the horizontal scaler coefficients according to the ratio of output to
+ * input widths, after accounting for up to two levels of decimation
+ */
+void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
+ unsigned int dst_w)
+{
+ int sixteenths;
+ int idx;
+ int i, j;
+ u16 *coeff_h = addr;
+ const u16 *cp;
+
+ if (dst_w > src_w) {
+ idx = HS_UP_SCALE;
+ } else {
+ if ((dst_w << 1) < src_w)
+ dst_w <<= 1; /* first level decimation */
+ if ((dst_w << 1) < src_w)
+ dst_w <<= 1; /* second level decimation */
+
+ if (dst_w == src_w) {
+ idx = HS_LE_16_16_SCALE;
+ } else {
+ sixteenths = (dst_w << 4) / src_w;
+ if (sixteenths < 8)
+ sixteenths = 8;
+ idx = HS_LT_9_16_SCALE + sixteenths - 8;
+ }
+ }
+
+ cp = scaler_hs_coeffs[idx];
+
+ for (i = 0; i < SC_NUM_PHASES * 2; i++) {
+ for (j = 0; j < SC_H_NUM_TAPS; j++)
+ *coeff_h++ = *cp++;
+ /*
+ * for each phase, the scaler expects space for 8 coefficients
+ * in it's memory. For the horizontal scaler, we copy the first
+ * 7 coefficients and skip the last slot to move to the next
+ * row to hold coefficients for the next phase
+ */
+ coeff_h += SC_NUM_TAPS_MEM_ALIGN - SC_H_NUM_TAPS;
+ }
+
+ sc->load_coeff_h = true;
+}
+EXPORT_SYMBOL(sc_set_hs_coeffs);
+
+/*
+ * set the vertical scaler coefficients according to the ratio of output to
+ * input heights
+ */
+void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
+ unsigned int dst_h)
+{
+ int sixteenths;
+ int idx;
+ int i, j;
+ u16 *coeff_v = addr;
+ const u16 *cp;
+
+ if (dst_h > src_h) {
+ idx = VS_UP_SCALE;
+ } else if (dst_h == src_h) {
+ idx = VS_1_TO_1_SCALE;
+ } else {
+ sixteenths = (dst_h << 4) / src_h;
+ if (sixteenths < 8)
+ sixteenths = 8;
+ idx = VS_LT_9_16_SCALE + sixteenths - 8;
+ }
+
+ cp = scaler_vs_coeffs[idx];
+
+ for (i = 0; i < SC_NUM_PHASES * 2; i++) {
+ for (j = 0; j < SC_V_NUM_TAPS; j++)
+ *coeff_v++ = *cp++;
+ /*
+ * for the vertical scaler, we copy the first 5 coefficients and
+ * skip the last 3 slots to move to the next row to hold
+ * coefficients for the next phase
+ */
+ coeff_v += SC_NUM_TAPS_MEM_ALIGN - SC_V_NUM_TAPS;
+ }
+
+ sc->load_coeff_v = true;
+}
+EXPORT_SYMBOL(sc_set_vs_coeffs);
+
+void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
+ u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
+ unsigned int dst_w, unsigned int dst_h)
+{
+ struct device *dev = &sc->pdev->dev;
+ u32 val;
+ int dcm_x, dcm_shift;
+ bool use_rav;
+ unsigned long lltmp;
+ u32 lin_acc_inc, lin_acc_inc_u;
+ u32 col_acc_offset;
+ u16 factor = 0;
+ int row_acc_init_rav = 0, row_acc_init_rav_b = 0;
+ u32 row_acc_inc = 0, row_acc_offset = 0, row_acc_offset_b = 0;
+ /*
+ * location of SC register in payload memory with respect to the first
+ * register in the mmr address data block
+ */
+ u32 *sc_reg9 = sc_reg8 + 1;
+ u32 *sc_reg12 = sc_reg8 + 4;
+ u32 *sc_reg13 = sc_reg8 + 5;
+ u32 *sc_reg24 = sc_reg17 + 7;
+
+ val = sc_reg0[0];
+
+ /* clear all the features(they may get enabled elsewhere later) */
+ val &= ~(CFG_SELFGEN_FID | CFG_TRIM | CFG_ENABLE_SIN2_VER_INTP |
+ CFG_INTERLACE_I | CFG_DCM_4X | CFG_DCM_2X | CFG_AUTO_HS |
+ CFG_ENABLE_EV | CFG_USE_RAV | CFG_INVT_FID | CFG_SC_BYPASS |
+ CFG_INTERLACE_O | CFG_Y_PK_EN | CFG_HP_BYPASS | CFG_LINEAR);
+
+ if (src_w == dst_w && src_h == dst_h) {
+ val |= CFG_SC_BYPASS;
+ sc_reg0[0] = val;
+ return;
+ }
+
+ /* we only support linear scaling for now */
+ val |= CFG_LINEAR;
+
+ /* configure horizontal scaler */
+
+ /* enable 2X or 4X decimation */
+ dcm_x = src_w / dst_w;
+ if (dcm_x > 4) {
+ val |= CFG_DCM_4X;
+ dcm_shift = 2;
+ } else if (dcm_x > 2) {
+ val |= CFG_DCM_2X;
+ dcm_shift = 1;
+ } else {
+ dcm_shift = 0;
+ }
+
+ lltmp = dst_w - 1;
+ lin_acc_inc = div64_u64(((u64)(src_w >> dcm_shift) - 1) << 24, lltmp);
+ lin_acc_inc_u = 0;
+ col_acc_offset = 0;
+
+ dev_dbg(dev, "hs config: src_w = %d, dst_w = %d, decimation = %s, lin_acc_inc = %08x\n",
+ src_w, dst_w, dcm_shift == 2 ? "4x" :
+ (dcm_shift == 1 ? "2x" : "none"), lin_acc_inc);
+
+ /* configure vertical scaler */
+
+ /* use RAV for vertical scaler if vertical downscaling is > 4x */
+ if (dst_h < (src_h >> 2)) {
+ use_rav = true;
+ val |= CFG_USE_RAV;
+ } else {
+ use_rav = false;
+ }
+
+ if (use_rav) {
+ /* use RAV */
+ factor = (u16) ((dst_h << 10) / src_h);
+
+ row_acc_init_rav = factor + ((1 + factor) >> 1);
+ if (row_acc_init_rav >= 1024)
+ row_acc_init_rav -= 1024;
+
+ row_acc_init_rav_b = row_acc_init_rav +
+ (1 + (row_acc_init_rav >> 1)) -
+ (1024 >> 1);
+
+ if (row_acc_init_rav_b < 0) {
+ row_acc_init_rav_b += row_acc_init_rav;
+ row_acc_init_rav *= 2;
+ }
+
+ dev_dbg(dev, "vs config(RAV): src_h = %d, dst_h = %d, factor = %d, acc_init = %08x, acc_init_b = %08x\n",
+ src_h, dst_h, factor, row_acc_init_rav,
+ row_acc_init_rav_b);
+ } else {
+ /* use polyphase */
+ row_acc_inc = ((src_h - 1) << 16) / (dst_h - 1);
+ row_acc_offset = 0;
+ row_acc_offset_b = 0;
+
+ dev_dbg(dev, "vs config(POLY): src_h = %d, dst_h = %d,row_acc_inc = %08x\n",
+ src_h, dst_h, row_acc_inc);
+ }
+
+
+ sc_reg0[0] = val;
+ sc_reg0[1] = row_acc_inc;
+ sc_reg0[2] = row_acc_offset;
+ sc_reg0[3] = row_acc_offset_b;
+
+ sc_reg0[4] = ((lin_acc_inc_u & CFG_LIN_ACC_INC_U_MASK) <<
+ CFG_LIN_ACC_INC_U_SHIFT) | (dst_w << CFG_TAR_W_SHIFT) |
+ (dst_h << CFG_TAR_H_SHIFT);
+
+ sc_reg0[5] = (src_w << CFG_SRC_W_SHIFT) | (src_h << CFG_SRC_H_SHIFT);
+
+ sc_reg0[6] = (row_acc_init_rav_b << CFG_ROW_ACC_INIT_RAV_B_SHIFT) |
+ (row_acc_init_rav << CFG_ROW_ACC_INIT_RAV_SHIFT);
+
+ *sc_reg9 = lin_acc_inc;
+
+ *sc_reg12 = col_acc_offset << CFG_COL_ACC_OFFSET_SHIFT;
+
+ *sc_reg13 = factor;
+
+ *sc_reg24 = (src_w << CFG_ORG_W_SHIFT) | (src_h << CFG_ORG_H_SHIFT);
+}
+EXPORT_SYMBOL(sc_config_scaler);
+
+struct sc_data *sc_create(struct platform_device *pdev, const char *res_name)
+{
+ struct sc_data *sc;
+
+ dev_dbg(&pdev->dev, "sc_create\n");
+
+ sc = devm_kzalloc(&pdev->dev, sizeof(*sc), GFP_KERNEL);
+ if (!sc) {
+ dev_err(&pdev->dev, "couldn't alloc sc_data\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ sc->pdev = pdev;
+
+ sc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
+ if (!sc->res) {
+ dev_err(&pdev->dev, "missing '%s' platform resources data\n",
+ res_name);
+ return ERR_PTR(-ENODEV);
+ }
+
+ sc->base = devm_ioremap_resource(&pdev->dev, sc->res);
+ if (IS_ERR(sc->base))
+ return ERR_CAST(sc->base);
+
+ return sc;
+}
+EXPORT_SYMBOL(sc_create);
+
+MODULE_DESCRIPTION("TI VIP/VPE Scaler");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti/vpe/sc.h b/drivers/media/platform/ti/vpe/sc.h
new file mode 100644
index 000000000000..d55de44d5257
--- /dev/null
+++ b/drivers/media/platform/ti/vpe/sc.h
@@ -0,0 +1,208 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2013 Texas Instruments Inc.
+ *
+ * David Griego,
+ * Dale Farnsworth,
+ * Archit Taneja,
+ */
+#ifndef TI_SC_H
+#define TI_SC_H
+
+/* Scaler regs */
+#define CFG_SC0 0x0
+#define CFG_INTERLACE_O (1 << 0)
+#define CFG_LINEAR (1 << 1)
+#define CFG_SC_BYPASS (1 << 2)
+#define CFG_INVT_FID (1 << 3)
+#define CFG_USE_RAV (1 << 4)
+#define CFG_ENABLE_EV (1 << 5)
+#define CFG_AUTO_HS (1 << 6)
+#define CFG_DCM_2X (1 << 7)
+#define CFG_DCM_4X (1 << 8)
+#define CFG_HP_BYPASS (1 << 9)
+#define CFG_INTERLACE_I (1 << 10)
+#define CFG_ENABLE_SIN2_VER_INTP (1 << 11)
+#define CFG_Y_PK_EN (1 << 14)
+#define CFG_TRIM (1 << 15)
+#define CFG_SELFGEN_FID (1 << 16)
+
+#define CFG_SC1 0x4
+#define CFG_ROW_ACC_INC_MASK 0x07ffffff
+#define CFG_ROW_ACC_INC_SHIFT 0
+
+#define CFG_SC2 0x08
+#define CFG_ROW_ACC_OFFSET_MASK 0x0fffffff
+#define CFG_ROW_ACC_OFFSET_SHIFT 0
+
+#define CFG_SC3 0x0c
+#define CFG_ROW_ACC_OFFSET_B_MASK 0x0fffffff
+#define CFG_ROW_ACC_OFFSET_B_SHIFT 0
+
+#define CFG_SC4 0x10
+#define CFG_TAR_H_MASK 0x07ff
+#define CFG_TAR_H_SHIFT 0
+#define CFG_TAR_W_MASK 0x07ff
+#define CFG_TAR_W_SHIFT 12
+#define CFG_LIN_ACC_INC_U_MASK 0x07
+#define CFG_LIN_ACC_INC_U_SHIFT 24
+#define CFG_NLIN_ACC_INIT_U_MASK 0x07
+#define CFG_NLIN_ACC_INIT_U_SHIFT 28
+
+#define CFG_SC5 0x14
+#define CFG_SRC_H_MASK 0x07ff
+#define CFG_SRC_H_SHIFT 0
+#define CFG_SRC_W_MASK 0x07ff
+#define CFG_SRC_W_SHIFT 12
+#define CFG_NLIN_ACC_INC_U_MASK 0x07
+#define CFG_NLIN_ACC_INC_U_SHIFT 24
+
+#define CFG_SC6 0x18
+#define CFG_ROW_ACC_INIT_RAV_MASK 0x03ff
+#define CFG_ROW_ACC_INIT_RAV_SHIFT 0
+#define CFG_ROW_ACC_INIT_RAV_B_MASK 0x03ff
+#define CFG_ROW_ACC_INIT_RAV_B_SHIFT 10
+
+#define CFG_SC8 0x20
+#define CFG_NLIN_LEFT_MASK 0x07ff
+#define CFG_NLIN_LEFT_SHIFT 0
+#define CFG_NLIN_RIGHT_MASK 0x07ff
+#define CFG_NLIN_RIGHT_SHIFT 12
+
+#define CFG_SC9 0x24
+#define CFG_LIN_ACC_INC CFG_SC9
+
+#define CFG_SC10 0x28
+#define CFG_NLIN_ACC_INIT CFG_SC10
+
+#define CFG_SC11 0x2c
+#define CFG_NLIN_ACC_INC CFG_SC11
+
+#define CFG_SC12 0x30
+#define CFG_COL_ACC_OFFSET_MASK 0x01ffffff
+#define CFG_COL_ACC_OFFSET_SHIFT 0
+
+#define CFG_SC13 0x34
+#define CFG_SC_FACTOR_RAV_MASK 0xff
+#define CFG_SC_FACTOR_RAV_SHIFT 0
+#define CFG_CHROMA_INTP_THR_MASK 0x03ff
+#define CFG_CHROMA_INTP_THR_SHIFT 12
+#define CFG_DELTA_CHROMA_THR_MASK 0x0f
+#define CFG_DELTA_CHROMA_THR_SHIFT 24
+
+#define CFG_SC17 0x44
+#define CFG_EV_THR_MASK 0x03ff
+#define CFG_EV_THR_SHIFT 12
+#define CFG_DELTA_LUMA_THR_MASK 0x0f
+#define CFG_DELTA_LUMA_THR_SHIFT 24
+#define CFG_DELTA_EV_THR_MASK 0x0f
+#define CFG_DELTA_EV_THR_SHIFT 28
+
+#define CFG_SC18 0x48
+#define CFG_HS_FACTOR_MASK 0x03ff
+#define CFG_HS_FACTOR_SHIFT 0
+#define CFG_CONF_DEFAULT_MASK 0x01ff
+#define CFG_CONF_DEFAULT_SHIFT 16
+
+#define CFG_SC19 0x4c
+#define CFG_HPF_COEFF0_MASK 0xff
+#define CFG_HPF_COEFF0_SHIFT 0
+#define CFG_HPF_COEFF1_MASK 0xff
+#define CFG_HPF_COEFF1_SHIFT 8
+#define CFG_HPF_COEFF2_MASK 0xff
+#define CFG_HPF_COEFF2_SHIFT 16
+#define CFG_HPF_COEFF3_MASK 0xff
+#define CFG_HPF_COEFF3_SHIFT 23
+
+#define CFG_SC20 0x50
+#define CFG_HPF_COEFF4_MASK 0xff
+#define CFG_HPF_COEFF4_SHIFT 0
+#define CFG_HPF_COEFF5_MASK 0xff
+#define CFG_HPF_COEFF5_SHIFT 8
+#define CFG_HPF_NORM_SHIFT_MASK 0x07
+#define CFG_HPF_NORM_SHIFT_SHIFT 16
+#define CFG_NL_LIMIT_MASK 0x1ff
+#define CFG_NL_LIMIT_SHIFT 20
+
+#define CFG_SC21 0x54
+#define CFG_NL_LO_THR_MASK 0x01ff
+#define CFG_NL_LO_THR_SHIFT 0
+#define CFG_NL_LO_SLOPE_MASK 0xff
+#define CFG_NL_LO_SLOPE_SHIFT 16
+
+#define CFG_SC22 0x58
+#define CFG_NL_HI_THR_MASK 0x01ff
+#define CFG_NL_HI_THR_SHIFT 0
+#define CFG_NL_HI_SLOPE_SH_MASK 0x07
+#define CFG_NL_HI_SLOPE_SH_SHIFT 16
+
+#define CFG_SC23 0x5c
+#define CFG_GRADIENT_THR_MASK 0x07ff
+#define CFG_GRADIENT_THR_SHIFT 0
+#define CFG_GRADIENT_THR_RANGE_MASK 0x0f
+#define CFG_GRADIENT_THR_RANGE_SHIFT 12
+#define CFG_MIN_GY_THR_MASK 0xff
+#define CFG_MIN_GY_THR_SHIFT 16
+#define CFG_MIN_GY_THR_RANGE_MASK 0x0f
+#define CFG_MIN_GY_THR_RANGE_SHIFT 28
+
+#define CFG_SC24 0x60
+#define CFG_ORG_H_MASK 0x07ff
+#define CFG_ORG_H_SHIFT 0
+#define CFG_ORG_W_MASK 0x07ff
+#define CFG_ORG_W_SHIFT 16
+
+#define CFG_SC25 0x64
+#define CFG_OFF_H_MASK 0x07ff
+#define CFG_OFF_H_SHIFT 0
+#define CFG_OFF_W_MASK 0x07ff
+#define CFG_OFF_W_SHIFT 16
+
+/* number of phases supported by the polyphase scalers */
+#define SC_NUM_PHASES 32
+
+/* number of taps used by horizontal polyphase scaler */
+#define SC_H_NUM_TAPS 7
+
+/* number of taps used by vertical polyphase scaler */
+#define SC_V_NUM_TAPS 5
+
+/* number of taps expected by the scaler in it's coefficient memory */
+#define SC_NUM_TAPS_MEM_ALIGN 8
+
+/* Maximum frame width the scaler can handle (in pixels) */
+#define SC_MAX_PIXEL_WIDTH 2047
+
+/* Maximum frame height the scaler can handle (in lines) */
+#define SC_MAX_PIXEL_HEIGHT 2047
+
+/*
+ * coefficient memory size in bytes:
+ * num phases x num sets(luma and chroma) x num taps(aligned) x coeff size
+ */
+#define SC_COEF_SRAM_SIZE (SC_NUM_PHASES * 2 * SC_NUM_TAPS_MEM_ALIGN * 2)
+
+struct sc_data {
+ void __iomem *base;
+ struct resource *res;
+
+ dma_addr_t loaded_coeff_h; /* loaded h coeffs in SC */
+ dma_addr_t loaded_coeff_v; /* loaded v coeffs in SC */
+
+ bool load_coeff_h; /* have new h SC coeffs */
+ bool load_coeff_v; /* have new v SC coeffs */
+
+ struct platform_device *pdev;
+};
+
+void sc_dump_regs(struct sc_data *sc);
+void sc_set_hs_coeffs(struct sc_data *sc, void *addr, unsigned int src_w,
+ unsigned int dst_w);
+void sc_set_vs_coeffs(struct sc_data *sc, void *addr, unsigned int src_h,
+ unsigned int dst_h);
+void sc_config_scaler(struct sc_data *sc, u32 *sc_reg0, u32 *sc_reg8,
+ u32 *sc_reg17, unsigned int src_w, unsigned int src_h,
+ unsigned int dst_w, unsigned int dst_h);
+struct sc_data *sc_create(struct platform_device *pdev, const char *res_name);
+
+#endif
diff --git a/drivers/media/platform/ti/vpe/sc_coeff.h b/drivers/media/platform/ti/vpe/sc_coeff.h
new file mode 100644
index 000000000000..c525d1764099
--- /dev/null
+++ b/drivers/media/platform/ti/vpe/sc_coeff.h
@@ -0,0 +1,1339 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * VPE SC coefs
+ *
+ * Copyright (c) 2013 Texas Instruments Inc.
+ *
+ * David Griego,
+ * Dale Farnsworth,
+ * Archit Taneja,
+ */
+
+#ifndef __TI_SC_COEFF_H
+#define __TI_SC_COEFF_H
+
+/* horizontal scaler coefficients */
+enum {
+ HS_UP_SCALE = 0,
+ HS_LT_9_16_SCALE,
+ HS_LT_10_16_SCALE,
+ HS_LT_11_16_SCALE,
+ HS_LT_12_16_SCALE,
+ HS_LT_13_16_SCALE,
+ HS_LT_14_16_SCALE,
+ HS_LT_15_16_SCALE,
+ HS_LE_16_16_SCALE,
+};
+
+static const u16 scaler_hs_coeffs[13][SC_NUM_PHASES * 2 * SC_H_NUM_TAPS] = {
+ [HS_UP_SCALE] = {
+ /* Luma */
+ 0x001F, 0x1F90, 0x00D2, 0x06FE, 0x00D2, 0x1F90, 0x001F,
+ 0x001C, 0x1F9E, 0x009F, 0x06FB, 0x0108, 0x1F82, 0x0022,
+ 0x0019, 0x1FAC, 0x006F, 0x06F3, 0x0140, 0x1F74, 0x0025,
+ 0x0016, 0x1FB9, 0x0041, 0x06E7, 0x017B, 0x1F66, 0x0028,
+ 0x0013, 0x1FC6, 0x0017, 0x06D6, 0x01B7, 0x1F58, 0x002B,
+ 0x0010, 0x1FD3, 0x1FEF, 0x06C0, 0x01F6, 0x1F4B, 0x002D,
+ 0x000E, 0x1FDF, 0x1FCB, 0x06A5, 0x0235, 0x1F3F, 0x002F,
+ 0x000B, 0x1FEA, 0x1FAA, 0x0686, 0x0277, 0x1F33, 0x0031,
+ 0x0009, 0x1FF5, 0x1F8C, 0x0663, 0x02B8, 0x1F28, 0x0033,
+ 0x0007, 0x1FFF, 0x1F72, 0x063A, 0x02FB, 0x1F1F, 0x0034,
+ 0x0005, 0x0008, 0x1F5A, 0x060F, 0x033E, 0x1F17, 0x0035,
+ 0x0003, 0x0010, 0x1F46, 0x05E0, 0x0382, 0x1F10, 0x0035,
+ 0x0002, 0x0017, 0x1F34, 0x05AF, 0x03C5, 0x1F0B, 0x0034,
+ 0x0001, 0x001E, 0x1F26, 0x0579, 0x0407, 0x1F08, 0x0033,
+ 0x0000, 0x0023, 0x1F1A, 0x0541, 0x0449, 0x1F07, 0x0032,
+ 0x1FFF, 0x0028, 0x1F12, 0x0506, 0x048A, 0x1F08, 0x002F,
+ 0x002C, 0x1F0C, 0x04C8, 0x04C8, 0x1F0C, 0x002C, 0x0000,
+ 0x002F, 0x1F08, 0x048A, 0x0506, 0x1F12, 0x0028, 0x1FFF,
+ 0x0032, 0x1F07, 0x0449, 0x0541, 0x1F1A, 0x0023, 0x0000,
+ 0x0033, 0x1F08, 0x0407, 0x0579, 0x1F26, 0x001E, 0x0001,
+ 0x0034, 0x1F0B, 0x03C5, 0x05AF, 0x1F34, 0x0017, 0x0002,
+ 0x0035, 0x1F10, 0x0382, 0x05E0, 0x1F46, 0x0010, 0x0003,
+ 0x0035, 0x1F17, 0x033E, 0x060F, 0x1F5A, 0x0008, 0x0005,
+ 0x0034, 0x1F1F, 0x02FB, 0x063A, 0x1F72, 0x1FFF, 0x0007,
+ 0x0033, 0x1F28, 0x02B8, 0x0663, 0x1F8C, 0x1FF5, 0x0009,
+ 0x0031, 0x1F33, 0x0277, 0x0686, 0x1FAA, 0x1FEA, 0x000B,
+ 0x002F, 0x1F3F, 0x0235, 0x06A5, 0x1FCB, 0x1FDF, 0x000E,
+ 0x002D, 0x1F4B, 0x01F6, 0x06C0, 0x1FEF, 0x1FD3, 0x0010,
+ 0x002B, 0x1F58, 0x01B7, 0x06D6, 0x0017, 0x1FC6, 0x0013,
+ 0x0028, 0x1F66, 0x017B, 0x06E7, 0x0041, 0x1FB9, 0x0016,
+ 0x0025, 0x1F74, 0x0140, 0x06F3, 0x006F, 0x1FAC, 0x0019,
+ 0x0022, 0x1F82, 0x0108, 0x06FB, 0x009F, 0x1F9E, 0x001C,
+ /* Chroma */
+ 0x001F, 0x1F90, 0x00D2, 0x06FE, 0x00D2, 0x1F90, 0x001F,
+ 0x001C, 0x1F9E, 0x009F, 0x06FB, 0x0108, 0x1F82, 0x0022,
+ 0x0019, 0x1FAC, 0x006F, 0x06F3, 0x0140, 0x1F74, 0x0025,
+ 0x0016, 0x1FB9, 0x0041, 0x06E7, 0x017B, 0x1F66, 0x0028,
+ 0x0013, 0x1FC6, 0x0017, 0x06D6, 0x01B7, 0x1F58, 0x002B,
+ 0x0010, 0x1FD3, 0x1FEF, 0x06C0, 0x01F6, 0x1F4B, 0x002D,
+ 0x000E, 0x1FDF, 0x1FCB, 0x06A5, 0x0235, 0x1F3F, 0x002F,
+ 0x000B, 0x1FEA, 0x1FAA, 0x0686, 0x0277, 0x1F33, 0x0031,
+ 0x0009, 0x1FF5, 0x1F8C, 0x0663, 0x02B8, 0x1F28, 0x0033,
+ 0x0007, 0x1FFF, 0x1F72, 0x063A, 0x02FB, 0x1F1F, 0x0034,
+ 0x0005, 0x0008, 0x1F5A, 0x060F, 0x033E, 0x1F17, 0x0035,
+ 0x0003, 0x0010, 0x1F46, 0x05E0, 0x0382, 0x1F10, 0x0035,
+ 0x0002, 0x0017, 0x1F34, 0x05AF, 0x03C5, 0x1F0B, 0x0034,
+ 0x0001, 0x001E, 0x1F26, 0x0579, 0x0407, 0x1F08, 0x0033,
+ 0x0000, 0x0023, 0x1F1A, 0x0541, 0x0449, 0x1F07, 0x0032,
+ 0x1FFF, 0x0028, 0x1F12, 0x0506, 0x048A, 0x1F08, 0x002F,
+ 0x002C, 0x1F0C, 0x04C8, 0x04C8, 0x1F0C, 0x002C, 0x0000,
+ 0x002F, 0x1F08, 0x048A, 0x0506, 0x1F12, 0x0028, 0x1FFF,
+ 0x0032, 0x1F07, 0x0449, 0x0541, 0x1F1A, 0x0023, 0x0000,
+ 0x0033, 0x1F08, 0x0407, 0x0579, 0x1F26, 0x001E, 0x0001,
+ 0x0034, 0x1F0B, 0x03C5, 0x05AF, 0x1F34, 0x0017, 0x0002,
+ 0x0035, 0x1F10, 0x0382, 0x05E0, 0x1F46, 0x0010, 0x0003,
+ 0x0035, 0x1F17, 0x033E, 0x060F, 0x1F5A, 0x0008, 0x0005,
+ 0x0034, 0x1F1F, 0x02FB, 0x063A, 0x1F72, 0x1FFF, 0x0007,
+ 0x0033, 0x1F28, 0x02B8, 0x0663, 0x1F8C, 0x1FF5, 0x0009,
+ 0x0031, 0x1F33, 0x0277, 0x0686, 0x1FAA, 0x1FEA, 0x000B,
+ 0x002F, 0x1F3F, 0x0235, 0x06A5, 0x1FCB, 0x1FDF, 0x000E,
+ 0x002D, 0x1F4B, 0x01F6, 0x06C0, 0x1FEF, 0x1FD3, 0x0010,
+ 0x002B, 0x1F58, 0x01B7, 0x06D6, 0x0017, 0x1FC6, 0x0013,
+ 0x0028, 0x1F66, 0x017B, 0x06E7, 0x0041, 0x1FB9, 0x0016,
+ 0x0025, 0x1F74, 0x0140, 0x06F3, 0x006F, 0x1FAC, 0x0019,
+ 0x0022, 0x1F82, 0x0108, 0x06FB, 0x009F, 0x1F9E, 0x001C,
+ },
+ [HS_LT_9_16_SCALE] = {
+ /* Luma */
+ 0x1FA3, 0x005E, 0x024A, 0x036A, 0x024A, 0x005E, 0x1FA3,
+ 0x1FA3, 0x0052, 0x023A, 0x036A, 0x0259, 0x006A, 0x1FA4,
+ 0x1FA3, 0x0046, 0x022A, 0x036A, 0x0269, 0x0076, 0x1FA4,
+ 0x1FA3, 0x003B, 0x021A, 0x0368, 0x0278, 0x0083, 0x1FA5,
+ 0x1FA4, 0x0031, 0x020A, 0x0365, 0x0286, 0x0090, 0x1FA6,
+ 0x1FA5, 0x0026, 0x01F9, 0x0362, 0x0294, 0x009E, 0x1FA8,
+ 0x1FA6, 0x001C, 0x01E8, 0x035E, 0x02A3, 0x00AB, 0x1FAA,
+ 0x1FA7, 0x0013, 0x01D7, 0x035A, 0x02B0, 0x00B9, 0x1FAC,
+ 0x1FA9, 0x000A, 0x01C6, 0x0354, 0x02BD, 0x00C7, 0x1FAF,
+ 0x1FAA, 0x0001, 0x01B6, 0x034E, 0x02C9, 0x00D6, 0x1FB2,
+ 0x1FAC, 0x1FF9, 0x01A5, 0x0347, 0x02D5, 0x00E5, 0x1FB5,
+ 0x1FAE, 0x1FF1, 0x0194, 0x0340, 0x02E1, 0x00F3, 0x1FB9,
+ 0x1FB0, 0x1FEA, 0x0183, 0x0338, 0x02EC, 0x0102, 0x1FBD,
+ 0x1FB2, 0x1FE3, 0x0172, 0x0330, 0x02F6, 0x0112, 0x1FC1,
+ 0x1FB4, 0x1FDC, 0x0161, 0x0327, 0x0301, 0x0121, 0x1FC6,
+ 0x1FB7, 0x1FD6, 0x0151, 0x031D, 0x030A, 0x0130, 0x1FCB,
+ 0x1FD2, 0x0136, 0x02F8, 0x02F8, 0x0136, 0x1FD2, 0x0000,
+ 0x1FCB, 0x0130, 0x030A, 0x031D, 0x0151, 0x1FD6, 0x1FB7,
+ 0x1FC6, 0x0121, 0x0301, 0x0327, 0x0161, 0x1FDC, 0x1FB4,
+ 0x1FC1, 0x0112, 0x02F6, 0x0330, 0x0172, 0x1FE3, 0x1FB2,
+ 0x1FBD, 0x0102, 0x02EC, 0x0338, 0x0183, 0x1FEA, 0x1FB0,
+ 0x1FB9, 0x00F3, 0x02E1, 0x0340, 0x0194, 0x1FF1, 0x1FAE,
+ 0x1FB5, 0x00E5, 0x02D5, 0x0347, 0x01A5, 0x1FF9, 0x1FAC,
+ 0x1FB2, 0x00D6, 0x02C9, 0x034E, 0x01B6, 0x0001, 0x1FAA,
+ 0x1FAF, 0x00C7, 0x02BD, 0x0354, 0x01C6, 0x000A, 0x1FA9,
+ 0x1FAC, 0x00B9, 0x02B0, 0x035A, 0x01D7, 0x0013, 0x1FA7,
+ 0x1FAA, 0x00AB, 0x02A3, 0x035E, 0x01E8, 0x001C, 0x1FA6,
+ 0x1FA8, 0x009E, 0x0294, 0x0362, 0x01F9, 0x0026, 0x1FA5,
+ 0x1FA6, 0x0090, 0x0286, 0x0365, 0x020A, 0x0031, 0x1FA4,
+ 0x1FA5, 0x0083, 0x0278, 0x0368, 0x021A, 0x003B, 0x1FA3,
+ 0x1FA4, 0x0076, 0x0269, 0x036A, 0x022A, 0x0046, 0x1FA3,
+ 0x1FA4, 0x006A, 0x0259, 0x036A, 0x023A, 0x0052, 0x1FA3,
+ /* Chroma */
+ 0x1FA3, 0x005E, 0x024A, 0x036A, 0x024A, 0x005E, 0x1FA3,
+ 0x1FA3, 0x0052, 0x023A, 0x036A, 0x0259, 0x006A, 0x1FA4,
+ 0x1FA3, 0x0046, 0x022A, 0x036A, 0x0269, 0x0076, 0x1FA4,
+ 0x1FA3, 0x003B, 0x021A, 0x0368, 0x0278, 0x0083, 0x1FA5,
+ 0x1FA4, 0x0031, 0x020A, 0x0365, 0x0286, 0x0090, 0x1FA6,
+ 0x1FA5, 0x0026, 0x01F9, 0x0362, 0x0294, 0x009E, 0x1FA8,
+ 0x1FA6, 0x001C, 0x01E8, 0x035E, 0x02A3, 0x00AB, 0x1FAA,
+ 0x1FA7, 0x0013, 0x01D7, 0x035A, 0x02B0, 0x00B9, 0x1FAC,
+ 0x1FA9, 0x000A, 0x01C6, 0x0354, 0x02BD, 0x00C7, 0x1FAF,
+ 0x1FAA, 0x0001, 0x01B6, 0x034E, 0x02C9, 0x00D6, 0x1FB2,
+ 0x1FAC, 0x1FF9, 0x01A5, 0x0347, 0x02D5, 0x00E5, 0x1FB5,
+ 0x1FAE, 0x1FF1, 0x0194, 0x0340, 0x02E1, 0x00F3, 0x1FB9,
+ 0x1FB0, 0x1FEA, 0x0183, 0x0338, 0x02EC, 0x0102, 0x1FBD,
+ 0x1FB2, 0x1FE3, 0x0172, 0x0330, 0x02F6, 0x0112, 0x1FC1,
+ 0x1FB4, 0x1FDC, 0x0161, 0x0327, 0x0301, 0x0121, 0x1FC6,
+ 0x1FB7, 0x1FD6, 0x0151, 0x031D, 0x030A, 0x0130, 0x1FCB,
+ 0x1FD2, 0x0136, 0x02F8, 0x02F8, 0x0136, 0x1FD2, 0x0000,
+ 0x1FCB, 0x0130, 0x030A, 0x031D, 0x0151, 0x1FD6, 0x1FB7,
+ 0x1FC6, 0x0121, 0x0301, 0x0327, 0x0161, 0x1FDC, 0x1FB4,
+ 0x1FC1, 0x0112, 0x02F6, 0x0330, 0x0172, 0x1FE3, 0x1FB2,
+ 0x1FBD, 0x0102, 0x02EC, 0x0338, 0x0183, 0x1FEA, 0x1FB0,
+ 0x1FB9, 0x00F3, 0x02E1, 0x0340, 0x0194, 0x1FF1, 0x1FAE,
+ 0x1FB5, 0x00E5, 0x02D5, 0x0347, 0x01A5, 0x1FF9, 0x1FAC,
+ 0x1FB2, 0x00D6, 0x02C9, 0x034E, 0x01B6, 0x0001, 0x1FAA,
+ 0x1FAF, 0x00C7, 0x02BD, 0x0354, 0x01C6, 0x000A, 0x1FA9,
+ 0x1FAC, 0x00B9, 0x02B0, 0x035A, 0x01D7, 0x0013, 0x1FA7,
+ 0x1FAA, 0x00AB, 0x02A3, 0x035E, 0x01E8, 0x001C, 0x1FA6,
+ 0x1FA8, 0x009E, 0x0294, 0x0362, 0x01F9, 0x0026, 0x1FA5,
+ 0x1FA6, 0x0090, 0x0286, 0x0365, 0x020A, 0x0031, 0x1FA4,
+ 0x1FA5, 0x0083, 0x0278, 0x0368, 0x021A, 0x003B, 0x1FA3,
+ 0x1FA4, 0x0076, 0x0269, 0x036A, 0x022A, 0x0046, 0x1FA3,
+ 0x1FA4, 0x006A, 0x0259, 0x036A, 0x023A, 0x0052, 0x1FA3,
+ },
+ [HS_LT_10_16_SCALE] = {
+ /* Luma */
+ 0x1F8D, 0x000C, 0x026A, 0x03FA, 0x026A, 0x000C, 0x1F8D,
+ 0x1F8F, 0x0000, 0x0255, 0x03FA, 0x027F, 0x0019, 0x1F8A,
+ 0x1F92, 0x1FF5, 0x023F, 0x03F8, 0x0293, 0x0027, 0x1F88,
+ 0x1F95, 0x1FEA, 0x022A, 0x03F6, 0x02A7, 0x0034, 0x1F86,
+ 0x1F99, 0x1FDF, 0x0213, 0x03F2, 0x02BB, 0x0043, 0x1F85,
+ 0x1F9C, 0x1FD5, 0x01FE, 0x03ED, 0x02CF, 0x0052, 0x1F83,
+ 0x1FA0, 0x1FCC, 0x01E8, 0x03E7, 0x02E1, 0x0061, 0x1F83,
+ 0x1FA4, 0x1FC3, 0x01D2, 0x03E0, 0x02F4, 0x0071, 0x1F82,
+ 0x1FA7, 0x1FBB, 0x01BC, 0x03D9, 0x0306, 0x0081, 0x1F82,
+ 0x1FAB, 0x1FB4, 0x01A6, 0x03D0, 0x0317, 0x0092, 0x1F82,
+ 0x1FAF, 0x1FAD, 0x0190, 0x03C7, 0x0327, 0x00A3, 0x1F83,
+ 0x1FB3, 0x1FA7, 0x017A, 0x03BC, 0x0337, 0x00B5, 0x1F84,
+ 0x1FB8, 0x1FA1, 0x0165, 0x03B0, 0x0346, 0x00C7, 0x1F85,
+ 0x1FBC, 0x1F9C, 0x0150, 0x03A4, 0x0354, 0x00D9, 0x1F87,
+ 0x1FC0, 0x1F98, 0x013A, 0x0397, 0x0361, 0x00EC, 0x1F8A,
+ 0x1FC4, 0x1F93, 0x0126, 0x0389, 0x036F, 0x00FE, 0x1F8D,
+ 0x1F93, 0x010A, 0x0363, 0x0363, 0x010A, 0x1F93, 0x0000,
+ 0x1F8D, 0x00FE, 0x036F, 0x0389, 0x0126, 0x1F93, 0x1FC4,
+ 0x1F8A, 0x00EC, 0x0361, 0x0397, 0x013A, 0x1F98, 0x1FC0,
+ 0x1F87, 0x00D9, 0x0354, 0x03A4, 0x0150, 0x1F9C, 0x1FBC,
+ 0x1F85, 0x00C7, 0x0346, 0x03B0, 0x0165, 0x1FA1, 0x1FB8,
+ 0x1F84, 0x00B5, 0x0337, 0x03BC, 0x017A, 0x1FA7, 0x1FB3,
+ 0x1F83, 0x00A3, 0x0327, 0x03C7, 0x0190, 0x1FAD, 0x1FAF,
+ 0x1F82, 0x0092, 0x0317, 0x03D0, 0x01A6, 0x1FB4, 0x1FAB,
+ 0x1F82, 0x0081, 0x0306, 0x03D9, 0x01BC, 0x1FBB, 0x1FA7,
+ 0x1F82, 0x0071, 0x02F4, 0x03E0, 0x01D2, 0x1FC3, 0x1FA4,
+ 0x1F83, 0x0061, 0x02E1, 0x03E7, 0x01E8, 0x1FCC, 0x1FA0,
+ 0x1F83, 0x0052, 0x02CF, 0x03ED, 0x01FE, 0x1FD5, 0x1F9C,
+ 0x1F85, 0x0043, 0x02BB, 0x03F2, 0x0213, 0x1FDF, 0x1F99,
+ 0x1F86, 0x0034, 0x02A7, 0x03F6, 0x022A, 0x1FEA, 0x1F95,
+ 0x1F88, 0x0027, 0x0293, 0x03F8, 0x023F, 0x1FF5, 0x1F92,
+ 0x1F8A, 0x0019, 0x027F, 0x03FA, 0x0255, 0x0000, 0x1F8F,
+ /* Chroma */
+ 0x1F8D, 0x000C, 0x026A, 0x03FA, 0x026A, 0x000C, 0x1F8D,
+ 0x1F8F, 0x0000, 0x0255, 0x03FA, 0x027F, 0x0019, 0x1F8A,
+ 0x1F92, 0x1FF5, 0x023F, 0x03F8, 0x0293, 0x0027, 0x1F88,
+ 0x1F95, 0x1FEA, 0x022A, 0x03F6, 0x02A7, 0x0034, 0x1F86,
+ 0x1F99, 0x1FDF, 0x0213, 0x03F2, 0x02BB, 0x0043, 0x1F85,
+ 0x1F9C, 0x1FD5, 0x01FE, 0x03ED, 0x02CF, 0x0052, 0x1F83,
+ 0x1FA0, 0x1FCC, 0x01E8, 0x03E7, 0x02E1, 0x0061, 0x1F83,
+ 0x1FA4, 0x1FC3, 0x01D2, 0x03E0, 0x02F4, 0x0071, 0x1F82,
+ 0x1FA7, 0x1FBB, 0x01BC, 0x03D9, 0x0306, 0x0081, 0x1F82,
+ 0x1FAB, 0x1FB4, 0x01A6, 0x03D0, 0x0317, 0x0092, 0x1F82,
+ 0x1FAF, 0x1FAD, 0x0190, 0x03C7, 0x0327, 0x00A3, 0x1F83,
+ 0x1FB3, 0x1FA7, 0x017A, 0x03BC, 0x0337, 0x00B5, 0x1F84,
+ 0x1FB8, 0x1FA1, 0x0165, 0x03B0, 0x0346, 0x00C7, 0x1F85,
+ 0x1FBC, 0x1F9C, 0x0150, 0x03A4, 0x0354, 0x00D9, 0x1F87,
+ 0x1FC0, 0x1F98, 0x013A, 0x0397, 0x0361, 0x00EC, 0x1F8A,
+ 0x1FC4, 0x1F93, 0x0126, 0x0389, 0x036F, 0x00FE, 0x1F8D,
+ 0x1F93, 0x010A, 0x0363, 0x0363, 0x010A, 0x1F93, 0x0000,
+ 0x1F8D, 0x00FE, 0x036F, 0x0389, 0x0126, 0x1F93, 0x1FC4,
+ 0x1F8A, 0x00EC, 0x0361, 0x0397, 0x013A, 0x1F98, 0x1FC0,
+ 0x1F87, 0x00D9, 0x0354, 0x03A4, 0x0150, 0x1F9C, 0x1FBC,
+ 0x1F85, 0x00C7, 0x0346, 0x03B0, 0x0165, 0x1FA1, 0x1FB8,
+ 0x1F84, 0x00B5, 0x0337, 0x03BC, 0x017A, 0x1FA7, 0x1FB3,
+ 0x1F83, 0x00A3, 0x0327, 0x03C7, 0x0190, 0x1FAD, 0x1FAF,
+ 0x1F82, 0x0092, 0x0317, 0x03D0, 0x01A6, 0x1FB4, 0x1FAB,
+ 0x1F82, 0x0081, 0x0306, 0x03D9, 0x01BC, 0x1FBB, 0x1FA7,
+ 0x1F82, 0x0071, 0x02F4, 0x03E0, 0x01D2, 0x1FC3, 0x1FA4,
+ 0x1F83, 0x0061, 0x02E1, 0x03E7, 0x01E8, 0x1FCC, 0x1FA0,
+ 0x1F83, 0x0052, 0x02CF, 0x03ED, 0x01FE, 0x1FD5, 0x1F9C,
+ 0x1F85, 0x0043, 0x02BB, 0x03F2, 0x0213, 0x1FDF, 0x1F99,
+ 0x1F86, 0x0034, 0x02A7, 0x03F6, 0x022A, 0x1FEA, 0x1F95,
+ 0x1F88, 0x0027, 0x0293, 0x03F8, 0x023F, 0x1FF5, 0x1F92,
+ 0x1F8A, 0x0019, 0x027F, 0x03FA, 0x0255, 0x0000, 0x1F8F,
+ },
+ [HS_LT_11_16_SCALE] = {
+ /* Luma */
+ 0x1F95, 0x1FB5, 0x0272, 0x0488, 0x0272, 0x1FB5, 0x1F95,
+ 0x1F9B, 0x1FAA, 0x0257, 0x0486, 0x028D, 0x1FC1, 0x1F90,
+ 0x1FA0, 0x1FA0, 0x023C, 0x0485, 0x02A8, 0x1FCD, 0x1F8A,
+ 0x1FA6, 0x1F96, 0x0221, 0x0481, 0x02C2, 0x1FDB, 0x1F85,
+ 0x1FAC, 0x1F8E, 0x0205, 0x047C, 0x02DC, 0x1FE9, 0x1F80,
+ 0x1FB1, 0x1F86, 0x01E9, 0x0476, 0x02F6, 0x1FF8, 0x1F7C,
+ 0x1FB7, 0x1F7F, 0x01CE, 0x046E, 0x030F, 0x0008, 0x1F77,
+ 0x1FBD, 0x1F79, 0x01B3, 0x0465, 0x0326, 0x0019, 0x1F73,
+ 0x1FC3, 0x1F73, 0x0197, 0x045B, 0x033E, 0x002A, 0x1F70,
+ 0x1FC8, 0x1F6F, 0x017D, 0x044E, 0x0355, 0x003C, 0x1F6D,
+ 0x1FCE, 0x1F6B, 0x0162, 0x0441, 0x036B, 0x004F, 0x1F6A,
+ 0x1FD3, 0x1F68, 0x0148, 0x0433, 0x0380, 0x0063, 0x1F67,
+ 0x1FD8, 0x1F65, 0x012E, 0x0424, 0x0395, 0x0077, 0x1F65,
+ 0x1FDE, 0x1F63, 0x0115, 0x0413, 0x03A8, 0x008B, 0x1F64,
+ 0x1FE3, 0x1F62, 0x00FC, 0x0403, 0x03BA, 0x00A0, 0x1F62,
+ 0x1FE7, 0x1F62, 0x00E4, 0x03EF, 0x03CC, 0x00B6, 0x1F62,
+ 0x1F63, 0x00CA, 0x03D3, 0x03D3, 0x00CA, 0x1F63, 0x0000,
+ 0x1F62, 0x00B6, 0x03CC, 0x03EF, 0x00E4, 0x1F62, 0x1FE7,
+ 0x1F62, 0x00A0, 0x03BA, 0x0403, 0x00FC, 0x1F62, 0x1FE3,
+ 0x1F64, 0x008B, 0x03A8, 0x0413, 0x0115, 0x1F63, 0x1FDE,
+ 0x1F65, 0x0077, 0x0395, 0x0424, 0x012E, 0x1F65, 0x1FD8,
+ 0x1F67, 0x0063, 0x0380, 0x0433, 0x0148, 0x1F68, 0x1FD3,
+ 0x1F6A, 0x004F, 0x036B, 0x0441, 0x0162, 0x1F6B, 0x1FCE,
+ 0x1F6D, 0x003C, 0x0355, 0x044E, 0x017D, 0x1F6F, 0x1FC8,
+ 0x1F70, 0x002A, 0x033E, 0x045B, 0x0197, 0x1F73, 0x1FC3,
+ 0x1F73, 0x0019, 0x0326, 0x0465, 0x01B3, 0x1F79, 0x1FBD,
+ 0x1F77, 0x0008, 0x030F, 0x046E, 0x01CE, 0x1F7F, 0x1FB7,
+ 0x1F7C, 0x1FF8, 0x02F6, 0x0476, 0x01E9, 0x1F86, 0x1FB1,
+ 0x1F80, 0x1FE9, 0x02DC, 0x047C, 0x0205, 0x1F8E, 0x1FAC,
+ 0x1F85, 0x1FDB, 0x02C2, 0x0481, 0x0221, 0x1F96, 0x1FA6,
+ 0x1F8A, 0x1FCD, 0x02A8, 0x0485, 0x023C, 0x1FA0, 0x1FA0,
+ 0x1F90, 0x1FC1, 0x028D, 0x0486, 0x0257, 0x1FAA, 0x1F9B,
+ /* Chroma */
+ 0x1F95, 0x1FB5, 0x0272, 0x0488, 0x0272, 0x1FB5, 0x1F95,
+ 0x1F9B, 0x1FAA, 0x0257, 0x0486, 0x028D, 0x1FC1, 0x1F90,
+ 0x1FA0, 0x1FA0, 0x023C, 0x0485, 0x02A8, 0x1FCD, 0x1F8A,
+ 0x1FA6, 0x1F96, 0x0221, 0x0481, 0x02C2, 0x1FDB, 0x1F85,
+ 0x1FAC, 0x1F8E, 0x0205, 0x047C, 0x02DC, 0x1FE9, 0x1F80,
+ 0x1FB1, 0x1F86, 0x01E9, 0x0476, 0x02F6, 0x1FF8, 0x1F7C,
+ 0x1FB7, 0x1F7F, 0x01CE, 0x046E, 0x030F, 0x0008, 0x1F77,
+ 0x1FBD, 0x1F79, 0x01B3, 0x0465, 0x0326, 0x0019, 0x1F73,
+ 0x1FC3, 0x1F73, 0x0197, 0x045B, 0x033E, 0x002A, 0x1F70,
+ 0x1FC8, 0x1F6F, 0x017D, 0x044E, 0x0355, 0x003C, 0x1F6D,
+ 0x1FCE, 0x1F6B, 0x0162, 0x0441, 0x036B, 0x004F, 0x1F6A,
+ 0x1FD3, 0x1F68, 0x0148, 0x0433, 0x0380, 0x0063, 0x1F67,
+ 0x1FD8, 0x1F65, 0x012E, 0x0424, 0x0395, 0x0077, 0x1F65,
+ 0x1FDE, 0x1F63, 0x0115, 0x0413, 0x03A8, 0x008B, 0x1F64,
+ 0x1FE3, 0x1F62, 0x00FC, 0x0403, 0x03BA, 0x00A0, 0x1F62,
+ 0x1FE7, 0x1F62, 0x00E4, 0x03EF, 0x03CC, 0x00B6, 0x1F62,
+ 0x1F63, 0x00CA, 0x03D3, 0x03D3, 0x00CA, 0x1F63, 0x0000,
+ 0x1F62, 0x00B6, 0x03CC, 0x03EF, 0x00E4, 0x1F62, 0x1FE7,
+ 0x1F62, 0x00A0, 0x03BA, 0x0403, 0x00FC, 0x1F62, 0x1FE3,
+ 0x1F64, 0x008B, 0x03A8, 0x0413, 0x0115, 0x1F63, 0x1FDE,
+ 0x1F65, 0x0077, 0x0395, 0x0424, 0x012E, 0x1F65, 0x1FD8,
+ 0x1F67, 0x0063, 0x0380, 0x0433, 0x0148, 0x1F68, 0x1FD3,
+ 0x1F6A, 0x004F, 0x036B, 0x0441, 0x0162, 0x1F6B, 0x1FCE,
+ 0x1F6D, 0x003C, 0x0355, 0x044E, 0x017D, 0x1F6F, 0x1FC8,
+ 0x1F70, 0x002A, 0x033E, 0x045B, 0x0197, 0x1F73, 0x1FC3,
+ 0x1F73, 0x0019, 0x0326, 0x0465, 0x01B3, 0x1F79, 0x1FBD,
+ 0x1F77, 0x0008, 0x030F, 0x046E, 0x01CE, 0x1F7F, 0x1FB7,
+ 0x1F7C, 0x1FF8, 0x02F6, 0x0476, 0x01E9, 0x1F86, 0x1FB1,
+ 0x1F80, 0x1FE9, 0x02DC, 0x047C, 0x0205, 0x1F8E, 0x1FAC,
+ 0x1F85, 0x1FDB, 0x02C2, 0x0481, 0x0221, 0x1F96, 0x1FA6,
+ 0x1F8A, 0x1FCD, 0x02A8, 0x0485, 0x023C, 0x1FA0, 0x1FA0,
+ 0x1F90, 0x1FC1, 0x028D, 0x0486, 0x0257, 0x1FAA, 0x1F9B,
+ },
+ [HS_LT_12_16_SCALE] = {
+ /* Luma */
+ 0x1FBB, 0x1F65, 0x025E, 0x0504, 0x025E, 0x1F65, 0x1FBB,
+ 0x1FC3, 0x1F5D, 0x023C, 0x0503, 0x027F, 0x1F6E, 0x1FB4,
+ 0x1FCA, 0x1F56, 0x021B, 0x0501, 0x02A0, 0x1F78, 0x1FAC,
+ 0x1FD1, 0x1F50, 0x01FA, 0x04FD, 0x02C0, 0x1F83, 0x1FA5,
+ 0x1FD8, 0x1F4B, 0x01D9, 0x04F6, 0x02E1, 0x1F90, 0x1F9D,
+ 0x1FDF, 0x1F47, 0x01B8, 0x04EF, 0x0301, 0x1F9D, 0x1F95,
+ 0x1FE6, 0x1F43, 0x0198, 0x04E5, 0x0321, 0x1FAB, 0x1F8E,
+ 0x1FEC, 0x1F41, 0x0178, 0x04DA, 0x0340, 0x1FBB, 0x1F86,
+ 0x1FF2, 0x1F40, 0x0159, 0x04CC, 0x035E, 0x1FCC, 0x1F7F,
+ 0x1FF8, 0x1F40, 0x013A, 0x04BE, 0x037B, 0x1FDD, 0x1F78,
+ 0x1FFE, 0x1F40, 0x011B, 0x04AD, 0x0398, 0x1FF0, 0x1F72,
+ 0x0003, 0x1F41, 0x00FD, 0x049C, 0x03B4, 0x0004, 0x1F6B,
+ 0x0008, 0x1F43, 0x00E0, 0x0489, 0x03CE, 0x0019, 0x1F65,
+ 0x000D, 0x1F46, 0x00C4, 0x0474, 0x03E8, 0x002E, 0x1F5F,
+ 0x0011, 0x1F49, 0x00A9, 0x045E, 0x0400, 0x0045, 0x1F5A,
+ 0x0015, 0x1F4D, 0x008E, 0x0447, 0x0418, 0x005C, 0x1F55,
+ 0x1F4F, 0x0076, 0x043B, 0x043B, 0x0076, 0x1F4F, 0x0000,
+ 0x1F55, 0x005C, 0x0418, 0x0447, 0x008E, 0x1F4D, 0x0015,
+ 0x1F5A, 0x0045, 0x0400, 0x045E, 0x00A9, 0x1F49, 0x0011,
+ 0x1F5F, 0x002E, 0x03E8, 0x0474, 0x00C4, 0x1F46, 0x000D,
+ 0x1F65, 0x0019, 0x03CE, 0x0489, 0x00E0, 0x1F43, 0x0008,
+ 0x1F6B, 0x0004, 0x03B4, 0x049C, 0x00FD, 0x1F41, 0x0003,
+ 0x1F72, 0x1FF0, 0x0398, 0x04AD, 0x011B, 0x1F40, 0x1FFE,
+ 0x1F78, 0x1FDD, 0x037B, 0x04BE, 0x013A, 0x1F40, 0x1FF8,
+ 0x1F7F, 0x1FCC, 0x035E, 0x04CC, 0x0159, 0x1F40, 0x1FF2,
+ 0x1F86, 0x1FBB, 0x0340, 0x04DA, 0x0178, 0x1F41, 0x1FEC,
+ 0x1F8E, 0x1FAB, 0x0321, 0x04E5, 0x0198, 0x1F43, 0x1FE6,
+ 0x1F95, 0x1F9D, 0x0301, 0x04EF, 0x01B8, 0x1F47, 0x1FDF,
+ 0x1F9D, 0x1F90, 0x02E1, 0x04F6, 0x01D9, 0x1F4B, 0x1FD8,
+ 0x1FA5, 0x1F83, 0x02C0, 0x04FD, 0x01FA, 0x1F50, 0x1FD1,
+ 0x1FAC, 0x1F78, 0x02A0, 0x0501, 0x021B, 0x1F56, 0x1FCA,
+ 0x1FB4, 0x1F6E, 0x027F, 0x0503, 0x023C, 0x1F5D, 0x1FC3,
+ /* Chroma */
+ 0x1FBB, 0x1F65, 0x025E, 0x0504, 0x025E, 0x1F65, 0x1FBB,
+ 0x1FC3, 0x1F5D, 0x023C, 0x0503, 0x027F, 0x1F6E, 0x1FB4,
+ 0x1FCA, 0x1F56, 0x021B, 0x0501, 0x02A0, 0x1F78, 0x1FAC,
+ 0x1FD1, 0x1F50, 0x01FA, 0x04FD, 0x02C0, 0x1F83, 0x1FA5,
+ 0x1FD8, 0x1F4B, 0x01D9, 0x04F6, 0x02E1, 0x1F90, 0x1F9D,
+ 0x1FDF, 0x1F47, 0x01B8, 0x04EF, 0x0301, 0x1F9D, 0x1F95,
+ 0x1FE6, 0x1F43, 0x0198, 0x04E5, 0x0321, 0x1FAB, 0x1F8E,
+ 0x1FEC, 0x1F41, 0x0178, 0x04DA, 0x0340, 0x1FBB, 0x1F86,
+ 0x1FF2, 0x1F40, 0x0159, 0x04CC, 0x035E, 0x1FCC, 0x1F7F,
+ 0x1FF8, 0x1F40, 0x013A, 0x04BE, 0x037B, 0x1FDD, 0x1F78,
+ 0x1FFE, 0x1F40, 0x011B, 0x04AD, 0x0398, 0x1FF0, 0x1F72,
+ 0x0003, 0x1F41, 0x00FD, 0x049C, 0x03B4, 0x0004, 0x1F6B,
+ 0x0008, 0x1F43, 0x00E0, 0x0489, 0x03CE, 0x0019, 0x1F65,
+ 0x000D, 0x1F46, 0x00C4, 0x0474, 0x03E8, 0x002E, 0x1F5F,
+ 0x0011, 0x1F49, 0x00A9, 0x045E, 0x0400, 0x0045, 0x1F5A,
+ 0x0015, 0x1F4D, 0x008E, 0x0447, 0x0418, 0x005C, 0x1F55,
+ 0x1F4F, 0x0076, 0x043B, 0x043B, 0x0076, 0x1F4F, 0x0000,
+ 0x1F55, 0x005C, 0x0418, 0x0447, 0x008E, 0x1F4D, 0x0015,
+ 0x1F5A, 0x0045, 0x0400, 0x045E, 0x00A9, 0x1F49, 0x0011,
+ 0x1F5F, 0x002E, 0x03E8, 0x0474, 0x00C4, 0x1F46, 0x000D,
+ 0x1F65, 0x0019, 0x03CE, 0x0489, 0x00E0, 0x1F43, 0x0008,
+ 0x1F6B, 0x0004, 0x03B4, 0x049C, 0x00FD, 0x1F41, 0x0003,
+ 0x1F72, 0x1FF0, 0x0398, 0x04AD, 0x011B, 0x1F40, 0x1FFE,
+ 0x1F78, 0x1FDD, 0x037B, 0x04BE, 0x013A, 0x1F40, 0x1FF8,
+ 0x1F7F, 0x1FCC, 0x035E, 0x04CC, 0x0159, 0x1F40, 0x1FF2,
+ 0x1F86, 0x1FBB, 0x0340, 0x04DA, 0x0178, 0x1F41, 0x1FEC,
+ 0x1F8E, 0x1FAB, 0x0321, 0x04E5, 0x0198, 0x1F43, 0x1FE6,
+ 0x1F95, 0x1F9D, 0x0301, 0x04EF, 0x01B8, 0x1F47, 0x1FDF,
+ 0x1F9D, 0x1F90, 0x02E1, 0x04F6, 0x01D9, 0x1F4B, 0x1FD8,
+ 0x1FA5, 0x1F83, 0x02C0, 0x04FD, 0x01FA, 0x1F50, 0x1FD1,
+ 0x1FAC, 0x1F78, 0x02A0, 0x0501, 0x021B, 0x1F56, 0x1FCA,
+ 0x1FB4, 0x1F6E, 0x027F, 0x0503, 0x023C, 0x1F5D, 0x1FC3,
+ },
+ [HS_LT_13_16_SCALE] = {
+ /* Luma */
+ 0x1FF4, 0x1F29, 0x022D, 0x056C, 0x022D, 0x1F29, 0x1FF4,
+ 0x1FFC, 0x1F26, 0x0206, 0x056A, 0x0254, 0x1F2E, 0x1FEC,
+ 0x0003, 0x1F24, 0x01E0, 0x0567, 0x027A, 0x1F34, 0x1FE4,
+ 0x000A, 0x1F23, 0x01BA, 0x0561, 0x02A2, 0x1F3B, 0x1FDB,
+ 0x0011, 0x1F22, 0x0194, 0x055B, 0x02C9, 0x1F43, 0x1FD2,
+ 0x0017, 0x1F23, 0x016F, 0x0551, 0x02F0, 0x1F4D, 0x1FC9,
+ 0x001D, 0x1F25, 0x014B, 0x0545, 0x0316, 0x1F58, 0x1FC0,
+ 0x0022, 0x1F28, 0x0127, 0x0538, 0x033C, 0x1F65, 0x1FB6,
+ 0x0027, 0x1F2C, 0x0104, 0x0528, 0x0361, 0x1F73, 0x1FAD,
+ 0x002B, 0x1F30, 0x00E2, 0x0518, 0x0386, 0x1F82, 0x1FA3,
+ 0x002F, 0x1F36, 0x00C2, 0x0504, 0x03AA, 0x1F92, 0x1F99,
+ 0x0032, 0x1F3C, 0x00A2, 0x04EF, 0x03CD, 0x1FA4, 0x1F90,
+ 0x0035, 0x1F42, 0x0083, 0x04D9, 0x03EF, 0x1FB8, 0x1F86,
+ 0x0038, 0x1F49, 0x0065, 0x04C0, 0x0410, 0x1FCD, 0x1F7D,
+ 0x003A, 0x1F51, 0x0048, 0x04A6, 0x0431, 0x1FE3, 0x1F73,
+ 0x003C, 0x1F59, 0x002D, 0x048A, 0x0450, 0x1FFA, 0x1F6A,
+ 0x1F5D, 0x0014, 0x048F, 0x048F, 0x0014, 0x1F5D, 0x0000,
+ 0x1F6A, 0x1FFA, 0x0450, 0x048A, 0x002D, 0x1F59, 0x003C,
+ 0x1F73, 0x1FE3, 0x0431, 0x04A6, 0x0048, 0x1F51, 0x003A,
+ 0x1F7D, 0x1FCD, 0x0410, 0x04C0, 0x0065, 0x1F49, 0x0038,
+ 0x1F86, 0x1FB8, 0x03EF, 0x04D9, 0x0083, 0x1F42, 0x0035,
+ 0x1F90, 0x1FA4, 0x03CD, 0x04EF, 0x00A2, 0x1F3C, 0x0032,
+ 0x1F99, 0x1F92, 0x03AA, 0x0504, 0x00C2, 0x1F36, 0x002F,
+ 0x1FA3, 0x1F82, 0x0386, 0x0518, 0x00E2, 0x1F30, 0x002B,
+ 0x1FAD, 0x1F73, 0x0361, 0x0528, 0x0104, 0x1F2C, 0x0027,
+ 0x1FB6, 0x1F65, 0x033C, 0x0538, 0x0127, 0x1F28, 0x0022,
+ 0x1FC0, 0x1F58, 0x0316, 0x0545, 0x014B, 0x1F25, 0x001D,
+ 0x1FC9, 0x1F4D, 0x02F0, 0x0551, 0x016F, 0x1F23, 0x0017,
+ 0x1FD2, 0x1F43, 0x02C9, 0x055B, 0x0194, 0x1F22, 0x0011,
+ 0x1FDB, 0x1F3B, 0x02A2, 0x0561, 0x01BA, 0x1F23, 0x000A,
+ 0x1FE4, 0x1F34, 0x027A, 0x0567, 0x01E0, 0x1F24, 0x0003,
+ 0x1FEC, 0x1F2E, 0x0254, 0x056A, 0x0206, 0x1F26, 0x1FFC,
+ /* Chroma */
+ 0x1FF4, 0x1F29, 0x022D, 0x056C, 0x022D, 0x1F29, 0x1FF4,
+ 0x1FFC, 0x1F26, 0x0206, 0x056A, 0x0254, 0x1F2E, 0x1FEC,
+ 0x0003, 0x1F24, 0x01E0, 0x0567, 0x027A, 0x1F34, 0x1FE4,
+ 0x000A, 0x1F23, 0x01BA, 0x0561, 0x02A2, 0x1F3B, 0x1FDB,
+ 0x0011, 0x1F22, 0x0194, 0x055B, 0x02C9, 0x1F43, 0x1FD2,
+ 0x0017, 0x1F23, 0x016F, 0x0551, 0x02F0, 0x1F4D, 0x1FC9,
+ 0x001D, 0x1F25, 0x014B, 0x0545, 0x0316, 0x1F58, 0x1FC0,
+ 0x0022, 0x1F28, 0x0127, 0x0538, 0x033C, 0x1F65, 0x1FB6,
+ 0x0027, 0x1F2C, 0x0104, 0x0528, 0x0361, 0x1F73, 0x1FAD,
+ 0x002B, 0x1F30, 0x00E2, 0x0518, 0x0386, 0x1F82, 0x1FA3,
+ 0x002F, 0x1F36, 0x00C2, 0x0504, 0x03AA, 0x1F92, 0x1F99,
+ 0x0032, 0x1F3C, 0x00A2, 0x04EF, 0x03CD, 0x1FA4, 0x1F90,
+ 0x0035, 0x1F42, 0x0083, 0x04D9, 0x03EF, 0x1FB8, 0x1F86,
+ 0x0038, 0x1F49, 0x0065, 0x04C0, 0x0410, 0x1FCD, 0x1F7D,
+ 0x003A, 0x1F51, 0x0048, 0x04A6, 0x0431, 0x1FE3, 0x1F73,
+ 0x003C, 0x1F59, 0x002D, 0x048A, 0x0450, 0x1FFA, 0x1F6A,
+ 0x1F5D, 0x0014, 0x048F, 0x048F, 0x0014, 0x1F5D, 0x0000,
+ 0x1F6A, 0x1FFA, 0x0450, 0x048A, 0x002D, 0x1F59, 0x003C,
+ 0x1F73, 0x1FE3, 0x0431, 0x04A6, 0x0048, 0x1F51, 0x003A,
+ 0x1F7D, 0x1FCD, 0x0410, 0x04C0, 0x0065, 0x1F49, 0x0038,
+ 0x1F86, 0x1FB8, 0x03EF, 0x04D9, 0x0083, 0x1F42, 0x0035,
+ 0x1F90, 0x1FA4, 0x03CD, 0x04EF, 0x00A2, 0x1F3C, 0x0032,
+ 0x1F99, 0x1F92, 0x03AA, 0x0504, 0x00C2, 0x1F36, 0x002F,
+ 0x1FA3, 0x1F82, 0x0386, 0x0518, 0x00E2, 0x1F30, 0x002B,
+ 0x1FAD, 0x1F73, 0x0361, 0x0528, 0x0104, 0x1F2C, 0x0027,
+ 0x1FB6, 0x1F65, 0x033C, 0x0538, 0x0127, 0x1F28, 0x0022,
+ 0x1FC0, 0x1F58, 0x0316, 0x0545, 0x014B, 0x1F25, 0x001D,
+ 0x1FC9, 0x1F4D, 0x02F0, 0x0551, 0x016F, 0x1F23, 0x0017,
+ 0x1FD2, 0x1F43, 0x02C9, 0x055B, 0x0194, 0x1F22, 0x0011,
+ 0x1FDB, 0x1F3B, 0x02A2, 0x0561, 0x01BA, 0x1F23, 0x000A,
+ 0x1FE4, 0x1F34, 0x027A, 0x0567, 0x01E0, 0x1F24, 0x0003,
+ 0x1FEC, 0x1F2E, 0x0254, 0x056A, 0x0206, 0x1F26, 0x1FFC,
+ },
+ [HS_LT_14_16_SCALE] = {
+ /* Luma */
+ 0x002F, 0x1F0B, 0x01E7, 0x05BE, 0x01E7, 0x1F0B, 0x002F,
+ 0x0035, 0x1F0D, 0x01BC, 0x05BD, 0x0213, 0x1F0A, 0x0028,
+ 0x003A, 0x1F11, 0x0191, 0x05BA, 0x023F, 0x1F0A, 0x0021,
+ 0x003F, 0x1F15, 0x0167, 0x05B3, 0x026C, 0x1F0C, 0x001A,
+ 0x0043, 0x1F1B, 0x013E, 0x05AA, 0x0299, 0x1F0F, 0x0012,
+ 0x0046, 0x1F21, 0x0116, 0x05A1, 0x02C6, 0x1F13, 0x0009,
+ 0x0049, 0x1F28, 0x00EF, 0x0593, 0x02F4, 0x1F19, 0x0000,
+ 0x004C, 0x1F30, 0x00C9, 0x0584, 0x0321, 0x1F20, 0x1FF6,
+ 0x004E, 0x1F39, 0x00A4, 0x0572, 0x034D, 0x1F2A, 0x1FEC,
+ 0x004F, 0x1F43, 0x0080, 0x055E, 0x037A, 0x1F34, 0x1FE2,
+ 0x0050, 0x1F4D, 0x005E, 0x0548, 0x03A5, 0x1F41, 0x1FD7,
+ 0x0050, 0x1F57, 0x003D, 0x0531, 0x03D1, 0x1F4F, 0x1FCB,
+ 0x0050, 0x1F62, 0x001E, 0x0516, 0x03FB, 0x1F5F, 0x1FC0,
+ 0x004F, 0x1F6D, 0x0000, 0x04FA, 0x0425, 0x1F71, 0x1FB4,
+ 0x004E, 0x1F79, 0x1FE4, 0x04DC, 0x044D, 0x1F84, 0x1FA8,
+ 0x004D, 0x1F84, 0x1FCA, 0x04BC, 0x0474, 0x1F99, 0x1F9C,
+ 0x1F8C, 0x1FAE, 0x04C6, 0x04C6, 0x1FAE, 0x1F8C, 0x0000,
+ 0x1F9C, 0x1F99, 0x0474, 0x04BC, 0x1FCA, 0x1F84, 0x004D,
+ 0x1FA8, 0x1F84, 0x044D, 0x04DC, 0x1FE4, 0x1F79, 0x004E,
+ 0x1FB4, 0x1F71, 0x0425, 0x04FA, 0x0000, 0x1F6D, 0x004F,
+ 0x1FC0, 0x1F5F, 0x03FB, 0x0516, 0x001E, 0x1F62, 0x0050,
+ 0x1FCB, 0x1F4F, 0x03D1, 0x0531, 0x003D, 0x1F57, 0x0050,
+ 0x1FD7, 0x1F41, 0x03A5, 0x0548, 0x005E, 0x1F4D, 0x0050,
+ 0x1FE2, 0x1F34, 0x037A, 0x055E, 0x0080, 0x1F43, 0x004F,
+ 0x1FEC, 0x1F2A, 0x034D, 0x0572, 0x00A4, 0x1F39, 0x004E,
+ 0x1FF6, 0x1F20, 0x0321, 0x0584, 0x00C9, 0x1F30, 0x004C,
+ 0x0000, 0x1F19, 0x02F4, 0x0593, 0x00EF, 0x1F28, 0x0049,
+ 0x0009, 0x1F13, 0x02C6, 0x05A1, 0x0116, 0x1F21, 0x0046,
+ 0x0012, 0x1F0F, 0x0299, 0x05AA, 0x013E, 0x1F1B, 0x0043,
+ 0x001A, 0x1F0C, 0x026C, 0x05B3, 0x0167, 0x1F15, 0x003F,
+ 0x0021, 0x1F0A, 0x023F, 0x05BA, 0x0191, 0x1F11, 0x003A,
+ 0x0028, 0x1F0A, 0x0213, 0x05BD, 0x01BC, 0x1F0D, 0x0035,
+ /* Chroma */
+ 0x002F, 0x1F0B, 0x01E7, 0x05BE, 0x01E7, 0x1F0B, 0x002F,
+ 0x0035, 0x1F0D, 0x01BC, 0x05BD, 0x0213, 0x1F0A, 0x0028,
+ 0x003A, 0x1F11, 0x0191, 0x05BA, 0x023F, 0x1F0A, 0x0021,
+ 0x003F, 0x1F15, 0x0167, 0x05B3, 0x026C, 0x1F0C, 0x001A,
+ 0x0043, 0x1F1B, 0x013E, 0x05AA, 0x0299, 0x1F0F, 0x0012,
+ 0x0046, 0x1F21, 0x0116, 0x05A1, 0x02C6, 0x1F13, 0x0009,
+ 0x0049, 0x1F28, 0x00EF, 0x0593, 0x02F4, 0x1F19, 0x0000,
+ 0x004C, 0x1F30, 0x00C9, 0x0584, 0x0321, 0x1F20, 0x1FF6,
+ 0x004E, 0x1F39, 0x00A4, 0x0572, 0x034D, 0x1F2A, 0x1FEC,
+ 0x004F, 0x1F43, 0x0080, 0x055E, 0x037A, 0x1F34, 0x1FE2,
+ 0x0050, 0x1F4D, 0x005E, 0x0548, 0x03A5, 0x1F41, 0x1FD7,
+ 0x0050, 0x1F57, 0x003D, 0x0531, 0x03D1, 0x1F4F, 0x1FCB,
+ 0x0050, 0x1F62, 0x001E, 0x0516, 0x03FB, 0x1F5F, 0x1FC0,
+ 0x004F, 0x1F6D, 0x0000, 0x04FA, 0x0425, 0x1F71, 0x1FB4,
+ 0x004E, 0x1F79, 0x1FE4, 0x04DC, 0x044D, 0x1F84, 0x1FA8,
+ 0x004D, 0x1F84, 0x1FCA, 0x04BC, 0x0474, 0x1F99, 0x1F9C,
+ 0x1F8C, 0x1FAE, 0x04C6, 0x04C6, 0x1FAE, 0x1F8C, 0x0000,
+ 0x1F9C, 0x1F99, 0x0474, 0x04BC, 0x1FCA, 0x1F84, 0x004D,
+ 0x1FA8, 0x1F84, 0x044D, 0x04DC, 0x1FE4, 0x1F79, 0x004E,
+ 0x1FB4, 0x1F71, 0x0425, 0x04FA, 0x0000, 0x1F6D, 0x004F,
+ 0x1FC0, 0x1F5F, 0x03FB, 0x0516, 0x001E, 0x1F62, 0x0050,
+ 0x1FCB, 0x1F4F, 0x03D1, 0x0531, 0x003D, 0x1F57, 0x0050,
+ 0x1FD7, 0x1F41, 0x03A5, 0x0548, 0x005E, 0x1F4D, 0x0050,
+ 0x1FE2, 0x1F34, 0x037A, 0x055E, 0x0080, 0x1F43, 0x004F,
+ 0x1FEC, 0x1F2A, 0x034D, 0x0572, 0x00A4, 0x1F39, 0x004E,
+ 0x1FF6, 0x1F20, 0x0321, 0x0584, 0x00C9, 0x1F30, 0x004C,
+ 0x0000, 0x1F19, 0x02F4, 0x0593, 0x00EF, 0x1F28, 0x0049,
+ 0x0009, 0x1F13, 0x02C6, 0x05A1, 0x0116, 0x1F21, 0x0046,
+ 0x0012, 0x1F0F, 0x0299, 0x05AA, 0x013E, 0x1F1B, 0x0043,
+ 0x001A, 0x1F0C, 0x026C, 0x05B3, 0x0167, 0x1F15, 0x003F,
+ 0x0021, 0x1F0A, 0x023F, 0x05BA, 0x0191, 0x1F11, 0x003A,
+ 0x0028, 0x1F0A, 0x0213, 0x05BD, 0x01BC, 0x1F0D, 0x0035,
+ },
+ [HS_LT_15_16_SCALE] = {
+ /* Luma */
+ 0x005B, 0x1F0A, 0x0195, 0x060C, 0x0195, 0x1F0A, 0x005B,
+ 0x005D, 0x1F13, 0x0166, 0x0609, 0x01C6, 0x1F03, 0x0058,
+ 0x005F, 0x1F1C, 0x0138, 0x0605, 0x01F7, 0x1EFD, 0x0054,
+ 0x0060, 0x1F26, 0x010B, 0x05FF, 0x0229, 0x1EF8, 0x004F,
+ 0x0060, 0x1F31, 0x00DF, 0x05F5, 0x025C, 0x1EF5, 0x004A,
+ 0x0060, 0x1F3D, 0x00B5, 0x05E8, 0x028F, 0x1EF3, 0x0044,
+ 0x005F, 0x1F49, 0x008C, 0x05DA, 0x02C3, 0x1EF2, 0x003D,
+ 0x005E, 0x1F56, 0x0065, 0x05C7, 0x02F6, 0x1EF4, 0x0036,
+ 0x005C, 0x1F63, 0x003F, 0x05B3, 0x032B, 0x1EF7, 0x002D,
+ 0x0059, 0x1F71, 0x001B, 0x059D, 0x035F, 0x1EFB, 0x0024,
+ 0x0057, 0x1F7F, 0x1FF9, 0x0583, 0x0392, 0x1F02, 0x001A,
+ 0x0053, 0x1F8D, 0x1FD9, 0x0567, 0x03C5, 0x1F0B, 0x0010,
+ 0x0050, 0x1F9B, 0x1FBB, 0x0548, 0x03F8, 0x1F15, 0x0005,
+ 0x004C, 0x1FA9, 0x1F9E, 0x0528, 0x042A, 0x1F22, 0x1FF9,
+ 0x0048, 0x1FB7, 0x1F84, 0x0505, 0x045A, 0x1F31, 0x1FED,
+ 0x0043, 0x1FC5, 0x1F6C, 0x04E0, 0x048A, 0x1F42, 0x1FE0,
+ 0x1FD1, 0x1F50, 0x04DF, 0x04DF, 0x1F50, 0x1FD1, 0x0000,
+ 0x1FE0, 0x1F42, 0x048A, 0x04E0, 0x1F6C, 0x1FC5, 0x0043,
+ 0x1FED, 0x1F31, 0x045A, 0x0505, 0x1F84, 0x1FB7, 0x0048,
+ 0x1FF9, 0x1F22, 0x042A, 0x0528, 0x1F9E, 0x1FA9, 0x004C,
+ 0x0005, 0x1F15, 0x03F8, 0x0548, 0x1FBB, 0x1F9B, 0x0050,
+ 0x0010, 0x1F0B, 0x03C5, 0x0567, 0x1FD9, 0x1F8D, 0x0053,
+ 0x001A, 0x1F02, 0x0392, 0x0583, 0x1FF9, 0x1F7F, 0x0057,
+ 0x0024, 0x1EFB, 0x035F, 0x059D, 0x001B, 0x1F71, 0x0059,
+ 0x002D, 0x1EF7, 0x032B, 0x05B3, 0x003F, 0x1F63, 0x005C,
+ 0x0036, 0x1EF4, 0x02F6, 0x05C7, 0x0065, 0x1F56, 0x005E,
+ 0x003D, 0x1EF2, 0x02C3, 0x05DA, 0x008C, 0x1F49, 0x005F,
+ 0x0044, 0x1EF3, 0x028F, 0x05E8, 0x00B5, 0x1F3D, 0x0060,
+ 0x004A, 0x1EF5, 0x025C, 0x05F5, 0x00DF, 0x1F31, 0x0060,
+ 0x004F, 0x1EF8, 0x0229, 0x05FF, 0x010B, 0x1F26, 0x0060,
+ 0x0054, 0x1EFD, 0x01F7, 0x0605, 0x0138, 0x1F1C, 0x005F,
+ 0x0058, 0x1F03, 0x01C6, 0x0609, 0x0166, 0x1F13, 0x005D,
+ /* Chroma */
+ 0x005B, 0x1F0A, 0x0195, 0x060C, 0x0195, 0x1F0A, 0x005B,
+ 0x005D, 0x1F13, 0x0166, 0x0609, 0x01C6, 0x1F03, 0x0058,
+ 0x005F, 0x1F1C, 0x0138, 0x0605, 0x01F7, 0x1EFD, 0x0054,
+ 0x0060, 0x1F26, 0x010B, 0x05FF, 0x0229, 0x1EF8, 0x004F,
+ 0x0060, 0x1F31, 0x00DF, 0x05F5, 0x025C, 0x1EF5, 0x004A,
+ 0x0060, 0x1F3D, 0x00B5, 0x05E8, 0x028F, 0x1EF3, 0x0044,
+ 0x005F, 0x1F49, 0x008C, 0x05DA, 0x02C3, 0x1EF2, 0x003D,
+ 0x005E, 0x1F56, 0x0065, 0x05C7, 0x02F6, 0x1EF4, 0x0036,
+ 0x005C, 0x1F63, 0x003F, 0x05B3, 0x032B, 0x1EF7, 0x002D,
+ 0x0059, 0x1F71, 0x001B, 0x059D, 0x035F, 0x1EFB, 0x0024,
+ 0x0057, 0x1F7F, 0x1FF9, 0x0583, 0x0392, 0x1F02, 0x001A,
+ 0x0053, 0x1F8D, 0x1FD9, 0x0567, 0x03C5, 0x1F0B, 0x0010,
+ 0x0050, 0x1F9B, 0x1FBB, 0x0548, 0x03F8, 0x1F15, 0x0005,
+ 0x004C, 0x1FA9, 0x1F9E, 0x0528, 0x042A, 0x1F22, 0x1FF9,
+ 0x0048, 0x1FB7, 0x1F84, 0x0505, 0x045A, 0x1F31, 0x1FED,
+ 0x0043, 0x1FC5, 0x1F6C, 0x04E0, 0x048A, 0x1F42, 0x1FE0,
+ 0x1FD1, 0x1F50, 0x04DF, 0x04DF, 0x1F50, 0x1FD1, 0x0000,
+ 0x1FE0, 0x1F42, 0x048A, 0x04E0, 0x1F6C, 0x1FC5, 0x0043,
+ 0x1FED, 0x1F31, 0x045A, 0x0505, 0x1F84, 0x1FB7, 0x0048,
+ 0x1FF9, 0x1F22, 0x042A, 0x0528, 0x1F9E, 0x1FA9, 0x004C,
+ 0x0005, 0x1F15, 0x03F8, 0x0548, 0x1FBB, 0x1F9B, 0x0050,
+ 0x0010, 0x1F0B, 0x03C5, 0x0567, 0x1FD9, 0x1F8D, 0x0053,
+ 0x001A, 0x1F02, 0x0392, 0x0583, 0x1FF9, 0x1F7F, 0x0057,
+ 0x0024, 0x1EFB, 0x035F, 0x059D, 0x001B, 0x1F71, 0x0059,
+ 0x002D, 0x1EF7, 0x032B, 0x05B3, 0x003F, 0x1F63, 0x005C,
+ 0x0036, 0x1EF4, 0x02F6, 0x05C7, 0x0065, 0x1F56, 0x005E,
+ 0x003D, 0x1EF2, 0x02C3, 0x05DA, 0x008C, 0x1F49, 0x005F,
+ 0x0044, 0x1EF3, 0x028F, 0x05E8, 0x00B5, 0x1F3D, 0x0060,
+ 0x004A, 0x1EF5, 0x025C, 0x05F5, 0x00DF, 0x1F31, 0x0060,
+ 0x004F, 0x1EF8, 0x0229, 0x05FF, 0x010B, 0x1F26, 0x0060,
+ 0x0054, 0x1EFD, 0x01F7, 0x0605, 0x0138, 0x1F1C, 0x005F,
+ 0x0058, 0x1F03, 0x01C6, 0x0609, 0x0166, 0x1F13, 0x005D,
+ },
+ [HS_LE_16_16_SCALE] = {
+ /* Luma */
+ 0x006E, 0x1F24, 0x013E, 0x0660, 0x013E, 0x1F24, 0x006E,
+ 0x006C, 0x1F33, 0x010B, 0x065D, 0x0172, 0x1F17, 0x0070,
+ 0x0069, 0x1F41, 0x00DA, 0x0659, 0x01A8, 0x1F0B, 0x0070,
+ 0x0066, 0x1F51, 0x00AA, 0x0650, 0x01DF, 0x1F00, 0x0070,
+ 0x0062, 0x1F61, 0x007D, 0x0644, 0x0217, 0x1EF6, 0x006F,
+ 0x005E, 0x1F71, 0x0051, 0x0636, 0x0250, 0x1EED, 0x006D,
+ 0x0059, 0x1F81, 0x0028, 0x0624, 0x028A, 0x1EE5, 0x006B,
+ 0x0054, 0x1F91, 0x0000, 0x060F, 0x02C5, 0x1EE0, 0x0067,
+ 0x004E, 0x1FA2, 0x1FDB, 0x05F6, 0x0300, 0x1EDC, 0x0063,
+ 0x0049, 0x1FB2, 0x1FB8, 0x05DB, 0x033B, 0x1EDA, 0x005D,
+ 0x0043, 0x1FC3, 0x1F98, 0x05BC, 0x0376, 0x1ED9, 0x0057,
+ 0x003D, 0x1FD3, 0x1F7A, 0x059B, 0x03B1, 0x1EDB, 0x004F,
+ 0x0036, 0x1FE2, 0x1F5E, 0x0578, 0x03EC, 0x1EDF, 0x0047,
+ 0x0030, 0x1FF1, 0x1F45, 0x0551, 0x0426, 0x1EE6, 0x003D,
+ 0x002A, 0x0000, 0x1F2E, 0x0528, 0x045F, 0x1EEE, 0x0033,
+ 0x0023, 0x000E, 0x1F19, 0x04FD, 0x0498, 0x1EFA, 0x0027,
+ 0x001B, 0x1F04, 0x04E1, 0x04E1, 0x1F04, 0x001B, 0x0000,
+ 0x0027, 0x1EFA, 0x0498, 0x04FD, 0x1F19, 0x000E, 0x0023,
+ 0x0033, 0x1EEE, 0x045F, 0x0528, 0x1F2E, 0x0000, 0x002A,
+ 0x003D, 0x1EE6, 0x0426, 0x0551, 0x1F45, 0x1FF1, 0x0030,
+ 0x0047, 0x1EDF, 0x03EC, 0x0578, 0x1F5E, 0x1FE2, 0x0036,
+ 0x004F, 0x1EDB, 0x03B1, 0x059B, 0x1F7A, 0x1FD3, 0x003D,
+ 0x0057, 0x1ED9, 0x0376, 0x05BC, 0x1F98, 0x1FC3, 0x0043,
+ 0x005D, 0x1EDA, 0x033B, 0x05DB, 0x1FB8, 0x1FB2, 0x0049,
+ 0x0063, 0x1EDC, 0x0300, 0x05F6, 0x1FDB, 0x1FA2, 0x004E,
+ 0x0067, 0x1EE0, 0x02C5, 0x060F, 0x0000, 0x1F91, 0x0054,
+ 0x006B, 0x1EE5, 0x028A, 0x0624, 0x0028, 0x1F81, 0x0059,
+ 0x006D, 0x1EED, 0x0250, 0x0636, 0x0051, 0x1F71, 0x005E,
+ 0x006F, 0x1EF6, 0x0217, 0x0644, 0x007D, 0x1F61, 0x0062,
+ 0x0070, 0x1F00, 0x01DF, 0x0650, 0x00AA, 0x1F51, 0x0066,
+ 0x0070, 0x1F0B, 0x01A8, 0x0659, 0x00DA, 0x1F41, 0x0069,
+ 0x0070, 0x1F17, 0x0172, 0x065D, 0x010B, 0x1F33, 0x006C,
+ /* Chroma */
+ 0x006E, 0x1F24, 0x013E, 0x0660, 0x013E, 0x1F24, 0x006E,
+ 0x006C, 0x1F33, 0x010B, 0x065D, 0x0172, 0x1F17, 0x0070,
+ 0x0069, 0x1F41, 0x00DA, 0x0659, 0x01A8, 0x1F0B, 0x0070,
+ 0x0066, 0x1F51, 0x00AA, 0x0650, 0x01DF, 0x1F00, 0x0070,
+ 0x0062, 0x1F61, 0x007D, 0x0644, 0x0217, 0x1EF6, 0x006F,
+ 0x005E, 0x1F71, 0x0051, 0x0636, 0x0250, 0x1EED, 0x006D,
+ 0x0059, 0x1F81, 0x0028, 0x0624, 0x028A, 0x1EE5, 0x006B,
+ 0x0054, 0x1F91, 0x0000, 0x060F, 0x02C5, 0x1EE0, 0x0067,
+ 0x004E, 0x1FA2, 0x1FDB, 0x05F6, 0x0300, 0x1EDC, 0x0063,
+ 0x0049, 0x1FB2, 0x1FB8, 0x05DB, 0x033B, 0x1EDA, 0x005D,
+ 0x0043, 0x1FC3, 0x1F98, 0x05BC, 0x0376, 0x1ED9, 0x0057,
+ 0x003D, 0x1FD3, 0x1F7A, 0x059B, 0x03B1, 0x1EDB, 0x004F,
+ 0x0036, 0x1FE2, 0x1F5E, 0x0578, 0x03EC, 0x1EDF, 0x0047,
+ 0x0030, 0x1FF1, 0x1F45, 0x0551, 0x0426, 0x1EE6, 0x003D,
+ 0x002A, 0x0000, 0x1F2E, 0x0528, 0x045F, 0x1EEE, 0x0033,
+ 0x0023, 0x000E, 0x1F19, 0x04FD, 0x0498, 0x1EFA, 0x0027,
+ 0x001B, 0x1F04, 0x04E1, 0x04E1, 0x1F04, 0x001B, 0x0000,
+ 0x0027, 0x1EFA, 0x0498, 0x04FD, 0x1F19, 0x000E, 0x0023,
+ 0x0033, 0x1EEE, 0x045F, 0x0528, 0x1F2E, 0x0000, 0x002A,
+ 0x003D, 0x1EE6, 0x0426, 0x0551, 0x1F45, 0x1FF1, 0x0030,
+ 0x0047, 0x1EDF, 0x03EC, 0x0578, 0x1F5E, 0x1FE2, 0x0036,
+ 0x004F, 0x1EDB, 0x03B1, 0x059B, 0x1F7A, 0x1FD3, 0x003D,
+ 0x0057, 0x1ED9, 0x0376, 0x05BC, 0x1F98, 0x1FC3, 0x0043,
+ 0x005D, 0x1EDA, 0x033B, 0x05DB, 0x1FB8, 0x1FB2, 0x0049,
+ 0x0063, 0x1EDC, 0x0300, 0x05F6, 0x1FDB, 0x1FA2, 0x004E,
+ 0x0067, 0x1EE0, 0x02C5, 0x060F, 0x0000, 0x1F91, 0x0054,
+ 0x006B, 0x1EE5, 0x028A, 0x0624, 0x0028, 0x1F81, 0x0059,
+ 0x006D, 0x1EED, 0x0250, 0x0636, 0x0051, 0x1F71, 0x005E,
+ 0x006F, 0x1EF6, 0x0217, 0x0644, 0x007D, 0x1F61, 0x0062,
+ 0x0070, 0x1F00, 0x01DF, 0x0650, 0x00AA, 0x1F51, 0x0066,
+ 0x0070, 0x1F0B, 0x01A8, 0x0659, 0x00DA, 0x1F41, 0x0069,
+ 0x0070, 0x1F17, 0x0172, 0x065D, 0x010B, 0x1F33, 0x006C,
+ },
+};
+
+/* vertical scaler coefficients */
+enum {
+ VS_UP_SCALE = 0,
+ VS_LT_9_16_SCALE,
+ VS_LT_10_16_SCALE,
+ VS_LT_11_16_SCALE,
+ VS_LT_12_16_SCALE,
+ VS_LT_13_16_SCALE,
+ VS_LT_14_16_SCALE,
+ VS_LT_15_16_SCALE,
+ VS_LT_16_16_SCALE,
+ VS_1_TO_1_SCALE,
+};
+
+static const u16 scaler_vs_coeffs[15][SC_NUM_PHASES * 2 * SC_V_NUM_TAPS] = {
+ [VS_UP_SCALE] = {
+ /* Luma */
+ 0x1FD1, 0x00B1, 0x06FC, 0x00B1, 0x1FD1,
+ 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
+ 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
+ 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
+ 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
+ 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
+ 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
+ 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
+ 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
+ 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
+ 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
+ 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
+ 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
+ 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
+ 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
+ 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
+ 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
+ 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
+ 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
+ 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
+ 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
+ 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
+ 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
+ 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
+ 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
+ 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
+ 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
+ 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
+ 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
+ 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
+ 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
+ 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
+ /* Chroma */
+ 0x1FD1, 0x00B1, 0x06FC, 0x00B1, 0x1FD1,
+ 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
+ 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
+ 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
+ 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
+ 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
+ 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
+ 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
+ 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
+ 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
+ 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
+ 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
+ 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
+ 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
+ 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
+ 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
+ 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
+ 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
+ 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
+ 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
+ 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
+ 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
+ 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
+ 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
+ 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
+ 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
+ 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
+ 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
+ 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
+ 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
+ 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
+ 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
+ },
+ [VS_LT_9_16_SCALE] = {
+ /* Luma */
+ 0x001C, 0x01F6, 0x03DC, 0x01F6, 0x001C,
+ 0x0018, 0x01DF, 0x03DB, 0x020C, 0x0022,
+ 0x0013, 0x01C9, 0x03D9, 0x0223, 0x0028,
+ 0x000F, 0x01B3, 0x03D6, 0x023A, 0x002E,
+ 0x000C, 0x019D, 0x03D2, 0x0250, 0x0035,
+ 0x0009, 0x0188, 0x03CC, 0x0266, 0x003D,
+ 0x0006, 0x0173, 0x03C5, 0x027D, 0x0045,
+ 0x0004, 0x015E, 0x03BD, 0x0293, 0x004E,
+ 0x0002, 0x014A, 0x03B4, 0x02A8, 0x0058,
+ 0x0000, 0x0136, 0x03AA, 0x02BE, 0x0062,
+ 0x1FFF, 0x0123, 0x039E, 0x02D3, 0x006D,
+ 0x1FFE, 0x0110, 0x0392, 0x02E8, 0x0078,
+ 0x1FFD, 0x00FE, 0x0384, 0x02FC, 0x0085,
+ 0x1FFD, 0x00ED, 0x0376, 0x030F, 0x0091,
+ 0x1FFC, 0x00DC, 0x0367, 0x0322, 0x009F,
+ 0x1FFC, 0x00CC, 0x0357, 0x0334, 0x00AD,
+ 0x00BC, 0x0344, 0x0344, 0x00BC, 0x0000,
+ 0x00AD, 0x0334, 0x0357, 0x00CC, 0x1FFC,
+ 0x009F, 0x0322, 0x0367, 0x00DC, 0x1FFC,
+ 0x0091, 0x030F, 0x0376, 0x00ED, 0x1FFD,
+ 0x0085, 0x02FC, 0x0384, 0x00FE, 0x1FFD,
+ 0x0078, 0x02E8, 0x0392, 0x0110, 0x1FFE,
+ 0x006D, 0x02D3, 0x039E, 0x0123, 0x1FFF,
+ 0x0062, 0x02BE, 0x03AA, 0x0136, 0x0000,
+ 0x0058, 0x02A8, 0x03B4, 0x014A, 0x0002,
+ 0x004E, 0x0293, 0x03BD, 0x015E, 0x0004,
+ 0x0045, 0x027D, 0x03C5, 0x0173, 0x0006,
+ 0x003D, 0x0266, 0x03CC, 0x0188, 0x0009,
+ 0x0035, 0x0250, 0x03D2, 0x019D, 0x000C,
+ 0x002E, 0x023A, 0x03D6, 0x01B3, 0x000F,
+ 0x0028, 0x0223, 0x03D9, 0x01C9, 0x0013,
+ 0x0022, 0x020C, 0x03DB, 0x01DF, 0x0018,
+ /* Chroma */
+ 0x001C, 0x01F6, 0x03DC, 0x01F6, 0x001C,
+ 0x0018, 0x01DF, 0x03DB, 0x020C, 0x0022,
+ 0x0013, 0x01C9, 0x03D9, 0x0223, 0x0028,
+ 0x000F, 0x01B3, 0x03D6, 0x023A, 0x002E,
+ 0x000C, 0x019D, 0x03D2, 0x0250, 0x0035,
+ 0x0009, 0x0188, 0x03CC, 0x0266, 0x003D,
+ 0x0006, 0x0173, 0x03C5, 0x027D, 0x0045,
+ 0x0004, 0x015E, 0x03BD, 0x0293, 0x004E,
+ 0x0002, 0x014A, 0x03B4, 0x02A8, 0x0058,
+ 0x0000, 0x0136, 0x03AA, 0x02BE, 0x0062,
+ 0x1FFF, 0x0123, 0x039E, 0x02D3, 0x006D,
+ 0x1FFE, 0x0110, 0x0392, 0x02E8, 0x0078,
+ 0x1FFD, 0x00FE, 0x0384, 0x02FC, 0x0085,
+ 0x1FFD, 0x00ED, 0x0376, 0x030F, 0x0091,
+ 0x1FFC, 0x00DC, 0x0367, 0x0322, 0x009F,
+ 0x1FFC, 0x00CC, 0x0357, 0x0334, 0x00AD,
+ 0x00BC, 0x0344, 0x0344, 0x00BC, 0x0000,
+ 0x00AD, 0x0334, 0x0357, 0x00CC, 0x1FFC,
+ 0x009F, 0x0322, 0x0367, 0x00DC, 0x1FFC,
+ 0x0091, 0x030F, 0x0376, 0x00ED, 0x1FFD,
+ 0x0085, 0x02FC, 0x0384, 0x00FE, 0x1FFD,
+ 0x0078, 0x02E8, 0x0392, 0x0110, 0x1FFE,
+ 0x006D, 0x02D3, 0x039E, 0x0123, 0x1FFF,
+ 0x0062, 0x02BE, 0x03AA, 0x0136, 0x0000,
+ 0x0058, 0x02A8, 0x03B4, 0x014A, 0x0002,
+ 0x004E, 0x0293, 0x03BD, 0x015E, 0x0004,
+ 0x0045, 0x027D, 0x03C5, 0x0173, 0x0006,
+ 0x003D, 0x0266, 0x03CC, 0x0188, 0x0009,
+ 0x0035, 0x0250, 0x03D2, 0x019D, 0x000C,
+ 0x002E, 0x023A, 0x03D6, 0x01B3, 0x000F,
+ 0x0028, 0x0223, 0x03D9, 0x01C9, 0x0013,
+ 0x0022, 0x020C, 0x03DB, 0x01DF, 0x0018,
+ },
+ [VS_LT_10_16_SCALE] = {
+ /* Luma */
+ 0x0003, 0x01E9, 0x0428, 0x01E9, 0x0003,
+ 0x0000, 0x01D0, 0x0426, 0x0203, 0x0007,
+ 0x1FFD, 0x01B7, 0x0424, 0x021C, 0x000C,
+ 0x1FFB, 0x019E, 0x0420, 0x0236, 0x0011,
+ 0x1FF9, 0x0186, 0x041A, 0x0250, 0x0017,
+ 0x1FF7, 0x016E, 0x0414, 0x026A, 0x001D,
+ 0x1FF6, 0x0157, 0x040B, 0x0284, 0x0024,
+ 0x1FF5, 0x0140, 0x0401, 0x029E, 0x002C,
+ 0x1FF4, 0x012A, 0x03F6, 0x02B7, 0x0035,
+ 0x1FF4, 0x0115, 0x03E9, 0x02D0, 0x003E,
+ 0x1FF4, 0x0100, 0x03DB, 0x02E9, 0x0048,
+ 0x1FF4, 0x00EC, 0x03CC, 0x0301, 0x0053,
+ 0x1FF4, 0x00D9, 0x03BC, 0x0318, 0x005F,
+ 0x1FF5, 0x00C7, 0x03AA, 0x032F, 0x006B,
+ 0x1FF6, 0x00B5, 0x0398, 0x0345, 0x0078,
+ 0x1FF6, 0x00A5, 0x0384, 0x035B, 0x0086,
+ 0x0094, 0x036C, 0x036C, 0x0094, 0x0000,
+ 0x0086, 0x035B, 0x0384, 0x00A5, 0x1FF6,
+ 0x0078, 0x0345, 0x0398, 0x00B5, 0x1FF6,
+ 0x006B, 0x032F, 0x03AA, 0x00C7, 0x1FF5,
+ 0x005F, 0x0318, 0x03BC, 0x00D9, 0x1FF4,
+ 0x0053, 0x0301, 0x03CC, 0x00EC, 0x1FF4,
+ 0x0048, 0x02E9, 0x03DB, 0x0100, 0x1FF4,
+ 0x003E, 0x02D0, 0x03E9, 0x0115, 0x1FF4,
+ 0x0035, 0x02B7, 0x03F6, 0x012A, 0x1FF4,
+ 0x002C, 0x029E, 0x0401, 0x0140, 0x1FF5,
+ 0x0024, 0x0284, 0x040B, 0x0157, 0x1FF6,
+ 0x001D, 0x026A, 0x0414, 0x016E, 0x1FF7,
+ 0x0017, 0x0250, 0x041A, 0x0186, 0x1FF9,
+ 0x0011, 0x0236, 0x0420, 0x019E, 0x1FFB,
+ 0x000C, 0x021C, 0x0424, 0x01B7, 0x1FFD,
+ 0x0007, 0x0203, 0x0426, 0x01D0, 0x0000,
+ /* Chroma */
+ 0x0003, 0x01E9, 0x0428, 0x01E9, 0x0003,
+ 0x0000, 0x01D0, 0x0426, 0x0203, 0x0007,
+ 0x1FFD, 0x01B7, 0x0424, 0x021C, 0x000C,
+ 0x1FFB, 0x019E, 0x0420, 0x0236, 0x0011,
+ 0x1FF9, 0x0186, 0x041A, 0x0250, 0x0017,
+ 0x1FF7, 0x016E, 0x0414, 0x026A, 0x001D,
+ 0x1FF6, 0x0157, 0x040B, 0x0284, 0x0024,
+ 0x1FF5, 0x0140, 0x0401, 0x029E, 0x002C,
+ 0x1FF4, 0x012A, 0x03F6, 0x02B7, 0x0035,
+ 0x1FF4, 0x0115, 0x03E9, 0x02D0, 0x003E,
+ 0x1FF4, 0x0100, 0x03DB, 0x02E9, 0x0048,
+ 0x1FF4, 0x00EC, 0x03CC, 0x0301, 0x0053,
+ 0x1FF4, 0x00D9, 0x03BC, 0x0318, 0x005F,
+ 0x1FF5, 0x00C7, 0x03AA, 0x032F, 0x006B,
+ 0x1FF6, 0x00B5, 0x0398, 0x0345, 0x0078,
+ 0x1FF6, 0x00A5, 0x0384, 0x035B, 0x0086,
+ 0x0094, 0x036C, 0x036C, 0x0094, 0x0000,
+ 0x0086, 0x035B, 0x0384, 0x00A5, 0x1FF6,
+ 0x0078, 0x0345, 0x0398, 0x00B5, 0x1FF6,
+ 0x006B, 0x032F, 0x03AA, 0x00C7, 0x1FF5,
+ 0x005F, 0x0318, 0x03BC, 0x00D9, 0x1FF4,
+ 0x0053, 0x0301, 0x03CC, 0x00EC, 0x1FF4,
+ 0x0048, 0x02E9, 0x03DB, 0x0100, 0x1FF4,
+ 0x003E, 0x02D0, 0x03E9, 0x0115, 0x1FF4,
+ 0x0035, 0x02B7, 0x03F6, 0x012A, 0x1FF4,
+ 0x002C, 0x029E, 0x0401, 0x0140, 0x1FF5,
+ 0x0024, 0x0284, 0x040B, 0x0157, 0x1FF6,
+ 0x001D, 0x026A, 0x0414, 0x016E, 0x1FF7,
+ 0x0017, 0x0250, 0x041A, 0x0186, 0x1FF9,
+ 0x0011, 0x0236, 0x0420, 0x019E, 0x1FFB,
+ 0x000C, 0x021C, 0x0424, 0x01B7, 0x1FFD,
+ 0x0007, 0x0203, 0x0426, 0x01D0, 0x0000,
+ },
+ [VS_LT_11_16_SCALE] = {
+ /* Luma */
+ 0x1FEC, 0x01D6, 0x047C, 0x01D6, 0x1FEC,
+ 0x1FEA, 0x01BA, 0x047B, 0x01F3, 0x1FEE,
+ 0x1FE9, 0x019D, 0x0478, 0x0211, 0x1FF1,
+ 0x1FE8, 0x0182, 0x0473, 0x022E, 0x1FF5,
+ 0x1FE8, 0x0167, 0x046C, 0x024C, 0x1FF9,
+ 0x1FE8, 0x014D, 0x0464, 0x026A, 0x1FFD,
+ 0x1FE8, 0x0134, 0x0459, 0x0288, 0x0003,
+ 0x1FE9, 0x011B, 0x044D, 0x02A6, 0x0009,
+ 0x1FE9, 0x0104, 0x0440, 0x02C3, 0x0010,
+ 0x1FEA, 0x00ED, 0x0430, 0x02E1, 0x0018,
+ 0x1FEB, 0x00D7, 0x0420, 0x02FD, 0x0021,
+ 0x1FED, 0x00C2, 0x040D, 0x0319, 0x002B,
+ 0x1FEE, 0x00AE, 0x03F9, 0x0336, 0x0035,
+ 0x1FF0, 0x009C, 0x03E3, 0x0350, 0x0041,
+ 0x1FF1, 0x008A, 0x03CD, 0x036B, 0x004D,
+ 0x1FF3, 0x0079, 0x03B5, 0x0384, 0x005B,
+ 0x0069, 0x0397, 0x0397, 0x0069, 0x0000,
+ 0x005B, 0x0384, 0x03B5, 0x0079, 0x1FF3,
+ 0x004D, 0x036B, 0x03CD, 0x008A, 0x1FF1,
+ 0x0041, 0x0350, 0x03E3, 0x009C, 0x1FF0,
+ 0x0035, 0x0336, 0x03F9, 0x00AE, 0x1FEE,
+ 0x002B, 0x0319, 0x040D, 0x00C2, 0x1FED,
+ 0x0021, 0x02FD, 0x0420, 0x00D7, 0x1FEB,
+ 0x0018, 0x02E1, 0x0430, 0x00ED, 0x1FEA,
+ 0x0010, 0x02C3, 0x0440, 0x0104, 0x1FE9,
+ 0x0009, 0x02A6, 0x044D, 0x011B, 0x1FE9,
+ 0x0003, 0x0288, 0x0459, 0x0134, 0x1FE8,
+ 0x1FFD, 0x026A, 0x0464, 0x014D, 0x1FE8,
+ 0x1FF9, 0x024C, 0x046C, 0x0167, 0x1FE8,
+ 0x1FF5, 0x022E, 0x0473, 0x0182, 0x1FE8,
+ 0x1FF1, 0x0211, 0x0478, 0x019D, 0x1FE9,
+ 0x1FEE, 0x01F3, 0x047B, 0x01BA, 0x1FEA,
+ /* Chroma */
+ 0x1FEC, 0x01D6, 0x047C, 0x01D6, 0x1FEC,
+ 0x1FEA, 0x01BA, 0x047B, 0x01F3, 0x1FEE,
+ 0x1FE9, 0x019D, 0x0478, 0x0211, 0x1FF1,
+ 0x1FE8, 0x0182, 0x0473, 0x022E, 0x1FF5,
+ 0x1FE8, 0x0167, 0x046C, 0x024C, 0x1FF9,
+ 0x1FE8, 0x014D, 0x0464, 0x026A, 0x1FFD,
+ 0x1FE8, 0x0134, 0x0459, 0x0288, 0x0003,
+ 0x1FE9, 0x011B, 0x044D, 0x02A6, 0x0009,
+ 0x1FE9, 0x0104, 0x0440, 0x02C3, 0x0010,
+ 0x1FEA, 0x00ED, 0x0430, 0x02E1, 0x0018,
+ 0x1FEB, 0x00D7, 0x0420, 0x02FD, 0x0021,
+ 0x1FED, 0x00C2, 0x040D, 0x0319, 0x002B,
+ 0x1FEE, 0x00AE, 0x03F9, 0x0336, 0x0035,
+ 0x1FF0, 0x009C, 0x03E3, 0x0350, 0x0041,
+ 0x1FF1, 0x008A, 0x03CD, 0x036B, 0x004D,
+ 0x1FF3, 0x0079, 0x03B5, 0x0384, 0x005B,
+ 0x0069, 0x0397, 0x0397, 0x0069, 0x0000,
+ 0x005B, 0x0384, 0x03B5, 0x0079, 0x1FF3,
+ 0x004D, 0x036B, 0x03CD, 0x008A, 0x1FF1,
+ 0x0041, 0x0350, 0x03E3, 0x009C, 0x1FF0,
+ 0x0035, 0x0336, 0x03F9, 0x00AE, 0x1FEE,
+ 0x002B, 0x0319, 0x040D, 0x00C2, 0x1FED,
+ 0x0021, 0x02FD, 0x0420, 0x00D7, 0x1FEB,
+ 0x0018, 0x02E1, 0x0430, 0x00ED, 0x1FEA,
+ 0x0010, 0x02C3, 0x0440, 0x0104, 0x1FE9,
+ 0x0009, 0x02A6, 0x044D, 0x011B, 0x1FE9,
+ 0x0003, 0x0288, 0x0459, 0x0134, 0x1FE8,
+ 0x1FFD, 0x026A, 0x0464, 0x014D, 0x1FE8,
+ 0x1FF9, 0x024C, 0x046C, 0x0167, 0x1FE8,
+ 0x1FF5, 0x022E, 0x0473, 0x0182, 0x1FE8,
+ 0x1FF1, 0x0211, 0x0478, 0x019D, 0x1FE9,
+ 0x1FEE, 0x01F3, 0x047B, 0x01BA, 0x1FEA,
+ },
+ [VS_LT_12_16_SCALE] = {
+ /* Luma */
+ 0x1FD8, 0x01BC, 0x04D8, 0x01BC, 0x1FD8,
+ 0x1FD8, 0x019C, 0x04D8, 0x01DC, 0x1FD8,
+ 0x1FD8, 0x017D, 0x04D4, 0x01FE, 0x1FD9,
+ 0x1FD9, 0x015E, 0x04CF, 0x0220, 0x1FDA,
+ 0x1FDB, 0x0141, 0x04C7, 0x0241, 0x1FDC,
+ 0x1FDC, 0x0125, 0x04BC, 0x0264, 0x1FDF,
+ 0x1FDE, 0x0109, 0x04B0, 0x0286, 0x1FE3,
+ 0x1FE0, 0x00EF, 0x04A1, 0x02A9, 0x1FE7,
+ 0x1FE2, 0x00D6, 0x0491, 0x02CB, 0x1FEC,
+ 0x1FE4, 0x00BE, 0x047E, 0x02EE, 0x1FF2,
+ 0x1FE6, 0x00A7, 0x046A, 0x030F, 0x1FFA,
+ 0x1FE9, 0x0092, 0x0453, 0x0330, 0x0002,
+ 0x1FEB, 0x007E, 0x043B, 0x0351, 0x000B,
+ 0x1FED, 0x006B, 0x0421, 0x0372, 0x0015,
+ 0x1FEF, 0x005A, 0x0406, 0x0391, 0x0020,
+ 0x1FF1, 0x0049, 0x03EA, 0x03AF, 0x002D,
+ 0x003A, 0x03C6, 0x03C6, 0x003A, 0x0000,
+ 0x002D, 0x03AF, 0x03EA, 0x0049, 0x1FF1,
+ 0x0020, 0x0391, 0x0406, 0x005A, 0x1FEF,
+ 0x0015, 0x0372, 0x0421, 0x006B, 0x1FED,
+ 0x000B, 0x0351, 0x043B, 0x007E, 0x1FEB,
+ 0x0002, 0x0330, 0x0453, 0x0092, 0x1FE9,
+ 0x1FFA, 0x030F, 0x046A, 0x00A7, 0x1FE6,
+ 0x1FF2, 0x02EE, 0x047E, 0x00BE, 0x1FE4,
+ 0x1FEC, 0x02CB, 0x0491, 0x00D6, 0x1FE2,
+ 0x1FE7, 0x02A9, 0x04A1, 0x00EF, 0x1FE0,
+ 0x1FE3, 0x0286, 0x04B0, 0x0109, 0x1FDE,
+ 0x1FDF, 0x0264, 0x04BC, 0x0125, 0x1FDC,
+ 0x1FDC, 0x0241, 0x04C7, 0x0141, 0x1FDB,
+ 0x1FDA, 0x0220, 0x04CF, 0x015E, 0x1FD9,
+ 0x1FD9, 0x01FE, 0x04D4, 0x017D, 0x1FD8,
+ 0x1FD8, 0x01DC, 0x04D8, 0x019C, 0x1FD8,
+ /* Chroma */
+ 0x1FD8, 0x01BC, 0x04D8, 0x01BC, 0x1FD8,
+ 0x1FD8, 0x019C, 0x04D8, 0x01DC, 0x1FD8,
+ 0x1FD8, 0x017D, 0x04D4, 0x01FE, 0x1FD9,
+ 0x1FD9, 0x015E, 0x04CF, 0x0220, 0x1FDA,
+ 0x1FDB, 0x0141, 0x04C7, 0x0241, 0x1FDC,
+ 0x1FDC, 0x0125, 0x04BC, 0x0264, 0x1FDF,
+ 0x1FDE, 0x0109, 0x04B0, 0x0286, 0x1FE3,
+ 0x1FE0, 0x00EF, 0x04A1, 0x02A9, 0x1FE7,
+ 0x1FE2, 0x00D6, 0x0491, 0x02CB, 0x1FEC,
+ 0x1FE4, 0x00BE, 0x047E, 0x02EE, 0x1FF2,
+ 0x1FE6, 0x00A7, 0x046A, 0x030F, 0x1FFA,
+ 0x1FE9, 0x0092, 0x0453, 0x0330, 0x0002,
+ 0x1FEB, 0x007E, 0x043B, 0x0351, 0x000B,
+ 0x1FED, 0x006B, 0x0421, 0x0372, 0x0015,
+ 0x1FEF, 0x005A, 0x0406, 0x0391, 0x0020,
+ 0x1FF1, 0x0049, 0x03EA, 0x03AF, 0x002D,
+ 0x003A, 0x03C6, 0x03C6, 0x003A, 0x0000,
+ 0x002D, 0x03AF, 0x03EA, 0x0049, 0x1FF1,
+ 0x0020, 0x0391, 0x0406, 0x005A, 0x1FEF,
+ 0x0015, 0x0372, 0x0421, 0x006B, 0x1FED,
+ 0x000B, 0x0351, 0x043B, 0x007E, 0x1FEB,
+ 0x0002, 0x0330, 0x0453, 0x0092, 0x1FE9,
+ 0x1FFA, 0x030F, 0x046A, 0x00A7, 0x1FE6,
+ 0x1FF2, 0x02EE, 0x047E, 0x00BE, 0x1FE4,
+ 0x1FEC, 0x02CB, 0x0491, 0x00D6, 0x1FE2,
+ 0x1FE7, 0x02A9, 0x04A1, 0x00EF, 0x1FE0,
+ 0x1FE3, 0x0286, 0x04B0, 0x0109, 0x1FDE,
+ 0x1FDF, 0x0264, 0x04BC, 0x0125, 0x1FDC,
+ 0x1FDC, 0x0241, 0x04C7, 0x0141, 0x1FDB,
+ 0x1FDA, 0x0220, 0x04CF, 0x015E, 0x1FD9,
+ 0x1FD9, 0x01FE, 0x04D4, 0x017D, 0x1FD8,
+ 0x1FD8, 0x01DC, 0x04D8, 0x019C, 0x1FD8,
+ },
+ [VS_LT_13_16_SCALE] = {
+ /* Luma */
+ 0x1FC8, 0x0199, 0x053E, 0x0199, 0x1FC8,
+ 0x1FCA, 0x0175, 0x053E, 0x01BD, 0x1FC6,
+ 0x1FCD, 0x0153, 0x0539, 0x01E2, 0x1FC5,
+ 0x1FCF, 0x0132, 0x0532, 0x0209, 0x1FC4,
+ 0x1FD2, 0x0112, 0x0529, 0x022F, 0x1FC4,
+ 0x1FD5, 0x00F4, 0x051C, 0x0256, 0x1FC5,
+ 0x1FD8, 0x00D7, 0x050D, 0x027E, 0x1FC6,
+ 0x1FDC, 0x00BB, 0x04FB, 0x02A6, 0x1FC8,
+ 0x1FDF, 0x00A1, 0x04E7, 0x02CE, 0x1FCB,
+ 0x1FE2, 0x0089, 0x04D1, 0x02F5, 0x1FCF,
+ 0x1FE5, 0x0072, 0x04B8, 0x031D, 0x1FD4,
+ 0x1FE8, 0x005D, 0x049E, 0x0344, 0x1FD9,
+ 0x1FEB, 0x0049, 0x0480, 0x036B, 0x1FE1,
+ 0x1FEE, 0x0037, 0x0462, 0x0390, 0x1FE9,
+ 0x1FF0, 0x0026, 0x0442, 0x03B6, 0x1FF2,
+ 0x1FF2, 0x0017, 0x0420, 0x03DA, 0x1FFD,
+ 0x0009, 0x03F7, 0x03F7, 0x0009, 0x0000,
+ 0x1FFD, 0x03DA, 0x0420, 0x0017, 0x1FF2,
+ 0x1FF2, 0x03B6, 0x0442, 0x0026, 0x1FF0,
+ 0x1FE9, 0x0390, 0x0462, 0x0037, 0x1FEE,
+ 0x1FE1, 0x036B, 0x0480, 0x0049, 0x1FEB,
+ 0x1FD9, 0x0344, 0x049E, 0x005D, 0x1FE8,
+ 0x1FD4, 0x031D, 0x04B8, 0x0072, 0x1FE5,
+ 0x1FCF, 0x02F5, 0x04D1, 0x0089, 0x1FE2,
+ 0x1FCB, 0x02CE, 0x04E7, 0x00A1, 0x1FDF,
+ 0x1FC8, 0x02A6, 0x04FB, 0x00BB, 0x1FDC,
+ 0x1FC6, 0x027E, 0x050D, 0x00D7, 0x1FD8,
+ 0x1FC5, 0x0256, 0x051C, 0x00F4, 0x1FD5,
+ 0x1FC4, 0x022F, 0x0529, 0x0112, 0x1FD2,
+ 0x1FC4, 0x0209, 0x0532, 0x0132, 0x1FCF,
+ 0x1FC5, 0x01E2, 0x0539, 0x0153, 0x1FCD,
+ 0x1FC6, 0x01BD, 0x053E, 0x0175, 0x1FCA,
+ /* Chroma */
+ 0x1FC8, 0x0199, 0x053E, 0x0199, 0x1FC8,
+ 0x1FCA, 0x0175, 0x053E, 0x01BD, 0x1FC6,
+ 0x1FCD, 0x0153, 0x0539, 0x01E2, 0x1FC5,
+ 0x1FCF, 0x0132, 0x0532, 0x0209, 0x1FC4,
+ 0x1FD2, 0x0112, 0x0529, 0x022F, 0x1FC4,
+ 0x1FD5, 0x00F4, 0x051C, 0x0256, 0x1FC5,
+ 0x1FD8, 0x00D7, 0x050D, 0x027E, 0x1FC6,
+ 0x1FDC, 0x00BB, 0x04FB, 0x02A6, 0x1FC8,
+ 0x1FDF, 0x00A1, 0x04E7, 0x02CE, 0x1FCB,
+ 0x1FE2, 0x0089, 0x04D1, 0x02F5, 0x1FCF,
+ 0x1FE5, 0x0072, 0x04B8, 0x031D, 0x1FD4,
+ 0x1FE8, 0x005D, 0x049E, 0x0344, 0x1FD9,
+ 0x1FEB, 0x0049, 0x0480, 0x036B, 0x1FE1,
+ 0x1FEE, 0x0037, 0x0462, 0x0390, 0x1FE9,
+ 0x1FF0, 0x0026, 0x0442, 0x03B6, 0x1FF2,
+ 0x1FF2, 0x0017, 0x0420, 0x03DA, 0x1FFD,
+ 0x0009, 0x03F7, 0x03F7, 0x0009, 0x0000,
+ 0x1FFD, 0x03DA, 0x0420, 0x0017, 0x1FF2,
+ 0x1FF2, 0x03B6, 0x0442, 0x0026, 0x1FF0,
+ 0x1FE9, 0x0390, 0x0462, 0x0037, 0x1FEE,
+ 0x1FE1, 0x036B, 0x0480, 0x0049, 0x1FEB,
+ 0x1FD9, 0x0344, 0x049E, 0x005D, 0x1FE8,
+ 0x1FD4, 0x031D, 0x04B8, 0x0072, 0x1FE5,
+ 0x1FCF, 0x02F5, 0x04D1, 0x0089, 0x1FE2,
+ 0x1FCB, 0x02CE, 0x04E7, 0x00A1, 0x1FDF,
+ 0x1FC8, 0x02A6, 0x04FB, 0x00BB, 0x1FDC,
+ 0x1FC6, 0x027E, 0x050D, 0x00D7, 0x1FD8,
+ 0x1FC5, 0x0256, 0x051C, 0x00F4, 0x1FD5,
+ 0x1FC4, 0x022F, 0x0529, 0x0112, 0x1FD2,
+ 0x1FC4, 0x0209, 0x0532, 0x0132, 0x1FCF,
+ 0x1FC5, 0x01E2, 0x0539, 0x0153, 0x1FCD,
+ 0x1FC6, 0x01BD, 0x053E, 0x0175, 0x1FCA,
+ },
+ [VS_LT_14_16_SCALE] = {
+ /* Luma */
+ 0x1FBF, 0x016C, 0x05AA, 0x016C, 0x1FBF,
+ 0x1FC3, 0x0146, 0x05A8, 0x0194, 0x1FBB,
+ 0x1FC7, 0x0121, 0x05A3, 0x01BD, 0x1FB8,
+ 0x1FCB, 0x00FD, 0x059B, 0x01E8, 0x1FB5,
+ 0x1FD0, 0x00DC, 0x058F, 0x0213, 0x1FB2,
+ 0x1FD4, 0x00BC, 0x0580, 0x0240, 0x1FB0,
+ 0x1FD8, 0x009E, 0x056E, 0x026D, 0x1FAF,
+ 0x1FDC, 0x0082, 0x055A, 0x029A, 0x1FAE,
+ 0x1FE0, 0x0067, 0x0542, 0x02C9, 0x1FAE,
+ 0x1FE4, 0x004F, 0x0528, 0x02F6, 0x1FAF,
+ 0x1FE8, 0x0038, 0x050A, 0x0325, 0x1FB1,
+ 0x1FEB, 0x0024, 0x04EB, 0x0352, 0x1FB4,
+ 0x1FEE, 0x0011, 0x04C8, 0x0380, 0x1FB9,
+ 0x1FF1, 0x0000, 0x04A4, 0x03AC, 0x1FBF,
+ 0x1FF4, 0x1FF1, 0x047D, 0x03D8, 0x1FC6,
+ 0x1FF6, 0x1FE4, 0x0455, 0x0403, 0x1FCE,
+ 0x1FD8, 0x0428, 0x0428, 0x1FD8, 0x0000,
+ 0x1FCE, 0x0403, 0x0455, 0x1FE4, 0x1FF6,
+ 0x1FC6, 0x03D8, 0x047D, 0x1FF1, 0x1FF4,
+ 0x1FBF, 0x03AC, 0x04A4, 0x0000, 0x1FF1,
+ 0x1FB9, 0x0380, 0x04C8, 0x0011, 0x1FEE,
+ 0x1FB4, 0x0352, 0x04EB, 0x0024, 0x1FEB,
+ 0x1FB1, 0x0325, 0x050A, 0x0038, 0x1FE8,
+ 0x1FAF, 0x02F6, 0x0528, 0x004F, 0x1FE4,
+ 0x1FAE, 0x02C9, 0x0542, 0x0067, 0x1FE0,
+ 0x1FAE, 0x029A, 0x055A, 0x0082, 0x1FDC,
+ 0x1FAF, 0x026D, 0x056E, 0x009E, 0x1FD8,
+ 0x1FB0, 0x0240, 0x0580, 0x00BC, 0x1FD4,
+ 0x1FB2, 0x0213, 0x058F, 0x00DC, 0x1FD0,
+ 0x1FB5, 0x01E8, 0x059B, 0x00FD, 0x1FCB,
+ 0x1FB8, 0x01BD, 0x05A3, 0x0121, 0x1FC7,
+ 0x1FBB, 0x0194, 0x05A8, 0x0146, 0x1FC3,
+ /* Chroma */
+ 0x1FBF, 0x016C, 0x05AA, 0x016C, 0x1FBF,
+ 0x1FC3, 0x0146, 0x05A8, 0x0194, 0x1FBB,
+ 0x1FC7, 0x0121, 0x05A3, 0x01BD, 0x1FB8,
+ 0x1FCB, 0x00FD, 0x059B, 0x01E8, 0x1FB5,
+ 0x1FD0, 0x00DC, 0x058F, 0x0213, 0x1FB2,
+ 0x1FD4, 0x00BC, 0x0580, 0x0240, 0x1FB0,
+ 0x1FD8, 0x009E, 0x056E, 0x026D, 0x1FAF,
+ 0x1FDC, 0x0082, 0x055A, 0x029A, 0x1FAE,
+ 0x1FE0, 0x0067, 0x0542, 0x02C9, 0x1FAE,
+ 0x1FE4, 0x004F, 0x0528, 0x02F6, 0x1FAF,
+ 0x1FE8, 0x0038, 0x050A, 0x0325, 0x1FB1,
+ 0x1FEB, 0x0024, 0x04EB, 0x0352, 0x1FB4,
+ 0x1FEE, 0x0011, 0x04C8, 0x0380, 0x1FB9,
+ 0x1FF1, 0x0000, 0x04A4, 0x03AC, 0x1FBF,
+ 0x1FF4, 0x1FF1, 0x047D, 0x03D8, 0x1FC6,
+ 0x1FF6, 0x1FE4, 0x0455, 0x0403, 0x1FCE,
+ 0x1FD8, 0x0428, 0x0428, 0x1FD8, 0x0000,
+ 0x1FCE, 0x0403, 0x0455, 0x1FE4, 0x1FF6,
+ 0x1FC6, 0x03D8, 0x047D, 0x1FF1, 0x1FF4,
+ 0x1FBF, 0x03AC, 0x04A4, 0x0000, 0x1FF1,
+ 0x1FB9, 0x0380, 0x04C8, 0x0011, 0x1FEE,
+ 0x1FB4, 0x0352, 0x04EB, 0x0024, 0x1FEB,
+ 0x1FB1, 0x0325, 0x050A, 0x0038, 0x1FE8,
+ 0x1FAF, 0x02F6, 0x0528, 0x004F, 0x1FE4,
+ 0x1FAE, 0x02C9, 0x0542, 0x0067, 0x1FE0,
+ 0x1FAE, 0x029A, 0x055A, 0x0082, 0x1FDC,
+ 0x1FAF, 0x026D, 0x056E, 0x009E, 0x1FD8,
+ 0x1FB0, 0x0240, 0x0580, 0x00BC, 0x1FD4,
+ 0x1FB2, 0x0213, 0x058F, 0x00DC, 0x1FD0,
+ 0x1FB5, 0x01E8, 0x059B, 0x00FD, 0x1FCB,
+ 0x1FB8, 0x01BD, 0x05A3, 0x0121, 0x1FC7,
+ 0x1FBB, 0x0194, 0x05A8, 0x0146, 0x1FC3,
+ },
+ [VS_LT_15_16_SCALE] = {
+ /* Luma */
+ 0x1FBD, 0x0136, 0x061A, 0x0136, 0x1FBD,
+ 0x1FC3, 0x010D, 0x0617, 0x0161, 0x1FB8,
+ 0x1FC9, 0x00E6, 0x0611, 0x018E, 0x1FB2,
+ 0x1FCE, 0x00C1, 0x0607, 0x01BD, 0x1FAD,
+ 0x1FD4, 0x009E, 0x05F9, 0x01ED, 0x1FA8,
+ 0x1FD9, 0x007D, 0x05E8, 0x021F, 0x1FA3,
+ 0x1FDE, 0x005E, 0x05D3, 0x0252, 0x1F9F,
+ 0x1FE2, 0x0042, 0x05BC, 0x0285, 0x1F9B,
+ 0x1FE7, 0x0029, 0x059F, 0x02B9, 0x1F98,
+ 0x1FEA, 0x0011, 0x0580, 0x02EF, 0x1F96,
+ 0x1FEE, 0x1FFC, 0x055D, 0x0324, 0x1F95,
+ 0x1FF1, 0x1FE9, 0x0538, 0x0359, 0x1F95,
+ 0x1FF4, 0x1FD8, 0x0510, 0x038E, 0x1F96,
+ 0x1FF7, 0x1FC9, 0x04E5, 0x03C2, 0x1F99,
+ 0x1FF9, 0x1FBD, 0x04B8, 0x03F5, 0x1F9D,
+ 0x1FFB, 0x1FB2, 0x0489, 0x0428, 0x1FA2,
+ 0x1FAA, 0x0456, 0x0456, 0x1FAA, 0x0000,
+ 0x1FA2, 0x0428, 0x0489, 0x1FB2, 0x1FFB,
+ 0x1F9D, 0x03F5, 0x04B8, 0x1FBD, 0x1FF9,
+ 0x1F99, 0x03C2, 0x04E5, 0x1FC9, 0x1FF7,
+ 0x1F96, 0x038E, 0x0510, 0x1FD8, 0x1FF4,
+ 0x1F95, 0x0359, 0x0538, 0x1FE9, 0x1FF1,
+ 0x1F95, 0x0324, 0x055D, 0x1FFC, 0x1FEE,
+ 0x1F96, 0x02EF, 0x0580, 0x0011, 0x1FEA,
+ 0x1F98, 0x02B9, 0x059F, 0x0029, 0x1FE7,
+ 0x1F9B, 0x0285, 0x05BC, 0x0042, 0x1FE2,
+ 0x1F9F, 0x0252, 0x05D3, 0x005E, 0x1FDE,
+ 0x1FA3, 0x021F, 0x05E8, 0x007D, 0x1FD9,
+ 0x1FA8, 0x01ED, 0x05F9, 0x009E, 0x1FD4,
+ 0x1FAD, 0x01BD, 0x0607, 0x00C1, 0x1FCE,
+ 0x1FB2, 0x018E, 0x0611, 0x00E6, 0x1FC9,
+ 0x1FB8, 0x0161, 0x0617, 0x010D, 0x1FC3,
+ /* Chroma */
+ 0x1FBD, 0x0136, 0x061A, 0x0136, 0x1FBD,
+ 0x1FC3, 0x010D, 0x0617, 0x0161, 0x1FB8,
+ 0x1FC9, 0x00E6, 0x0611, 0x018E, 0x1FB2,
+ 0x1FCE, 0x00C1, 0x0607, 0x01BD, 0x1FAD,
+ 0x1FD4, 0x009E, 0x05F9, 0x01ED, 0x1FA8,
+ 0x1FD9, 0x007D, 0x05E8, 0x021F, 0x1FA3,
+ 0x1FDE, 0x005E, 0x05D3, 0x0252, 0x1F9F,
+ 0x1FE2, 0x0042, 0x05BC, 0x0285, 0x1F9B,
+ 0x1FE7, 0x0029, 0x059F, 0x02B9, 0x1F98,
+ 0x1FEA, 0x0011, 0x0580, 0x02EF, 0x1F96,
+ 0x1FEE, 0x1FFC, 0x055D, 0x0324, 0x1F95,
+ 0x1FF1, 0x1FE9, 0x0538, 0x0359, 0x1F95,
+ 0x1FF4, 0x1FD8, 0x0510, 0x038E, 0x1F96,
+ 0x1FF7, 0x1FC9, 0x04E5, 0x03C2, 0x1F99,
+ 0x1FF9, 0x1FBD, 0x04B8, 0x03F5, 0x1F9D,
+ 0x1FFB, 0x1FB2, 0x0489, 0x0428, 0x1FA2,
+ 0x1FAA, 0x0456, 0x0456, 0x1FAA, 0x0000,
+ 0x1FA2, 0x0428, 0x0489, 0x1FB2, 0x1FFB,
+ 0x1F9D, 0x03F5, 0x04B8, 0x1FBD, 0x1FF9,
+ 0x1F99, 0x03C2, 0x04E5, 0x1FC9, 0x1FF7,
+ 0x1F96, 0x038E, 0x0510, 0x1FD8, 0x1FF4,
+ 0x1F95, 0x0359, 0x0538, 0x1FE9, 0x1FF1,
+ 0x1F95, 0x0324, 0x055D, 0x1FFC, 0x1FEE,
+ 0x1F96, 0x02EF, 0x0580, 0x0011, 0x1FEA,
+ 0x1F98, 0x02B9, 0x059F, 0x0029, 0x1FE7,
+ 0x1F9B, 0x0285, 0x05BC, 0x0042, 0x1FE2,
+ 0x1F9F, 0x0252, 0x05D3, 0x005E, 0x1FDE,
+ 0x1FA3, 0x021F, 0x05E8, 0x007D, 0x1FD9,
+ 0x1FA8, 0x01ED, 0x05F9, 0x009E, 0x1FD4,
+ 0x1FAD, 0x01BD, 0x0607, 0x00C1, 0x1FCE,
+ 0x1FB2, 0x018E, 0x0611, 0x00E6, 0x1FC9,
+ 0x1FB8, 0x0161, 0x0617, 0x010D, 0x1FC3,
+ },
+ [VS_LT_16_16_SCALE] = {
+ /* Luma */
+ 0x1FC3, 0x00F8, 0x068A, 0x00F8, 0x1FC3,
+ 0x1FCA, 0x00CC, 0x0689, 0x0125, 0x1FBC,
+ 0x1FD1, 0x00A3, 0x0681, 0x0156, 0x1FB5,
+ 0x1FD7, 0x007D, 0x0676, 0x0188, 0x1FAE,
+ 0x1FDD, 0x005A, 0x0666, 0x01BD, 0x1FA6,
+ 0x1FE3, 0x0039, 0x0652, 0x01F3, 0x1F9F,
+ 0x1FE8, 0x001B, 0x0639, 0x022C, 0x1F98,
+ 0x1FEC, 0x0000, 0x061D, 0x0265, 0x1F92,
+ 0x1FF0, 0x1FE8, 0x05FC, 0x02A0, 0x1F8C,
+ 0x1FF4, 0x1FD2, 0x05D7, 0x02DC, 0x1F87,
+ 0x1FF7, 0x1FBF, 0x05AF, 0x0319, 0x1F82,
+ 0x1FFA, 0x1FAF, 0x0583, 0x0356, 0x1F7E,
+ 0x1FFC, 0x1FA1, 0x0554, 0x0393, 0x1F7C,
+ 0x1FFE, 0x1F95, 0x0523, 0x03CF, 0x1F7B,
+ 0x0000, 0x1F8C, 0x04EE, 0x040B, 0x1F7B,
+ 0x0001, 0x1F85, 0x04B8, 0x0446, 0x1F7C,
+ 0x1F80, 0x0480, 0x0480, 0x1F80, 0x0000,
+ 0x1F7C, 0x0446, 0x04B8, 0x1F85, 0x0001,
+ 0x1F7B, 0x040B, 0x04EE, 0x1F8C, 0x0000,
+ 0x1F7B, 0x03CF, 0x0523, 0x1F95, 0x1FFE,
+ 0x1F7C, 0x0393, 0x0554, 0x1FA1, 0x1FFC,
+ 0x1F7E, 0x0356, 0x0583, 0x1FAF, 0x1FFA,
+ 0x1F82, 0x0319, 0x05AF, 0x1FBF, 0x1FF7,
+ 0x1F87, 0x02DC, 0x05D7, 0x1FD2, 0x1FF4,
+ 0x1F8C, 0x02A0, 0x05FC, 0x1FE8, 0x1FF0,
+ 0x1F92, 0x0265, 0x061D, 0x0000, 0x1FEC,
+ 0x1F98, 0x022C, 0x0639, 0x001B, 0x1FE8,
+ 0x1F9F, 0x01F3, 0x0652, 0x0039, 0x1FE3,
+ 0x1FA6, 0x01BD, 0x0666, 0x005A, 0x1FDD,
+ 0x1FAE, 0x0188, 0x0676, 0x007D, 0x1FD7,
+ 0x1FB5, 0x0156, 0x0681, 0x00A3, 0x1FD1,
+ 0x1FBC, 0x0125, 0x0689, 0x00CC, 0x1FCA,
+ /* Chroma */
+ 0x1FC3, 0x00F8, 0x068A, 0x00F8, 0x1FC3,
+ 0x1FCA, 0x00CC, 0x0689, 0x0125, 0x1FBC,
+ 0x1FD1, 0x00A3, 0x0681, 0x0156, 0x1FB5,
+ 0x1FD7, 0x007D, 0x0676, 0x0188, 0x1FAE,
+ 0x1FDD, 0x005A, 0x0666, 0x01BD, 0x1FA6,
+ 0x1FE3, 0x0039, 0x0652, 0x01F3, 0x1F9F,
+ 0x1FE8, 0x001B, 0x0639, 0x022C, 0x1F98,
+ 0x1FEC, 0x0000, 0x061D, 0x0265, 0x1F92,
+ 0x1FF0, 0x1FE8, 0x05FC, 0x02A0, 0x1F8C,
+ 0x1FF4, 0x1FD2, 0x05D7, 0x02DC, 0x1F87,
+ 0x1FF7, 0x1FBF, 0x05AF, 0x0319, 0x1F82,
+ 0x1FFA, 0x1FAF, 0x0583, 0x0356, 0x1F7E,
+ 0x1FFC, 0x1FA1, 0x0554, 0x0393, 0x1F7C,
+ 0x1FFE, 0x1F95, 0x0523, 0x03CF, 0x1F7B,
+ 0x0000, 0x1F8C, 0x04EE, 0x040B, 0x1F7B,
+ 0x0001, 0x1F85, 0x04B8, 0x0446, 0x1F7C,
+ 0x1F80, 0x0480, 0x0480, 0x1F80, 0x0000,
+ 0x1F7C, 0x0446, 0x04B8, 0x1F85, 0x0001,
+ 0x1F7B, 0x040B, 0x04EE, 0x1F8C, 0x0000,
+ 0x1F7B, 0x03CF, 0x0523, 0x1F95, 0x1FFE,
+ 0x1F7C, 0x0393, 0x0554, 0x1FA1, 0x1FFC,
+ 0x1F7E, 0x0356, 0x0583, 0x1FAF, 0x1FFA,
+ 0x1F82, 0x0319, 0x05AF, 0x1FBF, 0x1FF7,
+ 0x1F87, 0x02DC, 0x05D7, 0x1FD2, 0x1FF4,
+ 0x1F8C, 0x02A0, 0x05FC, 0x1FE8, 0x1FF0,
+ 0x1F92, 0x0265, 0x061D, 0x0000, 0x1FEC,
+ 0x1F98, 0x022C, 0x0639, 0x001B, 0x1FE8,
+ 0x1F9F, 0x01F3, 0x0652, 0x0039, 0x1FE3,
+ 0x1FA6, 0x01BD, 0x0666, 0x005A, 0x1FDD,
+ 0x1FAE, 0x0188, 0x0676, 0x007D, 0x1FD7,
+ 0x1FB5, 0x0156, 0x0681, 0x00A3, 0x1FD1,
+ 0x1FBC, 0x0125, 0x0689, 0x00CC, 0x1FCA,
+ },
+ [VS_1_TO_1_SCALE] = {
+ /* Luma */
+ 0x0000, 0x0000, 0x0800, 0x0000, 0x0000,
+ 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
+ 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
+ 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
+ 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
+ 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
+ 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
+ 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
+ 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
+ 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
+ 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
+ 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
+ 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
+ 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
+ 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
+ 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
+ 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
+ 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
+ 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
+ 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
+ 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
+ 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
+ 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
+ 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
+ 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
+ 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
+ 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
+ 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
+ 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
+ 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
+ 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
+ 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
+ /* Chroma */
+ 0x0000, 0x0000, 0x0800, 0x0000, 0x0000,
+ 0x1FD8, 0x0085, 0x06F9, 0x00E1, 0x1FC9,
+ 0x1FDF, 0x005B, 0x06F2, 0x0114, 0x1FC0,
+ 0x1FE5, 0x0035, 0x06E5, 0x014A, 0x1FB7,
+ 0x1FEB, 0x0012, 0x06D3, 0x0182, 0x1FAE,
+ 0x1FF1, 0x1FF3, 0x06BA, 0x01BD, 0x1FA5,
+ 0x1FF5, 0x1FD7, 0x069D, 0x01FB, 0x1F9C,
+ 0x1FF9, 0x1FBE, 0x067C, 0x023A, 0x1F93,
+ 0x1FFD, 0x1FA8, 0x0656, 0x027B, 0x1F8A,
+ 0x0000, 0x1F95, 0x062B, 0x02BF, 0x1F81,
+ 0x0002, 0x1F86, 0x05FC, 0x0303, 0x1F79,
+ 0x0004, 0x1F79, 0x05CA, 0x0347, 0x1F72,
+ 0x0005, 0x1F6F, 0x0594, 0x038D, 0x1F6B,
+ 0x0006, 0x1F67, 0x055B, 0x03D2, 0x1F66,
+ 0x0007, 0x1F62, 0x051E, 0x0417, 0x1F62,
+ 0x0007, 0x1F5F, 0x04DF, 0x045C, 0x1F5F,
+ 0x1F5E, 0x04A2, 0x04A2, 0x1F5E, 0x0000,
+ 0x1F5F, 0x045C, 0x04DF, 0x1F5F, 0x0007,
+ 0x1F62, 0x0417, 0x051E, 0x1F62, 0x0007,
+ 0x1F66, 0x03D2, 0x055B, 0x1F67, 0x0006,
+ 0x1F6B, 0x038D, 0x0594, 0x1F6F, 0x0005,
+ 0x1F72, 0x0347, 0x05CA, 0x1F79, 0x0004,
+ 0x1F79, 0x0303, 0x05FC, 0x1F86, 0x0002,
+ 0x1F81, 0x02BF, 0x062B, 0x1F95, 0x0000,
+ 0x1F8A, 0x027B, 0x0656, 0x1FA8, 0x1FFD,
+ 0x1F93, 0x023A, 0x067C, 0x1FBE, 0x1FF9,
+ 0x1F9C, 0x01FB, 0x069D, 0x1FD7, 0x1FF5,
+ 0x1FA5, 0x01BD, 0x06BA, 0x1FF3, 0x1FF1,
+ 0x1FAE, 0x0182, 0x06D3, 0x0012, 0x1FEB,
+ 0x1FB7, 0x014A, 0x06E5, 0x0035, 0x1FE5,
+ 0x1FC0, 0x0114, 0x06F2, 0x005B, 0x1FDF,
+ 0x1FC9, 0x00E1, 0x06F9, 0x0085, 0x1FD8,
+ },
+};
+#endif
diff --git a/drivers/media/platform/ti/vpe/vpdma.c b/drivers/media/platform/ti/vpe/vpdma.c
new file mode 100644
index 000000000000..f8998a8ad371
--- /dev/null
+++ b/drivers/media/platform/ti/vpe/vpdma.c
@@ -0,0 +1,1176 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * VPDMA helper library
+ *
+ * Copyright (c) 2013 Texas Instruments Inc.
+ *
+ * David Griego,
+ * Dale Farnsworth,
+ * Archit Taneja,
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "vpdma.h"
+#include "vpdma_priv.h"
+
+#define VPDMA_FIRMWARE "vpdma-1b8.bin"
+
+const struct vpdma_data_format vpdma_yuv_fmts[] = {
+ [VPDMA_DATA_FMT_Y444] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_Y444,
+ .depth = 8,
+ },
+ [VPDMA_DATA_FMT_Y422] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_Y422,
+ .depth = 8,
+ },
+ [VPDMA_DATA_FMT_Y420] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_Y420,
+ .depth = 8,
+ },
+ [VPDMA_DATA_FMT_C444] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_C444,
+ .depth = 8,
+ },
+ [VPDMA_DATA_FMT_C422] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_C422,
+ .depth = 8,
+ },
+ [VPDMA_DATA_FMT_C420] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_C420,
+ .depth = 4,
+ },
+ [VPDMA_DATA_FMT_CB420] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_CB420,
+ .depth = 4,
+ },
+ [VPDMA_DATA_FMT_YCR422] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_YCR422,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_YC444] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_YC444,
+ .depth = 24,
+ },
+ [VPDMA_DATA_FMT_CRY422] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_CRY422,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_CBY422] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_CBY422,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_YCB422] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_YCB422,
+ .depth = 16,
+ },
+};
+EXPORT_SYMBOL(vpdma_yuv_fmts);
+
+const struct vpdma_data_format vpdma_rgb_fmts[] = {
+ [VPDMA_DATA_FMT_RGB565] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_RGB16_565,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_ARGB16_1555] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_ARGB_1555,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_ARGB16] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_ARGB_4444,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_RGBA16_5551] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_RGBA_5551,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_RGBA16] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_RGBA_4444,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_ARGB24] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_ARGB24_6666,
+ .depth = 24,
+ },
+ [VPDMA_DATA_FMT_RGB24] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_RGB24_888,
+ .depth = 24,
+ },
+ [VPDMA_DATA_FMT_ARGB32] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_ARGB32_8888,
+ .depth = 32,
+ },
+ [VPDMA_DATA_FMT_RGBA24] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_RGBA24_6666,
+ .depth = 24,
+ },
+ [VPDMA_DATA_FMT_RGBA32] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_RGBA32_8888,
+ .depth = 32,
+ },
+ [VPDMA_DATA_FMT_BGR565] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_BGR16_565,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_ABGR16_1555] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_ABGR_1555,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_ABGR16] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_ABGR_4444,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_BGRA16_5551] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_BGRA_5551,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_BGRA16] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_BGRA_4444,
+ .depth = 16,
+ },
+ [VPDMA_DATA_FMT_ABGR24] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_ABGR24_6666,
+ .depth = 24,
+ },
+ [VPDMA_DATA_FMT_BGR24] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_BGR24_888,
+ .depth = 24,
+ },
+ [VPDMA_DATA_FMT_ABGR32] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_ABGR32_8888,
+ .depth = 32,
+ },
+ [VPDMA_DATA_FMT_BGRA24] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_BGRA24_6666,
+ .depth = 24,
+ },
+ [VPDMA_DATA_FMT_BGRA32] = {
+ .type = VPDMA_DATA_FMT_TYPE_RGB,
+ .data_type = DATA_TYPE_BGRA32_8888,
+ .depth = 32,
+ },
+};
+EXPORT_SYMBOL(vpdma_rgb_fmts);
+
+/*
+ * To handle RAW format we are re-using the CBY422
+ * vpdma data type so that we use the vpdma to re-order
+ * the incoming bytes, as the parser assumes that the
+ * first byte presented on the bus is the MSB of a 2
+ * bytes value.
+ * RAW8 handles from 1 to 8 bits
+ * RAW16 handles from 9 to 16 bits
+ */
+const struct vpdma_data_format vpdma_raw_fmts[] = {
+ [VPDMA_DATA_FMT_RAW8] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_CBY422,
+ .depth = 8,
+ },
+ [VPDMA_DATA_FMT_RAW16] = {
+ .type = VPDMA_DATA_FMT_TYPE_YUV,
+ .data_type = DATA_TYPE_CBY422,
+ .depth = 16,
+ },
+};
+EXPORT_SYMBOL(vpdma_raw_fmts);
+
+const struct vpdma_data_format vpdma_misc_fmts[] = {
+ [VPDMA_DATA_FMT_MV] = {
+ .type = VPDMA_DATA_FMT_TYPE_MISC,
+ .data_type = DATA_TYPE_MV,
+ .depth = 4,
+ },
+};
+EXPORT_SYMBOL(vpdma_misc_fmts);
+
+struct vpdma_channel_info {
+ int num; /* VPDMA channel number */
+ int cstat_offset; /* client CSTAT register offset */
+};
+
+static const struct vpdma_channel_info chan_info[] = {
+ [VPE_CHAN_LUMA1_IN] = {
+ .num = VPE_CHAN_NUM_LUMA1_IN,
+ .cstat_offset = VPDMA_DEI_LUMA1_CSTAT,
+ },
+ [VPE_CHAN_CHROMA1_IN] = {
+ .num = VPE_CHAN_NUM_CHROMA1_IN,
+ .cstat_offset = VPDMA_DEI_CHROMA1_CSTAT,
+ },
+ [VPE_CHAN_LUMA2_IN] = {
+ .num = VPE_CHAN_NUM_LUMA2_IN,
+ .cstat_offset = VPDMA_DEI_LUMA2_CSTAT,
+ },
+ [VPE_CHAN_CHROMA2_IN] = {
+ .num = VPE_CHAN_NUM_CHROMA2_IN,
+ .cstat_offset = VPDMA_DEI_CHROMA2_CSTAT,
+ },
+ [VPE_CHAN_LUMA3_IN] = {
+ .num = VPE_CHAN_NUM_LUMA3_IN,
+ .cstat_offset = VPDMA_DEI_LUMA3_CSTAT,
+ },
+ [VPE_CHAN_CHROMA3_IN] = {
+ .num = VPE_CHAN_NUM_CHROMA3_IN,
+ .cstat_offset = VPDMA_DEI_CHROMA3_CSTAT,
+ },
+ [VPE_CHAN_MV_IN] = {
+ .num = VPE_CHAN_NUM_MV_IN,
+ .cstat_offset = VPDMA_DEI_MV_IN_CSTAT,
+ },
+ [VPE_CHAN_MV_OUT] = {
+ .num = VPE_CHAN_NUM_MV_OUT,
+ .cstat_offset = VPDMA_DEI_MV_OUT_CSTAT,
+ },
+ [VPE_CHAN_LUMA_OUT] = {
+ .num = VPE_CHAN_NUM_LUMA_OUT,
+ .cstat_offset = VPDMA_VIP_UP_Y_CSTAT,
+ },
+ [VPE_CHAN_CHROMA_OUT] = {
+ .num = VPE_CHAN_NUM_CHROMA_OUT,
+ .cstat_offset = VPDMA_VIP_UP_UV_CSTAT,
+ },
+ [VPE_CHAN_RGB_OUT] = {
+ .num = VPE_CHAN_NUM_RGB_OUT,
+ .cstat_offset = VPDMA_VIP_UP_Y_CSTAT,
+ },
+};
+
+static u32 read_reg(struct vpdma_data *vpdma, int offset)
+{
+ return ioread32(vpdma->base + offset);
+}
+
+static void write_reg(struct vpdma_data *vpdma, int offset, u32 value)
+{
+ iowrite32(value, vpdma->base + offset);
+}
+
+static int read_field_reg(struct vpdma_data *vpdma, int offset,
+ u32 mask, int shift)
+{
+ return (read_reg(vpdma, offset) & (mask << shift)) >> shift;
+}
+
+static void write_field_reg(struct vpdma_data *vpdma, int offset, u32 field,
+ u32 mask, int shift)
+{
+ u32 val = read_reg(vpdma, offset);
+
+ val &= ~(mask << shift);
+ val |= (field & mask) << shift;
+
+ write_reg(vpdma, offset, val);
+}
+
+void vpdma_dump_regs(struct vpdma_data *vpdma)
+{
+ struct device *dev = &vpdma->pdev->dev;
+
+#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(vpdma, VPDMA_##r))
+
+ dev_dbg(dev, "VPDMA Registers:\n");
+
+ DUMPREG(PID);
+ DUMPREG(LIST_ADDR);
+ DUMPREG(LIST_ATTR);
+ DUMPREG(LIST_STAT_SYNC);
+ DUMPREG(BG_RGB);
+ DUMPREG(BG_YUV);
+ DUMPREG(SETUP);
+ DUMPREG(MAX_SIZE1);
+ DUMPREG(MAX_SIZE2);
+ DUMPREG(MAX_SIZE3);
+
+ /*
+ * dumping registers of only group0 and group3, because VPE channels
+ * lie within group0 and group3 registers
+ */
+ DUMPREG(INT_CHAN_STAT(0));
+ DUMPREG(INT_CHAN_MASK(0));
+ DUMPREG(INT_CHAN_STAT(3));
+ DUMPREG(INT_CHAN_MASK(3));
+ DUMPREG(INT_CLIENT0_STAT);
+ DUMPREG(INT_CLIENT0_MASK);
+ DUMPREG(INT_CLIENT1_STAT);
+ DUMPREG(INT_CLIENT1_MASK);
+ DUMPREG(INT_LIST0_STAT);
+ DUMPREG(INT_LIST0_MASK);
+
+ /*
+ * these are registers specific to VPE clients, we can make this
+ * function dump client registers specific to VPE or VIP based on
+ * who is using it
+ */
+ DUMPREG(DEI_CHROMA1_CSTAT);
+ DUMPREG(DEI_LUMA1_CSTAT);
+ DUMPREG(DEI_CHROMA2_CSTAT);
+ DUMPREG(DEI_LUMA2_CSTAT);
+ DUMPREG(DEI_CHROMA3_CSTAT);
+ DUMPREG(DEI_LUMA3_CSTAT);
+ DUMPREG(DEI_MV_IN_CSTAT);
+ DUMPREG(DEI_MV_OUT_CSTAT);
+ DUMPREG(VIP_UP_Y_CSTAT);
+ DUMPREG(VIP_UP_UV_CSTAT);
+ DUMPREG(VPI_CTL_CSTAT);
+}
+EXPORT_SYMBOL(vpdma_dump_regs);
+
+/*
+ * Allocate a DMA buffer
+ */
+int vpdma_alloc_desc_buf(struct vpdma_buf *buf, size_t size)
+{
+ buf->size = size;
+ buf->mapped = false;
+ buf->addr = kzalloc(size, GFP_KERNEL);
+ if (!buf->addr)
+ return -ENOMEM;
+
+ WARN_ON(((unsigned long)buf->addr & VPDMA_DESC_ALIGN) != 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(vpdma_alloc_desc_buf);
+
+void vpdma_free_desc_buf(struct vpdma_buf *buf)
+{
+ WARN_ON(buf->mapped);
+ kfree(buf->addr);
+ buf->addr = NULL;
+ buf->size = 0;
+}
+EXPORT_SYMBOL(vpdma_free_desc_buf);
+
+/*
+ * map descriptor/payload DMA buffer, enabling DMA access
+ */
+int vpdma_map_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
+{
+ struct device *dev = &vpdma->pdev->dev;
+
+ WARN_ON(buf->mapped);
+ buf->dma_addr = dma_map_single(dev, buf->addr, buf->size,
+ DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(dev, buf->dma_addr)) {
+ dev_err(dev, "failed to map buffer\n");
+ return -EINVAL;
+ }
+
+ buf->mapped = true;
+
+ return 0;
+}
+EXPORT_SYMBOL(vpdma_map_desc_buf);
+
+/*
+ * unmap descriptor/payload DMA buffer, disabling DMA access and
+ * allowing the main processor to access the data
+ */
+void vpdma_unmap_desc_buf(struct vpdma_data *vpdma, struct vpdma_buf *buf)
+{
+ struct device *dev = &vpdma->pdev->dev;
+
+ if (buf->mapped)
+ dma_unmap_single(dev, buf->dma_addr, buf->size,
+ DMA_BIDIRECTIONAL);
+
+ buf->mapped = false;
+}
+EXPORT_SYMBOL(vpdma_unmap_desc_buf);
+
+/*
+ * Cleanup all pending descriptors of a list
+ * First, stop the current list being processed.
+ * If the VPDMA was busy, this step makes vpdma to accept post lists.
+ * To cleanup the internal FSM, post abort list descriptor for all the
+ * channels from @channels array of size @size.
+ */
+int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num,
+ int *channels, int size)
+{
+ struct vpdma_desc_list abort_list;
+ int i, ret, timeout = 500;
+
+ write_reg(vpdma, VPDMA_LIST_ATTR,
+ (list_num << VPDMA_LIST_NUM_SHFT) |
+ (1 << VPDMA_LIST_STOP_SHFT));
+
+ if (size <= 0 || !channels)
+ return 0;
+
+ ret = vpdma_create_desc_list(&abort_list,
+ size * sizeof(struct vpdma_dtd), VPDMA_LIST_TYPE_NORMAL);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < size; i++)
+ vpdma_add_abort_channel_ctd(&abort_list, channels[i]);
+
+ ret = vpdma_map_desc_buf(vpdma, &abort_list.buf);
+ if (ret)
+ goto free_desc;
+ ret = vpdma_submit_descs(vpdma, &abort_list, list_num);
+ if (ret)
+ goto unmap_desc;
+
+ while (vpdma_list_busy(vpdma, list_num) && --timeout)
+ ;
+
+ if (timeout == 0) {
+ dev_err(&vpdma->pdev->dev, "Timed out cleaning up VPDMA list\n");
+ ret = -EBUSY;
+ }
+
+unmap_desc:
+ vpdma_unmap_desc_buf(vpdma, &abort_list.buf);
+free_desc:
+ vpdma_free_desc_buf(&abort_list.buf);
+
+ return ret;
+}
+EXPORT_SYMBOL(vpdma_list_cleanup);
+
+/*
+ * create a descriptor list, the user of this list will append configuration,
+ * control and data descriptors to this list, this list will be submitted to
+ * VPDMA. VPDMA's list parser will go through each descriptor and perform the
+ * required DMA operations
+ */
+int vpdma_create_desc_list(struct vpdma_desc_list *list, size_t size, int type)
+{
+ int r;
+
+ r = vpdma_alloc_desc_buf(&list->buf, size);
+ if (r)
+ return r;
+
+ list->next = list->buf.addr;
+
+ list->type = type;
+
+ return 0;
+}
+EXPORT_SYMBOL(vpdma_create_desc_list);
+
+/*
+ * once a descriptor list is parsed by VPDMA, we reset the list by emptying it,
+ * to allow new descriptors to be added to the list.
+ */
+void vpdma_reset_desc_list(struct vpdma_desc_list *list)
+{
+ list->next = list->buf.addr;
+}
+EXPORT_SYMBOL(vpdma_reset_desc_list);
+
+/*
+ * free the buffer allocated for the VPDMA descriptor list, this should be
+ * called when the user doesn't want to use VPDMA any more.
+ */
+void vpdma_free_desc_list(struct vpdma_desc_list *list)
+{
+ vpdma_free_desc_buf(&list->buf);
+
+ list->next = NULL;
+}
+EXPORT_SYMBOL(vpdma_free_desc_list);
+
+bool vpdma_list_busy(struct vpdma_data *vpdma, int list_num)
+{
+ return read_reg(vpdma, VPDMA_LIST_STAT_SYNC) & BIT(list_num + 16);
+}
+EXPORT_SYMBOL(vpdma_list_busy);
+
+/*
+ * submit a list of DMA descriptors to the VPE VPDMA, do not wait for completion
+ */
+int vpdma_submit_descs(struct vpdma_data *vpdma,
+ struct vpdma_desc_list *list, int list_num)
+{
+ int list_size;
+ unsigned long flags;
+
+ if (vpdma_list_busy(vpdma, list_num))
+ return -EBUSY;
+
+ /* 16-byte granularity */
+ list_size = (list->next - list->buf.addr) >> 4;
+
+ spin_lock_irqsave(&vpdma->lock, flags);
+ write_reg(vpdma, VPDMA_LIST_ADDR, (u32) list->buf.dma_addr);
+
+ write_reg(vpdma, VPDMA_LIST_ATTR,
+ (list_num << VPDMA_LIST_NUM_SHFT) |
+ (list->type << VPDMA_LIST_TYPE_SHFT) |
+ list_size);
+ spin_unlock_irqrestore(&vpdma->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(vpdma_submit_descs);
+
+static void dump_dtd(struct vpdma_dtd *dtd);
+
+void vpdma_update_dma_addr(struct vpdma_data *vpdma,
+ struct vpdma_desc_list *list, dma_addr_t dma_addr,
+ void *write_dtd, int drop, int idx)
+{
+ struct vpdma_dtd *dtd = list->buf.addr;
+ dma_addr_t write_desc_addr;
+ int offset;
+
+ dtd += idx;
+ vpdma_unmap_desc_buf(vpdma, &list->buf);
+
+ dtd->start_addr = dma_addr;
+
+ /* Calculate write address from the offset of write_dtd from start
+ * of the list->buf
+ */
+ offset = (void *)write_dtd - list->buf.addr;
+ write_desc_addr = list->buf.dma_addr + offset;
+
+ if (drop)
+ dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
+ 1, 1, 0);
+ else
+ dtd->desc_write_addr = dtd_desc_write_addr(write_desc_addr,
+ 1, 0, 0);
+
+ vpdma_map_desc_buf(vpdma, &list->buf);
+
+ dump_dtd(dtd);
+}
+EXPORT_SYMBOL(vpdma_update_dma_addr);
+
+void vpdma_set_max_size(struct vpdma_data *vpdma, int reg_addr,
+ u32 width, u32 height)
+{
+ if (reg_addr != VPDMA_MAX_SIZE1 && reg_addr != VPDMA_MAX_SIZE2 &&
+ reg_addr != VPDMA_MAX_SIZE3)
+ reg_addr = VPDMA_MAX_SIZE1;
+
+ write_field_reg(vpdma, reg_addr, width - 1,
+ VPDMA_MAX_SIZE_WIDTH_MASK, VPDMA_MAX_SIZE_WIDTH_SHFT);
+
+ write_field_reg(vpdma, reg_addr, height - 1,
+ VPDMA_MAX_SIZE_HEIGHT_MASK, VPDMA_MAX_SIZE_HEIGHT_SHFT);
+
+}
+EXPORT_SYMBOL(vpdma_set_max_size);
+
+static void dump_cfd(struct vpdma_cfd *cfd)
+{
+ int class;
+
+ class = cfd_get_class(cfd);
+
+ pr_debug("config descriptor of payload class: %s\n",
+ class == CFD_CLS_BLOCK ? "simple block" :
+ "address data block");
+
+ if (class == CFD_CLS_BLOCK)
+ pr_debug("word0: dst_addr_offset = 0x%08x\n",
+ cfd->dest_addr_offset);
+
+ if (class == CFD_CLS_BLOCK)
+ pr_debug("word1: num_data_wrds = %d\n", cfd->block_len);
+
+ pr_debug("word2: payload_addr = 0x%08x\n", cfd->payload_addr);
+
+ pr_debug("word3: pkt_type = %d, direct = %d, class = %d, dest = %d, payload_len = %d\n",
+ cfd_get_pkt_type(cfd),
+ cfd_get_direct(cfd), class, cfd_get_dest(cfd),
+ cfd_get_payload_len(cfd));
+}
+
+/*
+ * append a configuration descriptor to the given descriptor list, where the
+ * payload is in the form of a simple data block specified in the descriptor
+ * header, this is used to upload scaler coefficients to the scaler module
+ */
+void vpdma_add_cfd_block(struct vpdma_desc_list *list, int client,
+ struct vpdma_buf *blk, u32 dest_offset)
+{
+ struct vpdma_cfd *cfd;
+ int len = blk->size;
+
+ WARN_ON(blk->dma_addr & VPDMA_DESC_ALIGN);
+
+ cfd = list->next;
+ WARN_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
+
+ cfd->dest_addr_offset = dest_offset;
+ cfd->block_len = len;
+ cfd->payload_addr = (u32) blk->dma_addr;
+ cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_BLOCK,
+ client, len >> 4);
+
+ list->next = cfd + 1;
+
+ dump_cfd(cfd);
+}
+EXPORT_SYMBOL(vpdma_add_cfd_block);
+
+/*
+ * append a configuration descriptor to the given descriptor list, where the
+ * payload is in the address data block format, this is used to a configure a
+ * discontiguous set of MMRs
+ */
+void vpdma_add_cfd_adb(struct vpdma_desc_list *list, int client,
+ struct vpdma_buf *adb)
+{
+ struct vpdma_cfd *cfd;
+ unsigned int len = adb->size;
+
+ WARN_ON(len & VPDMA_ADB_SIZE_ALIGN);
+ WARN_ON(adb->dma_addr & VPDMA_DESC_ALIGN);
+
+ cfd = list->next;
+ BUG_ON((void *)(cfd + 1) > (list->buf.addr + list->buf.size));
+
+ cfd->w0 = 0;
+ cfd->w1 = 0;
+ cfd->payload_addr = (u32) adb->dma_addr;
+ cfd->ctl_payload_len = cfd_pkt_payload_len(CFD_INDIRECT, CFD_CLS_ADB,
+ client, len >> 4);
+
+ list->next = cfd + 1;
+
+ dump_cfd(cfd);
+};
+EXPORT_SYMBOL(vpdma_add_cfd_adb);
+
+/*
+ * control descriptor format change based on what type of control descriptor it
+ * is, we only use 'sync on channel' control descriptors for now, so assume it's
+ * that
+ */
+static void dump_ctd(struct vpdma_ctd *ctd)
+{
+ pr_debug("control descriptor\n");
+
+ pr_debug("word3: pkt_type = %d, source = %d, ctl_type = %d\n",
+ ctd_get_pkt_type(ctd), ctd_get_source(ctd), ctd_get_ctl(ctd));
+}
+
+/*
+ * append a 'sync on channel' type control descriptor to the given descriptor
+ * list, this descriptor stalls the VPDMA list till the time DMA is completed
+ * on the specified channel
+ */
+void vpdma_add_sync_on_channel_ctd(struct vpdma_desc_list *list,
+ enum vpdma_channel chan)
+{
+ struct vpdma_ctd *ctd;
+
+ ctd = list->next;
+ WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
+
+ ctd->w0 = 0;
+ ctd->w1 = 0;
+ ctd->w2 = 0;
+ ctd->type_source_ctl = ctd_type_source_ctl(chan_info[chan].num,
+ CTD_TYPE_SYNC_ON_CHANNEL);
+
+ list->next = ctd + 1;
+
+ dump_ctd(ctd);
+}
+EXPORT_SYMBOL(vpdma_add_sync_on_channel_ctd);
+
+/*
+ * append an 'abort_channel' type control descriptor to the given descriptor
+ * list, this descriptor aborts any DMA transaction happening using the
+ * specified channel
+ */
+void vpdma_add_abort_channel_ctd(struct vpdma_desc_list *list,
+ int chan_num)
+{
+ struct vpdma_ctd *ctd;
+
+ ctd = list->next;
+ WARN_ON((void *)(ctd + 1) > (list->buf.addr + list->buf.size));
+
+ ctd->w0 = 0;
+ ctd->w1 = 0;
+ ctd->w2 = 0;
+ ctd->type_source_ctl = ctd_type_source_ctl(chan_num,
+ CTD_TYPE_ABORT_CHANNEL);
+
+ list->next = ctd + 1;
+
+ dump_ctd(ctd);
+}
+EXPORT_SYMBOL(vpdma_add_abort_channel_ctd);
+
+static void dump_dtd(struct vpdma_dtd *dtd)
+{
+ int dir, chan;
+
+ dir = dtd_get_dir(dtd);
+ chan = dtd_get_chan(dtd);
+
+ pr_debug("%s data transfer descriptor for channel %d\n",
+ dir == DTD_DIR_OUT ? "outbound" : "inbound", chan);
+
+ pr_debug("word0: data_type = %d, notify = %d, field = %d, 1D = %d, even_ln_skp = %d, odd_ln_skp = %d, line_stride = %d\n",
+ dtd_get_data_type(dtd), dtd_get_notify(dtd), dtd_get_field(dtd),
+ dtd_get_1d(dtd), dtd_get_even_line_skip(dtd),
+ dtd_get_odd_line_skip(dtd), dtd_get_line_stride(dtd));
+
+ if (dir == DTD_DIR_IN)
+ pr_debug("word1: line_length = %d, xfer_height = %d\n",
+ dtd_get_line_length(dtd), dtd_get_xfer_height(dtd));
+
+ pr_debug("word2: start_addr = %x\n", dtd->start_addr);
+
+ pr_debug("word3: pkt_type = %d, mode = %d, dir = %d, chan = %d, pri = %d, next_chan = %d\n",
+ dtd_get_pkt_type(dtd),
+ dtd_get_mode(dtd), dir, chan, dtd_get_priority(dtd),
+ dtd_get_next_chan(dtd));
+
+ if (dir == DTD_DIR_IN)
+ pr_debug("word4: frame_width = %d, frame_height = %d\n",
+ dtd_get_frame_width(dtd), dtd_get_frame_height(dtd));
+ else
+ pr_debug("word4: desc_write_addr = 0x%08x, write_desc = %d, drp_data = %d, use_desc_reg = %d\n",
+ dtd_get_desc_write_addr(dtd), dtd_get_write_desc(dtd),
+ dtd_get_drop_data(dtd), dtd_get_use_desc(dtd));
+
+ if (dir == DTD_DIR_IN)
+ pr_debug("word5: hor_start = %d, ver_start = %d\n",
+ dtd_get_h_start(dtd), dtd_get_v_start(dtd));
+ else
+ pr_debug("word5: max_width %d, max_height %d\n",
+ dtd_get_max_width(dtd), dtd_get_max_height(dtd));
+
+ pr_debug("word6: client specific attr0 = 0x%08x\n", dtd->client_attr0);
+ pr_debug("word7: client specific attr1 = 0x%08x\n", dtd->client_attr1);
+}
+
+/*
+ * append an outbound data transfer descriptor to the given descriptor list,
+ * this sets up a 'client to memory' VPDMA transfer for the given VPDMA channel
+ *
+ * @list: vpdma desc list to which we add this descriptor
+ * @width: width of the image in pixels in memory
+ * @c_rect: compose params of output image
+ * @fmt: vpdma data format of the buffer
+ * dma_addr: dma address as seen by VPDMA
+ * max_width: enum for maximum width of data transfer
+ * max_height: enum for maximum height of data transfer
+ * chan: VPDMA channel
+ * flags: VPDMA flags to configure some descriptor fields
+ */
+void vpdma_add_out_dtd(struct vpdma_desc_list *list, int width,
+ int stride, const struct v4l2_rect *c_rect,
+ const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
+ int max_w, int max_h, enum vpdma_channel chan, u32 flags)
+{
+ vpdma_rawchan_add_out_dtd(list, width, stride, c_rect, fmt, dma_addr,
+ max_w, max_h, chan_info[chan].num, flags);
+}
+EXPORT_SYMBOL(vpdma_add_out_dtd);
+
+void vpdma_rawchan_add_out_dtd(struct vpdma_desc_list *list, int width,
+ int stride, const struct v4l2_rect *c_rect,
+ const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
+ int max_w, int max_h, int raw_vpdma_chan, u32 flags)
+{
+ int priority = 0;
+ int field = 0;
+ int notify = 1;
+ int channel, next_chan;
+ struct v4l2_rect rect = *c_rect;
+ int depth = fmt->depth;
+ struct vpdma_dtd *dtd;
+
+ channel = next_chan = raw_vpdma_chan;
+
+ if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
+ (fmt->data_type == DATA_TYPE_C420 ||
+ fmt->data_type == DATA_TYPE_CB420)) {
+ rect.height >>= 1;
+ rect.top >>= 1;
+ depth = 8;
+ }
+
+ dma_addr += rect.top * stride + (rect.left * depth >> 3);
+
+ dtd = list->next;
+ WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
+
+ dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
+ notify,
+ field,
+ !!(flags & VPDMA_DATA_FRAME_1D),
+ !!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
+ !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
+ stride);
+ dtd->w1 = 0;
+ dtd->start_addr = (u32) dma_addr;
+ dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
+ DTD_DIR_OUT, channel, priority, next_chan);
+ dtd->desc_write_addr = dtd_desc_write_addr(0, 0, 0, 0);
+ dtd->max_width_height = dtd_max_width_height(max_w, max_h);
+ dtd->client_attr0 = 0;
+ dtd->client_attr1 = 0;
+
+ list->next = dtd + 1;
+
+ dump_dtd(dtd);
+}
+EXPORT_SYMBOL(vpdma_rawchan_add_out_dtd);
+
+/*
+ * append an inbound data transfer descriptor to the given descriptor list,
+ * this sets up a 'memory to client' VPDMA transfer for the given VPDMA channel
+ *
+ * @list: vpdma desc list to which we add this descriptor
+ * @width: width of the image in pixels in memory(not the cropped width)
+ * @c_rect: crop params of input image
+ * @fmt: vpdma data format of the buffer
+ * dma_addr: dma address as seen by VPDMA
+ * chan: VPDMA channel
+ * field: top or bottom field info of the input image
+ * flags: VPDMA flags to configure some descriptor fields
+ * frame_width/height: the complete width/height of the image presented to the
+ * client (this makes sense when multiple channels are
+ * connected to the same client, forming a larger frame)
+ * start_h, start_v: position where the given channel starts providing pixel
+ * data to the client (makes sense when multiple channels
+ * contribute to the client)
+ */
+void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width,
+ int stride, const struct v4l2_rect *c_rect,
+ const struct vpdma_data_format *fmt, dma_addr_t dma_addr,
+ enum vpdma_channel chan, int field, u32 flags, int frame_width,
+ int frame_height, int start_h, int start_v)
+{
+ int priority = 0;
+ int notify = 1;
+ int depth = fmt->depth;
+ int channel, next_chan;
+ struct v4l2_rect rect = *c_rect;
+ struct vpdma_dtd *dtd;
+
+ channel = next_chan = chan_info[chan].num;
+
+ if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV &&
+ (fmt->data_type == DATA_TYPE_C420 ||
+ fmt->data_type == DATA_TYPE_CB420)) {
+ rect.height >>= 1;
+ rect.top >>= 1;
+ depth = 8;
+ }
+
+ dma_addr += rect.top * stride + (rect.left * depth >> 3);
+
+ dtd = list->next;
+ WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size));
+
+ dtd->type_ctl_stride = dtd_type_ctl_stride(fmt->data_type,
+ notify,
+ field,
+ !!(flags & VPDMA_DATA_FRAME_1D),
+ !!(flags & VPDMA_DATA_EVEN_LINE_SKIP),
+ !!(flags & VPDMA_DATA_ODD_LINE_SKIP),
+ stride);
+
+ dtd->xfer_length_height = dtd_xfer_length_height(rect.width,
+ rect.height);
+ dtd->start_addr = (u32) dma_addr;
+ dtd->pkt_ctl = dtd_pkt_ctl(!!(flags & VPDMA_DATA_MODE_TILED),
+ DTD_DIR_IN, channel, priority, next_chan);
+ dtd->frame_width_height = dtd_frame_width_height(frame_width,
+ frame_height);
+ dtd->start_h_v = dtd_start_h_v(start_h, start_v);
+ dtd->client_attr0 = 0;
+ dtd->client_attr1 = 0;
+
+ list->next = dtd + 1;
+
+ dump_dtd(dtd);
+}
+EXPORT_SYMBOL(vpdma_add_in_dtd);
+
+int vpdma_hwlist_alloc(struct vpdma_data *vpdma, void *priv)
+{
+ int i, list_num = -1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vpdma->lock, flags);
+ for (i = 0; i < VPDMA_MAX_NUM_LIST && vpdma->hwlist_used[i]; i++)
+ ;
+
+ if (i < VPDMA_MAX_NUM_LIST) {
+ list_num = i;
+ vpdma->hwlist_used[i] = true;
+ vpdma->hwlist_priv[i] = priv;
+ }
+ spin_unlock_irqrestore(&vpdma->lock, flags);
+
+ return list_num;
+}
+EXPORT_SYMBOL(vpdma_hwlist_alloc);
+
+void *vpdma_hwlist_get_priv(struct vpdma_data *vpdma, int list_num)
+{
+ if (!vpdma || list_num >= VPDMA_MAX_NUM_LIST)
+ return NULL;
+
+ return vpdma->hwlist_priv[list_num];
+}
+EXPORT_SYMBOL(vpdma_hwlist_get_priv);
+
+void *vpdma_hwlist_release(struct vpdma_data *vpdma, int list_num)
+{
+ void *priv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&vpdma->lock, flags);
+ vpdma->hwlist_used[list_num] = false;
+ priv = vpdma->hwlist_priv;
+ spin_unlock_irqrestore(&vpdma->lock, flags);
+
+ return priv;
+}
+EXPORT_SYMBOL(vpdma_hwlist_release);
+
+/* set or clear the mask for list complete interrupt */
+void vpdma_enable_list_complete_irq(struct vpdma_data *vpdma, int irq_num,
+ int list_num, bool enable)
+{
+ u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
+ u32 val;
+
+ val = read_reg(vpdma, reg_addr);
+ if (enable)
+ val |= (1 << (list_num * 2));
+ else
+ val &= ~(1 << (list_num * 2));
+ write_reg(vpdma, reg_addr, val);
+}
+EXPORT_SYMBOL(vpdma_enable_list_complete_irq);
+
+/* get the LIST_STAT register */
+unsigned int vpdma_get_list_stat(struct vpdma_data *vpdma, int irq_num)
+{
+ u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
+
+ return read_reg(vpdma, reg_addr);
+}
+EXPORT_SYMBOL(vpdma_get_list_stat);
+
+/* get the LIST_MASK register */
+unsigned int vpdma_get_list_mask(struct vpdma_data *vpdma, int irq_num)
+{
+ u32 reg_addr = VPDMA_INT_LIST0_MASK + VPDMA_INTX_OFFSET * irq_num;
+
+ return read_reg(vpdma, reg_addr);
+}
+EXPORT_SYMBOL(vpdma_get_list_mask);
+
+/* clear previously occurred list interrupts in the LIST_STAT register */
+void vpdma_clear_list_stat(struct vpdma_data *vpdma, int irq_num,
+ int list_num)
+{
+ u32 reg_addr = VPDMA_INT_LIST0_STAT + VPDMA_INTX_OFFSET * irq_num;
+
+ write_reg(vpdma, reg_addr, 3 << (list_num * 2));
+}
+EXPORT_SYMBOL(vpdma_clear_list_stat);
+
+void vpdma_set_bg_color(struct vpdma_data *vpdma,
+ struct vpdma_data_format *fmt, u32 color)
+{
+ if (fmt->type == VPDMA_DATA_FMT_TYPE_RGB)
+ write_reg(vpdma, VPDMA_BG_RGB, color);
+ else if (fmt->type == VPDMA_DATA_FMT_TYPE_YUV)
+ write_reg(vpdma, VPDMA_BG_YUV, color);
+}
+EXPORT_SYMBOL(vpdma_set_bg_color);
+
+/*
+ * configures the output mode of the line buffer for the given client, the
+ * line buffer content can either be mirrored(each line repeated twice) or
+ * passed to the client as is
+ */
+void vpdma_set_line_mode(struct vpdma_data *vpdma, int line_mode,
+ enum vpdma_channel chan)
+{
+ int client_cstat = chan_info[chan].cstat_offset;
+
+ write_field_reg(vpdma, client_cstat, line_mode,
+ VPDMA_CSTAT_LINE_MODE_MASK, VPDMA_CSTAT_LINE_MODE_SHIFT);
+}
+EXPORT_SYMBOL(vpdma_set_line_mode);
+
+/*
+ * configures the event which should trigger VPDMA transfer for the given
+ * client
+ */
+void vpdma_set_frame_start_event(struct vpdma_data *vpdma,
+ enum vpdma_frame_start_event fs_event,
+ enum vpdma_channel chan)
+{
+ int client_cstat = chan_info[chan].cstat_offset;
+
+ write_field_reg(vpdma, client_cstat, fs_event,
+ VPDMA_CSTAT_FRAME_START_MASK, VPDMA_CSTAT_FRAME_START_SHIFT);
+}
+EXPORT_SYMBOL(vpdma_set_frame_start_event);
+
+static void vpdma_firmware_cb(const struct firmware *f, void *context)
+{
+ struct vpdma_data *vpdma = context;
+ struct vpdma_buf fw_dma_buf;
+ int i, r;
+
+ dev_dbg(&vpdma->pdev->dev, "firmware callback\n");
+
+ if (!f || !f->data) {
+ dev_err(&vpdma->pdev->dev, "couldn't get firmware\n");
+ return;
+ }
+
+ /* already initialized */
+ if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
+ VPDMA_LIST_RDY_SHFT)) {
+ vpdma->cb(vpdma->pdev);
+ return;
+ }
+
+ r = vpdma_alloc_desc_buf(&fw_dma_buf, f->size);
+ if (r) {
+ dev_err(&vpdma->pdev->dev,
+ "failed to allocate dma buffer for firmware\n");
+ goto rel_fw;
+ }
+
+ memcpy(fw_dma_buf.addr, f->data, f->size);
+
+ vpdma_map_desc_buf(vpdma, &fw_dma_buf);
+
+ write_reg(vpdma, VPDMA_LIST_ADDR, (u32) fw_dma_buf.dma_addr);
+
+ for (i = 0; i < 100; i++) { /* max 1 second */
+ msleep_interruptible(10);
+
+ if (read_field_reg(vpdma, VPDMA_LIST_ATTR, VPDMA_LIST_RDY_MASK,
+ VPDMA_LIST_RDY_SHFT))
+ break;
+ }
+
+ if (i == 100) {
+ dev_err(&vpdma->pdev->dev, "firmware upload failed\n");
+ goto free_buf;
+ }
+
+ vpdma->cb(vpdma->pdev);
+
+free_buf:
+ vpdma_unmap_desc_buf(vpdma, &fw_dma_buf);
+
+ vpdma_free_desc_buf(&fw_dma_buf);
+rel_fw:
+ release_firmware(f);
+}
+
+static int vpdma_load_firmware(struct vpdma_data *vpdma)
+{
+ int r;
+ struct device *dev = &vpdma->pdev->dev;
+
+ r = request_firmware_nowait(THIS_MODULE, 1,
+ (const char *) VPDMA_FIRMWARE, dev, GFP_KERNEL, vpdma,
+ vpdma_firmware_cb);
+ if (r) {
+ dev_err(dev, "firmware not available %s\n", VPDMA_FIRMWARE);
+ return r;
+ } else {
+ dev_info(dev, "loading firmware %s\n", VPDMA_FIRMWARE);
+ }
+
+ return 0;
+}
+
+int vpdma_create(struct platform_device *pdev, struct vpdma_data *vpdma,
+ void (*cb)(struct platform_device *pdev))
+{
+ struct resource *res;
+ int r;
+
+ dev_dbg(&pdev->dev, "vpdma_create\n");
+
+ vpdma->pdev = pdev;
+ vpdma->cb = cb;
+ spin_lock_init(&vpdma->lock);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vpdma");
+ if (res == NULL) {
+ dev_err(&pdev->dev, "missing platform resources data\n");
+ return -ENODEV;
+ }
+
+ vpdma->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!vpdma->base) {
+ dev_err(&pdev->dev, "failed to ioremap\n");
+ return -ENOMEM;
+ }
+
+ r = vpdma_load_firmware(vpdma);
+ if (r) {
+ pr_err("failed to load firmware %s\n", VPDMA_FIRMWARE);
+ return r;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(vpdma_create);
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_FIRMWARE(VPDMA_FIRMWARE);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti/vpe/vpdma.h b/drivers/media/platform/ti/vpe/vpdma.h
new file mode 100644
index 000000000000..393fcbb3cb40
--- /dev/null
+++ b/drivers/media/platform/ti/vpe/vpdma.h
@@ -0,0 +1,284 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2013 Texas Instruments Inc.
+ *
+ * David Griego,
+ * Dale Farnsworth,
+ * Archit Taneja,