root/drivers/media/platform/vsp1/vsp1_pipe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vsp1_get_format_info
  2. vsp1_pipeline_reset
  3. vsp1_pipeline_init
  4. vsp1_pipeline_run
  5. vsp1_pipeline_stopped
  6. vsp1_pipeline_stop
  7. vsp1_pipeline_ready
  8. vsp1_pipeline_frame_end
  9. vsp1_pipeline_propagate_alpha
  10. vsp1_pipeline_propagate_partition

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * vsp1_pipe.c  --  R-Car VSP1 Pipeline
   4  *
   5  * Copyright (C) 2013-2015 Renesas Electronics Corporation
   6  *
   7  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
   8  */
   9 
  10 #include <linux/delay.h>
  11 #include <linux/list.h>
  12 #include <linux/sched.h>
  13 #include <linux/wait.h>
  14 
  15 #include <media/media-entity.h>
  16 #include <media/v4l2-subdev.h>
  17 
  18 #include "vsp1.h"
  19 #include "vsp1_brx.h"
  20 #include "vsp1_dl.h"
  21 #include "vsp1_entity.h"
  22 #include "vsp1_hgo.h"
  23 #include "vsp1_hgt.h"
  24 #include "vsp1_pipe.h"
  25 #include "vsp1_rwpf.h"
  26 #include "vsp1_uds.h"
  27 
  28 /* -----------------------------------------------------------------------------
  29  * Helper Functions
  30  */
  31 
  32 static const struct vsp1_format_info vsp1_video_formats[] = {
  33         { V4L2_PIX_FMT_RGB332, MEDIA_BUS_FMT_ARGB8888_1X32,
  34           VI6_FMT_RGB_332, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  35           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
  36           1, { 8, 0, 0 }, false, false, 1, 1, false },
  37         { V4L2_PIX_FMT_ARGB444, MEDIA_BUS_FMT_ARGB8888_1X32,
  38           VI6_FMT_ARGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  39           VI6_RPF_DSWAP_P_WDS,
  40           1, { 16, 0, 0 }, false, false, 1, 1, true },
  41         { V4L2_PIX_FMT_XRGB444, MEDIA_BUS_FMT_ARGB8888_1X32,
  42           VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  43           VI6_RPF_DSWAP_P_WDS,
  44           1, { 16, 0, 0 }, false, false, 1, 1, false },
  45         { V4L2_PIX_FMT_RGBA444, MEDIA_BUS_FMT_ARGB8888_1X32,
  46           VI6_FMT_RGBA_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  47           VI6_RPF_DSWAP_P_WDS,
  48           1, { 16, 0, 0 }, false, false, 1, 1, true },
  49         { V4L2_PIX_FMT_RGBX444, MEDIA_BUS_FMT_ARGB8888_1X32,
  50           VI6_FMT_RGBX_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  51           VI6_RPF_DSWAP_P_WDS,
  52           1, { 16, 0, 0 }, false, false, 1, 1, false },
  53         { V4L2_PIX_FMT_ABGR444, MEDIA_BUS_FMT_ARGB8888_1X32,
  54           VI6_FMT_ABGR_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  55           VI6_RPF_DSWAP_P_WDS,
  56           1, { 16, 0, 0 }, false, false, 1, 1, true },
  57         { V4L2_PIX_FMT_XBGR444, MEDIA_BUS_FMT_ARGB8888_1X32,
  58           VI6_FMT_ABGR_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  59           VI6_RPF_DSWAP_P_WDS,
  60           1, { 16, 0, 0 }, false, false, 1, 1, false },
  61         { V4L2_PIX_FMT_BGRA444, MEDIA_BUS_FMT_ARGB8888_1X32,
  62           VI6_FMT_BGRA_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  63           VI6_RPF_DSWAP_P_WDS,
  64           1, { 16, 0, 0 }, false, false, 1, 1, true },
  65         { V4L2_PIX_FMT_BGRX444, MEDIA_BUS_FMT_ARGB8888_1X32,
  66           VI6_FMT_BGRA_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  67           VI6_RPF_DSWAP_P_WDS,
  68           1, { 16, 0, 0 }, false, false, 1, 1, false },
  69         { V4L2_PIX_FMT_ARGB555, MEDIA_BUS_FMT_ARGB8888_1X32,
  70           VI6_FMT_ARGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  71           VI6_RPF_DSWAP_P_WDS,
  72           1, { 16, 0, 0 }, false, false, 1, 1, true },
  73         { V4L2_PIX_FMT_XRGB555, MEDIA_BUS_FMT_ARGB8888_1X32,
  74           VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  75           VI6_RPF_DSWAP_P_WDS,
  76           1, { 16, 0, 0 }, false, false, 1, 1, false },
  77         { V4L2_PIX_FMT_RGBA555, MEDIA_BUS_FMT_ARGB8888_1X32,
  78           VI6_FMT_RGBA_5551, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  79           VI6_RPF_DSWAP_P_WDS,
  80           1, { 16, 0, 0 }, false, false, 1, 1, true },
  81         { V4L2_PIX_FMT_RGBX555, MEDIA_BUS_FMT_ARGB8888_1X32,
  82           VI6_FMT_RGBX_5551, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  83           VI6_RPF_DSWAP_P_WDS,
  84           1, { 16, 0, 0 }, false, false, 1, 1, false },
  85         { V4L2_PIX_FMT_ABGR555, MEDIA_BUS_FMT_ARGB8888_1X32,
  86           VI6_FMT_ABGR_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  87           VI6_RPF_DSWAP_P_WDS,
  88           1, { 16, 0, 0 }, false, false, 1, 1, true },
  89         { V4L2_PIX_FMT_XBGR555, MEDIA_BUS_FMT_ARGB8888_1X32,
  90           VI6_FMT_ABGR_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  91           VI6_RPF_DSWAP_P_WDS,
  92           1, { 16, 0, 0 }, false, false, 1, 1, false },
  93         { V4L2_PIX_FMT_BGRA555, MEDIA_BUS_FMT_ARGB8888_1X32,
  94           VI6_FMT_BGRA_5551, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  95           VI6_RPF_DSWAP_P_WDS,
  96           1, { 16, 0, 0 }, false, false, 1, 1, true },
  97         { V4L2_PIX_FMT_BGRX555, MEDIA_BUS_FMT_ARGB8888_1X32,
  98           VI6_FMT_BGRA_5551, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
  99           VI6_RPF_DSWAP_P_WDS,
 100           1, { 16, 0, 0 }, false, false, 1, 1, false },
 101         { V4L2_PIX_FMT_RGB565, MEDIA_BUS_FMT_ARGB8888_1X32,
 102           VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 103           VI6_RPF_DSWAP_P_WDS,
 104           1, { 16, 0, 0 }, false, false, 1, 1, false },
 105         { V4L2_PIX_FMT_BGR24, MEDIA_BUS_FMT_ARGB8888_1X32,
 106           VI6_FMT_BGR_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 107           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 108           1, { 24, 0, 0 }, false, false, 1, 1, false },
 109         { V4L2_PIX_FMT_RGB24, MEDIA_BUS_FMT_ARGB8888_1X32,
 110           VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 111           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 112           1, { 24, 0, 0 }, false, false, 1, 1, false },
 113         { V4L2_PIX_FMT_ABGR32, MEDIA_BUS_FMT_ARGB8888_1X32,
 114           VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
 115           1, { 32, 0, 0 }, false, false, 1, 1, true },
 116         { V4L2_PIX_FMT_XBGR32, MEDIA_BUS_FMT_ARGB8888_1X32,
 117           VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
 118           1, { 32, 0, 0 }, false, false, 1, 1, false },
 119         { V4L2_PIX_FMT_BGRA32, MEDIA_BUS_FMT_ARGB8888_1X32,
 120           VI6_FMT_RGBA_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
 121           1, { 32, 0, 0 }, false, false, 1, 1, true },
 122         { V4L2_PIX_FMT_BGRX32, MEDIA_BUS_FMT_ARGB8888_1X32,
 123           VI6_FMT_RGBA_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS,
 124           1, { 32, 0, 0 }, false, false, 1, 1, false },
 125         { V4L2_PIX_FMT_RGBA32, MEDIA_BUS_FMT_ARGB8888_1X32,
 126           VI6_FMT_RGBA_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 127           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 128           1, { 32, 0, 0 }, false, false, 1, 1, true },
 129         { V4L2_PIX_FMT_RGBX32, MEDIA_BUS_FMT_ARGB8888_1X32,
 130           VI6_FMT_RGBA_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 131           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 132           1, { 32, 0, 0 }, false, false, 1, 1, false },
 133         { V4L2_PIX_FMT_ARGB32, MEDIA_BUS_FMT_ARGB8888_1X32,
 134           VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 135           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 136           1, { 32, 0, 0 }, false, false, 1, 1, true },
 137         { V4L2_PIX_FMT_XRGB32, MEDIA_BUS_FMT_ARGB8888_1X32,
 138           VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 139           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 140           1, { 32, 0, 0 }, false, false, 1, 1, false },
 141         { V4L2_PIX_FMT_HSV24, MEDIA_BUS_FMT_AHSV8888_1X32,
 142           VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 143           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 144           1, { 24, 0, 0 }, false, false, 1, 1, false },
 145         { V4L2_PIX_FMT_HSV32, MEDIA_BUS_FMT_AHSV8888_1X32,
 146           VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 147           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 148           1, { 32, 0, 0 }, false, false, 1, 1, false },
 149         { V4L2_PIX_FMT_UYVY, MEDIA_BUS_FMT_AYUV8_1X32,
 150           VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 151           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 152           1, { 16, 0, 0 }, false, false, 2, 1, false },
 153         { V4L2_PIX_FMT_VYUY, MEDIA_BUS_FMT_AYUV8_1X32,
 154           VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 155           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 156           1, { 16, 0, 0 }, false, true, 2, 1, false },
 157         { V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_AYUV8_1X32,
 158           VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 159           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 160           1, { 16, 0, 0 }, true, false, 2, 1, false },
 161         { V4L2_PIX_FMT_YVYU, MEDIA_BUS_FMT_AYUV8_1X32,
 162           VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 163           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 164           1, { 16, 0, 0 }, true, true, 2, 1, false },
 165         { V4L2_PIX_FMT_NV12M, MEDIA_BUS_FMT_AYUV8_1X32,
 166           VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 167           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 168           2, { 8, 16, 0 }, false, false, 2, 2, false },
 169         { V4L2_PIX_FMT_NV21M, MEDIA_BUS_FMT_AYUV8_1X32,
 170           VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 171           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 172           2, { 8, 16, 0 }, false, true, 2, 2, false },
 173         { V4L2_PIX_FMT_NV16M, MEDIA_BUS_FMT_AYUV8_1X32,
 174           VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 175           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 176           2, { 8, 16, 0 }, false, false, 2, 1, false },
 177         { V4L2_PIX_FMT_NV61M, MEDIA_BUS_FMT_AYUV8_1X32,
 178           VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 179           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 180           2, { 8, 16, 0 }, false, true, 2, 1, false },
 181         { V4L2_PIX_FMT_YUV420M, MEDIA_BUS_FMT_AYUV8_1X32,
 182           VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 183           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 184           3, { 8, 8, 8 }, false, false, 2, 2, false },
 185         { V4L2_PIX_FMT_YVU420M, MEDIA_BUS_FMT_AYUV8_1X32,
 186           VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 187           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 188           3, { 8, 8, 8 }, false, true, 2, 2, false },
 189         { V4L2_PIX_FMT_YUV422M, MEDIA_BUS_FMT_AYUV8_1X32,
 190           VI6_FMT_Y_U_V_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 191           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 192           3, { 8, 8, 8 }, false, false, 2, 1, false },
 193         { V4L2_PIX_FMT_YVU422M, MEDIA_BUS_FMT_AYUV8_1X32,
 194           VI6_FMT_Y_U_V_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 195           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 196           3, { 8, 8, 8 }, false, true, 2, 1, false },
 197         { V4L2_PIX_FMT_YUV444M, MEDIA_BUS_FMT_AYUV8_1X32,
 198           VI6_FMT_Y_U_V_444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 199           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 200           3, { 8, 8, 8 }, false, false, 1, 1, false },
 201         { V4L2_PIX_FMT_YVU444M, MEDIA_BUS_FMT_AYUV8_1X32,
 202           VI6_FMT_Y_U_V_444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS |
 203           VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS,
 204           3, { 8, 8, 8 }, false, true, 1, 1, false },
 205 };
 206 
 207 /**
 208  * vsp1_get_format_info - Retrieve format information for a 4CC
 209  * @vsp1: the VSP1 device
 210  * @fourcc: the format 4CC
 211  *
 212  * Return a pointer to the format information structure corresponding to the
 213  * given V4L2 format 4CC, or NULL if no corresponding format can be found.
 214  */
 215 const struct vsp1_format_info *vsp1_get_format_info(struct vsp1_device *vsp1,
 216                                                     u32 fourcc)
 217 {
 218         unsigned int i;
 219 
 220         /* Special case, the VYUY and HSV formats are supported on Gen2 only. */
 221         if (vsp1->info->gen != 2) {
 222                 switch (fourcc) {
 223                 case V4L2_PIX_FMT_VYUY:
 224                 case V4L2_PIX_FMT_HSV24:
 225                 case V4L2_PIX_FMT_HSV32:
 226                         return NULL;
 227                 }
 228         }
 229 
 230         for (i = 0; i < ARRAY_SIZE(vsp1_video_formats); ++i) {
 231                 const struct vsp1_format_info *info = &vsp1_video_formats[i];
 232 
 233                 if (info->fourcc == fourcc)
 234                         return info;
 235         }
 236 
 237         return NULL;
 238 }
 239 
 240 /* -----------------------------------------------------------------------------
 241  * Pipeline Management
 242  */
 243 
 244 void vsp1_pipeline_reset(struct vsp1_pipeline *pipe)
 245 {
 246         struct vsp1_entity *entity;
 247         unsigned int i;
 248 
 249         if (pipe->brx) {
 250                 struct vsp1_brx *brx = to_brx(&pipe->brx->subdev);
 251 
 252                 for (i = 0; i < ARRAY_SIZE(brx->inputs); ++i)
 253                         brx->inputs[i].rpf = NULL;
 254         }
 255 
 256         for (i = 0; i < ARRAY_SIZE(pipe->inputs); ++i)
 257                 pipe->inputs[i] = NULL;
 258 
 259         pipe->output = NULL;
 260 
 261         list_for_each_entry(entity, &pipe->entities, list_pipe)
 262                 entity->pipe = NULL;
 263 
 264         INIT_LIST_HEAD(&pipe->entities);
 265         pipe->state = VSP1_PIPELINE_STOPPED;
 266         pipe->buffers_ready = 0;
 267         pipe->num_inputs = 0;
 268         pipe->brx = NULL;
 269         pipe->hgo = NULL;
 270         pipe->hgt = NULL;
 271         pipe->lif = NULL;
 272         pipe->uds = NULL;
 273 }
 274 
 275 void vsp1_pipeline_init(struct vsp1_pipeline *pipe)
 276 {
 277         mutex_init(&pipe->lock);
 278         spin_lock_init(&pipe->irqlock);
 279         init_waitqueue_head(&pipe->wq);
 280         kref_init(&pipe->kref);
 281 
 282         INIT_LIST_HEAD(&pipe->entities);
 283         pipe->state = VSP1_PIPELINE_STOPPED;
 284 }
 285 
 286 /* Must be called with the pipe irqlock held. */
 287 void vsp1_pipeline_run(struct vsp1_pipeline *pipe)
 288 {
 289         struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
 290 
 291         if (pipe->state == VSP1_PIPELINE_STOPPED) {
 292                 vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index),
 293                            VI6_CMD_STRCMD);
 294                 pipe->state = VSP1_PIPELINE_RUNNING;
 295         }
 296 
 297         pipe->buffers_ready = 0;
 298 }
 299 
 300 bool vsp1_pipeline_stopped(struct vsp1_pipeline *pipe)
 301 {
 302         unsigned long flags;
 303         bool stopped;
 304 
 305         spin_lock_irqsave(&pipe->irqlock, flags);
 306         stopped = pipe->state == VSP1_PIPELINE_STOPPED;
 307         spin_unlock_irqrestore(&pipe->irqlock, flags);
 308 
 309         return stopped;
 310 }
 311 
 312 int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
 313 {
 314         struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
 315         struct vsp1_entity *entity;
 316         unsigned long flags;
 317         int ret;
 318 
 319         if (pipe->lif) {
 320                 /*
 321                  * When using display lists in continuous frame mode the only
 322                  * way to stop the pipeline is to reset the hardware.
 323                  */
 324                 ret = vsp1_reset_wpf(vsp1, pipe->output->entity.index);
 325                 if (ret == 0) {
 326                         spin_lock_irqsave(&pipe->irqlock, flags);
 327                         pipe->state = VSP1_PIPELINE_STOPPED;
 328                         spin_unlock_irqrestore(&pipe->irqlock, flags);
 329                 }
 330         } else {
 331                 /* Otherwise just request a stop and wait. */
 332                 spin_lock_irqsave(&pipe->irqlock, flags);
 333                 if (pipe->state == VSP1_PIPELINE_RUNNING)
 334                         pipe->state = VSP1_PIPELINE_STOPPING;
 335                 spin_unlock_irqrestore(&pipe->irqlock, flags);
 336 
 337                 ret = wait_event_timeout(pipe->wq, vsp1_pipeline_stopped(pipe),
 338                                          msecs_to_jiffies(500));
 339                 ret = ret == 0 ? -ETIMEDOUT : 0;
 340         }
 341 
 342         list_for_each_entry(entity, &pipe->entities, list_pipe) {
 343                 if (entity->route && entity->route->reg)
 344                         vsp1_write(vsp1, entity->route->reg,
 345                                    VI6_DPR_NODE_UNUSED);
 346         }
 347 
 348         if (pipe->hgo)
 349                 vsp1_write(vsp1, VI6_DPR_HGO_SMPPT,
 350                            (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
 351                            (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
 352 
 353         if (pipe->hgt)
 354                 vsp1_write(vsp1, VI6_DPR_HGT_SMPPT,
 355                            (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
 356                            (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
 357 
 358         v4l2_subdev_call(&pipe->output->entity.subdev, video, s_stream, 0);
 359 
 360         return ret;
 361 }
 362 
 363 bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe)
 364 {
 365         unsigned int mask;
 366 
 367         mask = ((1 << pipe->num_inputs) - 1) << 1;
 368         if (!pipe->lif)
 369                 mask |= 1 << 0;
 370 
 371         return pipe->buffers_ready == mask;
 372 }
 373 
 374 void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe)
 375 {
 376         unsigned int flags;
 377 
 378         if (pipe == NULL)
 379                 return;
 380 
 381         /*
 382          * If the DL commit raced with the frame end interrupt, the commit ends
 383          * up being postponed by one frame. The returned flags tell whether the
 384          * active frame was finished or postponed.
 385          */
 386         flags = vsp1_dlm_irq_frame_end(pipe->output->dlm);
 387 
 388         if (pipe->hgo)
 389                 vsp1_hgo_frame_end(pipe->hgo);
 390 
 391         if (pipe->hgt)
 392                 vsp1_hgt_frame_end(pipe->hgt);
 393 
 394         /*
 395          * Regardless of frame completion we still need to notify the pipe
 396          * frame_end to account for vblank events.
 397          */
 398         if (pipe->frame_end)
 399                 pipe->frame_end(pipe, flags);
 400 
 401         pipe->sequence++;
 402 }
 403 
 404 /*
 405  * Propagate the alpha value through the pipeline.
 406  *
 407  * As the UDS has restricted scaling capabilities when the alpha component needs
 408  * to be scaled, we disable alpha scaling when the UDS input has a fixed alpha
 409  * value. The UDS then outputs a fixed alpha value which needs to be programmed
 410  * from the input RPF alpha.
 411  */
 412 void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
 413                                    struct vsp1_dl_body *dlb, unsigned int alpha)
 414 {
 415         if (!pipe->uds)
 416                 return;
 417 
 418         /*
 419          * The BRU and BRS background color has a fixed alpha value set to 255,
 420          * the output alpha value is thus always equal to 255.
 421          */
 422         if (pipe->uds_input->type == VSP1_ENTITY_BRU ||
 423             pipe->uds_input->type == VSP1_ENTITY_BRS)
 424                 alpha = 255;
 425 
 426         vsp1_uds_set_alpha(pipe->uds, dlb, alpha);
 427 }
 428 
 429 /*
 430  * Propagate the partition calculations through the pipeline
 431  *
 432  * Work backwards through the pipe, allowing each entity to update the partition
 433  * parameters based on its configuration, and the entity connected to its
 434  * source. Each entity must produce the partition required for the previous
 435  * entity in the pipeline.
 436  */
 437 void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
 438                                        struct vsp1_partition *partition,
 439                                        unsigned int index,
 440                                        struct vsp1_partition_window *window)
 441 {
 442         struct vsp1_entity *entity;
 443 
 444         list_for_each_entry_reverse(entity, &pipe->entities, list_pipe) {
 445                 if (entity->ops->partition)
 446                         entity->ops->partition(entity, pipe, partition, index,
 447                                                window);
 448         }
 449 }
 450 

/* [<][>][^][v][top][bottom][index][help] */