2 * Copyright (C) Icenowy Zheng <icenowy@aosc.io>
4 * Based on sun4i_layer.h, which is:
5 * Copyright (C) 2015 Free Electrons
6 * Copyright (C) 2015 NextThing Co
8 * Maxime Ripard <maxime.ripard@free-electrons.com>
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
16 #include <drm/drm_atomic_helper.h>
17 #include <drm/drm_plane_helper.h>
20 #include "sun8i_layer.h"
21 #include "sun8i_mixer.h"
23 struct sun8i_plane_desc
{
24 enum drm_plane_type type
;
25 const uint32_t *formats
;
29 static void sun8i_mixer_layer_atomic_disable(struct drm_plane
*plane
,
30 struct drm_plane_state
*old_state
)
32 struct sun8i_layer
*layer
= plane_to_sun8i_layer(plane
);
33 struct sun8i_mixer
*mixer
= layer
->mixer
;
35 sun8i_mixer_layer_enable(mixer
, layer
->id
, false);
38 static void sun8i_mixer_layer_atomic_update(struct drm_plane
*plane
,
39 struct drm_plane_state
*old_state
)
41 struct sun8i_layer
*layer
= plane_to_sun8i_layer(plane
);
42 struct sun8i_mixer
*mixer
= layer
->mixer
;
44 sun8i_mixer_update_layer_coord(mixer
, layer
->id
, plane
);
45 sun8i_mixer_update_layer_formats(mixer
, layer
->id
, plane
);
46 sun8i_mixer_update_layer_buffer(mixer
, layer
->id
, plane
);
47 sun8i_mixer_layer_enable(mixer
, layer
->id
, true);
50 static struct drm_plane_helper_funcs sun8i_mixer_layer_helper_funcs
= {
51 .atomic_disable
= sun8i_mixer_layer_atomic_disable
,
52 .atomic_update
= sun8i_mixer_layer_atomic_update
,
55 static const struct drm_plane_funcs sun8i_mixer_layer_funcs
= {
56 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
57 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
58 .destroy
= drm_plane_cleanup
,
59 .disable_plane
= drm_atomic_helper_disable_plane
,
60 .reset
= drm_atomic_helper_plane_reset
,
61 .update_plane
= drm_atomic_helper_update_plane
,
64 static const uint32_t sun8i_mixer_layer_formats
[] = {
70 static const struct sun8i_plane_desc sun8i_mixer_planes
[] = {
72 .type
= DRM_PLANE_TYPE_PRIMARY
,
73 .formats
= sun8i_mixer_layer_formats
,
74 .nformats
= ARRAY_SIZE(sun8i_mixer_layer_formats
),
78 static struct sun8i_layer
*sun8i_layer_init_one(struct drm_device
*drm
,
79 struct sun8i_mixer
*mixer
,
80 const struct sun8i_plane_desc
*plane
)
82 struct sun8i_layer
*layer
;
85 layer
= devm_kzalloc(drm
->dev
, sizeof(*layer
), GFP_KERNEL
);
87 return ERR_PTR(-ENOMEM
);
89 /* possible crtcs are set later */
90 ret
= drm_universal_plane_init(drm
, &layer
->plane
, 0,
91 &sun8i_mixer_layer_funcs
,
92 plane
->formats
, plane
->nformats
,
95 dev_err(drm
->dev
, "Couldn't initialize layer\n");
99 drm_plane_helper_add(&layer
->plane
,
100 &sun8i_mixer_layer_helper_funcs
);
101 layer
->mixer
= mixer
;
106 struct drm_plane
**sun8i_layers_init(struct drm_device
*drm
,
107 struct sunxi_engine
*engine
)
109 struct drm_plane
**planes
;
110 struct sun8i_mixer
*mixer
= engine_to_sun8i_mixer(engine
);
113 planes
= devm_kcalloc(drm
->dev
, ARRAY_SIZE(sun8i_mixer_planes
) + 1,
114 sizeof(*planes
), GFP_KERNEL
);
116 return ERR_PTR(-ENOMEM
);
118 for (i
= 0; i
< ARRAY_SIZE(sun8i_mixer_planes
); i
++) {
119 const struct sun8i_plane_desc
*plane
= &sun8i_mixer_planes
[i
];
120 struct sun8i_layer
*layer
;
122 layer
= sun8i_layer_init_one(drm
, mixer
, plane
);
124 dev_err(drm
->dev
, "Couldn't initialize %s plane\n",
125 i
? "overlay" : "primary");
126 return ERR_CAST(layer
);
130 planes
[i
] = &layer
->plane
;