mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
osd: add osd blend shift workaround
PD#163001: osd: add osd blend shift workaround(default disable) Change-Id: Ic488f9414a35f5a8e2ba7ec789c2061fe526e804 Signed-off-by: pengcheng chen <pengcheng.chen@amlogic.com>
This commit is contained in:
committed by
Jianxin Pan
parent
d65d69a6ad
commit
cccccd7680
@@ -320,6 +320,7 @@ enum osd_zorder_e {
|
||||
* OSD_BLEND_ABC: (OSD1 & (OSD2+SC & OSD3+SC)) +SC
|
||||
* OSD_BLEND_AB_C: (OSD1 & OSD2 + SC) + SC, OSD3+SC
|
||||
* OSD_BLEND_A_BC: OSD1+SC, (OSD2 +SC & OSD3 +SC)
|
||||
* OSD_BLEND_AB_C: ((OSD+ (OSD2+SC)) + SC) & (OSD3+SC)
|
||||
*/
|
||||
enum osd_blend_mode_e {
|
||||
OSD_BLEND_NONE,
|
||||
@@ -328,6 +329,7 @@ enum osd_blend_mode_e {
|
||||
OSD_BLEND_A_C,
|
||||
OSD_BLEND_ABC,
|
||||
OSD_BLEND_A_BC,
|
||||
OSD_BLEND_AB_C,
|
||||
};
|
||||
|
||||
enum afbc_pix_format_e {
|
||||
@@ -570,6 +572,7 @@ struct layer_blend_s {
|
||||
struct dispdata_s output_data;
|
||||
u32 background_w;
|
||||
u32 background_h;
|
||||
u32 blend_core1_bypass;
|
||||
};
|
||||
struct hw_osd_blending_s {
|
||||
u8 osd_blend_mode;
|
||||
@@ -731,7 +734,6 @@ struct hw_para_s {
|
||||
u32 hdr_used;
|
||||
u32 workaround_hdr;
|
||||
u32 workaround_not_hdr;
|
||||
u32 blend_reg_reset;
|
||||
u32 basic_urgent;
|
||||
u32 two_ports;
|
||||
u32 afbc_err_cnt;
|
||||
|
||||
@@ -1675,7 +1675,8 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd,
|
||||
if ((!strcmp(vinfo->name, "invalid")) ||
|
||||
(!strcmp(vinfo->name, "null")))
|
||||
return -1;
|
||||
|
||||
osd_hw.vinfo_width = vinfo->width;
|
||||
osd_hw.vinfo_height = vinfo->field_height;
|
||||
switch (cmd) {
|
||||
case VOUT_EVENT_MODE_CHANGE:
|
||||
set_osd_logo_freescaler();
|
||||
@@ -2677,6 +2678,7 @@ static ssize_t store_osd_background_size(struct device *device,
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_osd_hdr_mode(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "osd_hw_def.h"
|
||||
#include "osd_fb.h"
|
||||
|
||||
//#define OSD_BLEND_SHIFT_WORKAROUND
|
||||
#ifdef CONFIG_AMLOGIC_VSYNC_FIQ_ENABLE
|
||||
#define FIQ_VSYNC
|
||||
#endif
|
||||
@@ -5091,6 +5092,7 @@ static int get_available_layers(void)
|
||||
return available_layer;
|
||||
}
|
||||
|
||||
|
||||
static u32 blend_din_to_osd(
|
||||
u32 blend_din_index, struct hw_osd_blending_s *blending)
|
||||
{
|
||||
@@ -5104,6 +5106,200 @@ static u32 blend_din_to_osd(
|
||||
return osd_index;
|
||||
}
|
||||
|
||||
#ifdef OSD_BLEND_SHIFT_WORKAROUND
|
||||
static void generate_blend_din_table(struct hw_osd_blending_s *blending)
|
||||
{
|
||||
int i = 0;
|
||||
int osd_count = osd_hw.osd_meson_dev.osd_count - 1;
|
||||
int temp1 = 0, temp2 = 0;
|
||||
|
||||
/* 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;
|
||||
|
||||
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("blend_din4==%d\n",
|
||||
blending->reorder[temp_index[0]]);
|
||||
osd_log_dbg("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("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("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;
|
||||
}
|
||||
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->osd_blend_mode == OSD_BLEND_AB_C) {
|
||||
/* 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;
|
||||
osd_log_dbg("reorder:%d,%d,%d\n",
|
||||
blending->reorder[OSD1],
|
||||
blending->reorder[OSD2],
|
||||
blending->reorder[OSD3]);
|
||||
if (blending->reorder[OSD2] > blending->reorder[OSD1]) {
|
||||
/* osd1 is top */
|
||||
blending->b_exchange_din = true;
|
||||
osd_log_dbg("need exchange osd din order\n");
|
||||
temp1 = blending->din_reoder_sel & 0x000f;
|
||||
temp2 = blending->din_reoder_sel & 0x0f00;
|
||||
osd_log_dbg("temp1:%x,temp2=%x\n",
|
||||
temp1, temp2);
|
||||
//blending->din_reoder_sel = (1 << 12);
|
||||
blending->din_reoder_sel &= ~0x0f0f;
|
||||
blending->din_reoder_sel |= temp1 << 8;
|
||||
blending->din_reoder_sel |= temp2 >> 8;
|
||||
osd_log_dbg("din_reoder_sel%x\n",
|
||||
blending->din_reoder_sel);
|
||||
if (blending->reorder[OSD2] <
|
||||
blending->reorder[OSD3]) {
|
||||
blending->b_exchange_blend_in = true;
|
||||
osd_log_dbg("111,need exchange vpp order\n");
|
||||
}
|
||||
} else {
|
||||
if (blending->reorder[OSD1] >
|
||||
blending->reorder[OSD3]) {
|
||||
blending->b_exchange_blend_in = true;
|
||||
osd_log_dbg("222, need exchange vpp order\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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]) {
|
||||
u32 temp1, temp2;
|
||||
|
||||
blending->b_exchange_din = true;
|
||||
osd_log_dbg("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;
|
||||
}
|
||||
|
||||
/* workaround for shift issue */
|
||||
/* not enable layers used osd4 */
|
||||
temp2 = 0;
|
||||
for (i = 0; i < OSD_BLEND_LAYERS; i++) {
|
||||
temp1 = (blending->din_reoder_sel >> (i*4)) & 0xf;
|
||||
if (!(temp1 & 0x0f))
|
||||
temp2 |= (0x04 << (i*4));
|
||||
}
|
||||
blending->din_reoder_sel |= temp2;
|
||||
osd_log_dbg("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;
|
||||
}
|
||||
|
||||
#else
|
||||
static void generate_blend_din_table(struct hw_osd_blending_s *blending)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -5251,7 +5447,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending)
|
||||
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};
|
||||
@@ -5410,7 +5606,13 @@ static void set_blend_order(struct hw_osd_blending_s *blending)
|
||||
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;
|
||||
@@ -5455,7 +5657,11 @@ static void set_blend_mode(struct hw_osd_blending_s *blending)
|
||||
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;
|
||||
@@ -5509,10 +5715,8 @@ static void calc_max_output(struct hw_osd_blending_s *blending)
|
||||
output_end_y = input2_end_y;
|
||||
else
|
||||
output_end_y = input1_end_y;
|
||||
#if 1
|
||||
layer_blend->output_data.x = 0;
|
||||
layer_blend->output_data.y = 0;
|
||||
#endif
|
||||
layer_blend->output_data.w = output_end_x -
|
||||
layer_blend->output_data.x + 1;
|
||||
layer_blend->output_data.h = output_end_y -
|
||||
@@ -5595,7 +5799,10 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending)
|
||||
workaround_line = osd_hw.workaround_not_hdr;//1;
|
||||
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 */
|
||||
@@ -5604,7 +5811,7 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending)
|
||||
} 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;
|
||||
@@ -5674,6 +5881,16 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending)
|
||||
}
|
||||
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));
|
||||
else
|
||||
memcpy(&layer_blend->output_data,
|
||||
&layer_blend->input2_data,
|
||||
sizeof(struct dispdata_s));
|
||||
#else
|
||||
layer_blend->output_data.x = 0;
|
||||
layer_blend->output_data.y = 0;
|
||||
layer_blend->output_data.w =
|
||||
@@ -5682,6 +5899,7 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending)
|
||||
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;
|
||||
@@ -5703,6 +5921,7 @@ static void osd_setting_blend2(struct hw_osd_blending_s *blending)
|
||||
struct layer_blend_s *layer_blend;
|
||||
struct layer_blend_reg_s *blend_reg;
|
||||
u32 blend_hsize, blend_vsize;
|
||||
int blend1_input = 0;
|
||||
|
||||
if (!blending)
|
||||
return;
|
||||
@@ -5715,6 +5934,17 @@ static void osd_setting_blend2(struct hw_osd_blending_s *blending)
|
||||
/* 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;
|
||||
break;
|
||||
default:
|
||||
/* blend1_dout to dout1 */
|
||||
blend1_input = 1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (layer_blend->input2) {
|
||||
case BLEND1_DIN:
|
||||
/* blend1_dout to blend2 */
|
||||
@@ -5725,9 +5955,11 @@ static void osd_setting_blend2(struct hw_osd_blending_s *blending)
|
||||
blend_reg->din2_osd_sel = 1;
|
||||
break;
|
||||
}
|
||||
blend1_input = blend_reg->din2_osd_sel;
|
||||
#endif
|
||||
/* premult set */
|
||||
blend_reg->blend2_premult_en = 3;
|
||||
if (blend_reg->din2_osd_sel)
|
||||
if (blend1_input)
|
||||
memcpy(&(layer_blend->output_data), &(layer_blend->input1_data),
|
||||
sizeof(struct dispdata_s));
|
||||
else {
|
||||
@@ -5736,14 +5968,11 @@ static void osd_setting_blend2(struct hw_osd_blending_s *blending)
|
||||
blend_vsize = layer_blend->output_data.h;
|
||||
blend_reg->osd_blend_blend0_size =
|
||||
blend_vsize << 16 | blend_hsize;
|
||||
#if 0
|
||||
if ((blend_hsize > layer_blend->background_w) ||
|
||||
(blend_vsize > layer_blend->background_h))
|
||||
osd_log_err("blend0 input data size(%d, %d) > bk(%d, %d)\n",
|
||||
blend_hsize, blend_vsize,
|
||||
layer_blend->background_w,
|
||||
layer_blend->background_h);
|
||||
#endif
|
||||
#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_dbg("layer_blend2->output_data:%d,%d,%d,%d\n",
|
||||
layer_blend->output_data.x,
|
||||
@@ -5778,20 +6007,15 @@ static void vpp_setting_blend(struct hw_osd_blending_s *blending)
|
||||
osd2_v_start = layer_blend->input2_data.y;
|
||||
osd2_v_end = layer_blend->input2_data.y +
|
||||
layer_blend->input2_data.h - 1;
|
||||
osd_log_dbg("osd1_h_start=%x,osd1_h_end=%x\n",
|
||||
osd1_h_start, osd1_h_end);
|
||||
osd_log_dbg("osd1_v_start=%x, osd1_v_end=%x\n",
|
||||
osd1_v_start, osd1_v_end);
|
||||
|
||||
osd_log_dbg("osd2_h_start=%x,osd2_h_end=%x\n",
|
||||
osd2_h_start, osd2_h_end);
|
||||
osd_log_dbg("osd2_h_start=%x, osd2_v_end=%x\n",
|
||||
osd2_v_start, osd2_v_end);
|
||||
|
||||
/* vpp osd1 postblend scope */
|
||||
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;
|
||||
@@ -5816,11 +6040,15 @@ static void vpp_setting_blend(struct hw_osd_blending_s *blending)
|
||||
blend_reg->postbld_osd1_premult = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* vpp osd2 postblend scope */
|
||||
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;
|
||||
@@ -5851,7 +6079,6 @@ static void vpp_setting_blend(struct hw_osd_blending_s *blending)
|
||||
osd_log_dbg("vpp_osd2_blend_h_scope=%x, vpp_osd2_blend_v_scope=%x\n",
|
||||
blend_reg->vpp_osd2_blend_h_scope,
|
||||
blend_reg->vpp_osd2_blend_v_scope);
|
||||
|
||||
}
|
||||
|
||||
/* input w, h is background */
|
||||
@@ -5889,7 +6116,6 @@ static void osd_set_freescale(u32 index,
|
||||
|
||||
if ((blending->osd_blend_mode == OSD_BLEND_AC) ||
|
||||
(blending->osd_blend_mode == OSD_BLEND_ABC)) {
|
||||
|
||||
osd_hw.free_dst_data[index].x_start =
|
||||
((osd_hw.free_src_data[index].x_start *
|
||||
blending->screen1_ratio_w >> OSD_CALC) *
|
||||
@@ -5916,7 +6142,26 @@ static void osd_set_freescale(u32 index,
|
||||
blending->screen2_ratio_h >> OSD_CALC) *
|
||||
osd_hw.dst_data[index].h /
|
||||
osd_hw.src_data[index].h;
|
||||
} else {
|
||||
}
|
||||
#ifdef OSD_BLEND_SHIFT_WORKAROUND
|
||||
else if (blending->osd_blend_mode == OSD_BLEND_AB_C) {
|
||||
osd_hw.free_dst_data[index].x_start =
|
||||
(osd_hw.free_src_data[index].x_start *
|
||||
blending->screen1_ratio_w >> OSD_CALC) *
|
||||
blending->screen2_ratio_w >> OSD_CALC;
|
||||
osd_hw.free_dst_data[index].y_start =
|
||||
(osd_hw.free_src_data[index].y_start *
|
||||
blending->screen1_ratio_h >> OSD_CALC) *
|
||||
blending->screen2_ratio_h >> OSD_CALC;
|
||||
width = (layer_blend->output_data.w *
|
||||
blending->screen1_ratio_w >> OSD_CALC) *
|
||||
blending->screen2_ratio_w >> OSD_CALC;
|
||||
height = (layer_blend->output_data.h *
|
||||
blending->screen1_ratio_h >> OSD_CALC) *
|
||||
blending->screen2_ratio_h >> OSD_CALC;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
osd_hw.free_dst_data[index].x_start =
|
||||
(osd_hw.dst_data[index].x *
|
||||
blending->screen1_ratio_w >> OSD_CALC) *
|
||||
@@ -5972,7 +6217,25 @@ static void osd_set_freescale(u32 index,
|
||||
osd_hw.free_dst_data[index].y_end =
|
||||
osd_hw.free_dst_data[index].y_start +
|
||||
height - 1;
|
||||
} else {
|
||||
}
|
||||
#ifdef OSD_BLEND_SHIFT_WORKAROUND
|
||||
else if ((blending->osd_blend_mode == OSD_BLEND_AB_C)
|
||||
&& (index == blend_din_to_osd(BLEND_DIN3, blending))) {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
osd_hw.free_dst_data[index].x_start =
|
||||
(osd_hw.dst_data[index].x *
|
||||
blending->screen1_ratio_w >> OSD_CALC) *
|
||||
@@ -6031,9 +6294,9 @@ static void osd_setting_blend0_input(u32 index,
|
||||
/* for g12a blend shift issue */
|
||||
|
||||
if (osd_hw.hdr_used)
|
||||
workaround_line = osd_hw.workaround_hdr;//0;
|
||||
workaround_line = osd_hw.workaround_hdr;
|
||||
else
|
||||
workaround_line = osd_hw.workaround_not_hdr;//1;
|
||||
workaround_line = osd_hw.workaround_not_hdr;
|
||||
layer_blend = &(blending->layer_blend);
|
||||
if (index == OSD1) {
|
||||
blending->pic_w_ratio =
|
||||
@@ -6043,7 +6306,11 @@ static void osd_setting_blend0_input(u32 index,
|
||||
(osd_hw.src_data[index].h << OSD_CALC) /
|
||||
osd_hw.dst_data[index].h;
|
||||
if ((blending->osd_blend_mode == OSD_BLEND_AC)
|
||||
|| (blending->osd_blend_mode == OSD_BLEND_ABC)) {
|
||||
|| (blending->osd_blend_mode == OSD_BLEND_ABC)
|
||||
#ifdef OSD_BLEND_SHIFT_WORKAROUND
|
||||
|| (blending->osd_blend_mode == OSD_BLEND_AB_C)
|
||||
#endif
|
||||
) {
|
||||
layer_blend->input1_data.x =
|
||||
osd_hw.dst_data[index].x *
|
||||
blending->pic_w_ratio >> OSD_CALC;
|
||||
@@ -6057,9 +6324,14 @@ static void osd_setting_blend0_input(u32 index,
|
||||
osd_hw.src_data[index].h
|
||||
- workaround_line;
|
||||
} else {
|
||||
#ifdef OSD_BLEND_SHIFT_WORKAROUND
|
||||
layer_blend->input1_data.x = 0;
|
||||
layer_blend->input1_data.y = workaround_line;
|
||||
#else
|
||||
layer_blend->input1_data.x = osd_hw.src_data[index].x;
|
||||
layer_blend->input1_data.y = osd_hw.src_data[index].y
|
||||
+ workaround_line;
|
||||
#endif
|
||||
layer_blend->input1_data.w = osd_hw.src_data[index].w;
|
||||
layer_blend->input1_data.h = osd_hw.src_data[index].h
|
||||
- workaround_line;
|
||||
@@ -6087,13 +6359,12 @@ static void osd_setting_blend0_input(u32 index,
|
||||
}
|
||||
layer_blend->background_w = background_w;
|
||||
layer_blend->background_h = background_h;
|
||||
osd_log_dbg("index=%d,osd_hw.src_data.w=%d,h=%d\n",
|
||||
index, osd_hw.src_data[index].w, osd_hw.src_data[index].h);
|
||||
osd_log_dbg("index=%d,src:%d,%d,dst_data.w=%d,h=%d\n",
|
||||
index, osd_hw.src_data[index].w,
|
||||
osd_hw.src_data[index].h,
|
||||
osd_hw.dst_data[index].w,
|
||||
osd_hw.dst_data[index].h);
|
||||
osd_log_dbg("index=%d,src_data: x=%d,y=%d,w=%d,h=%d\n",
|
||||
index, osd_hw.src_data[index].x, osd_hw.src_data[index].y,
|
||||
osd_hw.src_data[index].w, osd_hw.src_data[index].h);
|
||||
osd_log_dbg("dst_data: x=%d,y=%d,w=%d,h=%d\n",
|
||||
osd_hw.dst_data[index].x, osd_hw.dst_data[index].y,
|
||||
osd_hw.dst_data[index].w, osd_hw.dst_data[index].h);
|
||||
osd_log_dbg("bk size:%d, %d\n",
|
||||
layer_blend->background_w,
|
||||
layer_blend->background_h);
|
||||
@@ -6107,11 +6378,17 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
|
||||
struct dispdata_s output1_data;
|
||||
u32 index = 0;
|
||||
u8 input1 = 0, input2 = 0;
|
||||
#ifdef OSD_BLEND_SHIFT_WORKAROUND
|
||||
u32 workaround_line = 1;
|
||||
#endif
|
||||
|
||||
if (!blending)
|
||||
return;
|
||||
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;
|
||||
@@ -6218,13 +6495,18 @@ static void set_blend_path(struct hw_osd_blending_s *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_dbg("before blend0: set osd%d freescale\n",
|
||||
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));
|
||||
@@ -6239,8 +6521,10 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
|
||||
}
|
||||
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
|
||||
layer_blend->input2_data.x =
|
||||
osd_hw.free_dst_data[index].x_start;
|
||||
layer_blend->input2_data.w =
|
||||
@@ -6335,12 +6619,18 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
|
||||
/* here freescale osd1/osd2 used */
|
||||
osd_log_dbg("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
|
||||
layer_blend->input2_data.x =
|
||||
osd_hw.free_dst_data[index].x_start +
|
||||
osd_hw.disp_info.position_x;
|
||||
@@ -6438,7 +6728,10 @@ static void set_blend_path(struct hw_osd_blending_s *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);
|
||||
@@ -6561,6 +6854,116 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
|
||||
}
|
||||
vpp_setting_blend(blending);
|
||||
break;
|
||||
#ifdef OSD_BLEND_SHIFT_WORKAROUND
|
||||
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;
|
||||
index = blend_din_to_osd(BLEND_DIN1, 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;
|
||||
index = blend_din_to_osd(BLEND_DIN3, blending);
|
||||
if (index != OSD1) {
|
||||
osd_log_dbg("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;
|
||||
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;
|
||||
layer_blend->input1_data.h =
|
||||
osd_hw.free_dst_data[index].y_end -
|
||||
osd_hw.free_dst_data[index].y_start + 1;
|
||||
} else {
|
||||
memcpy(&layer_blend->input1_data,
|
||||
&osd_hw.src_data[index],
|
||||
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.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;
|
||||
osd_log_dbg("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);
|
||||
osd_log_dbg("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;
|
||||
|
||||
/* 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));
|
||||
layer_blend->input2_data.y += workaround_line;
|
||||
layer_blend->input2_data.h -= workaround_line;
|
||||
} 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));
|
||||
layer_blend->input1_data.y += workaround_line;
|
||||
layer_blend->input1_data.h -= workaround_line;
|
||||
}
|
||||
vpp_setting_blend(blending);
|
||||
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6568,8 +6971,11 @@ static void set_blend_reg(struct layer_blend_reg_s *blend_reg)
|
||||
{
|
||||
int i;
|
||||
u32 reg_offset = 2;
|
||||
#ifdef OSD_BLEND_SHIFT_WORKAROUND
|
||||
u32 osd_count = osd_hw.osd_meson_dev.osd_count;
|
||||
#else
|
||||
u32 osd_count = osd_hw.osd_meson_dev.osd_count - 1;
|
||||
|
||||
#endif
|
||||
if (!blend_reg)
|
||||
return;
|
||||
/* osd blend ctrl */
|
||||
@@ -6620,6 +7026,15 @@ static void set_blend_reg(struct layer_blend_reg_s *blend_reg)
|
||||
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;
|
||||
VSYNCOSD_WR_MPEG_REG(
|
||||
VIU_OSD_BLEND_DIN0_SCOPE_V + reg_offset * i,
|
||||
blend_reg->osd_blend_din_scope_v[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6656,9 +7071,9 @@ static int osd_setting_order(void)
|
||||
blending->pic_w_ratio = 1 << OSD_CALC;
|
||||
blending->pic_h_ratio = 1 << OSD_CALC;
|
||||
|
||||
blending->layer_cnt = get_available_layers();
|
||||
set_blend_order(blending);
|
||||
|
||||
blending->layer_cnt = get_available_layers();
|
||||
osd_log_dbg("layer_cnt:%d\n", blending->layer_cnt);
|
||||
|
||||
blending->b_exchange_din = false;
|
||||
|
||||
Reference in New Issue
Block a user