Lines Matching +full:fixed +full:- +full:links

1 // SPDX-License-Identifier: GPL-2.0+
3 * vsp1_entity.c -- R-Car VSP1 Base Entity
5 * Copyright (C) 2013-2014 Renesas Electronics Corporation
13 #include <media/media-entity.h>
14 #include <media/v4l2-ctrls.h>
15 #include <media/v4l2-subdev.h>
30 if (entity->type == VSP1_ENTITY_HGO) { in vsp1_entity_route_setup()
37 source = entity->sources[0]; in vsp1_entity_route_setup()
38 smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT) in vsp1_entity_route_setup()
39 | (source->route->output << VI6_DPR_SMPPT_PT_SHIFT); in vsp1_entity_route_setup()
43 } else if (entity->type == VSP1_ENTITY_HGT) { in vsp1_entity_route_setup()
50 source = entity->sources[0]; in vsp1_entity_route_setup()
51 smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT) in vsp1_entity_route_setup()
52 | (source->route->output << VI6_DPR_SMPPT_PT_SHIFT); in vsp1_entity_route_setup()
59 if (source->route->reg == 0) in vsp1_entity_route_setup()
62 route = source->sink->route->inputs[source->sink_pad]; in vsp1_entity_route_setup()
67 if (source->type == VSP1_ENTITY_BRS) in vsp1_entity_route_setup()
69 vsp1_dl_body_write(dlb, source->route->reg, route); in vsp1_entity_route_setup()
77 if (entity->ops->configure_stream) in vsp1_entity_configure_stream()
78 entity->ops->configure_stream(entity, pipe, dl, dlb); in vsp1_entity_configure_stream()
86 if (entity->ops->configure_frame) in vsp1_entity_configure_frame()
87 entity->ops->configure_frame(entity, pipe, dl, dlb); in vsp1_entity_configure_frame()
95 if (entity->ops->configure_partition) in vsp1_entity_configure_partition()
96 entity->ops->configure_partition(entity, pipe, dl, dlb); in vsp1_entity_configure_partition()
99 /* -----------------------------------------------------------------------------
104 * vsp1_entity_get_pad_config - Get the pad configuration for an entity
124 return entity->config; in vsp1_entity_get_pad_config()
132 * vsp1_entity_get_pad_format - Get a pad format from storage for an entity
145 return v4l2_subdev_get_try_format(&entity->subdev, sd_state, pad); in vsp1_entity_get_pad_format()
149 * vsp1_entity_get_pad_selection - Get a pad selection from storage for entity
166 return v4l2_subdev_get_try_compose(&entity->subdev, sd_state, in vsp1_entity_get_pad_selection()
169 return v4l2_subdev_get_try_crop(&entity->subdev, sd_state, in vsp1_entity_get_pad_selection()
177 * vsp1_entity_init_cfg - Initialize formats on all pads
190 for (pad = 0; pad < subdev->entity.num_pads - 1; ++pad) { in vsp1_entity_init_cfg()
204 * vsp1_subdev_get_pad_format - Subdev pad get_fmt handler
210 * a direct drop-in for the operation handler.
219 config = vsp1_entity_get_pad_config(entity, sd_state, fmt->which); in vsp1_subdev_get_pad_format()
221 return -EINVAL; in vsp1_subdev_get_pad_format()
223 mutex_lock(&entity->lock); in vsp1_subdev_get_pad_format()
224 fmt->format = *vsp1_entity_get_pad_format(entity, config, fmt->pad); in vsp1_subdev_get_pad_format()
225 mutex_unlock(&entity->lock); in vsp1_subdev_get_pad_format()
231 * vsp1_subdev_enum_mbus_code - Subdev pad enum_mbus_code handler
250 if (code->pad == 0) { in vsp1_subdev_enum_mbus_code()
251 if (code->index >= ncodes) in vsp1_subdev_enum_mbus_code()
252 return -EINVAL; in vsp1_subdev_enum_mbus_code()
254 code->code = codes[code->index]; in vsp1_subdev_enum_mbus_code()
263 if (code->index) in vsp1_subdev_enum_mbus_code()
264 return -EINVAL; in vsp1_subdev_enum_mbus_code()
267 code->which); in vsp1_subdev_enum_mbus_code()
269 return -EINVAL; in vsp1_subdev_enum_mbus_code()
271 mutex_lock(&entity->lock); in vsp1_subdev_enum_mbus_code()
273 code->code = format->code; in vsp1_subdev_enum_mbus_code()
274 mutex_unlock(&entity->lock); in vsp1_subdev_enum_mbus_code()
281 * vsp1_subdev_enum_frame_size - Subdev pad enum_frame_size handler
292 * minimum and maximum frame width and height on the sink pad, and a fixed
306 config = vsp1_entity_get_pad_config(entity, sd_state, fse->which); in vsp1_subdev_enum_frame_size()
308 return -EINVAL; in vsp1_subdev_enum_frame_size()
310 format = vsp1_entity_get_pad_format(entity, config, fse->pad); in vsp1_subdev_enum_frame_size()
312 mutex_lock(&entity->lock); in vsp1_subdev_enum_frame_size()
314 if (fse->index || fse->code != format->code) { in vsp1_subdev_enum_frame_size()
315 ret = -EINVAL; in vsp1_subdev_enum_frame_size()
319 if (fse->pad == 0) { in vsp1_subdev_enum_frame_size()
320 fse->min_width = min_width; in vsp1_subdev_enum_frame_size()
321 fse->max_width = max_width; in vsp1_subdev_enum_frame_size()
322 fse->min_height = min_height; in vsp1_subdev_enum_frame_size()
323 fse->max_height = max_height; in vsp1_subdev_enum_frame_size()
326 * The size on the source pad are fixed and always identical to in vsp1_subdev_enum_frame_size()
329 fse->min_width = format->width; in vsp1_subdev_enum_frame_size()
330 fse->max_width = format->width; in vsp1_subdev_enum_frame_size()
331 fse->min_height = format->height; in vsp1_subdev_enum_frame_size()
332 fse->max_height = format->height; in vsp1_subdev_enum_frame_size()
336 mutex_unlock(&entity->lock); in vsp1_subdev_enum_frame_size()
341 * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
372 mutex_lock(&entity->lock); in vsp1_subdev_set_pad_format()
374 config = vsp1_entity_get_pad_config(entity, sd_state, fmt->which); in vsp1_subdev_set_pad_format()
376 ret = -EINVAL; in vsp1_subdev_set_pad_format()
380 format = vsp1_entity_get_pad_format(entity, config, fmt->pad); in vsp1_subdev_set_pad_format()
382 if (fmt->pad == entity->source_pad) { in vsp1_subdev_set_pad_format()
384 fmt->format = *format; in vsp1_subdev_set_pad_format()
393 if (fmt->format.code == codes[i]) in vsp1_subdev_set_pad_format()
397 format->code = i < ncodes ? codes[i] : codes[0]; in vsp1_subdev_set_pad_format()
398 format->width = clamp_t(unsigned int, fmt->format.width, in vsp1_subdev_set_pad_format()
400 format->height = clamp_t(unsigned int, fmt->format.height, in vsp1_subdev_set_pad_format()
402 format->field = V4L2_FIELD_NONE; in vsp1_subdev_set_pad_format()
403 format->colorspace = V4L2_COLORSPACE_SRGB; in vsp1_subdev_set_pad_format()
405 fmt->format = *format; in vsp1_subdev_set_pad_format()
408 format = vsp1_entity_get_pad_format(entity, config, entity->source_pad); in vsp1_subdev_set_pad_format()
409 *format = fmt->format; in vsp1_subdev_set_pad_format()
412 selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad, in vsp1_subdev_set_pad_format()
414 selection->left = 0; in vsp1_subdev_set_pad_format()
415 selection->top = 0; in vsp1_subdev_set_pad_format()
416 selection->width = format->width; in vsp1_subdev_set_pad_format()
417 selection->height = format->height; in vsp1_subdev_set_pad_format()
419 selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad, in vsp1_subdev_set_pad_format()
421 selection->left = 0; in vsp1_subdev_set_pad_format()
422 selection->top = 0; in vsp1_subdev_set_pad_format()
423 selection->width = format->width; in vsp1_subdev_set_pad_format()
424 selection->height = format->height; in vsp1_subdev_set_pad_format()
427 mutex_unlock(&entity->lock); in vsp1_subdev_set_pad_format()
431 /* -----------------------------------------------------------------------------
447 source = media_entity_to_vsp1_entity(source_pad->entity); in vsp1_entity_link_setup_source()
449 if (!source->route) in vsp1_entity_link_setup_source()
454 = media_entity_to_vsp1_entity(sink_pad->entity); in vsp1_entity_link_setup_source()
457 * Fan-out is limited to one for the normal data path plus in vsp1_entity_link_setup_source()
460 if (sink->type != VSP1_ENTITY_HGO && in vsp1_entity_link_setup_source()
461 sink->type != VSP1_ENTITY_HGT) { in vsp1_entity_link_setup_source()
462 if (source->sink) in vsp1_entity_link_setup_source()
463 return -EBUSY; in vsp1_entity_link_setup_source()
464 source->sink = sink; in vsp1_entity_link_setup_source()
465 source->sink_pad = sink_pad->index; in vsp1_entity_link_setup_source()
468 source->sink = NULL; in vsp1_entity_link_setup_source()
469 source->sink_pad = 0; in vsp1_entity_link_setup_source()
482 sink = media_entity_to_vsp1_entity(sink_pad->entity); in vsp1_entity_link_setup_sink()
483 source = media_entity_to_vsp1_entity(source_pad->entity); in vsp1_entity_link_setup_sink()
486 /* Fan-in is limited to one. */ in vsp1_entity_link_setup_sink()
487 if (sink->sources[sink_pad->index]) in vsp1_entity_link_setup_sink()
488 return -EBUSY; in vsp1_entity_link_setup_sink()
490 sink->sources[sink_pad->index] = source; in vsp1_entity_link_setup_sink()
492 sink->sources[sink_pad->index] = NULL; in vsp1_entity_link_setup_sink()
502 if (local->flags & MEDIA_PAD_FL_SOURCE) in vsp1_entity_link_setup()
509 * vsp1_entity_remote_pad - Find the pad at the remote end of a link
513 * links originating or terminating at that pad until an enabled link is found.
515 * Our link setup implementation guarantees that the output fan-out will not be
516 * higher than one for the data pipelines, except for the links to the HGO and
518 * outgoing links this function ignores HGO and HGT entities and should thus be
529 list_for_each_entry(link, &pad->entity->links, list) { in vsp1_entity_remote_pad()
532 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) in vsp1_entity_remote_pad()
536 if (link->sink == pad) in vsp1_entity_remote_pad()
537 return link->source; in vsp1_entity_remote_pad()
539 if (link->source != pad) in vsp1_entity_remote_pad()
543 if (!is_media_entity_v4l2_subdev(link->sink->entity)) in vsp1_entity_remote_pad()
544 return link->sink; in vsp1_entity_remote_pad()
546 entity = media_entity_to_vsp1_entity(link->sink->entity); in vsp1_entity_remote_pad()
547 if (entity->type != VSP1_ENTITY_HGO && in vsp1_entity_remote_pad()
548 entity->type != VSP1_ENTITY_HGT) in vsp1_entity_remote_pad()
549 return link->sink; in vsp1_entity_remote_pad()
556 /* -----------------------------------------------------------------------------
621 if (vsp1_routes[i].type == entity->type && in vsp1_entity_init()
622 vsp1_routes[i].index == entity->index) { in vsp1_entity_init()
623 entity->route = &vsp1_routes[i]; in vsp1_entity_init()
629 return -EINVAL; in vsp1_entity_init()
631 mutex_init(&entity->lock); in vsp1_entity_init()
633 entity->vsp1 = vsp1; in vsp1_entity_init()
634 entity->source_pad = num_pads - 1; in vsp1_entity_init()
637 entity->pads = devm_kcalloc(vsp1->dev, in vsp1_entity_init()
638 num_pads, sizeof(*entity->pads), in vsp1_entity_init()
640 if (entity->pads == NULL) in vsp1_entity_init()
641 return -ENOMEM; in vsp1_entity_init()
643 for (i = 0; i < num_pads - 1; ++i) in vsp1_entity_init()
644 entity->pads[i].flags = MEDIA_PAD_FL_SINK; in vsp1_entity_init()
646 entity->sources = devm_kcalloc(vsp1->dev, max(num_pads - 1, 1U), in vsp1_entity_init()
647 sizeof(*entity->sources), GFP_KERNEL); in vsp1_entity_init()
648 if (entity->sources == NULL) in vsp1_entity_init()
649 return -ENOMEM; in vsp1_entity_init()
651 /* Single-pad entities only have a sink. */ in vsp1_entity_init()
652 entity->pads[num_pads - 1].flags = num_pads > 1 ? MEDIA_PAD_FL_SOURCE in vsp1_entity_init()
656 ret = media_entity_pads_init(&entity->subdev.entity, num_pads, in vsp1_entity_init()
657 entity->pads); in vsp1_entity_init()
662 subdev = &entity->subdev; in vsp1_entity_init()
665 subdev->entity.function = function; in vsp1_entity_init()
666 subdev->entity.ops = &vsp1->media_ops; in vsp1_entity_init()
667 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in vsp1_entity_init()
669 snprintf(subdev->name, sizeof(subdev->name), "%s %s", in vsp1_entity_init()
670 dev_name(vsp1->dev), name); in vsp1_entity_init()
678 entity->config = v4l2_subdev_alloc_state(&entity->subdev); in vsp1_entity_init()
679 if (IS_ERR(entity->config)) { in vsp1_entity_init()
680 media_entity_cleanup(&entity->subdev.entity); in vsp1_entity_init()
681 return PTR_ERR(entity->config); in vsp1_entity_init()
689 if (entity->ops && entity->ops->destroy) in vsp1_entity_destroy()
690 entity->ops->destroy(entity); in vsp1_entity_destroy()
691 if (entity->subdev.ctrl_handler) in vsp1_entity_destroy()
692 v4l2_ctrl_handler_free(entity->subdev.ctrl_handler); in vsp1_entity_destroy()
693 v4l2_subdev_free_state(entity->config); in vsp1_entity_destroy()
694 media_entity_cleanup(&entity->subdev.entity); in vsp1_entity_destroy()