0001
0002
0003
0004
0005
0006
0007 #include <linux/of.h>
0008
0009 #include <drm/drm_print.h>
0010
0011 #include "komeda_dev.h"
0012 #include "komeda_pipeline.h"
0013
0014
0015 struct komeda_pipeline *
0016 komeda_pipeline_add(struct komeda_dev *mdev, size_t size,
0017 const struct komeda_pipeline_funcs *funcs)
0018 {
0019 struct komeda_pipeline *pipe;
0020
0021 if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) {
0022 DRM_ERROR("Exceed max support %d pipelines.\n",
0023 KOMEDA_MAX_PIPELINES);
0024 return ERR_PTR(-ENOSPC);
0025 }
0026
0027 if (size < sizeof(*pipe)) {
0028 DRM_ERROR("Request pipeline size too small.\n");
0029 return ERR_PTR(-EINVAL);
0030 }
0031
0032 pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
0033 if (!pipe)
0034 return ERR_PTR(-ENOMEM);
0035
0036 pipe->mdev = mdev;
0037 pipe->id = mdev->n_pipelines;
0038 pipe->funcs = funcs;
0039
0040 mdev->pipelines[mdev->n_pipelines] = pipe;
0041 mdev->n_pipelines++;
0042
0043 return pipe;
0044 }
0045
0046 void komeda_pipeline_destroy(struct komeda_dev *mdev,
0047 struct komeda_pipeline *pipe)
0048 {
0049 struct komeda_component *c;
0050 int i;
0051 unsigned long avail_comps = pipe->avail_comps;
0052
0053 for_each_set_bit(i, &avail_comps, 32) {
0054 c = komeda_pipeline_get_component(pipe, i);
0055 komeda_component_destroy(mdev, c);
0056 }
0057
0058 clk_put(pipe->pxlclk);
0059
0060 of_node_put(pipe->of_output_links[0]);
0061 of_node_put(pipe->of_output_links[1]);
0062 of_node_put(pipe->of_output_port);
0063 of_node_put(pipe->of_node);
0064
0065 devm_kfree(mdev->dev, pipe);
0066 }
0067
0068 static struct komeda_component **
0069 komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id)
0070 {
0071 struct komeda_dev *mdev = pipe->mdev;
0072 struct komeda_pipeline *temp = NULL;
0073 struct komeda_component **pos = NULL;
0074
0075 switch (id) {
0076 case KOMEDA_COMPONENT_LAYER0:
0077 case KOMEDA_COMPONENT_LAYER1:
0078 case KOMEDA_COMPONENT_LAYER2:
0079 case KOMEDA_COMPONENT_LAYER3:
0080 pos = to_cpos(pipe->layers[id - KOMEDA_COMPONENT_LAYER0]);
0081 break;
0082 case KOMEDA_COMPONENT_WB_LAYER:
0083 pos = to_cpos(pipe->wb_layer);
0084 break;
0085 case KOMEDA_COMPONENT_COMPIZ0:
0086 case KOMEDA_COMPONENT_COMPIZ1:
0087 temp = mdev->pipelines[id - KOMEDA_COMPONENT_COMPIZ0];
0088 if (!temp) {
0089 DRM_ERROR("compiz-%d doesn't exist.\n", id);
0090 return NULL;
0091 }
0092 pos = to_cpos(temp->compiz);
0093 break;
0094 case KOMEDA_COMPONENT_SCALER0:
0095 case KOMEDA_COMPONENT_SCALER1:
0096 pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]);
0097 break;
0098 case KOMEDA_COMPONENT_SPLITTER:
0099 pos = to_cpos(pipe->splitter);
0100 break;
0101 case KOMEDA_COMPONENT_MERGER:
0102 pos = to_cpos(pipe->merger);
0103 break;
0104 case KOMEDA_COMPONENT_IPS0:
0105 case KOMEDA_COMPONENT_IPS1:
0106 temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0];
0107 if (!temp) {
0108 DRM_ERROR("ips-%d doesn't exist.\n", id);
0109 return NULL;
0110 }
0111 pos = to_cpos(temp->improc);
0112 break;
0113 case KOMEDA_COMPONENT_TIMING_CTRLR:
0114 pos = to_cpos(pipe->ctrlr);
0115 break;
0116 default:
0117 pos = NULL;
0118 DRM_ERROR("Unknown pipeline resource ID: %d.\n", id);
0119 break;
0120 }
0121
0122 return pos;
0123 }
0124
0125 struct komeda_component *
0126 komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
0127 {
0128 struct komeda_component **pos = NULL;
0129 struct komeda_component *c = NULL;
0130
0131 pos = komeda_pipeline_get_component_pos(pipe, id);
0132 if (pos)
0133 c = *pos;
0134
0135 return c;
0136 }
0137
0138 struct komeda_component *
0139 komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
0140 u32 comp_mask)
0141 {
0142 struct komeda_component *c = NULL;
0143 unsigned long comp_mask_local = (unsigned long)comp_mask;
0144 int id;
0145
0146 id = find_first_bit(&comp_mask_local, 32);
0147 if (id < 32)
0148 c = komeda_pipeline_get_component(pipe, id);
0149
0150 return c;
0151 }
0152
0153 static struct komeda_component *
0154 komeda_component_pickup_input(struct komeda_component *c, u32 avail_comps)
0155 {
0156 u32 avail_inputs = c->supported_inputs & (avail_comps);
0157
0158 return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
0159 }
0160
0161
0162 struct komeda_component *
0163 komeda_component_add(struct komeda_pipeline *pipe,
0164 size_t comp_sz, u32 id, u32 hw_id,
0165 const struct komeda_component_funcs *funcs,
0166 u8 max_active_inputs, u32 supported_inputs,
0167 u8 max_active_outputs, u32 __iomem *reg,
0168 const char *name_fmt, ...)
0169 {
0170 struct komeda_component **pos;
0171 struct komeda_component *c;
0172 int idx, *num = NULL;
0173
0174 if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) {
0175 WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n",
0176 max_active_inputs);
0177 return ERR_PTR(-ENOSPC);
0178 }
0179
0180 pos = komeda_pipeline_get_component_pos(pipe, id);
0181 if (!pos || (*pos))
0182 return ERR_PTR(-EINVAL);
0183
0184 if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) {
0185 idx = id - KOMEDA_COMPONENT_LAYER0;
0186 num = &pipe->n_layers;
0187 if (idx != pipe->n_layers) {
0188 DRM_ERROR("please add Layer by id sequence.\n");
0189 return ERR_PTR(-EINVAL);
0190 }
0191 } else if (has_bit(id, KOMEDA_PIPELINE_SCALERS)) {
0192 idx = id - KOMEDA_COMPONENT_SCALER0;
0193 num = &pipe->n_scalers;
0194 if (idx != pipe->n_scalers) {
0195 DRM_ERROR("please add Scaler by id sequence.\n");
0196 return ERR_PTR(-EINVAL);
0197 }
0198 }
0199
0200 c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL);
0201 if (!c)
0202 return ERR_PTR(-ENOMEM);
0203
0204 c->id = id;
0205 c->hw_id = hw_id;
0206 c->reg = reg;
0207 c->pipeline = pipe;
0208 c->max_active_inputs = max_active_inputs;
0209 c->max_active_outputs = max_active_outputs;
0210 c->supported_inputs = supported_inputs;
0211 c->funcs = funcs;
0212
0213 if (name_fmt) {
0214 va_list args;
0215
0216 va_start(args, name_fmt);
0217 vsnprintf(c->name, sizeof(c->name), name_fmt, args);
0218 va_end(args);
0219 }
0220
0221 if (num)
0222 *num = *num + 1;
0223
0224 pipe->avail_comps |= BIT(c->id);
0225 *pos = c;
0226
0227 return c;
0228 }
0229
0230 void komeda_component_destroy(struct komeda_dev *mdev,
0231 struct komeda_component *c)
0232 {
0233 devm_kfree(mdev->dev, c);
0234 }
0235
0236 static void komeda_component_dump(struct komeda_component *c)
0237 {
0238 if (!c)
0239 return;
0240
0241 DRM_DEBUG(" %s: ID %d-0x%08lx.\n",
0242 c->name, c->id, BIT(c->id));
0243 DRM_DEBUG(" max_active_inputs:%d, supported_inputs: 0x%08x.\n",
0244 c->max_active_inputs, c->supported_inputs);
0245 DRM_DEBUG(" max_active_outputs:%d, supported_outputs: 0x%08x.\n",
0246 c->max_active_outputs, c->supported_outputs);
0247 }
0248
0249 static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
0250 {
0251 struct komeda_component *c;
0252 int id;
0253 unsigned long avail_comps = pipe->avail_comps;
0254
0255 DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
0256 pipe->id, pipe->n_layers, pipe->n_scalers,
0257 pipe->dual_link ? "dual-link" : "single-link");
0258 DRM_INFO(" output_link[0]: %s.\n",
0259 pipe->of_output_links[0] ?
0260 pipe->of_output_links[0]->full_name : "none");
0261 DRM_INFO(" output_link[1]: %s.\n",
0262 pipe->of_output_links[1] ?
0263 pipe->of_output_links[1]->full_name : "none");
0264
0265 for_each_set_bit(id, &avail_comps, 32) {
0266 c = komeda_pipeline_get_component(pipe, id);
0267
0268 komeda_component_dump(c);
0269 }
0270 }
0271
0272 static void komeda_component_verify_inputs(struct komeda_component *c)
0273 {
0274 struct komeda_pipeline *pipe = c->pipeline;
0275 struct komeda_component *input;
0276 int id;
0277 unsigned long supported_inputs = c->supported_inputs;
0278
0279 for_each_set_bit(id, &supported_inputs, 32) {
0280 input = komeda_pipeline_get_component(pipe, id);
0281 if (!input) {
0282 c->supported_inputs &= ~(BIT(id));
0283 DRM_WARN("Can not find input(ID-%d) for component: %s.\n",
0284 id, c->name);
0285 continue;
0286 }
0287
0288 input->supported_outputs |= BIT(c->id);
0289 }
0290 }
0291
0292 static struct komeda_layer *
0293 komeda_get_layer_split_right_layer(struct komeda_pipeline *pipe,
0294 struct komeda_layer *left)
0295 {
0296 int index = left->base.id - KOMEDA_COMPONENT_LAYER0;
0297 int i;
0298
0299 for (i = index + 1; i < pipe->n_layers; i++)
0300 if (left->layer_type == pipe->layers[i]->layer_type)
0301 return pipe->layers[i];
0302 return NULL;
0303 }
0304
0305 static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
0306 {
0307 struct komeda_component *c;
0308 struct komeda_layer *layer;
0309 int i, id;
0310 unsigned long avail_comps = pipe->avail_comps;
0311
0312 for_each_set_bit(id, &avail_comps, 32) {
0313 c = komeda_pipeline_get_component(pipe, id);
0314 komeda_component_verify_inputs(c);
0315 }
0316
0317 for (i = 0; i < pipe->n_layers; i++) {
0318 layer = pipe->layers[i];
0319
0320 layer->right = komeda_get_layer_split_right_layer(pipe, layer);
0321 }
0322
0323 if (pipe->dual_link && !pipe->ctrlr->supports_dual_link) {
0324 pipe->dual_link = false;
0325 DRM_WARN("PIPE-%d doesn't support dual-link, ignore DT dual-link configuration.\n",
0326 pipe->id);
0327 }
0328 }
0329
0330
0331
0332
0333 struct komeda_pipeline *
0334 komeda_pipeline_get_slave(struct komeda_pipeline *master)
0335 {
0336 struct komeda_component *slave;
0337
0338 slave = komeda_component_pickup_input(&master->compiz->base,
0339 KOMEDA_PIPELINE_COMPIZS);
0340
0341 return slave ? slave->pipeline : NULL;
0342 }
0343
0344 int komeda_assemble_pipelines(struct komeda_dev *mdev)
0345 {
0346 struct komeda_pipeline *pipe;
0347 int i;
0348
0349 for (i = 0; i < mdev->n_pipelines; i++) {
0350 pipe = mdev->pipelines[i];
0351
0352 komeda_pipeline_assemble(pipe);
0353 komeda_pipeline_dump(pipe);
0354 }
0355
0356 return 0;
0357 }
0358
0359 void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
0360 struct seq_file *sf)
0361 {
0362 struct komeda_component *c;
0363 u32 id;
0364 unsigned long avail_comps;
0365
0366 seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
0367
0368 if (pipe->funcs && pipe->funcs->dump_register)
0369 pipe->funcs->dump_register(pipe, sf);
0370
0371 avail_comps = pipe->avail_comps;
0372 for_each_set_bit(id, &avail_comps, 32) {
0373 c = komeda_pipeline_get_component(pipe, id);
0374
0375 seq_printf(sf, "\n------%s------\n", c->name);
0376 if (c->funcs->dump_register)
0377 c->funcs->dump_register(c, sf);
0378 }
0379 }