mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
v2d: add new composer device. [1/1]
PD#SWPL-183637 Problem: add new composer device Solution: add new composer device Verify: SC2 Change-Id: I4f70a9c195c2ca2ffd4e311f4f2250618343baf8 Signed-off-by: zhenteng.tian <zhenteng.tian@amlogic.com>
This commit is contained in:
committed by
gerrit autosubmit
parent
9f5cb6fdd6
commit
e007cda856
@@ -1823,6 +1823,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
v2d {
|
||||
compatible = "amlogic, v2d";
|
||||
dev_name = "v2d";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
video_composer {
|
||||
compatible = "amlogic, video_composer";
|
||||
dev_name = "video_composer";
|
||||
|
||||
@@ -206,6 +206,7 @@ CONFIG_AMLOGIC_VIDEO_PP_COMMON=y
|
||||
CONFIG_AMLOGIC_VIDEO_TUNNEL=y
|
||||
CONFIG_AMLOGIC_VIDEOQUEUE=y
|
||||
CONFIG_AMLOGIC_DI_PROCESS=y
|
||||
CONFIG_AMLOGIC_MEDIA_V2D=y
|
||||
CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM=y
|
||||
CONFIG_AMLOGIC_MEDIA_FRC=y
|
||||
CONFIG_AMLOGIC_MEDIA_GDC=y
|
||||
|
||||
@@ -1823,6 +1823,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
v2d {
|
||||
compatible = "amlogic, v2d";
|
||||
dev_name = "v2d";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
video_composer {
|
||||
compatible = "amlogic, video_composer";
|
||||
dev_name = "video_composer";
|
||||
|
||||
@@ -238,6 +238,7 @@ CONFIG_AMLOGIC_VIDEO_DISPLAY=y
|
||||
CONFIG_AMLOGIC_VIDEO_PP_COMMON=y
|
||||
CONFIG_AMLOGIC_VIDEO_TUNNEL=y
|
||||
CONFIG_AMLOGIC_VIDEOQUEUE=y
|
||||
CONFIG_AMLOGIC_MEDIA_V2D=y
|
||||
CONFIG_AMLOGIC_DI_PROCESS=y
|
||||
CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM=y
|
||||
CONFIG_AMLOGIC_MEDIA_FRC=y
|
||||
|
||||
@@ -660,6 +660,14 @@ ddk_module(
|
||||
"video_processor/di_process/di_process.c",
|
||||
],
|
||||
},
|
||||
"CONFIG_AMLOGIC_MEDIA_V2D": {
|
||||
True: [
|
||||
"video_processor/v2d/v2d.c",
|
||||
"video_processor/v2d/v2d_dewarp_composer.c",
|
||||
"video_processor/v2d/v2d_ge2d_composer.c",
|
||||
"video_processor/v2d/v2d_vicp_composer.c",
|
||||
],
|
||||
},
|
||||
"CONFIG_AMLOGIC_VIDEO_DISPLAY": {
|
||||
True: [
|
||||
"video_processor/videodisplay/videodisplay_util.c",
|
||||
|
||||
@@ -120,6 +120,7 @@ static int __init media_main_init(void)
|
||||
call_sub_init(amlogic_codec_mm_dma_buf_init);
|
||||
call_sub_init(amprime_sl_init);
|
||||
call_sub_init(di_process_module_init);
|
||||
call_sub_init(v2d_module_init);
|
||||
pr_debug("### %s() end\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -765,4 +765,13 @@ static inline int di_process_module_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_V2D
|
||||
int v2d_module_init(void);
|
||||
#else
|
||||
static inline int v2d_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,7 @@ source "$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/videoqueue/Kconfig"
|
||||
source "$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/common/Kconfig"
|
||||
source "$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/di_process/Kconfig"
|
||||
source "$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/videodisplay/Kconfig"
|
||||
source "$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/v2d/Kconfig"
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -11,3 +11,4 @@ include $(srctree)/$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/videoqueu
|
||||
include $(srctree)/$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/common/Makefile
|
||||
include $(srctree)/$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/di_process/Makefile
|
||||
include $(srctree)/$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/videodisplay/Makefile
|
||||
include $(srctree)/$(COMMON_DRIVERS_DIR)/drivers/media/video_processor/v2d/Makefile
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
|
||||
#
|
||||
# Amlogic v2d device configuration
|
||||
#
|
||||
|
||||
menu "Amlogic v2d support"
|
||||
|
||||
config AMLOGIC_MEDIA_V2D
|
||||
tristate "Amlogic v2d device support"
|
||||
default y
|
||||
|
||||
help
|
||||
Select to enable "Amlogic v2d device support.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,8 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
|
||||
asflags-y += -mfloat-abi=softfp -mfpu=neon
|
||||
|
||||
$(MEDIA_MODULE_NAME)-$(CONFIG_AMLOGIC_MEDIA_V2D) += video_processor/v2d/v2d.o
|
||||
$(MEDIA_MODULE_NAME)-$(CONFIG_AMLOGIC_MEDIA_V2D) += video_processor/v2d/v2d_ge2d_composer.o
|
||||
$(MEDIA_MODULE_NAME)-$(CONFIG_AMLOGIC_MEDIA_V2D) += video_processor/v2d/v2d_dewarp_composer.o
|
||||
$(MEDIA_MODULE_NAME)-$(CONFIG_AMLOGIC_MEDIA_V2D) += video_processor/v2d/v2d_vicp_composer.o
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,286 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef V2D_H
|
||||
#define V2D_H
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
#include <linux/amlogic/media/vfm/vframe.h>
|
||||
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/amlogic/media/video_sink/v4lvideo_ext.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/amlogic/media/ge2d/ge2d.h>
|
||||
#include <linux/amlogic/media/video_sink/video.h>
|
||||
#include "v2d_ge2d_composer.h"
|
||||
#include "v2d_dewarp_composer.h"
|
||||
#include "v2d_vicp_composer.h"
|
||||
|
||||
#define MAX_LAYER_COUNT 9
|
||||
#define V2D_POOL_SIZE 16
|
||||
#define BUFFER_LEN 4
|
||||
#define V2D_SET_ENABLE_MODE 1
|
||||
#define V2D_SET_DISABLE_MODE 0
|
||||
|
||||
#define PRINT_ERROR 0X0
|
||||
#define PRINT_QUEUE_STATUS 0X01
|
||||
#define PRINT_FENCE 0X02
|
||||
#define PRINT_PERFORMANCE 0X04
|
||||
#define PRINT_AXIS 0X08
|
||||
#define PRINT_INDEX_DISP 0X10
|
||||
#define PRINT_PATTERN 0X20
|
||||
#define PRINT_OTHER 0X040
|
||||
#define PRINT_DEWARP 0X0100
|
||||
#define PRINT_VICP 0x0200
|
||||
|
||||
#define WAIT_READY_Q_TIMEOUT 100
|
||||
#define WAIT_DISPLAY_Q_TIMEOUT 100
|
||||
#define MAX_RECEIVE_WAIT_TIME 15 /*15ms*/
|
||||
|
||||
#define V2D_IOC_MAGIC 'R'
|
||||
#define V2D_IOCTL_SET_FRAMES _IOW(V2D_IOC_MAGIC, 0x00, struct frames_info_t)
|
||||
#define V2D_IOCTL_SET_ENABLE _IOW(V2D_IOC_MAGIC, 0x01, int)
|
||||
#define V2D_IOCTL_SET_FENCE _IOW(V2D_IOC_MAGIC, 0x02, struct release_info_t)
|
||||
|
||||
struct frame_info_t {
|
||||
s32 fd;
|
||||
s32 fence_fd;
|
||||
s32 buffer_w;
|
||||
s32 buffer_h;
|
||||
s32 align_w;
|
||||
s32 align_h;
|
||||
s32 dst_x;
|
||||
s32 dst_y;
|
||||
s32 dst_w;
|
||||
s32 dst_h;
|
||||
s32 crop_x;
|
||||
s32 crop_y;
|
||||
s32 crop_w;
|
||||
s32 crop_h;
|
||||
s32 zorder;
|
||||
s32 buffer_format;
|
||||
s32 transform;
|
||||
s32 alpha;
|
||||
s32 reserved[10];
|
||||
};
|
||||
|
||||
struct frames_info_t {
|
||||
s32 frame_count;
|
||||
struct frame_info_t input_buffer[MAX_LAYER_COUNT];
|
||||
struct frame_info_t out_buffer;
|
||||
s32 reserved[4];
|
||||
};
|
||||
|
||||
struct release_info_t {
|
||||
s32 release_fd;
|
||||
s32 release_fence_fd;
|
||||
};
|
||||
|
||||
enum v2d_buffer_status {
|
||||
UNINITIAL = 0,
|
||||
INIT_SIZE_SUCCESS,
|
||||
INIT_BUFFER_SUCCESS,
|
||||
INIT_BUFFER_ERROR,
|
||||
};
|
||||
|
||||
struct input_crop_s {
|
||||
u32 left;
|
||||
u32 top;
|
||||
u32 width;
|
||||
u32 height;
|
||||
};
|
||||
|
||||
struct input_axis_s {
|
||||
int left;
|
||||
int top;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct output_axis {
|
||||
u32 min_left;
|
||||
u32 min_top;
|
||||
u32 max_right;
|
||||
u32 max_bottom;
|
||||
};
|
||||
|
||||
enum v2d_transform_t {
|
||||
/* flip source image horizontally */
|
||||
V2D_TRANSFORM_FLIP_H = 1,
|
||||
/* flip source image vertically */
|
||||
V2D_TRANSFORM_FLIP_V = 2,
|
||||
/* rotate source image 90 degrees clock-wise */
|
||||
V2D_TRANSFORM_ROT_90 = 4,
|
||||
/* rotate source image 180 degrees */
|
||||
V2D_TRANSFORM_ROT_180 = 3,
|
||||
/* rotate source image 270 degrees clock-wise */
|
||||
V2D_TRANSFORM_ROT_270 = 7,
|
||||
/* flip source image horizontally, the rotate 90 degrees clock-wise */
|
||||
V2D_TRANSFORM_FLIP_H_ROT_90 = V2D_TRANSFORM_FLIP_H | V2D_TRANSFORM_ROT_90,
|
||||
/* flip source image vertically, the rotate 90 degrees clock-wise */
|
||||
V2D_TRANSFORM_FLIP_V_ROT_90 = V2D_TRANSFORM_FLIP_V | V2D_TRANSFORM_ROT_90,
|
||||
};
|
||||
|
||||
enum buffer_format_t {
|
||||
NV21 = 0,
|
||||
YUV444 = 1,
|
||||
};
|
||||
|
||||
enum output_buf_mode_t {
|
||||
BUFFER_MODE_UNINIT = 0,
|
||||
BUFFER_MODE_GE2D,
|
||||
BUFFER_MODE_DEWARP,
|
||||
BUFFER_MODE_VICP,
|
||||
};
|
||||
|
||||
struct received_frames_t {
|
||||
int index;
|
||||
atomic_t on_use;
|
||||
struct input_crop_s crop_info[MAX_LAYER_COUNT];
|
||||
struct input_axis_s axis_info[MAX_LAYER_COUNT];
|
||||
struct output_axis output_axis;
|
||||
struct frames_info_t frames_info;
|
||||
struct file *input_file[MAX_LAYER_COUNT];
|
||||
struct file *input_fence[MAX_LAYER_COUNT];
|
||||
unsigned long phy_addr[MAX_LAYER_COUNT];
|
||||
bool is_tvp;
|
||||
size_t usage;
|
||||
};
|
||||
|
||||
struct dst_buf_t {
|
||||
int index;
|
||||
struct composer_info_t composer_info;
|
||||
enum output_buf_mode_t buf_used;
|
||||
bool dirty;
|
||||
ulong phy_addr;
|
||||
u32 buf_w;
|
||||
u32 buf_h;
|
||||
u32 buf_size;
|
||||
bool is_tvp;
|
||||
u32 dw_size;
|
||||
ulong afbc_head_addr;
|
||||
u32 afbc_head_size;
|
||||
ulong afbc_body_addr;
|
||||
u32 afbc_body_size;
|
||||
ulong afbc_table_addr;
|
||||
ulong afbc_table_handle;
|
||||
u32 afbc_table_size;
|
||||
};
|
||||
|
||||
struct v2d_fence_cb_t {
|
||||
struct dma_fence_cb base_cb;
|
||||
struct v2d_dev *dev;
|
||||
struct file *buffer_file;
|
||||
struct file *fence_file;
|
||||
};
|
||||
|
||||
struct display_data_t {
|
||||
struct dma_buf *output_dmabuf;
|
||||
struct dst_buf_t *output_buffer;
|
||||
atomic_t on_use;
|
||||
};
|
||||
|
||||
enum composer_dev {
|
||||
COMPOSER_WITH_DEFAULT = 0,
|
||||
COMPOSER_WITH_GE2D,
|
||||
COMPOSER_WITH_DEWARP,
|
||||
COMPOSER_WITH_VICP,
|
||||
COMPOSER_WITH_UNINITIAL,
|
||||
};
|
||||
|
||||
enum v2d_work_mode {
|
||||
V2D_MODE_UNINITIAL = 0,
|
||||
V2D_MODE_ROTATE,
|
||||
V2D_MODE_COMPOSER,
|
||||
};
|
||||
|
||||
union composer_device_config {
|
||||
struct ge2d_src_para_s ge2d_data;
|
||||
struct dewarp_vf_para_s dewarp_data;
|
||||
struct vicp_data_config_s vicp_data;
|
||||
};
|
||||
|
||||
struct v2d_dev_config {
|
||||
union composer_device_config composer_device_param;
|
||||
unsigned long addr;
|
||||
struct vframe_s *input_vf;
|
||||
struct dst_buf_t *dst_buf;
|
||||
struct input_axis_s frame_axis;
|
||||
struct input_crop_s frame_crop;
|
||||
int count;
|
||||
int index;
|
||||
int zorder;
|
||||
bool is_tvp;
|
||||
};
|
||||
|
||||
struct v2d_dev {
|
||||
u32 index;
|
||||
struct v2d_port_s *port;
|
||||
enum composer_dev dev_choice;
|
||||
enum v2d_work_mode work_mode;
|
||||
bool status_enabled;
|
||||
DECLARE_KFIFO(receive_q, struct received_frames_t *, V2D_POOL_SIZE);
|
||||
DECLARE_KFIFO(free_q, struct dst_buf_t *, BUFFER_LEN);
|
||||
DECLARE_KFIFO(file_free_q, struct dma_buf *, V2D_POOL_SIZE);
|
||||
DECLARE_KFIFO(file_wait_q, struct dma_buf *, V2D_POOL_SIZE);
|
||||
DECLARE_KFIFO(display_q, struct display_data_t *, BUFFER_LEN);
|
||||
DECLARE_KFIFO(fence_wait_q, struct file *, V2D_POOL_SIZE);
|
||||
DECLARE_KFIFO(fence_cb_q, struct v2d_fence_cb_t *, V2D_POOL_SIZE);
|
||||
struct received_frames_t received_frames[V2D_POOL_SIZE];
|
||||
struct dst_buf_t dst_buf[BUFFER_LEN];
|
||||
struct v2d_fence_cb_t v2d_fence_cb[V2D_POOL_SIZE];
|
||||
struct display_data_t display_data[V2D_POOL_SIZE];
|
||||
struct task_struct *file_thread;
|
||||
wait_queue_head_t file_wq;
|
||||
struct completion file_task_done;
|
||||
struct dma_buf *out_dmabuf[V2D_POOL_SIZE];
|
||||
void *v2d_timeline;
|
||||
u32 cur_streamline_val;
|
||||
u32 buf_width;
|
||||
u32 buf_height;
|
||||
int (*config_param_func)(struct v2d_dev *dev,
|
||||
struct frame_info_t *vframe_info_cur, struct v2d_dev_config *v2d_composer_param);
|
||||
int (*process_data_func)(struct v2d_dev *dev, struct v2d_dev_config *v2d_composer_param);
|
||||
enum v2d_buffer_status buffer_status;
|
||||
struct ge2d_composer_para ge2d_para;
|
||||
struct dewarp_composer_para dewarp_para;
|
||||
u32 vinfo_w;
|
||||
u32 vinfo_h;
|
||||
u32 output_duration;
|
||||
u32 file_thread_stopped;
|
||||
bool thread_need_stop;
|
||||
bool need_do_file;
|
||||
u32 fget_count;
|
||||
u32 fput_count;
|
||||
u32 received_count;
|
||||
u32 received_new_count;
|
||||
u32 fence_creat_count;
|
||||
u32 fence_signal_count;
|
||||
u32 buffer_release_count;
|
||||
u32 fence_wait_count;
|
||||
u32 fence_wait_time_total;
|
||||
};
|
||||
|
||||
struct v2d_port_s {
|
||||
const char *name;
|
||||
u32 index;
|
||||
u32 open_count;
|
||||
struct device *class_dev;
|
||||
struct device *pdev;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,457 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/amlogic/media/ge2d/ge2d.h>
|
||||
#include <linux/amlogic/media/canvas/canvas.h>
|
||||
#include <linux/amlogic/media/canvas/canvas_mgr.h>
|
||||
#include <linux/amlogic/media/utils/amlog.h>
|
||||
#include <linux/amlogic/media/ge2d/ge2d_func.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/amlogic/media/codec_mm/codec_mm.h>
|
||||
#include <linux/amlogic/media/vfm/vframe.h>
|
||||
#include <api/gdc_api.h>
|
||||
#include "v2d_dewarp_composer.h"
|
||||
|
||||
#define GDC_FIRMWARE_PATH "/vendor/lib/firmware/gdc/"
|
||||
|
||||
static unsigned int dewarp_com_dump_last;
|
||||
int v2d_get_dewarp_format(int index, struct vframe_s *vf)
|
||||
{
|
||||
int format = NV12;
|
||||
|
||||
if (IS_ERR_OR_NULL(vf)) {
|
||||
pr_info("v2d:[%d] %s: vf is NULL.\n", index, __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((vf->type & VIDTYPE_VIU_NV21) ||
|
||||
(vf->type & VIDTYPE_VIU_NV12))
|
||||
format = NV12;
|
||||
else if (vf->type & VIDTYPE_VIU_422)
|
||||
format = 0;
|
||||
else if (vf->type & VIDTYPE_VIU_444)
|
||||
format = YUV444_P;
|
||||
else if (vf->type & VIDTYPE_RGB_444)
|
||||
format = RGB444_P;
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static int get_dewarp_rotation_value(int transform)
|
||||
{
|
||||
int rotate_value = 0;
|
||||
|
||||
if (transform == 4 || transform == 5 || transform == 6)
|
||||
rotate_value = 270;
|
||||
else if (transform == 3)
|
||||
rotate_value = 180;
|
||||
else if (transform == 7)
|
||||
rotate_value = 90;
|
||||
else
|
||||
rotate_value = 0;
|
||||
|
||||
return rotate_value;
|
||||
}
|
||||
|
||||
static int dump_dewarp_vframe(char *path, int width, int height, u32 phy_adr_y, u32 phy_adr_uv)
|
||||
{
|
||||
#ifdef CONFIG_AMLOGIC_ENABLE_VIDEO_PIPELINE_DUMP_DATA
|
||||
int size = 0;
|
||||
struct file *fp = NULL;
|
||||
loff_t position = 0;
|
||||
u8 *data;
|
||||
|
||||
if (IS_ERR_OR_NULL(path)) {
|
||||
pr_info("%s: path is NULL.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open file to write */
|
||||
fp = filp_open(path, O_WRONLY | O_CREAT, 0644);
|
||||
if (IS_ERR(fp)) {
|
||||
pr_info("%s: open file error\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Write buf to file */
|
||||
size = width * height;
|
||||
data = codec_mm_vmap(phy_adr_y, size);
|
||||
if (!data) {
|
||||
pr_info("%s: vmap failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
/* change to KERNEL_DS address limit */
|
||||
kernel_write(fp, data, size, &position);
|
||||
codec_mm_unmap_phyaddr(data);
|
||||
|
||||
size = width * height / 2;
|
||||
data = codec_mm_vmap(phy_adr_uv, size);
|
||||
if (!data) {
|
||||
pr_info("%s: vmap failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
/* change to KERNEL_DS address limit */
|
||||
kernel_write(fp, data, size, &position);
|
||||
codec_mm_unmap_phyaddr(data);
|
||||
|
||||
filp_close(fp, NULL);
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int v2d_load_dewarp_firmware(struct dewarp_composer_para *param)
|
||||
{
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_GDC
|
||||
int ret = 0;
|
||||
#endif
|
||||
char file_name[64];
|
||||
struct firmware_rotate_s fw_param;
|
||||
bool is_need_load = false;
|
||||
int frame_rotation = 0;
|
||||
|
||||
if (IS_ERR_OR_NULL(param)) {
|
||||
pr_info("%s: NULL param, please check.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
frame_rotation = get_dewarp_rotation_value(param->vf_para->src_vf_angle);
|
||||
if (param->last_fw_param.in_width != param->vf_para->src_vf_width ||
|
||||
param->last_fw_param.in_height != param->vf_para->src_vf_height ||
|
||||
param->last_fw_param.out_width != param->vf_para->dst_vf_width ||
|
||||
param->last_fw_param.out_height != param->vf_para->dst_vf_height ||
|
||||
param->last_fw_param.degree != frame_rotation) {
|
||||
param->last_fw_param.format = NV12;
|
||||
param->last_fw_param.in_width = param->vf_para->src_vf_width;
|
||||
param->last_fw_param.in_height = param->vf_para->src_vf_height;
|
||||
param->last_fw_param.out_width = param->vf_para->dst_vf_width;
|
||||
param->last_fw_param.out_height = param->vf_para->dst_vf_height;
|
||||
param->last_fw_param.degree = frame_rotation;
|
||||
is_need_load = true;
|
||||
}
|
||||
|
||||
if (dewarp_print) {
|
||||
pr_info("v2d:[%d] need load firmware: %d.\n", param->index, is_need_load);
|
||||
pr_info("v2d:[%d] src_vf, w:%d, h:%d, fromat:%d, rotation:%d.\n",
|
||||
param->index,
|
||||
param->vf_para->src_vf_width,
|
||||
param->vf_para->src_vf_height,
|
||||
param->vf_para->src_vf_format,
|
||||
param->vf_para->src_vf_angle);
|
||||
pr_info("v2d:[%d] src_buf, w0:%d, w1:%d.\n", param->index,
|
||||
param->vf_para->src_buf_stride0, param->vf_para->src_buf_stride1);
|
||||
pr_info("v2d:[%d] dst_vf, w:%d, h:%d.\n", param->index,
|
||||
param->vf_para->dst_vf_width, param->vf_para->dst_vf_height);
|
||||
pr_info("v2d:[%d] dst_buf, w:%d.\n", param->index,
|
||||
param->vf_para->dst_buf_stride);
|
||||
}
|
||||
|
||||
if (param->fw_load.phys_addr == 0 || is_need_load) {
|
||||
v2d_unload_dewarp_firmware(param);
|
||||
pr_info("v2d:[%d] start load firmware.\n", param->index);
|
||||
if (dewarp_load_flag) {
|
||||
memset(file_name, 0, 64);
|
||||
sprintf(file_name, "%dx%d-%dx%d-%d_nv12.bin",
|
||||
param->vf_para->src_vf_width,
|
||||
param->vf_para->src_vf_height,
|
||||
param->vf_para->dst_vf_width,
|
||||
param->vf_para->dst_vf_height,
|
||||
frame_rotation);
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_GDC
|
||||
ret = load_firmware_by_name(file_name, ¶m->fw_load);
|
||||
if (ret <= 0) {
|
||||
pr_info("v2d:[%d] %s: load firmware failed.\n",
|
||||
param->index, __func__);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
} else {
|
||||
fw_param.format = NV12;
|
||||
fw_param.in_width = param->vf_para->src_vf_width;
|
||||
fw_param.in_height = param->vf_para->src_vf_height;
|
||||
fw_param.out_width = param->vf_para->dst_vf_width;
|
||||
fw_param.out_height = param->vf_para->dst_vf_height;
|
||||
fw_param.degree = frame_rotation;
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_GDC
|
||||
ret = rotation_calc_and_load_firmware(&fw_param, ¶m->fw_load);
|
||||
if (ret <= 0) {
|
||||
pr_info("v2d:[%d] %s: calc and load firmware failed.\n",
|
||||
param->index, __func__);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_unload_dewarp_firmware(struct dewarp_composer_para *param)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(param)) {
|
||||
pr_info("%s: NULL param, please check.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (param->fw_load.phys_addr != 0) {
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_GDC
|
||||
release_config_firmware(¶m->fw_load);
|
||||
#endif
|
||||
param->fw_load.phys_addr = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool check_dewarp_status(struct vframe_s *input_vf, int count, int work_mode, int index)
|
||||
{
|
||||
int src_formate;
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_GDC
|
||||
if (!is_aml_gdc_supported())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (count > 1) {
|
||||
pr_info("%s: dewarp not support composer.\n", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (work_mode != 1)
|
||||
return false;
|
||||
|
||||
if (!input_vf)
|
||||
src_formate = NV12;
|
||||
else
|
||||
src_formate = v2d_get_dewarp_format(index, input_vf);
|
||||
if (src_formate != NV12)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int v2d_init_dewarp_composer(struct dewarp_composer_para *param)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(param)) {
|
||||
pr_info("%s: NULL param, please check.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(param->context)) {
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_GDC
|
||||
param->context = create_gdc_work_queue(AML_GDC);
|
||||
#else
|
||||
param->context = NULL;
|
||||
#endif
|
||||
if (IS_ERR_OR_NULL(param->context)) {
|
||||
pr_info("v2d:[%d] %s: create dewrap work_queue failed.\n",
|
||||
param->index,
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
pr_info("v2d:[%d] %s: dewrap work queue exist.\n",
|
||||
param->index, __func__);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_uninit_dewarp_composer(struct dewarp_composer_para *param)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR_OR_NULL(param)) {
|
||||
pr_info("%s: NULL param, please check.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
v2d_unload_dewarp_firmware(param);
|
||||
|
||||
if (!IS_ERR_OR_NULL(param->context)) {
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_GDC
|
||||
ret = destroy_gdc_work_queue(param->context);
|
||||
#else
|
||||
ret = -1;
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
pr_info("v2d:[%d] %s: destroy dewarp work queue failed.\n",
|
||||
param->index,
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
pr_info("v2d:[%d] %s: destroy dewarp work queue success.\n",
|
||||
param->index, __func__);
|
||||
} else {
|
||||
pr_info("v2d:[%d] %s: dewarp work queue not create.\n",
|
||||
param->index,
|
||||
__func__);
|
||||
}
|
||||
|
||||
param->context = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_config_dewarp_vframe(struct dewarp_vf_para_s *vframe_para,
|
||||
struct dewarp_common_para *common_para)
|
||||
{
|
||||
struct vframe_s *vf = NULL;
|
||||
struct vframe_s *src_vf = common_para->input_para.vframe;
|
||||
int call_index = common_para->input_para.call_index;
|
||||
struct pic_s *pic_info_in = &common_para->input_para.pic_info;
|
||||
struct pic_s *pic_info_out = &common_para->output_para.pic_info;
|
||||
|
||||
if (IS_ERR_OR_NULL(vframe_para)) {
|
||||
pr_info("v2d:[%d] %s: vframe_para is null.\n", call_index, __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src_vf) {
|
||||
if (src_vf->canvas0_config[0].phy_addr == 0) {
|
||||
if ((src_vf->flag & VFRAME_FLAG_DOUBLE_FRAM) &&
|
||||
src_vf->vf_ext) {
|
||||
vf = src_vf->vf_ext;
|
||||
} else {
|
||||
pr_info("v2d:[%d] %s: vf no yuv data.\n", call_index, __func__);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
vf = src_vf;
|
||||
}
|
||||
|
||||
vframe_para->src_vf_width = vf->width;
|
||||
vframe_para->src_vf_height = vf->height;
|
||||
vframe_para->src_vf_format = v2d_get_dewarp_format(call_index, vf);
|
||||
vframe_para->src_vf_plane_count = 2;
|
||||
vframe_para->src_buf_addr0 = vf->canvas0_config[0].phy_addr;
|
||||
vframe_para->src_buf_stride0 = vf->canvas0_config[0].width;
|
||||
vframe_para->src_buf_addr1 = vf->canvas0_config[1].phy_addr;
|
||||
vframe_para->src_buf_stride1 = vf->canvas0_config[1].width;
|
||||
vframe_para->src_vf_angle = common_para->input_para.transform;
|
||||
vframe_para->src_endian = vf->canvas0_config[0].endian;
|
||||
if (vf->type & VIDTYPE_VIU_NV12)
|
||||
vframe_para->uvswap_enable = 1;
|
||||
|
||||
vframe_para->dst_vf_width = pic_info_out->align_w;
|
||||
vframe_para->dst_vf_height = pic_info_out->align_h;
|
||||
vframe_para->dst_vf_plane_count = 2;
|
||||
vframe_para->dst_buf_addr = pic_info_out->addr[0];
|
||||
vframe_para->dst_buf_stride = pic_info_out->align_w;
|
||||
vframe_para->dst_endian = 0;
|
||||
vframe_para->is_tvp = pic_info_in->is_tvp;
|
||||
} else {
|
||||
if (pic_info_in->format == 1) {
|
||||
vframe_para->src_vf_format = YUV444_P;
|
||||
vframe_para->src_buf_stride0 = pic_info_in->align_w * 3;
|
||||
} else {
|
||||
vframe_para->src_vf_format = NV12;
|
||||
vframe_para->src_buf_stride0 = pic_info_in->align_w;
|
||||
}
|
||||
|
||||
vframe_para->src_vf_width = pic_info_in->width;
|
||||
vframe_para->src_vf_height = pic_info_in->height;
|
||||
vframe_para->src_vf_plane_count = 2;
|
||||
vframe_para->src_buf_addr0 = pic_info_in->addr[0];
|
||||
vframe_para->src_buf_addr1 = pic_info_in->addr[0]
|
||||
+ vframe_para->src_buf_stride0 * pic_info_in->align_h;
|
||||
vframe_para->src_buf_stride1 = vframe_para->src_buf_stride0;
|
||||
vframe_para->src_vf_angle = common_para->input_para.transform;
|
||||
vframe_para->src_endian = 0;
|
||||
|
||||
vframe_para->dst_vf_width = pic_info_out->align_w;
|
||||
vframe_para->dst_vf_height = pic_info_out->align_h;
|
||||
vframe_para->dst_vf_plane_count = 2;
|
||||
vframe_para->dst_buf_addr = pic_info_out->addr[0];
|
||||
vframe_para->dst_buf_stride = pic_info_out->align_w;
|
||||
vframe_para->dst_endian = 0;
|
||||
vframe_para->is_tvp = pic_info_in->is_tvp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_dewarp_data_composer(struct dewarp_composer_para *param, bool is_tvp)
|
||||
{
|
||||
int ret;
|
||||
struct gdc_phy_setting gdc_config;
|
||||
char dump_name[32];
|
||||
|
||||
if (IS_ERR_OR_NULL(param)) {
|
||||
pr_info("%s: NULL param, please check.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&gdc_config, 0, sizeof(struct gdc_phy_setting));
|
||||
gdc_config.format = param->vf_para->src_vf_format;
|
||||
gdc_config.in_width = param->vf_para->src_vf_width;
|
||||
gdc_config.in_height = param->vf_para->src_vf_height;
|
||||
/*16-byte alignment*/
|
||||
gdc_config.in_y_stride = AXI_WORD_ALIGN(param->vf_para->src_buf_stride0);
|
||||
/*16-byte alignment*/
|
||||
gdc_config.in_c_stride = AXI_WORD_ALIGN(param->vf_para->src_buf_stride1);
|
||||
gdc_config.in_plane_num = param->vf_para->src_vf_plane_count;
|
||||
gdc_config.out_width = param->vf_para->dst_vf_width;
|
||||
gdc_config.out_height = param->vf_para->dst_vf_height;
|
||||
/*16-byte alignment*/
|
||||
gdc_config.out_y_stride = AXI_WORD_ALIGN(param->vf_para->dst_buf_stride);
|
||||
/*16-byte alignment*/
|
||||
gdc_config.out_c_stride = AXI_WORD_ALIGN(param->vf_para->dst_buf_stride);
|
||||
gdc_config.out_plane_num = param->vf_para->dst_vf_plane_count;
|
||||
gdc_config.in_paddr[0] = param->vf_para->src_buf_addr0;
|
||||
gdc_config.in_paddr[1] = param->vf_para->src_buf_addr1;
|
||||
gdc_config.out_paddr[0] = param->vf_para->dst_buf_addr;
|
||||
gdc_config.out_paddr[1] = param->vf_para->dst_buf_addr
|
||||
+ AXI_WORD_ALIGN(gdc_config.out_width)
|
||||
* AXI_WORD_ALIGN(gdc_config.out_height);
|
||||
gdc_config.config_paddr = param->fw_load.phys_addr;
|
||||
gdc_config.config_size = param->fw_load.size_32bit; /* in 32bit */
|
||||
gdc_config.uvswap_enable = param->vf_para->uvswap_enable;
|
||||
if (param->vf_para->is_tvp)
|
||||
gdc_config.use_sec_mem = 1; /* secure mem access */
|
||||
else
|
||||
gdc_config.use_sec_mem = 0;
|
||||
|
||||
if (param->vf_para->src_endian != 0)
|
||||
gdc_config.in_endian = GDC_ENDIAN_BIG_8BYTES;
|
||||
else
|
||||
gdc_config.in_endian = GDC_ENDIAN_LITTLE;
|
||||
|
||||
if (param->vf_para->dst_endian != 0)
|
||||
gdc_config.out_endian = GDC_ENDIAN_BIG_8BYTES;
|
||||
else
|
||||
gdc_config.out_endian = GDC_ENDIAN_LITTLE;
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_GDC
|
||||
ret = gdc_process_phys(param->context, &gdc_config);
|
||||
#else
|
||||
ret = -1;
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
pr_info("v2d:[%d] %s: dewrap process failed.\n", param->index, __func__);
|
||||
} else {
|
||||
if (dewarp_com_dump != dewarp_com_dump_last) {
|
||||
sprintf(dump_name, "/data/src_%d.yuv", dewarp_com_dump);
|
||||
dump_dewarp_vframe(dump_name,
|
||||
param->vf_para->src_vf_width,
|
||||
param->vf_para->src_vf_height,
|
||||
param->vf_para->src_buf_addr0,
|
||||
param->vf_para->src_buf_addr1);
|
||||
|
||||
sprintf(dump_name, "/data/dst_%d.yuv", dewarp_com_dump);
|
||||
dump_dewarp_vframe(dump_name,
|
||||
param->vf_para->dst_vf_width,
|
||||
param->vf_para->dst_vf_height,
|
||||
gdc_config.out_paddr[0],
|
||||
gdc_config.out_paddr[1]);
|
||||
dewarp_com_dump_last = dewarp_com_dump;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef VFRAME_DEWARP_COMPOSER_H
|
||||
#define VFRAME_DEWARP_COMPOSER_H
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
#include <linux/amlogic/media/vfm/vframe.h>
|
||||
#include <linux/amlogic/media/gdc/gdc.h>
|
||||
|
||||
struct dewarp_vf_para_s {
|
||||
int src_vf_format;
|
||||
int src_vf_width;
|
||||
int src_vf_height;
|
||||
int src_vf_plane_count;
|
||||
int src_vf_angle;
|
||||
ulong src_buf_addr0;
|
||||
int src_buf_stride0;
|
||||
ulong src_buf_addr1;
|
||||
int src_buf_stride1;
|
||||
int src_endian;
|
||||
int dst_vf_format;
|
||||
int dst_vf_width;
|
||||
int dst_vf_height;
|
||||
int dst_vf_plane_count;
|
||||
ulong dst_buf_addr;
|
||||
int dst_buf_stride;
|
||||
int dst_endian;
|
||||
bool is_tvp;
|
||||
bool uvswap_enable;
|
||||
};
|
||||
|
||||
struct pic_s {
|
||||
int format;
|
||||
u32 width;
|
||||
u32 height;
|
||||
ulong addr[2];
|
||||
u32 align_w;
|
||||
u32 align_h;
|
||||
int plane_count;
|
||||
bool is_tvp;
|
||||
};
|
||||
|
||||
struct composer_input_para {
|
||||
int call_index;
|
||||
struct vframe_s *vframe;
|
||||
struct pic_s pic_info;
|
||||
int transform;
|
||||
};
|
||||
|
||||
struct composer_output_para {
|
||||
struct pic_s pic_info;
|
||||
};
|
||||
|
||||
struct dewarp_common_para {
|
||||
struct composer_input_para input_para;
|
||||
struct composer_output_para output_para;
|
||||
};
|
||||
|
||||
struct dewarp_composer_para {
|
||||
int index;
|
||||
struct gdc_context_s *context;
|
||||
struct firmware_load_s fw_load;
|
||||
struct dewarp_vf_para_s *vf_para;
|
||||
struct firmware_rotate_s last_fw_param;
|
||||
};
|
||||
|
||||
extern u32 dewarp_load_flag;
|
||||
extern int dewarp_com_dump;
|
||||
extern int dewarp_print;
|
||||
|
||||
int v2d_get_dewarp_format(int index, struct vframe_s *vf);
|
||||
int v2d_load_dewarp_firmware(struct dewarp_composer_para *param);
|
||||
int v2d_unload_dewarp_firmware(struct dewarp_composer_para *param);
|
||||
bool check_dewarp_status(struct vframe_s *input_vf, int count, int work_mode, int index);
|
||||
int v2d_init_dewarp_composer(struct dewarp_composer_para *param);
|
||||
int v2d_uninit_dewarp_composer(struct dewarp_composer_para *param);
|
||||
int v2d_config_dewarp_vframe(struct dewarp_vf_para_s *vframe_para,
|
||||
struct dewarp_common_para *common_para);
|
||||
int v2d_dewarp_data_composer(struct dewarp_composer_para *param, bool is_tvp);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,949 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/amlogic/media/ge2d/ge2d.h>
|
||||
#include <linux/amlogic/media/canvas/canvas.h>
|
||||
#include <linux/amlogic/media/canvas/canvas_mgr.h>
|
||||
#include <linux/amlogic/media/utils/amlog.h>
|
||||
#include <linux/amlogic/media/ge2d/ge2d_func.h>
|
||||
/* media module used media/registers/cpu_version.h since kernel 5.4 */
|
||||
#include <linux/amlogic/media/registers/cpu_version.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/amlogic/media/codec_mm/codec_mm.h>
|
||||
#include <linux/amlogic/media/vfm/vframe.h>
|
||||
#include "v2d_ge2d_composer.h"
|
||||
|
||||
#define WIDTH_8K 7680
|
||||
#define HEIGHT_8K 7680
|
||||
#define IS_DI_PSTLINK(di_flag) ((di_flag) & DI_FLAG_DI_PSTVPPLINK)
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_ENABLE_VIDEO_PIPELINE_DUMP_DATA
|
||||
static int dump_src_count;
|
||||
static int dump_before_dst_count;
|
||||
static int dump_dst_count;
|
||||
static int dump_black_count;
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_AMLOGIC_MEDIA_GE2D
|
||||
void stretchblt_noalpha(struct ge2d_context_s *wq,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h)
|
||||
{
|
||||
}
|
||||
|
||||
int destroy_ge2d_work_queue(struct ge2d_context_s *ge2d_work_queue)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fillrect(struct ge2d_context_s *wq,
|
||||
int x, int y, int w, int h, unsigned int color)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_AMLOGIC_UVM_CORE
|
||||
struct vframe_s *dmabuf_get_vframe(struct dma_buf *dmabuf)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int get_source_type(struct ge2d_src_para_s *src_data)
|
||||
{
|
||||
enum videocom_source_type ret;
|
||||
int interlace_mode;
|
||||
|
||||
interlace_mode = src_data->type & VIDTYPE_TYPEMASK;
|
||||
if (src_data->source_type == VFRAME_SOURCE_TYPE_HDMI ||
|
||||
src_data->source_type == VFRAME_SOURCE_TYPE_CVBS) {
|
||||
if ((src_data->bitdepth & BITDEPTH_Y10) &&
|
||||
(!(src_data->type & VIDTYPE_COMPRESS)) &&
|
||||
(get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL))
|
||||
ret = VDIN_10BIT_NORMAL;
|
||||
else
|
||||
ret = VDIN_8BIT_NORMAL;
|
||||
} else {
|
||||
if ((src_data->bitdepth & BITDEPTH_Y10) &&
|
||||
(!(src_data->type & VIDTYPE_COMPRESS)) &&
|
||||
(get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)) {
|
||||
if (interlace_mode == VIDTYPE_INTERLACE_TOP)
|
||||
ret = DECODER_10BIT_TOP;
|
||||
else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM)
|
||||
ret = DECODER_10BIT_BOTTOM;
|
||||
else
|
||||
ret = DECODER_10BIT_NORMAL;
|
||||
} else {
|
||||
if (interlace_mode == VIDTYPE_INTERLACE_TOP)
|
||||
ret = DECODER_8BIT_TOP;
|
||||
else if (interlace_mode == VIDTYPE_INTERLACE_BOTTOM)
|
||||
ret = DECODER_8BIT_BOTTOM;
|
||||
else
|
||||
ret = DECODER_8BIT_NORMAL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_input_format(struct ge2d_src_para_s *src_data)
|
||||
{
|
||||
int format = GE2D_FORMAT_M24_YUV420;
|
||||
enum videocom_source_type source_type;
|
||||
|
||||
source_type = get_source_type(src_data);
|
||||
switch (source_type) {
|
||||
case DECODER_8BIT_NORMAL:
|
||||
if (src_data->type & VIDTYPE_VIU_422)
|
||||
format = GE2D_FORMAT_S16_YUV422;
|
||||
else if (src_data->type & VIDTYPE_VIU_NV21)
|
||||
format = GE2D_FORMAT_M24_NV21;
|
||||
else if (src_data->type & VIDTYPE_VIU_NV12)
|
||||
format = GE2D_FORMAT_M24_NV12;
|
||||
else if (src_data->type & VIDTYPE_VIU_444)
|
||||
format = GE2D_FORMAT_S24_YUV444;
|
||||
else
|
||||
format = GE2D_FORMAT_M24_YUV420;
|
||||
break;
|
||||
case DECODER_8BIT_BOTTOM:
|
||||
if (src_data->type & VIDTYPE_VIU_422)
|
||||
format = GE2D_FORMAT_S16_YUV422
|
||||
| (GE2D_FORMAT_S16_YUV422B & (3 << 3));
|
||||
else if (src_data->type & VIDTYPE_VIU_NV21)
|
||||
format = GE2D_FORMAT_M24_NV21
|
||||
| (GE2D_FORMAT_M24_NV21B & (3 << 3));
|
||||
else if (src_data->type & VIDTYPE_VIU_NV12)
|
||||
format = GE2D_FORMAT_M24_NV12
|
||||
| (GE2D_FORMAT_M24_NV12B & (3 << 3));
|
||||
else if (src_data->type & VIDTYPE_VIU_444)
|
||||
format = GE2D_FORMAT_S24_YUV444
|
||||
| (GE2D_FORMAT_S24_YUV444B & (3 << 3));
|
||||
else
|
||||
format = GE2D_FORMAT_M24_YUV420
|
||||
| (GE2D_FMT_M24_YUV420B & (3 << 3));
|
||||
break;
|
||||
case DECODER_8BIT_TOP:
|
||||
if (src_data->type & VIDTYPE_VIU_422)
|
||||
format = GE2D_FORMAT_S16_YUV422
|
||||
| (GE2D_FORMAT_S16_YUV422T & (3 << 3));
|
||||
else if (src_data->type & VIDTYPE_VIU_NV21)
|
||||
format = GE2D_FORMAT_M24_NV21
|
||||
| (GE2D_FORMAT_M24_NV21T & (3 << 3));
|
||||
else if (src_data->type & VIDTYPE_VIU_NV12)
|
||||
format = GE2D_FORMAT_M24_NV12
|
||||
| (GE2D_FORMAT_M24_NV12T & (3 << 3));
|
||||
else if (src_data->type & VIDTYPE_VIU_444)
|
||||
format = GE2D_FORMAT_S24_YUV444
|
||||
| (GE2D_FORMAT_S24_YUV444T & (3 << 3));
|
||||
else
|
||||
format = GE2D_FORMAT_M24_YUV420
|
||||
| (GE2D_FMT_M24_YUV420T & (3 << 3));
|
||||
break;
|
||||
case DECODER_10BIT_NORMAL:
|
||||
if (src_data->type & VIDTYPE_VIU_422) {
|
||||
if (src_data->bitdepth & FULL_PACK_422_MODE)
|
||||
format = GE2D_FORMAT_S16_10BIT_YUV422;
|
||||
else
|
||||
format = GE2D_FORMAT_S16_12BIT_YUV422;
|
||||
}
|
||||
break;
|
||||
case DECODER_10BIT_BOTTOM:
|
||||
if (src_data->type & VIDTYPE_VIU_422) {
|
||||
if (src_data->bitdepth & FULL_PACK_422_MODE)
|
||||
format = GE2D_FORMAT_S16_10BIT_YUV422
|
||||
| (GE2D_FORMAT_S16_10BIT_YUV422B
|
||||
& (3 << 3));
|
||||
else
|
||||
format = GE2D_FORMAT_S16_12BIT_YUV422
|
||||
| (GE2D_FORMAT_S16_12BIT_YUV422B
|
||||
& (3 << 3));
|
||||
}
|
||||
break;
|
||||
case DECODER_10BIT_TOP:
|
||||
if (src_data->type & VIDTYPE_VIU_422) {
|
||||
if (src_data->bitdepth & FULL_PACK_422_MODE)
|
||||
format = GE2D_FORMAT_S16_10BIT_YUV422
|
||||
| (GE2D_FORMAT_S16_10BIT_YUV422T
|
||||
& (3 << 3));
|
||||
else
|
||||
format = GE2D_FORMAT_S16_12BIT_YUV422
|
||||
| (GE2D_FORMAT_S16_12BIT_YUV422T
|
||||
& (3 << 3));
|
||||
}
|
||||
break;
|
||||
case VDIN_8BIT_NORMAL:
|
||||
if (src_data->type & VIDTYPE_VIU_422) {
|
||||
format = GE2D_FORMAT_S16_YUV422;
|
||||
} else if (src_data->type & VIDTYPE_VIU_NV21) {
|
||||
format = GE2D_FORMAT_M24_NV21;
|
||||
} else if (src_data->type & VIDTYPE_VIU_NV12) {
|
||||
format = GE2D_FORMAT_M24_NV12;
|
||||
} else if (src_data->type & VIDTYPE_VIU_444) {
|
||||
format = GE2D_FORMAT_S24_YUV444;
|
||||
} else if (src_data->type & VIDTYPE_RGB_444) {
|
||||
format = GE2D_FORMAT_S24_RGB;
|
||||
if (src_data->is_vframe)
|
||||
format &= (~GE2D_LITTLE_ENDIAN);
|
||||
} else {
|
||||
format = GE2D_FORMAT_M24_YUV420;
|
||||
}
|
||||
break;
|
||||
case VDIN_10BIT_NORMAL:
|
||||
if (src_data->type & VIDTYPE_VIU_422) {
|
||||
if (src_data->bitdepth & FULL_PACK_422_MODE)
|
||||
format = GE2D_FORMAT_S16_10BIT_YUV422;
|
||||
else
|
||||
format = GE2D_FORMAT_S16_12BIT_YUV422;
|
||||
} else if (src_data->type & VIDTYPE_VIU_444) {
|
||||
format = GE2D_FORMAT_S24_10BIT_YUV444;
|
||||
} else if (src_data->type & VIDTYPE_RGB_444) {
|
||||
format = GE2D_FORMAT_S24_10BIT_RGB888;
|
||||
if (!src_data->is_vframe)
|
||||
format |= GE2D_LITTLE_ENDIAN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
format = GE2D_FORMAT_M24_YUV420;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
static enum ge2d_angle_type config_ge2d_rotation(int vf_transform)
|
||||
{
|
||||
int ge2d_angle = 0;
|
||||
|
||||
if (vf_transform == 1)
|
||||
ge2d_angle = GE2D_ANGLE_TYPE_FLIP_H;
|
||||
else if (vf_transform == 2)
|
||||
ge2d_angle = GE2D_ANGLE_TYPE_FLIP_V;
|
||||
else if (vf_transform == 4 || vf_transform == 5 || vf_transform == 6)
|
||||
ge2d_angle = GE2D_ANGLE_TYPE_ROT_90;
|
||||
else if (vf_transform == 3)
|
||||
ge2d_angle = GE2D_ANGLE_TYPE_ROT_180;
|
||||
else if (vf_transform == 7)
|
||||
ge2d_angle = GE2D_ANGLE_TYPE_ROT_270;
|
||||
else if (vf_transform != 0)
|
||||
VIDEOCOM_INFO("%s: not support transform=%d\n", __func__, vf_transform);
|
||||
|
||||
return ge2d_angle;
|
||||
}
|
||||
|
||||
static int alloc_src_canvas(struct ge2d_composer_para *ge2d_comp_para)
|
||||
{
|
||||
const char *keep_owner = "ge2d_composer";
|
||||
|
||||
if (ge2d_comp_para->canvas_scr[0] < 0)
|
||||
ge2d_comp_para->canvas_scr[0] =
|
||||
canvas_pool_map_alloc_canvas(keep_owner);
|
||||
if (ge2d_comp_para->canvas_scr[1] < 0)
|
||||
ge2d_comp_para->canvas_scr[1] =
|
||||
canvas_pool_map_alloc_canvas(keep_owner);
|
||||
if (ge2d_comp_para->canvas_scr[2] < 0)
|
||||
ge2d_comp_para->canvas_scr[2] =
|
||||
canvas_pool_map_alloc_canvas(keep_owner);
|
||||
|
||||
if (ge2d_comp_para->canvas_scr[0] < 0 ||
|
||||
ge2d_comp_para->canvas_scr[1] < 0 ||
|
||||
ge2d_comp_para->canvas_scr[2] < 0) {
|
||||
VIDEOCOM_INFO("%s failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int free_src_canvas(struct ge2d_composer_para *ge2d_comp_para)
|
||||
{
|
||||
if (ge2d_comp_para->canvas_scr[0] >= 0) {
|
||||
canvas_pool_map_free_canvas(ge2d_comp_para->canvas_scr[0]);
|
||||
ge2d_comp_para->canvas_scr[0] = -1;
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->canvas_scr[1] >= 0) {
|
||||
canvas_pool_map_free_canvas(ge2d_comp_para->canvas_scr[1]);
|
||||
ge2d_comp_para->canvas_scr[1] = -1;
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->canvas_scr[2] >= 0) {
|
||||
canvas_pool_map_free_canvas(ge2d_comp_para->canvas_scr[2]);
|
||||
ge2d_comp_para->canvas_scr[2] = -1;
|
||||
}
|
||||
if (ge2d_comp_para->canvas_scr[0] >= 0 ||
|
||||
ge2d_comp_para->canvas_scr[1] >= 0 ||
|
||||
ge2d_comp_para->canvas_scr[2] >= 0) {
|
||||
VIDEOCOM_INFO("%s failed!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_init_ge2d_composer(struct ge2d_composer_para *ge2d_comp_para)
|
||||
{
|
||||
const char *keep_owner = "ge2d_dest_comp";
|
||||
|
||||
ge2d_comp_para->context = create_ge2d_work_queue();
|
||||
if (IS_ERR_OR_NULL(ge2d_comp_para->context)) {
|
||||
VIDEOCOM_INFO("creat ge2d work failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->plane_num > 0) {
|
||||
if (ge2d_comp_para->canvas_dst[0] < 0)
|
||||
ge2d_comp_para->canvas_dst[0] =
|
||||
canvas_pool_map_alloc_canvas(keep_owner);
|
||||
if (ge2d_comp_para->canvas_dst[0] < 0) {
|
||||
VIDEOCOM_ERR("ge2d init dst canvas_0 failed!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->plane_num > 1) {
|
||||
if (ge2d_comp_para->canvas_dst[1] < 0)
|
||||
ge2d_comp_para->canvas_dst[1] =
|
||||
canvas_pool_map_alloc_canvas(keep_owner);
|
||||
if (ge2d_comp_para->canvas_dst[1] < 0) {
|
||||
VIDEOCOM_ERR("ge2d init dst canvas_1 failed!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->plane_num > 2) {
|
||||
if (ge2d_comp_para->canvas_dst[2] < 0)
|
||||
ge2d_comp_para->canvas_dst[2] =
|
||||
canvas_pool_map_alloc_canvas(keep_owner);
|
||||
if (ge2d_comp_para->canvas_dst[2] < 0) {
|
||||
VIDEOCOM_ERR("ge2d init dst canvas_2 failed!\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_uninit_ge2d_composer(struct ge2d_composer_para *ge2d_comp_para)
|
||||
{
|
||||
destroy_ge2d_work_queue(ge2d_comp_para->context);
|
||||
ge2d_comp_para->context = NULL;
|
||||
|
||||
if (free_src_canvas(ge2d_comp_para) < 0) {
|
||||
VIDEOCOM_ERR("free src canvas failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->canvas_dst[0] >= 0) {
|
||||
canvas_pool_map_free_canvas(ge2d_comp_para->canvas_dst[0]);
|
||||
ge2d_comp_para->canvas_dst[0] = -1;
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->canvas_dst[1] >= 0) {
|
||||
canvas_pool_map_free_canvas(ge2d_comp_para->canvas_dst[1]);
|
||||
ge2d_comp_para->canvas_dst[1] = -1;
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->canvas_dst[2] >= 0) {
|
||||
canvas_pool_map_free_canvas(ge2d_comp_para->canvas_dst[2]);
|
||||
ge2d_comp_para->canvas_dst[2] = -1;
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->canvas_dst[0] >= 0 ||
|
||||
ge2d_comp_para->canvas_dst[1] >= 0 ||
|
||||
ge2d_comp_para->canvas_dst[2] >= 0) {
|
||||
VIDEOCOM_ERR("free dst canvas failed!\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_ENABLE_VIDEO_PIPELINE_DUMP_DATA
|
||||
static int copy_phybuf_to_file(struct canvas_config_s *config,
|
||||
struct file *fp, loff_t pos)
|
||||
{
|
||||
u32 span = SZ_1M;
|
||||
u8 *p;
|
||||
int remain_size = 0;
|
||||
ssize_t ret;
|
||||
ulong phys;
|
||||
|
||||
if (IS_ERR_OR_NULL(config))
|
||||
return -1;
|
||||
|
||||
phys = config->phy_addr;
|
||||
remain_size = config->width * config->height;
|
||||
while (remain_size > 0) {
|
||||
if (remain_size < span)
|
||||
span = remain_size;
|
||||
p = codec_mm_vmap(phys, PAGE_ALIGN(span));
|
||||
if (!p) {
|
||||
VIDEOCOM_ERR("vmap failed\n");
|
||||
return -1;
|
||||
}
|
||||
codec_mm_dma_flush(p, span, DMA_FROM_DEVICE);
|
||||
ret = kernel_write(fp, (char *)p, span, &pos);
|
||||
if (ret <= 0)
|
||||
VIDEOCOM_ERR("vfs write failed!\n");
|
||||
phys += span;
|
||||
codec_mm_unmap_phyaddr(p);
|
||||
remain_size -= span;
|
||||
|
||||
VIDEOCOM_INFO("pos: %lld, phys: %lx, remain_size: %d\n",
|
||||
pos, phys, remain_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static bool dump_data(struct dump_param *para, enum buffer_data type)
|
||||
{
|
||||
#ifdef CONFIG_AMLOGIC_ENABLE_VIDEO_PIPELINE_DUMP_DATA
|
||||
bool ret = false;
|
||||
struct file *filp_dst = NULL;
|
||||
char dst_path[64] = {'\0'};
|
||||
struct canvas_config_s *dump_config;
|
||||
int result = 0;
|
||||
int offset = 0;
|
||||
|
||||
offset = 0;
|
||||
if (type == BLACK_BUFFER)
|
||||
sprintf(dst_path, "/data/temp/black_%d", dump_black_count++);
|
||||
else if (type == SCR_BUFFER)
|
||||
sprintf(dst_path, "/data/temp/scr_%d", dump_src_count++);
|
||||
else if (type == DST_EMPTY_BUFFER)
|
||||
sprintf(dst_path,
|
||||
"/data/temp/before_dst_%d",
|
||||
dump_before_dst_count++);
|
||||
else if (type == DST_BUFFER_DATA)
|
||||
sprintf(dst_path, "/data/temp/dst_%d", dump_dst_count++);
|
||||
filp_dst = filp_open(dst_path, O_RDWR | O_CREAT, 0666);
|
||||
if (IS_ERR(filp_dst)) {
|
||||
VIDEOCOM_ERR("open %s failed\n", dst_path);
|
||||
ret = false;
|
||||
} else {
|
||||
dump_config = ¶->canvas0_config[0];
|
||||
result = copy_phybuf_to_file(dump_config, filp_dst, 0);
|
||||
if (result < 0) {
|
||||
VIDEOCOM_ERR("write %s failed\n", dst_path);
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
if (para->plane_num >= 2) {
|
||||
offset = dump_config->width *
|
||||
dump_config->height;
|
||||
dump_config = ¶->canvas0_config[1];
|
||||
result =
|
||||
copy_phybuf_to_file(dump_config,
|
||||
filp_dst, offset);
|
||||
if (result < 0) {
|
||||
VIDEOCOM_ERR("#1 write %s failed\n",
|
||||
dst_path);
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (para->plane_num >= 3) {
|
||||
offset += dump_config->width *
|
||||
dump_config->height;
|
||||
dump_config = ¶->canvas0_config[2];
|
||||
result =
|
||||
copy_phybuf_to_file(dump_config,
|
||||
filp_dst, offset);
|
||||
if (result < 0) {
|
||||
VIDEOCOM_ERR("#2 write %s failed\n",
|
||||
dst_path);
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
filp_close(filp_dst, NULL);
|
||||
ret = true;
|
||||
}
|
||||
end:
|
||||
return ret;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int v2d_fill_vframe_black(struct ge2d_composer_para *ge2d_comp_para)
|
||||
{
|
||||
struct canvas_config_s dst_canvas0_config[3];
|
||||
struct config_para_ex_s ge2d_config;
|
||||
u32 dst_plane_num;
|
||||
struct dump_param para;
|
||||
bool ret = false;
|
||||
int temp = 0;
|
||||
int canvas_index = 0;
|
||||
|
||||
memset(dst_canvas0_config, 0, sizeof(dst_canvas0_config));
|
||||
memset(&ge2d_config, 0, sizeof(struct config_para_ex_s));
|
||||
|
||||
if (ge2d_comp_para->format == GE2D_FORMAT_S24_YUV444) {
|
||||
dst_canvas0_config[0].phy_addr = ge2d_comp_para->phy_addr[0];
|
||||
dst_canvas0_config[0].width = ge2d_comp_para->buffer_w * 3;
|
||||
dst_canvas0_config[0].height = ge2d_comp_para->buffer_h;
|
||||
dst_canvas0_config[0].block_mode = 0;
|
||||
dst_canvas0_config[0].endian = 0;
|
||||
} else if (ge2d_comp_para->format == GE2D_FORMAT_M24_NV21) {
|
||||
dst_canvas0_config[0].phy_addr = ge2d_comp_para->phy_addr[0];
|
||||
dst_canvas0_config[0].width = ge2d_comp_para->buffer_w;
|
||||
dst_canvas0_config[0].height = ge2d_comp_para->buffer_h;
|
||||
dst_canvas0_config[0].block_mode = 0;
|
||||
dst_canvas0_config[0].endian = 0;
|
||||
dst_canvas0_config[1].phy_addr = ge2d_comp_para->phy_addr[0]
|
||||
+ ge2d_comp_para->buffer_w * ge2d_comp_para->buffer_h;
|
||||
dst_canvas0_config[1].width = ge2d_comp_para->buffer_w;
|
||||
dst_canvas0_config[1].height = ge2d_comp_para->buffer_h >> 1;
|
||||
dst_canvas0_config[1].block_mode = 0;
|
||||
dst_canvas0_config[1].endian = 0;
|
||||
}
|
||||
dst_plane_num = ge2d_comp_para->plane_num;
|
||||
|
||||
if (ge2d_comp_para->canvas0_addr == (u32)-1) {
|
||||
canvas_config_config(ge2d_comp_para->canvas_dst[0],
|
||||
&dst_canvas0_config[0]);
|
||||
if (dst_plane_num == 2) {
|
||||
canvas_config_config(ge2d_comp_para->canvas_dst[1],
|
||||
&dst_canvas0_config[1]);
|
||||
} else if (dst_plane_num == 3) {
|
||||
canvas_config_config(ge2d_comp_para->canvas_dst[2],
|
||||
&dst_canvas0_config[2]);
|
||||
}
|
||||
canvas_index = ge2d_comp_para->canvas_dst[0]
|
||||
| (ge2d_comp_para->canvas_dst[1] << 8)
|
||||
| (ge2d_comp_para->canvas_dst[2] << 16);
|
||||
|
||||
} else {
|
||||
canvas_index = ge2d_comp_para->canvas0_addr;
|
||||
}
|
||||
|
||||
ge2d_config.src_para.canvas_index = canvas_index;
|
||||
ge2d_config.alu_const_color = 0;/*0x000000ff;*/
|
||||
ge2d_config.bitmask_en = 0;
|
||||
ge2d_config.src1_gb_alpha = 0;/*0xff;*/
|
||||
ge2d_config.dst_xy_swap = 0;
|
||||
|
||||
ge2d_config.src_key.key_enable = 0;
|
||||
ge2d_config.src_key.key_mask = 0;
|
||||
ge2d_config.src_key.key_mode = 0;
|
||||
ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID;
|
||||
ge2d_config.src_para.format = ge2d_comp_para->format;
|
||||
ge2d_config.src_para.fill_color_en = 0;
|
||||
ge2d_config.src_para.fill_mode = 0;
|
||||
ge2d_config.src_para.x_rev = 0;
|
||||
ge2d_config.src_para.y_rev = 0;
|
||||
ge2d_config.src_para.color = 0;
|
||||
ge2d_config.src_para.top = 0;
|
||||
ge2d_config.src_para.left = 0;
|
||||
ge2d_config.src_para.width = ge2d_comp_para->buffer_w;
|
||||
ge2d_config.src_para.height = ge2d_comp_para->buffer_h;
|
||||
ge2d_config.src2_para.mem_type = CANVAS_TYPE_INVALID;
|
||||
|
||||
ge2d_config.dst_para.canvas_index = canvas_index;
|
||||
ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID;
|
||||
ge2d_config.dst_para.fill_color_en = 0;
|
||||
ge2d_config.dst_para.fill_mode = 0;
|
||||
ge2d_config.dst_para.x_rev = 0;
|
||||
ge2d_config.dst_para.y_rev = 0;
|
||||
ge2d_config.dst_para.color = 0;
|
||||
ge2d_config.dst_para.top = 0;
|
||||
ge2d_config.dst_para.left = 0;
|
||||
ge2d_config.dst_para.format = ge2d_comp_para->format;
|
||||
if (ge2d_comp_para->format == GE2D_FORMAT_M24_NV21)
|
||||
ge2d_config.dst_para.format |= GE2D_LITTLE_ENDIAN;
|
||||
ge2d_config.dst_para.width = ge2d_comp_para->buffer_w;
|
||||
ge2d_config.dst_para.height = ge2d_comp_para->buffer_h;
|
||||
ge2d_config.mem_sec = ge2d_comp_para->is_tvp;
|
||||
|
||||
temp = ge2d_context_config_ex(ge2d_comp_para->context, &ge2d_config);
|
||||
if (temp < 0) {
|
||||
VIDEOCOM_ERR("++ge2d configing error.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fillrect(ge2d_comp_para->context, 0, 0,
|
||||
ge2d_comp_para->buffer_w,
|
||||
ge2d_comp_para->buffer_h,
|
||||
0x008080ff);
|
||||
if (ge2d_com_debug & 2) {
|
||||
para.canvas0_config[0] = dst_canvas0_config[0];
|
||||
para.canvas0_config[1] = dst_canvas0_config[1];
|
||||
para.canvas0_config[2] = dst_canvas0_config[2];
|
||||
para.plane_num = dst_plane_num;
|
||||
ret = dump_data(¶, BLACK_BUFFER);
|
||||
if (ret)
|
||||
VIDEOCOM_INFO("dump black buffer successful.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_config_ge2d_data(struct vframe_s *src_vf, unsigned long addr, int buf_w, int buf_h,
|
||||
int data_w, int data_h, int crop_x, int crop_y, int crop_w, int crop_h,
|
||||
struct ge2d_src_para_s *data)
|
||||
{
|
||||
struct vframe_s *vf = NULL;
|
||||
int vf_height;
|
||||
|
||||
if (IS_ERR_OR_NULL(data)) {
|
||||
pr_info("%s: invalid param.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src_vf) {
|
||||
if (src_vf->canvas0_config[0].phy_addr == 0) {
|
||||
if ((src_vf->flag & VFRAME_FLAG_DOUBLE_FRAM) && src_vf->vf_ext) {
|
||||
vf = src_vf->vf_ext;
|
||||
} else {
|
||||
VIDEOCOM_ERR("%s: vf no yuv data, composer fail\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
vf = src_vf;
|
||||
}
|
||||
|
||||
if (vf && vf->di_flag && IS_DI_PSTLINK(vf->di_flag))
|
||||
vf_height = vf->height >> 1;
|
||||
else
|
||||
vf_height = vf->height;
|
||||
|
||||
data->canvas0Addr = vf->canvas0Addr;
|
||||
data->canvas1Addr = vf->canvas1Addr;
|
||||
data->canvas0_config[0] = vf->canvas0_config[0];
|
||||
data->canvas0_config[1] = vf->canvas0_config[1];
|
||||
data->canvas0_config[2] = vf->canvas0_config[2];
|
||||
data->canvas1_config[0] = vf->canvas1_config[0];
|
||||
data->canvas1_config[1] = vf->canvas1_config[1];
|
||||
data->canvas1_config[2] = vf->canvas1_config[2];
|
||||
data->bitdepth = vf->bitdepth;
|
||||
data->source_type = vf->source_type;
|
||||
data->type = vf->type;
|
||||
data->plane_num = vf->plane_num;
|
||||
|
||||
if (vf->type & VIDTYPE_COMPRESS) {
|
||||
if ((crop_w > WIDTH_8K || crop_w < 0) ||
|
||||
(crop_h > HEIGHT_8K || crop_h < 0)) {
|
||||
data->width = vf->width;
|
||||
data->height = vf_height;
|
||||
} else {
|
||||
if (crop_w > vf->compWidth)
|
||||
crop_w = vf->compWidth;
|
||||
if (crop_h > vf->compHeight)
|
||||
crop_h = vf->compHeight;
|
||||
data->position_x = crop_x * vf->width / vf->compWidth;
|
||||
data->position_y = crop_y * vf->width / vf->compWidth;
|
||||
data->width =
|
||||
crop_w * vf->width / vf->compWidth;
|
||||
data->height =
|
||||
crop_h * vf->width / vf->compWidth * vf_height / vf->height;
|
||||
}
|
||||
} else {
|
||||
if ((crop_w > WIDTH_8K || crop_w < 0) ||
|
||||
(crop_h > HEIGHT_8K || crop_h < 0)) {
|
||||
data->width = vf->width;
|
||||
data->height = vf_height;
|
||||
} else {
|
||||
data->position_x = crop_x;
|
||||
data->position_y = crop_y;
|
||||
data->width = crop_w;
|
||||
data->height = crop_h;
|
||||
if (vf && vf->di_flag && IS_DI_PSTLINK(vf->di_flag)) {
|
||||
data->position_y >>= 1;
|
||||
data->height >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ge2d_com_debug & 1) {
|
||||
VIDEOCOM_INFO("scr:vf->canvas0_config[0]: paddr=%lu width=%d height=%d\n",
|
||||
vf->canvas0_config[0].phy_addr,
|
||||
vf->canvas0_config[0].width,
|
||||
vf->canvas0_config[0].height);
|
||||
VIDEOCOM_INFO("scr:vf->canvas0_config[1]: paddr=%lu width=%d height=%d\n",
|
||||
vf->canvas0_config[1].phy_addr,
|
||||
vf->canvas0_config[1].width,
|
||||
vf->canvas0_config[1].height);
|
||||
VIDEOCOM_INFO("scr:vf->width=%d vf->height=%d vf->ComW=%d vf->ComH=%d\n",
|
||||
vf->width,
|
||||
vf->height,
|
||||
vf->compWidth,
|
||||
vf->compHeight);
|
||||
VIDEOCOM_INFO("scr:crop %d %d %d %d\n", crop_x, crop_y, crop_w, crop_h);
|
||||
VIDEOCOM_INFO("scr:data %d %d %d %d\n",
|
||||
data->position_x, data->position_y, data->width, data->height);
|
||||
}
|
||||
if (vf->flag & VFRAME_FLAG_VIDEO_LINEAR)
|
||||
data->is_vframe = false;
|
||||
else
|
||||
data->is_vframe = true;
|
||||
} else {
|
||||
data->canvas0Addr = -1;
|
||||
data->canvas1Addr = -1;
|
||||
data->canvas0_config[0].phy_addr = addr;
|
||||
|
||||
VIDEOCOM_INFO("buffer_w(%d), data_w(%d)\n", buf_w, data_w);
|
||||
if (buf_w > data_w) {
|
||||
if (data->is_yuv444)
|
||||
data->canvas0_config[0].width = buf_w * 3;
|
||||
else
|
||||
data->canvas0_config[0].width = buf_w;
|
||||
} else {
|
||||
if (data->is_yuv444)
|
||||
data->canvas0_config[0].width = data_w * 3;
|
||||
else
|
||||
data->canvas0_config[0].width = data_w;
|
||||
}
|
||||
VIDEOCOM_INFO("buffer_h(%d), data_h(%d)\n", buf_h, data_h);
|
||||
|
||||
if (buf_h > data_h)
|
||||
data->canvas0_config[0].height = buf_h;
|
||||
else
|
||||
data->canvas0_config[0].height = data_h;
|
||||
|
||||
data->canvas0_config[0].block_mode = CANVAS_BLKMODE_LINEAR;
|
||||
data->canvas0_config[0].endian = 0;
|
||||
data->canvas0_config[1].phy_addr =
|
||||
(u32)(addr + (data->canvas0_config[0].width)
|
||||
* (data->canvas0_config[0].height));
|
||||
data->canvas0_config[1].width =
|
||||
data->canvas0_config[0].width;
|
||||
data->canvas0_config[1].height =
|
||||
data->canvas0_config[0].height / 2;
|
||||
data->canvas0_config[1].block_mode =
|
||||
CANVAS_BLKMODE_LINEAR;
|
||||
data->canvas0_config[1].endian = 0;
|
||||
data->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8;
|
||||
data->source_type = 0;
|
||||
if (data->is_yuv444) {
|
||||
data->type = VIDTYPE_VIU_SINGLE_PLANE
|
||||
| VIDTYPE_VIU_FIELD
|
||||
| VIDTYPE_VIU_444;
|
||||
data->plane_num = 1;
|
||||
} else {
|
||||
data->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21;
|
||||
data->plane_num = 2;
|
||||
}
|
||||
|
||||
VIDEOCOM_INFO("crop %d %d %d %d\n", crop_x, crop_y, crop_w, crop_h);
|
||||
data->position_x = crop_x;
|
||||
data->position_y = crop_y;
|
||||
data->is_vframe = false;
|
||||
if (crop_w <= 0 || crop_h <= 0) {
|
||||
data->width = buf_w;
|
||||
data->height = buf_h;
|
||||
} else {
|
||||
data->width = crop_w;
|
||||
data->height = crop_h;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_ge2d_data_composer(struct ge2d_src_para_s *scr_data,
|
||||
struct ge2d_composer_para *ge2d_comp_para)
|
||||
{
|
||||
int ret;
|
||||
struct canvas_config_s dst_canvas0_config[3];
|
||||
struct config_para_ex_s ge2d_config;
|
||||
u32 dst_plane_num;
|
||||
int src_canvas_id, dst_canvas_id;
|
||||
int input_x, input_y, input_width, input_height;
|
||||
int position_left, position_top;
|
||||
int position_width, position_height;
|
||||
struct dump_param para;
|
||||
enum ge2d_angle_type ge2d_angle;
|
||||
bool result = false;
|
||||
|
||||
memset(&ge2d_config, 0, sizeof(struct config_para_ex_s));
|
||||
memset(dst_canvas0_config, 0, sizeof(dst_canvas0_config));
|
||||
|
||||
if (ge2d_comp_para->format == GE2D_FORMAT_S24_YUV444) {
|
||||
dst_canvas0_config[0].phy_addr = ge2d_comp_para->phy_addr[0];
|
||||
dst_canvas0_config[0].width = ge2d_comp_para->buffer_w * 3;
|
||||
dst_canvas0_config[0].height = ge2d_comp_para->buffer_h;
|
||||
dst_canvas0_config[0].block_mode = 0;
|
||||
dst_canvas0_config[0].endian = 0;
|
||||
} else if (ge2d_comp_para->format == GE2D_FORMAT_M24_NV21) {
|
||||
dst_canvas0_config[0].phy_addr = ge2d_comp_para->phy_addr[0];
|
||||
dst_canvas0_config[0].width = ge2d_comp_para->buffer_w;
|
||||
dst_canvas0_config[0].height = ge2d_comp_para->buffer_h;
|
||||
dst_canvas0_config[0].block_mode = 0;
|
||||
dst_canvas0_config[0].endian = 0;
|
||||
dst_canvas0_config[1].phy_addr = ge2d_comp_para->phy_addr[0]
|
||||
+ ge2d_comp_para->buffer_w * ge2d_comp_para->buffer_h;
|
||||
dst_canvas0_config[1].width = ge2d_comp_para->buffer_w;
|
||||
dst_canvas0_config[1].height = ge2d_comp_para->buffer_h >> 1;
|
||||
dst_canvas0_config[1].block_mode = 0;
|
||||
dst_canvas0_config[1].endian = 0;
|
||||
}
|
||||
dst_plane_num = ge2d_comp_para->plane_num;
|
||||
if (scr_data->canvas0Addr == (u32)-1) {
|
||||
ret = alloc_src_canvas(ge2d_comp_para);
|
||||
if (ret < 0) {
|
||||
VIDEOCOM_ERR("alloc src canvas failed!\n");
|
||||
return -1;
|
||||
}
|
||||
canvas_config_config(ge2d_comp_para->canvas_scr[0],
|
||||
&scr_data->canvas0_config[0]);
|
||||
if (scr_data->plane_num == 2) {
|
||||
canvas_config_config(ge2d_comp_para->canvas_scr[1],
|
||||
&scr_data->canvas0_config[1]);
|
||||
} else if (scr_data->plane_num == 3) {
|
||||
canvas_config_config(ge2d_comp_para->canvas_scr[2],
|
||||
&scr_data->canvas0_config[2]);
|
||||
}
|
||||
src_canvas_id = ge2d_comp_para->canvas_scr[0]
|
||||
| (ge2d_comp_para->canvas_scr[1] << 8)
|
||||
| (ge2d_comp_para->canvas_scr[2] << 16);
|
||||
} else {
|
||||
src_canvas_id = scr_data->canvas0Addr;
|
||||
}
|
||||
|
||||
if (ge2d_comp_para->canvas0_addr == (u32)-1) {
|
||||
canvas_config_config(ge2d_comp_para->canvas_dst[0],
|
||||
&dst_canvas0_config[0]);
|
||||
if (dst_plane_num == 2) {
|
||||
canvas_config_config(ge2d_comp_para->canvas_dst[1],
|
||||
&dst_canvas0_config[1]);
|
||||
} else if (dst_plane_num == 3) {
|
||||
canvas_config_config(ge2d_comp_para->canvas_dst[2],
|
||||
&dst_canvas0_config[2]);
|
||||
}
|
||||
dst_canvas_id = ge2d_comp_para->canvas_dst[0]
|
||||
| (ge2d_comp_para->canvas_dst[1] << 8)
|
||||
| (ge2d_comp_para->canvas_dst[2] << 16);
|
||||
} else {
|
||||
dst_canvas_id = ge2d_comp_para->canvas0_addr;
|
||||
}
|
||||
input_width = scr_data->width;
|
||||
input_height = scr_data->height;
|
||||
input_x = scr_data->position_x;
|
||||
input_y = scr_data->position_y;
|
||||
|
||||
if (scr_data->type & VIDTYPE_INTERLACE)
|
||||
input_height = scr_data->height >> 1;
|
||||
else
|
||||
input_height = scr_data->height;
|
||||
|
||||
ge2d_config.alu_const_color = 0;
|
||||
ge2d_config.bitmask_en = 0;
|
||||
ge2d_config.src1_gb_alpha = 0;
|
||||
ge2d_config.dst_xy_swap = 0;
|
||||
ge2d_config.src_key.key_enable = 0;
|
||||
ge2d_config.src_key.key_mask = 0;
|
||||
ge2d_config.src_key.key_mode = 0;
|
||||
ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID;
|
||||
ge2d_config.src_para.format = get_input_format(scr_data);
|
||||
if (!scr_data->is_vframe)
|
||||
ge2d_config.src_para.format |= GE2D_LITTLE_ENDIAN;
|
||||
ge2d_config.src_para.fill_color_en = 0;
|
||||
ge2d_config.src_para.fill_mode = 0;
|
||||
ge2d_config.src_para.x_rev = 0;
|
||||
ge2d_config.src_para.y_rev = 0;
|
||||
ge2d_config.src_para.color = 0xffffffff;
|
||||
ge2d_config.src_para.top = input_y;
|
||||
ge2d_config.src_para.left = input_x;
|
||||
ge2d_config.src_para.width = input_width;
|
||||
ge2d_config.src_para.height = input_height;
|
||||
ge2d_config.src_para.canvas_index = src_canvas_id;
|
||||
ge2d_config.src2_para.mem_type = CANVAS_TYPE_INVALID;
|
||||
ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID;
|
||||
ge2d_config.dst_para.fill_color_en = 0;
|
||||
ge2d_config.dst_para.fill_mode = 0;
|
||||
ge2d_config.dst_para.x_rev = 0;
|
||||
ge2d_config.dst_para.y_rev = 0;
|
||||
ge2d_config.dst_xy_swap = 0;
|
||||
ge2d_angle = config_ge2d_rotation(ge2d_comp_para->angle);
|
||||
|
||||
if (ge2d_angle == GE2D_ANGLE_TYPE_ROT_90) {
|
||||
ge2d_config.dst_xy_swap = 1;
|
||||
ge2d_config.dst_para.x_rev = 1;
|
||||
} else if (ge2d_angle == GE2D_ANGLE_TYPE_ROT_180) {
|
||||
ge2d_config.dst_para.x_rev = 1;
|
||||
ge2d_config.dst_para.y_rev = 1;
|
||||
} else if (ge2d_angle == GE2D_ANGLE_TYPE_ROT_270) {
|
||||
ge2d_config.dst_xy_swap = 1;
|
||||
ge2d_config.dst_para.y_rev = 1;
|
||||
} else if (ge2d_angle == GE2D_ANGLE_TYPE_FLIP_H) {
|
||||
ge2d_config.dst_xy_swap = 0;
|
||||
ge2d_config.dst_para.x_rev = 1;
|
||||
ge2d_config.dst_para.y_rev = 0;
|
||||
} else if (ge2d_angle == GE2D_ANGLE_TYPE_FLIP_V) {
|
||||
ge2d_config.dst_xy_swap = 0;
|
||||
ge2d_config.dst_para.x_rev = 0;
|
||||
ge2d_config.dst_para.y_rev = 1;
|
||||
}
|
||||
|
||||
ge2d_config.dst_para.canvas_index = dst_canvas_id;
|
||||
ge2d_config.dst_para.color = 0;
|
||||
ge2d_config.dst_para.top = 0;
|
||||
ge2d_config.dst_para.left = 0;
|
||||
ge2d_config.dst_para.format = ge2d_comp_para->format;
|
||||
if (ge2d_comp_para->format == GE2D_FORMAT_M24_NV21)
|
||||
ge2d_config.dst_para.format |= GE2D_LITTLE_ENDIAN;
|
||||
ge2d_config.dst_para.width = ge2d_comp_para->buffer_w;
|
||||
ge2d_config.dst_para.height = ge2d_comp_para->buffer_h;
|
||||
ge2d_config.mem_sec = ge2d_comp_para->is_tvp;
|
||||
|
||||
ret = ge2d_context_config_ex(ge2d_comp_para->context, &ge2d_config);
|
||||
if (ret < 0) {
|
||||
VIDEOCOM_ERR("++ge2d configing error.\n");
|
||||
return -1;
|
||||
}
|
||||
if (ge2d_com_debug & 4) {
|
||||
para.canvas0_config[0] = scr_data->canvas0_config[0];
|
||||
para.canvas0_config[1] = scr_data->canvas0_config[1];
|
||||
para.canvas0_config[2] = scr_data->canvas0_config[2];
|
||||
VIDEOCOM_INFO("canvas0:%d %d canvas1:%d %d canvas2:%d %d.\n",
|
||||
scr_data->canvas0_config[0].width, scr_data->canvas0_config[0].height,
|
||||
scr_data->canvas0_config[1].width, scr_data->canvas0_config[1].height,
|
||||
scr_data->canvas0_config[2].width, scr_data->canvas0_config[2].height);
|
||||
para.plane_num = scr_data->plane_num;
|
||||
result = dump_data(¶, SCR_BUFFER);
|
||||
if (result)
|
||||
VIDEOCOM_INFO("dump scr buffer successful.\n");
|
||||
}
|
||||
if (ge2d_com_debug & 8) {
|
||||
para.canvas0_config[0] = dst_canvas0_config[0];
|
||||
para.canvas0_config[1] = dst_canvas0_config[1];
|
||||
para.canvas0_config[2] = dst_canvas0_config[2];
|
||||
para.plane_num = dst_plane_num;
|
||||
result = dump_data(¶, DST_EMPTY_BUFFER);
|
||||
if (result)
|
||||
VIDEOCOM_INFO("dump dst empty buffer successful.\n");
|
||||
}
|
||||
|
||||
position_left = ge2d_comp_para->position_left;
|
||||
position_top = ge2d_comp_para->position_top;
|
||||
position_width = ge2d_comp_para->position_width;
|
||||
position_height = ge2d_comp_para->position_height;
|
||||
|
||||
stretchblt_noalpha(ge2d_comp_para->context,
|
||||
input_x,
|
||||
input_y,
|
||||
input_width,
|
||||
input_height,
|
||||
position_left,
|
||||
position_top,
|
||||
position_width,
|
||||
position_height);
|
||||
if (ge2d_com_debug & 1)
|
||||
VIDEOCOM_INFO("scr %0x,dst: %0x!,%d, %d, %d, %d\n",
|
||||
ge2d_config.src_para.format,
|
||||
ge2d_config.dst_para.format,
|
||||
position_left,
|
||||
position_top,
|
||||
position_width,
|
||||
position_height);
|
||||
if (ge2d_com_debug & 16) {
|
||||
para.canvas0_config[0] = dst_canvas0_config[0];
|
||||
para.canvas0_config[1] = dst_canvas0_config[1];
|
||||
para.canvas0_config[2] = dst_canvas0_config[2];
|
||||
para.plane_num = dst_plane_num;
|
||||
result = dump_data(¶, DST_BUFFER_DATA);
|
||||
if (result)
|
||||
VIDEOCOM_INFO("dump dst data successful.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef VFRAME_GE2D_COMPOSER_H
|
||||
#define VFRAME_GE2D_COMPOSER_H
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
#include <linux/amlogic/media/vfm/vframe.h>
|
||||
//#include "video_composer.h"
|
||||
|
||||
#define VIDEOCOM_INFO(fmt, args...) \
|
||||
pr_info("video_composer: info:" fmt "", ## args)
|
||||
#define VIDEOCOM_DBG(fmt, args...) \
|
||||
pr_debug("video_composer: dbg:" fmt "", ## args)
|
||||
#define VIDEOCOM_WARN(fmt, args...) \
|
||||
pr_warn("video_composer: warn:" fmt "", ## args)
|
||||
#define VIDEOCOM_ERR(fmt, args...) \
|
||||
pr_err("video_composer: err:" fmt "", ## args)
|
||||
|
||||
enum ge2d_angle_type {
|
||||
GE2D_ANGLE_TYPE_ROT_90 = 1,
|
||||
GE2D_ANGLE_TYPE_ROT_180,
|
||||
GE2D_ANGLE_TYPE_ROT_270,
|
||||
GE2D_ANGLE_TYPE_FLIP_H,
|
||||
GE2D_ANGLE_TYPE_FLIP_V,
|
||||
GE2D_ANGLE_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum videocom_source_type {
|
||||
DECODER_8BIT_NORMAL = 0,
|
||||
DECODER_8BIT_BOTTOM,
|
||||
DECODER_8BIT_TOP,
|
||||
DECODER_10BIT_NORMAL,
|
||||
DECODER_10BIT_BOTTOM,
|
||||
DECODER_10BIT_TOP,
|
||||
VDIN_8BIT_NORMAL,
|
||||
VDIN_10BIT_NORMAL,
|
||||
};
|
||||
|
||||
struct ge2d_composer_para {
|
||||
int count;
|
||||
int format;
|
||||
int position_left;
|
||||
int position_top;
|
||||
int position_width;
|
||||
int position_height;
|
||||
int buffer_w;
|
||||
int buffer_h;
|
||||
int plane_num;
|
||||
int canvas_scr[3];
|
||||
int canvas_dst[3];
|
||||
ulong phy_addr[3];
|
||||
u32 canvas0_addr;
|
||||
struct ge2d_context_s *context;
|
||||
int angle;
|
||||
bool is_tvp;
|
||||
};
|
||||
|
||||
struct ge2d_src_para_s {
|
||||
u32 canvas0Addr;
|
||||
u32 canvas1Addr;
|
||||
u32 plane_num;
|
||||
u32 type;
|
||||
u32 position_x;
|
||||
u32 position_y;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 bitdepth;
|
||||
struct canvas_config_s canvas0_config[3];
|
||||
struct canvas_config_s canvas1_config[3];
|
||||
enum vframe_source_type_e source_type;
|
||||
bool is_vframe;
|
||||
bool is_yuv444;
|
||||
};
|
||||
|
||||
struct dump_param {
|
||||
u32 plane_num;
|
||||
struct canvas_config_s canvas0_config[3];
|
||||
};
|
||||
|
||||
enum buffer_data {
|
||||
BLACK_BUFFER = 0,
|
||||
SCR_BUFFER,
|
||||
DST_EMPTY_BUFFER,
|
||||
DST_BUFFER_DATA,
|
||||
OTHER_BUFFER,
|
||||
};
|
||||
|
||||
extern int ge2d_com_debug;
|
||||
int v2d_init_ge2d_composer(struct ge2d_composer_para *ge2d_comp_para);
|
||||
|
||||
int v2d_uninit_ge2d_composer(struct ge2d_composer_para *ge2d_comp_para);
|
||||
|
||||
int v2d_fill_vframe_black(struct ge2d_composer_para *ge2d_comp_para);
|
||||
|
||||
int v2d_config_ge2d_data(struct vframe_s *src_vf, unsigned long addr, int buf_w, int buf_h,
|
||||
int data_w, int data_h, int crop_x, int crop_y, int crop_w, int crop_h,
|
||||
struct ge2d_src_para_s *data);
|
||||
|
||||
int v2d_ge2d_data_composer(struct ge2d_src_para_s *src_para,
|
||||
struct ge2d_composer_para *ge2d_comp_para);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/amlogic/media/canvas/canvas.h>
|
||||
#include <linux/amlogic/media/canvas/canvas_mgr.h>
|
||||
#include <linux/amlogic/media/utils/amlog.h>
|
||||
#include <linux/amlogic/media/vicp/vicp.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/amlogic/media/codec_mm/codec_mm.h>
|
||||
#include <linux/amlogic/media/vfm/vframe.h>
|
||||
#include "v2d_vicp_composer.h"
|
||||
|
||||
bool check_vicp_status(void)
|
||||
{
|
||||
int cpu_type = 0;
|
||||
|
||||
cpu_type = get_cpu_type();
|
||||
if (cpu_type == MESON_CPU_MAJOR_ID_S5 ||
|
||||
cpu_type == MESON_CPU_MAJOR_ID_T3X ||
|
||||
cpu_type == MESON_CPU_MAJOR_ID_S6)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
enum vicp_rotation_mode_e map_rotationmode_from_v2d_to_vicp(int v2d_rotation)
|
||||
{
|
||||
enum vicp_rotation_mode_e rotation = VICP_ROTATION_MAX;
|
||||
|
||||
if (v2d_rotation == 1)
|
||||
rotation = VICP_ROTATION_MIRROR_H;
|
||||
else if (v2d_rotation == 2)
|
||||
rotation = VICP_ROTATION_MIRROR_V;
|
||||
else if (v2d_rotation == 3)
|
||||
rotation = VICP_ROTATION_180;
|
||||
else if (v2d_rotation == 4)
|
||||
rotation = VICP_ROTATION_90;
|
||||
else if (v2d_rotation == 7)
|
||||
rotation = VICP_ROTATION_270;
|
||||
else
|
||||
rotation = VICP_ROTATION_0;
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
int v2d_config_vicp_input_data(struct vframe_s *vf, ulong addr, int width, int height,
|
||||
int stride_w, int stride_y, int endian, int color_fmt, int color_depth,
|
||||
struct input_data_param_s *input_data)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(input_data)) {
|
||||
pr_info("%s: NULL param, please check.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(input_data, 0, sizeof(struct input_data_param_s));
|
||||
if (vf) {
|
||||
input_data->is_vframe = true;
|
||||
input_data->data_vf = vf;
|
||||
} else {
|
||||
input_data->is_vframe = false;
|
||||
if (stride_w > width)
|
||||
input_data->data_dma.buf_stride_w = stride_w;
|
||||
else
|
||||
input_data->data_dma.buf_stride_w = width;
|
||||
|
||||
if (stride_y > height)
|
||||
input_data->data_dma.buf_stride_h = stride_y;
|
||||
else
|
||||
input_data->data_dma.buf_stride_h = height;
|
||||
|
||||
input_data->data_dma.buf_addr = addr;
|
||||
input_data->data_dma.data_width = width;
|
||||
input_data->data_dma.data_height = height;
|
||||
input_data->data_dma.color_format = color_fmt;
|
||||
input_data->data_dma.color_depth = color_depth;
|
||||
input_data->data_dma.plane_count = 2;
|
||||
input_data->data_dma.endian = endian;
|
||||
input_data->data_dma.need_swap_cbcr = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_config_vicp_output_data(int fbc_out_en, int mif_out_en, ulong *phy_addr, int stride,
|
||||
int width, int height, int endian, enum vicp_color_format_e cfmt_mif, int cdep_mif,
|
||||
enum vicp_color_format_e cfmt_fbc, int cdep_fbc, int init_ctrl, int pip_mode,
|
||||
int out_sig_fmt, struct output_data_param_s *output_data)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(output_data)) {
|
||||
pr_info("%s: NULL param, please check.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
memset(output_data, 0, sizeof(struct output_data_param_s));
|
||||
output_data->width = width;
|
||||
output_data->height = height;
|
||||
output_data->phy_addr[0] = phy_addr[0];
|
||||
output_data->stride[0] = stride;
|
||||
output_data->mif_out_en = mif_out_en;
|
||||
output_data->endian = endian;
|
||||
output_data->need_swap_cbcr = 1;
|
||||
output_data->out_sig_fmt = out_sig_fmt;
|
||||
if (mif_out_en) {
|
||||
output_data->mif_color_fmt = cfmt_mif;
|
||||
output_data->mif_color_dep = cdep_mif;
|
||||
}
|
||||
|
||||
output_data->fbc_out_en = fbc_out_en;
|
||||
if (fbc_out_en) {
|
||||
output_data->fbc_color_fmt = cfmt_fbc;
|
||||
output_data->fbc_color_dep = cdep_fbc;
|
||||
output_data->phy_addr[1] = phy_addr[1];
|
||||
output_data->phy_addr[2] = phy_addr[2];
|
||||
output_data->fbc_init_ctrl = init_ctrl;
|
||||
output_data->fbc_pip_mode = pip_mode;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v2d_vicp_data_composer(struct vicp_data_config_s *data_config)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ERR_OR_NULL(data_config)) {
|
||||
pr_info("%s: NULL param, please check.\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_VICP
|
||||
ret = vicp_process(data_config);
|
||||
#endif
|
||||
if (ret < 0)
|
||||
pr_info("%s: vicp_process failed.\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
|
||||
/*
|
||||
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef V2D_VICP_COMPOSER_H
|
||||
#define V2D_VICP_COMPOSER_H
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/amlogic/media/vout/vout_notify.h>
|
||||
#include <linux/amlogic/media/vfm/vframe.h>
|
||||
#include <linux/amlogic/media/vicp/vicp.h>
|
||||
|
||||
bool check_vicp_status(void);
|
||||
enum vicp_rotation_mode_e map_rotationmode_from_v2d_to_vicp(int v2d_rotation);
|
||||
int v2d_config_vicp_input_data(struct vframe_s *vf, ulong addr, int width, int height,
|
||||
int stride_w, int stride_y, int endian, int color_fmt, int color_depth,
|
||||
struct input_data_param_s *input_data);
|
||||
int v2d_config_vicp_output_data(int fbc_out_en, int mif_out_en, ulong *phy_addr, int stride,
|
||||
int width, int height, int endian, enum vicp_color_format_e cfmt_mif, int cdep_mif,
|
||||
enum vicp_color_format_e cfmt_fbc, int cdep_fbc, int init_ctrl, int pip_mode,
|
||||
int out_sig_fmt, struct output_data_param_s *output_data);
|
||||
int v2d_vicp_data_composer(struct vicp_data_config_s *data_config);
|
||||
#ifdef CONFIG_AMLOGIC_MEDIA_VICP
|
||||
int vicp_process(struct vicp_data_config_s *data_config);
|
||||
#endif
|
||||
#endif
|
||||
@@ -50,4 +50,5 @@
|
||||
#define DI_PROCESS_MAJOR (32 + (AML_BASE))
|
||||
#define AML_DHP_MAJOR (33 + (AML_BASE))
|
||||
#define VIDEODISPLAY_MAJOR (34 + (AML_BASE))
|
||||
#define V2D_MAJOR (35 + (AML_BASE))
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user