diff options
Diffstat (limited to 'drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c')
-rw-r--r-- | drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c | 117 |
1 files changed, 106 insertions, 11 deletions
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c index f1908e9ef128..a130b62fa6d1 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c @@ -12,24 +12,24 @@ /** komeda_pipeline_add - Add a pipeline to &komeda_dev */ struct komeda_pipeline * komeda_pipeline_add(struct komeda_dev *mdev, size_t size, - struct komeda_pipeline_funcs *funcs) + const struct komeda_pipeline_funcs *funcs) { struct komeda_pipeline *pipe; if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) { DRM_ERROR("Exceed max support %d pipelines.\n", KOMEDA_MAX_PIPELINES); - return NULL; + return ERR_PTR(-ENOSPC); } if (size < sizeof(*pipe)) { DRM_ERROR("Request pipeline size too small.\n"); - return NULL; + return ERR_PTR(-EINVAL); } pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL); if (!pipe) - return NULL; + return ERR_PTR(-ENOMEM); pipe->mdev = mdev; pipe->id = mdev->n_pipelines; @@ -62,7 +62,7 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev, devm_kfree(mdev->dev, pipe); } -struct komeda_component ** +static struct komeda_component ** komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id) { struct komeda_dev *mdev = pipe->mdev; @@ -130,7 +130,7 @@ komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id) struct komeda_component * komeda_component_add(struct komeda_pipeline *pipe, size_t comp_sz, u32 id, u32 hw_id, - struct komeda_component_funcs *funcs, + const struct komeda_component_funcs *funcs, u8 max_active_inputs, u32 supported_inputs, u8 max_active_outputs, u32 __iomem *reg, const char *name_fmt, ...) @@ -142,32 +142,32 @@ komeda_component_add(struct komeda_pipeline *pipe, if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) { WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n", max_active_inputs); - return NULL; + return ERR_PTR(-ENOSPC); } pos = komeda_pipeline_get_component_pos(pipe, id); if (!pos || (*pos)) - return NULL; + return ERR_PTR(-EINVAL); if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) { idx = id - KOMEDA_COMPONENT_LAYER0; num = &pipe->n_layers; if (idx != pipe->n_layers) { DRM_ERROR("please add Layer by id sequence.\n"); - return NULL; + return ERR_PTR(-EINVAL); } } else if (has_bit(id, KOMEDA_PIPELINE_SCALERS)) { idx = id - KOMEDA_COMPONENT_SCALER0; num = &pipe->n_scalers; if (idx != pipe->n_scalers) { DRM_ERROR("please add Scaler by id sequence.\n"); - return NULL; + return ERR_PTR(-EINVAL); } } c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL); if (!c) - return NULL; + return ERR_PTR(-ENOMEM); c->id = id; c->hw_id = hw_id; @@ -200,3 +200,98 @@ void komeda_component_destroy(struct komeda_dev *mdev, { devm_kfree(mdev->dev, c); } + +static void komeda_component_dump(struct komeda_component *c) +{ + if (!c) + return; + + DRM_DEBUG(" %s: ID %d-0x%08lx.\n", + c->name, c->id, BIT(c->id)); + DRM_DEBUG(" max_active_inputs:%d, supported_inputs: 0x%08x.\n", + c->max_active_inputs, c->supported_inputs); + DRM_DEBUG(" max_active_outputs:%d, supported_outputs: 0x%08x.\n", + c->max_active_outputs, c->supported_outputs); +} + +static void komeda_pipeline_dump(struct komeda_pipeline *pipe) +{ + struct komeda_component *c; + int id; + + DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s\n", + pipe->id, pipe->n_layers, pipe->n_scalers, + pipe->of_output_dev ? pipe->of_output_dev->full_name : "none"); + + dp_for_each_set_bit(id, pipe->avail_comps) { + c = komeda_pipeline_get_component(pipe, id); + + komeda_component_dump(c); + } +} + +static void komeda_component_verify_inputs(struct komeda_component *c) +{ + struct komeda_pipeline *pipe = c->pipeline; + struct komeda_component *input; + int id; + + dp_for_each_set_bit(id, c->supported_inputs) { + input = komeda_pipeline_get_component(pipe, id); + if (!input) { + c->supported_inputs &= ~(BIT(id)); + DRM_WARN("Can not find input(ID-%d) for component: %s.\n", + id, c->name); + continue; + } + + input->supported_outputs |= BIT(c->id); + } +} + +static void komeda_pipeline_assemble(struct komeda_pipeline *pipe) +{ + struct komeda_component *c; + int id; + + dp_for_each_set_bit(id, pipe->avail_comps) { + c = komeda_pipeline_get_component(pipe, id); + + komeda_component_verify_inputs(c); + } +} + +int komeda_assemble_pipelines(struct komeda_dev *mdev) +{ + struct komeda_pipeline *pipe; + int i; + + for (i = 0; i < mdev->n_pipelines; i++) { + pipe = mdev->pipelines[i]; + + komeda_pipeline_assemble(pipe); + komeda_pipeline_dump(pipe); + } + + return 0; +} + +void komeda_pipeline_dump_register(struct komeda_pipeline *pipe, + struct seq_file *sf) +{ + struct komeda_component *c; + u32 id; + + seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id); + + if (pipe->funcs && pipe->funcs->dump_register) + pipe->funcs->dump_register(pipe, sf); + + dp_for_each_set_bit(id, pipe->avail_comps) { + c = komeda_pipeline_get_component(pipe, id); + + seq_printf(sf, "\n------%s------\n", c->name); + if (c->funcs->dump_register) + c->funcs->dump_register(c, sf); + } +} |