From 6ec967cecfdde4abad1ee4492fc4c7ccacc434d7 Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Tue, 29 Apr 2025 17:56:55 +0800 Subject: [PATCH] video: rockchip: rga3: RGA3 support RGBX/BGRX8888 Change-Id: I93a403d5dd94a44e267692a3542a938a2aaacf8d Signed-off-by: Yu Qiaowei --- drivers/video/rockchip/rga3/include/rga.h | 8 +-- drivers/video/rockchip/rga3/rga3_reg_info.c | 77 +++++++++++---------- drivers/video/rockchip/rga3/rga_hw_config.c | 6 ++ 3 files changed, 50 insertions(+), 41 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga.h b/drivers/video/rockchip/rga3/include/rga.h index b0ffc217381f..671867b22371 100644 --- a/drivers/video/rockchip/rga3/include/rga.h +++ b/drivers/video/rockchip/rga3/include/rga.h @@ -923,7 +923,8 @@ struct rga3_req { struct rga_alpha_config alpha_config; /* for abb mode presever alpha. */ - bool abb_alpha_pass; + bool bg_alpha_pass; + bool fg_alpha_pass; u8 scale_bicu_mode; @@ -941,11 +942,6 @@ struct rga3_req { 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; diff --git a/drivers/video/rockchip/rga3/rga3_reg_info.c b/drivers/video/rockchip/rga3/rga3_reg_info.c index 8c68cb8863dd..c0ce4a3ff4f1 100644 --- a/drivers/video/rockchip/rga3/rga3_reg_info.c +++ b/drivers/video/rockchip/rga3/rga3_reg_info.c @@ -143,11 +143,13 @@ static void RGA3_set_reg_win0_info(u8 *base, struct rga3_req *msg) 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; @@ -526,11 +528,13 @@ static void RGA3_set_reg_win1_info(u8 *base, struct rga3_req *msg) 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; @@ -817,12 +821,14 @@ static void RGA3_set_reg_wr_info(u8 *base, struct rga3_req *msg) 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; @@ -1244,21 +1250,25 @@ static void RGA3_set_reg_overlap_info(u8 *base, struct rga3_req *msg) break; } - if (!config->enable && msg->abb_alpha_pass) { + if (!config->enable) { /* * 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). */ - top_color_ctrl.bits.color_mode = RGA_ALPHA_PRE_MULTIPLIED; + if (msg->fg_alpha_pass) { + 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; + } - bottom_color_ctrl.bits.color_mode = RGA_ALPHA_PRE_MULTIPLIED; + if (msg->bg_alpha_pass) { + 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 ? @@ -1467,18 +1477,6 @@ static void rga_cmd_to_rga3_cmd(struct rga_req *req_rga, struct rga3_req *req) 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) && @@ -1489,14 +1487,6 @@ static void rga_cmd_to_rga3_cmd(struct rga_req *req_rga, struct rga3_req *req) * 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 */ @@ -1519,14 +1509,6 @@ static void rga_cmd_to_rga3_cmd(struct rga_req *req_rga, struct rga3_req *req) * 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. */ @@ -1666,6 +1648,31 @@ static void rga_cmd_to_rga3_cmd(struct rga_req *req_rga, struct rga3_req *req) 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 */ diff --git a/drivers/video/rockchip/rga3/rga_hw_config.c b/drivers/video/rockchip/rga3/rga_hw_config.c index 08621fde6574..d558c1513501 100644 --- a/drivers/video/rockchip/rga3/rga_hw_config.c +++ b/drivers/video/rockchip/rga3/rga_hw_config.c @@ -14,6 +14,8 @@ 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, @@ -37,6 +39,8 @@ const uint32_t rga3_input_raster_format[] = { 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, @@ -58,6 +62,8 @@ const uint32_t rga3_output_raster_format[] = { 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,