Skip to content

Commit c8fa1e7

Browse files
bparrottomba
authored andcommitted
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 <[email protected]> Signed-off-by: Neil Armstrong <[email protected]> Reviewed-by: Tomi Valkeinen <[email protected]> Signed-off-by: Tomi Valkeinen <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 0b0f728 commit c8fa1e7

File tree

6 files changed

+148
-34
lines changed

6 files changed

+148
-34
lines changed

drivers/gpu/drm/omapdrm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ omapdrm-y := omap_drv.o \
99
omap_debugfs.o \
1010
omap_crtc.o \
1111
omap_plane.o \
12+
omap_overlay.o \
1213
omap_encoder.o \
1314
omap_fb.o \
1415
omap_gem.o \

drivers/gpu/drm/omapdrm/omap_drv.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,10 +583,14 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
583583

584584
omap_gem_init(ddev);
585585

586+
ret = omap_hwoverlays_init(priv);
587+
if (ret)
588+
goto err_gem_deinit;
589+
586590
ret = omap_modeset_init(ddev);
587591
if (ret) {
588592
dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret);
589-
goto err_gem_deinit;
593+
goto err_free_overlays;
590594
}
591595

592596
/* Initialize vblank handling, start with all CRTCs disabled. */
@@ -618,6 +622,8 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev)
618622
omap_fbdev_fini(ddev);
619623
err_cleanup_modeset:
620624
omap_modeset_fini(ddev);
625+
err_free_overlays:
626+
omap_hwoverlays_destroy(priv);
621627
err_gem_deinit:
622628
omap_gem_deinit(ddev);
623629
destroy_workqueue(priv->wq);
@@ -642,6 +648,7 @@ static void omapdrm_cleanup(struct omap_drm_private *priv)
642648
drm_atomic_helper_shutdown(ddev);
643649

644650
omap_modeset_fini(ddev);
651+
omap_hwoverlays_destroy(priv);
645652
omap_gem_deinit(ddev);
646653

647654
destroy_workqueue(priv->wq);

drivers/gpu/drm/omapdrm/omap_drv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "omap_gem.h"
2525
#include "omap_irq.h"
2626
#include "omap_plane.h"
27+
#include "omap_overlay.h"
2728

2829
#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
2930
#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) /* verbose debug */
@@ -57,6 +58,9 @@ struct omap_drm_private {
5758
unsigned int num_planes;
5859
struct drm_plane *planes[8];
5960

61+
unsigned int num_ovls;
62+
struct omap_hw_overlay *overlays[8];
63+
6064
struct drm_fb_helper *fbdev;
6165

6266
struct workqueue_struct *wq;
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
4+
* Author: Benoit Parrot <[email protected]>
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+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
4+
* Author: Benoit Parrot <[email protected]>
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__ */

drivers/gpu/drm/omapdrm/omap_plane.c

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
struct omap_plane {
2222
struct drm_plane base;
2323
enum omap_plane_id id;
24-
const char *name;
24+
25+
struct omap_hw_overlay *overlay;
2526
};
2627

2728
static int omap_plane_prepare_fb(struct drm_plane *plane,
@@ -49,10 +50,11 @@ static void omap_plane_atomic_update(struct drm_plane *plane,
4950
struct omap_plane *omap_plane = to_omap_plane(plane);
5051
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
5152
plane);
53+
enum omap_plane_id ovl_id = omap_plane->overlay->id;
5254
struct omap_overlay_info info;
5355
int ret;
5456

55-
DBG("%s, crtc=%p fb=%p", omap_plane->name, new_state->crtc,
57+
DBG("%s, crtc=%p fb=%p", plane->name, new_state->crtc,
5658
new_state->fb);
5759

5860
memset(&info, 0, sizeof(info));
@@ -77,17 +79,17 @@ static void omap_plane_atomic_update(struct drm_plane *plane,
7779
&info.paddr, &info.p_uv_addr);
7880

7981
/* and finally, update omapdss: */
80-
ret = dispc_ovl_setup(priv->dispc, omap_plane->id, &info,
82+
ret = dispc_ovl_setup(priv->dispc, ovl_id, &info,
8183
omap_crtc_timings(new_state->crtc), false,
8284
omap_crtc_channel(new_state->crtc));
8385
if (ret) {
8486
dev_err(plane->dev->dev, "Failed to setup plane %s\n",
85-
omap_plane->name);
86-
dispc_ovl_enable(priv->dispc, omap_plane->id, false);
87+
plane->name);
88+
dispc_ovl_enable(priv->dispc, ovl_id, false);
8789
return;
8890
}
8991

90-
dispc_ovl_enable(priv->dispc, omap_plane->id, true);
92+
dispc_ovl_enable(priv->dispc, ovl_id, true);
9193
}
9294

9395
static void omap_plane_atomic_disable(struct drm_plane *plane,
@@ -97,11 +99,12 @@ static void omap_plane_atomic_disable(struct drm_plane *plane,
9799
plane);
98100
struct omap_drm_private *priv = plane->dev->dev_private;
99101
struct omap_plane *omap_plane = to_omap_plane(plane);
102+
enum omap_plane_id ovl_id = omap_plane->overlay->id;
100103

101104
new_state->rotation = DRM_MODE_ROTATE_0;
102105
new_state->zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : omap_plane->id;
103106

104-
dispc_ovl_enable(priv->dispc, omap_plane->id, false);
107+
dispc_ovl_enable(priv->dispc, ovl_id, false);
105108
}
106109

107110
#define FRAC_16_16(mult, div) (((mult) << 16) / (div))
@@ -184,7 +187,7 @@ static void omap_plane_destroy(struct drm_plane *plane)
184187
{
185188
struct omap_plane *omap_plane = to_omap_plane(plane);
186189

187-
DBG("%s", omap_plane->name);
190+
DBG("%s", plane->name);
188191

189192
drm_plane_cleanup(plane);
190193

@@ -290,20 +293,6 @@ static bool omap_plane_supports_yuv(struct drm_plane *plane)
290293
return false;
291294
}
292295

293-
static const char *plane_id_to_name[] = {
294-
[OMAP_DSS_GFX] = "gfx",
295-
[OMAP_DSS_VIDEO1] = "vid1",
296-
[OMAP_DSS_VIDEO2] = "vid2",
297-
[OMAP_DSS_VIDEO3] = "vid3",
298-
};
299-
300-
static const enum omap_plane_id plane_idx_to_id[] = {
301-
OMAP_DSS_GFX,
302-
OMAP_DSS_VIDEO1,
303-
OMAP_DSS_VIDEO2,
304-
OMAP_DSS_VIDEO3,
305-
};
306-
307296
/* initialize plane */
308297
struct drm_plane *omap_plane_init(struct drm_device *dev,
309298
int idx, enum drm_plane_type type,
@@ -313,27 +302,26 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
313302
unsigned int num_planes = dispc_get_num_ovls(priv->dispc);
314303
struct drm_plane *plane;
315304
struct omap_plane *omap_plane;
316-
enum omap_plane_id id;
317305
int ret;
318306
u32 nformats;
319307
const u32 *formats;
320308

321-
if (WARN_ON(idx >= ARRAY_SIZE(plane_idx_to_id)))
309+
if (WARN_ON(idx >= num_planes))
322310
return ERR_PTR(-EINVAL);
323311

324-
id = plane_idx_to_id[idx];
325-
326-
DBG("%s: type=%d", plane_id_to_name[id], type);
327-
328312
omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
329313
if (!omap_plane)
330314
return ERR_PTR(-ENOMEM);
331315

332-
formats = dispc_ovl_get_color_modes(priv->dispc, id);
316+
omap_plane->id = idx;
317+
omap_plane->overlay = priv->overlays[idx];
318+
319+
DBG("%d: type=%d", omap_plane->id, type);
320+
DBG(" crtc_mask: 0x%04x", possible_crtcs);
321+
322+
formats = dispc_ovl_get_color_modes(priv->dispc, omap_plane->overlay->id);
333323
for (nformats = 0; formats[nformats]; ++nformats)
334324
;
335-
omap_plane->id = id;
336-
omap_plane->name = plane_id_to_name[id];
337325

338326
plane = &omap_plane->base;
339327

@@ -363,8 +351,8 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
363351
return plane;
364352

365353
error:
366-
dev_err(dev->dev, "%s(): could not create plane: %s\n",
367-
__func__, plane_id_to_name[id]);
354+
dev_err(dev->dev, "%s(): could not create plane: %d\n",
355+
__func__, omap_plane->id);
368356

369357
kfree(omap_plane);
370358
return NULL;

0 commit comments

Comments
 (0)