1 // SPDX-License-Identifier: GPL-2.0
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
9 #include <drm/drm_print.h>
11 #include "komeda_dev.h"
12 #include "komeda_pipeline.h"
14 /** komeda_pipeline_add - Add a pipeline to &komeda_dev */
15 struct komeda_pipeline *
16 komeda_pipeline_add(struct komeda_dev *mdev, size_t size,
17 const struct komeda_pipeline_funcs *funcs)
19 struct komeda_pipeline *pipe;
21 if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) {
22 DRM_ERROR("Exceed max support %d pipelines.\n",
23 KOMEDA_MAX_PIPELINES);
24 return ERR_PTR(-ENOSPC);
27 if (size < sizeof(*pipe)) {
28 DRM_ERROR("Request pipeline size too small.\n");
29 return ERR_PTR(-EINVAL);
32 pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
34 return ERR_PTR(-ENOMEM);
37 pipe->id = mdev->n_pipelines;
40 mdev->pipelines[mdev->n_pipelines] = pipe;
46 void komeda_pipeline_destroy(struct komeda_dev *mdev,
47 struct komeda_pipeline *pipe)
49 struct komeda_component *c;
51 unsigned long avail_comps = pipe->avail_comps;
53 for_each_set_bit(i, &avail_comps, 32) {
54 c = komeda_pipeline_get_component(pipe, i);
55 komeda_component_destroy(mdev, c);
58 clk_put(pipe->pxlclk);
60 of_node_put(pipe->of_output_links[0]);
61 of_node_put(pipe->of_output_links[1]);
62 of_node_put(pipe->of_output_port);
63 of_node_put(pipe->of_node);
65 devm_kfree(mdev->dev, pipe);
68 static struct komeda_component **
69 komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id)
71 struct komeda_dev *mdev = pipe->mdev;
72 struct komeda_pipeline *temp = NULL;
73 struct komeda_component **pos = NULL;
76 case KOMEDA_COMPONENT_LAYER0:
77 case KOMEDA_COMPONENT_LAYER1:
78 case KOMEDA_COMPONENT_LAYER2:
79 case KOMEDA_COMPONENT_LAYER3:
80 pos = to_cpos(pipe->layers[id - KOMEDA_COMPONENT_LAYER0]);
82 case KOMEDA_COMPONENT_WB_LAYER:
83 pos = to_cpos(pipe->wb_layer);
85 case KOMEDA_COMPONENT_COMPIZ0:
86 case KOMEDA_COMPONENT_COMPIZ1:
87 temp = mdev->pipelines[id - KOMEDA_COMPONENT_COMPIZ0];
89 DRM_ERROR("compiz-%d doesn't exist.\n", id);
92 pos = to_cpos(temp->compiz);
94 case KOMEDA_COMPONENT_SCALER0:
95 case KOMEDA_COMPONENT_SCALER1:
96 pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]);
98 case KOMEDA_COMPONENT_SPLITTER:
99 pos = to_cpos(pipe->splitter);
101 case KOMEDA_COMPONENT_MERGER:
102 pos = to_cpos(pipe->merger);
104 case KOMEDA_COMPONENT_IPS0:
105 case KOMEDA_COMPONENT_IPS1:
106 temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0];
108 DRM_ERROR("ips-%d doesn't exist.\n", id);
111 pos = to_cpos(temp->improc);
113 case KOMEDA_COMPONENT_TIMING_CTRLR:
114 pos = to_cpos(pipe->ctrlr);
118 DRM_ERROR("Unknown pipeline resource ID: %d.\n", id);
125 struct komeda_component *
126 komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
128 struct komeda_component **pos = NULL;
129 struct komeda_component *c = NULL;
131 pos = komeda_pipeline_get_component_pos(pipe, id);
138 struct komeda_component *
139 komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
142 struct komeda_component *c = NULL;
143 unsigned long comp_mask_local = (unsigned long)comp_mask;
146 id = find_first_bit(&comp_mask_local, 32);
148 c = komeda_pipeline_get_component(pipe, id);
153 static struct komeda_component *
154 komeda_component_pickup_input(struct komeda_component *c, u32 avail_comps)
156 u32 avail_inputs = c->supported_inputs & (avail_comps);
158 return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
161 /** komeda_component_add - Add a component to &komeda_pipeline */
162 struct komeda_component *
163 komeda_component_add(struct komeda_pipeline *pipe,
164 size_t comp_sz, u32 id, u32 hw_id,
165 const struct komeda_component_funcs *funcs,
166 u8 max_active_inputs, u32 supported_inputs,
167 u8 max_active_outputs, u32 __iomem *reg,
168 const char *name_fmt, ...)
170 struct komeda_component **pos;
171 struct komeda_component *c;
172 int idx, *num = NULL;
174 if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) {
175 WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n",
177 return ERR_PTR(-ENOSPC);
180 pos = komeda_pipeline_get_component_pos(pipe, id);
182 return ERR_PTR(-EINVAL);
184 if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) {
185 idx = id - KOMEDA_COMPONENT_LAYER0;
186 num = &pipe->n_layers;
187 if (idx != pipe->n_layers) {
188 DRM_ERROR("please add Layer by id sequence.\n");
189 return ERR_PTR(-EINVAL);
191 } else if (has_bit(id, KOMEDA_PIPELINE_SCALERS)) {
192 idx = id - KOMEDA_COMPONENT_SCALER0;
193 num = &pipe->n_scalers;
194 if (idx != pipe->n_scalers) {
195 DRM_ERROR("please add Scaler by id sequence.\n");
196 return ERR_PTR(-EINVAL);
200 c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL);
202 return ERR_PTR(-ENOMEM);
208 c->max_active_inputs = max_active_inputs;
209 c->max_active_outputs = max_active_outputs;
210 c->supported_inputs = supported_inputs;
216 va_start(args, name_fmt);
217 vsnprintf(c->name, sizeof(c->name), name_fmt, args);
224 pipe->avail_comps |= BIT(c->id);
230 void komeda_component_destroy(struct komeda_dev *mdev,
231 struct komeda_component *c)
233 devm_kfree(mdev->dev, c);
236 static void komeda_component_dump(struct komeda_component *c)
241 DRM_DEBUG(" %s: ID %d-0x%08lx.\n",
242 c->name, c->id, BIT(c->id));
243 DRM_DEBUG(" max_active_inputs:%d, supported_inputs: 0x%08x.\n",
244 c->max_active_inputs, c->supported_inputs);
245 DRM_DEBUG(" max_active_outputs:%d, supported_outputs: 0x%08x.\n",
246 c->max_active_outputs, c->supported_outputs);
249 static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
251 struct komeda_component *c;
253 unsigned long avail_comps = pipe->avail_comps;
255 DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
256 pipe->id, pipe->n_layers, pipe->n_scalers,
257 pipe->dual_link ? "dual-link" : "single-link");
258 DRM_INFO(" output_link[0]: %s.\n",
259 pipe->of_output_links[0] ?
260 pipe->of_output_links[0]->full_name : "none");
261 DRM_INFO(" output_link[1]: %s.\n",
262 pipe->of_output_links[1] ?
263 pipe->of_output_links[1]->full_name : "none");
265 for_each_set_bit(id, &avail_comps, 32) {
266 c = komeda_pipeline_get_component(pipe, id);
268 komeda_component_dump(c);
272 static void komeda_component_verify_inputs(struct komeda_component *c)
274 struct komeda_pipeline *pipe = c->pipeline;
275 struct komeda_component *input;
277 unsigned long supported_inputs = c->supported_inputs;
279 for_each_set_bit(id, &supported_inputs, 32) {
280 input = komeda_pipeline_get_component(pipe, id);
282 c->supported_inputs &= ~(BIT(id));
283 DRM_WARN("Can not find input(ID-%d) for component: %s.\n",
288 input->supported_outputs |= BIT(c->id);
292 static struct komeda_layer *
293 komeda_get_layer_split_right_layer(struct komeda_pipeline *pipe,
294 struct komeda_layer *left)
296 int index = left->base.id - KOMEDA_COMPONENT_LAYER0;
299 for (i = index + 1; i < pipe->n_layers; i++)
300 if (left->layer_type == pipe->layers[i]->layer_type)
301 return pipe->layers[i];
305 static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
307 struct komeda_component *c;
308 struct komeda_layer *layer;
310 unsigned long avail_comps = pipe->avail_comps;
312 for_each_set_bit(id, &avail_comps, 32) {
313 c = komeda_pipeline_get_component(pipe, id);
314 komeda_component_verify_inputs(c);
316 /* calculate right layer for the layer split */
317 for (i = 0; i < pipe->n_layers; i++) {
318 layer = pipe->layers[i];
320 layer->right = komeda_get_layer_split_right_layer(pipe, layer);
323 if (pipe->dual_link && !pipe->ctrlr->supports_dual_link) {
324 pipe->dual_link = false;
325 DRM_WARN("PIPE-%d doesn't support dual-link, ignore DT dual-link configuration.\n",
330 /* if pipeline_A accept another pipeline_B's component as input, treat
331 * pipeline_B as slave of pipeline_A.
333 struct komeda_pipeline *
334 komeda_pipeline_get_slave(struct komeda_pipeline *master)
336 struct komeda_component *slave;
338 slave = komeda_component_pickup_input(&master->compiz->base,
339 KOMEDA_PIPELINE_COMPIZS);
341 return slave ? slave->pipeline : NULL;
344 int komeda_assemble_pipelines(struct komeda_dev *mdev)
346 struct komeda_pipeline *pipe;
349 for (i = 0; i < mdev->n_pipelines; i++) {
350 pipe = mdev->pipelines[i];
352 komeda_pipeline_assemble(pipe);
353 komeda_pipeline_dump(pipe);
359 void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
362 struct komeda_component *c;
364 unsigned long avail_comps;
366 seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
368 if (pipe->funcs && pipe->funcs->dump_register)
369 pipe->funcs->dump_register(pipe, sf);
371 avail_comps = pipe->avail_comps;
372 for_each_set_bit(id, &avail_comps, 32) {
373 c = komeda_pipeline_get_component(pipe, id);
375 seq_printf(sf, "\n------%s------\n", c->name);
376 if (c->funcs->dump_register)
377 c->funcs->dump_register(c, sf);