Re: [PATCH v9 6/7] media: qcom: camss: Add support for PHY API devices

From: Dmitry Baryshkov

Date: Thu Feb 26 2026 - 19:06:12 EST


On Thu, Feb 26, 2026 at 02:28:47PM +0000, Bryan O'Donoghue wrote:
> Add the ability to use a PHY pointer which interacts with the standard PHY
> API.
>
> In the first instance the code will try to use the new PHY interface. If no
> PHYs are present in the DT then the legacy method will be attempted.
>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@xxxxxxxxxx>
> ---
> drivers/media/platform/qcom/camss/Kconfig | 1 +
> drivers/media/platform/qcom/camss/camss-csiphy.c | 185 +++++++++++++++++++++--
> drivers/media/platform/qcom/camss/camss-csiphy.h | 7 +
> drivers/media/platform/qcom/camss/camss.c | 72 +++++++--
> 4 files changed, 235 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/Kconfig b/drivers/media/platform/qcom/camss/Kconfig
> index 4eda48cb1adf0..1edc5e5a1829e 100644
> --- a/drivers/media/platform/qcom/camss/Kconfig
> +++ b/drivers/media/platform/qcom/camss/Kconfig
> @@ -7,3 +7,4 @@ config VIDEO_QCOM_CAMSS
> select VIDEO_V4L2_SUBDEV_API
> select VIDEOBUF2_DMA_SG
> select V4L2_FWNODE
> + select PHY_QCOM_MIPI_CSI2
> diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
> index 62623393f4144..b8bfbf2fef8fa 100644
> --- a/drivers/media/platform/qcom/camss/camss-csiphy.c
> +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
> @@ -7,12 +7,14 @@
> * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
> * Copyright (C) 2016-2018 Linaro Ltd.
> */
> +#include <dt-bindings/phy/phy.h>
> #include <linux/clk.h>
> #include <linux/delay.h>
> #include <linux/interrupt.h>
> #include <linux/io.h>
> #include <linux/kernel.h>
> #include <linux/of.h>
> +#include <linux/phy/phy.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> #include <media/media-entity.h>
> @@ -131,10 +133,10 @@ static u8 csiphy_get_bpp(const struct csiphy_format_info *formats,
> }
>
> /*
> - * csiphy_set_clock_rates - Calculate and set clock rates on CSIPHY module
> + * csiphy_set_clock_rates_legacy - Calculate and set clock rates on CSIPHY module
> * @csiphy: CSIPHY device
> */
> -static int csiphy_set_clock_rates(struct csiphy_device *csiphy)
> +static int csiphy_set_clock_rates_legacy(struct csiphy_device *csiphy)
> {
> struct device *dev = csiphy->camss->dev;
> s64 link_freq;
> @@ -200,7 +202,7 @@ static int csiphy_set_clock_rates(struct csiphy_device *csiphy)
> *
> * Return 0 on success or a negative error code otherwise
> */
> -static int csiphy_set_power(struct v4l2_subdev *sd, int on)
> +static int csiphy_set_power_legacy(struct v4l2_subdev *sd, int on)
> {
> struct csiphy_device *csiphy = v4l2_get_subdevdata(sd);
> struct device *dev = csiphy->camss->dev;
> @@ -219,7 +221,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on)
> return ret;
> }
>
> - ret = csiphy_set_clock_rates(csiphy);
> + ret = csiphy_set_clock_rates_legacy(csiphy);
> if (ret < 0) {
> regulator_bulk_disable(csiphy->num_supplies,
> csiphy->supplies);
> @@ -254,7 +256,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on)
> }
>
> /*
> - * csiphy_stream_on - Enable streaming on CSIPHY module
> + * csiphy_stream_on_legacy - Enable streaming on CSIPHY module
> * @csiphy: CSIPHY device
> *
> * Helper function to enable streaming on CSIPHY module.
> @@ -262,7 +264,7 @@ static int csiphy_set_power(struct v4l2_subdev *sd, int on)
> *
> * Return 0 on success or a negative error code otherwise
> */
> -static int csiphy_stream_on(struct csiphy_device *csiphy)
> +static int csiphy_stream_on_legacy(struct csiphy_device *csiphy)
> {
> struct csiphy_config *cfg = &csiphy->cfg;
> s64 link_freq;
> @@ -306,11 +308,86 @@ static int csiphy_stream_on(struct csiphy_device *csiphy)
> *
> * Helper function to disable streaming on CSIPHY module
> */
> -static void csiphy_stream_off(struct csiphy_device *csiphy)
> +static void csiphy_stream_off_legacy(struct csiphy_device *csiphy)
> {
> csiphy->res->hw_ops->lanes_disable(csiphy, &csiphy->cfg);
> }
>
> +/*
> + * csiphy_stream_on - Enable streaming on CSIPHY module
> + * @csiphy: CSIPHY device
> + *
> + * Helper function to enable streaming on CSIPHY module.
> + * Main configuration of CSIPHY module is also done here.
> + *
> + * Return 0 on success or a negative error code otherwise
> + */
> +static int csiphy_stream_on(struct csiphy_device *csiphy)
> +{
> + u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats,
> + csiphy->fmt[MSM_CSIPHY_PAD_SINK].code);
> + u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data;
> + struct phy_configure_opts_mipi_dphy *dphy_cfg;
> + union phy_configure_opts dphy_opts = { 0 };
> + struct device *dev = csiphy->camss->dev;
> + s64 link_freq;
> + int ret;
> +
> + dphy_cfg = &dphy_opts.mipi_dphy;
> +
> + link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes);
> +
> + if (link_freq < 0) {
> + dev_err(dev,
> + "Cannot get CSI2 transmitter's link frequency\n");
> + return -EINVAL;
> + }
> +
> + phy_mipi_dphy_get_default_config_for_hsclk(link_freq, num_lanes, dphy_cfg);
> +
> + phy_set_mode(csiphy->phy, PHY_MODE_MIPI_DPHY);
> + ret = phy_configure(csiphy->phy, &dphy_opts);
> + if (ret) {
> + dev_err(dev, "failed to configure MIPI D-PHY\n");
> + goto error;
> + }
> +
> + return phy_power_on(csiphy->phy);
> +
> +error:
> + return ret;
> +}
> +
> +/*
> + * csiphy_stream_off - Disable streaming on CSIPHY module
> + * @csiphy: CSIPHY device
> + *
> + * Helper function to disable streaming on CSIPHY module
> + */
> +static void csiphy_stream_off(struct csiphy_device *csiphy)
> +{
> + phy_power_off(csiphy->phy);
> +}
> +
> +/*
> + * csiphy_set_stream - Enable/disable streaming on CSIPHY module
> + * @sd: CSIPHY V4L2 subdevice
> + * @enable: Requested streaming state
> + *
> + * Return 0 on success or a negative error code otherwise
> + */
> +static int csiphy_set_stream_legacy(struct v4l2_subdev *sd, int enable)
> +{
> + struct csiphy_device *csiphy = v4l2_get_subdevdata(sd);
> + int ret = 0;
> +
> + if (enable)
> + ret = csiphy_stream_on_legacy(csiphy);
> + else
> + csiphy_stream_off_legacy(csiphy);
> +
> + return ret;
> +}
>
> /*
> * csiphy_set_stream - Enable/disable streaming on CSIPHY module
> @@ -568,16 +645,16 @@ static bool csiphy_match_clock_name(const char *clock_name, const char *format,
> }
>
> /*
> - * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resources
> + * msm_csiphy_subdev_init_legacy - Initialize CSIPHY device structure and resources
> * @csiphy: CSIPHY device
> * @res: CSIPHY module resources table
> * @id: CSIPHY module id
> *
> * Return 0 on success or a negative error code otherwise
> */
> -int msm_csiphy_subdev_init(struct camss *camss,
> - struct csiphy_device *csiphy,
> - const struct camss_subdev_resources *res, u8 id)
> +int msm_csiphy_subdev_init_legacy(struct camss *camss,
> + struct csiphy_device *csiphy,
> + const struct camss_subdev_resources *res, u8 id)
> {
> struct device *dev = camss->dev;
> struct platform_device *pdev = to_platform_device(dev);
> @@ -705,6 +782,69 @@ int msm_csiphy_subdev_init(struct camss *camss,
> return ret;
> }
>
> +/*
> + * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resources
> + * @csiphy: CSIPHY device
> + * @res: CSIPHY module resources table
> + * @id: CSIPHY module id
> + *
> + * Return 0 on success or a negative error code otherwise
> + */
> +int msm_csiphy_subdev_init(struct camss *camss,
> + struct csiphy_device *csiphy,
> + const struct camss_subdev_resources *res, u8 id)
> +{
> + struct device *dev = camss->dev;
> + struct of_phandle_args args;
> + u8 combo_mode;
> + int idx;
> + int ret;
> +
> + snprintf(csiphy->name, ARRAY_SIZE(csiphy->name), "csiphy%d", id);
> +
> + idx = of_property_match_string(dev->of_node, "phy-names", csiphy->name);
> + if (idx < 0) {
> + dev_err(dev, "%s not found\n", csiphy->name);

It can't be an error. You are breaking the possiblity for existing
platforms to gradually migrate from the legacy DT bindings to the new
CSI PHY bindings (or to the new CSI PHY driver, if you prefer it this
way).

Not to mention that you've just broken compatibility with the camss
schema that was defined for the last 4(?) Linux releases for X1E8.

> + return idx;
> + }
> +

--
With best wishes
Dmitry