mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
viu2: add viu2 rotate
PD#165090: viu2: add viu2 rotate Change-Id: Ib9804f7113a8da9fd97c653fcf367b46db5af778 Signed-off-by: pengcheng chen <pengcheng.chen@amlogic.com>
This commit is contained in:
committed by
Yixun Lan
parent
13344233a2
commit
b5a9acd89f
@@ -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",
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user