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 
8 #include <drm/drm_print.h>
9 #include <linux/clk.h>
10 #include "komeda_dev.h"
11 #include "komeda_kms.h"
12 #include "komeda_pipeline.h"
13 #include "komeda_framebuffer.h"
14 
15 static inline bool is_switching_user(void *old, void *new)
16 {
17 	if (!old || !new)
18 		return false;
19 
20 	return old != new;
21 }
22 
23 static struct komeda_pipeline_state *
24 komeda_pipeline_get_state(struct komeda_pipeline *pipe,
25 			  struct drm_atomic_state *state)
26 {
27 	struct drm_private_state *priv_st;
28 
29 	priv_st = drm_atomic_get_private_obj_state(state, &pipe->obj);
30 	if (IS_ERR(priv_st))
31 		return ERR_CAST(priv_st);
32 
33 	return priv_to_pipe_st(priv_st);
34 }
35 
36 struct komeda_pipeline_state *
37 komeda_pipeline_get_old_state(struct komeda_pipeline *pipe,
38 			      struct drm_atomic_state *state)
39 {
40 	struct drm_private_state *priv_st;
41 
42 	priv_st = drm_atomic_get_old_private_obj_state(state, &pipe->obj);
43 	if (priv_st)
44 		return priv_to_pipe_st(priv_st);
45 	return NULL;
46 }
47 
48 static struct komeda_pipeline_state *
49 komeda_pipeline_get_new_state(struct komeda_pipeline *pipe,
50 			      struct drm_atomic_state *state)
51 {
52 	struct drm_private_state *priv_st;
53 
54 	priv_st = drm_atomic_get_new_private_obj_state(state, &pipe->obj);
55 	if (priv_st)
56 		return priv_to_pipe_st(priv_st);
57 	return NULL;
58 }
59 
60 /* Assign pipeline for crtc */
61 static struct komeda_pipeline_state *
62 komeda_pipeline_get_state_and_set_crtc(struct komeda_pipeline *pipe,
63 				       struct drm_atomic_state *state,
64 				       struct drm_crtc *crtc)
65 {
66 	struct komeda_pipeline_state *st;
67 
68 	st = komeda_pipeline_get_state(pipe, state);
69 	if (IS_ERR(st))
70 		return st;
71 
72 	if (is_switching_user(crtc, st->crtc)) {
73 		DRM_DEBUG_ATOMIC("CRTC%d required pipeline%d is busy.\n",
74 				 drm_crtc_index(crtc), pipe->id);
75 		return ERR_PTR(-EBUSY);
76 	}
77 
78 	/* pipeline only can be disabled when the it is free or unused */
79 	if (!crtc && st->active_comps) {
80 		DRM_DEBUG_ATOMIC("Disabling a busy pipeline:%d.\n", pipe->id);
81 		return ERR_PTR(-EBUSY);
82 	}
83 
84 	st->crtc = crtc;
85 
86 	if (crtc) {
87 		struct komeda_crtc_state *kcrtc_st;
88 
89 		kcrtc_st = to_kcrtc_st(drm_atomic_get_new_crtc_state(state,
90 								     crtc));
91 
92 		kcrtc_st->active_pipes |= BIT(pipe->id);
93 		kcrtc_st->affected_pipes |= BIT(pipe->id);
94 	}
95 	return st;
96 }
97 
98 static struct komeda_component_state *
99 komeda_component_get_state(struct komeda_component *c,
100 			   struct drm_atomic_state *state)
101 {
102 	struct drm_private_state *priv_st;
103 
104 	WARN_ON(!drm_modeset_is_locked(&c->pipeline->obj.lock));
105 
106 	priv_st = drm_atomic_get_private_obj_state(state, &c->obj);
107 	if (IS_ERR(priv_st))
108 		return ERR_CAST(priv_st);
109 
110 	return priv_to_comp_st(priv_st);
111 }
112 
113 static struct komeda_component_state *
114 komeda_component_get_old_state(struct komeda_component *c,
115 			       struct drm_atomic_state *state)
116 {
117 	struct drm_private_state *priv_st;
118 
119 	priv_st = drm_atomic_get_old_private_obj_state(state, &c->obj);
120 	if (priv_st)
121 		return priv_to_comp_st(priv_st);
122 	return NULL;
123 }
124 
125 /**
126  * komeda_component_get_state_and_set_user()
127  *
128  * @c: component to get state and set user
129  * @state: global atomic state
130  * @user: direct user, the binding user
131  * @crtc: the CRTC user, the big boss :)
132  *
133  * This function accepts two users:
134  * -   The direct user: can be plane/crtc/wb_connector depends on component
135  * -   The big boss (CRTC)
136  * CRTC is the big boss (the final user), because all component resources
137  * eventually will be assigned to CRTC, like the layer will be binding to
138  * kms_plane, but kms plane will be binding to a CRTC eventually.
139  *
140  * The big boss (CRTC) is for pipeline assignment, since &komeda_component isn't
141  * independent and can be assigned to CRTC freely, but belongs to a specific
142  * pipeline, only pipeline can be shared between crtc, and pipeline as a whole
143  * (include all the internal components) assigned to a specific CRTC.
144  *
145  * So when set a user to komeda_component, need first to check the status of
146  * component->pipeline to see if the pipeline is available on this specific
147  * CRTC. if the pipeline is busy (assigned to another CRTC), even the required
148  * component is free, the component still cannot be assigned to the direct user.
149  */
150 static struct komeda_component_state *
151 komeda_component_get_state_and_set_user(struct komeda_component *c,
152 					struct drm_atomic_state *state,
153 					void *user,
154 					struct drm_crtc *crtc)
155 {
156 	struct komeda_pipeline_state *pipe_st;
157 	struct komeda_component_state *st;
158 
159 	/* First check if the pipeline is available */
160 	pipe_st = komeda_pipeline_get_state_and_set_crtc(c->pipeline,
161 							 state, crtc);
162 	if (IS_ERR(pipe_st))
163 		return ERR_CAST(pipe_st);
164 
165 	st = komeda_component_get_state(c, state);
166 	if (IS_ERR(st))
167 		return st;
168 
169 	/* check if the component has been occupied */
170 	if (is_switching_user(user, st->binding_user)) {
171 		DRM_DEBUG_ATOMIC("required %s is busy.\n", c->name);
172 		return ERR_PTR(-EBUSY);
173 	}
174 
175 	st->binding_user = user;
176 	/* mark the component as active if user is valid */
177 	if (st->binding_user)
178 		pipe_st->active_comps |= BIT(c->id);
179 
180 	return st;
181 }
182 
183 static void
184 komeda_component_add_input(struct komeda_component_state *state,
185 			   struct komeda_component_output *input,
186 			   int idx)
187 {
188 	struct komeda_component *c = state->component;
189 
190 	WARN_ON((idx < 0 || idx >= c->max_active_inputs));
191 
192 	/* since the inputs[i] is only valid when it is active. So if a input[i]
193 	 * is a newly enabled input which switches from disable to enable, then
194 	 * the old inputs[i] is undefined (NOT zeroed), we can not rely on
195 	 * memcmp, but directly mark it changed
196 	 */
197 	if (!has_bit(idx, state->affected_inputs) ||
198 	    memcmp(&state->inputs[idx], input, sizeof(*input))) {
199 		memcpy(&state->inputs[idx], input, sizeof(*input));
200 		state->changed_active_inputs |= BIT(idx);
201 	}
202 	state->active_inputs |= BIT(idx);
203 	state->affected_inputs |= BIT(idx);
204 }
205 
206 static int
207 komeda_component_check_input(struct komeda_component_state *state,
208 			     struct komeda_component_output *input,
209 			     int idx)
210 {
211 	struct komeda_component *c = state->component;
212 
213 	if ((idx < 0) || (idx >= c->max_active_inputs)) {
214 		DRM_DEBUG_ATOMIC("%s invalid input id: %d.\n", c->name, idx);
215 		return -EINVAL;
216 	}
217 
218 	if (has_bit(idx, state->active_inputs)) {
219 		DRM_DEBUG_ATOMIC("%s required input_id: %d has been occupied already.\n",
220 				 c->name, idx);
221 		return -EINVAL;
222 	}
223 
224 	return 0;
225 }
226 
227 static void
228 komeda_component_set_output(struct komeda_component_output *output,
229 			    struct komeda_component *comp,
230 			    u8 output_port)
231 {
232 	output->component = comp;
233 	output->output_port = output_port;
234 }
235 
236 static int
237 komeda_component_validate_private(struct komeda_component *c,
238 				  struct komeda_component_state *st)
239 {
240 	int err;
241 
242 	if (!c->funcs->validate)
243 		return 0;
244 
245 	err = c->funcs->validate(c, st);
246 	if (err)
247 		DRM_DEBUG_ATOMIC("%s validate private failed.\n", c->name);
248 
249 	return err;
250 }
251 
252 static int
253 komeda_layer_check_cfg(struct komeda_layer *layer,
254 		       struct komeda_plane_state *kplane_st,
255 		       struct komeda_data_flow_cfg *dflow)
256 {
257 	if (!in_range(&layer->hsize_in, dflow->in_w)) {
258 		DRM_DEBUG_ATOMIC("src_w: %d is out of range.\n", dflow->in_w);
259 		return -EINVAL;
260 	}
261 
262 	if (!in_range(&layer->vsize_in, dflow->in_h)) {
263 		DRM_DEBUG_ATOMIC("src_h: %d is out of range.\n", dflow->in_h);
264 		return -EINVAL;
265 	}
266 
267 	return 0;
268 }
269 
270 static int
271 komeda_layer_validate(struct komeda_layer *layer,
272 		      struct komeda_plane_state *kplane_st,
273 		      struct komeda_data_flow_cfg *dflow)
274 {
275 	struct drm_plane_state *plane_st = &kplane_st->base;
276 	struct drm_framebuffer *fb = plane_st->fb;
277 	struct komeda_fb *kfb = to_kfb(fb);
278 	struct komeda_component_state *c_st;
279 	struct komeda_layer_state *st;
280 	int i, err;
281 
282 	err = komeda_layer_check_cfg(layer, kplane_st, dflow);
283 	if (err)
284 		return err;
285 
286 	c_st = komeda_component_get_state_and_set_user(&layer->base,
287 			plane_st->state, plane_st->plane, plane_st->crtc);
288 	if (IS_ERR(c_st))
289 		return PTR_ERR(c_st);
290 
291 	st = to_layer_st(c_st);
292 
293 	st->rot = dflow->rot;
294 	st->hsize = kfb->aligned_w;
295 	st->vsize = kfb->aligned_h;
296 
297 	for (i = 0; i < fb->format->num_planes; i++)
298 		st->addr[i] = komeda_fb_get_pixel_addr(kfb, dflow->in_x,
299 						       dflow->in_y, i);
300 
301 	err = komeda_component_validate_private(&layer->base, c_st);
302 	if (err)
303 		return err;
304 
305 	/* update the data flow for the next stage */
306 	komeda_component_set_output(&dflow->input, &layer->base, 0);
307 
308 	return 0;
309 }
310 
311 static void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
312 				      u16 *hsize, u16 *vsize)
313 {
314 	struct drm_display_mode *m = &kcrtc_st->base.adjusted_mode;
315 
316 	if (hsize)
317 		*hsize = m->hdisplay;
318 	if (vsize)
319 		*vsize = m->vdisplay;
320 }
321 
322 static int
323 komeda_compiz_set_input(struct komeda_compiz *compiz,
324 			struct komeda_crtc_state *kcrtc_st,
325 			struct komeda_data_flow_cfg *dflow)
326 {
327 	struct drm_atomic_state *drm_st = kcrtc_st->base.state;
328 	struct komeda_component_state *c_st, *old_st;
329 	struct komeda_compiz_input_cfg *cin;
330 	u16 compiz_w, compiz_h;
331 	int idx = dflow->blending_zorder;
332 
333 	pipeline_composition_size(kcrtc_st, &compiz_w, &compiz_h);
334 	/* check display rect */
335 	if ((dflow->out_x + dflow->out_w > compiz_w) ||
336 	    (dflow->out_y + dflow->out_h > compiz_h) ||
337 	     dflow->out_w == 0 || dflow->out_h == 0) {
338 		DRM_DEBUG_ATOMIC("invalid disp rect [x=%d, y=%d, w=%d, h=%d]\n",
339 				 dflow->out_x, dflow->out_y,
340 				 dflow->out_w, dflow->out_h);
341 		return -EINVAL;
342 	}
343 
344 	c_st = komeda_component_get_state_and_set_user(&compiz->base, drm_st,
345 			kcrtc_st->base.crtc, kcrtc_st->base.crtc);
346 	if (IS_ERR(c_st))
347 		return PTR_ERR(c_st);
348 
349 	if (komeda_component_check_input(c_st, &dflow->input, idx))
350 		return -EINVAL;
351 
352 	cin = &(to_compiz_st(c_st)->cins[idx]);
353 
354 	cin->hsize   = dflow->out_w;
355 	cin->vsize   = dflow->out_h;
356 	cin->hoffset = dflow->out_x;
357 	cin->voffset = dflow->out_y;
358 	cin->pixel_blend_mode = dflow->pixel_blend_mode;
359 	cin->layer_alpha = dflow->layer_alpha;
360 
361 	old_st = komeda_component_get_old_state(&compiz->base, drm_st);
362 	WARN_ON(!old_st);
363 
364 	/* compare with old to check if this input has been changed */
365 	if (memcmp(&(to_compiz_st(old_st)->cins[idx]), cin, sizeof(*cin)))
366 		c_st->changed_active_inputs |= BIT(idx);
367 
368 	komeda_component_add_input(c_st, &dflow->input, idx);
369 
370 	return 0;
371 }
372 
373 static int
374 komeda_compiz_validate(struct komeda_compiz *compiz,
375 		       struct komeda_crtc_state *state,
376 		       struct komeda_data_flow_cfg *dflow)
377 {
378 	struct komeda_component_state *c_st;
379 	struct komeda_compiz_state *st;
380 
381 	c_st = komeda_component_get_state_and_set_user(&compiz->base,
382 			state->base.state, state->base.crtc, state->base.crtc);
383 	if (IS_ERR(c_st))
384 		return PTR_ERR(c_st);
385 
386 	st = to_compiz_st(c_st);
387 
388 	pipeline_composition_size(state, &st->hsize, &st->vsize);
389 
390 	komeda_component_set_output(&dflow->input, &compiz->base, 0);
391 
392 	/* compiz output dflow will be fed to the next pipeline stage, prepare
393 	 * the data flow configuration for the next stage
394 	 */
395 	if (dflow) {
396 		dflow->in_w = st->hsize;
397 		dflow->in_h = st->vsize;
398 		dflow->out_w = dflow->in_w;
399 		dflow->out_h = dflow->in_h;
400 		/* the output data of compiz doesn't have alpha, it only can be
401 		 * used as bottom layer when blend it with master layers
402 		 */
403 		dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE;
404 		dflow->layer_alpha = 0xFF;
405 		dflow->blending_zorder = 0;
406 	}
407 
408 	return 0;
409 }
410 
411 static int
412 komeda_improc_validate(struct komeda_improc *improc,
413 		       struct komeda_crtc_state *kcrtc_st,
414 		       struct komeda_data_flow_cfg *dflow)
415 {
416 	struct drm_crtc *crtc = kcrtc_st->base.crtc;
417 	struct komeda_component_state *c_st;
418 	struct komeda_improc_state *st;
419 
420 	c_st = komeda_component_get_state_and_set_user(&improc->base,
421 			kcrtc_st->base.state, crtc, crtc);
422 	if (IS_ERR(c_st))
423 		return PTR_ERR(c_st);
424 
425 	st = to_improc_st(c_st);
426 
427 	st->hsize = dflow->in_w;
428 	st->vsize = dflow->in_h;
429 
430 	komeda_component_add_input(&st->base, &dflow->input, 0);
431 	komeda_component_set_output(&dflow->input, &improc->base, 0);
432 
433 	return 0;
434 }
435 
436 static int
437 komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr *ctrlr,
438 			     struct komeda_crtc_state *kcrtc_st,
439 			     struct komeda_data_flow_cfg *dflow)
440 {
441 	struct drm_crtc *crtc = kcrtc_st->base.crtc;
442 	struct komeda_timing_ctrlr_state *st;
443 	struct komeda_component_state *c_st;
444 
445 	c_st = komeda_component_get_state_and_set_user(&ctrlr->base,
446 			kcrtc_st->base.state, crtc, crtc);
447 	if (IS_ERR(c_st))
448 		return PTR_ERR(c_st);
449 
450 	st = to_ctrlr_st(c_st);
451 
452 	komeda_component_add_input(&st->base, &dflow->input, 0);
453 	komeda_component_set_output(&dflow->input, &ctrlr->base, 0);
454 
455 	return 0;
456 }
457 
458 int komeda_build_layer_data_flow(struct komeda_layer *layer,
459 				 struct komeda_plane_state *kplane_st,
460 				 struct komeda_crtc_state *kcrtc_st,
461 				 struct komeda_data_flow_cfg *dflow)
462 {
463 	struct drm_plane *plane = kplane_st->base.plane;
464 	struct komeda_pipeline *pipe = layer->base.pipeline;
465 	int err;
466 
467 	DRM_DEBUG_ATOMIC("%s handling [PLANE:%d:%s]: src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]",
468 			 layer->base.name, plane->base.id, plane->name,
469 			 dflow->in_x, dflow->in_y, dflow->in_w, dflow->in_h,
470 			 dflow->out_x, dflow->out_y, dflow->out_w, dflow->out_h);
471 
472 	err = komeda_layer_validate(layer, kplane_st, dflow);
473 	if (err)
474 		return err;
475 
476 	err = komeda_compiz_set_input(pipe->compiz, kcrtc_st, dflow);
477 
478 	return err;
479 }
480 
481 /* build display output data flow, the data path is:
482  * compiz -> improc -> timing_ctrlr
483  */
484 int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
485 				   struct komeda_crtc_state *kcrtc_st)
486 {
487 	struct komeda_pipeline *master = kcrtc->master;
488 	struct komeda_data_flow_cfg m_dflow; /* master data flow */
489 	int err;
490 
491 	memset(&m_dflow, 0, sizeof(m_dflow));
492 
493 	err = komeda_compiz_validate(master->compiz, kcrtc_st, &m_dflow);
494 	if (err)
495 		return err;
496 
497 	err = komeda_improc_validate(master->improc, kcrtc_st, &m_dflow);
498 	if (err)
499 		return err;
500 
501 	err = komeda_timing_ctrlr_validate(master->ctrlr, kcrtc_st, &m_dflow);
502 	if (err)
503 		return err;
504 
505 	return 0;
506 }
507 
508 static void
509 komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
510 				   struct komeda_pipeline_state *new)
511 {
512 	struct drm_atomic_state *drm_st = new->obj.state;
513 	struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state);
514 	struct komeda_component_state *c_st;
515 	struct komeda_component *c;
516 	u32 disabling_comps, id;
517 
518 	WARN_ON(!old);
519 
520 	disabling_comps = (~new->active_comps) & old->active_comps;
521 
522 	/* unbound all disabling component */
523 	dp_for_each_set_bit(id, disabling_comps) {
524 		c = komeda_pipeline_get_component(pipe, id);
525 		c_st = komeda_component_get_state_and_set_user(c,
526 				drm_st, NULL, new->crtc);
527 		WARN_ON(IS_ERR(c_st));
528 	}
529 }
530 
531 /* release unclaimed pipeline resource */
532 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
533 				       struct komeda_crtc_state *kcrtc_st)
534 {
535 	struct drm_atomic_state *drm_st = kcrtc_st->base.state;
536 	struct komeda_pipeline_state *st;
537 
538 	/* ignore the pipeline which is not affected */
539 	if (!pipe || !has_bit(pipe->id, kcrtc_st->affected_pipes))
540 		return 0;
541 
542 	if (has_bit(pipe->id, kcrtc_st->active_pipes))
543 		st = komeda_pipeline_get_new_state(pipe, drm_st);
544 	else
545 		st = komeda_pipeline_get_state_and_set_crtc(pipe, drm_st, NULL);
546 
547 	if (WARN_ON(IS_ERR_OR_NULL(st)))
548 		return -EINVAL;
549 
550 	komeda_pipeline_unbound_components(pipe, st);
551 
552 	return 0;
553 }
554 
555 void komeda_pipeline_disable(struct komeda_pipeline *pipe,
556 			     struct drm_atomic_state *old_state)
557 {
558 	struct komeda_pipeline_state *old;
559 	struct komeda_component *c;
560 	struct komeda_component_state *c_st;
561 	u32 id, disabling_comps = 0;
562 
563 	old = komeda_pipeline_get_old_state(pipe, old_state);
564 
565 	disabling_comps = old->active_comps;
566 	DRM_DEBUG_ATOMIC("PIPE%d: disabling_comps: 0x%x.\n",
567 			 pipe->id, disabling_comps);
568 
569 	dp_for_each_set_bit(id, disabling_comps) {
570 		c = komeda_pipeline_get_component(pipe, id);
571 		c_st = priv_to_comp_st(c->obj.state);
572 
573 		/*
574 		 * If we disabled a component then all active_inputs should be
575 		 * put in the list of changed_active_inputs, so they get
576 		 * re-enabled.
577 		 * This usually happens during a modeset when the pipeline is
578 		 * first disabled and then the actual state gets committed
579 		 * again.
580 		 */
581 		c_st->changed_active_inputs |= c_st->active_inputs;
582 
583 		c->funcs->disable(c);
584 	}
585 }
586 
587 void komeda_pipeline_update(struct komeda_pipeline *pipe,
588 			    struct drm_atomic_state *old_state)
589 {
590 	struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state);
591 	struct komeda_pipeline_state *old;
592 	struct komeda_component *c;
593 	u32 id, changed_comps = 0;
594 
595 	old = komeda_pipeline_get_old_state(pipe, old_state);
596 
597 	changed_comps = new->active_comps | old->active_comps;
598 
599 	DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n",
600 			 pipe->id, new->active_comps, changed_comps);
601 
602 	dp_for_each_set_bit(id, changed_comps) {
603 		c = komeda_pipeline_get_component(pipe, id);
604 
605 		if (new->active_comps & BIT(c->id))
606 			c->funcs->update(c, priv_to_comp_st(c->obj.state));
607 		else
608 			c->funcs->disable(c);
609 	}
610 }
611