summaryrefslogtreecommitdiff
path: root/drivers/media/platform/sti/hva
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@kernel.org>2022-03-14 12:43:10 +0100
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-03-18 05:58:34 +0100
commite7b8153e2a4f0c9c8d1450aa7328d54ea64fe8b2 (patch)
tree66b31cbad2bcee3f115a8c910cfebefcb9f4e048 /drivers/media/platform/sti/hva
parent43ecec16c4face9a59e81771e7cbff4671c62117 (diff)
media: platform: place stm32/ and sti/ under st/ dir
As the end goal is to have platform drivers split by vendor, move both stm32/ and sti/ for them to be inside st/ directory. Acked-by: Hugues Fruchet <hugues.fruchet@st.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/platform/sti/hva')
-rw-r--r--drivers/media/platform/sti/hva/Kconfig26
-rw-r--r--drivers/media/platform/sti/hva/Makefile4
-rw-r--r--drivers/media/platform/sti/hva/hva-debugfs.c396
-rw-r--r--drivers/media/platform/sti/hva/hva-h264.c1063
-rw-r--r--drivers/media/platform/sti/hva/hva-hw.c585
-rw-r--r--drivers/media/platform/sti/hva/hva-hw.h45
-rw-r--r--drivers/media/platform/sti/hva/hva-mem.c62
-rw-r--r--drivers/media/platform/sti/hva/hva-mem.h34
-rw-r--r--drivers/media/platform/sti/hva/hva-v4l2.c1476
-rw-r--r--drivers/media/platform/sti/hva/hva.h409
10 files changed, 0 insertions, 4100 deletions
diff --git a/drivers/media/platform/sti/hva/Kconfig b/drivers/media/platform/sti/hva/Kconfig
deleted file mode 100644
index 5651667bcc54..000000000000
--- a/drivers/media/platform/sti/hva/Kconfig
+++ /dev/null
@@ -1,26 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config VIDEO_STI_HVA
- tristate "STMicroelectronics HVA multi-format video encoder V4L2 driver"
- depends on V4L_MEM2MEM_DRIVERS
- depends on VIDEO_DEV && VIDEO_V4L2
- depends on ARCH_STI || COMPILE_TEST
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- help
- This V4L2 driver enables HVA (Hardware Video Accelerator) multi-format
- video encoder of STMicroelectronics SoC, allowing hardware encoding of
- raw uncompressed formats in various compressed video bitstreams format.
-
- To compile this driver as a module, choose M here:
- the module will be called st-hva.
-
-config VIDEO_STI_HVA_DEBUGFS
- bool "Export STMicroelectronics HVA internals in debugfs"
- depends on VIDEO_STI_HVA
- depends on DEBUG_FS
- help
- Select this to see information about the internal state and the last
- operation of STMicroelectronics HVA multi-format video encoder in
- debugfs.
-
- Choose N unless you know you need this.
diff --git a/drivers/media/platform/sti/hva/Makefile b/drivers/media/platform/sti/hva/Makefile
deleted file mode 100644
index b5a5478bdd01..000000000000
--- a/drivers/media/platform/sti/hva/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_VIDEO_STI_HVA) += st-hva.o
-st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o hva-h264.o
-st-hva-$(CONFIG_VIDEO_STI_HVA_DEBUGFS) += hva-debugfs.o
diff --git a/drivers/media/platform/sti/hva/hva-debugfs.c b/drivers/media/platform/sti/hva/hva-debugfs.c
deleted file mode 100644
index a86a07b6fbc7..000000000000
--- a/drivers/media/platform/sti/hva/hva-debugfs.c
+++ /dev/null
@@ -1,396 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) STMicroelectronics SA 2015
- * Authors: Yannick Fertre <yannick.fertre@st.com>
- * Hugues Fruchet <hugues.fruchet@st.com>
- */
-
-#include <linux/debugfs.h>
-
-#include "hva.h"
-#include "hva-hw.h"
-
-static void format_ctx(struct seq_file *s, struct hva_ctx *ctx)
-{
- struct hva_streaminfo *stream = &ctx->streaminfo;
- struct hva_frameinfo *frame = &ctx->frameinfo;
- struct hva_controls *ctrls = &ctx->ctrls;
- struct hva_ctx_dbg *dbg = &ctx->dbg;
- u32 bitrate_mode, aspect, entropy, vui_sar, sei_fp;
-
- seq_printf(s, "|-%s\n |\n", ctx->name);
-
- seq_printf(s, " |-[%sframe info]\n",
- ctx->flags & HVA_FLAG_FRAMEINFO ? "" : "default ");
- seq_printf(s, " | |- pixel format=%4.4s\n"
- " | |- wxh=%dx%d\n"
- " | |- wxh (w/ encoder alignment constraint)=%dx%d\n"
- " |\n",
- (char *)&frame->pixelformat,
- frame->width, frame->height,
- frame->aligned_width, frame->aligned_height);
-
- seq_printf(s, " |-[%sstream info]\n",
- ctx->flags & HVA_FLAG_STREAMINFO ? "" : "default ");
- seq_printf(s, " | |- stream format=%4.4s\n"
- " | |- wxh=%dx%d\n"
- " | |- %s\n"
- " | |- %s\n"
- " |\n",
- (char *)&stream->streamformat,
- stream->width, stream->height,
- stream->profile, stream->level);
-
- bitrate_mode = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
- aspect = V4L2_CID_MPEG_VIDEO_ASPECT;
- seq_puts(s, " |-[parameters]\n");
- seq_printf(s, " | |- %s\n"
- " | |- bitrate=%d bps\n"
- " | |- GOP size=%d\n"
- " | |- video aspect=%s\n"
- " | |- framerate=%d/%d\n",
- v4l2_ctrl_get_menu(bitrate_mode)[ctrls->bitrate_mode],
- ctrls->bitrate,
- ctrls->gop_size,
- v4l2_ctrl_get_menu(aspect)[ctrls->aspect],
- ctrls->time_per_frame.denominator,
- ctrls->time_per_frame.numerator);
-
- entropy = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
- vui_sar = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC;
- sei_fp = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE;
- if (stream->streamformat == V4L2_PIX_FMT_H264) {
- seq_printf(s, " | |- %s entropy mode\n"
- " | |- CPB size=%d kB\n"
- " | |- DCT8x8 enable=%s\n"
- " | |- qpmin=%d\n"
- " | |- qpmax=%d\n"
- " | |- PAR enable=%s\n"
- " | |- PAR id=%s\n"
- " | |- SEI frame packing enable=%s\n"
- " | |- SEI frame packing type=%s\n",
- v4l2_ctrl_get_menu(entropy)[ctrls->entropy_mode],
- ctrls->cpb_size,
- ctrls->dct8x8 ? "true" : "false",
- ctrls->qpmin,
- ctrls->qpmax,
- ctrls->vui_sar ? "true" : "false",
- v4l2_ctrl_get_menu(vui_sar)[ctrls->vui_sar_idc],
- ctrls->sei_fp ? "true" : "false",
- v4l2_ctrl_get_menu(sei_fp)[ctrls->sei_fp_type]);
- }
-
- if (ctx->sys_errors || ctx->encode_errors || ctx->frame_errors) {
- seq_puts(s, " |\n |-[errors]\n");
- seq_printf(s, " | |- system=%d\n"
- " | |- encoding=%d\n"
- " | |- frame=%d\n",
- ctx->sys_errors,
- ctx->encode_errors,
- ctx->frame_errors);
- }
-
- seq_puts(s, " |\n |-[performances]\n");
- seq_printf(s, " | |- frames encoded=%d\n"
- " | |- avg HW processing duration (0.1ms)=%d [min=%d, max=%d]\n"
- " | |- avg encoding period (0.1ms)=%d [min=%d, max=%d]\n"
- " | |- avg fps (0.1Hz)=%d\n"
- " | |- max reachable fps (0.1Hz)=%d\n"
- " | |- avg bitrate (kbps)=%d [min=%d, max=%d]\n"
- " | |- last bitrate (kbps)=%d\n",
- dbg->cnt_duration,
- dbg->avg_duration,
- dbg->min_duration,
- dbg->max_duration,
- dbg->avg_period,
- dbg->min_period,
- dbg->max_period,
- dbg->avg_fps,
- dbg->max_fps,
- dbg->avg_bitrate,
- dbg->min_bitrate,
- dbg->max_bitrate,
- dbg->last_bitrate);
-}
-
-/*
- * performance debug info
- */
-void hva_dbg_perf_begin(struct hva_ctx *ctx)
-{
- u64 div;
- u32 period;
- u32 bitrate;
- struct hva_ctx_dbg *dbg = &ctx->dbg;
- ktime_t prev = dbg->begin;
-
- dbg->begin = ktime_get();
-
- if (dbg->is_valid_period) {
- /* encoding period */
- div = (u64)ktime_us_delta(dbg->begin, prev);
- do_div(div, 100);
- period = (u32)div;
- dbg->min_period = min(period, dbg->min_period);
- dbg->max_period = max(period, dbg->max_period);
- dbg->total_period += period;
- dbg->cnt_period++;
-
- /*
- * minimum and maximum bitrates are based on the
- * encoding period values upon a window of 32 samples
- */
- dbg->window_duration += period;
- dbg->cnt_window++;
- if (dbg->cnt_window >= 32) {
- /*
- * bitrate in kbps = (size * 8 / 1000) /
- * (duration / 10000)
- * = size * 80 / duration
- */
- if (dbg->window_duration > 0) {
- div = (u64)dbg->window_stream_size * 80;
- do_div(div, dbg->window_duration);
- bitrate = (u32)div;
- dbg->last_bitrate = bitrate;
- dbg->min_bitrate = min(bitrate,
- dbg->min_bitrate);
- dbg->max_bitrate = max(bitrate,
- dbg->max_bitrate);
- }
- dbg->window_stream_size = 0;
- dbg->window_duration = 0;
- dbg->cnt_window = 0;
- }
- }
-
- /*
- * filter sequences valid for performance:
- * - begin/begin (no stream available) is an invalid sequence
- * - begin/end is a valid sequence
- */
- dbg->is_valid_period = false;
-}
-
-void hva_dbg_perf_end(struct hva_ctx *ctx, struct hva_stream *stream)
-{
- struct device *dev = ctx_to_dev(ctx);
- u64 div;
- u32 duration;
- u32 bytesused;
- u32 timestamp;
- struct hva_ctx_dbg *dbg = &ctx->dbg;
- ktime_t end = ktime_get();
-
- /* stream bytesused and timestamp in us */
- bytesused = vb2_get_plane_payload(&stream->vbuf.vb2_buf, 0);
- div = stream->vbuf.vb2_buf.timestamp;
- do_div(div, 1000);
- timestamp = (u32)div;
-
- /* encoding duration */
- div = (u64)ktime_us_delta(end, dbg->begin);
-
- dev_dbg(dev,
- "%s perf stream[%d] dts=%d encoded using %d bytes in %d us",
- ctx->name,
- stream->vbuf.sequence,
- timestamp,
- bytesused, (u32)div);
-
- do_div(div, 100);
- duration = (u32)div;
-
- dbg->min_duration = min(duration, dbg->min_duration);
- dbg->max_duration = max(duration, dbg->max_duration);
- dbg->total_duration += duration;
- dbg->cnt_duration++;
-
- /*
- * the average bitrate is based on the total stream size
- * and the total encoding periods
- */
- dbg->total_stream_size += bytesused;
- dbg->window_stream_size += bytesused;
-
- dbg->is_valid_period = true;
-}
-
-static void hva_dbg_perf_compute(struct hva_ctx *ctx)
-{
- u64 div;
- struct hva_ctx_dbg *dbg = &ctx->dbg;
-
- if (dbg->cnt_duration > 0) {
- div = (u64)dbg->total_duration;
- do_div(div, dbg->cnt_duration);
- dbg->avg_duration = (u32)div;
- } else {
- dbg->avg_duration = 0;
- }
-
- if (dbg->total_duration > 0) {
- div = (u64)dbg->cnt_duration * 100000;
- do_div(div, dbg->total_duration);
- dbg->max_fps = (u32)div;
- } else {
- dbg->max_fps = 0;
- }
-
- if (dbg->cnt_period > 0) {
- div = (u64)dbg->total_period;
- do_div(div, dbg->cnt_period);
- dbg->avg_period = (u32)div;
- } else {
- dbg->avg_period = 0;
- }
-
- if (dbg->total_period > 0) {
- div = (u64)dbg->cnt_period * 100000;
- do_div(div, dbg->total_period);
- dbg->avg_fps = (u32)div;
- } else {
- dbg->avg_fps = 0;
- }
-
- if (dbg->total_period > 0) {
- /*
- * bitrate in kbps = (video size * 8 / 1000) /
- * (video duration / 10000)
- * = video size * 80 / video duration
- */
- div = (u64)dbg->total_stream_size * 80;
- do_div(div, dbg->total_period);
- dbg->avg_bitrate = (u32)div;
- } else {
- dbg->avg_bitrate = 0;
- }
-}
-
-/*
- * device debug info
- */
-
-static int device_show(struct seq_file *s, void *data)
-{
- struct hva_dev *hva = s->private;
-
- seq_printf(s, "[%s]\n", hva->v4l2_dev.name);
- seq_printf(s, "registered as /dev/video%d\n", hva->vdev->num);
-
- return 0;
-}
-
-static int encoders_show(struct seq_file *s, void *data)
-{
- struct hva_dev *hva = s->private;
- unsigned int i = 0;
-
- seq_printf(s, "[encoders]\n|- %d registered encoders:\n",
- hva->nb_of_encoders);
-
- while (hva->encoders[i]) {
- seq_printf(s, "|- %s: %4.4s => %4.4s\n", hva->encoders[i]->name,
- (char *)&hva->encoders[i]->pixelformat,
- (char *)&hva->encoders[i]->streamformat);
- i++;
- }
-
- return 0;
-}
-
-static int last_show(struct seq_file *s, void *data)
-{
- struct hva_dev *hva = s->private;
- struct hva_ctx *last_ctx = &hva->dbg.last_ctx;
-
- if (last_ctx->flags & HVA_FLAG_STREAMINFO) {
- seq_puts(s, "[last encoding]\n");
-
- hva_dbg_perf_compute(last_ctx);
- format_ctx(s, last_ctx);
- } else {
- seq_puts(s, "[no information recorded about last encoding]\n");
- }
-
- return 0;
-}
-
-static int regs_show(struct seq_file *s, void *data)
-{
- struct hva_dev *hva = s->private;
-
- hva_hw_dump_regs(hva, s);
-
- return 0;
-}
-
-#define hva_dbg_create_entry(name) \
- debugfs_create_file(#name, 0444, hva->dbg.debugfs_entry, hva, \
- &name##_fops)
-
-DEFINE_SHOW_ATTRIBUTE(device);
-DEFINE_SHOW_ATTRIBUTE(encoders);
-DEFINE_SHOW_ATTRIBUTE(last);
-DEFINE_SHOW_ATTRIBUTE(regs);
-
-void hva_debugfs_create(struct hva_dev *hva)
-{
- hva->dbg.debugfs_entry = debugfs_create_dir(HVA_NAME, NULL);
-
- hva_dbg_create_entry(device);
- hva_dbg_create_entry(encoders);
- hva_dbg_create_entry(last);
- hva_dbg_create_entry(regs);
-}
-
-void hva_debugfs_remove(struct hva_dev *hva)
-{
- debugfs_remove_recursive(hva->dbg.debugfs_entry);
- hva->dbg.debugfs_entry = NULL;
-}
-
-/*
- * context (instance) debug info
- */
-
-static int ctx_show(struct seq_file *s, void *data)
-{
- struct hva_ctx *ctx = s->private;
-
- seq_printf(s, "[running encoding %d]\n", ctx->id);
-
- hva_dbg_perf_compute(ctx);
- format_ctx(s, ctx);
-
- return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(ctx);
-
-void hva_dbg_ctx_create(struct hva_ctx *ctx)
-{
- struct hva_dev *hva = ctx->hva_dev;
- char name[4] = "";
-
- ctx->dbg.min_duration = UINT_MAX;
- ctx->dbg.min_period = UINT_MAX;
- ctx->dbg.min_bitrate = UINT_MAX;
-
- snprintf(name, sizeof(name), "%d", hva->instance_id);
-
- ctx->dbg.debugfs_entry = debugfs_create_file(name, 0444,
- hva->dbg.debugfs_entry,
- ctx, &ctx_fops);
-}
-
-void hva_dbg_ctx_remove(struct hva_ctx *ctx)
-{
- struct hva_dev *hva = ctx->hva_dev;
-
- if (ctx->flags & HVA_FLAG_STREAMINFO)
- /* save context before removing */
- memcpy(&hva->dbg.last_ctx, ctx, sizeof(*ctx));
-
- debugfs_remove(ctx->dbg.debugfs_entry);
-}
diff --git a/drivers/media/platform/sti/hva/hva-h264.c b/drivers/media/platform/sti/hva/hva-h264.c
deleted file mode 100644
index 98cb00d2d868..000000000000
--- a/drivers/media/platform/sti/hva/hva-h264.c
+++ /dev/null
@@ -1,1063 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) STMicroelectronics SA 2015
- * Authors: Yannick Fertre <yannick.fertre@st.com>
- * Hugues Fruchet <hugues.fruchet@st.com>
- */
-
-#include "hva.h"
-#include "hva-hw.h"
-
-#define MAX_SPS_PPS_SIZE 128
-
-#define BITSTREAM_OFFSET_MASK 0x7F
-
-/* video max size*/
-#define H264_MAX_SIZE_W 1920
-#define H264_MAX_SIZE_H 1920
-
-/* macroBlocs number (width & height) */
-#define MB_W(w) ((w + 0xF) / 0x10)
-#define MB_H(h) ((h + 0xF) / 0x10)
-
-/* formula to get temporal or spatial data size */
-#define DATA_SIZE(w, h) (MB_W(w) * MB_H(h) * 16)
-
-#define SEARCH_WINDOW_BUFFER_MAX_SIZE(w) ((4 * MB_W(w) + 42) * 256 * 3 / 2)
-#define CABAC_CONTEXT_BUFFER_MAX_SIZE(w) (MB_W(w) * 16)
-#define CTX_MB_BUFFER_MAX_SIZE(w) (MB_W(w) * 16 * 8)
-#define SLICE_HEADER_SIZE (4 * 16)
-#define BRC_DATA_SIZE (5 * 16)
-
-/* source buffer copy in YUV 420 MB-tiled format with size=16*256*3/2 */
-#define CURRENT_WINDOW_BUFFER_MAX_SIZE (16 * 256 * 3 / 2)
-
-/*
- * 4 lines of pixels (in Luma, Chroma blue and Chroma red) of top MB
- * for deblocking with size=4*16*MBx*2
- */
-#define LOCAL_RECONSTRUCTED_BUFFER_MAX_SIZE(w) (4 * 16 * MB_W(w) * 2)
-
-/* factor for bitrate and cpb buffer size max values if profile >= high */
-#define H264_FACTOR_HIGH 1200
-
-/* factor for bitrate and cpb buffer size max values if profile < high */
-#define H264_FACTOR_BASELINE 1000
-
-/* number of bytes for NALU_TYPE_FILLER_DATA header and footer */
-#define H264_FILLER_DATA_SIZE 6
-
-struct h264_profile {
- enum v4l2_mpeg_video_h264_level level;
- u32 max_mb_per_seconds;
- u32 max_frame_size;
- u32 max_bitrate;
- u32 max_cpb_size;
- u32 min_comp_ratio;
-};
-
-static const struct h264_profile h264_infos_list[] = {
- {V4L2_MPEG_VIDEO_H264_LEVEL_1_0, 1485, 99, 64, 175, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_1B, 1485, 99, 128, 350, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_1_1, 3000, 396, 192, 500, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_1_2, 6000, 396, 384, 1000, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_1_3, 11880, 396, 768, 2000, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_2_0, 11880, 396, 2000, 2000, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_2_1, 19800, 792, 4000, 4000, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_2_2, 20250, 1620, 4000, 4000, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_3_0, 40500, 1620, 10000, 10000, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_3_1, 108000, 3600, 14000, 14000, 4},
- {V4L2_MPEG_VIDEO_H264_LEVEL_3_2, 216000, 5120, 20000, 20000, 4},
- {V4L2_MPEG_VIDEO_H264_LEVEL_4_0, 245760, 8192, 20000, 25000, 4},
- {V4L2_MPEG_VIDEO_H264_LEVEL_4_1, 245760, 8192, 50000, 62500, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_4_2, 522240, 8704, 50000, 62500, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_5_0, 589824, 22080, 135000, 135000, 2},
- {V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 983040, 36864, 240000, 240000, 2}
-};
-
-enum hva_brc_type {
- BRC_TYPE_NONE = 0,
- BRC_TYPE_CBR = 1,
- BRC_TYPE_VBR = 2,
- BRC_TYPE_VBR_LOW_DELAY = 3
-};
-
-enum hva_entropy_coding_mode {
- CAVLC = 0,
- CABAC = 1
-};
-
-enum hva_picture_coding_type {
- PICTURE_CODING_TYPE_I = 0,
- PICTURE_CODING_TYPE_P = 1,
- PICTURE_CODING_TYPE_B = 2
-};
-
-enum hva_h264_sampling_mode {
- SAMPLING_MODE_NV12 = 0,
- SAMPLING_MODE_UYVY = 1,
- SAMPLING_MODE_RGB3 = 3,
- SAMPLING_MODE_XRGB4 = 4,
- SAMPLING_MODE_NV21 = 8,
- SAMPLING_MODE_VYUY = 9,
- SAMPLING_MODE_BGR3 = 11,
- SAMPLING_MODE_XBGR4 = 12,
- SAMPLING_MODE_RGBX4 = 20,
- SAMPLING_MODE_BGRX4 = 28
-};
-
-enum hva_h264_nalu_type {
- NALU_TYPE_UNKNOWN = 0,
- NALU_TYPE_SLICE = 1,
- NALU_TYPE_SLICE_DPA = 2,
- NALU_TYPE_SLICE_DPB = 3,
- NALU_TYPE_SLICE_DPC = 4,
- NALU_TYPE_SLICE_IDR = 5,
- NALU_TYPE_SEI = 6,
- NALU_TYPE_SPS = 7,
- NALU_TYPE_PPS = 8,
- NALU_TYPE_AU_DELIMITER = 9,
- NALU_TYPE_SEQ_END = 10,
- NALU_TYPE_STREAM_END = 11,
- NALU_TYPE_FILLER_DATA = 12,
- NALU_TYPE_SPS_EXT = 13,
- NALU_TYPE_PREFIX_UNIT = 14,
- NALU_TYPE_SUBSET_SPS = 15,
- NALU_TYPE_SLICE_AUX = 19,
- NALU_TYPE_SLICE_EXT = 20
-};
-
-enum hva_h264_sei_payload_type {
- SEI_BUFFERING_PERIOD = 0,
- SEI_PICTURE_TIMING = 1,
- SEI_STEREO_VIDEO_INFO = 21,
- SEI_FRAME_PACKING_ARRANGEMENT = 45
-};
-
-/*
- * stereo Video Info struct
- */
-struct hva_h264_stereo_video_sei {
- u8 field_views_flag;
- u8 top_field_is_left_view_flag;
- u8 current_frame_is_left_view_flag;
- u8 next_frame_is_second_view_flag;
- u8 left_view_self_contained_flag;
- u8 right_view_self_contained_flag;
-};
-
-/*
- * struct hva_h264_td
- *
- * @frame_width: width in pixels of the buffer containing the input frame
- * @frame_height: height in pixels of the buffer containing the input frame
- * @frame_num: the parameter to be written in the slice header
- * @picture_coding_type: type I, P or B
- * @pic_order_cnt_type: POC mode, as defined in H264 std : can be 0,1,2
- * @first_picture_in_sequence: flag telling to encoder that this is the
- * first picture in a video sequence.
- * Used for VBR
- * @slice_size_type: 0 = no constraint to close the slice
- * 1= a slice is closed as soon as the slice_mb_size limit
- * is reached
- * 2= a slice is closed as soon as the slice_byte_size limit
- * is reached
- * 3= a slice is closed as soon as either the slice_byte_size
- * limit or the slice_mb_size limit is reached
- * @slice_mb_size: defines the slice size in number of macroblocks
- * (used when slice_size_type=1 or slice_size_type=3)
- * @ir_param_option: defines the number of macroblocks per frame to be
- * refreshed by AIR algorithm OR the refresh period
- * by CIR algorithm
- * @intra_refresh_type: enables the adaptive intra refresh algorithm.
- * Disable=0 / Adaptative=1 and Cycle=2 as intra refresh
- * @use_constrained_intra_flag: constrained_intra_pred_flag from PPS
- * @transform_mode: controls the use of 4x4/8x8 transform mode
- * @disable_deblocking_filter_idc:
- * 0: specifies that all luma and chroma block edges of
- * the slice are filtered.
- * 1: specifies that deblocking is disabled for all block
- * edges of the slice.
- * 2: specifies that all luma and chroma block edges of
- * the slice are filtered with exception of the block edges
- * that coincide with slice boundaries
- * @slice_alpha_c0_offset_div2: to be written in slice header,
- * controls deblocking
- * @slice_beta_offset_div2: to be written in slice header,
- * controls deblocking
- * @encoder_complexity: encoder complexity control (IME).
- * 0 = I_16x16, P_16x16, Full ME Complexity
- * 1 = I_16x16, I_NxN, P_16x16, Full ME Complexity
- * 2 = I_16x16, I_NXN, P_16x16, P_WxH, Full ME Complexity
- * 4 = I_16x16, P_16x16, Reduced ME Complexity
- * 5 = I_16x16, I_NxN, P_16x16, Reduced ME Complexity
- * 6 = I_16x16, I_NXN, P_16x16, P_WxH, Reduced ME Complexity
- * @chroma_qp_index_offset: coming from picture parameter set
- * (PPS see [H.264 STD] 7.4.2.2)
- * @entropy_coding_mode: entropy coding mode.
- * 0 = CAVLC
- * 1 = CABAC
- * @brc_type: selects the bit-rate control algorithm
- * 0 = constant Qp, (no BRC)
- * 1 = CBR
- * 2 = VBR
- * @quant: Quantization param used in case of fix QP encoding (no BRC)
- * @non_VCL_NALU_Size: size of non-VCL NALUs (SPS, PPS, filler),
- * used by BRC
- * @cpb_buffer_size: size of Coded Picture Buffer, used by BRC
- * @bit_rate: target bitrate, for BRC
- * @qp_min: min QP threshold
- * @qp_max: max QP threshold
- * @framerate_num: target framerate numerator , used by BRC
- * @framerate_den: target framerate denomurator , used by BRC
- * @delay: End-to-End Initial Delay
- * @strict_HRD_compliancy: flag for HDR compliancy (1)
- * May impact quality encoding
- * @addr_source_buffer: address of input frame buffer for current frame
- * @addr_fwd_Ref_Buffer: address of reference frame buffer
- * @addr_rec_buffer: address of reconstructed frame buffer
- * @addr_output_bitstream_start: output bitstream start address
- * @addr_output_bitstream_end: output bitstream end address
- * @addr_external_sw : address of external search window
- * @addr_lctx : address of context picture buffer
- * @addr_local_rec_buffer: address of local reconstructed buffer
- * @addr_spatial_context: address of spatial context buffer
- * @bitstream_offset: offset in bits between aligned bitstream start
- * address and first bit to be written by HVA.
- * Range value is [0..63]
- * @sampling_mode: Input picture format .
- * 0: YUV420 semi_planar Interleaved
- * 1: YUV422 raster Interleaved
- * @addr_param_out: address of output parameters structure
- * @addr_scaling_matrix: address to the coefficient of
- * the inverse scaling matrix
- * @addr_scaling_matrix_dir: address to the coefficient of
- * the direct scaling matrix
- * @addr_cabac_context_buffer: address of cabac context buffer
- * @GmvX: Input information about the horizontal global displacement of
- * the encoded frame versus the previous one
- * @GmvY: Input information about the vertical global displacement of
- * the encoded frame versus the previous one
- * @window_width: width in pixels of the window to be encoded inside
- * the input frame
- * @window_height: width in pixels of the window to be encoded inside
- * the input frame
- * @window_horizontal_offset: horizontal offset in pels for input window
- * within input frame
- * @window_vertical_offset: vertical offset in pels for input window
- * within input frame
- * @addr_roi: Map of QP offset for the Region of Interest algorithm and
- * also used for Error map.
- * Bit 0-6 used for qp offset (value -64 to 63).
- * Bit 7 used to force intra
- * @addr_slice_header: address to slice header
- * @slice_header_size_in_bits: size in bits of the Slice header
- * @slice_header_offset0: Slice header offset where to insert
- * first_Mb_in_slice
- * @slice_header_offset1: Slice header offset where to insert
- * slice_qp_delta
- * @slice_header_offset2: Slice header offset where to insert
- * num_MBs_in_slice
- * @slice_synchro_enable: enable "slice ready" interrupt after each slice
- * @max_slice_number: Maximum number of slice in a frame
- * (0 is strictly forbidden)
- * @rgb2_yuv_y_coeff: Four coefficients (C0C1C2C3) to convert from RGB to
- * YUV for the Y component.
- * Y = C0*R + C1*G + C2*B + C3 (C0 is on byte 0)
- * @rgb2_yuv_u_coeff: four coefficients (C0C1C2C3) to convert from RGB to
- * YUV for the Y component.
- * Y = C0*R + C1*G + C2*B + C3 (C0 is on byte 0)
- * @rgb2_yuv_v_coeff: Four coefficients (C0C1C2C3) to convert from RGB to
- * YUV for the U (Cb) component.
- * U = C0*R + C1*G + C2*B + C3 (C0 is on byte 0)
- * @slice_byte_size: maximum slice size in bytes
- * (used when slice_size_type=2 or slice_size_type=3)
- * @max_air_intra_mb_nb: Maximum number of intra macroblock in a frame
- * for the AIR algorithm
- * @brc_no_skip: Disable skipping in the Bitrate Controller
- * @addr_brc_in_out_parameter: address of static buffer for BRC parameters
- */
-struct hva_h264_td {
- u16 frame_width;
- u16 frame_height;
- u32 frame_num;
- u16 picture_coding_type;
- u16 reserved1;
- u16 pic_order_cnt_type;
- u16 first_picture_in_sequence;
- u16 slice_size_type;
- u16 reserved2;
- u32 slice_mb_size;
- u16 ir_param_option;
- u16 intra_refresh_type;
- u16 use_constrained_intra_flag;
- u16 transform_mode;
- u16 disable_deblocking_filter_idc;
- s16 slice_alpha_c0_offset_div2;
- s16 slice_beta_offset_div2;
- u16 encoder_complexity;
- s16 chroma_qp_index_offset;
- u16 entropy_coding_mode;
- u16 brc_type;
- u16 quant;
- u32 non_vcl_nalu_size;
- u32 cpb_buffer_size;
- u32 bit_rate;
- u16 qp_min;
- u16 qp_max;
- u16 framerate_num;
- u16 framerate_den;
- u16 delay;
- u16 strict_hrd_compliancy;
- u32 addr_source_buffer;
- u32 addr_fwd_ref_buffer;
- u32 addr_rec_buffer;
- u32 addr_output_bitstream_start;
- u32 addr_output_bitstream_end;
- u32 addr_external_sw;
- u32 addr_lctx;
- u32 addr_local_rec_buffer;
- u32 addr_spatial_context;
- u16 bitstream_offset;
- u16 sampling_mode;
- u32 addr_param_out;
- u32 addr_scaling_matrix;
- u32 addr_scaling_matrix_dir;
- u32 addr_cabac_context_buffer;
- u32 reserved3;
- u32 reserved4;
- s16 gmv_x;
- s16 gmv_y;
- u16 window_width;
- u16 window_height;
- u16 window_horizontal_offset;
- u16 window_vertical_offset;
- u32 addr_roi;
- u32 addr_slice_header;
- u16 slice_header_size_in_bits;
- u16 slice_header_offset0;
- u16 slice_header_offset1;
- u16 slice_header_offset2;
- u32 reserved5;
- u32 reserved6;
- u16 reserved7;
- u16 reserved8;
- u16 slice_synchro_enable;
- u16 max_slice_number;
- u32 rgb2_yuv_y_coeff;
- u32 rgb2_yuv_u_coeff;
- u32 rgb2_yuv_v_coeff;
- u32 slice_byte_size;
- u16 max_air_intra_mb_nb;
- u16 brc_no_skip;
- u32 addr_temporal_context;
- u32 addr_brc_in_out_parameter;
-};
-
-/*
- * struct hva_h264_slice_po
- *
- * @ slice_size: slice size
- * @ slice_start_time: start time
- * @ slice_stop_time: stop time
- * @ slice_num: slice number
- */
-struct hva_h264_slice_po {
- u32 slice_size;
- u32 slice_start_time;
- u32 slice_end_time;
- u32 slice_num;
-};
-
-/*
- * struct hva_h264_po
- *
- * @ bitstream_size: bitstream size
- * @ dct_bitstream_size: dtc bitstream size
- * @ stuffing_bits: number of stuffing bits inserted by the encoder
- * @ removal_time: removal time of current frame (nb of ticks 1/framerate)
- * @ hvc_start_time: hvc start time
- * @ hvc_stop_time: hvc stop time
- * @ slice_count: slice count
- */
-struct hva_h264_po {
- u32 bitstream_size;
- u32 dct_bitstream_size;
- u32 stuffing_bits;
- u32 removal_time;
- u32 hvc_start_time;
- u32 hvc_stop_time;
- u32 slice_count;
- u32 reserved0;
- struct hva_h264_slice_po slice_params[16];
-};
-
-struct hva_h264_task {
- struct hva_h264_td td;
- struct hva_h264_po po;
-};
-
-/*
- * struct hva_h264_ctx
- *
- * @seq_info: sequence information buffer
- * @ref_frame: reference frame buffer
- * @rec_frame: reconstructed frame buffer
- * @task: task descriptor
- */
-struct hva_h264_ctx {
- struct hva_buffer *seq_info;
- struct hva_buffer *ref_frame;
- struct hva_buffer *rec_frame;
- struct hva_buffer *task;
-};
-
-static int hva_h264_fill_slice_header(struct hva_ctx *pctx,
- u8 *slice_header_addr,
- struct hva_controls *ctrls,
- int frame_num,
- u16 *header_size,
- u16 *header_offset0,
- u16 *header_offset1,
- u16 *header_offset2)
-{
- /*
- * with this HVA hardware version, part of the slice header is computed
- * on host and part by hardware.
- * The part of host is precomputed and available through this array.
- */
- struct device *dev = ctx_to_dev(pctx);
- int cabac = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
- static const unsigned char slice_header[] = {
- 0x00, 0x00, 0x00, 0x01,
- 0x41, 0x34, 0x07, 0x00
- };
- int idr_pic_id = frame_num % 2;
- enum hva_picture_coding_type type;
- u32 frame_order = frame_num % ctrls->gop_size;
-
- if (!(frame_num % ctrls->gop_size))
- type = PICTURE_CODING_TYPE_I;
- else
- type = PICTURE_CODING_TYPE_P;
-
- memcpy(slice_header_addr, slice_header, sizeof(slice_header));
-
- *header_size = 56;
- *header_offset0 = 40;
- *header_offset1 = 13;
- *header_offset2 = 0;
-
- if (type == PICTURE_CODING_TYPE_I) {
- slice_header_addr[4] = 0x65;
- slice_header_addr[5] = 0x11;
-
- /* toggle the I frame */
- if ((frame_num / ctrls->gop_size) % 2) {
- *header_size += 4;
- *header_offset1 += 4;
- slice_header_addr[6] = 0x04;
- slice_header_addr[7] = 0x70;
-
- } else {
- *header_size += 2;
- *header_offset1 += 2;
- slice_header_addr[6] = 0x09;
- slice_header_addr[7] = 0xC0;
- }
- } else {
- if (ctrls->entropy_mode == cabac) {
- *header_size += 1;
- *header_offset1 += 1;
- slice_header_addr[7] = 0x80;
- }
- /*
- * update slice header with P frame order
- * frame order is limited to 16 (coded on 4bits only)
- */
- slice_header_addr[5] += ((frame_order & 0x0C) >> 2);
- slice_header_addr[6] += ((frame_order & 0x03) << 6);
- }
-
- dev_dbg(dev,
- "%s %s slice header order %d idrPicId %d header size %d\n",
- pctx->name, __func__, frame_order, idr_pic_id, *header_size);
- return 0;
-}
-
-static int hva_h264_fill_data_nal(struct hva_ctx *pctx,
- unsigned int stuffing_bytes, u8 *addr,
- unsigned int stream_size, unsigned int *size)
-{
- struct device *dev = ctx_to_dev(pctx);
- static const u8 start[] = { 0x00, 0x00, 0x00, 0x01 };
-
- dev_dbg(dev, "%s %s stuffing bytes %d\n", pctx->name, __func__,
- stuffing_bytes);
-
- if ((*size + stuffing_bytes + H264_FILLER_DATA_SIZE) > stream_size) {
- dev_dbg(dev, "%s %s too many stuffing bytes %d\n",
- pctx->name, __func__, stuffing_bytes);
- return 0;
- }
-
- /* start code */
- memcpy(addr + *size, start, sizeof(start));
- *size += sizeof(start);
-
- /* nal_unit_type */
- addr[*size] = NALU_TYPE_FILLER_DATA;
- *size += 1;
-
- memset(addr + *size, 0xff, stuffing_bytes);
- *size += stuffing_bytes;
-
- addr[*size] = 0x80;
- *size += 1;
-
- return 0;
-}
-
-static int hva_h264_fill_sei_nal(struct hva_ctx *pctx,
- enum hva_h264_sei_payload_type type,
- u8 *addr, u32 *size)
-{
- struct device *dev = ctx_to_dev(pctx);
- static const u8 start[] = { 0x00, 0x00, 0x00, 0x01 };
- struct hva_h264_stereo_video_sei info;
- u8 offset = 7;
- u8 msg = 0;
-
- /* start code */
- memcpy(addr + *size, start, sizeof(start));
- *size += sizeof(start);
-
- /* nal_unit_type */
- addr[*size] = NALU_TYPE_SEI;
- *size += 1;
-
- /* payload type */
- addr[*size] = type;
- *size += 1;
-
- switch (type) {
- case SEI_STEREO_VIDEO_INFO:
- memset(&info, 0, sizeof(info));
-
- /* set to top/bottom frame packing arrangement */
- info.field_views_flag = 1;
- info.top_field_is_left_view_flag = 1;
-
- /* payload size */
- addr[*size] = 1;
- *size += 1;
-
- /* payload */
- msg = info.field_views_flag << offset--;
-
- if (info.field_views_flag) {
- msg |= info.top_field_is_left_view_flag <<
- offset--;
- } else {
- msg |= info.current_frame_is_left_view_flag <<
- offset--;
- msg |= info.next_frame_is_second_view_flag <<
- offset--;
- }
- msg |= info.left_view_self_contained_flag << offset--;
- msg |= info.right_view_self_contained_flag << offset--;
-
- addr[*size] = msg;
- *size += 1;
-
- addr[*size] = 0x80;
- *size += 1;
-
- return 0;
- case SEI_BUFFERING_PERIOD:
- case SEI_PICTURE_TIMING:
- case SEI_FRAME_PACKING_ARRANGEMENT:
- default:
- dev_err(dev, "%s sei nal type not supported %d\n",
- pctx->name, type);
- return -EINVAL;
- }
-}
-
-static int hva_h264_prepare_task(struct hva_ctx *pctx,
- struct hva_h264_task *task,
- struct hva_frame *frame,
- struct hva_stream *stream)
-{
- struct hva_dev *hva = ctx_to_hdev(pctx);
- struct device *dev = ctx_to_dev(pctx);
- struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv;
- struct hva_buffer *seq_info = ctx->seq_info;
- struct hva_buffer *fwd_ref_frame = ctx->ref_frame;
- struct hva_buffer *loc_rec_frame = ctx->rec_frame;
- struct hva_h264_td *td = &task->td;
- struct hva_controls *ctrls = &pctx->ctrls;
- struct v4l2_fract *time_per_frame = &pctx->ctrls.time_per_frame;
- int cavlc = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
- u32 frame_num = pctx->stream_num;
- u32 addr_esram = hva->esram_addr;
- enum v4l2_mpeg_video_h264_level level;
- dma_addr_t paddr = 0;
- u8 *slice_header_vaddr;
- u32 frame_width = frame->info.aligned_width;
- u32 frame_height = frame->info.aligned_height;
- u32 max_cpb_buffer_size;
- unsigned int payload = stream->bytesused;
- u32 max_bitrate;
-
- /* check width and height parameters */
- if ((frame_width > max(H264_MAX_SIZE_W, H264_MAX_SIZE_H)) ||
- (frame_height > max(H264_MAX_SIZE_W, H264_MAX_SIZE_H))) {
- dev_err(dev,
- "%s width(%d) or height(%d) exceeds limits (%dx%d)\n",
- pctx->name, frame_width, frame_height,
- H264_MAX_SIZE_W, H264_MAX_SIZE_H);
- pctx->frame_errors++;
- return -EINVAL;
- }
-
- level = ctrls->level;
-
- memset(td, 0, sizeof(struct hva_h264_td));
-
- td->frame_width = frame_width;
- td->frame_height = frame_height;
-
- /* set frame alignment */
- td->window_width = frame_width;
- td->window_height = frame_height;
- td->window_horizontal_offset = 0;
- td->window_vertical_offset = 0;
-
- td->first_picture_in_sequence = (!frame_num) ? 1 : 0;
-
- /* pic_order_cnt_type hard coded to '2' as only I & P frames */
- td->pic_order_cnt_type = 2;
-
- /* useConstrainedIntraFlag set to false for better coding efficiency */
- td->use_constrained_intra_flag = false;
- td->brc_type = (ctrls->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
- ? BRC_TYPE_CBR : BRC_TYPE_VBR;
-
- td->entropy_coding_mode = (ctrls->entropy_mode == cavlc) ? CAVLC :
- CABAC;
-
- td->bit_rate = ctrls->bitrate;
-
- /* set framerate, framerate = 1 n/ time per frame */
- if (time_per_frame->numerator >= 536) {
- /*
- * due to a hardware bug, framerate denominator can't exceed
- * 536 (BRC overflow). Compute nearest framerate
- */
- td->framerate_den = 1;
- td->framerate_num = (time_per_frame->denominator +
- (time_per_frame->numerator >> 1) - 1) /
- time_per_frame->numerator;
-
- /*
- * update bitrate to introduce a correction due to
- * the new framerate
- * new bitrate = (old bitrate * new framerate) / old framerate
- */
- td->bit_rate /= time_per_frame->numerator;
- td->bit_rate *= time_per_frame->denominator;
- td->bit_rate /= td->framerate_num;
- } else {
- td->framerate_den = time_per_frame->numerator;
- td->framerate_num = time_per_frame->denominator;
- }
-
- /* compute maximum bitrate depending on profile */
- if (ctrls->profile >= V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)
- max_bitrate = h264_infos_list[level].max_bitrate *
- H264_FACTOR_HIGH;
- else
- max_bitrate = h264_infos_list[level].max_bitrate *
- H264_FACTOR_BASELINE;
-
- /* check if bitrate doesn't exceed max size */
- if (td->bit_rate > max_bitrate) {
- dev_dbg(dev,
- "%s bitrate (%d) larger than level and profile allow, clip to %d\n",
- pctx->name, td->bit_rate, max_bitrate);
- td->bit_rate = max_bitrate;
- }
-
- /* convert cpb_buffer_size in bits */
- td->cpb_buffer_size = ctrls->cpb_size * 8000;
-
- /* compute maximum cpb buffer size depending on profile */
- if (ctrls->profile >= V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)
- max_cpb_buffer_size =
- h264_infos_list[level].max_cpb_size * H264_FACTOR_HIGH;
- else
- max_cpb_buffer_size =
- h264_infos_list[level].max_cpb_size * H264_FACTOR_BASELINE;
-
- /* check if cpb buffer size doesn't exceed max size */
- if (td->cpb_buffer_size > max_cpb_buffer_size) {
- dev_dbg(dev,
- "%s cpb size larger than level %d allows, clip to %d\n",
- pctx->name, td->cpb_buffer_size, max_cpb_buffer_size);
- td->cpb_buffer_size = max_cpb_buffer_size;
- }
-
- /* enable skipping in the Bitrate Controller */
- td->brc_no_skip = 0;
-
- /* initial delay */
- if ((ctrls->bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) &&
- td->bit_rate)
- td->delay = 1000 * (td->cpb_buffer_size / td->bit_rate);
- else
- td->delay = 0;
-
- switch (frame->info.pixelformat) {
- case V4L2_PIX_FMT_NV12:
- td->sampling_mode = SAMPLING_MODE_NV12;
- break;
- case V4L2_PIX_FMT_NV21:
- td->sampling_mode = SAMPLING_MODE_NV21;
- break;
- default:
- dev_err(dev, "%s invalid source pixel format\n",
- pctx->name);
- pctx->frame_errors++;
- return -EINVAL;
- }
-
- /*
- * fill matrix color converter (RGB to YUV)
- * Y = 0,299 R + 0,587 G + 0,114 B
- * Cb = -0,1687 R -0,3313 G + 0,5 B + 128
- * Cr = 0,5 R - 0,4187 G - 0,0813 B + 128
- */
- td->rgb2_yuv_y_coeff = 0x12031008;
- td->rgb2_yuv_u_coeff = 0x800EF7FB;
- td->rgb2_yuv_v_coeff = 0x80FEF40E;
-
- /* enable/disable transform mode */
- td->transform_mode = ctrls->dct8x8;
-
- /* encoder complexity fix to 2, ENCODE_I_16x16_I_NxN_P_16x16_P_WxH */
- td->encoder_complexity = 2;
-
- /* quant fix to 28, default VBR value */
- td->quant = 28;
-
- if (td->framerate_den == 0) {
- dev_err(dev, "%s invalid framerate\n", pctx->name);
- pctx->frame_errors++;
- return -EINVAL;
- }
-
- /* if automatic framerate, deactivate bitrate controller */
- if (td->framerate_num == 0)
- td->brc_type = 0;
-
- /* compliancy fix to true */
- td->strict_hrd_compliancy = 1;
-
- /* set minimum & maximum quantizers */
- td->qp_min = clamp_val(ctrls->qpmin, 0, 51);
- td->qp_max = clamp_val(ctrls->qpmax, 0, 51);
-
- td->addr_source_buffer = frame->paddr;
- td->addr_fwd_ref_buffer = fwd_ref_frame->paddr;
- td->addr_rec_buffer = loc_rec_frame->paddr;
-
- td->addr_output_bitstream_end = (u32)stream->paddr + stream->size;
-
- td->addr_output_bitstream_start = (u32)stream->paddr;
- td->bitstream_offset = (((u32)stream->paddr & 0xF) << 3) &
- BITSTREAM_OFFSET_MASK;
-
- td->addr_param_out = (u32)ctx->task->paddr +
- offsetof(struct hva_h264_task, po);
-
- /* swap spatial and temporal context */
- if (frame_num % 2) {
- paddr = seq_info->paddr;
- td->addr_spatial_context = ALIGN(paddr, 0x100);
- paddr = seq_info->paddr + DATA_SIZE(frame_width,
- frame_height);
- td->addr_temporal_context = ALIGN(paddr, 0x100);
- } else {
- paddr = seq_info->paddr;
- td->addr_temporal_context = ALIGN(paddr, 0x100);
- paddr = seq_info->paddr + DATA_SIZE(frame_width,
- frame_height);
- td->addr_spatial_context = ALIGN(paddr, 0x100);
- }
-
- paddr = seq_info->paddr + 2 * DATA_SIZE(frame_width, frame_height);
-
- td->addr_brc_in_out_parameter = ALIGN(paddr, 0x100);
-
- paddr = td->addr_brc_in_out_parameter + BRC_DATA_SIZE;
- td->addr_slice_header = ALIGN(paddr, 0x100);
- td->addr_external_sw = ALIGN(addr_esram, 0x100);
-
- addr_esram += SEARCH_WINDOW_BUFFER_MAX_SIZE(frame_width);
- td->addr_local_rec_buffer = ALIGN(addr_esram, 0x100);
-
- addr_esram += LOCAL_RECONSTRUCTED_BUFFER_MAX_SIZE(frame_width);
- td->addr_lctx = ALIGN(addr_esram, 0x100);
-
- addr_esram += CTX_MB_BUFFER_MAX_SIZE(max(frame_width, frame_height));
- td->addr_cabac_context_buffer = ALIGN(addr_esram, 0x100);
-
- if (!(frame_num % ctrls->gop_size)) {
- td->picture_coding_type = PICTURE_CODING_TYPE_I;
- stream->vbuf.flags |= V4L2_BUF_FLAG_KEYFRAME;
- } else {
- td->picture_coding_type = PICTURE_CODING_TYPE_P;
- stream->vbuf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
- }
-
- /* fill the slice header part */
- slice_header_vaddr = seq_info->vaddr + (td->addr_slice_header -
- seq_info->paddr);
-
- hva_h264_fill_slice_header(pctx, slice_header_vaddr, ctrls, frame_num,
- &td->slice_header_size_in_bits,
- &td->slice_header_offset0,
- &td->slice_header_offset1,
- &td->slice_header_offset2);
-
- td->chroma_qp_index_offset = 2;
- td->slice_synchro_enable = 0;
- td->max_slice_number = 1;
-
- /*
- * check the sps/pps header size for key frame only
- * sps/pps header was previously fill by libv4l
- * during qbuf of stream buffer
- */
- if ((stream->vbuf.flags == V4L2_BUF_FLAG_KEYFRAME) &&
- (payload > MAX_SPS_PPS_SIZE)) {
- dev_err(dev, "%s invalid sps/pps size %d\n", pctx->name,
- payload);
- pctx->frame_errors++;
- return -EINVAL;
- }
-
- if (stream->vbuf.flags != V4L2_BUF_FLAG_KEYFRAME)
- payload = 0;
-
- /* add SEI nal (video stereo info) */
- if (ctrls->sei_fp && hva_h264_fill_sei_nal(pctx, SEI_STEREO_VIDEO_INFO,
- (u8 *)stream->vaddr,
- &payload)) {
- dev_err(dev, "%s fail to get SEI nal\n", pctx->name);
- pctx->frame_errors++;
- return -EINVAL;
- }
-
- /* fill size of non-VCL NAL units (SPS, PPS, filler and SEI) */
- td->non_vcl_nalu_size = payload * 8;
-
- /* compute bitstream offset & new start address of bitstream */
- td->addr_output_bitstream_start += ((payload >> 4) << 4);
- td->bitstream_offset += (payload - ((payload >> 4) << 4)) * 8;
-
- stream->bytesused = payload;
-
- return 0;
-}
-
-static unsigned int hva_h264_get_stream_size(struct hva_h264_task *task)
-{
- struct hva_h264_po *po = &task->po;
-
- return po->bitstream_size;
-}
-
-static u32 hva_h264_get_stuffing_bytes(struct hva_h264_task *task)
-{
- struct hva_h264_po *po = &task->po;
-
- return po->stuffing_bits >> 3;
-}
-
-static int hva_h264_open(struct hva_ctx *pctx)
-{
- struct device *dev = ctx_to_dev(pctx);
- struct hva_h264_ctx *ctx;
- struct hva_dev *hva = ctx_to_hdev(pctx);
- u32 frame_width = pctx->frameinfo.aligned_width;
- u32 frame_height = pctx->frameinfo.aligned_height;
- u32 size;
- int ret;
-
- /* check esram size necessary to encode a frame */
- size = SEARCH_WINDOW_BUFFER_MAX_SIZE(frame_width) +
- LOCAL_RECONSTRUCTED_BUFFER_MAX_SIZE(frame_width) +
- CTX_MB_BUFFER_MAX_SIZE(max(frame_width, frame_height)) +
- CABAC_CONTEXT_BUFFER_MAX_SIZE(frame_width);
-
- if (hva->esram_size < size) {
- dev_err(dev, "%s not enough esram (max:%d request:%d)\n",
- pctx->name, hva->esram_size, size);
- ret = -EINVAL;
- goto err;
- }
-
- /* allocate context for codec */
- ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
- if (!ctx) {
- ret = -ENOMEM;
- goto err;
- }
-
- /* allocate sequence info buffer */
- ret = hva_mem_alloc(pctx,
- 2 * DATA_SIZE(frame_width, frame_height) +
- SLICE_HEADER_SIZE +
- BRC_DATA_SIZE,
- "hva sequence info",
- &ctx->seq_info);
- if (ret) {
- dev_err(dev,
- "%s failed to allocate sequence info buffer\n",
- pctx->name);
- goto err_ctx;
- }
-
- /* allocate reference frame buffer */
- ret = hva_mem_alloc(pctx,
- frame_width * frame_height * 3 / 2,
- "hva reference frame",
- &ctx->ref_frame);
- if (ret) {
- dev_err(dev, "%s failed to allocate reference frame buffer\n",
- pctx->name);
- goto err_seq_info;
- }
-
- /* allocate reconstructed frame buffer */
- ret = hva_mem_alloc(pctx,
- frame_width * frame_height * 3 / 2,
- "hva reconstructed frame",
- &ctx->rec_frame);
- if (ret) {
- dev_err(dev,
- "%s failed to allocate reconstructed frame buffer\n",
- pctx->name);
- goto err_ref_frame;
- }
-
- /* allocate task descriptor */
- ret = hva_mem_alloc(pctx,
- sizeof(struct hva_h264_task),
- "hva task descriptor",
- &ctx->task);
- if (ret) {
- dev_err(dev,
- "%s failed to allocate task descriptor\n",
- pctx->name);
- goto err_rec_frame;
- }
-
- pctx->priv = (void *)ctx;
-
- return 0;
-
-err_rec_frame:
- hva_mem_free(pctx, ctx->rec_frame);
-err_ref_frame:
- hva_mem_free(pctx, ctx->ref_frame);
-err_seq_info:
- hva_mem_free(pctx, ctx->seq_info);
-err_ctx:
- devm_kfree(dev, ctx);
-err:
- pctx->sys_errors++;
- return ret;
-}
-
-static int hva_h264_close(struct hva_ctx *pctx)
-{
- struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv;
- struct device *dev = ctx_to_dev(pctx);
-
- if (ctx->seq_info)
- hva_mem_free(pctx, ctx->seq_info);
-
- if (ctx->ref_frame)
- hva_mem_free(pctx, ctx->ref_frame);
-
- if (ctx->rec_frame)
- hva_mem_free(pctx, ctx->rec_frame);
-
- if (ctx->task)
- hva_mem_free(pctx, ctx->task);
-
- devm_kfree(dev, ctx);
-
- return 0;
-}
-
-static int hva_h264_encode(struct hva_ctx *pctx, struct hva_frame *frame,
- struct hva_stream *stream)
-{
- struct hva_h264_ctx *ctx = (struct hva_h264_ctx *)pctx->priv;
- struct hva_h264_task *task = (struct hva_h264_task *)ctx->task->vaddr;
- u32 stuffing_bytes = 0;
- int ret = 0;
-
- ret = hva_h264_prepare_task(pctx, task, frame, stream);
- if (ret)
- goto err;
-
- ret = hva_hw_execute_task(pctx, H264_ENC, ctx->task);
- if (ret)
- goto err;
-
- pctx->stream_num++;
- stream->bytesused += hva_h264_get_stream_size(task);
-
- stuffing_bytes = hva_h264_get_stuffing_bytes(task);
-
- if (stuffing_bytes)
- hva_h264_fill_data_nal(pctx, stuffing_bytes,
- (u8 *)stream->vaddr,
- stream->size,
- &stream->bytesused);
-
- /* switch reference & reconstructed frame */
- swap(ctx->ref_frame, ctx->rec_frame);
-
- return 0;
-err:
- stream->bytesused = 0;
- return ret;
-}
-
-const struct hva_enc nv12h264enc = {
- .name = "H264(NV12)",
- .pixelformat = V4L2_PIX_FMT_NV12,
- .streamformat = V4L2_PIX_FMT_H264,
- .max_width = H264_MAX_SIZE_W,
- .max_height = H264_MAX_SIZE_H,
- .open = hva_h264_open,
- .close = hva_h264_close,
- .encode = hva_h264_encode,
-};
-
-const struct hva_enc nv21h264enc = {
- .name = "H264(NV21)",
- .pixelformat = V4L2_PIX_FMT_NV21,
- .streamformat = V4L2_PIX_FMT_H264,
- .max_width = H264_MAX_SIZE_W,
- .max_height = H264_MAX_SIZE_H,
- .open = hva_h264_open,
- .close = hva_h264_close,
- .encode = hva_h264_encode,
-};
diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c
deleted file mode 100644
index fe4ea2e7f37e..000000000000
--- a/drivers/media/platform/sti/hva/hva-hw.c
+++ /dev/null
@@ -1,585 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) STMicroelectronics SA 2015
- * Authors: Yannick Fertre <yannick.fertre@st.com>
- * Hugues Fruchet <hugues.fruchet@st.com>
- */
-
-#include <linux/clk.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
-#include <linux/seq_file.h>
-#endif
-
-#include "hva.h"
-#include "hva-hw.h"
-
-/* HVA register offsets */
-#define HVA_HIF_REG_RST 0x0100U
-#define HVA_HIF_REG_RST_ACK 0x0104U
-#define HVA_HIF_REG_MIF_CFG 0x0108U
-#define HVA_HIF_REG_HEC_MIF_CFG 0x010CU
-#define HVA_HIF_REG_CFL 0x0110U
-#define HVA_HIF_FIFO_CMD 0x0114U
-#define HVA_HIF_FIFO_STS 0x0118U
-#define HVA_HIF_REG_SFL 0x011CU
-#define HVA_HIF_REG_IT_ACK 0x0120U
-#define HVA_HIF_REG_ERR_IT_ACK 0x0124U
-#define HVA_HIF_REG_LMI_ERR 0x0128U
-#define HVA_HIF_REG_EMI_ERR 0x012CU
-#define HVA_HIF_REG_HEC_MIF_ERR 0x0130U
-#define HVA_HIF_REG_HEC_STS 0x0134U
-#define HVA_HIF_REG_HVC_STS 0x0138U
-#define HVA_HIF_REG_HJE_STS 0x013CU
-#define HVA_HIF_REG_CNT 0x0140U
-#define HVA_HIF_REG_HEC_CHKSYN_DIS 0x0144U
-#define HVA_HIF_REG_CLK_GATING 0x0148U
-#define HVA_HIF_REG_VERSION 0x014CU
-#define HVA_HIF_REG_BSM 0x0150U
-
-/* define value for version id register (HVA_HIF_REG_VERSION) */
-#define VERSION_ID_MASK 0x0000FFFF
-
-/* define values for BSM register (HVA_HIF_REG_BSM) */
-#define BSM_CFG_VAL1 0x0003F000
-#define BSM_CFG_VAL2 0x003F0000
-
-/* define values for memory interface register (HVA_HIF_REG_MIF_CFG) */
-#define MIF_CFG_VAL1 0x04460446
-#define MIF_CFG_VAL2 0x04460806
-#define MIF_CFG_VAL3 0x00000000
-
-/* define value for HEC memory interface register (HVA_HIF_REG_MIF_CFG) */
-#define HEC_MIF_CFG_VAL 0x000000C4
-
-/* Bits definition for clock gating register (HVA_HIF_REG_CLK_GATING) */
-#define CLK_GATING_HVC BIT(0)
-#define CLK_GATING_HEC BIT(1)
-#define CLK_GATING_HJE BIT(2)
-
-/* fix hva clock rate */
-#define CLK_RATE 300000000
-
-/* fix delay for pmruntime */
-#define AUTOSUSPEND_DELAY_MS 3
-
-/*
- * hw encode error values
- * NO_ERROR: Success, Task OK
- * H264_BITSTREAM_OVERSIZE: VECH264 Bitstream size > bitstream buffer
- * H264_FRAME_SKIPPED: VECH264 Frame skipped (refers to CPB Buffer Size)
- * H264_SLICE_LIMIT_SIZE: VECH264 MB > slice limit size
- * H264_MAX_SLICE_NUMBER: VECH264 max slice number reached
- * H264_SLICE_READY: VECH264 Slice ready
- * TASK_LIST_FULL: HVA/FPC task list full
- (discard latest transform command)
- * UNKNOWN_COMMAND: Transform command not known by HVA/FPC
- * WRONG_CODEC_OR_RESOLUTION: Wrong Codec or Resolution Selection
- * NO_INT_COMPLETION: Time-out on interrupt completion
- * LMI_ERR: Local Memory Interface Error
- * EMI_ERR: External Memory Interface Error
- * HECMI_ERR: HEC Memory Interface Error
- */
-enum hva_hw_error {
- NO_ERROR = 0x0,
- H264_BITSTREAM_OVERSIZE = 0x2,
- H264_FRAME_SKIPPED = 0x4,
- H264_SLICE_LIMIT_SIZE = 0x5,
- H264_MAX_SLICE_NUMBER = 0x7,
- H264_SLICE_READY = 0x8,
- TASK_LIST_FULL = 0xF0,
- UNKNOWN_COMMAND = 0xF1,
- WRONG_CODEC_OR_RESOLUTION = 0xF4,
- NO_INT_COMPLETION = 0x100,
- LMI_ERR = 0x101,
- EMI_ERR = 0x102,
- HECMI_ERR = 0x103,
-};
-
-static irqreturn_t hva_hw_its_interrupt(int irq, void *data)
-{
- struct hva_dev *hva = data;
-
- /* read status registers */
- hva->sts_reg = readl_relaxed(hva->regs + HVA_HIF_FIFO_STS);
- hva->sfl_reg = readl_relaxed(hva->regs + HVA_HIF_REG_SFL);
-
- /* acknowledge interruption */
- writel_relaxed(0x1, hva->regs + HVA_HIF_REG_IT_ACK);
-
- return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t hva_hw_its_irq_thread(int irq, void *arg)
-{
- struct hva_dev *hva = arg;
- struct device *dev = hva_to_dev(hva);
- u32 status = hva->sts_reg & 0xFF;
- u8 ctx_id = 0;
- struct hva_ctx *ctx = NULL;
-
- dev_dbg(dev, "%s %s: status: 0x%02x fifo level: 0x%02x\n",
- HVA_PREFIX, __func__, hva->sts_reg & 0xFF, hva->sfl_reg & 0xF);
-
- /*
- * status: task_id[31:16] client_id[15:8] status[7:0]
- * the context identifier is retrieved from the client identifier
- */
- ctx_id = (hva->sts_reg & 0xFF00) >> 8;
- if (ctx_id >= HVA_MAX_INSTANCES) {
- dev_err(dev, "%s %s: bad context identifier: %d\n",
- HVA_PREFIX, __func__, ctx_id);
- goto out;
- }
-
- ctx = hva->instances[ctx_id];
- if (!ctx)
- goto out;
-
- switch (status) {
- case NO_ERROR:
- dev_dbg(dev, "%s %s: no error\n",
- ctx->name, __func__);
- ctx->hw_err = false;
- break;
- case H264_SLICE_READY:
- dev_dbg(dev, "%s %s: h264 slice ready\n",
- ctx->name, __func__);
- ctx->hw_err = false;
- break;
- case H264_FRAME_SKIPPED:
- dev_dbg(dev, "%s %s: h264 frame skipped\n",
- ctx->name, __func__);
- ctx->hw_err = false;
- break;
- case H264_BITSTREAM_OVERSIZE:
- dev_err(dev, "%s %s:h264 bitstream oversize\n",
- ctx->name, __func__);
- ctx->hw_err = true;
- break;
- case H264_SLICE_LIMIT_SIZE:
- dev_err(dev, "%s %s: h264 slice limit size is reached\n",
- ctx->name, __func__);
- ctx->hw_err = true;
- break;
- case H264_MAX_SLICE_NUMBER:
- dev_err(dev, "%s %s: h264 max slice number is reached\n",
- ctx->name, __func__);
- ctx->hw_err = true;
- break;
- case TASK_LIST_FULL:
- dev_err(dev, "%s %s:task list full\n",
- ctx->name, __func__);
- ctx->hw_err = true;
- break;
- case UNKNOWN_COMMAND:
- dev_err(dev, "%s %s: command not known\n",
- ctx->name, __func__);
- ctx->hw_err = true;
- break;
- case WRONG_CODEC_OR_RESOLUTION:
- dev_err(dev, "%s %s: wrong codec or resolution\n",
- ctx->name, __func__);
- ctx->hw_err = true;
- break;
- default:
- dev_err(dev, "%s %s: status not recognized\n",
- ctx->name, __func__);
- ctx->hw_err = true;
- break;
- }
-out:
- complete(&hva->interrupt);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t hva_hw_err_interrupt(int irq, void *data)
-{
- struct hva_dev *hva = data;
-
- /* read status registers */
- hva->sts_reg = readl_relaxed(hva->regs + HVA_HIF_FIFO_STS);
- hva->sfl_reg = readl_relaxed(hva->regs + HVA_HIF_REG_SFL);
-
- /* read error registers */
- hva->lmi_err_reg = readl_relaxed(hva->regs + HVA_HIF_REG_LMI_ERR);
- hva->emi_err_reg = readl_relaxed(hva->regs + HVA_HIF_REG_EMI_ERR);
- hva->hec_mif_err_reg = readl_relaxed(hva->regs +
- HVA_HIF_REG_HEC_MIF_ERR);
-
- /* acknowledge interruption */
- writel_relaxed(0x1, hva->regs + HVA_HIF_REG_IT_ACK);
-
- return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t hva_hw_err_irq_thread(int irq, void *arg)
-{
- struct hva_dev *hva = arg;
- struct device *dev = hva_to_dev(hva);
- u8 ctx_id = 0;
- struct hva_ctx *ctx;
-
- dev_dbg(dev, "%s status: 0x%02x fifo level: 0x%02x\n",
- HVA_PREFIX, hva->sts_reg & 0xFF, hva->sfl_reg & 0xF);
-
- /*
- * status: task_id[31:16] client_id[15:8] status[7:0]
- * the context identifier is retrieved from the client identifier
- */
- ctx_id = (hva->sts_reg & 0xFF00) >> 8;
- if (ctx_id >= HVA_MAX_INSTANCES) {
- dev_err(dev, "%s bad context identifier: %d\n", HVA_PREFIX,
- ctx_id);
- goto out;
- }
-
- ctx = hva->instances[ctx_id];
- if (!ctx)
- goto out;
-
- if (hva->lmi_err_reg) {
- dev_err(dev, "%s local memory interface error: 0x%08x\n",
- ctx->name, hva->lmi_err_reg);
- ctx->hw_err = true;
- }
-
- if (hva->emi_err_reg) {
- dev_err(dev, "%s external memory interface error: 0x%08x\n",
- ctx->name, hva->emi_err_reg);
- ctx->hw_err = true;
- }
-
- if (hva->hec_mif_err_reg) {
- dev_err(dev, "%s hec memory interface error: 0x%08x\n",
- ctx->name, hva->hec_mif_err_reg);
- ctx->hw_err = true;
- }
-out:
- complete(&hva->interrupt);
-
- return IRQ_HANDLED;
-}
-
-static unsigned long int hva_hw_get_ip_version(struct hva_dev *hva)
-{
- struct device *dev = hva_to_dev(hva);
- unsigned long int version;
-
- if (pm_runtime_resume_and_get(dev) < 0) {
- dev_err(dev, "%s failed to get pm_runtime\n", HVA_PREFIX);
- mutex_unlock(&hva->protect_mutex);
- return -EFAULT;
- }
-
- version = readl_relaxed(hva->regs + HVA_HIF_REG_VERSION) &
- VERSION_ID_MASK;
-
- pm_runtime_put_autosuspend(dev);
-
- switch (version) {
- case HVA_VERSION_V400:
- dev_dbg(dev, "%s IP hardware version 0x%lx\n",
- HVA_PREFIX, version);
- break;
- default:
- dev_err(dev, "%s unknown IP hardware version 0x%lx\n",
- HVA_PREFIX, version);
- version = HVA_VERSION_UNKNOWN;
- break;
- }
-
- return version;
-}
-
-int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva)
-{
- struct device *dev = &pdev->dev;
- struct resource *esram;
- int ret;
-
- WARN_ON(!hva);
-
- /* get memory for registers */
- hva->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(hva->regs)) {
- dev_err(dev, "%s failed to get regs\n", HVA_PREFIX);
- return PTR_ERR(hva->regs);
- }
-
- /* get memory for esram */
- esram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!esram) {
- dev_err(dev, "%s failed to get esram\n", HVA_PREFIX);
- return -ENODEV;
- }
- hva->esram_addr = esram->start;
- hva->esram_size = resource_size(esram);
-
- dev_info(dev, "%s esram reserved for address: 0x%x size:%d\n",
- HVA_PREFIX, hva->esram_addr, hva->esram_size);
-
- /* get clock resource */
- hva->clk = devm_clk_get(dev, "clk_hva");
- if (IS_ERR(hva->clk)) {
- dev_err(dev, "%s failed to get clock\n", HVA_PREFIX);
- return PTR_ERR(hva->clk);
- }
-
- ret = clk_prepare(hva->clk);
- if (ret < 0) {
- dev_err(dev, "%s failed to prepare clock\n", HVA_PREFIX);
- hva->clk = ERR_PTR(-EINVAL);
- return ret;
- }
-
- /* get status interruption resource */
- ret = platform_get_irq(pdev, 0);
- if (ret < 0)
- goto err_clk;
- hva->irq_its = ret;
-
- ret = devm_request_threaded_irq(dev, hva->irq_its, hva_hw_its_interrupt,
- hva_hw_its_irq_thread,
- IRQF_ONESHOT,
- "hva_its_irq", hva);
- if (ret) {
- dev_err(dev, "%s failed to install status IRQ 0x%x\n",
- HVA_PREFIX, hva->irq_its);
- goto err_clk;
- }
- disable_irq(hva->irq_its);
-
- /* get error interruption resource */
- ret = platform_get_irq(pdev, 1);
- if (ret < 0)
- goto err_clk;
- hva->irq_err = ret;
-
- ret = devm_request_threaded_irq(dev, hva->irq_err, hva_hw_err_interrupt,
- hva_hw_err_irq_thread,
- IRQF_ONESHOT,
- "hva_err_irq", hva);
- if (ret) {
- dev_err(dev, "%s failed to install error IRQ 0x%x\n",
- HVA_PREFIX, hva->irq_err);
- goto err_clk;
- }
- disable_irq(hva->irq_err);
-
- /* initialise protection mutex */
- mutex_init(&hva->protect_mutex);
-
- /* initialise completion signal */
- init_completion(&hva->interrupt);
-
- /* initialise runtime power management */
- pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_DELAY_MS);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_set_suspended(dev);
- pm_runtime_enable(dev);
-
- ret = pm_runtime_resume_and_get(dev);
- if (ret < 0) {
- dev_err(dev, "%s failed to set PM\n", HVA_PREFIX);
- goto err_disable;
- }
-
- /* check IP hardware version */
- hva->ip_version = hva_hw_get_ip_version(hva);
-
- if (hva->ip_version == HVA_VERSION_UNKNOWN) {
- ret = -EINVAL;
- goto err_pm;
- }
-
- dev_info(dev, "%s found hva device (version 0x%lx)\n", HVA_PREFIX,
- hva->ip_version);
-
- return 0;
-
-err_pm:
- pm_runtime_put(dev);
-err_disable:
- pm_runtime_disable(dev);
-err_clk:
- if (hva->clk)
- clk_unprepare(hva->clk);
-
- return ret;
-}
-
-void hva_hw_remove(struct hva_dev *hva)
-{
- struct device *dev = hva_to_dev(hva);
-
- disable_irq(hva->irq_its);
- disable_irq(hva->irq_err);
-
- pm_runtime_put_autosuspend(dev);
- pm_runtime_disable(dev);
-}
-
-int hva_hw_runtime_suspend(struct device *dev)
-{
- struct hva_dev *hva = dev_get_drvdata(dev);
-
- clk_disable_unprepare(hva->clk);
-
- return 0;
-}
-
-int hva_hw_runtime_resume(struct device *dev)
-{
- struct hva_dev *hva = dev_get_drvdata(dev);
-
- if (clk_prepare_enable(hva->clk)) {
- dev_err(hva->dev, "%s failed to prepare hva clk\n",
- HVA_PREFIX);
- return -EINVAL;
- }
-
- if (clk_set_rate(hva->clk, CLK_RATE)) {
- dev_err(dev, "%s failed to set clock frequency\n",
- HVA_PREFIX);
- clk_disable_unprepare(hva->clk);
- return -EINVAL;
- }
-
- return 0;
-}
-
-int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd,
- struct hva_buffer *task)
-{
- struct hva_dev *hva = ctx_to_hdev(ctx);
- struct device *dev = hva_to_dev(hva);
- u8 client_id = ctx->id;
- int ret;
- u32 reg = 0;
- bool got_pm = false;
-
- mutex_lock(&hva->protect_mutex);
-
- /* enable irqs */
- enable_irq(hva->irq_its);
- enable_irq(hva->irq_err);
-
- if (pm_runtime_resume_and_get(dev) < 0) {
- dev_err(dev, "%s failed to get pm_runtime\n", ctx->name);
- ctx->sys_errors++;
- ret = -EFAULT;
- goto out;
- }
- got_pm = true;
-
- reg = readl_relaxed(hva->regs + HVA_HIF_REG_CLK_GATING);
- switch (cmd) {
- case H264_ENC:
- reg |= CLK_GATING_HVC;
- break;
- default:
- dev_dbg(dev, "%s unknown command 0x%x\n", ctx->name, cmd);
- ctx->encode_errors++;
- ret = -EFAULT;
- goto out;
- }
- writel_relaxed(reg, hva->regs + HVA_HIF_REG_CLK_GATING);
-
- dev_dbg(dev, "%s %s: write configuration registers\n", ctx->name,
- __func__);
-
- /* byte swap config */
- writel_relaxed(BSM_CFG_VAL1, hva->regs + HVA_HIF_REG_BSM);
-
- /* define Max Opcode Size and Max Message Size for LMI and EMI */
- writel_relaxed(MIF_CFG_VAL3, hva->regs + HVA_HIF_REG_MIF_CFG);
- writel_relaxed(HEC_MIF_CFG_VAL, hva->regs + HVA_HIF_REG_HEC_MIF_CFG);
-
- /*
- * command FIFO: task_id[31:16] client_id[15:8] command_type[7:0]
- * the context identifier is provided as client identifier to the
- * hardware, and is retrieved in the interrupt functions from the
- * status register
- */
- dev_dbg(dev, "%s %s: send task (cmd: %d, task_desc: %pad)\n",
- ctx->name, __func__, cmd + (client_id << 8), &task->paddr);
- writel_relaxed(cmd + (client_id << 8), hva->regs + HVA_HIF_FIFO_CMD);
- writel_relaxed(task->paddr, hva->regs + HVA_HIF_FIFO_CMD);
-
- if (!wait_for_completion_timeout(&hva->interrupt,
- msecs_to_jiffies(2000))) {
- dev_err(dev, "%s %s: time out on completion\n", ctx->name,
- __func__);
- ctx->encode_errors++;
- ret = -EFAULT;
- goto out;
- }
-
- /* get encoding status */
- ret = ctx->hw_err ? -EFAULT : 0;
-
- ctx->encode_errors += ctx->hw_err ? 1 : 0;
-
-out:
- disable_irq(hva->irq_its);
- disable_irq(hva->irq_err);
-
- switch (cmd) {
- case H264_ENC:
- reg &= ~CLK_GATING_HVC;
- writel_relaxed(reg, hva->regs + HVA_HIF_REG_CLK_GATING);
- break;
- default:
- dev_dbg(dev, "%s unknown command 0x%x\n", ctx->name, cmd);
- }
-
- if (got_pm)
- pm_runtime_put_autosuspend(dev);
- mutex_unlock(&hva->protect_mutex);
-
- return ret;
-}
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
-#define DUMP(reg) seq_printf(s, "%-30s: 0x%08X\n",\
- #reg, readl_relaxed(hva->regs + reg))
-
-void hva_hw_dump_regs(struct hva_dev *hva, struct seq_file *s)
-{
- struct device *dev = hva_to_dev(hva);
-
- mutex_lock(&hva->protect_mutex);
-
- if (pm_runtime_resume_and_get(dev) < 0) {
- seq_puts(s, "Cannot wake up IP\n");
- mutex_unlock(&hva->protect_mutex);
- return;
- }
-
- seq_printf(s, "Registers:\nReg @ = 0x%p\n", hva->regs);
-
- DUMP(HVA_HIF_REG_RST);
- DUMP(HVA_HIF_REG_RST_ACK);
- DUMP(HVA_HIF_REG_MIF_CFG);
- DUMP(HVA_HIF_REG_HEC_MIF_CFG);
- DUMP(HVA_HIF_REG_CFL);
- DUMP(HVA_HIF_REG_SFL);
- DUMP(HVA_HIF_REG_LMI_ERR);
- DUMP(HVA_HIF_REG_EMI_ERR);
- DUMP(HVA_HIF_REG_HEC_MIF_ERR);
- DUMP(HVA_HIF_REG_HEC_STS);
- DUMP(HVA_HIF_REG_HVC_STS);
- DUMP(HVA_HIF_REG_HJE_STS);
- DUMP(HVA_HIF_REG_CNT);
- DUMP(HVA_HIF_REG_HEC_CHKSYN_DIS);
- DUMP(HVA_HIF_REG_CLK_GATING);
- DUMP(HVA_HIF_REG_VERSION);
-
- pm_runtime_put_autosuspend(dev);
- mutex_unlock(&hva->protect_mutex);
-}
-#endif
diff --git a/drivers/media/platform/sti/hva/hva-hw.h b/drivers/media/platform/sti/hva/hva-hw.h
deleted file mode 100644
index b298990264d5..000000000000
--- a/drivers/media/platform/sti/hva/hva-hw.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) STMicroelectronics SA 2015
- * Authors: Yannick Fertre <yannick.fertre@st.com>
- * Hugues Fruchet <hugues.fruchet@st.com>
- */
-
-#ifndef HVA_HW_H
-#define HVA_HW_H
-
-#include "hva-mem.h"
-
-/* HVA Versions */
-#define HVA_VERSION_UNKNOWN 0x000
-#define HVA_VERSION_V400 0x400
-
-/* HVA command types */
-enum hva_hw_cmd_type {
- /* RESERVED = 0x00 */
- /* RESERVED = 0x01 */
- H264_ENC = 0x02,
- /* RESERVED = 0x03 */
- /* RESERVED = 0x04 */
- /* RESERVED = 0x05 */
- /* RESERVED = 0x06 */
- /* RESERVED = 0x07 */
- REMOVE_CLIENT = 0x08,
- FREEZE_CLIENT = 0x09,
- START_CLIENT = 0x0A,
- FREEZE_ALL = 0x0B,
- START_ALL = 0x0C,
- REMOVE_ALL = 0x0D
-};
-
-int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva);
-void hva_hw_remove(struct hva_dev *hva);
-int hva_hw_runtime_suspend(struct device *dev);
-int hva_hw_runtime_resume(struct device *dev);
-int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd,
- struct hva_buffer *task);
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
-void hva_hw_dump_regs(struct hva_dev *hva, struct seq_file *s);
-#endif
-
-#endif /* HVA_HW_H */
diff --git a/drivers/media/platform/sti/hva/hva-mem.c b/drivers/media/platform/sti/hva/hva-mem.c
deleted file mode 100644
index 68047b60b66c..000000000000
--- a/drivers/media/platform/sti/hva/hva-mem.c
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) STMicroelectronics SA 2015
- * Authors: Yannick Fertre <yannick.fertre@st.com>
- * Hugues Fruchet <hugues.fruchet@st.com>
- */
-
-#include "hva.h"
-#include "hva-mem.h"
-
-int hva_mem_alloc(struct hva_ctx *ctx, u32 size, const char *name,
- struct hva_buffer **buf)
-{
- struct device *dev = ctx_to_dev(ctx);
- struct hva_buffer *b;
- dma_addr_t paddr;
- void *base;
-
- b = devm_kzalloc(dev, sizeof(*b), GFP_KERNEL);
- if (!b) {
- ctx->sys_errors++;
- return -ENOMEM;
- }
-
- base = dma_alloc_attrs(dev, size, &paddr, GFP_KERNEL,
- DMA_ATTR_WRITE_COMBINE);
- if (!base) {
- dev_err(dev, "%s %s : dma_alloc_attrs failed for %s (size=%d)\n",
- ctx->name, __func__, name, size);
- ctx->sys_errors++;
- devm_kfree(dev, b);
- return -ENOMEM;
- }
-
- b->size = size;
- b->paddr = paddr;
- b->vaddr = base;
- b->name = name;
-
- dev_dbg(dev,
- "%s allocate %d bytes of HW memory @(virt=%p, phy=%pad): %s\n",
- ctx->name, size, b->vaddr, &b->paddr, b->name);
-
- /* return hva buffer to user */
- *buf = b;
-
- return 0;
-}
-
-void hva_mem_free(struct hva_ctx *ctx, struct hva_buffer *buf)
-{
- struct device *dev = ctx_to_dev(ctx);
-
- dev_dbg(dev,
- "%s free %d bytes of HW memory @(virt=%p, phy=%pad): %s\n",
- ctx->name, buf->size, buf->vaddr, &buf->paddr, buf->name);
-
- dma_free_attrs(dev, buf->size, buf->vaddr, buf->paddr,
- DMA_ATTR_WRITE_COMBINE);
-
- devm_kfree(dev, buf);
-}
diff --git a/drivers/media/platform/sti/hva/hva-mem.h b/drivers/media/platform/sti/hva/hva-mem.h
deleted file mode 100644
index fec549dff2b3..000000000000
--- a/drivers/media/platform/sti/hva/hva-mem.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) STMicroelectronics SA 2015
- * Authors: Yannick Fertre <yannick.fertre@st.com>
- * Hugues Fruchet <hugues.fruchet@st.com>
- */
-
-#ifndef HVA_MEM_H
-#define HVA_MEM_H
-
-/**
- * struct hva_buffer - hva buffer
- *
- * @name: name of requester
- * @paddr: physical address (for hardware)
- * @vaddr: virtual address (kernel can read/write)
- * @size: size of buffer
- */
-struct hva_buffer {
- const char *name;
- dma_addr_t paddr;
- void *vaddr;
- u32 size;
-};
-
-int hva_mem_alloc(struct hva_ctx *ctx,
- __u32 size,
- const char *name,
- struct hva_buffer **buf);
-
-void hva_mem_free(struct hva_ctx *ctx,
- struct hva_buffer *buf);
-
-#endif /* HVA_MEM_H */
diff --git a/drivers/media/platform/sti/hva/hva-v4l2.c b/drivers/media/platform/sti/hva/hva-v4l2.c
deleted file mode 100644
index bb34d6997d99..000000000000
--- a/drivers/media/platform/sti/hva/hva-v4l2.c
+++ /dev/null
@@ -1,1476 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) STMicroelectronics SA 2015
- * Authors: Yannick Fertre <yannick.fertre@st.com>
- * Hugues Fruchet <hugues.fruchet@st.com>
- */
-
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "hva.h"
-#include "hva-hw.h"
-
-#define MIN_FRAMES 1
-#define MIN_STREAMS 1
-
-#define HVA_MIN_WIDTH 32
-#define HVA_MAX_WIDTH 1920
-#define HVA_MIN_HEIGHT 32
-#define HVA_MAX_HEIGHT 1920
-
-/* HVA requires a 16x16 pixels alignment for frames */
-#define HVA_WIDTH_ALIGNMENT 16
-#define HVA_HEIGHT_ALIGNMENT 16
-
-#define HVA_DEFAULT_WIDTH HVA_MIN_WIDTH
-#define HVA_DEFAULT_HEIGHT HVA_MIN_HEIGHT
-#define HVA_DEFAULT_FRAME_NUM 1
-#define HVA_DEFAULT_FRAME_DEN 30
-
-#define to_type_str(type) (type == V4L2_BUF_TYPE_VIDEO_OUTPUT ? \
- "frame" : "stream")
-
-#define fh_to_ctx(f) (container_of(f, struct hva_ctx, fh))
-
-/* registry of available encoders */
-static const struct hva_enc *hva_encoders[] = {
- &nv12h264enc,
- &nv21h264enc,
-};
-
-static inline int frame_size(u32 w, u32 h, u32 fmt)
-{
- switch (fmt) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- return (w * h * 3) / 2;
- default:
- return 0;
- }
-}
-
-static inline int frame_stride(u32 w, u32 fmt)
-{
- switch (fmt) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- return w;
- default:
- return 0;
- }
-}
-
-static inline int frame_alignment(u32 fmt)
-{
- switch (fmt) {
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- /* multiple of 2 */
- return 2;
- default:
- return 1;
- }
-}
-
-static inline int estimated_stream_size(u32 w, u32 h)
-{
- /*
- * HVA only encodes in YUV420 format, whatever the frame format.
- * A compression ratio of 2 is assumed: thus, the maximum size
- * of a stream is estimated to ((width x height x 3 / 2) / 2)
- */
- return (w * h * 3) / 4;
-}
-
-static void set_default_params(struct hva_ctx *ctx)
-{
- struct hva_frameinfo *frameinfo = &ctx->frameinfo;
- struct hva_streaminfo *streaminfo = &ctx->streaminfo;
-
- frameinfo->pixelformat = V4L2_PIX_FMT_NV12;
- frameinfo->width = HVA_DEFAULT_WIDTH;
- frameinfo->height = HVA_DEFAULT_HEIGHT;
- frameinfo->aligned_width = ALIGN(frameinfo->width,
- HVA_WIDTH_ALIGNMENT);
- frameinfo->aligned_height = ALIGN(frameinfo->height,
- HVA_HEIGHT_ALIGNMENT);
- frameinfo->size = frame_size(frameinfo->aligned_width,
- frameinfo->aligned_height,
- frameinfo->pixelformat);
-
- streaminfo->streamformat = V4L2_PIX_FMT_H264;
- streaminfo->width = HVA_DEFAULT_WIDTH;
- streaminfo->height = HVA_DEFAULT_HEIGHT;
-
- ctx->colorspace = V4L2_COLORSPACE_REC709;
- ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT;
- ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
- ctx->quantization = V4L2_QUANTIZATION_DEFAULT;
-
- ctx->max_stream_size = estimated_stream_size(streaminfo->width,
- streaminfo->height);
-}
-
-static const struct hva_enc *hva_find_encoder(struct hva_ctx *ctx,
- u32 pixelformat,
- u32 streamformat)
-{
- struct hva_dev *hva = ctx_to_hdev(ctx);
- const struct hva_enc *enc;
- unsigned int i;
-
- for (i = 0; i < hva->nb_of_encoders; i++) {
- enc = hva->encoders[i];
- if ((enc->pixelformat == pixelformat) &&
- (enc->streamformat == streamformat))
- return enc;
- }
-
- return NULL;
-}
-
-static void register_format(u32 format, u32 formats[], u32 *nb_of_formats)
-{
- u32 i;
- bool found = false;
-
- for (i = 0; i < *nb_of_formats; i++) {
- if (format == formats[i]) {
- found = true;
- break;
- }
- }
-
- if (!found)
- formats[(*nb_of_formats)++] = format;
-}
-
-static void register_formats(struct hva_dev *hva)
-{
- unsigned int i;
-
- for (i = 0; i < hva->nb_of_encoders; i++) {
- register_format(hva->encoders[i]->pixelformat,
- hva->pixelformats,
- &hva->nb_of_pixelformats);
-
- register_format(hva->encoders[i]->streamformat,
- hva->streamformats,
- &hva->nb_of_streamformats);
- }
-}
-
-static void register_encoders(struct hva_dev *hva)
-{
- struct device *dev = hva_to_dev(hva);
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(hva_encoders); i++) {
- if (hva->nb_of_encoders >= HVA_MAX_ENCODERS) {
- dev_dbg(dev,
- "%s failed to register %s encoder (%d maximum reached)\n",
- HVA_PREFIX, hva_encoders[i]->name,
- HVA_MAX_ENCODERS);
- return;
- }
-
- hva->encoders[hva->nb_of_encoders++] = hva_encoders[i];
- dev_info(dev, "%s %s encoder registered\n", HVA_PREFIX,
- hva_encoders[i]->name);
- }
-}
-
-static int hva_open_encoder(struct hva_ctx *ctx, u32 streamformat,
- u32 pixelformat, struct hva_enc **penc)
-{
- struct hva_dev *hva = ctx_to_hdev(ctx);
- struct device *dev = ctx_to_dev(ctx);
- struct hva_enc *enc;
- int ret;
-
- /* find an encoder which can deal with these formats */
- enc = (struct hva_enc *)hva_find_encoder(ctx, pixelformat,
- streamformat);
- if (!enc) {
- dev_err(dev, "%s no encoder found matching %4.4s => %4.4s\n",
- ctx->name, (char *)&pixelformat, (char *)&streamformat);
- return -EINVAL;
- }
-
- dev_dbg(dev, "%s one encoder matching %4.4s => %4.4s\n",
- ctx->name, (char *)&pixelformat, (char *)&streamformat);
-
- /* update instance name */
- snprintf(ctx->name, sizeof(ctx->name), "[%3d:%4.4s]",
- hva->instance_id, (char *)&streamformat);
-
- /* open encoder instance */
- ret = enc->open(ctx);
- if (ret) {
- dev_err(dev, "%s failed to open encoder instance (%d)\n",
- ctx->name, ret);
- return ret;
- }
-
- dev_dbg(dev, "%s %s encoder opened\n", ctx->name, enc->name);
-
- *penc = enc;
-
- return ret;
-}
-
-static void hva_dbg_summary(struct hva_ctx *ctx)
-{
- struct device *dev = ctx_to_dev(ctx);
- struct hva_streaminfo *stream = &ctx->streaminfo;
- struct hva_frameinfo *frame = &ctx->frameinfo;
-
- if (!(ctx->flags & HVA_FLAG_STREAMINFO))
- return;
-
- dev_dbg(dev, "%s %4.4s %dx%d > %4.4s %dx%d %s %s: %d frames encoded, %d system errors, %d encoding errors, %d frame errors\n",
- ctx->name,
- (char *)&frame->pixelformat,
- frame->aligned_width, frame->aligned_height,
- (char *)&stream->streamformat,
- stream->width, stream->height,
- stream->profile, stream->level,
- ctx->encoded_frames,
- ctx->sys_errors,
- ctx->encode_errors,
- ctx->frame_errors);
-}
-
-/*
- * V4L2 ioctl operations
- */
-
-static int hva_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct hva_dev *hva = ctx_to_hdev(ctx);
-
- strscpy(cap->driver, HVA_NAME, sizeof(cap->driver));
- strscpy(cap->card, hva->vdev->name, sizeof(cap->card));
- snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
- hva->pdev->name);
-
- return 0;
-}
-
-static int hva_enum_fmt_stream(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct hva_dev *hva = ctx_to_hdev(ctx);
-
- if (unlikely(f->index >= hva->nb_of_streamformats))
- return -EINVAL;
-
- f->pixelformat = hva->streamformats[f->index];
-
- return 0;
-}
-
-static int hva_enum_fmt_frame(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct hva_dev *hva = ctx_to_hdev(ctx);
-
- if (unlikely(f->index >= hva->nb_of_pixelformats))
- return -EINVAL;
-
- f->pixelformat = hva->pixelformats[f->index];
-
- return 0;
-}
-
-static int hva_g_fmt_stream(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct hva_streaminfo *streaminfo = &ctx->streaminfo;
-
- f->fmt.pix.width = streaminfo->width;
- f->fmt.pix.height = streaminfo->height;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.colorspace = ctx->colorspace;
- f->fmt.pix.xfer_func = ctx->xfer_func;
- f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
- f->fmt.pix.quantization = ctx->quantization;
- f->fmt.pix.pixelformat = streaminfo->streamformat;
- f->fmt.pix.bytesperline = 0;
- f->fmt.pix.sizeimage = ctx->max_stream_size;
-
- return 0;
-}
-
-static int hva_g_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct hva_frameinfo *frameinfo = &ctx->frameinfo;
-
- f->fmt.pix.width = frameinfo->width;
- f->fmt.pix.height = frameinfo->height;
- f->fmt.pix.field = V4L2_FIELD_NONE;
- f->fmt.pix.colorspace = ctx->colorspace;
- f->fmt.pix.xfer_func = ctx->xfer_func;
- f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
- f->fmt.pix.quantization = ctx->quantization;
- f->fmt.pix.pixelformat = frameinfo->pixelformat;
- f->fmt.pix.bytesperline = frame_stride(frameinfo->aligned_width,
- frameinfo->pixelformat);
- f->fmt.pix.sizeimage = frameinfo->size;
-
- return 0;
-}
-
-static int hva_try_fmt_stream(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct device *dev = ctx_to_dev(ctx);
- struct v4l2_pix_format *pix = &f->fmt.pix;
- u32 streamformat = pix->pixelformat;
- const struct hva_enc *enc;
- u32 width, height;
- u32 stream_size;
-
- enc = hva_find_encoder(ctx, ctx->frameinfo.pixelformat, streamformat);
- if (!enc) {
- dev_dbg(dev,
- "%s V4L2 TRY_FMT (CAPTURE): unsupported format %.4s\n",
- ctx->name, (char *)&pix->pixelformat);
- return -EINVAL;
- }
-
- width = pix->width;
- height = pix->height;
- if (ctx->flags & HVA_FLAG_FRAMEINFO) {
- /*
- * if the frame resolution is already fixed, only allow the
- * same stream resolution
- */
- pix->width = ctx->frameinfo.width;
- pix->height = ctx->frameinfo.height;
- if ((pix->width != width) || (pix->height != height))
- dev_dbg(dev,
- "%s V4L2 TRY_FMT (CAPTURE): resolution updated %dx%d -> %dx%d to fit frame resolution\n",
- ctx->name, width, height,
- pix->width, pix->height);
- } else {
- /* adjust width & height */
- v4l_bound_align_image(&pix->width,
- HVA_MIN_WIDTH, enc->max_width,
- 0,
- &pix->height,
- HVA_MIN_HEIGHT, enc->max_height,
- 0,
- 0);
-
- if ((pix->width != width) || (pix->height != height))
- dev_dbg(dev,
- "%s V4L2 TRY_FMT (CAPTURE): resolution updated %dx%d -> %dx%d to fit min/max/alignment\n",
- ctx->name, width, height,
- pix->width, pix->height);
- }
-
- stream_size = estimated_stream_size(pix->width, pix->height);
- if (pix->sizeimage < stream_size)
- pix->sizeimage = stream_size;
-
- pix->bytesperline = 0;
- pix->colorspace = ctx->colorspace;
- pix->xfer_func = ctx->xfer_func;
- pix->ycbcr_enc = ctx->ycbcr_enc;
- pix->quantization = ctx->quantization;
- pix->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int hva_try_fmt_frame(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct device *dev = ctx_to_dev(ctx);
- struct v4l2_pix_format *pix = &f->fmt.pix;
- u32 pixelformat = pix->pixelformat;
- const struct hva_enc *enc;
- u32 width, height;
-
- enc = hva_find_encoder(ctx, pixelformat, ctx->streaminfo.streamformat);
- if (!enc) {
- dev_dbg(dev,
- "%s V4L2 TRY_FMT (OUTPUT): unsupported format %.4s\n",
- ctx->name, (char *)&pixelformat);
- return -EINVAL;
- }
-
- /* adjust width & height */
- width = pix->width;
- height = pix->height;
- v4l_bound_align_image(&pix->width,
- HVA_MIN_WIDTH, HVA_MAX_WIDTH,
- frame_alignment(pixelformat) - 1,
- &pix->height,
- HVA_MIN_HEIGHT, HVA_MAX_HEIGHT,
- frame_alignment(pixelformat) - 1,
- 0);
-
- if ((pix->width != width) || (pix->height != height))
- dev_dbg(dev,
- "%s V4L2 TRY_FMT (OUTPUT): resolution updated %dx%d -> %dx%d to fit min/max/alignment\n",
- ctx->name, width, height, pix->width, pix->height);
-
- width = ALIGN(pix->width, HVA_WIDTH_ALIGNMENT);
- height = ALIGN(pix->height, HVA_HEIGHT_ALIGNMENT);
-
- if (!pix->colorspace) {
- pix->colorspace = V4L2_COLORSPACE_REC709;
- pix->xfer_func = V4L2_XFER_FUNC_DEFAULT;
- pix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
- pix->quantization = V4L2_QUANTIZATION_DEFAULT;
- }
-
- pix->bytesperline = frame_stride(width, pixelformat);
- pix->sizeimage = frame_size(width, height, pixelformat);
- pix->field = V4L2_FIELD_NONE;
-
- return 0;
-}
-
-static int hva_s_fmt_stream(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct device *dev = ctx_to_dev(ctx);
- struct vb2_queue *vq;
- int ret;
-
- ret = hva_try_fmt_stream(file, fh, f);
- if (ret) {
- dev_dbg(dev, "%s V4L2 S_FMT (CAPTURE): unsupported format %.4s\n",
- ctx->name, (char *)&f->fmt.pix.pixelformat);
- return ret;
- }
-
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
- if (vb2_is_streaming(vq)) {
- dev_dbg(dev, "%s V4L2 S_FMT (CAPTURE): queue busy\n",
- ctx->name);
- return -EBUSY;
- }
-
- ctx->max_stream_size = f->fmt.pix.sizeimage;
- ctx->streaminfo.width = f->fmt.pix.width;
- ctx->streaminfo.height = f->fmt.pix.height;
- ctx->streaminfo.streamformat = f->fmt.pix.pixelformat;
- ctx->flags |= HVA_FLAG_STREAMINFO;
-
- return 0;
-}
-
-static int hva_s_fmt_frame(struct file *file, void *fh, struct v4l2_format *f)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct device *dev = ctx_to_dev(ctx);
- struct v4l2_pix_format *pix = &f->fmt.pix;
- struct vb2_queue *vq;
- int ret;
-
- ret = hva_try_fmt_frame(file, fh, f);
- if (ret) {
- dev_dbg(dev, "%s V4L2 S_FMT (OUTPUT): unsupported format %.4s\n",
- ctx->name, (char *)&pix->pixelformat);
- return ret;
- }
-
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
- if (vb2_is_streaming(vq)) {
- dev_dbg(dev, "%s V4L2 S_FMT (OUTPUT): queue busy\n", ctx->name);
- return -EBUSY;
- }
-
- ctx->colorspace = pix->colorspace;
- ctx->xfer_func = pix->xfer_func;
- ctx->ycbcr_enc = pix->ycbcr_enc;
- ctx->quantization = pix->quantization;
-
- ctx->frameinfo.aligned_width = ALIGN(pix->width, HVA_WIDTH_ALIGNMENT);
- ctx->frameinfo.aligned_height = ALIGN(pix->height,
- HVA_HEIGHT_ALIGNMENT);
- ctx->frameinfo.size = pix->sizeimage;
- ctx->frameinfo.pixelformat = pix->pixelformat;
- ctx->frameinfo.width = pix->width;
- ctx->frameinfo.height = pix->height;
- ctx->flags |= HVA_FLAG_FRAMEINFO;
-
- return 0;
-}
-
-static int hva_g_parm(struct file *file, void *fh, struct v4l2_streamparm *sp)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct v4l2_fract *time_per_frame = &ctx->ctrls.time_per_frame;
-
- if (sp->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
-
- sp->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
- sp->parm.output.timeperframe.numerator = time_per_frame->numerator;
- sp->parm.output.timeperframe.denominator =
- time_per_frame->denominator;
-
- return 0;
-}
-
-static int hva_s_parm(struct file *file, void *fh, struct v4l2_streamparm *sp)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct v4l2_fract *time_per_frame = &ctx->ctrls.time_per_frame;
-
- if (sp->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
-
- if (!sp->parm.output.timeperframe.numerator ||
- !sp->parm.output.timeperframe.denominator)
- return hva_g_parm(file, fh, sp);
-
- sp->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
- time_per_frame->numerator = sp->parm.output.timeperframe.numerator;
- time_per_frame->denominator =
- sp->parm.output.timeperframe.denominator;
-
- return 0;
-}
-
-static int hva_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct device *dev = ctx_to_dev(ctx);
-
- if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- /*
- * depending on the targeted compressed video format, the
- * capture buffer might contain headers (e.g. H.264 SPS/PPS)
- * filled in by the driver client; the size of these data is
- * copied from the bytesused field of the V4L2 buffer in the
- * payload field of the hva stream buffer
- */
- struct vb2_queue *vq;
- struct hva_stream *stream;
- struct vb2_buffer *vb2_buf;
-
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, buf->type);
-
- if (buf->index >= vq->num_buffers) {
- dev_dbg(dev, "%s buffer index %d out of range (%d)\n",
- ctx->name, buf->index, vq->num_buffers);
- return -EINVAL;
- }
-
- vb2_buf = vb2_get_buffer(vq, buf->index);
- stream = to_hva_stream(to_vb2_v4l2_buffer(vb2_buf));
- stream->bytesused = buf->bytesused;
- }
-
- return v4l2_m2m_qbuf(file, ctx->fh.m2m_ctx, buf);
-}
-
-/* V4L2 ioctl ops */
-static const struct v4l2_ioctl_ops hva_ioctl_ops = {
- .vidioc_querycap = hva_querycap,
- .vidioc_enum_fmt_vid_cap = hva_enum_fmt_stream,
- .vidioc_enum_fmt_vid_out = hva_enum_fmt_frame,
- .vidioc_g_fmt_vid_cap = hva_g_fmt_stream,
- .vidioc_g_fmt_vid_out = hva_g_fmt_frame,
- .vidioc_try_fmt_vid_cap = hva_try_fmt_stream,
- .vidioc_try_fmt_vid_out = hva_try_fmt_frame,
- .vidioc_s_fmt_vid_cap = hva_s_fmt_stream,
- .vidioc_s_fmt_vid_out = hva_s_fmt_frame,
- .vidioc_g_parm = hva_g_parm,
- .vidioc_s_parm = hva_s_parm,
- .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
- .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
- .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
- .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
- .vidioc_qbuf = hva_qbuf,
- .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
- .vidioc_streamon = v4l2_m2m_ioctl_streamon,
- .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
- .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-};
-
-/*
- * V4L2 control operations
- */
-
-static int hva_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct hva_ctx *ctx = container_of(ctrl->handler, struct hva_ctx,
- ctrl_handler);
- struct device *dev = ctx_to_dev(ctx);
-
- dev_dbg(dev, "%s S_CTRL: id = %d, val = %d\n", ctx->name,
- ctrl->id, ctrl->val);
-
- switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- ctx->ctrls.bitrate_mode = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- ctx->ctrls.gop_size = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- ctx->ctrls.bitrate = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- ctx->ctrls.aspect = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
- ctx->ctrls.profile = ctrl->val;
- snprintf(ctx->streaminfo.profile,
- sizeof(ctx->streaminfo.profile),
- "%s profile",
- v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]);
- break;
- case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
- ctx->ctrls.level = ctrl->val;
- snprintf(ctx->streaminfo.level,
- sizeof(ctx->streaminfo.level),
- "level %s",
- v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]);
- break;
- case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
- ctx->ctrls.entropy_mode = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
- ctx->ctrls.cpb_size = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
- ctx->ctrls.dct8x8 = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
- ctx->ctrls.qpmin = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
- ctx->ctrls.qpmax = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
- ctx->ctrls.vui_sar = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
- ctx->ctrls.vui_sar_idc = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING:
- ctx->ctrls.sei_fp = ctrl->val;
- break;
- case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
- ctx->ctrls.sei_fp_type = ctrl->val;
- break;
- default:
- dev_dbg(dev, "%s S_CTRL: invalid control (id = %d)\n",
- ctx->name, ctrl->id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* V4L2 control ops */
-static const struct v4l2_ctrl_ops hva_ctrl_ops = {
- .s_ctrl = hva_s_ctrl,
-};
-
-static int hva_ctrls_setup(struct hva_ctx *ctx)
-{
- struct device *dev = ctx_to_dev(ctx);
- u64 mask;
- enum v4l2_mpeg_video_h264_sei_fp_arrangement_type sei_fp_type =
- V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM;
-
- v4l2_ctrl_handler_init(&ctx->ctrl_handler, 15);
-
- v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
- 0,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_GOP_SIZE,
- 1, 60, 1, 16);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_BITRATE,
- 1000, 60000000, 1000, 20000000);
-
- mask = ~(1 << V4L2_MPEG_VIDEO_ASPECT_1x1);
- v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_ASPECT,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- mask,
- V4L2_MPEG_VIDEO_ASPECT_1x1);
-
- mask = ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
- (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
- (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
- (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH));
- v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_PROFILE,
- V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH,
- mask,
- V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
-
- v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_LEVEL,
- V4L2_MPEG_VIDEO_H264_LEVEL_4_2,
- 0,
- V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
-
- v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
- V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
- 0,
- V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,
- 1, 10000, 1, 3000);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
- 0, 1, 1, 0);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
- 0, 51, 1, 5);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
- 0, 51, 1, 51);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE,
- 0, 1, 1, 1);
-
- mask = ~(1 << V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
- v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1,
- mask,
- V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
-
- v4l2_ctrl_new_std(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING,
- 0, 1, 1, 0);
-
- mask = ~(1 << sei_fp_type);
- v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &hva_ctrl_ops,
- V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE,
- sei_fp_type,
- mask,
- sei_fp_type);
-
- if (ctx->ctrl_handler.error) {
- int err = ctx->ctrl_handler.error;
-
- dev_dbg(dev, "%s controls setup failed (%d)\n",
- ctx->name, err);
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
- return err;
- }
-
- v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
-
- /* set default time per frame */
- ctx->ctrls.time_per_frame.numerator = HVA_DEFAULT_FRAME_NUM;
- ctx->ctrls.time_per_frame.denominator = HVA_DEFAULT_FRAME_DEN;
-
- return 0;
-}
-
-/*
- * mem-to-mem operations
- */
-
-static void hva_run_work(struct work_struct *work)
-{
- struct hva_ctx *ctx = container_of(work, struct hva_ctx, run_work);
- struct vb2_v4l2_buffer *src_buf, *dst_buf;
- const struct hva_enc *enc = ctx->enc;
- struct hva_frame *frame;
- struct hva_stream *stream;
- int ret;
-
- /* protect instance against reentrancy */
- mutex_lock(&ctx->lock);
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- hva_dbg_perf_begin(ctx);
-#endif
-
- src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-
- frame = to_hva_frame(src_buf);
- stream = to_hva_stream(dst_buf);
- frame->vbuf.sequence = ctx->frame_num++;
-
- ret = enc->encode(ctx, frame, stream);
-
- vb2_set_plane_payload(&dst_buf->vb2_buf, 0, stream->bytesused);
- if (ret) {
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
- } else {
- /* propagate frame timestamp */
- dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
- dst_buf->field = V4L2_FIELD_NONE;
- dst_buf->sequence = ctx->stream_num - 1;
-
- ctx->encoded_frames++;
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- hva_dbg_perf_end(ctx, stream);
-#endif
-
- v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
- v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
- }
-
- mutex_unlock(&ctx->lock);
-
- v4l2_m2m_job_finish(ctx->hva_dev->m2m_dev, ctx->fh.m2m_ctx);
-}
-
-static void hva_device_run(void *priv)
-{
- struct hva_ctx *ctx = priv;
- struct hva_dev *hva = ctx_to_hdev(ctx);
-
- queue_work(hva->work_queue, &ctx->run_work);
-}
-
-static void hva_job_abort(void *priv)
-{
- struct hva_ctx *ctx = priv;
- struct device *dev = ctx_to_dev(ctx);
-
- dev_dbg(dev, "%s aborting job\n", ctx->name);
-
- ctx->aborting = true;
-}
-
-static int hva_job_ready(void *priv)
-{
- struct hva_ctx *ctx = priv;
- struct device *dev = ctx_to_dev(ctx);
-
- if (!v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx)) {
- dev_dbg(dev, "%s job not ready: no frame buffers\n",
- ctx->name);
- return 0;
- }
-
- if (!v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx)) {
- dev_dbg(dev, "%s job not ready: no stream buffers\n",
- ctx->name);
- return 0;
- }
-
- if (ctx->aborting) {
- dev_dbg(dev, "%s job not ready: aborting\n", ctx->name);
- return 0;
- }
-
- return 1;
-}
-
-/* mem-to-mem ops */
-static const struct v4l2_m2m_ops hva_m2m_ops = {
- .device_run = hva_device_run,
- .job_abort = hva_job_abort,
- .job_ready = hva_job_ready,
-};
-
-/*
- * VB2 queue operations
- */
-
-static int hva_queue_setup(struct vb2_queue *vq,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- struct hva_ctx *ctx = vb2_get_drv_priv(vq);
- struct device *dev = ctx_to_dev(ctx);
- unsigned int size;
-
- dev_dbg(dev, "%s %s queue setup: num_buffers %d\n", ctx->name,
- to_type_str(vq->type), *num_buffers);
-
- size = vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ?
- ctx->frameinfo.size : ctx->max_stream_size;
-
- if (*num_planes)
- return sizes[0] < size ? -EINVAL : 0;
-
- /* only one plane supported */
- *num_planes = 1;
- sizes[0] = size;
-
- return 0;
-}
-
-static int hva_buf_prepare(struct vb2_buffer *vb)
-{
- struct hva_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct device *dev = ctx_to_dev(ctx);
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-
- if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- struct hva_frame *frame = to_hva_frame(vbuf);
-
- if (vbuf->field == V4L2_FIELD_ANY)
- vbuf->field = V4L2_FIELD_NONE;
- if (vbuf->field != V4L2_FIELD_NONE) {
- dev_dbg(dev,
- "%s frame[%d] prepare: %d field not supported\n",
- ctx->name, vb->index, vbuf->field);
- return -EINVAL;
- }
-
- if (!frame->prepared) {
- /* get memory addresses */
- frame->vaddr = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
- frame->paddr = vb2_dma_contig_plane_dma_addr(
- &vbuf->vb2_buf, 0);
- frame->info = ctx->frameinfo;
- frame->prepared = true;
-
- dev_dbg(dev,
- "%s frame[%d] prepared; virt=%p, phy=%pad\n",
- ctx->name, vb->index,
- frame->vaddr, &frame->paddr);
- }
- } else {
- struct hva_stream *stream = to_hva_stream(vbuf);
-
- if (!stream->prepared) {
- /* get memory addresses */
- stream->vaddr = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
- stream->paddr = vb2_dma_contig_plane_dma_addr(
- &vbuf->vb2_buf, 0);
- stream->size = vb2_plane_size(&vbuf->vb2_buf, 0);
- stream->prepared = true;
-
- dev_dbg(dev,
- "%s stream[%d] prepared; virt=%p, phy=%pad\n",
- ctx->name, vb->index,
- stream->vaddr, &stream->paddr);
- }
- }
-
- return 0;
-}
-
-static void hva_buf_queue(struct vb2_buffer *vb)
-{
- struct hva_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-
- if (ctx->fh.m2m_ctx)
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-}
-
-static int hva_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct hva_ctx *ctx = vb2_get_drv_priv(vq);
- struct hva_dev *hva = ctx_to_hdev(ctx);
- struct device *dev = ctx_to_dev(ctx);
- struct vb2_v4l2_buffer *vbuf;
- int ret;
- unsigned int i;
- bool found = false;
-
- dev_dbg(dev, "%s %s start streaming\n", ctx->name,
- to_type_str(vq->type));
-
- /* open encoder when both start_streaming have been called */
- if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
- if (!vb2_start_streaming_called(&ctx->fh.m2m_ctx->cap_q_ctx.q))
- return 0;
- } else {
- if (!vb2_start_streaming_called(&ctx->fh.m2m_ctx->out_q_ctx.q))
- return 0;
- }
-
- /* store the instance context in the instances array */
- for (i = 0; i < HVA_MAX_INSTANCES; i++) {
- if (!hva->instances[i]) {
- hva->instances[i] = ctx;
- /* save the context identifier in the context */
- ctx->id = i;
- found = true;
- break;
- }
- }
-
- if (!found) {
- dev_err(dev, "%s maximum instances reached\n", ctx->name);
- ret = -ENOMEM;
- goto err;
- }
-
- hva->nb_of_instances++;
-
- if (!ctx->enc) {
- ret = hva_open_encoder(ctx,
- ctx->streaminfo.streamformat,
- ctx->frameinfo.pixelformat,
- &ctx->enc);
- if (ret < 0)
- goto err_ctx;
- }
-
- return 0;
-
-err_ctx:
- hva->instances[ctx->id] = NULL;
- hva->nb_of_instances--;
-err:
- if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- /* return of all pending buffers to vb2 (in queued state) */
- while ((vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
- v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_QUEUED);
- } else {
- /* return of all pending buffers to vb2 (in queued state) */
- while ((vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx)))
- v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_QUEUED);
- }
-
- ctx->sys_errors++;
-
- return ret;
-}
-
-static void hva_stop_streaming(struct vb2_queue *vq)
-{
- struct hva_ctx *ctx = vb2_get_drv_priv(vq);
- struct hva_dev *hva = ctx_to_hdev(ctx);
- struct device *dev = ctx_to_dev(ctx);
- const struct hva_enc *enc = ctx->enc;
- struct vb2_v4l2_buffer *vbuf;
-
- dev_dbg(dev, "%s %s stop streaming\n", ctx->name,
- to_type_str(vq->type));
-
- if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- /* return of all pending buffers to vb2 (in error state) */
- ctx->frame_num = 0;
- while ((vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
- v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
- } else {
- /* return of all pending buffers to vb2 (in error state) */
- ctx->stream_num = 0;
- while ((vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx)))
- v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
- }
-
- if ((V4L2_TYPE_IS_OUTPUT(vq->type) &&
- vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q)) ||
- (V4L2_TYPE_IS_CAPTURE(vq->type) &&
- vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q))) {
- dev_dbg(dev, "%s %s out=%d cap=%d\n",
- ctx->name, to_type_str(vq->type),
- vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q),
- vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q));
- return;
- }
-
- /* close encoder when both stop_streaming have been called */
- if (enc) {
- dev_dbg(dev, "%s %s encoder closed\n", ctx->name, enc->name);
- enc->close(ctx);
- ctx->enc = NULL;
-
- /* clear instance context in instances array */
- hva->instances[ctx->id] = NULL;
- hva->nb_of_instances--;
- }
-
- ctx->aborting = false;
-}
-
-/* VB2 queue ops */
-static const struct vb2_ops hva_qops = {
- .queue_setup = hva_queue_setup,
- .buf_prepare = hva_buf_prepare,
- .buf_queue = hva_buf_queue,
- .start_streaming = hva_start_streaming,
- .stop_streaming = hva_stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
-};
-
-/*
- * V4L2 file operations
- */
-
-static int queue_init(struct hva_ctx *ctx, struct vb2_queue *vq)
-{
- vq->io_modes = VB2_MMAP | VB2_DMABUF;
- vq->drv_priv = ctx;
- vq->ops = &hva_qops;
- vq->mem_ops = &vb2_dma_contig_memops;
- vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- vq->lock = &ctx->hva_dev->lock;
-
- return vb2_queue_init(vq);
-}
-
-static int hva_queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct hva_ctx *ctx = priv;
- int ret;
-
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- src_vq->buf_struct_size = sizeof(struct hva_frame);
- src_vq->min_buffers_needed = MIN_FRAMES;
- src_vq->dev = ctx->hva_dev->dev;
-
- ret = queue_init(ctx, src_vq);
- if (ret)
- return ret;
-
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- dst_vq->buf_struct_size = sizeof(struct hva_stream);
- dst_vq->min_buffers_needed = MIN_STREAMS;
- dst_vq->dev = ctx->hva_dev->dev;
-
- return queue_init(ctx, dst_vq);
-}
-
-static int hva_open(struct file *file)
-{
- struct hva_dev *hva = video_drvdata(file);
- struct device *dev = hva_to_dev(hva);
- struct hva_ctx *ctx;
- int ret;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx) {
- ret = -ENOMEM;
- goto out;
- }
- ctx->hva_dev = hva;
-
- INIT_WORK(&ctx->run_work, hva_run_work);
- v4l2_fh_init(&ctx->fh, video_devdata(file));
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
-
- ret = hva_ctrls_setup(ctx);
- if (ret) {
- dev_err(dev, "%s [x:x] failed to setup controls\n",
- HVA_PREFIX);
- ctx->sys_errors++;
- goto err_fh;
- }
- ctx->fh.ctrl_handler = &ctx->ctrl_handler;
-
- mutex_init(&ctx->lock);
-
- ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(hva->m2m_dev, ctx,
- &hva_queue_init);
- if (IS_ERR(ctx->fh.m2m_ctx)) {
- ret = PTR_ERR(ctx->fh.m2m_ctx);
- dev_err(dev, "%s failed to initialize m2m context (%d)\n",
- HVA_PREFIX, ret);
- ctx->sys_errors++;
- goto err_ctrls;
- }
-
- /* set the instance name */
- mutex_lock(&hva->lock);
- hva->instance_id++;
- snprintf(ctx->name, sizeof(ctx->name), "[%3d:----]",
- hva->instance_id);
- mutex_unlock(&hva->lock);
-
- /* default parameters for frame and stream */
- set_default_params(ctx);
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- hva_dbg_ctx_create(ctx);
-#endif
-
- dev_info(dev, "%s encoder instance created\n", ctx->name);
-
- return 0;
-
-err_ctrls:
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
-err_fh:
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
-out:
- return ret;
-}
-
-static int hva_release(struct file *file)
-{
- struct hva_ctx *ctx = fh_to_ctx(file->private_data);
- struct hva_dev *hva = ctx_to_hdev(ctx);
- struct device *dev = ctx_to_dev(ctx);
- const struct hva_enc *enc = ctx->enc;
-
- if (enc) {
- dev_dbg(dev, "%s %s encoder closed\n", ctx->name, enc->name);
- enc->close(ctx);
- ctx->enc = NULL;
-
- /* clear instance context in instances array */
- hva->instances[ctx->id] = NULL;
- hva->nb_of_instances--;
- }
-
- /* trace a summary of instance before closing (debug purpose) */
- hva_dbg_summary(ctx);
-
- v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
-
- v4l2_ctrl_handler_free(&ctx->ctrl_handler);
-
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- hva_dbg_ctx_remove(ctx);
-#endif
-
- dev_info(dev, "%s encoder instance released\n", ctx->name);
-
- kfree(ctx);
-
- return 0;
-}
-
-/* V4L2 file ops */
-static const struct v4l2_file_operations hva_fops = {
- .owner = THIS_MODULE,
- .open = hva_open,
- .release = hva_release,
- .unlocked_ioctl = video_ioctl2,
- .mmap = v4l2_m2m_fop_mmap,
- .poll = v4l2_m2m_fop_poll,
-};
-
-/*
- * Platform device operations
- */
-
-static int hva_register_device(struct hva_dev *hva)
-{
- int ret;
- struct video_device *vdev;
- struct device *dev;
-
- if (!hva)
- return -ENODEV;
- dev = hva_to_dev(hva);
-
- hva->m2m_dev = v4l2_m2m_init(&hva_m2m_ops);
- if (IS_ERR(hva->m2m_dev)) {
- dev_err(dev, "%s failed to initialize v4l2-m2m device\n",
- HVA_PREFIX);
- ret = PTR_ERR(hva->m2m_dev);
- goto err;
- }
-
- vdev = video_device_alloc();
- if (!vdev) {
- dev_err(dev, "%s failed to allocate video device\n",
- HVA_PREFIX);
- ret = -ENOMEM;
- goto err_m2m_release;
- }
-
- vdev->fops = &hva_fops;
- vdev->ioctl_ops = &hva_ioctl_ops;
- vdev->release = video_device_release;
- vdev->lock = &hva->lock;
- vdev->vfl_dir = VFL_DIR_M2M;
- vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
- vdev->v4l2_dev = &hva->v4l2_dev;
- snprintf(vdev->name, sizeof(vdev->name), "%s%lx", HVA_NAME,
- hva->ip_version);
-
- ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
- if (ret) {
- dev_err(dev, "%s failed to register video device\n",
- HVA_PREFIX);
- goto err_vdev_release;
- }
-
- hva->vdev = vdev;
- video_set_drvdata(vdev, hva);
- return 0;
-
-err_vdev_release:
- video_device_release(vdev);
-err_m2m_release:
- v4l2_m2m_release(hva->m2m_dev);
-err:
- return ret;
-}
-
-static void hva_unregister_device(struct hva_dev *hva)
-{
- if (!hva)
- return;
-
- if (hva->m2m_dev)
- v4l2_m2m_release(hva->m2m_dev);
-
- video_unregister_device(hva->vdev);
-}
-
-static int hva_probe(struct platform_device *pdev)
-{
- struct hva_dev *hva;
- struct device *dev = &pdev->dev;
- int ret;
-
- hva = devm_kzalloc(dev, sizeof(*hva), GFP_KERNEL);
- if (!hva) {
- ret = -ENOMEM;
- goto err;
- }
-
- ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
- if (ret)
- return ret;
-
- hva->dev = dev;
- hva->pdev = pdev;
- platform_set_drvdata(pdev, hva);
-
- mutex_init(&hva->lock);
-
- /* probe hardware */
- ret = hva_hw_probe(pdev, hva);
- if (ret)
- goto err;
-
- /* register all available encoders */
- register_encoders(hva);
-
- /* register all supported formats */
- register_formats(hva);
-
- /* register on V4L2 */
- ret = v4l2_device_register(dev, &hva->v4l2_dev);
- if (ret) {
- dev_err(dev, "%s %s failed to register V4L2 device\n",
- HVA_PREFIX, HVA_NAME);
- goto err_hw;
- }
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- hva_debugfs_create(hva);
-#endif
-
- hva->work_queue = create_workqueue(HVA_NAME);
- if (!hva->work_queue) {
- dev_err(dev, "%s %s failed to allocate work queue\n",
- HVA_PREFIX, HVA_NAME);
- ret = -ENOMEM;
- goto err_v4l2;
- }
-
- /* register device */
- ret = hva_register_device(hva);
- if (ret)
- goto err_work_queue;
-
- dev_info(dev, "%s %s registered as /dev/video%d\n", HVA_PREFIX,
- HVA_NAME, hva->vdev->num);
-
- return 0;
-
-err_work_queue:
- destroy_workqueue(hva->work_queue);
-err_v4l2:
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- hva_debugfs_remove(hva);
-#endif
- v4l2_device_unregister(&hva->v4l2_dev);
-err_hw:
- hva_hw_remove(hva);
-err:
- return ret;
-}
-
-static int hva_remove(struct platform_device *pdev)
-{
- struct hva_dev *hva = platform_get_drvdata(pdev);
- struct device *dev = hva_to_dev(hva);
-
- hva_unregister_device(hva);
-
- destroy_workqueue(hva->work_queue);
-
- hva_hw_remove(hva);
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- hva_debugfs_remove(hva);
-#endif
-
- v4l2_device_unregister(&hva->v4l2_dev);
-
- dev_info(dev, "%s %s removed\n", HVA_PREFIX, pdev->name);
-
- return 0;
-}
-
-/* PM ops */
-static const struct dev_pm_ops hva_pm_ops = {
- .runtime_suspend = hva_hw_runtime_suspend,
- .runtime_resume = hva_hw_runtime_resume,
-};
-
-static const struct of_device_id hva_match_types[] = {
- {
- .compatible = "st,st-hva",
- },
- { /* end node */ }
-};
-
-MODULE_DEVICE_TABLE(of, hva_match_types);
-
-static struct platform_driver hva_driver = {
- .probe = hva_probe,
- .remove = hva_remove,
- .driver = {
- .name = HVA_NAME,
- .of_match_table = hva_match_types,
- .pm = &hva_pm_ops,
- },
-};
-
-module_platform_driver(hva_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
-MODULE_DESCRIPTION("STMicroelectronics HVA video encoder V4L2 driver");
diff --git a/drivers/media/platform/sti/hva/hva.h b/drivers/media/platform/sti/hva/hva.h
deleted file mode 100644
index ba6b893416ec..000000000000
--- a/drivers/media/platform/sti/hva/hva.h
+++ /dev/null
@@ -1,409 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) STMicroelectronics SA 2015
- * Authors: Yannick Fertre <yannick.fertre@st.com>
- * Hugues Fruchet <hugues.fruchet@st.com>
- */
-
-#ifndef HVA_H
-#define HVA_H
-
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/v4l2-mem2mem.h>
-
-#define fh_to_ctx(f) (container_of(f, struct hva_ctx, fh))
-
-#define hva_to_dev(h) (h->dev)
-
-#define ctx_to_dev(c) (c->hva_dev->dev)
-
-#define ctx_to_hdev(c) (c->hva_dev)
-
-#define HVA_NAME "st-hva"
-#define HVA_PREFIX "[---:----]"
-
-extern const struct hva_enc nv12h264enc;
-extern const struct hva_enc nv21h264enc;
-
-/**
- * struct hva_frameinfo - information about hva frame
- *
- * @pixelformat: fourcc code for uncompressed video format
- * @width: width of frame
- * @height: height of frame
- * @aligned_width: width of frame (with encoder alignment constraint)
- * @aligned_height: height of frame (with encoder alignment constraint)
- * @size: maximum size in bytes required for data
-*/
-struct hva_frameinfo {
- u32 pixelformat;
- u32 width;
- u32 height;
- u32 aligned_width;
- u32 aligned_height;
- u32 size;
-};
-
-/**
- * struct hva_streaminfo - information about hva stream
- *
- * @streamformat: fourcc code of compressed video format (H.264...)
- * @width: width of stream
- * @height: height of stream
- * @profile: profile string
- * @level: level string
- */
-struct hva_streaminfo {
- u32 streamformat;
- u32 width;
- u32 height;
- u8 profile[32];
- u8 level[32];
-};
-
-/**
- * struct hva_controls - hva controls set
- *
- * @time_per_frame: time per frame in seconds
- * @bitrate_mode: bitrate mode (constant bitrate or variable bitrate)
- * @gop_size: groupe of picture size
- * @bitrate: bitrate (in bps)
- * @aspect: video aspect
- * @profile: H.264 profile
- * @level: H.264 level
- * @entropy_mode: H.264 entropy mode (CABAC or CVLC)
- * @cpb_size: coded picture buffer size (in kB)
- * @dct8x8: transform mode 8x8 enable
- * @qpmin: minimum quantizer
- * @qpmax: maximum quantizer
- * @vui_sar: pixel aspect ratio enable
- * @vui_sar_idc: pixel aspect ratio identifier
- * @sei_fp: sei frame packing arrangement enable
- * @sei_fp_type: sei frame packing arrangement type
- */
-struct hva_controls {
- struct v4l2_fract time_per_frame;
- enum v4l2_mpeg_video_bitrate_mode bitrate_mode;
- u32 gop_size;
- u32 bitrate;
- enum v4l2_mpeg_video_aspect aspect;
- enum v4l2_mpeg_video_h264_profile profile;
- enum v4l2_mpeg_video_h264_level level;
- enum v4l2_mpeg_video_h264_entropy_mode entropy_mode;
- u32 cpb_size;
- bool dct8x8;
- u32 qpmin;
- u32 qpmax;
- bool vui_sar;
- enum v4l2_mpeg_video_h264_vui_sar_idc vui_sar_idc;
- bool sei_fp;
- enum v4l2_mpeg_video_h264_sei_fp_arrangement_type sei_fp_type;
-};
-
-/**
- * struct hva_frame - hva frame buffer (output)
- *
- * @vbuf: video buffer information for V4L2
- * @list: V4L2 m2m list that the frame belongs to
- * @info: frame information (width, height, format, alignment...)
- * @paddr: physical address (for hardware)
- * @vaddr: virtual address (kernel can read/write)
- * @prepared: true if vaddr/paddr are resolved
- */
-struct hva_frame {
- struct vb2_v4l2_buffer vbuf;
- struct list_head list;
- struct hva_frameinfo info;
- dma_addr_t paddr;
- void *vaddr;
- bool prepared;
-};
-
-/*
- * to_hva_frame() - cast struct vb2_v4l2_buffer * to struct hva_frame *
- */
-#define to_hva_frame(vb) \
- container_of(vb, struct hva_frame, vbuf)
-
-/**
- * struct hva_stream - hva stream buffer (capture)
- *
- * @vbuf: video buffer information for V4L2
- * @list: V4L2 m2m list that the frame belongs to
- * @paddr: physical address (for hardware)
- * @vaddr: virtual address (kernel can read/write)
- * @prepared: true if vaddr/paddr are resolved
- * @size: size of the buffer in bytes
- * @bytesused: number of bytes occupied by data in the buffer
- */
-struct hva_stream {
- struct vb2_v4l2_buffer vbuf;
- struct list_head list;
- dma_addr_t paddr;
- void *vaddr;
- bool prepared;
- unsigned int size;
- unsigned int bytesused;
-};
-
-/*
- * to_hva_stream() - cast struct vb2_v4l2_buffer * to struct hva_stream *
- */
-#define to_hva_stream(vb) \
- container_of(vb, struct hva_stream, vbuf)
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
-/**
- * struct hva_ctx_dbg - instance context debug info
- *
- * @debugfs_entry: debugfs entry
- * @is_valid_period: true if the sequence is valid for performance
- * @begin: start time of last HW task
- * @total_duration: total HW processing durations in 0.1ms
- * @cnt_duration: number of HW processings
- * @min_duration: minimum HW processing duration in 0.1ms
- * @max_duration: maximum HW processing duration in 0.1ms
- * @avg_duration: average HW processing duration in 0.1ms
- * @max_fps: maximum frames encoded per second (in 0.1Hz)
- * @total_period: total encoding periods in 0.1ms
- * @cnt_period: number of periods
- * @min_period: minimum encoding period in 0.1ms
- * @max_period: maximum encoding period in 0.1ms
- * @avg_period: average encoding period in 0.1ms
- * @total_stream_size: total number of encoded bytes
- * @avg_fps: average frames encoded per second (in 0.1Hz)
- * @window_duration: duration of the sampling window in 0.1ms
- * @cnt_window: number of samples in the window
- * @window_stream_size: number of encoded bytes upon the sampling window
- * @last_bitrate: bitrate upon the last sampling window
- * @min_bitrate: minimum bitrate in kbps
- * @max_bitrate: maximum bitrate in kbps
- * @avg_bitrate: average bitrate in kbps
- */
-struct hva_ctx_dbg {
- struct dentry *debugfs_entry;
- bool is_valid_period;
- ktime_t begin;
- u32 total_duration;
- u32 cnt_duration;
- u32 min_duration;
- u32 max_duration;
- u32 avg_duration;
- u32 max_fps;
- u32 total_period;
- u32 cnt_period;
- u32 min_period;
- u32 max_period;
- u32 avg_period;
- u32 total_stream_size;
- u32 avg_fps;
- u32 window_duration;
- u32 cnt_window;
- u32 window_stream_size;
- u32 last_bitrate;
- u32 min_bitrate;
- u32 max_bitrate;
- u32 avg_bitrate;
-};
-#endif
-
-struct hva_dev;
-struct hva_enc;
-
-/**
- * struct hva_ctx - context of hva instance
- *
- * @hva_dev: the device that this instance is associated with
- * @fh: V4L2 file handle
- * @ctrl_handler: V4L2 controls handler
- * @ctrls: hva controls set
- * @id: instance identifier
- * @aborting: true if current job aborted
- * @name: instance name (debug purpose)
- * @run_work: encode work
- * @lock: mutex used to lock access of this context
- * @flags: validity of streaminfo and frameinfo fields
- * @frame_num: frame number
- * @stream_num: stream number
- * @max_stream_size: maximum size in bytes required for stream data
- * @colorspace: colorspace identifier
- * @xfer_func: transfer function identifier
- * @ycbcr_enc: Y'CbCr encoding identifier
- * @quantization: quantization identifier
- * @streaminfo: stream properties
- * @frameinfo: frame properties
- * @enc: current encoder
- * @priv: private codec data for this instance, allocated
- * by encoder @open time
- * @hw_err: true if hardware error detected
- * @encoded_frames: number of encoded frames
- * @sys_errors: number of system errors (memory, resource, pm...)
- * @encode_errors: number of encoding errors (hw/driver errors)
- * @frame_errors: number of frame errors (format, size, header...)
- * @dbg: context debug info
- */
-struct hva_ctx {
- struct hva_dev *hva_dev;
- struct v4l2_fh fh;
- struct v4l2_ctrl_handler ctrl_handler;
- struct hva_controls ctrls;
- u8 id;
- bool aborting;
- char name[100];
- struct work_struct run_work;
- /* mutex protecting this data structure */
- struct mutex lock;
- u32 flags;
- u32 frame_num;
- u32 stream_num;
- u32 max_stream_size;
- enum v4l2_colorspace colorspace;
- enum v4l2_xfer_func xfer_func;
- enum v4l2_ycbcr_encoding ycbcr_enc;
- enum v4l2_quantization quantization;
- struct hva_streaminfo streaminfo;
- struct hva_frameinfo frameinfo;
- struct hva_enc *enc;
- void *priv;
- bool hw_err;
- u32 encoded_frames;
- u32 sys_errors;
- u32 encode_errors;
- u32 frame_errors;
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- struct hva_ctx_dbg dbg;
-#endif
-};
-
-#define HVA_FLAG_STREAMINFO 0x0001
-#define HVA_FLAG_FRAMEINFO 0x0002
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
-/**
- * struct hva_dev_dbg - device debug info
- *
- * @debugfs_entry: debugfs entry
- * @last_ctx: debug information about last running instance context
- */
-struct hva_dev_dbg {
- struct dentry *debugfs_entry;
- struct hva_ctx last_ctx;
-};
-#endif
-
-#define HVA_MAX_INSTANCES 16
-#define HVA_MAX_ENCODERS 10
-#define HVA_MAX_FORMATS HVA_MAX_ENCODERS
-
-/**
- * struct hva_dev - abstraction for hva entity
- *
- * @v4l2_dev: V4L2 device
- * @vdev: video device
- * @pdev: platform device
- * @dev: device
- * @lock: mutex used for critical sections & V4L2 ops
- * serialization
- * @m2m_dev: memory-to-memory V4L2 device information
- * @instances: opened instances
- * @nb_of_instances: number of opened instances
- * @instance_id: rolling counter identifying an instance (debug purpose)
- * @regs: register io memory access
- * @esram_addr: esram address
- * @esram_size: esram size
- * @clk: hva clock
- * @irq_its: status interruption
- * @irq_err: error interruption
- * @work_queue: work queue to handle the encode jobs
- * @protect_mutex: mutex used to lock access of hardware
- * @interrupt: completion interrupt
- * @ip_version: IP hardware version
- * @encoders: registered encoders
- * @nb_of_encoders: number of registered encoders
- * @pixelformats: supported uncompressed video formats
- * @nb_of_pixelformats: number of supported umcompressed video formats
- * @streamformats: supported compressed video formats
- * @nb_of_streamformats: number of supported compressed video formats
- * @sfl_reg: status fifo level register value
- * @sts_reg: status register value
- * @lmi_err_reg: local memory interface error register value
- * @emi_err_reg: external memory interface error register value
- * @hec_mif_err_reg: HEC memory interface error register value
- * @dbg: device debug info
- */
-struct hva_dev {
- struct v4l2_device v4l2_dev;
- struct video_device *vdev;
- struct platform_device *pdev;
- struct device *dev;
- /* mutex protecting vb2_queue structure */
- struct mutex lock;
- struct v4l2_m2m_dev *m2m_dev;
- struct hva_ctx *instances[HVA_MAX_INSTANCES];
- unsigned int nb_of_instances;
- unsigned int instance_id;
- void __iomem *regs;
- u32 esram_addr;
- u32 esram_size;
- struct clk *clk;
- int irq_its;
- int irq_err;
- struct workqueue_struct *work_queue;
- /* mutex protecting hardware access */
- struct mutex protect_mutex;
- struct completion interrupt;
- unsigned long int ip_version;
- const struct hva_enc *encoders[HVA_MAX_ENCODERS];
- u32 nb_of_encoders;
- u32 pixelformats[HVA_MAX_FORMATS];
- u32 nb_of_pixelformats;
- u32 streamformats[HVA_MAX_FORMATS];
- u32 nb_of_streamformats;
- u32 sfl_reg;
- u32 sts_reg;
- u32 lmi_err_reg;
- u32 emi_err_reg;
- u32 hec_mif_err_reg;
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
- struct hva_dev_dbg dbg;
-#endif
-};
-
-/**
- * struct hva_enc - hva encoder
- *
- * @name: encoder name
- * @streamformat: fourcc code for compressed video format (H.264...)
- * @pixelformat: fourcc code for uncompressed video format
- * @max_width: maximum width of frame for this encoder
- * @max_height: maximum height of frame for this encoder
- * @open: open encoder
- * @close: close encoder
- * @encode: encode a frame (struct hva_frame) in a stream
- * (struct hva_stream)
- */
-
-struct hva_enc {
- const char *name;
- u32 streamformat;
- u32 pixelformat;
- u32 max_width;
- u32 max_height;
- int (*open)(struct hva_ctx *ctx);
- int (*close)(struct hva_ctx *ctx);
- int (*encode)(struct hva_ctx *ctx, struct hva_frame *frame,
- struct hva_stream *stream);
-};
-
-#ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
-void hva_debugfs_create(struct hva_dev *hva);
-void hva_debugfs_remove(struct hva_dev *hva);
-void hva_dbg_ctx_create(struct hva_ctx *ctx);
-void hva_dbg_ctx_remove(struct hva_ctx *ctx);
-void hva_dbg_perf_begin(struct hva_ctx *ctx);
-void hva_dbg_perf_end(struct hva_ctx *ctx, struct hva_stream *stream);
-#endif
-
-#endif /* HVA_H */