vidc_3x: Add snapshot of video driver
This is snapshot of the video driver as of msm-4.14(vidc_3x) commit 9dc1a255ba77c95 (" Fix qbuf error in gralloc buffers encoding"). Change-Id: I146b66cb0e0ce44d8414efaa8748c2de87b9fc74 Signed-off-by: Vasantha Balla <vballa@codeaurora.org>
This commit is contained in:
parent
74de771171
commit
6e7d1f9d72
53 changed files with 37856 additions and 4 deletions
|
@ -410,6 +410,8 @@ CONFIG_VIDEO_FIXED_MINOR_RANGES=y
|
|||
CONFIG_MEDIA_USB_SUPPORT=y
|
||||
CONFIG_USB_VIDEO_CLASS=y
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_MSM_VIDC_3X_GOVERNORS=y
|
||||
CONFIG_MSM_VIDC_3X_V4L2=y
|
||||
CONFIG_DVB_MPQ=m
|
||||
CONFIG_DVB_MPQ_DEMUX=m
|
||||
CONFIG_FB=y
|
||||
|
|
2
arch/arm64/configs/vendor/sdm660_defconfig
vendored
2
arch/arm64/configs/vendor/sdm660_defconfig
vendored
|
@ -411,6 +411,8 @@ CONFIG_VIDEO_FIXED_MINOR_RANGES=y
|
|||
CONFIG_MEDIA_USB_SUPPORT=y
|
||||
CONFIG_USB_VIDEO_CLASS=y
|
||||
CONFIG_V4L_PLATFORM_DRIVERS=y
|
||||
CONFIG_MSM_VIDC_3X_GOVERNORS=y
|
||||
CONFIG_MSM_VIDC_3X_V4L2=y
|
||||
CONFIG_DVB_MPQ=m
|
||||
CONFIG_DVB_MPQ_DEMUX=m
|
||||
CONFIG_FB=y
|
||||
|
|
|
@ -9,6 +9,7 @@ menuconfig SPECTRA_CAMERA
|
|||
Enabling this adds support for the camera driver stack including sensor,
|
||||
IFE and postprocessing drivers.
|
||||
|
||||
source "drivers/media/platform/msm/vidc_3x/Kconfig"
|
||||
source "drivers/media/platform/msm/cvp/Kconfig"
|
||||
source "drivers/media/platform/msm/npu/Kconfig"
|
||||
source "drivers/media/platform/msm/synx/Kconfig"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# Makefile for the qti specific video device drivers
|
||||
# based on V4L2.
|
||||
#
|
||||
obj-$(CONFIG_MSM_VIDC_3X_V4L2) += vidc_3x/
|
||||
obj-$(CONFIG_MSM_CVP_V4L2) += cvp/
|
||||
obj-$(CONFIG_MSM_NPU) += npu/
|
||||
obj-$(CONFIG_MSM_GLOBAL_SYNX) += synx/
|
||||
|
|
14
drivers/media/platform/msm/vidc_3x/Kconfig
Normal file
14
drivers/media/platform/msm/vidc_3x/Kconfig
Normal file
|
@ -0,0 +1,14 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# VIDEO CORE
|
||||
#
|
||||
source "drivers/media/platform/msm/vidc_3x/governors/Kconfig"
|
||||
|
||||
menuconfig MSM_VIDC_3X_V4L2
|
||||
tristate "Qualcomm Technologies, Inc. MSM V4L2 3X based video driver"
|
||||
depends on ARCH_QCOM && VIDEO_V4L2
|
||||
select VIDEOBUF2_CORE
|
||||
help
|
||||
Enable support of MSM V4L2 3X based video driver for
|
||||
Qualcomm Technologies, Inc.
|
||||
|
19
drivers/media/platform/msm/vidc_3x/Makefile
Normal file
19
drivers/media/platform/msm/vidc_3x/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_MSM_VIDC_3X_V4L2) := msm_v4l2_vidc.o \
|
||||
msm_vidc_common.o \
|
||||
msm_vidc.o \
|
||||
msm_vdec.o \
|
||||
msm_venc.o \
|
||||
msm_smem.o \
|
||||
msm_vidc_debug.o \
|
||||
msm_vidc_res_parse.o \
|
||||
venus_hfi.o \
|
||||
hfi_response_handler.o \
|
||||
hfi_packetization.o \
|
||||
vidc_hfi.o \
|
||||
venus_boot.o \
|
||||
msm_vidc_dcvs.o
|
||||
|
||||
obj-$(CONFIG_MSM_VIDC_3X_V4L2) += governors/
|
||||
|
||||
obj-$(CONFIG_MSM_VIDC_VMEM) += vmem/
|
7
drivers/media/platform/msm/vidc_3x/governors/Kconfig
Normal file
7
drivers/media/platform/msm/vidc_3x/governors/Kconfig
Normal file
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
menuconfig MSM_VIDC_3X_GOVERNORS
|
||||
tristate "Clock and bandwidth governors for QTI MSM V4L2 based video driver"
|
||||
depends on MSM_VIDC_3X_V4L2 && PM_DEVFREQ
|
||||
help
|
||||
Chooses a set of devfreq governors aimed at providing accurate bandwidth
|
||||
or clock frequency values for MSM V4L2 video driver.
|
6
drivers/media/platform/msm/vidc_3x/governors/Makefile
Normal file
6
drivers/media/platform/msm/vidc_3x/governors/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
ccflags-y := -I$(srctree)/drivers/devfreq/ \
|
||||
-I$(srctree)/drivers/media/platform/msm/vidc_3x/
|
||||
|
||||
obj-$(CONFIG_MSM_VIDC_3X_GOVERNORS) := msm_vidc_dyn_gov.o \
|
||||
msm_vidc_table_gov.o
|
74
drivers/media/platform/msm/vidc_3x/governors/fixedpoint.h
Normal file
74
drivers/media/platform/msm/vidc_3x/governors/fixedpoint.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015, 2019-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifdef _FIXP_ARITH_H
|
||||
#error "This implementation is meant to override fixp-arith.h, don't use both"
|
||||
#endif
|
||||
|
||||
#ifndef __FP_H__
|
||||
#define __FP_H__
|
||||
|
||||
/*
|
||||
* Normally would typedef'ed, but checkpatch doesn't like typedef.
|
||||
* Also should be normally typedef'ed to intmax_t but that doesn't seem to be
|
||||
* available in the kernel
|
||||
*/
|
||||
#define fp_t size_t
|
||||
|
||||
/* (Arbitrarily) make the first 25% of the bits to be the fractional bits */
|
||||
#define FP_FRACTIONAL_BITS ((sizeof(fp_t) * 8) / 4)
|
||||
|
||||
#define FP(__i, __f_n, __f_d) \
|
||||
((((fp_t)(__i)) << FP_FRACTIONAL_BITS) + \
|
||||
(((__f_n) << FP_FRACTIONAL_BITS) / (__f_d)))
|
||||
|
||||
#define FP_INT(__i) FP(__i, 0, 1)
|
||||
#define FP_ONE FP_INT(1)
|
||||
#define FP_ZERO FP_INT(0)
|
||||
|
||||
static inline size_t fp_frac_base(void)
|
||||
{
|
||||
return GENMASK(FP_FRACTIONAL_BITS - 1, 0);
|
||||
}
|
||||
|
||||
static inline size_t fp_frac(fp_t a)
|
||||
{
|
||||
return a & GENMASK(FP_FRACTIONAL_BITS - 1, 0);
|
||||
}
|
||||
|
||||
static inline size_t fp_int(fp_t a)
|
||||
{
|
||||
return a >> FP_FRACTIONAL_BITS;
|
||||
}
|
||||
|
||||
static inline size_t fp_round(fp_t a)
|
||||
{
|
||||
/* is the fractional part >= frac_max / 2? */
|
||||
bool round_up = fp_frac(a) >= fp_frac_base() / 2;
|
||||
|
||||
return fp_int(a) + round_up;
|
||||
}
|
||||
|
||||
static inline fp_t fp_mult(fp_t a, fp_t b)
|
||||
{
|
||||
return (a * b) >> FP_FRACTIONAL_BITS;
|
||||
}
|
||||
|
||||
|
||||
static inline fp_t fp_div(fp_t a, fp_t b)
|
||||
{
|
||||
return (a << FP_FRACTIONAL_BITS) / b;
|
||||
}
|
||||
|
||||
#endif
|
1036
drivers/media/platform/msm/vidc_3x/governors/msm_vidc_dyn_gov.c
Normal file
1036
drivers/media/platform/msm/vidc_3x/governors/msm_vidc_dyn_gov.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,380 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2016, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/string.h>
|
||||
#include "governor.h"
|
||||
#include "../msm_vidc_debug.h"
|
||||
#include "../msm_vidc_res_parse.h"
|
||||
#include "../msm_vidc_internal.h"
|
||||
#include "../venus_hfi.h"
|
||||
#include "../vidc_hfi_api.h"
|
||||
|
||||
|
||||
enum bus_profile {
|
||||
VIDC_BUS_PROFILE_NORMAL = BIT(0),
|
||||
VIDC_BUS_PROFILE_LOW = BIT(1),
|
||||
VIDC_BUS_PROFILE_UBWC = BIT(2),
|
||||
};
|
||||
|
||||
struct bus_profile_entry {
|
||||
struct {
|
||||
u32 load, freq;
|
||||
} *bus_table;
|
||||
u32 bus_table_size;
|
||||
u32 codec_mask;
|
||||
enum bus_profile profile;
|
||||
};
|
||||
|
||||
struct msm_vidc_bus_table_gov {
|
||||
struct bus_profile_entry *bus_prof_entries;
|
||||
u32 count;
|
||||
struct devfreq_governor devfreq_gov;
|
||||
};
|
||||
|
||||
static int __get_bus_freq(struct msm_vidc_bus_table_gov *gov,
|
||||
struct vidc_bus_vote_data *data,
|
||||
enum bus_profile profile)
|
||||
{
|
||||
int i = 0, load = 0, freq = 0;
|
||||
enum vidc_vote_data_session sess_type = 0;
|
||||
struct bus_profile_entry *entry = NULL;
|
||||
bool found = false;
|
||||
|
||||
load = NUM_MBS_PER_SEC(data->width, data->height, data->fps);
|
||||
sess_type = VIDC_VOTE_DATA_SESSION_VAL(data->codec, data->domain);
|
||||
|
||||
/* check if ubwc bus profile is present */
|
||||
for (i = 0; i < gov->count; i++) {
|
||||
entry = &gov->bus_prof_entries[i];
|
||||
if (!entry->bus_table || !entry->bus_table_size)
|
||||
continue;
|
||||
if (!venus_hfi_is_session_supported(
|
||||
entry->codec_mask, sess_type))
|
||||
continue;
|
||||
if (entry->profile == profile) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
/* loop over bus table and select frequency */
|
||||
for (i = entry->bus_table_size - 1; i >= 0; --i) {
|
||||
/*load is arranged in descending order */
|
||||
freq = entry->bus_table[i].freq;
|
||||
if (load <= entry->bus_table[i].load)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return freq;
|
||||
}
|
||||
|
||||
|
||||
static int msm_vidc_table_get_target_freq(struct devfreq *dev,
|
||||
unsigned long *frequency)
|
||||
{
|
||||
struct devfreq_dev_status status = {0};
|
||||
struct msm_vidc_gov_data *vidc_data = NULL;
|
||||
struct msm_vidc_bus_table_gov *gov = NULL;
|
||||
enum bus_profile profile = 0;
|
||||
int i = 0;
|
||||
|
||||
if (!dev || !frequency) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid params %pK, %pK\n",
|
||||
__func__, dev, frequency);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gov = container_of(dev->governor,
|
||||
struct msm_vidc_bus_table_gov, devfreq_gov);
|
||||
if (!gov) {
|
||||
dprintk(VIDC_ERR, "%s: governor not found\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev->profile->get_dev_status(dev->dev.parent, &status);
|
||||
vidc_data = (struct msm_vidc_gov_data *)status.private_data;
|
||||
|
||||
*frequency = 0;
|
||||
for (i = 0; i < vidc_data->data_count; i++) {
|
||||
struct vidc_bus_vote_data *data = &vidc_data->data[i];
|
||||
int freq = 0;
|
||||
|
||||
if (data->power_mode == VIDC_POWER_TURBO) {
|
||||
dprintk(VIDC_DBG, "bus: found turbo session[%d] %#x\n",
|
||||
i, VIDC_VOTE_DATA_SESSION_VAL(data->codec,
|
||||
data->domain));
|
||||
*frequency = INT_MAX;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
profile = VIDC_BUS_PROFILE_NORMAL;
|
||||
if (data->color_formats[0] == HAL_COLOR_FORMAT_NV12_TP10_UBWC ||
|
||||
data->color_formats[0] == HAL_COLOR_FORMAT_NV12_UBWC)
|
||||
profile = VIDC_BUS_PROFILE_UBWC;
|
||||
|
||||
freq = __get_bus_freq(gov, data, profile);
|
||||
|
||||
/* chose frequency from normal profile
|
||||
* if specific profile frequency was not found.
|
||||
*/
|
||||
if (!freq)
|
||||
freq = __get_bus_freq(gov, data,
|
||||
VIDC_BUS_PROFILE_NORMAL);
|
||||
|
||||
*frequency += (unsigned long)freq;
|
||||
|
||||
dprintk(VIDC_DBG,
|
||||
"session[%d] %#x: wxh %dx%d, fps %d, bus_profile %#x, freq %d, total_freq %ld KBps\n",
|
||||
i, VIDC_VOTE_DATA_SESSION_VAL(
|
||||
data->codec, data->domain), data->width,
|
||||
data->height, data->fps, profile,
|
||||
freq, *frequency);
|
||||
}
|
||||
exit:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_table_event_handler(struct devfreq *devfreq,
|
||||
unsigned int event, void *data)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!devfreq) {
|
||||
dprintk(VIDC_ERR, "%s: NULL devfreq\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case DEVFREQ_GOV_START:
|
||||
case DEVFREQ_GOV_RESUME:
|
||||
mutex_lock(&devfreq->lock);
|
||||
rc = update_devfreq(devfreq);
|
||||
mutex_unlock(&devfreq->lock);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_free_bus_table(struct platform_device *pdev,
|
||||
struct msm_vidc_bus_table_gov *data)
|
||||
{
|
||||
int rc = 0, i = 0;
|
||||
|
||||
if (!pdev || !data) {
|
||||
dprintk(VIDC_ERR, "%s: invalid args %pK %pK\n",
|
||||
__func__, pdev, data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < data->count; i++)
|
||||
data->bus_prof_entries[i].bus_table = NULL;
|
||||
|
||||
data->bus_prof_entries = NULL;
|
||||
data->count = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_load_bus_table(struct platform_device *pdev,
|
||||
struct msm_vidc_bus_table_gov *data)
|
||||
{
|
||||
int rc = 0, i = 0, j = 0;
|
||||
const char *name = NULL;
|
||||
struct bus_profile_entry *entry = NULL;
|
||||
struct device_node *parent_node = NULL;
|
||||
struct device_node *child_node = NULL;
|
||||
|
||||
if (!pdev || !data) {
|
||||
dprintk(VIDC_ERR, "%s: invalid args %pK %pK\n",
|
||||
__func__, pdev, data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_property_read_string(pdev->dev.of_node, "name", &name);
|
||||
if (strlen(name) > ARRAY_SIZE(data->devfreq_gov.name) - 1) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: name is too long, max should be %zu chars\n",
|
||||
__func__, ARRAY_SIZE(data->devfreq_gov.name) - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
strlcpy((char *)data->devfreq_gov.name, name,
|
||||
ARRAY_SIZE(data->devfreq_gov.name));
|
||||
data->devfreq_gov.get_target_freq = msm_vidc_table_get_target_freq;
|
||||
data->devfreq_gov.event_handler = msm_vidc_table_event_handler;
|
||||
|
||||
parent_node = of_find_node_by_name(pdev->dev.of_node,
|
||||
"qcom,bus-freq-table");
|
||||
if (!parent_node) {
|
||||
dprintk(VIDC_DBG, "Node qcom,bus-freq-table not found.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->count = of_get_child_count(parent_node);
|
||||
if (!data->count) {
|
||||
dprintk(VIDC_DBG, "No child nodes in qcom,bus-freq-table\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->bus_prof_entries = devm_kzalloc(&pdev->dev,
|
||||
sizeof(*data->bus_prof_entries) * data->count,
|
||||
GFP_KERNEL);
|
||||
if (!data->bus_prof_entries) {
|
||||
dprintk(VIDC_DBG, "no memory to allocate bus_prof_entries\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for_each_child_of_node(parent_node, child_node) {
|
||||
|
||||
if (i >= data->count) {
|
||||
dprintk(VIDC_ERR,
|
||||
"qcom,bus-freq-table: invalid child node %d, max is %d\n",
|
||||
i, data->count);
|
||||
break;
|
||||
}
|
||||
entry = &data->bus_prof_entries[i];
|
||||
|
||||
if (of_find_property(child_node, "qcom,codec-mask", NULL)) {
|
||||
rc = of_property_read_u32(child_node,
|
||||
"qcom,codec-mask", &entry->codec_mask);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"qcom,codec-mask not found\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (of_find_property(child_node, "qcom,low-power-mode", NULL))
|
||||
entry->profile = VIDC_BUS_PROFILE_LOW;
|
||||
else if (of_find_property(child_node, "qcom,ubwc-mode", NULL))
|
||||
entry->profile = VIDC_BUS_PROFILE_UBWC;
|
||||
else
|
||||
entry->profile = VIDC_BUS_PROFILE_NORMAL;
|
||||
|
||||
if (of_find_property(child_node,
|
||||
"qcom,load-busfreq-tbl", NULL)) {
|
||||
rc = msm_vidc_load_u32_table(pdev, child_node,
|
||||
"qcom,load-busfreq-tbl",
|
||||
sizeof(*entry->bus_table),
|
||||
(u32 **)&entry->bus_table,
|
||||
&entry->bus_table_size);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"qcom,load-busfreq-tbl failed\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
entry->bus_table = NULL;
|
||||
entry->bus_table_size = 0;
|
||||
}
|
||||
|
||||
dprintk(VIDC_DBG,
|
||||
"qcom,load-busfreq-tbl: size %d, codec_mask %#x, profile %#x\n",
|
||||
entry->bus_table_size, entry->codec_mask,
|
||||
entry->profile);
|
||||
for (j = 0; j < entry->bus_table_size; j++)
|
||||
dprintk(VIDC_DBG, " load %8d freq %8d\n",
|
||||
entry->bus_table[j].load,
|
||||
entry->bus_table[j].freq);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_bus_table_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_bus_table_gov *gov = NULL;
|
||||
|
||||
dprintk(VIDC_DBG, "%s\n", __func__);
|
||||
|
||||
gov = devm_kzalloc(&pdev->dev, sizeof(*gov), GFP_KERNEL);
|
||||
if (!gov) {
|
||||
dprintk(VIDC_ERR, "%s: allocation failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, gov);
|
||||
|
||||
rc = msm_vidc_load_bus_table(pdev, gov);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = devfreq_add_governor(&gov->devfreq_gov);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR, "%s: add governor failed\n", __func__);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_bus_table_remove(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_bus_table_gov *gov = NULL;
|
||||
|
||||
dprintk(VIDC_DBG, "%s\n", __func__);
|
||||
|
||||
gov = platform_get_drvdata(pdev);
|
||||
if (IS_ERR_OR_NULL(gov))
|
||||
return PTR_ERR(gov);
|
||||
|
||||
rc = msm_vidc_free_bus_table(pdev, gov);
|
||||
if (rc)
|
||||
dprintk(VIDC_WARN, "%s: free bus table failed\n", __func__);
|
||||
|
||||
rc = devfreq_remove_governor(&gov->devfreq_gov);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct of_device_id device_id[] = {
|
||||
{.compatible = "qcom,msm-vidc,governor,table"},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver msm_vidc_bus_table_driver = {
|
||||
.probe = msm_vidc_bus_table_probe,
|
||||
.remove = msm_vidc_bus_table_remove,
|
||||
.driver = {
|
||||
.name = "msm_vidc_bus_table_governor",
|
||||
.of_match_table = device_id,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init msm_vidc_bus_table_init(void)
|
||||
{
|
||||
|
||||
dprintk(VIDC_DBG, "%s\n", __func__);
|
||||
|
||||
return platform_driver_register(&msm_vidc_bus_table_driver);
|
||||
}
|
||||
|
||||
module_init(msm_vidc_bus_table_init);
|
||||
|
||||
static void __exit msm_vidc_bus_table_exit(void)
|
||||
{
|
||||
dprintk(VIDC_DBG, "%s\n", __func__);
|
||||
platform_driver_unregister(&msm_vidc_bus_table_driver);
|
||||
}
|
||||
|
||||
module_exit(msm_vidc_bus_table_exit);
|
||||
MODULE_LICENSE("GPL v2");
|
2568
drivers/media/platform/msm/vidc_3x/hfi_packetization.c
Normal file
2568
drivers/media/platform/msm/vidc_3x/hfi_packetization.c
Normal file
File diff suppressed because it is too large
Load diff
103
drivers/media/platform/msm/vidc_3x/hfi_packetization.h
Normal file
103
drivers/media/platform/msm/vidc_3x/hfi_packetization.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2015, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#ifndef __HFI_PACKETIZATION__
|
||||
#define __HFI_PACKETIZATION__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "vidc_hfi_helper.h"
|
||||
#include "vidc_hfi.h"
|
||||
#include "vidc_hfi_api.h"
|
||||
|
||||
#define call_hfi_pkt_op(q, op, args...) \
|
||||
(((q) && (q)->pkt_ops && (q)->pkt_ops->op) ? \
|
||||
((q)->pkt_ops->op(args)) : 0)
|
||||
|
||||
enum hfi_packetization_type {
|
||||
HFI_PACKETIZATION_LEGACY,
|
||||
HFI_PACKETIZATION_3XX,
|
||||
};
|
||||
|
||||
struct hfi_packetization_ops {
|
||||
int (*sys_init)(struct hfi_cmd_sys_init_packet *pkt, u32 arch_type);
|
||||
int (*sys_pc_prep)(struct hfi_cmd_sys_pc_prep_packet *pkt);
|
||||
int (*sys_idle_indicator)(struct hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 enable);
|
||||
int (*sys_power_control)(struct hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 enable);
|
||||
int (*sys_set_resource)(
|
||||
struct hfi_cmd_sys_set_resource_packet *pkt,
|
||||
struct vidc_resource_hdr *resource_hdr,
|
||||
void *resource_value);
|
||||
int (*sys_debug_config)(struct hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 mode);
|
||||
int (*sys_coverage_config)(struct hfi_cmd_sys_set_property_packet *pkt,
|
||||
u32 mode);
|
||||
int (*sys_release_resource)(
|
||||
struct hfi_cmd_sys_release_resource_packet *pkt,
|
||||
struct vidc_resource_hdr *resource_hdr);
|
||||
int (*sys_ping)(struct hfi_cmd_sys_ping_packet *pkt);
|
||||
int (*sys_image_version)(struct hfi_cmd_sys_get_property_packet *pkt);
|
||||
int (*ssr_cmd)(enum hal_ssr_trigger_type type,
|
||||
struct hfi_cmd_sys_test_ssr_packet *pkt);
|
||||
int (*session_init)(
|
||||
struct hfi_cmd_sys_session_init_packet *pkt,
|
||||
struct hal_session *session,
|
||||
u32 session_domain, u32 session_codec);
|
||||
int (*session_cmd)(struct vidc_hal_session_cmd_pkt *pkt,
|
||||
int pkt_type, struct hal_session *session);
|
||||
int (*session_set_buffers)(
|
||||
struct hfi_cmd_session_set_buffers_packet *pkt,
|
||||
struct hal_session *session,
|
||||
struct vidc_buffer_addr_info *buffer_info);
|
||||
int (*session_release_buffers)(
|
||||
struct hfi_cmd_session_release_buffer_packet *pkt,
|
||||
struct hal_session *session,
|
||||
struct vidc_buffer_addr_info *buffer_info);
|
||||
int (*session_etb_decoder)(
|
||||
struct hfi_cmd_session_empty_buffer_compressed_packet *pkt,
|
||||
struct hal_session *session,
|
||||
struct vidc_frame_data *input_frame);
|
||||
int (*session_etb_encoder)(
|
||||
struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet
|
||||
*pkt, struct hal_session *session,
|
||||
struct vidc_frame_data *input_frame);
|
||||
int (*session_ftb)(struct hfi_cmd_session_fill_buffer_packet *pkt,
|
||||
struct hal_session *session,
|
||||
struct vidc_frame_data *output_frame);
|
||||
int (*session_parse_seq_header)(
|
||||
struct hfi_cmd_session_parse_sequence_header_packet *pkt,
|
||||
struct hal_session *session, struct vidc_seq_hdr *seq_hdr);
|
||||
int (*session_get_seq_hdr)(
|
||||
struct hfi_cmd_session_get_sequence_header_packet *pkt,
|
||||
struct hal_session *session, struct vidc_seq_hdr *seq_hdr);
|
||||
int (*session_get_buf_req)(
|
||||
struct hfi_cmd_session_get_property_packet *pkt,
|
||||
struct hal_session *session);
|
||||
int (*session_flush)(struct hfi_cmd_session_flush_packet *pkt,
|
||||
struct hal_session *session, enum hal_flush flush_mode);
|
||||
int (*session_get_property)(
|
||||
struct hfi_cmd_session_get_property_packet *pkt,
|
||||
struct hal_session *session, enum hal_property ptype);
|
||||
int (*session_set_property)(
|
||||
struct hfi_cmd_session_set_property_packet *pkt,
|
||||
struct hal_session *session,
|
||||
enum hal_property ptype, void *pdata);
|
||||
int (*session_sync_process)(
|
||||
struct hfi_cmd_session_sync_process_packet *pkt,
|
||||
struct hal_session *session);
|
||||
};
|
||||
|
||||
struct hfi_packetization_ops *hfi_get_pkt_ops_handle(
|
||||
enum hfi_packetization_type);
|
||||
#endif
|
2106
drivers/media/platform/msm/vidc_3x/hfi_response_handler.c
Normal file
2106
drivers/media/platform/msm/vidc_3x/hfi_response_handler.c
Normal file
File diff suppressed because it is too large
Load diff
652
drivers/media/platform/msm/vidc_3x/msm_smem.c
Normal file
652
drivers/media/platform/msm/vidc_3x/msm_smem.c
Normal file
|
@ -0,0 +1,652 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <asm/dma-iommu.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/msm_dma_iommu_mapping.h>
|
||||
#include <linux/msm_ion.h>
|
||||
#include <linux/ion_kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include "media/msm_vidc.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_resources.h"
|
||||
|
||||
|
||||
static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align,
|
||||
dma_addr_t *iova, unsigned long *buffer_size,
|
||||
unsigned long flags, enum hal_buffer buffer_type,
|
||||
unsigned long session_type, struct msm_vidc_platform_resources *res,
|
||||
struct dma_mapping_info *mapping_info)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dma_buf_attachment *attach;
|
||||
struct sg_table *table = NULL;
|
||||
struct context_bank_info *cb = NULL;
|
||||
|
||||
if (!dbuf || !iova || !buffer_size || !mapping_info) {
|
||||
dprintk(VIDC_ERR, "Invalid params: %pK, %pK, %pK, %pK\n",
|
||||
dbuf, iova, buffer_size, mapping_info);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_iommu_present(res)) {
|
||||
cb = msm_smem_get_context_bank(
|
||||
session_type, (flags & SMEM_SECURE),
|
||||
res, buffer_type);
|
||||
if (!cb) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: Failed to get context bank device\n",
|
||||
__func__);
|
||||
rc = -EIO;
|
||||
goto mem_map_failed;
|
||||
}
|
||||
|
||||
/* Check if the dmabuf size matches expected size */
|
||||
if (dbuf->size < *buffer_size) {
|
||||
rc = -EINVAL;
|
||||
dprintk(VIDC_ERR,
|
||||
"Size mismatch: Dmabuf size: %zu Expected Size: %lu\n",
|
||||
dbuf->size, *buffer_size);
|
||||
goto mem_buf_size_mismatch;
|
||||
}
|
||||
|
||||
/* Prepare a dma buf for dma on the given device */
|
||||
attach = dma_buf_attach(dbuf, cb->dev);
|
||||
if (IS_ERR_OR_NULL(attach)) {
|
||||
rc = PTR_ERR(attach) ?: -ENOMEM;
|
||||
dprintk(VIDC_ERR, "Failed to attach dmabuf\n");
|
||||
goto mem_buf_attach_failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the scatterlist for the given attachment
|
||||
* Mapping of sg is taken care by map attachment
|
||||
*/
|
||||
attach->dma_map_attrs = DMA_ATTR_DELAYED_UNMAP;
|
||||
/*
|
||||
* We do not need dma_map function to perform cache operations
|
||||
* on the whole buffer size and hence pass skip sync flag.
|
||||
* We do the required cache operations separately for the
|
||||
* required buffer size
|
||||
*/
|
||||
attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
|
||||
/*
|
||||
*if (res->sys_cache_present)
|
||||
* attach->dma_map_attrs |=
|
||||
* DMA_ATTR_IOMMU_USE_UPSTREAM_HINT;
|
||||
*/
|
||||
|
||||
table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
||||
if (IS_ERR_OR_NULL(table)) {
|
||||
rc = PTR_ERR(table) ?: -ENOMEM;
|
||||
dprintk(VIDC_ERR, "Failed to map table\n");
|
||||
goto mem_map_table_failed;
|
||||
}
|
||||
|
||||
/* debug trace's need to be updated later */
|
||||
trace_msm_smem_buffer_iommu_op_start("MAP", 0, 0,
|
||||
align, *iova, *buffer_size);
|
||||
|
||||
if (table->sgl) {
|
||||
*iova = table->sgl->dma_address;
|
||||
*buffer_size = table->sgl->dma_length;
|
||||
} else {
|
||||
dprintk(VIDC_ERR, "sgl is NULL\n");
|
||||
rc = -ENOMEM;
|
||||
goto mem_map_sg_failed;
|
||||
}
|
||||
|
||||
mapping_info->dev = cb->dev;
|
||||
mapping_info->domain = cb->domain;
|
||||
mapping_info->table = table;
|
||||
mapping_info->attach = attach;
|
||||
mapping_info->buf = dbuf;
|
||||
mapping_info->cb_info = (void *)cb;
|
||||
|
||||
trace_msm_smem_buffer_iommu_op_end("MAP", 0, 0,
|
||||
align, *iova, *buffer_size);
|
||||
} else {
|
||||
dprintk(VIDC_DBG, "iommu not present, use phys mem addr\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
mem_map_sg_failed:
|
||||
dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL);
|
||||
mem_map_table_failed:
|
||||
dma_buf_detach(dbuf, attach);
|
||||
mem_buf_size_mismatch:
|
||||
mem_buf_attach_failed:
|
||||
mem_map_failed:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_dma_put_device_address(u32 flags,
|
||||
struct dma_mapping_info *mapping_info,
|
||||
enum hal_buffer buffer_type)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!mapping_info) {
|
||||
dprintk(VIDC_WARN, "Invalid mapping_info\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!mapping_info->dev || !mapping_info->table ||
|
||||
!mapping_info->buf || !mapping_info->attach ||
|
||||
!mapping_info->cb_info) {
|
||||
dprintk(VIDC_WARN, "Invalid params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
trace_msm_smem_buffer_iommu_op_start("UNMAP", 0, 0, 0, 0, 0);
|
||||
dma_buf_unmap_attachment(mapping_info->attach,
|
||||
mapping_info->table, DMA_BIDIRECTIONAL);
|
||||
dma_buf_detach(mapping_info->buf, mapping_info->attach);
|
||||
trace_msm_smem_buffer_iommu_op_end("UNMAP", 0, 0, 0, 0, 0);
|
||||
|
||||
mapping_info->dev = NULL;
|
||||
mapping_info->domain = NULL;
|
||||
mapping_info->table = NULL;
|
||||
mapping_info->attach = NULL;
|
||||
mapping_info->buf = NULL;
|
||||
mapping_info->cb_info = NULL;
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct dma_buf *msm_smem_get_dma_buf(int fd)
|
||||
{
|
||||
struct dma_buf *dma_buf;
|
||||
|
||||
dma_buf = dma_buf_get(fd);
|
||||
if (IS_ERR_OR_NULL(dma_buf)) {
|
||||
dprintk(VIDC_ERR, "Failed to get dma_buf for %d, error %ld\n",
|
||||
fd, PTR_ERR(dma_buf));
|
||||
dma_buf = NULL;
|
||||
}
|
||||
|
||||
return dma_buf;
|
||||
}
|
||||
|
||||
void msm_smem_put_dma_buf(void *dma_buf)
|
||||
{
|
||||
if (!dma_buf) {
|
||||
dprintk(VIDC_ERR, "%s: NULL dma_buf\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dma_buf_put((struct dma_buf *)dma_buf);
|
||||
}
|
||||
bool msm_smem_compare_buffers(int fd, void *dma_buf)
|
||||
{
|
||||
unsigned long dma_plane;
|
||||
|
||||
/*
|
||||
* always compare dma_buf addresses which is guaranteed
|
||||
* to be same across the processes (duplicate fds).
|
||||
*/
|
||||
dma_plane = (unsigned long)msm_smem_get_dma_buf(
|
||||
fd);
|
||||
if (!dma_plane)
|
||||
return false;
|
||||
msm_smem_put_dma_buf((struct dma_buf *)dma_plane);
|
||||
|
||||
if ((unsigned long)dma_buf == dma_plane)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
dma_addr_t iova = 0;
|
||||
u32 temp = 0;
|
||||
unsigned long buffer_size = 0;
|
||||
unsigned long align = SZ_4K;
|
||||
struct dma_buf *dbuf;
|
||||
unsigned long ion_flags = 0;
|
||||
|
||||
if (!inst || !smem) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid params: %pK %pK\n",
|
||||
__func__, inst, smem);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (smem->refcount) {
|
||||
smem->refcount++;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dbuf = msm_smem_get_dma_buf(smem->fd);
|
||||
if (!dbuf) {
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
smem->dma_buf = dbuf;
|
||||
|
||||
rc = dma_buf_get_flags(dbuf, &ion_flags);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to get dma buf flags: %d\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
if (ion_flags & ION_FLAG_CACHED)
|
||||
smem->flags |= SMEM_CACHED;
|
||||
|
||||
if (ion_flags & ION_FLAG_SECURE)
|
||||
smem->flags |= SMEM_SECURE;
|
||||
|
||||
buffer_size = smem->size;
|
||||
|
||||
rc = msm_dma_get_device_address(dbuf, align, &iova, &buffer_size,
|
||||
smem->flags, smem->buffer_type, inst->session_type,
|
||||
&(inst->core->resources), &smem->mapping_info);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to get device address: %d\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
temp = (u32)iova;
|
||||
if ((dma_addr_t)temp != iova) {
|
||||
dprintk(VIDC_ERR, "iova(%pa) truncated to %#x", &iova, temp);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
smem->device_addr = (u32)iova;
|
||||
|
||||
smem->refcount++;
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!inst || !smem) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid params: %pK %pK\n",
|
||||
__func__, inst, smem);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (smem->refcount) {
|
||||
smem->refcount--;
|
||||
} else {
|
||||
dprintk(VIDC_WARN,
|
||||
"unmap called while refcount is zero already\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (smem->refcount)
|
||||
goto exit;
|
||||
|
||||
rc = msm_dma_put_device_address(smem->flags, &smem->mapping_info,
|
||||
smem->buffer_type);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to put device address: %d\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
msm_smem_put_dma_buf(smem->dma_buf);
|
||||
|
||||
smem->device_addr = 0x0;
|
||||
smem->dma_buf = NULL;
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
struct msm_smem *msm_smem_user_to_kernel(struct msm_vidc_inst *inst, int fd,
|
||||
u32 offset, u32 size,
|
||||
enum hal_buffer buffer_type)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_smem *mem;
|
||||
|
||||
if (fd < 0 || !inst) {
|
||||
dprintk(VIDC_ERR, "Invalid fd: %d\n", fd);
|
||||
return NULL;
|
||||
}
|
||||
mem = kzalloc(sizeof(*mem), GFP_KERNEL);
|
||||
if (!mem) {
|
||||
dprintk(VIDC_ERR, "Failed to allocate shared mem\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem->fd = fd;
|
||||
mem->size = size;
|
||||
mem->buffer_type = buffer_type;
|
||||
mem->offset = offset;
|
||||
|
||||
//rc = ion_user_to_kernel(clt, fd, offset, mem, buffer_type);
|
||||
rc = msm_smem_map_dma_buf(inst, mem);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to allocate shared memory\n");
|
||||
kfree(mem);
|
||||
mem = NULL;
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
static int get_secure_flag_for_buffer_type(
|
||||
u32 session_type, enum hal_buffer buffer_type)
|
||||
{
|
||||
switch (buffer_type) {
|
||||
case HAL_BUFFER_INPUT:
|
||||
if (session_type == MSM_VIDC_ENCODER)
|
||||
return ION_FLAG_CP_PIXEL;
|
||||
else
|
||||
return ION_FLAG_CP_BITSTREAM;
|
||||
case HAL_BUFFER_OUTPUT:
|
||||
case HAL_BUFFER_OUTPUT2:
|
||||
if (session_type == MSM_VIDC_ENCODER)
|
||||
return ION_FLAG_CP_BITSTREAM;
|
||||
else
|
||||
return ION_FLAG_CP_PIXEL;
|
||||
case HAL_BUFFER_INTERNAL_SCRATCH:
|
||||
return ION_FLAG_CP_BITSTREAM;
|
||||
case HAL_BUFFER_INTERNAL_SCRATCH_1:
|
||||
return ION_FLAG_CP_NON_PIXEL;
|
||||
case HAL_BUFFER_INTERNAL_SCRATCH_2:
|
||||
return ION_FLAG_CP_PIXEL;
|
||||
case HAL_BUFFER_INTERNAL_PERSIST:
|
||||
if (session_type == MSM_VIDC_ENCODER)
|
||||
return ION_FLAG_CP_NON_PIXEL;
|
||||
else
|
||||
return ION_FLAG_CP_BITSTREAM;
|
||||
case HAL_BUFFER_INTERNAL_PERSIST_1:
|
||||
return ION_FLAG_CP_NON_PIXEL;
|
||||
default:
|
||||
WARN(1, "No matching secure flag for buffer type : %x\n",
|
||||
buffer_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int alloc_dma_mem(size_t size, u32 align, u32 flags,
|
||||
enum hal_buffer buffer_type, int map_kernel,
|
||||
struct msm_vidc_platform_resources *res, u32 session_type,
|
||||
struct msm_smem *mem)
|
||||
{
|
||||
dma_addr_t iova = 0;
|
||||
unsigned long buffer_size = 0;
|
||||
unsigned long heap_mask = 0;
|
||||
int rc = 0;
|
||||
int ion_flags = 0;
|
||||
struct dma_buf *dbuf = NULL;
|
||||
|
||||
if (!res) {
|
||||
dprintk(VIDC_ERR, "%s: NULL res\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
align = ALIGN(align, SZ_4K);
|
||||
size = ALIGN(size, SZ_4K);
|
||||
|
||||
if (is_iommu_present(res)) {
|
||||
if (flags & SMEM_ADSP) {
|
||||
dprintk(VIDC_DBG, "Allocating from ADSP heap\n");
|
||||
heap_mask = ION_HEAP(ION_ADSP_HEAP_ID);
|
||||
} else {
|
||||
heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID);
|
||||
}
|
||||
} else {
|
||||
dprintk(VIDC_DBG,
|
||||
"allocate shared memory from adsp heap size %zx align %d\n",
|
||||
size, align);
|
||||
heap_mask = ION_HEAP(ION_ADSP_HEAP_ID);
|
||||
}
|
||||
|
||||
if (flags & SMEM_CACHED)
|
||||
ion_flags |= ION_FLAG_CACHED;
|
||||
|
||||
if ((flags & SMEM_SECURE) ||
|
||||
(buffer_type == HAL_BUFFER_INTERNAL_PERSIST &&
|
||||
session_type == MSM_VIDC_ENCODER)) {
|
||||
int secure_flag =
|
||||
get_secure_flag_for_buffer_type(
|
||||
session_type, buffer_type);
|
||||
if (secure_flag < 0) {
|
||||
rc = secure_flag;
|
||||
goto fail_shared_mem_alloc;
|
||||
}
|
||||
|
||||
ion_flags |= ION_FLAG_SECURE | secure_flag;
|
||||
heap_mask = ION_HEAP(ION_SECURE_HEAP_ID);
|
||||
|
||||
if (res->slave_side_cp) {
|
||||
heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
|
||||
size = ALIGN(size, SZ_1M);
|
||||
align = ALIGN(size, SZ_1M);
|
||||
}
|
||||
flags |= SMEM_SECURE;
|
||||
}
|
||||
|
||||
trace_msm_smem_buffer_dma_op_start("ALLOC", (u32)buffer_type,
|
||||
heap_mask, size, align, flags, map_kernel);
|
||||
dbuf = ion_alloc(size, heap_mask, ion_flags);
|
||||
if (IS_ERR_OR_NULL(dbuf)) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to allocate shared memory = %zx, %#x\n",
|
||||
size, flags);
|
||||
rc = -ENOMEM;
|
||||
goto fail_shared_mem_alloc;
|
||||
}
|
||||
trace_msm_smem_buffer_dma_op_end("ALLOC", (u32)buffer_type,
|
||||
heap_mask, size, align, flags, map_kernel);
|
||||
|
||||
mem->flags = flags;
|
||||
mem->buffer_type = buffer_type;
|
||||
mem->offset = 0;
|
||||
mem->size = size;
|
||||
mem->dma_buf = dbuf;
|
||||
mem->kvaddr = NULL;
|
||||
|
||||
rc = msm_dma_get_device_address(dbuf, align, &iova,
|
||||
&buffer_size, flags, buffer_type,
|
||||
session_type, res, &mem->mapping_info);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to get device address: %d\n",
|
||||
rc);
|
||||
goto fail_device_address;
|
||||
}
|
||||
mem->device_addr = (u32)iova;
|
||||
if ((dma_addr_t)mem->device_addr != iova) {
|
||||
dprintk(VIDC_ERR, "iova(%pa) truncated to %#x",
|
||||
&iova, mem->device_addr);
|
||||
goto fail_device_address;
|
||||
}
|
||||
|
||||
if (map_kernel) {
|
||||
dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL);
|
||||
mem->kvaddr = dma_buf_vmap(dbuf);
|
||||
if (!mem->kvaddr) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to map shared mem in kernel\n");
|
||||
rc = -EIO;
|
||||
goto fail_map;
|
||||
}
|
||||
}
|
||||
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x, flags = %#lx\n",
|
||||
__func__, mem->dma_buf, mem->device_addr, mem->size,
|
||||
mem->kvaddr, mem->buffer_type, mem->flags);
|
||||
return rc;
|
||||
|
||||
fail_map:
|
||||
if (map_kernel)
|
||||
dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL);
|
||||
fail_device_address:
|
||||
dma_buf_put(dbuf);
|
||||
fail_shared_mem_alloc:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int free_dma_mem(struct msm_smem *mem)
|
||||
{
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, buffer_type = %#x\n",
|
||||
__func__, mem->dma_buf, mem->device_addr, mem->size,
|
||||
mem->kvaddr, mem->buffer_type);
|
||||
|
||||
if (mem->device_addr) {
|
||||
msm_dma_put_device_address(mem->flags,
|
||||
&mem->mapping_info, mem->buffer_type);
|
||||
mem->device_addr = 0x0;
|
||||
}
|
||||
|
||||
if (mem->kvaddr) {
|
||||
dma_buf_vunmap(mem->dma_buf, mem->kvaddr);
|
||||
mem->kvaddr = NULL;
|
||||
dma_buf_end_cpu_access(mem->dma_buf, DMA_BIDIRECTIONAL);
|
||||
}
|
||||
|
||||
if (mem->dma_buf) {
|
||||
trace_msm_smem_buffer_dma_op_start("FREE",
|
||||
(u32)mem->buffer_type, -1, mem->size, -1,
|
||||
mem->flags, -1);
|
||||
dma_buf_put(mem->dma_buf);
|
||||
mem->dma_buf = NULL;
|
||||
trace_msm_smem_buffer_dma_op_end("FREE", (u32)mem->buffer_type,
|
||||
-1, mem->size, -1, mem->flags, -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_smem_alloc(size_t size, u32 align, u32 flags,
|
||||
enum hal_buffer buffer_type, int map_kernel,
|
||||
void *res, u32 session_type, struct msm_smem *smem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!smem || !size) {
|
||||
dprintk(VIDC_ERR, "%s: NULL smem or %d size\n",
|
||||
__func__, (u32)size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = alloc_dma_mem(size, align, flags, buffer_type, map_kernel,
|
||||
(struct msm_vidc_platform_resources *)res,
|
||||
session_type, smem);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_smem_free(struct msm_smem *smem)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!smem) {
|
||||
dprintk(VIDC_ERR, "NULL smem passed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = free_dma_mem(smem);
|
||||
|
||||
return rc;
|
||||
};
|
||||
|
||||
int msm_smem_cache_operations(struct dma_buf *dbuf,
|
||||
enum smem_cache_ops cache_op, unsigned long offset, unsigned long size)
|
||||
{
|
||||
int rc = 0;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (!dbuf) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return if buffer doesn't support caching */
|
||||
rc = dma_buf_get_flags(dbuf, &flags);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "%s: dma_buf_get_flags failed, err %d\n",
|
||||
__func__, rc);
|
||||
return rc;
|
||||
} else if (!(flags & ION_FLAG_CACHED)) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
switch (cache_op) {
|
||||
case SMEM_CACHE_CLEAN:
|
||||
case SMEM_CACHE_CLEAN_INVALIDATE:
|
||||
rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE,
|
||||
offset, size);
|
||||
if (rc)
|
||||
break;
|
||||
rc = dma_buf_end_cpu_access_partial(dbuf, DMA_TO_DEVICE,
|
||||
offset, size);
|
||||
break;
|
||||
case SMEM_CACHE_INVALIDATE:
|
||||
rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE,
|
||||
offset, size);
|
||||
if (rc)
|
||||
break;
|
||||
rc = dma_buf_end_cpu_access_partial(dbuf, DMA_FROM_DEVICE,
|
||||
offset, size);
|
||||
break;
|
||||
default:
|
||||
dprintk(VIDC_ERR, "%s: cache (%d) operation not supported\n",
|
||||
__func__, cache_op);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct context_bank_info *msm_smem_get_context_bank(u32 session_type,
|
||||
bool is_secure, struct msm_vidc_platform_resources *res,
|
||||
enum hal_buffer buffer_type)
|
||||
{
|
||||
struct context_bank_info *cb = NULL, *match = NULL;
|
||||
|
||||
/*
|
||||
* HAL_BUFFER_INPUT is directly mapped to bitstream CB in DT
|
||||
* as the buffer type structure was initially designed
|
||||
* just for decoder. For Encoder, input should be mapped to
|
||||
* yuvpixel CB. Persist is mapped to nonpixel CB.
|
||||
* So swap the buffer types just in this local scope.
|
||||
*/
|
||||
if (is_secure && session_type == MSM_VIDC_ENCODER) {
|
||||
if (buffer_type == HAL_BUFFER_INPUT)
|
||||
buffer_type = HAL_BUFFER_OUTPUT;
|
||||
else if (buffer_type == HAL_BUFFER_OUTPUT)
|
||||
buffer_type = HAL_BUFFER_INPUT;
|
||||
else if (buffer_type == HAL_BUFFER_INTERNAL_PERSIST)
|
||||
buffer_type = HAL_BUFFER_INTERNAL_PERSIST_1;
|
||||
}
|
||||
|
||||
list_for_each_entry(cb, &res->context_banks, list) {
|
||||
if (cb->is_secure == is_secure &&
|
||||
cb->buffer_type & buffer_type) {
|
||||
match = cb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!match)
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: cb not found for buffer_type %x, is_secure %d\n",
|
||||
__func__, buffer_type, is_secure);
|
||||
|
||||
return match;
|
||||
}
|
||||
|
835
drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c
Normal file
835
drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c
Normal file
|
@ -0,0 +1,835 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/io.h>
|
||||
#include <media/msm_vidc.h>
|
||||
#include "msm_vidc_common.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_internal.h"
|
||||
#include "msm_vidc_res_parse.h"
|
||||
#include "msm_vidc_resources.h"
|
||||
#include "venus_boot.h"
|
||||
#include "vidc_hfi_api.h"
|
||||
|
||||
#define BASE_DEVICE_NUMBER 32
|
||||
|
||||
struct msm_vidc_drv *vidc_driver;
|
||||
|
||||
uint32_t msm_vidc_pwr_collapse_delay = 2000;
|
||||
|
||||
static inline struct msm_vidc_inst *get_vidc_inst(struct file *filp, void *fh)
|
||||
{
|
||||
return container_of(filp->private_data,
|
||||
struct msm_vidc_inst, event_handler);
|
||||
}
|
||||
|
||||
static int msm_v4l2_open(struct file *filp)
|
||||
{
|
||||
struct video_device *vdev = video_devdata(filp);
|
||||
struct msm_video_device *vid_dev =
|
||||
container_of(vdev, struct msm_video_device, vdev);
|
||||
struct msm_vidc_core *core = video_drvdata(filp);
|
||||
struct msm_vidc_inst *vidc_inst;
|
||||
|
||||
trace_msm_v4l2_vidc_open_start("v4l2-vidc open start");
|
||||
vidc_inst = msm_vidc_open(core->id, vid_dev->type);
|
||||
if (!vidc_inst) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to create video instance, core: %d, type = %d\n",
|
||||
core->id, vid_dev->type);
|
||||
return -ENOMEM;
|
||||
}
|
||||
clear_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags);
|
||||
filp->private_data = &(vidc_inst->event_handler);
|
||||
trace_msm_v4l2_vidc_open_end("v4l2-vidc open end");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_close(struct file *filp)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_inst *vidc_inst;
|
||||
|
||||
trace_msm_v4l2_vidc_close_start("v4l2-vidc close start");
|
||||
vidc_inst = get_vidc_inst(filp, NULL);
|
||||
rc = msm_vidc_release_buffers(vidc_inst,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
|
||||
if (rc)
|
||||
dprintk(VIDC_WARN,
|
||||
"Failed in %s for release output buffers\n", __func__);
|
||||
|
||||
rc = msm_vidc_close(vidc_inst);
|
||||
trace_msm_v4l2_vidc_close_end("v4l2-vidc close end");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_v4l2_querycap(struct file *filp, void *fh,
|
||||
struct v4l2_capability *cap)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, fh);
|
||||
|
||||
return msm_vidc_querycap((void *)vidc_inst, cap);
|
||||
}
|
||||
|
||||
int msm_v4l2_enum_fmt(struct file *file, void *fh,
|
||||
struct v4l2_fmtdesc *f)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_enum_fmt((void *)vidc_inst, f);
|
||||
}
|
||||
|
||||
int msm_v4l2_s_fmt(struct file *file, void *fh,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_s_fmt((void *)vidc_inst, f);
|
||||
}
|
||||
|
||||
int msm_v4l2_g_fmt(struct file *file, void *fh,
|
||||
struct v4l2_format *f)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_g_fmt((void *)vidc_inst, f);
|
||||
}
|
||||
|
||||
int msm_v4l2_s_ctrl(struct file *file, void *fh,
|
||||
struct v4l2_control *a)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_s_ctrl((void *)vidc_inst, a);
|
||||
}
|
||||
|
||||
int msm_v4l2_g_ctrl(struct file *file, void *fh,
|
||||
struct v4l2_control *a)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_g_ctrl((void *)vidc_inst, a);
|
||||
}
|
||||
|
||||
int msm_v4l2_s_ext_ctrl(struct file *file, void *fh,
|
||||
struct v4l2_ext_controls *a)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_s_ext_ctrl((void *)vidc_inst, a);
|
||||
}
|
||||
|
||||
int msm_v4l2_reqbufs(struct file *file, void *fh,
|
||||
struct v4l2_requestbuffers *b)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
int rc = 0;
|
||||
|
||||
if (!b->count)
|
||||
rc = msm_vidc_release_buffers(vidc_inst, b->type);
|
||||
if (rc)
|
||||
dprintk(VIDC_WARN,
|
||||
"Failed in %s for release output buffers\n", __func__);
|
||||
return msm_vidc_reqbufs((void *)vidc_inst, b);
|
||||
}
|
||||
|
||||
int msm_v4l2_prepare_buf(struct file *file, void *fh,
|
||||
struct v4l2_buffer *b)
|
||||
{
|
||||
return msm_vidc_prepare_buf(get_vidc_inst(file, fh), b);
|
||||
}
|
||||
|
||||
int msm_v4l2_qbuf(struct file *file, void *fh,
|
||||
struct v4l2_buffer *b)
|
||||
{
|
||||
return msm_vidc_qbuf(get_vidc_inst(file, fh), b);
|
||||
}
|
||||
|
||||
int msm_v4l2_dqbuf(struct file *file, void *fh,
|
||||
struct v4l2_buffer *b)
|
||||
{
|
||||
return msm_vidc_dqbuf(get_vidc_inst(file, fh), b);
|
||||
}
|
||||
|
||||
int msm_v4l2_streamon(struct file *file, void *fh,
|
||||
enum v4l2_buf_type i)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_streamon((void *)vidc_inst, i);
|
||||
}
|
||||
|
||||
int msm_v4l2_streamoff(struct file *file, void *fh,
|
||||
enum v4l2_buf_type i)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_streamoff((void *)vidc_inst, i);
|
||||
}
|
||||
|
||||
static int msm_v4l2_subscribe_event(struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = container_of(fh,
|
||||
struct msm_vidc_inst, event_handler);
|
||||
|
||||
return msm_vidc_subscribe_event((void *)vidc_inst, sub);
|
||||
}
|
||||
|
||||
static int msm_v4l2_unsubscribe_event(struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = container_of(fh,
|
||||
struct msm_vidc_inst, event_handler);
|
||||
|
||||
return msm_vidc_unsubscribe_event((void *)vidc_inst, sub);
|
||||
}
|
||||
|
||||
static int msm_v4l2_decoder_cmd(struct file *file, void *fh,
|
||||
struct v4l2_decoder_cmd *dec)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_comm_cmd((void *)vidc_inst, (union msm_v4l2_cmd *)dec);
|
||||
}
|
||||
|
||||
static int msm_v4l2_encoder_cmd(struct file *file, void *fh,
|
||||
struct v4l2_encoder_cmd *enc)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_comm_cmd((void *)vidc_inst, (union msm_v4l2_cmd *)enc);
|
||||
}
|
||||
static int msm_v4l2_s_parm(struct file *file, void *fh,
|
||||
struct v4l2_streamparm *a)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_comm_s_parm(vidc_inst, a);
|
||||
}
|
||||
static int msm_v4l2_g_parm(struct file *file, void *fh,
|
||||
struct v4l2_streamparm *a)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_v4l2_enum_framesizes(struct file *file, void *fh,
|
||||
struct v4l2_frmsizeenum *fsize)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
|
||||
|
||||
return msm_vidc_enum_framesizes((void *)vidc_inst, fsize);
|
||||
}
|
||||
|
||||
static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
|
||||
.vidioc_querycap = msm_v4l2_querycap,
|
||||
.vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt,
|
||||
.vidioc_enum_fmt_vid_out_mplane = msm_v4l2_enum_fmt,
|
||||
.vidioc_s_fmt_vid_cap_mplane = msm_v4l2_s_fmt,
|
||||
.vidioc_s_fmt_vid_out_mplane = msm_v4l2_s_fmt,
|
||||
.vidioc_g_fmt_vid_cap_mplane = msm_v4l2_g_fmt,
|
||||
.vidioc_g_fmt_vid_out_mplane = msm_v4l2_g_fmt,
|
||||
.vidioc_reqbufs = msm_v4l2_reqbufs,
|
||||
.vidioc_prepare_buf = msm_v4l2_prepare_buf,
|
||||
.vidioc_qbuf = msm_v4l2_qbuf,
|
||||
.vidioc_dqbuf = msm_v4l2_dqbuf,
|
||||
.vidioc_streamon = msm_v4l2_streamon,
|
||||
.vidioc_streamoff = msm_v4l2_streamoff,
|
||||
.vidioc_s_ctrl = msm_v4l2_s_ctrl,
|
||||
.vidioc_g_ctrl = msm_v4l2_g_ctrl,
|
||||
.vidioc_s_ext_ctrls = msm_v4l2_s_ext_ctrl,
|
||||
.vidioc_subscribe_event = msm_v4l2_subscribe_event,
|
||||
.vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event,
|
||||
.vidioc_decoder_cmd = msm_v4l2_decoder_cmd,
|
||||
.vidioc_encoder_cmd = msm_v4l2_encoder_cmd,
|
||||
.vidioc_s_parm = msm_v4l2_s_parm,
|
||||
.vidioc_g_parm = msm_v4l2_g_parm,
|
||||
.vidioc_enum_framesizes = msm_v4l2_enum_framesizes,
|
||||
};
|
||||
|
||||
static const struct v4l2_ioctl_ops msm_v4l2_enc_ioctl_ops = {
|
||||
};
|
||||
|
||||
static unsigned int msm_v4l2_poll(struct file *filp,
|
||||
struct poll_table_struct *pt)
|
||||
{
|
||||
struct msm_vidc_inst *vidc_inst = get_vidc_inst(filp, NULL);
|
||||
|
||||
return msm_vidc_poll((void *)vidc_inst, filp, pt);
|
||||
}
|
||||
|
||||
static const struct v4l2_file_operations msm_v4l2_vidc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = msm_v4l2_open,
|
||||
.release = msm_v4l2_close,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
.poll = msm_v4l2_poll,
|
||||
};
|
||||
|
||||
void msm_vidc_release_video_device(struct video_device *pvdev)
|
||||
{
|
||||
}
|
||||
|
||||
static int read_platform_resources(struct msm_vidc_core *core,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
if (!core || !pdev) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid params %pK %pK\n",
|
||||
__func__, core, pdev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core->hfi_type = VIDC_HFI_VENUS;
|
||||
core->resources.pdev = pdev;
|
||||
if (pdev->dev.of_node) {
|
||||
/* Target supports DT, parse from it */
|
||||
return read_platform_resources_from_dt(&core->resources);
|
||||
}
|
||||
dprintk(VIDC_ERR, "pdev node is NULL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int msm_vidc_initialize_core(struct platform_device *pdev,
|
||||
struct msm_vidc_core *core)
|
||||
{
|
||||
int i = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (!core)
|
||||
return -EINVAL;
|
||||
rc = read_platform_resources(core, pdev);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to get platform resources\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&core->instances);
|
||||
mutex_init(&core->lock);
|
||||
|
||||
core->state = VIDC_CORE_UNINIT;
|
||||
for (i = SYS_MSG_INDEX(SYS_MSG_START);
|
||||
i <= SYS_MSG_INDEX(SYS_MSG_END); i++) {
|
||||
init_completion(&core->completions[i]);
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t link_name_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct msm_vidc_core *core = dev_get_drvdata(dev);
|
||||
|
||||
if (core)
|
||||
if (dev == &core->vdev[MSM_VIDC_DECODER].vdev.dev)
|
||||
return scnprintf(buf, PAGE_SIZE, "venus_dec");
|
||||
else if (dev == &core->vdev[MSM_VIDC_ENCODER].vdev.dev)
|
||||
return scnprintf(buf, PAGE_SIZE, "venus_enc");
|
||||
else
|
||||
return 0;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(link_name);
|
||||
|
||||
static ssize_t pwr_collapse_delay_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
int rc = 0;
|
||||
|
||||
rc = kstrtoul(buf, 0, &val);
|
||||
if (rc)
|
||||
return rc;
|
||||
else if (!val)
|
||||
return -EINVAL;
|
||||
msm_vidc_pwr_collapse_delay = val;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t pwr_collapse_delay_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%u\n", msm_vidc_pwr_collapse_delay);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(pwr_collapse_delay);
|
||||
|
||||
static ssize_t thermal_level_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", vidc_driver->thermal_level);
|
||||
}
|
||||
|
||||
static ssize_t thermal_level_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int rc = 0, val = 0;
|
||||
|
||||
rc = kstrtoint(buf, 0, &val);
|
||||
if (rc || val < 0) {
|
||||
dprintk(VIDC_WARN,
|
||||
"Invalid thermal level value: %s\n", buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
dprintk(VIDC_DBG, "Thermal level old %d new %d\n",
|
||||
vidc_driver->thermal_level, val);
|
||||
|
||||
if (val == vidc_driver->thermal_level)
|
||||
return count;
|
||||
vidc_driver->thermal_level = val;
|
||||
|
||||
msm_comm_handle_thermal_event();
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(thermal_level);
|
||||
|
||||
static ssize_t platform_version_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d",
|
||||
vidc_driver->platform_version);
|
||||
}
|
||||
|
||||
static ssize_t platform_version_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
dprintk(VIDC_WARN, "store platform version is not allowed\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(platform_version);
|
||||
|
||||
static ssize_t capability_version_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return scnprintf(buf, PAGE_SIZE, "%d",
|
||||
vidc_driver->capability_version);
|
||||
}
|
||||
|
||||
static ssize_t capability_version_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
dprintk(VIDC_WARN, "store capability version is not allowed\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(capability_version);
|
||||
|
||||
static struct attribute *msm_vidc_core_attrs[] = {
|
||||
&dev_attr_pwr_collapse_delay.attr,
|
||||
&dev_attr_thermal_level.attr,
|
||||
&dev_attr_platform_version.attr,
|
||||
&dev_attr_capability_version.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group msm_vidc_core_attr_group = {
|
||||
.attrs = msm_vidc_core_attrs,
|
||||
};
|
||||
|
||||
static const struct of_device_id msm_vidc_dt_match[] = {
|
||||
{.compatible = "qcom,msm-vidc"},
|
||||
{.compatible = "qcom,msm-vidc,context-bank"},
|
||||
{.compatible = "qcom,msm-vidc,bus"},
|
||||
{}
|
||||
};
|
||||
|
||||
static u32 msm_vidc_read_efuse_version(struct platform_device *pdev,
|
||||
struct version_table *table, const char *fuse_name)
|
||||
{
|
||||
void __iomem *base;
|
||||
struct resource *res;
|
||||
u32 ret = 0;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, fuse_name);
|
||||
if (!res) {
|
||||
dprintk(VIDC_DBG, "Failed to get resource %s\n", fuse_name);
|
||||
goto exit;
|
||||
}
|
||||
base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||
if (!base) {
|
||||
dprintk(VIDC_ERR,
|
||||
"failed ioremap: res->start %#x, size %d\n",
|
||||
(u32)res->start, (u32)resource_size(res));
|
||||
goto exit;
|
||||
} else {
|
||||
ret = readl_relaxed(base);
|
||||
ret = (ret & table->version_mask) >>
|
||||
table->version_shift;
|
||||
|
||||
// devm_iounmap(&pdev->dev, base);
|
||||
}
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int msm_vidc_probe_vidc_device(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
struct device *dev;
|
||||
int nr = BASE_DEVICE_NUMBER;
|
||||
|
||||
if (!vidc_driver) {
|
||||
dprintk(VIDC_ERR, "Invalid vidc driver\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = kzalloc(sizeof(*core), GFP_KERNEL);
|
||||
if (!core) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to allocate memory for device core\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&pdev->dev, core);
|
||||
rc = msm_vidc_initialize_core(pdev, core);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to init core\n");
|
||||
goto err_core_init;
|
||||
}
|
||||
rc = sysfs_create_group(&pdev->dev.kobj, &msm_vidc_core_attr_group);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to create attributes\n");
|
||||
goto err_core_init;
|
||||
}
|
||||
|
||||
core->id = MSM_VIDC_CORE_VENUS;
|
||||
|
||||
rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to register v4l2 device\n");
|
||||
goto err_v4l2_register;
|
||||
}
|
||||
|
||||
/* setup the decoder device */
|
||||
core->vdev[MSM_VIDC_DECODER].vdev.release =
|
||||
msm_vidc_release_video_device;
|
||||
core->vdev[MSM_VIDC_DECODER].vdev.fops = &msm_v4l2_vidc_fops;
|
||||
core->vdev[MSM_VIDC_DECODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
|
||||
core->vdev[MSM_VIDC_DECODER].vdev.vfl_dir = VFL_DIR_M2M;
|
||||
core->vdev[MSM_VIDC_DECODER].type = MSM_VIDC_DECODER;
|
||||
core->vdev[MSM_VIDC_DECODER].vdev.v4l2_dev = &core->v4l2_dev;
|
||||
rc = video_register_device(&core->vdev[MSM_VIDC_DECODER].vdev,
|
||||
VFL_TYPE_GRABBER, nr);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to register video decoder device");
|
||||
goto err_dec_register;
|
||||
}
|
||||
|
||||
video_set_drvdata(&core->vdev[MSM_VIDC_DECODER].vdev, core);
|
||||
dev = &core->vdev[MSM_VIDC_DECODER].vdev.dev;
|
||||
rc = device_create_file(dev, &dev_attr_link_name);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to create link name sysfs for decoder");
|
||||
goto err_dec_attr_link_name;
|
||||
}
|
||||
|
||||
/* setup the encoder device */
|
||||
core->vdev[MSM_VIDC_ENCODER].vdev.release =
|
||||
msm_vidc_release_video_device;
|
||||
core->vdev[MSM_VIDC_ENCODER].vdev.fops = &msm_v4l2_vidc_fops;
|
||||
core->vdev[MSM_VIDC_ENCODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
|
||||
core->vdev[MSM_VIDC_ENCODER].vdev.vfl_dir = VFL_DIR_M2M;
|
||||
core->vdev[MSM_VIDC_ENCODER].type = MSM_VIDC_ENCODER;
|
||||
core->vdev[MSM_VIDC_ENCODER].vdev.v4l2_dev = &core->v4l2_dev;
|
||||
rc = video_register_device(&core->vdev[MSM_VIDC_ENCODER].vdev,
|
||||
VFL_TYPE_GRABBER, nr + 1);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to register video encoder device");
|
||||
goto err_enc_register;
|
||||
}
|
||||
|
||||
video_set_drvdata(&core->vdev[MSM_VIDC_ENCODER].vdev, core);
|
||||
dev = &core->vdev[MSM_VIDC_ENCODER].vdev.dev;
|
||||
rc = device_create_file(dev, &dev_attr_link_name);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to create link name sysfs for encoder");
|
||||
goto err_enc_attr_link_name;
|
||||
}
|
||||
|
||||
/* finish setting up the 'core' */
|
||||
mutex_lock(&vidc_driver->lock);
|
||||
if (vidc_driver->num_cores + 1 > MSM_VIDC_CORES_MAX) {
|
||||
mutex_unlock(&vidc_driver->lock);
|
||||
dprintk(VIDC_ERR, "Maximum cores already exist, core_no = %d\n",
|
||||
vidc_driver->num_cores);
|
||||
goto err_cores_exceeded;
|
||||
}
|
||||
vidc_driver->num_cores++;
|
||||
mutex_unlock(&vidc_driver->lock);
|
||||
|
||||
core->device = vidc_hfi_initialize(core->hfi_type, core->id,
|
||||
&core->resources, &handle_cmd_response);
|
||||
if (IS_ERR_OR_NULL(core->device)) {
|
||||
mutex_lock(&vidc_driver->lock);
|
||||
vidc_driver->num_cores--;
|
||||
mutex_unlock(&vidc_driver->lock);
|
||||
|
||||
rc = PTR_ERR(core->device) ?: -EBADHANDLE;
|
||||
if (rc != -EPROBE_DEFER)
|
||||
dprintk(VIDC_ERR, "Failed to create HFI device\n");
|
||||
else
|
||||
dprintk(VIDC_DBG, "msm_vidc: request probe defer\n");
|
||||
goto err_cores_exceeded;
|
||||
}
|
||||
|
||||
mutex_lock(&vidc_driver->lock);
|
||||
list_add_tail(&core->list, &vidc_driver->cores);
|
||||
mutex_unlock(&vidc_driver->lock);
|
||||
|
||||
core->debugfs_root = msm_vidc_debugfs_init_core(
|
||||
core, vidc_driver->debugfs_root);
|
||||
|
||||
vidc_driver->platform_version =
|
||||
msm_vidc_read_efuse_version(pdev,
|
||||
core->resources.pf_ver_tbl, "efuse");
|
||||
|
||||
vidc_driver->capability_version =
|
||||
msm_vidc_read_efuse_version(
|
||||
pdev, core->resources.pf_cap_tbl, "efuse2");
|
||||
|
||||
rc = call_hfi_op(core->device, core_early_init,
|
||||
core->device->hfi_device_data);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to early init core\n");
|
||||
goto err_fail_sub_device_probe;
|
||||
}
|
||||
dprintk(VIDC_DBG, "populating sub devices\n");
|
||||
/*
|
||||
* Trigger probe for each sub-device i.e. qcom,msm-vidc,context-bank.
|
||||
* When msm_vidc_probe is called for each sub-device, parse the
|
||||
* context-bank details and store it in core->resources.context_banks
|
||||
* list.
|
||||
*/
|
||||
rc = of_platform_populate(pdev->dev.of_node, msm_vidc_dt_match, NULL,
|
||||
&pdev->dev);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Failed to trigger probe for sub-devices\n");
|
||||
call_hfi_op(core->device, core_early_release,
|
||||
core->device->hfi_device_data);
|
||||
goto err_fail_sub_device_probe;
|
||||
}
|
||||
call_hfi_op(core->device, core_early_release,
|
||||
core->device->hfi_device_data);
|
||||
|
||||
return rc;
|
||||
|
||||
err_fail_sub_device_probe:
|
||||
vidc_hfi_deinitialize(core->hfi_type, core->device);
|
||||
err_cores_exceeded:
|
||||
device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev,
|
||||
&dev_attr_link_name);
|
||||
err_enc_attr_link_name:
|
||||
video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
|
||||
err_enc_register:
|
||||
device_remove_file(&core->vdev[MSM_VIDC_DECODER].vdev.dev,
|
||||
&dev_attr_link_name);
|
||||
err_dec_attr_link_name:
|
||||
video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
|
||||
err_dec_register:
|
||||
v4l2_device_unregister(&core->v4l2_dev);
|
||||
err_v4l2_register:
|
||||
sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group);
|
||||
err_core_init:
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
kfree(core);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_probe_context_bank(struct platform_device *pdev)
|
||||
{
|
||||
return read_context_bank_resources_from_dt(pdev);
|
||||
}
|
||||
|
||||
static int msm_vidc_probe_bus(struct platform_device *pdev)
|
||||
{
|
||||
return read_bus_resources_from_dt(pdev);
|
||||
}
|
||||
|
||||
static int msm_vidc_probe(struct platform_device *pdev)
|
||||
{
|
||||
/*
|
||||
* Sub devices probe will be triggered by of_platform_populate() towards
|
||||
* the end of the probe function after msm-vidc device probe is
|
||||
* completed. Return immediately after completing sub-device probe.
|
||||
*/
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-vidc")) {
|
||||
return msm_vidc_probe_vidc_device(pdev);
|
||||
} else if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,msm-vidc,bus")) {
|
||||
return msm_vidc_probe_bus(pdev);
|
||||
} else if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"qcom,msm-vidc,context-bank")) {
|
||||
return msm_vidc_probe_context_bank(pdev);
|
||||
}
|
||||
/* How did we end up here? */
|
||||
WARN_ON(VIDC_DBG_WARN_ENABLE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int msm_vidc_remove(struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
|
||||
if (!pdev) {
|
||||
dprintk(VIDC_ERR, "%s invalid input %pK", __func__, pdev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = dev_get_drvdata(&pdev->dev);
|
||||
if (!core) {
|
||||
dprintk(VIDC_ERR, "%s invalid core", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (core->resources.use_non_secure_pil)
|
||||
venus_boot_deinit();
|
||||
|
||||
vidc_hfi_deinitialize(core->hfi_type, core->device);
|
||||
device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev,
|
||||
&dev_attr_link_name);
|
||||
video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
|
||||
device_remove_file(&core->vdev[MSM_VIDC_DECODER].vdev.dev,
|
||||
&dev_attr_link_name);
|
||||
video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
|
||||
v4l2_device_unregister(&core->v4l2_dev);
|
||||
|
||||
msm_vidc_free_platform_resources(&core->resources);
|
||||
sysfs_remove_group(&pdev->dev.kobj, &msm_vidc_core_attr_group);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
kfree(core);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_pm_suspend(struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
|
||||
/*
|
||||
* Bail out if
|
||||
* - driver possibly not probed yet
|
||||
* - not the main device. We don't support power management on
|
||||
* subdevices (e.g. context banks)
|
||||
*/
|
||||
if (!dev || !dev->driver ||
|
||||
!of_device_is_compatible(dev->of_node, "qcom,msm-vidc"))
|
||||
return 0;
|
||||
|
||||
core = dev_get_drvdata(dev);
|
||||
if (!core) {
|
||||
dprintk(VIDC_ERR, "%s invalid core\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = msm_vidc_suspend(core->id);
|
||||
if (rc == -ENOTSUPP)
|
||||
rc = 0;
|
||||
else if (rc)
|
||||
dprintk(VIDC_WARN, "Failed to suspend: %d\n", rc);
|
||||
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int msm_vidc_pm_resume(struct device *dev)
|
||||
{
|
||||
dprintk(VIDC_INFO, "%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops msm_vidc_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(msm_vidc_pm_suspend, msm_vidc_pm_resume)
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);
|
||||
|
||||
static struct platform_driver msm_vidc_driver = {
|
||||
.probe = msm_vidc_probe,
|
||||
.remove = msm_vidc_remove,
|
||||
.driver = {
|
||||
.name = "msm_vidc_v4l2",
|
||||
.of_match_table = msm_vidc_dt_match,
|
||||
.pm = &msm_vidc_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init msm_vidc_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
vidc_driver = kzalloc(sizeof(*vidc_driver),
|
||||
GFP_KERNEL);
|
||||
if (!vidc_driver) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to allocate memroy for msm_vidc_drv\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&vidc_driver->cores);
|
||||
mutex_init(&vidc_driver->lock);
|
||||
vidc_driver->debugfs_root = msm_vidc_debugfs_init_drv();
|
||||
if (!vidc_driver->debugfs_root)
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to create debugfs for msm_vidc\n");
|
||||
|
||||
rc = platform_driver_register(&msm_vidc_driver);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to register platform driver\n");
|
||||
debugfs_remove_recursive(vidc_driver->debugfs_root);
|
||||
kfree(vidc_driver);
|
||||
vidc_driver = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void __exit msm_vidc_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&msm_vidc_driver);
|
||||
debugfs_remove_recursive(vidc_driver->debugfs_root);
|
||||
kfree(vidc_driver);
|
||||
vidc_driver = NULL;
|
||||
}
|
||||
|
||||
module_init(msm_vidc_init);
|
||||
module_exit(msm_vidc_exit);
|
2820
drivers/media/platform/msm/vidc_3x/msm_vdec.c
Normal file
2820
drivers/media/platform/msm/vidc_3x/msm_vdec.c
Normal file
File diff suppressed because it is too large
Load diff
38
drivers/media/platform/msm/vidc_3x/msm_vdec.h
Normal file
38
drivers/media/platform/msm/vidc_3x/msm_vdec.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#ifndef _MSM_VDEC_H_
|
||||
#define _MSM_VDEC_H_
|
||||
|
||||
#include <media/msm_vidc.h>
|
||||
#include "msm_vidc_internal.h"
|
||||
|
||||
int msm_vdec_inst_init(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
|
||||
int msm_vdec_querycap(void *instance, struct v4l2_capability *cap);
|
||||
int msm_vdec_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
|
||||
int msm_vdec_s_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_vdec_g_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_vdec_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
|
||||
int msm_vdec_reqbufs(void *instance, struct v4l2_requestbuffers *b);
|
||||
int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
|
||||
int msm_vdec_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
|
||||
int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
|
||||
int msm_vdec_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
|
||||
int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
|
||||
int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
|
||||
int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec);
|
||||
int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
|
||||
struct vb2_ops *msm_vdec_get_vb2q_ops(void);
|
||||
|
||||
#endif
|
4659
drivers/media/platform/msm/vidc_3x/msm_venc.c
Normal file
4659
drivers/media/platform/msm/vidc_3x/msm_venc.c
Normal file
File diff suppressed because it is too large
Load diff
38
drivers/media/platform/msm/vidc_3x/msm_venc.h
Normal file
38
drivers/media/platform/msm/vidc_3x/msm_venc.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2015, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#ifndef _MSM_VENC_H_
|
||||
#define _MSM_VENC_H_
|
||||
|
||||
#include <media/msm_vidc.h>
|
||||
#include "msm_vidc_internal.h"
|
||||
|
||||
int msm_venc_inst_init(struct msm_vidc_inst *inst);
|
||||
int msm_venc_ctrl_init(struct msm_vidc_inst *inst);
|
||||
int msm_venc_querycap(void *instance, struct v4l2_capability *cap);
|
||||
int msm_venc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
|
||||
int msm_venc_s_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_venc_g_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_venc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
|
||||
int msm_venc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
|
||||
int msm_venc_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
|
||||
int msm_venc_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
|
||||
int msm_venc_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
|
||||
int msm_venc_dqbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
|
||||
int msm_venc_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
|
||||
int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
|
||||
int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc);
|
||||
int msm_venc_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
|
||||
struct vb2_ops *msm_venc_get_vb2q_ops(void);
|
||||
|
||||
#endif
|
1498
drivers/media/platform/msm/vidc_3x/msm_vidc.c
Normal file
1498
drivers/media/platform/msm/vidc_3x/msm_vidc.c
Normal file
File diff suppressed because it is too large
Load diff
5325
drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
Normal file
5325
drivers/media/platform/msm/vidc_3x/msm_vidc_common.c
Normal file
File diff suppressed because it is too large
Load diff
104
drivers/media/platform/msm/vidc_3x/msm_vidc_common.h
Normal file
104
drivers/media/platform/msm/vidc_3x/msm_vidc_common.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2016, 2018, 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_VIDC_COMMON_H_
|
||||
#define _MSM_VIDC_COMMON_H_
|
||||
#include "msm_vidc_internal.h"
|
||||
struct vb2_buf_entry {
|
||||
struct list_head list;
|
||||
struct vb2_buffer *vb;
|
||||
};
|
||||
|
||||
extern const char *const mpeg_video_vidc_extradata[];
|
||||
|
||||
enum load_calc_quirks {
|
||||
LOAD_CALC_NO_QUIRKS = 0,
|
||||
LOAD_CALC_IGNORE_TURBO_LOAD = 1 << 0,
|
||||
LOAD_CALC_IGNORE_THUMBNAIL_LOAD = 1 << 1,
|
||||
LOAD_CALC_IGNORE_NON_REALTIME_LOAD = 1 << 2,
|
||||
};
|
||||
|
||||
struct msm_vidc_core *get_vidc_core(int core_id);
|
||||
const struct msm_vidc_format *msm_comm_get_pixel_fmt_index(
|
||||
const struct msm_vidc_format fmt[], int size, int index, int fmt_type);
|
||||
struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc(
|
||||
struct msm_vidc_format fmt[], int size, int fourcc, int fmt_type);
|
||||
struct buf_queue *msm_comm_get_vb2q(
|
||||
struct msm_vidc_inst *inst, enum v4l2_buf_type type);
|
||||
int msm_comm_try_state(struct msm_vidc_inst *inst, int state);
|
||||
int msm_comm_try_get_bufreqs(struct msm_vidc_inst *inst);
|
||||
int msm_comm_try_set_prop(struct msm_vidc_inst *inst,
|
||||
enum hal_property ptype, void *pdata);
|
||||
int msm_comm_try_get_prop(struct msm_vidc_inst *inst,
|
||||
enum hal_property ptype, union hal_get_property *hprop);
|
||||
int msm_comm_set_scratch_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_set_persist_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_set_output_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_queue_output_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb);
|
||||
void msm_comm_scale_clocks_and_bus(struct msm_vidc_inst *inst);
|
||||
int msm_comm_scale_clocks(struct msm_vidc_core *core);
|
||||
int msm_comm_scale_clocks_load(struct msm_vidc_core *core,
|
||||
int num_mbs_per_sec, enum load_calc_quirks quirks);
|
||||
void msm_comm_flush_dynamic_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags);
|
||||
int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
|
||||
bool check_for_reuse);
|
||||
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst);
|
||||
void msm_comm_release_eos_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_release_output_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_comm_force_cleanup(struct msm_vidc_inst *inst);
|
||||
int msm_comm_suspend(int core_id);
|
||||
enum hal_extradata_id msm_comm_get_hal_extradata_index(
|
||||
enum v4l2_mpeg_vidc3x_extradata index);
|
||||
enum hal_buffer_layout_type msm_comm_get_hal_buffer_layout(
|
||||
enum v4l2_mpeg_vidc_video_mvc_layout index);
|
||||
struct hal_buffer_requirements *get_buff_req_buffer(
|
||||
struct msm_vidc_inst *inst, u32 buffer_type);
|
||||
#define IS_PRIV_CTRL(idx) (\
|
||||
(V4L2_CTRL_ID2WHICH(idx) == V4L2_CTRL_CLASS_MPEG) && \
|
||||
V4L2_CTRL_DRIVER_PRIV(idx))
|
||||
void msm_comm_session_clean(struct msm_vidc_inst *inst);
|
||||
int msm_comm_kill_session(struct msm_vidc_inst *inst);
|
||||
enum multi_stream msm_comm_get_stream_output_mode(struct msm_vidc_inst *inst);
|
||||
enum hal_buffer msm_comm_get_hal_output_buffer(struct msm_vidc_inst *inst);
|
||||
int msm_comm_smem_alloc(struct msm_vidc_inst *inst,
|
||||
size_t size, u32 align, u32 flags,
|
||||
enum hal_buffer buffer_type, int map_kernel,
|
||||
struct msm_smem *smem);
|
||||
void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem);
|
||||
int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
|
||||
struct msm_smem *mem, enum smem_cache_ops cache_ops);
|
||||
enum hal_video_codec get_hal_codec(int fourcc);
|
||||
enum hal_domain get_hal_domain(int session_type);
|
||||
int msm_comm_check_core_init(struct msm_vidc_core *core);
|
||||
int msm_comm_get_inst_load(struct msm_vidc_inst *inst,
|
||||
enum load_calc_quirks quirks);
|
||||
int msm_comm_get_load(struct msm_vidc_core *core,
|
||||
enum session_type type, enum load_calc_quirks quirks);
|
||||
int msm_comm_set_color_format(struct msm_vidc_inst *inst,
|
||||
enum hal_buffer buffer_type, int fourcc);
|
||||
int msm_comm_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl);
|
||||
int msm_comm_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl);
|
||||
int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id);
|
||||
int msm_comm_ctrl_init(struct msm_vidc_inst *inst,
|
||||
struct msm_vidc_ctrl *drv_ctrls, u32 num_ctrls,
|
||||
const struct v4l2_ctrl_ops *ctrl_ops);
|
||||
int msm_comm_ctrl_deinit(struct msm_vidc_inst *inst);
|
||||
void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
|
||||
bool msm_comm_turbo_session(struct msm_vidc_inst *inst);
|
||||
struct msm_vidc_inst *get_inst(struct msm_vidc_core *core, void *session_id);
|
||||
void put_inst(struct msm_vidc_inst *inst);
|
||||
#endif
|
704
drivers/media/platform/msm/vidc_3x/msm_vidc_dcvs.c
Normal file
704
drivers/media/platform/msm/vidc_3x/msm_vidc_dcvs.c
Normal file
|
@ -0,0 +1,704 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2014-2016, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "msm_vidc_common.h"
|
||||
#include "vidc_hfi_api.h"
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "msm_vidc_dcvs.h"
|
||||
|
||||
#define IS_VALID_DCVS_SESSION(__cur_mbpf, __min_mbpf) \
|
||||
((__cur_mbpf) >= (__min_mbpf))
|
||||
|
||||
static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst);
|
||||
static bool msm_dcvs_enc_check(struct msm_vidc_inst *inst);
|
||||
static int msm_dcvs_enc_scale_clocks(struct msm_vidc_inst *inst);
|
||||
static int msm_dcvs_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd);
|
||||
|
||||
static inline int msm_dcvs_get_mbs_per_frame(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int height, width;
|
||||
|
||||
if (!inst->in_reconfig) {
|
||||
height = max(inst->prop.height[CAPTURE_PORT],
|
||||
inst->prop.height[OUTPUT_PORT]);
|
||||
width = max(inst->prop.width[CAPTURE_PORT],
|
||||
inst->prop.width[OUTPUT_PORT]);
|
||||
} else {
|
||||
height = inst->reconfig_height;
|
||||
width = inst->reconfig_width;
|
||||
}
|
||||
|
||||
return NUM_MBS_PER_FRAME(height, width);
|
||||
}
|
||||
|
||||
static inline int msm_dcvs_count_active_instances(struct msm_vidc_core *core)
|
||||
{
|
||||
int active_instances = 0;
|
||||
struct msm_vidc_inst *inst = NULL;
|
||||
|
||||
if (!core) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(inst, &core->instances, list) {
|
||||
if (inst->state >= MSM_VIDC_OPEN_DONE &&
|
||||
inst->state < MSM_VIDC_STOP_DONE)
|
||||
active_instances++;
|
||||
}
|
||||
mutex_unlock(&core->lock);
|
||||
return active_instances;
|
||||
}
|
||||
|
||||
static bool msm_dcvs_check_codec_supported(int fourcc,
|
||||
unsigned long codecs_supported, enum session_type type)
|
||||
{
|
||||
int codec_bit, session_type_bit;
|
||||
bool codec_type, session_type;
|
||||
unsigned long session;
|
||||
|
||||
session = VIDC_VOTE_DATA_SESSION_VAL(get_hal_codec(fourcc),
|
||||
get_hal_domain(type));
|
||||
|
||||
if (!codecs_supported || !session)
|
||||
return false;
|
||||
|
||||
/* ffs returns a 1 indexed, test_bit takes a 0 indexed...index */
|
||||
codec_bit = ffs(session) - 1;
|
||||
session_type_bit = codec_bit + 1;
|
||||
|
||||
codec_type =
|
||||
test_bit(codec_bit, &codecs_supported) ==
|
||||
test_bit(codec_bit, &session);
|
||||
session_type =
|
||||
test_bit(session_type_bit, &codecs_supported) ==
|
||||
test_bit(session_type_bit, &session);
|
||||
|
||||
return codec_type && session_type;
|
||||
}
|
||||
|
||||
static void msm_dcvs_update_dcvs_params(int idx, struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct dcvs_stats *dcvs = NULL;
|
||||
struct msm_vidc_platform_resources *res = NULL;
|
||||
struct dcvs_table *table = NULL;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
dcvs = &inst->dcvs;
|
||||
res = &inst->core->resources;
|
||||
table = res->dcvs_tbl;
|
||||
|
||||
dcvs->load_low = table[idx].load_low;
|
||||
dcvs->load_high = table[idx].load_high;
|
||||
dcvs->supported_codecs = table[idx].supported_codecs;
|
||||
}
|
||||
|
||||
static void msm_dcvs_enc_check_and_scale_clocks(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (inst->session_type == MSM_VIDC_ENCODER && msm_vidc_enc_dcvs_mode) {
|
||||
inst->dcvs_mode = msm_dcvs_check_supported(inst);
|
||||
dprintk(VIDC_DBG, "%s: session DCVS %s supported\n",
|
||||
__func__, inst->dcvs_mode ? "" : "not");
|
||||
|
||||
if (inst->dcvs_mode) {
|
||||
rc = msm_dcvs_enc_scale_clocks(inst);
|
||||
if (rc) {
|
||||
dprintk(VIDC_DBG,
|
||||
"ENC_DCVS: error while scaling clocks\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void msm_dcvs_dec_check_and_scale_clocks(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (inst->session_type != MSM_VIDC_DECODER || !msm_vidc_dec_dcvs_mode)
|
||||
return;
|
||||
|
||||
if (msm_dcvs_check_supported(inst)) {
|
||||
inst->dcvs_mode = true;
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: session DCVS supported, decode_dcvs_mode = %d\n",
|
||||
__func__, inst->dcvs_mode);
|
||||
} else {
|
||||
inst->dcvs_mode = false;
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: session DCVS not supported, decode_dcvs_mode = %d\n",
|
||||
__func__, inst->dcvs_mode);
|
||||
}
|
||||
|
||||
if (msm_vidc_dec_dcvs_mode && inst->dcvs_mode) {
|
||||
msm_dcvs_monitor_buffer(inst);
|
||||
rc = msm_dcvs_dec_scale_clocks(inst, false);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: Failed to scale clocks in DCVS: %d\n",
|
||||
__func__, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb)
|
||||
{
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_etb)
|
||||
msm_dcvs_enc_check_and_scale_clocks(inst);
|
||||
else
|
||||
msm_dcvs_dec_check_and_scale_clocks(inst);
|
||||
}
|
||||
|
||||
static inline int get_pending_bufs_fw(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int fw_out_qsize = 0, buffers_in_driver = 0;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (inst->state >= MSM_VIDC_OPEN_DONE &&
|
||||
inst->state < MSM_VIDC_STOP_DONE) {
|
||||
fw_out_qsize = inst->count.ftb - inst->count.fbd;
|
||||
buffers_in_driver = inst->buffers_held_in_driver;
|
||||
}
|
||||
|
||||
return fw_out_qsize + buffers_in_driver;
|
||||
}
|
||||
|
||||
static inline void msm_dcvs_print_dcvs_stats(struct dcvs_stats *dcvs)
|
||||
{
|
||||
dprintk(VIDC_DBG,
|
||||
"DCVS: Load_Low %d, Load High %d\n",
|
||||
dcvs->load_low,
|
||||
dcvs->load_high);
|
||||
|
||||
dprintk(VIDC_DBG,
|
||||
"DCVS: ThrDispBufLow %d, ThrDispBufHigh %d\n",
|
||||
dcvs->threshold_disp_buf_low,
|
||||
dcvs->threshold_disp_buf_high);
|
||||
|
||||
dprintk(VIDC_DBG,
|
||||
"DCVS: min_threshold %d, max_threshold %d\n",
|
||||
dcvs->min_threshold, dcvs->max_threshold);
|
||||
}
|
||||
|
||||
void msm_dcvs_init_load(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_vidc_core *core;
|
||||
struct hal_buffer_requirements *output_buf_req;
|
||||
struct dcvs_stats *dcvs;
|
||||
struct dcvs_table *table;
|
||||
struct msm_vidc_platform_resources *res = NULL;
|
||||
int i, num_rows, fourcc;
|
||||
|
||||
dprintk(VIDC_DBG, "Init DCVS Load\n");
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
core = inst->core;
|
||||
dcvs = &inst->dcvs;
|
||||
res = &core->resources;
|
||||
dcvs->load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS);
|
||||
|
||||
num_rows = res->dcvs_tbl_size;
|
||||
table = res->dcvs_tbl;
|
||||
|
||||
if (!num_rows || !table) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: Dcvs table entry not found.\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
fourcc = inst->session_type == MSM_VIDC_DECODER ?
|
||||
inst->fmts[OUTPUT_PORT].fourcc :
|
||||
inst->fmts[CAPTURE_PORT].fourcc;
|
||||
|
||||
for (i = 0; i < num_rows; i++) {
|
||||
bool matches = msm_dcvs_check_codec_supported(
|
||||
fourcc,
|
||||
table[i].supported_codecs,
|
||||
inst->session_type);
|
||||
if (!matches)
|
||||
continue;
|
||||
|
||||
if (dcvs->load > table[i].load) {
|
||||
msm_dcvs_update_dcvs_params(i, inst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inst->session_type == MSM_VIDC_ENCODER)
|
||||
goto print_stats;
|
||||
|
||||
output_buf_req = get_buff_req_buffer(inst,
|
||||
msm_comm_get_hal_output_buffer(inst));
|
||||
|
||||
if (!output_buf_req) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: No buffer requirement for buffer type %x\n",
|
||||
__func__, HAL_BUFFER_OUTPUT);
|
||||
return;
|
||||
}
|
||||
|
||||
dcvs->transition_turbo = false;
|
||||
|
||||
/* calculating the min and max threshold */
|
||||
if (output_buf_req->buffer_count_actual) {
|
||||
dcvs->min_threshold = output_buf_req->buffer_count_actual -
|
||||
output_buf_req->buffer_count_min -
|
||||
msm_dcvs_get_extra_buff_count(inst) + 1;
|
||||
dcvs->max_threshold = output_buf_req->buffer_count_actual;
|
||||
if (dcvs->max_threshold <= dcvs->min_threshold)
|
||||
dcvs->max_threshold =
|
||||
dcvs->min_threshold + DCVS_BUFFER_SAFEGUARD;
|
||||
dcvs->threshold_disp_buf_low = dcvs->min_threshold;
|
||||
dcvs->threshold_disp_buf_high = dcvs->max_threshold;
|
||||
}
|
||||
|
||||
print_stats:
|
||||
msm_dcvs_print_dcvs_stats(dcvs);
|
||||
}
|
||||
|
||||
void msm_dcvs_init(struct msm_vidc_inst *inst)
|
||||
{
|
||||
dprintk(VIDC_DBG, "Init DCVS Struct\n");
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
|
||||
return;
|
||||
}
|
||||
|
||||
inst->dcvs = (struct dcvs_stats){ {0} };
|
||||
inst->dcvs.threshold_disp_buf_high = DCVS_NOMINAL_THRESHOLD;
|
||||
inst->dcvs.threshold_disp_buf_low = DCVS_TURBO_THRESHOLD;
|
||||
}
|
||||
|
||||
void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int new_ftb, i, prev_buf_count;
|
||||
int fw_pending_bufs, total_output_buf, buffers_outside_fw;
|
||||
struct dcvs_stats *dcvs;
|
||||
struct hal_buffer_requirements *output_buf_req;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst);
|
||||
return;
|
||||
}
|
||||
dcvs = &inst->dcvs;
|
||||
|
||||
mutex_lock(&inst->lock);
|
||||
output_buf_req = get_buff_req_buffer(inst,
|
||||
msm_comm_get_hal_output_buffer(inst));
|
||||
if (!output_buf_req) {
|
||||
dprintk(VIDC_ERR, "%s : Get output buffer req failed %pK\n",
|
||||
__func__, inst);
|
||||
mutex_unlock(&inst->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
total_output_buf = output_buf_req->buffer_count_actual;
|
||||
fw_pending_bufs = get_pending_bufs_fw(inst);
|
||||
mutex_unlock(&inst->lock);
|
||||
|
||||
buffers_outside_fw = total_output_buf - fw_pending_bufs;
|
||||
dcvs->num_ftb[dcvs->ftb_index] = buffers_outside_fw;
|
||||
dcvs->ftb_index = (dcvs->ftb_index + 1) % DCVS_FTB_WINDOW;
|
||||
|
||||
if (dcvs->ftb_counter < DCVS_FTB_WINDOW)
|
||||
dcvs->ftb_counter++;
|
||||
|
||||
dprintk(VIDC_PROF,
|
||||
"DCVS: ftb_counter %d\n", dcvs->ftb_counter);
|
||||
|
||||
if (dcvs->ftb_counter == DCVS_FTB_WINDOW) {
|
||||
new_ftb = 0;
|
||||
for (i = 0; i < dcvs->ftb_counter; i++) {
|
||||
if (dcvs->num_ftb[i] > new_ftb)
|
||||
new_ftb = dcvs->num_ftb[i];
|
||||
}
|
||||
|
||||
dcvs->threshold_disp_buf_high = new_ftb;
|
||||
if (dcvs->threshold_disp_buf_high <=
|
||||
dcvs->threshold_disp_buf_low +
|
||||
DCVS_BUFFER_SAFEGUARD) {
|
||||
dcvs->threshold_disp_buf_high =
|
||||
dcvs->threshold_disp_buf_low +
|
||||
DCVS_BUFFER_SAFEGUARD
|
||||
+ (DCVS_BUFFER_SAFEGUARD == 0);
|
||||
}
|
||||
|
||||
dcvs->threshold_disp_buf_high =
|
||||
clamp(dcvs->threshold_disp_buf_high,
|
||||
dcvs->min_threshold,
|
||||
dcvs->max_threshold);
|
||||
}
|
||||
|
||||
if (dcvs->ftb_counter == DCVS_FTB_WINDOW &&
|
||||
dcvs->load == dcvs->load_low) {
|
||||
prev_buf_count =
|
||||
dcvs->num_ftb[((dcvs->ftb_index - 2 +
|
||||
DCVS_FTB_WINDOW) % DCVS_FTB_WINDOW)];
|
||||
if (prev_buf_count == dcvs->threshold_disp_buf_low &&
|
||||
buffers_outside_fw <= dcvs->threshold_disp_buf_low) {
|
||||
dcvs->transition_turbo = true;
|
||||
} else if (buffers_outside_fw > dcvs->threshold_disp_buf_low &&
|
||||
(buffers_outside_fw -
|
||||
(prev_buf_count - buffers_outside_fw))
|
||||
< dcvs->threshold_disp_buf_low){
|
||||
dcvs->transition_turbo = true;
|
||||
}
|
||||
}
|
||||
|
||||
dprintk(VIDC_PROF,
|
||||
"DCVS: total_output_buf %d buffers_outside_fw %d load %d transition_turbo %d\n",
|
||||
total_output_buf, buffers_outside_fw, dcvs->load_low,
|
||||
dcvs->transition_turbo);
|
||||
}
|
||||
|
||||
static int msm_dcvs_enc_scale_clocks(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0, fw_pending_bufs = 0, total_input_buf = 0;
|
||||
struct msm_vidc_core *core;
|
||||
struct dcvs_stats *dcvs;
|
||||
|
||||
if (!inst || !inst->core || !inst->core->device) {
|
||||
dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = inst->core;
|
||||
dcvs = &inst->dcvs;
|
||||
|
||||
mutex_lock(&inst->lock);
|
||||
total_input_buf = inst->buff_req.buffer[0].buffer_count_actual;
|
||||
fw_pending_bufs = (inst->count.etb - inst->count.ebd);
|
||||
mutex_unlock(&inst->lock);
|
||||
|
||||
dprintk(VIDC_PROF,
|
||||
"DCVS: total_input_buf %d, fw_pending_bufs %d\n",
|
||||
total_input_buf, fw_pending_bufs);
|
||||
|
||||
if (dcvs->etb_counter < total_input_buf) {
|
||||
dcvs->etb_counter++;
|
||||
if (dcvs->etb_counter != total_input_buf)
|
||||
return rc;
|
||||
}
|
||||
|
||||
dprintk(VIDC_PROF,
|
||||
"DCVS: total_input_buf %d, fw_pending_bufs %d etb_counter %d dcvs->load %d\n",
|
||||
total_input_buf, fw_pending_bufs,
|
||||
dcvs->etb_counter, dcvs->load);
|
||||
|
||||
if (fw_pending_bufs <= DCVS_ENC_LOW_THR &&
|
||||
dcvs->load > dcvs->load_low) {
|
||||
dcvs->load = dcvs->load_low;
|
||||
dcvs->prev_freq_lowered = true;
|
||||
} else {
|
||||
dcvs->prev_freq_lowered = false;
|
||||
}
|
||||
|
||||
if (fw_pending_bufs >= DCVS_ENC_HIGH_THR &&
|
||||
dcvs->load <= dcvs->load_low) {
|
||||
dcvs->load = dcvs->load_high;
|
||||
dcvs->prev_freq_increased = true;
|
||||
} else {
|
||||
dcvs->prev_freq_increased = false;
|
||||
}
|
||||
|
||||
if (dcvs->prev_freq_lowered || dcvs->prev_freq_increased) {
|
||||
dprintk(VIDC_PROF,
|
||||
"DCVS: (Scaling Clock %s) etb clock set = %d total_input_buf = %d fw_pending_bufs %d\n",
|
||||
dcvs->prev_freq_lowered ? "Lower" : "Higher",
|
||||
dcvs->load, total_input_buf, fw_pending_bufs);
|
||||
|
||||
rc = msm_comm_scale_clocks_load(core, dcvs->load,
|
||||
LOAD_CALC_NO_QUIRKS);
|
||||
if (rc) {
|
||||
dprintk(VIDC_PROF,
|
||||
"Failed to set clock rate in FBD: %d\n", rc);
|
||||
}
|
||||
} else {
|
||||
dprintk(VIDC_PROF,
|
||||
"DCVS: etb clock load_old = %d total_input_buf = %d fw_pending_bufs %d\n",
|
||||
dcvs->load, total_input_buf, fw_pending_bufs);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* In DCVS scale_clocks will be done both in qbuf and FBD
|
||||
* 1 indicates call made from fbd that lowers clock
|
||||
* 0 indicates call made from qbuf that increases clock
|
||||
* based on DCVS algorithm
|
||||
*/
|
||||
|
||||
static int msm_dcvs_dec_scale_clocks(struct msm_vidc_inst *inst, bool fbd)
|
||||
{
|
||||
int rc = 0;
|
||||
int fw_pending_bufs = 0;
|
||||
int total_output_buf = 0;
|
||||
int buffers_outside_fw = 0;
|
||||
struct msm_vidc_core *core;
|
||||
struct hal_buffer_requirements *output_buf_req;
|
||||
struct dcvs_stats *dcvs;
|
||||
|
||||
if (!inst || !inst->core || !inst->core->device) {
|
||||
dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
dcvs = &inst->dcvs;
|
||||
mutex_lock(&inst->lock);
|
||||
fw_pending_bufs = get_pending_bufs_fw(inst);
|
||||
|
||||
output_buf_req = get_buff_req_buffer(inst,
|
||||
msm_comm_get_hal_output_buffer(inst));
|
||||
mutex_unlock(&inst->lock);
|
||||
if (!output_buf_req) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: No buffer requirement for buffer type %x\n",
|
||||
__func__, HAL_BUFFER_OUTPUT);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Total number of output buffers */
|
||||
total_output_buf = output_buf_req->buffer_count_actual;
|
||||
|
||||
/* Buffers outside FW are with display */
|
||||
buffers_outside_fw = total_output_buf - fw_pending_bufs;
|
||||
|
||||
if (buffers_outside_fw >= dcvs->threshold_disp_buf_high &&
|
||||
!dcvs->prev_freq_increased &&
|
||||
dcvs->load > dcvs->load_low) {
|
||||
dcvs->load = dcvs->load_low;
|
||||
dcvs->prev_freq_lowered = true;
|
||||
dcvs->prev_freq_increased = false;
|
||||
} else if (dcvs->transition_turbo && dcvs->load == dcvs->load_low) {
|
||||
dcvs->load = dcvs->load_high;
|
||||
dcvs->prev_freq_increased = true;
|
||||
dcvs->prev_freq_lowered = false;
|
||||
dcvs->transition_turbo = false;
|
||||
} else {
|
||||
dcvs->prev_freq_increased = false;
|
||||
dcvs->prev_freq_lowered = false;
|
||||
}
|
||||
|
||||
if (dcvs->prev_freq_lowered || dcvs->prev_freq_increased) {
|
||||
dprintk(VIDC_PROF,
|
||||
"DCVS: clock set = %d tot_output_buf = %d buffers_outside_fw %d threshold_high %d transition_turbo %d\n",
|
||||
dcvs->load, total_output_buf, buffers_outside_fw,
|
||||
dcvs->threshold_disp_buf_high, dcvs->transition_turbo);
|
||||
|
||||
rc = msm_comm_scale_clocks_load(core, dcvs->load,
|
||||
LOAD_CALC_NO_QUIRKS);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to set clock rate in FBD: %d\n", rc);
|
||||
}
|
||||
} else {
|
||||
dprintk(VIDC_PROF,
|
||||
"DCVS: clock old = %d tot_output_buf = %d buffers_outside_fw %d threshold_high %d transition_turbo %d\n",
|
||||
dcvs->load, total_output_buf, buffers_outside_fw,
|
||||
dcvs->threshold_disp_buf_high, dcvs->transition_turbo);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool msm_dcvs_enc_check(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int num_mbs_per_frame = 0;
|
||||
long instance_load = 0;
|
||||
long dcvs_limit = 0;
|
||||
bool dcvs_check_passed = false, is_codec_supported = false;
|
||||
struct msm_vidc_platform_resources *res = NULL;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
dprintk(VIDC_ERR, "%s Invalid params\n", __func__);
|
||||
return dcvs_check_passed;
|
||||
}
|
||||
|
||||
res = &inst->core->resources;
|
||||
if (!res->dcvs_limit) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s Dcvs limit table uninitialized\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
is_codec_supported =
|
||||
msm_dcvs_check_codec_supported(
|
||||
inst->fmts[CAPTURE_PORT].fourcc,
|
||||
inst->dcvs.supported_codecs,
|
||||
inst->session_type);
|
||||
|
||||
num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
|
||||
instance_load = msm_comm_get_inst_load(inst, LOAD_CALC_NO_QUIRKS);
|
||||
dcvs_limit =
|
||||
(long)res->dcvs_limit[inst->session_type].min_mbpf *
|
||||
res->dcvs_limit[inst->session_type].fps;
|
||||
|
||||
if (msm_vidc_enc_dcvs_mode && is_codec_supported &&
|
||||
inst->dcvs.is_power_save_mode &&
|
||||
IS_VALID_DCVS_SESSION(num_mbs_per_frame,
|
||||
res->dcvs_limit[inst->session_type].min_mbpf) &&
|
||||
IS_VALID_DCVS_SESSION(instance_load, dcvs_limit)) {
|
||||
dcvs_check_passed = true;
|
||||
}
|
||||
return dcvs_check_passed;
|
||||
}
|
||||
|
||||
static bool msm_dcvs_check_supported(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int num_mbs_per_frame = 0, instance_count = 0;
|
||||
long instance_load = 0;
|
||||
long dcvs_limit = 0;
|
||||
struct msm_vidc_inst *temp = NULL;
|
||||
struct msm_vidc_core *core;
|
||||
struct hal_buffer_requirements *output_buf_req;
|
||||
struct dcvs_stats *dcvs;
|
||||
bool is_codec_supported = false;
|
||||
struct msm_vidc_platform_resources *res = NULL;
|
||||
|
||||
if (!inst || !inst->core || !inst->core->device) {
|
||||
dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = inst->core;
|
||||
dcvs = &inst->dcvs;
|
||||
res = &core->resources;
|
||||
|
||||
if (!res->dcvs_limit) {
|
||||
dprintk(VIDC_INFO,
|
||||
"%s: dcvs limit table not found\n", __func__);
|
||||
return false;
|
||||
}
|
||||
instance_count = msm_dcvs_count_active_instances(core);
|
||||
|
||||
if (instance_count == 1 && inst->session_type == MSM_VIDC_DECODER &&
|
||||
!msm_comm_turbo_session(inst)) {
|
||||
num_mbs_per_frame = msm_dcvs_get_mbs_per_frame(inst);
|
||||
instance_load = msm_comm_get_inst_load(inst,
|
||||
LOAD_CALC_NO_QUIRKS);
|
||||
output_buf_req = get_buff_req_buffer(inst,
|
||||
msm_comm_get_hal_output_buffer(inst));
|
||||
dcvs_limit =
|
||||
(long)res->dcvs_limit[inst->session_type].min_mbpf *
|
||||
res->dcvs_limit[inst->session_type].fps;
|
||||
is_codec_supported =
|
||||
msm_dcvs_check_codec_supported(
|
||||
inst->fmts[OUTPUT_PORT].fourcc,
|
||||
inst->dcvs.supported_codecs,
|
||||
inst->session_type);
|
||||
if (!is_codec_supported ||
|
||||
!IS_VALID_DCVS_SESSION(num_mbs_per_frame,
|
||||
res->dcvs_limit[inst->session_type].min_mbpf) ||
|
||||
!IS_VALID_DCVS_SESSION(instance_load, dcvs_limit) ||
|
||||
inst->seqchanged_count > 1)
|
||||
return false;
|
||||
|
||||
if (!output_buf_req) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: No buffer requirement for buffer type %x\n",
|
||||
__func__, HAL_BUFFER_OUTPUT);
|
||||
return false;
|
||||
}
|
||||
} else if (instance_count == 1 &&
|
||||
inst->session_type == MSM_VIDC_ENCODER &&
|
||||
!msm_comm_turbo_session(inst)) {
|
||||
if (!msm_dcvs_enc_check(inst))
|
||||
return false;
|
||||
} else {
|
||||
/*
|
||||
* For multiple instance use case with 4K, clocks will be scaled
|
||||
* as per load in streamon, but the clocks may be scaled
|
||||
* down as DCVS is running for first playback instance
|
||||
* Rescaling the core clock for multiple instance use case
|
||||
*/
|
||||
if (!dcvs->is_clock_scaled) {
|
||||
if (!msm_comm_scale_clocks(core)) {
|
||||
dcvs->is_clock_scaled = true;
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: Scaled clocks = %d\n",
|
||||
__func__, dcvs->is_clock_scaled);
|
||||
} else {
|
||||
dprintk(VIDC_DBG,
|
||||
"%s: Failed to Scale clocks. Perf might be impacted\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* For multiple instance use case turn OFF DCVS algorithm
|
||||
* immediately
|
||||
*/
|
||||
if (instance_count > 1) {
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(temp, &core->instances, list)
|
||||
temp->dcvs_mode = false;
|
||||
mutex_unlock(&core->lock);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int extra_buffer = 0;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inst->session_type == MSM_VIDC_ENCODER) {
|
||||
if (msm_dcvs_enc_check(inst))
|
||||
extra_buffer = DCVS_ENC_EXTRA_OUTPUT_BUFFERS;
|
||||
} else if (inst->session_type == MSM_VIDC_DECODER) {
|
||||
if (msm_dcvs_check_supported(inst))
|
||||
extra_buffer = DCVS_DEC_EXTRA_OUTPUT_BUFFERS;
|
||||
}
|
||||
return extra_buffer;
|
||||
}
|
||||
|
||||
|
||||
void msm_dcvs_enc_set_power_save_mode(struct msm_vidc_inst *inst,
|
||||
bool is_power_save_mode)
|
||||
{
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s Invalid args\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
inst->dcvs.is_power_save_mode = is_power_save_mode;
|
||||
}
|
42
drivers/media/platform/msm/vidc_3x/msm_vidc_dcvs.h
Normal file
42
drivers/media/platform/msm/vidc_3x/msm_vidc_dcvs.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2014-2015, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_VIDC_DCVS_H_
|
||||
#define _MSM_VIDC_DCVS_H_
|
||||
#include "msm_vidc_internal.h"
|
||||
|
||||
/* Low threshold for encoder dcvs */
|
||||
#define DCVS_ENC_LOW_THR 4
|
||||
/* High threshold for encoder dcvs */
|
||||
#define DCVS_ENC_HIGH_THR 9
|
||||
/* extra o/p buffers in case of encoder dcvs */
|
||||
#define DCVS_ENC_EXTRA_OUTPUT_BUFFERS 2
|
||||
/* extra o/p buffers in case of decoder dcvs */
|
||||
#define DCVS_DEC_EXTRA_OUTPUT_BUFFERS 4
|
||||
/* Default threshold to reduce the core frequency */
|
||||
#define DCVS_NOMINAL_THRESHOLD 8
|
||||
/* Default threshold to increase the core frequency */
|
||||
#define DCVS_TURBO_THRESHOLD 4
|
||||
|
||||
/* Considering one safeguard buffer */
|
||||
#define DCVS_BUFFER_SAFEGUARD (DCVS_DEC_EXTRA_OUTPUT_BUFFERS - 1)
|
||||
|
||||
void msm_dcvs_init(struct msm_vidc_inst *inst);
|
||||
void msm_dcvs_init_load(struct msm_vidc_inst *inst);
|
||||
void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst);
|
||||
void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb);
|
||||
int msm_dcvs_get_extra_buff_count(struct msm_vidc_inst *inst);
|
||||
void msm_dcvs_enc_set_power_save_mode(struct msm_vidc_inst *inst,
|
||||
bool is_power_save_mode);
|
||||
#endif
|
540
drivers/media/platform/msm/vidc_3x/msm_vidc_debug.c
Normal file
540
drivers/media/platform/msm/vidc_3x/msm_vidc_debug.c
Normal file
|
@ -0,0 +1,540 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "msm_vidc_common.h"
|
||||
#define MAX_SSR_STRING_LEN 10
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "vidc_hfi_api.h"
|
||||
|
||||
int msm_vidc_debug = VIDC_ERR | VIDC_WARN;
|
||||
int msm_vidc_debug_out = VIDC_OUT_PRINTK;
|
||||
int msm_vidc_fw_debug = 0x18;
|
||||
int msm_vidc_fw_debug_mode = 1;
|
||||
int msm_vidc_fw_low_power_mode = 1;
|
||||
int msm_vidc_hw_rsp_timeout = 1000;
|
||||
bool msm_vidc_fw_coverage = true;
|
||||
bool msm_vidc_dec_dcvs_mode = true;
|
||||
bool msm_vidc_enc_dcvs_mode = true;
|
||||
bool msm_vidc_sys_idle_indicator = true;
|
||||
int msm_vidc_firmware_unload_delay = 15000;
|
||||
bool msm_vidc_thermal_mitigation_disabled = true;
|
||||
bool msm_vidc_bitrate_clock_scaling = true;
|
||||
bool msm_vidc_debug_timeout = true;
|
||||
|
||||
#define MAX_DBG_BUF_SIZE 4096
|
||||
|
||||
#define DYNAMIC_BUF_OWNER(__binfo) ({ \
|
||||
atomic_read(&__binfo->ref_count) == 2 ? "video driver" : "firmware";\
|
||||
})
|
||||
|
||||
struct core_inst_pair {
|
||||
struct msm_vidc_core *core;
|
||||
struct msm_vidc_inst *inst;
|
||||
};
|
||||
|
||||
static u32 write_str(char *buffer,
|
||||
size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
u32 len;
|
||||
|
||||
va_start(args, fmt);
|
||||
len = vscnprintf(buffer, size, fmt, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t core_info_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct msm_vidc_core *core = file->private_data;
|
||||
struct hfi_device *hdev;
|
||||
struct hal_fw_info fw_info = { {0} };
|
||||
char *dbuf, *cur, *end;
|
||||
int i = 0, rc = 0;
|
||||
ssize_t len = 0;
|
||||
|
||||
if (!core || !core->device) {
|
||||
dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL);
|
||||
if (!dbuf) {
|
||||
dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cur = dbuf;
|
||||
end = cur + MAX_DBG_BUF_SIZE;
|
||||
hdev = core->device;
|
||||
|
||||
cur += write_str(cur, end - cur, "===============================\n");
|
||||
cur += write_str(cur, end - cur, "CORE %d: %pK\n", core->id, core);
|
||||
cur += write_str(cur, end - cur, "===============================\n");
|
||||
cur += write_str(cur, end - cur, "Core state: %d\n", core->state);
|
||||
rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info);
|
||||
if (rc) {
|
||||
dprintk(VIDC_WARN, "Failed to read FW info\n");
|
||||
goto err_fw_info;
|
||||
}
|
||||
|
||||
cur += write_str(cur, end - cur,
|
||||
"FW version : %s\n", &fw_info.version);
|
||||
cur += write_str(cur, end - cur,
|
||||
"base addr: 0x%x\n", fw_info.base_addr);
|
||||
cur += write_str(cur, end - cur,
|
||||
"register_base: 0x%x\n", fw_info.register_base);
|
||||
cur += write_str(cur, end - cur,
|
||||
"register_size: %u\n", fw_info.register_size);
|
||||
cur += write_str(cur, end - cur, "irq: %u\n", fw_info.irq);
|
||||
|
||||
err_fw_info:
|
||||
for (i = SYS_MSG_START; i < SYS_MSG_END; i++) {
|
||||
cur += write_str(cur, end - cur, "completions[%d]: %s\n", i,
|
||||
completion_done(&core->completions[SYS_MSG_INDEX(i)]) ?
|
||||
"pending" : "done");
|
||||
}
|
||||
len = simple_read_from_buffer(buf, count, ppos,
|
||||
dbuf, cur - dbuf);
|
||||
|
||||
kfree(dbuf);
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct file_operations core_info_fops = {
|
||||
.open = simple_open,
|
||||
.read = core_info_read,
|
||||
};
|
||||
|
||||
static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
unsigned long ssr_trigger_val = 0;
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core = filp->private_data;
|
||||
size_t size = MAX_SSR_STRING_LEN;
|
||||
char kbuf[MAX_SSR_STRING_LEN + 1] = {0};
|
||||
|
||||
if (!count)
|
||||
goto exit;
|
||||
|
||||
if (count < size)
|
||||
size = count;
|
||||
|
||||
if (copy_from_user(kbuf, buf, size)) {
|
||||
dprintk(VIDC_WARN, "%s User memory fault\n", __func__);
|
||||
rc = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = kstrtoul(kbuf, 0, &ssr_trigger_val);
|
||||
if (rc) {
|
||||
dprintk(VIDC_WARN, "returning error err %d\n", rc);
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
msm_vidc_trigger_ssr(core, ssr_trigger_val);
|
||||
rc = count;
|
||||
}
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct file_operations ssr_fops = {
|
||||
.open = simple_open,
|
||||
.write = trigger_ssr_write,
|
||||
};
|
||||
|
||||
struct dentry *msm_vidc_debugfs_init_drv(void)
|
||||
{
|
||||
bool ok = false;
|
||||
struct dentry *dir = NULL;
|
||||
|
||||
dir = debugfs_create_dir("msm_vidc", NULL);
|
||||
if (IS_ERR_OR_NULL(dir)) {
|
||||
dir = NULL;
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
#define __debugfs_create(__type, __name, __value) ({ \
|
||||
struct dentry *f = debugfs_create_##__type(__name, 0644, \
|
||||
dir, __value); \
|
||||
if (IS_ERR_OR_NULL(f)) { \
|
||||
dprintk(VIDC_ERR, "Failed creating debugfs file '%pd/%s'\n", \
|
||||
dir, __name); \
|
||||
f = NULL; \
|
||||
} \
|
||||
f; \
|
||||
})
|
||||
|
||||
ok =
|
||||
__debugfs_create(x32, "debug_level", &msm_vidc_debug) &&
|
||||
__debugfs_create(x32, "fw_level", &msm_vidc_fw_debug) &&
|
||||
__debugfs_create(u32, "fw_debug_mode", &msm_vidc_fw_debug_mode) &&
|
||||
__debugfs_create(bool, "fw_coverage", &msm_vidc_fw_coverage) &&
|
||||
__debugfs_create(bool, "dcvs_dec_mode", &msm_vidc_dec_dcvs_mode) &&
|
||||
__debugfs_create(bool, "dcvs_enc_mode", &msm_vidc_enc_dcvs_mode) &&
|
||||
__debugfs_create(u32, "fw_low_power_mode",
|
||||
&msm_vidc_fw_low_power_mode) &&
|
||||
__debugfs_create(u32, "debug_output", &msm_vidc_debug_out) &&
|
||||
__debugfs_create(u32, "hw_rsp_timeout", &msm_vidc_hw_rsp_timeout) &&
|
||||
__debugfs_create(bool, "sys_idle_indicator",
|
||||
&msm_vidc_sys_idle_indicator) &&
|
||||
__debugfs_create(u32, "firmware_unload_delay",
|
||||
&msm_vidc_firmware_unload_delay) &&
|
||||
__debugfs_create(bool, "disable_thermal_mitigation",
|
||||
&msm_vidc_thermal_mitigation_disabled) &&
|
||||
__debugfs_create(bool, "bitrate_clock_scaling",
|
||||
&msm_vidc_bitrate_clock_scaling) &&
|
||||
__debugfs_create(bool, "debug_timeout",
|
||||
&msm_vidc_debug_timeout);
|
||||
|
||||
#undef __debugfs_create
|
||||
|
||||
if (!ok)
|
||||
goto failed_create_dir;
|
||||
|
||||
return dir;
|
||||
|
||||
failed_create_dir:
|
||||
if (dir)
|
||||
debugfs_remove_recursive(vidc_driver->debugfs_root);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
|
||||
struct dentry *parent)
|
||||
{
|
||||
struct dentry *dir = NULL;
|
||||
char debugfs_name[MAX_DEBUGFS_NAME];
|
||||
|
||||
if (!core) {
|
||||
dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core);
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id);
|
||||
dir = debugfs_create_dir(debugfs_name, parent);
|
||||
if (!dir) {
|
||||
dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
if (!debugfs_create_file("info", 0444, dir, core, &core_info_fops)) {
|
||||
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
if (!debugfs_create_file("trigger_ssr", 0200,
|
||||
dir, core, &ssr_fops)) {
|
||||
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
failed_create_dir:
|
||||
return dir;
|
||||
}
|
||||
|
||||
static int inst_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
dprintk(VIDC_INFO, "Open inode ptr: %pK\n", inode->i_private);
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int publish_unreleased_reference(struct msm_vidc_inst *inst,
|
||||
char **dbuf, char *end)
|
||||
{
|
||||
char *cur = *dbuf;
|
||||
struct buffer_info *temp = NULL;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) {
|
||||
cur += write_str(cur, end - cur, "Pending buffer references\n");
|
||||
|
||||
mutex_lock(&inst->registeredbufs.lock);
|
||||
list_for_each_entry(temp, &inst->registeredbufs.list, list) {
|
||||
if (temp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
|
||||
!temp->inactive && atomic_read(&temp->ref_count)) {
|
||||
cur += write_str(cur, end - cur,
|
||||
"\tpending buffer: %#lx fd[0] = %d ref_count = %d held by: %s\n",
|
||||
temp->device_addr[0],
|
||||
temp->fd[0],
|
||||
atomic_read(&temp->ref_count),
|
||||
DYNAMIC_BUF_OWNER(temp));
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inst->registeredbufs.lock);
|
||||
}
|
||||
|
||||
*dbuf = cur;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void put_inst_helper(struct kref *kref)
|
||||
{
|
||||
struct msm_vidc_inst *inst = container_of(kref,
|
||||
struct msm_vidc_inst, kref);
|
||||
|
||||
msm_vidc_destroy(inst);
|
||||
}
|
||||
|
||||
static ssize_t inst_info_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct core_inst_pair *idata = file->private_data;
|
||||
struct msm_vidc_core *core;
|
||||
struct msm_vidc_inst *inst, *temp = NULL;
|
||||
char *dbuf, *cur, *end;
|
||||
int i, j;
|
||||
ssize_t len = 0;
|
||||
|
||||
if (!idata || !idata->core || !idata->inst) {
|
||||
dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
core = idata->core;
|
||||
inst = idata->inst;
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
list_for_each_entry(temp, &core->instances, list) {
|
||||
if (temp == inst)
|
||||
break;
|
||||
}
|
||||
inst = ((temp == inst) && kref_get_unless_zero(&inst->kref)) ?
|
||||
inst : NULL;
|
||||
mutex_unlock(&core->lock);
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "%s: Instance has become obsolete", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL);
|
||||
if (!dbuf) {
|
||||
dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__);
|
||||
len = -ENOMEM;
|
||||
goto failed_alloc;
|
||||
}
|
||||
cur = dbuf;
|
||||
end = cur + MAX_DBG_BUF_SIZE;
|
||||
|
||||
cur += write_str(cur, end - cur, "==============================\n");
|
||||
cur += write_str(cur, end - cur, "INSTANCE: %pK (%s)\n", inst,
|
||||
inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder");
|
||||
cur += write_str(cur, end - cur, "==============================\n");
|
||||
cur += write_str(cur, end - cur, "core: %pK\n", inst->core);
|
||||
cur += write_str(cur, end - cur, "height: %d\n",
|
||||
inst->prop.height[CAPTURE_PORT]);
|
||||
cur += write_str(cur, end - cur, "width: %d\n",
|
||||
inst->prop.width[CAPTURE_PORT]);
|
||||
cur += write_str(cur, end - cur, "fps: %d\n", inst->prop.fps);
|
||||
cur += write_str(cur, end - cur, "state: %d\n", inst->state);
|
||||
cur += write_str(cur, end - cur, "secure: %d\n",
|
||||
!!(inst->flags & VIDC_SECURE));
|
||||
cur += write_str(cur, end - cur, "-----------Formats-------------\n");
|
||||
for (i = 0; i < MAX_PORT_NUM; i++) {
|
||||
cur += write_str(cur, end - cur, "capability: %s\n",
|
||||
i == OUTPUT_PORT ? "Output" : "Capture");
|
||||
cur += write_str(cur, end - cur, "name : %s\n",
|
||||
inst->fmts[i].name);
|
||||
cur += write_str(cur, end - cur, "planes : %d\n",
|
||||
inst->fmts[i].num_planes);
|
||||
cur += write_str(cur, end - cur,
|
||||
"type: %s\n", inst->fmts[i].type == OUTPUT_PORT ?
|
||||
"Output" : "Capture");
|
||||
|
||||
switch (inst->buffer_mode_set[i]) {
|
||||
case HAL_BUFFER_MODE_STATIC:
|
||||
cur += write_str(cur, end - cur,
|
||||
"buffer mode : %s\n", "static");
|
||||
break;
|
||||
case HAL_BUFFER_MODE_RING:
|
||||
cur += write_str(cur, end - cur,
|
||||
"buffer mode : %s\n", "ring");
|
||||
break;
|
||||
case HAL_BUFFER_MODE_DYNAMIC:
|
||||
cur += write_str(cur, end - cur,
|
||||
"buffer mode : %s\n", "dynamic");
|
||||
break;
|
||||
default:
|
||||
cur += write_str(cur, end - cur,
|
||||
"buffer mode : unsupported\n");
|
||||
}
|
||||
|
||||
cur += write_str(cur, end - cur, "count: %u\n",
|
||||
inst->bufq[i].vb2_bufq.num_buffers);
|
||||
|
||||
for (j = 0; j < inst->fmts[i].num_planes; j++)
|
||||
cur += write_str(cur, end - cur,
|
||||
"size for plane %d: %u\n", j,
|
||||
inst->bufq[i].plane_sizes[j]);
|
||||
|
||||
if (i < MAX_PORT_NUM - 1)
|
||||
cur += write_str(cur, end - cur, "\n");
|
||||
}
|
||||
cur += write_str(cur, end - cur, "-------------------------------\n");
|
||||
for (i = SESSION_MSG_START; i < SESSION_MSG_END; i++) {
|
||||
cur += write_str(cur, end - cur, "completions[%d]: %s\n", i,
|
||||
completion_done(&inst->completions[SESSION_MSG_INDEX(i)]) ?
|
||||
"pending" : "done");
|
||||
}
|
||||
|
||||
cur += write_str(cur, end - cur, "ETB Count: %d\n", inst->count.etb);
|
||||
cur += write_str(cur, end - cur, "EBD Count: %d\n", inst->count.ebd);
|
||||
cur += write_str(cur, end - cur, "FTB Count: %d\n", inst->count.ftb);
|
||||
cur += write_str(cur, end - cur, "FBD Count: %d\n", inst->count.fbd);
|
||||
|
||||
publish_unreleased_reference(inst, &cur, end);
|
||||
len = simple_read_from_buffer(buf, count, ppos,
|
||||
dbuf, cur - dbuf);
|
||||
|
||||
kfree(dbuf);
|
||||
failed_alloc:
|
||||
kref_put(&inst->kref, put_inst_helper);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int inst_info_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
dprintk(VIDC_INFO, "Release inode ptr: %pK\n", inode->i_private);
|
||||
file->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations inst_info_fops = {
|
||||
.open = inst_info_open,
|
||||
.read = inst_info_read,
|
||||
.release = inst_info_release,
|
||||
};
|
||||
|
||||
struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
|
||||
struct dentry *parent)
|
||||
{
|
||||
struct dentry *dir = NULL, *info = NULL;
|
||||
char debugfs_name[MAX_DEBUGFS_NAME];
|
||||
struct core_inst_pair *idata = NULL;
|
||||
|
||||
if (!inst) {
|
||||
dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst);
|
||||
goto exit;
|
||||
}
|
||||
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst);
|
||||
|
||||
idata = kzalloc(sizeof(struct core_inst_pair), GFP_KERNEL);
|
||||
if (!idata) {
|
||||
dprintk(VIDC_ERR, "%s: Allocation failed!\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
idata->core = inst->core;
|
||||
idata->inst = inst;
|
||||
|
||||
dir = debugfs_create_dir(debugfs_name, parent);
|
||||
if (!dir) {
|
||||
dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
info = debugfs_create_file("info", 0444, dir,
|
||||
idata, &inst_info_fops);
|
||||
if (!info) {
|
||||
dprintk(VIDC_ERR, "debugfs_create_file: fail\n");
|
||||
goto failed_create_file;
|
||||
}
|
||||
|
||||
dir->d_inode->i_private = info->d_inode->i_private;
|
||||
inst->debug.pdata[FRAME_PROCESSING].sampling = true;
|
||||
return dir;
|
||||
|
||||
failed_create_file:
|
||||
debugfs_remove_recursive(dir);
|
||||
dir = NULL;
|
||||
failed_create_dir:
|
||||
kfree(idata);
|
||||
exit:
|
||||
return dir;
|
||||
}
|
||||
|
||||
void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct dentry *dentry = NULL;
|
||||
|
||||
if (!inst || !inst->debugfs_root)
|
||||
return;
|
||||
|
||||
dentry = inst->debugfs_root;
|
||||
if (dentry->d_inode) {
|
||||
dprintk(VIDC_INFO, "Destroy %pK\n", dentry->d_inode->i_private);
|
||||
kfree(dentry->d_inode->i_private);
|
||||
dentry->d_inode->i_private = NULL;
|
||||
}
|
||||
debugfs_remove_recursive(dentry);
|
||||
inst->debugfs_root = NULL;
|
||||
}
|
||||
|
||||
void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_debugfs_event e)
|
||||
{
|
||||
struct msm_vidc_debug *d = &inst->debug;
|
||||
char a[64] = "Frame processing";
|
||||
|
||||
switch (e) {
|
||||
case MSM_VIDC_DEBUGFS_EVENT_ETB:
|
||||
mutex_lock(&inst->lock);
|
||||
inst->count.etb++;
|
||||
mutex_unlock(&inst->lock);
|
||||
if (inst->count.ebd && inst->count.ftb > inst->count.fbd) {
|
||||
d->pdata[FRAME_PROCESSING].name[0] = '\0';
|
||||
tic(inst, FRAME_PROCESSING, a);
|
||||
}
|
||||
break;
|
||||
case MSM_VIDC_DEBUGFS_EVENT_EBD:
|
||||
mutex_lock(&inst->lock);
|
||||
inst->count.ebd++;
|
||||
mutex_unlock(&inst->lock);
|
||||
if (inst->count.ebd && inst->count.ebd == inst->count.etb) {
|
||||
toc(inst, FRAME_PROCESSING);
|
||||
dprintk(VIDC_PROF, "EBD: FW needs input buffers\n");
|
||||
}
|
||||
if (inst->count.ftb == inst->count.fbd)
|
||||
dprintk(VIDC_PROF, "EBD: FW needs output buffers\n");
|
||||
break;
|
||||
case MSM_VIDC_DEBUGFS_EVENT_FTB: {
|
||||
inst->count.ftb++;
|
||||
if (inst->count.ebd && inst->count.etb > inst->count.ebd) {
|
||||
d->pdata[FRAME_PROCESSING].name[0] = '\0';
|
||||
tic(inst, FRAME_PROCESSING, a);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSM_VIDC_DEBUGFS_EVENT_FBD:
|
||||
inst->debug.samples++;
|
||||
if (inst->count.ebd && inst->count.fbd == inst->count.ftb) {
|
||||
toc(inst, FRAME_PROCESSING);
|
||||
dprintk(VIDC_PROF, "FBD: FW needs output buffers\n");
|
||||
}
|
||||
if (inst->count.etb == inst->count.ebd)
|
||||
dprintk(VIDC_PROF, "FBD: FW needs input buffers\n");
|
||||
break;
|
||||
default:
|
||||
dprintk(VIDC_ERR, "Invalid state in debugfs: %d\n", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
178
drivers/media/platform/msm/vidc_3x/msm_vidc_debug.h
Normal file
178
drivers/media/platform/msm/vidc_3x/msm_vidc_debug.h
Normal file
|
@ -0,0 +1,178 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2015, 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __MSM_VIDC_DEBUG__
|
||||
#define __MSM_VIDC_DEBUG__
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include "msm_vidc_internal.h"
|
||||
#include "trace/events/msm_vidc.h"
|
||||
|
||||
#ifndef VIDC_DBG_LABEL
|
||||
#define VIDC_DBG_LABEL "msm_vidc"
|
||||
#endif
|
||||
|
||||
#define VIDC_DBG_TAG VIDC_DBG_LABEL ": %4s: "
|
||||
#define VIDC_DBG_WARN_ENABLE (msm_vidc_debug & VIDC_INFO)
|
||||
|
||||
/* To enable messages OR these values and
|
||||
* echo the result to debugfs file.
|
||||
*
|
||||
* To enable all messages set debug_level = 0x101F
|
||||
*/
|
||||
|
||||
enum vidc_msg_prio {
|
||||
VIDC_ERR = 0x0001,
|
||||
VIDC_WARN = 0x0002,
|
||||
VIDC_INFO = 0x0004,
|
||||
VIDC_DBG = 0x0008,
|
||||
VIDC_PROF = 0x0010,
|
||||
VIDC_PKT = 0x0020,
|
||||
VIDC_FW = 0x1000,
|
||||
};
|
||||
|
||||
enum vidc_msg_out {
|
||||
VIDC_OUT_PRINTK = 0,
|
||||
VIDC_OUT_FTRACE,
|
||||
};
|
||||
|
||||
enum msm_vidc_debugfs_event {
|
||||
MSM_VIDC_DEBUGFS_EVENT_ETB,
|
||||
MSM_VIDC_DEBUGFS_EVENT_EBD,
|
||||
MSM_VIDC_DEBUGFS_EVENT_FTB,
|
||||
MSM_VIDC_DEBUGFS_EVENT_FBD,
|
||||
};
|
||||
|
||||
extern int msm_vidc_debug;
|
||||
extern int msm_vidc_debug_out;
|
||||
extern int msm_vidc_fw_debug;
|
||||
extern int msm_vidc_fw_debug_mode;
|
||||
extern int msm_vidc_fw_low_power_mode;
|
||||
extern int msm_vidc_hw_rsp_timeout;
|
||||
extern bool msm_vidc_fw_coverage;
|
||||
extern int msm_vidc_vpe_csc_601_to_709;
|
||||
extern bool msm_vidc_dec_dcvs_mode;
|
||||
extern bool msm_vidc_enc_dcvs_mode;
|
||||
extern bool msm_vidc_sys_idle_indicator;
|
||||
extern int msm_vidc_firmware_unload_delay;
|
||||
extern bool msm_vidc_thermal_mitigation_disabled;
|
||||
extern bool msm_vidc_bitrate_clock_scaling;
|
||||
extern bool msm_vidc_debug_timeout;
|
||||
|
||||
static inline char *VIDC_MSG_PRIO2STRING(int __level)
|
||||
{
|
||||
char *__str;
|
||||
|
||||
switch (__level) {
|
||||
case VIDC_ERR:
|
||||
__str = "err";
|
||||
break;
|
||||
case VIDC_WARN:
|
||||
__str = "warn";
|
||||
break;
|
||||
case VIDC_INFO:
|
||||
__str = "info";
|
||||
break;
|
||||
case VIDC_DBG:
|
||||
__str = "dbg";
|
||||
break;
|
||||
case VIDC_PROF:
|
||||
__str = "prof";
|
||||
break;
|
||||
case VIDC_PKT:
|
||||
__str = "pkt";
|
||||
break;
|
||||
case VIDC_FW:
|
||||
__str = "fw";
|
||||
break;
|
||||
default:
|
||||
__str = "????";
|
||||
break;
|
||||
}
|
||||
return __str;
|
||||
}
|
||||
|
||||
#define dprintk(__level, __fmt, arg...) \
|
||||
do { \
|
||||
if (msm_vidc_debug & __level) { \
|
||||
if (msm_vidc_debug_out == VIDC_OUT_PRINTK) { \
|
||||
pr_info(VIDC_DBG_TAG __fmt, \
|
||||
VIDC_MSG_PRIO2STRING(__level), \
|
||||
## arg); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct dentry *msm_vidc_debugfs_init_drv(void);
|
||||
struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core,
|
||||
struct dentry *parent);
|
||||
struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
|
||||
struct dentry *parent);
|
||||
void msm_vidc_debugfs_deinit_inst(struct msm_vidc_inst *inst);
|
||||
void msm_vidc_debugfs_update(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_debugfs_event e);
|
||||
|
||||
static inline void tic(struct msm_vidc_inst *i, enum profiling_points p,
|
||||
char *b)
|
||||
{
|
||||
struct timeval __ddl_tv;
|
||||
|
||||
if (!i->debug.pdata[p].name[0])
|
||||
memcpy(i->debug.pdata[p].name, b, 64);
|
||||
if ((msm_vidc_debug & VIDC_PROF) &&
|
||||
i->debug.pdata[p].sampling) {
|
||||
do_gettimeofday(&__ddl_tv);
|
||||
i->debug.pdata[p].start =
|
||||
(__ddl_tv.tv_sec * 1000) + (__ddl_tv.tv_usec / 1000);
|
||||
i->debug.pdata[p].sampling = false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void toc(struct msm_vidc_inst *i, enum profiling_points p)
|
||||
{
|
||||
struct timeval __ddl_tv;
|
||||
|
||||
if ((msm_vidc_debug & VIDC_PROF) &&
|
||||
!i->debug.pdata[p].sampling) {
|
||||
do_gettimeofday(&__ddl_tv);
|
||||
i->debug.pdata[p].stop = (__ddl_tv.tv_sec * 1000)
|
||||
+ (__ddl_tv.tv_usec / 1000);
|
||||
i->debug.pdata[p].cumulative += i->debug.pdata[p].stop -
|
||||
i->debug.pdata[p].start;
|
||||
i->debug.pdata[p].sampling = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void show_stats(struct msm_vidc_inst *i)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; x < MAX_PROFILING_POINTS; x++) {
|
||||
if (i->debug.pdata[x].name[0] &&
|
||||
(msm_vidc_debug & VIDC_PROF)) {
|
||||
if (i->debug.samples) {
|
||||
dprintk(VIDC_PROF, "%s averaged %d ms/sample\n",
|
||||
i->debug.pdata[x].name,
|
||||
i->debug.pdata[x].cumulative /
|
||||
i->debug.samples);
|
||||
}
|
||||
|
||||
dprintk(VIDC_PROF, "%s Samples: %d\n",
|
||||
i->debug.pdata[x].name,
|
||||
i->debug.samples);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
413
drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h
Normal file
413
drivers/media/platform/msm/vidc_3x/msm_vidc_internal.h
Normal file
|
@ -0,0 +1,413 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_VIDC_INTERNAL_H_
|
||||
#define _MSM_VIDC_INTERNAL_H_
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/msm-bus.h>
|
||||
#include <linux/msm-bus-board.h>
|
||||
#include <linux/kref.h>
|
||||
#include <media/v4l2-dev.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <media/videobuf2-core.h>
|
||||
#include <media/videobuf2-v4l2.h>
|
||||
#include <media/msm_vidc.h>
|
||||
#include <media/msm_media_info.h>
|
||||
|
||||
#include "vidc_hfi_api.h"
|
||||
|
||||
#define MSM_VIDC_DRV_NAME "msm_vidc_driver"
|
||||
//#define MSM_VIDC_VERSION KERNEL_VERSION(0, 0, 1)
|
||||
#define MAX_DEBUGFS_NAME 50
|
||||
#define DEFAULT_TIMEOUT 3
|
||||
#define DEFAULT_HEIGHT 1088
|
||||
#define DEFAULT_WIDTH 1920
|
||||
#define MIN_SUPPORTED_WIDTH 32
|
||||
#define MIN_SUPPORTED_HEIGHT 32
|
||||
#define DEFAULT_FPS 15
|
||||
|
||||
/* Maintains the number of FTB's between each FBD over a window */
|
||||
#define DCVS_FTB_WINDOW 32
|
||||
|
||||
#define V4L2_EVENT_VIDC_BASE 10
|
||||
|
||||
#define SYS_MSG_START HAL_SYS_INIT_DONE
|
||||
#define SYS_MSG_END HAL_SYS_ERROR
|
||||
#define SESSION_MSG_START HAL_SESSION_EVENT_CHANGE
|
||||
#define SESSION_MSG_END HAL_SESSION_ERROR
|
||||
#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START)
|
||||
#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
|
||||
|
||||
|
||||
#define MAX_NAME_LENGTH 64
|
||||
|
||||
#define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
|
||||
|
||||
#define NUM_MBS_PER_SEC(__height, __width, __fps) \
|
||||
(NUM_MBS_PER_FRAME(__height, __width) * __fps)
|
||||
|
||||
#define NUM_MBS_PER_FRAME(__height, __width) \
|
||||
((ALIGN(__height, 16) / 16) * (ALIGN(__width, 16) / 16))
|
||||
|
||||
enum vidc_ports {
|
||||
OUTPUT_PORT,
|
||||
CAPTURE_PORT,
|
||||
MAX_PORT_NUM
|
||||
};
|
||||
|
||||
enum vidc_core_state {
|
||||
VIDC_CORE_UNINIT = 0,
|
||||
VIDC_CORE_INIT,
|
||||
VIDC_CORE_INIT_DONE,
|
||||
VIDC_CORE_INVALID
|
||||
};
|
||||
|
||||
/* Do not change the enum values unless
|
||||
* you know what you are doing
|
||||
*/
|
||||
enum instance_state {
|
||||
MSM_VIDC_CORE_UNINIT_DONE = 0x0001,
|
||||
MSM_VIDC_CORE_INIT,
|
||||
MSM_VIDC_CORE_INIT_DONE,
|
||||
MSM_VIDC_OPEN,
|
||||
MSM_VIDC_OPEN_DONE,
|
||||
MSM_VIDC_LOAD_RESOURCES,
|
||||
MSM_VIDC_LOAD_RESOURCES_DONE,
|
||||
MSM_VIDC_START,
|
||||
MSM_VIDC_START_DONE,
|
||||
MSM_VIDC_STOP,
|
||||
MSM_VIDC_STOP_DONE,
|
||||
MSM_VIDC_RELEASE_RESOURCES,
|
||||
MSM_VIDC_RELEASE_RESOURCES_DONE,
|
||||
MSM_VIDC_CLOSE,
|
||||
MSM_VIDC_CLOSE_DONE,
|
||||
MSM_VIDC_CORE_UNINIT,
|
||||
MSM_VIDC_CORE_INVALID
|
||||
};
|
||||
|
||||
struct buf_info {
|
||||
struct list_head list;
|
||||
struct vb2_buffer *buf;
|
||||
};
|
||||
|
||||
struct msm_vidc_list {
|
||||
struct list_head list;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static inline void INIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist)
|
||||
{
|
||||
mutex_init(&mlist->lock);
|
||||
INIT_LIST_HEAD(&mlist->list);
|
||||
}
|
||||
|
||||
static inline void DEINIT_MSM_VIDC_LIST(struct msm_vidc_list *mlist)
|
||||
{
|
||||
mutex_destroy(&mlist->lock);
|
||||
}
|
||||
|
||||
enum buffer_owner {
|
||||
DRIVER,
|
||||
FIRMWARE,
|
||||
CLIENT,
|
||||
MAX_OWNER
|
||||
};
|
||||
|
||||
struct eos_buf {
|
||||
struct list_head list;
|
||||
struct msm_smem smem;
|
||||
};
|
||||
|
||||
struct internal_buf {
|
||||
struct list_head list;
|
||||
enum hal_buffer buffer_type;
|
||||
struct msm_smem smem;
|
||||
enum buffer_owner buffer_ownership;
|
||||
};
|
||||
|
||||
struct msm_vidc_format {
|
||||
char name[MAX_NAME_LENGTH];
|
||||
u8 description[32];
|
||||
u32 fourcc;
|
||||
int num_planes;
|
||||
int type;
|
||||
u32 (*get_frame_size)(int plane, u32 height, u32 width);
|
||||
};
|
||||
|
||||
struct msm_vidc_drv {
|
||||
struct mutex lock;
|
||||
struct list_head cores;
|
||||
int num_cores;
|
||||
struct dentry *debugfs_root;
|
||||
int thermal_level;
|
||||
u32 platform_version;
|
||||
u32 capability_version;
|
||||
};
|
||||
|
||||
struct msm_video_device {
|
||||
int type;
|
||||
struct video_device vdev;
|
||||
};
|
||||
|
||||
struct session_prop {
|
||||
u32 width[MAX_PORT_NUM];
|
||||
u32 height[MAX_PORT_NUM];
|
||||
u32 fps;
|
||||
u32 bitrate;
|
||||
u32 operating_rate;
|
||||
};
|
||||
|
||||
struct buf_queue {
|
||||
struct vb2_queue vb2_bufq;
|
||||
struct mutex lock;
|
||||
unsigned int plane_sizes[VB2_MAX_PLANES];
|
||||
int num_planes;
|
||||
};
|
||||
|
||||
|
||||
enum profiling_points {
|
||||
SYS_INIT = 0,
|
||||
SESSION_INIT,
|
||||
LOAD_RESOURCES,
|
||||
FRAME_PROCESSING,
|
||||
FW_IDLE,
|
||||
MAX_PROFILING_POINTS,
|
||||
};
|
||||
|
||||
struct buf_count {
|
||||
int etb;
|
||||
int ftb;
|
||||
int fbd;
|
||||
int ebd;
|
||||
};
|
||||
|
||||
struct dcvs_stats {
|
||||
int num_ftb[DCVS_FTB_WINDOW];
|
||||
bool transition_turbo;
|
||||
int ftb_index;
|
||||
int ftb_counter;
|
||||
bool prev_freq_lowered;
|
||||
bool prev_freq_increased;
|
||||
int threshold_disp_buf_high;
|
||||
int threshold_disp_buf_low;
|
||||
int load;
|
||||
int load_low;
|
||||
int load_high;
|
||||
int min_threshold;
|
||||
int max_threshold;
|
||||
bool is_clock_scaled;
|
||||
int etb_counter;
|
||||
bool is_power_save_mode;
|
||||
u32 supported_codecs;
|
||||
};
|
||||
|
||||
struct profile_data {
|
||||
int start;
|
||||
int stop;
|
||||
int cumulative;
|
||||
char name[64];
|
||||
int sampling;
|
||||
int average;
|
||||
};
|
||||
|
||||
struct msm_vidc_debug {
|
||||
struct profile_data pdata[MAX_PROFILING_POINTS];
|
||||
int profile;
|
||||
int samples;
|
||||
};
|
||||
|
||||
enum msm_vidc_modes {
|
||||
VIDC_SECURE = BIT(0),
|
||||
VIDC_TURBO = BIT(1),
|
||||
VIDC_THUMBNAIL = BIT(2),
|
||||
VIDC_LOW_POWER = BIT(3),
|
||||
VIDC_REALTIME = BIT(4),
|
||||
};
|
||||
|
||||
struct msm_vidc_core {
|
||||
struct list_head list;
|
||||
struct mutex lock;
|
||||
int id;
|
||||
struct hfi_device *device;
|
||||
struct msm_video_device vdev[MSM_VIDC_MAX_DEVICES];
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct list_head instances;
|
||||
struct dentry *debugfs_root;
|
||||
enum vidc_core_state state;
|
||||
struct completion completions[SYS_MSG_END - SYS_MSG_START + 1];
|
||||
enum msm_vidc_hfi_type hfi_type;
|
||||
struct msm_vidc_platform_resources resources;
|
||||
u32 enc_codec_supported;
|
||||
u32 dec_codec_supported;
|
||||
u32 codec_count;
|
||||
struct msm_vidc_capability *capabilities;
|
||||
struct delayed_work fw_unload_work;
|
||||
bool smmu_fault_handled;
|
||||
};
|
||||
|
||||
struct msm_vidc_inst {
|
||||
struct list_head list;
|
||||
struct mutex sync_lock, lock;
|
||||
struct msm_vidc_core *core;
|
||||
enum session_type session_type;
|
||||
void *session;
|
||||
struct session_prop prop;
|
||||
enum instance_state state;
|
||||
struct msm_vidc_format fmts[MAX_PORT_NUM];
|
||||
struct buf_queue bufq[MAX_PORT_NUM];
|
||||
struct msm_vidc_list pendingq;
|
||||
struct msm_vidc_list scratchbufs;
|
||||
struct msm_vidc_list persistbufs;
|
||||
struct msm_vidc_list pending_getpropq;
|
||||
struct msm_vidc_list outputbufs;
|
||||
struct msm_vidc_list eosbufs;
|
||||
struct msm_vidc_list registeredbufs;
|
||||
struct buffer_requirements buff_req;
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
|
||||
struct v4l2_ctrl **cluster;
|
||||
struct v4l2_fh event_handler;
|
||||
struct msm_smem *extradata_handle;
|
||||
bool in_reconfig;
|
||||
u32 reconfig_width;
|
||||
u32 reconfig_height;
|
||||
u32 seqchanged_count;
|
||||
struct dentry *debugfs_root;
|
||||
void *priv;
|
||||
struct msm_vidc_debug debug;
|
||||
struct buf_count count;
|
||||
struct dcvs_stats dcvs;
|
||||
enum msm_vidc_modes flags;
|
||||
struct msm_vidc_capability capability;
|
||||
u32 buffer_size_limit;
|
||||
enum buffer_mode_type buffer_mode_set[MAX_PORT_NUM];
|
||||
atomic_t seq_hdr_reqs;
|
||||
struct v4l2_ctrl **ctrls;
|
||||
bool dcvs_mode;
|
||||
enum msm_vidc_pixel_depth bit_depth;
|
||||
struct kref kref;
|
||||
unsigned long instant_bitrate;
|
||||
u32 buffers_held_in_driver;
|
||||
atomic_t in_flush;
|
||||
u32 pic_struct;
|
||||
u32 colour_space;
|
||||
};
|
||||
|
||||
extern struct msm_vidc_drv *vidc_driver;
|
||||
|
||||
struct msm_vidc_ctrl_cluster {
|
||||
struct v4l2_ctrl **cluster;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct msm_vidc_ctrl {
|
||||
u32 id;
|
||||
char name[MAX_NAME_LENGTH];
|
||||
enum v4l2_ctrl_type type;
|
||||
s32 minimum;
|
||||
s32 maximum;
|
||||
s32 default_value;
|
||||
u32 step;
|
||||
u64 menu_skip_mask;
|
||||
u32 flags;
|
||||
const char * const *qmenu;
|
||||
};
|
||||
|
||||
void handle_cmd_response(enum hal_command_response cmd, void *data);
|
||||
int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
|
||||
enum hal_ssr_trigger_type type);
|
||||
int msm_vidc_check_session_supported(struct msm_vidc_inst *inst);
|
||||
int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst);
|
||||
void msm_vidc_queue_v4l2_event(struct msm_vidc_inst *inst, int event_type);
|
||||
|
||||
struct crop_info {
|
||||
u32 nLeft;
|
||||
u32 nTop;
|
||||
u32 nWidth;
|
||||
u32 nHeight;
|
||||
u32 width_height[MAX_PORT_NUM];
|
||||
};
|
||||
|
||||
struct buffer_info {
|
||||
struct list_head list;
|
||||
int type;
|
||||
int num_planes;
|
||||
int fd[VIDEO_MAX_PLANES];
|
||||
int buff_off[VIDEO_MAX_PLANES];
|
||||
int size[VIDEO_MAX_PLANES];
|
||||
unsigned long uvaddr[VIDEO_MAX_PLANES];
|
||||
phys_addr_t device_addr[VIDEO_MAX_PLANES];
|
||||
struct msm_smem smem[VIDEO_MAX_PLANES];
|
||||
enum v4l2_memory memory;
|
||||
u32 v4l2_index;
|
||||
bool pending_deletion;
|
||||
atomic_t ref_count;
|
||||
bool dequeued;
|
||||
bool inactive;
|
||||
bool mapped[VIDEO_MAX_PLANES];
|
||||
int same_fd_ref[VIDEO_MAX_PLANES];
|
||||
struct timeval timestamp;
|
||||
struct crop_info crop_data;
|
||||
};
|
||||
|
||||
struct buffer_info *device_to_uvaddr(struct msm_vidc_list *buf_list,
|
||||
phys_addr_t device_addr);
|
||||
int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo);
|
||||
int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo);
|
||||
|
||||
int qbuf_cache_operations(struct msm_vidc_inst *inst,
|
||||
struct buffer_info *binfo);
|
||||
int dqbuf_cache_operations(struct msm_vidc_inst *inst,
|
||||
struct v4l2_buffer *b,
|
||||
struct buffer_info *binfo);
|
||||
int qbuf_dynamic_buf(struct msm_vidc_inst *inst,
|
||||
struct buffer_info *binfo);
|
||||
int unmap_and_deregister_buf(struct msm_vidc_inst *inst,
|
||||
struct buffer_info *binfo);
|
||||
|
||||
void msm_comm_handle_thermal_event(void);
|
||||
int msm_smem_alloc(size_t size, u32 align, u32 flags,
|
||||
enum hal_buffer buffer_type, int map_kernel,
|
||||
void *res, u32 session_type, struct msm_smem *smem);
|
||||
int msm_smem_free(struct msm_smem *mem);
|
||||
int msm_smem_cache_operations(struct dma_buf *dbuf,
|
||||
enum smem_cache_ops, unsigned long offset, unsigned long size);
|
||||
struct context_bank_info *msm_smem_get_context_bank(u32 session_type,
|
||||
bool is_secure, struct msm_vidc_platform_resources *res,
|
||||
enum hal_buffer buffer_type);
|
||||
int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem);
|
||||
int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem);
|
||||
struct dma_buf *msm_smem_get_dma_buf(int fd);
|
||||
void msm_smem_put_dma_buf(void *dma_buf);
|
||||
bool msm_smem_compare_buffers(int fd, void *dma_buf);
|
||||
struct msm_smem *msm_smem_user_to_kernel(struct msm_vidc_inst *inst,
|
||||
int fd, u32 offset,
|
||||
u32 size, enum hal_buffer buffer_type);
|
||||
|
||||
void msm_vidc_fw_unload_handler(struct work_struct *work);
|
||||
/* XXX: normally should be in msm_vidc.h, but that's meant for public APIs,
|
||||
* whereas this is private
|
||||
*/
|
||||
int msm_vidc_destroy(struct msm_vidc_inst *inst);
|
||||
#endif
|
1617
drivers/media/platform/msm/vidc_3x/msm_vidc_res_parse.c
Normal file
1617
drivers/media/platform/msm/vidc_3x/msm_vidc_res_parse.c
Normal file
File diff suppressed because it is too large
Load diff
35
drivers/media/platform/msm/vidc_3x/msm_vidc_res_parse.h
Normal file
35
drivers/media/platform/msm/vidc_3x/msm_vidc_res_parse.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2016, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef DT_PARSE
|
||||
#define DT_PARSE
|
||||
#include <linux/of.h>
|
||||
#include "msm_vidc_resources.h"
|
||||
void msm_vidc_free_platform_resources(
|
||||
struct msm_vidc_platform_resources *res);
|
||||
|
||||
int read_hfi_type(struct platform_device *pdev);
|
||||
|
||||
int read_platform_resources_from_dt(
|
||||
struct msm_vidc_platform_resources *res);
|
||||
|
||||
int read_context_bank_resources_from_dt(struct platform_device *pdev);
|
||||
|
||||
int read_bus_resources_from_dt(struct platform_device *pdev);
|
||||
|
||||
int msm_vidc_load_u32_table(struct platform_device *pdev,
|
||||
struct device_node *of_node, char *table_name, int struct_size,
|
||||
u32 **table, u32 *num_elements);
|
||||
|
||||
#endif
|
202
drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h
Normal file
202
drivers/media/platform/msm/vidc_3x/msm_vidc_resources.h
Normal file
|
@ -0,0 +1,202 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __MSM_VIDC_RESOURCES_H__
|
||||
#define __MSM_VIDC_RESOURCES_H__
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <media/msm_vidc.h>
|
||||
#define MAX_BUFFER_TYPES 32
|
||||
|
||||
struct version_table {
|
||||
u32 version_mask;
|
||||
u32 version_shift;
|
||||
};
|
||||
|
||||
struct load_freq_table {
|
||||
u32 load;
|
||||
u32 freq;
|
||||
u32 supported_codecs;
|
||||
};
|
||||
|
||||
struct dcvs_table {
|
||||
u32 load;
|
||||
u32 load_low;
|
||||
u32 load_high;
|
||||
u32 supported_codecs;
|
||||
};
|
||||
|
||||
struct dcvs_limit {
|
||||
u32 min_mbpf;
|
||||
u32 fps;
|
||||
};
|
||||
|
||||
struct imem_ab_table {
|
||||
u32 core_freq;
|
||||
u32 imem_ab;
|
||||
};
|
||||
|
||||
struct reg_value_pair {
|
||||
u32 reg;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct reg_set {
|
||||
struct reg_value_pair *reg_tbl;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct addr_range {
|
||||
u32 start;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct addr_set {
|
||||
struct addr_range *addr_tbl;
|
||||
int count;
|
||||
};
|
||||
|
||||
struct context_bank_info {
|
||||
struct list_head list;
|
||||
const char *name;
|
||||
u32 buffer_type;
|
||||
bool is_secure;
|
||||
struct addr_range addr_range;
|
||||
struct device *dev;
|
||||
struct iommu_domain *domain;
|
||||
};
|
||||
|
||||
struct buffer_usage_table {
|
||||
u32 buffer_type;
|
||||
u32 tz_usage;
|
||||
};
|
||||
|
||||
struct buffer_usage_set {
|
||||
struct buffer_usage_table *buffer_usage_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct regulator_info {
|
||||
struct regulator *regulator;
|
||||
bool has_hw_power_collapse;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct regulator_set {
|
||||
struct regulator_info *regulator_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct clock_info {
|
||||
const char *name;
|
||||
struct clk *clk;
|
||||
struct load_freq_table *load_freq_tbl;
|
||||
u32 count;
|
||||
bool has_scaling;
|
||||
};
|
||||
|
||||
struct clock_set {
|
||||
struct clock_info *clock_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct bus_info {
|
||||
char *name;
|
||||
int master;
|
||||
int slave;
|
||||
unsigned int range[2];
|
||||
struct device *dev;
|
||||
struct msm_bus_client_handle *client;
|
||||
bool is_prfm_gov_used;
|
||||
const char *mode;
|
||||
};
|
||||
|
||||
struct bus_set {
|
||||
struct bus_info *bus_tbl;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
enum imem_type {
|
||||
IMEM_NONE,
|
||||
IMEM_OCMEM,
|
||||
IMEM_VMEM,
|
||||
IMEM_MAX,
|
||||
};
|
||||
|
||||
struct allowed_clock_rates_table {
|
||||
u32 clock_rate;
|
||||
};
|
||||
|
||||
struct clock_profile_entry {
|
||||
u32 codec_mask;
|
||||
u32 cycles;
|
||||
u32 low_power_factor;
|
||||
};
|
||||
|
||||
struct clock_freq_table {
|
||||
struct clock_profile_entry *clk_prof_entries;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct msm_vidc_platform_resources {
|
||||
phys_addr_t firmware_base;
|
||||
phys_addr_t register_base;
|
||||
uint32_t register_size;
|
||||
uint32_t irq;
|
||||
struct version_table *pf_ver_tbl;
|
||||
struct version_table *pf_cap_tbl;
|
||||
struct version_table *pf_speedbin_tbl;
|
||||
struct allowed_clock_rates_table *allowed_clks_tbl;
|
||||
u32 allowed_clks_tbl_size;
|
||||
struct clock_freq_table clock_freq_tbl;
|
||||
struct load_freq_table *load_freq_tbl;
|
||||
uint32_t load_freq_tbl_size;
|
||||
struct dcvs_table *dcvs_tbl;
|
||||
uint32_t dcvs_tbl_size;
|
||||
struct dcvs_limit *dcvs_limit;
|
||||
struct imem_ab_table *imem_ab_tbl;
|
||||
u32 imem_ab_tbl_size;
|
||||
struct reg_set reg_set;
|
||||
struct addr_set qdss_addr_set;
|
||||
struct buffer_usage_set buffer_usage_set;
|
||||
uint32_t imem_size;
|
||||
enum imem_type imem_type;
|
||||
uint32_t max_load;
|
||||
struct platform_device *pdev;
|
||||
struct regulator_set regulator_set;
|
||||
struct clock_set clock_set;
|
||||
struct bus_set bus_set;
|
||||
bool use_non_secure_pil;
|
||||
bool sw_power_collapsible;
|
||||
bool sys_idle_indicator;
|
||||
bool slave_side_cp;
|
||||
struct list_head context_banks;
|
||||
bool thermal_mitigable;
|
||||
const char *fw_name;
|
||||
const char *hfi_version;
|
||||
bool never_unload_fw;
|
||||
uint32_t pm_qos_latency_us;
|
||||
uint32_t max_inst_count;
|
||||
uint32_t max_secure_inst_count;
|
||||
};
|
||||
|
||||
static inline bool is_iommu_present(struct msm_vidc_platform_resources *res)
|
||||
{
|
||||
return !list_empty(&res->context_banks);
|
||||
}
|
||||
|
||||
extern uint32_t msm_vidc_pwr_collapse_delay;
|
||||
|
||||
#endif
|
||||
|
471
drivers/media/platform/msm/vidc_3x/venus_boot.c
Normal file
471
drivers/media/platform/msm/vidc_3x/venus_boot.c
Normal file
|
@ -0,0 +1,471 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2014-2016, 2018, 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define VIDC_DBG_LABEL "venus_boot"
|
||||
|
||||
#include <asm/dma-iommu.h>
|
||||
#include <asm/page.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/slab.h>
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
#include <soc/qcom/subsystem_restart.h>
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "vidc_hfi_io.h"
|
||||
#include "venus_boot.h"
|
||||
|
||||
/* VENUS WRAPPER registers */
|
||||
#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR_v1 \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x1018)
|
||||
#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR_v1 \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x101C)
|
||||
#define VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR_v1 \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x1020)
|
||||
#define VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR_v1 \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x1024)
|
||||
|
||||
#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR_v2 \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x1020)
|
||||
#define VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR_v2 \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x1024)
|
||||
#define VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR_v2 \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x1028)
|
||||
#define VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR_v2 \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x102C)
|
||||
|
||||
#define VENUS_WRAPPER_SW_RESET (VIDC_WRAPPER_BASE_OFFS + 0x3000)
|
||||
|
||||
/* VENUS VBIF registers */
|
||||
#define VENUS_VBIF_CLKON_FORCE_ON BIT(0)
|
||||
|
||||
#define VENUS_VBIF_ADDR_TRANS_EN (VIDC_VBIF_BASE_OFFS + 0x1000)
|
||||
#define VENUS_VBIF_AT_OLD_BASE (VIDC_VBIF_BASE_OFFS + 0x1004)
|
||||
#define VENUS_VBIF_AT_OLD_HIGH (VIDC_VBIF_BASE_OFFS + 0x1008)
|
||||
#define VENUS_VBIF_AT_NEW_BASE (VIDC_VBIF_BASE_OFFS + 0x1010)
|
||||
#define VENUS_VBIF_AT_NEW_HIGH (VIDC_VBIF_BASE_OFFS + 0x1018)
|
||||
|
||||
|
||||
/* Poll interval in uS */
|
||||
#define POLL_INTERVAL_US 50
|
||||
|
||||
#define VENUS_REGION_SIZE 0x00500000
|
||||
|
||||
static struct {
|
||||
struct msm_vidc_platform_resources *resources;
|
||||
struct regulator *gdsc;
|
||||
const char *reg_name;
|
||||
void __iomem *reg_base;
|
||||
struct device *iommu_ctx_bank_dev;
|
||||
struct iommu_domain *domain;
|
||||
dma_addr_t fw_iova;
|
||||
bool is_booted;
|
||||
bool hw_ver_checked;
|
||||
u32 fw_sz;
|
||||
u32 hw_ver_major;
|
||||
u32 hw_ver_minor;
|
||||
void *venus_notif_hdle;
|
||||
} *venus_data = NULL;
|
||||
|
||||
/* Get venus clocks and set rates for rate-settable clocks */
|
||||
static int venus_clock_setup(void)
|
||||
{
|
||||
int i, rc = 0;
|
||||
unsigned long rate;
|
||||
struct msm_vidc_platform_resources *res = venus_data->resources;
|
||||
struct clock_info *cl;
|
||||
|
||||
for (i = 0; i < res->clock_set.count; i++) {
|
||||
cl = &res->clock_set.clock_tbl[i];
|
||||
/* Make sure rate-settable clocks' rates are set */
|
||||
if (!clk_get_rate(cl->clk) && cl->count) {
|
||||
rate = clk_round_rate(cl->clk, 0);
|
||||
rc = clk_set_rate(cl->clk, rate);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"Failed to set clock rate %lu %s: %d\n",
|
||||
rate, cl->name, rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int venus_clock_prepare_enable(void)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct msm_vidc_platform_resources *res = venus_data->resources;
|
||||
struct clock_info *cl;
|
||||
|
||||
for (i = 0; i < res->clock_set.count; i++) {
|
||||
cl = &res->clock_set.clock_tbl[i];
|
||||
rc = clk_prepare_enable(cl->clk);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "failed to enable %s\n", cl->name);
|
||||
for (i--; i >= 0; i--) {
|
||||
cl = &res->clock_set.clock_tbl[i];
|
||||
clk_disable_unprepare(cl->clk);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void venus_clock_disable_unprepare(void)
|
||||
{
|
||||
int i;
|
||||
struct msm_vidc_platform_resources *res = venus_data->resources;
|
||||
struct clock_info *cl;
|
||||
|
||||
for (i = 0; i < res->clock_set.count; i++) {
|
||||
cl = &res->clock_set.clock_tbl[i];
|
||||
clk_disable_unprepare(cl->clk);
|
||||
}
|
||||
}
|
||||
|
||||
static int venus_setup_cb(struct device *dev,
|
||||
u32 size)
|
||||
{
|
||||
venus_data->domain = iommu_get_domain_for_dev(dev);
|
||||
if (IS_ERR_OR_NULL(venus_data->domain)) {
|
||||
dprintk(VIDC_ERR, "%s: failed to create mapping for %s\n",
|
||||
__func__, dev_name(dev));
|
||||
return -ENODEV;
|
||||
}
|
||||
dprintk(VIDC_DBG,
|
||||
"%s Attached device %pK and created domain %pK for %s\n",
|
||||
__func__, dev, venus_data->domain, dev_name(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pil_venus_mem_setup(size_t size)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!venus_data->domain) {
|
||||
size = round_up(size, SZ_4K);
|
||||
rc = venus_setup_cb(venus_data->iommu_ctx_bank_dev, size);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR,
|
||||
"%s: Failed to setup context bank for venus : %s\n",
|
||||
__func__,
|
||||
dev_name(venus_data->iommu_ctx_bank_dev));
|
||||
return rc;
|
||||
}
|
||||
venus_data->fw_sz = size;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int pil_venus_auth_and_reset(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
phys_addr_t fw_bias = venus_data->resources->firmware_base;
|
||||
void __iomem *reg_base = venus_data->reg_base;
|
||||
u32 ver;
|
||||
bool iommu_present = is_iommu_present(venus_data->resources);
|
||||
struct device *dev = venus_data->iommu_ctx_bank_dev;
|
||||
|
||||
if (!fw_bias) {
|
||||
dprintk(VIDC_ERR, "FW bias is not valid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
venus_data->fw_iova = (dma_addr_t)NULL;
|
||||
/* Get Venus version number */
|
||||
if (!venus_data->hw_ver_checked) {
|
||||
ver = readl_relaxed(reg_base + VIDC_WRAPPER_HW_VERSION);
|
||||
venus_data->hw_ver_minor = (ver & 0x0FFF0000) >> 16;
|
||||
venus_data->hw_ver_major = (ver & 0xF0000000) >> 28;
|
||||
venus_data->hw_ver_checked = true;
|
||||
}
|
||||
|
||||
if (iommu_present) {
|
||||
u32 cpa_start_addr, cpa_end_addr, fw_start_addr, fw_end_addr;
|
||||
/* Get the cpa and fw start/end addr based on Venus version */
|
||||
if (venus_data->hw_ver_major == 0x1 &&
|
||||
venus_data->hw_ver_minor <= 1) {
|
||||
cpa_start_addr =
|
||||
VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR_v1;
|
||||
cpa_end_addr =
|
||||
VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR_v1;
|
||||
fw_start_addr =
|
||||
VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR_v1;
|
||||
fw_end_addr =
|
||||
VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR_v1;
|
||||
} else {
|
||||
cpa_start_addr =
|
||||
VENUS_WRAPPER_VBIF_SS_SEC_CPA_START_ADDR_v2;
|
||||
cpa_end_addr =
|
||||
VENUS_WRAPPER_VBIF_SS_SEC_CPA_END_ADDR_v2;
|
||||
fw_start_addr =
|
||||
VENUS_WRAPPER_VBIF_SS_SEC_FW_START_ADDR_v2;
|
||||
fw_end_addr =
|
||||
VENUS_WRAPPER_VBIF_SS_SEC_FW_END_ADDR_v2;
|
||||
}
|
||||
|
||||
/* Program CPA start and end address */
|
||||
writel_relaxed(0, reg_base + cpa_start_addr);
|
||||
writel_relaxed(venus_data->fw_sz, reg_base + cpa_end_addr);
|
||||
|
||||
/* Program FW start and end address */
|
||||
writel_relaxed(0, reg_base + fw_start_addr);
|
||||
writel_relaxed(venus_data->fw_sz, reg_base + fw_end_addr);
|
||||
} else {
|
||||
rc = regulator_enable(venus_data->gdsc);
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "GDSC enable failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = venus_clock_prepare_enable();
|
||||
if (rc) {
|
||||
dprintk(VIDC_ERR, "Clock prepare and enable failed\n");
|
||||
regulator_disable(venus_data->gdsc);
|
||||
goto err;
|
||||
}
|
||||
|
||||
writel_relaxed(0, reg_base + VENUS_VBIF_AT_OLD_BASE);
|
||||
writel_relaxed(VENUS_REGION_SIZE,
|
||||
reg_base + VENUS_VBIF_AT_OLD_HIGH);
|
||||
writel_relaxed(fw_bias, reg_base + VENUS_VBIF_AT_NEW_BASE);
|
||||
writel_relaxed(fw_bias + VENUS_REGION_SIZE,
|
||||
reg_base + VENUS_VBIF_AT_NEW_HIGH);
|
||||
writel_relaxed(0x7F007F, reg_base + VENUS_VBIF_ADDR_TRANS_EN);
|
||||
venus_clock_disable_unprepare();
|
||||
regulator_disable(venus_data->gdsc);
|
||||
}
|
||||
/* Make sure all register writes are committed. */
|
||||
mb();
|
||||
|
||||
/*
|
||||
* Need to wait 10 cycles of internal clocks before bringing ARM9
|
||||
* out of reset.
|
||||
*/
|
||||
udelay(1);
|
||||
|
||||
if (iommu_present) {
|
||||
phys_addr_t pa = fw_bias;
|
||||
|
||||
dprintk(VIDC_DBG, "Attached and created mapping for %s\n",
|
||||
dev_name(dev));
|
||||
|
||||
/* Map virtual addr space 0 - fw_sz to fw phys addr space */
|
||||
rc = iommu_map(venus_data->domain,
|
||||
venus_data->fw_iova, pa, venus_data->fw_sz,
|
||||
IOMMU_READ|IOMMU_WRITE|IOMMU_PRIV);
|
||||
if (!rc) {
|
||||
dprintk(VIDC_DBG,
|
||||
"%s - Successfully mapped and performed test translation!\n",
|
||||
dev_name(dev));
|
||||
}
|
||||
|
||||
if (rc || (venus_data->fw_iova != 0)) {
|
||||
dprintk(VIDC_ERR, "%s - Failed to setup IOMMU\n",
|
||||
dev_name(dev));
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
/* Bring Arm9 out of reset */
|
||||
writel_relaxed(0, reg_base + VENUS_WRAPPER_SW_RESET);
|
||||
|
||||
venus_data->is_booted = true;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int pil_venus_shutdown(void)
|
||||
{
|
||||
void __iomem *reg_base = venus_data->reg_base;
|
||||
u32 reg;
|
||||
int rc;
|
||||
|
||||
if (!venus_data->is_booted)
|
||||
return 0;
|
||||
|
||||
/* Assert the reset to ARM9 */
|
||||
reg = readl_relaxed(reg_base + VENUS_WRAPPER_SW_RESET);
|
||||
reg |= BIT(4);
|
||||
writel_relaxed(reg, reg_base + VENUS_WRAPPER_SW_RESET);
|
||||
|
||||
/* Make sure reset is asserted before the mapping is removed */
|
||||
mb();
|
||||
|
||||
if (is_iommu_present(venus_data->resources)) {
|
||||
iommu_unmap(venus_data->domain, venus_data->fw_iova,
|
||||
venus_data->fw_sz);
|
||||
}
|
||||
/*
|
||||
* Force the VBIF clk to be on to avoid AXI bridge halt ack failure
|
||||
* for certain Venus version.
|
||||
*/
|
||||
if (venus_data->hw_ver_major == 0x1 &&
|
||||
(venus_data->hw_ver_minor == 0x2 ||
|
||||
venus_data->hw_ver_minor == 0x3)) {
|
||||
reg = readl_relaxed(reg_base + VIDC_VENUS_VBIF_CLK_ON);
|
||||
reg |= VENUS_VBIF_CLKON_FORCE_ON;
|
||||
writel_relaxed(reg, reg_base + VIDC_VENUS_VBIF_CLK_ON);
|
||||
}
|
||||
|
||||
/* Halt AXI and AXI OCMEM VBIF Access */
|
||||
reg = readl_relaxed(reg_base + VENUS_VBIF_AXI_HALT_CTRL0);
|
||||
reg |= VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ;
|
||||
writel_relaxed(reg, reg_base + VENUS_VBIF_AXI_HALT_CTRL0);
|
||||
|
||||
/* Request for AXI bus port halt */
|
||||
rc = readl_poll_timeout(reg_base + VENUS_VBIF_AXI_HALT_CTRL1,
|
||||
reg, reg & VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK,
|
||||
POLL_INTERVAL_US,
|
||||
VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US);
|
||||
if (rc)
|
||||
dprintk(VIDC_ERR, "Port halt timeout\n");
|
||||
|
||||
venus_data->is_booted = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int venus_notifier_cb(struct notifier_block *this, unsigned long code,
|
||||
void *ss_handle)
|
||||
{
|
||||
struct notif_data *data = (struct notif_data *)ss_handle;
|
||||
static bool venus_data_set;
|
||||
int ret;
|
||||
|
||||
if (!data->no_auth)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (!venus_data_set) {
|
||||
ret = venus_clock_setup();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = of_property_read_string(data->pdev->dev.of_node,
|
||||
"qcom,proxy-reg-names", &venus_data->reg_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
venus_data->gdsc = devm_regulator_get(
|
||||
&data->pdev->dev, venus_data->reg_name);
|
||||
if (IS_ERR(venus_data->gdsc)) {
|
||||
dprintk(VIDC_ERR, "Failed to get Venus GDSC\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
venus_data_set = true;
|
||||
}
|
||||
|
||||
if (code != SUBSYS_AFTER_POWERUP && code != SUBSYS_AFTER_SHUTDOWN)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
ret = regulator_enable(venus_data->gdsc);
|
||||
if (ret) {
|
||||
dprintk(VIDC_ERR, "GDSC enable failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = venus_clock_prepare_enable();
|
||||
if (ret) {
|
||||
dprintk(VIDC_ERR, "Clock prepare and enable failed\n");
|
||||
goto err_clks;
|
||||
}
|
||||
|
||||
if (code == SUBSYS_AFTER_POWERUP) {
|
||||
if (is_iommu_present(venus_data->resources))
|
||||
pil_venus_mem_setup(VENUS_REGION_SIZE);
|
||||
pil_venus_auth_and_reset();
|
||||
} else if (code == SUBSYS_AFTER_SHUTDOWN)
|
||||
pil_venus_shutdown();
|
||||
|
||||
venus_clock_disable_unprepare();
|
||||
regulator_disable(venus_data->gdsc);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
err_clks:
|
||||
regulator_disable(venus_data->gdsc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct notifier_block venus_notifier = {
|
||||
.notifier_call = venus_notifier_cb,
|
||||
};
|
||||
|
||||
int venus_boot_init(struct msm_vidc_platform_resources *res,
|
||||
struct context_bank_info *cb)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!res || !cb) {
|
||||
dprintk(VIDC_ERR, "Invalid platform resource handle\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
venus_data = kzalloc(sizeof(*venus_data), GFP_KERNEL);
|
||||
if (!venus_data)
|
||||
return -ENOMEM;
|
||||
|
||||
venus_data->resources = res;
|
||||
venus_data->iommu_ctx_bank_dev = cb->dev;
|
||||
if (!venus_data->iommu_ctx_bank_dev) {
|
||||
dprintk(VIDC_ERR, "Invalid venus context bank device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
venus_data->reg_base = ioremap_nocache(res->register_base,
|
||||
(unsigned long)res->register_size);
|
||||
if (!venus_data->reg_base) {
|
||||
dprintk(VIDC_ERR,
|
||||
"could not map reg addr %pa of size %d\n",
|
||||
&res->register_base, res->register_size);
|
||||
rc = -ENOMEM;
|
||||
goto err_ioremap_fail;
|
||||
}
|
||||
venus_data->venus_notif_hdle = subsys_notif_register_notifier("venus",
|
||||
&venus_notifier);
|
||||
if (IS_ERR(venus_data->venus_notif_hdle)) {
|
||||
dprintk(VIDC_ERR, "register event notification failed\n");
|
||||
rc = PTR_ERR(venus_data->venus_notif_hdle);
|
||||
goto err_subsys_notif;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
err_subsys_notif:
|
||||
err_ioremap_fail:
|
||||
kfree(venus_data);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void venus_boot_deinit(void)
|
||||
{
|
||||
venus_data->resources = NULL;
|
||||
subsys_notif_unregister_notifier(venus_data->venus_notif_hdle,
|
||||
&venus_notifier);
|
||||
kfree(venus_data);
|
||||
}
|
23
drivers/media/platform/msm/vidc_3x/venus_boot.h
Normal file
23
drivers/media/platform/msm/vidc_3x/venus_boot.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2014, 2019-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __VENUS_BOOT_H__
|
||||
#define __VENUS_BOOT_H__
|
||||
#include "msm_vidc_resources.h"
|
||||
|
||||
int venus_boot_init(struct msm_vidc_platform_resources *res,
|
||||
struct context_bank_info *cb);
|
||||
void venus_boot_deinit(void);
|
||||
|
||||
#endif /* __VENUS_BOOT_H__ */
|
4663
drivers/media/platform/msm/vidc_3x/venus_hfi.c
Normal file
4663
drivers/media/platform/msm/vidc_3x/venus_hfi.c
Normal file
File diff suppressed because it is too large
Load diff
266
drivers/media/platform/msm/vidc_3x/venus_hfi.h
Normal file
266
drivers/media/platform/msm/vidc_3x/venus_hfi.h
Normal file
|
@ -0,0 +1,266 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2015, 2018-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __H_VENUS_HFI_H__
|
||||
#define __H_VENUS_HFI_H__
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include "vmem/vmem.h"
|
||||
#include "vidc_hfi_api.h"
|
||||
#include "vidc_hfi_helper.h"
|
||||
#include "vidc_hfi_api.h"
|
||||
#include "vidc_hfi.h"
|
||||
#include "msm_vidc_resources.h"
|
||||
#include "hfi_packetization.h"
|
||||
|
||||
#define HFI_MASK_QHDR_TX_TYPE 0xFF000000
|
||||
#define HFI_MASK_QHDR_RX_TYPE 0x00FF0000
|
||||
#define HFI_MASK_QHDR_PRI_TYPE 0x0000FF00
|
||||
#define HFI_MASK_QHDR_Q_ID_TYPE 0x000000FF
|
||||
#define HFI_Q_ID_HOST_TO_CTRL_CMD_Q 0x00
|
||||
#define HFI_Q_ID_CTRL_TO_HOST_MSG_Q 0x01
|
||||
#define HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q 0x02
|
||||
#define HFI_MASK_QHDR_STATUS 0x000000FF
|
||||
|
||||
#define VIDC_MAX_UNCOMPRESSED_FMT_PLANES 3
|
||||
|
||||
#define VIDC_IFACEQ_NUMQ 3
|
||||
#define VIDC_IFACEQ_CMDQ_IDX 0
|
||||
#define VIDC_IFACEQ_MSGQ_IDX 1
|
||||
#define VIDC_IFACEQ_DBGQ_IDX 2
|
||||
#define VIDC_IFACEQ_MAX_BUF_COUNT 50
|
||||
#define VIDC_IFACE_MAX_PARALLEL_CLNTS 16
|
||||
#define VIDC_IFACEQ_DFLT_QHDR 0x01010000
|
||||
|
||||
#define VIDC_MAX_NAME_LENGTH 64
|
||||
#define VIDC_MAX_PC_SKIP_COUNT 10
|
||||
|
||||
extern unsigned long __calc_bw(struct bus_info *bus,
|
||||
struct msm_vidc_gov_data *vidc_data);
|
||||
struct hfi_queue_table_header {
|
||||
u32 qtbl_version;
|
||||
u32 qtbl_size;
|
||||
u32 qtbl_qhdr0_offset;
|
||||
u32 qtbl_qhdr_size;
|
||||
u32 qtbl_num_q;
|
||||
u32 qtbl_num_active_q;
|
||||
};
|
||||
|
||||
struct hfi_queue_header {
|
||||
u32 qhdr_status;
|
||||
u32 qhdr_start_addr;
|
||||
u32 qhdr_type;
|
||||
u32 qhdr_q_size;
|
||||
u32 qhdr_pkt_size;
|
||||
u32 qhdr_pkt_drop_cnt;
|
||||
u32 qhdr_rx_wm;
|
||||
u32 qhdr_tx_wm;
|
||||
u32 qhdr_rx_req;
|
||||
u32 qhdr_tx_req;
|
||||
u32 qhdr_rx_irq_status;
|
||||
u32 qhdr_tx_irq_status;
|
||||
u32 qhdr_read_idx;
|
||||
u32 qhdr_write_idx;
|
||||
};
|
||||
|
||||
struct hfi_mem_map_table {
|
||||
u32 mem_map_num_entries;
|
||||
u32 mem_map_table_base_addr;
|
||||
};
|
||||
|
||||
struct hfi_mem_map {
|
||||
u32 virtual_addr;
|
||||
u32 physical_addr;
|
||||
u32 size;
|
||||
u32 attr;
|
||||
};
|
||||
|
||||
#define VIDC_IFACEQ_TABLE_SIZE (sizeof(struct hfi_queue_table_header) \
|
||||
+ sizeof(struct hfi_queue_header) * VIDC_IFACEQ_NUMQ)
|
||||
|
||||
#define VIDC_IFACEQ_QUEUE_SIZE (VIDC_IFACEQ_MAX_PKT_SIZE * \
|
||||
VIDC_IFACEQ_MAX_BUF_COUNT * VIDC_IFACE_MAX_PARALLEL_CLNTS)
|
||||
|
||||
#define VIDC_IFACEQ_GET_QHDR_START_ADDR(ptr, i) \
|
||||
(void *)((ptr + sizeof(struct hfi_queue_table_header)) + \
|
||||
(i * sizeof(struct hfi_queue_header)))
|
||||
|
||||
#define QDSS_SIZE 4096
|
||||
#define SFR_SIZE 4096
|
||||
|
||||
#define QUEUE_SIZE (VIDC_IFACEQ_TABLE_SIZE + \
|
||||
(VIDC_IFACEQ_QUEUE_SIZE * VIDC_IFACEQ_NUMQ))
|
||||
|
||||
#define ALIGNED_QDSS_SIZE ALIGN(QDSS_SIZE, SZ_4K)
|
||||
#define ALIGNED_SFR_SIZE ALIGN(SFR_SIZE, SZ_4K)
|
||||
#define ALIGNED_QUEUE_SIZE ALIGN(QUEUE_SIZE, SZ_4K)
|
||||
#define SHARED_QSIZE ALIGN(ALIGNED_SFR_SIZE + ALIGNED_QUEUE_SIZE + \
|
||||
ALIGNED_QDSS_SIZE, SZ_1M)
|
||||
|
||||
enum vidc_hw_reg {
|
||||
VIDC_HWREG_CTRL_STATUS = 0x1,
|
||||
VIDC_HWREG_QTBL_INFO = 0x2,
|
||||
VIDC_HWREG_QTBL_ADDR = 0x3,
|
||||
VIDC_HWREG_CTRLR_RESET = 0x4,
|
||||
VIDC_HWREG_IFACEQ_FWRXREQ = 0x5,
|
||||
VIDC_HWREG_IFACEQ_FWTXREQ = 0x6,
|
||||
VIDC_HWREG_VHI_SOFTINTEN = 0x7,
|
||||
VIDC_HWREG_VHI_SOFTINTSTATUS = 0x8,
|
||||
VIDC_HWREG_VHI_SOFTINTCLR = 0x9,
|
||||
VIDC_HWREG_HVI_SOFTINTEN = 0xA,
|
||||
};
|
||||
|
||||
struct vidc_mem_addr {
|
||||
phys_addr_t align_device_addr;
|
||||
u8 *align_virtual_addr;
|
||||
u32 mem_size;
|
||||
struct msm_smem mem_data;
|
||||
};
|
||||
|
||||
struct vidc_iface_q_info {
|
||||
void *q_hdr;
|
||||
struct vidc_mem_addr q_array;
|
||||
};
|
||||
|
||||
/*
|
||||
* These are helper macros to iterate over various lists within
|
||||
* venus_hfi_device->res. The intention is to cut down on a lot of boiler-plate
|
||||
* code
|
||||
*/
|
||||
|
||||
/* Read as "for each 'thing' in a set of 'thingies'" */
|
||||
#define venus_hfi_for_each_thing(__device, __thing, __thingy) \
|
||||
venus_hfi_for_each_thing_continue(__device, __thing, __thingy, 0)
|
||||
|
||||
#define venus_hfi_for_each_thing_reverse(__device, __thing, __thingy) \
|
||||
venus_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \
|
||||
(__device)->res->__thingy##_set.count - 1)
|
||||
|
||||
/* TODO: the __from parameter technically not required since we can figure it
|
||||
* out with some pointer magic (i.e. __thing - __thing##_tbl[0]). If this macro
|
||||
* sees extensive use, probably worth cleaning it up but for now omitting it
|
||||
* since it introduces unnecessary complexity.
|
||||
*/
|
||||
#define venus_hfi_for_each_thing_continue(__device, __thing, __thingy, __from) \
|
||||
for (__thing = &(__device)->res->\
|
||||
__thingy##_set.__thingy##_tbl[__from]; \
|
||||
__thing < &(__device)->res->__thingy##_set.__thingy##_tbl[0] + \
|
||||
((__device)->res->__thingy##_set.count - __from); \
|
||||
++__thing)
|
||||
|
||||
#define venus_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \
|
||||
__from) \
|
||||
for (__thing = &(__device)->res->\
|
||||
__thingy##_set.__thingy##_tbl[__from]; \
|
||||
__thing >= &(__device)->res->__thingy##_set.__thingy##_tbl[0]; \
|
||||
--__thing)
|
||||
|
||||
/* Regular set helpers */
|
||||
#define venus_hfi_for_each_regulator(__device, __rinfo) \
|
||||
venus_hfi_for_each_thing(__device, __rinfo, regulator)
|
||||
|
||||
#define venus_hfi_for_each_regulator_reverse(__device, __rinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __rinfo, regulator)
|
||||
|
||||
#define venus_hfi_for_each_regulator_reverse_continue(__device, __rinfo, \
|
||||
__from) \
|
||||
venus_hfi_for_each_thing_reverse_continue(__device, __rinfo, \
|
||||
regulator, __from)
|
||||
|
||||
/* Clock set helpers */
|
||||
#define venus_hfi_for_each_clock(__device, __cinfo) \
|
||||
venus_hfi_for_each_thing(__device, __cinfo, clock)
|
||||
|
||||
#define venus_hfi_for_each_clock_reverse(__device, __cinfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __cinfo, clock)
|
||||
|
||||
/* Bus set helpers */
|
||||
#define venus_hfi_for_each_bus(__device, __binfo) \
|
||||
venus_hfi_for_each_thing(__device, __binfo, bus)
|
||||
#define venus_hfi_for_each_bus_reverse(__device, __binfo) \
|
||||
venus_hfi_for_each_thing_reverse(__device, __binfo, bus)
|
||||
|
||||
|
||||
/* Internal data used in vidc_hal not exposed to msm_vidc*/
|
||||
struct hal_data {
|
||||
u32 irq;
|
||||
phys_addr_t firmware_base;
|
||||
u8 __iomem *register_base;
|
||||
u32 register_size;
|
||||
};
|
||||
|
||||
struct imem {
|
||||
enum imem_type type;
|
||||
union {
|
||||
phys_addr_t vmem;
|
||||
};
|
||||
};
|
||||
|
||||
struct venus_resources {
|
||||
struct msm_vidc_fw fw;
|
||||
struct imem imem;
|
||||
};
|
||||
|
||||
enum venus_hfi_state {
|
||||
VENUS_STATE_DEINIT = 1,
|
||||
VENUS_STATE_INIT,
|
||||
};
|
||||
|
||||
struct venus_hfi_device {
|
||||
struct list_head list;
|
||||
struct list_head sess_head;
|
||||
u32 intr_status;
|
||||
u32 device_id;
|
||||
u32 clk_freq;
|
||||
u32 last_packet_type;
|
||||
unsigned long clk_bitrate;
|
||||
unsigned long scaled_rate;
|
||||
struct msm_vidc_gov_data bus_vote;
|
||||
bool power_enabled;
|
||||
struct mutex lock;
|
||||
msm_vidc_callback callback;
|
||||
struct vidc_mem_addr iface_q_table;
|
||||
struct vidc_mem_addr qdss;
|
||||
struct vidc_mem_addr sfr;
|
||||
struct vidc_mem_addr mem_addr;
|
||||
struct vidc_iface_q_info iface_queues[VIDC_IFACEQ_NUMQ];
|
||||
struct hal_data *hal_data;
|
||||
struct workqueue_struct *vidc_workq;
|
||||
struct workqueue_struct *venus_pm_workq;
|
||||
int spur_count;
|
||||
int reg_count;
|
||||
struct venus_resources resources;
|
||||
struct msm_vidc_platform_resources *res;
|
||||
enum venus_hfi_state state;
|
||||
struct hfi_packetization_ops *pkt_ops;
|
||||
enum hfi_packetization_type packetization_type;
|
||||
struct msm_vidc_cb_info *response_pkt;
|
||||
struct pm_qos_request qos;
|
||||
unsigned int skip_pc_count;
|
||||
struct msm_vidc_capability *sys_init_capabilities;
|
||||
};
|
||||
|
||||
void venus_hfi_delete_device(void *device);
|
||||
|
||||
int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id,
|
||||
struct msm_vidc_platform_resources *res,
|
||||
hfi_cmd_response_callback callback);
|
||||
bool venus_hfi_is_session_supported(unsigned long sessions_supported,
|
||||
enum vidc_vote_data_session session_type);
|
||||
|
||||
#endif
|
73
drivers/media/platform/msm/vidc_3x/vidc_hfi.c
Normal file
73
drivers/media/platform/msm/vidc_3x/vidc_hfi.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include "msm_vidc_debug.h"
|
||||
#include "vidc_hfi_api.h"
|
||||
#include "venus_hfi.h"
|
||||
|
||||
struct hfi_device *vidc_hfi_initialize(enum msm_vidc_hfi_type hfi_type,
|
||||
u32 device_id, struct msm_vidc_platform_resources *res,
|
||||
hfi_cmd_response_callback callback)
|
||||
{
|
||||
struct hfi_device *hdev = NULL;
|
||||
int rc = 0;
|
||||
|
||||
hdev = kzalloc(sizeof(struct hfi_device), GFP_KERNEL);
|
||||
if (!hdev) {
|
||||
dprintk(VIDC_ERR, "%s: failed to allocate hdev\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (hfi_type) {
|
||||
case VIDC_HFI_VENUS:
|
||||
rc = venus_hfi_initialize(hdev, device_id, res, callback);
|
||||
break;
|
||||
default:
|
||||
dprintk(VIDC_ERR, "Unsupported host-firmware interface\n");
|
||||
goto err_hfi_init;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
if (rc != -EPROBE_DEFER)
|
||||
dprintk(VIDC_ERR, "%s device init failed rc = %d",
|
||||
__func__, rc);
|
||||
goto err_hfi_init;
|
||||
}
|
||||
|
||||
return hdev;
|
||||
|
||||
err_hfi_init:
|
||||
kfree(hdev);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type,
|
||||
struct hfi_device *hdev)
|
||||
{
|
||||
if (!hdev) {
|
||||
dprintk(VIDC_ERR, "%s invalid device %pK", __func__, hdev);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (hfi_type) {
|
||||
case VIDC_HFI_VENUS:
|
||||
venus_hfi_delete_device(hdev->hfi_device_data);
|
||||
break;
|
||||
default:
|
||||
dprintk(VIDC_ERR, "Unsupported host-firmware interface\n");
|
||||
}
|
||||
|
||||
kfree(hdev);
|
||||
}
|
||||
|
935
drivers/media/platform/msm/vidc_3x/vidc_hfi.h
Normal file
935
drivers/media/platform/msm/vidc_3x/vidc_hfi.h
Normal file
|
@ -0,0 +1,935 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2016, 2018-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#ifndef __H_VIDC_HFI_H__
|
||||
#define __H_VIDC_HFI_H__
|
||||
|
||||
#include <media/msm_media_info.h>
|
||||
#include "vidc_hfi_helper.h"
|
||||
#include "vidc_hfi_api.h"
|
||||
|
||||
#define HFI_EVENT_SESSION_SEQUENCE_CHANGED (HFI_OX_BASE + 0x3)
|
||||
#define HFI_EVENT_SESSION_PROPERTY_CHANGED (HFI_OX_BASE + 0x4)
|
||||
#define HFI_EVENT_SESSION_LTRUSE_FAILED (HFI_OX_BASE + 0x5)
|
||||
#define HFI_EVENT_RELEASE_BUFFER_REFERENCE (HFI_OX_BASE + 0x6)
|
||||
|
||||
#define HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES \
|
||||
(HFI_OX_BASE + 0x1)
|
||||
#define HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUFFER_RESOURCES \
|
||||
(HFI_OX_BASE + 0x2)
|
||||
|
||||
#define HFI_BUFFERFLAG_EOS 0x00000001
|
||||
#define HFI_BUFFERFLAG_STARTTIME 0x00000002
|
||||
#define HFI_BUFFERFLAG_DECODEONLY 0x00000004
|
||||
#define HFI_BUFFERFLAG_DATACORRUPT 0x00000008
|
||||
#define HFI_BUFFERFLAG_ENDOFFRAME 0x00000010
|
||||
#define HFI_BUFFERFLAG_SYNCFRAME 0x00000020
|
||||
#define HFI_BUFFERFLAG_EXTRADATA 0x00000040
|
||||
#define HFI_BUFFERFLAG_CODECCONFIG 0x00000080
|
||||
#define HFI_BUFFERFLAG_TIMESTAMPINVALID 0x00000100
|
||||
#define HFI_BUFFERFLAG_READONLY 0x00000200
|
||||
#define HFI_BUFFERFLAG_ENDOFSUBFRAME 0x00000400
|
||||
#define HFI_BUFFERFLAG_EOSEQ 0x00200000
|
||||
#define HFI_BUFFER_FLAG_MBAFF 0x08000000
|
||||
#define HFI_BUFFERFLAG_VPE_YUV_601_709_CSC_CLAMP \
|
||||
0x10000000
|
||||
#define HFI_BUFFERFLAG_DROP_FRAME 0x20000000
|
||||
#define HFI_BUFFERFLAG_TEI 0x40000000
|
||||
#define HFI_BUFFERFLAG_DISCONTINUITY 0x80000000
|
||||
|
||||
|
||||
#define HFI_ERR_SESSION_EMPTY_BUFFER_DONE_OUTPUT_PENDING \
|
||||
(HFI_OX_BASE + 0x1001)
|
||||
#define HFI_ERR_SESSION_SAME_STATE_OPERATION \
|
||||
(HFI_OX_BASE + 0x1002)
|
||||
#define HFI_ERR_SESSION_SYNC_FRAME_NOT_DETECTED \
|
||||
(HFI_OX_BASE + 0x1003)
|
||||
#define HFI_ERR_SESSION_START_CODE_NOT_FOUND \
|
||||
(HFI_OX_BASE + 0x1004)
|
||||
|
||||
#define HFI_BUFFER_INTERNAL_SCRATCH (HFI_OX_BASE + 0x1)
|
||||
#define HFI_BUFFER_EXTRADATA_INPUT (HFI_OX_BASE + 0x2)
|
||||
#define HFI_BUFFER_EXTRADATA_OUTPUT (HFI_OX_BASE + 0x3)
|
||||
#define HFI_BUFFER_EXTRADATA_OUTPUT2 (HFI_OX_BASE + 0x4)
|
||||
#define HFI_BUFFER_INTERNAL_SCRATCH_1 (HFI_OX_BASE + 0x5)
|
||||
#define HFI_BUFFER_INTERNAL_SCRATCH_2 (HFI_OX_BASE + 0x6)
|
||||
|
||||
#define HFI_BUFFER_MODE_STATIC (HFI_OX_BASE + 0x1)
|
||||
#define HFI_BUFFER_MODE_RING (HFI_OX_BASE + 0x2)
|
||||
#define HFI_BUFFER_MODE_DYNAMIC (HFI_OX_BASE + 0x3)
|
||||
|
||||
#define HFI_FLUSH_INPUT (HFI_OX_BASE + 0x1)
|
||||
#define HFI_FLUSH_OUTPUT (HFI_OX_BASE + 0x2)
|
||||
#define HFI_FLUSH_ALL (HFI_OX_BASE + 0x4)
|
||||
|
||||
#define HFI_EXTRADATA_NONE 0x00000000
|
||||
#define HFI_EXTRADATA_MB_QUANTIZATION 0x00000001
|
||||
#define HFI_EXTRADATA_INTERLACE_VIDEO 0x00000002
|
||||
#define HFI_EXTRADATA_VC1_FRAMEDISP 0x00000003
|
||||
#define HFI_EXTRADATA_VC1_SEQDISP 0x00000004
|
||||
#define HFI_EXTRADATA_TIMESTAMP 0x00000005
|
||||
#define HFI_EXTRADATA_S3D_FRAME_PACKING 0x00000006
|
||||
#define HFI_EXTRADATA_FRAME_RATE 0x00000007
|
||||
#define HFI_EXTRADATA_PANSCAN_WINDOW 0x00000008
|
||||
#define HFI_EXTRADATA_RECOVERY_POINT_SEI 0x00000009
|
||||
#define HFI_EXTRADATA_MPEG2_SEQDISP 0x0000000D
|
||||
#define HFI_EXTRADATA_STREAM_USERDATA 0x0000000E
|
||||
#define HFI_EXTRADATA_FRAME_QP 0x0000000F
|
||||
#define HFI_EXTRADATA_FRAME_BITS_INFO 0x00000010
|
||||
#define HFI_EXTRADATA_VPX_COLORSPACE 0x00000014
|
||||
#define HFI_EXTRADATA_MULTISLICE_INFO 0x7F100000
|
||||
#define HFI_EXTRADATA_NUM_CONCEALED_MB 0x7F100001
|
||||
#define HFI_EXTRADATA_INDEX 0x7F100002
|
||||
#define HFI_EXTRADATA_METADATA_LTR 0x7F100004
|
||||
#define HFI_EXTRADATA_METADATA_FILLER 0x7FE00002
|
||||
|
||||
#define HFI_INDEX_EXTRADATA_INPUT_CROP 0x0700000E
|
||||
#define HFI_INDEX_EXTRADATA_OUTPUT_CROP 0x0700000F
|
||||
#define HFI_INDEX_EXTRADATA_ASPECT_RATIO 0x7F100003
|
||||
|
||||
struct hfi_buffer_alloc_mode {
|
||||
u32 buffer_type;
|
||||
u32 buffer_mode;
|
||||
};
|
||||
|
||||
|
||||
struct hfi_index_extradata_config {
|
||||
int enable;
|
||||
u32 index_extra_data_id;
|
||||
};
|
||||
|
||||
struct hfi_extradata_header {
|
||||
u32 size;
|
||||
u32 version;
|
||||
u32 port_index;
|
||||
u32 type;
|
||||
u32 data_size;
|
||||
u8 rg_data[1];
|
||||
};
|
||||
|
||||
#define HFI_INTERLACE_FRAME_PROGRESSIVE 0x01
|
||||
#define HFI_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST 0x02
|
||||
#define HFI_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST 0x04
|
||||
#define HFI_INTERLACE_FRAME_TOPFIELDFIRST 0x08
|
||||
#define HFI_INTERLACE_FRAME_BOTTOMFIELDFIRST 0x10
|
||||
|
||||
#define HFI_PROPERTY_SYS_OX_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x0000)
|
||||
|
||||
#define HFI_PROPERTY_PARAM_OX_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x1000)
|
||||
#define HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x001)
|
||||
#define HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x002)
|
||||
#define HFI_PROPERTY_PARAM_INTERLACE_FORMAT_SUPPORTED \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x003)
|
||||
#define HFI_PROPERTY_PARAM_CHROMA_SITE \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x004)
|
||||
#define HFI_PROPERTY_PARAM_EXTRA_DATA_HEADER_CONFIG \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x005)
|
||||
#define HFI_PROPERTY_PARAM_INDEX_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x006)
|
||||
#define HFI_PROPERTY_PARAM_DIVX_FORMAT \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x007)
|
||||
#define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x008)
|
||||
#define HFI_PROPERTY_PARAM_S3D_FRAME_PACKING_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x009)
|
||||
#define HFI_PROPERTY_PARAM_ERR_DETECTION_CODE_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x00A)
|
||||
#define HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x00B)
|
||||
#define HFI_PROPERTY_PARAM_BUFFER_SIZE_MINIMUM \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x00C)
|
||||
#define HFI_PROPERTY_PARAM_SYNC_BASED_INTERRUPT \
|
||||
(HFI_PROPERTY_PARAM_OX_START + 0x00E)
|
||||
|
||||
#define HFI_PROPERTY_CONFIG_OX_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x02000)
|
||||
#define HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS \
|
||||
(HFI_PROPERTY_CONFIG_OX_START + 0x001)
|
||||
#define HFI_PROPERTY_CONFIG_REALTIME \
|
||||
(HFI_PROPERTY_CONFIG_OX_START + 0x002)
|
||||
#define HFI_PROPERTY_CONFIG_PRIORITY \
|
||||
(HFI_PROPERTY_CONFIG_OX_START + 0x003)
|
||||
#define HFI_PROPERTY_CONFIG_BATCH_INFO \
|
||||
(HFI_PROPERTY_CONFIG_OX_START + 0x004)
|
||||
|
||||
#define HFI_PROPERTY_PARAM_VDEC_OX_START \
|
||||
(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x3000)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT\
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x002)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_MULTI_VIEW_SELECT \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x003)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x004)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x005)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_MB_QUANTIZATION \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x006)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_NUM_CONCEALED_MB \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x007)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_H264_ENTROPY_SWITCHING \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x008)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO\
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x009)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_FRAME_RATE_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00A)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_PANSCAN_WNDW_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00B)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_RECOVERY_POINT_SEI_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00C)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00D)
|
||||
|
||||
#define HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x00E)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_VC1_FRAMEDISP_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x011)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_VC1_SEQDISP_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x012)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_TIMESTAMP_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x013)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_INTERLACE_VIDEO_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x014)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_AVC_SESSION_SELECT \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x015)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_MPEG2_SEQDISP_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x016)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_STREAM_USERDATA_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x017)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_FRAME_QP_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x018)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_FRAME_BITS_INFO_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x019)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_SCS_THRESHOLD \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x01A)
|
||||
#define HFI_PROPERTY_PARAM_VUI_DISPLAY_INFO_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x01B)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_VQZIP_SEI_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001C)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_VPX_COLORSPACE_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001D)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_MASTERING_DISPLAY_COLOUR_SEI_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001E)
|
||||
#define HFI_PROPERTY_PARAM_VDEC_CONTENT_LIGHT_LEVEL_SEI_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x001F)
|
||||
|
||||
#define HFI_PROPERTY_CONFIG_VDEC_OX_START \
|
||||
(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x4000)
|
||||
#define HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER \
|
||||
(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x001)
|
||||
#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING \
|
||||
(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x002)
|
||||
#define HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP \
|
||||
(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x003)
|
||||
#define HFI_PROPERTY_CONFIG_VDEC_ENTROPY \
|
||||
(HFI_PROPERTY_CONFIG_VDEC_OX_START + 0x004)
|
||||
|
||||
#define HFI_PROPERTY_PARAM_VENC_OX_START \
|
||||
(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x5000)
|
||||
#define HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_INFO \
|
||||
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x001)
|
||||
#define HFI_PROPERTY_PARAM_VENC_H264_IDR_S3D_FRAME_PACKING_NAL \
|
||||
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x002)
|
||||
#define HFI_PROPERTY_PARAM_VENC_LTR_INFO \
|
||||
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x003)
|
||||
#define HFI_PROPERTY_PARAM_VENC_MBI_DUMPING \
|
||||
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x005)
|
||||
#define HFI_PROPERTY_PARAM_VENC_FRAME_QP_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x006)
|
||||
#define HFI_PROPERTY_PARAM_VENC_YUVSTAT_INFO_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x007)
|
||||
#define HFI_PROPERTY_PARAM_VENC_ROI_QP_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x008)
|
||||
#define HFI_PROPERTY_PARAM_VENC_OVERRIDE_QP_EXTRADATA \
|
||||
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x009)
|
||||
|
||||
#define HFI_PROPERTY_CONFIG_VENC_OX_START \
|
||||
(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x6000)
|
||||
#define HFI_PROPERTY_CONFIG_VENC_FRAME_QP \
|
||||
(HFI_PROPERTY_CONFIG_VENC_OX_START + 0x001)
|
||||
|
||||
#define HFI_PROPERTY_PARAM_VPE_OX_START \
|
||||
(HFI_DOMAIN_BASE_VPE + HFI_ARCH_OX_OFFSET + 0x7000)
|
||||
#define HFI_PROPERTY_PARAM_VPE_COLOR_SPACE_CONVERSION \
|
||||
(HFI_PROPERTY_PARAM_VPE_OX_START + 0x001)
|
||||
|
||||
#define HFI_PROPERTY_CONFIG_VPE_OX_START \
|
||||
(HFI_DOMAIN_BASE_VPE + HFI_ARCH_OX_OFFSET + 0x8000)
|
||||
|
||||
struct hfi_batch_info {
|
||||
u32 input_batch_count;
|
||||
u32 output_batch_count;
|
||||
};
|
||||
|
||||
struct hfi_buffer_count_actual {
|
||||
u32 buffer_type;
|
||||
u32 buffer_count_actual;
|
||||
};
|
||||
|
||||
struct hfi_buffer_size_minimum {
|
||||
u32 buffer_type;
|
||||
u32 buffer_size;
|
||||
};
|
||||
|
||||
struct hfi_buffer_requirements {
|
||||
u32 buffer_type;
|
||||
u32 buffer_size;
|
||||
u32 buffer_region_size;
|
||||
u32 buffer_hold_count;
|
||||
u32 buffer_count_min;
|
||||
u32 buffer_count_actual;
|
||||
u32 contiguous;
|
||||
u32 buffer_alignment;
|
||||
};
|
||||
|
||||
#define HFI_CHROMA_SITE_0 (HFI_OX_BASE + 0x1)
|
||||
#define HFI_CHROMA_SITE_1 (HFI_OX_BASE + 0x2)
|
||||
#define HFI_CHROMA_SITE_2 (HFI_OX_BASE + 0x3)
|
||||
#define HFI_CHROMA_SITE_3 (HFI_OX_BASE + 0x4)
|
||||
#define HFI_CHROMA_SITE_4 (HFI_OX_BASE + 0x5)
|
||||
#define HFI_CHROMA_SITE_5 (HFI_OX_BASE + 0x6)
|
||||
|
||||
struct hfi_data_payload {
|
||||
u32 size;
|
||||
u8 rg_data[1];
|
||||
};
|
||||
|
||||
struct hfi_enable_picture {
|
||||
u32 picture_type;
|
||||
};
|
||||
|
||||
struct hfi_display_picture_buffer_count {
|
||||
int enable;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct hfi_extra_data_header_config {
|
||||
u32 type;
|
||||
u32 buffer_type;
|
||||
u32 version;
|
||||
u32 port_index;
|
||||
u32 client_extra_data_id;
|
||||
};
|
||||
|
||||
struct hfi_interlace_format_supported {
|
||||
u32 buffer_type;
|
||||
u32 format;
|
||||
};
|
||||
|
||||
struct hfi_buffer_alloc_mode_supported {
|
||||
u32 buffer_type;
|
||||
u32 num_entries;
|
||||
u32 rg_data[1];
|
||||
};
|
||||
|
||||
struct hfi_mb_error_map {
|
||||
u32 error_map_size;
|
||||
u8 rg_error_map[1];
|
||||
};
|
||||
|
||||
struct hfi_metadata_pass_through {
|
||||
int enable;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct hfi_multi_view_select {
|
||||
u32 view_index;
|
||||
};
|
||||
|
||||
struct hfi_hybrid_hierp {
|
||||
u32 layers;
|
||||
};
|
||||
|
||||
#define HFI_PRIORITY_LOW 10
|
||||
#define HFI_PRIOIRTY_MEDIUM 20
|
||||
#define HFI_PRIORITY_HIGH 30
|
||||
|
||||
#define HFI_OUTPUT_ORDER_DISPLAY (HFI_OX_BASE + 0x1)
|
||||
#define HFI_OUTPUT_ORDER_DECODE (HFI_OX_BASE + 0x2)
|
||||
|
||||
#define HFI_RATE_CONTROL_OFF (HFI_OX_BASE + 0x1)
|
||||
#define HFI_RATE_CONTROL_VBR_VFR (HFI_OX_BASE + 0x2)
|
||||
#define HFI_RATE_CONTROL_VBR_CFR (HFI_OX_BASE + 0x3)
|
||||
#define HFI_RATE_CONTROL_CBR_VFR (HFI_OX_BASE + 0x4)
|
||||
#define HFI_RATE_CONTROL_CBR_CFR (HFI_OX_BASE + 0x5)
|
||||
#define HFI_RATE_CONTROL_MBR_CFR (HFI_OX_BASE + 0x6)
|
||||
#define HFI_RATE_CONTROL_MBR_VFR (HFI_OX_BASE + 0x7)
|
||||
|
||||
|
||||
struct hfi_uncompressed_plane_actual_constraints_info {
|
||||
u32 buffer_type;
|
||||
u32 num_planes;
|
||||
struct hfi_uncompressed_plane_constraints rg_plane_format[1];
|
||||
};
|
||||
|
||||
#define HFI_CMD_SYS_OX_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x0000)
|
||||
#define HFI_CMD_SYS_SESSION_ABORT (HFI_CMD_SYS_OX_START + 0x001)
|
||||
#define HFI_CMD_SYS_PING (HFI_CMD_SYS_OX_START + 0x002)
|
||||
|
||||
#define HFI_CMD_SESSION_OX_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x1000)
|
||||
#define HFI_CMD_SESSION_LOAD_RESOURCES (HFI_CMD_SESSION_OX_START + 0x001)
|
||||
#define HFI_CMD_SESSION_START (HFI_CMD_SESSION_OX_START + 0x002)
|
||||
#define HFI_CMD_SESSION_STOP (HFI_CMD_SESSION_OX_START + 0x003)
|
||||
#define HFI_CMD_SESSION_EMPTY_BUFFER (HFI_CMD_SESSION_OX_START + 0x004)
|
||||
#define HFI_CMD_SESSION_FILL_BUFFER (HFI_CMD_SESSION_OX_START + 0x005)
|
||||
#define HFI_CMD_SESSION_SUSPEND (HFI_CMD_SESSION_OX_START + 0x006)
|
||||
#define HFI_CMD_SESSION_RESUME (HFI_CMD_SESSION_OX_START + 0x007)
|
||||
#define HFI_CMD_SESSION_FLUSH (HFI_CMD_SESSION_OX_START + 0x008)
|
||||
#define HFI_CMD_SESSION_GET_PROPERTY (HFI_CMD_SESSION_OX_START + 0x009)
|
||||
#define HFI_CMD_SESSION_PARSE_SEQUENCE_HEADER \
|
||||
(HFI_CMD_SESSION_OX_START + 0x00A)
|
||||
#define HFI_CMD_SESSION_RELEASE_BUFFERS \
|
||||
(HFI_CMD_SESSION_OX_START + 0x00B)
|
||||
#define HFI_CMD_SESSION_RELEASE_RESOURCES \
|
||||
(HFI_CMD_SESSION_OX_START + 0x00C)
|
||||
#define HFI_CMD_SESSION_CONTINUE (HFI_CMD_SESSION_OX_START + 0x00D)
|
||||
#define HFI_CMD_SESSION_SYNC (HFI_CMD_SESSION_OX_START + 0x00E)
|
||||
|
||||
#define HFI_MSG_SYS_OX_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x0000)
|
||||
#define HFI_MSG_SYS_PING_ACK (HFI_MSG_SYS_OX_START + 0x2)
|
||||
#define HFI_MSG_SYS_SESSION_ABORT_DONE (HFI_MSG_SYS_OX_START + 0x4)
|
||||
|
||||
#define HFI_MSG_SESSION_OX_START \
|
||||
(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x1000)
|
||||
#define HFI_MSG_SESSION_LOAD_RESOURCES_DONE (HFI_MSG_SESSION_OX_START + 0x1)
|
||||
#define HFI_MSG_SESSION_START_DONE (HFI_MSG_SESSION_OX_START + 0x2)
|
||||
#define HFI_MSG_SESSION_STOP_DONE (HFI_MSG_SESSION_OX_START + 0x3)
|
||||
#define HFI_MSG_SESSION_SUSPEND_DONE (HFI_MSG_SESSION_OX_START + 0x4)
|
||||
#define HFI_MSG_SESSION_RESUME_DONE (HFI_MSG_SESSION_OX_START + 0x5)
|
||||
#define HFI_MSG_SESSION_FLUSH_DONE (HFI_MSG_SESSION_OX_START + 0x6)
|
||||
#define HFI_MSG_SESSION_EMPTY_BUFFER_DONE (HFI_MSG_SESSION_OX_START + 0x7)
|
||||
#define HFI_MSG_SESSION_FILL_BUFFER_DONE (HFI_MSG_SESSION_OX_START + 0x8)
|
||||
#define HFI_MSG_SESSION_PROPERTY_INFO (HFI_MSG_SESSION_OX_START + 0x9)
|
||||
#define HFI_MSG_SESSION_RELEASE_RESOURCES_DONE \
|
||||
(HFI_MSG_SESSION_OX_START + 0xA)
|
||||
#define HFI_MSG_SESSION_PARSE_SEQUENCE_HEADER_DONE \
|
||||
(HFI_MSG_SESSION_OX_START + 0xB)
|
||||
#define HFI_MSG_SESSION_RELEASE_BUFFERS_DONE \
|
||||
(HFI_MSG_SESSION_OX_START + 0xC)
|
||||
|
||||
#define VIDC_IFACEQ_MAX_PKT_SIZE 1024
|
||||
#define VIDC_IFACEQ_MED_PKT_SIZE 768
|
||||
#define VIDC_IFACEQ_MIN_PKT_SIZE 8
|
||||
#define VIDC_IFACEQ_VAR_SMALL_PKT_SIZE 100
|
||||
#define VIDC_IFACEQ_VAR_LARGE_PKT_SIZE 512
|
||||
#define VIDC_IFACEQ_VAR_HUGE_PKT_SIZE (1024*12)
|
||||
|
||||
|
||||
struct hfi_cmd_sys_session_abort_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct hfi_cmd_sys_ping_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 client_data;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_load_resources_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_start_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_stop_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_empty_buffer_compressed_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 time_stamp_hi;
|
||||
u32 time_stamp_lo;
|
||||
u32 flags;
|
||||
u32 mark_target;
|
||||
u32 mark_data;
|
||||
u32 offset;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 input_tag;
|
||||
u32 packet_buffer;
|
||||
u32 extra_data_buffer;
|
||||
u32 rgData[1];
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_empty_buffer_uncompressed_plane0_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 view_id;
|
||||
u32 time_stamp_hi;
|
||||
u32 time_stamp_lo;
|
||||
u32 flags;
|
||||
u32 mark_target;
|
||||
u32 mark_data;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 offset;
|
||||
u32 input_tag;
|
||||
u32 packet_buffer;
|
||||
u32 extra_data_buffer;
|
||||
u32 rgData[1];
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_empty_buffer_uncompressed_plane1_packet {
|
||||
u32 flags;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 offset;
|
||||
u32 packet_buffer2;
|
||||
u32 rgData[1];
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_empty_buffer_uncompressed_plane2_packet {
|
||||
u32 flags;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 offset;
|
||||
u32 packet_buffer3;
|
||||
u32 rgData[1];
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_fill_buffer_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 stream_id;
|
||||
u32 offset;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 output_tag;
|
||||
u32 packet_buffer;
|
||||
u32 extra_data_buffer;
|
||||
u32 rgData[1];
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_flush_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 flush_type;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_suspend_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_resume_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_get_property_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_release_buffer_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 buffer_type;
|
||||
u32 buffer_size;
|
||||
u32 extra_data_size;
|
||||
int response_req;
|
||||
u32 num_buffers;
|
||||
u32 rg_buffer_info[1];
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_release_resources_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_parse_sequence_header_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 header_len;
|
||||
u32 packet_buffer;
|
||||
};
|
||||
|
||||
struct hfi_msg_sys_session_abort_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_sys_idle_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_sys_ping_ack_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 client_data;
|
||||
};
|
||||
|
||||
struct hfi_msg_sys_property_info_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct hfi_msg_session_load_resources_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_session_start_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_session_stop_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_session_suspend_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_session_resume_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_session_flush_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
u32 flush_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_session_empty_buffer_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
u32 offset;
|
||||
u32 filled_len;
|
||||
u32 input_tag;
|
||||
u32 packet_buffer;
|
||||
u32 extra_data_buffer;
|
||||
u32 rgData[1];
|
||||
};
|
||||
|
||||
struct hfi_msg_session_fill_buffer_done_compressed_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 time_stamp_hi;
|
||||
u32 time_stamp_lo;
|
||||
u32 error_type;
|
||||
u32 flags;
|
||||
u32 mark_target;
|
||||
u32 mark_data;
|
||||
u32 stats;
|
||||
u32 offset;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 input_tag;
|
||||
u32 output_tag;
|
||||
u32 picture_type;
|
||||
u32 packet_buffer;
|
||||
u32 extra_data_buffer;
|
||||
u32 rgData[0];
|
||||
};
|
||||
|
||||
struct hfi_msg_session_fbd_uncompressed_plane0_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 stream_id;
|
||||
u32 view_id;
|
||||
u32 error_type;
|
||||
u32 time_stamp_hi;
|
||||
u32 time_stamp_lo;
|
||||
u32 flags;
|
||||
u32 mark_target;
|
||||
u32 mark_data;
|
||||
u32 stats;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 offset;
|
||||
u32 frame_width;
|
||||
u32 frame_height;
|
||||
u32 start_x_coord;
|
||||
u32 start_y_coord;
|
||||
u32 input_tag;
|
||||
u32 input_tag2;
|
||||
u32 output_tag;
|
||||
u32 picture_type;
|
||||
u32 packet_buffer;
|
||||
u32 extra_data_buffer;
|
||||
u32 rgData[0];
|
||||
};
|
||||
|
||||
struct hfi_msg_session_fill_buffer_done_uncompressed_plane1_packet {
|
||||
u32 flags;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 offset;
|
||||
u32 packet_buffer2;
|
||||
u32 rgData[0];
|
||||
};
|
||||
|
||||
struct hfi_msg_session_fill_buffer_done_uncompressed_plane2_packet {
|
||||
u32 flags;
|
||||
u32 alloc_len;
|
||||
u32 filled_len;
|
||||
u32 offset;
|
||||
u32 packet_buffer3;
|
||||
u32 rgData[0];
|
||||
};
|
||||
|
||||
struct hfi_msg_session_parse_sequence_header_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct hfi_msg_session_property_info_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 num_properties;
|
||||
u32 rg_property_data[1];
|
||||
};
|
||||
|
||||
struct hfi_msg_session_release_resources_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
};
|
||||
|
||||
struct hfi_msg_session_release_buffers_done_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
u32 error_type;
|
||||
u32 num_buffers;
|
||||
u32 rg_buffer_info[1];
|
||||
};
|
||||
|
||||
struct hfi_extradata_mb_quantization_payload {
|
||||
u8 rg_mb_qp[1];
|
||||
};
|
||||
|
||||
struct hfi_extradata_vc1_pswnd {
|
||||
u32 ps_wnd_h_offset;
|
||||
u32 ps_wnd_v_offset;
|
||||
u32 ps_wnd_width;
|
||||
u32 ps_wnd_height;
|
||||
};
|
||||
|
||||
struct hfi_extradata_vc1_framedisp_payload {
|
||||
u32 res_pic;
|
||||
u32 ref;
|
||||
u32 range_map_present;
|
||||
u32 range_map_y;
|
||||
u32 range_map_uv;
|
||||
u32 num_pan_scan_wnds;
|
||||
struct hfi_extradata_vc1_pswnd rg_ps_wnd[1];
|
||||
};
|
||||
|
||||
struct hfi_extradata_vc1_seqdisp_payload {
|
||||
u32 prog_seg_frm;
|
||||
u32 uv_sampling_fmt;
|
||||
u32 color_fmt_flag;
|
||||
u32 color_primaries;
|
||||
u32 transfer_char;
|
||||
u32 mat_coeff;
|
||||
u32 aspect_ratio;
|
||||
u32 aspect_horiz;
|
||||
u32 aspect_vert;
|
||||
};
|
||||
|
||||
struct hfi_extradata_timestamp_payload {
|
||||
u32 time_stamp_low;
|
||||
u32 time_stamp_high;
|
||||
};
|
||||
|
||||
|
||||
struct hfi_extradata_s3d_frame_packing_payload {
|
||||
u32 fpa_id;
|
||||
int cancel_flag;
|
||||
u32 fpa_type;
|
||||
int quin_cunx_flag;
|
||||
u32 content_interprtation_type;
|
||||
int spatial_flipping_flag;
|
||||
int frame0_flipped_flag;
|
||||
int field_views_flag;
|
||||
int current_frame_isFrame0_flag;
|
||||
int frame0_self_contained_flag;
|
||||
int frame1_self_contained_flag;
|
||||
u32 frame0_graid_pos_x;
|
||||
u32 frame0_graid_pos_y;
|
||||
u32 frame1_graid_pos_x;
|
||||
u32 frame1_graid_pos_y;
|
||||
u32 fpa_reserved_byte;
|
||||
u32 fpa_repetition_period;
|
||||
int fpa_extension_flag;
|
||||
};
|
||||
|
||||
struct hfi_extradata_interlace_video_payload {
|
||||
u32 format;
|
||||
};
|
||||
|
||||
struct hfi_extradata_num_concealed_mb_payload {
|
||||
u32 num_mb_concealed;
|
||||
};
|
||||
|
||||
struct hfi_extradata_sliceinfo {
|
||||
u32 offset_in_stream;
|
||||
u32 slice_length;
|
||||
};
|
||||
|
||||
struct hfi_extradata_multislice_info_payload {
|
||||
u32 num_slices;
|
||||
struct hfi_extradata_sliceinfo rg_slice_info[1];
|
||||
};
|
||||
|
||||
struct hfi_index_extradata_input_crop_payload {
|
||||
u32 size;
|
||||
u32 version;
|
||||
u32 port_index;
|
||||
u32 left;
|
||||
u32 top;
|
||||
u32 width;
|
||||
u32 height;
|
||||
};
|
||||
|
||||
struct hfi_index_extradata_output_crop_payload {
|
||||
u32 size;
|
||||
u32 version;
|
||||
u32 port_index;
|
||||
u32 left;
|
||||
u32 top;
|
||||
u32 display_width;
|
||||
u32 display_height;
|
||||
u32 width;
|
||||
u32 height;
|
||||
};
|
||||
|
||||
struct hfi_index_extradata_digital_zoom_payload {
|
||||
u32 size;
|
||||
u32 version;
|
||||
u32 port_index;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct hfi_index_extradata_aspect_ratio_payload {
|
||||
u32 size;
|
||||
u32 version;
|
||||
u32 port_index;
|
||||
u32 aspect_width;
|
||||
u32 aspect_height;
|
||||
};
|
||||
struct hfi_extradata_panscan_wndw_payload {
|
||||
u32 num_window;
|
||||
struct hfi_extradata_vc1_pswnd wnd[1];
|
||||
};
|
||||
|
||||
struct hfi_extradata_frame_type_payload {
|
||||
u32 frame_rate;
|
||||
};
|
||||
|
||||
struct hfi_extradata_recovery_point_sei_payload {
|
||||
u32 flag;
|
||||
};
|
||||
|
||||
struct hfi_cmd_session_continue_packet {
|
||||
u32 size;
|
||||
u32 packet_type;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
struct hal_session {
|
||||
struct list_head list;
|
||||
void *session_id;
|
||||
bool is_decoder;
|
||||
enum hal_video_codec codec;
|
||||
enum hal_domain domain;
|
||||
void *device;
|
||||
};
|
||||
|
||||
struct hal_device_data {
|
||||
struct list_head dev_head;
|
||||
int dev_count;
|
||||
};
|
||||
|
||||
struct msm_vidc_fw {
|
||||
void *cookie;
|
||||
};
|
||||
|
||||
int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr,
|
||||
struct msm_vidc_cb_info *info);
|
||||
|
||||
enum vidc_status hfi_process_sys_init_done_prop_read(
|
||||
struct hfi_msg_sys_init_done_packet *pkt,
|
||||
struct vidc_hal_sys_init_done *sys_init_done);
|
||||
|
||||
enum vidc_status hfi_process_session_init_done_prop_read(
|
||||
struct hfi_msg_sys_session_init_done_packet *pkt,
|
||||
struct vidc_hal_session_init_done *session_init_done);
|
||||
|
||||
#endif
|
||||
|
1551
drivers/media/platform/msm/vidc_3x/vidc_hfi_api.h
Normal file
1551
drivers/media/platform/msm/vidc_3x/vidc_hfi_api.h
Normal file
File diff suppressed because it is too large
Load diff
1185
drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h
Normal file
1185
drivers/media/platform/msm/vidc_3x/vidc_hfi_helper.h
Normal file
File diff suppressed because it is too large
Load diff
196
drivers/media/platform/msm/vidc_3x/vidc_hfi_io.h
Normal file
196
drivers/media/platform/msm/vidc_3x/vidc_hfi_io.h
Normal file
|
@ -0,0 +1,196 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2016, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __VIDC_HFI_IO_H__
|
||||
#define __VIDC_HFI_IO_H__
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
#define VENUS_VCODEC_SS_CLOCK_HALT 0x0000000C
|
||||
#define VENUS_VPP_CORE_SW_RESET 0x00042004
|
||||
#define VENUS_VPP_CTRL_CTRL_RESET 0x00041008
|
||||
|
||||
#define VIDC_VBIF_BASE_OFFS 0x00080000
|
||||
#define VIDC_VBIF_VERSION (VIDC_VBIF_BASE_OFFS + 0x00)
|
||||
#define VIDC_VENUS_VBIF_DDR_OUT_MAX_BURST \
|
||||
(VIDC_VBIF_BASE_OFFS + 0xD8)
|
||||
#define VIDC_VENUS_VBIF_OCMEM_OUT_MAX_BURST \
|
||||
(VIDC_VBIF_BASE_OFFS + 0xDC)
|
||||
#define VIDC_VENUS_VBIF_ROUND_ROBIN_QOS_ARB \
|
||||
(VIDC_VBIF_BASE_OFFS + 0x124)
|
||||
|
||||
#define VIDC_CPU_BASE_OFFS 0x000C0000
|
||||
#define VIDC_CPU_CS_BASE_OFFS (VIDC_CPU_BASE_OFFS + 0x00012000)
|
||||
#define VIDC_CPU_IC_BASE_OFFS (VIDC_CPU_BASE_OFFS + 0x0001F000)
|
||||
|
||||
#define VIDC_CPU_CS_REMAP_OFFS (VIDC_CPU_CS_BASE_OFFS + 0x00)
|
||||
#define VIDC_CPU_CS_TIMER_CONTROL (VIDC_CPU_CS_BASE_OFFS + 0x04)
|
||||
#define VIDC_CPU_CS_A2HSOFTINTEN (VIDC_CPU_CS_BASE_OFFS + 0x10)
|
||||
#define VIDC_CPU_CS_A2HSOFTINTENCLR (VIDC_CPU_CS_BASE_OFFS + 0x14)
|
||||
#define VIDC_CPU_CS_A2HSOFTINT (VIDC_CPU_CS_BASE_OFFS + 0x18)
|
||||
#define VIDC_CPU_CS_A2HSOFTINTCLR (VIDC_CPU_CS_BASE_OFFS + 0x1C)
|
||||
#define VIDC_CPU_CS_SCIACMD (VIDC_CPU_CS_BASE_OFFS + 0x48)
|
||||
|
||||
/* HFI_CTRL_STATUS */
|
||||
#define VIDC_CPU_CS_SCIACMDARG0 (VIDC_CPU_CS_BASE_OFFS + 0x4C)
|
||||
#define VIDC_CPU_CS_SCIACMDARG0_BMSK 0xff
|
||||
#define VIDC_CPU_CS_SCIACMDARG0_SHFT 0x0
|
||||
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK 0xfe
|
||||
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT 0x1
|
||||
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK 0x1
|
||||
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT 0x0
|
||||
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY 0x100
|
||||
#define VIDC_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK 0x40000000
|
||||
|
||||
/* HFI_QTBL_INFO */
|
||||
#define VIDC_CPU_CS_SCIACMDARG1 (VIDC_CPU_CS_BASE_OFFS + 0x50)
|
||||
|
||||
/* HFI_QTBL_ADDR */
|
||||
#define VIDC_CPU_CS_SCIACMDARG2 (VIDC_CPU_CS_BASE_OFFS + 0x54)
|
||||
|
||||
/* HFI_VERSION_INFO */
|
||||
#define VIDC_CPU_CS_SCIACMDARG3 (VIDC_CPU_CS_BASE_OFFS + 0x58)
|
||||
#define VIDC_CPU_IC_IRQSTATUS (VIDC_CPU_IC_BASE_OFFS + 0x00)
|
||||
#define VIDC_CPU_IC_FIQSTATUS (VIDC_CPU_IC_BASE_OFFS + 0x04)
|
||||
#define VIDC_CPU_IC_RAWINTR (VIDC_CPU_IC_BASE_OFFS + 0x08)
|
||||
#define VIDC_CPU_IC_INTSELECT (VIDC_CPU_IC_BASE_OFFS + 0x0C)
|
||||
#define VIDC_CPU_IC_INTENABLE (VIDC_CPU_IC_BASE_OFFS + 0x10)
|
||||
#define VIDC_CPU_IC_INTENACLEAR (VIDC_CPU_IC_BASE_OFFS + 0x14)
|
||||
#define VIDC_CPU_IC_SOFTINT (VIDC_CPU_IC_BASE_OFFS + 0x18)
|
||||
#define VIDC_CPU_IC_SOFTINT_H2A_BMSK 0x8000
|
||||
#define VIDC_CPU_IC_SOFTINT_H2A_SHFT 0xF
|
||||
#define VIDC_CPU_IC_SOFTINTCLEAR (VIDC_CPU_IC_BASE_OFFS + 0x1C)
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* MODULE: vidc_wrapper
|
||||
*--------------------------------------------------------------------------
|
||||
*/
|
||||
#define VIDC_WRAPPER_BASE_OFFS 0x000E0000
|
||||
|
||||
#define VIDC_WRAPPER_HW_VERSION (VIDC_WRAPPER_BASE_OFFS + 0x00)
|
||||
#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_MASK 0x78000000
|
||||
#define VIDC_WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT 28
|
||||
#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_MASK 0xFFF0000
|
||||
#define VIDC_WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT 16
|
||||
#define VIDC_WRAPPER_HW_VERSION_STEP_VERSION_MASK 0xFFFF
|
||||
#define VIDC_WRAPPER_CLOCK_CONFIG (VIDC_WRAPPER_BASE_OFFS + 0x04)
|
||||
|
||||
#define VIDC_WRAPPER_INTR_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x0C)
|
||||
#define VIDC_WRAPPER_INTR_STATUS_A2HWD_BMSK 0x10
|
||||
#define VIDC_WRAPPER_INTR_STATUS_A2HWD_SHFT 0x4
|
||||
#define VIDC_WRAPPER_INTR_STATUS_A2H_BMSK 0x4
|
||||
#define VIDC_WRAPPER_INTR_STATUS_A2H_SHFT 0x2
|
||||
|
||||
#define VIDC_WRAPPER_INTR_MASK (VIDC_WRAPPER_BASE_OFFS + 0x10)
|
||||
#define VIDC_WRAPPER_INTR_MASK_A2HWD_BMSK 0x10
|
||||
#define VIDC_WRAPPER_INTR_MASK_A2HWD_SHFT 0x4
|
||||
#define VIDC_WRAPPER_INTR_MASK_A2HVCODEC_BMSK 0x8
|
||||
#define VIDC_WRAPPER_INTR_MASK_A2HVCODEC_SHFT 0x3
|
||||
#define VIDC_WRAPPER_INTR_MASK_A2HCPU_BMSK 0x4
|
||||
#define VIDC_WRAPPER_INTR_MASK_A2HCPU_SHFT 0x2
|
||||
|
||||
#define VIDC_WRAPPER_INTR_CLEAR (VIDC_WRAPPER_BASE_OFFS + 0x14)
|
||||
#define VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK 0x10
|
||||
#define VIDC_WRAPPER_INTR_CLEAR_A2HWD_SHFT 0x4
|
||||
#define VIDC_WRAPPER_INTR_CLEAR_A2H_BMSK 0x4
|
||||
#define VIDC_WRAPPER_INTR_CLEAR_A2H_SHFT 0x2
|
||||
|
||||
#define VIDC_WRAPPER_VBIF_XIN_SW_RESET (VIDC_WRAPPER_BASE_OFFS + 0x18)
|
||||
#define VIDC_WRAPPER_VBIF_XIN_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x1C)
|
||||
#define VIDC_WRAPPER_CPU_CLOCK_CONFIG (VIDC_WRAPPER_BASE_OFFS + 0x2000)
|
||||
#define VIDC_WRAPPER_VBIF_XIN_CPU_SW_RESET \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x2004)
|
||||
#define VIDC_WRAPPER_AXI_HALT (VIDC_WRAPPER_BASE_OFFS + 0x2008)
|
||||
#define VIDC_WRAPPER_AXI_HALT_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x200C)
|
||||
#define VIDC_WRAPPER_CPU_CGC_DIS (VIDC_WRAPPER_BASE_OFFS + 0x2010)
|
||||
#define VIDC_WRAPPER_CPU_STATUS (VIDC_WRAPPER_BASE_OFFS + 0x2014)
|
||||
#define VIDC_VENUS_VBIF_CLK_ON (VIDC_VBIF_BASE_OFFS + 0x4)
|
||||
#define VIDC_VBIF_IN_RD_LIM_CONF0 (VIDC_VBIF_BASE_OFFS + 0xB0)
|
||||
#define VIDC_VBIF_IN_RD_LIM_CONF1 (VIDC_VBIF_BASE_OFFS + 0xB4)
|
||||
#define VIDC_VBIF_IN_RD_LIM_CONF2 (VIDC_VBIF_BASE_OFFS + 0xB8)
|
||||
#define VIDC_VBIF_IN_RD_LIM_CONF3 (VIDC_VBIF_BASE_OFFS + 0xBC)
|
||||
#define VIDC_VBIF_IN_WR_LIM_CONF0 (VIDC_VBIF_BASE_OFFS + 0xC0)
|
||||
#define VIDC_VBIF_IN_WR_LIM_CONF1 (VIDC_VBIF_BASE_OFFS + 0xC4)
|
||||
#define VIDC_VBIF_IN_WR_LIM_CONF2 (VIDC_VBIF_BASE_OFFS + 0xC8)
|
||||
#define VIDC_VBIF_IN_WR_LIM_CONF3 (VIDC_VBIF_BASE_OFFS + 0xCC)
|
||||
#define VIDC_VBIF_OUT_RD_LIM_CONF0 (VIDC_VBIF_BASE_OFFS + 0xD0)
|
||||
#define VIDC_VBIF_OUT_WR_LIM_CONF0 (VIDC_VBIF_BASE_OFFS + 0xD4)
|
||||
#define VIDC_VBIF_DDR_OUT_MAX_BURST (VIDC_VBIF_BASE_OFFS + 0xD8)
|
||||
#define VIDC_VBIF_OCMEM_OUT_MAX_BURST (VIDC_VBIF_BASE_OFFS + 0xDC)
|
||||
#define VIDC_VBIF_DDR_ARB_CONF0 (VIDC_VBIF_BASE_OFFS + 0xF4)
|
||||
#define VIDC_VBIF_DDR_ARB_CONF1 (VIDC_VBIF_BASE_OFFS + 0xF8)
|
||||
#define VIDC_VBIF_ROUND_ROBIN_QOS_ARB (VIDC_VBIF_BASE_OFFS + 0x124)
|
||||
#define VIDC_VBIF_OUT_AXI_AOOO_EN (VIDC_VBIF_BASE_OFFS + 0x178)
|
||||
#define VIDC_VBIF_OUT_AXI_AOOO (VIDC_VBIF_BASE_OFFS + 0x17C)
|
||||
#define VIDC_VBIF_ARB_CTL (VIDC_VBIF_BASE_OFFS + 0xF0)
|
||||
#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF0 (VIDC_VBIF_BASE_OFFS + 0x160)
|
||||
#define VIDC_VBIF_OUT_AXI_AMEMTYPE_CONF1 (VIDC_VBIF_BASE_OFFS + 0x164)
|
||||
#define VIDC_VBIF_ADDR_TRANS_EN (VIDC_VBIF_BASE_OFFS + 0xC00)
|
||||
#define VIDC_VBIF_AT_OLD_BASE (VIDC_VBIF_BASE_OFFS + 0xC04)
|
||||
#define VIDC_VBIF_AT_OLD_HIGH (VIDC_VBIF_BASE_OFFS + 0xC08)
|
||||
#define VIDC_VBIF_AT_NEW_BASE (VIDC_VBIF_BASE_OFFS + 0xC10)
|
||||
#define VIDC_VBIF_AT_NEW_HIGH (VIDC_VBIF_BASE_OFFS + 0xC18)
|
||||
#define VENUS_VBIF_XIN_HALT_CTRL1 (VIDC_VBIF_BASE_OFFS + 0x204)
|
||||
#define VENUS_VBIF_AXI_HALT_CTRL0 (VIDC_VBIF_BASE_OFFS + 0x208)
|
||||
#define VENUS_VBIF_AXI_HALT_CTRL1 (VIDC_VBIF_BASE_OFFS + 0x20C)
|
||||
|
||||
#define VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ BIT(0)
|
||||
#define VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK BIT(0)
|
||||
#define VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US 500000
|
||||
|
||||
#define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x20)
|
||||
#define VIDC_VENUS0_WRAPPER_VBIF_PRIORITY_LEVEL \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x24)
|
||||
#define VIDC_VENUS_WRAPPER_MMCC_VENUS0_POWER_STATUS \
|
||||
(VIDC_WRAPPER_BASE_OFFS + 0x44)
|
||||
|
||||
#define VIDC_CTRL_INIT 0x000D2048
|
||||
#define VIDC_CTRL_INIT_RESERVED_BITS31_1__M 0xFFFFFFFE
|
||||
#define VIDC_CTRL_INIT_RESERVED_BITS31_1__S 1
|
||||
#define VIDC_CTRL_INIT_CTRL__M 0x00000001
|
||||
#define VIDC_CTRL_INIT_CTRL__S 0
|
||||
|
||||
#define VIDC_CTRL_STATUS 0x000D204C
|
||||
#define VIDC_CTRL_STATUS_RESERVED_BITS31_8__M 0xFFFFFF00
|
||||
#define VIDC_CTRL_STATUS_RESERVED_BITS31_8__S 8
|
||||
#define VIDC_CTRL_ERROR_STATUS__M 0x000000FE
|
||||
#define VIDC_CTRL_ERROR_STATUS__S 1
|
||||
#define VIDC_CTRL_INIT_STATUS__M 0x00000001
|
||||
#define VIDC_CTRL_INIT_STATUS__S 0
|
||||
|
||||
#define VIDC_QTBL_INFO 0x000D2050
|
||||
#define VIDC_QTBL_HOSTID__M 0xFF000000
|
||||
#define VIDC_QTBL_HOSTID__S 24
|
||||
#define VIDC_QTBL_INFO_RESERVED_BITS23_8__M 0x00FFFF00
|
||||
#define VIDC_QTBL_INFO_RESERVED_BITS23_8__S 8
|
||||
#define VIDC_QTBL_STATUS__M 0x000000FF
|
||||
#define VIDC_QTBL_STATUS__S 0
|
||||
|
||||
#define VIDC_QTBL_ADDR 0x000D2054
|
||||
|
||||
#define VIDC_VERSION_INFO 0x000D2058
|
||||
#define VIDC_VERSION_INFO_MAJOR__M 0xF0000000
|
||||
#define VIDC_VERSION_INFO_MAJOR__S 28
|
||||
#define VIDC_VERSION_INFO_MINOR__M 0x0FFFFFE0
|
||||
#define VIDC_VERSION_INFO_MINOR__S 5
|
||||
#define VIDC_VERSION_INFO_BRANCH__M 0x0000001F
|
||||
#define VIDC_VERSION_INFO_BRANCH__S 0
|
||||
|
||||
#define VIDC_SFR_ADDR 0x000D205C
|
||||
#define VIDC_MMAP_ADDR 0x000D2060
|
||||
#define VIDC_UC_REGION_ADDR 0x000D2064
|
||||
#define VIDC_UC_REGION_SIZE 0x000D2068
|
||||
|
||||
#endif
|
4
drivers/media/platform/msm/vidc_3x/vmem/Kconfig
Normal file
4
drivers/media/platform/msm/vidc_3x/vmem/Kconfig
Normal file
|
@ -0,0 +1,4 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
menuconfig MSM_VIDC_VMEM
|
||||
bool "Qualcomm Technologies Inc MSM VMEM driver"
|
||||
depends on ARCH_MSM && MSM_VIDC_V4L2
|
3
drivers/media/platform/msm/vidc_3x/vmem/Makefile
Normal file
3
drivers/media/platform/msm/vidc_3x/vmem/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_MSM_VIDC_VMEM) := vmem.o \
|
||||
vmem_debugfs.o
|
699
drivers/media/platform/msm/vidc_3x/vmem/vmem.c
Normal file
699
drivers/media/platform/msm/vidc_3x/vmem/vmem.c
Normal file
|
@ -0,0 +1,699 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2014-2016, 2018-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/msm-bus.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include "vmem.h"
|
||||
#include "vmem_debugfs.h"
|
||||
|
||||
/* Registers */
|
||||
#define OCIMEM_BASE(v) ((uint8_t *)(v)->reg.base)
|
||||
#define OCIMEM_HW_VERSION(v) (OCIMEM_BASE(v) + 0x00)
|
||||
#define OCIMEM_HW_PROFILE(v) (OCIMEM_BASE(v) + 0x04)
|
||||
#define OCIMEM_GEN_CTL(v) (OCIMEM_BASE(v) + 0x08)
|
||||
#define OCIMEM_GEN_STAT(v) (OCIMEM_BASE(v) + 0x0C)
|
||||
#define OCIMEM_INTC_CLR(v) (OCIMEM_BASE(v) + 0x10)
|
||||
#define OCIMEM_INTC_MASK(v) (OCIMEM_BASE(v) + 0x14)
|
||||
#define OCIMEM_INTC_STAT(v) (OCIMEM_BASE(v) + 0x18)
|
||||
#define OCIMEM_OSW_STATUS(v) (OCIMEM_BASE(v) + 0x1C)
|
||||
#define OCIMEM_PSCGC_TIMERS(v) (OCIMEM_BASE(v) + 0x34)
|
||||
#define OCIMEM_PSCGC_STAT(v) (OCIMEM_BASE(v) + 0x38)
|
||||
#define OCIMEM_PSCGC_M0_M7_CTL(v) (OCIMEM_BASE(v) + 0x3C)
|
||||
#define OCIMEM_ERR_ADDRESS(v) (OCIMEM_BASE(v) + 0x60)
|
||||
#define OCIMEM_AXI_ERR_SYNDROME(v) (OCIMEM_BASE(v) + 0x64)
|
||||
#define OCIMEM_DEBUG_CTL(v) (OCIMEM_BASE(v) + 0x68)
|
||||
|
||||
/*
|
||||
* Helper macro to help out with masks and shifts for values packed into
|
||||
* registers.
|
||||
*/
|
||||
#define DECLARE_TYPE(__type, __end, __start) \
|
||||
static const unsigned int __type##_BITS = (__end) - (__start) + 1; \
|
||||
static const unsigned int __type##_SHIFT = (__start); \
|
||||
static const unsigned int __type##_MASK = GENMASK((__end), (__start)); \
|
||||
static inline unsigned int __type(uint32_t val) \
|
||||
{ \
|
||||
return (val & __type##_MASK) >> __type##_SHIFT; \
|
||||
} \
|
||||
static inline uint32_t __type##_UPDATE(unsigned int val) \
|
||||
{ \
|
||||
return (val << __type##_SHIFT) & __type##_MASK; \
|
||||
}
|
||||
|
||||
/* Register masks */
|
||||
/* OCIMEM_PSCGC_M0_M7_CTL */
|
||||
DECLARE_TYPE(BANK0_STATE, 3, 0);
|
||||
DECLARE_TYPE(BANK1_STATE, 7, 4);
|
||||
DECLARE_TYPE(BANK2_STATE, 11, 8);
|
||||
DECLARE_TYPE(BANK3_STATE, 15, 12);
|
||||
/* OCIMEM_PSCGC_TIMERS */
|
||||
DECLARE_TYPE(TIMERS_WAKEUP, 3, 0);
|
||||
DECLARE_TYPE(TIMERS_SLEEP, 11, 8);
|
||||
/* OCIMEM_HW_VERSION */
|
||||
DECLARE_TYPE(VERSION_STEP, 15, 0);
|
||||
DECLARE_TYPE(VERSION_MINOR, 27, 16);
|
||||
DECLARE_TYPE(VERSION_MAJOR, 31, 28);
|
||||
/* OCIMEM_HW_PROFILE */
|
||||
DECLARE_TYPE(PROFILE_BANKS, 16, 12);
|
||||
/* OCIMEM_AXI_ERR_SYNDROME */
|
||||
DECLARE_TYPE(ERR_SYN_ATID, 14, 8);
|
||||
DECLARE_TYPE(ERR_SYN_AMID, 23, 16);
|
||||
DECLARE_TYPE(ERR_SYN_APID, 28, 24);
|
||||
DECLARE_TYPE(ERR_SYN_ABID, 31, 29);
|
||||
/* OCIMEM_INTC_MASK */
|
||||
DECLARE_TYPE(AXI_ERR_INT, 0, 0);
|
||||
|
||||
/* Internal stuff */
|
||||
#define MAX_BANKS 4
|
||||
|
||||
enum bank_state {
|
||||
BANK_STATE_NORM_PASSTHRU = 0,
|
||||
BANK_STATE_NORM_FORCE_CORE_ON = 2,
|
||||
BANK_STATE_NORM_FORCE_PERIPH_ON = 1,
|
||||
BANK_STATE_NORM_FORCE_ALL_ON = 3,
|
||||
BANK_STATE_SLEEP_RET = 6,
|
||||
BANK_STATE_SLEEP_RET_PERIPH_ON = 7,
|
||||
BANK_STATE_SLEEP_NO_RET = 4,
|
||||
};
|
||||
|
||||
struct vmem {
|
||||
int irq;
|
||||
int num_banks;
|
||||
int bank_size;
|
||||
struct {
|
||||
struct resource *resource;
|
||||
void __iomem *base;
|
||||
} reg, mem;
|
||||
struct regulator *vdd;
|
||||
struct {
|
||||
const char *name;
|
||||
struct clk *clk;
|
||||
} *clocks;
|
||||
int num_clocks;
|
||||
struct {
|
||||
struct msm_bus_scale_pdata *pdata;
|
||||
uint32_t priv;
|
||||
} bus;
|
||||
atomic_t alloc_count;
|
||||
struct dentry *debugfs_root;
|
||||
};
|
||||
|
||||
static struct vmem *vmem;
|
||||
|
||||
static inline u32 __readl(void * __iomem addr)
|
||||
{
|
||||
u32 value = 0;
|
||||
|
||||
pr_debug("read %pK\n", addr);
|
||||
value = readl_relaxed(addr);
|
||||
pr_debug("-> %08x\n", value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline void __writel(u32 val, void * __iomem addr)
|
||||
{
|
||||
pr_debug("write %08x -> %pK\n", val, addr);
|
||||
writel_relaxed(val, addr);
|
||||
/*
|
||||
* Commit all writes via a mem barrier, as subsequent __readl()
|
||||
* will depend on the state that's set via __writel().
|
||||
*/
|
||||
mb();
|
||||
}
|
||||
|
||||
static inline void __wait_timer(struct vmem *v, bool wakeup)
|
||||
{
|
||||
uint32_t ticks = 0;
|
||||
unsigned int (*timer)(uint32_t) = wakeup ?
|
||||
TIMERS_WAKEUP : TIMERS_SLEEP;
|
||||
|
||||
ticks = timer(__readl(OCIMEM_PSCGC_TIMERS(v)));
|
||||
|
||||
/* Sleep for `ticks` nanoseconds as per h/w spec */
|
||||
ndelay(ticks);
|
||||
}
|
||||
|
||||
static inline void __wait_wakeup(struct vmem *v)
|
||||
{
|
||||
return __wait_timer(v, true);
|
||||
}
|
||||
|
||||
static inline void __wait_sleep(struct vmem *v)
|
||||
{
|
||||
return __wait_timer(v, false);
|
||||
}
|
||||
|
||||
static inline int __power_on(struct vmem *v)
|
||||
{
|
||||
int rc = 0, c = 0;
|
||||
|
||||
rc = msm_bus_scale_client_update_request(v->bus.priv, 1);
|
||||
if (rc) {
|
||||
pr_err("Failed to vote for buses (%d)\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
pr_debug("Voted for buses\n");
|
||||
|
||||
rc = regulator_enable(v->vdd);
|
||||
if (rc) {
|
||||
pr_err("Failed to power on gdsc (%d)\n", rc);
|
||||
goto unvote_bus;
|
||||
}
|
||||
pr_debug("Enabled regulator vdd\n");
|
||||
|
||||
for (c = 0; c < v->num_clocks; ++c) {
|
||||
rc = clk_prepare_enable(v->clocks[c].clk);
|
||||
if (rc) {
|
||||
pr_err("Failed to enable %s clock (%d)\n",
|
||||
v->clocks[c].name, rc);
|
||||
goto disable_clocks;
|
||||
}
|
||||
|
||||
pr_debug("Enabled clock %s\n", v->clocks[c].name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
disable_clocks:
|
||||
for (--c; c >= 0; c--)
|
||||
clk_disable_unprepare(v->clocks[c].clk);
|
||||
regulator_disable(v->vdd);
|
||||
unvote_bus:
|
||||
msm_bus_scale_client_update_request(v->bus.priv, 0);
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int __power_off(struct vmem *v)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
for (c = 0; c < v->num_clocks; ++c) {
|
||||
clk_disable_unprepare(v->clocks[c].clk);
|
||||
pr_debug("Disabled clock %s\n", v->clocks[c].name);
|
||||
}
|
||||
|
||||
regulator_disable(v->vdd);
|
||||
pr_debug("Disabled regulator vdd\n");
|
||||
|
||||
msm_bus_scale_client_update_request(v->bus.priv, 0);
|
||||
pr_debug("Unvoted for buses\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline enum bank_state __bank_get_state(struct vmem *v,
|
||||
unsigned int bank)
|
||||
{
|
||||
unsigned int (*func[MAX_BANKS])(uint32_t) = {
|
||||
BANK0_STATE, BANK1_STATE, BANK2_STATE, BANK3_STATE
|
||||
};
|
||||
|
||||
WARN_ON(bank >= ARRAY_SIZE(func));
|
||||
return func[bank](__readl(OCIMEM_PSCGC_M0_M7_CTL(v)));
|
||||
}
|
||||
|
||||
static inline void __bank_set_state(struct vmem *v, unsigned int bank,
|
||||
enum bank_state state)
|
||||
{
|
||||
uint32_t bank_state = 0;
|
||||
struct {
|
||||
uint32_t (*update)(unsigned int b);
|
||||
uint32_t mask;
|
||||
} banks[MAX_BANKS] = {
|
||||
{BANK0_STATE_UPDATE, BANK0_STATE_MASK},
|
||||
{BANK1_STATE_UPDATE, BANK1_STATE_MASK},
|
||||
{BANK2_STATE_UPDATE, BANK2_STATE_MASK},
|
||||
{BANK3_STATE_UPDATE, BANK3_STATE_MASK},
|
||||
};
|
||||
|
||||
WARN_ON(bank >= ARRAY_SIZE(banks));
|
||||
|
||||
bank_state = __readl(OCIMEM_PSCGC_M0_M7_CTL(v));
|
||||
bank_state &= ~banks[bank].mask;
|
||||
bank_state |= banks[bank].update(state);
|
||||
|
||||
__writel(bank_state, OCIMEM_PSCGC_M0_M7_CTL(v));
|
||||
}
|
||||
|
||||
static inline void __toggle_interrupts(struct vmem *v, bool enable)
|
||||
{
|
||||
uint32_t ints = __readl(OCIMEM_INTC_MASK(v)),
|
||||
mask = AXI_ERR_INT_MASK,
|
||||
update = AXI_ERR_INT_UPDATE(!enable);
|
||||
|
||||
ints &= ~mask;
|
||||
ints |= update;
|
||||
|
||||
__writel(ints, OCIMEM_INTC_MASK(v));
|
||||
}
|
||||
|
||||
static void __enable_interrupts(struct vmem *v)
|
||||
{
|
||||
pr_debug("Enabling interrupts\n");
|
||||
enable_irq(v->irq);
|
||||
__toggle_interrupts(v, true);
|
||||
}
|
||||
|
||||
static void __disable_interrupts(struct vmem *v)
|
||||
{
|
||||
pr_debug("Disabling interrupts\n");
|
||||
__toggle_interrupts(v, false);
|
||||
disable_irq_nosync(v->irq);
|
||||
}
|
||||
|
||||
/**
|
||||
* vmem_allocate: - Allocates memory from VMEM. Allocations have a few
|
||||
* restrictions: only allocations of the entire VMEM memory are allowed, and
|
||||
* , as a result, only single outstanding allocations are allowed.
|
||||
*
|
||||
* @size: amount of bytes to allocate
|
||||
* @addr: A pointer to phys_addr_t where the physical address of the memory
|
||||
* allocated is stored.
|
||||
*
|
||||
* Return: 0 in case of successful allocation (i.e. *addr != NULL). -ENOTSUPP,
|
||||
* if platform doesn't support VMEM. -EEXIST, if there are outstanding VMEM
|
||||
* allocations. -ENOMEM, if platform can't support allocation of `size` bytes.
|
||||
* -EAGAIN, if `size` does not allocate the entire VMEM region. -EIO in case of
|
||||
* internal errors.
|
||||
*/
|
||||
int vmem_allocate(size_t size, phys_addr_t *addr)
|
||||
{
|
||||
int rc = 0, c = 0;
|
||||
resource_size_t max_size = 0;
|
||||
|
||||
if (!vmem) {
|
||||
pr_err("No vmem, try rebooting your device\n");
|
||||
rc = -ENOTSUPP;
|
||||
goto exit;
|
||||
}
|
||||
if (!size) {
|
||||
pr_err("%s Invalid size %ld\n", __func__, size);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
max_size = resource_size(vmem->mem.resource);
|
||||
|
||||
if (atomic_read(&vmem->alloc_count)) {
|
||||
pr_err("Only single allocations allowed for vmem\n");
|
||||
rc = -EEXIST;
|
||||
goto exit;
|
||||
} else if (size > max_size) {
|
||||
pr_err("Out of memory, have max %pa\n", &max_size);
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
} else if (size != max_size) {
|
||||
pr_err("Only support allocations of size %pa\n", &max_size);
|
||||
rc = -EAGAIN;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = __power_on(vmem);
|
||||
if (rc) {
|
||||
pr_err("Failed power on (%d)\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
WARN_ON(vmem->num_banks != DIV_ROUND_UP(size, vmem->bank_size));
|
||||
|
||||
/* Turn on the necessary banks */
|
||||
for (c = 0; c < vmem->num_banks; ++c) {
|
||||
__bank_set_state(vmem, c, BANK_STATE_NORM_FORCE_CORE_ON);
|
||||
__wait_wakeup(vmem);
|
||||
}
|
||||
|
||||
/* Enable interrupts to detect faults */
|
||||
__enable_interrupts(vmem);
|
||||
|
||||
atomic_inc(&vmem->alloc_count);
|
||||
*addr = (phys_addr_t)vmem->mem.resource->start;
|
||||
return 0;
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmem_free: - Frees the memory allocated via vmem_allocate. Undefined
|
||||
* behaviour if to_free is a not a pointer returned via vmem_allocate
|
||||
*/
|
||||
void vmem_free(phys_addr_t to_free)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
if (!to_free || !vmem)
|
||||
return;
|
||||
|
||||
WARN_ON(atomic_read(&vmem->alloc_count) == 0);
|
||||
|
||||
for (c = 0; c < vmem->num_banks; ++c) {
|
||||
enum bank_state curr_state = __bank_get_state(vmem, c);
|
||||
|
||||
if (curr_state != BANK_STATE_NORM_FORCE_CORE_ON) {
|
||||
pr_warn("When freeing, expected bank state to be %d, was instead %d\n",
|
||||
BANK_STATE_NORM_FORCE_CORE_ON,
|
||||
curr_state);
|
||||
}
|
||||
|
||||
__bank_set_state(vmem, c, BANK_STATE_SLEEP_NO_RET);
|
||||
}
|
||||
|
||||
__disable_interrupts(vmem);
|
||||
__power_off(vmem);
|
||||
atomic_dec(&vmem->alloc_count);
|
||||
}
|
||||
|
||||
struct vmem_interrupt_cookie {
|
||||
struct vmem *vmem;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
static void __irq_helper(struct work_struct *work)
|
||||
{
|
||||
struct vmem_interrupt_cookie *cookie = container_of(work,
|
||||
struct vmem_interrupt_cookie, work);
|
||||
struct vmem *v = cookie->vmem;
|
||||
unsigned int stat, gen_stat, pscgc_stat, err_addr_abs,
|
||||
err_addr_rel, err_syn;
|
||||
|
||||
stat = __readl(OCIMEM_INTC_STAT(v));
|
||||
gen_stat = __readl(OCIMEM_GEN_CTL(v));
|
||||
pscgc_stat = __readl(OCIMEM_PSCGC_STAT(v));
|
||||
|
||||
err_addr_abs = __readl(OCIMEM_ERR_ADDRESS(v));
|
||||
err_addr_rel = v->mem.resource->start - err_addr_abs;
|
||||
|
||||
err_syn = __readl(OCIMEM_AXI_ERR_SYNDROME(v));
|
||||
|
||||
pr_crit("Detected a fault on VMEM:\n");
|
||||
pr_debug("\tinterrupt status: %x\n", stat);
|
||||
pr_debug("\tgeneral status: %x\n", gen_stat);
|
||||
pr_debug("\tmemory status: %x\n", pscgc_stat);
|
||||
pr_debug("\tfault address: %x (absolute), %x (relative)\n",
|
||||
err_addr_abs, err_addr_rel);
|
||||
pr_debug("\tfault bank: %x\n", err_addr_rel / v->bank_size);
|
||||
pr_debug("\tfault core: %u (mid), %u (pid), %u (bid)\n",
|
||||
ERR_SYN_AMID(err_syn), ERR_SYN_APID(err_syn),
|
||||
ERR_SYN_ABID(err_syn));
|
||||
|
||||
/* Clear the interrupt */
|
||||
__writel(0, OCIMEM_INTC_CLR(v));
|
||||
|
||||
__enable_interrupts(v);
|
||||
}
|
||||
|
||||
static struct vmem_interrupt_cookie interrupt_cookie;
|
||||
|
||||
static irqreturn_t __irq_handler(int irq, void *cookie)
|
||||
{
|
||||
struct vmem *v = cookie;
|
||||
irqreturn_t status = __readl(OCIMEM_INTC_STAT(vmem)) ?
|
||||
IRQ_HANDLED : IRQ_NONE;
|
||||
|
||||
if (status != IRQ_NONE) {
|
||||
/* Mask further interrupts while handling this one */
|
||||
__disable_interrupts(v);
|
||||
|
||||
interrupt_cookie.vmem = v;
|
||||
INIT_WORK(&interrupt_cookie.work, __irq_helper);
|
||||
schedule_work(&interrupt_cookie.work);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static inline int __init_resources(struct vmem *v,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
int rc = 0, c = 0;
|
||||
|
||||
v->irq = platform_get_irq(pdev, 0);
|
||||
if (v->irq < 0) {
|
||||
rc = v->irq;
|
||||
pr_err("Failed to get irq (%d)\n", rc);
|
||||
v->irq = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Registers and memory */
|
||||
v->reg.resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"reg-base");
|
||||
if (!v->reg.resource) {
|
||||
pr_err("Failed to find register base\n");
|
||||
rc = -ENOENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
v->reg.base = devm_ioremap_resource(&pdev->dev, v->reg.resource);
|
||||
if (IS_ERR_OR_NULL(v->reg.base)) {
|
||||
rc = PTR_ERR(v->reg.base) ?: -EIO;
|
||||
pr_err("Failed to map register base into kernel (%d)\n", rc);
|
||||
v->reg.base = NULL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pr_debug("Register range: %pa -> %pa\n", &v->reg.resource->start,
|
||||
&v->reg.resource->end);
|
||||
|
||||
v->mem.resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
"mem-base");
|
||||
if (!v->mem.resource) {
|
||||
pr_err("Failed to find memory base\n");
|
||||
rc = -ENOENT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
v->mem.base = NULL;
|
||||
pr_debug("Memory range: %pa -> %pa\n", &v->mem.resource->start,
|
||||
&v->mem.resource->end);
|
||||
|
||||
/* Buses, Clocks & Regulators*/
|
||||
v->num_clocks = of_property_count_strings(pdev->dev.of_node,
|
||||
"clock-names");
|
||||
if (v->num_clocks <= 0) {
|
||||
pr_err("Can't find any clocks\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
v->clocks = devm_kzalloc(&pdev->dev, sizeof(*v->clocks) * v->num_clocks,
|
||||
GFP_KERNEL);
|
||||
if (!v->clocks) {
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (c = 0; c < v->num_clocks; ++c) {
|
||||
const char *name = NULL;
|
||||
struct clk *temp = NULL;
|
||||
|
||||
of_property_read_string_index(pdev->dev.of_node, "clock-names",
|
||||
c, &name);
|
||||
temp = devm_clk_get(&pdev->dev, name);
|
||||
if (IS_ERR_OR_NULL(temp)) {
|
||||
rc = PTR_ERR(temp) ?: -ENOENT;
|
||||
pr_err("Failed to find %s (%d)\n", name, rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
v->clocks[c].clk = temp;
|
||||
v->clocks[c].name = name;
|
||||
}
|
||||
|
||||
v->vdd = devm_regulator_get(&pdev->dev, "vdd");
|
||||
if (IS_ERR_OR_NULL(v->vdd)) {
|
||||
rc = PTR_ERR(v->vdd) ?: -ENOENT;
|
||||
pr_err("Failed to find regulator (vdd) (%d)\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
v->bus.pdata = msm_bus_cl_get_pdata(pdev);
|
||||
if (IS_ERR_OR_NULL(v->bus.pdata)) {
|
||||
rc = PTR_ERR(v->bus.pdata) ?: -ENOENT;
|
||||
pr_err("Failed to find bus vectors (%d)\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
v->bus.priv = msm_bus_scale_register_client(v->bus.pdata);
|
||||
if (!v->bus.priv) {
|
||||
rc = -EBADHANDLE;
|
||||
pr_err("Failed to register bus client\n");
|
||||
goto free_pdata;
|
||||
}
|
||||
|
||||
/* Misc. */
|
||||
rc = of_property_read_u32(pdev->dev.of_node, "qcom,bank-size",
|
||||
&v->bank_size);
|
||||
if (rc || !v->bank_size) {
|
||||
pr_err("Failed reading (or found invalid) qcom,bank-size in %s (%d)\n",
|
||||
of_node_full_name(pdev->dev.of_node), rc);
|
||||
rc = -ENOENT;
|
||||
goto free_pdata;
|
||||
}
|
||||
|
||||
v->num_banks = resource_size(v->mem.resource) / v->bank_size;
|
||||
|
||||
pr_debug("Found configuration with %d banks with size %d\n",
|
||||
v->num_banks, v->bank_size);
|
||||
|
||||
return 0;
|
||||
free_pdata:
|
||||
msm_bus_cl_clear_pdata(v->bus.pdata);
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline void __uninit_resources(struct vmem *v,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
msm_bus_cl_clear_pdata(v->bus.pdata);
|
||||
v->bus.pdata = NULL;
|
||||
v->bus.priv = 0;
|
||||
|
||||
for (c = 0; c < v->num_clocks; ++c) {
|
||||
v->clocks[c].clk = NULL;
|
||||
v->clocks[c].name = NULL;
|
||||
}
|
||||
|
||||
v->vdd = NULL;
|
||||
}
|
||||
|
||||
static int vmem_probe(struct platform_device *pdev)
|
||||
{
|
||||
uint32_t version = 0, num_banks = 0, rc = 0;
|
||||
struct vmem *v = NULL;
|
||||
|
||||
if (vmem) {
|
||||
pr_err("Only one instance of %s allowed\n", pdev->name);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
v = devm_kzalloc(&pdev->dev, sizeof(*v), GFP_KERNEL);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = __init_resources(v, pdev);
|
||||
if (rc) {
|
||||
pr_err("Failed to read resources\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* For now, only support up to 4 banks. It's unrealistic that VMEM has
|
||||
* more banks than that (even in the future).
|
||||
*/
|
||||
if (v->num_banks > MAX_BANKS) {
|
||||
pr_err("Number of banks (%d) exceeds what's supported (%d)\n",
|
||||
v->num_banks, MAX_BANKS);
|
||||
rc = -ENOTSUPP;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Cross check the platform resources with what's available on chip */
|
||||
rc = __power_on(v);
|
||||
if (rc) {
|
||||
pr_err("Failed to power on (%d)\n", rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
version = __readl(OCIMEM_HW_VERSION(v));
|
||||
pr_debug("v%d.%d.%d\n", VERSION_MAJOR(version), VERSION_MINOR(version),
|
||||
VERSION_STEP(version));
|
||||
|
||||
num_banks = PROFILE_BANKS(__readl(OCIMEM_HW_PROFILE(v)));
|
||||
pr_debug("Found %d banks on chip\n", num_banks);
|
||||
if (v->num_banks != num_banks) {
|
||||
pr_err("Platform configuration of %d banks differs from what's available on chip (%d)\n",
|
||||
v->num_banks, num_banks);
|
||||
rc = -EINVAL;
|
||||
goto disable_clocks;
|
||||
}
|
||||
|
||||
rc = devm_request_irq(&pdev->dev, v->irq, __irq_handler,
|
||||
IRQF_TRIGGER_HIGH, "vmem", v);
|
||||
if (rc) {
|
||||
pr_err("Failed to setup irq (%d)\n", rc);
|
||||
goto disable_clocks;
|
||||
}
|
||||
|
||||
__disable_interrupts(v);
|
||||
|
||||
/* Everything good so far, set up the global context and debug hooks */
|
||||
pr_info("Up and running with %d banks of memory from %pR\n",
|
||||
v->num_banks, &v->mem.resource);
|
||||
v->debugfs_root = vmem_debugfs_init(pdev);
|
||||
platform_set_drvdata(pdev, v);
|
||||
vmem = v;
|
||||
|
||||
disable_clocks:
|
||||
__power_off(v);
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int vmem_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct vmem *v = platform_get_drvdata(pdev);
|
||||
|
||||
WARN_ON(v != vmem);
|
||||
|
||||
__uninit_resources(v, pdev);
|
||||
vmem_debugfs_deinit(v->debugfs_root);
|
||||
vmem = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id vmem_of_match[] = {
|
||||
{.compatible = "qcom,msm-vmem"},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, vmem_of_match);
|
||||
|
||||
static struct platform_driver vmem_driver = {
|
||||
.probe = vmem_probe,
|
||||
.remove = vmem_remove,
|
||||
.driver = {
|
||||
.name = "msm_vidc_vmem",
|
||||
.of_match_table = vmem_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init vmem_init(void)
|
||||
{
|
||||
return platform_driver_register(&vmem_driver);
|
||||
}
|
||||
|
||||
static void __exit vmem_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&vmem_driver);
|
||||
}
|
||||
|
||||
module_init(vmem_init);
|
||||
module_exit(vmem_exit);
|
36
drivers/media/platform/msm/vidc_3x/vmem/vmem.h
Normal file
36
drivers/media/platform/msm/vidc_3x/vmem/vmem.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __VMEM_H__
|
||||
#define __VMEM_H__
|
||||
|
||||
#ifdef CONFIG_MSM_VIDC_VMEM
|
||||
|
||||
int vmem_allocate(size_t size, phys_addr_t *addr);
|
||||
void vmem_free(phys_addr_t to_free);
|
||||
|
||||
#else
|
||||
|
||||
static inline int vmem_allocate(size_t size, phys_addr_t *addr)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void vmem_free(phys_addr_t to_free)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __VMEM_H__ */
|
83
drivers/media/platform/msm/vidc_3x/vmem/vmem_debugfs.c
Normal file
83
drivers/media/platform/msm/vidc_3x/vmem/vmem_debugfs.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "vmem.h"
|
||||
|
||||
struct vmem_debugfs_cookie {
|
||||
phys_addr_t addr;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static int __vmem_alloc_get(void *priv, u64 *val)
|
||||
{
|
||||
struct vmem_debugfs_cookie *cookie = priv;
|
||||
|
||||
*val = cookie->size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __vmem_alloc_set(void *priv, u64 val)
|
||||
{
|
||||
struct vmem_debugfs_cookie *cookie = priv;
|
||||
int rc = 0;
|
||||
|
||||
switch (val) {
|
||||
case 0: /* free */
|
||||
vmem_free(cookie->addr);
|
||||
cookie->size = 0;
|
||||
break;
|
||||
default:
|
||||
rc = vmem_allocate(val, &cookie->addr);
|
||||
cookie->size = val;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_vmem_alloc, __vmem_alloc_get,
|
||||
__vmem_alloc_set, "%llu");
|
||||
|
||||
struct dentry *vmem_debugfs_init(struct platform_device *pdev)
|
||||
{
|
||||
struct vmem_debugfs_cookie *alloc_cookie = NULL;
|
||||
struct dentry *debugfs_root = NULL;
|
||||
|
||||
alloc_cookie = devm_kzalloc(&pdev->dev, sizeof(*alloc_cookie),
|
||||
GFP_KERNEL);
|
||||
if (!alloc_cookie)
|
||||
goto exit;
|
||||
|
||||
debugfs_root = debugfs_create_dir("vmem", NULL);
|
||||
if (IS_ERR_OR_NULL(debugfs_root)) {
|
||||
pr_warn("Failed to create '<debugfs>/vmem'\n");
|
||||
debugfs_root = NULL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
debugfs_create_file("alloc", 0600, debugfs_root,
|
||||
alloc_cookie, &fops_vmem_alloc);
|
||||
|
||||
exit:
|
||||
return debugfs_root;
|
||||
}
|
||||
|
||||
void vmem_debugfs_deinit(struct dentry *debugfs_root)
|
||||
{
|
||||
debugfs_remove_recursive(debugfs_root);
|
||||
}
|
||||
|
23
drivers/media/platform/msm/vidc_3x/vmem/vmem_debugfs.h
Normal file
23
drivers/media/platform/msm/vidc_3x/vmem/vmem_debugfs.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __VMEM_DEBUGFS_H__
|
||||
#define __VMEM_DEBUGFS_H__
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
struct dentry *vmem_debugfs_init(struct platform_device *pdev);
|
||||
void vmem_debugfs_deinit(struct dentry *debugfs_root);
|
||||
|
||||
#endif /* __VMEM_DEBUGFS_H__ */
|
|
@ -645,6 +645,7 @@ gen_headers_out_arm = [
|
|||
"media/msm_cvp_utils.h",
|
||||
"media/msm_media_info.h",
|
||||
"media/msm_sde_rotator.h",
|
||||
"media/msm_vidc.h",
|
||||
"media/msm_vidc_private.h",
|
||||
"media/msm_vidc_utils.h",
|
||||
"media/radio-iris-commands.h",
|
||||
|
|
|
@ -641,6 +641,7 @@ gen_headers_out_arm64 = [
|
|||
"media/msm_sde_rotator.h",
|
||||
"media/msm_vidc_private.h",
|
||||
"media/msm_vidc_utils.h",
|
||||
"media/msm_vidc.h",
|
||||
"media/radio-iris-commands.h",
|
||||
"media/radio-iris.h",
|
||||
"media/synx.h",
|
||||
|
|
137
include/media/msm_vidc.h
Normal file
137
include/media/msm_vidc.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _MSM_VIDC_H_
|
||||
#define _MSM_VIDC_H_
|
||||
|
||||
#include <linux/poll.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/msm_ion.h>
|
||||
#include <uapi/media/msm_vidc.h>
|
||||
|
||||
#define HAL_BUFFER_MAX 0xd
|
||||
|
||||
enum smem_type {
|
||||
SMEM_ION,
|
||||
};
|
||||
|
||||
enum smem_prop {
|
||||
SMEM_UNCACHED = 0x1,
|
||||
SMEM_CACHED = 0x2,
|
||||
SMEM_SECURE = 0x4,
|
||||
SMEM_ADSP = 0x8,
|
||||
};
|
||||
|
||||
/* NOTE: if you change this enum you MUST update the
|
||||
* "buffer-type-tz-usage-table" for any affected target
|
||||
* in arch/arm/boot/dts/<arch>.dtsi
|
||||
*/
|
||||
enum hal_buffer {
|
||||
HAL_BUFFER_NONE = 0x0,
|
||||
HAL_BUFFER_INPUT = 0x1,
|
||||
HAL_BUFFER_OUTPUT = 0x2,
|
||||
HAL_BUFFER_OUTPUT2 = 0x4,
|
||||
HAL_BUFFER_EXTRADATA_INPUT = 0x8,
|
||||
HAL_BUFFER_EXTRADATA_OUTPUT = 0x10,
|
||||
HAL_BUFFER_EXTRADATA_OUTPUT2 = 0x20,
|
||||
HAL_BUFFER_INTERNAL_SCRATCH = 0x40,
|
||||
HAL_BUFFER_INTERNAL_SCRATCH_1 = 0x80,
|
||||
HAL_BUFFER_INTERNAL_SCRATCH_2 = 0x100,
|
||||
HAL_BUFFER_INTERNAL_PERSIST = 0x200,
|
||||
HAL_BUFFER_INTERNAL_PERSIST_1 = 0x400,
|
||||
HAL_BUFFER_INTERNAL_CMD_QUEUE = 0x800,
|
||||
HAL_BUFFER_INTERNAL_RECON = 0x1000,
|
||||
};
|
||||
|
||||
struct dma_mapping_info {
|
||||
struct device *dev;
|
||||
struct iommu_domain *domain;
|
||||
struct sg_table *table;
|
||||
struct dma_buf_attachment *attach;
|
||||
struct dma_buf *buf;
|
||||
void *cb_info;
|
||||
};
|
||||
|
||||
struct msm_smem {
|
||||
u32 refcount;
|
||||
int fd;
|
||||
void *dma_buf;
|
||||
void *handle;
|
||||
void *kvaddr;
|
||||
u32 device_addr;
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
unsigned long flags;
|
||||
enum hal_buffer buffer_type;
|
||||
struct dma_mapping_info mapping_info;
|
||||
int mem_type;
|
||||
void *smem_priv;
|
||||
};
|
||||
|
||||
enum smem_cache_ops {
|
||||
SMEM_CACHE_CLEAN,
|
||||
SMEM_CACHE_INVALIDATE,
|
||||
SMEM_CACHE_CLEAN_INVALIDATE,
|
||||
};
|
||||
|
||||
enum core_id {
|
||||
MSM_VIDC_CORE_VENUS = 0,
|
||||
MSM_VIDC_CORE_Q6,
|
||||
MSM_VIDC_CORES_MAX,
|
||||
};
|
||||
enum session_type {
|
||||
MSM_VIDC_ENCODER = 0,
|
||||
MSM_VIDC_DECODER,
|
||||
MSM_VIDC_UNKNOWN,
|
||||
MSM_VIDC_MAX_DEVICES = MSM_VIDC_UNKNOWN,
|
||||
};
|
||||
|
||||
union msm_v4l2_cmd {
|
||||
struct v4l2_decoder_cmd dec;
|
||||
struct v4l2_encoder_cmd enc;
|
||||
};
|
||||
|
||||
void *msm_vidc_open(int core_id, int session_type);
|
||||
int msm_vidc_close(void *instance);
|
||||
int msm_vidc_suspend(int core_id);
|
||||
int msm_vidc_querycap(void *instance, struct v4l2_capability *cap);
|
||||
int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
|
||||
int msm_vidc_s_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_vidc_g_fmt(void *instance, struct v4l2_format *f);
|
||||
int msm_vidc_release_buffers(void *instance, int buffer_type);
|
||||
int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b);
|
||||
int msm_vidc_s_ctrl(void *instance, struct v4l2_control *a);
|
||||
int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
|
||||
int msm_vidc_g_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
|
||||
int msm_vidc_g_ctrl(void *instance, struct v4l2_control *a);
|
||||
int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
|
||||
int msm_vidc_release_buffer(void *instance, int buffer_type,
|
||||
unsigned int buffer_index);
|
||||
int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b);
|
||||
int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b);
|
||||
int msm_vidc_streamon(void *instance, enum v4l2_buf_type i);
|
||||
int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl);
|
||||
int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i);
|
||||
int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd);
|
||||
int msm_vidc_poll(void *instance, struct file *filp,
|
||||
struct poll_table_struct *pt);
|
||||
int msm_vidc_subscribe_event(void *instance,
|
||||
const struct v4l2_event_subscription *sub);
|
||||
int msm_vidc_unsubscribe_event(void *instance,
|
||||
const struct v4l2_event_subscription *sub);
|
||||
int msm_vidc_dqevent(void *instance, struct v4l2_event *event);
|
||||
int msm_vidc_g_crop(void *instance, struct v4l2_crop *a);
|
||||
int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize);
|
||||
#endif
|
406
include/trace/events/msm_vidc.h
Normal file
406
include/trace/events/msm_vidc.h
Normal file
|
@ -0,0 +1,406 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2014-2017, 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM msm_vidc
|
||||
|
||||
#if !defined(_TRACE_MSM_VIDC_H_) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_MSM_VIDC_H
|
||||
#include <linux/types.h>
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_v4l2_vidc,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(char *, dummy)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dummy = dummy;
|
||||
),
|
||||
|
||||
TP_printk("%s", __entry->dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_open_start,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_open_end,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_close_start,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_close_end,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_fw_load_start,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_vidc, msm_v4l2_vidc_fw_load_end,
|
||||
|
||||
TP_PROTO(char *dummy),
|
||||
|
||||
TP_ARGS(dummy)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_vidc_common,
|
||||
|
||||
TP_PROTO(void *instp, int old_state, int new_state),
|
||||
|
||||
TP_ARGS(instp, old_state, new_state),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(void *, instp)
|
||||
__field(int, old_state)
|
||||
__field(int, new_state)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->instp = instp;
|
||||
__entry->old_state = old_state;
|
||||
__entry->new_state = new_state;
|
||||
),
|
||||
|
||||
TP_printk("Moved inst: %p from 0x%x to 0x%x",
|
||||
__entry->instp,
|
||||
__entry->old_state,
|
||||
__entry->new_state)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_vidc_common, msm_vidc_common_state_change,
|
||||
|
||||
TP_PROTO(void *instp, int old_state, int new_state),
|
||||
|
||||
TP_ARGS(instp, old_state, new_state)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(venus_hfi_var,
|
||||
|
||||
TP_PROTO(u32 cp_start, u32 cp_size,
|
||||
u32 cp_nonpixel_start, u32 cp_nonpixel_size),
|
||||
|
||||
TP_ARGS(cp_start, cp_size, cp_nonpixel_start, cp_nonpixel_size),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(u32, cp_start)
|
||||
__field(u32, cp_size)
|
||||
__field(u32, cp_nonpixel_start)
|
||||
__field(u32, cp_nonpixel_size)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->cp_start = cp_start;
|
||||
__entry->cp_size = cp_size;
|
||||
__entry->cp_nonpixel_start = cp_nonpixel_start;
|
||||
__entry->cp_nonpixel_size = cp_nonpixel_size;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"TZBSP_MEM_PROTECT_VIDEO_VAR done, cp_start : 0x%x, cp_size : 0x%x, cp_nonpixel_start : 0x%x, cp_nonpixel_size : 0x%x",
|
||||
__entry->cp_start,
|
||||
__entry->cp_size,
|
||||
__entry->cp_nonpixel_start,
|
||||
__entry->cp_nonpixel_size)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(venus_hfi_var, venus_hfi_var_done,
|
||||
|
||||
TP_PROTO(u32 cp_start, u32 cp_size,
|
||||
u32 cp_nonpixel_start, u32 cp_nonpixel_size),
|
||||
|
||||
TP_ARGS(cp_start, cp_size, cp_nonpixel_start, cp_nonpixel_size)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_v4l2_vidc_buffer_events,
|
||||
|
||||
TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp,
|
||||
u32 alloc_len, u32 filled_len, u32 offset),
|
||||
|
||||
TP_ARGS(event_type, device_addr, timestamp, alloc_len,
|
||||
filled_len, offset),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(char *, event_type)
|
||||
__field(u32, device_addr)
|
||||
__field(int64_t, timestamp)
|
||||
__field(u32, alloc_len)
|
||||
__field(u32, filled_len)
|
||||
__field(u32, offset)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->event_type = event_type;
|
||||
__entry->device_addr = device_addr;
|
||||
__entry->timestamp = timestamp;
|
||||
__entry->alloc_len = alloc_len;
|
||||
__entry->filled_len = filled_len;
|
||||
__entry->offset = offset;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s, device_addr : 0x%x, timestamp : %lld, alloc_len : 0x%x, filled_len : 0x%x, offset : 0x%x",
|
||||
__entry->event_type,
|
||||
__entry->device_addr,
|
||||
__entry->timestamp,
|
||||
__entry->alloc_len,
|
||||
__entry->filled_len,
|
||||
__entry->offset)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_vidc_buffer_events, msm_v4l2_vidc_buffer_event_start,
|
||||
|
||||
TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp,
|
||||
u32 alloc_len, u32 filled_len, u32 offset),
|
||||
|
||||
TP_ARGS(event_type, device_addr, timestamp, alloc_len,
|
||||
filled_len, offset)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_v4l2_vidc_buffer_events, msm_v4l2_vidc_buffer_event_end,
|
||||
|
||||
TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp,
|
||||
u32 alloc_len, u32 filled_len, u32 offset),
|
||||
|
||||
TP_ARGS(event_type, device_addr, timestamp, alloc_len,
|
||||
filled_len, offset)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_smem_buffer_ion_ops,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(buffer_op, buffer_op)
|
||||
__field(u32, buffer_type)
|
||||
__field(u32, heap_mask)
|
||||
__field(u32, size)
|
||||
__field(u32, align)
|
||||
__field(u32, flags)
|
||||
__field(int, map_kernel)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(buffer_op, buffer_op);
|
||||
__entry->buffer_type = buffer_type;
|
||||
__entry->heap_mask = heap_mask;
|
||||
__entry->size = size;
|
||||
__entry->align = align;
|
||||
__entry->flags = flags;
|
||||
__entry->map_kernel = map_kernel;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s, buffer_type : 0x%x, heap_mask : 0x%x, size : 0x%x, align : 0x%x, flags : 0x%x, map_kernel : %d",
|
||||
__get_str(buffer_op),
|
||||
__entry->buffer_type,
|
||||
__entry->heap_mask,
|
||||
__entry->size,
|
||||
__entry->align,
|
||||
__entry->flags,
|
||||
__entry->map_kernel)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_smem_buffer_ion_ops, msm_smem_buffer_ion_op_start,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_smem_buffer_ion_ops, msm_smem_buffer_ion_op_end,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel)
|
||||
);
|
||||
DECLARE_EVENT_CLASS(msm_smem_buffer_dma_ops,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(buffer_op, buffer_op)
|
||||
__field(u32, buffer_type)
|
||||
__field(u32, heap_mask)
|
||||
__field(u32, size)
|
||||
__field(u32, align)
|
||||
__field(u32, flags)
|
||||
__field(int, map_kernel)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(buffer_op, buffer_op);
|
||||
__entry->buffer_type = buffer_type;
|
||||
__entry->heap_mask = heap_mask;
|
||||
__entry->size = size;
|
||||
__entry->align = align;
|
||||
__entry->flags = flags;
|
||||
__entry->map_kernel = map_kernel;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s, buffer_type : 0x%x, heap_mask : 0x%x, size : 0x%x, align : 0x%x, flags : 0x%x, map_kernel : %d",
|
||||
__get_str(buffer_op),
|
||||
__entry->buffer_type,
|
||||
__entry->heap_mask,
|
||||
__entry->size,
|
||||
__entry->align,
|
||||
__entry->flags,
|
||||
__entry->map_kernel)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_smem_buffer_dma_ops, msm_smem_buffer_dma_op_start,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_smem_buffer_dma_ops, msm_smem_buffer_dma_op_end,
|
||||
|
||||
TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask,
|
||||
size_t size, u32 align, u32 flags, int map_kernel),
|
||||
|
||||
TP_ARGS(buffer_op, buffer_type, heap_mask, size, align,
|
||||
flags, map_kernel)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_smem_buffer_iommu_ops,
|
||||
|
||||
TP_PROTO(char *buffer_op, int domain_num, int partition_num,
|
||||
unsigned long align, unsigned long iova,
|
||||
unsigned long buffer_size),
|
||||
|
||||
TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(buffer_op, buffer_op)
|
||||
__field(int, domain_num)
|
||||
__field(int, partition_num)
|
||||
__field(unsigned long, align)
|
||||
__field(unsigned long, iova)
|
||||
__field(unsigned long, buffer_size)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(buffer_op, buffer_op);
|
||||
__entry->domain_num = domain_num;
|
||||
__entry->partition_num = partition_num;
|
||||
__entry->align = align;
|
||||
__entry->iova = iova;
|
||||
__entry->buffer_size = buffer_size;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s, domain : %d, partition : %d, align : %lx, iova : 0x%lx, buffer_size=%lx",
|
||||
__get_str(buffer_op),
|
||||
__entry->domain_num,
|
||||
__entry->partition_num,
|
||||
__entry->align,
|
||||
__entry->iova,
|
||||
__entry->buffer_size)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_smem_buffer_iommu_ops, msm_smem_buffer_iommu_op_start,
|
||||
|
||||
TP_PROTO(char *buffer_op, int domain_num, int partition_num,
|
||||
unsigned long align, unsigned long iova,
|
||||
unsigned long buffer_size),
|
||||
|
||||
TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_smem_buffer_iommu_ops, msm_smem_buffer_iommu_op_end,
|
||||
|
||||
TP_PROTO(char *buffer_op, int domain_num, int partition_num,
|
||||
unsigned long align, unsigned long iova,
|
||||
unsigned long buffer_size),
|
||||
|
||||
TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(msm_vidc_perf,
|
||||
|
||||
TP_PROTO(const char *name, unsigned long value),
|
||||
|
||||
TP_ARGS(name, value),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(const char *, name)
|
||||
__field(unsigned long, value)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->name = name;
|
||||
__entry->value = value;
|
||||
),
|
||||
|
||||
TP_printk("%s %lu", __entry->name, __entry->value)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_vidc_perf, msm_vidc_perf_clock_scale,
|
||||
|
||||
TP_PROTO(const char *clock_name, unsigned long frequency),
|
||||
|
||||
TP_ARGS(clock_name, frequency)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(msm_vidc_perf, msm_vidc_perf_bus_vote,
|
||||
|
||||
TP_PROTO(const char *governor_mode, unsigned long ab),
|
||||
|
||||
TP_ARGS(governor_mode, ab)
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#include <trace/define_trace.h>
|
|
@ -387,6 +387,7 @@ enum v4l2_mpeg_video_bitrate_mode {
|
|||
enum v4l2_mpeg_video_header_mode {
|
||||
V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0,
|
||||
V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1,
|
||||
V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME = 2,
|
||||
|
||||
};
|
||||
#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217)
|
||||
|
@ -398,6 +399,7 @@ enum v4l2_mpeg_video_multi_slice_mode {
|
|||
V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0,
|
||||
V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1,
|
||||
V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2,
|
||||
V4L2_MPEG_VIDEO_MULTI_SLICE_GOB = 3,
|
||||
};
|
||||
#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222)
|
||||
#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223)
|
||||
|
@ -784,7 +786,6 @@ enum v4l2_mpeg_mfc51_video_force_frame_type {
|
|||
/* MPEG-class control IDs specific to the msm_vidc driver */
|
||||
#define V4L2_CID_MPEG_MSM_VIDC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000)
|
||||
|
||||
|
||||
#define V4L2_MPEG_MSM_VIDC_DISABLE 0
|
||||
#define V4L2_MPEG_MSM_VIDC_ENABLE 1
|
||||
|
||||
|
@ -796,21 +797,81 @@ enum v4l2_mpeg_vidc_video_pictype_dec_mode {
|
|||
V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_B = 4,
|
||||
};
|
||||
|
||||
enum v4l2_mpeg_vidc_video_pictype_dec_enable {
|
||||
V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+1)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT (V4L2_CID_MPEG_MSM_VIDC_BASE+2)
|
||||
enum v4l2_mpeg_vidc_video_stream_format {
|
||||
V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_NAL_PER_BUFFER = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_ONE_BYTE_LENGTH = 2,
|
||||
V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH = 3,
|
||||
V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH = 4,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_DECODE_ORDER (V4L2_CID_MPEG_MSM_VIDC_BASE+3)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD (V4L2_CID_MPEG_MSM_VIDC_BASE+5)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES (V4L2_CID_MPEG_MSM_VIDC_BASE+6)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES (V4L2_CID_MPEG_MSM_VIDC_BASE+7)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME (V4L2_CID_MPEG_MSM_VIDC_BASE+8)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL (V4L2_CID_MPEG_MSM_VIDC_BASE+9)
|
||||
enum v4l2_mpeg_vidc_video_rate_control {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR = 1,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR = 2,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR = 3,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR = 4,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR = 5,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR = 6,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CQ = 7,
|
||||
};
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR \
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR \
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_ROTATION (V4L2_CID_MPEG_MSM_VIDC_BASE+10)
|
||||
enum v4l2_mpeg_vidc_video_rotation {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90 = 1,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180 = 2,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270 = 3,
|
||||
};
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+11)
|
||||
enum v4l2_mpeg_vidc_h264_cabac_model {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0 = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1 = 1,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2 = 2,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE_CYCLIC \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+12)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+13)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 14)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_au_delimiter {
|
||||
V4L2_MPEG_VIDC_VIDEO_AU_DELIMITER_DISABLED = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_AU_DELIMITER_ENABLED = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 15)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_sync_frame_decode {
|
||||
V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_DISABLE = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_SECURE (V4L2_CID_MPEG_MSM_VIDC_BASE+16)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 17)
|
||||
|
@ -824,6 +885,66 @@ enum v4l2_mpeg_vidc_extradata {
|
|||
EXTRADATA_ENC_INPUT_HDR10PLUS = 8,
|
||||
EXTRADATA_ENC_INPUT_CVP = 16,
|
||||
};
|
||||
enum v4l2_mpeg_vidc3x_extradata {
|
||||
V4L2_MPEG_VIDC_EXTRADATA_NONE = 0,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_MB_QUANTIZATION = 1,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO = 2,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_ENC_DTS \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_ENC_DTS
|
||||
V4L2_MPEG_VIDC_EXTRADATA_ENC_DTS = 3,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_VC1_FRAMEDISP = 4,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP = 5,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING = 6,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE = 7,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW = 8,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI = 9,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO = 10,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB = 11,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER = 12,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP
|
||||
V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP = 13,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM = 14,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO = 15,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP = 16,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA = 17,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP = 18,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO = 19,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_LTR = 20,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI = 21,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI = 22,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_HDR10PLUS_METADATA \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_HDR10PLUS_METADATA
|
||||
V4L2_MPEG_VIDC_EXTRADATA_HDR10PLUS_METADATA = 23,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_ROI_QP = 24,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP
|
||||
V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP = 25,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI
|
||||
V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI = 26,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI
|
||||
V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 27,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO
|
||||
V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO = 28,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY
|
||||
V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY = 29,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE
|
||||
V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE = 30,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO
|
||||
V4L2_MPEG_VIDC_EXTRADATA_UBWC_CR_STATS_INFO = 31,
|
||||
#define V4L2_MPEG_VIDC_EXTRADATA_ENC_FRAME_QP \
|
||||
V4L2_MPEG_VIDC_EXTRADATA_ENC_FRAME_QP
|
||||
V4L2_MPEG_VIDC_EXTRADATA_ENC_FRAME_QP = 32,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP = 33,
|
||||
V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS = 34,
|
||||
};
|
||||
|
||||
enum v4l2_mpeg_cvp_extradata {
|
||||
V4L2_MPEG_CVP_EXTRADATA_NONE = 0,
|
||||
V4L2_MPEG_CVP_EXTRADATA_INTERLACE_VIDEO = 2,
|
||||
|
@ -850,9 +971,17 @@ enum v4l2_mpeg_cvp_extradata {
|
|||
V4L2_MPEG_CVP_EXTRADATA_UBWC_CR_STATS_INFO = 31,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 18)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VUI_TIMING_INFO \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 19)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_vui_timing_info {
|
||||
V4L2_MPEG_VIDC_VIDEO_VUI_TIMING_INFO_DISABLED = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_VUI_TIMING_INFO_ENABLED = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 20)
|
||||
enum v4l2_mpeg_vidc_video_vp8_profile_level {
|
||||
|
@ -863,6 +992,13 @@ enum v4l2_mpeg_vidc_video_vp8_profile_level {
|
|||
V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_PRESERVE_TEXT_QUALITY \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 21)
|
||||
enum v4l2_mpeg_vidc_video_preserve_text_quality {
|
||||
V4L2_MPEG_VIDC_VIDEO_PRESERVE_TEXT_QUALITY_DISABLED = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_PRESERVE_TEXT_QUALITY_ENABLED = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE+23)
|
||||
enum v4l2_mpeg_vidc_video_mpeg2_level {
|
||||
V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0 = 0,
|
||||
|
@ -875,6 +1011,26 @@ enum v4l2_mpeg_vidc_video_mpeg2_profile {
|
|||
V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_HIGH = 2,
|
||||
V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SNR_SCALABLE = 3,
|
||||
V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SPATIAL_SCALABLE = 4,
|
||||
V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_422 = 5,
|
||||
};
|
||||
|
||||
enum v4l2_mpeg_vidc_video_mvc_layout {
|
||||
V4L2_MPEG_VIDC_VIDEO_MVC_SEQUENTIAL = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 25)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 26)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_ltrmode {
|
||||
V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_LTR_MODE_PERIODIC = 2
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT \
|
||||
|
@ -886,29 +1042,176 @@ enum v4l2_mpeg_vidc_video_mpeg2_profile {
|
|||
#define V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 29)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 30)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+31)
|
||||
enum v4l2_mpeg_vidc_video_alloc_mode_type {
|
||||
V4L2_MPEG_VIDC_VIDEO_STATIC = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_RING = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_DYNAMIC = 2,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 32)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 33)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 34)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 35)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 36)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 37)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 38)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 39)
|
||||
|
||||
enum vl42_mpeg_vidc_video_vpx_error_resilience {
|
||||
V4L2_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE_DISABLED = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE_ENABLED = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 40)
|
||||
enum v4l2_cid_mpeg_video_hevc_profile {
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10 = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN_STILL_PIC = 2,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 41)
|
||||
enum v4l2_cid_mpeg_video_hevc_level {
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1 = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1 = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2 = 2,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2 = 3,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1 = 4,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1 = 5,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3 = 6,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3 = 7,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1 = 8,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1 = 9,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4 = 10,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4 = 11,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1 = 12,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1 = 13,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5 = 14,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5 = 15,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1 = 16,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1 = 17,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2 = 18,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2 = 19,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6 = 20,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6 = 21,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1 = 22,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1 = 23,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2 = 24,
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_2 = 25,
|
||||
#define V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN \
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN
|
||||
V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN = 26,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 42)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 43)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 44)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_dpb_color_format {
|
||||
V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC = 2
|
||||
};
|
||||
|
||||
#define V4L2_CID_VIDC_QBUF_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 45)
|
||||
enum v4l2_vidc_qbuf_mode {
|
||||
V4L2_VIDC_QBUF_STANDARD = 0,
|
||||
V4L2_VIDC_QBUF_BATCHED = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 46)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 47)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 48)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 49)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 50)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_vqzip_sei_enable {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 51)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 52)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_priority {
|
||||
V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 53)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 54)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_venc_bitrate_type_enable {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 55)
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 55)
|
||||
|
||||
enum v4l2_cid_mpeg_vidc_video_vpe_csc_type_enable {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_DISABLE = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 56)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_lowlatency_mode {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_DISABLE = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_ENABLE = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_BLUR_DIMENSIONS \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 57)
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 57)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 58)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 59)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 60)
|
||||
|
@ -916,12 +1219,31 @@ enum v4l2_mpeg_vidc_video_mpeg2_profile {
|
|||
#define V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 61)
|
||||
|
||||
enum v4l2_cid_mpeg_vidc_video_full_range {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_DISABLE = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE_ENABLE = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 62)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 63)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_TYPE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 64)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_LAYER_ID \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 65)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VP9_PROFILE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 66)
|
||||
enum v4l2_mpeg_vidc_video_vp9_profile {
|
||||
V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_UNUSED = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P0 = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P2_10 = 2,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VP9_LEVEL \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 67)
|
||||
enum v4l2_mpeg_vidc_video_vp9_level {
|
||||
|
@ -940,17 +1262,132 @@ enum v4l2_mpeg_vidc_video_vp9_level {
|
|||
V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61 = 12,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE_CAPS \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 68)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_CAPS \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 69)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_MB_ERROR_MAP_REPORTING \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 70)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 71)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_INPUT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 72)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_FRAME_ASSEMBLY \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 73)
|
||||
enum v4l2_mpeg_vidc_video_assembly {
|
||||
V4L2_MPEG_VIDC_FRAME_ASSEMBLY_DISABLE = 0,
|
||||
V4L2_MPEG_VIDC_FRAME_ASSEMBLY_ENABLE = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE\
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 74)
|
||||
enum v4l2_mpeg_vidc_video_h263_profile {
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE = 2,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2 = 3,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3 = 4,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION = 5,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET = 6,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE = 7,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY = 8,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+75)
|
||||
enum v4l2_mpeg_vidc_video_output_order {
|
||||
V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8 \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 76)
|
||||
enum v4l2_mpeg_vidc_video_h264_transform_8x8 {
|
||||
V4L2_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8_DISABLE = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8_ENABLE = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_QP_MASK \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 77)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDEO_MIN_QP_PACKED \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 96)
|
||||
#define V4L2_CID_MPEG_VIDEO_MAX_QP_PACKED \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 97)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_ADAPTIVE_B \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 98)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 99)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 100)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 101)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MIN \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 102)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MIN \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 103)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MIN \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 104)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP_MAX \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 105)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP_MAX \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 106)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP_MAX \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 107)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_DYN_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 108)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_venc_iframesize_type {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_DEFAULT,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_MEDIUM,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_HUGE,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_SIZE_UNLIMITED,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_8BIT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 109)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR_10BIT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 110)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_TME_PROFILE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 111)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_tme_profile {
|
||||
V4L2_MPEG_VIDC_VIDEO_TME_PROFILE_0 = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_TME_PROFILE_1 = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_TME_PROFILE_2 = 2,
|
||||
V4L2_MPEG_VIDC_VIDEO_TME_PROFILE_3 = 3,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_TME_LEVEL \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 112)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_tme_level {
|
||||
V4L2_MPEG_VIDC_VIDEO_TME_LEVEL_INTEGER = 0,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_TME_PAYLOAD_VERSION \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 113)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 114)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_FLIP (V4L2_CID_MPEG_MSM_VIDC_BASE + 115)
|
||||
enum v4l2_mpeg_vidc_video_flip {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_FLIP_NONE = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_FLIP_HORI = 1,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_FLIP_VERT = 2,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_FLIP_BOTH = 3,
|
||||
};
|
||||
|
||||
/* HDR SEI INFO related control IDs and definitions*/
|
||||
#define V4L2_MPEG_VIDC_VENC_HDR_INFO_ENABLED 1
|
||||
#define V4L2_MPEG_VIDC_VENC_HDR_INFO_DISABLED 0
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VENC_HDR_INFO \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 116)
|
||||
|
||||
|
@ -1003,9 +1440,166 @@ enum v4l2_mpeg_vidc_video_roi_type {
|
|||
V4L2_CID_MPEG_VIDC_VIDEO_ROI_TYPE_2BYTE = 2,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 128)
|
||||
enum v4l2_mpeg_vidc_perf_level {
|
||||
V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL = 0,
|
||||
V4L2_CID_MPEG_VIDC_PERF_LEVEL_PERFORMANCE = 1,
|
||||
V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO = 2,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 133)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS (V4L2_CID_MPEG_MSM_VIDC_BASE + 134)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_AIR_REF (V4L2_CID_MPEG_MSM_VIDC_BASE + 135)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS (V4L2_CID_MPEG_MSM_VIDC_BASE + 136)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 137)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 138)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 139)
|
||||
enum v4l2_mpeg_vidc_video_h264_vui_bitstream_restrict {
|
||||
V4L2_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT_DISABLED = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_H264_VUI_BITSTREAM_RESTRICT_ENABLED = 1
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 140)
|
||||
enum v4l2_mpeg_vidc_video_deinterlace {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_DISABLED = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_MPEG4_TIME_RESOLUTION \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 141)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 142)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_TIMESTAMP_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 143)
|
||||
enum v4l2_mpeg_vidc_video_rate_control_timestamp_mode {
|
||||
V4L2_MPEG_VIDC_VIDEO_RATE_CONTROL_TIMESTAMP_MODE_HONOR = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_RATE_CONTROL_TIMESTAMP_MODE_IGNORE = 1,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 144)
|
||||
enum vl42_mpeg_vidc_video_enable_initial_qp {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_IFRAME = 0x1,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_PFRAME = 0x2,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP_BFRAME = 0x4,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_I_FRAME_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 145)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_P_FRAME_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 146)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_INITIAL_B_FRAME_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 147)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 148)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 149)
|
||||
enum v4l2_mpeg_vidc_video_perf_mode {
|
||||
V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE = 2
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 150)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 151)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_H264_PIC_ORDER_CNT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 152)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_SCS_THRESHOLD \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 153)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 154)
|
||||
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 155)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2 \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 156)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 157)
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP (V4L2_CID_MPEG_MSM_VIDC_BASE + 158)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 159)
|
||||
enum v4l2_mpeg_vidc_video_h263_level {
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0 = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0 = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0 = 2,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0 = 3,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5 = 4,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0 = 5,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0 = 6,
|
||||
V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0 = 7,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_POST_LOOP_DEBLOCKER_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 160)
|
||||
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT (V4L2_CID_MPEG_MSM_VIDC_BASE+161)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_divx_format_type {
|
||||
V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4 = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5 = 1,
|
||||
V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6 = 2,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_IMG_GRID_DIMENSION \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+163)
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_FRAME_QP \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+164)
|
||||
|
||||
#define \
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE+165)
|
||||
enum v4l2_mpeg_vidc_video_intra_refresh_mode {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC = 1,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOMMODE = 2,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE = 3,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE = 4,
|
||||
};
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_IR_MBS (V4L2_CID_MPEG_MSM_VIDC_BASE+166)
|
||||
|
||||
enum v4l2_mpeg_vidc_video_mbi_statistics_mode {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_DEFAULT = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_1 = 1,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_2 = 2,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_MBI_MODE_3 = 3,
|
||||
};
|
||||
|
||||
enum vl42_mpeg_vidc_video_h264_svc_nal {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_DISABLED = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED = 1,
|
||||
};
|
||||
|
||||
enum v4l2_mpeg_vidc_video_h264_vui_timing_info {
|
||||
V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED = 0,
|
||||
V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED = 1
|
||||
};
|
||||
|
||||
/* Camera class control IDs */
|
||||
|
||||
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
|
||||
|
|
|
@ -662,7 +662,10 @@ struct v4l2_pix_format {
|
|||
#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
|
||||
#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */
|
||||
#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
|
||||
#define V4L2_PIX_FMT_DIVX_311 v4l2_fourcc('D', 'I', 'V', '3') /* DIVX311 */
|
||||
#define V4L2_PIX_FMT_DIVX v4l2_fourcc('D', 'I', 'V', 'X') /* DIVX */
|
||||
#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC aka H.265 */
|
||||
#define V4L2_PIX_FMT_HEVC_HYBRID v4l2_fourcc('H', 'V', 'C', 'H')
|
||||
#define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') /* Fast Walsh Hadamard Transform (vicodec) */
|
||||
#define V4L2_PIX_FMT_TME v4l2_fourcc('T', 'M', 'E', '0') /* TME stream */
|
||||
#define V4L2_PIX_FMT_CVP v4l2_fourcc('C', 'V', 'P', '0') /* CVP stream */
|
||||
|
@ -1085,7 +1088,23 @@ struct v4l2_buffer {
|
|||
#define V4L2_BUF_FLAG_EOS 0x02000000
|
||||
#define V4L2_BUF_FLAG_READONLY 0x04000000
|
||||
#define V4L2_BUF_FLAG_PERF_MODE 0x20000000
|
||||
#define V4L2_BUF_FLAG_CVPMETADATA_SKIP 0x40000000
|
||||
#define V4L2_BUF_FLAG_CVPMETADATA_SKIP 0x40000000
|
||||
|
||||
#define V4L2_QCOM_BUF_FLAG_EOSEQ 0x00040000
|
||||
#define V4L2_QCOM_BUF_TIMESTAMP_INVALID 0x00080000
|
||||
#define V4L2_MSM_BUF_FLAG_MBAFF 0x00000200
|
||||
#define V4L2_QCOM_BUF_FLAG_DECODEONLY 0x00200000
|
||||
#define V4L2_QCOM_BUF_DROP_FRAME 0x00800000
|
||||
#define V4L2_MSM_VIDC_BUF_START_CODE_NOT_FOUND 0x08000000
|
||||
#define V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP 0x10000000
|
||||
#define V4L2_MSM_BUF_FLAG_DEFER 0x40000000
|
||||
#define V4L2_QCOM_BUF_FLAG_IDRFRAME 0x80000000
|
||||
#define V4L2_QCOM_BUF_END_OF_SUBFRAME V4L2_BUF_FLAG_END_OF_SUBFRAME
|
||||
#define V4L2_QCOM_BUF_FLAG_CODECCONFIG V4L2_BUF_FLAG_CODECCONFIG
|
||||
#define V4L2_QCOM_BUF_INPUT_UNSUPPORTED V4L2_BUF_INPUT_UNSUPPORTED
|
||||
#define V4L2_QCOM_BUF_FLAG_EOS V4L2_BUF_FLAG_EOS
|
||||
#define V4L2_QCOM_BUF_FLAG_READONLY V4L2_BUF_FLAG_READONLY
|
||||
#define V4L2_QCOM_BUF_FLAG_PERF_MODE V4L2_BUF_FLAG_PERF_MODE
|
||||
|
||||
/**
|
||||
* struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
|
||||
|
@ -1994,6 +2013,8 @@ struct v4l2_encoder_cmd {
|
|||
#define V4L2_DEC_CMD_RESUME (3)
|
||||
#define V4L2_CMD_FLUSH (4)
|
||||
#define V4L2_CMD_SESSION_CONTINUE (5)
|
||||
#define V4L2_DEC_QCOM_CMD_RECONFIG_HINT (6)
|
||||
|
||||
/* Flags for V4L2_DEC_CMD_START */
|
||||
#define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0)
|
||||
|
||||
|
@ -2008,6 +2029,11 @@ struct v4l2_encoder_cmd {
|
|||
#define V4L2_CMD_FLUSH_OUTPUT (1 << 0)
|
||||
#define V4L2_CMD_FLUSH_CAPTURE (1 << 1)
|
||||
|
||||
#define V4L2_QCOM_CMD_FLUSH V4L2_CMD_FLUSH
|
||||
#define V4L2_QCOM_CMD_SESSION_CONTINUE V4L2_CMD_SESSION_CONTINUE
|
||||
#define V4L2_QCOM_CMD_FLUSH_OUTPUT V4L2_CMD_FLUSH_OUTPUT
|
||||
#define V4L2_QCOM_CMD_FLUSH_CAPTURE V4L2_CMD_FLUSH_CAPTURE
|
||||
|
||||
/* Play format requirements (returned by the driver): */
|
||||
|
||||
/* The decoder has no special format requirements */
|
||||
|
@ -2286,6 +2312,10 @@ struct v4l2_streamparm {
|
|||
#define V4L2_EVENT_MOTION_DET 6
|
||||
#define V4L2_EVENT_PRIVATE_START 0x08000000
|
||||
|
||||
#define V4L2_EVENT_BITDEPTH_FLAG 0x1
|
||||
#define V4L2_EVENT_PICSTRUCT_FLAG 0x2
|
||||
#define V4L2_EVENT_COLOUR_SPACE_FLAG 0x4
|
||||
|
||||
#define V4L2_EVENT_MSM_VIDC_START (V4L2_EVENT_PRIVATE_START + 0x00001000)
|
||||
#define V4L2_EVENT_MSM_VIDC_FLUSH_DONE (V4L2_EVENT_MSM_VIDC_START + 1)
|
||||
#define V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT \
|
||||
|
@ -2293,6 +2323,13 @@ struct v4l2_streamparm {
|
|||
#define V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT \
|
||||
(V4L2_EVENT_MSM_VIDC_START + 3)
|
||||
|
||||
/*
|
||||
* Bitdepth changed insufficient is deprecated now, however retaining
|
||||
* to prevent changing the values of the other macros after bitdepth
|
||||
*/
|
||||
#define V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT \
|
||||
(V4L2_EVENT_MSM_VIDC_START + 4)
|
||||
|
||||
#define V4L2_EVENT_MSM_VIDC_SYS_ERROR (V4L2_EVENT_MSM_VIDC_START + 5)
|
||||
#define V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE \
|
||||
(V4L2_EVENT_MSM_VIDC_START + 6)
|
||||
|
|
446
include/uapi/media/msm_vidc.h
Normal file
446
include/uapi/media/msm_vidc.h
Normal file
|
@ -0,0 +1,446 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef __MSM_VIDC_H__
|
||||
#define __MSM_VIDC_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12 0x2
|
||||
#define MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC 0x8002
|
||||
#define MSM_VIDC_4x_1 0x1
|
||||
#define MSM_VIDC_EXTRADATA_FRAME_QP_ADV 0x1
|
||||
|
||||
|
||||
static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height)
|
||||
{
|
||||
(void)height;
|
||||
(void)width;
|
||||
/*
|
||||
* In the future, calculate the size based on the w/h but just
|
||||
* hardcode it for now since 16K satisfies all current usecases.
|
||||
*/
|
||||
return 16 * 1024;
|
||||
}
|
||||
|
||||
#define V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE \
|
||||
(V4L2_CID_MPEG_MSM_VIDC_BASE + 22)
|
||||
enum v4l2_mpeg_vidc_video_decoder_multi_stream {
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY = 0,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY = 1,
|
||||
};
|
||||
|
||||
struct msm_vidc_extradata_header {
|
||||
unsigned int size;
|
||||
unsigned int:32; /** Keeping binary compatibility */
|
||||
unsigned int:32; /* with firmware and OpenMAX IL **/
|
||||
unsigned int type; /* msm_vidc_extradata_type */
|
||||
unsigned int data_size;
|
||||
unsigned char data[1];
|
||||
};
|
||||
|
||||
struct msm_vidc_interlace_payload {
|
||||
unsigned int format;
|
||||
unsigned int color_format;
|
||||
};
|
||||
|
||||
struct msm_vidc_framerate_payload {
|
||||
unsigned int frame_rate;
|
||||
};
|
||||
|
||||
struct msm_vidc_ts_payload {
|
||||
unsigned int timestamp_lo;
|
||||
unsigned int timestamp_hi;
|
||||
};
|
||||
|
||||
struct msm_vidc_concealmb_payload {
|
||||
unsigned int num_mbs;
|
||||
};
|
||||
|
||||
struct msm_vidc_recoverysei_payload {
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct msm_vidc_aspect_ratio_payload {
|
||||
unsigned int size;
|
||||
unsigned int version;
|
||||
unsigned int port_index;
|
||||
unsigned int aspect_width;
|
||||
unsigned int aspect_height;
|
||||
};
|
||||
|
||||
struct msm_vidc_mpeg2_seqdisp_payload {
|
||||
unsigned int video_format;
|
||||
unsigned int color_descp;
|
||||
unsigned int color_primaries;
|
||||
unsigned int transfer_char;
|
||||
unsigned int matrix_coeffs;
|
||||
unsigned int disp_width;
|
||||
unsigned int disp_height;
|
||||
};
|
||||
|
||||
struct msm_vidc_vc1_seqdisp_payload {
|
||||
unsigned int prog_seg_format;
|
||||
unsigned int uv_sampl_fmt;
|
||||
unsigned int color_format;
|
||||
unsigned int color_primaries;
|
||||
unsigned int transfer_char;
|
||||
unsigned int matrix_coeffs;
|
||||
unsigned int aspect_ratio;
|
||||
unsigned int aspect_horiz;
|
||||
unsigned int aspect_vert;
|
||||
};
|
||||
|
||||
struct msm_vidc_input_crop_payload {
|
||||
unsigned int size;
|
||||
unsigned int version;
|
||||
unsigned int port_index;
|
||||
unsigned int left;
|
||||
unsigned int top;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
};
|
||||
|
||||
struct msm_vidc_misr_info {
|
||||
unsigned int misr_dpb_luma;
|
||||
unsigned int misr_dpb_chroma;
|
||||
unsigned int misr_opb_luma;
|
||||
unsigned int misr_opb_chroma;
|
||||
};
|
||||
struct msm_vidc_output_crop_payload {
|
||||
unsigned int size;
|
||||
unsigned int version;
|
||||
unsigned int port_index;
|
||||
unsigned int left;
|
||||
unsigned int top;
|
||||
unsigned int display_width;
|
||||
unsigned int display_height;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int frame_num;
|
||||
unsigned int bit_depth_y;
|
||||
unsigned int bit_depth_c;
|
||||
struct msm_vidc_misr_info misr_info[2];
|
||||
};
|
||||
|
||||
|
||||
struct msm_vidc_digital_zoom_payload {
|
||||
unsigned int size;
|
||||
unsigned int version;
|
||||
unsigned int port_index;
|
||||
unsigned int zoom_width;
|
||||
unsigned int zoom_height;
|
||||
};
|
||||
|
||||
struct msm_vidc_extradata_index {
|
||||
unsigned int type;
|
||||
union {
|
||||
struct msm_vidc_input_crop_payload input_crop;
|
||||
struct msm_vidc_digital_zoom_payload digital_zoom;
|
||||
struct msm_vidc_aspect_ratio_payload aspect_ratio;
|
||||
};
|
||||
};
|
||||
|
||||
struct msm_vidc_panscan_window {
|
||||
unsigned int panscan_height_offset;
|
||||
unsigned int panscan_width_offset;
|
||||
unsigned int panscan_window_width;
|
||||
unsigned int panscan_window_height;
|
||||
};
|
||||
|
||||
struct msm_vidc_panscan_window_payload {
|
||||
unsigned int num_panscan_windows;
|
||||
struct msm_vidc_panscan_window wnd[1];
|
||||
};
|
||||
|
||||
struct msm_vidc_stream_userdata_payload {
|
||||
unsigned int type;
|
||||
unsigned int data[1];
|
||||
};
|
||||
|
||||
struct msm_vidc_frame_qp_payload {
|
||||
unsigned int frame_qp;
|
||||
unsigned int qp_sum;
|
||||
unsigned int skip_qp_sum;
|
||||
unsigned int skip_num_blocks;
|
||||
unsigned int total_num_blocks;
|
||||
};
|
||||
|
||||
struct msm_vidc_frame_bits_info_payload {
|
||||
unsigned int frame_bits;
|
||||
unsigned int header_bits;
|
||||
};
|
||||
|
||||
struct msm_vidc_s3d_frame_packing_payload {
|
||||
unsigned int fpa_id;
|
||||
unsigned int cancel_flag;
|
||||
unsigned int fpa_type;
|
||||
unsigned int quin_cunx_flag;
|
||||
unsigned int content_interprtation_type;
|
||||
unsigned int spatial_flipping_flag;
|
||||
unsigned int frame0_flipped_flag;
|
||||
unsigned int field_views_flag;
|
||||
unsigned int current_frame_is_frame0_flag;
|
||||
unsigned int frame0_self_contained_flag;
|
||||
unsigned int frame1_self_contained_flag;
|
||||
unsigned int frame0_graid_pos_x;
|
||||
unsigned int frame0_graid_pos_y;
|
||||
unsigned int frame1_graid_pos_x;
|
||||
unsigned int frame1_graid_pos_y;
|
||||
unsigned int fpa_reserved_byte;
|
||||
unsigned int fpa_repetition_period;
|
||||
unsigned int fpa_extension_flag;
|
||||
};
|
||||
|
||||
struct msm_vidc_vqzip_sei_payload {
|
||||
unsigned int size;
|
||||
unsigned int data[1];
|
||||
};
|
||||
|
||||
struct msm_vidc_ubwc_cr_stats_info {
|
||||
unsigned int stats_tile_32;
|
||||
unsigned int stats_tile_64;
|
||||
unsigned int stats_tile_96;
|
||||
unsigned int stats_tile_128;
|
||||
unsigned int stats_tile_160;
|
||||
unsigned int stats_tile_192;
|
||||
unsigned int stats_tile_256;
|
||||
};
|
||||
|
||||
struct msm_vidc_yuv_stats_payload {
|
||||
unsigned int frame_qp;
|
||||
unsigned int texture;
|
||||
unsigned int luma_in_q16;
|
||||
unsigned int frame_difference;
|
||||
};
|
||||
|
||||
struct msm_vidc_vpx_colorspace_payload {
|
||||
unsigned int color_space;
|
||||
unsigned int yuv_range_flag;
|
||||
unsigned int sumsampling_x;
|
||||
unsigned int sumsampling_y;
|
||||
};
|
||||
|
||||
struct msm_vidc_roi_qp_payload {
|
||||
int upper_qp_offset;
|
||||
int lower_qp_offset;
|
||||
unsigned int b_roi_info;
|
||||
int mbi_info_size;
|
||||
unsigned int data[1];
|
||||
};
|
||||
|
||||
struct msm_vidc_mastering_display_colour_sei_payload {
|
||||
unsigned int nDisplayPrimariesX[3];
|
||||
unsigned int nDisplayPrimariesY[3];
|
||||
unsigned int nWhitePointX;
|
||||
unsigned int nWhitePointY;
|
||||
unsigned int nMaxDisplayMasteringLuminance;
|
||||
unsigned int nMinDisplayMasteringLuminance;
|
||||
};
|
||||
|
||||
struct msm_vidc_content_light_level_sei_payload {
|
||||
unsigned int nMaxContentLight;
|
||||
unsigned int nMaxPicAverageLight;
|
||||
};
|
||||
|
||||
struct msm_vidc_vui_display_info_payload {
|
||||
unsigned int video_signal_present_flag;
|
||||
unsigned int video_format;
|
||||
unsigned int bit_depth_y;
|
||||
unsigned int bit_depth_c;
|
||||
unsigned int video_full_range_flag;
|
||||
unsigned int color_description_present_flag;
|
||||
unsigned int color_primaries;
|
||||
unsigned int transfer_characteristics;
|
||||
unsigned int matrix_coefficients;
|
||||
unsigned int chroma_location_info_present_flag;
|
||||
unsigned int chroma_format_idc;
|
||||
unsigned int separate_color_plane_flag;
|
||||
unsigned int chroma_sample_loc_type_top_field;
|
||||
unsigned int chroma_sample_loc_type_bottom_field;
|
||||
};
|
||||
|
||||
enum msm_vidc_extradata_type {
|
||||
MSM_VIDC_EXTRADATA_NONE = 0x00000000,
|
||||
MSM_VIDC_EXTRADATA_MB_QUANTIZATION = 0x00000001,
|
||||
MSM_VIDC_EXTRADATA_INTERLACE_VIDEO = 0x00000002,
|
||||
MSM_VIDC_EXTRADATA_VC1_FRAMEDISP = 0x00000003,
|
||||
MSM_VIDC_EXTRADATA_VC1_SEQDISP = 0x00000004,
|
||||
MSM_VIDC_EXTRADATA_TIMESTAMP = 0x00000005,
|
||||
MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING = 0x00000006,
|
||||
MSM_VIDC_EXTRADATA_FRAME_RATE = 0x00000007,
|
||||
MSM_VIDC_EXTRADATA_PANSCAN_WINDOW = 0x00000008,
|
||||
MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI = 0x00000009,
|
||||
MSM_VIDC_EXTRADATA_MPEG2_SEQDISP = 0x0000000D,
|
||||
MSM_VIDC_EXTRADATA_STREAM_USERDATA = 0x0000000E,
|
||||
MSM_VIDC_EXTRADATA_FRAME_QP = 0x0000000F,
|
||||
MSM_VIDC_EXTRADATA_FRAME_BITS_INFO = 0x00000010,
|
||||
MSM_VIDC_EXTRADATA_VQZIP_SEI = 0x00000011,
|
||||
MSM_VIDC_EXTRADATA_ROI_QP = 0x00000013,
|
||||
#define MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO \
|
||||
MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO
|
||||
MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO = 0x00000014,
|
||||
#define MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI \
|
||||
MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI
|
||||
MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI = 0x00000015,
|
||||
#define MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI \
|
||||
MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI
|
||||
MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI = 0x00000016,
|
||||
#define MSM_VIDC_EXTRADATA_PQ_INFO \
|
||||
MSM_VIDC_EXTRADATA_PQ_INFO
|
||||
MSM_VIDC_EXTRADATA_PQ_INFO = 0x00000017,
|
||||
#define MSM_VIDC_EXTRADATA_COLOUR_REMAPPING_INFO_SEI \
|
||||
MSM_VIDC_EXTRADATA_COLOUR_REMAPPING_INFO_SEI
|
||||
MSM_VIDC_EXTRADATA_COLOUR_REMAPPING_INFO_SEI = 0x00000018,
|
||||
#define MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO \
|
||||
MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO
|
||||
MSM_VIDC_EXTRADATA_UBWC_CR_STAT_INFO = 0x00000019,
|
||||
MSM_VIDC_EXTRADATA_INPUT_CROP = 0x0700000E,
|
||||
#define MSM_VIDC_EXTRADATA_OUTPUT_CROP \
|
||||
MSM_VIDC_EXTRADATA_OUTPUT_CROP
|
||||
MSM_VIDC_EXTRADATA_OUTPUT_CROP = 0x0700000F,
|
||||
MSM_VIDC_EXTRADATA_DIGITAL_ZOOM = 0x07000010,
|
||||
MSM_VIDC_EXTRADATA_MULTISLICE_INFO = 0x7F100000,
|
||||
MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB = 0x7F100001,
|
||||
MSM_VIDC_EXTRADATA_INDEX = 0x7F100002,
|
||||
MSM_VIDC_EXTRADATA_ASPECT_RATIO = 0x7F100003,
|
||||
MSM_VIDC_EXTRADATA_METADATA_LTR = 0x7F100004,
|
||||
MSM_VIDC_EXTRADATA_METADATA_FILLER = 0x7FE00002,
|
||||
MSM_VIDC_EXTRADATA_METADATA_MBI = 0x7F100005,
|
||||
#define MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO \
|
||||
MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO
|
||||
MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO = 0x7F100006,
|
||||
MSM_VIDC_EXTRADATA_YUVSTATS_INFO = 0x7F100007,
|
||||
};
|
||||
enum msm_vidc_interlace_type {
|
||||
MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE = 0x01,
|
||||
MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST = 0x02,
|
||||
MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST = 0x04,
|
||||
MSM_VIDC_INTERLACE_FRAME_TOPFIELDFIRST = 0x08,
|
||||
MSM_VIDC_INTERLACE_FRAME_BOTTOMFIELDFIRST = 0x10,
|
||||
#define MSM_VIDC_INTERLACE_FRAME_MBAFF \
|
||||
MSM_VIDC_INTERLACE_FRAME_MBAFF
|
||||
MSM_VIDC_INTERLACE_FRAME_MBAFF = 0x20,
|
||||
};
|
||||
|
||||
/* enum msm_vidc_framepack_type */
|
||||
#define MSM_VIDC_FRAMEPACK_CHECKERBOARD 0x00
|
||||
#define MSM_VIDC_FRAMEPACK_COLUMN_INTERLEAVE 0x01
|
||||
#define MSM_VIDC_FRAMEPACK_ROW_INTERLEAVE 0x02
|
||||
#define MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE 0x03
|
||||
#define MSM_VIDC_FRAMEPACK_TOP_BOTTOM 0x04
|
||||
#define MSM_VIDC_FRAMEPACK_TEMPORAL_INTERLEAVE 0x05
|
||||
|
||||
enum msm_vidc_recovery_sei {
|
||||
MSM_VIDC_FRAME_RECONSTRUCTION_INCORRECT = 0x0,
|
||||
MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT = 0x01,
|
||||
MSM_VIDC_FRAME_RECONSTRUCTION_APPROXIMATELY_CORRECT = 0x02,
|
||||
};
|
||||
enum msm_vidc_userdata_type {
|
||||
MSM_VIDC_USERDATA_TYPE_FRAME = 0x1,
|
||||
MSM_VIDC_USERDATA_TYPE_TOP_FIELD = 0x2,
|
||||
MSM_VIDC_USERDATA_TYPE_BOTTOM_FIELD = 0x3,
|
||||
};
|
||||
|
||||
/* See colour_primaries of ISO/IEC 14496 for significance */
|
||||
enum msm_vidc_h264_color_primaries_values {
|
||||
MSM_VIDC_RESERVED_1 = 0,
|
||||
MSM_VIDC_BT709_5 = 1,
|
||||
MSM_VIDC_UNSPECIFIED = 2,
|
||||
MSM_VIDC_RESERVED_2 = 3,
|
||||
MSM_VIDC_BT470_6_M = 4,
|
||||
MSM_VIDC_BT601_6_625 = 5,
|
||||
MSM_VIDC_BT470_6_BG = MSM_VIDC_BT601_6_625,
|
||||
MSM_VIDC_BT601_6_525 = 6,
|
||||
MSM_VIDC_SMPTE_240M = 7,
|
||||
MSM_VIDC_GENERIC_FILM = 8,
|
||||
MSM_VIDC_BT2020 = 9,
|
||||
};
|
||||
|
||||
enum msm_vidc_vp9_color_primaries_values {
|
||||
MSM_VIDC_CS_UNKNOWN,
|
||||
MSM_VIDC_CS_BT_601,
|
||||
MSM_VIDC_CS_BT_709,
|
||||
MSM_VIDC_CS_SMPTE_170,
|
||||
MSM_VIDC_CS_SMPTE_240,
|
||||
MSM_VIDC_CS_BT_2020,
|
||||
MSM_VIDC_CS_RESERVED,
|
||||
MSM_VIDC_CS_RGB,
|
||||
};
|
||||
|
||||
enum msm_vidc_h264_matrix_coeff_values {
|
||||
MSM_VIDC_MATRIX_RGB = 0,
|
||||
MSM_VIDC_MATRIX_BT_709_5 = 1,
|
||||
MSM_VIDC_MATRIX_UNSPECIFIED = 2,
|
||||
MSM_VIDC_MATRIX_RESERVED = 3,
|
||||
MSM_VIDC_MATRIX_FCC_47 = 4,
|
||||
MSM_VIDC_MATRIX_601_6_625 = 5,
|
||||
MSM_VIDC_MATRIX_BT470_BG = MSM_VIDC_MATRIX_601_6_625,
|
||||
MSM_VIDC_MATRIX_601_6_525 = 6,
|
||||
MSM_VIDC_MATRIX_SMPTE_170M = MSM_VIDC_MATRIX_601_6_525,
|
||||
MSM_VIDC_MATRIX_SMPTE_240M = 7,
|
||||
MSM_VIDC_MATRIX_Y_CG_CO = 8,
|
||||
MSM_VIDC_MATRIX_BT_2020 = 9,
|
||||
MSM_VIDC_MATRIX_BT_2020_CONST = 10,
|
||||
};
|
||||
|
||||
enum msm_vidc_h264_transfer_chars_values {
|
||||
MSM_VIDC_TRANSFER_RESERVED_1 = 0,
|
||||
MSM_VIDC_TRANSFER_BT709_5 = 1,
|
||||
MSM_VIDC_TRANSFER_UNSPECIFIED = 2,
|
||||
MSM_VIDC_TRANSFER_RESERVED_2 = 3,
|
||||
MSM_VIDC_TRANSFER_BT_470_6_M = 4,
|
||||
MSM_VIDC_TRANSFER_BT_470_6_BG = 5,
|
||||
MSM_VIDC_TRANSFER_601_6_625 = 6,
|
||||
MSM_VIDC_TRANSFER_601_6_525 = MSM_VIDC_TRANSFER_601_6_625,
|
||||
MSM_VIDC_TRANSFER_SMPTE_240M = 7,
|
||||
MSM_VIDC_TRANSFER_LINEAR = 8,
|
||||
MSM_VIDC_TRANSFER_LOG_100_1 = 9,
|
||||
MSM_VIDC_TRANSFER_LOG_100_SQRT10_1 = 10,
|
||||
MSM_VIDC_TRANSFER_IEC_61966 = 11,
|
||||
MSM_VIDC_TRANSFER_BT_1361 = 12,
|
||||
MSM_VIDC_TRANSFER_SRGB = 13,
|
||||
MSM_VIDC_TRANSFER_BT_2020_10 = 14,
|
||||
MSM_VIDC_TRANSFER_BT_2020_12 = 15,
|
||||
#define MSM_VIDC_TRANSFER_SMPTE_ST2084 \
|
||||
MSM_VIDC_TRANSFER_SMPTE_ST2084
|
||||
MSM_VIDC_TRANSFER_SMPTE_ST2084 = 16,
|
||||
#define MSM_VIDC_TRANSFER_SMPTE_ST428_1 \
|
||||
MSM_VIDC_TRANSFER_SMPTE_ST428_1
|
||||
MSM_VIDC_TRANSFER_SMPTE_ST428_1 = 17,
|
||||
#define MSM_VIDC_TRANSFER_HLG \
|
||||
MSM_VIDC_TRANSFER_HLG
|
||||
MSM_VIDC_TRANSFER_HLG = 18,
|
||||
};
|
||||
|
||||
enum msm_vidc_pixel_depth {
|
||||
MSM_VIDC_BIT_DEPTH_8,
|
||||
MSM_VIDC_BIT_DEPTH_10,
|
||||
MSM_VIDC_BIT_DEPTH_UNSUPPORTED = 0XFFFFFFFF,
|
||||
};
|
||||
|
||||
enum msm_vidc_video_format {
|
||||
MSM_VIDC_COMPONENT,
|
||||
MSM_VIDC_PAL,
|
||||
MSM_VIDC_NTSC,
|
||||
MSM_VIDC_SECAM,
|
||||
MSM_VIDC_MAC,
|
||||
MSM_VIDC_UNSPECIFIED_FORMAT,
|
||||
MSM_VIDC_RESERVED_1_FORMAT,
|
||||
MSM_VIDC_RESERVED_2_FORMAT,
|
||||
};
|
||||
|
||||
enum msm_vidc_color_desc_flag {
|
||||
MSM_VIDC_COLOR_DESC_NOT_PRESENT,
|
||||
MSM_VIDC_COLOR_DESC_PRESENT,
|
||||
};
|
||||
|
||||
/*enum msm_vidc_pic_struct */
|
||||
#define MSM_VIDC_PIC_STRUCT_MAYBE_INTERLACED 0x0
|
||||
#define MSM_VIDC_PIC_STRUCT_PROGRESSIVE 0x1
|
||||
#define MSM_VIDC_PIC_STRUCT_UNKNOWN 0XFFFFFFFF
|
||||
/*default when layer ID isn't specified*/
|
||||
#define MSM_VIDC_ALL_LAYER_ID 0xFF
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue