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

drm: omapdrm: Use DRM core's atomic commit helper

The DRM core atomic helper now supports asynchronous commits natively.
The custom omapdrm implementation isn't needed anymore, remove it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

authored by

Laurent Pinchart and committed by
Tomi Valkeinen
a9e6f9f7 ce9a8f1a

+15 -106
+14 -98
drivers/gpu/drm/omapdrm/omap_drv.c
··· 17 17 * this program. If not, see <http://www.gnu.org/licenses/>. 18 18 */ 19 19 20 - #include <linux/wait.h> 21 - 22 20 #include <drm/drm_atomic.h> 23 21 #include <drm/drm_atomic_helper.h> 24 22 #include <drm/drm_crtc_helper.h> ··· 52 54 drm_fb_helper_hotplug_event(priv->fbdev); 53 55 } 54 56 55 - struct omap_atomic_state_commit { 56 - struct work_struct work; 57 - struct drm_device *dev; 58 - struct drm_atomic_state *state; 59 - u32 crtcs; 60 - }; 61 - 62 57 static void omap_atomic_wait_for_completion(struct drm_device *dev, 63 58 struct drm_atomic_state *old_state) 64 59 { ··· 72 81 } 73 82 } 74 83 75 - static void omap_atomic_complete(struct omap_atomic_state_commit *commit) 84 + static void omap_atomic_commit_tail(struct drm_atomic_state *old_state) 76 85 { 77 - struct drm_device *dev = commit->dev; 86 + struct drm_device *dev = old_state->dev; 78 87 struct omap_drm_private *priv = dev->dev_private; 79 - struct drm_atomic_state *old_state = commit->state; 80 88 81 - /* Apply the atomic update. */ 82 89 priv->dispc_ops->runtime_get(); 83 90 91 + /* Apply the atomic update. */ 84 92 drm_atomic_helper_commit_modeset_disables(dev, old_state); 85 93 86 94 /* With the current dss dispc implementation we have to enable ··· 98 108 99 109 drm_atomic_helper_commit_planes(dev, old_state, 0); 100 110 111 + drm_atomic_helper_commit_hw_done(old_state); 112 + 113 + /* 114 + * Wait for completion of the page flips to ensure that old buffers 115 + * can't be touched by the hardware anymore before cleaning up planes. 116 + */ 101 117 omap_atomic_wait_for_completion(dev, old_state); 102 118 103 119 drm_atomic_helper_cleanup_planes(dev, old_state); 104 120 105 121 priv->dispc_ops->runtime_put(); 106 - 107 - drm_atomic_state_put(old_state); 108 - 109 - /* Complete the commit, wake up any waiter. */ 110 - spin_lock(&priv->commit.lock); 111 - priv->commit.pending &= ~commit->crtcs; 112 - spin_unlock(&priv->commit.lock); 113 - 114 - wake_up_all(&priv->commit.wait); 115 - 116 - kfree(commit); 117 122 } 118 123 119 - static void omap_atomic_work(struct work_struct *work) 120 - { 121 - struct omap_atomic_state_commit *commit = 122 - container_of(work, struct omap_atomic_state_commit, work); 123 - 124 - omap_atomic_complete(commit); 125 - } 126 - 127 - static bool omap_atomic_is_pending(struct omap_drm_private *priv, 128 - struct omap_atomic_state_commit *commit) 129 - { 130 - bool pending; 131 - 132 - spin_lock(&priv->commit.lock); 133 - pending = priv->commit.pending & commit->crtcs; 134 - spin_unlock(&priv->commit.lock); 135 - 136 - return pending; 137 - } 138 - 139 - static int omap_atomic_commit(struct drm_device *dev, 140 - struct drm_atomic_state *state, bool nonblock) 141 - { 142 - struct omap_drm_private *priv = dev->dev_private; 143 - struct omap_atomic_state_commit *commit; 144 - struct drm_crtc *crtc; 145 - struct drm_crtc_state *crtc_state; 146 - int i, ret; 147 - 148 - ret = drm_atomic_helper_prepare_planes(dev, state); 149 - if (ret) 150 - return ret; 151 - 152 - /* Allocate the commit object. */ 153 - commit = kzalloc(sizeof(*commit), GFP_KERNEL); 154 - if (commit == NULL) { 155 - ret = -ENOMEM; 156 - goto error; 157 - } 158 - 159 - INIT_WORK(&commit->work, omap_atomic_work); 160 - commit->dev = dev; 161 - commit->state = state; 162 - 163 - /* Wait until all affected CRTCs have completed previous commits and 164 - * mark them as pending. 165 - */ 166 - for_each_crtc_in_state(state, crtc, crtc_state, i) 167 - commit->crtcs |= drm_crtc_mask(crtc); 168 - 169 - wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit)); 170 - 171 - spin_lock(&priv->commit.lock); 172 - priv->commit.pending |= commit->crtcs; 173 - spin_unlock(&priv->commit.lock); 174 - 175 - /* Swap the state, this is the point of no return. */ 176 - drm_atomic_helper_swap_state(state, true); 177 - 178 - drm_atomic_state_get(state); 179 - if (nonblock) 180 - schedule_work(&commit->work); 181 - else 182 - omap_atomic_complete(commit); 183 - 184 - return 0; 185 - 186 - error: 187 - drm_atomic_helper_cleanup_planes(dev, state); 188 - return ret; 189 - } 124 + static const struct drm_mode_config_helper_funcs omap_mode_config_helper_funcs = { 125 + .atomic_commit_tail = omap_atomic_commit_tail, 126 + }; 190 127 191 128 static const struct drm_mode_config_funcs omap_mode_config_funcs = { 192 129 .fb_create = omap_framebuffer_create, 193 130 .output_poll_changed = omap_fb_output_poll_changed, 194 131 .atomic_check = drm_atomic_helper_check, 195 - .atomic_commit = omap_atomic_commit, 132 + .atomic_commit = drm_atomic_helper_commit, 196 133 }; 197 134 198 135 static int get_connector_type(struct omap_dss_device *dssdev) ··· 302 385 dev->mode_config.max_height = 2048; 303 386 304 387 dev->mode_config.funcs = &omap_mode_config_funcs; 388 + dev->mode_config.helper_private = &omap_mode_config_helper_funcs; 305 389 306 390 drm_mode_config_reset(dev); 307 391 ··· 592 674 priv->omaprev = pdata->omaprev; 593 675 priv->wq = alloc_ordered_workqueue("omapdrm", 0); 594 676 595 - init_waitqueue_head(&priv->commit.wait); 596 - spin_lock_init(&priv->commit.lock); 597 677 spin_lock_init(&priv->list_lock); 598 678 INIT_LIST_HEAD(&priv->obj_list); 599 679
+1 -8
drivers/gpu/drm/omapdrm/omap_drv.h
··· 23 23 #include <linux/module.h> 24 24 #include <linux/platform_data/omap_drm.h> 25 25 #include <linux/types.h> 26 - #include <linux/wait.h> 26 + #include <linux/workqueue.h> 27 27 28 28 #include <drm/drmP.h> 29 29 #include <drm/drm_crtc_helper.h> ··· 93 93 spinlock_t wait_lock; /* protects the wait_list */ 94 94 struct list_head wait_list; /* list of omap_irq_wait */ 95 95 uint32_t irq_mask; /* enabled irqs in addition to wait_list */ 96 - 97 - /* atomic commit */ 98 - struct { 99 - wait_queue_head_t wait; 100 - u32 pending; 101 - spinlock_t lock; /* Protects commit.pending */ 102 - } commit; 103 96 }; 104 97 105 98