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