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",
RGBA1010102,
};
+enum viu2_rotate_format {
+ YUV422 = 4,
+ RGB = 6,
+ RGBA = 8,
+};
+
struct pandata_s {
s32 x_start;
s32 x_end;
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];
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",
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;
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') {
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
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");
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);
}
}
+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;
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);
}
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);
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
#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