Linux Audio

Check our new training course

Loading...
v5.4
  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_print.h>
  8
  9#include "komeda_dev.h"
 10#include "komeda_pipeline.h"
 11
 12/** komeda_pipeline_add - Add a pipeline to &komeda_dev */
 13struct komeda_pipeline *
 14komeda_pipeline_add(struct komeda_dev *mdev, size_t size,
 15		    const struct komeda_pipeline_funcs *funcs)
 16{
 17	struct komeda_pipeline *pipe;
 18
 19	if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) {
 20		DRM_ERROR("Exceed max support %d pipelines.\n",
 21			  KOMEDA_MAX_PIPELINES);
 22		return ERR_PTR(-ENOSPC);
 23	}
 24
 25	if (size < sizeof(*pipe)) {
 26		DRM_ERROR("Request pipeline size too small.\n");
 27		return ERR_PTR(-EINVAL);
 28	}
 29
 30	pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
 31	if (!pipe)
 32		return ERR_PTR(-ENOMEM);
 33
 34	pipe->mdev = mdev;
 35	pipe->id   = mdev->n_pipelines;
 36	pipe->funcs = funcs;
 37
 38	mdev->pipelines[mdev->n_pipelines] = pipe;
 39	mdev->n_pipelines++;
 40
 41	return pipe;
 42}
 43
 44void komeda_pipeline_destroy(struct komeda_dev *mdev,
 45			     struct komeda_pipeline *pipe)
 46{
 47	struct komeda_component *c;
 48	int i;
 
 49
 50	dp_for_each_set_bit(i, pipe->avail_comps) {
 51		c = komeda_pipeline_get_component(pipe, i);
 52		komeda_component_destroy(mdev, c);
 53	}
 54
 55	clk_put(pipe->pxlclk);
 56
 57	of_node_put(pipe->of_output_links[0]);
 58	of_node_put(pipe->of_output_links[1]);
 59	of_node_put(pipe->of_output_port);
 60	of_node_put(pipe->of_node);
 61
 62	devm_kfree(mdev->dev, pipe);
 63}
 64
 65static struct komeda_component **
 66komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id)
 67{
 68	struct komeda_dev *mdev = pipe->mdev;
 69	struct komeda_pipeline *temp = NULL;
 70	struct komeda_component **pos = NULL;
 71
 72	switch (id) {
 73	case KOMEDA_COMPONENT_LAYER0:
 74	case KOMEDA_COMPONENT_LAYER1:
 75	case KOMEDA_COMPONENT_LAYER2:
 76	case KOMEDA_COMPONENT_LAYER3:
 77		pos = to_cpos(pipe->layers[id - KOMEDA_COMPONENT_LAYER0]);
 78		break;
 79	case KOMEDA_COMPONENT_WB_LAYER:
 80		pos = to_cpos(pipe->wb_layer);
 81		break;
 82	case KOMEDA_COMPONENT_COMPIZ0:
 83	case KOMEDA_COMPONENT_COMPIZ1:
 84		temp = mdev->pipelines[id - KOMEDA_COMPONENT_COMPIZ0];
 85		if (!temp) {
 86			DRM_ERROR("compiz-%d doesn't exist.\n", id);
 87			return NULL;
 88		}
 89		pos = to_cpos(temp->compiz);
 90		break;
 91	case KOMEDA_COMPONENT_SCALER0:
 92	case KOMEDA_COMPONENT_SCALER1:
 93		pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]);
 94		break;
 95	case KOMEDA_COMPONENT_SPLITTER:
 96		pos = to_cpos(pipe->splitter);
 97		break;
 98	case KOMEDA_COMPONENT_MERGER:
 99		pos = to_cpos(pipe->merger);
100		break;
101	case KOMEDA_COMPONENT_IPS0:
102	case KOMEDA_COMPONENT_IPS1:
103		temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0];
104		if (!temp) {
105			DRM_ERROR("ips-%d doesn't exist.\n", id);
106			return NULL;
107		}
108		pos = to_cpos(temp->improc);
109		break;
110	case KOMEDA_COMPONENT_TIMING_CTRLR:
111		pos = to_cpos(pipe->ctrlr);
112		break;
113	default:
114		pos = NULL;
115		DRM_ERROR("Unknown pipeline resource ID: %d.\n", id);
116		break;
117	}
118
119	return pos;
120}
121
122struct komeda_component *
123komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
124{
125	struct komeda_component **pos = NULL;
126	struct komeda_component *c = NULL;
127
128	pos = komeda_pipeline_get_component_pos(pipe, id);
129	if (pos)
130		c = *pos;
131
132	return c;
133}
134
135struct komeda_component *
136komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
137				    u32 comp_mask)
138{
139	struct komeda_component *c = NULL;
 
140	int id;
141
142	id = find_first_bit((unsigned long *)&comp_mask, 32);
143	if (id < 32)
144		c = komeda_pipeline_get_component(pipe, id);
145
146	return c;
147}
148
149static struct komeda_component *
150komeda_component_pickup_input(struct komeda_component *c, u32 avail_comps)
151{
152	u32 avail_inputs = c->supported_inputs & (avail_comps);
153
154	return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
155}
156
157/** komeda_component_add - Add a component to &komeda_pipeline */
158struct komeda_component *
159komeda_component_add(struct komeda_pipeline *pipe,
160		     size_t comp_sz, u32 id, u32 hw_id,
161		     const struct komeda_component_funcs *funcs,
162		     u8 max_active_inputs, u32 supported_inputs,
163		     u8 max_active_outputs, u32 __iomem *reg,
164		     const char *name_fmt, ...)
165{
166	struct komeda_component **pos;
167	struct komeda_component *c;
168	int idx, *num = NULL;
169
170	if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) {
171		WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n",
172		     max_active_inputs);
173		return ERR_PTR(-ENOSPC);
174	}
175
176	pos = komeda_pipeline_get_component_pos(pipe, id);
177	if (!pos || (*pos))
178		return ERR_PTR(-EINVAL);
179
180	if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) {
181		idx = id - KOMEDA_COMPONENT_LAYER0;
182		num = &pipe->n_layers;
183		if (idx != pipe->n_layers) {
184			DRM_ERROR("please add Layer by id sequence.\n");
185			return ERR_PTR(-EINVAL);
186		}
187	} else if (has_bit(id,  KOMEDA_PIPELINE_SCALERS)) {
188		idx = id - KOMEDA_COMPONENT_SCALER0;
189		num = &pipe->n_scalers;
190		if (idx != pipe->n_scalers) {
191			DRM_ERROR("please add Scaler by id sequence.\n");
192			return ERR_PTR(-EINVAL);
193		}
194	}
195
196	c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL);
197	if (!c)
198		return ERR_PTR(-ENOMEM);
199
200	c->id = id;
201	c->hw_id = hw_id;
202	c->reg = reg;
203	c->pipeline = pipe;
204	c->max_active_inputs = max_active_inputs;
205	c->max_active_outputs = max_active_outputs;
206	c->supported_inputs = supported_inputs;
207	c->funcs = funcs;
208
209	if (name_fmt) {
210		va_list args;
211
212		va_start(args, name_fmt);
213		vsnprintf(c->name, sizeof(c->name), name_fmt, args);
214		va_end(args);
215	}
216
217	if (num)
218		*num = *num + 1;
219
220	pipe->avail_comps |= BIT(c->id);
221	*pos = c;
222
223	return c;
224}
225
226void komeda_component_destroy(struct komeda_dev *mdev,
227			      struct komeda_component *c)
228{
229	devm_kfree(mdev->dev, c);
230}
231
232static void komeda_component_dump(struct komeda_component *c)
233{
234	if (!c)
235		return;
236
237	DRM_DEBUG("	%s: ID %d-0x%08lx.\n",
238		  c->name, c->id, BIT(c->id));
239	DRM_DEBUG("		max_active_inputs:%d, supported_inputs: 0x%08x.\n",
240		  c->max_active_inputs, c->supported_inputs);
241	DRM_DEBUG("		max_active_outputs:%d, supported_outputs: 0x%08x.\n",
242		  c->max_active_outputs, c->supported_outputs);
243}
244
245static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
246{
247	struct komeda_component *c;
248	int id;
 
249
250	DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
251		 pipe->id, pipe->n_layers, pipe->n_scalers,
252		 pipe->dual_link ? "dual-link" : "single-link");
253	DRM_INFO("	output_link[0]: %s.\n",
254		 pipe->of_output_links[0] ?
255		 pipe->of_output_links[0]->full_name : "none");
256	DRM_INFO("	output_link[1]: %s.\n",
257		 pipe->of_output_links[1] ?
258		 pipe->of_output_links[1]->full_name : "none");
259
260	dp_for_each_set_bit(id, pipe->avail_comps) {
261		c = komeda_pipeline_get_component(pipe, id);
262
263		komeda_component_dump(c);
264	}
265}
266
267static void komeda_component_verify_inputs(struct komeda_component *c)
268{
269	struct komeda_pipeline *pipe = c->pipeline;
270	struct komeda_component *input;
271	int id;
 
272
273	dp_for_each_set_bit(id, c->supported_inputs) {
274		input = komeda_pipeline_get_component(pipe, id);
275		if (!input) {
276			c->supported_inputs &= ~(BIT(id));
277			DRM_WARN("Can not find input(ID-%d) for component: %s.\n",
278				 id, c->name);
279			continue;
280		}
281
282		input->supported_outputs |= BIT(c->id);
283	}
284}
285
286static struct komeda_layer *
287komeda_get_layer_split_right_layer(struct komeda_pipeline *pipe,
288				   struct komeda_layer *left)
289{
290	int index = left->base.id - KOMEDA_COMPONENT_LAYER0;
291	int i;
292
293	for (i = index + 1; i < pipe->n_layers; i++)
294		if (left->layer_type == pipe->layers[i]->layer_type)
295			return pipe->layers[i];
296	return NULL;
297}
298
299static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
300{
301	struct komeda_component *c;
302	struct komeda_layer *layer;
303	int i, id;
 
304
305	dp_for_each_set_bit(id, pipe->avail_comps) {
306		c = komeda_pipeline_get_component(pipe, id);
307		komeda_component_verify_inputs(c);
308	}
309	/* calculate right layer for the layer split */
310	for (i = 0; i < pipe->n_layers; i++) {
311		layer = pipe->layers[i];
312
313		layer->right = komeda_get_layer_split_right_layer(pipe, layer);
314	}
315
316	if (pipe->dual_link && !pipe->ctrlr->supports_dual_link) {
317		pipe->dual_link = false;
318		DRM_WARN("PIPE-%d doesn't support dual-link, ignore DT dual-link configuration.\n",
319			 pipe->id);
320	}
321}
322
323/* if pipeline_A accept another pipeline_B's component as input, treat
324 * pipeline_B as slave of pipeline_A.
325 */
326struct komeda_pipeline *
327komeda_pipeline_get_slave(struct komeda_pipeline *master)
328{
329	struct komeda_component *slave;
330
331	slave = komeda_component_pickup_input(&master->compiz->base,
332					      KOMEDA_PIPELINE_COMPIZS);
333
334	return slave ? slave->pipeline : NULL;
335}
336
337int komeda_assemble_pipelines(struct komeda_dev *mdev)
338{
339	struct komeda_pipeline *pipe;
340	int i;
341
342	for (i = 0; i < mdev->n_pipelines; i++) {
343		pipe = mdev->pipelines[i];
344
345		komeda_pipeline_assemble(pipe);
346		komeda_pipeline_dump(pipe);
347	}
348
349	return 0;
350}
351
352void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
353				   struct seq_file *sf)
354{
355	struct komeda_component *c;
356	u32 id;
 
357
358	seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
359
360	if (pipe->funcs && pipe->funcs->dump_register)
361		pipe->funcs->dump_register(pipe, sf);
362
363	dp_for_each_set_bit(id, pipe->avail_comps) {
 
364		c = komeda_pipeline_get_component(pipe, id);
365
366		seq_printf(sf, "\n------%s------\n", c->name);
367		if (c->funcs->dump_register)
368			c->funcs->dump_register(c, sf);
369	}
370}
v5.14.15
  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_print.h>
  8
  9#include "komeda_dev.h"
 10#include "komeda_pipeline.h"
 11
 12/** komeda_pipeline_add - Add a pipeline to &komeda_dev */
 13struct komeda_pipeline *
 14komeda_pipeline_add(struct komeda_dev *mdev, size_t size,
 15		    const struct komeda_pipeline_funcs *funcs)
 16{
 17	struct komeda_pipeline *pipe;
 18
 19	if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) {
 20		DRM_ERROR("Exceed max support %d pipelines.\n",
 21			  KOMEDA_MAX_PIPELINES);
 22		return ERR_PTR(-ENOSPC);
 23	}
 24
 25	if (size < sizeof(*pipe)) {
 26		DRM_ERROR("Request pipeline size too small.\n");
 27		return ERR_PTR(-EINVAL);
 28	}
 29
 30	pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
 31	if (!pipe)
 32		return ERR_PTR(-ENOMEM);
 33
 34	pipe->mdev = mdev;
 35	pipe->id   = mdev->n_pipelines;
 36	pipe->funcs = funcs;
 37
 38	mdev->pipelines[mdev->n_pipelines] = pipe;
 39	mdev->n_pipelines++;
 40
 41	return pipe;
 42}
 43
 44void komeda_pipeline_destroy(struct komeda_dev *mdev,
 45			     struct komeda_pipeline *pipe)
 46{
 47	struct komeda_component *c;
 48	int i;
 49	unsigned long avail_comps = pipe->avail_comps;
 50
 51	for_each_set_bit(i, &avail_comps, 32) {
 52		c = komeda_pipeline_get_component(pipe, i);
 53		komeda_component_destroy(mdev, c);
 54	}
 55
 56	clk_put(pipe->pxlclk);
 57
 58	of_node_put(pipe->of_output_links[0]);
 59	of_node_put(pipe->of_output_links[1]);
 60	of_node_put(pipe->of_output_port);
 61	of_node_put(pipe->of_node);
 62
 63	devm_kfree(mdev->dev, pipe);
 64}
 65
 66static struct komeda_component **
 67komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id)
 68{
 69	struct komeda_dev *mdev = pipe->mdev;
 70	struct komeda_pipeline *temp = NULL;
 71	struct komeda_component **pos = NULL;
 72
 73	switch (id) {
 74	case KOMEDA_COMPONENT_LAYER0:
 75	case KOMEDA_COMPONENT_LAYER1:
 76	case KOMEDA_COMPONENT_LAYER2:
 77	case KOMEDA_COMPONENT_LAYER3:
 78		pos = to_cpos(pipe->layers[id - KOMEDA_COMPONENT_LAYER0]);
 79		break;
 80	case KOMEDA_COMPONENT_WB_LAYER:
 81		pos = to_cpos(pipe->wb_layer);
 82		break;
 83	case KOMEDA_COMPONENT_COMPIZ0:
 84	case KOMEDA_COMPONENT_COMPIZ1:
 85		temp = mdev->pipelines[id - KOMEDA_COMPONENT_COMPIZ0];
 86		if (!temp) {
 87			DRM_ERROR("compiz-%d doesn't exist.\n", id);
 88			return NULL;
 89		}
 90		pos = to_cpos(temp->compiz);
 91		break;
 92	case KOMEDA_COMPONENT_SCALER0:
 93	case KOMEDA_COMPONENT_SCALER1:
 94		pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]);
 95		break;
 96	case KOMEDA_COMPONENT_SPLITTER:
 97		pos = to_cpos(pipe->splitter);
 98		break;
 99	case KOMEDA_COMPONENT_MERGER:
100		pos = to_cpos(pipe->merger);
101		break;
102	case KOMEDA_COMPONENT_IPS0:
103	case KOMEDA_COMPONENT_IPS1:
104		temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0];
105		if (!temp) {
106			DRM_ERROR("ips-%d doesn't exist.\n", id);
107			return NULL;
108		}
109		pos = to_cpos(temp->improc);
110		break;
111	case KOMEDA_COMPONENT_TIMING_CTRLR:
112		pos = to_cpos(pipe->ctrlr);
113		break;
114	default:
115		pos = NULL;
116		DRM_ERROR("Unknown pipeline resource ID: %d.\n", id);
117		break;
118	}
119
120	return pos;
121}
122
123struct komeda_component *
124komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
125{
126	struct komeda_component **pos = NULL;
127	struct komeda_component *c = NULL;
128
129	pos = komeda_pipeline_get_component_pos(pipe, id);
130	if (pos)
131		c = *pos;
132
133	return c;
134}
135
136struct komeda_component *
137komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
138				    u32 comp_mask)
139{
140	struct komeda_component *c = NULL;
141	unsigned long comp_mask_local = (unsigned long)comp_mask;
142	int id;
143
144	id = find_first_bit(&comp_mask_local, 32);
145	if (id < 32)
146		c = komeda_pipeline_get_component(pipe, id);
147
148	return c;
149}
150
151static struct komeda_component *
152komeda_component_pickup_input(struct komeda_component *c, u32 avail_comps)
153{
154	u32 avail_inputs = c->supported_inputs & (avail_comps);
155
156	return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
157}
158
159/** komeda_component_add - Add a component to &komeda_pipeline */
160struct komeda_component *
161komeda_component_add(struct komeda_pipeline *pipe,
162		     size_t comp_sz, u32 id, u32 hw_id,
163		     const struct komeda_component_funcs *funcs,
164		     u8 max_active_inputs, u32 supported_inputs,
165		     u8 max_active_outputs, u32 __iomem *reg,
166		     const char *name_fmt, ...)
167{
168	struct komeda_component **pos;
169	struct komeda_component *c;
170	int idx, *num = NULL;
171
172	if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) {
173		WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n",
174		     max_active_inputs);
175		return ERR_PTR(-ENOSPC);
176	}
177
178	pos = komeda_pipeline_get_component_pos(pipe, id);
179	if (!pos || (*pos))
180		return ERR_PTR(-EINVAL);
181
182	if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) {
183		idx = id - KOMEDA_COMPONENT_LAYER0;
184		num = &pipe->n_layers;
185		if (idx != pipe->n_layers) {
186			DRM_ERROR("please add Layer by id sequence.\n");
187			return ERR_PTR(-EINVAL);
188		}
189	} else if (has_bit(id,  KOMEDA_PIPELINE_SCALERS)) {
190		idx = id - KOMEDA_COMPONENT_SCALER0;
191		num = &pipe->n_scalers;
192		if (idx != pipe->n_scalers) {
193			DRM_ERROR("please add Scaler by id sequence.\n");
194			return ERR_PTR(-EINVAL);
195		}
196	}
197
198	c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL);
199	if (!c)
200		return ERR_PTR(-ENOMEM);
201
202	c->id = id;
203	c->hw_id = hw_id;
204	c->reg = reg;
205	c->pipeline = pipe;
206	c->max_active_inputs = max_active_inputs;
207	c->max_active_outputs = max_active_outputs;
208	c->supported_inputs = supported_inputs;
209	c->funcs = funcs;
210
211	if (name_fmt) {
212		va_list args;
213
214		va_start(args, name_fmt);
215		vsnprintf(c->name, sizeof(c->name), name_fmt, args);
216		va_end(args);
217	}
218
219	if (num)
220		*num = *num + 1;
221
222	pipe->avail_comps |= BIT(c->id);
223	*pos = c;
224
225	return c;
226}
227
228void komeda_component_destroy(struct komeda_dev *mdev,
229			      struct komeda_component *c)
230{
231	devm_kfree(mdev->dev, c);
232}
233
234static void komeda_component_dump(struct komeda_component *c)
235{
236	if (!c)
237		return;
238
239	DRM_DEBUG("	%s: ID %d-0x%08lx.\n",
240		  c->name, c->id, BIT(c->id));
241	DRM_DEBUG("		max_active_inputs:%d, supported_inputs: 0x%08x.\n",
242		  c->max_active_inputs, c->supported_inputs);
243	DRM_DEBUG("		max_active_outputs:%d, supported_outputs: 0x%08x.\n",
244		  c->max_active_outputs, c->supported_outputs);
245}
246
247static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
248{
249	struct komeda_component *c;
250	int id;
251	unsigned long avail_comps = pipe->avail_comps;
252
253	DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
254		 pipe->id, pipe->n_layers, pipe->n_scalers,
255		 pipe->dual_link ? "dual-link" : "single-link");
256	DRM_INFO("	output_link[0]: %s.\n",
257		 pipe->of_output_links[0] ?
258		 pipe->of_output_links[0]->full_name : "none");
259	DRM_INFO("	output_link[1]: %s.\n",
260		 pipe->of_output_links[1] ?
261		 pipe->of_output_links[1]->full_name : "none");
262
263	for_each_set_bit(id, &avail_comps, 32) {
264		c = komeda_pipeline_get_component(pipe, id);
265
266		komeda_component_dump(c);
267	}
268}
269
270static void komeda_component_verify_inputs(struct komeda_component *c)
271{
272	struct komeda_pipeline *pipe = c->pipeline;
273	struct komeda_component *input;
274	int id;
275	unsigned long supported_inputs = c->supported_inputs;
276
277	for_each_set_bit(id, &supported_inputs, 32) {
278		input = komeda_pipeline_get_component(pipe, id);
279		if (!input) {
280			c->supported_inputs &= ~(BIT(id));
281			DRM_WARN("Can not find input(ID-%d) for component: %s.\n",
282				 id, c->name);
283			continue;
284		}
285
286		input->supported_outputs |= BIT(c->id);
287	}
288}
289
290static struct komeda_layer *
291komeda_get_layer_split_right_layer(struct komeda_pipeline *pipe,
292				   struct komeda_layer *left)
293{
294	int index = left->base.id - KOMEDA_COMPONENT_LAYER0;
295	int i;
296
297	for (i = index + 1; i < pipe->n_layers; i++)
298		if (left->layer_type == pipe->layers[i]->layer_type)
299			return pipe->layers[i];
300	return NULL;
301}
302
303static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
304{
305	struct komeda_component *c;
306	struct komeda_layer *layer;
307	int i, id;
308	unsigned long avail_comps = pipe->avail_comps;
309
310	for_each_set_bit(id, &avail_comps, 32) {
311		c = komeda_pipeline_get_component(pipe, id);
312		komeda_component_verify_inputs(c);
313	}
314	/* calculate right layer for the layer split */
315	for (i = 0; i < pipe->n_layers; i++) {
316		layer = pipe->layers[i];
317
318		layer->right = komeda_get_layer_split_right_layer(pipe, layer);
319	}
320
321	if (pipe->dual_link && !pipe->ctrlr->supports_dual_link) {
322		pipe->dual_link = false;
323		DRM_WARN("PIPE-%d doesn't support dual-link, ignore DT dual-link configuration.\n",
324			 pipe->id);
325	}
326}
327
328/* if pipeline_A accept another pipeline_B's component as input, treat
329 * pipeline_B as slave of pipeline_A.
330 */
331struct komeda_pipeline *
332komeda_pipeline_get_slave(struct komeda_pipeline *master)
333{
334	struct komeda_component *slave;
335
336	slave = komeda_component_pickup_input(&master->compiz->base,
337					      KOMEDA_PIPELINE_COMPIZS);
338
339	return slave ? slave->pipeline : NULL;
340}
341
342int komeda_assemble_pipelines(struct komeda_dev *mdev)
343{
344	struct komeda_pipeline *pipe;
345	int i;
346
347	for (i = 0; i < mdev->n_pipelines; i++) {
348		pipe = mdev->pipelines[i];
349
350		komeda_pipeline_assemble(pipe);
351		komeda_pipeline_dump(pipe);
352	}
353
354	return 0;
355}
356
357void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
358				   struct seq_file *sf)
359{
360	struct komeda_component *c;
361	u32 id;
362	unsigned long avail_comps;
363
364	seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
365
366	if (pipe->funcs && pipe->funcs->dump_register)
367		pipe->funcs->dump_register(pipe, sf);
368
369	avail_comps = pipe->avail_comps;
370	for_each_set_bit(id, &avail_comps, 32) {
371		c = komeda_pipeline_get_component(pipe, id);
372
373		seq_printf(sf, "\n------%s------\n", c->name);
374		if (c->funcs->dump_register)
375			c->funcs->dump_register(c, sf);
376	}
377}