static void lif_configure(struct vsp1_entity *entity, struct vsp1_pipeline *pipe, struct vsp1_dl_list *dl, bool full) { const struct v4l2_mbus_framefmt *format; struct vsp1_lif *lif = to_lif(&entity->subdev); unsigned int hbth = 1300; unsigned int obth = 400; unsigned int lbth = 200; if (!full) return; format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config, LIF_PAD_SOURCE); obth = min(obth, (format->width + 1) / 2 * format->height - 4); vsp1_lif_write(lif, dl, VI6_LIF_CSBTH, (hbth << VI6_LIF_CSBTH_HBTH_SHIFT) | (lbth << VI6_LIF_CSBTH_LBTH_SHIFT)); vsp1_lif_write(lif, dl, VI6_LIF_CTRL, (obth << VI6_LIF_CTRL_OBTH_SHIFT) | (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) | VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN); }
static int lif_s_stream(struct v4l2_subdev *subdev, int enable) { const struct v4l2_mbus_framefmt *format; struct vsp1_lif *lif = to_lif(subdev); unsigned int hbth = 1300; unsigned int obth = 400; unsigned int lbth = 200; if (!enable) { vsp1_lif_write(lif, VI6_LIF_CTRL, 0); return 0; } format = &lif->entity.formats[LIF_PAD_SOURCE]; obth = min(obth, (format->width + 1) / 2 * format->height - 4); vsp1_lif_write(lif, VI6_LIF_CSBTH, (hbth << VI6_LIF_CSBTH_HBTH_SHIFT) | (lbth << VI6_LIF_CSBTH_LBTH_SHIFT)); vsp1_lif_write(lif, VI6_LIF_CTRL, (obth << VI6_LIF_CTRL_OBTH_SHIFT) | (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) | VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN); return 0; }
static void lif_configure_stream(struct vsp1_entity *entity, struct vsp1_pipeline *pipe, struct vsp1_dl_body *dlb) { const struct v4l2_mbus_framefmt *format; struct vsp1_lif *lif = to_lif(&entity->subdev); unsigned int hbth; unsigned int obth; unsigned int lbth; format = vsp1_entity_get_pad_format(&lif->entity, lif->entity.config, LIF_PAD_SOURCE); switch (entity->vsp1->version & VI6_IP_VERSION_SOC_MASK) { case VI6_IP_VERSION_MODEL_VSPD_GEN2: case VI6_IP_VERSION_MODEL_VSPD_V2H: hbth = 1536; obth = min(128U, (format->width + 1) / 2 * format->height - 4); lbth = 1520; break; case VI6_IP_VERSION_MODEL_VSPDL_GEN3: case VI6_IP_VERSION_MODEL_VSPD_V3: hbth = 0; obth = 1500; lbth = 0; break; case VI6_IP_VERSION_MODEL_VSPD_GEN3: default: hbth = 0; obth = 3000; lbth = 0; break; } vsp1_lif_write(lif, dlb, VI6_LIF_CSBTH, (hbth << VI6_LIF_CSBTH_HBTH_SHIFT) | (lbth << VI6_LIF_CSBTH_LBTH_SHIFT)); vsp1_lif_write(lif, dlb, VI6_LIF_CTRL, (obth << VI6_LIF_CTRL_OBTH_SHIFT) | (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) | VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN); /* * On R-Car V3M the LIF0 buffer attribute register has to be set to a * non-default value to guarantee proper operation (otherwise artifacts * may appear on the output). The value required by the manual is not * explained but is likely a buffer size or threshold. */ if ((entity->vsp1->version & VI6_IP_VERSION_MASK) == (VI6_IP_VERSION_MODEL_VSPD_V3 | VI6_IP_VERSION_SOC_V3M)) vsp1_lif_write(lif, dlb, VI6_LIF_LBA, VI6_LIF_LBA_LBA0 | (1536 << VI6_LIF_LBA_LBA1_SHIFT)); }