Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/bridge: cdns-dsi: Move DSI mode check to _atomic_check()

At present, the DSI mode configuration check happens during the
_atomic_enable() phase, which is not really the best place for this.
Moreover, if the mode is not valid, the driver gives a warning and
continues the hardware configuration.

Move the DSI mode configuration check to _atomic_check() instead, which
can properly report back any invalid mode, before the _enable phase even
begins.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Tested-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Signed-off-by: Aradhya Bhatia <a-bhatia1@ti.com>
Signed-off-by: Aradhya Bhatia <aradhya.bhatia@linux.dev>
Link: https://lore.kernel.org/r/20250329113925.68204-10-aradhya.bhatia@linux.dev
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

authored by

Aradhya Bhatia and committed by
Dmitry Baryshkov
a53d9877 bc36ee98

+88 -5
+88 -5
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c
··· 425 425 #define DSI_NULL_FRAME_OVERHEAD 6 426 426 #define DSI_EOT_PKT_SIZE 4 427 427 428 + struct cdns_dsi_bridge_state { 429 + struct drm_bridge_state base; 430 + struct cdns_dsi_cfg dsi_cfg; 431 + }; 432 + 433 + static inline struct cdns_dsi_bridge_state * 434 + to_cdns_dsi_bridge_state(struct drm_bridge_state *bridge_state) 435 + { 436 + return container_of(bridge_state, struct cdns_dsi_bridge_state, base); 437 + } 438 + 428 439 static inline struct cdns_dsi *input_to_dsi(struct cdns_dsi_input *input) 429 440 { 430 441 return container_of(input, struct cdns_dsi, input); ··· 782 771 struct cdns_dsi_output *output = &dsi->output; 783 772 struct drm_connector_state *conn_state; 784 773 struct drm_crtc_state *crtc_state; 774 + struct cdns_dsi_bridge_state *dsi_state; 775 + struct drm_bridge_state *new_bridge_state; 785 776 struct drm_display_mode *mode; 786 777 struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; 787 778 struct drm_connector *connector; ··· 795 782 if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) 796 783 return; 797 784 785 + new_bridge_state = drm_atomic_get_new_bridge_state(state, bridge); 786 + if (WARN_ON(!new_bridge_state)) 787 + return; 788 + 789 + dsi_state = to_cdns_dsi_bridge_state(new_bridge_state); 790 + dsi_cfg = dsi_state->dsi_cfg; 791 + 798 792 if (dsi->platform_ops && dsi->platform_ops->enable) 799 793 dsi->platform_ops->enable(dsi); 800 794 ··· 810 790 crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); 811 791 mode = &crtc_state->adjusted_mode; 812 792 nlanes = output->dev->lanes; 813 - 814 - WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false)); 815 793 816 794 cdns_dsi_hs_init(dsi); 817 795 cdns_dsi_init_link(dsi); ··· 981 963 return input_fmts; 982 964 } 983 965 966 + static int cdns_dsi_bridge_atomic_check(struct drm_bridge *bridge, 967 + struct drm_bridge_state *bridge_state, 968 + struct drm_crtc_state *crtc_state, 969 + struct drm_connector_state *conn_state) 970 + { 971 + struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); 972 + struct cdns_dsi *dsi = input_to_dsi(input); 973 + struct cdns_dsi_bridge_state *dsi_state = to_cdns_dsi_bridge_state(bridge_state); 974 + const struct drm_display_mode *mode = &crtc_state->mode; 975 + struct cdns_dsi_cfg *dsi_cfg = &dsi_state->dsi_cfg; 976 + 977 + return cdns_dsi_check_conf(dsi, mode, dsi_cfg, false); 978 + } 979 + 980 + static struct drm_bridge_state * 981 + cdns_dsi_bridge_atomic_duplicate_state(struct drm_bridge *bridge) 982 + { 983 + struct cdns_dsi_bridge_state *dsi_state, *old_dsi_state; 984 + struct drm_bridge_state *bridge_state; 985 + 986 + if (WARN_ON(!bridge->base.state)) 987 + return NULL; 988 + 989 + bridge_state = drm_priv_to_bridge_state(bridge->base.state); 990 + old_dsi_state = to_cdns_dsi_bridge_state(bridge_state); 991 + 992 + dsi_state = kzalloc(sizeof(*dsi_state), GFP_KERNEL); 993 + if (!dsi_state) 994 + return NULL; 995 + 996 + __drm_atomic_helper_bridge_duplicate_state(bridge, &dsi_state->base); 997 + 998 + memcpy(&dsi_state->dsi_cfg, &old_dsi_state->dsi_cfg, 999 + sizeof(dsi_state->dsi_cfg)); 1000 + 1001 + return &dsi_state->base; 1002 + } 1003 + 1004 + static void 1005 + cdns_dsi_bridge_atomic_destroy_state(struct drm_bridge *bridge, 1006 + struct drm_bridge_state *state) 1007 + { 1008 + struct cdns_dsi_bridge_state *dsi_state; 1009 + 1010 + dsi_state = to_cdns_dsi_bridge_state(state); 1011 + 1012 + kfree(dsi_state); 1013 + } 1014 + 1015 + static struct drm_bridge_state * 1016 + cdns_dsi_bridge_atomic_reset(struct drm_bridge *bridge) 1017 + { 1018 + struct cdns_dsi_bridge_state *dsi_state; 1019 + 1020 + dsi_state = kzalloc(sizeof(*dsi_state), GFP_KERNEL); 1021 + if (!dsi_state) 1022 + return NULL; 1023 + 1024 + memset(dsi_state, 0, sizeof(*dsi_state)); 1025 + dsi_state->base.bridge = bridge; 1026 + 1027 + return &dsi_state->base; 1028 + } 1029 + 984 1030 static const struct drm_bridge_funcs cdns_dsi_bridge_funcs = { 985 1031 .attach = cdns_dsi_bridge_attach, 986 1032 .mode_valid = cdns_dsi_bridge_mode_valid, ··· 1052 970 .atomic_pre_enable = cdns_dsi_bridge_atomic_pre_enable, 1053 971 .atomic_enable = cdns_dsi_bridge_atomic_enable, 1054 972 .atomic_post_disable = cdns_dsi_bridge_atomic_post_disable, 1055 - .atomic_reset = drm_atomic_helper_bridge_reset, 1056 - .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 1057 - .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 973 + .atomic_check = cdns_dsi_bridge_atomic_check, 974 + .atomic_reset = cdns_dsi_bridge_atomic_reset, 975 + .atomic_duplicate_state = cdns_dsi_bridge_atomic_duplicate_state, 976 + .atomic_destroy_state = cdns_dsi_bridge_atomic_destroy_state, 1058 977 .atomic_get_input_bus_fmts = cdns_dsi_bridge_get_input_bus_fmts, 1059 978 }; 1060 979