osd: fix osd flicker issue on AXG

PD#146558: osd: fix osd flicker issue on AXG

1. osd: move reg update to vsync interrupt
2. osd: add osd hold line size to 24
3. osd: add read/wirte reg function
4. osd: add osd fps stat function

Change-Id: Iaa382bb8deba49ecb94732691a3608cec9fb9679
Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
Pengcheng Chen
2017-07-03 15:26:39 +08:00
committed by Jianxin Pan
parent 82062d5a49
commit af82c9e477
6 changed files with 139 additions and 8 deletions

View File

@@ -61,9 +61,9 @@
//reg = <0x0 0x3e000000 0x0 0x1f00000>;
compatible = "shared-dma-pool";
reusable;
size = <0x0 0x1000000>;
size = <0x0 0x2000000>;
alignment = <0x0 0x400000>;
alloc-ranges = <0x0 0x3f000000 0x0 0x1000000>;
alloc-ranges = <0x0 0x3e000000 0x0 0x2000000>;
};
};
mtd_nand {
@@ -738,14 +738,14 @@
interrupts = <0 3 1
0 89 1>;
interrupt-names = "viu-vsync", "rdma";
mem_size = <0x00300000 0x600000 0x00000000>;
mem_size = <0x00300000 0x1800000 0x00000000>;
/* uboot logo,fb0/fb1 memory size */
display_mode_default = "1080p60hz";
scale_mode = <0>;
/** 0:VPU free scale 1:OSD free scale 2:OSD super scale */
display_size_default = <768 1024 768 2048 32>;
/*768*1024*4*2 = 0x600000*/
logo_addr = "0x3f000000";
logo_addr = "0x3e000000";
pxp_mode = <0>; /** 0:normal mode 1:pxp mode */
};

View File

@@ -357,6 +357,8 @@ struct hw_para_s {
struct afbcd_data_s osd_afbcd[HW_OSD_COUNT];
u32 urgent[HW_OSD_COUNT];
u32 osd_deband_enable;
u32 osd_fps;
u32 osd_fps_start;
};
#endif /* _OSD_H_ */

View File

@@ -1266,7 +1266,8 @@ static int osd_open(struct fb_info *info, int arg)
if (osd_check_fbsize(var, info))
return -ENOMEM;
/* clear osd buffer if not logo layer */
if ((logo_index < 0) || (logo_index != fb_index)) {
if (((logo_index < 0) || (logo_index != fb_index)) ||
(get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)) {
osd_log_info("---------------clear fb%d memory %p\n",
fb_index, fbdev->fb_mem_vaddr);
set_logo_loaded();
@@ -2270,6 +2271,83 @@ static ssize_t store_osd_deband(struct device *device,
return count;
}
static ssize_t show_osd_fps(struct device *device,
struct device_attribute *attr,
char *buf)
{
u32 osd_fps;
osd_get_fps(&osd_fps);
return snprintf(buf, 40, "%d\n",
osd_fps);
}
static ssize_t store_osd_fps(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
int res = 0;
int ret = 0;
ret = kstrtoint(buf, 0, &res);
osd_set_fps(res);
return count;
}
static void parse_param(char *buf_orig, char **parm)
{
char *ps, *token;
unsigned int n = 0;
char delim1[3] = " ";
char delim2[2] = "\n";
ps = buf_orig;
strcat(delim1, delim2);
while (1) {
token = strsep(&ps, delim1);
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
}
static ssize_t store_osd_reg(struct device *device,
struct device_attribute *attr,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
long val = 0;
unsigned int reg_addr, reg_val;
if (!buf)
return count;
buf_orig = kstrdup(buf, GFP_KERNEL);
parse_param(buf_orig, (char **)&parm);
if (!strcmp(parm[0], "rv")) {
if (kstrtoul(parm[1], 16, &val) < 0)
return -EINVAL;
reg_addr = val;
reg_val = osd_reg_read(reg_addr);
pr_info("reg[0x%04x]=0x%08x\n", reg_addr, reg_val);
} else if (!strcmp(parm[0], "wv")) {
if (kstrtoul(parm[1], 16, &val) < 0)
return -EINVAL;
reg_addr = val;
if (kstrtoul(parm[2], 16, &val) < 0)
return -EINVAL;
reg_val = val;
osd_reg_write(reg_addr, reg_val);
}
return count;
}
static inline int str2lower(char *str)
{
while (*str != '\0') {
@@ -2452,6 +2530,10 @@ static struct device_attribute osd_attrs[] = {
NULL, free_scale_switch),
__ATTR(osd_deband, 0644,
show_osd_deband, store_osd_deband),
__ATTR(osd_fps, 0644,
show_osd_fps, store_osd_fps),
__ATTR(osd_reg, 0220,
NULL, store_osd_reg),
};
#ifdef CONFIG_PM

View File

@@ -1950,6 +1950,32 @@ void osd_set_deband(u32 osd_deband_enable)
}
}
}
void osd_get_fps(u32 *osd_fps)
{
*osd_fps = osd_hw.osd_fps;
}
void osd_set_fps(u32 osd_fps_start)
{
static int stime, etime;
osd_hw.osd_fps_start = osd_fps_start;
if (osd_fps_start) {
/* start to calc fps */
stime = ktime_to_us(ktime_get());
osd_hw.osd_fps = 0;
} else {
/* stop to calc fps */
etime = ktime_to_us(ktime_get());
osd_hw.osd_fps = (osd_hw.osd_fps * 1000000)
/ (etime - stime);
osd_log_info("osd fps:=%d\n", osd_hw.osd_fps);
}
}
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
enum {
HAL_PIXEL_FORMAT_RGBA_8888 = 1,
@@ -2157,6 +2183,8 @@ static void osd_pan_display_fence(struct osd_fence_map_s *fence_map)
osd_log_dbg("fence wait ret %d\n", ret);
}
if (ret) {
if (osd_hw.osd_fps_start)
osd_hw.osd_fps++;
if (fence_map->op == 0xffffffff)
skip = true;
else
@@ -2356,6 +2384,8 @@ void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset)
osd_hw.pandata[index].y_start += diff_y;
osd_hw.pandata[index].y_end += diff_y;
add_to_update_list(index, DISP_GEOMETRY);
if (osd_hw.osd_fps_start)
osd_hw.osd_fps++;
osd_wait_vsync_hw();
}
#ifdef CONFIG_AMLOGIC_MEDIA_FB_EXT
@@ -3858,6 +3888,11 @@ void osd_init_hw(u32 logo_loaded)
osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0xff);
else
osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0x008080ff);
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) {
data32 = osd_reg_read(VIU_OSD1_FIFO_CTRL_STAT);
data32 |= 0x18 << 5;
osd_reg_write(VIU_OSD1_FIFO_CTRL_STAT, data32);
}
osd_set_deband(osd_hw.osd_deband_enable);
/* osd_hw.osd_afbcd[OSD1].enable = 0;
* osd_hw.osd_afbcd[OSD2].enable = 0;

View File

@@ -151,6 +151,8 @@ extern void osd_get_urgent(u32 index, u32 *urgent);
extern void osd_set_urgent(u32 index, u32 urgent);
void osd_get_deband(u32 *osd_deband_enable);
void osd_set_deband(u32 osd_deband_enable);
void osd_get_fps(u32 *osd_fps);
void osd_set_fps(u32 osd_fps_start);
extern void osd_get_info(u32 index, u32 *addr, u32 *width, u32 *height);
int logo_work_init(void);
void set_logo_loaded(void);

View File

@@ -97,7 +97,10 @@ static update_func_t hw_func_array[HW_OSD_COUNT][HW_REG_INDEX_MAX] = {
spin_lock_irqsave(&osd_lock, lock_flags); \
raw_local_save_flags(fiq_flag); \
local_fiq_disable(); \
osd_hw.reg[osd_idx][cmd_idx].update_func(); \
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) \
osd_hw.updated[osd_idx] |= (1<<cmd_idx); \
else \
osd_hw.reg[osd_idx][cmd_idx].update_func(); \
raw_local_irq_restore(fiq_flag); \
spin_unlock_irqrestore(&osd_lock, lock_flags); \
} while (0)
@@ -105,7 +108,10 @@ static update_func_t hw_func_array[HW_OSD_COUNT][HW_REG_INDEX_MAX] = {
#define add_to_update_list(osd_idx, cmd_idx) \
do { \
spin_lock_irqsave(&osd_lock, lock_flags); \
osd_hw.reg[osd_idx][cmd_idx].update_func(); \
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) \
osd_hw.updated[osd_idx] |= (1<<cmd_idx); \
else \
osd_hw.reg[osd_idx][cmd_idx].update_func(); \
spin_unlock_irqrestore(&osd_lock, lock_flags); \
} while (0)
#endif
@@ -131,7 +137,11 @@ static update_func_t hw_func_array[HW_OSD_COUNT][HW_REG_INDEX_MAX] = {
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
#define remove_from_update_list(osd_idx, cmd_idx)
#define remove_from_update_list(osd_idx, cmd_idx) \
do { \
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) \
(osd_hw.updated[osd_idx] &= ~(1<<cmd_idx)); \
} while (0)
#else
#define remove_from_update_list(osd_idx, cmd_idx) \
(osd_hw.updated[osd_idx] &= ~(1<<cmd_idx))