Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
0004  * Author: James.Qian.Wang <james.qian.wang@arm.com>
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 /** komeda_pipeline_add - Add a pipeline to &komeda_dev */
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 /** komeda_component_add - Add a component to &komeda_pipeline */
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     /* calculate right layer for the layer split */
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 /* if pipeline_A accept another pipeline_B's component as input, treat
0331  * pipeline_B as slave of pipeline_A.
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 }