[Freedreno] [PATCH v5 06/21] drm/bridge: lt8912b: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/lontium-lt8912b.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c index cc968d65936b..c642d1e02b2f 100644 --- a/drivers/gpu/drm/bridge/lontium-lt8912b.c +++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c @@ -544,10 +544,6 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge, if (ret) goto error; - ret = lt8912_attach_dsi(lt); - if (ret) - goto error; - lt->is_attached = true; return 0; @@ -706,8 +702,15 @@ static int lt8912_probe(struct i2c_client *client, drm_bridge_add(<->bridge); + ret = lt8912_attach_dsi(lt); + if (ret) + goto err_attach; + return 0; +err_attach: + drm_bridge_remove(<->bridge); + lt8912_free_i2c(lt); err_i2c: lt8912_put_dt(lt); err_dt_parse: -- 2.31.1
[Freedreno] [PATCH v5 00/21] drm/bridge: Make panel and bridge probe order consistent
Hi, We've encountered an issue with the RaspberryPi DSI panel that prevented the whole display driver from probing. The issue is described in detail in the commit 7213246a803f ("drm/vc4: dsi: Only register our component once a DSI device is attached"), but the basic idea is that since the panel is probed through i2c, there's no synchronization between its probe and the registration of the MIPI-DSI host it's attached to. We initially moved the component framework registration to the MIPI-DSI Host attach hook to make sure we register our component only when we have a DSI device attached to our MIPI-DSI host, and then use lookup our DSI device in our bind hook. However, all the DSI bridges controlled through i2c are only registering their associated DSI device in their bridge attach hook, meaning with our change above, we never got that far, and therefore ended up in the same situation than the one we were trying to fix for panels. The best practice to avoid those issues is to register its functions only after all its dependencies are live. We also shouldn't wait any longer than we should to play nice with the other components that are waiting for us, so in our case that would mean moving the DSI device registration to the bridge probe. This has been tested on vc4 (with sn65dsi83 and ps8640), msm (sn65dsi86, lt9611), kirin (adv7511) and exynos. Let me know what you think, Maxime --- Changes from v4: - Rebased on current drm-misc-next - Collected the various tags - Fix for Kirin - Added conversion patch for msm Changes from v3: - Converted exynos and kirin - Converted all the affected bridge drivers - Reworded the documentation a bit Changes from v2: - Changed the approach as suggested by Andrzej, and aligned the bridge on the panel this time. - Fixed some typos Changes from v1: - Change the name of drm_of_get_next function to drm_of_get_bridge - Mention the revert of 87154ff86bf6 and squash the two patches that were reverting that commit - Add some documentation - Make drm_panel_attach and _detach succeed when no callback is there Maxime Ripard (20): drm/bridge: adv7533: Switch to devm MIPI-DSI helpers drm/bridge: adv7511: Register and attach our DSI device at probe drm/bridge: anx7625: Switch to devm MIPI-DSI helpers drm/bridge: anx7625: Register and attach our DSI device at probe drm/bridge: lt8912b: Switch to devm MIPI-DSI helpers drm/bridge: lt8912b: Register and attach our DSI device at probe drm/bridge: lt9611: Switch to devm MIPI-DSI helpers drm/bridge: lt9611: Register and attach our DSI device at probe drm/bridge: lt9611uxc: Switch to devm MIPI-DSI helpers drm/bridge: lt9611uxc: Register and attach our DSI device at probe drm/bridge: ps8640: Switch to devm MIPI-DSI helpers drm/bridge: ps8640: Register and attach our DSI device at probe drm/bridge: sn65dsi83: Fix bridge removal drm/bridge: sn65dsi83: Switch to devm MIPI-DSI helpers drm/bridge: sn65dsi83: Register and attach our DSI device at probe drm/bridge: sn65dsi86: Switch to devm MIPI-DSI helpers drm/bridge: sn65dsi86: Register and attach our DSI device at probe drm/bridge: tc358775: Switch to devm MIPI-DSI helpers drm/bridge: tc358775: Register and attach our DSI device at probe drm/kirin: dsi: Adjust probe order Rob Clark (1): drm/msm/dsi: Adjust probe order drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 - drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 15 ++- drivers/gpu/drm/bridge/adv7511/adv7533.c | 20 +--- drivers/gpu/drm/bridge/analogix/anx7625.c| 40 --- drivers/gpu/drm/bridge/lontium-lt8912b.c | 31 ++ drivers/gpu/drm/bridge/lontium-lt9611.c | 62 --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 65 +-- drivers/gpu/drm/bridge/parade-ps8640.c | 107 ++- drivers/gpu/drm/bridge/tc358775.c| 50 + drivers/gpu/drm/bridge/ti-sn65dsi83.c| 88 --- drivers/gpu/drm/bridge/ti-sn65dsi86.c| 101 + drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 52 + drivers/gpu/drm/msm/dsi/dsi.c| 50 + drivers/gpu/drm/msm/dsi/dsi.h| 2 +- drivers/gpu/drm/msm/dsi/dsi_host.c | 22 ++-- drivers/gpu/drm/msm/dsi/dsi_manager.c| 6 +- drivers/gpu/drm/msm/msm_drv.h| 2 + 17 files changed, 348 insertions(+), 366 deletions(-) -- 2.31.1
[Freedreno] [PATCH v5 07/21] drm/bridge: lt9611: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. Acked-by: Sam Ravnborg Tested-by: John Stultz Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/lontium-lt9611.c | 24 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 29b1ce2140ab..654131aca5ed 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -760,6 +760,7 @@ static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611, const struct mipi_dsi_device_info info = { "lt9611", 0, NULL }; struct mipi_dsi_device *dsi; struct mipi_dsi_host *host; + struct device *dev = lt9611->dev; int ret; host = of_find_mipi_dsi_host_by_node(dsi_node); @@ -768,7 +769,7 @@ static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611, return ERR_PTR(-EPROBE_DEFER); } - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { dev_err(lt9611->dev, "failed to create dsi device\n"); return dsi; @@ -779,29 +780,15 @@ static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611, dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_HSE; - ret = mipi_dsi_attach(dsi); + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { - dev_err(lt9611->dev, "failed to attach dsi to host\n"); - mipi_dsi_device_unregister(dsi); + dev_err(dev, "failed to attach dsi to host\n"); return ERR_PTR(ret); } return dsi; } -static void lt9611_bridge_detach(struct drm_bridge *bridge) -{ - struct lt9611 *lt9611 = bridge_to_lt9611(bridge); - - if (lt9611->dsi1) { - mipi_dsi_detach(lt9611->dsi1); - mipi_dsi_device_unregister(lt9611->dsi1); - } - - mipi_dsi_detach(lt9611->dsi0); - mipi_dsi_device_unregister(lt9611->dsi0); -} - static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 *lt9611) { int ret; @@ -855,9 +842,7 @@ static int lt9611_bridge_attach(struct drm_bridge *bridge, return 0; err_unregister_dsi0: - lt9611_bridge_detach(bridge); drm_connector_cleanup(<9611->connector); - mipi_dsi_device_unregister(lt9611->dsi0); return ret; } @@ -952,7 +937,6 @@ static void lt9611_bridge_hpd_enable(struct drm_bridge *bridge) static const struct drm_bridge_funcs lt9611_bridge_funcs = { .attach = lt9611_bridge_attach, - .detach = lt9611_bridge_detach, .mode_valid = lt9611_bridge_mode_valid, .enable = lt9611_bridge_enable, .disable = lt9611_bridge_disable, -- 2.31.1
[Freedreno] [PATCH v5 02/21] drm/bridge: adv7511: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Tested-by: John Stultz Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 9e3585f23cf1..f8e5da148599 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -910,9 +910,6 @@ static int adv7511_bridge_attach(struct drm_bridge *bridge, return ret; } - if (adv->type == ADV7533 || adv->type == ADV7535) - ret = adv7533_attach_dsi(adv); - if (adv->i2c_main->irq) regmap_write(adv->regmap, ADV7511_REG_INT_ENABLE(0), ADV7511_INT0_HPD); @@ -1288,8 +1285,18 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) drm_bridge_add(&adv7511->bridge); adv7511_audio_init(dev, adv7511); + + if (adv7511->type == ADV7533 || adv7511->type == ADV7535) { + ret = adv7533_attach_dsi(adv7511); + if (ret) + goto err_unregister_audio; + } + return 0; +err_unregister_audio: + adv7511_audio_exit(adv7511); + drm_bridge_remove(&adv7511->bridge); err_unregister_cec: i2c_unregister_device(adv7511->i2c_cec); clk_disable_unprepare(adv7511->cec_clk); -- 2.31.1
[Freedreno] [PATCH v5 03/21] drm/bridge: anx7625: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/analogix/anx7625.c | 20 +--- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 1a871f6b6822..4adeb2bad03a 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1316,6 +1316,7 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) .channel = 0, .node = NULL, }; + int ret; DRM_DEV_DEBUG_DRIVER(dev, "attach dsi\n"); @@ -1325,7 +1326,7 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) return -EINVAL; } - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { DRM_DEV_ERROR(dev, "fail to create dsi device.\n"); return -EINVAL; @@ -1337,10 +1338,10 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_HSE; - if (mipi_dsi_attach(dsi) < 0) { + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret) { DRM_DEV_ERROR(dev, "fail to attach dsi to host.\n"); - mipi_dsi_device_unregister(dsi); - return -EINVAL; + return ret; } ctx->dsi = dsi; @@ -1350,16 +1351,6 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx) return 0; } -static void anx7625_bridge_detach(struct drm_bridge *bridge) -{ - struct anx7625_data *ctx = bridge_to_anx7625(bridge); - - if (ctx->dsi) { - mipi_dsi_detach(ctx->dsi); - mipi_dsi_device_unregister(ctx->dsi); - } -} - static int anx7625_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { @@ -1624,7 +1615,6 @@ static struct edid *anx7625_bridge_get_edid(struct drm_bridge *bridge, static const struct drm_bridge_funcs anx7625_bridge_funcs = { .attach = anx7625_bridge_attach, - .detach = anx7625_bridge_detach, .disable = anx7625_bridge_disable, .mode_valid = anx7625_bridge_mode_valid, .mode_set = anx7625_bridge_mode_set, -- 2.31.1
[Freedreno] [PATCH v5 09/21] drm/bridge: lt9611uxc: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 38 +- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 010657ea7af7..ab1a0c00aad8 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -258,17 +258,18 @@ static struct mipi_dsi_device *lt9611uxc_attach_dsi(struct lt9611uxc *lt9611uxc, const struct mipi_dsi_device_info info = { "lt9611uxc", 0, NULL }; struct mipi_dsi_device *dsi; struct mipi_dsi_host *host; + struct device *dev = lt9611uxc->dev; int ret; host = of_find_mipi_dsi_host_by_node(dsi_node); if (!host) { - dev_err(lt9611uxc->dev, "failed to find dsi host\n"); + dev_err(dev, "failed to find dsi host\n"); return ERR_PTR(-EPROBE_DEFER); } - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { - dev_err(lt9611uxc->dev, "failed to create dsi device\n"); + dev_err(dev, "failed to create dsi device\n"); return dsi; } @@ -277,10 +278,9 @@ static struct mipi_dsi_device *lt9611uxc_attach_dsi(struct lt9611uxc *lt9611uxc, dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_HSE; - ret = mipi_dsi_attach(dsi); + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { - dev_err(lt9611uxc->dev, "failed to attach dsi to host\n"); - mipi_dsi_device_unregister(dsi); + dev_err(dev, "failed to attach dsi to host\n"); return ERR_PTR(ret); } @@ -355,19 +355,6 @@ static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc return drm_connector_attach_encoder(<9611uxc->connector, bridge->encoder); } -static void lt9611uxc_bridge_detach(struct drm_bridge *bridge) -{ - struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge); - - if (lt9611uxc->dsi1) { - mipi_dsi_detach(lt9611uxc->dsi1); - mipi_dsi_device_unregister(lt9611uxc->dsi1); - } - - mipi_dsi_detach(lt9611uxc->dsi0); - mipi_dsi_device_unregister(lt9611uxc->dsi0); -} - static int lt9611uxc_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { @@ -388,19 +375,11 @@ static int lt9611uxc_bridge_attach(struct drm_bridge *bridge, /* Attach secondary DSI, if specified */ if (lt9611uxc->dsi1_node) { lt9611uxc->dsi1 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi1_node); - if (IS_ERR(lt9611uxc->dsi1)) { - ret = PTR_ERR(lt9611uxc->dsi1); - goto err_unregister_dsi0; - } + if (IS_ERR(lt9611uxc->dsi1)) + return PTR_ERR(lt9611uxc->dsi1); } return 0; - -err_unregister_dsi0: - mipi_dsi_detach(lt9611uxc->dsi0); - mipi_dsi_device_unregister(lt9611uxc->dsi0); - - return ret; } static enum drm_mode_status @@ -544,7 +523,6 @@ static struct edid *lt9611uxc_bridge_get_edid(struct drm_bridge *bridge, static const struct drm_bridge_funcs lt9611uxc_bridge_funcs = { .attach = lt9611uxc_bridge_attach, - .detach = lt9611uxc_bridge_detach, .mode_valid = lt9611uxc_bridge_mode_valid, .mode_set = lt9611uxc_bridge_mode_set, .detect = lt9611uxc_bridge_detect, -- 2.31.1
[Freedreno] [PATCH v5 05/21] drm/bridge: lt8912b: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/lontium-lt8912b.c | 20 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c index 1b0c7eaf6c84..cc968d65936b 100644 --- a/drivers/gpu/drm/bridge/lontium-lt8912b.c +++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c @@ -472,11 +472,11 @@ static int lt8912_attach_dsi(struct lt8912 *lt) return -EPROBE_DEFER; } - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { ret = PTR_ERR(dsi); dev_err(dev, "failed to create dsi device (%d)\n", ret); - goto err_dsi_device; + return ret; } lt->dsi = dsi; @@ -489,24 +489,13 @@ static int lt8912_attach_dsi(struct lt8912 *lt) MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET; - ret = mipi_dsi_attach(dsi); + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { dev_err(dev, "failed to attach dsi to host\n"); - goto err_dsi_attach; + return ret; } return 0; - -err_dsi_attach: - mipi_dsi_device_unregister(dsi); -err_dsi_device: - return ret; -} - -static void lt8912_detach_dsi(struct lt8912 *lt) -{ - mipi_dsi_detach(lt->dsi); - mipi_dsi_device_unregister(lt->dsi); } static int lt8912_bridge_connector_init(struct drm_bridge *bridge) @@ -573,7 +562,6 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge) struct lt8912 *lt = bridge_to_lt8912(bridge); if (lt->is_attached) { - lt8912_detach_dsi(lt); lt8912_hard_power_off(lt); drm_connector_unregister(<->connector); drm_connector_cleanup(<->connector); -- 2.31.1
[Freedreno] [PATCH v5 04/21] drm/bridge: anx7625: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/analogix/anx7625.c | 20 ++-- 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 4adeb2bad03a..d0317651cd75 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1367,12 +1367,6 @@ static int anx7625_bridge_attach(struct drm_bridge *bridge, return -ENODEV; } - err = anx7625_attach_dsi(ctx); - if (err) { - DRM_DEV_ERROR(dev, "Fail to attach to dsi : %d\n", err); - return err; - } - if (ctx->pdata.panel_bridge) { err = drm_bridge_attach(bridge->encoder, ctx->pdata.panel_bridge, @@ -1845,10 +1839,24 @@ static int anx7625_i2c_probe(struct i2c_client *client, platform->bridge.type = DRM_MODE_CONNECTOR_eDP; drm_bridge_add(&platform->bridge); + ret = anx7625_attach_dsi(platform); + if (ret) { + DRM_DEV_ERROR(dev, "Fail to attach to dsi : %d\n", ret); + goto unregister_bridge; + } + DRM_DEV_DEBUG_DRIVER(dev, "probe done\n"); return 0; +unregister_bridge: + drm_bridge_remove(&platform->bridge); + + if (!platform->pdata.low_power_mode) + pm_runtime_put_sync_suspend(&client->dev); + + anx7625_unregister_i2c_dummy_clients(platform); + free_wq: if (platform->workqueue) destroy_workqueue(platform->workqueue); -- 2.31.1
[Freedreno] [PATCH v5 01/21] drm/bridge: adv7533: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. This also avoids leaking the device when we detach the bridge. Acked-by: Sam Ravnborg Tested-by: John Stultz Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 - drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 -- drivers/gpu/drm/bridge/adv7511/adv7533.c | 20 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 05e3abb5a0c9..592ecfcf00ca 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -401,7 +401,6 @@ void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode); int adv7533_patch_registers(struct adv7511 *adv); int adv7533_patch_cec_registers(struct adv7511 *adv); int adv7533_attach_dsi(struct adv7511 *adv); -void adv7533_detach_dsi(struct adv7511 *adv); int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv); #ifdef CONFIG_DRM_I2C_ADV7511_AUDIO diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 76555ae64e9c..9e3585f23cf1 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1307,8 +1307,6 @@ static int adv7511_remove(struct i2c_client *i2c) { struct adv7511 *adv7511 = i2c_get_clientdata(i2c); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) - adv7533_detach_dsi(adv7511); i2c_unregister_device(adv7511->i2c_cec); clk_disable_unprepare(adv7511->cec_clk); diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index 59d718bde8c4..eb7579dec40a 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -153,11 +153,10 @@ int adv7533_attach_dsi(struct adv7511 *adv) return -EPROBE_DEFER; } - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { dev_err(dev, "failed to create dsi device\n"); - ret = PTR_ERR(dsi); - goto err_dsi_device; + return PTR_ERR(dsi); } adv->dsi = dsi; @@ -167,24 +166,13 @@ int adv7533_attach_dsi(struct adv7511 *adv) dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE; - ret = mipi_dsi_attach(dsi); + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { dev_err(dev, "failed to attach dsi to host\n"); - goto err_dsi_attach; + return ret; } return 0; - -err_dsi_attach: - mipi_dsi_device_unregister(dsi); -err_dsi_device: - return ret; -} - -void adv7533_detach_dsi(struct adv7511 *adv) -{ - mipi_dsi_detach(adv->dsi); - mipi_dsi_device_unregister(adv->dsi); } int adv7533_parse_dt(struct device_node *np, struct adv7511 *adv) -- 2.31.1
[Freedreno] [PATCH v5 08/21] drm/bridge: lt9611: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Tested-by: John Stultz Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/lontium-lt9611.c | 38 - 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index 654131aca5ed..d2f45a0f79c8 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -825,26 +825,7 @@ static int lt9611_bridge_attach(struct drm_bridge *bridge, return ret; } - /* Attach primary DSI */ - lt9611->dsi0 = lt9611_attach_dsi(lt9611, lt9611->dsi0_node); - if (IS_ERR(lt9611->dsi0)) - return PTR_ERR(lt9611->dsi0); - - /* Attach secondary DSI, if specified */ - if (lt9611->dsi1_node) { - lt9611->dsi1 = lt9611_attach_dsi(lt9611, lt9611->dsi1_node); - if (IS_ERR(lt9611->dsi1)) { - ret = PTR_ERR(lt9611->dsi1); - goto err_unregister_dsi0; - } - } - return 0; - -err_unregister_dsi0: - drm_connector_cleanup(<9611->connector); - - return ret; } static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge, @@ -1165,10 +1146,29 @@ static int lt9611_probe(struct i2c_client *client, drm_bridge_add(<9611->bridge); + /* Attach primary DSI */ + lt9611->dsi0 = lt9611_attach_dsi(lt9611, lt9611->dsi0_node); + if (IS_ERR(lt9611->dsi0)) { + ret = PTR_ERR(lt9611->dsi0); + goto err_remove_bridge; + } + + /* Attach secondary DSI, if specified */ + if (lt9611->dsi1_node) { + lt9611->dsi1 = lt9611_attach_dsi(lt9611, lt9611->dsi1_node); + if (IS_ERR(lt9611->dsi1)) { + ret = PTR_ERR(lt9611->dsi1); + goto err_remove_bridge; + } + } + lt9611_enable_hpd_interrupts(lt9611); return lt9611_audio_init(dev, lt9611); +err_remove_bridge: + drm_bridge_remove(<9611->bridge); + err_disable_regulators: regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies); -- 2.31.1
[Freedreno] [PATCH v5 19/21] drm/bridge: tc358775: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/tc358775.c | 37 +-- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358775.c b/drivers/gpu/drm/bridge/tc358775.c index 35e66d1b6456..2c76331b251d 100644 --- a/drivers/gpu/drm/bridge/tc358775.c +++ b/drivers/gpu/drm/bridge/tc358775.c @@ -594,11 +594,26 @@ static int tc_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { struct tc_data *tc = bridge_to_tc(bridge); + + /* Attach the panel-bridge to the dsi bridge */ + return drm_bridge_attach(bridge->encoder, tc->panel_bridge, +&tc->bridge, flags); +} + +static const struct drm_bridge_funcs tc_bridge_funcs = { + .attach = tc_bridge_attach, + .pre_enable = tc_bridge_pre_enable, + .enable = tc_bridge_enable, + .mode_valid = tc_mode_valid, + .post_disable = tc_bridge_post_disable, +}; + +static int tc_attach_host(struct tc_data *tc) +{ struct device *dev = &tc->i2c->dev; struct mipi_dsi_host *host; struct mipi_dsi_device *dsi; int ret; - const struct mipi_dsi_device_info info = { .type = "tc358775", .channel = 0, .node = NULL, @@ -628,19 +643,9 @@ static int tc_bridge_attach(struct drm_bridge *bridge, return ret; } - /* Attach the panel-bridge to the dsi bridge */ - return drm_bridge_attach(bridge->encoder, tc->panel_bridge, -&tc->bridge, flags); + return 0; } -static const struct drm_bridge_funcs tc_bridge_funcs = { - .attach = tc_bridge_attach, - .pre_enable = tc_bridge_pre_enable, - .enable = tc_bridge_enable, - .mode_valid = tc_mode_valid, - .post_disable = tc_bridge_post_disable, -}; - static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; @@ -704,7 +709,15 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) i2c_set_clientdata(client, tc); + ret = tc_attach_host(tc); + if (ret) + goto err_bridge_remove; + return 0; + +err_bridge_remove: + drm_bridge_remove(&tc->bridge); + return ret; } static int tc_remove(struct i2c_client *client) -- 2.31.1
[Freedreno] [PATCH v5 17/21] drm/bridge: sn65dsi86: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 77 ++- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 36a82e3d17ab..b6ce6776cdf1 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -655,58 +655,27 @@ static struct ti_sn65dsi86 *bridge_to_ti_sn65dsi86(struct drm_bridge *bridge) return container_of(bridge, struct ti_sn65dsi86, bridge); } -static int ti_sn_bridge_attach(struct drm_bridge *bridge, - enum drm_bridge_attach_flags flags) +static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata) { int ret, val; - struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); struct mipi_dsi_host *host; struct mipi_dsi_device *dsi; struct device *dev = pdata->dev; const struct mipi_dsi_device_info info = { .type = "ti_sn_bridge", .channel = 0, .node = NULL, -}; + }; - if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { - DRM_ERROR("Fix bridge driver to make connector optional!"); - return -EINVAL; - } - - pdata->aux.drm_dev = bridge->dev; - ret = drm_dp_aux_register(&pdata->aux); - if (ret < 0) { - drm_err(bridge->dev, "Failed to register DP AUX channel: %d\n", ret); - return ret; - } - - ret = ti_sn_bridge_connector_init(pdata); - if (ret < 0) - goto err_conn_init; - - /* -* TODO: ideally finding host resource and dsi dev registration needs -* to be done in bridge probe. But some existing DSI host drivers will -* wait for any of the drm_bridge/drm_panel to get added to the global -* bridge/panel list, before completing their probe. So if we do the -* dsi dev registration part in bridge probe, before populating in -* the global bridge list, then it will cause deadlock as dsi host probe -* will never complete, neither our bridge probe. So keeping it here -* will satisfy most of the existing host drivers. Once the host driver -* is fixed we can move the below code to bridge probe safely. -*/ host = of_find_mipi_dsi_host_by_node(pdata->host_node); if (!host) { DRM_ERROR("failed to find dsi host\n"); - ret = -ENODEV; - goto err_dsi_host; + return -ENODEV; } dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { DRM_ERROR("failed to create dsi device\n"); - ret = PTR_ERR(dsi); - goto err_dsi_host; + return PTR_ERR(dsi); } /* TODO: setting to 4 MIPI lanes always for now */ @@ -721,12 +690,38 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, if (!(val & DPPLL_CLK_SRC_DSICLK)) dsi->mode_flags |= MIPI_DSI_CLOCK_NON_CONTINUOUS; + pdata->dsi = dsi; + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { DRM_ERROR("failed to attach dsi to host\n"); - goto err_dsi_host; + return ret; } - pdata->dsi = dsi; + + return 0; +} + +static int ti_sn_bridge_attach(struct drm_bridge *bridge, + enum drm_bridge_attach_flags flags) +{ + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); + int ret; + + if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { + DRM_ERROR("Fix bridge driver to make connector optional!"); + return -EINVAL; + } + + pdata->aux.drm_dev = bridge->dev; + ret = drm_dp_aux_register(&pdata->aux); + if (ret < 0) { + drm_err(bridge->dev, "Failed to register DP AUX channel: %d\n", ret); + return ret; + } + + ret = ti_sn_bridge_connector_init(pdata); + if (ret < 0) + goto err_conn_init; /* We never want the next bridge to *also* create a connector: */ flags |= DRM_BRIDGE_ATTACH_NO_CONNECTOR; @@ -1224,7 +1219,15 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, drm_bridge_add(&pdata->bridge); + ret = ti_sn_attach_host(pdata); + if (ret) + goto err_remove_bridge; + return 0; + +err_remove_bridge: + drm_bridge_remove(&pdata->bridge); + return ret; } static void ti_sn_bridge_remove(struct auxiliary_device *adev) -- 2.31.1
[Freedreno] [PATCH v5 13/21] drm/bridge: sn65dsi83: Fix bridge removal
Commit 24417d5b0c00 ("drm/bridge: ti-sn65dsi83: Implement .detach callback") moved the unregistration of the bridge DSI device and bridge itself to the detach callback. While this is correct for the DSI device detach and unregistration, the bridge is added in the driver probe, and should thus be removed as part of its remove callback. Cc: Marek Vasut Fixes: 24417d5b0c00 ("drm/bridge: ti-sn65dsi83: Implement .detach callback") Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index 52030a82f3e1..3bfd07caf8d7 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -297,7 +297,6 @@ static void sn65dsi83_detach(struct drm_bridge *bridge) mipi_dsi_detach(ctx->dsi); mipi_dsi_device_unregister(ctx->dsi); - drm_bridge_remove(&ctx->bridge); ctx->dsi = NULL; } @@ -693,6 +692,7 @@ static int sn65dsi83_remove(struct i2c_client *client) { struct sn65dsi83 *ctx = i2c_get_clientdata(client); + drm_bridge_remove(&ctx->bridge); of_node_put(ctx->host_node); return 0; -- 2.31.1
[Freedreno] [PATCH v5 15/21] drm/bridge: sn65dsi83: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Tested-by: Laurent Pinchart Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 80 +++ 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index 539edd2c19f5..945f08de45f1 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -245,40 +245,6 @@ static int sn65dsi83_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge); - struct device *dev = ctx->dev; - struct mipi_dsi_device *dsi; - struct mipi_dsi_host *host; - int ret = 0; - - const struct mipi_dsi_device_info info = { - .type = "sn65dsi83", - .channel = 0, - .node = NULL, - }; - - host = of_find_mipi_dsi_host_by_node(ctx->host_node); - if (!host) { - dev_err(dev, "failed to find dsi host\n"); - return -EPROBE_DEFER; - } - - dsi = devm_mipi_dsi_device_register_full(dev, host, &info); - if (IS_ERR(dsi)) { - return dev_err_probe(dev, PTR_ERR(dsi), -"failed to create dsi device\n"); - } - - ctx->dsi = dsi; - - dsi->lanes = ctx->dsi_lanes; - dsi->format = MIPI_DSI_FMT_RGB888; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; - - ret = devm_mipi_dsi_attach(dev, dsi); - if (ret < 0) { - dev_err(dev, "failed to attach dsi to host\n"); - return ret; - } return drm_bridge_attach(bridge->encoder, ctx->panel_bridge, &ctx->bridge, flags); @@ -636,6 +602,44 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model) return 0; } +static int sn65dsi83_host_attach(struct sn65dsi83 *ctx) +{ + struct device *dev = ctx->dev; + struct mipi_dsi_device *dsi; + struct mipi_dsi_host *host; + const struct mipi_dsi_device_info info = { + .type = "sn65dsi83", + .channel = 0, + .node = NULL, + }; + int ret; + + host = of_find_mipi_dsi_host_by_node(ctx->host_node); + if (!host) { + dev_err(dev, "failed to find dsi host\n"); + return -EPROBE_DEFER; + } + + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); + if (IS_ERR(dsi)) + return dev_err_probe(dev, PTR_ERR(dsi), +"failed to create dsi device\n"); + + ctx->dsi = dsi; + + dsi->lanes = ctx->dsi_lanes; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret < 0) { + dev_err(dev, "failed to attach dsi to host: %d\n", ret); + return ret; + } + + return 0; +} + static int sn65dsi83_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -679,7 +683,15 @@ static int sn65dsi83_probe(struct i2c_client *client, ctx->bridge.of_node = dev->of_node; drm_bridge_add(&ctx->bridge); + ret = sn65dsi83_host_attach(ctx); + if (ret) + goto err_remove_bridge; + return 0; + +err_remove_bridge: + drm_bridge_remove(&ctx->bridge); + return ret; } static int sn65dsi83_remove(struct i2c_client *client) -- 2.31.1
[Freedreno] [PATCH v5 10/21] drm/bridge: lt9611uxc: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 31 +- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index ab1a0c00aad8..33f9716da0ee 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -367,18 +367,6 @@ static int lt9611uxc_bridge_attach(struct drm_bridge *bridge, return ret; } - /* Attach primary DSI */ - lt9611uxc->dsi0 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi0_node); - if (IS_ERR(lt9611uxc->dsi0)) - return PTR_ERR(lt9611uxc->dsi0); - - /* Attach secondary DSI, if specified */ - if (lt9611uxc->dsi1_node) { - lt9611uxc->dsi1 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi1_node); - if (IS_ERR(lt9611uxc->dsi1)) - return PTR_ERR(lt9611uxc->dsi1); - } - return 0; } @@ -958,8 +946,27 @@ static int lt9611uxc_probe(struct i2c_client *client, drm_bridge_add(<9611uxc->bridge); + /* Attach primary DSI */ + lt9611uxc->dsi0 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi0_node); + if (IS_ERR(lt9611uxc->dsi0)) { + ret = PTR_ERR(lt9611uxc->dsi0); + goto err_remove_bridge; + } + + /* Attach secondary DSI, if specified */ + if (lt9611uxc->dsi1_node) { + lt9611uxc->dsi1 = lt9611uxc_attach_dsi(lt9611uxc, lt9611uxc->dsi1_node); + if (IS_ERR(lt9611uxc->dsi1)) { + ret = PTR_ERR(lt9611uxc->dsi1); + goto err_remove_bridge; + } + } + return lt9611uxc_audio_init(dev, lt9611uxc); +err_remove_bridge: + drm_bridge_remove(<9611uxc->bridge); + err_disable_regulators: regulator_bulk_disable(ARRAY_SIZE(lt9611uxc->supplies), lt9611uxc->supplies); -- 2.31.1
[Freedreno] [PATCH v5 21/21] drm/msm/dsi: Adjust probe order
From: Rob Clark Switch to the documented order dsi-host vs bridge probe. Tested-by: Amit Pundir Tested-by: Caleb Connolly Tested-by: John Stultz Signed-off-by: Rob Clark Signed-off-by: Maxime Ripard --- drivers/gpu/drm/msm/dsi/dsi.c | 50 --- drivers/gpu/drm/msm/dsi/dsi.h | 2 +- drivers/gpu/drm/msm/dsi/dsi_host.c| 22 drivers/gpu/drm/msm/dsi/dsi_manager.c | 6 ++-- drivers/gpu/drm/msm/msm_drv.h | 2 ++ 5 files changed, 43 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 614dc7f26f2c..ad73ebb84b2d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -112,18 +112,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = dev_get_drvdata(master); struct msm_drm_private *priv = drm->dev_private; - struct platform_device *pdev = to_platform_device(dev); - struct msm_dsi *msm_dsi; - - DBG(""); - msm_dsi = dsi_init(pdev); - if (IS_ERR(msm_dsi)) { - /* Don't fail the bind if the dsi port is not connected */ - if (PTR_ERR(msm_dsi) == -ENODEV) - return 0; - else - return PTR_ERR(msm_dsi); - } + struct msm_dsi *msm_dsi = dev_get_drvdata(dev); priv->dsi[msm_dsi->id] = msm_dsi; @@ -136,12 +125,8 @@ static void dsi_unbind(struct device *dev, struct device *master, struct drm_device *drm = dev_get_drvdata(master); struct msm_drm_private *priv = drm->dev_private; struct msm_dsi *msm_dsi = dev_get_drvdata(dev); - int id = msm_dsi->id; - if (priv->dsi[id]) { - dsi_destroy(msm_dsi); - priv->dsi[id] = NULL; - } + priv->dsi[msm_dsi->id] = NULL; } static const struct component_ops dsi_ops = { @@ -149,15 +134,40 @@ static const struct component_ops dsi_ops = { .unbind = dsi_unbind, }; -static int dsi_dev_probe(struct platform_device *pdev) +int dsi_dev_attach(struct platform_device *pdev) { return component_add(&pdev->dev, &dsi_ops); } -static int dsi_dev_remove(struct platform_device *pdev) +void dsi_dev_detach(struct platform_device *pdev) { - DBG(""); component_del(&pdev->dev, &dsi_ops); +} + +static int dsi_dev_probe(struct platform_device *pdev) +{ + struct msm_dsi *msm_dsi; + + DBG(""); + msm_dsi = dsi_init(pdev); + if (IS_ERR(msm_dsi)) { + /* Don't fail the bind if the dsi port is not connected */ + if (PTR_ERR(msm_dsi) == -ENODEV) + return 0; + else + return PTR_ERR(msm_dsi); + } + + return 0; +} + +static int dsi_dev_remove(struct platform_device *pdev) +{ + struct msm_dsi *msm_dsi = platform_get_drvdata(pdev); + + DBG(""); + dsi_destroy(msm_dsi); + return 0; } diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index b50db91cb8a7..83787cbee419 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -116,7 +116,7 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host); unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host); -int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer); +int msm_dsi_host_register(struct mipi_dsi_host *host); void msm_dsi_host_unregister(struct mipi_dsi_host *host); int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host, struct msm_dsi_phy *src_phy); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index e269df285136..f741494b1bf6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1624,6 +1624,10 @@ static int dsi_host_attach(struct mipi_dsi_host *host, if (ret) return ret; + ret = dsi_dev_attach(msm_host->pdev); + if (ret) + return ret; + DBG("id=%d", msm_host->id); if (msm_host->dev) queue_work(msm_host->workqueue, &msm_host->hpd_work); @@ -1636,6 +1640,8 @@ static int dsi_host_detach(struct mipi_dsi_host *host, { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + dsi_dev_detach(msm_host->pdev); + msm_host->device_node = NULL; DBG("id=%d", msm_host->id); @@ -1970,7 +1976,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, return 0; } -int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer) +int msm_dsi_host_register(struct mipi_dsi_host *host) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); int ret; @@ -1984,20 +1990,6 @@ int msm_dsi_ho
[Freedreno] [PATCH v5 16/21] drm/bridge: sn65dsi86: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. This also avoids leaking the device when we detach the bridge. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 22 +++--- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 6154bed0af5b..36a82e3d17ab 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -662,6 +662,7 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); struct mipi_dsi_host *host; struct mipi_dsi_device *dsi; + struct device *dev = pdata->dev; const struct mipi_dsi_device_info info = { .type = "ti_sn_bridge", .channel = 0, .node = NULL, @@ -701,7 +702,7 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, goto err_dsi_host; } - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { DRM_ERROR("failed to create dsi device\n"); ret = PTR_ERR(dsi); @@ -714,16 +715,16 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, dsi->mode_flags = MIPI_DSI_MODE_VIDEO; /* check if continuous dsi clock is required or not */ - pm_runtime_get_sync(pdata->dev); + pm_runtime_get_sync(dev); regmap_read(pdata->regmap, SN_DPPLL_SRC_REG, &val); - pm_runtime_put_autosuspend(pdata->dev); + pm_runtime_put_autosuspend(dev); if (!(val & DPPLL_CLK_SRC_DSICLK)) dsi->mode_flags |= MIPI_DSI_CLOCK_NON_CONTINUOUS; - ret = mipi_dsi_attach(dsi); + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { DRM_ERROR("failed to attach dsi to host\n"); - goto err_dsi_attach; + goto err_dsi_host; } pdata->dsi = dsi; @@ -734,14 +735,10 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, ret = drm_bridge_attach(bridge->encoder, pdata->next_bridge, &pdata->bridge, flags); if (ret < 0) - goto err_dsi_detach; + goto err_dsi_host; return 0; -err_dsi_detach: - mipi_dsi_detach(dsi); -err_dsi_attach: - mipi_dsi_device_unregister(dsi); err_dsi_host: drm_connector_cleanup(&pdata->connector); err_conn_init: @@ -1237,11 +1234,6 @@ static void ti_sn_bridge_remove(struct auxiliary_device *adev) if (!pdata) return; - if (pdata->dsi) { - mipi_dsi_detach(pdata->dsi); - mipi_dsi_device_unregister(pdata->dsi); - } - drm_bridge_remove(&pdata->bridge); of_node_put(pdata->host_node); -- 2.31.1
[Freedreno] [PATCH v5 11/21] drm/bridge: ps8640: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. This also avoids leaking the device on removal. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/parade-ps8640.c | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c index 3aaa90913bf8..5ae15fc407c5 100644 --- a/drivers/gpu/drm/bridge/parade-ps8640.c +++ b/drivers/gpu/drm/bridge/parade-ps8640.c @@ -428,7 +428,7 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge, if (!host) return -ENODEV; - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { dev_err(dev, "failed to create dsi device\n"); ret = PTR_ERR(dsi); @@ -442,27 +442,22 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge, MIPI_DSI_MODE_VIDEO_SYNC_PULSE; dsi->format = MIPI_DSI_FMT_RGB888; dsi->lanes = NUM_MIPI_LANES; - ret = mipi_dsi_attach(dsi); + + ret = devm_mipi_dsi_attach(dev, dsi); if (ret) { dev_err(dev, "failed to attach dsi device: %d\n", ret); - goto err_dsi_attach; + return ret; } ret = drm_dp_aux_register(&ps_bridge->aux); if (ret) { dev_err(dev, "failed to register DP AUX channel: %d\n", ret); - goto err_aux_register; + return ret; } /* Attach the panel-bridge to the dsi bridge */ return drm_bridge_attach(bridge->encoder, ps_bridge->panel_bridge, &ps_bridge->bridge, flags); - -err_aux_register: - mipi_dsi_detach(dsi); -err_dsi_attach: - mipi_dsi_device_unregister(dsi); - return ret; } static void ps8640_bridge_detach(struct drm_bridge *bridge) -- 2.31.1
[Freedreno] [PATCH v5 12/21] drm/bridge: ps8640: Register and attach our DSI device at probe
In order to avoid any probe ordering issue, the best practice is to move the secondary MIPI-DSI device registration and attachment to the MIPI-DSI host at probe time. Let's do this. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/parade-ps8640.c | 100 ++--- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c index 5ae15fc407c5..5f70eaca175b 100644 --- a/drivers/gpu/drm/bridge/parade-ps8640.c +++ b/drivers/gpu/drm/bridge/parade-ps8640.c @@ -400,55 +400,10 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge, enum drm_bridge_attach_flags flags) { struct ps8640 *ps_bridge = bridge_to_ps8640(bridge); - struct device *dev = &ps_bridge->page[0]->dev; - struct device_node *in_ep, *dsi_node; - struct mipi_dsi_device *dsi; - struct mipi_dsi_host *host; - int ret; - const struct mipi_dsi_device_info info = { .type = "ps8640", - .channel = 0, - .node = NULL, -}; if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) return -EINVAL; - /* port@0 is ps8640 dsi input port */ - in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); - if (!in_ep) - return -ENODEV; - - dsi_node = of_graph_get_remote_port_parent(in_ep); - of_node_put(in_ep); - if (!dsi_node) - return -ENODEV; - - host = of_find_mipi_dsi_host_by_node(dsi_node); - of_node_put(dsi_node); - if (!host) - return -ENODEV; - - dsi = devm_mipi_dsi_device_register_full(dev, host, &info); - if (IS_ERR(dsi)) { - dev_err(dev, "failed to create dsi device\n"); - ret = PTR_ERR(dsi); - return ret; - } - - ps_bridge->dsi = dsi; - - dsi->host = host; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | - MIPI_DSI_MODE_VIDEO_SYNC_PULSE; - dsi->format = MIPI_DSI_FMT_RGB888; - dsi->lanes = NUM_MIPI_LANES; - - ret = devm_mipi_dsi_attach(dev, dsi); - if (ret) { - dev_err(dev, "failed to attach dsi device: %d\n", ret); - return ret; - } - ret = drm_dp_aux_register(&ps_bridge->aux); if (ret) { dev_err(dev, "failed to register DP AUX channel: %d\n", ret); @@ -507,6 +462,53 @@ static const struct drm_bridge_funcs ps8640_bridge_funcs = { .pre_enable = ps8640_pre_enable, }; +static int ps8640_bridge_host_attach(struct device *dev, struct ps8640 *ps_bridge) +{ + struct device_node *in_ep, *dsi_node; + struct mipi_dsi_device *dsi; + struct mipi_dsi_host *host; + int ret; + const struct mipi_dsi_device_info info = { .type = "ps8640", + .channel = 0, + .node = NULL, +}; + + /* port@0 is ps8640 dsi input port */ + in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); + if (!in_ep) + return -ENODEV; + + dsi_node = of_graph_get_remote_port_parent(in_ep); + of_node_put(in_ep); + if (!dsi_node) + return -ENODEV; + + host = of_find_mipi_dsi_host_by_node(dsi_node); + of_node_put(dsi_node); + if (!host) + return -EPROBE_DEFER; + + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); + if (IS_ERR(dsi)) { + dev_err(dev, "failed to create dsi device\n"); + return PTR_ERR(dsi); + } + + ps_bridge->dsi = dsi; + + dsi->host = host; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | + MIPI_DSI_MODE_VIDEO_SYNC_PULSE; + dsi->format = MIPI_DSI_FMT_RGB888; + dsi->lanes = NUM_MIPI_LANES; + + ret = devm_mipi_dsi_attach(dev, dsi); + if (ret) + return ret; + + return 0; +} + static int ps8640_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -584,7 +586,15 @@ static int ps8640_probe(struct i2c_client *client) drm_bridge_add(&ps_bridge->bridge); + ret = ps8640_bridge_host_attach(dev, ps_bridge); + if (ret) + goto err_bridge_remove; + return 0; + +err_bridge_remove: + drm_bridge_remove(&ps_bridge->bridge); + return ret; } static int ps8640_remove(struct i2c_client *client) -- 2.31.1
[Freedreno] [PATCH v5 20/21] drm/kirin: dsi: Adjust probe order
Without proper care and an agreement between how DSI hosts and devices drivers register their MIPI-DSI entities and potential components, we can end up in a situation where the drivers can never probe. Most drivers were taking evasive maneuvers to try to workaround this, but not all of them were following the same conventions, resulting in various incompatibilities between DSI hosts and devices. Now that we have a sequence agreed upon and documented, let's convert kirin to it. Tested-by: John Stultz Signed-off-by: Maxime Ripard --- drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 52 +--- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c index 952cfdb1961d..1d556482bb46 100644 --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c +++ b/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c @@ -81,7 +81,7 @@ struct dsi_hw_ctx { struct dw_dsi { struct drm_encoder encoder; - struct drm_bridge *bridge; + struct device *dev; struct mipi_dsi_host host; struct drm_display_mode cur_mode; struct dsi_hw_ctx *ctx; @@ -720,10 +720,13 @@ static int dw_drm_encoder_init(struct device *dev, return 0; } +static const struct component_ops dsi_ops; static int dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *mdsi) { struct dw_dsi *dsi = host_to_dsi(host); + struct device *dev = host->dev; + int ret; if (mdsi->lanes < 1 || mdsi->lanes > 4) { DRM_ERROR("dsi device params invalid\n"); @@ -734,13 +737,20 @@ static int dsi_host_attach(struct mipi_dsi_host *host, dsi->format = mdsi->format; dsi->mode_flags = mdsi->mode_flags; + ret = component_add(dev, &dsi_ops); + if (ret) + return ret; + return 0; } static int dsi_host_detach(struct mipi_dsi_host *host, struct mipi_dsi_device *mdsi) { - /* do nothing */ + struct device *dev = host->dev; + + component_del(dev, &dsi_ops); + return 0; } @@ -768,7 +778,17 @@ static int dsi_host_init(struct device *dev, struct dw_dsi *dsi) static int dsi_bridge_init(struct drm_device *dev, struct dw_dsi *dsi) { struct drm_encoder *encoder = &dsi->encoder; - struct drm_bridge *bridge = dsi->bridge; + struct drm_bridge *bridge; + struct device_node *np = dsi->dev->of_node; + int ret; + + /* +* Get the endpoint node. In our case, dsi has one output port1 +* to which the external HDMI bridge is connected. +*/ + ret = drm_of_find_panel_or_bridge(np, 1, 0, NULL, &bridge); + if (ret) + return ret; /* associate the bridge to dsi encoder */ return drm_bridge_attach(encoder, bridge, NULL, 0); @@ -785,10 +805,6 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - ret = dsi_host_init(dev, dsi); - if (ret) - return ret; - ret = dsi_bridge_init(drm_dev, dsi); if (ret) return ret; @@ -809,17 +825,7 @@ static const struct component_ops dsi_ops = { static int dsi_parse_dt(struct platform_device *pdev, struct dw_dsi *dsi) { struct dsi_hw_ctx *ctx = dsi->ctx; - struct device_node *np = pdev->dev.of_node; struct resource *res; - int ret; - - /* -* Get the endpoint node. In our case, dsi has one output port1 -* to which the external HDMI bridge is connected. -*/ - ret = drm_of_find_panel_or_bridge(np, 1, 0, NULL, &dsi->bridge); - if (ret) - return ret; ctx->pclk = devm_clk_get(&pdev->dev, "pclk"); if (IS_ERR(ctx->pclk)) { @@ -852,6 +858,7 @@ static int dsi_probe(struct platform_device *pdev) dsi = &data->dsi; ctx = &data->ctx; dsi->ctx = ctx; + dsi->dev = &pdev->dev; ret = dsi_parse_dt(pdev, dsi); if (ret) @@ -859,12 +866,19 @@ static int dsi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); - return component_add(&pdev->dev, &dsi_ops); + ret = dsi_host_init(&pdev->dev, dsi); + if (ret) + return ret; + + return 0; } static int dsi_remove(struct platform_device *pdev) { - component_del(&pdev->dev, &dsi_ops); + struct dsi_data *data = platform_get_drvdata(pdev); + struct dw_dsi *dsi = &data->dsi; + + mipi_dsi_host_unregister(&dsi->host); return 0; } -- 2.31.1
[Freedreno] [PATCH v5 14/21] drm/bridge: sn65dsi83: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. This also avoids leaking the device when we detach the bridge but don't remove its driver. Acked-by: Sam Ravnborg Tested-by: Laurent Pinchart Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 12 +++- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index 3bfd07caf8d7..539edd2c19f5 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -262,7 +262,7 @@ static int sn65dsi83_attach(struct drm_bridge *bridge, return -EPROBE_DEFER; } - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { return dev_err_probe(dev, PTR_ERR(dsi), "failed to create dsi device\n"); @@ -274,18 +274,14 @@ static int sn65dsi83_attach(struct drm_bridge *bridge, dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; - ret = mipi_dsi_attach(dsi); + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { dev_err(dev, "failed to attach dsi to host\n"); - goto err_dsi_attach; + return ret; } return drm_bridge_attach(bridge->encoder, ctx->panel_bridge, &ctx->bridge, flags); - -err_dsi_attach: - mipi_dsi_device_unregister(dsi); - return ret; } static void sn65dsi83_detach(struct drm_bridge *bridge) @@ -295,8 +291,6 @@ static void sn65dsi83_detach(struct drm_bridge *bridge) if (!ctx->dsi) return; - mipi_dsi_detach(ctx->dsi); - mipi_dsi_device_unregister(ctx->dsi); ctx->dsi = NULL; } -- 2.31.1
[Freedreno] [PATCH v5 18/21] drm/bridge: tc358775: Switch to devm MIPI-DSI helpers
Let's switch to the new devm MIPI-DSI function to register and attach our secondary device. This also avoids leaking the device when we detach the bridge. Acked-by: Sam Ravnborg Signed-off-by: Maxime Ripard --- drivers/gpu/drm/bridge/tc358775.c | 13 - 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358775.c b/drivers/gpu/drm/bridge/tc358775.c index 2272adcc5b4a..35e66d1b6456 100644 --- a/drivers/gpu/drm/bridge/tc358775.c +++ b/drivers/gpu/drm/bridge/tc358775.c @@ -610,11 +610,10 @@ static int tc_bridge_attach(struct drm_bridge *bridge, return -EPROBE_DEFER; } - dsi = mipi_dsi_device_register_full(host, &info); + dsi = devm_mipi_dsi_device_register_full(dev, host, &info); if (IS_ERR(dsi)) { dev_err(dev, "failed to create dsi device\n"); - ret = PTR_ERR(dsi); - goto err_dsi_device; + return PTR_ERR(dsi); } tc->dsi = dsi; @@ -623,19 +622,15 @@ static int tc_bridge_attach(struct drm_bridge *bridge, dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO; - ret = mipi_dsi_attach(dsi); + ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { dev_err(dev, "failed to attach dsi to host\n"); - goto err_dsi_attach; + return ret; } /* Attach the panel-bridge to the dsi bridge */ return drm_bridge_attach(bridge->encoder, tc->panel_bridge, &tc->bridge, flags); -err_dsi_attach: - mipi_dsi_device_unregister(dsi); -err_dsi_device: - return ret; } static const struct drm_bridge_funcs tc_bridge_funcs = { -- 2.31.1
Re: [Freedreno] [PATCH 0/2] drm/msm: fix build error
Yanteng Si 于2021年10月14日周四 下午4:51写道: > > Include linux/vmalloc.h to fix below errors: > > error: implicit declaration of function 'vmap'; > error: implicit declaration of function 'register_vmap_purge_notifier' > error: implicit declaration of function 'unregister_vmap_purge_notifier' > > Yanteng Si (2): > drm/msm: Fix missing include files in msm_gem.c > drm/msm: Fix missing include files in msm_gem_shrinker.c ping? Thanks, Yanteng
Re: [Freedreno] [PATCH v2 2/2] dt-bindings: Add SC7280 compatible string
Hi Doug, Sorry about that, this is the first time I am posting changes upstream and still getting hold of conventions. I think I misinterpreted your subject line comment and changed the just title to include dp-controller. I will correct it in the next version. sc7280-dp will be added later when dp support for sc7280 will be posted. I will reply on the feedback email from Stephen. Thank you, Sankeerth -Original Message- From: Doug Anderson Sent: Wednesday, October 20, 2021 11:11 PM To: quic_sbillaka Cc: dri-devel ; linux-arm-msm ; freedreno ; LKML ; Sankeerth Billakanti ; Rob Clark ; Sean Paul ; Stephen Boyd ; Kalyan Thota ; Abhinav Kumar ; Kuogee Hsieh ; Krishna Manikandan Subject: Re: [PATCH v2 2/2] dt-bindings: Add SC7280 compatible string WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros. Hi, On Wed, Oct 20, 2021 at 5:14 AM Sankeerth Billakanti wrote: > > From: Sankeerth Billakanti > > The Qualcomm SC7280 platform supports an eDP controller, add > compatible string for it to dp-controller. > > Signed-off-by: Sankeerth Billakanti > --- > Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 1 > + > 1 file changed, 1 insertion(+) I think you ignored some of the feedback that was given on v1. Perhaps you could go back and re-read that feedback? See the replies to: https://lore.kernel.org/r/1628726882-27841-3-git-send-email-sbill...@codeaurora.org/ For one, ${SUBJECT} needs updating. It's probably as simple as adding the "msm/dp" tag, like: dt-bindings: msm/dp: Add SC7280 compatible string For another, Stephen requested that you add "sc7280-dp" too.
Re: [Freedreno] [PATCH v3 13/13] drm/i915: replace drm_detect_hdmi_monitor() with drm_display_info.is_hdmi
On Wed, Oct 20, 2021 at 12:51:21AM +0200, Claudio Suarez wrote: > drm_get_edid() internally calls to drm_connector_update_edid_property() > and then drm_add_display_info(), which parses the EDID. > This happens in the function intel_hdmi_set_edid() and > intel_sdvo_tmds_sink_detect() (via intel_sdvo_get_edid()). > > Once EDID is parsed, the monitor HDMI support information is available > through drm_display_info.is_hdmi. Retriving the same information with > drm_detect_hdmi_monitor() is less efficient. Change to > drm_display_info.is_hdmi I meant we need to examine all call chains that can lead to .detect() to make sure all of them do in fact update the display_info beforehand. > > This is a TODO task in Documentation/gpu/todo.rst > > Signed-off-by: Claudio Suarez > --- > drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- > drivers/gpu/drm/i915/display/intel_sdvo.c | 3 ++- > 2 files changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c > b/drivers/gpu/drm/i915/display/intel_hdmi.c > index b04685bb6439..008e5b0ba408 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c > @@ -2355,7 +2355,7 @@ intel_hdmi_set_edid(struct drm_connector *connector) > to_intel_connector(connector)->detect_edid = edid; > if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { > intel_hdmi->has_audio = drm_detect_monitor_audio(edid); > - intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); > + intel_hdmi->has_hdmi_sink = connector->display_info.is_hdmi; > > connected = true; > } > diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c > b/drivers/gpu/drm/i915/display/intel_sdvo.c > index 6cb27599ea03..b4065e4df644 100644 > --- a/drivers/gpu/drm/i915/display/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c > @@ -2060,8 +2060,9 @@ intel_sdvo_tmds_sink_detect(struct drm_connector > *connector) > if (edid->input & DRM_EDID_INPUT_DIGITAL) { > status = connector_status_connected; > if (intel_sdvo_connector->is_hdmi) { > - intel_sdvo->has_hdmi_monitor = > drm_detect_hdmi_monitor(edid); > intel_sdvo->has_hdmi_audio = > drm_detect_monitor_audio(edid); > + intel_sdvo->has_hdmi_monitor = > + > connector->display_info.is_hdmi; > } > } else > status = connector_status_disconnected; > -- > 2.33.0 > > -- Ville Syrjälä Intel
Re: [Freedreno] [PATCH v5 13/21] drm/bridge: sn65dsi83: Fix bridge removal
On Thu, Oct 21, 2021 at 09:39:39AM +0200, Maxime Ripard wrote: > Commit 24417d5b0c00 ("drm/bridge: ti-sn65dsi83: Implement .detach > callback") moved the unregistration of the bridge DSI device and bridge > itself to the detach callback. > > While this is correct for the DSI device detach and unregistration, the > bridge is added in the driver probe, and should thus be removed as part > of its remove callback. > > Cc: Marek Vasut > Fixes: 24417d5b0c00 ("drm/bridge: ti-sn65dsi83: Implement .detach callback") > Signed-off-by: Maxime Ripard Acked-by: Sam Ravnborg
Re: [Freedreno] [PATCH v5 00/21] drm/bridge: Make panel and bridge probe order consistent
Hi Maxime, > Let me know what you think, apply the lot to drm-misc-next. Maybe wait for an r-b or a-b on the kirin patch but the rest is IMO good to go. Sam
Re: [Freedreno] [PATCH v5 21/21] drm/msm/dsi: Adjust probe order
On Thu, Oct 21, 2021 at 12:41 AM Maxime Ripard wrote: > > From: Rob Clark > > Switch to the documented order dsi-host vs bridge probe. > > Tested-by: Amit Pundir > Tested-by: Caleb Connolly > Tested-by: John Stultz > Signed-off-by: Rob Clark > Signed-off-by: Maxime Ripard I guess this should probably land together w/ the rest of the series, so a-b for merging thru drm-misc BR, -R > --- > drivers/gpu/drm/msm/dsi/dsi.c | 50 --- > drivers/gpu/drm/msm/dsi/dsi.h | 2 +- > drivers/gpu/drm/msm/dsi/dsi_host.c| 22 > drivers/gpu/drm/msm/dsi/dsi_manager.c | 6 ++-- > drivers/gpu/drm/msm/msm_drv.h | 2 ++ > 5 files changed, 43 insertions(+), 39 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c > index 614dc7f26f2c..ad73ebb84b2d 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi.c > +++ b/drivers/gpu/drm/msm/dsi/dsi.c > @@ -112,18 +112,7 @@ static int dsi_bind(struct device *dev, struct device > *master, void *data) > { > struct drm_device *drm = dev_get_drvdata(master); > struct msm_drm_private *priv = drm->dev_private; > - struct platform_device *pdev = to_platform_device(dev); > - struct msm_dsi *msm_dsi; > - > - DBG(""); > - msm_dsi = dsi_init(pdev); > - if (IS_ERR(msm_dsi)) { > - /* Don't fail the bind if the dsi port is not connected */ > - if (PTR_ERR(msm_dsi) == -ENODEV) > - return 0; > - else > - return PTR_ERR(msm_dsi); > - } > + struct msm_dsi *msm_dsi = dev_get_drvdata(dev); > > priv->dsi[msm_dsi->id] = msm_dsi; > > @@ -136,12 +125,8 @@ static void dsi_unbind(struct device *dev, struct device > *master, > struct drm_device *drm = dev_get_drvdata(master); > struct msm_drm_private *priv = drm->dev_private; > struct msm_dsi *msm_dsi = dev_get_drvdata(dev); > - int id = msm_dsi->id; > > - if (priv->dsi[id]) { > - dsi_destroy(msm_dsi); > - priv->dsi[id] = NULL; > - } > + priv->dsi[msm_dsi->id] = NULL; > } > > static const struct component_ops dsi_ops = { > @@ -149,15 +134,40 @@ static const struct component_ops dsi_ops = { > .unbind = dsi_unbind, > }; > > -static int dsi_dev_probe(struct platform_device *pdev) > +int dsi_dev_attach(struct platform_device *pdev) > { > return component_add(&pdev->dev, &dsi_ops); > } > > -static int dsi_dev_remove(struct platform_device *pdev) > +void dsi_dev_detach(struct platform_device *pdev) > { > - DBG(""); > component_del(&pdev->dev, &dsi_ops); > +} > + > +static int dsi_dev_probe(struct platform_device *pdev) > +{ > + struct msm_dsi *msm_dsi; > + > + DBG(""); > + msm_dsi = dsi_init(pdev); > + if (IS_ERR(msm_dsi)) { > + /* Don't fail the bind if the dsi port is not connected */ > + if (PTR_ERR(msm_dsi) == -ENODEV) > + return 0; > + else > + return PTR_ERR(msm_dsi); > + } > + > + return 0; > +} > + > +static int dsi_dev_remove(struct platform_device *pdev) > +{ > + struct msm_dsi *msm_dsi = platform_get_drvdata(pdev); > + > + DBG(""); > + dsi_destroy(msm_dsi); > + > return 0; > } > > diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h > index b50db91cb8a7..83787cbee419 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi.h > +++ b/drivers/gpu/drm/msm/dsi/dsi.h > @@ -116,7 +116,7 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host > *host, > struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host); > unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); > struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host); > -int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer); > +int msm_dsi_host_register(struct mipi_dsi_host *host); > void msm_dsi_host_unregister(struct mipi_dsi_host *host); > int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host, > struct msm_dsi_phy *src_phy); > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c > b/drivers/gpu/drm/msm/dsi/dsi_host.c > index e269df285136..f741494b1bf6 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -1624,6 +1624,10 @@ static int dsi_host_attach(struct mipi_dsi_host *host, > if (ret) > return ret; > > + ret = dsi_dev_attach(msm_host->pdev); > + if (ret) > + return ret; > + > DBG("id=%d", msm_host->id); > if (msm_host->dev) > queue_work(msm_host->workqueue, &msm_host->hpd_work); > @@ -1636,6 +1640,8 @@ static int dsi_host_detach(struct mipi_dsi_host *host, > { > struct msm_dsi_host *msm_host = to_msm_dsi_host(host); > > + dsi_dev_detach(msm_host->pdev); > + >
Re: [Freedreno] [PATCH v2 1/2] drm/msm/dp: Add support for SC7280 eDP
Quoting Sankeerth Billakanti (2021-10-20 05:14:10) > diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c > b/drivers/gpu/drm/msm/dp/dp_ctrl.c > index 62e75dc..9fea49c 100644 > --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c > +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c > @@ -1238,9 +1240,21 @@ static int dp_ctrl_link_train(struct dp_ctrl_private > *ctrl, > link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING; > > dp_aux_link_configure(ctrl->aux, &link_info); > + > + if (dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5) { Please add a static inline macro in include/drm/drm_dp_helper.h that makes this more readable. Something similar to drm_dp_is_branch() but with a human readable replacement for "is_branch". Maybe drm_dp_ssc()? > + ssc = DP_SPREAD_AMP_0_5; > + drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, &ssc, 1); > + } > + > drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, > &encoding, 1); > > + if (dpcd[DP_EDP_CONFIGURATION_CAP] & > DP_ALTERNATE_SCRAMBLER_RESET_CAP) { And this one already has a helper, drm_dp_alternate_scrambler_reset_cap(). > + assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE; > + drm_dp_dpcd_write(ctrl->aux, DP_EDP_CONFIGURATION_SET, > + &assr, 1); > + } > + > ret = dp_ctrl_link_train_1(ctrl, training_step); > if (ret) { > DRM_ERROR("link training #1 failed. ret=%d\n", ret); > @@ -1312,9 +1326,11 @@ static int dp_ctrl_enable_mainlink_clocks(struct > dp_ctrl_private *ctrl) > struct dp_io *dp_io = &ctrl->parser->io; > struct phy *phy = dp_io->phy; > struct phy_configure_opts_dp *opts_dp = &dp_io->phy_opts.dp; > + const u8 *dpcd = ctrl->panel->dpcd; > > opts_dp->lanes = ctrl->link->link_params.num_lanes; > opts_dp->link_rate = ctrl->link->link_params.rate / 100; > + opts_dp->ssc = dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5; > dp_ctrl_set_clock_rate(ctrl, DP_CTRL_PM, "ctrl_link", > ctrl->link->link_params.rate * 1000); > > @@ -1406,7 +1422,7 @@ void dp_ctrl_host_deinit(struct dp_ctrl *dp_ctrl) > > static bool dp_ctrl_use_fixed_nvid(struct dp_ctrl_private *ctrl) > { > - u8 *dpcd = ctrl->panel->dpcd; > + const u8 *dpcd = ctrl->panel->dpcd; > > /* > * For better interop experience, used a fixed NVID=0x8000 > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c > b/drivers/gpu/drm/msm/dp/dp_display.c > index c867745..c16311b 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.c > +++ b/drivers/gpu/drm/msm/dp/dp_display.c > @@ -144,8 +144,16 @@ static const struct msm_dp_config sc8180x_dp_cfg = { > .num_descs = 3, > }; > > +static const struct msm_dp_config sc7280_dp_cfg = { > + .descs = (struct msm_dp_desc[]) { const > + { .io_start = 0x0aea, .connector_type = > DRM_MODE_CONNECTOR_eDP }, > + }, > + .num_descs = 1, > +}; > + > static const struct of_device_id dp_dt_match[] = { > { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_cfg }, > + { .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_cfg }, > { .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_cfg }, > { .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_cfg }, > {} > @@ -1440,7 +1448,7 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display) > > dp_hpd_event_setup(dp); > > - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); > + dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 1); This has no explanation. What is it?
Re: [Freedreno] [PATCH v2 1/4] dt-bindings: msm: add DT bindings for sc7280
Quoting Krishna Manikandan (2021-10-20 06:58:50) > MSM Mobile Display Subsystem (MDSS) encapsulates sub-blocks > like DPU display controller, DSI, EDP etc. Add required DPU > device tree bindings for SC7280. > > Signed-off-by: Krishna Manikandan > > Changes in v2: > - Drop target from description (Stephen Boyd) > - Drop items from compatible (Stephen Boyd) > - Add clock names one per line for readability (Stephen Boyd) > - Use correct indendation (Stephen Boyd) This changelog should come after the triple dash. qcom maintainers don't want drm style changelogs in the commit text. > --- Reviewed-by: Stephen Boyd
Re: [Freedreno] [PATCH v2 2/4] arm64: dts: qcom: sc7280: add display dt nodes
Quoting Krishna Manikandan (2021-10-20 06:58:51) > Add mdss and mdp DT nodes for sc7280. > > Signed-off-by: Krishna Manikandan > > Changes in v2: > - Rename display dt nodes (Stephen Boyd) > - Add clock names one per line for readability (Stephen Boyd) > --- Reviewed-by: Stephen Boyd
Re: [Freedreno] [PATCH v2 4/4] arm64: dts: qcom: sc7280: add edp display dt nodes
Quoting Krishna Manikandan (2021-10-20 06:58:53) > From: Sankeerth Billakanti > > Add edp controller and phy DT nodes for sc7280. > > Signed-off-by: Sankeerth Billakanti > Signed-off-by: Krishna Manikandan > Some comments below Reviewed-by: Stephen Boyd > Changes in v2: > - Move regulator definitions to board file (Matthias Kaehlcke) > - Move the gpio definitions to board file (Matthias Kaehlcke) > - Move the pinconf to board file (Matthias Kaehlcke) > - Move status property (Stephen Boyd) > - Drop flags from interrupts (Stephen Boyd) > - Add clock names one per line for readability (Stephen Boyd) > - Rename edp-opp-table (Stephen Boyd) > --- > arch/arm64/boot/dts/qcom/sc7280.dtsi | 107 > ++- > 1 file changed, 106 insertions(+), 1 deletion(-) > > diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi > b/arch/arm64/boot/dts/qcom/sc7280.dtsi > index dd35882..4450277 100644 > --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi > +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi > @@ -2575,7 +2575,7 @@ > reg = <0 0xaf0 0 0x2>; > clocks = <&rpmhcc RPMH_CXO_CLK>, > <&gcc GCC_DISP_GPLL0_CLK_SRC>, > -<0>, <0>, <0>, <0>, <0>, <0>; > +<0>, <0>, <0>, <0>, <&edp_phy 0>, <&edp_phy > 1>; I can already tell this is going to be a merge mess! Can this also be one cell per line? > clock-names = "bi_tcxo", "gcc_disp_gpll0_clk", > "dsi0_phy_pll_out_byteclk", > "dsi0_phy_pll_out_dsiclk", > @@ -2777,6 +2784,103 @@ > > status = "disabled"; > }; > + > + msm_edp: edp@aea { > + compatible = "qcom,sc7280-edp"; > + > + reg = <0 0xaea 0 0x200>, > + <0 0xaea0200 0 0x200>, > + <0 0xaea0400 0 0xc00>, > + <0 0xaea1000 0 0x400>; > + > + interrupt-parent = <&mdss>; > + interrupts = <14>; > + > + clocks = <&rpmhcc RPMH_CXO_CLK>, > +<&gcc GCC_EDP_CLKREF_EN>, > +<&dispcc DISP_CC_MDSS_AHB_CLK>, > +<&dispcc DISP_CC_MDSS_EDP_AUX_CLK>, > +<&dispcc DISP_CC_MDSS_EDP_LINK_CLK>, > +<&dispcc > DISP_CC_MDSS_EDP_LINK_INTF_CLK>, > +<&dispcc DISP_CC_MDSS_EDP_PIXEL_CLK>; > + clock-names = "core_xo", > + "core_ref", > + "core_iface", > + "core_aux", > + "ctrl_link", > + "ctrl_link_iface", > + "stream_pixel"; > + #clock-cells = <1>; > + assigned-clocks = <&dispcc > DISP_CC_MDSS_EDP_LINK_CLK_SRC>, > + <&dispcc > DISP_CC_MDSS_EDP_PIXEL_CLK_SRC>; > + assigned-clock-parents = <&edp_phy 0>, > <&edp_phy 1>; > + > + phys = <&edp_phy>; > + phy-names = "dp"; > + > + operating-points-v2 = <&edp_opp_table>; > + power-domains = <&rpmhpd SC7280_CX>; > + > + > + #address-cells = <1>; > + #size-cells = <0>; > + > + status = "disabled"; > + > + ports { > + #address-cells = <1>; > + #size-cells = <0>; > + port@0 { > + reg = <0>; > + edp_in: endpoint { > + remote-endpoint = > <&dpu_intf5_out>; > + }; > + }; > + }; > + > + edp_opp_table: opp-table { > + compatible = "operating-points-v2"; > + > + opp-16000 { > + opp-hz = /bits/ 64 > <16000>; > + required-opps = > <&rpm
Re: [Freedreno] [PATCH v2 3/4] arm64: dts: qcom: sc7280: Add DSI display nodes
Quoting Krishna Manikandan (2021-10-20 06:58:52) > Add DSI controller and PHY nodes for sc7280. > > Signed-off-by: Rajeev Nandan > Signed-off-by: Krishna Manikandan > Reviewed-by: Matthias Kaehlcke > > Changes in v2: > - Drop flags from interrupts (Stephen Boyd) > - Rename dsi-opp-table (Stephen Boyd) > - Rename dsi phy node (Stephen Boyd) > --- Reviewed-by: Stephen Boyd
Re: [Freedreno] [PATCH] drm/msm/dsi: use bulk clk API
On 2021-10-01 18:27, Dmitry Baryshkov wrote: Use clk_bulk_* API instead of hand-coding them. Note, this drops support for legacy clk naming (e.g. "iface_clk" instead of just "iface"), however all in-kernel device trees were converted long long ago. The warning is present there since 2017. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/dsi_host.c | 59 ++ 1 file changed, 12 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index e269df285136..3b81f40bba2e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -106,7 +106,8 @@ struct msm_dsi_host { phys_addr_t ctrl_size; struct regulator_bulk_data supplies[DSI_DEV_REGULATOR_MAX]; - struct clk *bus_clks[DSI_BUS_CLK_MAX]; + int num_bus_clks; + struct clk_bulk_data bus_clks[DSI_BUS_CLK_MAX]; struct clk *byte_clk; struct clk *esc_clk; @@ -374,15 +375,14 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host) int i, ret = 0; /* get bus clocks */ - for (i = 0; i < cfg->num_bus_clks; i++) { - msm_host->bus_clks[i] = msm_clk_get(pdev, - cfg->bus_clk_names[i]); - if (IS_ERR(msm_host->bus_clks[i])) { - ret = PTR_ERR(msm_host->bus_clks[i]); - pr_err("%s: Unable to get %s clock, ret = %d\n", - __func__, cfg->bus_clk_names[i], ret); - goto exit; - } + for (i = 0; i < cfg->num_bus_clks; i++) + msm_host->bus_clks[i].id = cfg->bus_clk_names[i]; + msm_host->num_bus_clks = cfg->num_bus_clks; + + ret = devm_clk_bulk_get(&pdev->dev, msm_host->num_bus_clks, msm_host->bus_clks); + if (ret < 0) { + dev_err(&pdev->dev, "Unable to get clocks, ret = %d\n", ret); + goto exit; } /* get link and source clocks */ @@ -433,41 +433,6 @@ static int dsi_clk_init(struct msm_dsi_host *msm_host) return ret; } -static int dsi_bus_clk_enable(struct msm_dsi_host *msm_host) -{ - const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg; - int i, ret; - - DBG("id=%d", msm_host->id); - - for (i = 0; i < cfg->num_bus_clks; i++) { - ret = clk_prepare_enable(msm_host->bus_clks[i]); - if (ret) { - pr_err("%s: failed to enable bus clock %d ret %d\n", - __func__, i, ret); - goto err; - } - } - - return 0; -err: - for (; i > 0; i--) - clk_disable_unprepare(msm_host->bus_clks[i]); - - return ret; -} - -static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host) -{ - const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg; - int i; - - DBG(""); - - for (i = cfg->num_bus_clks - 1; i >= 0; i--) - clk_disable_unprepare(msm_host->bus_clks[i]); -} - int msm_dsi_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -478,7 +443,7 @@ int msm_dsi_runtime_suspend(struct device *dev) if (!msm_host->cfg_hnd) return 0; - dsi_bus_clk_disable(msm_host); + clk_bulk_disable_unprepare(msm_host->num_bus_clks, msm_host->bus_clks); return 0; } @@ -493,7 +458,7 @@ int msm_dsi_runtime_resume(struct device *dev) if (!msm_host->cfg_hnd) return 0; - return dsi_bus_clk_enable(msm_host); + return clk_bulk_prepare_enable(msm_host->num_bus_clks, msm_host->bus_clks); } int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
Re: [Freedreno] [PATCH 01/11] drm/msm/dpu: move LUT levels out of QOS config
On 2021-09-30 06:59, Dmitry Baryshkov wrote: LUT levels are setup outside of setup_qos_ctrl, so remove them from the struct dpu_hw_pipe_qos_cfg. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 15 --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 17 ++--- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 69eed7932486..cbafb61404d0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -569,19 +569,20 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum } static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx, - struct dpu_hw_pipe_qos_cfg *cfg) + u32 danger_lut, + u32 safe_lut) { u32 idx; if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx)) return; - DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, cfg->danger_lut); - DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, cfg->safe_lut); + DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, danger_lut); + DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut); } static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx, - struct dpu_hw_pipe_qos_cfg *cfg) + u64 creq_lut) { u32 idx; @@ -589,11 +590,11 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx, return; if (ctx->cap && test_bit(DPU_SSPP_QOS_8LVL, &ctx->cap->features)) { - DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, cfg->creq_lut); + DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, creq_lut); DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_1 + idx, - cfg->creq_lut >> 32); + creq_lut >> 32); } else { - DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut); + DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, creq_lut); } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index fdfd4b46e2c6..27263bc1a1ef 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -166,18 +166,12 @@ struct dpu_hw_pipe_cfg { /** * struct dpu_hw_pipe_qos_cfg : Source pipe QoS configuration - * @danger_lut: LUT for generate danger level based on fill level - * @safe_lut: LUT for generate safe level based on fill level - * @creq_lut: LUT for generate creq level based on fill level * @creq_vblank: creq value generated to vbif during vertical blanking * @danger_vblank: danger value generated during vertical blanking * @vblank_en: enable creq_vblank and danger_vblank during vblank * @danger_safe_en: enable danger safe generation */ struct dpu_hw_pipe_qos_cfg { - u32 danger_lut; - u32 safe_lut; - u64 creq_lut; u32 creq_vblank; u32 danger_vblank; bool vblank_en; @@ -302,20 +296,22 @@ struct dpu_hw_sspp_ops { /** * setup_danger_safe_lut - setup danger safe LUTs * @ctx: Pointer to pipe context -* @cfg: Pointer to pipe QoS configuration +* @danger_lut: LUT for generate danger level based on fill level +* @safe_lut: LUT for generate safe level based on fill level * */ void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx, - struct dpu_hw_pipe_qos_cfg *cfg); + u32 danger_lut, + u32 safe_lut); /** * setup_creq_lut - setup CREQ LUT * @ctx: Pointer to pipe context -* @cfg: Pointer to pipe QoS configuration +* @creq_lut: LUT for generate creq level based on fill level * */ void (*setup_creq_lut)(struct dpu_hw_pipe *ctx, - struct dpu_hw_pipe_qos_cfg *cfg); + u64 creq_lut); /** * setup_qos_ctrl - setup QoS control diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index c989621209aa..5e0d06f26e53 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -348,8 +348,6 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, qos_lut = _dpu_plane_get_qos_lut( &pdpu->catalog->perf.qos_lut_tbl[lut_usage], total_fl); - pdpu->pipe_qos_cfg.creq_lut = qos_lut; - trace_dpu_perf_set_qos_luts(pdpu->pipe - SSPP_VIG0, (fmt) ? fmt->base.pixel_format : 0, pdpu->is_rt_pipe, total_fl, qos_lut, lut_usage); @@ -359,7 +357,7 @@ static void _dpu_pla
Re: [Freedreno] [PATCH 02/11] drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
On 2021-09-30 06:59, Dmitry Baryshkov wrote: The pipe_qos_cfg is used only in _dpu_plane_set_qos_ctrl(), so remove it from the dpu_plane struct and allocate it on stack when necessary. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 --- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 5e0d06f26e53..88d726133b8b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -105,7 +105,6 @@ struct dpu_plane { struct dpu_hw_pipe *pipe_hw; struct dpu_hw_pipe_cfg pipe_cfg; - struct dpu_hw_pipe_qos_cfg pipe_qos_cfg; uint32_t color_fill; bool is_error; bool is_rt_pipe; @@ -422,38 +421,41 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, bool enable, u32 flags) { struct dpu_plane *pdpu = to_dpu_plane(plane); + struct dpu_hw_pipe_qos_cfg pipe_qos_cfg; + + memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg)); if (flags & DPU_PLANE_QOS_VBLANK_CTRL) { - pdpu->pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank; - pdpu->pipe_qos_cfg.danger_vblank = + pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank; + pipe_qos_cfg.danger_vblank = pdpu->pipe_sblk->danger_vblank; - pdpu->pipe_qos_cfg.vblank_en = enable; + pipe_qos_cfg.vblank_en = enable; } if (flags & DPU_PLANE_QOS_VBLANK_AMORTIZE) { /* this feature overrules previous VBLANK_CTRL */ - pdpu->pipe_qos_cfg.vblank_en = false; - pdpu->pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */ + pipe_qos_cfg.vblank_en = false; + pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */ } if (flags & DPU_PLANE_QOS_PANIC_CTRL) - pdpu->pipe_qos_cfg.danger_safe_en = enable; + pipe_qos_cfg.danger_safe_en = enable; if (!pdpu->is_rt_pipe) { - pdpu->pipe_qos_cfg.vblank_en = false; - pdpu->pipe_qos_cfg.danger_safe_en = false; + pipe_qos_cfg.vblank_en = false; + pipe_qos_cfg.danger_safe_en = false; } DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d vb:%d pri[0x%x, 0x%x] is_rt:%d\n", pdpu->pipe - SSPP_VIG0, - pdpu->pipe_qos_cfg.danger_safe_en, - pdpu->pipe_qos_cfg.vblank_en, - pdpu->pipe_qos_cfg.creq_vblank, - pdpu->pipe_qos_cfg.danger_vblank, + pipe_qos_cfg.danger_safe_en, + pipe_qos_cfg.vblank_en, + pipe_qos_cfg.creq_vblank, + pipe_qos_cfg.danger_vblank, pdpu->is_rt_pipe); pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw, - &pdpu->pipe_qos_cfg); + &pipe_qos_cfg); } /**
Re: [Freedreno] [PATCH 03/11] drm/msm/dpu: drop pipe_name from struct dpu_plane
On 2021-09-30 06:59, Dmitry Baryshkov wrote: Use plane->name instead of artificial pipe_name. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 88d726133b8b..ef3737642b0c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -115,7 +115,6 @@ struct dpu_plane { struct dpu_csc_cfg *csc_ptr; const struct dpu_sspp_sub_blks *pipe_sblk; - char pipe_name[DPU_NAME_SIZE]; /* debugfs related stuff */ struct dentry *debugfs_root; @@ -1429,7 +1428,7 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane) /* create overall sub-directory for the pipe */ pdpu->debugfs_root = - debugfs_create_dir(pdpu->pipe_name, + debugfs_create_dir(plane->name, plane->dev->primary->debugfs_root); /* don't error check these */ @@ -1660,12 +1659,9 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, /* success! finalize initialization */ drm_plane_helper_add(plane, &dpu_plane_helper_funcs); - /* save user friendly pipe name for later */ - snprintf(pdpu->pipe_name, DPU_NAME_SIZE, "plane%u", plane->base.id); - mutex_init(&pdpu->lock); - DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", pdpu->pipe_name, + DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", plane->name, pipe, plane->base.id, master_plane_id); return plane;
Re: [Freedreno] [PATCH 04/11] drm/msm/dpu: remove stage_cfg from struct dpu_crtc
On 2021-09-30 06:59, Dmitry Baryshkov wrote: The stage_cfg is not used outside of _dpu_crtc_blend_setup(), so remove the temporary config from global struct. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 11 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 2 -- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 768012243b44..19f0715a4089 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -207,7 +207,8 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc) } static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, - struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer) + struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer, + struct dpu_hw_stage_cfg *stage_cfg) { struct drm_plane *plane; struct drm_framebuffer *fb; @@ -216,7 +217,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, struct dpu_plane_state *pstate = NULL; struct dpu_format *format; struct dpu_hw_ctl *ctl = mixer->lm_ctl; - struct dpu_hw_stage_cfg *stage_cfg = &dpu_crtc->stage_cfg; u32 flush_mask; uint32_t stage_idx, lm_idx; @@ -292,6 +292,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) struct dpu_crtc_mixer *mixer = cstate->mixers; struct dpu_hw_ctl *ctl; struct dpu_hw_mixer *lm; + struct dpu_hw_stage_cfg stage_cfg; int i; DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name); @@ -305,9 +306,9 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) } /* initialize stage cfg */ - memset(&dpu_crtc->stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg)); + memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg)); - _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer); + _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg); for (i = 0; i < cstate->num_mixers; i++) { ctl = mixer[i].lm_ctl; @@ -328,7 +329,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) mixer[i].flush_mask); ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx, - &dpu_crtc->stage_cfg); + &stage_cfg); } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index cec3474340e8..30535acec670 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -116,7 +116,6 @@ struct dpu_crtc_frame_event { * @drm_requested_vblank : Whether vblanks have been enabled in the encoder * @property_info : Opaque structure for generic property support * @property_defaults : Array of default values for generic property support - * @stage_cfg : H/w mixer stage configuration * @debugfs_root : Parent of debugfs node * @vblank_cb_count : count of vblank callback since last reset * @play_count: frame count between crtc enable and disable @@ -147,7 +146,6 @@ struct dpu_crtc { struct drm_pending_vblank_event *event; u32 vsync_count; - struct dpu_hw_stage_cfg stage_cfg; struct dentry *debugfs_root; u32 vblank_cb_count;
Re: [Freedreno] [PATCH 05/11] drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
On 2021-09-30 06:59, Dmitry Baryshkov wrote: struct dpu_hw_pipe_cfg represents an interim state during atomic update/color fill, so move it out of struct dpu_plane. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 -- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index ef3737642b0c..5288b5b824f8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -104,7 +104,6 @@ struct dpu_plane { uint32_t features; /* capabilities from catalog */ struct dpu_hw_pipe *pipe_hw; - struct dpu_hw_pipe_cfg pipe_cfg; uint32_t color_fill; bool is_error; bool is_rt_pipe; @@ -143,14 +142,15 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane) * _dpu_plane_calc_bw - calculate bandwidth required for a plane * @plane: Pointer to drm plane. * @fb: Pointer to framebuffer associated with the given plane + * @pipe_cfg: Pointer to pipe configuration * Result: Updates calculated bandwidth in the plane state. * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest) * Prefill BW Equation: line src bytes * line_time */ static void _dpu_plane_calc_bw(struct drm_plane *plane, - struct drm_framebuffer *fb) + struct drm_framebuffer *fb, + struct dpu_hw_pipe_cfg *pipe_cfg) { - struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_plane_state *pstate; struct drm_display_mode *mode; const struct dpu_format *fmt = NULL; @@ -167,9 +167,9 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane, fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier); - src_width = drm_rect_width(&pdpu->pipe_cfg.src_rect); - src_height = drm_rect_height(&pdpu->pipe_cfg.src_rect); - dst_height = drm_rect_height(&pdpu->pipe_cfg.dst_rect); + src_width = drm_rect_width(&pipe_cfg->src_rect); + src_height = drm_rect_height(&pipe_cfg->src_rect); + dst_height = drm_rect_height(&pipe_cfg->dst_rect); fps = drm_mode_vrefresh(mode); vbp = mode->vtotal - mode->vsync_end; vpw = mode->vsync_end - mode->vsync_start; @@ -200,12 +200,12 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane, /** * _dpu_plane_calc_clk - calculate clock required for a plane * @plane: Pointer to drm plane. + * @pipe_cfg: Pointer to pipe configuration * Result: Updates calculated clock in the plane state. * Clock equation: dst_w * v_total * fps * (src_h / dst_h) */ -static void _dpu_plane_calc_clk(struct drm_plane *plane) +static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_pipe_cfg *pipe_cfg) { - struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_plane_state *pstate; struct drm_display_mode *mode; int dst_width, src_height, dst_height, fps; @@ -213,9 +213,9 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane) pstate = to_dpu_plane_state(plane->state); mode = &plane->state->crtc->mode; - src_height = drm_rect_height(&pdpu->pipe_cfg.src_rect); - dst_width = drm_rect_width(&pdpu->pipe_cfg.dst_rect); - dst_height = drm_rect_height(&pdpu->pipe_cfg.dst_rect); + src_height = drm_rect_height(&pipe_cfg->src_rect); + dst_width = drm_rect_width(&pipe_cfg->dst_rect); + dst_height = drm_rect_height(&pipe_cfg->dst_rect); fps = drm_mode_vrefresh(mode); pstate->plane_clk = @@ -252,14 +252,17 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, fixed_buff_size = pdpu->catalog->caps->pixel_ram_size; list_for_each_entry(tmp, &pdpu->mplane_list, mplane_list) { + u32 tmp_width; + if (!tmp->base.state->visible) continue; + tmp_width = drm_rect_width(&tmp->base.state->src) >> 16; DPU_DEBUG("plane%d/%d src_width:%d/%d\n", pdpu->base.base.id, tmp->base.base.id, src_width, - drm_rect_width(&tmp->pipe_cfg.src_rect)); + tmp_width); src_width = max_t(u32, src_width, - drm_rect_width(&tmp->pipe_cfg.src_rect)); + tmp_width); } if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) { @@ -319,9 +322,10 @@ static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, * _dpu_plane_set_qos_lut - set QoS LUT of the given plane * @plane: Pointer to drm plane * @fb:Pointer to framebuffer associated with the given plane + * @pipe_cfg: Pointer to pipe configuration */ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, - struct drm
Re: [Freedreno] [PATCH 06/11] drm/msm/dpu: drop scaler config from plane state
On 2021-09-30 06:59, Dmitry Baryshkov wrote: Scaler and pixel_ext configuration does not contain a long living state, it is used only during plane update, so remove these two fiels from fiels ---> fields dpu_plane_state and allocate them on stack. Signed-off-by: Dmitry Baryshkov While addressing the bugs reported by the smatch tool, I saw that pe is not being used at the moment. 412 static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx, 413 struct dpu_hw_pipe_cfg *sspp, 414 struct dpu_hw_pixel_ext *pe, 415 void *scaler_cfg) 416 { 417 u32 idx; 418 struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg; 419 420 (void)pe; 421 if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp 422 || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk) 423 return; 424 425 dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx, 426 ctx->cap->sblk->scaler_blk.version, 427 sspp->layout.format); 428 } As part of this change, can you please drop this? --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 59 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 6 --- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 5288b5b824f8..4259c4ecde9b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -542,14 +542,12 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu, struct dpu_plane_state *pstate, uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h, struct dpu_hw_scaler3_cfg *scale_cfg, + struct dpu_hw_pixel_ext *pixel_ext, const struct dpu_format *fmt, uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v) { uint32_t i; - memset(scale_cfg, 0, sizeof(*scale_cfg)); - memset(&pstate->pixel_ext, 0, sizeof(struct dpu_hw_pixel_ext)); - scale_cfg->phase_step_x[DPU_SSPP_COMP_0] = mult_frac((1 << PHASE_STEP_SHIFT), src_w, dst_w); scale_cfg->phase_step_y[DPU_SSPP_COMP_0] = @@ -588,9 +586,9 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu, scale_cfg->preload_y[i] = DPU_QSEED3_DEFAULT_PRELOAD_V; } - pstate->pixel_ext.num_ext_pxls_top[i] = + pixel_ext->num_ext_pxls_top[i] = scale_cfg->src_height[i]; - pstate->pixel_ext.num_ext_pxls_left[i] = + pixel_ext->num_ext_pxls_left[i] = scale_cfg->src_width[i]; } if (!(DPU_FORMAT_IS_YUV(fmt)) && (src_h == dst_h) @@ -660,6 +658,11 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu, struct dpu_hw_pipe_cfg *pipe_cfg) { const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format); + struct dpu_hw_scaler3_cfg scaler3_cfg; + struct dpu_hw_pixel_ext pixel_ext; + + memset(&scaler3_cfg, 0, sizeof(scaler3_cfg)); + memset(&pixel_ext, 0, sizeof(pixel_ext)); /* don't chroma subsample if decimating */ /* update scaler. calculate default config for QSEED3 */ @@ -668,8 +671,23 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu, drm_rect_height(&pipe_cfg->src_rect), drm_rect_width(&pipe_cfg->dst_rect), drm_rect_height(&pipe_cfg->dst_rect), - &pstate->scaler3_cfg, fmt, + &scaler3_cfg, &pixel_ext, fmt, info->hsub, info->vsub); + + if (pdpu->pipe_hw->ops.setup_pe) + pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw, + &pixel_ext); + + /** +* when programmed in multirect mode, scalar block will be +* bypassed. Still we need to update alpha and bitwidth +* ONLY for RECT0 +*/ + if (pdpu->pipe_hw->ops.setup_scaler && + pstate->multirect_index != DPU_SSPP_RECT_1) + pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw, + pipe_cfg, &pixel_ext, + &scaler3_cfg); } /** @@ -710,7 +728,6 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu, drm_rect_width(&pipe_cfg.dst_rect); pipe_cfg.src_rect.y2 = drm_rect_height(&pipe_cfg.dst_rect); - _dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg); if (pdpu->pipe_hw->ops.setup_format) pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, @@ -722,15 +739,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu, &pipe_cfg,
Re: [Freedreno] [PATCH 07/11] drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
On 2021-09-30 06:59, Dmitry Baryshkov wrote: Simplify code surrounding CSC table setup by removing struct dpu_csc_cfg pointer from dpu_plane and getting it directly at the CSC setup time. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 96 +++-- 5 files changed, 54 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index cbafb61404d0..103d4bd7585b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -537,7 +537,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx, } static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx, - struct dpu_csc_cfg *data) + const struct dpu_csc_cfg *data) { u32 idx; bool csc10 = false; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h index 27263bc1a1ef..e8939d7387cb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h @@ -262,7 +262,7 @@ struct dpu_hw_sspp_ops { * @ctx: Pointer to pipe context * @data: Pointer to config structure */ - void (*setup_csc)(struct dpu_hw_pipe *ctx, struct dpu_csc_cfg *data); + void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data); /** * setup_solidfill - enable/disable colorfill diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c index f94584c982cd..aad85116b0a0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -374,7 +374,7 @@ u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c, void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, u32 csc_reg_off, - struct dpu_csc_cfg *data, bool csc10) + const struct dpu_csc_cfg *data, bool csc10) { static const u32 matrix_shift = 7; u32 clamp_shift = csc10 ? 16 : 8; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h index ff3cffde84cd..bc2fdb2b8f5f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -321,6 +321,6 @@ u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c, void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, u32 csc_reg_off, - struct dpu_csc_cfg *data, bool csc10); + const struct dpu_csc_cfg *data, bool csc10); #endif /* _DPU_HW_UTIL_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 4259c4ecde9b..b8836c089863 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -90,7 +90,6 @@ enum dpu_plane_qos { /* * struct dpu_plane - local dpu plane structure * @aspace: address space pointer - * @csc_ptr: Points to dpu_csc_cfg structure to use for current * @mplane_list: List of multirect planes of the same pipe * @catalog: Points to dpu catalog structure * @revalidate: force revalidation of all the plane properties @@ -111,8 +110,6 @@ struct dpu_plane { struct list_head mplane_list; struct dpu_mdss_cfg *catalog; - struct dpu_csc_cfg *csc_ptr; - const struct dpu_sspp_sub_blks *pipe_sblk; /* debugfs related stuff */ @@ -605,51 +602,59 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu, scale_cfg->enable = 1; } -static void _dpu_plane_setup_csc(struct dpu_plane *pdpu) -{ - static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = { - { - /* S15.16 format */ - 0x00012A00, 0x, 0x00019880, - 0x00012A00, 0x9B80, 0x3000, - 0x00012A00, 0x00020480, 0x, +static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = { + { + /* S15.16 format */ + 0x00012A00, 0x, 0x00019880, + 0x00012A00, 0x9B80, 0x3000, + 0x00012A00, 0x00020480, 0x, + }, + /* signed bias */ + { 0xfff0, 0xff80, 0xff80,}, + { 0x0, 0x0, 0x0,}, + /* unsigned clamp */ + { 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,}, + { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,}, +}; + +static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = { + { + /* S15.16 format */ + 0x00012A00, 0x, 0x00019880, + 0x00012A00, 0x9B80, 0x3000, + 0x00012A00, 0x00020480, 0x,
Re: [Freedreno] [PATCH 08/11] drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
On 2021-09-30 06:59, Dmitry Baryshkov wrote: Remove struct dpu_hw_pipe_cdp_cfg instance from dpu_plane, it is an interim configuration structure. Allocate it on stack instead. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 14 +++--- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 2 -- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index b8836c089863..d3ae0cb2047c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1182,20 +1182,20 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) pstate->multirect_index); if (pdpu->pipe_hw->ops.setup_cdp) { - struct dpu_hw_pipe_cdp_cfg *cdp_cfg = &pstate->cdp_cfg; + struct dpu_hw_pipe_cdp_cfg cdp_cfg; - memset(cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg)); + memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg)); - cdp_cfg->enable = pdpu->catalog->perf.cdp_cfg + cdp_cfg.enable = pdpu->catalog->perf.cdp_cfg [DPU_PERF_CDP_USAGE_RT].rd_enable; - cdp_cfg->ubwc_meta_enable = + cdp_cfg.ubwc_meta_enable = DPU_FORMAT_IS_UBWC(fmt); - cdp_cfg->tile_amortize_enable = + cdp_cfg.tile_amortize_enable = DPU_FORMAT_IS_UBWC(fmt) || DPU_FORMAT_IS_TILE(fmt); - cdp_cfg->preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64; + cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64; - pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, cdp_cfg); + pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, &cdp_cfg); } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h index 087194be3c22..1ee5ca5fcdf7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h @@ -23,7 +23,6 @@ * @multirect_index: index of the rectangle of SSPP * @multirect_mode: parallel or time multiplex multirect mode * @pending: whether the current update is still pending - * @cdp_cfg: CDP configuration * @plane_fetch_bw: calculated BW per plane * @plane_clk: calculated clk per plane */ @@ -36,7 +35,6 @@ struct dpu_plane_state { uint32_t multirect_mode; bool pending; - struct dpu_hw_pipe_cdp_cfg cdp_cfg; u64 plane_fetch_bw; u64 plane_clk; };
Re: [Freedreno] [PATCH 09/11] drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
On 2021-09-30 07:00, Dmitry Baryshkov wrote: Do not cache hw_pipe's features in dpu_plane. Use pdpu->pipe_hw->cap->features directly. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index d3ae0cb2047c..af403c0d3d7d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -100,7 +100,6 @@ struct dpu_plane { struct mutex lock; enum dpu_sspp pipe; - uint32_t features; /* capabilities from catalog */ struct dpu_hw_pipe *pipe_hw; uint32_t color_fill; @@ -644,7 +643,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons if (!DPU_FORMAT_IS_YUV(fmt)) return NULL; - if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->features) + if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features) csc_ptr = &dpu_csc10_YUV2RGB_601L; else csc_ptr = &dpu_csc_YUV2RGB_601L; @@ -1012,8 +1011,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1; if (DPU_FORMAT_IS_YUV(fmt) && - (!(pdpu->features & DPU_SSPP_SCALER) || -!(pdpu->features & (BIT(DPU_SSPP_CSC) + (!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) || +!(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC) | BIT(DPU_SSPP_CSC_10BIT) { DPU_DEBUG_PLANE(pdpu, "plane doesn't have scaler/csc for yuv\n"); @@ -1439,8 +1438,8 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane) plane->dev->primary->debugfs_root); /* don't error check these */ - debugfs_create_x32("features", 0600, - pdpu->debugfs_root, &pdpu->features); + debugfs_create_xul("features", 0600, + pdpu->debugfs_root, (unsigned long *)&pdpu->pipe_hw->cap->features); /* add register dump support */ dpu_debugfs_setup_regset32(&pdpu->debugfs_src, @@ -1613,7 +1612,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, } /* cache features mask for later */ - pdpu->features = pdpu->pipe_hw->cap->features; pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk; if (!pdpu->pipe_sblk) { DPU_ERROR("[%u]invalid sblk\n", pipe);
Re: [Freedreno] [PATCH 10/11] drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
On 2021-09-30 07:00, Dmitry Baryshkov wrote: Do not cache hw_pipe's sblk in dpu_plane. Use pdpu->pipe_hw->cap->sblk directly. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 25 --- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index af403c0d3d7d..d8018e664925 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -109,8 +109,6 @@ struct dpu_plane { struct list_head mplane_list; struct dpu_mdss_cfg *catalog; - const struct dpu_sspp_sub_blks *pipe_sblk; - /* debugfs related stuff */ struct dentry *debugfs_root; struct dpu_debugfs_regset32 debugfs_src; @@ -425,9 +423,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg)); if (flags & DPU_PLANE_QOS_VBLANK_CTRL) { - pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank; + pipe_qos_cfg.creq_vblank = pdpu->pipe_hw->cap->sblk->creq_vblank; pipe_qos_cfg.danger_vblank = - pdpu->pipe_sblk->danger_vblank; + pdpu->pipe_hw->cap->sblk->danger_vblank; pipe_qos_cfg.vblank_en = enable; } @@ -982,10 +980,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); - min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale); + min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale); ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, min_scale, - pdpu->pipe_sblk->maxdwnscale << 16, + pdpu->pipe_hw->cap->sblk->maxdwnscale << 16, true, true); if (ret) { DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret); @@ -1611,20 +1609,13 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, goto clean_sspp; } - /* cache features mask for later */ - pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk; - if (!pdpu->pipe_sblk) { - DPU_ERROR("[%u]invalid sblk\n", pipe); - goto clean_sspp; - } - if (pdpu->is_virtual) { - format_list = pdpu->pipe_sblk->virt_format_list; - num_formats = pdpu->pipe_sblk->virt_num_formats; + format_list = pdpu->pipe_hw->cap->sblk->virt_format_list; + num_formats = pdpu->pipe_hw->cap->sblk->virt_num_formats; } else { - format_list = pdpu->pipe_sblk->format_list; - num_formats = pdpu->pipe_sblk->num_formats; + format_list = pdpu->pipe_hw->cap->sblk->format_list; + num_formats = pdpu->pipe_hw->cap->sblk->num_formats; } ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
Re: [Freedreno] [PATCH 11/11] drm/msm/dpu: rip out debugfs support from dpu_plane
On 2021-09-30 07:00, Dmitry Baryshkov wrote: In preparations of virtualizing the dpu_plane rip out debugfs support from dpu_plane (as it is mostly used to expose plane's pipe registers). Also move disable_danger file to danger/ debugfs subdir where it belongs. Signed-off-by: Dmitry Baryshkov I am yet to review the second part of the virtual plane series to understand why this removal is necessary so I might be missing something. The plane's debugfs holds useful information to check a few things rightaway. So if there is some misconfiguration or corruption in addition to the plane state, this is good to check. localhost /sys/kernel/debug/dri/1/plane35 # cat src_blk [4000] 03000556 03000556 [4010] 00414000 0040e000 [4020] 1600 0080 [4030] 800236ff 03010002 8001 [4040] 0030 000c0087 0707 [4050] [4060] 0001 [4070] 44556677 00112233 [4080] [4090] [40a0] 00414000 0040e000 [40b0] [40c0] [40d0] 0003f820 [40e0] 0003e2c4 [40f0] 000f000f 00010330 02e402e4 [4100] 03000556 [4110] 03000556 [4120] 03000556 [4130] 000f 000f [4140] So I would like to keep this functionality unless there is some compelling reason to remove this. BTW, are you going to submit the second half as a new series now that most of the first one has been reviewed? --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 123 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 69 - drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 171 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 6 + 4 files changed, 69 insertions(+), 300 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index ae48f41821cf..fe33273cdf57 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -101,84 +101,85 @@ static int dpu_debugfs_safe_stats_show(struct seq_file *s, void *v) } DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_safe_stats); -static void dpu_debugfs_danger_init(struct dpu_kms *dpu_kms, - struct dentry *parent) +static ssize_t _dpu_plane_danger_read(struct file *file, + char __user *buff, size_t count, loff_t *ppos) { - struct dentry *entry = debugfs_create_dir("danger", parent); + struct dpu_kms *kms = file->private_data; + int len; + char buf[40]; - debugfs_create_file("danger_status", 0600, entry, - dpu_kms, &dpu_debugfs_danger_stats_fops); - debugfs_create_file("safe_status", 0600, entry, - dpu_kms, &dpu_debugfs_safe_stats_fops); + len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl); + + return simple_read_from_buffer(buff, count, ppos, buf, len); } -static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data) +static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool enable) { - struct dpu_debugfs_regset32 *regset = s->private; - struct dpu_kms *dpu_kms = regset->dpu_kms; - void __iomem *base; - uint32_t i, addr; - - if (!dpu_kms->mmio) - return 0; - - base = dpu_kms->mmio + regset->offset; - - /* insert padding spaces, if needed */ - if (regset->offset & 0xF) { - seq_printf(s, "[%x]", regset->offset & ~0xF); - for (i = 0; i < (regset->offset & 0xF); i += 4) - seq_puts(s, " "); - } - - pm_runtime_get_sync(&dpu_kms->pdev->dev); - - /* main register output */ - for (i = 0; i < regset->blk_len; i += 4) { - addr = regset->offset + i; - if ((addr & 0xF) == 0x0) - seq_printf(s, i ? "\n[%x]" : "[%x]", addr); - seq_printf(s, " %08x", readl_relaxed(base + i)); + struct drm_plane *plane; + + drm_for_each_plane(plane, kms->dev) { + if (plane->fb && plane->state) { + dpu_plane_danger_signal_ctrl(plane, enable); + DPU_DEBUG("plane:%d img:%dx%d ", + plane->base.id, plane->fb->width, + plane->fb->height); + DPU_DEBUG("src[%d,%d,%d,%d] dst[%d,%d,%d,%d]\n", + plane->state->src_x >> 16, + plane->state->src_y >> 16, + plane->state->src_w >> 16, + plane->state->src_h >> 16,