[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <9aedfb528600ecf871885f7293ca4207c84d16c1.camel@gmail.com>
Date: Thu, 21 Jan 2021 13:13:17 +0200
From: aleksandr.o.makarov@...il.com
To: Thomas Hebb <tommyhebb@...il.com>, linux-kernel@...r.kernel.org,
Nickey Yang <nickey.yang@...k-chips.com>,
Heiko Stuebner <heiko@...ech.de>,
Andrzej Hajda <a.hajda@...sung.com>
Cc: Archit Taneja <architt@...eaurora.org>,
David Airlie <airlied@...ux.ie>,
Brian Norris <briannorris@...omium.org>,
Sandy Huang <hjc@...k-chips.com>,
dri-devel@...ts.freedesktop.org,
linux-rockchip@...ts.infradead.org,
Sean Paul <seanpaul@...omium.org>,
Daniel Vetter <daniel@...ll.ch>,
linux-arm-kernel@...ts.infradead.org
Subject: Re: [RESEND PATCH] drm/rockchip: dsi: move all lane config except
LCDC mux to bind()
В Вс, 13/12/2020 в 12:58 -0800, Thomas Hebb пишет:
> When we first enable the DSI encoder, we currently program some per-chip
> configuration that we look up in rk3399_chip_data based on the device
> tree compatible we match. This data configures various parameters of the
> MIPI lanes, including on RK3399 whether DSI1 is slaved to DSI0 in a
> dual-mode configuration. It also selects which LCDC (i.e. VOP) to scan
> out from.
>
> This causes a problem in RK3399 dual-mode configurations, though: panel
> prepare() callbacks run before the encoder gets enabled and expect to be
> able to write commands to the DSI bus, but the bus isn't fully
> functional until the lane and master/slave configuration have been
> programmed. As a result, dual-mode panels (and possibly others too) fail
> to turn on when the rockchipdrm driver is initially loaded.
>
> Because the LCDC mux is the only thing we don't know until enable time
> (and is the only thing that can ever change), we can actually move most
> of the initialization to bind() and get it out of the way early. That's
> what this change does. (Rockchip's 4.4 BSP kernel does it in mode_set(),
> which also avoids the issue, but bind() seems like the more correct
> place to me.)
>
> Tested on a Google Scarlet board (Acer Chromebook Tab 10), which has a
> Kingdisplay KD097D04 dual-mode panel. Prior to this change, the panel's
> backlight would turn on but no image would appear when initially loading
> rockchipdrm. If I kept rockchipdrm loaded and reloaded the panel driver,
> it would come on. With this change, the panel successfully turns on
> during initial rockchipdrm load as expected.
>
> Fixes: 2d4f7bdafd70 ("drm/rockchip: dsi: migrate to use dw-mipi-dsi bridge driver")
> Signed-off-by: Thomas Hebb <tommyhebb@...il.com>
> ---
> Resending since I wasn't subscribed to dri-devel
>
> .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 36 ++++++++++++++-----
> 1 file changed, 28 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> index ce044db8c97e..d0c9610ad220 100644
> --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> @@ -691,13 +691,8 @@ static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = {
> .get_timing = dw_mipi_dsi_phy_get_timing,
> };
>
>
> -static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi,
> - int mux)
> +static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi)
> {
> - if (dsi->cdata->lcdsel_grf_reg)
> - regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
> - mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
> -
> if (dsi->cdata->lanecfg1_grf_reg)
> regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg,
> dsi->cdata->lanecfg1);
> @@ -711,6 +706,13 @@ static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi,
> dsi->cdata->enable);
> }
>
>
> +static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi,
> + int mux)
> +{
> + regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
> + mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
> +}
> +
> static int
> dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
> struct drm_crtc_state *crtc_state,
> @@ -766,9 +768,9 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
> return;
> }
>
>
> - dw_mipi_dsi_rockchip_config(dsi, mux);
> + dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux);
> if (dsi->slave)
> - dw_mipi_dsi_rockchip_config(dsi->slave, mux);
> + dw_mipi_dsi_rockchip_set_lcdsel(dsi->slave, mux);
>
>
> clk_disable_unprepare(dsi->grf_clk);
> }
> @@ -922,6 +924,24 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
> return ret;
> }
>
>
> + /*
> + * With the GRF clock running, write lane and dual-mode configurations
> + * that won't change immediately. If we waited until enable() to do
> + * this, things like panel preparation would not be able to send
> + * commands over DSI.
> + */
> + ret = clk_prepare_enable(dsi->grf_clk);
> + if (ret) {
> + DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret);
> + return ret;
> + }
> +
> + dw_mipi_dsi_rockchip_config(dsi);
> + if (dsi->slave)
> + dw_mipi_dsi_rockchip_config(dsi->slave);
> +
> + clk_disable_unprepare(dsi->grf_clk);
> +
> ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev);
> if (ret) {
> DRM_DEV_ERROR(dev, "Failed to create drm encoder\n");
Have tested this patch on a Pine64 RockPro64 v2.1 with Linux v5.4.44
All works good when DRM_PANEL_KINGDISPLAY_KD097D04=m
Something bad happens when DRM_PANEL_KINGDISPLAY_KD097D04=y - the panel
driver starts again to fail to write prepare() commands to DSI:
[ 28.709049] 005: dw-mipi-dsi-rockchip ff960000.mipi: failed to write
command FIFO
[ 28.709056] 005: panel-kingdisplay-kd097d04 ff960000.mipi.0:
[drm:kingdisplay_panel_prepare] *ERROR* failed write init cmds: -110
View attachment "dmesg-21-01-2021-13:02" of type "text/plain" (26251 bytes)
Powered by blists - more mailing lists