#include "osd_hw_def.h"
#include "osd_fb.h"
-#define OSD_BLEND_SHIFT_WORKAROUND
#ifdef CONFIG_AMLOGIC_VSYNC_FIQ_ENABLE
#define FIQ_VSYNC
#endif
#define osd_tprintk(...)
-#define OSD_CALC 14
#define FREE_SCALE_MAX_WIDTH 1920
struct hw_para_s osd_hw;
static DEFINE_MUTEX(osd_mutex);
static int ext_canvas_id[HW_OSD_COUNT];
static int osd_extra_idx[HW_OSD_COUNT][2];
static bool suspend_flag;
-
+static u32 rdma_dt_cnt;
static void osd_clone_pan(u32 index, u32 yoffset, int debug_flag);
static void osd_set_dummy_data(u32 index, u32 alpha);
-struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT] = {
+struct hw_osd_reg_s hw_osd_reg_array[HW_OSD_COUNT];
+
+struct hw_osd_reg_s hw_osd_reg_array_g12a[HW_OSD_COUNT] = {
{
VIU_OSD1_CTRL_STAT,
VIU_OSD1_CTRL_STAT2,
VIU_OSD1_PROT_CTRL,
VIU_OSD1_MALI_UNPACK_CTRL,
VIU_OSD1_DIMM_CTRL,
- //VIU_OSD_BLEND_DIN0_SCOPE_H,
- //VIU_OSD_BLEND_DIN0_SCOPE_V,
VPP_OSD_SCALE_COEF_IDX,
VPP_OSD_SCALE_COEF,
VIU_OSD2_PROT_CTRL,
VIU_OSD2_MALI_UNPACK_CTRL,
VIU_OSD2_DIMM_CTRL,
- //VIU_OSD_BLEND_DIN2_SCOPE_H,
- //VIU_OSD_BLEND_DIN2_SCOPE_V,
OSD2_SCALE_COEF_IDX,
OSD2_SCALE_COEF,
VIU_OSD3_PROT_CTRL,
VIU_OSD3_MALI_UNPACK_CTRL,
VIU_OSD3_DIMM_CTRL,
- //VIU_OSD_BLEND_DIN3_SCOPE_H,
- //VIU_OSD_BLEND_DIN3_SCOPE_V,
OSD34_SCALE_COEF_IDX,
OSD34_SCALE_COEF,
VIU2_OSD1_UNSUPPORT,
}
};
+
+struct hw_osd_reg_s hw_osd_reg_array_tl1[HW_OSD_COUNT] = {
+ {
+ VIU_OSD1_CTRL_STAT,
+ VIU_OSD1_CTRL_STAT2,
+ VIU_OSD1_COLOR_ADDR,
+ VIU_OSD1_COLOR,
+ VIU_OSD1_TCOLOR_AG0,
+ VIU_OSD1_TCOLOR_AG1,
+ VIU_OSD1_TCOLOR_AG2,
+ VIU_OSD1_TCOLOR_AG3,
+ VIU_OSD1_BLK0_CFG_W0,
+ VIU_OSD1_BLK0_CFG_W1,
+ VIU_OSD1_BLK0_CFG_W2,
+ VIU_OSD1_BLK0_CFG_W3,
+ VIU_OSD1_BLK0_CFG_W4,
+ VIU_OSD1_BLK1_CFG_W4,
+ VIU_OSD1_BLK2_CFG_W4,
+ VIU_OSD1_FIFO_CTRL_STAT,
+ VIU_OSD1_TEST_RDDATA,
+ VIU_OSD1_PROT_CTRL,
+ VIU_OSD1_MALI_UNPACK_CTRL,
+ VIU_OSD1_DIMM_CTRL,
+
+ VPP_OSD_SCALE_COEF_IDX,
+ VPP_OSD_SCALE_COEF,
+ VPP_OSD_VSC_PHASE_STEP,
+ VPP_OSD_VSC_INI_PHASE,
+ VPP_OSD_VSC_CTRL0,
+ VPP_OSD_HSC_PHASE_STEP,
+ VPP_OSD_HSC_INI_PHASE,
+ VPP_OSD_HSC_CTRL0,
+ VPP_OSD_SC_DUMMY_DATA,
+ VPP_OSD_SC_CTRL0,
+ VPP_OSD_SCI_WH_M1,
+ VPP_OSD_SCO_H_START_END,
+ VPP_OSD_SCO_V_START_END,
+ VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0,
+ VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0,
+ VPU_MAFBC_FORMAT_SPECIFIER_S0,
+ VPU_MAFBC_BUFFER_WIDTH_S0,
+ VPU_MAFBC_BUFFER_HEIGHT_S0,
+ VPU_MAFBC_BOUNDING_BOX_X_START_S0,
+ VPU_MAFBC_BOUNDING_BOX_X_END_S0,
+ VPU_MAFBC_BOUNDING_BOX_Y_START_S0,
+ VPU_MAFBC_BOUNDING_BOX_Y_END_S0,
+ VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S0,
+ VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S0,
+ VPU_MAFBC_OUTPUT_BUF_STRIDE_S0,
+ VPU_MAFBC_PREFETCH_CFG_S0,
+
+
+ },
+ {
+ VIU_OSD2_CTRL_STAT,
+ VIU_OSD2_CTRL_STAT2,
+ VIU_OSD2_COLOR_ADDR,
+ VIU_OSD2_COLOR,
+ VIU_OSD2_TCOLOR_AG0,
+ VIU_OSD2_TCOLOR_AG1,
+ VIU_OSD2_TCOLOR_AG2,
+ VIU_OSD2_TCOLOR_AG3,
+ VIU_OSD2_BLK0_CFG_W0,
+ VIU_OSD2_BLK0_CFG_W1,
+ VIU_OSD2_BLK0_CFG_W2,
+ VIU_OSD2_BLK0_CFG_W3,
+ VIU_OSD2_BLK0_CFG_W4,
+ VIU_OSD2_BLK1_CFG_W4,
+ VIU_OSD2_BLK2_CFG_W4,
+ VIU_OSD2_FIFO_CTRL_STAT,
+ VIU_OSD2_TEST_RDDATA,
+ VIU_OSD2_PROT_CTRL,
+ VIU_OSD2_MALI_UNPACK_CTRL,
+ VIU_OSD2_DIMM_CTRL,
+
+ OSD2_SCALE_COEF_IDX,
+ OSD2_SCALE_COEF,
+ OSD2_VSC_PHASE_STEP,
+ OSD2_VSC_INI_PHASE,
+ OSD2_VSC_CTRL0,
+ OSD2_HSC_PHASE_STEP,
+ OSD2_HSC_INI_PHASE,
+ OSD2_HSC_CTRL0,
+ OSD2_SC_DUMMY_DATA,
+ OSD2_SC_CTRL0,
+ OSD2_SCI_WH_M1,
+ OSD2_SCO_H_START_END,
+ OSD2_SCO_V_START_END,
+ VPU_MAFBC_HEADER_BUF_ADDR_LOW_S1,
+ VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S1,
+ VPU_MAFBC_FORMAT_SPECIFIER_S1,
+ VPU_MAFBC_BUFFER_WIDTH_S1,
+ VPU_MAFBC_BUFFER_HEIGHT_S1,
+ VPU_MAFBC_BOUNDING_BOX_X_START_S1,
+ VPU_MAFBC_BOUNDING_BOX_X_END_S1,
+ VPU_MAFBC_BOUNDING_BOX_Y_START_S1,
+ VPU_MAFBC_BOUNDING_BOX_Y_END_S1,
+ VPU_MAFBC_OUTPUT_BUF_ADDR_LOW_S1,
+ VPU_MAFBC_OUTPUT_BUF_ADDR_HIGH_S1,
+ VPU_MAFBC_OUTPUT_BUF_STRIDE_S1,
+ VPU_MAFBC_PREFETCH_CFG_S1,
+
+ },
+ {
+ VIU2_OSD1_CTRL_STAT,
+ VIU2_OSD1_CTRL_STAT2,
+ VIU2_OSD1_COLOR_ADDR,
+ VIU2_OSD1_COLOR,
+ VIU2_OSD1_TCOLOR_AG0,
+ VIU2_OSD1_TCOLOR_AG1,
+ VIU2_OSD1_TCOLOR_AG2,
+ VIU2_OSD1_TCOLOR_AG3,
+ VIU2_OSD1_BLK0_CFG_W0,
+ VIU2_OSD1_BLK0_CFG_W1,
+ VIU2_OSD1_BLK0_CFG_W2,
+ VIU2_OSD1_BLK0_CFG_W3,
+ VIU2_OSD1_BLK0_CFG_W4,
+ VIU2_OSD1_BLK1_CFG_W4,
+ VIU2_OSD1_BLK2_CFG_W4,
+ VIU2_OSD1_FIFO_CTRL_STAT,
+ VIU2_OSD1_TEST_RDDATA,
+ VIU2_OSD1_PROT_CTRL,
+ VIU2_OSD1_MALI_UNPACK_CTRL,
+ VIU2_OSD1_DIMM_CTRL,
+
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ VIU2_OSD1_UNSUPPORT,
+ }
+};
+
static int osd_setting_blending_scope(u32 index);
static int vpp_blend_setting_default(u32 index);
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
/* sync fence relative varible. */
-static int timeline_created;
-static void *osd_timeline;
-static u32 cur_streamline_val;
+static int timeline_created[VIU_COUNT];
+static void *osd_timeline[VIU_COUNT];
+static u32 cur_streamline_val[VIU_COUNT];
/* thread control part */
-struct kthread_worker buffer_toggle_worker;
-struct task_struct *buffer_toggle_thread;
-struct kthread_work buffer_toggle_work;
-struct list_head post_fence_list;
-struct mutex post_fence_list_lock;
-struct osd_layers_fence_map_s map_layers;
+struct kthread_worker buffer_toggle_worker[VIU_COUNT];
+struct task_struct *buffer_toggle_thread[VIU_COUNT];
+struct kthread_work buffer_toggle_work[VIU_COUNT];
+struct list_head post_fence_list[VIU_COUNT];
+struct mutex post_fence_list_lock[VIU_COUNT]; /*post fence mutex*/
+struct osd_layers_fence_map_s map_layers[VIU_COUNT];
struct file *displayed_bufs[HW_OSD_COUNT];
static void osd_pan_display_single_fence(
struct osd_fence_map_s *fence_map);
static void osd_pan_display_layers_fence(
struct osd_layers_fence_map_s *fence_map);
+static void osd_pan_display_single_fence_viu2(
+ struct osd_fence_map_s *fence_map);
+static void osd_pan_display_layers_fence_viu2(
+ struct osd_layers_fence_map_s *fence_map);
-static void *osd_timeline_create(void)
+static void *osd_timeline_create(u32 output_index)
{
- const char *tlName = "osd_timeline";
+ char tlname[32] = {};
- if (osd_timeline == NULL) {
- if (osd_hw.hwc_enable)
+ sprintf(tlname, "osd_timeline_%d", output_index);
+ if (!osd_timeline[output_index]) {
+ if (osd_hw.hwc_enable[output_index])
/* present fence */
- cur_streamline_val = 0;
+ cur_streamline_val[output_index] = 0;
else
- cur_streamline_val = 1;
- osd_timeline = aml_sync_create_timeline(tlName);
+ cur_streamline_val[output_index] = 1;
+ osd_timeline[output_index] = aml_sync_create_timeline(tlname);
osd_tprintk("osd timeline create\n");
}
-
- return osd_timeline;
+ return osd_timeline[output_index];
}
-static int osd_timeline_create_fence(void)
+static int osd_timeline_create_fence(u32 output_index)
{
int out_fence_fd = -1;
u32 pt_val = 0;
- pt_val = cur_streamline_val + 1;
- out_fence_fd = aml_sync_create_fence(osd_timeline, pt_val);
+ pt_val = cur_streamline_val[output_index] + 1;
+ out_fence_fd = aml_sync_create_fence
+ (osd_timeline[output_index], pt_val);
osd_tprintk("osd created out pt:%d, fence_fd:%d\n",
pt_val, out_fence_fd);
if (out_fence_fd >= 0)
- cur_streamline_val++;
+ cur_streamline_val[output_index]++;
else
pr_info("create fence returned %d", out_fence_fd);
return out_fence_fd;
}
-static void osd_timeline_increase(void)
+static void osd_timeline_increase(u32 output_index)
{
- aml_sync_inc_timeline(osd_timeline, 1);
- osd_tprintk("osd out timeline inc\n");
+ aml_sync_inc_timeline(osd_timeline[output_index], 1);
+ osd_tprintk("osd out timeline %d inc\n", output_index);
+
}
static struct fence *osd_get_fenceobj(int fencefd)
static int vsync_enter_line_max;
static int vsync_exit_line_max;
static int vsync_line_threshold = 950;
+static int line_threshold = 90;
MODULE_PARM_DESC(vsync_enter_line_max, "\n vsync_enter_line_max\n");
module_param(vsync_enter_line_max, uint, 0664);
MODULE_PARM_DESC(vsync_exit_line_max, "\n vsync_exit_line_max\n");
module_param(vsync_exit_line_max, uint, 0664);
MODULE_PARM_DESC(vsync_line_threshold, "\n vsync_line_threshold\n");
module_param(vsync_line_threshold, uint, 0664);
+MODULE_PARM_DESC(line_threshold, "\n line_threshold\n");
+module_param(line_threshold, uint, 0664);
static unsigned int osd_filter_coefs_bicubic_sharp[] = {
0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300,
static bool osd_hdr_on;
#endif
-static int cnt;
-#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
static int get_encp_line(void)
{
int enc_line = 0;
+ int active_line_begin = 0;
+ unsigned int reg = 0;
switch (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3) {
case 0:
- enc_line = (osd_reg_read(ENCL_INFO_READ) >> 16) & 0x1fff;
+ reg = osd_reg_read(ENCL_INFO_READ);
+ active_line_begin =
+ osd_reg_read(ENCL_VIDEO_VAVON_BLINE);
break;
case 1:
- enc_line = (osd_reg_read(ENCI_INFO_READ) >> 16) & 0x1fff;
+ reg = osd_reg_read(ENCI_INFO_READ);
+ active_line_begin =
+ osd_reg_read(ENCI_VFIFO2VD_LINE_TOP_START);
break;
case 2:
- enc_line = (osd_reg_read(ENCP_INFO_READ) >> 16) & 0x1fff;
+ reg = osd_reg_read(ENCP_INFO_READ);
+ active_line_begin =
+ osd_reg_read(ENCP_VIDEO_VAVON_BLINE);
break;
case 3:
- enc_line = (osd_reg_read(ENCT_INFO_READ) >> 16) & 0x1fff;
+ reg = osd_reg_read(ENCT_INFO_READ);
+ active_line_begin =
+ osd_reg_read(ENCT_VIDEO_VAVON_BLINE);
break;
}
+ enc_line = (reg >> 16) & 0x1fff;
+ enc_line -= active_line_begin;
return enc_line;
}
-#endif
static int get_enter_encp_line(void)
{
int enc_line = 0;
- switch (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3) {
- case 0:
- enc_line = (osd_reg_read(ENCL_INFO_READ) >> 16) & 0x1fff;
- break;
- case 1:
- enc_line = (osd_reg_read(ENCI_INFO_READ) >> 16) & 0x1fff;
- break;
- case 2:
- enc_line = (osd_reg_read(ENCP_INFO_READ) >> 16) & 0x1fff;
- break;
- case 3:
- enc_line = (osd_reg_read(ENCT_INFO_READ) >> 16) & 0x1fff;
- break;
- }
+ enc_line = get_encp_line();
if (enc_line > vsync_enter_line_max)
vsync_enter_line_max = enc_line;
return enc_line;
{
int enc_line = 0;
- switch (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3) {
- case 0:
- enc_line = (osd_reg_read(ENCL_INFO_READ) >> 16) & 0x1fff;
- break;
- case 1:
- enc_line = (osd_reg_read(ENCI_INFO_READ) >> 16) & 0x1fff;
- break;
- case 2:
- enc_line = (osd_reg_read(ENCP_INFO_READ) >> 16) & 0x1fff;
- break;
- case 3:
- enc_line = (osd_reg_read(ENCT_INFO_READ) >> 16) & 0x1fff;
- break;
- }
+ enc_line = get_encp_line();
if (enc_line > vsync_exit_line_max)
vsync_exit_line_max = enc_line;
return enc_line;
#endif
}
-static int get_osd_hwc_type(void)
+u32 get_output_device_id(u32 index)
+{
+ u32 output_index = VIU1;
+
+ if (osd_hw.osd_meson_dev.has_viu2) {
+ switch (osd_hw.osd_meson_dev.cpu_id) {
+ case __MESON_CPU_MAJOR_ID_G12A:
+ case __MESON_CPU_MAJOR_ID_G12B:
+ if (index == osd_hw.osd_meson_dev.viu2_index)
+ output_index = VIU2;
+ else
+ output_index = VIU1;
+ break;
+ case __MESON_CPU_MAJOR_ID_TL1:
+ if (index == osd_hw.osd_meson_dev.viu2_index)
+ output_index = VIU2;
+ else
+ output_index = VIU1;
+ break;
+ default:
+ break;
+ }
+ }
+ return output_index;
+}
+
+static int get_osd_hwc_type(u32 index)
{
int ret = 0;
+ u32 output_index;
+ output_index = get_output_device_id(index);
/* new hwcomposer enable */
- if (osd_hw.hwc_enable) {
+ if (osd_hw.hwc_enable[output_index]) {
if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE)
ret = OSD_G12A_NEW_HWC;
else
struct osd_fence_map_s *data, *next;
struct list_head saved_list;
- mutex_lock(&post_fence_list_lock);
- saved_list = post_fence_list;
- list_replace_init(&post_fence_list, &saved_list);
- mutex_unlock(&post_fence_list_lock);
+ mutex_lock(&post_fence_list_lock[VIU1]);
+ saved_list = post_fence_list[VIU1];
+ list_replace_init(&post_fence_list[VIU1], &saved_list);
+ mutex_unlock(&post_fence_list_lock[VIU1]);
list_for_each_entry_safe(data, next, &saved_list, list) {
osd_pan_display_single_fence(data);
list_del(&data->list);
struct osd_layers_fence_map_s *data, *next;
struct list_head saved_list;
- mutex_lock(&post_fence_list_lock);
- saved_list = post_fence_list;
- list_replace_init(&post_fence_list, &saved_list);
- mutex_unlock(&post_fence_list_lock);
+ mutex_lock(&post_fence_list_lock[VIU1]);
+ saved_list = post_fence_list[VIU1];
+ list_replace_init(&post_fence_list[VIU1], &saved_list);
+ mutex_unlock(&post_fence_list_lock[VIU1]);
list_for_each_entry_safe(data, next, &saved_list, list) {
osd_pan_display_layers_fence(data);
list_del(&data->list);
static void osd_toggle_buffer(struct kthread_work *work)
{
- osd_hw.osd_fence[osd_hw.hwc_enable].
- toggle_buffer_handler(work);
+ u32 hwc_enable;
+
+ hwc_enable = osd_hw.hwc_enable[VIU1];
+ if (osd_hw.osd_fence[VIU1][hwc_enable].toggle_buffer_handler)
+ osd_hw.osd_fence[VIU1][hwc_enable]
+ .toggle_buffer_handler(work);
+}
+
+static void osd_toggle_buffer_single_viu2(struct kthread_work *work)
+{
+ struct osd_fence_map_s *data, *next;
+ struct list_head saved_list;
+
+ mutex_lock(&post_fence_list_lock[VIU2]);
+ saved_list = post_fence_list[VIU2];
+ list_replace_init(&post_fence_list[VIU2], &saved_list);
+ mutex_unlock(&post_fence_list_lock[VIU2]);
+ list_for_each_entry_safe(data, next, &saved_list, list) {
+ osd_pan_display_single_fence_viu2(data);
+ list_del(&data->list);
+ kfree(data);
+ }
+}
+
+static void osd_toggle_buffer_layers_viu2(struct kthread_work *work)
+{
+ struct osd_layers_fence_map_s *data, *next;
+ struct list_head saved_list;
+
+ mutex_lock(&post_fence_list_lock[VIU2]);
+ saved_list = post_fence_list[VIU2];
+ list_replace_init(&post_fence_list[VIU2], &saved_list);
+ mutex_unlock(&post_fence_list_lock[VIU2]);
+ list_for_each_entry_safe(data, next, &saved_list, list) {
+ osd_pan_display_layers_fence_viu2(data);
+ list_del(&data->list);
+ kfree(data);
+ }
+}
+
+static void osd_toggle_buffer_viu2(struct kthread_work *work)
+{
+ u32 hwc_enable;
+
+ hwc_enable = osd_hw.hwc_enable[VIU2];
+ if (osd_hw.osd_fence[VIU2][hwc_enable].toggle_buffer_handler)
+ osd_hw.osd_fence[VIU2][hwc_enable]
+ .toggle_buffer_handler(work);
}
-static int out_fence_create(int *release_fence_fd)
+static int out_fence_create(u32 output_index, int *release_fence_fd)
{
int out_fence_fd = -1;
struct sched_param param = {.sched_priority = 2};
+ char toggle_thread_name[32] = {};
- if (!timeline_created) {
+ if (!timeline_created[output_index]) {
/* timeline has not been created */
- if (osd_timeline_create()) {
- kthread_init_worker(&buffer_toggle_worker);
- buffer_toggle_thread = kthread_run(
+ if (osd_timeline_create(output_index)) {
+ kthread_init_worker
+ (&buffer_toggle_worker[output_index]);
+ sprintf(toggle_thread_name,
+ "aml_buf_toggle_%d", output_index);
+ buffer_toggle_thread[output_index] = kthread_run(
kthread_worker_fn,
- &buffer_toggle_worker,
- "aml_buf_toggle");
- if (IS_ERR(buffer_toggle_thread)) {
+ &buffer_toggle_worker[output_index],
+ toggle_thread_name);
+ if (IS_ERR(buffer_toggle_thread[output_index])) {
osd_log_err("create osd toggle kthread failed");
return -1;
}
- sched_setscheduler(buffer_toggle_thread,
- SCHED_FIFO, ¶m);
- kthread_init_work(
- &buffer_toggle_work, osd_toggle_buffer);
- timeline_created = 1;
+ sched_setscheduler(buffer_toggle_thread[output_index],
+ SCHED_FIFO, ¶m);
+ if (output_index == VIU1)
+ kthread_init_work(
+ &buffer_toggle_work[output_index],
+ osd_toggle_buffer);
+ else if (output_index == VIU2)
+ kthread_init_work(
+ &buffer_toggle_work[output_index],
+ osd_toggle_buffer_viu2);
+ timeline_created[output_index] = 1;
}
}
/* hwc_enable disable create fence every time */
- if (!osd_hw.hwc_enable) {
- out_fence_fd = osd_timeline_create_fence();
+ if (!osd_hw.hwc_enable[output_index]) {
+ out_fence_fd = osd_timeline_create_fence(output_index);
if (out_fence_fd < 0) {
osd_log_err("fence obj create fail\n");
out_fence_fd = -1;
/* hwc_enable enable create fence
* when first sync request called
*/
- if (osd_hw.out_fence_fd == -1) {
- out_fence_fd = osd_timeline_create_fence();
+ if (osd_hw.out_fence_fd[output_index] == -1) {
+ out_fence_fd = osd_timeline_create_fence(output_index);
if (out_fence_fd < 0) {
osd_log_err("fence obj create fail\n");
out_fence_fd = -1;
}
- osd_hw.out_fence_fd = out_fence_fd;
- } else
- out_fence_fd = osd_hw.out_fence_fd;
+ osd_hw.out_fence_fd[output_index] = out_fence_fd;
+ } else {
+ out_fence_fd = osd_hw.out_fence_fd[output_index];
+ }
}
if (release_fence_fd)
*release_fence_fd = out_fence_fd;
int out_fence_fd = -1;
int buf_num = 0;
int in_fence_fd = -1;
+ u32 output_index = 0;
struct osd_fence_map_s *fence_map =
kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL);
- osd_hw.hwc_enable = 0;
+ output_index = get_output_device_id(index);
+ osd_hw.hwc_enable[output_index] = 0;
if (request->sync_req.magic == FB_SYNC_REQUEST_MAGIC) {
buf_num = find_buf_num(yres, request->sync_req.yoffset);
if (!fence_map) {
osd_log_err("could not allocate osd_fence_map\n");
return -ENOMEM;
}
- mutex_lock(&post_fence_list_lock);
+ mutex_lock(&post_fence_list_lock[output_index]);
fence_map->op = 0xffffffff;
fence_map->fb_index = index;
fence_map->buf_num = buf_num;
fence_map->in_fence = osd_get_fenceobj(
request->sync_req.in_fen_fd);
fence_map->out_fd =
- out_fence_create(&out_fence_fd);
+ out_fence_create(output_index, &out_fence_fd);
} else {
buf_num = find_buf_num(yres, request->sync_req_old.yoffset);
if (!fence_map) {
osd_log_err("could not allocate osd_fence_map\n");
return -ENOMEM;
}
- mutex_lock(&post_fence_list_lock);
+ mutex_lock(&post_fence_list_lock[output_index]);
fence_map->op = 0xffffffff;
fence_map->fb_index = index;
fence_map->buf_num = buf_num;
fence_map->in_fence = osd_get_fenceobj(
request->sync_req_old.in_fen_fd);
fence_map->out_fd =
- out_fence_create(&out_fence_fd);
+ out_fence_create(output_index, &out_fence_fd);
}
- list_add_tail(&fence_map->list, &post_fence_list);
- mutex_unlock(&post_fence_list_lock);
- kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work);
+ list_add_tail(&fence_map->list, &post_fence_list[output_index]);
+ mutex_unlock(&post_fence_list_lock[output_index]);
+ kthread_queue_work(&buffer_toggle_worker[output_index],
+ &buffer_toggle_work[output_index]);
if (in_fence_fd >= 0)
__close_fd(current->files, in_fence_fd);
return out_fence_fd;
int out_fence_fd = -1;
int buf_num = 0;
u32 xoffset, yoffset;
+ u32 output_index = 0;
struct osd_fence_map_s *fence_map = NULL;
if (index > OSD1)
osd_log_err("could not allocate osd_fence_map\n");
return -ENOMEM;
}
- mutex_lock(&post_fence_list_lock);
+ output_index = get_output_device_id(index);
+ mutex_lock(&post_fence_list_lock[output_index]);
fence_map->op = 0xffffffff;
fence_map->fb_index = index;
fence_map->buf_num = buf_num;
osd_tprintk("direct render fence fd:%d\n", fence_map->in_fd);
fence_map->in_fence = osd_get_fenceobj(fence_map->in_fd);
fence_map->out_fd =
- out_fence_create(&out_fence_fd);
+ out_fence_create(output_index, &out_fence_fd);
/* Todo: */
- list_add_tail(&fence_map->list, &post_fence_list);
- mutex_unlock(&post_fence_list_lock);
- kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work);
+ list_add_tail(&fence_map->list, &post_fence_list[output_index]);
+ mutex_unlock(&post_fence_list_lock[output_index]);
+ kthread_queue_work(&buffer_toggle_worker[output_index],
+ &buffer_toggle_work[output_index]);
request->out_fen_fd = out_fence_fd;
- __close_fd(current->files, request->in_fen_fd);
+ if (request->in_fen_fd >= 0)
+ __close_fd(current->files, request->in_fen_fd);
return out_fence_fd;
}
{
int out_fence_fd = -1;
s32 in_fence_fd;
+ u32 output_index = 0;
struct osd_layers_fence_map_s *fence_map = NULL;
if (index > OSD_MAX)
return -1;
+ output_index = get_output_device_id(index);
in_fence_fd = request->in_fen_fd;
- mutex_lock(&post_fence_list_lock);
- fence_map = &map_layers;
+ mutex_lock(&post_fence_list_lock[output_index]);
+ fence_map = &map_layers[output_index];
fence_map->cmd = LAYER_SYNC;
fence_map->layer_map[index].fb_index = index;
/* layer_map[index].enable will update if have blank ioctl */
/* no longer put list, will put them via do_hwc */
fence_map->layer_map[index].in_fence = osd_get_fenceobj(in_fence_fd);
fence_map->layer_map[index].out_fd =
- out_fence_create(&out_fence_fd);
- mutex_unlock(&post_fence_list_lock);
+ out_fence_create(output_index, &out_fence_fd);
+ mutex_unlock(&post_fence_list_lock[output_index]);
osd_log_dbg(MODULE_FENCE, "sync_render_layers_fence:osd%d: ind_fd=%d,out_fd=%d\n",
fence_map->layer_map[index].fb_index,
fence_map->layer_map[index].in_fd,
fence_map->layer_map[index].out_fd);
request->out_fen_fd = out_fence_fd;
- __close_fd(current->files, in_fence_fd);
- __close_fd(current->files, request->shared_fd);
+ if (in_fence_fd >= 0)
+ __close_fd(current->files, in_fence_fd);
+ if (request->shared_fd >= 0)
+ __close_fd(current->files, request->shared_fd);
return out_fence_fd;
}
u32 phys_addr,
size_t len)
{
- int line;
+ int line, hwc_enable;
+ u32 output_index = 0;
- cnt++;
line = get_encp_line();
+ output_index = get_output_device_id(index);
osd_log_dbg2(MODULE_RENDER,
- "enter osd_sync_request_render:cnt=%d,encp line=%d\n",
- cnt, line);
+ "enter osd_sync_request_render:encp line=%d\n",
+ line);
if (request->magic == FB_SYNC_REQUEST_RENDER_MAGIC_V1)
- osd_hw.hwc_enable = 0;
+ osd_hw.hwc_enable[output_index] = 0;
else if (request->magic == FB_SYNC_REQUEST_RENDER_MAGIC_V2)
- osd_hw.hwc_enable = 1;
- if (index == OSD4)
- osd_hw.viu_type = VIU2;
- else
- osd_hw.viu_type = VIU1;
- osd_hw.osd_fence[osd_hw.hwc_enable].sync_fence_handler(
- index, yres, request, phys_addr, len);
+ osd_hw.hwc_enable[output_index] = 1;
+ output_index = get_output_device_id(index);
+ hwc_enable = osd_hw.hwc_enable[output_index];
+
+ if (osd_hw.osd_fence[output_index][hwc_enable].sync_fence_handler)
+ osd_hw.osd_fence[output_index][hwc_enable]
+ .sync_fence_handler(index, yres,
+ request, phys_addr, len);
return request->out_fen_fd;
}
-int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd)
+int osd_sync_do_hwc(u32 index, struct do_hwc_cmd_s *hwc_cmd)
{
int out_fence_fd = -1;
struct osd_layers_fence_map_s *fence_map = NULL;
int line;
+ u32 output_index = 0;
+ output_index = get_output_device_id(index);
line = get_encp_line();
osd_log_dbg2(MODULE_RENDER,
- "enter osd_sync_do_hwc:cnt=%d,encp line=%d\n",
- cnt, line);
+ "enter osd_sync_do_hwc:encp line=%d\n",
+ line);
fence_map = kzalloc(
sizeof(struct osd_layers_fence_map_s), GFP_KERNEL);
if (!fence_map)
return -ENOMEM;
- osd_hw.hwc_enable = 1;
- mutex_lock(&post_fence_list_lock);
- memcpy(fence_map, &map_layers,
- sizeof(struct osd_layers_fence_map_s));
+ osd_hw.hwc_enable[output_index] = 1;
+ mutex_lock(&post_fence_list_lock[output_index]);
+ memcpy(fence_map, &map_layers[output_index],
+ sizeof(struct osd_layers_fence_map_s));
/* clear map_layers, need alloc next add_sync ioctl */
- memset(&map_layers, 0,
- sizeof(struct osd_layers_fence_map_s));
+ memset(&map_layers[output_index], 0,
+ sizeof(struct osd_layers_fence_map_s));
fence_map->out_fd =
- out_fence_create(&out_fence_fd);
+ out_fence_create(output_index, &out_fence_fd);
fence_map->disp_info.background_w =
hwc_cmd->disp_info.background_w;
fence_map->disp_info.background_h =
hwc_cmd->disp_info.position_h;
fence_map->hdr_mode = hwc_cmd->hdr_mode;
/* other info set via add_sync and blank ioctl */
- list_add_tail(&fence_map->list, &post_fence_list);
+ list_add_tail(&fence_map->list, &post_fence_list[output_index]);
/* after do_hwc, clear osd_hw.out_fence_fd */
- if (timeline_created && osd_hw.out_fence_fd)
- osd_hw.out_fence_fd = -1;
- mutex_unlock(&post_fence_list_lock);
- kthread_queue_work(&buffer_toggle_worker, &buffer_toggle_work);
+ if (timeline_created[output_index] &&
+ osd_hw.out_fence_fd[output_index])
+ osd_hw.out_fence_fd[output_index] = -1;
+ mutex_unlock(&post_fence_list_lock[output_index]);
+ kthread_queue_work(&buffer_toggle_worker[output_index],
+ &buffer_toggle_work[output_index]);
if (get_logo_loaded()) {
int logo_index;
return -5566;
}
-int osd_sync_do_hwc(struct do_hwc_cmd_s *hwc_cmd)
+int osd_sync_do_hwc(u32 output_index, struct do_hwc_cmd_s *hwc_cmd)
{
osd_log_err("osd_do_hwc not supported\n");
return -5566;
void osd_set_enable_hw(u32 index, u32 enable)
{
- if (osd_hw.hwc_enable) {
+ u32 output_index = 0;
+
+ output_index = get_output_device_id(index);
+ if (osd_hw.hwc_enable[output_index]) {
if (index > OSD_MAX)
return;
if ((osd_hw.osd_meson_dev.osd_ver < OSD_HIGH_ONE)
osd_enable_hw(index, enable);
else {
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
- mutex_lock(&post_fence_list_lock);
- map_layers.layer_map[index].fb_index = index;
- map_layers.layer_map[index].enable = enable;
- map_layers.cmd = BLANK_CMD;
- mutex_unlock(&post_fence_list_lock);
+ mutex_lock(&post_fence_list_lock[output_index]);
+ map_layers[output_index].layer_map[index]
+ .fb_index = index;
+ map_layers[output_index].layer_map[index]
+ .enable = enable;
+ map_layers[output_index].cmd = BLANK_CMD;
+ mutex_unlock(&post_fence_list_lock[output_index]);
osd_log_dbg(MODULE_BASE, "osd_set_enable_hw: osd%d,enable=%d\n",
index, enable);
#endif
{
/* only called by vsync irq or rdma irq */
unsigned int fb0_cfg_w0 = 0, fb1_cfg_w0 = 0;
- unsigned int fb3_cfg_w0 = 0;
unsigned int scan_line_number = 0;
unsigned int odd_even;
if ((index & (1 << OSD1)) == (1 << OSD1)) {
VSYNCOSD_IRQ_WR_MPEG_REG(
hw_osd_reg_array[OSD1].osd_blk0_cfg_w0, fb0_cfg_w0);
- if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE)
- VSYNCOSD_IRQ_WR_MPEG_REG(
- hw_osd_reg_array[OSD3].osd_blk0_cfg_w0, fb0_cfg_w0);
+ if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
+ if ((osd_hw.osd_meson_dev.viu1_osd_count - 1) == OSD3)
+ VSYNCOSD_IRQ_WR_MPEG_REG(
+ hw_osd_reg_array[OSD3].osd_blk0_cfg_w0,
+ fb0_cfg_w0);
+ }
}
if ((index & (1 << OSD2)) == (1 << OSD2))
VSYNCOSD_IRQ_WR_MPEG_REG(
hw_osd_reg_array[OSD2].osd_blk0_cfg_w0, fb1_cfg_w0);
- if (osd_hw.powered[OSD4]) {
- if (osd_hw.powered[OSD4])
- fb3_cfg_w0 = VSYNCOSD_RD_MPEG_REG(
- hw_osd_reg_array[OSD4].osd_blk0_cfg_w0);
- if (osd_hw.scan_mode[OSD4] == SCAN_MODE_INTERLACE) {
- if ((osd_hw.pandata[OSD4].y_start % 2) == 1) {
- odd_even = (osd_reg_read(ENCI_INFO_READ) &
- (1 << 29)) ? OSD_TYPE_TOP_FIELD :
- OSD_TYPE_BOT_FIELD;
- } else {
- odd_even = (osd_reg_read(ENCI_INFO_READ)
- & (1 << 29)) ? OSD_TYPE_BOT_FIELD :
- OSD_TYPE_TOP_FIELD;
- }
- }
- fb3_cfg_w0 &= ~1;
- fb3_cfg_w0 |= odd_even;
- if ((index & (1 << OSD4)) == (1 << OSD4))
- VSYNCOSD_IRQ_WR_MPEG_REG(
- hw_osd_reg_array[OSD4].osd_blk0_cfg_w0, fb3_cfg_w0);
- }
spin_unlock_irqrestore(&osd_lock, lock_flags);
}
/* only called by vsync irq or rdma irq */
unsigned int output_type = 0;
int index = 0;
+ int viu2_index = osd_hw.osd_meson_dev.viu2_index;
+ int osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
+ int has_osd3 = 0;
+ if ((osd_count - 1) == OSD3)
+ has_osd3 = 1;
+ //todo: Karry
output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3;
osd_hw.scan_mode[OSD1] = SCAN_MODE_PROGRESSIVE;
osd_hw.scan_mode[OSD2] = SCAN_MODE_PROGRESSIVE;
- osd_hw.scan_mode[OSD3] = SCAN_MODE_PROGRESSIVE;
- osd_hw.scan_mode[OSD4] = SCAN_MODE_PROGRESSIVE;
+ if (has_osd3)
+ osd_hw.scan_mode[OSD3] = SCAN_MODE_PROGRESSIVE;
+ osd_hw.scan_mode[viu2_index] = SCAN_MODE_PROGRESSIVE;
switch (output_type) {
case VOUT_ENCP:
if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12)) {
/* 1080i */
osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE;
osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE;
+ if (has_osd3)
osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE;
}
break;
if (osd_reg_read(ENCI_VIDEO_EN) & 1) {
osd_hw.scan_mode[OSD1] = SCAN_MODE_INTERLACE;
osd_hw.scan_mode[OSD2] = SCAN_MODE_INTERLACE;
+ if (has_osd3)
osd_hw.scan_mode[OSD3] = SCAN_MODE_INTERLACE;
}
break;
}
- if (osd_hw.powered[OSD4]) {
- output_type = (osd_reg_read(VPU_VIU_VENC_MUX_CTRL) >> 2) & 0x3;
- switch (output_type) {
- case VOUT_ENCP:
- if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12))
- /* 1080i */
- osd_hw.scan_mode[OSD4] = SCAN_MODE_INTERLACE;
- break;
- case VOUT_ENCI:
- if (osd_reg_read(ENCI_VIDEO_EN) & 1)
- osd_hw.scan_mode[OSD4] = SCAN_MODE_INTERLACE;
- break;
- }
-
- }
if (osd_hw.hw_cursor_en) {
/* 3 layers osd don't support osd2 cursor */
if (osd_hw.free_scale_enable[OSD1])
}
}
if ((osd_hw.scan_mode[OSD1] == SCAN_MODE_INTERLACE)
- || (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE)
- || (osd_hw.scan_mode[OSD4] == SCAN_MODE_INTERLACE))
+ || (osd_hw.scan_mode[OSD2] == SCAN_MODE_INTERLACE))
osd_update_interlace_mode(index);
}
+static void osd_update_interlace_mode_viu2(void)
+{
+ /* only called by vsync irq or rdma irq */
+ unsigned int fb3_cfg_w0 = 0;
+ unsigned int odd_even = 0;
+ u32 viu2_index;
+
+ spin_lock_irqsave(&osd_lock, lock_flags);
+ viu2_index = osd_hw.osd_meson_dev.viu2_index;
+ if (osd_hw.powered[viu2_index]) {
+ fb3_cfg_w0 = VSYNCOSD_RD_MPEG_REG(
+ hw_osd_reg_array[viu2_index].osd_blk0_cfg_w0);
+ if (osd_hw.scan_mode[viu2_index] == SCAN_MODE_INTERLACE) {
+ if ((osd_hw.pandata[viu2_index].y_start % 2) == 1) {
+ odd_even = (osd_reg_read(ENCI_INFO_READ) &
+ (1 << 29)) ? OSD_TYPE_TOP_FIELD :
+ OSD_TYPE_BOT_FIELD;
+ } else {
+ odd_even = (osd_reg_read(ENCI_INFO_READ)
+ & (1 << 29)) ? OSD_TYPE_BOT_FIELD :
+ OSD_TYPE_TOP_FIELD;
+ }
+ }
+ fb3_cfg_w0 &= ~1;
+ fb3_cfg_w0 |= odd_even;
+ VSYNCOSD_IRQ_WR_MPEG_REG(
+ hw_osd_reg_array[viu2_index].osd_blk0_cfg_w0,
+ fb3_cfg_w0);
+ }
+ spin_unlock_irqrestore(&osd_lock, lock_flags);
+}
+
+void osd_update_scan_mode_viu2(void)
+{
+ /* only called by vsync irq or rdma irq */
+ unsigned int output_type = 0;
+ int viu2_index = osd_hw.osd_meson_dev.viu2_index;
+
+ output_type = osd_reg_read(VPU_VIU_VENC_MUX_CTRL) & 0x3;
+ osd_hw.scan_mode[viu2_index] = SCAN_MODE_PROGRESSIVE;
+ if (osd_hw.powered[viu2_index]) {
+ output_type = (osd_reg_read(VPU_VIU_VENC_MUX_CTRL)
+ >> 2) & 0x3;
+ switch (output_type) {
+ case VOUT_ENCP:
+ if (osd_reg_read(ENCP_VIDEO_MODE) & (1 << 12))
+ /* 1080i */
+ osd_hw.scan_mode[viu2_index] =
+ SCAN_MODE_INTERLACE;
+ break;
+ case VOUT_ENCI:
+ if (osd_reg_read(ENCI_VIDEO_EN) & 1)
+ osd_hw.scan_mode[viu2_index] =
+ SCAN_MODE_INTERLACE;
+ break;
+ }
+
+ }
+ if (osd_hw.scan_mode[viu2_index] == SCAN_MODE_INTERLACE)
+ osd_update_interlace_mode_viu2();
+}
+
//not rdma will call update func;
void walk_through_update_list(void)
{
status = VSYNCOSD_RD_MPEG_REG(VPU_MAFBC_IRQ_RAW_STATUS);
if (status & 0x3c) {
- osd_log_dbg(MODULE_BASE, "afbc error happened\n");
+ osd_log_dbg(MODULE_BASE,
+ "afbc error happened,status=0x%x\n", status);
osd_hw.afbc_err_cnt++;
error = true;
}
static irqreturn_t vsync_viu2_isr(int irq, void *dev_id)
#endif
{
+ osd_update_scan_mode_viu2();
#ifndef FIQ_VSYNC
return IRQ_HANDLED;
#endif
if (pxp_mode)
timeout = msecs_to_jiffies(50);
- else
- timeout = msecs_to_jiffies(1000);
+ else {
+ struct vinfo_s *vinfo;
+
+ vinfo = get_current_vinfo();
+ if (vinfo && (!strcmp(vinfo->name, "invalid") ||
+ !strcmp(vinfo->name, "null"))) {
+ timeout = msecs_to_jiffies(1);
+ } else
+ timeout = msecs_to_jiffies(1000);
+ }
wait_event_interruptible_timeout(
osd_vsync_wq, vsync_hit, timeout);
}
int is_interlaced(struct vinfo_s *vinfo)
{
+ if (!vinfo)
+ return 0;
if (vinfo->mode == VMODE_CVBS)
return 1;
if (vinfo->height != vinfo->field_height)
int osd_set_scan_mode(u32 index)
{
- struct vinfo_s *vinfo;
+ struct vinfo_s *vinfo = NULL;
u32 data32 = 0x0;
s32 y_end = 0;
+ u32 output_index;
+ output_index = get_output_device_id(index);
osd_hw.scan_mode[index] = SCAN_MODE_PROGRESSIVE;
- vinfo = get_current_vinfo();
+ if (output_index == VIU1)
+ vinfo = get_current_vinfo();
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+ else if (output_index == VIU2)
+ vinfo = get_current_vinfo2();
+#endif
if (vinfo && (strcmp(vinfo->name, "invalid") &&
strcmp(vinfo->name, "null"))) {
osd_hw.scale_workaround = 0;
if ((vinfo->width == 720)
&& (vinfo->height == 480)) {
if (osd_hw.free_scale_mode[index]) {
- osd_hw.field_out_en = 1;
+ osd_hw.field_out_en[output_index] = 1;
switch (y_end) {
case 719:
osd_hw.bot_type = 2;
} else if ((vinfo->width == 720)
&& (vinfo->height == 576)) {
if (osd_hw.free_scale_mode[index]) {
- osd_hw.field_out_en = 1;
+ osd_hw.field_out_en[output_index] = 1;
switch (y_end) {
case 719:
osd_hw.bot_type = 2;
} else if ((vinfo->width == 1920)
&& (vinfo->height == 1080)) {
if (osd_hw.free_scale_mode[index]) {
- osd_hw.field_out_en = 1;
+ osd_hw.field_out_en[output_index] = 1;
switch (y_end) {
case 719:
osd_hw.bot_type = 1;
&& (osd_hw.free_scale_enable[index]))
if (!(osd_hw.osd_meson_dev.afbc_type))
osd_hw.scale_workaround = 1;
- osd_hw.field_out_en = 0;
+ osd_hw.field_out_en[output_index] = 0;
} else if (((vinfo->width == 720)
&& (vinfo->height == 480))
|| ((vinfo->width == 720)
osd_v_filter_mode = 6;
}
if (osd_hw.free_scale_mode[index])
- osd_hw.field_out_en = 0;
+ osd_hw.field_out_en[output_index] = 0;
} else {
if (osd_hw.free_scale_mode[index])
- osd_hw.field_out_en = 0;
+ osd_hw.field_out_en[output_index] = 0;
}
}
}
void osd_set_free_scale_enable_hw(u32 index, u32 enable)
{
- if (osd_hw.free_scale_mode[index] && (index != OSD4)) {
+ if (osd_hw.free_scale_mode[index]
+ && (osd_hw.osd_meson_dev.has_viu2 ?
+ ((index != osd_hw.osd_meson_dev.viu2_index) ?
+ 1 : 0) : 1)) {
osd_set_free_scale_enable_mode1(index, enable);
if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) {
u32 height_dst, height_src;
void osd_get_window_axis_hw(u32 index, s32 *x0, s32 *y0, s32 *x1, s32 *y1)
{
- struct vinfo_s *vinfo;
+ struct vinfo_s *vinfo = NULL;
s32 height;
+ u32 output_index;
+ output_index = get_output_device_id(index);
if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
- vinfo = get_current_vinfo();
+ if (output_index == VIU1)
+ vinfo = get_current_vinfo();
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+ else if (output_index == VIU2)
+ vinfo = get_current_vinfo2();
+#endif
if (vinfo && (strcmp(vinfo->name, "invalid") &&
strcmp(vinfo->name, "null"))) {
if (is_interlaced(vinfo)) {
void osd_set_window_axis_hw(u32 index, s32 x0, s32 y0, s32 x1, s32 y1)
{
- struct vinfo_s *vinfo;
+ struct vinfo_s *vinfo = NULL;
s32 temp_y0, temp_y1;
+ u32 output_index;
- #if 0
- if (osd_hw.hwc_enable &&
- (osd_hw.osd_display_debug != OSD_DISP_DEBUG))
- return;
- #endif
- vinfo = get_current_vinfo();
+ output_index = get_output_device_id(index);
+ if (output_index == VIU1)
+ vinfo = get_current_vinfo();
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+ else if (output_index == VIU2)
+ vinfo = get_current_vinfo2();
+#endif
mutex_lock(&osd_mutex);
if (vinfo && (strcmp(vinfo->name, "invalid") &&
strcmp(vinfo->name, "null"))) {
if (osd_hw.free_dst_data[index].y_end >= 2159)
osd_set_dummy_data(index, 0xff);
osd_update_window_axis = true;
- if (osd_hw.hwc_enable &&
- (osd_hw.osd_display_debug == OSD_DISP_DEBUG))
- osd_setting_blend();
+ if (osd_hw.hwc_enable[output_index] &&
+ (osd_hw.osd_display_debug == OSD_DISP_DEBUG))
+ osd_setting_blend(output_index);
mutex_unlock(&osd_mutex);
}
-
s32 osd_get_position_from_reg(
u32 index,
s32 *src_x_start, s32 *src_x_end,
struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
u32 data32 = 0x0;
- if (index >= OSD4)
+ if (index >= OSD_MAX)
return -1;
if (!src_x_start || !src_x_end || !src_y_start || !src_y_end
{
int i = 0;
int count = (pxp_mode == 1)?3:WAIT_AFBC_READY_COUNT;
+ u32 output_index;
if (index == 0) {
osd_log_info("osd[%d] enable: %d (%s)\n",
/* reset viu 31bit ?? */
if (!osd_hw.enable[index] &&
- osd_hw.osd_afbcd[index].enable && enable
- && (get_osd_hwc_type() != OSD_G12A_NEW_HWC)) {
+ osd_hw.osd_afbcd[index].enable && enable &&
+ (get_osd_hwc_type(index) != OSD_G12A_NEW_HWC)) {
spin_lock_irqsave(&osd_lock, lock_flags);
if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) {
osd_reg_write(VIU_SW_RESET, 0x80000000);
}
osd_hw.enable[index] = enable;
- if (get_osd_hwc_type() != OSD_G12A_NEW_HWC) {
+ output_index = get_output_device_id(index);
+ if (get_osd_hwc_type(index) != OSD_G12A_NEW_HWC) {
add_to_update_list(index, OSD_ENABLE);
osd_wait_vsync_hw();
- } else if (osd_hw.hwc_enable && osd_hw.osd_display_debug)
- osd_setting_blend();
+ } else if (osd_hw.hwc_enable[output_index] &&
+ osd_hw.osd_display_debug)
+ osd_setting_blend(output_index);
}
void osd_set_2x_scale_hw(u32 index, u16 h_scale_enable, u16 v_scale_enable)
osd_wait_vsync_hw();
}
-void osd_get_flush_rate_hw(u32 *break_rate)
+void osd_get_flush_rate_hw(u32 index, u32 *break_rate)
{
- const struct vinfo_s *vinfo;
+ const struct vinfo_s *vinfo = NULL;
+ u32 output_index;
- vinfo = get_current_vinfo();
+ output_index = get_output_device_id(index);
+ if (output_index == VIU1)
+ vinfo = get_current_vinfo();
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+ else if (output_index == VIU2)
+ vinfo = get_current_vinfo2();
+#endif
+ if (!vinfo)
+ return;
*break_rate = vinfo->sync_duration_num / vinfo->sync_duration_den;
}
}
-void osd_get_fps(u32 *osd_fps)
+void osd_get_fps(u32 index, u32 *osd_fps)
{
- *osd_fps = osd_hw.osd_fps;
+ u32 output_index;
+
+ output_index = get_output_device_id(index);
+ *osd_fps = osd_hw.osd_fps[output_index];
+
}
-void osd_set_fps(u32 osd_fps_start)
+void osd_set_fps(u32 index, u32 osd_fps_start)
{
static int stime, etime;
+ u32 output_index;
- osd_hw.osd_fps_start = osd_fps_start;
+ output_index = get_output_device_id(index);
+ osd_hw.osd_fps_start[output_index] = osd_fps_start;
if (osd_fps_start) {
/* start to calc fps */
stime = ktime_to_us(ktime_get());
- osd_hw.osd_fps = 0;
+ osd_hw.osd_fps[output_index] = 0;
} else {
/* stop to calc fps */
etime = ktime_to_us(ktime_get());
- osd_hw.osd_fps = (osd_hw.osd_fps * 1000000)
+ osd_hw.osd_fps[output_index] =
+ (osd_hw.osd_fps[output_index] * 1000000)
/ (etime - stime);
- osd_log_info("osd fps:=%d\n", osd_hw.osd_fps);
+ osd_log_info("osd fps:=%d\n", osd_hw.osd_fps[output_index]);
}
}
osd_hw.osd_display_debug = osd_display_debug_enable;
}
-void osd_get_background_size(struct display_flip_info_s *disp_info)
+void osd_get_background_size(u32 index, struct display_flip_info_s *disp_info)
{
- memcpy(disp_info, &osd_hw.disp_info,
- sizeof(struct display_flip_info_s));
+ u32 output_index;
+
+ output_index = get_output_device_id(index);
+ memcpy(disp_info, &osd_hw.disp_info[output_index],
+ sizeof(struct display_flip_info_s));
}
-void osd_set_background_size(struct display_flip_info_s *disp_info)
+void osd_set_background_size(u32 index, struct display_flip_info_s *disp_info)
{
- memcpy(&osd_hw.disp_info, disp_info,
- sizeof(struct display_flip_info_s));
+ u32 output_index;
+
+ output_index = get_output_device_id(index);
+ memcpy(&osd_hw.disp_info[output_index], disp_info,
+ sizeof(struct display_flip_info_s));
}
void osd_get_hdr_used(u32 *val)
osd_hw.osd_afbcd[index].inter_format = inter_format;
}
-void osd_get_hwc_enable(u32 *hwc_enable)
+void osd_get_hwc_enable(u32 index, u32 *hwc_enable)
{
- *hwc_enable = osd_hw.hwc_enable;
+ u32 output_index;
+
+ output_index = get_output_device_id(index);
+ *hwc_enable = osd_hw.hwc_enable[output_index];
}
-void osd_set_hwc_enable(u32 hwc_enable)
+void osd_set_hwc_enable(u32 index, u32 hwc_enable)
{
- osd_hw.hwc_enable = hwc_enable;
+ u32 output_index;
+
+ output_index = get_output_device_id(index);
+ osd_hw.hwc_enable[output_index] = hwc_enable;
/* setting default hwc path */
if (!hwc_enable)
- osd_setting_blend();
+ osd_setting_blend(OSD1);
}
-void osd_do_hwc(void)
+void osd_do_hwc(u32 index)
{
- osd_setting_blend();
+ u32 output_index;
+
+ output_index = get_output_device_id(index);
+ osd_setting_blend(output_index);
}
static void osd_set_two_ports(bool set)
osd_set_two_ports(osd_hw.two_ports);
}
-void osd_set_single_step_mode(u32 osd_single_step_mode)
+void osd_set_single_step_mode(u32 index, u32 osd_single_step_mode)
{
+ u32 output_index;
+
+ output_index = get_output_device_id(index);
+ if (output_index != VIU1)
+ return;
osd_hw.osd_debug.osd_single_step_mode = osd_single_step_mode;
if ((osd_hw.osd_debug.wait_fence_release) &&
(osd_hw.osd_debug.osd_single_step_mode == 0)) {
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
- osd_timeline_increase();
+ osd_timeline_increase(output_index);
#endif
osd_hw.osd_debug.wait_fence_release = false;
}
}
-void osd_set_single_step(u32 osd_single_step)
+void osd_set_single_step(u32 index, u32 osd_single_step)
{
+ u32 output_index;
+
+ output_index = get_output_device_id(index);
+ if (output_index != VIU1)
+ return;
osd_hw.osd_debug.osd_single_step = osd_single_step;
if ((osd_hw.osd_debug.wait_fence_release) &&
(osd_hw.osd_debug.osd_single_step > 0)) {
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
- osd_timeline_increase();
+ osd_timeline_increase(output_index);
#endif
osd_hw.osd_debug.wait_fence_release = false;
}
void osd_set_rotate(u32 index, u32 osd_rotate)
{
- if (index != OSD4)
+ if (index != osd_hw.osd_meson_dev.viu2_index)
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_hw.dim_color[index] = osd_dimm_color;
}
+void osd_set_hold_line(int hold_line)
+{
+ int i;
+ unsigned int data32 = 0, val = 0;
+
+ for (i = 0; i <= osd_hw.osd_meson_dev.viu1_osd_count; i++) {
+ if (osd_hw.powered[i]) {
+ data32 = VSYNCOSD_RD_MPEG_REG
+ (hw_osd_reg_array[i].osd_fifo_ctrl_stat);
+ val = (data32 >> 5) & 0x1f;
+ if (val != hold_line) {
+ VSYNCOSD_WR_MPEG_REG_BITS
+ (hw_osd_reg_array[i].osd_fifo_ctrl_stat,
+ hold_line & 0x1f, 5, 5);
+ }
+ }
+ }
+}
+
int osd_get_capbility(u32 index)
{
u32 capbility = 0;
capbility |= OSD_LAYER_ENABLE | OSD_FREESCALE
| OSD_UBOOT_LOGO | OSD_ZORDER | OSD_VIU1
| OSD_PRIMARY;
- else if ((index == OSD2) || (index == OSD3))
+ else if (index < osd_hw.osd_meson_dev.viu1_osd_count)
capbility |= OSD_LAYER_ENABLE | OSD_FREESCALE |
OSD_ZORDER | OSD_VIU1;
- else if (index == OSD4)
+ else if (index == osd_hw.osd_meson_dev.viu2_index)
capbility |= OSD_LAYER_ENABLE | OSD_VIU2;
} else if (osd_hw.osd_meson_dev.osd_ver == OSD_NORMAL) {
if (index == OSD1)
height_dst) / height_src - 1;
if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[VIU1]
- freescale_dst[index].x_end - 1;
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[VIU1]
- freescale_dst[index].y_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[VIU1]
- freescale_dst[index].x_start - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[VIU1]
- freescale_dst[index].y_start - 1;
freescale_dst[index].x_start = x_start;
freescale_dst[index].y_start = y_start;
freescale_dst[index].x_end = x_end;
freescale_dst[index].y_end = y_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_X) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[VIU1]
- freescale_dst[index].x_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[VIU1]
- freescale_dst[index].x_start - 1;
freescale_dst[index].x_start = x_start;
freescale_dst[index].x_end = x_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[VIU1]
- freescale_dst[index].y_end - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[VIU1]
- freescale_dst[index].y_start - 1;
freescale_dst[index].y_start = y_start;
freescale_dst[index].y_end = y_end;
osd_hw.dispdata[index].y_end =
fence_map->dst_y + fence_map->dst_h - 1;
if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[VIU1]
- osd_hw.dispdata[index].x_end - 1;
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[VIU1]
- osd_hw.dispdata[index].y_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[VIU1]
- osd_hw.dispdata[index].x_start - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[VIU1]
- osd_hw.dispdata[index].y_start - 1;
osd_hw.dispdata[index].x_start = x_start;
osd_hw.dispdata[index].y_start = y_start;
osd_hw.dispdata[index].x_end = x_end;
osd_hw.dispdata[index].y_end = y_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_X) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[VIU1]
- osd_hw.dispdata[index].x_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[VIU1]
- osd_hw.dispdata[index].x_start - 1;
osd_hw.dispdata[index].x_start = x_start;
osd_hw.dispdata[index].x_end = x_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[VIU1]
- osd_hw.dispdata[index].y_end - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[VIU1]
- osd_hw.dispdata[index].y_start - 1;
osd_hw.dispdata[index].y_start = y_start;
osd_hw.dispdata[index].y_end = y_end;
u32 osd_enable = 0;
bool skip = false;
const struct vinfo_s *vinfo;
-
+ u32 output_index = VIU1;
if (index >= OSD2)
goto out;
- if (timeline_created) { /* out fence created success. */
+ vinfo = get_current_vinfo();
+ if (!vinfo || (!strcmp(vinfo->name, "invalid") ||
+ !strcmp(vinfo->name, "null")))
+ goto out;
+
+ osd_hw.vinfo_width[output_index] = vinfo->width;
+ osd_hw.vinfo_height[output_index] = vinfo->height;
+
+ if (timeline_created[output_index]) { /* out fence created success. */
ret = osd_wait_buf_ready(fence_map);
if (ret < 0)
osd_log_dbg(MODULE_BASE, "fence wait ret %d\n", ret);
}
if (ret) {
osd_hw.buffer_alloc[index] = 1;
- if (osd_hw.osd_fps_start)
- osd_hw.osd_fps++;
+ if (osd_hw.osd_fps_start[output_index])
+ osd_hw.osd_fps[output_index]++;
if (fence_map->op == 0xffffffff)
skip = true;
else
AFBC_EN | BLOCK_SPLIT |
YUV_TRANSFORM | SUPER_BLOCK_ASPECT;
}
- vinfo = get_current_vinfo();
- if (vinfo) {
- if ((strcmp(vinfo->name, "invalid")) &&
- (strcmp(vinfo->name, "null"))) {
- osd_hw.vinfo_width = vinfo->width;
- osd_hw.vinfo_height = vinfo->height;
- }
- }
/* Todo: */
if (fence_map->ext_addr && fence_map->width
&& fence_map->height) {
.update_func(index);
osd_update_window_axis = false;
}
- if ((osd_enable != osd_hw.enable[index])
+ if ((osd_enable != osd_hw.enable[index] ||
+ (osd_hw.osd_meson_dev.afbc_type
+ == MALI_AFBC &&
+ osd_hw.osd_afbcd[index].enable))
&& (skip == false)
&& (suspend_flag == false)) {
osd_hw.enable[index] = osd_enable;
.update_func(index);
osd_update_window_axis = false;
}
- if ((osd_enable != osd_hw.enable[index])
+ if ((osd_enable != osd_hw.enable[index] ||
+ (osd_hw.osd_meson_dev.afbc_type
+ == MALI_AFBC &&
+ osd_hw.osd_afbcd[index].enable))
&& (skip == false)
&& (suspend_flag == false)) {
osd_hw.enable[index] = osd_enable;
osd_mali_afbc_start();
spin_unlock_irqrestore(&osd_lock, lock_flags);
osd_wait_vsync_hw();
- } else if ((osd_enable != osd_hw.enable[index])
+ } else if ((osd_enable != osd_hw.enable[index] ||
+ (osd_hw.osd_meson_dev.afbc_type == MALI_AFBC &&
+ osd_hw.osd_afbcd[index].enable))
&& (skip == false)) {
spin_lock_irqsave(&osd_lock, lock_flags);
if (suspend_flag == false) {
osd_wait_vsync_hw();
}
}
- if (timeline_created) {
+#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
+ if (ret)
+ osd_ext_clone_pan(index);
+#endif
+out:
+ if (timeline_created[output_index]) {
if (ret)
- osd_timeline_increase();
+ osd_timeline_increase(output_index);
else
osd_log_err("------NOT signal out_fence ERROR\n");
}
-#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
- if (ret)
- osd_ext_clone_pan(index);
-#endif
-out:
if (fence_map->in_fence)
osd_put_fenceobj(fence_map->in_fence);
+}
+static void osd_pan_display_single_fence_viu2(struct osd_fence_map_s *fence_map)
+{
+ osd_log_err("osd hwc version not support viu2\n");
}
static void osd_pan_display_update_info(struct layer_fence_map_s *layer_map)
const struct color_bit_define_s *color = NULL;
u32 ext_addr = 0;
u32 format = 0;
+ u32 output_index = 0;
if (index > OSD_MAX)
return;
layer_map->dst_x + layer_map->dst_w - 1;
osd_hw.free_dst_data[index].y_end =
layer_map->dst_y + layer_map->dst_h - 1;
- if (osd_hw.field_out_en) {
+ output_index = get_output_device_id(index);
+ if (osd_hw.field_out_en[output_index]) {
osd_hw.free_dst_data[index].y_start /= 2;
osd_hw.free_dst_data[index].y_end /= 2;
}
#endif
}
-static void osd_pan_display_layers_fence(
+static void _osd_pan_display_layers_fence(
+ u32 output_index,
+ struct vinfo_s *vinfo,
struct osd_layers_fence_map_s *fence_map)
{
int i = 0;
int ret;
- int osd_count = osd_hw.osd_meson_dev.osd_count - 1;
+ int start_index = 0;
+ int backup_en = 0;
+ int osd_count = 0;
/* osd_count need -1 when VIU2 enable */
struct layer_fence_map_s *layer_map = NULL;
- struct vinfo_s *vinfo;
- if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL)
- osd_count = 1;
- vinfo = get_current_vinfo();
- if (vinfo && (strcmp(vinfo->name, "invalid") &&
- strcmp(vinfo->name, "null"))) {
- osd_hw.vinfo_width = vinfo->width;
- osd_hw.vinfo_height = vinfo->field_height;
+ if (!vinfo || (!strcmp(vinfo->name, "invalid") ||
+ !strcmp(vinfo->name, "null")))
+ /* vout is null, release fence */
+ goto out;
+
+ osd_hw.vinfo_width[output_index] = vinfo->width;
+ osd_hw.vinfo_height[output_index] = vinfo->field_height;
+ memcpy(&osd_hw.disp_info[output_index], &fence_map->disp_info,
+ sizeof(struct display_flip_info_s));
+ if (output_index == VIU1) {
+ osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
+ if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL)
+ osd_count = 1;
+ start_index = 0;
+ backup_en = 1;
+ } else if (output_index == VIU2) {
+ start_index = osd_hw.osd_meson_dev.viu2_index;
+ osd_count = start_index + 1;
+ backup_en = 0;
+ } else {
+ osd_log_err("invald output_index=%d\n", output_index);
+ return;
}
- osd_set_background_size(&(fence_map->disp_info));
- if (osd_hw.osd_fps_start)
- osd_hw.osd_fps++;
- clear_backup_info();
+ if (osd_hw.osd_fps_start[output_index])
+ osd_hw.osd_fps[output_index]++;
+ if (backup_en)
+ clear_backup_info();
osd_hw.hdr_used = fence_map->hdr_mode;
- for (i = 0; i < osd_count; i++) {
+ for (i = start_index; i < osd_count; i++) {
layer_map = &fence_map->layer_map[i];
if (i != layer_map->fb_index) {
osd_hw.screen_base[i] = 0;
continue;
}
/* wait in fence */
- if (timeline_created && layer_map->enable
+ if (timeline_created[output_index] && layer_map->enable
&& (fence_map->cmd == LAYER_SYNC)) {
ret = osd_wait_buf_ready_combine(layer_map);
if (ret < 0)
"fence wait ret %d\n", ret);
}
osd_pan_display_update_info(layer_map);
- save_layer_info(layer_map);
+ if (backup_en)
+ save_layer_info(layer_map);
}
/* set hw regs */
if (osd_hw.osd_display_debug != OSD_DISP_DEBUG)
- osd_setting_blend();
+ osd_setting_blend(output_index);
+out:
/* signal out fence */
- if (timeline_created) {
+ if (timeline_created[output_index]) {
if (osd_hw.osd_debug.osd_single_step_mode) {
/* single step mode */
if (osd_hw.osd_debug.osd_single_step > 0) {
- osd_timeline_increase();
+ osd_timeline_increase(output_index);
osd_log_dbg(MODULE_FENCE, "signal out fence\n");
osd_hw.osd_debug.osd_single_step--;
} else
osd_hw.osd_debug.wait_fence_release = true;
} else
- osd_timeline_increase();
+ osd_timeline_increase(output_index);
}
/*clear last displayed buffer.*/
for (i = 0; i < HW_OSD_COUNT; i++) {
}
}
/* clear osd layer's order */
- for (i = 0; i < osd_count; i++) {
+ for (i = start_index; i < osd_count; i++) {
layer_map = &fence_map->layer_map[i];
if (layer_map->buf_file)
displayed_bufs[i] = layer_map->buf_file;
osd_hw.order[i] = 0;
}
}
+
+static void osd_pan_display_layers_fence(
+ struct osd_layers_fence_map_s *fence_map)
+{
+ u32 output_index = VIU1;
+ struct vinfo_s *vinfo = NULL;
+
+ vinfo = get_current_vinfo();
+
+ _osd_pan_display_layers_fence(output_index,
+ vinfo, fence_map);
+}
+
+static void osd_pan_display_layers_fence_viu2(
+ struct osd_layers_fence_map_s *fence_map)
+{
+ u32 output_index = VIU2;
+ struct vinfo_s *vinfo = NULL;
+
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+ vinfo = get_current_vinfo2();
+#endif
+
+ _osd_pan_display_layers_fence(output_index,
+ vinfo, fence_map);
+}
#endif
void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset)
{
long diff_x, diff_y;
+ u32 output_index;
if (index >= HW_OSD_COUNT)
return;
+ output_index = get_output_device_id(index);
if (xoffset != osd_hw.pandata[index].x_start
|| yoffset != osd_hw.pandata[index].y_start) {
diff_x = xoffset - osd_hw.pandata[index].x_start;
osd_hw.src_data[index].h = osd_hw.pandata[index].y_end
- osd_hw.pandata[index].y_start + 1;
add_to_update_list(index, DISP_GEOMETRY);
- if (osd_hw.osd_fps_start)
- osd_hw.osd_fps++;
+ if (osd_hw.osd_fps_start[output_index])
+ osd_hw.osd_fps[output_index]++;
/* osd_wait_vsync_hw(); */
}
#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
struct hw_osd_reg_s *osd_reg = &hw_osd_reg_array[index];
u32 data32 = 0x0;
u32 shift_workaround = 0;
+ u32 output_index = 0;
if (osd_hw.osd_meson_dev.osd_ver != OSD_HIGH_ONE)
osd_reg = &hw_osd_reg_array[0];
else
vf_bank_len = 4;
- if (osd_hw.hwc_enable && (index == OSD1))
+ output_index = get_output_device_id(index);
+ if (osd_hw.hwc_enable[output_index] && (index == OSD1))
shift_workaround = osd_hw.workaround_line;
#ifndef NEW_PPS_PHASE
vf_phase_step = (src_h << 20) / dst_h;
#ifdef NEW_PPS_PHASE
- if (osd_hw.field_out_en) {
+ if (osd_hw.field_out_en[output_index]) {
struct osd_f2v_vphase_s vphase;
f2v_get_vertical_phase(
bot_ini_phase = 0;
}
#else
- if (osd_hw.field_out_en) /* interface output */
+ if (osd_hw.field_out_en[output_index]) /* interface output */
bot_ini_phase = ((vf_phase_step / 2) >> 4);
else
bot_ini_phase = 0;
data32 = 0x0;
if (shift_workaround) {
vsc_ini_rcv_num++;
- if (osd_hw.field_out_en)
+ if (osd_hw.field_out_en[output_index])
vsc_bot_rcv_num++;
}
data32 |= (vf_bank_len & 0x7)
| ((vsc_ini_rcv_num & 0xf) << 3)
| ((vsc_ini_rpt_p0_num & 0x3) << 8);
- if (osd_hw.field_out_en)
+ if (osd_hw.field_out_en[output_index])
data32 |= ((vsc_bot_rcv_num & 0xf) << 11)
| ((vsc_bot_rpt_p0_num & 0x3) << 16)
| (1 << 23);
VSYNCOSD_WR_MPEG_REG(
osd_reg->osd_vsc_init_phase, data32);
}
- if ((osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE)
- && (!osd_hw.hwc_enable)) {
+ if ((osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) &&
+ (!osd_hw.hwc_enable[output_index])) {
osd_setting_blending_scope(index);
vpp_blend_setting_default(index);
}
notify_to_amvideo();
VSYNCOSD_CLR_MPEG_REG_MASK(VPP_MISC, temp_val);
}
- VSYNCOSD_CLR_MPEG_REG_MASK(
- osd_reg->osd_ctrl_stat, 1 << 0);
+ if (!(osd_hw.osd_meson_dev.cpu_id ==
+ __MESON_CPU_MAJOR_ID_G12B))
+ VSYNCOSD_CLR_MPEG_REG_MASK(
+ osd_reg->osd_ctrl_stat, 1 << 0);
}
if (osd_hw.osd_meson_dev.afbc_type == MESON_AFBC) {
if ((osd_hw.osd_afbcd[index].enable == ENABLE)
u32 data32;
enum color_index_e idx;
struct dispdata_s src_data;
- const struct vinfo_s *vinfo;
+ const struct vinfo_s *vinfo = NULL;
int out_y_crop_start, out_y_crop_end;
if (osd_hw.osd_meson_dev.cpu_id != __MESON_CPU_MAJOR_ID_G12B)
src_data.y = 0;
src_data.w = osd_hw.fb_gem[index].xres;
src_data.h = osd_hw.fb_gem[index].yres;
+ src_data.h = osd_hw.fb_gem[index].yres;
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
vinfo = get_current_vinfo2();
if (!vinfo) {
osd_log_err("current vinfo NULL\n");
return;
}
+#endif
out_y_crop_start = 0;
out_y_crop_end = vinfo->height;
src_width = src_data.w;
osd_index =
blending->osd_to_bdin_table[blend_din_index];
- if (osd_index > OSD3)
+ if (osd_index >= osd_hw.osd_meson_dev.viu1_osd_count)
return OSD_MAX;
else
return osd_index;
}
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
static u32 get_max_order(u32 order1, u32 order2)
{
u32 max_order = 0;
blending->din_reoder_sel;
}
-#else
-static void generate_blend_din_table(struct hw_osd_blending_s *blending)
+static bool is_freescale_para_changed(u32 index)
{
- int i = 0;
- int osd_count = osd_hw.osd_meson_dev.osd_count - 1;
-
- /* reorder[i] = osd[i]'s display layer */
- for (i = 0; i < OSD_BLEND_LAYERS; i++)
- blending->osd_to_bdin_table[i] = -1;
- blending->din_reoder_sel = 0;
- switch (blending->layer_cnt) {
- case 0:
- break;
- case 1:
- for (i = 0; i < osd_count; i++) {
- if (blending->reorder[i] != LAYER_UNSUPPORT) {
- /* blend_din1 */
- blending->din_reoder_sel |= (i + 1) << 0;
- /* blend_din1 -- osdx */
- blending->osd_to_bdin_table[0] = i;
- break;
- }
- }
- break;
- case 2:
- {
- int temp_index[2] = {0};
- int j = 0;
+ static int first[HW_OSD_COUNT - 1] = {1};
+ bool freescale_update = false;
- for (i = 0; i < osd_count; i++) {
- if (blending->reorder[i] != LAYER_UNSUPPORT) {
- /* save the osd index */
- temp_index[j] = i;
- j++;
- }
- }
- osd_log_dbg(MODULE_BLEND, "blend_din4==%d\n",
- blending->reorder[temp_index[0]]);
- osd_log_dbg(MODULE_BLEND, "blend_din1==%d\n",
- blending->reorder[temp_index[1]]);
- /* mode A_C */
- if (blending->osd_blend_mode == OSD_BLEND_A_C) {
- /* blend_din1 */
- blending->din_reoder_sel |= (temp_index[0] + 1) << 0;
- /* blend_din1 -- osdx */
- blending->osd_to_bdin_table[0] = temp_index[0];
- /* blend_din3 */
- blending->din_reoder_sel |= (temp_index[1] + 1) << 12;
- /* blend_din3 -- osdx */
- blending->osd_to_bdin_table[3] = temp_index[1];
- /* exchane vpp osd blend in order */
- if (blending->reorder[temp_index[0]] <
- blending->reorder[temp_index[1]]) {
- blending->b_exchange_blend_in = true;
- osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n");
- }
- } else {
- if (blending->reorder[temp_index[0]] <
- blending->reorder[temp_index[1]]) {
- /* blend_din4 */
- blending->din_reoder_sel |=
- (temp_index[0] + 1) << 12;
- /* blend_din3 -- osdx */
- blending->osd_to_bdin_table[3] = temp_index[0];
- /* blend_din1 */
- blending->din_reoder_sel |=
- (temp_index[1] + 1) << 0;
- /* blend_din1 -- osdx */
- blending->osd_to_bdin_table[0] = temp_index[1];
- blending->b_exchange_din = true;
- osd_log_dbg(MODULE_BLEND, "need exchange osd din order\n");
- } else {
- /* blend_din1 */
- blending->din_reoder_sel |=
- (temp_index[0] + 1) << 0;
- /* blend_din1 -- osdx */
- blending->osd_to_bdin_table[0] = temp_index[0];
- /* blend_din3 */
- blending->din_reoder_sel |=
- (temp_index[1] + 1) << 12;
- /* blend_din3 -- osdx */
- blending->osd_to_bdin_table[3] = temp_index[1];
- }
- }
- break;
+ if (memcmp(&(osd_hw.free_src_data[index]),
+ &osd_hw.free_src_data_backup[index],
+ sizeof(struct pandata_s)) != 0 ||
+ memcmp(&(osd_hw.free_dst_data[index]),
+ &osd_hw.free_dst_data_backup[index],
+ sizeof(struct pandata_s)) != 0) {
+ memcpy(&(osd_hw.free_src_data_backup[index]),
+ &osd_hw.free_src_data[index],
+ sizeof(struct pandata_s));
+ memcpy(&(osd_hw.free_dst_data_backup[index]),
+ &osd_hw.free_dst_data[index],
+ sizeof(struct pandata_s));
+ freescale_update = true;
}
- case 3:
- /* blend_din1 is bottom, blend_din4 is top layer */
- /* mode A_BC */
- /* osd0 always used blend_din1 */
- /* blend_din1 */
- blending->din_reoder_sel |= 1 << 0;
- /* blend_din1 -- osd1 */
- blending->osd_to_bdin_table[0] = OSD1;
- if (blending->reorder[OSD2] > blending->reorder[OSD3]) {
- /* blend_din4 */
- blending->din_reoder_sel |= (OSD3 + 1) << 12;
- /* blend_din4 -- osd3 */
- blending->osd_to_bdin_table[3] = OSD3;
-
- /* blend_din3 */
- blending->din_reoder_sel |= (OSD2 + 1) << 8;
- /* blend_din3 -- osd2 */
- blending->osd_to_bdin_table[2] = OSD2;
- } else {
- /* blend_din3 */
- blending->din_reoder_sel |= (OSD2 + 1) << 12;
- /* blend_din3 -- osd2 */
- blending->osd_to_bdin_table[3] = OSD2;
-
- /* blend_din3 */
- blending->din_reoder_sel |= (OSD3 + 1) << 8;
- /* blend_din3 -- osd2 */
- blending->osd_to_bdin_table[2] = OSD3;
-
- }
- if (blending->reorder[OSD1] < blending->reorder[OSD3]) {
- if (blending->osd_blend_mode == OSD_BLEND_A_BC) {
- blending->b_exchange_blend_in = true;
- osd_log_dbg(MODULE_BLEND, "need exchange vpp order\n");
- } else {
- u32 temp1, temp2;
-
- blending->b_exchange_din = true;
- osd_log_dbg(MODULE_BLEND, "need exchange osd din order\n");
- temp1 = blending->osd_to_bdin_table[2];
- temp2 = blending->osd_to_bdin_table[3];
- blending->osd_to_bdin_table[3] =
- blending->osd_to_bdin_table[0];
- blending->osd_to_bdin_table[2] = temp2;
- blending->osd_to_bdin_table[0] = temp1;
- temp1 = blending->din_reoder_sel & 0xf000;
- temp2 = blending->din_reoder_sel & 0x0f00;
- blending->din_reoder_sel = (1 << 12);
- blending->din_reoder_sel |= temp1 >> 4;
- blending->din_reoder_sel |= temp2 >> 8;
- }
- }
- break;
- }
- osd_log_dbg(MODULE_BLEND, "osd_to_bdin_table[i]=[%x,%x,%x,%x]\n",
- blending->osd_to_bdin_table[0],
- blending->osd_to_bdin_table[1],
- blending->osd_to_bdin_table[2],
- blending->osd_to_bdin_table[3]);
- blending->blend_reg.din_reoder_sel =
- blending->din_reoder_sel;
-}
-#endif
-static bool is_freescale_para_changed(u32 index)
-{
- static int first[HW_OSD_COUNT - 1] = {1};
- bool freescale_update = false;
-
- if (memcmp(&(osd_hw.free_src_data[index]),
- &osd_hw.free_src_data_backup[index],
- sizeof(struct pandata_s)) != 0 ||
- memcmp(&(osd_hw.free_dst_data[index]),
- &osd_hw.free_dst_data_backup[index],
- sizeof(struct pandata_s)) != 0) {
- memcpy(&(osd_hw.free_src_data_backup[index]),
- &osd_hw.free_src_data[index],
- sizeof(struct pandata_s));
- memcpy(&(osd_hw.free_dst_data_backup[index]),
- &osd_hw.free_dst_data[index],
- sizeof(struct pandata_s));
- freescale_update = true;
- }
- if (first[index])
- freescale_update = true;
- first[index] = 0;
- return freescale_update;
-}
+ if (first[index])
+ freescale_update = true;
+ first[index] = 0;
+ return freescale_update;
+}
static int osd_setting_blending_scope(u32 index)
{
u32 bld_osd_v_start, bld_osd_v_end;
u32 reg_offset = 2;
- if (index > OSD3) {
+ if (index >= osd_hw.osd_meson_dev.viu1_osd_count) {
osd_log_err("error osd index=%d\n", index);
return -1;
}
osd_log_dbg(MODULE_BASE, "vpp_blend_setting_default\n");
- if (index > OSD3) {
+ if (index >= osd_hw.osd_meson_dev.viu1_osd_count) {
osd_log_err("error osd index=%d\n", index);
return -1;
}
osd1_v_start = osd_hw.dispdata[index].y_start;
osd1_v_end = osd_hw.dispdata[index].y_end;
}
- VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE,
- osd1_dst_h | osd1_dst_v << 16);
/* setting blend scope */
VSYNCOSD_WR_MPEG_REG(VPP_OSD1_BLD_H_SCOPE,
static void set_blend_din(struct hw_osd_blending_s *blending)
{
int i = 0, osd_index;
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
/* workaround for shift issue */
/* blend_din_en must equal 5 */
u32 blend_din_en = 0x5;
-#else
- u32 blend_din_en = 0x9;
-#endif
if (!blending)
return;
static void set_blend_mode(struct hw_osd_blending_s *blending)
{
u8 osd_blend_mode = OSD_BLEND_NONE;
- //u32 osd_index;
if (!blending)
return;
if (osd_hw.hdr_used)
osd_blend_mode = OSD_BLEND_ABC;
else
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
osd_blend_mode = OSD_BLEND_AB_C;
-#else
- osd_blend_mode = OSD_BLEND_A_BC;
-#endif
break;
}
blending->osd_blend_mode = osd_blend_mode;
}
layer_blend = &(blending->layer_blend);
blend_reg = &(blending->blend_reg);
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
/* blend1_dout to blend2 */
blend_reg->din2_osd_sel = 0;
-#else
- /* input1 default route to blend1 */
- if (layer_blend->input1 & BYPASS_DIN) {
- /* blend1_dout to dout1 */
- blend_reg->din2_osd_sel = 1;
- layer_blend->input1 &= ~BYPASS_DIN;
- } else
- /* blend1_dout to blend2 */
- blend_reg->din2_osd_sel = 0;
-#endif
+
if (layer_blend->input2 & BYPASS_DIN) {
/* blend1_din3 bypass to dout1 */
blend_reg->din3_osd_sel = 1;
}
if (blend_reg->din3_osd_sel || layer_blend->input1 == BLEND_NO_DIN) {
/* blend din3 bypass,output == input */
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
if (layer_blend->input2 == BLEND_NO_DIN) {
memcpy(&layer_blend->output_data,
&layer_blend->input1_data,
sizeof(struct dispdata_s));
}
layer_blend->output_data.h += workaround_line;
-#else
- layer_blend->output_data.x = 0;
- layer_blend->output_data.y = 0;
- layer_blend->output_data.w =
- layer_blend->input2_data.x +
- layer_blend->input2_data.w;
- layer_blend->output_data.h =
- layer_blend->input2_data.y +
- layer_blend->input2_data.h;
-#endif
+
} else
calc_max_output(blending);
blend_hsize = layer_blend->output_data.w;
/* osd_blend_blend0_size share with blend2_size*/
blend_reg->osd_blend_blend0_size =
blend_vsize << 16 | blend_hsize;
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
switch (layer_blend->input2) {
case BLEND1_DIN:
blend1_input = 0;
blend1_input = 1;
break;
}
-#else
- switch (layer_blend->input2) {
- case BLEND1_DIN:
- /* blend1_dout to blend2 */
- blend_reg->din2_osd_sel = 0;
- break;
- default:
- /* blend1_dout to dout1 */
- blend_reg->din2_osd_sel = 1;
- break;
- }
- blend1_input = blend_reg->din2_osd_sel;
-#endif
+
/* premult set */
blend_reg->blend2_premult_en = 3;
if (blend1_input)
blend_vsize = layer_blend->output_data.h;
blend_reg->osd_blend_blend0_size =
blend_vsize << 16 | blend_hsize;
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
/* blend 0 and blend1 size need same */
blend_reg->osd_blend_blend1_size =
blend_reg->osd_blend_blend0_size;
-#endif
}
osd_log_dbg2(MODULE_BLEND, "layer_blend2->output_data:%d,%d,%d,%d\n",
layer_blend->output_data.x,
switch (layer_blend->input1) {
case BLEND1_DIN:
blend_reg->postbld_src3_sel = POSTBLD_OSD2;
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
if (layer_blend->blend_core1_bypass)
-#else
- if (blend_reg->din3_osd_sel)
-#endif
blend_reg->postbld_osd1_premult = 0;
else
blend_reg->postbld_osd1_premult = 1;
switch (layer_blend->input2) {
case BLEND1_DIN:
blend_reg->postbld_src4_sel = POSTBLD_OSD2;
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
if (layer_blend->blend_core1_bypass)
-#else
- if (blend_reg->din3_osd_sel)
-#endif
blend_reg->postbld_osd2_premult = 0;
else
blend_reg->postbld_osd2_premult = 1;
blend_reg->vpp_osd2_blend_v_scope);
}
-/* input w, h is background */
static void osd_set_freescale(u32 index,
struct hw_osd_blending_s *blending)
u32 width, height;
u32 src_height;
u32 workaround_line = osd_hw.workaround_line;
+ u32 output_index = 0;
layer_blend = &(blending->layer_blend);
blend_reg = &(blending->blend_reg);
- if (index > OSD3) {
+ if (index >= osd_hw.osd_meson_dev.viu1_osd_count) {
osd_log_err("error osd index=%d\n", index);
return;
}
osd_hw.free_scale[index].h_enable = 1;
osd_hw.free_scale[index].v_enable = 1;
osd_hw.free_scale_mode[index] = 1;
+ output_index = get_output_device_id(index);
if (index == OSD1) {
osd_hw.free_src_data[index].x_start =
osd_hw.free_dst_data[index].x_start = 0;
osd_hw.free_dst_data[index].y_start = 0;
- width = layer_blend->output_data.w
- * blending->screen_ratio_w >> OSD_CALC;
- height = (layer_blend->output_data.h - workaround_line)
- * blending->screen_ratio_h >> OSD_CALC;
- if (osd_hw.field_out_en)
+ width = layer_blend->output_data.w *
+ blending->screen_ratio_w_num /
+ blending->screen_ratio_w_den;
+ height = (layer_blend->output_data.h - workaround_line) *
+ blending->screen_ratio_h_num /
+ blending->screen_ratio_h_den;
+ if (osd_hw.field_out_en[output_index])
height = height >> 1;
} else {
osd_hw.free_src_data[index].x_start =
(blending->osd_blend_mode == OSD_BLEND_ABC)) {
/* combine mode, need uniformization */
osd_hw.free_dst_data[index].x_start =
- (osd_hw.dst_data[index].x << OSD_CALC) /
- blending->screen_ratio_w;
+ osd_hw.dst_data[index].x *
+ blending->screen_ratio_w_den /
+ blending->screen_ratio_w_num;
osd_hw.free_dst_data[index].y_start =
- (osd_hw.dst_data[index].y << OSD_CALC) /
- blending->screen_ratio_h;
- width = (osd_hw.dst_data[index].w << OSD_CALC) /
- blending->screen_ratio_w;
- height = (osd_hw.dst_data[index].h << OSD_CALC) /
- blending->screen_ratio_h;
+ osd_hw.dst_data[index].y *
+ blending->screen_ratio_h_den /
+ blending->screen_ratio_h_num;
+ width = osd_hw.dst_data[index].w *
+ blending->screen_ratio_w_den /
+ blending->screen_ratio_w_num;
+ height = osd_hw.dst_data[index].h *
+ blending->screen_ratio_h_den /
+ blending->screen_ratio_h_num;
if (width > FREE_SCALE_MAX_WIDTH)
width = FREE_SCALE_MAX_WIDTH;
} else if (blending->osd_blend_mode == OSD_BLEND_AB_C) {
if (blending->blend_din != BLEND_DIN4) {
/* combine mode, need uniformization */
osd_hw.free_dst_data[index].x_start =
- (osd_hw.dst_data[index].x << OSD_CALC) /
- blending->screen_ratio_w;
+ osd_hw.dst_data[index].x *
+ blending->screen_ratio_w_den /
+ blending->screen_ratio_w_num;
osd_hw.free_dst_data[index].y_start =
- (osd_hw.dst_data[index].y << OSD_CALC) /
- blending->screen_ratio_h;
- width = (osd_hw.dst_data[index].w
- << OSD_CALC) /
- blending->screen_ratio_w;
- height = (osd_hw.dst_data[index].h
- << OSD_CALC) /
- blending->screen_ratio_h;
+ osd_hw.dst_data[index].y *
+ blending->screen_ratio_h_den /
+ blending->screen_ratio_h_num;
+ width = osd_hw.dst_data[index].w *
+ blending->screen_ratio_w_den /
+ blending->screen_ratio_w_num;
+ height = osd_hw.dst_data[index].h *
+ blending->screen_ratio_h_den /
+ blending->screen_ratio_h_num;
} else {
/* direct used dst as freescale dst */
osd_hw.free_dst_data[index].x_start =
width = osd_hw.dst_data[index].w;
height = osd_hw.dst_data[index].h;
/* interleaced case */
- if (osd_hw.field_out_en) {
+ if (osd_hw.field_out_en[output_index]) {
height = height >> 1;
osd_hw.free_dst_data[index].y_start
>>= 1;
osd_hw.dst_data[index].y;
width = osd_hw.dst_data[index].w;
height = osd_hw.dst_data[index].h;
- if (osd_hw.field_out_en) {
+ if (osd_hw.field_out_en[output_index]) {
height = height >> 1;
osd_hw.free_dst_data[index].y_start >>= 1;
}
layer_blend->output_data.h);
}
-/* every output is next path input */
static void set_blend_path(struct hw_osd_blending_s *blending)
{
struct layer_blend_s *layer_blend;
struct dispdata_s output1_data;
u32 index = 0;
u8 input1 = 0, input2 = 0;
+ u32 output_index;
if (!blending)
return;
+ output_index = get_output_device_id(index);
layer_blend = &(blending->layer_blend);
blend_reg = &(blending->blend_reg);
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
layer_blend->blend_core1_bypass = 0;
-#endif
switch (blending->osd_blend_mode) {
case OSD_BLEND_NONE:
blend_reg->postbld_osd1_premult = 0;
layer_blend->input1_data.x =
osd_hw.free_dst_data[index].x_start +
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
layer_blend->input1_data.w =
osd_hw.free_dst_data[index].x_end -
osd_hw.free_dst_data[index].x_start + 1;
layer_blend->input1_data.y =
osd_hw.free_dst_data[index].y_start +
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
layer_blend->input1_data.h =
osd_hw.free_dst_data[index].y_end -
osd_hw.free_dst_data[index].y_start + 1;
"first: set osd%d freescale\n", index);
osd_set_freescale(index, blending);
osd_hw.free_dst_data[index].x_start +=
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
osd_hw.free_dst_data[index].x_end +=
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
osd_hw.free_dst_data[index].y_start +=
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
osd_hw.free_dst_data[index].y_end +=
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
osd_setting_blend0_input(index, blending);
osd_setting_blend0(blending);
index = blend_din_to_osd(input1, blending);
if (index >= OSD_MAX)
return;
-#ifndef OSD_BLEND_SHIFT_WORKAROUND
- osd_setting_blend0_input(index, blending);
-#endif
if (index != OSD1) {
/* here used freescale osd1/osd2 */
osd_log_dbg2(MODULE_BLEND,
index);
osd_set_freescale(index, blending);
}
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
osd_setting_blend0_input(index, blending);
-#endif
osd_setting_blend0(blending);
memcpy(&output1_data, &(layer_blend->output_data),
sizeof(struct dispdata_s));
}
layer_blend->input1 = BLEND_NO_DIN;
layer_blend->input2 = input2;
-#ifndef OSD_BLEND_SHIFT_WORKAROUND
- if (osd_hw.blend_bypass)
- layer_blend->input2 |= BYPASS_DIN;
-#endif
-#if 0
- layer_blend->input2_data.x =
- osd_hw.free_dst_data[index].x_start;
- layer_blend->input2_data.w =
- osd_hw.free_dst_data[index].x_end -
- osd_hw.free_dst_data[index].x_start + 1;
- layer_blend->input2_data.y =
- osd_hw.free_dst_data[index].y_start;
- layer_blend->input2_data.h =
- osd_hw.free_dst_data[index].y_end -
- osd_hw.free_dst_data[index].y_start + 1;
-#endif
+
osd_setting_blend1_input(index, blending);
memcpy(&layer_blend->input2_data,
&layer_blend->output_data,
layer_blend->input2 = BLEND_NO_DIN;
layer_blend->input1_data.x =
osd_hw.free_dst_data[OSD1].x_start +
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
layer_blend->input1_data.w =
osd_hw.free_dst_data[OSD1].x_end -
osd_hw.free_dst_data[OSD1].x_start + 1;
layer_blend->input1_data.y =
osd_hw.free_dst_data[OSD1].y_start +
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
layer_blend->input1_data.h =
osd_hw.free_dst_data[OSD1].y_end -
osd_hw.free_dst_data[OSD1].y_start + 1;
/* save freescale output */
output1_data.x =
osd_hw.free_dst_data[index].x_start +
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
output1_data.w =
osd_hw.free_dst_data[index].x_end -
osd_hw.free_dst_data[index].x_start + 1;
output1_data.y =
osd_hw.free_dst_data[index].y_start +
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
output1_data.h =
osd_hw.free_dst_data[index].y_end -
osd_hw.free_dst_data[index].y_start + 1;
osd_log_dbg2(MODULE_BLEND, "position_x=%d, y=%d\n",
- osd_hw.disp_info.position_x,
- osd_hw.disp_info.position_y);
+ osd_hw.disp_info[output_index].position_x,
+ osd_hw.disp_info[output_index].position_y);
index = blend_din_to_osd(BLEND_DIN4, blending);
if (index >= OSD_MAX)
osd_log_dbg2(MODULE_BLEND,
"before blend1: set osd%d freescale\n", index);
osd_set_freescale(index, blending);
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
layer_blend->input1 = BLEND_NO_DIN;
/* must bypass for shift workaround */
layer_blend->input2 = BLEND_DIN4 | BYPASS_DIN;
layer_blend->blend_core1_bypass = 1;
-#else
- /* always route(bypass) to dout1 */
- layer_blend->input1 = BLEND_NO_DIN | BYPASS_DIN;
- layer_blend->input2 = BLEND_DIN4;
- if (osd_hw.blend_bypass)
- layer_blend->input2 |= BYPASS_DIN;
-#endif
- #if 0
- layer_blend->input2_data.x =
- osd_hw.free_dst_data[index].x_start +
- osd_hw.disp_info.position_x;
- layer_blend->input2_data.w =
- osd_hw.free_dst_data[index].x_end -
- osd_hw.free_dst_data[index].x_start + 1;
- layer_blend->input2_data.y =
- osd_hw.free_dst_data[index].y_start +
- osd_hw.disp_info.position_y;
- layer_blend->input2_data.h =
- osd_hw.free_dst_data[index].y_end -
- osd_hw.free_dst_data[index].y_start + 1;
- #endif
osd_setting_blend1_input(index, blending);
memcpy(&layer_blend->input2_data,
&layer_blend->output_data,
sizeof(struct dispdata_s));
/* adjust offset*/
layer_blend->input2_data.x +=
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
layer_blend->input2_data.y +=
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
osd_setting_blend1(blending);
layer_blend->input2 = BLEND1_DIN;
memcpy(&layer_blend->input1_data, &output1_data,
sizeof(struct dispdata_s));
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
memcpy(&layer_blend->input2_data, &layer_blend->output_data,
sizeof(struct dispdata_s));
-#endif
osd_setting_blend2(blending);
/* used osd0 freescale */
osd_set_freescale(OSD1, blending);
layer_blend->input2 = BLEND_NO_DIN;
layer_blend->input1_data.x =
osd_hw.free_dst_data[OSD1].x_start +
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
layer_blend->input1_data.w =
osd_hw.free_dst_data[OSD1].x_end -
osd_hw.free_dst_data[OSD1].x_start + 1;
layer_blend->input1_data.y =
osd_hw.free_dst_data[OSD1].y_start +
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
layer_blend->input1_data.h =
osd_hw.free_dst_data[OSD1].y_end -
osd_hw.free_dst_data[OSD1].y_start + 1;
vpp_setting_blend(blending);
break;
- case OSD_BLEND_A_BC:
- /* blend0 -->blend2-->sc->vpp_osd1 */
- /* 2input-->sc-->blend1 -->vpp_osd2 */
+ case OSD_BLEND_A_BC:
+ /* blend0 -->blend2-->sc->vpp_osd1 */
+ /* 2input-->sc-->blend1 -->vpp_osd2 */
+ layer_blend->input1 = BLEND_DIN1;
+ if (osd_hw.blend_bypass)
+ layer_blend->input1 |= BYPASS_DIN;
+ layer_blend->input2 = BLEND_NO_DIN;
+ index = blend_din_to_osd(BLEND_DIN1, blending);
+ if (index >= OSD_MAX)
+ return;
+ osd_setting_blend0_input(index, blending);
+ osd_setting_blend0(blending);
+
+ if (!blend_reg->din0_byp_blend) {
+ layer_blend->input1 = BLEND0_DIN;
+ layer_blend->input2 = BLEND_NO_DIN;
+ memcpy(&layer_blend->input1_data,
+ &layer_blend->output_data,
+ sizeof(struct dispdata_s));
+ /* background is same with blend0's background */
+ osd_setting_blend2(blending);
+ }
+
+ osd_log_dbg(MODULE_BLEND,
+ "after blend2: set osd%d freescale\n", index);
+ osd_set_freescale(index, blending);
+ /* save freescale output */
+ output1_data.x =
+ osd_hw.free_dst_data[index].x_start +
+ osd_hw.disp_info[output_index].position_x;
+ output1_data.w =
+ osd_hw.free_dst_data[index].x_end -
+ osd_hw.free_dst_data[index].x_start + 1;
+ output1_data.y =
+ osd_hw.free_dst_data[index].y_start +
+ osd_hw.disp_info[output_index].position_y;
+ output1_data.h =
+ osd_hw.free_dst_data[index].y_end -
+ osd_hw.free_dst_data[index].y_start + 1;
+ index = blend_din_to_osd(BLEND_DIN3, blending);
+ if (index >= OSD_MAX)
+ return;
+ osd_log_dbg2(MODULE_BLEND,
+ "before blend1: set osd%d freescale\n", index);
+ osd_set_freescale(index, blending);
+ layer_blend->input1_data.x =
+ osd_hw.free_dst_data[index].x_start +
+ osd_hw.disp_info[output_index].position_x;
+ layer_blend->input1_data.w =
+ osd_hw.free_dst_data[index].x_end -
+ osd_hw.free_dst_data[index].x_start + 1;
+ layer_blend->input1_data.y =
+ osd_hw.free_dst_data[index].y_start +
+ osd_hw.disp_info[output_index].position_y;
+ layer_blend->input1_data.h =
+ osd_hw.free_dst_data[index].y_end -
+ osd_hw.free_dst_data[index].y_start + 1;
+
+ index = blend_din_to_osd(BLEND_DIN4, blending);
+ if (index >= OSD_MAX)
+ return;
+ osd_log_dbg2(MODULE_BLEND,
+ "before blend1: set osd%d freescale\n", index);
+ osd_set_freescale(index, blending);
+ layer_blend->input2_data.x =
+ osd_hw.free_dst_data[index].x_start +
+ osd_hw.disp_info[output_index].position_x;
+ layer_blend->input2_data.w =
+ osd_hw.free_dst_data[index].x_end -
+ osd_hw.free_dst_data[index].x_start + 1;
+ layer_blend->input2_data.y =
+ osd_hw.free_dst_data[index].y_start +
+ osd_hw.disp_info[output_index].position_y;
+ layer_blend->input2_data.h =
+ osd_hw.free_dst_data[index].y_end -
+ osd_hw.free_dst_data[index].y_start + 1;
+
+ /* always route(bypass) to dout1 */
+ layer_blend->input1 = BLEND_DIN3 | BYPASS_DIN;
+ layer_blend->input2 = BLEND_DIN4;
+
+ osd_setting_blend1(blending);
+
+ if (!blending->b_exchange_blend_in) {
+ layer_blend->input1 = BLEND2_DIN;
+ layer_blend->input2 = BLEND1_DIN;
+ memcpy(&layer_blend->input1_data, &output1_data,
+ sizeof(struct dispdata_s));
+ memcpy(&layer_blend->input2_data,
+ &layer_blend->output_data,
+ sizeof(struct dispdata_s));
+ } else {
+ layer_blend->input1 = BLEND1_DIN;
+ layer_blend->input2 = BLEND2_DIN;
+ memcpy(&layer_blend->input1_data,
+ &layer_blend->output_data,
+ sizeof(struct dispdata_s));
+ memcpy(&layer_blend->input2_data,
+ &output1_data,
+ sizeof(struct dispdata_s));
+ }
+ vpp_setting_blend(blending);
+ break;
+ case OSD_BLEND_AB_C:
+ /* blend0 -->blend2-->sc->vpp_osd1 */
+ /* sc-->blend1-->blend2-->sc-->vpp_osd1 */
+ /* sc -->vpp_osd2 */
+ layer_blend->input1 = BLEND_DIN1;
+ layer_blend->input2 = BLEND_NO_DIN;
+ blending->blend_din = BLEND_DIN1;
+ index = blend_din_to_osd(BLEND_DIN1, blending);
+ if (index != OSD1) {
+ osd_log_info("index=%d, need set freescale\n", index);
+ osd_set_freescale(index, blending);
+ }
+ osd_setting_blend0_input(index, blending);
+ osd_setting_blend0(blending);
+ /* save blend0 output */
+ memcpy(&output1_data, &(layer_blend->output_data),
+ sizeof(struct dispdata_s));
+
+ /* din3 input to blend1 */
+ layer_blend->input1 = BLEND_DIN3;
+ layer_blend->input2 = BLEND_NO_DIN | BYPASS_DIN;
+ layer_blend->blend_core1_bypass = 1;
+ blending->blend_din = BLEND_DIN3;
+ index = blend_din_to_osd(BLEND_DIN3, blending);
+ if (index != OSD1) {
+ osd_log_dbg2(MODULE_BLEND,
+ "before blend1: set osd%d freescale\n",
+ index);
+ osd_set_freescale(index, blending);
+ }
+ osd_setting_blend1_input(index, blending);
+ memcpy(&layer_blend->input1_data,
+ &layer_blend->output_data,
+ sizeof(struct dispdata_s));
+ osd_setting_blend1(blending);
+
+ /* din1=>blend0 & din3-> blend1 ==> blend2 */
+ layer_blend->input1 = BLEND0_DIN;
+ layer_blend->input2 = BLEND1_DIN;
+ memcpy(&layer_blend->input1_data, &output1_data,
+ sizeof(struct dispdata_s));
+ memcpy(&layer_blend->input2_data, &layer_blend->output_data,
+ sizeof(struct dispdata_s));
+ osd_setting_blend2(blending);
+
+ /* blend2 ==> osd0 freescale */
+ osd_set_freescale(OSD1, blending);
+ output1_data.x =
+ osd_hw.free_dst_data[OSD1].x_start +
+ osd_hw.disp_info[output_index].position_x;
+ output1_data.w =
+ osd_hw.free_dst_data[OSD1].x_end -
+ osd_hw.free_dst_data[OSD1].x_start + 1;
+ output1_data.y =
+ osd_hw.free_dst_data[OSD1].y_start +
+ osd_hw.disp_info[output_index].position_y;
+ output1_data.h =
+ osd_hw.free_dst_data[OSD1].y_end -
+ osd_hw.free_dst_data[OSD1].y_start + 1;
+ osd_log_dbg2(MODULE_BLEND, "output1_data:%d,%d,%d,%d\n",
+ output1_data.x,
+ output1_data.w,
+ output1_data.y,
+ output1_data.h);
+
+
+ /* din4 ==> vpp */
+ index = blend_din_to_osd(BLEND_DIN4, blending);
+ blending->blend_din = BLEND_DIN4;
+ osd_log_dbg2(MODULE_BLEND,
+ "bypass blend1: set osd%d freescale\n", index);
+ osd_set_freescale(index, blending);
+
+ layer_blend->input2_data.x =
+ osd_hw.free_dst_data[index].x_start +
+ osd_hw.disp_info[output_index].position_x;
+ layer_blend->input2_data.w =
+ osd_hw.free_dst_data[index].x_end -
+ osd_hw.free_dst_data[index].x_start + 1;
+ layer_blend->input2_data.y =
+ osd_hw.free_dst_data[index].y_start +
+ osd_hw.disp_info[output_index].position_y;
+ layer_blend->input2_data.h =
+ osd_hw.free_dst_data[index].y_end -
+ osd_hw.free_dst_data[index].y_start + 1;
+
+ /* 2vpp input */
+ if (!blending->b_exchange_blend_in) {
+ layer_blend->input1 = BLEND2_DIN;
+ layer_blend->input2 = BLEND1_DIN;
+ memcpy(&layer_blend->input1_data, &output1_data,
+ sizeof(struct dispdata_s));
+ } else {
+ layer_blend->input1 = BLEND1_DIN;
+ layer_blend->input2 = BLEND2_DIN;
+ memcpy(&layer_blend->input1_data,
+ &layer_blend->input2_data,
+ sizeof(struct dispdata_s));
+ memcpy(&layer_blend->input2_data,
+ &output1_data,
+ sizeof(struct dispdata_s));
+ }
+ vpp_setting_blend(blending);
+ break;
+ }
+}
+
+static void osd_setting_blend0_new(struct hw_osd_blending_s *blending)
+{
+ struct layer_blend_reg_s *blend_reg;
+ struct layer_blend_s *layer_blend;
+ u32 index = 0;
+ u32 bld_osd_h_start = 0, bld_osd_h_end = 0;
+ u32 bld_osd_v_start = 0, bld_osd_v_end = 0;
+
+ if (!blending)
+ return;
+ layer_blend = &(blending->layer_blend);
+ blend_reg = &(blending->blend_reg);
+ /* blend0 only accept input1 */
+ if (layer_blend->input1 & BYPASS_DIN) {
+ blend_reg->din0_byp_blend = 1;
+ layer_blend->input1 &= ~BYPASS_DIN;
+ } else
+ blend_reg->din0_byp_blend = 0;
+ if (layer_blend->input1 != BLEND_NO_DIN) {
+ /* calculate osd blend din scope */
+ index = blend_din_to_osd(layer_blend->input1, blending);
+ if (index >= OSD_MAX)
+ return;
+ layer_blend->input1_data.x =
+ osd_hw.free_dst_data[index].x_start;
+ layer_blend->input1_data.y =
+ osd_hw.free_dst_data[index].y_start;
+ layer_blend->input1_data.w =
+ osd_hw.free_dst_data[index].x_end -
+ osd_hw.free_dst_data[index].x_start + 1;
+ layer_blend->input1_data.h =
+ osd_hw.free_dst_data[index].y_end -
+ osd_hw.free_dst_data[index].y_start + 1;
+
+ bld_osd_h_start =
+ layer_blend->input1_data.x;
+ bld_osd_h_end =
+ layer_blend->input1_data.x +
+ layer_blend->input1_data.w - 1;
+ bld_osd_v_start =
+ layer_blend->input1_data.y;
+ bld_osd_v_end =
+ layer_blend->input1_data.y +
+ layer_blend->input1_data.h - 1;
+ blend_reg->osd_blend_din_scope_h[index] =
+ bld_osd_h_end << 16 | bld_osd_h_start;
+ blend_reg->osd_blend_din_scope_v[index] =
+ bld_osd_v_end << 16 | bld_osd_v_start;
+ }
+ layer_blend->output_data.x = 0;
+ layer_blend->output_data.y = 0;
+ layer_blend->output_data.w = layer_blend->input1_data.x
+ + layer_blend->input1_data.w;
+ layer_blend->output_data.h = layer_blend->input1_data.y
+ + layer_blend->input1_data.h;
+ osd_log_dbg2(MODULE_BLEND,
+ "blend0:input1_data[osd%d]:%d,%d,%d,%d\n",
+ index,
+ layer_blend->input1_data.x,
+ layer_blend->input1_data.y,
+ layer_blend->input1_data.w,
+ layer_blend->input1_data.h);
+ osd_log_dbg2(MODULE_BLEND,
+ "blend0:layer_blend->output_data:%d,%d,%d,%d\n",
+ layer_blend->output_data.x,
+ layer_blend->output_data.y,
+ layer_blend->output_data.w,
+ layer_blend->output_data.h);
+}
+
+static void osd_setting_blend1_new(struct hw_osd_blending_s *blending)
+{
+ struct layer_blend_s *layer_blend;
+ struct layer_blend_reg_s *blend_reg;
+ u32 index = 0;
+ u32 blend_hsize, blend_vsize;
+ u32 bld_osd_h_start = 0, bld_osd_h_end = 0;
+ u32 bld_osd_v_start = 0, bld_osd_v_end = 0;
+ /* for g12a blend shift issue */
+
+ if (!blending)
+ return;
+ layer_blend = &(blending->layer_blend);
+ blend_reg = &(blending->blend_reg);
+ /* blend1_dout to blend2 */
+ blend_reg->din2_osd_sel = 0;
+
+ if (layer_blend->input2 & BYPASS_DIN) {
+ /* blend1_din3 bypass to dout1 */
+ blend_reg->din3_osd_sel = 1;
+ layer_blend->input2 &= ~BYPASS_DIN;
+ } else
+ /* blend1_din3 input to blend1 */
+ blend_reg->din3_osd_sel = 0;
+
+ if (layer_blend->input1 != BLEND_NO_DIN) {
+ index = blend_din_to_osd(layer_blend->input1, blending);
+ if (index >= OSD_MAX)
+ return;
+ layer_blend->input1_data.x =
+ osd_hw.free_dst_data[index].x_start;
+ layer_blend->input1_data.y =
+ osd_hw.free_dst_data[index].y_start;
+ layer_blend->input1_data.w =
+ osd_hw.free_dst_data[index].x_end -
+ osd_hw.free_dst_data[index].x_start + 1;
+ layer_blend->input1_data.h =
+ osd_hw.free_dst_data[index].y_end -
+ osd_hw.free_dst_data[index].y_start + 1;
+
+ /* calculate osd blend din scope */
+ bld_osd_h_start =
+ layer_blend->input1_data.x;
+ bld_osd_h_end =
+ layer_blend->input1_data.x +
+ layer_blend->input1_data.w - 1;
+ bld_osd_v_start =
+ layer_blend->input1_data.y;
+ bld_osd_v_end =
+ layer_blend->input1_data.y +
+ layer_blend->input1_data.h - 1;
+ blend_reg->osd_blend_din_scope_h[index] =
+ bld_osd_h_end << 16 | bld_osd_h_start;
+ blend_reg->osd_blend_din_scope_v[index] =
+ bld_osd_v_end << 16 | bld_osd_v_start;
+ osd_log_dbg2(MODULE_BLEND,
+ "blend1:input1_data(osd%d):%d,%d,%d,%d\n",
+ index,
+ layer_blend->input1_data.x,
+ layer_blend->input1_data.y,
+ layer_blend->input1_data.w,
+ layer_blend->input1_data.h);
+ }
+ if (layer_blend->input2 != BLEND_NO_DIN) {
+ index = blend_din_to_osd(layer_blend->input2, blending);
+ if (index >= OSD_MAX)
+ return;
+ layer_blend->input2_data.x =
+ osd_hw.free_dst_data[index].x_start;
+ layer_blend->input2_data.y =
+ osd_hw.free_dst_data[index].y_start;
+ layer_blend->input2_data.w =
+ osd_hw.free_dst_data[index].x_end -
+ osd_hw.free_dst_data[index].x_start + 1;
+ layer_blend->input2_data.h =
+ osd_hw.free_dst_data[index].y_end -
+ osd_hw.free_dst_data[index].y_start + 1;
+ /* calculate osd blend din scope */
+ bld_osd_h_start =
+ layer_blend->input2_data.x;
+ bld_osd_h_end =
+ layer_blend->input2_data.x +
+ layer_blend->input2_data.w - 1;
+ bld_osd_v_start =
+ layer_blend->input2_data.y;
+ bld_osd_v_end =
+ layer_blend->input2_data.y +
+ layer_blend->input2_data.h - 1;
+ blend_reg->osd_blend_din_scope_h[index] =
+ bld_osd_h_end << 16 | bld_osd_h_start;
+ blend_reg->osd_blend_din_scope_v[index] =
+ bld_osd_v_end << 16 | bld_osd_v_start;
+ osd_log_dbg2(MODULE_BLEND,
+ "layer_blend->input2_data:%d,%d,%d,%d\n",
+ layer_blend->input2_data.x,
+ layer_blend->input2_data.y,
+ layer_blend->input2_data.w,
+ layer_blend->input2_data.h);
+ }
+ if (blend_reg->din3_osd_sel || layer_blend->input1 == BLEND_NO_DIN) {
+ /* blend din3 bypass,output == input */
+ if (layer_blend->input2 == BLEND_NO_DIN) {
+ memcpy(&layer_blend->output_data,
+ &layer_blend->input1_data,
+ sizeof(struct dispdata_s));
+ } else {
+ memcpy(&layer_blend->output_data,
+ &layer_blend->input2_data,
+ sizeof(struct dispdata_s));
+ }
+ } else
+ calc_max_output(blending);
+ blend_hsize = layer_blend->output_data.w;
+ blend_vsize = layer_blend->output_data.h;
+ blend_reg->osd_blend_blend1_size =
+ blend_vsize << 16 | blend_hsize;
+
+ osd_log_dbg2(MODULE_BLEND, "layer_blend1->output_data:%d,%d,%d,%d\n",
+ layer_blend->output_data.x,
+ layer_blend->output_data.y,
+ layer_blend->output_data.w,
+ layer_blend->output_data.h);
+}
+
+/* input w, h is background */
+static void osd_set_freescale_new(u32 index,
+ struct hw_osd_blending_s *blending)
+
+{
+ struct layer_blend_s *layer_blend;
+ struct layer_blend_reg_s *blend_reg;
+ u32 width, height;
+ u32 src_height;
+ u32 output_index;
+
+ layer_blend = &(blending->layer_blend);
+ blend_reg = &(blending->blend_reg);
+ if (index >= osd_hw.osd_meson_dev.viu1_osd_count) {
+ osd_log_err("error osd index=%d\n", index);
+ return;
+ }
+ output_index = get_output_device_id(index);
+ osd_hw.free_scale_enable[index] = 0x10001;
+ osd_hw.free_scale[index].h_enable = 1;
+ osd_hw.free_scale[index].v_enable = 1;
+ osd_hw.free_scale_mode[index] = 1;
+
+ osd_hw.free_src_data[index].x_start =
+ osd_hw.src_data[index].x;
+ osd_hw.free_src_data[index].x_end =
+ osd_hw.src_data[index].x +
+ osd_hw.src_data[index].w - 1;
+ osd_hw.free_src_data[index].y_start =
+ osd_hw.src_data[index].y;
+ osd_hw.free_src_data[index].y_end =
+ osd_hw.src_data[index].y +
+ osd_hw.src_data[index].h - 1;
+
+ /* direct used dst as freescale dst */
+ osd_hw.free_dst_data[index].x_start =
+ osd_hw.dst_data[index].x;
+ osd_hw.free_dst_data[index].y_start =
+ osd_hw.dst_data[index].y;
+ width = osd_hw.dst_data[index].w;
+ height = osd_hw.dst_data[index].h;
+ if (osd_hw.field_out_en[output_index]) {
+ height = height >> 1;
+ osd_hw.free_dst_data[index].y_start >>= 1;
+ }
+ osd_hw.free_dst_data[index].x_end =
+ osd_hw.free_dst_data[index].x_start +
+ width - 1;
+ osd_hw.free_dst_data[index].y_end =
+ osd_hw.free_dst_data[index].y_start +
+ height - 1;
+
+ src_height = osd_hw.free_src_data[index].x_end -
+ osd_hw.free_src_data[index].x_start + 1;
+ osd_set_dummy_data(index, 0xff);
+ osd_log_dbg2(MODULE_BLEND, "osd%d:free_src_data:%d,%d,%d,%d\n",
+ index,
+ osd_hw.free_src_data[index].x_start,
+ osd_hw.free_src_data[index].y_start,
+ osd_hw.free_src_data[index].x_end,
+ osd_hw.free_src_data[index].y_end);
+ osd_log_dbg2(MODULE_BLEND, "osd%d:free_dst_data:%d,%d,%d,%d\n",
+ index,
+ osd_hw.free_dst_data[index].x_start,
+ osd_hw.free_dst_data[index].y_start,
+ osd_hw.free_dst_data[index].x_end,
+ osd_hw.free_dst_data[index].y_end);
+}
+
+/* every output is next path input */
+static void set_blend_path_new(struct hw_osd_blending_s *blending)
+{
+ struct layer_blend_s *layer_blend;
+ struct layer_blend_reg_s *blend_reg;
+ struct dispdata_s output1_data;
+ u32 index = 0;
+ u8 input1 = 0, input2 = 0;
+ u32 output_index;
+
+ if (!blending)
+ return;
+ output_index = get_output_device_id(index);
+
+ layer_blend = &(blending->layer_blend);
+ blend_reg = &(blending->blend_reg);
+ layer_blend->blend_core1_bypass = 0;
+ switch (blending->osd_blend_mode) {
+ case OSD_BLEND_NONE:
+ blend_reg->postbld_osd1_premult = 0;
+ blend_reg->postbld_src4_sel = POSTBLD_CLOSE;
+ blend_reg->postbld_src3_sel = POSTBLD_CLOSE;
+ blend_reg->postbld_osd2_premult = 0;
+ break;
+ case OSD_BLEND_A:
+ /* sc-->blend0-->blend2-->vpp_osd1 */
+ layer_blend->input1 = BLEND_DIN1;
+ if (osd_hw.blend_bypass)
+ layer_blend->input1 |= BYPASS_DIN;
+ layer_blend->input2 = BLEND_NO_DIN;
+ index = blend_din_to_osd(BLEND_DIN1, blending);
+ if (index >= OSD_MAX)
+ return;
+ osd_set_freescale_new(index, blending);
+ osd_setting_blend0_new(blending);
+ if (!blend_reg->din0_byp_blend) {
+ layer_blend->input1 = BLEND0_DIN;
+ layer_blend->input2 = BLEND_NO_DIN;
+ memcpy(&layer_blend->input1_data,
+ &layer_blend->output_data,
+ sizeof(struct dispdata_s));
+ /* same with blend0's background */
+ osd_setting_blend2(blending);
+ }
+ layer_blend->input1 = BLEND2_DIN;
+ layer_blend->input2 = BLEND_NO_DIN;
+ memcpy(&(layer_blend->input1_data),
+ &(layer_blend->output_data),
+ sizeof(struct dispdata_s));
+ layer_blend->input1_data.x +=
+ osd_hw.disp_info[output_index].position_x;
+ layer_blend->input1_data.y +=
+ osd_hw.disp_info[output_index].position_y;
+ vpp_setting_blend(blending);
+ break;
+ case OSD_BLEND_AC:
+ /* sc-->blend0 -->blend1-->blend2-->vpp_osd1 */
+ /* sc-->blend0 & blend1-->blend2-->vpp_osd1 */
+ if (!blending->b_exchange_din) {
+ input1 = BLEND_DIN1;
+ input2 = BLEND_DIN4;
+ } else {
+ input1 = BLEND_DIN4;
+ input2 = BLEND_DIN1;
+ }
+ layer_blend->input1 = input1;
+ layer_blend->input2 = BLEND_NO_DIN;
+ index = blend_din_to_osd(input1, blending);
+ if (index >= OSD_MAX)
+ return;
+ osd_set_freescale_new(index, blending);
+ osd_setting_blend0_new(blending);
+ /* save blend0 output */
+ memcpy(&output1_data, &(layer_blend->output_data),
+ sizeof(struct dispdata_s));
+
+ index = blend_din_to_osd(input2, blending);
+ if (index >= OSD_MAX)
+ return;
+ osd_set_freescale_new(index, blending);
+ layer_blend->input1 = BLEND_NO_DIN;
+ layer_blend->input2 = input2;
+ osd_setting_blend1_new(blending);
+
+ layer_blend->input1 = BLEND0_DIN;
+ layer_blend->input2 = BLEND1_DIN;
+
+ /* blend0 output-> blend2 input1 */
+ memcpy(&layer_blend->input1_data, &output1_data,
+ sizeof(struct dispdata_s));
+ /* blend1 output-> blend2 input2 */
+ memcpy(&layer_blend->input2_data, &layer_blend->output_data,
+ sizeof(struct dispdata_s));
+ osd_setting_blend2(blending);
+
+ layer_blend->input1 = BLEND2_DIN;
+ layer_blend->input2 = BLEND_NO_DIN;
+ memcpy(&(layer_blend->input1_data),
+ &(layer_blend->output_data),
+ sizeof(struct dispdata_s));
+ layer_blend->input1_data.x +=
+ osd_hw.disp_info[output_index].position_x;
+ layer_blend->input1_data.y +=
+ osd_hw.disp_info[output_index].position_y;
+ vpp_setting_blend(blending);
+ break;
+ case OSD_BLEND_A_C:
+ /* sc-->blend0 -->blend2->vpp_osd1 */
+ /* sc-->blend1 -->vpp_osd2 */
layer_blend->input1 = BLEND_DIN1;
if (osd_hw.blend_bypass)
layer_blend->input1 |= BYPASS_DIN;
index = blend_din_to_osd(BLEND_DIN1, blending);
if (index >= OSD_MAX)
return;
- osd_setting_blend0_input(index, blending);
- osd_setting_blend0(blending);
-
+ osd_set_freescale_new(index, blending);
+ osd_setting_blend0_new(blending);
if (!blend_reg->din0_byp_blend) {
layer_blend->input1 = BLEND0_DIN;
layer_blend->input2 = BLEND_NO_DIN;
/* background is same with blend0's background */
osd_setting_blend2(blending);
}
-
- osd_log_dbg(MODULE_BLEND,
- "after blend2: set osd%d freescale\n", index);
- osd_set_freescale(index, blending);
- /* save freescale output */
- output1_data.x =
- osd_hw.free_dst_data[index].x_start +
- osd_hw.disp_info.position_x;
- output1_data.w =
- osd_hw.free_dst_data[index].x_end -
- osd_hw.free_dst_data[index].x_start + 1;
- output1_data.y =
- osd_hw.free_dst_data[index].y_start +
- osd_hw.disp_info.position_y;
- output1_data.h =
- osd_hw.free_dst_data[index].y_end -
- osd_hw.free_dst_data[index].y_start + 1;
- index = blend_din_to_osd(BLEND_DIN3, blending);
- if (index >= OSD_MAX)
- return;
- osd_log_dbg2(MODULE_BLEND,
- "before blend1: set osd%d freescale\n", index);
- osd_set_freescale(index, blending);
- layer_blend->input1_data.x =
- osd_hw.free_dst_data[index].x_start +
- osd_hw.disp_info.position_x;
- layer_blend->input1_data.w =
- osd_hw.free_dst_data[index].x_end -
- osd_hw.free_dst_data[index].x_start + 1;
- layer_blend->input1_data.y =
- osd_hw.free_dst_data[index].y_start +
- osd_hw.disp_info.position_y;
- layer_blend->input1_data.h =
- osd_hw.free_dst_data[index].y_end -
- osd_hw.free_dst_data[index].y_start + 1;
+ /* save blend0/blend2 output */
+ memcpy(&output1_data, &(layer_blend->output_data),
+ sizeof(struct dispdata_s));
+ /* adjust input 1 offset*/
+ output1_data.x +=
+ osd_hw.disp_info[output_index].position_x;
+ output1_data.y +=
+ osd_hw.disp_info[output_index].position_y;
index = blend_din_to_osd(BLEND_DIN4, blending);
if (index >= OSD_MAX)
return;
- osd_log_dbg2(MODULE_BLEND,
- "before blend1: set osd%d freescale\n", index);
- osd_set_freescale(index, blending);
- layer_blend->input2_data.x =
- osd_hw.free_dst_data[index].x_start +
- osd_hw.disp_info.position_x;
- layer_blend->input2_data.w =
- osd_hw.free_dst_data[index].x_end -
- osd_hw.free_dst_data[index].x_start + 1;
- layer_blend->input2_data.y =
- osd_hw.free_dst_data[index].y_start +
- osd_hw.disp_info.position_y;
- layer_blend->input2_data.h =
- osd_hw.free_dst_data[index].y_end -
- osd_hw.free_dst_data[index].y_start + 1;
-
- /* always route(bypass) to dout1 */
- layer_blend->input1 = BLEND_DIN3 | BYPASS_DIN;
- layer_blend->input2 = BLEND_DIN4;
-
- osd_setting_blend1(blending);
+ osd_set_freescale_new(index, blending);
+ layer_blend->input1 = BLEND_NO_DIN;
+ layer_blend->input2 = BLEND_DIN4 | BYPASS_DIN;
+ layer_blend->blend_core1_bypass = 1;
+ osd_setting_blend1_new(blending);
+ /* adjust input 2 offset*/
+ layer_blend->output_data.x +=
+ osd_hw.disp_info[output_index].position_x;
+ layer_blend->output_data.y +=
+ osd_hw.disp_info[output_index].position_y;
if (!blending->b_exchange_blend_in) {
layer_blend->input1 = BLEND2_DIN;
memcpy(&layer_blend->input1_data,
&layer_blend->output_data,
sizeof(struct dispdata_s));
- memcpy(&layer_blend->input2_data,
- &output1_data,
+ memcpy(&layer_blend->input2_data, &output1_data,
sizeof(struct dispdata_s));
}
vpp_setting_blend(blending);
break;
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
+ case OSD_BLEND_ABC:
+ /* sc->blend0 -->blend2-->vpp_osd1 */
+ /* sc-->blend1 -->blend2 */
+ input1 = BLEND_DIN1;
+ input2 = BLEND_DIN4;
+ layer_blend->input1 = input1;
+ layer_blend->input2 = BLEND_NO_DIN;
+ index = blend_din_to_osd(input1, blending);
+ if (index >= OSD_MAX)
+ return;
+ osd_set_freescale_new(index, blending);
+ osd_setting_blend0_new(blending);
+ /* save blend0 output */
+ memcpy(&output1_data, &(layer_blend->output_data),
+ sizeof(struct dispdata_s));
+
+ layer_blend->input1 = BLEND_DIN3;
+ layer_blend->input2 = input2;
+ index = blend_din_to_osd(layer_blend->input1, blending);
+ osd_set_freescale_new(index, blending);
+ index = blend_din_to_osd(layer_blend->input2, blending);
+ osd_set_freescale_new(index, blending);
+ osd_setting_blend1_new(blending);
+
+ layer_blend->input1 = BLEND0_DIN;
+ layer_blend->input2 = BLEND1_DIN;
+ memcpy(&layer_blend->input1_data, &output1_data,
+ sizeof(struct dispdata_s));
+ memcpy(&layer_blend->input2_data, &layer_blend->output_data,
+ sizeof(struct dispdata_s));
+ osd_setting_blend2(blending);
+
+ layer_blend->input1 = BLEND2_DIN;
+ layer_blend->input2 = BLEND_NO_DIN;
+ memcpy(&(layer_blend->input1_data),
+ &(layer_blend->output_data),
+ sizeof(struct dispdata_s));
+ layer_blend->input1_data.x +=
+ osd_hw.disp_info[output_index].position_x;
+ layer_blend->input1_data.y +=
+ osd_hw.disp_info[output_index].position_y;
+ vpp_setting_blend(blending);
+ break;
case OSD_BLEND_AB_C:
- /* blend0 -->blend2-->sc->vpp_osd1 */
- /* sc-->blend1-->blend2-->sc-->vpp_osd1 */
+ /* sc-->blend0 -->blend2->vpp_osd1 */
+ /* sc-->blend1-->blend2-->vpp_osd1 */
/* sc -->vpp_osd2 */
layer_blend->input1 = BLEND_DIN1;
layer_blend->input2 = BLEND_NO_DIN;
blending->blend_din = BLEND_DIN1;
index = blend_din_to_osd(BLEND_DIN1, blending);
- if (index != OSD1) {
- osd_log_info("index=%d, need set freescale\n", index);
- osd_set_freescale(index, blending);
- }
- osd_setting_blend0_input(index, blending);
- osd_setting_blend0(blending);
+ if (index >= OSD_MAX)
+ return;
+ osd_set_freescale_new(index, blending);
+ osd_setting_blend0_new(blending);
/* save blend0 output */
memcpy(&output1_data, &(layer_blend->output_data),
sizeof(struct dispdata_s));
layer_blend->blend_core1_bypass = 1;
blending->blend_din = BLEND_DIN3;
index = blend_din_to_osd(BLEND_DIN3, blending);
- if (index != OSD1) {
- osd_log_dbg2(MODULE_BLEND,
- "before blend1: set osd%d freescale\n",
- index);
- osd_set_freescale(index, blending);
- }
- osd_setting_blend1_input(index, blending);
- memcpy(&layer_blend->input1_data,
- &layer_blend->output_data,
- sizeof(struct dispdata_s));
- osd_setting_blend1(blending);
+ osd_set_freescale_new(index, blending);
+ osd_setting_blend1_new(blending);
/* din1=>blend0 & din3-> blend1 ==> blend2 */
layer_blend->input1 = BLEND0_DIN;
memcpy(&layer_blend->input2_data, &layer_blend->output_data,
sizeof(struct dispdata_s));
osd_setting_blend2(blending);
-
- /* blend2 ==> osd0 freescale */
- osd_set_freescale(OSD1, blending);
- output1_data.x =
- osd_hw.free_dst_data[OSD1].x_start +
- osd_hw.disp_info.position_x;
- output1_data.w =
- osd_hw.free_dst_data[OSD1].x_end -
- osd_hw.free_dst_data[OSD1].x_start + 1;
- output1_data.y =
- osd_hw.free_dst_data[OSD1].y_start +
- osd_hw.disp_info.position_y;
- output1_data.h =
- osd_hw.free_dst_data[OSD1].y_end -
- osd_hw.free_dst_data[OSD1].y_start + 1;
+ memcpy(&output1_data, &(layer_blend->output_data),
+ sizeof(struct dispdata_s));
+ output1_data.x +=
+ osd_hw.disp_info[output_index].position_x;
+ output1_data.y +=
+ osd_hw.disp_info[output_index].position_y;
osd_log_dbg2(MODULE_BLEND, "output1_data:%d,%d,%d,%d\n",
output1_data.x,
output1_data.w,
/* din4 ==> vpp */
index = blend_din_to_osd(BLEND_DIN4, blending);
blending->blend_din = BLEND_DIN4;
- osd_log_dbg2(MODULE_BLEND,
- "bypass blend1: set osd%d freescale\n", index);
- osd_set_freescale(index, blending);
-
+ osd_set_freescale_new(index, blending);
layer_blend->input2_data.x =
osd_hw.free_dst_data[index].x_start +
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
layer_blend->input2_data.w =
osd_hw.free_dst_data[index].x_end -
osd_hw.free_dst_data[index].x_start + 1;
layer_blend->input2_data.y =
osd_hw.free_dst_data[index].y_start +
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
layer_blend->input2_data.h =
osd_hw.free_dst_data[index].y_end -
osd_hw.free_dst_data[index].y_start + 1;
}
vpp_setting_blend(blending);
break;
-#endif
}
}
int i;
u32 reg_offset = 2;
u32 osd1_alpha_div = 0, osd2_alpha_div = 0;
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
u32 osd_count = OSD_BLEND_LAYERS;
-#else
- u32 osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
-#endif
u32 dv_core2_hsize;
u32 dv_core2_vsize;
if (!blend_reg)
return;
+ /* osd0 scale position before osd blend */
+ if (osd_hw.osd_meson_dev.osd0_sc_independ)
+ VSYNCOSD_WR_MPEG_REG(VPP_OSD_SCALE_CTRL, 0x01);
+
/* osd blend ctrl */
VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_CTRL,
4 << 29|
VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND0_SIZE,
blend_reg->osd_blend_blend0_size);
+ /* hdr input size should set to osd blend0 output size */
+ VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE,
+ blend_reg->osd_blend_blend0_size);
+
VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND1_SIZE,
blend_reg->osd_blend_blend1_size);
VIU_OSD_BLEND_DIN0_SCOPE_V + reg_offset * i,
blend_reg->osd_blend_din_scope_v[i]);
}
-#ifdef OSD_BLEND_SHIFT_WORKAROUND
else {
if ((blend_reg->osd_blend_din_scope_v[i] & 0xffff) == 0)
blend_reg->osd_blend_din_scope_v[i] = 0x43a0439;
VIU_OSD_BLEND_DIN0_SCOPE_V + reg_offset * i,
blend_reg->osd_blend_din_scope_v[i]);
}
-#endif
}
dv_core2_vsize = (blend_reg->osd_blend_blend0_size >> 16) & 0xfff;
static void uniformization_fb(u32 index,
struct hw_osd_blending_s *blending)
{
- blending->dst_data.x = (osd_hw.dst_data[index].x << OSD_CALC) /
- blending->screen_ratio_w;
- blending->dst_data.y = (osd_hw.dst_data[index].y << OSD_CALC) /
- blending->screen_ratio_h;
- blending->dst_data.w = (osd_hw.dst_data[index].w << OSD_CALC) /
- blending->screen_ratio_w;
- blending->dst_data.h = (osd_hw.dst_data[index].h << OSD_CALC) /
- blending->screen_ratio_h;
- if (osd_hw.dst_data[index].w < osd_hw.disp_info.position_w)
- osd_log_err("base dispframe w(%d) must >= position_w(%d)\n",
- osd_hw.dst_data[index].w, osd_hw.disp_info.position_w);
- if ((blending->dst_data.w + blending->dst_data.x) >
- osd_hw.disp_info.background_w) {
- blending->dst_data.w = osd_hw.disp_info.background_w
- - blending->dst_data.x;
- osd_log_info("blending w(%d) must < base fb w(%d)\n",
- blending->dst_data.w + blending->dst_data.x,
- osd_hw.disp_info.background_w);
- }
+ blending->dst_data.x = osd_hw.dst_data[index].x *
+ blending->screen_ratio_w_den /
+ blending->screen_ratio_w_num;
+ blending->dst_data.y = osd_hw.dst_data[index].y *
+ blending->screen_ratio_h_den /
+ blending->screen_ratio_h_num;
+ blending->dst_data.w = osd_hw.dst_data[index].w *
+ blending->screen_ratio_w_den /
+ blending->screen_ratio_w_num;
+ blending->dst_data.h = osd_hw.dst_data[index].h *
+ blending->screen_ratio_h_den /
+ blending->screen_ratio_h_num;
osd_log_dbg2(MODULE_BLEND,
"uniformization:osd%d:dst_data:%d,%d,%d,%d\n",
index,
blending->dst_data.h);
}
-static void adjust_dst_position(void)
+static void adjust_dst_position(u32 output_index)
{
int i = 0;
- int osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
+ int osd_count = 0;
+ int start_index = 0;
+
+ if (output_index == VIU1) {
+ osd_count = osd_hw.osd_meson_dev.viu1_osd_count;
+ start_index = 0;
+ } else if (output_index == VIU2) {
+ start_index = osd_hw.osd_meson_dev.viu2_index;
+ osd_count = start_index + 1;
+ } else {
+ osd_log_err("invald output_index=%d\n", output_index);
+ return;
+ }
for (i = 0; i < osd_count; i++) {
if (osd_hw.enable[i]) {
osd_hw.dst_data[i].x -=
- osd_hw.disp_info.position_x;
+ osd_hw.disp_info[output_index].position_x;
osd_hw.dst_data[i].y -=
- osd_hw.disp_info.position_y;
+ osd_hw.disp_info[output_index].position_y;
if (osd_hw.dst_data[i].x < 0)
osd_hw.dst_data[i].x = 0;
if (osd_hw.dst_data[i].y < 0)
osd_hw.dst_data[i].h);
}
}
- if (osd_hw.field_out_en)
- osd_hw.disp_info.position_y /= 2;
+ if (osd_hw.field_out_en[output_index])
+ osd_hw.disp_info[output_index].position_y /= 2;
}
-static int osd_setting_order(void)
+static int osd_setting_order(u32 output_index)
{
+#define RDMA_DETECT_REG VIU_OSD2_TCOLOR_AG2
int i;
struct layer_blend_reg_s *blend_reg;
struct hw_osd_blending_s *blending;
int line1;
int line2;
int vinfo_height;
+ u32 val;
blending = &osd_blending;
blend_reg = &(blending->blend_reg);
- blending->vinfo_width = osd_hw.vinfo_width;
- blending->vinfo_height = osd_hw.vinfo_height;
- blending->screen_ratio_w =
- (osd_hw.disp_info.position_w << OSD_CALC)
- / osd_hw.disp_info.background_w;
- blending->screen_ratio_h =
- (osd_hw.disp_info.position_h << OSD_CALC)
- / osd_hw.disp_info.background_h;
+ blending->vinfo_width = osd_hw.vinfo_width[output_index];
+ blending->vinfo_height = osd_hw.vinfo_height[output_index];
+ blending->screen_ratio_w_num =
+ osd_hw.disp_info[output_index].position_w;
+ blending->screen_ratio_w_den =
+ osd_hw.disp_info[output_index].background_w;
+ blending->screen_ratio_h_num =
+ osd_hw.disp_info[output_index].position_h;
+ blending->screen_ratio_h_den =
+ osd_hw.disp_info[output_index].background_h;
blending->layer_cnt = get_available_layers();
set_blend_order(blending);
blending->b_exchange_din = false;
blending->b_exchange_blend_in = false;
blending->osd1_freescale_disable = false;
- adjust_dst_position();
- uniformization_fb(OSD1, blending);
+ adjust_dst_position(output_index);
+ if (!osd_hw.osd_meson_dev.osd0_sc_independ)
+ uniformization_fb(OSD1, blending);
/* set blend mode */
set_blend_mode(blending);
set_blend_din(blending);
/* set blend path */
- set_blend_path(blending);
+ if (osd_hw.osd_meson_dev.osd0_sc_independ)
+ set_blend_path_new(blending);
+ else
+ set_blend_path(blending);
line1 = get_enter_encp_line();
- vinfo_height = osd_hw.field_out_en ?
- (osd_hw.vinfo_height * 2) : osd_hw.vinfo_height;
- if (line1 >= vinfo_height) {
+ vinfo_height = osd_hw.field_out_en[output_index] ?
+ (osd_hw.vinfo_height[output_index] * 2) :
+ osd_hw.vinfo_height[output_index];
+ /* if nearly vsync signal, wait vsync here */
+ if (line1 >= vinfo_height * line_threshold / 100) {
osd_log_dbg(MODULE_RENDER,
- "enter osd_setting_order:cnt=%d,encp line=%d\n",
- cnt, line1);
+ "enter osd_setting_order:encp line=%d\n",
+ line1);
osd_wait_vsync_hw();
line1 = get_enter_encp_line();
}
set_blend_reg(blend_reg);
save_blend_reg(blend_reg);
+ /* append RDMA_DETECT_REG at last and detect if rdma missed some regs */
+ rdma_dt_cnt++;
+ VSYNCOSD_WR_MPEG_REG(RDMA_DETECT_REG, rdma_dt_cnt);
spin_unlock_irqrestore(&osd_lock, lock_flags);
line2 = get_exit_encp_line();
osd_log_dbg2(MODULE_RENDER,
- "enter osd_setting_order:cnt=%d,encp line=%d\n",
- cnt, line2);
- if (line2 < line1)
- osd_log_info("osd line %d,%d\n", line1, line2);
+ "enter osd_setting_order:encp line=%d\n",
+ line2);
osd_wait_vsync_hw();
+ val = osd_reg_read(RDMA_DETECT_REG);
+ /* if missed, need wait vsync */
+ if (/*(line2 < line1) || */(val != rdma_dt_cnt)) {
+ osd_wait_vsync_hw();
+ osd_log_dbg(MODULE_RENDER, "osd line %d,%d\n", line1, line2);
+ }
return 0;
}
0x0 << 11 |
0x0);
- blend_hsize = osd_hw.disp_info.background_w;
- blend_vsize = osd_hw.disp_info.background_h;
+ blend_hsize = osd_hw.disp_info[VIU1].background_w;
+ blend_vsize = osd_hw.disp_info[VIU1].background_h;
VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND0_SIZE,
blend_vsize << 16 |
VSYNCOSD_WR_MPEG_REG(VIU_OSD_BLEND_BLEND1_SIZE,
blend_vsize << 16 |
blend_hsize);
+ /* hdr input size should set to osd blend0 output size */
+ VSYNCOSD_WR_MPEG_REG(VPP_OSD1_IN_SIZE,
+ blend_vsize << 16 |
+ blend_hsize);
VSYNCOSD_WR_MPEG_REG_BITS(DOLBY_PATH_CTRL,
0x3, 2, 2);
}
u32 x_start, x_end, y_start, y_end, height_dst, height_src;
if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[VIU1]
- osd_hw.free_dst_data[index].x_end - 1;
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[VIU1]
- osd_hw.free_dst_data[index].y_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[VIU1]
- osd_hw.free_dst_data[index].x_start - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[VIU1]
- osd_hw.free_dst_data[index].y_start - 1;
osd_hw.free_dst_data[index].x_start = x_start;
osd_hw.free_dst_data[index].y_start = y_start;
osd_hw.free_dst_data[index].x_end = x_end;
osd_hw.free_dst_data[index].y_end = y_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_X) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[VIU1]
- osd_hw.free_dst_data[index].x_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[VIU1]
- osd_hw.free_dst_data[index].x_start - 1;
osd_hw.free_dst_data[index].x_start = x_start;
osd_hw.free_dst_data[index].x_end = x_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[VIU1]
- osd_hw.free_dst_data[index].y_end - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[VIU1]
- osd_hw.free_dst_data[index].y_start - 1;
osd_hw.free_dst_data[index].y_start = y_start;
osd_hw.free_dst_data[index].y_end = y_end;
return false;
}
-#if 0
-static bool set_old_hwc_freescale(u32 index)
-{
- u32 x_start, x_end, y_start, y_end;
- u32 width_src = 0, width_dst = 0, height_src = 0, height_dst = 0;
- u32 width, height;
- u32 screen_ratio_w, screen_ratio_h;
-
- width_src = osd_hw.disp_info.background_w;
- height_src = osd_hw.disp_info.background_h;
-
- width_dst = osd_hw.vinfo_width;
- height_dst = osd_hw.vinfo_height;
- screen_ratio_w = (osd_hw.disp_info.position_w << OSD_CALC)
- / osd_hw.disp_info.background_w;
- screen_ratio_h = (osd_hw.disp_info.position_h << OSD_CALC)
- / osd_hw.disp_info.background_h;
- osd_log_dbg("width_src:%d,%d\n",
- width_src, height_src);
- osd_log_dbg("width_src:%d,%d\n",
- width_dst, height_dst);
-
- width = osd_hw.free_dst_data[index].x_end -
- osd_hw.free_dst_data[index].x_start;
- height = osd_hw.free_dst_data[index].y_end -
- osd_hw.free_dst_data[index].y_start;
- osd_hw.free_dst_data[index].x_start =
- (osd_hw.free_dst_data[index].x_start
- * screen_ratio_w >> OSD_CALC);
- osd_hw.free_dst_data[index].y_start =
- (osd_hw.free_dst_data[index].y_start
- * screen_ratio_h >> OSD_CALC);
- width = (width * screen_ratio_w >> OSD_CALC);
- height = (height * screen_ratio_h >> OSD_CALC);
-
- osd_hw.free_dst_data[index].x_start +=
- osd_hw.disp_info.position_x;
- osd_hw.free_dst_data[index].x_end =
- osd_hw.free_dst_data[index].x_start + width;
- osd_hw.free_dst_data[index].y_start +=
- osd_hw.disp_info.position_y;
- osd_hw.free_dst_data[index].y_end =
- osd_hw.free_dst_data[index].y_start + height;
-
- if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
- x_start = osd_hw.vinfo_width
- - osd_hw.free_dst_data[index].x_end - 1;
- y_start = osd_hw.vinfo_height
- - osd_hw.free_dst_data[index].y_end - 1;
- x_end = osd_hw.vinfo_width
- - osd_hw.free_dst_data[index].x_start - 1;
- y_end = osd_hw.vinfo_height
- - osd_hw.free_dst_data[index].y_start - 1;
- osd_hw.free_dst_data[index].x_start = x_start;
- osd_hw.free_dst_data[index].y_start = y_start;
- osd_hw.free_dst_data[index].x_end = x_end;
- osd_hw.free_dst_data[index].y_end = y_end;
- } else if (osd_hw.osd_reverse[index] == REVERSE_X) {
- x_start = osd_hw.vinfo_width
- - osd_hw.free_dst_data[index].x_end - 1;
- x_end = osd_hw.vinfo_width
- - osd_hw.free_dst_data[index].x_start - 1;
- osd_hw.free_dst_data[index].x_start = x_start;
- osd_hw.free_dst_data[index].x_end = x_end;
- } else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
- y_start = osd_hw.vinfo_height
- - osd_hw.free_dst_data[index].y_end - 1;
- y_end = osd_hw.vinfo_height
- - osd_hw.free_dst_data[index].y_start - 1;
- osd_hw.free_dst_data[index].y_start = y_start;
- osd_hw.free_dst_data[index].y_end = y_end;
- }
- osd_log_dbg("free_dst_data: %x,%x,%x,%x\n",
- osd_hw.free_dst_data[index].x_start,
- osd_hw.free_dst_data[index].x_end,
- osd_hw.free_dst_data[index].y_start,
- osd_hw.free_dst_data[index].y_end);
- if ((memcmp(&(osd_hw.free_src_data[index]),
- &osd_hw.free_src_data_backup[index],
- sizeof(struct pandata_s)) != 0) ||
- (memcmp(&(osd_hw.free_dst_data[index]),
- &osd_hw.free_dst_data_backup[index],
- sizeof(struct pandata_s)) != 0)) {
- memcpy(&osd_hw.free_src_data_backup[index],
- &osd_hw.free_src_data[index],
- sizeof(struct pandata_s));
- memcpy(&osd_hw.free_dst_data_backup[index],
- &osd_hw.free_dst_data[index],
- sizeof(struct pandata_s));
- return true;
- } else
- return false;
-}
-#endif
-
static void osd_setting_old_hwc(void)
{
int index = OSD1;
static void osd_setting_viu2(void)
{
- int index = OSD4;
+ int index = osd_hw.osd_meson_dev.viu2_index;
if (!osd_hw.osd_afbcd[index].enable)
canvas_config(osd_hw.fb_gem[index].canvas_idx,
if (!osd_hw.osd_display_debug)
osd_hw.reg[OSD_ENABLE]
.update_func(index);
+ osd_wait_vsync_hw();
}
-int osd_setting_blend(void)
+int osd_setting_blend(u32 output_index)
{
int ret;
if (osd_hw.osd_meson_dev.osd_ver < OSD_HIGH_ONE)
osd_setting_old_hwc();
else {
- if (osd_hw.hwc_enable) {
- if (osd_hw.viu_type == VIU1) {
- ret = osd_setting_order();
+ if (osd_hw.hwc_enable[output_index]) {
+ if (output_index == VIU1) {
+ ret = osd_setting_order(output_index);
if (ret < 0)
return -1;
- } else if (osd_hw.viu_type == VIU2)
+ } else if (output_index == VIU2) {
osd_setting_viu2();
- } else
+ }
+ } else {
osd_setting_default_hwc();
+ }
}
return 0;
}
{
u32 data32;
- data32 = osd_hw.urgent[index] & 1;
+ data32 = VSYNCOSD_RD_MPEG_REG(
+ hw_osd_reg_array[index].osd_fifo_ctrl_stat);
+ data32 |= osd_hw.urgent[index] & 1;
+ #if 0
data32 |= 4 << 5; /* hold_fifo_lines */
/* burst_len_sel: 3=64, g12a = 5 */
data32 |= 2 << 22;
/* bit 28:24, fifo_lim */
data32 |= 2 << 24;
+ #endif
VSYNCOSD_WR_MPEG_REG(
hw_osd_reg_array[index].osd_fifo_ctrl_stat, data32);
remove_from_update_list(index, OSD_FIFO);
sizeof(struct osd_device_data_s));
osd_vpu_power_on();
+ if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_TL1) {
+ /* VIU1 2 OSD + 1 VIU2 1 OSD*/
+ memcpy(&hw_osd_reg_array[0], &hw_osd_reg_array_tl1[0],
+ sizeof(struct hw_osd_reg_s) *
+ osd_hw.osd_meson_dev.osd_count);
+ } else {
+ /* VIU1 3 OSD + 1 VIU2 1 OSD or VIU1 2 OSD*/
+ memcpy(&hw_osd_reg_array[0], &hw_osd_reg_array_g12a[0],
+ sizeof(struct hw_osd_reg_s) *
+ osd_hw.osd_meson_dev.osd_count);
+ }
if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_GXTVBB)
backup_regs_init(HW_RESET_AFBCD_REGS);
else if (osd_meson->cpu_id == __MESON_CPU_MAJOR_ID_GXM)
osd_hdr_on = false;
#endif
osd_hw.hw_reset_flag = HW_RESET_NONE;
- osd_hw.hwc_enable = 0;
+ osd_hw.hwc_enable[VIU1] = 0;
+ osd_hw.hwc_enable[VIU2] = 0;
if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
osd_hw.hw_cursor_en = 1;
if (osd_hw.osd_meson_dev.has_rdma)
/* init vpu fifo control register */
data32 = osd_reg_read(VPP_OFIFO_SIZE);
if (osd_hw.osd_meson_dev.osd_ver >= OSD_HIGH_ONE) {
- data32 = 0; /* reset value 0xfff0fff */
+ data32 &= ~((0xfff << 20) | 0x3fff);
data32 |= (osd_hw.osd_meson_dev.vpp_fifo_len) << 20;
data32 |= osd_hw.osd_meson_dev.vpp_fifo_len + 1;
} else
osd_hw.order[OSD1] = LAYER_1;
osd_hw.order[OSD2] = LAYER_2;
osd_hw.order[OSD3] = LAYER_3;
- //osd_hw.osd_blend_mode = OSD_BLEND_NONE;
- osd_hw.disp_info.background_w = 1920;
- osd_hw.disp_info.background_h = 1080;
- osd_hw.disp_info.fullscreen_w = 1920;
- osd_hw.disp_info.fullscreen_h = 1080;
- osd_hw.disp_info.position_x = 0;
- osd_hw.disp_info.position_y = 0;
- osd_hw.disp_info.position_w = 1920;
- osd_hw.disp_info.position_h = 1080;
- osd_hw.vinfo_width = 1920;
- osd_hw.vinfo_height = 1080;
- osd_hw.workaround_line = 0;
+ for (idx = 0; idx < VIU_COUNT; idx++) {
+ osd_hw.disp_info[idx].background_w = 1920;
+ osd_hw.disp_info[idx].background_h = 1080;
+ osd_hw.disp_info[idx].fullscreen_w = 1920;
+ osd_hw.disp_info[idx].fullscreen_h = 1080;
+ osd_hw.disp_info[idx].position_x = 0;
+ osd_hw.disp_info[idx].position_y = 0;
+ osd_hw.disp_info[idx].position_w = 1920;
+ osd_hw.disp_info[idx].background_h = 1080;
+ osd_hw.vinfo_width[idx] = 1920;
+ osd_hw.vinfo_height[idx] = 1080;
+ }
if ((osd_hw.osd_meson_dev.cpu_id ==
__MESON_CPU_MAJOR_ID_G12A) ||
((osd_hw.osd_meson_dev.cpu_id ==
osd_hw.afbc_regs_backup = 1;
} else {
osd_hw.afbc_force_reset = 1;
- osd_hw.afbc_regs_backup = 0;
+ osd_hw.afbc_regs_backup = 1;
data32 = osd_reg_read(MALI_AFBCD_TOP_CTRL);
osd_reg_write(MALI_AFBCD_TOP_CTRL,
data32 | 0x800000);
osd_reg_set_bits(
hw_osd_reg_array[idx].osd_fifo_ctrl_stat,
1, 10, 2);
- /* TODO: temp set at here,
- * need check for logo
- */
- if (idx > 0)
- osd_reg_set_bits(
- hw_osd_reg_array[idx].osd_ctrl_stat,
- 0, 0, 1);
+ if (osd_hw.osd_meson_dev.cpu_id ==
+ __MESON_CPU_MAJOR_ID_G12B)
+ osd_reg_set_bits
+ (hw_osd_reg_array[idx].osd_ctrl_stat,
+ 1, 0, 1);
osd_reg_set_bits(
hw_osd_reg_array[idx].osd_ctrl_stat,
0, 31, 1);
}
/* hwc_enable == 0 handler */
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
- osd_hw.osd_fence[DISABLE].sync_fence_handler =
+ osd_hw.osd_fence[VIU1][DISABLE].sync_fence_handler =
sync_render_single_fence;
- osd_hw.osd_fence[DISABLE].toggle_buffer_handler =
+ osd_hw.osd_fence[VIU1][DISABLE].toggle_buffer_handler =
osd_toggle_buffer_single;
/* hwc_enable == 1 handler */
- osd_hw.osd_fence[ENABLE].sync_fence_handler =
+ osd_hw.osd_fence[VIU1][ENABLE].sync_fence_handler =
sync_render_layers_fence;
- osd_hw.osd_fence[ENABLE].toggle_buffer_handler =
+ osd_hw.osd_fence[VIU1][ENABLE].toggle_buffer_handler =
osd_toggle_buffer_layers;
+ if (osd_hw.osd_meson_dev.has_viu2) {
+ osd_hw.osd_fence[VIU2][DISABLE].sync_fence_handler =
+ sync_render_single_fence;
+ osd_hw.osd_fence[VIU2][DISABLE].toggle_buffer_handler =
+ osd_toggle_buffer_single_viu2;
+ /* hwc_enable == 1 handler */
+ osd_hw.osd_fence[VIU2][ENABLE].sync_fence_handler =
+ sync_render_layers_fence;
+ osd_hw.osd_fence[VIU2][ENABLE].toggle_buffer_handler =
+ osd_toggle_buffer_layers_viu2;
+ }
#endif
osd_hw.fb_gem[OSD1].canvas_idx = OSD1_CANVAS_INDEX;
osd_hw.fb_gem[OSD2].canvas_idx = OSD2_CANVAS_INDEX;
if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
osd_hw.fb_gem[OSD3].canvas_idx = OSD3_CANVAS_INDEX;
+ if (osd_hw.osd_meson_dev.osd_count == 4)
osd_hw.fb_gem[OSD4].canvas_idx = OSD4_CANVAS_INDEX;
}
osd_extra_canvas_alloc();
osd_hw.antiflicker_mode = 0;
osd_hw.osd_deband_enable = 1;
- osd_hw.out_fence_fd = -1;
+ osd_hw.out_fence_fd[VIU1] = -1;
+ osd_hw.out_fence_fd[VIU2] = -1;
osd_hw.blend_bypass = 0;
osd_hw.afbc_err_cnt = 0;
if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) {
osd_set_deband(osd_hw.osd_deband_enable);
if (osd_hw.fb_drvier_probe) {
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
- INIT_LIST_HEAD(&post_fence_list);
- mutex_init(&post_fence_list_lock);
+ INIT_LIST_HEAD(&post_fence_list[VIU1]);
+ mutex_init(&post_fence_list_lock[VIU1]);
+ INIT_LIST_HEAD(&post_fence_list[VIU2]);
+ mutex_init(&post_fence_list_lock[VIU2]);
#endif
#ifdef FIQ_VSYNC
osd_hw.fiq_handle_item.handle = vsync_isr;
void osd_init_viu2(void)
{
u32 idx, data32;
+ struct vinfo_s *vinfo;
set_viu2_rgb2yuv(1);
* set DDR request priority to be urgent
*/
data32 = 1;
- data32 |= 4 << 5; /* hold_fifo_lines */
+ vinfo = get_current_vinfo2();
+ if (vinfo && (!strcmp(vinfo->name, "dummy_panel"))) {
+ data32 |= MAX_HOLD_LINE << 5; /* hold_fifo_lines */
+ } else
+ data32 |= DEFAULT_HOLD_LINE << 5; /* hold_fifo_lines */
/* burst_len_sel: 3=64, g12a = 5 */
if (osd_hw.osd_meson_dev.osd_ver == OSD_HIGH_ONE) {
data32 |= 1 << 10;
memcpy(&disp_tmp, &osd_hw.dispdata[OSD1],
sizeof(struct pandata_s));
- if (osd_hw.field_out_en) {
+ if (osd_hw.field_out_en[VIU1]) {
disp_tmp.y_start *= 2;
disp_tmp.y_end *= 2;
}
}
}
- if (osd_hw.field_out_en)
+ if (osd_hw.field_out_en[VIU1])
osd_hw.dispdata[OSD2].y_start /= 2;
osd_hw.dispdata[OSD2].x_end = osd_hw.dispdata[OSD2].x_start +
{
const struct color_bit_define_s *color = NULL;
+ format &= ~AFBC_EN;
switch (format) {
case COLOR_INDEX_02_PAL4:
case COLOR_INDEX_04_PAL16:
u32 x_start, x_end, y_start, y_end;
bool freescale_update = false;
struct pandata_s freescale_dst[HW_OSD_COUNT];
+ u32 output_index;
+ output_index = get_output_device_id(index);
phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y;
osd_hw.screen_base[index] = phy_addr;
osd_hw.screen_size[index] =
plane_map->byte_stride * plane_map->src_h;
osd_log_dbg(MODULE_RENDER, "canvas_id=%x, phy_addr=%x\n",
osd_hw.fb_gem[index].canvas_idx, phy_addr);
- canvas_config(osd_hw.fb_gem[index].canvas_idx,
- phy_addr,
- plane_map->byte_stride,
- plane_map->src_h,
- CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
- if (osd_hw.hwc_enable) {
+ if (osd_hw.osd_meson_dev.osd_ver == OSD_SIMPLE) {
+ osd_hw.fb_gem[index].addr = phy_addr;
+ osd_hw.fb_gem[index].width = plane_map->byte_stride;
+ osd_update_phy_addr(0);
+ } else {
+ canvas_config(osd_hw.fb_gem[index].canvas_idx,
+ phy_addr,
+ plane_map->byte_stride,
+ plane_map->src_h,
+ CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
+ }
+ if (osd_hw.hwc_enable[output_index]) {
/* just get para, need update via do_hwc */
osd_hw.order[index] = plane_map->zorder;
switch (plane_map->blend_mode) {
((plane_map->dst_y + plane_map->dst_h) *
height_dst) / height_src - 1;
if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[output_index]
- freescale_dst[index].x_end - 1;
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[output_index]
- freescale_dst[index].y_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[output_index]
- freescale_dst[index].x_start - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[output_index]
- freescale_dst[index].y_start - 1;
freescale_dst[index].x_start = x_start;
freescale_dst[index].y_start = y_start;
freescale_dst[index].x_end = x_end;
freescale_dst[index].y_end = y_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_X) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[output_index]
- freescale_dst[index].x_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[output_index]
- freescale_dst[index].x_start - 1;
freescale_dst[index].x_start = x_start;
freescale_dst[index].x_end = x_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[output_index]
- freescale_dst[index].y_end - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[output_index]
- freescale_dst[index].y_start - 1;
freescale_dst[index].y_start = y_start;
freescale_dst[index].y_end = y_end;
osd_hw.dispdata[index].y_end =
plane_map->dst_y + plane_map->dst_h - 1;
if (osd_hw.osd_reverse[index] == REVERSE_TRUE) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[output_index]
- osd_hw.dispdata[index].x_end - 1;
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[output_index]
- osd_hw.dispdata[index].y_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[output_index]
- osd_hw.dispdata[index].x_start - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[output_index]
- osd_hw.dispdata[index].y_start - 1;
osd_hw.dispdata[index].x_start = x_start;
osd_hw.dispdata[index].y_start = y_start;
osd_hw.dispdata[index].x_end = x_end;
osd_hw.dispdata[index].y_end = y_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_X) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[output_index]
- osd_hw.dispdata[index].x_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[output_index]
- osd_hw.dispdata[index].x_start - 1;
osd_hw.dispdata[index].x_start = x_start;
osd_hw.dispdata[index].x_end = x_end;
} else if (osd_hw.osd_reverse[index] == REVERSE_Y) {
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[output_index]
- osd_hw.dispdata[index].y_end - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[output_index]
- osd_hw.dispdata[index].y_start - 1;
osd_hw.dispdata[index].y_start = y_start;
osd_hw.dispdata[index].y_end = y_end;
u32 x, y;
struct pandata_s disp_tmp;
struct pandata_s free_dst_data_backup;
+ u32 output_index;
if (index != OSD2)
return;
+ output_index = get_output_device_id(index);
phy_addr = phy_addr + plane_map->byte_stride * plane_map->src_y;
osd_hw.screen_base[index] = phy_addr;
osd_hw.screen_size[index] =
osd_hw.pandata[OSD2].y_end - osd_hw.pandata[OSD2].y_start;
if (osd_hw.osd_reverse[OSD2] == REVERSE_TRUE) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[output_index]
- osd_hw.dispdata[index].x_end - 1;
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[output_index]
- osd_hw.dispdata[index].y_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[output_index]
- osd_hw.dispdata[index].x_start - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[output_index]
- osd_hw.dispdata[index].y_start - 1;
osd_hw.dispdata[index].x_start = x_start;
osd_hw.dispdata[index].y_start = y_start;
osd_hw.dispdata[index].x_end = x_end;
osd_hw.dispdata[index].y_end = y_end;
} else if (osd_hw.osd_reverse[OSD2] == REVERSE_X) {
- x_start = osd_hw.vinfo_width
+ x_start = osd_hw.vinfo_width[output_index]
- osd_hw.dispdata[index].x_end - 1;
- x_end = osd_hw.vinfo_width
+ x_end = osd_hw.vinfo_width[output_index]
- osd_hw.dispdata[index].x_start - 1;
osd_hw.dispdata[index].x_start = x_start;
osd_hw.dispdata[index].x_end = x_end;
} else if (osd_hw.osd_reverse[OSD2] == REVERSE_Y) {
- y_start = osd_hw.vinfo_height
+ y_start = osd_hw.vinfo_height[output_index]
- osd_hw.dispdata[index].y_end - 1;
- y_end = osd_hw.vinfo_height
+ y_end = osd_hw.vinfo_height[output_index]
- osd_hw.dispdata[index].y_start - 1;
osd_hw.dispdata[index].y_start = y_start;
osd_hw.dispdata[index].y_end = y_end;
bool freescale_update = false;
u32 osd_enable = 0;
u32 format = 0;
- const struct vinfo_s *vinfo;
+ const struct vinfo_s *vinfo = NULL;
+ u32 output_index;
- if (!osd_hw.hwc_enable) {
+ output_index = get_output_device_id(index);
+ if (!osd_hw.hwc_enable[output_index]) {
if (index >= OSD2)
return;
} else {
}
osd_hw.buffer_alloc[index] = 1;
- if (osd_hw.osd_fps_start)
- osd_hw.osd_fps++;
-
+ if (osd_hw.osd_fps_start[output_index])
+ osd_hw.osd_fps[output_index]++;
osd_enable = (plane_map->enable & 1) ? ENABLE : DISABLE;
- vinfo = get_current_vinfo();
- if (vinfo && (strcmp(vinfo->name, "invalid") &&
- strcmp(vinfo->name, "null"))) {
- osd_hw.vinfo_width = vinfo->width;
- osd_hw.vinfo_height = vinfo->height;
+
+ if (output_index == VIU1)
+ vinfo = get_current_vinfo();
+#ifdef CONFIG_AMLOGIC_VOUT2_SERVE
+ else if (output_index == VIU2)
+ vinfo = get_current_vinfo2();
+#endif
+ if (!vinfo || (!strcmp(vinfo->name, "invalid") ||
+ !strcmp(vinfo->name, "null"))) {
+ return;
}
+ osd_hw.vinfo_width[output_index] = vinfo->width;
+ osd_hw.vinfo_height[output_index] = vinfo->height;
+
osd_hw.osd_afbcd[index].enable =
(plane_map->afbc_inter_format & AFBC_EN) >> 31;
if (osd_hw.osd_meson_dev.osd_ver <= OSD_NORMAL) {
osd_hw.osd_afbcd[index].phy_addr =
plane_map->phy_addr;
osd_hw.reg[OSD_COLOR_MODE].update_func(index);
- if (!osd_hw.hwc_enable) {
+ if (!osd_hw.hwc_enable[output_index]) {
osd_hw.reg[DISP_GEOMETRY].update_func(index);
osd_hw.reg[DISP_OSD_REVERSE].update_func(index);
if ((osd_hw.free_scale_enable[index]