mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
video: rockchip: rga3: fix bi-linear scaled down causing timeout
Adjust config based on RGA2 limit. Update driver version to 1.3.7 Signed-off-by: Yu Qiaowei <cerf.yu@rock-chips.com> Change-Id: I2954dbb36a1698e34da14fff33fb9d97792478da
This commit is contained in:
@@ -292,11 +292,15 @@
|
||||
|
||||
|
||||
/* RGA_SRC_ACT_INFO */
|
||||
#define m_RGA2_SRC_ACT_INFO_SW_SRC_ACT_WIDTH (0x1fff << 0)
|
||||
#define m_RGA2_SRC_ACT_INFO_SW_SRC_ACT_HEIGHT (0x1fff << 16)
|
||||
#define 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 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)
|
||||
#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)
|
||||
|
||||
/* RGA2_OSD_CTRL0 */
|
||||
#define m_RGA2_OSD_CTRL0_SW_OSD_MODE (0x3 << 0)
|
||||
@@ -480,6 +484,7 @@
|
||||
#define s_RGA2_MMU_CTRL1_SW_ELS_MMU_FLUSH(x) ((x & 0x1) << 13)
|
||||
|
||||
#define RGA2_VSP_BICUBIC_LIMIT 1996
|
||||
#define RGA2_BILINEAR_PREC 12
|
||||
|
||||
union rga2_color_ctrl {
|
||||
uint32_t value;
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
#define DRIVER_MAJOR_VERISON 1
|
||||
#define DRIVER_MINOR_VERSION 3
|
||||
#define DRIVER_REVISION_VERSION 6
|
||||
#define DRIVER_REVISION_VERSION 7
|
||||
#define DRIVER_PATCH_VERSION
|
||||
|
||||
#define DRIVER_VERSION (STR(DRIVER_MAJOR_VERISON) "." STR(DRIVER_MINOR_VERSION) \
|
||||
|
||||
@@ -101,17 +101,52 @@ unsigned int rga2_rop_code[256] = {
|
||||
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 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)) {
|
||||
@@ -128,10 +163,24 @@ static void RGA2_reg_get_param(unsigned char *base, struct rga2_req *msg)
|
||||
if (sw > dw) {
|
||||
if (msg->interp.horiz == RGA_INTERP_LINEAR) {
|
||||
/* default to half_pixel mode. */
|
||||
param_x = (sw << 12) / dw;
|
||||
scale_x_offset = 0x1ff;
|
||||
param_x = (sw << RGA2_BILINEAR_PREC) / dw;
|
||||
scale_x_offset = (1 << RGA2_BILINEAR_PREC) >> 1;
|
||||
|
||||
*bRGA_SRC_X_FACTOR = ((param_x & 0xffff) | ((scale_x_offset) << 16));
|
||||
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 / 2)) / sw;
|
||||
|
||||
@@ -151,10 +200,24 @@ static void RGA2_reg_get_param(unsigned char *base, struct rga2_req *msg)
|
||||
if (sh > dh) {
|
||||
if (msg->interp.verti == RGA_INTERP_LINEAR) {
|
||||
/* default to half_pixel mode. */
|
||||
param_y = (sh << 12) / dh;
|
||||
scale_y_offset = 0x1ff;
|
||||
param_y = (sh << RGA2_BILINEAR_PREC) / dh;
|
||||
scale_y_offset = (1 << RGA2_BILINEAR_PREC) >> 1;
|
||||
|
||||
*bRGA_SRC_Y_FACTOR = ((param_y & 0xffff) | ((scale_y_offset) << 16));
|
||||
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 / 2)) / sh;
|
||||
|
||||
@@ -363,10 +426,6 @@ static void RGA2_set_reg_src_info(u8 *base, struct rga2_req *msg)
|
||||
vsd_scale_mode = 0;
|
||||
break;
|
||||
case RGA_INTERP_LINEAR:
|
||||
if (sh > 4096)
|
||||
/* force select average */
|
||||
vsd_scale_mode = 0;
|
||||
else
|
||||
vsd_scale_mode = 1;
|
||||
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user