diff --git a/.clang-format b/.clang-format index 6a3de86ab27a..5ef5743b77c9 100644 --- a/.clang-format +++ b/.clang-format @@ -167,7 +167,7 @@ ForEachMacros: - 'drm_connector_for_each_possible_encoder' - 'drm_exec_for_each_locked_object' - 'drm_exec_for_each_locked_object_reverse' - - 'drm_for_each_bridge_in_chain_scoped' + - 'drm_for_each_bridge_in_chain' - 'drm_for_each_connector_iter' - 'drm_for_each_crtc' - 'drm_for_each_crtc_reverse' diff --git a/drivers/gpu/drm/adp/adp-mipi.c b/drivers/gpu/drm/adp/adp-mipi.c index cba7d32150a9..232bb9539423 100644 --- a/drivers/gpu/drm/adp/adp-mipi.c +++ b/drivers/gpu/drm/adp/adp-mipi.c @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -222,6 +223,9 @@ static int adp_dsi_bridge_attach(struct drm_bridge *bridge, } static const struct drm_bridge_funcs adp_dsi_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = adp_dsi_bridge_attach, }; diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c index f3fe47b12edc..eba5c6dcb5ad 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c @@ -566,7 +566,8 @@ anx6345_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void anx6345_bridge_disable(struct drm_bridge *bridge) +static void anx6345_bridge_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct anx6345 *anx6345 = bridge_to_anx6345(bridge); @@ -580,7 +581,8 @@ static void anx6345_bridge_disable(struct drm_bridge *bridge) anx6345_poweroff(anx6345); } -static void anx6345_bridge_enable(struct drm_bridge *bridge) +static void anx6345_bridge_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct anx6345 *anx6345 = bridge_to_anx6345(bridge); int err; @@ -600,11 +602,14 @@ static void anx6345_bridge_enable(struct drm_bridge *bridge) } static const struct drm_bridge_funcs anx6345_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = anx6345_bridge_attach, .detach = anx6345_bridge_detach, .mode_valid = anx6345_bridge_mode_valid, - .disable = anx6345_bridge_disable, - .enable = anx6345_bridge_enable, + .atomic_disable = anx6345_bridge_disable, + .atomic_enable = anx6345_bridge_enable, }; static void unregister_i2c_dummy_clients(struct anx6345 *anx6345) diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c index ba0fc149a9e7..32186efa6f50 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c @@ -937,7 +937,8 @@ anx78xx_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void anx78xx_bridge_disable(struct drm_bridge *bridge) +static void anx78xx_bridge_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct anx78xx *anx78xx = bridge_to_anx78xx(bridge); @@ -975,7 +976,8 @@ static void anx78xx_bridge_mode_set(struct drm_bridge *bridge, mutex_unlock(&anx78xx->lock); } -static void anx78xx_bridge_enable(struct drm_bridge *bridge) +static void anx78xx_bridge_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct anx78xx *anx78xx = bridge_to_anx78xx(bridge); int err; @@ -992,12 +994,15 @@ static void anx78xx_bridge_enable(struct drm_bridge *bridge) } static const struct drm_bridge_funcs anx78xx_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = anx78xx_bridge_attach, .detach = anx78xx_bridge_detach, .mode_valid = anx78xx_bridge_mode_valid, - .disable = anx78xx_bridge_disable, + .atomic_disable = anx78xx_bridge_disable, .mode_set = anx78xx_bridge_mode_set, - .enable = anx78xx_bridge_enable, + .atomic_enable = anx78xx_bridge_enable, }; static irqreturn_t anx78xx_hpd_threaded_handler(int irq, void *data) diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c index 1ed21a8713bf..169939d23310 100644 --- a/drivers/gpu/drm/bridge/aux-bridge.c +++ b/drivers/gpu/drm/bridge/aux-bridge.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -104,6 +105,9 @@ static int drm_aux_bridge_attach(struct drm_bridge *bridge, } static const struct drm_bridge_funcs drm_aux_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = drm_aux_bridge_attach, }; diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c index f02a38a2638a..a2e525aa5788 100644 --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -165,6 +166,9 @@ static int drm_aux_hpd_bridge_attach(struct drm_bridge *bridge, } static const struct drm_bridge_funcs drm_aux_hpd_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = drm_aux_hpd_bridge_attach, }; diff --git a/drivers/gpu/drm/bridge/chrontel-ch7033.c b/drivers/gpu/drm/bridge/chrontel-ch7033.c index a237c65ebd69..92d464727e41 100644 --- a/drivers/gpu/drm/bridge/chrontel-ch7033.c +++ b/drivers/gpu/drm/bridge/chrontel-ch7033.c @@ -330,7 +330,8 @@ static enum drm_mode_status ch7033_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void ch7033_bridge_disable(struct drm_bridge *bridge) +static void ch7033_bridge_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge); @@ -338,7 +339,8 @@ static void ch7033_bridge_disable(struct drm_bridge *bridge) regmap_update_bits(priv->regmap, 0x52, RESETDB, 0x00); } -static void ch7033_bridge_enable(struct drm_bridge *bridge) +static void ch7033_bridge_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct ch7033_priv *priv = bridge_to_ch7033_priv(bridge); @@ -514,11 +516,14 @@ static void ch7033_bridge_mode_set(struct drm_bridge *bridge, } static const struct drm_bridge_funcs ch7033_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = ch7033_bridge_attach, .detach = ch7033_bridge_detach, .mode_valid = ch7033_bridge_mode_valid, - .disable = ch7033_bridge_disable, - .enable = ch7033_bridge_enable, + .atomic_disable = ch7033_bridge_disable, + .atomic_enable = ch7033_bridge_enable, .mode_set = ch7033_bridge_mode_set, }; diff --git a/drivers/gpu/drm/bridge/cros-ec-anx7688.c b/drivers/gpu/drm/bridge/cros-ec-anx7688.c index a35dae9b56e2..da16c793e3ba 100644 --- a/drivers/gpu/drm/bridge/cros-ec-anx7688.c +++ b/drivers/gpu/drm/bridge/cros-ec-anx7688.c @@ -5,6 +5,7 @@ * Copyright 2020 Google LLC */ +#include #include #include #include @@ -92,6 +93,9 @@ static bool cros_ec_anx7688_bridge_mode_fixup(struct drm_bridge *bridge, } static const struct drm_bridge_funcs cros_ec_anx7688_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .mode_fixup = cros_ec_anx7688_bridge_mode_fixup, }; diff --git a/drivers/gpu/drm/bridge/lontium-lt8713sx.c b/drivers/gpu/drm/bridge/lontium-lt8713sx.c index cee485adf5e5..4a6420b876da 100644 --- a/drivers/gpu/drm/bridge/lontium-lt8713sx.c +++ b/drivers/gpu/drm/bridge/lontium-lt8713sx.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -508,6 +509,9 @@ static const struct attribute_group *lt8713sx_attr_groups[] = { }; static const struct drm_bridge_funcs lt8713sx_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = lt8713sx_bridge_attach, }; diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c index 729b12b67470..df5d07e7644c 100644 --- a/drivers/gpu/drm/bridge/lontium-lt8912b.c +++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c @@ -457,7 +457,8 @@ static void lt8912_bridge_mode_set(struct drm_bridge *bridge, drm_display_mode_to_videomode(adj, <->mode); } -static void lt8912_bridge_enable(struct drm_bridge *bridge) +static void lt8912_bridge_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct lt8912 *lt = bridge_to_lt8912(bridge); @@ -634,11 +635,14 @@ static const struct drm_edid *lt8912_bridge_edid_read(struct drm_bridge *bridge, } static const struct drm_bridge_funcs lt8912_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = lt8912_bridge_attach, .detach = lt8912_bridge_detach, .mode_valid = lt8912_bridge_mode_valid, .mode_set = lt8912_bridge_mode_set, - .enable = lt8912_bridge_enable, + .atomic_enable = lt8912_bridge_enable, .detect = lt8912_bridge_detect, .edid_read = lt8912_bridge_edid_read, }; diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 9427cc2358ae..6625ba23761c 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -465,6 +465,9 @@ static void lt9611uxc_hdmi_audio_shutdown(struct drm_bridge *bridge, } static const struct drm_bridge_funcs lt9611uxc_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = lt9611uxc_bridge_attach, .mode_valid = lt9611uxc_bridge_mode_valid, .mode_set = lt9611uxc_bridge_mode_set, diff --git a/drivers/gpu/drm/bridge/lvds-codec.c b/drivers/gpu/drm/bridge/lvds-codec.c index d1135dc3b99f..a82ea0c944eb 100644 --- a/drivers/gpu/drm/bridge/lvds-codec.c +++ b/drivers/gpu/drm/bridge/lvds-codec.c @@ -43,7 +43,8 @@ static int lvds_codec_attach(struct drm_bridge *bridge, bridge, flags); } -static void lvds_codec_enable(struct drm_bridge *bridge) +static void lvds_codec_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct lvds_codec *lvds_codec = to_lvds_codec(bridge); int ret; @@ -59,7 +60,8 @@ static void lvds_codec_enable(struct drm_bridge *bridge) gpiod_set_value_cansleep(lvds_codec->powerdown_gpio, 0); } -static void lvds_codec_disable(struct drm_bridge *bridge) +static void lvds_codec_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct lvds_codec *lvds_codec = to_lvds_codec(bridge); int ret; @@ -100,8 +102,8 @@ lvds_codec_atomic_get_input_bus_fmts(struct drm_bridge *bridge, static const struct drm_bridge_funcs funcs = { .attach = lvds_codec_attach, - .enable = lvds_codec_enable, - .disable = lvds_codec_disable, + .atomic_enable = lvds_codec_enable, + .atomic_disable = lvds_codec_disable, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_create_state = drm_atomic_helper_bridge_create_state, diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c index 2d02cc69f237..25ff0a0acc93 100644 --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c @@ -214,6 +214,9 @@ static int ge_b850v3_lvds_attach(struct drm_bridge *bridge, } static const struct drm_bridge_funcs ge_b850v3_lvds_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = ge_b850v3_lvds_attach, .detect = ge_b850v3_lvds_bridge_detect, .edid_read = ge_b850v3_lvds_edid_read, diff --git a/drivers/gpu/drm/bridge/microchip-lvds.c b/drivers/gpu/drm/bridge/microchip-lvds.c index 5fb8633f43c5..dd4ffc9f4df3 100644 --- a/drivers/gpu/drm/bridge/microchip-lvds.c +++ b/drivers/gpu/drm/bridge/microchip-lvds.c @@ -167,6 +167,9 @@ static void mchp_lvds_atomic_disable(struct drm_bridge *bridge, } static const struct drm_bridge_funcs mchp_lvds_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = mchp_lvds_attach, .atomic_enable = mchp_lvds_atomic_enable, .atomic_disable = mchp_lvds_atomic_disable, diff --git a/drivers/gpu/drm/bridge/nxp-ptn3460.c b/drivers/gpu/drm/bridge/nxp-ptn3460.c index 7acb11f16dc1..a9b4ac2defc9 100644 --- a/drivers/gpu/drm/bridge/nxp-ptn3460.c +++ b/drivers/gpu/drm/bridge/nxp-ptn3460.c @@ -111,7 +111,8 @@ static int ptn3460_select_edid(struct ptn3460_bridge *ptn_bridge) return 0; } -static void ptn3460_pre_enable(struct drm_bridge *bridge) +static void ptn3460_pre_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge); int ret; @@ -139,7 +140,8 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge) ptn_bridge->enabled = true; } -static void ptn3460_disable(struct drm_bridge *bridge) +static void ptn3460_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge); @@ -163,7 +165,7 @@ static const struct drm_edid *ptn3460_edid_read(struct drm_bridge *bridge, int ret; power_off = !ptn_bridge->enabled; - ptn3460_pre_enable(&ptn_bridge->bridge); + ptn3460_pre_enable(&ptn_bridge->bridge, NULL); edid = kmalloc(EDID_LENGTH, GFP_KERNEL); if (!edid) { @@ -182,7 +184,7 @@ static const struct drm_edid *ptn3460_edid_read(struct drm_bridge *bridge, out: if (power_off) - ptn3460_disable(&ptn_bridge->bridge); + ptn3460_disable(&ptn_bridge->bridge, NULL); return drm_edid; } @@ -248,8 +250,11 @@ static int ptn3460_bridge_attach(struct drm_bridge *bridge, } static const struct drm_bridge_funcs ptn3460_bridge_funcs = { - .pre_enable = ptn3460_pre_enable, - .disable = ptn3460_disable, + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_pre_enable = ptn3460_pre_enable, + .atomic_disable = ptn3460_disable, .attach = ptn3460_bridge_attach, .edid_read = ptn3460_edid_read, }; diff --git a/drivers/gpu/drm/bridge/of-display-mode-bridge.c b/drivers/gpu/drm/bridge/of-display-mode-bridge.c index e66dae168fd0..af3e727e91c9 100644 --- a/drivers/gpu/drm/bridge/of-display-mode-bridge.c +++ b/drivers/gpu/drm/bridge/of-display-mode-bridge.c @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -52,6 +53,9 @@ static int of_display_mode_bridge_get_modes(struct drm_bridge *bridge, } static const struct drm_bridge_funcs of_display_mode_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = of_display_mode_bridge_attach, .get_modes = of_display_mode_bridge_get_modes, }; diff --git a/drivers/gpu/drm/bridge/parade-ps8622.c b/drivers/gpu/drm/bridge/parade-ps8622.c index f879a1df077d..33844db753aa 100644 --- a/drivers/gpu/drm/bridge/parade-ps8622.c +++ b/drivers/gpu/drm/bridge/parade-ps8622.c @@ -336,7 +336,8 @@ static const struct backlight_ops ps8622_backlight_ops = { .update_status = ps8622_backlight_update, }; -static void ps8622_pre_enable(struct drm_bridge *bridge) +static void ps8622_pre_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct ps8622_bridge *ps8622 = bridge_to_ps8622(bridge); int ret; @@ -381,13 +382,15 @@ static void ps8622_pre_enable(struct drm_bridge *bridge) ps8622->enabled = true; } -static void ps8622_disable(struct drm_bridge *bridge) +static void ps8622_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { /* Delay after panel is disabled */ msleep(PS8622_PWMO_END_T12_MS); } -static void ps8622_post_disable(struct drm_bridge *bridge) +static void ps8622_post_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct ps8622_bridge *ps8622 = bridge_to_ps8622(bridge); @@ -428,9 +431,12 @@ static int ps8622_attach(struct drm_bridge *bridge, } static const struct drm_bridge_funcs ps8622_bridge_funcs = { - .pre_enable = ps8622_pre_enable, - .disable = ps8622_disable, - .post_disable = ps8622_post_disable, + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_pre_enable = ps8622_pre_enable, + .atomic_disable = ps8622_disable, + .atomic_post_disable = ps8622_post_disable, .attach = ps8622_attach, }; diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 5788066d479e..25ab475309e8 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -1919,7 +1919,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host, /* * of_graph_get_remote_node() produces a noisy error message if port * node isn't found and the absence of the port is a legit case here, - * so at first we silently check whether graph presents in the + * so at first we silently check whether a graph is present in the * device-tree node. */ if (!of_graph_is_present(np)) diff --git a/drivers/gpu/drm/bridge/sii9234.c b/drivers/gpu/drm/bridge/sii9234.c index bb1bed03eb5b..be67642ab7d3 100644 --- a/drivers/gpu/drm/bridge/sii9234.c +++ b/drivers/gpu/drm/bridge/sii9234.c @@ -13,6 +13,7 @@ * Dharam Kumar */ #include +#include #include #include #include @@ -339,7 +340,7 @@ static int sii9234_cbus_reset(struct sii9234 *ctx) return sii9234_clear_error(ctx); } -/* Require to chek mhl imformation of samsung in cbus_init_register */ +/* Require to check mhl information of samsung in cbus_init_register */ static int sii9234_cbus_init(struct sii9234 *ctx) { cbus_writeb(ctx, 0x07, 0xF2); @@ -614,7 +615,7 @@ static void sii9234_cable_out(struct sii9234 *ctx) disable_irq(to_i2c_client(ctx->dev)->irq); tpi_writeb(ctx, TPI_DPD_REG, 0); - /* Turn on&off hpd festure for only QCT HDMI */ + /* Turn on&off hpd feature for only QCT HDMI */ sii9234_hw_off(ctx); ctx->state = ST_OFF; @@ -708,7 +709,7 @@ static enum sii9234_state sii9234_rsen_change(struct sii9234 *ctx) { int value; - /* Work_around code to handle wrong interrupt */ + /* Workaround code to handle wrong interrupt */ if (ctx->state != ST_RGND_1K) { dev_err(ctx->dev, "RSEN_HIGH without RGND_1K\n"); return ST_FAILURE; @@ -723,9 +724,9 @@ static enum sii9234_state sii9234_rsen_change(struct sii9234 *ctx) } dev_dbg(ctx->dev, "RSEN lost\n"); /* - * Once RSEN loss is confirmed,we need to check - * based on cable status and chip power status,whether - * it is SINK Loss(HDMI cable not connected, TV Off) + * Once RSEN loss is confirmed, we need to check + * based on cable status and chip power status, whether + * it is SINK Loss (HDMI cable not connected, TV Off) * or MHL cable disconnection * TODO: Define the below mhl_disconnection() */ @@ -820,26 +821,22 @@ static int sii9234_init_resources(struct sii9234 *ctx, int ret; if (!ctx->dev->of_node) { - dev_err(ctx->dev, "not DT device\n"); + dev_err(ctx->dev, "no DT device\n"); return -ENODEV; } ctx->gpio_reset = devm_gpiod_get(ctx->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(ctx->gpio_reset)) { - dev_err(ctx->dev, "failed to get reset gpio from DT\n"); - return PTR_ERR(ctx->gpio_reset); - } + if (IS_ERR(ctx->gpio_reset)) + return dev_err_probe(ctx->dev, PTR_ERR(ctx->gpio_reset), + "failed to get reset gpio from DT\n"); ctx->supplies[0].supply = "avcc12"; ctx->supplies[1].supply = "avcc33"; ctx->supplies[2].supply = "iovcc18"; ctx->supplies[3].supply = "cvcc12"; ret = devm_regulator_bulk_get(ctx->dev, 4, ctx->supplies); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(ctx->dev, "regulator_bulk failed\n"); - return ret; - } + if (ret) + return dev_err_probe(ctx->dev, ret, "regulator_bulk failed\n"); ctx->client[I2C_MHL] = client; @@ -878,6 +875,9 @@ static enum drm_mode_status sii9234_mode_valid(struct drm_bridge *bridge, } static const struct drm_bridge_funcs sii9234_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .mode_valid = sii9234_mode_valid, }; @@ -911,10 +911,9 @@ static int sii9234_probe(struct i2c_client *client) sii9234_irq_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "sii9234", ctx); - if (ret < 0) { - dev_err(dev, "failed to install IRQ handler\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, + "failed to install IRQ handler\n"); ret = sii9234_init_resources(ctx, client); if (ret < 0) diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 982306eb4f0a..22c81b38b41e 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -2280,6 +2281,9 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge, } static const struct drm_bridge_funcs sii8620_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = sii8620_attach, .detach = sii8620_detach, .mode_fixup = sii8620_mode_fixup, diff --git a/drivers/gpu/drm/bridge/simple-bridge.c b/drivers/gpu/drm/bridge/simple-bridge.c index cc13c98f9be6..3fba7002322e 100644 --- a/drivers/gpu/drm/bridge/simple-bridge.c +++ b/drivers/gpu/drm/bridge/simple-bridge.c @@ -132,7 +132,8 @@ static int simple_bridge_attach(struct drm_bridge *bridge, return 0; } -static void simple_bridge_enable(struct drm_bridge *bridge) +static void simple_bridge_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge); int ret; @@ -146,7 +147,8 @@ static void simple_bridge_enable(struct drm_bridge *bridge) gpiod_set_value_cansleep(sbridge->enable, 1); } -static void simple_bridge_disable(struct drm_bridge *bridge) +static void simple_bridge_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge); @@ -157,9 +159,12 @@ static void simple_bridge_disable(struct drm_bridge *bridge) } static const struct drm_bridge_funcs simple_bridge_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = simple_bridge_attach, - .enable = simple_bridge_enable, - .disable = simple_bridge_disable, + .atomic_enable = simple_bridge_enable, + .atomic_disable = simple_bridge_disable, }; static int simple_bridge_probe(struct platform_device *pdev) diff --git a/drivers/gpu/drm/bridge/tc358764.c b/drivers/gpu/drm/bridge/tc358764.c index 12b43245bb8f..f55a56cbd88f 100644 --- a/drivers/gpu/drm/bridge/tc358764.c +++ b/drivers/gpu/drm/bridge/tc358764.c @@ -266,7 +266,8 @@ static void tc358764_reset(struct tc358764 *ctx) usleep_range(1000, 2000); } -static void tc358764_post_disable(struct drm_bridge *bridge) +static void tc358764_post_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct tc358764 *ctx = bridge_to_tc358764(bridge); int ret; @@ -278,7 +279,8 @@ static void tc358764_post_disable(struct drm_bridge *bridge) dev_err(ctx->dev, "error disabling regulators (%d)\n", ret); } -static void tc358764_pre_enable(struct drm_bridge *bridge) +static void tc358764_pre_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct tc358764 *ctx = bridge_to_tc358764(bridge); int ret; @@ -303,8 +305,11 @@ static int tc358764_attach(struct drm_bridge *bridge, } static const struct drm_bridge_funcs tc358764_bridge_funcs = { - .post_disable = tc358764_post_disable, - .pre_enable = tc358764_pre_enable, + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_post_disable = tc358764_post_disable, + .atomic_pre_enable = tc358764_pre_enable, .attach = tc358764_attach, }; diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 966c3eae437e..ce1b73214f26 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -527,7 +527,7 @@ static ssize_t tc_aux_transfer(struct drm_dp_aux *aux, * address-only transfer */ if (size) - size = FIELD_GET(AUX_BYTES, auxstatus); + size = min_t(size_t, size, FIELD_GET(AUX_BYTES, auxstatus)); msg->reply = FIELD_GET(AUX_STATUS, auxstatus); switch (request) { diff --git a/drivers/gpu/drm/bridge/tda998x_drv.c b/drivers/gpu/drm/bridge/tda998x_drv.c index 6c427bc75896..16c745591175 100644 --- a/drivers/gpu/drm/bridge/tda998x_drv.c +++ b/drivers/gpu/drm/bridge/tda998x_drv.c @@ -1410,7 +1410,8 @@ static enum drm_mode_status tda998x_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void tda998x_bridge_enable(struct drm_bridge *bridge) +static void tda998x_bridge_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); @@ -1428,7 +1429,8 @@ static void tda998x_bridge_enable(struct drm_bridge *bridge) } } -static void tda998x_bridge_disable(struct drm_bridge *bridge) +static void tda998x_bridge_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct tda998x_priv *priv = bridge_to_tda998x_priv(bridge); @@ -1745,12 +1747,15 @@ static void tda998x_bridge_hpd_disable(struct drm_bridge *bridge) } static const struct drm_bridge_funcs tda998x_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = tda998x_bridge_attach, .detach = tda998x_bridge_detach, .mode_valid = tda998x_bridge_mode_valid, - .disable = tda998x_bridge_disable, + .atomic_disable = tda998x_bridge_disable, .mode_set = tda998x_bridge_mode_set, - .enable = tda998x_bridge_enable, + .atomic_enable = tda998x_bridge_enable, .edid_read = tda998x_bridge_edid_read, .detect = tda998x_bridge_detect, .hpd_enable = tda998x_bridge_hpd_enable, diff --git a/drivers/gpu/drm/bridge/thc63lvd1024.c b/drivers/gpu/drm/bridge/thc63lvd1024.c index c804222846c3..679b424ba0c3 100644 --- a/drivers/gpu/drm/bridge/thc63lvd1024.c +++ b/drivers/gpu/drm/bridge/thc63lvd1024.c @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -81,7 +82,8 @@ static enum drm_mode_status thc63_mode_valid(struct drm_bridge *bridge, return MODE_OK; } -static void thc63_enable(struct drm_bridge *bridge) +static void thc63_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct thc63_dev *thc63 = to_thc63(bridge); int ret; @@ -97,7 +99,8 @@ static void thc63_enable(struct drm_bridge *bridge) gpiod_set_value(thc63->oe, 1); } -static void thc63_disable(struct drm_bridge *bridge) +static void thc63_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct thc63_dev *thc63 = to_thc63(bridge); int ret; @@ -112,10 +115,13 @@ static void thc63_disable(struct drm_bridge *bridge) } static const struct drm_bridge_funcs thc63_bridge_func = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = thc63_attach, .mode_valid = thc63_mode_valid, - .enable = thc63_enable, - .disable = thc63_disable, + .atomic_enable = thc63_enable, + .atomic_disable = thc63_disable, }; static int thc63_parse_dt(struct thc63_dev *thc63) diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index 6f06f7b4e992..f0a14f52aaac 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -174,14 +174,16 @@ static void tfp410_detach(struct drm_bridge *bridge) } } -static void tfp410_enable(struct drm_bridge *bridge) +static void tfp410_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct tfp410 *dvi = drm_bridge_to_tfp410(bridge); gpiod_set_value_cansleep(dvi->powerdown, 0); } -static void tfp410_disable(struct drm_bridge *bridge) +static void tfp410_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct tfp410 *dvi = drm_bridge_to_tfp410(bridge); @@ -242,8 +244,8 @@ static int tfp410_atomic_check(struct drm_bridge *bridge, static const struct drm_bridge_funcs tfp410_bridge_funcs = { .attach = tfp410_attach, .detach = tfp410_detach, - .enable = tfp410_enable, - .disable = tfp410_disable, + .atomic_enable = tfp410_enable, + .atomic_disable = tfp410_disable, .mode_valid = tfp410_mode_valid, .atomic_create_state = drm_atomic_helper_bridge_create_state, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, diff --git a/drivers/gpu/drm/bridge/ti-tpd12s015.c b/drivers/gpu/drm/bridge/ti-tpd12s015.c index 136e47ad1a10..e7b172ab7f55 100644 --- a/drivers/gpu/drm/bridge/ti-tpd12s015.c +++ b/drivers/gpu/drm/bridge/ti-tpd12s015.c @@ -19,6 +19,7 @@ #include #include +#include #include struct tpd12s015_device { @@ -96,6 +97,9 @@ static void tpd12s015_hpd_disable(struct drm_bridge *bridge) } static const struct drm_bridge_funcs tpd12s015_bridge_funcs = { + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .attach = tpd12s015_attach, .detach = tpd12s015_detach, .detect = tpd12s015_bridge_detect, diff --git a/drivers/gpu/drm/bridge/waveshare-dsi.c b/drivers/gpu/drm/bridge/waveshare-dsi.c index ded57f298d64..9c9825c9b7c5 100644 --- a/drivers/gpu/drm/bridge/waveshare-dsi.c +++ b/drivers/gpu/drm/bridge/waveshare-dsi.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -92,7 +93,8 @@ static int ws_bridge_bridge_attach(struct drm_bridge *bridge, &ws->bridge, flags); } -static void ws_bridge_bridge_enable(struct drm_bridge *bridge) +static void ws_bridge_bridge_enable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct ws_bridge *ws = bridge_to_ws_bridge(bridge); @@ -100,7 +102,8 @@ static void ws_bridge_bridge_enable(struct drm_bridge *bridge) backlight_enable(ws->backlight); } -static void ws_bridge_bridge_disable(struct drm_bridge *bridge) +static void ws_bridge_bridge_disable(struct drm_bridge *bridge, + struct drm_atomic_commit *commit) { struct ws_bridge *ws = bridge_to_ws_bridge(bridge); @@ -109,8 +112,11 @@ static void ws_bridge_bridge_disable(struct drm_bridge *bridge) } static const struct drm_bridge_funcs ws_bridge_bridge_funcs = { - .enable = ws_bridge_bridge_enable, - .disable = ws_bridge_bridge_disable, + .atomic_create_state = drm_atomic_helper_bridge_create_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_enable = ws_bridge_bridge_enable, + .atomic_disable = ws_bridge_bridge_disable, .attach = ws_bridge_bridge_attach, }; diff --git a/drivers/gpu/drm/display/drm_bridge_connector.c b/drivers/gpu/drm/display/drm_bridge_connector.c index 92f8a2d7aab4..8b54069fa53a 100644 --- a/drivers/gpu/drm/display/drm_bridge_connector.c +++ b/drivers/gpu/drm/display/drm_bridge_connector.c @@ -147,7 +147,7 @@ static void drm_bridge_connector_hpd_notify(struct drm_connector *connector, to_drm_bridge_connector(connector); /* Notify all bridges in the pipeline of hotplug events. */ - drm_for_each_bridge_in_chain_scoped(bridge_connector->encoder, bridge) { + drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) { if (bridge->funcs->hpd_notify) bridge->funcs->hpd_notify(bridge, connector, status); } @@ -854,7 +854,7 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, * detection are available, we don't support hotplug detection at all. */ connector_type = DRM_MODE_CONNECTOR_Unknown; - drm_for_each_bridge_in_chain_scoped(encoder, bridge) { + drm_for_each_bridge_in_chain(encoder, bridge) { if (!bridge->interlace_allowed) connector->interlace_allowed = false; if (!bridge->ycbcr_420_allowed) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 735ab7badc2e..e5c8ef06caed 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1554,7 +1554,7 @@ drm_atomic_add_encoder_bridges(struct drm_atomic_commit *state, "Adding all bridges for [encoder:%d:%s] to %p\n", encoder->base.id, encoder->name, state); - drm_for_each_bridge_in_chain_scoped(encoder, bridge) { + drm_for_each_bridge_in_chain(encoder, bridge) { /* Skip bridges that don't implement the atomic state hooks. */ if (!bridge->funcs->atomic_duplicate_state) continue; diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index 2f0d1ba285be..d17ae964fb21 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -563,10 +563,10 @@ EXPORT_SYMBOL(drm_atomic_normalize_zpos); /** * drm_plane_create_blend_mode_property - create a new blend mode property * @plane: drm plane - * @supported_modes: bitmask of supported modes, must include - * BIT(DRM_MODE_BLEND_PREMULTI). Current DRM assumption is - * that alpha is premultiplied, and old userspace can break if - * the property defaults to anything else. + * @supported_modes: bitmask of supported modes. When + * BIT(DRM_MODE_BLEND_PREMULTI) is included, it will be used + * as the default. Otherwise, the default will fallback to one + * of the supported modes. * * This creates a new property describing the blend mode. * @@ -599,13 +599,14 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane, { DRM_MODE_BLEND_PREMULTI, "Pre-multiplied" }, { DRM_MODE_BLEND_COVERAGE, "Coverage" }, }; + unsigned int default_mode; unsigned int valid_mode_mask = BIT(DRM_MODE_BLEND_PIXEL_NONE) | BIT(DRM_MODE_BLEND_PREMULTI) | BIT(DRM_MODE_BLEND_COVERAGE); int i; if (WARN_ON((supported_modes & ~valid_mode_mask) || - ((supported_modes & BIT(DRM_MODE_BLEND_PREMULTI)) == 0))) + (supported_modes == 0))) return -EINVAL; prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, @@ -630,7 +631,14 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane, } } - drm_object_attach_property(&plane->base, prop, DRM_MODE_BLEND_PREMULTI); + if (supported_modes & BIT(DRM_MODE_BLEND_PREMULTI)) + default_mode = DRM_MODE_BLEND_PREMULTI; + else if (supported_modes & BIT(DRM_MODE_BLEND_COVERAGE)) + default_mode = DRM_MODE_BLEND_COVERAGE; + else + default_mode = DRM_MODE_BLEND_PIXEL_NONE; + + drm_object_attach_property(&plane->base, prop, default_mode); plane->blend_mode_property = prop; return 0; diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 6ead9b75ae3d..83f1809a5d37 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -555,11 +555,6 @@ static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = { .atomic_destroy_state = drm_bridge_atomic_destroy_priv_state, }; -static bool drm_bridge_is_atomic(struct drm_bridge *bridge) -{ - return bridge->funcs->atomic_create_state != NULL; -} - /** * drm_bridge_attach - attach the bridge to an encoder's chain * @@ -629,9 +624,8 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge, goto err_reset_bridge; } - if (drm_bridge_is_atomic(bridge)) - drm_atomic_private_obj_init(bridge->dev, &bridge->base, - &drm_bridge_priv_state_funcs); + drm_atomic_private_obj_init(bridge->dev, &bridge->base, + &drm_bridge_priv_state_funcs); return 0; @@ -664,8 +658,7 @@ void drm_bridge_detach(struct drm_bridge *bridge) if (WARN_ON(!bridge->dev)) return; - if (drm_bridge_is_atomic(bridge)) - drm_atomic_private_obj_fini(&bridge->base); + drm_atomic_private_obj_fini(&bridge->base); if (bridge->funcs->detach) bridge->funcs->detach(bridge); @@ -690,9 +683,9 @@ void drm_bridge_detach(struct drm_bridge *bridge) * disable the bridge automatically. * * The enable and disable operations are split in - * &drm_bridge_funcs.pre_enable, &drm_bridge_funcs.enable, - * &drm_bridge_funcs.disable and &drm_bridge_funcs.post_disable to provide - * finer-grained control. + * &drm_bridge_funcs.atomic_pre_enable, &drm_bridge_funcs.atomic_enable, + * &drm_bridge_funcs.atomic_disable and &drm_bridge_funcs.atomic_post_disable + * to provide finer-grained control. * * Bridge drivers may implement the legacy version of those operations, or * the atomic version (prefixed with atomic\_), in which case they shall also @@ -833,10 +826,9 @@ EXPORT_SYMBOL(drm_bridge_chain_mode_set); * @bridge: bridge control structure * @state: atomic state being committed * - * Calls &drm_bridge_funcs.atomic_disable (falls back on - * &drm_bridge_funcs.disable) op for all the bridges in the encoder chain, - * starting from the last bridge to the first. These are called before calling - * &drm_encoder_helper_funcs.atomic_disable + * Calls &drm_bridge_funcs.atomic_disable op for all the bridges in the encoder + * chain, starting from the last bridge to the first. These are called before + * calling &drm_encoder_helper_funcs.atomic_disable * * Note: the bridge passed should be the one closest to the encoder */ @@ -852,11 +844,8 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, encoder = bridge->encoder; mutex_lock(&encoder->bridge_chain_mutex); list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { - if (iter->funcs->atomic_disable) { + if (iter->funcs->atomic_disable) iter->funcs->atomic_disable(iter, state); - } else if (iter->funcs->disable) { - iter->funcs->disable(iter); - } if (iter == bridge) break; @@ -870,8 +859,6 @@ static void drm_atomic_bridge_call_post_disable(struct drm_bridge *bridge, { if (state && bridge->funcs->atomic_post_disable) bridge->funcs->atomic_post_disable(bridge, state); - else if (bridge->funcs->post_disable) - bridge->funcs->post_disable(bridge); } /** @@ -880,10 +867,9 @@ static void drm_atomic_bridge_call_post_disable(struct drm_bridge *bridge, * @bridge: bridge control structure * @state: atomic state being committed * - * Calls &drm_bridge_funcs.atomic_post_disable (falls back on - * &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain, - * starting from the first bridge to the last. These are called after completing - * &drm_encoder_helper_funcs.atomic_disable + * Calls &drm_bridge_funcs.atomic_post_disable op for all the bridges in the + * encoder chain, starting from the first bridge to the last. These are called + * after completing &drm_encoder_helper_funcs.atomic_disable * * If a bridge sets @pre_enable_prev_first, then the @post_disable for that * bridge will be called before the previous one to reverse the @pre_enable @@ -967,8 +953,6 @@ static void drm_atomic_bridge_call_pre_enable(struct drm_bridge *bridge, { if (state && bridge->funcs->atomic_pre_enable) bridge->funcs->atomic_pre_enable(bridge, state); - else if (bridge->funcs->pre_enable) - bridge->funcs->pre_enable(bridge); } /** @@ -977,10 +961,9 @@ static void drm_atomic_bridge_call_pre_enable(struct drm_bridge *bridge, * @bridge: bridge control structure * @state: atomic state being committed * - * Calls &drm_bridge_funcs.atomic_pre_enable (falls back on - * &drm_bridge_funcs.pre_enable) op for all the bridges in the encoder chain, - * starting from the last bridge to the first. These are called before calling - * &drm_encoder_helper_funcs.atomic_enable + * Calls &drm_bridge_funcs.atomic_pre_enable op for all the bridges in the + * encoder chain, starting from the last bridge to the first. These are called + * before calling &drm_encoder_helper_funcs.atomic_enable * * If a bridge sets @pre_enable_prev_first, then the pre_enable for the * prev bridge will be called before pre_enable of this bridge. @@ -1057,10 +1040,9 @@ EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable); * @first_bridge: bridge control structure * @state: atomic state being committed * - * Calls &drm_bridge_funcs.atomic_enable (falls back on - * &drm_bridge_funcs.enable) op for all the bridges in the encoder chain, - * starting from the first bridge to the last. These are called after completing - * &drm_encoder_helper_funcs.atomic_enable + * Calls &drm_bridge_funcs.atomic_enable op for all the bridges in the encoder + * chain, starting from the first bridge to the last. These are called after + * completing &drm_encoder_helper_funcs.atomic_enable * * Note: the bridge passed should be the one closest to the encoder */ @@ -1071,11 +1053,8 @@ void drm_atomic_bridge_chain_enable(struct drm_bridge *first_bridge, return; drm_for_each_bridge_in_chain_from(first_bridge, bridge) - if (bridge->funcs->atomic_enable) { + if (bridge->funcs->atomic_enable) bridge->funcs->atomic_enable(bridge, state); - } else if (bridge->funcs->enable) { - bridge->funcs->enable(bridge); - } } EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); @@ -1717,7 +1696,7 @@ struct drm_bridge *of_drm_get_bridge_by_endpoint(const struct device_node *np, /* * of_graph_get_remote_node() produces a noisy error message if port * node isn't found and the absence of the port is a legit case here, - * so at first we silently check whether graph is present in the + * so at first we silently check whether a graph is present in the * device-tree node. */ if (!of_graph_is_present(np)) @@ -1817,7 +1796,7 @@ static int encoder_bridges_show(struct seq_file *m, void *data) struct drm_printer p = drm_seq_file_printer(m); unsigned int idx = 0; - drm_for_each_bridge_in_chain_scoped(encoder, bridge) + drm_for_each_bridge_in_chain(encoder, bridge) drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false, true); return 0; diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index 958cb605aedd..fcfe635bc195 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -48,6 +48,47 @@ * event. As mentioned above, ranges are tracked in a notifier's Red-Black * tree. * + * - Pages: + * struct drm_gpusvm_pages holds the DMA mapping state for a range of + * CPU virtual addresses: the DMA mapped device addresses, + * the device private pagemap, the IOVA state, the per mapping + * notifier sequence number, and the drm_device that owns the DMA + * mappings. + * A driver embeds one or more struct drm_gpusvm_pages alongside its + * struct drm_gpusvm_range, choosing one of two layouts: + * + * 1:1 - one drm_gpusvm_pages per range (one drm_device). Simplest + * layout; to mirror a VA range on several devices a driver uses a + * separate range (and notifier) per device, so the HMM fault is taken + * once per device. + * + * N:1 - one drm_gpusvm_pages per drm_device, all sharing one range and + * notifier; only the per-device DMA mapping differs. The instances must + * sit in contiguous memory so a single drm_gpusvm_range_set_unmapped() + * can mark them all. A driver can keep one instance inline for the single + * device case and switch to a heap array only when more devices join, + * e.g.: + * + * .. code-block:: c + * + * struct driver_range { + * struct drm_gpusvm_range base; + * unsigned int num_pages; // 1: inline_pages, >1: pages[] + * union { + * struct drm_gpusvm_pages inline_pages; + * struct drm_gpusvm_pages *pages; + * }; + * }; + * + * In the N:1 case the driver allocates the pages array with a zeroing + * allocator (e.g. kcalloc(num_pages, ...)), initialises each entry with + * drm_gpusvm_init_pages(), and frees each entry with + * drm_gpusvm_free_pages() plus the array itself, from its range free + * callback. Each drm_gpusvm_pages is mapped independently by their own + * drm_device. + * Each drm_gpusvm_pages must be zero-initialised and initialised with + * drm_gpusvm_init_pages(), called once per entry. + * * - Operations: * Define the interface for driver-specific GPU SVM operations such as * range allocation, notifier allocation, and invalidations. @@ -92,7 +133,7 @@ * range RB tree and list, as well as the range's DMA mappings and sequence * number. GPU SVM manages all necessary locking and unlocking operations, * except for the recheck range's pages being valid - * (drm_gpusvm_range_pages_valid) when the driver is committing GPU bindings. + * (drm_gpusvm_pages_valid) when the driver is committing GPU bindings. * This lock corresponds to the ``driver->update`` lock mentioned in * Documentation/mm/hmm.rst. Future revisions may transition from a GPU SVM * global lock to a per-notifier lock if finer-grained locking is deemed @@ -140,15 +181,20 @@ * * .. code-block:: c * - * int driver_bind_range(struct drm_gpusvm *gpusvm, struct drm_gpusvm_range *range) + * struct driver_range { + * struct drm_gpusvm_range base; + * struct drm_gpusvm_pages pages; + * }; + * + * int driver_bind_range(struct drm_gpusvm *gpusvm, struct driver_range *drange) * { * int err = 0; * - * driver_alloc_and_setup_memory_for_bind(gpusvm, range); + * driver_alloc_and_setup_memory_for_bind(gpusvm, drange); * * drm_gpusvm_notifier_lock(gpusvm); - * if (drm_gpusvm_range_pages_valid(range)) - * driver_commit_bind(gpusvm, range); + * if (drm_gpusvm_pages_valid(gpusvm, &drange->pages)) + * driver_commit_bind(gpusvm, drange); * else * err = -EAGAIN; * drm_gpusvm_notifier_unlock(gpusvm); @@ -160,6 +206,8 @@ * unsigned long gpuva_start, unsigned long gpuva_end) * { * struct drm_gpusvm_ctx ctx = {}; + * struct driver_range *drange; + * struct drm_gpusvm_range *range; * int err; * * driver_svm_lock(); @@ -174,6 +222,7 @@ * err = PTR_ERR(range); * goto unlock; * } + * drange = container_of(range, struct driver_range, base); * * if (driver_migration_policy(range)) { * err = drm_pagemap_populate_mm(driver_choose_drm_pagemap(), @@ -183,7 +232,10 @@ * goto retry; * } * - * err = drm_gpusvm_range_get_pages(gpusvm, range, &ctx); + * err = drm_gpusvm_get_pages(gpusvm, &drange->pages, + * gpusvm->mm, &range->notifier->notifier, + * drm_gpusvm_range_start(range), + * drm_gpusvm_range_end(range), &ctx); * if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM) { // CPU mappings changed * if (err == -EOPNOTSUPP) * drm_gpusvm_range_evict(gpusvm, range); @@ -192,7 +244,7 @@ * goto unlock; * } * - * err = driver_bind_range(gpusvm, range); + * err = driver_bind_range(gpusvm, drange); * if (err == -EAGAIN) // CPU mappings changed * goto retry * @@ -205,6 +257,21 @@ * * .. code-block:: c * + * // The driver owns the drm_gpusvm_pages lifecycle. ops->range_free is + * // the final fallback: drm_gpusvm_free_pages() unmaps any + * // lingering DMA mapping and a no-op if already unmapped and frees the + * // dma_addr array. The normal flow is to DMA unmap before + * // drm_gpusvm_range_remove() (before the range leaves the tree). + * void driver_range_free(struct drm_gpusvm_range *range) + * { + * struct driver_range *drange = + * container_of(range, struct driver_range, base); + * + * drm_gpusvm_free_pages(range->gpusvm, &drange->pages, + * drm_gpusvm_range_size(range) >> PAGE_SHIFT); + * kfree(drange); + * } + * * void __driver_garbage_collector(struct drm_gpusvm *gpusvm, * struct drm_gpusvm_range *range) * { @@ -215,6 +282,14 @@ * drm_gpusvm_range_evict(gpusvm, range); * * driver_unbind_range(range); + * // The pages must be DMA unmapped before drm_gpusvm_range_remove() + * // , so a range is never off the MMU interval tree while still DMA + * // mapped as the original drmsvm design flow. Otherwise a concurrent CPU + * // munmap's notifier could miss this range and free pages still mapped + * // for device DMA. This is the normal unmap point. + * drm_gpusvm_unmap_pages(gpusvm, &drange->pages, + * drm_gpusvm_range_size(range) >> PAGE_SHIFT, + * &(struct drm_gpusvm_ctx){ .in_notifier = false }); * drm_gpusvm_range_remove(gpusvm, range); * } * @@ -236,17 +311,22 @@ * { * struct drm_gpusvm_ctx ctx = { .in_notifier = true, }; * struct drm_gpusvm_range *range = NULL; + * struct driver_range *drange; * * driver_invalidate_device_pages(gpusvm, mmu_range->start, mmu_range->end); * * drm_gpusvm_for_each_range(range, notifier, mmu_range->start, * mmu_range->end) { - * drm_gpusvm_range_unmap_pages(gpusvm, range, &ctx); + * drange = container_of(range, struct driver_range, base); + * + * drm_gpusvm_unmap_pages(gpusvm, &drange->pages, + * drm_gpusvm_range_size(range) >> PAGE_SHIFT, + * &ctx); * * if (mmu_range->event != MMU_NOTIFY_UNMAP) * continue; * - * drm_gpusvm_range_set_unmapped(range, mmu_range); + * drm_gpusvm_range_set_unmapped(range, &drange->pages, 1, mmu_range); * driver_garbage_collector_add(gpusvm, range); * } * } @@ -359,7 +439,6 @@ static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = { * drm_gpusvm_init() - Initialize the GPU SVM. * @gpusvm: Pointer to the GPU SVM structure. * @name: Name of the GPU SVM. - * @drm: Pointer to the DRM device structure. * @mm: Pointer to the mm_struct for the address space. * @mm_start: Start address of GPU SVM. * @mm_range: Range of the GPU SVM. @@ -373,7 +452,9 @@ static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = { * This function initializes the GPU SVM. * * Note: If only using the simple drm_gpusvm_pages API (get/unmap/free), - * then only @gpusvm, @name, and @drm are expected. However, the same base + * then only @gpusvm and @name are expected. The @drm drm_device for dma + * mappings is bound per-pages via drm_gpusvm_init_pages() before the first + * drm_gpusvm_get_pages() call. However, the same base * @gpusvm can also be used with both modes together in which case the full * setup is needed, where the core drm_gpusvm_pages API will simply never use * the other fields. @@ -381,7 +462,7 @@ static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = { * Return: 0 on success, a negative error code on failure. */ int drm_gpusvm_init(struct drm_gpusvm *gpusvm, - const char *name, struct drm_device *drm, + const char *name, struct mm_struct *mm, unsigned long mm_start, unsigned long mm_range, unsigned long notifier_size, @@ -399,7 +480,6 @@ int drm_gpusvm_init(struct drm_gpusvm *gpusvm, } gpusvm->name = name; - gpusvm->drm = drm; gpusvm->mm = mm; gpusvm->mm_start = mm_start; gpusvm->mm_range = mm_range; @@ -640,8 +720,7 @@ drm_gpusvm_range_alloc(struct drm_gpusvm *gpusvm, range->itree.start = ALIGN_DOWN(fault_addr, chunk_size); range->itree.last = ALIGN(fault_addr + 1, chunk_size) - 1; INIT_LIST_HEAD(&range->entry); - range->pages.notifier_seq = LONG_MAX; - range->pages.flags.migrate_devmem = migrate_devmem ? 1 : 0; + range->flags.migrate_devmem = migrate_devmem ? 1 : 0; return range; } @@ -929,7 +1008,7 @@ drm_gpusvm_range_chunk_size(struct drm_gpusvm *gpusvm, * mallocs 16k but the CPU VMA is ~128k which results in 64k SVM * ranges. When migrating the SVM ranges, some processes fail in * drm_pagemap_migrate_to_devmem with 'migrate.cpages != npages' - * and then upon drm_gpusvm_range_get_pages device pages from + * and then upon drm_gpusvm_get_pages device pages from * other processes are collected + faulted in which creates all * sorts of problems. Unsure exactly how this happening, also * problem goes away if 'xe_exec_system_allocator --r @@ -1135,11 +1214,16 @@ static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, unsigned long npages) { struct drm_pagemap *dpagemap = svm_pages->dpagemap; - struct device *dev = gpusvm->drm->dev; + struct device *dev; unsigned long i, j; lockdep_assert_held(&gpusvm->notifier_lock); + if (!svm_pages->drm) + return; + + dev = svm_pages->drm->dev; + if (svm_pages->flags.has_dma_mapping) { struct drm_gpusvm_pages_flags flags = { .__flags = svm_pages->flags.__flags, @@ -1222,12 +1306,17 @@ EXPORT_SYMBOL_GPL(drm_gpusvm_free_pages); * This function removes the specified GPU SVM range and also removes the parent * GPU SVM notifier if no more ranges remain in the notifier. The caller must * hold a lock to protect range and notifier removal. + * + * This function does not unmap or free the drm_gpusvm_pages, the driver owns + * that lifecycle. The caller must DMA unmap the range's pages before calling + * this function, so a range is never removed from the MMU interval tree while + * still DMA mapped. Typically the driver calls drm_gpusvm_unmap_pages() first. + * And the range_free callback's drm_gpusvm_free_pages() is a final fallback safe + * net. */ void drm_gpusvm_range_remove(struct drm_gpusvm *gpusvm, struct drm_gpusvm_range *range) { - unsigned long npages = npages_in_range(drm_gpusvm_range_start(range), - drm_gpusvm_range_end(range)); struct drm_gpusvm_notifier *notifier; drm_gpusvm_driver_lock_held(gpusvm); @@ -1239,8 +1328,6 @@ void drm_gpusvm_range_remove(struct drm_gpusvm *gpusvm, return; drm_gpusvm_notifier_lock(gpusvm); - __drm_gpusvm_unmap_pages(gpusvm, &range->pages, npages); - __drm_gpusvm_free_pages(gpusvm, &range->pages); __drm_gpusvm_range_remove(notifier, range); drm_gpusvm_notifier_unlock(gpusvm); @@ -1319,34 +1406,14 @@ EXPORT_SYMBOL_GPL(drm_gpusvm_range_put); * * Return: True if GPU SVM range has valid pages, False otherwise */ -static bool drm_gpusvm_pages_valid(struct drm_gpusvm *gpusvm, - struct drm_gpusvm_pages *svm_pages) +bool drm_gpusvm_pages_valid(struct drm_gpusvm *gpusvm, + struct drm_gpusvm_pages *svm_pages) { lockdep_assert_held(&gpusvm->notifier_lock); return svm_pages->flags.has_devmem_pages || svm_pages->flags.has_dma_mapping; } - -/** - * drm_gpusvm_range_pages_valid() - GPU SVM range pages valid - * @gpusvm: Pointer to the GPU SVM structure - * @range: Pointer to the GPU SVM range structure - * - * This function determines if a GPU SVM range pages are valid. Expected be - * called holding gpusvm->notifier_lock and as the last step before committing a - * GPU binding. This is akin to a notifier seqno check in the HMM documentation - * but due to wider notifiers (i.e., notifiers which span multiple ranges) this - * function is required for finer grained checking (i.e., per range) if pages - * are valid. - * - * Return: True if GPU SVM range has valid pages, False otherwise - */ -bool drm_gpusvm_range_pages_valid(struct drm_gpusvm *gpusvm, - struct drm_gpusvm_range *range) -{ - return drm_gpusvm_pages_valid(gpusvm, &range->pages); -} -EXPORT_SYMBOL_GPL(drm_gpusvm_range_pages_valid); +EXPORT_SYMBOL_GPL(drm_gpusvm_pages_valid); /** * drm_gpusvm_pages_valid_unlocked() - GPU SVM pages valid unlocked @@ -1421,6 +1488,9 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, DMA_BIDIRECTIONAL; struct dma_iova_state *state = &svm_pages->state; + if (!svm_pages->drm) + return -EINVAL; + retry: if (time_after(jiffies, timeout)) return -EBUSY; @@ -1520,7 +1590,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, pagemap = page_pgmap(page); dpagemap = drm_pagemap_page_to_dpagemap(page); - if (drm_WARN_ON(gpusvm->drm, !dpagemap)) { + if (drm_WARN_ON(svm_pages->drm, !dpagemap)) { /* * Raced. This is not supposed to happen * since hmm_range_fault() should've migrated @@ -1532,10 +1602,10 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, } svm_pages->dma_addr[j] = dpagemap->ops->device_map(dpagemap, - gpusvm->drm->dev, + svm_pages->drm->dev, page, order, dma_dir); - if (dma_mapping_error(gpusvm->drm->dev, + if (dma_mapping_error(svm_pages->drm->dev, svm_pages->dma_addr[j].addr)) { err = -EFAULT; goto err_unmap; @@ -1555,11 +1625,11 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, } if (!i) - dma_iova_try_alloc(gpusvm->drm->dev, state, + dma_iova_try_alloc(svm_pages->drm->dev, state, 0, npages * PAGE_SIZE); if (dma_use_iova(state)) { - err = dma_iova_link(gpusvm->drm->dev, state, + err = dma_iova_link(svm_pages->drm->dev, state, hmm_pfn_to_phys(pfns[i]), svm_pages->state_offset, PAGE_SIZE << order, @@ -1570,11 +1640,11 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, addr = state->addr + svm_pages->state_offset; svm_pages->state_offset += PAGE_SIZE << order; } else { - addr = dma_map_page(gpusvm->drm->dev, + addr = dma_map_page(svm_pages->drm->dev, page, 0, PAGE_SIZE << order, dma_dir); - if (dma_mapping_error(gpusvm->drm->dev, addr)) { + if (dma_mapping_error(svm_pages->drm->dev, addr)) { err = -EFAULT; goto err_unmap; } @@ -1590,7 +1660,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, } if (dma_use_iova(state)) { - err = dma_iova_sync(gpusvm->drm->dev, state, 0, + err = dma_iova_sync(svm_pages->drm->dev, state, 0, svm_pages->state_offset); if (err) goto err_unmap; @@ -1625,28 +1695,6 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, } EXPORT_SYMBOL_GPL(drm_gpusvm_get_pages); -/** - * drm_gpusvm_range_get_pages() - Get pages for a GPU SVM range - * @gpusvm: Pointer to the GPU SVM structure - * @range: Pointer to the GPU SVM range structure - * @ctx: GPU SVM context - * - * This function gets pages for a GPU SVM range and ensures they are mapped for - * DMA access. - * - * Return: 0 on success, negative error code on failure. - */ -int drm_gpusvm_range_get_pages(struct drm_gpusvm *gpusvm, - struct drm_gpusvm_range *range, - const struct drm_gpusvm_ctx *ctx) -{ - return drm_gpusvm_get_pages(gpusvm, &range->pages, gpusvm->mm, - &range->notifier->notifier, - drm_gpusvm_range_start(range), - drm_gpusvm_range_end(range), ctx); -} -EXPORT_SYMBOL_GPL(drm_gpusvm_range_get_pages); - /** * drm_gpusvm_unmap_pages() - Unmap GPU svm pages * @gpusvm: Pointer to the GPU SVM structure @@ -1677,29 +1725,6 @@ void drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, } EXPORT_SYMBOL_GPL(drm_gpusvm_unmap_pages); -/** - * drm_gpusvm_range_unmap_pages() - Unmap pages associated with a GPU SVM range - * @gpusvm: Pointer to the GPU SVM structure - * @range: Pointer to the GPU SVM range structure - * @ctx: GPU SVM context - * - * This function unmaps pages associated with a GPU SVM range. If @in_notifier - * is set, it is assumed that gpusvm->notifier_lock is held in write mode; if it - * is clear, it acquires gpusvm->notifier_lock in read mode. Must be called on - * each GPU SVM range attached to notifier in gpusvm->ops->invalidate for IOMMU - * security model. - */ -void drm_gpusvm_range_unmap_pages(struct drm_gpusvm *gpusvm, - struct drm_gpusvm_range *range, - const struct drm_gpusvm_ctx *ctx) -{ - unsigned long npages = npages_in_range(drm_gpusvm_range_start(range), - drm_gpusvm_range_end(range)); - - return drm_gpusvm_unmap_pages(gpusvm, &range->pages, npages, ctx); -} -EXPORT_SYMBOL_GPL(drm_gpusvm_range_unmap_pages); - /** * drm_gpusvm_range_evict() - Evict GPU SVM range * @gpusvm: Pointer to the GPU SVM structure @@ -1784,20 +1809,40 @@ EXPORT_SYMBOL_GPL(drm_gpusvm_has_mapping); /** * drm_gpusvm_range_set_unmapped() - Mark a GPU SVM range as unmapped * @range: Pointer to the GPU SVM range structure. + * @pages: Pointer to the GPU SVM pages structure(s). + * @pages_count: Number of GPU SVM pages structure(s) passed in. * @mmu_range: Pointer to the MMU notifier range structure. * * This function marks a GPU SVM range as unmapped and sets the partial_unmap flag * if the range partially falls within the provided MMU notifier range. */ void drm_gpusvm_range_set_unmapped(struct drm_gpusvm_range *range, + struct drm_gpusvm_pages *pages, + unsigned int pages_count, const struct mmu_notifier_range *mmu_range) { + struct drm_gpusvm_range_flags range_flags = { + .__flags = range->flags.__flags, + }; + unsigned int i; + lockdep_assert_held_write(&range->gpusvm->notifier_lock); - range->pages.flags.unmapped = true; + range_flags.unmapped = true; + for (i = 0; i < pages_count; ++i) { + struct drm_gpusvm_pages_flags flags = { + .__flags = pages[i].flags.__flags, + }; + + flags.unmapped = true; + /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ + WRITE_ONCE(pages[i].flags.__flags, flags.__flags); + } if (drm_gpusvm_range_start(range) < mmu_range->start || drm_gpusvm_range_end(range) > mmu_range->end) - range->pages.flags.partial_unmap = true; + range_flags.partial_unmap = true; + /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ + WRITE_ONCE(range->flags.__flags, range_flags.__flags); } EXPORT_SYMBOL_GPL(drm_gpusvm_range_set_unmapped); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index f432f485a914..3bcc7bf0900c 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -857,6 +857,25 @@ static void validate_encoder_possible_crtcs(struct drm_encoder *encoder) encoder->possible_crtcs, crtc_mask); } +static void validate_blend_mode_for_alpha_formats(struct drm_plane *plane) +{ + const struct drm_format_info *fmt; + u32 i; + + /* blend mode property supported, no need to check anything */ + if (plane->blend_mode_property) + return; + + for (i = 0; i < plane->format_count; i++) { + fmt = drm_format_info(plane->format_types[i]); + if (fmt->has_alpha) { + WARN(1, "[PLANE:%d:%s] pixel format with alpha exposed but blend mode not setup", + plane->base.id, plane->name); + break; + } + } +} + void drm_mode_config_validate(struct drm_device *dev) { struct drm_encoder *encoder; @@ -915,6 +934,8 @@ void drm_mode_config_validate(struct drm_device *dev) drm_for_each_plane(plane, dev) { if (plane->type == DRM_PLANE_TYPE_PRIMARY) num_primary++; + + validate_blend_mode_for_alpha_formats(plane); } WARN(num_primary != dev->mode_config.num_crtc, diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 96eef327bf7e..1f4cff6bb4a7 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -297,7 +297,7 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, /* * of_graph_get_remote_node() produces a noisy error message if port * node isn't found and the absence of the port is a legit case here, - * so at first we silently check whether graph presents in the + * so at first we silently check whether a graph is present in the * device-tree node. */ if (!of_graph_is_present(np)) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index c314b3cb5e70..4dbc8a7ea6af 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -584,9 +584,9 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) /* read idle register. */ idle = gpu_read(gpu, VIVS_HI_IDLE_STATE); - /* try resetting again if FE is not idle */ - if ((idle & VIVS_HI_IDLE_STATE_FE) == 0) { - dev_dbg(gpu->dev, "FE is not idle\n"); + /* try resetting again if any module is not idle */ + if ((idle & gpu->idle_mask) != gpu->idle_mask) { + dev_dbg(gpu->dev, "GPU modules not idle\n"); continue; } @@ -600,6 +600,23 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) continue; } + /* try resetting again if MMUv2 is not disabled */ + if (gpu->identity.minor_features1 & chipMinorFeatures1_MMU_VERSION) { + if (gpu->sec_mode == ETNA_SEC_KERNEL) { + if (gpu_read(gpu, VIVS_MMUv2_SEC_CONTROL) & + VIVS_MMUv2_SEC_CONTROL_ENABLE) { + dev_dbg(gpu->dev, "MMU is not disabled\n"); + continue; + } + } else { + if (gpu_read(gpu, VIVS_MMUv2_CONTROL) & + VIVS_MMUv2_CONTROL_ENABLE) { + dev_dbg(gpu->dev, "MMU is not disabled\n"); + continue; + } + } + } + /* enable debug register access */ control &= ~VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS; gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control); diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c index e68c954ec3e6..3069f958137f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -21,6 +21,7 @@ #include