Re: [PATCH 02/10] phy: Add configuration interface
From: Kishon Vijay Abraham I
Date: Mon Sep 24 2018 - 04:49:34 EST
Hi Maxime,
On Wednesday 19 September 2018 05:44 PM, Maxime Ripard wrote:
> Hi,
>
> On Fri, Sep 14, 2018 at 02:18:37PM +0530, Kishon Vijay Abraham I wrote:
>>>>>>> +/**
>>>>>>> + * phy_validate() - Checks the phy parameters
>>>>>>> + * @phy: the phy returned by phy_get()
>>>>>>> + * @mode: phy_mode the configuration is applicable to.
>>>>>>> + * @opts: Configuration to check
>>>>>>> + *
>>>>>>> + * Used to check that the current set of parameters can be handled by
>>>>>>> + * the phy. Implementations are free to tune the parameters passed as
>>>>>>> + * arguments if needed by some implementation detail or
>>>>>>> + * constraints. It will not change any actual configuration of the
>>>>>>> + * PHY, so calling it as many times as deemed fit will have no side
>>>>>>> + * effect.
>>>>>>> + *
>>>>>>> + * Returns: 0 if successful, an negative error code otherwise
>>>>>>> + */
>>>>>>> +int phy_validate(struct phy *phy, enum phy_mode mode,
>>>>>>> + union phy_configure_opts *opts)
>>>>>>
>>>>>> IIUC the consumer driver will pass configuration options (or PHY parameters)
>>>>>> which will be validated by the PHY driver and in some cases the PHY driver can
>>>>>> modify the configuration options? And these modified configuration options will
>>>>>> again be given to phy_configure?
>>>>>>
>>>>>> Looks like it's a round about way of doing the same thing.
>>>>>
>>>>> Not really. The validate callback allows to check whether a particular
>>>>> configuration would work, and try to negotiate a set of configurations
>>>>> that both the consumer and the PHY could work with.
>>>>
>>>> Maybe the PHY should provide the list of supported features to the consumer
>>>> driver and the consumer should select a supported feature?
>>>
>>> It's not really about the features it supports, but the boundaries it
>>> might have on those features. For example, the same phy integrated in
>>> two different SoCs will probably have some limit on the clock rate it
>>> can output because of the phy design itself, but also because of the
>>> clock that is fed into that phy, and that will be different from one
>>> SoC to the other.
>>>
>>> This integration will prevent us to use some clock rates on the first
>>> SoC, while the second one would be totally fine with it.
>>
>> If there's a clock that is fed to the PHY from the consumer, then the consumer
>> driver should model a clock provider and the PHY can get a reference to it
>> using clk_get(). Rockchip and Arasan eMMC PHYs has already used something like
>> that.
>
> That would be doable, but no current driver has had this in their
> binding. So that would prevent any further rework, and make that whole
> series moot. And while I could live without the Allwinner part, the
> Cadence one is really needed.
We could add a binding and modify the driver to to register a clock provider.
That could be included in this series itself.
>
>> Assuming the PHY can get a reference to the clock provided by the consumer,
>> what are the parameters we'll be able to get rid of in struct
>> phy_configure_opts_mipi_dphy?
>
> hs_clock_rate and lp_clock_rate. All the other ones are needed.
For a start we could use that and get rid of hs_clock_rate and lp_clock_rate in
phy_configure_opts_mipi_dphy.
We could also use phy_set_bus_width() for lanes.
>
>> I'm sorry but I'm not convinced a consumer driver should have all the details
>> that are added in phy_configure_opts_mipi_dphy.
>
> If it can convince you, here is the parameters that are needed by all
> the MIPI-DSI drivers currently in Linux to configure their PHY:
>
> - cdns-dsi (drivers/gpu/drm/bridge/cdns-dsi.c)
> - hs_clk_rate
> - lanes
> - videomode
>
> - kirin (drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c)
> - hs_exit
> - hs_prepare
> - hs_trail
> - hs_zero
> - lpx
> - ta_get
> - ta_go
> - wakeup
>
> - msm (drivers/gpu/drm/msm/dsi/*)
> - clk_post
> - clk_pre
> - clk_prepare
> - clk_trail
> - clk_zero
> - hs_clk_rate
> - hs_exit
> - hs_prepare
> - hs_trail
> - hs_zero
> - lp_clk_rate
> - ta_get
> - ta_go
> - ta_sure
>
> - mtk (drivers/gpu/drm/mediatek/mtk_dsi.c)
> - hs_clk_rate
> - hs_exit
> - hs_prepare
> - hs_trail
> - hs_zero
> - lpx
>
> - sun4i (drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c)
> - clk_post
> - clk_pre
> - clk_prepare
> - clk_zero
> - hs_prepare
> - hs_trail
> - lanes
> - lp_clk_rate
>
> - tegra (drivers/gpu/drm/tegra/dsi.c)
> - clk_post
> - clk_pre
> - clk_prepare
> - clk_trail
> - clk_zero
> - hs_exit
> - hs_prepare
> - hs_trail
> - hs_zero
> - lpx
> - ta_get
> - ta_go
> - ta_sure
>
> - vc4 (drivers/gpu/drm/vc4/vc4_dsi.c)
> - hs_clk_rate
> - lanes
>
> Now, for MIPI-CSI receivers:
>
> - marvell-ccic (drivers/media/platform/marvell-ccic/mcam-core.c)
> - clk_term_en
> - clk_settle
> - d_term_en
> - hs_settle
> - lp_clk_rate
>
> - omap4iss (drivers/staging/media/omap4iss/iss_csiphy.c)
> - clk_miss
> - clk_settle
> - clk_term
> - hs_settle
> - hs_term
> - lanes
>
> - rcar-vin (drivers/media/platform/rcar-vin/rcar-csi2.c)
> - hs_clk_rate
> - lanes
>
> - ti-vpe (drivers/media/platform/ti-vpe/cal.c)
> - clk_term_en
> - d_term_en
> - hs_settle
> - hs_term
Thank you for providing the exhaustive list.
>
> So the timings expressed in the structure are the set of all the ones
> currently used in the tree by DSI and CSI drivers. I would consider
> that a good proof that it would be useful.
The problem I see here is each platform (PHY) will have it's own set of
parameters and we have to keep adding members to phy_configure_opts which is
not scalable. We should try to find a correlation between generic PHY modes and
these parameters (at-least for a subset).
Thanks
Kishon