/** * vsp1_get_format_info - Retrieve format information for a 4CC * @vsp1: the VSP1 device * @fourcc: the format 4CC * * Return a pointer to the format information structure corresponding to the * given V4L2 format 4CC, or NULL if no corresponding format can be found.
*/ conststruct vsp1_format_info *vsp1_get_format_info(struct vsp1_device *vsp1,
u32 fourcc)
{ unsignedint i;
for (i = 0; i < ARRAY_SIZE(vsp1_video_formats); ++i) { conststruct vsp1_format_info *info = &vsp1_video_formats[i];
if (info->fourcc == fourcc) return info;
}
if (vsp1->info->gen == 2) { for (i = 0; i < ARRAY_SIZE(vsp1_video_gen2_formats); ++i) { conststruct vsp1_format_info *info =
&vsp1_video_gen2_formats[i];
if (info->fourcc == fourcc) return info;
}
}
if (vsp1_feature(vsp1, VSP1_HAS_HSIT)) { for (i = 0; i < ARRAY_SIZE(vsp1_video_hsit_formats); ++i) { conststruct vsp1_format_info *info =
&vsp1_video_hsit_formats[i];
if (info->fourcc == fourcc) return info;
}
}
return NULL;
}
/** * vsp1_get_format_info_by_index - Enumerate format information * @vsp1: the VSP1 device * @index: the format index * @code: media bus code to limit enumeration * * Return a pointer to the format information structure corresponding to the * given index, or NULL if the index exceeds the supported formats list. If the * @code parameter is not zero, only formats compatible with the media bus code * will be enumerated.
*/ conststruct vsp1_format_info *
vsp1_get_format_info_by_index(struct vsp1_device *vsp1, unsignedint index,
u32 code)
{ unsignedint i;
if (!code) { if (index < ARRAY_SIZE(vsp1_video_formats)) return &vsp1_video_formats[index];
if (vsp1->info->gen == 2) {
index -= ARRAY_SIZE(vsp1_video_formats); if (index < ARRAY_SIZE(vsp1_video_gen2_formats)) return &vsp1_video_gen2_formats[index];
}
if (vsp1_feature(vsp1, VSP1_HAS_HSIT)) {
index -= ARRAY_SIZE(vsp1_video_gen2_formats); if (index < ARRAY_SIZE(vsp1_video_hsit_formats)) return &vsp1_video_hsit_formats[index];
}
return NULL;
}
for (i = 0; i < ARRAY_SIZE(vsp1_video_formats); ++i) { conststruct vsp1_format_info *info = &vsp1_video_formats[i];
if (info->mbus == code) { if (!index) return info;
index--;
}
}
if (vsp1->info->gen == 2) { for (i = 0; i < ARRAY_SIZE(vsp1_video_gen2_formats); ++i) { conststruct vsp1_format_info *info =
&vsp1_video_gen2_formats[i];
if (info->mbus == code) { if (!index) return info;
index--;
}
}
}
if (vsp1_feature(vsp1, VSP1_HAS_HSIT)) { for (i = 0; i < ARRAY_SIZE(vsp1_video_hsit_formats); ++i) { conststruct vsp1_format_info *info =
&vsp1_video_hsit_formats[i];
if (info->mbus == code) { if (!index) return info;
index--;
}
}
}
return NULL;
}
/** * vsp1_adjust_color_space - Adjust color space fields in a format * @code: the media bus code * @colorspace: the colorspace * @xfer_func: the transfer function * @encoding: the encoding * @quantization: the quantization * * This function adjusts all color space fields of a video device of subdev * format structure, taking into account the requested format, requested color * space and limitations of the VSP1. It should be used in the video device and * subdev set format handlers. * * The colorspace and xfer_func fields are freely configurable, as they are out * of scope for VSP processing. The encoding and quantization is hardcoded for * non-YUV formats, and can be configured for YUV formats.
*/ void vsp1_adjust_color_space(u32 code, u32 *colorspace, u8 *xfer_func,
u8 *encoding, u8 *quantization)
{ if (*colorspace == V4L2_COLORSPACE_DEFAULT ||
*colorspace >= V4L2_COLORSPACE_LAST)
*colorspace = code == MEDIA_BUS_FMT_AYUV8_1X32
? V4L2_COLORSPACE_SMPTE170M
: V4L2_COLORSPACE_SRGB;
name = strchrnul(entity->subdev.name, ' ');
name = name ? name + 1 : entity->subdev.name;
pr_cont("%s%s", first ? "" : ", ", name);
first = false;
}
pr_cont("\n");
}
/* Must be called with the pipe irqlock held. */ void vsp1_pipeline_run(struct vsp1_pipeline *pipe)
{ struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
{ struct vsp1_device *vsp1 = pipe->output->entity.vsp1; struct vsp1_entity *entity; unsignedlong flags; int ret;
if (pipe->lif) { /* * When using display lists in continuous frame mode the only * way to stop the pipeline is to reset the hardware.
*/
ret = vsp1_reset_wpf(vsp1, pipe->output->entity.index); if (ret == 0) {
spin_lock_irqsave(&pipe->irqlock, flags);
pipe->state = VSP1_PIPELINE_STOPPED;
spin_unlock_irqrestore(&pipe->irqlock, flags);
}
} else { /* Otherwise just request a stop and wait. */
spin_lock_irqsave(&pipe->irqlock, flags); if (pipe->state == VSP1_PIPELINE_RUNNING)
pipe->state = VSP1_PIPELINE_STOPPING;
spin_unlock_irqrestore(&pipe->irqlock, flags);
ret = wait_event_timeout(pipe->wq, vsp1_pipeline_stopped(pipe),
msecs_to_jiffies(500));
ret = ret == 0 ? -ETIMEDOUT : 0;
}
/* * If the DL commit raced with the frame end interrupt, the commit ends * up being postponed by one frame. The returned flags tell whether the * active frame was finished or postponed.
*/
flags = vsp1_dlm_irq_frame_end(pipe->output->dlm);
if (pipe->hgo)
vsp1_hgo_frame_end(pipe->hgo);
if (pipe->hgt)
vsp1_hgt_frame_end(pipe->hgt);
/* * Regardless of frame completion we still need to notify the pipe * frame_end to account for vblank events.
*/ if (pipe->frame_end)
pipe->frame_end(pipe, flags);
pipe->sequence++;
}
/* * Propagate the alpha value through the pipeline. * * As the UDS has restricted scaling capabilities when the alpha component needs * to be scaled, we disable alpha scaling when the UDS input has a fixed alpha * value. The UDS then outputs a fixed alpha value which needs to be programmed * from the input RPF alpha.
*/ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe, struct vsp1_dl_body *dlb, unsignedint alpha)
{ if (!pipe->uds) return;
/* * The BRU and BRS background color has a fixed alpha value set to 255, * the output alpha value is thus always equal to 255.
*/ if (pipe->uds_input->type == VSP1_ENTITY_BRU ||
pipe->uds_input->type == VSP1_ENTITY_BRS)
alpha = 255;
vsp1_uds_set_alpha(pipe->uds, dlb, alpha);
}
/* ----------------------------------------------------------------------------- * VSP1 Partition Algorithm support
*/
/* * Propagate the partition calculations through the pipeline * * Work backwards through the pipe, allowing each entity to update the partition * parameters based on its configuration, and the entity connected to its * source. Each entity must produce the partition required for the previous * entity in the pipeline.
*/ staticvoid vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe, struct vsp1_partition *partition, unsignedint index, struct v4l2_rect *window)
{ struct vsp1_entity *entity;
/* * vsp1_pipeline_calculate_partition - Calculate pipeline configuration for a * partition * * @pipe: the pipeline * @partition: partition that will hold the calculated values * @div_size: pre-determined maximum partition division size * @index: partition index
*/ void vsp1_pipeline_calculate_partition(struct vsp1_pipeline *pipe, struct vsp1_partition *partition, unsignedint div_size, unsignedint index)
{ conststruct v4l2_mbus_framefmt *format; struct v4l2_rect window; unsignedint modulus;
/* * Partitions are computed on the size before rotation, use the format * at the WPF sink.
*/
format = v4l2_subdev_state_get_format(pipe->output->entity.state,
RWPF_PAD_SINK);
/* Initialise the partition with sane starting conditions. */
window.left = index * div_size;
window.width = div_size;
window.top = 0;
window.height = format->height;
modulus = format->width % div_size;
/* * We need to prevent the last partition from being smaller than the * *minimum* width of the hardware capabilities. * * If the modulus is less than half of the partition size, * the penultimate partition is reduced to half, which is added * to the final partition: |1234|1234|1234|12|341| * to prevent this: |1234|1234|1234|1234|1|.
*/ if (modulus) { /* * pipe->partitions is 1 based, whilst index is a 0 based index. * Normalise this locally.
*/ unsignedint partitions = pipe->partitions - 1;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.