From c3edb7d03bbe597a81a568805d031ac05fa9a04e Mon Sep 17 00:00:00 2001 From: kele bai Date: Thu, 4 Jan 2018 19:20:30 +0800 Subject: [PATCH] di: G12A add di support PD#156734: G12A add di support 1) add new mtn&cont&mcinfo&mv&if0 mif 2) add nr downscale 3) post viu link case 4) add pps Change-Id: Id9ce920323d4324f0e1429df787f8af2dad07318 Signed-off-by: kele bai --- MAINTAINERS | 4 +- arch/arm64/boot/dts/amlogic/g12a_pxp.dts | 55 + .../boot/dts/amlogic/txlx_t962e_r321.dts | 1 + .../boot/dts/amlogic/txlx_t962x_r311_2g.dts | 1 + drivers/amlogic/media/deinterlace/Makefile | 3 +- .../amlogic/media/deinterlace/deinterlace.c | 527 ++++--- .../amlogic/media/deinterlace/deinterlace.h | 18 +- .../media/deinterlace/deinterlace_dbg.c | 281 +++- .../media/deinterlace/deinterlace_dbg.h | 2 + .../media/deinterlace/deinterlace_hw.c | 990 ++++++++++--- .../media/deinterlace/deinterlace_hw.h | 27 +- drivers/amlogic/media/deinterlace/di_pps.c | 1319 +++++++++++++++++ drivers/amlogic/media/deinterlace/di_pps.h | 101 ++ .../amlogic/media/deinterlace/nr_downscale.c | 187 +++ .../amlogic/media/deinterlace/nr_downscale.h | 45 + drivers/amlogic/media/deinterlace/nr_drv.c | 8 +- drivers/amlogic/media/deinterlace/register.h | 208 ++- drivers/amlogic/media/video_sink/video.c | 8 +- .../amlogic/media/registers/regs/di_regs.h | 165 +-- 19 files changed, 3301 insertions(+), 649 deletions(-) create mode 100644 drivers/amlogic/media/deinterlace/di_pps.c create mode 100644 drivers/amlogic/media/deinterlace/di_pps.h create mode 100644 drivers/amlogic/media/deinterlace/nr_downscale.c create mode 100644 drivers/amlogic/media/deinterlace/nr_downscale.h diff --git a/MAINTAINERS b/MAINTAINERS index 0e78cc6d2b02..a3711fb0b2d2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13666,12 +13666,14 @@ AMLOGIC VRTC DRIVER M: Yun Cai F: drivers/amlogic/vrtc/ -AMLOGIC DEINTERLACE, NR, CUE, Field Detection, VOF DRIVERS +AMLOGIC DEINTERLACE, NR, CUE, Field Detection, NR DS, PPS, VOF DRIVERS M: Kele Bai F: drivers/amlogic/deinterlace/* F: drivers/amlogic/media/deinterlace/film_mode_fmw/* F: include/linux/amlogic/media/amvecm/amvecm.h F: arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts +F: arch/arm64/boot/dts/amlogic/txlx_t962x_r311.dts +F: arch/arm64/boot/dts/amlogic/g12a_pxp.dts AMLOGIC TVIN M: Dezhi Kong diff --git a/arch/arm64/boot/dts/amlogic/g12a_pxp.dts b/arch/arm64/boot/dts/amlogic/g12a_pxp.dts index e2a41d47bd24..2b067b5b572e 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_pxp.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_pxp.dts @@ -67,6 +67,32 @@ size = <0x0 0x8000000>; alignment = <0x0 0x400000>; }; + + //di_reserved:linux,di { + //compatible = "amlogic, di-mem"; + /* buffer_size = 3621952(yuv422 8bit) */ + /* 4179008(yuv422 10bit full pack mode) */ + /** 10x3621952=34.6M(0x23) support 8bit **/ + /** 10x4736064=45.2M(0x2e) support 12bit **/ + /** 10x4179008=40M(0x28) support 10bit **/ + //size = <0x0 0x2800000>; + //no-map; + //}; + /*di CMA pool */ + di_cma_reserved:linux,di_cma { + compatible = "shared-dma-pool"; + reusable; + /* buffer_size = 3621952(yuv422 8bit) + * | 4736064(yuv422 10bit) + * | 4074560(yuv422 10bit full pack mode) + * 10x3621952=34.6M(0x23) support 8bit + * 10x4736064=45.2M(0x2e) support 12bit + * 10x4074560=40M(0x28) support 10bit + */ + size = <0x0 0x02900000>; + alignment = <0x0 0x400000>; + }; + }; vout { @@ -208,6 +234,35 @@ reg = <0x0 0xff940000 0x0 0x10000>; }; + deinterlace { + compatible = "amlogic, deinterlace"; + status = "okay"; + /* 0:use reserved; 1:use cma; 2:use cma as reserved */ + flag_cma = <1>; + //memory-region = <&di_reserved>; + memory-region = <&di_cma_reserved>; + interrupts = <0 46 1 + 0 40 1>; + interrupt-names = "pre_irq", "post_irq"; + clocks = <&clkc CLKID_VPU_MUX>, + <&clkc CLKID_FCLK_DIV4>, + <&clkc CLKID_VPU_CLKB_TMP_COMP>, + <&clkc CLKID_VPU_CLKB_COMP>; + clock-names = "vpu_mux", + "fclk_div4", + "vpu_clkb_tmp_composite", + "vpu_clkb_composite"; + clock-range = <333 666>; + /* buffer-size = <3621952>;(yuv422 8bit) */ + buffer-size = <4074560>;/*yuv422 fullpack*/ + /* reserve-iomap = "true"; */ + /* if enable nr10bit, set nr10bit-support to 1 */ + post-wr-support = <1>; + nr10bit-support = <1>; + nrds-enable = <1>; + pps-enable = <1>; + }; + amlvecm { compatible = "amlogic, vecm"; dev_name = "aml_vecm"; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts index 249aa0bdb7ac..acff2eee43f1 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts @@ -386,6 +386,7 @@ "fclk_div4", "vpu_clkb_tmp_composite", "vpu_clkb_composite"; + clock-range = <250 500>; /* buffer-size = <3621952>;(yuv422 8bit) */ buffer-size = <4179008>;/*yuv422 fullpack*/ /* reserve-iomap = "true"; */ diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts index de2928f973da..664d4785fe03 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -387,6 +387,7 @@ "fclk_div4", "vpu_clkb_tmp_composite", "vpu_clkb_composite"; + clock-range = <250 500>; /* buffer-size = <3621952>;(yuv422 8bit) */ buffer-size = <4179008>;/*yuv422 fullpack*/ /* reserve-iomap = "true"; */ diff --git a/drivers/amlogic/media/deinterlace/Makefile b/drivers/amlogic/media/deinterlace/Makefile index 4ece1445c10c..ea280fbd7b63 100644 --- a/drivers/amlogic/media/deinterlace/Makefile +++ b/drivers/amlogic/media/deinterlace/Makefile @@ -12,6 +12,7 @@ di-objs += deinterlace_dbg.o di-objs += nr_drv.o di-objs += pulldown_drv.o di-objs += detect3d.o -di-objs += detect3d.o +di-objs += nr_downscale.o +di-objs += di_pps.o ccflags-y += -Idrivers/amlogic/media/common/rdma/ diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index 6190cbf5fc86..441716dc01ad 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -63,6 +63,8 @@ #include "register.h" #include "deinterlace.h" #include "deinterlace_dbg.h" +#include "nr_downscale.h" +#include "di_pps.h" #define CREATE_TRACE_POINTS #include "deinterlace_trace.h" #ifdef DET3D @@ -112,7 +114,7 @@ static di_dev_t *de_devp; static dev_t di_devno; static struct class *di_clsp; -static const char version_s[] = "2016-09-29a"; +static const char version_s[] = "2018-01-04a"; static int bypass_state = 1; static int bypass_all; @@ -247,8 +249,6 @@ static long same_field_bot_count; */ static int post_hold_line = 17;/* for m8 1080i/50 output */ -static int pre_hold_line = 10; -static int pre_urgent = 1; static int post_urgent = 1; /*pre process speed debug */ @@ -316,6 +316,23 @@ void trigger_pre_di_process(unsigned char idx) static unsigned int di_printk_flag; #define DI_PRE_INTERVAL (HZ / 100) +/* + * progressive frame process type config: + * 0, process by field; + * 1, process by frame (only valid for vdin source whose + * width/height does not change) + */ +static vframe_t *vframe_in[MAX_IN_BUF_NUM]; +static vframe_t vframe_in_dup[MAX_IN_BUF_NUM]; +static vframe_t vframe_local[MAX_LOCAL_BUF_NUM * 2]; +static vframe_t vframe_post[MAX_POST_BUF_NUM]; +static struct di_buf_s *cur_post_ready_di_buf; + +static struct di_buf_s di_buf_local[MAX_LOCAL_BUF_NUM * 2]; +static struct di_buf_s di_buf_in[MAX_IN_BUF_NUM]; +static struct di_buf_s di_buf_post[MAX_POST_BUF_NUM]; + + /************For Write register**********************/ static unsigned int di_stop_reg_flag; static unsigned int num_di_stop_reg_addr = 4; @@ -473,11 +490,19 @@ store_dbg(struct device *dev, } else if (strncmp(buf, "pstep", 5) == 0) { pre_run_flag = DI_RUN_FLAG_STEP; } else if (strncmp(buf, "dumpreg", 7) == 0) { - dump_di_reg(); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dump_di_reg_g12(); + else + dump_di_reg(); } else if (strncmp(buf, "robust_test", 11) == 0) { recovery_flag = 1; } else if (strncmp(buf, "recycle_buf", 11) == 0) { recycle_keep_buffer(); + } else if (strncmp(buf, "recycle_post", 12) == 0) { + if (di_vf_peek(NULL)) + di_vf_put(di_vf_get(NULL), NULL); + } else if (strncmp(buf, "mem_map", 7) == 0) { + dump_buf_addr(di_buf_local, MAX_LOCAL_BUF_NUM * 2); } else { pr_info("DI no support cmd %s!!!\n", buf); } @@ -711,22 +736,6 @@ static char *vframe_type_name[] = { static unsigned int default_width = 1920; static unsigned int default_height = 1080; -/* - * progressive frame process type config: - * 0, process by field; - * 1, process by frame (only valid for vdin source whose - * width/height does not change) - */ -static vframe_t *vframe_in[MAX_IN_BUF_NUM]; -static vframe_t vframe_in_dup[MAX_IN_BUF_NUM]; -static vframe_t vframe_local[MAX_LOCAL_BUF_NUM * 2]; -static vframe_t vframe_post[MAX_POST_BUF_NUM]; -static struct di_buf_s *cur_post_ready_di_buf; - -static struct di_buf_s di_buf_local[MAX_LOCAL_BUF_NUM * 2]; -static struct di_buf_s di_buf_in[MAX_IN_BUF_NUM]; -static struct di_buf_s di_buf_post[MAX_POST_BUF_NUM]; - /* * all buffers are in * 1) list of local_free_list,in_free_list,pre_ready_list,recycle_list @@ -1165,8 +1174,8 @@ store_dump_mem(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { unsigned int n = 0, canvas_w = 0, canvas_h = 0; - unsigned long nr_size = 0; - struct di_buf_s *di_buf; + unsigned long nr_size = 0, dump_adr = 0; + struct di_buf_s *di_buf = NULL; char *buf_orig, *ps, *token; char *parm[3] = { NULL }; char delim1[2] = " "; @@ -1193,17 +1202,20 @@ store_dump_mem(struct device *dev, struct device_attribute *attr, di_buf = di_pre_stru.di_mem_buf_dup_p; else if (strcmp(parm[0], "capture_post") == 0) di_buf = di_post_stru.cur_post_buf; + else if (strcmp(parm[0], "capture_nrds") == 0) + get_nr_ds_buf(&dump_adr, &nr_size); else { pr_err("wrong dump cmd\n"); return len; } - if (parm[1] != NULL) { + if (nr_size == 0) { if (unlikely(di_buf == NULL)) return len; + canvas_w = di_buf->canvas_width[NR_CANVAS]; + canvas_h = di_buf->canvas_height; + nr_size = canvas_w * canvas_h * 2; + dump_adr = di_buf->nr_adr; } - canvas_w = di_buf->canvas_width[NR_CANVAS]; - canvas_h = di_buf->canvas_height; - nr_size = canvas_w * canvas_h * 2; old_fs = get_fs(); set_fs(KERNEL_DS); /* pr_dbg("dump path =%s\n",dump_path); */ @@ -1213,10 +1225,10 @@ store_dump_mem(struct device *dev, struct device_attribute *attr, return len; } dump_state_flag = 1; - if (de_devp->flags && DI_MAP_FLAG) - buff = (void *)phys_to_virt(di_buf->nr_adr); + if (de_devp->flags & DI_MAP_FLAG) + buff = (void *)phys_to_virt(dump_adr); else - buff = ioremap(di_buf->nr_adr, nr_size); + buff = ioremap(dump_adr, nr_size); if (buff == NULL) pr_err("%s: ioremap error.\n", __func__); vfs_write(filp, buff, nr_size, &pos); @@ -1239,12 +1251,12 @@ store_dump_mem(struct device *dev, struct device_attribute *attr, * pr_dbg("di_mem_start=%u\n",di_mem_start); */ vfs_fsync(filp, 0); + pr_info("write buffer 0x%lx to %s.\n", dump_adr, parm[1]); if (!(de_devp->flags & DI_MAP_FLAG)) iounmap(buff); dump_state_flag = 0; filp_close(filp, NULL); set_fs(old_fs); - pr_info("write buffer %d to %s.\n", di_buf->seq, parm[1]); return len; } @@ -1499,7 +1511,7 @@ static unsigned int di_inp_idx[3]; #endif static int di_get_canvas(void) { - int pre_num = 7, post_num = 6, i = 0; + unsigned int pre_num = 7, post_num = 6, i = 0; if (mcpre_en) { /* mem/chan2/nr/mtn/contrd/contrd2/ @@ -1549,15 +1561,18 @@ static int di_get_canvas(void) pr_info("DI: support multi decoding %u~%u~%u.\n", di_inp_idx[0], di_inp_idx[1], di_inp_idx[2]); #endif - if (canvas_pool_alloc_canvas_table("di_wr", - &di_wr_idx, 1, CANVAS_MAP_TYPE_1)) { - pr_err("%s allocat di write back canvas error.\n", - __func__); + if (de_devp->post_wr_support == 0) + return 0; + if (canvas_pool_alloc_canvas_table("di_wr", + &di_wr_idx, 1, CANVAS_MAP_TYPE_1)) { + pr_err("%s allocat di write back canvas error.\n", + __func__); return 1; - } - pr_info("DI: support post write back %u.\n", di_wr_idx); + } + pr_info("DI: support post write back %u.\n", di_wr_idx); return 0; } + static void config_canvas_idx(struct di_buf_s *di_buf, int nr_canvas_idx, int mtn_canvas_idx) { @@ -1681,6 +1696,11 @@ static unsigned int di_cma_alloc_total(struct di_dev_s *de_devp) return 1; } pr_err("%s:xxxxxx DI CMA allocate fail.\n", __func__); + if (de_devp->flag_cma != 0 && de_devp->nrds_enable) { + nr_ds_buf_init(de_devp->flag_cma, 0, + &(de_devp->pdev->dev)); + } + return 0; @@ -1766,6 +1786,11 @@ static unsigned int di_cma_alloc(struct di_dev_s *devp) pr_info(" addr 0x%lx ok.\n", buf_p->nr_adr); } } + if (de_devp->flag_cma != 0 && de_devp->nrds_enable) { + nr_ds_buf_init(de_devp->flag_cma, 0, + &(de_devp->pdev->dev)); + } + end_time = jiffies_to_msecs(jiffies); delta_time = end_time - start_time; pr_info("%s:alloc %u buffer use %u ms(%u~%u)\n", @@ -1831,6 +1856,11 @@ static void di_cma_release(struct di_dev_s *devp) } } } + if (de_devp->nrds_enable) { + nr_ds_buf_uninit(de_devp->flag_cma, + &(de_devp->pdev->dev)); + } + end_time = jiffies_to_msecs(jiffies); delta_time = end_time - start_time; pr_info("%s:release %u buffer use %u ms(%u~%u)\n", @@ -1846,10 +1876,13 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) unsigned int nr_size = 0, count_size = 0, mv_size = 0, mc_size = 0; unsigned int nr_width = width, mtn_width = width, mv_width = width; unsigned int nr_canvas_width = width, mtn_canvas_width = width; - unsigned int mv_canvas_width = width; - unsigned long di_post_mem = 0; + unsigned int mv_canvas_width = width, canvas_align_width = 32; + unsigned long di_post_mem = 0, nrds_mem = 0; struct di_buf_s *keep_buf = di_post_stru.keep_buf; + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + canvas_align_width = 64; + frame_count = 0; disp_frame_count = 0; cur_post_ready_di_buf = NULL; @@ -1869,9 +1902,9 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) nr_canvas_width = nr_width << 1; mtn_canvas_width = mtn_width >> 1; mv_canvas_width = (mv_width << 1) / 5; - nr_canvas_width = roundup(nr_canvas_width, 32); - mtn_canvas_width = roundup(mtn_canvas_width, 32); - mv_canvas_width = roundup(mv_canvas_width, 32); + nr_canvas_width = roundup(nr_canvas_width, canvas_align_width); + mtn_canvas_width = roundup(mtn_canvas_width, canvas_align_width); + mv_canvas_width = roundup(mv_canvas_width, canvas_align_width); nr_width = nr_canvas_width >> 1; mtn_width = mtn_canvas_width << 1; mv_width = (mv_canvas_width * 5) >> 1; @@ -1978,7 +2011,7 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) di_buf->canvas_config_flag = 2; } di_buf->index = i; - di_buf->vframe = &(vframe_local[i]); + di_buf->vframe = &(vframe_local[i]); di_buf->vframe->private_data = di_buf; di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; @@ -1996,9 +2029,9 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) up(&di_sema); } #endif + di_post_mem = de_devp->mem_start + + di_buf_size*de_devp->buf_num_avail; if (post_wr_en && post_wr_support) { - di_post_mem = de_devp->mem_start + - di_buf_size*de_devp->buf_num_avail; di_post_buf_size = nr_width * canvas_height * 2; /* pre buffer must 2 more than post buffer */ if ((de_devp->buf_num_avail - 2) > MAX_POST_BUF_NUM) @@ -2052,6 +2085,12 @@ static int di_init_buf(int width, int height, unsigned char prog_flag) } } } + if (de_devp->flag_cma == 0 && de_devp->nrds_enable) { + nrds_mem = di_post_mem + + di_post_stru.di_post_num * di_post_buf_size; + nr_ds_buf_init(de_devp->flag_cma, nrds_mem, + &(de_devp->pdev->dev)); + } return 0; } @@ -2125,6 +2164,10 @@ static void di_uninit_buf(unsigned int disable_mirror) di_post_stru.de_post_process_done = 0; di_post_stru.post_wr_cnt = 0; } + if (de_devp->flag_cma == 0 && de_devp->nrds_enable) { + nr_ds_buf_uninit(de_devp->flag_cma, + &(de_devp->pdev->dev)); + } } static void log_buffer_state(unsigned char *tag) @@ -2389,12 +2432,12 @@ static void config_di_cnt_mif(struct DI_SIM_MIF_s *di_cnt_mif, static void config_di_wr_mif(struct DI_SIM_MIF_s *di_nrwr_mif, struct DI_SIM_MIF_s *di_mtnwr_mif, - struct di_buf_s *di_buf, - vframe_t *in_vframe) + struct di_buf_s *di_buf) { + vframe_t *vf = di_buf->vframe; di_nrwr_mif->canvas_num = di_buf->nr_canvas_idx; di_nrwr_mif->start_x = 0; - di_nrwr_mif->end_x = in_vframe->width - 1; + di_nrwr_mif->end_x = vf->width - 1; di_nrwr_mif->start_y = 0; if (di_buf->vframe->bitdepth & BITDEPTH_Y10) di_nrwr_mif->bit_mode = @@ -2402,14 +2445,14 @@ config_di_wr_mif(struct DI_SIM_MIF_s *di_nrwr_mif, else di_nrwr_mif->bit_mode = 0; if (di_pre_stru.prog_proc_type == 0) - di_nrwr_mif->end_y = in_vframe->height / 2 - 1; + di_nrwr_mif->end_y = vf->height / 2 - 1; else - di_nrwr_mif->end_y = in_vframe->height - 1; + di_nrwr_mif->end_y = vf->height - 1; if (di_pre_stru.prog_proc_type == 0) { di_mtnwr_mif->start_x = 0; - di_mtnwr_mif->end_x = in_vframe->width - 1; + di_mtnwr_mif->end_x = vf->width - 1; di_mtnwr_mif->start_y = 0; - di_mtnwr_mif->end_y = in_vframe->height / 2 - 1; + di_mtnwr_mif->end_y = vf->height / 2 - 1; di_mtnwr_mif->canvas_num = di_buf->mtn_canvas_idx; } } @@ -2543,14 +2586,12 @@ static void pre_inp_canvas_config(struct vframe_s *vf); static void pre_de_process(void) { unsigned short pre_width = 0, pre_height = 0; - int chan2_field_num = 1; + unsigned char chan2_field_num = 1; int canvases_idex = di_pre_stru.field_count_for_cont % 2; unsigned short cur_inp_field_type = VIDTYPE_TYPEMASK; - bool me_auto_en = true; - int cont_rd = 1; + unsigned short int_mask = 0x7f; + di_print("%s: start\n", __func__); - if (is_meson_gxlx_cpu() || is_meson_txhd_cpu()) - me_auto_en = false; di_pre_stru.pre_de_busy = 1; di_pre_stru.pre_de_busy_timer_count = 0; #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC @@ -2611,7 +2652,7 @@ static void pre_de_process(void) config_di_mif(&di_pre_stru.di_chan2_mif, di_pre_stru.di_chan2_buf_dup_p); config_di_wr_mif(&di_pre_stru.di_nrwr_mif, &di_pre_stru.di_mtnwr_mif, - di_pre_stru.di_wr_buf, di_pre_stru.di_inp_buf->vframe); + di_pre_stru.di_wr_buf); if (di_pre_stru.di_chan2_buf_dup_p) config_di_cnt_mif(&di_pre_stru.di_contprd_mif, @@ -2648,88 +2689,64 @@ static void pre_de_process(void) cur_inp_field_type); di_pre_stru.input_size_change_flag = false; } + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (de_devp->nrds_enable) { + nr_ds_mif_config(); + nr_ds_hw_ctrl(true); + int_mask = 0x3f; + } else { + RDMA_WR_BITS(DI_PRE_CTRL, 0, 11, 1); + nr_ds_hw_ctrl(false); + } + } /* set interrupt mask for pre module. * we need to only leave one mask open * to prevent multiple entry for de_irq */ + + RDMA_WR(DI_INTR_CTRL, + /* mask nrwr interrupt. */ + (2 << 16) | + /* mask diwr intrpt. */ + (((post_wr_en && post_wr_support)?0:1) << 18) | + (int_mask << 19) | /* mask hist check interrupt. */ + #ifdef DET3D + ((det3d_en ? 0 : 1) << 24) | /* mask det3d interrupt. */ + #else + (1 << 24) | /* mask det3d interrupt. */ + #endif + ((de_devp->nrds_enable ? 0 : 1) << 25) | + ((post_wr_en && post_wr_support)?0xb:0xf)); + /* clean all pending interrupt bits. */ + enable_di_pre_aml(&di_pre_stru.di_inp_mif, - &di_pre_stru.di_mem_mif, - &di_pre_stru.di_chan2_mif, - &di_pre_stru.di_nrwr_mif, - &di_pre_stru.di_mtnwr_mif, - &di_pre_stru.di_contp2rd_mif, - &di_pre_stru.di_contprd_mif, - &di_pre_stru.di_contwr_mif, - 1, - di_pre_stru.enable_mtnwr, - di_pre_stru.enable_pulldown_check, - di_pre_stru.enable_pulldown_check, - 0, - chan2_field_num, - di_pre_stru.vdin2nr, - pre_hold_line, - pre_urgent - ); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) - enable_afbc_input(di_pre_stru.di_inp_buf->vframe); + &di_pre_stru.di_mem_mif, + &di_pre_stru.di_chan2_mif, + &di_pre_stru.di_nrwr_mif, + &di_pre_stru.di_mtnwr_mif, + &di_pre_stru.di_contp2rd_mif, + &di_pre_stru.di_contprd_mif, + &di_pre_stru.di_contwr_mif, + di_pre_stru.madi_enable, + chan2_field_num, + di_pre_stru.vdin2nr); + + enable_afbc_input(di_pre_stru.di_inp_buf->vframe); if (mcpre_en) { - if (!di_pre_stru.cur_prog_flag && mcpre_en) - enable_mc_di_pre(&di_pre_stru.di_mcinford_mif, + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + enable_mc_di_pre_g12( + &di_pre_stru.di_mcinford_mif, &di_pre_stru.di_mcinfowr_mif, - &di_pre_stru.di_mcvecwr_mif, pre_urgent); - } - if (di_pre_stru.cur_prog_flag == 1 || di_pre_stru.enable_mtnwr == 0) { - RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 31, 1); /* disable contwr */ - RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 29, 1); /* disable txt */ - cont_rd = 0; - - RDMA_WR_BITS(MCDI_MOTINEN, 0, 0, 2); - RDMA_WR(MCDI_CTRL_MODE, 0); - RDMA_WR_BITS(DI_MTN_CTRL1, 0, 12, 2); - RDMA_WR(DI_INTR_CTRL, - /* mask nrwr interrupt. */ - (2 << 16) | - /* mask diwr intrpt. */ - (((post_wr_en && post_wr_support)?0:1) << 18) | - (0x1f << 19) | /* mask hist check interrupt. */ - #ifdef DET3D - ((det3d_en ? 0 : 1) << 24) | /* mask det3d interrupt. */ - #else - (1 << 24) | /* mask det3d interrupt. */ - #endif - ((post_wr_en && post_wr_support)?0xb:0xf)); - /* clean all pending interrupt bits. */ - } else { - RDMA_WR_BITS(DI_MTN_1_CTRL1, 5, 29, 3); - RDMA_WR(DI_PRE_CTRL, RDMA_RD(DI_PRE_CTRL) | (1 << 1)); - cont_rd = 1; - RDMA_WR(DI_INTR_CTRL, - (((post_wr_en && post_wr_support)?0:1) << 18) | - (1 << 19) | /* mask hist check interrupt. */ - (7 << 21) | /* mask mcdi interrupt. */ - #ifdef DET3D - ((det3d_en ? 0 : 1) << 24) | - #else - (1 << 24) | /* mask det3d interrupt. */ - #endif - ((post_wr_en && post_wr_support)?0xb:0xf)); - if (mcpre_en) { - /* enable me(mc di) */ - RDMA_WR_BITS(MCDI_MOTINEN, 3, 0, 2); - RDMA_WR(MCDI_CTRL_MODE, - me_auto_en ? 0x1bfff7ff:0x1bfe37ff); - /* - * bit12=0 disable autoen for - * hw issue in mcdi - */ - RDMA_WR_BITS(DI_MTN_CTRL1, - (me_auto_en ? 3 : 2), 12, 2); - } else { - RDMA_WR_BITS(MCDI_MOTINEN, 0, 0, 2); - RDMA_WR(MCDI_CTRL_MODE, 0); - RDMA_WR_BITS(DI_MTN_CTRL1, 0, 12, 2); - } + &di_pre_stru.di_mcvecwr_mif, + di_pre_stru.mcdi_enable); + else + enable_mc_di_pre( + &di_pre_stru.di_mcinford_mif, + &di_pre_stru.di_mcinfowr_mif, + &di_pre_stru.di_mcvecwr_mif, + di_pre_stru.mcdi_enable); } di_pre_stru.field_count_for_cont++; @@ -2744,12 +2761,20 @@ static void pre_de_process(void) vdin_ops->tvin_vdin_func(0, &vdin_arg); } #endif - /* enable pre mif before reset avoid timeout */ +#if 0 + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + RDMA_WR(DI_PRE_GL_CTRL, 0xc3200005); + RDMA_WR(DI_PRE_GL_CTRL, 0x83200005); + } else { + /* frame + soft reset for the pre modules. */ + RDMA_WR(DI_PRE_CTRL, Rd(DI_PRE_CTRL) | 3 << 30); + } +#endif enable_di_pre_mif(true, mcpre_en); + /* frame + soft reset for the pre modules. */ - RDMA_WR(DI_PRE_CTRL, Rd(DI_PRE_CTRL) | 3 << 30); - RDMA_WR(DI_PRE_CTRL, - RDMA_RD(DI_PRE_CTRL) | (cont_rd << 25)); + RDMA_WR_BITS(DI_PRE_CTRL, 3, 30, 2); + #ifdef SUPPORT_MPEG_TO_VDIN if (mpeg2vdin_flag) RDMA_WR_BITS(DI_PRE_CTRL, 1, 13, 1); @@ -3146,6 +3171,15 @@ static void pre_inp_canvas_config(struct vframe_s *vf) } } #endif +static int pps_dstw; +module_param_named(pps_dstw, pps_dstw, int, 0644); +static int pps_dsth; +module_param_named(pps_dsth, pps_dsth, int, 0644); +static bool pps_en; +module_param_named(pps_en, pps_en, bool, 0644); +static unsigned int pre_enable_mask = 3; +module_param_named(pre_enable_mask, pre_enable_mask, uint, 0644); + static unsigned char pre_de_buf_config(void) { struct di_buf_s *di_buf = NULL; @@ -3634,6 +3668,14 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); /* set vframe bit info */ di_buf->vframe->bitdepth &= ~(BITDEPTH_YMASK); di_buf->vframe->bitdepth &= ~(FULL_PACK_422_MODE); + if (de_devp->pps_enable || pps_en) { + if (pps_dstw != di_buf->vframe->width) { + di_buf->vframe->width = pps_dstw; + di_pre_stru.width_bk = pps_dstw; + } + if (pps_dsth != di_buf->vframe->height) + di_buf->vframe->height = pps_dsth; + } if (di_force_bit_mode == 10) { di_buf->vframe->bitdepth |= (BITDEPTH_Y10); if (full_422_pack) @@ -3680,20 +3722,18 @@ jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); } if (di_pre_stru.di_inp_buf->post_proc_flag == 0) { - di_pre_stru.enable_mtnwr = 0; - di_pre_stru.enable_pulldown_check = 0; + di_pre_stru.madi_enable = 0; + di_pre_stru.mcdi_enable = 0; di_buf->post_proc_flag = 0; } else if (bypass_post_state) { - di_pre_stru.enable_mtnwr = 0; - di_pre_stru.enable_pulldown_check = 0; + di_pre_stru.madi_enable = 0; + di_pre_stru.mcdi_enable = 0; di_buf->post_proc_flag = 0; } else { - di_pre_stru.enable_mtnwr = 1; + di_pre_stru.madi_enable = (pre_enable_mask&1); + di_pre_stru.mcdi_enable = ((pre_enable_mask>>1)&1); di_buf->post_proc_flag = 1; - di_pre_stru.enable_pulldown_check = - di_pre_stru.cur_prog_flag ? 0 : 1; } - if ((di_pre_stru.di_mem_buf_dup_p == di_pre_stru.di_wr_buf) || (di_pre_stru.di_chan2_buf_dup_p == di_pre_stru.di_wr_buf)) { pr_dbg("+++++++++++++++++++++++\n"); @@ -3968,6 +4008,8 @@ static void set_post_mcinfo(struct mcinfo_pre_s *curr_field_mcinfo) DI_VSYNC_WR_MPEG_REG(0x2f78 + i, value); } } +static bool nrwr_dbg; +module_param_named(nrwr_dbg, nrwr_dbg, bool, 0644); static irqreturn_t de_irq(int irq, void *dev_instance) { #ifndef CHECK_DI_DONE @@ -4027,6 +4069,12 @@ static irqreturn_t de_irq(int irq, void *dev_instance) } if (flag) { + if (nrwr_dbg) { + pr_info("%dth bc %u bd %u.\n", + di_pre_stru.field_count_for_cont, + RDMA_RD(0x20bc), + RDMA_RD(0x20bd)); + } di_pre_stru.irq_time = (sched_clock()/NSEC_PER_MSEC - di_pre_stru.irq_time); trace_di_pre("PRE-IRQ-0", @@ -4042,6 +4090,8 @@ static irqreturn_t de_irq(int irq, void *dev_instance) di_pre_stru.di_wr_buf->mcinfo_adr); } nr_process_in_irq(); + if ((data32&0x200) && de_devp->nrds_enable) + nr_ds_irq(); /* disable mif */ enable_di_pre_mif(false, mcpre_en); di_pre_stru.pre_de_process_done = 1; @@ -4136,7 +4186,6 @@ static void vscale_skip_disable_post(struct di_buf_s *di_buf, vframe_t *disp_vf) disp_vf->height = di_buf_i->vframe->height; disp_vf->duration = di_buf_i->vframe->duration; disp_vf->pts = di_buf_i->vframe->pts; - disp_vf->omx_index = di_buf_i->vframe->omx_index; disp_vf->flag = di_buf_i->vframe->flag; disp_vf->canvas0Addr = di_post_idx[di_post_stru.canvas_id][0]; disp_vf->canvas1Addr = di_post_idx[di_post_stru.canvas_id][0]; @@ -4294,6 +4343,12 @@ MODULE_PARM_DESC(post_blend, "/n show blend mode/n"); static unsigned int post_ei; module_param(post_ei, uint, 0664); MODULE_PARM_DESC(post_ei, "/n show blend mode/n"); + +static unsigned int post_cnt; +module_param(post_cnt, uint, 0664); +MODULE_PARM_DESC(post_cnt, "/n show blend mode/n"); +static bool post_refresh; +module_param_named(post_refresh, post_refresh, bool, 0644); static int de_post_process(void *arg, unsigned int zoom_start_x_lines, unsigned int zoom_end_x_lines, unsigned int zoom_start_y_lines, @@ -4310,6 +4365,7 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, bool invert_mv = false; static int post_index = -1; + post_cnt++; if (di_post_stru.vscale_skip_flag) return 0; @@ -4336,7 +4392,7 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, di_post_stru.cur_disp_index = di_buf->index; - if (get_vpp_reg_update_flag(zoom_start_x_lines)) + if (get_vpp_reg_update_flag(zoom_start_x_lines) || post_refresh) di_post_stru.update_post_reg_flag = 1; /* pr_dbg("%s set update_post_reg_flag to %d\n", __func__, * di_post_stru.update_post_reg_flag); @@ -4732,11 +4788,18 @@ de_post_process(void *arg, unsigned int zoom_start_x_lines, (invert_mv?1:0), di_vscale_skip_count_real ); - if (mcpre_en) - enable_mc_di_post( - &di_post_stru.di_mcvecrd_mif, post_urgent, - overturn, (invert_mv?1:0)); - else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) + if (mcpre_en) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + enable_mc_di_post_g12( + &di_post_stru.di_mcvecrd_mif, + post_urgent, + overturn, (invert_mv?1:0)); + else + enable_mc_di_post( + &di_post_stru.di_mcvecrd_mif, + post_urgent, + overturn, (invert_mv?1:0)); + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); } else { di_post_switch_buffer( @@ -4847,8 +4910,6 @@ static void di_post_process(void) } } -int pd_detect_rst; - static void recycle_vframe_type_post(struct di_buf_s *di_buf) { int i; @@ -5642,6 +5703,7 @@ static void di_pre_size_change(unsigned short width, unsigned short height, unsigned short vf_type) { unsigned int blkhsize = 0; + int pps_w = 0, pps_h = 0; nr_all_config(width, height, vf_type); #ifdef DET3D @@ -5652,13 +5714,15 @@ static void di_pre_size_change(unsigned short width, init_field_mode(height); if (is_meson_txlx_cpu() || is_meson_gxlx_cpu() || - is_meson_txhd_cpu()) + is_meson_txhd_cpu() || + is_meson_g12a_cpu()) film_mode_win_config(width, height); } if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) combing_pd22_window_config(width, height); RDMA_WR(DI_PRE_SIZE, (width - 1) | ((height - 1) << 16)); + if (mcpre_en) { blkhsize = (width + 4) / 5; RDMA_WR(MCDI_HV_SIZEIN, height @@ -5671,8 +5735,22 @@ static void di_pre_size_change(unsigned short width, RDMA_WR(MCDI_FIELD_MV, 0); } } + di_load_pq_table(); + +#if 0 + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + RDMA_WR(DI_PRE_GL_CTRL, 0x80000005); +#endif + if (de_devp->nrds_enable) + nr_ds_init(width, height); + if (de_devp->pps_enable || pps_en) { + pps_w = di_pre_stru.cur_width; + pps_h = di_pre_stru.cur_height>>(vf_type?1:0); + di_pps_config(1, pps_w, pps_h, pps_dstw, (pps_dsth>>1)); + } } + static bool need_bypass(struct vframe_s *vf) { if (vf->type & VIDTYPE_MVC) @@ -5696,6 +5774,10 @@ static bool need_bypass(struct vframe_s *vf) return false; } + +static bool nrds_en; +module_param_named(nrds_en, nrds_en, bool, 0644); + static void di_reg_process_irq(void) { ulong irq_flag2 = 0; @@ -5739,6 +5821,8 @@ static void di_reg_process_irq(void) use_2_interlace_buff = 0; nr_height = (vframe->height>>1); } + de_devp->nrds_enable = nrds_en; + de_devp->pps_enable = pps_en; switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON); if (post_wr_en && post_wr_support) { diwr_set_power_control(1); @@ -5746,18 +5830,22 @@ static void di_reg_process_irq(void) enable_rdma(0); #endif } - if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) { if (!use_2_interlace_buff) { + #ifdef CLK_TREE_SUPPORT /* nr only clkb upto 500M*/ clk_set_rate(de_devp->vpu_clkb, de_devp->clkb_min_rate); + #endif di_top_gate_control(true, true); di_post_gate_control(true); /* freerun for reg configuration */ enable_di_post_mif(GATE_AUTO); } else { + #ifdef CLK_TREE_SUPPORT clk_set_rate(de_devp->vpu_clkb, de_devp->clkb_max_rate); + #endif di_top_gate_control(true, false); } enable_di_pre_mif(true, mcpre_en); @@ -5940,6 +6028,8 @@ static void di_pre_trigger_work(struct di_pre_stru_s *pre_stru_p) pre_stru_p->pre_de_busy_timer_count++; if (pre_stru_p->pre_de_busy_timer_count >= nr_done_check_cnt) { enable_di_pre_mif(false, mcpre_en); + if (de_devp->nrds_enable) + nr_ds_hw_ctrl(false); pre_stru_p->pre_de_busy_timer_count = 0; pre_stru_p->pre_de_irq_timeout_count++; if (timeout_miss_policy == 0) { @@ -6284,7 +6374,6 @@ light_unreg: di_pre_stru.vdin_source = true; } else { di_pre_stru.vdin_source = false; - pre_urgent = 0; } receiver_name = vf_get_receiver_name(VFM_NAME); if (receiver_name) { @@ -6677,8 +6766,6 @@ static struct di_pq_parm_s *di_pq_parm_create(struct am_pq_parm_s *pq_parm_p) size_t mem_size = 0; pq_ptr = vzalloc(sizeof(struct di_pq_parm_s)); - if (!pq_ptr) - return NULL; mem_size = sizeof(struct am_pq_parm_s); memcpy(&pq_ptr->pq_parm, pq_parm_p, mem_size); mem_size = sizeof(struct am_reg_s)*pq_parm_p->table_len; @@ -6934,10 +7021,11 @@ static void set_di_flag(void) { if (is_meson_txlx_cpu() || is_meson_gxlx_cpu() || - is_meson_txhd_cpu()) { + is_meson_txhd_cpu() || + is_meson_g12a_cpu()) { mcpre_en = true; mc_mem_alloc = true; - pulldown_enable = true; + pulldown_enable = false; di_pre_rdma_enable = false; /* * txlx atsc 1080i ei only will cause flicker @@ -6946,14 +7034,14 @@ static void set_di_flag(void) di_vscale_skip_enable = (is_meson_txlx_cpu() || is_meson_txhd_cpu())?12:4; use_2_interlace_buff = is_meson_gxlx_cpu()?0:1; - pre_hold_line = 12; if (nr10bit_support) di_force_bit_mode = 10; else di_force_bit_mode = 8; if (is_meson_txlx_cpu() || is_meson_gxlx_cpu() || - is_meson_txhd_cpu()) { + is_meson_txhd_cpu() || + is_meson_g12a_cpu()) { full_422_pack = true; } } else { @@ -6996,49 +7084,42 @@ RESERVEDMEM_OF_DECLARE(di, "amlogic, di-mem", rmem_di_setup); static void di_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev) { - struct clk *clk_div4, *clk_div3, *vpu_clkb_tmp, *vpu_clk; - unsigned long clkb_tmp_rate; + int ret = 0; + unsigned int tmp_clk[2] = {0, 0}; + struct clk *vpu_clk = NULL; vpu_clk = clk_get(dev, "vpu_mux"); if (IS_ERR(vpu_clk)) pr_err("%s: get clk vpu error.\n", __func__); - vpu_clkb_tmp = clk_get(dev, "vpu_clkb_tmp_composite"); - if (IS_ERR(vpu_clkb_tmp)) - pr_err("%s: get vpu clkb tmp error.\n", __func__); + else + clk_prepare_enable(vpu_clk); + + ret = of_property_read_u32_array(dev->of_node, "clock-range", + tmp_clk, 2); + if (ret) { + pdev->clkb_min_rate = 250000000; + pdev->clkb_max_rate = 500000000; + } else { + pdev->clkb_min_rate = tmp_clk[0]*1000000; + pdev->clkb_max_rate = tmp_clk[1]*1000000; + } + pr_info("DI: vpu clkb <%lu, %lu>\n", pdev->clkb_min_rate, + pdev->clkb_max_rate); + #ifdef CLK_TREE_SUPPORT pdev->vpu_clkb = clk_get(dev, "vpu_clkb_composite"); if (IS_ERR(pdev->vpu_clkb)) pr_err("%s: get vpu clkb gate error.\n", __func__); - if (is_meson_txlx_cpu()) { - clk_div4 = clk_get(dev, "fclk_div4"); - if (IS_ERR(clk_div4)) - pr_err("%s: get clk div4 error.\n", __func__); - clk_set_parent(vpu_clkb_tmp, clk_div4); - pdev->clkb_max_rate = 500000000; - pdev->clkb_min_rate = 250000000; - clkb_tmp_rate = 500000000; - } else { - clk_div3 = clk_get(dev, "fclk_div3"); - if (IS_ERR(clk_div3)) - pr_err("%s: get clk div3 error.\n", __func__); - clk_set_parent(vpu_clkb_tmp, clk_div3); - pdev->clkb_max_rate = 333000000; - pdev->clkb_min_rate = 333000000; - clkb_tmp_rate = 666000000; - } - clk_set_rate(vpu_clkb_tmp, clkb_tmp_rate); - clk_set_rate(pdev->vpu_clkb, pdev->clkb_min_rate); - clk_prepare_enable(vpu_clkb_tmp); - + clk_set_rate(pdev->vpu_clkb, pdev->clkb_max_rate); + clk_set_rate(pdev->vpu_clkb, pdev->clkb_max_rate); + #endif } + static int di_probe(struct platform_device *pdev) { int ret = 0; -/* struct resource *res_irq = NULL; */ struct di_dev_s *di_devp = NULL; -/* const void *name = NULL; */ - di_pr_info("di_probe\n"); di_devp = kmalloc(sizeof(struct di_dev_s), GFP_KERNEL); if (!di_devp) { pr_err("%s fail to allocate memory.\n", __func__); @@ -7068,8 +7149,15 @@ static int di_probe(struct platform_device *pdev) "flag_cma", &(di_devp->flag_cma)); if (ret) pr_err("DI-%s: get flag_cma error.\n", __func__); - else - pr_info("DI-%s: flag_cma: %d\n", __func__, di_devp->flag_cma); + ret = of_property_read_u32(pdev->dev.of_node, + "nrds-enable", &(di_devp->nrds_enable)); + ret = of_property_read_u32(pdev->dev.of_node, + "pps-enable", &(di_devp->pps_enable)); + + pr_info("DI cma_flag %u, nrds %u, pps %u.\n", + di_devp->flag_cma, + di_devp->nrds_enable, + di_devp->pps_enable); if (di_devp->flag_cma >= 1) { #ifdef CONFIG_CMA di_devp->pdev = pdev; @@ -7087,10 +7175,16 @@ static int di_probe(struct platform_device *pdev) } mutex_init(&di_devp->cma_mutex); INIT_LIST_HEAD(&di_devp->pq_table_list); + atomic_set(&di_devp->pq_flag, 0); - di_devp->di_irq = irq_of_parse_and_map(pdev->dev.of_node, 0); - pr_info("di_irq:%d\n", - di_devp->di_irq); + + di_devp->pre_irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + pr_info("pre_irq:%d\n", + di_devp->pre_irq); + di_devp->post_irq = irq_of_parse_and_map(pdev->dev.of_node, 1); + pr_info("post_irq:%d\n", + di_devp->post_irq); + #ifdef CONFIG_AMLOGIC_MEDIA_RDMA /* rdma handle */ if (di_pre_rdma_enable) { @@ -7101,9 +7195,16 @@ static int di_probe(struct platform_device *pdev) #endif di_pr_info("%s allocate rdma channel %d.\n", __func__, di_devp->rdma_handle); - if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) { di_get_vpu_clkb(&pdev->dev, di_devp); + #ifdef CLK_TREE_SUPPORT clk_prepare_enable(di_devp->vpu_clkb); + pr_info("DI:enable vpu clkb.\n"); + #else + aml_write_hiubus(HHI_VPU_CLKB_CNTL, 0x1200300); + #endif + pr_info("DI:clkb cnt 0x%x.\n", + aml_read_hiubus(HHI_VPU_CLKB_CNTL)); } di_devp->flags &= (~DI_SUSPEND_FLAG); ret = of_property_read_u32(pdev->dev.of_node, @@ -7111,7 +7212,6 @@ static int di_probe(struct platform_device *pdev) if (ret) pr_err("DI-%s: get buffer size error.\n", __func__); - /* set flag to indicate that post_wr is supportted */ ret = of_property_read_u32(pdev->dev.of_node, "post-wr-support", @@ -7138,8 +7238,6 @@ static int di_probe(struct platform_device *pdev) return ret; } #endif -/* call di_add_reg_cfg() */ - device_create_file(di_devp->dev, &dev_attr_config); device_create_file(di_devp->dev, &dev_attr_debug); @@ -7162,14 +7260,15 @@ static int di_probe(struct platform_device *pdev) vf_reg_receiver(&di_vf_recv); vf_provider_init(&di_vf_prov, VFM_NAME, &deinterlace_vf_provider, NULL); active_flag = 1; - ret = request_irq(di_devp->di_irq, &de_irq, IRQF_SHARED, - "deinterlace", (void *)"deinterlace"); - + ret = request_irq(di_devp->pre_irq, &de_irq, IRQF_SHARED, + "pre_di", (void *)"pre_di"); + if (di_devp->post_wr_support) { + ret = request_irq(di_devp->post_irq, &de_irq, + IRQF_SHARED, "post_di", (void *)"post_di"); + } sema_init(&di_sema, 1); di_sema_init_flag = 1; - di_hw_init(pulldown_enable, mcpre_en); - set_di_flag(); /* Disable MCDI when code does not surpport MCDI */ @@ -7196,7 +7295,7 @@ static int di_remove(struct platform_device *pdev) di_devp = platform_get_drvdata(pdev); - if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) clk_disable_unprepare(di_devp->vpu_clkb); di_hw_uninit(); di_devp->di_event = 0xff; @@ -7236,6 +7335,11 @@ static int di_remove(struct platform_device *pdev) } else { pr_dbg("DI CMA total release fail.\n"); } + if (de_devp->nrds_enable) { + nr_ds_buf_uninit(de_devp->flag_cma, + &(pdev->dev)); + } + } device_destroy(di_clsp, di_devno); kfree(di_devp); @@ -7297,7 +7401,7 @@ static int di_suspend(struct device *dev) if (!is_meson_txlx_cpu()) switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_OFF); - if (is_meson_txhd_cpu()) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) clk_disable_unprepare(di_devp->vpu_clkb); pr_info("di: di_suspend\n"); return 0; @@ -7308,7 +7412,7 @@ static int di_resume(struct device *dev) struct di_dev_s *di_devp = NULL; di_devp = dev_get_drvdata(dev); - if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) clk_prepare_enable(di_devp->vpu_clkb); init_flag = save_init_flag; di_devp->flags &= ~DI_SUSPEND_FLAG; @@ -7388,7 +7492,6 @@ static void __exit di_module_exit(void) module_init(di_module_init); module_exit(di_module_exit); - module_param_named(bypass_all, bypass_all, int, 0664); module_param_named(bypass_3d, bypass_3d, int, 0664); module_param_named(bypass_trick_mode, bypass_trick_mode, int, 0664); @@ -7433,12 +7536,6 @@ MODULE_PARM_DESC(det3d_mode, "\n det3d_mode\n"); module_param(det3d_mode, uint, 0664); #endif -MODULE_PARM_DESC(pre_hold_line, "\n pre_hold_line\n"); -module_param(pre_hold_line, uint, 0664); - -MODULE_PARM_DESC(pre_urgent, "\n pre_urgent\n"); -module_param(pre_urgent, uint, 0664); - MODULE_PARM_DESC(post_hold_line, "\n post_hold_line\n"); module_param(post_hold_line, uint, 0664); diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h index ff18beeec076..a06b5cc26c67 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.h +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -18,6 +18,7 @@ #ifndef _DI_H #define _DI_H #include +#include #include #include @@ -50,7 +51,7 @@ /* buffer management related */ #define MAX_IN_BUF_NUM 20 -#define MAX_LOCAL_BUF_NUM 12 +#define MAX_LOCAL_BUF_NUM 10 #define MAX_POST_BUF_NUM 16 #define VFRAME_TYPE_IN 1 @@ -65,7 +66,7 @@ #define DI_USE_FIXED_CANVAS_IDX #define DET3D #undef SUPPORT_MPEG_TO_VDIN - +#define CLK_TREE_SUPPORT #ifndef CONFIG_AMLOGIC_MEDIA_RDMA #ifndef VSYNC_WR_MPEG_REG #define VSYNC_WR_MPEG_REG(adr, val) aml_write_vcbus(adr, val) @@ -203,7 +204,8 @@ struct di_dev_s { struct list_head pq_table_list; atomic_t pq_flag; unsigned char di_event; - unsigned int di_irq; + unsigned int pre_irq; + unsigned int post_irq; unsigned int flags; unsigned long jiffy; unsigned long mem_start; @@ -216,6 +218,8 @@ struct di_dev_s { unsigned int nr10bit_support; /* is DI support post wr to mem for OMX */ unsigned int post_wr_support; + unsigned int nrds_enable; + unsigned int pps_enable; struct mutex cma_mutex; unsigned int flag_cma; struct page *total_pages; @@ -293,13 +297,15 @@ struct di_pre_stru_s { /* alloc di buf as p or i;0: alloc buf as i; * 1: alloc buf as p; */ - unsigned char enable_mtnwr; - unsigned char enable_pulldown_check; + unsigned char madi_enable; + unsigned char mcdi_enable; + unsigned int pps_dstw; + unsigned int pps_dsth; int left_right;/*1,left eye; 0,right eye in field alternative*/ /*input2pre*/ int bypass_start_count; /* need discard some vframe when input2pre => bypass */ - int vdin2nr; + unsigned char vdin2nr; enum tvin_trans_fmt source_trans_fmt; enum tvin_trans_fmt det3d_trans_fmt; unsigned int det_lr; diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c index 64ea2bdce9af..5ed3fd5df094 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c @@ -32,8 +32,10 @@ #include #include #include -#include "deinterlace_dbg.h" #include "register.h" +#include "deinterlace_dbg.h" +#include "di_pps.h" +#include "nr_downscale.h" void parse_cmd_params(char *buf_orig, char **parm) { @@ -57,7 +59,7 @@ void parse_cmd_params(char *buf_orig, char **parm) void dump_di_reg(void) { unsigned int i = 0, base_addr = 0; - unsigned int size_reg_addr[57] = { + unsigned int size_reg_addr[] = { 0x1702, 0x1703, 0x2d01, 0x2d01, 0x2d8f, 0x2d08, 0x2d09, 0x2f00, 0x2f01, @@ -76,7 +78,18 @@ void dump_di_reg(void) 0x1a53, 0x1a54, 0x1a55, 0x1a56, 0x17ea, 0x17eb, 0x17ec, 0x17ed, 0x2012, - 0x2013, 0x2014, 0x2015 + 0x2013, 0x2014, 0x2015, + 0x37d2, 0x37d3, 0x37d7, + 0x37d8, 0x37dc, 0x37dd, + 0x37e1, 0x37e2, 0x37e6, + 0x37e7, 0x37e9, 0x37ea, + 0x37ed, 0x37ee, 0x37f1, + 0x37f2, 0x37f4, 0x37f5, + 0x37f6, 0x37f8, 0x3751, + 0x3752, 0x376e, 0x376f, + 0x37f9, 0x37fa, 0x37fc, + 0x3740, 0x3757, 0x3762, + 0xffff }; if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) base_addr = 0xff900000; @@ -85,7 +98,7 @@ void dump_di_reg(void) pr_info("----dump di reg----\n"); pr_info("----dump size reg---"); - for (i = 0; i < 57; i++) + for (i = 0; size_reg_addr[i] != 0xffff; i++) pr_info("[0x%x][0x%x]=0x%x\n", base_addr + ((size_reg_addr[i]) << 2), size_reg_addr[i], RDMA_RD(size_reg_addr[i])); @@ -102,6 +115,11 @@ void dump_di_reg(void) base_addr + ((0x1700 + i) << 2), 0x1700 + i, RDMA_RD(0x1700 + i)); } + for (i = 0; i < 4; i++) { + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x20ab + i) << 2), + 0x20ab + i, RDMA_RD(0x20ab + i)); + } pr_info("----dump mcdi reg----\n"); for (i = 0; i < 201; i++) pr_info("[0x%x][0x%x]=0x%x\n", @@ -171,6 +189,192 @@ void dump_di_reg(void) pr_info("----dump reg done----\n"); } +void dump_di_reg_g12(void) +{ + unsigned int i = 0, base_addr = 0; + unsigned int size_reg_addr[] = { + 0x1700, 0x1701, 0x1702, + 0x1703, 0x37d2, 0x27d3, + 0x37d7, 0x37d8, 0x37dc, + 0x37dd, 0x37e1, 0x37e2, + 0x37e6, 0x37e7, 0x37e9, + 0x37ea, 0x37ec, 0x37ed, + 0x37ee, 0x37f0, 0x37f1, + 0x37f2, 0x37f4, 0x37f5, + 0x37f6, 0x37f8, 0x2032, + 0x2033, 0x2034, 0x2035, + 0x2d01, 0x2d02, 0x2d8f, + 0x2d08, 0x2d09, 0x2f00, + 0x2f01, 0x17d0, 0x17d1, + 0x17d2, 0x17d3, 0x17dd, + 0x17de, 0x17df, 0x17e0, + 0x17f7, 0x17f8, 0x17f9, + 0x17fa, 0x17c0, 0x17c1, + 0x17c6, 0x17c7, 0x3253, + 0x3254, 0x3255, 0x3256, + 0x17ea, 0x17eb, 0x17ec, + 0x17ed, 0x2012, 0x2013, + 0x2014, 0x2015, 0x37d2, + 0x37d3, 0x37d7, 0x37d8, + 0x37dc, 0x37dd, 0x37e1, + 0x37e2, 0x37e6, 0x37e7, + 0x37e9, 0x37ea, 0x37ed, + 0x37ee, 0x37f1, 0x37f2, + 0x37f4, 0x37f5, 0x37f6, + 0x37f8, 0x3751, 0x3752, + 0x376e, 0x376f, 0x37f9, + 0x37fa, 0x37fc, 0x3740, + 0x3757, 0x3762, 0x3755, + 0x3757, 0x3760, 0x3762, + 0x376e, 0x376f, 0x37f9, + 0x37fa, 0x37fc, 0xffff + }; + if (is_meson_txlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu()) + base_addr = 0xff900000; + else + base_addr = 0xd0100000; + + pr_info("----dump di reg----\n"); + pr_info("----dump size reg---"); + for (i = 0; size_reg_addr[i] != 0xffff; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((size_reg_addr[i]) << 2), + size_reg_addr[i], RDMA_RD(size_reg_addr[i])); + for (i = 0; i < 255; i++) { + if (i == 0x45) + pr_info("----nr reg----"); + if (i == 0x80) + pr_info("----3d reg----"); + if (i == 0x9e) + pr_info("---nr reg done---"); + if (i == 0x9c) + pr_info("---3d reg done---"); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x1700 + i) << 2), + 0x1700 + i, RDMA_RD(0x1700 + i)); + } + dump_pps_reg(base_addr); + dump_nrds_reg(base_addr); + pr_info("----dump mcdi reg----\n"); + for (i = 0; i < 201; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2f00 + i) << 2), + 0x2f00 + i, RDMA_RD(0x2f00 + i)); + pr_info("----dump pulldown reg----\n"); + for (i = 0; i < 26; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2fd0 + i) << 2), + 0x2fd0 + i, RDMA_RD(0x2fd0 + i)); + pr_info("----dump bit mode reg----\n"); + for (i = 0; i < 4; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x20a7 + i) << 2), + 0x20a7 + i, RDMA_RD(0x20a7 + i)); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (0x2022 << 2), + 0x2022, RDMA_RD(0x2022)); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (0x17c1 << 2), + 0x17c1, RDMA_RD(0x17c1)); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (0x17c2 << 2), + 0x17c2, RDMA_RD(0x17c2)); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (0x1aa7 << 2), + 0x1aa7, RDMA_RD(0x1aa7)); + pr_info("----dump dnr reg----\n"); + for (i = 0; i < 29; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2d00 + i) << 2), + 0x2d00 + i, RDMA_RD(0x2d00 + i)); + pr_info("----dump if0 reg----\n"); + for (i = 0; i < 26; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x3200 + i) << 2), + 0x3200 + i, RDMA_RD(0x3200 + i)); + pr_info("----dump gate reg----\n"); + pr_info("[0x%x][0x1718]=0x%x\n", + base_addr + ((0x1718) << 2), + RDMA_RD(0x1718)); + for (i = 0; i < 5; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2006 + i) << 2), + 0x2006 + i, RDMA_RD(0x2006 + i)); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2dff) << 2), + 0x2dff, RDMA_RD(0x2dff)); + pr_info("----dump if2 reg----\n"); + for (i = 0; i < 29; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2010 + i) << 2), + 0x2010 + i, RDMA_RD(0x2010 + i)); + pr_info("----dump nr4 reg----\n"); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2fff) << 2), + 0x2fff, RDMA_RD(0x2fff)); + for (i = 0x2da4; i < 0x2df6; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), + i, RDMA_RD(i)); + for (i = 0x3700; i < 0x373f; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), + i, RDMA_RD(i)); + for (i = 0; i < 57; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((size_reg_addr[i]) << 2), + size_reg_addr[i], RDMA_RD(size_reg_addr[i])); + pr_info("----dump arb reg----\n"); + for (i = 0; i < 14; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x3750 + i) << 2), + 0x3750 + i, RDMA_RD(0x3750 + i)); + for (i = 0; i < 14; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x37c0 + i) << 2), + 0x37c0 + i, RDMA_RD(0x37c0 + i)); + + pr_info("----dump pps reg----\n"); + for (i = 0; i < 32; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x374e + i) << 2), + 0x374e + i, RDMA_RD(0x374e + i)); + + pr_info("----dump di hdr reg----\n"); + for (i = 0; i < 62; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + ((0x376e + i) << 2), + 0x376e + i, RDMA_RD(0x376e + i)); + pr_info("----dump reg done----\n"); +} + +static void dump_mif_state(struct DI_MIF_s *mif) +{ + pr_info("luma <%u, %u> <%u %u>.\n", + mif->luma_x_start0, mif->luma_x_end0, + mif->luma_y_start0, mif->luma_y_end0); + pr_info("if0 chroma <%u, %u> <%u %u>.\n", + mif->chroma_x_start0, mif->chroma_x_end0, + mif->chroma_y_start0, mif->chroma_y_end0); +} + +static void dump_simple_mif_state(struct DI_SIM_MIF_s *simp_mif) +{ + pr_info("<%u %u> <%u %u>.\n", + simp_mif->start_x, simp_mif->end_x, + simp_mif->start_y, simp_mif->end_y); +} + +static void dump_mc_mif_state(struct DI_MC_MIF_s *mc_mif) +{ + pr_info("startx %u,<%u %u>, size <%u %u>.\n", + mc_mif->start_x, mc_mif->start_y, + mc_mif->end_y, mc_mif->size_x, + mc_mif->size_y); +} + void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p) { pr_info("di_pre_stru:\n"); @@ -214,10 +418,10 @@ void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p) di_pre_stru_p->source_change_flag); pr_info("prog_proc_type = %d\n", di_pre_stru_p->prog_proc_type); - pr_info("enable_mtnwr = %d\n", - di_pre_stru_p->enable_mtnwr); - pr_info("enable_pulldown_check = %d\n", - di_pre_stru_p->enable_pulldown_check); + pr_info("madi_enable = %u\n", + di_pre_stru_p->madi_enable); + pr_info("mcdi_enable = %u\n", + di_pre_stru_p->mcdi_enable); #ifdef DET3D pr_info("vframe_interleave_flag = %d\n", di_pre_stru_p->vframe_interleave_flag); @@ -232,21 +436,55 @@ void dump_di_pre_stru(struct di_pre_stru_s *di_pre_stru_p) di_pre_stru_p->bypass_pre ? "true" : "false"); pr_info("invert_flag = %s\n", di_pre_stru_p->invert_flag ? "true" : "false"); + pr_info("inp mif:\n"); + dump_mif_state(&di_pre_stru_p->di_inp_mif); + pr_info("mem mif:\n"); + dump_mif_state(&di_pre_stru_p->di_mem_mif); + pr_info("chan2 mif:\n"); + dump_mif_state(&di_pre_stru_p->di_chan2_mif); + pr_info("nrwr mif:\n"); + dump_simple_mif_state(&di_pre_stru_p->di_nrwr_mif); + pr_info("mtnwr mif:\n"); + dump_simple_mif_state(&di_pre_stru_p->di_mtnwr_mif); + pr_info("contp2rd mif:\n"); + dump_simple_mif_state(&di_pre_stru_p->di_contp2rd_mif); + pr_info("contprd mif:\n"); + dump_simple_mif_state(&di_pre_stru_p->di_contprd_mif); + pr_info("contwr mif:\n"); + dump_simple_mif_state(&di_pre_stru_p->di_contwr_mif); + pr_info("mcinford mif:\n"); + dump_mc_mif_state(&di_pre_stru_p->di_mcinford_mif); + pr_info("mcinfowr mif:\n"); + dump_mc_mif_state(&di_pre_stru_p->di_mcinfowr_mif); + pr_info("mcvecwr mif:\n"); + dump_mc_mif_state(&di_pre_stru_p->di_mcvecwr_mif); } void dump_di_post_stru(struct di_post_stru_s *di_post_stru_p) { - di_pr_info("\ndi_post_stru:\n"); - di_pr_info("run_early_proc_fun_flag = %d\n", + pr_info("\ndi_post_stru:\n"); + pr_info("run_early_proc_fun_flag = %d\n", di_post_stru_p->run_early_proc_fun_flag); - di_pr_info("cur_disp_index = %d\n", + pr_info("cur_disp_index = %d\n", di_post_stru_p->cur_disp_index); - di_pr_info("post_de_busy = %d\n", + pr_info("post_de_busy = %d\n", di_post_stru_p->post_de_busy); - di_pr_info("de_post_process_done = %d\n", + pr_info("de_post_process_done = %d\n", di_post_stru_p->de_post_process_done); - di_pr_info("cur_post_buf = 0x%p\n,", + pr_info("cur_post_buf = 0x%p\n,", di_post_stru_p->cur_post_buf); + pr_info("if0 mif:\n"); + dump_mif_state(&di_post_stru_p->di_buf0_mif); + pr_info("if1 mif:\n"); + dump_mif_state(&di_post_stru_p->di_buf1_mif); + pr_info("if2 mif:\n"); + dump_mif_state(&di_post_stru_p->di_buf2_mif); + pr_info("diwr mif:\n"); + dump_simple_mif_state(&di_post_stru_p->di_diwr_mif); + pr_info("mtnprd mif:\n"); + dump_simple_mif_state(&di_post_stru_p->di_mtnprd_mif); + pr_info("mcvecrd mif:\n"); + dump_mc_mif_state(&di_post_stru_p->di_mcvecrd_mif); } void dump_di_buf(struct di_buf_s *di_buf) @@ -442,3 +680,18 @@ void dump_post_mif_reg(void) pr_info("DI_DIWR_X=0x%x.\n", Rd(DI_DIWR_X)); } +void dump_buf_addr(struct di_buf_s *di_buf, unsigned int num) +{ + unsigned int i = 0; + struct di_buf_s *di_buf_p = NULL; + + for (i = 0; i < num; i++) { + di_buf_p = (di_buf+i); + pr_info("di_buf[%d] nr_addr 0x%lx,", + di_buf_p->index, di_buf_p->nr_adr); + pr_info("mtn_addr 0x%lx, cnt_adr 0x%lx,", + di_buf_p->mtn_adr, di_buf_p->cnt_adr); + pr_info("mv_adr 0x%lx, mcinfo_adr 0x%lx.\n", + di_buf_p->mcvec_adr, di_buf_p->mcinfo_adr); + } +} diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.h b/drivers/amlogic/media/deinterlace/deinterlace_dbg.h index d4072de81231..51745911be68 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_dbg.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.h @@ -25,9 +25,11 @@ void dump_di_buf(struct di_buf_s *di_buf); void dump_pool(struct queue_s *q); void dump_vframe(vframe_t *vf); void dump_di_reg(void); +void dump_di_reg_g12(void); void print_di_buf(struct di_buf_s *di_buf, int format); void dump_pre_mif_state(void); void dump_post_mif_reg(void); +void dump_buf_addr(struct di_buf_s *di_buf, unsigned int num); void debug_device_files_add(struct device *dev); void debug_device_files_del(struct device *dev); #endif diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c index baa34fbd1af2..90d5a067be22 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.c +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -38,13 +39,13 @@ module_param(mcen_mode, ushort, 0664); static unsigned short mcuv_en = 1; MODULE_PARM_DESC(mcuv_en, "\n blend mcuv enable\n"); module_param(mcuv_en, ushort, 0664); + static unsigned short mcdebug_mode; MODULE_PARM_DESC(mcdebug_mode, "\n mcdi mcdebugmode\n"); module_param(mcdebug_mode, ushort, 0664); -static unsigned short debug_blend_mode_ctrl = 0xff; -MODULE_PARM_DESC(debug_blend_mode_ctrl, "\n debug blend mode ctrl\n"); -module_param(debug_blend_mode_ctrl, ushort, 0664); +static unsigned short pre_urgent; +static unsigned short pre_hold_line = 10; /* * 0: use vframe->bitdepth, * 8: froce to 8 bit mode. @@ -122,6 +123,10 @@ static void set_di_chan2_mif(struct DI_MIF_s *mif, int urgent, int hold_line); static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent, int hold_line, int vskip_cnt, int wr_en); +static void set_di_if0_mif_g12(struct DI_MIF_s *mif, int urgent, + int hold_line, int vskip_cnt, int wr_en); + + static void ma_di_init(void) { /* 420->422 chrome difference is large motion is large,flick */ @@ -273,10 +278,10 @@ void mc_pre_mv_irq(void) static void lmvs_init(struct mcinfo_lmv_s *lmvs, unsigned short lmv) { - lmvs->lock_flag = (lmv>>14) & 3; - lmvs->lmv = (lmv>>8)&63; - lmvs->lmv = lmvs->lmv > 32 ? (32 - lmvs->lmv) : lmvs->lmv; - lmvs->lock_cnt = (lmv & 255); + lmvs->lock_flag = (lmv>>14) & 3; + lmvs->lmv = (lmv>>8)&63; + lmvs->lmv = lmvs->lmv > 32 ? (32 - lmvs->lmv) : lmvs->lmv; + lmvs->lock_cnt = (lmv & 255); } static bool lmv_lock_win_en; @@ -413,7 +418,8 @@ void di_hw_init(bool pd_enable, bool mc_enable) unsigned short fifo_size_vpp = 0xc0; unsigned short fifo_size_di = 0xc0; switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON); - if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) + if (is_meson_txlx_cpu() || is_meson_txhd_cpu() + || is_meson_g12a_cpu()) di_top_gate_control(true, true); else if (is_meson_gxl_cpu() || is_meson_gxm_cpu() || is_meson_gxlx_cpu()) @@ -423,14 +429,13 @@ void di_hw_init(bool pd_enable, bool mc_enable) if (is_meson_txlx_cpu() || is_meson_gxlx_cpu() || - is_meson_txhd_cpu()) { + is_meson_txhd_cpu() || is_meson_g12a_cpu()) { /* vpp fifo max size on txl :128*3=384[0x180] */ /* di fifo max size on txl :96*3=288[0x120] */ fifo_size_vpp = 0x180; fifo_size_di = 0x120; } - /* enable di all arb */ - DI_Wr_reg_bits(DI_ARB_CTRL, 0xf0f, 0, 16); + DI_Wr(VD1_IF0_LUMA_FIFO_SIZE, fifo_size_vpp); DI_Wr(VD2_IF0_LUMA_FIFO_SIZE, fifo_size_vpp); /* 1a83 is vd2_if0_luma_fifo_size */ @@ -443,13 +448,28 @@ void di_hw_init(bool pd_enable, bool mc_enable) DI_Wr(DI_IF2_LUMA_FIFO_SIZE, fifo_size_di); /* 201a is if2 fifo size */ DI_Wr(DI_CHAN2_LUMA_FIFO_SIZE, fifo_size_di); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + DI_Wr(DI_IF0_LUMA_FIFO_SIZE, fifo_size_di); + DI_Wr(DI_ARB_CTRL, 0); + } else { + /* enable di all arb */ + DI_Wr_reg_bits(DI_ARB_CTRL, 0xf0f, 0, 16); + } /* 17b3 is DI_chan2_luma_fifo_size */ if (is_meson_txlx_cpu() || - is_meson_txhd_cpu()) { + is_meson_txhd_cpu() || is_meson_g12a_cpu()) { di_pre_gate_control(true, true); di_post_gate_control(true); } + pre_hold_block_mode_config(); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + DI_Wr(DI_PRE_HOLD, 0); + else + DI_Wr(DI_PRE_HOLD, (1 << 31) | (31 << 16) | 31); + ma_di_init(); ei_hw_init(); nr_hw_init(); @@ -459,7 +479,7 @@ void di_hw_init(bool pd_enable, bool mc_enable) if (mc_enable) mc_di_param_init(); if (is_meson_txlx_cpu() || - is_meson_txhd_cpu()) { + is_meson_txhd_cpu() || is_meson_g12a_cpu()) { di_pre_gate_control(false, true); di_post_gate_control(false); di_top_gate_control(false, false); @@ -480,21 +500,136 @@ void di_hw_uninit(void) nr_gate_control(false); } -/* config di pre bit mode */ -static void pre_bit_mode_config(unsigned char inp, - unsigned char mem, unsigned char chan2, unsigned char nrwr) +/* + * mtn wr mif, contprd mif, contp2rd mif, + * contwr mif config + */ +static void set_ma_pre_mif(struct DI_SIM_MIF_s *mtnwr_mif, + struct DI_SIM_MIF_s *contprd_mif, + struct DI_SIM_MIF_s *contp2rd_mif, + struct DI_SIM_MIF_s *contwr_mif, + unsigned short urgent) { - if (!cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) - return; + /* current field mtn canvas index. */ + RDMA_WR(DI_MTNWR_X, (mtnwr_mif->start_x << 16)| + (mtnwr_mif->end_x)); + RDMA_WR(DI_MTNWR_Y, (mtnwr_mif->start_y << 16)| + (mtnwr_mif->end_y)); + RDMA_WR(DI_MTNWR_CTRL, mtnwr_mif->canvas_num| + (urgent << 8)); /* urgent. */ - RDMA_WR_BITS(DI_INP_GEN_REG3, inp&0x3, 8, 2); - RDMA_WR_BITS(DI_MEM_GEN_REG3, mem&0x3, 8, 2); - RDMA_WR_BITS(DI_CHAN2_GEN_REG3, chan2&0x3, 8, 2); - RDMA_WR_BITS(DI_NRWR_Y, nrwr&0x1, 14, 1); - if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL) && ((nrwr&0x3) == 0x3)) + RDMA_WR(DI_CONTPRD_X, (contprd_mif->start_x << 16)| + (contprd_mif->end_x)); + RDMA_WR(DI_CONTPRD_Y, (contprd_mif->start_y << 16)| + (contprd_mif->end_y)); + RDMA_WR(DI_CONTP2RD_X, (contp2rd_mif->start_x << 16)| + (contp2rd_mif->end_x)); + RDMA_WR(DI_CONTP2RD_Y, (contp2rd_mif->start_y << 16)| + (contp2rd_mif->end_y)); + RDMA_WR(DI_CONTRD_CTRL, (contprd_mif->canvas_num << 8)| + (urgent << 16)|/* urgent */ + contp2rd_mif->canvas_num); + + RDMA_WR(DI_CONTWR_X, (contwr_mif->start_x << 16)| + (contwr_mif->end_x)); + RDMA_WR(DI_CONTWR_Y, (contwr_mif->start_y << 16)| + (contwr_mif->end_y)); + RDMA_WR(DI_CONTWR_CTRL, contwr_mif->canvas_num| + (urgent << 8));/* urgent. */ +} + +static bool ma_mif_dbg; +module_param_named(ma_mif_dbg, ma_mif_dbg, bool, 0644); +static void set_ma_pre_mif_g12(struct DI_SIM_MIF_s *mtnwr_mif, + struct DI_SIM_MIF_s *contprd_mif, + struct DI_SIM_MIF_s *contp2rd_mif, + struct DI_SIM_MIF_s *contwr_mif, + unsigned short urgent) +{ + + RDMA_WR_BITS(CONTRD_SCOPE_X, contprd_mif->start_x, 0, 13); + RDMA_WR_BITS(CONTRD_SCOPE_X, contprd_mif->end_x, 16, 13); + RDMA_WR_BITS(CONTRD_SCOPE_Y, contprd_mif->start_y, 0, 13); + RDMA_WR_BITS(CONTRD_SCOPE_Y, contprd_mif->end_y, 16, 13); + RDMA_WR_BITS(CONTRD_CTRL1, contprd_mif->canvas_num, 16, 8); + RDMA_WR_BITS(CONTRD_CTRL1, 2, 8, 2); + RDMA_WR_BITS(CONTRD_CTRL1, 0, 0, 3); + + RDMA_WR_BITS(CONT2RD_SCOPE_X, contp2rd_mif->start_x, 0, 13); + RDMA_WR_BITS(CONT2RD_SCOPE_X, contp2rd_mif->end_x, 16, 13); + RDMA_WR_BITS(CONT2RD_SCOPE_Y, contp2rd_mif->start_y, 0, 13); + RDMA_WR_BITS(CONT2RD_SCOPE_Y, contp2rd_mif->end_y, 16, 13); + RDMA_WR_BITS(CONT2RD_CTRL1, contp2rd_mif->canvas_num, 16, 8); + RDMA_WR_BITS(CONT2RD_CTRL1, 2, 8, 2); + RDMA_WR_BITS(CONT2RD_CTRL1, 0, 0, 3); + + /* current field mtn canvas index. */ + RDMA_WR_BITS(MTNWR_X, mtnwr_mif->start_x, 16, 13); + RDMA_WR_BITS(MTNWR_X, mtnwr_mif->end_x, 0, 13); + RDMA_WR_BITS(MTNWR_X, 2, 30, 2); + RDMA_WR_BITS(MTNWR_Y, mtnwr_mif->start_y, 16, 13); + RDMA_WR_BITS(MTNWR_Y, mtnwr_mif->end_y, 0, 13); + RDMA_WR_BITS(MTNWR_CTRL, mtnwr_mif->canvas_num, 0, 8); + RDMA_WR_BITS(MTNWR_CAN_SIZE, + (mtnwr_mif->end_y - mtnwr_mif->start_y), 0, 13); + RDMA_WR_BITS(MTNWR_CAN_SIZE, + (mtnwr_mif->end_x - mtnwr_mif->start_x), 16, 13); + + RDMA_WR_BITS(CONTWR_X, contwr_mif->start_x, 16, 13); + RDMA_WR_BITS(CONTWR_X, contwr_mif->end_x, 0, 13); + RDMA_WR_BITS(CONTWR_X, 2, 30, 2); + RDMA_WR_BITS(CONTWR_Y, contwr_mif->start_y, 16, 13); + RDMA_WR_BITS(CONTWR_Y, contwr_mif->end_y, 0, 13); + RDMA_WR_BITS(CONTWR_CTRL, contwr_mif->canvas_num, 0, 8); + RDMA_WR_BITS(CONTWR_CAN_SIZE, + (contwr_mif->end_y - contwr_mif->start_y), 0, 13); + RDMA_WR_BITS(CONTWR_CAN_SIZE, + (contwr_mif->end_x - contwr_mif->start_x), 16, 13); + if (ma_mif_dbg) { + pr_info("contrd x<%u, %u> y<%u %u>.\n", + contprd_mif->start_x, + contprd_mif->end_x, + contprd_mif->start_y, + contprd_mif->end_y); + pr_info("cont2rd x<%u, %u> y<%u %u>.\n", + contp2rd_mif->start_x, + contp2rd_mif->end_x, + contp2rd_mif->start_y, + contp2rd_mif->end_y); + pr_info("mtnwr x<%u, %u> y<%u %u>.\n", + mtnwr_mif->start_x, + mtnwr_mif->end_x, + mtnwr_mif->start_y, + mtnwr_mif->end_y); + pr_info("contwr x<%u, %u> y<%u %u>.\n", + contwr_mif->start_x, + contwr_mif->end_x, + contwr_mif->start_y, + contwr_mif->end_y); + ma_mif_dbg = false; + } +} + +static void set_di_nrwr_mif(struct DI_SIM_MIF_s *nrwr_mif, + unsigned short urgent) +{ + RDMA_WR_BITS(DI_NRWR_X, nrwr_mif->end_x, 0, 14); + RDMA_WR_BITS(DI_NRWR_X, nrwr_mif->start_x, 16, 14); + RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->start_y, 16, 13); + RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->end_y, 0, 13); + RDMA_WR_BITS(DI_NRWR_Y, 3, 30, 2); + RDMA_WR(DI_NRWR_CTRL, nrwr_mif->canvas_num| + (urgent<<16)| + 2<<26 | + 1<<30); + RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->bit_mode&0x1, 14, 1); + if ((nrwr_mif->bit_mode&0x3) == 0x3) RDMA_WR_BITS(DI_NRWR_CTRL, 0x3, 22, 2); } +static bool cont_en = true; +static bool mtn_en = true; +static unsigned int pre_ctrl; void enable_di_pre_aml( struct DI_MIF_s *di_inp_mif, struct DI_MIF_s *di_mem_mif, @@ -504,93 +639,115 @@ void enable_di_pre_aml( struct DI_SIM_MIF_s *di_contp2rd_mif, struct DI_SIM_MIF_s *di_contprd_mif, struct DI_SIM_MIF_s *di_contwr_mif, - int nr_en, int mtn_en, int pd32_check_en, int pd22_check_en, - int hist_check_en, int pre_field_num, int pre_vdin_link, - int hold_line, int urgent) + unsigned char madi_en, unsigned char pre_field_num, + unsigned char pre_vdin_link) { - int hist_check_only = 0; + bool mem_bypass = false, chan2_disable = false; + unsigned short nrwr_hsize = 0, nrwr_vsize = 0; + unsigned short chan2_hsize = 0, chan2_vsize = 0; + unsigned short mem_hsize = 0, mem_vsize = 0; - pd32_check_en = 1; /* for progressive luma detection */ + set_di_inp_mif(di_inp_mif, pre_urgent, pre_hold_line); + set_di_nrwr_mif(di_nrwr_mif, pre_urgent); + set_di_mem_mif(di_mem_mif, pre_urgent, pre_hold_line); + set_di_chan2_mif(di_chan2_mif, pre_urgent, pre_hold_line); + nrwr_hsize = di_nrwr_mif->end_x - di_nrwr_mif->start_x; + nrwr_vsize = di_nrwr_mif->end_y - di_nrwr_mif->start_y; + chan2_hsize = di_chan2_mif->luma_x_start0 - di_chan2_mif->luma_x_end0; + chan2_vsize = di_chan2_mif->luma_y_start0 - di_chan2_mif->luma_y_end0; + mem_hsize = di_mem_mif->luma_x_start0 - di_mem_mif->luma_x_end0; + mem_vsize = di_mem_mif->luma_y_start0 - di_mem_mif->luma_y_end0; + if ((chan2_hsize < nrwr_hsize) || (chan2_vsize < nrwr_vsize)) + chan2_disable = true; + if ((mem_hsize < nrwr_hsize) || (mem_vsize < nrwr_vsize)) + mem_bypass = true; - hist_check_only = hist_check_en && !nr_en && !mtn_en && - !pd22_check_en && !pd32_check_en; - - if (nr_en | mtn_en | pd22_check_en || pd32_check_en) { - set_di_mem_mif(di_mem_mif, urgent, hold_line); - set_di_inp_mif(di_inp_mif, urgent, hold_line); + if (madi_en) { + /* + * not mask cont wr & mtn wr interrupt + */ + RDMA_WR_BITS(DI_INTR_CTRL, cont_en?0:1, 20, 1); + RDMA_WR_BITS(DI_INTR_CTRL, mtn_en?0:1, 17, 1); + /* + * enable contwr txt + */ + RDMA_WR_BITS(DI_MTN_1_CTRL1, 5, 29, 3); + } else { + /* + * mask cont wr & mtn wr interrupt + */ + RDMA_WR_BITS(DI_INTR_CTRL, 1, 20, 1); + RDMA_WR_BITS(DI_INTR_CTRL, 1, 17, 1); + /* + * disable contwr txt + */ + RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 29, 3); } - if (pd22_check_en || hist_check_only) - set_di_chan2_mif(di_chan2_mif, urgent, hold_line); - /* set nr wr mif interface. */ - if (nr_en) { - RDMA_WR_BITS(DI_NRWR_X, di_nrwr_mif->end_x, 0, 14); - RDMA_WR_BITS(DI_NRWR_X, di_nrwr_mif->start_x, 16, 14); - RDMA_WR_BITS(DI_NRWR_Y, di_nrwr_mif->start_y, 16, 13); - RDMA_WR_BITS(DI_NRWR_Y, di_nrwr_mif->end_y, 0, 13); - RDMA_WR_BITS(DI_NRWR_Y, 3, 30, 2); - RDMA_WR(DI_NRWR_CTRL, di_nrwr_mif->canvas_num| - (urgent<<16)| - 2<<26 |/*burst_lim 1->2 2->4*/ - 1<<30); /* urgent bit 16 */ - } - - pre_bit_mode_config(di_inp_mif->bit_mode, - di_mem_mif->bit_mode, - di_chan2_mif->bit_mode, - di_nrwr_mif->bit_mode); - /* motion wr mif. */ - if (mtn_en) { - RDMA_WR(DI_CONTWR_X, (di_contwr_mif->start_x << 16)| - (di_contwr_mif->end_x)); - RDMA_WR(DI_CONTWR_Y, (di_contwr_mif->start_y << 16)| - (di_contwr_mif->end_y)); - RDMA_WR(DI_CONTWR_CTRL, di_contwr_mif->canvas_num| - (urgent << 8));/* urgent. */ - RDMA_WR(DI_CONTPRD_X, (di_contprd_mif->start_x << 16)| - (di_contprd_mif->end_x)); - RDMA_WR(DI_CONTPRD_Y, (di_contprd_mif->start_y << 16)| - (di_contprd_mif->end_y)); - RDMA_WR(DI_CONTP2RD_X, (di_contp2rd_mif->start_x << 16)| - (di_contp2rd_mif->end_x)); - RDMA_WR(DI_CONTP2RD_Y, (di_contp2rd_mif->start_y << 16)| - (di_contp2rd_mif->end_y)); - RDMA_WR(DI_CONTRD_CTRL, (di_contprd_mif->canvas_num << 8)| - (urgent << 16)|/* urgent */ - di_contp2rd_mif->canvas_num); - /* current field mtn canvas index. */ - RDMA_WR(DI_MTNWR_X, (di_mtnwr_mif->start_x << 16)| - (di_mtnwr_mif->end_x)); - RDMA_WR(DI_MTNWR_Y, (di_mtnwr_mif->start_y << 16)| - (di_mtnwr_mif->end_y)); - RDMA_WR(DI_MTNWR_CTRL, di_mtnwr_mif->canvas_num| - (urgent << 8)); /* urgent. */ - } - - RDMA_WR(DI_PRE_CTRL, nr_en | /* NR enable */ - (mtn_en << 1) | /* MTN_EN */ - (pd32_check_en << 2)|/* check 3:2 pulldown */ - (pd22_check_en << 3)|/* check 2:2 pulldown */ - (1 << 4) | -/* 2:2 check mid pixel come from next field after MTN. */ - (hist_check_en << 5)|/* hist check enable */ - (1 << 6)|/* hist check use chan2. */ - ((!nr_en) << 7)| -/* hist check use data before noise reduction. */ - ((pd22_check_en || hist_check_only) << 8)| + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (madi_en) { + set_ma_pre_mif_g12(di_mtnwr_mif, + di_contp2rd_mif, + di_contprd_mif, + di_contwr_mif, pre_urgent); + } + RDMA_WR_BITS(DI_PRE_CTRL, pre_field_num, 29, 1); + RDMA_WR_BITS(DI_PRE_GL_THD, pre_hold_line, 16, 6); + if (pre_ctrl) + RDMA_WR_BITS(DI_PRE_CTRL, pre_ctrl, 0, 29); + else + RDMA_WR(DI_PRE_CTRL, 1|/* nr wr en */ + (madi_en << 1)|/* mtn en */ + (madi_en << 2)|/* check 3:2 pulldown */ + (madi_en << 3)|/* check 2:2 pulldown */ + (1 << 4) | + (madi_en << 5)|/* hist check enable */ + (madi_en << 6)|/* hist check use chan2. */ + /* hist check use data before noise reduction. */ + ((chan2_disable ? 0 : 1) << 8)| /* chan 2 enable for 2:2 pull down check.*/ - (pd22_check_en << 9) |/* line buffer 2 enable */ + (madi_en << 9) |/* line buffer 2 enable */ + (0 << 10) | /* pre drop first. */ + (0 << 11) | /* di pre repeat */ + (0 << 12) | /* pre viu link */ + (pre_vdin_link << 13) | + (pre_vdin_link << 14) |/* pre go line link */ + (1 << 22) |/* MTN after NR. */ + (madi_en << 25) |/* contrd en */ + (mem_bypass ? 1 : 0) << 28 + ); + } else { + if (madi_en) { + set_ma_pre_mif(di_mtnwr_mif, + di_contp2rd_mif, + di_contprd_mif, + di_contwr_mif, pre_urgent); + } + RDMA_WR(DI_PRE_CTRL, 1 | /* nr enable */ + (madi_en << 1) | /* mtn_en */ + (madi_en << 2)|/* check 3:2 pulldown */ + (madi_en << 3)|/* check 2:2 pulldown */ + (1 << 4) | + (madi_en << 5)|/* hist check enable */ + (1 << 6)|/* hist check use chan2. */ + (0 << 7)| +/* hist check use data before noise reduction. */ + (madi_en << 8)| + /* chan 2 enable for 2:2 pull down check.*/ + (madi_en << 9) |/* line buffer 2 enable */ (0 << 10) | /* pre drop first. */ (0 << 11) | /* di pre repeat */ (0 << 12) | /* pre viu link */ (pre_vdin_link << 13) | (pre_vdin_link << 14) |/* pre go line link */ - (hold_line << 16)|/* pre hold line number */ - (1 << 22)|/* MTN after NR. */ + (pre_hold_line << 16) |/* pre hold line number */ + (1 << 22) |/* MTN after NR. */ + (madi_en << 25) | /* contrd en */ (pre_field_num << 29)/* pre field number.*/ ); - + } } + void enable_afbc_input(struct vframe_s *vf) { unsigned int r, u, v; @@ -645,24 +802,71 @@ void enable_afbc_input(struct vframe_s *vf) /* disable inp memory */ RDMA_WR_BITS(DI_INP_GEN_REG, 0, 0, 1); /* afbc to di enable */ - if (Rd_reg_bits(VIU_MISC_CTRL0, 19, 1) != 1) - RDMA_WR_BITS(VIU_MISC_CTRL0, 1, 19, 1); - /* DI inp(current data) switch to AFBC */ - RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1); + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (Rd_reg_bits(VIU_MISC_CTRL0, 19, 1) != 1) + RDMA_WR_BITS(VIU_MISC_CTRL0, 1, 19, 1); + /* DI inp(current data) switch to AFBC */ + RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1); + } } else { RDMA_WR(AFBC_ENABLE, 0); /* afbc to vpp(replace vd1) enable */ - if (Rd_reg_bits(VIU_MISC_CTRL0, 19, 1) != 0) - RDMA_WR_BITS(VIU_MISC_CTRL0, 0, 19, 1); - /* DI inp(current data) switch to memory */ - RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1); + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (Rd_reg_bits(VIU_MISC_CTRL0, 19, 1) != 0) + RDMA_WR_BITS(VIU_MISC_CTRL0, 0, 19, 1); + /* DI inp(current data) switch to memory */ + RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1); + } } } +void enable_mc_di_pre_g12(struct DI_MC_MIF_s *mcinford_mif, + struct DI_MC_MIF_s *mcinfowr_mif, + struct DI_MC_MIF_s *mcvecwr_mif, + unsigned char mcdi_en) +{ + /* enable int of mcdi */ + RDMA_WR_BITS(DI_INTR_CTRL, mcdi_en?0:7, 21, 3); + + RDMA_WR_BITS(MCDI_MOTINEN, (mcdi_en?3:0), 0, 2); + RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? 0x1bfff7ff : 0)); + RDMA_WR_BITS(DI_PRE_CTRL, (mcdi_en?3:0), 16, 2); + + RDMA_WR_BITS(MCINFRD_SCOPE_X, mcinford_mif->size_x, 16, 13); + RDMA_WR_BITS(MCINFRD_SCOPE_Y, mcinford_mif->size_y, 16, 13); + RDMA_WR_BITS(MCINFRD_CTRL1, mcvecwr_mif->canvas_num, 16, 8); + RDMA_WR_BITS(MCINFRD_CTRL1, 2, 0, 3); + + RDMA_WR_BITS(MCVECWR_X, mcvecwr_mif->size_x, 0, 13); + RDMA_WR_BITS(MCVECWR_Y, mcvecwr_mif->size_y, 0, 13); + RDMA_WR_BITS(MCVECWR_CTRL, mcvecwr_mif->canvas_num, 0, 8); + RDMA_WR_BITS(MCVECWR_CAN_SIZE, mcvecwr_mif->size_y, 0, 13); + RDMA_WR_BITS(MCVECWR_CAN_SIZE, mcvecwr_mif->size_x, 16, 13); + + RDMA_WR_BITS(MCINFWR_X, mcinfowr_mif->size_x, 0, 13); + RDMA_WR_BITS(MCINFWR_Y, mcinfowr_mif->size_y, 0, 13); + RDMA_WR_BITS(MCINFWR_CTRL, mcinfowr_mif->canvas_num, 0, 8); + RDMA_WR_BITS(MCINFWR_CAN_SIZE, mcinfowr_mif->size_y, 0, 13); + RDMA_WR_BITS(MCINFWR_CAN_SIZE, mcinfowr_mif->size_x, 16, 13); +} + void enable_mc_di_pre(struct DI_MC_MIF_s *di_mcinford_mif, struct DI_MC_MIF_s *di_mcinfowr_mif, - struct DI_MC_MIF_s *di_mcvecwr_mif, int urgent) + struct DI_MC_MIF_s *di_mcvecwr_mif, + unsigned char mcdi_en) { + bool me_auto_en = true; + unsigned int ctrl_mode = 0; + + RDMA_WR_BITS(DI_MTN_CTRL1, (mcdi_en?3:0), 12, 2); + if (is_meson_gxlx_cpu() || is_meson_txhd_cpu()) + me_auto_en = false; + ctrl_mode = (me_auto_en ? 0x1bfff7ff : 0x1bfe37ff); + RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? ctrl_mode : 0)); + RDMA_WR_BITS(MCDI_MOTINEN, (mcdi_en?3:0), 0, 2); + /* mask mcve&mcinfo&me interrupt */ + RDMA_WR_BITS(DI_INTR_CTRL, mcdi_en?0:7, 21, 3); + RDMA_WR(MCDI_MCVECWR_X, di_mcvecwr_mif->size_x); RDMA_WR(MCDI_MCVECWR_Y, di_mcvecwr_mif->size_y); RDMA_WR(MCDI_MCINFOWR_X, di_mcinfowr_mif->size_x); @@ -677,25 +881,56 @@ void enable_mc_di_pre(struct DI_MC_MIF_s *di_mcinford_mif, RDMA_WR(MCDI_MCINFORD_CANVAS_SIZE, (di_mcinford_mif->size_x<<16)+di_mcinford_mif->size_y); - /* DI_Wr(MCDI_MOTINEN,1<<1); //enable motin refinement */ - RDMA_WR(MCDI_MCVECWR_CTRL, di_mcvecwr_mif->canvas_num | (0<<14) | /* sync latch en */ - (urgent<<8) | /* urgent */ + (pre_urgent<<8) | /* urgent */ (1<<12) | /* enable reset by frame rst */ (0x4031<<16)); RDMA_WR(MCDI_MCINFOWR_CTRL, di_mcinfowr_mif->canvas_num | (0<<14) | /* sync latch en */ - (urgent<<8) | /* urgent */ + (pre_urgent<<8) | /* urgent */ (1<<12) | /* enable reset by frame rst */ (0x4042<<16)); RDMA_WR(MCDI_MCINFORD_CTRL, di_mcinford_mif->canvas_num | (0<<10) | /* sync latch en */ - (urgent<<8) | /* urgent */ + (pre_urgent<<8) | /* urgent */ (1<<9) | /* enable reset by frame rst */ (0x42<<16)); } +void enable_mc_di_post_g12(struct DI_MC_MIF_s *mcvecrd_mif, + int urgent, bool reverse, int invert_mv) +{ + unsigned int end_x; + + DI_VSYNC_WR_MPEG_REG(MCVECRD_CTRL1, + mcvecrd_mif->canvas_num << 16 | + 2 << 8 | + (reverse?3:0) << 4 | + 2); + end_x = mcvecrd_mif->size_x + mcvecrd_mif->start_x; + DI_VSYNC_WR_MPEG_REG(MCVECRD_SCOPE_X, + mcvecrd_mif->start_x | + end_x << 16); + DI_VSYNC_WR_MPEG_REG(MCVECRD_SCOPE_Y, (reverse?1:0)<<30 | + mcvecrd_mif->start_y | + mcvecrd_mif->end_y << 16); + DI_VSYNC_WR_MPEG_REG_BITS(MCVECRD_CTRL2, urgent, 16, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcvecrd_mif->vecrd_offset, + 12, 3); + if (mcvecrd_mif->blend_en) + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcen_mode, 0, 2); + else + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcuv_en, 10, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + invert_mv, 17, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 3, 18, 2); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcdebug_mode, 2, 3); +} + void enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif, int urgent, bool reverse, int invert_mv) { @@ -841,7 +1076,7 @@ static void set_di_inp_mif(struct DI_MIF_s *mif, int urgent, int hold_line) /* ---------------------- */ /* General register */ /* ---------------------- */ - reset_on_gofield = (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)?0:1; + reset_on_gofield = 0; RDMA_WR(DI_INP_GEN_REG, (reset_on_gofield << 29) | (urgent << 28) |/* chroma urgent bit */ (urgent << 27) |/* luma urgent bit. */ @@ -864,6 +1099,7 @@ static void set_di_inp_mif(struct DI_MIF_s *mif, int urgent, int hold_line) RDMA_WR_BITS(DI_INP_GEN_REG2, 0, 0, 1); } + RDMA_WR_BITS(DI_INP_GEN_REG3, mif->bit_mode&0x3, 8, 2); RDMA_WR(DI_INP_CANVAS0, (mif->canvas0_addr2 << 16) | /* cntl_canvas0_addr2 */ (mif->canvas0_addr1 << 8) | @@ -884,11 +1120,9 @@ static void set_di_inp_mif(struct DI_MIF_s *mif, int urgent, int hold_line) (mif->luma_y_start0 << 0) /* cntl_luma_y_start0 */ ); RDMA_WR(DI_INP_CHROMA_X0, (mif->chroma_x_end0 << 16) | - (mif->chroma_x_start0 << 0) - ); + (mif->chroma_x_start0 << 0)); RDMA_WR(DI_INP_CHROMA_Y0, (mif->chroma_y_end0 << 16) | - (mif->chroma_y_start0 << 0) - ); + (mif->chroma_y_start0 << 0)); /* ---------------------- */ /* Repeat or skip */ @@ -1052,7 +1286,7 @@ static void set_di_mem_mif(struct DI_MIF_s *mif, int urgent, int hold_line) /* ---------------------- */ /* General register */ /* ---------------------- */ - reset_on_gofield = (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)?0:1; + reset_on_gofield = 0; RDMA_WR(DI_MEM_GEN_REG, (reset_on_gofield << 29) | /* reset on go field */ (urgent << 28) | /* urgent bit. */ @@ -1075,6 +1309,7 @@ static void set_di_mem_mif(struct DI_MIF_s *mif, int urgent, int hold_line) } else { RDMA_WR_BITS(DI_MEM_GEN_REG2, 0, 0, 1); } + RDMA_WR_BITS(DI_MEM_GEN_REG3, mif->bit_mode&0x3, 8, 2); /* ---------------------- */ /* Canvas */ /* ---------------------- */ @@ -1488,7 +1723,7 @@ static void set_di_chan2_mif(struct DI_MIF_s *mif, int urgent, int hold_line) /* ---------------------- */ /* General register */ /* ---------------------- */ - reset_on_gofield = (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)?0:1; + reset_on_gofield = 0; RDMA_WR(DI_CHAN2_GEN_REG, (reset_on_gofield << 29) | (urgent << 28) | /* urgent */ (urgent << 27) | /* luma urgent */ @@ -1513,6 +1748,7 @@ static void set_di_chan2_mif(struct DI_MIF_s *mif, int urgent, int hold_line) } else { RDMA_WR_BITS(DI_CHAN2_GEN_REG2, 0, 0, 1); } + RDMA_WR_BITS(DI_CHAN2_GEN_REG3, mif->bit_mode&0x3, 8, 2); RDMA_WR(DI_CHAN2_CANVAS0, (mif->canvas0_addr2 << 16) | (mif->canvas0_addr1 << 8) | (mif->canvas0_addr0 << 0)); @@ -1629,6 +1865,7 @@ static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent, int hold_line, (mif->chroma_y_start0 << 0)); } + /* ---------------------- */ /* Repeat or skip */ /* ---------------------- */ @@ -1668,6 +1905,137 @@ mif->chroma_x_end0 - mif->chroma_x_start0 + 1, /* c length */ } } +static void set_di_if0_fmt_more_g12(int hfmt_en, + int hz_yc_ratio, /* 2bit */ + int hz_ini_phase, /* 4bit */ + int vfmt_en, + int vt_yc_ratio, /* 2bit */ + int vt_ini_phase, /* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ) +{ + int vt_phase_step = (16 >> vt_yc_ratio); + + DI_VSYNC_WR_MPEG_REG(DI_IF0_FMT_CTRL, +(hz_rpt << 28) | /* hz rpt pixel */ +(hz_ini_phase << 24) | /* hz ini phase */ +(0 << 23) | /* repeat p0 enable */ +(hz_yc_ratio << 21) | /* hz yc ratio */ +(hfmt_en << 20) | /* hz enable */ +(1 << 17) | /* nrpt_phase0 enable */ +(0 << 16) | /* repeat l0 enable */ +(0 << 12) | /* skip line num */ +(vt_ini_phase << 8) | /* vt ini phase */ +(vt_phase_step << 1) | /* vt phase step (3.4) */ +(vfmt_en << 0) /* vt enable */ + ); + + DI_VSYNC_WR_MPEG_REG(DI_IF0_FMT_W, + (y_length << 16) | /* hz format width */ + (c_length << 0) /* vt format width */ + ); +} + + +static void set_di_if0_mif_g12(struct DI_MIF_s *mif, int urgent, int hold_line, + int vskip_cnt, int post_write_en) +{ + unsigned int pat, loop = 0; + unsigned int bytes_per_pixel, demux_mode; + + + if (mif->set_separate_en == 1) { + pat = vpat[(vskip_cnt<<1)+1]; + if (mif->src_field_mode == 0) {/* top */ + loop = 0x11; + pat <<= 4; + } + } else { + loop = 0; + pat = vpat[vskip_cnt]; + + bytes_per_pixel = + mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + demux_mode = mif->video_mode; + DI_VSYNC_WR_MPEG_REG(DI_IF0_GEN_REG, +(0 << 29) | /* reset on go field */ +(urgent << 28) | /* urgent */ +(urgent << 27) | /* luma urgent */ +(1 << 25) | /* no dummy data. */ +(hold_line << 19) | /* hold lines */ +(1 << 18) | /* push dummy pixel */ +(demux_mode << 16) | /* demux_mode */ +(bytes_per_pixel << 14) | +(1 << 12) | +(1 << 10) | +(3 << 8) | +(0 << 6) | +((mif->set_separate_en != 0) << 1) | +(1 << 0) /* cntl_enable */ + ); + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF0_CANVAS0, (mif->canvas0_addr2 << 16)| +(mif->canvas0_addr1 << 8)|(mif->canvas0_addr0 << 0)); + if (mif->set_separate_en == 2) { + /* Enable NV12 Display */ + RDMA_WR_BITS(DI_IF0_GEN_REG2, 1, 0, 1); + } else { + RDMA_WR_BITS(DI_IF0_GEN_REG2, 0, 0, 1); + } + + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF0_LUMA_X0, (mif->luma_x_end0 << 16) | +(mif->luma_x_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF0_LUMA_Y0, (mif->luma_y_end0 << 16) | +(mif->luma_y_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA_X0, (mif->chroma_x_end0 << 16) | +(mif->chroma_x_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA_Y0, (mif->chroma_y_end0 << 16) | +(mif->chroma_y_start0 << 0)); + } + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF0_REPEAT_LOOP, + (loop << 24) | + (loop << 16) | + (loop << 8) | + (loop << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF0_LUMA0_RPT_PAT, pat); + DI_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA0_RPT_PAT, pat); + + /* 4:2:0 block mode. */ + if (mif->set_separate_en != 0) { + set_di_if0_fmt_more_g12( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 1, /* vfmt_en */ + 1, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ +mif->luma_x_end0 - mif->luma_x_start0 + 1, /* y_length */ +mif->chroma_x_end0 - mif->chroma_x_start0 + 1, /* c length */ + 0); /* hz repeat. */ + } else { + set_di_if0_fmt_more_g12( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 0, /* vfmt_en */ + 0, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, /* y_length */ + ((mif->luma_x_end0>>1) - (mif->luma_x_start0>>1) + 1), /* c length */ + 0); /* hz repeat */ + } +} + void initial_di_post_2(int hsize_post, int vsize_post, int hold_line, bool post_write_en) { @@ -1692,7 +2060,33 @@ void initial_di_post_2(int hsize_post, int vsize_post, DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_X, (hsize_post-1)); DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_X, (hsize_post-1)); DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_X, (hsize_post-1)); - + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + #if 0 + if (post_write_en) + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0x80000005); + else + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0x00200005); + #endif + if (post_write_en) { + DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, + 0, 8, 9); + DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, + 0, 20, 1); + } else { + DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, + 1, 8, 9); + DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, + 1, 20, 1); + } + } else { + /* enable ma,disable if0 to vpp */ + if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0x50000) { + DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3); + if (post_write_en) + DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, + 1, 28, 1); + } + } DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, (0 << 0) | (0 << 1) | (0 << 2) | @@ -1710,15 +2104,6 @@ void initial_di_post_2(int hsize_post, int vsize_post, (0 << 29) | (0x3 << 30) ); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { - /* enable ma,disable if0 to vpp */ - if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0x50000) { - DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3); - if (post_write_en) - DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, - 1, 28, 1); - } - } } static void post_bit_mode_config(unsigned char if0, @@ -1726,8 +2111,10 @@ static void post_bit_mode_config(unsigned char if0, { if (!cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) return; - - DI_Wr_reg_bits(VD1_IF0_GEN_REG3, if0&0x3, 8, 2); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + DI_Wr_reg_bits(DI_IF0_GEN_REG3, if0&0x3, 8, 2); + else + DI_Wr_reg_bits(VD1_IF0_GEN_REG3, if0&0x3, 8, 2); DI_Wr_reg_bits(DI_IF1_GEN_REG3, if1&0x3, 8, 2); DI_Wr_reg_bits(DI_IF2_GEN_REG3, if2&0x3, 8, 2); DI_Wr_reg_bits(DI_DIWR_Y, post_wr&0x1, 14, 1); @@ -1738,7 +2125,10 @@ static void post_bit_mode_config(unsigned char if0, static unsigned int pldn_ctrl_rflsh = 1; module_param(pldn_ctrl_rflsh, uint, 0644); MODULE_PARM_DESC(pldn_ctrl_rflsh, "/n post blend reflesh./n"); - +static unsigned int post_ctrl; +module_param_named(post_ctrl, post_ctrl, uint, 0644); +static bool vd1_en; +module_param_named(vd1_en, vd1_en, bool, 0644); void di_post_switch_buffer( struct DI_MIF_s *di_buf0_mif, struct DI_MIF_s *di_buf1_mif, @@ -1758,15 +2148,32 @@ void di_post_switch_buffer( ei_only = ei_en && !blend_en && (di_vpp_en || di_ddr_en); buf1_en = (!ei_only && (di_ddr_en || di_vpp_en)); - if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0x50000) - DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3); - if (di_ddr_en) - DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, - 1, 28, 1); - - if (ei_en || di_vpp_en || di_ddr_en) - set_di_if0_mif(di_buf0_mif, urgent, - hold_line, vskip_cnt, di_ddr_en); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + DI_VSYNC_WR_MPEG_REG(DI_IF0_CANVAS0, + (di_buf0_mif->canvas0_addr2 << 16) | + (di_buf0_mif->canvas0_addr1 << 8) | + (di_buf0_mif->canvas0_addr0 << 0)); + if (mc_enable) { + DI_VSYNC_WR_MPEG_REG_BITS(MCVECRD_CTRL1, + di_mcvecrd_mif->canvas_num, 16, 8); + } + } else { + if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0x50000) + DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3); + if (di_ddr_en) + DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, + 1, 28, 1); + if (ei_en || di_vpp_en || di_ddr_en) + set_di_if0_mif(di_buf0_mif, urgent, + hold_line, vskip_cnt, di_ddr_en); + if (mc_enable) { + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, + (1<<9) | /* canvas enable */ + (urgent << 8) | + di_mcvecrd_mif->canvas_num, + 0, 10); + } + } if (!ei_only && (di_ddr_en || di_vpp_en)) { DI_VSYNC_WR_MPEG_REG(DI_IF1_CANVAS0, @@ -1803,19 +2210,11 @@ void di_post_switch_buffer( DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_en, 31, 1); DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3); DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_mode, 20, 2); - if (debug_blend_mode_ctrl != 0xff) - DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, - debug_blend_mode_ctrl&0x3, 20, 2); } else DI_VSYNC_WR_MPEG_REG(DI_BLEND_CTRL, Rd(DI_BLEND_CTRL)| (blend_en<<31) | (blend_mode<<20) | 0x1c0001f); if (mc_enable) { - DI_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_CTRL, - (Rd(MCDI_MCVECRD_CTRL) & 0xffffff00) | - (1<<9) | /* canvas enable */ - di_mcvecrd_mif->canvas_num | /* canvas index. */ - (urgent << 8)); if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, invert_mv, 17, 1);/* invert mv */ @@ -1828,10 +2227,19 @@ void di_post_switch_buffer( DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); } + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_POST_GL_THD, + hold_line, 16, 5); + hold_line = 0; + } + if (!is_meson_txlx_cpu()) invert_mv = 0; - - DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, + DI_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG, vd1_en?1:0, 0, 1); + if (post_ctrl != 0) + DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, post_ctrl | (0x3 << 30)); + else { + DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, ((ei_en|blend_en) << 0) | /* line buf 0 enable */ ((blend_mode == 1?1:0) << 1) | (ei_en << 2) | /* ei enable */ @@ -1849,9 +2257,46 @@ void di_post_switch_buffer( (hold_line << 16) | /* post hold line number */ (post_field_num << 29) | /* post field number. */ (0x3 << 30) /* post soft rst post frame rst. */ - ); + ); + } if (di_ddr_en && mc_enable) DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, 1, 9, 1); + #if 0 + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && di_ddr_en) { + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0xc0200005); + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0x80200005); + } + #endif +} + +static void set_post_mtnrd_mif(struct DI_SIM_MIF_s *mtnprd_mif, + unsigned char urgent) +{ + DI_VSYNC_WR_MPEG_REG(DI_MTNPRD_X, + (mtnprd_mif->start_x << 16) | + (mtnprd_mif->end_x)); + DI_VSYNC_WR_MPEG_REG(DI_MTNPRD_Y, + (mtnprd_mif->start_y << 16) | + (mtnprd_mif->end_y)); + DI_VSYNC_WR_MPEG_REG(DI_MTNRD_CTRL, + (mtnprd_mif->canvas_num << 8) | + (urgent << 16) + ); +} + +static void set_post_mtnrd_mif_g12(struct DI_SIM_MIF_s *mtnprd_mif) +{ + DI_VSYNC_WR_MPEG_REG(MTNRD_SCOPE_X, + (mtnprd_mif->end_x << 16) | + (mtnprd_mif->start_x)); + DI_VSYNC_WR_MPEG_REG(MTNRD_SCOPE_Y, + (mtnprd_mif->end_y << 16) | + (mtnprd_mif->start_y)); + DI_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, + mtnprd_mif->canvas_num, 16, 8); + DI_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, + 0, 0, 3); + } void enable_di_post_2( @@ -1872,34 +2317,25 @@ void enable_di_post_2( ei_only = ei_en && !blend_en && (di_vpp_en || di_ddr_en); buf1_en = (!ei_only && (di_ddr_en || di_vpp_en)); - if (ei_en || di_vpp_en || di_ddr_en) - set_di_if0_mif(di_buf0_mif, di_vpp_en, - hold_line, vskip_cnt, di_ddr_en); - - /* if (!ei_only && (di_ddr_en || di_vpp_en)) */ - set_di_if1_mif(di_buf1_mif, di_vpp_en, hold_line, vskip_cnt); - if (is_meson_txlx_cpu() || - is_meson_gxlx_cpu() || - is_meson_txhd_cpu()) - set_di_if2_mif(di_buf2_mif, - di_vpp_en, hold_line, vskip_cnt); - - /* printk("%s: ei_only %d,buf1_en %d,ei_en %d,di_vpp_en %d, - * di_ddr_en %d,blend_mtn_en %d,blend_mode %d.\n", - * __func__,ei_only,buf1_en,ei_en,di_vpp_en,di_ddr_en, - * blend_mtn_en,blend_mode); - */ - /* motion for current display field. */ - DI_VSYNC_WR_MPEG_REG(DI_MTNPRD_X, -(di_mtnprd_mif->start_x << 16) | (di_mtnprd_mif->end_x)); - DI_VSYNC_WR_MPEG_REG(DI_MTNPRD_Y, -(di_mtnprd_mif->start_y << 16) | (di_mtnprd_mif->end_y)); - if (blend_mtn_en) { - DI_VSYNC_WR_MPEG_REG(DI_MTNRD_CTRL, -(di_mtnprd_mif->canvas_num << 8) | (urgent << 16) - ); /* current field mtn canvas index */ + if (ei_en || di_vpp_en || di_ddr_en) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + set_di_if0_mif_g12(di_buf0_mif, di_vpp_en, + hold_line, vskip_cnt, di_ddr_en); + else + set_di_if0_mif(di_buf0_mif, di_vpp_en, + hold_line, vskip_cnt, di_ddr_en); } + set_di_if1_mif(di_buf1_mif, di_vpp_en, hold_line, vskip_cnt); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { + set_di_if2_mif(di_buf2_mif, + di_vpp_en, hold_line, vskip_cnt); + } + /* motion for current display field. */ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + set_post_mtnrd_mif_g12(di_mtnprd_mif); + else + set_post_mtnrd_mif(di_mtnprd_mif, urgent); if (di_ddr_en) { DI_VSYNC_WR_MPEG_REG(DI_DIWR_X, (di_diwr_mif->start_x << 16) | (di_diwr_mif->end_x)); @@ -1914,6 +2350,10 @@ void enable_di_post_2( di_buf1_mif->bit_mode, di_buf2_mif->bit_mode, di_diwr_mif->bit_mode); + pr_info("%s diwr mif<%u, %u; %u, %u>.\n", + __func__, + di_diwr_mif->start_x, di_diwr_mif->end_x, + di_diwr_mif->start_y, di_diwr_mif->end_y); } DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3); @@ -1921,12 +2361,14 @@ void enable_di_post_2( blend_en&0x1, 31, 1); DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_mode&0x3, 20, 2); - if (debug_blend_mode_ctrl != 0xff) - DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, - debug_blend_mode_ctrl&0x3, 20, 2); if (!is_meson_txlx_cpu()) invert_mv = 0; + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_POST_GL_THD, + hold_line, 16, 5); + hold_line = 0; + } DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, ((ei_en | blend_en) << 0) | /* line buffer 0 enable */ ((blend_mode == 1?1:0) << 1) | @@ -1947,6 +2389,12 @@ void enable_di_post_2( (0x3 << 30) /* post soft rst post frame rst. */ ); + #if 0 + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && di_ddr_en) { + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0xc0200005); + DI_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0x80200005); + } + #endif } void disable_post_deinterlace_2(void) @@ -1956,8 +2404,8 @@ void disable_post_deinterlace_2(void) DI_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, 0x3 << 30); if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) DI_VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG, 0x3 << 30); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { - /* disable ma,enable if0 to vpp,enable afbc to vpp */ + /* disable ma,enable if0 to vpp,enable afbc to vpp */ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0) DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 0, 16, 4); /* DI inp(current data) switch to memory */ @@ -1966,6 +2414,10 @@ void disable_post_deinterlace_2(void) /* DI_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, * Rd(DI_IF1_GEN_REG) & 0xfffffffe); */ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 8, 9); + DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 20, 1); + } } void enable_di_post_mif(enum gate_mode_e mode) @@ -2004,14 +2456,15 @@ void di_hw_disable(bool mc_enable) enable_di_pre_mif(false, mc_enable); DI_Wr(DI_POST_SIZE, (32-1) | ((128-1) << 16)); DI_Wr_reg_bits(DI_IF1_GEN_REG, 0, 0, 1); - if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { DI_Wr_reg_bits(DI_IF2_GEN_REG, 0, 0, 1); - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { /* disable ma,enable if0 to vpp,enable afbc to vpp */ - if (Rd_reg_bits(VIU_MISC_CTRL0, 16, 4) != 0) - DI_Wr_reg_bits(VIU_MISC_CTRL0, 0, 16, 4); - /* DI inp(current data) switch to memory */ - DI_Wr_reg_bits(VIUB_MISC_CTRL0, 0, 16, 1); + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (Rd_reg_bits(VIU_MISC_CTRL0, 16, 4) != 0) + DI_Wr_reg_bits(VIU_MISC_CTRL0, 0, 16, 4); + /* DI inp(current data) switch to memory */ + DI_Wr_reg_bits(VIUB_MISC_CTRL0, 0, 16, 1); + } } } /* @@ -2122,10 +2575,15 @@ void di_post_read_reverse_irq(bool reverse, unsigned char mc_pre_flag, mc_pre_flag = if2_disable?1:mc_pre_flag; if (reverse) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF0_GEN_REG2, 3, 2, 2); + DI_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, 3, 4, 2); + } else { + DI_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0xf, 2, 4); + DI_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0xf, 17, 4); + } DI_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG2, 3, 2, 2); - DI_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0xf, 2, 4); DI_VSYNC_WR_MPEG_REG_BITS(VD2_IF0_GEN_REG2, 0xf, 2, 4); - DI_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0xf, 17, 4); if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) DI_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG2, 3, 2, 2); if (mc_enable) { @@ -2162,10 +2620,15 @@ void di_post_read_reverse_irq(bool reverse, unsigned char mc_pre_flag, mc_pre_flag, 8, 1); } } else { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF0_GEN_REG2, 0, 2, 2); + DI_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, 0, 4, 2); + } else { + DI_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0, 2, 4); + DI_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0, 17, 4); + } DI_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG2, 0, 2, 2); - DI_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0, 2, 4); DI_VSYNC_WR_MPEG_REG_BITS(VD2_IF0_GEN_REG2, 0, 2, 4); - DI_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0, 17, 4); if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) DI_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG2, 0, 2, 2); if (mc_enable) { @@ -2328,57 +2791,98 @@ void di_post_gate_control(bool gate) } } -static bool pre_mif_gate; -void enable_di_pre_mif(bool en, bool mc_enable) +/* + * enable/disable mc pre mif mcinfo&mv + */ +static void mc_pre_mif_ctrl_g12(bool enable) { - if (en) { + unsigned char mif_ctrl = 0; + + mif_ctrl = enable ? 1 : 0; + /* enable mcinfo rd mif */ + RDMA_WR_BITS(DI_PRE_CTRL, mif_ctrl, 10, 1); + /* enable mv wr mif */ + RDMA_WR_BITS(MCVECWR_CTRL, mif_ctrl, 12, 1); + /* enable mcinfo wr mif */ + RDMA_WR_BITS(MCINFWR_CTRL, mif_ctrl, 12, 1); +} + +static void mc_pre_mif_ctrl(bool enable) +{ + if (enable) { + /* gate clk */ + RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 9, 1); + /* gate clk */ + RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 9, 1); + /* mcinfo rd req en =1 */ + RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 1, 9, 1); + /* mv wr req en =1 */ + RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 12, 1); + /* mcinfo wr req en =1 */ + RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 12, 1); + } else { + /* no gate clk */ + RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 9, 1); + /* no gate clk */ + RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 9, 1); + /* mcvec wr req en =0 */ + RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 12, 1); + /* mcinfo wr req en =0 */ + RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 12, 1); + /* mcinfo rd req en = 0 */ + RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 0, 9, 1); + } +} +/* + * enable/disable madi pre mif, mtn&cont + */ +static void ma_pre_mif_ctrl_g12(bool enable) +{ + if (enable) { + /* enable cont wr mif */ + RDMA_WR_BITS(CONTWR_CTRL, cont_en?1:0, 12, 1); + /* enable mtn wr mif */ + RDMA_WR_BITS(MTNWR_CTRL, mtn_en?1:0, 12, 1); + /* enable cont rd mif */ + RDMA_WR_BITS(DI_PRE_CTRL, cont_en?1:0, 25, 1); + } else { + RDMA_WR_BITS(MTNWR_CTRL, 0, 12, 1); + RDMA_WR_BITS(CONTWR_CTRL, 0, 12, 1); + /* disable cont rd */ + RDMA_WR_BITS(DI_PRE_CTRL, 0, 25, 1); + } +} +/* + * use logic enable/disable replace mif + */ +static void ma_pre_mif_ctrl(bool enable) +{ + if (!enable) { + /* mtn wr req en =0 */ + RDMA_WR_BITS(DI_PRE_CTRL, 0, 1, 1); + /* cont wr req en =0 */ + RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 31, 1); + /* disable cont rd */ + RDMA_WR_BITS(DI_PRE_CTRL, 0, 25, 1); + } +} +/* + * enable/disable inp&chan2&mem&nrwr mif + */ +static void di_pre_data_mif_ctrl(bool enable) +{ + if (enable) { /* enable input mif*/ DI_Wr(DI_CHAN2_GEN_REG, Rd(DI_CHAN2_GEN_REG) | 0x1); DI_Wr(DI_MEM_GEN_REG, Rd(DI_MEM_GEN_REG) | 0x1); DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) | 0x1); /* nrwr no clk gate en=0 */ RDMA_WR_BITS(DI_NRWR_CTRL, 0, 24, 1); - if (mc_enable) { - /* gate clk */ - RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 9, 1); - /* gate clk */ - RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 9, 1); - /* mcinfo rd req en =1 */ - RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 1, 9, 1); - /* mv wr req en =1 */ - RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 12, 1); - /* mcinfo wr req en =1 */ - RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 12, 1); - } - /* enable di nr/mtn/mv mif */ - /* RDMA_WR(VPU_WRARB_REQEN_SLV_L1C1, 0x3f); */ } else { - if (pre_mif_gate) - return; /* nrwr no clk gate en=1 */ RDMA_WR_BITS(DI_NRWR_CTRL, 1, 24, 1); /* nr wr req en =0 */ RDMA_WR_BITS(DI_PRE_CTRL, 0, 0, 1); - /* mtn wr req en =0 */ - RDMA_WR_BITS(DI_PRE_CTRL, 0, 1, 1); - /* cont wr req en =0 */ - RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 31, 1); - if (mc_enable) { - /* no gate clk */ - RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 9, 1); - /* no gate clk */ - RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 9, 1); - /* mcvec wr req en =0 */ - RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 12, 1); - /* mcinfo wr req en =0 */ - RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 12, 1); - /* mcinfo rd req en = 0 */ - RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 0, 9, 1); - } - /* disable nr cont mtn mv minfo mif */ - /* RDMA_WR(VPU_WRARB_REQEN_SLV_L1C1, 0x2b); */ - /* disable cont rd */ - DI_Wr(DI_PRE_CTRL, Rd(DI_PRE_CTRL) & ~(1 << 25)); /* disable input mif*/ DI_Wr(DI_CHAN2_GEN_REG, Rd(DI_CHAN2_GEN_REG) & ~0x1); DI_Wr(DI_MEM_GEN_REG, Rd(DI_MEM_GEN_REG) & ~0x1); @@ -2386,6 +2890,23 @@ void enable_di_pre_mif(bool en, bool mc_enable) } } +static bool pre_mif_gate; +void enable_di_pre_mif(bool en, bool mc_enable) +{ + if (pre_mif_gate && !en) + return; + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (mc_enable) + mc_pre_mif_ctrl_g12(en); + ma_pre_mif_ctrl_g12(en); + } else { + if (mc_enable) + mc_pre_mif_ctrl(en); + ma_pre_mif_ctrl(en); + } + di_pre_data_mif_ctrl(en); +} + void combing_pd22_window_config(unsigned int width, unsigned int height) { unsigned short y1 = 39, y2 = height - 41; @@ -2498,7 +3019,14 @@ void di_load_regs(struct di_pq_parm_s *di_pq_ptr) value, Rd(addr) != value?"fail":"success"); } } - +#ifndef DEBUG_SUPPORT +#define DEBUG_SUPPORT +#endif #ifdef DEBUG_SUPPORT module_param_named(pre_mif_gate, pre_mif_gate, bool, 0644); +module_param_named(pre_urgent, pre_urgent, ushort, 0644); +module_param_named(pre_hold_line, pre_urgent, ushort, 0644); +module_param_named(pre_ctrl, pre_ctrl, uint, 0644); +module_param_named(cont_en, cont_en, bool, 0644); +module_param_named(mtn_en, mtn_en, bool, 0644); #endif diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.h b/drivers/amlogic/media/deinterlace/deinterlace_hw.h index 19656a101261..af31d6f96018 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace_hw.h +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.h @@ -97,25 +97,33 @@ void combing_pd22_window_config(unsigned int width, unsigned int height); void di_hw_init(bool pulldown_en, bool mc_enable); void di_hw_uninit(void); void enable_di_pre_aml( - struct DI_MIF_s *di_inp_mif, - struct DI_MIF_s *di_mem_mif, - struct DI_MIF_s *di_chan2_mif, - struct DI_SIM_MIF_s *di_nrwr_mif, - struct DI_SIM_MIF_s *di_mtnwr_mif, + struct DI_MIF_s *di_inp_mif, + struct DI_MIF_s *di_mem_mif, + struct DI_MIF_s *di_chan2_mif, + struct DI_SIM_MIF_s *di_nrwr_mif, + struct DI_SIM_MIF_s *di_mtnwr_mif, struct DI_SIM_MIF_s *di_contp2rd_mif, struct DI_SIM_MIF_s *di_contprd_mif, struct DI_SIM_MIF_s *di_contwr_mif, - int nr_en, int mtn_en, int pd32_check_en, int pd22_check_en, - int hist_check_en, int pre_field_num, int pre_vdin_link, - int hold_line, int urgent); + unsigned char madi_en, unsigned char pre_field_num, + unsigned char pre_vdin_link); void enable_afbc_input(struct vframe_s *vf); void mc_pre_mv_irq(void); void enable_mc_di_pre(struct DI_MC_MIF_s *di_mcinford_mif, struct DI_MC_MIF_s *di_mcinfowr_mif, - struct DI_MC_MIF_s *di_mcvecwr_mif, int urgent); + struct DI_MC_MIF_s *di_mcvecwr_mif, + unsigned char mcdi_en); +void enable_mc_di_pre_g12(struct DI_MC_MIF_s *di_mcinford_mif, + struct DI_MC_MIF_s *di_mcinfowr_mif, + struct DI_MC_MIF_s *di_mcvecwr_mif, + unsigned char mcdi_en); + void enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif, int urgent, bool reverse, int invert_mv); +void enable_mc_di_post_g12(struct DI_MC_MIF_s *di_mcvecrd_mif, + int urgent, bool reverse, int invert_mv); + void disable_post_deinterlace_2(void); void initial_di_post_2(int hsize_post, int vsize_post, int hold_line, bool write_en); @@ -154,7 +162,6 @@ void di_hw_disable(bool mc_enable); void enable_di_pre_mif(bool enable, bool mc_enable); void enable_di_post_mif(enum gate_mode_e mode); void di_hw_uninit(void); -void di_load_regs(struct di_pq_parm_s *di_pq_ptr); void combing_pd22_window_config(unsigned int width, unsigned int height); void calc_lmv_init(void); void calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr); diff --git a/drivers/amlogic/media/deinterlace/di_pps.c b/drivers/amlogic/media/deinterlace/di_pps.c new file mode 100644 index 000000000000..501025a79289 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/di_pps.c @@ -0,0 +1,1319 @@ +/* + * drivers/amlogic/media/deinterlace/di_pps.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. + * + */ + +#include +#include +#include +#include "di_pps.h" +#include "register.h" +#if 0 +/* pps filter coefficients */ +#define COEF_BICUBIC 0 +#define COEF_3POINT_TRIANGLE 1 +#define COEF_4POINT_TRIANGLE 2 +#define COEF_BILINEAR 3 +#define COEF_2POINT_BILINEAR 4 +#define COEF_BICUBIC_SHARP 5 +#define COEF_3POINT_TRIANGLE_SHARP 6 +#define COEF_3POINT_BSPLINE 7 +#define COEF_4POINT_BSPLINE 8 +#define COEF_3D_FILTER 9 +#define COEF_NULL 0xff +#define TOTAL_FILTERS 10 + +#define MAX_NONLINEAR_FACTOR 0x40 + + +const u32 vpp_filter_coefs_bicubic_sharp[] = { + 3, + 33 | 0x8000, + /* 0x01f80090, 0x01f80100, 0xff7f0200, 0xfe7f0300, */ + 0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300, + 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900, + 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff, + 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, + 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd, + 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb, + 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, + 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9, + 0xf84848f8 +}; + +const u32 vpp_filter_coefs_bicubic[] = { + 4, + 33, + 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, + 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900, + 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff, + 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, + 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd, + 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb, + 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, + 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9, + 0xf84848f8 +}; + +const u32 vpp_filter_coefs_bilinear[] = { + 4, + 33, + 0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, + 0x00780800, 0x00760a00, 0x00740c00, 0x00720e00, + 0x00701000, 0x006e1200, 0x006c1400, 0x006a1600, + 0x00681800, 0x00661a00, 0x00641c00, 0x00621e00, + 0x00602000, 0x005e2200, 0x005c2400, 0x005a2600, + 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00, + 0x00503000, 0x004e3200, 0x004c3400, 0x004a3600, + 0x00483800, 0x00463a00, 0x00443c00, 0x00423e00, + 0x00404000 +}; + +const u32 vpp_3d_filter_coefs_bilinear[] = { + 2, + 33, + 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, + 0x78080000, 0x760a0000, 0x740c0000, 0x720e0000, + 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000, + 0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, + 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000, + 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000, + 0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, + 0x48380000, 0x463a0000, 0x443c0000, 0x423e0000, + 0x40400000 +}; + +const u32 vpp_filter_coefs_3point_triangle[] = { + 3, + 33, + 0x40400000, 0x3f400100, 0x3d410200, 0x3c410300, + 0x3a420400, 0x39420500, 0x37430600, 0x36430700, + 0x35430800, 0x33450800, 0x32450900, 0x31450a00, + 0x30450b00, 0x2e460c00, 0x2d460d00, 0x2c470d00, + 0x2b470e00, 0x29480f00, 0x28481000, 0x27481100, + 0x26491100, 0x25491200, 0x24491300, 0x234a1300, + 0x224a1400, 0x214a1500, 0x204a1600, 0x1f4b1600, + 0x1e4b1700, 0x1d4b1800, 0x1c4c1800, 0x1b4c1900, + 0x1a4c1a00 +}; + +/* point_num =4, filt_len =4, group_num = 64, [1 2 1] */ +const u32 vpp_filter_coefs_4point_triangle[] = { + 4, + 33, + 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101, + 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303, + 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505, + 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707, + 0x18382808, 0x18382808, 0x17372909, 0x17372909, + 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b, + 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d, + 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f, + 0x10303010 +}; +/* + *4th order (cubic) b-spline + *filt_cubic point_num =4, filt_len =4, group_num = 64, [1 5 1] + */ +const u32 vpp_filter_coefs_4point_bspline[] = { + 4, + 33, + 0x15561500, 0x14561600, 0x13561700, 0x12561800, + 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00, + 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200, + 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700, + 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01, + 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201, + 0x05473301, 0x05463401, 0x04453601, 0x04433702, + 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02, + 0x033d3d03 +}; +/*3rd order (quadratic) b-spline*/ +/*filt_quadratic, point_num =3, filt_len =3, group_num = 64, [1 6 1] */ +const u32 vpp_filter_coefs_3point_bspline[] = { + 3, + 33, + 0x40400000, 0x3e420000, 0x3c440000, 0x3a460000, + 0x38480000, 0x364a0000, 0x344b0100, 0x334c0100, + 0x314e0100, 0x304f0100, 0x2e500200, 0x2c520200, + 0x2a540200, 0x29540300, 0x27560300, 0x26570300, + 0x24580400, 0x23590400, 0x215a0500, 0x205b0500, + 0x1e5c0600, 0x1d5c0700, 0x1c5d0700, 0x1a5e0800, + 0x195e0900, 0x185e0a00, 0x175f0a00, 0x15600b00, + 0x14600c00, 0x13600d00, 0x12600e00, 0x11600f00, + 0x10601000 +}; +/*filt_triangle, point_num =3, filt_len =2.6, group_num = 64, [1 7 1] */ +const u32 vpp_filter_coefs_3point_triangle_sharp[] = { + 3, + 33, + 0x40400000, 0x3e420000, 0x3d430000, 0x3b450000, + 0x3a460000, 0x38480000, 0x37490000, 0x354b0000, + 0x344c0000, 0x324e0000, 0x314f0000, 0x2f510000, + 0x2e520000, 0x2c540000, 0x2b550000, 0x29570000, + 0x28580000, 0x265a0000, 0x245c0000, 0x235d0000, + 0x215f0000, 0x20600000, 0x1e620000, 0x1d620100, + 0x1b620300, 0x19630400, 0x17630600, 0x15640700, + 0x14640800, 0x12640a00, 0x11640b00, 0x0f650c00, + 0x0d660d00 +}; + +const u32 vpp_filter_coefs_2point_binilear[] = { + 2, + 33, + 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, + 0x78080000, 0x760a0000, 0x740c0000, 0x720e0000, + 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000, + 0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, + 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000, + 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000, + 0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, + 0x48380000, 0x463a0000, 0x443c0000, 0x423e0000, + 0x40400000 +}; + +static const u32 *filter_table[] = { + vpp_filter_coefs_bicubic, + vpp_filter_coefs_3point_triangle, + vpp_filter_coefs_4point_triangle, + vpp_filter_coefs_bilinear, + vpp_filter_coefs_2point_binilear, + vpp_filter_coefs_bicubic_sharp, + vpp_filter_coefs_3point_triangle_sharp, + vpp_filter_coefs_3point_bspline, + vpp_filter_coefs_4point_bspline, + vpp_3d_filter_coefs_bilinear +}; + +static int chroma_filter_table[] = { + COEF_BICUBIC, /* bicubic */ + COEF_3POINT_TRIANGLE, + COEF_4POINT_TRIANGLE, + COEF_4POINT_TRIANGLE, /* bilinear */ + COEF_2POINT_BILINEAR, + COEF_3POINT_TRIANGLE, /* bicubic_sharp */ + COEF_3POINT_TRIANGLE, /* 3point_triangle_sharp */ + COEF_3POINT_TRIANGLE, /* 3point_bspline */ + COEF_4POINT_TRIANGLE, /* 4point_bspline */ + COEF_3D_FILTER /* can not change */ +}; + + +static unsigned int vert_scaler_filter = 0xff; +module_param(vert_scaler_filter, uint, 0664); +MODULE_PARM_DESC(vert_scaler_filter, "vert_scaler_filter"); + +static unsigned int vert_chroma_scaler_filter = 0xff; +module_param(vert_chroma_scaler_filter, uint, 0664); +MODULE_PARM_DESC(vert_chroma_scaler_filter, "vert_chroma_scaler_filter"); + +static unsigned int horz_scaler_filter = 0xff; +module_param(horz_scaler_filter, uint, 0664); +MODULE_PARM_DESC(horz_scaler_filter, "horz_scaler_filter"); + +bool pre_scaler_en = true; +module_param(pre_scaler_en, bool, 0664); +MODULE_PARM_DESC(pre_scaler_en, "pre_scaler_en"); +#endif +unsigned int di_filt_coef0[] = //bicubic +{ + 0x00800000, + 0x007f0100, + 0xff7f0200, + 0xfe7f0300, + 0xfd7e0500, + 0xfc7e0600, + 0xfb7d0800, + 0xfb7c0900, + 0xfa7b0b00, + 0xfa7a0dff, + 0xf9790fff, + 0xf97711ff, + 0xf87613ff, + 0xf87416fe, + 0xf87218fe, + 0xf8701afe, + 0xf76f1dfd, + 0xf76d1ffd, + 0xf76b21fd, + 0xf76824fd, + 0xf76627fc, + 0xf76429fc, + 0xf7612cfc, + 0xf75f2ffb, + 0xf75d31fb, + 0xf75a34fb, + 0xf75837fa, + 0xf7553afa, + 0xf8523cfa, + 0xf8503ff9, + 0xf84d42f9, + 0xf84a45f9, + 0xf84848f8 +}; + +unsigned int di_filt_coef1[] = //2 point bilinear +{ + 0x00800000, + 0x007e0200, + 0x007c0400, + 0x007a0600, + 0x00780800, + 0x00760a00, + 0x00740c00, + 0x00720e00, + 0x00701000, + 0x006e1200, + 0x006c1400, + 0x006a1600, + 0x00681800, + 0x00661a00, + 0x00641c00, + 0x00621e00, + 0x00602000, + 0x005e2200, + 0x005c2400, + 0x005a2600, + 0x00582800, + 0x00562a00, + 0x00542c00, + 0x00522e00, + 0x00503000, + 0x004e3200, + 0x004c3400, + 0x004a3600, + 0x00483800, + 0x00463a00, + 0x00443c00, + 0x00423e00, + 0x00404000 +}; + +unsigned int di_filt_coef2[] = //2 point bilinear, bank_length == 2 +{ + 0x80000000, + 0x7e020000, + 0x7c040000, + 0x7a060000, + 0x78080000, + 0x760a0000, + 0x740c0000, + 0x720e0000, + 0x70100000, + 0x6e120000, + 0x6c140000, + 0x6a160000, + 0x68180000, + 0x661a0000, + 0x641c0000, + 0x621e0000, + 0x60200000, + 0x5e220000, + 0x5c240000, + 0x5a260000, + 0x58280000, + 0x562a0000, + 0x542c0000, + 0x522e0000, + 0x50300000, + 0x4e320000, + 0x4c340000, + 0x4a360000, + 0x48380000, + 0x463a0000, + 0x443c0000, + 0x423e0000, + 0x40400000 +}; + + +#define ZOOM_BITS 20 +#define PHASE_BITS 16 + +static const unsigned char f2v_420_in_pos_luma[F2V_TYPE_MAX] = { +0, 2, 0, 2, 0, 0, 0, 2, 0}; +//static const unsigned char f2v_420_in_pos_chroma[F2V_TYPE_MAX] = { +//1, 5, 1, 5, 2, 2, 1, 5, 2}; +static const unsigned char f2v_420_out_pos[F2V_TYPE_MAX] = { +0, 2, 2, 0, 0, 2, 0, 0, 0}; + +static void f2v_get_vertical_phase(unsigned int zoom_ratio, + enum f2v_vphase_type_e type, + unsigned char bank_length, + struct pps_f2v_vphase_s *vphase) +{ + int offset_in, offset_out; + + /* luma */ + offset_in = f2v_420_in_pos_luma[type] << PHASE_BITS; + offset_out = (f2v_420_out_pos[type] * zoom_ratio) + >> (ZOOM_BITS - PHASE_BITS); + + vphase->rcv_num = bank_length; + if (bank_length == 4 || bank_length == 3) + vphase->rpt_num = 1; + else + vphase->rpt_num = 0; + + if (offset_in > offset_out) { + vphase->rpt_num = vphase->rpt_num + 1; + vphase->phase = + ((4 << PHASE_BITS) + offset_out - offset_in) >> 2; + } else { + while ((offset_in + (4 << PHASE_BITS)) <= offset_out) { + if (vphase->rpt_num == 1) + vphase->rpt_num = 0; + else + vphase->rcv_num++; + offset_in += 4 << PHASE_BITS; + } + vphase->phase = (offset_out - offset_in) >> 2; + } +} +/* + * patch 1: inp scaler 0: di wr scaler + */ +void di_pps_config(unsigned char path, int src_w, int src_h, + int dst_w, int dst_h) +{ + enum f2v_vphase_type_e top_conv_type = F2V_P2P; + enum f2v_vphase_type_e bot_conv_type = F2V_P2P; + struct pps_f2v_vphase_s vphase; + + int i; + int hsc_en = 0, vsc_en = 0; + int prehsc_en = 0, prevsc_en = 0; + int vsc_double_line_mode; + unsigned int p_src_w, p_src_h; + unsigned int vert_phase_step, horz_phase_step; + unsigned char top_rcv_num, bot_rcv_num; + unsigned char top_rpt_num, bot_rpt_num; + unsigned short top_vphase, bot_vphase; + unsigned char is_frame; + int vert_bank_length = 4; + + unsigned int *filt_coef0 = di_filt_coef0; + //unsigned int *filt_coef1 = di_filt_coef1; + unsigned int *filt_coef2 = di_filt_coef2; + + vsc_double_line_mode = 0; + + if (src_h != dst_h) + vsc_en = 1; + if (src_w != dst_w) + hsc_en = 1; + pr_info("[pps] input %d %d output %d %d.\n", + src_w, src_h, dst_w, dst_h); + p_src_w = (prehsc_en ? ((src_w+1) >> 1) : src_w); + p_src_h = prevsc_en ? ((src_h+1) >> 1) : src_h; + + Wr(DI_SC_HOLD_LINE, 0x10); + + if (p_src_w > 2048) { + //force vert bank length = 2 + vert_bank_length = 2; + vsc_double_line_mode = 1; + } + + //write vert filter coefs + Wr(DI_SC_COEF_IDX, 0x0000); + for (i = 0; i < 33; i++) { + if (vert_bank_length == 2) + Wr(DI_SC_COEF, filt_coef2[i]); //bilinear + else + Wr(DI_SC_COEF, filt_coef0[i]); //bicubic + } + + //write horz filter coefs + Wr(DI_SC_COEF_IDX, 0x0100); + for (i = 0; i < 33; i++) + Wr(DI_SC_COEF, filt_coef0[i]); //bicubic + + if (p_src_h > 2048) + vert_phase_step = ((p_src_h << 18) / dst_h) << 2; + else + vert_phase_step = (p_src_h << 20) / dst_h; + if (p_src_w > 2048) + horz_phase_step = ((p_src_w << 18) / dst_w) << 2; + else + horz_phase_step = (p_src_w << 20) / dst_w; + + is_frame = ((top_conv_type == F2V_IT2P) || + (top_conv_type == F2V_IB2P) || + (top_conv_type == F2V_P2P)); + + if (is_frame) { + f2v_get_vertical_phase(vert_phase_step, top_conv_type, + vert_bank_length, &vphase); + top_rcv_num = vphase.rcv_num; + top_rpt_num = vphase.rpt_num; + top_vphase = vphase.phase; + + bot_rcv_num = 0; + bot_rpt_num = 0; + bot_vphase = 0; + } else { + f2v_get_vertical_phase(vert_phase_step, top_conv_type, + vert_bank_length, &vphase); + top_rcv_num = vphase.rcv_num; + top_rpt_num = vphase.rpt_num; + top_vphase = vphase.phase; + + f2v_get_vertical_phase(vert_phase_step, bot_conv_type, + vert_bank_length, &vphase); + bot_rcv_num = vphase.rcv_num; + bot_rpt_num = vphase.rpt_num; + bot_vphase = vphase.phase; + } + vert_phase_step = (vert_phase_step << 4); + horz_phase_step = (horz_phase_step << 4); + + Wr(DI_SC_LINE_IN_LENGTH, src_w); + Wr(DI_SC_PIC_IN_HEIGHT, src_h); + Wr(DI_VSC_REGION12_STARTP, 0); + Wr(DI_VSC_REGION34_STARTP, ((dst_h << 16) | dst_h)); + Wr(DI_VSC_REGION4_ENDP, (dst_h - 1)); + + Wr(DI_VSC_START_PHASE_STEP, vert_phase_step); + Wr(DI_VSC_REGION0_PHASE_SLOPE, 0); + Wr(DI_VSC_REGION1_PHASE_SLOPE, 0); + Wr(DI_VSC_REGION3_PHASE_SLOPE, 0); + Wr(DI_VSC_REGION4_PHASE_SLOPE, 0); + + Wr(DI_VSC_PHASE_CTRL, + ((vsc_double_line_mode << 17) | + (!is_frame) << 16) | + (0 << 15) | + (bot_rpt_num << 13) | + (bot_rcv_num << 8) | + (0 << 7) | + (top_rpt_num << 5) | + (top_rcv_num)); + Wr(DI_VSC_INI_PHASE, (bot_vphase << 16) | top_vphase); + Wr(DI_HSC_REGION12_STARTP, 0); + Wr(DI_HSC_REGION34_STARTP, (dst_w << 16) | dst_w); + Wr(DI_HSC_REGION4_ENDP, dst_w - 1); + + Wr(DI_HSC_START_PHASE_STEP, horz_phase_step); + Wr(DI_HSC_REGION0_PHASE_SLOPE, 0); + Wr(DI_HSC_REGION1_PHASE_SLOPE, 0); + Wr(DI_HSC_REGION3_PHASE_SLOPE, 0); + Wr(DI_HSC_REGION4_PHASE_SLOPE, 0); + + Wr(DI_HSC_PHASE_CTRL, (1 << 21) | + (4 << 16) | 0); + Wr_reg_bits(DI_SC_TOP_CTRL, (path?3:0), 29, 2); + Wr(DI_SC_MISC, + (prevsc_en << 21) | + (prehsc_en << 20) | // prehsc_en + (prevsc_en << 19) | // prevsc_en + (vsc_en << 18) | // vsc_en + (hsc_en << 17) | // hsc_en + (1 << 16) | // sc_top_en + (1 << 15) | // vd1 sc out enable + (0 << 12) | // horz nonlinear 4region enable + (4 << 8) | // horz scaler bank length + (0 << 5) | // vert scaler phase field mode enable + (0 << 4) | // vert nonlinear 4region enable + (vert_bank_length << 0) // vert scaler bank length + ); +} +/* + * 0x374e ~ 0x376d, 20 regs + */ +void dump_pps_reg(unsigned int base_addr) +{ + unsigned int i = 0x374e; + + pr_info("-----dump pps start-----\n"); + for (i = 0x374e; i < 0x376e; i++) { + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), + i, RDMA_RD(i)); + } + pr_info("-----dump pps end-----\n"); +} +#if 0 +static void +vpp_set_filters2(u32 process_3d_type, u32 width_in, + u32 height_in, + u32 wid_out, + u32 hei_out, + const struct vinfo_s *vinfo, + u32 vpp_flags, + struct vpp_frame_par_s *next_frame_par) +{ + u32 screen_width, screen_height; + s32 start, end; + s32 video_top, video_left, temp; + u32 video_width, video_height; + u32 ratio_x = 0; + u32 ratio_y = 0; + u32 tmp_ratio_y = 0; + int temp_width; + int temp_height; + struct vppfilter_mode_s *filter = &next_frame_par->vpp_filter; + u32 wide_mode; + s32 height_shift = 0; + u32 height_after_ratio; + u32 aspect_factor; + s32 ini_vphase; + u32 w_in = width_in; + u32 h_in = height_in; + bool h_crop_enable = false, v_crop_enable = false; + u32 width_out = wid_out; /* vinfo->width; */ + u32 height_out = hei_out; /* vinfo->height; */ + u32 aspect_ratio_out = + (vinfo->aspect_ratio_den << 8) / vinfo->aspect_ratio_num; + bool fill_match = true; + u32 orig_aspect = 0; + u32 screen_aspect = 0; + bool skip_policy_check = true; + + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { + if ((likely(w_in > + (video_source_crop_left + video_source_crop_right))) + && (super_scaler == 0)) { + w_in -= video_source_crop_left; + w_in -= video_source_crop_right; + h_crop_enable = true; + } + + if ((likely(h_in > + (video_source_crop_top + video_source_crop_bottom))) + && (super_scaler == 0)) { + h_in -= video_source_crop_top; + h_in -= video_source_crop_bottom; + v_crop_enable = true; + } + } else { + if (likely(w_in > + (video_source_crop_left + video_source_crop_right))) { + w_in -= video_source_crop_left; + w_in -= video_source_crop_right; + h_crop_enable = true; + } + + if (likely(h_in > + (video_source_crop_top + video_source_crop_bottom))) { + h_in -= video_source_crop_top; + h_in -= video_source_crop_bottom; + v_crop_enable = true; + } + } + +#ifndef TV_3D_FUNCTION_OPEN + next_frame_par->vscale_skip_count = 0; + next_frame_par->hscale_skip_count = 0; +#endif + if (vpp_flags & VPP_FLAG_INTERLACE_IN) + next_frame_par->vscale_skip_count++; + if (vpp_flags & VPP_FLAG_INTERLACE_OUT) + height_shift++; + +RESTART: + + aspect_factor = (vpp_flags & VPP_FLAG_AR_MASK) >> VPP_FLAG_AR_BITS; + wide_mode = vpp_flags & VPP_FLAG_WIDEMODE_MASK; + + /* keep 8 bits resolution for aspect conversion */ + if (wide_mode == VIDEO_WIDEOPTION_4_3) { + if (vpp_flags & VPP_FLAG_PORTRAIT_MODE) + aspect_factor = 0x155; + else + aspect_factor = 0xc0; + wide_mode = VIDEO_WIDEOPTION_NORMAL; + } else if (wide_mode == VIDEO_WIDEOPTION_16_9) { + if (vpp_flags & VPP_FLAG_PORTRAIT_MODE) + aspect_factor = 0x1c7; + else + aspect_factor = 0x90; + wide_mode = VIDEO_WIDEOPTION_NORMAL; + } else if ((wide_mode >= VIDEO_WIDEOPTION_4_3_IGNORE) + && (wide_mode <= VIDEO_WIDEOPTION_4_3_COMBINED)) { + if (aspect_factor != 0xc0) + fill_match = false; + + orig_aspect = aspect_factor; + screen_aspect = 0xc0; + } else if ((wide_mode >= VIDEO_WIDEOPTION_16_9_IGNORE) + && (wide_mode <= VIDEO_WIDEOPTION_16_9_COMBINED)) { + if (aspect_factor != 0x90) + fill_match = false; + + orig_aspect = aspect_factor; + screen_aspect = 0x90; + } + + if ((aspect_factor == 0) + || (wide_mode == VIDEO_WIDEOPTION_FULL_STRETCH) + || (wide_mode == VIDEO_WIDEOPTION_NONLINEAR)) + aspect_factor = 0x100; + else { + aspect_factor = + div_u64((unsigned long long)w_in * height_out * + (aspect_factor << 8), + width_out * h_in * aspect_ratio_out); + } + + if (osd_layer_preblend) + aspect_factor = 0x100; + + height_after_ratio = (h_in * aspect_factor) >> 8; + + /* + *if we have ever set a cropped display area for video layer + * (by checking video_layer_width/video_height), then + * it will override the input width_out/height_out for + * ratio calculations, a.k.a we have a window for video content + */ + if (osd_layer_preblend) { + if ((osd_layer_width == 0) || (osd_layer_height == 0)) { + video_top = 0; + video_left = 0; + video_width = width_out; + video_height = height_out; + + } else { + video_top = osd_layer_top; + video_left = osd_layer_left; + video_width = osd_layer_width; + video_height = osd_layer_height; + } + } else { + if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) && + next_frame_par->supscl_path == sup0_pp_sp1_scpath) { + video_top = (video_layer_top >> next_frame_par-> + supsc1_vert_ratio); + video_height = (video_layer_height >> next_frame_par-> + supsc1_vert_ratio); + video_left = (video_layer_left >> next_frame_par-> + supsc1_hori_ratio); + video_width = (video_layer_width >> next_frame_par-> + supsc1_hori_ratio); + } else { + video_top = video_layer_top; + video_left = video_layer_left; + video_width = video_layer_width; + video_height = video_layer_height; + } + if ((video_top == 0) && (video_left == 0) && (video_width <= 1) + && (video_height <= 1)) { + /* special case to do full screen display */ + video_width = width_out; + video_height = height_out; + } else { + if ((video_layer_width < 16) + && (video_layer_height < 16)) { + /* + *sanity check to move + *video out when the target size is too small + */ + video_width = width_out; + video_height = height_out; + video_left = width_out * 2; + } + video_top += video_layer_global_offset_y; + video_left += video_layer_global_offset_x; + } + } + + /*aspect ratio match */ + if ((wide_mode >= VIDEO_WIDEOPTION_4_3_IGNORE) + && (wide_mode <= VIDEO_WIDEOPTION_16_9_COMBINED) + && orig_aspect) { + if (vinfo->width && vinfo->height) + aspect_ratio_out = (vinfo->height << 8) / vinfo->width; + + if ((video_height << 8) > (video_width * aspect_ratio_out)) { + u32 real_video_height = + (video_width * aspect_ratio_out) >> 8; + + video_top += (video_height - real_video_height) >> 1; + video_height = real_video_height; + } else { + u32 real_video_width = + (video_height << 8) / aspect_ratio_out; + + video_left += (video_width - real_video_width) >> 1; + video_width = real_video_width; + } + + if (!fill_match) { + u32 screen_ratio_x, screen_ratio_y; + + screen_ratio_x = 1 << 18; + screen_ratio_y = (orig_aspect << 18) / screen_aspect; + + switch (wide_mode) { + case VIDEO_WIDEOPTION_4_3_LETTER_BOX: + case VIDEO_WIDEOPTION_16_9_LETTER_BOX: + screen_ratio_x = screen_ratio_y = + max(screen_ratio_x, screen_ratio_y); + break; + case VIDEO_WIDEOPTION_4_3_PAN_SCAN: + case VIDEO_WIDEOPTION_16_9_PAN_SCAN: + screen_ratio_x = screen_ratio_y = + min(screen_ratio_x, screen_ratio_y); + break; + case VIDEO_WIDEOPTION_4_3_COMBINED: + case VIDEO_WIDEOPTION_16_9_COMBINED: + screen_ratio_x = screen_ratio_y = + ((screen_ratio_x + screen_ratio_y) >> 1); + break; + default: + break; + } + + ratio_x = screen_ratio_x * w_in / video_width; + ratio_y = + screen_ratio_y * h_in / orig_aspect * + screen_aspect / video_height; + } else { + screen_width = video_width * vpp_zoom_ratio / 100; + screen_height = video_height * vpp_zoom_ratio / 100; + + ratio_x = (w_in << 18) / screen_width; + ratio_y = (h_in << 18) / screen_height; + } + } else { + screen_width = video_width * vpp_zoom_ratio / 100; + screen_height = video_height * vpp_zoom_ratio / 100; + + ratio_x = (w_in << 18) / screen_width; + if (ratio_x * screen_width < (w_in << 18)) + ratio_x++; + + ratio_y = (height_after_ratio << 18) / screen_height; + if (super_debug) + pr_info("height_after_ratio=%d,%d,%d,%d,%d\n", + height_after_ratio, ratio_x, ratio_y, + aspect_factor, wide_mode); + + if (wide_mode == VIDEO_WIDEOPTION_NORMAL) { + ratio_x = ratio_y = max(ratio_x, ratio_y); + ratio_y = (ratio_y << 8) / aspect_factor; + } else if (wide_mode == VIDEO_WIDEOPTION_NORMAL_NOSCALEUP) { + u32 r1, r2; + + r1 = max(ratio_x, ratio_y); + r2 = (r1 << 8) / aspect_factor; + + if ((r1 < (1 << 18)) || (r2 < (1 << 18))) { + if (r1 < r2) { + ratio_x = 1 << 18; + ratio_y = + (ratio_x << 8) / aspect_factor; + } else { + ratio_y = 1 << 18; + ratio_x = aspect_factor << 10; + } + } else { + ratio_x = r1; + ratio_y = r2; + } + } + } + +#if 0 + debug_video_left = video_left; + debug_video_top = video_top; + debug_video_width = video_width; + debug_video_height = video_height; + debug_ratio_x = ratio_x; + debug_ratio_y = ratio_y; + debug_wide_mode = wide_mode; +#endif + + /* vertical */ + ini_vphase = vpp_zoom_center_y & 0xff; + + next_frame_par->VPP_pic_in_height_ = + h_in / (next_frame_par->vscale_skip_count + 1); + + /* screen position for source */ +#ifdef TV_REVERSE + start = + video_top + (video_height + 1) / 2 - ((h_in << 17) + + (vpp_zoom_center_y << 10) + + (ratio_y >> 1)) / ratio_y; + end = ((h_in << 18) + (ratio_y >> 1)) / ratio_y + start - 1; + if (super_debug) + pr_info("top:start =%d,%d,%d,%d %d,%d,%d\n", + start, end, video_top, + video_height, h_in, ratio_y, vpp_zoom_center_y); +#else + start = + video_top + video_height / 2 - ((h_in << 17) + + (vpp_zoom_center_y << 10)) / ratio_y; + end = (h_in << 18) / ratio_y + start - 1; + if (super_debug) + pr_info("top:start =%d,%d,%d,%d %d,%d,%d\n", + start, end, video_top, + video_height, h_in, ratio_y, vpp_zoom_center_y); +#endif + +#ifdef TV_REVERSE + if (reverse) { + /* calculate source vertical clip */ + if (video_top < 0) { + if (start < 0) { + temp = (-start * ratio_y) >> 18; + next_frame_par->VPP_vd_end_lines_ = + h_in - 1 - temp; + + } else + next_frame_par->VPP_vd_end_lines_ = h_in - 1; + + } else { + if (start < video_top) { + temp = ((video_top - start) * ratio_y) >> 18; + next_frame_par->VPP_vd_end_lines_ = + h_in - 1 - temp; + } else + next_frame_par->VPP_vd_end_lines_ = h_in - 1; + } + temp = + next_frame_par->VPP_vd_end_lines_ - + (video_height * ratio_y >> 18); + next_frame_par->VPP_vd_start_lines_ = (temp >= 0) ? temp : 0; + } else +#endif + { + if (video_top < 0) { + if (start < 0) { + temp = (-start * ratio_y) >> 18; + next_frame_par->VPP_vd_start_lines_ = temp; + + } else + next_frame_par->VPP_vd_start_lines_ = 0; + temp_height = min((video_top + video_height - 1), + (vinfo->height - 1)); + } else { + if (start < video_top) { + temp = ((video_top - start) * ratio_y) >> 18; + next_frame_par->VPP_vd_start_lines_ = temp; + + } else + next_frame_par->VPP_vd_start_lines_ = 0; + temp_height = min((video_top + video_height - 1), + (vinfo->height - 1)) - video_top + 1; + } + + temp = + next_frame_par->VPP_vd_start_lines_ + + (temp_height * ratio_y >> 18); + next_frame_par->VPP_vd_end_lines_ = + (temp <= (h_in - 1)) ? temp : (h_in - 1); + } + + if (v_crop_enable) { + next_frame_par->VPP_vd_start_lines_ += video_source_crop_top; + next_frame_par->VPP_vd_end_lines_ += video_source_crop_top; + } + + if (vpp_flags & VPP_FLAG_INTERLACE_IN) + next_frame_par->VPP_vd_start_lines_ &= ~1; + + /* + *find overlapped region between + *[start, end], [0, height_out-1], + *[video_top, video_top+video_height-1] + */ + start = max(start, max(0, video_top)); + end = min(end, min((s32)(vinfo->height - 1), + (s32)(video_top + video_height - 1))); + + if (start >= end) { + /* nothing to display */ + next_frame_par->VPP_vsc_startp = 0; + + next_frame_par->VPP_vsc_endp = 0; + + } else { + next_frame_par->VPP_vsc_startp = + (vpp_flags & VPP_FLAG_INTERLACE_OUT) ? (start >> 1) : start; + + next_frame_par->VPP_vsc_endp = + (vpp_flags & VPP_FLAG_INTERLACE_OUT) ? (end >> 1) : end; + } + + /* set filter co-efficients */ + tmp_ratio_y = ratio_y; + ratio_y <<= height_shift; + ratio_y = ratio_y / (next_frame_par->vscale_skip_count + 1); + + filter->vpp_vsc_start_phase_step = ratio_y << 6; + + f2v_get_vertical_phase(ratio_y, ini_vphase, + next_frame_par->VPP_vf_ini_phase_, + vpp_flags & VPP_FLAG_INTERLACE_OUT); + + /* horizontal */ + filter->vpp_hf_start_phase_slope = 0; + filter->vpp_hf_end_phase_slope = 0; + filter->vpp_hf_start_phase_step = ratio_x << 6; + + next_frame_par->VPP_hsc_linear_startp = next_frame_par->VPP_hsc_startp; + next_frame_par->VPP_hsc_linear_endp = next_frame_par->VPP_hsc_endp; + + filter->vpp_hsc_start_phase_step = ratio_x << 6; + next_frame_par->VPP_hf_ini_phase_ = vpp_zoom_center_x & 0xff; + + /* screen position for source */ +#ifdef TV_REVERSE + start = + video_left + (video_width + 1) / 2 - ((w_in << 17) + + (vpp_zoom_center_x << 10) + + (ratio_x >> 1)) / ratio_x; + end = ((w_in << 18) + (ratio_x >> 1)) / ratio_x + start - 1; + if (super_debug) + pr_info("left:start =%d,%d,%d,%d %d,%d,%d\n", + start, end, video_left, + video_width, w_in, ratio_x, vpp_zoom_center_x); +#else + start = + video_left + video_width / 2 - ((w_in << 17) + + (vpp_zoom_center_x << 10)) / + ratio_x; + end = (w_in << 18) / ratio_x + start - 1; + if (super_debug) + pr_info("left:start =%d,%d,%d,%d %d,%d,%d\n", + start, end, video_left, + video_width, w_in, ratio_x, vpp_zoom_center_x); +#endif + /* calculate source horizontal clip */ +#ifdef TV_REVERSE + if (reverse) { + if (video_left < 0) { + if (start < 0) { + temp = (-start * ratio_x) >> 18; + next_frame_par->VPP_hd_end_lines_ = + w_in - 1 - temp; + } else + next_frame_par->VPP_hd_end_lines_ = w_in - 1; + } else { + if (start < video_left) { + temp = ((video_left - start) * ratio_x) >> 18; + next_frame_par->VPP_hd_end_lines_ = + w_in - 1 - temp; + } else + next_frame_par->VPP_hd_end_lines_ = w_in - 1; + } + temp = next_frame_par->VPP_hd_end_lines_ - + (video_width * ratio_x >> 18); + next_frame_par->VPP_hd_start_lines_ = (temp >= 0) ? temp : 0; + } else +#endif + { + if (video_left < 0) { + if (start < 0) { + temp = (-start * ratio_x) >> 18; + next_frame_par->VPP_hd_start_lines_ = temp; + + } else + next_frame_par->VPP_hd_start_lines_ = 0; + temp_width = min((video_left + video_width - 1), + (vinfo->width - 1)); + } else { + if (start < video_left) { + temp = ((video_left - start) * ratio_x) >> 18; + next_frame_par->VPP_hd_start_lines_ = temp; + + } else + next_frame_par->VPP_hd_start_lines_ = 0; + temp_width = min((video_left + video_width - 1), + (vinfo->width - 1)) - video_left + 1; + } + temp = + next_frame_par->VPP_hd_start_lines_ + + (temp_width * ratio_x >> 18); + next_frame_par->VPP_hd_end_lines_ = + (temp <= (w_in - 1)) ? temp : (w_in - 1); + } + + if (h_crop_enable) { + next_frame_par->VPP_hd_start_lines_ += video_source_crop_left; + next_frame_par->VPP_hd_end_lines_ += video_source_crop_left; + } + + next_frame_par->VPP_line_in_length_ = + next_frame_par->VPP_hd_end_lines_ - + next_frame_par->VPP_hd_start_lines_ + 1; + /* + *find overlapped region between + * [start, end], [0, width_out-1], + * [video_left, video_left+video_width-1] + */ + start = max(start, max(0, video_left)); + end = min(end, + min((s32)(vinfo->width - 1), + (s32)(video_left + video_width - 1))); + + if (start >= end) { + /* nothing to display */ + next_frame_par->VPP_hsc_startp = 0; + next_frame_par->VPP_hsc_endp = 0; + /* avoid mif set wrong or di out size overflow */ + next_frame_par->VPP_hd_start_lines_ = 0; + next_frame_par->VPP_hd_end_lines_ = 0; + } else { + next_frame_par->VPP_hsc_startp = start; + + next_frame_par->VPP_hsc_endp = end; + } + + if ((wide_mode == VIDEO_WIDEOPTION_NONLINEAR) && (end > start)) { + calculate_non_linear_ratio(ratio_x, end - start, + next_frame_par); + + next_frame_par->VPP_hsc_linear_startp = + next_frame_par->VPP_hsc_linear_endp = (start + end) / 2; + } + + } + + if ((vf->type & VIDTYPE_COMPRESS) && + (vf->canvas0Addr != 0) && + (next_frame_par->vscale_skip_count > 1) && + (!next_frame_par->nocomp)) { + pr_info("Try DW buffer for compressed frame scaling.\n"); + + /* for VIDTYPE_COMPRESS, check if we can use double write + * buffer when primary frame can not be scaled. + */ + next_frame_par->nocomp = true; + w_in = width_in = vf->width; + h_in = height_in = vf->height; + next_frame_par->hscale_skip_count = 0; + next_frame_par->vscale_skip_count = 0; + + goto RESTART; + } + + if ((skip_policy & 0xf0) && (skip_policy_check == true)) { + skip_policy_check = false; + if (skip_policy & 0x40) { + next_frame_par->vscale_skip_count = skip_policy & 0xf; + goto RESTART; + } else if (skip_policy & 0x80) { + if ((((vf->width >= 4096) && + (!(vf->type & VIDTYPE_COMPRESS))) || + (vf->flag & VFRAME_FLAG_HIGH_BANDWIDTH)) + && (next_frame_par->vscale_skip_count == 0)) { + next_frame_par->vscale_skip_count = + skip_policy & 0xf; + goto RESTART; + } + } + } + + filter->vpp_hsc_start_phase_step = ratio_x << 6; + + /* coeff selection before skip and apply pre_scaler */ + filter->vpp_vert_filter = + coeff(vert_coeff_settings, + filter->vpp_vsc_start_phase_step * + (next_frame_par->vscale_skip_count + 1), + 1, + ((vf->type_original & VIDTYPE_TYPEMASK) + != VIDTYPE_PROGRESSIVE), + vf->combing_cur_lev); + filter->vpp_vert_coeff = + filter_table[filter->vpp_vert_filter]; + + /* when local interlace or AV or ATV */ + /* TODO: add 420 check for local */ + if (vert_chroma_filter_force_en || (vert_chroma_filter_en + && (((vf->source_type == VFRAME_SOURCE_TYPE_OTHERS) + && (((vf->type_original & VIDTYPE_TYPEMASK) != VIDTYPE_PROGRESSIVE) || + (vf->height < vert_chroma_filter_limit))) + || (vf->source_type == VFRAME_SOURCE_TYPE_CVBS) + || (vf->source_type == VFRAME_SOURCE_TYPE_TUNER)))) { + cur_vert_chroma_filter + = chroma_filter_table[filter->vpp_vert_filter]; + filter->vpp_vert_chroma_coeff + = filter_table[cur_vert_chroma_filter]; + filter->vpp_vert_chroma_filter_en = true; + } else { + cur_vert_chroma_filter = COEF_NULL; + filter->vpp_vert_chroma_filter_en = false; + } + /* avoid hscaler fitler adjustion affect on picture shift*/ + filter->vpp_horz_filter = + coeff(horz_coeff_settings, + filter->vpp_hf_start_phase_step, + next_frame_par->VPP_hf_ini_phase_, + ((vf->type_original & VIDTYPE_TYPEMASK) + != VIDTYPE_PROGRESSIVE), + vf->combing_cur_lev); + /*for gxl cvbs out index*/ + if ((vinfo->mode == VMODE_CVBS) && //DEBUG_TMP + (filter->vpp_hf_start_phase_step == (1 << 24))) + filter->vpp_horz_filter = COEF_BICUBIC_SHARP; + filter->vpp_horz_coeff = + filter_table[filter->vpp_horz_filter]; + + /* apply line skip */ + if (next_frame_par->hscale_skip_count) { + filter->vpp_hf_start_phase_step >>= 1; + filter->vpp_hsc_start_phase_step >>= 1; + next_frame_par->VPP_line_in_length_ >>= 1; + } + + /*pre hsc&vsc in pps for scaler down*/ + if ((filter->vpp_hf_start_phase_step >= 0x2000000) && + (filter->vpp_vsc_start_phase_step >= 0x2000000) && + (get_cpu_type() != MESON_CPU_MAJOR_ID_GXBB) && + pre_scaler_en) { + filter->vpp_pre_vsc_en = 1; + filter->vpp_vsc_start_phase_step >>= 1; + ratio_y >>= 1; + f2v_get_vertical_phase(ratio_y, ini_vphase, + next_frame_par->VPP_vf_ini_phase_, + vpp_flags & VPP_FLAG_INTERLACE_OUT); + + } else + filter->vpp_pre_vsc_en = 0; + + if ((filter->vpp_hf_start_phase_step >= 0x2000000) && + (get_cpu_type() != MESON_CPU_MAJOR_ID_GXBB) && + pre_scaler_en) { + filter->vpp_pre_hsc_en = 1; + filter->vpp_hf_start_phase_step >>= 1; + filter->vpp_hsc_start_phase_step >>= 1; + } else + filter->vpp_pre_hsc_en = 0; + + next_frame_par->VPP_hf_ini_phase_ = vpp_zoom_center_x & 0xff; + + /* overwrite filter setting for interlace output*/ + /* TODO: not reasonable when 4K input to 480i output */ + if (vpp_flags & VPP_FLAG_INTERLACE_OUT) { + filter->vpp_vert_coeff = filter_table[COEF_BILINEAR]; + filter->vpp_vert_filter = COEF_BILINEAR; + } + + /* force overwrite filter setting */ + if ((vert_scaler_filter >= COEF_BICUBIC) && + (vert_scaler_filter <= COEF_3D_FILTER)) { + filter->vpp_vert_coeff = filter_table[vert_scaler_filter]; + filter->vpp_vert_filter = vert_scaler_filter; + } + if (vert_chroma_filter_force_en && + (vert_chroma_scaler_filter >= COEF_BICUBIC) && + (vert_chroma_scaler_filter <= COEF_3D_FILTER)) { + cur_vert_chroma_filter = vert_chroma_scaler_filter; + filter->vpp_vert_chroma_coeff + = filter_table[cur_vert_chroma_filter]; + filter->vpp_vert_chroma_filter_en = true; + } else { + cur_vert_chroma_filter = COEF_NULL; + filter->vpp_vert_chroma_filter_en = false; + } + + if ((horz_scaler_filter >= COEF_BICUBIC) && + (horz_scaler_filter <= COEF_3D_FILTER)) { + filter->vpp_horz_coeff = filter_table[horz_scaler_filter]; + filter->vpp_horz_filter = horz_scaler_filter; + } + +#ifdef TV_3D_FUNCTION_OPEN + /* final stage for 3D filter overwrite */ + if ((next_frame_par->vpp_3d_scale) && force_filter_mode) { + filter->vpp_vert_coeff = filter_table[COEF_3D_FILTER]; + filter->vpp_vert_filter = COEF_3D_FILTER; + } +#endif + if ((last_vert_filter != filter->vpp_vert_filter) || + (last_horz_filter != filter->vpp_horz_filter)) { + last_vert_filter = filter->vpp_vert_filter; + last_horz_filter = filter->vpp_horz_filter; + scaler_filter_cnt = 0; + } else { + scaler_filter_cnt++; + } + if ((scaler_filter_cnt >= scaler_filter_cnt_limit) && + ((cur_vert_filter != filter->vpp_vert_filter) || + (cur_horz_filter != filter->vpp_horz_filter))) { + video_property_notify(1); + cur_vert_filter = filter->vpp_vert_filter; + cur_horz_filter = filter->vpp_horz_filter; + scaler_filter_cnt = scaler_filter_cnt_limit; + } + cur_skip_line = next_frame_par->vscale_skip_count; + +#if HAS_VPU_PROT + if (has_vpu_prot()) { + if (get_prot_status()) { + s32 tmp_height = + (((s32) next_frame_par->VPP_vd_end_lines_ + + 1) << 18) / tmp_ratio_y; + s32 tmp_top = 0; + s32 tmp_bottom = 0; + +/* pr_info("height_out %d video_height %d\n", height_out, video_height); */ +/* pr_info("vf1 %d %d %d %d vs %d %d\n", next_frame_par->VPP_hd_start_lines_,*/ +/* next_frame_par->VPP_hd_end_lines_, */ +/* next_frame_par->VPP_vd_start_lines_, next_frame_par->VPP_vd_end_lines_, */ +/* next_frame_par->hscale_skip_count, next_frame_par->vscale_skip_count); */ + if ((s32) video_height > tmp_height) { + tmp_top = (s32) video_top + + (((s32) video_height - tmp_height) >> 1); + } else + tmp_top = (s32) video_top; + tmp_bottom = tmp_top + + (((s32) next_frame_par->VPP_vd_end_lines_ + 1) << 18) / + (s32) tmp_ratio_y; + if (tmp_bottom > (s32) height_out + && tmp_top < (s32) height_out) { + s32 tmp_end = + (s32) next_frame_par->VPP_vd_end_lines_ - + ((tmp_bottom - + (s32) height_out) * + (s32) tmp_ratio_y >> 18); + if (tmp_end < + (s32) next_frame_par->VPP_vd_end_lines_) { + next_frame_par->VPP_vd_end_lines_ = + tmp_end; + } + + } else if (tmp_bottom > (s32) height_out + && tmp_top >= (s32) height_out) + next_frame_par->VPP_vd_end_lines_ = 1; + next_frame_par->VPP_vd_end_lines_ = + next_frame_par->VPP_vd_end_lines_ - + h_in / height_out; + if ((s32) next_frame_par->VPP_vd_end_lines_ < + (s32) next_frame_par->VPP_vd_start_lines_) { + next_frame_par->VPP_vd_end_lines_ = + next_frame_par->VPP_vd_start_lines_; + } + if ((s32) next_frame_par->VPP_hd_end_lines_ < + (s32) next_frame_par->VPP_hd_start_lines_) { + next_frame_par->VPP_hd_end_lines_ = + next_frame_par->VPP_hd_start_lines_; + } +/* pr_info("tmp_top %d tmp_bottom %d tmp_height %d\n",*/ +/* tmp_top, tmp_bottom, tmp_height); */ +/* pr_info("vf2 %d %d %d %d\n", next_frame_par->VPP_hd_start_lines_,*/ +/* next_frame_par->VPP_hd_end_lines_, */ +/* next_frame_par->VPP_vd_start_lines_, next_frame_par->VPP_vd_end_lines_); */ + } + } +#endif +} +#endif + diff --git a/drivers/amlogic/media/deinterlace/di_pps.h b/drivers/amlogic/media/deinterlace/di_pps.h new file mode 100644 index 000000000000..b78a020bd4fb --- /dev/null +++ b/drivers/amlogic/media/deinterlace/di_pps.h @@ -0,0 +1,101 @@ +/* + * drivers/amlogic/media/deinterlace/di_pps.h + * + * 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. + * + */ + +#ifndef DI_PPS_H +#define DI_PPS_H +#include +#if 0 +#define VPP_FLAG_WIDEMODE_MASK 0x0000000F +#define VPP_FLAG_INTERLACE_OUT 0x00000010 +#define VPP_FLAG_INTERLACE_IN 0x00000020 +#define VPP_FLAG_CBCR_SEPARATE 0x00000040 +#define VPP_FLAG_ZOOM_SHORTSIDE 0x00000080 +#define VPP_FLAG_AR_MASK 0x0003ff00 +#define VPP_FLAG_AR_BITS 8 +#define VPP_FLAG_PORTRAIT_MODE 0x00040000 +#define VPP_FLAG_VSCALE_DISABLE 0x00080000 + +#define IDX_H (2 << 8) +#define IDX_V_Y (1 << 13) +#define IDX_V_CBCR ((1 << 13) | (1 << 8)) + +#define ASPECT_4_3 ((3<<8)/4) +#define ASPECT_16_9 ((9<<8)/16) + +#define SPEED_CHECK_DONE 0 +#define SPEED_CHECK_HSKIP 1 +#define SPEED_CHECK_VSKIP 2 + +enum f2v_vphase_type_e { + F2V_IT2IT = 0, + F2V_IB2IB, + F2V_IT2IB, + F2V_IB2IT, + F2V_P2IT, + F2V_P2IB, + F2V_IT2P, + F2V_IB2P, + F2V_P2P, + F2V_TYPE_MAX +}; /* frame to video conversion type */ +#endif +struct pps_f2v_vphase_s { + unsigned char rcv_num; + unsigned char rpt_num; + unsigned short phase; +}; +struct ppsfilter_mode_s { + u32 pps_hf_start_phase_step; + u32 pps_hf_start_phase_slope; + u32 pps_hf_end_phase_slope; + const u32 *pps_vert_coeff; + const u32 *pps_horz_coeff; + u32 pps_sc_misc_; + u32 pps_vsc_start_phase_step; + u32 pps_hsc_start_phase_step; + bool pps_pre_vsc_en; + bool pps_pre_hsc_en; + u32 pps_vert_filter; + u32 pps_horz_filter; + const u32 *pps_chroma_coeff; + u32 pps_chroma_filter_en; +}; + +struct pps_frame_par_s { + u32 pps_vsc_startp; + u32 pps_vsc_endp; + u32 pps_hsc_startp; + u32 pps_hsc_linear_startp; + u32 pps_hsc_linear_endp; + u32 pps_hsc_endp; + u32 VPP_hf_ini_phase_; + struct f2v_vphase_s VPP_vf_ini_phase_[9]; + u32 pps_pic_in_height_; + u32 pps_line_in_length_; + struct ppsfilter_mode_s pps_filter; + u32 pps_3d_mode; + u32 trans_fmt; + /* bit[1:0] 0: 1 pic,1:two pic one buf,2:tow pic two buf */ + /* bit[2]0:select pic0,1:select pic1 */ + /* bit[3]0:pic0 first,1:pic1 first */ + bool pps_3d_scale; +}; + +void di_pps_config(unsigned char path, int src_w, int src_h, + int dst_w, int dst_h); +void dump_pps_reg(unsigned int base_addr); +#endif diff --git a/drivers/amlogic/media/deinterlace/nr_downscale.c b/drivers/amlogic/media/deinterlace/nr_downscale.c new file mode 100644 index 000000000000..adb0b28e8b65 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/nr_downscale.c @@ -0,0 +1,187 @@ +/* + * drivers/amlogic/media/deinterlace/nr_downscale.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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "register.h" +#include "nr_downscale.h" + +static struct nr_ds_s nrds_dev; + +static void nr_ds_hw_init(unsigned int width, unsigned int height) +{ + unsigned char h_step = 0, v_step = 0; + unsigned int width_out, height_out; + + width_out = NR_DS_WIDTH; + height_out = NR_DS_HEIGHT; + + h_step = width/width_out; + v_step = height/height_out; + + RDMA_WR_BITS(VIUB_MISC_CTRL0, 3, 5, 2); //Switch MIF to NR_DS + RDMA_WR_BITS(NR_DS_BUF_SIZE_REG, width_out, 0, 8); // config dsbuf_ocol + RDMA_WR_BITS(NR_DS_BUF_SIZE_REG, height_out, 0, 8); // config dsbuf_orow + + RDMA_WR_BITS(NRDSWR_X, (width_out-1), 0, 13); + RDMA_WR_BITS(NRDSWR_Y, (height_out-1), 0, 13); + + RDMA_WR_BITS(NRDSWR_CAN_SIZE, (height_out-1), 0, 13); + RDMA_WR_BITS(NRDSWR_CAN_SIZE, (width_out-1), 16, 13); + + RDMA_WR_BITS(NR_DS_CTRL, v_step, 16, 6); + RDMA_WR_BITS(NR_DS_CTRL, h_step, 24, 6); +} + +/* + * init nr ds buffer + */ +void nr_ds_buf_init(unsigned int cma_flag, unsigned long mem_start, + struct device *dev) +{ + unsigned int i = 0; + + if (cma_flag == 0) { + nrds_dev.nrds_addr = mem_start; + } else { + nrds_dev.nrds_pages = dma_alloc_from_contiguous(dev, + NR_DS_PAGE_NUM, 0); + if (nrds_dev.nrds_pages) + nrds_dev.nrds_addr = page_to_phys(nrds_dev.nrds_pages); + else + pr_err("DI: alloc nr ds mem error.\n"); + } + for (i = 0; i < NR_DS_BUF_NUM; i++) + nrds_dev.buf[i] = nrds_dev.nrds_addr + (NR_DS_BUF_SIZE*i); + nrds_dev.cur_buf_idx = 0; + +} + +void nr_ds_buf_uninit(unsigned int cma_flag, struct device *dev) +{ + unsigned int i = 0; + + if (cma_flag == 0) { + nrds_dev.nrds_addr = 0; + } else { + if (nrds_dev.nrds_pages) { + dma_release_from_contiguous(dev, + nrds_dev.nrds_pages, + NR_DS_PAGE_NUM); + nrds_dev.nrds_addr = 0; + nrds_dev.nrds_pages = NULL; + } else + pr_err("DI: release nr ds mem error.\n"); + } + for (i = 0; i < NR_DS_BUF_NUM; i++) + nrds_dev.buf[i] = 0; + nrds_dev.cur_buf_idx = 0; +} +/* + * hw config, alloc canvas + */ +void nr_ds_init(unsigned int width, unsigned int height) +{ + nr_ds_hw_init(width, height); + nrds_dev.field_num = 0; + + if (nrds_dev.canvas_idx != 0) + return; + + if (canvas_pool_alloc_canvas_table("nr_ds", + &nrds_dev.canvas_idx, 1, CANVAS_MAP_TYPE_1)) { + pr_err("%s alloc nrds canvas error.\n", __func__); + return; + } + pr_info("%s alloc nrds canvas %u.\n", + __func__, nrds_dev.canvas_idx); +} + +/* + * config nr ds mif, switch buffer + */ +void nr_ds_mif_config(void) +{ + unsigned long mem_addr = 0; + + mem_addr = nrds_dev.buf[nrds_dev.cur_buf_idx]; + canvas_config(nrds_dev.canvas_idx, mem_addr, + NR_DS_WIDTH, NR_DS_HEIGHT, 0, 0); + RDMA_WR_BITS(NRDSWR_CTRL, + nrds_dev.canvas_idx, 0, 8); + RDMA_WR_BITS(DI_PRE_CTRL, 1, 11, 1); + nr_ds_hw_ctrl(true); +} + +/* + * enable/disable nr ds mif&hw + */ +void nr_ds_hw_ctrl(bool enable) +{ + RDMA_WR_BITS(VIUB_MISC_CTRL0, enable?3:2, 5, 2); //Switch MIF to NR_DS + RDMA_WR_BITS(NRDSWR_CTRL, enable?1:0, 12, 1); + RDMA_WR_BITS(NR_DS_CTRL, enable?1:0, 30, 1); +} + +/* + * process in irq + */ +void nr_ds_irq(void) +{ + nr_ds_hw_ctrl(false); + nrds_dev.field_num++; + nrds_dev.cur_buf_idx++; + if (nrds_dev.cur_buf_idx >= NR_DS_BUF_NUM) + nrds_dev.cur_buf_idx = 0; +} +/* + * get buf addr&size for dump + */ +void get_nr_ds_buf(unsigned long *addr, unsigned long *size) +{ + *addr = nrds_dev.nrds_addr; + *size = NR_DS_BUF_SIZE; + pr_info("%s addr 0x%lx, size 0x%lx.\n", + __func__, *addr, *size); +} +/* + * 0x37f9 ~ 0x37fc 0x3740 ~ 0x3743 8 regs + */ +void dump_nrds_reg(unsigned int base_addr) +{ + unsigned int i = 0x37f9; + + pr_info("-----nrds reg start-----\n"); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (0x2006 << 2), i, RDMA_RD(0x2006)); + for (i = 0x37f9; i < 0x37fd; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), i, RDMA_RD(i)); + for (i = 0x3740; i < 0x3744; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), i, RDMA_RD(i)); + pr_info("-----nrds reg end-----\n"); +} diff --git a/drivers/amlogic/media/deinterlace/nr_downscale.h b/drivers/amlogic/media/deinterlace/nr_downscale.h new file mode 100644 index 000000000000..a1fde5f675c2 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/nr_downscale.h @@ -0,0 +1,45 @@ +/* + * drivers/amlogic/media/deinterlace/nr_downscale.h + * + * 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. + * + */ + +#ifndef _NR_DS_H +#define _NR_DS_H + +#define NR_DS_WIDTH 128 +#define NR_DS_HEIGHT 96 +#define NR_DS_BUF_SIZE (96<<7) +#define NR_DS_BUF_NUM 6 +#define NR_DS_MEM_SIZE (NR_DS_BUF_SIZE * NR_DS_BUF_NUM) +#define NR_DS_PAGE_NUM (NR_DS_MEM_SIZE>>PAGE_SHIFT) + +struct nr_ds_s { + unsigned int field_num; + unsigned long nrds_addr; + struct page *nrds_pages; + unsigned int canvas_idx; + unsigned char cur_buf_idx; + unsigned long buf[NR_DS_BUF_NUM]; +}; +void nr_ds_buf_init(unsigned int cma_flag, unsigned long mem_start, + struct device *dev); +void nr_ds_buf_uninit(unsigned int cma_flag, struct device *dev); +void nr_ds_init(unsigned int width, unsigned int height); +void nr_ds_mif_config(void); +void nr_ds_hw_ctrl(bool enable); +void nr_ds_irq(void); +void get_nr_ds_buf(unsigned long *addr, unsigned long *size); +void dump_nrds_reg(unsigned int base_addr); +#endif diff --git a/drivers/amlogic/media/deinterlace/nr_drv.c b/drivers/amlogic/media/deinterlace/nr_drv.c index 70a85b57e992..19f74110f3af 100644 --- a/drivers/amlogic/media/deinterlace/nr_drv.c +++ b/drivers/amlogic/media/deinterlace/nr_drv.c @@ -350,7 +350,7 @@ static void linebuffer_config(unsigned short width) static void nr2_config(unsigned short width, unsigned short height) { - if (is_meson_txlx_cpu()) + if (is_meson_txlx_cpu() || is_meson_g12a_cpu()) DI_Wr_reg_bits(NR4_TOP_CTRL, nr2_en, 2, 1); else { /*set max height to disable nfram cnt in cue*/ @@ -397,7 +397,7 @@ void nr_all_config(unsigned short width, unsigned short height, if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) cue_config(nr_param.pcue_parm, field_type); - if (is_meson_txlx_cpu()) { + if (is_meson_txlx_cpu() || is_meson_g12a_cpu()) { linebuffer_config(width); nr4_config(nr_param.pnr4_parm, width, height); } @@ -733,7 +733,7 @@ void nr_process_in_irq(void) cue_process_irq(); if (dnr_en) dnr_process(&dnr_param); - if (is_meson_txlx_cpu()) { + if (is_meson_txlx_cpu() || is_meson_g12a_cpu()) { noise_meter_process(nr_param.pnr4_parm, nr_param.frame_count); luma_enhancement_process(nr_param.pnr4_parm, nr_param.frame_count); @@ -1069,7 +1069,7 @@ void nr_hw_init(void) } void nr_gate_control(bool gate) { - if (!is_meson_txlx_cpu()) + if (!is_meson_txlx_cpu() && !is_meson_g12a_cpu()) return; if (gate) { /* enable nr auto gate */ diff --git a/drivers/amlogic/media/deinterlace/register.h b/drivers/amlogic/media/deinterlace/register.h index ebb6b4888cd2..1be93fadda7a 100644 --- a/drivers/amlogic/media/deinterlace/register.h +++ b/drivers/amlogic/media/deinterlace/register.h @@ -38,7 +38,7 @@ void DI_Wr_reg_bits(unsigned int adr, unsigned int val, void DI_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val); void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, unsigned int val, unsigned int start, unsigned int len); - +#define HHI_VPU_CLKB_CNTL 0x83 #define VPU_WRARB_REQEN_SLV_L1C1 ((0x2795)) /* << 2) + 0xd0100000) */ #define VPU_ARB_DBG_STAT_L1C1 ((0x27b4)) /* << 2) + 0xd0100000) */ #define SRSHARP0_SHARP_SR2_CTRL ((0x3257)) /* << 2) + 0xd0100000) */ @@ -359,6 +359,10 @@ void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, /* viu mux */ #define VIU_MISC_CTRL0 0x1a06 /* 0xd0106818 */ +#define VIU_MISC_CTRL1 0x1a07 +#define VD1_AFBCD0_MISC_CTRL 0x1a0a +#define VIUB_SW_RESET 0x2001 +#define VIUB_SW_RESET0 0x2002 #define VIUB_MISC_CTRL0 0x2006 /* 0xd0108018 */ #define VIUB_GCLK_CTRL0 0x2007 @@ -386,6 +390,208 @@ void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, #define DI_IF2_GEN_REG3 0x2022 /*txl new add end*/ +/* g12 new added */ +/* IF0 MIF */ +#define DI_IF0_GEN_REG 0x2030 +#define DI_IF0_CANVAS0 0x2031 +#define DI_IF0_LUMA_X0 0x2032 +#define DI_IF0_LUMA_Y0 0x2033 +#define DI_IF0_CHROMA_X0 0x2034 +#define DI_IF0_CHROMA_Y0 0x2035 +#define DI_IF0_REPEAT_LOOP 0x2036 +#define DI_IF0_LUMA0_RPT_PAT 0x2037 +#define DI_IF0_CHROMA0_RPT_PAT 0x2038 +#define DI_IF0_DUMMY_PIXEL 0x2039 +#define DI_IF0_LUMA_FIFO_SIZE 0x203A +#define DI_IF0_RANGE_MAP_Y 0x203B +#define DI_IF0_RANGE_MAP_CB 0x203C +#define DI_IF0_RANGE_MAP_CR 0x203D +#define DI_IF0_GEN_REG2 0x203E +#define DI_IF0_FMT_CTRL 0x203F +#define DI_IF0_FMT_W 0x2040 +#define DI_IF0_FMT_W 0x2040 +#define DI_IF0_URGENT_CTRL 0x2041 +#define DI_IF0_GEN_REG3 0x2042 +/* AXI ARB */ +#define DI_RDARB_MODE_L1C1 0x2050 +#define DI_RDARB_REQEN_SLV_L1C1 0x2051 +#define DI_RDARB_WEIGH0_SLV_L1C1 0x2052 +#define DI_RDARB_WEIGH1_SLV_L1C1 0x2053 +#define DI_WRARB_MODE_L1C1 0x2054 +#define DI_WRARB_REQEN_SLV_L1C1 0x2055 +#define DI_WRARB_WEIGH0_SLV_L1C1 0x2056 +#define DI_WRARB_WEIGH1_SLV_L1C1 0x2057 +#define DI_RDWR_ARB_STATUS_L1C1 0x2058 +#define DI_ARB_DBG_CTRL_L1C1 0x2059 +#define DI_ARB_DBG_STAT_L1C1 0x205a +#define DI_RDARB_UGT_L1C1 0x205b +#define DI_RDARB_LIMT0_L1C1 0x205c +#define DI_WRARB_UGT_L1C1 0x205d +#define DI_PRE_GL_CTRL 0x20ab +#define DI_PRE_GL_THD 0x20ac +#define DI_POST_GL_CTRL 0x20ad +#define DI_POST_GL_THD 0x20ae + +#define DI_SUB_RDARB_MODE 0x37c0 +#define DI_SUB_RDARB_REQEN_SLV 0x37c1 +#define DI_SUB_RDARB_WEIGH0_SLV 0x37c2 +#define DI_SUB_RDARB_WEIGH1_SLV 0x37c3 +#define DI_SUB_RDARB_UGT 0x37c4 +#define DI_SUB_RDARB_LIMT0 0x37c5 +#define DI_SUB_WRARB_MODE 0x37c6 +#define DI_SUB_WRARB_REQEN_SLV 0x37c7 +#define DI_SUB_WRARB_WEIGH0_SLV 0x37c8 +#define DI_SUB_WRARB_WEIGH1_SLV 0x37c9 +#define DI_SUB_WRARB_UGT 0x37ca +#define DI_SUB_RDWR_ARB_STATUS 0x37cb +#define DI_SUB_ARB_DBG_CTRL 0x37cc +#define DI_SUB_ARB_DBG_STAT 0x37cd +#define CONTRD_CTRL1 0x37d0 +#define CONTRD_CTRL2 0x37d1 +#define CONTRD_SCOPE_X 0x37d2 +#define CONTRD_SCOPE_Y 0x37d3 +#define CONTRD_RO_STAT 0x37d4 +#define CONT2RD_CTRL1 0x37d5 +#define CONT2RD_CTRL2 0x37d6 +#define CONT2RD_SCOPE_X 0x37d7 +#define CONT2RD_SCOPE_Y 0x37d8 +#define CONT2RD_RO_STAT 0x37d9 +#define MTNRD_CTRL1 0x37da +#define MTNRD_CTRL2 0x37db +#define MTNRD_SCOPE_X 0x37dc +#define MTNRD_SCOPE_Y 0x37dd +#define MTNRD_RO_STAT 0x37de +#define MCVECRD_CTRL1 0x37df +#define MCVECRD_CTRL2 0x37e0 +#define MCVECRD_SCOPE_X 0x37e1 +#define MCVECRD_SCOPE_Y 0x37e2 +#define MCVECRD_RO_STAT 0x37e3 +#define MCINFRD_CTRL1 0x37e4 +#define MCINFRD_CTRL2 0x37e5 +#define MCINFRD_SCOPE_X 0x37e6 +#define MCINFRD_SCOPE_Y 0x37e7 +#define MCINFRD_RO_STAT 0x37e8 +#define CONTWR_X 0x37e9 +#define CONTWR_Y 0x37ea +#define CONTWR_CTRL 0x37eb +#define CONTWR_CAN_SIZE 0x37ec +#define MTNWR_X 0x37ed +#define MTNWR_Y 0x37ee +#define MTNWR_CTRL 0x37ef +#define MTNWR_CAN_SIZE 0x37f0 +#define MCVECWR_X 0x37f1 +#define MCVECWR_Y 0x37f2 +#define MCVECWR_CTRL 0x37f3 +#define MCVECWR_CAN_SIZE 0x37f4 +#define MCINFWR_X 0x37f5 +#define MCINFWR_Y 0x37f6 +#define MCINFWR_CTRL 0x37f7 +#define MCINFWR_CAN_SIZE 0x37f8 +/* DI SCALE */ +#define DI_SCO_FIFO_CTRL 0x374e +#define DI_SC_TOP_CTRL 0x374f +#define DI_SC_DUMMY_DATA 0x3750 +#define DI_SC_LINE_IN_LENGTH 0x3751 +#define DI_SC_PIC_IN_HEIGHT 0x3752 +#define DI_SC_COEF_IDX 0x3753 +#define DI_SC_COEF 0x3754 +#define DI_VSC_REGION12_STARTP 0x3755 +#define DI_VSC_REGION34_STARTP 0x3756 +#define DI_VSC_REGION4_ENDP 0x3757 +#define DI_VSC_START_PHASE_STEP 0x3758 +#define DI_VSC_REGION0_PHASE_SLOPE 0x3759 +#define DI_VSC_REGION1_PHASE_SLOPE 0x375a +#define DI_VSC_REGION3_PHASE_SLOPE 0x375b +#define DI_VSC_REGION4_PHASE_SLOPE 0x375c +#define DI_VSC_PHASE_CTRL 0x375d +#define DI_VSC_INI_PHASE 0x375e +#define DI_HSC_REGION12_STARTP 0x3760 +#define DI_HSC_REGION34_STARTP 0x3761 +#define DI_HSC_REGION4_ENDP 0x3762 +#define DI_HSC_START_PHASE_STEP 0x3763 +#define DI_HSC_REGION0_PHASE_SLOPE 0x3764 +#define DI_HSC_REGION1_PHASE_SLOPE 0x3765 +#define DI_HSC_REGION3_PHASE_SLOPE 0x3766 +#define DI_HSC_REGION4_PHASE_SLOPE 0x3767 +#define DI_HSC_PHASE_CTRL 0x3768 +#define DI_SC_MISC 0x3769 +#define DI_HSC_PHASE_CTRL1 0x376a +#define DI_HSC_INI_PAT_CTRL 0x376b +#define DI_SC_GCLK_CTRL 0x376c +#define DI_SC_HOLD_LINE 0x376d +/* DI HDR */ +#define DI_HDR_IN_HSIZE 0x376e +#define DI_HDR_IN_VSIZE 0x376f +#define DI_HDR2_CTRL 0x3800 +#define DI_HDR2_CLK_GATE 0x3881 +#define DI_HDR2_MATRIXI_COEF00_01 0x3882 +#define DI_HDR2_MATRIXI_COEF02_10 0x3883 +#define DI_HDR2_MATRIXI_COEF11_12 0x3884 +#define DI_HDR2_MATRIXI_COEF20_21 0x3885 +#define DI_HDR2_MATRIXI_COEF22 0x3886 +#define DI_HDR2_MATRIXI_COEF30_31 0x3887 +#define DI_HDR2_MATRIXI_COEF32_40 0x3888 +#define DI_HDR2_MATRIXI_COEF41_42 0x3889 +#define DI_HDR2_MATRIXI_OFFSET0_1 0x388A +#define DI_HDR2_MATRIXI_OFFSET2 0x388B +#define DI_HDR2_MATRIXI_PRE_OFFSET0_1 0x388C +#define DI_HDR2_MATRIXI_PRE_OFFSET2 0x388D +#define DI_HDR2_MATRIXO_COEF00_01 0x388E +#define DI_HDR2_MATRIXO_COEF02_10 0x388F +#define DI_HDR2_MATRIXO_COEF11_12 0x3890 +#define DI_HDR2_MATRIXO_COEF20_21 0x3891 +#define DI_HDR2_MATRIXO_COEF22 0x3892 +#define DI_HDR2_MATRIXO_COEF30_31 0x3893 +#define DI_HDR2_MATRIXO_COEF32_40 0x3894 +#define DI_HDR2_MATRIXO_COEF41_42 0x3895 +#define DI_HDR2_MATRIXO_OFFSET0_1 0x3896 +#define DI_HDR2_MATRIXO_OFFSET2 0x3897 +#define DI_HDR2_MATRIXO_PRE_OFFSET0_1 0x3898 +#define DI_HDR2_MATRIXO_PRE_OFFSET2 0x3899 +#define DI_HDR2_MATRIXI_CLIP 0x389A +#define DI_HDR2_MATRIXO_CLIP 0x389B +#define DI_HDR2_CGAIN_OFFT 0x389C +#define DI_EOTF_LUT_ADDR_PORT 0x389E +#define DI_EOTF_LUT_DATA_PORT 0x389F +#define DI_OETF_LUT_ADDR_PORT 0x38A0 +#define DI_OETF_LUT_DATA_PORT 0x38A1 +#define DI_CGAIN_LUT_ADDR_PORT 0x38A2 +#define DI_CGAIN_LUT_DATA_PORT 0x38A3 +#define DI_HDR2_CGAIN_COEF0 0x38A4 +#define DI_HDR2_CGAIN_COEF1 0x38A5 +#define DI_OGAIN_LUT_ADDR_PORT 0x38A6 +#define DI_OGAIN_LUT_DATA_PORT 0x38A7 +#define DI_HDR2_ADPS_CTRL 0x38A8 +#define DI_HDR2_ADPS_ALPHA0 0x38A9 +#define DI_HDR2_ADPS_ALPHA1 0x38AA +#define DI_HDR2_ADPS_BETA0 0x38AB +#define DI_HDR2_ADPS_BETA1 0x38AC +#define DI_HDR2_ADPS_BETA2 0x38AD +#define DI_HDR2_ADPS_COEF0 0x38AE +#define DI_HDR2_ADPS_COEF1 0x38AF +#define DI_HDR2_GMUT_CTRL 0x38B0 +#define DI_HDR2_GMUT_COEF0 0x38B1 +#define DI_HDR2_GMUT_COEF1 0x38B2 +#define DI_HDR2_GMUT_COEF2 0x38B3 +#define DI_HDR2_GMUT_COEF3 0x38B4 +#define DI_HDR2_GMUT_COEF4 0x38B5 +#define DI_HDR2_PIPE_CTRL1 0x38B6 +#define DI_HDR2_PIPE_CTRL2 0x38B7 +#define DI_HDR2_PIPE_CTRL3 0x38B8 +#define DI_HDR2_PROC_WIN1 0x38B9 +#define DI_HDR2_PROC_WIN2 0x38BA +#define DI_HDR2_MATRIXI_EN_CTRL 0x38BB +#define DI_HDR2_MATRIXO_EN_CTRL 0x38BC +/* NR DOWNSAMPLE */ +#define NRDSWR_X 0x37f9 +#define NRDSWR_Y 0x37fa +#define NRDSWR_CTRL 0x37fb +#define NRDSWR_CAN_SIZE 0x37fc +#define NR_DS_BUF_SIZE_REG 0x3740 +#define NR_DS_CTRL 0x3741 +#define NR_DS_OFFSET 0x3742 +#define NR_DS_BLD_COEF 0x3743 + /* di */ #define DI_IF1_URGENT_CTRL (0x20a3) /* << 2 + 0xd0100000*/ /* bit15, auto enable; bit14, canvas write mode ;7:4, high threshold ;3:0 , diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 56235e94f821..0f1af0443987 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -2685,9 +2685,13 @@ static void viu_set_dcu(struct vpp_frame_par_s *frame_par, struct vframe_s *vf) } DI_POST_WR_REG_BITS(DI_IF1_GEN_REG3, (bit_mode&0x3), 8, 2); - if (is_meson_txl_cpu() || is_meson_txlx_cpu()) + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) DI_POST_WR_REG_BITS(DI_IF2_GEN_REG3, - (bit_mode & 0x3), 8, 2); + (bit_mode & 0x3), 8, 2); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + DI_POST_WR_REG_BITS(DI_IF0_GEN_REG3, + (bit_mode & 0x3), 8, 2); + vd1_path_select(false); VSYNC_WR_MPEG_REG(AFBC_ENABLE, 0); } diff --git a/include/linux/amlogic/media/registers/regs/di_regs.h b/include/linux/amlogic/media/registers/regs/di_regs.h index c9c246b33284..ebef0a51a9b9 100644 --- a/include/linux/amlogic/media/registers/regs/di_regs.h +++ b/include/linux/amlogic/media/registers/regs/di_regs.h @@ -18,172 +18,8 @@ #ifndef DI_REGS_HEADER_ #define DI_REGS_HEADER_ - -#define DI_PRE_CTRL 0x1700 #define DI_POST_CTRL 0x1701 #define DI_POST_SIZE 0x1702 -#define DI_PRE_SIZE 0x1703 -#define DI_EI_CTRL0 0x1704 -#define DI_EI_CTRL1 0x1705 -#define DI_EI_CTRL2 0x1706 -#define DI_NR_CTRL0 0x1707 -#define DI_NR_CTRL1 0x1708 -#define DI_NR_CTRL2 0x1709 -#define DI_NR_CTRL3 0x170a -#define DI_MTN_CTRL 0x170b -#define DI_MTN_CTRL1 0x170c -#define DI_BLEND_CTRL 0x170d -#define DI_BLEND_CTRL1 0x170e -#define DI_BLEND_CTRL2 0x170f -#define DI_BLEND_REG0_X 0x1710 -#define DI_BLEND_REG0_Y 0x1711 -#define DI_BLEND_REG1_X 0x1712 -#define DI_BLEND_REG1_Y 0x1713 -#define DI_BLEND_REG2_X 0x1714 -#define DI_BLEND_REG2_Y 0x1715 -#define DI_BLEND_REG3_X 0x1716 -#define DI_BLEND_REG3_Y 0x1717 -#define DI_CLKG_CTRL 0x1718 -#define DI_EI_CTRL3 0x1719 -#define DI_EI_CTRL4 0x171a -#define DI_EI_CTRL5 0x171b -#define DI_EI_CTRL6 0x171c -#define DI_EI_CTRL7 0x171d -#define DI_EI_CTRL8 0x171e -#define DI_EI_CTRL9 0x171f -#define DI_EI_CTRL10 0x1793 -#define DI_EI_CTRL11 0x179e -#define DI_EI_CTRL12 0x179f -#define DI_EI_CTRL13 0x17a8 -#define DI_EI_XWIN0 0x1798 -#define DI_EI_XWIN1 0x1799 -#define DI_MC_REG0_X 0x1720 -#define DI_MC_REG0_Y 0x1721 -#define DI_MC_REG1_X 0x1722 -#define DI_MC_REG1_Y 0x1723 -#define DI_MC_REG2_X 0x1724 -#define DI_MC_REG2_Y 0x1725 -#define DI_MC_REG3_X 0x1726 -#define DI_MC_REG3_Y 0x1727 -#define DI_MC_REG4_X 0x1728 -#define DI_MC_REG4_Y 0x1729 -#define DI_MC_32LVL0 0x172a -#define DI_MC_32LVL1 0x172b -#define DI_MC_22LVL0 0x172c -#define DI_MC_22LVL1 0x172d -#define DI_MC_22LVL2 0x172e -#define DI_MC_CTRL 0x172f -#define DI_INTR_CTRL 0x1730 -#define DI_INFO_ADDR 0x1731 -#define DI_INFO_DATA 0x1732 -#define DI_PRE_HOLD 0x1733 -#define DI_MTN_1_CTRL1 0x1740 -#define DI_MTN_1_CTRL2 0x1741 -#define DI_MTN_1_CTRL3 0x1742 -#define DI_MTN_1_CTRL4 0x1743 -#define DI_MTN_1_CTRL5 0x1744 -#define DI_MTN_1_CTRL6 0x17a9 -#define DI_MTN_1_CTRL7 0x17aa -#define DI_MTN_1_CTRL8 0x17ab -#define DI_MTN_1_CTRL9 0x17ac -#define DI_MTN_1_CTRL10 0x17ad -#define DI_MTN_1_CTRL11 0x17ae -#define DI_MTN_1_CTRL12 0x17af -#define DET3D_MOTN_CFG 0x1734 -#define DET3D_CB_CFG 0x1735 -#define DET3D_SPLT_CFG 0x1736 -#define DET3D_HV_MUTE 0x1737 -#define DET3D_MAT_STA_P1M1 0x1738 -#define DET3D_MAT_STA_P1TH 0x1739 -#define DET3D_MAT_STA_M1TH 0x173a -#define DET3D_MAT_STA_RSFT 0x173b -#define DET3D_MAT_SYMTC_TH 0x173c -#define DET3D_RO_DET_CB_HOR 0x173d -#define DET3D_RO_DET_CB_VER 0x173e -#define DET3D_RO_SPLT_HT 0x173f -#define NR2_MET_NM_CTRL 0x1745 -#define NR2_MET_NM_YCTRL 0x1746 -#define NR2_MET_NM_CCTRL 0x1747 -#define NR2_MET_NM_TNR 0x1748 -#define NR2_MET_NMFRM_TNR_YLEV 0x1749 -#define NR2_MET_NMFRM_TNR_YCNT 0x174a -#define NR2_MET_NMFRM_TNR_CLEV 0x174b -#define NR2_MET_NMFRM_TNR_CCNT 0x174c -#define NR2_3DEN_MODE 0x174d -#define NR2_IIR_CTRL 0x174e -#define NR2_SW_EN 0x174f -#define NR2_FRM_SIZE 0x1750 -#define NR2_SNR_SAD_CFG 0x1751 -#define NR2_MATNR_SNR_OS 0x1752 -#define NR2_MATNR_SNR_NRM_CFG 0x1753 -#define NR2_MATNR_SNR_NRM_GAIN 0x1754 -#define NR2_MATNR_SNR_LPF_CFG 0x1755 -#define NR2_MATNR_SNR_USF_GAIN 0x1756 -#define NR2_MATNR_SNR_EDGE2B 0x1757 -#define NR2_MATNR_BETA_EGAIN 0x1758 -#define NR2_MATNR_BETA_BRT 0x1759 -#define NR2_MATNR_XBETA_CFG 0x175a -#define NR2_MATNR_YBETA_SCL 0x175b -#define NR2_MATNR_CBETA_SCL 0x175c -#define NR2_SNR_MASK 0x175d -#define NR2_SAD2NORM_LUT0 0x175e -#define NR2_SAD2NORM_LUT1 0x175f -#define NR2_SAD2NORM_LUT2 0x1760 -#define NR2_SAD2NORM_LUT3 0x1761 -#define NR2_EDGE2BETA_LUT0 0x1762 -#define NR2_EDGE2BETA_LUT1 0x1763 -#define NR2_EDGE2BETA_LUT2 0x1764 -#define NR2_EDGE2BETA_LUT3 0x1765 -#define NR2_MOTION2BETA_LUT0 0x1766 -#define NR2_MOTION2BETA_LUT1 0x1767 -#define NR2_MOTION2BETA_LUT2 0x1768 -#define NR2_MOTION2BETA_LUT3 0x1769 -#define NR2_MATNR_MTN_CRTL 0x176a -#define NR2_MATNR_MTN_CRTL2 0x176b -#define NR2_MATNR_MTN_COR 0x176c -#define NR2_MATNR_MTN_GAIN 0x176d -#define NR2_MATNR_DEGHOST 0x176e -#define NR2_MATNR_ALPHALP_LUT0 0x176f -#define NR2_MATNR_ALPHALP_LUT1 0x1770 -#define NR2_MATNR_ALPHALP_LUT2 0x1771 -#define NR2_MATNR_ALPHALP_LUT3 0x1772 -#define NR2_MATNR_ALPHAHP_LUT0 0x1773 -#define NR2_MATNR_ALPHAHP_LUT1 0x1774 -#define NR2_MATNR_ALPHAHP_LUT2 0x1775 -#define NR2_MATNR_ALPHAHP_LUT3 0x1776 -#define NR2_MATNR_MTNB_BRT 0x1777 -#define NR2_CUE_MODE 0x1778 -#define NR2_CUE_CON_MOT_TH 0x1779 -#define NR2_CUE_CON_DIF0 0x177a -#define NR2_CUE_CON_DIF1 0x177b -#define NR2_CUE_CON_DIF2 0x177c -#define NR2_CUE_CON_DIF3 0x177d -#define NR2_CUE_PRG_DIF 0x177e -#define NR2_CONV_MODE 0x177f -#define DET3D_RO_SPLT_HB 0x1780 -#define DET3D_RO_SPLT_VL 0x1781 -#define DET3D_RO_SPLT_VR 0x1782 -#define DET3D_RO_MAT_LUMA_LR 0x1783 -#define DET3D_RO_MAT_LUMA_TB 0x1784 -#define DET3D_RO_MAT_CHRU_LR 0x1785 -#define DET3D_RO_MAT_CHRU_TB 0x1786 -#define DET3D_RO_MAT_CHRV_LR 0x1787 -#define DET3D_RO_MAT_CHRV_TB 0x1788 -#define DET3D_RO_MAT_HEDG_LR 0x1789 -#define DET3D_RO_MAT_HEDG_TB 0x178a -#define DET3D_RO_MAT_VEDG_LR 0x178b -#define DET3D_RO_MAT_VEDG_TB 0x178c -#define DET3D_RO_MAT_MOTN_LR 0x178d -#define DET3D_RO_MAT_MOTN_TB 0x178e -#define DET3D_RO_FRM_MOTN 0x178f -#define DET3D_RAMRD_ADDR_PORT 0x179a -#define DET3D_RAMRD_DATA_PORT 0x179b -#define NR2_CFR_PARA_CFG0 0x179c -#define NR2_CFR_PARA_CFG1 0x179d -#define DI_NR_1_CTRL0 0x1794 -#define DI_NR_1_CTRL1 0x1795 -#define DI_NR_1_CTRL2 0x1796 -#define DI_NR_1_CTRL3 0x1797 #define DI_CONTWR_X 0x17a0 #define DI_CONTWR_Y 0x17a1 #define DI_CONTWR_CTRL 0x17a2 @@ -278,6 +114,7 @@ #define VD1_IF0_GEN_REG3 0x1aa7 #define DI_IF1_GEN_REG3 0x20a7 #define DI_IF2_GEN_REG3 0x2022 +#define DI_IF0_GEN_REG3 0x2042 #endif