mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
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:
committed by
Jianxin Pan
parent
82062d5a49
commit
af82c9e477
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user