From f639494db450770fa30d6845d9c84b9cb009758f Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 19 Feb 2025 15:06:11 +0200 Subject: [PATCH 01/16] media: ccs-pll: Correct the upper limit of maximum op_pre_pll_clk_div The PLL calculator does a search of the PLL configuration space for all valid OP pre-PLL clock dividers. The maximum did not take into account the CCS PLL flag CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER in which case also odd PLL dividers (other than 1) are valid. Do that now. Fixes: 4e1e8d240dff ("media: ccs-pll: Add support for extended input PLL clock divider") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index 266fcd160da6..d985686b0a36 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -799,7 +799,7 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim, op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div); max_op_pre_pll_clk_div = min_t(u16, op_lim_fr->max_pre_pll_clk_div, - clk_div_even(pll->ext_clk_freq_hz / + DIV_ROUND_UP(pll->ext_clk_freq_hz, op_lim_fr->min_pll_ip_clk_freq_hz)); min_op_pre_pll_clk_div = max_t(u16, op_lim_fr->min_pre_pll_clk_div, -- 2.51.0 From 34af05f857cb8317ce3c19f00f68af4c14329dbe Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 20 Feb 2025 11:53:20 +0200 Subject: [PATCH 02/16] media: ccs-pll: Print a debug message on too high VT PLL OP clock In general the CCS PLL calculator prints debugging information on the process to ease debugging. This case was not annotated, do that now. Remove an extra multiplication while at it. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs-pll.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index d985686b0a36..66d046d576f7 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -318,12 +318,13 @@ __ccs_pll_calculate_vt_tree(struct device *dev, return -EINVAL; } - if (pll_fr->pll_multiplier * pll_fr->pll_ip_clk_freq_hz > - lim_fr->max_pll_op_clk_freq_hz) - return -EINVAL; - pll_fr->pll_op_clk_freq_hz = pll_fr->pll_ip_clk_freq_hz * pll_fr->pll_multiplier; + if (pll_fr->pll_op_clk_freq_hz > lim_fr->max_pll_op_clk_freq_hz) { + dev_dbg(dev, "too high OP clock %u\n", + pll_fr->pll_op_clk_freq_hz); + return -EINVAL; + } vt_div = div * more_mul; -- 2.51.0 From 2ab7b3d07d2549686a8088f3de6e477b6ceb0483 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Apr 2025 13:54:00 +0300 Subject: [PATCH 03/16] media: ccs-pll: Drop LINK_DECOUPLED flag The LINK_DECOUPLED flag isn't used by the PLL calculator other than printing it. The number of OP/VT lanes are already printed in any case. Thus drop the flag as it has no function. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs-pll.c | 3 +-- drivers/media/i2c/ccs-pll.h | 1 - drivers/media/i2c/ccs/ccs-core.c | 1 - drivers/media/i2c/ccs/ccs-quirk.c | 3 +-- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index 66d046d576f7..16eb09462c8b 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -124,9 +124,8 @@ static void print_pll(struct device *dev, const struct ccs_pll *pll) dev_dbg(dev, "pixel rate on CSI-2 bus:\t%u\n", pll->pixel_rate_csi); - dev_dbg(dev, "flags%s%s%s%s%s%s%s%s%s\n", + dev_dbg(dev, "flags%s%s%s%s%s%s%s%s\n", pll->flags & PLL_FL(LANE_SPEED_MODEL) ? " lane-speed" : "", - pll->flags & PLL_FL(LINK_DECOUPLED) ? " link-decoupled" : "", pll->flags & PLL_FL(EXT_IP_PLL_DIVIDER) ? " ext-ip-pll-divider" : "", pll->flags & PLL_FL(FLEXIBLE_OP_PIX_CLK_DIV) ? diff --git a/drivers/media/i2c/ccs-pll.h b/drivers/media/i2c/ccs-pll.h index 6eb1b1c68e1e..ee206e5b287b 100644 --- a/drivers/media/i2c/ccs-pll.h +++ b/drivers/media/i2c/ccs-pll.h @@ -24,7 +24,6 @@ #define CCS_PLL_FLAG_NO_OP_CLOCKS BIT(1) /* CCS PLL flags */ #define CCS_PLL_FLAG_LANE_SPEED_MODEL BIT(2) -#define CCS_PLL_FLAG_LINK_DECOUPLED BIT(3) #define CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER BIT(4) #define CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV BIT(5) #define CCS_PLL_FLAG_FIFO_DERATING BIT(6) diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 004d28c33287..06e0ba53f2a8 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -3451,7 +3451,6 @@ static int ccs_probe(struct i2c_client *client) CCS_LIM(sensor, NUM_OF_VT_LANES) + 1; sensor->pll.op_lanes = CCS_LIM(sensor, NUM_OF_OP_LANES) + 1; - sensor->pll.flags |= CCS_PLL_FLAG_LINK_DECOUPLED; } else { sensor->pll.vt_lanes = sensor->pll.csi2.lanes; sensor->pll.op_lanes = sensor->pll.csi2.lanes; diff --git a/drivers/media/i2c/ccs/ccs-quirk.c b/drivers/media/i2c/ccs/ccs-quirk.c index e3d4c7a275bc..e48a4fa1f5dd 100644 --- a/drivers/media/i2c/ccs/ccs-quirk.c +++ b/drivers/media/i2c/ccs/ccs-quirk.c @@ -190,8 +190,7 @@ static int jt8ev1_post_streamoff(struct ccs_sensor *sensor) static int jt8ev1_init(struct ccs_sensor *sensor) { - sensor->pll.flags |= CCS_PLL_FLAG_LANE_SPEED_MODEL | - CCS_PLL_FLAG_LINK_DECOUPLED; + sensor->pll.flags |= CCS_PLL_FLAG_LANE_SPEED_MODEL; sensor->pll.vt_lanes = 1; sensor->pll.op_lanes = sensor->pll.csi2.lanes; -- 2.51.0 From 715f84c1e54efd123da761bb3db204e76e051041 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Apr 2025 14:18:45 +0300 Subject: [PATCH 04/16] media: ccs-pll: Print missing PLL flags Printing the OP_PIX_CLOCK_PER_LANE and NO_OP_CLOCKS CCS PLL flags is missing, add them now. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs-pll.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index 16eb09462c8b..ebbc5e323244 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -124,7 +124,9 @@ static void print_pll(struct device *dev, const struct ccs_pll *pll) dev_dbg(dev, "pixel rate on CSI-2 bus:\t%u\n", pll->pixel_rate_csi); - dev_dbg(dev, "flags%s%s%s%s%s%s%s%s\n", + dev_dbg(dev, "flags%s%s%s%s%s%s%s%s%s%s\n", + pll->flags & PLL_FL(OP_PIX_CLOCK_PER_LANE) ? " op-pix-clock-per-lane" : "", + pll->flags & PLL_FL(NO_OP_CLOCKS) ? " no-op-clocks" : "", pll->flags & PLL_FL(LANE_SPEED_MODEL) ? " lane-speed" : "", pll->flags & PLL_FL(EXT_IP_PLL_DIVIDER) ? " ext-ip-pll-divider" : "", -- 2.51.0 From 2f19528845b80f8299fbe28b23c162ba9389ebad Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 14 Feb 2025 12:36:18 +0200 Subject: [PATCH 05/16] media: ccs-pll: Add a flag for even PLL multipliers Some devices (not entirely CCS compliant) only support even PLL multipliers. Add support for this through a PLL flag. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs-pll.c | 11 ++++++++++- drivers/media/i2c/ccs-pll.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index ebbc5e323244..f4be4e9f6777 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -124,9 +124,10 @@ static void print_pll(struct device *dev, const struct ccs_pll *pll) dev_dbg(dev, "pixel rate on CSI-2 bus:\t%u\n", pll->pixel_rate_csi); - dev_dbg(dev, "flags%s%s%s%s%s%s%s%s%s%s\n", + dev_dbg(dev, "flags%s%s%s%s%s%s%s%s%s%s%s\n", pll->flags & PLL_FL(OP_PIX_CLOCK_PER_LANE) ? " op-pix-clock-per-lane" : "", pll->flags & PLL_FL(NO_OP_CLOCKS) ? " no-op-clocks" : "", + pll->flags & PLL_FL(EVEN_PLL_MULTIPLIER) ? " even-pll-multiplier" : "", pll->flags & PLL_FL(LANE_SPEED_MODEL) ? " lane-speed" : "", pll->flags & PLL_FL(EXT_IP_PLL_DIVIDER) ? " ext-ip-pll-divider" : "", @@ -312,6 +313,10 @@ __ccs_pll_calculate_vt_tree(struct device *dev, more_mul *= DIV_ROUND_UP(lim_fr->min_pll_multiplier, mul * more_mul); dev_dbg(dev, "more_mul2: %u\n", more_mul); + if (pll->flags & CCS_PLL_FLAG_EVEN_PLL_MULTIPLIER && + (mul & 1) && (more_mul & 1)) + more_mul <<= 1; + pll_fr->pll_multiplier = mul * more_mul; if (pll_fr->pll_multiplier > lim_fr->max_pll_multiplier) { dev_dbg(dev, "pll multiplier %u too high\n", @@ -668,6 +673,10 @@ ccs_pll_calculate_op(struct device *dev, const struct ccs_pll_limits *lim, if (!is_one_or_even(i)) i <<= 1; + if (pll->flags & CCS_PLL_FLAG_EVEN_PLL_MULTIPLIER && + mul & 1 && i & 1) + i <<= 1; + dev_dbg(dev, "final more_mul: %u\n", i); if (i > more_mul_max) { dev_dbg(dev, "final more_mul is bad, max %u\n", more_mul_max); diff --git a/drivers/media/i2c/ccs-pll.h b/drivers/media/i2c/ccs-pll.h index ee206e5b287b..754eb5f52cc4 100644 --- a/drivers/media/i2c/ccs-pll.h +++ b/drivers/media/i2c/ccs-pll.h @@ -22,6 +22,7 @@ /* op pix clock is for all lanes in total normally */ #define CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE BIT(0) #define CCS_PLL_FLAG_NO_OP_CLOCKS BIT(1) +#define CCS_PLL_FLAG_EVEN_PLL_MULTIPLIER BIT(3) /* CCS PLL flags */ #define CCS_PLL_FLAG_LANE_SPEED_MODEL BIT(2) #define CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER BIT(4) -- 2.51.0 From cd9cb0313a42ae029cd5af9293b0add984ed252e Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 26 Feb 2025 14:27:58 +0200 Subject: [PATCH 06/16] media: ccs-pll: Better validate VT PLL branch Check that the VT PLL dividers are actually found, don't trust they always are even though they should be. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs-pll.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index f4be4e9f6777..8de8158a413b 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -449,7 +449,7 @@ static int ccs_pll_calculate_vt_tree(struct device *dev, return -EINVAL; } -static void +static int ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim, const struct ccs_pll_branch_limits_bk *op_lim_bk, struct ccs_pll *pll, struct ccs_pll_branch_fr *pll_fr, @@ -572,6 +572,8 @@ ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim, if (best_pix_div < SHRT_MAX >> 1) break; } + if (best_pix_div == SHRT_MAX >> 1) + return -EINVAL; pll->vt_bk.sys_clk_div = DIV_ROUND_UP(vt_div, best_pix_div); pll->vt_bk.pix_clk_div = best_pix_div; @@ -584,6 +586,8 @@ ccs_pll_calculate_vt(struct device *dev, const struct ccs_pll_limits *lim, out_calc_pixel_rate: pll->pixel_rate_pixel_array = pll->vt_bk.pix_clk_freq_hz * pll->vt_lanes; + + return 0; } /* @@ -863,8 +867,10 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim, if (pll->flags & CCS_PLL_FLAG_DUAL_PLL) break; - ccs_pll_calculate_vt(dev, lim, op_lim_bk, pll, op_pll_fr, - op_pll_bk, cphy, phy_const); + rval = ccs_pll_calculate_vt(dev, lim, op_lim_bk, pll, op_pll_fr, + op_pll_bk, cphy, phy_const); + if (rval) + continue; rval = check_bk_bounds(dev, lim, pll, PLL_VT); if (rval) -- 2.51.0 From de6514694b54bdaf1a6e6cde6575871330013cb2 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 5 Mar 2025 13:30:41 +0200 Subject: [PATCH 07/16] media: ccs-pll: Print PLL calculator flags in the beginning Print the PLL calculator flags right away when the PLL calculator is called. Previously this was done only in a successful case and that didn't really help solving a problem when one happened. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs-pll.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index 8de8158a413b..87798616b76d 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -123,8 +123,11 @@ static void print_pll(struct device *dev, const struct ccs_pll *pll) pll->pixel_rate_pixel_array); dev_dbg(dev, "pixel rate on CSI-2 bus:\t%u\n", pll->pixel_rate_csi); +} - dev_dbg(dev, "flags%s%s%s%s%s%s%s%s%s%s%s\n", +static void print_pll_flags(struct device *dev, struct ccs_pll *pll) +{ + dev_dbg(dev, "PLL flags%s%s%s%s%s%s%s%s%s%s%s\n", pll->flags & PLL_FL(OP_PIX_CLOCK_PER_LANE) ? " op-pix-clock-per-lane" : "", pll->flags & PLL_FL(NO_OP_CLOCKS) ? " no-op-clocks" : "", pll->flags & PLL_FL(EVEN_PLL_MULTIPLIER) ? " even-pll-multiplier" : "", @@ -738,6 +741,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim, u32 i; int rval = -EINVAL; + print_pll_flags(dev, pll); + if (!(pll->flags & CCS_PLL_FLAG_LANE_SPEED_MODEL)) { pll->op_lanes = 1; pll->vt_lanes = 1; -- 2.51.0 From 220ea1432a6d317272d94184bf5f98b317f514b9 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Apr 2025 14:08:56 +0300 Subject: [PATCH 08/16] media: ccs-pll: Document the CCS PLL flags Document the CCS PLL flags with short comments. The CCS spec has more information on them while the added documentation helps finding the relevant information in the CCS spec. Signed-off-by: Sakari Ailus Reviewed-by: Laurent Pinchart Signed-off-by: Hans Verkuil --- drivers/media/i2c/ccs-pll.c | 2 +- drivers/media/i2c/ccs-pll.h | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c index 87798616b76d..8f9a695bd9e5 100644 --- a/drivers/media/i2c/ccs-pll.c +++ b/drivers/media/i2c/ccs-pll.c @@ -129,8 +129,8 @@ static void print_pll_flags(struct device *dev, struct ccs_pll *pll) { dev_dbg(dev, "PLL flags%s%s%s%s%s%s%s%s%s%s%s\n", pll->flags & PLL_FL(OP_PIX_CLOCK_PER_LANE) ? " op-pix-clock-per-lane" : "", - pll->flags & PLL_FL(NO_OP_CLOCKS) ? " no-op-clocks" : "", pll->flags & PLL_FL(EVEN_PLL_MULTIPLIER) ? " even-pll-multiplier" : "", + pll->flags & PLL_FL(NO_OP_CLOCKS) ? " no-op-clocks" : "", pll->flags & PLL_FL(LANE_SPEED_MODEL) ? " lane-speed" : "", pll->flags & PLL_FL(EXT_IP_PLL_DIVIDER) ? " ext-ip-pll-divider" : "", diff --git a/drivers/media/i2c/ccs-pll.h b/drivers/media/i2c/ccs-pll.h index 754eb5f52cc4..e22903931e72 100644 --- a/drivers/media/i2c/ccs-pll.h +++ b/drivers/media/i2c/ccs-pll.h @@ -18,19 +18,40 @@ #define CCS_PLL_BUS_TYPE_CSI2_DPHY 0x00 #define CCS_PLL_BUS_TYPE_CSI2_CPHY 0x01 -/* Old SMIA and implementation specific flags */ -/* op pix clock is for all lanes in total normally */ +/* Old SMIA and implementation specific flags. */ +/* OP PIX clock is for all lanes in total normally. */ #define CCS_PLL_FLAG_OP_PIX_CLOCK_PER_LANE BIT(0) -#define CCS_PLL_FLAG_NO_OP_CLOCKS BIT(1) +/* If set, the PLL multipliers are required to be even. */ #define CCS_PLL_FLAG_EVEN_PLL_MULTIPLIER BIT(3) + /* CCS PLL flags */ + +/* The sensor doesn't have OP clocks at all. */ +#define CCS_PLL_FLAG_NO_OP_CLOCKS BIT(1) +/* System speed model if this flag is unset. */ #define CCS_PLL_FLAG_LANE_SPEED_MODEL BIT(2) +/* If set, the pre-PLL divider may have odd values, too. */ #define CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER BIT(4) +/* + * If set, the OP PIX clock doesn't have to exactly match with data rate, it may + * be higher. See "OP Domain Formulas" in MIPI CCS 1.1 spec. + */ #define CCS_PLL_FLAG_FLEXIBLE_OP_PIX_CLK_DIV BIT(5) +/* If set, the VT domain may run faster than the OP domain. */ #define CCS_PLL_FLAG_FIFO_DERATING BIT(6) +/* If set, the VT domain may run slower than the OP domain. */ #define CCS_PLL_FLAG_FIFO_OVERRATING BIT(7) +/* If set, the PLL tree has two PLLs instead of one. */ #define CCS_PLL_FLAG_DUAL_PLL BIT(8) +/* + * If set, the OP SYS clock is a dual data rate clock, transferring two bits per + * cycle instead of one. + */ #define CCS_PLL_FLAG_OP_SYS_DDR BIT(9) +/* + * If set, the OP PIX clock is a dual data rate clock, transferring two pixels + * per cycle instead of one. + */ #define CCS_PLL_FLAG_OP_PIX_DDR BIT(10) /** -- 2.51.0 From c3d8e388ac9dd56fd99dbe71874aa67097840a57 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 13 Mar 2025 11:17:42 +0100 Subject: [PATCH 09/16] media: intel/ipu6: Remove unused IPU6_BUS_NAME Remove unused define. Reviewed-by: Hans de Goede Signed-off-by: Stanislaw Gruszka Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/pci/intel/ipu6/ipu6-bus.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-bus.h b/drivers/media/pci/intel/ipu6/ipu6-bus.h index bb4926dfdf08..ebf470806a74 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-bus.h +++ b/drivers/media/pci/intel/ipu6/ipu6-bus.h @@ -15,8 +15,6 @@ struct firmware; struct pci_dev; -#define IPU6_BUS_NAME IPU6_NAME "-bus" - struct ipu6_buttress_ctrl; struct ipu6_bus_device { -- 2.51.0 From be1534a2e71452afbab7c69cf59f783bb33f644a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 13 Mar 2025 11:17:43 +0100 Subject: [PATCH 10/16] media: intel/ipu6: Remove ipu6_buttress_ctrl started field We assign to ->started field but newer read back, the field can be removed. Reviewed-by: Hans de Goede Signed-off-by: Stanislaw Gruszka Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/pci/intel/ipu6/ipu6-buttress.c | 2 -- drivers/media/pci/intel/ipu6/ipu6-buttress.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c index d8db5aa5d528..787fcbd1df09 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c +++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c @@ -478,8 +478,6 @@ int ipu6_buttress_power(struct device *dev, struct ipu6_buttress_ctrl *ctrl, dev_err(&isp->pdev->dev, "Change power status timeout with 0x%x\n", val); - ctrl->started = !ret && on; - mutex_unlock(&isp->buttress.power_mutex); return ret; diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.h b/drivers/media/pci/intel/ipu6/ipu6-buttress.h index 482978c2a09d..4b9763acdfdd 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-buttress.h +++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.h @@ -26,7 +26,6 @@ struct ipu6_buttress_ctrl { u32 freq_ctl, pwr_sts_shift, pwr_sts_mask, pwr_sts_on, pwr_sts_off; unsigned int ratio; unsigned int qos_floor; - bool started; }; struct ipu6_buttress_ipc { -- 2.51.0 From 6ad57f8f86de024d10c764f829a50530e7121958 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 13 Mar 2025 11:17:44 +0100 Subject: [PATCH 11/16] media: intel/ipu6: Constify ipu6_buttress_ctrl structure Make ipu6_buttress_ctrl constant since it is not modified any longer. Reviewed-by: Hans de Goede Signed-off-by: Stanislaw Gruszka Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/pci/intel/ipu6/ipu6-bus.c | 2 +- drivers/media/pci/intel/ipu6/ipu6-bus.h | 4 ++-- drivers/media/pci/intel/ipu6/ipu6-buttress.c | 4 ++-- drivers/media/pci/intel/ipu6/ipu6-buttress.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-bus.c b/drivers/media/pci/intel/ipu6/ipu6-bus.c index 37d88ddb6ee7..5cee2748983b 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-bus.c +++ b/drivers/media/pci/intel/ipu6/ipu6-bus.c @@ -82,7 +82,7 @@ static void ipu6_bus_release(struct device *dev) struct ipu6_bus_device * ipu6_bus_initialize_device(struct pci_dev *pdev, struct device *parent, - void *pdata, struct ipu6_buttress_ctrl *ctrl, + void *pdata, const struct ipu6_buttress_ctrl *ctrl, char *name) { struct auxiliary_device *auxdev; diff --git a/drivers/media/pci/intel/ipu6/ipu6-bus.h b/drivers/media/pci/intel/ipu6/ipu6-bus.h index ebf470806a74..b790f9cc37e3 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-bus.h +++ b/drivers/media/pci/intel/ipu6/ipu6-bus.h @@ -25,7 +25,7 @@ struct ipu6_bus_device { void *pdata; struct ipu6_mmu *mmu; struct ipu6_device *isp; - struct ipu6_buttress_ctrl *ctrl; + const struct ipu6_buttress_ctrl *ctrl; u64 dma_mask; const struct firmware *fw; struct sg_table fw_sgt; @@ -48,7 +48,7 @@ struct ipu6_auxdrv_data { struct ipu6_bus_device * ipu6_bus_initialize_device(struct pci_dev *pdev, struct device *parent, - void *pdata, struct ipu6_buttress_ctrl *ctrl, + void *pdata, const struct ipu6_buttress_ctrl *ctrl, char *name); int ipu6_bus_add_device(struct ipu6_bus_device *adev); void ipu6_bus_del_devices(struct pci_dev *pdev); diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c index 787fcbd1df09..103386c4f6ae 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c +++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c @@ -443,8 +443,8 @@ irqreturn_t ipu6_buttress_isr_threaded(int irq, void *isp_ptr) return ret; } -int ipu6_buttress_power(struct device *dev, struct ipu6_buttress_ctrl *ctrl, - bool on) +int ipu6_buttress_power(struct device *dev, + const struct ipu6_buttress_ctrl *ctrl, bool on) { struct ipu6_device *isp = to_ipu6_bus_device(dev)->isp; u32 pwr_sts, val; diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.h b/drivers/media/pci/intel/ipu6/ipu6-buttress.h index 4b9763acdfdd..51e5ad48db82 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-buttress.h +++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.h @@ -65,8 +65,8 @@ int ipu6_buttress_map_fw_image(struct ipu6_bus_device *sys, struct sg_table *sgt); void ipu6_buttress_unmap_fw_image(struct ipu6_bus_device *sys, struct sg_table *sgt); -int ipu6_buttress_power(struct device *dev, struct ipu6_buttress_ctrl *ctrl, - bool on); +int ipu6_buttress_power(struct device *dev, + const struct ipu6_buttress_ctrl *ctrl, bool on); bool ipu6_buttress_get_secure_mode(struct ipu6_device *isp); int ipu6_buttress_authenticate(struct ipu6_device *isp); int ipu6_buttress_reset_authentication(struct ipu6_device *isp); -- 2.51.0 From 94a6c188b89b8099e3abe78ebb6916a534690e21 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 17 Mar 2025 15:28:42 +0100 Subject: [PATCH 12/16] media: intel/ipu6: Remove unused ipu6_isys_subdev_link_validate() Remove unused declaration. Signed-off-by: Stanislaw Gruszka Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h index 9ef8d95464f5..268dfa01e903 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h @@ -37,10 +37,6 @@ int ipu6_isys_subdev_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_mbus_code_enum *code); -int ipu6_isys_subdev_link_validate(struct v4l2_subdev *sd, - struct media_link *link, - struct v4l2_subdev_format *source_fmt, - struct v4l2_subdev_format *sink_fmt); u32 ipu6_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad); int ipu6_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream, struct v4l2_mbus_framefmt *format); -- 2.51.0 From adcdf4160a6cca8a8dcda853e07590c32566d6fd Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 19 Mar 2025 13:10:40 +0100 Subject: [PATCH 13/16] media: intel/ipu6: Add missing new line character in error message End error message with new line. Signed-off-by: Stanislaw Gruszka Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/pci/intel/ipu6/ipu6-isys-queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c index 72f5f987ef48..9a19695abbaf 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c @@ -797,7 +797,7 @@ void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, return; } - dev_err(dev, "Failed to find a matching video buffer"); + dev_err(dev, "Failed to find a matching video buffer\n"); spin_unlock_irqrestore(&aq->lock, flags); } -- 2.51.0 From 4fa1d8d81d7224a82c7ae07b9262a8751c4e85f2 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 19 Mar 2025 13:10:41 +0100 Subject: [PATCH 14/16] media: intel/ipu6: Make two functions static Make function used only in one file static and remove from header file. Signed-off-by: Stanislaw Gruszka Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- drivers/media/pci/intel/ipu6/ipu6-isys-queue.c | 7 ++++--- drivers/media/pci/intel/ipu6/ipu6-isys-queue.h | 4 ---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c index 9a19695abbaf..3984b9d43919 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c @@ -697,8 +697,9 @@ static u64 get_sof_ns_delta(struct ipu6_isys_video *av, return ipu6_buttress_tsc_ticks_to_ns(delta, isp); } -void ipu6_isys_buf_calc_sequence_time(struct ipu6_isys_buffer *ib, - struct ipu6_fw_isys_resp_info_abi *info) +static void +ipu6_isys_buf_calc_sequence_time(struct ipu6_isys_buffer *ib, + struct ipu6_fw_isys_resp_info_abi *info) { struct vb2_buffer *vb = ipu6_isys_buffer_to_vb2_buffer(ib); struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); @@ -721,7 +722,7 @@ void ipu6_isys_buf_calc_sequence_time(struct ipu6_isys_buffer *ib, vbuf->vb2_buf.timestamp); } -void ipu6_isys_queue_buf_done(struct ipu6_isys_buffer *ib) +static void ipu6_isys_queue_buf_done(struct ipu6_isys_buffer *ib) { struct vb2_buffer *vb = ipu6_isys_buffer_to_vb2_buffer(ib); diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.h b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.h index fe8fc796a58f..1a277b0fb4b5 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.h +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.h @@ -69,10 +69,6 @@ void ipu6_isys_buf_to_fw_frame_buf(struct ipu6_fw_isys_frame_buff_set_abi *set, struct ipu6_isys_stream *stream, struct ipu6_isys_buffer_list *bl); -void -ipu6_isys_buf_calc_sequence_time(struct ipu6_isys_buffer *ib, - struct ipu6_fw_isys_resp_info_abi *info); -void ipu6_isys_queue_buf_done(struct ipu6_isys_buffer *ib); void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, struct ipu6_fw_isys_resp_info_abi *info); int ipu6_isys_queue_init(struct ipu6_isys_queue *aq); -- 2.51.0 From 36b9d0521e4b10c9fab9bef0796d6374125b7b57 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 19 Mar 2025 13:10:42 +0100 Subject: [PATCH 15/16] media: intel/ipu6: Use timestamp value directly Remove pointer for fw abi structure when setting frame sequence and time, use timestamp value from the structure directly. Signed-off-by: Stanislaw Gruszka Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- .../media/pci/intel/ipu6/ipu6-isys-queue.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c index 3984b9d43919..c68dc577daf0 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c @@ -652,10 +652,8 @@ static void stop_streaming(struct vb2_queue *q) } static unsigned int -get_sof_sequence_by_timestamp(struct ipu6_isys_stream *stream, - struct ipu6_fw_isys_resp_info_abi *info) +get_sof_sequence_by_timestamp(struct ipu6_isys_stream *stream, u64 time) { - u64 time = (u64)info->timestamp[1] << 32 | info->timestamp[0]; struct ipu6_isys *isys = stream->isys; struct device *dev = &isys->adev->auxdev.dev; unsigned int i; @@ -681,8 +679,7 @@ get_sof_sequence_by_timestamp(struct ipu6_isys_stream *stream, return 0; } -static u64 get_sof_ns_delta(struct ipu6_isys_video *av, - struct ipu6_fw_isys_resp_info_abi *info) +static u64 get_sof_ns_delta(struct ipu6_isys_video *av, u64 timestamp) { struct ipu6_bus_device *adev = av->isys->adev; struct ipu6_device *isp = adev->isp; @@ -692,14 +689,13 @@ static u64 get_sof_ns_delta(struct ipu6_isys_video *av, if (!tsc_now) return 0; - delta = tsc_now - ((u64)info->timestamp[1] << 32 | info->timestamp[0]); + delta = tsc_now - timestamp; return ipu6_buttress_tsc_ticks_to_ns(delta, isp); } static void -ipu6_isys_buf_calc_sequence_time(struct ipu6_isys_buffer *ib, - struct ipu6_fw_isys_resp_info_abi *info) +ipu6_isys_buf_calc_sequence_time(struct ipu6_isys_buffer *ib, u64 time) { struct vb2_buffer *vb = ipu6_isys_buffer_to_vb2_buffer(ib); struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); @@ -710,8 +706,8 @@ ipu6_isys_buf_calc_sequence_time(struct ipu6_isys_buffer *ib, u64 ns; u32 sequence; - ns = ktime_get_ns() - get_sof_ns_delta(av, info); - sequence = get_sof_sequence_by_timestamp(stream, info); + ns = ktime_get_ns() - get_sof_ns_delta(av, time); + sequence = get_sof_sequence_by_timestamp(stream, time); vbuf->vb2_buf.timestamp = ns; vbuf->sequence = sequence; @@ -749,6 +745,7 @@ void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, unsigned long flags; bool first = true; struct vb2_v4l2_buffer *buf; + u64 time = (u64)info->timestamp[1] << 32 | info->timestamp[0]; spin_lock_irqsave(&aq->lock, flags); if (list_empty(&aq->active)) { @@ -791,7 +788,7 @@ void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, list_del(&ib->head); spin_unlock_irqrestore(&aq->lock, flags); - ipu6_isys_buf_calc_sequence_time(ib, info); + ipu6_isys_buf_calc_sequence_time(ib, time); ipu6_isys_queue_buf_done(ib); -- 2.51.0 From 95d1033c8da0b3307a40bd3dd95ddf85ad171dbc Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Wed, 19 Mar 2025 13:10:43 +0100 Subject: [PATCH 16/16] media: intel/ipu6: Abstract buf ready function Extract values needed by ipu6_queue_buf_ready() function from fw abi structure. This will allow to reuse same buf ready code when fw abi change. Signed-off-by: Stanislaw Gruszka Signed-off-by: Sakari Ailus Signed-off-by: Hans Verkuil --- .../media/pci/intel/ipu6/ipu6-isys-queue.c | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c index c68dc577daf0..55d45d2d8768 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c @@ -734,10 +734,11 @@ static void ipu6_isys_queue_buf_done(struct ipu6_isys_buffer *ib) } } -void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, - struct ipu6_fw_isys_resp_info_abi *info) +static void +ipu6_stream_buf_ready(struct ipu6_isys_stream *stream, u8 pin_id, u32 pin_addr, + u64 time, bool error_check) { - struct ipu6_isys_queue *aq = stream->output_pins[info->pin_id].aq; + struct ipu6_isys_queue *aq = stream->output_pins[pin_id].aq; struct ipu6_isys *isys = stream->isys; struct device *dev = &isys->adev->auxdev.dev; struct ipu6_isys_buffer *ib; @@ -745,7 +746,6 @@ void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, unsigned long flags; bool first = true; struct vb2_v4l2_buffer *buf; - u64 time = (u64)info->timestamp[1] << 32 | info->timestamp[0]; spin_lock_irqsave(&aq->lock, flags); if (list_empty(&aq->active)) { @@ -764,7 +764,7 @@ void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, ivb = vb2_buffer_to_ipu6_isys_video_buffer(vvb); addr = ivb->dma_addr; - if (info->pin.addr != addr) { + if (pin_addr != addr) { if (first) dev_err(dev, "Unexpected buffer address %pad\n", &addr); @@ -772,8 +772,7 @@ void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, continue; } - if (info->error_info.error == - IPU6_FW_ISYS_ERROR_HW_REPORTED_STR2MMIO) { + if (error_check) { /* * Check for error message: * 'IPU6_FW_ISYS_ERROR_HW_REPORTED_STR2MMIO' @@ -800,6 +799,15 @@ void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, spin_unlock_irqrestore(&aq->lock, flags); } +void ipu6_isys_queue_buf_ready(struct ipu6_isys_stream *stream, + struct ipu6_fw_isys_resp_info_abi *info) +{ + u64 time = (u64)info->timestamp[1] << 32 | info->timestamp[0]; + bool err = info->error_info.error == IPU6_FW_ISYS_ERROR_HW_REPORTED_STR2MMIO; + + ipu6_stream_buf_ready(stream, info->pin_id, info->pin.addr, time, err); +} + static const struct vb2_ops ipu6_isys_queue_ops = { .queue_setup = ipu6_isys_queue_setup, .buf_init = ipu6_isys_buf_init, -- 2.51.0