1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Cedrus VPU driver 4 * 5 * Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com> 6 * Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com> 7 * Copyright (C) 2018 Bootlin 8 * 9 * Based on the vim2m driver, that is: 10 * 11 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. 12 * Pawel Osciak, <pawel@osciak.com> 13 * Marek Szyprowski, <m.szyprowski@samsung.com> 14 */ 15 16#include <media/v4l2-device.h> 17#include <media/v4l2-ioctl.h> 18#include <media/v4l2-event.h> 19#include <media/v4l2-mem2mem.h> 20 21#include "cedrus.h" 22#include "cedrus_dec.h" 23#include "cedrus_hw.h" 24 25void cedrus_device_run(void *priv) 26{ 27 struct cedrus_ctx *ctx = priv; 28 struct cedrus_dev *dev = ctx->dev; 29 struct cedrus_run run = {}; 30 struct media_request *src_req; 31 int error; 32 33 run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 34 run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 35 36 /* Apply request(s) controls if needed. */ 37 src_req = run.src->vb2_buf.req_obj.req; 38 39 if (src_req) 40 v4l2_ctrl_request_setup(src_req, &ctx->hdl); 41 42 switch (ctx->src_fmt.pixelformat) { 43 case V4L2_PIX_FMT_MPEG2_SLICE: 44 run.mpeg2.sequence = cedrus_find_control_data(ctx, 45 V4L2_CID_STATELESS_MPEG2_SEQUENCE); 46 run.mpeg2.picture = cedrus_find_control_data(ctx, 47 V4L2_CID_STATELESS_MPEG2_PICTURE); 48 run.mpeg2.quantisation = cedrus_find_control_data(ctx, 49 V4L2_CID_STATELESS_MPEG2_QUANTISATION); 50 break; 51 52 case V4L2_PIX_FMT_H264_SLICE: 53 run.h264.decode_params = cedrus_find_control_data(ctx, 54 V4L2_CID_STATELESS_H264_DECODE_PARAMS); 55 run.h264.pps = cedrus_find_control_data(ctx, 56 V4L2_CID_STATELESS_H264_PPS); 57 run.h264.scaling_matrix = cedrus_find_control_data(ctx, 58 V4L2_CID_STATELESS_H264_SCALING_MATRIX); 59 run.h264.slice_params = cedrus_find_control_data(ctx, 60 V4L2_CID_STATELESS_H264_SLICE_PARAMS); 61 run.h264.sps = cedrus_find_control_data(ctx, 62 V4L2_CID_STATELESS_H264_SPS); 63 run.h264.pred_weights = cedrus_find_control_data(ctx, 64 V4L2_CID_STATELESS_H264_PRED_WEIGHTS); 65 break; 66 67 case V4L2_PIX_FMT_HEVC_SLICE: 68 run.h265.sps = cedrus_find_control_data(ctx, 69 V4L2_CID_STATELESS_HEVC_SPS); 70 run.h265.pps = cedrus_find_control_data(ctx, 71 V4L2_CID_STATELESS_HEVC_PPS); 72 run.h265.slice_params = cedrus_find_control_data(ctx, 73 V4L2_CID_STATELESS_HEVC_SLICE_PARAMS); 74 run.h265.decode_params = cedrus_find_control_data(ctx, 75 V4L2_CID_STATELESS_HEVC_DECODE_PARAMS); 76 run.h265.scaling_matrix = cedrus_find_control_data(ctx, 77 V4L2_CID_STATELESS_HEVC_SCALING_MATRIX); 78 run.h265.entry_points = cedrus_find_control_data(ctx, 79 V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS); 80 run.h265.entry_points_count = cedrus_get_num_of_controls(ctx, 81 V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS); 82 break; 83 84 case V4L2_PIX_FMT_VP8_FRAME: 85 run.vp8.frame_params = cedrus_find_control_data(ctx, 86 V4L2_CID_STATELESS_VP8_FRAME); 87 break; 88 89 default: 90 break; 91 } 92 93 v4l2_m2m_buf_copy_metadata(run.src, run.dst, true); 94 95 cedrus_dst_format_set(dev, &ctx->dst_fmt); 96 97 error = ctx->current_codec->setup(ctx, &run); 98 if (error) 99 v4l2_err(&ctx->dev->v4l2_dev, 100 "Failed to setup decoding job: %d\n", error); 101 102 /* Complete request(s) controls if needed. */ 103 104 if (src_req) 105 v4l2_ctrl_request_complete(src_req, &ctx->hdl); 106 107 /* Trigger decoding if setup went well, bail out otherwise. */ 108 if (!error) { 109 /* Start the watchdog timer. */ 110 schedule_delayed_work(&dev->watchdog_work, 111 msecs_to_jiffies(2000)); 112 113 ctx->current_codec->trigger(ctx); 114 } else { 115 v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, 116 ctx->fh.m2m_ctx, 117 VB2_BUF_STATE_ERROR); 118 } 119} 120