All of lore.kernel.org
 help / color / mirror / Atom feed
From: Guillaume Ranquet <granquet@baylibre.com>
To: AngeloGioacchino Del Regno 
	<angelogioacchino.delregno@collabora.com>,
	airlied@linux.ie, chunfeng.yun@mediatek.com,
	chunkuang.hu@kernel.org, ck.hu@mediatek.com, daniel@ffwll.ch,
	deller@gmx.de, jitao.shi@mediatek.com, kishon@ti.com,
	maarten.lankhorst@linux.intel.com, matthias.bgg@gmail.com,
	mripard@kernel.org, p.zabel@pengutronix.de, robh+dt@kernel.org,
	tzimmermann@suse.de, vkoul@kernel.org
Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-phy@lists.infradead.org, linux-fbdev@vger.kernel.org,
	Markus Schneider-Pargmann <msp@baylibre.com>
Subject: Re: [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy
Date: Fri, 25 Feb 2022 03:49:51 -0800	[thread overview]
Message-ID: <CABnWg9tfutasgiUaLBvb8CxTycLKf8Ry=9PMi2Vtu2JeB4a=dQ@mail.gmail.com> (raw)
In-Reply-To: <bdd867fe-3103-a99b-e9ec-02df6a18d385@collabora.com>

Quoting AngeloGioacchino Del Regno (2022-02-21 15:31:51)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> >
> > This is a new driver that supports the integrated DisplayPort phy for
> > mediatek SoCs, especially the mt8195. The phy is integrated into the
> > DisplayPort controller and will be created by the mtk-dp driver. This
> > driver expects a struct regmap to be able to work on the same registers
> > as the DisplayPort controller. It sets the device data to be the struct
> > phy so that the DisplayPort controller can easily work with it.
> >
> > The driver does not have any devicetree bindings because the datasheet
> > does not list the controller and the phy as distinct units.
> >
> > The interaction with the controller can be covered by the configure
> > callback of the phy framework and its displayport parameters.
> >
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   MAINTAINERS                       |   1 +
> >   drivers/phy/mediatek/Kconfig      |   8 ++
> >   drivers/phy/mediatek/Makefile     |   1 +
> >   drivers/phy/mediatek/phy-mtk-dp.c | 199 ++++++++++++++++++++++++++++++
> >   4 files changed, 209 insertions(+)
> >   create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fca970a46e77a..33a05d396dd03 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6467,6 +6467,7 @@ L:      linux-mediatek@lists.infradead.org (moderated for non-subscribers)
> >   S:  Supported
> >   F:  Documentation/devicetree/bindings/display/mediatek/
> >   F:  drivers/gpu/drm/mediatek/
> > +F:   drivers/phy/mediatek/phy-mtk-dp.c
> >   F:  drivers/phy/mediatek/phy-mtk-hdmi*
> >   F:  drivers/phy/mediatek/phy-mtk-mipi*
> >
> > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > index 55f8e6c048ab3..f7ec860590492 100644
> > --- a/drivers/phy/mediatek/Kconfig
> > +++ b/drivers/phy/mediatek/Kconfig
> > @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
> >       select GENERIC_PHY
> >       help
> >         Support MIPI DSI for Mediatek SoCs.
> > +
> > +config PHY_MTK_DP
> > +     tristate "MediaTek DP-PHY Driver"
> > +     depends on ARCH_MEDIATEK || COMPILE_TEST
> > +     depends on OF
> > +     select GENERIC_PHY
> > +     help
> > +       Support DisplayPort PHY for Mediatek SoCs.
> > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > index ace660fbed3a1..4ba1e06504346 100644
> > --- a/drivers/phy/mediatek/Makefile
> > +++ b/drivers/phy/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >   # Makefile for the phy drivers.
> >   #
> >
> > +obj-$(CONFIG_PHY_MTK_DP)             += phy-mtk-dp.o
> >   obj-$(CONFIG_PHY_MTK_TPHY)          += phy-mtk-tphy.o
> >   obj-$(CONFIG_PHY_MTK_UFS)           += phy-mtk-ufs.o
> >   obj-$(CONFIG_PHY_MTK_XSPHY)         += phy-mtk-xsphy.o
> > diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c
> > new file mode 100644
> > index 0000000000000..2841dd3f22543
> > --- /dev/null
> > +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> > @@ -0,0 +1,199 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
>
> Would be nice to add:
>
>   * phy-mtk-dp.c - MediaTek DisplayPort PHY driver
>   *
>
> > + * Copyright (c) 2021 BayLibre
> > + * Author: Markus Schneider-Pargmann <msp@baylibre.com>
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +
> > +#define PHY_OFFSET 0x1000
> > +
> > +#define MTK_DP_PHY_DIG_PLL_CTL_1             (PHY_OFFSET + 0x014)
> > +#define TPLL_SSC_EN                                  BIT(3)
> > +
> > +#define MTK_DP_PHY_DIG_BIT_RATE              (PHY_OFFSET + 0x03C)
> > +#define BIT_RATE_RBR                         0
> > +#define BIT_RATE_HBR                         1
> > +#define BIT_RATE_HBR2                                2
> > +#define BIT_RATE_HBR3                                3
> > +
> > +#define MTK_DP_PHY_DIG_SW_RST                (PHY_OFFSET + 0x038)
> > +#define DP_GLB_SW_RST_PHYD                   BIT(0)
> > +
> > +#define MTK_DP_LANE0_DRIVING_PARAM_3         (PHY_OFFSET + 0x138)
> > +#define MTK_DP_LANE1_DRIVING_PARAM_3         (PHY_OFFSET + 0x238)
> > +#define MTK_DP_LANE2_DRIVING_PARAM_3         (PHY_OFFSET + 0x338)
> > +#define MTK_DP_LANE3_DRIVING_PARAM_3         (PHY_OFFSET + 0x438)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT    0x10
>
> BIT(4)
>
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT    (0x14 << 8)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT    (0x18 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT    (0x20 << 24)
>
> Please use the GENMASK() macro for these definitions.
>
I will convert all the definitions to BIT() and GENMASK() for v9

> > +#define DRIVING_PARAM_3_DEFAULT              (XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT    0x18
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT    (0x1e << 8)
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT    (0x24 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT    (0x20 << 24)
> > +#define DRIVING_PARAM_4_DEFAULT              (XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT    0x28
> > +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT    (0x30 << 8)
> > +#define DRIVING_PARAM_5_DEFAULT              (XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT   0x00
>
> This is just 0
>
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT   (0x04 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT   (0x08 << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT   (0x10 << 24)
> > +#define DRIVING_PARAM_6_DEFAULT              (XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT   0x00
>
> ...just 0 again
>
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT   (0x06 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT   (0x0c << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT   (0x00 << 24)
>
> zero shifted by a million bits is still zero, so this statement does not make sense
>
> > +#define DRIVING_PARAM_7_DEFAULT              (XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT   0x08
> > +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT   (0x00 << 8)
>
> Same here.
>
> > +#define DRIVING_PARAM_8_DEFAULT              (XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> > +
> > +struct mtk_dp_phy {
> > +     struct regmap *regs;
> > +};
> > +
> > +static int mtk_dp_phy_init(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 driving_params[] = {
> > +             DRIVING_PARAM_3_DEFAULT,
> > +             DRIVING_PARAM_4_DEFAULT,
> > +             DRIVING_PARAM_5_DEFAULT,
> > +             DRIVING_PARAM_6_DEFAULT,
> > +             DRIVING_PARAM_7_DEFAULT,
> > +             DRIVING_PARAM_8_DEFAULT
> > +     };
> > +
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 val;
> > +
> > +     if (opts->dp.set_rate) {
> > +             switch (opts->dp.link_rate) {
> > +             default:
> > +                     dev_err(&phy->dev,
> > +                             "Implementation error, unknown linkrate %x\n",
> > +                             opts->dp.link_rate);
> > +                     return -EINVAL;
> > +             case 1620:
> > +                     val = BIT_RATE_RBR;
> > +                     break;
> > +             case 2700:
> > +                     val = BIT_RATE_HBR;
> > +                     break;
> > +             case 5400:
> > +                     val = BIT_RATE_HBR2;
> > +                     break;
> > +             case 8100:
> > +                     val = BIT_RATE_HBR3;
> > +                     break;
> > +             }
> > +             regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> > +     }
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> > +                        TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_reset(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 0);
>
> Please, when you add delays/sleeps, add a comment explaining the reason for that.
>
> To you.. and to me as well.. the reason is very much known and honestly obvious,
> but let's be nice with people that don't know the MediaTek platforms :)
>
It's sadly not obvious to me, I've asked mediatek engineers mutlple
times for these
kind of information, but I'm rather short on information... :-/

> > +     usleep_range(50, 200);
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 1);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct phy_ops mtk_dp_phy_dev_ops = {
> > +     .init = mtk_dp_phy_init,
> > +     .configure = mtk_dp_phy_configure,
> > +     .reset = mtk_dp_phy_reset,
> > +     .owner = THIS_MODULE,
> > +};
> > +
> > +static int mtk_dp_phy_probe(struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct mtk_dp_phy *dp_phy;
> > +     struct phy *phy;
>
>         struct regmap *regs = (blah);
>
>         if (!dp_phy->regs)
>                 return -EINVAL;
>
> Doing that before allocating the dp_phy struct seems sensible as, even
> if it's unlikely that this platform data is not passed, we'd be sparing
> some time around.
>
> Besides - I think that the error message is not necessary here, but, if
> you really want to keep it, please return dev_err_probe(): using it in
> these cases is also allowed.
>
You are right, it's logical to return as early as possible.

> > +
> > +     dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> > +     if (!dp_phy)
> > +             return -ENOMEM;
> > +
> > +     dp_phy->regs = *(struct regmap **)dev->platform_data;
> > +     if (!dp_phy->regs) {
> > +             dev_err(dev, "No data passed, requires struct regmap**\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
>
>         if (IS_ERR(phy))
>                 return dev_err_probe(dev, PTR_ERR(phy), "Cannot create DP PHY\n");
>
> > +     if (IS_ERR(phy)) {
> > +             dev_err(dev, "Failed to create DP PHY: %ld\n", PTR_ERR(phy));
> > +             return PTR_ERR(phy);
> > +     }
> > +     phy_set_drvdata(phy, dp_phy);
> > +
> > +     if (!dev->of_node)
>
> This will never happen if you use DT to probe this driver - and please do!
>
> An example device-tree binding would be:
>
> dp_phy: phy@somewhere {
>         compatible = "mediatek,mt8195-dp-phy", "mediatek,dp-phy";
>         reg = <...>;
>         #phy-cells = <0>;
> };
>
> mtk_dp: displayport-controller@somewhere_else {
>         compatible = "mediatek,mt8195-edp-tx", "mediatek,edp-tx";
>         reg = <....>;
>         other-properties;
>
>         phys = <&dp_phy>;
>         phy-names = "dp";
> };
>
> Also, remember: since you're nicely using regmap, if you - for any reason - need
> to share the same iospace between the two drivers, you can always use a
> syscon node for that purpose.
>
Sadly, I'm not using DT to prove this driver... and this driver will
probably never
be used with DT.
This phy is actually an integral part of the dp ip, this driver is
only a "logical"
separation between the DP/phy functionnalities.
It's probed from the DP driver with a call to `platform_register_device()`.
Both the DP and phy driver share the same regmap struct.

Markus tried to explain that in the commit message, please tell me if this needs
a reword?
The original discussion is here:
https://lore.kernel.org/all/CAAOTY__cJMqcAieEraJ2sz4gi0Zs-aiNXz38_x7dPQea6HvYEg@mail.gmail.com/

I didn't know about syscon, I'll have a look... but it's definitively what
I'm doing here...

> > +             phy_create_lookup(phy, "dp", dev_name(dev));
> > +
> > +     return 0;
> > +}
> > +
> > +struct platform_driver mtk_dp_phy_driver = {
> > +     .probe = mtk_dp_phy_probe,
> > +     .driver = {
> > +             .name = "mediatek-dp-phy",
> > +     },
> > +};
> > +module_platform_driver(mtk_dp_phy_driver);
> > +
> > +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> > +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> > +MODULE_LICENSE("GPL v2");
>

WARNING: multiple messages have this Message-ID (diff)
From: Guillaume Ranquet <granquet@baylibre.com>
To: AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	airlied@linux.ie,  chunfeng.yun@mediatek.com,
	chunkuang.hu@kernel.org, ck.hu@mediatek.com,  daniel@ffwll.ch,
	deller@gmx.de, jitao.shi@mediatek.com, kishon@ti.com,
	 maarten.lankhorst@linux.intel.com, matthias.bgg@gmail.com,
	mripard@kernel.org,  p.zabel@pengutronix.de, robh+dt@kernel.org,
	tzimmermann@suse.de,  vkoul@kernel.org
Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org,  devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	 linux-arm-kernel@lists.infradead.org,
	linux-phy@lists.infradead.org,  linux-fbdev@vger.kernel.org,
	Markus Schneider-Pargmann <msp@baylibre.com>
Subject: Re: [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy
Date: Fri, 25 Feb 2022 03:49:51 -0800	[thread overview]
Message-ID: <CABnWg9tfutasgiUaLBvb8CxTycLKf8Ry=9PMi2Vtu2JeB4a=dQ@mail.gmail.com> (raw)
In-Reply-To: <bdd867fe-3103-a99b-e9ec-02df6a18d385@collabora.com>

Quoting AngeloGioacchino Del Regno (2022-02-21 15:31:51)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> >
> > This is a new driver that supports the integrated DisplayPort phy for
> > mediatek SoCs, especially the mt8195. The phy is integrated into the
> > DisplayPort controller and will be created by the mtk-dp driver. This
> > driver expects a struct regmap to be able to work on the same registers
> > as the DisplayPort controller. It sets the device data to be the struct
> > phy so that the DisplayPort controller can easily work with it.
> >
> > The driver does not have any devicetree bindings because the datasheet
> > does not list the controller and the phy as distinct units.
> >
> > The interaction with the controller can be covered by the configure
> > callback of the phy framework and its displayport parameters.
> >
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   MAINTAINERS                       |   1 +
> >   drivers/phy/mediatek/Kconfig      |   8 ++
> >   drivers/phy/mediatek/Makefile     |   1 +
> >   drivers/phy/mediatek/phy-mtk-dp.c | 199 ++++++++++++++++++++++++++++++
> >   4 files changed, 209 insertions(+)
> >   create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fca970a46e77a..33a05d396dd03 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6467,6 +6467,7 @@ L:      linux-mediatek@lists.infradead.org (moderated for non-subscribers)
> >   S:  Supported
> >   F:  Documentation/devicetree/bindings/display/mediatek/
> >   F:  drivers/gpu/drm/mediatek/
> > +F:   drivers/phy/mediatek/phy-mtk-dp.c
> >   F:  drivers/phy/mediatek/phy-mtk-hdmi*
> >   F:  drivers/phy/mediatek/phy-mtk-mipi*
> >
> > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > index 55f8e6c048ab3..f7ec860590492 100644
> > --- a/drivers/phy/mediatek/Kconfig
> > +++ b/drivers/phy/mediatek/Kconfig
> > @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
> >       select GENERIC_PHY
> >       help
> >         Support MIPI DSI for Mediatek SoCs.
> > +
> > +config PHY_MTK_DP
> > +     tristate "MediaTek DP-PHY Driver"
> > +     depends on ARCH_MEDIATEK || COMPILE_TEST
> > +     depends on OF
> > +     select GENERIC_PHY
> > +     help
> > +       Support DisplayPort PHY for Mediatek SoCs.
> > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > index ace660fbed3a1..4ba1e06504346 100644
> > --- a/drivers/phy/mediatek/Makefile
> > +++ b/drivers/phy/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >   # Makefile for the phy drivers.
> >   #
> >
> > +obj-$(CONFIG_PHY_MTK_DP)             += phy-mtk-dp.o
> >   obj-$(CONFIG_PHY_MTK_TPHY)          += phy-mtk-tphy.o
> >   obj-$(CONFIG_PHY_MTK_UFS)           += phy-mtk-ufs.o
> >   obj-$(CONFIG_PHY_MTK_XSPHY)         += phy-mtk-xsphy.o
> > diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c
> > new file mode 100644
> > index 0000000000000..2841dd3f22543
> > --- /dev/null
> > +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> > @@ -0,0 +1,199 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
>
> Would be nice to add:
>
>   * phy-mtk-dp.c - MediaTek DisplayPort PHY driver
>   *
>
> > + * Copyright (c) 2021 BayLibre
> > + * Author: Markus Schneider-Pargmann <msp@baylibre.com>
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +
> > +#define PHY_OFFSET 0x1000
> > +
> > +#define MTK_DP_PHY_DIG_PLL_CTL_1             (PHY_OFFSET + 0x014)
> > +#define TPLL_SSC_EN                                  BIT(3)
> > +
> > +#define MTK_DP_PHY_DIG_BIT_RATE              (PHY_OFFSET + 0x03C)
> > +#define BIT_RATE_RBR                         0
> > +#define BIT_RATE_HBR                         1
> > +#define BIT_RATE_HBR2                                2
> > +#define BIT_RATE_HBR3                                3
> > +
> > +#define MTK_DP_PHY_DIG_SW_RST                (PHY_OFFSET + 0x038)
> > +#define DP_GLB_SW_RST_PHYD                   BIT(0)
> > +
> > +#define MTK_DP_LANE0_DRIVING_PARAM_3         (PHY_OFFSET + 0x138)
> > +#define MTK_DP_LANE1_DRIVING_PARAM_3         (PHY_OFFSET + 0x238)
> > +#define MTK_DP_LANE2_DRIVING_PARAM_3         (PHY_OFFSET + 0x338)
> > +#define MTK_DP_LANE3_DRIVING_PARAM_3         (PHY_OFFSET + 0x438)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT    0x10
>
> BIT(4)
>
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT    (0x14 << 8)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT    (0x18 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT    (0x20 << 24)
>
> Please use the GENMASK() macro for these definitions.
>
I will convert all the definitions to BIT() and GENMASK() for v9

> > +#define DRIVING_PARAM_3_DEFAULT              (XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT    0x18
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT    (0x1e << 8)
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT    (0x24 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT    (0x20 << 24)
> > +#define DRIVING_PARAM_4_DEFAULT              (XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT    0x28
> > +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT    (0x30 << 8)
> > +#define DRIVING_PARAM_5_DEFAULT              (XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT   0x00
>
> This is just 0
>
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT   (0x04 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT   (0x08 << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT   (0x10 << 24)
> > +#define DRIVING_PARAM_6_DEFAULT              (XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT   0x00
>
> ...just 0 again
>
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT   (0x06 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT   (0x0c << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT   (0x00 << 24)
>
> zero shifted by a million bits is still zero, so this statement does not make sense
>
> > +#define DRIVING_PARAM_7_DEFAULT              (XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT   0x08
> > +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT   (0x00 << 8)
>
> Same here.
>
> > +#define DRIVING_PARAM_8_DEFAULT              (XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> > +
> > +struct mtk_dp_phy {
> > +     struct regmap *regs;
> > +};
> > +
> > +static int mtk_dp_phy_init(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 driving_params[] = {
> > +             DRIVING_PARAM_3_DEFAULT,
> > +             DRIVING_PARAM_4_DEFAULT,
> > +             DRIVING_PARAM_5_DEFAULT,
> > +             DRIVING_PARAM_6_DEFAULT,
> > +             DRIVING_PARAM_7_DEFAULT,
> > +             DRIVING_PARAM_8_DEFAULT
> > +     };
> > +
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 val;
> > +
> > +     if (opts->dp.set_rate) {
> > +             switch (opts->dp.link_rate) {
> > +             default:
> > +                     dev_err(&phy->dev,
> > +                             "Implementation error, unknown linkrate %x\n",
> > +                             opts->dp.link_rate);
> > +                     return -EINVAL;
> > +             case 1620:
> > +                     val = BIT_RATE_RBR;
> > +                     break;
> > +             case 2700:
> > +                     val = BIT_RATE_HBR;
> > +                     break;
> > +             case 5400:
> > +                     val = BIT_RATE_HBR2;
> > +                     break;
> > +             case 8100:
> > +                     val = BIT_RATE_HBR3;
> > +                     break;
> > +             }
> > +             regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> > +     }
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> > +                        TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_reset(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 0);
>
> Please, when you add delays/sleeps, add a comment explaining the reason for that.
>
> To you.. and to me as well.. the reason is very much known and honestly obvious,
> but let's be nice with people that don't know the MediaTek platforms :)
>
It's sadly not obvious to me, I've asked mediatek engineers mutlple
times for these
kind of information, but I'm rather short on information... :-/

> > +     usleep_range(50, 200);
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 1);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct phy_ops mtk_dp_phy_dev_ops = {
> > +     .init = mtk_dp_phy_init,
> > +     .configure = mtk_dp_phy_configure,
> > +     .reset = mtk_dp_phy_reset,
> > +     .owner = THIS_MODULE,
> > +};
> > +
> > +static int mtk_dp_phy_probe(struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct mtk_dp_phy *dp_phy;
> > +     struct phy *phy;
>
>         struct regmap *regs = (blah);
>
>         if (!dp_phy->regs)
>                 return -EINVAL;
>
> Doing that before allocating the dp_phy struct seems sensible as, even
> if it's unlikely that this platform data is not passed, we'd be sparing
> some time around.
>
> Besides - I think that the error message is not necessary here, but, if
> you really want to keep it, please return dev_err_probe(): using it in
> these cases is also allowed.
>
You are right, it's logical to return as early as possible.

> > +
> > +     dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> > +     if (!dp_phy)
> > +             return -ENOMEM;
> > +
> > +     dp_phy->regs = *(struct regmap **)dev->platform_data;
> > +     if (!dp_phy->regs) {
> > +             dev_err(dev, "No data passed, requires struct regmap**\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
>
>         if (IS_ERR(phy))
>                 return dev_err_probe(dev, PTR_ERR(phy), "Cannot create DP PHY\n");
>
> > +     if (IS_ERR(phy)) {
> > +             dev_err(dev, "Failed to create DP PHY: %ld\n", PTR_ERR(phy));
> > +             return PTR_ERR(phy);
> > +     }
> > +     phy_set_drvdata(phy, dp_phy);
> > +
> > +     if (!dev->of_node)
>
> This will never happen if you use DT to probe this driver - and please do!
>
> An example device-tree binding would be:
>
> dp_phy: phy@somewhere {
>         compatible = "mediatek,mt8195-dp-phy", "mediatek,dp-phy";
>         reg = <...>;
>         #phy-cells = <0>;
> };
>
> mtk_dp: displayport-controller@somewhere_else {
>         compatible = "mediatek,mt8195-edp-tx", "mediatek,edp-tx";
>         reg = <....>;
>         other-properties;
>
>         phys = <&dp_phy>;
>         phy-names = "dp";
> };
>
> Also, remember: since you're nicely using regmap, if you - for any reason - need
> to share the same iospace between the two drivers, you can always use a
> syscon node for that purpose.
>
Sadly, I'm not using DT to prove this driver... and this driver will
probably never
be used with DT.
This phy is actually an integral part of the dp ip, this driver is
only a "logical"
separation between the DP/phy functionnalities.
It's probed from the DP driver with a call to `platform_register_device()`.
Both the DP and phy driver share the same regmap struct.

Markus tried to explain that in the commit message, please tell me if this needs
a reword?
The original discussion is here:
https://lore.kernel.org/all/CAAOTY__cJMqcAieEraJ2sz4gi0Zs-aiNXz38_x7dPQea6HvYEg@mail.gmail.com/

I didn't know about syscon, I'll have a look... but it's definitively what
I'm doing here...

> > +             phy_create_lookup(phy, "dp", dev_name(dev));
> > +
> > +     return 0;
> > +}
> > +
> > +struct platform_driver mtk_dp_phy_driver = {
> > +     .probe = mtk_dp_phy_probe,
> > +     .driver = {
> > +             .name = "mediatek-dp-phy",
> > +     },
> > +};
> > +module_platform_driver(mtk_dp_phy_driver);
> > +
> > +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> > +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> > +MODULE_LICENSE("GPL v2");
>

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

WARNING: multiple messages have this Message-ID (diff)
From: Guillaume Ranquet <granquet@baylibre.com>
To: AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	airlied@linux.ie,  chunfeng.yun@mediatek.com,
	chunkuang.hu@kernel.org, ck.hu@mediatek.com,  daniel@ffwll.ch,
	deller@gmx.de, jitao.shi@mediatek.com, kishon@ti.com,
	 maarten.lankhorst@linux.intel.com, matthias.bgg@gmail.com,
	mripard@kernel.org,  p.zabel@pengutronix.de, robh+dt@kernel.org,
	tzimmermann@suse.de,  vkoul@kernel.org
Cc: devicetree@vger.kernel.org, linux-fbdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
	Markus Schneider-Pargmann <msp@baylibre.com>,
	linux-mediatek@lists.infradead.org,
	linux-phy@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy
Date: Fri, 25 Feb 2022 03:49:51 -0800	[thread overview]
Message-ID: <CABnWg9tfutasgiUaLBvb8CxTycLKf8Ry=9PMi2Vtu2JeB4a=dQ@mail.gmail.com> (raw)
In-Reply-To: <bdd867fe-3103-a99b-e9ec-02df6a18d385@collabora.com>

Quoting AngeloGioacchino Del Regno (2022-02-21 15:31:51)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> >
> > This is a new driver that supports the integrated DisplayPort phy for
> > mediatek SoCs, especially the mt8195. The phy is integrated into the
> > DisplayPort controller and will be created by the mtk-dp driver. This
> > driver expects a struct regmap to be able to work on the same registers
> > as the DisplayPort controller. It sets the device data to be the struct
> > phy so that the DisplayPort controller can easily work with it.
> >
> > The driver does not have any devicetree bindings because the datasheet
> > does not list the controller and the phy as distinct units.
> >
> > The interaction with the controller can be covered by the configure
> > callback of the phy framework and its displayport parameters.
> >
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   MAINTAINERS                       |   1 +
> >   drivers/phy/mediatek/Kconfig      |   8 ++
> >   drivers/phy/mediatek/Makefile     |   1 +
> >   drivers/phy/mediatek/phy-mtk-dp.c | 199 ++++++++++++++++++++++++++++++
> >   4 files changed, 209 insertions(+)
> >   create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fca970a46e77a..33a05d396dd03 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6467,6 +6467,7 @@ L:      linux-mediatek@lists.infradead.org (moderated for non-subscribers)
> >   S:  Supported
> >   F:  Documentation/devicetree/bindings/display/mediatek/
> >   F:  drivers/gpu/drm/mediatek/
> > +F:   drivers/phy/mediatek/phy-mtk-dp.c
> >   F:  drivers/phy/mediatek/phy-mtk-hdmi*
> >   F:  drivers/phy/mediatek/phy-mtk-mipi*
> >
> > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > index 55f8e6c048ab3..f7ec860590492 100644
> > --- a/drivers/phy/mediatek/Kconfig
> > +++ b/drivers/phy/mediatek/Kconfig
> > @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
> >       select GENERIC_PHY
> >       help
> >         Support MIPI DSI for Mediatek SoCs.
> > +
> > +config PHY_MTK_DP
> > +     tristate "MediaTek DP-PHY Driver"
> > +     depends on ARCH_MEDIATEK || COMPILE_TEST
> > +     depends on OF
> > +     select GENERIC_PHY
> > +     help
> > +       Support DisplayPort PHY for Mediatek SoCs.
> > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > index ace660fbed3a1..4ba1e06504346 100644
> > --- a/drivers/phy/mediatek/Makefile
> > +++ b/drivers/phy/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >   # Makefile for the phy drivers.
> >   #
> >
> > +obj-$(CONFIG_PHY_MTK_DP)             += phy-mtk-dp.o
> >   obj-$(CONFIG_PHY_MTK_TPHY)          += phy-mtk-tphy.o
> >   obj-$(CONFIG_PHY_MTK_UFS)           += phy-mtk-ufs.o
> >   obj-$(CONFIG_PHY_MTK_XSPHY)         += phy-mtk-xsphy.o
> > diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c
> > new file mode 100644
> > index 0000000000000..2841dd3f22543
> > --- /dev/null
> > +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> > @@ -0,0 +1,199 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
>
> Would be nice to add:
>
>   * phy-mtk-dp.c - MediaTek DisplayPort PHY driver
>   *
>
> > + * Copyright (c) 2021 BayLibre
> > + * Author: Markus Schneider-Pargmann <msp@baylibre.com>
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +
> > +#define PHY_OFFSET 0x1000
> > +
> > +#define MTK_DP_PHY_DIG_PLL_CTL_1             (PHY_OFFSET + 0x014)
> > +#define TPLL_SSC_EN                                  BIT(3)
> > +
> > +#define MTK_DP_PHY_DIG_BIT_RATE              (PHY_OFFSET + 0x03C)
> > +#define BIT_RATE_RBR                         0
> > +#define BIT_RATE_HBR                         1
> > +#define BIT_RATE_HBR2                                2
> > +#define BIT_RATE_HBR3                                3
> > +
> > +#define MTK_DP_PHY_DIG_SW_RST                (PHY_OFFSET + 0x038)
> > +#define DP_GLB_SW_RST_PHYD                   BIT(0)
> > +
> > +#define MTK_DP_LANE0_DRIVING_PARAM_3         (PHY_OFFSET + 0x138)
> > +#define MTK_DP_LANE1_DRIVING_PARAM_3         (PHY_OFFSET + 0x238)
> > +#define MTK_DP_LANE2_DRIVING_PARAM_3         (PHY_OFFSET + 0x338)
> > +#define MTK_DP_LANE3_DRIVING_PARAM_3         (PHY_OFFSET + 0x438)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT    0x10
>
> BIT(4)
>
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT    (0x14 << 8)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT    (0x18 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT    (0x20 << 24)
>
> Please use the GENMASK() macro for these definitions.
>
I will convert all the definitions to BIT() and GENMASK() for v9

> > +#define DRIVING_PARAM_3_DEFAULT              (XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT    0x18
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT    (0x1e << 8)
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT    (0x24 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT    (0x20 << 24)
> > +#define DRIVING_PARAM_4_DEFAULT              (XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT    0x28
> > +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT    (0x30 << 8)
> > +#define DRIVING_PARAM_5_DEFAULT              (XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT   0x00
>
> This is just 0
>
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT   (0x04 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT   (0x08 << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT   (0x10 << 24)
> > +#define DRIVING_PARAM_6_DEFAULT              (XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT   0x00
>
> ...just 0 again
>
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT   (0x06 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT   (0x0c << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT   (0x00 << 24)
>
> zero shifted by a million bits is still zero, so this statement does not make sense
>
> > +#define DRIVING_PARAM_7_DEFAULT              (XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT   0x08
> > +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT   (0x00 << 8)
>
> Same here.
>
> > +#define DRIVING_PARAM_8_DEFAULT              (XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> > +
> > +struct mtk_dp_phy {
> > +     struct regmap *regs;
> > +};
> > +
> > +static int mtk_dp_phy_init(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 driving_params[] = {
> > +             DRIVING_PARAM_3_DEFAULT,
> > +             DRIVING_PARAM_4_DEFAULT,
> > +             DRIVING_PARAM_5_DEFAULT,
> > +             DRIVING_PARAM_6_DEFAULT,
> > +             DRIVING_PARAM_7_DEFAULT,
> > +             DRIVING_PARAM_8_DEFAULT
> > +     };
> > +
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 val;
> > +
> > +     if (opts->dp.set_rate) {
> > +             switch (opts->dp.link_rate) {
> > +             default:
> > +                     dev_err(&phy->dev,
> > +                             "Implementation error, unknown linkrate %x\n",
> > +                             opts->dp.link_rate);
> > +                     return -EINVAL;
> > +             case 1620:
> > +                     val = BIT_RATE_RBR;
> > +                     break;
> > +             case 2700:
> > +                     val = BIT_RATE_HBR;
> > +                     break;
> > +             case 5400:
> > +                     val = BIT_RATE_HBR2;
> > +                     break;
> > +             case 8100:
> > +                     val = BIT_RATE_HBR3;
> > +                     break;
> > +             }
> > +             regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> > +     }
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> > +                        TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_reset(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 0);
>
> Please, when you add delays/sleeps, add a comment explaining the reason for that.
>
> To you.. and to me as well.. the reason is very much known and honestly obvious,
> but let's be nice with people that don't know the MediaTek platforms :)
>
It's sadly not obvious to me, I've asked mediatek engineers mutlple
times for these
kind of information, but I'm rather short on information... :-/

> > +     usleep_range(50, 200);
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 1);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct phy_ops mtk_dp_phy_dev_ops = {
> > +     .init = mtk_dp_phy_init,
> > +     .configure = mtk_dp_phy_configure,
> > +     .reset = mtk_dp_phy_reset,
> > +     .owner = THIS_MODULE,
> > +};
> > +
> > +static int mtk_dp_phy_probe(struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct mtk_dp_phy *dp_phy;
> > +     struct phy *phy;
>
>         struct regmap *regs = (blah);
>
>         if (!dp_phy->regs)
>                 return -EINVAL;
>
> Doing that before allocating the dp_phy struct seems sensible as, even
> if it's unlikely that this platform data is not passed, we'd be sparing
> some time around.
>
> Besides - I think that the error message is not necessary here, but, if
> you really want to keep it, please return dev_err_probe(): using it in
> these cases is also allowed.
>
You are right, it's logical to return as early as possible.

> > +
> > +     dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> > +     if (!dp_phy)
> > +             return -ENOMEM;
> > +
> > +     dp_phy->regs = *(struct regmap **)dev->platform_data;
> > +     if (!dp_phy->regs) {
> > +             dev_err(dev, "No data passed, requires struct regmap**\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
>
>         if (IS_ERR(phy))
>                 return dev_err_probe(dev, PTR_ERR(phy), "Cannot create DP PHY\n");
>
> > +     if (IS_ERR(phy)) {
> > +             dev_err(dev, "Failed to create DP PHY: %ld\n", PTR_ERR(phy));
> > +             return PTR_ERR(phy);
> > +     }
> > +     phy_set_drvdata(phy, dp_phy);
> > +
> > +     if (!dev->of_node)
>
> This will never happen if you use DT to probe this driver - and please do!
>
> An example device-tree binding would be:
>
> dp_phy: phy@somewhere {
>         compatible = "mediatek,mt8195-dp-phy", "mediatek,dp-phy";
>         reg = <...>;
>         #phy-cells = <0>;
> };
>
> mtk_dp: displayport-controller@somewhere_else {
>         compatible = "mediatek,mt8195-edp-tx", "mediatek,edp-tx";
>         reg = <....>;
>         other-properties;
>
>         phys = <&dp_phy>;
>         phy-names = "dp";
> };
>
> Also, remember: since you're nicely using regmap, if you - for any reason - need
> to share the same iospace between the two drivers, you can always use a
> syscon node for that purpose.
>
Sadly, I'm not using DT to prove this driver... and this driver will
probably never
be used with DT.
This phy is actually an integral part of the dp ip, this driver is
only a "logical"
separation between the DP/phy functionnalities.
It's probed from the DP driver with a call to `platform_register_device()`.
Both the DP and phy driver share the same regmap struct.

Markus tried to explain that in the commit message, please tell me if this needs
a reword?
The original discussion is here:
https://lore.kernel.org/all/CAAOTY__cJMqcAieEraJ2sz4gi0Zs-aiNXz38_x7dPQea6HvYEg@mail.gmail.com/

I didn't know about syscon, I'll have a look... but it's definitively what
I'm doing here...

> > +             phy_create_lookup(phy, "dp", dev_name(dev));
> > +
> > +     return 0;
> > +}
> > +
> > +struct platform_driver mtk_dp_phy_driver = {
> > +     .probe = mtk_dp_phy_probe,
> > +     .driver = {
> > +             .name = "mediatek-dp-phy",
> > +     },
> > +};
> > +module_platform_driver(mtk_dp_phy_driver);
> > +
> > +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> > +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> > +MODULE_LICENSE("GPL v2");
>

WARNING: multiple messages have this Message-ID (diff)
From: Guillaume Ranquet <granquet@baylibre.com>
To: AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	airlied@linux.ie,  chunfeng.yun@mediatek.com,
	chunkuang.hu@kernel.org, ck.hu@mediatek.com,  daniel@ffwll.ch,
	deller@gmx.de, jitao.shi@mediatek.com, kishon@ti.com,
	 maarten.lankhorst@linux.intel.com, matthias.bgg@gmail.com,
	mripard@kernel.org,  p.zabel@pengutronix.de, robh+dt@kernel.org,
	tzimmermann@suse.de,  vkoul@kernel.org
Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org,  devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	 linux-arm-kernel@lists.infradead.org,
	linux-phy@lists.infradead.org,  linux-fbdev@vger.kernel.org,
	Markus Schneider-Pargmann <msp@baylibre.com>
Subject: Re: [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy
Date: Fri, 25 Feb 2022 03:49:51 -0800	[thread overview]
Message-ID: <CABnWg9tfutasgiUaLBvb8CxTycLKf8Ry=9PMi2Vtu2JeB4a=dQ@mail.gmail.com> (raw)
In-Reply-To: <bdd867fe-3103-a99b-e9ec-02df6a18d385@collabora.com>

Quoting AngeloGioacchino Del Regno (2022-02-21 15:31:51)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> >
> > This is a new driver that supports the integrated DisplayPort phy for
> > mediatek SoCs, especially the mt8195. The phy is integrated into the
> > DisplayPort controller and will be created by the mtk-dp driver. This
> > driver expects a struct regmap to be able to work on the same registers
> > as the DisplayPort controller. It sets the device data to be the struct
> > phy so that the DisplayPort controller can easily work with it.
> >
> > The driver does not have any devicetree bindings because the datasheet
> > does not list the controller and the phy as distinct units.
> >
> > The interaction with the controller can be covered by the configure
> > callback of the phy framework and its displayport parameters.
> >
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   MAINTAINERS                       |   1 +
> >   drivers/phy/mediatek/Kconfig      |   8 ++
> >   drivers/phy/mediatek/Makefile     |   1 +
> >   drivers/phy/mediatek/phy-mtk-dp.c | 199 ++++++++++++++++++++++++++++++
> >   4 files changed, 209 insertions(+)
> >   create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fca970a46e77a..33a05d396dd03 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6467,6 +6467,7 @@ L:      linux-mediatek@lists.infradead.org (moderated for non-subscribers)
> >   S:  Supported
> >   F:  Documentation/devicetree/bindings/display/mediatek/
> >   F:  drivers/gpu/drm/mediatek/
> > +F:   drivers/phy/mediatek/phy-mtk-dp.c
> >   F:  drivers/phy/mediatek/phy-mtk-hdmi*
> >   F:  drivers/phy/mediatek/phy-mtk-mipi*
> >
> > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > index 55f8e6c048ab3..f7ec860590492 100644
> > --- a/drivers/phy/mediatek/Kconfig
> > +++ b/drivers/phy/mediatek/Kconfig
> > @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
> >       select GENERIC_PHY
> >       help
> >         Support MIPI DSI for Mediatek SoCs.
> > +
> > +config PHY_MTK_DP
> > +     tristate "MediaTek DP-PHY Driver"
> > +     depends on ARCH_MEDIATEK || COMPILE_TEST
> > +     depends on OF
> > +     select GENERIC_PHY
> > +     help
> > +       Support DisplayPort PHY for Mediatek SoCs.
> > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > index ace660fbed3a1..4ba1e06504346 100644
> > --- a/drivers/phy/mediatek/Makefile
> > +++ b/drivers/phy/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >   # Makefile for the phy drivers.
> >   #
> >
> > +obj-$(CONFIG_PHY_MTK_DP)             += phy-mtk-dp.o
> >   obj-$(CONFIG_PHY_MTK_TPHY)          += phy-mtk-tphy.o
> >   obj-$(CONFIG_PHY_MTK_UFS)           += phy-mtk-ufs.o
> >   obj-$(CONFIG_PHY_MTK_XSPHY)         += phy-mtk-xsphy.o
> > diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c
> > new file mode 100644
> > index 0000000000000..2841dd3f22543
> > --- /dev/null
> > +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> > @@ -0,0 +1,199 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
>
> Would be nice to add:
>
>   * phy-mtk-dp.c - MediaTek DisplayPort PHY driver
>   *
>
> > + * Copyright (c) 2021 BayLibre
> > + * Author: Markus Schneider-Pargmann <msp@baylibre.com>
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +
> > +#define PHY_OFFSET 0x1000
> > +
> > +#define MTK_DP_PHY_DIG_PLL_CTL_1             (PHY_OFFSET + 0x014)
> > +#define TPLL_SSC_EN                                  BIT(3)
> > +
> > +#define MTK_DP_PHY_DIG_BIT_RATE              (PHY_OFFSET + 0x03C)
> > +#define BIT_RATE_RBR                         0
> > +#define BIT_RATE_HBR                         1
> > +#define BIT_RATE_HBR2                                2
> > +#define BIT_RATE_HBR3                                3
> > +
> > +#define MTK_DP_PHY_DIG_SW_RST                (PHY_OFFSET + 0x038)
> > +#define DP_GLB_SW_RST_PHYD                   BIT(0)
> > +
> > +#define MTK_DP_LANE0_DRIVING_PARAM_3         (PHY_OFFSET + 0x138)
> > +#define MTK_DP_LANE1_DRIVING_PARAM_3         (PHY_OFFSET + 0x238)
> > +#define MTK_DP_LANE2_DRIVING_PARAM_3         (PHY_OFFSET + 0x338)
> > +#define MTK_DP_LANE3_DRIVING_PARAM_3         (PHY_OFFSET + 0x438)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT    0x10
>
> BIT(4)
>
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT    (0x14 << 8)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT    (0x18 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT    (0x20 << 24)
>
> Please use the GENMASK() macro for these definitions.
>
I will convert all the definitions to BIT() and GENMASK() for v9

> > +#define DRIVING_PARAM_3_DEFAULT              (XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT    0x18
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT    (0x1e << 8)
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT    (0x24 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT    (0x20 << 24)
> > +#define DRIVING_PARAM_4_DEFAULT              (XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT    0x28
> > +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT    (0x30 << 8)
> > +#define DRIVING_PARAM_5_DEFAULT              (XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT   0x00
>
> This is just 0
>
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT   (0x04 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT   (0x08 << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT   (0x10 << 24)
> > +#define DRIVING_PARAM_6_DEFAULT              (XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT   0x00
>
> ...just 0 again
>
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT   (0x06 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT   (0x0c << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT   (0x00 << 24)
>
> zero shifted by a million bits is still zero, so this statement does not make sense
>
> > +#define DRIVING_PARAM_7_DEFAULT              (XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT   0x08
> > +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT   (0x00 << 8)
>
> Same here.
>
> > +#define DRIVING_PARAM_8_DEFAULT              (XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> > +
> > +struct mtk_dp_phy {
> > +     struct regmap *regs;
> > +};
> > +
> > +static int mtk_dp_phy_init(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 driving_params[] = {
> > +             DRIVING_PARAM_3_DEFAULT,
> > +             DRIVING_PARAM_4_DEFAULT,
> > +             DRIVING_PARAM_5_DEFAULT,
> > +             DRIVING_PARAM_6_DEFAULT,
> > +             DRIVING_PARAM_7_DEFAULT,
> > +             DRIVING_PARAM_8_DEFAULT
> > +     };
> > +
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 val;
> > +
> > +     if (opts->dp.set_rate) {
> > +             switch (opts->dp.link_rate) {
> > +             default:
> > +                     dev_err(&phy->dev,
> > +                             "Implementation error, unknown linkrate %x\n",
> > +                             opts->dp.link_rate);
> > +                     return -EINVAL;
> > +             case 1620:
> > +                     val = BIT_RATE_RBR;
> > +                     break;
> > +             case 2700:
> > +                     val = BIT_RATE_HBR;
> > +                     break;
> > +             case 5400:
> > +                     val = BIT_RATE_HBR2;
> > +                     break;
> > +             case 8100:
> > +                     val = BIT_RATE_HBR3;
> > +                     break;
> > +             }
> > +             regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> > +     }
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> > +                        TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_reset(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 0);
>
> Please, when you add delays/sleeps, add a comment explaining the reason for that.
>
> To you.. and to me as well.. the reason is very much known and honestly obvious,
> but let's be nice with people that don't know the MediaTek platforms :)
>
It's sadly not obvious to me, I've asked mediatek engineers mutlple
times for these
kind of information, but I'm rather short on information... :-/

> > +     usleep_range(50, 200);
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 1);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct phy_ops mtk_dp_phy_dev_ops = {
> > +     .init = mtk_dp_phy_init,
> > +     .configure = mtk_dp_phy_configure,
> > +     .reset = mtk_dp_phy_reset,
> > +     .owner = THIS_MODULE,
> > +};
> > +
> > +static int mtk_dp_phy_probe(struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct mtk_dp_phy *dp_phy;
> > +     struct phy *phy;
>
>         struct regmap *regs = (blah);
>
>         if (!dp_phy->regs)
>                 return -EINVAL;
>
> Doing that before allocating the dp_phy struct seems sensible as, even
> if it's unlikely that this platform data is not passed, we'd be sparing
> some time around.
>
> Besides - I think that the error message is not necessary here, but, if
> you really want to keep it, please return dev_err_probe(): using it in
> these cases is also allowed.
>
You are right, it's logical to return as early as possible.

> > +
> > +     dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> > +     if (!dp_phy)
> > +             return -ENOMEM;
> > +
> > +     dp_phy->regs = *(struct regmap **)dev->platform_data;
> > +     if (!dp_phy->regs) {
> > +             dev_err(dev, "No data passed, requires struct regmap**\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
>
>         if (IS_ERR(phy))
>                 return dev_err_probe(dev, PTR_ERR(phy), "Cannot create DP PHY\n");
>
> > +     if (IS_ERR(phy)) {
> > +             dev_err(dev, "Failed to create DP PHY: %ld\n", PTR_ERR(phy));
> > +             return PTR_ERR(phy);
> > +     }
> > +     phy_set_drvdata(phy, dp_phy);
> > +
> > +     if (!dev->of_node)
>
> This will never happen if you use DT to probe this driver - and please do!
>
> An example device-tree binding would be:
>
> dp_phy: phy@somewhere {
>         compatible = "mediatek,mt8195-dp-phy", "mediatek,dp-phy";
>         reg = <...>;
>         #phy-cells = <0>;
> };
>
> mtk_dp: displayport-controller@somewhere_else {
>         compatible = "mediatek,mt8195-edp-tx", "mediatek,edp-tx";
>         reg = <....>;
>         other-properties;
>
>         phys = <&dp_phy>;
>         phy-names = "dp";
> };
>
> Also, remember: since you're nicely using regmap, if you - for any reason - need
> to share the same iospace between the two drivers, you can always use a
> syscon node for that purpose.
>
Sadly, I'm not using DT to prove this driver... and this driver will
probably never
be used with DT.
This phy is actually an integral part of the dp ip, this driver is
only a "logical"
separation between the DP/phy functionnalities.
It's probed from the DP driver with a call to `platform_register_device()`.
Both the DP and phy driver share the same regmap struct.

Markus tried to explain that in the commit message, please tell me if this needs
a reword?
The original discussion is here:
https://lore.kernel.org/all/CAAOTY__cJMqcAieEraJ2sz4gi0Zs-aiNXz38_x7dPQea6HvYEg@mail.gmail.com/

I didn't know about syscon, I'll have a look... but it's definitively what
I'm doing here...

> > +             phy_create_lookup(phy, "dp", dev_name(dev));
> > +
> > +     return 0;
> > +}
> > +
> > +struct platform_driver mtk_dp_phy_driver = {
> > +     .probe = mtk_dp_phy_probe,
> > +     .driver = {
> > +             .name = "mediatek-dp-phy",
> > +     },
> > +};
> > +module_platform_driver(mtk_dp_phy_driver);
> > +
> > +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> > +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> > +MODULE_LICENSE("GPL v2");
>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

WARNING: multiple messages have this Message-ID (diff)
From: Guillaume Ranquet <granquet@baylibre.com>
To: AngeloGioacchino Del Regno
	<angelogioacchino.delregno@collabora.com>,
	airlied@linux.ie,  chunfeng.yun@mediatek.com,
	chunkuang.hu@kernel.org, ck.hu@mediatek.com,  daniel@ffwll.ch,
	deller@gmx.de, jitao.shi@mediatek.com, kishon@ti.com,
	 maarten.lankhorst@linux.intel.com, matthias.bgg@gmail.com,
	mripard@kernel.org,  p.zabel@pengutronix.de, robh+dt@kernel.org,
	tzimmermann@suse.de,  vkoul@kernel.org
Cc: dri-devel@lists.freedesktop.org,
	linux-mediatek@lists.infradead.org,  devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	 linux-arm-kernel@lists.infradead.org,
	linux-phy@lists.infradead.org,  linux-fbdev@vger.kernel.org,
	Markus Schneider-Pargmann <msp@baylibre.com>
Subject: Re: [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy
Date: Fri, 25 Feb 2022 03:49:51 -0800	[thread overview]
Message-ID: <CABnWg9tfutasgiUaLBvb8CxTycLKf8Ry=9PMi2Vtu2JeB4a=dQ@mail.gmail.com> (raw)
In-Reply-To: <bdd867fe-3103-a99b-e9ec-02df6a18d385@collabora.com>

Quoting AngeloGioacchino Del Regno (2022-02-21 15:31:51)
> Il 18/02/22 15:54, Guillaume Ranquet ha scritto:
> > From: Markus Schneider-Pargmann <msp@baylibre.com>
> >
> > This is a new driver that supports the integrated DisplayPort phy for
> > mediatek SoCs, especially the mt8195. The phy is integrated into the
> > DisplayPort controller and will be created by the mtk-dp driver. This
> > driver expects a struct regmap to be able to work on the same registers
> > as the DisplayPort controller. It sets the device data to be the struct
> > phy so that the DisplayPort controller can easily work with it.
> >
> > The driver does not have any devicetree bindings because the datasheet
> > does not list the controller and the phy as distinct units.
> >
> > The interaction with the controller can be covered by the configure
> > callback of the phy framework and its displayport parameters.
> >
> > Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
> > Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
> > ---
> >   MAINTAINERS                       |   1 +
> >   drivers/phy/mediatek/Kconfig      |   8 ++
> >   drivers/phy/mediatek/Makefile     |   1 +
> >   drivers/phy/mediatek/phy-mtk-dp.c | 199 ++++++++++++++++++++++++++++++
> >   4 files changed, 209 insertions(+)
> >   create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fca970a46e77a..33a05d396dd03 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6467,6 +6467,7 @@ L:      linux-mediatek@lists.infradead.org (moderated for non-subscribers)
> >   S:  Supported
> >   F:  Documentation/devicetree/bindings/display/mediatek/
> >   F:  drivers/gpu/drm/mediatek/
> > +F:   drivers/phy/mediatek/phy-mtk-dp.c
> >   F:  drivers/phy/mediatek/phy-mtk-hdmi*
> >   F:  drivers/phy/mediatek/phy-mtk-mipi*
> >
> > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > index 55f8e6c048ab3..f7ec860590492 100644
> > --- a/drivers/phy/mediatek/Kconfig
> > +++ b/drivers/phy/mediatek/Kconfig
> > @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI
> >       select GENERIC_PHY
> >       help
> >         Support MIPI DSI for Mediatek SoCs.
> > +
> > +config PHY_MTK_DP
> > +     tristate "MediaTek DP-PHY Driver"
> > +     depends on ARCH_MEDIATEK || COMPILE_TEST
> > +     depends on OF
> > +     select GENERIC_PHY
> > +     help
> > +       Support DisplayPort PHY for Mediatek SoCs.
> > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > index ace660fbed3a1..4ba1e06504346 100644
> > --- a/drivers/phy/mediatek/Makefile
> > +++ b/drivers/phy/mediatek/Makefile
> > @@ -3,6 +3,7 @@
> >   # Makefile for the phy drivers.
> >   #
> >
> > +obj-$(CONFIG_PHY_MTK_DP)             += phy-mtk-dp.o
> >   obj-$(CONFIG_PHY_MTK_TPHY)          += phy-mtk-tphy.o
> >   obj-$(CONFIG_PHY_MTK_UFS)           += phy-mtk-ufs.o
> >   obj-$(CONFIG_PHY_MTK_XSPHY)         += phy-mtk-xsphy.o
> > diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c
> > new file mode 100644
> > index 0000000000000..2841dd3f22543
> > --- /dev/null
> > +++ b/drivers/phy/mediatek/phy-mtk-dp.c
> > @@ -0,0 +1,199 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
>
> Would be nice to add:
>
>   * phy-mtk-dp.c - MediaTek DisplayPort PHY driver
>   *
>
> > + * Copyright (c) 2021 BayLibre
> > + * Author: Markus Schneider-Pargmann <msp@baylibre.com>
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +
> > +#define PHY_OFFSET 0x1000
> > +
> > +#define MTK_DP_PHY_DIG_PLL_CTL_1             (PHY_OFFSET + 0x014)
> > +#define TPLL_SSC_EN                                  BIT(3)
> > +
> > +#define MTK_DP_PHY_DIG_BIT_RATE              (PHY_OFFSET + 0x03C)
> > +#define BIT_RATE_RBR                         0
> > +#define BIT_RATE_HBR                         1
> > +#define BIT_RATE_HBR2                                2
> > +#define BIT_RATE_HBR3                                3
> > +
> > +#define MTK_DP_PHY_DIG_SW_RST                (PHY_OFFSET + 0x038)
> > +#define DP_GLB_SW_RST_PHYD                   BIT(0)
> > +
> > +#define MTK_DP_LANE0_DRIVING_PARAM_3         (PHY_OFFSET + 0x138)
> > +#define MTK_DP_LANE1_DRIVING_PARAM_3         (PHY_OFFSET + 0x238)
> > +#define MTK_DP_LANE2_DRIVING_PARAM_3         (PHY_OFFSET + 0x338)
> > +#define MTK_DP_LANE3_DRIVING_PARAM_3         (PHY_OFFSET + 0x438)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT    0x10
>
> BIT(4)
>
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT    (0x14 << 8)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT    (0x18 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT    (0x20 << 24)
>
> Please use the GENMASK() macro for these definitions.
>
I will convert all the definitions to BIT() and GENMASK() for v9

> > +#define DRIVING_PARAM_3_DEFAULT              (XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT    0x18
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT    (0x1e << 8)
> > +#define XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT    (0x24 << 16)
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT    (0x20 << 24)
> > +#define DRIVING_PARAM_4_DEFAULT              (XTP_LN_TX_LCTXC0_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT    0x28
> > +#define XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT    (0x30 << 8)
> > +#define DRIVING_PARAM_5_DEFAULT              (XTP_LN_TX_LCTXC0_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXC0_SW3_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT   0x00
>
> This is just 0
>
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT   (0x04 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT   (0x08 << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT   (0x10 << 24)
> > +#define DRIVING_PARAM_6_DEFAULT              (XTP_LN_TX_LCTXCP1_SW0_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW0_PRE3_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT   0x00
>
> ...just 0 again
>
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT   (0x06 << 8)
> > +#define XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT   (0x0c << 16)
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT   (0x00 << 24)
>
> zero shifted by a million bits is still zero, so this statement does not make sense
>
> > +#define DRIVING_PARAM_7_DEFAULT              (XTP_LN_TX_LCTXCP1_SW1_PRE0_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW1_PRE2_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW2_PRE0_DEFAULT)
> > +
> > +#define XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT   0x08
> > +#define XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT   (0x00 << 8)
>
> Same here.
>
> > +#define DRIVING_PARAM_8_DEFAULT              (XTP_LN_TX_LCTXCP1_SW2_PRE1_DEFAULT | \
> > +                                              XTP_LN_TX_LCTXCP1_SW3_PRE0_DEFAULT)
> > +
> > +struct mtk_dp_phy {
> > +     struct regmap *regs;
> > +};
> > +
> > +static int mtk_dp_phy_init(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 driving_params[] = {
> > +             DRIVING_PARAM_3_DEFAULT,
> > +             DRIVING_PARAM_4_DEFAULT,
> > +             DRIVING_PARAM_5_DEFAULT,
> > +             DRIVING_PARAM_6_DEFAULT,
> > +             DRIVING_PARAM_7_DEFAULT,
> > +             DRIVING_PARAM_8_DEFAULT
> > +     };
> > +
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE0_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE1_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE2_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +     regmap_bulk_write(dp_phy->regs, MTK_DP_LANE3_DRIVING_PARAM_3,
> > +                       driving_params, ARRAY_SIZE(driving_params));
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_configure(struct phy *phy, union phy_configure_opts *opts)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +     u32 val;
> > +
> > +     if (opts->dp.set_rate) {
> > +             switch (opts->dp.link_rate) {
> > +             default:
> > +                     dev_err(&phy->dev,
> > +                             "Implementation error, unknown linkrate %x\n",
> > +                             opts->dp.link_rate);
> > +                     return -EINVAL;
> > +             case 1620:
> > +                     val = BIT_RATE_RBR;
> > +                     break;
> > +             case 2700:
> > +                     val = BIT_RATE_HBR;
> > +                     break;
> > +             case 5400:
> > +                     val = BIT_RATE_HBR2;
> > +                     break;
> > +             case 8100:
> > +                     val = BIT_RATE_HBR3;
> > +                     break;
> > +             }
> > +             regmap_write(dp_phy->regs, MTK_DP_PHY_DIG_BIT_RATE, val);
> > +     }
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_PLL_CTL_1,
> > +                        TPLL_SSC_EN, opts->dp.ssc ? TPLL_SSC_EN : 0);
> > +
> > +     return 0;
> > +}
> > +
> > +static int mtk_dp_phy_reset(struct phy *phy)
> > +{
> > +     struct mtk_dp_phy *dp_phy = phy_get_drvdata(phy);
> > +
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 0);
>
> Please, when you add delays/sleeps, add a comment explaining the reason for that.
>
> To you.. and to me as well.. the reason is very much known and honestly obvious,
> but let's be nice with people that don't know the MediaTek platforms :)
>
It's sadly not obvious to me, I've asked mediatek engineers mutlple
times for these
kind of information, but I'm rather short on information... :-/

> > +     usleep_range(50, 200);
> > +     regmap_update_bits(dp_phy->regs, MTK_DP_PHY_DIG_SW_RST,
> > +                        DP_GLB_SW_RST_PHYD, 1);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct phy_ops mtk_dp_phy_dev_ops = {
> > +     .init = mtk_dp_phy_init,
> > +     .configure = mtk_dp_phy_configure,
> > +     .reset = mtk_dp_phy_reset,
> > +     .owner = THIS_MODULE,
> > +};
> > +
> > +static int mtk_dp_phy_probe(struct platform_device *pdev)
> > +{
> > +     struct device *dev = &pdev->dev;
> > +     struct mtk_dp_phy *dp_phy;
> > +     struct phy *phy;
>
>         struct regmap *regs = (blah);
>
>         if (!dp_phy->regs)
>                 return -EINVAL;
>
> Doing that before allocating the dp_phy struct seems sensible as, even
> if it's unlikely that this platform data is not passed, we'd be sparing
> some time around.
>
> Besides - I think that the error message is not necessary here, but, if
> you really want to keep it, please return dev_err_probe(): using it in
> these cases is also allowed.
>
You are right, it's logical to return as early as possible.

> > +
> > +     dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL);
> > +     if (!dp_phy)
> > +             return -ENOMEM;
> > +
> > +     dp_phy->regs = *(struct regmap **)dev->platform_data;
> > +     if (!dp_phy->regs) {
> > +             dev_err(dev, "No data passed, requires struct regmap**\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     phy = devm_phy_create(dev, NULL, &mtk_dp_phy_dev_ops);
>
>         if (IS_ERR(phy))
>                 return dev_err_probe(dev, PTR_ERR(phy), "Cannot create DP PHY\n");
>
> > +     if (IS_ERR(phy)) {
> > +             dev_err(dev, "Failed to create DP PHY: %ld\n", PTR_ERR(phy));
> > +             return PTR_ERR(phy);
> > +     }
> > +     phy_set_drvdata(phy, dp_phy);
> > +
> > +     if (!dev->of_node)
>
> This will never happen if you use DT to probe this driver - and please do!
>
> An example device-tree binding would be:
>
> dp_phy: phy@somewhere {
>         compatible = "mediatek,mt8195-dp-phy", "mediatek,dp-phy";
>         reg = <...>;
>         #phy-cells = <0>;
> };
>
> mtk_dp: displayport-controller@somewhere_else {
>         compatible = "mediatek,mt8195-edp-tx", "mediatek,edp-tx";
>         reg = <....>;
>         other-properties;
>
>         phys = <&dp_phy>;
>         phy-names = "dp";
> };
>
> Also, remember: since you're nicely using regmap, if you - for any reason - need
> to share the same iospace between the two drivers, you can always use a
> syscon node for that purpose.
>
Sadly, I'm not using DT to prove this driver... and this driver will
probably never
be used with DT.
This phy is actually an integral part of the dp ip, this driver is
only a "logical"
separation between the DP/phy functionnalities.
It's probed from the DP driver with a call to `platform_register_device()`.
Both the DP and phy driver share the same regmap struct.

Markus tried to explain that in the commit message, please tell me if this needs
a reword?
The original discussion is here:
https://lore.kernel.org/all/CAAOTY__cJMqcAieEraJ2sz4gi0Zs-aiNXz38_x7dPQea6HvYEg@mail.gmail.com/

I didn't know about syscon, I'll have a look... but it's definitively what
I'm doing here...

> > +             phy_create_lookup(phy, "dp", dev_name(dev));
> > +
> > +     return 0;
> > +}
> > +
> > +struct platform_driver mtk_dp_phy_driver = {
> > +     .probe = mtk_dp_phy_probe,
> > +     .driver = {
> > +             .name = "mediatek-dp-phy",
> > +     },
> > +};
> > +module_platform_driver(mtk_dp_phy_driver);
> > +
> > +MODULE_AUTHOR("Markus Schneider-Pargmann <msp@baylibre.com>");
> > +MODULE_DESCRIPTION("MediaTek DP PHY Driver");
> > +MODULE_LICENSE("GPL v2");
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2022-02-25 11:49 UTC|newest]

Thread overview: 315+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-18 14:54 [PATCH v8 0/19] drm/mediatek: Add mt8195 DisplayPort driver Guillaume Ranquet
2022-02-18 14:54 ` Guillaume Ranquet
2022-02-18 14:54 ` Guillaume Ranquet
2022-02-18 14:54 ` Guillaume Ranquet
2022-02-18 14:54 ` Guillaume Ranquet
2022-02-18 14:54 ` [PATCH v8 01/19] dt-bindings: mediatek,dpi: Add DP_INTF compatible Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54 ` [PATCH v8 02/19] dt-bindings: mediatek,dp: Add Display Port binding Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  2:36   ` Rob Herring
2022-02-21  2:36     ` [PATCH v8 02/19] dt-bindings: mediatek, dp: " Rob Herring
2022-02-21  2:36     ` Rob Herring
2022-02-21  2:36     ` Rob Herring
2022-02-21  2:36     ` Rob Herring
2022-02-18 14:54 ` [PATCH v8 03/19] drm/edid: Add cea_sad helpers for freq/length Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21 14:30   ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-25 10:35     ` Guillaume Ranquet
2022-02-25 10:35       ` Guillaume Ranquet
2022-02-25 10:35       ` Guillaume Ranquet
2022-02-25 10:35       ` Guillaume Ranquet
2022-02-25 10:35       ` Guillaume Ranquet
2022-02-18 14:54 ` [PATCH v8 04/19] video/hdmi: Add audio_infoframe packing for DP Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21 14:30   ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-25 10:38     ` Guillaume Ranquet
2022-02-25 10:38       ` Guillaume Ranquet
2022-02-25 10:38       ` Guillaume Ranquet
2022-02-25 10:38       ` Guillaume Ranquet
2022-02-25 10:38       ` Guillaume Ranquet
2022-02-22 15:16   ` AngeloGioacchino Del Regno
2022-02-22 15:16     ` AngeloGioacchino Del Regno
2022-02-22 15:16     ` AngeloGioacchino Del Regno
2022-02-22 15:16     ` AngeloGioacchino Del Regno
2022-02-22 15:16     ` AngeloGioacchino Del Regno
2022-02-25 10:40     ` Guillaume Ranquet
2022-02-25 10:40       ` Guillaume Ranquet
2022-02-25 10:40       ` Guillaume Ranquet
2022-02-25 10:40       ` Guillaume Ranquet
2022-02-25 10:40       ` Guillaume Ranquet
2022-02-18 14:54 ` [PATCH v8 05/19] drm/mediatek: dpi: move dpi limits to board config Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  1:46   ` Chun-Kuang Hu
2022-02-21  1:46     ` Chun-Kuang Hu
2022-02-21  1:46     ` Chun-Kuang Hu
2022-02-21  1:46     ` Chun-Kuang Hu
2022-02-21  1:46     ` Chun-Kuang Hu
2022-02-25 10:45     ` Guillaume Ranquet
2022-02-25 10:45       ` Guillaume Ranquet
2022-02-25 10:45       ` Guillaume Ranquet
2022-02-25 10:45       ` Guillaume Ranquet
2022-02-25 10:45       ` Guillaume Ranquet
2022-02-21 14:30   ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 06/19] drm/mediatek: dpi: implement a CK/DE pol toggle in " Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  2:14   ` Chun-Kuang Hu
2022-02-21  2:14     ` Chun-Kuang Hu
2022-02-21  2:14     ` Chun-Kuang Hu
2022-02-21  2:14     ` Chun-Kuang Hu
2022-02-21  2:14     ` Chun-Kuang Hu
2022-02-25 10:52     ` Guillaume Ranquet
2022-02-25 10:52       ` Guillaume Ranquet
2022-02-25 10:52       ` Guillaume Ranquet
2022-02-25 10:52       ` Guillaume Ranquet
2022-02-25 10:52       ` Guillaume Ranquet
2022-02-21 14:30   ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 07/19] drm/mediatek: dpi: implement a swap_input " Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  2:32   ` Chun-Kuang Hu
2022-02-21  2:32     ` Chun-Kuang Hu
2022-02-21  2:32     ` Chun-Kuang Hu
2022-02-21  2:32     ` Chun-Kuang Hu
2022-02-21  2:32     ` Chun-Kuang Hu
2022-02-25 10:55     ` Guillaume Ranquet
2022-02-25 10:55       ` Guillaume Ranquet
2022-02-25 10:55       ` Guillaume Ranquet
2022-02-25 10:55       ` Guillaume Ranquet
2022-02-25 10:55       ` Guillaume Ranquet
2022-02-18 14:54 ` [PATCH v8 08/19] drm/mediatek: dpi: move dimension mask to " Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  2:40   ` Chun-Kuang Hu
2022-02-21  2:40     ` Chun-Kuang Hu
2022-02-21  2:40     ` Chun-Kuang Hu
2022-02-21  2:40     ` Chun-Kuang Hu
2022-02-21  2:40     ` Chun-Kuang Hu
2022-02-21  2:42     ` Chun-Kuang Hu
2022-02-21  2:42       ` Chun-Kuang Hu
2022-02-21  2:42       ` Chun-Kuang Hu
2022-02-21  2:42       ` Chun-Kuang Hu
2022-02-21  2:42       ` Chun-Kuang Hu
2022-02-21 14:30   ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 09/19] drm/mediatek: dpi: move dimension_mask " Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  2:43   ` Chun-Kuang Hu
2022-02-21  2:43     ` Chun-Kuang Hu
2022-02-21  2:43     ` Chun-Kuang Hu
2022-02-21  2:43     ` Chun-Kuang Hu
2022-02-21  2:43     ` Chun-Kuang Hu
2022-02-21 14:31   ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 10/19] drm/mediatek: dpi: move swap_shift " Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  3:24   ` Chun-Kuang Hu
2022-02-21  3:24     ` Chun-Kuang Hu
2022-02-21  3:24     ` Chun-Kuang Hu
2022-02-21  3:24     ` Chun-Kuang Hu
2022-02-21  3:24     ` Chun-Kuang Hu
2022-02-25 11:10     ` Guillaume Ranquet
2022-02-25 11:10       ` Guillaume Ranquet
2022-02-25 11:10       ` Guillaume Ranquet
2022-02-25 11:10       ` Guillaume Ranquet
2022-02-25 11:10       ` Guillaume Ranquet
2022-02-21 14:31   ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 11/19] drm/mediatek: dpi: move the yuv422_en_bit " Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  3:31   ` Chun-Kuang Hu
2022-02-21  3:31     ` Chun-Kuang Hu
2022-02-21  3:31     ` Chun-Kuang Hu
2022-02-21  3:31     ` Chun-Kuang Hu
2022-02-21  3:31     ` Chun-Kuang Hu
2022-02-21 14:31   ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 12/19] drm/mediatek: dpi: move the csc_enable bit " Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  3:33   ` Chun-Kuang Hu
2022-02-21  3:33     ` Chun-Kuang Hu
2022-02-21  3:33     ` Chun-Kuang Hu
2022-02-21  3:33     ` Chun-Kuang Hu
2022-02-21  3:33     ` Chun-Kuang Hu
2022-02-21 14:31   ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 13/19] drm/mediatek: dpi: Add dpintf support Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21  4:34   ` Chun-Kuang Hu
2022-02-21  4:34     ` Chun-Kuang Hu
2022-02-21  4:34     ` Chun-Kuang Hu
2022-02-21  4:34     ` Chun-Kuang Hu
2022-02-21  4:34     ` Chun-Kuang Hu
2022-02-21  9:44   ` Maxime Ripard
2022-02-21  9:44     ` Maxime Ripard
2022-02-21  9:44     ` Maxime Ripard
2022-02-21  9:44     ` Maxime Ripard
2022-02-21  9:44     ` Maxime Ripard
2022-02-25 11:25     ` Guillaume Ranquet
2022-02-25 11:25       ` Guillaume Ranquet
2022-02-25 11:25       ` Guillaume Ranquet
2022-02-25 11:25       ` Guillaume Ranquet
2022-02-25 11:25       ` Guillaume Ranquet
2022-02-21 14:30   ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-21 14:30     ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 14/19] phy: phy-mtk-dp: Add driver for DP phy Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21 14:31   ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-25 11:49     ` Guillaume Ranquet [this message]
2022-02-25 11:49       ` Guillaume Ranquet
2022-02-25 11:49       ` Guillaume Ranquet
2022-02-25 11:49       ` Guillaume Ranquet
2022-02-25 11:49       ` Guillaume Ranquet
2022-02-25 12:06       ` AngeloGioacchino Del Regno
2022-02-25 12:06         ` AngeloGioacchino Del Regno
2022-02-25 12:06         ` AngeloGioacchino Del Regno
2022-02-25 12:06         ` AngeloGioacchino Del Regno
2022-02-25 12:06         ` AngeloGioacchino Del Regno
2022-02-18 14:54 ` [PATCH v8 15/19] drm/mediatek: Add mt8195 Embedded DisplayPort driver Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-21 14:31   ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-21 14:31     ` AngeloGioacchino Del Regno
2022-02-24 13:57   ` AngeloGioacchino Del Regno
2022-02-24 13:57     ` AngeloGioacchino Del Regno
2022-02-24 13:57     ` AngeloGioacchino Del Regno
2022-02-24 13:57     ` AngeloGioacchino Del Regno
2022-02-24 13:57     ` AngeloGioacchino Del Regno
2022-02-25  9:45   ` CK Hu
2022-02-25  9:45     ` CK Hu
2022-02-25  9:45     ` CK Hu
2022-02-25  9:45     ` CK Hu
2022-02-25  9:45     ` CK Hu
2022-02-25 13:04     ` Guillaume Ranquet
2022-02-25 13:04       ` Guillaume Ranquet
2022-02-25 13:04       ` Guillaume Ranquet
2022-02-25 13:04       ` Guillaume Ranquet
2022-02-25 13:04       ` Guillaume Ranquet
2022-03-04  2:42   ` CK Hu
2022-03-04  2:42     ` CK Hu
2022-03-04  2:42     ` CK Hu
2022-03-04  2:42     ` CK Hu
2022-03-04  2:42     ` CK Hu
2022-02-18 14:54 ` [PATCH v8 16/19] drm/mediatek: Add mt8195 External DisplayPort support Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54 ` [PATCH v8 17/19] drm/mediatek: add hpd debounce Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-03-16  6:48   ` Rex-BC Chen
2022-03-16  6:48     ` Rex-BC Chen
2022-03-16  6:48     ` Rex-BC Chen
2022-03-16  6:48     ` Rex-BC Chen
2022-03-16  6:48     ` Rex-BC Chen
2022-03-18  9:03   ` Wei-Shun Chang
2022-03-18  9:03     ` Wei-Shun Chang
2022-03-18  9:03     ` Wei-Shun Chang
2022-03-18  9:03     ` Wei-Shun Chang
2022-03-18  9:03     ` Wei-Shun Chang
2022-03-21  7:24   ` Rex-BC Chen
2022-03-21  7:24     ` Rex-BC Chen
2022-03-21  7:24     ` Rex-BC Chen
2022-03-21  7:24     ` Rex-BC Chen
2022-03-21  7:24     ` Rex-BC Chen
2022-02-18 14:54 ` [PATCH v8 18/19] drm/mediatek: change the aux retries times when receiving AUX_DEFER Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-03-16 13:35   ` Chen-Yu Tsai
2022-03-16 13:35     ` Chen-Yu Tsai
2022-03-16 13:35     ` Chen-Yu Tsai
2022-03-16 13:35     ` Chen-Yu Tsai
2022-03-16 13:35     ` Chen-Yu Tsai
2022-02-18 14:54 ` [PATCH v8 19/19] drm/mediatek: DP audio support for mt8195 Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet
2022-02-18 14:54   ` Guillaume Ranquet

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='CABnWg9tfutasgiUaLBvb8CxTycLKf8Ry=9PMi2Vtu2JeB4a=dQ@mail.gmail.com' \
    --to=granquet@baylibre.com \
    --cc=airlied@linux.ie \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=chunfeng.yun@mediatek.com \
    --cc=chunkuang.hu@kernel.org \
    --cc=ck.hu@mediatek.com \
    --cc=daniel@ffwll.ch \
    --cc=deller@gmx.de \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jitao.shi@mediatek.com \
    --cc=kishon@ti.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=matthias.bgg@gmail.com \
    --cc=mripard@kernel.org \
    --cc=msp@baylibre.com \
    --cc=p.zabel@pengutronix.de \
    --cc=robh+dt@kernel.org \
    --cc=tzimmermann@suse.de \
    --cc=vkoul@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.