mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
To: Hitesh Patel <hitesh@ebytelogic.com>, linux-media@vger.kernel.org
Cc: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>,
	Loic Poulain <loic.poulain@oss.qualcomm.com>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
	ravi@ebytelogic.com
Subject: Re: [PATCH 1/8] media: qcom: camss: take the link frequency from the CSI-2 transmitter
Date: Mon, 14 Sep 2026 15:58:13 +0100	[thread overview]
Message-ID: <bd3fa7ab-9c60-4697-a0bc-92877e8a2885@linaro.org> (raw)
In-Reply-To: <20260914133416.1030231-2-hitesh@ebytelogic.com>

On 14/09/2026 14:34, Hitesh Patel wrote:
> camss_get_link_freq() walks the pipeline to an entity whose function
> is MEDIA_ENT_F_CAM_SENSOR and reads the link frequency from there, to
> derive the CSIPHY settle count and the CSID clock.
> 
> The rate the receiver has to be programmed for is the rate on the
> CSI-2 bus, which is a property of whatever drives that bus, not of
> the sensor at the far end of the pipeline. The two coincide only when
> the sensor is wired directly to the CSIPHY. With a CSI-2 to CSI-2
> bridge in between, a GMSL or FPD-Link deserializer for instance, the
> bridge re-times the stream onto its own output: it may aggregate
> several sensors onto one link, forward a single sensor at a different
> rate, or generate a test pattern with no sensor involved at all. The
> sensor's rate is then simply not what arrives at the SoC, and the
> PHY does not lock.
> 
> Walking to a MEDIA_ENT_F_CAM_SENSOR also fails outright on a
> deserializer that has one sink pad per serial link: the walk follows
> pad 0, while the sensor may be attached to any of the other sink
> pads, and streaming is refused with "Cannot get CSI2 transmitter's
> link frequency".
> 
> Stop the walk at the first entity that is not a CAMSS receiver, i.e.
> at the external subdev feeding the CSIPHY, and query that pad with
> v4l2_get_link_freq(). This is what the helper is for: it asks the
> transmitter through .get_mbus_config first and falls back to its
> V4L2_CID_LINK_FREQ, then V4L2_CID_PIXEL_RATE controls.
> 
> For a sensor connected straight to a CSIPHY the transmitter is the
> sensor itself, so the pad found and the value returned are the same
> as before.
> 
> camss_find_sensor_pad() keeps walking to the sensor: its other users,
> camss_get_pixel_clock() and the frame skip query, do want the sensor.
> 
> Signed-off-by: Hitesh Patel <hitesh@ebytelogic.com>
> ---
>   .../media/platform/qcom/camss/camss-csid.c    |  2 +-
>   .../media/platform/qcom/camss/camss-csiphy.c  |  6 +-
>   drivers/media/platform/qcom/camss/camss.c     | 74 +++++++++++++++++--
>   drivers/media/platform/qcom/camss/camss.h     |  4 +-
>   4 files changed, 73 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
> index 48459b46a..c631119e2 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -546,7 +546,7 @@ static int csid_set_clock_rates(struct csid_device *csid)
>   
>   	fmt = csid_get_fmt_entry(csid->res->formats->formats, csid->res->formats->nformats,
>   				 csid->fmt[MSM_CSIPHY_PAD_SINK].code);
> -	link_freq = camss_get_link_freq(&csid->subdev.entity, fmt->bpp,
> +	link_freq = camss_get_link_freq(csid->camss, &csid->subdev.entity, fmt->bpp,
>   					csid->phy.lane_cnt);
>   	if (link_freq < 0)
>   		link_freq = 0;
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
> index 539ac4888..000fde129 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> @@ -145,7 +145,8 @@ static int csiphy_set_clock_rates(struct csiphy_device *csiphy)
>   				csiphy->fmt[MSM_CSIPHY_PAD_SINK].code);
>   	u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data;
>   
> -	link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes);
> +	link_freq = camss_get_link_freq(csiphy->camss, &csiphy->subdev.entity,
> +					bpp, num_lanes);
>   	if (link_freq < 0)
>   		link_freq  = 0;
>   
> @@ -272,7 +273,8 @@ static int csiphy_stream_on(struct csiphy_device *csiphy)
>   	u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data;
>   	u8 val;
>   
> -	link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes);
> +	link_freq = camss_get_link_freq(csiphy->camss, &csiphy->subdev.entity,

Its redundant to pass csiphy->camss and &csiphy->subdev.entity

Just pass struct camss_csiphy *csiphy once and then extract the pointers 
you need in the routine.

In fact if you line that particular change up as a first patch in this 
series, the overall structure will be neater.

> +					bpp, num_lanes);
>   
>   	if (link_freq < 0) {
>   		dev_err(csiphy->camss->dev,
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 2123f6388..16ad1c26c 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -4619,24 +4619,82 @@ struct media_pad *camss_find_sensor_pad(struct media_entity *entity)
>   	}
>   }
>   
> +/*
> + * camss_is_receiver_subdev - Test whether a subdev is a CAMSS CSI-2 receiver
> + * @camss: CAMSS device
> + * @sd: Subdevice to test
> + *
> + * Return true for a CSIPHY or CSID belonging to @camss, false for anything
> + * else, in particular for the external subdev transmitting to them.
> + */
> +static bool camss_is_receiver_subdev(struct camss *camss,
> +				     struct v4l2_subdev *sd)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < camss->res->csiphy_num; i++)
> +		if (sd == &camss->csiphy[i].subdev)
> +			return true;
> +
> +	for (i = 0; i < camss->res->csid_num; i++)
> +		if (sd == &camss->csid[i].subdev)
> +			return true;
> +
> +	return false;
> +}

This seems fine. I wonder how it works with the TPG, probably fine, 
needs testing.

> +/*
> + * camss_find_transmitter_pad - Find the pad of the CSI-2 transmitter
> + * @camss: CAMSS device
> + * @entity: Media entity in the current pipeline
> + *
> + * Walk the pipeline upstream through the CAMSS receiver subdevs and return the
> + * source pad of the first entity that is not one of them: the CSI-2
> + * transmitter driving the SoC.
> + *
> + * Return a pointer to the transmitter media pad or NULL if not found
> + */
> +static struct media_pad *camss_find_transmitter_pad(struct camss *camss,
> +						    struct media_entity *entity)
> +{
> +	struct media_pad *pad;
> +
> +	while (1) {
> +		pad = &entity->pads[0];
> +		if (!(pad->flags & MEDIA_PAD_FL_SINK))
> +			return NULL;
> +
> +		pad = media_pad_remote_pad_first(pad);
> +		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
> +			return NULL;
> +
> +		entity = pad->entity;
> +
> +		if (!camss_is_receiver_subdev(camss,
> +					      media_entity_to_v4l2_subdev(entity)))

Please fix up that clause a bit so its not spralling multi-line get the 
media_entity one line previous and pass.

> +			return pad;
> +	}
> +}
> +
>   /**
> - * camss_get_link_freq - Get link frequency from sensor
> + * camss_get_link_freq - Get link frequency from the CSI-2 transmitter
> + * @camss: CAMSS device
>    * @entity: Media entity in the current pipeline
>    * @bpp: Number of bits per pixel for the current format
> - * @lanes: Number of lanes in the link to the sensor
> + * @lanes: Number of lanes in the link to the transmitter
>    *
>    * Return link frequency on success or a negative error code otherwise
>    */
> -s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp,
> -			unsigned int lanes)
> +s64 camss_get_link_freq(struct camss *camss, struct media_entity *entity,
> +			unsigned int bpp, unsigned int lanes)
>   {
> -	struct media_pad *sensor_pad;
> +	struct media_pad *tx_pad;
>   
> -	sensor_pad = camss_find_sensor_pad(entity);
> -	if (!sensor_pad)
> +	tx_pad = camss_find_transmitter_pad(camss, entity);
> +	if (!tx_pad)
>   		return -ENODEV;
>   
> -	return v4l2_get_link_freq(sensor_pad, bpp, 2 * lanes);
> +	return v4l2_get_link_freq(tx_pad, bpp, 2 * lanes);
>   }
>   
>   /*
> diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
> index 93d691c8a..39ea33e61 100644
> --- a/drivers/media/platform/qcom/camss/camss.h
> +++ b/drivers/media/platform/qcom/camss/camss.h
> @@ -168,8 +168,8 @@ int camss_enable_clocks(int nclocks, struct camss_clock *clock,
>   			struct device *dev);
>   void camss_disable_clocks(int nclocks, struct camss_clock *clock);
>   struct media_pad *camss_find_sensor_pad(struct media_entity *entity);
> -s64 camss_get_link_freq(struct media_entity *entity, unsigned int bpp,
> -			unsigned int lanes);
> +s64 camss_get_link_freq(struct camss *camss, struct media_entity *entity,
> +			unsigned int bpp, unsigned int lanes);
>   int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock);
>   int camss_pm_domain_on(struct camss *camss, int id);
>   void camss_pm_domain_off(struct camss *camss, int id);


  reply	other threads:[~2026-09-14 14:58 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-14 13:34 [PATCH 0/8] media: qcom: camss: support several cameras behind a CSI-2 bridge Hitesh Patel
2026-09-14 13:34 ` [PATCH 1/8] media: qcom: camss: take the link frequency from the CSI-2 transmitter Hitesh Patel
2026-09-14 14:58   ` Bryan O'Donoghue [this message]
2026-09-15  9:08     ` Hitesh Patel
2026-09-15  9:12       ` Bryan O'Donoghue
2026-09-14 13:34 ` [PATCH 2/8] media: qcom: camss: create the source to CSIPHY link per endpoint Hitesh Patel
2026-09-14 15:07   ` Bryan O'Donoghue
2026-09-15  9:08     ` Hitesh Patel
2026-09-14 13:34 ` [PATCH 3/8] media: qcom: camss: vfe-17x: do not gate write master done on IRQ_STATUS_0 Hitesh Patel
2026-09-14 15:18   ` Bryan O'Donoghue
2026-09-15  9:08     ` Hitesh Patel
2026-09-14 13:34 ` [PATCH 4/8] media: qcom: camss: vfe-17x: use the write master matching the RDI line Hitesh Patel
2026-09-14 15:21   ` Bryan O'Donoghue
2026-09-15  9:08     ` Hitesh Patel
2026-09-14 13:34 ` [PATCH 5/8] media: qcom: camss: vfe: only reset the VFE when its last line stops Hitesh Patel
2026-09-14 15:28   ` Bryan O'Donoghue
2026-09-15  9:08     ` Hitesh Patel
2026-09-14 13:34 ` [PATCH 6/8] media: qcom: camss: refcount streaming on the shared CSIPHY and CSID Hitesh Patel
2026-09-14 19:13   ` Bryan O'Donoghue
2026-09-15  9:08     ` Hitesh Patel
2026-09-14 13:34 ` [PATCH 7/8] media: qcom: camss: drive streams-aware transmitters through the streams API Hitesh Patel
2026-09-14 15:57   ` Loic Poulain
2026-09-14 19:16     ` Bryan O'Donoghue
2026-09-15  9:08     ` Hitesh Patel
2026-09-14 13:34 ` [PATCH 8/8] media: qcom: camss: enable only the stream of the pipeline's virtual channel Hitesh Patel
2026-09-14 19:17   ` Bryan O'Donoghue
2026-09-15 12:15 ` [PATCH v2 0/5] media: qcom: camss: fixes for several cameras behind a CSI-2 bridge Hitesh Patel
2026-09-15 12:15   ` [PATCH v2 1/5] media: qcom: camss: vfe-17x: Fix write master buffer done being dropped Hitesh Patel
2026-09-15 12:15   ` [PATCH v2 2/5] media: qcom: camss: vfe-17x: Fix write master selection for RDI lines Hitesh Patel
2026-09-15 12:15   ` [PATCH v2 3/5] media: qcom: camss: vfe: Fix VFE reset while another line is streaming Hitesh Patel
2026-09-15 12:15   ` [PATCH v2 4/5] media: qcom: camss: Take the link frequency from the CSI-2 transmitter Hitesh Patel
2026-09-15 12:15   ` [PATCH v2 5/5] media: qcom: camss: Create the source to CSIPHY link per endpoint Hitesh Patel
2026-09-25 11:45   ` [PATCH v2 0/5] media: qcom: camss: fixes for several cameras behind a CSI-2 bridge Hitesh Patel
2026-09-26  9:48     ` Bryan O'Donoghue

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bd3fa7ab-9c60-4697-a0bc-92877e8a2885@linaro.org \
    --to=bryan.odonoghue@linaro.org \
    --cc=hitesh@ebytelogic.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=loic.poulain@oss.qualcomm.com \
    --cc=mchehab@kernel.org \
    --cc=ravi@ebytelogic.com \
    --cc=vladimir.zapolskiy@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®