mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
video/rockchip: rga3: Init version 1.1.1
Signed-off-by: Li Huang <putin.li@rock-chips.com> Change-Id: Ib19d2d141e6b0eefa9d67b062e564559f58fb0b4
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
source "drivers/video/rockchip/rga/Kconfig"
|
||||
source "drivers/video/rockchip/rga2/Kconfig"
|
||||
source "drivers/video/rockchip/rga3/Kconfig"
|
||||
source "drivers/video/rockchip/iep/Kconfig"
|
||||
source "drivers/video/rockchip/mpp/Kconfig"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_ROCKCHIP_RGA) += rga/
|
||||
obj-$(CONFIG_ROCKCHIP_RGA2) += rga2/
|
||||
obj-$(CONFIG_ROCKCHIP_MULTI_RGA) += rga3/
|
||||
obj-$(CONFIG_IEP) += iep/
|
||||
obj-$(CONFIG_ROCKCHIP_MPP_SERVICE) += mpp/
|
||||
|
||||
30
drivers/video/rockchip/rga3/Kconfig
Normal file
30
drivers/video/rockchip/rga3/Kconfig
Normal file
@@ -0,0 +1,30 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
menuconfig ROCKCHIP_MULTI_RGA
|
||||
tristate "MULTI_RGA"
|
||||
depends on ARCH_ROCKCHIP
|
||||
help
|
||||
multi_rga module.
|
||||
|
||||
if ROCKCHIP_MULTI_RGA
|
||||
|
||||
config ROCKCHIP_RGA_PROC_FS
|
||||
bool "Enable RGA procfs"
|
||||
select ROCKCHIP_RGA_DEBUGGER
|
||||
depends on PROC_FS
|
||||
help
|
||||
Enable procfs to debug multi RGA driver.
|
||||
|
||||
config ROCKCHIP_RGA_DEBUG_FS
|
||||
bool "Enable RGA debugfs"
|
||||
select ROCKCHIP_RGA_DEBUGGER
|
||||
depends on DEBUG_FS
|
||||
default y
|
||||
help
|
||||
Enable debugfs to debug multi RGA driver.
|
||||
|
||||
config ROCKCHIP_RGA_DEBUGGER
|
||||
bool
|
||||
help
|
||||
Enabling the debugger of multi RGA, you can use procfs and debugfs for debugging.
|
||||
|
||||
endif
|
||||
8
drivers/video/rockchip/rga3/Makefile
Normal file
8
drivers/video/rockchip/rga3/Makefile
Normal file
@@ -0,0 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
ccflags-y += -I$(srctree)/$(src)/include
|
||||
|
||||
rga3-y := rga_drv.o rga3_reg_info.o rga_dma_buf.o rga_fence.o rga_job.o rga_hw_config.o rga2_reg_info.o rga2_mmu_info.o
|
||||
rga3-$(CONFIG_ROCKCHIP_RGA_DEBUGGER) += rga_debugger.o
|
||||
|
||||
obj-$(CONFIG_ROCKCHIP_MULTI_RGA) += rga3.o
|
||||
613
drivers/video/rockchip/rga3/include/rga.h
Normal file
613
drivers/video/rockchip/rga3/include/rga.h
Normal file
@@ -0,0 +1,613 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _RGA_DRIVER_H_
|
||||
#define _RGA_DRIVER_H_
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
#define RGA_BLIT_SYNC 0x5017
|
||||
#define RGA_BLIT_ASYNC 0x5018
|
||||
#define RGA_FLUSH 0x5019
|
||||
#define RGA_GET_RESULT 0x501a
|
||||
#define RGA_GET_VERSION 0x501b
|
||||
#define RGA_CACHE_FLUSH 0x501c
|
||||
|
||||
#define RGA2_GET_VERSION 0x601b
|
||||
#define RGA_IMPORT_DMA 0x601d
|
||||
#define RGA_RELEASE_DMA 0x601e
|
||||
|
||||
#define RGA_OUT_OF_RESOURCES -10
|
||||
#define RGA_MALLOC_ERROR -11
|
||||
|
||||
#define SCALE_DOWN_LARGE 1
|
||||
#define SCALE_UP_LARGE 1
|
||||
|
||||
#define RGA3_MAJOR_VERSION_MASK (0xF0000000)
|
||||
#define RGA3_MINOR_VERSION_MASK (0x0FF00000)
|
||||
#define RGA3_SVN_VERSION_MASK (0x000FFFFF)
|
||||
|
||||
#define RGA2_MAJOR_VERSION_MASK (0xFF000000)
|
||||
#define RGA2_MINOR_VERSION_MASK (0x00F00000)
|
||||
#define RGA2_SVN_VERSION_MASK (0x000FFFFF)
|
||||
|
||||
#define RGA_MODE_ROTATE_0 (1<<0)
|
||||
#define RGA_MODE_ROTATE_90 (1<<1)
|
||||
#define RGA_MODE_ROTATE_180 (1<<2)
|
||||
#define RGA_MODE_ROTATE_270 (1<<3)
|
||||
#define RGA_MODE_X_MIRROR (1<<4)
|
||||
#define RGA_MODE_Y_MIRROR (1<<5)
|
||||
|
||||
#define RGA_MODE_CSC_BT601L (1<<0)
|
||||
#define RGA_MODE_CSC_BT601F (1<<1)
|
||||
#define RGA_MODE_CSC_BT709 (1<<2)
|
||||
#define RGA_MODE_CSC_BT2020 (1<<3)
|
||||
|
||||
#define RGA_MODE_ROTATE_MASK (\
|
||||
RGA_MODE_ROTATE_0 | \
|
||||
RGA_MODE_ROTATE_90 | \
|
||||
RGA_MODE_ROTATE_180 | \
|
||||
RGA_MODE_ROTATE_270 | \
|
||||
RGA_MODE_X_MIRROR | \
|
||||
RGA_MODE_Y_MIRROR)
|
||||
|
||||
enum rga_scale_up_mode {
|
||||
RGA_SCALE_UP_NONE = 0x0,
|
||||
RGA_SCALE_UP_BIC = 0x1,
|
||||
};
|
||||
|
||||
enum rga_scale_down_mode {
|
||||
RGA_SCALE_DOWN_NONE = 0x0,
|
||||
RGA_SCALE_DOWN_AVG = 0x1,
|
||||
};
|
||||
|
||||
/* RGA process mode enum */
|
||||
enum {
|
||||
BITBLT_MODE = 0x0,
|
||||
COLOR_PALETTE_MODE = 0x1,
|
||||
COLOR_FILL_MODE = 0x2,
|
||||
/* used by rga2 */
|
||||
UPDATE_PALETTE_TABLE_MODE = 0x6,
|
||||
UPDATE_PATTEN_BUF_MODE = 0x7,
|
||||
}; /*render mode*/
|
||||
|
||||
/* RGA rd_mode */
|
||||
enum {
|
||||
RGA_RASTER_MODE = 0x1 << 0,
|
||||
RGA_FBC_MODE = 0x1 << 1,
|
||||
RGA_TILE_MODE = 0x1 << 2,
|
||||
};
|
||||
|
||||
/* RGA feature */
|
||||
enum {
|
||||
RGA_COLOR_FILL = 0x1 << 0,
|
||||
RGA_COLOR_PALETTE = 0x1 << 1,
|
||||
RGA_COLOR_KEY = 0x1 << 2,
|
||||
RGA_ROP_CALCULATE = 0x1 << 3,
|
||||
RGA_NN_QUANTIZE = 0x1 << 4,
|
||||
RGA_OSD_BLEND = 0x1 << 5,
|
||||
RGA_DITHER = 0x1 << 6,
|
||||
};
|
||||
|
||||
enum {
|
||||
RGA2_FORMAT_RGBA_8888 = 0x0,
|
||||
RGA2_FORMAT_RGBX_8888 = 0x1,
|
||||
RGA2_FORMAT_RGB_888 = 0x2,
|
||||
RGA2_FORMAT_BGRA_8888 = 0x3,
|
||||
RGA2_FORMAT_BGRX_8888 = 0x4,
|
||||
RGA2_FORMAT_BGR_888 = 0x5,
|
||||
RGA2_FORMAT_RGB_565 = 0x6,
|
||||
RGA2_FORMAT_RGBA_5551 = 0x7,
|
||||
RGA2_FORMAT_RGBA_4444 = 0x8,
|
||||
RGA2_FORMAT_BGR_565 = 0x9,
|
||||
RGA2_FORMAT_BGRA_5551 = 0xa,
|
||||
RGA2_FORMAT_BGRA_4444 = 0xb,
|
||||
|
||||
RGA2_FORMAT_Y4 = 0xe,
|
||||
RGA2_FORMAT_YCbCr_400 = 0xf,
|
||||
|
||||
RGA2_FORMAT_YCbCr_422_SP = 0x10,
|
||||
RGA2_FORMAT_YCbCr_422_P = 0x11,
|
||||
RGA2_FORMAT_YCbCr_420_SP = 0x12,
|
||||
RGA2_FORMAT_YCbCr_420_P = 0x13,
|
||||
RGA2_FORMAT_YCrCb_422_SP = 0x14,
|
||||
RGA2_FORMAT_YCrCb_422_P = 0x15,
|
||||
RGA2_FORMAT_YCrCb_420_SP = 0x16,
|
||||
RGA2_FORMAT_YCrCb_420_P = 0x17,
|
||||
|
||||
RGA2_FORMAT_YVYU_422 = 0x18,
|
||||
RGA2_FORMAT_YVYU_420 = 0x19,
|
||||
RGA2_FORMAT_VYUY_422 = 0x1a,
|
||||
RGA2_FORMAT_VYUY_420 = 0x1b,
|
||||
RGA2_FORMAT_YUYV_422 = 0x1c,
|
||||
RGA2_FORMAT_YUYV_420 = 0x1d,
|
||||
RGA2_FORMAT_UYVY_422 = 0x1e,
|
||||
RGA2_FORMAT_UYVY_420 = 0x1f,
|
||||
|
||||
RGA2_FORMAT_YCbCr_420_SP_10B = 0x20,
|
||||
RGA2_FORMAT_YCrCb_420_SP_10B = 0x21,
|
||||
RGA2_FORMAT_YCbCr_422_SP_10B = 0x22,
|
||||
RGA2_FORMAT_YCrCb_422_SP_10B = 0x23,
|
||||
|
||||
RGA2_FORMAT_BPP_1 = 0x24,
|
||||
RGA2_FORMAT_BPP_2 = 0x25,
|
||||
RGA2_FORMAT_BPP_4 = 0x26,
|
||||
RGA2_FORMAT_BPP_8 = 0x27,
|
||||
|
||||
RGA2_FORMAT_ARGB_8888 = 0x28,
|
||||
RGA2_FORMAT_XRGB_8888 = 0x29,
|
||||
RGA2_FORMAT_ARGB_5551 = 0x2a,
|
||||
RGA2_FORMAT_ARGB_4444 = 0x2b,
|
||||
RGA2_FORMAT_ABGR_8888 = 0x2c,
|
||||
RGA2_FORMAT_XBGR_8888 = 0x2d,
|
||||
RGA2_FORMAT_ABGR_5551 = 0x2e,
|
||||
RGA2_FORMAT_ABGR_4444 = 0x2f,
|
||||
};
|
||||
|
||||
#define RGA_SCHED_PRIORITY_DEFAULT 0
|
||||
#define RGA_SCHED_PRIORITY_MAX 6
|
||||
|
||||
struct rga_mmu_info_t {
|
||||
unsigned long src0_base_addr;
|
||||
unsigned long src1_base_addr;
|
||||
unsigned long dst_base_addr;
|
||||
unsigned long els_base_addr;
|
||||
|
||||
/* [0] mmu enable [1] flush [2] prefetch_en [3] prefetch dir */
|
||||
u8 src0_mmu_flag;
|
||||
u8 src1_mmu_flag;
|
||||
u8 dst_mmu_flag;
|
||||
u8 els_mmu_flag;
|
||||
};
|
||||
|
||||
struct rga_color_fill_t {
|
||||
int16_t gr_x_a;
|
||||
int16_t gr_y_a;
|
||||
int16_t gr_x_b;
|
||||
int16_t gr_y_b;
|
||||
int16_t gr_x_g;
|
||||
int16_t gr_y_g;
|
||||
int16_t gr_x_r;
|
||||
int16_t gr_y_r;
|
||||
};
|
||||
|
||||
/***************************************/
|
||||
/* porting from rga.h for msg convert */
|
||||
/***************************************/
|
||||
|
||||
struct rga_fading_t {
|
||||
uint8_t b;
|
||||
uint8_t g;
|
||||
uint8_t r;
|
||||
uint8_t res;
|
||||
};
|
||||
|
||||
struct rga_mmu_t {
|
||||
uint8_t mmu_en;
|
||||
uint64_t base_addr;
|
||||
/*
|
||||
* [0] mmu enable [1] src_flush [2] dst_flush
|
||||
* [3] CMD_flush [4~5] page size
|
||||
*/
|
||||
uint32_t mmu_flag;
|
||||
};
|
||||
|
||||
struct rga_rect_t {
|
||||
uint16_t xmin;
|
||||
/* width - 1 */
|
||||
uint16_t xmax;
|
||||
uint16_t ymin;
|
||||
/* height - 1 */
|
||||
uint16_t ymax;
|
||||
};
|
||||
|
||||
struct rga_point_t {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
};
|
||||
|
||||
struct rga_line_draw_t {
|
||||
/* LineDraw_start_point */
|
||||
struct rga_point_t start_point;
|
||||
/* LineDraw_end_point */
|
||||
struct rga_point_t end_point;
|
||||
/* LineDraw_color */
|
||||
uint32_t color;
|
||||
/* (enum) LineDrawing mode sel */
|
||||
uint32_t flag;
|
||||
/* range 1~16 */
|
||||
uint32_t line_width;
|
||||
};
|
||||
|
||||
/* color space convert coefficient. */
|
||||
struct rga_csc_coe_t {
|
||||
int16_t r_v;
|
||||
int16_t g_y;
|
||||
int16_t b_u;
|
||||
int32_t off;
|
||||
};
|
||||
|
||||
struct rga_full_csc_t {
|
||||
uint8_t flag;
|
||||
struct rga_csc_coe_t coe_y;
|
||||
struct rga_csc_coe_t coe_u;
|
||||
struct rga_csc_coe_t coe_v;
|
||||
};
|
||||
|
||||
struct rga_win_info_t {
|
||||
/* yrgb mem addr */
|
||||
unsigned long yrgb_addr;
|
||||
/* cb/cr mem addr */
|
||||
unsigned long uv_addr;
|
||||
/* cr mem addr */
|
||||
unsigned long v_addr;
|
||||
/* definition by RK_FORMAT */
|
||||
unsigned int format;
|
||||
|
||||
unsigned short src_act_w;
|
||||
unsigned short src_act_h;
|
||||
|
||||
unsigned short dst_act_w;
|
||||
unsigned short dst_act_h;
|
||||
|
||||
unsigned short x_offset;
|
||||
unsigned short y_offset;
|
||||
|
||||
unsigned short vir_w;
|
||||
unsigned short vir_h;
|
||||
|
||||
unsigned short rotate_mode;
|
||||
/* RASTER or FBCD or TILE */
|
||||
unsigned short rd_mode;
|
||||
|
||||
unsigned short is_10b_compact;
|
||||
unsigned short is_10b_endian;
|
||||
|
||||
unsigned short enable;
|
||||
};
|
||||
|
||||
struct rga_img_info_t {
|
||||
/* yrgb mem addr */
|
||||
uint64_t yrgb_addr;
|
||||
/* cb/cr mem addr */
|
||||
uint64_t uv_addr;
|
||||
/* cr mem addr */
|
||||
uint64_t v_addr;
|
||||
/* definition by RK_FORMAT */
|
||||
uint32_t format;
|
||||
|
||||
uint16_t act_w;
|
||||
uint16_t act_h;
|
||||
uint16_t x_offset;
|
||||
uint16_t y_offset;
|
||||
|
||||
uint16_t vir_w;
|
||||
uint16_t vir_h;
|
||||
|
||||
uint16_t endian_mode;
|
||||
/* useless */
|
||||
uint16_t alpha_swap;
|
||||
|
||||
/* used by RGA3 */
|
||||
uint16_t rotate_mode;
|
||||
uint16_t rd_mode;
|
||||
|
||||
uint16_t is_10b_compact;
|
||||
uint16_t is_10b_endian;
|
||||
|
||||
uint16_t enable;
|
||||
};
|
||||
|
||||
struct rga_req {
|
||||
/* (enum) process mode sel */
|
||||
uint8_t render_mode;
|
||||
|
||||
struct rga_img_info_t src;
|
||||
struct rga_img_info_t dst;
|
||||
struct rga_img_info_t pat;
|
||||
|
||||
/* rop4 mask addr */
|
||||
uint64_t rop_mask_addr;
|
||||
/* LUT addr */
|
||||
uint64_t LUT_addr;
|
||||
|
||||
/* dst clip window default value is dst_vir */
|
||||
/* value from [0, w-1] / [0, h-1]*/
|
||||
struct rga_rect_t clip;
|
||||
|
||||
/* dst angle default value 0 16.16 scan from table */
|
||||
int32_t sina;
|
||||
/* dst angle default value 0 16.16 scan from table */
|
||||
int32_t cosa;
|
||||
|
||||
/* alpha rop process flag */
|
||||
/* ([0] = 1 alpha_rop_enable) */
|
||||
/* ([1] = 1 rop enable) */
|
||||
/* ([2] = 1 fading_enable) */
|
||||
/* ([3] = 1 PD_enable) */
|
||||
/* ([4] = 1 alpha cal_mode_sel) */
|
||||
/* ([5] = 1 dither_enable) */
|
||||
/* ([6] = 1 gradient fill mode sel) */
|
||||
/* ([7] = 1 AA_enable) */
|
||||
uint16_t alpha_rop_flag;
|
||||
|
||||
/* 0 nearst / 1 bilnear / 2 bicubic */
|
||||
uint8_t scale_mode;
|
||||
|
||||
/* color key max */
|
||||
uint32_t color_key_max;
|
||||
/* color key min */
|
||||
uint32_t color_key_min;
|
||||
|
||||
/* foreground color */
|
||||
uint32_t fg_color;
|
||||
/* background color */
|
||||
uint32_t bg_color;
|
||||
|
||||
/* color fill use gradient */
|
||||
struct rga_color_fill_t gr_color;
|
||||
|
||||
struct rga_line_draw_t line_draw_info;
|
||||
|
||||
struct rga_fading_t fading;
|
||||
|
||||
/* porter duff alpha mode sel */
|
||||
uint8_t PD_mode;
|
||||
|
||||
/* global alpha value */
|
||||
uint8_t alpha_global_value;
|
||||
|
||||
/* rop2/3/4 code scan from rop code table*/
|
||||
uint16_t rop_code;
|
||||
|
||||
/* [2] 0 blur 1 sharp / [1:0] filter_type*/
|
||||
uint8_t bsfilter_flag;
|
||||
|
||||
/* (enum) color palette 0/1bpp, 1/2bpp 2/4bpp 3/8bpp*/
|
||||
uint8_t palette_mode;
|
||||
|
||||
/* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */
|
||||
uint8_t yuv2rgb_mode;
|
||||
|
||||
/* 0/big endian 1/little endian*/
|
||||
uint8_t endian_mode;
|
||||
|
||||
/* (enum) rotate mode */
|
||||
/* 0x0, no rotate */
|
||||
/* 0x1, rotate */
|
||||
/* 0x2, x_mirror */
|
||||
/* 0x3, y_mirror */
|
||||
uint8_t rotate_mode;
|
||||
|
||||
/* 0 solid color / 1 pattern color */
|
||||
uint8_t color_fill_mode;
|
||||
|
||||
/* mmu information */
|
||||
struct rga_mmu_t mmu_info;
|
||||
|
||||
/* ([0~1] alpha mode) */
|
||||
/* ([2~3] rop mode) */
|
||||
/* ([4] zero mode en) */
|
||||
/* ([5] dst alpha mode) */
|
||||
/* ([6] alpha output mode sel) 0 src / 1 dst*/
|
||||
uint8_t alpha_rop_mode;
|
||||
|
||||
uint8_t src_trans_mode;
|
||||
|
||||
uint8_t dither_mode;
|
||||
|
||||
/* full color space convert */
|
||||
struct rga_full_csc_t full_csc;
|
||||
|
||||
int32_t in_fence_fd;
|
||||
uint8_t core;
|
||||
uint8_t priority;
|
||||
int32_t out_fence_fd;
|
||||
|
||||
uint8_t reservr[128];
|
||||
};
|
||||
|
||||
struct rga2_req {
|
||||
/* (enum) process mode sel */
|
||||
u8 render_mode;
|
||||
|
||||
/* active window */
|
||||
struct rga_img_info_t src;
|
||||
struct rga_img_info_t src1;
|
||||
struct rga_img_info_t dst;
|
||||
struct rga_img_info_t pat;
|
||||
|
||||
/* rop4 mask addr */
|
||||
unsigned long rop_mask_addr;
|
||||
/* LUT addr */
|
||||
unsigned long LUT_addr;
|
||||
|
||||
u32 rop_mask_stride;
|
||||
|
||||
/* 0: SRC + DST => DST */
|
||||
/* 1: SRC + SRC1 => DST */
|
||||
u8 bitblt_mode;
|
||||
|
||||
/* [1:0] */
|
||||
/* 0 degree 0x0 */
|
||||
/* 90 degree 0x1 */
|
||||
/* 180 degree 0x2 */
|
||||
/* 270 degree 0x3 */
|
||||
/* [5:4] */
|
||||
/* none 0x0 */
|
||||
/* x_mirror 0x1 */
|
||||
/* y_mirror 0x2 */
|
||||
/* x_mirror + y_mirror 0x3 */
|
||||
u8 rotate_mode;
|
||||
|
||||
/* alpha rop process flag */
|
||||
/* ([0] = 1 alpha_rop_enable) */
|
||||
/* ([1] = 1 rop enable) */
|
||||
/* ([2] = 1 fading_enable) */
|
||||
/* ([3] = 1 alpha cal_mode_sel) */
|
||||
/* ([4] = 1 src_dither_up_enable) */
|
||||
/* ([5] = 1 dst_dither_up_enable) */
|
||||
/* ([6] = 1 dither_down_enable) */
|
||||
/* ([7] = 1 gradient fill mode sel) */
|
||||
u16 alpha_rop_flag;
|
||||
|
||||
/* [0] SrcAlphaMode0 */
|
||||
/* [2:1] SrcGlobalAlphaMode0 */
|
||||
/* [3] SrcAlphaSelectMode0 */
|
||||
/* [6:4] SrcFactorMode0 */
|
||||
/* [7] SrcColorMode */
|
||||
|
||||
/* [8] DstAlphaMode0 */
|
||||
/* [10:9] DstGlobalAlphaMode0 */
|
||||
/* [11] DstAlphaSelectMode0 */
|
||||
/* [14:12] DstFactorMode0 */
|
||||
/* [15] DstColorMode0 */
|
||||
u16 alpha_mode_0;
|
||||
|
||||
/* [0] SrcAlphaMode1 */
|
||||
/* [2:1] SrcGlobalAlphaMode1 */
|
||||
/* [3] SrcAlphaSelectMode1 */
|
||||
/* [6:4] SrcFactorMode1 */
|
||||
|
||||
/* [8] DstAlphaMode1 */
|
||||
/* [10:9] DstGlobalAlphaMode1 */
|
||||
/* [11] DstAlphaSelectMode1 */
|
||||
/* [14:12] DstFactorMode1 */
|
||||
u16 alpha_mode_1;
|
||||
|
||||
/* 0 1 2 3 */
|
||||
u8 scale_bicu_mode;
|
||||
|
||||
u32 color_key_max;
|
||||
u32 color_key_min;
|
||||
|
||||
/* foreground color */
|
||||
u32 fg_color;
|
||||
/* background color */
|
||||
u32 bg_color;
|
||||
|
||||
u8 color_fill_mode;
|
||||
/* color fill use gradient */
|
||||
struct rga_color_fill_t gr_color;
|
||||
|
||||
/* Fading value */
|
||||
u8 fading_alpha_value;
|
||||
u8 fading_r_value;
|
||||
u8 fading_g_value;
|
||||
u8 fading_b_value;
|
||||
|
||||
/* src global alpha value */
|
||||
u8 src_a_global_val;
|
||||
/* dst global alpha value */
|
||||
u8 dst_a_global_val;
|
||||
|
||||
/* rop mode select 0 : rop2 1 : rop3 2 : rop4 */
|
||||
u8 rop_mode;
|
||||
/* rop2/3/4 code */
|
||||
u16 rop_code;
|
||||
|
||||
/* (enum) color palette 0/1bpp, 1/2bpp 2/4bpp 3/8bpp*/
|
||||
u8 palette_mode;
|
||||
|
||||
/* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */
|
||||
u8 yuv2rgb_mode;
|
||||
|
||||
/* [1:0] src0 csc mode */
|
||||
/* [3:2] dst csc mode */
|
||||
/* [4] dst csc clip enable */
|
||||
/* [6:5] src1 csc mdoe */
|
||||
/* [7] src1 csc clip enable */
|
||||
/* full color space convert */
|
||||
struct rga_full_csc_t full_csc;
|
||||
|
||||
/* 0/little endian 1/big endian */
|
||||
u8 endian_mode;
|
||||
|
||||
u8 CMD_fin_int_enable;
|
||||
|
||||
/* mmu information */
|
||||
struct rga_mmu_info_t mmu_info;
|
||||
|
||||
u8 alpha_zero_key;
|
||||
u8 src_trans_mode;
|
||||
|
||||
/* useless */
|
||||
u8 alpha_swp;
|
||||
u8 dither_mode;
|
||||
|
||||
u8 rgb2yuv_mode;
|
||||
};
|
||||
|
||||
struct rga3_req {
|
||||
/* (enum) process mode sel */
|
||||
u8 render_mode;
|
||||
|
||||
struct rga_win_info_t win0;
|
||||
struct rga_win_info_t wr;
|
||||
struct rga_win_info_t win1;
|
||||
|
||||
/* rop4 mask addr */
|
||||
unsigned long rop_mask_addr;
|
||||
unsigned long LUT_addr;
|
||||
|
||||
u32 rop_mask_stride;
|
||||
|
||||
u8 bitblt_mode;
|
||||
u8 rotate_mode;
|
||||
|
||||
u16 alpha_rop_flag;
|
||||
|
||||
u16 alpha_mode_0;
|
||||
u16 alpha_mode_1;
|
||||
|
||||
u8 scale_bicu_mode;
|
||||
|
||||
u32 color_key_max;
|
||||
u32 color_key_min;
|
||||
|
||||
u32 fg_color;
|
||||
u32 bg_color;
|
||||
|
||||
u8 color_fill_mode;
|
||||
struct rga_color_fill_t gr_color;
|
||||
|
||||
u8 fading_alpha_value;
|
||||
u8 fading_r_value;
|
||||
u8 fading_g_value;
|
||||
u8 fading_b_value;
|
||||
|
||||
/* win0 global alpha value */
|
||||
u8 win0_a_global_val;
|
||||
/* win1 global alpha value */
|
||||
u8 win1_a_global_val;
|
||||
|
||||
u8 rop_mode;
|
||||
u16 rop_code;
|
||||
|
||||
u8 palette_mode;
|
||||
|
||||
u8 yuv2rgb_mode;
|
||||
|
||||
u8 endian_mode;
|
||||
|
||||
u8 CMD_fin_int_enable;
|
||||
|
||||
struct rga_mmu_info_t mmu_info;
|
||||
|
||||
u8 alpha_zero_key;
|
||||
u8 src_trans_mode;
|
||||
|
||||
u8 alpha_swp;
|
||||
u8 dither_mode;
|
||||
|
||||
u8 rgb2yuv_mode;
|
||||
};
|
||||
|
||||
struct rga_mpi_job_t {
|
||||
struct dma_buf *dma_buf_src0;
|
||||
struct dma_buf *dma_buf_src1;
|
||||
struct dma_buf *dma_buf_dst;
|
||||
};
|
||||
|
||||
int rga_mpi_commit(struct rga_req *cmd, struct rga_mpi_job_t *mpi_job);
|
||||
|
||||
#endif /*_RGA_DRIVER_H_*/
|
||||
47
drivers/video/rockchip/rga3/include/rga2_mmu_info.h
Normal file
47
drivers/video/rockchip/rga3/include/rga2_mmu_info.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __RGA_MMU_INFO_H__
|
||||
#define __RGA_MMU_INFO_H__
|
||||
|
||||
#include "rga_drv.h"
|
||||
|
||||
/*
|
||||
* The maximum input is 8192*8192, the maximum output is 4096*4096
|
||||
* The size of physical pages requested is:
|
||||
* (( maximum_input_value *
|
||||
* maximum_input_value * format_bpp ) / 4K_page_size) + 1
|
||||
*/
|
||||
#define RGA2_PHY_PAGE_SIZE (((8192 * 8192 * 4) / 4096) + 1)
|
||||
|
||||
enum {
|
||||
MMU_MAP_CLEAN = 1 << 0,
|
||||
MMU_MAP_INVALID = 1 << 1,
|
||||
MMU_MAP_MASK = 0x03,
|
||||
MMU_UNMAP_CLEAN = 1 << 2,
|
||||
MMU_UNMAP_INVALID = 1 << 3,
|
||||
MMU_UNMAP_MASK = 0x0c,
|
||||
};
|
||||
|
||||
struct rga2_mmu_info_t {
|
||||
int32_t front;
|
||||
int32_t back;
|
||||
int32_t size;
|
||||
int32_t curr;
|
||||
unsigned int *buf;
|
||||
unsigned int *buf_virtual;
|
||||
|
||||
struct page **pages;
|
||||
|
||||
u8 buf_order;
|
||||
u8 pages_order;
|
||||
};
|
||||
|
||||
void rga2_dma_sync_flush_range(void *pstart, void *pend, struct rga_scheduler_t *scheduler);
|
||||
dma_addr_t rga2_dma_map_flush_page(struct page *page, int map, struct rga_scheduler_t *scheduler);
|
||||
void rga2_dma_flush_cache_for_virtual_address(struct rga2_mmu_other_t *reg,
|
||||
struct rga_scheduler_t *scheduler);
|
||||
|
||||
int rga2_set_mmu_reg_info(struct rga2_mmu_other_t *reg,
|
||||
struct rga2_req *req, struct rga_job *job);
|
||||
|
||||
#endif
|
||||
|
||||
332
drivers/video/rockchip/rga3/include/rga2_reg_info.h
Normal file
332
drivers/video/rockchip/rga3/include/rga2_reg_info.h
Normal file
@@ -0,0 +1,332 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __REG2_INFO_H__
|
||||
#define __REG2_INFO_H__
|
||||
|
||||
#include "rga_drv.h"
|
||||
|
||||
/* General Registers */
|
||||
#define RGA2_SYS_CTRL 0x000
|
||||
#define RGA2_CMD_CTRL 0x004
|
||||
#define RGA2_CMD_BASE 0x008
|
||||
#define RGA2_STATUS 0x00c
|
||||
#define RGA2_INT 0x010
|
||||
#define RGA2_MMU_CTRL0 0x018
|
||||
#define RGA2_MMU_CMD_BASE 0x01c
|
||||
#define RGA2_VERSION_NUM 0x028
|
||||
|
||||
/* Full Csc Coefficient */
|
||||
#define RGA2_CSC_COE_BASE 0x60
|
||||
|
||||
#define rRGA_SYS_CTRL \
|
||||
(*(volatile u32 *)(RGA2_BASE + RGA2_SYS_CTRL_OFFSET))
|
||||
#define rRGA_CMD_CTRL \
|
||||
(*(volatile u32 *)(RGA2_BASE + RGA2_CMD_CTRL_OFFSET))
|
||||
#define rRGA_CMD_BASE \
|
||||
(*(volatile u32 *)(RGA2_BASE + RGA2_CMD_BASE_OFFSET))
|
||||
#define rRGA_STATUS \
|
||||
(*(volatile u32 *)(RGA2_BASE + RGA2_STATUS_OFFSET))
|
||||
#define rRGA_INT \
|
||||
(*(volatile u32 *)(RGA2_BASE + RGA2_INT_OFFSET))
|
||||
#define rRGA_MMU_CTRL0 \
|
||||
(*(volatile u32 *)(RGA2_BASE + RGA2_MMU_CTRL0_OFFSET))
|
||||
#define rRGA_MMU_CMD_BASE \
|
||||
(*(volatile u32 *)(RGA2_BASE + RGA2_MMU_CMD_BASE_OFFSET))
|
||||
#define rRGA_CMD_ADDR \
|
||||
(*(volatile u32 *)(RGA2_BASE + RGA2_CMD_ADDR))
|
||||
|
||||
/* RGA_INT */
|
||||
#define m_RGA2_INT_ALL_CMD_DONE_INT_EN (1<<10)
|
||||
#define m_RGA2_INT_MMU_INT_EN (1<<9)
|
||||
#define m_RGA2_INT_ERROR_INT_EN (1<<8)
|
||||
#define m_RGA2_INT_NOW_CMD_DONE_INT_CLEAR (1<<7)
|
||||
#define m_RGA2_INT_ALL_CMD_DONE_INT_CLEAR (1<<6)
|
||||
#define m_RGA2_INT_MMU_INT_CLEAR (1<<5)
|
||||
#define m_RGA2_INT_ERROR_INT_CLEAR (1<<4)
|
||||
#define m_RGA2_INT_CUR_CMD_DONE_INT_FLAG (1<<3)
|
||||
#define m_RGA2_INT_ALL_CMD_DONE_INT_FLAG (1<<2)
|
||||
#define m_RGA2_INT_MMU_INT_FLAG (1<<1)
|
||||
#define m_RGA2_INT_ERROR_INT_FLAG (1<<0)
|
||||
|
||||
#define s_RGA2_INT_ALL_CMD_DONE_INT_EN(x) ((x&0x1)<<10)
|
||||
#define s_RGA2_INT_MMU_INT_EN(x) ((x&0x1)<<9)
|
||||
#define s_RGA2_INT_ERROR_INT_EN(x) ((x&0x1)<<8)
|
||||
#define s_RGA2_INT_NOW_CMD_DONE_INT_CLEAR(x) ((x&0x1)<<7)
|
||||
#define s_RGA2_INT_ALL_CMD_DONE_INT_CLEAR(x) ((x&0x1)<<6)
|
||||
#define s_RGA2_INT_MMU_INT_CLEAR(x) ((x&0x1)<<5)
|
||||
#define s_RGA2_INT_ERROR_INT_CLEAR(x) ((x&0x1)<<4)
|
||||
|
||||
/* RGA_MODE_CTRL */
|
||||
#define m_RGA2_MODE_CTRL_SW_RENDER_MODE (0x7<<0)
|
||||
#define m_RGA2_MODE_CTRL_SW_BITBLT_MODE (0x1<<3)
|
||||
#define m_RGA2_MODE_CTRL_SW_CF_ROP4_PAT (0x1<<4)
|
||||
#define m_RGA2_MODE_CTRL_SW_ALPHA_ZERO_KET (0x1<<5)
|
||||
#define m_RGA2_MODE_CTRL_SW_GRADIENT_SAT (0x1<<6)
|
||||
#define m_RGA2_MODE_CTRL_SW_INTR_CF_E (0x1<<7)
|
||||
|
||||
#define s_RGA2_MODE_CTRL_SW_RENDER_MODE(x) ((x&0x7)<<0)
|
||||
#define s_RGA2_MODE_CTRL_SW_BITBLT_MODE(x) ((x&0x1)<<3)
|
||||
#define s_RGA2_MODE_CTRL_SW_CF_ROP4_PAT(x) ((x&0x1)<<4)
|
||||
#define s_RGA2_MODE_CTRL_SW_ALPHA_ZERO_KET(x) ((x&0x1)<<5)
|
||||
#define s_RGA2_MODE_CTRL_SW_GRADIENT_SAT(x) ((x&0x1)<<6)
|
||||
#define s_RGA2_MODE_CTRL_SW_INTR_CF_E(x) ((x&0x1)<<7)
|
||||
|
||||
/* RGA_SRC_INFO */
|
||||
#define m_RGA2_SRC_INFO_SW_SRC_FMT (0xf<<0)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_RB_SWAP (0x1<<4)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_ALPHA_SWAP (0x1<<5)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_UV_SWAP (0x1<<6)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_CP_ENDAIN (0x1<<7)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_CSC_MODE (0x3<<8)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_ROT_MODE (0x3<<10)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_MIR_MODE (0x3<<12)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_HSCL_MODE (0x3<<14)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_VSCL_MODE (0x3<<16)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_TRANS_MODE (0x1<<18)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_TRANS_E (0xf<<19)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_DITHER_UP_E (0x1<<23)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_SRC_SCL_FILTER (0x3<<24)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL (0x1<<26)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_YUV10_E (0x1<<27)
|
||||
#define m_RGA2_SRC_INFO_SW_SW_YUV10_ROUND_E (0x1<<28)
|
||||
|
||||
|
||||
#define s_RGA2_SRC_INFO_SW_SRC_FMT(x) ((x&0xf)<<0)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_RB_SWAP(x) ((x&0x1)<<4)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_ALPHA_SWAP(x) ((x&0x1)<<5)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_UV_SWAP(x) ((x&0x1)<<6)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_CP_ENDAIN(x) ((x&0x1)<<7)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_CSC_MODE(x) ((x&0x3)<<8)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_ROT_MODE(x) ((x&0x3)<<10)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_MIR_MODE(x) ((x&0x3)<<12)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_HSCL_MODE(x) ((x&0x3)<<14)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_VSCL_MODE(x) ((x&0x3)<<16)
|
||||
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_TRANS_MODE(x) ((x&0x1)<<18)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_TRANS_E(x) ((x&0xf)<<19)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_DITHER_UP_E(x) ((x&0x1)<<23)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_SRC_SCL_FILTER(x) ((x&0x3)<<24)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_VSP_MODE_SEL(x) ((x&0x1)<<26)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_YUV10_E(x) ((x&0x1)<<27)
|
||||
#define s_RGA2_SRC_INFO_SW_SW_YUV10_ROUND_E(x) ((x&0x1)<<28)
|
||||
|
||||
/* RGA_SRC_VIR_INFO */
|
||||
#define m_RGA2_SRC_VIR_INFO_SW_SRC_VIR_STRIDE (0x7fff<<0)
|
||||
#define m_RGA2_SRC_VIR_INFO_SW_MASK_VIR_STRIDE (0x3ff<<16)
|
||||
|
||||
#define s_RGA2_SRC_VIR_INFO_SW_SRC_VIR_STRIDE(x) ((x&0x7fff)<<0)
|
||||
#define s_RGA2_SRC_VIR_INFO_SW_MASK_VIR_STRIDE(x) ((x&0x3ff)<<16)
|
||||
|
||||
|
||||
/* RGA_SRC_ACT_INFO */
|
||||
#define m_RGA2_SRC_ACT_INFO_SW_SRC_ACT_WIDTH (0x1fff<<0)
|
||||
#define m_RGA2_SRC_ACT_INFO_SW_SRC_ACT_HEIGHT (0x1fff<<16)
|
||||
|
||||
#define s_RGA2_SRC_ACT_INFO_SW_SRC_ACT_WIDTH(x) ((x&0x1fff)<<0)
|
||||
#define s_RGA2_SRC_ACT_INFO_SW_SRC_ACT_HEIGHT(x) ((x&0x1fff)<<16)
|
||||
|
||||
|
||||
/* RGA_DST_INFO */
|
||||
#define m_RGA2_DST_INFO_SW_DST_FMT (0xf<<0)
|
||||
#define m_RGA2_DST_INFO_SW_DST_RB_SWAP (0x1<<4)
|
||||
#define m_RGA2_DST_INFO_SW_ALPHA_SWAP (0x1<<5)
|
||||
#define m_RGA2_DST_INFO_SW_DST_UV_SWAP (0x1<<6)
|
||||
#define m_RGA2_DST_INFO_SW_SRC1_FMT (0x7<<7)
|
||||
#define m_RGA2_DST_INFO_SW_SRC1_RB_SWP (0x1<<10)
|
||||
#define m_RGA2_DST_INFO_SW_SRC1_ALPHA_SWP (0x1<<11)
|
||||
#define m_RGA2_DST_INFO_SW_DITHER_UP_E (0x1<<12)
|
||||
#define m_RGA2_DST_INFO_SW_DITHER_DOWN_E (0x1<<13)
|
||||
#define m_RGA2_DST_INFO_SW_DITHER_MODE (0x3<<14)
|
||||
#define m_RGA2_DST_INFO_SW_DST_CSC_MODE (0x3<<16)
|
||||
#define m_RGA2_DST_INFO_SW_CSC_CLIP_MODE (0x1<<18)
|
||||
#define m_RGA2_DST_INFO_SW_DST_CSC_MODE_2 (0x1<<19)
|
||||
#define m_RGA2_DST_INFO_SW_DST_FMT_YUV400_EN (0x1<<24)
|
||||
#define m_RGA2_DST_INFO_SW_DST_FMT_Y4_EN (0x1<<25)
|
||||
#define m_RGA2_DST_INFO_SW_DST_NN_QUANTIZE_EN (0x1<<26)
|
||||
#define m_RGA2_DST_INFO_SW_SRC1_CSC_MODE (0x3<<20)
|
||||
#define m_RGA2_DST_INFO_SW_SRC1_CSC_CLIP_MODE (0x1<<22)
|
||||
|
||||
#define s_RGA2_DST_INFO_SW_DST_FMT(x) ((x&0xf)<<0)
|
||||
#define s_RGA2_DST_INFO_SW_DST_RB_SWAP(x) ((x&0x1)<<4)
|
||||
#define s_RGA2_DST_INFO_SW_ALPHA_SWAP(x) ((x&0x1)<<5)
|
||||
#define s_RGA2_DST_INFO_SW_DST_UV_SWAP(x) ((x&0x1)<<6)
|
||||
#define s_RGA2_DST_INFO_SW_SRC1_FMT(x) ((x&0x7)<<7)
|
||||
#define s_RGA2_DST_INFO_SW_SRC1_RB_SWP(x) ((x&0x1)<<10)
|
||||
#define s_RGA2_DST_INFO_SW_SRC1_ALPHA_SWP(x) ((x&0x1)<<11)
|
||||
#define s_RGA2_DST_INFO_SW_DITHER_UP_E(x) ((x&0x1)<<12)
|
||||
#define s_RGA2_DST_INFO_SW_DITHER_DOWN_E(x) ((x&0x1)<<13)
|
||||
#define s_RGA2_DST_INFO_SW_DITHER_MODE(x) ((x&0x3)<<14)
|
||||
#define s_RGA2_DST_INFO_SW_DST_CSC_MODE(x) ((x&0x3)<<16)
|
||||
#define s_RGA2_DST_INFO_SW_CSC_CLIP_MODE(x) ((x&0x1)<<18)
|
||||
#define s_RGA2_DST_INFO_SW_DST_CSC_MODE_2(x) ((x&0x1)<<19)
|
||||
#define s_RGA2_DST_INFO_SW_DST_FMT_YUV400_EN(x) ((x&0x1)<<24)
|
||||
#define s_RGA2_DST_INFO_SW_DST_FMT_Y4_EN(x) ((x&0x1)<<25)
|
||||
#define s_RGA2_DST_INFO_SW_DST_NN_QUANTIZE_EN(x) ((x&0x1)<<26)
|
||||
#define s_RGA2_DST_INFO_SW_SRC1_CSC_MODE(x) ((x&0x3)<<20)
|
||||
#define s_RGA2_DST_INFO_SW_SRC1_CSC_CLIP_MODE(x) ((x&0x1)<<22)
|
||||
|
||||
|
||||
/* RGA_ALPHA_CTRL0 */
|
||||
#define m_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_0 (0x1<<0)
|
||||
#define m_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_SEL (0x1<<1)
|
||||
#define m_RGA2_ALPHA_CTRL0_SW_ROP_MODE (0x3<<2)
|
||||
#define m_RGA2_ALPHA_CTRL0_SW_SRC_GLOBAL_ALPHA (0xff<<4)
|
||||
#define m_RGA2_ALPHA_CTRL0_SW_DST_GLOBAL_ALPHA (0xff<<12)
|
||||
#define m_RGA2_ALPHA_CTRLO_SW_MASK_ENDIAN (0x1<<20)
|
||||
|
||||
#define s_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_0(x) ((x&0x1)<<0)
|
||||
#define s_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_SEL(x) ((x&0x1)<<1)
|
||||
#define s_RGA2_ALPHA_CTRL0_SW_ROP_MODE(x) ((x&0x3)<<2)
|
||||
#define s_RGA2_ALPHA_CTRL0_SW_SRC_GLOBAL_ALPHA(x) ((x&0xff)<<4)
|
||||
#define s_RGA2_ALPHA_CTRL0_SW_DST_GLOBAL_ALPHA(x) ((x&0xff)<<12)
|
||||
#define s_RGA2_ALPHA_CTRLO_SW_MASK_ENDIAN(x) ((x&0x1)<<20)
|
||||
|
||||
|
||||
|
||||
/* RGA_ALPHA_CTRL1 */
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_COLOR_M0 (0x1<<0)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_COLOR_M0 (0x1<<1)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_FACTOR_M0 (0x7<<2)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_FACTOR_M0 (0x7<<5)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_CAL_M0 (0x1<<8)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_CAL_M0 (0x1<<9)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_BLEND_M0 (0x3<<10)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_BLEND_M0 (0x3<<12)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_M0 (0x1<<14)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_M0 (0x1<<15)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_FACTOR_M1 (0x7<<16)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_FACTOR_M1 (0x7<<19)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_CAL_M1 (0x1<<22)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_CAL_M1 (0x1<<23)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_BLEND_M1 (0x3<<24)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_BLEND_M1 (0x3<<26)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_M1 (0x1<<28)
|
||||
#define m_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_M1 (0x1<<29)
|
||||
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_COLOR_M0(x) ((x&0x1)<<0)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_COLOR_M0(x) ((x&0x1)<<1)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_FACTOR_M0(x) ((x&0x7)<<2)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_FACTOR_M0(x) ((x&0x7)<<5)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_CAL_M0(x) ((x&0x1)<<8)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_CAL_M0(x) ((x&0x1)<<9)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_BLEND_M0(x) ((x&0x3)<<10)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_BLEND_M0(x) ((x&0x3)<<12)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_M0(x) ((x&0x1)<<14)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_M0(x) ((x&0x1)<<15)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_FACTOR_M1(x) ((x&0x7)<<16)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_FACTOR_M1(x) ((x&0x7)<<19)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_CAL_M1(x) ((x&0x1)<<22)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_CAL_M1(x) ((x&0x1)<<23)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_BLEND_M1(x) ((x&0x3)<<24)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_BLEND_M1(x) ((x&0x3)<<26)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_DST_ALPHA_M1(x) ((x&0x1)<<28)
|
||||
#define s_RGA2_ALPHA_CTRL1_SW_SRC_ALPHA_M1(x) ((x&0x1)<<29)
|
||||
|
||||
|
||||
|
||||
/* RGA_MMU_CTRL1 */
|
||||
#define m_RGA2_MMU_CTRL1_SW_SRC_MMU_EN (0x1<<0)
|
||||
#define m_RGA2_MMU_CTRL1_SW_SRC_MMU_FLUSH (0x1<<1)
|
||||
#define m_RGA2_MMU_CTRL1_SW_SRC_MMU_PREFETCH_EN (0x1<<2)
|
||||
#define m_RGA2_MMU_CTRL1_SW_SRC_MMU_PREFETCH_DIR (0x1<<3)
|
||||
#define m_RGA2_MMU_CTRL1_SW_SRC1_MMU_EN (0x1<<4)
|
||||
#define m_RGA2_MMU_CTRL1_SW_SRC1_MMU_FLUSH (0x1<<5)
|
||||
#define m_RGA2_MMU_CTRL1_SW_SRC1_MMU_PREFETCH_EN (0x1<<6)
|
||||
#define m_RGA2_MMU_CTRL1_SW_SRC1_MMU_PREFETCH_DIR (0x1<<7)
|
||||
#define m_RGA2_MMU_CTRL1_SW_DST_MMU_EN (0x1<<8)
|
||||
#define m_RGA2_MMU_CTRL1_SW_DST_MMU_FLUSH (0x1<<9)
|
||||
#define m_RGA2_MMU_CTRL1_SW_DST_MMU_PREFETCH_EN (0x1<<10)
|
||||
#define m_RGA2_MMU_CTRL1_SW_DST_MMU_PREFETCH_DIR (0x1<<11)
|
||||
#define m_RGA2_MMU_CTRL1_SW_ELS_MMU_EN (0x1<<12)
|
||||
#define m_RGA2_MMU_CTRL1_SW_ELS_MMU_FLUSH (0x1<<13)
|
||||
|
||||
#define s_RGA2_MMU_CTRL1_SW_SRC_MMU_EN(x) ((x&0x1)<<0)
|
||||
#define s_RGA2_MMU_CTRL1_SW_SRC_MMU_FLUSH(x) ((x&0x1)<<1)
|
||||
#define s_RGA2_MMU_CTRL1_SW_SRC_MMU_PREFETCH_EN(x) ((x&0x1)<<2)
|
||||
#define s_RGA2_MMU_CTRL1_SW_SRC_MMU_PREFETCH_DIR(x) ((x&0x1)<<3)
|
||||
#define s_RGA2_MMU_CTRL1_SW_SRC1_MMU_EN(x) ((x&0x1)<<4)
|
||||
#define s_RGA2_MMU_CTRL1_SW_SRC1_MMU_FLUSH(x) ((x&0x1)<<5)
|
||||
#define s_RGA2_MMU_CTRL1_SW_SRC1_MMU_PREFETCH_EN(x) ((x&0x1)<<6)
|
||||
#define s_RGA2_MMU_CTRL1_SW_SRC1_MMU_PREFETCH_DIR(x) ((x&0x1)<<7)
|
||||
#define s_RGA2_MMU_CTRL1_SW_DST_MMU_EN(x) ((x&0x1)<<8)
|
||||
#define s_RGA2_MMU_CTRL1_SW_DST_MMU_FLUSH(x) ((x&0x1)<<9)
|
||||
#define s_RGA2_MMU_CTRL1_SW_DST_MMU_PREFETCH_EN(x) ((x&0x1)<<10)
|
||||
#define s_RGA2_MMU_CTRL1_SW_DST_MMU_PREFETCH_DIR(x) ((x&0x1)<<11)
|
||||
#define s_RGA2_MMU_CTRL1_SW_ELS_MMU_EN(x) ((x&0x1)<<12)
|
||||
#define s_RGA2_MMU_CTRL1_SW_ELS_MMU_FLUSH(x) ((x&0x1)<<13)
|
||||
|
||||
|
||||
#define RGA2_SYS_CTRL_OFFSET 0x0
|
||||
#define RGA2_CMD_CTRL_OFFSET 0x4
|
||||
#define RGA2_CMD_BASE_OFFSET 0x8
|
||||
#define RGA2_STATUS_OFFSET 0xc
|
||||
#define RGA2_INT_OFFSET 0x10
|
||||
#define RGA2_MMU_CTRL0_OFFSET 0x14
|
||||
#define RGA2_MMU_CMD_BASE_OFFSET 0x18
|
||||
|
||||
/* dst full csc */
|
||||
#define RGA2_DST_CSC_00_OFFSET 0x0
|
||||
#define RGA2_DST_CSC_01_OFFSET 0x4
|
||||
#define RGA2_DST_CSC_02_OFFSET 0x8
|
||||
#define RGA2_DST_CSC_OFF0_OFFSET 0xc
|
||||
#define RGA2_DST_CSC_10_OFFSET 0x10
|
||||
#define RGA2_DST_CSC_11_OFFSET 0x14
|
||||
#define RGA2_DST_CSC_12_OFFSET 0x18
|
||||
#define RGA2_DST_CSC_OFF1_OFFSET 0x1c
|
||||
#define RGA2_DST_CSC_20_OFFSET 0x20
|
||||
#define RGA2_DST_CSC_21_OFFSET 0x24
|
||||
#define RGA2_DST_CSC_22_OFFSET 0x28
|
||||
#define RGA2_DST_CSC_OFF2_OFFSET 0x2c
|
||||
|
||||
#define RGA2_MODE_CTRL_OFFSET 0x00
|
||||
#define RGA2_SRC_INFO_OFFSET 0x04
|
||||
#define RGA2_SRC_BASE0_OFFSET 0x08
|
||||
#define RGA2_SRC_BASE1_OFFSET 0x0c
|
||||
#define RGA2_SRC_BASE2_OFFSET 0x10
|
||||
#define RGA2_SRC_BASE3_OFFSET 0x14
|
||||
#define RGA2_SRC_VIR_INFO_OFFSET 0x18
|
||||
#define RGA2_SRC_ACT_INFO_OFFSET 0x1c
|
||||
#define RGA2_SRC_X_FACTOR_OFFSET 0x20
|
||||
#define RGA2_SRC_Y_FACTOR_OFFSET 0x24
|
||||
#define RGA2_SRC_BG_COLOR_OFFSET 0x28
|
||||
#define RGA2_SRC_FG_COLOR_OFFSET 0x2c
|
||||
#define RGA2_SRC_TR_COLOR0_OFFSET 0x30
|
||||
#define RGA2_CF_GR_A_OFFSET 0x30 // repeat
|
||||
#define RGA2_SRC_TR_COLOR1_OFFSET 0x34
|
||||
#define RGA2_CF_GR_B_OFFSET 0x34 // repeat
|
||||
#define RGA2_DST_INFO_OFFSET 0x38
|
||||
#define RGA2_DST_BASE0_OFFSET 0x3c
|
||||
#define RGA2_DST_BASE1_OFFSET 0x40
|
||||
#define RGA2_DST_BASE2_OFFSET 0x44
|
||||
#define RGA2_DST_VIR_INFO_OFFSET 0x48
|
||||
#define RGA2_DST_ACT_INFO_OFFSET 0x4c
|
||||
#define RGA2_ALPHA_CTRL0_OFFSET 0x50
|
||||
#define RGA2_ALPHA_CTRL1_OFFSET 0x54
|
||||
#define RGA2_FADING_CTRL_OFFSET 0x58
|
||||
#define RGA2_PAT_CON_OFFSET 0x5c
|
||||
#define RGA2_ROP_CTRL0_OFFSET 0x60
|
||||
#define RGA2_CF_GR_G_OFFSET 0x60 // repeat
|
||||
#define RGA2_DST_Y4MAP_LUT0_OFFSET 0x60 // repeat
|
||||
#define RGA2_DST_QUANTIZE_SCALE_OFFSET 0x60 // repeat
|
||||
#define RGA2_ROP_CTRL1_OFFSET 0x64
|
||||
#define RGA2_CF_GR_R_OFFSET 0x64 // repeat
|
||||
#define RGA2_DST_Y4MAP_LUT1_OFFSET 0x64 // repeat
|
||||
#define RGA2_DST_QUANTIZE_OFFSET_OFFSET 0x64 // repeat
|
||||
#define RGA2_MASK_BASE_OFFSET 0x68
|
||||
#define RGA2_MMU_CTRL1_OFFSET 0x6c
|
||||
#define RGA2_MMU_SRC_BASE_OFFSET 0x70
|
||||
#define RGA2_MMU_SRC1_BASE_OFFSET 0x74
|
||||
#define RGA2_MMU_DST_BASE_OFFSET 0x78
|
||||
#define RGA2_MMU_ELS_BASE_OFFSET 0x7c
|
||||
|
||||
int rga2_gen_reg_info(unsigned char *base,
|
||||
unsigned char *csc_base, struct rga2_req *msg);
|
||||
|
||||
void rga_cmd_to_rga2_cmd(struct rga_req *req_rga, struct rga2_req *req);
|
||||
|
||||
void rga2_soft_reset(struct rga_scheduler_t *scheduler);
|
||||
int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler);
|
||||
int rga2_init_reg(struct rga_job *job);
|
||||
int rga2_get_version(struct rga_scheduler_t *scheduler);
|
||||
|
||||
#endif
|
||||
|
||||
450
drivers/video/rockchip/rga3/include/rga3_reg_info.h
Normal file
450
drivers/video/rockchip/rga3/include/rga3_reg_info.h
Normal file
@@ -0,0 +1,450 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __REG3_INFO_H__
|
||||
#define __REG3_INFO_H__
|
||||
|
||||
#include "rga_drv.h"
|
||||
|
||||
//General Registers
|
||||
/* yqw: status和int寄存器尚不明了,无法进行修改。 */
|
||||
//#define RGA2_STATUS 0x00c
|
||||
//#define RGA2_INT 0x010
|
||||
|
||||
#define RGA3_SYS_CTRL 0x000
|
||||
#define RGA3_CMD_CTRL 0x004
|
||||
#define RGA3_CMD_ADDR 0x008
|
||||
#define RGA3_MI_GROUP_CTRL 0x00c
|
||||
#define RGA3_ARQOS_CTRL 0x010
|
||||
#define RGA3_VERSION_NUM 0x018
|
||||
#define RGA3_VERSION_TIM 0x01c
|
||||
#define RGA3_INT_EN 0x020
|
||||
#define RGA3_INT_RAW 0x024
|
||||
#define RGA3_INT_MSK 0x028
|
||||
#define RGA3_INT_CLR 0x02c
|
||||
#define RGA3_RO_SRST 0x030
|
||||
#define RGA3_STATUS0 0x034
|
||||
#define RGA3_SCAN_CNT 0x038
|
||||
#define RGA3_STATUS1 0x03c
|
||||
#define RGA3_CMD_STATE 0x040
|
||||
|
||||
/* TODO: RGA_INT */
|
||||
|
||||
/* RGA3_WIN0_RD_CTRL */
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_ENABLE (0x1 << 0)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_MODE (0x3 << 1)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_PIC_FORMAT (0xf << 4)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_FORMAT (0x3 << 8)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_YUV10B_COMPACT (0x1 << 10)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_ENDIAN_MODE (0x1 << 11)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_PIX_SWAP (0x1 << 12)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_YC_SWAP (0x1 << 13)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_ROT (0x1 << 16)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_XMIRROR (0x1 << 17)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_YMIRROR (0x1 << 18)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_HOR_BY (0x1 << 20)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_HOR_UP (0x1 << 21)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_VER_BY (0x1 << 22)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_VER_UP (0x1 << 23)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_Y2R_EN (0x1 << 24)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_R2Y_EN (0x1 << 25)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE (0x3 << 26)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_PERF_OPT_DIS (0x1 << 29)
|
||||
#define m_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_ALIGN_DIS (0x1 << 30)
|
||||
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_ENABLE(x) ((x & 0x1) << 0)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_MODE(x) ((x & 0x3) << 1)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_PIC_FORMAT(x) ((x & 0xf) << 4)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_FORMAT(x) ((x & 0x3) << 8)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_YUV10B_COMPACT(x) ((x & 0x1) << 10)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_ENDIAN_MODE(x) ((x & 0x1) << 11)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_PIX_SWAP(x) ((x & 0x1) << 12)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_YC_SWAP(x) ((x & 0x1) << 13)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_ROT(x) ((x & 0x1) << 16)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_XMIRROR(x) ((x & 0x1) << 17)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_YMIRROR(x) ((x & 0x1) << 18)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_HOR_BY(x) ((x & 0x1) << 20)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_HOR_UP(x) ((x & 0x1) << 21)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_VER_BY(x) ((x & 0x1) << 22)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_VER_UP(x) ((x & 0x1) << 23)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_Y2R_EN(x) ((x & 0x1) << 24)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_R2Y_EN(x) ((x & 0x1) << 25)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_CSC_MODE(x) ((x & 0x3) << 26)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_PERF_OPT_DIS(x) ((x & 0x1) << 29)
|
||||
#define s_RGA3_WIN0_RD_CTRL_SW_WIN0_RD_ALIGN_DIS(x) ((x & 0x1) << 30)
|
||||
|
||||
/* RGA3_WIN0_FBC_OFF */
|
||||
#define m_RGA3_WIN0_FBC_OFF_SW_WIN0_FBC_XOFF (0x1fff << 0)
|
||||
#define m_RGA3_WIN0_FBC_OFF_SW_WIN0_FBC_YOFF (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN0_FBC_OFF_SW_WIN0_FBC_XOFF(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN0_FBC_OFF_SW_WIN0_FBC_YOFF(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN0_SRC_SIZE */
|
||||
#define m_RGA3_WIN0_SRC_SIZE_SW_WIN0_SRC_WIDTH (0x1fff << 0)
|
||||
#define m_RGA3_WIN0_SRC_SIZE_SW_WIN0_SRC_HEIGHT (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN0_SRC_OFF_SW_WIN0_SRC_WIDTH(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN0_SRC_OFF_SW_WIN0_SRC_HEIGHT(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN0_ACT_OFF */
|
||||
#define m_RGA3_WIN0_ACT_OFF_SW_WIN0_ACT_XOFF (0x1fff << 0)
|
||||
#define m_RGA3_WIN0_ACT_OFF_SW_WIN0_ACT_YOFF (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN0_ACT_OFF_SW_WIN0_ACT_XOFF(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN0_ACT_OFF_SW_WIN0_ACT_YOFF(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN0_ACT_SIZE */
|
||||
#define m_RGA3_WIN0_ACT_SIZE_SW_WIN0_ACT_WIDTH (0x1fff << 0)
|
||||
#define m_RGA3_WIN0_ACT_SIZE_SW_WIN0_ACT_HEIGHT (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN0_ACT_SIZE_SW_WIN0_ACT_WIDTH(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN0_ACT_SIZE_SW_WIN0_ACT_HEIGHT(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN0_DST_SIZE */
|
||||
#define m_RGA3_WIN0_DST_SIZE_SW_WIN0_DST_WIDTH (0x1fff << 0)
|
||||
#define m_RGA3_WIN0_DST_SIZE_SW_WIN0_DST_HEIGHT (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN0_DST_SIZE_SW_WIN0_DST_WIDTH(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN0_DST_SIZE_SW_WIN0_DST_HEIGHT(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN0_SCL_FAC */
|
||||
#define m_RGA3_WIN0_SCL_FAC_SW_WIN0_VER_FAC (0xffff << 0)
|
||||
#define m_RGA3_WIN0_SCL_FAC_SW_WIN0_HOR_FAC (0xffff << 16)
|
||||
|
||||
#define s_RGA3_WIN0_SCL_FAC_SW_WIN0_VER_FAC(x) ((x & 0xffff) << 0)
|
||||
#define s_RGA3_WIN0_SCL_FAC_SW_WIN0_HOR_FAC(x) ((x & 0xffff) << 16)
|
||||
|
||||
/* RGA3_WIN1_RD_CTRL */
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_ENABLE (0x1 << 0)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_MODE (0x3 << 1)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_PIC_FORMAT (0xf << 4)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_FORMAT (0x3 << 8)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_YUV10B_COMPACT (0x1 << 10)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_ENDIAN_MODE (0x1 << 11)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_PIX_SWAP (0x1 << 12)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_YC_SWAP (0x1 << 13)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_ROT (0x1 << 16)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_XMIRROR (0x1 << 17)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_YMIRROR (0x1 << 18)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_HOR_BY (0x1 << 20)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_HOR_UP (0x1 << 21)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_VER_BY (0x1 << 22)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_VER_UP (0x1 << 23)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_Y2R_EN (0x1 << 24)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_R2Y_EN (0x1 << 25)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_CSC_MODE (0x3 << 26)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_PERF_OPT_DIS (0x1 << 29)
|
||||
#define m_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_ALIGN_DIS (0x1 << 30)
|
||||
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_ENABLE(x) ((x & 0x1) << 0)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_MODE(x) ((x & 0x3) << 1)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_PIC_FORMAT(x) ((x & 0xf) << 4)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_FORMAT(x) ((x & 0x3) << 8)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_YUV10B_COMPACT(x) ((x & 0x1) << 10)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_ENDIAN_MODE(x) ((x & 0x1) << 11)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_PIX_SWAP(x) ((x & 0x1) << 12)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_YC_SWAP(x) ((x & 0x1) << 13)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_ROT(x) ((x & 0x1) << 16)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_XMIRROR(x) ((x & 0x1) << 17)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_YMIRROR(x) ((x & 0x1) << 18)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_HOR_BY(x) ((x & 0x1) << 20)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_HOR_UP(x) ((x & 0x1) << 21)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_VER_BY(x) ((x & 0x1) << 22)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_VER_UP(x) ((x & 0x1) << 23)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_Y2R_EN(x) ((x & 0x1) << 24)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_R2Y_EN(x) ((x & 0x1) << 25)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_CSC_MODE(x) ((x & 0x3) << 26)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_PERF_OPT_DIS(x) ((x & 0x1) << 29)
|
||||
#define s_RGA3_WIN1_RD_CTRL_SW_WIN1_RD_ALIGN_DIS(x) ((x & 0x1) << 30)
|
||||
|
||||
/* RGA3_WIN1_FBC_OFF */
|
||||
#define m_RGA3_WIN1_FBC_OFF_SW_WIN1_FBC_XOFF (0x1fff << 0)
|
||||
#define m_RGA3_WIN1_FBC_OFF_SW_WIN1_FBC_YOFF (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN1_FBC_OFF_SW_WIN1_FBC_XOFF(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN1_FBC_OFF_SW_WIN1_FBC_YOFF(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN1_SRC_SIZE */
|
||||
#define m_RGA3_WIN1_SRC_SIZE_SW_WIN1_SRC_WIDTH (0x1fff << 0)
|
||||
#define m_RGA3_WIN1_SRC_SIZE_SW_WIN1_SRC_HEIGHT (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN1_SRC_OFF_SW_WIN1_SRC_WIDTH(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN1_SRC_OFF_SW_WIN1_SRC_HEIGHT(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN1_ACT_OFF */
|
||||
#define m_RGA3_WIN1_ACT_OFF_SW_WIN1_ACT_XOFF (0x1fff << 0)
|
||||
#define m_RGA3_WIN1_ACT_OFF_SW_WIN1_ACT_YOFF (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN1_ACT_OFF_SW_WIN1_ACT_XOFF(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN1_ACT_OFF_SW_WIN1_ACT_YOFF(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN1_ACT_SIZE */
|
||||
#define m_RGA3_WIN1_ACT_SIZE_SW_WIN1_ACT_WIDTH (0x1fff << 0)
|
||||
#define m_RGA3_WIN1_ACT_SIZE_SW_WIN1_ACT_HEIGHT (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN1_ACT_SIZE_SW_WIN1_ACT_WIDTH(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN1_ACT_SIZE_SW_WIN1_ACT_HEIGHT(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN1_DST_SIZE */
|
||||
#define m_RGA3_WIN1_DST_SIZE_SW_WIN1_DST_WIDTH (0x1fff << 0)
|
||||
#define m_RGA3_WIN1_DST_SIZE_SW_WIN1_DST_HEIGHT (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_WIN1_DST_SIZE_SW_WIN1_DST_WIDTH(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_WIN1_DST_SIZE_SW_WIN1_DST_HEIGHT(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_WIN1_SCL_FAC */
|
||||
#define m_RGA3_WIN1_SCL_FAC_SW_WIN1_VER_FAC (0xffff << 0)
|
||||
#define m_RGA3_WIN1_SCL_FAC_SW_WIN1_HOR_FAC (0xffff << 16)
|
||||
|
||||
#define s_RGA3_WIN1_SCL_FAC_SW_WIN1_VER_FAC(x) ((x & 0xffff) << 0)
|
||||
#define s_RGA3_WIN1_SCL_FAC_SW_WIN1_HOR_FAC(x) ((x & 0xffff) << 16)
|
||||
|
||||
/* RGA3_OVLP_CTRL */
|
||||
#define m_RGA3_OVLP_CTRL_SW_OVLP_MODE (0x3 << 0)
|
||||
#define m_RGA3_OVLP_CTRL_SW_OVLP_FIELD (0x1 << 2)
|
||||
#define m_RGA3_OVLP_CTRL_SW_TOP_SWAP (0x1 << 3)
|
||||
#define m_RGA3_OVLP_CTRL_SW_TOP_ALPHA_EN (0x1 << 4)
|
||||
#define m_RGA3_OVLP_CTRL_SW_TOP_KEY_EN (0x7FFF << 5)
|
||||
#define m_RGA3_OVLP_CTRL_SW_OVLP_Y2R_EN (0x1 << 20)
|
||||
#define m_RGA3_OVLP_CTRL_SW_OVLP_R2Y_EN (0x1 << 21)
|
||||
#define m_RGA3_OVLP_CTRL_SW_OVLP_CSC_MODE (0x3 << 22)
|
||||
|
||||
#define s_RGA3_OVLP_CTRL_SW_OVLP_MODE(x) ((x & 0x3) << 0)
|
||||
#define s_RGA3_OVLP_CTRL_SW_OVLP_FIELD(x) ((x & 0x1) << 2)
|
||||
#define s_RGA3_OVLP_CTRL_SW_TOP_SWAP(x) ((x & 0x1) << 3)
|
||||
#define s_RGA3_OVLP_CTRL_SW_TOP_ALPHA_EN(x) ((x & 0x1) << 4)
|
||||
#define s_RGA3_OVLP_CTRL_SW_TOP_KEY_EN(x) ((x & 0x7FFF) << 5)
|
||||
#define s_RGA3_OVLP_CTRL_SW_OVLP_Y2R_EN(x) ((x & 0x1) << 20)
|
||||
#define s_RGA3_OVLP_CTRL_SW_OVLP_R2Y_EN(x) ((x & 0x1) << 21)
|
||||
#define s_RGA3_OVLP_CTRL_SW_OVLP_CSC_MODE(x) ((x & 0x3) << 22)
|
||||
|
||||
/* RGA3_OVLP_OFF */
|
||||
#define m_RGA3_OVLP_OFF_SW_OVLP_XOFF (0x1fff << 0)
|
||||
#define m_RGA3_OVLP_OFF_SW_OVLP_YOFF (0x1fff << 16)
|
||||
|
||||
#define s_RGA3_OVLP_OFF_SW_OVLP_XOFF(x) ((x & 0x1fff) << 0)
|
||||
#define s_RGA3_OVLP_OFF_SW_OVLP_YOFF(x) ((x & 0x1fff) << 16)
|
||||
|
||||
/* RGA3_OVLP_TOP_KEY_MIN */
|
||||
#define m_RGA3_OVLP_TOP_KEY_MIN_SW_TOP_KEY_YG_MIN (0x3ff << 0)
|
||||
#define m_RGA3_OVLP_TOP_KEY_MIN_SW_TOP_KEY_UB_MIN (0x3ff << 10)
|
||||
#define m_RGA3_OVLP_TOP_KEY_MIN_SW_TOP_KEY_VR_MIN (0x3ff << 20)
|
||||
|
||||
#define s_RGA3_OVLP_TOP_KEY_MIN_SW_TOP_KEY_YG_MIN(x) ((x & 0x3f)f << 0)
|
||||
#define s_RGA3_OVLP_TOP_KEY_MIN_SW_TOP_KEY_UB_MIN(x) ((x & 0x3ff) << 10)
|
||||
#define s_RGA3_OVLP_TOP_KEY_MIN_SW_TOP_KEY_VR_MIN(x) ((x & 0x3ff) << 20)
|
||||
|
||||
/* RGA3_OVLP_TOP_KEY_MAX */
|
||||
#define m_RGA3_OVLP_TOP_KEY_MAX_SW_TOP_KEY_YG_MAX (0x3ff << 0)
|
||||
#define m_RGA3_OVLP_TOP_KEY_MAX_SW_TOP_KEY_UB_MAX (0x3ff << 10)
|
||||
#define m_RGA3_OVLP_TOP_KEY_MAX_SW_TOP_KEY_VR_MAX (0x3ff << 20)
|
||||
|
||||
#define s_RGA3_OVLP_TOP_KEY_MAX_SW_TOP_KEY_YG_MAX(x) ((x & 0x3ff) << 0)
|
||||
#define s_RGA3_OVLP_TOP_KEY_MAX_SW_TOP_KEY_UB_MAX(x) ((x & 0x3ff) << 10)
|
||||
#define s_RGA3_OVLP_TOP_KEY_MAX_SW_TOP_KEY_VR_MAX(x) ((x & 0x3ff) << 20)
|
||||
|
||||
/* RGA3_OVLP_TOP_CTRL */
|
||||
#define m_RGA3_OVLP_TOP_CTRL_SW_TOP_COLOR_M0 (0x1 << 0)
|
||||
#define m_RGA3_OVLP_TOP_CTRL_SW_TOP_ALPHA_M0 (0x1 << 1)
|
||||
#define m_RGA3_OVLP_TOP_CTRL_SW_TOP_BLEND_M0 (0x3 << 2)
|
||||
#define m_RGA3_OVLP_TOP_CTRL_SW_TOP_ALPHA_CAL_M0 (0x1 << 4)
|
||||
#define m_RGA3_OVLP_TOP_CTRL_SW_TOP_FACTOR_M0 (0x7 << 5)
|
||||
#define m_RGA3_OVLP_TOP_CTRL_SW_TOP_GLOBAL_ALPHA (0xff << 16)
|
||||
|
||||
#define s_RGA3_OVLP_TOP_CTRL_SW_TOP_COLOR_M0(x) ((x & 0x1) << 0)
|
||||
#define s_RGA3_OVLP_TOP_CTRL_SW_TOP_ALPHA_M0(x) ((x & 0x1) << 1)
|
||||
#define s_RGA3_OVLP_TOP_CTRL_SW_TOP_BLEND_M0(x) ((x & 0x3) << 2)
|
||||
#define s_RGA3_OVLP_TOP_CTRL_SW_TOP_ALPHA_CAL_M0(x) ((x & 0x1) << 4)
|
||||
#define s_RGA3_OVLP_TOP_CTRL_SW_TOP_FACTOR_M0(x) ((x & 0x7) << 5)
|
||||
#define s_RGA3_OVLP_TOP_CTRL_SW_TOP_GLOBAL_ALPHA(x) ((x & 0xff) << 16)
|
||||
|
||||
/* RGA3_OVLP_BOT_CTRL */
|
||||
#define m_RGA3_OVLP_BOT_CTRL_SW_BOT_COLOR_M0 (0x1 << 0)
|
||||
#define m_RGA3_OVLP_BOT_CTRL_SW_BOT_ALPHA_M0 (0x1 << 1)
|
||||
#define m_RGA3_OVLP_BOT_CTRL_SW_BOT_BLEND_M0 (0x3 << 2)
|
||||
#define m_RGA3_OVLP_BOT_CTRL_SW_BOT_ALPHA_CAL_M0 (0x1 << 4)
|
||||
#define m_RGA3_OVLP_BOT_CTRL_SW_BOT_FACTOR_M0 (0x7 << 5)
|
||||
#define m_RGA3_OVLP_BOT_CTRL_SW_BOT_GLOBAL_ALPHA (0xff << 16)
|
||||
|
||||
#define s_RGA3_OVLP_BOT_CTRL_SW_BOT_COLOR_M0(x) ((x & 0x1) << 0)
|
||||
#define s_RGA3_OVLP_BOT_CTRL_SW_BOT_ALPHA_M0(x) ((x & 0x1) << 1)
|
||||
#define s_RGA3_OVLP_BOT_CTRL_SW_BOT_BLEND_M0(x) ((x & 0x3) << 2)
|
||||
#define s_RGA3_OVLP_BOT_CTRL_SW_BOT_ALPHA_CAL_M0(x) ((x & 0x1) << 4)
|
||||
#define s_RGA3_OVLP_BOT_CTRL_SW_BOT_FACTOR_M0(x) ((x & 0x7) << 5)
|
||||
#define s_RGA3_OVLP_BOT_CTRL_SW_BOT_GLOBAL_ALPHA(x) ((x & 0xff) << 16)
|
||||
|
||||
/* RGA3_OVLP_TOP_ALPHA */
|
||||
#define m_RGA3_OVLP_TOP_ALPHA_SW_TOP_ALPHA_M1 (0x1 << 1)
|
||||
#define m_RGA3_OVLP_TOP_ALPHA_SW_TOP_BLEND_M1 (0x3 << 2)
|
||||
#define m_RGA3_OVLP_TOP_ALPHA_SW_TOP_ALPHA_CAL_M1 (0x1 << 4)
|
||||
#define m_RGA3_OVLP_TOP_ALPHA_SW_TOP_FACTOR_M1 (0x7 << 5)
|
||||
|
||||
#define s_RGA3_OVLP_TOP_ALPHA_SW_TOP_ALPHA_M1(x) ((x & 0x1) << 1)
|
||||
#define s_RGA3_OVLP_TOP_ALPHA_SW_TOP_BLEND_M1(x) ((x & 0x3) << 2)
|
||||
#define s_RGA3_OVLP_TOP_ALPHA_SW_TOP_ALPHA_CAL_M1(x) ((x & 0x1) << 4)
|
||||
#define s_RGA3_OVLP_TOP_ALPHA_SW_TOP_FACTOR_M1(x) ((x & 0x7) << 5)
|
||||
|
||||
/* RGA3_OVLP_BOT_ALPHA */
|
||||
#define m_RGA3_OVLP_BOT_ALPHA_SW_BOT_ALPHA_M1 (0x1 << 1)
|
||||
#define m_RGA3_OVLP_BOT_ALPHA_SW_BOT_BLEND_M1 (0x3 << 2)
|
||||
#define m_RGA3_OVLP_BOT_ALPHA_SW_BOT_ALPHA_CAL_M1 (0x1 << 4)
|
||||
#define m_RGA3_OVLP_BOT_ALPHA_SW_BOT_FACTOR_M1 (0x7 << 5)
|
||||
|
||||
#define s_RGA3_OVLP_BOT_ALPHA_SW_BOT_ALPHA_M1(x) ((x & 0x1) << 1)
|
||||
#define s_RGA3_OVLP_BOT_ALPHA_SW_BOT_BLEND_M1(x) ((x & 0x3) << 2)
|
||||
#define s_RGA3_OVLP_BOT_ALPHA_SW_BOT_ALPHA_CAL_M1(x) ((x & 0x1) << 4)
|
||||
#define s_RGA3_OVLP_BOT_ALPHA_SW_BOT_FACTOR_M1(x) ((x & 0x7) << 5)
|
||||
|
||||
/* RGA3_WR_CTRL */
|
||||
#define m_RGA3_WR_CTRL_SW_WR_MODE (0x3 << 0)
|
||||
#define m_RGA3_WR_CTRL_SW_WR_FBCE_SPARSE_EN (0x1 << 2)
|
||||
#define m_RGA3_WR_CTRL_SW_WR_PIC_FORMAT (0xf << 4)
|
||||
#define m_RGA3_WR_CTRL_SW_WR_FORMAT (0x3 << 8)
|
||||
#define m_RGA3_WR_CTRL_SW_WR_YUV10B_COMPACT (0x1 << 10)
|
||||
#define m_RGA3_WR_CTRL_SW_WR_ENDIAN_MODE (0x1 << 11)
|
||||
#define m_RGA3_WR_CTRL_SW_WR_PIX_SWAP (0x1 << 12)
|
||||
#define m_RGA3_WR_CTRL_SW_OUTSTANDING_MAX (0x3f << 13)
|
||||
#define m_RGA3_WR_CTRL_SW_WR_YC_SWAP (0x1 << 20)
|
||||
|
||||
#define s_RGA3_WR_CTRL_SW_WR_MODE(x) ((x & 0x3) << 0)
|
||||
#define s_RGA3_WR_CTRL_SW_WR_FBCE_SPARSE_EN(x) ((x & 0x1) << 2)
|
||||
#define s_RGA3_WR_CTRL_SW_WR_PIC_FORMAT(x) ((x & 0xf) << 4)
|
||||
#define s_RGA3_WR_CTRL_SW_WR_FORMAT(x) ((x & 0x3) << 8)
|
||||
#define s_RGA3_WR_CTRL_SW_WR_YUV10B_COMPACT(x) ((x & 0x1) << 10)
|
||||
#define s_RGA3_WR_CTRL_SW_WR_ENDIAN_MODE(x) ((x & 0x1) << 11)
|
||||
#define s_RGA3_WR_CTRL_SW_WR_PIX_SWAP(x) ((x & 0x1) << 12)
|
||||
#define s_RGA3_WR_CTRL_SW_OUTSTANDING_MAX(x) ((x & 0x3f) << 13)
|
||||
#define s_RGA3_WR_CTRL_SW_WR_YC_SWAP(x) ((x & 0x1) << 20)
|
||||
|
||||
/* RGA3_WR_FBCE_CTRL */
|
||||
#define m_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_BLKBD_OPT_DIS (0x1 << 0)
|
||||
#define m_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_HOFF_DISS (0x1 << 1)
|
||||
#define m_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_PL_FIFO0_WATERMARK (0x3f << 2)
|
||||
#define m_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_PL_FIFO1_WATERMARK (0x3f << 8)
|
||||
#define m_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_SIZE_ALIGN_DIS (0x1 << 31)
|
||||
|
||||
#define s_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_BLKBD_OPT_DIS(x) ((x & 0x1) << 0)
|
||||
#define s_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_HOFF_DISS(x) ((x & 0x1) << 1)
|
||||
#define s_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_PL_FIFO0_WATERMARK(x) ((x & 0x3f) << 2)
|
||||
#define s_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_PL_FIFO1_WATERMARK(x) ((x & 0x3f) << 8)
|
||||
#define s_RGA3_WR_FBCE_CTRL_SW_WR_FBCE_SIZE_ALIGN_DIS(x) ((x & 0x1) << 31)
|
||||
|
||||
/* RGA3_MMU_STATUS read_only */
|
||||
#define m_RGA3_MMU_STATUS_PAGING_ENABLED (0x1 << 0)
|
||||
#define m_RGA3_MMU_STATUS_PAGE_FAULT_ACTIVE (0x1 << 1)
|
||||
#define m_RGA3_MMU_STATUS_STAIL_ACTIVE (0x1 << 2)
|
||||
#define m_RGA3_MMU_STATUS_MMU_IDLE (0x1 << 3)
|
||||
#define m_RGA3_MMU_STATUS_REPLAY_BUFFER_EMPTY (0x1 << 4)
|
||||
#define m_RGA3_MMU_STATUS_PAGE_FAULT_IS_WRITE (0x1 << 5)
|
||||
#define m_RGA3_MMU_STATUS_PAGE_FAULT_BUS_ID (0x1f << 6)
|
||||
|
||||
/* RGA3_MMU_INT_RAWSTAT read_only */
|
||||
#define m_RGA3_MMU_INT_RAWSTAT_READ_BUS_ERROR (0x1 << 0)
|
||||
#define m_RGA3_MMU_INT_RAWSTAT_PAGE_FAULT (0x1 << 1)
|
||||
|
||||
/* RGA3_MMU_INT_CLEAR write_only */
|
||||
#define m_RGA3_MMU_INT_CLEAR_READ_BUS_ERROR (0x1 << 0)
|
||||
#define m_RGA3_MMU_INT_CLEAR_PAGE_FAULT (0x1 << 1)
|
||||
|
||||
#define s_RGA3_MMU_INT_CLEAR_READ_BUS_ERROR(x) ((x & 0x1) << 0)
|
||||
#define s_RGA3_MMU_INT_CLEAR_PAGE_FAULT(x) ((x & 0x1) << 1)
|
||||
|
||||
/* RGA3_MMU_INT_MASK */
|
||||
#define m_RGA3_MMU_INT_MASK_READ_BUS_ERROR (0x1 << 0)
|
||||
#define m_RGA3_MMU_INT_MASK_PAGE_FAULT (0x1 << 1)
|
||||
|
||||
#define s_RGA3_MMU_INT_MASK_READ_BUS_ERROR(x) ((x & 0x1) << 0)
|
||||
#define s_RGA3_MMU_INT_MASK_PAGE_FAULT(x) ((x & 0x1) << 1)
|
||||
|
||||
/* RGA3_MMU_INT_STATUS read_only */
|
||||
#define m_RGA3_MMU_INT_STATUS_READ_BUS_ERROR (0x1 << 0)
|
||||
#define m_RGA3_MMU_INT_STATUS_PAGE_FAULT (0x1 << 1)
|
||||
|
||||
/* RGA3_MMU_AUTO_GATING */
|
||||
#define m_RGA3_MMU_AUTO_GATING_MMU_AUTO_GATING (0x1 << 1)
|
||||
#define m_RGA3_MMU_AUTO_GATING_MMU_CFG_MODE (0x1 << 1)
|
||||
#define m_RGA3_MMU_AUTO_GATING_MMU_BUG_FIXED_DISABLE (0x1 << 31)
|
||||
|
||||
#define s_RGA3_MMU_AUTO_GATING_MMU_AUTO_GATING(x) ((x & 0x1) << 1)
|
||||
#define s_RGA3_MMU_AUTO_GATING_MMU_BUG_FIXED_DISABLE(x) ((x & 0x1) << 31)
|
||||
|
||||
/* sys_reg */
|
||||
#define RGA3_SYS_CTRL_OFFSET 0x000
|
||||
#define RGA3_CMD_CTRL_OFFSET 0x004
|
||||
#define RGA3_CMD_ADDR_OFFSET 0x008
|
||||
#define RGA3_MI_GROUP_CTRL_OFFSET 0x00c
|
||||
#define RGA3_ARQOS_CTRL_OFFSET 0x010
|
||||
#define RGA3_VERSION_NUM_OFFSET 0x018
|
||||
#define RGA3_VERSION_TIM_OFFSET 0x01c
|
||||
#define RGA3_INT_EN_OFFSET 0x020
|
||||
#define RGA3_INT_RAW_OFFSET 0x024
|
||||
#define RGA3_INT_MSK_OFFSET 0x028
|
||||
#define RGA3_INT_CLR_OFFSET 0x02c
|
||||
#define RGA3_RO_SRST_OFFSET 0x030
|
||||
#define RGA3_STATUS0_OFFSET 0x034
|
||||
#define RGA3_SCAN_CNT_OFFSET 0x038
|
||||
#define RGA3_STATUS1_OFFSET 0x03c
|
||||
#define RGA3_CMD_STATE_OFFSET 0x040
|
||||
|
||||
/* op_reg */
|
||||
#define RGA3_WIN0_RD_CTRL_OFFSET 0x000
|
||||
#define RGA3_WIN0_Y_BASE_OFFSET 0x010
|
||||
#define RGA3_WIN0_U_BASE_OFFSET 0x014
|
||||
#define RGA3_WIN0_V_BASE_OFFSET 0x018
|
||||
#define RGA3_WIN0_VIR_STRIDE_OFFSET 0x01c
|
||||
#define RGA3_WIN0_FBC_OFF_OFFSET 0x020
|
||||
#define RGA3_WIN0_SRC_SIZE_OFFSET 0x024
|
||||
#define RGA3_WIN0_ACT_OFF_OFFSET 0x028
|
||||
#define RGA3_WIN0_ACT_SIZE_OFFSET 0x02c
|
||||
#define RGA3_WIN0_DST_SIZE_OFFSET 0x030
|
||||
#define RGA3_WIN0_SCL_FAC_OFFSET 0x034
|
||||
#define RGA3_WIN0_UV_VIR_STRIDE_OFFSET 0x038
|
||||
#define RGA3_WIN1_RD_CTRL_OFFSET 0x040
|
||||
#define RGA3_WIN1_Y_BASE_OFFSET 0x050
|
||||
#define RGA3_WIN1_U_BASE_OFFSET 0x054
|
||||
#define RGA3_WIN1_V_BASE_OFFSET 0x058
|
||||
#define RGA3_WIN1_VIR_STRIDE_OFFSET 0x05c
|
||||
#define RGA3_WIN1_FBC_OFF_OFFSET 0x060
|
||||
#define RGA3_WIN1_SRC_SIZE_OFFSET 0x064
|
||||
#define RGA3_WIN1_ACT_OFF_OFFSET 0x068
|
||||
#define RGA3_WIN1_ACT_SIZE_OFFSET 0x06c
|
||||
#define RGA3_WIN1_DST_SIZE_OFFSET 0x070
|
||||
#define RGA3_WIN1_SCL_FAC_OFFSET 0x074
|
||||
#define RGA3_WIN1_UV_VIR_STRIDE_OFFSET 0x078
|
||||
#define RGA3_OVLP_CTRL_OFFSET 0x080
|
||||
#define RGA3_OVLP_OFF_OFFSET 0x084
|
||||
#define RGA3_OVLP_TOP_KEY_MIN_OFFSET 0x088
|
||||
#define RGA3_OVLP_TOP_KEY_MAX_OFFSET 0x08c
|
||||
#define RGA3_OVLP_TOP_CTRL_OFFSET 0x090
|
||||
#define RGA3_OVLP_BOT_CTRL_OFFSET 0x094
|
||||
#define RGA3_OVLP_TOP_ALPHA_OFFSET 0x098
|
||||
#define RGA3_OVLP_BOT_ALPHA_OFFSET 0x09c
|
||||
#define RGA3_WR_CTRL_OFFSET 0x0a0
|
||||
#define RGA3_WR_FBCE_CTRL_OFFSET 0x0a4
|
||||
#define RGA3_WR_VIR_STRIDE_OFFSET 0x0a8
|
||||
#define RGA3_WR_PL_VIR_STRIDE_OFFSET 0x0ac
|
||||
#define RGA3_WR_Y_BASE_OFFSET 0x0b0
|
||||
#define RGA3_WR_U_BASE_OFFSET 0x0b4
|
||||
#define RGA3_WR_V_BASE_OFFSET 0x0b8
|
||||
#define RGA3_MMU_DTE_ADDR_OFFSET 0x0f00
|
||||
#define RGA3_MMU_STATUS_OFFSET 0x0f04
|
||||
#define RGA3_MMU_COMMAND_OFFSET 0x0f08
|
||||
#define RGA3_MMU_PAGE_FAULT_ADDR_OFFSET 0x0f0c
|
||||
#define RGA3_MMU_ZAP_ONE_LINE_OFFSET 0x0f10
|
||||
#define RGA3_MMU_INT_RAWSTAT_OFFSET 0x0f14
|
||||
#define RGA3_MMU_INT_CLEAR_OFFSET 0x0f18
|
||||
#define RGA3_MMU_INT_MASK_OFFSET 0x0f1c
|
||||
#define RGA3_MMU_INT_STATUS_OFFSET 0x0f20
|
||||
#define RGA3_MMU_AUTO_GATING_OFFSET 0x0f24
|
||||
#define RGA3_MMU_REG_LOAD_EN_OFFSET 0x0f28
|
||||
|
||||
int rga3_gen_reg_info(unsigned char *base, struct rga3_req *msg);
|
||||
void rga_cmd_to_rga3_cmd(struct rga_req *req_rga, struct rga3_req *req);
|
||||
//void RGA_MSG_2_RGA3_MSG_32(struct rga_req_32 *req_rga, struct rga3_req *req);
|
||||
|
||||
void rga3_soft_reset(struct rga_scheduler_t *scheduler);
|
||||
int rga3_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler);
|
||||
int rga3_init_reg(struct rga_job *job);
|
||||
int rga3_get_version(struct rga_scheduler_t *scheduler);
|
||||
|
||||
#endif
|
||||
|
||||
129
drivers/video/rockchip/rga3/include/rga_debugger.h
Normal file
129
drivers/video/rockchip/rga3/include/rga_debugger.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author:
|
||||
* Cerf Yu <cerf.yu@rock-chips.com>
|
||||
* Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef _RGA_DEBUGGER_H_
|
||||
#define _RGA_DEBUGGER_H_
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
|
||||
extern int RGA_DEBUG_REG;
|
||||
extern int RGA_DEBUG_MSG;
|
||||
extern int RGA_DEBUG_TIME;
|
||||
extern int RGA_DEBUG_CHECK_MODE;
|
||||
extern int RGA_DEBUG_NONUSE;
|
||||
extern int RGA_DEBUG_INT_FLAG;
|
||||
|
||||
extern struct rga_drvdata_t *rga_drvdata;
|
||||
|
||||
/*
|
||||
* struct rga_debugger - RGA debugger information
|
||||
*
|
||||
* This structure represents a debugger to be created by the rga driver
|
||||
* or core.
|
||||
*/
|
||||
struct rga_debugger {
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS
|
||||
/* Directory of debugfs file */
|
||||
struct dentry *debugfs_dir;
|
||||
struct list_head debugfs_entry_list;
|
||||
struct mutex debugfs_lock;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_PROC_FS
|
||||
/* Directory of procfs file */
|
||||
struct proc_dir_entry *procfs_dir;
|
||||
struct list_head procfs_entry_list;
|
||||
struct mutex procfs_lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* struct rga_debugger_list - debugfs/procfs info list entry
|
||||
*
|
||||
* This structure represents a debugfs/procfs file to be created by the rga
|
||||
* driver or core.
|
||||
*/
|
||||
struct rga_debugger_list {
|
||||
/* File name */
|
||||
const char *name;
|
||||
/*
|
||||
* Show callback. &seq_file->private will be set to the &struct
|
||||
* rga_debugger_node corresponding to the instance of this info
|
||||
* on a given &struct rga_debugger.
|
||||
*/
|
||||
int (*show)(struct seq_file *seq, void *data);
|
||||
/*
|
||||
* Write callback. &seq_file->private will be set to the &struct
|
||||
* rga_debugger_node corresponding to the instance of this info
|
||||
* on a given &struct rga_debugger.
|
||||
*/
|
||||
ssize_t (*write)(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *offp);
|
||||
/* Procfs/Debugfs private data. */
|
||||
void *data;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct rga_debugger_node - Nodes for debugfs/procfs
|
||||
*
|
||||
* This structure represents each instance of procfs/debugfs created from the
|
||||
* template.
|
||||
*/
|
||||
struct rga_debugger_node {
|
||||
struct rga_debugger *debugger;
|
||||
|
||||
/* template for this node. */
|
||||
const struct rga_debugger_list *info_ent;
|
||||
|
||||
/* Each Procfs/Debugfs file. */
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS
|
||||
struct dentry *dent;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_PROC_FS
|
||||
struct proc_dir_entry *pent;
|
||||
#endif
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS
|
||||
int rga_debugfs_init(void);
|
||||
int rga_debugfs_remove(void);
|
||||
#else
|
||||
static inline int rga_debugfs_remove(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int rga_debugfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* #ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS */
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_PROC_FS
|
||||
int rga_procfs_remove(void);
|
||||
int rga_procfs_init(void);
|
||||
#else
|
||||
static inline int rga_procfs_remove(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int rga_procfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* #ifdef CONFIG_ROCKCHIP_RGA_PROC_FS */
|
||||
|
||||
#endif /* #ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER */
|
||||
|
||||
void rga_cmd_print_debug_info(struct rga_req *req);
|
||||
|
||||
#endif /* #ifndef _RGA_DEBUGGER_H_ */
|
||||
|
||||
30
drivers/video/rockchip/rga3/include/rga_dma_buf.h
Normal file
30
drivers/video/rockchip/rga3/include/rga_dma_buf.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author:
|
||||
* Cerf Yu <cerf.yu@rock-chips.com>
|
||||
* Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
#ifndef __RGA3_DMA_BUF_H__
|
||||
#define __RGA3_DMA_BUF_H__
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/iova.h>
|
||||
#include <linux/dma-iommu.h>
|
||||
|
||||
#include "rga_drv.h"
|
||||
|
||||
void rga_dma_print_session_info(struct rga_dma_session *session);
|
||||
|
||||
int rga_dma_import_fd(int fd);
|
||||
int rga_dma_release_fd(int fd);
|
||||
|
||||
int rga_dma_buf_get(struct rga_job *job);
|
||||
|
||||
int rga_dma_get_info(struct rga_job *job);
|
||||
void rga_dma_put_info(struct rga_job *job);
|
||||
|
||||
int rga_get_format_bits(u32 format);
|
||||
|
||||
#endif /* #ifndef __RGA3_DMA_BUF_H__ */
|
||||
|
||||
274
drivers/video/rockchip/rga3/include/rga_drv.h
Normal file
274
drivers/video/rockchip/rga3/include/rga_drv.h
Normal file
@@ -0,0 +1,274 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_RGA_DRV_H_
|
||||
#define __LINUX_RGA_DRV_H_
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/wakelock.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#include "rga.h"
|
||||
#include "rga_debugger.h"
|
||||
|
||||
#define RGA_CORE_REG_OFFSET 0x10000
|
||||
|
||||
/* sample interval: 100ms */
|
||||
#define RGA_LOAD_INTERVAL 100000
|
||||
|
||||
#if ((defined(CONFIG_RK_IOMMU) || defined(CONFIG_ROCKCHIP_IOMMU)) \
|
||||
&& defined(CONFIG_ION_ROCKCHIP))
|
||||
#define CONFIG_RGA_IOMMU
|
||||
#endif
|
||||
|
||||
/* Driver information */
|
||||
#define DRIVER_DESC "RGA multicore Device Driver"
|
||||
#define DRIVER_NAME "rga_multicore"
|
||||
#define DRIVER_VERSION "1.1.1"
|
||||
#define RGA3_VERSION "2.000"
|
||||
|
||||
/* time limit */
|
||||
#define RGA_ASYNC_TIMEOUT_DELAY HZ
|
||||
#define RGA_RESET_TIMEOUT 1000
|
||||
|
||||
#define RGA_MAX_SCHEDULER 3
|
||||
#define RGA_MAX_BUS_CLK 10
|
||||
|
||||
#define RGA_BUFFER_POOL_MAX_SIZE 64
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
||||
#endif
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(X) (((X) < 0) ? (-(X)) : (X))
|
||||
#endif
|
||||
|
||||
#ifndef CLIP
|
||||
#define CLIP(x, a, b) (((x) < (a)) \
|
||||
? (a) : (((x) > (b)) ? (b) : (x)))
|
||||
#endif
|
||||
|
||||
enum {
|
||||
RGA3_SCHEDULER_CORE0 = 1 << 0,
|
||||
RGA3_SCHEDULER_CORE1 = 1 << 1,
|
||||
RGA2_SCHEDULER_CORE0 = 1 << 2,
|
||||
RGA_CORE_MASK = 0x7,
|
||||
RGA_NONE_CORE = 0x0,
|
||||
};
|
||||
|
||||
struct rga_fence_context {
|
||||
unsigned int context;
|
||||
unsigned int seqno;
|
||||
spinlock_t spinlock;
|
||||
};
|
||||
|
||||
struct rga_fence_waiter {
|
||||
/* Base sync driver waiter structure */
|
||||
struct dma_fence_cb waiter;
|
||||
|
||||
struct rga_job *job;
|
||||
};
|
||||
|
||||
struct rga_dma_buffer_t {
|
||||
/* DMABUF information */
|
||||
struct dma_buf *dma_buf;
|
||||
struct dma_buf_attachment *attach;
|
||||
struct sg_table *sgt;
|
||||
|
||||
dma_addr_t iova;
|
||||
unsigned long size;
|
||||
void *vaddr;
|
||||
enum dma_data_direction dir;
|
||||
|
||||
/* It indicates whether the buffer is cached */
|
||||
bool cached;
|
||||
|
||||
struct list_head link;
|
||||
struct kref refcount;
|
||||
|
||||
/*
|
||||
* use dma_buf directly,
|
||||
* do not call dma_buf_put, such as mpi
|
||||
*/
|
||||
bool use_dma_buf;
|
||||
};
|
||||
|
||||
struct rga_dma_buffer_pool {
|
||||
int __user *fd;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct rga_dma_session {
|
||||
struct mutex lock;
|
||||
/* cached dma buffer list */
|
||||
struct list_head cached_list;
|
||||
|
||||
/* the count of buffer in the cached_list */
|
||||
int buffer_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* yqw add:
|
||||
* In order to use the virtual address to refresh the cache,
|
||||
* it may be merged into sgt later.
|
||||
*/
|
||||
struct rga2_mmu_other_t {
|
||||
uint32_t *MMU_src0_base;
|
||||
uint32_t *MMU_src1_base;
|
||||
uint32_t *MMU_dst_base;
|
||||
uint32_t MMU_src0_count;
|
||||
uint32_t MMU_src1_count;
|
||||
uint32_t MMU_dst_count;
|
||||
|
||||
uint32_t MMU_len;
|
||||
bool MMU_map;
|
||||
};
|
||||
|
||||
struct rga_job {
|
||||
struct list_head head;
|
||||
struct rga_req rga_command_base;
|
||||
uint32_t cmd_reg[32 * 8];
|
||||
uint32_t csc_reg[12];
|
||||
|
||||
struct rga_dma_buffer_t *rga_dma_buffer_src0;
|
||||
struct rga_dma_buffer_t *rga_dma_buffer_src1;
|
||||
struct rga_dma_buffer_t *rga_dma_buffer_dst;
|
||||
/* used by rga2 */
|
||||
struct rga_dma_buffer_t *rga_dma_buffer_els;
|
||||
|
||||
struct dma_buf *dma_buf_src0;
|
||||
struct dma_buf *dma_buf_src1;
|
||||
struct dma_buf *dma_buf_dst;
|
||||
struct dma_buf *dma_buf_els;
|
||||
|
||||
struct rga2_mmu_other_t vir_page_table;
|
||||
|
||||
struct dma_fence *out_fence;
|
||||
struct dma_fence *in_fence;
|
||||
spinlock_t fence_lock;
|
||||
ktime_t timestamp;
|
||||
unsigned int flags;
|
||||
int job_id;
|
||||
int priority;
|
||||
int core;
|
||||
int ret;
|
||||
};
|
||||
|
||||
struct rga_scheduler_t;
|
||||
|
||||
struct rga_backend_ops {
|
||||
int (*get_version)(struct rga_scheduler_t *scheduler);
|
||||
int (*set_reg)(struct rga_job *job, struct rga_scheduler_t *scheduler);
|
||||
int (*init_reg)(struct rga_job *job);
|
||||
void (*soft_reset)(struct rga_scheduler_t *scheduler);
|
||||
};
|
||||
|
||||
struct rga_scheduler_t {
|
||||
struct device *dev;
|
||||
void __iomem *rga_base;
|
||||
|
||||
struct clk *clks[RGA_MAX_BUS_CLK];
|
||||
int num_clks;
|
||||
|
||||
struct rga_job *running_job;
|
||||
struct list_head todo_list;
|
||||
spinlock_t irq_lock;
|
||||
wait_queue_head_t job_done_wq;
|
||||
const struct rga_backend_ops *ops;
|
||||
const struct rga_hw_data *data;
|
||||
int job_count;
|
||||
int irq;
|
||||
char version[16];
|
||||
int core;
|
||||
unsigned int core_offset;
|
||||
};
|
||||
|
||||
struct rga_drvdata_t {
|
||||
struct miscdevice miscdev;
|
||||
|
||||
struct rga_fence_context *fence_ctx;
|
||||
|
||||
struct mutex mutex; // mutex
|
||||
|
||||
/* used by rga2's mmu lock */
|
||||
struct mutex lock;
|
||||
|
||||
struct rga_scheduler_t *rga_scheduler[RGA_MAX_SCHEDULER];
|
||||
int num_of_scheduler;
|
||||
|
||||
struct delayed_work power_off_work;
|
||||
struct wake_lock wake_lock;
|
||||
|
||||
struct rga_dma_session *dma_session;
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
struct rga_debugger *debugger;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct rga_irqs_data_t {
|
||||
const char *name;
|
||||
irqreturn_t (*irq_hdl)(int irq, void *ctx);
|
||||
irqreturn_t (*irq_thread)(int irq, void *ctx);
|
||||
};
|
||||
|
||||
struct rga_match_data_t {
|
||||
const char * const *clks;
|
||||
int num_clks;
|
||||
const struct rga_irqs_data_t *irqs;
|
||||
int num_irqs;
|
||||
};
|
||||
|
||||
static inline int rga_read(int offset, struct rga_scheduler_t *rga_scheduler)
|
||||
{
|
||||
return readl(rga_scheduler->rga_base + offset);
|
||||
}
|
||||
|
||||
static inline void rga_write(int value, int offset, struct rga_scheduler_t *rga_scheduler)
|
||||
{
|
||||
writel(value, rga_scheduler->rga_base + offset);
|
||||
}
|
||||
|
||||
#endif /* __LINUX_RGA_FENCE_H_ */
|
||||
28
drivers/video/rockchip/rga3/include/rga_fence.h
Normal file
28
drivers/video/rockchip/rga3/include/rga_fence.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_RGA_FENCE_H_
|
||||
#define __LINUX_RGA_FENCE_H_
|
||||
|
||||
#include "rga_drv.h"
|
||||
|
||||
struct rga_fence_context *rga_fence_context_alloc(void);
|
||||
|
||||
void rga_fence_context_free(struct rga_fence_context *fence_ctx);
|
||||
|
||||
int rga_out_fence_alloc(struct rga_job *job);
|
||||
|
||||
int rga_out_fence_get_fd(struct rga_job *job);
|
||||
|
||||
struct dma_fence *rga_get_input_fence(int in_fence_fd);
|
||||
|
||||
int rga_wait_input_fence(struct dma_fence *in_fence);
|
||||
|
||||
int rga_add_dma_fence_callback(struct rga_job *job,
|
||||
struct dma_fence *in_fence, dma_fence_func_t func);
|
||||
|
||||
#endif /* __LINUX_RGA_FENCE_H_ */
|
||||
58
drivers/video/rockchip/rga3/include/rga_hw_config.h
Normal file
58
drivers/video/rockchip/rga3/include/rga_hw_config.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_RGA_HW_CONFIG_H_
|
||||
#define __LINUX_RGA_HW_CONFIG_H_
|
||||
|
||||
#include "rga_drv.h"
|
||||
|
||||
struct rga_rect {
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
struct rga_win_data {
|
||||
const char *name;
|
||||
const uint32_t *raster_formats;
|
||||
const uint32_t *fbcd_formats;
|
||||
const uint32_t *tile_formats;
|
||||
uint32_t num_of_raster_formats;
|
||||
uint32_t num_of_fbcd_formats;
|
||||
uint32_t num_of_tile_formats;
|
||||
|
||||
const unsigned int supported_rotations;
|
||||
const unsigned int scale_up_mode;
|
||||
const unsigned int scale_down_mode;
|
||||
const unsigned int rd_mode;
|
||||
|
||||
};
|
||||
|
||||
struct rga_hw_data {
|
||||
uint32_t version;
|
||||
uint32_t feature;
|
||||
|
||||
uint32_t csc_r2y_mode;
|
||||
uint32_t csc_y2r_mode;
|
||||
|
||||
struct rga_rect max_input;
|
||||
struct rga_rect max_output;
|
||||
struct rga_rect min_input;
|
||||
struct rga_rect min_output;
|
||||
|
||||
unsigned int max_upscale_factor;
|
||||
unsigned int max_downscale_factor;
|
||||
|
||||
const struct rga_win_data *win;
|
||||
unsigned int win_size;
|
||||
};
|
||||
|
||||
extern const struct rga_hw_data rga3_data;
|
||||
extern const struct rga_hw_data rga2e_data;
|
||||
|
||||
void user_format_convert(uint32_t *df, uint32_t sf);
|
||||
|
||||
#endif /* __LINUX_RGA_HW_CONFIG_H_ */
|
||||
26
drivers/video/rockchip/rga3/include/rga_job.h
Normal file
26
drivers/video/rockchip/rga3/include/rga_job.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_RKRGA_JOB_H_
|
||||
#define __LINUX_RKRGA_JOB_H_
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/dma-fence.h>
|
||||
|
||||
#include "rga_drv.h"
|
||||
|
||||
#define RGA_JOB_DONE (1 << 0)
|
||||
#define RGA_JOB_ASYNC (1 << 1)
|
||||
#define RGA_JOB_SYNC (1 << 2)
|
||||
|
||||
void rga_job_done(struct rga_scheduler_t *rga_scheduler, int ret);
|
||||
int rga_commit(struct rga_req *rga_command_base, int flags);
|
||||
|
||||
int rga_kernel_commit(struct rga_req *rga_command_base,
|
||||
struct rga_mpi_job_t *mpi_job, int flags);
|
||||
|
||||
#endif /* __LINUX_RKRGA_JOB_H_ */
|
||||
1314
drivers/video/rockchip/rga3/rga2_mmu_info.c
Normal file
1314
drivers/video/rockchip/rga3/rga2_mmu_info.c
Normal file
File diff suppressed because it is too large
Load Diff
2540
drivers/video/rockchip/rga3/rga2_reg_info.c
Normal file
2540
drivers/video/rockchip/rga3/rga2_reg_info.c
Normal file
File diff suppressed because it is too large
Load Diff
2054
drivers/video/rockchip/rga3/rga3_reg_info.c
Normal file
2054
drivers/video/rockchip/rga3/rga3_reg_info.c
Normal file
File diff suppressed because it is too large
Load Diff
486
drivers/video/rockchip/rga3/rga_debugger.c
Normal file
486
drivers/video/rockchip/rga3/rga_debugger.c
Normal file
@@ -0,0 +1,486 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author:
|
||||
* Cerf Yu <cerf.yu@rock-chips.com>
|
||||
* Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "rga_debugger: " fmt
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include "rga.h"
|
||||
#include "rga_debugger.h"
|
||||
#include "rga_drv.h"
|
||||
|
||||
#define RGA_DEBUGGER_ROOT_NAME "rkrga"
|
||||
|
||||
#define STR_ENABLE(en) (en ? "EN" : "DIS")
|
||||
|
||||
int RGA_DEBUG_REG;
|
||||
int RGA_DEBUG_MSG;
|
||||
int RGA_DEBUG_TIME;
|
||||
int RGA_DEBUG_CHECK_MODE;
|
||||
int RGA_DEBUG_NONUSE;
|
||||
int RGA_DEBUG_INT_FLAG;
|
||||
|
||||
static int rga_debug_show(struct seq_file *m, void *data)
|
||||
{
|
||||
seq_printf(m, "REG [%s]\n"
|
||||
"MSG [%s]\n"
|
||||
"TIME [%s]\n"
|
||||
"INT [%s]\n"
|
||||
"CHECK [%s]\n"
|
||||
"STOP [%s]\n",
|
||||
STR_ENABLE(RGA_DEBUG_REG),
|
||||
STR_ENABLE(RGA_DEBUG_MSG),
|
||||
STR_ENABLE(RGA_DEBUG_TIME),
|
||||
STR_ENABLE(RGA_DEBUG_CHECK_MODE),
|
||||
STR_ENABLE(RGA_DEBUG_NONUSE),
|
||||
STR_ENABLE(RGA_DEBUG_INT_FLAG));
|
||||
|
||||
seq_puts(m, "\nhelp:\n");
|
||||
seq_puts(m,
|
||||
" 'echo reg > debug' to enable/disable register log printing.\n");
|
||||
seq_puts(m,
|
||||
" 'echo msg > debug' to enable/disable message log printing.\n");
|
||||
seq_puts(m,
|
||||
" 'echo time > debug' to enable/disable time log printing.\n");
|
||||
seq_puts(m,
|
||||
" 'echo int > debug' to enable/disable interruppt log printing.\n");
|
||||
seq_puts(m, " 'echo check > debug' to enable/disable check mode.\n");
|
||||
seq_puts(m,
|
||||
" 'echo stop > debug' to enable/disable stop using hardware\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t rga_debug_write(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
char buf[14];
|
||||
|
||||
if (len > sizeof(buf) - 1)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(buf, ubuf, len))
|
||||
return -EFAULT;
|
||||
buf[len - 1] = '\0';
|
||||
|
||||
if (strncmp(buf, "reg", 4) == 0) {
|
||||
if (RGA_DEBUG_REG) {
|
||||
RGA_DEBUG_REG = 0;
|
||||
pr_info("close rga reg!\n");
|
||||
} else {
|
||||
RGA_DEBUG_REG = 1;
|
||||
pr_info("open rga reg!\n");
|
||||
}
|
||||
} else if (strncmp(buf, "msg", 3) == 0) {
|
||||
if (RGA_DEBUG_MSG) {
|
||||
RGA_DEBUG_MSG = 0;
|
||||
pr_info("close rga test MSG!\n");
|
||||
} else {
|
||||
RGA_DEBUG_MSG = 1;
|
||||
pr_info("open rga test MSG!\n");
|
||||
}
|
||||
} else if (strncmp(buf, "time", 4) == 0) {
|
||||
if (RGA_DEBUG_TIME) {
|
||||
RGA_DEBUG_TIME = 0;
|
||||
pr_info("close rga test time!\n");
|
||||
} else {
|
||||
RGA_DEBUG_TIME = 1;
|
||||
pr_info("open rga test time!\n");
|
||||
}
|
||||
} else if (strncmp(buf, "check", 5) == 0) {
|
||||
if (RGA_DEBUG_CHECK_MODE) {
|
||||
RGA_DEBUG_CHECK_MODE = 0;
|
||||
pr_info("close rga check flag!\n");
|
||||
} else {
|
||||
RGA_DEBUG_CHECK_MODE = 1;
|
||||
pr_info("open rga check flag!\n");
|
||||
}
|
||||
} else if (strncmp(buf, "stop", 4) == 0) {
|
||||
if (RGA_DEBUG_NONUSE) {
|
||||
RGA_DEBUG_NONUSE = 0;
|
||||
pr_info("using rga hardware!\n");
|
||||
} else {
|
||||
RGA_DEBUG_NONUSE = 1;
|
||||
pr_info("stop using rga hardware!\n");
|
||||
}
|
||||
} else if (strncmp(buf, "int", 3) == 0) {
|
||||
if (RGA_DEBUG_INT_FLAG) {
|
||||
RGA_DEBUG_INT_FLAG = 0;
|
||||
pr_info("close inturrupt MSG!\n");
|
||||
} else {
|
||||
RGA_DEBUG_INT_FLAG = 1;
|
||||
pr_info("open inturrupt MSG!\n");
|
||||
}
|
||||
} else if (strncmp(buf, "slt", 3) == 0) {
|
||||
pr_err("Null");
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int rga_version_show(struct seq_file *m, void *data)
|
||||
{
|
||||
seq_printf(m, "%s: v%s\n", DRIVER_DESC, DRIVER_VERSION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_load_show(struct seq_file *m, void *data)
|
||||
{
|
||||
seq_printf(m, "%s: v%s\n", DRIVER_DESC, DRIVER_VERSION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_scheduler_show(struct seq_file *m, void *data)
|
||||
{
|
||||
struct rga_scheduler_t *rga_scheduler = NULL;
|
||||
int i;
|
||||
|
||||
seq_printf(m, "num of scheduler = %d\n", rga_drvdata->num_of_scheduler);
|
||||
seq_printf(m, "===================================\n");
|
||||
|
||||
for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
|
||||
rga_scheduler = rga_drvdata->rga_scheduler[i];
|
||||
|
||||
seq_printf(m, "scheduler[%d]: core = %d\n",
|
||||
i, rga_scheduler->core);
|
||||
seq_printf(m, "-----------------------------------\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rga_debugger_list rga_debugger_root_list[] = {
|
||||
{"debug", rga_debug_show, rga_debug_write, NULL},
|
||||
{"driver_version", rga_version_show, NULL, NULL},
|
||||
{"load", rga_load_show, NULL, NULL},
|
||||
{"scheduler_status", rga_scheduler_show, NULL, NULL},
|
||||
};
|
||||
|
||||
static ssize_t rga_debugger_write(struct file *file, const char __user *ubuf,
|
||||
size_t len, loff_t *offp)
|
||||
{
|
||||
struct seq_file *priv = file->private_data;
|
||||
struct rga_debugger_node *node = priv->private;
|
||||
|
||||
if (node->info_ent->write)
|
||||
return node->info_ent->write(file, ubuf, len, offp);
|
||||
else
|
||||
return len;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS
|
||||
static int rga_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct rga_debugger_node *node = inode->i_private;
|
||||
|
||||
return single_open(file, node->info_ent->show, node);
|
||||
}
|
||||
|
||||
static const struct file_operations rga_debugfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = rga_debugfs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = rga_debugger_write,
|
||||
};
|
||||
|
||||
static int rga_debugfs_remove_files(struct rga_debugger *debugger)
|
||||
{
|
||||
struct rga_debugger_node *pos, *q;
|
||||
struct list_head *entry_list;
|
||||
|
||||
mutex_lock(&debugger->debugfs_lock);
|
||||
|
||||
/* Delete debugfs entry list */
|
||||
entry_list = &debugger->debugfs_entry_list;
|
||||
list_for_each_entry_safe(pos, q, entry_list, list) {
|
||||
if (pos->dent == NULL)
|
||||
continue;
|
||||
list_del(&pos->list);
|
||||
kfree(pos);
|
||||
pos = NULL;
|
||||
}
|
||||
|
||||
/* Delete all debugfs node in this directory */
|
||||
debugfs_remove_recursive(debugger->debugfs_dir);
|
||||
debugger->debugfs_dir = NULL;
|
||||
|
||||
mutex_unlock(&debugger->debugfs_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_debugfs_create_files(const struct rga_debugger_list *files,
|
||||
int count, struct dentry *root,
|
||||
struct rga_debugger *debugger)
|
||||
{
|
||||
int i;
|
||||
struct dentry *ent;
|
||||
struct rga_debugger_node *tmp;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
tmp = kmalloc(sizeof(struct rga_debugger_node), GFP_KERNEL);
|
||||
if (tmp == NULL) {
|
||||
pr_err("Cannot alloc node path /sys/kernel/debug/%pd/%s\n",
|
||||
root, files[i].name);
|
||||
goto MALLOC_FAIL;
|
||||
}
|
||||
|
||||
tmp->info_ent = &files[i];
|
||||
tmp->debugger = debugger;
|
||||
|
||||
ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
|
||||
root, tmp, &rga_debugfs_fops);
|
||||
if (!ent) {
|
||||
pr_err("Cannot create /sys/kernel/debug/%pd/%s\n", root,
|
||||
files[i].name);
|
||||
goto CREATE_FAIL;
|
||||
}
|
||||
|
||||
tmp->dent = ent;
|
||||
|
||||
mutex_lock(&debugger->debugfs_lock);
|
||||
list_add_tail(&tmp->list, &debugger->debugfs_entry_list);
|
||||
mutex_unlock(&debugger->debugfs_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
CREATE_FAIL:
|
||||
kfree(tmp);
|
||||
MALLOC_FAIL:
|
||||
rga_debugfs_remove_files(debugger);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rga_debugfs_remove(void)
|
||||
{
|
||||
struct rga_debugger *debugger;
|
||||
|
||||
debugger = rga_drvdata->debugger;
|
||||
|
||||
rga_debugfs_remove_files(debugger);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rga_debugfs_init(void)
|
||||
{
|
||||
int ret;
|
||||
struct rga_debugger *debugger;
|
||||
|
||||
debugger = rga_drvdata->debugger;
|
||||
|
||||
debugger->debugfs_dir =
|
||||
debugfs_create_dir(RGA_DEBUGGER_ROOT_NAME, NULL);
|
||||
if (IS_ERR_OR_NULL(debugger->debugfs_dir)) {
|
||||
pr_err("failed on mkdir /sys/kernel/debug/%s\n",
|
||||
RGA_DEBUGGER_ROOT_NAME);
|
||||
debugger->debugfs_dir = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = rga_debugfs_create_files(rga_debugger_root_list, ARRAY_SIZE(rga_debugger_root_list),
|
||||
debugger->debugfs_dir, debugger);
|
||||
if (ret) {
|
||||
pr_err("Could not install rga_debugger_root_list debugfs\n");
|
||||
goto CREATE_FAIL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
CREATE_FAIL:
|
||||
rga_debugfs_remove();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* #ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS */
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA2_PROC_FS
|
||||
static int rga_procfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct rga_debugger_node *node = PDE_DATA(inode);
|
||||
|
||||
return single_open(file, node->info_ent->show, node);
|
||||
}
|
||||
|
||||
static const struct file_operations rga_procfs_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = rga_procfs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = rga_debugger_write,
|
||||
};
|
||||
|
||||
static int rga_procfs_remove_files(struct rga_debugger *debugger)
|
||||
{
|
||||
struct rga_debugger_node *pos, *q;
|
||||
struct list_head *entry_list;
|
||||
|
||||
mutex_lock(&debugger->procfs_lock);
|
||||
|
||||
/* Delete procfs entry list */
|
||||
entry_list = &debugger->procfs_entry_list;
|
||||
list_for_each_entry_safe(pos, q, entry_list, list) {
|
||||
if (pos->pent == NULL)
|
||||
continue;
|
||||
list_del(&pos->list);
|
||||
kfree(pos);
|
||||
pos = NULL;
|
||||
}
|
||||
|
||||
/* Delete all procfs node in this directory */
|
||||
proc_remove(debugger->procfs_dir);
|
||||
debugger->procfs_dir = NULL;
|
||||
|
||||
mutex_unlock(&debugger->procfs_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_procfs_create_files(const struct rga_debugger_list *files,
|
||||
int count, struct proc_dir_entry *root,
|
||||
struct rga_debugger *debugger)
|
||||
{
|
||||
int i;
|
||||
struct proc_dir_entry *ent;
|
||||
struct rga_debugger_node *tmp;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
tmp = kmalloc(sizeof(struct rga_debugger_node), GFP_KERNEL);
|
||||
if (tmp == NULL) {
|
||||
pr_err("Cannot alloc node path for /proc/%s/%s\n",
|
||||
RGA_DEBUGGER_ROOT_NAME, files[i].name);
|
||||
goto MALLOC_FAIL;
|
||||
}
|
||||
|
||||
tmp->info_ent = &files[i];
|
||||
tmp->debugger = debugger;
|
||||
|
||||
ent = proc_create_data(files[i].name, S_IFREG | S_IRUGO,
|
||||
root, &rga_procfs_fops, tmp);
|
||||
if (!ent) {
|
||||
pr_err("Cannot create /proc/%s/%s\n",
|
||||
RGA_DEBUGGER_ROOT_NAME, files[i].name);
|
||||
goto CREATE_FAIL;
|
||||
}
|
||||
|
||||
tmp->pent = ent;
|
||||
|
||||
mutex_lock(&debugger->procfs_lock);
|
||||
list_add_tail(&tmp->list, &debugger->procfs_entry_list);
|
||||
mutex_unlock(&debugger->procfs_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
CREATE_FAIL:
|
||||
kfree(tmp);
|
||||
MALLOC_FAIL:
|
||||
rga_procfs_remove_files(debugger);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rga_procfs_remove(void)
|
||||
{
|
||||
struct rga_debugger *debugger;
|
||||
|
||||
debugger = rga_drvdata->debugger;
|
||||
|
||||
rga_procfs_remove_files(debugger);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rga_procfs_init(void)
|
||||
{
|
||||
int ret;
|
||||
struct rga_debugger *debugger;
|
||||
|
||||
debugger = rga_drvdata->debugger;
|
||||
|
||||
debugger->procfs_dir = proc_mkdir(RGA_DEBUGGER_ROOT_NAME, NULL);
|
||||
if (IS_ERR_OR_NULL(debugger->procfs_dir)) {
|
||||
pr_err("failed on mkdir /proc/%s\n", RGA_DEBUGGER_ROOT_NAME);
|
||||
debugger->procfs_dir = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = rga_procfs_create_files(rga_debugger_root_list, ARRAY_SIZE(rga_debugger_root_list),
|
||||
debugger->procfs_dir, debugger);
|
||||
if (ret) {
|
||||
pr_err("Could not install rga_debugger_root_list procfs\n");
|
||||
goto CREATE_FAIL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
CREATE_FAIL:
|
||||
rga_procfs_remove();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* #ifdef CONFIG_ROCKCHIP_RGA_PROC_FS */
|
||||
|
||||
void rga_cmd_print_debug_info(struct rga_req *req)
|
||||
{
|
||||
pr_info("============= start ==============\n");
|
||||
pr_info("render_mode = %d, bitblit_mode=%d, rotate_mode = %d\n",
|
||||
req->render_mode, req->bsfilter_flag,
|
||||
req->rotate_mode);
|
||||
|
||||
pr_info("src: y = %lx uv = %lx v = %lx aw = %d ah = %d vw = %d vh = %d\n",
|
||||
(unsigned long)req->src.yrgb_addr,
|
||||
(unsigned long)req->src.uv_addr,
|
||||
(unsigned long)req->src.v_addr,
|
||||
req->src.act_w, req->src.act_h,
|
||||
req->src.vir_w, req->src.vir_h);
|
||||
pr_info("src: xoff = %d, yoff = %d, format = 0x%x, rd_mode = %d\n",
|
||||
req->src.x_offset, req->src.y_offset,
|
||||
req->src.format, req->src.rd_mode);
|
||||
|
||||
if (req->pat.yrgb_addr != 0 || req->pat.uv_addr != 0
|
||||
|| req->pat.v_addr != 0) {
|
||||
pr_info("pat: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n",
|
||||
(unsigned long)req->pat.yrgb_addr,
|
||||
(unsigned long)req->pat.uv_addr,
|
||||
(unsigned long)req->pat.v_addr,
|
||||
req->pat.act_w, req->pat.act_h,
|
||||
req->pat.vir_w, req->pat.vir_h);
|
||||
pr_info("pat: xoff = %d yoff = %d, format = 0x%x, rd_mode = %d\n",
|
||||
req->pat.x_offset, req->pat.y_offset,
|
||||
req->pat.format, req->pat.rd_mode);
|
||||
}
|
||||
|
||||
pr_info("dst: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n",
|
||||
(unsigned long)req->dst.yrgb_addr,
|
||||
(unsigned long)req->dst.uv_addr,
|
||||
(unsigned long)req->dst.v_addr,
|
||||
req->dst.act_w, req->dst.act_h,
|
||||
req->dst.vir_w, req->dst.vir_h);
|
||||
pr_info("dst: xoff = %d, yoff = %d, format = 0x%x, rd_mode = %d\n",
|
||||
req->dst.x_offset, req->dst.y_offset,
|
||||
req->dst.format, req->dst.rd_mode);
|
||||
|
||||
pr_info("mmu: mmu_flag=%x en=%x\n",
|
||||
req->mmu_info.mmu_flag, req->mmu_info.mmu_en);
|
||||
pr_info("alpha: rop_mode = %x\n", req->alpha_rop_mode);
|
||||
pr_info("yuv2rgb mode is %x\n", req->yuv2rgb_mode);
|
||||
pr_info("set core = %d, priority = %d, in_fence_fd = %d\n",
|
||||
req->core, req->priority, req->in_fence_fd);
|
||||
}
|
||||
590
drivers/video/rockchip/rga3/rga_dma_buf.c
Normal file
590
drivers/video/rockchip/rga3/rga_dma_buf.c
Normal file
@@ -0,0 +1,590 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "rga_dma_buf: " fmt
|
||||
|
||||
#include "rga_dma_buf.h"
|
||||
#include "rga.h"
|
||||
|
||||
#if CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
extern int RGA_DEBUG_CHECK_MODE;
|
||||
#endif
|
||||
|
||||
static struct rga_scheduler_t *get_scheduler(int core)
|
||||
{
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
|
||||
if (core == rga_drvdata->rga_scheduler[i]->core) {
|
||||
scheduler = rga_drvdata->rga_scheduler[i];
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_info("choose core: %d\n",
|
||||
rga_drvdata->rga_scheduler[i]->core);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
static bool is_yuv422p_format(u32 format)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
switch (format) {
|
||||
case RGA2_FORMAT_YCbCr_422_P:
|
||||
case RGA2_FORMAT_YCrCb_422_P:
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rga_convert_addr(struct rga_img_info_t *img)
|
||||
{
|
||||
/*
|
||||
* If it is not using dma fd, the virtual/phyical address is assigned
|
||||
* to the address of the corresponding channel.
|
||||
*/
|
||||
|
||||
//img->yrgb_addr = img->uv_addr;
|
||||
|
||||
if (img->rd_mode != RGA_FBC_MODE) {
|
||||
img->uv_addr = img->yrgb_addr + (img->vir_w * img->vir_h);
|
||||
|
||||
//warning: rga3 may need /2 for all
|
||||
if (is_yuv422p_format(img->format))
|
||||
img->v_addr =
|
||||
img->uv_addr + (img->vir_w * img->vir_h) / 2;
|
||||
else
|
||||
img->v_addr =
|
||||
img->uv_addr + (img->vir_w * img->vir_h) / 4;
|
||||
} else {
|
||||
img->uv_addr = img->yrgb_addr;
|
||||
img->v_addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int rga_get_format_bits(u32 format)
|
||||
{
|
||||
int bits = 0;
|
||||
|
||||
switch (format) {
|
||||
case RGA2_FORMAT_RGBA_8888:
|
||||
case RGA2_FORMAT_RGBX_8888:
|
||||
case RGA2_FORMAT_BGRA_8888:
|
||||
case RGA2_FORMAT_BGRX_8888:
|
||||
case RGA2_FORMAT_ARGB_8888:
|
||||
case RGA2_FORMAT_XRGB_8888:
|
||||
case RGA2_FORMAT_ABGR_8888:
|
||||
case RGA2_FORMAT_XBGR_8888:
|
||||
bits = 32;
|
||||
break;
|
||||
case RGA2_FORMAT_RGB_888:
|
||||
case RGA2_FORMAT_BGR_888:
|
||||
bits = 24;
|
||||
break;
|
||||
case RGA2_FORMAT_RGB_565:
|
||||
case RGA2_FORMAT_RGBA_5551:
|
||||
case RGA2_FORMAT_RGBA_4444:
|
||||
case RGA2_FORMAT_BGR_565:
|
||||
case RGA2_FORMAT_YCbCr_422_SP:
|
||||
case RGA2_FORMAT_YCbCr_422_P:
|
||||
case RGA2_FORMAT_YCrCb_422_SP:
|
||||
case RGA2_FORMAT_YCrCb_422_P:
|
||||
case RGA2_FORMAT_BGRA_5551:
|
||||
case RGA2_FORMAT_BGRA_4444:
|
||||
case RGA2_FORMAT_ARGB_5551:
|
||||
case RGA2_FORMAT_ARGB_4444:
|
||||
case RGA2_FORMAT_ABGR_5551:
|
||||
case RGA2_FORMAT_ABGR_4444:
|
||||
bits = 16;
|
||||
break;
|
||||
case RGA2_FORMAT_YCbCr_420_SP:
|
||||
case RGA2_FORMAT_YCbCr_420_P:
|
||||
case RGA2_FORMAT_YCrCb_420_SP:
|
||||
case RGA2_FORMAT_YCrCb_420_P:
|
||||
bits = 12;
|
||||
break;
|
||||
case RGA2_FORMAT_YCbCr_420_SP_10B:
|
||||
case RGA2_FORMAT_YCrCb_420_SP_10B:
|
||||
case RGA2_FORMAT_YCbCr_422_SP_10B:
|
||||
case RGA2_FORMAT_YCrCb_422_SP_10B:
|
||||
bits = 15;
|
||||
break;
|
||||
default:
|
||||
pr_err("unknown format [%d]\n", format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
static int rga_virtual_memory_check(void *vaddr, u32 w, u32 h, u32 format,
|
||||
int fd)
|
||||
{
|
||||
int bits = 32;
|
||||
int temp_data = 0;
|
||||
void *one_line = NULL;
|
||||
|
||||
bits = rga_get_format_bits(format);
|
||||
if (bits < 0)
|
||||
return -1;
|
||||
|
||||
one_line = kzalloc(w * 4, GFP_KERNEL);
|
||||
if (!one_line) {
|
||||
pr_err("kzalloc fail %s[%d]\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
temp_data = w * (h - 1) * bits >> 3;
|
||||
if (fd > 0) {
|
||||
pr_info("vaddr is%p, bits is %d, fd check\n", vaddr, bits);
|
||||
memcpy(one_line, (char *)vaddr + temp_data, w * bits >> 3);
|
||||
pr_info("fd check ok\n");
|
||||
} else {
|
||||
pr_info("vir addr memory check.\n");
|
||||
memcpy((void *)((char *)vaddr + temp_data), one_line,
|
||||
w * bits >> 3);
|
||||
pr_info("vir addr check ok.\n");
|
||||
}
|
||||
|
||||
kfree(one_line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_dma_memory_check(struct rga_dma_buffer_t *rga_dma_buffer,
|
||||
struct rga_img_info_t *img)
|
||||
{
|
||||
int ret = 0;
|
||||
void *vaddr;
|
||||
struct dma_buf *dma_buf;
|
||||
|
||||
dma_buf = rga_dma_buffer->dma_buf;
|
||||
|
||||
if (!IS_ERR_OR_NULL(dma_buf)) {
|
||||
vaddr = dma_buf_vmap(dma_buf);
|
||||
if (vaddr) {
|
||||
ret = rga_virtual_memory_check(vaddr, img->vir_w,
|
||||
img->vir_h, img->format, img->yrgb_addr);
|
||||
} else {
|
||||
pr_err("can't vmap the dma buffer!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dma_buf_vunmap(dma_buf, vaddr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rga_dma_map_buffer(struct dma_buf *dma_buf,
|
||||
struct rga_dma_buffer_t *rga_dma_buffer,
|
||||
enum dma_data_direction dir, struct device *rga_dev)
|
||||
{
|
||||
struct dma_buf_attachment *attach = NULL;
|
||||
struct sg_table *sgt = NULL;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
attach = dma_buf_attach(dma_buf, rga_dev);
|
||||
if (IS_ERR(attach)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("Failed to attach dma_buf\n");
|
||||
goto err_get_attach;
|
||||
}
|
||||
|
||||
sgt = dma_buf_map_attachment(attach, dir);
|
||||
if (IS_ERR(sgt)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("Failed to map src attachment\n");
|
||||
goto err_get_sg;
|
||||
}
|
||||
|
||||
rga_dma_buffer->dma_buf = dma_buf;
|
||||
rga_dma_buffer->attach = attach;
|
||||
rga_dma_buffer->sgt = sgt;
|
||||
rga_dma_buffer->iova = sg_dma_address(sgt->sgl);
|
||||
|
||||
/* TODO: size for check */
|
||||
rga_dma_buffer->size = sg_dma_len(sgt->sgl);
|
||||
rga_dma_buffer->dir = dir;
|
||||
|
||||
return ret;
|
||||
|
||||
err_get_sg:
|
||||
if (sgt)
|
||||
dma_buf_unmap_attachment(attach, sgt, dir);
|
||||
if (attach)
|
||||
dma_buf_detach(dma_buf, attach);
|
||||
err_get_attach:
|
||||
if (dma_buf && (rga_dma_buffer->use_dma_buf == false))
|
||||
dma_buf_put(dma_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rga_dma_unmap_buffer(struct rga_dma_buffer_t *rga_dma_buffer)
|
||||
{
|
||||
if (rga_dma_buffer->attach && rga_dma_buffer->sgt) {
|
||||
dma_buf_unmap_attachment(rga_dma_buffer->attach,
|
||||
rga_dma_buffer->sgt, rga_dma_buffer->dir);
|
||||
}
|
||||
|
||||
if (rga_dma_buffer->attach)
|
||||
dma_buf_detach(rga_dma_buffer->dma_buf, rga_dma_buffer->attach);
|
||||
|
||||
if (rga_dma_buffer->dma_buf && (rga_dma_buffer->use_dma_buf == false))
|
||||
dma_buf_put(rga_dma_buffer->dma_buf);
|
||||
}
|
||||
|
||||
static int rga_dma_fd_get_channel_info(struct rga_img_info_t *channel_info,
|
||||
struct rga_dma_buffer_t **rga_dma_buffer,
|
||||
int mmu_flag, int fd, int core)
|
||||
{
|
||||
int ret;
|
||||
struct rga_dma_buffer_t *alloc_buffer;
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
struct dma_buf *dma_buf = NULL;
|
||||
|
||||
if (unlikely(!mmu_flag && fd)) {
|
||||
pr_err("Fix it please enable mmu on dma fd channel\n");
|
||||
return -EINVAL;
|
||||
} else if (mmu_flag && fd) {
|
||||
/* else, perform a single mapping to dma buffer */
|
||||
alloc_buffer = kmalloc(sizeof(struct rga_dma_buffer_t),
|
||||
GFP_KERNEL);
|
||||
if (alloc_buffer == NULL) {
|
||||
pr_err("rga2_dma_import_fd alloc error!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dma_buf = dma_buf_get(fd);
|
||||
if (IS_ERR(dma_buf)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("dma_buf_get fail fd[%d]\n", fd);
|
||||
kfree(alloc_buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
alloc_buffer->cached = false;
|
||||
alloc_buffer->use_dma_buf = false;
|
||||
|
||||
scheduler = get_scheduler(core);
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n", __func__,
|
||||
__LINE__);
|
||||
kfree(alloc_buffer);
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret =
|
||||
rga_dma_map_buffer(dma_buf, alloc_buffer,
|
||||
DMA_BIDIRECTIONAL, scheduler->dev);
|
||||
if (ret < 0) {
|
||||
pr_err("Can't map dma-buf\n");
|
||||
kfree(alloc_buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*rga_dma_buffer = alloc_buffer;
|
||||
}
|
||||
|
||||
#if CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
if (RGA_DEBUG_CHECK_MODE) {
|
||||
ret = rga_dma_memory_check(*rga_dma_buffer,
|
||||
channel_info);
|
||||
if (ret < 0) {
|
||||
pr_err("Channel check memory error!\n");
|
||||
/*
|
||||
* Note: This error is released by external
|
||||
* rga_dma_put_channel_info().
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (core == RGA2_SCHEDULER_CORE0)
|
||||
channel_info->yrgb_addr = channel_info->uv_addr;
|
||||
else if (core == RGA3_SCHEDULER_CORE0 || core == RGA3_SCHEDULER_CORE1) {
|
||||
if (fd)
|
||||
channel_info->yrgb_addr = (*rga_dma_buffer)->iova;
|
||||
}
|
||||
|
||||
rga_convert_addr(channel_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_dma_buf_get_channel_info(struct rga_img_info_t *channel_info,
|
||||
struct rga_dma_buffer_t **rga_dma_buffer, int mmu_flag,
|
||||
struct dma_buf **dma_buf, int core)
|
||||
{
|
||||
int ret;
|
||||
struct rga_dma_buffer_t *alloc_buffer;
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
if (unlikely(!mmu_flag && *dma_buf)) {
|
||||
pr_err("Fix it please enable mmu on dma buf channel\n");
|
||||
return -EINVAL;
|
||||
} else if (mmu_flag && *dma_buf) {
|
||||
/* perform a single mapping to dma buffer */
|
||||
alloc_buffer =
|
||||
kmalloc(sizeof(struct rga_dma_buffer_t),
|
||||
GFP_KERNEL);
|
||||
if (alloc_buffer == NULL) {
|
||||
pr_err("rga2_dma_import_fd alloc error!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
alloc_buffer->use_dma_buf = true;
|
||||
|
||||
scheduler = get_scheduler(core);
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n", __func__,
|
||||
__LINE__);
|
||||
kfree(alloc_buffer);
|
||||
ret = -EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret =
|
||||
rga_dma_map_buffer(*dma_buf, alloc_buffer,
|
||||
DMA_BIDIRECTIONAL, scheduler->dev);
|
||||
if (ret < 0) {
|
||||
pr_err("Can't map dma-buf\n");
|
||||
kfree(alloc_buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*rga_dma_buffer = alloc_buffer;
|
||||
}
|
||||
|
||||
#if CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
if (RGA_DEBUG_CHECK_MODE) {
|
||||
ret = rga_dma_memory_check(*rga_dma_buffer,
|
||||
channel_info);
|
||||
if (ret < 0) {
|
||||
pr_err("Channel check memory error!\n");
|
||||
/*
|
||||
* Note: This error is released by external
|
||||
* rga_dma_put_channel_info().
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (core == RGA2_SCHEDULER_CORE0)
|
||||
channel_info->yrgb_addr = channel_info->uv_addr;
|
||||
else if (core == RGA3_SCHEDULER_CORE0 || core == RGA3_SCHEDULER_CORE1)
|
||||
channel_info->yrgb_addr = (*rga_dma_buffer)->iova;
|
||||
|
||||
rga_convert_addr(channel_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rga_dma_put_channel_info(struct rga_dma_buffer_t **rga_dma_buffer)
|
||||
{
|
||||
struct rga_dma_buffer_t *buffer;
|
||||
|
||||
buffer = *rga_dma_buffer;
|
||||
if (buffer == NULL)
|
||||
return;
|
||||
|
||||
rga_dma_unmap_buffer(buffer);
|
||||
kfree(buffer);
|
||||
|
||||
*rga_dma_buffer = NULL;
|
||||
}
|
||||
|
||||
int rga_dma_buf_get(struct rga_job *job)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
int mmu_flag;
|
||||
|
||||
struct rga_img_info_t *src0 = NULL;
|
||||
struct rga_img_info_t *src1 = NULL;
|
||||
struct rga_img_info_t *dst = NULL;
|
||||
struct rga_img_info_t *els = NULL;
|
||||
|
||||
src0 = &job->rga_command_base.src;
|
||||
dst = &job->rga_command_base.dst;
|
||||
if (job->rga_command_base.render_mode != UPDATE_PALETTE_TABLE_MODE)
|
||||
src1 = &job->rga_command_base.pat;
|
||||
else
|
||||
els = &job->rga_command_base.pat;
|
||||
|
||||
if (likely(src0 != NULL)) {
|
||||
mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 8) & 1);
|
||||
if (mmu_flag && src0->yrgb_addr) {
|
||||
job->dma_buf_src0 = dma_buf_get(src0->yrgb_addr);
|
||||
if (IS_ERR(job->dma_buf_src0)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("%s src0 dma_buf_get fail fd[%lu]\n",
|
||||
__func__, (unsigned long)src0->yrgb_addr);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(dst != NULL)) {
|
||||
mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 10) & 1);
|
||||
if (mmu_flag && dst->yrgb_addr) {
|
||||
job->dma_buf_dst = dma_buf_get(dst->yrgb_addr);
|
||||
if (IS_ERR(job->dma_buf_dst)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("%s dst dma_buf_get fail fd[%lu]\n",
|
||||
__func__, (unsigned long)dst->yrgb_addr);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (src1 != NULL) {
|
||||
mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 9) & 1);
|
||||
if (mmu_flag && src1->yrgb_addr) {
|
||||
job->dma_buf_src1 = dma_buf_get(src1->yrgb_addr);
|
||||
if (IS_ERR(job->dma_buf_src0)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("%s src1 dma_buf_get fail fd[%lu]\n",
|
||||
__func__, (unsigned long)src1->yrgb_addr);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (els != NULL) {
|
||||
mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 11) & 1);
|
||||
if (mmu_flag && els->yrgb_addr) {
|
||||
job->dma_buf_els = dma_buf_get(els->yrgb_addr);
|
||||
if (IS_ERR(job->dma_buf_els)) {
|
||||
ret = -EINVAL;
|
||||
pr_err("%s els dma_buf_get fail fd[%lu]\n",
|
||||
__func__, (unsigned long)els->yrgb_addr);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rga_dma_get_info(struct rga_job *job)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t mmu_flag;
|
||||
struct rga_img_info_t *src0 = NULL;
|
||||
struct rga_img_info_t *src1 = NULL;
|
||||
struct rga_img_info_t *dst = NULL;
|
||||
struct rga_img_info_t *els = NULL;
|
||||
|
||||
src0 = &job->rga_command_base.src;
|
||||
dst = &job->rga_command_base.dst;
|
||||
if (job->rga_command_base.render_mode != UPDATE_PALETTE_TABLE_MODE)
|
||||
src1 = &job->rga_command_base.pat;
|
||||
else
|
||||
els = &job->rga_command_base.pat;
|
||||
|
||||
/* src0 channel */
|
||||
if (likely(src0 != NULL)) {
|
||||
mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 8) & 1);
|
||||
if (job->dma_buf_src0 == NULL) {
|
||||
ret = rga_dma_fd_get_channel_info(src0,
|
||||
&job->rga_dma_buffer_src0, mmu_flag,
|
||||
src0->yrgb_addr, job->core);
|
||||
} else {
|
||||
ret = rga_dma_buf_get_channel_info(src0,
|
||||
&job->rga_dma_buffer_src0, mmu_flag,
|
||||
&job->dma_buf_src0, job->core);
|
||||
}
|
||||
if (unlikely(ret < 0)) {
|
||||
pr_err("src0 channel get info error!\n");
|
||||
goto src0_channel_err;
|
||||
}
|
||||
}
|
||||
|
||||
/* dst channel */
|
||||
if (likely(dst != NULL)) {
|
||||
if (job->dma_buf_dst == NULL && dst != NULL) {
|
||||
mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 10) & 1);
|
||||
ret = rga_dma_fd_get_channel_info(dst,
|
||||
&job->rga_dma_buffer_dst, mmu_flag,
|
||||
dst->yrgb_addr, job->core);
|
||||
} else if (dst != NULL) {
|
||||
ret = rga_dma_buf_get_channel_info(dst,
|
||||
&job->rga_dma_buffer_dst, mmu_flag,
|
||||
&job->dma_buf_dst, job->core);
|
||||
}
|
||||
if (unlikely(ret < 0)) {
|
||||
pr_err("dst channel get info error!\n");
|
||||
goto dst_channel_err;
|
||||
}
|
||||
}
|
||||
|
||||
/* src1 channel */
|
||||
if (src1 != NULL) {
|
||||
mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 9) & 1);
|
||||
if (job->dma_buf_src1 == NULL) {
|
||||
ret = rga_dma_fd_get_channel_info(src1,
|
||||
&job->rga_dma_buffer_src1, mmu_flag,
|
||||
src1->yrgb_addr, job->core);
|
||||
} else {
|
||||
ret = rga_dma_buf_get_channel_info(src1,
|
||||
&job->rga_dma_buffer_src1, mmu_flag,
|
||||
&job->dma_buf_src1, job->core);
|
||||
}
|
||||
if (unlikely(ret < 0)) {
|
||||
pr_err("src1 channel get info error!\n");
|
||||
goto src1_channel_err;
|
||||
}
|
||||
}
|
||||
|
||||
/* els channel */
|
||||
if (els != NULL) {
|
||||
mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 11) & 1);
|
||||
if (job->dma_buf_els == NULL && els != NULL) {
|
||||
ret = rga_dma_fd_get_channel_info(els,
|
||||
&job->rga_dma_buffer_els, mmu_flag,
|
||||
els->yrgb_addr, job->core);
|
||||
} else if (els != NULL) {
|
||||
ret = rga_dma_buf_get_channel_info(els,
|
||||
&job->rga_dma_buffer_els, mmu_flag,
|
||||
&job->dma_buf_els, job->core);
|
||||
}
|
||||
if (unlikely(ret < 0)) {
|
||||
pr_err("els channel get info error!\n");
|
||||
goto els_channel_err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
els_channel_err:
|
||||
rga_dma_put_channel_info(&job->rga_dma_buffer_els);
|
||||
dst_channel_err:
|
||||
rga_dma_put_channel_info(&job->rga_dma_buffer_dst);
|
||||
src1_channel_err:
|
||||
rga_dma_put_channel_info(&job->rga_dma_buffer_src1);
|
||||
src0_channel_err:
|
||||
rga_dma_put_channel_info(&job->rga_dma_buffer_src0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rga_dma_put_info(struct rga_job *job)
|
||||
{
|
||||
rga_dma_put_channel_info(&job->rga_dma_buffer_src0);
|
||||
rga_dma_put_channel_info(&job->rga_dma_buffer_src1);
|
||||
rga_dma_put_channel_info(&job->rga_dma_buffer_dst);
|
||||
rga_dma_put_channel_info(&job->rga_dma_buffer_els);
|
||||
}
|
||||
758
drivers/video/rockchip/rga3/rga_drv.c
Normal file
758
drivers/video/rockchip/rga3/rga_drv.c
Normal file
@@ -0,0 +1,758 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "rga: " fmt
|
||||
|
||||
#include "rga2_reg_info.h"
|
||||
#include "rga3_reg_info.h"
|
||||
#include "rga_dma_buf.h"
|
||||
|
||||
#include "rga_job.h"
|
||||
#include "rga_fence.h"
|
||||
#include "rga_hw_config.h"
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#endif
|
||||
|
||||
#include "rga2_mmu_info.h"
|
||||
#include "rga_debugger.h"
|
||||
|
||||
struct rga2_mmu_info_t rga2_mmu_info;
|
||||
|
||||
struct rga_drvdata_t *rga_drvdata;
|
||||
|
||||
static const struct rga_backend_ops rga3_ops = {
|
||||
.get_version = rga3_get_version,
|
||||
.set_reg = rga3_set_reg,
|
||||
.init_reg = rga3_init_reg,
|
||||
.soft_reset = rga3_soft_reset
|
||||
};
|
||||
|
||||
static const struct rga_backend_ops rga2_ops = {
|
||||
.get_version = rga2_get_version,
|
||||
.set_reg = rga2_set_reg,
|
||||
.init_reg = rga2_init_reg,
|
||||
.soft_reset = rga2_soft_reset
|
||||
};
|
||||
|
||||
int rga_mpi_commit(struct rga_req *cmd, struct rga_mpi_job_t *mpi_job)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = rga_kernel_commit(cmd, mpi_job, RGA_BLIT_SYNC);
|
||||
if (ret < 0) {
|
||||
pr_err("rga_kernel_commit failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rga_mpi_commit);
|
||||
|
||||
#ifndef CONFIG_ROCKCHIP_FPGA
|
||||
static int rga_power_enable(struct rga_scheduler_t *rga_scheduler)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
int i;
|
||||
|
||||
ret = pm_runtime_get_sync(rga_scheduler->dev);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to get pm runtime, ret = %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < rga_scheduler->num_clks; i++) {
|
||||
if (!IS_ERR(rga_scheduler->clks[i])) {
|
||||
ret = clk_prepare_enable(rga_scheduler->clks[i]);
|
||||
if (ret < 0)
|
||||
goto err_enable_clk;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_enable_clk:
|
||||
for (--i; i >= 0; --i)
|
||||
if (!IS_ERR(rga_scheduler->clks[i]))
|
||||
clk_disable_unprepare(rga_scheduler->clks[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rga_power_disable(struct rga_scheduler_t *rga_scheduler)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = rga_scheduler->num_clks - 1; i >= 0; i--)
|
||||
if (!IS_ERR(rga_scheduler->clks[i]))
|
||||
clk_disable_unprepare(rga_scheduler->clks[i]);
|
||||
|
||||
pm_runtime_put(rga_scheduler->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif //CONFIG_ROCKCHIP_FPGA
|
||||
|
||||
static long rga_ioctl(struct file *file, uint32_t cmd, unsigned long arg)
|
||||
{
|
||||
struct rga_drvdata_t *rga = rga_drvdata;
|
||||
struct rga_req req_rga;
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
int major_version = 0, minor_version = 0;
|
||||
char version[16] = { 0 };
|
||||
|
||||
if (!rga) {
|
||||
pr_err("rga_drvdata is null, rga is not init\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (RGA_DEBUG_NONUSE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case RGA_BLIT_SYNC:
|
||||
case RGA_BLIT_ASYNC:
|
||||
if (unlikely(copy_from_user(&req_rga,
|
||||
(struct rga_req *)arg, sizeof(struct rga_req)))) {
|
||||
pr_err("copy_from_user failed\n");
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (RGA_DEBUG_MSG)
|
||||
rga_cmd_print_debug_info(&req_rga);
|
||||
|
||||
ret = rga_commit(&req_rga, cmd);
|
||||
if (ret < 0) {
|
||||
pr_err("rga_commit failed\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_to_user((struct rga_req *)arg,
|
||||
&req_rga, sizeof(struct rga_req))) {
|
||||
pr_err("copy_to_user failed\n");
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case RGA_CACHE_FLUSH:
|
||||
case RGA_FLUSH:
|
||||
case RGA_GET_RESULT:
|
||||
break;
|
||||
case RGA_GET_VERSION:
|
||||
sscanf(rga->rga_scheduler[i]->version, "%x.%x.%*x",
|
||||
&major_version, &minor_version);
|
||||
snprintf(version, 5, "%x.%02x", major_version, minor_version);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
/* TODO: userspcae to get version */
|
||||
if (copy_to_user((void *)arg, version, sizeof(version)))
|
||||
ret = -EFAULT;
|
||||
#else
|
||||
if (copy_to_user((void *)arg, RGA3_VERSION,
|
||||
sizeof(RGA3_VERSION)))
|
||||
ret = -EFAULT;
|
||||
#endif
|
||||
break;
|
||||
case RGA2_GET_VERSION:
|
||||
for (i = 0; i < rga->num_of_scheduler; i++) {
|
||||
if (rga->rga_scheduler[i]->ops == &rga2_ops) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
if (copy_to_user((void *)arg, rga->rga_scheduler[i]->version,
|
||||
sizeof(rga->rga_scheduler[i]->version)))
|
||||
ret = -EFAULT;
|
||||
#else
|
||||
if (copy_to_user((void *)arg, RGA3_VERSION,
|
||||
sizeof(RGA3_VERSION)))
|
||||
ret = -EFAULT;
|
||||
#endif
|
||||
else
|
||||
ret = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* This will indicate that the RGA2 version number cannot be obtained. */
|
||||
if (ret != true)
|
||||
ret = -EFAULT;
|
||||
|
||||
break;
|
||||
|
||||
case RGA_IMPORT_DMA:
|
||||
case RGA_RELEASE_DMA:
|
||||
default:
|
||||
pr_err("unknown ioctl cmd!\n");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
static int rga_debugger_init(struct rga_debugger **debugger_p)
|
||||
{
|
||||
struct rga_debugger *debugger;
|
||||
|
||||
*debugger_p = kzalloc(sizeof(struct rga_debugger), GFP_KERNEL);
|
||||
if (*debugger_p == NULL) {
|
||||
pr_err("can not alloc for rga debugger\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
debugger = *debugger_p;
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUG_FS
|
||||
mutex_init(&debugger->debugfs_lock);
|
||||
INIT_LIST_HEAD(&debugger->debugfs_entry_list);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_PROC_FS
|
||||
mutex_init(&debugger->procfs_lock);
|
||||
INIT_LIST_HEAD(&debugger->procfs_entry_list);
|
||||
#endif
|
||||
|
||||
rga_debugfs_init();
|
||||
rga_procfs_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_debugger_remove(struct rga_debugger **debugger_p)
|
||||
{
|
||||
rga_debugfs_remove();
|
||||
rga_procfs_remove();
|
||||
|
||||
kfree(*debugger_p);
|
||||
*debugger_p = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rga_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
|
||||
static int rga_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t rga3_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct rga_scheduler_t *rga_scheduler = data;
|
||||
|
||||
if (RGA_DEBUG_INT_FLAG)
|
||||
pr_info("irqthread INT[%x],STATS0[%x], STATS1[%x]\n",
|
||||
rga_read(RGA3_INT_RAW, rga_scheduler),
|
||||
rga_read(RGA3_STATUS0, rga_scheduler),
|
||||
rga_read(RGA3_STATUS1, rga_scheduler));
|
||||
|
||||
/* TODO: if error interrupt then soft reset hardware */
|
||||
//rga_scheduler->ops->soft_reset(job->core);
|
||||
|
||||
/*clear INT */
|
||||
rga_write(1, RGA3_INT_CLR, rga_scheduler);
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static irqreturn_t rga3_irq_thread(int irq, void *data)
|
||||
{
|
||||
struct rga_scheduler_t *rga_scheduler = data;
|
||||
struct rga_job *job;
|
||||
|
||||
job = rga_scheduler->running_job;
|
||||
|
||||
if (!job) {
|
||||
pr_err("running job is invaild on irq thread\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (RGA_DEBUG_INT_FLAG)
|
||||
pr_info("irq INT[%x], STATS0[%x], STATS1[%x]\n",
|
||||
rga_read(RGA3_INT_RAW, rga_scheduler),
|
||||
rga_read(RGA3_STATUS0, rga_scheduler),
|
||||
rga_read(RGA3_STATUS1, rga_scheduler));
|
||||
|
||||
rga_job_done(rga_scheduler, 0);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t rga2_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct rga_scheduler_t *rga_scheduler = data;
|
||||
|
||||
if (RGA_DEBUG_INT_FLAG)
|
||||
pr_info("irqthread INT[%x],STATS0[%x]\n",
|
||||
rga_read(RGA2_INT, rga_scheduler), rga_read(RGA2_STATUS,
|
||||
rga_scheduler));
|
||||
|
||||
/*if error interrupt then soft reset hardware */
|
||||
//warning
|
||||
if (rga_read(RGA2_INT, rga_scheduler) & 0x01) {
|
||||
pr_err("err irq! INT[%x],STATS0[%x]\n",
|
||||
rga_read(RGA2_INT, rga_scheduler),
|
||||
rga_read(RGA2_STATUS, rga_scheduler));
|
||||
rga_scheduler->ops->soft_reset(rga_scheduler);
|
||||
}
|
||||
|
||||
/*clear INT */
|
||||
rga_write(rga_read(RGA2_INT, rga_scheduler) | (0x1 << 4) | (0x1 << 5) |
|
||||
(0x1 << 6) | (0x1 << 7), RGA2_INT, rga_scheduler);
|
||||
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static irqreturn_t rga2_irq_thread(int irq, void *data)
|
||||
{
|
||||
struct rga_scheduler_t *rga_scheduler = data;
|
||||
struct rga_job *job;
|
||||
|
||||
job = rga_scheduler->running_job;
|
||||
|
||||
if (!job)
|
||||
return IRQ_HANDLED;
|
||||
|
||||
if (RGA_DEBUG_INT_FLAG)
|
||||
pr_info("irq INT[%x], STATS0[%x]\n",
|
||||
rga_read(RGA2_INT, rga_scheduler), rga_read(RGA2_STATUS,
|
||||
rga_scheduler));
|
||||
|
||||
rga_job_done(rga_scheduler, 0);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
const struct file_operations rga_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = rga_open,
|
||||
.release = rga_release,
|
||||
.unlocked_ioctl = rga_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = rga_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct miscdevice rga_dev = {
|
||||
.name = "rga",
|
||||
.fops = &rga_fops,
|
||||
};
|
||||
|
||||
static const char *const old_rga2_clks[] = {
|
||||
"aclk_rga",
|
||||
"hclk_rga",
|
||||
"clk_rga",
|
||||
};
|
||||
|
||||
static const char *const rk3588_rga2_clks[] = {
|
||||
"aclk_rga2",
|
||||
"hclk_rga2",
|
||||
"clk_rga2",
|
||||
};
|
||||
|
||||
static const char *const rga3_core_0_clks[] = {
|
||||
"aclk_rga3_0",
|
||||
"hclk_rga3_0",
|
||||
"clk_rga3_0",
|
||||
};
|
||||
|
||||
static const char *const rga3_core_1_clks[] = {
|
||||
"aclk_rga3_1",
|
||||
"hclk_rga3_1",
|
||||
"clk_rga3_1",
|
||||
};
|
||||
|
||||
static const struct rga_irqs_data_t single_rga2_irqs[] = {
|
||||
{"rga2_irq", rga2_irq_handler, rga2_irq_thread}
|
||||
};
|
||||
|
||||
static const struct rga_irqs_data_t rga3_core0_irqs[] = {
|
||||
{"rga3_core0_irq", rga3_irq_handler, rga3_irq_thread}
|
||||
};
|
||||
|
||||
static const struct rga_irqs_data_t rga3_core1_irqs[] = {
|
||||
{"rga3_core1_irq", rga3_irq_handler, rga3_irq_thread}
|
||||
};
|
||||
|
||||
static const struct rga_match_data_t old_rga2_match_data = {
|
||||
.clks = old_rga2_clks,
|
||||
.num_clks = ARRAY_SIZE(old_rga2_clks),
|
||||
.irqs = single_rga2_irqs,
|
||||
.num_irqs = ARRAY_SIZE(single_rga2_irqs)
|
||||
};
|
||||
|
||||
static const struct rga_match_data_t rk3588_rga2_match_data = {
|
||||
.clks = rk3588_rga2_clks,
|
||||
.num_clks = ARRAY_SIZE(rk3588_rga2_clks),
|
||||
.irqs = single_rga2_irqs,
|
||||
.num_irqs = ARRAY_SIZE(single_rga2_irqs)
|
||||
};
|
||||
|
||||
static const struct rga_match_data_t rga3_core0_match_data = {
|
||||
.clks = rga3_core_0_clks,
|
||||
.num_clks = ARRAY_SIZE(rga3_core_0_clks),
|
||||
.irqs = rga3_core0_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rga3_core0_irqs)
|
||||
};
|
||||
|
||||
static const struct rga_match_data_t rga3_core1_match_data = {
|
||||
.clks = rga3_core_1_clks,
|
||||
.num_clks = ARRAY_SIZE(rga3_core_1_clks),
|
||||
.irqs = rga3_core1_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rga3_core1_irqs)
|
||||
};
|
||||
|
||||
static const struct of_device_id rga3_core0_dt_ids[] = {
|
||||
{
|
||||
.compatible = "rockchip,rga3_core0",
|
||||
.data = &rga3_core0_match_data,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
static const struct of_device_id rga3_core1_dt_ids[] = {
|
||||
{
|
||||
.compatible = "rockchip,rga3_core1",
|
||||
.data = &rga3_core1_match_data,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
static const struct of_device_id rga2_dt_ids[] = {
|
||||
{
|
||||
.compatible = "rockchip,rga2_core0",
|
||||
.data = &rk3588_rga2_match_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rga2",
|
||||
.data = &old_rga2_match_data,
|
||||
},
|
||||
};
|
||||
|
||||
static void init_scheduler(struct rga_scheduler_t *rga_scheduler,
|
||||
const char *name)
|
||||
{
|
||||
spin_lock_init(&rga_scheduler->irq_lock);
|
||||
INIT_LIST_HEAD(&rga_scheduler->todo_list);
|
||||
init_waitqueue_head(&rga_scheduler->job_done_wq);
|
||||
|
||||
if (!strcmp(name, "rga3_core0")) {
|
||||
rga_scheduler->ops = &rga3_ops;
|
||||
/* TODO: get by hw version */
|
||||
rga_scheduler->data = &rga3_data;
|
||||
rga_scheduler->core = RGA3_SCHEDULER_CORE0;
|
||||
} else if (!strcmp(name, "rga3_core1")) {
|
||||
rga_scheduler->ops = &rga3_ops;
|
||||
rga_scheduler->data = &rga3_data;
|
||||
rga_scheduler->core = RGA3_SCHEDULER_CORE1;
|
||||
} else if (!strcmp(name, "rga2")) {
|
||||
rga_scheduler->ops = &rga2_ops;
|
||||
rga_scheduler->data = &rga2e_data;
|
||||
rga_scheduler->core = RGA2_SCHEDULER_CORE0;
|
||||
}
|
||||
}
|
||||
|
||||
static int rga_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rga_drvdata_t *data = rga_drvdata;
|
||||
struct resource *res;
|
||||
int ret = 0;
|
||||
const struct of_device_id *match = NULL;
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct rga_match_data_t *match_data;
|
||||
int i, irq;
|
||||
struct rga_scheduler_t *rga_scheduler = NULL;
|
||||
|
||||
if (!pdev->dev.of_node)
|
||||
return -EINVAL;
|
||||
|
||||
if (!strcmp(dev_driver_string(dev), "rga3_core0"))
|
||||
match = of_match_device(rga3_core0_dt_ids, dev);
|
||||
else if (!strcmp(dev_driver_string(dev), "rga3_core1"))
|
||||
match = of_match_device(rga3_core1_dt_ids, dev);
|
||||
else if (!strcmp(dev_driver_string(dev), "rga2"))
|
||||
match = of_match_device(rga2_dt_ids, dev);
|
||||
|
||||
if (!match) {
|
||||
dev_err(dev, "%s missing DT entry!\n", dev_driver_string(dev));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rga_scheduler =
|
||||
devm_kzalloc(&pdev->dev, sizeof(struct rga_scheduler_t),
|
||||
GFP_KERNEL);
|
||||
if (rga_scheduler == NULL) {
|
||||
pr_err("failed to allocate scheduler. dev name = %s\n",
|
||||
dev_driver_string(dev));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
init_scheduler(rga_scheduler,
|
||||
dev_driver_string(dev));
|
||||
|
||||
rga_scheduler->dev = &pdev->dev;
|
||||
|
||||
/* map the registers */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
pr_err("get memory resource failed.\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
rga_scheduler->rga_base =
|
||||
devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||
if (!rga_scheduler->rga_base) {
|
||||
pr_err("ioremap failed\n");
|
||||
ret = -ENOENT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* get the IRQ */
|
||||
match_data = match->data;
|
||||
|
||||
/* there are irq names in dts */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "no irq %s in dts\n",
|
||||
match_data->irqs[0].name);
|
||||
return irq;
|
||||
}
|
||||
|
||||
rga_scheduler->irq = irq;
|
||||
|
||||
pr_err("%s, irq = %d, match scheduler\n",
|
||||
match_data->irqs[0].name, irq);
|
||||
|
||||
ret = devm_request_threaded_irq(dev, irq,
|
||||
match_data->irqs[0].irq_hdl,
|
||||
match_data->irqs[0].irq_thread, IRQF_SHARED,
|
||||
dev_driver_string(dev),
|
||||
rga_scheduler);
|
||||
if (ret < 0) {
|
||||
pr_err("request irq name: %s failed: %d\n",
|
||||
match_data->irqs[0].name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_ROCKCHIP_FPGA
|
||||
for (i = 0; i < match_data->num_clks; i++) {
|
||||
struct clk *clk = devm_clk_get(dev, match_data->clks[i]);
|
||||
|
||||
if (IS_ERR(clk))
|
||||
pr_err("failed to get %s\n", match_data->clks[i]);
|
||||
|
||||
rga_scheduler->clks[i] = clk;
|
||||
}
|
||||
rga_scheduler->num_clks = match_data->num_clks;
|
||||
#endif
|
||||
|
||||
platform_set_drvdata(pdev, rga_scheduler);
|
||||
|
||||
/* PM init */
|
||||
#ifndef CONFIG_ROCKCHIP_FPGA
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = rga_power_enable(rga_scheduler);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif //CONFIG_ROCKCHIP_FPGA
|
||||
|
||||
rga_scheduler->ops->get_version(rga_scheduler);
|
||||
pr_err("Driver loaded successfully rga[%d] ver:%s\n", i,
|
||||
rga_scheduler->version);
|
||||
|
||||
data->rga_scheduler[data->num_of_scheduler] = rga_scheduler;
|
||||
|
||||
data->num_of_scheduler++;
|
||||
|
||||
pr_err("probe successfully\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rga_drv_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rga_scheduler_t *rga_scheduler =
|
||||
platform_get_drvdata(pdev);
|
||||
|
||||
#ifndef CONFIG_ROCKCHIP_FPGA
|
||||
rga_power_disable(rga_scheduler);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
#endif //CONFIG_ROCKCHIP_FPGA
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rga3_core0_driver = {
|
||||
.probe = rga_drv_probe,
|
||||
.remove = rga_drv_remove,
|
||||
.driver = {
|
||||
.name = "rga3_core0",
|
||||
.of_match_table = of_match_ptr(rga3_core0_dt_ids),
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver rga3_core1_driver = {
|
||||
.probe = rga_drv_probe,
|
||||
.remove = rga_drv_remove,
|
||||
.driver = {
|
||||
.name = "rga3_core1",
|
||||
.of_match_table = of_match_ptr(rga3_core1_dt_ids),
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver rga2_driver = {
|
||||
.probe = rga_drv_probe,
|
||||
.remove = rga_drv_remove,
|
||||
.driver = {
|
||||
.name = "rga2",
|
||||
.of_match_table = of_match_ptr(rga2_dt_ids),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init rga_init(void)
|
||||
{
|
||||
int ret;
|
||||
int order = 0;
|
||||
|
||||
uint32_t *buf_p;
|
||||
uint32_t *buf;
|
||||
|
||||
/*
|
||||
* malloc pre scale mid buf mmu table:
|
||||
* RGA2_PHY_PAGE_SIZE * channel_num * address_size
|
||||
*/
|
||||
order = get_order(RGA2_PHY_PAGE_SIZE * 3 * sizeof(buf_p));
|
||||
buf_p = (uint32_t *) __get_free_pages(GFP_KERNEL | GFP_DMA32, order);
|
||||
if (buf_p == NULL) {
|
||||
pr_err("Can not alloc pages for mmu_page_table\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rga2_mmu_info.buf_virtual = buf_p;
|
||||
rga2_mmu_info.buf_order = order;
|
||||
|
||||
#if (defined(CONFIG_ARM) && defined(CONFIG_ARM_LPAE))
|
||||
buf =
|
||||
(uint32_t *) (uint32_t)
|
||||
virt_to_phys((void *)((unsigned long)buf_p));
|
||||
#else
|
||||
buf = (uint32_t *) virt_to_phys((void *)((unsigned long)buf_p));
|
||||
#endif
|
||||
rga2_mmu_info.buf = buf;
|
||||
rga2_mmu_info.front = 0;
|
||||
rga2_mmu_info.back = RGA2_PHY_PAGE_SIZE * 3;
|
||||
rga2_mmu_info.size = RGA2_PHY_PAGE_SIZE * 3;
|
||||
|
||||
order = get_order(RGA2_PHY_PAGE_SIZE * sizeof(struct page *));
|
||||
rga2_mmu_info.pages =
|
||||
(struct page **)__get_free_pages(GFP_KERNEL | GFP_DMA32, order);
|
||||
if (rga2_mmu_info.pages == NULL)
|
||||
pr_err("Can not alloc pages for rga2_mmu_info.pages\n");
|
||||
|
||||
rga2_mmu_info.pages_order = order;
|
||||
|
||||
rga_drvdata = kzalloc(sizeof(struct rga_drvdata_t), GFP_KERNEL);
|
||||
if (rga_drvdata == NULL) {
|
||||
pr_err("failed to allocate driver data.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&rga_drvdata->mutex);
|
||||
mutex_init(&rga_drvdata->lock);
|
||||
|
||||
wake_lock_init(&rga_drvdata->wake_lock, WAKE_LOCK_SUSPEND, "rga");
|
||||
|
||||
ret = platform_driver_register(&rga2_driver);
|
||||
if (ret != 0) {
|
||||
pr_err("Platform device rga2_driver register failed (%d).\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&rga3_core0_driver);
|
||||
if (ret != 0) {
|
||||
pr_err("Platform device rga3_core0_driver register failed (%d).\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&rga3_core1_driver);
|
||||
if (ret != 0) {
|
||||
pr_err("Platform device rga3_core1_driver register failed (%d).\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rga_drvdata->fence_ctx = rga_fence_context_alloc();
|
||||
if (IS_ERR(rga_drvdata->fence_ctx)) {
|
||||
pr_err("failed to allocate fence context for RGA\n");
|
||||
ret = PTR_ERR(rga_drvdata->fence_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = misc_register(&rga_dev);
|
||||
if (ret) {
|
||||
pr_err("cannot register miscdev (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
rga_debugger_init(&rga_drvdata->debugger);
|
||||
#endif
|
||||
|
||||
pr_info("Module initialized. v%s\n", DRIVER_VERSION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rga_exit(void)
|
||||
{
|
||||
free_pages((unsigned long)rga2_mmu_info.buf_virtual,
|
||||
rga2_mmu_info.buf_order);
|
||||
free_pages((unsigned long)rga2_mmu_info.pages, rga2_mmu_info.pages_order);
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER
|
||||
rga_debugger_remove(&rga_drvdata->debugger);
|
||||
#endif
|
||||
|
||||
wake_lock_destroy(&rga_drvdata->wake_lock);
|
||||
|
||||
rga_fence_context_free(rga_drvdata->fence_ctx);
|
||||
|
||||
platform_driver_unregister(&rga3_core0_driver);
|
||||
platform_driver_unregister(&rga3_core1_driver);
|
||||
platform_driver_unregister(&rga2_driver);
|
||||
|
||||
misc_deregister(&(rga_drvdata->miscdev));
|
||||
|
||||
kfree(rga_drvdata);
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
||||
#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
|
||||
module_init(rga_init);
|
||||
#else
|
||||
late_initcall(rga_init);
|
||||
#endif
|
||||
#else
|
||||
fs_initcall(rga_init);
|
||||
#endif
|
||||
module_exit(rga_exit);
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("putin.li@rock-chips.com");
|
||||
MODULE_DESCRIPTION("Driver for rga device");
|
||||
MODULE_LICENSE("GPL");
|
||||
136
drivers/video/rockchip/rga3/rga_fence.c
Normal file
136
drivers/video/rockchip/rga3/rga_fence.c
Normal file
@@ -0,0 +1,136 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "rga_fence: " fmt
|
||||
|
||||
#include <linux/dma-fence.h>
|
||||
#include <linux/sync_file.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "rga_fence.h"
|
||||
|
||||
static const char *rga_fence_get_name(struct dma_fence *fence)
|
||||
{
|
||||
return DRIVER_NAME;
|
||||
}
|
||||
|
||||
static const struct dma_fence_ops rga_fence_ops = {
|
||||
.get_driver_name = rga_fence_get_name,
|
||||
.get_timeline_name = rga_fence_get_name,
|
||||
};
|
||||
|
||||
struct rga_fence_context *rga_fence_context_alloc(void)
|
||||
{
|
||||
struct rga_fence_context *fence_ctx = NULL;
|
||||
|
||||
fence_ctx = kzalloc(sizeof(*fence_ctx), GFP_KERNEL);
|
||||
if (!fence_ctx)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
fence_ctx->context = dma_fence_context_alloc(1);
|
||||
spin_lock_init(&fence_ctx->spinlock);
|
||||
|
||||
return fence_ctx;
|
||||
}
|
||||
|
||||
void rga_fence_context_free(struct rga_fence_context *fence_ctx)
|
||||
{
|
||||
kfree(fence_ctx);
|
||||
}
|
||||
|
||||
int rga_out_fence_alloc(struct rga_job *job)
|
||||
{
|
||||
struct rga_fence_context *fence_ctx = rga_drvdata->fence_ctx;
|
||||
struct dma_fence *fence = NULL;
|
||||
|
||||
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
|
||||
if (!fence)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_fence_init(fence, &rga_fence_ops, &job->fence_lock,
|
||||
fence_ctx->context, ++fence_ctx->seqno);
|
||||
|
||||
job->out_fence = fence;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rga_out_fence_get_fd(struct rga_job *job)
|
||||
{
|
||||
struct sync_file *sync_file = NULL;
|
||||
int fence_fd = -1;
|
||||
|
||||
if (!job->out_fence)
|
||||
return -EINVAL;
|
||||
|
||||
fence_fd = get_unused_fd_flags(O_CLOEXEC);
|
||||
if (fence_fd < 0)
|
||||
return fence_fd;
|
||||
|
||||
sync_file = sync_file_create(job->out_fence);
|
||||
if (!sync_file)
|
||||
return -ENOMEM;
|
||||
|
||||
fd_install(fence_fd, sync_file->file);
|
||||
|
||||
return fence_fd;
|
||||
}
|
||||
|
||||
struct dma_fence *rga_get_input_fence(int in_fence_fd)
|
||||
{
|
||||
struct dma_fence *in_fence;
|
||||
|
||||
in_fence = sync_file_get_fence(in_fence_fd);
|
||||
|
||||
if (!in_fence)
|
||||
pr_err("can not get in-fence from fd\n");
|
||||
|
||||
return in_fence;
|
||||
}
|
||||
|
||||
int rga_wait_input_fence(struct dma_fence *in_fence)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = dma_fence_wait(in_fence, true);
|
||||
|
||||
dma_fence_put(in_fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rga_add_dma_fence_callback(struct rga_job *job, struct dma_fence *in_fence,
|
||||
dma_fence_func_t func)
|
||||
{
|
||||
struct rga_fence_waiter *waiter;
|
||||
int ret;
|
||||
|
||||
waiter = kmalloc(sizeof(*waiter), GFP_KERNEL);
|
||||
if (!waiter) {
|
||||
pr_err("%s: Failed to allocate waiter\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
waiter->job = job;
|
||||
|
||||
ret = dma_fence_add_callback(in_fence, &waiter->waiter, func);
|
||||
if (ret == -ENOENT) {
|
||||
pr_err("'input fence' has been already signaled.");
|
||||
goto err_free_waiter;
|
||||
} else if (ret == -EINVAL) {
|
||||
pr_err
|
||||
("%s: failed to add callback to dma_fence, err: %d\n",
|
||||
__func__, ret);
|
||||
goto err_free_waiter;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_free_waiter:
|
||||
kfree(waiter);
|
||||
return ret;
|
||||
}
|
||||
370
drivers/video/rockchip/rga3/rga_hw_config.c
Normal file
370
drivers/video/rockchip/rga3/rga_hw_config.c
Normal file
@@ -0,0 +1,370 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author:
|
||||
* Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include "rga_hw_config.h"
|
||||
|
||||
const uint32_t rga3_raster_format[] = {
|
||||
RGA2_FORMAT_RGBA_8888,
|
||||
RGA2_FORMAT_RGBX_8888,
|
||||
RGA2_FORMAT_BGRA_8888,
|
||||
RGA2_FORMAT_BGRX_8888,
|
||||
RGA2_FORMAT_RGB_888,
|
||||
RGA2_FORMAT_BGR_888,
|
||||
RGA2_FORMAT_RGB_565,
|
||||
RGA2_FORMAT_BGR_565,
|
||||
RGA2_FORMAT_YCbCr_422_SP,
|
||||
RGA2_FORMAT_YCbCr_420_SP,
|
||||
RGA2_FORMAT_YCrCb_422_SP,
|
||||
RGA2_FORMAT_YCrCb_420_SP,
|
||||
RGA2_FORMAT_YVYU_422,
|
||||
RGA2_FORMAT_VYUY_422,
|
||||
RGA2_FORMAT_YUYV_422,
|
||||
RGA2_FORMAT_UYVY_422,
|
||||
RGA2_FORMAT_YCbCr_420_SP_10B,
|
||||
RGA2_FORMAT_YCrCb_420_SP_10B,
|
||||
RGA2_FORMAT_YCbCr_422_SP_10B,
|
||||
RGA2_FORMAT_YCrCb_422_SP_10B,
|
||||
};
|
||||
|
||||
const uint32_t rga3_fbcd_format[] = {
|
||||
RGA2_FORMAT_RGBA_8888,
|
||||
RGA2_FORMAT_RGBX_8888,
|
||||
RGA2_FORMAT_BGRA_8888,
|
||||
RGA2_FORMAT_BGRX_8888,
|
||||
RGA2_FORMAT_RGB_888,
|
||||
RGA2_FORMAT_BGR_888,
|
||||
RGA2_FORMAT_RGB_565,
|
||||
RGA2_FORMAT_BGR_565,
|
||||
RGA2_FORMAT_YCbCr_422_SP,
|
||||
RGA2_FORMAT_YCbCr_420_SP,
|
||||
RGA2_FORMAT_YCrCb_422_SP,
|
||||
RGA2_FORMAT_YCrCb_420_SP,
|
||||
RGA2_FORMAT_YCbCr_420_SP_10B,
|
||||
RGA2_FORMAT_YCrCb_420_SP_10B,
|
||||
RGA2_FORMAT_YCbCr_422_SP_10B,
|
||||
RGA2_FORMAT_YCrCb_422_SP_10B,
|
||||
};
|
||||
|
||||
const uint32_t rga3_tile_format[] = {
|
||||
RGA2_FORMAT_YCbCr_422_SP,
|
||||
RGA2_FORMAT_YCbCr_420_SP,
|
||||
RGA2_FORMAT_YCrCb_422_SP,
|
||||
RGA2_FORMAT_YCrCb_420_SP,
|
||||
RGA2_FORMAT_YCbCr_420_SP_10B,
|
||||
RGA2_FORMAT_YCrCb_420_SP_10B,
|
||||
RGA2_FORMAT_YCbCr_422_SP_10B,
|
||||
RGA2_FORMAT_YCrCb_422_SP_10B,
|
||||
};
|
||||
|
||||
const uint32_t rga2e_raster_format[] = {
|
||||
RGA2_FORMAT_RGBA_8888,
|
||||
RGA2_FORMAT_RGBX_8888,
|
||||
RGA2_FORMAT_BGRA_8888,
|
||||
RGA2_FORMAT_BGRX_8888,
|
||||
RGA2_FORMAT_RGB_888,
|
||||
RGA2_FORMAT_BGR_888,
|
||||
RGA2_FORMAT_RGB_565,
|
||||
RGA2_FORMAT_BGR_565,
|
||||
RGA2_FORMAT_YCbCr_422_SP,
|
||||
RGA2_FORMAT_YCbCr_420_SP,
|
||||
RGA2_FORMAT_YCrCb_422_SP,
|
||||
RGA2_FORMAT_YCrCb_420_SP,
|
||||
RGA2_FORMAT_YVYU_422,
|
||||
RGA2_FORMAT_VYUY_422,
|
||||
RGA2_FORMAT_YUYV_422,
|
||||
RGA2_FORMAT_UYVY_422,
|
||||
RGA2_FORMAT_YCbCr_420_SP_10B,
|
||||
RGA2_FORMAT_YCrCb_420_SP_10B,
|
||||
RGA2_FORMAT_YCbCr_422_SP_10B,
|
||||
RGA2_FORMAT_YCrCb_422_SP_10B,
|
||||
RGA2_FORMAT_Y4,
|
||||
RGA2_FORMAT_YCbCr_400,
|
||||
RGA2_FORMAT_RGBA_5551,
|
||||
RGA2_FORMAT_BGRA_5551,
|
||||
RGA2_FORMAT_RGBA_4444,
|
||||
RGA2_FORMAT_BGRA_4444,
|
||||
RGA2_FORMAT_XRGB_8888,
|
||||
RGA2_FORMAT_XBGR_8888,
|
||||
};
|
||||
|
||||
const struct rga_win_data rga3_win_data[] = {
|
||||
{
|
||||
.name = "rga3-win0",
|
||||
.raster_formats = rga3_raster_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga3_raster_format),
|
||||
.fbcd_formats = rga3_fbcd_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga3_fbcd_format),
|
||||
.tile_formats = rga3_tile_format,
|
||||
.num_of_tile_formats = ARRAY_SIZE(rga3_tile_format),
|
||||
.supported_rotations = RGA_MODE_ROTATE_MASK,
|
||||
.scale_up_mode = RGA_SCALE_UP_BIC,
|
||||
.scale_down_mode = RGA_SCALE_DOWN_AVG,
|
||||
.rd_mode = RGA_RASTER_MODE | RGA_FBC_MODE | RGA_TILE_MODE,
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
.name = "rga3-win1",
|
||||
.raster_formats = rga3_raster_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga3_raster_format),
|
||||
.fbcd_formats = rga3_fbcd_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga3_fbcd_format),
|
||||
.tile_formats = rga3_tile_format,
|
||||
.num_of_tile_formats = ARRAY_SIZE(rga3_tile_format),
|
||||
.supported_rotations = RGA_MODE_ROTATE_MASK,
|
||||
.scale_up_mode = RGA_SCALE_UP_BIC,
|
||||
.scale_down_mode = RGA_SCALE_DOWN_AVG,
|
||||
.rd_mode = RGA_RASTER_MODE | RGA_FBC_MODE | RGA_TILE_MODE,
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
.name = "rga3-wr",
|
||||
.raster_formats = rga3_raster_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga3_raster_format),
|
||||
.fbcd_formats = rga3_fbcd_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga3_fbcd_format),
|
||||
.tile_formats = rga3_tile_format,
|
||||
.num_of_tile_formats = ARRAY_SIZE(rga3_tile_format),
|
||||
.supported_rotations = 0,
|
||||
.scale_up_mode = RGA_SCALE_UP_NONE,
|
||||
.scale_down_mode = RGA_SCALE_DOWN_NONE,
|
||||
.rd_mode = RGA_RASTER_MODE | RGA_FBC_MODE | RGA_TILE_MODE,
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
const struct rga_win_data rga2e_win_data[] = {
|
||||
{
|
||||
.name = "rga2e-src0",
|
||||
.raster_formats = rga2e_raster_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga2e_raster_format),
|
||||
.supported_rotations = RGA_MODE_ROTATE_MASK,
|
||||
.scale_up_mode = RGA_SCALE_UP_BIC,
|
||||
.scale_down_mode = RGA_SCALE_DOWN_AVG,
|
||||
.rd_mode = RGA_RASTER_MODE,
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
.name = "rga2e-src1",
|
||||
.raster_formats = rga2e_raster_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga2e_raster_format),
|
||||
.supported_rotations = RGA_MODE_ROTATE_MASK,
|
||||
.scale_up_mode = RGA_SCALE_UP_BIC,
|
||||
.scale_down_mode = RGA_SCALE_DOWN_AVG,
|
||||
.rd_mode = RGA_RASTER_MODE,
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
.name = "rga2-dst",
|
||||
.raster_formats = rga2e_raster_format,
|
||||
.num_of_raster_formats = ARRAY_SIZE(rga2e_raster_format),
|
||||
.supported_rotations = 0,
|
||||
.scale_up_mode = RGA_SCALE_UP_NONE,
|
||||
.scale_down_mode = RGA_SCALE_DOWN_NONE,
|
||||
.rd_mode = RGA_RASTER_MODE,
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
const struct rga_hw_data rga3_data = {
|
||||
.version = 0,
|
||||
.min_input = { 128, 128 },
|
||||
.min_output = { 128, 128 },
|
||||
.max_input = { 8128, 8128 },
|
||||
.max_output = { 8128, 8128 },
|
||||
|
||||
.win = rga3_win_data,
|
||||
.win_size = ARRAY_SIZE(rga3_win_data),
|
||||
/* 1 << factor mean real factor */
|
||||
.max_upscale_factor = 3,
|
||||
.max_downscale_factor = 3,
|
||||
|
||||
.feature = RGA_COLOR_KEY,
|
||||
.csc_r2y_mode = RGA_MODE_CSC_BT601L |
|
||||
RGA_MODE_CSC_BT601F | RGA_MODE_CSC_BT709 |
|
||||
RGA_MODE_CSC_BT2020,
|
||||
.csc_y2r_mode = RGA_MODE_CSC_BT601L |
|
||||
RGA_MODE_CSC_BT601F | RGA_MODE_CSC_BT709 |
|
||||
RGA_MODE_CSC_BT2020,
|
||||
};
|
||||
|
||||
const struct rga_hw_data rga2e_data = {
|
||||
.version = 0,
|
||||
.min_input = { 0, 0 },
|
||||
.min_output = { 0, 0 },
|
||||
.max_input = { 8192, 8192 },
|
||||
.max_output = { 4096, 4096 },
|
||||
|
||||
.win = rga2e_win_data,
|
||||
.win_size = ARRAY_SIZE(rga2e_win_data),
|
||||
/* 1 << factor mean real factor */
|
||||
.max_upscale_factor = 4,
|
||||
.max_downscale_factor = 4,
|
||||
|
||||
.feature = RGA_COLOR_FILL | RGA_COLOR_PALETTE |
|
||||
RGA_COLOR_KEY | RGA_ROP_CALCULATE |
|
||||
RGA_NN_QUANTIZE | RGA_DITHER,
|
||||
.csc_r2y_mode = RGA_MODE_CSC_BT601L | RGA_MODE_CSC_BT601F |
|
||||
RGA_MODE_CSC_BT709,
|
||||
.csc_y2r_mode = RGA_MODE_CSC_BT601L | RGA_MODE_CSC_BT601F |
|
||||
RGA_MODE_CSC_BT709,
|
||||
};
|
||||
|
||||
|
||||
void user_format_convert(uint32_t *df, uint32_t sf)
|
||||
{
|
||||
switch (sf) {
|
||||
case 0x0:
|
||||
*df = RGA2_FORMAT_RGBA_8888;
|
||||
break;
|
||||
case 0x1:
|
||||
*df = RGA2_FORMAT_RGBX_8888;
|
||||
break;
|
||||
case 0x2:
|
||||
*df = RGA2_FORMAT_RGB_888;
|
||||
break;
|
||||
case 0x3:
|
||||
*df = RGA2_FORMAT_BGRA_8888;
|
||||
break;
|
||||
case 0x4:
|
||||
*df = RGA2_FORMAT_RGB_565;
|
||||
break;
|
||||
case 0x5:
|
||||
*df = RGA2_FORMAT_RGBA_5551;
|
||||
break;
|
||||
case 0x6:
|
||||
*df = RGA2_FORMAT_RGBA_4444;
|
||||
break;
|
||||
case 0x7:
|
||||
*df = RGA2_FORMAT_BGR_888;
|
||||
break;
|
||||
case 0x16:
|
||||
*df = RGA2_FORMAT_BGRX_8888;
|
||||
break;
|
||||
case 0x8:
|
||||
*df = RGA2_FORMAT_YCbCr_422_SP;
|
||||
break;
|
||||
case 0x9:
|
||||
*df = RGA2_FORMAT_YCbCr_422_P;
|
||||
break;
|
||||
case 0xa:
|
||||
*df = RGA2_FORMAT_YCbCr_420_SP;
|
||||
break;
|
||||
case 0xb:
|
||||
*df = RGA2_FORMAT_YCbCr_420_P;
|
||||
break;
|
||||
case 0xc:
|
||||
*df = RGA2_FORMAT_YCrCb_422_SP;
|
||||
break;
|
||||
case 0xd:
|
||||
*df = RGA2_FORMAT_YCrCb_422_P;
|
||||
break;
|
||||
case 0xe:
|
||||
*df = RGA2_FORMAT_YCrCb_420_SP;
|
||||
break;
|
||||
case 0xf:
|
||||
*df = RGA2_FORMAT_YCrCb_420_P;
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
*df = RGA2_FORMAT_BPP_1;
|
||||
break;
|
||||
case 0x11:
|
||||
*df = RGA2_FORMAT_BPP_2;
|
||||
break;
|
||||
case 0x12:
|
||||
*df = RGA2_FORMAT_BPP_4;
|
||||
break;
|
||||
case 0x13:
|
||||
*df = RGA2_FORMAT_BPP_8;
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
*df = RGA2_FORMAT_Y4;
|
||||
break;
|
||||
case 0x15:
|
||||
*df = RGA2_FORMAT_YCbCr_400;
|
||||
break;
|
||||
|
||||
case 0x18:
|
||||
*df = RGA2_FORMAT_YVYU_422;
|
||||
break;
|
||||
case 0x19:
|
||||
*df = RGA2_FORMAT_YVYU_420;
|
||||
break;
|
||||
case 0x1a:
|
||||
*df = RGA2_FORMAT_VYUY_422;
|
||||
break;
|
||||
case 0x1b:
|
||||
*df = RGA2_FORMAT_VYUY_420;
|
||||
break;
|
||||
case 0x1c:
|
||||
*df = RGA2_FORMAT_YUYV_422;
|
||||
break;
|
||||
case 0x1d:
|
||||
*df = RGA2_FORMAT_YUYV_420;
|
||||
break;
|
||||
case 0x1e:
|
||||
*df = RGA2_FORMAT_UYVY_422;
|
||||
break;
|
||||
case 0x1f:
|
||||
*df = RGA2_FORMAT_UYVY_420;
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
*df = RGA2_FORMAT_YCbCr_420_SP_10B;
|
||||
break;
|
||||
case 0x21:
|
||||
*df = RGA2_FORMAT_YCrCb_420_SP_10B;
|
||||
break;
|
||||
case 0x22:
|
||||
*df = RGA2_FORMAT_YCbCr_422_SP_10B;
|
||||
break;
|
||||
case 0x23:
|
||||
*df = RGA2_FORMAT_YCrCb_422_SP_10B;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
*df = RGA2_FORMAT_BGR_565;
|
||||
break;
|
||||
case 0x25:
|
||||
*df = RGA2_FORMAT_BGRA_5551;
|
||||
break;
|
||||
case 0x26:
|
||||
*df = RGA2_FORMAT_BGRA_4444;
|
||||
break;
|
||||
|
||||
case 0x28:
|
||||
*df = RGA2_FORMAT_ARGB_8888;
|
||||
break;
|
||||
case 0x29:
|
||||
*df = RGA2_FORMAT_XRGB_8888;
|
||||
break;
|
||||
case 0x2a:
|
||||
*df = RGA2_FORMAT_ARGB_5551;
|
||||
break;
|
||||
case 0x2b:
|
||||
*df = RGA2_FORMAT_ARGB_4444;
|
||||
break;
|
||||
case 0x2c:
|
||||
*df = RGA2_FORMAT_ABGR_8888;
|
||||
break;
|
||||
case 0x2d:
|
||||
*df = RGA2_FORMAT_XBGR_8888;
|
||||
break;
|
||||
case 0x2e:
|
||||
*df = RGA2_FORMAT_ABGR_5551;
|
||||
break;
|
||||
case 0x2f:
|
||||
*df = RGA2_FORMAT_ABGR_4444;
|
||||
break;
|
||||
}
|
||||
}
|
||||
797
drivers/video/rockchip/rga3/rga_job.c
Normal file
797
drivers/video/rockchip/rga3/rga_job.c
Normal file
@@ -0,0 +1,797 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
* Author: Huang Lee <Putin.li@rock-chips.com>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "rga_job: " fmt
|
||||
|
||||
#include "rga_job.h"
|
||||
#include "rga_fence.h"
|
||||
#include "rga_dma_buf.h"
|
||||
#include "rga_hw_config.h"
|
||||
#include "rga2_mmu_info.h"
|
||||
|
||||
static struct rga_scheduler_t *get_scheduler(struct rga_job *job)
|
||||
{
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
|
||||
if (job->core == rga_drvdata->rga_scheduler[i]->core) {
|
||||
scheduler = rga_drvdata->rga_scheduler[i];
|
||||
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_info("job choose core: %d\n",
|
||||
rga_drvdata->rga_scheduler[i]->core);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
static void rga_job_free(struct rga_job *job)
|
||||
{
|
||||
if (job->out_fence)
|
||||
dma_fence_put(job->out_fence);
|
||||
|
||||
free_page((unsigned long)job);
|
||||
}
|
||||
|
||||
static int rga_job_cleanup(struct rga_job *job)
|
||||
{
|
||||
rga_job_free(job);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rga_job *rga_job_alloc(struct rga_req *rga_command_base)
|
||||
{
|
||||
struct rga_job *job = NULL;
|
||||
|
||||
job = (struct rga_job *)get_zeroed_page(GFP_KERNEL | GFP_DMA32);
|
||||
if (!job)
|
||||
return NULL;
|
||||
|
||||
job->timestamp = ktime_get();
|
||||
|
||||
job->rga_command_base = *rga_command_base;
|
||||
|
||||
if (rga_command_base->priority > 0) {
|
||||
if (rga_command_base->priority > RGA_SCHED_PRIORITY_MAX)
|
||||
job->priority = RGA_SCHED_PRIORITY_MAX;
|
||||
else
|
||||
job->priority = rga_command_base->priority;
|
||||
}
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
static void print_job_info(struct rga_job *job)
|
||||
{
|
||||
pr_info("job: priority = %d, core = %d\n",
|
||||
job->priority, job->core);
|
||||
}
|
||||
|
||||
static int rga_job_run(struct rga_job *job, struct rga_scheduler_t *scheduler)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = rga_dma_get_info(job);
|
||||
if (ret < 0) {
|
||||
pr_err("dma buf get failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = scheduler->ops->init_reg(job);
|
||||
if (ret < 0) {
|
||||
pr_err("init reg failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = scheduler->ops->set_reg(job, scheduler);
|
||||
if (ret < 0) {
|
||||
pr_err("set reg failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* for debug */
|
||||
if (RGA_DEBUG_MSG)
|
||||
print_job_info(job);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rga_job_next(struct rga_scheduler_t *rga_scheduler)
|
||||
{
|
||||
struct rga_job *job = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
next_job:
|
||||
spin_lock_irqsave(&rga_scheduler->irq_lock, flags);
|
||||
|
||||
if (rga_scheduler->running_job ||
|
||||
list_empty(&rga_scheduler->todo_list)) {
|
||||
spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
job = list_first_entry(&rga_scheduler->todo_list, struct rga_job, head);
|
||||
|
||||
list_del_init(&job->head);
|
||||
|
||||
rga_scheduler->job_count--;
|
||||
|
||||
rga_scheduler->running_job = job;
|
||||
|
||||
spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags);
|
||||
|
||||
job->ret = rga_job_run(job, rga_scheduler);
|
||||
|
||||
/* If some error on ASYNC mode before hw run */
|
||||
if (job->ret < 0) {
|
||||
pr_err("some error on rga_job_run, %s(%d)\n", __func__,
|
||||
__LINE__);
|
||||
|
||||
spin_lock_irqsave(&rga_scheduler->irq_lock, flags);
|
||||
|
||||
rga_scheduler->running_job = NULL;
|
||||
|
||||
spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags);
|
||||
|
||||
if (job->out_fence)
|
||||
dma_fence_signal(job->out_fence);
|
||||
|
||||
if (job->flags & RGA_JOB_ASYNC)
|
||||
rga_job_cleanup(job);
|
||||
|
||||
goto next_job;
|
||||
}
|
||||
}
|
||||
|
||||
void rga_job_done(struct rga_scheduler_t *rga_scheduler, int ret)
|
||||
{
|
||||
struct rga_job *job;
|
||||
unsigned long flags;
|
||||
|
||||
ktime_t now;
|
||||
|
||||
spin_lock_irqsave(&rga_scheduler->irq_lock, flags);
|
||||
job = rga_scheduler->running_job;
|
||||
rga_scheduler->running_job = NULL;
|
||||
spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags);
|
||||
|
||||
job->flags |= RGA_JOB_DONE;
|
||||
job->ret = ret;
|
||||
|
||||
now = ktime_get();
|
||||
|
||||
if (RGA_DEBUG_TIME)
|
||||
pr_err("%s use time = %lld\n", __func__,
|
||||
ktime_to_us(ktime_sub(now, job->timestamp)));
|
||||
|
||||
rga2_dma_flush_cache_for_virtual_address(&job->vir_page_table, rga_scheduler);
|
||||
|
||||
rga_dma_put_info(job);
|
||||
|
||||
if (job->out_fence)
|
||||
dma_fence_signal(job->out_fence);
|
||||
|
||||
wake_up(&rga_scheduler->job_done_wq);
|
||||
|
||||
if (job->flags & RGA_JOB_ASYNC)
|
||||
rga_job_cleanup(job);
|
||||
|
||||
rga_job_next(rga_scheduler);
|
||||
}
|
||||
|
||||
static int rga_set_feature(struct rga_req *rga_base)
|
||||
{
|
||||
int feature = 0;
|
||||
|
||||
if (rga_base->render_mode == COLOR_FILL_MODE)
|
||||
feature |= RGA_COLOR_FILL;
|
||||
|
||||
if (rga_base->render_mode == COLOR_PALETTE_MODE)
|
||||
feature |= RGA_COLOR_PALETTE;
|
||||
|
||||
if (rga_base->color_key_max > 0 || rga_base->color_key_min > 0)
|
||||
feature |= RGA_COLOR_KEY;
|
||||
|
||||
if ((rga_base->alpha_rop_flag >> 1) & 1)
|
||||
feature |= RGA_ROP_CALCULATE;
|
||||
|
||||
if ((rga_base->alpha_rop_flag >> 8) & 1)
|
||||
feature |= RGA_NN_QUANTIZE;
|
||||
|
||||
return feature;
|
||||
}
|
||||
|
||||
static bool rga_check_src0(const struct rga_hw_data *data,
|
||||
struct rga_img_info_t *src0)
|
||||
{
|
||||
int i;
|
||||
bool matched = false;
|
||||
int format;
|
||||
|
||||
user_format_convert(&format, src0->format);
|
||||
|
||||
if (src0->act_w < data->min_input.w ||
|
||||
src0->act_h < data->min_input.h)
|
||||
return false;
|
||||
|
||||
if (src0->act_w > data->max_input.w ||
|
||||
src0->act_h > data->max_input.h)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < data->win[0].num_of_raster_formats; i++) {
|
||||
if (format == data->win[0].raster_formats[i]) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rga_check_src1(const struct rga_hw_data *data,
|
||||
struct rga_img_info_t *src1)
|
||||
{
|
||||
int i;
|
||||
bool matched = false;
|
||||
int format;
|
||||
|
||||
user_format_convert(&format, src1->format);
|
||||
|
||||
if (src1->act_w < data->min_input.w ||
|
||||
src1->act_h < data->min_input.h)
|
||||
return false;
|
||||
|
||||
if (src1->act_w > data->max_input.w ||
|
||||
src1->act_h > data->max_input.h)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < data->win[1].num_of_raster_formats; i++) {
|
||||
if (format == data->win[1].raster_formats[i]) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rga_check_dst(const struct rga_hw_data *data,
|
||||
struct rga_img_info_t *dst)
|
||||
{
|
||||
int i;
|
||||
bool matched = false;
|
||||
int format;
|
||||
|
||||
user_format_convert(&format, dst->format);
|
||||
|
||||
if (dst->act_w < data->min_output.w ||
|
||||
dst->act_h < data->min_output.h)
|
||||
return false;
|
||||
|
||||
if (dst->act_w > data->max_output.w ||
|
||||
dst->act_h > data->max_output.h)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < data->win[2].num_of_raster_formats; i++) {
|
||||
if (format == data->win[2].raster_formats[i]) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rga_check_scale(const struct rga_hw_data *data,
|
||||
struct rga_req *rga_base)
|
||||
{
|
||||
struct rga_img_info_t *src0 = &rga_base->src;
|
||||
struct rga_img_info_t *dst = &rga_base->dst;
|
||||
|
||||
int sw, sh;
|
||||
int dw, dh;
|
||||
|
||||
sw = src0->act_w;
|
||||
sh = src0->act_h;
|
||||
|
||||
if ((rga_base->sina == 65536 && rga_base->cosa == 0)
|
||||
|| (rga_base->sina == -65536 && rga_base->cosa == 0)) {
|
||||
dw = dst->act_h;
|
||||
dh = dst->act_w;
|
||||
} else {
|
||||
dw = dst->act_w;
|
||||
dh = dst->act_h;
|
||||
}
|
||||
|
||||
if (sw > dw) {
|
||||
if ((sw >> data->max_downscale_factor) > dw)
|
||||
return false;
|
||||
} else if (sw < dw) {
|
||||
if ((sw << data->max_upscale_factor) < dw)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sh > dh) {
|
||||
if ((sh >> data->max_downscale_factor) > dh)
|
||||
return false;
|
||||
} else if (sh < dh) {
|
||||
if ((sh << data->max_upscale_factor) < dh)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int rga_job_assign(struct rga_job *job)
|
||||
{
|
||||
struct rga_img_info_t *src0 = &job->rga_command_base.src;
|
||||
struct rga_img_info_t *src1 = &job->rga_command_base.pat;
|
||||
struct rga_img_info_t *dst = &job->rga_command_base.dst;
|
||||
|
||||
struct rga_req *rga_base = &job->rga_command_base;
|
||||
const struct rga_hw_data *data;
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
int feature;
|
||||
int core = RGA_NONE_CORE;
|
||||
int optional_cores = RGA_NONE_CORE;
|
||||
int i;
|
||||
int min_of_job_count = 0;
|
||||
unsigned long flags;
|
||||
|
||||
/* assigned by userspace */
|
||||
/* TODO: valid value */
|
||||
if (rga_base->core > RGA_NONE_CORE)
|
||||
return rga_base->core;
|
||||
|
||||
feature = rga_set_feature(rga_base);
|
||||
|
||||
/* function */
|
||||
for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
|
||||
data = rga_drvdata->rga_scheduler[i]->data;
|
||||
scheduler = rga_drvdata->rga_scheduler[i];
|
||||
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("start policy on core = %d", scheduler->core);
|
||||
|
||||
if ((scheduler->core != RGA2_SCHEDULER_CORE0) &&
|
||||
(src0->uv_addr > 0 || src1->uv_addr > 0 ||
|
||||
dst->uv_addr > 0)) {
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("rga3 can not support viraddr\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (feature > 0) {
|
||||
if (!(feature & data->feature)) {
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("core = %d, break on feature",
|
||||
scheduler->core);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* only colorfill need single win (colorpalette?) */
|
||||
if (!(feature & 1)) {
|
||||
if (src1->yrgb_addr > 0) {
|
||||
if ((!(src0->rd_mode & data->win[0].rd_mode)) ||
|
||||
(!(src1->rd_mode & data->win[1].rd_mode)) ||
|
||||
(!(dst->rd_mode & data->win[2].rd_mode))) {
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("core = %d, ABC break on rd_mode",
|
||||
scheduler->core);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if ((!(src0->rd_mode & data->win[0].rd_mode)) ||
|
||||
(!(dst->rd_mode & data->win[2].rd_mode))) {
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("core = %d, ABB break on rd_mode",
|
||||
scheduler->core);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rga_check_scale(data, rga_base)) {
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("core = %d, break on rga_check_scale",
|
||||
scheduler->core);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rga_check_src0(data, src0)) {
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("core = %d, break on rga_check_src0",
|
||||
scheduler->core);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (src1->yrgb_addr > 0) {
|
||||
if (!rga_check_src1(data, src1)) {
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("core = %d, break on rga_check_src1",
|
||||
scheduler->core);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!rga_check_dst(data, dst)) {
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("core = %d, break on rga_check_dst",
|
||||
scheduler->core);
|
||||
continue;
|
||||
}
|
||||
|
||||
optional_cores |= scheduler->core;
|
||||
}
|
||||
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_info("optional_cores = %d\n", optional_cores);
|
||||
|
||||
if (optional_cores == 0) {
|
||||
core = -1;
|
||||
pr_err("invalid function policy\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
for (i = 0; i < rga_drvdata->num_of_scheduler; i++) {
|
||||
scheduler = rga_drvdata->rga_scheduler[i];
|
||||
|
||||
if (optional_cores & scheduler->core) {
|
||||
spin_lock_irqsave(&scheduler->irq_lock, flags);
|
||||
|
||||
if (scheduler->running_job == NULL) {
|
||||
core = scheduler->core;
|
||||
spin_unlock_irqrestore(&scheduler->irq_lock,
|
||||
flags);
|
||||
break;
|
||||
} else {
|
||||
if ((min_of_job_count > scheduler->job_count) ||
|
||||
(min_of_job_count == 0)) {
|
||||
min_of_job_count = scheduler->job_count;
|
||||
core = scheduler->core;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: need consider full load */
|
||||
finish:
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_info("assign core: %d\n", core);
|
||||
|
||||
return core;
|
||||
}
|
||||
|
||||
static struct rga_scheduler_t *rga_job_schedule(struct rga_job *job)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
struct rga_job *job_pos;
|
||||
bool first_match = 0;
|
||||
|
||||
if (rga_drvdata->num_of_scheduler > 1) {
|
||||
job->core = rga_job_assign(job);
|
||||
if (job->core <= 0) {
|
||||
pr_err("job assign failed");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
job->core = rga_drvdata->rga_scheduler[0]->core;
|
||||
}
|
||||
|
||||
scheduler = get_scheduler(job);
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n", __func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&scheduler->irq_lock, flags);
|
||||
|
||||
/* priority policy set by userspace */
|
||||
if (list_empty(&scheduler->todo_list)
|
||||
|| (job->priority == RGA_SCHED_PRIORITY_DEFAULT)) {
|
||||
list_add_tail(&job->head, &scheduler->todo_list);
|
||||
} else {
|
||||
list_for_each_entry(job_pos, &scheduler->todo_list, head) {
|
||||
if (job->priority > job_pos->priority &&
|
||||
(!first_match)) {
|
||||
list_add(&job->head, &job_pos->head);
|
||||
first_match = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase the priority of subsequent tasks
|
||||
* after inserting into the list
|
||||
*/
|
||||
if (first_match)
|
||||
job_pos->priority++;
|
||||
}
|
||||
|
||||
if (!first_match)
|
||||
list_add_tail(&job->head, &scheduler->todo_list);
|
||||
}
|
||||
|
||||
scheduler->job_count++;
|
||||
|
||||
spin_unlock_irqrestore(&scheduler->irq_lock, flags);
|
||||
|
||||
rga_job_next(scheduler);
|
||||
|
||||
return scheduler;
|
||||
}
|
||||
|
||||
static void rga_running_job_abort(struct rga_job *job,
|
||||
struct rga_scheduler_t *rga_scheduler)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (job->ret == -ETIMEDOUT)
|
||||
rga_scheduler->ops->soft_reset(rga_scheduler);
|
||||
|
||||
spin_lock_irqsave(&rga_scheduler->irq_lock, flags);
|
||||
|
||||
/* invalid job */
|
||||
if (job == rga_scheduler->running_job) {
|
||||
rga_scheduler->running_job = NULL;
|
||||
|
||||
rga_job_cleanup(job);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&rga_scheduler->irq_lock, flags);
|
||||
}
|
||||
|
||||
static void rga_invalid_job_abort(struct rga_job *job)
|
||||
{
|
||||
rga_job_cleanup(job);
|
||||
}
|
||||
|
||||
static inline int rga_job_wait(struct rga_scheduler_t *rga_scheduler,
|
||||
struct rga_job *job)
|
||||
{
|
||||
int left_time;
|
||||
ktime_t now;
|
||||
int ret;
|
||||
|
||||
left_time = wait_event_interruptible_timeout(rga_scheduler->job_done_wq,
|
||||
job->flags & RGA_JOB_DONE, RGA_ASYNC_TIMEOUT_DELAY);
|
||||
|
||||
if (left_time <= 0) {
|
||||
ret = left_time < 0 ? left_time : -ETIMEDOUT;
|
||||
if (ret < 0)
|
||||
rga_scheduler->ops->soft_reset(rga_scheduler);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
now = ktime_get();
|
||||
|
||||
if (RGA_DEBUG_TIME)
|
||||
pr_err("%s use time = %lld\n", __func__,
|
||||
ktime_to_us(ktime_sub(now, job->timestamp)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rga_input_fence_signaled(struct dma_fence *fence,
|
||||
struct dma_fence_cb *_waiter)
|
||||
{
|
||||
struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter;
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
|
||||
ktime_t now;
|
||||
|
||||
now = ktime_get();
|
||||
|
||||
if (RGA_DEBUG_TIME)
|
||||
pr_err("rga job wait in_fence signal use time = %lld\n",
|
||||
ktime_to_us(ktime_sub(now, waiter->job->timestamp)));
|
||||
|
||||
scheduler = rga_job_schedule(waiter->job);
|
||||
|
||||
if (scheduler == NULL)
|
||||
pr_err("failed to get scheduler, %s(%d)\n", __func__, __LINE__);
|
||||
|
||||
kfree(waiter);
|
||||
}
|
||||
|
||||
int rga_commit(struct rga_req *rga_command_base, int flags)
|
||||
{
|
||||
struct rga_job *job = NULL;
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
struct dma_fence *in_fence;
|
||||
int ret = 0;
|
||||
|
||||
job = rga_job_alloc(rga_command_base);
|
||||
if (!job) {
|
||||
pr_err("failed to alloc rga job!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (flags == RGA_BLIT_ASYNC) {
|
||||
ret = rga_out_fence_alloc(job);
|
||||
if (ret) {
|
||||
rga_job_free(job);
|
||||
return ret;
|
||||
}
|
||||
job->flags |= RGA_JOB_ASYNC;
|
||||
rga_command_base->out_fence_fd = rga_out_fence_get_fd(job);
|
||||
|
||||
//TODO: job timeout clean
|
||||
|
||||
if (RGA_DEBUG_MSG)
|
||||
pr_err("in_fence_fd = %d",
|
||||
rga_command_base->in_fence_fd);
|
||||
|
||||
/* if input fence is valiable */
|
||||
if (rga_command_base->in_fence_fd > 0) {
|
||||
in_fence = rga_get_input_fence(
|
||||
rga_command_base->in_fence_fd);
|
||||
if (!in_fence) {
|
||||
pr_err("%s: failed to get input dma_fence\n",
|
||||
__func__);
|
||||
rga_job_free(job);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* close input fence fd */
|
||||
ksys_close(rga_command_base->in_fence_fd);
|
||||
|
||||
ret = dma_fence_get_status(in_fence);
|
||||
/* ret = 1: fence has been signaled */
|
||||
if (ret == 1) {
|
||||
scheduler = rga_job_schedule(job);
|
||||
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n",
|
||||
__func__, __LINE__);
|
||||
goto invalid_job;
|
||||
}
|
||||
/* if input fence is valid */
|
||||
} else if (ret == 0) {
|
||||
/*
|
||||
* because fd can not pass on dma_fence_callback,
|
||||
* so need to get dma_buf first.
|
||||
*/
|
||||
ret = rga_dma_buf_get(job);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to get dma buf from fd\n",
|
||||
__func__);
|
||||
rga_job_free(job);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rga_add_dma_fence_callback(job,
|
||||
in_fence, rga_input_fence_signaled);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: failed to add fence callback\n",
|
||||
__func__);
|
||||
rga_job_free(job);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
pr_err("%s: fence status error\n", __func__);
|
||||
rga_job_free(job);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
scheduler = rga_job_schedule(job);
|
||||
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n",
|
||||
__func__, __LINE__);
|
||||
goto invalid_job;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* sync mode: wait utill job finish */
|
||||
} else if (flags == RGA_BLIT_SYNC) {
|
||||
scheduler = rga_job_schedule(job);
|
||||
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n", __func__,
|
||||
__LINE__);
|
||||
goto invalid_job;
|
||||
}
|
||||
|
||||
ret = job->ret;
|
||||
if (ret < 0) {
|
||||
pr_err("some error on job, %s(%d)\n", __func__,
|
||||
__LINE__);
|
||||
goto running_job_abort;
|
||||
}
|
||||
|
||||
ret = rga_job_wait(scheduler, job);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to wait rga job! May be timeout\n");
|
||||
goto running_job_abort;
|
||||
}
|
||||
rga_job_cleanup(job);
|
||||
}
|
||||
return ret;
|
||||
|
||||
invalid_job:
|
||||
rga_invalid_job_abort(job);
|
||||
return ret;
|
||||
|
||||
/* only used by SYNC mode */
|
||||
running_job_abort:
|
||||
rga_running_job_abort(job, scheduler);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rga_kernel_commit(struct rga_req *rga_command_base,
|
||||
struct rga_mpi_job_t *mpi_job, int flags)
|
||||
{
|
||||
struct rga_job *job = NULL;
|
||||
struct rga_scheduler_t *scheduler = NULL;
|
||||
int ret = 0;
|
||||
|
||||
job = rga_job_alloc(rga_command_base);
|
||||
if (!job) {
|
||||
pr_err("failed to alloc rga job!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
job->dma_buf_src0 = mpi_job->dma_buf_src0;
|
||||
job->dma_buf_src1 = mpi_job->dma_buf_src1;
|
||||
job->dma_buf_dst = mpi_job->dma_buf_dst;
|
||||
|
||||
if (flags == RGA_BLIT_ASYNC) {
|
||||
//TODO:
|
||||
pr_err("rk-debug TODO\n");
|
||||
} else if (flags == RGA_BLIT_SYNC) {
|
||||
scheduler = rga_job_schedule(job);
|
||||
|
||||
if (scheduler == NULL) {
|
||||
pr_err("failed to get scheduler, %s(%d)\n", __func__,
|
||||
__LINE__);
|
||||
goto invalid_job;
|
||||
}
|
||||
|
||||
ret = job->ret;
|
||||
if (ret < 0) {
|
||||
pr_err("some error on job, %s(%d)\n", __func__,
|
||||
__LINE__);
|
||||
goto running_job_abort;
|
||||
}
|
||||
|
||||
ret = rga_job_wait(scheduler, job);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to wait rga job! May be timeout\n");
|
||||
goto running_job_abort;
|
||||
}
|
||||
rga_job_cleanup(job);
|
||||
}
|
||||
return ret;
|
||||
|
||||
invalid_job:
|
||||
rga_invalid_job_abort(job);
|
||||
return ret;
|
||||
|
||||
/* only used by SYNC mode */
|
||||
running_job_abort:
|
||||
rga_running_job_abort(job, scheduler);
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user