Skip to content

Commit 113d77f

Browse files
author
Wei Dun
committed
media: rockchip: vpss: Fix FBC format output issue in offline mode
Signed-off-by: Wei Dun <[email protected]> Change-Id: Ife1b94330d20f16816cc1e5cdb8da6e98ce265b5
1 parent b526d36 commit 113d77f

File tree

1 file changed

+75
-39
lines changed

1 file changed

+75
-39
lines changed

drivers/media/platform/rockchip/vpss/vpss_offline_v20.c

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,8 @@ static int read_config(struct rkvpss_offline_dev *ofl,
837837
const struct vb2_mem_ops *mem_ops = hw->mem_ops;
838838
struct sg_table *sg_tbl;
839839
struct rkvpss_offline_buf *buf;
840-
u32 in_ctrl, in_size, in_c_offs, unite_r_offs, val, mask, unite_off = 0, enlarge = 0;
840+
u32 in_ctrl, in_size, in_c_offs, unite_r_offs, val, mask, unite_off = 0, enlarge = 0,
841+
header_size = 0, payload_size = 0;
841842

842843
in_c_offs = 0;
843844
in_ctrl = 0;
@@ -934,24 +935,33 @@ static int read_config(struct rkvpss_offline_dev *ofl,
934935
unite_off = 32;
935936
break;
936937
case V4L2_PIX_FMT_FBC0:
937-
if (cfg->input.stride < ALIGN(cfg->input.width, 16))
938-
cfg->input.stride = ALIGN(cfg->input.width, 16);
938+
cfg->input.stride = 0;
939939
in_c_offs = 0;
940-
in_size = cfg->input.stride * cfg->input.height * 3 / 2;
940+
header_size = ((cfg->input.width + 63) / 64) *
941+
((cfg->input.height + 3) / 4) * 16;
942+
payload_size = ((cfg->input.width + 63) / 64) * 384 *
943+
((cfg->input.height + 3) / 4);
944+
in_size = header_size + payload_size;
941945
in_ctrl |= RKVPSS_MI_RD_INPUT_420SP;
942946
break;
943947
case V4L2_PIX_FMT_FBC2:
944-
if (cfg->input.stride < ALIGN(cfg->input.width, 16))
945-
cfg->input.stride = ALIGN(cfg->input.width, 16);
948+
cfg->input.stride = 0;
946949
in_c_offs = 0;
947-
in_size = cfg->input.stride * cfg->input.height * 2;
950+
header_size = ((cfg->input.width + 63) / 64) *
951+
((cfg->input.height + 3) / 4) * 16;
952+
payload_size = ((cfg->input.width + 63) / 64) * 512 *
953+
((cfg->input.height + 3) / 4);
954+
in_size = header_size + payload_size;
948955
in_ctrl |= RKVPSS_MI_RD_INPUT_422SP;
949956
break;
950957
case V4L2_PIX_FMT_FBC4:
951-
if (cfg->input.stride < ALIGN(cfg->input.width, 16))
952-
cfg->input.stride = ALIGN(cfg->input.width, 16);
958+
cfg->input.stride = 0;
953959
in_c_offs = 0;
954-
in_size = cfg->input.stride * cfg->input.height * 3;
960+
header_size = ((cfg->input.width + 63) / 64) *
961+
((cfg->input.height + 3) / 4) * 16;
962+
payload_size = ((cfg->input.width + 63) / 64) * 768 *
963+
((cfg->input.height + 3) / 4);
964+
in_size = header_size + payload_size;
955965
in_ctrl |= RKVPSS_MI_RD_INPUT_422SP | RKVPSS_MI_RD_FBCD_YUV444_EN;
956966
break;
957967
case V4L2_PIX_FMT_TILE420:
@@ -1244,7 +1254,8 @@ static int write_config(struct rkvpss_offline_dev *ofl,
12441254
struct rkvpss_offline_buf *buf;
12451255
struct rkvpss_output_ch out_ch[RKVPSS_OUT_V20_MAX] = { 0 };
12461256
int i;
1247-
u32 w, h, val, reg, mask, mi_update, flip_en, unite_off = 0;
1257+
u32 w, h, val, reg, mask, mi_update, flip_en, unite_off = 0,
1258+
header_size = 0, payload_size = 0;
12481259
bool ch_en = false, wr_uv_swap = false;
12491260

12501261
for (i = 0; i < RKVPSS_OUT_V20_MAX; i++) {
@@ -1376,16 +1387,22 @@ static int write_config(struct rkvpss_offline_dev *ofl,
13761387
out_ch[i].c_offs = 0;
13771388
break;
13781389
case V4L2_PIX_FMT_FBC0:
1379-
if (cfg->output[i].stride < ALIGN(w, 16))
1380-
cfg->output[i].stride = ALIGN(w, 16);
1390+
cfg->output[i].stride = 0;
1391+
header_size = ((cfg->input.width + 63) / 64) *
1392+
((cfg->input.height + 3) / 4) * 16;
1393+
payload_size = ((cfg->input.width + 63) / 64) * 384 *
1394+
((cfg->input.height + 3) / 4);
13811395
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_YUV420;
1382-
out_ch[i].size = cfg->output[i].stride * h * 3 / 2;
1396+
out_ch[i].size = header_size + payload_size;
13831397
break;
13841398
case V4L2_PIX_FMT_FBC2:
1385-
if (cfg->output[i].stride < ALIGN(w, 16))
1386-
cfg->output[i].stride = ALIGN(w, 16);
1399+
cfg->input.stride = 0;
1400+
header_size = ((cfg->input.width + 63) / 64) *
1401+
((cfg->input.height + 3) / 4) * 16;
1402+
payload_size = ((cfg->input.width + 63) / 64) * 512 *
1403+
((cfg->input.height + 3) / 4);
13871404
out_ch[i].ctrl |= RKVPSS_MI_CHN_WR_OUTPUT_YUV422;
1388-
out_ch[i].size = cfg->output[i].stride * h * 2;
1405+
out_ch[i].size = header_size + payload_size;
13891406
break;
13901407
default:
13911408
v4l2_err(&ofl->v4l2_dev, "dev_id:%d no support output ch%d format:%c%c%c%c\n",
@@ -1435,44 +1452,63 @@ static int write_config(struct rkvpss_offline_dev *ofl,
14351452
if (cfg->output[i].format == V4L2_PIX_FMT_FBC0 ||
14361453
cfg->output[i].format == V4L2_PIX_FMT_FBC2) {
14371454
val = sg_dma_address(sg_tbl->sgl);
1455+
14381456
reg = RKVPSS_MI_CHN0_WR_CB_BASE;
14391457
rkvpss_hw_write(hw, reg + i * 0x100, val);
1440-
val += (ALIGN(w, 64) / 64) * (ALIGN(h, 4) / 4) * 16;
1458+
1459+
header_size = ((cfg->input.width + 63) / 64) *
1460+
((cfg->input.height + 3) / 4) * 16;
1461+
val += header_size;
14411462
reg = RKVPSS_MI_CHN0_WR_Y_BASE;
14421463
rkvpss_hw_write(hw, reg + i * 0x100, val);
14431464

1444-
cfg->output[i].stride = 0; //stride is 0
1465+
cfg->output[i].stride = 0;
1466+
reg = RKVPSS_MI_CHN0_WR_Y_STRIDE;
1467+
val = cfg->output[i].stride;
1468+
rkvpss_hw_write(hw, reg + i * 0x100, val);
1469+
1470+
reg = RKVPSS_MI_CHN0_WR_Y_SIZE;
1471+
if (cfg->output[i].format == V4L2_PIX_FMT_FBC0)
1472+
payload_size = ((cfg->input.width + 63) / 64) * 384 *
1473+
((cfg->input.height + 3) / 4);
1474+
else if (cfg->output[i].format == V4L2_PIX_FMT_FBC2)
1475+
payload_size = ((cfg->input.width + 63) / 64) * 512 *
1476+
((cfg->input.height + 3) / 4);
1477+
1478+
val = payload_size;
1479+
rkvpss_hw_write(hw, reg + i * 0x100, val);
1480+
1481+
reg = RKVPSS_MI_CHN0_WR_CB_SIZE;
1482+
val = header_size;
1483+
rkvpss_hw_write(hw, reg + i * 0x100, val);
14451484
} else {
14461485
val = sg_dma_address(sg_tbl->sgl) + unite_off;
14471486
reg = RKVPSS_MI_CHN0_WR_Y_BASE;
14481487
rkvpss_hw_write(hw, reg + i * 0x100, val);
14491488
reg = RKVPSS_MI_CHN0_WR_CB_BASE;
14501489
val += out_ch[i].c_offs;
14511490
rkvpss_hw_write(hw, reg + i * 0x100, val);
1452-
}
14531491

1454-
reg = RKVPSS_MI_CHN0_WR_Y_STRIDE;
1455-
val = cfg->output[i].stride;
1456-
rkvpss_hw_write(hw, reg + i * 0x100, val);
1457-
reg = RKVPSS_MI_CHN0_WR_Y_SIZE;
1492+
reg = RKVPSS_MI_CHN0_WR_Y_STRIDE;
1493+
val = cfg->output[i].stride;
1494+
rkvpss_hw_write(hw, reg + i * 0x100, val);
14581495

1459-
if (cfg->output[i].format == V4L2_PIX_FMT_TILE420 ||
1460-
cfg->output[i].format == V4L2_PIX_FMT_TILE422)
1461-
val = cfg->output[i].stride * (ALIGN(h, 4) / 4);
1462-
else if (cfg->output[i].format == V4L2_PIX_FMT_FBC0 ||
1463-
cfg->output[i].format == V4L2_PIX_FMT_FBC2)
1464-
val = 0x1f000000;
1465-
else
1466-
val = cfg->output[i].stride * h;
1496+
reg = RKVPSS_MI_CHN0_WR_Y_SIZE;
1497+
if (cfg->output[i].format == V4L2_PIX_FMT_TILE420 ||
1498+
cfg->output[i].format == V4L2_PIX_FMT_TILE422)
1499+
val = cfg->output[i].stride * (ALIGN(h, 4) / 4);
1500+
else
1501+
val = cfg->output[i].stride * h;
14671502

1468-
/* for wrap recalutate y_size*/
1469-
if (cfg->output[i].wrap.enable)
1470-
val = (val / h) * cfg->output[i].wrap.wrap_line;
1503+
/* for wrap recalutate y_size*/
1504+
if (cfg->output[i].wrap.enable)
1505+
val = (val / h) * cfg->output[i].wrap.wrap_line;
14711506

1472-
rkvpss_hw_write(hw, reg + i * 0x100, val);
1473-
reg = RKVPSS_MI_CHN0_WR_CB_SIZE;
1474-
val = out_ch[i].size - val;
1475-
rkvpss_hw_write(hw, reg + i * 0x100, val);
1507+
rkvpss_hw_write(hw, reg + i * 0x100, val);
1508+
reg = RKVPSS_MI_CHN0_WR_CB_SIZE;
1509+
val = out_ch[i].size - val;
1510+
rkvpss_hw_write(hw, reg + i * 0x100, val);
1511+
}
14761512

14771513
reg = RKVPSS_MI_CHN0_WR_CTRL;
14781514
val = out_ch[i].ctrl;

0 commit comments

Comments
 (0)