From 54e59ae5c903275585230994bc5160ac0c838285 Mon Sep 17 00:00:00 2001 From: oh_ci Date: Fri, 29 Aug 2025 08:09:58 +0000 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E9=80=80=20'Pull=20Request=20!538=20:?= =?UTF-8?q?=20update=20rga3=20driver=20version=20v1.3.9g=5Fi'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- linux-6.6/rk3568_patch/kernel.patch | 5903 +++++++++------------------ 1 file changed, 1932 insertions(+), 3971 deletions(-) diff --git a/linux-6.6/rk3568_patch/kernel.patch b/linux-6.6/rk3568_patch/kernel.patch index 592760a..1e12a66 100644 --- a/linux-6.6/rk3568_patch/kernel.patch +++ b/linux-6.6/rk3568_patch/kernel.patch @@ -1894659,10 +1894659,10 @@ index 000000000..11f401de2 +obj-$(CONFIG_ROCKCHIP_MULTI_RGA) += rga3.o diff --git a/drivers/video/rockchip/rga3/include/rga.h b/drivers/video/rockchip/rga3/include/rga.h new file mode 100644 -index 000000000..671867b22 +index 000000000..2a60a1ae7 --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga.h -@@ -0,0 +1,1007 @@ +@@ -0,0 +1,944 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _RGA_DRIVER_H_ +#define _RGA_DRIVER_H_ @@ -1894696,7 +1894696,7 @@ index 000000000..671867b22 +#define RGA_IMPORT_DMA 0x601d +#define RGA_RELEASE_DMA 0x601e + -+#define RGA_TASK_NUM_MAX 256 ++#define RGA_TASK_NUM_MAX 50 + +#define RGA_OUT_OF_RESOURCES -10 +#define RGA_MALLOC_ERROR -11 @@ -1894734,17 +1894734,6 @@ index 000000000..671867b22 + RGA_MODE_X_MIRROR | \ + RGA_MODE_Y_MIRROR) + -+enum rga_csc_mode { -+ RGA_Y2R_BT601_LIMIT = 0x1 << 0, -+ RGA_Y2R_BT601_FULL = 0x2 << 0, -+ RGA_Y2R_BT709_LIMIT = 0x3 << 0, -+ RGA_Y2R_MASK = 0x3 << 0, -+ RGA_R2Y_BT601_LIMIT = 0x2 << 0, -+ RGA_R2Y_BT601_FULL = 0x1 << 0, -+ RGA_R2Y_BT709_LIMIT = 0x3 << 0, -+ RGA_R2Y_MASK = 0x3 << 0, -+}; -+ +enum rga_memory_type { + RGA_DMA_BUFFER = 0, + RGA_VIRTUAL_ADDRESS, @@ -1894763,19 +1894752,9 @@ index 000000000..671867b22 +}; + +enum RGA_SCHEDULER_CORE { -+ RGA3_SCHEDULER_CORE0 = 1 << 0, -+ RGA3_SCHEDULER_CORE1 = 1 << 1, -+ RGA2_SCHEDULER_CORE0 = 1 << 2, -+ RGA2_SCHEDULER_CORE1 = 1 << 3, -+ RGA_CORE_MASK = 0xf, -+ RGA_NONE_CORE = 0x0, -+}; -+ -+enum rga_scale_interp { -+ RGA_INTERP_DEFAULT = 0x0, -+ RGA_INTERP_LINEAR = 0x1, -+ RGA_INTERP_BICUBIC = 0x2, -+ RGA_INTERP_AVERAGE = 0x3, ++ RGA_SCHEDULER_RGA3_CORE0 = 1 << 0, ++ RGA_SCHEDULER_RGA3_CORE1 = 1 << 1, ++ RGA_SCHEDULER_RGA2_CORE0 = 1 << 2, +}; + +/* RGA process mode enum */ @@ -1894793,9 +1894772,6 @@ index 000000000..671867b22 + RGA_RASTER_MODE = 0x1 << 0, + RGA_FBC_MODE = 0x1 << 1, + RGA_TILE_MODE = 0x1 << 2, -+ RGA_TILE4x4_MODE = 0x1 << 3, -+ RGA_RKFBC_MODE = 0x1 << 4, -+ RGA_AFBC32x8_MODE = 0x1 << 5, +}; + +enum { @@ -1894835,7 +1894811,6 @@ index 000000000..671867b22 + RGA_OSD = 0x1 << 11, + RGA_PRE_INTR = 0x1 << 12, + RGA_FULL_CSC = 0x1 << 13, -+ RGA_GAUSS = 0x1 << 14, +}; + +enum rga_surf_format { @@ -1894896,12 +1894871,6 @@ index 000000000..671867b22 + RGA_FORMAT_ABGR_4444 = 0x2f, + + RGA_FORMAT_RGBA_2BPP = 0x30, -+ RGA_FORMAT_A8 = 0x31, -+ -+ RGA_FORMAT_YCbCr_444_SP = 0x32, -+ RGA_FORMAT_YCrCb_444_SP = 0x33, -+ -+ RGA_FORMAT_Y8 = 0x34, + + RGA_FORMAT_UNKNOWN = 0x100, +}; @@ -1895098,11 +1895067,6 @@ index 000000000..671867b22 + uint8_t mode; +}; + -+struct rga_gauss_config { -+ uint32_t size; -+ uint64_t coe_ptr; -+}; -+ +/* MAX(min, (max - channel_value)) */ +struct rga_osd_invert_factor { + uint8_t alpha_max; @@ -1895280,22 +1895244,6 @@ index 000000000..671867b22 + uint32_t user_close_fence:1; +}; + -+struct rga_interp { -+ uint8_t horiz:4; -+ uint8_t verti:4; -+}; -+ -+struct rga_iommu_prefetch { -+ uint32_t y_threshold; -+ uint32_t uv_threshold; -+}; -+ -+struct rga_rgba5551_alpha { -+ uint16_t flags; -+ uint8_t alpha0; -+ uint8_t alpha1; -+}; -+ +struct rga_req { + /* (enum) process mode sel */ + uint8_t render_mode; @@ -1895329,11 +1895277,8 @@ index 000000000..671867b22 + /* ([7] = 1 AA_enable) */ + uint16_t alpha_rop_flag; + -+ union { -+ struct rga_interp interp; -+ /* 0 nearst / 1 bilnear / 2 bicubic */ -+ uint8_t scale_mode; -+ }; ++ /* 0 nearst / 1 bilnear / 2 bicubic */ ++ uint8_t scale_mode; + + /* color key max */ + uint32_t color_key_max; @@ -1895425,11 +1895370,7 @@ index 000000000..671867b22 + + struct rga_csc_clip full_csc_clip; + -+ struct rga_rgba5551_alpha rgba5551_alpha; -+ -+ struct rga_gauss_config gauss_config; -+ -+ uint8_t reservr[24]; ++ uint8_t reservr[43]; +}; + +struct rga_alpha_config { @@ -1895556,14 +1895497,6 @@ index 000000000..671867b22 + uint8_t uvvds_mode; + + struct rga_osd_info osd_info; -+ -+ struct rga_interp interp; -+ -+ struct rga_iommu_prefetch iommu_prefetch; -+ -+ struct rga_rgba5551_alpha rgba5551_alpha; -+ -+ struct rga_gauss_config gauss_config; +}; + +struct rga3_req { @@ -1895588,8 +1895521,7 @@ index 000000000..671867b22 + struct rga_alpha_config alpha_config; + + /* for abb mode presever alpha. */ -+ bool bg_alpha_pass; -+ bool fg_alpha_pass; ++ bool abb_alpha_pass; + + u8 scale_bicu_mode; + @@ -1895607,6 +1895539,11 @@ index 000000000..671867b22 + 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; + @@ -1895672,10 +1895609,10 @@ index 000000000..671867b22 +#endif /*_RGA_DRIVER_H_*/ diff --git a/drivers/video/rockchip/rga3/include/rga2_reg_info.h b/drivers/video/rockchip/rga3/include/rga2_reg_info.h new file mode 100644 -index 000000000..187460833 +index 000000000..add2f41bd --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga2_reg_info.h -@@ -0,0 +1,573 @@ +@@ -0,0 +1,477 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __REG2_INFO_H__ +#define __REG2_INFO_H__ @@ -1895684,9 +1895621,7 @@ index 000000000..187460833 + +#define RGA2_SYS_REG_BASE 0x000 +#define RGA2_CSC_REG_BASE 0x060 -+#define RGA2_OTHER_REG_BASE 0x090 +#define RGA2_CMD_REG_BASE 0x100 -+#define RGA2_IOMMU_REG_BASE 0xf00 + +/* sys reg */ +#define RGA2_SYS_CTRL 0x000 @@ -1895697,7 +1895632,6 @@ index 000000000..187460833 +#define RGA2_MMU_CTRL0 0x014 +#define RGA2_MMU_CMD_BASE 0x018 +#define RGA2_STATUS2 0x01c -+#define RGA2_WORK_CNT 0x020 +#define RGA2_VERSION_NUM 0x028 +#define RGA2_READ_LINE_CNT 0x030 +#define RGA2_WRITE_LINE_CNT 0x034 @@ -1895718,27 +1895652,18 @@ index 000000000..187460833 +#define RGA2_DST_CSC_22 0x088 +#define RGA2_DST_CSC_OFF2 0x08c + -+/* back door0 */ -+#define RGA2_BACKDOOR0 0x090 -+ +/* osd read-back reg */ +#define RGA2_OSD_CUR_FLAGS0 0x090 +#define RGA2_OSD_CUR_FLAGS1 0x09c -+#define RGA2_FIXED_OSD_CUR_FLAGS0 0x440 -+#define RGA2_FIXED_OSD_CUR_FLAGS1 0x444 + +/* mode ctrl */ +#define RGA2_MODE_CTRL_OFFSET 0x000 +#define RGA2_SRC_INFO_OFFSET 0x004 +#define RGA2_SRC_BASE0_OFFSET 0x008 -+#define RGA2_FBCIN_HEAD_BASE_OFFSET 0x008 // repeat +#define RGA2_SRC_BASE1_OFFSET 0x00c -+#define RGA2_FBCIN_PAYL_BASE_OFFSET 0x00c // repeat +#define RGA2_SRC_BASE2_OFFSET 0x010 -+#define RGA2_FBCIN_OFF_OFFSET 0x010 // repeat +#define RGA2_SRC_BASE3_OFFSET 0x014 +#define RGA2_SRC_VIR_INFO_OFFSET 0x018 -+#define RGA2_FBCIN_HEAD_VIR_INFO_OFFSET 0x018 // repeat +#define RGA2_SRC_ACT_INFO_OFFSET 0x01c +#define RGA2_SRC_X_FACTOR_OFFSET 0x020 +#define RGA2_OSD_CTRL0_OFFSET 0x020 // repeat @@ -1895746,7 +1895671,6 @@ index 000000000..187460833 +#define RGA2_OSD_CTRL1_OFFSET 0x024 // repeat +#define RGA2_SRC_BG_COLOR_OFFSET 0x028 +#define RGA2_OSD_COLOR0_OFFSET 0x028 // repeat -+#define RGA2_GAUSS_COE_OFFSET 0x028 // repeat +#define RGA2_SRC_FG_COLOR_OFFSET 0x02c +#define RGA2_OSD_COLOR1_OFFSET 0x02c // repeat +#define RGA2_SRC_TR_COLOR0_OFFSET 0x030 @@ -1895760,7 +1895684,6 @@ index 000000000..187460833 +#define RGA2_DST_BASE0_OFFSET 0x03c +#define RGA2_DST_BASE1_OFFSET 0x040 +#define RGA2_DST_BASE2_OFFSET 0x044 -+#define RGA2_TILE4x4_OUT_BASE_OFFSET 0x044 //repeat +#define RGA2_DST_VIR_INFO_OFFSET 0x048 +#define RGA2_DST_ACT_INFO_OFFSET 0x04c +#define RGA2_ALPHA_CTRL0_OFFSET 0x050 @@ -1895779,17 +1895702,14 @@ index 000000000..187460833 +#define RGA2_OSD_INVERTSION_CAL1_OFFSET 0x064 // repeat +#define RGA2_MASK_BASE_OFFSET 0x068 +#define RGA2_MMU_CTRL1_OFFSET 0x06c -+#define RGA2_UV_VIR_INFO 0x06c // repeat +#define RGA2_MMU_SRC_BASE_OFFSET 0x070 -+#define RGA2_PREFETCH_ADDR_TH_OFFSET 0x070 // repeat +#define RGA2_MMU_SRC1_BASE_OFFSET 0x074 +#define RGA2_MMU_DST_BASE_OFFSET 0x078 +#define RGA2_MMU_ELS_BASE_OFFSET 0x07c + +/*RGA_SYS*/ -+#define m_RGA2_SYS_CTRL_SRC0YUV420SP_RD_OPT_DIS (0x1 << 12) /* moved to RGA_BACKDOOR0 since RV1126B */ -+#define m_RGA2_SYS_CTRL_DST_WR_OPT_DIS (0x1 << 11) /* moved to RGA_BACKDOOR0 since RV1126B */ -+#define m_RGA2_MASTER_CMD_BYPASS_EN (0x1 << 11) /* after RV1126B */ ++#define m_RGA2_SYS_CTRL_SRC0YUV420SP_RD_OPT_DIS (0x1 << 12) ++#define m_RGA2_SYS_CTRL_DST_WR_OPT_DIS (0x1 << 11) +#define m_RGA2_SYS_CTRL_CMD_CONTINUE_P (0x1 << 10) +#define m_RGA2_SYS_CTRL_HOLD_MODE_EN (0x1 << 9) +#define m_RGA2_SYS_CTRL_RST_HANDSAVE_P (0x1 << 7) @@ -1895811,22 +1895731,12 @@ index 000000000..187460833 +#define m_RGA2_CMD_CTRL_INCR_VALID_P (0x1 << 1) +#define m_RGA2_CMD_CTRL_CMD_LINE_ST_P (0x1 << 0) + -+#define s_RGA2_CMD_CTRL_INCR_NUM(x) ((x & 0x3ff) << 3) -+ +/* RGA_STATUS1 */ +#define m_RGA2_STATUS1_SW_CMD_TOTAL_NUM (0xfff << 8) +#define m_RGA2_STATUS1_SW_CMD_CUR_NUM (0xfff << 8) +#define m_RGA2_STATUS1_SW_RGA_STA (0x1 << 0) + +/*RGA_INT*/ -+#define m_RGA2_INT_FBCIN_DEC_ERROR_CLEAR (1 << 24) -+#define m_RGA2_INT_FBCIN_DEC_ERROR_EN (1 << 23) -+#define m_RGA2_INT_FBCIN_DEC_ERROR (1 << 22) -+#define m_RGA2_INT_PREFETCH_TH_INTR (1 << 21) -+#define m_RGA2_INT_PRE_TH_CLEAR (1 << 20) -+#define m_RGA2_INT_SCL_ERROR_CLEAR (1 << 19) -+#define m_RGA2_INT_SCL_ERROR_EN (1 << 18) -+#define m_RGA2_INT_SCL_ERROR_INTR (1 << 17) +#define m_RGA2_INT_LINE_WR_CLEAR (1 << 16) +#define m_RGA2_INT_LINE_RD_CLEAR (1 << 15) +#define m_RGA2_INT_LINE_WR_EN (1 << 14) @@ -1895848,23 +1895758,17 @@ index 000000000..187460833 +#define m_RGA2_INT_ERROR_FLAG_MASK \ + ( \ + m_RGA2_INT_MMU_INT_FLAG | \ -+ m_RGA2_INT_ERROR_INT_FLAG | \ -+ m_RGA2_INT_SCL_ERROR_INTR | \ -+ m_RGA2_INT_FBCIN_DEC_ERROR \ ++ m_RGA2_INT_ERROR_INT_FLAG \ + ) +#define m_RGA2_INT_ERROR_CLEAR_MASK \ + ( \ -+ m_RGA2_INT_MMU_INT_CLEAR | \ -+ m_RGA2_INT_ERROR_INT_CLEAR | \ -+ m_RGA2_INT_SCL_ERROR_CLEAR | \ -+ m_RGA2_INT_FBCIN_DEC_ERROR_CLEAR \ ++ m_RGA2_INT_MMU_INT_CLEAR | \ ++ m_RGA2_INT_ERROR_INT_CLEAR \ +) +#define m_RGA2_INT_ERROR_ENABLE_MASK \ + ( \ + m_RGA2_INT_MMU_INT_EN | \ -+ m_RGA2_INT_ERROR_INT_EN | \ -+ m_RGA2_INT_SCL_ERROR_EN | \ -+ m_RGA2_INT_FBCIN_DEC_ERROR_EN \ ++ m_RGA2_INT_ERROR_INT_EN \ + ) + +#define s_RGA2_INT_LINE_WR_CLEAR(x) ((x & 0x1) << 16) @@ -1895898,17 +1895802,6 @@ index 000000000..187460833 +#define s_RGA2_WRITE_LINE_SW_INTR_LINE_WR_START(x) ((x & 0x1fff) << 0) +#define s_RGA2_WRITE_LINE_SW_INTR_LINE_WR_STEP(x) ((x & 0x1fff) << 16) + -+/* RGA BACKDOOR0 */ -+#define m_RGA2_HSDBIL_VSP_FIX_DIS (0x1 << 0) -+#define m_RGA2_HSP_LEFT_COPY_DIS (0x1 << 1) -+#define m_RGA2_AXI_WR128_DIS (0x1 << 2) -+#define m_RGA2_TABLE_PRE_FETCH_DIS (0X1 << 3) -+#define m_RGA2_FBCIN_BSP_DIS (0X1 << 4) -+#define m_RGA2_SRC1_RGB888_FIX_DIS (0X1 << 5) -+#define m_RGA2_SRC0_YUV420SP_RD_OPT_DIS (0X1 << 6) -+#define m_RGA2_DST_WR_OPT_DIS (0X1 << 7) -+#define m_RGA2_OUTSTANDING_CFG_DIS (0X1 << 8) -+ +/* RGA_MODE_CTRL */ +#define m_RGA2_MODE_CTRL_SW_RENDER_MODE (0x7 << 0) +#define m_RGA2_MODE_CTRL_SW_BITBLT_MODE (0x1 << 3) @@ -1895919,15 +1895812,6 @@ index 000000000..187460833 +#define m_RGA2_MODE_CTRL_SW_OSD_E (0x1<<8) +#define m_RGA2_MODE_CTRL_SW_MOSAIC_EN (0x1<<9) +#define m_RGA2_MODE_CTRL_SW_YIN_YOUT_EN (0x1<<10) -+#define m_RGA2_MODE_CTRL_SW_TILE4x4_IN_EN (0x1 << 12) -+#define m_RGA2_MODE_CTRL_SW_TILE4x4_OUT_EN (0x1 << 13) -+#define m_RGA2_MODE_CTRL_SW_TABLE_PRE_FETCH_MODE (0x3 << 14) -+#define m_RGA2_MODE_CTRL_SW_FBC_IN_EN (0x1 << 16) -+#define m_RGA2_MODE_CTRL_SW_SRC_GAUSS_EN (0x1 << 17) -+#define m_RGA2_MODE_CTRL_SW_FBC_BSP_DIS (0x1 << 18) /* moved to RGA_BACKDOOR0 since RV1126B */ -+#define m_RGA2_MODE_CTRL_SW_TABLE_PRE_FETCH_DIS (0x1 << 19) /* moved to RGA_BACKDOOR0 since RV1126B */ -+#define m_RGA2_MODE_CTRL_SW_AXI_WR128_DIS (0x1 << 20) /* moved to RGA_BACKDOOR0 since RV1126B */ -+#define m_RGA2_MODE_CTRL_SW_HSP_LEFT_COPY_DIS (0x1 << 21) /* moved to RGA_BACKDOOR0 since RV1126B */ + +#define s_RGA2_MODE_CTRL_SW_RENDER_MODE(x) ((x & 0x7) << 0) +#define s_RGA2_MODE_CTRL_SW_BITBLT_MODE(x) ((x & 0x1) << 3) @@ -1895938,20 +1895822,8 @@ index 000000000..187460833 +#define s_RGA2_MODE_CTRL_SW_OSD_E(x) ((x & 0x1) << 8) +#define s_RGA2_MODE_CTRL_SW_MOSAIC_EN(x) ((x & 0x1) << 9) +#define s_RGA2_MODE_CTRL_SW_YIN_YOUT_EN(x) ((x & 0x1) << 10) -+#define s_RGA2_MODE_CTRL_SW_TILE4x4_IN_EN(x) ((x & 0x1) << 12) -+#define s_RGA2_MODE_CTRL_SW_TILE4x4_OUT_EN(x) ((x & 0x1) << 13) -+#define s_RGA2_MODE_CTRL_SW_TABLE_PRE_FETCH_MODE(x) ((x & 0x3) << 14) -+#define s_RGA2_MODE_CTRL_SW_FBC_IN_EN(x) ((x & 0x1) << 16) -+#define s_RGA2_MODE_CTRL_SW_SRC_GAUSS_EN(x) ((x & 0x1) << 17) -+#define s_RGA2_MODE_CTRL_SW_FBC_BSP_DIS(x) ((x & 0x1) << 18) -+#define s_RGA2_MODE_CTRL_SW_TABLE_PRE_FETCH_DIS(x) ((x & 0x1) << 19) -+#define s_RGA2_MODE_CTRL_SW_AXI_WR128_DIS(x) ((x & 0x1) << 20) -+#define s_RGA2_MODE_CTRL_SW_HSP_LEFT_COPY_DIS(x) ((x & 0x1) << 21) -+ +/* RGA_SRC_INFO */ +#define m_RGA2_SRC_INFO_SW_SRC_FMT (0xf << 0) -+#define m_RGA2_SRC_INFO_SW_FBCIN_MODE (0x3 << 0) // repeat -+#define m_RGA2_SRC_INFO_SW_FBCIN_FMT (0x3 << 2) // repeat +#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) @@ -1895968,14 +1895840,9 @@ index 000000000..187460833 +#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 m_RGA2_SRC_INFO_SW_SW_VSD_MODE_SEL (0x1 << 29) -+#define m_RGA2_SRC_INFO_SW_SW_HSP_MODE_SEL (0x1 << 30) -+#define m_RGA2_SRC_INFO_SW_SW_HSD_MODE_SEL (0x1 << 31) + + +#define s_RGA2_SRC_INFO_SW_SRC_FMT(x) ((x & 0xf) << 0) -+#define s_RGA2_SRC_INFO_SW_FBCIN_MODE(x) ((x & 0x3) << 0) // repeat -+#define s_RGA2_SRC_INFO_SW_FBCIN_FMT(x) ((x & 0x3) << 2) // repeat +#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) @@ -1895993,9 +1895860,6 @@ index 000000000..187460833 +#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) -+#define s_RGA2_SRC_INFO_SW_SW_VSD_MODE_SEL(x) ((x & 0x1) << 29) -+#define s_RGA2_SRC_INFO_SW_SW_HSP_MODE_SEL(x) ((x & 0x1) << 30) -+#define s_RGA2_SRC_INFO_SW_SW_HSD_MODE_SEL(x) ((x & 0x1) << 31) + +/* RGA_SRC_VIR_INFO */ +#define m_RGA2_SRC_VIR_INFO_SW_SRC_VIR_STRIDE (0x7fff << 0) @@ -1896006,15 +1895870,11 @@ index 000000000..187460833 + + +/* RGA_SRC_ACT_INFO */ -+#define m_RGA2_SRC_ACT_INFO_SW_TILE4X4_IN_YOFF (0x3 << 30) -+#define m_RGA2_SRC_ACT_INFO_SW_SRC_ACT_HEIGHT (0x7ff << 16) -+#define m_RGA2_SRC_ACT_INFO_SW_TILE4X4_IN_XOFF (0x3 << 14) -+#define m_RGA2_SRC_ACT_INFO_SW_SRC_ACT_WIDTH (0x7ff << 0) ++#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_TILE4X4_IN_YOFF(x) ((x & 0x3) << 30) -+#define s_RGA2_SRC_ACT_INFO_SW_SRC_ACT_HEIGHT(x) ((x & 0x7ff) << 16) -+#define s_RGA2_SRC_ACT_INFO_SW_TILE4X4_IN_XOFF(x) ((x & 0x3) << 14) -+#define s_RGA2_SRC_ACT_INFO_SW_SRC_ACT_WIDTH(x) ((x & 0x7ff) << 0) ++#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) + +/* RGA2_OSD_CTRL0 */ +#define m_RGA2_OSD_CTRL0_SW_OSD_MODE (0x3 << 0) @@ -1896033,15 +1895893,6 @@ index 000000000..187460833 +#define s_RGA2_OSD_CTRL0_SW_OSD_FIX_WIDTH(x) ((x & 0x3ff) << 20) +#define s_RGA2_OSD_CTRL0_SW_OSD_2BPP_MODE(x) ((x & 0x1) << 30) + -+/* RGA2_GAUSS_COE */ -+#define m_RGA2_GAUSS_COE_SW_COE0 (0x3f << 0) -+#define m_RGA2_GAUSS_COE_SW_COE1 (0x3f << 8) -+#define m_RGA2_GAUSS_COE_SW_COE2 (0xff << 16) -+ -+#define s_RGA2_GAUSS_COE_SW_COE0(x) ((x & 0x3f) << 0) -+#define s_RGA2_GAUSS_COE_SW_COE1(x) ((x & 0x3f) << 8) -+#define s_RGA2_GAUSS_COE_SW_COE2(x) ((x & 0xff) << 16) -+ +/* RGA2_OSD_CTRL1 */ +#define m_RGA2_OSD_CTRL1_SW_OSD_COLOR_SEL (0x1 << 0) +#define m_RGA2_OSD_CTRL1_SW_OSD_FLAG_SEL (0x1 << 1) @@ -1896084,7 +1895935,6 @@ index 000000000..187460833 +#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_DST_UVVDS_MODE (0x1 << 27) -+#define m_RGA2_DST_INFO_SW_SRC1_A1555_ACONFIG_EN (0x1 << 28) + +#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) @@ -1896106,7 +1895956,7 @@ index 000000000..187460833 +#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_DST_UVVDS_MODE(x) ((x & 0x1) << 27) -+#define s_RGA2_DST_INFO_SW_SRC1_A1555_ACONFIG_EN(x) ((x & 0x1) << 28) ++ + +/* RGA_ALPHA_CTRL0 */ +#define m_RGA2_ALPHA_CTRL0_SW_ALPHA_ROP_0 (0x1 << 0) @@ -1896198,15 +1896048,6 @@ index 000000000..187460833 +#define s_RGA2_MMU_CTRL1_SW_ELS_MMU_FLUSH(x) ((x & 0x1) << 13) + +#define RGA2_VSP_BICUBIC_LIMIT 1996 -+#define RGA2_BILINEAR_PREC 12 -+ -+#define RGA2_IOMMU_PREFETCH_SHIFT 16 -+#define RGA2_IOMMU_PREFETCH_MASK 0xffff -+#define RGA2_IOMMU_PREFETCH_ALIGN(x) \ -+ (((x) + RGA2_IOMMU_PREFETCH_MASK) & ~RGA2_IOMMU_PREFETCH_MASK) -+#define RGA2_IOMMU_PREFETCH_ALIGN_DOWN(x) ((x) & ~RGA2_IOMMU_PREFETCH_MASK) -+#define RGA2_IOMMU_PREFETCH_THRESHOLD_MIN (0x1U << RGA2_IOMMU_PREFETCH_SHIFT) -+#define RGA2_IOMMU_PREFETCH_THRESHOLD_MAX (0xffffU << RGA2_IOMMU_PREFETCH_SHIFT) + +union rga2_color_ctrl { + uint32_t value; @@ -1896251,19 +1896092,16 @@ index 000000000..187460833 + diff --git a/drivers/video/rockchip/rga3/include/rga3_reg_info.h b/drivers/video/rockchip/rga3/include/rga3_reg_info.h new file mode 100644 -index 000000000..1f9d66a50 +index 000000000..4db80cfb0 --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga3_reg_info.h -@@ -0,0 +1,524 @@ +@@ -0,0 +1,521 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __REG3_INFO_H__ +#define __REG3_INFO_H__ + +#include "rga_drv.h" + -+#define RGA3_SYS_REG_BASE 0x000 -+#define RGA3_CMD_REG_BASE 0x100 -+ +/* sys reg */ +#define RGA3_SYS_CTRL 0x000 +#define RGA3_CMD_CTRL 0x004 @@ -1896781,10 +1896619,10 @@ index 000000000..1f9d66a50 + diff --git a/drivers/video/rockchip/rga3/include/rga_common.h b/drivers/video/rockchip/rga3/include/rga_common.h new file mode 100644 -index 000000000..4ed75821f +index 000000000..32e83cc9c --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga_common.h -@@ -0,0 +1,88 @@ +@@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1896799,39 +1896637,6 @@ index 000000000..4ed75821f +#include "rga_drv.h" +#include "rga_hw_config.h" + -+#ifdef pr_fmt -+#undef pr_fmt -+#endif -+ -+#define pr_fmt(fmt) "%s: " fmt, "rga" -+ -+#define rga_log(fmt, args...) \ -+ pr_info("%-6d %-6d: " fmt, get_current()->tgid, get_current()->pid, ##args) -+#define rga_err(fmt, args...) \ -+ pr_err("%-6d %-6d: " fmt, get_current()->tgid, get_current()->pid, ##args) -+ -+#define rga_dev_log(dev, fmt, args...) \ -+ dev_info(dev, "%-6d %-6d: " fmt, current->tgid, current->pid, ##args) -+#define rga_dev_err(dev, fmt, args...) \ -+ dev_err(dev, "%-6d %-6d: " fmt, current->tgid, current->pid, ##args) -+ -+#define rga_job_log(job, fmt, args...) \ -+ pr_info("%-6d %-6d: ID[%d]: " fmt, job->session->tgid, job->pid, job->request_id, ##args) -+#define rga_job_err(job, fmt, args...) \ -+ pr_err("%-6d %-6d: ID[%d]: " fmt, job->session->tgid, job->pid, job->request_id, ##args) -+ -+#define rga_req_log(request, fmt, args...) \ -+ pr_info("%-6d %-6d: ID[%d]: " fmt, \ -+ request->session->tgid, request->pid, request->id, ##args) -+#define rga_req_err(request, fmt, args...) \ -+ pr_err("%-6d %-6d: ID[%d]: " fmt, request->session->tgid, request->pid, request->id, ##args) -+ -+#define rga_buf_log(buf, fmt, args...) \ -+ pr_info("%-6d %-6d: handle[%d]: " fmt, \ -+ buf->session->tgid, current->pid, buf->handle, ##args) -+#define rga_buf_err(buf, fmt, args...) \ -+ pr_err("%-6d %-6d: handle[%d]: " fmt, buf->session->tgid, current->pid, buf->handle, ##args) -+ +#define RGA_GET_PAGE_COUNT(size) (((size) >> PAGE_SHIFT) + (((size) & (~PAGE_MASK)) ? 1 : 0)) + +bool rga_is_rgb_format(uint32_t format); @@ -1896853,13 +1896658,10 @@ index 000000000..4ed75821f + +const char *rga_get_format_name(uint32_t format); +const char *rga_get_render_mode_str(uint8_t mode); -+const char *rga_get_store_mode_str(uint32_t mode); -+const char *rga_get_interp_str(uint8_t interp); +const char *rga_get_rotate_mode_str(uint8_t mode); +const char *rga_get_blend_mode_str(enum rga_alpha_blend_mode mode); +const char *rga_get_memory_type_str(uint8_t type); +const char *rga_get_mmu_type_str(enum rga_mmu mmu_type); -+const char *rga_get_dma_data_direction_str(enum dma_data_direction dir); +const char *rga_get_core_name(enum RGA_SCHEDULER_CORE core); + +void rga_convert_addr(struct rga_img_info_t *img, bool before_vir_get_channel); @@ -1896868,14 +1896670,11 @@ index 000000000..4ed75821f + int *yrgb_size, int *uv_size, int *v_size); +void rga_dump_memory_parm(struct rga_memory_parm *parm); +void rga_dump_external_buffer(struct rga_external_buffer *buffer); -+void rga_dump_req(struct rga_request *request, struct rga_req *req); -+ -+unsigned long rga_get_free_pages(gfp_t gfp_mask, unsigned int *order, unsigned long size); + +#endif diff --git a/drivers/video/rockchip/rga3/include/rga_debugger.h b/drivers/video/rockchip/rga3/include/rga_debugger.h new file mode 100644 -index 000000000..cc2966ec5 +index 000000000..c274fe87f --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga_debugger.h @@ -0,0 +1,145 @@ @@ -1896901,7 +1896700,6 @@ index 000000000..cc2966ec5 +extern int RGA_DEBUG_INT_FLAG; +extern int RGA_DEBUG_MM; +extern int RGA_DEBUG_CHECK_MODE; -+extern int RGA_DEBUG_INTERNAL_MODE; +extern int RGA_DEBUG_NONUSE; +extern int RGA_DEBUG_DUMP_IMAGE; + @@ -1897013,6 +1896811,7 @@ index 000000000..cc2966ec5 + +#endif /* #ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER */ + ++void rga_cmd_print_debug_info(struct rga_req *req); +void rga_request_task_debug_info(struct seq_file *m, struct rga_req *req); +#ifdef CONFIG_NO_GKI +void rga_dump_job_image(struct rga_job *dump_job); @@ -1897026,10 +1896825,10 @@ index 000000000..cc2966ec5 + diff --git a/drivers/video/rockchip/rga3/include/rga_dma_buf.h b/drivers/video/rockchip/rga3/include/rga_dma_buf.h new file mode 100644 -index 000000000..05a801c07 +index 000000000..2ff0857a6 --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga_dma_buf.h -@@ -0,0 +1,49 @@ +@@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1897058,33 +1896857,30 @@ index 000000000..05a801c07 +int rga_virtual_memory_check(void *vaddr, u32 w, u32 h, u32 format, int fd); +int rga_dma_memory_check(struct rga_dma_buffer *rga_dma_buffer, struct rga_img_info_t *img); + -+int rga_dma_map_phys_addr(phys_addr_t phys_addr, size_t size, struct rga_dma_buffer *buffer, -+ enum dma_data_direction dir, struct device *map_dev); -+void rga_dma_unmap_phys_addr(struct rga_dma_buffer *buffer); -+ -+int rga_dma_map_sgt(struct sg_table *sgt, struct rga_dma_buffer *buffer, -+ enum dma_data_direction dir, struct device *map_dev); -+void rga_dma_unmap_sgt(struct rga_dma_buffer *buffer); ++int rga_iommu_map_sgt(struct sg_table *sgt, size_t size, ++ struct rga_dma_buffer *buffer, ++ struct device *rga_dev); ++int rga_iommu_map(phys_addr_t paddr, size_t size, ++ struct rga_dma_buffer *buffer, ++ struct device *rga_dev); ++void rga_iommu_unmap(struct rga_dma_buffer *buffer); + +int rga_dma_map_buf(struct dma_buf *dma_buf, struct rga_dma_buffer *rga_dma_buffer, -+ enum dma_data_direction dir, struct device *map_dev); ++ enum dma_data_direction dir, struct device *rga_dev); +int rga_dma_map_fd(int fd, struct rga_dma_buffer *rga_dma_buffer, -+ enum dma_data_direction dir, struct device *map_dev); ++ enum dma_data_direction dir, struct device *rga_dev); +void rga_dma_unmap_buf(struct rga_dma_buffer *rga_dma_buffer); + +void rga_dma_sync_flush_range(void *pstart, void *pend, struct rga_scheduler_t *scheduler); + -+struct rga_dma_buffer *rga_dma_alloc_coherent(struct rga_scheduler_t *scheduler, int size); -+int rga_dma_free(struct rga_dma_buffer *buffer); -+ +#endif /* #ifndef __RGA3_DMA_BUF_H__ */ + diff --git a/drivers/video/rockchip/rga3/include/rga_drv.h b/drivers/video/rockchip/rga3/include/rga_drv.h new file mode 100644 -index 000000000..181dbe07a +index 000000000..e9743a403 --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga_drv.h -@@ -0,0 +1,499 @@ +@@ -0,0 +1,463 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1897156,7 +1896952,6 @@ index 000000000..181dbe07a + +/* load interval: 1000ms */ +#define RGA_LOAD_INTERVAL_US 1000000 -+#define RGA_LOAD_ACTIVE_MAX_US 5000000 + +/* timer interval: 1000ms */ +#define RGA_TIMER_INTERVAL_NS 1000000000 @@ -1897175,8 +1896970,8 @@ index 000000000..181dbe07a + +#define DRIVER_MAJOR_VERISON 1 +#define DRIVER_MINOR_VERSION 3 -+#define DRIVER_REVISION_VERSION 9 -+#define DRIVER_PATCH_VERSION g_i ++#define DRIVER_REVISION_VERSION 1 ++#define DRIVER_PATCH_VERSION + +#define DRIVER_VERSION (STR(DRIVER_MAJOR_VERISON) "." STR(DRIVER_MINOR_VERSION) \ + "." STR(DRIVER_REVISION_VERSION) STR(DRIVER_PATCH_VERSION)) @@ -1897202,6 +1896997,14 @@ index 000000000..181dbe07a +extern struct rga_drvdata_t *rga_drvdata; + +enum { ++ RGA3_SCHEDULER_CORE0 = 1 << 0, ++ RGA3_SCHEDULER_CORE1 = 1 << 1, ++ RGA2_SCHEDULER_CORE0 = 1 << 2, ++ RGA_CORE_MASK = 0x7, ++ RGA_NONE_CORE = 0x0, ++}; ++ ++enum { + RGA_CMD_SLAVE = 1, + RGA_CMD_MASTER = 2, +}; @@ -1897228,12 +1897031,6 @@ index 000000000..181dbe07a + RGA_JOB_STATE_ABORT, +}; + -+enum RGA_DEVICE_TYPE { -+ RGA_DEVICE_RGA2 = 0, -+ RGA_DEVICE_RGA3, -+ RGA_DEVICE_BUTT, -+}; -+ +struct rga_iommu_dma_cookie { + enum iommu_dma_cookie_type type; + @@ -1897253,14 +1897050,13 @@ index 000000000..181dbe07a + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach; + struct sg_table *sgt; -+ void *vaddr; ++ void *vmap_ptr; + + struct iommu_domain *domain; + + enum dma_data_direction dir; + + dma_addr_t iova; -+ dma_addr_t dma_addr; + unsigned long size; + /* + * The offset of the first page of the sgt. @@ -1897269,11 +1897065,8 @@ index 000000000..181dbe07a + */ + size_t offset; + -+ /* -+ * The device used by dma-buf mapping, which usually corresponds to the -+ * default domain or the current device. -+ */ -+ struct device *map_dev; ++ /* The scheduler of the mapping */ ++ struct rga_scheduler_t *scheduler; +}; + +struct rga_virt_addr { @@ -1897282,7 +1897075,6 @@ index 000000000..181dbe07a + struct page **pages; + int pages_order; + int page_count; -+ /* Actual effective size */ + unsigned long size; + + /* The offset of the first page of the virtual address */ @@ -1897318,9 +1897110,6 @@ index 000000000..181dbe07a + + struct kref refcount; + struct rga_session *session; -+ -+ /* The scheduler of the mapping */ -+ struct rga_scheduler_t *scheduler; +}; + +struct rga_scheduler_t; @@ -1897331,12 +1897120,6 @@ index 000000000..181dbe07a + pid_t tgid; + + char *pname; -+ -+ ktime_t last_active; -+ -+ bool release; -+ struct rw_semaphore release_rwsem; -+ struct kref refcount; +}; + +struct rga_job_buffer { @@ -1897363,17 +1897146,6 @@ index 000000000..181dbe07a + int page_count; +}; + -+struct rga_job_timestamp { -+ ktime_t init; -+ ktime_t insert; -+ ktime_t hw_execute; -+ ktime_t hw_done; -+ ktime_t done; -+ -+ /* The time only for hrtimer to calculate the load */ -+ ktime_t hw_recode; -+}; -+ +struct rga_job { + struct list_head head; + @@ -1897381,7 +1897153,7 @@ index 000000000..181dbe07a + struct rga_session *session; + + struct rga_req rga_command_base; -+ struct rga_dma_buffer *cmd_buf; ++ uint32_t cmd_reg[32 * 8]; + struct rga_full_csc full_csc; + struct rga_csc_clip full_csc_clip; + struct rga_pre_intr_info pre_intr_info; @@ -1897396,8 +1897168,11 @@ index 000000000..181dbe07a + struct mm_struct *mm; + + /* job time stamp */ -+ struct rga_job_timestamp timestamp; -+ ++ ktime_t timestamp; ++ /* The time when the job is actually executed on the hardware */ ++ ktime_t hw_running_time; ++ /* The time only for hrtimer to calculate the load */ ++ ktime_t hw_recoder_time; + unsigned int flags; + int request_id; + int priority; @@ -1897411,8 +1897186,6 @@ index 000000000..181dbe07a + uint32_t intr_status; + uint32_t hw_status; + uint32_t cmd_status; -+ -+ uint32_t work_cycle; +}; + +struct rga_backend_ops { @@ -1897421,7 +1897194,6 @@ index 000000000..181dbe07a + int (*init_reg)(struct rga_job *job); + void (*soft_reset)(struct rga_scheduler_t *scheduler); + int (*read_back_reg)(struct rga_job *job, struct rga_scheduler_t *scheduler); -+ int (*read_status)(struct rga_job *job, struct rga_scheduler_t *scheduler); + int (*irq)(struct rga_scheduler_t *scheduler); + int (*isr_thread)(struct rga_job *job, struct rga_scheduler_t *scheduler); +}; @@ -1897436,7 +1897208,7 @@ index 000000000..181dbe07a + void __iomem *rga_base; + struct rga_iommu_info *iommu_info; + -+ struct clk_bulk_data *clks; ++ struct clk *clks[RGA_MAX_BUS_CLK]; + int num_clks; + + enum rga_scheduler_status status; @@ -1897446,11 +1897218,8 @@ index 000000000..181dbe07a + 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; -+ unsigned long hw_issues_mask; -+ + int job_count; + int irq; + struct rga_version_t version; @@ -1897475,7 +1897244,6 @@ index 000000000..181dbe07a + int32_t release_fence_fd; + struct dma_fence *release_fence; + spinlock_t fence_lock; -+ struct work_struct fence_work; + + wait_queue_head_t finished_wq; + @@ -1897527,7 +1897295,6 @@ index 000000000..181dbe07a + + struct rga_scheduler_t *scheduler[RGA_MAX_SCHEDULER]; + int num_of_scheduler; -+ int device_count[RGA_DEVICE_BUTT]; + /* The scheduler_index used by default for memory mapping. */ + int map_scheduler_index; + struct rga_mmu_base *mmu_base; @@ -1897548,9 +1897315,6 @@ index 000000000..181dbe07a +#ifdef CONFIG_ROCKCHIP_RGA_DEBUGGER + struct rga_debugger *debugger; +#endif -+ -+ bool shutdown; -+ struct rw_semaphore rwsem; +}; + +struct rga_irqs_data_t { @@ -1897560,9 +1897324,8 @@ index 000000000..181dbe07a +}; + +struct rga_match_data_t { -+ enum RGA_DEVICE_TYPE device_type; -+ -+ const struct rga_backend_ops *ops; ++ const char * const *clks; ++ int num_clks; +}; + +static inline int rga_read(int offset, struct rga_scheduler_t *scheduler) @@ -1897578,15 +1897341,12 @@ index 000000000..181dbe07a +int rga_power_enable(struct rga_scheduler_t *scheduler); +int rga_power_disable(struct rga_scheduler_t *scheduler); + -+int rga_session_put(struct rga_session *session); -+void rga_session_get(struct rga_session *session); -+ +int rga_kernel_commit(struct rga_req *cmd); + +#endif /* __LINUX_RGA_FENCE_H_ */ diff --git a/drivers/video/rockchip/rga3/include/rga_fence.h b/drivers/video/rockchip/rga3/include/rga_fence.h new file mode 100644 -index 000000000..75c7c2292 +index 000000000..7e3bbeebb --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga_fence.h @@ -0,0 +1,101 @@ @@ -1897650,12 +1897410,12 @@ index 000000000..75c7c2292 +#else +static inline struct dma_fence *rga_dma_fence_alloc(void) +{ -+ return ERR_PTR(-EINVAL); ++ return NULL; +} + +static inline int rga_dma_fence_get_fd(struct dma_fence *fence) +{ -+ return -1; ++ return 0; +} + +static inline struct dma_fence *rga_get_dma_fence_from_fd(int fence_fd) @@ -1897672,7 +1897432,7 @@ index 000000000..75c7c2292 + dma_fence_func_t func, + void *private) +{ -+ return -EINVAL; ++ return 0; +} + +static inline void rga_dma_fence_put(struct dma_fence *fence) @@ -1897685,7 +1897445,7 @@ index 000000000..75c7c2292 + +static inline int rga_dma_fence_get_status(struct dma_fence *fence) +{ -+ return -EINVAL; ++ return 0; +} + +#endif /* #ifdef CONFIG_SYNC_FILE */ @@ -1897693,10 +1897453,10 @@ index 000000000..75c7c2292 +#endif /* __LINUX_RGA_FENCE_H_ */ diff --git a/drivers/video/rockchip/rga3/include/rga_hw_config.h b/drivers/video/rockchip/rga3/include/rga_hw_config.h new file mode 100644 -index 000000000..34f48e004 +index 000000000..46f7531aa --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga_hw_config.h -@@ -0,0 +1,95 @@ +@@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1897719,16 +1897479,9 @@ index 000000000..34f48e004 + RGA_RASTER_INDEX, + RGA_AFBC16x16_INDEX, + RGA_TILE8x8_INDEX, -+ RGA_TILE4x4_INDEX, -+ RGA_RKFBC64x4_INDEX, -+ RGA_AFBC32x8_INDEX, + RGA_FORMAT_INDEX_BUTT, +}; + -+enum rga_hw_issue { -+ RGA_HW_ISSUE_DIS_AUTO_RST, -+}; -+ +struct rga_win_data { + const char *name; + const uint32_t *formats[RGA_FORMAT_INDEX_BUTT]; @@ -1897775,14 +1897528,7 @@ index 000000000..34f48e004 +extern const struct rga_hw_data rga3_data; +extern const struct rga_hw_data rga2e_data; +extern const struct rga_hw_data rga2e_1106_data; -+extern const struct rga_hw_data rga2e_3506_data; +extern const struct rga_hw_data rga2e_iommu_data; -+extern const struct rga_hw_data rga2p_iommu_data; -+extern const struct rga_hw_data rga2p_lite_1103b_data; -+extern const struct rga_hw_data rga2p_iommu_non_fbc_data; -+ -+#define rga_hw_has_issue(scheduler, issue) test_bit(issue, &((scheduler)->hw_issues_mask)) -+#define rga_hw_set_issue_mask(scheduler, issue) set_bit(issue, &((scheduler)->hw_issues_mask)) + +/* Returns false if in range, true otherwise */ +static inline bool rga_hw_out_of_range(const struct rga_rect_range *range, int width, int height) @@ -1897879,10 +1897625,10 @@ index 000000000..b80a1f48b + diff --git a/drivers/video/rockchip/rga3/include/rga_job.h b/drivers/video/rockchip/rga3/include/rga_job.h new file mode 100644 -index 000000000..28bf35bac +index 000000000..0fc776173 --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga_job.h -@@ -0,0 +1,58 @@ +@@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1897898,21 +1897644,18 @@ index 000000000..28bf35bac + +#include "rga_drv.h" + -+#define RGA_CMD_REG_SIZE 256 /* 32 * 8 bit */ -+ +enum job_flags { + RGA_JOB_DONE = 1 << 0, + RGA_JOB_ASYNC = 1 << 1, + RGA_JOB_SYNC = 1 << 2, + RGA_JOB_USE_HANDLE = 1 << 3, + RGA_JOB_UNSUPPORT_RGA_MMU = 1 << 4, -+ RGA_JOB_DEBUG_FAKE_BUFFER = 1 << 5, +}; + +void rga_job_scheduler_dump_info(struct rga_scheduler_t *scheduler); +void rga_job_next(struct rga_scheduler_t *scheduler); +struct rga_job *rga_job_done(struct rga_scheduler_t *scheduler); -+int rga_job_commit(struct rga_req *rga_command_base, struct rga_request *request); ++struct rga_job *rga_job_commit(struct rga_req *rga_command_base, struct rga_request *request); +int rga_job_mpi_commit(struct rga_req *rga_command_base, struct rga_request *request); + +int rga_job_assign(struct rga_job *job); @@ -1897923,8 +1897666,6 @@ index 000000000..28bf35bac + uint32_t id); + +int rga_request_commit(struct rga_request *user_request); -+void rga_request_scheduler_shutdown(struct rga_scheduler_t *scheduler); -+void rga_request_scheduler_abort(struct rga_scheduler_t *scheduler); +void rga_request_session_destroy_abort(struct rga_session *session); +int rga_request_put(struct rga_request *request); +void rga_request_get(struct rga_request *request); @@ -1897943,7 +1897684,7 @@ index 000000000..28bf35bac +#endif /* __LINUX_RKRGA_JOB_H_ */ diff --git a/drivers/video/rockchip/rga3/include/rga_mm.h b/drivers/video/rockchip/rga3/include/rga_mm.h new file mode 100644 -index 000000000..a75f2470b +index 000000000..d68fd75dc --- /dev/null +++ b/drivers/video/rockchip/rga3/include/rga_mm.h @@ -0,0 +1,67 @@ @@ -1897991,7 +1897732,7 @@ index 000000000..a75f2470b + if (buffer == NULL) + return true; + -+ return buffer->map_dev == NULL ? true : false; ++ return buffer->scheduler == NULL ? true : false; +} + +struct rga_internal_buffer *rga_mm_lookup_handle(struct rga_mm *mm_session, uint32_t handle); @@ -1898016,10 +1897757,10 @@ index 000000000..a75f2470b +#endif diff --git a/drivers/video/rockchip/rga3/rga2_reg_info.c b/drivers/video/rockchip/rga3/rga2_reg_info.c new file mode 100644 -index 000000000..9574318b5 +index 000000000..d2e379fa9 --- /dev/null +++ b/drivers/video/rockchip/rga3/rga2_reg_info.c -@@ -0,0 +1,3383 @@ +@@ -0,0 +1,2744 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1898027,6 +1897768,8 @@ index 000000000..9574318b5 + * Author: Huang Lee + */ + ++#define pr_fmt(fmt) "rga2_reg: " fmt ++ +#include "rga2_reg_info.h" +#include "rga_dma_buf.h" +#include "rga_iommu.h" @@ -1898034,13 +1897777,6 @@ index 000000000..9574318b5 +#include "rga_hw_config.h" +#include "rga_debugger.h" + -+enum rga2_scale_mode_reg { -+ RGA2_SCALE_BYPASS = 0x0, -+ RGA2_SCALE_DOWN = 0x1, -+ RGA2_SCALE_UP = 0x2, -+ RGA2_SCALE_FORCE_TILE = 0x3, -+}; -+ +unsigned int rga2_rop_code[256] = { + 0x00000007, 0x00000451, 0x00006051, 0x00800051, + 0x00007041, 0x00800041, 0x00804830, 0x000004f0,//0 @@ -1898123,68 +1897859,16 @@ index 000000000..9574318b5 + 0x00000051, 0x008004d4, 0x00800451, 0x00800007,//f +}; + -+static void rga2_scale_down_bilinear_protect(u32 *param_fix, u32 *src_fix, -+ u32 param, u32 offset, u32 src, u32 dst) -+{ -+ int final_coor, final_diff, final_steps; -+ -+ while (1) { -+ final_coor = offset + param * (dst - 1); -+ final_diff = (src - 1) * (1 << RGA2_BILINEAR_PREC) - final_coor; -+ -+ /* -+ * The hardware requires that the last point of the dst map on -+ * src must not exceed the range of src. -+ */ -+ if (final_diff <= 0) -+ param = param - 1; -+ else -+ break; -+ } -+ -+ /* -+ * The hardware requires that the last point of dst mapping on -+ * src be between the last two points of each row/column, so -+ * actual width/height needs to be modified. -+ */ -+ final_steps = (final_coor & ((1 << RGA2_BILINEAR_PREC) - 1)) ? -+ ((final_coor >> RGA2_BILINEAR_PREC) + 1) : -+ (final_coor >> RGA2_BILINEAR_PREC); -+ -+ *param_fix = param; -+ *src_fix = final_steps + 1; -+} -+ -+static void rag2_scale_down_average_protect(u32 *param_fix, u32 param, -+ u32 src, u32 dst) -+{ -+ /* division Loss */ -+ param = param + 1; -+ -+ /* -+ * Ensure that the (src - 1) drop point is to the left of the last -+ * point of the dst. -+ */ -+ while ((param * (src - 1)) > (dst << 16)) -+ param--; -+ -+ *param_fix = param; -+} -+ +static void RGA2_reg_get_param(unsigned char *base, struct rga2_req *msg) +{ + u32 *bRGA_SRC_X_FACTOR; + u32 *bRGA_SRC_Y_FACTOR; -+ u32 *bRGA_SRC_ACT_INFO; + u32 sw, sh; + u32 dw, dh; + u32 param_x, param_y; -+ u32 scale_x_offset, scale_y_offset; -+ u32 src_fix, param_fix; + + bRGA_SRC_X_FACTOR = (u32 *) (base + RGA2_SRC_X_FACTOR_OFFSET); + bRGA_SRC_Y_FACTOR = (u32 *) (base + RGA2_SRC_Y_FACTOR_OFFSET); -+ bRGA_SRC_ACT_INFO = (u32 *) (base + RGA2_SRC_ACT_INFO_OFFSET); + + if (((msg->rotate_mode & 0x3) == 1) || + ((msg->rotate_mode & 0x3) == 3)) { @@ -1898199,32 +1897883,12 @@ index 000000000..9574318b5 + sh = msg->src.act_h; + + if (sw > dw) { -+ if (msg->interp.horiz == RGA_INTERP_LINEAR) { -+ /* default to half_pixel mode. */ -+ param_x = (sw << RGA2_BILINEAR_PREC) / dw; -+ scale_x_offset = (1 << RGA2_BILINEAR_PREC) >> 1; -+ -+ rga2_scale_down_bilinear_protect(¶m_fix, &src_fix, -+ param_x, scale_x_offset, sw, dw); -+ if (DEBUGGER_EN(MSG)) { -+ if (param_x != param_fix) -+ rga_log("scale: Bi-linear horiz factor %#x fix to %#x\n", -+ param_x, param_fix); -+ if (sw != src_fix) -+ rga_log("scale: Bi-linear src_width %d -> %d\n", -+ sw, src_fix); -+ } -+ -+ *bRGA_SRC_X_FACTOR = ((param_fix & 0xffff) | ((scale_x_offset) << 16)); -+ *bRGA_SRC_ACT_INFO = -+ ((*bRGA_SRC_ACT_INFO & (~m_RGA2_SRC_ACT_INFO_SW_SRC_ACT_WIDTH)) | -+ s_RGA2_SRC_ACT_INFO_SW_SRC_ACT_WIDTH((src_fix - 1))); -+ } else { -+ param_x = (dw << 16) / sw; -+ rag2_scale_down_average_protect(¶m_x, param_x, sw, dw); -+ -+ *bRGA_SRC_X_FACTOR |= ((param_x & 0xffff) << 0); -+ } ++#if SCALE_DOWN_LARGE ++ param_x = ((dw) << 16) / (sw) + 1; ++#else ++ param_x = ((dw) << 16) / (sw); ++#endif ++ *bRGA_SRC_X_FACTOR |= ((param_x & 0xffff) << 0); + } else if (sw < dw) { +#if SCALE_UP_LARGE + param_x = ((sw - 1) << 16) / (dw - 1); @@ -1898237,32 +1897901,12 @@ index 000000000..9574318b5 + } + + if (sh > dh) { -+ if (msg->interp.verti == RGA_INTERP_LINEAR) { -+ /* default to half_pixel mode. */ -+ param_y = (sh << RGA2_BILINEAR_PREC) / dh; -+ scale_y_offset = (1 << RGA2_BILINEAR_PREC) >> 1; -+ -+ rga2_scale_down_bilinear_protect(¶m_fix, &src_fix, -+ param_y, scale_y_offset, sh, dh); -+ if (DEBUGGER_EN(MSG)) { -+ if (param_y != param_fix) -+ rga_log("scale: Bi-linear verti factor %#x fix to %#x\n", -+ param_y, param_fix); -+ if (sh != src_fix) -+ rga_log("scale: Bi-linear src_height %d fix to %d\n", -+ sh, src_fix); -+ } -+ -+ *bRGA_SRC_Y_FACTOR = ((param_fix & 0xffff) | ((scale_y_offset) << 16)); -+ *bRGA_SRC_ACT_INFO = -+ ((*bRGA_SRC_ACT_INFO & (~m_RGA2_SRC_ACT_INFO_SW_SRC_ACT_HEIGHT)) | -+ s_RGA2_SRC_ACT_INFO_SW_SRC_ACT_HEIGHT((src_fix - 1))); -+ } else { -+ param_y = (dh << 16) / sh; -+ rag2_scale_down_average_protect(¶m_y, param_y, sh, dh); -+ -+ *bRGA_SRC_Y_FACTOR |= ((param_y & 0xffff) << 0); -+ } ++#if SCALE_DOWN_LARGE ++ param_y = ((dh) << 16) / (sh) + 1; ++#else ++ param_y = ((dh) << 16) / (sh); ++#endif ++ *bRGA_SRC_Y_FACTOR |= ((param_y & 0xffff) << 0); + } else if (sh < dh) { +#if SCALE_UP_LARGE + param_y = ((sh - 1) << 16) / (dh - 1); @@ -1898311,28 +1897955,9 @@ index 000000000..9574318b5 + reg = ((reg & (~m_RGA2_MODE_CTRL_SW_YIN_YOUT_EN)) | + (s_RGA2_MODE_CTRL_SW_YIN_YOUT_EN(msg->yin_yout_en))); + -+ if (msg->src.rd_mode == RGA_TILE4x4_MODE) -+ reg = ((reg & (~m_RGA2_MODE_CTRL_SW_TILE4x4_IN_EN)) | -+ (s_RGA2_MODE_CTRL_SW_TILE4x4_IN_EN(1))); -+ -+ if (msg->dst.rd_mode == RGA_TILE4x4_MODE) -+ reg = ((reg & (~m_RGA2_MODE_CTRL_SW_TILE4x4_OUT_EN)) | -+ (s_RGA2_MODE_CTRL_SW_TILE4x4_OUT_EN(1))); -+ -+ reg = ((reg & (~m_RGA2_MODE_CTRL_SW_TABLE_PRE_FETCH_MODE)) | -+ (s_RGA2_MODE_CTRL_SW_TABLE_PRE_FETCH_MODE(0))); /* 128k */ -+ -+ if (msg->src.rd_mode == RGA_RKFBC_MODE || msg->src.rd_mode == RGA_AFBC32x8_MODE) -+ reg = ((reg & (~m_RGA2_MODE_CTRL_SW_FBC_IN_EN)) | -+ (s_RGA2_MODE_CTRL_SW_FBC_IN_EN(1))); -+ + reg = ((reg & (~m_RGA2_MODE_CTRL_SW_OSD_E)) | + (s_RGA2_MODE_CTRL_SW_OSD_E(msg->osd_info.enable))); + -+ if (msg->gauss_config.size > 0) -+ reg = ((reg & (~m_RGA2_MODE_CTRL_SW_SRC_GAUSS_EN)) | -+ (s_RGA2_MODE_CTRL_SW_SRC_GAUSS_EN(1))); -+ + *bRGA_MODE_CTL = reg; +} + @@ -1898344,10 +1897969,6 @@ index 000000000..9574318b5 + u32 *bRGA_SRC_ACT_INFO; + u32 *bRGA_MASK_ADDR; + u32 *bRGA_SRC_TR_COLOR0, *bRGA_SRC_TR_COLOR1; -+ u32 *bRGA_FBCIN_HEAD_BASE; -+ u32 *bRGA_FBCIN_PAYL_BASE; -+ u32 *bRGA_FBCIN_OFF; -+ u32 *bRGA_FBCIN_HEAD_VIR_INFO; + + u8 disable_uv_channel_en = 0; + @@ -1898359,12 +1897980,9 @@ index 000000000..9574318b5 + + u8 src0_cbcr_swp = 0; + u8 pixel_width = 1; -+ u8 plane_width = 0; -+ u8 pixel_depth = 8; + u32 stride = 0; + u32 uv_stride = 0; + u32 mask_stride = 0; -+ u32 byte_stride = 0; + u32 ydiv = 1, xdiv = 2; + u8 yuv10 = 0; + @@ -1898372,17 +1897990,7 @@ index 000000000..9574318b5 + u32 dw, dh; + u8 rotate_mode; + u8 vsp_scale_mode = 0; -+ u8 vsd_scale_mode = 0; -+ u8 hsp_scale_mode = 0; -+ u8 hsd_scale_mode = 0; + u8 scale_w_flag, scale_h_flag; -+ u32 yrgb_offset = 0, uv_offset = 0, v_offset = 0; -+ u32 tile_x_offset = 0; -+ u32 tile_y_offset = 0; -+ u32 tile_block_size; -+ -+ u32 fbc_fmt = 0, fbc_mode = 0; -+ u32 head_base_addr, payload_base_addr; + + bRGA_SRC_INFO = (u32 *) (base + RGA2_SRC_INFO_OFFSET); + @@ -1898398,10 +1898006,15 @@ index 000000000..9574318b5 + bRGA_SRC_TR_COLOR0 = (u32 *) (base + RGA2_SRC_TR_COLOR0_OFFSET); + bRGA_SRC_TR_COLOR1 = (u32 *) (base + RGA2_SRC_TR_COLOR1_OFFSET); + -+ bRGA_FBCIN_HEAD_BASE = (u32 *) (base + RGA2_FBCIN_HEAD_BASE_OFFSET); -+ bRGA_FBCIN_PAYL_BASE = (u32 *) (base + RGA2_FBCIN_PAYL_BASE_OFFSET); -+ bRGA_FBCIN_OFF = (u32 *) (base + RGA2_FBCIN_OFF_OFFSET); -+ bRGA_FBCIN_HEAD_VIR_INFO = (u32 *) (base + RGA2_FBCIN_HEAD_VIR_INFO_OFFSET); ++ if (msg->src.format == RGA_FORMAT_YCbCr_420_SP_10B || ++ msg->src.format == RGA_FORMAT_YCrCb_420_SP_10B || ++ msg->src.format == RGA_FORMAT_YCbCr_422_SP_10B || ++ msg->src.format == RGA_FORMAT_YCrCb_422_SP_10B) { ++ if ((msg->src.act_w == msg->dst.act_w) && ++ (msg->src.act_h == msg->dst.act_h) && ++ (msg->rotate_mode == 0)) ++ msg->rotate_mode = 1 << 6; ++ } + + { + rotate_mode = msg->rotate_mode & 0x3; @@ -1898418,21 +1898031,21 @@ index 000000000..9574318b5 + } + + if (sw > dw) -+ scale_w_flag = RGA2_SCALE_DOWN; ++ scale_w_flag = 1; + else if (sw < dw) -+ scale_w_flag = RGA2_SCALE_UP; ++ scale_w_flag = 2; + else { -+ scale_w_flag = RGA2_SCALE_BYPASS; ++ scale_w_flag = 0; + if (msg->rotate_mode >> 6) + scale_w_flag = 3; + } + + if (sh > dh) -+ scale_h_flag = RGA2_SCALE_DOWN; ++ scale_h_flag = 1; + else if (sh < dh) -+ scale_h_flag = RGA2_SCALE_UP; ++ scale_h_flag = 2; + else { -+ scale_h_flag = RGA2_SCALE_BYPASS; ++ scale_h_flag = 0; + if (msg->rotate_mode >> 6) + scale_h_flag = 3; + } @@ -1898442,68 +1898055,16 @@ index 000000000..9574318b5 + scale_w_flag = 3; + } + -+ if (scale_h_flag == RGA2_SCALE_UP) { -+ switch (msg->interp.verti) { -+ case RGA_INTERP_BICUBIC: -+ /* -+ * VSP scale mode select, HSD > VSD > VSP > HSP -+ * After HSD, VSP needs to check dst_width. -+ */ -+ if (((scale_w_flag == RGA2_SCALE_DOWN) && (dw < RGA2_VSP_BICUBIC_LIMIT)) || -+ (sw < RGA2_VSP_BICUBIC_LIMIT)) { -+ vsp_scale_mode = 0x0; -+ } else { -+ /* force select bi-linear */ -+ rga_err("Horizontal scaling will be forcibly switched to bilinear.\n"); -+ vsp_scale_mode = 0x1; -+ } -+ break; -+ case RGA_INTERP_LINEAR: -+ vsp_scale_mode = 1; -+ break; -+ case RGA_INTERP_DEFAULT: -+ if (((scale_w_flag == RGA2_SCALE_DOWN) && (dw < RGA2_VSP_BICUBIC_LIMIT)) || -+ (sw < RGA2_VSP_BICUBIC_LIMIT)) { -+ vsp_scale_mode = 0x0; -+ } else { -+ vsp_scale_mode = 0x1; -+ } -+ break; -+ } -+ -+ } else if (scale_h_flag == RGA2_SCALE_DOWN) { -+ switch (msg->interp.verti) { -+ case RGA_INTERP_AVERAGE: -+ case RGA_INTERP_DEFAULT: -+ vsd_scale_mode = 0; -+ break; -+ case RGA_INTERP_LINEAR: -+ vsd_scale_mode = 1; -+ -+ break; -+ } -+ } -+ -+ if (scale_w_flag == RGA2_SCALE_UP) { -+ switch (msg->interp.horiz) { -+ case RGA_INTERP_BICUBIC: -+ case RGA_INTERP_DEFAULT: -+ hsp_scale_mode = 0; -+ break; -+ case RGA_INTERP_LINEAR: -+ hsp_scale_mode = 1; -+ break; -+ } -+ } else if (scale_w_flag == RGA2_SCALE_DOWN) { -+ switch (msg->interp.horiz) { -+ case RGA_INTERP_AVERAGE: -+ case RGA_INTERP_DEFAULT: -+ hsd_scale_mode = 0; -+ break; -+ case RGA_INTERP_LINEAR: -+ hsd_scale_mode = 1; -+ break; -+ } ++ /* VSP scale mode select, HSD > VSD > VSP > HSP */ ++ if (scale_h_flag == 0x2) { ++ /* After HSD, VSP needs to check dst_width */ ++ if ((scale_w_flag == 0x1) && (dw < RGA2_VSP_BICUBIC_LIMIT)) ++ vsp_scale_mode = 0x0; ++ else if (sw < RGA2_VSP_BICUBIC_LIMIT) ++ vsp_scale_mode = 0x0; ++ else ++ /* default select bilinear */ ++ vsp_scale_mode = 0x1; + } + + switch (msg->src.format) { @@ -1898543,12 +1898104,30 @@ index 000000000..9574318b5 + pixel_width = 2; + msg->src_trans_mode &= 0x07; + break; ++ case RGA_FORMAT_RGBA_5551: ++ src0_format = 0x5; ++ pixel_width = 2; ++ break; ++ case RGA_FORMAT_RGBA_4444: ++ src0_format = 0x6; ++ pixel_width = 2; ++ break; + case RGA_FORMAT_BGR_565: + src0_format = 0x4; + pixel_width = 2; + msg->src_trans_mode &= 0x07; + src0_rb_swp = 0x1; + break; ++ case RGA_FORMAT_BGRA_5551: ++ src0_format = 0x5; ++ pixel_width = 2; ++ src0_rb_swp = 0x1; ++ break; ++ case RGA_FORMAT_BGRA_4444: ++ src0_format = 0x6; ++ pixel_width = 2; ++ src0_rb_swp = 0x1; ++ break; + + /* ARGB */ + /* @@ -1898582,19 +1898161,23 @@ index 000000000..9574318b5 + case RGA_FORMAT_ARGB_5551: + src0_format = 0x5; + pixel_width = 2; ++ src0_alpha_swp = 1; + break; + case RGA_FORMAT_ABGR_5551: + src0_format = 0x5; + pixel_width = 2; ++ src0_alpha_swp = 1; + src0_rb_swp = 0x1; + break; + case RGA_FORMAT_ARGB_4444: + src0_format = 0x6; + pixel_width = 2; ++ src0_alpha_swp = 1; + break; + case RGA_FORMAT_ABGR_4444: + src0_format = 0x6; + pixel_width = 2; ++ src0_alpha_swp = 1; + src0_rb_swp = 0x1; + break; + @@ -1898625,52 +1898208,44 @@ index 000000000..9574318b5 + + case RGA_FORMAT_YCbCr_422_SP: + src0_format = 0x8; -+ plane_width = 2; -+ xdiv = 2; ++ xdiv = 1; + ydiv = 1; + break; + case RGA_FORMAT_YCbCr_422_P: + src0_format = 0x9; -+ plane_width = 1; + xdiv = 2; + ydiv = 1; + break; + case RGA_FORMAT_YCbCr_420_SP: + src0_format = 0xa; -+ plane_width = 2; -+ xdiv = 2; ++ xdiv = 1; + ydiv = 2; + break; + case RGA_FORMAT_YCbCr_420_P: + src0_format = 0xb; -+ plane_width = 1; + xdiv = 2; + ydiv = 2; + break; + case RGA_FORMAT_YCrCb_422_SP: + src0_format = 0x8; -+ plane_width = 2; -+ xdiv = 2; ++ xdiv = 1; + ydiv = 1; + src0_cbcr_swp = 1; + break; + case RGA_FORMAT_YCrCb_422_P: + src0_format = 0x9; -+ plane_width = 1; + xdiv = 2; + ydiv = 1; + src0_cbcr_swp = 1; + break; + case RGA_FORMAT_YCrCb_420_SP: + src0_format = 0xa; -+ plane_width = 2; -+ xdiv = 2; ++ xdiv = 1; + ydiv = 2; + src0_cbcr_swp = 1; + break; + case RGA_FORMAT_YCrCb_420_P: + src0_format = 0xb; -+ plane_width = 1; + xdiv = 2; + ydiv = 2; + src0_cbcr_swp = 1; @@ -1898678,34 +1898253,26 @@ index 000000000..9574318b5 + + case RGA_FORMAT_YCbCr_420_SP_10B: + src0_format = 0xa; -+ plane_width = 2; -+ pixel_depth = 10; -+ xdiv = 2; ++ xdiv = 1; + ydiv = 2; + yuv10 = 1; + break; + case RGA_FORMAT_YCrCb_420_SP_10B: + src0_format = 0xa; -+ plane_width = 2; -+ pixel_depth = 10; -+ xdiv = 2; ++ xdiv = 1; + ydiv = 2; + src0_cbcr_swp = 1; + yuv10 = 1; + break; + case RGA_FORMAT_YCbCr_422_SP_10B: + src0_format = 0x8; -+ plane_width = 2; -+ pixel_depth = 10; -+ xdiv = 2; ++ xdiv = 1; + ydiv = 1; + yuv10 = 1; + break; + case RGA_FORMAT_YCrCb_422_SP_10B: + src0_format = 0x8; -+ plane_width = 2; -+ pixel_depth = 10; -+ xdiv = 2; ++ xdiv = 1; + ydiv = 1; + src0_cbcr_swp = 1; + yuv10 = 1; @@ -1898718,170 +1898285,28 @@ index 000000000..9574318b5 + xdiv = 1; + ydiv = 1; + break; -+ -+ case RGA_FORMAT_YCbCr_444_SP: -+ src0_format = 0x3; -+ plane_width = 2; -+ xdiv = 1; -+ ydiv = 1; -+ break; -+ case RGA_FORMAT_YCrCb_444_SP: -+ src0_format = 0x3; -+ plane_width = 2; -+ xdiv = 1; -+ ydiv = 1; -+ src0_cbcr_swp = 1; -+ break; + }; + -+ switch (msg->src.rd_mode) { -+ case RGA_RASTER_MODE: -+ if (msg->src.format == RGA_FORMAT_YCbCr_420_SP_10B || -+ msg->src.format == RGA_FORMAT_YCrCb_420_SP_10B || -+ msg->src.format == RGA_FORMAT_YCbCr_422_SP_10B || -+ msg->src.format == RGA_FORMAT_YCrCb_422_SP_10B) -+ /* -+ * Legacy: implicit semantics exist here, 10bit format -+ * width_stride equals byte_stride. -+ */ -+ byte_stride = msg->src.vir_w; -+ else -+ byte_stride = msg->src.vir_w * pixel_width * pixel_depth / 8; -+ -+ stride = ALIGN(byte_stride, 4); -+ uv_stride = ALIGN(msg->src.vir_w / xdiv * plane_width, 4); ++ reg = ++ ((reg & (~m_RGA2_SRC_INFO_SW_SRC_FMT)) | ++ (s_RGA2_SRC_INFO_SW_SRC_FMT(src0_format))); ++ reg = ++ ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_RB_SWAP)) | ++ (s_RGA2_SRC_INFO_SW_SW_SRC_RB_SWAP(src0_rb_swp))); ++ reg = ++ ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_ALPHA_SWAP)) | ++ (s_RGA2_SRC_INFO_SW_SW_SRC_ALPHA_SWAP(src0_alpha_swp))); ++ reg = ++ ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_UV_SWAP)) | ++ (s_RGA2_SRC_INFO_SW_SW_SRC_UV_SWAP(src0_cbcr_swp))); + -+ yrgb_offset = msg->src.y_offset * stride + -+ msg->src.x_offset * pixel_width * pixel_depth / 8; -+ uv_offset = (msg->src.y_offset / ydiv) * uv_stride + -+ (msg->src.x_offset / xdiv * plane_width * pixel_depth / 8); -+ v_offset = uv_offset; ++ if (msg->src1.format == RGA_FORMAT_RGBA_2BPP) ++ reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_CP_ENDIAN)) | ++ (s_RGA2_SRC_INFO_SW_SW_CP_ENDAIN(msg->osd_info.bpp2_info.endian_swap & 1))); + -+ break; -+ -+ case RGA_TILE4x4_MODE: -+ switch (msg->src.format) { -+ case RGA_FORMAT_YCbCr_400: -+ tile_block_size = 16; -+ break; -+ case RGA_FORMAT_YCbCr_420_SP: -+ case RGA_FORMAT_YCrCb_420_SP: -+ tile_block_size = 24; -+ break; -+ case RGA_FORMAT_YCbCr_422_SP: -+ case RGA_FORMAT_YCrCb_422_SP: -+ tile_block_size = 32; -+ break; -+ case RGA_FORMAT_YCbCr_444_SP: -+ case RGA_FORMAT_YCrCb_444_SP: -+ tile_block_size = 48; -+ break; -+ case RGA_FORMAT_YCbCr_420_SP_10B: -+ case RGA_FORMAT_YCrCb_420_SP_10B: -+ tile_block_size = 30; -+ break; -+ case RGA_FORMAT_YCbCr_422_SP_10B: -+ case RGA_FORMAT_YCrCb_422_SP_10B: -+ tile_block_size = 40; -+ break; -+ default: -+ tile_block_size = 16; -+ break; -+ } -+ -+ stride = ALIGN((u32)((msg->src.vir_w * pixel_width) * (tile_block_size / 4)), 4); -+ -+ yrgb_offset = (u32)((msg->src.y_offset / 4) * stride + -+ (msg->src.x_offset / 4) * pixel_width * tile_block_size); -+ uv_offset = 0; -+ v_offset = 0; -+ -+ tile_x_offset = (msg->src.x_offset % 4) & 0x3; -+ tile_y_offset = (msg->src.y_offset % 4) & 0x3; -+ -+ break; -+ -+ case RGA_RKFBC_MODE: -+ switch (msg->src.format) { -+ case RGA_FORMAT_YCbCr_420_SP: -+ case RGA_FORMAT_YCrCb_420_SP: -+ case RGA_FORMAT_YCbCr_420_SP_10B: -+ case RGA_FORMAT_YCrCb_420_SP_10B: -+ fbc_fmt = 0x0; -+ break; -+ case RGA_FORMAT_YCbCr_422_SP: -+ case RGA_FORMAT_YCrCb_422_SP: -+ case RGA_FORMAT_YCbCr_422_SP_10B: -+ case RGA_FORMAT_YCrCb_422_SP_10B: -+ fbc_fmt = 0x1; -+ break; -+ case RGA_FORMAT_YCbCr_444_SP: -+ case RGA_FORMAT_YCrCb_444_SP: -+ fbc_fmt = 0x2; -+ break; -+ } -+ -+ fbc_mode = 0x0; -+ head_base_addr = msg->src.yrgb_addr; -+ payload_base_addr = head_base_addr; -+ stride = ALIGN(msg->src.vir_w, 64) / 64 * 4; -+ -+ break; -+ -+ case RGA_AFBC32x8_MODE: -+ switch (msg->src.format) { -+ case RGA_FORMAT_RGBA_8888: -+ case RGA_FORMAT_BGRA_8888: -+ case RGA_FORMAT_ARGB_8888: -+ case RGA_FORMAT_ABGR_8888: -+ case RGA_FORMAT_RGBX_8888: -+ case RGA_FORMAT_BGRX_8888: -+ case RGA_FORMAT_XRGB_8888: -+ case RGA_FORMAT_XBGR_8888: -+ fbc_fmt = 0x0; -+ break; -+ case RGA_FORMAT_RGB_888: -+ case RGA_FORMAT_BGR_888: -+ fbc_fmt = 0x1; -+ break; -+ } -+ -+ fbc_mode = 0x1; -+ head_base_addr = msg->src.yrgb_addr; -+ payload_base_addr = head_base_addr; -+ stride = ALIGN(msg->src.vir_w, 32) / 32 * 4; -+ -+ break; -+ } -+ -+ if (msg->src.rd_mode == RGA_RKFBC_MODE || msg->src.rd_mode == RGA_AFBC32x8_MODE) { -+ reg = ((reg & (~m_RGA2_SRC_INFO_SW_FBCIN_MODE)) | -+ (s_RGA2_SRC_INFO_SW_FBCIN_MODE(fbc_mode))); -+ -+ reg = ((reg & (~m_RGA2_SRC_INFO_SW_FBCIN_FMT)) | -+ (s_RGA2_SRC_INFO_SW_FBCIN_FMT(fbc_fmt))); -+ } else { -+ reg = ((reg & (~m_RGA2_SRC_INFO_SW_SRC_FMT)) | -+ (s_RGA2_SRC_INFO_SW_SRC_FMT(src0_format))); -+ } -+ -+ reg = -+ ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_RB_SWAP)) | -+ (s_RGA2_SRC_INFO_SW_SW_SRC_RB_SWAP(src0_rb_swp))); -+ reg = -+ ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_ALPHA_SWAP)) | -+ (s_RGA2_SRC_INFO_SW_SW_SRC_ALPHA_SWAP(src0_alpha_swp))); -+ reg = -+ ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_UV_SWAP)) | -+ (s_RGA2_SRC_INFO_SW_SW_SRC_UV_SWAP(src0_cbcr_swp))); -+ -+ if (msg->src1.format == RGA_FORMAT_RGBA_2BPP) -+ reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_CP_ENDIAN)) | -+ (s_RGA2_SRC_INFO_SW_SW_CP_ENDAIN(msg->osd_info.bpp2_info.endian_swap & 1))); -+ -+ reg = -+ ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_CSC_MODE)) | -+ (s_RGA2_SRC_INFO_SW_SW_SRC_CSC_MODE(msg->yuv2rgb_mode))); ++ reg = ++ ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_CSC_MODE)) | ++ (s_RGA2_SRC_INFO_SW_SW_SRC_CSC_MODE(msg->yuv2rgb_mode))); + + reg = + ((reg & (~m_RGA2_SRC_INFO_SW_SW_SRC_ROT_MODE)) | @@ -1898920,49 +1898345,54 @@ index 000000000..9574318b5 + reg = + ((reg & (~m_RGA2_SRC_INFO_SW_SW_YUV10_ROUND_E)) | + (s_RGA2_SRC_INFO_SW_SW_YUV10_ROUND_E((yuv10)))); -+ reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_VSD_MODE_SEL)) | -+ (s_RGA2_SRC_INFO_SW_SW_VSD_MODE_SEL((vsd_scale_mode)))); -+ reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_HSP_MODE_SEL)) | -+ (s_RGA2_SRC_INFO_SW_SW_HSP_MODE_SEL((hsp_scale_mode)))); -+ reg = ((reg & (~m_RGA2_SRC_INFO_SW_SW_HSD_MODE_SEL)) | -+ (s_RGA2_SRC_INFO_SW_SW_HSD_MODE_SEL((hsd_scale_mode)))); + -+ *bRGA_SRC_INFO = reg; -+ if (msg->src.rd_mode == RGA_RKFBC_MODE || msg->src.rd_mode == RGA_AFBC32x8_MODE) { -+ *bRGA_FBCIN_HEAD_BASE = head_base_addr; -+ *bRGA_FBCIN_PAYL_BASE = payload_base_addr; -+ *bRGA_FBCIN_HEAD_VIR_INFO = stride; -+ *bRGA_FBCIN_OFF = msg->src.x_offset | (msg->src.y_offset << 16); -+ *bRGA_SRC_ACT_INFO = (msg->src.act_w - 1) | ((msg->src.act_h - 1) << 16); -+ } else { -+ *bRGA_SRC_BASE0 = (u32)(msg->src.yrgb_addr + yrgb_offset); -+ if (disable_uv_channel_en == 1) { -+ /* -+ * When Y400 as the input format, because the current RGA does -+ * not support closing the access of the UV channel, the address -+ * of the UV channel access is equal to the address of -+ * the Y channel access to ensure that the UV channel can access, -+ * preventing the RGA hardware from reporting errors. -+ */ -+ *bRGA_SRC_BASE1 = *bRGA_SRC_BASE0; -+ *bRGA_SRC_BASE2 = *bRGA_SRC_BASE0; -+ } else { -+ *bRGA_SRC_BASE1 = (u32)(msg->src.uv_addr + uv_offset); -+ *bRGA_SRC_BASE2 = (u32)(msg->src.v_addr + v_offset); -+ } ++ RGA2_reg_get_param(base, msg); + -+ //mask_stride = ((msg->src0_act.width + 31) & ~31) >> 5; -+ mask_stride = msg->rop_mask_stride; -+ *bRGA_SRC_VIR_INFO = (stride >> 2) | (mask_stride << 16); ++ stride = (((msg->src.vir_w * pixel_width) + 3) & ~3) >> 2; ++ uv_stride = ((msg->src.vir_w / xdiv + 3) & ~3); + -+ *bRGA_SRC_ACT_INFO = -+ (msg->src.act_w - 1) | ((msg->src.act_h - 1) << 16) | -+ tile_x_offset << 14 | tile_y_offset << 30; ++ if (disable_uv_channel_en == 1) { ++ /* ++ * When Y400 as the input format, because the current ++ * RGA does not support closing ++ * the access of the UV channel, the address of the UV ++ * channel access is equal to ++ * the address of the Y channel access to ensure that ++ * the UV channel can access, ++ * preventing the RGA hardware from reporting errors. ++ */ ++ *bRGA_SRC_BASE0 = ++ (u32) (msg->src.yrgb_addr + ++ msg->src.y_offset * (stride << 2) + ++ msg->src.x_offset * pixel_width); ++ *bRGA_SRC_BASE1 = *bRGA_SRC_BASE0; ++ *bRGA_SRC_BASE2 = *bRGA_SRC_BASE0; ++ } else { ++ *bRGA_SRC_BASE0 = ++ (u32) (msg->src.yrgb_addr + ++ msg->src.y_offset * (stride << 2) + ++ msg->src.x_offset * pixel_width); ++ *bRGA_SRC_BASE1 = ++ (u32) (msg->src.uv_addr + ++ (msg->src.y_offset / ydiv) * uv_stride + ++ (msg->src.x_offset / xdiv)); ++ *bRGA_SRC_BASE2 = ++ (u32) (msg->src.v_addr + ++ (msg->src.y_offset / ydiv) * uv_stride + ++ (msg->src.x_offset / xdiv)); ++ } ++ ++ //mask_stride = ((msg->src0_act.width + 31) & ~31) >> 5; ++ mask_stride = msg->rop_mask_stride; + -+ *bRGA_MASK_ADDR = (u32) msg->rop_mask_addr; -+ } ++ *bRGA_SRC_VIR_INFO = stride | (mask_stride << 16); + -+ RGA2_reg_get_param(base, msg); ++ *bRGA_SRC_ACT_INFO = ++ (msg->src.act_w - 1) | ((msg->src.act_h - 1) << 16); ++ ++ *bRGA_MASK_ADDR = (u32) msg->rop_mask_addr; ++ ++ *bRGA_SRC_INFO = reg; + + *bRGA_SRC_TR_COLOR0 = msg->color_key_min; + *bRGA_SRC_TR_COLOR1 = msg->color_key_max; @@ -1898970,12 +1898400,9 @@ index 000000000..9574318b5 + +static void RGA2_set_reg_dst_info(u8 *base, struct rga2_req *msg) +{ -+ u32 *bRGA_SRC_FG_COLOR; -+ u32 *bRGA_SRC_BG_COLOR; + u32 *bRGA_DST_INFO; + u32 *bRGA_DST_BASE0, *bRGA_DST_BASE1, *bRGA_DST_BASE2, + *bRGA_SRC_BASE3; -+ u32 *bRGA_TILE4x4_OUT_BASE; + u32 *bRGA_DST_VIR_INFO; + u32 *bRGA_DST_ACT_INFO; + @@ -1898999,38 +1898426,28 @@ index 000000000..9574318b5 + + u8 dst_fmt_yuv400_en = 0; + u8 dst_fmt_y4_en = 0; -+ u8 dst_fmt_y4_lut_en = 0; + u8 dst_nn_quantize_en = 0; + + u32 reg = 0; + u8 spw, dpw; -+ u8 plane_width = 0; + u8 bbp_shift = 0; -+ u32 s_stride = 0, d_stride = 0; ++ u32 s_stride, d_stride; + u32 x_mirr, y_mirr, rot_90_flag; + u32 yrgb_addr, u_addr, v_addr, s_yrgb_addr; + u32 d_uv_stride, x_div, y_div; -+ u32 y_lt_addr = 0, y_ld_addr = 0, y_rt_addr = 0, y_rd_addr = 0; -+ u32 u_lt_addr = 0, u_ld_addr = 0, u_rt_addr = 0, u_rd_addr = 0; -+ u32 v_lt_addr = 0, v_ld_addr = 0, v_rt_addr = 0, v_rd_addr = 0; -+ u32 yrgb_offset = 0, uv_offset = 0, v_offset = 0; -+ u32 tile_x_offset = 0; -+ u32 tile_y_offset = 0; -+ u32 tile_block_size; ++ u32 y_lt_addr, y_ld_addr, y_rt_addr, y_rd_addr; ++ u32 u_lt_addr, u_ld_addr, u_rt_addr, u_rd_addr; ++ u32 v_lt_addr, v_ld_addr, v_rt_addr, v_rd_addr; + + dpw = 1; + x_div = y_div = 1; + + dst_nn_quantize_en = (msg->alpha_rop_flag >> 8) & 0x1; + -+ bRGA_SRC_FG_COLOR = (u32 *) (base + RGA2_SRC_FG_COLOR_OFFSET); -+ bRGA_SRC_BG_COLOR = (u32 *) (base + RGA2_SRC_BG_COLOR_OFFSET); -+ + bRGA_DST_INFO = (u32 *) (base + RGA2_DST_INFO_OFFSET); + bRGA_DST_BASE0 = (u32 *) (base + RGA2_DST_BASE0_OFFSET); + bRGA_DST_BASE1 = (u32 *) (base + RGA2_DST_BASE1_OFFSET); + bRGA_DST_BASE2 = (u32 *) (base + RGA2_DST_BASE2_OFFSET); -+ bRGA_TILE4x4_OUT_BASE = (u32 *) (base + RGA2_TILE4x4_OUT_BASE_OFFSET); + + bRGA_SRC_BASE3 = (u32 *) (base + RGA2_SRC_BASE3_OFFSET); + @@ -1899076,11 +1898493,29 @@ index 000000000..9574318b5 + src1_format = 0x4; + spw = 2; + break; ++ case RGA_FORMAT_RGBA_5551: ++ src1_format = 0x5; ++ spw = 2; ++ break; ++ case RGA_FORMAT_RGBA_4444: ++ src1_format = 0x6; ++ spw = 2; ++ break; + case RGA_FORMAT_BGR_565: + src1_format = 0x4; + spw = 2; + src1_rb_swp = 0x1; + break; ++ case RGA_FORMAT_BGRA_5551: ++ src1_format = 0x5; ++ spw = 2; ++ src1_rb_swp = 0x1; ++ break; ++ case RGA_FORMAT_BGRA_4444: ++ src1_format = 0x6; ++ spw = 2; ++ src1_rb_swp = 0x1; ++ break; + + /* ARGB */ + case RGA_FORMAT_ARGB_8888: @@ -1899108,19 +1898543,23 @@ index 000000000..9574318b5 + case RGA_FORMAT_ARGB_5551: + src1_format = 0x5; + spw = 2; ++ src1_alpha_swp = 1; + break; + case RGA_FORMAT_ABGR_5551: + src1_format = 0x5; + spw = 2; ++ src1_alpha_swp = 1; + src1_rb_swp = 0x1; + break; + case RGA_FORMAT_ARGB_4444: + src1_format = 0x6; + spw = 2; ++ src1_alpha_swp = 1; + break; + case RGA_FORMAT_ABGR_4444: + src1_format = 0x6; + spw = 2; ++ src1_alpha_swp = 1; + src1_rb_swp = 0x1; + break; + case RGA_FORMAT_RGBA_2BPP: @@ -1899130,10 +1898569,6 @@ index 000000000..9574318b5 + bbp_shift = 2; + src1_alpha_swp = msg->osd_info.bpp2_info.ac_swap; + break; -+ case RGA_FORMAT_A8: -+ src1_format = 0x3; -+ spw = 1; -+ break; + default: + spw = 4; + break; @@ -1899149,14 +1898584,6 @@ index 000000000..9574318b5 + ((reg & (~m_RGA2_DST_INFO_SW_SRC1_ALPHA_SWP)) | + (s_RGA2_DST_INFO_SW_SRC1_ALPHA_SWP(src1_alpha_swp))); + -+ if (msg->rgba5551_alpha.flags & 0x1) { -+ reg = ((reg & (~m_RGA2_DST_INFO_SW_SRC1_A1555_ACONFIG_EN)) | -+ (s_RGA2_DST_INFO_SW_SRC1_A1555_ACONFIG_EN(1))); -+ -+ *bRGA_SRC_FG_COLOR = (msg->rgba5551_alpha.alpha1 & 0xff) << 24; -+ *bRGA_SRC_BG_COLOR = (msg->rgba5551_alpha.alpha0 & 0xff) << 24; -+ } -+ + switch (msg->dst.format) { + case RGA_FORMAT_RGBA_8888: + dst_format = 0x0; @@ -1899261,53 +1898688,45 @@ index 000000000..9574318b5 + + case RGA_FORMAT_YCbCr_422_SP: + dst_format = 0x8; -+ plane_width = 2; -+ x_div = 2; ++ x_div = 1; + y_div = 1; + break; + case RGA_FORMAT_YCbCr_422_P: + dst_format = 0x9; -+ plane_width = 1; + x_div = 2; + y_div = 1; + break; + case RGA_FORMAT_YCbCr_420_SP: + dst_format = 0xa; -+ plane_width = 2; -+ x_div = 2; ++ x_div = 1; + y_div = 2; + break; + case RGA_FORMAT_YCbCr_420_P: + dst_format = 0xb; + dst_cbcr_swp = 1; -+ plane_width = 1; + x_div = 2; + y_div = 2; + break; + case RGA_FORMAT_YCrCb_422_SP: + dst_format = 0x8; + dst_cbcr_swp = 1; -+ plane_width = 2; -+ x_div = 2; ++ x_div = 1; + y_div = 1; + break; + case RGA_FORMAT_YCrCb_422_P: + dst_format = 0x9; + dst_cbcr_swp = 1; -+ plane_width = 1; + x_div = 2; + y_div = 1; + break; + case RGA_FORMAT_YCrCb_420_SP: + dst_format = 0xa; + dst_cbcr_swp = 1; -+ plane_width = 2; -+ x_div = 2; ++ x_div = 1; + y_div = 2; + break; + case RGA_FORMAT_YCrCb_420_P: + dst_format = 0xb; -+ plane_width = 1; + x_div = 2; + y_div = 2; + break; @@ -1899321,15 +1898740,6 @@ index 000000000..9574318b5 + case RGA_FORMAT_Y4: + dst_format = 0x8; + dst_fmt_y4_en = 1; -+ dst_fmt_y4_lut_en = 1; -+ dst_fmt_yuv400_en = 1; -+ x_div = 1; -+ y_div = 1; -+ break; -+ -+ case RGA_FORMAT_Y8: -+ dst_format = 0x8; -+ dst_fmt_y4_lut_en = 1; + dst_fmt_yuv400_en = 1; + x_div = 1; + y_div = 1; @@ -1899371,20 +1898781,6 @@ index 000000000..9574318b5 + dst_format = 0xd; + dpw = 2; + break; -+ -+ case RGA_FORMAT_YCbCr_444_SP: -+ dst_format = 0x3; -+ plane_width = 2; -+ x_div = 1; -+ y_div = 1; -+ break; -+ case RGA_FORMAT_YCrCb_444_SP: -+ dst_format = 0x3; -+ plane_width = 2; -+ x_div = 1; -+ y_div = 1; -+ dst_cbcr_swp = 1; -+ break; + }; + + reg = @@ -1899445,14 +1898841,37 @@ index 000000000..9574318b5 + reg = ((reg & (~m_RGA2_DST_INFO_SW_DST_UVVDS_MODE)) | + (s_RGA2_DST_INFO_SW_DST_UVVDS_MODE(msg->uvvds_mode))); + -+ ydither_en = (msg->dst.format == RGA_FORMAT_Y4 || -+ msg->dst.format == RGA_FORMAT_Y8) ++ ydither_en = (msg->dst.format == RGA_FORMAT_Y4) + && ((msg->alpha_rop_flag >> 6) & 0x1); + + *bRGA_DST_INFO = reg; + ++ s_stride = (((msg->src1.vir_w * spw >> bbp_shift) + 3) & ~3) >> 2; ++ d_stride = ((msg->dst.vir_w * dpw + 3) & ~3) >> 2; ++ ++ if (dst_fmt_y4_en) { ++ /* Y4 output will HALF */ ++ d_stride = ((d_stride + 1) & ~1) >> 1; ++ } ++ ++ d_uv_stride = (d_stride << 2) / x_div; ++ ++ *bRGA_DST_VIR_INFO = d_stride | (s_stride << 16); ++ if ((msg->dst.vir_w % 2 != 0) && ++ (msg->dst.act_w == msg->src.act_w) ++ && (msg->dst.act_h == msg->src.act_h) ++ && (msg->dst.format == RGA_FORMAT_BGR_888 ++ || msg->dst.format == RGA_FORMAT_RGB_888)) ++ *bRGA_DST_ACT_INFO = ++ (msg->dst.act_w) | ((msg->dst.act_h - 1) << 16); ++ else ++ *bRGA_DST_ACT_INFO = ++ (msg->dst.act_w - 1) | ((msg->dst.act_h - 1) << 16); ++ s_stride <<= 2; ++ d_stride <<= 2; ++ + if (((msg->rotate_mode & 0xf) == 0) || -+ ((msg->rotate_mode & 0xf) == 1)) { ++ ((msg->rotate_mode & 0xf) == 1)) { + x_mirr = 0; + y_mirr = 0; + } else { @@ -1899466,22 +1898885,22 @@ index 000000000..9574318b5 + + if (ydither_en) { + if (x_mirr && y_mirr) { -+ rga_err("ydither mode do not support rotate x_mirr=%d,y_mirr=%d\n", ++ pr_err("ydither mode do not support rotate x_mirr=%d,y_mirr=%d\n", + x_mirr, y_mirr); + } + + if (msg->dst.act_w != msg->src.act_w) -+ rga_err("ydither mode do not support x dir scale\n"); ++ pr_err("ydither mode do not support x dir scale\n"); + + if (msg->dst.act_h != msg->src.act_h) -+ rga_err("ydither mode do not support y dir scale\n"); ++ pr_err("ydither mode do not support y dir scale\n"); + } + -+ if (dst_fmt_y4_lut_en) { ++ if (dst_fmt_y4_en) { + *RGA_DST_Y4MAP_LUT0 = (msg->gr_color.gr_x_r & 0xffff) | -+ (msg->gr_color.gr_x_g << 16); ++ (msg->gr_color.gr_x_g << 16); + *RGA_DST_Y4MAP_LUT1 = (msg->gr_color.gr_y_r & 0xffff) | -+ (msg->gr_color.gr_y_g << 16); ++ (msg->gr_color.gr_y_g << 16); + } + + if (dst_nn_quantize_en) { @@ -1899493,143 +1898912,67 @@ index 000000000..9574318b5 + (msg->gr_color.gr_y_b << 20); + } + -+ s_stride = (((msg->src1.vir_w * spw >> bbp_shift) + 3) & ~3); -+ + s_yrgb_addr = + (u32) msg->src1.yrgb_addr + (msg->src1.y_offset * s_stride) + + (msg->src1.x_offset * spw >> bbp_shift); -+ *bRGA_SRC_BASE3 = s_yrgb_addr; -+ -+ /* Warning */ -+ line_width_real = dst_fmt_y4_en ? ((msg->dst.act_w) >> 1) : msg->dst.act_w; -+ -+ switch (msg->dst.rd_mode) { -+ case RGA_RASTER_MODE: -+ d_stride = ALIGN(msg->dst.vir_w * dpw, 4); -+ /* Y4 output will HALF */ -+ if (dst_fmt_y4_en) -+ d_stride = ALIGN(d_stride, 2) >> 1; -+ d_uv_stride = ALIGN(d_stride / x_div * plane_width, 4); -+ -+ yrgb_offset = msg->dst.y_offset * d_stride + msg->dst.x_offset * dpw; -+ uv_offset = (msg->dst.y_offset / y_div) * d_uv_stride + -+ (msg->dst.x_offset / x_div * plane_width); -+ v_offset = uv_offset; -+ -+ yrgb_addr = (u32)msg->dst.yrgb_addr + yrgb_offset; -+ u_addr = (u32)msg->dst.uv_addr + uv_offset; -+ v_addr = (u32)msg->dst.v_addr + v_offset; -+ -+ y_lt_addr = yrgb_addr; -+ u_lt_addr = u_addr; -+ v_lt_addr = v_addr; -+ -+ /* -+ * YUV packet mode is a new format, and the write behavior during -+ * rotation is different from the old format. -+ */ -+ if (rga_is_yuv422_packed_format(msg->dst.format)) { -+ y_ld_addr = yrgb_addr + (msg->dst.act_h - 1) * (d_stride); -+ y_rt_addr = yrgb_addr + (msg->dst.act_w * 2 - 1); -+ y_rd_addr = y_ld_addr + (msg->dst.act_w * 2 - 1); -+ } else if (rga_is_yuv420_packed_format(msg->dst.format)) { -+ y_ld_addr = (u32)msg->dst.yrgb_addr + -+ ((msg->dst.y_offset + (msg->dst.act_h - 1)) * d_stride) + -+ msg->dst.x_offset; -+ y_rt_addr = yrgb_addr + (msg->dst.act_w * 2 - 1); -+ y_rd_addr = y_ld_addr + (msg->dst.act_w - 1); -+ } else { -+ /* 270 degree & Mirror V */ -+ y_ld_addr = yrgb_addr + (msg->dst.act_h - 1) * (d_stride); -+ /* 90 degree & Mirror H */ -+ y_rt_addr = yrgb_addr + (line_width_real - 1) * dpw; -+ /* 180 degree */ -+ y_rd_addr = y_ld_addr + (line_width_real - 1) * dpw; -+ } -+ -+ u_ld_addr = u_addr + ((msg->dst.act_h / y_div) - 1) * (d_uv_stride); -+ v_ld_addr = v_addr + ((msg->dst.act_h / y_div) - 1) * (d_uv_stride); -+ -+ u_rt_addr = u_addr + (msg->dst.act_w / x_div * plane_width) - 1; -+ v_rt_addr = v_addr + (msg->dst.act_w / x_div * plane_width) - 1; -+ -+ u_rd_addr = u_ld_addr + (msg->dst.act_w / x_div * plane_width) - 1; -+ v_rd_addr = v_ld_addr + (msg->dst.act_w / x_div * plane_width) - 1; -+ -+ break; -+ -+ case RGA_TILE4x4_MODE: -+ switch (msg->dst.format) { -+ case RGA_FORMAT_YCbCr_400: -+ tile_block_size = 16; -+ break; -+ case RGA_FORMAT_YCbCr_420_SP: -+ case RGA_FORMAT_YCrCb_420_SP: -+ tile_block_size = 24; -+ break; -+ case RGA_FORMAT_YCbCr_422_SP: -+ case RGA_FORMAT_YCrCb_422_SP: -+ tile_block_size = 32; -+ break; -+ case RGA_FORMAT_YCbCr_444_SP: -+ case RGA_FORMAT_YCrCb_444_SP: -+ tile_block_size = 48; -+ break; -+ case RGA_FORMAT_YCbCr_420_SP_10B: -+ case RGA_FORMAT_YCrCb_420_SP_10B: -+ tile_block_size = 30; -+ break; -+ case RGA_FORMAT_YCbCr_422_SP_10B: -+ case RGA_FORMAT_YCrCb_422_SP_10B: -+ tile_block_size = 40; -+ break; -+ default: -+ tile_block_size = 16; -+ break; -+ } -+ -+ d_stride = ALIGN((u32)((msg->dst.vir_w * dpw) * (tile_block_size / 4)), 4); + -+ yrgb_offset = (u32)((msg->dst.y_offset / 4) * d_stride + -+ (msg->dst.x_offset / 4) * dpw * tile_block_size); -+ -+ tile_x_offset = (msg->dst.x_offset % 4) & 0x3; -+ tile_y_offset = (msg->dst.y_offset % 4) & 0x3; ++ *bRGA_SRC_BASE3 = s_yrgb_addr; + -+ y_lt_addr = (u32)msg->dst.yrgb_addr + yrgb_offset; -+ y_ld_addr = y_lt_addr + -+ (msg->dst.act_h / 4 - ((msg->dst.act_h % 4 == 0) ? 1 : 0)) * d_stride; -+ y_rt_addr = y_lt_addr + -+ (line_width_real / 4 - ((msg->dst.act_w % 4 == 0) ? 0 : 1)) * dpw * -+ tile_block_size; -+ y_rd_addr = y_rt_addr + -+ (msg->dst.act_h / 4 - ((msg->dst.act_h % 4 == 0) ? 1 : 0)) * d_stride; ++ if (dst_fmt_y4_en) { ++ yrgb_addr = (u32) msg->dst.yrgb_addr + ++ (msg->dst.y_offset * d_stride) + ++ ((msg->dst.x_offset * dpw) >> 1); ++ } else { ++ yrgb_addr = (u32) msg->dst.yrgb_addr + ++ (msg->dst.y_offset * d_stride) + ++ (msg->dst.x_offset * dpw); ++ } ++ u_addr = (u32) msg->dst.uv_addr + ++ (msg->dst.y_offset / y_div) * d_uv_stride + ++ msg->dst.x_offset / x_div; ++ v_addr = (u32) msg->dst.v_addr + ++ (msg->dst.y_offset / y_div) * d_uv_stride + ++ msg->dst.x_offset / x_div; + -+ u_lt_addr = 0; -+ u_ld_addr = 0; -+ u_rt_addr = 0; -+ u_rd_addr = 0; ++ y_lt_addr = yrgb_addr; ++ u_lt_addr = u_addr; ++ v_lt_addr = v_addr; + -+ v_lt_addr = 0; -+ v_ld_addr = 0; -+ v_rt_addr = 0; -+ v_rd_addr = 0; ++ /* Warning */ ++ line_width_real = ++ dst_fmt_y4_en ? ((msg->dst.act_w) >> 1) : msg->dst.act_w; + -+ break; ++ /* ++ * YUV packet mode is a new format, and the write behavior during ++ * rotation is different from the old format. ++ */ ++ if (rga_is_yuv422_packed_format(msg->dst.format)) { ++ y_ld_addr = yrgb_addr + (msg->dst.act_h - 1) * (d_stride); ++ y_rt_addr = yrgb_addr + (msg->dst.act_w * 2 - 1); ++ y_rd_addr = y_ld_addr + (msg->dst.act_w * 2 - 1); ++ } else if (rga_is_yuv420_packed_format(msg->dst.format)) { ++ y_ld_addr = (u32)msg->dst.yrgb_addr + ++ ((msg->dst.y_offset + (msg->dst.act_h - 1)) * d_stride) + ++ msg->dst.x_offset; ++ y_rt_addr = yrgb_addr + (msg->dst.act_w * 2 - 1); ++ y_rd_addr = y_ld_addr + (msg->dst.act_w - 1); ++ } else { ++ /* 270 degree & Mirror V */ ++ y_ld_addr = yrgb_addr + (msg->dst.act_h - 1) * (d_stride); ++ /* 90 degree & Mirror H */ ++ y_rt_addr = yrgb_addr + (line_width_real - 1) * dpw; ++ /* 180 degree */ ++ y_rd_addr = y_ld_addr + (line_width_real - 1) * dpw; + } + -+ *bRGA_DST_VIR_INFO = (d_stride >> 2) | ((s_stride >> 2) << 16); ++ u_ld_addr = u_addr + ((msg->dst.act_h / y_div) - 1) * (d_uv_stride); ++ v_ld_addr = v_addr + ((msg->dst.act_h / y_div) - 1) * (d_uv_stride); + -+ if ((msg->dst.vir_w % 2 != 0) && -+ (msg->dst.act_w == msg->src.act_w) && (msg->dst.act_h == msg->src.act_h) && -+ (msg->dst.format == RGA_FORMAT_BGR_888 || msg->dst.format == RGA_FORMAT_RGB_888)) -+ *bRGA_DST_ACT_INFO = -+ (msg->dst.act_w) | ((msg->dst.act_h - 1) << 16) | -+ tile_x_offset << 14 | tile_y_offset << 30; -+ else -+ *bRGA_DST_ACT_INFO = -+ (msg->dst.act_w - 1) | ((msg->dst.act_h - 1) << 16) | -+ tile_x_offset << 14 | tile_y_offset << 30; ++ u_rt_addr = u_addr + (msg->dst.act_w / x_div) - 1; ++ v_rt_addr = v_addr + (msg->dst.act_w / x_div) - 1; ++ ++ u_rd_addr = u_ld_addr + (msg->dst.act_w / x_div) - 1; ++ v_rd_addr = v_ld_addr + (msg->dst.act_w / x_div) - 1; + + if (rot_90_flag == 0) { + if (y_mirr == 1) { @@ -1899679,45 +1899022,18 @@ index 000000000..9574318b5 + + *bRGA_DST_BASE0 = (u32) yrgb_addr; + -+ switch (msg->dst.rd_mode) { -+ case RGA_RASTER_MODE: -+ if ((msg->dst.format == RGA_FORMAT_YCbCr_420_P) || -+ (msg->dst.format == RGA_FORMAT_YCrCb_420_P)) { -+ if (dst_cbcr_swp == 0) { -+ *bRGA_DST_BASE1 = (u32) v_addr; -+ *bRGA_DST_BASE2 = (u32) u_addr; -+ } else { -+ *bRGA_DST_BASE1 = (u32) u_addr; -+ *bRGA_DST_BASE2 = (u32) v_addr; -+ } ++ if ((msg->dst.format == RGA_FORMAT_YCbCr_420_P) ++ || (msg->dst.format == RGA_FORMAT_YCrCb_420_P)) { ++ if (dst_cbcr_swp == 0) { ++ *bRGA_DST_BASE1 = (u32) v_addr; ++ *bRGA_DST_BASE2 = (u32) u_addr; + } else { + *bRGA_DST_BASE1 = (u32) u_addr; + *bRGA_DST_BASE2 = (u32) v_addr; + } -+ -+ break; -+ case RGA_TILE4x4_MODE: -+ *bRGA_TILE4x4_OUT_BASE = yrgb_addr; -+ -+ break; -+ } -+ -+ if (rot_90_flag == 1) { -+ if (y_mirr == 1) { -+ msg->iommu_prefetch.y_threshold = y_lt_addr >> 16 ? -+ RGA2_IOMMU_PREFETCH_ALIGN_DOWN(y_lt_addr) : -+ RGA2_IOMMU_PREFETCH_THRESHOLD_MIN; -+ msg->iommu_prefetch.uv_threshold = u_lt_addr >> 16 ? -+ RGA2_IOMMU_PREFETCH_ALIGN_DOWN(u_lt_addr) : -+ RGA2_IOMMU_PREFETCH_THRESHOLD_MIN; -+ } else { -+ msg->iommu_prefetch.y_threshold = (y_rd_addr >> 16) == 0xffff ? -+ RGA2_IOMMU_PREFETCH_THRESHOLD_MAX : -+ RGA2_IOMMU_PREFETCH_ALIGN(y_rd_addr); -+ msg->iommu_prefetch.uv_threshold = (u_rd_addr >> 16) == 0xffff ? -+ RGA2_IOMMU_PREFETCH_THRESHOLD_MAX : -+ RGA2_IOMMU_PREFETCH_ALIGN(u_rd_addr); -+ } ++ } else { ++ *bRGA_DST_BASE1 = (u32) u_addr; ++ *bRGA_DST_BASE2 = (u32) v_addr; + } +} + @@ -1900028,50 +1899344,6 @@ index 000000000..9574318b5 + *bRGA_MOSAIC_MODE = (u32)(msg->mosaic_info.mode & 0x7); +} + -+static int RGA_set_reg_gauss(u8 *base, struct rga2_req *msg) -+{ -+ uint32_t *bRGA_GAUSS_COE; -+ uint32_t reg = 0; -+ uint32_t *coe; -+ -+ bRGA_GAUSS_COE = (u32 *)(base + RGA2_GAUSS_COE_OFFSET); -+ -+ if (msg->gauss_config.size != 3) { -+ rga_err("Gaussian blur only support 3x3\n"); -+ return -EINVAL; -+ } -+ -+ coe = kmalloc(sizeof(uint32_t) * msg->gauss_config.size, GFP_KERNEL); -+ if (coe == NULL) { -+ rga_err("Gaussian blur alloc coe buffer error!\n"); -+ return -ENOMEM; -+ } -+ -+ if (unlikely(copy_from_user(coe, -+ u64_to_user_ptr(msg->gauss_config.coe_ptr), -+ sizeof(uint32_t) * msg->gauss_config.size))) { -+ rga_err("Gaussian blur coe copy_from_user failed\n"); -+ -+ kfree(coe); -+ return -EFAULT; -+ } -+ -+ reg = ((reg & (~m_RGA2_GAUSS_COE_SW_COE0)) | -+ (s_RGA2_GAUSS_COE_SW_COE0(coe[0]))); -+ -+ reg = ((reg & (~m_RGA2_GAUSS_COE_SW_COE1)) | -+ (s_RGA2_GAUSS_COE_SW_COE1(coe[1]))); -+ -+ reg = ((reg & (~m_RGA2_GAUSS_COE_SW_COE2)) | -+ (s_RGA2_GAUSS_COE_SW_COE2(coe[2]))); -+ -+ *bRGA_GAUSS_COE = reg; -+ -+ kfree(coe); -+ -+ return 0; -+} -+ +static void RGA2_set_reg_osd(u8 *base, struct rga2_req *msg) +{ + u32 *bRGA_OSD_CTRL0; @@ -1900336,52 +1899608,36 @@ index 000000000..9574318b5 + *bRGA_FADING_CTRL = (num << 8) | offset; +} + -+static void RGA2_set_mmu_reg_info(struct rga_scheduler_t *scheduler, u8 *base, struct rga2_req *msg) ++static void RGA2_set_mmu_reg_info(u8 *base, struct rga2_req *msg) +{ + u32 *bRGA_MMU_CTRL1; + u32 *bRGA_MMU_SRC_BASE; + u32 *bRGA_MMU_SRC1_BASE; + u32 *bRGA_MMU_DST_BASE; + u32 *bRGA_MMU_ELS_BASE; -+ u32 *RGA_PREFETCH_ADDR_TH; + + u32 reg; + -+ switch (scheduler->data->mmu) { -+ case RGA_MMU: -+ bRGA_MMU_CTRL1 = (u32 *) (base + RGA2_MMU_CTRL1_OFFSET); -+ bRGA_MMU_SRC_BASE = (u32 *) (base + RGA2_MMU_SRC_BASE_OFFSET); -+ bRGA_MMU_SRC1_BASE = (u32 *) (base + RGA2_MMU_SRC1_BASE_OFFSET); -+ bRGA_MMU_DST_BASE = (u32 *) (base + RGA2_MMU_DST_BASE_OFFSET); -+ bRGA_MMU_ELS_BASE = (u32 *) (base + RGA2_MMU_ELS_BASE_OFFSET); -+ -+ reg = (msg->mmu_info.src0_mmu_flag & 0xf) | -+ ((msg->mmu_info.src1_mmu_flag & 0xf) << 4) | -+ ((msg->mmu_info.dst_mmu_flag & 0xf) << 8) | -+ ((msg->mmu_info.els_mmu_flag & 0x3) << 12); ++ bRGA_MMU_CTRL1 = (u32 *) (base + RGA2_MMU_CTRL1_OFFSET); ++ bRGA_MMU_SRC_BASE = (u32 *) (base + RGA2_MMU_SRC_BASE_OFFSET); ++ bRGA_MMU_SRC1_BASE = (u32 *) (base + RGA2_MMU_SRC1_BASE_OFFSET); ++ bRGA_MMU_DST_BASE = (u32 *) (base + RGA2_MMU_DST_BASE_OFFSET); ++ bRGA_MMU_ELS_BASE = (u32 *) (base + RGA2_MMU_ELS_BASE_OFFSET); + -+ *bRGA_MMU_CTRL1 = reg; -+ *bRGA_MMU_SRC_BASE = (u32) (msg->mmu_info.src0_base_addr) >> 4; -+ *bRGA_MMU_SRC1_BASE = (u32) (msg->mmu_info.src1_base_addr) >> 4; -+ *bRGA_MMU_DST_BASE = (u32) (msg->mmu_info.dst_base_addr) >> 4; -+ *bRGA_MMU_ELS_BASE = (u32) (msg->mmu_info.els_base_addr) >> 4; ++ reg = (msg->mmu_info.src0_mmu_flag & 0xf) | ++ ((msg->mmu_info.src1_mmu_flag & 0xf) << 4) | ++ ((msg->mmu_info.dst_mmu_flag & 0xf) << 8) | ++ ((msg->mmu_info.els_mmu_flag & 0x3) << 12); + -+ break; -+ case RGA_IOMMU: -+ RGA_PREFETCH_ADDR_TH = (u32 *)(base + RGA2_PREFETCH_ADDR_TH_OFFSET); -+ -+ *RGA_PREFETCH_ADDR_TH = -+ (msg->iommu_prefetch.y_threshold >> RGA2_IOMMU_PREFETCH_SHIFT) | -+ ((msg->iommu_prefetch.uv_threshold >> RGA2_IOMMU_PREFETCH_SHIFT) << 16); -+ break; -+ default: -+ break; -+ } ++ *bRGA_MMU_CTRL1 = reg; ++ *bRGA_MMU_SRC_BASE = (u32) (msg->mmu_info.src0_base_addr) >> 4; ++ *bRGA_MMU_SRC1_BASE = (u32) (msg->mmu_info.src1_base_addr) >> 4; ++ *bRGA_MMU_DST_BASE = (u32) (msg->mmu_info.dst_base_addr) >> 4; ++ *bRGA_MMU_ELS_BASE = (u32) (msg->mmu_info.els_base_addr) >> 4; +} + -+static int rga2_gen_reg_info(struct rga_scheduler_t *scheduler, u8 *base, struct rga2_req *msg) ++static int rga2_gen_reg_info(u8 *base, struct rga2_req *msg) +{ -+ int ret; + u8 dst_nn_quantize_en = 0; + + RGA2_set_mode_ctrl(base, msg); @@ -1900394,37 +1899650,20 @@ index 000000000..9574318b5 + RGA2_set_reg_dst_info(base, msg); + dst_nn_quantize_en = (msg->alpha_rop_flag >> 8) & 0x1; + if (dst_nn_quantize_en != 1) { -+ if ((msg->dst.format != RGA_FORMAT_Y4) && -+ (msg->dst.format != RGA_FORMAT_Y8)) { ++ if ((msg->dst.format != ++ RGA_FORMAT_Y4)) { + RGA2_set_reg_alpha_info(base, msg); -+ if (msg->rgba5551_alpha.flags != 1) -+ RGA2_set_reg_rop_info(base, msg); ++ RGA2_set_reg_rop_info(base, msg); + } + } + if (msg->mosaic_info.enable) + RGA_set_reg_mosaic(base, msg); + if (msg->osd_info.enable) + RGA2_set_reg_osd(base, msg); -+ if (msg->gauss_config.size > 0) { -+ ret = RGA_set_reg_gauss(base, msg); -+ if (ret < 0) -+ return ret; -+ } + + break; + case COLOR_FILL_MODE: + RGA2_set_reg_color_fill(base, msg); -+ /* tile4x4 need a fake input */ -+ if (msg->dst.rd_mode == RGA_TILE4x4_MODE) { -+ msg->src.act_w = msg->dst.act_w; -+ msg->src.act_h = msg->dst.act_h; -+ msg->src.vir_w = msg->dst.vir_w; -+ msg->src.vir_h = msg->dst.vir_h; -+ msg->src.format = RGA_FORMAT_RGBA_8888; -+ msg->src.rd_mode = RGA_RASTER_MODE; -+ -+ RGA2_set_reg_src_info(base, msg); -+ } + RGA2_set_reg_dst_info(base, msg); + RGA2_set_reg_alpha_info(base, msg); + break; @@ -1900439,11 +1899678,11 @@ index 000000000..9574318b5 + RGA2_set_reg_update_patten_buff(base, msg); + break; + default: -+ rga_err("ERROR msg render mode %d\n", msg->render_mode); -+ return -EINVAL; ++ pr_err("ERROR msg render mode %d\n", msg->render_mode); ++ break; + } + -+ RGA2_set_mmu_reg_info(scheduler, base, msg); ++ RGA2_set_mmu_reg_info(base, msg); + + return 0; +} @@ -1900528,27 +1899767,6 @@ index 000000000..9574318b5 + break; + } + -+ if ((req->src.act_w == req->dst.act_w) && -+ (req->src.act_h == req->dst.act_h) && -+ (req->rotate_mode == 0)) { -+ if (req->src.format == RGA_FORMAT_YCbCr_420_SP_10B || -+ req->src.format == RGA_FORMAT_YCrCb_420_SP_10B || -+ req->src.format == RGA_FORMAT_YCbCr_444_SP || -+ req->src.format == RGA_FORMAT_YCrCb_444_SP || -+ req->dst.format == RGA_FORMAT_YCbCr_444_SP || -+ req->dst.format == RGA_FORMAT_YCrCb_444_SP) -+ /* force select to tile mode */ -+ req->rotate_mode = 1 << 6; -+ } -+ -+ if (req->src.rd_mode == RGA_TILE4x4_MODE || -+ req->dst.rd_mode == RGA_TILE4x4_MODE || -+ req->src.rd_mode == RGA_RKFBC_MODE || -+ req->src.rd_mode == RGA_AFBC32x8_MODE) -+ /* force select to tile mode */ -+ req->rotate_mode |= 1 << 6; -+ -+ req->interp = req_rga->interp; + req->LUT_addr = req_rga->LUT_addr; + req->rop_mask_addr = req_rga->rop_mask_addr; + @@ -1900602,8 +1899820,6 @@ index 000000000..9574318b5 + /* RGA2 1106 add */ + memcpy(&req->mosaic_info, &req_rga->mosaic_info, sizeof(req_rga->mosaic_info)); + -+ memcpy(&req->gauss_config, &req_rga->gauss_config, sizeof(req_rga->gauss_config)); -+ + if ((scheduler->data->feature & RGA_YIN_YOUT) && + rga_is_only_y_format(req->src.format) && + rga_is_only_y_format(req->dst.format)) @@ -1900614,8 +1899830,6 @@ index 000000000..9574318b5 + + memcpy(&req->osd_info, &req_rga->osd_info, sizeof(req_rga->osd_info)); + -+ memcpy(&req->rgba5551_alpha, &req_rga->rgba5551_alpha, sizeof(req_rga->rgba5551_alpha)); -+ + if (((req_rga->alpha_rop_flag) & 1)) { + if ((req_rga->alpha_rop_flag >> 3) & 1) { + req->alpha_config.enable = true; @@ -1900659,19 +1899873,12 @@ index 000000000..9574318b5 + req->alpha_config.bg_global_alpha_value = 0xff; + } + } else { -+ req->alpha_config.bg_global_alpha_value = 0xff; ++ req->alpha_config.fg_global_alpha_value = 0xff; + req->alpha_config.bg_global_alpha_value = 0xff; + } + + req->alpha_config.mode = req_rga->PD_mode; + } -+ } else if (req_rga->gauss_config.size > 0) { -+ if (req_rga->feature.global_alpha_en) { -+ req->alpha_config.fg_global_alpha_en = true; -+ req->alpha_config.fg_global_alpha_value = req_rga->fg_global_alpha; -+ } else { -+ req->alpha_config.fg_global_alpha_value = 0xff; -+ } + } + + if (req_rga->mmu_info.mmu_en && (req_rga->mmu_info.mmu_flag & 1) == 1) { @@ -1900713,7 +1899920,7 @@ index 000000000..9574318b5 + } +} + -+static int rga2_soft_reset(struct rga_scheduler_t *scheduler) ++static void rga2_soft_reset(struct rga_scheduler_t *scheduler) +{ + u32 i; + u32 reg; @@ -1900742,63 +1899949,53 @@ index 000000000..9574318b5 + rga_write(RGA_IOMMU_CMD_ENABLE_PAGING, RGA_IOMMU_COMMAND, scheduler); + } + -+ return i; -+} -+ -+static void rga2_soft_reset_print(struct rga_scheduler_t *scheduler) -+{ -+ int ret; -+ -+ ret = rga2_soft_reset(scheduler); -+ if (ret >= RGA_RESET_TIMEOUT) -+ rga_err("%s[%#x] soft reset timeout.\n", -+ rga_get_core_name(scheduler->core), scheduler->core); ++ if (i == RGA_RESET_TIMEOUT) ++ pr_err("RAG2 core[%d] soft reset timeout.\n", scheduler->core); + else -+ rga_log("%s[%#x] soft reset complete.\n", -+ rga_get_core_name(scheduler->core), scheduler->core); ++ pr_info("RGA2 core[%d] soft reset complete.\n", scheduler->core); ++ +} + -+static int rga2_check_param(struct rga_job *job, -+ const struct rga_hw_data *data, const struct rga2_req *req) ++static int rga2_check_param(const struct rga_hw_data *data, const struct rga2_req *req) +{ + if (!((req->render_mode == COLOR_FILL_MODE))) { + if (unlikely(rga_hw_out_of_range(&data->input_range, + req->src.act_w, req->src.act_h))) { -+ rga_job_err(job, "invalid src resolution act_w = %d, act_h = %d\n", ++ pr_err("invalid src resolution act_w = %d, act_h = %d\n", + req->src.act_w, req->src.act_h); + return -EINVAL; + } + + if (unlikely(req->src.vir_w * rga_get_pixel_stride_from_format(req->src.format) > + data->max_byte_stride * 8)) { -+ rga_job_err(job, "invalid src stride, stride = %d, max_byte_stride = %d\n", ++ pr_err("invalid src stride, stride = %d, max_byte_stride = %d\n", + req->src.vir_w, data->max_byte_stride); + return -EINVAL; + } + + if (unlikely(req->src.vir_w < req->src.act_w)) { -+ rga_job_err(job, "invalid src_vir_w act_w = %d, vir_w = %d\n", ++ pr_err("invalid src_vir_w act_w = %d, vir_w = %d\n", + req->src.act_w, req->src.vir_w); + return -EINVAL; + } + } + + if (unlikely(rga_hw_out_of_range(&data->output_range, req->dst.act_w, req->dst.act_h))) { -+ rga_job_err(job, "invalid dst resolution act_w = %d, act_h = %d\n", ++ pr_err("invalid dst resolution act_w = %d, act_h = %d\n", + req->dst.act_w, req->dst.act_h); + return -EINVAL; + } + + if (unlikely(req->dst.vir_w * rga_get_pixel_stride_from_format(req->dst.format) > + data->max_byte_stride * 8)) { -+ rga_err("invalid dst stride, stride = %d, max_byte_stride = %d\n", ++ pr_err("invalid dst stride, stride = %d, max_byte_stride = %d\n", + req->dst.vir_w, data->max_byte_stride); + return -EINVAL; + } + + if (unlikely(req->dst.vir_w < req->dst.act_w)) { + if (req->rotate_mode != 1) { -+ rga_err("invalid dst_vir_w act_h = %d, vir_h = %d\n", ++ pr_err("invalid dst_vir_w act_h = %d, vir_h = %d\n", + req->dst.act_w, req->dst.vir_w); + return -EINVAL; + } @@ -1900807,79 +1900004,83 @@ index 000000000..9574318b5 + return 0; +} + -+static int rga2_align_check(struct rga_job *job, struct rga2_req *req) ++static int rga2_align_check(struct rga2_req *req) +{ + if (rga_is_yuv10bit_format(req->src.format)) -+ if ((req->src.x_offset % 2) || (req->src.y_offset % 2) || -+ (req->src.act_w % 2) || (req->src.act_w % 2)) -+ rga_job_log(job, "err src wstride, 10bit yuv\n"); ++ if ((req->src.vir_w % 16) || (req->src.x_offset % 2) || ++ (req->src.act_w % 2) || (req->src.y_offset % 2) || ++ (req->src.act_h % 2) || (req->src.vir_h % 2)) ++ pr_info("err src wstride, 10bit yuv\n"); + if (rga_is_yuv10bit_format(req->dst.format)) -+ if ((req->dst.x_offset % 2) || (req->dst.y_offset % 2) || -+ (req->dst.act_w % 2) || (req->dst.act_w % 2)) -+ rga_job_log(job, "err dst wstride, 10bit yuv\n"); ++ if ((req->dst.vir_w % 16) || (req->dst.x_offset % 2) || ++ (req->dst.act_w % 2) || (req->dst.y_offset % 2) || ++ (req->dst.act_h % 2) || (req->dst.vir_h % 2)) ++ pr_info("err dst wstride, 10bit yuv\n"); + if (rga_is_yuv8bit_format(req->src.format)) -+ if ((req->src.x_offset % 2) || (req->src.y_offset % 2) || -+ (req->src.act_w % 2) || (req->src.act_w % 2)) -+ rga_job_log(job, "err src wstride, 8bit yuv\n"); ++ if ((req->src.vir_w % 4) || (req->src.x_offset % 2) || ++ (req->src.act_w % 2) || (req->src.y_offset % 2) || ++ (req->src.act_h % 2) || (req->src.vir_h % 2)) ++ pr_info("err src wstride, 8bit yuv\n"); + if (rga_is_yuv8bit_format(req->dst.format)) -+ if ((req->dst.x_offset % 2) || (req->dst.y_offset % 2) || -+ (req->dst.act_w % 2) || (req->dst.act_w % 2)) -+ rga_job_log(job, "err dst wstride, 8bit yuv\n"); ++ if ((req->dst.vir_w % 4) || (req->dst.x_offset % 2) || ++ (req->dst.act_w % 2) || (req->dst.y_offset % 2) || ++ (req->dst.act_h % 2) || (req->dst.vir_h % 2)) ++ pr_info("err dst wstride, 8bit yuv\n"); + + return 0; +} + -+static void print_debug_info(struct rga_job *job, struct rga2_req *req) ++static void print_debug_info(struct rga2_req *req) +{ -+ rga_job_log(job, "render_mode:%s,bitblit_mode=%d,rotate_mode:%s\n", ++ pr_info("render_mode:%s,bitblit_mode=%d,rotate_mode:%s\n", + rga_get_render_mode_str(req->render_mode), req->bitblt_mode, + rga_get_rotate_mode_str(req->rotate_mode)); + -+ rga_job_log(job, "src: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n", ++ 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); -+ rga_job_log(job, "src: xoff=%d yoff=%d format=%s\n", ++ pr_info("src: xoff=%d yoff=%d format=%s\n", + req->src.x_offset, req->src.y_offset, + rga_get_format_name(req->src.format)); + + if (req->src1.yrgb_addr != 0 || req->src1.uv_addr != 0 + || req->src1.v_addr != 0) { -+ rga_job_log(job, "src1: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n", ++ pr_info("src1: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n", + (unsigned long)req->src1.yrgb_addr, + (unsigned long)req->src1.uv_addr, + (unsigned long)req->src1.v_addr, + req->src1.act_w, req->src1.act_h, + req->src1.vir_w, req->src1.vir_h); -+ rga_job_log(job, "src1: xoff=%d yoff=%d format=%s\n", ++ pr_info("src1: xoff=%d yoff=%d format=%s\n", + req->src1.x_offset, req->src1.y_offset, + rga_get_format_name(req->src1.format)); + } + -+ rga_job_log(job, "dst: y=%lx uv=%lx v=%lx aw=%d ah=%d vw=%d vh=%d\n", ++ 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); -+ rga_job_log(job, "dst: xoff=%d yoff=%d format=%s\n", ++ pr_info("dst: xoff=%d yoff=%d format=%s\n", + req->dst.x_offset, req->dst.y_offset, + rga_get_format_name(req->dst.format)); + -+ rga_job_log(job, "mmu: src=%.2x src1=%.2x dst=%.2x els=%.2x\n", ++ pr_info("mmu: src=%.2x src1=%.2x dst=%.2x els=%.2x\n", + req->mmu_info.src0_mmu_flag, req->mmu_info.src1_mmu_flag, + req->mmu_info.dst_mmu_flag, req->mmu_info.els_mmu_flag); -+ rga_job_log(job, "alpha: flag %x mode=%s\n", ++ pr_info("alpha: flag %x mode=%s\n", + req->alpha_rop_flag, rga_get_blend_mode_str(req->alpha_config.mode)); -+ rga_job_log(job, "alpha: pre_multi=[%d,%d] pixl=[%d,%d] glb=[%d,%d]\n", ++ pr_info("alpha: pre_multi=[%d,%d] pixl=[%d,%d] glb=[%d,%d]\n", + req->alpha_config.fg_pre_multiplied, req->alpha_config.bg_pre_multiplied, + req->alpha_config.fg_pixel_alpha_en, req->alpha_config.bg_pixel_alpha_en, + req->alpha_config.fg_global_alpha_en, req->alpha_config.bg_global_alpha_en); -+ rga_job_log(job, "alpha: fg_global_alpha=%x bg_global_alpha=%x\n", ++ pr_info("alpha: fg_global_alpha=%x bg_global_alpha=%x\n", + req->alpha_config.fg_global_alpha_value, req->alpha_config.bg_global_alpha_value); -+ rga_job_log(job, "yuv2rgb mode is %x\n", req->yuv2rgb_mode); ++ pr_info("yuv2rgb mode is %x\n", req->yuv2rgb_mode); +} + +static int rga2_init_reg(struct rga_job *job) @@ -1900891,7 +1900092,7 @@ index 000000000..9574318b5 + + scheduler = job->scheduler; + if (unlikely(scheduler == NULL)) { -+ rga_job_err(job, "failed to get scheduler, %s(%d)\n", __func__, __LINE__); ++ pr_err("failed to get scheduler, %s(%d)\n", __func__, __LINE__); + return -EINVAL; + } + @@ -1900919,34 +1900120,34 @@ index 000000000..9574318b5 + memcpy(&job->pre_intr_info, &job->rga_command_base.pre_intr_info, + sizeof(job->pre_intr_info)); + -+ /* for debug */ -+ if (DEBUGGER_EN(MSG)) -+ print_debug_info(job, &req); -+ + /* check value if legal */ -+ ret = rga2_check_param(job, scheduler->data, &req); ++ ret = rga2_check_param(scheduler->data, &req); + if (ret == -EINVAL) { -+ rga_job_err(job, "req argument is inval\n"); ++ pr_err("req argument is inval\n"); + return ret; + } + -+ rga2_align_check(job, &req); ++ rga2_align_check(&req); ++ ++ /* for debug */ ++ if (DEBUGGER_EN(MSG)) ++ print_debug_info(&req); + + /* RGA2 mmu set */ + if ((req.mmu_info.src0_mmu_flag & 1) || (req.mmu_info.src1_mmu_flag & 1) || + (req.mmu_info.dst_mmu_flag & 1) || (req.mmu_info.els_mmu_flag & 1)) { + if (scheduler->data->mmu != RGA_MMU) { -+ rga_job_err(job, "core[%d] has no MMU, please use physically contiguous memory.\n", -+ scheduler->core); -+ rga_job_err(job, "mmu_flag[src, src1, dst, els] = [0x%x, 0x%x, 0x%x, 0x%x]\n", -+ req.mmu_info.src0_mmu_flag, req.mmu_info.src1_mmu_flag, -+ req.mmu_info.dst_mmu_flag, req.mmu_info.els_mmu_flag); ++ pr_err("core[%d] has no MMU, please use physically contiguous memory.\n", ++ scheduler->core); ++ pr_err("mmu_flag[src, src1, dst, els] = [0x%x, 0x%x, 0x%x, 0x%x]\n", ++ req.mmu_info.src0_mmu_flag, req.mmu_info.src1_mmu_flag, ++ req.mmu_info.dst_mmu_flag, req.mmu_info.els_mmu_flag); + return -EINVAL; + } + + ret = rga_set_mmu_base(job, &req); + if (ret < 0) { -+ rga_job_err(job, "%s, [%d] set mmu info error\n", __func__, ++ pr_err("%s, [%d] set mmu info error\n", __func__, + __LINE__); + return -EFAULT; + } @@ -1900956,20 +1900157,19 @@ index 000000000..9574318b5 + if (scheduler->data->mmu == RGA_IOMMU) + req.CMD_fin_int_enable = 1; + -+ ret = rga2_gen_reg_info(scheduler, (uint8_t *)job->cmd_buf->vaddr, &req); -+ if (ret < 0) { -+ rga_job_err(job, "gen reg info error\n"); ++ if (rga2_gen_reg_info((uint8_t *)job->cmd_reg, &req) == -1) { ++ pr_err("gen reg info error\n"); + return -EINVAL; + } + + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "generate register cost time %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); ++ pr_info("request[%d], generate register cost time %lld us\n", ++ job->request_id, ktime_us_delta(ktime_get(), timestamp)); + + return ret; +} + -+static void rga2_dump_read_back_sys_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) ++static void rga2_dump_read_back_sys_reg(struct rga_scheduler_t *scheduler) +{ + int i; + unsigned long flags; @@ -1900982,15 +1900182,15 @@ index 000000000..9574318b5 + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + -+ rga_job_log(job, "SYS_READ_BACK_REG\n"); ++ pr_info("SYS_READ_BACK_REG\n"); + for (i = 0; i < 6; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", ++ pr_info("0x%04x : %.8x %.8x %.8x %.8x\n", + RGA2_SYS_REG_BASE + i * 0x10, + sys_reg[0 + i * 4], sys_reg[1 + i * 4], + sys_reg[2 + i * 4], sys_reg[3 + i * 4]); +} + -+static void rga2_dump_read_back_csc_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) ++static void rga2_dump_read_back_csc_reg(struct rga_scheduler_t *scheduler) +{ + int i; + unsigned long flags; @@ -1901003,36 +1900203,15 @@ index 000000000..9574318b5 + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + -+ rga_job_log(job, "CSC_READ_BACK_REG\n"); ++ pr_info("CSC_READ_BACK_REG\n"); + for (i = 0; i < 3; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", ++ pr_info("0x%04x : %.8x %.8x %.8x %.8x\n", + RGA2_CSC_REG_BASE + i * 0x10, + csc_reg[0 + i * 4], csc_reg[1 + i * 4], + csc_reg[2 + i * 4], csc_reg[3 + i * 4]); +} + -+static void rga2_dump_read_back_other_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) -+{ -+ int i; -+ unsigned long flags; -+ uint32_t other_reg[4] = {0}; -+ -+ spin_lock_irqsave(&scheduler->irq_lock, flags); -+ -+ for (i = 0; i < 4; i++) -+ other_reg[i] = rga_read(RGA2_OTHER_REG_BASE + i * 4, scheduler); -+ -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ -+ rga_job_log(job, "OTHER_READ_BACK_REG\n"); -+ for (i = 0; i < 1; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", -+ RGA2_OTHER_REG_BASE + i * 0x10, -+ other_reg[0 + i * 4], other_reg[1 + i * 4], -+ other_reg[2 + i * 4], other_reg[3 + i * 4]); -+} -+ -+static void rga2_dump_read_back_cmd_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) ++static void rga2_dump_read_back_cmd_reg(struct rga_scheduler_t *scheduler) +{ + int i; + unsigned long flags; @@ -1901045,43 +1900224,19 @@ index 000000000..9574318b5 + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + -+ rga_job_log(job, "CMD_READ_BACK_REG\n"); ++ pr_info("CMD_READ_BACK_REG\n"); + for (i = 0; i < 8; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", ++ pr_info("0x%04x : %.8x %.8x %.8x %.8x\n", + RGA2_CMD_REG_BASE + i * 0x10, + cmd_reg[0 + i * 4], cmd_reg[1 + i * 4], + cmd_reg[2 + i * 4], cmd_reg[3 + i * 4]); +} + -+static void rga2_dump_read_back_iommu_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) -+{ -+ int i; -+ unsigned long flags; -+ uint32_t cmd_reg[12] = {0}; -+ -+ spin_lock_irqsave(&scheduler->irq_lock, flags); -+ -+ for (i = 0; i < 12; i++) -+ cmd_reg[i] = rga_read(RGA2_IOMMU_REG_BASE + i * 4, scheduler); -+ -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ -+ rga_job_log(job, "IOMMU_READ_BACK_REG\n"); -+ for (i = 0; i < 3; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", -+ RGA2_IOMMU_REG_BASE + i * 0x10, -+ cmd_reg[0 + i * 4], cmd_reg[1 + i * 4], -+ cmd_reg[2 + i * 4], cmd_reg[3 + i * 4]); -+} -+ -+static void rga2_dump_read_back_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) ++static void rga2_dump_read_back_reg(struct rga_scheduler_t *scheduler) +{ -+ rga2_dump_read_back_sys_reg(job, scheduler); -+ rga2_dump_read_back_csc_reg(job, scheduler); -+ if (scheduler->data->version > 0) -+ rga2_dump_read_back_other_reg(job, scheduler); -+ rga2_dump_read_back_cmd_reg(job, scheduler); -+ rga2_dump_read_back_iommu_reg(job, scheduler); ++ rga2_dump_read_back_sys_reg(scheduler); ++ rga2_dump_read_back_csc_reg(scheduler); ++ rga2_dump_read_back_cmd_reg(scheduler); +} + +static void rga2_set_pre_intr_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) @@ -1901145,12 +1900300,8 @@ index 000000000..9574318b5 + int i; + bool master_mode_en; + uint32_t sys_ctrl; -+ uint32_t *cmd; -+ unsigned long flags; + ktime_t now = ktime_get(); + -+ cmd = job->cmd_buf->vaddr; -+ + /* + * Currently there is no iova allocated for storing cmd for the IOMMU device, + * so the iommu device needs to use the slave mode. @@ -1901160,82 +1900311,72 @@ index 000000000..9574318b5 + else + master_mode_en = false; + -+ if (DEBUGGER_EN(REG)) { -+ rga2_dump_read_back_sys_reg(job, scheduler); -+ rga2_dump_read_back_csc_reg(job, scheduler); -+ if (scheduler->data->version > 0) -+ rga2_dump_read_back_other_reg(job, scheduler); -+ -+ rga_job_log(job, "CMD_REG\n"); -+ for (i = 0; i < 8; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", -+ RGA2_CMD_REG_BASE + i * 0x10, -+ cmd[0 + i * 4], cmd[1 + i * 4], -+ cmd[2 + i * 4], cmd[3 + i * 4]); -+ } -+ -+ spin_lock_irqsave(&scheduler->irq_lock, flags); -+ -+ /* sys_reg init */ -+ sys_ctrl = m_RGA2_SYS_CTRL_AUTO_CKG; -+ -+ /* RV1106 need disables these optimizations */ -+ if (scheduler->data == &rga2e_1106_data) -+ sys_ctrl |= m_RGA2_SYS_CTRL_DST_WR_OPT_DIS | m_RGA2_SRC0_YUV420SP_RD_OPT_DIS; -+ -+ if (rga_hw_has_issue(scheduler, RGA_HW_ISSUE_DIS_AUTO_RST)) { -+ /* disable all_finish & cur_finish intr_en */ -+ rga_write(0, RGA2_INT, scheduler); -+ rga_write(0, RGA2_CMD_REG_BASE + RGA2_MODE_CTRL_OFFSET, scheduler); -+ /* replace auto_rst */ -+ rga2_soft_reset(scheduler); -+ } else { -+ sys_ctrl |= m_RGA2_SYS_CTRL_AUTO_RST; -+ } -+ + if (job->pre_intr_info.enable) + rga2_set_pre_intr_reg(job, scheduler); + + if (job->full_csc.flag) + rga2_set_reg_full_csc(job, scheduler); + ++ if (DEBUGGER_EN(REG)) { ++ uint32_t *p; ++ ++ rga2_dump_read_back_sys_reg(scheduler); ++ rga2_dump_read_back_csc_reg(scheduler); ++ ++ p = job->cmd_reg; ++ pr_info("CMD_REG\n"); ++ for (i = 0; i < 8; i++) ++ pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i, ++ p[0 + i * 4], p[1 + i * 4], ++ p[2 + i * 4], p[3 + i * 4]); ++ } ++ + /* All CMD finish int */ + rga_write(rga_read(RGA2_INT, scheduler) | + m_RGA2_INT_ERROR_ENABLE_MASK | m_RGA2_INT_ALL_CMD_DONE_INT_EN, + RGA2_INT, scheduler); + ++ /* sys_reg init */ ++ sys_ctrl = m_RGA2_SYS_CTRL_AUTO_CKG | m_RGA2_SYS_CTRL_AUTO_RST | ++ m_RGA2_SYS_CTRL_RST_PROTECT_P | m_RGA2_SYS_CTRL_DST_WR_OPT_DIS | ++ m_RGA2_SYS_CTRL_SRC0YUV420SP_RD_OPT_DIS; ++ + if (master_mode_en) { + /* master mode */ + sys_ctrl |= s_RGA2_SYS_CTRL_CMD_MODE(1); + ++ /* cmd buffer flush cache to ddr */ ++ rga_dma_sync_flush_range(&job->cmd_reg[0], &job->cmd_reg[32], scheduler); ++ + /* set cmd_addr */ -+ rga_write(job->cmd_buf->dma_addr, RGA2_CMD_BASE, scheduler); ++ rga_write(virt_to_phys(job->cmd_reg), RGA2_CMD_BASE, scheduler); + rga_write(sys_ctrl, RGA2_SYS_CTRL, scheduler); -+ rga_write(rga_read(RGA2_CMD_CTRL, scheduler) | m_RGA2_CMD_CTRL_CMD_LINE_ST_P, -+ RGA2_CMD_CTRL, scheduler); ++ rga_write(m_RGA2_CMD_CTRL_CMD_LINE_ST_P, RGA2_CMD_CTRL, scheduler); + } else { + /* slave mode */ + sys_ctrl |= s_RGA2_SYS_CTRL_CMD_MODE(0) | m_RGA2_SYS_CTRL_CMD_OP_ST_P; + + /* set cmd_reg */ + for (i = 0; i <= 32; i++) -+ rga_write(cmd[i], 0x100 + i * 4, scheduler); ++ rga_write(job->cmd_reg[i], 0x100 + i * 4, scheduler); + + rga_write(sys_ctrl, RGA2_SYS_CTRL, scheduler); + } + -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); ++ if (DEBUGGER_EN(REG)) ++ pr_info("sys_ctrl = %x, int = %x\n", ++ rga_read(RGA2_SYS_CTRL, scheduler), ++ rga_read(RGA2_INT, scheduler)); + + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "set register cost time %lld us\n", -+ ktime_us_delta(ktime_get(), now)); ++ pr_info("request[%d], set register cost time %lld us\n", ++ job->request_id, ktime_us_delta(now, job->timestamp)); + -+ job->timestamp.hw_execute = now; -+ job->timestamp.hw_recode = now; -+ job->session->last_active = now; ++ job->hw_running_time = now; ++ job->hw_recoder_time = now; + + if (DEBUGGER_EN(REG)) -+ rga2_dump_read_back_reg(job, scheduler); ++ rga2_dump_read_back_reg(scheduler); + + return 0; +} @@ -1901246,7 +1900387,7 @@ index 000000000..9574318b5 + u32 reg_version; + + if (!scheduler) { -+ rga_err("scheduler is null\n"); ++ pr_err("scheduler is null\n"); + return -EINVAL; + } + @@ -1901275,83 +1900416,51 @@ index 000000000..9574318b5 +static int rga2_read_back_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) +{ + if (job->rga_command_base.osd_info.enable) { -+ if (scheduler->data->version == 0) { -+ job->rga_command_base.osd_info.cur_flags0 = -+ rga_read(RGA2_OSD_CUR_FLAGS0, scheduler); -+ job->rga_command_base.osd_info.cur_flags1 = -+ rga_read(RGA2_OSD_CUR_FLAGS1, scheduler); -+ } else { -+ job->rga_command_base.osd_info.cur_flags0 = -+ rga_read(RGA2_FIXED_OSD_CUR_FLAGS0, scheduler); -+ job->rga_command_base.osd_info.cur_flags1 = -+ rga_read(RGA2_FIXED_OSD_CUR_FLAGS1, scheduler); -+ } ++ job->rga_command_base.osd_info.cur_flags0 = rga_read(RGA2_OSD_CUR_FLAGS0, ++ scheduler); ++ job->rga_command_base.osd_info.cur_flags1 = rga_read(RGA2_OSD_CUR_FLAGS1, ++ scheduler); + } + + return 0; +} + -+static int rga2_read_status(struct rga_job *job, struct rga_scheduler_t *scheduler) -+{ -+ job->intr_status = rga_read(RGA2_INT, scheduler); -+ job->hw_status = rga_read(RGA2_STATUS2, scheduler); -+ job->cmd_status = rga_read(RGA2_STATUS1, scheduler); -+ job->work_cycle = rga_read(RGA2_WORK_CNT, scheduler); -+ -+ return 0; -+} -+ -+static void rga2_clear_intr(struct rga_scheduler_t *scheduler) -+{ -+ rga_write(rga_read(RGA2_INT, scheduler) | -+ (m_RGA2_INT_ERROR_CLEAR_MASK | -+ m_RGA2_INT_ALL_CMD_DONE_INT_CLEAR | m_RGA2_INT_NOW_CMD_DONE_INT_CLEAR | -+ m_RGA2_INT_LINE_RD_CLEAR | m_RGA2_INT_LINE_WR_CLEAR), -+ RGA2_INT, scheduler); -+} -+ +static int rga2_irq(struct rga_scheduler_t *scheduler) +{ + struct rga_job *job = scheduler->running_job; + + /* The hardware interrupt top-half don't need to lock the scheduler. */ -+ if (job == NULL) { -+ rga2_clear_intr(scheduler); -+ rga_err("core[%d], invalid job, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n", -+ scheduler->core, rga_read(RGA2_INT, scheduler), -+ rga_read(RGA2_STATUS2, scheduler), rga_read(RGA2_STATUS1, scheduler), -+ rga_read(RGA2_WORK_CNT, scheduler), rga_read(RGA2_WORK_CNT, scheduler)); -+ ++ if (job == NULL) + return IRQ_HANDLED; -+ } -+ -+ if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) { -+ rga2_clear_intr(scheduler); + ++ if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) + return IRQ_WAKE_THREAD; -+ } + -+ scheduler->ops->read_status(job, scheduler); ++ job->intr_status = rga_read(RGA2_INT, scheduler); ++ job->hw_status = rga_read(RGA2_STATUS2, scheduler); ++ job->cmd_status = rga_read(RGA2_STATUS1, scheduler); + + if (DEBUGGER_EN(INT_FLAG)) -+ rga_job_log(job, "irq handler, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n", -+ job->intr_status, job->hw_status, job->cmd_status, -+ job->work_cycle, job->work_cycle); ++ pr_info("irq handler, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", ++ job->intr_status, job->hw_status, job->cmd_status); + -+ if (job->intr_status & m_RGA2_INT_ERROR_FLAG_MASK) { ++ if (job->intr_status & ++ (m_RGA2_INT_CUR_CMD_DONE_INT_FLAG | m_RGA2_INT_ALL_CMD_DONE_INT_FLAG)) { ++ set_bit(RGA_JOB_STATE_FINISH, &job->state); ++ } else if (job->intr_status & m_RGA2_INT_ERROR_FLAG_MASK) { + set_bit(RGA_JOB_STATE_INTR_ERR, &job->state); + -+ rga_job_err(job, "irq handler err! INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n", -+ job->intr_status, job->hw_status, job->cmd_status, -+ job->work_cycle, job->work_cycle); -+ ++ pr_err("irq handler err! INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", ++ job->intr_status, job->hw_status, job->cmd_status); + scheduler->ops->soft_reset(scheduler); -+ } else if (job->intr_status & -+ (m_RGA2_INT_CUR_CMD_DONE_INT_FLAG | m_RGA2_INT_ALL_CMD_DONE_INT_FLAG)) { -+ set_bit(RGA_JOB_STATE_FINISH, &job->state); + } + -+ rga2_clear_intr(scheduler); ++ /*clear INTR */ ++ rga_write(rga_read(RGA2_INT, scheduler) | ++ (m_RGA2_INT_ERROR_CLEAR_MASK | ++ m_RGA2_INT_ALL_CMD_DONE_INT_CLEAR | m_RGA2_INT_NOW_CMD_DONE_INT_CLEAR | ++ m_RGA2_INT_LINE_RD_CLEAR | m_RGA2_INT_LINE_WR_CLEAR), ++ RGA2_INT, scheduler); + + return IRQ_WAKE_THREAD; +} @@ -1901359,33 +1900468,27 @@ index 000000000..9574318b5 +static int rga2_isr_thread(struct rga_job *job, struct rga_scheduler_t *scheduler) +{ + if (DEBUGGER_EN(INT_FLAG)) -+ rga_job_log(job, "isr thread, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", ++ pr_info("isr thread, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", + rga_read(RGA2_INT, scheduler), + rga_read(RGA2_STATUS2, scheduler), + rga_read(RGA2_STATUS1, scheduler)); + + if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) { + if (job->hw_status & m_RGA2_STATUS2_RPP_ERROR) -+ rga_job_err(job, "RGA current status: rpp error!\n"); ++ pr_err("RGA current status: rpp error!\n"); + if (job->hw_status & m_RGA2_STATUS2_BUS_ERROR) -+ rga_job_err(job, "RGA current status: bus error!\n"); ++ pr_err("RGA current status: bus error!\n"); + + if (job->intr_status & m_RGA2_INT_ERROR_INT_FLAG) { -+ rga_job_err(job, "RGA bus error intr, please check your configuration and buffer.\n"); ++ pr_err("RGA bus error intr, please check your configuration and buffer.\n"); + job->ret = -EFAULT; + } else if (job->intr_status & m_RGA2_INT_MMU_INT_FLAG) { -+ rga_job_err(job, "mmu failed, please check size of the buffer or whether the buffer has been freed.\n"); -+ job->ret = -EACCES; -+ } else if (job->intr_status & m_RGA2_INT_SCL_ERROR_INTR) { -+ rga_job_err(job, "scale failed, check scale config or formula.\n"); -+ job->ret = -EACCES; -+ } else if (job->intr_status & m_RGA2_INT_FBCIN_DEC_ERROR) { -+ rga_job_err(job, "FBC decode failed, please check if the source data is FBC data.\n"); ++ pr_err("mmu failed, please check size of the buffer or whether the buffer has been freed.\n"); + job->ret = -EACCES; + } + + if (job->ret == 0) { -+ rga_job_err(job, "rga intr error[0x%x]!\n", job->intr_status); ++ pr_err("rga intr error[0x%x]!\n", job->intr_status); + job->ret = -EFAULT; + } + } @@ -1901397,18 +1900500,17 @@ index 000000000..9574318b5 + .get_version = rga2_get_version, + .set_reg = rga2_set_reg, + .init_reg = rga2_init_reg, -+ .soft_reset = rga2_soft_reset_print, ++ .soft_reset = rga2_soft_reset, + .read_back_reg = rga2_read_back_reg, -+ .read_status = rga2_read_status, + .irq = rga2_irq, + .isr_thread = rga2_isr_thread, +}; diff --git a/drivers/video/rockchip/rga3/rga3_reg_info.c b/drivers/video/rockchip/rga3/rga3_reg_info.c new file mode 100644 -index 000000000..c0ce4a3ff +index 000000000..4091892e0 --- /dev/null +++ b/drivers/video/rockchip/rga3/rga3_reg_info.c -@@ -0,0 +1,2269 @@ +@@ -0,0 +1,2191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1901416,6 +1900518,8 @@ index 000000000..c0ce4a3ff + * Author: Huang Lee + */ + ++#define pr_fmt(fmt) "rga3_reg: " fmt ++ +#include "rga3_reg_info.h" +#include "rga_dma_buf.h" +#include "rga_iommu.h" @@ -1901554,13 +1900658,11 @@ index 000000000..c0ce4a3ff + + switch (msg->win0.format) { + case RGA_FORMAT_RGBA_8888: -+ case RGA_FORMAT_RGBX_8888: + win_format = 0x8; + pixel_width = 4; + win_interleaved = 2; + break; + case RGA_FORMAT_BGRA_8888: -+ case RGA_FORMAT_BGRX_8888: + win_format = 0x6; + pixel_width = 4; + win_interleaved = 2; @@ -1901939,13 +1901041,11 @@ index 000000000..c0ce4a3ff + + switch (msg->win1.format) { + case RGA_FORMAT_RGBA_8888: -+ case RGA_FORMAT_RGBX_8888: + win_format = 0x8; + pixel_width = 4; + win_interleaved = 2; + break; + case RGA_FORMAT_BGRA_8888: -+ case RGA_FORMAT_BGRX_8888: + win_format = 0x6; + pixel_width = 4; + win_interleaved = 2; @@ -1902232,14 +1901332,12 @@ index 000000000..c0ce4a3ff + + switch (msg->wr.format) { + case RGA_FORMAT_RGBA_8888: -+ case RGA_FORMAT_RGBX_8888: + wr_format = 0x6; + pixel_width = 4; + wr_interleaved = 2; + wr_pix_swp = 1; + break; + case RGA_FORMAT_BGRA_8888: -+ case RGA_FORMAT_BGRX_8888: + wr_format = 0x6; + pixel_width = 4; + wr_interleaved = 2; @@ -1902661,25 +1901759,21 @@ index 000000000..c0ce4a3ff + break; + } + -+ if (!config->enable) { ++ if (!config->enable && msg->abb_alpha_pass) { + /* + * enabled by default bot_blend_m1 && bot_alpha_cal_m1 for src channel(win0) + * In ABB mode, the number will be fetched according to 16*16, so it needs to + * be enabled top_blend_m1 && top_alpha_cal_m1 for dst channel(wr). + */ -+ if (msg->fg_alpha_pass) { -+ top_color_ctrl.bits.color_mode = RGA_ALPHA_PRE_MULTIPLIED; ++ top_color_ctrl.bits.color_mode = RGA_ALPHA_PRE_MULTIPLIED; + -+ top_alpha_ctrl.bits.blend_mode = RGA_ALPHA_PER_PIXEL; -+ top_alpha_ctrl.bits.alpha_cal_mode = RGA_ALPHA_NO_SATURATION; -+ } ++ top_alpha_ctrl.bits.blend_mode = RGA_ALPHA_PER_PIXEL; ++ top_alpha_ctrl.bits.alpha_cal_mode = RGA_ALPHA_NO_SATURATION; + -+ if (msg->bg_alpha_pass) { -+ bottom_color_ctrl.bits.color_mode = RGA_ALPHA_PRE_MULTIPLIED; ++ bottom_color_ctrl.bits.color_mode = RGA_ALPHA_PRE_MULTIPLIED; + -+ bottom_alpha_ctrl.bits.blend_mode = RGA_ALPHA_PER_PIXEL; -+ bottom_alpha_ctrl.bits.alpha_cal_mode = RGA_ALPHA_NO_SATURATION; -+ } ++ bottom_alpha_ctrl.bits.blend_mode = RGA_ALPHA_PER_PIXEL; ++ bottom_alpha_ctrl.bits.alpha_cal_mode = RGA_ALPHA_NO_SATURATION; + } else { + top_color_ctrl.bits.color_mode = + config->fg_pre_multiplied ? @@ -1902757,7 +1901851,7 @@ index 000000000..c0ce4a3ff + RGA3_set_reg_wr_info(base, msg); + break; + default: -+ rga_err("error msg render mode %d\n", msg->render_mode); ++ pr_err("error msg render mode %d\n", msg->render_mode); + break; + } + @@ -1902888,6 +1901982,18 @@ index 000000000..c0ce4a3ff + break; + } + ++ req->win0_a_global_val = req_rga->alpha_global_value; ++ req->win1_a_global_val = req_rga->alpha_global_value; ++ ++ /* fixup yuv/rgb convert to rgba missing alpha channel */ ++ if (!(req_rga->alpha_rop_flag & 1)) { ++ if (!rga_is_alpha_format(req_rga->src.format) && ++ rga_is_alpha_format(req_rga->dst.format)) { ++ req->alpha_config.fg_global_alpha_value = 0xff; ++ req->alpha_config.bg_global_alpha_value = 0xff; ++ } ++ } ++ + /* simple win can not support dst offset */ + if ((!((req_rga->alpha_rop_flag) & 1)) && + (req_rga->dst.x_offset == 0 && req_rga->dst.y_offset == 0) && @@ -1902898,6 +1902004,14 @@ index 000000000..c0ce4a3ff + * dst => wr + */ + ++ /* ++ * enabled by default bot_blend_m1 && bot_alpha_cal_m1 for src channel(win0) ++ * In ABB mode, the number will be fetched according to 16*16, so it needs to ++ * be enabled top_blend_m1 && top_alpha_cal_m1 for dst channel(wr). ++ */ ++ if (rga_is_alpha_format(req_rga->src.format)) ++ req->abb_alpha_pass = true; ++ + set_win_info(&req->win0, &req_rga->src); + + /* enable win0 rotate */ @@ -1902920,6 +1902034,14 @@ index 000000000..c0ce4a3ff + * dst => wr + */ + ++ /* ++ * enabled by default top_blend_m1 && top_alpha_cal_m1 for src channel(win1) ++ * In ABB mode, the number will be fetched according to 16*16, so it needs to ++ * be enabled bot_blend_m1 && bot_alpha_cal_m1 for src1/dst channel(win0). ++ */ ++ if (rga_is_alpha_format(req_rga->src.format)) ++ req->abb_alpha_pass = true; ++ + if (req_rga->pat.yrgb_addr != 0) { + if (req_rga->src.yrgb_addr == req_rga->dst.yrgb_addr) { + /* Convert ABC mode to ABB mode. */ @@ -1903053,37 +1902175,12 @@ index 000000000..c0ce4a3ff + req->alpha_config.bg_global_alpha_value = 0xff; + } + } else { -+ req->alpha_config.bg_global_alpha_value = 0xff; ++ req->alpha_config.fg_global_alpha_value = 0xff; + req->alpha_config.bg_global_alpha_value = 0xff; + } + + req->alpha_config.mode = req_rga->PD_mode; + } -+ } else { -+ /* -+ * top/bottom Layer binding: -+ * top/fg => win1/wr -+ * bottom/bg => win0 -+ * The alpha channel of RGA3 is controlled by the overlap register, choosing -+ * to use globalAlpha or perpixelAlpha. -+ * When the input/output format does not have alpha, need to use globalAlpha to -+ * control the output alpha to '0xff'. -+ */ -+ if (req->win1.enable) { -+ req->bg_alpha_pass = true; -+ -+ if (rga_is_alpha_format(req->win1.format) && -+ rga_is_alpha_format(req->wr.format)) -+ req->fg_alpha_pass = true; -+ else -+ req->alpha_config.fg_global_alpha_value = 0xff; -+ } else { -+ if (rga_is_alpha_format(req->win0.format) && -+ rga_is_alpha_format(req->wr.format)) -+ req->bg_alpha_pass = true; -+ else -+ req->alpha_config.bg_global_alpha_value = 0xff; -+ } + } + + /* yuv to rgb */ @@ -1903159,85 +1902256,44 @@ index 000000000..c0ce4a3ff + } + + if (i == RGA_RESET_TIMEOUT) -+ rga_err("%s[%#x] soft reset timeout. SYS_CTRL[0x%x], RO_SRST[0x%x]\n", -+ rga_get_core_name(scheduler->core), scheduler->core, -+ rga_read(RGA3_SYS_CTRL, scheduler), -+ rga_read(RGA3_RO_SRST, scheduler)); ++ pr_err("RGA3 core[%d] soft reset timeout. SYS_CTRL[0x%x], RO_SRST[0x%x]\n", ++ scheduler->core, rga_read(RGA3_SYS_CTRL, scheduler), ++ rga_read(RGA3_RO_SRST, scheduler)); + else -+ rga_log("%s[%#x] soft reset complete.\n", -+ rga_get_core_name(scheduler->core), scheduler->core); ++ pr_info("RGA3 core[%d] soft reset complete.\n", scheduler->core); +} + -+static int rga3_scale_check(struct rga_job *job, const struct rga3_req *req) ++static int rga3_scale_check(const struct rga3_req *req) +{ + u32 win0_saw, win0_sah, win0_daw, win0_dah; + u32 win1_saw, win1_sah, win1_daw, win1_dah; + -+ if (req->rotate_mode & RGA3_ROT_BIT_ROT_90) { -+ if (req->win1.yrgb_addr != 0) { -+ /* ABB */ -+ if (req->win0.yrgb_addr == req->wr.yrgb_addr) { -+ /* win0 do not need rotate, but net equal to wr */ -+ win0_saw = req->win0.src_act_h; -+ win0_sah = req->win0.src_act_w; -+ win0_daw = req->win0.dst_act_h; -+ win0_dah = req->win0.dst_act_w; -+ -+ win1_saw = req->win1.src_act_w; -+ win1_sah = req->win1.src_act_h; -+ win1_daw = req->win1.dst_act_h; -+ win1_dah = req->win1.dst_act_w; -+ } else { -+ win0_saw = req->win0.src_act_w; -+ win0_sah = req->win0.src_act_h; -+ win0_daw = req->win0.dst_act_w; -+ win0_dah = req->win0.dst_act_h; -+ -+ win1_saw = req->win1.src_act_w; -+ win1_sah = req->win1.src_act_h; -+ win1_daw = req->win1.dst_act_w; -+ win1_dah = req->win1.dst_act_h; -+ } -+ } else { -+ win0_saw = req->win0.src_act_w; -+ win0_sah = req->win0.src_act_h; -+ win0_daw = req->win0.dst_act_h; -+ win0_dah = req->win0.dst_act_w; -+ } -+ } else { -+ win0_saw = req->win0.src_act_w; -+ win0_sah = req->win0.src_act_h; -+ win0_daw = req->win0.dst_act_w; -+ win0_dah = req->win0.dst_act_h; -+ -+ if (req->win1.yrgb_addr != 0) { -+ win1_saw = req->win1.src_act_w; -+ win1_sah = req->win1.src_act_h; -+ win1_daw = req->win1.dst_act_w; -+ win1_dah = req->win1.dst_act_h; -+ } -+ } ++ win0_saw = req->win0.src_act_w; ++ win0_sah = req->win0.src_act_h; ++ win0_daw = req->win0.dst_act_w; ++ win0_dah = req->win0.dst_act_h; + + if (((win0_saw >> 3) > win0_daw) || ((win0_sah >> 3) > win0_dah)) { -+ rga_job_log(job, "win0 unsupported to scaling less than 1/8 times. src[%d, %d], dst[%d, %d]\n", -+ win0_saw, win0_sah, win0_daw, win0_dah); ++ pr_info("win0 unsupported to scaling less than 1/8 times.\n"); + return -EINVAL; + } + if (((win0_daw >> 3) > win0_saw) || ((win0_dah >> 3) > win0_sah)) { -+ rga_job_log(job, "win0 unsupported to scaling more than 8 times. src[%d, %d], dst[%d, %d]\n", -+ win0_saw, win0_sah, win0_daw, win0_dah); ++ pr_info("win0 unsupported to scaling more than 8 times.\n"); + return -EINVAL; + } + + if (req->win1.yrgb_addr != 0) { ++ win1_saw = req->win1.src_act_w; ++ win1_sah = req->win1.src_act_h; ++ win1_daw = req->win1.dst_act_w; ++ win1_dah = req->win1.dst_act_h; ++ + if (((win1_saw >> 3) > win1_daw) || ((win1_sah >> 3) > win1_dah)) { -+ rga_job_log(job, "win1 unsupported to scaling less than 1/8 times. src[%d, %d], dst[%d, %d]\n", -+ win1_saw, win1_sah, win1_daw, win1_dah); ++ pr_info("win1 unsupported to scaling less than 1/8 times.\n"); + return -EINVAL; + } + if (((win1_daw >> 3) > win1_saw) || ((win1_dah >> 3) > win1_sah)) { -+ rga_job_log(job, "win1 unsupported to scaling more than 8 times. src[%d, %d], dst[%d, %d]\n", -+ win1_saw, win1_sah, win1_daw, win1_dah); ++ pr_info("win1 unsupported to scaling more than 8 times.\n"); + return -EINVAL; + } + } @@ -1903245,8 +1902301,7 @@ index 000000000..c0ce4a3ff + return 0; +} + -+static int rga3_check_param(struct rga_job *job, const struct rga_hw_data *data, -+ const struct rga3_req *req) ++static int rga3_check_param(const struct rga_hw_data *data, const struct rga3_req *req) +{ + if (unlikely(rga_hw_out_of_range(&(data->input_range), + req->win0.src_act_w, req->win0.src_act_h) || @@ -1903255,32 +1902310,32 @@ index 000000000..c0ce4a3ff + rga_hw_out_of_range(&(data->input_range), + req->win0.src_act_w + req->win0.x_offset, + req->win0.src_act_h + req->win0.y_offset))) { -+ rga_job_err(job, "invalid win0, src[w,h] = [%d, %d], dst[w,h] = [%d, %d], off[x,y] = [%d,%d]\n", -+ req->win0.src_act_w, req->win0.src_act_h, -+ req->win0.dst_act_w, req->win0.dst_act_h, -+ req->win0.x_offset, req->win0.y_offset); ++ pr_err("invalid win0, src[w,h] = [%d, %d], dst[w,h] = [%d, %d], off[x,y] = [%d,%d]\n", ++ req->win0.src_act_w, req->win0.src_act_h, ++ req->win0.dst_act_w, req->win0.dst_act_h, ++ req->win0.x_offset, req->win0.y_offset); + return -EINVAL; + } + + if (unlikely(req->win0.vir_w * rga_get_pixel_stride_from_format(req->win0.format) > + data->max_byte_stride * 8)) { -+ rga_job_err(job, "invalid win0 stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n", -+ req->win0.vir_w, rga_get_pixel_stride_from_format(req->win0.format), -+ data->max_byte_stride); ++ pr_err("invalid win0 stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n", ++ req->win0.vir_w, rga_get_pixel_stride_from_format(req->win0.format), ++ data->max_byte_stride); + return -EINVAL; + } + + if (unlikely(rga_hw_out_of_range(&(data->output_range), + req->wr.dst_act_w, req->wr.dst_act_h))) { -+ rga_job_err(job, "invalid wr, [w,h] = [%d, %d]\n", req->wr.dst_act_w, req->wr.dst_act_h); ++ pr_err("invalid wr, [w,h] = [%d, %d]\n", req->wr.dst_act_w, req->wr.dst_act_h); + return -EINVAL; + } + + if (unlikely(req->wr.vir_w * rga_get_pixel_stride_from_format(req->wr.format) > + data->max_byte_stride * 8)) { -+ rga_job_err(job, "invalid wr stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n", -+ req->wr.vir_w, rga_get_pixel_stride_from_format(req->wr.format), -+ data->max_byte_stride); ++ pr_err("invalid wr stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n", ++ req->wr.vir_w, rga_get_pixel_stride_from_format(req->wr.format), ++ data->max_byte_stride); + return -EINVAL; + } + @@ -1903292,18 +1902347,18 @@ index 000000000..c0ce4a3ff + rga_hw_out_of_range(&(data->input_range), + req->win1.src_act_w + req->win1.x_offset, + req->win1.src_act_h + req->win1.y_offset))) { -+ rga_job_err(job, "invalid win1, src[w,h] = [%d, %d], dst[w,h] = [%d, %d], off[x,y] = [%d,%d]\n", -+ req->win1.src_act_w, req->win1.src_act_h, -+ req->win1.dst_act_w, req->win1.dst_act_h, -+ req->win1.x_offset, req->win1.y_offset); ++ pr_err("invalid win1, src[w,h] = [%d, %d], dst[w,h] = [%d, %d], off[x,y] = [%d,%d]\n", ++ req->win1.src_act_w, req->win1.src_act_h, ++ req->win1.dst_act_w, req->win1.dst_act_h, ++ req->win1.x_offset, req->win1.y_offset); + return -EINVAL; + } + + if (unlikely(req->win1.vir_w * rga_get_pixel_stride_from_format(req->win1.format) > + data->max_byte_stride * 8)) { -+ rga_job_err(job, "invalid win1 stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n", -+ req->win1.vir_w, rga_get_pixel_stride_from_format(req->win1.format), -+ data->max_byte_stride); ++ pr_err("invalid win1 stride, stride = %d, pixel_stride = %d, max_byte_stride = %d\n", ++ req->win1.vir_w, rga_get_pixel_stride_from_format(req->win1.format), ++ data->max_byte_stride); + return -EINVAL; + } + @@ -1903312,95 +1902367,99 @@ index 000000000..c0ce4a3ff + /* check win0 dst size > win1 dst size */ + if (unlikely((req->win1.dst_act_w > req->win0.dst_act_w) || + (req->win1.dst_act_h > req->win0.dst_act_h))) { -+ rga_job_err(job, "invalid output param win0[w,h] = [%d, %d], win1[w,h] = [%d, %d]\n", -+ req->win0.dst_act_w, req->win0.dst_act_h, -+ req->win1.dst_act_w, req->win1.dst_act_h); ++ pr_err("invalid output param win0[w,h] = [%d, %d], win1[w,h] = [%d, %d]\n", ++ req->win0.dst_act_w, req->win0.dst_act_h, ++ req->win1.dst_act_w, req->win1.dst_act_h); + return -EINVAL; + } + } + } + -+ if (rga3_scale_check(job, req) < 0) ++ if (rga3_scale_check(req) < 0) + return -EINVAL; + + return 0; +} + -+static void print_debug_info(struct rga_job *job, struct rga3_req *req) ++static void print_debug_info(struct rga3_req *req) +{ -+ rga_job_log(job, "render_mode:%s, bitblit_mode=%d, rotate_mode:%x\n", ++ pr_info("render_mode:%s, bitblit_mode=%d, rotate_mode:%x\n", + rga_get_render_mode_str(req->render_mode), req->bitblt_mode, + req->rotate_mode); -+ rga_job_log(job, "win0: y = %lx uv = %lx v = %lx src_w = %d src_h = %d\n", -+ req->win0.yrgb_addr, req->win0.uv_addr, req->win0.v_addr, -+ req->win0.src_act_w, req->win0.src_act_h); -+ rga_job_log(job, "win0: vw = %d vh = %d xoff = %d yoff = %d format = %s\n", -+ req->win0.vir_w, req->win0.vir_h, -+ req->win0.x_offset, req->win0.y_offset, -+ rga_get_format_name(req->win0.format)); -+ rga_job_log(job, "win0: dst_w = %d, dst_h = %d, rd_mode = %d\n", -+ req->win0.dst_act_w, req->win0.dst_act_h, req->win0.rd_mode); -+ rga_job_log(job, "win0: rot_mode = %d, en = %d, compact = %d, endian = %d\n", -+ req->win0.rotate_mode, req->win0.enable, -+ req->win0.is_10b_compact, req->win0.is_10b_endian); ++ pr_info("win0: y = %lx uv = %lx v = %lx src_w = %d src_h = %d\n", ++ req->win0.yrgb_addr, req->win0.uv_addr, req->win0.v_addr, ++ req->win0.src_act_w, req->win0.src_act_h); ++ pr_info("win0: vw = %d vh = %d xoff = %d yoff = %d format = %s\n", ++ req->win0.vir_w, req->win0.vir_h, ++ req->win0.x_offset, req->win0.y_offset, ++ rga_get_format_name(req->win0.format)); ++ pr_info("win0: dst_w = %d, dst_h = %d, rd_mode = %d\n", ++ req->win0.dst_act_w, req->win0.dst_act_h, req->win0.rd_mode); ++ pr_info("win0: rot_mode = %d, en = %d, compact = %d, endian = %d\n", ++ req->win0.rotate_mode, req->win0.enable, ++ req->win0.is_10b_compact, req->win0.is_10b_endian); + + if (req->win1.yrgb_addr != 0 || req->win1.uv_addr != 0 + || req->win1.v_addr != 0) { -+ rga_job_log(job, "win1: y = %lx uv = %lx v = %lx src_w = %d src_h = %d\n", -+ req->win1.yrgb_addr, req->win1.uv_addr, -+ req->win1.v_addr, req->win1.src_act_w, -+ req->win1.src_act_h); -+ rga_job_log(job, "win1: vw = %d vh = %d xoff = %d yoff = %d format = %s\n", -+ req->win1.vir_w, req->win1.vir_h, -+ req->win1.x_offset, req->win1.y_offset, -+ rga_get_format_name(req->win1.format)); -+ rga_job_log(job, "win1: dst_w = %d, dst_h = %d, rd_mode = %d\n", -+ req->win1.dst_act_w, req->win1.dst_act_h, -+ req->win1.rd_mode); -+ rga_job_log(job, "win1: rot_mode = %d, en = %d, compact = %d, endian = %d\n", -+ req->win1.rotate_mode, req->win1.enable, -+ req->win1.is_10b_compact, req->win1.is_10b_endian); -+ } -+ -+ rga_job_log(job, "wr: y = %lx uv = %lx v = %lx vw = %d vh = %d\n", -+ req->wr.yrgb_addr, req->wr.uv_addr, req->wr.v_addr, -+ req->wr.vir_w, req->wr.vir_h); -+ rga_job_log(job, "wr: ovlp_xoff = %d ovlp_yoff = %d format = %s rdmode = %d\n", -+ req->wr.x_offset, req->wr.y_offset, -+ rga_get_format_name(req->wr.format), req->wr.rd_mode); -+ -+ rga_job_log(job, "mmu: win0 = %.2x win1 = %.2x wr = %.2x\n", ++ pr_info("win1: y = %lx uv = %lx v = %lx src_w = %d src_h = %d\n", ++ req->win1.yrgb_addr, req->win1.uv_addr, ++ req->win1.v_addr, req->win1.src_act_w, ++ req->win1.src_act_h); ++ pr_info("win1: vw = %d vh = %d xoff = %d yoff = %d format = %s\n", ++ req->win1.vir_w, req->win1.vir_h, ++ req->win1.x_offset, req->win1.y_offset, ++ rga_get_format_name(req->win1.format)); ++ pr_info("win1: dst_w = %d, dst_h = %d, rd_mode = %d\n", ++ req->win1.dst_act_w, req->win1.dst_act_h, ++ req->win1.rd_mode); ++ pr_info("win1: rot_mode = %d, en = %d, compact = %d, endian = %d\n", ++ req->win1.rotate_mode, req->win1.enable, ++ req->win1.is_10b_compact, req->win1.is_10b_endian); ++ } ++ ++ pr_info("wr: y = %lx uv = %lx v = %lx vw = %d vh = %d\n", ++ req->wr.yrgb_addr, req->wr.uv_addr, req->wr.v_addr, ++ req->wr.vir_w, req->wr.vir_h); ++ pr_info("wr: ovlp_xoff = %d ovlp_yoff = %d format = %s rdmode = %d\n", ++ req->wr.x_offset, req->wr.y_offset, ++ rga_get_format_name(req->wr.format), req->wr.rd_mode); ++ ++ pr_info("mmu: win0 = %.2x win1 = %.2x wr = %.2x\n", + req->mmu_info.src0_mmu_flag, req->mmu_info.src1_mmu_flag, + req->mmu_info.dst_mmu_flag); -+ rga_job_log(job, "alpha: flag %x mode=%s\n", ++ pr_info("alpha: flag %x mode=%s\n", + req->alpha_rop_flag, rga_get_blend_mode_str(req->alpha_config.mode)); -+ rga_job_log(job, "alpha: pre_multi=[%d,%d] pixl=[%d,%d] glb=[%d,%d]\n", ++ pr_info("alpha: pre_multi=[%d,%d] pixl=[%d,%d] glb=[%d,%d]\n", + req->alpha_config.fg_pre_multiplied, req->alpha_config.bg_pre_multiplied, + req->alpha_config.fg_pixel_alpha_en, req->alpha_config.bg_pixel_alpha_en, + req->alpha_config.fg_global_alpha_en, req->alpha_config.bg_global_alpha_en); -+ rga_job_log(job, "alpha: fg_global_alpha=%x bg_global_alpha=%x\n", ++ pr_info("alpha: fg_global_alpha=%x bg_global_alpha=%x\n", + req->alpha_config.fg_global_alpha_value, req->alpha_config.bg_global_alpha_value); -+ rga_job_log(job, "yuv2rgb mode is %x\n", req->yuv2rgb_mode); ++ pr_info("yuv2rgb mode is %x\n", req->yuv2rgb_mode); +} + -+static int rga3_align_check(struct rga_job *job, struct rga3_req *req) ++static int rga3_align_check(struct rga3_req *req) +{ + if (rga_is_yuv10bit_format(req->win0.format)) -+ if ((req->win0.x_offset % 4) || (req->win0.y_offset % 2) || -+ (req->win0.src_act_w % 4) || (req->win0.src_act_h % 2)) -+ rga_job_log(job, "yuv10bit err win0 wstride is not align\n"); ++ if ((req->win0.vir_w % 64) || (req->win0.x_offset % 4) || ++ (req->win0.src_act_w % 4) || (req->win0.y_offset % 4) || ++ (req->win0.src_act_h % 4) || (req->win0.vir_h % 2)) ++ pr_info("yuv10bit err win0 wstride is not align\n"); + if (rga_is_yuv10bit_format(req->win1.format)) -+ if ((req->win1.x_offset % 4) || (req->win1.y_offset % 2) || -+ (req->win1.src_act_w % 4) || (req->win1.src_act_h % 2)) -+ rga_job_log(job, "yuv10bit err win1 wstride is not align\n"); ++ if ((req->win1.vir_w % 64) || (req->win1.x_offset % 4) || ++ (req->win1.src_act_w % 4) || (req->win1.y_offset % 4) || ++ (req->win1.src_act_h % 4) || (req->win1.vir_h % 2)) ++ pr_info("yuv10bit err win1 wstride is not align\n"); + if (rga_is_yuv8bit_format(req->win0.format)) -+ if ((req->win0.x_offset % 2) || (req->win0.y_offset % 2) || -+ (req->win0.src_act_w % 2) || (req->win0.src_act_h % 2)) -+ rga_job_log(job, "yuv8bit err win0 wstride is not align\n"); ++ if ((req->win0.vir_w % 16) || (req->win0.x_offset % 2) || ++ (req->win0.src_act_w % 2) || (req->win0.y_offset % 2) || ++ (req->win0.src_act_h % 2) || (req->win0.vir_h % 2)) ++ pr_info("yuv8bit err win0 wstride is not align\n"); + if (rga_is_yuv8bit_format(req->win1.format)) -+ if ((req->win1.x_offset % 2) || (req->win1.y_offset % 2) || -+ (req->win1.src_act_w % 2) || (req->win1.src_act_h % 2)) -+ rga_job_log(job, "yuv8bit err win1 wstride is not align\n"); ++ if ((req->win1.vir_w % 16) || (req->win1.x_offset % 2) || ++ (req->win1.src_act_w % 2) || (req->win1.y_offset % 2) || ++ (req->win1.src_act_h % 2) || (req->win1.vir_h % 2)) ++ pr_info("yuv8bit err win1 wstride is not align\n"); + return 0; +} + @@ -1903413,7 +1902472,7 @@ index 000000000..c0ce4a3ff + + scheduler = job->scheduler; + if (unlikely(scheduler == NULL)) { -+ rga_job_err(job, "failed to get scheduler, %s(%d)\n", __func__, __LINE__); ++ pr_err("failed to get scheduler, %s(%d)\n", __func__, __LINE__); + return -EINVAL; + } + @@ -1903421,53 +1902480,32 @@ index 000000000..c0ce4a3ff + + rga_cmd_to_rga3_cmd(&job->rga_command_base, &req); + -+ /* for debug */ -+ if (DEBUGGER_EN(MSG)) -+ print_debug_info(job, &req); -+ + /* check value if legal */ -+ ret = rga3_check_param(job, scheduler->data, &req); ++ ret = rga3_check_param(scheduler->data, &req); + if (ret == -EINVAL) { -+ rga_job_err(job, "req argument is inval\n"); ++ pr_err("req argument is inval\n"); + return ret; + } + -+ rga3_align_check(job, &req); ++ rga3_align_check(&req); ++ ++ /* for debug */ ++ if (DEBUGGER_EN(MSG)) ++ print_debug_info(&req); + -+ if (rga3_gen_reg_info((uint8_t *) job->cmd_buf->vaddr, &req) == -1) { -+ rga_job_err(job, "RKA: gen reg info error\n"); ++ if (rga3_gen_reg_info((uint8_t *) job->cmd_reg, &req) == -1) { ++ pr_err("RKA: gen reg info error\n"); + return -EINVAL; + } + + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "generate register cost time %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); ++ pr_info("request[%d], generate register cost time %lld us\n", ++ job->request_id, ktime_us_delta(ktime_get(), timestamp)); + + return ret; +} + -+static void rga3_dump_read_back_sys_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) -+{ -+ int i; -+ unsigned long flags; -+ uint32_t sys_reg[20] = {0}; -+ -+ spin_lock_irqsave(&scheduler->irq_lock, flags); -+ -+ for (i = 0; i < 20; i++) -+ sys_reg[i] = rga_read(RGA3_SYS_REG_BASE + i * 4, scheduler); -+ -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ -+ rga_job_log(job, "SYS_READ_BACK_REG\n"); -+ for (i = 0; i < 5; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", -+ RGA3_SYS_REG_BASE + i * 0x10, -+ sys_reg[0 + i * 4], sys_reg[1 + i * 4], -+ sys_reg[2 + i * 4], sys_reg[3 + i * 4]); -+} -+ -+static void rga3_dump_read_back_reg(struct rga_job *job, struct rga_scheduler_t *scheduler) ++static void rga3_dump_read_back_reg(struct rga_scheduler_t *scheduler) +{ + int i; + unsigned long flags; @@ -1903476,14 +1902514,13 @@ index 000000000..c0ce4a3ff + spin_lock_irqsave(&scheduler->irq_lock, flags); + + for (i = 0; i < 48; i++) -+ cmd_reg[i] = rga_read(RGA3_CMD_REG_BASE + i * 4, scheduler); ++ cmd_reg[i] = rga_read(0x100 + i * 4, scheduler); + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + -+ rga_job_log(job, "CMD_READ_BACK_REG\n"); ++ pr_info("CMD_READ_BACK_REG\n"); + for (i = 0; i < 12; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", -+ RGA3_CMD_REG_BASE + i * 0x10, ++ pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i, + cmd_reg[0 + i * 4], cmd_reg[1 + i * 4], + cmd_reg[2 + i * 4], cmd_reg[3 + i * 4]); +} @@ -1903493,11 +1902530,8 @@ index 000000000..c0ce4a3ff + int i; + bool master_mode_en; + uint32_t sys_ctrl; -+ uint32_t *cmd; + ktime_t now = ktime_get(); + -+ cmd = job->cmd_buf->vaddr; -+ + /* + * Currently there is no iova allocated for storing cmd for the IOMMU device, + * so the iommu device needs to use the slave mode. @@ -1903508,14 +1902542,14 @@ index 000000000..c0ce4a3ff + master_mode_en = false; + + if (DEBUGGER_EN(REG)) { -+ rga3_dump_read_back_sys_reg(job, scheduler); ++ uint32_t *p; + -+ rga_job_log(job, "CMD_REG\n"); ++ p = job->cmd_reg; ++ pr_info("CMD_REG\n"); + for (i = 0; i < 12; i++) -+ rga_job_log(job, "0x%04x : %.8x %.8x %.8x %.8x\n", -+ RGA3_CMD_REG_BASE + i * 0x10, -+ cmd[0 + i * 4], cmd[1 + i * 4], -+ cmd[2 + i * 4], cmd[3 + i * 4]); ++ pr_info("i = %x : %.8x %.8x %.8x %.8x\n", i, ++ p[0 + i * 4], p[1 + i * 4], ++ p[2 + i * 4], p[3 + i * 4]); + } + + /* All CMD finish int */ @@ -1903526,7 +1902560,10 @@ index 000000000..c0ce4a3ff + /* master mode */ + sys_ctrl = s_RGA3_SYS_CTRL_CMD_MODE(1); + -+ rga_write(job->cmd_buf->dma_addr, RGA3_CMD_ADDR, scheduler); ++ /* cmd buffer flush cache to ddr */ ++ rga_dma_sync_flush_range(&job->cmd_reg[0], &job->cmd_reg[50], scheduler); ++ ++ rga_write(virt_to_phys(job->cmd_reg), RGA3_CMD_ADDR, scheduler); + rga_write(sys_ctrl, RGA3_SYS_CTRL, scheduler); + rga_write(m_RGA3_CMD_CTRL_CMD_LINE_ST_P, RGA3_CMD_CTRL, scheduler); + } else { @@ -1903534,23 +1902571,31 @@ index 000000000..c0ce4a3ff + sys_ctrl = s_RGA3_SYS_CTRL_CMD_MODE(0) | m_RGA3_SYS_CTRL_RGA_SART; + + for (i = 0; i <= 50; i++) -+ rga_write(cmd[i], 0x100 + i * 4, scheduler); ++ rga_write(job->cmd_reg[i], 0x100 + i * 4, scheduler); + + rga_write(sys_ctrl, RGA3_SYS_CTRL, scheduler); + } + ++ if (DEBUGGER_EN(REG)) { ++ pr_info("sys_ctrl = 0x%x, int_en = 0x%x, int_raw = 0x%x\n", ++ rga_read(RGA3_SYS_CTRL, scheduler), ++ rga_read(RGA3_INT_EN, scheduler), ++ rga_read(RGA3_INT_RAW, scheduler)); ++ ++ pr_info("hw_status = 0x%x, cmd_status = 0x%x\n", ++ rga_read(RGA3_STATUS0, scheduler), ++ rga_read(RGA3_CMD_STATE, scheduler)); ++ } ++ + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "set register cost time %lld us\n", -+ ktime_us_delta(ktime_get(), now)); ++ pr_info("request[%d], set register cost time %lld us\n", ++ job->request_id, ktime_us_delta(now, job->timestamp)); + -+ job->timestamp.hw_execute = now; -+ job->timestamp.hw_recode = now; -+ job->session->last_active = now; ++ job->hw_running_time = now; ++ job->hw_recoder_time = now; + -+ if (DEBUGGER_EN(REG)) { -+ rga3_dump_read_back_sys_reg(job, scheduler); -+ rga3_dump_read_back_reg(job, scheduler); -+ } ++ if (DEBUGGER_EN(REG)) ++ rga3_dump_read_back_reg(scheduler); + + return 0; +} @@ -1903561,7 +1902606,7 @@ index 000000000..c0ce4a3ff + u32 reg_version; + + if (!scheduler) { -+ rga_err("scheduler is null\n"); ++ pr_err("scheduler is null\n"); + return -EINVAL; + } + @@ -1903581,44 +1902626,22 @@ index 000000000..c0ce4a3ff + return 0; +} + -+static int rga3_read_status(struct rga_job *job, struct rga_scheduler_t *scheduler) -+{ -+ job->intr_status = rga_read(RGA3_INT_RAW, scheduler); -+ job->hw_status = rga_read(RGA3_STATUS0, scheduler); -+ job->cmd_status = rga_read(RGA3_CMD_STATE, scheduler); -+ job->work_cycle = 0; -+ -+ return 0; -+} -+ -+static void rga3_clear_intr(struct rga_scheduler_t *scheduler) -+{ -+ rga_write(m_RGA3_INT_FRM_DONE | m_RGA3_INT_CMD_LINE_FINISH | m_RGA3_INT_ERROR_MASK, -+ RGA3_INT_CLR, scheduler); -+} -+ +static int rga3_irq(struct rga_scheduler_t *scheduler) +{ + struct rga_job *job = scheduler->running_job; + -+ if (job == NULL) { -+ rga3_clear_intr(scheduler); -+ rga_err("core[%d], invalid job, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", -+ scheduler->core, rga_read(RGA3_INT_RAW, scheduler), -+ rga_read(RGA3_STATUS0, scheduler), rga_read(RGA3_CMD_STATE, scheduler)); -+ ++ if (job == NULL) + return IRQ_HANDLED; -+ } + -+ if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) { -+ rga3_clear_intr(scheduler); ++ if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) + return IRQ_WAKE_THREAD; -+ } + -+ scheduler->ops->read_status(job, scheduler); ++ job->intr_status = rga_read(RGA3_INT_RAW, scheduler); ++ job->hw_status = rga_read(RGA3_STATUS0, scheduler); ++ job->cmd_status = rga_read(RGA3_CMD_STATE, scheduler); + + if (DEBUGGER_EN(INT_FLAG)) -+ rga_job_log(job, "irq handler, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", ++ pr_info("irq handler, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", + job->intr_status, job->hw_status, job->cmd_status); + + if (job->intr_status & (m_RGA3_INT_FRM_DONE | m_RGA3_INT_CMD_LINE_FINISH)) { @@ -1903626,12 +1902649,14 @@ index 000000000..c0ce4a3ff + } else if (job->intr_status & m_RGA3_INT_ERROR_MASK) { + set_bit(RGA_JOB_STATE_INTR_ERR, &job->state); + -+ rga_job_err(job, "irq handler err! INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", ++ pr_err("irq handler err! INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", + job->intr_status, job->hw_status, job->cmd_status); + scheduler->ops->soft_reset(scheduler); + } + -+ rga3_clear_intr(scheduler); ++ /*clear INTR */ ++ rga_write(m_RGA3_INT_FRM_DONE | m_RGA3_INT_CMD_LINE_FINISH | m_RGA3_INT_ERROR_MASK, ++ RGA3_INT_CLR, scheduler); + + return IRQ_WAKE_THREAD; +} @@ -1903639,28 +1902664,28 @@ index 000000000..c0ce4a3ff +static int rga3_isr_thread(struct rga_job *job, struct rga_scheduler_t *scheduler) +{ + if (DEBUGGER_EN(INT_FLAG)) -+ rga_job_log(job, "isr thread, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", ++ pr_info("isr thread, INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x]\n", + rga_read(RGA3_INT_RAW, scheduler), + rga_read(RGA3_STATUS0, scheduler), + rga_read(RGA3_CMD_STATE, scheduler)); + + if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) { + if (job->intr_status & m_RGA3_INT_RAG_MI_RD_BUS_ERR) { -+ rga_job_err(job, "DMA read bus error, please check size of the input_buffer or whether the buffer has been freed.\n"); ++ pr_err("DMA read bus error, please check size of the input_buffer or whether the buffer has been freed.\n"); + job->ret = -EFAULT; + } else if (job->intr_status & m_RGA3_INT_WIN0_FBCD_DEC_ERR) { -+ rga_job_err(job, "win0 FBC decoder error, please check the fbc image of the source.\n"); ++ pr_err("win0 FBC decoder error, please check the fbc image of the source.\n"); + job->ret = -EFAULT; + } else if (job->intr_status & m_RGA3_INT_WIN1_FBCD_DEC_ERR) { -+ rga_job_err(job, "win1 FBC decoder error, please check the fbc image of the source.\n"); ++ pr_err("win1 FBC decoder error, please check the fbc image of the source.\n"); + job->ret = -EFAULT; + } else if (job->intr_status & m_RGA3_INT_RGA_MI_WR_BUS_ERR) { -+ rga_job_err(job, "wr buss error, please check size of the output_buffer or whether the buffer has been freed.\n"); ++ pr_err("wr buss error, please check size of the output_buffer or whether the buffer has been freed.\n"); + job->ret = -EFAULT; + } + + if (job->ret == 0) { -+ rga_job_err(job, "rga intr error[0x%x]!\n", job->intr_status); ++ pr_err("rga intr error[0x%x]!\n", job->intr_status); + job->ret = -EFAULT; + } + } @@ -1903674,16 +1902699,15 @@ index 000000000..c0ce4a3ff + .init_reg = rga3_init_reg, + .soft_reset = rga3_soft_reset, + .read_back_reg = NULL, -+ .read_status = rga3_read_status, + .irq = rga3_irq, + .isr_thread = rga3_isr_thread, +}; diff --git a/drivers/video/rockchip/rga3/rga_common.c b/drivers/video/rockchip/rga3/rga_common.c new file mode 100644 -index 000000000..1563583dd +index 000000000..80d4821fb --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_common.c -@@ -0,0 +1,951 @@ +@@ -0,0 +1,772 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1903691,6 +1902715,8 @@ index 000000000..1563583dd + * Author: Cerf Yu + */ + ++#define pr_fmt(fmt) "rga_common: " fmt ++ +#include "rga.h" +#include "rga_common.h" + @@ -1903727,7 +1902753,6 @@ index 000000000..1563583dd +{ + switch (format) { + case RGA_FORMAT_Y4: -+ case RGA_FORMAT_Y8: + case RGA_FORMAT_YCbCr_400: + + case RGA_FORMAT_YCbCr_422_SP: @@ -1903752,9 +1902777,6 @@ index 000000000..1563583dd + case RGA_FORMAT_YCrCb_420_SP_10B: + case RGA_FORMAT_YCbCr_422_SP_10B: + case RGA_FORMAT_YCrCb_422_SP_10B: -+ -+ case RGA_FORMAT_YCbCr_444_SP: -+ case RGA_FORMAT_YCrCb_444_SP: + return true; + default: + return false; @@ -1903776,8 +1902798,6 @@ index 000000000..1563583dd + case RGA_FORMAT_ABGR_8888: + case RGA_FORMAT_ABGR_5551: + case RGA_FORMAT_ABGR_4444: -+ -+ case RGA_FORMAT_A8: + return true; + default: + return false; @@ -1903862,7 +1902882,6 @@ index 000000000..1563583dd +{ + switch (format) { + case RGA_FORMAT_Y4: -+ case RGA_FORMAT_Y8: + case RGA_FORMAT_YCbCr_400: + + case RGA_FORMAT_YCbCr_422_SP: @@ -1903882,9 +1902901,6 @@ index 000000000..1563583dd + case RGA_FORMAT_YUYV_420: + case RGA_FORMAT_UYVY_422: + case RGA_FORMAT_UYVY_420: -+ -+ case RGA_FORMAT_YCbCr_444_SP: -+ case RGA_FORMAT_YCrCb_444_SP: + return true; + default: + return false; @@ -1903920,7 +1902936,6 @@ index 000000000..1563583dd + switch (format) { + case RGA_FORMAT_YCbCr_400: + case RGA_FORMAT_Y4: -+ case RGA_FORMAT_Y8: + return true; + default: + return false; @@ -1904008,7 +1903023,7 @@ index 000000000..1563583dd + case RGA_FORMAT_YCbCr_400: + return "YCbCr400"; + case RGA_FORMAT_Y4: -+ return "Y4"; ++ return "y4"; + + case RGA_FORMAT_ARGB_8888: + return "ARGB8888"; @@ -1904030,16 +1903045,6 @@ index 000000000..1563583dd + case RGA_FORMAT_RGBA_2BPP: + return "RGBA2BPP"; + -+ case RGA_FORMAT_A8: -+ return "alpha-8"; -+ case RGA_FORMAT_YCbCr_444_SP: -+ return "YCbCr444SP"; -+ case RGA_FORMAT_YCrCb_444_SP: -+ return "YCrCb444SP"; -+ -+ case RGA_FORMAT_Y8: -+ return "Y8"; -+ + default: + return "UNF"; + } @@ -1904062,8 +1903067,6 @@ index 000000000..1563583dd + break; + case RGA_FORMAT_RGB_888: + case RGA_FORMAT_BGR_888: -+ case RGA_FORMAT_YCbCr_444_SP: -+ case RGA_FORMAT_YCrCb_444_SP: + bits = 24; + break; + case RGA_FORMAT_RGB_565: @@ -1904105,8 +1903108,6 @@ index 000000000..1563583dd + break; + case RGA_FORMAT_YCbCr_400: + case RGA_FORMAT_BPP8: -+ case RGA_FORMAT_A8: -+ case RGA_FORMAT_Y8: + bits = 8; + break; + case RGA_FORMAT_Y4: @@ -1904120,7 +1903121,7 @@ index 000000000..1563583dd + bits = 1; + break; + default: -+ rga_err("unknown format [0x%x]\n", format); ++ pr_err("unknown format [0x%x]\n", format); + return -1; + } + @@ -1904144,8 +1903145,6 @@ index 000000000..1563583dd + break; + case RGA_FORMAT_RGB_888: + case RGA_FORMAT_BGR_888: -+ case RGA_FORMAT_YCbCr_444_SP: -+ case RGA_FORMAT_YCrCb_444_SP: + pixel_stride = 24; + break; + case RGA_FORMAT_RGB_565: @@ -1904179,7 +1903178,6 @@ index 000000000..1563583dd + case RGA_FORMAT_BPP4: + case RGA_FORMAT_BPP8: + case RGA_FORMAT_YCbCr_400: -+ case RGA_FORMAT_A8: + case RGA_FORMAT_YCbCr_420_SP: + case RGA_FORMAT_YCbCr_420_P: + case RGA_FORMAT_YCrCb_420_SP: @@ -1904188,14 +1903186,13 @@ index 000000000..1563583dd + case RGA_FORMAT_YCbCr_422_P: + case RGA_FORMAT_YCrCb_422_SP: + case RGA_FORMAT_YCrCb_422_P: -+ case RGA_FORMAT_Y8: + pixel_stride = 8; + break; + case RGA_FORMAT_Y4: + pixel_stride = 4; + break; + default: -+ rga_err("unknown format [0x%x]\n", format); ++ pr_err("unknown format [0x%x]\n", format); + return -1; + } + @@ -1904220,42 +1903217,6 @@ index 000000000..1563583dd + } +} + -+const char *rga_get_store_mode_str(uint32_t mode) -+{ -+ switch (mode) { -+ case RGA_RASTER_MODE: -+ return "raster"; -+ case RGA_FBC_MODE: -+ return "afbc16x16"; -+ case RGA_TILE_MODE: -+ return "tile8x8"; -+ case RGA_TILE4x4_MODE: -+ return "tile4x4"; -+ case RGA_RKFBC_MODE: -+ return "rkfbc64x4"; -+ case RGA_AFBC32x8_MODE: -+ return "afbc32x8"; -+ default: -+ return "unknown"; -+ } -+} -+ -+const char *rga_get_interp_str(uint8_t interp) -+{ -+ switch (interp) { -+ case RGA_INTERP_DEFAULT: -+ return "default"; -+ case RGA_INTERP_LINEAR: -+ return "bi-linear"; -+ case RGA_INTERP_BICUBIC: -+ return "bi-cubic"; -+ case RGA_INTERP_AVERAGE: -+ return "average_filter"; -+ default: -+ return "unknown"; -+ } -+} -+ +const char *rga_get_rotate_mode_str(uint8_t mode) +{ + switch (mode) { @@ -1904353,33 +1903314,15 @@ index 000000000..1563583dd + } +} + -+const char *rga_get_dma_data_direction_str(enum dma_data_direction dir) -+{ -+ switch (dir) { -+ case DMA_BIDIRECTIONAL: -+ return "bidirectional"; -+ case DMA_TO_DEVICE: -+ return "to_device"; -+ case DMA_FROM_DEVICE: -+ return "from_device"; -+ case DMA_NONE: -+ return "none"; -+ default: -+ return "unknown"; -+ } -+} -+ -+const char *rga_get_core_name(enum RGA_SCHEDULER_CORE core) ++const char *rga_get_core_name(enum RGA_SCHEDULER_CORE core) +{ + switch (core) { -+ case RGA3_SCHEDULER_CORE0: ++ case RGA_SCHEDULER_RGA3_CORE0: + return "RGA3_core0"; -+ case RGA3_SCHEDULER_CORE1: ++ case RGA_SCHEDULER_RGA3_CORE1: + return "RGA3_core1"; -+ case RGA2_SCHEDULER_CORE0: ++ case RGA_SCHEDULER_RGA2_CORE0: + return "RGA2_core0"; -+ case RGA2_SCHEDULER_CORE1: -+ return "RGA2_core1"; + default: + return "unknown_core"; + } @@ -1904475,12 +1903418,6 @@ index 000000000..1563583dd + yrgb = w * h * 2; + break; + /* YUV FORMAT */ -+ case RGA_FORMAT_YCbCr_444_SP: -+ case RGA_FORMAT_YCrCb_444_SP: -+ yrgb = w * h; -+ uv = w * h; -+ v = w * h; -+ break; + case RGA_FORMAT_YCbCr_422_SP: + case RGA_FORMAT_YCrCb_422_SP: + /* 10bit format stride is externally configured. */ @@ -1904510,15 +1903447,13 @@ index 000000000..1563583dd + v = uv; + break; + case RGA_FORMAT_YCbCr_400: -+ case RGA_FORMAT_A8: -+ case RGA_FORMAT_Y8: + yrgb = w * h; + break; + case RGA_FORMAT_Y4: + yrgb = (w * h) >> 1; + break; + default: -+ rga_err("Unsuport format [0x%x]\n", format); ++ pr_err("Unsuport format [0x%x]\n", format); + return -EFAULT; + } + @@ -1904534,113 +1903469,23 @@ index 000000000..1563583dd + +void rga_dump_memory_parm(struct rga_memory_parm *parm) +{ -+ rga_log("memory param: w = %d, h = %d, f = %s(0x%x), size = %d\n", ++ pr_info("memory param: w = %d, h = %d, f = %s(0x%x), size = %d\n", + parm->width, parm->height, rga_get_format_name(parm->format), + parm->format, parm->size); +} + +void rga_dump_external_buffer(struct rga_external_buffer *buffer) +{ -+ rga_log("external: memory = 0x%lx, type = %s\n", ++ pr_info("external: memory = 0x%lx, type = %s\n", + (unsigned long)buffer->memory, rga_get_memory_type_str(buffer->type)); + rga_dump_memory_parm(&buffer->memory_parm); +} -+ -+static void rga_dump_image_info(struct rga_request *request, const char *name, -+ struct rga_img_info_t *img, uint8_t handle_flag, int need_mmu) -+{ -+ if (handle_flag) { -+ if (img->uv_addr && img->v_addr) -+ rga_req_log(request, "%s: handle[y,uv,v] = [%ld(%#lx), %ld(%#lx), %ld(%#lx)], mode = %s\n", -+ name, -+ (unsigned long)img->yrgb_addr, (unsigned long)img->yrgb_addr, -+ (unsigned long)img->uv_addr, (unsigned long)img->uv_addr, -+ (unsigned long)img->v_addr, (unsigned long)img->v_addr, -+ rga_get_store_mode_str(img->rd_mode)); -+ else if (img->uv_addr) -+ rga_req_log(request, "%s: handle[y,uv] = [%ld(%#lx), %ld(%#lx)], mode = %s\n", -+ name, -+ (unsigned long)img->yrgb_addr, (unsigned long)img->yrgb_addr, -+ (unsigned long)img->uv_addr, (unsigned long)img->uv_addr, -+ rga_get_store_mode_str(img->rd_mode)); -+ else -+ rga_req_log(request, "%s: handle = %ld(%#lx), mode = %s\n", -+ name, -+ (unsigned long)img->yrgb_addr, (unsigned long)img->yrgb_addr, -+ rga_get_store_mode_str(img->rd_mode)); -+ } else { -+ if (img->yrgb_addr) -+ rga_req_log(request, "%s: fd = %ld(%#lx), mode = %s\n", -+ name, -+ (unsigned long)img->yrgb_addr, (unsigned long)img->yrgb_addr, -+ rga_get_store_mode_str(img->rd_mode)); -+ else if (img->uv_addr) -+ rga_req_log(request, "%s: %s = %#lx, mode = %s\n", -+ name, -+ need_mmu ? "virt_addr" : "phys_addr", (unsigned long)img->uv_addr, -+ rga_get_store_mode_str(img->rd_mode)); -+ } -+ -+ rga_req_log(request, "%s: rect[x,y,w,h] = [%d, %d, %d, %d], stride[w,h] = [%d, %d], format = %s(%#x)\n", -+ name, -+ img->x_offset, img->y_offset, img->act_w, img->act_h, img->vir_w, img->vir_h, -+ rga_get_format_name(img->format), img->format); -+} -+ -+void rga_dump_req(struct rga_request *request, struct rga_req *req) -+{ -+ rga_req_log(request, "render_mode = %d, bitblit_mode = %d, rotate_mode = %d\n", -+ req->render_mode, req->bsfilter_flag, -+ req->rotate_mode); -+ -+ rga_dump_image_info(request, "src", &req->src, req->handle_flag, -+ (req->mmu_info.mmu_flag >> 8) & 1); -+ if (req->pat.yrgb_addr != 0 || req->pat.uv_addr != 0 || req->pat.v_addr != 0) -+ rga_dump_image_info(request, "pat", &req->pat, req->handle_flag, -+ (req->mmu_info.mmu_flag >> 9) & 1); -+ rga_dump_image_info(request, "dst", &req->dst, req->handle_flag, -+ (req->mmu_info.mmu_flag >> 10) & 1); -+ -+ rga_req_log(request, "mmu: mmu_flag = %#x en = %#x\n", -+ req->mmu_info.mmu_flag, req->mmu_info.mmu_en); -+ rga_req_log(request, "alpha: rop_mode = %#x\n", req->alpha_rop_mode); -+ rga_req_log(request, "csc = %#x\n", req->yuv2rgb_mode); -+ rga_req_log(request, "imterplotion: horiz = %s(%#x), verti = %s(%#x)\n", -+ rga_get_interp_str(req->interp.horiz), req->interp.horiz, -+ rga_get_interp_str(req->interp.verti), req->interp.verti); -+ rga_req_log(request, "core_mask = %#x, priority = %d, in_fence = %d(%#x)\n", -+ req->core, req->priority, req->in_fence_fd, req->in_fence_fd); -+} -+ -+unsigned long rga_get_free_pages(gfp_t gfp_mask, unsigned int *order, unsigned long size) -+{ -+ int cur_order, max_order; -+ unsigned long pages; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) -+ max_order = MAX_ORDER; -+#else -+ max_order = MAX_PAGE_ORDER; -+#endif -+ -+ cur_order = get_order(size); -+ if (cur_order > max_order) { -+ rga_err("Can not alloc pages with order[%d] for viraddr pages, max_order = %d\n", -+ cur_order, max_order); -+ return 0; -+ } -+ -+ pages = __get_free_pages(gfp_mask, cur_order); -+ *order = cur_order; -+ -+ return pages; -+} diff --git a/drivers/video/rockchip/rga3/rga_debugger.c b/drivers/video/rockchip/rga3/rga_debugger.c new file mode 100644 -index 000000000..95cc80976 +index 000000000..fe2103147 --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_debugger.c -@@ -0,0 +1,1004 @@ +@@ -0,0 +1,970 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1904650,21 +1903495,20 @@ index 000000000..95cc80976 + * Huang Lee + */ + ++#define pr_fmt(fmt) "rga_debugger: " fmt ++ +#include +#include +#include -+#include +#include +#include +#include -+#include + +#include "rga.h" +#include "rga_debugger.h" +#include "rga_drv.h" +#include "rga_mm.h" +#include "rga_common.h" -+#include "rga_job.h" + +#define RGA_DEBUGGER_ROOT_NAME "rkrga" + @@ -1904676,7 +1903520,6 @@ index 000000000..95cc80976 +int RGA_DEBUG_INT_FLAG; +int RGA_DEBUG_MM; +int RGA_DEBUG_CHECK_MODE; -+int RGA_DEBUG_INTERNAL_MODE; +int RGA_DEBUG_NONUSE; +int RGA_DEBUG_DEBUG_MODE; +int RGA_DEBUG_DUMP_IMAGE; @@ -1904693,7 +1903536,6 @@ index 000000000..95cc80976 + "INT [%s]\n" + "MM [%s]\n" + "CHECK [%s]\n" -+ "INTL [%s]\n" + "STOP [%s]\n", + STR_ENABLE(RGA_DEBUG_REG), + STR_ENABLE(RGA_DEBUG_MSG), @@ -1904701,7 +1903543,6 @@ index 000000000..95cc80976 + STR_ENABLE(RGA_DEBUG_INT_FLAG), + STR_ENABLE(RGA_DEBUG_MM), + STR_ENABLE(RGA_DEBUG_CHECK_MODE), -+ STR_ENABLE(RGA_DEBUG_INTERNAL_MODE), + STR_ENABLE(RGA_DEBUG_NONUSE)); + + seq_puts(m, "\nhelp:\n"); @@ -1904711,7 +1903552,6 @@ index 000000000..95cc80976 + seq_puts(m, " 'echo int > debug' to enable/disable interruppt log printing.\n"); + seq_puts(m, " 'echo mm > debug' to enable/disable memory manager log printing.\n"); + seq_puts(m, " 'echo check > debug' to enable/disable check mode.\n"); -+ seq_puts(m, " 'echo intl > debug' to enable/disable internal mode.\n"); + seq_puts(m, " 'echo stop > debug' to enable/disable stop using hardware\n"); + + return 0; @@ -1904752,14 +1903592,6 @@ index 000000000..95cc80976 + RGA_DEBUG_TIME = 1; + pr_info("open rga test time!\n"); + } -+ } else if (strncmp(buf, "intl", 4) == 0) { -+ if (RGA_DEBUG_INTERNAL_MODE) { -+ RGA_DEBUG_INTERNAL_MODE = 0; -+ pr_info("close rga internal flag!\n"); -+ } else { -+ RGA_DEBUG_INTERNAL_MODE = 1; -+ pr_info("open rga internal flag!\n"); -+ } + } else if (strncmp(buf, "int", 3) == 0) { + if (RGA_DEBUG_INT_FLAG) { + RGA_DEBUG_INT_FLAG = 0; @@ -1904834,12 +1903666,11 @@ index 000000000..95cc80976 + int i; + int load; + u32 busy_time_total; -+ ktime_t now; + + session_manager = rga_drvdata->session_manager; + + seq_printf(m, "num of scheduler = %d\n", rga_drvdata->num_of_scheduler); -+ seq_puts(m, "================= load ==================\n"); ++ seq_printf(m, "================= load ==================\n"); + + for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { + scheduler = rga_drvdata->scheduler[i]; @@ -1904858,20 +1903689,13 @@ index 000000000..95cc80976 + load = 100; + + seq_printf(m, "\t load = %d%%\n", load); -+ seq_puts(m, "-----------------------------------\n"); ++ seq_printf(m, "-----------------------------------\n"); + } + -+ seq_puts(m, "=========================================\n"); -+ seq_puts(m, " \n"); -+ + mutex_lock(&session_manager->lock); + -+ now = ktime_get(); + idr_for_each_entry(&session_manager->ctx_id_idr, session, id) -+ seq_printf(m, "%-9d %-8s %-6d %-s\n", -+ session->id, -+ ktime_us_delta(now, session->last_active) < RGA_LOAD_ACTIVE_MAX_US ? -+ "active" : "idle", ++ seq_printf(m, "\t process %d: pid = %d, name: %s\n", id, + session->tgid, session->pname); + + mutex_unlock(&session_manager->lock); @@ -1904930,7 +1903754,7 @@ index 000000000..95cc80976 + (unsigned long)dump_buffer->dma_buffer->iova, + dump_buffer->dma_buffer->sgt, + dump_buffer->dma_buffer->size, -+ dump_buffer->scheduler->core); ++ dump_buffer->dma_buffer->scheduler->core); + + if (dump_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) + seq_printf(m, "\t is contiguous, pa = 0x%lx\n", @@ -1904954,7 +1903778,7 @@ index 000000000..95cc80976 + (unsigned long)dump_buffer->dma_buffer->offset, + dump_buffer->dma_buffer->sgt, + dump_buffer->dma_buffer->size, -+ dump_buffer->scheduler->core); ++ dump_buffer->dma_buffer->scheduler->core); + + if (dump_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) + seq_printf(m, "\t is contiguous, pa = 0x%lx\n", @@ -1905126,65 +1903950,6 @@ index 000000000..95cc80976 + return 0; +} + -+static int rga_reset_show(struct seq_file *m, void *data) -+{ -+ struct rga_scheduler_t *scheduler = NULL; -+ int i; -+ -+ seq_puts(m, "help:\n"); -+ seq_puts(m, " 'echo > reset' to reset hardware.\n"); -+ -+ seq_puts(m, "core:\n"); -+ for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { -+ scheduler = rga_drvdata->scheduler[i]; -+ -+ seq_printf(m, " %s core <%d>\n", -+ dev_driver_string(scheduler->dev), scheduler->core); -+ } -+ -+ return 0; -+} -+ -+static ssize_t rga_reset_write(struct file *file, const char __user *ubuf, -+ size_t len, loff_t *offp) -+{ -+ char buf[14]; -+ int i, ret; -+ int reset_core = 0; -+ int reset_done = false; -+ struct rga_scheduler_t *scheduler = NULL; -+ -+ if (len > sizeof(buf) - 1) -+ return -EINVAL; -+ if (copy_from_user(buf, ubuf, len)) -+ return -EFAULT; -+ buf[len - 1] = '\0'; -+ -+ ret = kstrtoint(buf, 10, &reset_core); -+ if (ret < 0 || reset_core <= 0) { -+ pr_err("invalid core! failed to reset hardware, data = %s len = %zu.\n", buf, len); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { -+ scheduler = rga_drvdata->scheduler[i]; -+ -+ if (scheduler->core == reset_core) { -+ reset_done = true; -+ pr_info("reset hardware core[%d]!\n", reset_core); -+ -+ rga_request_scheduler_abort(scheduler); -+ -+ break; -+ } -+ } -+ -+ if (!reset_done) -+ pr_err("cannot find core[%d]\n", reset_core); -+ -+ return len; -+} -+ +static struct rga_debugger_list rga_debugger_root_list[] = { + {"debug", rga_debug_show, rga_debug_write, NULL}, + {"driver_version", rga_version_show, NULL, NULL}, @@ -1905197,7 +1903962,6 @@ index 000000000..95cc80976 + {"dump_image", rga_dump_image_show, rga_dump_image_write, NULL}, +#endif + {"hardware", rga_hardware_show, NULL, NULL}, -+ {"reset", rga_reset_show, rga_reset_write, NULL}, +}; + +static ssize_t rga_debugger_write(struct file *file, const char __user *ubuf, @@ -1905507,6 +1904271,53 @@ index 000000000..95cc80976 + req->core, req->priority, req->in_fence_fd); +} + ++void rga_cmd_print_debug_info(struct rga_req *req) ++{ ++ 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); ++} ++ +#ifdef CONFIG_NO_GKI +static int rga_dump_image_to_file(struct rga_internal_buffer *dump_buffer, + const char *channel_name, @@ -1905647,10 +1904458,10 @@ index 000000000..95cc80976 +#endif /* #ifdef CONFIG_NO_GKI */ diff --git a/drivers/video/rockchip/rga3/rga_dma_buf.c b/drivers/video/rockchip/rga3/rga_dma_buf.c new file mode 100644 -index 000000000..96609d078 +index 000000000..753348a00 --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_dma_buf.c -@@ -0,0 +1,482 @@ +@@ -0,0 +1,546 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1905658,12 +1904469,28 @@ index 000000000..96609d078 + * Author: Huang Lee + */ + ++#define pr_fmt(fmt) "rga_dma_buf: " fmt ++ +#include "rga_dma_buf.h" +#include "rga.h" +#include "rga_common.h" +#include "rga_job.h" +#include "rga_debugger.h" + ++static int rga_dma_info_to_prot(enum dma_data_direction dir) ++{ ++ switch (dir) { ++ case DMA_BIDIRECTIONAL: ++ return IOMMU_READ | IOMMU_WRITE; ++ case DMA_TO_DEVICE: ++ return IOMMU_READ; ++ case DMA_FROM_DEVICE: ++ return IOMMU_WRITE; ++ default: ++ return 0; ++ } ++} ++ +int rga_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, + unsigned long v_addr, int format, uint32_t w, + uint32_t h, unsigned long *StartAddr, unsigned long *size) @@ -1905770,7 +1904597,6 @@ index 000000000..96609d078 + pageCount = end - start; + break; + case RGA_FORMAT_YCbCr_400: -+ case RGA_FORMAT_Y8: + stride = (w + 3) & (~3); + size_yrgb = stride * h; + start = yrgb_addr >> PAGE_SHIFT; @@ -1905837,6 +1904663,165 @@ index 000000000..96609d078 + return pageCount; +} + ++static dma_addr_t rga_iommu_dma_alloc_iova(struct iommu_domain *domain, ++ size_t size, u64 dma_limit, ++ struct device *dev) ++{ ++ struct rga_iommu_dma_cookie *cookie = (void *)domain->iova_cookie; ++ struct iova_domain *iovad = &cookie->iovad; ++ unsigned long shift, iova_len, iova = 0; ++ ++ shift = iova_shift(iovad); ++ iova_len = size >> shift; ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)) ++ /* ++ * Freeing non-power-of-two-sized allocations back into the IOVA caches ++ * will come back to bite us badly, so we have to waste a bit of space ++ * rounding up anything cacheable to make sure that can't happen. The ++ * order of the unadjusted size will still match upon freeing. ++ */ ++ if (iova_len < (1 << (IOVA_RANGE_CACHE_MAX_SIZE - 1))) ++ iova_len = roundup_pow_of_two(iova_len); ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) ++ dma_limit = min_not_zero(dma_limit, dev->bus_dma_limit); ++#else ++ if (dev->bus_dma_mask) ++ dma_limit &= dev->bus_dma_mask; ++#endif ++ ++ if (domain->geometry.force_aperture) ++ dma_limit = min(dma_limit, (u64)domain->geometry.aperture_end); ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(4, 19, 111) && \ ++ LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) ++ iova = alloc_iova_fast(iovad, iova_len, ++ min_t(dma_addr_t, dma_limit >> shift, iovad->end_pfn), ++ true); ++#else ++ iova = alloc_iova_fast(iovad, iova_len, dma_limit >> shift, true); ++#endif ++ ++ return (dma_addr_t)iova << shift; ++} ++ ++static void rga_iommu_dma_free_iova(struct iommu_domain *domain, ++ dma_addr_t iova, size_t size) ++{ ++ struct rga_iommu_dma_cookie *cookie = (void *)domain->iova_cookie; ++ struct iova_domain *iovad = &cookie->iovad; ++ ++ free_iova_fast(iovad, iova_pfn(iovad, iova), size >> iova_shift(iovad)); ++} ++ ++static inline struct iommu_domain *rga_iommu_get_dma_domain(struct device *dev) ++{ ++ return iommu_get_domain_for_dev(dev); ++} ++ ++void rga_iommu_unmap(struct rga_dma_buffer *buffer) ++{ ++ if (buffer == NULL) ++ return; ++ if (buffer->iova == 0) ++ return; ++ ++ iommu_unmap(buffer->domain, buffer->iova, buffer->size); ++ rga_iommu_dma_free_iova(buffer->domain, buffer->iova, buffer->size); ++} ++ ++int rga_iommu_map_sgt(struct sg_table *sgt, size_t size, ++ struct rga_dma_buffer *buffer, ++ struct device *rga_dev) ++{ ++ struct iommu_domain *domain = NULL; ++ struct rga_iommu_dma_cookie *cookie; ++ struct iova_domain *iovad; ++ dma_addr_t iova; ++ size_t map_size; ++ unsigned long align_size; ++ ++ if (sgt == NULL) { ++ pr_err("can not map iommu, because sgt is null!\n"); ++ return -EINVAL; ++ } ++ ++ domain = rga_iommu_get_dma_domain(rga_dev); ++ cookie = (void *)domain->iova_cookie; ++ iovad = &cookie->iovad; ++ align_size = iova_align(iovad, size); ++ ++ if (DEBUGGER_EN(MSG)) ++ pr_info("iova_align size = %ld", align_size); ++ ++ iova = rga_iommu_dma_alloc_iova(domain, align_size, rga_dev->coherent_dma_mask, rga_dev); ++ if (!iova) { ++ pr_err("rga_iommu_dma_alloc_iova failed"); ++ return -ENOMEM; ++ } ++ ++ map_size = iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, ++ rga_dma_info_to_prot(DMA_BIDIRECTIONAL)); ++ if (map_size < align_size) { ++ pr_err("iommu can not map sgt to iova"); ++ rga_iommu_dma_free_iova(domain, iova, align_size); ++ return -EINVAL; ++ } ++ ++ buffer->domain = domain; ++ buffer->iova = iova; ++ buffer->size = align_size; ++ ++ return 0; ++} ++ ++int rga_iommu_map(phys_addr_t paddr, size_t size, ++ struct rga_dma_buffer *buffer, ++ struct device *rga_dev) ++{ ++ int ret; ++ struct iommu_domain *domain = NULL; ++ struct rga_iommu_dma_cookie *cookie; ++ struct iova_domain *iovad; ++ dma_addr_t iova; ++ unsigned long align_size; ++ ++ if (paddr == 0) { ++ pr_err("can not map iommu, because phys_addr is 0!\n"); ++ return -EINVAL; ++ } ++ ++ domain = rga_iommu_get_dma_domain(rga_dev); ++ cookie = (void *)domain->iova_cookie; ++ iovad = &cookie->iovad; ++ align_size = iova_align(iovad, size); ++ ++ if (DEBUGGER_EN(MSG)) ++ pr_info("iova_align size = %ld", align_size); ++ ++ iova = rga_iommu_dma_alloc_iova(domain, align_size, rga_dev->coherent_dma_mask, rga_dev); ++ if (!iova) { ++ pr_err("rga_iommu_dma_alloc_iova failed"); ++ return -ENOMEM; ++ } ++ ++ ret = iommu_map(domain, iova, paddr, align_size, ++ rga_dma_info_to_prot(DMA_BIDIRECTIONAL)); ++ if (ret) { ++ pr_err("iommu can not map phys_addr to iova"); ++ rga_iommu_dma_free_iova(domain, iova, align_size); ++ return ret; ++ } ++ ++ buffer->domain = domain; ++ buffer->iova = iova; ++ buffer->size = align_size; ++ ++ return 0; ++} ++ +int rga_virtual_memory_check(void *vaddr, u32 w, u32 h, u32 format, int fd) +{ + int bits = 32; @@ -1905849,20 +1904834,20 @@ index 000000000..96609d078 + + one_line = kzalloc(w * 4, GFP_KERNEL); + if (!one_line) { -+ rga_err("kzalloc fail %s[%d]\n", __func__, __LINE__); ++ pr_err("kzalloc fail %s[%d]\n", __func__, __LINE__); + return 0; + } + + temp_data = w * (h - 1) * bits >> 3; + if (fd > 0) { -+ rga_log("vaddr is%p, bits is %d, fd check\n", vaddr, bits); ++ pr_info("vaddr is%p, bits is %d, fd check\n", vaddr, bits); + memcpy(one_line, (char *)vaddr + temp_data, w * bits >> 3); -+ rga_log("fd check ok\n"); ++ pr_info("fd check ok\n"); + } else { -+ rga_log("vir addr memory check.\n"); ++ pr_info("vir addr memory check.\n"); + memcpy((void *)((char *)vaddr + temp_data), one_line, + w * bits >> 3); -+ rga_log("vir addr check ok.\n"); ++ pr_info("vir addr check ok.\n"); + } + + kfree(one_line); @@ -1905873,7 +1904858,7 @@ index 000000000..96609d078 +{ + int ret = 0; + void *vaddr; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) + struct iosys_map map; +#endif + struct dma_buf *dma_buf; @@ -1905881,7 +1904866,7 @@ index 000000000..96609d078 + dma_buf = rga_dma_buffer->dma_buf; + + if (!IS_ERR_OR_NULL(dma_buf)) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) + ret = dma_buf_vmap(dma_buf, &map); + vaddr = ret ? NULL : map.vaddr; +#else @@ -1905891,10 +1904876,10 @@ index 000000000..96609d078 + ret = rga_virtual_memory_check(vaddr, img->vir_w, + img->vir_h, img->format, img->yrgb_addr); + } else { -+ rga_err("can't vmap the dma buffer!\n"); ++ pr_err("can't vmap the dma buffer!\n"); + return -EINVAL; + } -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) + dma_buf_vunmap(dma_buf, &map); +#else + dma_buf_vunmap(dma_buf, vaddr); @@ -1905904,103 +1904889,43 @@ index 000000000..96609d078 + return ret; +} + -+int rga_dma_map_phys_addr(phys_addr_t phys_addr, size_t size, struct rga_dma_buffer *buffer, -+ enum dma_data_direction dir, struct device *map_dev) ++int rga_dma_map_buf(struct dma_buf *dma_buf, struct rga_dma_buffer *rga_dma_buffer, ++ enum dma_data_direction dir, struct device *rga_dev) +{ -+ dma_addr_t addr; ++ struct dma_buf_attachment *attach = NULL; ++ struct sg_table *sgt = NULL; ++ struct scatterlist *sg = NULL; ++ int i, ret = 0; + -+ addr = dma_map_resource(map_dev, phys_addr, size, dir, 0); -+ if (addr == DMA_MAPPING_ERROR) { -+ rga_err("dma_map_resouce failed!\n"); ++ if (dma_buf != NULL) { ++ get_dma_buf(dma_buf); ++ } else { ++ pr_err("dma_buf is invalid[%p]\n", dma_buf); + return -EINVAL; + } + -+ buffer->dma_addr = addr; -+ buffer->dir = dir; -+ buffer->size = size; -+ buffer->map_dev = map_dev; -+ -+ return 0; -+} -+ -+void rga_dma_unmap_phys_addr(struct rga_dma_buffer *buffer) -+{ -+ dma_unmap_resource(buffer->map_dev, buffer->dma_addr, buffer->size, buffer->dir, 0); -+} -+ -+int rga_dma_map_sgt(struct sg_table *sgt, struct rga_dma_buffer *buffer, -+ enum dma_data_direction dir, struct device *map_dev) -+{ -+ int i, ret = 0; -+ struct scatterlist *sg = NULL; -+ -+ ret = dma_map_sg(map_dev, sgt->sgl, sgt->orig_nents, dir); -+ if (ret <= 0) { -+ rga_err("dma_map_sg failed! ret = %d\n", ret); -+ return ret < 0 ? ret : -EINVAL; -+ } -+ sgt->nents = ret; -+ -+ buffer->sgt = sgt; -+ buffer->dma_addr = sg_dma_address(sgt->sgl); -+ buffer->dir = dir; -+ buffer->size = 0; -+ for_each_sgtable_sg(sgt, sg, i) -+ buffer->size += sg_dma_len(sg); -+ buffer->map_dev = map_dev; -+ -+ return 0; -+} -+ -+void rga_dma_unmap_sgt(struct rga_dma_buffer *buffer) -+{ -+ if (!buffer->sgt) -+ return; -+ -+ dma_unmap_sg(buffer->map_dev, -+ buffer->sgt->sgl, -+ buffer->sgt->orig_nents, -+ buffer->dir); -+} -+ -+int rga_dma_map_buf(struct dma_buf *dma_buf, struct rga_dma_buffer *rga_dma_buffer, -+ enum dma_data_direction dir, struct device *map_dev) -+{ -+ struct dma_buf_attachment *attach = NULL; -+ struct sg_table *sgt = NULL; -+ struct scatterlist *sg = NULL; -+ int i, ret = 0; -+ -+ if (dma_buf != NULL) { -+ get_dma_buf(dma_buf); -+ } else { -+ rga_err("dma_buf is invalid[%p]\n", dma_buf); -+ return -EINVAL; -+ } -+ -+ attach = dma_buf_attach(dma_buf, map_dev); -+ if (IS_ERR(attach)) { -+ ret = PTR_ERR(attach); -+ rga_err("Failed to attach dma_buf, ret[%d]\n", ret); -+ goto err_get_attach; -+ } ++ attach = dma_buf_attach(dma_buf, rga_dev); ++ if (IS_ERR(attach)) { ++ ret = PTR_ERR(attach); ++ pr_err("Failed to attach dma_buf, ret[%d]\n", ret); ++ goto err_get_attach; ++ } + + sgt = dma_buf_map_attachment(attach, dir); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); -+ rga_err("Failed to map attachment, ret[%d]\n", ret); ++ pr_err("Failed to map attachment, ret[%d]\n", ret); + goto err_get_sgt; + } + + rga_dma_buffer->dma_buf = dma_buf; + rga_dma_buffer->attach = attach; + rga_dma_buffer->sgt = sgt; -+ rga_dma_buffer->dma_addr = sg_dma_address(sgt->sgl); ++ rga_dma_buffer->iova = sg_dma_address(sgt->sgl); + rga_dma_buffer->dir = dir; + rga_dma_buffer->size = 0; + for_each_sgtable_sg(sgt, sg, i) + rga_dma_buffer->size += sg_dma_len(sg); -+ rga_dma_buffer->map_dev = map_dev; + + return ret; + @@ -1906015,7 +1904940,7 @@ index 000000000..96609d078 +} + +int rga_dma_map_fd(int fd, struct rga_dma_buffer *rga_dma_buffer, -+ enum dma_data_direction dir, struct device *map_dev) ++ enum dma_data_direction dir, struct device *rga_dev) +{ + struct dma_buf *dma_buf = NULL; + struct dma_buf_attachment *attach = NULL; @@ -1906026,33 +1904951,32 @@ index 000000000..96609d078 + dma_buf = dma_buf_get(fd); + if (IS_ERR(dma_buf)) { + ret = PTR_ERR(dma_buf); -+ rga_err("Fail to get dma_buf from fd[%d], ret[%d]\n", fd, ret); ++ pr_err("Fail to get dma_buf from fd[%d], ret[%d]\n", fd, ret); + return ret; + } + -+ attach = dma_buf_attach(dma_buf, map_dev); ++ attach = dma_buf_attach(dma_buf, rga_dev); + if (IS_ERR(attach)) { + ret = PTR_ERR(attach); -+ rga_err("Failed to attach dma_buf, ret[%d]\n", ret); ++ pr_err("Failed to attach dma_buf, ret[%d]\n", ret); + goto err_get_attach; + } + + sgt = dma_buf_map_attachment(attach, dir); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); -+ rga_err("Failed to map attachment, ret[%d]\n", ret); ++ pr_err("Failed to map attachment, ret[%d]\n", ret); + goto err_get_sgt; + } + + rga_dma_buffer->dma_buf = dma_buf; + rga_dma_buffer->attach = attach; + rga_dma_buffer->sgt = sgt; -+ rga_dma_buffer->dma_addr = sg_dma_address(sgt->sgl); ++ rga_dma_buffer->iova = sg_dma_address(sgt->sgl); + rga_dma_buffer->dir = dir; + rga_dma_buffer->size = 0; + for_each_sgtable_sg(sgt, sg, i) + rga_dma_buffer->size += sg_dma_len(sg); -+ rga_dma_buffer->map_dev = map_dev; + + return ret; + @@ -1906084,61 +1905008,12 @@ index 000000000..96609d078 + dma_sync_single_for_device(scheduler->dev, virt_to_phys(pstart), + pend - pstart, DMA_TO_DEVICE); +} -+ -+int rga_dma_free(struct rga_dma_buffer *buffer) -+{ -+ if (buffer == NULL) { -+ rga_err("rga_dma_buffer is NULL.\n"); -+ return -EINVAL; -+ } -+ -+ dma_free_coherent(buffer->map_dev, buffer->size, buffer->vaddr, buffer->dma_addr); -+ buffer->vaddr = NULL; -+ buffer->dma_addr = 0; -+ buffer->iova = 0; -+ buffer->size = 0; -+ buffer->map_dev = NULL; -+ -+ kfree(buffer); -+ -+ return 0; -+} -+ -+struct rga_dma_buffer *rga_dma_alloc_coherent(struct rga_scheduler_t *scheduler, -+ int size) -+{ -+ size_t align_size; -+ dma_addr_t dma_addr; -+ struct rga_dma_buffer *buffer; -+ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (!buffer) -+ return NULL; -+ -+ align_size = PAGE_ALIGN(size); -+ buffer->vaddr = dma_alloc_coherent(scheduler->dev, align_size, &dma_addr, GFP_KERNEL); -+ if (!buffer->vaddr) -+ goto fail_dma_alloc; -+ -+ buffer->size = align_size; -+ buffer->dma_addr = dma_addr; -+ buffer->map_dev = scheduler->dev; -+ if (scheduler->data->mmu == RGA_IOMMU) -+ buffer->iova = buffer->dma_addr; -+ -+ return buffer; -+ -+fail_dma_alloc: -+ kfree(buffer); -+ -+ return NULL; -+} diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c new file mode 100644 -index 000000000..9ef013bb6 +index 000000000..2d80c8089 --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_drv.c -@@ -0,0 +1,1678 @@ +@@ -0,0 +1,1615 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1906146,6 +1905021,8 @@ index 000000000..9ef013bb6 + * Author: Huang Lee + */ + ++#define pr_fmt(fmt) "rga: " fmt ++ +#include "rga2_reg_info.h" +#include "rga3_reg_info.h" +#include "rga_dma_buf.h" @@ -1906166,6 +1905043,7 @@ index 000000000..9ef013bb6 +static ktime_t kt; + +static struct rga_session *rga_session_init(void); ++static int rga_session_deinit(struct rga_session *session); + +static int rga_mpi_set_channel_buffer(struct dma_buf *dma_buf, + struct rga_img_info_t *channel_info, @@ -1906182,7 +1905060,7 @@ index 000000000..9ef013bb6 + + buffer.handle = rga_mm_import_buffer(&buffer, session); + if (buffer.handle == 0) { -+ rga_err("can not import dma_buf %p\n", dma_buf); ++ pr_err("can not import dma_buf %p\n", dma_buf); + return -EFAULT; + } + channel_info->yrgb_addr = buffer.handle; @@ -1906253,28 +1905131,25 @@ index 000000000..9ef013bb6 + mutex_lock(&request_manager->lock); + request = rga_request_lookup(request_manager, mpi_job->ctx_id); + if (IS_ERR_OR_NULL(request)) { -+ rga_err("can not find request from id[%d]", mpi_job->ctx_id); ++ pr_err("can not find request from id[%d]", mpi_job->ctx_id); + mutex_unlock(&request_manager->lock); + return -EINVAL; + } + + if (request->task_count > 1) { + /* TODO */ -+ rga_req_err(request, "Currently request does not support multiple tasks!"); ++ pr_err("Currently request does not support multiple tasks!"); + mutex_unlock(&request_manager->lock); + return -EINVAL; + } + ++ /* ++ * The mpi commit will use the request repeatedly, so an additional ++ * get() is added here. ++ */ + rga_request_get(request); + mutex_unlock(&request_manager->lock); + -+ down_read(&request->session->release_rwsem); -+ if (request->session->release) { -+ rga_req_err(request, "current session has been release\n"); -+ ret = -EFAULT; -+ goto err_release_rwsem; -+ } -+ + spin_lock_irqsave(&request->lock, flags); + + /* TODO: batch mode need mpi async mode */ @@ -1906313,7 +1905188,7 @@ index 000000000..9ef013bb6 + &mpi_cmd.src, + request->session); + if (ret < 0) { -+ rga_req_err(request, "src channel set buffer handle failed!\n"); ++ pr_err("src channel set buffer handle failed!\n"); + goto err_put_request; + } + } @@ -1906323,7 +1905198,7 @@ index 000000000..9ef013bb6 + &mpi_cmd.pat, + request->session); + if (ret < 0) { -+ rga_req_err(request, "src1 channel set buffer handle failed!\n"); ++ pr_err("src1 channel set buffer handle failed!\n"); + goto err_put_request; + } + } @@ -1906333,7 +1905208,7 @@ index 000000000..9ef013bb6 + &mpi_cmd.dst, + request->session); + if (ret < 0) { -+ rga_req_err(request, "dst channel set buffer handle failed!\n"); ++ pr_err("dst channel set buffer handle failed!\n"); + goto err_put_request; + } + } @@ -1906343,21 +1905218,28 @@ index 000000000..9ef013bb6 + mpi_cmd.mmu_info.mmu_flag = 0; + + if (DEBUGGER_EN(MSG)) -+ rga_dump_req(request, &mpi_cmd); ++ rga_cmd_print_debug_info(&mpi_cmd); + + ret = rga_request_mpi_submit(&mpi_cmd, request); + if (ret < 0) { + if (ret == -ERESTARTSYS) { + if (DEBUGGER_EN(MSG)) -+ rga_req_err(request, "%s, commit mpi job failed, by a software interrupt.\n", ++ pr_err("%s, commit mpi job failed, by a software interrupt.\n", + __func__); + } else { -+ rga_req_err(request, "%s, commit mpi job failed\n", __func__); ++ pr_err("%s, commit mpi job failed\n", __func__); + } + + goto err_put_request; + } + ++ if ((mpi_job->dma_buf_src0 != NULL) && (mpi_cmd.src.yrgb_addr > 0)) ++ rga_mm_release_buffer(mpi_cmd.src.yrgb_addr); ++ if ((mpi_job->dma_buf_src1 != NULL) && (mpi_cmd.pat.yrgb_addr > 0)) ++ rga_mm_release_buffer(mpi_cmd.pat.yrgb_addr); ++ if ((mpi_job->dma_buf_dst != NULL) && (mpi_cmd.dst.yrgb_addr > 0)) ++ rga_mm_release_buffer(mpi_cmd.dst.yrgb_addr); ++ + /* copy dst info to mpi job for next node */ + if (mpi_job->output != NULL) { + mpi_job->output->x_offset = mpi_cmd.dst.x_offset; @@ -1906370,17 +1905252,9 @@ index 000000000..9ef013bb6 + mpi_job->output->format = mpi_cmd.dst.format; + } + -+err_put_request: -+ if ((mpi_job->dma_buf_src0 != NULL) && (mpi_cmd.src.yrgb_addr > 0)) -+ rga_mm_release_buffer(mpi_cmd.src.yrgb_addr); -+ if ((mpi_job->dma_buf_src1 != NULL) && (mpi_cmd.pat.yrgb_addr > 0)) -+ rga_mm_release_buffer(mpi_cmd.pat.yrgb_addr); -+ if ((mpi_job->dma_buf_dst != NULL) && (mpi_cmd.dst.yrgb_addr > 0)) -+ rga_mm_release_buffer(mpi_cmd.dst.yrgb_addr); -+ -+err_release_rwsem: -+ up_read(&request->session->release_rwsem); ++ return 0; + ++err_put_request: + mutex_lock(&request_manager->lock); + rga_request_put(request); + mutex_unlock(&request_manager->lock); @@ -1906402,13 +1905276,11 @@ index 000000000..9ef013bb6 + if (IS_ERR(session)) + return PTR_ERR(session); + -+ down_read(&session->release_rwsem); -+ + request_id = rga_request_alloc(0, session); + if (request_id < 0) { -+ rga_err("request alloc error!\n"); ++ pr_err("request alloc error!\n"); + ret = request_id; -+ goto err_put_session; ++ return ret; + } + + memset(&kernel_request, 0, sizeof(kernel_request)); @@ -1906419,48 +1905291,51 @@ index 000000000..9ef013bb6 + + ret = rga_request_check(&kernel_request); + if (ret < 0) { -+ rga_err("ID[%d]: user request check error!\n", kernel_request.id); -+ goto err_put_request; ++ pr_err("user request check error!\n"); ++ goto err_free_request_by_id; + } + + request = rga_request_kernel_config(&kernel_request); + if (IS_ERR(request)) { -+ rga_err("ID[%d]: config failed!\n", kernel_request.id); ++ pr_err("request[%d] config failed!\n", kernel_request.id); + ret = -EFAULT; -+ goto err_put_request; ++ goto err_free_request_by_id; + } + + if (DEBUGGER_EN(MSG)) { -+ rga_req_log(request, "kernel blit mode:\n"); -+ rga_dump_req(request, cmd); ++ pr_info("kernel blit mode: request id = %d", kernel_request.id); ++ rga_cmd_print_debug_info(cmd); + } + + ret = rga_request_submit(request); -+ if (ret < 0) -+ rga_req_err(request, "submit failed!\n"); ++ if (ret < 0) { ++ pr_err("request[%d] submit failed!\n", kernel_request.id); ++ goto err_put_request; ++ } + +err_put_request: + mutex_lock(&request_manager->lock); ++ rga_request_put(request); ++ mutex_unlock(&request_manager->lock); + -+ if (request == NULL) { -+ request = rga_request_lookup(request_manager, request_id); -+ if (IS_ERR_OR_NULL(request)) { -+ rga_err("can not find request from id[%d]", request_id); ++ rga_session_deinit(session); + -+ mutex_unlock(&request_manager->lock); -+ ret = -EINVAL; -+ goto err_put_session; -+ } ++ return ret; ++ ++err_free_request_by_id: ++ mutex_lock(&request_manager->lock); ++ ++ request = rga_request_lookup(request_manager, request_id); ++ if (IS_ERR_OR_NULL(request)) { ++ pr_err("can not find request from id[%d]", request_id); ++ mutex_unlock(&request_manager->lock); ++ return -EINVAL; + } + -+ rga_request_put(request); ++ rga_request_free(request); + + mutex_unlock(&request_manager->lock); + -+err_put_session: -+ up_read(&session->release_rwsem); -+ rga_session_put(session); -+ + return ret; +} +EXPORT_SYMBOL_GPL(rga_kernel_commit); @@ -1906483,8 +1905358,8 @@ index 000000000..9ef013bb6 + /* if timer action on job running */ + job = scheduler->running_job; + if (job) { -+ scheduler->timer.busy_time += ktime_us_delta(now, job->timestamp.hw_recode); -+ job->timestamp.hw_recode = now; ++ scheduler->timer.busy_time += ktime_us_delta(now, job->hw_recoder_time); ++ job->hw_recoder_time = now; + } + + scheduler->timer.busy_time_record = scheduler->timer.busy_time; @@ -1906516,14 +1905391,19 @@ index 000000000..9ef013bb6 +int rga_power_enable(struct rga_scheduler_t *scheduler) +{ + int ret = -EINVAL; ++ int i; + unsigned long flags; + + pm_runtime_get_sync(scheduler->dev); + pm_stay_awake(scheduler->dev); + -+ ret = clk_bulk_prepare_enable(scheduler->num_clks, scheduler->clks); -+ if (ret < 0) -+ goto err_enable_clk; ++ for (i = 0; i < scheduler->num_clks; i++) { ++ if (!IS_ERR(scheduler->clks[i])) { ++ ret = clk_prepare_enable(scheduler->clks[i]); ++ if (ret < 0) ++ goto err_enable_clk; ++ } ++ } + + spin_lock_irqsave(&scheduler->irq_lock, flags); + @@ -1906536,6 +1905416,10 @@ index 000000000..9ef013bb6 + return 0; + +err_enable_clk: ++ for (--i; i >= 0; --i) ++ if (!IS_ERR(scheduler->clks[i])) ++ clk_disable_unprepare(scheduler->clks[i]); ++ + pm_relax(scheduler->dev); + pm_runtime_put_sync_suspend(scheduler->dev); + @@ -1906544,6 +1905428,7 @@ index 000000000..9ef013bb6 + +int rga_power_disable(struct rga_scheduler_t *scheduler) +{ ++ int i; + unsigned long flags; + + spin_lock_irqsave(&scheduler->irq_lock, flags); @@ -1906561,7 +1905446,9 @@ index 000000000..9ef013bb6 + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + -+ clk_bulk_disable_unprepare(scheduler->num_clks, scheduler->clks); ++ for (i = scheduler->num_clks - 1; i >= 0; i--) ++ if (!IS_ERR(scheduler->clks[i])) ++ clk_disable_unprepare(scheduler->clks[i]); + + pm_relax(scheduler->dev); + pm_runtime_put_sync_suspend(scheduler->dev); @@ -1906579,7 +1905466,7 @@ index 000000000..9ef013bb6 + scheduler = rga_drvdata->scheduler[i]; + ret = rga_power_enable(scheduler); + if (ret < 0) -+ rga_err("power enable failed"); ++ pr_err("power enable failed"); + } +} + @@ -1906684,13 +1905571,13 @@ index 000000000..9ef013bb6 + + session_manager = rga_drvdata->session_manager; + if (session_manager == NULL) { -+ rga_err("rga_session_manager is null!\n"); ++ pr_err("rga_session_manager is null!\n"); + return ERR_PTR(-EFAULT); + } + + session = kzalloc(sizeof(*session), GFP_KERNEL); + if (!session) { -+ rga_err("rga_session alloc failed\n"); ++ pr_err("rga_session alloc failed\n"); + return ERR_PTR(-ENOMEM); + } + @@ -1906702,7 +1905589,7 @@ index 000000000..9ef013bb6 + if (new_id < 0) { + mutex_unlock(&session_manager->lock); + -+ rga_err("rga_session alloc id failed!\n"); ++ pr_err("rga_session alloc id failed!\n"); + kfree(session); + return ERR_PTR(new_id); + } @@ -1906715,34 +1905602,20 @@ index 000000000..9ef013bb6 + session->tgid = current->tgid; + session->pname = kstrdup_quotable_cmdline(current, GFP_KERNEL); + -+ session->last_active = ktime_get(); -+ session->release = false; -+ init_rwsem(&session->release_rwsem); -+ kref_init(&session->refcount); -+ + return session; +} + -+static void rga_session_kref_release(struct kref *ref) ++static int rga_session_deinit(struct rga_session *session) +{ -+ struct rga_session *session; -+ -+ session = container_of(ref, struct rga_session, refcount); ++ rga_request_session_destroy_abort(session); ++ rga_mm_session_release_buffer(session); + + rga_session_free_remove_idr(session); + + kfree(session->pname); + kfree(session); -+} -+ -+int rga_session_put(struct rga_session *session) -+{ -+ return kref_put(&session->refcount, rga_session_kref_release); -+} + -+void rga_session_get(struct rga_session *session) -+{ -+ kref_get(&session->refcount); ++ return 0; +} + +static long rga_ioctl_import_buffer(unsigned long arg, struct rga_session *session) @@ -1906755,32 +1905628,32 @@ index 000000000..9ef013bb6 + if (unlikely(copy_from_user(&buffer_pool, + (struct rga_buffer_pool *)arg, + sizeof(buffer_pool)))) { -+ rga_err("rga_buffer_pool copy_from_user failed!\n"); ++ pr_err("rga_buffer_pool copy_from_user failed!\n"); + return -EFAULT; + } + + if (buffer_pool.size > RGA_BUFFER_POOL_SIZE_MAX) { -+ rga_err("Cannot import more than %d buffers at a time!\n", ++ pr_err("Cannot import more than %d buffers at a time!\n", + RGA_BUFFER_POOL_SIZE_MAX); + return -EFBIG; + } + + if (buffer_pool.buffers_ptr == 0) { -+ rga_err("Import buffers is NULL!\n"); ++ pr_err("Import buffers is NULL!\n"); + return -EFAULT; + } + + external_buffer = kmalloc(sizeof(struct rga_external_buffer) * buffer_pool.size, + GFP_KERNEL); + if (external_buffer == NULL) { -+ rga_err("external buffer list alloc error!\n"); ++ pr_err("external buffer list alloc error!\n"); + return -ENOMEM; + } + + if (unlikely(copy_from_user(external_buffer, + u64_to_user_ptr(buffer_pool.buffers_ptr), + sizeof(struct rga_external_buffer) * buffer_pool.size))) { -+ rga_err("rga_buffer_pool external_buffer list copy_from_user failed\n"); ++ pr_err("rga_buffer_pool external_buffer list copy_from_user failed\n"); + ret = -EFAULT; + + goto err_free_external_buffer; @@ -1906788,13 +1905661,13 @@ index 000000000..9ef013bb6 + + for (i = 0; i < buffer_pool.size; i++) { + if (DEBUGGER_EN(MSG)) { -+ rga_log("import buffer info:\n"); ++ pr_info("import buffer info:\n"); + rga_dump_external_buffer(&external_buffer[i]); + } + + ret = rga_mm_import_buffer(&external_buffer[i], session); + if (ret <= 0) { -+ rga_err("buffer[%d] mm import buffer failed! memory = 0x%lx, type = %s(0x%x)\n", ++ pr_err("buffer[%d] mm import buffer failed! memory = 0x%lx, type = %s(0x%x)\n", + i, (unsigned long)external_buffer[i].memory, + rga_get_memory_type_str(external_buffer[i].type), + external_buffer[i].type); @@ -1906808,7 +1905681,7 @@ index 000000000..9ef013bb6 + if (unlikely(copy_to_user(u64_to_user_ptr(buffer_pool.buffers_ptr), + external_buffer, + sizeof(struct rga_external_buffer) * buffer_pool.size))) { -+ rga_err("rga_buffer_pool external_buffer list copy_to_user failed\n"); ++ pr_err("rga_buffer_pool external_buffer list copy_to_user failed\n"); + ret = -EFAULT; + + goto err_free_external_buffer; @@ -1906829,32 +1905702,32 @@ index 000000000..9ef013bb6 + if (unlikely(copy_from_user(&buffer_pool, + (struct rga_buffer_pool *)arg, + sizeof(buffer_pool)))) { -+ rga_err("rga_buffer_pool copy_from_user failed!\n"); ++ pr_err("rga_buffer_pool copy_from_user failed!\n"); + return -EFAULT; + } + + if (buffer_pool.size > RGA_BUFFER_POOL_SIZE_MAX) { -+ rga_err("Cannot release more than %d buffers at a time!\n", ++ pr_err("Cannot release more than %d buffers at a time!\n", + RGA_BUFFER_POOL_SIZE_MAX); + return -EFBIG; + } + + if (buffer_pool.buffers_ptr == 0) { -+ rga_err("Release buffers is NULL!\n"); ++ pr_err("Release buffers is NULL!\n"); + return -EFAULT; + } + + external_buffer = kmalloc(sizeof(struct rga_external_buffer) * buffer_pool.size, + GFP_KERNEL); + if (external_buffer == NULL) { -+ rga_err("external buffer list alloc error!\n"); ++ pr_err("external buffer list alloc error!\n"); + return -ENOMEM; + } + + if (unlikely(copy_from_user(external_buffer, + u64_to_user_ptr(buffer_pool.buffers_ptr), + sizeof(struct rga_external_buffer) * buffer_pool.size))) { -+ rga_err("rga_buffer_pool external_buffer list copy_from_user failed\n"); ++ pr_err("rga_buffer_pool external_buffer list copy_from_user failed\n"); + ret = -EFAULT; + + goto err_free_external_buffer; @@ -1906862,11 +1905735,11 @@ index 000000000..9ef013bb6 + + for (i = 0; i < buffer_pool.size; i++) { + if (DEBUGGER_EN(MSG)) -+ rga_log("release buffer handle[%d]\n", external_buffer[i].handle); ++ pr_info("release buffer handle[%d]\n", external_buffer[i].handle); + + ret = rga_mm_release_buffer(external_buffer[i].handle); + if (ret < 0) { -+ rga_err("buffer[%d] mm release buffer failed! handle = %d\n", ++ pr_err("buffer[%d] mm release buffer failed! handle = %d\n", + i, external_buffer[i].handle); + + goto err_free_external_buffer; @@ -1906884,14 +1905757,14 @@ index 000000000..9ef013bb6 + uint32_t flags; + + if (copy_from_user(&flags, (void *)arg, sizeof(uint32_t))) { -+ rga_err("%s failed to copy from user!\n", __func__); ++ pr_err("%s failed to copy from usrer!\n", __func__); + return -EFAULT; + } + + id = rga_request_alloc(flags, session); + + if (copy_to_user((void *)arg, &id, sizeof(uint32_t))) { -+ rga_err("%s failed to copy to user!\n", __func__); ++ pr_err("%s failed to copy to usrer!\n", __func__); + return -EFAULT; + } + @@ -1906910,29 +1905783,29 @@ index 000000000..9ef013bb6 + if (unlikely(copy_from_user(&user_request, + (struct rga_user_request *)arg, + sizeof(user_request)))) { -+ rga_err("%s copy_from_user failed!\n", __func__); ++ pr_err("%s copy_from_user failed!\n", __func__); + return -EFAULT; + } + + ret = rga_request_check(&user_request); + if (ret < 0) { -+ rga_err("user request check error!\n"); ++ pr_err("user request check error!\n"); + return ret; + } + + if (DEBUGGER_EN(MSG)) -+ rga_log("config request id = %d", user_request.id); ++ pr_info("config request id = %d", user_request.id); + + request = rga_request_config(&user_request); + if (IS_ERR_OR_NULL(request)) { -+ rga_err("request[%d] config failed!\n", user_request.id); ++ pr_err("request[%d] config failed!\n", user_request.id); + return -EFAULT; + } + + if (run_enbale) { + ret = rga_request_submit(request); + if (ret < 0) { -+ rga_err("request[%d] submit failed!\n", user_request.id); ++ pr_err("request[%d] submit failed!\n", user_request.id); + return -EFAULT; + } + @@ -1906940,7 +1905813,7 @@ index 000000000..9ef013bb6 + user_request.release_fence_fd = request->release_fence_fd; + if (copy_to_user((struct rga_req *)arg, + &user_request, sizeof(user_request))) { -+ rga_err("copy_to_user failed\n"); ++ pr_err("copy_to_user failed\n"); + return -EFAULT; + } + } @@ -1906961,23 +1905834,23 @@ index 000000000..9ef013bb6 + + request_manager = rga_drvdata->pend_request_manager; + if (request_manager == NULL) { -+ rga_err("rga_pending_request_manager is null!\n"); ++ pr_err("rga_pending_request_manager is null!\n"); + return -EFAULT; + } + + if (unlikely(copy_from_user(&id, (uint32_t *)arg, sizeof(uint32_t)))) { -+ rga_err("request id copy_from_user failed!\n"); ++ pr_err("request id copy_from_user failed!\n"); + return -EFAULT; + } + + if (DEBUGGER_EN(MSG)) -+ rga_log("config cancel request id = %d", id); ++ pr_info("config cancel request id = %d", id); + + mutex_lock(&request_manager->lock); + + request = rga_request_lookup(request_manager, id); + if (IS_ERR_OR_NULL(request)) { -+ rga_err("can not find request from id[%d]", id); ++ pr_err("can not find request from id[%d]", id); + mutex_unlock(&request_manager->lock); + return -EINVAL; + } @@ -1907000,7 +1905873,7 @@ index 000000000..9ef013bb6 + + request_id = rga_request_alloc(0, session); + if (request_id < 0) { -+ rga_err("request alloc error!\n"); ++ pr_err("request alloc error!\n"); + ret = request_id; + return ret; + } @@ -1907013,13 +1905886,13 @@ index 000000000..9ef013bb6 + + ret = rga_request_check(&user_request); + if (ret < 0) { -+ rga_err("ID[%d]: user request check error!\n", user_request.id); ++ pr_err("user request check error!\n"); + goto err_free_request_by_id; + } + + request = rga_request_config(&user_request); + if (IS_ERR(request)) { -+ rga_err("ID[%d]: config failed!\n", user_request.id); ++ pr_err("request[%d] config failed!\n", user_request.id); + ret = -EFAULT; + goto err_free_request_by_id; + } @@ -1907030,14 +1905903,14 @@ index 000000000..9ef013bb6 + + ret = rga_request_submit(request); + if (ret < 0) { -+ rga_req_err(request, "submit failed!\n"); ++ pr_err("request[%d] submit failed!\n", user_request.id); + goto err_put_request; + } + + if (request->sync_mode == RGA_BLIT_ASYNC) { + rga_req->out_fence_fd = request->release_fence_fd; + if (copy_to_user((struct rga_req *)arg, rga_req, sizeof(struct rga_req))) { -+ rga_req_err(request, "copy_to_user failed\n"); ++ pr_err("copy_to_user failed\n"); + ret = -EFAULT; + goto err_put_request; + } @@ -1907055,7 +1905928,7 @@ index 000000000..9ef013bb6 + + request = rga_request_lookup(request_manager, request_id); + if (IS_ERR_OR_NULL(request)) { -+ rga_err("can not find request from id[%d]", request_id); ++ pr_err("can not find request from id[%d]", request_id); + mutex_unlock(&request_manager->lock); + return -EINVAL; + } @@ -1907079,34 +1905952,13 @@ index 000000000..9ef013bb6 + struct rga_session *session = file->private_data; + + if (!rga) { -+ rga_err("rga_drvdata is null, rga is not init\n"); ++ pr_err("rga_drvdata is null, rga is not init\n"); + return -ENODEV; + } + + if (DEBUGGER_EN(NONUSE)) + return 0; + -+ if (cmd == RGA_BLIT_ASYNC && !IS_ENABLED(CONFIG_ROCKCHIP_RGA_ASYNC)) { -+ rga_log("The current driver does not support asynchronous mode, please enable CONFIG_ROCKCHIP_RGA_ASYNC.\n"); -+ -+ return -EINVAL; -+ } -+ -+ down_read(&session->release_rwsem); -+ down_read(&rga_drvdata->rwsem); -+ -+ if (rga_drvdata->shutdown || session->release) { -+ up_read(&rga_drvdata->rwsem); -+ up_read(&session->release_rwsem); -+ -+ if (rga_drvdata->shutdown) -+ rga_log("driver has been shutdown\n"); -+ else if (session->release) -+ rga_log("current session has been release\n"); -+ -+ return -EBUSY; -+ } -+ + switch (cmd) { + case RGA_BLIT_SYNC: + case RGA_BLIT_ASYNC: @@ -1907228,14 +1906080,11 @@ index 000000000..9ef013bb6 + case RGA_IMPORT_DMA: + case RGA_RELEASE_DMA: + default: -+ rga_err("unknown ioctl cmd!\n"); ++ pr_err("unknown ioctl cmd!\n"); + ret = -EINVAL; + break; + } + -+ up_read(&rga_drvdata->rwsem); -+ up_read(&session->release_rwsem); -+ + return ret; +} + @@ -1907297,18 +1906146,7 @@ index 000000000..9ef013bb6 +{ + struct rga_session *session = file->private_data; + -+ down_write(&session->release_rwsem); -+ -+ session->release = true; -+ -+ rga_request_session_destroy_abort(session); -+ rga_mm_session_release_buffer(session); -+ -+ up_write(&session->release_rwsem); -+ -+ rga_session_put(session); -+ -+ file->private_data = NULL; ++ rga_session_deinit(session); + + return 0; +} @@ -1907317,26 +1906155,9 @@ index 000000000..9ef013bb6 +{ + irqreturn_t irq_ret = IRQ_NONE; + struct rga_scheduler_t *scheduler = data; -+ ktime_t timestamp = ktime_get(); + -+ spin_lock(&scheduler->irq_lock); -+ -+ if (scheduler->ops->irq) { ++ if (scheduler->ops->irq) + irq_ret = scheduler->ops->irq(scheduler); -+ if (irq_ret == IRQ_HANDLED) { -+ spin_unlock(&scheduler->irq_lock); -+ return irq_ret; -+ } -+ } -+ -+ if (scheduler->running_job == NULL) { -+ spin_unlock(&scheduler->irq_lock); -+ return IRQ_HANDLED; -+ } -+ -+ scheduler->running_job->timestamp.hw_done = timestamp; -+ -+ spin_unlock(&scheduler->irq_lock); + + return irq_ret; +} @@ -1907349,7 +1906170,7 @@ index 000000000..9ef013bb6 + + job = rga_job_done(scheduler); + if (job == NULL) { -+ rga_err("isr thread invalid job!\n"); ++ pr_err("isr thread invalid job!\n"); + return IRQ_HANDLED; + } + @@ -1907381,97 +1906202,103 @@ index 000000000..9ef013bb6 + .fops = &rga_fops, +}; + -+static const struct rga_match_data_t rga2_match_data = { -+ .device_type = RGA_DEVICE_RGA2, -+ .ops = &rga2_ops, ++static const char *const old_rga2_clks[] = { ++ "aclk_rga", ++ "hclk_rga", ++ "clk_rga", +}; + -+static const struct rga_match_data_t rga3_match_data = { -+ .device_type = RGA_DEVICE_RGA3, -+ .ops = &rga3_ops, ++static const char *const rk3588_rga2_clks[] = { ++ "aclk_rga2", ++ "hclk_rga2", ++ "clk_rga2", +}; + -+static const struct of_device_id rga3_dt_ids[] = { -+ { -+ .compatible = "rockchip,rga3", -+ .data = &rga3_match_data, -+ }, -+ /* legacy */ ++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_match_data_t old_rga2_match_data = { ++ .clks = old_rga2_clks, ++ .num_clks = ARRAY_SIZE(old_rga2_clks), ++}; ++ ++static const struct rga_match_data_t rk3588_rga2_match_data = { ++ .clks = rk3588_rga2_clks, ++ .num_clks = ARRAY_SIZE(rk3588_rga2_clks), ++}; ++ ++static const struct rga_match_data_t rga3_core0_match_data = { ++ .clks = rga3_core_0_clks, ++ .num_clks = ARRAY_SIZE(rga3_core_0_clks), ++}; ++ ++static const struct rga_match_data_t rga3_core1_match_data = { ++ .clks = rga3_core_1_clks, ++ .num_clks = ARRAY_SIZE(rga3_core_1_clks), ++}; ++ ++static const struct of_device_id rga3_core0_dt_ids[] = { + { + .compatible = "rockchip,rga3_core0", -+ .data = &rga3_match_data, ++ .data = &rga3_core0_match_data, + }, ++ {}, ++}; ++ ++static const struct of_device_id rga3_core1_dt_ids[] = { + { + .compatible = "rockchip,rga3_core1", -+ .data = &rga3_match_data, ++ .data = &rga3_core1_match_data, + }, + {}, +}; + +static const struct of_device_id rga2_dt_ids[] = { + { -+ .compatible = "rockchip,rga2", -+ .data = &rga2_match_data, ++ .compatible = "rockchip,rga2_core0", ++ .data = &rk3588_rga2_match_data, + }, -+ /* legacy */ + { -+ .compatible = "rockchip,rga2_core0", -+ .data = &rga2_match_data, ++ .compatible = "rockchip,rga2", ++ .data = &old_rga2_match_data, + }, + {}, +}; + -+static int init_scheduler(struct rga_scheduler_t *scheduler, -+ struct device *dev, -+ const struct rga_match_data_t *match_data, -+ struct rga_drvdata_t *drv_data) ++static void init_scheduler(struct rga_scheduler_t *scheduler, ++ const char *name) +{ -+ switch (match_data->device_type) { -+ case RGA_DEVICE_RGA2: -+ switch (drv_data->device_count[match_data->device_type]) { -+ case 0: -+ scheduler->core = RGA2_SCHEDULER_CORE0; -+ break; -+ case 1: -+ scheduler->core = RGA2_SCHEDULER_CORE1; -+ break; -+ default: -+ pr_err("scheduler failed to match RGA2\n"); -+ return -EINVAL; -+ } -+ -+ break; -+ case RGA_DEVICE_RGA3: -+ switch (drv_data->device_count[match_data->device_type]) { -+ case 0: -+ scheduler->core = RGA3_SCHEDULER_CORE0; -+ break; -+ case 1: -+ scheduler->core = RGA3_SCHEDULER_CORE1; -+ break; -+ default: -+ pr_err("scheduler failed to match RGA2\n"); -+ return -EINVAL; -+ } -+ -+ break; -+ default: -+ -+ return -EINVAL; -+ } -+ -+ scheduler->ops = match_data->ops; -+ scheduler->dev = dev; -+ + spin_lock_init(&scheduler->irq_lock); + INIT_LIST_HEAD(&scheduler->todo_list); + init_waitqueue_head(&scheduler->job_done_wq); + -+ return 0; ++ if (!strcmp(name, "rga3_core0")) { ++ scheduler->ops = &rga3_ops; ++ /* TODO: get by hw version */ ++ scheduler->core = RGA3_SCHEDULER_CORE0; ++ } else if (!strcmp(name, "rga3_core1")) { ++ scheduler->ops = &rga3_ops; ++ scheduler->core = RGA3_SCHEDULER_CORE1; ++ } else if (!strcmp(name, "rga2")) { ++ scheduler->ops = &rga2_ops; ++ scheduler->core = RGA2_SCHEDULER_CORE0; ++ } +} + +static int rga_drv_probe(struct platform_device *pdev) +{ ++#ifndef RGA_DISABLE_PM ++ int i; ++#endif + int ret = 0; + int irq; + struct resource *res; @@ -1907484,73 +1906311,80 @@ index 000000000..9ef013bb6 + if (!dev->of_node) + return -EINVAL; + -+ if (!strcmp(dev_driver_string(dev), "rga3")) -+ match = of_match_device(rga3_dt_ids, dev); ++ 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); + else + match = NULL; ++ + if (!match) { -+ dev_err(dev, "missing DT entry!\n"); ++ dev_err(dev, "%s missing DT entry!\n", dev_driver_string(dev)); + return -EINVAL; + } + + scheduler = devm_kzalloc(dev, sizeof(struct rga_scheduler_t), GFP_KERNEL); + if (scheduler == NULL) { -+ dev_err(dev, "failed to allocate scheduler.\n"); ++ pr_err("failed to allocate scheduler. dev name = %s\n", dev_driver_string(dev)); + return -ENOMEM; + } + -+ match_data = match->data; -+ ret = init_scheduler(scheduler, dev, match_data, data); -+ if (ret < 0) { -+ dev_err(dev, "init scheduler failed!\n"); -+ return ret; -+ } ++ init_scheduler(scheduler, dev_driver_string(dev)); ++ ++ scheduler->dev = dev; + + /* map the registers */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { -+ dev_err(dev, "get memory resource failed.\n"); ++ pr_err("get memory resource failed.\n"); + return -ENXIO; + } + + scheduler->rga_base = devm_ioremap(dev, res->start, resource_size(res)); + if (!scheduler->rga_base) { -+ dev_err(dev, "ioremap failed\n"); ++ 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 in dts\n"); ++ dev_err(dev, "no irq %s in dts\n", dev_driver_string(dev)); + return irq; + } + + scheduler->irq = irq; + ++ pr_info("%s, irq = %d, match scheduler\n", dev_driver_string(dev), irq); ++ + ret = devm_request_threaded_irq(dev, irq, + rga_irq_handler, + rga_isr_thread, + IRQF_SHARED, + dev_driver_string(dev), scheduler); + if (ret < 0) { -+ dev_err(dev, "request irq failed: %d\n", ret); ++ pr_err("request irq name: %s failed: %d\n", dev_driver_string(dev), ret); + return ret; + } + + +#ifndef RGA_DISABLE_PM + /* clk init */ -+ ret = devm_clk_bulk_get_all(dev, &scheduler->clks); -+ if (ret < 1) { -+ dev_err(dev, "failed to get clk\n"); -+ return ret < 0 ? ret : -EINVAL; ++ 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]); ++ ++ scheduler->clks[i] = clk; + } -+ scheduler->num_clks = ret; ++ scheduler->num_clks = match_data->num_clks; + + /* PM init */ + device_init_wakeup(dev, true); @@ -1907558,52 +1906392,47 @@ index 000000000..9ef013bb6 + + ret = pm_runtime_get_sync(scheduler->dev); + if (ret < 0) { -+ dev_err(dev, "failed to get pm runtime, ret = %d\n", ret); ++ pr_err("failed to get pm runtime, ret = %d\n", ret); + goto pm_disable; + } + -+ ret = clk_bulk_prepare_enable(scheduler->num_clks, scheduler->clks); -+ if (ret < 0) { -+ dev_err(dev, "failed to enable clk\n"); -+ goto pm_disable; ++ for (i = 0; i < scheduler->num_clks; i++) { ++ if (!IS_ERR(scheduler->clks[i])) { ++ ret = clk_prepare_enable(scheduler->clks[i]); ++ if (ret < 0) { ++ pr_err("failed to enable clk\n"); ++ goto pm_disable; ++ } ++ } + } +#endif /* #ifndef RGA_DISABLE_PM */ + + scheduler->ops->get_version(scheduler); ++ pr_info("%s hardware loaded successfully, hw_version:%s.\n", ++ dev_driver_string(dev), scheduler->version.str); + + /* TODO: get by hw version, Currently only supports judgment 1106. */ + if (scheduler->core == RGA3_SCHEDULER_CORE0 || + scheduler->core == RGA3_SCHEDULER_CORE1) { + scheduler->data = &rga3_data; -+ } else if (scheduler->core == RGA2_SCHEDULER_CORE0 || -+ scheduler->core == RGA2_SCHEDULER_CORE1) { -+ if (!strcmp(scheduler->version.str, "3.3.87975")) { ++ } else if (scheduler->core == RGA2_SCHEDULER_CORE0) { ++ if (!strcmp(scheduler->version.str, "3.3.87975")) + scheduler->data = &rga2e_1106_data; -+ } else if (!strcmp(scheduler->version.str, "3.6.92812") || -+ !strcmp(scheduler->version.str, "3.7.93215")) { ++ else if (!strcmp(scheduler->version.str, "3.6.92812") || ++ !strcmp(scheduler->version.str, "3.7.93215")) + scheduler->data = &rga2e_iommu_data; -+ } else if (!strcmp(scheduler->version.str, "3.a.07135")) { -+ scheduler->data = &rga2e_3506_data; -+ } else if (!strcmp(scheduler->version.str, "3.e.19357")) { -+ scheduler->data = &rga2p_iommu_data; -+ rga_hw_set_issue_mask(scheduler, RGA_HW_ISSUE_DIS_AUTO_RST); -+ } else if (!strcmp(scheduler->version.str, "3.f.23690")) { -+ scheduler->data = &rga2p_lite_1103b_data; -+ } else if (scheduler->version.major == 0x4 && -+ scheduler->version.minor == 0x1 && -+ scheduler->version.revision == 0x34669) { -+ scheduler->data = &rga2p_iommu_non_fbc_data; -+ } else { ++ else + scheduler->data = &rga2e_data; -+ } + } + + data->scheduler[data->num_of_scheduler] = scheduler; ++ + data->num_of_scheduler++; -+ data->device_count[match_data->device_type]++; + +#ifndef RGA_DISABLE_PM -+ clk_bulk_disable_unprepare(scheduler->num_clks, scheduler->clks); ++ for (i = scheduler->num_clks - 1; i >= 0; i--) ++ if (!IS_ERR(scheduler->clks[i])) ++ clk_disable_unprepare(scheduler->clks[i]); + + pm_runtime_put_sync(dev); +#endif /* #ifndef RGA_DISABLE_PM */ @@ -1907614,18 +1906443,11 @@ index 000000000..9ef013bb6 + dev_err(dev, "failed to attach iommu\n"); + scheduler->iommu_info = NULL; + } -+ -+ dma_set_mask(dev, DMA_BIT_MASK(40)); -+ dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); -+ } else { -+ dma_set_mask(dev, DMA_BIT_MASK(32)); -+ dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + } + + platform_set_drvdata(pdev, scheduler); + -+ dev_info(dev, "probe successfully, irq = %d, hw_version:%s\n", -+ scheduler->irq, scheduler->version.str); ++ pr_info("%s probe successfully\n", dev_driver_string(dev)); + + return 0; + @@ -1907638,56 +1906460,37 @@ index 000000000..9ef013bb6 + return ret; +} + -+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) +static int rga_drv_remove(struct platform_device *pdev) -+#else -+static void rga_drv_remove(struct platform_device *pdev) -+#endif +{ -+ struct rga_scheduler_t *scheduler = NULL; -+ -+ down_write(&rga_drvdata->rwsem); -+ rga_drvdata->shutdown = true; -+ -+ scheduler = (struct rga_scheduler_t *)platform_get_drvdata(pdev); -+ if (scheduler) -+ rga_request_scheduler_shutdown(scheduler); -+ +#ifndef RGA_DISABLE_PM + device_init_wakeup(&pdev->dev, false); + pm_runtime_disable(&pdev->dev); +#endif /* #ifndef RGA_DISABLE_PM */ + -+ up_write(&rga_drvdata->rwsem); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) + return 0; -+#endif +} + -+static void rga_drv_shutdown(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ -+ rga_drv_remove(pdev); -+ -+ dev_info(dev, "shutdown success\n"); -+} ++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_driver = { ++static struct platform_driver rga3_core1_driver = { + .probe = rga_drv_probe, + .remove = rga_drv_remove, -+ .shutdown = rga_drv_shutdown, + .driver = { -+ .name = "rga3", -+ .of_match_table = of_match_ptr(rga3_dt_ids), ++ .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, -+ .shutdown = rga_drv_shutdown, + .driver = { + .name = "rga2", + .of_match_table = of_match_ptr(rga2_dt_ids), @@ -1907705,18 +1906508,23 @@ index 000000000..9ef013bb6 + } + + mutex_init(&rga_drvdata->lock); -+ init_rwsem(&rga_drvdata->rwsem); -+ rga_drvdata->shutdown = false; + -+ ret = platform_driver_register(&rga3_driver); ++ ret = platform_driver_register(&rga3_core0_driver); + if (ret != 0) { -+ pr_err("Platform device rga3_driver register failed (%d).\n", ret); ++ pr_err("Platform device rga3_core0_driver register failed (%d).\n", ret); + goto err_free_drvdata; + } ++ ++ ret = platform_driver_register(&rga3_core1_driver); ++ if (ret != 0) { ++ pr_err("Platform device rga3_core1_driver register failed (%d).\n", ret); ++ goto err_unregister_rga3_core0; ++ } ++ + ret = platform_driver_register(&rga2_driver); + if (ret != 0) { + pr_err("Platform device rga2_driver register failed (%d).\n", ret); -+ goto err_unregister_rga3; ++ goto err_unregister_rga3_core1; + } + + ret = rga_iommu_bind(); @@ -1907757,8 +1906565,11 @@ index 000000000..9ef013bb6 +err_unregister_rga2: + platform_driver_unregister(&rga2_driver); + -+err_unregister_rga3: -+ platform_driver_unregister(&rga3_driver); ++err_unregister_rga3_core1: ++ platform_driver_unregister(&rga3_core1_driver); ++ ++err_unregister_rga3_core0: ++ platform_driver_unregister(&rga3_core0_driver); + +err_free_drvdata: + kfree(rga_drvdata); @@ -1907786,7 +1906597,8 @@ index 000000000..9ef013bb6 + + rga_iommu_unbind(); + -+ platform_driver_unregister(&rga3_driver); ++ platform_driver_unregister(&rga3_core0_driver); ++ platform_driver_unregister(&rga3_core1_driver); + platform_driver_unregister(&rga2_driver); + + misc_deregister(&rga_dev); @@ -1907819,10 +1906631,10 @@ index 000000000..9ef013bb6 +#endif diff --git a/drivers/video/rockchip/rga3/rga_fence.c b/drivers/video/rockchip/rga3/rga_fence.c new file mode 100644 -index 000000000..9c663f3be +index 000000000..7d831d55d --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_fence.c -@@ -0,0 +1,145 @@ +@@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1907830,13 +1906642,14 @@ index 000000000..9c663f3be + * Author: Huang Lee + */ + ++#define pr_fmt(fmt) "rga_fence: " fmt ++ +#include +#include +#include + +#include "rga_drv.h" +#include "rga_fence.h" -+#include "rga_common.h" + +static const char *rga_fence_get_name(struct dma_fence *fence) +{ @@ -1907881,7 +1906694,7 @@ index 000000000..9c663f3be + struct dma_fence *fence = NULL; + + if (fence_ctx == NULL) { -+ rga_err("fence_context is NULL!\n"); ++ pr_err("fence_context is NULL!\n"); + return ERR_PTR(-EINVAL); + } + @@ -1907924,7 +1906737,7 @@ index 000000000..9c663f3be + + fence = sync_file_get_fence(fence_fd); + if (!fence) -+ rga_err("can not get fence from fd\n"); ++ pr_err("can not get fence from fd\n"); + + return fence; +} @@ -1907947,7 +1906760,7 @@ index 000000000..9c663f3be + + waiter = kmalloc(sizeof(*waiter), GFP_KERNEL); + if (!waiter) { -+ rga_err("%s: Failed to allocate waiter\n", __func__); ++ pr_err("%s: Failed to allocate waiter\n", __func__); + return -ENOMEM; + } + @@ -1907955,10 +1906768,10 @@ index 000000000..9c663f3be + + ret = dma_fence_add_callback(fence, &waiter->waiter, func); + if (ret == -ENOENT) { -+ rga_err("'input fence' has been already signaled."); ++ pr_err("'input fence' has been already signaled."); + goto err_free_waiter; + } else if (ret == -EINVAL) { -+ rga_err("%s: failed to add callback to dma_fence, err: %d\n", __func__, ret); ++ pr_err("%s: failed to add callback to dma_fence, err: %d\n", __func__, ret); + goto err_free_waiter; + } + @@ -1907970,10 +1906783,10 @@ index 000000000..9c663f3be +} diff --git a/drivers/video/rockchip/rga3/rga_hw_config.c b/drivers/video/rockchip/rga3/rga_hw_config.c new file mode 100644 -index 000000000..d558c1513 +index 000000000..0cf2599b9 --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_hw_config.c -@@ -0,0 +1,743 @@ +@@ -0,0 +1,352 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1907990,8 +1906803,6 @@ index 000000000..d558c1513 +const uint32_t rga3_input_raster_format[] = { + RGA_FORMAT_RGBA_8888, + RGA_FORMAT_BGRA_8888, -+ RGA_FORMAT_RGBX_8888, -+ RGA_FORMAT_BGRX_8888, + RGA_FORMAT_RGB_888, + RGA_FORMAT_BGR_888, + RGA_FORMAT_RGB_565, @@ -1908015,8 +1906826,6 @@ index 000000000..d558c1513 +const uint32_t rga3_output_raster_format[] = { + RGA_FORMAT_RGBA_8888, + RGA_FORMAT_BGRA_8888, -+ RGA_FORMAT_RGBX_8888, -+ RGA_FORMAT_BGRX_8888, + RGA_FORMAT_RGB_888, + RGA_FORMAT_BGR_888, + RGA_FORMAT_RGB_565, @@ -1908038,8 +1906847,6 @@ index 000000000..d558c1513 +const uint32_t rga3_fbcd_format[] = { + RGA_FORMAT_RGBA_8888, + RGA_FORMAT_BGRA_8888, -+ RGA_FORMAT_RGBX_8888, -+ RGA_FORMAT_BGRX_8888, + RGA_FORMAT_RGB_888, + RGA_FORMAT_BGR_888, + RGA_FORMAT_RGB_565, @@ -1908091,6 +1906898,10 @@ index 000000000..d558c1513 + RGA_FORMAT_YCbCr_422_SP_10B, + RGA_FORMAT_YCrCb_422_SP_10B, + RGA_FORMAT_YCbCr_400, ++ RGA_FORMAT_RGBA_5551, ++ RGA_FORMAT_BGRA_5551, ++ RGA_FORMAT_RGBA_4444, ++ RGA_FORMAT_BGRA_4444, + RGA_FORMAT_XRGB_8888, + RGA_FORMAT_XBGR_8888, + RGA_FORMAT_BPP1, @@ -1908136,112 +1906947,6 @@ index 000000000..d558c1513 + RGA_FORMAT_YCrCb_422_SP_10B, + RGA_FORMAT_Y4, + RGA_FORMAT_YCbCr_400, -+ RGA_FORMAT_XRGB_8888, -+ RGA_FORMAT_XBGR_8888, -+ RGA_FORMAT_ARGB_8888, -+ RGA_FORMAT_ARGB_5551, -+ RGA_FORMAT_ARGB_4444, -+ RGA_FORMAT_ABGR_8888, -+ RGA_FORMAT_ABGR_5551, -+ RGA_FORMAT_ABGR_4444, -+}; -+ -+const uint32_t rga2p_input_raster_format[] = { -+ RGA_FORMAT_RGBA_8888, -+ RGA_FORMAT_RGBX_8888, -+ RGA_FORMAT_BGRA_8888, -+ RGA_FORMAT_BGRX_8888, -+ RGA_FORMAT_RGB_888, -+ RGA_FORMAT_BGR_888, -+ RGA_FORMAT_RGB_565, -+ RGA_FORMAT_BGR_565, -+ RGA_FORMAT_YCbCr_422_P, -+ RGA_FORMAT_YCbCr_420_P, -+ RGA_FORMAT_YCrCb_422_P, -+ RGA_FORMAT_YCrCb_420_P, -+ RGA_FORMAT_YCbCr_422_SP, -+ RGA_FORMAT_YCbCr_420_SP, -+ RGA_FORMAT_YCrCb_422_SP, -+ RGA_FORMAT_YCrCb_420_SP, -+ RGA_FORMAT_YVYU_422, -+ RGA_FORMAT_VYUY_422, -+ RGA_FORMAT_YUYV_422, -+ RGA_FORMAT_UYVY_422, -+ RGA_FORMAT_YCbCr_420_SP_10B, -+ RGA_FORMAT_YCrCb_420_SP_10B, -+ RGA_FORMAT_YCbCr_422_SP_10B, -+ RGA_FORMAT_YCrCb_422_SP_10B, -+ RGA_FORMAT_YCbCr_400, -+ RGA_FORMAT_XRGB_8888, -+ RGA_FORMAT_XBGR_8888, -+ RGA_FORMAT_BPP1, -+ RGA_FORMAT_BPP2, -+ RGA_FORMAT_BPP4, -+ RGA_FORMAT_BPP8, -+ RGA_FORMAT_ARGB_8888, -+ RGA_FORMAT_ARGB_5551, -+ RGA_FORMAT_ARGB_4444, -+ RGA_FORMAT_ABGR_8888, -+ RGA_FORMAT_ABGR_5551, -+ RGA_FORMAT_ABGR_4444, -+ RGA_FORMAT_RGBA_2BPP, -+ RGA_FORMAT_A8, -+ RGA_FORMAT_YCbCr_444_SP, -+ RGA_FORMAT_YCrCb_444_SP, -+}; -+ -+const uint32_t rga2p_input1_raster_format[] = { -+ RGA_FORMAT_RGBA_8888, -+ RGA_FORMAT_BGRA_8888, -+ RGA_FORMAT_RGBX_8888, -+ RGA_FORMAT_BGRX_8888, -+ RGA_FORMAT_XRGB_8888, -+ RGA_FORMAT_XBGR_8888, -+ RGA_FORMAT_ARGB_8888, -+ RGA_FORMAT_ABGR_8888, -+ RGA_FORMAT_ARGB_5551, -+ RGA_FORMAT_ABGR_5551, -+ RGA_FORMAT_ARGB_4444, -+ RGA_FORMAT_ABGR_4444, -+ RGA_FORMAT_RGB_888, -+ RGA_FORMAT_BGR_888, -+ RGA_FORMAT_RGB_565, -+ RGA_FORMAT_BGR_565, -+ RGA_FORMAT_A8, -+}; -+ -+const uint32_t rga2p_output_raster_format[] = { -+ RGA_FORMAT_RGBA_8888, -+ RGA_FORMAT_RGBX_8888, -+ RGA_FORMAT_BGRA_8888, -+ RGA_FORMAT_BGRX_8888, -+ RGA_FORMAT_RGB_888, -+ RGA_FORMAT_BGR_888, -+ RGA_FORMAT_RGB_565, -+ RGA_FORMAT_BGR_565, -+ RGA_FORMAT_YCbCr_422_P, -+ RGA_FORMAT_YCbCr_420_P, -+ RGA_FORMAT_YCrCb_422_P, -+ RGA_FORMAT_YCrCb_420_P, -+ RGA_FORMAT_YCbCr_422_SP, -+ RGA_FORMAT_YCbCr_420_SP, -+ RGA_FORMAT_YCrCb_422_SP, -+ RGA_FORMAT_YCrCb_420_SP, -+ RGA_FORMAT_YVYU_420, -+ RGA_FORMAT_VYUY_420, -+ RGA_FORMAT_YUYV_420, -+ RGA_FORMAT_UYVY_420, -+ RGA_FORMAT_YVYU_422, -+ RGA_FORMAT_VYUY_422, -+ RGA_FORMAT_YUYV_422, -+ RGA_FORMAT_UYVY_422, -+ RGA_FORMAT_YCbCr_420_SP_10B, -+ RGA_FORMAT_YCrCb_420_SP_10B, -+ RGA_FORMAT_YCbCr_422_SP_10B, -+ RGA_FORMAT_YCrCb_422_SP_10B, -+ RGA_FORMAT_Y4, -+ RGA_FORMAT_Y8, -+ RGA_FORMAT_YCbCr_400, + RGA_FORMAT_RGBA_5551, + RGA_FORMAT_BGRA_5551, + RGA_FORMAT_RGBA_4444, @@ -1908254,49 +1906959,6 @@ index 000000000..d558c1513 + RGA_FORMAT_ABGR_8888, + RGA_FORMAT_ABGR_5551, + RGA_FORMAT_ABGR_4444, -+ RGA_FORMAT_YCbCr_444_SP, -+ RGA_FORMAT_YCrCb_444_SP, -+}; -+ -+const uint32_t rga2p_tile4x4_format[] = { -+ RGA_FORMAT_YCbCr_400, -+ RGA_FORMAT_YCbCr_420_SP, -+ RGA_FORMAT_YCrCb_420_SP, -+ RGA_FORMAT_YCbCr_422_SP, -+ RGA_FORMAT_YCrCb_422_SP, -+ RGA_FORMAT_YCbCr_444_SP, -+ RGA_FORMAT_YCrCb_444_SP, -+ RGA_FORMAT_YCbCr_420_SP_10B, -+ RGA_FORMAT_YCrCb_420_SP_10B, -+ RGA_FORMAT_YCbCr_422_SP_10B, -+ RGA_FORMAT_YCrCb_422_SP_10B, -+}; -+ -+const uint32_t rga2p_rkfbc64x4_format[] = { -+ RGA_FORMAT_YCbCr_400, -+ RGA_FORMAT_YCbCr_420_SP, -+ RGA_FORMAT_YCrCb_420_SP, -+ RGA_FORMAT_YCbCr_422_SP, -+ RGA_FORMAT_YCrCb_422_SP, -+ RGA_FORMAT_YCbCr_444_SP, -+ RGA_FORMAT_YCrCb_444_SP, -+ RGA_FORMAT_YCbCr_420_SP_10B, -+ RGA_FORMAT_YCrCb_420_SP_10B, -+ RGA_FORMAT_YCbCr_422_SP_10B, -+ RGA_FORMAT_YCrCb_422_SP_10B, -+}; -+ -+const uint32_t rga2p_afbc32x8_format[] = { -+ RGA_FORMAT_RGBA_8888, -+ RGA_FORMAT_BGRA_8888, -+ RGA_FORMAT_RGBX_8888, -+ RGA_FORMAT_BGRX_8888, -+ RGA_FORMAT_XRGB_8888, -+ RGA_FORMAT_XBGR_8888, -+ RGA_FORMAT_ARGB_8888, -+ RGA_FORMAT_ABGR_8888, -+ RGA_FORMAT_RGB_888, -+ RGA_FORMAT_BGR_888, +}; + +const struct rga_win_data rga3_win_data[] = { @@ -1908339,144 +1907001,18 @@ index 000000000..d558c1513 + .formats[RGA_TILE8x8_INDEX] = rga3_tile_format, + .formats_count[RGA_TILE8x8_INDEX] = 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", -+ .formats[RGA_RASTER_INDEX] = rga2e_input_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_input_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", -+ .formats[RGA_RASTER_INDEX] = rga2e_input_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_input_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", -+ .formats[RGA_RASTER_INDEX] = rga2e_output_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_output_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_win_data rga2e_3506_win_data[] = { -+ { -+ .name = "rga2e-src0", -+ .formats[RGA_RASTER_INDEX] = rga2e_input_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_input_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", -+ .formats[RGA_RASTER_INDEX] = rga2p_input_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2p_input_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", -+ .formats[RGA_RASTER_INDEX] = rga2e_output_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_output_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_win_data rga2p_win_data[] = { -+ { -+ .name = "rga2p-src0", -+ .formats[RGA_RASTER_INDEX] = rga2p_input_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2p_input_raster_format), -+ .formats[RGA_TILE4x4_INDEX] = rga2p_tile4x4_format, -+ .formats_count[RGA_TILE4x4_INDEX] = ARRAY_SIZE(rga2p_tile4x4_format), -+ .formats[RGA_RKFBC64x4_INDEX] = rga2p_rkfbc64x4_format, -+ .formats_count[RGA_RKFBC64x4_INDEX] = ARRAY_SIZE(rga2p_rkfbc64x4_format), -+ .formats[RGA_AFBC32x8_INDEX] = rga2p_afbc32x8_format, -+ .formats_count[RGA_AFBC32x8_INDEX] = ARRAY_SIZE(rga2p_afbc32x8_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_TILE4x4_MODE | RGA_RKFBC_MODE | RGA_AFBC32x8_MODE, -+ -+ }, -+ -+ { -+ .name = "rga2p-src1", -+ .formats[RGA_RASTER_INDEX] = rga2p_input1_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2p_input1_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 | RGA_TILE4x4_MODE | RGA_RKFBC_MODE | RGA_AFBC32x8_MODE, -+ -+ }, -+ -+ { -+ .name = "rga2p-dst", -+ .formats[RGA_RASTER_INDEX] = rga2p_output_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2p_output_raster_format), -+ .formats[RGA_TILE4x4_INDEX] = rga2p_tile4x4_format, -+ .formats_count[RGA_TILE4x4_INDEX] = ARRAY_SIZE(rga2p_tile4x4_format), -+ .supported_rotations = 0, -+ .scale_up_mode = RGA_SCALE_UP_NONE, -+ .scale_down_mode = RGA_SCALE_DOWN_NONE, -+ .rd_mode = RGA_RASTER_MODE | RGA_TILE4x4_MODE, -+ -+ }, -+}; -+ -+const struct rga_win_data rga2p_non_fbc_win_data[] = { -+ { -+ .name = "rga2p-src0", -+ .formats[RGA_RASTER_INDEX] = rga2p_input_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2p_input_raster_format), -+ .formats[RGA_TILE4x4_INDEX] = rga2p_tile4x4_format, -+ .formats_count[RGA_TILE4x4_INDEX] = ARRAY_SIZE(rga2p_tile4x4_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_TILE4x4_MODE, ++ .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 = "rga2p-src1", -+ .formats[RGA_RASTER_INDEX] = rga2p_input1_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2p_input1_raster_format), ++ .name = "rga2e-src0", ++ .formats[RGA_RASTER_INDEX] = rga2e_input_raster_format, ++ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_input_raster_format), + .supported_rotations = RGA_MODE_ROTATE_MASK, + .scale_up_mode = RGA_SCALE_UP_BIC, + .scale_down_mode = RGA_SCALE_DOWN_AVG, @@ -1908485,20 +1907021,7 @@ index 000000000..d558c1513 + }, + + { -+ .name = "rga2p-dst", -+ .formats[RGA_RASTER_INDEX] = rga2p_output_raster_format, -+ .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2p_output_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_win_data rga2p_lite_win_data[] = { -+ { -+ .name = "rga2e-src0", ++ .name = "rga2e-src1", + .formats[RGA_RASTER_INDEX] = rga2e_input_raster_format, + .formats_count[RGA_RASTER_INDEX] = ARRAY_SIZE(rga2e_input_raster_format), + .supported_rotations = RGA_MODE_ROTATE_MASK, @@ -1908559,8 +1907082,7 @@ index 000000000..d558c1513 + .feature = RGA_COLOR_FILL | RGA_COLOR_PALETTE | + RGA_COLOR_KEY | RGA_ROP_CALCULATE | + RGA_NN_QUANTIZE | RGA_DITHER | RGA_FULL_CSC, -+ .csc_r2y_mode = RGA_MODE_CSC_BT601L | RGA_MODE_CSC_BT601F | -+ RGA_MODE_CSC_BT709, ++ .csc_r2y_mode = RGA_MODE_CSC_BT601L | RGA_MODE_CSC_BT601F, + .csc_y2r_mode = RGA_MODE_CSC_BT601L | RGA_MODE_CSC_BT601F | + RGA_MODE_CSC_BT709, + .mmu = RGA_MMU, @@ -1908592,30 +1907114,6 @@ index 000000000..d558c1513 + .mmu = RGA_NONE_MMU, +}; + -+const struct rga_hw_data rga2e_3506_data = { -+ .version = 0, -+ .input_range = {{2, 2}, {1280, 8192}}, -+ .output_range = {{2, 2}, {1280, 4096}}, -+ -+ .win = rga2e_3506_win_data, -+ .win_size = ARRAY_SIZE(rga2e_3506_win_data), -+ /* 1 << factor mean real factor */ -+ .max_upscale_factor = 4, -+ .max_downscale_factor = 4, -+ -+ .byte_stride_align = 4, -+ .max_byte_stride = WORD_TO_BYTE(8192), -+ -+ .feature = RGA_COLOR_FILL | RGA_COLOR_PALETTE | -+ RGA_COLOR_KEY | RGA_YIN_YOUT | RGA_YUV_HDS | RGA_YUV_VDS | -+ RGA_PRE_INTR | RGA_FULL_CSC | RGA_GAUSS, -+ .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, -+ .mmu = RGA_NONE_MMU, -+}; -+ +const struct rga_hw_data rga2e_iommu_data = { + .version = 0, + .input_range = {{2, 2}, {8192, 8192}}, @@ -1908641,88 +1907139,12 @@ index 000000000..d558c1513 + RGA_MODE_CSC_BT709, + .mmu = RGA_IOMMU, +}; -+ -+const struct rga_hw_data rga2p_iommu_data = { -+ .version = 0, -+ .input_range = {{2, 2}, {8192, 8192}}, -+ .output_range = {{2, 2}, {8192, 8192}}, -+ -+ .win = rga2p_win_data, -+ .win_size = ARRAY_SIZE(rga2p_win_data), -+ /* 1 << factor mean real factor */ -+ .max_upscale_factor = 4, -+ .max_downscale_factor = 4, -+ -+ .byte_stride_align = 4, -+ .max_byte_stride = WORD_TO_BYTE(8192), -+ -+ .feature = RGA_COLOR_FILL | RGA_COLOR_PALETTE | -+ RGA_COLOR_KEY | RGA_ROP_CALCULATE | -+ RGA_NN_QUANTIZE | RGA_DITHER | RGA_MOSAIC | -+ RGA_YIN_YOUT | RGA_YUV_HDS | RGA_YUV_VDS | -+ RGA_OSD | RGA_PRE_INTR | RGA_FULL_CSC, -+ .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, -+ .mmu = RGA_IOMMU, -+}; -+ -+const struct rga_hw_data rga2p_lite_1103b_data = { -+ .version = 0, -+ .input_range = {{2, 2}, {2880, 8192}}, -+ .output_range = {{2, 2}, {2880, 8192}}, -+ -+ .win = rga2p_lite_win_data, -+ .win_size = ARRAY_SIZE(rga2p_lite_win_data), -+ /* 1 << factor mean real factor */ -+ .max_upscale_factor = 4, -+ .max_downscale_factor = 4, -+ -+ .byte_stride_align = 4, -+ .max_byte_stride = WORD_TO_BYTE(8192), -+ -+ .feature = RGA_COLOR_FILL | RGA_DITHER | RGA_YIN_YOUT | -+ RGA_YUV_HDS | RGA_YUV_VDS | -+ RGA_PRE_INTR | RGA_FULL_CSC, -+ .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, -+ .mmu = RGA_NONE_MMU, -+}; -+ -+const struct rga_hw_data rga2p_iommu_non_fbc_data = { -+ /* Register have changed, so the version is increased. */ -+ .version = 1, -+ .input_range = {{2, 2}, {8192, 8192}}, -+ .output_range = {{2, 2}, {8192, 8192}}, -+ -+ .win = rga2p_non_fbc_win_data, -+ .win_size = ARRAY_SIZE(rga2p_non_fbc_win_data), -+ /* 1 << factor mean real factor */ -+ .max_upscale_factor = 4, -+ .max_downscale_factor = 4, -+ -+ .byte_stride_align = 4, -+ .max_byte_stride = WORD_TO_BYTE(8192), -+ -+ .feature = RGA_COLOR_FILL | RGA_COLOR_PALETTE | -+ RGA_COLOR_KEY | RGA_DITHER | -+ RGA_YIN_YOUT | RGA_YUV_HDS | RGA_YUV_VDS | -+ RGA_OSD | RGA_PRE_INTR | RGA_FULL_CSC, -+ .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, -+ .mmu = RGA_IOMMU, -+}; diff --git a/drivers/video/rockchip/rga3/rga_iommu.c b/drivers/video/rockchip/rga3/rga_iommu.c new file mode 100644 -index 000000000..4a3223e83 +index 000000000..6ef9cbc0d --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_iommu.c -@@ -0,0 +1,411 @@ +@@ -0,0 +1,425 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1908730,6 +1907152,8 @@ index 000000000..4a3223e83 + * Author: Huang Lee + */ + ++#define pr_fmt(fmt) "rga_iommu: " fmt ++ +#include "rga_iommu.h" +#include "rga_dma_buf.h" +#include "rga_mm.h" @@ -1908760,11 +1907184,11 @@ index 000000000..4a3223e83 + } + + if (flag == 1) { -+ rga_log("src user memory check\n"); -+ rga_log("tai data is %d\n", *tai_vaddr); ++ pr_info("src user memory check\n"); ++ pr_info("tai data is %d\n", *tai_vaddr); + } else { -+ rga_log("dst user memory check\n"); -+ rga_log("tai data is %d\n", *tai_vaddr); ++ pr_info("dst user memory check\n"); ++ pr_info("tai data is %d\n", *tai_vaddr); + } + + if (taidata_num == 0) @@ -1908823,14 +1907247,14 @@ index 000000000..4a3223e83 + + if ((t->back - t->front) > t->size) { + if (t->front + size > t->back - t->size) { -+ rga_log("front %d, back %d dsize %d size %d", ++ pr_info("front %d, back %d dsize %d size %d", + t->front, t->back, t->size, size); + ret = -ENOMEM; + goto out; + } + } else { + if ((t->front + size) > t->back) { -+ rga_log("front %d, back %d dsize %d size %d", ++ pr_info("front %d, back %d dsize %d size %d", + t->front, t->back, t->size, size); + ret = -ENOMEM; + goto out; @@ -1908838,7 +1907262,7 @@ index 000000000..4a3223e83 + + if (t->front + size > t->size) { + if (size > (t->back - t->size)) { -+ rga_log("front %d, back %d dsize %d size %d", ++ pr_info("front %d, back %d dsize %d size %d", + t->front, t->back, t->size, size); + ret = -ENOMEM; + goto out; @@ -1908861,7 +1907285,7 @@ index 000000000..4a3223e83 + + ret = rga_mmu_buf_get_try(mmu_base, size); + if (ret < 0) { -+ rga_err("Get MMU mem failed\n"); ++ pr_err("Get MMU mem failed\n"); + return NULL; + } + @@ -1908892,16 +1907316,28 @@ index 000000000..4a3223e83 + * malloc pre scale mid buf mmu table: + * size * channel_num * address_size + */ -+ mmu_base->buf_virtual = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32, -+ &order, size * 3 * sizeof(*mmu_base->buf_virtual)); ++ order = get_order(size * 3 * sizeof(*mmu_base->buf_virtual)); ++ if (order >= MAX_ORDER) { ++ pr_err("Can not alloc pages with order[%d] for mmu_page_table, max_order = %d\n", ++ order, MAX_ORDER); ++ goto err_free_mmu_base; ++ } ++ ++ mmu_base->buf_virtual = (uint32_t *) __get_free_pages(GFP_KERNEL | GFP_DMA32, order); + if (mmu_base->buf_virtual == NULL) { + pr_err("Can not alloc pages for mmu_page_table\n"); + goto err_free_mmu_base; + } + mmu_base->buf_order = order; + -+ mmu_base->pages = (struct page **)rga_get_free_pages(GFP_KERNEL | GFP_DMA32, -+ &order, size * sizeof(*mmu_base->pages)); ++ order = get_order(size * sizeof(*mmu_base->pages)); ++ if (order >= MAX_ORDER) { ++ pr_err("Can not alloc pages with order[%d] for mmu_base->pages, max_order = %d\n", ++ order, MAX_ORDER); ++ goto err_free_buf_virtual; ++ } ++ ++ mmu_base->pages = (struct page **)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); + if (mmu_base->pages == NULL) { + pr_err("Can not alloc pages for mmu_base->pages\n"); + goto err_free_buf_virtual; @@ -1908953,7 +1907389,7 @@ index 000000000..4a3223e83 + if (job == NULL) + return 0; + -+ rga_err("IOMMU intr fault, IOVA[0x%lx], STATUS[0x%x]\n", iova, status); ++ pr_err("IOMMU intr fault, IOVA[0x%lx], STATUS[0x%x]\n", iova, status); + if (scheduler->ops->irq) + scheduler->ops->irq(scheduler); + @@ -1908964,13 +1907400,13 @@ index 000000000..4a3223e83 + } + + if (status & RGA_IOMMU_IRQ_PAGE_FAULT) { -+ rga_err("RGA IOMMU: page fault! Please check the memory size.\n"); ++ pr_err("RGA IOMMU: page fault! Please check the memory size.\n"); + job->ret = -EACCES; + } else if (status & RGA_IOMMU_IRQ_BUS_ERROR) { -+ rga_err("RGA IOMMU: bus error! Please check if the memory is invalid or has been freed.\n"); ++ pr_err("RGA IOMMU: bus error! Please check if the memory is invalid or has been freed.\n"); + job->ret = -EACCES; + } else { -+ rga_err("RGA IOMMU: Wrong IOMMU interrupt signal!\n"); ++ pr_err("RGA IOMMU: Wrong IOMMU interrupt signal!\n"); + } + + return 0; @@ -1909136,10 +1907572,10 @@ index 000000000..4a3223e83 +} diff --git a/drivers/video/rockchip/rga3/rga_job.c b/drivers/video/rockchip/rga3/rga_job.c new file mode 100644 -index 000000000..93e47be00 +index 000000000..fae613bbf --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_job.c -@@ -0,0 +1,1558 @@ +@@ -0,0 +1,1423 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1909147,6 +1907583,8 @@ index 000000000..93e47be00 + * Author: Huang Lee + */ + ++#define pr_fmt(fmt) "rga_job: " fmt ++ +#include "rga_job.h" +#include "rga_fence.h" +#include "rga_dma_buf.h" @@ -1909157,10 +1907595,7 @@ index 000000000..93e47be00 + +static void rga_job_free(struct rga_job *job) +{ -+ if (job->cmd_buf) -+ rga_dma_free(job->cmd_buf); -+ -+ kfree(job); ++ free_page((unsigned long)job); +} + +static void rga_job_kref_release(struct kref *ref) @@ -1909186,6 +1907621,11 @@ index 000000000..93e47be00 +{ + rga_job_put(job); + ++ if (DEBUGGER_EN(TIME)) ++ pr_info("request[%d], job cleanup total cost time %lld us\n", ++ job->request_id, ++ ktime_us_delta(ktime_get(), job->timestamp)); ++ + return 0; +} + @@ -1909199,7 +1907639,7 @@ index 000000000..93e47be00 + req = &job->rga_command_base; + mm = rga_drvdata->mm; + if (mm == NULL) { -+ rga_job_err(job, "rga mm is null!\n"); ++ pr_err("rga mm is null!\n"); + return -EFAULT; + } + @@ -1909254,14 +1907694,14 @@ index 000000000..93e47be00 +{ + struct rga_job *job = NULL; + -+ job = kzalloc(sizeof(*job), GFP_KERNEL); ++ job = (struct rga_job *)get_zeroed_page(GFP_KERNEL | GFP_DMA32); + if (!job) + return NULL; + + INIT_LIST_HEAD(&job->head); + kref_init(&job->refcount); + -+ job->timestamp.init = ktime_get(); ++ job->timestamp = ktime_get(); + job->pid = current->pid; + + job->rga_command_base = *rga_command_base; @@ -1909273,13 +1907713,6 @@ index 000000000..93e47be00 + job->priority = rga_command_base->priority; + } + -+ if (DEBUGGER_EN(INTERNAL_MODE)) { -+ job->flags |= RGA_JOB_DEBUG_FAKE_BUFFER; -+ -+ /* skip subsequent flag judgments. */ -+ return job; -+ } -+ + if (job->rga_command_base.handle_flag & 1) { + job->flags |= RGA_JOB_USE_HANDLE; + @@ -1909289,6 +1907722,33 @@ index 000000000..93e47be00 + return job; +} + ++static void rga_job_dump_info(struct rga_job *job) ++{ ++ pr_info("job: reqeust_id = %d, priority = %d, core = %d\n", ++ job->request_id, job->priority, job->core); ++} ++ ++void rga_job_scheduler_dump_info(struct rga_scheduler_t *scheduler) ++{ ++ struct rga_job *job_pos; ++ ++ lockdep_assert_held(&scheduler->irq_lock); ++ ++ pr_info("===============================================================\n"); ++ pr_info("%s core = %d job_count = %d status = %d\n", ++ dev_driver_string(scheduler->dev), ++ scheduler->core, scheduler->job_count, scheduler->status); ++ ++ if (scheduler->running_job) ++ rga_job_dump_info(scheduler->running_job); ++ ++ list_for_each_entry(job_pos, &scheduler->todo_list, head) { ++ rga_job_dump_info(job_pos); ++ } ++ ++ pr_info("===============================================================\n"); ++} ++ +static int rga_job_run(struct rga_job *job, struct rga_scheduler_t *scheduler) +{ + int ret = 0; @@ -1909296,19 +1907756,23 @@ index 000000000..93e47be00 + /* enable power */ + ret = rga_power_enable(scheduler); + if (ret < 0) { -+ rga_job_err(job, "power enable failed"); ++ pr_err("power enable failed"); + return ret; + } + + ret = scheduler->ops->set_reg(job, scheduler); + if (ret < 0) { -+ rga_job_err(job, "set reg failed"); ++ pr_err("set reg failed"); + rga_power_disable(scheduler); + return ret; + } + + set_bit(RGA_JOB_STATE_RUNNING, &job->state); + ++ /* for debug */ ++ if (DEBUGGER_EN(MSG)) ++ rga_job_dump_info(job); ++ + return ret; +} + @@ -1909342,18 +1907806,18 @@ index 000000000..93e47be00 + ret = rga_job_run(job, scheduler); + /* If some error before hw run */ + if (ret < 0) { -+ rga_job_err(job, "some error on rga_job_run before hw start, %s(%d)\n", -+ __func__, __LINE__); ++ pr_err("some error on rga_job_run before hw start, %s(%d)\n", __func__, __LINE__); + + spin_lock_irqsave(&scheduler->irq_lock, flags); ++ + scheduler->running_job = NULL; ++ rga_job_put(job); ++ + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + + job->ret = ret; + rga_request_release_signal(scheduler, job); + -+ rga_job_put(job); -+ + goto next_job; + } + @@ -1909364,32 +1907828,20 @@ index 000000000..93e47be00 +{ + struct rga_job *job; + unsigned long flags; ++ ktime_t now = ktime_get(); + + spin_lock_irqsave(&scheduler->irq_lock, flags); + + job = scheduler->running_job; + if (job == NULL) { -+ rga_err("%s(%#x) running job has been cleanup.\n", -+ rga_get_core_name(scheduler->core), scheduler->core); -+ -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ return NULL; -+ } -+ -+ if (!test_bit(RGA_JOB_STATE_FINISH, &job->state) && -+ !test_bit(RGA_JOB_STATE_INTR_ERR, &job->state)) { -+ rga_err("%s(%#x) running job has not yet been completed.", -+ rga_get_core_name(scheduler->core), scheduler->core); ++ pr_err("core[0x%x] running job has been cleanup.\n", scheduler->core); + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + return NULL; + } -+ + scheduler->running_job = NULL; + -+ scheduler->timer.busy_time += -+ ktime_us_delta(job->timestamp.hw_done, job->timestamp.hw_recode); -+ job->session->last_active = job->timestamp.hw_done; ++ scheduler->timer.busy_time += ktime_us_delta(now, job->hw_recoder_time); + set_bit(RGA_JOB_STATE_DONE, &job->state); + + spin_unlock_irqrestore(&scheduler->irq_lock, flags); @@ -1909401,47 +1907853,16 @@ index 000000000..93e47be00 + rga_dump_job_image(job); + + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "hardware[%s] cost time %lld us, work cycle %d\n", ++ pr_info("request[%d], hardware[%s] cost time %lld us\n", ++ job->request_id, + rga_get_core_name(scheduler->core), -+ ktime_us_delta(job->timestamp.hw_done, job->timestamp.hw_execute), -+ job->work_cycle); ++ ktime_us_delta(now, job->hw_running_time)); + + rga_mm_unmap_job_info(job); + + return job; +} + -+static int rga_job_timeout_query_state(struct rga_job *job, int orig_ret) -+{ -+ int ret = orig_ret; -+ struct rga_scheduler_t *scheduler = job->scheduler; -+ -+ if (test_bit(RGA_JOB_STATE_DONE, &job->state) && -+ test_bit(RGA_JOB_STATE_FINISH, &job->state)) { -+ return orig_ret; -+ } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && -+ test_bit(RGA_JOB_STATE_FINISH, &job->state)) { -+ rga_job_err(job, "job hardware has finished, but the software has timeout!\n"); -+ -+ ret = -EBUSY; -+ } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && -+ !test_bit(RGA_JOB_STATE_FINISH, &job->state)) { -+ rga_job_err(job, "job hardware has timeout.\n"); -+ -+ if (scheduler->ops->read_status) -+ scheduler->ops->read_status(job, scheduler); -+ -+ ret = -EBUSY; -+ } -+ -+ rga_job_err(job, "timeout core[%d]: INTR[0x%x], HW_STATUS[0x%x], CMD_STATUS[0x%x], WORK_CYCLE[0x%x(%d)]\n", -+ scheduler->core, -+ job->intr_status, job->hw_status, job->cmd_status, -+ job->work_cycle, job->work_cycle); -+ -+ return ret; -+} -+ +static void rga_job_scheduler_timeout_clean(struct rga_scheduler_t *scheduler) +{ + unsigned long flags; @@ -1909449,15 +1907870,13 @@ index 000000000..93e47be00 + + spin_lock_irqsave(&scheduler->irq_lock, flags); + -+ if (scheduler->running_job == NULL || scheduler->running_job->timestamp.hw_execute == 0) { ++ if (scheduler->running_job == NULL || scheduler->running_job->hw_running_time == 0) { + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + return; + } + + job = scheduler->running_job; -+ if (ktime_ms_delta(ktime_get(), job->timestamp.hw_execute) >= RGA_JOB_TIMEOUT_DELAY) { -+ job->ret = rga_job_timeout_query_state(job, job->ret); -+ ++ if (ktime_ms_delta(ktime_get(), job->hw_running_time) >= RGA_JOB_TIMEOUT_DELAY) { + scheduler->running_job = NULL; + scheduler->status = RGA_SCHEDULER_ABORT; + scheduler->ops->soft_reset(scheduler); @@ -1909465,6 +1907884,8 @@ index 000000000..93e47be00 + spin_unlock_irqrestore(&scheduler->irq_lock, flags); + + rga_mm_unmap_job_info(job); ++ ++ job->ret = -EBUSY; + rga_request_release_signal(scheduler, job); + + rga_power_disable(scheduler); @@ -1909506,7 +1907927,6 @@ index 000000000..93e47be00 + list_add_tail(&job->head, &scheduler->todo_list); + } + -+ job->timestamp.insert = ktime_get(); + scheduler->job_count++; + set_bit(RGA_JOB_STATE_PENDING, &job->state); + @@ -1909526,7 +1907946,7 @@ index 000000000..93e47be00 + if (rga_drvdata->num_of_scheduler > 1) { + job->core = rga_job_assign(job); + if (job->core <= 0) { -+ rga_job_err(job, "job assign failed"); ++ pr_err("job assign failed"); + job->ret = -EINVAL; + return NULL; + } @@ -1909537,7 +1907957,7 @@ index 000000000..93e47be00 + + scheduler = job->scheduler; + if (scheduler == NULL) { -+ rga_job_err(job, "failed to get scheduler, %s(%d)\n", __func__, __LINE__); ++ pr_err("failed to get scheduler, %s(%d)\n", __func__, __LINE__); + job->ret = -EFAULT; + return NULL; + } @@ -1909545,7 +1907965,7 @@ index 000000000..93e47be00 + return scheduler; +} + -+int rga_job_commit(struct rga_req *rga_command_base, struct rga_request *request) ++struct rga_job *rga_job_commit(struct rga_req *rga_command_base, struct rga_request *request) +{ + int ret; + struct rga_job *job = NULL; @@ -1909553,8 +1907973,8 @@ index 000000000..93e47be00 + + job = rga_job_alloc(rga_command_base); + if (!job) { -+ rga_err("failed to alloc rga job!\n"); -+ return -ENOMEM; ++ pr_err("failed to alloc rga job!\n"); ++ return ERR_PTR(-ENOMEM); + } + + job->use_batch_mode = request->use_batch_mode; @@ -1909564,32 +1907984,27 @@ index 000000000..93e47be00 + + scheduler = rga_job_schedule(job); + if (scheduler == NULL) { -+ goto err_free_job; -+ } -+ -+ job->cmd_buf = rga_dma_alloc_coherent(scheduler, RGA_CMD_REG_SIZE); -+ if (job->cmd_buf == NULL) { -+ rga_job_err(job, "failed to alloc command buffer.\n"); ++ pr_err("failed to get scheduler, %s(%d)\n", __func__, __LINE__); + goto err_free_job; + } + + /* Memory mapping needs to keep pd enabled. */ + if (rga_power_enable(scheduler) < 0) { -+ rga_job_err(job, "power enable failed"); ++ pr_err("power enable failed"); + job->ret = -EFAULT; -+ goto err_free_cmd_buf; ++ goto err_free_job; + } + + ret = rga_mm_map_job_info(job); + if (ret < 0) { -+ rga_job_err(job, "%s: failed to map job info\n", __func__); ++ pr_err("%s: failed to map job info\n", __func__); + job->ret = ret; + goto err_power_disable; + } + + ret = scheduler->ops->init_reg(job); + if (ret < 0) { -+ rga_job_err(job, "%s: init reg failed", __func__); ++ pr_err("%s: init reg failed", __func__); + job->ret = ret; + goto err_unmap_job_info; + } @@ -1909600,7 +1908015,7 @@ index 000000000..93e47be00 + + rga_power_disable(scheduler); + -+ return 0; ++ return job; + +err_unmap_job_info: + rga_mm_unmap_job_info(job); @@ -1909608,15 +1908023,11 @@ index 000000000..93e47be00 +err_power_disable: + rga_power_disable(scheduler); + -+err_free_cmd_buf: -+ rga_dma_free(job->cmd_buf); -+ job->cmd_buf = NULL; -+ +err_free_job: + ret = job->ret; -+ rga_job_free(job); ++ rga_request_release_signal(scheduler, job); + -+ return ret; ++ return ERR_PTR(ret); +} + +static bool rga_is_need_current_mm(struct rga_req *req) @@ -1909695,11 +1908106,11 @@ index 000000000..93e47be00 + struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; + + if (DEBUGGER_EN(MSG)) -+ rga_req_log(request, "acquire_fence_fd = %d", acquire_fence_fd); ++ pr_info("acquire_fence_fd = %d", acquire_fence_fd); + + acquire_fence = rga_get_dma_fence_from_fd(acquire_fence_fd); + if (IS_ERR_OR_NULL(acquire_fence)) { -+ rga_req_err(request, "%s: failed to get acquire dma_fence from[%d]\n", ++ pr_err("%s: failed to get acquire dma_fence from[%d]\n", + __func__, acquire_fence_fd); + return -EINVAL; + } @@ -1909713,7 +1908124,7 @@ index 000000000..93e47be00 + ksys_close(acquire_fence_fd); +#endif +#else -+ rga_req_err(request, "Please update the driver to v1.2.28 to prevent acquire_fence_fd leaks."); ++ pr_err("Please update the driver to v1.2.28 to prevent acquire_fence_fd leaks."); + return -EFAULT; +#endif + } @@ -1909721,7 +1908132,7 @@ index 000000000..93e47be00 + + ret = rga_dma_fence_get_status(acquire_fence); + if (ret < 0) { -+ rga_req_err(request, "%s: Current acquire fence unexpectedly has error status before signal\n", ++ pr_err("%s: Current acquire fence unexpectedly has error status before signal\n", + __func__); + return ret; + } else if (ret > 0) { @@ -1909740,7 +1908151,7 @@ index 000000000..93e47be00 + ret = rga_dma_fence_add_callback(acquire_fence, cb_func, (void *)request); + if (ret < 0) { + if (ret != -ENOENT) -+ rga_req_err(request, "%s: failed to add fence callback\n", __func__); ++ pr_err("%s: failed to add fence callback\n", __func__); + + mutex_lock(&request_manager->lock); + rga_request_put(request); @@ -1909754,23 +1908165,23 @@ index 000000000..93e47be00 +int rga_request_check(struct rga_user_request *req) +{ + if (req->id <= 0) { -+ rga_err("ID[%d]: request_id is invalid", req->id); ++ pr_err("user request id[%d] is invalid", req->id); + return -EINVAL; + } + + if (req->task_num <= 0) { -+ rga_err("ID[%d]: invalid user request!\n", req->id); ++ pr_err("invalied user request!\n"); + return -EINVAL; + } + + if (req->task_ptr == 0) { -+ rga_err("ID[%d]: task_ptr is NULL!\n", req->id); ++ pr_err("task_ptr is NULL!\n"); + return -EINVAL; + } + + if (req->task_num > RGA_TASK_NUM_MAX) { -+ rga_err("ID[%d]: Only supports running %d tasks, now %d\n", -+ req->id, RGA_TASK_NUM_MAX, req->task_num); ++ pr_err("Only supports running %d tasks, now %d\n", ++ RGA_TASK_NUM_MAX, req->task_num); + return -EFBIG; + } + @@ -1909779,103 +1908190,13 @@ index 000000000..93e47be00 + +struct rga_request *rga_request_lookup(struct rga_pending_request_manager *manager, uint32_t id) +{ -+ struct rga_request *request = NULL; -+ -+ WARN_ON(!mutex_is_locked(&manager->lock)); -+ -+ request = idr_find(&manager->request_idr, id); -+ -+ return request; -+} -+ -+void rga_request_scheduler_shutdown(struct rga_scheduler_t *scheduler) -+{ -+ struct rga_job *job, *job_q; -+ unsigned long flags; -+ -+ rga_power_enable(scheduler); -+ -+ spin_lock_irqsave(&scheduler->irq_lock, flags); -+ -+ job = scheduler->running_job; -+ if (job) { -+ if (test_bit(RGA_JOB_STATE_INTR_ERR, &job->state) || -+ test_bit(RGA_JOB_STATE_FINISH, &job->state)) { -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ goto finish; -+ } -+ -+ scheduler->running_job = NULL; -+ scheduler->status = RGA_SCHEDULER_ABORT; -+ scheduler->ops->soft_reset(scheduler); -+ -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ -+ rga_mm_unmap_job_info(job); -+ -+ job->ret = -EBUSY; -+ rga_request_release_signal(scheduler, job); -+ -+ /* -+ * Since the running job was abort, turn off the power here that -+ * should have been turned off after job done (corresponds to -+ * power_enable in rga_job_run()). -+ */ -+ rga_power_disable(scheduler); -+ } else { -+ /* Clean up the jobs in the todo list that need to be free. */ -+ list_for_each_entry_safe(job, job_q, &scheduler->todo_list, head) { -+ rga_mm_unmap_job_info(job); -+ -+ job->ret = -EBUSY; -+ rga_request_release_signal(scheduler, job); -+ } -+ -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ } -+ -+finish: -+ rga_power_disable(scheduler); -+} -+ -+void rga_request_scheduler_abort(struct rga_scheduler_t *scheduler) -+{ -+ struct rga_job *job; -+ unsigned long flags; -+ -+ rga_power_enable(scheduler); -+ -+ spin_lock_irqsave(&scheduler->irq_lock, flags); -+ -+ job = scheduler->running_job; -+ if (job) { -+ scheduler->running_job = NULL; -+ scheduler->status = RGA_SCHEDULER_ABORT; -+ scheduler->ops->soft_reset(scheduler); -+ -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ -+ rga_mm_unmap_job_info(job); -+ -+ job->ret = -EBUSY; -+ rga_request_release_signal(scheduler, job); -+ -+ rga_job_next(scheduler); ++ struct rga_request *request = NULL; + -+ /* -+ * Since the running job was abort, turn off the power here that -+ * should have been turned off after job done (corresponds to -+ * power_enable in rga_job_run()). -+ */ -+ rga_power_disable(scheduler); -+ } else { -+ scheduler->status = RGA_SCHEDULER_ABORT; -+ scheduler->ops->soft_reset(scheduler); ++ WARN_ON(!mutex_is_locked(&manager->lock)); + -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ } ++ request = idr_find(&manager->request_idr, id); + -+ rga_power_disable(scheduler); ++ return request; +} + +static int rga_request_scheduler_job_abort(struct rga_request *request) @@ -1909883,7 +1908204,7 @@ index 000000000..93e47be00 + int i; + unsigned long flags; + enum rga_scheduler_status scheduler_status; -+ int running_abort_count = 0, todo_abort_count = 0, all_task_count = 0; ++ int running_abort_count = 0, todo_abort_count = 0; + struct rga_scheduler_t *scheduler = NULL; + struct rga_job *job, *job_q; + LIST_HEAD(list_to_free); @@ -1909910,16 +1908231,14 @@ index 000000000..93e47be00 + scheduler->status = RGA_SCHEDULER_ABORT; + list_add_tail(&job->head, &list_to_free); + -+ if (job->timestamp.hw_execute != 0) { ++ if (job->hw_running_time != 0) { + scheduler->timer.busy_time += -+ ktime_us_delta(ktime_get(), -+ job->timestamp.hw_recode); ++ ktime_us_delta(ktime_get(), job->hw_recoder_time); + scheduler->ops->soft_reset(scheduler); + } -+ job->session->last_active = ktime_get(); + -+ rga_req_err(request, "reset core[%d] by request abort", -+ scheduler->core); ++ pr_err("reset core[%d] by request[%d] abort", ++ scheduler->core, request->id); + running_abort_count++; + } + } @@ -1909938,17 +1908257,13 @@ index 000000000..93e47be00 + rga_job_cleanup(job); + } + -+ all_task_count = request->finished_task_count + request->failed_task_count + -+ running_abort_count + todo_abort_count; -+ + /* This means it has been cleaned up. */ -+ if (running_abort_count + todo_abort_count == 0 && -+ all_task_count == request->task_count) ++ if (running_abort_count + todo_abort_count == 0) + return 1; + -+ rga_err("request[%d] abort! finished %d failed %d running_abort %d todo_abort %d\n", -+ request->id, request->finished_task_count, request->failed_task_count, -+ running_abort_count, todo_abort_count); ++ pr_err("request[%d] abort! finished %d failed %d running_abort %d todo_abort %d\n", ++ request->id, request->finished_task_count, request->failed_task_count, ++ running_abort_count, todo_abort_count); + + return 0; +} @@ -1909994,7 +1908309,7 @@ index 000000000..93e47be00 + + request_manager = rga_drvdata->pend_request_manager; + if (request_manager == NULL) { -+ rga_err("rga_pending_request_manager is null!\n"); ++ pr_err("rga_pending_request_manager is null!\n"); + return; + } + @@ -1910002,8 +1908317,8 @@ index 000000000..93e47be00 + + idr_for_each_entry(&request_manager->request_idr, request, request_id) { + if (session == request->session) { -+ rga_req_err(request, "destroy when the user exits, current refcount = %d\n", -+ kref_read(&request->refcount)); ++ pr_err("[tgid:%d pid:%d] destroy request[%d] when the user exits", ++ session->tgid, current->pid, request->id); + rga_request_put(request); + } + } @@ -1910025,12 +1908340,23 @@ index 000000000..93e47be00 + + if (scheduler->running_job) { + job = scheduler->running_job; -+ + if (request->id == job->request_id) { -+ request->ret = rga_job_timeout_query_state(job, request->ret); -+ -+ spin_unlock_irqrestore(&scheduler->irq_lock, flags); -+ break; ++ if (test_bit(RGA_JOB_STATE_DONE, &job->state) && ++ test_bit(RGA_JOB_STATE_FINISH, &job->state)) { ++ spin_unlock_irqrestore(&scheduler->irq_lock, flags); ++ return request->ret; ++ } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && ++ test_bit(RGA_JOB_STATE_FINISH, &job->state)) { ++ spin_unlock_irqrestore(&scheduler->irq_lock, flags); ++ pr_err("request[%d] hardware has finished, but the software has timeout!\n", ++ request->id); ++ return -EBUSY; ++ } else if (!test_bit(RGA_JOB_STATE_DONE, &job->state) && ++ !test_bit(RGA_JOB_STATE_FINISH, &job->state)) { ++ spin_unlock_irqrestore(&scheduler->irq_lock, flags); ++ pr_err("request[%d] hardware has timeout.\n", request->id); ++ return -EBUSY; ++ } + } + } + @@ -1910051,39 +1908377,43 @@ index 000000000..93e47be00 + switch (left_time) { + case 0: + ret = rga_request_timeout_query_state(request); -+ break; ++ goto err_request_abort; + case -ERESTARTSYS: + ret = -ERESTARTSYS; -+ break; ++ goto err_request_abort; + default: + ret = request->ret; + break; + } + + return ret; ++ ++err_request_abort: ++ rga_request_release_abort(request, ret); ++ ++ return ret; +} + +int rga_request_commit(struct rga_request *request) +{ + int ret; + int i = 0; -+ -+ if (DEBUGGER_EN(MSG)) -+ rga_req_log(request, "commit process: %s\n", request->session->pname); ++ struct rga_job *job; + + for (i = 0; i < request->task_count; i++) { + struct rga_req *req = &(request->task_list[i]); + + if (DEBUGGER_EN(MSG)) { -+ rga_req_log(request, "commit task[%d]:\n", i); -+ rga_dump_req(request, req); ++ pr_info("commit request[%d] task[%d]:\n", request->id, i); ++ rga_cmd_print_debug_info(req); + } + -+ ret = rga_job_commit(req, request); -+ if (ret < 0) { -+ rga_req_err(request, "task[%d] job_commit failed.\n", i); ++ job = rga_job_commit(req, request); ++ if (IS_ERR(job)) { ++ pr_err("request[%d] task[%d] job_commit failed.\n", request->id, i); ++ rga_request_release_abort(request, PTR_ERR(job)); + -+ return ret; ++ return PTR_ERR(job); + } + } + @@ -1910096,17 +1908426,19 @@ index 000000000..93e47be00 + return 0; +} + -+static void rga_request_acquire_fence_work(struct work_struct *work) ++static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence, ++ struct dma_fence_cb *_waiter) +{ + int ret; + unsigned long flags; + struct mm_struct *current_mm; -+ struct rga_request *request = container_of(work, struct rga_request, fence_work); ++ struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter; ++ struct rga_request *request = (struct rga_request *)waiter->private; + struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager; + + ret = rga_request_commit(request); + if (ret < 0) { -+ rga_req_err(request, "acquire_fence callback: request commit failed!\n"); ++ pr_err("acquire_fence callback: rga request[%d] commit failed!\n", request->id); + + spin_lock_irqsave(&request->lock, flags); + @@ -1910118,22 +1908450,18 @@ index 000000000..93e47be00 + + rga_request_put_current_mm(current_mm); + -+ if (rga_dma_fence_get_status(request->release_fence) == 0) -+ rga_dma_fence_signal(request->release_fence, ret); ++ /* ++ * Since the callback is called while holding &dma_fence.lock, ++ * the _locked API is used here. ++ */ ++ if (dma_fence_get_status_locked(request->release_fence) == 0) ++ dma_fence_signal_locked(request->release_fence); + } + + mutex_lock(&request_manager->lock); + rga_request_put(request); + mutex_unlock(&request_manager->lock); -+} + -+static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence, -+ struct dma_fence_cb *_waiter) -+{ -+ struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter; -+ struct rga_request *request = (struct rga_request *)waiter->private; -+ -+ queue_work(system_highpri_wq, &request->fence_work); + kfree(waiter); +} + @@ -1910148,7 +1908476,7 @@ index 000000000..93e47be00 + + request_manager = rga_drvdata->pend_request_manager; + if (request_manager == NULL) { -+ rga_job_err(job, "rga_pending_request_manager is null!\n"); ++ pr_err("rga_pending_request_manager is null!\n"); + return -EFAULT; + } + @@ -1910156,7 +1908484,7 @@ index 000000000..93e47be00 + + request = rga_request_lookup(request_manager, job->request_id); + if (IS_ERR_OR_NULL(request)) { -+ rga_job_err(job, "can not find internal request from id[%d]", job->request_id); ++ pr_err("can not find internal request from id[%d]", job->request_id); + mutex_unlock(&request_manager->lock); + return -EINVAL; + } @@ -1910193,10 +1908521,10 @@ index 000000000..93e47be00 + rga_dma_fence_signal(request->release_fence, request->ret); + + is_finished = true; -+ job->timestamp.done = ktime_get(); + + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "finished %d failed %d\n", finished_count, failed_count); ++ pr_info("request[%d] finished %d failed %d\n", ++ request->id, finished_count, failed_count); + + /* current submit request put */ + mutex_lock(&request_manager->lock); @@ -1910213,17 +1908541,10 @@ index 000000000..93e47be00 + + mutex_unlock(&request_manager->lock); + -+ if (DEBUGGER_EN(TIME)) { -+ rga_job_log(job, -+ "stats: prepare %lld us, schedule %lld us, hardware %lld us, free %lld us\n", -+ ktime_us_delta(job->timestamp.insert, job->timestamp.init), -+ ktime_us_delta(job->timestamp.hw_execute, job->timestamp.insert), -+ ktime_us_delta(job->timestamp.hw_done, job->timestamp.hw_execute), -+ ktime_us_delta(ktime_get(), job->timestamp.hw_done)); -+ rga_job_log(job, "total: job done cost %lld us, cleanup done cost %lld us\n", -+ ktime_us_delta(job->timestamp.done, job->timestamp.init), -+ ktime_us_delta(ktime_get(), job->timestamp.init)); -+ } ++ if (DEBUGGER_EN(TIME)) ++ pr_info("request[%d], job done total cost time %lld us\n", ++ job->request_id, ++ ktime_us_delta(ktime_get(), job->timestamp)); + + rga_job_cleanup(job); + @@ -1910240,7 +1908561,7 @@ index 000000000..93e47be00 + + request_manager = rga_drvdata->pend_request_manager; + if (request_manager == NULL) { -+ rga_err("rga_pending_request_manager is null!\n"); ++ pr_err("rga_pending_request_manager is null!\n"); + return ERR_PTR(-EFAULT); + } + @@ -1910248,7 +1908569,7 @@ index 000000000..93e47be00 + + request = rga_request_lookup(request_manager, user_request->id); + if (IS_ERR_OR_NULL(request)) { -+ rga_err("can not find request from id[%d]", user_request->id); ++ pr_err("can not find request from id[%d]", user_request->id); + mutex_unlock(&request_manager->lock); + return ERR_PTR(-EINVAL); + } @@ -1910258,14 +1908579,14 @@ index 000000000..93e47be00 + + task_list = kmalloc_array(user_request->task_num, sizeof(struct rga_req), GFP_KERNEL); + if (task_list == NULL) { -+ rga_req_err(request, "task_req list alloc error!\n"); ++ pr_err("task_req list alloc error!\n"); + ret = -ENOMEM; + goto err_put_request; + } + + if (unlikely(copy_from_user(task_list, u64_to_user_ptr(user_request->task_ptr), + sizeof(struct rga_req) * user_request->task_num))) { -+ rga_req_err(request, "rga_user_request task list copy_from_user failed\n"); ++ pr_err("rga_user_request task list copy_from_user failed\n"); + ret = -EFAULT; + goto err_free_task_list; + } @@ -1910304,7 +1908625,7 @@ index 000000000..93e47be00 + + request_manager = rga_drvdata->pend_request_manager; + if (request_manager == NULL) { -+ rga_err("rga_pending_request_manager is null!\n"); ++ pr_err("rga_pending_request_manager is null!\n"); + return ERR_PTR(-EFAULT); + } + @@ -1910312,7 +1908633,7 @@ index 000000000..93e47be00 + + request = rga_request_lookup(request_manager, user_request->id); + if (IS_ERR_OR_NULL(request)) { -+ rga_err("can not find request from id[%d]", user_request->id); ++ pr_err("can not find request from id[%d]", user_request->id); + mutex_unlock(&request_manager->lock); + return ERR_PTR(-EINVAL); + } @@ -1910322,7 +1908643,7 @@ index 000000000..93e47be00 + + task_list = kmalloc_array(user_request->task_num, sizeof(struct rga_req), GFP_KERNEL); + if (task_list == NULL) { -+ rga_req_err(request, "task_req list alloc error!\n"); ++ pr_err("task_req list alloc error!\n"); + ret = -ENOMEM; + goto err_put_request; + } @@ -1910356,23 +1908677,26 @@ index 000000000..93e47be00 + int ret = 0; + unsigned long flags; + struct dma_fence *release_fence; ++ struct mm_struct *current_mm; ++ ++ current_mm = rga_request_get_current_mm(request); + + spin_lock_irqsave(&request->lock, flags); + + if (request->is_running) { + spin_unlock_irqrestore(&request->lock, flags); + -+ rga_req_err(request, "can not re-config when request is running\n"); ++ pr_err("can not re-config when request is running\n"); + ret = -EFAULT; -+ goto err_abort_request; ++ goto err_put_current_mm; + } + + if (request->task_list == NULL) { + spin_unlock_irqrestore(&request->lock, flags); + -+ rga_req_err(request, "can not find task list\n"); ++ pr_err("can not find task list from id[%d]\n", request->id); + ret = -EINVAL; -+ goto err_abort_request; ++ goto err_put_current_mm; + } + + /* Reset */ @@ -1910380,24 +1908704,21 @@ index 000000000..93e47be00 + request->is_done = false; + request->finished_task_count = 0; + request->failed_task_count = 0; -+ request->ret = 0; ++ request->current_mm = current_mm; + + /* Unlock after ensuring that the current request will not be resubmitted. */ + spin_unlock_irqrestore(&request->lock, flags); + + if (request->sync_mode == RGA_BLIT_ASYNC) { + release_fence = rga_dma_fence_alloc(); -+ if (IS_ERR_OR_NULL(release_fence)) { -+ rga_req_err(request, "Can not alloc release fence!\n"); -+ ret = IS_ERR(release_fence) ? PTR_ERR(release_fence) : -EINVAL; -+ goto err_abort_request; ++ if (IS_ERR(release_fence)) { ++ pr_err("Can not alloc release fence!\n"); ++ ret = IS_ERR(release_fence); ++ goto err_reset_request; + } -+ -+ request->current_mm = rga_request_get_current_mm(request); + request->release_fence = release_fence; + + if (request->acquire_fence_fd > 0) { -+ INIT_WORK(&request->fence_work, rga_request_acquire_fence_work); + ret = rga_request_add_acquire_fence_callback( + request->acquire_fence_fd, request, + rga_request_acquire_fence_signaled_cb); @@ -1910408,32 +1908729,27 @@ index 000000000..93e47be00 + /* acquire fence has been signaled */ + goto request_commit; + } else { -+ rga_req_err(request, "Failed to add callback with acquire fence fd[%d]!\n", ++ pr_err("Failed to add callback with acquire fence fd[%d]!\n", + request->acquire_fence_fd); -+ -+ rga_dma_fence_put(request->release_fence); -+ request->release_fence = NULL; -+ goto err_put_current_mm; ++ goto err_put_release_fence; + } + } -+ } else { -+ request->current_mm = rga_request_get_current_mm(request); -+ request->release_fence = NULL; + } + +request_commit: + ret = rga_request_commit(request); + if (ret < 0) { -+ rga_req_err(request, "request commit failed!\n"); -+ goto err_put_current_mm; ++ pr_err("rga request[%d] commit failed!\n", request->id); ++ goto err_put_release_fence; + } + +export_release_fence_fd: + if (request->release_fence != NULL) { + ret = rga_dma_fence_get_fd(request->release_fence); + if (ret < 0) { -+ rga_req_err(request, "Failed to alloc release fence fd!\n"); -+ goto err_put_current_mm; ++ pr_err("Failed to alloc release fence fd!\n"); ++ rga_request_release_abort(request, ret); ++ return ret; + } + + request->release_fence_fd = ret; @@ -1910441,12 +1908757,22 @@ index 000000000..93e47be00 + + return 0; + -+err_put_current_mm: -+ rga_request_put_current_mm(request->current_mm); ++err_put_release_fence: ++ if (request->release_fence != NULL) { ++ rga_dma_fence_put(request->release_fence); ++ request->release_fence = NULL; ++ } ++ ++err_reset_request: ++ spin_lock_irqsave(&request->lock, flags); ++ + request->current_mm = NULL; ++ request->is_running = false; + -+err_abort_request: -+ rga_request_release_abort(request, ret); ++ spin_unlock_irqrestore(&request->lock, flags); ++ ++err_put_current_mm: ++ rga_request_put_current_mm(current_mm); + + return ret; +} @@ -1910454,31 +1908780,26 @@ index 000000000..93e47be00 +int rga_request_mpi_submit(struct rga_req *req, struct rga_request *request) +{ + int ret = 0; ++ struct rga_job *job = NULL; + unsigned long flags; -+ struct rga_pending_request_manager *request_manager; -+ -+ request_manager = rga_drvdata->pend_request_manager; + + if (request->sync_mode == RGA_BLIT_ASYNC) { -+ rga_req_err(request, "mpi unsupported async mode!\n"); -+ ret = -EINVAL; -+ goto err_abort_request; ++ pr_err("mpi unsupported async mode!\n"); ++ return -EINVAL; + } + + spin_lock_irqsave(&request->lock, flags); + + if (request->is_running) { -+ rga_req_err(request, "can not re-config when request is running"); ++ pr_err("can not re-config when request is running"); + spin_unlock_irqrestore(&request->lock, flags); -+ ret = -EFAULT; -+ goto err_abort_request; ++ return -EFAULT; + } + + if (request->task_list == NULL) { -+ rga_req_err(request, "can not find task list"); ++ pr_err("can not find task list from id[%d]", request->id); + spin_unlock_irqrestore(&request->lock, flags); -+ ret = -EINVAL; -+ goto err_abort_request; ++ return -EINVAL; + } + + /* Reset */ @@ -1910486,34 +1908807,20 @@ index 000000000..93e47be00 + request->is_done = false; + request->finished_task_count = 0; + request->failed_task_count = 0; -+ request->ret = 0; + + spin_unlock_irqrestore(&request->lock, flags); + -+ /* -+ * The mpi submit will use the request repeatedly, so an additional -+ * get() is added here. -+ */ -+ mutex_lock(&request_manager->lock); -+ rga_request_get(request); -+ mutex_unlock(&request_manager->lock); -+ -+ ret = rga_job_commit(req, request); -+ if (ret < 0) { -+ rga_req_err(request, "failed to commit job!\n"); -+ goto err_abort_request; ++ job = rga_job_commit(req, request); ++ if (IS_ERR_OR_NULL(job)) { ++ pr_err("failed to commit job!\n"); ++ return job ? PTR_ERR(job) : -EFAULT; + } + + ret = rga_request_wait(request); + if (ret < 0) -+ goto err_abort_request; ++ return ret; + + return 0; -+ -+err_abort_request: -+ rga_request_release_abort(request, ret); -+ -+ return ret; +} + +int rga_request_free(struct rga_request *request) @@ -1910524,14 +1908831,14 @@ index 000000000..93e47be00 + + request_manager = rga_drvdata->pend_request_manager; + if (request_manager == NULL) { -+ rga_err("rga_pending_request_manager is null!\n"); ++ pr_err("rga_pending_request_manager is null!\n"); + return -EFAULT; + } + + WARN_ON(!mutex_is_locked(&request_manager->lock)); + + if (IS_ERR_OR_NULL(request)) { -+ rga_err("request already freed"); ++ pr_err("request already freed"); + return -EFAULT; + } + @@ -1910547,8 +1908854,6 @@ index 000000000..93e47be00 + if (task_list != NULL) + kfree(task_list); + -+ rga_session_put(request->session); -+ + kfree(request); + + return 0; @@ -1910605,13 +1908910,13 @@ index 000000000..93e47be00 + + request_manager = rga_drvdata->pend_request_manager; + if (request_manager == NULL) { -+ rga_err("rga_pending_request_manager is null!\n"); ++ pr_err("rga_pending_request_manager is null!\n"); + return -EFAULT; + } + + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (request == NULL) { -+ rga_err("can not kzalloc for rga_request\n"); ++ pr_err("can not kzalloc for rga_request\n"); + return -ENOMEM; + } + @@ -1910620,10 +1908925,7 @@ index 000000000..93e47be00 + + request->pid = current->pid; + request->flags = flags; -+ -+ rga_session_get(session); + request->session = session; -+ + kref_init(&request->refcount); + + /* @@ -1910636,10 +1908938,9 @@ index 000000000..93e47be00 + new_id = idr_alloc_cyclic(&request_manager->request_idr, request, 1, 0, GFP_NOWAIT); + idr_preload_end(); + if (new_id < 0) { -+ rga_err("request alloc id failed!\n"); ++ pr_err("request alloc id failed!\n"); + + mutex_unlock(&request_manager->lock); -+ rga_session_put(session); + kfree(request); + return new_id; + } @@ -1910700,10 +1909001,10 @@ index 000000000..93e47be00 +} diff --git a/drivers/video/rockchip/rga3/rga_mm.c b/drivers/video/rockchip/rga3/rga_mm.c new file mode 100644 -index 000000000..b130e6e60 +index 000000000..de7e9a6fd --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_mm.c -@@ -0,0 +1,2483 @@ +@@ -0,0 +1,2229 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1910711,6 +1909012,8 @@ index 000000000..b130e6e60 + * Author: Cerf Yu + */ + ++#define pr_fmt(fmt) "rga_mm: " fmt ++ +#include "rga.h" +#include "rga_job.h" +#include "rga_mm.h" @@ -1910757,14 +1909060,14 @@ index 000000000..b130e6e60 + for (i = 0; i < pageCount; i++) { + vma = find_vma(current_mm, (Memory + i) << PAGE_SHIFT); + if (!vma) { -+ rga_err("page[%d] failed to get vma\n", i); ++ pr_err("page[%d] failed to get vma\n", i); + ret = RGA_OUT_OF_RESOURCES; + break; + } + + pgd = pgd_offset(current_mm, (Memory + i) << PAGE_SHIFT); + if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) { -+ rga_err("page[%d] failed to get pgd\n", i); ++ pr_err("page[%d] failed to get pgd\n", i); + ret = RGA_OUT_OF_RESOURCES; + break; + } @@ -1910775,7 +1909078,7 @@ index 000000000..b130e6e60 + */ + p4d = p4d_offset(pgd, (Memory + i) << PAGE_SHIFT); + if (p4d_none(*p4d) || unlikely(p4d_bad(*p4d))) { -+ rga_err("page[%d] failed to get p4d\n", i); ++ pr_err("page[%d] failed to get p4d\n", i); + ret = RGA_OUT_OF_RESOURCES; + break; + } @@ -1910786,20 +1909089,20 @@ index 000000000..b130e6e60 +#endif + + if (pud_none(*pud) || unlikely(pud_bad(*pud))) { -+ rga_err("page[%d] failed to get pud\n", i); ++ pr_err("page[%d] failed to get pud\n", i); + ret = RGA_OUT_OF_RESOURCES; + break; + } + pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT); + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) { -+ rga_err("page[%d] failed to get pmd\n", i); ++ pr_err("page[%d] failed to get pmd\n", i); + ret = RGA_OUT_OF_RESOURCES; + break; + } + pte = pte_offset_map_lock(current_mm, pmd, + (Memory + i) << PAGE_SHIFT, &ptl); + if (pte_none(*pte)) { -+ rga_err("page[%d] failed to get pte\n", i); ++ pr_err("page[%d] failed to get pte\n", i); + pte_unmap_unlock(pte, ptl); + ret = RGA_OUT_OF_RESOURCES; + break; @@ -1910811,8 +1909114,8 @@ index 000000000..b130e6e60 + } + + if (ret == RGA_OUT_OF_RESOURCES && i > 0) -+ rga_err("Only get buffer %d byte from vma, but current image required %d byte", -+ (int)(i * PAGE_SIZE), (int)(pageCount * PAGE_SIZE)); ++ pr_err("Only get buffer %d byte from vma, but current image required %d byte", ++ (int)(i * PAGE_SIZE), (int)(pageCount * PAGE_SIZE)); + + return ret; +} @@ -1910839,12 +1909142,9 @@ index 000000000..b130e6e60 + result = get_user_pages_remote(current, current_mm, + Memory << PAGE_SHIFT, + pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL, NULL); -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 5, 0) -+ result = get_user_pages_remote(current_mm, Memory << PAGE_SHIFT, -+ pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL, NULL); +#else + result = get_user_pages_remote(current_mm, Memory << PAGE_SHIFT, -+ pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL); ++ pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL, NULL); +#endif + + if (result > 0 && result >= pageCount) { @@ -1910856,8 +1909156,8 @@ index 000000000..b130e6e60 + + ret = rga_get_user_pages_from_vma(pages, Memory, pageCount, current_mm); + if (ret < 0 && result > 0) { -+ rga_err("Only get buffer %d byte from user pages, but current image required %d byte\n", -+ (int)(result * PAGE_SIZE), (int)(pageCount * PAGE_SIZE)); ++ pr_err("Only get buffer %d byte from user pages, but current image required %d byte\n", ++ (int)(result * PAGE_SIZE), (int)(pageCount * PAGE_SIZE)); + } + } + @@ -1910883,19 +1909183,20 @@ index 000000000..b130e6e60 + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (sgt == NULL) { -+ rga_err("%s alloc sgt error!\n", __func__); ++ pr_err("%s alloc sgt error!\n", __func__); + return ERR_PTR(-ENOMEM); + } + + /* get sg form pages. */ ++ /* iova requires minimum page alignment, so sgt cannot have offset */ + ret = sg_alloc_table_from_pages(sgt, + virt_addr->pages, + virt_addr->page_count, -+ virt_addr->offset, ++ 0, + virt_addr->size, + GFP_KERNEL); + if (ret) { -+ rga_err("sg_alloc_table_from_pages failed"); ++ pr_err("sg_alloc_table_from_pages failed"); + goto out_free_sgt; + } + @@ -1910940,6 +1909241,7 @@ index 000000000..b130e6e60 + unsigned int count; + int img_size; + size_t offset; ++ unsigned long size; + struct page **pages = NULL; + struct rga_virt_addr *virt_addr = NULL; + @@ -1910953,25 +1909255,32 @@ index 000000000..b130e6e60 + + offset = viraddr & (~PAGE_MASK); + count = RGA_GET_PAGE_COUNT(img_size + offset); -+ if (!count) { -+ rga_err("failed to calculating buffer size! img_size = %d, count = %d, offset = %ld\n", -+ img_size, count, (unsigned long)offset); ++ size = count * PAGE_SIZE; ++ if (!size) { ++ pr_err("failed to calculating buffer size! size = %ld, count = %d, offset = %ld\n", ++ size, count, (unsigned long)offset); + rga_dump_memory_parm(memory_parm); + return -EFAULT; + } + + /* alloc pages and page_table */ -+ pages = (struct page **)rga_get_free_pages(GFP_KERNEL, -+ &order, count * sizeof(struct page *)); ++ order = get_order(count * sizeof(struct page *)); ++ if (order >= MAX_ORDER) { ++ pr_err("Can not alloc pages with order[%d] for viraddr pages, max_order = %d\n", ++ order, MAX_ORDER); ++ return -ENOMEM; ++ } ++ ++ pages = (struct page **)__get_free_pages(GFP_KERNEL, order); + if (pages == NULL) { -+ rga_err("%s can not alloc pages for viraddr pages\n", __func__); ++ pr_err("%s can not alloc pages for viraddr pages\n", __func__); + return -ENOMEM; + } + + /* get pages from virtual address. */ + ret = rga_get_user_pages(pages, viraddr >> PAGE_SHIFT, count, writeFlag, mm); + if (ret < 0) { -+ rga_err("failed to get pages from virtual adrees: 0x%lx\n", ++ pr_err("failed to get pages from virtual adrees: 0x%lx\n", + (unsigned long)viraddr); + ret = -EINVAL; + goto out_free_pages; @@ -1910982,7 +1909291,7 @@ index 000000000..b130e6e60 + + *virt_addr_p = kzalloc(sizeof(struct rga_virt_addr), GFP_KERNEL); + if (*virt_addr_p == NULL) { -+ rga_err("%s alloc virt_addr error!\n", __func__); ++ pr_err("%s alloc virt_addr error!\n", __func__); + ret = -ENOMEM; + goto out_put_and_free_pages; + } @@ -1910992,7 +1909301,7 @@ index 000000000..b130e6e60 + virt_addr->pages = pages; + virt_addr->pages_order = order; + virt_addr->page_count = count; -+ virt_addr->size = img_size; ++ virt_addr->size = size; + virt_addr->offset = offset; + virt_addr->result = result; + @@ -1911014,7 +1909323,7 @@ index 000000000..b130e6e60 + + if (scheduler->data->mmu == RGA_MMU && + !(mm_flag & RGA_MEM_UNDER_4G)) { -+ rga_err("%s unsupported memory larger than 4G!\n", ++ pr_err("%s unsupported memory larger than 4G!\n", + rga_get_mmu_type_str(scheduler->data->mmu)); + return false; + } @@ -1911081,7 +1909390,7 @@ index 000000000..b130e6e60 + scheduler = job ? job->scheduler : + rga_drvdata->scheduler[rga_drvdata->map_scheduler_index]; + if (scheduler == NULL) { -+ rga_err("Invalid scheduler device!\n"); ++ pr_err("Invalid scheduler device!\n"); + return -EINVAL; + } + @@ -1911093,22 +1909402,23 @@ index 000000000..b130e6e60 + external_buffer->memory_parm.format, + NULL, NULL, NULL); + if (ex_buffer_size <= 0) { -+ rga_err("failed to calculating buffer size!\n"); ++ pr_err("failed to calculating buffer size!\n"); + rga_dump_memory_parm(&external_buffer->memory_parm); + return ex_buffer_size == 0 ? -EINVAL : ex_buffer_size; + } + -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (buffer == NULL) { -+ rga_err("%s alloc internal_buffer error!\n", __func__); -+ return -ENOMEM; -+ } -+ + /* + * dma-buf api needs to use default_domain of main dev, + * and not IOMMU for devices without iommu_info ptr. + */ + map_dev = scheduler->iommu_info ? scheduler->iommu_info->default_dev : scheduler->dev; ++ ++ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); ++ if (buffer == NULL) { ++ pr_err("%s alloc internal_buffer error!\n", __func__); ++ return -ENOMEM; ++ } ++ + switch (external_buffer->type) { + case RGA_DMA_BUFFER: + ret = rga_dma_map_fd((int)external_buffer->memory, @@ -1911125,22 +1909435,21 @@ index 000000000..b130e6e60 + break; + } + if (ret < 0) { -+ rga_err("%s core[%d] map dma buffer error!\n", -+ __func__, scheduler->core); ++ pr_err("%s core[%d] map dma buffer error!\n", ++ __func__, scheduler->core); + goto free_buffer; + } + + if (buffer->size < ex_buffer_size) { -+ rga_err("Only get buffer %ld byte from %s = 0x%lx, but current image required %d byte\n", -+ buffer->size, rga_get_memory_type_str(external_buffer->type), -+ (unsigned long)external_buffer->memory, ex_buffer_size); ++ pr_err("Only get buffer %ld byte from %s = 0x%lx, but current image required %d byte\n", ++ buffer->size, rga_get_memory_type_str(external_buffer->type), ++ (unsigned long)external_buffer->memory, ex_buffer_size); + rga_dump_memory_parm(&external_buffer->memory_parm); + ret = -EINVAL; + goto unmap_buffer; + } + -+ if (scheduler->data->mmu == RGA_IOMMU) -+ buffer->iova = buffer->dma_addr; ++ buffer->scheduler = scheduler; + + if (rga_mm_check_range_sgt(buffer->sgt)) + mm_flag |= RGA_MEM_UNDER_4G; @@ -1911152,7 +1909461,7 @@ index 000000000..b130e6e60 + if (rga_mm_check_contiguous_sgt(buffer->sgt)) { + phys_addr = sg_phys(buffer->sgt->sgl); + if (phys_addr == 0) { -+ rga_err("%s get physical address error!", __func__); ++ pr_err("%s get physical address error!", __func__); + ret = -EFAULT; + goto unmap_buffer; + } @@ -1911161,8 +1909470,8 @@ index 000000000..b130e6e60 + } + + if (!rga_mm_check_memory_limit(scheduler, mm_flag)) { -+ rga_err("scheduler core[%d] unsupported mm_flag[0x%x]!\n", -+ scheduler->core, mm_flag); ++ pr_err("scheduler core[%d] unsupported mm_flag[0x%x]!\n", ++ scheduler->core, mm_flag); + ret = -EINVAL; + goto unmap_buffer; + } @@ -1911170,8 +1909479,6 @@ index 000000000..b130e6e60 + internal_buffer->dma_buffer = buffer; + internal_buffer->mm_flag = mm_flag; + internal_buffer->phys_addr = phys_addr ? phys_addr : 0; -+ internal_buffer->size = buffer->size - buffer->offset; -+ internal_buffer->scheduler = scheduler; + + return 0; + @@ -1911191,7 +1909498,19 @@ index 000000000..b130e6e60 + if (rga_mm_is_invalid_dma_buffer(internal_buffer->dma_buffer)) + return; + -+ rga_dma_unmap_sgt(internal_buffer->dma_buffer); ++ switch (internal_buffer->dma_buffer->scheduler->data->mmu) { ++ case RGA_IOMMU: ++ rga_iommu_unmap(internal_buffer->dma_buffer); ++ break; ++ case RGA_MMU: ++ dma_unmap_sg(internal_buffer->dma_buffer->scheduler->dev, ++ internal_buffer->dma_buffer->sgt->sgl, ++ internal_buffer->dma_buffer->sgt->orig_nents, ++ DMA_BIDIRECTIONAL); ++ break; ++ default: ++ break; ++ } + + if (internal_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS && + internal_buffer->phys_addr > 0) @@ -1911219,19 +1909538,18 @@ index 000000000..b130e6e60 + struct sg_table *sgt; + struct rga_virt_addr *virt_addr; + struct rga_dma_buffer *buffer; -+ struct device *map_dev; + struct rga_scheduler_t *scheduler; + + scheduler = job ? job->scheduler : + rga_drvdata->scheduler[rga_drvdata->map_scheduler_index]; + if (scheduler == NULL) { -+ rga_err("Invalid scheduler device!\n"); ++ pr_err("Invalid scheduler device!\n"); + return -EINVAL; + } + + internal_buffer->current_mm = job ? job->mm : current->mm; + if (internal_buffer->current_mm == NULL) { -+ rga_err("%s, cannot get current mm!\n", __func__); ++ pr_err("%s, cannot get current mm!\n", __func__); + return -EFAULT; + } + mmgrab(internal_buffer->current_mm); @@ -1911242,14 +1909560,14 @@ index 000000000..b130e6e60 + &internal_buffer->memory_parm, + write_flag, internal_buffer->current_mm); + if (ret < 0) { -+ rga_err("Can not alloc rga_virt_addr from 0x%lx\n", ++ pr_err("Can not alloc rga_virt_addr from 0x%lx\n", + (unsigned long)external_buffer->memory); + goto put_current_mm; + } + + sgt = rga_alloc_sgt(virt_addr); + if (IS_ERR(sgt)) { -+ rga_err("alloc sgt error!\n"); ++ pr_err("alloc sgt error!\n"); + ret = PTR_ERR(sgt); + goto free_virt_addr; + } @@ -1911260,17 +1909578,12 @@ index 000000000..b130e6e60 + if (rga_mm_check_contiguous_sgt(sgt)) { + phys_addr = sg_phys(sgt->sgl); + if (phys_addr == 0) { -+ rga_err("%s get physical address error!", __func__); ++ pr_err("%s get physical address error!", __func__); + ret = -EFAULT; + goto free_sgt; + } + + mm_flag |= RGA_MEM_PHYSICAL_CONTIGUOUS; -+ } else if (scheduler->data->mmu == RGA_NONE_MMU) { -+ rga_err("Current %s[%d] cannot support physically discontinuous virtual address!\n", -+ rga_get_mmu_type_str(scheduler->data->mmu), scheduler->data->mmu); -+ ret = -EOPNOTSUPP; -+ goto free_sgt; + } + + /* @@ -1911281,41 +1909594,57 @@ index 000000000..b130e6e60 + mm_flag |= RGA_MEM_FORCE_FLUSH_CACHE; + + if (!rga_mm_check_memory_limit(scheduler, mm_flag)) { -+ rga_err("scheduler core[%d] unsupported mm_flag[0x%x]!\n", -+ scheduler->core, mm_flag); ++ pr_err("scheduler core[%d] unsupported mm_flag[0x%x]!\n", ++ scheduler->core, mm_flag); + ret = -EINVAL; + goto free_sgt; + } + + buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + if (buffer == NULL) { -+ rga_err("%s alloc internal dma_buffer error!\n", __func__); ++ pr_err("%s alloc internal dma_buffer error!\n", __func__); + ret = -ENOMEM; + goto free_sgt; + } + -+ /* -+ * dma-buf api needs to use default_domain of main dev, -+ * and not IOMMU for devices without iommu_info ptr. -+ */ -+ map_dev = scheduler->iommu_info ? scheduler->iommu_info->default_dev : scheduler->dev; -+ ret = rga_dma_map_sgt(sgt, buffer, DMA_BIDIRECTIONAL, map_dev); -+ if (ret < 0) { -+ rga_err("%s core[%d] rga map sgt failed! va = 0x%lx, orig_nents = %d\n", -+ __func__, scheduler->core, -+ (unsigned long)virt_addr->addr, sgt->orig_nents); ++ switch (scheduler->data->mmu) { ++ case RGA_IOMMU: ++ ret = rga_iommu_map_sgt(sgt, virt_addr->size, buffer, scheduler->dev); ++ if (ret < 0) { ++ pr_err("%s core[%d] iommu_map virtual address error!\n", ++ __func__, scheduler->core); ++ goto free_dma_buffer; ++ } ++ break; ++ case RGA_MMU: ++ ret = dma_map_sg(scheduler->dev, sgt->sgl, sgt->orig_nents, DMA_BIDIRECTIONAL); ++ if (ret == 0) { ++ pr_err("%s core[%d] dma_map_sgt error! va = 0x%lx, nents = %d\n", ++ __func__, scheduler->core, ++ (unsigned long)virt_addr->addr, sgt->orig_nents); ++ ret = -EINVAL; ++ goto free_dma_buffer; ++ } ++ break; ++ default: ++ if (mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) ++ break; ++ ++ pr_err("Current %s[%d] cannot support physically discontinuous virtual address!\n", ++ rga_get_mmu_type_str(scheduler->data->mmu), scheduler->data->mmu); ++ ret = -EOPNOTSUPP; + goto free_dma_buffer; + } + -+ if (scheduler->data->mmu == RGA_IOMMU) -+ buffer->iova = buffer->dma_addr; ++ buffer->sgt = sgt; ++ buffer->offset = virt_addr->offset; ++ buffer->size = virt_addr->size; ++ buffer->scheduler = scheduler; + + internal_buffer->virt_addr = virt_addr; + internal_buffer->dma_buffer = buffer; + internal_buffer->mm_flag = mm_flag; + internal_buffer->phys_addr = phys_addr ? phys_addr + virt_addr->offset : 0; -+ internal_buffer->size = buffer->size - buffer->offset; -+ internal_buffer->scheduler = scheduler; + + return 0; + @@ -1911335,12 +1909664,16 @@ index 000000000..b130e6e60 + +static void rga_mm_unmap_phys_addr(struct rga_internal_buffer *internal_buffer) +{ -+ if (internal_buffer->dma_buffer != NULL) { -+ rga_dma_unmap_phys_addr(internal_buffer->dma_buffer); -+ kfree(internal_buffer->dma_buffer); -+ internal_buffer->dma_buffer = NULL; -+ } ++ WARN_ON(internal_buffer->dma_buffer == NULL); ++ ++ if (rga_mm_is_invalid_dma_buffer(internal_buffer->dma_buffer)) ++ return; ++ ++ if (internal_buffer->dma_buffer->scheduler->data->mmu == RGA_IOMMU) ++ rga_iommu_unmap(internal_buffer->dma_buffer); + ++ kfree(internal_buffer->dma_buffer); ++ internal_buffer->dma_buffer = NULL; + internal_buffer->phys_addr = 0; + internal_buffer->size = 0; +} @@ -1911353,14 +1909686,13 @@ index 000000000..b130e6e60 + phys_addr_t phys_addr; + int buffer_size; + uint32_t mm_flag = 0; -+ struct rga_dma_buffer *buffer = NULL; -+ struct device *map_dev; ++ struct rga_dma_buffer *buffer; + struct rga_scheduler_t *scheduler; + + scheduler = job ? job->scheduler : + rga_drvdata->scheduler[rga_drvdata->map_scheduler_index]; + if (scheduler == NULL) { -+ rga_err("Invalid scheduler device!\n"); ++ pr_err("Invalid scheduler device!\n"); + return -EINVAL; + } + @@ -1911372,7 +1909704,7 @@ index 000000000..b130e6e60 + internal_buffer->memory_parm.format, + NULL, NULL, NULL); + if (buffer_size <= 0) { -+ rga_err("Failed to get phys addr size!\n"); ++ pr_err("Failed to get phys addr size!\n"); + rga_dump_memory_parm(&internal_buffer->memory_parm); + return buffer_size == 0 ? -EINVAL : buffer_size; + } @@ -1911383,39 +1909715,31 @@ index 000000000..b130e6e60 + mm_flag |= RGA_MEM_UNDER_4G; + + if (!rga_mm_check_memory_limit(scheduler, mm_flag)) { -+ rga_err("scheduler core[%d] unsupported mm_flag[0x%x]!\n", -+ scheduler->core, mm_flag); ++ pr_err("scheduler core[%d] unsupported mm_flag[0x%x]!\n", ++ scheduler->core, mm_flag); + return -EINVAL; + } + -+ if (scheduler->data->mmu == RGA_IOMMU) { -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (buffer == NULL) { -+ rga_err("%s alloc internal dma buffer error!\n", __func__); -+ return -ENOMEM; -+ } ++ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); ++ if (buffer == NULL) { ++ pr_err("%s alloc internal dma buffer error!\n", __func__); ++ return -ENOMEM; ++ } + -+ /* -+ * dma-buf api needs to use default_domain of main dev, -+ * and not IOMMU for devices without iommu_info ptr. -+ */ -+ map_dev = scheduler->iommu_info ? -+ scheduler->iommu_info->default_dev : scheduler->dev; -+ ret = rga_dma_map_phys_addr(phys_addr, buffer_size, buffer, -+ DMA_BIDIRECTIONAL, map_dev); ++ if (scheduler->data->mmu == RGA_IOMMU) { ++ ret = rga_iommu_map(phys_addr, buffer_size, buffer, scheduler->dev); + if (ret < 0) { -+ rga_err("%s core[%d] map phys_addr error!\n", __func__, scheduler->core); ++ pr_err("%s core[%d] map phys_addr error!\n", __func__, scheduler->core); + goto free_dma_buffer; + } -+ -+ buffer->iova = buffer->dma_addr; + } + -+ internal_buffer->dma_buffer = buffer; -+ internal_buffer->mm_flag = mm_flag; ++ buffer->scheduler = scheduler; ++ + internal_buffer->phys_addr = phys_addr; -+ internal_buffer->size = buffer ? buffer->size : buffer_size; -+ internal_buffer->scheduler = scheduler; ++ internal_buffer->size = buffer_size; ++ internal_buffer->mm_flag = mm_flag; ++ internal_buffer->dma_buffer = buffer; + + return 0; + @@ -1911439,7 +1909763,7 @@ index 000000000..b130e6e60 + rga_mm_unmap_phys_addr(internal_buffer); + break; + default: -+ rga_err("Illegal external buffer!\n"); ++ pr_err("Illegal external buffer!\n"); + return -EFAULT; + } + @@ -1911461,35 +1909785,41 @@ index 000000000..b130e6e60 + internal_buffer->type = external_buffer->type; + + ret = rga_mm_map_dma_buffer(external_buffer, internal_buffer, job); -+ if (ret < 0) ++ if (ret < 0) { ++ pr_err("%s map dma_buf error!\n", __func__); + return ret; ++ } + ++ internal_buffer->size = internal_buffer->dma_buffer->size - ++ internal_buffer->dma_buffer->offset; + internal_buffer->mm_flag |= RGA_MEM_NEED_USE_IOMMU; + break; + case RGA_VIRTUAL_ADDRESS: + internal_buffer->type = RGA_VIRTUAL_ADDRESS; + + ret = rga_mm_map_virt_addr(external_buffer, internal_buffer, job, write_flag); -+ if (ret < 0) ++ if (ret < 0) { ++ pr_err("%s map virtual address error!\n", __func__); + return ret; ++ } + ++ internal_buffer->size = internal_buffer->virt_addr->size - ++ internal_buffer->virt_addr->offset; + internal_buffer->mm_flag |= RGA_MEM_NEED_USE_IOMMU; + break; + case RGA_PHYSICAL_ADDRESS: + internal_buffer->type = RGA_PHYSICAL_ADDRESS; + + ret = rga_mm_map_phys_addr(external_buffer, internal_buffer, job); -+ if (ret < 0) ++ if (ret < 0) { ++ pr_err("%s map physical address error!\n", __func__); + return ret; ++ } + + internal_buffer->mm_flag |= RGA_MEM_NEED_USE_IOMMU; + break; + default: -+ if (job) -+ rga_job_err(job, "Illegal external buffer!\n"); -+ else -+ rga_err("Illegal external buffer!\n"); -+ ++ pr_err("Illegal external buffer!\n"); + return -EFAULT; + } + @@ -1911499,46 +1909829,32 @@ index 000000000..b130e6e60 +static void rga_mm_kref_release_buffer(struct kref *ref) +{ + struct rga_internal_buffer *internal_buffer; -+ struct rga_mm *mm = rga_drvdata->mm; + + internal_buffer = container_of(ref, struct rga_internal_buffer, refcount); -+ idr_remove(&mm->memory_idr, internal_buffer->handle); -+ mm->buffer_count--; -+ mutex_unlock(&mm->lock); -+ -+ + rga_mm_unmap_buffer(internal_buffer); -+ kfree(internal_buffer); -+ -+ mutex_lock(&mm->lock); -+} + -+/* Force release the current internal_buffer from the IDR. */ -+static void rga_mm_force_releaser_buffer(struct rga_internal_buffer *buffer) -+{ -+ struct rga_mm *mm = rga_drvdata->mm; -+ -+ WARN_ON(!mutex_is_locked(&mm->lock)); -+ -+ idr_remove(&mm->memory_idr, buffer->handle); -+ mm->buffer_count--; -+ -+ rga_mm_unmap_buffer(buffer); -+ kfree(buffer); ++ idr_remove(&rga_drvdata->mm->memory_idr, internal_buffer->handle); ++ kfree(internal_buffer); ++ rga_drvdata->mm->buffer_count--; +} + +/* + * Called at driver close to release the memory's handle references. + */ -+static int rga_mm_buffer_destroy_for_idr(int id, void *ptr, void *data) ++static int rga_mm_handle_remove(int id, void *ptr, void *data) +{ + struct rga_internal_buffer *internal_buffer = ptr; + -+ rga_mm_force_releaser_buffer(internal_buffer); ++ rga_mm_kref_release_buffer(&internal_buffer->refcount); + + return 0; +} + ++static void rga_mm_buffer_destroy(struct rga_internal_buffer *buffer) ++{ ++ rga_mm_kref_release_buffer(&buffer->refcount); ++} ++ +static struct rga_internal_buffer * +rga_mm_lookup_external(struct rga_mm *mm_session, + struct rga_external_buffer *external_buffer, @@ -1911609,7 +1909925,7 @@ index 000000000..b130e6e60 + break; + + default: -+ rga_err("Illegal external buffer!\n"); ++ pr_err("Illegal external buffer!\n"); + return NULL; + } + @@ -1911633,7 +1909949,7 @@ index 000000000..b130e6e60 + + output_buffer = rga_mm_lookup_handle(mm_session, handle); + if (output_buffer == NULL) { -+ rga_err("This handle[%ld] is illegal.\n", (unsigned long)handle); ++ pr_err("This handle[%ld] is illegal.\n", (unsigned long)handle); + return -EINVAL; + } + @@ -1911658,9 +1909974,8 @@ index 000000000..b130e6e60 + +void rga_mm_dump_buffer(struct rga_internal_buffer *dump_buffer) +{ -+ rga_buf_log(dump_buffer, "type = %s, refcount = %d mm_flag = 0x%x\n", -+ rga_get_memory_type_str(dump_buffer->type), -+ kref_read(&dump_buffer->refcount), ++ pr_info("handle = %d refcount = %d mm_flag = 0x%x\n", ++ dump_buffer->handle, kref_read(&dump_buffer->refcount), + dump_buffer->mm_flag); + + switch (dump_buffer->type) { @@ -1911669,25 +1909984,24 @@ index 000000000..b130e6e60 + if (rga_mm_is_invalid_dma_buffer(dump_buffer->dma_buffer)) + break; + -+ rga_buf_log(dump_buffer, "dma_buf = %p\n", -+ dump_buffer->dma_buffer->dma_buf); -+ rga_buf_log(dump_buffer, "iova = 0x%lx, dma_addr = 0x%lx, offset = 0x%lx, sgt = %p, size = %ld, map_core = 0x%x\n", ++ pr_info("dma_buffer:\n"); ++ pr_info("dma_buf = %p, iova = 0x%lx, sgt = %p, size = %ld, map_core = 0x%x\n", ++ dump_buffer->dma_buffer->dma_buf, + (unsigned long)dump_buffer->dma_buffer->iova, -+ (unsigned long)dump_buffer->dma_buffer->dma_addr, -+ (unsigned long)dump_buffer->dma_buffer->offset, + dump_buffer->dma_buffer->sgt, + dump_buffer->dma_buffer->size, -+ dump_buffer->scheduler->core); ++ dump_buffer->dma_buffer->scheduler->core); + + if (dump_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) -+ rga_log("is contiguous, pa = 0x%lx\n", ++ pr_info("is contiguous, pa = 0x%lx\n", + (unsigned long)dump_buffer->phys_addr); + break; + case RGA_VIRTUAL_ADDRESS: + if (dump_buffer->virt_addr == NULL) + break; + -+ rga_buf_log(dump_buffer, "va = 0x%lx, pages = %p, size = %ld\n", ++ pr_info("virtual address:\n"); ++ pr_info("va = 0x%lx, pages = %p, size = %ld\n", + (unsigned long)dump_buffer->virt_addr->addr, + dump_buffer->virt_addr->pages, + dump_buffer->virt_addr->size); @@ -1911695,33 +1910009,22 @@ index 000000000..b130e6e60 + if (rga_mm_is_invalid_dma_buffer(dump_buffer->dma_buffer)) + break; + -+ rga_buf_log(dump_buffer, "iova = 0x%lx, dma_addr = 0x%lx, offset = 0x%lx, sgt = %p, size = %ld, map_core = 0x%x\n", ++ pr_info("iova = 0x%lx, offset = 0x%lx, sgt = %p, size = %ld, map_core = 0x%x\n", + (unsigned long)dump_buffer->dma_buffer->iova, -+ (unsigned long)dump_buffer->dma_buffer->dma_addr, + (unsigned long)dump_buffer->dma_buffer->offset, + dump_buffer->dma_buffer->sgt, + dump_buffer->dma_buffer->size, -+ dump_buffer->scheduler->core); ++ dump_buffer->dma_buffer->scheduler->core); + + if (dump_buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) -+ rga_buf_log(dump_buffer, "is contiguous, pa = 0x%lx\n", ++ pr_info("is contiguous, pa = 0x%lx\n", + (unsigned long)dump_buffer->phys_addr); + break; + case RGA_PHYSICAL_ADDRESS: -+ rga_buf_log(dump_buffer, "pa = 0x%lx\n", (unsigned long)dump_buffer->phys_addr); -+ -+ if (rga_mm_is_invalid_dma_buffer(dump_buffer->dma_buffer)) -+ break; -+ -+ rga_buf_log(dump_buffer, "iova = 0x%lx, dma_addr = 0x%lx, offset = 0x%lx, size = %ld, map_core = 0x%x\n", -+ (unsigned long)dump_buffer->dma_buffer->iova, -+ (unsigned long)dump_buffer->dma_buffer->dma_addr, -+ (unsigned long)dump_buffer->dma_buffer->offset, -+ dump_buffer->dma_buffer->size, -+ dump_buffer->scheduler->core); ++ pr_info("physical address: pa = 0x%lx\n", (unsigned long)dump_buffer->phys_addr); + break; + default: -+ rga_buf_err(dump_buffer, "Illegal buffer! type= %d\n", dump_buffer->type); ++ pr_err("Illegal external buffer!\n"); + break; + } +} @@ -1911733,15 +1910036,15 @@ index 000000000..b130e6e60 + + WARN_ON(!mutex_is_locked(&mm_session->lock)); + -+ rga_log("rga mm info:\n"); ++ pr_info("rga mm info:\n"); + -+ rga_log("buffer count = %d\n", mm_session->buffer_count); -+ rga_log("===============================================================\n"); ++ pr_info("buffer count = %d\n", mm_session->buffer_count); ++ pr_info("===============================================================\n"); + + idr_for_each_entry(&mm_session->memory_idr, dump_buffer, id) { + rga_mm_dump_buffer(dump_buffer); + -+ rga_log("---------------------------------------------------------------\n"); ++ pr_info("---------------------------------------------------------------\n"); + } +} + @@ -1911814,7 +1910117,7 @@ index 000000000..b130e6e60 + * The length of each sgl is expected to be obtained here, not + * the length of the entire dma_buf, so sg_dma_len() is not used. + */ -+ len = (sgl->length + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ len = sgl->length >> PAGE_SHIFT; + + if (use_dma_address) + /* @@ -1911833,8 +1910136,6 @@ index 000000000..b130e6e60 + else + Address = sg_phys(sgl); + -+ Address &= PAGE_MASK; -+ + for (i = 0; i < len; i++) { + if (mapped_size + i >= pageCount) { + break_flag = 1; @@ -1911873,8 +1910174,8 @@ index 000000000..b130e6e60 + img_size = rga_image_size_cal(img->vir_w, img->vir_h, img->format, + &yrgb_size, &uv_size, &v_size); + if (img_size <= 0) { -+ rga_job_err(job, "Image size cal error! width = %d, height = %d, format = %s\n", -+ img->vir_w, img->vir_h, rga_get_format_name(img->format)); ++ pr_err("Image size cal error! width = %d, height = %d, format = %s\n", ++ img->vir_w, img->vir_h, rga_get_format_name(img->format)); + return -EINVAL; + } + @@ -1911893,17 +1910194,23 @@ index 000000000..b130e6e60 + page_count = yrgb_count + uv_count + v_count; + + if (page_count <= 0) { -+ rga_job_err(job, "page count cal error! yrba = %d, uv = %d, v = %d\n", -+ yrgb_count, uv_count, v_count); ++ pr_err("page count cal error! yrba = %d, uv = %d, v = %d\n", ++ yrgb_count, uv_count, v_count); + return -EFAULT; + } + + if (job->flags & RGA_JOB_USE_HANDLE) { -+ page_table = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32, -+ &order, page_count * sizeof(uint32_t *)); ++ order = get_order(page_count * sizeof(uint32_t *)); ++ if (order >= MAX_ORDER) { ++ pr_err("Can not alloc pages with order[%d] for page_table, max_order = %d\n", ++ order, MAX_ORDER); ++ return -ENOMEM; ++ } ++ ++ page_table = (uint32_t *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); + if (page_table == NULL) { -+ rga_job_err(job, "%s can not alloc pages for page_table, order = %d\n", -+ __func__, order); ++ pr_err("%s can not alloc pages for page_table, order = %d\n", ++ __func__, order); + return -ENOMEM; + } + } else { @@ -1911911,7 +1910218,7 @@ index 000000000..b130e6e60 + + page_table = rga_mmu_buf_get(rga_drvdata->mmu_base, page_count); + if (page_table == NULL) { -+ rga_err("mmu_buf get error!\n"); ++ pr_err("mmu_buf get error!\n"); + mutex_unlock(&rga_drvdata->lock); + return -EFAULT; + } @@ -1911921,7 +1910228,7 @@ index 000000000..b130e6e60 + + sgt = rga_mm_lookup_sgt(job_buf->y_addr); + if (sgt == NULL) { -+ rga_job_err(job, "rga2 cannot get sgt from internal buffer!\n"); ++ pr_err("rga2 cannot get sgt from internal buffer!\n"); + ret = -EINVAL; + goto err_free_page_table; + } @@ -1911929,7 +1910236,7 @@ index 000000000..b130e6e60 + + sgt = rga_mm_lookup_sgt(job_buf->uv_addr); + if (sgt == NULL) { -+ rga_job_err(job, "rga2 cannot get sgt from internal buffer!\n"); ++ pr_err("rga2 cannot get sgt from internal buffer!\n"); + ret = -EINVAL; + goto err_free_page_table; + } @@ -1911937,7 +1910244,7 @@ index 000000000..b130e6e60 + + sgt = rga_mm_lookup_sgt(job_buf->v_addr); + if (sgt == NULL) { -+ rga_job_err(job, "rga2 cannot get sgt from internal buffer!\n"); ++ pr_err("rga2 cannot get sgt from internal buffer!\n"); + ret = -EINVAL; + goto err_free_page_table; + } @@ -1911952,17 +1910259,23 @@ index 000000000..b130e6e60 + + page_count = RGA_GET_PAGE_COUNT(img_size + img_offset); + if (page_count < 0) { -+ rga_job_err(job, "page count cal error! yrba = %d, uv = %d, v = %d\n", -+ yrgb_count, uv_count, v_count); ++ pr_err("page count cal error! yrba = %d, uv = %d, v = %d\n", ++ yrgb_count, uv_count, v_count); + return -EFAULT; + } + + if (job->flags & RGA_JOB_USE_HANDLE) { -+ page_table = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32, -+ &order, page_count * sizeof(uint32_t *)); ++ order = get_order(page_count * sizeof(uint32_t *)); ++ if (order >= MAX_ORDER) { ++ pr_err("Can not alloc pages with order[%d] for page_table, max_order = %d\n", ++ order, MAX_ORDER); ++ return -ENOMEM; ++ } ++ ++ page_table = (uint32_t *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); + if (page_table == NULL) { -+ rga_job_err(job, "%s can not alloc pages for page_table, order = %d\n", -+ __func__, order); ++ pr_err("%s can not alloc pages for page_table, order = %d\n", ++ __func__, order); + return -ENOMEM; + } + } else { @@ -1911970,7 +1910283,7 @@ index 000000000..b130e6e60 + + page_table = rga_mmu_buf_get(rga_drvdata->mmu_base, page_count); + if (page_table == NULL) { -+ rga_job_err(job, "mmu_buf get error!\n"); ++ pr_err("mmu_buf get error!\n"); + mutex_unlock(&rga_drvdata->lock); + return -EFAULT; + } @@ -1911980,7 +1910293,7 @@ index 000000000..b130e6e60 + + sgt = rga_mm_lookup_sgt(job_buf->addr); + if (sgt == NULL) { -+ rga_job_err(job, "rga2 cannot get sgt from internal buffer!\n"); ++ pr_err("rga2 cannot get sgt from internal buffer!\n"); + ret = -EINVAL; + goto err_free_page_table; + } @@ -1912008,44 +1910321,28 @@ index 000000000..b130e6e60 +{ + struct sg_table *sgt; + struct rga_scheduler_t *scheduler; -+ ktime_t timestamp = ktime_get(); + -+ scheduler = buffer->scheduler; ++ scheduler = buffer->dma_buffer->scheduler; + if (scheduler == NULL) { -+ rga_job_err(job, "%s(%d), failed to get scheduler, core = 0x%x\n", -+ __func__, __LINE__, job->core); ++ pr_err("%s(%d), failed to get scheduler, core = 0x%x\n", ++ __func__, __LINE__, job->core); + return -EFAULT; + } + -+ if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) { -+ if (scheduler->data->mmu == RGA_IOMMU) { -+ if (rga_mm_is_invalid_dma_buffer(buffer->dma_buffer)) { -+ rga_job_err(job, "invalid dma-buffer with IOMMU device!\n"); -+ return -EFAULT; -+ } -+ -+ dma_sync_single_for_device(buffer->dma_buffer->map_dev, -+ buffer->dma_buffer->iova, buffer->dma_buffer->size, dir); -+ } else { -+ dma_sync_single_for_device(scheduler->dev, -+ buffer->phys_addr, buffer->size, dir); -+ } ++ if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS && ++ scheduler->data->mmu != RGA_IOMMU) { ++ dma_sync_single_for_device(scheduler->dev, buffer->phys_addr, buffer->size, dir); + } else { + sgt = rga_mm_lookup_sgt(buffer); + if (sgt == NULL) { -+ rga_job_err(job, "%s(%d), failed to get sgt, core = 0x%x\n", -+ __func__, __LINE__, job->core); ++ pr_err("%s(%d), failed to get sgt, core = 0x%x\n", ++ __func__, __LINE__, job->core); + return -EINVAL; + } + + dma_sync_sg_for_device(scheduler->dev, sgt->sgl, sgt->orig_nents, dir); + } + -+ if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "handle[%d], %s, flush CPU cache for device cost %lld us\n", -+ buffer->handle, rga_get_dma_data_direction_str(dir), -+ ktime_us_delta(ktime_get(), timestamp)); -+ + return 0; +} + @@ -1912055,44 +1910352,28 @@ index 000000000..b130e6e60 +{ + struct sg_table *sgt; + struct rga_scheduler_t *scheduler; -+ ktime_t timestamp = ktime_get(); + -+ scheduler = buffer->scheduler; ++ scheduler = buffer->dma_buffer->scheduler; + if (scheduler == NULL) { -+ rga_job_err(job, "%s(%d), failed to get scheduler, core = 0x%x\n", -+ __func__, __LINE__, job->core); ++ pr_err("%s(%d), failed to get scheduler, core = 0x%x\n", ++ __func__, __LINE__, job->core); + return -EFAULT; + } + -+ if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) { -+ if (scheduler->data->mmu == RGA_IOMMU) { -+ if (rga_mm_is_invalid_dma_buffer(buffer->dma_buffer)) { -+ rga_job_err(job, "invalid dma-buffer with IOMMU device!\n"); -+ return -EFAULT; -+ } -+ -+ dma_sync_single_for_cpu(buffer->dma_buffer->map_dev, -+ buffer->dma_buffer->iova, buffer->dma_buffer->size, dir); -+ } else { -+ dma_sync_single_for_cpu(scheduler->dev, -+ buffer->phys_addr, buffer->size, dir); -+ } ++ if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS && ++ scheduler->data->mmu != RGA_IOMMU) { ++ dma_sync_single_for_cpu(scheduler->dev, buffer->phys_addr, buffer->size, dir); + } else { + sgt = rga_mm_lookup_sgt(buffer); + if (sgt == NULL) { -+ rga_job_err(job, "%s(%d), failed to get sgt, core = 0x%x\n", -+ __func__, __LINE__, job->core); ++ pr_err("%s(%d), failed to get sgt, core = 0x%x\n", ++ __func__, __LINE__, job->core); + return -EINVAL; + } + + dma_sync_sg_for_cpu(scheduler->dev, sgt->sgl, sgt->orig_nents, dir); + } + -+ if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "handle[%d], %s, flush CPU cache for CPU cost %lld us\n", -+ buffer->handle, rga_get_dma_data_direction_str(dir), -+ ktime_us_delta(ktime_get(), timestamp)); -+ + return 0; +} + @@ -1912104,15 +1910385,12 @@ index 000000000..b130e6e60 + + switch (job->scheduler->data->mmu) { + case RGA_IOMMU: -+ if (rga_mm_is_invalid_dma_buffer(internal_buffer->dma_buffer)) { -+ rga_job_err(job, -+ "core[%d] handle[%d] lookup buffer_type[0x%x] iova error!\n", -+ job->core, internal_buffer->handle, internal_buffer->type); ++ addr = rga_mm_lookup_iova(internal_buffer); ++ if (addr == 0) { ++ pr_err("core[%d] lookup buffer_type[0x%x] iova error!\n", ++ job->core, internal_buffer->type); + return -EINVAL; + } -+ -+ addr = rga_mm_lookup_iova(internal_buffer); -+ + break; + case RGA_MMU: + default: @@ -1912133,7 +1910411,7 @@ index 000000000..b130e6e60 + addr = internal_buffer->phys_addr; + break; + default: -+ rga_job_err(job, "Illegal external buffer!\n"); ++ pr_err("Illegal external buffer!\n"); + return -EFAULT; + } + break; @@ -1912156,14 +1910434,14 @@ index 000000000..b130e6e60 + struct rga_internal_buffer *internal_buffer = NULL; + + if (handle == 0) { -+ rga_job_err(job, "No buffer handle can be used!\n"); ++ pr_err("No buffer handle can be used!\n"); + return -EFAULT; + } + + mutex_lock(&mm->lock); + *buf = rga_mm_lookup_handle(mm, handle); + if (*buf == NULL) { -+ rga_job_err(job, "This handle[%ld] is illegal.\n", (unsigned long)handle); ++ pr_err("This handle[%ld] is illegal.\n", (unsigned long)handle); + + mutex_unlock(&mm->lock); + return -EFAULT; @@ -1912173,7 +1910451,7 @@ index 000000000..b130e6e60 + kref_get(&internal_buffer->refcount); + + if (DEBUGGER_EN(MM)) { -+ rga_job_log(job, "handle[%d] get info:\n", (int)handle); ++ pr_info("handle[%d] get info:\n", (int)handle); + rga_mm_dump_buffer(internal_buffer); + } + @@ -1912181,14 +1910459,13 @@ index 000000000..b130e6e60 + + ret = rga_mm_get_buffer_info(job, internal_buffer, channel_addr); + if (ret < 0) { -+ rga_job_err(job, "handle[%ld] failed to get internal buffer info!\n", -+ (unsigned long)handle); ++ pr_err("handle[%ld] failed to get internal buffer info!\n", (unsigned long)handle); + return ret; + } + + if (internal_buffer->size < require_size) { + ret = -EINVAL; -+ rga_job_err(job, "Only get buffer %ld byte from handle[%ld], but current required %d byte\n", ++ pr_err("Only get buffer %ld byte from handle[%ld], but current required %d byte\n", + internal_buffer->size, (unsigned long)handle, require_size); + + goto put_internal_buffer; @@ -1912202,7 +1910479,7 @@ index 000000000..b130e6e60 + */ + ret = rga_mm_sync_dma_sg_for_device(internal_buffer, job, dir); + if (ret < 0) { -+ rga_job_err(job, "sync sgt for device error!\n"); ++ pr_err("sync sgt for device error!\n"); + goto put_internal_buffer; + } + } @@ -1912225,10 +1910502,10 @@ index 000000000..b130e6e60 +{ + if (internal_buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE && dir != DMA_NONE) + if (rga_mm_sync_dma_sg_for_cpu(internal_buffer, job, dir)) -+ rga_job_err(job, "sync sgt for cpu error!\n"); ++ pr_err("sync sgt for cpu error!\n"); + + if (DEBUGGER_EN(MM)) { -+ rga_job_log(job, "handle[%d] put info:\n", (int)internal_buffer->handle); ++ pr_info("handle[%d] put info:\n", (int)internal_buffer->handle); + rga_mm_dump_buffer(internal_buffer); + } + @@ -1912266,8 +1910543,8 @@ index 000000000..b130e6e60 + img_size = rga_image_size_cal(img->vir_w, img->vir_h, img->format, + &yrgb_size, &uv_size, &v_size); + if (img_size <= 0) { -+ rga_job_err(job, "Image size cal error! width = %d, height = %d, format = %s\n", -+ img->vir_w, img->vir_h, rga_get_format_name(img->format)); ++ pr_err("Image size cal error! width = %d, height = %d, format = %s\n", ++ img->vir_w, img->vir_h, rga_get_format_name(img->format)); + return -EINVAL; + } + @@ -1912278,8 +1910555,7 @@ index 000000000..b130e6e60 + ret = rga_mm_get_buffer(mm, job, handle, &img->yrgb_addr, + &job_buf->y_addr, yrgb_size, dir); + if (ret < 0) { -+ rga_job_err(job, "handle[%d] Can't get y/rgb address info!\n", -+ handle); ++ pr_err("handle[%d] Can't get y/rgb address info!\n", handle); + return ret; + } + } @@ -1912289,7 +1910565,7 @@ index 000000000..b130e6e60 + ret = rga_mm_get_buffer(mm, job, handle, &img->uv_addr, + &job_buf->uv_addr, uv_size, dir); + if (ret < 0) { -+ rga_job_err(job, "handle[%d] Can't get uv address info!\n", handle); ++ pr_err("handle[%d] Can't get uv address info!\n", handle); + return ret; + } + } @@ -1912299,7 +1910575,7 @@ index 000000000..b130e6e60 + ret = rga_mm_get_buffer(mm, job, handle, &img->v_addr, + &job_buf->v_addr, v_size, dir); + if (ret < 0) { -+ rga_job_err(job, "handle[%d] Can't get uv address info!\n", handle); ++ pr_err("handle[%d] Can't get uv address info!\n", handle); + return ret; + } + } @@ -1912309,8 +1910585,7 @@ index 000000000..b130e6e60 + ret = rga_mm_get_buffer(mm, job, handle, &img->yrgb_addr, + &job_buf->addr, img_size, dir); + if (ret < 0) { -+ rga_job_err(job, "handle[%d] Can't get y/rgb address info!\n", -+ handle); ++ pr_err("handle[%d] Can't get y/rgb address info!\n", handle); + return ret; + } + } @@ -1912322,7 +1910597,7 @@ index 000000000..b130e6e60 + rga_mm_is_need_mmu(job, job_buf->addr)) { + ret = rga_mm_set_mmu_base(job, img, job_buf); + if (ret < 0) { -+ rga_job_err(job, "Can't set RGA2 MMU_BASE from handle!\n"); ++ pr_err("Can't set RGA2 MMU_BASE from handle!\n"); + + rga_mm_put_channel_handle_info(mm, job, job_buf, dir); + return ret; @@ -1912346,21 +1910621,21 @@ index 000000000..b130e6e60 + case BITBLT_MODE: + case COLOR_PALETTE_MODE: + if (unlikely(req->src.yrgb_addr <= 0)) { -+ rga_job_err(job, "render_mode[0x%x] src0 channel handle[%ld] must is valid!", -+ req->render_mode, (unsigned long)req->src.yrgb_addr); ++ pr_err("render_mode[0x%x] src0 channel handle[%ld] must is valid!", ++ req->render_mode, (unsigned long)req->src.yrgb_addr); + return -EINVAL; + } + + if (unlikely(req->dst.yrgb_addr <= 0)) { -+ rga_job_err(job, "render_mode[0x%x] dst channel handle[%ld] must is valid!", -+ req->render_mode, (unsigned long)req->dst.yrgb_addr); ++ pr_err("render_mode[0x%x] dst channel handle[%ld] must is valid!", ++ req->render_mode, (unsigned long)req->dst.yrgb_addr); + return -EINVAL; + } + + if (req->bsfilter_flag) { + if (unlikely(req->pat.yrgb_addr <= 0)) { -+ rga_job_err(job, "render_mode[0x%x] src1/pat channel handle[%ld] must is valid!", -+ req->render_mode, (unsigned long)req->pat.yrgb_addr); ++ pr_err("render_mode[0x%x] src1/pat channel handle[%ld] must is valid!", ++ req->render_mode, (unsigned long)req->pat.yrgb_addr); + return -EINVAL; + } + } @@ -1912368,8 +1910643,8 @@ index 000000000..b130e6e60 + break; + case COLOR_FILL_MODE: + if (unlikely(req->dst.yrgb_addr <= 0)) { -+ rga_job_err(job, "render_mode[0x%x] dst channel handle[%ld] must is valid!", -+ req->render_mode, (unsigned long)req->dst.yrgb_addr); ++ pr_err("render_mode[0x%x] dst channel handle[%ld] must is valid!", ++ req->render_mode, (unsigned long)req->dst.yrgb_addr); + return -EINVAL; + } + @@ -1912378,14 +1910653,14 @@ index 000000000..b130e6e60 + case UPDATE_PALETTE_TABLE_MODE: + case UPDATE_PATTEN_BUF_MODE: + if (unlikely(req->pat.yrgb_addr <= 0)) { -+ rga_job_err(job, "render_mode[0x%x] lut/pat channel handle[%ld] must is valid!", -+ req->render_mode, (unsigned long)req->pat.yrgb_addr); ++ pr_err("render_mode[0x%x] lut/pat channel handle[%ld] must is valid!, req->render_mode", ++ req->render_mode, (unsigned long)req->pat.yrgb_addr); + return -EINVAL; + } + + break; + default: -+ rga_job_err(job, "%s, unknown render mode!\n", __func__); ++ pr_err("%s, unknown render mode!\n", __func__); + break; + } + @@ -1912394,7 +1910669,7 @@ index 000000000..b130e6e60 + &job->src_buffer, + DMA_TO_DEVICE); + if (ret < 0) { -+ rga_job_err(job, "Can't get src buffer info from handle!\n"); ++ pr_err("Can't get src buffer info from handle!\n"); + return ret; + } + } @@ -1912404,7 +1910679,7 @@ index 000000000..b130e6e60 + &job->dst_buffer, + DMA_TO_DEVICE); + if (ret < 0) { -+ rga_job_err(job, "Can't get dst buffer info from handle!\n"); ++ pr_err("Can't get dst buffer info from handle!\n"); + return ret; + } + } @@ -1912426,7 +1910701,7 @@ index 000000000..b130e6e60 + DMA_BIDIRECTIONAL); + } + if (ret < 0) { -+ rga_job_err(job, "Can't get pat buffer info from handle!\n"); ++ pr_err("Can't get pat buffer info from handle!\n"); + return ret; + } + } @@ -1912465,15 +1910740,15 @@ index 000000000..b130e6e60 + /* Default unsupported multi-planar format */ + external_buffer = kzalloc(sizeof(*external_buffer), GFP_KERNEL); + if (external_buffer == NULL) { -+ rga_err("Cannot alloc job_buffer!\n"); ++ pr_err("Cannot alloc job_buffer!\n"); + return -ENOMEM; + } + + if (img_info->yrgb_addr) { + dma_buf = dma_buf_get(img_info->yrgb_addr); + if (IS_ERR(dma_buf)) { -+ rga_err("%s dma_buf_get fail fd[%lu]\n", -+ __func__, (unsigned long)img_info->yrgb_addr); ++ pr_err("%s dma_buf_get fail fd[%lu]\n", ++ __func__, (unsigned long)img_info->yrgb_addr); + kfree(external_buffer); + return -EINVAL; + } @@ -1912537,7 +1910812,7 @@ index 000000000..b130e6e60 + mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 8) & 1); + ret = rga_mm_get_channel_external_buffer(mmu_flag, src0, &job->src_buffer); + if (ret < 0) { -+ rga_job_err(job, "Cannot get src0 channel buffer!\n"); ++ pr_err("Cannot get src0 channel buffer!\n"); + return ret; + } + } @@ -1912546,7 +1910821,7 @@ index 000000000..b130e6e60 + mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 10) & 1); + ret = rga_mm_get_channel_external_buffer(mmu_flag, dst, &job->dst_buffer); + if (ret < 0) { -+ rga_job_err(job, "Cannot get dst channel buffer!\n"); ++ pr_err("Cannot get dst channel buffer!\n"); + goto error_put_buffer; + } + } @@ -1912555,7 +1910830,7 @@ index 000000000..b130e6e60 + mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 9) & 1); + ret = rga_mm_get_channel_external_buffer(mmu_flag, src1, &job->src1_buffer); + if (ret < 0) { -+ rga_job_err(job, "Cannot get src1 channel buffer!\n"); ++ pr_err("Cannot get src1 channel buffer!\n"); + goto error_put_buffer; + } + } @@ -1912564,7 +1910839,7 @@ index 000000000..b130e6e60 + mmu_flag = ((job->rga_command_base.mmu_info.mmu_flag >> 11) & 1); + ret = rga_mm_get_channel_external_buffer(mmu_flag, els, &job->els_buffer); + if (ret < 0) { -+ rga_job_err(job, "Cannot get els channel buffer!\n"); ++ pr_err("Cannot get els channel buffer!\n"); + goto error_put_buffer; + } + } @@ -1912581,12 +1910856,7 @@ index 000000000..b130e6e60 +{ + if (job_buffer->addr->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE && dir != DMA_NONE) + if (rga_mm_sync_dma_sg_for_cpu(job_buffer->addr, job, dir)) -+ rga_job_err(job, "sync sgt for cpu error!\n"); -+ -+ if (DEBUGGER_EN(MM)) { -+ rga_job_log(job, "unmap buffer:\n"); -+ rga_mm_dump_buffer(job_buffer->addr); -+ } ++ pr_err("sync sgt for cpu error!\n"); + + rga_mm_unmap_buffer(job_buffer->addr); + kfree(job_buffer->addr); @@ -1912605,33 +1910875,26 @@ index 000000000..b130e6e60 + + buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + if (buffer == NULL) { -+ rga_job_err(job, "%s alloc internal_buffer error!\n", __func__); ++ pr_err("%s alloc internal_buffer error!\n", __func__); + return -ENOMEM; + } + -+ ret = rga_mm_map_buffer(job_buffer->ex_addr, buffer, job, write_flag); -+ if (ret < 0) { -+ rga_job_err(job, "job buffer map failed!\n"); -+ goto error_free_buffer; -+ } -+ -+ buffer->session = job->session; -+ -+ if (DEBUGGER_EN(MM)) { -+ rga_job_log(job, "map buffer:\n"); -+ rga_mm_dump_buffer(buffer); ++ ret = rga_mm_map_buffer(job_buffer->ex_addr, buffer, job, write_flag); ++ if (ret < 0) { ++ pr_err("job buffer map failed!\n"); ++ goto error_free_buffer; + } + + ret = rga_mm_get_buffer_info(job, buffer, &img->yrgb_addr); + if (ret < 0) { -+ rga_job_err(job, "Failed to get internal buffer info!\n"); ++ pr_err("Failed to get internal buffer info!\n"); + goto error_unmap_buffer; + } + + if (buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE) { + ret = rga_mm_sync_dma_sg_for_device(buffer, job, dir); + if (ret < 0) { -+ rga_job_err(job, "sync sgt for device error!\n"); ++ pr_err("sync sgt for device error!\n"); + goto error_unmap_buffer; + } + } @@ -1912644,7 +1910907,7 @@ index 000000000..b130e6e60 + rga_mm_is_need_mmu(job, job_buffer->addr)) { + ret = rga_mm_set_mmu_base(job, img, job_buffer); + if (ret < 0) { -+ rga_job_err(job, "Can't set RGA2 MMU_BASE!\n"); ++ pr_err("Can't set RGA2 MMU_BASE!\n"); + job_buffer->addr = NULL; + goto error_unmap_buffer; + } @@ -1912682,7 +1910945,7 @@ index 000000000..b130e6e60 + + ret = rga_mm_get_external_buffer(job); + if (ret < 0) { -+ rga_job_err(job, "failed to get external buffer from job_cmd!\n"); ++ pr_err("failed to get external buffer from job_cmd!\n"); + return ret; + } + @@ -1912693,7 +1910956,7 @@ index 000000000..b130e6e60 + &job->src_buffer, + DMA_TO_DEVICE, false); + if (ret < 0) { -+ rga_job_err(job, "src channel map job buffer failed!"); ++ pr_err("src channel map job buffer failed!"); + goto error_unmap_buffer; + } + } @@ -1912703,7 +1910966,7 @@ index 000000000..b130e6e60 + &job->dst_buffer, + DMA_TO_DEVICE, true); + if (ret < 0) { -+ rga_job_err(job, "dst channel map job buffer failed!"); ++ pr_err("dst channel map job buffer failed!"); + goto error_unmap_buffer; + } + } @@ -1912718,7 +1910981,7 @@ index 000000000..b130e6e60 + &job->src1_buffer, + dir, false); + if (ret < 0) { -+ rga_job_err(job, "src1 channel map job buffer failed!"); ++ pr_err("src1 channel map job buffer failed!"); + goto error_unmap_buffer; + } + } @@ -1912728,7 +1910991,7 @@ index 000000000..b130e6e60 + &job->els_buffer, + DMA_BIDIRECTIONAL, false); + if (ret < 0) { -+ rga_job_err(job, "els channel map job buffer failed!"); ++ pr_err("els channel map job buffer failed!"); + goto error_unmap_buffer; + } + } @@ -1912742,221 +1911005,31 @@ index 000000000..b130e6e60 + return ret; +} + -+static void rga_mm_free_channel_fake_buffer(struct rga_job *job, -+ struct rga_job_buffer *job_buffer, -+ enum dma_data_direction dir) -+{ -+ struct rga_internal_buffer *buffer = job_buffer->addr; -+ -+ if (rga_mm_is_invalid_dma_buffer(buffer->dma_buffer)) -+ return; -+ -+ if (DEBUGGER_EN(MM)) { -+ rga_job_log(job, "free fake-buffer dump info:\n"); -+ rga_mm_dump_buffer(buffer); -+ } -+ -+ rga_dma_free(buffer->dma_buffer); -+ kfree(buffer); -+ job_buffer->addr = NULL; -+} -+ -+static int rga_mm_alloc_channel_fake_buffer(struct rga_job *job, -+ struct rga_img_info_t *img, -+ struct rga_job_buffer *job_buffer, -+ enum dma_data_direction dir) -+{ -+ int ret; -+ int size; -+ uint32_t mm_flag; -+ uint64_t phys_addr; -+ struct rga_internal_buffer *buffer; -+ struct rga_dma_buffer *dma_buf; -+ -+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); -+ if (buffer == NULL) { -+ rga_job_err(job, "%s alloc internal_buffer error!\n", __func__); -+ return -ENOMEM; -+ } -+ -+ size = rga_image_size_cal(img->vir_w, img->vir_h, img->format, -+ NULL, NULL, NULL); -+ dma_buf = rga_dma_alloc_coherent(job->scheduler, size); -+ if (dma_buf == NULL) { -+ ret = -ENOMEM; -+ rga_job_err(job, "%s failed to alloc dma_buf.\n", __func__); -+ goto error_free_buffer; -+ } -+ -+ mm_flag = RGA_MEM_PHYSICAL_CONTIGUOUS | RGA_MEM_UNDER_4G; -+ if (job->scheduler->data->mmu != RGA_IOMMU) { -+ mm_flag |= RGA_MEM_NEED_USE_IOMMU; -+ phys_addr = 0; -+ } else { -+ phys_addr = dma_buf->dma_addr; -+ } -+ -+ if (!rga_mm_check_memory_limit(job->scheduler, mm_flag)) { -+ rga_job_err(job, "%s scheduler core[%d] unsupported mm_flag[0x%x]!\n", -+ __func__, job->scheduler->core, mm_flag); -+ ret = -EINVAL; -+ goto error_free_dma_buf; -+ } -+ -+ buffer->type = RGA_DMA_BUFFER_PTR; -+ buffer->size = dma_buf->size - dma_buf->offset; -+ buffer->mm_flag = mm_flag; -+ buffer->dma_buffer = dma_buf; -+ buffer->phys_addr = phys_addr; -+ -+ buffer->memory_parm.width = img->vir_w; -+ buffer->memory_parm.height = img->vir_h; -+ buffer->memory_parm.format = img->format; -+ buffer->memory_parm.size = size; -+ -+ ret = rga_mm_get_buffer_info(job, buffer, &img->yrgb_addr); -+ if (ret < 0) -+ goto error_free_dma_buf; -+ -+ rga_convert_addr(img, false); -+ -+ job_buffer->addr = buffer; -+ -+ if (job->scheduler->data->mmu == RGA_MMU && -+ rga_mm_is_need_mmu(job, job_buffer->addr)) { -+ ret = rga_mm_set_mmu_base(job, img, job_buffer); -+ if (ret < 0) { -+ job_buffer->addr = NULL; -+ goto error_free_dma_buf; -+ } -+ } -+ -+ if (DEBUGGER_EN(MM)) { -+ rga_job_log(job, "alloc fake-buffer dump info:\n"); -+ rga_mm_dump_buffer(buffer); -+ } -+ -+ return 0; -+ -+error_free_dma_buf: -+ rga_dma_free(dma_buf); -+ -+error_free_buffer: -+ kfree(buffer); -+ -+ return ret; -+} -+ -+static void rga_mm_free_fake_buffer(struct rga_job *job) -+{ -+ if (job->src_buffer.addr) -+ rga_mm_free_channel_fake_buffer(job, &job->src_buffer, DMA_NONE); -+ if (job->dst_buffer.addr) -+ rga_mm_free_channel_fake_buffer(job, &job->dst_buffer, DMA_FROM_DEVICE); -+ if (job->src1_buffer.addr) -+ rga_mm_free_channel_fake_buffer(job, &job->src1_buffer, DMA_NONE); -+ if (job->els_buffer.addr) -+ rga_mm_free_channel_fake_buffer(job, &job->els_buffer, DMA_NONE); -+} -+ -+static int rga_mm_alloc_fake_buffer(struct rga_job *job) -+{ -+ int ret = 0; -+ struct rga_req *req = NULL; -+ enum dma_data_direction dir; -+ -+ req = &job->rga_command_base; -+ -+ if (req->src.yrgb_addr != 0 || req->src.uv_addr != 0) { -+ ret = rga_mm_alloc_channel_fake_buffer(job, &req->src, -+ &job->src_buffer, DMA_TO_DEVICE); -+ if (ret < 0) { -+ rga_job_err(job, "%s src channel map job buffer failed!", __func__); -+ goto error_free_fake_buffer; -+ } -+ } -+ -+ if (req->dst.yrgb_addr != 0 || req->dst.uv_addr != 0) { -+ ret = rga_mm_alloc_channel_fake_buffer(job, &req->dst, -+ &job->dst_buffer, DMA_TO_DEVICE); -+ if (ret < 0) { -+ rga_job_err(job, "%s dst channel map job buffer failed!", __func__); -+ goto error_free_fake_buffer; -+ } -+ } -+ -+ if (job->rga_command_base.render_mode != UPDATE_PALETTE_TABLE_MODE && -+ (req->pat.yrgb_addr != 0 || req->pat.uv_addr != 0)) { -+ if (req->bsfilter_flag) -+ dir = DMA_BIDIRECTIONAL; -+ else -+ dir = DMA_TO_DEVICE; -+ -+ ret = rga_mm_alloc_channel_fake_buffer(job, &req->pat, -+ &job->src1_buffer, dir); -+ if (ret < 0) { -+ rga_job_err(job, "%s src1 channel map job buffer failed!", __func__); -+ goto error_free_fake_buffer; -+ } -+ } else if (req->pat.yrgb_addr != 0 || req->pat.uv_addr != 0) { -+ ret = rga_mm_alloc_channel_fake_buffer(job, &req->pat, -+ &job->els_buffer, DMA_TO_DEVICE); -+ if (ret < 0) { -+ rga_job_err(job, "%s els channel map job buffer failed!", __func__); -+ goto error_free_fake_buffer; -+ } -+ } -+ -+ rga_mm_set_mmu_flag(job); -+ -+ return 0; -+ -+error_free_fake_buffer: -+ rga_mm_free_fake_buffer(job); -+ -+ return ret; -+} -+ +int rga_mm_map_job_info(struct rga_job *job) +{ + int ret; + ktime_t timestamp = ktime_get(); + -+ if (job->flags & RGA_JOB_DEBUG_FAKE_BUFFER) { -+ ret = rga_mm_alloc_fake_buffer(job); -+ if (ret < 0) -+ return ret; -+ -+ if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "alloc fake buffer cost %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); -+ -+ job->flags &= ~RGA_JOB_USE_HANDLE; -+ job->flags |= RGA_JOB_DEBUG_FAKE_BUFFER; -+ -+ return 0; -+ } -+ + if (job->flags & RGA_JOB_USE_HANDLE) { + ret = rga_mm_get_handle_info(job); + if (ret < 0) { -+ rga_job_err(job, "failed to get buffer from handle\n"); ++ pr_err("failed to get buffer from handle\n"); + return ret; + } + + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "get buffer_handle info cost %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); ++ pr_info("request[%d], get buffer_handle info cost %lld us\n", ++ job->request_id, ktime_us_delta(ktime_get(), timestamp)); + } else { + ret = rga_mm_map_buffer_info(job); + if (ret < 0) { -+ rga_job_err(job, "failed to map buffer\n"); ++ pr_err("failed to map buffer\n"); + return ret; + } + + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "map buffer cost %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); ++ pr_info("request[%d], map buffer cost %lld us\n", ++ job->request_id, ktime_us_delta(ktime_get(), timestamp)); + } + + return 0; @@ -1912966,28 +1911039,18 @@ index 000000000..b130e6e60 +{ + ktime_t timestamp = ktime_get(); + -+ if (job->flags & RGA_JOB_DEBUG_FAKE_BUFFER) { -+ rga_mm_free_fake_buffer(job); -+ -+ if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "free fake buffer cost %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); -+ -+ return; -+ } -+ + if (job->flags & RGA_JOB_USE_HANDLE) { + rga_mm_put_handle_info(job); + + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "put buffer_handle info cost %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); ++ pr_info("request[%d], put buffer_handle info cost %lld us\n", ++ job->request_id, ktime_us_delta(ktime_get(), timestamp)); + } else { + rga_mm_unmap_buffer_info(job); + + if (DEBUGGER_EN(TIME)) -+ rga_job_log(job, "unmap buffer cost %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); ++ pr_info("request[%d], unmap buffer cost %lld us\n", ++ job->request_id, ktime_us_delta(ktime_get(), timestamp)); + } +} + @@ -1913007,11 +1911070,10 @@ index 000000000..b130e6e60 + int ret = 0, new_id; + struct rga_mm *mm; + struct rga_internal_buffer *internal_buffer; -+ ktime_t timestamp = ktime_get(); + + mm = rga_drvdata->mm; + if (mm == NULL) { -+ rga_err("rga mm is null!\n"); ++ pr_err("rga mm is null!\n"); + return -EFAULT; + } + @@ -1913025,19 +1911087,17 @@ index 000000000..b130e6e60 + mutex_unlock(&mm->lock); + + if (DEBUGGER_EN(MM)) { -+ rga_buf_log(internal_buffer, "import existing buffer:\n"); ++ pr_info("import existing buffer:\n"); + rga_mm_dump_buffer(internal_buffer); + } + + return internal_buffer->handle; + } + -+ mutex_unlock(&mm->lock); -+ + /* finally, map and cached external_buffer in rga_mm */ + internal_buffer = kzalloc(sizeof(struct rga_internal_buffer), GFP_KERNEL); + if (internal_buffer == NULL) { -+ rga_err("%s alloc internal_buffer error!\n", __func__); ++ pr_err("%s alloc internal_buffer error!\n", __func__); + + mutex_unlock(&mm->lock); + return -ENOMEM; @@ -1913050,7 +1911110,6 @@ index 000000000..b130e6e60 + kref_init(&internal_buffer->refcount); + internal_buffer->session = session; + -+ mutex_lock(&mm->lock); + /* + * Get the user-visible handle using idr. Preload and perform + * allocation under our spinlock. @@ -1913059,10 +1911118,8 @@ index 000000000..b130e6e60 + new_id = idr_alloc_cyclic(&mm->memory_idr, internal_buffer, 1, 0, GFP_NOWAIT); + idr_preload_end(); + if (new_id < 0) { -+ rga_err("internal_buffer alloc id failed!\n"); ++ pr_err("internal_buffer alloc id failed!\n"); + ret = new_id; -+ -+ mutex_unlock(&mm->lock); + goto FREE_INTERNAL_BUFFER; + } + @@ -1913070,19 +1911127,15 @@ index 000000000..b130e6e60 + mm->buffer_count++; + + if (DEBUGGER_EN(MM)) { -+ rga_buf_log(internal_buffer, "import buffer:\n"); ++ pr_info("import buffer:\n"); + rga_mm_dump_buffer(internal_buffer); + } + + mutex_unlock(&mm->lock); -+ -+ if (DEBUGGER_EN(TIME)) -+ rga_buf_log(internal_buffer, "import buffer cost %lld us\n", -+ ktime_us_delta(ktime_get(), timestamp)); -+ + return internal_buffer->handle; + +FREE_INTERNAL_BUFFER: ++ mutex_unlock(&mm->lock); + kfree(internal_buffer); + + return ret; @@ -1913092,11 +1911145,10 @@ index 000000000..b130e6e60 +{ + struct rga_mm *mm; + struct rga_internal_buffer *internal_buffer; -+ ktime_t timestamp = ktime_get(); + + mm = rga_drvdata->mm; + if (mm == NULL) { -+ rga_err("rga mm is null!\n"); ++ pr_err("rga mm is null!\n"); + return -EFAULT; + } + @@ -1913105,25 +1911157,20 @@ index 000000000..b130e6e60 + /* Find the buffer that has been imported */ + internal_buffer = rga_mm_lookup_handle(mm, handle); + if (IS_ERR_OR_NULL(internal_buffer)) { -+ rga_err("This is not a buffer that has been imported, handle = %d\n", (int)handle); ++ pr_err("This is not a buffer that has been imported, handle = %d\n", (int)handle); + + mutex_unlock(&mm->lock); + return -ENOENT; + } + + if (DEBUGGER_EN(MM)) { -+ rga_buf_log(internal_buffer, "release buffer:\n"); ++ pr_info("release buffer:\n"); + rga_mm_dump_buffer(internal_buffer); + } + + kref_put(&internal_buffer->refcount, rga_mm_kref_release_buffer); + -+ if (DEBUGGER_EN(TIME)) -+ rga_log("handle[%d]: release buffer cost %lld us\n", -+ handle, ktime_us_delta(ktime_get(), timestamp)); -+ + mutex_unlock(&mm->lock); -+ + return 0; +} + @@ -1913135,7 +1911182,7 @@ index 000000000..b130e6e60 + + mm = rga_drvdata->mm; + if (mm == NULL) { -+ rga_err("rga mm is null!\n"); ++ pr_err("rga mm is null!\n"); + return -EFAULT; + } + @@ -1913143,9 +1911190,9 @@ index 000000000..b130e6e60 + + idr_for_each_entry(&mm->memory_idr, buffer, i) { + if (session == buffer->session) { -+ rga_err("[tgid:%d] Destroy handle[%d] when the user exits\n", ++ pr_err("[tgid:%d] Destroy handle[%d] when the user exits\n", + session->tgid, buffer->handle); -+ rga_mm_force_releaser_buffer(buffer); ++ rga_mm_buffer_destroy(buffer); + } + } + @@ -1913177,7 +1911224,7 @@ index 000000000..b130e6e60 + + mutex_lock(&mm->lock); + -+ idr_for_each(&mm->memory_idr, &rga_mm_buffer_destroy_for_idr, mm); ++ idr_for_each(&mm->memory_idr, &rga_mm_handle_remove, mm); + idr_destroy(&mm->memory_idr); + + mutex_unlock(&mm->lock); @@ -1913189,10 +1911236,10 @@ index 000000000..b130e6e60 +} diff --git a/drivers/video/rockchip/rga3/rga_policy.c b/drivers/video/rockchip/rga3/rga_policy.c new file mode 100644 -index 000000000..2554f4bf6 +index 000000000..c87ce1881 --- /dev/null +++ b/drivers/video/rockchip/rga3/rga_policy.c -@@ -0,0 +1,512 @@ +@@ -0,0 +1,426 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Rockchip Electronics Co., Ltd. @@ -1913200,6 +1911247,8 @@ index 000000000..2554f4bf6 + * Author: Huang Lee + */ + ++#define pr_fmt(fmt) "rga_policy: " fmt ++ +#include "rga_job.h" +#include "rga_common.h" +#include "rga_hw_config.h" @@ -1913239,52 +1911288,50 @@ index 000000000..2554f4bf6 + return feature; +} + -+static bool rga_check_csc(const struct rga_hw_data *data, struct rga_req *rga_base) ++static bool rga_check_csc_constant(const struct rga_hw_data *data, struct rga_req *rga_base, ++ uint32_t mode, uint32_t flag) +{ -+ switch (rga_base->yuv2rgb_mode & RGA_Y2R_MASK) { -+ case RGA_Y2R_BT601_LIMIT: -+ if (!(data->csc_y2r_mode & RGA_MODE_CSC_BT601L)) -+ return false; ++ if (mode & flag) ++ return true; + -+ break; -+ case RGA_Y2R_BT601_FULL: -+ if (!(data->csc_y2r_mode & RGA_MODE_CSC_BT601F)) -+ return false; ++ if ((rga_base->full_csc.flag & 0x1) && (data->feature & RGA_FULL_CSC)) ++ return true; + -+ break; -+ case RGA_Y2R_BT709_LIMIT: -+ if (!(data->csc_y2r_mode & RGA_MODE_CSC_BT709)) -+ return false; ++ return false; ++} + -+ break; ++static bool rga_check_csc(const struct rga_hw_data *data, struct rga_req *rga_base) ++{ ++ switch (rga_base->yuv2rgb_mode) { ++ case 0x1: ++ return rga_check_csc_constant(data, rga_base, ++ data->csc_y2r_mode, RGA_MODE_CSC_BT601L); ++ case 0x2: ++ return rga_check_csc_constant(data, rga_base, ++ data->csc_y2r_mode, RGA_MODE_CSC_BT601F); ++ case 0x3: ++ return rga_check_csc_constant(data, rga_base, ++ data->csc_y2r_mode, RGA_MODE_CSC_BT709); ++ case 0x1 << 2: ++ return rga_check_csc_constant(data, rga_base, ++ data->csc_r2y_mode, RGA_MODE_CSC_BT601F); ++ case 0x2 << 2: ++ return rga_check_csc_constant(data, rga_base, ++ data->csc_r2y_mode, RGA_MODE_CSC_BT601L); ++ case 0x3 << 2: ++ return rga_check_csc_constant(data, rga_base, ++ data->csc_r2y_mode, RGA_MODE_CSC_BT709); + default: + break; + } + -+ switch (rga_base->yuv2rgb_mode & RGA_R2Y_MASK) { -+ case RGA_R2Y_BT601_LIMIT: -+ if (!(data->csc_r2y_mode & RGA_MODE_CSC_BT601L)) -+ return false; -+ -+ break; -+ case RGA_R2Y_BT601_FULL: -+ if (!(data->csc_r2y_mode & RGA_MODE_CSC_BT601F)) -+ return false; -+ -+ break; -+ case RGA_R2Y_BT709_LIMIT: -+ if (!(data->csc_r2y_mode & RGA_MODE_CSC_BT709)) ++ if ((rga_base->full_csc.flag & 0x1)) { ++ if (data->feature & RGA_FULL_CSC) ++ return true; ++ else + return false; -+ -+ break; -+ default: -+ break; + } + -+ -+ if ((rga_base->full_csc.flag & 0x1) && !(data->feature & RGA_FULL_CSC)) -+ return false; -+ + return true; +} + @@ -1913319,18 +1911366,6 @@ index 000000000..2554f4bf6 + formats = data->win[win_num].formats[RGA_TILE8x8_INDEX]; + format_count = data->win[win_num].formats_count[RGA_TILE8x8_INDEX]; + break; -+ case RGA_TILE4x4_MODE: -+ formats = data->win[win_num].formats[RGA_TILE4x4_INDEX]; -+ format_count = data->win[win_num].formats_count[RGA_TILE4x4_INDEX]; -+ break; -+ case RGA_RKFBC_MODE: -+ formats = data->win[win_num].formats[RGA_RKFBC64x4_INDEX]; -+ format_count = data->win[win_num].formats_count[RGA_RKFBC64x4_INDEX]; -+ break; -+ case RGA_AFBC32x8_MODE: -+ formats = data->win[win_num].formats[RGA_AFBC32x8_INDEX]; -+ format_count = data->win[win_num].formats_count[RGA_AFBC32x8_INDEX]; -+ break; + default: + return false; + } @@ -1913345,8 +1911380,7 @@ index 000000000..2554f4bf6 + return false; +} + -+static bool rga_check_align(struct rga_job *job, -+ uint32_t byte_stride_align, uint32_t format, uint16_t w_stride) ++static bool rga_check_align(uint32_t byte_stride_align, uint32_t format, uint16_t w_stride) +{ + int bit_stride, pixel_stride, align, gcd; + @@ -1913362,77 +1911396,78 @@ index 000000000..2554f4bf6 + if (DEBUGGER_EN(MSG)) { + gcd = GET_GCD(pixel_stride, byte_stride_align * 8); + align = GET_LCM(pixel_stride, byte_stride_align * 8, gcd) / pixel_stride; -+ rga_job_log(job, "unsupported width stride %d, 0x%x should be %d aligned!", ++ pr_info("unsupported width stride %d, 0x%x should be %d aligned!", + w_stride, format, align); + } + + return false; +} + -+static bool rga_check_channel(struct rga_job *job, const struct rga_hw_data *data, -+ struct rga_img_info_t *img, -+ const char *name, int input, int swap, int win_num) ++static bool rga_check_src0(const struct rga_hw_data *data, ++ struct rga_img_info_t *src0) +{ -+ int w, h; -+ const struct rga_rect_range *range; ++ if (!rga_check_resolution(&data->input_range, src0->act_w, src0->act_h)) ++ return false; + -+ if (input) -+ range = &data->input_range; -+ else -+ range = &data->output_range; ++ if (data == &rga3_data && ++ !rga_check_resolution(&data->input_range, ++ src0->act_w + src0->x_offset, ++ src0->act_h + src0->y_offset)) ++ return false; + -+ if (swap) { -+ w = img->act_h; -+ h = img->act_w; -+ } else { -+ w = img->act_w; -+ h = img->act_h; -+ } ++ if (!rga_check_format(data, src0->rd_mode, src0->format, 0)) ++ return false; + -+ if (!rga_check_resolution(range, w, h)) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s resolution check error, input range[%dx%d ~ %dx%d], [w,h] = [%d, %d]\n", -+ name, -+ data->input_range.min.width, data->input_range.min.height, -+ data->input_range.max.width, data->input_range.max.height, -+ w, h); ++ if (!rga_check_align(data->byte_stride_align, src0->format, src0->vir_w)) ++ return false; ++ ++ return true; ++} + ++static bool rga_check_src1(const struct rga_hw_data *data, ++ struct rga_img_info_t *src1) ++{ ++ if (!rga_check_resolution(&data->input_range, src1->act_w, src1->act_h)) + return false; -+ } + + if (data == &rga3_data && + !rga_check_resolution(&data->input_range, -+ w + img->x_offset, -+ h + img->y_offset)) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s RGA3 resolution check error, input range[%dx%d ~ %dx%d], [w+x,h+y] = [%d, %d]\n", -+ name, -+ data->input_range.min.width, data->input_range.min.height, -+ data->input_range.max.width, data->input_range.max.height, -+ w + img->x_offset, -+ h + img->y_offset); ++ src1->act_w + src1->x_offset, ++ src1->act_h + src1->y_offset)) + return false; -+ } + -+ if (!rga_check_format(data, img->rd_mode, img->format, win_num)) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s format check error, mode = %#x, format = %#x\n", -+ name, img->rd_mode, img->format); ++ if (!rga_check_format(data, src1->rd_mode, src1->format, 1)) + return false; -+ } + -+ if (!rga_check_align(job, data->byte_stride_align, img->format, img->vir_w)) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s align check error, byte_stride_align[%d], format[%#x], vir_w[%d]\n", -+ name, data->byte_stride_align, img->format, img->vir_w); ++ if (!rga_check_align(data->byte_stride_align, src1->format, src1->vir_w)) ++ return false; ++ ++ return true; ++} ++ ++static bool rga_check_dst(const struct rga_hw_data *data, ++ struct rga_img_info_t *dst) ++{ ++ if (!rga_check_resolution(&data->output_range, dst->act_w, dst->act_h)) ++ return false; ++ ++ if (data == &rga3_data && ++ !rga_check_resolution(&data->output_range, ++ dst->act_w + dst->x_offset, ++ dst->act_h + dst->y_offset)) ++ return false; ++ ++ if (!rga_check_format(data, dst->rd_mode, dst->format, 2)) ++ return false; ++ ++ if (!rga_check_align(data->byte_stride_align, dst->format, dst->vir_w)) + return false; -+ } + + return true; +} + -+static bool rga_check_scale(struct rga_job *job, const struct rga_hw_data *data, -+ struct rga_req *rga_base) ++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; @@ -1913442,51 +1911477,30 @@ index 000000000..2554f4bf6 + + sw = src0->act_w; + sh = src0->act_h; -+ dw = dst->act_w; -+ dh = dst->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) -+ goto check_error; ++ return false; + } else if (sw < dw) { + if ((sw << data->max_upscale_factor) < dw) -+ goto check_error; ++ return false; + } + + if (sh > dh) { + if ((sh >> data->max_downscale_factor) > dh) -+ goto check_error; ++ return false; + } else if (sh < dh) { + if ((sh << data->max_upscale_factor) < dh) -+ goto check_error; -+ } -+ -+ return true; -+check_error: -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "scale check error, scale limit[1/%d ~ %d], src[%d, %d], dst[%d, %d]\n", -+ (1 << data->max_downscale_factor), (1 << data->max_upscale_factor), -+ sw, sh, dw, dh); -+ -+ return false; -+} -+ -+static bool rga_check_rotate(struct rga_job *job, const struct rga_hw_data *data, -+ struct rga_req *rga_base) -+{ -+ /* rot-90 and rot-270 */ -+ if (((rga_base->rotate_mode & 0x0f) == 1) && -+ ((rga_base->sina == 65536 && rga_base->cosa == 0) || -+ (rga_base->sina == -65536 && rga_base->cosa == 0))) { -+ if (data == &rga3_data && -+ (rga_is_yuv422_packed_format(rga_base->src.format) || -+ rga_is_yuv422_semi_planar_format(rga_base->src.format))) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "rotate check error, RGA3 unsupported YUV422 rotate 90/270, format[%s(%#x)]\n", -+ rga_get_format_name(rga_base->src.format), -+ rga_base->src.format); + return false; -+ } + } + + return true; @@ -1913509,13 +1911523,12 @@ index 000000000..2554f4bf6 + int i; + int min_of_job_count = -1; + unsigned long flags; -+ int need_swap = false; + + /* assigned by userspace */ + if (rga_base->core > RGA_NONE_CORE) { + if (rga_base->core > RGA_CORE_MASK) { -+ rga_job_err(job, "invalid setting core by user\n"); -+ return -1; ++ pr_err("invalid setting core by user\n"); ++ goto finish; + } else if (rga_base->core & RGA_CORE_MASK) + specified_cores = rga_base->core; + } @@ -1913532,134 +1911545,79 @@ index 000000000..2554f4bf6 + continue; + + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "start policy on %s(%#x)", -+ rga_get_core_name(scheduler->core), scheduler->core); ++ pr_info("start policy on core = %d", scheduler->core); + + if (scheduler->data->mmu == RGA_MMU && + job->flags & RGA_JOB_UNSUPPORT_RGA_MMU) { + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "RGA2 only support under 4G memory!\n"); ++ pr_info("RGA2 only support under 4G memory!\n"); + continue; + } + + if (feature > 0) { + if (!(feature & data->feature)) { + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), break on feature\n", -+ rga_get_core_name(scheduler->core), ++ pr_info("core = %d, break on feature", + scheduler->core); + continue; + } + } + -+ /* some mode rotate 90/270 need swap dst_width/dst_height */ -+ if (((rga_base->rotate_mode & 0x0f) == 1) && -+ ((rga_base->sina == 65536 && rga_base->cosa == 0) || -+ (rga_base->sina == -65536 && rga_base->cosa == 0))) { -+ need_swap = true; -+ } -+ + /* only colorfill need single win (colorpalette?) */ + if (!(feature & 1)) { + if (src1->yrgb_addr > 0) { -+ if (!(src0->rd_mode & data->win[0].rd_mode)) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), src0 break on %s(%#x)\n", -+ rga_get_core_name(scheduler->core), -+ scheduler->core, -+ rga_get_store_mode_str(src0->rd_mode), -+ src0->rd_mode); -+ continue; -+ } -+ -+ if (!(src1->rd_mode & data->win[1].rd_mode)) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), src1 break on %s(%#x)\n", -+ rga_get_core_name(scheduler->core), -+ scheduler->core, -+ rga_get_store_mode_str(src1->rd_mode), -+ src1->rd_mode); -+ continue; -+ } -+ -+ if (!(dst->rd_mode & data->win[2].rd_mode)) { ++ 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 (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), dst break on %s(%#x)\n", -+ rga_get_core_name(scheduler->core), -+ scheduler->core, -+ rga_get_store_mode_str(dst->rd_mode), -+ dst->rd_mode); ++ pr_info("core = %d, ABC break on rd_mode", ++ scheduler->core); + continue; + } + } else { -+ if (!(src0->rd_mode & data->win[0].rd_mode)) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), src break on %s(%#x)\n", -+ rga_get_core_name(scheduler->core), -+ scheduler->core, -+ rga_get_store_mode_str(src0->rd_mode), -+ src0->rd_mode); -+ continue; -+ } -+ -+ if (!(dst->rd_mode & data->win[2].rd_mode)) { ++ if ((!(src0->rd_mode & data->win[0].rd_mode)) || ++ (!(dst->rd_mode & data->win[2].rd_mode))) { + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), dst break on %s(%#x)\n", -+ rga_get_core_name(scheduler->core), -+ scheduler->core, -+ rga_get_store_mode_str(dst->rd_mode), -+ dst->rd_mode); ++ pr_info("core = %d, ABB break on rd_mode", ++ scheduler->core); + continue; + } + } + -+ if (!rga_check_scale(job, data, rga_base)) { ++ if (!rga_check_scale(data, rga_base)) { + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), break on rga_check_scale", -+ rga_get_core_name(scheduler->core), ++ pr_info("core = %d, break on rga_check_scale", + scheduler->core); + continue; + } + -+ if (!rga_check_channel(job, data, src0, "src0", true, false, 0)) { ++ if (!rga_check_src0(data, src0)) { + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), break on src0", -+ rga_get_core_name(scheduler->core), ++ pr_info("core = %d, break on rga_check_src0", + scheduler->core); + continue; + } + + if (src1->yrgb_addr > 0) { -+ if (!rga_check_channel(job, data, src1, "src1", true, false, 1)) { ++ if (!rga_check_src1(data, src1)) { + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), break on src1", -+ rga_get_core_name(scheduler->core), ++ pr_info("core = %d, break on rga_check_src1", + scheduler->core); + continue; + } + } + } + -+ if (!rga_check_channel(job, data, dst, "dst", false, need_swap, 2)) { ++ if (!rga_check_dst(data, dst)) { + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), break on dst", -+ rga_get_core_name(scheduler->core), ++ pr_info("core = %d, break on rga_check_dst", + scheduler->core); + continue; + } + + if (!rga_check_csc(data, rga_base)) { + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), break on rga_check_csc", -+ rga_get_core_name(scheduler->core), -+ scheduler->core); -+ continue; -+ } -+ -+ if (!rga_check_rotate(job, data, rga_base)) { -+ if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "%s(%#x), break on rga_check_rotate", -+ rga_get_core_name(scheduler->core), ++ pr_info("core = %d, break on rga_check_csc", + scheduler->core); + continue; + } @@ -1913667,9 +1911625,13 @@ index 000000000..2554f4bf6 + optional_cores |= scheduler->core; + } + ++ if (DEBUGGER_EN(MSG)) ++ pr_info("optional_cores = %d\n", optional_cores); ++ + if (optional_cores == 0) { -+ rga_job_err(job, "no core match\n"); -+ return -1; ++ core = -1; ++ pr_err("invalid function policy\n"); ++ goto finish; + } + + for (i = 0; i < rga_drvdata->num_of_scheduler; i++) { @@ -1913698,10 +1911660,9 @@ index 000000000..2554f4bf6 + } + + /* TODO: need consider full load */ ++finish: + if (DEBUGGER_EN(MSG)) -+ rga_job_log(job, "matched cores = %#x, assign core: %s(%#x)\n", -+ optional_cores, -+ rga_get_core_name(core), core); ++ pr_info("assign core: %d\n", core); + + return core; +} -- Gitee