mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 22:31:32 +00:00
drm: omapdrm: Switch to the universal plane API
Remove the CRTC private planes by switching to the universal plane API. This results in a merge of the CRTC private plane created by the driver (omap_crtc->plane) and the CRTC primary plane created by the DRM core (crtc->primary). Reference counting of the framebuffers in the update plane operation is thus simplified as no reference needs to be stored in the private plane anymore. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
9c660b7ceb
commit
ef6b0e0275
@ -28,7 +28,6 @@
|
|||||||
|
|
||||||
struct omap_crtc {
|
struct omap_crtc {
|
||||||
struct drm_crtc base;
|
struct drm_crtc base;
|
||||||
struct drm_plane *plane;
|
|
||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
int pipe;
|
int pipe;
|
||||||
@ -217,10 +216,7 @@ static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||||||
omap_crtc->full_update = true;
|
omap_crtc->full_update = true;
|
||||||
omap_crtc_apply(crtc, &omap_crtc->apply);
|
omap_crtc_apply(crtc, &omap_crtc->apply);
|
||||||
|
|
||||||
/* also enable our private plane: */
|
/* Enable/disable all planes associated with the CRTC. */
|
||||||
WARN_ON(omap_plane_dpms(omap_crtc->plane, mode));
|
|
||||||
|
|
||||||
/* and any attached overlay planes: */
|
|
||||||
for (i = 0; i < priv->num_planes; i++) {
|
for (i = 0; i < priv->num_planes; i++) {
|
||||||
struct drm_plane *plane = priv->planes[i];
|
struct drm_plane *plane = priv->planes[i];
|
||||||
if (plane->crtc == crtc)
|
if (plane->crtc == crtc)
|
||||||
@ -258,7 +254,13 @@ static int omap_crtc_mode_set(struct drm_crtc *crtc,
|
|||||||
copy_timings_drm_to_omap(&omap_crtc->timings, mode);
|
copy_timings_drm_to_omap(&omap_crtc->timings, mode);
|
||||||
omap_crtc->full_update = true;
|
omap_crtc->full_update = true;
|
||||||
|
|
||||||
return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb,
|
/*
|
||||||
|
* The primary plane CRTC can be reset if the plane is disabled directly
|
||||||
|
* through the universal plane API. Set it again here.
|
||||||
|
*/
|
||||||
|
crtc->primary->crtc = crtc;
|
||||||
|
|
||||||
|
return omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
|
||||||
0, 0, mode->hdisplay, mode->vdisplay,
|
0, 0, mode->hdisplay, mode->vdisplay,
|
||||||
x << 16, y << 16,
|
x << 16, y << 16,
|
||||||
mode->hdisplay << 16, mode->vdisplay << 16,
|
mode->hdisplay << 16, mode->vdisplay << 16,
|
||||||
@ -282,8 +284,7 @@ static void omap_crtc_commit(struct drm_crtc *crtc)
|
|||||||
static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
|
static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
|
||||||
struct drm_framebuffer *old_fb)
|
struct drm_framebuffer *old_fb)
|
||||||
{
|
{
|
||||||
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
|
struct drm_plane *plane = crtc->primary;
|
||||||
struct drm_plane *plane = omap_crtc->plane;
|
|
||||||
struct drm_display_mode *mode = &crtc->mode;
|
struct drm_display_mode *mode = &crtc->mode;
|
||||||
|
|
||||||
return omap_plane_mode_set(plane, crtc, crtc->primary->fb,
|
return omap_plane_mode_set(plane, crtc, crtc->primary->fb,
|
||||||
@ -321,7 +322,7 @@ static void page_flip_worker(struct work_struct *work)
|
|||||||
struct drm_gem_object *bo;
|
struct drm_gem_object *bo;
|
||||||
|
|
||||||
drm_modeset_lock(&crtc->mutex, NULL);
|
drm_modeset_lock(&crtc->mutex, NULL);
|
||||||
omap_plane_mode_set(omap_crtc->plane, crtc, crtc->primary->fb,
|
omap_plane_mode_set(crtc->primary, crtc, crtc->primary->fb,
|
||||||
0, 0, mode->hdisplay, mode->vdisplay,
|
0, 0, mode->hdisplay, mode->vdisplay,
|
||||||
crtc->x << 16, crtc->y << 16,
|
crtc->x << 16, crtc->y << 16,
|
||||||
mode->hdisplay << 16, mode->vdisplay << 16,
|
mode->hdisplay << 16, mode->vdisplay << 16,
|
||||||
@ -385,7 +386,6 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
|
|||||||
static int omap_crtc_set_property(struct drm_crtc *crtc,
|
static int omap_crtc_set_property(struct drm_crtc *crtc,
|
||||||
struct drm_property *property, uint64_t val)
|
struct drm_property *property, uint64_t val)
|
||||||
{
|
{
|
||||||
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
|
|
||||||
struct omap_drm_private *priv = crtc->dev->dev_private;
|
struct omap_drm_private *priv = crtc->dev->dev_private;
|
||||||
|
|
||||||
if (property == priv->rotation_prop) {
|
if (property == priv->rotation_prop) {
|
||||||
@ -393,7 +393,7 @@ static int omap_crtc_set_property(struct drm_crtc *crtc,
|
|||||||
!!(val & ((1LL << DRM_ROTATE_90) | (1LL << DRM_ROTATE_270)));
|
!!(val & ((1LL << DRM_ROTATE_90) | (1LL << DRM_ROTATE_270)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return omap_plane_set_property(omap_crtc->plane, property, val);
|
return omap_plane_set_property(crtc->primary, property, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_crtc_funcs omap_crtc_funcs = {
|
static const struct drm_crtc_funcs omap_crtc_funcs = {
|
||||||
@ -681,12 +681,13 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
|||||||
struct drm_crtc *crtc = NULL;
|
struct drm_crtc *crtc = NULL;
|
||||||
struct omap_crtc *omap_crtc;
|
struct omap_crtc *omap_crtc;
|
||||||
struct omap_overlay_manager_info *info;
|
struct omap_overlay_manager_info *info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
DBG("%s", channel_names[channel]);
|
DBG("%s", channel_names[channel]);
|
||||||
|
|
||||||
omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
|
omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
|
||||||
if (!omap_crtc)
|
if (!omap_crtc)
|
||||||
goto fail;
|
return NULL;
|
||||||
|
|
||||||
crtc = &omap_crtc->base;
|
crtc = &omap_crtc->base;
|
||||||
|
|
||||||
@ -700,8 +701,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
|||||||
omap_crtc->apply.post_apply = omap_crtc_post_apply;
|
omap_crtc->apply.post_apply = omap_crtc_post_apply;
|
||||||
|
|
||||||
omap_crtc->channel = channel;
|
omap_crtc->channel = channel;
|
||||||
omap_crtc->plane = plane;
|
|
||||||
omap_crtc->plane->crtc = crtc;
|
|
||||||
omap_crtc->name = channel_names[channel];
|
omap_crtc->name = channel_names[channel];
|
||||||
omap_crtc->pipe = id;
|
omap_crtc->pipe = id;
|
||||||
|
|
||||||
@ -723,18 +722,18 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
|||||||
info->trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
|
info->trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
|
||||||
info->trans_enabled = false;
|
info->trans_enabled = false;
|
||||||
|
|
||||||
drm_crtc_init(dev, crtc, &omap_crtc_funcs);
|
ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
|
||||||
|
&omap_crtc_funcs);
|
||||||
|
if (ret < 0) {
|
||||||
|
kfree(omap_crtc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
|
drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
|
||||||
|
|
||||||
omap_plane_install_properties(omap_crtc->plane, &crtc->base);
|
omap_plane_install_properties(crtc->primary, &crtc->base);
|
||||||
|
|
||||||
omap_crtcs[channel] = omap_crtc;
|
omap_crtcs[channel] = omap_crtc;
|
||||||
|
|
||||||
return crtc;
|
return crtc;
|
||||||
|
|
||||||
fail:
|
|
||||||
if (crtc)
|
|
||||||
omap_crtc_destroy(crtc);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ static int omap_modeset_create_crtc(struct drm_device *dev, int id,
|
|||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
plane = omap_plane_init(dev, id, true);
|
plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_PRIMARY);
|
||||||
if (IS_ERR(plane))
|
if (IS_ERR(plane))
|
||||||
return PTR_ERR(plane);
|
return PTR_ERR(plane);
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ static int omap_modeset_init(struct drm_device *dev)
|
|||||||
for (; id < num_ovls; id++) {
|
for (; id < num_ovls; id++) {
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
|
|
||||||
plane = omap_plane_init(dev, id, false);
|
plane = omap_plane_init(dev, id, DRM_PLANE_TYPE_OVERLAY);
|
||||||
if (IS_ERR(plane))
|
if (IS_ERR(plane))
|
||||||
return PTR_ERR(plane);
|
return PTR_ERR(plane);
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
|
|||||||
void omap_crtc_flush(struct drm_crtc *crtc);
|
void omap_crtc_flush(struct drm_crtc *crtc);
|
||||||
|
|
||||||
struct drm_plane *omap_plane_init(struct drm_device *dev,
|
struct drm_plane *omap_plane_init(struct drm_device *dev,
|
||||||
int plane_id, bool private_plane);
|
int id, enum drm_plane_type type);
|
||||||
int omap_plane_dpms(struct drm_plane *plane, int mode);
|
int omap_plane_dpms(struct drm_plane *plane, int mode);
|
||||||
int omap_plane_mode_set(struct drm_plane *plane,
|
int omap_plane_mode_set(struct drm_plane *plane,
|
||||||
struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
||||||
|
@ -220,14 +220,6 @@ int omap_plane_mode_set(struct drm_plane *plane,
|
|||||||
omap_plane->apply_done_cb.arg = arg;
|
omap_plane->apply_done_cb.arg = arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plane->fb)
|
|
||||||
drm_framebuffer_unreference(plane->fb);
|
|
||||||
|
|
||||||
drm_framebuffer_reference(fb);
|
|
||||||
|
|
||||||
plane->fb = fb;
|
|
||||||
plane->crtc = crtc;
|
|
||||||
|
|
||||||
return apply(plane);
|
return apply(plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +241,13 @@ static int omap_plane_update(struct drm_plane *plane,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't need to take a reference to the framebuffer as the DRM core
|
||||||
|
* has already done so for the purpose of setting plane->fb.
|
||||||
|
*/
|
||||||
|
plane->fb = fb;
|
||||||
|
plane->crtc = crtc;
|
||||||
|
|
||||||
return omap_plane_mode_set(plane, crtc, fb,
|
return omap_plane_mode_set(plane, crtc, fb,
|
||||||
crtc_x, crtc_y, crtc_w, crtc_h,
|
crtc_x, crtc_y, crtc_w, crtc_h,
|
||||||
src_x, src_y, src_w, src_h,
|
src_x, src_y, src_w, src_h,
|
||||||
@ -377,14 +376,15 @@ static const uint32_t error_irqs[] = {
|
|||||||
|
|
||||||
/* initialize plane */
|
/* initialize plane */
|
||||||
struct drm_plane *omap_plane_init(struct drm_device *dev,
|
struct drm_plane *omap_plane_init(struct drm_device *dev,
|
||||||
int id, bool private_plane)
|
int id, enum drm_plane_type type)
|
||||||
{
|
{
|
||||||
struct omap_drm_private *priv = dev->dev_private;
|
struct omap_drm_private *priv = dev->dev_private;
|
||||||
struct drm_plane *plane = NULL;
|
struct drm_plane *plane;
|
||||||
struct omap_plane *omap_plane;
|
struct omap_plane *omap_plane;
|
||||||
struct omap_overlay_info *info;
|
struct omap_overlay_info *info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
DBG("%s: priv=%d", plane_names[id], private_plane);
|
DBG("%s: type=%d", plane_names[id], type);
|
||||||
|
|
||||||
omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
|
omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL);
|
||||||
if (!omap_plane)
|
if (!omap_plane)
|
||||||
@ -408,8 +408,11 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
|
|||||||
omap_plane->error_irq.irq = omap_plane_error_irq;
|
omap_plane->error_irq.irq = omap_plane_error_irq;
|
||||||
omap_irq_register(dev, &omap_plane->error_irq);
|
omap_irq_register(dev, &omap_plane->error_irq);
|
||||||
|
|
||||||
drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &omap_plane_funcs,
|
ret = drm_universal_plane_init(dev, plane, (1 << priv->num_crtcs) - 1,
|
||||||
omap_plane->formats, omap_plane->nformats, private_plane);
|
&omap_plane_funcs, omap_plane->formats,
|
||||||
|
omap_plane->nformats, type);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
omap_plane_install_properties(plane, &plane->base);
|
omap_plane_install_properties(plane, &plane->base);
|
||||||
|
|
||||||
@ -427,10 +430,15 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
|
|||||||
* TODO add ioctl to give userspace an API to change this.. this
|
* TODO add ioctl to give userspace an API to change this.. this
|
||||||
* will come in a subsequent patch.
|
* will come in a subsequent patch.
|
||||||
*/
|
*/
|
||||||
if (private_plane)
|
if (type == DRM_PLANE_TYPE_PRIMARY)
|
||||||
omap_plane->info.zorder = 0;
|
omap_plane->info.zorder = 0;
|
||||||
else
|
else
|
||||||
omap_plane->info.zorder = id;
|
omap_plane->info.zorder = id;
|
||||||
|
|
||||||
return plane;
|
return plane;
|
||||||
|
|
||||||
|
error:
|
||||||
|
omap_irq_unregister(plane->dev, &omap_plane->error_irq);
|
||||||
|
kfree(omap_plane);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user