linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] drm/panel: seperate panel power control from panel prepare/unprepare
@ 2021-04-20 13:26 Jitao Shi
  2021-04-20 13:26 ` [PATCH 2/4] drm/panel: boe-tv101wum-n16 seperate the panel power control Jitao Shi
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Jitao Shi @ 2021-04-20 13:26 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Matthias Brugger, Daniel Vetter,
	David Airlie, dri-devel, linux-kernel
  Cc: linux-mediatek, devicetree, linux-arm-kernel, srv_heupstream,
	yingjoe.chen, eddie.huang, cawa.cheng, bibby.hsieh, ck.hu,
	stonea168, huijuan.xie, rex-bc.chen, Jitao Shi

Some dsi panels require the dsi lanes keeping low before panel power
on. So seperate the panel power control and the communication with panel.

And put the power control in drm_panel_prepare_power and
drm_panel_unprepare_power. Put the communication with panel in
drm_panel_prepare and drm_panel_unprepare.

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
---
 drivers/gpu/drm/bridge/panel.c | 17 +++++++++++++++
 drivers/gpu/drm/drm_panel.c    | 38 ++++++++++++++++++++++++++++++++++
 include/drm/drm_bridge.h       |  2 ++
 include/drm/drm_panel.h        | 17 +++++++++++++++
 4 files changed, 74 insertions(+)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 0ddc37551194..a19c96e710fc 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -125,6 +125,23 @@ static int panel_bridge_get_modes(struct drm_bridge *bridge,
 	return drm_panel_get_modes(panel_bridge->panel, connector);
 }
 
+int panel_bridge_prepare_power(struct drm_bridge *bridge)
+{
+	struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+
+	return drm_panel_prepare_power(panel_bridge->panel);
+}
+EXPORT_SYMBOL(panel_bridge_prepare_power);
+
+int panel_bridge_unprepare_power(struct drm_bridge *bridge)
+{
+        struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+
+        return drm_panel_unprepare_power(panel_bridge->panel);
+}
+EXPORT_SYMBOL(panel_bridge_unprepare_power);
+
+
 static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
 	.attach = panel_bridge_attach,
 	.detach = panel_bridge_detach,
diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index f634371c717a..7bb5185db17d 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -115,6 +115,24 @@ int drm_panel_prepare(struct drm_panel *panel)
 }
 EXPORT_SYMBOL(drm_panel_prepare);
 
+/**
+ * drm_panel_prepare_power - power on a panel's power
+ * @panel: DRM panel
+ *
+ * Calling this function will enable power and deassert any reset signals to
+ * the panel.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int drm_panel_prepare_power(struct drm_panel *panel)
+{
+	if (panel && panel->funcs && panel->funcs->prepare_power)
+		return panel->funcs->prepare_power(panel);
+
+	return panel ? -ENOSYS : -EINVAL;
+}
+EXPORT_SYMBOL(drm_panel_prepare_power);
+
 /**
  * drm_panel_unprepare - power off a panel
  * @panel: DRM panel
@@ -138,6 +156,26 @@ int drm_panel_unprepare(struct drm_panel *panel)
 }
 EXPORT_SYMBOL(drm_panel_unprepare);
 
+/**
+ * drm_panel_unprepare_power - power off a panel
+ * @panel: DRM panel
+ *
+ * Calling this function will completely power off a panel (assert the panel's
+ * reset, turn off power supplies, ...). After this function has completed, it
+ * is usually no longer possible to communicate with the panel until another
+ * call to drm_panel_prepare_power and drm_panel_prepare().
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int drm_panel_unprepare_power(struct drm_panel *panel)
+{
+	if (panel && panel->funcs && panel->funcs->unprepare_power)
+		return panel->funcs->unprepare_power(panel);
+
+	return panel ? -ENOSYS : -EINVAL;
+}
+EXPORT_SYMBOL(drm_panel_unprepare_power);
+
 /**
  * drm_panel_enable - enable a panel
  * @panel: DRM panel
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 2195daa289d2..cc94c9da47d8 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -892,6 +892,8 @@ struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
 						   struct drm_panel *panel,
 						   u32 connector_type);
 struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge);
+int panel_bridge_prepare_power(struct drm_bridge *bridge);
+int panel_bridge_unprepare_power(struct drm_bridge *bridge);
 #endif
 
 #endif
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 33605c3f0eba..48e83712ad44 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -68,6 +68,13 @@ enum drm_panel_orientation;
  * functionality to enable/disable backlight.
  */
 struct drm_panel_funcs {
+	/**
+	 * @prepare_power:
+	 *
+	 * Turn on panel power.
+	 */
+	int (*prepare_power)(struct drm_panel *panel);
+
 	/**
 	 * @prepare:
 	 *
@@ -115,6 +122,13 @@ struct drm_panel_funcs {
 	int (*get_modes)(struct drm_panel *panel,
 			 struct drm_connector *connector);
 
+	/**
+	 * @unprepare_power:
+	 *
+	 * Turn off panel_power.
+	 */
+	int (*unprepare_power)(struct drm_panel *panel);
+
 	/**
 	 * @get_timings:
 	 *
@@ -180,6 +194,9 @@ void drm_panel_init(struct drm_panel *panel, struct device *dev,
 void drm_panel_add(struct drm_panel *panel);
 void drm_panel_remove(struct drm_panel *panel);
 
+int drm_panel_prepare_power(struct drm_panel *panel);
+int drm_panel_unprepare_power(struct drm_panel *panel);
+
 int drm_panel_prepare(struct drm_panel *panel);
 int drm_panel_unprepare(struct drm_panel *panel);
 
-- 
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/4] drm/panel: boe-tv101wum-n16 seperate the panel power control
  2021-04-20 13:26 [PATCH 1/4] drm/panel: seperate panel power control from panel prepare/unprepare Jitao Shi
@ 2021-04-20 13:26 ` Jitao Shi
  2021-04-20 13:26 ` [PATCH 3/4] drm/mediatek: fine tune the dsi panel's power sequence Jitao Shi
  2021-04-20 13:26 ` [PATCH 4/4] drm/mediatek: add dsi module reset driver Jitao Shi
  2 siblings, 0 replies; 8+ messages in thread
From: Jitao Shi @ 2021-04-20 13:26 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Matthias Brugger, Daniel Vetter,
	David Airlie, dri-devel, linux-kernel
  Cc: linux-mediatek, devicetree, linux-arm-kernel, srv_heupstream,
	yingjoe.chen, eddie.huang, cawa.cheng, bibby.hsieh, ck.hu,
	stonea168, huijuan.xie, rex-bc.chen, Jitao Shi

Seperate the panel power control from prepare/unprepare.

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
---
 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c    | 72 +++++++++++++------
 1 file changed, 50 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index db9d0b86d542..dc49079a74d1 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -50,6 +50,7 @@ struct boe_panel {
 	struct regulator *avdd;
 	struct gpio_desc *enable_gpio;
 
+	bool prepared_power;
 	bool prepared;
 };
 
@@ -488,22 +489,13 @@ static int boe_panel_enter_sleep_mode(struct boe_panel *boe)
 	return 0;
 }
 
-static int boe_panel_unprepare(struct drm_panel *panel)
+static int boe_panel_unprepare_power(struct drm_panel *panel)
 {
 	struct boe_panel *boe = to_boe_panel(panel);
-	int ret;
 
-	if (!boe->prepared)
+	if (!boe->prepared_power)
 		return 0;
 
-	ret = boe_panel_enter_sleep_mode(boe);
-	if (ret < 0) {
-		dev_err(panel->dev, "failed to set panel off: %d\n", ret);
-		return ret;
-	}
-
-	msleep(150);
-
 	if (boe->desc->discharge_on_disable) {
 		regulator_disable(boe->avee);
 		regulator_disable(boe->avdd);
@@ -512,6 +504,7 @@ static int boe_panel_unprepare(struct drm_panel *panel)
 		usleep_range(5000, 7000);
 		regulator_disable(boe->pp1800);
 	} else {
+		msleep(150);
 		gpiod_set_value(boe->enable_gpio, 0);
 		usleep_range(500, 1000);
 		regulator_disable(boe->avee);
@@ -520,17 +513,39 @@ static int boe_panel_unprepare(struct drm_panel *panel)
 		regulator_disable(boe->pp1800);
 	}
 
+	boe->prepared_power = false;
+
+	return 0;
+}
+
+static int boe_panel_unprepare(struct drm_panel *panel)
+{
+	struct boe_panel *boe = to_boe_panel(panel);
+	int ret;
+
+	if (!boe->prepared)
+		return 0;
+
+	if (!boe->desc->discharge_on_disable) {
+		ret = boe_panel_enter_sleep_mode(boe);
+		if (ret < 0) {
+			dev_err(panel->dev, "failed to set panel off: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	boe->prepared = false;
 
 	return 0;
 }
 
-static int boe_panel_prepare(struct drm_panel *panel)
+static int boe_panel_prepare_power(struct drm_panel *panel)
 {
 	struct boe_panel *boe = to_boe_panel(panel);
 	int ret;
 
-	if (boe->prepared)
+	if (boe->prepared_power)
 		return 0;
 
 	gpiod_set_value(boe->enable_gpio, 0);
@@ -558,18 +573,10 @@ static int boe_panel_prepare(struct drm_panel *panel)
 	gpiod_set_value(boe->enable_gpio, 1);
 	usleep_range(6000, 10000);
 
-	ret = boe_panel_init_dcs_cmd(boe);
-	if (ret < 0) {
-		dev_err(panel->dev, "failed to init panel: %d\n", ret);
-		goto poweroff;
-	}
-
-	boe->prepared = true;
+	boe->prepared_power = true;
 
 	return 0;
 
-poweroff:
-	regulator_disable(boe->avee);
 poweroffavdd:
 	regulator_disable(boe->avdd);
 poweroff1v8:
@@ -580,6 +587,25 @@ static int boe_panel_prepare(struct drm_panel *panel)
 	return ret;
 }
 
+static int boe_panel_prepare(struct drm_panel *panel)
+{
+	struct boe_panel *boe = to_boe_panel(panel);
+	int ret;
+
+	if (boe->prepared)
+		return 0;
+
+	ret = boe_panel_init_dcs_cmd(boe);
+	if (ret < 0) {
+		dev_err(panel->dev, "failed to init panel: %d\n", ret);
+		return ret;
+	}
+
+	boe->prepared = true;
+
+	return 0;
+}
+
 static int boe_panel_enable(struct drm_panel *panel)
 {
 	msleep(130);
@@ -749,7 +775,9 @@ static int boe_panel_get_modes(struct drm_panel *panel,
 
 static const struct drm_panel_funcs boe_panel_funcs = {
 	.unprepare = boe_panel_unprepare,
+	.unprepare_power = boe_panel_unprepare_power,
 	.prepare = boe_panel_prepare,
+	.prepare_power = boe_panel_prepare_power,
 	.enable = boe_panel_enable,
 	.get_modes = boe_panel_get_modes,
 };
-- 
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] drm/mediatek: fine tune the dsi panel's power sequence
  2021-04-20 13:26 [PATCH 1/4] drm/panel: seperate panel power control from panel prepare/unprepare Jitao Shi
  2021-04-20 13:26 ` [PATCH 2/4] drm/panel: boe-tv101wum-n16 seperate the panel power control Jitao Shi
@ 2021-04-20 13:26 ` Jitao Shi
  2021-04-23 16:36   ` Chun-Kuang Hu
  2021-04-20 13:26 ` [PATCH 4/4] drm/mediatek: add dsi module reset driver Jitao Shi
  2 siblings, 1 reply; 8+ messages in thread
From: Jitao Shi @ 2021-04-20 13:26 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Matthias Brugger, Daniel Vetter,
	David Airlie, dri-devel, linux-kernel
  Cc: linux-mediatek, devicetree, linux-arm-kernel, srv_heupstream,
	yingjoe.chen, eddie.huang, cawa.cheng, bibby.hsieh, ck.hu,
	stonea168, huijuan.xie, rex-bc.chen, Jitao Shi

Add the drm_panel_prepare_power and drm_panel_unprepare_power control.
Turn on panel power(drm_panel_prepare_power) and control before dsi
enable. And then dsi enable, send dcs cmd in drm_panel_prepare, last
turn on backlight.

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a1ff152ef468..455fe582c6b5 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -615,10 +615,13 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel,
 					  dsi->lanes);
 
+	if (panel_bridge_prepare_power(dsi->next_bridge))
+		DRM_INFO("can't prepare power the panel\n");
+
 	ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
 	if (ret < 0) {
 		dev_err(dev, "Failed to set data rate: %d\n", ret);
-		goto err_refcount;
+		goto err_prepare_power;
 	}
 
 	phy_power_on(dsi->phy);
@@ -661,7 +664,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 	clk_disable_unprepare(dsi->engine_clk);
 err_phy_power_off:
 	phy_power_off(dsi->phy);
-err_refcount:
+err_prepare_power:
+	if (panel_bridge_unprepare_power(dsi->next_bridge))
+		DRM_INFO("Can't unprepare power the panel\n");
 	dsi->refcount--;
 	return ret;
 }
@@ -694,6 +699,9 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
 	clk_disable_unprepare(dsi->digital_clk);
 
 	phy_power_off(dsi->phy);
+
+	if (panel_bridge_unprepare_power(dsi->next_bridge))
+		DRM_INFO("Can't unprepare power the panel\n");
 }
 
 static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
-- 
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/4] drm/mediatek: add dsi module reset driver
  2021-04-20 13:26 [PATCH 1/4] drm/panel: seperate panel power control from panel prepare/unprepare Jitao Shi
  2021-04-20 13:26 ` [PATCH 2/4] drm/panel: boe-tv101wum-n16 seperate the panel power control Jitao Shi
  2021-04-20 13:26 ` [PATCH 3/4] drm/mediatek: fine tune the dsi panel's power sequence Jitao Shi
@ 2021-04-20 13:26 ` Jitao Shi
  2021-04-23 23:50   ` Chun-Kuang Hu
  2 siblings, 1 reply; 8+ messages in thread
From: Jitao Shi @ 2021-04-20 13:26 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Matthias Brugger, Daniel Vetter,
	David Airlie, dri-devel, linux-kernel
  Cc: linux-mediatek, devicetree, linux-arm-kernel, srv_heupstream,
	yingjoe.chen, eddie.huang, cawa.cheng, bibby.hsieh, ck.hu,
	stonea168, huijuan.xie, rex-bc.chen, Jitao Shi

Reset dsi HW to default when power on. Prevent the setting differet
between bootloader and kernel.

Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 36 +++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 455fe582c6b5..113438ddd4cc 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -7,10 +7,12 @@
 #include <linux/component.h>
 #include <linux/iopoll.h>
 #include <linux/irq.h>
+#include <linux/mfd/syscon.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 <video/mipi_display.h>
 #include <video/videomode.h>
@@ -143,6 +145,8 @@
 #define DATA_0				(0xff << 16)
 #define DATA_1				(0xff << 24)
 
+#define MMSYS_SW_RST_DSI_B BIT(25)
+
 #define NS_TO_CYCLE(n, c)    ((n) / (c) + (((n) % (c)) ? 1 : 0))
 
 #define MTK_DSI_HOST_IS_READ(type) \
@@ -186,7 +190,8 @@ struct mtk_dsi {
 	struct drm_bridge *next_bridge;
 	struct drm_connector *connector;
 	struct phy *phy;
-
+	struct regmap *mmsys_sw_rst_b;
+	u32 sw_rst_b;
 	void __iomem *regs;
 
 	struct clk *engine_clk;
@@ -272,6 +277,16 @@ static void mtk_dsi_disable(struct mtk_dsi *dsi)
 	mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, 0);
 }
 
+static void mtk_dsi_reset_all(struct mtk_dsi *dsi)
+{
+	regmap_update_bits(dsi->mmsys_sw_rst_b, dsi->sw_rst_b,
+			   MMSYS_SW_RST_DSI_B, 0);
+	usleep_range(1000, 1100);
+
+	regmap_update_bits(dsi->mmsys_sw_rst_b, dsi->sw_rst_b,
+			   MMSYS_SW_RST_DSI_B, MMSYS_SW_RST_DSI_B);
+}
+
 static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
 {
 	mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET);
@@ -985,6 +1000,8 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
 
 	ret = mtk_dsi_encoder_init(drm, dsi);
 
+	mtk_dsi_reset_all(dsi);
+
 	return ret;
 }
 
@@ -1007,6 +1024,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct drm_panel *panel;
 	struct resource *regs;
+	struct regmap *regmap;
 	int irq_num;
 	int ret;
 
@@ -1022,6 +1040,22 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
+						 "mediatek,syscon-dsi");
+	ret = of_property_read_u32_index(dev->of_node, "mediatek,syscon-dsi", 1,
+					 &dsi->sw_rst_b);
+
+	if (IS_ERR(regmap))
+		ret = PTR_ERR(regmap);
+
+	if (ret) {
+		ret = PTR_ERR(regmap);
+		dev_err(dev, "Failed to get mmsys registers: %d\n", ret);
+		return ret;
+	}
+
+	dsi->mmsys_sw_rst_b = regmap;
+
 	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
 					  &panel, &dsi->next_bridge);
 	if (ret)
-- 
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/4] drm/mediatek: fine tune the dsi panel's power sequence
  2021-04-20 13:26 ` [PATCH 3/4] drm/mediatek: fine tune the dsi panel's power sequence Jitao Shi
@ 2021-04-23 16:36   ` Chun-Kuang Hu
  2021-05-19  3:54     ` Jitao Shi
  0 siblings, 1 reply; 8+ messages in thread
From: Chun-Kuang Hu @ 2021-04-23 16:36 UTC (permalink / raw)
  To: Jitao Shi
  Cc: Rob Herring, Mark Rutland, Matthias Brugger, Daniel Vetter,
	David Airlie, DRI Development, linux-kernel, DTML,
	srv_heupstream, huijuan.xie, stonea168, Cawa Cheng, Rex-BC Chen,
	moderated list:ARM/Mediatek SoC support, yingjoe.chen,
	eddie.huang, Linux ARM

Hi, Jitao:

Jitao Shi <jitao.shi@mediatek.com> 於 2021年4月20日 週二 下午9:26寫道:
>
> Add the drm_panel_prepare_power and drm_panel_unprepare_power control.
> Turn on panel power(drm_panel_prepare_power) and control before dsi
> enable. And then dsi enable, send dcs cmd in drm_panel_prepare, last
> turn on backlight.

Please describe WHY do you need this patch? Fix any bug?

>
> Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index a1ff152ef468..455fe582c6b5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -615,10 +615,13 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>         dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel,
>                                           dsi->lanes);
>
> +       if (panel_bridge_prepare_power(dsi->next_bridge))

ret = panel_bridge_prepare_power(dsi->next_bridge);
if (ret)

> +               DRM_INFO("can't prepare power the panel\n");

I think you should goto err_refcount;

> +
>         ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
>         if (ret < 0) {
>                 dev_err(dev, "Failed to set data rate: %d\n", ret);
> -               goto err_refcount;
> +               goto err_prepare_power;
>         }
>
>         phy_power_on(dsi->phy);
> @@ -661,7 +664,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
>         clk_disable_unprepare(dsi->engine_clk);
>  err_phy_power_off:
>         phy_power_off(dsi->phy);
> -err_refcount:
> +err_prepare_power:
> +       if (panel_bridge_unprepare_power(dsi->next_bridge))

ret = panel_bridge_unprepare_power(dsi->next_bridge);

> +               DRM_INFO("Can't unprepare power the panel\n");
>         dsi->refcount--;
>         return ret;
>  }
> @@ -694,6 +699,9 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
>         clk_disable_unprepare(dsi->digital_clk);
>
>         phy_power_off(dsi->phy);
> +
> +       if (panel_bridge_unprepare_power(dsi->next_bridge))

ret = panel_bridge_unprepare_power(dsi->next_bridge);

> +               DRM_INFO("Can't unprepare power the panel\n");
>  }
>
>  static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
> --
> 2.25.1
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] drm/mediatek: add dsi module reset driver
  2021-04-20 13:26 ` [PATCH 4/4] drm/mediatek: add dsi module reset driver Jitao Shi
@ 2021-04-23 23:50   ` Chun-Kuang Hu
  2021-05-19  5:31     ` Jitao Shi
  0 siblings, 1 reply; 8+ messages in thread
From: Chun-Kuang Hu @ 2021-04-23 23:50 UTC (permalink / raw)
  To: Jitao Shi
  Cc: Rob Herring, Mark Rutland, Matthias Brugger, Daniel Vetter,
	David Airlie, DRI Development, linux-kernel, DTML,
	srv_heupstream, huijuan.xie, stonea168, Cawa Cheng, Rex-BC Chen,
	moderated list:ARM/Mediatek SoC support, yingjoe.chen,
	eddie.huang, Linux ARM

Hi, Jitao:

Jitao Shi <jitao.shi@mediatek.com> 於 2021年4月20日 週二 下午9:26寫道:
>
> Reset dsi HW to default when power on. Prevent the setting differet
> between bootloader and kernel.
>
> Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 36 +++++++++++++++++++++++++++++-
>  1 file changed, 35 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 455fe582c6b5..113438ddd4cc 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -7,10 +7,12 @@
>  #include <linux/component.h>
>  #include <linux/iopoll.h>
>  #include <linux/irq.h>
> +#include <linux/mfd/syscon.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 <video/mipi_display.h>
>  #include <video/videomode.h>
> @@ -143,6 +145,8 @@
>  #define DATA_0                         (0xff << 16)
>  #define DATA_1                         (0xff << 24)
>
> +#define MMSYS_SW_RST_DSI_B BIT(25)
> +
>  #define NS_TO_CYCLE(n, c)    ((n) / (c) + (((n) % (c)) ? 1 : 0))
>
>  #define MTK_DSI_HOST_IS_READ(type) \
> @@ -186,7 +190,8 @@ struct mtk_dsi {
>         struct drm_bridge *next_bridge;
>         struct drm_connector *connector;
>         struct phy *phy;
> -
> +       struct regmap *mmsys_sw_rst_b;
> +       u32 sw_rst_b;
>         void __iomem *regs;
>
>         struct clk *engine_clk;
> @@ -272,6 +277,16 @@ static void mtk_dsi_disable(struct mtk_dsi *dsi)
>         mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, 0);
>  }
>
> +static void mtk_dsi_reset_all(struct mtk_dsi *dsi)
> +{
> +       regmap_update_bits(dsi->mmsys_sw_rst_b, dsi->sw_rst_b,
> +                          MMSYS_SW_RST_DSI_B, 0);
> +       usleep_range(1000, 1100);
> +
> +       regmap_update_bits(dsi->mmsys_sw_rst_b, dsi->sw_rst_b,
> +                          MMSYS_SW_RST_DSI_B, MMSYS_SW_RST_DSI_B);
> +}
> +
>  static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
>  {
>         mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET);
> @@ -985,6 +1000,8 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>
>         ret = mtk_dsi_encoder_init(drm, dsi);
>
> +       mtk_dsi_reset_all(dsi);
> +
>         return ret;
>  }
>
> @@ -1007,6 +1024,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>         struct device *dev = &pdev->dev;
>         struct drm_panel *panel;
>         struct resource *regs;
> +       struct regmap *regmap;
>         int irq_num;
>         int ret;
>
> @@ -1022,6 +1040,22 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> +       regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
> +                                                "mediatek,syscon-dsi");
> +       ret = of_property_read_u32_index(dev->of_node, "mediatek,syscon-dsi", 1,
> +                                        &dsi->sw_rst_b);
> +
> +       if (IS_ERR(regmap))
> +               ret = PTR_ERR(regmap);
> +
> +       if (ret) {
> +               ret = PTR_ERR(regmap);
> +               dev_err(dev, "Failed to get mmsys registers: %d\n", ret);
> +               return ret;
> +       }
> +
> +       dsi->mmsys_sw_rst_b = regmap;
> +

It looks like that mtk-mmsys is the reset controller and mtk-dsi is
reset consumer. Please refer to [1], [2] to implement.

[1] https://www.kernel.org/doc/html/latest/driver-api/reset.html
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/reset/reset.txt?h=v5.12-rc8

Regards,
Chun-Kuang.

>         ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
>                                           &panel, &dsi->next_bridge);
>         if (ret)
> --
> 2.25.1
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/4] drm/mediatek: fine tune the dsi panel's power sequence
  2021-04-23 16:36   ` Chun-Kuang Hu
@ 2021-05-19  3:54     ` Jitao Shi
  0 siblings, 0 replies; 8+ messages in thread
From: Jitao Shi @ 2021-05-19  3:54 UTC (permalink / raw)
  To: Chun-Kuang Hu
  Cc: Rob Herring, Mark Rutland, Matthias Brugger, Daniel Vetter,
	David Airlie, DRI Development, linux-kernel, DTML,
	srv_heupstream, Huijuan Xie (谢慧娟),
	stonea168, Cawa Cheng (鄭曄禧),
	Rex-BC Chen (陳柏辰),
	moderated list:ARM/Mediatek SoC support,
	Yingjoe Chen (陳英洲),
	Eddie Huang (黃智傑),
	Linux ARM

On Sat, 2021-04-24 at 00:36 +0800, Chun-Kuang Hu wrote:
> Hi, Jitao:
> 
> Jitao Shi <jitao.shi@mediatek.com> 於 2021年4月20日 週二 下午9:26寫道:
> >
> > Add the drm_panel_prepare_power and drm_panel_unprepare_power control.
> > Turn on panel power(drm_panel_prepare_power) and control before dsi
> > enable. And then dsi enable, send dcs cmd in drm_panel_prepare, last
> > turn on backlight.
> 
> Please describe WHY do you need this patch? Fix any bug?

Most panels, have five steps when poweron.

1. turn on dsi signal to LP11   --> dsi host's action
2. turn on the power supplies,  --> panel's action
3. send the DCS  cmd to panel   --> panel's action
4. start send video stream      --> dsi host's action
5. turn on backlight.           --> panel's action

we put "turn on the power supplies" and "send the DCS  cmd to panel" in
panel_prepare. And "turn on backlight" in panel_enable.

But some other panels has a special poweron sequence as the following.

1. turn on the power supplies,  --> panel's action
2. turn on dsi signal to LP11   --> dsi host's action
3. send the DCS  cmd to panel   --> panel's action
4. start send video stream      --> dsi host's action
5. turn on backlight.           --> panel's action

panel's actions are divided into three parts.

So I add a new api "drm_panel_prepare_power/rm_panel_unprepare_power" to
control the sequence.


Best Regards
Jitao

> 
> >
> > Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > index a1ff152ef468..455fe582c6b5 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > @@ -615,10 +615,13 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
> >         dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel,
> >                                           dsi->lanes);
> >
> > +       if (panel_bridge_prepare_power(dsi->next_bridge))
> 
> ret = panel_bridge_prepare_power(dsi->next_bridge);
> if (ret)
> 
> > +               DRM_INFO("can't prepare power the panel\n");
> 
> I think you should goto err_refcount;

Thanks for your review. I'll fix it next patch.

> 
> > +
> >         ret = clk_set_rate(dsi->hs_clk, dsi->data_rate);
> >         if (ret < 0) {
> >                 dev_err(dev, "Failed to set data rate: %d\n", ret);
> > -               goto err_refcount;
> > +               goto err_prepare_power;
> >         }
> >
> >         phy_power_on(dsi->phy);
> > @@ -661,7 +664,9 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
> >         clk_disable_unprepare(dsi->engine_clk);
> >  err_phy_power_off:
> >         phy_power_off(dsi->phy);
> > -err_refcount:
> > +err_prepare_power:
> > +       if (panel_bridge_unprepare_power(dsi->next_bridge))
> 
> ret = panel_bridge_unprepare_power(dsi->next_bridge);
> 
> > +               DRM_INFO("Can't unprepare power the panel\n");
> >         dsi->refcount--;
> >         return ret;
> >  }
> > @@ -694,6 +699,9 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
> >         clk_disable_unprepare(dsi->digital_clk);
> >
> >         phy_power_off(dsi->phy);
> > +
> > +       if (panel_bridge_unprepare_power(dsi->next_bridge))
> 
> ret = panel_bridge_unprepare_power(dsi->next_bridge);
> 
> > +               DRM_INFO("Can't unprepare power the panel\n");
> >  }
> >
> >  static void mtk_output_dsi_enable(struct mtk_dsi *dsi)
> > --
> > 2.25.1
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] drm/mediatek: add dsi module reset driver
  2021-04-23 23:50   ` Chun-Kuang Hu
@ 2021-05-19  5:31     ` Jitao Shi
  0 siblings, 0 replies; 8+ messages in thread
From: Jitao Shi @ 2021-05-19  5:31 UTC (permalink / raw)
  To: Chun-Kuang Hu
  Cc: Rob Herring, Mark Rutland, Matthias Brugger, Daniel Vetter,
	David Airlie, DRI Development, linux-kernel, DTML,
	srv_heupstream, Huijuan Xie (谢慧娟),
	stonea168, Cawa Cheng (鄭曄禧),
	Rex-BC Chen (陳柏辰),
	moderated list:ARM/Mediatek SoC support,
	Yingjoe Chen (陳英洲),
	Eddie Huang (黃智傑),
	Linux ARM

On Sat, 2021-04-24 at 07:50 +0800, Chun-Kuang Hu wrote:
> Hi, Jitao:
> 
> Jitao Shi <jitao.shi@mediatek.com> 於 2021年4月20日 週二 下午9:26寫道:
> >
> > Reset dsi HW to default when power on. Prevent the setting differet
> > between bootloader and kernel.
> >
> > Signed-off-by: Jitao Shi <jitao.shi@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dsi.c | 36 +++++++++++++++++++++++++++++-
> >  1 file changed, 35 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > index 455fe582c6b5..113438ddd4cc 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > @@ -7,10 +7,12 @@
> >  #include <linux/component.h>
> >  #include <linux/iopoll.h>
> >  #include <linux/irq.h>
> > +#include <linux/mfd/syscon.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 <video/mipi_display.h>
> >  #include <video/videomode.h>
> > @@ -143,6 +145,8 @@
> >  #define DATA_0                         (0xff << 16)
> >  #define DATA_1                         (0xff << 24)
> >
> > +#define MMSYS_SW_RST_DSI_B BIT(25)
> > +
> >  #define NS_TO_CYCLE(n, c)    ((n) / (c) + (((n) % (c)) ? 1 : 0))
> >
> >  #define MTK_DSI_HOST_IS_READ(type) \
> > @@ -186,7 +190,8 @@ struct mtk_dsi {
> >         struct drm_bridge *next_bridge;
> >         struct drm_connector *connector;
> >         struct phy *phy;
> > -
> > +       struct regmap *mmsys_sw_rst_b;
> > +       u32 sw_rst_b;
> >         void __iomem *regs;
> >
> >         struct clk *engine_clk;
> > @@ -272,6 +277,16 @@ static void mtk_dsi_disable(struct mtk_dsi *dsi)
> >         mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, 0);
> >  }
> >
> > +static void mtk_dsi_reset_all(struct mtk_dsi *dsi)
> > +{
> > +       regmap_update_bits(dsi->mmsys_sw_rst_b, dsi->sw_rst_b,
> > +                          MMSYS_SW_RST_DSI_B, 0);
> > +       usleep_range(1000, 1100);
> > +
> > +       regmap_update_bits(dsi->mmsys_sw_rst_b, dsi->sw_rst_b,
> > +                          MMSYS_SW_RST_DSI_B, MMSYS_SW_RST_DSI_B);
> > +}
> > +
> >  static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
> >  {
> >         mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET);
> > @@ -985,6 +1000,8 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
> >
> >         ret = mtk_dsi_encoder_init(drm, dsi);
> >
> > +       mtk_dsi_reset_all(dsi);
> > +
> >         return ret;
> >  }
> >
> > @@ -1007,6 +1024,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
> >         struct device *dev = &pdev->dev;
> >         struct drm_panel *panel;
> >         struct resource *regs;
> > +       struct regmap *regmap;
> >         int irq_num;
> >         int ret;
> >
> > @@ -1022,6 +1040,22 @@ static int mtk_dsi_probe(struct platform_device *pdev)
> >                 return ret;
> >         }
> >
> > +       regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
> > +                                                "mediatek,syscon-dsi");
> > +       ret = of_property_read_u32_index(dev->of_node, "mediatek,syscon-dsi", 1,
> > +                                        &dsi->sw_rst_b);
> > +
> > +       if (IS_ERR(regmap))
> > +               ret = PTR_ERR(regmap);
> > +
> > +       if (ret) {
> > +               ret = PTR_ERR(regmap);
> > +               dev_err(dev, "Failed to get mmsys registers: %d\n", ret);
> > +               return ret;
> > +       }
> > +
> > +       dsi->mmsys_sw_rst_b = regmap;
> > +
> 
> It looks like that mtk-mmsys is the reset controller and mtk-dsi is
> reset consumer. Please refer to [1], [2] to implement.
> 
> [1] https://www.kernel.org/doc/html/latest/driver-api/reset.html
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/reset/reset.txt?h=v5.12-rc8
> 
> Regards,
> Chun-Kuang.
> 

Thanks, I'll fix next version.

> >         ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> >                                           &panel, &dsi->next_bridge);
> >         if (ret)
> > --
> > 2.25.1
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-05-19  5:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-20 13:26 [PATCH 1/4] drm/panel: seperate panel power control from panel prepare/unprepare Jitao Shi
2021-04-20 13:26 ` [PATCH 2/4] drm/panel: boe-tv101wum-n16 seperate the panel power control Jitao Shi
2021-04-20 13:26 ` [PATCH 3/4] drm/mediatek: fine tune the dsi panel's power sequence Jitao Shi
2021-04-23 16:36   ` Chun-Kuang Hu
2021-05-19  3:54     ` Jitao Shi
2021-04-20 13:26 ` [PATCH 4/4] drm/mediatek: add dsi module reset driver Jitao Shi
2021-04-23 23:50   ` Chun-Kuang Hu
2021-05-19  5:31     ` Jitao Shi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).