|
@@ -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;
|
|
|
};
|