drm/komeda: remove set but not used variable 'kcrtc'
[muen/linux.git] / drivers / gpu / drm / arm / display / komeda / komeda_plane.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4  * Author: James.Qian.Wang <james.qian.wang@arm.com>
5  *
6  */
7 #include <drm/drm_atomic.h>
8 #include <drm/drm_atomic_helper.h>
9 #include <drm/drm_plane_helper.h>
10 #include <drm/drm_print.h>
11 #include "komeda_dev.h"
12 #include "komeda_kms.h"
13
14 static int
15 komeda_plane_init_data_flow(struct drm_plane_state *st,
16                             struct komeda_data_flow_cfg *dflow)
17 {
18         struct drm_framebuffer *fb = st->fb;
19
20         memset(dflow, 0, sizeof(*dflow));
21
22         dflow->blending_zorder = st->zpos;
23
24         /* if format doesn't have alpha, fix blend mode to PIXEL_NONE */
25         dflow->pixel_blend_mode = fb->format->has_alpha ?
26                 st->pixel_blend_mode : DRM_MODE_BLEND_PIXEL_NONE;
27         dflow->layer_alpha = st->alpha >> 8;
28
29         dflow->out_x = st->crtc_x;
30         dflow->out_y = st->crtc_y;
31         dflow->out_w = st->crtc_w;
32         dflow->out_h = st->crtc_h;
33
34         dflow->in_x = st->src_x >> 16;
35         dflow->in_y = st->src_y >> 16;
36         dflow->in_w = st->src_w >> 16;
37         dflow->in_h = st->src_h >> 16;
38
39         return 0;
40 }
41
42 /**
43  * komeda_plane_atomic_check - build input data flow
44  * @plane: DRM plane
45  * @state: the plane state object
46  *
47  * RETURNS:
48  * Zero for success or -errno
49  */
50 static int
51 komeda_plane_atomic_check(struct drm_plane *plane,
52                           struct drm_plane_state *state)
53 {
54         struct komeda_plane *kplane = to_kplane(plane);
55         struct komeda_plane_state *kplane_st = to_kplane_st(state);
56         struct komeda_layer *layer = kplane->layer;
57         struct drm_crtc_state *crtc_st;
58         struct komeda_crtc_state *kcrtc_st;
59         struct komeda_data_flow_cfg dflow;
60         int err;
61
62         if (!state->crtc || !state->fb)
63                 return 0;
64
65         crtc_st = drm_atomic_get_crtc_state(state->state, state->crtc);
66         if (!crtc_st->enable) {
67                 DRM_DEBUG_ATOMIC("Cannot update plane on a disabled CRTC.\n");
68                 return -EINVAL;
69         }
70
71         /* crtc is inactive, skip the resource assignment */
72         if (!crtc_st->active)
73                 return 0;
74
75         kcrtc_st = to_kcrtc_st(crtc_st);
76
77         err = komeda_plane_init_data_flow(state, &dflow);
78         if (err)
79                 return err;
80
81         err = komeda_build_layer_data_flow(layer, kplane_st, kcrtc_st, &dflow);
82
83         return err;
84 }
85
86 /* plane doesn't represent a real HW, so there is no HW update for plane.
87  * komeda handles all the HW update in crtc->atomic_flush
88  */
89 static void
90 komeda_plane_atomic_update(struct drm_plane *plane,
91                            struct drm_plane_state *old_state)
92 {
93 }
94
95 static const struct drm_plane_helper_funcs komeda_plane_helper_funcs = {
96         .atomic_check   = komeda_plane_atomic_check,
97         .atomic_update  = komeda_plane_atomic_update,
98 };
99
100 static void komeda_plane_destroy(struct drm_plane *plane)
101 {
102         drm_plane_cleanup(plane);
103
104         kfree(to_kplane(plane));
105 }
106
107 static void komeda_plane_reset(struct drm_plane *plane)
108 {
109         struct komeda_plane_state *state;
110         struct komeda_plane *kplane = to_kplane(plane);
111
112         if (plane->state)
113                 __drm_atomic_helper_plane_destroy_state(plane->state);
114
115         kfree(plane->state);
116         plane->state = NULL;
117
118         state = kzalloc(sizeof(*state), GFP_KERNEL);
119         if (state) {
120                 state->base.rotation = DRM_MODE_ROTATE_0;
121                 state->base.pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
122                 state->base.alpha = DRM_BLEND_ALPHA_OPAQUE;
123                 state->base.zpos = kplane->layer->base.id;
124                 plane->state = &state->base;
125                 plane->state->plane = plane;
126         }
127 }
128
129 static struct drm_plane_state *
130 komeda_plane_atomic_duplicate_state(struct drm_plane *plane)
131 {
132         struct komeda_plane_state *new;
133
134         if (WARN_ON(!plane->state))
135                 return NULL;
136
137         new = kzalloc(sizeof(*new), GFP_KERNEL);
138         if (!new)
139                 return NULL;
140
141         __drm_atomic_helper_plane_duplicate_state(plane, &new->base);
142
143         return &new->base;
144 }
145
146 static void
147 komeda_plane_atomic_destroy_state(struct drm_plane *plane,
148                                   struct drm_plane_state *state)
149 {
150         __drm_atomic_helper_plane_destroy_state(state);
151         kfree(to_kplane_st(state));
152 }
153
154 static const struct drm_plane_funcs komeda_plane_funcs = {
155         .update_plane           = drm_atomic_helper_update_plane,
156         .disable_plane          = drm_atomic_helper_disable_plane,
157         .destroy                = komeda_plane_destroy,
158         .reset                  = komeda_plane_reset,
159         .atomic_duplicate_state = komeda_plane_atomic_duplicate_state,
160         .atomic_destroy_state   = komeda_plane_atomic_destroy_state,
161 };
162
163 /* for komeda, which is pipeline can be share between crtcs */
164 static u32 get_possible_crtcs(struct komeda_kms_dev *kms,
165                               struct komeda_pipeline *pipe)
166 {
167         struct komeda_crtc *crtc;
168         u32 possible_crtcs = 0;
169         int i;
170
171         for (i = 0; i < kms->n_crtcs; i++) {
172                 crtc = &kms->crtcs[i];
173
174                 if ((pipe == crtc->master) || (pipe == crtc->slave))
175                         possible_crtcs |= BIT(i);
176         }
177
178         return possible_crtcs;
179 }
180
181 /* use Layer0 as primary */
182 static u32 get_plane_type(struct komeda_kms_dev *kms,
183                           struct komeda_component *c)
184 {
185         bool is_primary = (c->id == KOMEDA_COMPONENT_LAYER0);
186
187         return is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
188 }
189
190 static int komeda_plane_add(struct komeda_kms_dev *kms,
191                             struct komeda_layer *layer)
192 {
193         struct komeda_dev *mdev = kms->base.dev_private;
194         struct komeda_component *c = &layer->base;
195         struct komeda_plane *kplane;
196         struct drm_plane *plane;
197         u32 *formats, n_formats = 0;
198         int err;
199
200         kplane = kzalloc(sizeof(*kplane), GFP_KERNEL);
201         if (!kplane)
202                 return -ENOMEM;
203
204         plane = &kplane->base;
205         kplane->layer = layer;
206
207         formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl,
208                                                layer->layer_type, &n_formats);
209
210         err = drm_universal_plane_init(&kms->base, plane,
211                         get_possible_crtcs(kms, c->pipeline),
212                         &komeda_plane_funcs,
213                         formats, n_formats, NULL,
214                         get_plane_type(kms, c),
215                         "%s", c->name);
216
217         komeda_put_fourcc_list(formats);
218
219         if (err)
220                 goto cleanup;
221
222         drm_plane_helper_add(plane, &komeda_plane_helper_funcs);
223
224         return 0;
225 cleanup:
226         komeda_plane_destroy(plane);
227         return err;
228 }
229
230 int komeda_kms_add_planes(struct komeda_kms_dev *kms, struct komeda_dev *mdev)
231 {
232         struct komeda_pipeline *pipe;
233         int i, j, err;
234
235         for (i = 0; i < mdev->n_pipelines; i++) {
236                 pipe = mdev->pipelines[i];
237
238                 for (j = 0; j < pipe->n_layers; j++) {
239                         err = komeda_plane_add(kms, pipe->layers[j]);
240                         if (err)
241                                 return err;
242                 }
243         }
244
245         return 0;
246 }