diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_layer.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_layer.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 068ab806309b..f0035bf5efea 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -19,7 +19,12 @@ #include "sun4i_drv.h" #include "sun4i_layer.h" -#define SUN4I_NUM_LAYERS 2 +struct sun4i_plane_desc { + enum drm_plane_type type; + u8 pipe; + const uint32_t *formats; + uint32_t nformats; +}; static int sun4i_backend_layer_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) @@ -65,14 +70,35 @@ static const struct drm_plane_funcs sun4i_backend_layer_funcs = { .update_plane = drm_atomic_helper_update_plane, }; -static const uint32_t sun4i_backend_layer_formats[] = { +static const uint32_t sun4i_backend_layer_formats_primary[] = { DRM_FORMAT_ARGB8888, + DRM_FORMAT_RGB888, DRM_FORMAT_XRGB8888, +}; + +static const uint32_t sun4i_backend_layer_formats_overlay[] = { + DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB888, + DRM_FORMAT_XRGB8888, +}; + +static const struct sun4i_plane_desc sun4i_backend_planes[] = { + { + .type = DRM_PLANE_TYPE_PRIMARY, + .pipe = 0, + .formats = sun4i_backend_layer_formats_primary, + .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_primary), + }, + { + .type = DRM_PLANE_TYPE_OVERLAY, + .pipe = 1, + .formats = sun4i_backend_layer_formats_overlay, + .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_overlay), + }, }; static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, - enum drm_plane_type type) + const struct sun4i_plane_desc *plane) { struct sun4i_drv *drv = drm->dev_private; struct sun4i_layer *layer; @@ -84,10 +110,8 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, ret = drm_universal_plane_init(drm, &layer->plane, BIT(0), &sun4i_backend_layer_funcs, - sun4i_backend_layer_formats, - ARRAY_SIZE(sun4i_backend_layer_formats), - type, - NULL); + plane->formats, plane->nformats, + plane->type, NULL); if (ret) { dev_err(drm->dev, "Couldn't initialize layer\n"); return ERR_PTR(ret); @@ -97,7 +121,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, &sun4i_backend_layer_helper_funcs); layer->drv = drv; - if (type == DRM_PLANE_TYPE_PRIMARY) + if (plane->type == DRM_PLANE_TYPE_PRIMARY) drv->primary = &layer->plane; return layer; @@ -109,8 +133,8 @@ struct sun4i_layer **sun4i_layers_init(struct drm_device *drm) struct sun4i_layer **layers; int i; - layers = devm_kcalloc(drm->dev, SUN4I_NUM_LAYERS, sizeof(**layers), - GFP_KERNEL); + layers = devm_kcalloc(drm->dev, ARRAY_SIZE(sun4i_backend_planes), + sizeof(**layers), GFP_KERNEL); if (!layers) return ERR_PTR(-ENOMEM); @@ -135,13 +159,11 @@ struct sun4i_layer **sun4i_layers_init(struct drm_device *drm) * SoCs that support it, sprites could fill the need for more * layers. */ - for (i = 0; i < SUN4I_NUM_LAYERS; i++) { - enum drm_plane_type type = (i == 0) - ? DRM_PLANE_TYPE_PRIMARY - : DRM_PLANE_TYPE_OVERLAY; + for (i = 0; i < ARRAY_SIZE(sun4i_backend_planes); i++) { + const struct sun4i_plane_desc *plane = &sun4i_backend_planes[i]; struct sun4i_layer *layer = layers[i]; - layer = sun4i_layer_init_one(drm, type); + layer = sun4i_layer_init_one(drm, plane); if (IS_ERR(layer)) { dev_err(drm->dev, "Couldn't initialize %s plane\n", i ? "overlay" : "primary"); @@ -149,10 +171,10 @@ struct sun4i_layer **sun4i_layers_init(struct drm_device *drm) }; DRM_DEBUG_DRIVER("Assigning %s plane to pipe %d\n", - i ? "overlay" : "primary", i); + i ? "overlay" : "primary", plane->pipe); regmap_update_bits(drv->backend->regs, SUN4I_BACKEND_ATTCTL_REG0(i), SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK, - SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(i)); + SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(plane->pipe)); layer->id = i; }; |