From b5a9acd89ff83b2d4d59af64966db539b7a4dbb4 Mon Sep 17 00:00:00 2001 From: pengcheng chen Date: Mon, 4 Jun 2018 18:10:25 +0800 Subject: [PATCH] viu2: add viu2 rotate PD#165090: viu2: add viu2 rotate Change-Id: Ib9804f7113a8da9fd97c653fcf367b46db5af778 Signed-off-by: pengcheng chen --- arch/arm64/boot/dts/amlogic/mesong12b.dtsi | 2 +- drivers/amlogic/media/osd/osd.h | 7 ++ drivers/amlogic/media/osd/osd_debug.c | 60 +++++++++--- drivers/amlogic/media/osd/osd_fb.c | 48 ++++++++- drivers/amlogic/media/osd/osd_hw.c | 109 ++++++++++++++++++++- drivers/amlogic/media/osd/osd_hw.h | 2 + drivers/amlogic/media/osd/osd_reg.h | 9 ++ 7 files changed, 217 insertions(+), 20 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/mesong12b.dtsi b/arch/arm64/boot/dts/amlogic/mesong12b.dtsi index b11a38449113..1f679f105aa4 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12b.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12b.dtsi @@ -1187,7 +1187,7 @@ vout2 { compatible = "amlogic, vout2"; dev_name = "vout"; - status = "disabled"; + status = "okay"; clocks = <&clkc CLKID_VPU_CLKC_P0_COMP>, <&clkc CLKID_VPU_CLKC_MUX>; clock-names = "vpu_clkc0", diff --git a/drivers/amlogic/media/osd/osd.h b/drivers/amlogic/media/osd/osd.h index ebaa105d242f..48844e9acb56 100644 --- a/drivers/amlogic/media/osd/osd.h +++ b/drivers/amlogic/media/osd/osd.h @@ -339,6 +339,12 @@ enum afbc_pix_format_e { RGBA1010102, }; +enum viu2_rotate_format { + YUV422 = 4, + RGB = 6, + RGBA = 8, +}; + struct pandata_s { s32 x_start; s32 x_end; @@ -673,6 +679,7 @@ struct hw_para_s { u32 free_scale_mode[HW_OSD_COUNT]; u32 free_scale_mode_backup[HW_OSD_COUNT]; u32 osd_reverse[HW_OSD_COUNT]; + u32 osd_rotate[HW_OSD_COUNT]; /* struct osd_rotate_s rotate[HW_OSD_COUNT]; */ int use_h_filter_mode[HW_OSD_COUNT]; int use_v_filter_mode[HW_OSD_COUNT]; diff --git a/drivers/amlogic/media/osd/osd_debug.c b/drivers/amlogic/media/osd/osd_debug.c index ceec4aeeadb6..d52da8a01650 100644 --- a/drivers/amlogic/media/osd/osd_debug.c +++ b/drivers/amlogic/media/osd/osd_debug.c @@ -299,47 +299,81 @@ static void osd_debug_dump_register_all(void) if ((osd_hw.osd_meson_dev.afbc_type == MALI_AFBC) && (osd_hw.osd_afbcd[index].enable)) { reg = osd_reg->afbc_header_buf_addr_low_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_header_buf_addr_high_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_format_specifier_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_buffer_width_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_buffer_hight_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_boundings_box_x_start_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_boundings_box_x_end_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_boundings_box_y_start_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_boundings_box_y_end_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_output_buf_addr_low_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_output_buf_addr_high_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_output_buf_stride_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); reg = osd_reg->afbc_prefetch_cfg_s; - osd_log_info("reg[0x%x]: 0x%08x\n\n", + osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg)); } } + if (osd_hw.osd_meson_dev.cpu_id >= __MESON_CPU_MAJOR_ID_G12B) { + if (osd_hw.osd_meson_dev.has_viu2) { + reg = VPP2_MISC; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VPU_VIU_VENC_MUX_CTRL; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VIU2_RMIF_CTRL1; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VIU2_RMIF_SCOPE_X; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VIU2_RMIF_SCOPE_Y; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VIU2_ROT_BLK_SIZE; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VIU2_ROT_LBUF_SIZE; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VIU2_ROT_FMT_CTRL; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VIU2_ROT_OUT_VCROP; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + reg = VPP2_OFIFO_SIZE; + osd_log_info("reg[0x%x]: 0x%08x\n", + reg, osd_reg_read(reg)); + } + } if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) { reg = VIU_MISC_CTRL1; osd_log_info("reg[0x%x]: 0x%08x\n", diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index 68d0e060c9e3..744ecd559276 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -653,10 +653,18 @@ static int osd_set_par(struct fb_info *info) struct osd_ctl_s *osd_ctrl = &fbdev->osd_ctl; u32 virt_end_x, virt_end_y; - vinfo = get_current_vinfo(); - if (!vinfo) { - osd_log_err("current vinfo NULL\n"); - return -1; + if (fbdev->fb_index <= OSD3) { + vinfo = get_current_vinfo(); + if (!vinfo) { + osd_log_err("current vinfo NULL\n"); + return -1; + } + } else { + vinfo = get_current_vinfo2(); + if (!vinfo) { + osd_log_err("current vinfo NULL\n"); + return -1; + } } virt_end_x = osd_ctrl->disp_start_x + info->var.xres; virt_end_y = osd_ctrl->disp_start_y + info->var.yres; @@ -2862,6 +2870,34 @@ static ssize_t store_osd_single_step(struct device *device, return count; } +static ssize_t show_osd_rotate( + struct device *device, struct device_attribute *attr, + char *buf) +{ + struct fb_info *fb_info = dev_get_drvdata(device); + u32 rotate; + + osd_get_rotate(fb_info->node, &rotate); + + return snprintf(buf, PAGE_SIZE, "%d\n", rotate); +} + +static ssize_t store_osd_rotate( + struct device *device, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fb_info = dev_get_drvdata(device); + int res = 0; + int ret = 0; + + ret = kstrtoint(buf, 0, &res); + if (ret < 0) + return -EINVAL; + + osd_set_rotate(fb_info->node, res); + return count; +} + static inline int str2lower(char *str) { while (*str != '\0') { @@ -3112,6 +3148,8 @@ static struct device_attribute osd_attrs_viu2[] = { show_osd_afbc_debug, store_osd_afbc_debug), __ATTR(osd_afbc_format, 0644, show_osd_afbc_format, store_osd_afbc_format), + __ATTR(osd_rotate, 0644, + show_osd_rotate, store_osd_rotate), }; #ifdef CONFIG_PM @@ -3481,7 +3519,7 @@ static int osd_probe(struct platform_device *pdev) goto failed1; } else osd_log_info("viu vsync irq: %d\n", int_viu_vsync); - if (osd_hw.osd_meson_dev.has_viu2) { + if (osd_meson_dev.has_viu2) { int_viu2_vsync = platform_get_irq_byname(pdev, "viu2-vsync"); if (int_viu2_vsync == -ENXIO) { osd_log_err("cannot get viu2 irq resource\n"); diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index f979fe23bb88..14eaa7a7b6fd 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -660,6 +660,8 @@ static void osd_vpu_power_on_viu2(void) VPU_MEM_POWER_ON); switch_vpu_mem_pd_vmod(VPU_VIU2_OFIFO, VPU_MEM_POWER_ON); + switch_vpu_mem_pd_vmod(VPU_VIU2_OSD_ROT, + VPU_MEM_POWER_ON); val = osd_reg_read(VPU_CLK_GATE); val = val | 0x30000; osd_reg_write(VPU_CLK_GATE, val); @@ -2922,6 +2924,20 @@ void osd_set_single_step(u32 osd_single_step) } } +void osd_get_rotate(u32 index, u32 *osd_rotate) +{ + *osd_rotate = osd_hw.osd_rotate[index]; +} + +void osd_set_rotate(u32 index, u32 osd_rotate) +{ + if (index != OSD4) + osd_log_err("osd%d not support rotate\n", index); + osd_hw.osd_rotate[index] = osd_rotate; + add_to_update_list(index, DISP_OSD_ROTATE); + osd_wait_vsync_hw(); +} + int osd_get_capbility(u32 index) { u32 capbility = 0; @@ -4428,6 +4444,98 @@ static void osd_update_disp_osd_reverse(u32 index) static void osd_update_disp_osd_rotate(u32 index) { + u32 rotate_en = osd_hw.osd_rotate[index]; + u32 src_fmt = RGBA; + u32 x_start, x_end, y_start, y_end; + u32 src_width, src_height; + u32 rot_hsize, blk_vsize, rd_blk_hsize; + u32 reg_fmt_buf_en, reg_fmt_444_mode, line5_mode; + u32 y_reverse = 0, x_reverse = 0; + u32 data32; + enum color_index_e idx; + struct dispdata_s src_data; + const struct vinfo_s *vinfo; + int out_y_crop_start, out_y_crop_end; + + if (osd_hw.osd_meson_dev.cpu_id < __MESON_CPU_MAJOR_ID_G12B) + return; + src_data.x = 0; + src_data.y = 0; + src_data.w = osd_hw.fb_gem[index].xres; + src_data.h = osd_hw.fb_gem[index].yres; + vinfo = get_current_vinfo2(); + if (!vinfo) { + osd_log_err("current vinfo NULL\n"); + return; + } + out_y_crop_start = 0; + out_y_crop_end = vinfo->height; + src_width = src_data.w; + src_height = src_data.h; + + x_start = src_data.x; + x_end = src_data.x + src_data.w - 1; + y_start = src_data.y; + y_end = src_data.y + src_data.h - 1; + /* x/y start end can be crop axis */ + switch (src_fmt) { + case YUV422: + blk_vsize = 30; + rd_blk_hsize = 32; + reg_fmt_buf_en = 1; + reg_fmt_444_mode = 0; + line5_mode = 1; + break; + case RGB: + blk_vsize = 20; + rd_blk_hsize = 22; + reg_fmt_buf_en = 0; + reg_fmt_444_mode = 1; + line5_mode = 0; + break; + case RGBA: + blk_vsize = 15; + rd_blk_hsize = 16; + reg_fmt_buf_en = 0; + reg_fmt_444_mode = 1; + line5_mode = 0; + break; + } + osd_reg_set_bits(VPP2_MISC, rotate_en, 16, 1); + rotate_en = 0; + osd_reg_set_bits(VPU_VIU_VENC_MUX_CTRL, + rotate_en, 20, 1); + idx = osd_hw.color_info[index]->color_index; + data32 = (osd_hw.fb_gem[index].canvas_idx << 16) | + (2 << 8) | (1 << 7) | (0 << 6) | + (y_reverse << 5) | + (x_reverse << 4) | src_fmt; + osd_reg_set_bits(VIU2_RMIF_CTRL1, data32, 0, 32); + osd_reg_set_bits(VIU2_RMIF_SCOPE_X, + x_end << 16 | x_start, 0, 32); + osd_reg_set_bits(VIU2_RMIF_SCOPE_Y, + y_end << 16 | y_start, 0, 32); + + rot_hsize = (src_height + blk_vsize - 1) / blk_vsize; + osd_reg_set_bits( + VIU2_ROT_BLK_SIZE, + rd_blk_hsize | (blk_vsize << 8), 0, 32); + osd_reg_set_bits( + VIU2_ROT_LBUF_SIZE, + rot_hsize * rd_blk_hsize | + (rot_hsize << 16), 0, 32); + osd_reg_set_bits( + VIU2_ROT_FMT_CTRL, + reg_fmt_buf_en | + (line5_mode << 1) | + (reg_fmt_444_mode << 2) | + (180 << 8) | (0xe4 << 24), 0, 32); + osd_reg_set_bits(VIU2_ROT_OUT_VCROP, + out_y_crop_end | + out_y_crop_start << 16, 0, 32); + osd_reg_set_bits( + VPP2_OFIFO_SIZE, + src_height - 1, 20, 12); remove_from_update_list(index, DISP_OSD_ROTATE); } @@ -7231,7 +7339,6 @@ void osd_init_hw(u32 logo_loaded, u32 osd_probe, hw_osd_reg_array[OSD1].osd_fifo_ctrl_stat, data32); } osd_set_deband(osd_hw.osd_deband_enable); - /* memset(osd_hw.rotate, 0, sizeof(struct osd_rotate_s)); */ if (osd_hw.fb_drvier_probe) { #ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE INIT_LIST_HEAD(&post_fence_list); diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index 60d6dbd202a7..a0fcfba66a97 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -198,4 +198,6 @@ void osd_get_urgent_info(u32 *ports, u32 *basic_urgent); void osd_set_single_step_mode(u32 osd_single_step_mode); void osd_set_single_step(u32 osd_single_step); void output_save_info(void); +void osd_get_rotate(u32 index, u32 *osd_rotate); +void osd_set_rotate(u32 index, u32 osd_rotate); #endif diff --git a/drivers/amlogic/media/osd/osd_reg.h b/drivers/amlogic/media/osd/osd_reg.h index ac92bf0ef894..5941fe8f1b64 100644 --- a/drivers/amlogic/media/osd/osd_reg.h +++ b/drivers/amlogic/media/osd/osd_reg.h @@ -469,6 +469,15 @@ #define VIU2_OSD1_MALI_UNPACK_CTRL 0x1e4f #define VIU2_OSD1_DIMM_CTRL 0x1e50 #define VIU2_OSD1_UNSUPPORT VIU_OSD2_TCOLOR_AG3 +/* viu2 rotate */ +#define VIU2_RMIF_CTRL1 0x1e81 +#define VIU2_RMIF_SCOPE_X 0x1e83 +#define VIU2_RMIF_SCOPE_Y 0x1e84 +#define VIU2_ROT_BLK_SIZE 0x1e85 +#define VIU2_ROT_LBUF_SIZE 0x1e86 +#define VIU2_ROT_FMT_CTRL 0x1e87 +#define VIU2_ROT_OUT_VCROP 0x1e89 + /* encode */ #define ENCP_VFIFO2VD_CTL 0x1b58 #define ENCP_VFIFO2VD_PIXEL_START 0x1b59 -- 2.20.1