Merge tag 'media/v7.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:

 - Add support for GMSL1 and GMSL‑coax modules (PCI mgb4)

 - Add driver for TI VIP

 - AV1 – first kernel support (pixel‑format, decoder, transcoder)

 - Three new camera‑sensor drivers (os05b10, s5k3m5, s5kjn1)

 - Synopsys CSI‑2 receiver driver

 - Verisilicon & rkvdec – major fixes and enhancements

 - IPU6 (and 7) fixes and preparation for metadata

 - omap3isp: v4l2-compliance updates

 - Fix DVB streaming, drop wait_prepare/finish (dvb/vb2)

* tag 'media/v7.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (307 commits)
  media: uvcvideo: Pass allocation size directly to uvc_alloc_urb_buffer
  media: uvcvideo: Fix allocation for small frame sizes
  media: uvcvideo: Return queued buffers on start_streaming() failure
  media: uvcvideo: Create an ID namespace for streaming output terminals
  media: rkvdec: Add HEVC support for the VDPU383 variant
  media: rkvdec: Add HEVC support for the VDPU381 variant
  media: rkvdec: Add H264 support for the VDPU383 variant
  media: rkvdec: Add H264 support for the VDPU381 variant
  media: rkvdec: Disable multicore support
  media: rkvdec: Enable all clocks without naming them
  media: rkvdec: Support per-variant interrupt handler
  media: rkvdec: Add RCB and SRAM support
  media: rkvdec: Add variant specific coded formats list
  media: rkvdec: Move hevc functions to common file
  media: rkvdec: Move h264 functions to common file
  media: rkvdec: Use structs to represent the HW RPS
  media: rkvdec: Move cabac tables to their own source file
  media: rkvdec: Switch to using structs instead of writel
  media: visl: Add HEVC short and long term RPS sets
  media: v4l2-ctrls: Add hevc_ext_sps_[ls]t_rps controls
  ...
This commit is contained in:
Linus Torvalds
2026-02-11 12:20:25 -08:00
265 changed files with 23552 additions and 4743 deletions

View File

@@ -2961,11 +2961,8 @@ int atomisp_set_parameters(struct video_device *vdev,
* per-frame setting only works for the main output frame.
*/
param = kvzalloc(sizeof(*param), GFP_KERNEL);
if (!param) {
dev_err(asd->isp->dev, "%s: failed to alloc params buffer\n",
__func__);
if (!param)
return -ENOMEM;
}
css_param = &param->params;
}

View File

@@ -35,7 +35,8 @@ ia_css_formats_dump(
const struct sh_css_isp_formats_params *formats,
unsigned int level)
{
if (!formats) return;
if (!formats)
return;
ia_css_debug_dtrace(level, "\t%-32s = %d\n",
"video_full_range_flag", formats->video_full_range_flag);
}

View File

@@ -312,7 +312,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
pr_err("%s(): timeout waiting for MSGSTATE %04x\n", __func__, stat & flags);
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
return 0;
}
@@ -343,7 +343,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16 *buf, int length)
av7110->arm_errors++;
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
if (FW_VERSION(av7110->arm_app) <= 0x261f)
@@ -359,7 +359,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16 *buf, int length)
pr_err("%s(): timeout waiting for HANDSHAKE_REG\n", __func__);
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
#endif
@@ -405,7 +405,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16 *buf, int length)
av7110->arm_errors++;
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
}
@@ -433,7 +433,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16 *buf, int length)
__func__, (buf[0] >> 8) & 0xff);
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
@@ -559,7 +559,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
return -ETIMEDOUT;
}
#ifdef _NOHANDSHAKE
msleep(1);
usleep_range(1000, 2000);
#endif
}
@@ -574,7 +574,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
#endif
@@ -719,7 +719,7 @@ static int FlushText(struct av7110 *av7110)
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
mutex_unlock(&av7110->dcomlock);
return 0;
@@ -745,7 +745,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
#ifndef _NOHANDSHAKE
start = jiffies;
@@ -758,7 +758,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf)
mutex_unlock(&av7110->dcomlock);
return -ETIMEDOUT;
}
msleep(1);
usleep_range(1000, 2000);
}
#endif
for (i = 0; i < length / 2; i++)

View File

@@ -496,7 +496,7 @@ static int sp8870_set_frontend(struct dvb_frontend *fe)
dprintk("delay = %i usec\n", check_count * 10);
break;
}
udelay(10);
usleep_range(10, 20);
}
if (valid)
break;

View File

@@ -23,65 +23,65 @@
* there must be 5 pads: 1 input pad from sensor, and
* the 4 virtual channel output pads
*/
#define CSI2_SINK_PAD 0
#define CSI2_NUM_SINK_PADS 1
#define CSI2_NUM_SRC_PADS 4
#define CSI2_NUM_PADS 5
#define CSI2_SINK_PAD 0
#define CSI2_NUM_SINK_PADS 1
#define CSI2_NUM_SRC_PADS 4
#define CSI2_NUM_PADS 5
/*
* The default maximum bit-rate per lane in Mbps, if the
* source subdev does not provide V4L2_CID_LINK_FREQ.
*/
#define CSI2_DEFAULT_MAX_MBPS 849
#define CSI2_DEFAULT_MAX_MBPS 849
struct csi2_dev {
struct device *dev;
struct v4l2_subdev sd;
struct device *dev;
struct v4l2_subdev sd;
struct v4l2_async_notifier notifier;
struct media_pad pad[CSI2_NUM_PADS];
struct clk *dphy_clk;
struct clk *pllref_clk;
struct clk *pix_clk; /* what is this? */
void __iomem *base;
struct media_pad pad[CSI2_NUM_PADS];
struct clk *dphy_clk;
struct clk *pllref_clk;
struct clk *pix_clk; /* what is this? */
void __iomem *base;
struct v4l2_subdev *remote;
unsigned int remote_pad;
unsigned short data_lanes;
struct v4l2_subdev *remote;
unsigned int remote_pad;
unsigned short data_lanes;
/* lock to protect all members below */
struct mutex lock;
struct v4l2_mbus_framefmt format_mbus;
int stream_count;
struct v4l2_subdev *src_sd;
bool sink_linked[CSI2_NUM_SRC_PADS];
int stream_count;
struct v4l2_subdev *src_sd;
bool sink_linked[CSI2_NUM_SRC_PADS];
};
#define DEVICE_NAME "imx6-mipi-csi2"
/* Register offsets */
#define CSI2_VERSION 0x000
#define CSI2_N_LANES 0x004
#define CSI2_PHY_SHUTDOWNZ 0x008
#define CSI2_DPHY_RSTZ 0x00c
#define CSI2_RESETN 0x010
#define CSI2_PHY_STATE 0x014
#define PHY_STOPSTATEDATA_BIT 4
#define PHY_STOPSTATEDATA(n) BIT(PHY_STOPSTATEDATA_BIT + (n))
#define PHY_RXCLKACTIVEHS BIT(8)
#define PHY_RXULPSCLKNOT BIT(9)
#define PHY_STOPSTATECLK BIT(10)
#define CSI2_DATA_IDS_1 0x018
#define CSI2_DATA_IDS_2 0x01c
#define CSI2_ERR1 0x020
#define CSI2_ERR2 0x024
#define CSI2_MSK1 0x028
#define CSI2_MSK2 0x02c
#define CSI2_PHY_TST_CTRL0 0x030
#define CSI2_VERSION 0x000
#define CSI2_N_LANES 0x004
#define CSI2_PHY_SHUTDOWNZ 0x008
#define CSI2_DPHY_RSTZ 0x00c
#define CSI2_RESETN 0x010
#define CSI2_PHY_STATE 0x014
#define PHY_STOPSTATEDATA_BIT 4
#define PHY_STOPSTATEDATA(n) BIT(PHY_STOPSTATEDATA_BIT + (n))
#define PHY_RXCLKACTIVEHS BIT(8)
#define PHY_RXULPSCLKNOT BIT(9)
#define PHY_STOPSTATECLK BIT(10)
#define CSI2_DATA_IDS_1 0x018
#define CSI2_DATA_IDS_2 0x01c
#define CSI2_ERR1 0x020
#define CSI2_ERR2 0x024
#define CSI2_MSK1 0x028
#define CSI2_MSK2 0x02c
#define CSI2_PHY_TST_CTRL0 0x030
#define PHY_TESTCLR BIT(0)
#define PHY_TESTCLK BIT(1)
#define CSI2_PHY_TST_CTRL1 0x034
#define CSI2_PHY_TST_CTRL1 0x034
#define PHY_TESTEN BIT(16)
/*
* i.MX CSI2IPU Gasket registers follow. The CSI2IPU gasket is
@@ -106,13 +106,13 @@ static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
* reference manual is as follows:
*
* 1. Deassert presetn signal (global reset).
* It's not clear what this "global reset" signal is (maybe APB
* global reset), but in any case this step would be probably
* be carried out during driver load in csi2_probe().
* It's not clear what this "global reset" signal is (maybe APB
* global reset), but in any case this step would be probably
* be carried out during driver load in csi2_probe().
*
* 2. Configure MIPI Camera Sensor to put all Tx lanes in LP-11 state.
* This must be carried out by the MIPI sensor's s_power(ON) subdev
* op.
* This must be carried out by the MIPI sensor's s_power(ON) subdev
* op.
*
* 3. D-PHY initialization.
* 4. CSI2 Controller programming (Set N_LANES, deassert PHY_SHUTDOWNZ,
@@ -719,7 +719,6 @@ err_parse:
static int csi2_probe(struct platform_device *pdev)
{
struct csi2_dev *csi2;
struct resource *res;
int i, ret;
csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
@@ -767,22 +766,18 @@ static int csi2_probe(struct platform_device *pdev)
return PTR_ERR(csi2->pix_clk);
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
v4l2_err(&csi2->sd, "failed to get platform resources\n");
return -ENODEV;
}
csi2->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(csi2->base))
return PTR_ERR(csi2->base);
csi2->base = devm_ioremap(&pdev->dev, res->start, PAGE_SIZE);
if (!csi2->base)
return -ENOMEM;
mutex_init(&csi2->lock);
ret = devm_mutex_init(&pdev->dev, &csi2->lock);
if (ret)
return ret;
ret = clk_prepare_enable(csi2->pllref_clk);
if (ret) {
v4l2_err(&csi2->sd, "failed to enable pllref_clk\n");
goto rmmutex;
return ret;
}
ret = clk_prepare_enable(csi2->dphy_clk);
@@ -805,8 +800,6 @@ clean_notifier:
clk_disable_unprepare(csi2->dphy_clk);
pllref_off:
clk_disable_unprepare(csi2->pllref_clk);
rmmutex:
mutex_destroy(&csi2->lock);
return ret;
}
@@ -820,7 +813,6 @@ static void csi2_remove(struct platform_device *pdev)
v4l2_async_unregister_subdev(sd);
clk_disable_unprepare(csi2->dphy_clk);
clk_disable_unprepare(csi2->pllref_clk);
mutex_destroy(&csi2->lock);
media_entity_cleanup(&sd->entity);
}

View File

@@ -342,14 +342,23 @@ irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr)
u32 disable_irqs = 0;
u32 irq_status;
unsigned int i;
int active;
pm_runtime_get_noresume(dev);
active = pm_runtime_get_if_active(dev);
if (active <= 0)
return IRQ_NONE;
pb_irq = readl(isp->pb_base + INTERRUPT_STATUS);
writel(pb_irq, isp->pb_base + INTERRUPT_STATUS);
/* check btrs ATS, CFI and IMR errors, BIT(0) is unused for IPU */
pb_local_irq = readl(isp->pb_base + BTRS_LOCAL_INTERRUPT_MASK);
if (pb_local_irq == 0xffffffff) {
dev_warn_once(dev, "invalid PB irq status\n");
pm_runtime_put_noidle(dev);
return IRQ_NONE;
}
if (pb_local_irq & ~BIT(0)) {
dev_warn(dev, "PB interrupt status 0x%x local 0x%x\n", pb_irq,
pb_local_irq);
@@ -370,6 +379,12 @@ irqreturn_t ipu_buttress_isr(int irq, void *isp_ptr)
return IRQ_NONE;
}
if (irq_status == 0xffffffff) {
dev_warn_once(dev, "invalid irq status 0x%08x\n", irq_status);
pm_runtime_put_noidle(dev);
return IRQ_NONE;
}
do {
writel(irq_status, isp->base + BUTTRESS_REG_IRQ_CLEAR);

View File

@@ -124,6 +124,7 @@ static const struct cdr_fbk_cap_prog_params table7[] = {
{ 1350, 1589, 4 },
{ 1590, 1949, 5 },
{ 1950, 2499, 6 },
{ 2500, 3500, 7 },
{ }
};
@@ -838,9 +839,10 @@ static void ipu7_isys_cphy_config(struct ipu7_isys *isys, u8 id, u8 lanes,
dwc_phy_write_mask(isys, id, reg + 0x400 * i,
reset_thresh, 9, 11);
/* Tuning ITMINRX to 2 for CPHY */
reg = CORE_DIG_CLANE_0_RW_LP_0;
for (i = 0; i < trios; i++)
dwc_phy_write_mask(isys, id, reg + 0x400 * i, 1, 12, 15);
dwc_phy_write_mask(isys, id, reg + 0x400 * i, 2, 12, 15);
reg = CORE_DIG_CLANE_0_RW_LP_2;
for (i = 0; i < trios; i++)
@@ -860,7 +862,11 @@ static void ipu7_isys_cphy_config(struct ipu7_isys *isys, u8 id, u8 lanes,
for (i = 0; i < (lanes + 1); i++) {
reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_9 + 0x400 * i;
dwc_phy_write_mask(isys, id, reg, 4U, 0, 2);
dwc_phy_write_mask(isys, id, reg, 0U, 3, 4);
/* Set GMODE to 2 when CPHY >= 1.5Gsps */
if (mbps >= 1500)
dwc_phy_write_mask(isys, id, reg, 2U, 3, 4);
else
dwc_phy_write_mask(isys, id, reg, 0U, 3, 4);
reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_7 + 0x400 * i;
dwc_phy_write_mask(isys, id, reg, cap_prog, 10, 12);
@@ -930,8 +936,9 @@ static int ipu7_isys_phy_config(struct ipu7_isys *isys, u8 id, u8 lanes,
7, 12, 14);
dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_7,
0, 8, 10);
/* resistance tuning: 1 for 45ohm, 0 for 50ohm */
dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_CB_CTRL_2_5,
0, 8, 8);
1, 8, 8);
if (aggregation)
phy_mode = isys->csi2[0].phy_mode;

View File

@@ -231,7 +231,7 @@ static u32 *alloc_l2_pt(struct ipu7_mmu_info *mmu_info)
dev_dbg(mmu_info->dev, "alloc_l2: get_zeroed_page() = %p\n", pt);
for (i = 0; i < ISP_L1PT_PTES; i++)
for (i = 0; i < ISP_L2PT_PTES; i++)
pt[i] = mmu_info->dummy_page_pteval;
return pt;

View File

@@ -2620,7 +2620,7 @@ out_ipu_bus_del_devices:
if (!IS_ERR_OR_NULL(isp->isys) && !IS_ERR_OR_NULL(isp->isys->mmu))
ipu7_mmu_cleanup(isp->isys->mmu);
if (!IS_ERR_OR_NULL(isp->psys))
pm_runtime_put(&isp->psys->auxdev.dev);
pm_runtime_put_sync(&isp->psys->auxdev.dev);
ipu7_bus_del_devices(pdev);
release_firmware(isp->cpd_fw);
buttress_exit:
@@ -2684,6 +2684,10 @@ static void ipu7_pci_reset_done(struct pci_dev *pdev)
*/
static int ipu7_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
synchronize_irq(pdev->irq);
return 0;
}

View File

@@ -835,10 +835,6 @@ static void tegra_csi_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
}
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
extern const struct tegra_csi_soc tegra210_csi_soc;
#endif
static const struct of_device_id tegra_csi_of_id_table[] = {
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
{ .compatible = "nvidia,tegra210-csi", .data = &tegra210_csi_soc },

View File

@@ -130,6 +130,10 @@ struct tegra_csi_soc {
unsigned int tpg_frmrate_table_size;
};
#if defined(CONFIG_ARCH_TEGRA_210_SOC)
extern const struct tegra_csi_soc tegra210_csi_soc;
#endif
/**
* struct tegra_csi - NVIDIA Tegra CSI device structure
*

View File

@@ -438,7 +438,7 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
.target = V4L2_SEL_TGT_CROP_BOUNDS,
};
struct v4l2_rect *try_crop;
int ret;
int ret = 0;
subdev = tegra_channel_get_remote_source_subdev(chan);
if (!subdev)
@@ -482,8 +482,10 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
} else {
ret = v4l2_subdev_call(subdev, pad, get_selection,
NULL, &sdsel);
if (ret)
return -EINVAL;
if (ret) {
ret = -EINVAL;
goto out_free;
}
try_crop->width = sdsel.r.width;
try_crop->height = sdsel.r.height;
@@ -495,14 +497,15 @@ static int __tegra_channel_try_format(struct tegra_vi_channel *chan,
ret = v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &fmt);
if (ret < 0)
return ret;
goto out_free;
v4l2_fill_pix_format(pix, &fmt.format);
chan->vi->ops->vi_fmt_align(pix, fmtinfo->bpp);
out_free:
__v4l2_subdev_state_free(sd_state);
return 0;
return ret;
}
static int tegra_channel_try_format(struct file *file, void *fh,

View File

@@ -263,10 +263,6 @@ static void tegra_vip_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
}
#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
extern const struct tegra_vip_soc tegra20_vip_soc;
#endif
static const struct of_device_id tegra_vip_of_id_table[] = {
#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
{ .compatible = "nvidia,tegra20-vip", .data = &tegra20_vip_soc },

View File

@@ -50,6 +50,10 @@ struct tegra_vip_soc {
const struct tegra_vip_ops *ops;
};
#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
extern const struct tegra_vip_soc tegra20_vip_soc;
#endif
/**
* struct tegra_vip - NVIDIA Tegra VIP device structure
*