diff options
Diffstat (limited to 'drivers/media/platform/vsp1')
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_dl.c | 3 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_drm.c | 30 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_lif.c | 12 | ||||
-rw-r--r-- | drivers/media/platform/vsp1/vsp1_regs.h | 8 |
4 files changed, 38 insertions, 15 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 4257451f1bd8..0b86ed01e85d 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -509,7 +509,8 @@ static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm) return !!(vsp1_read(vsp1, VI6_DL_BODY_SIZE) & VI6_DL_BODY_SIZE_UPD); else - return !!(vsp1_read(vsp1, VI6_CMD(dlm->index) & VI6_CMD_UPDHDR)); + return !!(vsp1_read(vsp1, VI6_CMD(dlm->index)) + & VI6_CMD_UPDHDR); } static void vsp1_dl_list_hw_enqueue(struct vsp1_dl_list *dl) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 7ce69f23f50a..b8fee1834253 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -27,6 +27,7 @@ #include "vsp1_pipe.h" #include "vsp1_rwpf.h" +#define BRU_NAME(e) (e)->type == VSP1_ENTITY_BRU ? "BRU" : "BRS" /* ----------------------------------------------------------------------------- * Interrupt Handling @@ -88,7 +89,6 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, struct vsp1_entity *next; struct vsp1_dl_list *dl; struct v4l2_subdev_format format; - const char *bru_name; unsigned long flags; unsigned int i; int ret; @@ -99,7 +99,6 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, drm_pipe = &vsp1->drm->pipe[pipe_index]; pipe = &drm_pipe->pipe; bru = to_bru(&pipe->bru->subdev); - bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"; if (!cfg) { /* @@ -165,7 +164,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", __func__, format.format.width, format.format.height, - format.format.code, bru_name, i); + format.format.code, BRU_NAME(pipe->bru), i); } format.pad = pipe->bru->source_pad; @@ -181,7 +180,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index, dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", __func__, format.format.width, format.format.height, - format.format.code, bru_name, i); + format.format.code, BRU_NAME(pipe->bru), i); format.pad = RWPF_PAD_SINK; ret = v4l2_subdev_call(&pipe->output->entity.subdev, pad, set_fmt, NULL, @@ -473,9 +472,9 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1, if (ret < 0) return ret; - dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on BRU pad %u\n", + dev_dbg(vsp1->dev, "%s: set format %ux%u (%x) on %s pad %u\n", __func__, format.format.width, format.format.height, - format.format.code, format.pad); + format.format.code, BRU_NAME(pipe->bru), format.pad); sel.pad = bru_input; sel.target = V4L2_SEL_TGT_COMPOSE; @@ -486,10 +485,9 @@ static int vsp1_du_setup_rpf_pipe(struct vsp1_device *vsp1, if (ret < 0) return ret; - dev_dbg(vsp1->dev, - "%s: set selection (%u,%u)/%ux%u on BRU pad %u\n", + dev_dbg(vsp1->dev, "%s: set selection (%u,%u)/%ux%u on %s pad %u\n", __func__, sel.r.left, sel.r.top, sel.r.width, sel.r.height, - sel.pad); + BRU_NAME(pipe->bru), sel.pad); return 0; } @@ -514,12 +512,9 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index) struct vsp1_entity *entity; struct vsp1_entity *next; struct vsp1_dl_list *dl; - const char *bru_name; unsigned int i; int ret; - bru_name = pipe->bru->type == VSP1_ENTITY_BRU ? "BRU" : "BRS"; - /* Prepare the display list. */ dl = vsp1_dl_list_get(pipe->output->dlm); @@ -530,6 +525,15 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index) struct vsp1_rwpf *rpf = vsp1->rpf[i]; unsigned int j; + /* + * Make sure we don't accept more inputs than the hardware can + * handle. This is a temporary fix to avoid display stall, we + * need to instead allocate the BRU or BRS to display pipelines + * dynamically based on the number of planes they each use. + */ + if (pipe->num_inputs >= pipe->bru->source_pad) + pipe->inputs[i] = NULL; + if (!pipe->inputs[i]) continue; @@ -561,7 +565,7 @@ void vsp1_du_atomic_flush(struct device *dev, unsigned int pipe_index) rpf->entity.sink_pad = i; dev_dbg(vsp1->dev, "%s: connecting RPF.%u to %s:%u\n", - __func__, rpf->entity.index, bru_name, i); + __func__, rpf->entity.index, BRU_NAME(pipe->bru), i); ret = vsp1_du_setup_rpf_pipe(vsp1, pipe, rpf, i); if (ret < 0) diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c index e6fa16d7fda8..704920753998 100644 --- a/drivers/media/platform/vsp1/vsp1_lif.c +++ b/drivers/media/platform/vsp1/vsp1_lif.c @@ -155,6 +155,18 @@ static void lif_configure(struct vsp1_entity *entity, (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, dl, VI6_LIF_LBA, + VI6_LIF_LBA_LBA0 | + (1536 << VI6_LIF_LBA_LBA1_SHIFT)); } static const struct vsp1_entity_operations lif_entity_ops = { diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index 26c4ffad2f46..dae0c1901297 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h @@ -225,7 +225,7 @@ #define VI6_RPF_MULT_ALPHA_P_MMD_RATIO (1 << 8) #define VI6_RPF_MULT_ALPHA_P_MMD_IMAGE (2 << 8) #define VI6_RPF_MULT_ALPHA_P_MMD_BOTH (3 << 8) -#define VI6_RPF_MULT_ALPHA_RATIO_MASK (0xff < 0) +#define VI6_RPF_MULT_ALPHA_RATIO_MASK (0xff << 0) #define VI6_RPF_MULT_ALPHA_RATIO_SHIFT 0 /* ----------------------------------------------------------------------------- @@ -693,6 +693,11 @@ #define VI6_LIF_CSBTH_LBTH_MASK (0x7ff << 0) #define VI6_LIF_CSBTH_LBTH_SHIFT 0 +#define VI6_LIF_LBA 0x3b0c +#define VI6_LIF_LBA_LBA0 (1 << 31) +#define VI6_LIF_LBA_LBA1_MASK (0xfff << 16) +#define VI6_LIF_LBA_LBA1_SHIFT 16 + /* ----------------------------------------------------------------------------- * Security Control Registers */ @@ -705,6 +710,7 @@ */ #define VI6_IP_VERSION 0x3f00 +#define VI6_IP_VERSION_MASK (0xffff << 0) #define VI6_IP_VERSION_MODEL_MASK (0xff << 8) #define VI6_IP_VERSION_MODEL_VSPS_H2 (0x09 << 8) #define VI6_IP_VERSION_MODEL_VSPR_H2 (0x0a << 8) |