• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <linux/clk.h>
8 #include <linux/pm_runtime.h>
9 #include <linux/spinlock.h>
10 
11 #include <drm/drm_atomic.h>
12 #include <drm/drm_atomic_helper.h>
13 #include <drm/drm_crtc_helper.h>
14 #include <drm/drm_plane_helper.h>
15 #include <drm/drm_print.h>
16 #include <drm/drm_vblank.h>
17 
18 #include "komeda_dev.h"
19 #include "komeda_kms.h"
20 
komeda_crtc_get_color_config(struct drm_crtc_state * crtc_st,u32 * color_depths,u32 * color_formats)21 void komeda_crtc_get_color_config(struct drm_crtc_state *crtc_st,
22 				  u32 *color_depths, u32 *color_formats)
23 {
24 	struct drm_connector *conn;
25 	struct drm_connector_state *conn_st;
26 	u32 conn_color_formats = ~0u;
27 	int i, min_bpc = 31, conn_bpc = 0;
28 
29 	for_each_new_connector_in_state(crtc_st->state, conn, conn_st, i) {
30 		if (conn_st->crtc != crtc_st->crtc)
31 			continue;
32 
33 		conn_bpc = conn->display_info.bpc ? conn->display_info.bpc : 8;
34 		conn_color_formats &= conn->display_info.color_formats;
35 
36 		if (conn_bpc < min_bpc)
37 			min_bpc = conn_bpc;
38 	}
39 
40 	/* connector doesn't config any color_format, use RGB444 as default */
41 	if (!conn_color_formats)
42 		conn_color_formats = DRM_COLOR_FORMAT_RGB444;
43 
44 	*color_depths = GENMASK(min_bpc, 0);
45 	*color_formats = conn_color_formats;
46 }
47 
komeda_crtc_update_clock_ratio(struct komeda_crtc_state * kcrtc_st)48 static void komeda_crtc_update_clock_ratio(struct komeda_crtc_state *kcrtc_st)
49 {
50 	u64 pxlclk, aclk;
51 
52 	if (!kcrtc_st->base.active) {
53 		kcrtc_st->clock_ratio = 0;
54 		return;
55 	}
56 
57 	pxlclk = kcrtc_st->base.adjusted_mode.crtc_clock * 1000ULL;
58 	aclk = komeda_crtc_get_aclk(kcrtc_st);
59 
60 	kcrtc_st->clock_ratio = div64_u64(aclk << 32, pxlclk);
61 }
62 
63 /**
64  * komeda_crtc_atomic_check - build display output data flow
65  * @crtc: DRM crtc
66  * @state: the crtc state object
67  *
68  * crtc_atomic_check is the final check stage, so beside build a display data
69  * pipeline according to the crtc_state, but still needs to release or disable
70  * the unclaimed pipeline resources.
71  *
72  * RETURNS:
73  * Zero for success or -errno
74  */
75 static int
komeda_crtc_atomic_check(struct drm_crtc * crtc,struct drm_crtc_state * state)76 komeda_crtc_atomic_check(struct drm_crtc *crtc,
77 			 struct drm_crtc_state *state)
78 {
79 	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
80 	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state);
81 	int err;
82 
83 	if (drm_atomic_crtc_needs_modeset(state))
84 		komeda_crtc_update_clock_ratio(kcrtc_st);
85 
86 	if (state->active) {
87 		err = komeda_build_display_data_flow(kcrtc, kcrtc_st);
88 		if (err)
89 			return err;
90 	}
91 
92 	/* release unclaimed pipeline resources */
93 	err = komeda_release_unclaimed_resources(kcrtc->slave, kcrtc_st);
94 	if (err)
95 		return err;
96 
97 	err = komeda_release_unclaimed_resources(kcrtc->master, kcrtc_st);
98 	if (err)
99 		return err;
100 
101 	return 0;
102 }
103 
104 /* For active a crtc, mainly need two parts of preparation
105  * 1. adjust display operation mode.
106  * 2. enable needed clk
107  */
108 static int
komeda_crtc_prepare(struct komeda_crtc * kcrtc)109 komeda_crtc_prepare(struct komeda_crtc *kcrtc)
110 {
111 	struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
112 	struct komeda_pipeline *master = kcrtc->master;
113 	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(kcrtc->base.state);
114 	struct drm_display_mode *mode = &kcrtc_st->base.adjusted_mode;
115 	u32 new_mode;
116 	int err;
117 
118 	mutex_lock(&mdev->lock);
119 
120 	new_mode = mdev->dpmode | BIT(master->id);
121 	if (WARN_ON(new_mode == mdev->dpmode)) {
122 		err = 0;
123 		goto unlock;
124 	}
125 
126 	err = mdev->funcs->change_opmode(mdev, new_mode);
127 	if (err) {
128 		DRM_ERROR("failed to change opmode: 0x%x -> 0x%x.\n,",
129 			  mdev->dpmode, new_mode);
130 		goto unlock;
131 	}
132 
133 	mdev->dpmode = new_mode;
134 	/* Only need to enable aclk on single display mode, but no need to
135 	 * enable aclk it on dual display mode, since the dual mode always
136 	 * switch from single display mode, the aclk already enabled, no need
137 	 * to enable it again.
138 	 */
139 	if (new_mode != KOMEDA_MODE_DUAL_DISP) {
140 		err = clk_set_rate(mdev->aclk, komeda_crtc_get_aclk(kcrtc_st));
141 		if (err)
142 			DRM_ERROR("failed to set aclk.\n");
143 		err = clk_prepare_enable(mdev->aclk);
144 		if (err)
145 			DRM_ERROR("failed to enable aclk.\n");
146 	}
147 
148 	err = clk_set_rate(master->pxlclk, mode->crtc_clock * 1000);
149 	if (err)
150 		DRM_ERROR("failed to set pxlclk for pipe%d\n", master->id);
151 	err = clk_prepare_enable(master->pxlclk);
152 	if (err)
153 		DRM_ERROR("failed to enable pxl clk for pipe%d.\n", master->id);
154 
155 unlock:
156 	mutex_unlock(&mdev->lock);
157 
158 	return err;
159 }
160 
161 static int
komeda_crtc_unprepare(struct komeda_crtc * kcrtc)162 komeda_crtc_unprepare(struct komeda_crtc *kcrtc)
163 {
164 	struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
165 	struct komeda_pipeline *master = kcrtc->master;
166 	u32 new_mode;
167 	int err;
168 
169 	mutex_lock(&mdev->lock);
170 
171 	new_mode = mdev->dpmode & (~BIT(master->id));
172 
173 	if (WARN_ON(new_mode == mdev->dpmode)) {
174 		err = 0;
175 		goto unlock;
176 	}
177 
178 	err = mdev->funcs->change_opmode(mdev, new_mode);
179 	if (err) {
180 		DRM_ERROR("failed to change opmode: 0x%x -> 0x%x.\n,",
181 			  mdev->dpmode, new_mode);
182 		goto unlock;
183 	}
184 
185 	mdev->dpmode = new_mode;
186 
187 	clk_disable_unprepare(master->pxlclk);
188 	if (new_mode == KOMEDA_MODE_INACTIVE)
189 		clk_disable_unprepare(mdev->aclk);
190 
191 unlock:
192 	mutex_unlock(&mdev->lock);
193 
194 	return err;
195 }
196 
komeda_crtc_handle_event(struct komeda_crtc * kcrtc,struct komeda_events * evts)197 void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
198 			      struct komeda_events *evts)
199 {
200 	struct drm_crtc *crtc = &kcrtc->base;
201 	u32 events = evts->pipes[kcrtc->master->id];
202 
203 	if (events & KOMEDA_EVENT_VSYNC)
204 		drm_crtc_handle_vblank(crtc);
205 
206 	if (events & KOMEDA_EVENT_EOW) {
207 		struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
208 
209 		if (wb_conn)
210 			drm_writeback_signal_completion(&wb_conn->base, 0);
211 		else
212 			DRM_WARN("CRTC[%d]: EOW happen but no wb_connector.\n",
213 				 drm_crtc_index(&kcrtc->base));
214 	}
215 	/* will handle it together with the write back support */
216 	if (events & KOMEDA_EVENT_EOW)
217 		DRM_DEBUG("EOW.\n");
218 
219 	if (events & KOMEDA_EVENT_FLIP) {
220 		unsigned long flags;
221 		struct drm_pending_vblank_event *event;
222 
223 		spin_lock_irqsave(&crtc->dev->event_lock, flags);
224 		if (kcrtc->disable_done) {
225 			complete_all(kcrtc->disable_done);
226 			kcrtc->disable_done = NULL;
227 		} else if (crtc->state->event) {
228 			event = crtc->state->event;
229 			/*
230 			 * Consume event before notifying drm core that flip
231 			 * happened.
232 			 */
233 			crtc->state->event = NULL;
234 			drm_crtc_send_vblank_event(crtc, event);
235 		} else {
236 			DRM_WARN("CRTC[%d]: FLIP happen but no pending commit.\n",
237 				 drm_crtc_index(&kcrtc->base));
238 		}
239 		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
240 	}
241 }
242 
243 static void
komeda_crtc_do_flush(struct drm_crtc * crtc,struct drm_crtc_state * old)244 komeda_crtc_do_flush(struct drm_crtc *crtc,
245 		     struct drm_crtc_state *old)
246 {
247 	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
248 	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc->state);
249 	struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
250 	struct komeda_pipeline *master = kcrtc->master;
251 	struct komeda_pipeline *slave = kcrtc->slave;
252 	struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
253 	struct drm_connector_state *conn_st;
254 
255 	DRM_DEBUG_ATOMIC("CRTC%d_FLUSH: active_pipes: 0x%x, affected: 0x%x.\n",
256 			 drm_crtc_index(crtc),
257 			 kcrtc_st->active_pipes, kcrtc_st->affected_pipes);
258 
259 	/* step 1: update the pipeline/component state to HW */
260 	if (has_bit(master->id, kcrtc_st->affected_pipes))
261 		komeda_pipeline_update(master, old->state);
262 
263 	if (slave && has_bit(slave->id, kcrtc_st->affected_pipes))
264 		komeda_pipeline_update(slave, old->state);
265 
266 	conn_st = wb_conn ? wb_conn->base.base.state : NULL;
267 	if (conn_st && conn_st->writeback_job)
268 		drm_writeback_queue_job(&wb_conn->base, conn_st);
269 
270 	/* step 2: notify the HW to kickoff the update */
271 	mdev->funcs->flush(mdev, master->id, kcrtc_st->active_pipes);
272 }
273 
274 static void
komeda_crtc_atomic_enable(struct drm_crtc * crtc,struct drm_crtc_state * old)275 komeda_crtc_atomic_enable(struct drm_crtc *crtc,
276 			  struct drm_crtc_state *old)
277 {
278 	pm_runtime_get_sync(crtc->dev->dev);
279 	komeda_crtc_prepare(to_kcrtc(crtc));
280 	drm_crtc_vblank_on(crtc);
281 	WARN_ON(drm_crtc_vblank_get(crtc));
282 	komeda_crtc_do_flush(crtc, old);
283 }
284 
285 static void
komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc * kcrtc,struct completion * input_flip_done)286 komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
287 					 struct completion *input_flip_done)
288 {
289 	struct drm_device *drm = kcrtc->base.dev;
290 	struct komeda_dev *mdev = kcrtc->master->mdev;
291 	struct completion *flip_done;
292 	struct completion temp;
293 	int timeout;
294 
295 	/* if caller doesn't send a flip_done, use a private flip_done */
296 	if (input_flip_done) {
297 		flip_done = input_flip_done;
298 	} else {
299 		init_completion(&temp);
300 		kcrtc->disable_done = &temp;
301 		flip_done = &temp;
302 	}
303 
304 	mdev->funcs->flush(mdev, kcrtc->master->id, 0);
305 
306 	/* wait the flip take affect.*/
307 	timeout = wait_for_completion_timeout(flip_done, HZ);
308 	if (timeout == 0) {
309 		DRM_ERROR("wait pipe%d flip done timeout\n", kcrtc->master->id);
310 		if (!input_flip_done) {
311 			unsigned long flags;
312 
313 			spin_lock_irqsave(&drm->event_lock, flags);
314 			kcrtc->disable_done = NULL;
315 			spin_unlock_irqrestore(&drm->event_lock, flags);
316 		}
317 	}
318 }
319 
320 static void
komeda_crtc_atomic_disable(struct drm_crtc * crtc,struct drm_crtc_state * old)321 komeda_crtc_atomic_disable(struct drm_crtc *crtc,
322 			   struct drm_crtc_state *old)
323 {
324 	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
325 	struct komeda_crtc_state *old_st = to_kcrtc_st(old);
326 	struct komeda_pipeline *master = kcrtc->master;
327 	struct komeda_pipeline *slave  = kcrtc->slave;
328 	struct completion *disable_done;
329 	bool needs_phase2 = false;
330 
331 	DRM_DEBUG_ATOMIC("CRTC%d_DISABLE: active_pipes: 0x%x, affected: 0x%x\n",
332 			 drm_crtc_index(crtc),
333 			 old_st->active_pipes, old_st->affected_pipes);
334 
335 	if (slave && has_bit(slave->id, old_st->active_pipes))
336 		komeda_pipeline_disable(slave, old->state);
337 
338 	if (has_bit(master->id, old_st->active_pipes))
339 		needs_phase2 = komeda_pipeline_disable(master, old->state);
340 
341 	/* crtc_disable has two scenarios according to the state->active switch.
342 	 * 1. active -> inactive
343 	 *    this commit is a disable commit. and the commit will be finished
344 	 *    or done after the disable operation. on this case we can directly
345 	 *    use the crtc->state->event to tracking the HW disable operation.
346 	 * 2. active -> active
347 	 *    the crtc->commit is not for disable, but a modeset operation when
348 	 *    crtc is active, such commit actually has been completed by 3
349 	 *    DRM operations:
350 	 *    crtc_disable, update_planes(crtc_flush), crtc_enable
351 	 *    so on this case the crtc->commit is for the whole process.
352 	 *    we can not use it for tracing the disable, we need a temporary
353 	 *    flip_done for tracing the disable. and crtc->state->event for
354 	 *    the crtc_enable operation.
355 	 *    That's also the reason why skip modeset commit in
356 	 *    komeda_crtc_atomic_flush()
357 	 */
358 	disable_done = (needs_phase2 || crtc->state->active) ?
359 		       NULL : &crtc->state->commit->flip_done;
360 
361 	/* wait phase 1 disable done */
362 	komeda_crtc_flush_and_wait_for_flip_done(kcrtc, disable_done);
363 
364 	/* phase 2 */
365 	if (needs_phase2) {
366 		komeda_pipeline_disable(kcrtc->master, old->state);
367 
368 		disable_done = crtc->state->active ?
369 			       NULL : &crtc->state->commit->flip_done;
370 
371 		komeda_crtc_flush_and_wait_for_flip_done(kcrtc, disable_done);
372 	}
373 
374 	drm_crtc_vblank_put(crtc);
375 	drm_crtc_vblank_off(crtc);
376 	komeda_crtc_unprepare(kcrtc);
377 	pm_runtime_put(crtc->dev->dev);
378 }
379 
380 static void
komeda_crtc_atomic_flush(struct drm_crtc * crtc,struct drm_crtc_state * old)381 komeda_crtc_atomic_flush(struct drm_crtc *crtc,
382 			 struct drm_crtc_state *old)
383 {
384 	/* commit with modeset will be handled in enable/disable */
385 	if (drm_atomic_crtc_needs_modeset(crtc->state))
386 		return;
387 
388 	komeda_crtc_do_flush(crtc, old);
389 }
390 
391 /* Returns the minimum frequency of the aclk rate (main engine clock) in Hz */
392 static unsigned long
komeda_calc_min_aclk_rate(struct komeda_crtc * kcrtc,unsigned long pxlclk)393 komeda_calc_min_aclk_rate(struct komeda_crtc *kcrtc,
394 			  unsigned long pxlclk)
395 {
396 	/* Once dual-link one display pipeline drives two display outputs,
397 	 * the aclk needs run on the double rate of pxlclk
398 	 */
399 	if (kcrtc->master->dual_link)
400 		return pxlclk * 2;
401 	else
402 		return pxlclk;
403 }
404 
405 /* Get current aclk rate that specified by state */
komeda_crtc_get_aclk(struct komeda_crtc_state * kcrtc_st)406 unsigned long komeda_crtc_get_aclk(struct komeda_crtc_state *kcrtc_st)
407 {
408 	struct drm_crtc *crtc = kcrtc_st->base.crtc;
409 	struct komeda_dev *mdev = crtc->dev->dev_private;
410 	unsigned long pxlclk = kcrtc_st->base.adjusted_mode.crtc_clock * 1000;
411 	unsigned long min_aclk;
412 
413 	min_aclk = komeda_calc_min_aclk_rate(to_kcrtc(crtc), pxlclk);
414 
415 	return clk_round_rate(mdev->aclk, min_aclk);
416 }
417 
418 static enum drm_mode_status
komeda_crtc_mode_valid(struct drm_crtc * crtc,const struct drm_display_mode * m)419 komeda_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *m)
420 {
421 	struct komeda_dev *mdev = crtc->dev->dev_private;
422 	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
423 	struct komeda_pipeline *master = kcrtc->master;
424 	unsigned long min_pxlclk, min_aclk;
425 
426 	if (m->flags & DRM_MODE_FLAG_INTERLACE)
427 		return MODE_NO_INTERLACE;
428 
429 	min_pxlclk = m->clock * 1000;
430 	if (master->dual_link)
431 		min_pxlclk /= 2;
432 
433 	if (min_pxlclk != clk_round_rate(master->pxlclk, min_pxlclk)) {
434 		DRM_DEBUG_ATOMIC("pxlclk doesn't support %lu Hz\n", min_pxlclk);
435 
436 		return MODE_NOCLOCK;
437 	}
438 
439 	min_aclk = komeda_calc_min_aclk_rate(to_kcrtc(crtc), min_pxlclk);
440 	if (clk_round_rate(mdev->aclk, min_aclk) < min_aclk) {
441 		DRM_DEBUG_ATOMIC("engine clk can't satisfy the requirement of %s-clk: %lu.\n",
442 				 m->name, min_pxlclk);
443 
444 		return MODE_CLOCK_HIGH;
445 	}
446 
447 	return MODE_OK;
448 }
449 
komeda_crtc_mode_fixup(struct drm_crtc * crtc,const struct drm_display_mode * m,struct drm_display_mode * adjusted_mode)450 static bool komeda_crtc_mode_fixup(struct drm_crtc *crtc,
451 				   const struct drm_display_mode *m,
452 				   struct drm_display_mode *adjusted_mode)
453 {
454 	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
455 	unsigned long clk_rate;
456 
457 	drm_mode_set_crtcinfo(adjusted_mode, 0);
458 	/* In dual link half the horizontal settings */
459 	if (kcrtc->master->dual_link) {
460 		adjusted_mode->crtc_clock /= 2;
461 		adjusted_mode->crtc_hdisplay /= 2;
462 		adjusted_mode->crtc_hsync_start /= 2;
463 		adjusted_mode->crtc_hsync_end /= 2;
464 		adjusted_mode->crtc_htotal /= 2;
465 	}
466 
467 	clk_rate = adjusted_mode->crtc_clock * 1000;
468 	/* crtc_clock will be used as the komeda output pixel clock */
469 	adjusted_mode->crtc_clock = clk_round_rate(kcrtc->master->pxlclk,
470 						   clk_rate) / 1000;
471 
472 	return true;
473 }
474 
475 static const struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = {
476 	.atomic_check	= komeda_crtc_atomic_check,
477 	.atomic_flush	= komeda_crtc_atomic_flush,
478 	.atomic_enable	= komeda_crtc_atomic_enable,
479 	.atomic_disable	= komeda_crtc_atomic_disable,
480 	.mode_valid	= komeda_crtc_mode_valid,
481 	.mode_fixup	= komeda_crtc_mode_fixup,
482 };
483 
komeda_crtc_reset(struct drm_crtc * crtc)484 static void komeda_crtc_reset(struct drm_crtc *crtc)
485 {
486 	struct komeda_crtc_state *state;
487 
488 	if (crtc->state)
489 		__drm_atomic_helper_crtc_destroy_state(crtc->state);
490 
491 	kfree(to_kcrtc_st(crtc->state));
492 	crtc->state = NULL;
493 
494 	state = kzalloc(sizeof(*state), GFP_KERNEL);
495 	if (state)
496 		__drm_atomic_helper_crtc_reset(crtc, &state->base);
497 }
498 
499 static struct drm_crtc_state *
komeda_crtc_atomic_duplicate_state(struct drm_crtc * crtc)500 komeda_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
501 {
502 	struct komeda_crtc_state *old = to_kcrtc_st(crtc->state);
503 	struct komeda_crtc_state *new;
504 
505 	new = kzalloc(sizeof(*new), GFP_KERNEL);
506 	if (!new)
507 		return NULL;
508 
509 	__drm_atomic_helper_crtc_duplicate_state(crtc, &new->base);
510 
511 	new->affected_pipes = old->active_pipes;
512 	new->clock_ratio = old->clock_ratio;
513 	new->max_slave_zorder = old->max_slave_zorder;
514 
515 	return &new->base;
516 }
517 
komeda_crtc_atomic_destroy_state(struct drm_crtc * crtc,struct drm_crtc_state * state)518 static void komeda_crtc_atomic_destroy_state(struct drm_crtc *crtc,
519 					     struct drm_crtc_state *state)
520 {
521 	__drm_atomic_helper_crtc_destroy_state(state);
522 	kfree(to_kcrtc_st(state));
523 }
524 
komeda_crtc_vblank_enable(struct drm_crtc * crtc)525 static int komeda_crtc_vblank_enable(struct drm_crtc *crtc)
526 {
527 	struct komeda_dev *mdev = crtc->dev->dev_private;
528 	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
529 
530 	mdev->funcs->on_off_vblank(mdev, kcrtc->master->id, true);
531 	return 0;
532 }
533 
komeda_crtc_vblank_disable(struct drm_crtc * crtc)534 static void komeda_crtc_vblank_disable(struct drm_crtc *crtc)
535 {
536 	struct komeda_dev *mdev = crtc->dev->dev_private;
537 	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
538 
539 	mdev->funcs->on_off_vblank(mdev, kcrtc->master->id, false);
540 }
541 
542 static const struct drm_crtc_funcs komeda_crtc_funcs = {
543 	.gamma_set		= drm_atomic_helper_legacy_gamma_set,
544 	.destroy		= drm_crtc_cleanup,
545 	.set_config		= drm_atomic_helper_set_config,
546 	.page_flip		= drm_atomic_helper_page_flip,
547 	.reset			= komeda_crtc_reset,
548 	.atomic_duplicate_state	= komeda_crtc_atomic_duplicate_state,
549 	.atomic_destroy_state	= komeda_crtc_atomic_destroy_state,
550 	.enable_vblank		= komeda_crtc_vblank_enable,
551 	.disable_vblank		= komeda_crtc_vblank_disable,
552 };
553 
komeda_kms_setup_crtcs(struct komeda_kms_dev * kms,struct komeda_dev * mdev)554 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
555 			   struct komeda_dev *mdev)
556 {
557 	struct komeda_crtc *crtc;
558 	struct komeda_pipeline *master;
559 	char str[16];
560 	int i;
561 
562 	kms->n_crtcs = 0;
563 
564 	for (i = 0; i < mdev->n_pipelines; i++) {
565 		crtc = &kms->crtcs[kms->n_crtcs];
566 		master = mdev->pipelines[i];
567 
568 		crtc->master = master;
569 		crtc->slave  = komeda_pipeline_get_slave(master);
570 
571 		if (crtc->slave)
572 			sprintf(str, "pipe-%d", crtc->slave->id);
573 		else
574 			sprintf(str, "None");
575 
576 		DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s).\n",
577 			 kms->n_crtcs, master->id, str);
578 
579 		kms->n_crtcs++;
580 	}
581 
582 	return 0;
583 }
584 
585 static struct drm_plane *
get_crtc_primary(struct komeda_kms_dev * kms,struct komeda_crtc * crtc)586 get_crtc_primary(struct komeda_kms_dev *kms, struct komeda_crtc *crtc)
587 {
588 	struct komeda_plane *kplane;
589 	struct drm_plane *plane;
590 
591 	drm_for_each_plane(plane, &kms->base) {
592 		if (plane->type != DRM_PLANE_TYPE_PRIMARY)
593 			continue;
594 
595 		kplane = to_kplane(plane);
596 		/* only master can be primary */
597 		if (kplane->layer->base.pipeline == crtc->master)
598 			return plane;
599 	}
600 
601 	return NULL;
602 }
603 
komeda_crtc_add(struct komeda_kms_dev * kms,struct komeda_crtc * kcrtc)604 static int komeda_crtc_add(struct komeda_kms_dev *kms,
605 			   struct komeda_crtc *kcrtc)
606 {
607 	struct drm_crtc *crtc = &kcrtc->base;
608 	int err;
609 
610 	err = drm_crtc_init_with_planes(&kms->base, crtc,
611 					get_crtc_primary(kms, kcrtc), NULL,
612 					&komeda_crtc_funcs, NULL);
613 	if (err)
614 		return err;
615 
616 	drm_crtc_helper_add(crtc, &komeda_crtc_helper_funcs);
617 
618 	crtc->port = kcrtc->master->of_output_port;
619 
620 	drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
621 
622 	return err;
623 }
624 
komeda_kms_add_crtcs(struct komeda_kms_dev * kms,struct komeda_dev * mdev)625 int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev)
626 {
627 	int i, err;
628 
629 	for (i = 0; i < kms->n_crtcs; i++) {
630 		err = komeda_crtc_add(kms, &kms->crtcs[i]);
631 		if (err)
632 			return err;
633 	}
634 
635 	return 0;
636 }
637