osd: add osd driver for axg

PD#146066: osd: add osd driver for axg bringup

Change-Id: Iea6889046d2a0bd0d7c79f106e4d89ed9828d035
Signed-off-by: Pengcheng Chen <pengcheng.chen@amlogic.com>
This commit is contained in:
Pengcheng Chen
2017-05-05 13:48:36 +08:00
committed by Jianxin Pan
parent d640e7be13
commit 44a77d4de8
22 changed files with 745 additions and 207 deletions

View File

@@ -13944,3 +13944,7 @@ AMLOGIC unifykey driver
M: Jiamin Ma <jiamin.ma@amlogic.com>
F: drivers/amlogic/unifykey/*
F: include/linux/amlogic/unifykey/*
AMLOGIC AXG ADD OSD DRIVER
M: Pengcheng Chen <pengcheng.chen@amlogic.com>
F: drivers/amlogic/media/osd/osd_io.c

View File

@@ -623,7 +623,6 @@
mask = <4>;
};
};
}; /* end of / */
/* Audio Related start */

View File

@@ -54,7 +54,15 @@
reg = <0x0 0x05300000 0x0 0x2000000>;
no-map;
};
fb_reserved:linux,meson-fb {
//compatible = "amlogic, fb-memory";
//reg = <0x0 0x3e000000 0x0 0x1f00000>;
compatible = "shared-dma-pool";
reusable;
size = <0x0 0x2000000>;
alignment = <0x0 0x400000>;
alloc-ranges = <0x0 0x3e000000 0x0 0x2000000>;
};
};
@@ -204,6 +212,24 @@
/* 0: 100.0M 1: 166.7M 2: 200.0M 3: 250.0M */
};
meson-fb {
compatible = "amlogic, meson-fb";
memory-region = <&fb_reserved>;
dev_name = "meson-fb";
status = "okay";
interrupts = <0 3 1
0 89 1>;
interrupt-names = "viu-vsync", "rdma";
mem_size = <0x006AF000 0x01851000 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 = <1920 1080 1920 3240 32>;
/*1920*1080*4*3 = 0x17BB000*/
logo_addr = "0x3e000000";
pxp_mode = <1>; /** 0:normal mode 1:pxp mode */
};
}; /* end of / */
&spicc_a{

View File

@@ -55,6 +55,15 @@
reg = <0x0 0x05300000 0x0 0x2000000>;
no-map;
};
fb_reserved:linux,meson-fb {
//compatible = "amlogic, fb-memory";
//reg = <0x0 0x3e000000 0x0 0x1f00000>;
compatible = "shared-dma-pool";
reusable;
size = <0x0 0x2000000>;
alignment = <0x0 0x400000>;
alloc-ranges = <0x0 0x3e000000 0x0 0x2000000>;
};
};
mtd_nand {
compatible = "amlogic, aml_mtd_nand";
@@ -712,7 +721,24 @@
mask = <4>;
};
};
meson-fb {
compatible = "amlogic, meson-fb";
memory-region = <&fb_reserved>;
dev_name = "meson-fb";
status = "okay";
interrupts = <0 3 1
0 89 1>;
interrupt-names = "viu-vsync", "rdma";
mem_size = <0x006AF000 0x01851000 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 = <1920 1080 1920 3240 32>;
/*1920*1080*4*3 = 0x17BB000*/
logo_addr = "0x3e000000";
pxp_mode = <0>; /** 0:normal mode 1:pxp mode */
};
}; /* end of / */
/* Audio Related start */

View File

@@ -55,7 +55,6 @@
reg = <0x0 0x05300000 0x0 0x2000000>;
no-map;
};
};
mtd_nand {
compatible = "amlogic, aml_mtd_nand";

View File

@@ -9,7 +9,7 @@ config AMLOGIC_MEDIA_FB
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
depends on AMLOGIC_MEDIA_CANVAS
# depends on AMLOGIC_MEDIA_CANVAS
# depends on AMLOGIC_VOUT_SERVE
default n
help

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 osd_logo.o
fb-objs = osd_hw.o osd_fb.o osd_debug.o osd_backup.o osd_logo.o osd_io.o
fb-objs += osd_antiflicker.o osd_clone.o
obj-$(CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA) += osd_rdma.o

View File

@@ -41,6 +41,7 @@
#include "osd_antiflicker.h"
#include "osd_log.h"
#include "osd_io.h"
#include "osd_hw.h"
#ifdef OSD_GE2D_ANTIFLICKER_SUPPORT
@@ -63,7 +64,11 @@ void osd_antiflicker_enable(u32 enable)
static int osd_antiflicker_process(void)
{
int ret = -1;
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
struct canvas_s cs, cd;
#endif
u32 cs_addr = 0, cs_width = 0, cs_height = 0;
u32 cd_addr = 0, cd_width = 0, cd_height = 0;
u32 x0 = 0;
u32 y0 = 0;
u32 y1 = 0;
@@ -75,28 +80,47 @@ static int osd_antiflicker_process(void)
context = ge2d_osd_antiflicker.ge2d_context;
mutex_lock(&osd_antiflicker_mutex);
canvas_read(OSD1_CANVAS_INDEX, &cs);
canvas_read(OSD1_CANVAS_INDEX, &cd);
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) {
canvas_read(OSD1_CANVAS_INDEX, &cs);
canvas_read(OSD1_CANVAS_INDEX, &cd);
cs_addr = cs.addr;
cs_width = cs.width;
cs_height = cs.height;
cd_addr = cd.addr;
cd_width = cd.width;
cd_height = cd.height;
} else {
osd_get_info(OSD1, &cs_addr,
&cs_width, &cs_height);
osd_get_info(OSD2, &cs_addr,
&cs_width, &cs_height);
}
#else
osd_get_info(OSD1, &cs_addr,
&cs_width, &cs_height);
osd_get_info(OSD2, &cs_addr,
&cs_width, &cs_height);
#endif
if (ge2d_osd_antiflicker.yoffset > 0) {
y0 = ge2d_osd_antiflicker.yoffset;
y1 = ge2d_osd_antiflicker.yoffset;
}
yres = cs.height / ge2d_osd_antiflicker.yres;
yres = cs_height / ge2d_osd_antiflicker.yres;
memset(ge2d_config, 0, sizeof(struct config_para_ex_s));
ge2d_config->alu_const_color = 0;
ge2d_config->bitmask_en = 0;
ge2d_config->src1_gb_alpha = 0;
ge2d_config->src_planes[0].addr = cs.addr;
ge2d_config->src_planes[0].w = cs.width / 4;
ge2d_config->src_planes[0].h = cs.height;
ge2d_config->src_planes[0].addr = cs_addr;
ge2d_config->src_planes[0].w = cs_width / 4;
ge2d_config->src_planes[0].h = cs_height;
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width / 4;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->dst_planes[0].addr = cd_addr;
ge2d_config->dst_planes[0].w = cd_width / 4;
ge2d_config->dst_planes[0].h = cd_height;
ge2d_config->src_para.canvas_index = OSD1_CANVAS_INDEX;
ge2d_config->src_para.mem_type = CANVAS_OSD0;
@@ -108,16 +132,16 @@ static int osd_antiflicker_process(void)
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
ge2d_config->src_para.width = cs.width / 4;
ge2d_config->src_para.height = cs.height;
ge2d_config->src_para.width = cs_width / 4;
ge2d_config->src_para.height = cs_height;
ge2d_config->dst_para.canvas_index = OSD1_CANVAS_INDEX;
ge2d_config->dst_para.mem_type = CANVAS_OSD0;
ge2d_config->dst_para.format = GE2D_FORMAT_S32_ARGB;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = cd.width / 4;
ge2d_config->dst_para.height = cd.height;
ge2d_config->dst_para.width = cd_width / 4;
ge2d_config->dst_para.height = cd_height;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.color = 0;
@@ -133,8 +157,8 @@ static int osd_antiflicker_process(void)
return ret;
}
stretchblt(context, x0, y0, cs.width / 4, (cs.height / yres), x0, y1,
cd.width / 4, (cd.height / yres));
stretchblt(context, x0, y0, cs_width / 4, (cs_height / yres), x0, y1,
cd_width / 4, (cd_height / yres));
return ret;
}

View File

@@ -40,6 +40,7 @@
#include "osd_log.h"
#include "osd_io.h"
#include "osd_canvas.h"
#include "osd_hw.h"
#ifdef OSD_GE2D_CLONE_SUPPORT
@@ -58,7 +59,11 @@ static struct osd_clone_s s_osd_clone;
static void osd_clone_process(void)
{
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
struct canvas_s cs, cd;
#endif
u32 cs_addr = 0, cs_width = 0, cs_height = 0;
u32 cd_addr = 0, cd_width = 0, cd_height = 0;
u32 x0 = 0;
u32 y0 = 0;
u32 y1 = 0;
@@ -67,10 +72,28 @@ static void osd_clone_process(void)
unsigned char xy_swap = 0;
struct config_para_ex_s *ge2d_config = &s_osd_clone.ge2d_config;
struct ge2d_context_s *context = s_osd_clone.ge2d_context;
canvas_read(OSD1_CANVAS_INDEX, &cs);
canvas_read(OSD2_CANVAS_INDEX, &cd);
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) {
canvas_read(OSD1_CANVAS_INDEX, &cs);
canvas_read(OSD2_CANVAS_INDEX, &cd);
cs_addr = cs.addr;
cs_width = cs.width;
cs_height = cs.height;
cd_addr = cd.addr;
cd_width = cd.width;
cd_height = cd.height;
} else {
osd_get_info(OSD1, &cs_addr,
&cs_width, &cs_height);
osd_get_info(OSD2, &cs_addr,
&cs_width, &cs_height);
}
#else
osd_get_info(OSD1, &cs_addr,
&cs_width, &cs_height);
osd_get_info(OSD2, &cs_addr,
&cs_width, &cs_height);
#endif
y0 = s_osd_clone.osd1_yres * s_osd_clone.buffer_number;
y1 = s_osd_clone.osd2_yres * s_osd_clone.buffer_number;
@@ -91,13 +114,13 @@ static void osd_clone_process(void)
ge2d_config->src1_gb_alpha = 0;
ge2d_config->dst_xy_swap = 0;
ge2d_config->src_planes[0].addr = cs.addr;
ge2d_config->src_planes[0].w = cs.width / 4;
ge2d_config->src_planes[0].h = cs.height;
ge2d_config->src_planes[0].addr = cs_addr;
ge2d_config->src_planes[0].w = cs_width / 4;
ge2d_config->src_planes[0].h = cs_height;
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width / 4;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->dst_planes[0].addr = cd_addr;
ge2d_config->dst_planes[0].w = cd_width / 4;
ge2d_config->dst_planes[0].h = cd_height;
ge2d_config->src_para.canvas_index = OSD1_CANVAS_INDEX;
ge2d_config->src_para.mem_type = CANVAS_OSD0;
@@ -109,16 +132,16 @@ static void osd_clone_process(void)
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
ge2d_config->src_para.width = cs.width / 4;
ge2d_config->src_para.height = cs.height;
ge2d_config->src_para.width = cs_width / 4;
ge2d_config->src_para.height = cs_height;
ge2d_config->dst_para.canvas_index = OSD2_CANVAS_INDEX;
ge2d_config->dst_para.mem_type = CANVAS_OSD1;
ge2d_config->dst_para.format = GE2D_FORMAT_S32_ABGR;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = cd.width / 4;
ge2d_config->dst_para.height = cd.height;
ge2d_config->dst_para.width = cd_width / 4;
ge2d_config->dst_para.height = cd_height;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.color = 0;
@@ -131,8 +154,9 @@ static void osd_clone_process(void)
return;
}
stretchblt(context, x0, y0, cs.width / 4, s_osd_clone.osd1_yres, x0, y1,
cd.width / 4, s_osd_clone.osd2_yres);
stretchblt(context, x0, y0, cs_width / 4,
s_osd_clone.osd1_yres, x0, y1,
cd_width / 4, s_osd_clone.osd2_yres);
}
void osd_clone_update_pan(int buffer_number)

View File

@@ -125,6 +125,7 @@ static void osd_debug_dump_register_all(void)
u32 reg = 0;
u32 offset = 0;
u32 index = 0;
u32 count = 2;
reg = VPU_VIU_VENC_MUX_CTRL;
osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg));
@@ -142,14 +143,18 @@ static void osd_debug_dump_register_all(void)
osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg));
reg = VPP_OSD_SCO_V_START_END;
osd_log_info("reg[0x%x]: 0x%08x\n\n", reg, osd_reg_read(reg));
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXLX) {
if (get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX) {
reg = OSD_DB_FLT_CTRL;
osd_log_info("reg[0x%x]: 0x%08x\n\n", reg, osd_reg_read(reg));
}
for (index = 0; index < 2; index++) {
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
count = 1;
for (index = 0; index < count; index++) {
if (index == 1)
offset = REG_OFFSET;
reg = offset + VIU_OSD1_FIFO_CTRL_STAT;
osd_log_info("reg[0x%x]: 0x%08x\n", reg, osd_reg_read(reg));
reg = offset + VIU_OSD1_CTRL_STAT;
@@ -180,6 +185,16 @@ static void osd_debug_dump_register_all(void)
osd_log_info("reg[0x%x]: 0x%08x\n",
reg, osd_reg_read(reg));
}
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) {
reg = VIU_OSD1_BLK1_CFG_W4;
osd_log_info("reg[0x%x]: 0x%08x\n",
reg, osd_reg_read(reg));
reg = VIU_OSD1_BLK2_CFG_W4;
osd_log_info("reg[0x%x]: 0x%08x\n",
reg, osd_reg_read(reg));
}
}
static void osd_debug_dump_register_region(u32 start, u32 end)
@@ -195,7 +210,8 @@ static void osd_debug_dump_register(int argc, char **argv)
int ret;
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
read_rdma_table();
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG)
read_rdma_table();
#endif
if ((argc == 3) && argv[1] && argv[2]) {
ret = kstrtoint(argv[1], 16, &reg_start);
@@ -241,12 +257,12 @@ static void osd_test_colorbar(void)
u32 gclk_other = 0;
u32 encp_video_adv = 0;
gclk_other = aml_read_cbus(HHI_GCLK_OTHER);
gclk_other = osd_cbus_read(HHI_GCLK_OTHER);
encp_video_adv = osd_reg_read(ENCP_VIDEO_MODE_ADV);
/* start test mode */
osd_log_info("--- OSD TEST COLORBAR ---\n");
aml_write_cbus(HHI_GCLK_OTHER, 0xFFFFFFFF);
osd_cbus_write(HHI_GCLK_OTHER, 0xFFFFFFFF);
osd_reg_write(ENCP_VIDEO_MODE_ADV, 0);
osd_reg_write(VENC_VIDEO_TST_EN, 1);
/* TST_MODE COLORBAR */
@@ -264,7 +280,7 @@ static void osd_test_colorbar(void)
msleep(OSD_TEST_DURATION);
/* stop test mode */
aml_write_cbus(HHI_GCLK_OTHER, gclk_other);
osd_cbus_write(HHI_GCLK_OTHER, gclk_other);
osd_reg_write(ENCP_VIDEO_MODE_ADV, encp_video_adv);
osd_reg_write(VENC_VIDEO_TST_EN, 0);
osd_reg_write(VENC_VIDEO_TST_MDSEL, 0);
@@ -300,12 +316,27 @@ static void osd_test_rect(void)
u32 w = 0;
u32 h = 0;
u32 color = 0;
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
struct canvas_s cs;
#endif
u32 cs_addr, cs_width, cs_height;
struct config_para_s *cfg = &ge2d_config;
struct config_para_ex_s *cfg_ex = &ge2d_config_ex;
struct ge2d_context_s *context = ge2d_context;
canvas_read(OSD1_CANVAS_INDEX, &cs);
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) {
canvas_read(OSD1_CANVAS_INDEX, &cs);
cs_addr = cs.addr;
cs_width = cs.width;
cs_height = cs.height;
} else
osd_get_info(0, &cs_addr,
&cs_width, &cs_height);
#else
osd_get_info(0, &cs_addr,
&cs_width, &cs_height);
#endif
context = create_ge2d_work_queue();
if (!context) {
osd_log_err("create work queue error\n");
@@ -315,12 +346,12 @@ static void osd_test_rect(void)
memset(cfg, 0, sizeof(struct config_para_s));
cfg->src_dst_type = OSD0_OSD0;
cfg->src_format = GE2D_FORMAT_S32_ARGB;
cfg->src_planes[0].addr = cs.addr;
cfg->src_planes[0].w = cs.width / 4;
cfg->src_planes[0].h = cs.height;
cfg->dst_planes[0].addr = cs.addr;
cfg->dst_planes[0].w = cs.width / 4;
cfg->dst_planes[0].h = cs.height;
cfg->src_planes[0].addr = cs_addr;
cfg->src_planes[0].w = cs_width / 4;
cfg->src_planes[0].h = cs_height;
cfg->dst_planes[0].addr = cs_addr;
cfg->dst_planes[0].w = cs_width / 4;
cfg->dst_planes[0].h = cs_height;
if (ge2d_context_config(context, cfg) < 0) {
osd_log_err("ge2d config error.\n");
@@ -329,8 +360,8 @@ static void osd_test_rect(void)
x = 0;
y = 0;
w = cs.width / 4;
h = cs.height;
w = cs_width / 4;
h = cs_height;
color = 0x0;
osd_log_info("- BLACK -");
osd_log_info("- (%d, %d)-(%d, %d) -\n", x, y, w, h);
@@ -362,12 +393,12 @@ static void osd_test_rect(void)
msleep(OSD_TEST_DURATION);
memset(cfg_ex, 0, sizeof(struct config_para_ex_s));
cfg_ex->src_planes[0].addr = cs.addr;
cfg_ex->src_planes[0].w = cs.width / 4;
cfg_ex->src_planes[0].h = cs.height;
cfg_ex->dst_planes[0].addr = cs.addr;
cfg_ex->dst_planes[0].w = cs.width / 4;
cfg_ex->dst_planes[0].h = cs.height;
cfg_ex->src_planes[0].addr = cs_addr;
cfg_ex->src_planes[0].w = cs_width / 4;
cfg_ex->src_planes[0].h = cs_height;
cfg_ex->dst_planes[0].addr = cs_addr;
cfg_ex->dst_planes[0].w = cs_width / 4;
cfg_ex->dst_planes[0].h = cs_height;
cfg_ex->src_para.canvas_index = OSD1_CANVAS_INDEX;
cfg_ex->src_para.mem_type = CANVAS_OSD0;
@@ -379,16 +410,16 @@ static void osd_test_rect(void)
cfg_ex->src_para.color = 0xffffffff;
cfg_ex->src_para.top = 0;
cfg_ex->src_para.left = 0;
cfg_ex->src_para.width = cs.width / 4;
cfg_ex->src_para.height = cs.height;
cfg_ex->src_para.width = cs_width / 4;
cfg_ex->src_para.height = cs_height;
cfg_ex->dst_para.canvas_index = OSD1_CANVAS_INDEX;
cfg_ex->dst_para.mem_type = CANVAS_OSD0;
cfg_ex->dst_para.format = GE2D_FORMAT_S32_ARGB;
cfg_ex->dst_para.top = 0;
cfg_ex->dst_para.left = 0;
cfg_ex->dst_para.width = cs.width / 4;
cfg_ex->dst_para.height = cs.height;
cfg_ex->dst_para.width = cs_width / 4;
cfg_ex->dst_para.height = cs_height;
cfg_ex->dst_para.fill_color_en = 0;
cfg_ex->dst_para.fill_mode = 0;
cfg_ex->dst_para.color = 0;
@@ -409,7 +440,8 @@ static void osd_test_rect(void)
static void osd_debug_auto_test(void)
{
osd_test_colorbar();
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG)
osd_test_colorbar();
osd_test_dummydata();

View File

@@ -46,6 +46,7 @@
#include <linux/cma.h>
#include <linux/dma-contiguous.h>
/* Amlogic Headers */
#include <linux/amlogic/cpu_version.h>
#include <linux/amlogic/media/vout/vinfo.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#ifdef CONFIG_INSTABOOT
@@ -57,7 +58,7 @@
#include "osd_hw.h"
#include "osd_log.h"
#include "osd_sync.h"
#include "osd_io.h"
static __u32 var_screeninfo[5];
struct osd_info_s osd_info = {
@@ -312,12 +313,18 @@ static void __iomem *fb_rmem_afbc_vaddr[OSD_COUNT][OSD_MAX_BUF_NUM];
static size_t fb_rmem_afbc_size[OSD_COUNT][OSD_MAX_BUF_NUM];
struct ion_client *fb_ion_client;
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE
struct ion_handle *fb_ion_handle[OSD_COUNT][OSD_MAX_BUF_NUM] = {
{NULL, NULL, NULL}, {NULL, NULL, NULL}
};
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR
static int osd_cursor(struct fb_info *fbi, struct fb_cursor *var);
#else
struct ion_handle *fb_ion_handle[OSD_COUNT][OSD_MAX_BUF_NUM] = {
{NULL, NULL, NULL}
};
#endif
phys_addr_t get_fb_rmem_paddr(int index)
{
if (index < 0 || index > 1)
@@ -1060,6 +1067,13 @@ static int osd_open(struct fb_info *info, int arg)
__func__, __LINE__, base, size);
pdev = fbdev->dev;
fb_index = fbdev->fb_index;
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
if (fb_index >= 1)
return -1;
#ifndef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE
if (fb_index >= 1)
return -1;
#endif
fix = &info->fix;
var = &info->var;
/* read cma/fb-reserved memory first */
@@ -2606,12 +2620,20 @@ static int osd_probe(struct platform_device *pdev)
} else
osd_log_info("viu vsync irq: %d\n", int_viu_vsync);
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
int_rdma = platform_get_irq_byname(pdev, "rdma");
if (int_viu_vsync == -ENXIO) {
osd_log_err("cannot get osd rdma irq resource\n");
goto failed1;
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) {
int_rdma = platform_get_irq_byname(pdev, "rdma");
if (int_viu_vsync == -ENXIO) {
osd_log_err("cannot get osd rdma irq resource\n");
goto failed1;
}
}
#endif
ret = osd_io_remap();
if (!ret) {
osd_log_err("osd_io_remap failed\n");
goto failed1;
}
/* init osd logo */
ret = logo_work_init();
if (ret == 0)
@@ -2706,6 +2728,7 @@ static int osd_probe(struct platform_device *pdev)
fb_def_var[index].width = vinfo->screen_real_width;
fb_def_var[index].height = vinfo->screen_real_height;
}
/* setup fb0 display size */
if (index == DEV_OSD0) {
ret = of_property_read_u32_array(pdev->dev.of_node,

View File

@@ -483,6 +483,7 @@ int osd_sync_request_render(u32 index, u32 yres,
}
#endif
void osd_update_3d_mode(void)
{
/* only called by vsync irq or rdma irq */
@@ -509,6 +510,92 @@ void osd_update_vsync_hit(void)
}
}
/* the return stride unit is 128bit(16bytes) */
static u32 line_stride_calc(
u32 fmt_mode,
u32 hsize,
u32 stride_align_32bytes)
{
u32 line_stride = 0;
switch (fmt_mode) {
/* 2-bit LUT */
case COLOR_INDEX_02_PAL4:
line_stride = ((hsize<<1)+127)>>7;
break;
/* 4-bit LUT */
case COLOR_INDEX_04_PAL16:
line_stride = ((hsize<<2)+127)>>7;
break;
/* 8-bit LUT */
case COLOR_INDEX_08_PAL256:
line_stride = ((hsize<<3)+127)>>7;
break;
/* 4:2:2, 32-bit per 2 pixels */
case COLOR_INDEX_YUV_422:
line_stride = ((((hsize+1)>>1)<<5)+127)>>7;
break;
/* 16-bit LUT */
case COLOR_INDEX_16_655:
case COLOR_INDEX_16_844:
case COLOR_INDEX_16_6442:
case COLOR_INDEX_16_4444_R:
case COLOR_INDEX_16_4642_R:
case COLOR_INDEX_16_1555_A:
case COLOR_INDEX_16_4444_A:
case COLOR_INDEX_16_565:
line_stride = ((hsize<<4)+127)>>7;
break;
/* 32-bit LUT */
case COLOR_INDEX_32_BGRX:
case COLOR_INDEX_32_XBGR:
case COLOR_INDEX_32_RGBX:
case COLOR_INDEX_32_XRGB:
case COLOR_INDEX_32_BGRA:
case COLOR_INDEX_32_ABGR:
case COLOR_INDEX_32_RGBA:
case COLOR_INDEX_32_ARGB:
line_stride = ((hsize<<5)+127)>>7;
break;
/* 24-bit LUT */
case COLOR_INDEX_24_6666_A:
case COLOR_INDEX_24_6666_R:
case COLOR_INDEX_24_8565:
case COLOR_INDEX_24_5658:
case COLOR_INDEX_24_888_B:
case COLOR_INDEX_24_RGB:
line_stride = ((hsize<<4)+(hsize<<3)+127)>>7;
break;
}
/* need wr ddr is 32bytes aligned */
if (stride_align_32bytes)
line_stride = ((line_stride+1)>>1)<<1;
else
line_stride = line_stride;
return line_stride;
}
static void osd_update_phy_addr(u32 index)
{
u32 line_stride, bpp;
u32 fmt_mode = COLOR_INDEX_32_BGRX;
if (osd_hw.color_info[index])
fmt_mode =
osd_hw.color_info[index]->color_index;
bpp = osd_hw.color_info[index]->bpp / 8;
line_stride = line_stride_calc(fmt_mode,
osd_hw.fb_gem[index].width / bpp, 1);
VSYNCOSD_WR_MPEG_REG(
VIU_OSD1_BLK1_CFG_W4,
osd_hw.fb_gem[index].addr);
VSYNCOSD_WR_MPEG_REG_BITS(
VIU_OSD1_BLK2_CFG_W4,
line_stride,
0, 12);
}
static void osd_update_interlace_mode(void)
{
/* only called by vsync irq or rdma irq */
@@ -550,9 +637,10 @@ static void osd_update_interlace_mode(void)
}
}
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
/* when RDMA enabled, top/bottom fields changed in next vsync */
odd_even = (odd_even == OSD_TYPE_TOP_FIELD) ?
OSD_TYPE_BOT_FIELD : OSD_TYPE_TOP_FIELD;
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG)
/* when RDMA enabled, top/bottom fields changed in next vsync */
odd_even = (odd_even == OSD_TYPE_TOP_FIELD) ?
OSD_TYPE_BOT_FIELD : OSD_TYPE_TOP_FIELD;
#endif
fb0_cfg_w0 &= ~1;
fb1_cfg_w0 &= ~1;
@@ -709,7 +797,8 @@ void osd_hw_reset(void)
}
}
#else
osd_rdma_reset_and_flush(reset_bit);
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG)
osd_rdma_reset_and_flush(reset_bit);
#endif
spin_unlock_irqrestore(&osd_lock, lock_flags);
/* maybe change reset bit */
@@ -726,10 +815,11 @@ static int notify_to_amvideo(void)
"osd notify_to_amvideo vpp misc:0x%08x, mask:0x%08x\n",
para[0], para[1]);
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
#ifdef CONFIG_AMLOGIC_MEDIA_VIDEO
amvideo_notifier_call_chain(
AMVIDEO_UPDATE_OSD_MODE,
(void *)&para[0]);
#ifdef CONFIG_AMLOGIC_VIDEO
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG)
amvideo_notifier_call_chain(
AMVIDEO_UPDATE_OSD_MODE,
(void *)&para[0]);
#endif
#endif
return 0;
@@ -756,7 +846,16 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
osd_update_vsync_hit();
osd_hw_reset();
#else
osd_rdma_interrupt_done_clear();
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG)
osd_rdma_interrupt_done_clear();
else {
osd_update_scan_mode();
/* go through update list */
walk_through_update_list();
osd_update_3d_mode();
osd_update_vsync_hit();
osd_hw_reset();
}
#endif
#ifndef FIQ_VSYNC
return IRQ_HANDLED;
@@ -1081,7 +1180,7 @@ void osd_setup_hw(u32 index,
int update_color_mode = 0;
int update_geometry = 0;
u32 w = (color->bpp * xres_virtual + 7) >> 3;
u32 i;
u32 i, cpu_type;
pan_data.x_start = xoffset;
pan_data.y_start = yoffset;
@@ -1104,6 +1203,14 @@ void osd_setup_hw(u32 index,
disp_data.x_end = disp_end_x;
disp_data.y_end = disp_end_y;
}
/* need always set color mode for osd2 */
if ((color != osd_hw.color_info[index]) || (index == OSD2)) {
update_color_mode = 1;
osd_hw.color_info[index] = color;
osd_hw.color_backup[index] = color;
}
if (osd_hw.fb_gem[index].addr != fbmem
|| osd_hw.fb_gem[index].width != w
|| osd_hw.fb_gem[index].height != yres_virtual) {
@@ -1159,21 +1266,21 @@ void osd_setup_hw(u32 index,
index, osd_hw.fb_gem[index].xres);
osd_log_info("osd[%d] frame.height=%d\n",
index, osd_hw.fb_gem[index].yres);
cpu_type = get_cpu_type();
if (cpu_type == MESON_CPU_MAJOR_ID_AXG)
osd_update_phy_addr(0);
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
canvas_config(osd_hw.fb_gem[index].canvas_idx,
osd_hw.fb_gem[index].addr,
osd_hw.fb_gem[index].width,
osd_hw.fb_gem[index].height,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
else {
canvas_config(osd_hw.fb_gem[index].canvas_idx,
osd_hw.fb_gem[index].addr,
osd_hw.fb_gem[index].width,
osd_hw.fb_gem[index].height,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
}
#endif
}
/* need always set color mode for osd2 */
if ((color != osd_hw.color_info[index]) || (index == OSD2)) {
update_color_mode = 1;
osd_hw.color_info[index] = color;
osd_hw.color_backup[index] = color;
}
/* osd blank only control by /sys/class/graphcis/fbx/blank */
#if 0
if (osd_hw.enable[index] == DISABLE) {
@@ -1265,6 +1372,8 @@ static void osd_set_free_scale_enable_mode1(u32 index, u32 enable)
unsigned int v_enable = 0;
int ret = 0;
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
return;
h_enable = (enable & 0xffff0000 ? 1 : 0);
v_enable = (enable & 0xffff ? 1 : 0);
osd_hw.free_scale[index].h_enable = h_enable;
@@ -2260,6 +2369,13 @@ void osd_pan_display_hw(u32 index, unsigned int xoffset, unsigned int yoffset)
osd_hw.pandata[index].y_end);
}
void osd_get_info(u32 index, u32 *addr, u32 *width, u32 *height)
{
*addr = osd_hw.fb_gem[index].addr;
*width = osd_hw.fb_gem[index].width;
*height = osd_hw.fb_gem[index].height;
}
static void osd1_update_disp_scale_enable(void)
{
if (osd_hw.scale[OSD1].h_enable)
@@ -3583,7 +3699,6 @@ void osd_init_hw(u32 logo_loaded)
int err_num = 0;
osd_vpu_power_on();
if (get_cpu_type() ==
MESON_CPU_MAJOR_ID_GXTVBB)
backup_regs_init(HW_RESET_AFBCD_REGS);
@@ -3609,7 +3724,6 @@ void osd_init_hw(u32 logo_loaded)
osd_hdr_on = false;
#endif
osd_hw.hw_reset_flag = HW_RESET_NONE;
/* here we will init default value ,these value only set once . */
if (!logo_loaded) {
/* init vpu fifo control register */
@@ -3617,6 +3731,8 @@ void osd_init_hw(u32 logo_loaded)
if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) ||
(get_cpu_type() == MESON_CPU_MAJOR_ID_GXM))
data32 |= 0xfff;
else if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
data32 |= 0x400;
else
data32 |= 0x77f;
osd_reg_write(VPP_OFIFO_SIZE, data32);
@@ -3674,6 +3790,7 @@ void osd_init_hw(u32 logo_loaded)
osd_reg_clr_mask(VPP_MISC, VPP_POST_FG_OSD2 | VPP_PRE_FG_OSD2);
osd_hw.order = OSD_ORDER_01;
#endif
osd_hw.enable[OSD2] = osd_hw.enable[OSD1] = DISABLE;
osd_hw.fb_gem[OSD1].canvas_idx = OSD1_CANVAS_INDEX;
osd_hw.fb_gem[OSD2].canvas_idx = OSD2_CANVAS_INDEX;
@@ -3746,7 +3863,6 @@ void osd_init_hw(u32 logo_loaded)
* osd_hw.osd_afbcd[OSD2].enable = 0;
*/
/* memset(osd_hw.rotate, 0, sizeof(struct osd_rotate_s)); */
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_SYNC_FENCE
INIT_LIST_HEAD(&post_fence_list);
mutex_init(&post_fence_list_lock);
@@ -3768,9 +3884,9 @@ void osd_init_hw(u32 logo_loaded)
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
osd_rdma_enable(1);
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG)
osd_rdma_enable(1);
#endif
}
#if defined(CONFIG_AMLOGIC_MEDIA_FB_OSD2_CURSOR)
@@ -3881,11 +3997,16 @@ void osd_resume_hw(void)
void osd_shutdown_hw(void)
{
int cpu_type;
cpu_type = get_cpu_type();
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
enable_rdma(0);
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
enable_rdma(0);
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
osd_rdma_enable(0);
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
osd_rdma_enable(0);
#endif
pr_info("osd_shutdown\n");
}
@@ -3908,15 +4029,22 @@ void osd_realdata_restore_hw(void)
void osd_freeze_hw(void)
{
int cpu_type;
cpu_type = get_cpu_type();
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
enable_rdma(0);
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
enable_rdma(0);
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
osd_rdma_enable(0);
if (get_backup_reg(VIU_OSD1_BLK0_CFG_W0,
&fb0_cfg_w0_save) != 0)
fb0_cfg_w0_save =
osd_reg_read(VIU_OSD1_BLK0_CFG_W0);
if (cpu_type != MESON_CPU_MAJOR_ID_AXG) {
osd_rdma_enable(0);
if (get_backup_reg(VIU_OSD1_BLK0_CFG_W0,
&fb0_cfg_w0_save) != 0)
fb0_cfg_w0_save =
osd_reg_read(VIU_OSD1_BLK0_CFG_W0);
} else
fb0_cfg_w0_save = osd_reg_read(VIU_OSD1_BLK0_CFG_W0);
#else
fb0_cfg_w0_save = osd_reg_read(VIU_OSD1_BLK0_CFG_W0);
#endif
@@ -3924,28 +4052,46 @@ void osd_freeze_hw(void)
}
void osd_thaw_hw(void)
{
int cpu_type;
pr_debug("osd_thawed\n");
cpu_type = get_cpu_type();
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
osd_rdma_enable(2);
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
osd_rdma_enable(2);
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
enable_rdma(1);
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
enable_rdma(1);
#endif
}
void osd_restore_hw(void)
{
int cpu_type;
cpu_type = get_cpu_type();
osd_reg_write(VIU_OSD1_BLK0_CFG_W0, fb0_cfg_w0_save);
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
osd_rdma_enable(2);
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
osd_rdma_enable(2);
#endif
#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
enable_rdma(1);
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
enable_rdma(1);
#endif
canvas_config(osd_hw.fb_gem[0].canvas_idx,
if (cpu_type == MESON_CPU_MAJOR_ID_AXG)
osd_update_phy_addr(0);
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
else {
canvas_config(osd_hw.fb_gem[0].canvas_idx,
osd_hw.fb_gem[0].addr,
osd_hw.fb_gem[0].width,
osd_hw.fb_gem[0].height,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
}
#endif
pr_debug("osd_restored\n");
}
#endif

View File

@@ -151,6 +151,7 @@ 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);
extern void osd_get_info(u32 index, u32 *addr, u32 *width, u32 *height);
int logo_work_init(void);
void set_logo_loaded(void);
int set_osd_logo_freescaler(void);

View File

@@ -0,0 +1,158 @@
/*
* drivers/amlogic/media/osd/osd_io.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* 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/amlogic/iomap.h>
#include <linux/io.h>
#include <linux/amlogic/cpu_version.h>
/* Local Headers */
#include "osd_log.h"
#include "osd_backup.h"
#define OSDBUS_REG_ADDR(reg) (reg << 2)
struct reg_map_s {
unsigned int phy_addr;
unsigned int size;
void __iomem *vir_addr;
int flag;
};
static struct reg_map_s osd_reg_map = {
.phy_addr = 0xff900000,
.size = 0x10000,
};
int osd_io_remap(void)
{
int ret = 0;
u32 cpu_type;
cpu_type = get_cpu_type();
if (cpu_type == MESON_CPU_MAJOR_ID_AXG) {
if (osd_reg_map.flag)
return 1;
osd_reg_map.vir_addr =
ioremap(osd_reg_map.phy_addr, osd_reg_map.size);
if (!osd_reg_map.vir_addr) {
pr_info("failed map phy: 0x%x\n", osd_reg_map.phy_addr);
ret = 0;
} else {
osd_reg_map.flag = 1;
pr_info("mapped phy: 0x%x\n", osd_reg_map.phy_addr);
ret = 1;
}
} else
ret = 1;
return ret;
}
uint32_t osd_cbus_read(uint32_t reg)
{
uint32_t ret = 0;
u32 cpu_type;
unsigned int addr = 0;
cpu_type = get_cpu_type();
if (cpu_type == MESON_CPU_MAJOR_ID_AXG) {
addr = OSDBUS_REG_ADDR(reg);
ret = readl(osd_reg_map.vir_addr + addr);
} else
ret = (uint32_t)aml_read_cbus(reg);
osd_log_dbg3("%s(0x%x)=0x%x\n", __func__, reg, ret);
return ret;
};
void osd_cbus_write(uint32_t reg,
const uint32_t val)
{
u32 cpu_type;
unsigned int addr = 0;
cpu_type = get_cpu_type();
if (cpu_type == MESON_CPU_MAJOR_ID_AXG) {
addr = OSDBUS_REG_ADDR(reg);
writel(val, osd_reg_map.vir_addr + addr);
} else
aml_write_cbus(reg, val);
osd_log_dbg3("%s(0x%x, 0x%x)\n", __func__, reg, val);
};
uint32_t osd_reg_read(uint32_t reg)
{
uint32_t ret = 0;
u32 cpu_type;
unsigned int addr = 0;
/* if (get_backup_reg(reg, &ret) != 0) */
/* not read from bakcup */
cpu_type = get_cpu_type();
if (cpu_type == MESON_CPU_MAJOR_ID_AXG) {
addr = OSDBUS_REG_ADDR(reg);
ret = readl(osd_reg_map.vir_addr + addr);
} else
ret = (uint32_t)aml_read_vcbus(reg);
osd_log_dbg3("%s(0x%x)=0x%x\n", __func__, reg, ret);
return ret;
};
void osd_reg_write(uint32_t reg,
const uint32_t val)
{
u32 cpu_type;
unsigned int addr = 0;
cpu_type = get_cpu_type();
if (cpu_type == MESON_CPU_MAJOR_ID_AXG) {
addr = OSDBUS_REG_ADDR(reg);
writel(val, osd_reg_map.vir_addr + addr);
} else
aml_write_vcbus(reg, val);
update_backup_reg(reg, val);
osd_log_dbg3("%s(0x%x, 0x%x)\n", __func__, reg, val);
};
void osd_reg_set_mask(uint32_t reg,
const uint32_t mask)
{
osd_reg_write(reg, (osd_reg_read(reg) | (mask)));
}
void osd_reg_clr_mask(uint32_t reg,
const uint32_t mask)
{
osd_reg_write(reg, (osd_reg_read(reg) & (~(mask))));
}
void osd_reg_set_bits(uint32_t reg,
const uint32_t value,
const uint32_t start,
const uint32_t len)
{
osd_reg_write(reg, ((osd_reg_read(reg) &
~(((1L << (len)) - 1) << (start))) |
(((value) & ((1L << (len)) - 1)) << (start))));
}

View File

@@ -17,74 +17,25 @@
#ifndef _OSD_IO_H_
#define _OSD_IO_H_
#include <linux/amlogic/iomap.h>
/* Local Headers */
#include "osd_log.h"
#include "osd_backup.h"
static inline uint32_t osd_cbus_read(uint32_t reg)
{
uint32_t ret = 0;
ret = (uint32_t)aml_read_cbus(reg);
osd_log_dbg3("%s(0x%x)=0x%x\n", __func__, reg, ret);
return ret;
};
static inline void osd_cbus_write(uint32_t reg,
const uint32_t val)
{
uint32_t ret = 0;
aml_write_cbus(reg, val);
ret = aml_read_cbus(reg);
osd_log_dbg3("%s(0x%x, 0x%x)=0x%x\n", __func__, reg, val, ret);
};
static inline uint32_t osd_reg_read(uint32_t reg)
{
uint32_t ret = 0;
/* if (get_backup_reg(reg, &ret) != 0) */
/* not read from bakcup */
ret = (uint32_t)aml_read_vcbus(reg);
osd_log_dbg3("%s(0x%x)=0x%x\n", __func__, reg, ret);
return ret;
};
static inline void osd_reg_write(uint32_t reg,
const uint32_t val)
{
aml_write_vcbus(reg, val);
update_backup_reg(reg, val);
osd_log_dbg3("%s(0x%x, 0x%x)\n", __func__, reg, val);
};
static inline void osd_reg_set_mask(uint32_t reg,
const uint32_t mask)
{
osd_reg_write(reg, (osd_reg_read(reg) | (mask)));
}
static inline void osd_reg_clr_mask(uint32_t reg,
const uint32_t mask)
{
osd_reg_write(reg, (osd_reg_read(reg) & (~(mask))));
}
static inline void osd_reg_set_bits(uint32_t reg,
int osd_io_remap(void);
uint32_t osd_cbus_read(uint32_t reg);
void osd_cbus_write(uint32_t reg,
const uint32_t val);
uint32_t osd_reg_read(uint32_t reg);
void osd_reg_write(uint32_t reg,
const uint32_t val);
void osd_reg_set_mask(uint32_t reg,
const uint32_t mask);
void osd_reg_clr_mask(uint32_t reg,
const uint32_t mask);
void osd_reg_set_bits(uint32_t reg,
const uint32_t value,
const uint32_t start,
const uint32_t len)
{
osd_reg_write(reg, ((osd_reg_read(reg) &
~(((1L << (len)) - 1) << (start))) |
(((value) & ((1L << (len)) - 1)) << (start))));
}
const uint32_t len);
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD_VSYNC_RDMA
u32 VSYNCOSD_RD_MPEG_REG(u32 reg);

View File

@@ -23,6 +23,7 @@
#include <linux/delay.h>
/* Amlogic Headers */
#include <linux/amlogic/cpu_version.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/amlogic/media/vout/hdmi_tx/hdmi_tx_module.h>
@@ -170,6 +171,11 @@ int set_osd_logo_freescaler(void)
pr_info("logo changed, return!\n");
return -1;
}
#ifdef CONFIG_AMLOGIC_MEDIA_FB_OSD2_ENABLE
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
if (index >= 1)
return -1;
#endif
osd_set_free_scale_mode_hw(index, 1);
osd_set_free_scale_enable_hw(index, 0);

View File

@@ -26,6 +26,7 @@
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/amlogic/media/canvas/canvas.h>
#include <linux/amlogic/media/canvas/canvas_mgr.h>
#include <linux/amlogic/cpu_version.h>
#include "osd_canvas.h"
#include "osd_fb.h"
@@ -156,11 +157,17 @@ int osd_init_progress_bar(void)
struct src_dst_info_s *op_info = &progress_bar.op_info;
const struct vinfo_s *vinfo = progress_bar.vinfo;
struct osd_fb_dev_s *fb_dev;
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
struct canvas_s cs;
#endif
u32 cs_addr, cs_width, cs_height;
struct config_para_s *cfg = &ge2d_config;
struct ge2d_context_s *context = ge2d_context;
u32 step = 1;
if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG)
return 0;
memset(&progress_bar, 0, sizeof(struct osd_progress_bar_s));
vinfo = get_current_vinfo();
@@ -182,8 +189,16 @@ int osd_init_progress_bar(void)
pr_debug("fb1 should exit!!!");
return -EFAULT;
}
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
canvas_read(OSD2_CANVAS_INDEX, &cs);
cs_addr = cs.addr;
cs_width = cs.width / 4;
cs_height = cs.height;
#else
cs_addr = 0;
cs_width = 0;
cs_height = 0;
#endif
context = create_ge2d_work_queue();
if (!context) {
pr_debug("create work queue error\n");
@@ -193,12 +208,12 @@ int osd_init_progress_bar(void)
memset(cfg, 0, sizeof(struct config_para_s));
cfg->src_dst_type = OSD1_OSD1;
cfg->src_format = GE2D_FORMAT_S32_ARGB;
cfg->src_planes[0].addr = cs.addr;
cfg->src_planes[0].w = cs.width / 4;
cfg->src_planes[0].h = cs.height;
cfg->dst_planes[0].addr = cs.addr;
cfg->dst_planes[0].w = cs.width / 4;
cfg->dst_planes[0].h = cs.height;
cfg->src_planes[0].addr = cs_addr;
cfg->src_planes[0].w = cs_width;
cfg->src_planes[0].h = cs_height;
cfg->dst_planes[0].addr = cs_addr;
cfg->dst_planes[0].w = cs_width;
cfg->dst_planes[0].h = cs_height;
if (ge2d_context_config(context, cfg) < 0) {
pr_debug("ge2d config error.\n");

View File

@@ -41,7 +41,7 @@
#include <osd/osd_log.h>
#include <osd/osd_canvas.h>
#include "osd_clone.h"
#include "osd_hw.h"
#ifdef OSD_EXT_GE2D_CLONE_SUPPORT
struct osd_ext_clone_s {
@@ -57,7 +57,12 @@ static struct osd_ext_clone_s s_osd_ext_clone;
static void osd_clone_process(void)
{
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
struct canvas_s cs, cd;
#endif
u32 cs_addr = 0, cs_width = 0, cs_height = 0;
u32 cd_addr = 0, cd_width = 0, cd_height = 0;
u32 x0 = 0;
u32 y0 = 0;
u32 y1 = 0;
@@ -66,13 +71,31 @@ static void osd_clone_process(void)
unsigned char xy_swap = 0;
struct config_para_ex_s *ge2d_config = &s_osd_ext_clone.ge2d_config;
struct ge2d_context_s *context = s_osd_ext_clone.ge2d_context;
canvas_read(OSD1_CANVAS_INDEX, &cs);
canvas_read(OSD3_CANVAS_INDEX, &cd);
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) {
canvas_read(OSD1_CANVAS_INDEX, &cs);
canvas_read(OSD2_CANVAS_INDEX, &cd);
cs_addr = cs.addr;
cs_width = cs.width;
cs_height = cs.height;
cd_addr = cd.addr;
cd_width = cd.width;
cd_height = cd.height;
} else {
osd_ext_get_info(OSD1, &cs_addr,
&cs_width, &cs_height);
osd_ext_get_info(OSD2, &cs_addr,
&cs_width, &cs_height);
}
#else
osd_ext_get_info(OSD1, &cs_addr,
&cs_width, &cs_height);
osd_ext_get_info(OSD2, &cs_addr,
&cs_width, &cs_height);
#endif
if (s_osd_ext_clone.pan == 1) {
y0 = cs.height / 2;
y1 = cd.height / 2;
y0 = cs_height / 2;
y1 = cd_height / 2;
}
if (s_osd_ext_clone.angle == 1) {
@@ -92,13 +115,13 @@ static void osd_clone_process(void)
ge2d_config->src1_gb_alpha = 0;
ge2d_config->dst_xy_swap = 0;
ge2d_config->src_planes[0].addr = cs.addr;
ge2d_config->src_planes[0].w = cs.width / 4;
ge2d_config->src_planes[0].h = cs.height;
ge2d_config->src_planes[0].addr = cs_addr;
ge2d_config->src_planes[0].w = cs_width / 4;
ge2d_config->src_planes[0].h = cs_height;
ge2d_config->dst_planes[0].addr = cd.addr;
ge2d_config->dst_planes[0].w = cd.width / 4;
ge2d_config->dst_planes[0].h = cd.height;
ge2d_config->dst_planes[0].addr = cd_addr;
ge2d_config->dst_planes[0].w = cd_width / 4;
ge2d_config->dst_planes[0].h = cd_height;
ge2d_config->src_para.canvas_index = OSD1_CANVAS_INDEX;
ge2d_config->src_para.mem_type = CANVAS_OSD0;
@@ -111,16 +134,16 @@ static void osd_clone_process(void)
ge2d_config->src_para.color = 0xffffffff;
ge2d_config->src_para.top = 0;
ge2d_config->src_para.left = 0;
ge2d_config->src_para.width = cs.width / 4;
ge2d_config->src_para.height = cs.height;
ge2d_config->src_para.width = cs_width / 4;
ge2d_config->src_para.height = cs_height;
ge2d_config->dst_para.canvas_index = OSD3_CANVAS_INDEX;
ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
ge2d_config->dst_para.format = GE2D_FORMAT_S32_ARGB;
ge2d_config->dst_para.top = 0;
ge2d_config->dst_para.left = 0;
ge2d_config->dst_para.width = cd.width / 4;
ge2d_config->dst_para.height = cd.height;
ge2d_config->dst_para.width = cd_width / 4;
ge2d_config->dst_para.height = cd_height;
ge2d_config->dst_para.fill_color_en = 0;
ge2d_config->dst_para.fill_mode = 0;
ge2d_config->dst_para.color = 0;
@@ -133,8 +156,8 @@ static void osd_clone_process(void)
return;
}
stretchblt(context, x0, y0, cs.width / 4, cs.height / 2,
x0, y1, cd.width / 4, cd.height / 2);
stretchblt(context, x0, y0, cs_width / 4, cs_height / 2,
x0, y1, cd_width / 4, cd_height / 2);
}
void osd_ext_clone_update_pan(int pan)

View File

@@ -43,14 +43,15 @@
#include <linux/amlogic/media/vout/vinfo.h>
#include <linux/amlogic/media/vout/vout_notify.h>
/* Local Headers */
#include <osd/osd.h>
#include <osd/osd_log.h>
#include <osd/osd_sync.h>
#include <osd/osd_io.h>
#include "osd_hw.h"
#include "osd_fb.h"
#ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND
#include <linux/amlogic/pm.h>
static struct early_suspend early_suspend;
@@ -1394,6 +1395,12 @@ osd_ext_probe(struct platform_device *pdev)
} else
osd_log_info("viu2 vysnc irq: %d\n", int_viu2_vsync);
ret = osd_io_remap();
if (!ret) {
osd_log_err("osd_io_remap failed\n");
goto failed1;
}
/* get buffer size from dt */
ret = of_property_read_u32_array(pdev->dev.of_node,
"mem_size", memsize, 2);

View File

@@ -546,6 +546,61 @@ s32 osd_ext_wait_vsync_event(void)
return 0;
}
/* the return stride unit is 128bit(16bytes) */
static u32 line_stride_calc(
u32 fmt_mode,
u32 hsize,
u32 stride_align_32bytes)
{
u32 line_stride = 0;
/* 2-bit LUT */
if (fmt_mode == 0)
line_stride = ((hsize<<1)+127)>>7;
/* 4-bit LUT */
else if (fmt_mode == 1)
line_stride = ((hsize<<2)+127)>>7;
/* 8-bit LUT */
else if (fmt_mode == 2)
line_stride = ((hsize<<3)+127)>>7;
/* 4:2:2, 32-bit per 2 pixels */
else if (fmt_mode == 3)
line_stride = ((((hsize+1)>>1)<<5)+127)>>7;
/* 16-bit LUT */
else if (fmt_mode == 4)
line_stride = ((hsize<<4)+127)>>7;
/* 32-bit LUT */
else if (fmt_mode == 5)
line_stride = ((hsize<<5)+127)>>7;
/* 24-bit LUT */
else if (fmt_mode == 7)
line_stride = ((hsize<<4)+(hsize<<3)+127)>>7;
/* need wr ddr is 32bytes aligned */
if (stride_align_32bytes)
line_stride = ((line_stride+1)>>1)<<1;
else
line_stride = line_stride;
return line_stride;
}
static void osd_ext_update_phy_addr(u32 index)
{
u32 line_stride, fmt_mode;
fmt_mode =
osd_ext_hw.color_info[index]->hw_colormat << 2;
line_stride = line_stride_calc(fmt_mode,
osd_ext_hw.fb_gem[index].width, 1);
VSYNCOSD_WR_MPEG_REG(
VIU_OSD1_BLK1_CFG_W4,
osd_ext_hw.fb_gem[index].addr);
VSYNCOSD_WR_MPEG_REG_BITS(
VIU_OSD1_BLK2_CFG_W4,
line_stride,
0, 12);
}
void osd_ext_set_gbl_alpha_hw(u32 index, u32 gbl_alpha)
{
if (osd_ext_hw.gbl_alpha[index] != gbl_alpha) {
@@ -678,6 +733,7 @@ void osd_ext_setup(struct osd_ctl_s *osd_ext_ctl,
const struct color_bit_define_s *color,
int index)
{
int cpu_type;
u32 w = (color->bpp * xres_virtual + 7) >> 3;
struct pandata_s disp_data;
struct pandata_s pan_data;
@@ -707,7 +763,17 @@ void osd_ext_setup(struct osd_ctl_s *osd_ext_ctl,
osd_ext_hw.fb_gem[index].width = w;
osd_ext_hw.fb_gem[index].height = yres_virtual;
if (color != osd_ext_hw.color_info[index]) {
osd_ext_hw.color_info[index] = color;
add_to_update_list(index, OSD_COLOR_MODE);
}
cpu_type = get_cpu_type();
if (cpu_type == MESON_CPU_MAJOR_ID_AXG)
osd_ext_update_phy_addr(0);
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
else {
if (fbmem == 0) {
canvas_config(osd_ext_hw.fb_gem[index].canvas_idx,
osd_hw->fb_gem[index].addr,
@@ -721,12 +787,8 @@ void osd_ext_setup(struct osd_ctl_s *osd_ext_ctl,
osd_ext_hw.fb_gem[index].height,
CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
}
#endif
}
if (color != osd_ext_hw.color_info[index]) {
osd_ext_hw.color_info[index] = color;
add_to_update_list(index, OSD_COLOR_MODE);
#endif
}
/* osd blank only control by /sys/class/graphcis/fbx/blank */
@@ -1232,6 +1294,13 @@ void osd_ext_pan_display_hw(u32 index, unsigned int xoffset,
}
}
void osd_ext_get_info(u32 index, u32 *addr, u32 *width, u32 *height)
{
*addr = osd_ext_hw.fb_gem[index].addr;
*width = osd_ext_hw.fb_gem[index].width;
*height = osd_ext_hw.fb_gem[index].height;
}
static void osd1_update_disp_scale_enable(void)
{
if (osd_ext_hw.scale[OSD1].h_enable)
@@ -2496,7 +2565,9 @@ void osd_ext_set_clone_hw(u32 index, u32 clone)
memcpy(&pandata, &osd_ext_hw.pandata[index],
sizeof(struct pandata_s));
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
canvas_update_addr(osd_ext_hw.fb_gem[index].canvas_idx,
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
canvas_update_addr(
osd_ext_hw.fb_gem[index].canvas_idx,
osd_hw->fb_gem[index].addr);
#endif
}
@@ -2506,7 +2577,9 @@ void osd_ext_set_clone_hw(u32 index, u32 clone)
else {
color_info[index] = osd_ext_hw.color_info[index];
#ifdef CONFIG_AMLOGIC_MEDIA_CANVAS
canvas_update_addr(osd_ext_hw.fb_gem[index].canvas_idx,
if (cpu_type != MESON_CPU_MAJOR_ID_AXG)
canvas_update_addr(
osd_ext_hw.fb_gem[index].canvas_idx,
osd_ext_hw.fb_gem[index].addr);
#endif
osd_ext_hw.color_info[index] = color_info[index];

View File

@@ -95,4 +95,6 @@ extern void osd_ext_get_angle_hw(u32 index, u32 *angle);
extern void osd_ext_set_angle_hw(u32 index, u32 angle);
extern void osd_ext_get_clone_hw(u32 index, u32 *clone);
extern void osd_ext_set_clone_hw(u32 index, u32 clone);
extern void osd_ext_get_info(u32 index, u32 *addr, u32 *width, u32 *height);
#endif

View File

@@ -266,5 +266,4 @@ int query_video_status(int type, int *value);
int get_video0_frame_info(struct vframe_s *vf);
int amvideo_notifier_call_chain(unsigned long val, void *v);
struct device *get_video_device(void);
#endif /* VIDEO_H */