summaryrefslogtreecommitdiff
path: root/drivers/media/platform/renesas/vsp1/vsp1_rpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/renesas/vsp1/vsp1_rpf.c')
-rw-r--r--drivers/media/platform/renesas/vsp1/vsp1_rpf.c96
1 files changed, 63 insertions, 33 deletions
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c
index c47579efc65f..811f2b7c5cc5 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c
@@ -48,6 +48,7 @@ static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf,
*/
static void rpf_configure_stream(struct vsp1_entity *entity,
+ struct v4l2_subdev_state *state,
struct vsp1_pipeline *pipe,
struct vsp1_dl_list *dl,
struct vsp1_dl_body *dlb)
@@ -80,14 +81,10 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_PSTRIDE, pstride);
/* Format */
- sink_format = vsp1_entity_get_pad_format(&rpf->entity,
- rpf->entity.state,
- RWPF_PAD_SINK);
- source_format = vsp1_entity_get_pad_format(&rpf->entity,
- rpf->entity.state,
- RWPF_PAD_SOURCE);
-
- infmt = VI6_RPF_INFMT_CIPM
+ sink_format = v4l2_subdev_state_get_format(state, RWPF_PAD_SINK);
+ source_format = v4l2_subdev_state_get_format(state, RWPF_PAD_SOURCE);
+
+ infmt = (pipe->iif ? 0 : VI6_RPF_INFMT_CIPM)
| (fmtinfo->hwfmt << VI6_RPF_INFMT_RDFMT_SHIFT);
if (fmtinfo->swap_yc)
@@ -95,12 +92,44 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
if (fmtinfo->swap_uv)
infmt |= VI6_RPF_INFMT_SPUVS;
- if (sink_format->code != source_format->code)
- infmt |= VI6_RPF_INFMT_CSC;
+ if (sink_format->code != source_format->code) {
+ u16 ycbcr_enc;
+ u16 quantization;
+ u32 rdtm;
+
+ if (sink_format->code == MEDIA_BUS_FMT_AYUV8_1X32) {
+ ycbcr_enc = sink_format->ycbcr_enc;
+ quantization = sink_format->quantization;
+ } else {
+ ycbcr_enc = source_format->ycbcr_enc;
+ quantization = source_format->quantization;
+ }
+
+ if (ycbcr_enc == V4L2_YCBCR_ENC_601 &&
+ quantization == V4L2_QUANTIZATION_LIM_RANGE)
+ rdtm = VI6_RPF_INFMT_RDTM_BT601;
+ else if (ycbcr_enc == V4L2_YCBCR_ENC_601 &&
+ quantization == V4L2_QUANTIZATION_FULL_RANGE)
+ rdtm = VI6_RPF_INFMT_RDTM_BT601_EXT;
+ else if (ycbcr_enc == V4L2_YCBCR_ENC_709 &&
+ quantization == V4L2_QUANTIZATION_LIM_RANGE)
+ rdtm = VI6_RPF_INFMT_RDTM_BT709;
+ else
+ rdtm = VI6_RPF_INFMT_RDTM_BT709_EXT;
+
+ infmt |= VI6_RPF_INFMT_CSC | rdtm;
+ }
vsp1_rpf_write(rpf, dlb, VI6_RPF_INFMT, infmt);
vsp1_rpf_write(rpf, dlb, VI6_RPF_DSWAP, fmtinfo->swap);
+ /* No further configuration for VSPX. */
+ if (pipe->iif) {
+ /* VSPX wants alpha_sel to be set to 0. */
+ vsp1_rpf_write(rpf, dlb, VI6_RPF_ALPH_SEL, 0);
+ return;
+ }
+
if (entity->vsp1->info->gen == 4) {
u32 ext_infmt0;
u32 ext_infmt1;
@@ -157,10 +186,8 @@ static void rpf_configure_stream(struct vsp1_entity *entity,
if (pipe->brx) {
const struct v4l2_rect *compose;
- compose = vsp1_entity_get_pad_selection(pipe->brx,
- pipe->brx->state,
- rpf->brx_input,
- V4L2_SEL_TGT_COMPOSE);
+ compose = v4l2_subdev_state_get_compose(pipe->brx->state,
+ rpf->brx_input);
left = compose->left;
top = compose->top;
}
@@ -284,6 +311,7 @@ static void rpf_configure_frame(struct vsp1_entity *entity,
static void rpf_configure_partition(struct vsp1_entity *entity,
struct vsp1_pipeline *pipe,
+ const struct vsp1_partition *partition,
struct vsp1_dl_list *dl,
struct vsp1_dl_body *dlb)
{
@@ -292,7 +320,7 @@ static void rpf_configure_partition(struct vsp1_entity *entity,
struct vsp1_device *vsp1 = rpf->entity.vsp1;
const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
const struct v4l2_pix_format_mplane *format = &rpf->format;
- struct v4l2_rect crop;
+ struct v4l2_rect crop = partition->rpf[rpf->entity.index];
/*
* Source size and crop offsets.
@@ -302,22 +330,6 @@ static void rpf_configure_partition(struct vsp1_entity *entity,
* offsets are needed, as planes 2 and 3 always have identical
* strides.
*/
- crop = *vsp1_rwpf_get_crop(rpf, rpf->entity.state);
-
- /*
- * Partition Algorithm Control
- *
- * The partition algorithm can split this frame into multiple
- * slices. We must scale our partition window based on the pipe
- * configuration to match the destination partition window.
- * To achieve this, we adjust our crop to provide a 'sub-crop'
- * matching the expected partition window. Only 'left' and
- * 'width' need to be adjusted.
- */
- if (pipe->partitions > 1) {
- crop.width = pipe->partition->rpf.width;
- crop.left += pipe->partition->rpf.left;
- }
if (pipe->interlaced) {
crop.height = round_down(crop.height / 2, fmtinfo->vsub);
@@ -366,12 +378,30 @@ static void rpf_configure_partition(struct vsp1_entity *entity,
}
static void rpf_partition(struct vsp1_entity *entity,
+ struct v4l2_subdev_state *state,
struct vsp1_pipeline *pipe,
struct vsp1_partition *partition,
unsigned int partition_idx,
- struct vsp1_partition_window *window)
+ struct v4l2_rect *window)
{
- partition->rpf = *window;
+ struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
+ struct v4l2_rect *rpf_rect = &partition->rpf[rpf->entity.index];
+
+ /*
+ * Partition Algorithm Control
+ *
+ * The partition algorithm can split this frame into multiple slices. We
+ * must adjust our partition window based on the pipe configuration to
+ * match the destination partition window. To achieve this, we adjust
+ * our crop to provide a 'sub-crop' matching the expected partition
+ * window.
+ */
+ *rpf_rect = *v4l2_subdev_state_get_crop(state, RWPF_PAD_SINK);
+
+ if (pipe->partitions > 1) {
+ rpf_rect->width = window->width;
+ rpf_rect->left += window->left;
+ }
}
static const struct vsp1_entity_operations rpf_entity_ops = {