diff options
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_plane.c')
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_plane.c | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index f27e87a23df7..8b92a45a3c89 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -19,11 +19,11 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_uapi.h> #include <drm/drm_blend.h> -#include <drm/drm_fb_cma_helper.h> +#include <drm/drm_drv.h> +#include <drm/drm_fb_dma_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> -#include <drm/drm_plane_helper.h> #include "uapi/drm/vc4_drm.h" @@ -340,7 +340,7 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) { struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); struct drm_framebuffer *fb = state->fb; - struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); + struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, 0); int num_planes = fb->format->num_planes; struct drm_crtc_state *crtc_state; u32 h_subsample = fb->format->hsub; @@ -360,7 +360,7 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) return ret; for (i = 0; i < num_planes; i++) - vc4_state->offsets[i] = bo->paddr + fb->offsets[i]; + vc4_state->offsets[i] = bo->dma_addr + fb->offsets[i]; /* * We don't support subpixel source positioning for scaling, @@ -1220,6 +1220,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist) { struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); int i; + int idx; + + if (!drm_dev_enter(plane->dev, &idx)) + goto out; vc4_state->hw_dlist = dlist; @@ -1227,6 +1231,9 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist) for (i = 0; i < vc4_state->dlist_count; i++) writel(vc4_state->dlist[i], &dlist[i]); + drm_dev_exit(idx); + +out: return vc4_state->dlist_count; } @@ -1244,14 +1251,18 @@ u32 vc4_plane_dlist_size(const struct drm_plane_state *state) void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb) { struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); - struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); + struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, 0); uint32_t addr; + int idx; + + if (!drm_dev_enter(plane->dev, &idx)) + return; /* We're skipping the address adjustment for negative origin, * because this is only called on the primary plane. */ WARN_ON_ONCE(plane->state->crtc_x < 0 || plane->state->crtc_y < 0); - addr = bo->paddr + fb->offsets[0]; + addr = bo->dma_addr + fb->offsets[0]; /* Write the new address into the hardware immediately. The * scanout will start from this address as soon as the FIFO @@ -1264,6 +1275,8 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb) * also use our updated address. */ vc4_state->dlist[vc4_state->ptr0_offset] = addr; + + drm_dev_exit(idx); } static void vc4_plane_atomic_async_update(struct drm_plane *plane, @@ -1272,6 +1285,10 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); struct vc4_plane_state *vc4_state, *new_vc4_state; + int idx; + + if (!drm_dev_enter(plane->dev, &idx)) + return; swap(plane->state->fb, new_plane_state->fb); plane->state->crtc_x = new_plane_state->crtc_x; @@ -1334,6 +1351,8 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, &vc4_state->hw_dlist[vc4_state->pos2_offset]); writel(vc4_state->dlist[vc4_state->ptr0_offset], &vc4_state->hw_dlist[vc4_state->ptr0_offset]); + + drm_dev_exit(idx); } static int vc4_plane_atomic_async_check(struct drm_plane *plane, @@ -1388,7 +1407,7 @@ static int vc4_prepare_fb(struct drm_plane *plane, if (!state->fb) return 0; - bo = to_vc4_bo(&drm_fb_cma_get_gem_obj(state->fb, 0)->base); + bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base); drm_gem_plane_helper_prepare_fb(plane, state); @@ -1406,7 +1425,7 @@ static void vc4_cleanup_fb(struct drm_plane *plane, if (plane->state->fb == state->fb || !state->fb) return; - bo = to_vc4_bo(&drm_fb_cma_get_gem_obj(state->fb, 0)->base); + bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base); vc4_bo_dec_usecnt(bo); } @@ -1483,8 +1502,6 @@ static bool vc4_format_mod_supported(struct drm_plane *plane, static const struct drm_plane_funcs vc4_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, - .destroy = drm_plane_cleanup, - .set_property = NULL, .reset = vc4_plane_reset, .atomic_duplicate_state = vc4_plane_duplicate_state, .atomic_destroy_state = vc4_plane_destroy_state, @@ -1492,14 +1509,14 @@ static const struct drm_plane_funcs vc4_plane_funcs = { }; struct drm_plane *vc4_plane_init(struct drm_device *dev, - enum drm_plane_type type) + enum drm_plane_type type, + uint32_t possible_crtcs) { struct vc4_dev *vc4 = to_vc4_dev(dev); - struct drm_plane *plane = NULL; + struct drm_plane *plane; struct vc4_plane *vc4_plane; u32 formats[ARRAY_SIZE(hvs_formats)]; int num_formats = 0; - int ret = 0; unsigned i; static const uint64_t modifiers[] = { DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED, @@ -1510,11 +1527,6 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, DRM_FORMAT_MOD_INVALID }; - vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane), - GFP_KERNEL); - if (!vc4_plane) - return ERR_PTR(-ENOMEM); - for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) { if (!hvs_formats[i].hvs5_only || vc4->is_vc5) { formats[num_formats] = hvs_formats[i].drm; @@ -1522,13 +1534,14 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, } } + vc4_plane = drmm_universal_plane_alloc(dev, struct vc4_plane, base, + possible_crtcs, + &vc4_plane_funcs, + formats, num_formats, + modifiers, type, NULL); + if (IS_ERR(vc4_plane)) + return ERR_CAST(vc4_plane); plane = &vc4_plane->base; - ret = drm_universal_plane_init(dev, plane, 0, - &vc4_plane_funcs, - formats, num_formats, - modifiers, type, NULL); - if (ret) - return ERR_PTR(ret); if (vc4->is_vc5) drm_plane_helper_add(plane, &vc5_plane_helper_funcs); @@ -1575,13 +1588,11 @@ int vc4_plane_create_additional_planes(struct drm_device *drm) */ for (i = 0; i < 16; i++) { struct drm_plane *plane = - vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY); + vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY, + GENMASK(drm->mode_config.num_crtc - 1, 0)); if (IS_ERR(plane)) continue; - - plane->possible_crtcs = - GENMASK(drm->mode_config.num_crtc - 1, 0); } drm_for_each_crtc(crtc, drm) { @@ -1589,9 +1600,9 @@ int vc4_plane_create_additional_planes(struct drm_device *drm) * since we overlay planes on the CRTC in the order they were * initialized. */ - cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR); + cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR, + drm_crtc_mask(crtc)); if (!IS_ERR(cursor_plane)) { - cursor_plane->possible_crtcs = drm_crtc_mask(crtc); crtc->cursor = cursor_plane; } } |