.../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 10 +++ drivers/gpu/drm/sun4i/sun4i_tcon.c | 40 ++++++++++++ drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 65 ++++++++++++++++++- 4 files changed, 119 insertions(+), 2 deletions(-)
Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo MIPI DSI D-PHY" which is required when using single-link LVDS0. The same PD0..PD9 pins are used for either DSI or LVDS. Other than having to use the combo D-PHY, LVDS output is configured in the same way as on older chips. This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It is then configured by the LCD TCON, which allows connecting a single-link LVDS display panel. Kuba Szczodrzyński (5): phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY drm/sun4i: Support LVDS using MIPI DSI combo D-PHY drm/sun4i: Enable LVDS output on sun20i D1s/T113 riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 riscv: dts: allwinner: d1s-t113: Add LVDS0 pins .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 10 +++ drivers/gpu/drm/sun4i/sun4i_tcon.c | 40 ++++++++++++ drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 65 ++++++++++++++++++- 4 files changed, 119 insertions(+), 2 deletions(-) -- 2.25.1
Hi, Thanks for your work! On Fri 21 Feb 25, 17:17, Kuba Szczodrzyński wrote: > Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo > MIPI DSI D-PHY" which is required when using single-link LVDS0. The same > PD0..PD9 pins are used for either DSI or LVDS. > > Other than having to use the combo D-PHY, LVDS output is configured in > the same way as on older chips. From what I understand of section 5.1.4.2 LVDS Mode Configuration Process there's two LVDS outputs: - LVDS0, driven by the combo-phy - LVDS1, driven by the usual TCON0 LVDS PHY As far as I understand the LVDS_IF register still has to be configured for LVDS0. The D1 manual mentions a LVDS1_IF register at offset 0x244 (which I don't see in the T113-S3 manual, but is probably also there), which is liekely used to configure LVDS1. Then we find our LVDS_ANA0/ANA1 registers that are likely just used for LVDS1. While this series adds support for LVDS0 only, it would be good to also be able to support LVDS1, including dual-link modes. So eventually we'd need a way to actually support both cases. It would be great if you could include these details somewhere so they don't get lost. And this seems to be the exact same situation as the A133 by the way. All the best, Paul > This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It > is then configured by the LCD TCON, which allows connecting a > single-link LVDS display panel. > > Kuba Szczodrzyński (5): > phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY > drm/sun4i: Support LVDS using MIPI DSI combo D-PHY > drm/sun4i: Enable LVDS output on sun20i D1s/T113 > riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 > riscv: dts: allwinner: d1s-t113: Add LVDS0 pins > > .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 10 +++ > drivers/gpu/drm/sun4i/sun4i_tcon.c | 40 ++++++++++++ > drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ > drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 65 ++++++++++++++++++- > 4 files changed, 119 insertions(+), 2 deletions(-) > > -- > 2.25.1 > > -- Paul Kocialkowski, Independent contractor - sys-base - https://www.sys-base.io/ Free software developer - https://www.paulk.fr/ Expert in multimedia, graphics and embedded hardware support with Linux.
[replying to v1 to keep the same series on Patchwork] Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo MIPI DSI D-PHY" which is required when using single-link LVDS0. The same PD0..PD9 pins are used for either DSI or LVDS. Other than having to use the combo D-PHY, LVDS output is configured in the same way as on older chips. This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It is then configured by the LCD TCON, which allows connecting a single-link LVDS display panel. Changes in v2/v3: - Applied code formatting changes from review comments - Changed "dphy" to "combo-phy" - Made the LVDS setup/teardown functions abort early in case of error (adding a proper return value would require changes in several levels of caller functions; perhaps could be done in a separate patch) - Added the PHY properties to DT bindings - Renamed lvds0_pins to lcd_lvds0_pins - Rebased on top of drm/misc/kernel/for-linux-next - Hopefully corrected the incomplete patch list of v2, which happened due to an SMTP error Kuba Szczodrzyński (6): phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY drm/sun4i: Support LVDS using MIPI DSI combo D-PHY drm/sun4i: Enable LVDS output on sun20i D1s/T113 dt-bindings: display: sun4i: Add D1s/T113 combo D-PHY bindings riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 riscv: dts: allwinner: d1s-t113: Add LVDS0 pins .../display/allwinner,sun4i-a10-tcon.yaml | 6 ++ .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 11 +++ drivers/gpu/drm/sun4i/sun4i_tcon.c | 50 +++++++++++++ drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++- 5 files changed, 141 insertions(+), 2 deletions(-) -- 2.25.1
On Sun, Nov 16, 2025 at 9:46 PM Kuba Szczodrzyński <kuba@szczodrzynski.pl> wrote: > > [replying to v1 to keep the same series on Patchwork] That is not the right way to do it. If you reply to an old series, the tooling does not pickup the new version as a separate series. ChenYu > Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo > MIPI DSI D-PHY" which is required when using single-link LVDS0. The same > PD0..PD9 pins are used for either DSI or LVDS. > > Other than having to use the combo D-PHY, LVDS output is configured in > the same way as on older chips. > > This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It > is then configured by the LCD TCON, which allows connecting a > single-link LVDS display panel. > > Changes in v2/v3: > - Applied code formatting changes from review comments > - Changed "dphy" to "combo-phy" > - Made the LVDS setup/teardown functions abort early in case of error > (adding a proper return value would require changes in several levels > of caller functions; perhaps could be done in a separate patch) > - Added the PHY properties to DT bindings > - Renamed lvds0_pins to lcd_lvds0_pins > - Rebased on top of drm/misc/kernel/for-linux-next > - Hopefully corrected the incomplete patch list of v2, which happened > due to an SMTP error > > Kuba Szczodrzyński (6): > phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY > drm/sun4i: Support LVDS using MIPI DSI combo D-PHY > drm/sun4i: Enable LVDS output on sun20i D1s/T113 > dt-bindings: display: sun4i: Add D1s/T113 combo D-PHY bindings > riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 > riscv: dts: allwinner: d1s-t113: Add LVDS0 pins > > .../display/allwinner,sun4i-a10-tcon.yaml | 6 ++ > .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 11 +++ > drivers/gpu/drm/sun4i/sun4i_tcon.c | 50 +++++++++++++ > drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ > drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++- > 5 files changed, 141 insertions(+), 2 deletions(-) > > -- > 2.25.1 >
W dniu 2025-11-16 o 15:03:18, Chen-Yu Tsai pisze: > On Sun, Nov 16, 2025 at 9:46 PM Kuba Szczodrzyński > <kuba@szczodrzynski.pl> wrote: >> [replying to v1 to keep the same series on Patchwork] > That is not the right way to do it. > > If you reply to an old series, the tooling does not pickup the new version > as a separate series. > > ChenYu Hi, I noticed that it indeed didn't work. However, Patchwork didn't pick up the v2 cover letter at all, so I thought replying to v2 would mess up the thread even more. That being said, the v3 cover letter is not visible there either. Should I resend this as v4 [which message to reply to?] or send a completely new series perhaps? I apologize for the confusion, this is my first time doing that. Regards Kuba >> Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo >> MIPI DSI D-PHY" which is required when using single-link LVDS0. The same >> PD0..PD9 pins are used for either DSI or LVDS. >> >> Other than having to use the combo D-PHY, LVDS output is configured in >> the same way as on older chips. >> >> This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It >> is then configured by the LCD TCON, which allows connecting a >> single-link LVDS display panel. >> >> Changes in v2/v3: >> - Applied code formatting changes from review comments >> - Changed "dphy" to "combo-phy" >> - Made the LVDS setup/teardown functions abort early in case of error >> (adding a proper return value would require changes in several levels >> of caller functions; perhaps could be done in a separate patch) >> - Added the PHY properties to DT bindings >> - Renamed lvds0_pins to lcd_lvds0_pins >> - Rebased on top of drm/misc/kernel/for-linux-next >> - Hopefully corrected the incomplete patch list of v2, which happened >> due to an SMTP error >> >> Kuba Szczodrzyński (6): >> phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY >> drm/sun4i: Support LVDS using MIPI DSI combo D-PHY >> drm/sun4i: Enable LVDS output on sun20i D1s/T113 >> dt-bindings: display: sun4i: Add D1s/T113 combo D-PHY bindings >> riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 >> riscv: dts: allwinner: d1s-t113: Add LVDS0 pins >> >> .../display/allwinner,sun4i-a10-tcon.yaml | 6 ++ >> .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 11 +++ >> drivers/gpu/drm/sun4i/sun4i_tcon.c | 50 +++++++++++++ >> drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ >> drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++- >> 5 files changed, 141 insertions(+), 2 deletions(-) >> >> -- >> 2.25.1 >>
On Sun, Nov 16, 2025 at 10:31 PM Kuba Szczodrzyński <kuba@szczodrzynski.pl> wrote: > > W dniu 2025-11-16 o 15:03:18, Chen-Yu Tsai pisze: > > > On Sun, Nov 16, 2025 at 9:46 PM Kuba Szczodrzyński > > <kuba@szczodrzynski.pl> wrote: > >> [replying to v1 to keep the same series on Patchwork] > > That is not the right way to do it. > > > > If you reply to an old series, the tooling does not pickup the new version > > as a separate series. > > > > ChenYu > > Hi, > > I noticed that it indeed didn't work. However, Patchwork didn't pick up the v2 cover letter at all, so I thought replying to v2 would mess up the thread even more. > > That being said, the v3 cover letter is not visible there either. > > Should I resend this as v4 [which message to reply to?] or send a completely new series perhaps? Each new version should be a completely new series. If patchwork still didn't pick it up, then it's possible either your patches didn't reach the mailing lists or the patchwork instances. Please check lore to see if your patches are there. ChenYu > I apologize for the confusion, this is my first time doing that. > > Regards > Kuba > > >> Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo > >> MIPI DSI D-PHY" which is required when using single-link LVDS0. The same > >> PD0..PD9 pins are used for either DSI or LVDS. > >> > >> Other than having to use the combo D-PHY, LVDS output is configured in > >> the same way as on older chips. > >> > >> This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It > >> is then configured by the LCD TCON, which allows connecting a > >> single-link LVDS display panel. > >> > >> Changes in v2/v3: > >> - Applied code formatting changes from review comments > >> - Changed "dphy" to "combo-phy" > >> - Made the LVDS setup/teardown functions abort early in case of error > >> (adding a proper return value would require changes in several levels > >> of caller functions; perhaps could be done in a separate patch) > >> - Added the PHY properties to DT bindings > >> - Renamed lvds0_pins to lcd_lvds0_pins > >> - Rebased on top of drm/misc/kernel/for-linux-next > >> - Hopefully corrected the incomplete patch list of v2, which happened > >> due to an SMTP error > >> > >> Kuba Szczodrzyński (6): > >> phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY > >> drm/sun4i: Support LVDS using MIPI DSI combo D-PHY > >> drm/sun4i: Enable LVDS output on sun20i D1s/T113 > >> dt-bindings: display: sun4i: Add D1s/T113 combo D-PHY bindings > >> riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 > >> riscv: dts: allwinner: d1s-t113: Add LVDS0 pins > >> > >> .../display/allwinner,sun4i-a10-tcon.yaml | 6 ++ > >> .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 11 +++ > >> drivers/gpu/drm/sun4i/sun4i_tcon.c | 50 +++++++++++++ > >> drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ > >> drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++- > >> 5 files changed, 141 insertions(+), 2 deletions(-) > >> > >> -- > >> 2.25.1 > >> >
W dniu 2025-11-16 o 15:37:15, Chen-Yu Tsai pisze: > On Sun, Nov 16, 2025 at 10:31 PM Kuba Szczodrzyński > <kuba@szczodrzynski.pl> wrote: >> W dniu 2025-11-16 o 15:03:18, Chen-Yu Tsai pisze: >> >>> On Sun, Nov 16, 2025 at 9:46 PM Kuba Szczodrzyński >>> <kuba@szczodrzynski.pl> wrote: >>>> [replying to v1 to keep the same series on Patchwork] >>> That is not the right way to do it. >>> >>> If you reply to an old series, the tooling does not pickup the new version >>> as a separate series. >>> >>> ChenYu >> Hi, >> >> I noticed that it indeed didn't work. However, Patchwork didn't pick up the v2 cover letter at all, so I thought replying to v2 would mess up the thread even more. >> >> That being said, the v3 cover letter is not visible there either. >> >> Should I resend this as v4 [which message to reply to?] or send a completely new series perhaps? > Each new version should be a completely new series. > > If patchwork still didn't pick it up, then it's possible either your > patches didn't reach the mailing lists or the patchwork instances. > Please check lore to see if your patches are there. The patches are on lore, but patchwork didn't pick them up because some were sent with the wrong In-Reply-To header, and that created threading issues. Assuming I understood your reply correctly, I'll send the entire series as v4 *without* the In-Reply-To header, which will create a new series on patchwork. Regards Kuba > > ChenYu > >> I apologize for the confusion, this is my first time doing that. >> >> Regards >> Kuba >> >>>> Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo >>>> MIPI DSI D-PHY" which is required when using single-link LVDS0. The same >>>> PD0..PD9 pins are used for either DSI or LVDS. >>>> >>>> Other than having to use the combo D-PHY, LVDS output is configured in >>>> the same way as on older chips. >>>> >>>> This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It >>>> is then configured by the LCD TCON, which allows connecting a >>>> single-link LVDS display panel. >>>> >>>> Changes in v2/v3: >>>> - Applied code formatting changes from review comments >>>> - Changed "dphy" to "combo-phy" >>>> - Made the LVDS setup/teardown functions abort early in case of error >>>> (adding a proper return value would require changes in several levels >>>> of caller functions; perhaps could be done in a separate patch) >>>> - Added the PHY properties to DT bindings >>>> - Renamed lvds0_pins to lcd_lvds0_pins >>>> - Rebased on top of drm/misc/kernel/for-linux-next >>>> - Hopefully corrected the incomplete patch list of v2, which happened >>>> due to an SMTP error >>>> >>>> Kuba Szczodrzyński (6): >>>> phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY >>>> drm/sun4i: Support LVDS using MIPI DSI combo D-PHY >>>> drm/sun4i: Enable LVDS output on sun20i D1s/T113 >>>> dt-bindings: display: sun4i: Add D1s/T113 combo D-PHY bindings >>>> riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 >>>> riscv: dts: allwinner: d1s-t113: Add LVDS0 pins >>>> >>>> .../display/allwinner,sun4i-a10-tcon.yaml | 6 ++ >>>> .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 11 +++ >>>> drivers/gpu/drm/sun4i/sun4i_tcon.c | 50 +++++++++++++ >>>> drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ >>>> drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++- >>>> 5 files changed, 141 insertions(+), 2 deletions(-) >>>> >>>> -- >>>> 2.25.1 >>>>
Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo
MIPI DSI D-PHY" which is required when using single-link LVDS0.
In this mode, the DSI peripheral is not used and the PHY is not
configured for DSI. Instead, the COMBO_PHY_REGx registers are set to
enable LVDS operation.
Enable the PHY driver to work in LVDS mode on chips with a combo D-PHY.
Also change the SUN50I_COMBO_PHY_REG1 macro names to reflect the correct
register name.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++++-
1 file changed, 68 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
index 36eab9527..57035b3a4 100644
--- a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
+++ b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
@@ -166,8 +166,8 @@
#define SUN50I_COMBO_PHY_REG0_EN_CP BIT(0)
#define SUN50I_COMBO_PHY_REG1 0x114
-#define SUN50I_COMBO_PHY_REG2_REG_VREF1P6(n) (((n) & 0x7) << 4)
-#define SUN50I_COMBO_PHY_REG2_REG_VREF0P8(n) ((n) & 0x7)
+#define SUN50I_COMBO_PHY_REG1_REG_VREF1P6(n) (((n) & 0x7) << 4)
+#define SUN50I_COMBO_PHY_REG1_REG_VREF0P8(n) ((n) & 0x7)
#define SUN50I_COMBO_PHY_REG2 0x118
#define SUN50I_COMBO_PHY_REG2_HS_STOP_DLY(n) ((n) & 0xff)
@@ -181,7 +181,9 @@ struct sun6i_dphy;
struct sun6i_dphy_variant {
void (*tx_power_on)(struct sun6i_dphy *dphy);
+ void (*lvds_power_on)(struct sun6i_dphy *dphy);
bool rx_supported;
+ bool is_combo_dphy;
};
struct sun6i_dphy {
@@ -222,6 +224,18 @@ static int sun6i_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
return 0;
}
+static int sun6i_dphy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+ struct sun6i_dphy *dphy = phy_get_drvdata(phy);
+
+ if (mode == PHY_MODE_LVDS && !dphy->variant->is_combo_dphy) {
+ /* Not a combo D-PHY: LVDS is not supported. */
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static void sun6i_a31_mipi_dphy_tx_power_on(struct sun6i_dphy *dphy)
{
u8 lanes_mask = GENMASK(dphy->config.lanes - 1, 0);
@@ -329,6 +343,43 @@ static void sun50i_a100_mipi_dphy_tx_power_on(struct sun6i_dphy *dphy)
udelay(1);
}
+static void sun50i_a100_mipi_dphy_lvds_power_on(struct sun6i_dphy *dphy)
+{
+ regmap_write(dphy->regs, SUN50I_COMBO_PHY_REG1,
+ SUN50I_COMBO_PHY_REG1_REG_VREF1P6(4) |
+ SUN50I_COMBO_PHY_REG1_REG_VREF0P8(3));
+
+ regmap_write(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_CP);
+ udelay(5);
+
+ regmap_update_bits(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_LVDS,
+ SUN50I_COMBO_PHY_REG0_EN_LVDS);
+ udelay(5);
+
+ regmap_update_bits(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_COMBOLDO,
+ SUN50I_COMBO_PHY_REG0_EN_COMBOLDO);
+ udelay(5);
+
+ regmap_update_bits(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_MIPI,
+ SUN50I_COMBO_PHY_REG0_EN_MIPI);
+
+ regmap_write(dphy->regs, SUN6I_DPHY_ANA4_REG,
+ SUN6I_DPHY_ANA4_REG_EN_MIPI |
+ SUN6I_DPHY_ANA4_REG_IB(2));
+
+ regmap_write(dphy->regs, SUN6I_DPHY_ANA3_REG,
+ SUN6I_DPHY_ANA3_EN_LDOR |
+ SUN6I_DPHY_ANA3_EN_LDOD);
+
+ regmap_write(dphy->regs, SUN6I_DPHY_ANA2_REG, 0);
+
+ regmap_write(dphy->regs, SUN6I_DPHY_ANA1_REG, 0);
+}
+
static int sun6i_dphy_tx_power_on(struct sun6i_dphy *dphy)
{
u8 lanes_mask = GENMASK(dphy->config.lanes - 1, 0);
@@ -492,6 +543,13 @@ static int sun6i_dphy_power_on(struct phy *phy)
{
struct sun6i_dphy *dphy = phy_get_drvdata(phy);
+ if (phy->attrs.mode == PHY_MODE_LVDS && dphy->variant->is_combo_dphy) {
+ if (!dphy->variant->lvds_power_on)
+ return -EINVAL;
+ dphy->variant->lvds_power_on(dphy);
+ return 0;
+ }
+
switch (dphy->direction) {
case SUN6I_DPHY_DIRECTION_TX:
return sun6i_dphy_tx_power_on(dphy);
@@ -514,6 +572,11 @@ static int sun6i_dphy_power_off(struct phy *phy)
regmap_write(dphy->regs, SUN6I_DPHY_ANA3_REG, 0);
regmap_write(dphy->regs, SUN6I_DPHY_ANA4_REG, 0);
+ if (phy->attrs.mode == PHY_MODE_LVDS && dphy->variant->is_combo_dphy) {
+ regmap_write(dphy->regs, SUN50I_COMBO_PHY_REG1, 0);
+ regmap_write(dphy->regs, SUN50I_COMBO_PHY_REG0, 0);
+ }
+
return 0;
}
@@ -533,6 +596,7 @@ static const struct phy_ops sun6i_dphy_ops = {
.configure = sun6i_dphy_configure,
.power_on = sun6i_dphy_power_on,
.power_off = sun6i_dphy_power_off,
+ .set_mode = sun6i_dphy_set_mode,
.init = sun6i_dphy_init,
.exit = sun6i_dphy_exit,
};
@@ -619,6 +683,8 @@ static const struct sun6i_dphy_variant sun6i_a31_mipi_dphy_variant = {
static const struct sun6i_dphy_variant sun50i_a100_mipi_dphy_variant = {
.tx_power_on = sun50i_a100_mipi_dphy_tx_power_on,
+ .lvds_power_on = sun50i_a100_mipi_dphy_lvds_power_on,
+ .is_combo_dphy = true,
};
static const struct of_device_id sun6i_dphy_of_table[] = {
--
2.25.1
Dear Kuba,
Thanks for your efforts.
On 11/16/25 2:47 PM, Kuba Szczodrzyński wrote:
> Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo
> MIPI DSI D-PHY" which is required when using single-link LVDS0.
>
> In this mode, the DSI peripheral is not used and the PHY is not
> configured for DSI. Instead, the COMBO_PHY_REGx registers are set to
> enable LVDS operation.
>
> Enable the PHY driver to work in LVDS mode on chips with a combo D-PHY.
>
> Also change the SUN50I_COMBO_PHY_REG1 macro names to reflect the correct
> register name.
>
> Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
> ---
> drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++++-
> 1 file changed, 68 insertions(+), 2 deletions(-)
I tried integrating your changes in A133 display pipeline and I couldn't get the LVDS working.
Am still narrowing down what is missing in your patch. Driver registration is success and I
can see /dev/fb0 as well. But nothing on the display itself.
But with below changes from my patch,
diff --git a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
index 36eab95271b2..d164b2ea5dfd 100644
--- a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
+++ b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
@@ -314,13 +314,11 @@ static void sun50i_a100_mipi_dphy_tx_power_on(struct sun6i_dphy *dphy)
/* Disable sigma-delta modulation. */
regmap_write(dphy->regs, SUN50I_DPHY_PLL_REG2, 0);
- regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA4_REG,
- SUN6I_DPHY_ANA4_REG_EN_MIPI,
- SUN6I_DPHY_ANA4_REG_EN_MIPI);
-
regmap_update_bits(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_LVDS |
SUN50I_COMBO_PHY_REG0_EN_MIPI |
SUN50I_COMBO_PHY_REG0_EN_COMBOLDO,
+ SUN50I_COMBO_PHY_REG0_EN_LVDS |
SUN50I_COMBO_PHY_REG0_EN_MIPI |
SUN50I_COMBO_PHY_REG0_EN_COMBOLDO);
@@ -528,6 +526,22 @@ static int sun6i_dphy_exit(struct phy *phy)
return 0;
}
LVDS works fine.
Could you please share the diff of your dts / dtsi?
Thanks,
Parthiban
W dniu 2025-11-20 o 07:24:53, Parthiban pisze:
> Dear Kuba,
>
> Thanks for your efforts.
>
> On 11/16/25 2:47 PM, Kuba Szczodrzyński wrote:
>> Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo
>> MIPI DSI D-PHY" which is required when using single-link LVDS0.
>>
>> In this mode, the DSI peripheral is not used and the PHY is not
>> configured for DSI. Instead, the COMBO_PHY_REGx registers are set to
>> enable LVDS operation.
>>
>> Enable the PHY driver to work in LVDS mode on chips with a combo D-PHY.
>>
>> Also change the SUN50I_COMBO_PHY_REG1 macro names to reflect the correct
>> register name.
>>
>> Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
>> ---
>> drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++++-
>> 1 file changed, 68 insertions(+), 2 deletions(-)
> I tried integrating your changes in A133 display pipeline and I couldn't get the LVDS working.
> Am still narrowing down what is missing in your patch. Driver registration is success and I
> can see /dev/fb0 as well. But nothing on the display itself.
>
> But with below changes from my patch,
>
> diff --git a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
> index 36eab95271b2..d164b2ea5dfd 100644
> --- a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
> +++ b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
> @@ -314,13 +314,11 @@ static void sun50i_a100_mipi_dphy_tx_power_on(struct sun6i_dphy *dphy)
> /* Disable sigma-delta modulation. */
> regmap_write(dphy->regs, SUN50I_DPHY_PLL_REG2, 0);
>
> - regmap_update_bits(dphy->regs, SUN6I_DPHY_ANA4_REG,
> - SUN6I_DPHY_ANA4_REG_EN_MIPI,
> - SUN6I_DPHY_ANA4_REG_EN_MIPI);
> -
> regmap_update_bits(dphy->regs, SUN50I_COMBO_PHY_REG0,
> + SUN50I_COMBO_PHY_REG0_EN_LVDS |
> SUN50I_COMBO_PHY_REG0_EN_MIPI |
> SUN50I_COMBO_PHY_REG0_EN_COMBOLDO,
> + SUN50I_COMBO_PHY_REG0_EN_LVDS |
> SUN50I_COMBO_PHY_REG0_EN_MIPI |
> SUN50I_COMBO_PHY_REG0_EN_COMBOLDO);
>
> @@ -528,6 +526,22 @@ static int sun6i_dphy_exit(struct phy *phy)
> return 0;
> }
>
> LVDS works fine.
>
> Could you please share the diff of your dts / dtsi?
Hi,
Here's the DTS overlay I used to enable an LVDS panel on T113. You'll need to adapt the panel specification to your particular display.
I did not need to change the phy driver, so this extra requirement might be specific to A133.
/dts-v1/;
/plugin/;
&{/} {
panel {
compatible = "panel-lvds";
data-mapping = "jeida-18";
ddc-i2c-bus = <&i2c2>;
port {
panel_input: endpoint {
remote-endpoint = <&tcon_lcd0_out_lvds>;
};
};
};
};
&tcon_lcd0 {
pinctrl-names = "default";
pinctrl-0 = <&lcd_lvds0_pins>;
};
&tcon_lcd0_out {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
tcon_lcd0_out_lvds: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_input>;
};
};
Regards
Kuba
>
> Thanks,
> Parthiban
On Allwinner chips with a combo D-PHY, the TCON LCD0 should fetch it
from device tree in order to enable LVDS. Since the PHY also needs to
be powered off to disable LVDS, add a function to the quirks.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 12 ++++++++++++
drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 960e83c82..247400785 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
@@ -183,6 +184,8 @@ static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
} else {
regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
SUN4I_TCON0_LVDS_IF_EN, 0);
+ if (tcon->quirks->teardown_lvds_phy)
+ tcon->quirks->teardown_lvds_phy(tcon, encoder);
}
}
@@ -1245,6 +1248,15 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
goto err_free_dclk;
}
+ if (tcon->quirks->has_combo_dphy) {
+ tcon->dphy = devm_phy_get(dev, "combo-phy");
+ if (IS_ERR(tcon->dphy)) {
+ dev_err(dev, "Couldn't get the combo D-PHY\n");
+ ret = PTR_ERR(tcon->dphy);
+ goto err_free_dclk;
+ }
+ }
+
if (tcon->quirks->has_channel_0) {
/*
* If we have an LVDS panel connected to the TCON, we should
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index fa23aa23f..82b65a2e6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -239,6 +239,7 @@ struct sun4i_tcon_quirks {
bool has_channel_0; /* a83t does not have channel 0 on second TCON */
bool has_channel_1; /* a33 does not have channel 1 */
bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */
+ bool has_combo_dphy; /* Is the D-PHY used for LVDS output? */
bool needs_de_be_mux; /* sun6i needs mux to select backend */
bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */
bool supports_lvds; /* Does the TCON support an LVDS output? */
@@ -250,6 +251,8 @@ struct sun4i_tcon_quirks {
/* handler for LVDS setup routine */
void (*setup_lvds_phy)(struct sun4i_tcon *tcon,
const struct drm_encoder *encoder);
+ void (*teardown_lvds_phy)(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder);
};
struct sun4i_tcon {
@@ -282,6 +285,9 @@ struct sun4i_tcon {
/* Associated crtc */
struct sun4i_crtc *crtc;
+ /* Associated D-PHY */
+ struct phy *dphy;
+
int id;
/* TCON list management */
--
2.25.1
The Allwinner D1s/T113 needs to use the combo D-PHY to enable LVDS
output.
Enable LVDS support in the TCON and configure it using the PHY.
Abort PHY setup/teardown early if it fails.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 38 ++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 247400785..e072ecc6d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -171,6 +171,40 @@ static void sun6i_tcon_setup_lvds_phy(struct sun4i_tcon *tcon,
SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
}
+static void sun20i_tcon_setup_lvds_dphy(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder)
+{
+ union phy_configure_opts opts = { };
+
+ if (!tcon->quirks->has_combo_dphy || !tcon->dphy)
+ return;
+
+ if (phy_init(tcon->dphy))
+ return;
+
+ if (phy_set_mode(tcon->dphy, PHY_MODE_LVDS))
+ return;
+
+ if (phy_configure(tcon->dphy, &opts))
+ return;
+
+ if (phy_power_on(tcon->dphy))
+ return;
+}
+
+static void sun20i_tcon_teardown_lvds_dphy(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder)
+{
+ if (!tcon->quirks->has_combo_dphy || !tcon->dphy)
+ return;
+
+ if (phy_power_off(tcon->dphy))
+ return;
+
+ if (phy_exit(tcon->dphy))
+ return;
+}
+
static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
const struct drm_encoder *encoder,
bool enabled)
@@ -1550,8 +1584,12 @@ static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = {
static const struct sun4i_tcon_quirks sun20i_d1_lcd_quirks = {
.has_channel_0 = true,
+ .has_combo_dphy = true,
+ .supports_lvds = true,
.dclk_min_div = 1,
.set_mux = sun8i_r40_tcon_tv_set_mux,
+ .setup_lvds_phy = sun20i_tcon_setup_lvds_dphy,
+ .teardown_lvds_phy = sun20i_tcon_teardown_lvds_dphy,
};
/* sun4i_drv uses this list to check if a device node is a TCON */
--
2.25.1
The sun4i TCON needs a reference to the D-PHY in order to support LVDS
on Allwinner D1s/T113.
Add phys and phy-names to DT bindings.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
.../bindings/display/allwinner,sun4i-a10-tcon.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
index 724d93b91..52589341f 100644
--- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
+++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
@@ -115,6 +115,12 @@ properties:
- const: edp
- const: lvds
+ phys:
+ maxItems: 1
+
+ phy-names:
+ const: combo-phy
+
ports:
$ref: /schemas/graph.yaml#/properties/ports
--
2.25.1
On Sun, Nov 16, 2025 at 02:49:43PM +0100, Kuba Szczodrzyński wrote: > The sun4i TCON needs a reference to the D-PHY in order to support LVDS > on Allwinner D1s/T113. > > Add phys and phy-names to DT bindings. Do not attach (thread) your patchsets to some other threads (unrelated or older versions). This buries them deep in the mailbox and might interfere with applying entire sets. See also: https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830 > > Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl> > --- > .../bindings/display/allwinner,sun4i-a10-tcon.yaml | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml > index 724d93b91..52589341f 100644 > --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml > +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml > @@ -115,6 +115,12 @@ properties: > - const: edp > - const: lvds > > + phys: > + maxItems: 1 > + > + phy-names: > + const: combo-phy Drop phy suffix. Can a "phy" property hold reference to something else than phy? You don't need names in the first place, you have only one entry. Best regards, Krzysztof
W dniu 2025-11-17 o 08:05:33, Krzysztof Kozlowski pisze: > On Sun, Nov 16, 2025 at 02:49:43PM +0100, Kuba Szczodrzyński wrote: >> The sun4i TCON needs a reference to the D-PHY in order to support LVDS >> on Allwinner D1s/T113. >> >> Add phys and phy-names to DT bindings. > Do not attach (thread) your patchsets to some other threads (unrelated > or older versions). This buries them deep in the mailbox and might > interfere with applying entire sets. See also: > https://elixir.bootlin.com/linux/v6.16-rc2/source/Documentation/process/submitting-patches.rst#L830 I'll resend v4 as a new patchset. > >> Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl> >> --- >> .../bindings/display/allwinner,sun4i-a10-tcon.yaml | 6 ++++++ >> 1 file changed, 6 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml >> index 724d93b91..52589341f 100644 >> --- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml >> +++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml >> @@ -115,6 +115,12 @@ properties: >> - const: edp >> - const: lvds >> >> + phys: >> + maxItems: 1 >> + >> + phy-names: >> + const: combo-phy > Drop phy suffix. Can a "phy" property hold reference to something else > than phy? Will do. > You don't need names in the first place, you have only one > entry. However, phy-names was added because of how other bindings are made, such as "allwinner,sun4i-a10-musb" (single phy entry with const name). So I think it makes sense to keep it, in line with other drivers. Regards Kuba > > Best regards, > Krzysztof >
On 17/11/2025 12:08, Kuba Szczodrzyński wrote: > Will do. > >> You don't need names in the first place, you have only one >> entry. > > However, phy-names was added because of how other bindings are made, such as "allwinner,sun4i-a10-musb" (single phy entry with const name). It looks like USB binding, not a display one, so not really applicable argument. Do existing display drivers using this binding rely on names of phy or not? Best regards, Krzysztof
W dniu 2025-11-17 o 12:53:41, Krzysztof Kozlowski pisze: > On 17/11/2025 12:08, Kuba Szczodrzyński wrote: >> Will do. >> >>> You don't need names in the first place, you have only one >>> entry. >> However, phy-names was added because of how other bindings are made, such as "allwinner,sun4i-a10-musb" (single phy entry with const name). > > It looks like USB binding, not a display one, so not really applicable > argument. Do existing display drivers using this binding rely on names > of phy or not? Actually, existing display bindings that use PHY rely on their names. See: allwinner,sun6i-a31-mipi-dsi, allwinner,sun8i-a83t-dw-hdmi, as well as some bindings for different SoCs. > Best regards, > Krzysztof
The sun4i TCON needs a reference to the D-PHY in order to support LVDS
on Allwinner D1s/T113.
Add phys and phy-names to sunxi-d1s-t113 common device tree.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi b/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
index 63e252b44..78aa61607 100644
--- a/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
@@ -876,6 +876,8 @@ tcon_lcd0: lcd-controller@5461000 {
resets = <&ccu RST_BUS_TCON_LCD0>,
<&ccu RST_BUS_LVDS0>;
reset-names = "lcd", "lvds";
+ phys = <&dphy>;
+ phy-names = "combo-phy";
#clock-cells = <0>;
ports {
--
2.25.1
Add LVDS pins to the PIO since it's now supported on D1s/T113.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi b/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
index 78aa61607..c4ce809be 100644
--- a/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
+++ b/arch/riscv/boot/dts/allwinner/sunxi-d1s-t113.dtsi
@@ -108,6 +108,15 @@ i2s1_dout0_pin: i2s1-dout0-pin {
function = "i2s1_dout";
};
+ /omit-if-no-ref/
+ lcd_lvds0_pins: lcd-lvds0-pins {
+ pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5",
+ "PD6", "PD7", "PD8", "PD9";
+ function = "lvds0";
+ drive-strength = <30>;
+ bias-disable;
+ };
+
/omit-if-no-ref/
lcd_rgb666_pins: lcd-rgb666-pins {
pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5",
--
2.25.1
Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo MIPI DSI D-PHY" which is required when using single-link LVDS0. The same PD0..PD9 pins are used for either DSI or LVDS. Other than having to use the combo D-PHY, LVDS output is configured in the same way as on older chips. This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It is then configured by the LCD TCON, which allows connecting a single-link LVDS display panel. Changes in v2: - Applied code formatting changes from review comments - Changed "dphy" to "combo-phy" - Made the LVDS setup/teardown functions abort early in case of error (adding a proper return value would require changes in several levels of caller functions; perhaps could be done in a separate patch) - Added the PHY properties to DT bindings - Renamed lvds0_pins to lcd_lvds0_pins - Rebased on top of drm/misc/kernel/for-linux-next Kuba Szczodrzyński (6): phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY drm/sun4i: Support LVDS using MIPI DSI combo D-PHY drm/sun4i: Enable LVDS output on sun20i D1s/T113 dt-bindings: display: sun4i: Add D1s/T113 combo D-PHY bindings riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 riscv: dts: allwinner: d1s-t113: Add LVDS0 pins .../display/allwinner,sun4i-a10-tcon.yaml | 6 ++ .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 11 +++ drivers/gpu/drm/sun4i/sun4i_tcon.c | 50 +++++++++++++ drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++- 5 files changed, 141 insertions(+), 2 deletions(-) -- 2.25.1
Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo
MIPI DSI D-PHY" which is required when using single-link LVDS0.
In this mode, the DSI peripheral is not used and the PHY is not
configured for DSI. Instead, the COMBO_PHY_REGx registers are set to
enable LVDS operation.
Enable the PHY driver to work in LVDS mode on chips with a combo D-PHY.
Also change the SUN50I_COMBO_PHY_REG1 macro names to reflect the correct
register name.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 70 ++++++++++++++++++++-
1 file changed, 68 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
index 36eab9527..57035b3a4 100644
--- a/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
+++ b/drivers/phy/allwinner/phy-sun6i-mipi-dphy.c
@@ -166,8 +166,8 @@
#define SUN50I_COMBO_PHY_REG0_EN_CP BIT(0)
#define SUN50I_COMBO_PHY_REG1 0x114
-#define SUN50I_COMBO_PHY_REG2_REG_VREF1P6(n) (((n) & 0x7) << 4)
-#define SUN50I_COMBO_PHY_REG2_REG_VREF0P8(n) ((n) & 0x7)
+#define SUN50I_COMBO_PHY_REG1_REG_VREF1P6(n) (((n) & 0x7) << 4)
+#define SUN50I_COMBO_PHY_REG1_REG_VREF0P8(n) ((n) & 0x7)
#define SUN50I_COMBO_PHY_REG2 0x118
#define SUN50I_COMBO_PHY_REG2_HS_STOP_DLY(n) ((n) & 0xff)
@@ -181,7 +181,9 @@ struct sun6i_dphy;
struct sun6i_dphy_variant {
void (*tx_power_on)(struct sun6i_dphy *dphy);
+ void (*lvds_power_on)(struct sun6i_dphy *dphy);
bool rx_supported;
+ bool is_combo_dphy;
};
struct sun6i_dphy {
@@ -222,6 +224,18 @@ static int sun6i_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
return 0;
}
+static int sun6i_dphy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+ struct sun6i_dphy *dphy = phy_get_drvdata(phy);
+
+ if (mode == PHY_MODE_LVDS && !dphy->variant->is_combo_dphy) {
+ /* Not a combo D-PHY: LVDS is not supported. */
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static void sun6i_a31_mipi_dphy_tx_power_on(struct sun6i_dphy *dphy)
{
u8 lanes_mask = GENMASK(dphy->config.lanes - 1, 0);
@@ -329,6 +343,43 @@ static void sun50i_a100_mipi_dphy_tx_power_on(struct sun6i_dphy *dphy)
udelay(1);
}
+static void sun50i_a100_mipi_dphy_lvds_power_on(struct sun6i_dphy *dphy)
+{
+ regmap_write(dphy->regs, SUN50I_COMBO_PHY_REG1,
+ SUN50I_COMBO_PHY_REG1_REG_VREF1P6(4) |
+ SUN50I_COMBO_PHY_REG1_REG_VREF0P8(3));
+
+ regmap_write(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_CP);
+ udelay(5);
+
+ regmap_update_bits(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_LVDS,
+ SUN50I_COMBO_PHY_REG0_EN_LVDS);
+ udelay(5);
+
+ regmap_update_bits(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_COMBOLDO,
+ SUN50I_COMBO_PHY_REG0_EN_COMBOLDO);
+ udelay(5);
+
+ regmap_update_bits(dphy->regs, SUN50I_COMBO_PHY_REG0,
+ SUN50I_COMBO_PHY_REG0_EN_MIPI,
+ SUN50I_COMBO_PHY_REG0_EN_MIPI);
+
+ regmap_write(dphy->regs, SUN6I_DPHY_ANA4_REG,
+ SUN6I_DPHY_ANA4_REG_EN_MIPI |
+ SUN6I_DPHY_ANA4_REG_IB(2));
+
+ regmap_write(dphy->regs, SUN6I_DPHY_ANA3_REG,
+ SUN6I_DPHY_ANA3_EN_LDOR |
+ SUN6I_DPHY_ANA3_EN_LDOD);
+
+ regmap_write(dphy->regs, SUN6I_DPHY_ANA2_REG, 0);
+
+ regmap_write(dphy->regs, SUN6I_DPHY_ANA1_REG, 0);
+}
+
static int sun6i_dphy_tx_power_on(struct sun6i_dphy *dphy)
{
u8 lanes_mask = GENMASK(dphy->config.lanes - 1, 0);
@@ -492,6 +543,13 @@ static int sun6i_dphy_power_on(struct phy *phy)
{
struct sun6i_dphy *dphy = phy_get_drvdata(phy);
+ if (phy->attrs.mode == PHY_MODE_LVDS && dphy->variant->is_combo_dphy) {
+ if (!dphy->variant->lvds_power_on)
+ return -EINVAL;
+ dphy->variant->lvds_power_on(dphy);
+ return 0;
+ }
+
switch (dphy->direction) {
case SUN6I_DPHY_DIRECTION_TX:
return sun6i_dphy_tx_power_on(dphy);
@@ -514,6 +572,11 @@ static int sun6i_dphy_power_off(struct phy *phy)
regmap_write(dphy->regs, SUN6I_DPHY_ANA3_REG, 0);
regmap_write(dphy->regs, SUN6I_DPHY_ANA4_REG, 0);
+ if (phy->attrs.mode == PHY_MODE_LVDS && dphy->variant->is_combo_dphy) {
+ regmap_write(dphy->regs, SUN50I_COMBO_PHY_REG1, 0);
+ regmap_write(dphy->regs, SUN50I_COMBO_PHY_REG0, 0);
+ }
+
return 0;
}
@@ -533,6 +596,7 @@ static const struct phy_ops sun6i_dphy_ops = {
.configure = sun6i_dphy_configure,
.power_on = sun6i_dphy_power_on,
.power_off = sun6i_dphy_power_off,
+ .set_mode = sun6i_dphy_set_mode,
.init = sun6i_dphy_init,
.exit = sun6i_dphy_exit,
};
@@ -619,6 +683,8 @@ static const struct sun6i_dphy_variant sun6i_a31_mipi_dphy_variant = {
static const struct sun6i_dphy_variant sun50i_a100_mipi_dphy_variant = {
.tx_power_on = sun50i_a100_mipi_dphy_tx_power_on,
+ .lvds_power_on = sun50i_a100_mipi_dphy_lvds_power_on,
+ .is_combo_dphy = true,
};
static const struct of_device_id sun6i_dphy_of_table[] = {
--
2.25.1
On Allwinner chips with a combo D-PHY, the TCON LCD0 should fetch it
from device tree in order to enable LVDS. Since the PHY also needs to
be powered off to disable LVDS, add a function to the quirks.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 12 ++++++++++++
drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 960e83c82..247400785 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
@@ -183,6 +184,8 @@ static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
} else {
regmap_update_bits(tcon->regs, SUN4I_TCON0_LVDS_IF_REG,
SUN4I_TCON0_LVDS_IF_EN, 0);
+ if (tcon->quirks->teardown_lvds_phy)
+ tcon->quirks->teardown_lvds_phy(tcon, encoder);
}
}
@@ -1245,6 +1248,15 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
goto err_free_dclk;
}
+ if (tcon->quirks->has_combo_dphy) {
+ tcon->dphy = devm_phy_get(dev, "combo-phy");
+ if (IS_ERR(tcon->dphy)) {
+ dev_err(dev, "Couldn't get the combo D-PHY\n");
+ ret = PTR_ERR(tcon->dphy);
+ goto err_free_dclk;
+ }
+ }
+
if (tcon->quirks->has_channel_0) {
/*
* If we have an LVDS panel connected to the TCON, we should
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index fa23aa23f..82b65a2e6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -239,6 +239,7 @@ struct sun4i_tcon_quirks {
bool has_channel_0; /* a83t does not have channel 0 on second TCON */
bool has_channel_1; /* a33 does not have channel 1 */
bool has_lvds_alt; /* Does the LVDS clock have a parent other than the TCON clock? */
+ bool has_combo_dphy; /* Is the D-PHY used for LVDS output? */
bool needs_de_be_mux; /* sun6i needs mux to select backend */
bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */
bool supports_lvds; /* Does the TCON support an LVDS output? */
@@ -250,6 +251,8 @@ struct sun4i_tcon_quirks {
/* handler for LVDS setup routine */
void (*setup_lvds_phy)(struct sun4i_tcon *tcon,
const struct drm_encoder *encoder);
+ void (*teardown_lvds_phy)(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder);
};
struct sun4i_tcon {
@@ -282,6 +285,9 @@ struct sun4i_tcon {
/* Associated crtc */
struct sun4i_crtc *crtc;
+ /* Associated D-PHY */
+ struct phy *dphy;
+
int id;
/* TCON list management */
--
2.25.1
The Allwinner D1s/T113 needs to use the combo D-PHY to enable LVDS
output.
Enable LVDS support in the TCON and configure it using the PHY.
Abort PHY setup/teardown early if it fails.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
drivers/gpu/drm/sun4i/sun4i_tcon.c | 38 ++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 247400785..e072ecc6d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -171,6 +171,40 @@ static void sun6i_tcon_setup_lvds_phy(struct sun4i_tcon *tcon,
SUN6I_TCON0_LVDS_ANA0_EN_DRVD(val));
}
+static void sun20i_tcon_setup_lvds_dphy(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder)
+{
+ union phy_configure_opts opts = { };
+
+ if (!tcon->quirks->has_combo_dphy || !tcon->dphy)
+ return;
+
+ if (phy_init(tcon->dphy))
+ return;
+
+ if (phy_set_mode(tcon->dphy, PHY_MODE_LVDS))
+ return;
+
+ if (phy_configure(tcon->dphy, &opts))
+ return;
+
+ if (phy_power_on(tcon->dphy))
+ return;
+}
+
+static void sun20i_tcon_teardown_lvds_dphy(struct sun4i_tcon *tcon,
+ const struct drm_encoder *encoder)
+{
+ if (!tcon->quirks->has_combo_dphy || !tcon->dphy)
+ return;
+
+ if (phy_power_off(tcon->dphy))
+ return;
+
+ if (phy_exit(tcon->dphy))
+ return;
+}
+
static void sun4i_tcon_lvds_set_status(struct sun4i_tcon *tcon,
const struct drm_encoder *encoder,
bool enabled)
@@ -1550,8 +1584,12 @@ static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = {
static const struct sun4i_tcon_quirks sun20i_d1_lcd_quirks = {
.has_channel_0 = true,
+ .has_combo_dphy = true,
+ .supports_lvds = true,
.dclk_min_div = 1,
.set_mux = sun8i_r40_tcon_tv_set_mux,
+ .setup_lvds_phy = sun20i_tcon_setup_lvds_dphy,
+ .teardown_lvds_phy = sun20i_tcon_teardown_lvds_dphy,
};
/* sun4i_drv uses this list to check if a device node is a TCON */
--
2.25.1
The sun4i TCON needs a reference to the D-PHY in order to support LVDS
on Allwinner D1s/T113.
Add phys and phy-names to DT bindings.
Signed-off-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
---
.../bindings/display/allwinner,sun4i-a10-tcon.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
index 724d93b91..52589341f 100644
--- a/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
+++ b/Documentation/devicetree/bindings/display/allwinner,sun4i-a10-tcon.yaml
@@ -115,6 +115,12 @@ properties:
- const: edp
- const: lvds
+ phys:
+ maxItems: 1
+
+ phy-names:
+ const: combo-phy
+
ports:
$ref: /schemas/graph.yaml#/properties/ports
--
2.25.1
Dear Kuba, On 2/21/25 5:17 PM, Kuba Szczodrzyński wrote: > Some Allwinner chips (notably the D1s/T113 and the A100) have a "combo > MIPI DSI D-PHY" which is required when using single-link LVDS0. The same > PD0..PD9 pins are used for either DSI or LVDS. > > Other than having to use the combo D-PHY, LVDS output is configured in > the same way as on older chips. > > This series enables the sun6i MIPI D-PHY to also work in LVDS mode. It > is then configured by the LCD TCON, which allows connecting a > single-link LVDS display panel. Thanks for your efforts. For the A133 patch series [1] with display engine support, I have also tried addressing the Combo PHY, but your changes are more clean and also addressing the missing pieces in my series. Will you be able to address the comments for upstream and I can pick it for A133? If not, am happy to pull your changes in my tree with comments addressed and push for upstream if you are fine with it. [1]: https://lore.kernel.org/linux-sunxi/20241227-a133-display-support-v1-0-13b52f71fb14@linumiz.com/ Thanks, Parthiban > > Kuba Szczodrzyński (5): > phy: allwinner: phy-sun6i-mipi-dphy: Support LVDS in combo D-PHY > drm/sun4i: Support LVDS using MIPI DSI combo D-PHY > drm/sun4i: Enable LVDS output on sun20i D1s/T113 > riscv: dts: allwinner: d1s-t113: Add D-PHY to TCON LCD0 > riscv: dts: allwinner: d1s-t113: Add LVDS0 pins > > .../boot/dts/allwinner/sunxi-d1s-t113.dtsi | 10 +++ > drivers/gpu/drm/sun4i/sun4i_tcon.c | 40 ++++++++++++ > drivers/gpu/drm/sun4i/sun4i_tcon.h | 6 ++ > drivers/phy/allwinner/phy-sun6i-mipi-dphy.c | 65 ++++++++++++++++++- > 4 files changed, 119 insertions(+), 2 deletions(-) >
© 2016 - 2025 Red Hat, Inc.