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: introduce omap_hw_overlay

Split out the hardware overlay specifics from omap_plane.
To start, the hw overlays are statically assigned to planes.

The goal is to eventually assign hw overlays dynamically to planes
during plane->atomic_check() based on requested caps (scaling, YUV,
etc). And then perform hw overlay re-assignment if required.

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-5-narmstrong@baylibre.com

authored by

Benoit Parrot and committed by
Tomi Valkeinen
c8fa1e73 0b0f7282

+148 -34
+1
drivers/gpu/drm/omapdrm/Makefile
··· 9 9 omap_debugfs.o \ 10 10 omap_crtc.o \ 11 11 omap_plane.o \ 12 + omap_overlay.o \ 12 13 omap_encoder.o \ 13 14 omap_fb.o \ 14 15 omap_gem.o \
+8 -1
drivers/gpu/drm/omapdrm/omap_drv.c
··· 583 583 584 584 omap_gem_init(ddev); 585 585 586 + ret = omap_hwoverlays_init(priv); 587 + if (ret) 588 + goto err_gem_deinit; 589 + 586 590 ret = omap_modeset_init(ddev); 587 591 if (ret) { 588 592 dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret); 589 - goto err_gem_deinit; 593 + goto err_free_overlays; 590 594 } 591 595 592 596 /* Initialize vblank handling, start with all CRTCs disabled. */ ··· 622 618 omap_fbdev_fini(ddev); 623 619 err_cleanup_modeset: 624 620 omap_modeset_fini(ddev); 621 + err_free_overlays: 622 + omap_hwoverlays_destroy(priv); 625 623 err_gem_deinit: 626 624 omap_gem_deinit(ddev); 627 625 destroy_workqueue(priv->wq); ··· 648 642 drm_atomic_helper_shutdown(ddev); 649 643 650 644 omap_modeset_fini(ddev); 645 + omap_hwoverlays_destroy(priv); 651 646 omap_gem_deinit(ddev); 652 647 653 648 destroy_workqueue(priv->wq);
+4
drivers/gpu/drm/omapdrm/omap_drv.h
··· 24 24 #include "omap_gem.h" 25 25 #include "omap_irq.h" 26 26 #include "omap_plane.h" 27 + #include "omap_overlay.h" 27 28 28 29 #define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__) 29 30 #define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) /* verbose debug */ ··· 57 56 58 57 unsigned int num_planes; 59 58 struct drm_plane *planes[8]; 59 + 60 + unsigned int num_ovls; 61 + struct omap_hw_overlay *overlays[8]; 60 62 61 63 struct drm_fb_helper *fbdev; 62 64
+84
drivers/gpu/drm/omapdrm/omap_overlay.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ 4 + * Author: Benoit Parrot <bparrot@ti.com> 5 + */ 6 + 7 + #include <drm/drm_atomic.h> 8 + #include <drm/drm_atomic_helper.h> 9 + #include <drm/drm_plane_helper.h> 10 + 11 + #include "omap_dmm_tiler.h" 12 + #include "omap_drv.h" 13 + 14 + /* 15 + * overlay funcs 16 + */ 17 + static const char * const overlay_id_to_name[] = { 18 + [OMAP_DSS_GFX] = "gfx", 19 + [OMAP_DSS_VIDEO1] = "vid1", 20 + [OMAP_DSS_VIDEO2] = "vid2", 21 + [OMAP_DSS_VIDEO3] = "vid3", 22 + }; 23 + 24 + static void omap_overlay_destroy(struct omap_hw_overlay *overlay) 25 + { 26 + kfree(overlay); 27 + } 28 + 29 + static struct omap_hw_overlay *omap_overlay_init(enum omap_plane_id overlay_id, 30 + enum omap_overlay_caps caps) 31 + { 32 + struct omap_hw_overlay *overlay; 33 + 34 + overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); 35 + if (!overlay) 36 + return ERR_PTR(-ENOMEM); 37 + 38 + overlay->name = overlay_id_to_name[overlay_id]; 39 + overlay->id = overlay_id; 40 + overlay->caps = caps; 41 + 42 + return overlay; 43 + } 44 + 45 + int omap_hwoverlays_init(struct omap_drm_private *priv) 46 + { 47 + static const enum omap_plane_id hw_plane_ids[] = { 48 + OMAP_DSS_GFX, OMAP_DSS_VIDEO1, 49 + OMAP_DSS_VIDEO2, OMAP_DSS_VIDEO3, 50 + }; 51 + u32 num_overlays = dispc_get_num_ovls(priv->dispc); 52 + enum omap_overlay_caps caps; 53 + int i, ret; 54 + 55 + for (i = 0; i < num_overlays; i++) { 56 + struct omap_hw_overlay *overlay; 57 + 58 + caps = dispc_ovl_get_caps(priv->dispc, hw_plane_ids[i]); 59 + overlay = omap_overlay_init(hw_plane_ids[i], caps); 60 + if (IS_ERR(overlay)) { 61 + ret = PTR_ERR(overlay); 62 + dev_err(priv->dev, "failed to construct overlay for %s (%d)\n", 63 + overlay_id_to_name[i], ret); 64 + omap_hwoverlays_destroy(priv); 65 + return ret; 66 + } 67 + overlay->idx = priv->num_ovls; 68 + priv->overlays[priv->num_ovls++] = overlay; 69 + } 70 + 71 + return 0; 72 + } 73 + 74 + void omap_hwoverlays_destroy(struct omap_drm_private *priv) 75 + { 76 + int i; 77 + 78 + for (i = 0; i < priv->num_ovls; i++) { 79 + omap_overlay_destroy(priv->overlays[i]); 80 + priv->overlays[i] = NULL; 81 + } 82 + 83 + priv->num_ovls = 0; 84 + }
+30
drivers/gpu/drm/omapdrm/omap_overlay.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ 4 + * Author: Benoit Parrot <bparrot@ti.com> 5 + */ 6 + 7 + #ifndef __OMAPDRM_OVERLAY_H__ 8 + #define __OMAPDRM_OVERLAY_H__ 9 + 10 + #include <linux/types.h> 11 + 12 + enum drm_plane_type; 13 + 14 + struct drm_device; 15 + struct drm_mode_object; 16 + struct drm_plane; 17 + 18 + /* Used to associate a HW overlay/plane to a plane */ 19 + struct omap_hw_overlay { 20 + unsigned int idx; 21 + 22 + const char *name; 23 + enum omap_plane_id id; 24 + 25 + enum omap_overlay_caps caps; 26 + }; 27 + 28 + int omap_hwoverlays_init(struct omap_drm_private *priv); 29 + void omap_hwoverlays_destroy(struct omap_drm_private *priv); 30 + #endif /* __OMAPDRM_OVERLAY_H__ */
+21 -33
drivers/gpu/drm/omapdrm/omap_plane.c
··· 21 21 struct omap_plane { 22 22 struct drm_plane base; 23 23 enum omap_plane_id id; 24 - const char *name; 24 + 25 + struct omap_hw_overlay *overlay; 25 26 }; 26 27 27 28 static int omap_plane_prepare_fb(struct drm_plane *plane, ··· 50 49 struct omap_plane *omap_plane = to_omap_plane(plane); 51 50 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, 52 51 plane); 52 + enum omap_plane_id ovl_id = omap_plane->overlay->id; 53 53 struct omap_overlay_info info; 54 54 int ret; 55 55 56 - DBG("%s, crtc=%p fb=%p", omap_plane->name, new_state->crtc, 56 + DBG("%s, crtc=%p fb=%p", plane->name, new_state->crtc, 57 57 new_state->fb); 58 58 59 59 memset(&info, 0, sizeof(info)); ··· 79 77 &info.paddr, &info.p_uv_addr); 80 78 81 79 /* and finally, update omapdss: */ 82 - ret = dispc_ovl_setup(priv->dispc, omap_plane->id, &info, 80 + ret = dispc_ovl_setup(priv->dispc, ovl_id, &info, 83 81 omap_crtc_timings(new_state->crtc), false, 84 82 omap_crtc_channel(new_state->crtc)); 85 83 if (ret) { 86 84 dev_err(plane->dev->dev, "Failed to setup plane %s\n", 87 - omap_plane->name); 88 - dispc_ovl_enable(priv->dispc, omap_plane->id, false); 85 + plane->name); 86 + dispc_ovl_enable(priv->dispc, ovl_id, false); 89 87 return; 90 88 } 91 89 92 - dispc_ovl_enable(priv->dispc, omap_plane->id, true); 90 + dispc_ovl_enable(priv->dispc, ovl_id, true); 93 91 } 94 92 95 93 static void omap_plane_atomic_disable(struct drm_plane *plane, ··· 99 97 plane); 100 98 struct omap_drm_private *priv = plane->dev->dev_private; 101 99 struct omap_plane *omap_plane = to_omap_plane(plane); 100 + enum omap_plane_id ovl_id = omap_plane->overlay->id; 102 101 103 102 new_state->rotation = DRM_MODE_ROTATE_0; 104 103 new_state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : omap_plane->id; 105 104 106 - dispc_ovl_enable(priv->dispc, omap_plane->id, false); 105 + dispc_ovl_enable(priv->dispc, ovl_id, false); 107 106 } 108 107 109 108 #define FRAC_16_16(mult, div) (((mult) << 16) / (div)) ··· 187 184 { 188 185 struct omap_plane *omap_plane = to_omap_plane(plane); 189 186 190 - DBG("%s", omap_plane->name); 187 + DBG("%s", plane->name); 191 188 192 189 drm_plane_cleanup(plane); 193 190 ··· 293 290 return false; 294 291 } 295 292 296 - static const char *plane_id_to_name[] = { 297 - [OMAP_DSS_GFX] = "gfx", 298 - [OMAP_DSS_VIDEO1] = "vid1", 299 - [OMAP_DSS_VIDEO2] = "vid2", 300 - [OMAP_DSS_VIDEO3] = "vid3", 301 - }; 302 - 303 - static const enum omap_plane_id plane_idx_to_id[] = { 304 - OMAP_DSS_GFX, 305 - OMAP_DSS_VIDEO1, 306 - OMAP_DSS_VIDEO2, 307 - OMAP_DSS_VIDEO3, 308 - }; 309 - 310 293 /* initialize plane */ 311 294 struct drm_plane *omap_plane_init(struct drm_device *dev, 312 295 int idx, enum drm_plane_type type, ··· 302 313 unsigned int num_planes = dispc_get_num_ovls(priv->dispc); 303 314 struct drm_plane *plane; 304 315 struct omap_plane *omap_plane; 305 - enum omap_plane_id id; 306 316 int ret; 307 317 u32 nformats; 308 318 const u32 *formats; 309 319 310 - if (WARN_ON(idx >= ARRAY_SIZE(plane_idx_to_id))) 320 + if (WARN_ON(idx >= num_planes)) 311 321 return ERR_PTR(-EINVAL); 312 - 313 - id = plane_idx_to_id[idx]; 314 - 315 - DBG("%s: type=%d", plane_id_to_name[id], type); 316 322 317 323 omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); 318 324 if (!omap_plane) 319 325 return ERR_PTR(-ENOMEM); 320 326 321 - formats = dispc_ovl_get_color_modes(priv->dispc, id); 327 + omap_plane->id = idx; 328 + omap_plane->overlay = priv->overlays[idx]; 329 + 330 + DBG("%d: type=%d", omap_plane->id, type); 331 + DBG(" crtc_mask: 0x%04x", possible_crtcs); 332 + 333 + formats = dispc_ovl_get_color_modes(priv->dispc, omap_plane->overlay->id); 322 334 for (nformats = 0; formats[nformats]; ++nformats) 323 335 ; 324 - omap_plane->id = id; 325 - omap_plane->name = plane_id_to_name[id]; 326 336 327 337 plane = &omap_plane->base; 328 338 ··· 351 363 return plane; 352 364 353 365 error: 354 - dev_err(dev->dev, "%s(): could not create plane: %s\n", 355 - __func__, plane_id_to_name[id]); 366 + dev_err(dev->dev, "%s(): could not create plane: %d\n", 367 + __func__, omap_plane->id); 356 368 357 369 kfree(omap_plane); 358 370 return NULL;