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/omap: Add global state as a private atomic object

Global shared resources (like hw overlays) for omapdrm are implemented
as a part of atomic state using the drm_private_obj infrastructure
available in the atomic core.

omap_global_state is introduced as a drm atomic private object. The two
funcs omap_get_global_state() and omap_get_existing_global_state() are
the two variants that will be used to access omap_global_state.

drm_mode_config_init() needs to be called earlier because it
creates/initializes the private_obj link list maintained by the atomic
framework. The private_obj link list has to exist prior to calling
drm_atomic_private_obj_init(). Similarly the cleanup handler are
reordered appropriately.

Signed-off-by: Benoit Parrot <bparrot@ti.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211117141928.771082-7-narmstrong@baylibre.com

authored by

Benoit Parrot and committed by
Tomi Valkeinen
6e42201b 3c265d92

+105 -3
+88 -3
drivers/gpu/drm/omapdrm/omap_drv.c
··· 128 128 .atomic_commit = drm_atomic_helper_commit, 129 129 }; 130 130 131 + /* Global/shared object state funcs */ 132 + 133 + /* 134 + * This is a helper that returns the private state currently in operation. 135 + * Note that this would return the "old_state" if called in the atomic check 136 + * path, and the "new_state" after the atomic swap has been done. 137 + */ 138 + struct omap_global_state * 139 + omap_get_existing_global_state(struct omap_drm_private *priv) 140 + { 141 + return to_omap_global_state(priv->glob_obj.state); 142 + } 143 + 144 + /* 145 + * This acquires the modeset lock set aside for global state, creates 146 + * a new duplicated private object state. 147 + */ 148 + struct omap_global_state *__must_check 149 + omap_get_global_state(struct drm_atomic_state *s) 150 + { 151 + struct omap_drm_private *priv = s->dev->dev_private; 152 + struct drm_private_state *priv_state; 153 + 154 + priv_state = drm_atomic_get_private_obj_state(s, &priv->glob_obj); 155 + if (IS_ERR(priv_state)) 156 + return ERR_CAST(priv_state); 157 + 158 + return to_omap_global_state(priv_state); 159 + } 160 + 161 + static struct drm_private_state * 162 + omap_global_duplicate_state(struct drm_private_obj *obj) 163 + { 164 + struct omap_global_state *state; 165 + 166 + state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); 167 + if (!state) 168 + return NULL; 169 + 170 + __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); 171 + 172 + return &state->base; 173 + } 174 + 175 + static void omap_global_destroy_state(struct drm_private_obj *obj, 176 + struct drm_private_state *state) 177 + { 178 + struct omap_global_state *omap_state = to_omap_global_state(state); 179 + 180 + kfree(omap_state); 181 + } 182 + 183 + static const struct drm_private_state_funcs omap_global_state_funcs = { 184 + .atomic_duplicate_state = omap_global_duplicate_state, 185 + .atomic_destroy_state = omap_global_destroy_state, 186 + }; 187 + 188 + static int omap_global_obj_init(struct drm_device *dev) 189 + { 190 + struct omap_drm_private *priv = dev->dev_private; 191 + struct omap_global_state *state; 192 + 193 + state = kzalloc(sizeof(*state), GFP_KERNEL); 194 + if (!state) 195 + return -ENOMEM; 196 + 197 + drm_atomic_private_obj_init(dev, &priv->glob_obj, &state->base, 198 + &omap_global_state_funcs); 199 + return 0; 200 + } 201 + 202 + static void omap_global_obj_fini(struct omap_drm_private *priv) 203 + { 204 + drm_atomic_private_obj_fini(&priv->glob_obj); 205 + } 206 + 131 207 static void omap_disconnect_pipelines(struct drm_device *ddev) 132 208 { 133 209 struct omap_drm_private *priv = ddev->dev_private; ··· 306 230 307 231 if (!omapdss_stack_is_ready()) 308 232 return -EPROBE_DEFER; 309 - 310 - drm_mode_config_init(dev); 311 233 312 234 ret = omap_modeset_init_properties(dev); 313 235 if (ret < 0) ··· 657 583 658 584 omap_gem_init(ddev); 659 585 660 - ret = omap_hwoverlays_init(priv); 586 + drm_mode_config_init(ddev); 587 + 588 + ret = omap_global_obj_init(ddev); 661 589 if (ret) 662 590 goto err_gem_deinit; 591 + 592 + ret = omap_hwoverlays_init(priv); 593 + if (ret) 594 + goto err_free_priv_obj; 663 595 664 596 ret = omap_modeset_init(ddev); 665 597 if (ret) { ··· 704 624 omap_modeset_fini(ddev); 705 625 err_free_overlays: 706 626 omap_hwoverlays_destroy(priv); 627 + err_free_priv_obj: 628 + omap_global_obj_fini(priv); 707 629 err_gem_deinit: 630 + drm_mode_config_cleanup(ddev); 708 631 omap_gem_deinit(ddev); 709 632 destroy_workqueue(priv->wq); 710 633 omap_disconnect_pipelines(ddev); ··· 732 649 733 650 omap_modeset_fini(ddev); 734 651 omap_hwoverlays_destroy(priv); 652 + omap_global_obj_fini(priv); 653 + drm_mode_config_cleanup(ddev); 735 654 omap_gem_deinit(ddev); 736 655 737 656 destroy_workqueue(priv->wq);
+17
drivers/gpu/drm/omapdrm/omap_drv.h
··· 14 14 #include "dss/omapdss.h" 15 15 #include "dss/dss.h" 16 16 17 + #include <drm/drm_atomic.h> 17 18 #include <drm/drm_gem.h> 18 19 #include <drm/omap_drm.h> 19 20 ··· 42 41 unsigned int alias_id; 43 42 }; 44 43 44 + /* 45 + * Global private object state for tracking resources that are shared across 46 + * multiple kms objects (planes/crtcs/etc). 47 + */ 48 + #define to_omap_global_state(x) container_of(x, struct omap_global_state, base) 49 + 50 + struct omap_global_state { 51 + struct drm_private_state base; 52 + }; 53 + 45 54 struct omap_drm_private { 46 55 struct drm_device *ddev; 47 56 struct device *dev; ··· 71 60 72 61 unsigned int num_ovls; 73 62 struct omap_hw_overlay *overlays[8]; 63 + 64 + struct drm_private_obj glob_obj; 74 65 75 66 struct drm_fb_helper *fbdev; 76 67 ··· 101 88 102 89 103 90 void omap_debugfs_init(struct drm_minor *minor); 91 + 92 + struct omap_global_state * __must_check omap_get_global_state(struct drm_atomic_state *s); 93 + 94 + struct omap_global_state *omap_get_existing_global_state(struct omap_drm_private *priv); 104 95 105 96 #endif /* __OMAPDRM_DRV_H__ */