[RFC PATCH] drm/panel: synaptics-r63353: Fix regulator unbalance

2024-06-24 Thread Michael Trimarchi
The shutdown function can be called when the display is already
unprepared. For example during reboot this trigger a kernel
backlog. Calling the drm_panel_unprepare, allow us to avoid
to trigger the kernel warning

Signed-off-by: Michael Trimarchi 
---

It's not obviovus if shutdown can be dropped or this problem depends
on the display stack as it is implmented. More feedback is required
here

---
 drivers/gpu/drm/panel/panel-synaptics-r63353.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-synaptics-r63353.c 
b/drivers/gpu/drm/panel/panel-synaptics-r63353.c
index 169c629746c7..17349825543f 100644
--- a/drivers/gpu/drm/panel/panel-synaptics-r63353.c
+++ b/drivers/gpu/drm/panel/panel-synaptics-r63353.c
@@ -325,7 +325,7 @@ static void r63353_panel_shutdown(struct mipi_dsi_device 
*dsi)
 {
struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi);
 
-   r63353_panel_unprepare(>base);
+   drm_panel_unprepare(>base);
 }
 
 static const struct r63353_desc sharp_ls068b3sx02_data = {
-- 
2.43.0



[RFC PATCH 4/4] drm/rockchip: rgb: Add dphy connection to rgb output

2022-10-02 Thread Michael Trimarchi
Dispite the commit 1f0f015151727, the rgb output has an option
to allow to sent the output pin using the dsi/lvds/ttl logic.
The only way to do and stay on the same design is let the
rockchip_rgb block to grab the handle if it is present and
enable it. The present of this handle depends on dts configuration

I have a full working example with an hardware with mixed lines
on direct logic and using the phy, with the follow dts example:

panel: panel {
compatible = "panel-dpi";
...
panel-timing {
clock-frequency = <3000>;
...
};

port {
panel_rgb_in: endpoint {
remote-endpoint = <_out_rgb>;
};
};
};

_out {
vopb_out_rgb: endpoint@2 {
reg = <2>;
remote-endpoint = <_rgb_in>;
};
};

 {
status = "okay";
pinctrl-names = "default", "sleep";
pinctrl-0 = <_rgb_pins>;
pinctrl-1 = <_sleep_pins>;

    phys = <_dphy>;
phy-names = "dphy";
};

Signed-off-by: Michael Trimarchi 
---
 drivers/gpu/drm/rockchip/rockchip_rgb.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c 
b/drivers/gpu/drm/rockchip/rockchip_rgb.c
index 75eb7cca3d82..c725774a0f40 100644
--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -30,6 +31,7 @@ struct rockchip_rgb {
struct drm_bridge *bridge;
struct drm_encoder encoder;
struct drm_connector connector;
+   struct phy *dphy;
int output_mode;
 };
 
@@ -168,6 +170,22 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
goto err_free_connector;
}
 
+   /* PHY */
+   rgb->dphy = devm_phy_get(dev, "dphy");
+   if (!IS_ERR(rgb->dphy)) {
+   ret = phy_init(rgb->dphy);
+   if (ret)
+   return ERR_PTR(ret);
+
+   ret = phy_set_mode(rgb->dphy, PHY_MODE_TTL);
+   if (ret)
+   return ERR_PTR(ret);
+
+   ret = phy_power_on(rgb->dphy);
+   if (ret)
+   return ERR_PTR(ret);
+   }
+
return rgb;
 
 err_free_connector:
-- 
2.34.1



[RFC PATCH 2/4] phy: rockchip: Add inno_is_valid_phy_mode

2022-10-02 Thread Michael Trimarchi
The function is used to avoid to enable clock on the hardware
if the mode requested is invalid

Signed-off-by: Michael Trimarchi 
---
 .../phy/rockchip/phy-rockchip-inno-dsidphy.c  | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c 
b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 630e01b5c19b..644cf73cfd53 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -217,6 +217,20 @@ static void phy_update_bits(struct inno_dsidphy *inno,
writel(tmp, inno->phy_base + reg);
 }
 
+static int inno_is_valid_phy_mode(struct inno_dsidphy *inno)
+{
+   switch (inno->mode) {
+   case PHY_MODE_MIPI_DPHY:
+   break;
+   case PHY_MODE_LVDS:
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   return 0;
+};
+
 static unsigned long inno_dsidphy_pll_calc_rate(struct inno_dsidphy *inno,
unsigned long rate)
 {
@@ -495,6 +509,11 @@ static void inno_dsidphy_lvds_mode_enable(struct 
inno_dsidphy *inno)
 static int inno_dsidphy_power_on(struct phy *phy)
 {
struct inno_dsidphy *inno = phy_get_drvdata(phy);
+   int ret = 0;
+
+   ret = inno_is_valid_phy_mode(inno);
+   if (ret)
+   return ret;
 
clk_prepare_enable(inno->pclk_phy);
clk_prepare_enable(inno->ref_clk);
-- 
2.34.1



[RFC PATCH 3/4] phy: rockchip: Implement TTY phy mode

2022-10-02 Thread Michael Trimarchi
The rockchip phy can be programmed in 3 modes:
- dsi
- lvds
- ttl

For instance in px30 there are two sets of rgb interface pins m0 and m1.
The logic can go outside from the VOP using m0 set or go outside using
the m1 set and the ttl logic enable. There are combination where a set
of pin can be taken from m1 and m0 where all the two path are enabled.

dsi and ttl enable share one register in their register area. Simple
implementation is overlap the area where we want access the register

Signed-off-by: Michael Trimarchi 
---
 .../phy/rockchip/phy-rockchip-inno-dsidphy.c  | 53 +++
 1 file changed, 53 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c 
b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 644cf73cfd53..0af50d2e0402 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -217,6 +217,17 @@ static void phy_update_bits(struct inno_dsidphy *inno,
writel(tmp, inno->phy_base + reg);
 }
 
+static void host_update_bits(struct inno_dsidphy *inno,
+u32 reg, u32 mask, u32 val)
+{
+   unsigned int tmp, orig;
+
+   orig = readl(inno->host_base + reg);
+   tmp = orig & ~mask;
+   tmp |= val & mask;
+   writel(tmp, inno->host_base + reg);
+}
+
 static int inno_is_valid_phy_mode(struct inno_dsidphy *inno)
 {
switch (inno->mode) {
@@ -224,6 +235,10 @@ static int inno_is_valid_phy_mode(struct inno_dsidphy 
*inno)
break;
case PHY_MODE_LVDS:
break;
+   case PHY_MODE_TTL:
+   if (IS_ERR(inno->host_base))
+   return -EINVAL;
+   break;
default:
return -EINVAL;
}
@@ -506,6 +521,32 @@ static void inno_dsidphy_lvds_mode_enable(struct 
inno_dsidphy *inno)
LVDS_DATA_LANE2_EN | LVDS_DATA_LANE3_EN);
 }
 
+static void inno_dsidphy_ttl_mode_enable(struct inno_dsidphy *inno)
+{
+   /* Select TTL mode */
+   phy_update_bits(inno, REGISTER_PART_LVDS, 0x03,
+   MODE_ENABLE_MASK, TTL_MODE_ENABLE);
+   /* Reset digital logic */
+   phy_update_bits(inno, REGISTER_PART_LVDS, 0x00,
+   LVDS_DIGITAL_INTERNAL_RESET_MASK,
+   LVDS_DIGITAL_INTERNAL_RESET_ENABLE);
+   udelay(1);
+   phy_update_bits(inno, REGISTER_PART_LVDS, 0x00,
+   LVDS_DIGITAL_INTERNAL_RESET_MASK,
+   LVDS_DIGITAL_INTERNAL_RESET_DISABLE);
+   /* Enable digital logic */
+   phy_update_bits(inno, REGISTER_PART_LVDS, 0x01,
+   LVDS_DIGITAL_INTERNAL_ENABLE_MASK,
+   LVDS_DIGITAL_INTERNAL_ENABLE);
+   /* Enable analog driver */
+   phy_update_bits(inno, REGISTER_PART_LVDS, 0x0b,
+   LVDS_LANE_EN_MASK, LVDS_CLK_LANE_EN |
+   LVDS_DATA_LANE0_EN | LVDS_DATA_LANE1_EN |
+   LVDS_DATA_LANE2_EN | LVDS_DATA_LANE3_EN);
+   /* Enable for clk lane in TTL mode */
+   host_update_bits(inno, DSI_PHY_RSTZ, PHY_ENABLECLK, PHY_ENABLECLK);
+}
+
 static int inno_dsidphy_power_on(struct phy *phy)
 {
struct inno_dsidphy *inno = phy_get_drvdata(phy);
@@ -533,6 +574,9 @@ static int inno_dsidphy_power_on(struct phy *phy)
case PHY_MODE_LVDS:
inno_dsidphy_lvds_mode_enable(inno);
break;
+   case PHY_MODE_TTL:
+   inno_dsidphy_ttl_mode_enable(inno);
+   break;
default:
return -EINVAL;
}
@@ -561,6 +605,10 @@ static int inno_dsidphy_power_off(struct phy *phy)
LVDS_PLL_POWER_MASK | LVDS_BANDGAP_POWER_MASK,
LVDS_PLL_POWER_OFF | LVDS_BANDGAP_POWER_DOWN);
 
+   /* Disable for clk lane in TTL mode */
+   if (!IS_ERR(inno->host_base))
+   host_update_bits(inno, DSI_PHY_RSTZ, PHY_ENABLECLK, 0);
+
pm_runtime_put(inno->dev);
clk_disable_unprepare(inno->ref_clk);
clk_disable_unprepare(inno->pclk_phy);
@@ -576,6 +624,7 @@ static int inno_dsidphy_set_mode(struct phy *phy, enum 
phy_mode mode,
switch (mode) {
case PHY_MODE_MIPI_DPHY:
case PHY_MODE_LVDS:
+   case PHY_MODE_TTL:
inno->mode = mode;
break;
default:
@@ -630,6 +679,10 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
if (IS_ERR(inno->phy_base))
return PTR_ERR(inno->phy_base);
 
+   inno->host_base = devm_platform_ioremap_resource(pdev, 1);
+   if (IS_ERR(inno->host_base))
+   dev_warn(dev, "TTL mode is not supported\n");
+
inno->ref_clk = devm_clk_get(dev, "ref");
if (IS_ERR(inno->ref_clk)) {
ret = PTR_ERR(inno->ref_clk);
-- 
2.34.1



[RFC PATCH 1/4] phy: add PHY_MODE_TTL

2022-10-02 Thread Michael Trimarchi
There are combo phys out there that can be switched between doing
dsi, lvds, and ttl. So add a mode definition for it.

Signed-off-by: Michael Trimarchi 
---
 include/linux/phy/phy.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index b1413757fcc3..87ae8c27ec57 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -42,7 +42,8 @@ enum phy_mode {
PHY_MODE_MIPI_DPHY,
PHY_MODE_SATA,
PHY_MODE_LVDS,
-   PHY_MODE_DP
+   PHY_MODE_DP,
+   PHY_MODE_TTL
 };
 
 enum phy_media {
-- 
2.34.1



[RFC PATCH 0/4] Add RGB ttl connection on rockchip phy

2022-10-02 Thread Michael Trimarchi
The rockchip phy can be convigured in ttl mode. The phy is shared
between lvds, dsi, ttl. The configuration that now I'm able to support
has the display output on some set of pins on standard vop output
and a set of pins using the ttl phy. The solution is not clean as I
would like to have because some register that are used to enable
the TTL, are in the same register area of the dsi controller.
In order to test I must add the following

dsi_dphy: phy@ff2e {

reg = <0x0 0xff2e 0x0 0x1>,
<0x0 0xff45 0x0 0x1>;
...
}

The problem here is the second region I have added is the same of
dsi logic. Only one register is needed by the the phy driver

Michael Trimarchi (4):
  phy: add PHY_MODE_TTL
  phy: rockchip: Add inno_is_valid_phy_mode
  phy: rockchip: Implement TTY phy mode
  drm/rockchip: rgb: Add dphy connection to rgb output

 drivers/gpu/drm/rockchip/rockchip_rgb.c   | 18 +
 .../phy/rockchip/phy-rockchip-inno-dsidphy.c  | 72 +++
 include/linux/phy/phy.h   |  3 +-
 3 files changed, 92 insertions(+), 1 deletion(-)

-- 
2.34.1



[RFC PATCH] drm/panel: Fix panel removal if mipi_dsi_attach fail

2021-12-06 Thread Michael Trimarchi
If mipi_dsi_attach fail the panel must be removed from panel list
because it get be probed back but later for -EPROBE_DEFER. A lot
of panels are affect on same issue, fix them all

Signed-off-by: Michael Trimarchi 
---
 drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c | 6 +-
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 6 +-
 drivers/gpu/drm/panel/panel-innolux-p079zca.c | 8 +++-
 drivers/gpu/drm/panel/panel-jdi-lt070me05000.c| 6 +-
 drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c| 6 +-
 drivers/gpu/drm/panel/panel-novatek-nt36672a.c| 6 +-
 drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c  | 6 +-
 drivers/gpu/drm/panel/panel-ronbo-rb070d30.c  | 6 +-
 drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c   | 6 +-
 drivers/gpu/drm/panel/panel-sitronix-st7701.c | 6 +-
 drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c  | 6 +-
 11 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c 
b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
index 581661b506f8..585f61cc42f0 100644
--- a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
+++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
@@ -227,7 +227,11 @@ static int feiyang_dsi_probe(struct mipi_dsi_device *dsi)
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->lanes = 4;
 
-   return mipi_dsi_attach(dsi);
+   ret = mipi_dsi_attach(dsi);
+   if (ret < 0)
+   drm_panel_remove(>panel);
+
+   return ret;
 }
 
 static int feiyang_dsi_remove(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
index 534dd7414d42..9dc6bafec3f3 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
@@ -674,7 +674,11 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi)
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->lanes = 4;
 
-   return mipi_dsi_attach(dsi);
+   ret = mipi_dsi_attach(dsi);
+   if (ret < 0)
+   drm_panel_remove(>panel);
+
+   return ret;
 }
 
 static int ili9881c_dsi_remove(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index aea316225391..d5abd792f12f 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
@@ -495,7 +495,13 @@ static int innolux_panel_probe(struct mipi_dsi_device *dsi)
if (err < 0)
return err;
 
-   return mipi_dsi_attach(dsi);
+   err = mipi_dsi_attach(dsi);
+   if (err < 0) {
+   struct innolux_panel *innolux = mipi_dsi_get_drvdata(dsi);
+   innolux_panel_del(innolux);
+   }
+
+   return err;
 }
 
 static int innolux_panel_remove(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c 
b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
index 733010b5e4f5..e52b0cc8e081 100644
--- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
+++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c
@@ -473,7 +473,11 @@ static int jdi_panel_probe(struct mipi_dsi_device *dsi)
if (ret < 0)
return ret;
 
-   return mipi_dsi_attach(dsi);
+   ret = mipi_dsi_attach(dsi);
+   if (ret < 0)
+   jdi_panel_del(jdi);
+
+   return ret;
 }
 
 static int jdi_panel_remove(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c 
b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
index 86e4213e8bb1..6e3cd6ea8bf9 100644
--- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
+++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
@@ -406,7 +406,11 @@ static int kingdisplay_panel_probe(struct mipi_dsi_device 
*dsi)
if (err < 0)
return err;
 
-   return mipi_dsi_attach(dsi);
+   err = mipi_dsi_attach(dsi);
+   if (err < 0)
+   drm_panel_remove(kingdisplay);
+
+   return err;
 }
 
 static int kingdisplay_panel_remove(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c 
b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
index 533cd3934b8b..ac7a003193c3 100644
--- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
+++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c
@@ -656,7 +656,11 @@ static int nt36672a_panel_probe(struct mipi_dsi_device 
*dsi)
if (err < 0)
return err;
 
-   return mipi_dsi_attach(dsi);
+   err = mipi_dsi_attach(dsi);
+   if (err < 0)
+   drm_panel_remove(>base);
+
+   return err;
 }
 
 static int nt36672a_panel_remove(struct mipi_dsi_device *dsi)
diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c 
b/drivers/gpu/drm/panel/panel-panasonic-vvx

[PATCH] drm/panel: ilitek-ili9881c: Avoid unbalance prepare/unprepare

2021-10-16 Thread Michael Trimarchi
All the panel driver check the fact that their prepare/unprepare
call was already called. It's not an ideal solution but fix
for now the problem on ili9881c

[ 9862.283296] [ cut here ]
[ 9862.288490] unbalanced disables for vcc3v3_lcd
[ 9862.293555] WARNING: CPU: 0 PID: 1 at drivers/regulator/core.c:2851
_regulator_disable+0xd4/0x190

from:

[ 9862.038619]  drm_panel_unprepare+0x2c/0x4c
[ 9862.043212]  panel_bridge_post_disable+0x18/0x24
[ 9862.048390]  dw_mipi_dsi_bridge_post_disable+0x3c/0xf0
[ 9862.054153]  drm_atomic_bridge_chain_post_disable+0x8c/0xd0

and:

[ 9862.183103]  drm_panel_unprepare+0x2c/0x4c
[ 9862.187695]  panel_bridge_post_disable+0x18/0x24
[ 9862.192872]  drm_atomic_bridge_chain_post_disable+0x8c/0xd0
[ 9862.199117]  disable_outputs+0x120/0x31c

Signed-off-by: Michael Trimarchi 
---
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
index 103a16018975..f75eecb0e65c 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
@@ -52,6 +52,8 @@ struct ili9881c {
 
struct regulator*power;
struct gpio_desc*reset;
+
+   boolprepared;
 };
 
 #define ILI9881C_SWITCH_PAGE_INSTR(_page)  \
@@ -707,6 +709,10 @@ static int ili9881c_prepare(struct drm_panel *panel)
unsigned int i;
int ret;
 
+   /* Preparing when already prepared is a no-op */
+   if (ctx->prepared)
+   return 0;
+
/* Power the panel */
ret = regulator_enable(ctx->power);
if (ret)
@@ -745,6 +751,8 @@ static int ili9881c_prepare(struct drm_panel *panel)
if (ret)
return ret;
 
+   ctx->prepared = true;
+
return 0;
 }
 
@@ -770,10 +778,16 @@ static int ili9881c_unprepare(struct drm_panel *panel)
 {
struct ili9881c *ctx = panel_to_ili9881c(panel);
 
+   /* Unpreparing when already unprepared is a no-op */
+   if (!ctx->prepared)
+   return 0;
+
mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);
regulator_disable(ctx->power);
gpiod_set_value(ctx->reset, 1);
 
+   ctx->prepared = false;
+
return 0;
 }
 
-- 
2.25.1



[PATCH 5/5] drm/bridge: dw-mipi-dsi: Fix dsi registration during drm probing

2021-10-16 Thread Michael Trimarchi
The dsi registration is implemented in rockchip platform driver.
The attach can be called before the probe is terminated and therefore
we need to be sure that corresponding entry during attach is valid

Signed-off-by: Michael Trimarchi 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c   |  8 +++-
 drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 12 
 include/drm/bridge/dw_mipi_dsi.h|  2 +-
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index e44e18a0112a..44b211be15fc 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -362,8 +362,14 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
dsi->device_found = true;
}
 
+   /*
+* NOTE: the dsi registration is implemented in
+* platform driver, that to say dsi would be exist after
+* probe is terminated. The call is done before the end of probe
+* so we need to pass the dsi to the platform driver.
+*/
if (pdata->host_ops && pdata->host_ops->attach) {
-   ret = pdata->host_ops->attach(pdata->priv_data, device);
+   ret = pdata->host_ops->attach(pdata->priv_data, device, dsi);
if (ret < 0)
return ret;
}
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index a2262bee5aa4..32ddc8642ec1 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -997,7 +997,8 @@ static const struct component_ops dw_mipi_dsi_rockchip_ops 
= {
 };
 
 static int dw_mipi_dsi_rockchip_host_attach(void *priv_data,
-   struct mipi_dsi_device *device)
+   struct mipi_dsi_device *device,
+   struct dw_mipi_dsi *dmd)
 {
struct dw_mipi_dsi_rockchip *dsi = priv_data;
struct device *second;
@@ -1005,6 +1006,8 @@ static int dw_mipi_dsi_rockchip_host_attach(void 
*priv_data,
 
mutex_lock(>usage_mutex);
 
+   dsi->dmd = dmd;
+
if (dsi->usage_mode != DW_DSI_USAGE_IDLE) {
DRM_DEV_ERROR(dsi->dev, "dsi controller already in use\n");
mutex_unlock(>usage_mutex);
@@ -1280,6 +1283,7 @@ static int dw_mipi_dsi_rockchip_probe(struct 
platform_device *pdev)
 {
struct device *dev = >dev;
struct device_node *np = dev->of_node;
+   struct dw_mipi_dsi *dmd;
struct dw_mipi_dsi_rockchip *dsi;
struct phy_provider *phy_provider;
struct resource *res;
@@ -1391,9 +1395,9 @@ static int dw_mipi_dsi_rockchip_probe(struct 
platform_device *pdev)
if (IS_ERR(phy_provider))
return PTR_ERR(phy_provider);
 
-   dsi->dmd = dw_mipi_dsi_probe(pdev, >pdata);
-   if (IS_ERR(dsi->dmd)) {
-   ret = PTR_ERR(dsi->dmd);
+   dmd = dw_mipi_dsi_probe(pdev, >pdata);
+   if (IS_ERR(dmd)) {
+   ret = PTR_ERR(dmd);
if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev,
  "Failed to probe dw_mipi_dsi: %d\n", ret);
diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h
index bda8aa7c2280..cf81f19806ad 100644
--- a/include/drm/bridge/dw_mipi_dsi.h
+++ b/include/drm/bridge/dw_mipi_dsi.h
@@ -41,7 +41,7 @@ struct dw_mipi_dsi_phy_ops {
 
 struct dw_mipi_dsi_host_ops {
int (*attach)(void *priv_data,
- struct mipi_dsi_device *dsi);
+ struct mipi_dsi_device *dsi, struct dw_mipi_dsi *dmd);
int (*detach)(void *priv_data,
  struct mipi_dsi_device *dsi);
 };
-- 
2.25.1



[PATCH 3/5] dt-bindings: ili9881c: add compatible string for Wanchanglong w552946aba

2021-10-16 Thread Michael Trimarchi
It utilizes an Ilitek ILI9881D controller chip, but its
compatible with ili9881c so should be added to ilitek,ili9881c file.

Add the compatible string for it.

Signed-off-by: Michael Trimarchi 
---
 .../devicetree/bindings/display/panel/ilitek,ili9881c.yaml   | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml 
b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
index b2fcec4f22fd..2d4a5643a785 100644
--- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
+++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
@@ -15,6 +15,7 @@ properties:
   - enum:
   - bananapi,lhr050h41
   - feixin,k101-im2byl02
+  - wanchanglong,w552946aba
   - const: ilitek,ili9881c
 
   backlight: true
-- 
2.25.1



[PATCH 4/5] drm/panel: ilitek-ili9881c: Make gpio-reset optional

2021-10-16 Thread Michael Trimarchi
Depends in how logic is connected to the board the gpio is
not stricly required.

Signed-off-by: Michael Trimarchi 
---
 .../devicetree/bindings/display/panel/ilitek,ili9881c.yaml  | 1 -
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c   | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml 
b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
index 2d4a5643a785..07789d554889 100644
--- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
+++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
@@ -27,7 +27,6 @@ required:
   - compatible
   - power-supply
   - reg
-  - reset-gpios
 
 additionalProperties: false
 
diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
index d1f20758ed08..103a16018975 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
@@ -883,7 +883,7 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi)
return PTR_ERR(ctx->power);
}
 
-   ctx->reset = devm_gpiod_get(>dev, "reset", GPIOD_OUT_LOW);
+   ctx->reset = devm_gpiod_get_optional(>dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(ctx->reset)) {
dev_err(>dev, "Couldn't get our reset GPIO\n");
return PTR_ERR(ctx->reset);
-- 
2.25.1



[PATCH 2/5] drm/panel: ilitek-ili9881d: add support for Wanchanglong W552946ABA panel

2021-10-16 Thread Michael Trimarchi
W552946ABA is a panel by Wanchanglong. This panel utilizes the Ilitek ILI9881D
controller.

Add this panel's initialzation sequence and timing to ILI9881D driver.
Tested on px30-evb v11

Signed-off-by: Michael Trimarchi 
---
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 238 +-
 1 file changed, 237 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
index 0145129d7c66..d1f20758ed08 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
@@ -42,6 +42,7 @@ struct ili9881c_desc {
const struct ili9881c_instr *init;
const size_t init_length;
const struct drm_display_mode *mode;
+   const unsigned long mode_flags;
 };
 
 struct ili9881c {
@@ -453,6 +454,213 @@ static const struct ili9881c_instr k101_im2byl02_init[] = 
{
ILI9881C_COMMAND_INSTR(0xD3, 0x3F), /* VN0 */
 };
 
+static const struct ili9881c_instr w552946ab_init[] = {
+   ILI9881C_SWITCH_PAGE_INSTR(3),
+   ILI9881C_COMMAND_INSTR(0x01, 0x00),
+   ILI9881C_COMMAND_INSTR(0x02, 0x00),
+   ILI9881C_COMMAND_INSTR(0x03, 0x53),
+   ILI9881C_COMMAND_INSTR(0x04, 0x53),
+   ILI9881C_COMMAND_INSTR(0x05, 0x13),
+   ILI9881C_COMMAND_INSTR(0x06, 0x04),
+   ILI9881C_COMMAND_INSTR(0x07, 0x02),
+   ILI9881C_COMMAND_INSTR(0x08, 0x02),
+   ILI9881C_COMMAND_INSTR(0x09, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0A, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0B, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0C, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0D, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0E, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0F, 0x00),
+
+   ILI9881C_COMMAND_INSTR(0x10, 0x00),
+   ILI9881C_COMMAND_INSTR(0x11, 0x00),
+   ILI9881C_COMMAND_INSTR(0x12, 0x00),
+   ILI9881C_COMMAND_INSTR(0x13, 0x00),
+   ILI9881C_COMMAND_INSTR(0x14, 0x00),
+   ILI9881C_COMMAND_INSTR(0x15, 0x08),
+   ILI9881C_COMMAND_INSTR(0x16, 0x10),
+   ILI9881C_COMMAND_INSTR(0x17, 0x00),
+   ILI9881C_COMMAND_INSTR(0x18, 0x08),
+   ILI9881C_COMMAND_INSTR(0x19, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1A, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1B, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1C, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1D, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1E, 0xC0),
+   ILI9881C_COMMAND_INSTR(0x1F, 0x80),
+
+   ILI9881C_COMMAND_INSTR(0x20, 0x02),
+   ILI9881C_COMMAND_INSTR(0x21, 0x09),
+   ILI9881C_COMMAND_INSTR(0x22, 0x00),
+   ILI9881C_COMMAND_INSTR(0x23, 0x00),
+   ILI9881C_COMMAND_INSTR(0x24, 0x00),
+   ILI9881C_COMMAND_INSTR(0x25, 0x00),
+   ILI9881C_COMMAND_INSTR(0x26, 0x00),
+   ILI9881C_COMMAND_INSTR(0x27, 0x00),
+   ILI9881C_COMMAND_INSTR(0x28, 0x55),
+   ILI9881C_COMMAND_INSTR(0x29, 0x03),
+   ILI9881C_COMMAND_INSTR(0x2A, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2B, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2C, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2D, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2E, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2F, 0x00),
+
+   ILI9881C_COMMAND_INSTR(0x30, 0x00),
+   ILI9881C_COMMAND_INSTR(0x31, 0x00),
+   ILI9881C_COMMAND_INSTR(0x32, 0x00),
+   ILI9881C_COMMAND_INSTR(0x33, 0x00),
+   ILI9881C_COMMAND_INSTR(0x34, 0x04),
+   ILI9881C_COMMAND_INSTR(0x35, 0x05),
+   ILI9881C_COMMAND_INSTR(0x36, 0x05),
+   ILI9881C_COMMAND_INSTR(0x37, 0x00),
+   ILI9881C_COMMAND_INSTR(0x38, 0x3C),
+   ILI9881C_COMMAND_INSTR(0x39, 0x35),
+   ILI9881C_COMMAND_INSTR(0x3A, 0x00),
+   ILI9881C_COMMAND_INSTR(0x3B, 0x40),
+   ILI9881C_COMMAND_INSTR(0x3C, 0x00),
+   ILI9881C_COMMAND_INSTR(0x3D, 0x00),
+   ILI9881C_COMMAND_INSTR(0x3E, 0x00),
+   ILI9881C_COMMAND_INSTR(0x3F, 0x00),
+
+   ILI9881C_COMMAND_INSTR(0x40, 0x00),
+   ILI9881C_COMMAND_INSTR(0x41, 0x88),
+   ILI9881C_COMMAND_INSTR(0x42, 0x00),
+   ILI9881C_COMMAND_INSTR(0x43, 0x00),
+   ILI9881C_COMMAND_INSTR(0x44, 0x1F),
+
+   ILI9881C_COMMAND_INSTR(0x50, 0x01),
+   ILI9881C_COMMAND_INSTR(0x51, 0x23),
+   ILI9881C_COMMAND_INSTR(0x52, 0x45),
+   ILI9881C_COMMAND_INSTR(0x53, 0x67),
+   ILI9881C_COMMAND_INSTR(0x54, 0x89),
+   ILI9881C_COMMAND_INSTR(0x55, 0xaB),
+   ILI9881C_COMMAND_INSTR(0x56, 0x01),
+   ILI9881C_COMMAND_INSTR(0x57, 0x23),
+   ILI9881C_COMMAND_INSTR(0x58, 0x45),
+   ILI9881C_COMMAND_INSTR(0x59, 0x67),
+   ILI9881C_COMMAND_INSTR(0x5A, 0x89),
+   ILI9881C_COMMAND_INSTR(0x5B, 0xAB),
+   ILI9881C_COMMAND_INSTR(0x5C, 0xCD),
+   ILI9881C_COMMAND_INSTR(0x5D, 0xEF),
+   ILI9881C_COMMAND_INSTR(0x5E, 0x03),
+   ILI9881C_COMMAND_INSTR(0x5F, 0x14),
+
+   ILI9881C_COMMAND_INSTR(0x60, 0x15),
+   ILI9881C_COMMAND_INSTR(0x61, 0x0C),
+   ILI9881C_COMMAND_INSTR(0x62, 0x0D),
+   ILI9881C_COMMAND_INSTR(0x63, 0x0E),
+   ILI9881C_COMMAND_INSTR(0x64, 0x0F

[PATCH 1/5] dt-bindings: vendor-prefix: add Wanchanglong Electronics Technology

2021-10-16 Thread Michael Trimarchi
Wanchanglong Electronics Technology is a company to provide LCD
modules.

Signed-off-by: Michael Trimarchi 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a867f7102c35..5c43391d8c3d 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1304,6 +1304,8 @@ patternProperties:
 description: Wondermedia Technologies, Inc.
   "^wobo,.*":
 description: Wobo
+  "^wanchanglong,.*":
+description: Wanchanglong Electronics Technology(SHENZHEN)Co.,Ltd.
   "^x-powers,.*":
 description: X-Powers
   "^xes,.*":
-- 
2.25.1



[PATCH 0/5] Add support for Wanchanglong panel used in px30-evb v11

2021-10-16 Thread Michael Trimarchi
This patch series add support for W552946ABA panel. This panel is used
in px30-evb v11. All the patches can be applied on top of drm-fixes
branch. The last patch is suppose to fix a race when the panel is built
in. Tested on px30 evb

Michael Trimarchi (5):
  dt-bindings: vendor-prefix: add Wanchanglong Electronics Technology
  drm/panel: ilitek-ili9881d: add support for Wanchanglong W552946ABA
panel
  dt-bindings: ili9881c: add compatible string for Wanchanglong
w552946aba
  drm/panel: ilitek-ili9881c: Make gpio-reset optional
  drm/bridge: dw-mipi-dsi: Fix dsi registration during drm probing

 .../display/panel/ilitek,ili9881c.yaml|   2 +-
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |   8 +-
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 240 +-
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   |  12 +-
 include/drm/bridge/dw_mipi_dsi.h  |   2 +-
 6 files changed, 257 insertions(+), 9 deletions(-)

-- 
2.25.1



[RFC PATCH] drm/panel: ilitek-ili9881d: add support for Wanchanglong W552946ABA panel

2021-10-14 Thread Michael Trimarchi
W552946ABA is a panel by Wanchanglong. This panel utilizes the Ilitek ILI9881D
controller.

Add this panel's initialzation sequence and timing to ILI9881D driver.
Tested on px30-evb v11

Signed-off-by: Michael Trimarchi 
---
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 238 +-
 1 file changed, 237 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c 
b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
index 0145129d7c66..cf53b43e0907 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
@@ -42,6 +42,7 @@ struct ili9881c_desc {
const struct ili9881c_instr *init;
const size_t init_length;
const struct drm_display_mode *mode;
+   const unsigned long mode_flags;
 };
 
 struct ili9881c {
@@ -453,6 +454,213 @@ static const struct ili9881c_instr k101_im2byl02_init[] = 
{
ILI9881C_COMMAND_INSTR(0xD3, 0x3F), /* VN0 */
 };
 
+static const struct ili9881c_instr w552946ab_init[] = {
+   ILI9881C_SWITCH_PAGE_INSTR(3),
+   ILI9881C_COMMAND_INSTR(0x01, 0x00),
+   ILI9881C_COMMAND_INSTR(0x02, 0x00),
+   ILI9881C_COMMAND_INSTR(0x03, 0x53),
+   ILI9881C_COMMAND_INSTR(0x04, 0x53),
+   ILI9881C_COMMAND_INSTR(0x05, 0x13),
+   ILI9881C_COMMAND_INSTR(0x06, 0x04),
+   ILI9881C_COMMAND_INSTR(0x07, 0x02),
+   ILI9881C_COMMAND_INSTR(0x08, 0x02),
+   ILI9881C_COMMAND_INSTR(0x09, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0A, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0B, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0C, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0D, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0E, 0x00),
+   ILI9881C_COMMAND_INSTR(0x0F, 0x00),
+
+   ILI9881C_COMMAND_INSTR(0x10, 0x00),
+   ILI9881C_COMMAND_INSTR(0x11, 0x00),
+   ILI9881C_COMMAND_INSTR(0x12, 0x00),
+   ILI9881C_COMMAND_INSTR(0x13, 0x00),
+   ILI9881C_COMMAND_INSTR(0x14, 0x00),
+   ILI9881C_COMMAND_INSTR(0x15, 0x08),
+   ILI9881C_COMMAND_INSTR(0x16, 0x10),
+   ILI9881C_COMMAND_INSTR(0x17, 0x00),
+   ILI9881C_COMMAND_INSTR(0x18, 0x08),
+   ILI9881C_COMMAND_INSTR(0x19, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1A, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1B, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1C, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1D, 0x00),
+   ILI9881C_COMMAND_INSTR(0x1E, 0xC0),
+   ILI9881C_COMMAND_INSTR(0x1F, 0x80),
+
+   ILI9881C_COMMAND_INSTR(0x20, 0x02),
+   ILI9881C_COMMAND_INSTR(0x21, 0x09),
+   ILI9881C_COMMAND_INSTR(0x22, 0x00),
+   ILI9881C_COMMAND_INSTR(0x23, 0x00),
+   ILI9881C_COMMAND_INSTR(0x24, 0x00),
+   ILI9881C_COMMAND_INSTR(0x25, 0x00),
+   ILI9881C_COMMAND_INSTR(0x26, 0x00),
+   ILI9881C_COMMAND_INSTR(0x27, 0x00),
+   ILI9881C_COMMAND_INSTR(0x28, 0x55),
+   ILI9881C_COMMAND_INSTR(0x29, 0x03),
+   ILI9881C_COMMAND_INSTR(0x2A, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2B, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2C, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2D, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2E, 0x00),
+   ILI9881C_COMMAND_INSTR(0x2F, 0x00),
+
+   ILI9881C_COMMAND_INSTR(0x30, 0x00),
+   ILI9881C_COMMAND_INSTR(0x31, 0x00),
+   ILI9881C_COMMAND_INSTR(0x32, 0x00),
+   ILI9881C_COMMAND_INSTR(0x33, 0x00),
+   ILI9881C_COMMAND_INSTR(0x34, 0x04),
+   ILI9881C_COMMAND_INSTR(0x35, 0x05),
+   ILI9881C_COMMAND_INSTR(0x36, 0x05),
+   ILI9881C_COMMAND_INSTR(0x37, 0x00),
+   ILI9881C_COMMAND_INSTR(0x38, 0x3C),
+   ILI9881C_COMMAND_INSTR(0x39, 0x35),
+   ILI9881C_COMMAND_INSTR(0x3A, 0x00),
+   ILI9881C_COMMAND_INSTR(0x3B, 0x40),
+   ILI9881C_COMMAND_INSTR(0x3C, 0x00),
+   ILI9881C_COMMAND_INSTR(0x3D, 0x00),
+   ILI9881C_COMMAND_INSTR(0x3E, 0x00),
+   ILI9881C_COMMAND_INSTR(0x3F, 0x00),
+
+   ILI9881C_COMMAND_INSTR(0x40, 0x00),
+   ILI9881C_COMMAND_INSTR(0x41, 0x88),
+   ILI9881C_COMMAND_INSTR(0x42, 0x00),
+   ILI9881C_COMMAND_INSTR(0x43, 0x00),
+   ILI9881C_COMMAND_INSTR(0x44, 0x1F),
+
+   ILI9881C_COMMAND_INSTR(0x50, 0x01),
+   ILI9881C_COMMAND_INSTR(0x51, 0x23),
+   ILI9881C_COMMAND_INSTR(0x52, 0x45),
+   ILI9881C_COMMAND_INSTR(0x53, 0x67),
+   ILI9881C_COMMAND_INSTR(0x54, 0x89),
+   ILI9881C_COMMAND_INSTR(0x55, 0xaB),
+   ILI9881C_COMMAND_INSTR(0x56, 0x01),
+   ILI9881C_COMMAND_INSTR(0x57, 0x23),
+   ILI9881C_COMMAND_INSTR(0x58, 0x45),
+   ILI9881C_COMMAND_INSTR(0x59, 0x67),
+   ILI9881C_COMMAND_INSTR(0x5A, 0x89),
+   ILI9881C_COMMAND_INSTR(0x5B, 0xAB),
+   ILI9881C_COMMAND_INSTR(0x5C, 0xCD),
+   ILI9881C_COMMAND_INSTR(0x5D, 0xEF),
+   ILI9881C_COMMAND_INSTR(0x5E, 0x03),
+   ILI9881C_COMMAND_INSTR(0x5F, 0x14),
+
+   ILI9881C_COMMAND_INSTR(0x60, 0x15),
+   ILI9881C_COMMAND_INSTR(0x61, 0x0C),
+   ILI9881C_COMMAND_INSTR(0x62, 0x0D),
+   ILI9881C_COMMAND_INSTR(0x63, 0x0E),
+   ILI9881C_COMMAND_INSTR(0x64, 0x0F

Re: [PATCH] drm/bridge: dw-mipi-dsi: Find the possible DSI devices

2021-10-11 Thread Michael Trimarchi
Hi

On Sun, Jul 04, 2021 at 07:33:09PM +0530, Jagan Teki wrote:
> Finding panel_or_bridge might vary based on associated
> DSI devices like DSI panel, bridge, and I2C based DSI
> bridge.
> 
> 1. DSI panels and bridges will invoke the host attach
>from probe in order to find the panel_or_bridge.
> 
>chipone_probe()
>dw_mipi_dsi_host_attach().start
>  dw_mipi_dsi_panel_or_bridge()
>   ...found the panel_or_bridge...
> 
>ltdc_encoder_init().start
>dw_mipi_dsi_bridge_attach().start
>  dw_mipi_dsi_host_attach().start
>  chipone_attach(). start
> 
>  chipone_attach(). done
>  dw_mipi_dsi_host_attach().done
>dw_mipi_dsi_bridge_attach(). done
>ltdc_encoder_init().done
> 
> 2. I2C based DSI bridge will invoke the drm_bridge_attach
>from bridge attach in order to find the panel_or_bridge.
> 
>ltdc_encoder_init().start
>dw_mipi_dsi_bridge_attach().start
>  dw_mipi_dsi_panel_or_bridge()
>   ...found the panel_or_bridge...
>  dw_mipi_dsi_host_attach().start
>  sn65dsi83_attach(). start
> 
>  sn65dsi83_attach(). done
>  dw_mipi_dsi_host_attach().done
>dw_mipi_dsi_bridge_attach(). done
>ltdc_encoder_init().done
> 
> So, invoke the panel_or_bridge from host attach and
> bridge attach in order to find all possible DSI devices.
> 

Working on linux-next-5.14-rc4 on px30-evb rockchip board. On top of this patch 
for px30 dsi
I need to add:


>From a0e0344b4cb4df3d97fac0e27e0aa76a2a191b0e Mon Sep 17 00:00:00 2001
From: Michael Trimarchi 
Date: Sun, 10 Oct 2021 23:56:20 +0200
Subject: [PATCH] drm: dw-mipi-dsi-rockchip: Avoid the attach before probe is
 completed

Signed-off-by: Michael Trimarchi 
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c   |  8 +++-
 drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 12 
 include/drm/bridge/dw_mipi_dsi.h|  2 +-
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 45f4515dda00..a5535f183af3 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -362,8 +362,14 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host 
*host,
dsi->device_found = true;
}
 
+   /*
+* NOTE: the dsi registration is implemented in
+* platform driver, that to say dsi would be exist after
+* probe is terminated. The call is done before the end of probe
+* so we need to pass the dsi to the platform driver.
+*/
if (pdata->host_ops && pdata->host_ops->attach) {
-   ret = pdata->host_ops->attach(pdata->priv_data, device);
+   ret = pdata->host_ops->attach(pdata->priv_data, device, dsi);
if (ret < 0)
return ret;
}
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index ec7729d18cb8..cf7c9cf11c9e 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -972,12 +972,15 @@ static const struct component_ops 
dw_mipi_dsi_rockchip_ops = {
 };
 
 static int dw_mipi_dsi_rockchip_host_attach(void *priv_data,
-   struct mipi_dsi_device *device)
+   struct mipi_dsi_device *device,
+   struct dw_mipi_dsi *dmd)
 {
struct dw_mipi_dsi_rockchip *dsi = priv_data;
struct device *second;
int ret;
 
+   dsi->dmd = dmd;
+
ret = component_add(dsi->dev, _mipi_dsi_rockchip_ops);
if (ret) {
DRM_DEV_ERROR(dsi->dev, "Failed to register component: %d\n",
@@ -1027,6 +1030,7 @@ static int dw_mipi_dsi_rockchip_probe(struct 
platform_device *pdev)
struct device_node *np = dev->of_node;
struct dw_mipi_dsi_rockchip *dsi;
struct resource *res;
+   struct dw_mipi_dsi *dmd;
const struct rockchip_dw_dsi_chip_data *cdata =
of_device_get_match_data(dev);
int ret, i;
@@ -1115,9 +1119,9 @@ static int dw_mipi_dsi_rockchip_probe(struct 
platform_device *pdev)
dsi->pdata.priv_data = dsi;
platform_set_drvdata(pdev, dsi);
 
-   dsi->dmd = dw_mipi_dsi_probe(pdev, >pdata);
-   if (IS_ERR(dsi->dmd)) {
-   ret = PTR_ERR(dsi->dmd);
+   dmd = dw_mipi_dsi_probe(pdev, >pdata);
+   if (IS_ERR(dmd)) {
+   ret = PTR_ERR(dmd);
if (r