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

drm: Add atomic variants for bridge enable/disable

This patch adds atomic variants for all of
pre_enable/enable/disable/post_disable bridge functions. These will be
called from the appropriate atomic helper functions. If the bridge
driver doesn't implement the atomic version of the function, we will
fall back to the vanilla implementation.

Note that some drivers call drm_bridge_disable directly, and these cases
are not covered. It's up to the driver to decide whether to implement
both atomic_disable and disable, or if it's not necessary.

Changes in v3:
- Added to the patchset
Changes in v4:
- Fix up docbook references (Daniel)
Changes in v5:
- None

Link to v3: https://patchwork.freedesktop.org/patch/msgid/20190502194956.218441-4-sean@poorly.run
Link to v4: https://patchwork.freedesktop.org/patch/msgid/20190508160920.144739-4-sean@poorly.run

Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190611160844.257498-4-sean@poorly.run

+220 -4
+4 -4
drivers/gpu/drm/drm_atomic_helper.c
··· 998 998 * Each encoder has at most one connector (since we always steal 999 999 * it away), so we won't call disable hooks twice. 1000 1000 */ 1001 - drm_bridge_disable(encoder->bridge); 1001 + drm_atomic_bridge_disable(encoder->bridge, old_state); 1002 1002 1003 1003 /* Right function depends upon target state. */ 1004 1004 if (funcs) { ··· 1012 1012 funcs->dpms(encoder, DRM_MODE_DPMS_OFF); 1013 1013 } 1014 1014 1015 - drm_bridge_post_disable(encoder->bridge); 1015 + drm_atomic_bridge_post_disable(encoder->bridge, old_state); 1016 1016 } 1017 1017 1018 1018 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { ··· 1310 1310 * Each encoder has at most one connector (since we always steal 1311 1311 * it away), so we won't call enable hooks twice. 1312 1312 */ 1313 - drm_bridge_pre_enable(encoder->bridge); 1313 + drm_atomic_bridge_pre_enable(encoder->bridge, old_state); 1314 1314 1315 1315 if (funcs) { 1316 1316 if (funcs->atomic_enable) ··· 1321 1321 funcs->commit(encoder); 1322 1322 } 1323 1323 1324 - drm_bridge_enable(encoder->bridge); 1324 + drm_atomic_bridge_enable(encoder->bridge, old_state); 1325 1325 } 1326 1326 1327 1327 drm_atomic_helper_commit_writebacks(dev, old_state);
+110
drivers/gpu/drm/drm_bridge.c
··· 352 352 } 353 353 EXPORT_SYMBOL(drm_bridge_enable); 354 354 355 + /** 356 + * drm_atomic_bridge_disable - disables all bridges in the encoder chain 357 + * @bridge: bridge control structure 358 + * @state: atomic state being committed 359 + * 360 + * Calls &drm_bridge_funcs.atomic_disable (falls back on 361 + * &drm_bridge_funcs.disable) op for all the bridges in the encoder chain, 362 + * starting from the last bridge to the first. These are called before calling 363 + * &drm_encoder_helper_funcs.atomic_disable 364 + * 365 + * Note: the bridge passed should be the one closest to the encoder 366 + */ 367 + void drm_atomic_bridge_disable(struct drm_bridge *bridge, 368 + struct drm_atomic_state *state) 369 + { 370 + if (!bridge) 371 + return; 372 + 373 + drm_atomic_bridge_disable(bridge->next, state); 374 + 375 + if (bridge->funcs->atomic_disable) 376 + bridge->funcs->atomic_disable(bridge, state); 377 + else if (bridge->funcs->disable) 378 + bridge->funcs->disable(bridge); 379 + } 380 + EXPORT_SYMBOL(drm_atomic_bridge_disable); 381 + 382 + /** 383 + * drm_atomic_bridge_post_disable - cleans up after disabling all bridges in the 384 + * encoder chain 385 + * @bridge: bridge control structure 386 + * @state: atomic state being committed 387 + * 388 + * Calls &drm_bridge_funcs.atomic_post_disable (falls back on 389 + * &drm_bridge_funcs.post_disable) op for all the bridges in the encoder chain, 390 + * starting from the first bridge to the last. These are called after completing 391 + * &drm_encoder_helper_funcs.atomic_disable 392 + * 393 + * Note: the bridge passed should be the one closest to the encoder 394 + */ 395 + void drm_atomic_bridge_post_disable(struct drm_bridge *bridge, 396 + struct drm_atomic_state *state) 397 + { 398 + if (!bridge) 399 + return; 400 + 401 + if (bridge->funcs->atomic_post_disable) 402 + bridge->funcs->atomic_post_disable(bridge, state); 403 + else if (bridge->funcs->post_disable) 404 + bridge->funcs->post_disable(bridge); 405 + 406 + drm_atomic_bridge_post_disable(bridge->next, state); 407 + } 408 + EXPORT_SYMBOL(drm_atomic_bridge_post_disable); 409 + 410 + /** 411 + * drm_atomic_bridge_pre_enable - prepares for enabling all bridges in the 412 + * encoder chain 413 + * @bridge: bridge control structure 414 + * @state: atomic state being committed 415 + * 416 + * Calls &drm_bridge_funcs.atomic_pre_enable (falls back on 417 + * &drm_bridge_funcs.pre_enable) op for all the bridges in the encoder chain, 418 + * starting from the last bridge to the first. These are called before calling 419 + * &drm_encoder_helper_funcs.atomic_enable 420 + * 421 + * Note: the bridge passed should be the one closest to the encoder 422 + */ 423 + void drm_atomic_bridge_pre_enable(struct drm_bridge *bridge, 424 + struct drm_atomic_state *state) 425 + { 426 + if (!bridge) 427 + return; 428 + 429 + drm_atomic_bridge_pre_enable(bridge->next, state); 430 + 431 + if (bridge->funcs->atomic_pre_enable) 432 + bridge->funcs->atomic_pre_enable(bridge, state); 433 + else if (bridge->funcs->pre_enable) 434 + bridge->funcs->pre_enable(bridge); 435 + } 436 + EXPORT_SYMBOL(drm_atomic_bridge_pre_enable); 437 + 438 + /** 439 + * drm_atomic_bridge_enable - enables all bridges in the encoder chain 440 + * @bridge: bridge control structure 441 + * @state: atomic state being committed 442 + * 443 + * Calls &drm_bridge_funcs.atomic_enable (falls back on 444 + * &drm_bridge_funcs.enable) op for all the bridges in the encoder chain, 445 + * starting from the first bridge to the last. These are called after completing 446 + * &drm_encoder_helper_funcs.atomic_enable 447 + * 448 + * Note: the bridge passed should be the one closest to the encoder 449 + */ 450 + void drm_atomic_bridge_enable(struct drm_bridge *bridge, 451 + struct drm_atomic_state *state) 452 + { 453 + if (!bridge) 454 + return; 455 + 456 + if (bridge->funcs->atomic_enable) 457 + bridge->funcs->atomic_enable(bridge, state); 458 + else if (bridge->funcs->enable) 459 + bridge->funcs->enable(bridge); 460 + 461 + drm_atomic_bridge_enable(bridge->next, state); 462 + } 463 + EXPORT_SYMBOL(drm_atomic_bridge_enable); 464 + 355 465 #ifdef CONFIG_OF 356 466 /** 357 467 * of_drm_find_bridge - find the bridge corresponding to the device node in
+106
include/drm/drm_bridge.h
··· 237 237 * The enable callback is optional. 238 238 */ 239 239 void (*enable)(struct drm_bridge *bridge); 240 + 241 + /** 242 + * @atomic_pre_enable: 243 + * 244 + * This callback should enable the bridge. It is called right before 245 + * the preceding element in the display pipe is enabled. If the 246 + * preceding element is a bridge this means it's called before that 247 + * bridge's @atomic_pre_enable or @pre_enable function. If the preceding 248 + * element is a &drm_encoder it's called right before the encoder's 249 + * &drm_encoder_helper_funcs.atomic_enable hook. 250 + * 251 + * The display pipe (i.e. clocks and timing signals) feeding this bridge 252 + * will not yet be running when this callback is called. The bridge must 253 + * not enable the display link feeding the next bridge in the chain (if 254 + * there is one) when this callback is called. 255 + * 256 + * Note that this function will only be invoked in the context of an 257 + * atomic commit. It will not be invoked from &drm_bridge_pre_enable. It 258 + * would be prudent to also provide an implementation of @pre_enable if 259 + * you are expecting driver calls into &drm_bridge_pre_enable. 260 + * 261 + * The @atomic_pre_enable callback is optional. 262 + */ 263 + void (*atomic_pre_enable)(struct drm_bridge *bridge, 264 + struct drm_atomic_state *state); 265 + 266 + /** 267 + * @atomic_enable: 268 + * 269 + * This callback should enable the bridge. It is called right after 270 + * the preceding element in the display pipe is enabled. If the 271 + * preceding element is a bridge this means it's called after that 272 + * bridge's @atomic_enable or @enable function. If the preceding element 273 + * is a &drm_encoder it's called right after the encoder's 274 + * &drm_encoder_helper_funcs.atomic_enable hook. 275 + * 276 + * The bridge can assume that the display pipe (i.e. clocks and timing 277 + * signals) feeding it is running when this callback is called. This 278 + * callback must enable the display link feeding the next bridge in the 279 + * chain if there is one. 280 + * 281 + * Note that this function will only be invoked in the context of an 282 + * atomic commit. It will not be invoked from &drm_bridge_enable. It 283 + * would be prudent to also provide an implementation of @enable if 284 + * you are expecting driver calls into &drm_bridge_enable. 285 + * 286 + * The enable callback is optional. 287 + */ 288 + void (*atomic_enable)(struct drm_bridge *bridge, 289 + struct drm_atomic_state *state); 290 + /** 291 + * @atomic_disable: 292 + * 293 + * This callback should disable the bridge. It is called right before 294 + * the preceding element in the display pipe is disabled. If the 295 + * preceding element is a bridge this means it's called before that 296 + * bridge's @atomic_disable or @disable vfunc. If the preceding element 297 + * is a &drm_encoder it's called right before the 298 + * &drm_encoder_helper_funcs.atomic_disable hook. 299 + * 300 + * The bridge can assume that the display pipe (i.e. clocks and timing 301 + * signals) feeding it is still running when this callback is called. 302 + * 303 + * Note that this function will only be invoked in the context of an 304 + * atomic commit. It will not be invoked from &drm_bridge_disable. It 305 + * would be prudent to also provide an implementation of @disable if 306 + * you are expecting driver calls into &drm_bridge_disable. 307 + * 308 + * The disable callback is optional. 309 + */ 310 + void (*atomic_disable)(struct drm_bridge *bridge, 311 + struct drm_atomic_state *state); 312 + 313 + /** 314 + * @atomic_post_disable: 315 + * 316 + * This callback should disable the bridge. It is called right after the 317 + * preceding element in the display pipe is disabled. If the preceding 318 + * element is a bridge this means it's called after that bridge's 319 + * @atomic_post_disable or @post_disable function. If the preceding 320 + * element is a &drm_encoder it's called right after the encoder's 321 + * &drm_encoder_helper_funcs.atomic_disable hook. 322 + * 323 + * The bridge must assume that the display pipe (i.e. clocks and timing 324 + * signals) feeding it is no longer running when this callback is 325 + * called. 326 + * 327 + * Note that this function will only be invoked in the context of an 328 + * atomic commit. It will not be invoked from &drm_bridge_post_disable. 329 + * It would be prudent to also provide an implementation of 330 + * @post_disable if you are expecting driver calls into 331 + * &drm_bridge_post_disable. 332 + * 333 + * The post_disable callback is optional. 334 + */ 335 + void (*atomic_post_disable)(struct drm_bridge *bridge, 336 + struct drm_atomic_state *state); 240 337 }; 241 338 242 339 /** ··· 410 313 const struct drm_display_mode *adjusted_mode); 411 314 void drm_bridge_pre_enable(struct drm_bridge *bridge); 412 315 void drm_bridge_enable(struct drm_bridge *bridge); 316 + 317 + void drm_atomic_bridge_disable(struct drm_bridge *bridge, 318 + struct drm_atomic_state *state); 319 + void drm_atomic_bridge_post_disable(struct drm_bridge *bridge, 320 + struct drm_atomic_state *state); 321 + void drm_atomic_bridge_pre_enable(struct drm_bridge *bridge, 322 + struct drm_atomic_state *state); 323 + void drm_atomic_bridge_enable(struct drm_bridge *bridge, 324 + struct drm_atomic_state *state); 413 325 414 326 #ifdef CONFIG_DRM_PANEL_BRIDGE 415 327 struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,