osd: osd logo optimize

PD#138714: osd logo optimize
1.move logo module,merge it into osd driver
2.fix remove get_logo_vmode() api caused video.c compile error

Change-Id: I8c90c0313fbf5661082627f7a37b3e465ba594da
Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
Pengcheng Chen
2017-04-14 11:41:11 +08:00
committed by Jianxin Pan
parent 273478ff4a
commit cd14fc32bd
11 changed files with 137 additions and 219 deletions

View File

@@ -44,7 +44,6 @@ source "drivers/amlogic/media/video_sink/Kconfig"
source "drivers/amlogic/media/vout/Kconfig"
source "drivers/amlogic/media/osd/Kconfig"
source "drivers/amlogic/media/osd_ext/Kconfig"
source "drivers/amlogic/media/logo/Kconfig"
source "drivers/amlogic/media/deinterlace/Kconfig"
source "drivers/amlogic/media/vin/Kconfig"
source "drivers/amlogic/media/video_processor/Kconfig"

View File

@@ -4,7 +4,6 @@ obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += video_sink/
obj-$(CONFIG_AMLOGIC_VOUT) += vout/
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += osd/
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += osd_ext/
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += logo/
obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += deinterlace/
obj-$(CONFIG_AMLOGIC_MEDIA_VIN) += vin/
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += video_processor/

View File

@@ -1,10 +0,0 @@
#
# Amlogic Logo configuration
#
config AMLOGIC_MEDIA_LOGO
bool "Amlogic Logo Module"
default n
depends on AMLOGIC_MEDIA_FB
depends on AMLOGIC_VOUT
help
Select to enable Logo module

View File

@@ -1,4 +0,0 @@
obj-$(CONFIG_AMLOGIC_MEDIA_LOGO) += logo.o
ccflags-y += -Idrivers/amlogic/display/
ccflags-y += -Idrivers/amlogic/media/

View File

@@ -19,7 +19,7 @@ config AMLOGIC_MEDIA_FB
It need enable canvas.
It need enable vout.
config AMLOGIC_MEDIAFB_OSD_SYNC_FENCE
config AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
bool "OSD SYNC FENCE"
default n
depends on AMLOGIC_MEDIA_FB

View File

@@ -1,5 +1,5 @@
obj-$(CONFIG_AMLOGIC_MEDIA_FB) += fb.o
fb-objs = osd_hw.o osd_fb.o osd_debug.o osd_backup.o
fb-objs = osd_hw.o osd_fb.o osd_debug.o osd_backup.o osd_logo.o
fb-objs += osd_antiflicker.o osd_clone.o
obj-$(CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA) += osd_rdma.o

View File

@@ -288,6 +288,8 @@ static int early_suspend_flag;
static int early_resume_flag;
#endif
static struct delayed_work osd_dwork;
static bool fb_map_flag;
static int osd_shutdown_flag;
unsigned int osd_log_level;
@@ -971,7 +973,35 @@ static int osd_open(struct fb_info *info, int arg)
fb_index = fbdev->fb_index;
fix = &info->fix;
var = &info->var;
if (fb_rmem.base == 0) {
/* read fb-reserved memory first */
if (fb_rmem.base &&
(fb_memsize[0] + fb_memsize[1]) <= fb_rmem.size) {
if (!fb_ion_client)
fb_ion_client = meson_ion_client_create(-1, "meson-fb");
fb_rmem_size[fb_index] = fb_memsize[fb_index];
if (fb_index == DEV_OSD0)
fb_rmem_paddr[fb_index] = fb_rmem.base;
else if (fb_index == DEV_OSD1) {
if ((OSD_COUNT == 2) &&
((fb_memsize[0] + fb_memsize[1]) <= fb_rmem.size)) {
fb_rmem_paddr[fb_index] =
fb_rmem.base + fb_memsize[0];
}
}
if ((fb_rmem_paddr[fb_index] > 0) &&
(fb_rmem_size[fb_index] > 0)) {
if (fb_map_flag)
fb_rmem_vaddr[fb_index] =
phys_to_virt(fb_rmem_paddr[fb_index]);
else
fb_rmem_vaddr[fb_index] =
ioremap_wc(fb_rmem_paddr[fb_index],
fb_rmem_size[fb_index]);
if (!fb_rmem_vaddr[fb_index])
osd_log_err("fb[%d] ioremap error",
fb_index);
}
} else {
#ifdef CONFIG_AMLOGIC_ION
pr_info("use ion buffer for fb memory\n");
if (!fb_ion_client)
@@ -1053,26 +1083,6 @@ static int osd_open(struct fb_info *info, int arg)
(unsigned long)fb_rmem_size[fb_index] / SZ_1M);
}
#endif
} else {
fb_rmem_size[fb_index] = fb_memsize[fb_index];
if (fb_index == DEV_OSD0)
fb_rmem_paddr[fb_index] = fb_rmem.base;
else if (fb_index == DEV_OSD1) {
if ((OSD_COUNT == 2) &&
((fb_memsize[0] + fb_memsize[1]) <= fb_rmem.size)) {
fb_rmem_paddr[fb_index] =
fb_rmem.base + fb_memsize[0];
}
}
if ((fb_rmem_paddr[fb_index] > 0) &&
(fb_rmem_size[fb_index] > 0)) {
fb_rmem_vaddr[fb_index] =
ioremap_wc(fb_rmem_paddr[fb_index],
fb_rmem_size[fb_index]);
if (!fb_rmem_vaddr[fb_index])
osd_log_err("fb[%d] ioremap error",
fb_index);
}
}
fbdev->fb_len = fb_rmem_size[fb_index];
fbdev->fb_mem_paddr = fb_rmem_paddr[fb_index];
@@ -1116,6 +1126,7 @@ static int osd_open(struct fb_info *info, int arg)
if ((logo_index < 0) || (logo_index != fb_index)) {
osd_log_info("---------------clear fb%d memory %p\n",
fb_index, fbdev->fb_mem_vaddr);
set_logo_loaded();
memset(fbdev->fb_mem_vaddr, 0x0, fbdev->fb_len);
if (fb_index == DEV_OSD0 && osd_get_afbc()) {
for (j = 1; j < OSD_MAX_BUF_NUM; j++) {
@@ -1277,6 +1288,7 @@ int osd_notify_callback(struct notifier_block *block, unsigned long cmd,
break;
#endif
case VOUT_EVENT_MODE_CHANGE:
set_osd_logo_freescaler();
for (i = 0; i < OSD_COUNT; i++) {
fb_dev = gp_fbdev_list[i];
if (fb_dev == NULL)
@@ -2358,6 +2370,30 @@ static int osd_pm_resume(struct device *dev)
}
#endif
static void mem_free_work(struct work_struct *work)
{
long r = -EINVAL;
unsigned long start_addr;
unsigned long end_addr;
if (fb_rmem.base && fb_map_flag) {
if (fb_rmem.size >= (fb_memsize[0] + fb_memsize[1])) {
/* logo reserved memory after fb0/fb1 memory, free it*/
start_addr = fb_rmem.base
+ fb_memsize[0] + fb_memsize[1];
end_addr = fb_rmem.base + fb_rmem.size;
} else {
/* logo reserved only, free it*/
start_addr = fb_rmem.base;
end_addr = fb_rmem.base + fb_rmem.size;
}
osd_log_info("%s, free memory: addr:%lx\n",
__func__, start_addr);
r = free_reserved_area(__va(start_addr),
__va(end_addr), 0, "fb-memory");
}
}
static int osd_probe(struct platform_device *pdev)
{
struct fb_info *fbi = NULL;
@@ -2366,8 +2402,6 @@ static int osd_probe(struct platform_device *pdev)
struct fb_fix_screeninfo *fix;
int index, bpp;
struct osd_fb_dev_s *fbdev = NULL;
enum vmode_e current_mode = VMODE_MASK;
enum vmode_e logo_init = 0;
const void *prop;
int prop_idx = 0;
const char *str;
@@ -2388,6 +2422,13 @@ static int osd_probe(struct platform_device *pdev)
goto failed1;
}
#endif
/* init osd logo */
ret = logo_work_init();
if (ret == 0)
osd_init_hw(1);
else
osd_init_hw(0);
/* get buffer size from dt */
ret = of_property_read_u32_array(pdev->dev.of_node,
"mem_size", fb_memsize, 2);
@@ -2416,12 +2457,6 @@ static int osd_probe(struct platform_device *pdev)
/* get default display mode from dt */
ret = of_property_read_string(pdev->dev.of_node,
"display_mode_default", &str);
if (ret)
current_mode = VMODE_MASK;
#ifdef CONFIG_AMLOGIC_TV_OUTPUT
else
current_mode = vmode_name_to_mode(str);
#endif
prop = of_get_property(pdev->dev.of_node, "pxp_mode", NULL);
if (prop)
prop_idx = of_read_ulong(prop, 1);
@@ -2434,16 +2469,7 @@ static int osd_probe(struct platform_device *pdev)
osd_set_urgent(1, (prop_idx != 0) ? 1 : 0);
}
/* if osd_init_hw is not set by logo, set vmode and init osd hw */
logo_init = osd_get_init_hw_flag();
if (logo_init == 0) {
if (current_mode < VMODE_MASK)
set_current_vmode(current_mode);
osd_init_hw(0);
}
vinfo = get_current_vinfo();
osd_log_info("%s vinfo:%p\n", __func__, vinfo);
for (index = 0; index < OSD_COUNT; index++) {
/* register frame buffer memory */
fbi = framebuffer_alloc(sizeof(struct osd_fb_dev_s),
@@ -2544,6 +2570,8 @@ static int osd_probe(struct platform_device *pdev)
/* register vout client */
vout_register_client(&osd_notifier_nb);
INIT_DELAYED_WORK(&osd_dwork, mem_free_work);
schedule_delayed_work(&osd_dwork, msecs_to_jiffies(60 * 1000));
osd_log_info("osd probe OK\n");
return 0;
@@ -2624,6 +2652,11 @@ exit:
static int rmem_fb_device_init(struct reserved_mem *rmem, struct device *dev)
{
if (!of_get_flat_dt_prop(rmem->fdt_node, "no-map", NULL)) {
fb_map_flag = true;
osd_log_info("momery mapped[can free]\n");
} else
fb_map_flag = false;
return 0;
}
@@ -2708,7 +2741,7 @@ static void __exit osd_exit_module(void)
platform_driver_unregister(&osd_driver);
}
module_init(osd_init_module);
subsys_initcall(osd_init_module);
module_exit(osd_exit_module);
MODULE_AUTHOR("Platform-BJ <platform.bj@amlogic.com>");

View File

@@ -112,7 +112,6 @@ static unsigned int osd_auto_adjust_filter = 1;
module_param(osd_auto_adjust_filter, uint, 0664);
MODULE_PARM_DESC(osd_auto_adjust_filter, "osd_auto_adjust_filter");
static int osd_init_hw_flag;
static int osd_logo_index = 1;
module_param(osd_logo_index, int, 0664);
MODULE_PARM_DESC(osd_logo_index, "osd_logo_index");
@@ -3256,7 +3255,7 @@ void osd_init_hw(u32 logo_loaded)
osd_hw.free_src_data[OSD2].x_end = 0;
osd_hw.free_src_data[OSD2].y_start = 0;
osd_hw.free_src_data[OSD2].y_end = 0;
osd_hw.free_scale_mode[OSD1] = 1;
osd_hw.free_scale_mode[OSD1] = 0;
osd_hw.free_scale_mode[OSD2] = 1;
if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM)
osd_reg_write(VPP_OSD_SC_DUMMY_DATA, 0x002020ff);
@@ -3294,7 +3293,6 @@ void osd_init_hw(u32 logo_loaded)
osd_rdma_enable(1);
#endif
osd_init_hw_flag = 1;
}
#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR)
@@ -3502,11 +3500,6 @@ void osd_set_logo_index(int index)
osd_logo_index = index;
}
int osd_get_init_hw_flag(void)
{
return osd_init_hw_flag;
}
void osd_get_hw_para(struct hw_para_s **para)
{
*para = &osd_hw;

View File

@@ -145,4 +145,7 @@ extern void osd_switch_free_scale(
u32 next_index, u32 next_enable, u32 next_scale);
extern void osd_get_urgent(u32 index, u32 *urgent);
extern void osd_set_urgent(u32 index, u32 urgent);
int logo_work_init(void);
void set_logo_loaded(void);
int set_osd_logo_freescaler(void);
#endif

View File

@@ -1,5 +1,5 @@
/*
* drivers/amlogic/media/logo/logo.c
* drivers/amlogic/media/osd/osd_logo.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
@@ -13,19 +13,23 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
*/
/* Linux Headers */
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/delay.h>
/* Amlogic Headers */
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h>
/* Local Headers */
#include <osd/osd_hw.h>
#include "osd_hw.h"
#include "osd_log.h"
#undef pr_fmt
@@ -36,12 +40,6 @@
#define LOGO_DEBUG 0x1001
#define LOGO_LOADED 0x1002
static enum vmode_e hdmimode = VMODE_MAX;
static enum vmode_e cvbsmode = VMODE_MAX;
static enum vmode_e last_mode = VMODE_MAX;
static u32 vout_init_vmode = VMODE_INIT_NULL;
struct delayed_work logo_work;
static DEFINE_MUTEX(logo_lock);
struct para_pair_s {
@@ -49,6 +47,7 @@ struct para_pair_s {
int value;
};
static struct para_pair_s logo_args[] = {
{"osd0", LOGO_DEV_OSD0},
{"osd1", LOGO_DEV_OSD1},
@@ -56,6 +55,7 @@ static struct para_pair_s logo_args[] = {
{"loaded", LOGO_LOADED},
};
struct logo_info_s {
int index;
u32 vmode;
@@ -68,7 +68,6 @@ struct logo_info_s {
.loaded = 0,
};
static int get_value_by_name(char *name, struct para_pair_s *pair, u32 cnt)
{
u32 i = 0;
@@ -84,118 +83,12 @@ static int get_value_by_name(char *name, struct para_pair_s *pair, u32 cnt)
return found;
}
int set_osd_freescaler(int index, enum vmode_e new_mode)
{
const struct vinfo_s *vinfo;
osd_set_free_scale_mode_hw(index, 1);
osd_set_free_scale_enable_hw(index, 0);
osd_set_free_scale_axis_hw(index, 0, 0, 1919, 1079);
osd_update_disp_axis_hw(index, 0, 1919, 0, 1079, 0, 0, 0);
vinfo = get_current_vinfo();
if (vinfo) {
pr_info("outputmode changed to %s, reset osd%d scaler\n",
vinfo->name, index);
osd_set_window_axis_hw(index, 0, 0,
(vinfo->width - 1), (vinfo->height - 1));
} else {
osd_set_window_axis_hw(index, 0, 0, 1919, 1079);
pr_info("error: vinfo is NULL\n");
}
if (osd_get_logo_index() != logo_info.index) {
pr_info("logo changed, return");
return -1;
}
osd_set_free_scale_enable_hw(index, 0x10001);
osd_enable_hw(index, 1);
pr_info("finish");
return 0;
}
enum vmode_e get_logo_vmode(void)
{
return vout_init_vmode;
}
EXPORT_SYMBOL(get_logo_vmode);
static int set_logo_vmode(enum vmode_e mode)
{
int ret = 0;
if (mode == VMODE_INIT_NULL)
return -1;
vout_init_vmode = mode;
set_current_vmode(mode);
return ret;
}
static int refresh_mode_and_logo(bool first)
{
enum vmode_e cur_mode = VMODE_MAX;
int hdp_state = 0;
#ifdef AMLOGIC_HDMI_TX
hdp_state = get_hpd_state();
#endif
if (!first && osd_get_logo_index() != logo_info.index)
return -1;
if (hdp_state)
cur_mode = hdmimode;
else
cur_mode = cvbsmode;
if (first) {
last_mode = get_logo_vmode();
if (logo_info.index >= 0) {
osd_set_logo_index(logo_info.index);
/* osd_init_hw(logo_info.loaded); */
}
}
if (cur_mode >= VMODE_MAX) /* not box platform */
return -1;
if (cur_mode != last_mode) {
pr_info("mode chang\n");
if (logo_info.index >= 0)
osd_enable_hw(logo_info.index, 0);
set_logo_vmode(cur_mode);
pr_info("set vmode: %s\n",
get_current_vinfo()->name);
last_mode = cur_mode;
vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &cur_mode);
if (logo_info.index >= 0)
set_osd_freescaler(logo_info.index, cur_mode);
}
return 0;
}
void aml_logo_work(struct work_struct *work)
{
mutex_lock(&logo_lock);
refresh_mode_and_logo(false);
mutex_unlock(&logo_lock);
if (osd_get_logo_index() == logo_info.index)
schedule_delayed_work(&logo_work, 1*HZ/2);
}
static int logo_info_init(char *para)
{
u32 count = 0;
int value = -1;
count = ARRAY_SIZE(logo_args) / sizeof(logo_args[0]);
count = sizeof(logo_args) / sizeof(logo_args[0]);
value = get_value_by_name(para, logo_args, count);
if (value >= 0) {
switch (value) {
@@ -264,45 +157,52 @@ static int __init logo_setup(char *str)
}
return 0;
}
__setup("logo=", logo_setup);
static int __init get_hdmi_mode(char *str)
int set_osd_logo_freescaler(void)
{
hdmimode = get_current_vmode();
/* hdmimode = vmode_name_to_mode(str); */
pr_info("get hdmimode: %s\n", str);
return 1;
}
__setup("hdmimode=", get_hdmi_mode);
static int __init get_cvbs_mode(char *str)
{
if (strncmp("480", str, 3) == 0)
cvbsmode = 0;//VMODE_480CVBS;//DEBUG_TMP
else if (strncmp("576", str, 3) == 0)
cvbsmode = 0;//VMODE_576CVBS;//DEBUG_TMP
else if (strncmp("nocvbs", str, 6) == 0)
cvbsmode = hdmimode;
pr_info("get cvbsmode: %s\n", str);
return 1;
}
__setup("cvbsmode=", get_cvbs_mode);
static int __init logo_init(void)
{
int ret = 0;
pr_info("%s\n", __func__);
const struct vinfo_s *vinfo;
u32 index = logo_info.index;
if (logo_info.loaded == 0)
return 0;
if (osd_get_logo_index() != logo_info.index) {
pr_info("logo changed, return!\n");
return -1;
}
refresh_mode_and_logo(true);
osd_set_free_scale_mode_hw(index, 1);
osd_set_free_scale_enable_hw(index, 0);
INIT_DELAYED_WORK(&logo_work, aml_logo_work);
schedule_delayed_work(&logo_work, 1*HZ/2);
return ret;
osd_set_free_scale_axis_hw(index, 0, 0, 1919, 1079);
osd_update_disp_axis_hw(index, 0, 1919, 0, 1079, 0, 0, 0);
vinfo = get_current_vinfo();
if (vinfo) {
pr_info("outputmode changed to %s, reset osd%d scaler\n",
vinfo->name, index);
osd_set_window_axis_hw(index, 0, 0,
(vinfo->width - 1), (vinfo->height - 1));
} else {
osd_set_window_axis_hw(index, 0, 0, 1919, 1079);
}
osd_set_free_scale_enable_hw(index, 0x10001);
osd_enable_hw(index, 1);
return 0;
}
void set_logo_loaded(void)
{
logo_info.loaded = 0;
}
__setup("logo=", logo_setup);
int logo_work_init(void)
{
if (logo_info.loaded == 0)
return -1;
osd_set_logo_index(logo_info.index);
return 0;
}
subsys_initcall(logo_init);

View File

@@ -7810,6 +7810,8 @@ static void do_vpu_delay_work(struct work_struct *work)
/*********************************************************/
static int __init video_early_init(void)
{
const struct vinfo_s *vinfo;
/* todo: move this to clock tree, enable VPU clock */
#if DEBUG_TMP
WRITE_CBUS_REG(HHI_VPU_CLK_CNTL,
@@ -7818,8 +7820,11 @@ static int __init video_early_init(void)
(3<<9) | (1<<8) | (0)); // fclk_div7/1 = 364M
//moved to vpu.c, default config by dts
#endif
vinfo = get_current_vinfo();
if (!vinfo)
return -1;
if (get_logo_vmode() >= VMODE_MAX) {
if (vinfo->mode >= VMODE_MAX) {
#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
if (is_meson_gxtvbb_cpu())
WRITE_VCBUS_REG_BITS(VPP_OFIFO_SIZE, 0xfff,
@@ -7851,7 +7856,7 @@ static int __init video_early_init(void)
if (is_meson_gxbb_cpu())
SET_VCBUS_REG_MASK(VPP_MISC, VPP_OUT_SATURATE);
if (get_logo_vmode() >= VMODE_MAX) {
if (vinfo->mode >= VMODE_MAX) {
CLEAR_VCBUS_REG_MASK(VPP_VSC_PHASE_CTRL,
VPP_PHASECTL_TYPE_INTERLACE);
#ifndef CONFIG_FB_AML_TCON
@@ -7860,7 +7865,7 @@ static int __init video_early_init(void)
WRITE_VCBUS_REG(VPP_HOLD_LINES + cur_dev->vpp_off, 0x08080808);
}
#ifdef CONFIG_SUPPORT_VIDEO_ON_VPP2
if (get_logo_vmode() >= VMODE_MAX) {
if (vinfo->mode >= VMODE_MAX) {
CLEAR_VCBUS_REG_MASK(VPP2_VSC_PHASE_CTRL,
VPP_PHASECTL_TYPE_INTERLACE);
#ifndef CONFIG_FB_AML_TCON