armbian_build/patch/kernel/archive/sunxi-5.16/patches.megous/drm-bridge-dw-mipi-dsi-Fix-enable-disable-of-dsi-controller.patch
The-going f80117f21c
Recycling of megous v5.16.4 patches (#3449)
* Recycling of megous v5.16.4 patches

The patches were sorted as far as possible. Some patches are renamed
according to their place of application. The length of the patch name
has been changed to improve readability using
the `git format-patch --filename-max-length=75` method.

The folder containing the patches will have the name `patches.name`
and the corresponding file `series.name` for the convenience
of processing and moving them upstream. But the control file remains
`series.conf`.


Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>

* Add a series of armbian patches for 5.16

Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>

* Remove patches whose fixes are already in the kernel

Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>
2022-02-02 11:03:44 +01:00

150 lines
4.9 KiB
Diff

From e3239a38bd64eeed399210446eeadd9cbcf1d690 Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Sun, 17 Oct 2021 20:14:25 +0200
Subject: [PATCH 248/446] drm: bridge: dw-mipi-dsi: Fix enable/disable of dsi
controller
The driver had it all wrong. mode_set is not for enabling the
DSI controller, that should be done in pre_enable so that
panel driver can initialize the panel (working dsi controller
is needed for that). Having dsi powerup in mode_set led to
all kind of fun, because disable would be called more often
than mode_set.
The whole panel/dsi enable/disable dance is such (for future
reference):
- dsi: mode set
- panel: prepare (we turn on panel power)
- dsi: pre enable (we enable and setup DSI)
- dsi: enable (we enable video data)
- panel: enable (we configure and turn on the display)
For disable:
- panel: disable (we turn off the display nicely)
- dsi: disable (we disable DSI)
- dsi: post disable
- panel: unprepare (we power off display power, panel should
be safely sleeping now)
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 45 +++++++++++++------
1 file changed, 32 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index e44e18a01..9cce2aba3 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -266,6 +266,7 @@ struct dw_mipi_dsi {
struct dw_mipi_dsi *master; /* dual-dsi master ptr */
struct dw_mipi_dsi *slave; /* dual-dsi slave ptr */
+ struct drm_display_mode mode;
const struct dw_mipi_dsi_plat_data *plat_data;
};
@@ -597,6 +598,8 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
{
u32 val;
+ dev_info(dsi->dev, "mode %d\n", (int)mode_flags);
+
dsi_write(dsi, DSI_PWR_UP, RESET);
if (mode_flags & MIPI_DSI_MODE_VIDEO) {
@@ -871,11 +874,20 @@ static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
dsi_write(dsi, DSI_INT_MSK1, 0);
}
+static void dw_mipi_dsi_bridge_disable(struct drm_bridge *bridge)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+ dev_info(dsi->dev, "disable\n");
+}
+
static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
{
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
+ dev_info(dsi->dev, "post disable\n");
+
/*
* Switch to command mode before panel-bridge post_disable &
* panel unprepare.
@@ -884,15 +896,6 @@ static void dw_mipi_dsi_bridge_post_disable(struct drm_bridge *bridge)
*/
dw_mipi_dsi_set_mode(dsi, 0);
- /*
- * TODO Only way found to call panel-bridge post_disable &
- * panel unprepare before the dsi "final" disable...
- * This needs to be fixed in the drm_bridge framework and the API
- * needs to be updated to manage our own call chains...
- */
- if (dsi->panel_bridge->funcs->post_disable)
- dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge);
-
if (phy_ops->power_off)
phy_ops->power_off(dsi->plat_data->priv_data);
@@ -921,7 +924,7 @@ static unsigned int dw_mipi_dsi_get_lanes(struct dw_mipi_dsi *dsi)
return dsi->lanes;
}
-static void dw_mipi_dsi_mode_set(struct dw_mipi_dsi *dsi,
+static void dw_mipi_dsi_enable(struct dw_mipi_dsi *dsi,
const struct drm_display_mode *adjusted_mode)
{
const struct dw_mipi_dsi_phy_ops *phy_ops = dsi->plat_data->phy_ops;
@@ -973,16 +976,30 @@ static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge,
{
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
- dw_mipi_dsi_mode_set(dsi, adjusted_mode);
+ dev_info(dsi->dev, "mode set\n");
+
+ /* Store the display mode for plugin/DKMS poweron events */
+ memcpy(&dsi->mode, mode, sizeof(dsi->mode));
+}
+
+static void dw_mipi_dsi_bridge_pre_enable(struct drm_bridge *bridge)
+{
+ struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
+
+ dev_info(dsi->dev, "pre enable\n");
+
+ /* power up the dsi ctl into a command mode */
+ dw_mipi_dsi_enable(dsi, &dsi->mode);
if (dsi->slave)
- dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode);
+ dw_mipi_dsi_enable(dsi->slave, &dsi->mode);
}
static void dw_mipi_dsi_bridge_enable(struct drm_bridge *bridge)
{
struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge);
- /* Switch to video mode for panel-bridge enable & panel enable */
+ dev_info(dsi->dev, "enable\n");
+
dw_mipi_dsi_set_mode(dsi, MIPI_DSI_MODE_VIDEO);
if (dsi->slave)
dw_mipi_dsi_set_mode(dsi->slave, MIPI_DSI_MODE_VIDEO);
@@ -1033,7 +1050,9 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge,
static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = {
.mode_set = dw_mipi_dsi_bridge_mode_set,
+ .pre_enable = dw_mipi_dsi_bridge_pre_enable,
.enable = dw_mipi_dsi_bridge_enable,
+ .disable = dw_mipi_dsi_bridge_disable,
.post_disable = dw_mipi_dsi_bridge_post_disable,
.mode_valid = dw_mipi_dsi_bridge_mode_valid,
.attach = dw_mipi_dsi_bridge_attach,
--
2.31.1