Hi,
This series aims to make the nwl-dsi bridge be able to connect with more MIPI DSI panels. Some MIPI DSI panel drivers like 'raydium,rm68200' send MIPI_DCS_SET_DISPLAY_ON commands in panel_funcs->prepare(), which requires the MIPI DSI controller and PHY to be ready beforehand. However, the existing nwl-dsi driver gets the MIPI DSI controller and PHY ready in bridge_funcs->pre_enable(), which happens after the panel_funcs->prepare(). So, this series shifts the bridge operation ealier from bridge_funcs->pre_enable() to bridge_funcs->mode_set().
Patch 3/3 does the essential bridge operation shift.
Patch 1/3 and 2/3 are split from the original single patch in v2 and are needed by patch 3/3. This split-up helps clarify changes better. The split-up is done in this way:
1) Patch 1/3 forces a full modeset when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). This makes sure ->mode_set() and ->atomic_disable() will be called in pairs. 2) Patch 2/3 removes a check on unchanged HS clock rate from ->mode_set(), to make sure MIPI DSI controller and PHY are brought up and taken down in pairs. 3) Patch 3/3 shifts the bridge operation as the last step.
v2->v3: * Split the single patch in v2 into 3 patches. (Neil)
v1->v2: * Fix a typo in commit message - s/unchange/unchanged/
Liu Ying (3): drm/bridge: nwl-dsi: Force a full modeset when crtc_state->active is changed to be true drm/bridge: nwl-dsi: Remove a check on unchanged HS clock rate from ->mode_set() drm/bridge: nwl-dsi: Get MIPI DSI controller and PHY ready in ->mode_set()
drivers/gpu/drm/bridge/nwl-dsi.c | 86 +++++++++++++++++--------------- 1 file changed, 46 insertions(+), 40 deletions(-)
This patch replaces ->mode_fixup() with ->atomic_check() so that a full modeset can be requested from there when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). Bridge functions are added or changed to accommodate the ->atomic_check() callback. That full modeset is needed by the up-coming patch which gets MIPI DSI controller and PHY ready in ->mode_set(), because it makes sure ->mode_set() and ->atomic_disable() are called in pairs.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com --- v2->v3: * Split from the single patch in v2 to clarify changes. (Neil)
drivers/gpu/drm/bridge/nwl-dsi.c | 61 ++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 66b67402f1acd..c65ca860712d2 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -21,6 +21,7 @@ #include <linux/sys_soc.h> #include <linux/time64.h>
+#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> @@ -742,7 +743,9 @@ static int nwl_dsi_disable(struct nwl_dsi *dsi) return 0; }
-static void nwl_dsi_bridge_disable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -803,17 +806,6 @@ static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi, return 0; }
-static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* At least LCDIF + NWL needs active high sync */ - adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); - adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); - - return true; -} - static enum drm_mode_status nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, @@ -831,6 +823,24 @@ nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; }
+static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; + + /* At least LCDIF + NWL needs active high sync */ + adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); + adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); + + /* Do a full modeset if crtc_state->active is changed to be true. */ + if (crtc_state->active_changed && crtc_state->active) + crtc_state->mode_changed = true; + + return 0; +} + static void nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, @@ -862,7 +872,9 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, drm_mode_debug_printmodeline(adjusted_mode); }
-static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -897,7 +909,9 @@ static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) } }
-static void nwl_dsi_bridge_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -942,14 +956,17 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) }
static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { - .pre_enable = nwl_dsi_bridge_pre_enable, - .enable = nwl_dsi_bridge_enable, - .disable = nwl_dsi_bridge_disable, - .mode_fixup = nwl_dsi_bridge_mode_fixup, - .mode_set = nwl_dsi_bridge_mode_set, - .mode_valid = nwl_dsi_bridge_mode_valid, - .attach = nwl_dsi_bridge_attach, - .detach = nwl_dsi_bridge_detach, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_check = nwl_dsi_bridge_atomic_check, + .atomic_pre_enable = nwl_dsi_bridge_atomic_pre_enable, + .atomic_enable = nwl_dsi_bridge_atomic_enable, + .atomic_disable = nwl_dsi_bridge_atomic_disable, + .mode_set = nwl_dsi_bridge_mode_set, + .mode_valid = nwl_dsi_bridge_mode_valid, + .attach = nwl_dsi_bridge_attach, + .detach = nwl_dsi_bridge_detach, };
static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
On 23/04/2021 11:26, Liu Ying wrote:
This patch replaces ->mode_fixup() with ->atomic_check() so that a full modeset can be requested from there when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). Bridge functions are added or changed to accommodate the ->atomic_check() callback. That full modeset is needed by the up-coming patch which gets MIPI DSI controller and PHY ready in ->mode_set(), because it makes sure ->mode_set() and ->atomic_disable() are called in pairs.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com
v2->v3:
- Split from the single patch in v2 to clarify changes. (Neil)
drivers/gpu/drm/bridge/nwl-dsi.c | 61 ++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 66b67402f1acd..c65ca860712d2 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -21,6 +21,7 @@ #include <linux/sys_soc.h> #include <linux/time64.h>
+#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> @@ -742,7 +743,9 @@ static int nwl_dsi_disable(struct nwl_dsi *dsi) return 0; }
-static void nwl_dsi_bridge_disable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{ struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -803,17 +806,6 @@ static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi, return 0; }
-static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
-{
- /* At least LCDIF + NWL needs active high sync */
- adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
- adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
- return true;
-}
static enum drm_mode_status nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, @@ -831,6 +823,24 @@ nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; }
+static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_bridge_state *bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
+{
- struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
- /* At least LCDIF + NWL needs active high sync */
- adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
- adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
- /* Do a full modeset if crtc_state->active is changed to be true. */
- if (crtc_state->active_changed && crtc_state->active)
crtc_state->mode_changed = true;
- return 0;
+}
static void nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, @@ -862,7 +872,9 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, drm_mode_debug_printmodeline(adjusted_mode); }
-static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{ struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -897,7 +909,9 @@ static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) } }
-static void nwl_dsi_bridge_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{ struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -942,14 +956,17 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) }
static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
- .pre_enable = nwl_dsi_bridge_pre_enable,
- .enable = nwl_dsi_bridge_enable,
- .disable = nwl_dsi_bridge_disable,
- .mode_fixup = nwl_dsi_bridge_mode_fixup,
- .mode_set = nwl_dsi_bridge_mode_set,
- .mode_valid = nwl_dsi_bridge_mode_valid,
- .attach = nwl_dsi_bridge_attach,
- .detach = nwl_dsi_bridge_detach,
- .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
- .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
- .atomic_reset = drm_atomic_helper_bridge_reset,
- .atomic_check = nwl_dsi_bridge_atomic_check,
- .atomic_pre_enable = nwl_dsi_bridge_atomic_pre_enable,
- .atomic_enable = nwl_dsi_bridge_atomic_enable,
- .atomic_disable = nwl_dsi_bridge_atomic_disable,
- .mode_set = nwl_dsi_bridge_mode_set,
- .mode_valid = nwl_dsi_bridge_mode_valid,
- .attach = nwl_dsi_bridge_attach,
- .detach = nwl_dsi_bridge_detach,
};
static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
Reviewed-by: Neil Armstrong narmstrong@baylibre.com
Hey Liu,
This patch does not apply on upstream-drm-misc/drm-misc-next. When it passes local testing & building, I'm ready to merge it.
On Fri, 23 Apr 2021 at 11:42, Liu Ying victor.liu@nxp.com wrote:
This patch replaces ->mode_fixup() with ->atomic_check() so that a full modeset can be requested from there when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). Bridge functions are added or changed to accommodate the ->atomic_check() callback. That full modeset is needed by the up-coming patch which gets MIPI DSI controller and PHY ready in ->mode_set(), because it makes sure ->mode_set() and ->atomic_disable() are called in pairs.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com
v2->v3:
- Split from the single patch in v2 to clarify changes. (Neil)
drivers/gpu/drm/bridge/nwl-dsi.c | 61 ++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 66b67402f1acd..c65ca860712d2 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -21,6 +21,7 @@ #include <linux/sys_soc.h> #include <linux/time64.h>
+#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> @@ -742,7 +743,9 @@ static int nwl_dsi_disable(struct nwl_dsi *dsi) return 0; }
-static void nwl_dsi_bridge_disable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{ struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -803,17 +806,6 @@ static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi, return 0; }
-static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode *mode,
struct drm_display_mode
*adjusted_mode) -{
/* At least LCDIF + NWL needs active high sync */
adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_PVSYNC);
adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_NVSYNC);
return true;
-}
static enum drm_mode_status nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, @@ -831,6 +823,24 @@ nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; }
+static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_bridge_state
*bridge_state,
struct drm_crtc_state *crtc_state,
struct drm_connector_state
*conn_state) +{
struct drm_display_mode *adjusted_mode =
&crtc_state->adjusted_mode;
/* At least LCDIF + NWL needs active high sync */
adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_PVSYNC);
adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_NVSYNC);
/* Do a full modeset if crtc_state->active is changed to be true.
*/
if (crtc_state->active_changed && crtc_state->active)
crtc_state->mode_changed = true;
return 0;
+}
static void nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, @@ -862,7 +872,9 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, drm_mode_debug_printmodeline(adjusted_mode); }
-static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{ struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -897,7 +909,9 @@ static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) } }
-static void nwl_dsi_bridge_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
{ struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -942,14 +956,17 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) }
static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
.pre_enable = nwl_dsi_bridge_pre_enable,
.enable = nwl_dsi_bridge_enable,
.disable = nwl_dsi_bridge_disable,
.mode_fixup = nwl_dsi_bridge_mode_fixup,
.mode_set = nwl_dsi_bridge_mode_set,
.mode_valid = nwl_dsi_bridge_mode_valid,
.attach = nwl_dsi_bridge_attach,
.detach = nwl_dsi_bridge_detach,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_check = nwl_dsi_bridge_atomic_check,
.atomic_pre_enable = nwl_dsi_bridge_atomic_pre_enable,
.atomic_enable = nwl_dsi_bridge_atomic_enable,
.atomic_disable = nwl_dsi_bridge_atomic_disable,
.mode_set = nwl_dsi_bridge_mode_set,
.mode_valid = nwl_dsi_bridge_mode_valid,
.attach = nwl_dsi_bridge_attach,
.detach = nwl_dsi_bridge_detach,
};
static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
2.25.1
Hi Robert,
On Fri, 2021-04-30 at 11:56 +0200, Robert Foss wrote:
Hey Liu,
This patch does not apply on upstream-drm-misc/drm-misc-next. When it passes local testing & building, I'm ready to merge it.
I see Neil has already pushed this entire patch series to drm-misc-next.
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=885811372fe101c4299c53e...
I also see Guido's R-b and T-b tags on this series, though they comes after Neil's push perhaps.
Thanks, Liu Ying
On Fri, 23 Apr 2021 at 11:42, Liu Ying victor.liu@nxp.com wrote:
This patch replaces ->mode_fixup() with ->atomic_check() so that a full modeset can be requested from there when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). Bridge functions are added or changed to accommodate the ->atomic_check() callback. That full modeset is needed by the up-coming patch which gets MIPI DSI controller and PHY ready in ->mode_set(), because it makes sure ->mode_set() and ->atomic_disable() are called in pairs.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com
v2->v3:
- Split from the single patch in v2 to clarify changes. (Neil)
drivers/gpu/drm/bridge/nwl-dsi.c | 61 ++++++++++++++++++++------
1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 66b67402f1acd..c65ca860712d2 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -21,6 +21,7 @@ #include <linux/sys_soc.h> #include <linux/time64.h>
+#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> @@ -742,7 +743,9 @@ static int nwl_dsi_disable(struct nwl_dsi *dsi) return 0; }
-static void nwl_dsi_bridge_disable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
struct drm_bridge_state
*old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -803,17 +806,6 @@ static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi, return 0; }
-static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode
*mode,
struct drm_display_mode
*adjusted_mode) -{
/* At least LCDIF + NWL needs active high sync */
adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_PVSYNC);
adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_NVSYNC);
return true;
-}
static enum drm_mode_status nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, @@ -831,6 +823,24 @@ nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; }
+static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_bridge_state
*bridge_state,
struct drm_crtc_state
*crtc_state,
struct drm_connector_state
*conn_state) +{
struct drm_display_mode *adjusted_mode = &crtc_state-
adjusted_mode;
/* At least LCDIF + NWL needs active high sync */
adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_PVSYNC);
adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_NVSYNC);
/* Do a full modeset if crtc_state->active is changed to be
true. */
if (crtc_state->active_changed && crtc_state->active)
crtc_state->mode_changed = true;
return 0;
+}
static void nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, @@ -862,7 +872,9 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, drm_mode_debug_printmodeline(adjusted_mode); }
-static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_bridge_state
*old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -897,7 +909,9 @@ static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) } }
-static void nwl_dsi_bridge_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state
*old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -942,14 +956,17 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) }
static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
.pre_enable = nwl_dsi_bridge_pre_enable,
.enable = nwl_dsi_bridge_enable,
.disable = nwl_dsi_bridge_disable,
.mode_fixup = nwl_dsi_bridge_mode_fixup,
.mode_set = nwl_dsi_bridge_mode_set,
.mode_valid = nwl_dsi_bridge_mode_valid,
.attach = nwl_dsi_bridge_attach,
.detach = nwl_dsi_bridge_detach,
.atomic_duplicate_state =
drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state =
drm_atomic_helper_bridge_destroy_state,
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_check = nwl_dsi_bridge_atomic_check,
.atomic_pre_enable = nwl_dsi_bridge_atomic_pre_enable,
.atomic_enable = nwl_dsi_bridge_atomic_enable,
.atomic_disable = nwl_dsi_bridge_atomic_disable,
.mode_set = nwl_dsi_bridge_mode_set,
.mode_valid = nwl_dsi_bridge_mode_valid,
.attach = nwl_dsi_bridge_attach,
.detach = nwl_dsi_bridge_detach,
};
static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
Even better :)
On Fri, Apr 30, 2021, 13:46 Liu Ying victor.liu@nxp.com wrote:
Hi Robert,
On Fri, 2021-04-30 at 11:56 +0200, Robert Foss wrote:
Hey Liu,
This patch does not apply on upstream-drm-misc/drm-misc-next. When it passes local testing & building, I'm ready to merge it.
I see Neil has already pushed this entire patch series to drm-misc-next.
https://cgit.freedesktop.org/drm/drm-misc/commit/?id=885811372fe101c4299c53e...
I also see Guido's R-b and T-b tags on this series, though they comes after Neil's push perhaps.
Thanks, Liu Ying
On Fri, 23 Apr 2021 at 11:42, Liu Ying victor.liu@nxp.com wrote:
This patch replaces ->mode_fixup() with ->atomic_check() so that a full modeset can be requested from there when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). Bridge functions are added or changed to accommodate the ->atomic_check() callback. That full modeset is needed by the up-coming patch which gets MIPI DSI controller and PHY ready in ->mode_set(), because it makes sure ->mode_set() and ->atomic_disable() are called in pairs.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com
v2->v3:
- Split from the single patch in v2 to clarify changes. (Neil)
drivers/gpu/drm/bridge/nwl-dsi.c | 61 ++++++++++++++++++++------
1 file changed, 39 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 66b67402f1acd..c65ca860712d2 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -21,6 +21,7 @@ #include <linux/sys_soc.h> #include <linux/time64.h>
+#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> @@ -742,7 +743,9 @@ static int nwl_dsi_disable(struct nwl_dsi *dsi) return 0; }
-static void nwl_dsi_bridge_disable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_disable(struct drm_bridge *bridge,
struct drm_bridge_state
*old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -803,17 +806,6 @@ static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi, return 0; }
-static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
const struct drm_display_mode
*mode,
struct drm_display_mode
*adjusted_mode) -{
/* At least LCDIF + NWL needs active high sync */
adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_PVSYNC);
adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_NVSYNC);
return true;
-}
static enum drm_mode_status nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, @@ -831,6 +823,24 @@ nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; }
+static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_bridge_state
*bridge_state,
struct drm_crtc_state
*crtc_state,
struct drm_connector_state
*conn_state) +{
struct drm_display_mode *adjusted_mode = &crtc_state-
adjusted_mode;
/* At least LCDIF + NWL needs active high sync */
adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
DRM_MODE_FLAG_PVSYNC);
adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC |
DRM_MODE_FLAG_NVSYNC);
/* Do a full modeset if crtc_state->active is changed to be
true. */
if (crtc_state->active_changed && crtc_state->active)
crtc_state->mode_changed = true;
return 0;
+}
static void nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, @@ -862,7 +872,9 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, drm_mode_debug_printmodeline(adjusted_mode); }
-static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_bridge_state
*old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -897,7 +909,9 @@ static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) } }
-static void nwl_dsi_bridge_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_bridge_state
*old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -942,14 +956,17 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) }
static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
.pre_enable = nwl_dsi_bridge_pre_enable,
.enable = nwl_dsi_bridge_enable,
.disable = nwl_dsi_bridge_disable,
.mode_fixup = nwl_dsi_bridge_mode_fixup,
.mode_set = nwl_dsi_bridge_mode_set,
.mode_valid = nwl_dsi_bridge_mode_valid,
.attach = nwl_dsi_bridge_attach,
.detach = nwl_dsi_bridge_detach,
.atomic_duplicate_state =
drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state =
drm_atomic_helper_bridge_destroy_state,
.atomic_reset = drm_atomic_helper_bridge_reset,
.atomic_check = nwl_dsi_bridge_atomic_check,
.atomic_pre_enable = nwl_dsi_bridge_atomic_pre_enable,
.atomic_enable = nwl_dsi_bridge_atomic_enable,
.atomic_disable = nwl_dsi_bridge_atomic_disable,
.mode_set = nwl_dsi_bridge_mode_set,
.mode_valid = nwl_dsi_bridge_mode_valid,
.attach = nwl_dsi_bridge_attach,
.detach = nwl_dsi_bridge_detach,
};
static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
The check on unchanged HS clock rate in ->mode_set() improves the callback's performance a bit by early return. However, the up-coming patch would get MIPI DSI controller and PHY ready in ->mode_set() after that check, thus likely skipped. So, this patch removes that check to make sure MIPI DSI controller and PHY will be brought up and taken down from ->mode_set() and ->atomic_disable() respectively in pairs.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com --- v2->v3: * Split from the single patch in v2 to clarify changes. (Neil)
drivers/gpu/drm/bridge/nwl-dsi.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index c65ca860712d2..601ccc4a7cdc7 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -856,13 +856,6 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, if (ret < 0) return;
- /* - * If hs clock is unchanged, we're all good - all parameters are - * derived from it atm. - */ - if (new_cfg.mipi_dphy.hs_clk_rate == dsi->phy_cfg.mipi_dphy.hs_clk_rate) - return; - phy_ref_rate = clk_get_rate(dsi->phy_ref_clk); DRM_DEV_DEBUG_DRIVER(dev, "PHY at ref rate: %lu\n", phy_ref_rate); /* Save the new desired phy config */
On 23/04/2021 11:26, Liu Ying wrote:
The check on unchanged HS clock rate in ->mode_set() improves the callback's performance a bit by early return. However, the up-coming patch would get MIPI DSI controller and PHY ready in ->mode_set() after that check, thus likely skipped. So, this patch removes that check to make sure MIPI DSI controller and PHY will be brought up and taken down from ->mode_set() and ->atomic_disable() respectively in pairs.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com
v2->v3:
- Split from the single patch in v2 to clarify changes. (Neil)
drivers/gpu/drm/bridge/nwl-dsi.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index c65ca860712d2..601ccc4a7cdc7 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -856,13 +856,6 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, if (ret < 0) return;
- /*
* If hs clock is unchanged, we're all good - all parameters are
* derived from it atm.
*/
- if (new_cfg.mipi_dphy.hs_clk_rate == dsi->phy_cfg.mipi_dphy.hs_clk_rate)
return;
- phy_ref_rate = clk_get_rate(dsi->phy_ref_clk); DRM_DEV_DEBUG_DRIVER(dev, "PHY at ref rate: %lu\n", phy_ref_rate); /* Save the new desired phy config */
Reviewed-by: Neil Armstrong narmstrong@baylibre.com
Some MIPI DSI panel drivers like 'raydium,rm68200' send MIPI_DCS_SET_DISPLAY_ON commands in panel_funcs->prepare(), which requires the MIPI DSI controller and PHY to be ready beforehand. Without this patch, the nwl-dsi driver gets the MIPI DSI controller and PHY ready in bridge_funcs->atomic_pre_enable(), which happens after the panel_funcs->prepare(). So, this patch shifts the bridge operation ealier from bridge_funcs->atomic_pre_enable() to bridge_funcs->mode_set(). This way, more MIPI DSI panels can connect to this nwl-dsi bridge.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com --- v2->v3: * Split some changes to patch 1/3 and 2/3, to clarify changes. (Neil)
v1->v2: * Fix a typo in commit message - s/unchange/unchanged/
drivers/gpu/drm/bridge/nwl-dsi.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 601ccc4a7cdc7..873995f0a7416 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -662,7 +662,7 @@ static irqreturn_t nwl_dsi_irq_handler(int irq, void *data) return IRQ_HANDLED; }
-static int nwl_dsi_enable(struct nwl_dsi *dsi) +static int nwl_dsi_mode_set(struct nwl_dsi *dsi) { struct device *dev = dsi->dev; union phy_configure_opts *phy_cfg = &dsi->phy_cfg; @@ -834,7 +834,12 @@ static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge, adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
- /* Do a full modeset if crtc_state->active is changed to be true. */ + /* + * Do a full modeset if crtc_state->active is changed to be true. + * This ensures our ->mode_set() is called to get the DSI controller + * and the PHY ready to send DCS commands, when only the connector's + * DPMS is brought out of "Off" status. + */ if (crtc_state->active_changed && crtc_state->active) crtc_state->mode_changed = true;
@@ -863,16 +868,8 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
memcpy(&dsi->mode, adjusted_mode, sizeof(dsi->mode)); drm_mode_debug_printmodeline(adjusted_mode); -} - -static void -nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, - struct drm_bridge_state *old_bridge_state) -{ - struct nwl_dsi *dsi = bridge_to_dsi(bridge); - int ret;
- pm_runtime_get_sync(dsi->dev); + pm_runtime_get_sync(dev);
if (clk_prepare_enable(dsi->lcdif_clk) < 0) return; @@ -882,22 +879,22 @@ nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, /* Step 1 from DSI reset-out instructions */ ret = reset_control_deassert(dsi->rst_pclk); if (ret < 0) { - DRM_DEV_ERROR(dsi->dev, "Failed to deassert PCLK: %d\n", ret); + DRM_DEV_ERROR(dev, "Failed to deassert PCLK: %d\n", ret); return; }
/* Step 2 from DSI reset-out instructions */ - nwl_dsi_enable(dsi); + nwl_dsi_mode_set(dsi);
/* Step 3 from DSI reset-out instructions */ ret = reset_control_deassert(dsi->rst_esc); if (ret < 0) { - DRM_DEV_ERROR(dsi->dev, "Failed to deassert ESC: %d\n", ret); + DRM_DEV_ERROR(dev, "Failed to deassert ESC: %d\n", ret); return; } ret = reset_control_deassert(dsi->rst_byte); if (ret < 0) { - DRM_DEV_ERROR(dsi->dev, "Failed to deassert BYTE: %d\n", ret); + DRM_DEV_ERROR(dev, "Failed to deassert BYTE: %d\n", ret); return; } } @@ -953,7 +950,6 @@ static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_check = nwl_dsi_bridge_atomic_check, - .atomic_pre_enable = nwl_dsi_bridge_atomic_pre_enable, .atomic_enable = nwl_dsi_bridge_atomic_enable, .atomic_disable = nwl_dsi_bridge_atomic_disable, .mode_set = nwl_dsi_bridge_mode_set,
On 23/04/2021 11:26, Liu Ying wrote:
Some MIPI DSI panel drivers like 'raydium,rm68200' send MIPI_DCS_SET_DISPLAY_ON commands in panel_funcs->prepare(), which requires the MIPI DSI controller and PHY to be ready beforehand. Without this patch, the nwl-dsi driver gets the MIPI DSI controller and PHY ready in bridge_funcs->atomic_pre_enable(), which happens after the panel_funcs->prepare(). So, this patch shifts the bridge operation ealier from bridge_funcs->atomic_pre_enable() to bridge_funcs->mode_set(). This way, more MIPI DSI panels can connect to this nwl-dsi bridge.
Cc: Andrzej Hajda a.hajda@samsung.com Cc: Neil Armstrong narmstrong@baylibre.com Cc: Robert Foss robert.foss@linaro.org Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Jonas Karlman jonas@kwiboo.se Cc: Jernej Skrabec jernej.skrabec@siol.net Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: Guido Günther agx@sigxcpu.org Cc: Robert Chiras robert.chiras@nxp.com Cc: NXP Linux Team linux-imx@nxp.com Signed-off-by: Liu Ying victor.liu@nxp.com
v2->v3:
- Split some changes to patch 1/3 and 2/3, to clarify changes. (Neil)
v1->v2:
- Fix a typo in commit message - s/unchange/unchanged/
drivers/gpu/drm/bridge/nwl-dsi.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 601ccc4a7cdc7..873995f0a7416 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -662,7 +662,7 @@ static irqreturn_t nwl_dsi_irq_handler(int irq, void *data) return IRQ_HANDLED; }
-static int nwl_dsi_enable(struct nwl_dsi *dsi) +static int nwl_dsi_mode_set(struct nwl_dsi *dsi) { struct device *dev = dsi->dev; union phy_configure_opts *phy_cfg = &dsi->phy_cfg; @@ -834,7 +834,12 @@ static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge, adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
- /* Do a full modeset if crtc_state->active is changed to be true. */
- /*
* Do a full modeset if crtc_state->active is changed to be true.
* This ensures our ->mode_set() is called to get the DSI controller
* and the PHY ready to send DCS commands, when only the connector's
* DPMS is brought out of "Off" status.
if (crtc_state->active_changed && crtc_state->active) crtc_state->mode_changed = true;*/
@@ -863,16 +868,8 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
memcpy(&dsi->mode, adjusted_mode, sizeof(dsi->mode)); drm_mode_debug_printmodeline(adjusted_mode); -}
-static void -nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_bridge_state *old_bridge_state)
-{
struct nwl_dsi *dsi = bridge_to_dsi(bridge);
int ret;
pm_runtime_get_sync(dsi->dev);
pm_runtime_get_sync(dev);
if (clk_prepare_enable(dsi->lcdif_clk) < 0) return;
@@ -882,22 +879,22 @@ nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, /* Step 1 from DSI reset-out instructions */ ret = reset_control_deassert(dsi->rst_pclk); if (ret < 0) {
DRM_DEV_ERROR(dsi->dev, "Failed to deassert PCLK: %d\n", ret);
DRM_DEV_ERROR(dev, "Failed to deassert PCLK: %d\n", ret);
return; }
/* Step 2 from DSI reset-out instructions */
- nwl_dsi_enable(dsi);
nwl_dsi_mode_set(dsi);
/* Step 3 from DSI reset-out instructions */ ret = reset_control_deassert(dsi->rst_esc); if (ret < 0) {
DRM_DEV_ERROR(dsi->dev, "Failed to deassert ESC: %d\n", ret);
return; } ret = reset_control_deassert(dsi->rst_byte); if (ret < 0) {DRM_DEV_ERROR(dev, "Failed to deassert ESC: %d\n", ret);
DRM_DEV_ERROR(dsi->dev, "Failed to deassert BYTE: %d\n", ret);
return; }DRM_DEV_ERROR(dev, "Failed to deassert BYTE: %d\n", ret);
} @@ -953,7 +950,6 @@ static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_check = nwl_dsi_bridge_atomic_check,
- .atomic_pre_enable = nwl_dsi_bridge_atomic_pre_enable, .atomic_enable = nwl_dsi_bridge_atomic_enable, .atomic_disable = nwl_dsi_bridge_atomic_disable, .mode_set = nwl_dsi_bridge_mode_set,
Reviewed-by: Neil Armstrong narmstrong@baylibre.com
Hi,
On 23/04/2021 11:26, Liu Ying wrote:
Hi,
This series aims to make the nwl-dsi bridge be able to connect with more MIPI DSI panels. Some MIPI DSI panel drivers like 'raydium,rm68200' send MIPI_DCS_SET_DISPLAY_ON commands in panel_funcs->prepare(), which requires the MIPI DSI controller and PHY to be ready beforehand. However, the existing nwl-dsi driver gets the MIPI DSI controller and PHY ready in bridge_funcs->pre_enable(), which happens after the panel_funcs->prepare(). So, this series shifts the bridge operation ealier from bridge_funcs->pre_enable() to bridge_funcs->mode_set().
Patch 3/3 does the essential bridge operation shift.
Patch 1/3 and 2/3 are split from the original single patch in v2 and are needed by patch 3/3. This split-up helps clarify changes better. The split-up is done in this way:
- Patch 1/3 forces a full modeset when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). This makes sure ->mode_set() and ->atomic_disable() will be called in pairs.
- Patch 2/3 removes a check on unchanged HS clock rate from ->mode_set(), to make sure MIPI DSI controller and PHY are brought up and taken down in pairs.
- Patch 3/3 shifts the bridge operation as the last step.
v2->v3:
- Split the single patch in v2 into 3 patches. (Neil)
v1->v2:
- Fix a typo in commit message - s/unchange/unchanged/
Liu Ying (3): drm/bridge: nwl-dsi: Force a full modeset when crtc_state->active is changed to be true drm/bridge: nwl-dsi: Remove a check on unchanged HS clock rate from ->mode_set() drm/bridge: nwl-dsi: Get MIPI DSI controller and PHY ready in ->mode_set()
drivers/gpu/drm/bridge/nwl-dsi.c | 86 +++++++++++++++++--------------- 1 file changed, 46 insertions(+), 40 deletions(-)
The patchset looks fine, I'll leave a few days for Laurent or Rob to eventually comment.
Thanks, Neil
On 23/04/2021 11:26, Liu Ying wrote:
Hi,
This series aims to make the nwl-dsi bridge be able to connect with more MIPI DSI panels. Some MIPI DSI panel drivers like 'raydium,rm68200' send MIPI_DCS_SET_DISPLAY_ON commands in panel_funcs->prepare(), which requires the MIPI DSI controller and PHY to be ready beforehand. However, the existing nwl-dsi driver gets the MIPI DSI controller and PHY ready in bridge_funcs->pre_enable(), which happens after the panel_funcs->prepare(). So, this series shifts the bridge operation ealier from bridge_funcs->pre_enable() to bridge_funcs->mode_set().
Patch 3/3 does the essential bridge operation shift.
Patch 1/3 and 2/3 are split from the original single patch in v2 and are needed by patch 3/3. This split-up helps clarify changes better. The split-up is done in this way:
- Patch 1/3 forces a full modeset when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). This makes sure ->mode_set() and ->atomic_disable() will be called in pairs.
- Patch 2/3 removes a check on unchanged HS clock rate from ->mode_set(), to make sure MIPI DSI controller and PHY are brought up and taken down in pairs.
- Patch 3/3 shifts the bridge operation as the last step.
v2->v3:
- Split the single patch in v2 into 3 patches. (Neil)
v1->v2:
- Fix a typo in commit message - s/unchange/unchanged/
Liu Ying (3): drm/bridge: nwl-dsi: Force a full modeset when crtc_state->active is changed to be true drm/bridge: nwl-dsi: Remove a check on unchanged HS clock rate from ->mode_set() drm/bridge: nwl-dsi: Get MIPI DSI controller and PHY ready in ->mode_set()
drivers/gpu/drm/bridge/nwl-dsi.c | 86 +++++++++++++++++--------------- 1 file changed, 46 insertions(+), 40 deletions(-)
Applying to drm-misc-next
Thanks, Neil
Hi Liu, On Fri, Apr 23, 2021 at 05:26:40PM +0800, Liu Ying wrote:
Hi,
This series aims to make the nwl-dsi bridge be able to connect with more MIPI DSI panels. Some MIPI DSI panel drivers like 'raydium,rm68200' send MIPI_DCS_SET_DISPLAY_ON commands in panel_funcs->prepare(), which requires the MIPI DSI controller and PHY to be ready beforehand. However, the existing nwl-dsi driver gets the MIPI DSI controller and PHY ready in bridge_funcs->pre_enable(), which happens after the panel_funcs->prepare(). So, this series shifts the bridge operation ealier from bridge_funcs->pre_enable() to bridge_funcs->mode_set().
Patch 3/3 does the essential bridge operation shift.
Patch 1/3 and 2/3 are split from the original single patch in v2 and are needed by patch 3/3. This split-up helps clarify changes better. The split-up is done in this way:
- Patch 1/3 forces a full modeset when crtc_state->active is changed to be true(which implies only connector's DPMS is brought out of "Off" status, though not necessarily). This makes sure ->mode_set() and ->atomic_disable() will be called in pairs.
- Patch 2/3 removes a check on unchanged HS clock rate from ->mode_set(), to make sure MIPI DSI controller and PHY are brought up and taken down in pairs.
- Patch 3/3 shifts the bridge operation as the last step.
Looks good to me and tested on imx8mq Librem 5 Devkit with
https://lore.kernel.org/linux-arm-kernel/cover.1617968250.git.agx@sigxcpu.or...
on top so
Reviewed-by: Guido Günther agx@sigxcpu.org Tested-by: Guido Günther agx@sigxcpu.org
Cheers, -- Guido
v2->v3:
- Split the single patch in v2 into 3 patches. (Neil)
v1->v2:
- Fix a typo in commit message - s/unchange/unchanged/
Liu Ying (3): drm/bridge: nwl-dsi: Force a full modeset when crtc_state->active is changed to be true drm/bridge: nwl-dsi: Remove a check on unchanged HS clock rate from ->mode_set() drm/bridge: nwl-dsi: Get MIPI DSI controller and PHY ready in ->mode_set()
drivers/gpu/drm/bridge/nwl-dsi.c | 86 +++++++++++++++++--------------- 1 file changed, 46 insertions(+), 40 deletions(-)
-- 2.25.1
dri-devel@lists.freedesktop.org