summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/sun4i/sun4i_layer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun4i_layer.c')
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_layer.c56
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;
};