From 44a77d4de8d50ef1d3b1bd66be13ac48a5824ac2 Mon Sep 17 00:00:00 2001 From: Pengcheng Chen Date: Fri, 5 May 2017 13:48:36 +0800 Subject: [PATCH] osd: add osd driver for axg PD#146066: osd: add osd driver for axg bringup Change-Id: Iea6889046d2a0bd0d7c79f106e4d89ed9828d035 Signed-off-by: Pengcheng Chen --- MAINTAINERS | 4 + arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts | 1 - arch/arm64/boot/dts/amlogic/axg_pxp.dts | 28 +++- arch/arm64/boot/dts/amlogic/axg_s400.dts | 28 +++- arch/arm64/boot/dts/amlogic/axg_s420.dts | 1 - drivers/amlogic/media/osd/Kconfig | 2 +- drivers/amlogic/media/osd/Makefile | 2 +- drivers/amlogic/media/osd/osd_antiflicker.c | 56 +++++-- drivers/amlogic/media/osd/osd_clone.c | 56 +++++-- drivers/amlogic/media/osd/osd_debug.c | 84 +++++++--- drivers/amlogic/media/osd/osd_fb.c | 35 +++- drivers/amlogic/media/osd/osd_hw.c | 224 ++++++++++++++++++++----- drivers/amlogic/media/osd/osd_hw.h | 1 + drivers/amlogic/media/osd/osd_io.c | 158 +++++++++++++++++ drivers/amlogic/media/osd/osd_io.h | 77 ++------- drivers/amlogic/media/osd/osd_logo.c | 6 + drivers/amlogic/media/osd/osd_progressbar.c | 29 +++- drivers/amlogic/media/osd_ext/osd_clone.c | 61 ++++--- drivers/amlogic/media/osd_ext/osd_fb.c | 9 +- drivers/amlogic/media/osd_ext/osd_hw.c | 87 +++++++++- drivers/amlogic/media/osd_ext/osd_hw.h | 2 + include/linux/amlogic/media/video_sink/video.h | 1 - 22 files changed, 745 insertions(+), 207 deletions(-) create mode 100644 drivers/amlogic/media/osd/osd_io.c diff --git a/MAINTAINERS b/MAINTAINERS index 73db7ecf..c8e71c6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13944,3 +13944,7 @@ AMLOGIC unifykey driver M: Jiamin Ma F: drivers/amlogic/unifykey/* F: include/linux/amlogic/unifykey/* + +AMLOGIC AXG ADD OSD DRIVER +M: Pengcheng Chen +F: drivers/amlogic/media/osd/osd_io.c diff --git a/arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts b/arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts index 56f4c61..dcb4746 100644 --- a/arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts +++ b/arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts @@ -623,7 +623,6 @@ mask = <4>; }; }; - }; /* end of / */ /* Audio Related start */ diff --git a/arch/arm64/boot/dts/amlogic/axg_pxp.dts b/arch/arm64/boot/dts/amlogic/axg_pxp.dts index 53f298f..4d98ef2 100644 --- a/arch/arm64/boot/dts/amlogic/axg_pxp.dts +++ b/arch/arm64/boot/dts/amlogic/axg_pxp.dts @@ -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{ diff --git a/arch/arm64/boot/dts/amlogic/axg_s400.dts b/arch/arm64/boot/dts/amlogic/axg_s400.dts index dac45af..083b862 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400.dts @@ -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 */ diff --git a/arch/arm64/boot/dts/amlogic/axg_s420.dts b/arch/arm64/boot/dts/amlogic/axg_s420.dts index 1af37a8..1c957d9 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420.dts @@ -55,7 +55,6 @@ reg = <0x0 0x05300000 0x0 0x2000000>; no-map; }; - }; mtd_nand { compatible = "amlogic, aml_mtd_nand"; diff --git a/drivers/amlogic/media/osd/Kconfig b/drivers/amlogic/media/osd/Kconfig index cd7cf5e..de88de9 100644 --- a/drivers/amlogic/media/osd/Kconfig +++ b/drivers/amlogic/media/osd/Kconfig @@ -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 diff --git a/drivers/amlogic/media/osd/Makefile b/drivers/amlogic/media/osd/Makefile index ca05027..1153b16 100644 --- a/drivers/amlogic/media/osd/Makefile +++ b/drivers/amlogic/media/osd/Makefile @@ -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 diff --git a/drivers/amlogic/media/osd/osd_antiflicker.c b/drivers/amlogic/media/osd/osd_antiflicker.c index 799d182..37d0a02 100644 --- a/drivers/amlogic/media/osd/osd_antiflicker.c +++ b/drivers/amlogic/media/osd/osd_antiflicker.c @@ -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; } diff --git a/drivers/amlogic/media/osd/osd_clone.c b/drivers/amlogic/media/osd/osd_clone.c index 1869f9c..b9cbfc3 100644 --- a/drivers/amlogic/media/osd/osd_clone.c +++ b/drivers/amlogic/media/osd/osd_clone.c @@ -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) diff --git a/drivers/amlogic/media/osd/osd_debug.c b/drivers/amlogic/media/osd/osd_debug.c index 6c08432..f2d9b08 100644 --- a/drivers/amlogic/media/osd/osd_debug.c +++ b/drivers/amlogic/media/osd/osd_debug.c @@ -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, ®_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(); diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index d7a5f64..0ab9e28 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -46,6 +46,7 @@ #include #include /* Amlogic Headers */ +#include #include #include #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, diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index 9f493fb..6c4e102 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -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 *)¶[0]); +#ifdef CONFIG_AMLOGIC_VIDEO + if (get_cpu_type() != MESON_CPU_MAJOR_ID_AXG) + amvideo_notifier_call_chain( + AMVIDEO_UPDATE_OSD_MODE, + (void *)¶[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 diff --git a/drivers/amlogic/media/osd/osd_hw.h b/drivers/amlogic/media/osd/osd_hw.h index 3b25980..c421ae3 100644 --- a/drivers/amlogic/media/osd/osd_hw.h +++ b/drivers/amlogic/media/osd/osd_hw.h @@ -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); diff --git a/drivers/amlogic/media/osd/osd_io.c b/drivers/amlogic/media/osd/osd_io.c new file mode 100644 index 0000000..b27f977 --- /dev/null +++ b/drivers/amlogic/media/osd/osd_io.c @@ -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 +#include +#include +#include + +#include +/* 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)))); +} + diff --git a/drivers/amlogic/media/osd/osd_io.h b/drivers/amlogic/media/osd/osd_io.h index 6b51a58..28e0017 100644 --- a/drivers/amlogic/media/osd/osd_io.h +++ b/drivers/amlogic/media/osd/osd_io.h @@ -17,74 +17,25 @@ #ifndef _OSD_IO_H_ #define _OSD_IO_H_ - #include - +/* 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); diff --git a/drivers/amlogic/media/osd/osd_logo.c b/drivers/amlogic/media/osd/osd_logo.c index 0e1a3a0..e261c0d 100644 --- a/drivers/amlogic/media/osd/osd_logo.c +++ b/drivers/amlogic/media/osd/osd_logo.c @@ -23,6 +23,7 @@ #include /* Amlogic Headers */ +#include #include #include @@ -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); diff --git a/drivers/amlogic/media/osd/osd_progressbar.c b/drivers/amlogic/media/osd/osd_progressbar.c index 6db96f2..280fefc 100644 --- a/drivers/amlogic/media/osd/osd_progressbar.c +++ b/drivers/amlogic/media/osd/osd_progressbar.c @@ -26,6 +26,7 @@ #include #include #include +#include #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"); diff --git a/drivers/amlogic/media/osd_ext/osd_clone.c b/drivers/amlogic/media/osd_ext/osd_clone.c index 9982875..2e694ee 100644 --- a/drivers/amlogic/media/osd_ext/osd_clone.c +++ b/drivers/amlogic/media/osd_ext/osd_clone.c @@ -41,7 +41,7 @@ #include #include #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) diff --git a/drivers/amlogic/media/osd_ext/osd_fb.c b/drivers/amlogic/media/osd_ext/osd_fb.c index 8194d77..da16b2c 100644 --- a/drivers/amlogic/media/osd_ext/osd_fb.c +++ b/drivers/amlogic/media/osd_ext/osd_fb.c @@ -43,14 +43,15 @@ #include #include + /* Local Headers */ #include #include #include +#include #include "osd_hw.h" #include "osd_fb.h" - #ifdef CONFIG_AMLOGIC_LEGACY_EARLY_SUSPEND #include 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); diff --git a/drivers/amlogic/media/osd_ext/osd_hw.c b/drivers/amlogic/media/osd_ext/osd_hw.c index 4d51cbd..faa873a 100644 --- a/drivers/amlogic/media/osd_ext/osd_hw.c +++ b/drivers/amlogic/media/osd_ext/osd_hw.c @@ -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]; diff --git a/drivers/amlogic/media/osd_ext/osd_hw.h b/drivers/amlogic/media/osd_ext/osd_hw.h index c287f94..9931422 100644 --- a/drivers/amlogic/media/osd_ext/osd_hw.h +++ b/drivers/amlogic/media/osd_ext/osd_hw.h @@ -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 diff --git a/include/linux/amlogic/media/video_sink/video.h b/include/linux/amlogic/media/video_sink/video.h index f9b692c..c2f5d4b 100644 --- a/include/linux/amlogic/media/video_sink/video.h +++ b/include/linux/amlogic/media/video_sink/video.h @@ -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 */ -- 2.7.4