| // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
| /* |
| * drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.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 <linux/module.h> |
| #include <linux/slab.h> |
| #include <linux/amlogic/media/frame_provider/tvin/tvin.h> |
| #include <linux/amlogic/media/vpu/vpu.h> |
| #include <linux/delay.h> |
| #include <linux/device.h> |
| #include <linux/platform_device.h> |
| #include <linux/amlogic/media/codec_mm/codec_mm.h> |
| #include <linux/amlogic/media/utils/vdec_reg.h> |
| #include <linux/highmem.h> |
| #include <linux/page-flags.h> |
| #include <linux/vmalloc.h> |
| #include <linux/dma-mapping.h> |
| #include <linux/dma-contiguous.h> |
| #include <linux/sched/clock.h> |
| |
| #include <linux/amlogic/media/video_sink/video.h> |
| #include <linux/amlogic/media/amdolbyvision/dolby_vision.h> |
| #include "../tvin_global.h" |
| #include "../tvin_format_table.h" |
| #include "vdin_ctl.h" |
| #include "vdin_regs.h" |
| #include "vdin_drv.h" |
| #include "vdin_vf.h" |
| #include "vdin_canvas.h" |
| #include "vdin_afbce.h" |
| #include "vdin_dv.h" |
| |
| #define VDIN_VSHRINK_HLIMIT 1280 |
| #define TVIN_MAX_PIXCLK 20000 |
| #define META_RETRY_MAX 10 |
| #define VDIN_MAX_HACTIVE 4096 /*the max hactive of vdin*/ |
| /*0: 1 word in 1burst, 1: 2 words in 1burst; |
| *2: 4 words in 1burst; |
| */ |
| #define VDIN_WR_BURST_MODE 2 |
| |
| static bool cm_enable = 1; |
| module_param(cm_enable, bool, 0644); |
| MODULE_PARM_DESC(cm_enable, "cm_enable"); |
| |
| static bool rgb_info_enable; |
| static unsigned int rgb_info_x; |
| static unsigned int rgb_info_y; |
| static unsigned int rgb_info_r; |
| static unsigned int rgb_info_g; |
| static unsigned int rgb_info_b; |
| static int vdin_det_idle_wait = 100; |
| static unsigned int delay_line_num; |
| static bool invert_top_bot; |
| unsigned int vdin0_afbce_debug_force; |
| |
| #ifdef DEBUG_SUPPORT |
| module_param(rgb_info_enable, bool, 0644); |
| MODULE_PARM_DESC(rgb_info_enable, "rgb_info_enable"); |
| |
| module_param(rgb_info_x, uint, 0644); |
| MODULE_PARM_DESC(rgb_info_x, "rgb_info_x"); |
| |
| module_param(rgb_info_y, uint, 0644); |
| MODULE_PARM_DESC(rgb_info_y, "rgb_info_y"); |
| |
| module_param(rgb_info_r, uint, 0644); |
| MODULE_PARM_DESC(rgb_info_r, "rgb_info_r"); |
| |
| module_param(rgb_info_g, uint, 0644); |
| MODULE_PARM_DESC(rgb_info_g, "rgb_info_g"); |
| |
| module_param(rgb_info_b, uint, 0644); |
| MODULE_PARM_DESC(rgb_info_b, "rgb_info_b"); |
| |
| module_param(vdin_det_idle_wait, int, 0664); |
| MODULE_PARM_DESC(vdin_det_idle_wait, "vdin_det_idle_wait"); |
| |
| module_param(delay_line_num, uint, 0644); |
| MODULE_PARM_DESC(delay_line_num, "delay_line_num"); |
| |
| module_param(invert_top_bot, bool, 0644); |
| MODULE_PARM_DESC(invert_top_bot, "invert field type top or bottom"); |
| #endif |
| |
| bool enable_reset; |
| module_param(enable_reset, bool, 0664); |
| MODULE_PARM_DESC(enable_reset, "enable_reset"); |
| static int vsync_reset_mask; |
| module_param(vsync_reset_mask, int, 0664); |
| MODULE_PARM_DESC(vsync_reset_mask, "vsync_reset_mask"); |
| |
| unsigned int dv_dbg_log; |
| module_param(dv_dbg_log, uint, 0664); |
| MODULE_PARM_DESC(dv_dbg_log, "enable/disable dv_dbg_log"); |
| |
| unsigned int dv_dbg_log_du = 60; |
| module_param(dv_dbg_log_du, uint, 0664); |
| MODULE_PARM_DESC(dv_dbg_log_du, "dv_dbg_log_duration"); |
| |
| unsigned int dv_dbg_mask = (DV_BUF_START_RESET); |
| module_param(dv_dbg_mask, uint, 0664); |
| MODULE_PARM_DESC(dv_dbg_mask, "enable/disable dv_dbg_mask"); |
| |
| static int vdin_ctl_dbg; |
| module_param(vdin_ctl_dbg, int, 0664); |
| MODULE_PARM_DESC(vdin_ctl_dbg, "vdin_ctl_dbg"); |
| |
| /*bit0/1:game mode enable for vdin0/1*/ |
| unsigned int vdin_force_game_mode; |
| unsigned int game_mode; |
| module_param(game_mode, uint, 0664); |
| MODULE_PARM_DESC(game_mode, "game_mode"); |
| |
| unsigned int vdin_pc_mode; |
| module_param(vdin_pc_mode, uint, 0664); |
| MODULE_PARM_DESC(vdin_pc_mode, "vdin_pc_mode"); |
| |
| unsigned int vdin_isr_monitor; |
| module_param(vdin_isr_monitor, uint, 0664); |
| MODULE_PARM_DESC(vdin_isr_monitor, "vdin_isr_monitor"); |
| |
| unsigned int vdin_get_prop_in_vs_en = 1; |
| module_param(vdin_get_prop_in_vs_en, uint, 0664); |
| MODULE_PARM_DESC(vdin_get_prop_in_vs_en, "vdin_get_prop_in_vs_en"); |
| |
| unsigned int vdin_get_prop_in_sm_en = 1; |
| module_param(vdin_get_prop_in_sm_en, uint, 0664); |
| MODULE_PARM_DESC(vdin_get_prop_in_sm_en, "vdin_get_prop_in_sm_en"); |
| |
| unsigned int vdin_get_prop_in_fe_en; |
| module_param(vdin_get_prop_in_fe_en, uint, 0664); |
| MODULE_PARM_DESC(vdin_get_prop_in_fe_en, "vdin_get_prop_in_fe_en"); |
| |
| unsigned int vdin_prop_monitor; |
| module_param(vdin_prop_monitor, uint, 0664); |
| MODULE_PARM_DESC(vdin_prop_monitor, "vdin_prop_monitor"); |
| |
| static unsigned int vpu_reg_27af = 0x3; |
| |
| /***************************Local defines**********************************/ |
| #define BBAR_BLOCK_THR_FACTOR 3 |
| #define BBAR_LINE_THR_FACTOR 7 |
| |
| #define VDIN_MUX_NULL 0 |
| #define VDIN_MUX_MPEG 1 |
| #define VDIN_MUX_656 2 |
| #define VDIN_MUX_TVFE 3 |
| #define VDIN_MUX_CVD2 4 |
| #define VDIN_MUX_HDMI 5 |
| #define VDIN_MUX_DVIN 6 |
| #define VDIN_MUX_VIU1_WB0 7 |
| #define VDIN_MUX_MIPI 8 |
| #define VDIN_MUX_ISP 9 |
| /* after g12a new add*/ |
| #define VDIN_MUX_VIU1_WB1 9 |
| #define VDIN_MUX_656_B 10 |
| |
| #define VDIN_MAP_Y_G 0 |
| #define VDIN_MAP_BPB 1 |
| #define VDIN_MAP_RCR 2 |
| |
| #define MEAS_MUX_NULL 0 |
| #define MEAS_MUX_656 1 |
| #define MEAS_MUX_TVFE 2 |
| #define MEAS_MUX_CVD2 3 |
| #define MEAS_MUX_HDMI 4 |
| #define MEAS_MUX_DVIN 5 |
| #define MEAS_MUX_DTV 6 |
| #define MEAS_MUX_ISP 8 |
| #define MEAS_MUX_656_B 9 |
| #define MEAS_MUX_VIU1 6 |
| #define MEAS_MUX_VIU2 8 |
| |
| #define HDMI_DE_REPEAT_DONE_FLAG 0xF0 |
| #define DECIMATION_REAL_RANGE 0x0F |
| #define VDIN_PIXELCLK_4K_30HZ 248832000 |
| #define VDIN_PIXELCLK_4K_60HZ 497664000 |
| |
| /*ndef VDIN_DEBUG*/ |
| /*#undef pr_info*/ |
| /*#define pr_info(fmt, ...)*/ |
| |
| u8 *vdin_vmap(ulong addr, u32 size) |
| { |
| u8 *vaddr = NULL; |
| struct page **pages = NULL; |
| u32 i, npages, offset = 0; |
| ulong phys, page_start; |
| /*pgprot_t pgprot = pgprot_noncached(PAGE_KERNEL);*/ |
| pgprot_t pgprot = PAGE_KERNEL; |
| |
| if (!PageHighMem(phys_to_page(addr))) |
| return phys_to_virt(addr); |
| |
| offset = offset_in_page(addr); |
| page_start = addr - offset; |
| npages = DIV_ROUND_UP(size + offset, PAGE_SIZE); |
| |
| pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); |
| if (!pages) |
| return NULL; |
| |
| for (i = 0; i < npages; i++) { |
| phys = page_start + i * PAGE_SIZE; |
| pages[i] = pfn_to_page(phys >> PAGE_SHIFT); |
| } |
| |
| vaddr = vmap(pages, npages, VM_MAP, pgprot); |
| if (!vaddr) { |
| pr_err("the phy(%lx) vmaped fail, size: %d\n", |
| page_start, npages << PAGE_SHIFT); |
| kfree(pages); |
| return NULL; |
| } |
| |
| kfree(pages); |
| |
| if (vdin_dbg_en) { |
| pr_info("[vdin HIGH-MEM-MAP] %s, pa(%lx) to va(%p), size: %d\n", |
| __func__, page_start, vaddr, npages << PAGE_SHIFT); |
| } |
| |
| return vaddr + offset; |
| } |
| |
| void vdin_unmap_phyaddr(u8 *vaddr) |
| { |
| void *addr = (void *)(PAGE_MASK & (ulong)vaddr); |
| |
| if (is_vmalloc_or_module_addr(vaddr)) { |
| if (vdin_dbg_en) |
| pr_info("----vdin unmap v: %p\n", addr); |
| vunmap(addr); |
| } |
| } |
| |
| void vdin_dma_flush(struct vdin_dev_s *devp, void *vaddr, |
| int size, enum dma_data_direction dir) |
| { |
| ulong phy_addr; |
| |
| if (is_vmalloc_or_module_addr(vaddr)) { |
| phy_addr = page_to_phys(vmalloc_to_page(vaddr)) |
| + offset_in_page(vaddr); |
| if (phy_addr && PageHighMem(phys_to_page(phy_addr))) { |
| if (vdin_dbg_en) |
| pr_info("----vdin flush v: %p, p: %lx\n", |
| vaddr, phy_addr); |
| dma_sync_single_for_device(&devp->this_pdev->dev, |
| phy_addr, size, dir); |
| } |
| return; |
| } |
| } |
| |
| /*reset reg mif value of vdin0: |
| * VDIN_WR_CTRL \VDIN_COM_CTRL0\ VDIN_MISC_CTRL |
| */ |
| static void vdin0_wr_mif_reset(void) |
| { |
| if (vsync_reset_mask & 0x08) { |
| W_VCBUS_BIT(VDIN_WR_CTRL, 1, FRAME_SOFT_RST_EN_BIT, FRAME_SOFT_RST_EN_WID); |
| W_VCBUS_BIT(VDIN_COM_CTRL0, 1, VDIN_FORCEGOLINE_EN_BIT, 1); |
| udelay(1); |
| W_VCBUS_BIT(VDIN_WR_CTRL, 0, FRAME_SOFT_RST_EN_BIT, FRAME_SOFT_RST_EN_WID); |
| } else { |
| W_VCBUS_BIT(VDIN_WR_CTRL, 0, VDIN_WRCTRLREG_PAUSE_BIT, VDIN_WRCTRLREG_PAUSE_WID); |
| W_VCBUS_BIT(VDIN_MISC_CTRL, 1, 2, 1); |
| W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_MIF_RST_BIT, 1); |
| udelay(1); |
| W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN0_MIF_RST_BIT, 1); |
| W_VCBUS_BIT(VDIN_MISC_CTRL, 0, 2, 1); |
| W_VCBUS_BIT(VDIN_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| W_VCBUS_BIT(VDIN_WR_CTRL, 1, VDIN_WRCTRLREG_PAUSE_BIT, VDIN_WRCTRLREG_PAUSE_WID); |
| } |
| }; |
| |
| /*reset reg mif value of vdin1: |
| * VDIN_WR_CTRL \VDIN_COM_CTRL1\ VDIN_MISC_CTRL |
| */ |
| static void vdin1_wr_mif_reset(void) |
| { |
| if (vsync_reset_mask & 0x08) { |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 1, FRAME_SOFT_RST_EN_BIT, 1); |
| W_VCBUS_BIT(VDIN_COM_CTRL1, 1, VDIN_FORCEGOLINE_EN_BIT, 1); |
| udelay(1); |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 0, FRAME_SOFT_RST_EN_BIT, 1); |
| } else { |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 0, VDIN_WRCTRLREG_PAUSE_BIT, 1); |
| W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN1_MIF_RST_BIT, 1); |
| udelay(1); |
| W_VCBUS_BIT(VDIN_MISC_CTRL, 0, VDIN1_MIF_RST_BIT, 1); |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 1, VDIN_WRCTRLREG_PAUSE_BIT, 1); |
| } |
| } |
| |
| /***************************Local Structures**********************************/ |
| static struct vdin_matrix_lup_s vdin_matrix_lup[] = { |
| {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 0x00000000, 0x0400200, 0x00000200,}, |
| /* VDIN_MATRIX_RGB_YUV601 */ |
| /* 0 0.257 0.504 0.098 16 */ |
| /* 0 -0.148 -0.291 0.439 128 */ |
| /* 0 0.439 -0.368 -0.071 128 */ |
| {0x00000000, 0x00000000, 0x01070204, 0x00641f68, 0x1ed601c2, 0x01c21e87, |
| 0x00001fb7, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_GBR_YUV601 */ |
| /* 0 0.504 0.098 0.257 16 */ |
| /* 0 -0.291 0.439 -0.148 128 */ |
| /* 0 -0.368 -0.071 0.439 128 */ |
| {0x00000000, 0x00000000, 0x02040064, 0x01071ed6, 0x01c21f68, 0x1e871fb7, |
| 0x000001c2, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_BRG_YUV601 */ |
| /* 0 0.098 0.257 0.504 16 */ |
| /* 0 0.439 -0.148 -0.291 128 */ |
| /* 0 -0.071 0.439 -0.368 128 */ |
| {0x00000000, 0x00000000, 0x00640107, 0x020401c2, 0x1f681ed6, 0x1fb701c2, |
| 0x00001e87, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601_RGB */ |
| /* -16 1.164 0 1.596 0 */ |
| /* -128 1.164 -0.391 -0.813 0 */ |
| /* -128 1.164 2.018 0 0 */ |
| {0x07c00600, 0x00000600, 0x04a80000, 0x066204a8, 0x1e701cbf, 0x04a80812, |
| 0x00000000, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_YUV601_GBR */ |
| /* -16 1.164 -0.391 -0.813 0 */ |
| /* -128 1.164 2.018 0 0 */ |
| /* -128 1.164 0 1.596 0 */ |
| {0x07c00600, 0x00000600, 0x04a81e70, 0x1cbf04a8, 0x08120000, 0x04a80000, |
| 0x00000662, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_YUV601_BRG */ |
| /* -16 1.164 2.018 0 0 */ |
| /* -128 1.164 0 1.596 0 */ |
| /* -128 1.164 -0.391 -0.813 0 */ |
| {0x07c00600, 0x00000600, 0x04a80812, 0x000004a8, 0x00000662, 0x04a81e70, |
| 0x00001cbf, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_RGB_YUV601F */ |
| /* 0 0.299 0.587 0.114 0 */ |
| /* 0 -0.169 -0.331 0.5 128 */ |
| /* 0 0.5 -0.419 -0.081 128 */ |
| {0x00000000, 0x00000000, 0x01320259, 0x00751f53, 0x1ead0200, 0x02001e53, |
| 0x00001fad, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601F_RGB */ |
| /* 0 1 0 1.402 0 */ |
| /* -128 1 -0.344 -0.714 0 */ |
| /* -128 1 1.772 0 0 */ |
| {0x00000600, 0x00000600, 0x04000000, 0x059c0400, 0x1ea01d25, 0x04000717, |
| 0x00000000, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_RGBS_YUV601 */ |
| /* -16 0.299 0.587 0.114 16 */ |
| /* -16 -0.173 -0.339 0.511 128 */ |
| /* -16 0.511 -0.429 -0.083 128 */ |
| {0x07c007c0, 0x000007c0, 0x01320259, 0x00751f4f, 0x1ea5020b, 0x020b1e49, |
| 0x00001fab, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601_RGBS */ |
| /* -16 1 0 1.371 16 */ |
| /* -128 1 -0.336 -0.698 16 */ |
| /* -128 1 1.733 0 16 */ |
| {0x07c00600, 0x00000600, 0x04000000, 0x057c0400, 0x1ea81d35, 0x040006ef, |
| 0x00000000, 0x00400040, 0x00000040,}, |
| /* VDIN_MATRIX_RGBS_YUV601F */ |
| /* -16 0.348 0.683 0.133 0 */ |
| /* -16 -0.197 -0.385 0.582 128 */ |
| /* -16 0.582 -0.488 -0.094 128 */ |
| {0x07c007c0, 0x000007c0, 0x016402bb, 0x00881f36, 0x1e760254, 0x02541e0c, |
| 0x00001fa0, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601F_RGBS */ |
| /* 0 0.859 0 1.204 16 */ |
| /* -128 0.859 -0.295 -0.613 16 */ |
| /* -128 0.859 1.522 0 16 */ |
| {0x00000600, 0x00000600, 0x03700000, 0x04d10370, 0x1ed21d8c, 0x03700617, |
| 0x00000000, 0x00400040, 0x00000040,}, |
| /* VDIN_MATRIX_YUV601F_YUV601 */ |
| /* 0 0.859 0 0 16 */ |
| /* -128 0 0.878 0 128 */ |
| /* -128 0 0 0.878 128 */ |
| {0x00000600, 0x00000600, 0x03700000, 0x00000000, 0x03830000, 0x00000000, |
| 0x00000383, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601_YUV601F */ |
| /* -16 1.164 0 0 0 */ |
| /* -128 0 1.138 0 128 */ |
| /* -128 0 0 1.138 128 */ |
| {0x07c00600, 0x00000600, 0x04a80000, 0x00000000, 0x048d0000, 0x00000000, |
| 0x0000048d, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_RGB_YUV709 */ |
| /* 0 0.183 0.614 0.062 16 */ |
| /* 0 -0.101 -0.338 0.439 128 */ |
| /* 0 0.439 -0.399 -0.04 128 */ |
| {0x00000000, 0x00000000, 0x00bb0275, 0x003f1f99, 0x1ea601c2, 0x01c21e67, |
| 0x00001fd7, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709_RGB */ |
| /* -16 1.164 0 1.793 0 */ |
| /* -128 1.164 -0.213 -0.534 0 */ |
| /* -128 1.164 2.115 0 0 */ |
| {0x07c00600, 0x00000600, 0x04a80000, 0x072c04a8, 0x1f261ddd, 0x04a80876, |
| 0x00000000, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_YUV709_GBR */ |
| /* -16 1.164 -0.213 -0.534 0 */ |
| /* -128 1.164 2.115 0 0 */ |
| /* -128 1.164 0 1.793 0 */ |
| {0x07c00600, 0x00000600, 0x04a81f26, 0x1ddd04a8, 0x08760000, 0x04a80000, |
| 0x0000072c, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_YUV709_BRG */ |
| /* -16 1.164 2.115 0 0 */ |
| /* -128 1.164 0 1.793 0 */ |
| /* -128 1.164 -0.213 -0.534 0 */ |
| {0x07c00600, 0x00000600, 0x04a80876, 0x000004a8, 0x0000072c, 0x04a81f26, |
| 0x00001ddd, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_RGB_YUV709F */ |
| /* 0 0.213 0.715 0.072 0 */ |
| /* 0 -0.115 -0.385 0.5 128 */ |
| /* 0 0.5 -0.454 -0.046 128 */ |
| {0x00000000, 0x00000000, 0x00da02dc, 0x004a1f8a, 0x1e760200, 0x02001e2f, |
| 0x00001fd1, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709F_RGB */ |
| /* 0 1 0 1.575 0 */ |
| /* -128 1 -0.187 -0.468 0 */ |
| /* -128 1 1.856 0 0 */ |
| {0x00000600, 0x00000600, 0x04000000, 0x064d0400, 0x1f411e21, 0x0400076d, |
| 0x00000000, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_RGBS_YUV709 */ |
| /* -16 0.213 0.715 0.072 16 */ |
| /* -16 -0.118 -0.394 0.511 128 */ |
| /* -16 0.511 -0.464 -0.047 128 */ |
| {0x07c007c0, 0x000007c0, 0x00da02dc, 0x004a1f87, 0x1e6d020b, 0x020b1e25, |
| 0x00001fd0, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709_RGBS */ |
| /* -16 1 0 1.54 16 */ |
| /* -128 1 -0.183 -0.459 16 */ |
| /* -128 1 1.816 0 16 */ |
| {0x07c00600, 0x00000600, 0x04000000, 0x06290400, 0x1f451e2a, 0x04000744, |
| 0x00000000, 0x00400040, 0x00000040,}, |
| /* VDIN_MATRIX_RGBS_YUV709F */ |
| /* -16 0.248 0.833 0.084 0 */ |
| /* -16 -0.134 -0.448 0.582 128 */ |
| /* -16 0.582 -0.529 -0.054 128 */ |
| {0x07c007c0, 0x000007c0, 0x00fe0355, 0x00561f77, 0x1e350254, 0x02541de2, |
| 0x00001fc9, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709F_RGBS */ |
| /* 0 0.859 0 1.353 16 */ |
| /* -128 0.859 -0.161 -0.402 16 */ |
| /* -128 0.859 1.594 0 16 */ |
| {0x00000600, 0x00000600, 0x03700000, 0x05690370, 0x1f5b1e64, 0x03700660, |
| 0x00000000, 0x00400040, 0x00000040,}, |
| /* VDIN_MATRIX_YUV709F_YUV709 */ |
| /* 0 0.859 0 0 16 */ |
| /* -128 0 0.878 0 128 */ |
| /* -128 0 0 0.878 128 */ |
| {0x00000600, 0x00000600, 0x03700000, 0x00000000, 0x03830000, 0x00000000, |
| 0x00000383, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709_YUV709F */ |
| /* -16 1.164 0 0 0 */ |
| /* -128 0 1.138 0 128 */ |
| /* -128 0 0 1.138 128 */ |
| {0x07c00600, 0x00000600, 0x04a80000, 0x00000000, 0x048d0000, 0x00000000, |
| 0x0000048d, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601_YUV709 */ |
| /* -16 1 -0.115 -0.207 16 */ |
| /* -128 0 1.018 0.114 128 */ |
| /* -128 0 0.075 1.025 128 */ |
| {0x07c00600, 0x00000600, 0x04001f8a, 0x1f2c0000, 0x04120075, 0x0000004d, |
| 0x0000041a, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709_YUV601 */ |
| /* -16 1 0.100 0.192 16 */ |
| /* -128 0 0.990 -0.110 128 */ |
| /* -128 0 -0.072 0.984 128 */ |
| {0x07c00600, 0x00000600, 0x04000066, 0x00c50000, 0x03f61f8f, 0x00001fb6, |
| 0x000003f0, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601_YUV709F */ |
| /* -16 1.164 -0.134 -0.241 0 */ |
| /* -128 0 1.160 0.129 128 */ |
| /* -128 0 0.085 1.167 128 */ |
| {0x07c00600, 0x00000600, 0x04a81f77, 0x1f090000, 0x04a40084, 0x00000057, |
| 0x000004ab, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709F_YUV601 */ |
| /* 0 0.859 0.088 0.169 16 */ |
| /* -128 0 0.869 -0.097 128 */ |
| /* -128 0 -0.063 0.864 128 */ |
| {0x00000600, 0x00000600, 0x0370005a, 0x00ad0000, 0x037a1f9d, 0x00001fbf, |
| 0x00000375, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601F_YUV709 */ |
| /* 0 0.859 -0.101 -0.182 16 */ |
| /* -128 0 0.894 0.100 128 */ |
| /* -128 0 0.066 0.900 128 */ |
| {0x00000600, 0x00000600, 0x03701f99, 0x1f460000, 0x03930066, 0x00000044, |
| 0x0000039a, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709_YUV601F */ |
| /* -16 1.164 0.116 0.223 0 */ |
| /* -128 0 1.128 -0.126 128 */ |
| /* -128 0 -0.082 1.120 128 */ |
| {0x07c00600, 0x00000600, 0x04a80077, 0x00e40000, 0x04831f7f, 0x00001fac, |
| 0x0000047b, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV601F_YUV709F */ |
| /* 0 1 -0.118 -0.212 16 */ |
| /* -128 0 1.018 0.114 128 */ |
| /* -128 0 0.075 1.025 128 */ |
| {0x00000600, 0x00000600, 0x04001f87, 0x1f270000, 0x04120075, 0x0000004d, |
| 0x0000041a, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV709F_YUV601F */ |
| /* 0 1 0.102 0.196 0 */ |
| /* -128 0 0.990 -0.111 128 */ |
| /* -128 0 -0.072 0.984 128 */ |
| {0x00000600, 0x00000600, 0x04000068, 0x00c90000, 0x03f61f8e, 0x00001fb6, |
| 0x000003f0, 0x00000200, 0x00000200,}, |
| /* VDIN_MATRIX_RGBS_RGB */ |
| /* -16 1.164 0 0 0 */ |
| /* -16 0 1.164 0 0 */ |
| /* -16 0 0 1.164 0 */ |
| {0x07c007c0, 0x000007c0, 0x04a80000, 0x00000000, 0x04a80000, 0x00000000, |
| 0x000004a8, 0x00000000, 0x00000000,}, |
| /* VDIN_MATRIX_RGB_RGBS */ |
| /* 0 0.859 0 0 16 */ |
| /* 0 0 0.859 0 16 */ |
| /* 0 0 0 0.859 16 */ |
| {0x00000000, 0x00000000, 0x03700000, 0x00000000, 0x03700000, 0x00000000, |
| 0x00000370, 0x00400040, 0x00000040,}, |
| /* VDIN_MATRIX_2020RGB_YUV2020 */ |
| /* 0 0.224732 0.580008 0.050729 16 */ |
| /* 0 -0.122176 -0.315324 0.437500 128 */ |
| /* 0 0.437500 -0.402312 -0.035188 128 */ |
| {0x00000000, 0x00000000, 0x00e60252, 0x00341f84, 0x1ebe01c0, 0x01c01e65, |
| 0x00001fdd, 0x00400200, 0x00000200,}, |
| /* VDIN_MATRIX_YUV2020F_YUV2020 */ |
| /* 0 0.859 0 0 16 */ |
| /* -128 0 0.878 0 128 */ |
| /* -128 0 0 0.878 128 */ |
| {0x00000600, 0x00000600, 0x03700000, 0x00000000, 0x03830000, 0x00000000, |
| 0x00000383, 0x00400200, 0x00000200,}, |
| }; |
| |
| /***************************Local function**********************************/ |
| |
| /*set csc idx conter to ranage |
| * parameters: |
| * a.devp |
| * return |
| * 0: limit |
| * 1: full |
| */ |
| u32 vdin_matrix_range_chk(struct vdin_dev_s *devp) |
| { |
| enum tvin_color_fmt_range_e fmt_range; |
| enum vdin_format_convert_e format_convert; |
| |
| fmt_range = devp->prop.color_fmt_range; |
| format_convert = devp->format_convert; |
| switch (devp->csc_idx) { |
| case VDIN_MATRIX_YUV601F_RGB: |
| case VDIN_MATRIX_RGBS_YUV601F: |
| case VDIN_MATRIX_YUV601_YUV601F: |
| case VDIN_MATRIX_YUV709_RGB: |
| case VDIN_MATRIX_YUV709_GBR: |
| case VDIN_MATRIX_YUV709_BRG: |
| case VDIN_MATRIX_RGB_YUV709F: |
| case VDIN_MATRIX_YUV709F_RGB: |
| case VDIN_MATRIX_RGBS_YUV709F: |
| case VDIN_MATRIX_YUV709_YUV709F: |
| case VDIN_MATRIX_YUV601_YUV709F: |
| case VDIN_MATRIX_YUV601F_YUV709F: |
| case VDIN_MATRIX_YUV709F_YUV601F: |
| case VDIN_MATRIX_YUV709_YUV601F: |
| case VDIN_MATRIX_RGBS_RGB: |
| return 1; |
| |
| case VDIN_MATRIX_NULL: |
| if (format_convert == VDIN_FORMAT_CONVERT_RGB_RGB) |
| if (fmt_range == TVIN_FMT_RANGE_NULL || |
| fmt_range == TVIN_RGB_FULL) |
| return 1; |
| else |
| return 0; |
| else |
| if (fmt_range == TVIN_RGB_FULL || |
| fmt_range == TVIN_YUV_FULL) |
| return 1; |
| else |
| return 0; |
| case VDIN_MATRIX_XXX_YUV601_BLACK: |
| case VDIN_MATRIX_RGB_YUV601: |
| case VDIN_MATRIX_GBR_YUV601: |
| case VDIN_MATRIX_BRG_YUV601: |
| case VDIN_MATRIX_RGBS_YUV601: |
| case VDIN_MATRIX_YUV601_RGBS: |
| case VDIN_MATRIX_YUV601F_RGBS: |
| case VDIN_MATRIX_YUV601F_YUV601: |
| case VDIN_MATRIX_RGB_YUV709: |
| case VDIN_MATRIX_RGBS_YUV709: |
| case VDIN_MATRIX_YUV709_RGBS: |
| case VDIN_MATRIX_YUV709F_RGBS: |
| case VDIN_MATRIX_YUV709F_YUV709: |
| case VDIN_MATRIX_YUV601_YUV709: |
| case VDIN_MATRIX_YUV709_YUV601: |
| case VDIN_MATRIX_YUV709F_YUV601: |
| case VDIN_MATRIX_YUV601F_YUV709: |
| case VDIN_MATRIX_RGB_RGBS: |
| case VDIN_MATRIX_RGB2020_YUV2020: |
| default: |
| return 0; |
| } |
| } |
| |
| /* set format_convert |
| * base on parameters: |
| * a.color_format |
| * b.dest_cfmt |
| */ |
| void vdin_get_format_convert(struct vdin_dev_s *devp) |
| { |
| enum vdin_format_convert_e format_convert; |
| unsigned int port = devp->parm.port; |
| unsigned int scan_mod = devp->fmt_info_p->scan_mode; |
| unsigned int manual_md = (devp->flags & VDIN_FLAG_MANUAL_CONVERSION); |
| |
| if (IS_HDMI_SRC(port) && !manual_md) |
| devp->prop.dest_cfmt = TVIN_COLOR_FMT_MAX; |
| |
| #ifdef VDIN_BRINGUP_BYPASS_COLOR_CNVT |
| devp->prop.dest_cfmt = devp->prop.color_format; |
| #endif |
| |
| if (devp->prop.color_format == devp->prop.dest_cfmt) { |
| switch (devp->prop.color_format) { |
| case TVIN_YUV422: |
| case TVIN_YUYV422: |
| case TVIN_YVYU422: |
| case TVIN_UYVY422: |
| case TVIN_VYUY422: |
| format_convert = VDIN_FORMAT_CONVERT_YUV_YUV422; |
| break; |
| case TVIN_YUV444: |
| format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444; |
| break; |
| case TVIN_RGB444: |
| format_convert = VDIN_FORMAT_CONVERT_RGB_RGB; |
| break; |
| default: |
| format_convert = VDIN_FORMAT_CONVERT_MAX; |
| break; |
| } |
| } else { |
| switch (devp->prop.color_format) { |
| case TVIN_YUV422: |
| case TVIN_YUYV422: |
| case TVIN_YVYU422: |
| case TVIN_UYVY422: |
| case TVIN_VYUY422: |
| if (devp->prop.dest_cfmt == TVIN_NV21) { |
| format_convert = VDIN_FORMAT_CONVERT_YUV_NV21; |
| } else if (devp->prop.dest_cfmt == TVIN_NV12) { |
| format_convert = VDIN_FORMAT_CONVERT_YUV_NV12; |
| } else { |
| if (manual_md && |
| devp->prop.dest_cfmt == TVIN_RGB444) |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_RGB; |
| else if (manual_md && |
| devp->prop.dest_cfmt == TVIN_YUV444) |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_YUV444; |
| else |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_YUV422; |
| } |
| break; |
| case TVIN_YUV444: |
| if (IS_HDMI_SRC(port) && |
| scan_mod == TVIN_SCAN_MODE_PROGRESSIVE) { |
| if (vdin_pc_mode) |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_YUV444; |
| else |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_YUV422; |
| } else if (devp->prop.dest_cfmt == TVIN_NV21) { |
| format_convert = VDIN_FORMAT_CONVERT_YUV_NV21; |
| } else if (devp->prop.dest_cfmt == TVIN_NV12) { |
| format_convert = VDIN_FORMAT_CONVERT_YUV_NV12; |
| } else { |
| if (manual_md && |
| devp->prop.dest_cfmt == TVIN_RGB444) |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_RGB; |
| else if (manual_md && |
| devp->prop.dest_cfmt == TVIN_YUV422) |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_YUV422; |
| else if (manual_md && |
| devp->prop.dest_cfmt == TVIN_YUV444) |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_YUV444; |
| else |
| format_convert = |
| VDIN_FORMAT_CONVERT_YUV_YUV422; |
| } |
| break; |
| case TVIN_RGB444: |
| if (IS_HDMI_SRC(port) && |
| scan_mod == TVIN_SCAN_MODE_PROGRESSIVE) { |
| if (vdin_pc_mode) |
| format_convert = |
| VDIN_FORMAT_CONVERT_RGB_RGB; |
| else |
| format_convert = |
| VDIN_FORMAT_CONVERT_RGB_YUV422; |
| } else if (devp->prop.dest_cfmt == TVIN_NV21) { |
| format_convert = VDIN_FORMAT_CONVERT_RGB_NV21; |
| } else if (devp->prop.dest_cfmt == TVIN_NV12) { |
| format_convert = VDIN_FORMAT_CONVERT_RGB_NV12; |
| } else { |
| if (manual_md && |
| devp->prop.dest_cfmt == TVIN_RGB444) |
| format_convert = |
| VDIN_FORMAT_CONVERT_RGB_RGB; |
| else if (manual_md && |
| devp->prop.dest_cfmt == TVIN_YUV422) |
| format_convert = |
| VDIN_FORMAT_CONVERT_RGB_YUV422; |
| else if (manual_md && |
| devp->prop.dest_cfmt == TVIN_YUV444) |
| format_convert = |
| VDIN_FORMAT_CONVERT_RGB_YUV444; |
| else |
| format_convert = |
| VDIN_FORMAT_CONVERT_RGB_YUV422; |
| } |
| break; |
| default: |
| format_convert = VDIN_FORMAT_CONVERT_MAX; |
| break; |
| } |
| } |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| if (vdin_is_dolby_signal_in(devp)) { |
| /* Is dolby vision signal input */ |
| /* |
| *if (devp->dv.low_latency) { |
| * if (devp->prop.color_format == TVIN_YUV422) { |
| * format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444; |
| * } else if (devp->prop.color_format == TVIN_RGB444) { |
| * format_convert = VDIN_FORMAT_CONVERT_RGB_RGB; |
| * } |
| *} else { |
| * format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444; |
| *} |
| */ |
| if (devp->prop.color_format == TVIN_YUV422) { |
| /*rx will tunneled to 444*/ |
| format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444; |
| } else if (devp->prop.color_format == TVIN_RGB444) { |
| format_convert = VDIN_FORMAT_CONVERT_RGB_RGB; |
| } else { |
| format_convert = VDIN_FORMAT_CONVERT_YUV_YUV444; |
| } |
| } |
| #endif |
| /*hw test:vdin de-tunnel to 422 12bit*/ |
| //if (devp->dtdata->ipt444_to_422_12bit && vdin_cfg_444_to_422_wmif_en) |
| // format_convert = VDIN_FORMAT_CONVERT_YUV_YUV422; |
| |
| devp->format_convert = format_convert; |
| if (vdin_is_convert_to_422(format_convert)) |
| devp->mif_fmt = MIF_FMT_YUV422; |
| else if (vdin_is_convert_to_444(format_convert)) |
| devp->mif_fmt = MIF_FMT_YUV444; |
| else if (vdin_is_convert_to_nv21(format_convert)) |
| devp->mif_fmt = MIF_FMT_NV12_21; |
| else |
| devp->mif_fmt = MIF_FMT_YUV422; |
| pr_info("%s pcmd:%d, man_md:0x%x, cfmt:%d, dstcfmt:%d convert md:%d mif_fmt:%d\n", __func__, |
| vdin_pc_mode, manual_md, |
| devp->prop.color_format, devp->prop.dest_cfmt, format_convert, |
| devp->mif_fmt); |
| } |
| |
| /*functiong: |
| * format_convert |
| * based on dest_cfmt |
| */ |
| enum vdin_format_convert_e |
| vdin_get_format_convert_matrix0(struct vdin_dev_s *devp) |
| { |
| enum vdin_format_convert_e format_convert = VDIN_FORMAT_CONVERT_MAX; |
| |
| switch (devp->format_convert) { |
| case VDIN_FORMAT_CONVERT_YUV_NV21: |
| case VDIN_FORMAT_CONVERT_RGB_NV21: |
| format_convert = VDIN_FORMAT_CONVERT_RGB_NV21; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_NV12: |
| case VDIN_FORMAT_CONVERT_RGB_NV12: |
| format_convert = VDIN_FORMAT_CONVERT_RGB_NV12; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_RGB: |
| case VDIN_FORMAT_CONVERT_RGB_RGB: |
| format_convert = VDIN_FORMAT_CONVERT_RGB_RGB; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_YUV444: |
| case VDIN_FORMAT_CONVERT_RGB_YUV444: |
| format_convert = VDIN_FORMAT_CONVERT_RGB_YUV444; |
| break; |
| default: |
| format_convert = VDIN_FORMAT_CONVERT_RGB_YUV422; |
| break; |
| } |
| |
| return format_convert; |
| } |
| |
| /*functiong: |
| * format_convert |
| * based on color_cfmt |
| */ |
| enum vdin_format_convert_e |
| vdin_get_format_convert_matrix1(struct vdin_dev_s *devp) |
| { |
| enum vdin_format_convert_e format_convert = VDIN_FORMAT_CONVERT_MAX; |
| |
| switch (devp->prop.color_format) { |
| case TVIN_YUV422: |
| case TVIN_YUYV422: |
| case TVIN_YVYU422: |
| case TVIN_UYVY422: |
| case TVIN_VYUY422: |
| case TVIN_YUV444: |
| format_convert = VDIN_FORMAT_CONVERT_YUV_RGB; |
| break; |
| case TVIN_RGB444: |
| format_convert = VDIN_FORMAT_CONVERT_RGB_RGB; |
| break; |
| default: |
| format_convert = VDIN_FORMAT_CONVERT_MAX; |
| break; |
| } |
| return format_convert; |
| } |
| |
| /*get prob of r/g/b |
| * r 9:0 |
| * g 19:10 |
| * b 29:20 |
| */ |
| void vdin_prob_get_rgb(unsigned int offset, |
| unsigned int *r, unsigned int *g, unsigned int *b) |
| { |
| *b = rgb_info_b = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, |
| COMPONENT2_PROBE_COLOR_BIT, |
| COMPONENT0_PROBE_COLOR_WID); |
| *g = rgb_info_g = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, |
| COMPONENT1_PROBE_COLOR_BIT, |
| COMPONENT1_PROBE_COLOR_WID); |
| *r = rgb_info_r = rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, |
| COMPONENT0_PROBE_COLOR_BIT, |
| COMPONENT0_PROBE_COLOR_WID); |
| } |
| |
| void vdin_prob_get_yuv(unsigned int offset, |
| unsigned int *rgb_yuv0, |
| unsigned int *rgb_yuv1, |
| unsigned int *rgb_yuv2) |
| { |
| *rgb_yuv0 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, |
| COMPONENT2_PROBE_COLOR_BIT, |
| COMPONENT2_PROBE_COLOR_WID) << 8) >> 10); |
| *rgb_yuv1 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, |
| COMPONENT1_PROBE_COLOR_BIT, |
| COMPONENT1_PROBE_COLOR_WID) << 8) >> 10); |
| *rgb_yuv2 = ((rd_bits(offset, VDIN_MATRIX_PROBE_COLOR, |
| COMPONENT0_PROBE_COLOR_BIT, |
| COMPONENT0_PROBE_COLOR_WID) << 8) >> 10); |
| } |
| |
| void vdin_prob_set_before_or_after_mat(unsigned int offset, |
| unsigned int x, struct vdin_dev_s *devp) |
| { |
| if (x != 0 && x != 1) |
| return; |
| /* 1:probe pixel data after matrix */ |
| wr_bits(offset, VDIN_MATRIX_CTRL, x, |
| VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID); |
| } |
| |
| void vdin_prob_matrix_sel(unsigned int offset, |
| unsigned int sel, struct vdin_dev_s *devp) |
| { |
| unsigned int x; |
| |
| x = sel & 0x03; |
| /* 1:select matrix 1 */ |
| wr_bits(offset, VDIN_MATRIX_CTRL, x, |
| VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID); |
| } |
| |
| /* this function set flowing parameters: |
| *a.rgb_info_x b.rgb_info_y |
| *debug usage: |
| *echo rgb_xy x y > /sys/class/vdin/vdinx/attr |
| */ |
| void vdin_prob_set_xy(unsigned int offset, |
| unsigned int x, unsigned int y, struct vdin_dev_s *devp) |
| { |
| /* set position */ |
| rgb_info_x = x; |
| if (devp->fmt_info_p->scan_mode == TVIN_SCAN_MODE_INTERLACED) |
| rgb_info_y = y / 2; |
| else |
| rgb_info_y = y; |
| /* #if defined(VDIN_V1) */ |
| wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_y, |
| PROBE_POX_Y_BIT, PROBE_POX_Y_WID); |
| wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_x, |
| PROBE_POS_X_BIT, PROBE_POS_X_WID); |
| } |
| |
| /*function: |
| * 1.set meas mux based on port_: |
| * 0x01: /mpeg/ 0x10: /CVBS/ |
| * 0x02: /bt656/ 0x20: /SVIDEO/ |
| * 0x04: /VGA/ 0x40: /hdmi/ |
| * 0x08: /COMPONENT/ 0x80: /dvin/ |
| * 0xc0:/viu/ 0x100:/dtv mipi/ |
| * 0x200:/isp/ |
| * 2.set VDIN_MEAS in accumulation mode |
| * 3.set VPP_VDO_MEAS in accumulation mode |
| * 4.set VPP_MEAS in latch-on-falling-edge mode |
| * 5.set VDIN_MEAS mux |
| * 6.manual reset VDIN_MEAS & VPP_VDO_MEAS at the same time |
| */ |
| static void vdin_set_meas_mux(unsigned int offset, enum tvin_port_e port_, |
| enum bt_path_e bt_path) |
| { |
| /* unsigned int offset = devp->addr_offset; */ |
| unsigned int meas_mux = MEAS_MUX_NULL; |
| |
| switch ((port_) >> 8) { |
| case 0x01: /* mpeg */ |
| meas_mux = MEAS_MUX_NULL; |
| break; |
| case 0x02: /* bt656 , txl and txlx do not support bt656 */ |
| if ((is_meson_gxbb_cpu() || is_meson_gxtvbb_cpu()) && |
| bt_path == BT_PATH_GPIO_B) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| meas_mux = MEAS_MUX_656_B; |
| #endif |
| } |
| else if ((is_meson_gxl_cpu() || is_meson_gxm_cpu() || |
| cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) && |
| (bt_path == BT_PATH_GPIO)) |
| meas_mux = MEAS_MUX_656; |
| else |
| pr_info("cpu not define or do not support bt656"); |
| break; |
| case 0x04: /* VGA */ |
| meas_mux = MEAS_MUX_TVFE; |
| break; |
| case 0x08: /* COMPONENT */ |
| meas_mux = MEAS_MUX_TVFE; |
| break; |
| case 0x10: /* CVBS */ |
| meas_mux = MEAS_MUX_CVD2; |
| break; |
| case 0x20: /* SVIDEO */ |
| meas_mux = MEAS_MUX_CVD2; |
| break; |
| case 0x40: /* hdmi */ |
| meas_mux = MEAS_MUX_HDMI; |
| break; |
| case 0x80: /* dvin */ |
| meas_mux = MEAS_MUX_DVIN; |
| break; |
| case 0xa0:/* viu */ |
| meas_mux = MEAS_MUX_VIU1; |
| break; |
| case 0xc0:/* viu */ |
| meas_mux = MEAS_MUX_VIU2; |
| break; |
| case 0x100:/* dtv mipi */ |
| meas_mux = MEAS_MUX_DTV; |
| break; |
| case 0x200:/* isp */ |
| meas_mux = MEAS_MUX_ISP; |
| break; |
| default: |
| meas_mux = MEAS_MUX_NULL; |
| break; |
| } |
| /* set VDIN_MEAS in accumulation mode */ |
| wr_bits(offset, VDIN_MEAS_CTRL0, 1, |
| MEAS_VS_TOTAL_CNT_EN_BIT, MEAS_VS_TOTAL_CNT_EN_WID); |
| /* set VPP_VDO_MEAS in accumulation mode */ |
| wr_bits(0, VPP_VDO_MEAS_CTRL, 1, 8, 1); |
| /* set VPP_MEAS in latch-on-falling-edge mode */ |
| wr_bits(0, VPP_VDO_MEAS_CTRL, 1, 9, 1); |
| /* set VDIN_MEAS mux */ |
| wr_bits(offset, VDIN_MEAS_CTRL0, meas_mux, |
| MEAS_HS_VS_SEL_BIT, MEAS_HS_VS_SEL_WID); |
| /* manual reset VDIN_MEAS & VPP_VDO_MEAS at the same time, |
| * rst = 1 & 0 |
| */ |
| wr_bits(offset, VDIN_MEAS_CTRL0, 1, MEAS_RST_BIT, MEAS_RST_WID); |
| W_VCBUS_BIT(VPP_VDO_MEAS_CTRL, 1, 10, 1); |
| wr_bits(offset, VDIN_MEAS_CTRL0, 0, MEAS_RST_BIT, MEAS_RST_WID); |
| W_VCBUS_BIT(VPP_VDO_MEAS_CTRL, 0, 10, 1); |
| } |
| |
| /*function:set VDIN_COM_CTRL0 |
| *Bit 3:0 vdin selection, |
| * 1: mpeg_in from dram, 2: bt656 input,3: component input |
| * 4: tvdecoder input, 5: hdmi rx input,6: digtial video input, |
| * 7: loopback from Viu1, 8: MIPI. |
| */ |
| /* Bit 7:6, component0 output switch, |
| * 00: select component0 in,01: select component1 in, |
| * 10: select component2 in |
| */ |
| /* Bit 9:8, component1 output switch, |
| * 00: select component0 in, |
| * 01: select component1 in, 10: select component2 in |
| */ |
| /* Bit 11:10, component2 output switch, |
| * 00: select component0 in, 01: select component1 in, |
| * 10: select component2 in |
| */ |
| |
| /* attention:new add for bt656 |
| * 0x02: /bt656/ |
| a.BT_PATH_GPIO: gxl & gxm & g12a |
| b.BT_PATH_GPIO_B:gxtvbb & gxbb |
| c.txl and txlx don't support bt656 |
| */ |
| void vdin_set_top(struct vdin_dev_s *devp, unsigned int offset, |
| enum tvin_port_e port, |
| enum tvin_color_fmt_e input_cfmt, unsigned int h, |
| enum bt_path_e bt_path) |
| { |
| /* unsigned int offset = devp->addr_offset; */ |
| unsigned int vdin_mux = VDIN_MUX_NULL; |
| unsigned int vdin_data_bus_0 = VDIN_MAP_Y_G; |
| unsigned int vdin_data_bus_1 = VDIN_MAP_BPB; |
| unsigned int vdin_data_bus_2 = VDIN_MAP_RCR; |
| |
| /* [28:16] top.input_width_m1 = h - 1 */ |
| /* [12: 0] top.output_width_m1 = h - 1 */ |
| wr(offset, VDIN_WIDTHM1I_WIDTHM1O, ((h - 1) << 16) | (h - 1)); |
| switch (port >> 8) { |
| case 0x01: /* mpeg */ |
| vdin_mux = VDIN_MUX_MPEG; |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe0, |
| VDI1_ASFIFO_CTRL_BIT, VDI1_ASFIFO_CTRL_WID); |
| break; |
| case 0x02: /* bt656 ,txl and txlx do not support bt656 */ |
| if ((is_meson_gxbb_cpu() || is_meson_gxtvbb_cpu()) && |
| bt_path == BT_PATH_GPIO_B) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| vdin_mux = VDIN_MUX_656_B; |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, |
| VDI9_ASFIFO_CTRL_BIT, VDI_ASFIFO_CTRL_WID); |
| #endif |
| } else if ((is_meson_gxm_cpu() || is_meson_gxl_cpu() || |
| cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) && |
| (bt_path == BT_PATH_GPIO)) { |
| vdin_mux = VDIN_MUX_656; |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4, |
| VDI1_ASFIFO_CTRL_BIT, VDI1_ASFIFO_CTRL_WID); |
| } else { |
| pr_info("cpu not define or do not support bt656"); |
| } |
| break; |
| case 0x04: /* VGA */ |
| vdin_mux = VDIN_MUX_TVFE; |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4, |
| VDI2_ASFIFO_CTRL_BIT, VDI2_ASFIFO_CTRL_WID); |
| /* In the order of RGB for further |
| * RGB->YUV601 or RGB->YUV709 conversion |
| */ |
| vdin_data_bus_0 = VDIN_MAP_RCR; |
| vdin_data_bus_1 = VDIN_MAP_Y_G; |
| vdin_data_bus_2 = VDIN_MAP_BPB; |
| break; |
| case 0x08: /* COMPONENT */ |
| vdin_mux = VDIN_MUX_TVFE; |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, 0xe4, |
| VDI2_ASFIFO_CTRL_BIT, VDI2_ASFIFO_CTRL_WID); |
| break; |
| case 0x10: /* CVBS */ |
| vdin_mux = VDIN_MUX_CVD2; |
| wr_bits(offset, VDIN_ASFIFO_CTRL1, 0xe4, |
| VDI3_ASFIFO_CTRL_BIT, VDI3_ASFIFO_CTRL_WID); |
| break; |
| case 0x20: /* SVIDEO */ |
| vdin_mux = VDIN_MUX_CVD2; |
| wr_bits(offset, VDIN_ASFIFO_CTRL1, 0xe4, |
| VDI3_ASFIFO_CTRL_BIT, VDI3_ASFIFO_CTRL_WID); |
| break; |
| case 0x40: /* hdmi */ |
| vdin_mux = VDIN_MUX_HDMI; |
| wr_bits(offset, VDIN_ASFIFO_CTRL1, 0xe4, |
| VDI4_ASFIFO_CTRL_BIT, VDI4_ASFIFO_CTRL_WID); |
| |
| /*reset top afifo for green screen when enter the channel*/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { |
| wr_bits(offset, VPU_SW_RESET, 1, 26, 1); |
| wr_bits(offset, VPU_SW_RESET, 0, 26, 1); |
| } |
| |
| break; |
| case 0x80: /* dvin */ |
| vdin_mux = VDIN_MUX_DVIN; |
| wr_bits(offset, VDIN_ASFIFO_CTRL2, 0xe4, |
| VDI5_ASFIFO_CTRL_BIT, VDI5_ASFIFO_CTRL_WID); |
| break; |
| case 0xa0:/* viu1 */ |
| if (port >= TVIN_PORT_VIU1_WB0_VD1 && port <= TVIN_PORT_VIU1_WB0_POST_BLEND) |
| vdin_mux = VDIN_MUX_VIU1_WB0; |
| else if ((port >= TVIN_PORT_VIU1_WB1_VD1) && |
| (port <= TVIN_PORT_VIU1_WB1_POST_BLEND)) |
| vdin_mux = VDIN_MUX_VIU1_WB1; |
| |
| if (port != TVIN_PORT_VIU1) { |
| if (vdin_mux == VDIN_MUX_VIU1_WB0) |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, |
| VDI6_ASFIFO_CTRL_BIT, VDI_ASFIFO_CTRL_WID); |
| else if (vdin_mux == VDIN_MUX_VIU1_WB1) |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, |
| VDI8_ASFIFO_CTRL_BIT, VDI_ASFIFO_CTRL_WID); |
| } else { |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xd4, |
| VDI6_ASFIFO_CTRL_BIT, |
| VDI_ASFIFO_CTRL_WID); |
| else |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4, |
| VDI6_ASFIFO_CTRL_BIT, |
| VDI_ASFIFO_CTRL_WID); |
| } |
| break; |
| |
| case 0xc0: /* viu2 */ |
| /* don't need set this actually, need confirm by experiment */ |
| vdin_mux = VDIN_MUX_VIU1_WB1; |
| if (port != TVIN_PORT_VIU2) { |
| if (devp->prop.polarity_vs == 0) /* positive */ |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, |
| VDI8_ASFIFO_CTRL_BIT, |
| VDI_ASFIFO_CTRL_WID); |
| else if (devp->prop.polarity_vs == 1) /* negative */ |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4, |
| VDI8_ASFIFO_CTRL_BIT, |
| VDI_ASFIFO_CTRL_WID); |
| } else { |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xd4, |
| VDI6_ASFIFO_CTRL_BIT, |
| VDI_ASFIFO_CTRL_WID); |
| else |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xf4, |
| VDI6_ASFIFO_CTRL_BIT, |
| VDI_ASFIFO_CTRL_WID); |
| } |
| break; |
| |
| case 0x100:/* mipi in mybe need modify base on truth */ |
| vdin_mux = VDIN_MUX_MIPI; |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe0, |
| VDI7_ASFIFO_CTRL_BIT, VDI_ASFIFO_CTRL_WID); |
| break; |
| case 0x200: |
| vdin_mux = VDIN_MUX_ISP; |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0xe4, |
| VDI8_ASFIFO_CTRL_BIT, VDI_ASFIFO_CTRL_WID); |
| break; |
| default: |
| vdin_mux = VDIN_MUX_NULL; |
| break; |
| } |
| |
| switch (input_cfmt) { |
| case TVIN_YVYU422: |
| vdin_data_bus_1 = VDIN_MAP_RCR; |
| vdin_data_bus_2 = VDIN_MAP_BPB; |
| break; |
| case TVIN_UYVY422: |
| vdin_data_bus_0 = VDIN_MAP_BPB; |
| vdin_data_bus_1 = VDIN_MAP_RCR; |
| vdin_data_bus_2 = VDIN_MAP_Y_G; |
| break; |
| case TVIN_VYUY422: |
| vdin_data_bus_0 = VDIN_MAP_BPB; |
| vdin_data_bus_1 = VDIN_MAP_RCR; |
| vdin_data_bus_2 = VDIN_MAP_Y_G; |
| break; |
| case TVIN_RGB444: |
| /*RGB mapping*/ |
| if (devp->set_canvas_manual == 1) { |
| vdin_data_bus_0 = VDIN_MAP_RCR; |
| vdin_data_bus_1 = VDIN_MAP_BPB; |
| vdin_data_bus_2 = VDIN_MAP_Y_G; |
| } |
| break; |
| default: |
| break; |
| } |
| wr_bits(offset, VDIN_COM_CTRL0, vdin_mux, VDIN_SEL_BIT, VDIN_SEL_WID); |
| wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_0, |
| COMP0_OUT_SWT_BIT, COMP0_OUT_SWT_WID); |
| wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_1, |
| COMP1_OUT_SWT_BIT, COMP1_OUT_SWT_WID); |
| wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_2, |
| COMP2_OUT_SWT_BIT, COMP2_OUT_SWT_WID); |
| } |
| |
| /*this function will set the bellow parameters of devp: |
| *1.h_active |
| *2.v_active |
| */ |
| void vdin_set_decimation(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int new_clk = 0; |
| bool decimation_in_frontend = false; |
| |
| if (devp->prop.decimation_ratio & HDMI_DE_REPEAT_DONE_FLAG) { |
| decimation_in_frontend = true; |
| if (vdin_ctl_dbg) |
| pr_info("decimation_in_frontend\n"); |
| } |
| devp->prop.decimation_ratio = devp->prop.decimation_ratio & |
| DECIMATION_REAL_RANGE; |
| |
| new_clk = devp->fmt_info_p->pixel_clk / |
| (devp->prop.decimation_ratio + 1); |
| if (vdin_ctl_dbg) |
| pr_info("%s decimation_ratio=%u,new_clk=%u.\n", |
| __func__, devp->prop.decimation_ratio, new_clk); |
| |
| devp->h_active = devp->fmt_info_p->h_active / |
| (devp->prop.decimation_ratio + 1); |
| devp->v_active = devp->fmt_info_p->v_active; |
| |
| if (devp->prop.decimation_ratio && !decimation_in_frontend) { |
| /* ratio */ |
| wr_bits(offset, VDIN_ASFIFO_CTRL2, |
| devp->prop.decimation_ratio, |
| ASFIFO_DECIMATION_NUM_BIT, ASFIFO_DECIMATION_NUM_WID); |
| /* en */ |
| wr_bits(offset, VDIN_ASFIFO_CTRL2, 1, |
| ASFIFO_DECIMATION_DE_EN_BIT, |
| ASFIFO_DECIMATION_DE_EN_WID); |
| /* manual reset, rst = 1 & 0 */ |
| wr_bits(offset, VDIN_ASFIFO_CTRL2, 1, |
| ASFIFO_DECIMATION_SYNC_WITH_DE_BIT, |
| ASFIFO_DECIMATION_SYNC_WITH_DE_WID); |
| wr_bits(offset, VDIN_ASFIFO_CTRL2, 0, |
| ASFIFO_DECIMATION_SYNC_WITH_DE_BIT, |
| ASFIFO_DECIMATION_SYNC_WITH_DE_WID); |
| } |
| |
| /* output_width_m1 */ |
| wr_bits(offset, VDIN_INTF_WIDTHM1, (devp->h_active - 1), |
| VDIN_INTF_WIDTHM1_BIT, VDIN_INTF_WIDTHM1_WID); |
| if (vdin_ctl_dbg) |
| pr_info("%s: h_active=%u, v_active=%u\n", |
| __func__, devp->h_active, devp->v_active); |
| } |
| |
| void vdin_fix_nonstd_vsync(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| /* prevent vdin enter hold status by mass vsync from hdmi rx |
| * phenomenon: not wr any data to DDR, picture stuck |
| */ |
| if (devp->dtdata->hw_ver >= VDIN_HW_TM2_B) { |
| wr_bits(offset, VDIN_WR_URGENT_CTRL, 1, |
| WR_DONE_LAST_SEL_BIT, WR_DONE_LAST_SEL_WID); |
| /*wr_bits(offset, VDIN_WR_URGENT_CTRL, 1, BVALID_EN_BIT, 1);*/ |
| } else if (devp->dtdata->hw_ver == VDIN_HW_ORG) { |
| /* tm2 revA is 0x12be[9]*/ |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) |
| wr_bits(offset, 0x12be, 1, 9, 1); |
| else /* others are 0x121c[25] */ |
| wr_bits(offset, VDIN_INTF_WIDTHM1, 1, |
| VDIN_WR_MIF_BURST_LAST_SEL_BIT, |
| VDIN_WR_MIF_BURST_LAST_SEL_WID); |
| } |
| } |
| |
| /*this function will set the bellow parameters of devp: |
| * 1.h_active |
| * 2.v_active |
| * set VDIN_WIN_H_START_END |
| * Bit 28:16 input window H start |
| * Bit 12:0 input window H end |
| * set VDIN_WIN_V_START_END |
| * Bit 28:16 input window V start |
| * Bit 12:0 input window V start |
| */ |
| void vdin_set_cutwin(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int he = 0, ve = 0; |
| |
| if ((devp->prop.hs || devp->prop.he || |
| devp->prop.vs || devp->prop.ve) && |
| devp->h_active > (devp->prop.hs + devp->prop.he) && |
| devp->v_active > (devp->prop.vs + devp->prop.ve)) { |
| devp->h_active -= (devp->prop.he + devp->prop.hs); |
| devp->v_active -= (devp->prop.ve + devp->prop.vs); |
| he = devp->prop.hs + devp->h_active - 1; |
| ve = devp->prop.vs + devp->v_active - 1; |
| |
| wr(offset, VDIN_WIN_H_START_END, |
| (devp->prop.hs << INPUT_WIN_H_START_BIT) | |
| (he << INPUT_WIN_H_END_BIT)); |
| wr(offset, VDIN_WIN_V_START_END, |
| (devp->prop.vs << INPUT_WIN_V_START_BIT) | |
| (ve << INPUT_WIN_V_END_BIT)); |
| wr_bits(offset, VDIN_COM_CTRL0, 1, |
| INPUT_WIN_SEL_EN_BIT, INPUT_WIN_SEL_EN_WID); |
| if (vdin_ctl_dbg) |
| pr_info("%s enable cutwin hs=%d, he=%d, vs=%d, ve=%d\n", |
| __func__, |
| devp->prop.hs, devp->prop.he, |
| devp->prop.vs, devp->prop.ve); |
| } else { |
| wr(offset, VDIN_WIN_H_START_END, 0); |
| wr(offset, VDIN_WIN_V_START_END, 0); |
| wr_bits(offset, VDIN_COM_CTRL0, 0, |
| INPUT_WIN_SEL_EN_BIT, INPUT_WIN_SEL_EN_WID); |
| if (vdin_ctl_dbg) |
| pr_info("%s disable cutwin!!! hs=%d, he=%d, vs=%d, ve=%d\n", |
| __func__, |
| devp->prop.hs, devp->prop.he, |
| devp->prop.vs, devp->prop.ve); |
| } |
| if (vdin_ctl_dbg) |
| pr_info("%s: h_active=%d, v_active=%d, hs:%u, he:%u, vs:%u, ve:%u\n", |
| __func__, devp->h_active, devp->v_active, |
| devp->prop.hs, devp->prop.he, |
| devp->prop.vs, devp->prop.ve); |
| } |
| |
| /*adjust the brightness for txhd hardware snow*/ |
| void vdin_adjust_tvafesnow_brightness(void) |
| { |
| enum vdin_matrix_sel_e maxsel; |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| maxsel = VDIN_SEL_MATRIX1;/*VDIN_SEL_MATRIXHDR*/ |
| else |
| maxsel = VDIN_SEL_MATRIX0; |
| |
| if (maxsel == VDIN_SEL_MATRIX0) |
| wr(0, VDIN_MATRIX_CTRL, 0x7); |
| else |
| wr(0, VDIN_MATRIX_CTRL, 0x6); |
| |
| /*post offset*/ |
| wr(0, VDIN_MATRIX_OFFSET0_1, 0x200); |
| wr(0, VDIN_MATRIX_OFFSET2, 0x200); |
| |
| /*coef*/ |
| wr(0, VDIN_MATRIX_COEF00_01, 0x6000000); |
| wr(0, VDIN_MATRIX_COEF02_10, 0); |
| wr(0, VDIN_MATRIX_COEF11_12, 0); |
| wr(0, VDIN_MATRIX_COEF20_21, 0); |
| wr(0, VDIN_MATRIX_COEF22, 0); |
| } |
| EXPORT_SYMBOL(vdin_adjust_tvafesnow_brightness); |
| |
| void vdin_set_config(struct vdin_dev_s *devp) |
| { |
| if (is_meson_gxbb_cpu() || is_meson_gxm_cpu() || is_meson_gxl_cpu()) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| /* max pixel clk of vdin for gxbb/gxm/gxl */ |
| devp->vdin_max_pixelclk = |
| VDIN_PIXELCLK_4K_30HZ; /* 2160p30hz*/ |
| #endif |
| } else { |
| devp->vdin_max_pixelclk = |
| VDIN_PIXELCLK_4K_60HZ; /* 2160p60hz*/ |
| } |
| } |
| |
| void vdin_change_matrix0(u32 offset, u32 matrix_csc) |
| { |
| struct vdin_matrix_lup_s *matrix_tbl; |
| |
| if (matrix_csc == VDIN_MATRIX_NULL) { |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); |
| } else { |
| matrix_tbl = &vdin_matrix_lup[matrix_csc - 1]; |
| |
| /*coefficient index select matrix0*/ |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID); |
| |
| wr(offset, |
| VDIN_MATRIX_PRE_OFFSET0_1, matrix_tbl->pre_offset0_1); |
| wr(offset, |
| VDIN_MATRIX_PRE_OFFSET2, matrix_tbl->pre_offset2); |
| wr(offset, VDIN_MATRIX_COEF00_01, matrix_tbl->coef00_01); |
| wr(offset, VDIN_MATRIX_COEF02_10, matrix_tbl->coef02_10); |
| wr(offset, VDIN_MATRIX_COEF11_12, matrix_tbl->coef11_12); |
| wr(offset, VDIN_MATRIX_COEF20_21, matrix_tbl->coef20_21); |
| wr(offset, VDIN_MATRIX_COEF22, matrix_tbl->coef22); |
| wr(offset, VDIN_MATRIX_OFFSET0_1, matrix_tbl->post_offset0_1); |
| wr(offset, VDIN_MATRIX_OFFSET2, matrix_tbl->post_offset2); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX0_BYPASS_BIT, VDIN_MATRIX0_BYPASS_WID); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 1, |
| VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); |
| } |
| |
| pr_info("%s id:%d\n", __func__, matrix_csc); |
| } |
| |
| void vdin_change_matrix1(u32 offset, u32 matrix_csc) |
| { |
| struct vdin_matrix_lup_s *matrix_tbl; |
| |
| if (matrix_csc == VDIN_MATRIX_NULL) { |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID); |
| } else { |
| matrix_tbl = &vdin_matrix_lup[matrix_csc - 1]; |
| /*select matrix1 post probe and postion(200,100)*/ |
| wr_bits(offset, VDIN_MATRIX_CTRL, 1, |
| VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 1, |
| VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID); |
| wr(offset, VDIN_MATRIX_PROBE_POS, 0xc812); |
| /*coefficient index select matrix1*/ |
| wr_bits(offset, VDIN_MATRIX_CTRL, 1, |
| VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID); |
| wr(offset, |
| VDIN_MATRIX_PRE_OFFSET0_1, matrix_tbl->pre_offset0_1); |
| wr(offset, VDIN_MATRIX_PRE_OFFSET2, matrix_tbl->pre_offset2); |
| wr(offset, VDIN_MATRIX_COEF00_01, matrix_tbl->coef00_01); |
| wr(offset, VDIN_MATRIX_COEF02_10, matrix_tbl->coef02_10); |
| wr(offset, VDIN_MATRIX_COEF11_12, matrix_tbl->coef11_12); |
| wr(offset, VDIN_MATRIX_COEF20_21, matrix_tbl->coef20_21); |
| wr(offset, VDIN_MATRIX_COEF22, matrix_tbl->coef22); |
| wr(offset, VDIN_MATRIX_OFFSET0_1, matrix_tbl->post_offset0_1); |
| wr(offset, VDIN_MATRIX_OFFSET2, matrix_tbl->post_offset2); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX1_BYPASS_BIT, VDIN_MATRIX1_BYPASS_WID); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 1, |
| VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID); |
| } |
| pr_info("%s id:%d\n", __func__, matrix_csc); |
| } |
| |
| /* |
| * after, equel g12a have this matrix |
| */ |
| void vdin_change_matrixhdr(u32 offset, u32 matrix_csc) |
| { |
| struct vdin_matrix_lup_s *matrix_tbl; |
| |
| if (matrix_csc == VDIN_MATRIX_NULL) { |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); |
| |
| if (is_meson_tm2_cpu() || |
| (get_cpu_type() == MESON_CPU_MAJOR_ID_SC2)) |
| wr_bits(offset, VDIN_HDR2_MATRIXI_EN_CTRL, 0, |
| VDIN_MATRIX_EN_BIT, |
| VDIN_MATRIX_EN_WID); |
| } else { |
| matrix_tbl = &vdin_matrix_lup[matrix_csc - 1]; |
| |
| /*coefficient index select matrix0*/ |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID); |
| |
| wr(offset, |
| VDIN_HDR2_MATRIXI_PRE_OFFSET0_1, matrix_tbl->pre_offset0_1); |
| wr(offset, |
| VDIN_HDR2_MATRIXI_PRE_OFFSET2, matrix_tbl->pre_offset2); |
| wr(offset, VDIN_HDR2_MATRIXI_COEF00_01, matrix_tbl->coef00_01); |
| wr(offset, VDIN_HDR2_MATRIXI_COEF02_10, matrix_tbl->coef02_10); |
| wr(offset, VDIN_HDR2_MATRIXI_COEF11_12, matrix_tbl->coef11_12); |
| wr(offset, VDIN_HDR2_MATRIXI_COEF20_21, matrix_tbl->coef20_21); |
| wr(offset, VDIN_HDR2_MATRIXI_COEF22, matrix_tbl->coef22); |
| wr(offset, VDIN_HDR2_MATRIXI_OFFSET0_1, |
| matrix_tbl->post_offset0_1); |
| wr(offset, VDIN_HDR2_MATRIXI_OFFSET2, matrix_tbl->post_offset2); |
| wr_bits(offset, VDIN_HDR2_MATRIXI_EN_CTRL, 1, 0, 1); |
| wr_bits(offset, VDIN_HDR2_CTRL, 1, 16, 1); |
| wr_bits(offset, VDIN_HDR2_CTRL, 0, 13, 1); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX0_BYPASS_BIT, VDIN_MATRIX0_BYPASS_WID); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 1, |
| VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); |
| } |
| |
| pr_info("%s id:%d\n", __func__, matrix_csc); |
| } |
| |
| static enum vdin_matrix_csc_e |
| vdin_set_color_matrix(enum vdin_matrix_sel_e maxsel, unsigned int offset, |
| struct tvin_format_s *tvin_fmt_p, |
| enum vdin_format_convert_e format_convert, |
| enum tvin_port_e port, |
| enum tvin_color_fmt_range_e color_fmt_range, |
| unsigned int vdin_hdr_flag, |
| unsigned int color_range_mode) |
| { |
| enum vdin_matrix_csc_e matrix_csc = VDIN_MATRIX_NULL; |
| /*struct vdin_matrix_lup_s *matrix_tbl;*/ |
| struct tvin_format_s *fmt_info = tvin_fmt_p; |
| |
| switch (format_convert) { |
| case VDIN_MATRIX_XXX_YUV_BLACK: |
| matrix_csc = VDIN_MATRIX_XXX_YUV601_BLACK; |
| break; |
| case VDIN_FORMAT_CONVERT_RGB_YUV422: |
| case VDIN_FORMAT_CONVERT_RGB_NV12: |
| case VDIN_FORMAT_CONVERT_RGB_NV21: |
| if (port >= TVIN_PORT_HDMI0 && port <= TVIN_PORT_HDMI7) { |
| if (color_range_mode == 1) { |
| if (color_fmt_range == TVIN_RGB_FULL) { |
| matrix_csc = VDIN_MATRIX_RGB_YUV709F; |
| if (vdin_hdr_flag == 1) |
| matrix_csc = |
| VDIN_MATRIX_RGB_YUV709; |
| } else { |
| matrix_csc = |
| VDIN_MATRIX_RGBS_YUV709F; |
| if (vdin_hdr_flag == 1) |
| matrix_csc = |
| VDIN_MATRIX_RGBS_YUV709; |
| } |
| } else { |
| if (color_fmt_range == TVIN_RGB_FULL) { |
| if (vdin_hdr_flag == 1) |
| matrix_csc = |
| VDIN_MATRIX_RGB2020_YUV2020; |
| else |
| matrix_csc = |
| VDIN_MATRIX_RGB_YUV709; |
| } else { |
| matrix_csc = VDIN_MATRIX_RGBS_YUV709; |
| } |
| } |
| } else { |
| if (color_range_mode == 1) |
| matrix_csc = VDIN_MATRIX_RGB_YUV709F; |
| else |
| matrix_csc = VDIN_MATRIX_RGB_YUV709; |
| } |
| break; |
| case VDIN_FORMAT_CONVERT_GBR_YUV422: |
| matrix_csc = VDIN_MATRIX_GBR_YUV601; |
| break; |
| case VDIN_FORMAT_CONVERT_BRG_YUV422: |
| matrix_csc = VDIN_MATRIX_BRG_YUV601; |
| break; |
| case VDIN_FORMAT_CONVERT_RGB_YUV444: |
| if (port >= TVIN_PORT_HDMI0 && port <= TVIN_PORT_HDMI7) { |
| if (color_range_mode == 1) { |
| if (color_fmt_range == TVIN_RGB_FULL) { |
| matrix_csc = VDIN_MATRIX_RGB_YUV709F; |
| if (vdin_hdr_flag == 1) |
| matrix_csc = |
| VDIN_MATRIX_RGB_YUV709; |
| } else { |
| matrix_csc = VDIN_MATRIX_RGBS_YUV709F; |
| if (vdin_hdr_flag == 1) |
| matrix_csc = |
| VDIN_MATRIX_RGBS_YUV709; |
| } |
| } else { |
| if (color_fmt_range == TVIN_RGB_FULL) { |
| if (vdin_hdr_flag == 1) |
| matrix_csc = |
| VDIN_MATRIX_RGB2020_YUV2020; |
| else |
| matrix_csc = |
| VDIN_MATRIX_RGB_YUV709F; |
| } else { |
| matrix_csc = VDIN_MATRIX_RGBS_YUV709; |
| } |
| } |
| } else { |
| if (color_range_mode == 1) |
| matrix_csc = VDIN_MATRIX_RGB_YUV709F; |
| else |
| matrix_csc = VDIN_MATRIX_RGB_YUV709; |
| } |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_RGB: |
| if ((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE && |
| fmt_info->v_active >= 720) || /* 720p & above */ |
| (fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED && |
| fmt_info->v_active >= 540)) /* 1080i & above */ |
| matrix_csc = VDIN_MATRIX_YUV709_RGB; |
| else |
| matrix_csc = VDIN_MATRIX_YUV601_RGB; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_GBR: |
| if ((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE && |
| fmt_info->v_active >= 720) || /* 720p & above */ |
| (fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED && |
| fmt_info->v_active >= 540)) /* 1080i & above */ |
| matrix_csc = VDIN_MATRIX_YUV709_GBR; |
| else |
| matrix_csc = VDIN_MATRIX_YUV601_GBR; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_BRG: |
| if ((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE && |
| fmt_info->v_active >= 720) || /* 720p & above */ |
| (fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED && |
| fmt_info->v_active >= 540)) /* 1080i & above */ |
| matrix_csc = VDIN_MATRIX_YUV709_BRG; |
| else |
| matrix_csc = VDIN_MATRIX_YUV601_BRG; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_YUV422: |
| case VDIN_FORMAT_CONVERT_YUV_YUV444: |
| case VDIN_FORMAT_CONVERT_YUV_NV12: |
| case VDIN_FORMAT_CONVERT_YUV_NV21: |
| if ((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE && |
| fmt_info->v_active >= 720) || /* 720p & above */ |
| (fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED && |
| fmt_info->v_active >= 540)) { /* 1080i & above */ |
| |
| if (color_range_mode == 1 && |
| color_fmt_range != TVIN_YUV_FULL) |
| matrix_csc = VDIN_MATRIX_YUV709_YUV709F; |
| else if (color_range_mode == 0 && |
| color_fmt_range == TVIN_YUV_FULL) |
| matrix_csc = VDIN_MATRIX_YUV709F_YUV709; |
| } else { |
| if (color_range_mode == 1) { |
| if (color_fmt_range == TVIN_YUV_FULL) |
| matrix_csc = |
| VDIN_MATRIX_YUV601F_YUV709F; |
| else |
| matrix_csc = VDIN_MATRIX_YUV601_YUV709F; |
| } else { |
| if (color_fmt_range == TVIN_YUV_FULL) |
| matrix_csc = VDIN_MATRIX_YUV601F_YUV709; |
| else |
| matrix_csc = VDIN_MATRIX_YUV601_YUV709; |
| } |
| } |
| if (vdin_hdr_flag == 1) { |
| if (color_fmt_range == TVIN_YUV_FULL) |
| matrix_csc = VDIN_MATRIX_YUV2020F_YUV2020; |
| else |
| matrix_csc = VDIN_MATRIX_NULL; |
| } |
| break; |
| default: |
| matrix_csc = VDIN_MATRIX_NULL; |
| break; |
| } |
| |
| if (maxsel == VDIN_SEL_MATRIX0) |
| vdin_change_matrix0(offset, matrix_csc); |
| else if (maxsel == VDIN_SEL_MATRIX1) |
| vdin_change_matrix1(offset, matrix_csc); |
| else if (maxsel == VDIN_SEL_MATRIXHDR) |
| vdin_change_matrixhdr(offset, matrix_csc); |
| else |
| matrix_csc = VDIN_MATRIX_NULL; |
| |
| return matrix_csc; |
| } |
| |
| void vdin_set_hdr(struct vdin_dev_s *devp) |
| { |
| enum vd_format_e video_format; |
| |
| if (devp->index == 0) |
| return; |
| |
| switch (devp->parm.port) { |
| case TVIN_PORT_VIU1_WB0_VD1: |
| case TVIN_PORT_VIU1_WB0_VD2: |
| case TVIN_PORT_VIU1_WB0_POST_BLEND: |
| case TVIN_PORT_VIU1_WB1_POST_BLEND: |
| case TVIN_PORT_VIU1_WB1_VD1: |
| case TVIN_PORT_VIU1_WB1_VD2: |
| case TVIN_PORT_VIU1_WB0_OSD1: |
| case TVIN_PORT_VIU1_WB0_OSD2: |
| case TVIN_PORT_VIU1_WB1_OSD1: |
| case TVIN_PORT_VIU1_WB1_OSD2: |
| video_format = devp->vd1_fmt; |
| break; |
| |
| case TVIN_PORT_VIU1_WB0_VPP: |
| case TVIN_PORT_VIU1_WB1_VPP: |
| case TVIN_PORT_VIU2_ENCL: |
| case TVIN_PORT_VIU2_ENCI: |
| case TVIN_PORT_VIU2_ENCP: |
| video_format = devp->tx_fmt; |
| break; |
| |
| default: |
| video_format = devp->tx_fmt; |
| break; |
| } |
| #ifndef VDIN_BRINGUP_NO_AMLVECM |
| pr_info("%s fmt:%d\n", __func__, video_format); |
| switch (video_format) { |
| case SIGNAL_HDR10: |
| case SIGNAL_HDR10PLUS: |
| /* parameters: |
| * 1st, moudle sel: 4=VDIN0_HDR, 5=VDIN1_HDR |
| * 2nd, process sel: bit1=HDR_SDR |
| * bit11=HDR10P_SDR |
| */ |
| hdr_set(5, 2, VPP_TOP0); |
| break; |
| |
| case SIGNAL_SDR: |
| /* HDR_BYPASS(bit0) | HLG_BYPASS(bit3) */ |
| hdr_set(5, 0x9, VPP_TOP0); |
| break; |
| |
| case SIGNAL_HLG: |
| /* HLG_SDR(bit4) */ |
| hdr_set(5, 0x10, VPP_TOP0); |
| break; |
| |
| /* VDIN DON'T support dv loopback currently */ |
| case SIGNAL_DOVI: |
| pr_err("err: don't support dv signal loopback"); |
| break; |
| |
| default: |
| break; |
| } |
| #endif |
| /* hdr set uses rdma, will delay 1 frame to take effect */ |
| devp->frame_drop_num = 1; |
| } |
| |
| /*set matrix based on rgb_info_enable: |
| * 0:set matrix0, disable matrix1 |
| * 1:set matrix1, set matrix0 |
| * after equal g12a: matris1, matrixhdr2 |
| */ |
| void vdin_set_matrix(struct vdin_dev_s *devp) |
| { |
| enum vdin_format_convert_e format_convert_matrix0; |
| enum vdin_format_convert_e format_convert_matrix1; |
| unsigned int offset = devp->addr_offset; |
| enum vdin_matrix_sel_e maxsel; |
| |
| if (rgb_info_enable == 0) { |
| /* matrix1 disable */ |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { |
| maxsel = VDIN_SEL_MATRIX1;/*VDIN_SEL_MATRIXHDR*/ |
| } else { |
| maxsel = VDIN_SEL_MATRIX0; |
| } |
| devp->csc_idx = |
| vdin_set_color_matrix(maxsel, |
| devp->addr_offset, |
| devp->fmt_info_p, |
| devp->format_convert, |
| devp->parm.port, |
| devp->prop.color_fmt_range, |
| devp->prop.vdin_hdr_flag | devp->dv.dv_flag, |
| devp->color_range_mode); |
| |
| vdin_set_hdr(devp); |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| if (vdin_is_dolby_signal_in(devp) || |
| devp->parm.info.fmt == TVIN_SIG_FMT_CVBS_SECAM) |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); |
| #endif |
| wr_bits(offset, VDIN_MATRIX_CTRL, 3, |
| VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID); |
| } else { |
| format_convert_matrix0 = vdin_get_format_convert_matrix0(devp); |
| format_convert_matrix1 = vdin_get_format_convert_matrix1(devp); |
| devp->csc_idx = vdin_set_color_matrix(VDIN_SEL_MATRIX1, |
| devp->addr_offset, |
| devp->fmt_info_p, |
| format_convert_matrix1, |
| devp->parm.port, |
| devp->prop.color_fmt_range, |
| devp->prop.vdin_hdr_flag | devp->dv.dv_flag, |
| devp->color_range_mode); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| devp->csc_idx = |
| vdin_set_color_matrix(VDIN_SEL_MATRIX1, |
| devp->addr_offset, |
| devp->fmt_info_p, |
| devp->format_convert, |
| devp->parm.port, |
| devp->prop.color_fmt_range, |
| devp->prop.vdin_hdr_flag | devp->dv.dv_flag, |
| devp->color_range_mode); |
| else |
| devp->csc_idx = |
| vdin_set_color_matrix(VDIN_SEL_MATRIX0, |
| devp->addr_offset, |
| devp->fmt_info_p, |
| format_convert_matrix0, |
| devp->parm.port, |
| devp->prop.color_fmt_range, |
| devp->prop.vdin_hdr_flag | devp->dv.dv_flag, |
| devp->color_range_mode); |
| if (devp->parm.info.fmt == TVIN_SIG_FMT_CVBS_SECAM) |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); |
| /* set xy */ |
| wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_y, |
| PROBE_POX_Y_BIT, PROBE_POX_Y_WID); |
| wr_bits(offset, VDIN_MATRIX_PROBE_POS, rgb_info_x, |
| PROBE_POS_X_BIT, PROBE_POS_X_WID); |
| /* 1:probe pixel data after matrix */ |
| wr_bits(offset, VDIN_MATRIX_CTRL, 1, |
| VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID); |
| /* 1:select matrix 1 */ |
| wr_bits(offset, VDIN_MATRIX_CTRL, 1, |
| VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID); |
| } |
| |
| if (devp->matrix_pattern_mode) |
| vdin_set_matrix_color(devp); |
| } |
| |
| void vdin_set_matrixs(struct vdin_dev_s *devp, unsigned char id, |
| enum vdin_format_convert_e csc) |
| { |
| switch (id) { |
| case 0: |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) |
| devp->csc_idx = |
| vdin_set_color_matrix(VDIN_SEL_MATRIX1, |
| devp->addr_offset, |
| devp->fmt_info_p, |
| devp->format_convert, |
| devp->parm.port, |
| devp->prop.color_fmt_range, |
| devp->prop.vdin_hdr_flag | devp->dv.dv_flag, |
| devp->color_range_mode); |
| else |
| devp->csc_idx = |
| vdin_set_color_matrix(VDIN_SEL_MATRIX0, |
| devp->addr_offset, |
| devp->fmt_info_p, csc, |
| devp->parm.port, |
| devp->prop.color_fmt_range, |
| devp->prop.vdin_hdr_flag | devp->dv.dv_flag, |
| devp->color_range_mode); |
| break; |
| case 1: |
| devp->csc_idx = vdin_set_color_matrix(VDIN_SEL_MATRIX1, |
| devp->addr_offset, |
| devp->fmt_info_p, csc, |
| devp->parm.port, |
| devp->prop.color_fmt_range, |
| devp->prop.vdin_hdr_flag | devp->dv.dv_flag, |
| devp->color_range_mode); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| /*set block bar |
| *base on flowing parameters: |
| *a.h_active b.v_active |
| */ |
| static inline void vdin_set_bbar(unsigned int offset, unsigned int v, |
| unsigned int h) |
| { |
| unsigned int region_width = 1, block_thr = 0, line_thr = 0; |
| |
| while ((region_width << 1) < h) |
| region_width <<= 1; |
| |
| block_thr = (region_width >> 1) * v; |
| /* bblk=(bpix>thr) */ |
| block_thr = block_thr - (block_thr >> BBAR_BLOCK_THR_FACTOR); |
| /* bln=!(wpix>=thr) */ |
| line_thr = h >> BBAR_LINE_THR_FACTOR; |
| |
| /* region_width */ |
| wr_bits(offset, VDIN_BLKBAR_CTRL0, |
| region_width, BLKBAR_H_WIDTH_BIT, BLKBAR_H_WIDTH_WID); |
| /* win_he */ |
| wr_bits(offset, VDIN_BLKBAR_H_START_END, |
| (h - 1), BLKBAR_HEND_BIT, BLKBAR_HEND_WID); |
| /* win_ve */ |
| wr_bits(offset, VDIN_BLKBAR_V_START_END, |
| (v - 1), BLKBAR_VEND_BIT, BLKBAR_VEND_WID); |
| /* bblk_thr_on_bpix */ |
| wr_bits(offset, VDIN_BLKBAR_CNT_THRESHOLD, |
| block_thr, BLKBAR_CNT_TH_BIT, BLKBAR_CNT_TH_WID); |
| /* blnt_thr_on_wpix */ |
| wr_bits(offset, VDIN_BLKBAR_ROW_TH1_TH2, |
| line_thr, BLKBAR_ROW_TH1_BIT, BLKBAR_ROW_TH1_WID); |
| /* blnb_thr_on_wpix */ |
| wr_bits(offset, VDIN_BLKBAR_ROW_TH1_TH2, |
| line_thr, BLKBAR_ROW_TH2_BIT, BLKBAR_ROW_TH2_WID); |
| /* en */ |
| wr_bits(offset, VDIN_BLKBAR_CTRL0, |
| 1, BLKBAR_DET_TOP_EN_BIT, BLKBAR_DET_TOP_EN_WID); |
| /* manual reset, rst = 0 & 1, raising edge mode */ |
| wr_bits(offset, VDIN_BLKBAR_CTRL0, 0, |
| BLKBAR_DET_SOFT_RST_N_BIT, BLKBAR_DET_SOFT_RST_N_WID); |
| wr_bits(offset, VDIN_BLKBAR_CTRL0, 1, |
| BLKBAR_DET_SOFT_RST_N_BIT, BLKBAR_DET_SOFT_RST_N_WID); |
| } |
| |
| /*et histogram window |
| * pow\h_start\h_end\v_start\v_end |
| */ |
| static inline void vdin_set_histogram(unsigned int offset, unsigned int hs, |
| unsigned int he, unsigned int vs, |
| unsigned int ve) |
| { |
| unsigned int pixel_sum = 0, record_len = 0, hist_pow = 0; |
| |
| if (hs < he && vs < ve) { |
| pixel_sum = (he - hs + 1) * (ve - vs + 1); |
| record_len = 0xffff << 3; |
| while (pixel_sum > record_len && hist_pow < 3) { |
| hist_pow++; |
| record_len <<= 1; |
| } |
| /* #ifdef CONFIG_MESON2_CHIP */ |
| /* pow */ |
| wr_bits(offset, VDIN_HIST_CTRL, hist_pow, |
| HIST_POW_BIT, HIST_POW_WID); |
| /* win_hs */ |
| wr_bits(offset, VDIN_HIST_H_START_END, hs, |
| HIST_HSTART_BIT, HIST_HSTART_WID); |
| /* win_he */ |
| wr_bits(offset, VDIN_HIST_H_START_END, he, |
| HIST_HEND_BIT, HIST_HEND_WID); |
| /* win_vs */ |
| wr_bits(offset, VDIN_HIST_V_START_END, vs, |
| HIST_VSTART_BIT, HIST_VSTART_WID); |
| /* win_ve */ |
| wr_bits(offset, VDIN_HIST_V_START_END, ve, |
| HIST_VEND_BIT, HIST_VEND_WID); |
| } |
| } |
| |
| /* set hist mux |
| * VDIN_HIST_CTRL |
| * Bit 3:2 hist_din_sel the source used for hist statistics. |
| * 00: from matrix0 dout, 01: from vsc_dout, |
| * 10: from matrix1 dout, 11: form matrix1 din |
| */ |
| static inline void vdin_set_hist_mux(struct vdin_dev_s *devp) |
| { |
| enum tvin_port_e port = TVIN_PORT_NULL; |
| |
| port = devp->parm.port; |
| /*if ((port < TVIN_PORT_HDMI0) || (port > TVIN_PORT_HDMI7))*/ |
| /* return;*/ |
| /* For AV input no correct data, from vlsi fei.jun |
| * AV, HDMI all set 3 |
| */ |
| /* use 11: form matrix1 din */ |
| wr_bits(devp->addr_offset, VDIN_HIST_CTRL, 3, |
| HIST_HIST_DIN_SEL_BIT, HIST_HIST_DIN_SEL_WID); |
| |
| /*for project get vdin1 hist*/ |
| //if (devp->index == 1) |
| // wr_bits(devp->addr_offset, VDIN_WR_CTRL2, 1, 8, 1); |
| } |
| |
| /* urgent ctr config */ |
| /* if vdin fifo over up_th,will trigger increase |
| * urgent responds to vdin write, |
| * if vdin fifo lower dn_th,will trigger decrease |
| * urgent responds to vdin write |
| */ |
| static void vdin_urgent_patch(unsigned int offset, unsigned int v, |
| unsigned int h) |
| { |
| if (h >= 1920 && v >= 1080) { |
| wr_bits(offset, VDIN_LFIFO_URG_CTRL, 1, |
| VDIN_LFIFO_URG_CTRL_EN_BIT, VDIN_LFIFO_URG_CTRL_EN_WID); |
| wr_bits(offset, VDIN_LFIFO_URG_CTRL, 1, |
| VDIN_LFIFO_URG_WR_EN_BIT, VDIN_LFIFO_URG_WR_EN_WID); |
| wr_bits(offset, VDIN_LFIFO_URG_CTRL, 20, |
| VDIN_LFIFO_URG_UP_TH_BIT, VDIN_LFIFO_URG_UP_TH_WID); |
| wr_bits(offset, VDIN_LFIFO_URG_CTRL, 8, |
| VDIN_LFIFO_URG_DN_TH_BIT, VDIN_LFIFO_URG_DN_TH_WID); |
| /*vlsi guys suggest setting:*/ |
| W_VCBUS_BIT(VPU_ARB_URG_CTRL, 1, |
| VDIN_LFF_URG_CTRL_BIT, VDIN_LFF_URG_CTRL_WID); |
| W_VCBUS_BIT(VPU_ARB_URG_CTRL, 1, |
| VPP_OFF_URG_CTRL_BIT, VPP_OFF_URG_CTRL_WID); |
| } else { |
| wr(offset, VDIN_LFIFO_URG_CTRL, 0); |
| aml_write_vcbus(VPU_ARB_URG_CTRL, 0); |
| } |
| } |
| |
| void vdin_urgent_patch_resume(unsigned int offset) |
| { |
| /* urgent ctr config */ |
| wr(offset, VDIN_LFIFO_URG_CTRL, 0); |
| aml_write_vcbus(VPU_ARB_URG_CTRL, 0); |
| } |
| |
| static unsigned int vdin_is_support_10bit_for_dw(struct vdin_dev_s *devp) |
| { |
| if (devp->double_wr) { |
| if (devp->double_wr_10bit_sup) |
| return 1; |
| else |
| return 0; |
| } else { |
| return 1; |
| } |
| } |
| |
| /*static unsigned int vdin_wr_mode = 0xff;*/ |
| /*module_param(vdin_wr_mode, uint, 0644);*/ |
| /*MODULE_PARM_DESC(vdin_wr_mode, "vdin_wr_mode");*/ |
| |
| /* set write ctrl regs: |
| * VDIN_WR_H_START_END |
| * VDIN_WR_V_START_END |
| * VDIN_WR_CTRL |
| * VDIN_LFIFO_URG_CTRL |
| */ |
| static inline void vdin_set_wr_ctrl(struct vdin_dev_s *devp, |
| unsigned int offset, unsigned int v, |
| unsigned int h, |
| enum vdin_format_convert_e format_convert, |
| unsigned int full_pack, |
| unsigned int source_bitdeth) |
| { |
| enum vdin_mif_fmt write_fmt = MIF_FMT_YUV422; |
| unsigned int swap_cbcr = 0; |
| unsigned int hconv_mode = 2; |
| |
| if (devp->vfmem_size_small) { |
| h = devp->h_shrink_out; |
| v = devp->v_shrink_out; |
| } |
| |
| switch (format_convert) { |
| case VDIN_FORMAT_CONVERT_YUV_YUV422: |
| case VDIN_FORMAT_CONVERT_RGB_YUV422: |
| case VDIN_FORMAT_CONVERT_GBR_YUV422: |
| case VDIN_FORMAT_CONVERT_BRG_YUV422: |
| write_fmt = MIF_FMT_YUV422; |
| break; |
| |
| case VDIN_FORMAT_CONVERT_YUV_NV12: |
| case VDIN_FORMAT_CONVERT_RGB_NV12: |
| write_fmt = MIF_FMT_NV12_21; |
| swap_cbcr = 1; |
| break; |
| |
| case VDIN_FORMAT_CONVERT_YUV_NV21: |
| case VDIN_FORMAT_CONVERT_RGB_NV21: |
| write_fmt = MIF_FMT_NV12_21; |
| swap_cbcr = 0; |
| break; |
| |
| default: |
| write_fmt = MIF_FMT_YUV444; |
| break; |
| } |
| |
| /* yuv422 full pack mode for 10bit |
| * only support 8bit at vpp side when double write |
| */ |
| if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422) && |
| full_pack == VDIN_422_FULL_PK_EN && |
| source_bitdeth > VDIN_COLOR_DEEPS_8BIT && |
| vdin_is_support_10bit_for_dw(devp)) { |
| write_fmt = MIF_FMT_YUV422_FULL_PACK; |
| |
| /* IC bug, fixed at tm2 revB */ |
| if (devp->dtdata->hw_ver == VDIN_HW_ORG) |
| hconv_mode = 0; |
| } |
| |
| /* win_he */ |
| if ((h % 2) && devp->source_bitdepth > VDIN_COLOR_DEEPS_8BIT && |
| devp->full_pack == VDIN_422_FULL_PK_EN && |
| (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) |
| h += 1; |
| |
| wr_bits(offset, VDIN_WR_H_START_END, (h - 1), WR_HEND_BIT, WR_HEND_WID); |
| /* win_ve */ |
| wr_bits(offset, VDIN_WR_V_START_END, (v - 1), WR_VEND_BIT, WR_VEND_WID); |
| /* hconv_mode */ |
| wr_bits(offset, VDIN_WR_CTRL, hconv_mode, HCONV_MODE_BIT, HCONV_MODE_WID); |
| /* vconv_mode */ |
| wr_bits(offset, VDIN_WR_CTRL, 0, VCONV_MODE_BIT, VCONV_MODE_WID); |
| |
| if (write_fmt == MIF_FMT_NV12_21) { |
| /* swap_cbcr */ |
| wr_bits(offset, VDIN_WR_CTRL, swap_cbcr, |
| SWAP_CBCR_BIT, SWAP_CBCR_WID); |
| /* output even lines's cbcr */ |
| wr_bits(offset, VDIN_WR_CTRL, 0, |
| VCONV_MODE_BIT, VCONV_MODE_WID); |
| /* chroma canvas */ |
| /* wr_bits(offset, VDIN_WR_CTRL2, def_canvas_id + 1, |
| * WRITE_CHROMA_CANVAS_ADDR_BIT, |
| * WRITE_CHROMA_CANVAS_ADDR_WID); |
| */ |
| } else if (write_fmt == MIF_FMT_YUV444) { |
| /* output all cbcr */ |
| wr_bits(offset, VDIN_WR_CTRL, 3, |
| VCONV_MODE_BIT, VCONV_MODE_WID); |
| } else { |
| /* swap_cbcr */ |
| wr_bits(offset, VDIN_WR_CTRL, 0, SWAP_CBCR_BIT, SWAP_CBCR_WID); |
| /* chroma canvas */ |
| /* wr_bits(offset, VDIN_WR_CTRL2, 0, |
| * WRITE_CHROMA_CANVAS_ADDR_BIT, |
| */ |
| /* WRITE_CHROMA_CANVAS_ADDR_WID); */ |
| } |
| /* format444 */ |
| wr_bits(offset, VDIN_WR_CTRL, write_fmt, WR_FMT_BIT, WR_FMT_WID); |
| /* canvas_id |
| * wr_bits(offset, VDIN_WR_CTRL, |
| * def_canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID); |
| */ |
| /* req_urgent */ |
| wr_bits(offset, VDIN_WR_CTRL, 1, WR_REQ_URGENT_BIT, WR_REQ_URGENT_WID); |
| /* req_en */ |
| wr_bits(offset, VDIN_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| /*only for vdin0*/ |
| if (devp->urgent_en && devp->index == 0) |
| vdin_urgent_patch(offset, v, h); |
| /* dis ctrl reg wpulse */ |
| /*if (is_meson_g9tv_cpu() || is_meson_m8_cpu() || |
| * is_meson_m8m2_cpu() || is_meson_gxbb_cpu() || |
| * is_meson_m8b_cpu()) |
| */ |
| wr_bits(offset, VDIN_WR_CTRL, 1, |
| VDIN_WRCTRLREG_PAUSE_BIT, VDIN_WRCTRLREG_PAUSE_WID); |
| /* swap the 2 64bits word in 128 words */ |
| /*if (is_meson_gxbb_cpu())*/ |
| if (devp->set_canvas_manual == 1 || devp->cfg_dma_buf) { |
| /*not swap 2 64bits words in 128 words */ |
| wr_bits(offset, VDIN_WR_CTRL, 0, WORDS_SWAP_BIT, WORDS_SWAP_WID); |
| /*little endian*/ |
| wr_bits(offset, VDIN_WR_H_START_END, 1, WR_ENDIAN_BIT, WR_ENDIAN_WID); |
| } else { |
| wr_bits(offset, VDIN_WR_CTRL, 1, WORDS_SWAP_BIT, WORDS_SWAP_WID); |
| } |
| |
| /*if (vdin_wr_mode == 0) {*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 0, SWAP_CBCR_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 0, WORDS_SWAP_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_H_START_END, 0, WR_ENDIAN_BIT, 1);*/ |
| /*} else if (vdin_wr_mode == 1) {*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 0, SWAP_CBCR_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 0, WORDS_SWAP_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_H_START_END, 1, WR_ENDIAN_BIT, 1);*/ |
| /*} else if (vdin_wr_mode == 2) {*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 0, SWAP_CBCR_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 1, WORDS_SWAP_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_H_START_END, 0, WR_ENDIAN_BIT, 1);*/ |
| /*} else if (vdin_wr_mode == 3) {*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 0, SWAP_CBCR_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 1, WORDS_SWAP_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_H_START_END, 1, WR_ENDIAN_BIT, 1);*/ |
| /*} else if (vdin_wr_mode == 4) {*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 1, SWAP_CBCR_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 0, WORDS_SWAP_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_H_START_END, 0, WR_ENDIAN_BIT, 1);*/ |
| /*} else if (vdin_wr_mode == 5) {*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 1, SWAP_CBCR_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 0, WORDS_SWAP_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_H_START_END, 1, WR_ENDIAN_BIT, 1);*/ |
| /*} else if (vdin_wr_mode == 6) {*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 1, SWAP_CBCR_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 1, WORDS_SWAP_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_H_START_END, 0, WR_ENDIAN_BIT, 1);*/ |
| /*} else if (vdin_wr_mode == 7) {*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 1, SWAP_CBCR_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_CTRL, 1, WORDS_SWAP_BIT, 1);*/ |
| /* wr_bits(offset, VDIN_WR_H_START_END, 1, WR_ENDIAN_BIT, 1);*/ |
| /*}*/ |
| } |
| |
| void vdin_set_wr_ctrl_vsync(struct vdin_dev_s *devp, |
| unsigned int offset, |
| enum vdin_format_convert_e format_convert, |
| unsigned int full_pack, |
| unsigned int source_bitdeth, |
| unsigned int rdma_enable) |
| { |
| enum vdin_mif_fmt write_fmt = MIF_FMT_YUV422; |
| unsigned int swap_cbcr = 0; |
| unsigned int hconv_mode = 2, vconv_mode; |
| |
| switch (format_convert) { |
| case VDIN_FORMAT_CONVERT_YUV_YUV422: |
| case VDIN_FORMAT_CONVERT_RGB_YUV422: |
| case VDIN_FORMAT_CONVERT_GBR_YUV422: |
| case VDIN_FORMAT_CONVERT_BRG_YUV422: |
| write_fmt = MIF_FMT_YUV422; |
| break; |
| |
| case VDIN_FORMAT_CONVERT_YUV_NV12: |
| case VDIN_FORMAT_CONVERT_RGB_NV12: |
| write_fmt = MIF_FMT_NV12_21; |
| swap_cbcr = 1; |
| |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_NV21: |
| case VDIN_FORMAT_CONVERT_RGB_NV21: |
| write_fmt = MIF_FMT_NV12_21; |
| swap_cbcr = 0; |
| break; |
| |
| default: |
| write_fmt = MIF_FMT_YUV444; |
| break; |
| } |
| |
| /* yuv422 full pack mode for 10bit |
| * only support 8bit at vpp side when double write |
| */ |
| if ((format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422) && |
| full_pack == VDIN_422_FULL_PK_EN && source_bitdeth > 8 && |
| vdin_is_support_10bit_for_dw(devp)) { |
| write_fmt = MIF_FMT_YUV422_FULL_PACK; |
| |
| /* IC bug, fixed at tm2 revB */ |
| if (devp->dtdata->hw_ver == VDIN_HW_ORG) |
| hconv_mode = 0; |
| } |
| |
| /* vconv_mode */ |
| vconv_mode = 0; |
| |
| if (write_fmt == MIF_FMT_NV12_21) |
| vconv_mode = 0; |
| else if (write_fmt == MIF_FMT_YUV444) |
| vconv_mode = 3; |
| else |
| swap_cbcr = 0; |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| if (rdma_enable) { |
| rdma_write_reg_bits(devp->rdma_handle, |
| VDIN_WR_CTRL + devp->addr_offset, |
| hconv_mode, HCONV_MODE_BIT, HCONV_MODE_WID); |
| rdma_write_reg_bits(devp->rdma_handle, |
| VDIN_WR_CTRL + devp->addr_offset, |
| vconv_mode, VCONV_MODE_BIT, VCONV_MODE_WID); |
| rdma_write_reg_bits(devp->rdma_handle, |
| VDIN_WR_CTRL + devp->addr_offset, |
| swap_cbcr, SWAP_CBCR_BIT, SWAP_CBCR_WID); |
| rdma_write_reg_bits(devp->rdma_handle, |
| VDIN_WR_CTRL + devp->addr_offset, |
| write_fmt, WR_FMT_BIT, WR_FMT_WID); |
| } else { |
| #endif |
| wr_bits(offset, VDIN_WR_CTRL, hconv_mode, |
| HCONV_MODE_BIT, HCONV_MODE_WID); |
| wr_bits(offset, VDIN_WR_CTRL, vconv_mode, |
| VCONV_MODE_BIT, VCONV_MODE_WID); |
| wr_bits(offset, VDIN_WR_CTRL, swap_cbcr, |
| SWAP_CBCR_BIT, SWAP_CBCR_WID); |
| wr_bits(offset, VDIN_WR_CTRL, write_fmt, |
| WR_FMT_BIT, WR_FMT_WID); |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| } |
| #endif |
| } |
| |
| /* set vdin_wr_mif for video only */ |
| void vdin_set_wr_mif(struct vdin_dev_s *devp) |
| { |
| int height, width; |
| static unsigned int temp_height; |
| static unsigned int temp_width; |
| |
| height = ((rd(0, VPP_POSTBLEND_VD1_V_START_END) & 0xfff) - |
| ((rd(0, VPP_POSTBLEND_VD1_V_START_END) >> 16) & 0xfff) + 1); |
| width = ((rd(0, VPP_POSTBLEND_VD1_H_START_END) & 0xfff) - |
| ((rd(0, VPP_POSTBLEND_VD1_H_START_END) >> 16) & 0xfff) + 1); |
| if (devp->parm.port == TVIN_PORT_VIU1_VIDEO && |
| devp->index == 1 && |
| height != temp_height && |
| width != temp_width) { |
| if ((width % 2) && |
| devp->source_bitdepth > VDIN_MIN_SOURCE_BITDEPTH && |
| (devp->full_pack == VDIN_422_FULL_PK_EN) && |
| (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) |
| width += 1; |
| |
| wr_bits(devp->addr_offset, VDIN_WR_H_START_END, |
| (width - 1), WR_HEND_BIT, WR_HEND_WID); |
| wr_bits(devp->addr_offset, VDIN_WR_V_START_END, |
| (height - 1), WR_VEND_BIT, WR_VEND_WID); |
| temp_height = height; |
| temp_width = width; |
| } |
| } |
| |
| void vdin_wr_frame_en(unsigned int ch, unsigned int onoff) |
| { |
| struct vdin_dev_s *devp = vdin_get_dev(ch); |
| |
| if (devp->vframe_wr_en != onoff) |
| devp->vframe_wr_en = onoff; |
| } |
| EXPORT_SYMBOL(vdin_wr_frame_en); |
| |
| void vdin_set_mif_onoff(struct vdin_dev_s *devp, unsigned int rdma_enable) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| if (devp->vframe_wr_en_pre == devp->vframe_wr_en) |
| return; |
| |
| #if CONFIG_AMLOGIC_MEDIA_RDMA |
| if (rdma_enable) { |
| rdma_write_reg_bits(devp->rdma_handle, VDIN_WR_CTRL2 + offset, |
| devp->vframe_wr_en ? 0 : 1, |
| DISCARD_BEF_LINE_FIFO_BIT, |
| DISCARD_BEF_LINE_FIFO_WID); |
| rdma_write_reg_bits(devp->rdma_handle, VDIN_WR_CTRL + offset, |
| devp->vframe_wr_en, WR_REQ_EN_BIT, |
| WR_REQ_EN_WID); |
| } |
| #endif |
| devp->vframe_wr_en_pre = devp->vframe_wr_en; |
| } |
| |
| /***************************global function**********************************/ |
| unsigned int vdin_get_meas_hcnt64(unsigned int offset) |
| { |
| return rd_bits(offset, VDIN_MEAS_HS_COUNT, |
| MEAS_HS_CNT_BIT, MEAS_HS_CNT_WID); |
| } |
| |
| unsigned int vdin_get_meas_vstamp(unsigned int offset) |
| { |
| return rd(offset, VDIN_MEAS_VS_COUNT_LO); |
| } |
| |
| unsigned int vdin_get_active_h(unsigned int offset) |
| { |
| return rd_bits(offset, VDIN_ACTIVE_MAX_PIX_CNT_STATUS, |
| ACTIVE_MAX_PIX_CNT_SDW_BIT, ACTIVE_MAX_PIX_CNT_SDW_WID); |
| } |
| |
| unsigned int vdin_get_active_v(unsigned int offset) |
| { |
| return rd_bits(offset, VDIN_LCNT_SHADOW_STATUS, |
| ACTIVE_LN_CNT_SDW_BIT, ACTIVE_LN_CNT_SDW_WID); |
| } |
| |
| unsigned int vdin_get_total_v(unsigned int offset) |
| { |
| return rd_bits(offset, VDIN_LCNT_SHADOW_STATUS, |
| GO_LN_CNT_SDW_BIT, GO_LN_CNT_SDW_WID); |
| } |
| |
| void vdin_set_frame_mif_write_addr(struct vdin_dev_s *devp, |
| unsigned int rdma_enable, |
| struct vf_entry *vfe) |
| { |
| u32 stride_luma, stride_chroma; |
| u32 hsize; |
| u32 phy_addr_luma = 0, phy_addr_chroma = 0; |
| |
| if (devp->vfmem_size_small) |
| hsize = devp->h_shrink_out; |
| else |
| hsize = devp->h_active; |
| |
| stride_luma = devp->canvas_w >> 4; |
| if (vfe->vf.plane_num == 2) |
| stride_chroma = devp->canvas_w >> 4; |
| |
| /* one region mode only have one buffer RGB,YUV */ |
| phy_addr_luma = vfe->vf.canvas0_config[0].phy_addr; |
| /* two region mode have Y and uv two buffer(NV12, NV21) */ |
| if (vfe->vf.plane_num == 2) |
| phy_addr_chroma = vfe->vf.canvas0_config[1].phy_addr; |
| |
| /*if (vdin_ctl_dbg) {*/ |
| /* pr_info("mif fmt:0x%x (0:422,1:444,2:NV21) bit:0x%x h:%d\n",*/ |
| /* devp->mif_fmt, devp->source_bitdepth, hsize);*/ |
| /* pr_info("phy addr luma:0x%x chroma:0x%x\n",*/ |
| /* phy_addr_luma, phy_addr_chroma);*/ |
| /* pr_info("stride luma:0x%x, chroma:0x%x\n",*/ |
| /* stride_luma, stride_chroma);*/ |
| /*}*/ |
| |
| if (rdma_enable) { |
| rdma_write_reg(devp->rdma_handle, |
| VDIN_WR_BADDR_LUMA + devp->addr_offset, |
| phy_addr_luma >> 4); |
| rdma_write_reg(devp->rdma_handle, |
| VDIN_WR_STRIDE_LUMA + devp->addr_offset, |
| stride_luma); |
| |
| if (vfe->vf.plane_num == 2) { |
| rdma_write_reg(devp->rdma_handle, |
| VDIN_WR_BADDR_CHROMA + devp->addr_offset, |
| phy_addr_chroma >> 4); |
| rdma_write_reg(devp->rdma_handle, |
| VDIN_WR_STRIDE_CHROMA + devp->addr_offset, |
| stride_chroma); |
| } |
| } else { |
| wr(devp->addr_offset, VDIN_WR_BADDR_LUMA, phy_addr_luma >> 4); |
| wr(devp->addr_offset, VDIN_WR_STRIDE_LUMA, stride_luma); |
| |
| if (vfe->vf.plane_num == 2) { |
| wr(devp->addr_offset, VDIN_WR_BADDR_CHROMA, |
| phy_addr_chroma >> 4); |
| wr(devp->addr_offset, VDIN_WR_STRIDE_CHROMA, |
| stride_chroma); |
| } |
| } |
| } |
| |
| void vdin_set_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable, |
| struct vf_entry *vfe) |
| { |
| u32 canvas_id; |
| |
| if (vfe) { |
| if (vfe->vf.canvas0Addr != (u32)-1) |
| canvas_id = vfe->vf.canvas0Addr; |
| else |
| canvas_id = devp->vf_canvas_id[vfe->vf.index]; |
| } else { |
| canvas_id = vdin_canvas_ids[devp->index][irq_max_count]; |
| } |
| canvas_id = (canvas_id & 0xff); |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| if (rdma_enable) { |
| if (is_meson_g12a_cpu() || is_meson_g12b_cpu() || |
| is_meson_sm1_cpu()) { |
| rdma_write_reg_bits(devp->rdma_handle, |
| VDIN_COM_CTRL0 + devp->addr_offset, |
| 1, |
| VDIN_FORCEGOLINE_EN_BIT, 1); |
| rdma_write_reg_bits(devp->rdma_handle, |
| VDIN_COM_CTRL0 + |
| devp->addr_offset, 0, |
| VDIN_FORCEGOLINE_EN_BIT, 1); |
| } |
| rdma_write_reg_bits(devp->rdma_handle, |
| VDIN_WR_CTRL + devp->addr_offset, |
| canvas_id, WR_CANVAS_BIT, WR_CANVAS_WID); |
| |
| if (devp->pause_dec) |
| rdma_write_reg_bits(devp->rdma_handle, VDIN_WR_CTRL + devp->addr_offset, |
| 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| else |
| rdma_write_reg_bits(devp->rdma_handle, VDIN_WR_CTRL + devp->addr_offset, |
| 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| } else { |
| #endif |
| wr_bits(devp->addr_offset, VDIN_WR_CTRL, canvas_id, |
| WR_CANVAS_BIT, WR_CANVAS_WID); |
| |
| if (devp->pause_dec) |
| wr_bits(devp->addr_offset, VDIN_WR_CTRL, 0, |
| WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| else |
| wr_bits(devp->addr_offset, VDIN_WR_CTRL, 1, |
| WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| } |
| #endif |
| } |
| |
| unsigned int vdin_get_canvas_id(unsigned int offset) |
| { |
| return rd_bits(offset, VDIN_WR_CTRL, WR_CANVAS_BIT, WR_CANVAS_WID); |
| } |
| |
| void vdin_set_chma_canvas_id(struct vdin_dev_s *devp, unsigned int rdma_enable, |
| struct vf_entry *vfe) |
| { |
| u32 canvas_id; |
| |
| if (!vfe) |
| return; |
| |
| if (vfe->vf.canvas0Addr != (u32)-1) |
| canvas_id = vfe->vf.canvas0Addr; |
| else |
| canvas_id = |
| devp->vf_canvas_id[vfe->vf.index]; |
| canvas_id = (canvas_id >> 8); |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| if (rdma_enable) |
| rdma_write_reg_bits(devp->rdma_handle, |
| VDIN_WR_CTRL2 + devp->addr_offset, |
| canvas_id, WRITE_CHROMA_CANVAS_ADDR_BIT, |
| WRITE_CHROMA_CANVAS_ADDR_WID); |
| else |
| #endif |
| wr_bits(devp->addr_offset, VDIN_WR_CTRL2, canvas_id, |
| WRITE_CHROMA_CANVAS_ADDR_BIT, |
| WRITE_CHROMA_CANVAS_ADDR_WID); |
| } |
| |
| unsigned int vdin_get_chma_canvas_id(unsigned int offset) |
| { |
| return rd_bits(offset, VDIN_WR_CTRL2, WRITE_CHROMA_CANVAS_ADDR_BIT, |
| WRITE_CHROMA_CANVAS_ADDR_WID); |
| } |
| |
| void vdin_set_crc_pulse(struct vdin_dev_s *devp) |
| { |
| if (!cpu_after_eq(MESON_CPU_MAJOR_ID_SM1) || |
| cpu_after_eq(MESON_CPU_MAJOR_ID_T5W)) |
| return; |
| |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| if (devp->flags & VDIN_FLAG_RDMA_ENABLE) { |
| rdma_write_reg(devp->rdma_handle, |
| VDIN_CRC_CHK + devp->addr_offset, 1); |
| } else { |
| #endif |
| wr(devp->addr_offset, VDIN_CRC_CHK, 1); |
| #ifdef CONFIG_AMLOGIC_MEDIA_RDMA |
| } |
| #endif |
| } |
| |
| /* reset default writing cavnas register */ |
| void vdin_set_def_wr_canvas(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int def_canvas; |
| |
| def_canvas = vdin_canvas_ids[devp->index][0]; |
| |
| /* [31:24] write.out_ctrl = 0x0b */ |
| /* [ 23] write.frame_rst_on_vs = 1 */ |
| /* [ 22] write.lfifo_rst_on_vs = 1 */ |
| /* [ 21] write.clr_direct_done = 0 */ |
| /* [ 20] write.clr_nr_done = 0 */ |
| /* [ 12] write.format444 = 1/(422, 444) */ |
| /* [ 11] write.canvas_latch_en = 0 */ |
| /* [ 9] write.req_urgent = 0 ***sub_module.enable*** */ |
| /* [ 8] write.req_en = 0 ***sub_module.enable*** */ |
| /* [ 7: 0] write.canvas = 0 */ |
| if (enable_reset) |
| wr(offset, VDIN_WR_CTRL, (0x0b401000 | def_canvas)); |
| else |
| wr(offset, VDIN_WR_CTRL, (0x0bc01000 | def_canvas)); |
| } |
| |
| /*set local dimming*/ |
| #ifdef CONFIG_AML_LOCAL_DIMMING |
| |
| #define VDIN_LDIM_PIC_ROWMAX 1080 |
| #define VDIN_LDIM_PIC_COLMAX 1920 |
| #define VDIN_LDIMMAX_HIDX 4095 |
| #define VDIN_LDIM_BLK_VNUM 2 |
| #define VDIN_LDIM_BLK_HNUM 8 |
| |
| static void vdin_set_ldim_max_init(unsigned int offset, |
| int pic_h, int pic_v, int blk_vnum, |
| int blk_hnum) |
| { |
| int k; |
| struct ldim_max_s ldimmax; |
| int ldim_pic_rowmax = VDIN_LDIM_PIC_ROWMAX; |
| int ldim_pic_colmax = VDIN_LDIM_PIC_COLMAX; |
| int ldim_blk_vnum = VDIN_LDIM_BLK_VNUM; |
| int ldim_blk_hnum = VDIN_LDIM_BLK_HNUM; |
| |
| ldim_pic_rowmax = pic_v; |
| ldim_pic_colmax = pic_h; |
| ldim_blk_vnum = blk_vnum; /* 8; */ |
| ldim_blk_hnum = blk_hnum; /* 2; */ |
| ldimmax.ld_stamax_hidx[0] = 0; |
| |
| /* check ic type */ |
| if (!is_meson_gxtvbb_cpu()) |
| return; |
| if (vdin_ctl_dbg) |
| pr_info("\n****************%s:hidx start********\n", __func__); |
| for (k = 1; k < 11; k++) { |
| ldimmax.ld_stamax_hidx[k] = |
| ((ldim_pic_colmax + ldim_blk_hnum - 1) / |
| ldim_blk_hnum) * k; |
| if (ldimmax.ld_stamax_hidx[k] > VDIN_LDIMMAX_HIDX) |
| /* clip U12 */ |
| ldimmax.ld_stamax_hidx[k] = VDIN_LDIMMAX_HIDX; |
| if (ldimmax.ld_stamax_hidx[k] == ldim_pic_colmax) |
| ldimmax.ld_stamax_hidx[k] = ldim_pic_colmax - 1; |
| if (vdin_ctl_dbg) |
| pr_info("%d\t", ldimmax.ld_stamax_hidx[k]); |
| } |
| if (vdin_ctl_dbg) |
| pr_info("\n****************%s:hidx end*********\n", __func__); |
| ldimmax.ld_stamax_vidx[0] = 0; |
| if (vdin_ctl_dbg) |
| pr_info("\n***********%s:vidx start************\n", __func__); |
| for (k = 1; k < 11; k++) { |
| ldimmax.ld_stamax_vidx[k] = ((ldim_pic_rowmax + |
| ldim_blk_vnum - 1) / |
| ldim_blk_vnum) * k; |
| if (ldimmax.ld_stamax_vidx[k] > VDIN_LDIMMAX_HIDX) |
| /* clip to U12 */ |
| ldimmax.ld_stamax_vidx[k] = VDIN_LDIMMAX_HIDX; |
| if (ldimmax.ld_stamax_vidx[k] == ldim_pic_rowmax) |
| ldimmax.ld_stamax_vidx[k] = ldim_pic_rowmax - 1; |
| if (vdin_ctl_dbg) |
| pr_info("%d\t", ldimmax.ld_stamax_vidx[k]); |
| } |
| if (vdin_ctl_dbg) |
| pr_info("\n*******%s:vidx end*******\n", __func__); |
| wr(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, |
| (1 << LOCAL_DIM_STATISTIC_EN_BIT) | |
| (0 << EOL_EN_BIT) | |
| (2 << VLINE_OVERLAP_NUMBER_BIT) | |
| (1 << HLINE_OVERLAP_NUMBER_BIT) | |
| (1 << LPF_BEFORE_STATISTIC_EN_BIT) | |
| (1 << REGION_RD_INDEX_INC_BIT)); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 0, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_vidx[0] << 16 | ldimmax.ld_stamax_hidx[0]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 1, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_hidx[2] << 16 | ldimmax.ld_stamax_hidx[1]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 2, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_vidx[2] << 16 | ldimmax.ld_stamax_vidx[1]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 3, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_hidx[4] << 16 | ldimmax.ld_stamax_hidx[3]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 4, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_vidx[4] << 16 | ldimmax.ld_stamax_vidx[3]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 5, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_hidx[6] << 16 | ldimmax.ld_stamax_hidx[5]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 6, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_vidx[6] << 16 | ldimmax.ld_stamax_vidx[5]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 7, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_hidx[8] << 16 | ldimmax.ld_stamax_hidx[7]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 8, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_vidx[8] << 16 | ldimmax.ld_stamax_vidx[7]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 9, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_hidx[10] << 16 | ldimmax.ld_stamax_hidx[9]); |
| wr_bits(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 10, |
| BLK_HV_POS_IDXS_BIT, BLK_HV_POS_IDXS_WID); |
| wr(offset, VDIN_LDIM_STTS_HIST_SET_REGION, |
| ldimmax.ld_stamax_vidx[10] << 16 | ldimmax.ld_stamax_vidx[9]); |
| wr_bits(offset, VDIN_HIST_CTRL, 3, 9, 2); |
| wr_bits(offset, VDIN_HIST_CTRL, 1, 8, 1); |
| } |
| |
| #endif |
| |
| static unsigned int vdin_luma_max; |
| |
| void vdin_set_vframe_prop_info(struct vframe_s *vf, |
| struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| u64 divid; |
| struct vframe_bbar_s bbar = {0}; |
| |
| #ifdef CONFIG_AML_LOCAL_DIMMING |
| /*int i;*/ |
| #endif |
| /* fetch hist info */ |
| /* vf->prop.hist.luma_sum = READ_CBUS_REG_BITS(VDIN_HIST_SPL_VAL, |
| * HIST_LUMA_SUM_BIT, HIST_LUMA_SUM_WID ); |
| */ |
| vf->prop.hist.hist_pow = rd_bits(offset, VDIN_HIST_CTRL, |
| HIST_POW_BIT, HIST_POW_WID); |
| vf->prop.hist.luma_sum = rd(offset, VDIN_HIST_SPL_VAL); |
| /* vf->prop.hist.chroma_sum = READ_CBUS_REG_BITS(VDIN_HIST_CHROMA_SUM, |
| * HIST_CHROMA_SUM_BIT, HIST_CHROMA_SUM_WID ); |
| */ |
| vf->prop.hist.chroma_sum = rd(offset, VDIN_HIST_CHROMA_SUM); |
| vf->prop.hist.pixel_sum = rd_bits(offset, VDIN_HIST_SPL_PIX_CNT, |
| HIST_PIX_CNT_BIT, HIST_PIX_CNT_WID); |
| vf->prop.hist.height = rd_bits(offset, VDIN_HIST_V_START_END, |
| HIST_VEND_BIT, HIST_VEND_WID) - |
| rd_bits(offset, VDIN_HIST_V_START_END, |
| HIST_VSTART_BIT, HIST_VSTART_WID) + 1; |
| vf->prop.hist.width = rd_bits(offset, VDIN_HIST_H_START_END, |
| HIST_HEND_BIT, HIST_HEND_WID) - |
| rd_bits(offset, VDIN_HIST_H_START_END, |
| HIST_HSTART_BIT, HIST_HSTART_WID) + 1; |
| vf->prop.hist.luma_max = rd_bits(offset, VDIN_HIST_MAX_MIN, |
| HIST_MAX_BIT, HIST_MAX_WID); |
| vf->prop.hist.luma_min = rd_bits(offset, VDIN_HIST_MAX_MIN, |
| HIST_MIN_BIT, HIST_MIN_WID); |
| vf->prop.hist.gamma[0] = rd_bits(offset, VDIN_DNLP_HIST00, |
| HIST_ON_BIN_00_BIT, |
| HIST_ON_BIN_00_WID); |
| vf->prop.hist.gamma[1] = rd_bits(offset, VDIN_DNLP_HIST00, |
| HIST_ON_BIN_01_BIT, |
| HIST_ON_BIN_01_WID); |
| vf->prop.hist.gamma[2] = rd_bits(offset, VDIN_DNLP_HIST01, |
| HIST_ON_BIN_02_BIT, |
| HIST_ON_BIN_02_WID); |
| vf->prop.hist.gamma[3] = rd_bits(offset, VDIN_DNLP_HIST01, |
| HIST_ON_BIN_03_BIT, |
| HIST_ON_BIN_03_WID); |
| vf->prop.hist.gamma[4] = rd_bits(offset, VDIN_DNLP_HIST02, |
| HIST_ON_BIN_04_BIT, |
| HIST_ON_BIN_04_WID); |
| vf->prop.hist.gamma[5] = rd_bits(offset, VDIN_DNLP_HIST02, |
| HIST_ON_BIN_05_BIT, |
| HIST_ON_BIN_05_WID); |
| vf->prop.hist.gamma[6] = rd_bits(offset, VDIN_DNLP_HIST03, |
| HIST_ON_BIN_06_BIT, |
| HIST_ON_BIN_06_WID); |
| vf->prop.hist.gamma[7] = rd_bits(offset, VDIN_DNLP_HIST03, |
| HIST_ON_BIN_07_BIT, |
| HIST_ON_BIN_07_WID); |
| vf->prop.hist.gamma[8] = rd_bits(offset, VDIN_DNLP_HIST04, |
| HIST_ON_BIN_08_BIT, |
| HIST_ON_BIN_08_WID); |
| vf->prop.hist.gamma[9] = rd_bits(offset, VDIN_DNLP_HIST04, |
| HIST_ON_BIN_09_BIT, |
| HIST_ON_BIN_09_WID); |
| vf->prop.hist.gamma[10] = rd_bits(offset, VDIN_DNLP_HIST05, |
| HIST_ON_BIN_10_BIT, |
| HIST_ON_BIN_10_WID); |
| vf->prop.hist.gamma[11] = rd_bits(offset, VDIN_DNLP_HIST05, |
| HIST_ON_BIN_11_BIT, |
| HIST_ON_BIN_11_WID); |
| vf->prop.hist.gamma[12] = rd_bits(offset, VDIN_DNLP_HIST06, |
| HIST_ON_BIN_12_BIT, |
| HIST_ON_BIN_12_WID); |
| vf->prop.hist.gamma[13] = rd_bits(offset, VDIN_DNLP_HIST06, |
| HIST_ON_BIN_13_BIT, |
| HIST_ON_BIN_13_WID); |
| vf->prop.hist.gamma[14] = rd_bits(offset, VDIN_DNLP_HIST07, |
| HIST_ON_BIN_14_BIT, |
| HIST_ON_BIN_14_WID); |
| vf->prop.hist.gamma[15] = rd_bits(offset, VDIN_DNLP_HIST07, |
| HIST_ON_BIN_15_BIT, |
| HIST_ON_BIN_15_WID); |
| vf->prop.hist.gamma[16] = rd_bits(offset, VDIN_DNLP_HIST08, |
| HIST_ON_BIN_16_BIT, |
| HIST_ON_BIN_16_WID); |
| vf->prop.hist.gamma[17] = rd_bits(offset, VDIN_DNLP_HIST08, |
| HIST_ON_BIN_17_BIT, |
| HIST_ON_BIN_17_WID); |
| vf->prop.hist.gamma[18] = rd_bits(offset, VDIN_DNLP_HIST09, |
| HIST_ON_BIN_18_BIT, |
| HIST_ON_BIN_18_WID); |
| vf->prop.hist.gamma[19] = rd_bits(offset, VDIN_DNLP_HIST09, |
| HIST_ON_BIN_19_BIT, |
| HIST_ON_BIN_19_WID); |
| vf->prop.hist.gamma[20] = rd_bits(offset, VDIN_DNLP_HIST10, |
| HIST_ON_BIN_20_BIT, |
| HIST_ON_BIN_20_WID); |
| vf->prop.hist.gamma[21] = rd_bits(offset, VDIN_DNLP_HIST10, |
| HIST_ON_BIN_21_BIT, |
| HIST_ON_BIN_21_WID); |
| vf->prop.hist.gamma[22] = rd_bits(offset, VDIN_DNLP_HIST11, |
| HIST_ON_BIN_22_BIT, |
| HIST_ON_BIN_22_WID); |
| vf->prop.hist.gamma[23] = rd_bits(offset, VDIN_DNLP_HIST11, |
| HIST_ON_BIN_23_BIT, |
| HIST_ON_BIN_23_WID); |
| vf->prop.hist.gamma[24] = rd_bits(offset, VDIN_DNLP_HIST12, |
| HIST_ON_BIN_24_BIT, |
| HIST_ON_BIN_24_WID); |
| vf->prop.hist.gamma[25] = rd_bits(offset, VDIN_DNLP_HIST12, |
| HIST_ON_BIN_25_BIT, |
| HIST_ON_BIN_25_WID); |
| vf->prop.hist.gamma[26] = rd_bits(offset, VDIN_DNLP_HIST13, |
| HIST_ON_BIN_26_BIT, |
| HIST_ON_BIN_26_WID); |
| vf->prop.hist.gamma[27] = rd_bits(offset, VDIN_DNLP_HIST13, |
| HIST_ON_BIN_27_BIT, |
| HIST_ON_BIN_27_WID); |
| vf->prop.hist.gamma[28] = rd_bits(offset, VDIN_DNLP_HIST14, |
| HIST_ON_BIN_28_BIT, |
| HIST_ON_BIN_28_WID); |
| vf->prop.hist.gamma[29] = rd_bits(offset, VDIN_DNLP_HIST14, |
| HIST_ON_BIN_29_BIT, |
| HIST_ON_BIN_29_WID); |
| vf->prop.hist.gamma[30] = rd_bits(offset, VDIN_DNLP_HIST15, |
| HIST_ON_BIN_30_BIT, |
| HIST_ON_BIN_30_WID); |
| vf->prop.hist.gamma[31] = rd_bits(offset, VDIN_DNLP_HIST15, |
| HIST_ON_BIN_31_BIT, |
| HIST_ON_BIN_31_WID); |
| vf->prop.hist.gamma[32] = rd_bits(offset, VDIN_DNLP_HIST16, |
| HIST_ON_BIN_32_BIT, |
| HIST_ON_BIN_32_WID); |
| vf->prop.hist.gamma[33] = rd_bits(offset, VDIN_DNLP_HIST16, |
| HIST_ON_BIN_33_BIT, |
| HIST_ON_BIN_33_WID); |
| vf->prop.hist.gamma[34] = rd_bits(offset, VDIN_DNLP_HIST17, |
| HIST_ON_BIN_34_BIT, |
| HIST_ON_BIN_34_WID); |
| vf->prop.hist.gamma[35] = rd_bits(offset, VDIN_DNLP_HIST17, |
| HIST_ON_BIN_35_BIT, |
| HIST_ON_BIN_35_WID); |
| vf->prop.hist.gamma[36] = rd_bits(offset, VDIN_DNLP_HIST18, |
| HIST_ON_BIN_36_BIT, |
| HIST_ON_BIN_36_WID); |
| vf->prop.hist.gamma[37] = rd_bits(offset, VDIN_DNLP_HIST18, |
| HIST_ON_BIN_37_BIT, |
| HIST_ON_BIN_37_WID); |
| vf->prop.hist.gamma[38] = rd_bits(offset, VDIN_DNLP_HIST19, |
| HIST_ON_BIN_38_BIT, |
| HIST_ON_BIN_38_WID); |
| vf->prop.hist.gamma[39] = rd_bits(offset, VDIN_DNLP_HIST19, |
| HIST_ON_BIN_39_BIT, |
| HIST_ON_BIN_39_WID); |
| vf->prop.hist.gamma[40] = rd_bits(offset, VDIN_DNLP_HIST20, |
| HIST_ON_BIN_40_BIT, |
| HIST_ON_BIN_40_WID); |
| vf->prop.hist.gamma[41] = rd_bits(offset, VDIN_DNLP_HIST20, |
| HIST_ON_BIN_41_BIT, |
| HIST_ON_BIN_41_WID); |
| vf->prop.hist.gamma[42] = rd_bits(offset, VDIN_DNLP_HIST21, |
| HIST_ON_BIN_42_BIT, |
| HIST_ON_BIN_42_WID); |
| vf->prop.hist.gamma[43] = rd_bits(offset, VDIN_DNLP_HIST21, |
| HIST_ON_BIN_43_BIT, |
| HIST_ON_BIN_43_WID); |
| vf->prop.hist.gamma[44] = rd_bits(offset, VDIN_DNLP_HIST22, |
| HIST_ON_BIN_44_BIT, |
| HIST_ON_BIN_44_WID); |
| vf->prop.hist.gamma[45] = rd_bits(offset, VDIN_DNLP_HIST22, |
| HIST_ON_BIN_45_BIT, |
| HIST_ON_BIN_45_WID); |
| vf->prop.hist.gamma[46] = rd_bits(offset, VDIN_DNLP_HIST23, |
| HIST_ON_BIN_46_BIT, |
| HIST_ON_BIN_46_WID); |
| vf->prop.hist.gamma[47] = rd_bits(offset, VDIN_DNLP_HIST23, |
| HIST_ON_BIN_47_BIT, |
| HIST_ON_BIN_47_WID); |
| vf->prop.hist.gamma[48] = rd_bits(offset, VDIN_DNLP_HIST24, |
| HIST_ON_BIN_48_BIT, |
| HIST_ON_BIN_48_WID); |
| vf->prop.hist.gamma[49] = rd_bits(offset, VDIN_DNLP_HIST24, |
| HIST_ON_BIN_49_BIT, |
| HIST_ON_BIN_49_WID); |
| vf->prop.hist.gamma[50] = rd_bits(offset, VDIN_DNLP_HIST25, |
| HIST_ON_BIN_50_BIT, |
| HIST_ON_BIN_50_WID); |
| vf->prop.hist.gamma[51] = rd_bits(offset, VDIN_DNLP_HIST25, |
| HIST_ON_BIN_51_BIT, |
| HIST_ON_BIN_51_WID); |
| vf->prop.hist.gamma[52] = rd_bits(offset, VDIN_DNLP_HIST26, |
| HIST_ON_BIN_52_BIT, |
| HIST_ON_BIN_52_WID); |
| vf->prop.hist.gamma[53] = rd_bits(offset, VDIN_DNLP_HIST26, |
| HIST_ON_BIN_53_BIT, |
| HIST_ON_BIN_53_WID); |
| vf->prop.hist.gamma[54] = rd_bits(offset, VDIN_DNLP_HIST27, |
| HIST_ON_BIN_54_BIT, |
| HIST_ON_BIN_54_WID); |
| vf->prop.hist.gamma[55] = rd_bits(offset, VDIN_DNLP_HIST27, |
| HIST_ON_BIN_55_BIT, |
| HIST_ON_BIN_55_WID); |
| vf->prop.hist.gamma[56] = rd_bits(offset, VDIN_DNLP_HIST28, |
| HIST_ON_BIN_56_BIT, |
| HIST_ON_BIN_56_WID); |
| vf->prop.hist.gamma[57] = rd_bits(offset, VDIN_DNLP_HIST28, |
| HIST_ON_BIN_57_BIT, |
| HIST_ON_BIN_57_WID); |
| vf->prop.hist.gamma[58] = rd_bits(offset, VDIN_DNLP_HIST29, |
| HIST_ON_BIN_58_BIT, |
| HIST_ON_BIN_58_WID); |
| vf->prop.hist.gamma[59] = rd_bits(offset, VDIN_DNLP_HIST29, |
| HIST_ON_BIN_59_BIT, |
| HIST_ON_BIN_59_WID); |
| vf->prop.hist.gamma[60] = rd_bits(offset, VDIN_DNLP_HIST30, |
| HIST_ON_BIN_60_BIT, |
| HIST_ON_BIN_60_WID); |
| vf->prop.hist.gamma[61] = rd_bits(offset, VDIN_DNLP_HIST30, |
| HIST_ON_BIN_61_BIT, |
| HIST_ON_BIN_61_WID); |
| vf->prop.hist.gamma[62] = rd_bits(offset, VDIN_DNLP_HIST31, |
| HIST_ON_BIN_62_BIT, |
| HIST_ON_BIN_62_WID); |
| vf->prop.hist.gamma[63] = rd_bits(offset, VDIN_DNLP_HIST31, |
| HIST_ON_BIN_63_BIT, |
| HIST_ON_BIN_63_WID); |
| |
| /* fetch bbar info */ |
| bbar.top = rd_bits(offset, VDIN_BLKBAR_STATUS0, |
| BLKBAR_TOP_POS_BIT, BLKBAR_TOP_POS_WID); |
| bbar.bottom = rd_bits(offset, VDIN_BLKBAR_STATUS0, |
| BLKBAR_BTM_POS_BIT, BLKBAR_BTM_POS_WID); |
| bbar.left = rd_bits(offset, VDIN_BLKBAR_STATUS1, |
| BLKBAR_LEFT_POS_BIT, BLKBAR_LEFT_POS_WID); |
| bbar.right = rd_bits(offset, VDIN_BLKBAR_STATUS1, |
| BLKBAR_RIGHT_POS_BIT, BLKBAR_RIGHT_POS_WID); |
| if (bbar.top > bbar.bottom) { |
| bbar.top = 0; |
| bbar.bottom = vf->height - 1; |
| } |
| if (bbar.left > bbar.right) { |
| bbar.left = 0; |
| bbar.right = vf->width - 1; |
| } |
| |
| /* Update Histgram windown with detected BlackBar window */ |
| if (devp->hist_bar_enable) |
| vdin_set_histogram(offset, 0, vf->width - 1, 0, vf->height - 1); |
| else |
| vdin_set_histogram(offset, bbar.left, bbar.right, |
| bbar.top, bbar.bottom); |
| |
| if (devp->black_bar_enable) { |
| vf->prop.bbar.top = bbar.top; |
| vf->prop.bbar.bottom = bbar.bottom; |
| vf->prop.bbar.left = bbar.left; |
| vf->prop.bbar.right = bbar.right; |
| } else { |
| memset(&vf->prop.bbar, 0, sizeof(struct vframe_bbar_s)); |
| } |
| |
| /* fetch meas info - For M2 or further chips only, not for M1 chip */ |
| vf->prop.meas.vs_stamp = devp->stamp; |
| vf->prop.meas.vs_cycle = devp->cycle; |
| if ((vdin_ctl_dbg & (1 << 8)) && |
| vdin_luma_max != vf->prop.hist.luma_max) { |
| vf->ready_clock_hist[0] = sched_clock(); |
| divid = vf->ready_clock_hist[0]; |
| do_div(divid, 1000); |
| pr_info("vdin write done %lld us. lum_max(0x%x-->0x%x)\n", |
| divid, vdin_luma_max, vf->prop.hist.luma_max); |
| vdin_luma_max = vf->prop.hist.luma_max; |
| } |
| } |
| |
| void vdin_get_crc_val(struct vframe_s *vf, struct vdin_dev_s *devp) |
| { |
| /* fetch CRC value of the previous frame */ |
| vf->crc = rd(devp->addr_offset, VDIN_RO_CRC); |
| } |
| |
| static inline ulong vdin_reg_limit(ulong val, ulong wid) |
| { |
| if (val < (1 << wid)) |
| return val; |
| else |
| return (1 << wid) - 1; |
| } |
| |
| void vdin_set_all_regs(struct vdin_dev_s *devp) |
| { |
| /* matrix sub-module */ |
| vdin_set_matrix(devp); |
| |
| /* bbar sub-module */ |
| vdin_set_bbar(devp->addr_offset, devp->v_active, devp->h_active); |
| #ifdef CONFIG_AML_LOCAL_DIMMING |
| /* ldim sub-module */ |
| /* vdin_set_ldim_max_init(devp->addr_offset, 1920, 1080, 8, 2); */ |
| vdin_set_ldim_max_init(devp->addr_offset, devp->h_active, |
| devp->v_active, |
| VDIN_LDIM_BLK_HNUM, VDIN_LDIM_BLK_VNUM); |
| #endif |
| /* hist sub-module */ |
| vdin_set_histogram(devp->addr_offset, 0, |
| devp->h_active - 1, 0, devp->v_active - 1); |
| /* hist mux selecttion */ |
| vdin_set_hist_mux(devp); |
| /* write sub-module */ |
| vdin_set_wr_ctrl(devp, devp->addr_offset, devp->v_active, |
| devp->h_active, devp->format_convert, |
| devp->full_pack, devp->source_bitdepth); |
| |
| /* top sub-module */ |
| vdin_set_top(devp, devp->addr_offset, devp->parm.port, |
| devp->prop.color_format, devp->h_active, |
| devp->bt_path); |
| |
| vdin_set_meas_mux(devp->addr_offset, devp->parm.port, |
| devp->bt_path); |
| |
| /* for t7 vdin2 write meta data */ |
| if (devp->dtdata->hw_ver == VDIN_HW_T7) { |
| vdin_wrmif2_initial(devp); |
| vdin_wrmif2_addr_update(devp); |
| vdin_wrmif2_enable(devp, 0); |
| } |
| } |
| |
| void vdin_set_dolby_tunnel(struct vdin_dev_s *devp) |
| { |
| unsigned int vdin_data_bus_0 = VDIN_MAP_BPB; |
| unsigned int vdin_data_bus_1 = VDIN_MAP_Y_G; |
| unsigned int vdin_data_bus_2 = VDIN_MAP_RCR; |
| unsigned int offset; |
| struct tvin_state_machine_ops_s *sm_ops; |
| |
| /* avoid null pointer oops */ |
| if (!devp || !(devp->frontend) || !(devp->frontend->sm_ops) || |
| !(devp->frontend->sm_ops->hdmi_dv_config)) |
| return; |
| |
| if (!IS_HDMI_SRC(devp->parm.port)) |
| return; |
| |
| sm_ops = devp->frontend->sm_ops; |
| |
| if (devp->dv.dv_flag/* && is_dolby_vision_enable()*/ && |
| !(is_dolby_vision_stb_mode() && cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) && |
| /*&& (devp->dv.low_latency)*/ |
| devp->prop.color_format == TVIN_YUV422) { |
| offset = devp->addr_offset; |
| /*channel map*/ |
| wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_0, |
| COMP0_OUT_SWT_BIT, COMP0_OUT_SWT_WID); |
| wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_1, |
| COMP1_OUT_SWT_BIT, COMP1_OUT_SWT_WID); |
| wr_bits(offset, VDIN_COM_CTRL0, vdin_data_bus_2, |
| COMP2_OUT_SWT_BIT, COMP2_OUT_SWT_WID); |
| /*hdmi rx call back, 422 tunnel to 444*/ |
| sm_ops->hdmi_dv_config(true, devp->frontend); |
| pr_info("dv rx tunnel mode\n"); |
| } else { |
| sm_ops->hdmi_dv_config(false, devp->frontend); |
| } |
| } |
| |
| static void vdin_delay_line(unsigned short num, unsigned int offset) |
| { |
| wr_bits(offset, VDIN_COM_CTRL0, num, |
| DLY_GO_FLD_LN_NUM_BIT, DLY_GO_FLD_LN_NUM_WID); |
| if (num) |
| wr_bits(offset, VDIN_COM_CTRL0, 1, |
| DLY_GO_FLD_EN_BIT, DLY_GO_FLD_EN_WID); |
| else |
| wr_bits(offset, VDIN_COM_CTRL0, 0, |
| DLY_GO_FLD_EN_BIT, DLY_GO_FLD_EN_WID); |
| } |
| |
| void vdin_set_double_write_regs(struct vdin_dev_s *devp) |
| { |
| if (devp->double_wr) { |
| if (devp->index == 0) { |
| /* vdin0 normal->afbce, small->mif0 */ |
| wr_bits(0, VDIN_TOP_DOUBLE_CTRL, WR_SEL_VDIN0_NOR, |
| AFBCE_OUT_SEL_BIT, VDIN_REORDER_SEL_WID); |
| wr_bits(0, VDIN_TOP_DOUBLE_CTRL, WR_SEL_VDIN0_SML, |
| MIF0_OUT_SEL_BIT, VDIN_REORDER_SEL_WID); |
| /* enable both channel for double wr */ |
| /*wr(0, VDIN_LFIFO_CTRL, 0xc0060f00);*/ |
| wr_bits(0, VDIN_LFIFO_CTRL, 0x1, CH0_OUT_EN_BIT, 1); |
| wr_bits(0, VDIN_LFIFO_CTRL, 0x1, CH1_OUT_EN_BIT, 1); |
| wr_bits(0, VDIN_LFIFO_CTRL, 0x3, 30, 2); |
| } |
| } |
| } |
| |
| void vdin_set_default_regmap(struct vdin_dev_s *devp) |
| { |
| /*unsigned int def_canvas_id;*/ |
| unsigned int offset = devp->addr_offset; |
| |
| /* [ 31] mpeg.en = 0 ***sub_module.enable*** */ |
| /* [ 30] mpeg.even_fld = 0/(odd, even) */ |
| |
| /* [26:20] top.hold_ln = 0 //8 */ |
| /* [ 19] vs_dly.en = 0 ***sub_module.enable*** */ |
| /* [18:12] vs_dly.dly_ln = 0 */ |
| /* [11:10] map.comp2 = 2/(comp0, comp1, comp2) */ |
| /* [ 9: 8] map.comp1 = 1/(comp0, comp1, comp2) */ |
| /* [ 7: 6] map.comp0 = 0/(comp0, comp1, comp2) */ |
| |
| /* [ 4] top.datapath_en = 1 */ |
| /* [ 3: 0] top.mux = 0/(null, mpeg, 656, tvfe, cvd2, hdmi, dvin) */ |
| wr(offset, VDIN_COM_CTRL0, 0x00000910); |
| vdin_delay_line(delay_line_num, offset); |
| /* [ 23] asfifo_hdmi.de_en = 1 */ |
| /* [ 22] asfifo_hdmi.vs_en = 1 */ |
| /* [ 21] asfifo_hdmi.hs_en = 1 */ |
| /* [ 20] asfifo_hdmi.vs_inv = 0/(positive-active, negative-active) */ |
| /* [ 19] asfifo_hdmi.hs_inv = 0/(positive-active, negative-active) */ |
| /* [ 18] asfifo_hdmi.rst_on_vs = 1 */ |
| /* [ 17] asfifo_hdmi.clr_ov_flag = 0 */ |
| /* [ 16] asfifo_hdmi.rst = 0 */ |
| /* [ 7] asfifo_cvd2.de_en = 1 */ |
| /* [ 6] asfifo_cvd2.vs_en = 1 */ |
| /* [ 5] asfifo_cvd2.hs_en = 1 */ |
| /* [ 4] asfifo_cvd2.vs_inv = 0/(positive-active, negative-active) */ |
| /* [ 3] asfifo_cvd2.hs_inv = 0/(positive-active, negative-active) */ |
| /* [ 2] asfifo_cvd2.rst_on_vs = 1 */ |
| /* [ 1] asfifo_cvd2.clr_ov_flag = 0 */ |
| /* [ 0] asfifo_cvd2.rst = 0 */ |
| /* wr(offset, VDIN_ASFIFO_CTRL1, 0x00000000); */ |
| /* [28:16] top.input_width_m1 = 0 */ |
| /* [12: 0] top.output_width_m1 = 0 */ |
| wr(offset, VDIN_WIDTHM1I_WIDTHM1O, 0x00000000); |
| /* [14: 8] hsc.init_pix_in_ptr = 0 */ |
| /* [ 7] hsc.phsc_en = 0 */ |
| /* [ 6] hsc.en = 0 ***sub_module.enable*** */ |
| /* [ 5] hsc.short_ln_en = 1 */ |
| /* [ 4] hsc.nearest_en = 0 */ |
| /* [ 3] hsc.phase0_always = 1 */ |
| /* [ 2: 0] hsc.filt_dep = 0/(DEPTH4,DEPTH1, DEPTH2, DEPTH3) */ |
| /* wr(offset, VDIN_SC_MISC_CTRL, 0x00000028); */ |
| /* [28:24] hsc.phase_step_int = 0 <u5.0> */ |
| /* [23: 0] hsc.phase_step_fra = 0 <u0.24> */ |
| /* wr(offset, VDIN_HSC_PHASE_STEP, 0x00000000); */ |
| /* [30:29] hsc.repeat_pix0_num = 1 // ? |
| * to confirm pix0 is always used |
| */ |
| /* [28:24] hsc.ini_receive_num = 4 // ? |
| * to confirm pix0 is always used |
| */ |
| /* [23: 0] hsc.ini_phase = 0 */ |
| /* wr(offset, VDIN_HSC_INI_CTRL, 0x24000000); */ |
| |
| /* [ 25] decimation.rst = 0 */ |
| /* [ 24] decimation.en = 0 ***sub_module.enable*** */ |
| /* [23:20] decimation.phase = 0 */ |
| /* [19:16] decimation.ratio = 0/(1, 1/2, ..., 1/16) */ |
| /* [ 7] asfifo_dvin.de_en = 1 */ |
| /* [ 6] asfifo_dvin.vs_en = 1 */ |
| /* [ 5] asfifo_dvin.hs_en = 1 */ |
| /* [ 4] asfifo_dvin.vs_inv = 0/(positive-active, negative-active) */ |
| /* [ 3] asfifo_dvin.hs_inv = 0/(positive-active, negative-active) */ |
| /* [ 2] asfifo_dvin.rst_on_vs = 1 */ |
| /* [ 1] asfifo_dvin.clr_ov_flag = 0 */ |
| /* [ 0] asfifo_dvin.rst = 0 */ |
| wr(offset, VDIN_ASFIFO_CTRL2, 0x00000000); |
| |
| /* [ 0] matrix.en = 0 ***sub_module.enable*** */ |
| wr(offset, VDIN_MATRIX_CTRL, 0x00000000); |
| /* [28:16] matrix.coef00 = 0 <s2.10> */ |
| /* [12: 0] matrix.coef01 = 0 <s2.10> */ |
| wr(offset, VDIN_MATRIX_COEF00_01, 0x00000000); |
| /* [28:16] matrix.coef02 = 0 <s2.10> */ |
| /* [12: 0] matrix.coef10 = 0 <s2.10> */ |
| wr(offset, VDIN_MATRIX_COEF02_10, 0x00000000); |
| /* [28:16] matrix.coef11 = 0 <s2.10> */ |
| /* [12: 0] matrix.coef12 = 0 <s2.10> */ |
| wr(offset, VDIN_MATRIX_COEF11_12, 0x00000000); |
| /* [28:16] matrix.coef20 = 0 <s2.10> */ |
| /* [12: 0] matrix.coef21 = 0 <s2.10> */ |
| wr(offset, VDIN_MATRIX_COEF20_21, 0x00000000); |
| /* [12: 0] matrix.coef22 = 0 <s2.10> */ |
| wr(offset, VDIN_MATRIX_COEF22, 0x00000000); |
| /* [26:16] matrix.offset0 = 0 <s8.2> */ |
| /* [10: 0] matrix.ofsset1 = 0 <s8.2> */ |
| wr(offset, VDIN_MATRIX_OFFSET0_1, 0x00000000); |
| /* [10: 0] matrix.ofsset2 = 0 <s8.2> */ |
| wr(offset, VDIN_MATRIX_OFFSET2, 0x00000000); |
| /* [26:16] matrix.pre_offset0 = 0 <s8.2> */ |
| /* [10: 0] matrix.pre_ofsset1 = 0 <s8.2> */ |
| wr(offset, VDIN_MATRIX_PRE_OFFSET0_1, 0x00000000); |
| /* [10: 0] matrix.pre_ofsset2 = 0 <s8.2> */ |
| wr(offset, VDIN_MATRIX_PRE_OFFSET2, 0x00000000); |
| /* [11: 0] write.lfifo_buf_size = 0x100 */ |
| |
| /*line buffer set*/ |
| if (devp->index == 0) |
| wr_bits(offset, VDIN_LFIFO_CTRL, devp->dtdata->vdin0_line_buff_size, |
| LFIFO_BUF_SIZE_BIT, LFIFO_BUF_SIZE_WID); |
| else |
| wr_bits(offset, VDIN_LFIFO_CTRL, devp->dtdata->vdin1_line_buff_size, |
| LFIFO_BUF_SIZE_BIT, LFIFO_BUF_SIZE_WID); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| /*reset*/ |
| /*wr(offset, VDIN_LFIFO_CTRL, 0xc0000000);*/ |
| |
| /*t7 capture use small path*/ |
| if (devp->dtdata->hw_ver == VDIN_HW_T7 && devp->index) { |
| //wr_bits(offset, VDIN_LFIFO_CTRL, 2, 17, 2); |
| wr_bits(offset, VDIN_LFIFO_CTRL, 0, CH0_OUT_EN_BIT, CH_OUT_EN_WID); |
| wr_bits(offset, VDIN_LFIFO_CTRL, 1, CH1_OUT_EN_BIT, CH_OUT_EN_WID); |
| } else { |
| //wr_bits(offset, VDIN_LFIFO_CTRL, 1, 17, 2); |
| wr_bits(offset, VDIN_LFIFO_CTRL, 1, CH0_OUT_EN_BIT, CH_OUT_EN_WID); |
| wr_bits(offset, VDIN_LFIFO_CTRL, 0, CH1_OUT_EN_BIT, CH_OUT_EN_WID); |
| } |
| |
| wr(offset, VDIN_VSHRK_CTRL, 0); |
| |
| if (devp->index == 0) { |
| /* vdin0 normal->mif0 */ |
| wr_bits(0, VDIN_TOP_DOUBLE_CTRL, WR_SEL_DIS, |
| AFBCE_OUT_SEL_BIT, VDIN_REORDER_SEL_WID); |
| wr_bits(0, VDIN_TOP_DOUBLE_CTRL, WR_SEL_VDIN0_NOR, |
| MIF0_OUT_SEL_BIT, VDIN_REORDER_SEL_WID); |
| wr(offset, VDIN_HDR2_MATRIXI_EN_CTRL, 0); |
| } else { |
| if (devp->dtdata->hw_ver == VDIN_HW_T7) |
| wr_bits(0, VDIN_TOP_DOUBLE_CTRL, WR_SEL_VDIN1_SML, |
| MIF1_OUT_SEL_BIT, VDIN_REORDER_SEL_WID); |
| else |
| wr_bits(0, VDIN_TOP_DOUBLE_CTRL, WR_SEL_VDIN1_NOR, |
| MIF1_OUT_SEL_BIT, VDIN_REORDER_SEL_WID); |
| } |
| } |
| |
| /* [15:14] clkgate.bbar = 0/(auto, off, on, on) */ |
| /* [13:12] clkgate.bbar = 0/(auto, off, on, on) */ |
| /* [11:10] clkgate.bbar = 0/(auto, off, on, on) */ |
| /* [ 9: 8] clkgate.bbar = 0/(auto, off, on, on) */ |
| /* [ 7: 6] clkgate.bbar = 0/(auto, off, on, on) */ |
| /* [ 5: 4] clkgate.bbar = 0/(auto, off, on, on) */ |
| /* [ 3: 2] clkgate.bbar = 0/(auto, off, on, on) */ |
| /* [ 0] clkgate.bbar = 0/(auto, off!!!!!!!!) */ |
| wr(offset, VDIN_COM_GCLK_CTRL, 0x00000000); |
| |
| /* [12: 0] decimation.output_width_m1 = 0 */ |
| wr(offset, VDIN_INTF_WIDTHM1, 0x00000000); |
| |
| /*set canvas move to vdin_frame_write_ctrl_set*/ |
| /*def_canvas_id = offset ? vdin_canvas_ids[1][0] : vdin_canvas_ids[0][0];*/ |
| |
| /* [31:24] write.out_ctrl = 0x0b */ |
| /* [ 23] write.frame_rst_on_vs = 1 */ |
| /* [ 22] write.lfifo_rst_on_vs = 1 */ |
| /* [ 21] write.clr_direct_done = 0 */ |
| /* [ 20] write.clr_nr_done = 0 */ |
| /* [ 12] write.format444 = 1/(422, 444) */ |
| /* [ 11] write.canvas_latch_en = 0 */ |
| /* [ 9] write.req_urgent = 0 ***sub_module.enable*** */ |
| /* [ 8] write.req_en = 0 ***sub_module.enable*** */ |
| /* [ 7: 0] write.canvas = 0 */ |
| /*if (enable_reset)*/ |
| /* wr(offset, VDIN_WR_CTRL, (0x0b401000 | def_canvas_id));*/ |
| /*else*/ |
| /* wr(offset, VDIN_WR_CTRL, (0x0bc01000 | def_canvas_id));*/ |
| |
| /* [8] discard data before line fifo= 0 normal mode */ |
| /* [7:0] write chroma addr = 1 */ |
| /*wr_bits(offset, VDIN_WR_CTRL2, def_canvas_id + 1,*/ |
| /* WRITE_CHROMA_CANVAS_ADDR_BIT,*/ |
| /* WRITE_CHROMA_CANVAS_ADDR_WID);*/ |
| wr_bits(offset, VDIN_WR_CTRL2, 0, |
| DISCARD_BEF_LINE_FIFO_BIT, DISCARD_BEF_LINE_FIFO_WID); |
| wr_bits(offset, VDIN_WR_CTRL2, VDIN_WR_BURST_MODE, |
| VDIN_WR_BURST_MODE_BIT, VDIN_WR_BURST_MODE_WID); |
| if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) |
| wr_bits(offset, VDIN_WR_CTRL2, 1, |
| VDIN_WR_DATA_EXT_EN_BIT, VDIN_WR_DATA_EXT_EN_WID); |
| else |
| wr_bits(offset, VDIN_WR_CTRL2, 0, |
| VDIN_WR_DATA_EXT_EN_BIT, VDIN_WR_DATA_EXT_EN_WID); |
| /* [20:25] integer = 0 */ |
| /* [0:19] fraction = 0 */ |
| wr(offset, VDIN_VSC_PHASE_STEP, 0x0000000); |
| |
| /* disable hscale&pre hscale */ |
| wr_bits(offset, VDIN_SC_MISC_CTRL, 0, PRE_HSCL_EN_BIT, PRE_HSCL_EN_WID); |
| wr_bits(offset, VDIN_SC_MISC_CTRL, 0, HSCL_EN_BIT, HSCL_EN_WID); |
| |
| /* Bit 23, vsc_en, vertical scaler enable */ |
| /* Bit 21 vsc_phase0_always_en, when scale up, |
| * you have to set it to 1 |
| */ |
| /* Bit 20:16 ini skip_line_num */ |
| /* Bit 15:0 vscaler ini_phase */ |
| wr(offset, VDIN_VSC_INI_CTRL, 0x000000); |
| /* Bit 12:0, scaler input height minus 1 */ |
| /*wr(offset, VDIN_SCIN_HEIGHTM1,0x000000);*/ |
| wr_bits(offset, VDIN_SCIN_HEIGHTM1, 0, SCALER_INPUT_HEIGHT_BIT, |
| SCALER_INPUT_HEIGHT_WID); |
| |
| /* Bit 23:16, dummy component 0 */ |
| /* Bit 15:8, dummy component 1 */ |
| /* Bit 7:0, dummy component 2 */ |
| wr(offset, VDIN_DUMMY_DATA, 0x8080); |
| /* Bit 23:16 component 0 */ |
| /* Bit 15:8 component 1 */ |
| /* Bit 7:0 component 2 */ |
| wr(offset, VDIN_MATRIX_HL_COLOR, 0x000000); |
| /* 28:16 probe x, postion */ |
| /* 12:0 probe y, position */ |
| wr(offset, VDIN_MATRIX_PROBE_POS, 0x00000000); |
| /* Bit 31, local dimming statistic enable */ |
| /* Bit 28, eol enable */ |
| /* Bit 27:25, vertical line overlap number for max finding */ |
| /* Bit 24:22, horizontal pixel overlap number, |
| * 0: 17 pix, 1: 9 pix, 2: 5 pix, 3: 3 pix, 4: 0 pix |
| */ |
| /* Bit 20, 1,2,1 low pass filter enable before max/hist statistic */ |
| /* Bit 19:16, region H/V position index, |
| * refer to VDIN_LDIM_STTS_HIST_SET_REGION |
| */ |
| /* Bit 15, 1: region read index auto increase |
| * per read to VDIN_LDIM_STTS_HIST_READ_REGION |
| */ |
| #ifdef CONFIG_AML_LOCAL_DIMMING |
| /* Bit 6:0, region read index */ |
| if (is_meson_gxtvbb_cpu()) |
| wr(offset, VDIN_LDIM_STTS_HIST_REGION_IDX, 0x00000000); |
| #endif |
| /* [27:16] write.output_hs = 0 */ |
| /* [11: 0] write.output_he = 0 */ |
| wr(offset, VDIN_WR_H_START_END, 0x00000000); |
| /* [27:16] write.output_vs = 0 */ |
| /* [11: 0] write.output_ve = 0 */ |
| wr(offset, VDIN_WR_V_START_END, 0x00000000); |
| /* [ 6: 5] hist.pow = 0 */ |
| /* [ 3: 2] hist.mux = 0/(matrix_out, hsc_out, phsc_in) */ |
| /* [ 1] hist.win_en = 1 */ |
| /* [ 0] hist.read_en = 1 */ |
| wr(offset, VDIN_HIST_CTRL, 0x00000003); |
| /* [28:16] hist.win_hs = 0 */ |
| /* [12: 0] hist.win_he = 0 */ |
| wr(offset, VDIN_HIST_H_START_END, 0x00000000); |
| /* [28:16] hist.win_vs = 0 */ |
| /* [12: 0] hist.win_ve = 0 */ |
| wr(offset, VDIN_HIST_V_START_END, 0x00000000); |
| |
| /* set VDIN_MEAS_CLK_CNTL, select XTAL clock */ |
| /* if (is_meson_gxbb_cpu()) */ |
| /* ; */ |
| /* else */ |
| /* aml_write_cbus(HHI_VDIN_MEAS_CLK_CNTL, 0x00000100); */ |
| |
| /* [ 18] meas.rst = 0 */ |
| /* [ 17] meas.widen_hs_vs_en = 1 */ |
| /* [ 16] meas.vs_cnt_accum_en = 0 */ |
| /* [14:12] meas.mux = 0/(null, 656, tvfe, cvd2, hdmi, dvin) */ |
| /* [11: 4] meas.vs_span_m1 = 0 */ |
| /* [ 2: 0] meas.hs_ind = 0 */ |
| wr(offset, VDIN_MEAS_CTRL0, 0x00020000); |
| /* HS range0: Line #112 ~ Line #175 */ |
| /* [28:16] meas.hs_range_start = 112*/ |
| /* [12: 0] meas.hs_range_end = 175 */ |
| wr(offset, VDIN_MEAS_HS_RANGE, 0x007000af); |
| |
| /* [ 8] bbar.white_en = 0 */ |
| /* [ 7: 0] bbar.white_thr = 0 */ |
| wr(offset, VDIN_BLKBAR_CTRL1, 0x00000000); |
| |
| /* [20: 8] bbar.region_width = 0 */ |
| /* [ 7: 5] bbar.src_on_v = 0/(Y, sU, sV, U, V) */ |
| /* [ 4] bbar.search_one_step = 0 */ |
| /* [ 3] bbar.raising_edge_rst = 0 */ |
| |
| /* [ 2: 1] bbar.mux = 0/(matrix_out, hsc_out, phsc_in) */ |
| /* [ 0] bbar.en = 0 ***sub_module.enable*** */ |
| wr(offset, VDIN_BLKBAR_CTRL0, 0x14000000); |
| /* [28:16] bbar.win_hs = 0 */ |
| /* [12: 0] bbar.win_he = 0 */ |
| wr(offset, VDIN_BLKBAR_H_START_END, 0x00000000); |
| /* [28:16] bbar.win_vs = 0 */ |
| /* [12: 0] bbar.win_ve = 0 */ |
| wr(offset, VDIN_BLKBAR_V_START_END, 0x00000000); |
| /* [19: 0] bbar.bblk_thr_on_bpix = 0 */ |
| wr(offset, VDIN_BLKBAR_CNT_THRESHOLD, 0x00000000); |
| /* [28:16] bbar.blnt_thr_on_wpix = 0 */ |
| /* [12: 0] bbar.blnb_thr_on_wpix = 0 */ |
| wr(offset, VDIN_BLKBAR_ROW_TH1_TH2, 0x00000000); |
| |
| /* [28:16] input_win.hs = 0 */ |
| /* [12: 0] input_win.he = 0 */ |
| wr(offset, VDIN_WIN_H_START_END, 0x00000000); |
| /* [28:16] input_win.vs = 0 */ |
| /* [12: 0] input_win.ve = 0 */ |
| wr(offset, VDIN_WIN_V_START_END, 0x00000000); |
| |
| /*hw verify:de-tunnel 444 to 422 12bit*/ |
| /*if (devp->dtdata->de_tunnel_tunnel) */{ |
| vdin_dolby_de_tunnel_to_44410bit(devp, false); |
| vdin_dolby_desc_to_4448bit(devp, false); |
| } |
| } |
| |
| void vdin_hw_enable(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| /* enable video data input */ |
| /* [ 4] top.datapath_en = 1 */ |
| wr_bits(offset, VDIN_COM_CTRL0, 1, |
| VDIN_COMMONINPUT_EN_BIT, VDIN_COMMONINPUT_EN_WID); |
| |
| vdin_clk_onoff(devp, true); |
| /* wr(offset, VDIN_COM_GCLK_CTRL, 0x0); */ |
| } |
| |
| void vdin_hw_disable(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int def_canvas; |
| |
| def_canvas = offset ? vdin_canvas_ids[1][0] : vdin_canvas_ids[0][0]; |
| /* disable cm2 */ |
| wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 0, CM_TOP_EN_BIT, CM_TOP_EN_WID); |
| /* disable video data input */ |
| /* [ 4] top.datapath_en = 0 */ |
| wr_bits(offset, VDIN_COM_CTRL0, 0, |
| VDIN_COMMONINPUT_EN_BIT, VDIN_COMMONINPUT_EN_WID); |
| |
| /* mux null input */ |
| /* [ 3: 0] top.mux = 0/(null, mpeg, 656, tvfe, cvd2, hdmi, dvin) */ |
| wr_bits(offset, VDIN_COM_CTRL0, 0, VDIN_SEL_BIT, VDIN_SEL_WID); |
| wr(offset, VDIN_COM_CTRL0, 0x00000910); |
| vdin_delay_line(delay_line_num, offset); |
| if (enable_reset) |
| wr(offset, VDIN_WR_CTRL, 0x0b401000 | def_canvas); |
| else |
| wr(offset, VDIN_WR_CTRL, 0x0bc01000 | def_canvas); |
| |
| vdin_wrmif2_enable(devp, 0); |
| |
| /* disable clock of blackbar, histogram, histogram, line fifo1, matrix, |
| * hscaler, pre hscaler, clock0 |
| */ |
| /* [15:14] Disable blackbar clock = 01/(auto, off, on, on) */ |
| /* [13:12] Disable histogram clock = 01/(auto, off, on, on) */ |
| /* [11:10] Disable line fifo1 clock = 01/(auto, off, on, on) */ |
| /* [ 9: 8] Disable matrix clock = 01/(auto, off, on, on) */ |
| /* [ 7: 6] Disable hscaler clock = 01/(auto, off, on, on) */ |
| /* [ 5: 4] Disable pre hscaler clock = 01/(auto, off, on, on) */ |
| /* [ 3: 2] Disable clock0 = 01/(auto, off, on, on) */ |
| /* [ 0] Enable register clock = 00/(auto, off!!!!!!!!) */ |
| /*switch_vpu_clk_gate_vmod(offset == 0 ? VPU_VIU_VDIN0:VPU_VIU_VDIN1, |
| *VPU_CLK_GATE_OFF); |
| */ |
| vdin_clk_onoff(devp, false); |
| /* wr(offset, VDIN_COM_GCLK_CTRL, 0x5554); */ |
| |
| /*if (devp->dtdata->de_tunnel_tunnel) */{ |
| vdin_dolby_desc_to_4448bit(devp, 0); |
| vdin_dolby_de_tunnel_to_44410bit(devp, 0); |
| } |
| } |
| |
| /* get current vsync field type 0:top 1 bottom */ |
| unsigned int vdin_get_field_type(unsigned int offset) |
| { |
| return rd_bits(offset, VDIN_COM_STATUS0, 0, 1); |
| } |
| |
| bool vdin_check_vdi6_afifo_overflow(unsigned int offset) |
| { |
| return rd_bits(offset, VDIN_COM_STATUS2, 15, 1); |
| } |
| |
| void vdin_clear_vdi6_afifo_overflow_flg(unsigned int offset) |
| { |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0x1, 1, 1); |
| wr_bits(offset, VDIN_ASFIFO_CTRL3, 0x0, 1, 1); |
| } |
| |
| static unsigned int vdin_reset_flag; |
| inline int vdin_vsync_reset_mif(int index) |
| { |
| int i; |
| int start_line = aml_read_vcbus(VDIN_LCNT_STATUS) & 0xfff; |
| |
| if (!enable_reset || vdin_reset_flag || start_line > 0) |
| return 0; |
| vdin_reset_flag = 1; |
| if (index == 0) { |
| /* vdin->vdin mif wr en */ |
| W_VCBUS_BIT(VDIN_WR_CTRL, 0, VCP_WR_EN_BIT, VCP_WR_EN_WID); |
| W_VCBUS_BIT(VDIN_WR_CTRL, 1, NO_CLOCK_GATE_BIT, NO_CLOCK_GATE_WID); |
| /* wr req en */ |
| W_VCBUS_BIT(VDIN_WR_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2, vpu_reg_27af & |
| (~(1 << VDIN0_REQ_EN_BIT))); |
| vpu_reg_27af &= (~VDIN0_REQ_EN_BIT); |
| if (R_VCBUS_BIT(VPU_ARB_DBG_STAT_L1C2, VDIN_DET_IDLE_BIT, |
| VDIN_DET_IDLE_WIDTH) & VDIN0_IDLE_MASK) { |
| vdin0_wr_mif_reset(); |
| } else { |
| for (i = 0; i < vdin_det_idle_wait; i++) { |
| if (R_VCBUS_BIT(VPU_ARB_DBG_STAT_L1C2, |
| VDIN_DET_IDLE_BIT, |
| VDIN_DET_IDLE_WIDTH) & |
| VDIN0_IDLE_MASK) { |
| vdin0_wr_mif_reset(); |
| break; |
| } |
| } |
| if (i >= vdin_det_idle_wait && vdin_ctl_dbg) |
| pr_info("============== !!! idle wait timeout\n"); |
| } |
| |
| aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2, |
| vpu_reg_27af | (1 << VDIN0_REQ_EN_BIT)); |
| |
| W_VCBUS_BIT(VDIN_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| W_VCBUS_BIT(VDIN_WR_CTRL, 0, NO_CLOCK_GATE_BIT, NO_CLOCK_GATE_WID); |
| W_VCBUS_BIT(VDIN_WR_CTRL, 1, VCP_WR_EN_BIT, VCP_WR_EN_WID); |
| |
| vpu_reg_27af |= VDIN0_REQ_EN_BIT; |
| } else if (index == 1) { |
| W_VCBUS_BIT(VDIN1_WR_CTRL2, 1, VDIN1_VCP_WR_EN_BIT, |
| VDIN1_VCP_WR_EN_WID); /* vdin->vdin mif wr en */ |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 1, VDIN1_DISABLE_CLOCKGATE_BIT, |
| VDIN1_DISABLE_CLOCKGATE_WID); /* clock gate */ |
| /* wr req en */ |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 0, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2, |
| vpu_reg_27af & (~(1 << VDIN1_REQ_EN_BIT))); |
| vpu_reg_27af &= (~(1 << VDIN1_REQ_EN_BIT)); |
| if (R_VCBUS_BIT(VPU_ARB_DBG_STAT_L1C2, VDIN_DET_IDLE_BIT, |
| VDIN_DET_IDLE_WIDTH) & VDIN1_IDLE_MASK) { |
| vdin1_wr_mif_reset(); |
| } else { |
| for (i = 0; i < vdin_det_idle_wait; i++) { |
| if (R_VCBUS_BIT(VPU_ARB_DBG_STAT_L1C2, |
| VDIN_DET_IDLE_BIT, |
| VDIN_DET_IDLE_WIDTH) & |
| VDIN1_IDLE_MASK) { |
| vdin1_wr_mif_reset(); |
| break; |
| } |
| } |
| } |
| aml_write_vcbus(VPU_WRARB_REQEN_SLV_L1C2, |
| vpu_reg_27af | (1 << VDIN1_REQ_EN_BIT)); |
| vpu_reg_27af |= (1 << VDIN1_REQ_EN_BIT); |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 1, WR_REQ_EN_BIT, WR_REQ_EN_WID); |
| W_VCBUS_BIT(VDIN1_WR_CTRL, 0, VDIN1_DISABLE_CLOCKGATE_BIT, |
| VDIN1_DISABLE_CLOCKGATE_WID); |
| W_VCBUS_BIT(VDIN1_WR_CTRL2, 0, |
| VDIN1_VCP_WR_EN_BIT, VDIN1_VCP_WR_EN_WID); |
| } |
| vdin_reset_flag = 0; |
| |
| return vsync_reset_mask & 0x08; |
| } |
| |
| void vdin_enable_module(struct vdin_dev_s *devp, bool enable) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| vdin_dmc_ctrl(devp, 1); |
| if (enable) { |
| /* set VDIN_MEAS_CLK_CNTL, select XTAL clock */ |
| /* if (is_meson_gxbb_cpu()) */ |
| /* ; */ |
| /* else */ |
| /* aml_write_cbus(HHI_VDIN_MEAS_CLK_CNTL, 0x00000100); */ |
| /* vdin_hw_enable(devp); */ |
| /* todo: check them */ |
| } else { |
| /* set VDIN_MEAS_CLK_CNTL, select XTAL clock */ |
| /* if (is_meson_gxbb_cpu()) */ |
| /* ; */ |
| /* else */ |
| /* aml_write_cbus(HHI_VDIN_MEAS_CLK_CNTL, 0x00000000); */ |
| vdin_hw_disable(devp); |
| vdin_dobly_mdata_write_en(offset, false); |
| } |
| } |
| |
| bool vdin_write_done_check(unsigned int offset, struct vdin_dev_s *devp) |
| { |
| /*clear int status*/ |
| wr_bits(offset, VDIN_WR_CTRL, 1, |
| DIRECT_DONE_CLR_BIT, DIRECT_DONE_CLR_WID); |
| wr_bits(offset, VDIN_WR_CTRL, 0, |
| DIRECT_DONE_CLR_BIT, DIRECT_DONE_CLR_WID); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| if (rd_bits(offset, VDIN_RO_WRMIF_STATUS, |
| WRITE_DONE_BIT, WRITE_DONE_WID)) |
| return true; |
| |
| } else { |
| if (rd_bits(offset, VDIN_COM_STATUS0, |
| DIRECT_DONE_STATUS_BIT, DIRECT_DONE_STATUS_WID)) |
| return true; |
| } |
| devp->wr_done_abnormal_cnt++; |
| return false; |
| } |
| |
| void vdin_get_duration_by_fps(struct vdin_dev_s *devp) |
| { |
| if (devp->parm.info.fps && IS_HDMI_SRC(devp->parm.port)) |
| devp->duration = 96000 / (devp->parm.info.fps); |
| else |
| devp->duration = devp->fmt_info_p->duration; |
| } |
| |
| /* |
| * cycle = delta_stamp = ((1/fps)/(1/msr_clk))*(vsync_span + 1) |
| * msr_clk/fps unit is HZ |
| * vsync_span(0x125a[11:4]) usually should be 0; |
| */ |
| bool vdin_check_cycle(struct vdin_dev_s *devp) |
| { |
| unsigned int stamp, cycle; |
| |
| stamp = vdin_get_meas_vstamp(devp->addr_offset); |
| |
| if (stamp < devp->stamp) |
| cycle = 0xffffffff - devp->stamp + stamp + 1; |
| else |
| cycle = stamp - devp->stamp; |
| |
| if (cycle <= (devp->msr_clk_val / 1000)) { |
| return true; |
| } else { |
| devp->stamp = stamp; |
| devp->cycle = cycle; |
| return false; |
| } |
| } |
| |
| /*function:calculate curr_wr_vf->duration |
| * based on parm.port\ msr_clk_val\ parm.flag and |
| * curr_field_type |
| */ |
| void vdin_calculate_duration(struct vdin_dev_s *devp) |
| { |
| unsigned int last_field_type, cycle_phase; |
| struct vframe_s *curr_wr_vf = NULL; |
| const struct tvin_format_s *fmt_info = devp->fmt_info_p; |
| enum tvin_port_e port = devp->parm.port; |
| unsigned int fps; |
| |
| curr_wr_vf = &devp->curr_wr_vfe->vf; |
| last_field_type = devp->curr_field_type; |
| cycle_phase = devp->msr_clk_val / 96000; |
| if (cycle_phase == 0) |
| cycle_phase = 250; |
| |
| /* dynamic duration update */ |
| if (devp->dtdata->hw_ver >= VDIN_HW_T7) { |
| /* vstamp to fps */ |
| if (devp->cycle) { |
| fps = devp->cycle * 96; |
| devp->duration = fps / (devp->msr_clk_val / 1000); |
| } |
| curr_wr_vf->duration = devp->duration; |
| } else { |
| #ifdef VDIN_DYNAMIC_DURATION |
| devp->curr_wr_vf->duration = |
| (devp->cycle + cycle_phase / 2) / cycle_phase; |
| #else |
| if (devp->use_frame_rate == 1 && |
| (port >= TVIN_PORT_HDMI0 && port <= TVIN_PORT_HDMI7)) { |
| curr_wr_vf->duration = |
| (devp->cycle + cycle_phase / 2) / cycle_phase; |
| } else { |
| curr_wr_vf->duration = devp->duration; |
| } |
| #endif |
| /* for 2D->3D mode & interlaced format, double top field |
| * duration to match software frame lock |
| */ |
| #ifdef VDIN_DYNAMIC_DURATION |
| if ((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) && |
| (last_field_type & VIDTYPE_INTERLACE)) |
| curr_wr_vf->duration <<= 1; |
| #else |
| if ((devp->parm.flag & TVIN_PARM_FLAG_2D_TO_3D) && |
| (last_field_type & VIDTYPE_INTERLACE)) { |
| if (!fmt_info->duration) |
| curr_wr_vf->duration = ((devp->cycle << 1) + |
| cycle_phase / 2) / cycle_phase; |
| else |
| curr_wr_vf->duration = fmt_info->duration << 1; |
| } |
| #endif |
| } |
| } |
| |
| /* just for horizontal down scale src_w is origin width, |
| * dst_w is width after scale down |
| */ |
| static void vdin_set_hscale(struct vdin_dev_s *devp, unsigned int dst_w) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int src_w = devp->h_active; |
| |
| unsigned int 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 |
| }; |
| |
| int horz_phase_step, i; |
| |
| if (!dst_w) { |
| pr_err("[vdin..]%s parameter dst_w error.\n", __func__); |
| return; |
| } |
| /* disable hscale */ |
| wr_bits(offset, VDIN_SC_MISC_CTRL, 0, HSCL_EN_BIT, HSCL_EN_WID); |
| /* write horz filter coefs */ |
| wr(offset, VDIN_SCALE_COEF_IDX, 0x0100); |
| for (i = 0; i < 33; i++) |
| wr(offset, VDIN_SCALE_COEF, filt_coef0[i]); /* bicubic */ |
| |
| if (src_w >> 12) {/* for src_w >= 4096, avoid data overflow. */ |
| horz_phase_step = (src_w << 18) / dst_w; |
| horz_phase_step = (horz_phase_step << 6); |
| } else { |
| horz_phase_step = (src_w << 20) / dst_w; |
| horz_phase_step = (horz_phase_step << 4); |
| } |
| |
| wr(offset, VDIN_WIDTHM1I_WIDTHM1O, ((src_w - 1) << WIDTHM1I_BIT) | |
| (dst_w - 1) |
| ); |
| |
| wr(offset, VDIN_HSC_PHASE_STEP, horz_phase_step); |
| /* hsc_p0_num */ |
| wr(offset, VDIN_HSC_INI_CTRL, (1 << HSCL_RPT_P0_NUM_BIT) | |
| (4 << HSCL_INI_RCV_NUM_BIT) | /* hsc_ini_rcv_num */ |
| (0 << HSCL_INI_PHASE_BIT) /* hsc_ini_phase */ |
| ); |
| |
| wr(offset, VDIN_SC_MISC_CTRL, |
| rd(offset, VDIN_SC_MISC_CTRL) | |
| (0 << INIT_PIX_IN_PTR_BIT) | |
| (1 << HSCL_EN_BIT) | /* hsc_en */ |
| (1 << SHORT_LN_OUT_EN_BIT) | /* short_lineo_en */ |
| (1 << HSCL_NEAREST_EN_BIT) | /* nearest_en */ |
| (0 << PHASE0_ALWAYS_EN_BIT) | /* phase0_always_en */ |
| (4 << HSCL_BANK_LEN_BIT) /* hsc_bank_length */ |
| ); |
| devp->h_active = dst_w; |
| } |
| |
| /* |
| *just for veritical scale src_w is origin height, |
| *just dst_h is the height after scale |
| */ |
| static void vdin_set_vscale(struct vdin_dev_s *devp) |
| { |
| int veri_phase_step, tmp; |
| unsigned int offset = devp->addr_offset; |
| unsigned int src_h = devp->v_active; |
| unsigned int dst_h = devp->prop.scaling4h; |
| |
| if (!dst_h) { |
| pr_err("[vdin..]%s parameter dst_h error.\n", __func__); |
| return; |
| } |
| /* disable vscale */ |
| wr_bits(offset, VDIN_VSC_INI_CTRL, 0, VSC_EN_BIT, VSC_EN_WID); |
| |
| veri_phase_step = (src_h << 20) / dst_h; |
| tmp = veri_phase_step >> 25; |
| if (tmp) { |
| pr_err("[vdin..]%s error. cannot be divided more than 31.9999.\n", |
| __func__); |
| return; |
| } |
| wr(offset, VDIN_VSC_PHASE_STEP, veri_phase_step); |
| if (!(veri_phase_step >> 20)) {/* scale up the bit should be 1 */ |
| wr_bits(offset, VDIN_VSC_INI_CTRL, 1, |
| VSC_PHASE0_ALWAYS_EN_BIT, VSC_PHASE0_ALWAYS_EN_WID); |
| /* scale phase is 0 */ |
| wr_bits(offset, VDIN_VSC_INI_CTRL, 0, |
| VSCALER_INI_PHASE_BIT, VSCALER_INI_PHASE_WID); |
| } else { |
| wr_bits(offset, VDIN_VSC_INI_CTRL, 0, |
| VSC_PHASE0_ALWAYS_EN_BIT, VSC_PHASE0_ALWAYS_EN_WID); |
| /* scale phase is 0x8000 */ |
| wr_bits(offset, VDIN_VSC_INI_CTRL, 0x8000, |
| VSCALER_INI_PHASE_BIT, VSCALER_INI_PHASE_WID); |
| } |
| /* skip 0 line in the beginning */ |
| wr_bits(offset, VDIN_VSC_INI_CTRL, 0, |
| INI_SKIP_LINE_NUM_BIT, INI_SKIP_LINE_NUM_WID); |
| |
| wr_bits(offset, VDIN_SCIN_HEIGHTM1, src_h - 1, |
| SCALER_INPUT_HEIGHT_BIT, SCALER_INPUT_HEIGHT_WID); |
| wr(offset, VDIN_DUMMY_DATA, 0x008080); |
| /* enable vscale */ |
| wr_bits(offset, VDIN_VSC_INI_CTRL, 1, VSC_EN_BIT, VSC_EN_WID); |
| devp->v_active = dst_h; |
| } |
| |
| /* new add pre_hscale module |
| * do hscaler down when scaling4w is smaller than half of h_active |
| * which is closed by default |
| */ |
| static void vdin_set_prehscale(struct vdin_dev_s *devp) |
| { |
| wr_bits(devp->addr_offset, VDIN_SC_MISC_CTRL, 0, PRE_HSCL_MODE_BIT, |
| PRE_HSCL_MODE_WID); |
| wr_bits(devp->addr_offset, VDIN_SC_MISC_CTRL, 1, PRE_HSCL_EN_BIT, |
| PRE_HSCL_EN_WID); |
| devp->h_active >>= 1; |
| pr_info("set_prehsc done!\n"); |
| } |
| |
| /*tm2 new add*/ |
| static void vdin_set_hshrink(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int src_w = devp->h_active; |
| unsigned int dst_w = devp->h_shrink_out; |
| unsigned int hshrk_mode = 0; |
| unsigned int i = 0; |
| unsigned int coef = 0; |
| |
| if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| pr_err("vdin.%d don't supports hshrink before TM2\n", |
| devp->index); |
| return; |
| } |
| |
| hshrk_mode = src_w / dst_w; |
| |
| /*check maximum value*/ |
| if (hshrk_mode < 2 || hshrk_mode > 64) { |
| pr_err("vdin.%d hshrink: size is out of range\n", devp->index); |
| return; |
| } |
| |
| /*check legality, valid is 2,4,8,16,32,64*/ |
| switch (hshrk_mode) { |
| case 2: |
| case 4: |
| case 8: |
| case 16: |
| case 32: |
| case 64: |
| break; |
| |
| default: |
| pr_err("vdin.%d invalid hshrink mode : %d\n", devp->index, |
| hshrk_mode); |
| return; |
| } |
| |
| coef = 64 / hshrk_mode; |
| coef = (coef << 24) | (coef << 16) | (coef << 8) | coef; |
| |
| /*hshrk_mode: 2->1/2, 4->1/4... 64->1/64(max)*/ |
| wr_bits(offset, VDIN_HSK_CTRL, hshrk_mode, HSK_MD_BIT, HSK_MD_WID); |
| wr_bits(offset, VDIN_HSK_CTRL, src_w, HSK_HSIZE_IN_BIT, |
| HSK_HSIZE_IN_WID); |
| |
| /*h shrink coef*/ |
| for (i = HSK_COEF_0; i <= HSK_COEF_15; i++) |
| wr(offset, i, coef); |
| |
| /*h shrink enable*/ |
| wr_bits(offset, VDIN_VSHRK_CTRL, 1, VDIN_HSHRK_EN_BIT, |
| VDIN_HSHRK_EN_WID); |
| pr_info("vdin.%d set_hshrink done! hshk mode = %d\n", devp->index, |
| hshrk_mode); |
| } |
| |
| /* new add vshrink module |
| * do vscaler down,when scaling4h is smaller than half of v_active |
| * which is closed by default |
| * vshrk_mode:0-->1:2; 1-->1:4; 2-->1:8 |
| * chip <= TL1, only vdin1 has this module. |
| * chip >= TM2 && != T5, both vdin0 and vdin1 are supported. |
| * chip == T5, only vdin0 support |
| */ |
| static void vdin_set_vshrink(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int src_w = devp->h_shrink_out; |
| unsigned int src_h = devp->v_active; |
| unsigned int vshrk_mode = 0; |
| |
| if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TM2) && devp->index == 0) { |
| pr_err("vdin.%d don't support vshrink before TM2\n", |
| devp->index); |
| return; |
| } else if ((devp->dtdata->hw_ver == VDIN_HW_T5 || |
| devp->dtdata->hw_ver == VDIN_HW_T5D) && devp->index) { |
| return; |
| } |
| |
| if (src_w > VDIN_VSHRINK_HLIMIT) { |
| pr_err("vdin.%d vshrink: only support input width <= %d\n", |
| devp->index, VDIN_VSHRINK_HLIMIT); |
| return; |
| } |
| |
| vshrk_mode = src_h / devp->v_shrink_out; |
| |
| if (vshrk_mode < 2) { |
| pr_info("vdin.%d vshrink: out > in/2,return\n", devp->index); |
| return; |
| } |
| |
| if (vshrk_mode >= 8) |
| vshrk_mode = 2; |
| else if (vshrk_mode >= 4) |
| vshrk_mode = 1; |
| else if (vshrk_mode >= 2) |
| vshrk_mode = 0; |
| |
| pr_info("vdin.%d vshrk mode = %d\n", devp->index, vshrk_mode); |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| /*v shrink input h size*/ |
| wr_bits(offset, VDIN_VSHRK_SIZE_M1, src_w - 1, |
| VSHRK_IN_HSIZE_BIT, VSHRK_IN_HSIZE_WID); |
| /*v shrink input v size*/ |
| wr_bits(offset, VDIN_VSHRK_SIZE_M1, src_h - 1, |
| VSHRK_IN_VSIZE_BIT, VSHRK_IN_VSIZE_WID); |
| /*v shrink output height*/ |
| wr_bits(offset, VDIN_SCIN_HEIGHTM1, |
| (src_h >> (vshrk_mode + 1)) - 1, |
| VSHRK_INPUT_HEIGHT_BIT, VSHRK_INPUT_HEIGHT_WID); |
| /*dummy data 0x8080*/ |
| wr_bits(offset, VDIN_VSHRK_CTRL, 0x8080, |
| VDIN_VSHRK_DYMMY_BIT, VDIN_VSHRK_DYMMY_WID); |
| } else { |
| wr_bits(offset, VDIN_SCIN_HEIGHTM1, src_h - 1, |
| VSHRK_INPUT_HEIGHT_BIT, VSHRK_INPUT_HEIGHT_WID); |
| } |
| |
| wr_bits(offset, VDIN_VSHRK_CTRL, 1, |
| VDIN_VSHRK_LPF_MODE_BIT, VDIN_VSHRK_LPF_MODE_WID); |
| wr_bits(offset, VDIN_VSHRK_CTRL, vshrk_mode, |
| VDIN_VSHRK_MODE_BIT, VDIN_VSHRK_MODE_WID); |
| wr_bits(offset, VDIN_VSHRK_CTRL, 1, |
| VDIN_VSHRK_EN_BIT, VDIN_VSHRK_EN_WID); |
| pr_info("vdin.%d set_vshrink done!\n", devp->index); |
| } |
| |
| /*function:set horizontal and veritical scale |
| *vdin scaler path: |
| * vdin0:prehsc-->hscaler-->vscaler; |
| * vdin1:prehsc-->hscaler-->vshrink-->vscaler |
| *for tm2, scalar path, both vdin are same: |
| * prehsc-->hscaler-->vscaler-->optional h/v shrink; |
| */ |
| void vdin_set_hvscale(struct vdin_dev_s *devp) |
| { |
| /*backup current h v size*/ |
| devp->h_active_org = devp->h_active; |
| devp->v_active_org = devp->v_active; |
| |
| if (K_FORCE_HV_SHRINK) |
| goto set_hvshrink; |
| |
| pr_info("[vdin.%d] %s hactive:%u,vactive:%u.\n", devp->index, |
| __func__, devp->h_active, devp->v_active); |
| if (devp->prop.scaling4w < devp->h_active && |
| devp->prop.scaling4w > 0) { |
| if (devp->prehsc_en && (devp->prop.scaling4w <= |
| (devp->h_active >> 1))) |
| vdin_set_prehscale(devp); |
| |
| if (devp->prop.scaling4w < devp->h_active) |
| vdin_set_hscale(devp, devp->prop.scaling4w); |
| } else if (devp->h_active > VDIN_MAX_HACTIVE) { |
| vdin_set_hscale(devp, VDIN_MAX_HACTIVE); |
| } |
| |
| if (devp->prop.scaling4h < devp->v_active && |
| devp->prop.scaling4h > 0) { |
| if (devp->vshrk_en && !cpu_after_eq(MESON_CPU_MAJOR_ID_TM2) && |
| (devp->prop.scaling4h <= (devp->v_active >> 1))) { |
| vdin_set_vshrink(devp); |
| } |
| |
| if (devp->prop.scaling4h < devp->v_active) |
| vdin_set_vscale(devp); |
| } |
| |
| pr_info("[vdin.%d] %s hactive:%u,vactive:%u.\n", devp->index, |
| __func__, devp->h_active, devp->v_active); |
| set_hvshrink: |
| |
| if ((devp->double_wr || K_FORCE_HV_SHRINK) && |
| devp->h_active > 1920 && devp->v_active > 1080) { |
| devp->h_shrink_times = H_SHRINK_TIMES_4k; |
| devp->v_shrink_times = V_SHRINK_TIMES_4k; |
| } else if (devp->double_wr && devp->h_active > 1280 && |
| devp->v_active > 720) { |
| devp->h_shrink_times = H_SHRINK_TIMES_1080; |
| devp->v_shrink_times = V_SHRINK_TIMES_1080; |
| } else { |
| devp->h_shrink_times = 1; |
| devp->v_shrink_times = 1; |
| } |
| devp->h_shrink_out = devp->h_active / devp->h_shrink_times; |
| devp->v_shrink_out = devp->v_active / devp->v_shrink_times; |
| |
| if (devp->double_wr || K_FORCE_HV_SHRINK) { |
| if (devp->h_shrink_out < devp->h_active) |
| vdin_set_hshrink(devp); |
| |
| if (devp->v_shrink_out < devp->v_active) |
| vdin_set_vshrink(devp); |
| } |
| |
| if (vdin_dbg_en) { |
| pr_info("[vdin.%d] %s hactive:%u,vactive:%u.\n", devp->index, |
| __func__, devp->h_active, devp->v_active); |
| pr_info("[vdin.%d] %s shrink out h:%d,v:%d\n", devp->index, |
| __func__, devp->h_shrink_out, devp->v_shrink_out); |
| } |
| } |
| |
| /*set source_bitdepth |
| * base on color_depth_config: |
| * 10, 8, 0, other |
| */ |
| void vdin_set_bitdepth(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int set_width = 0; |
| unsigned int port; |
| enum vdin_color_deeps_e bit_dep; |
| unsigned int convert_fmt; |
| |
| /* yuv 422 full pack check */ |
| if (devp->color_depth_support & |
| VDIN_WR_COLOR_DEPTH_10BIT_FULL_PCAK_MODE) |
| devp->full_pack = VDIN_422_FULL_PK_EN; |
| else |
| devp->full_pack = VDIN_422_FULL_PK_DIS; |
| |
| /*hw verify:de-tunnel 444 to 422 12bit*/ |
| //if (devp->dtdata->ipt444_to_422_12bit && vdin_cfg_444_to_422_wmif_en) |
| // devp->full_pack = VDIN_422_FULL_PK_DIS; |
| |
| if (devp->output_color_depth && |
| (devp->prop.fps == 50 || devp->prop.fps == 60) && |
| (devp->parm.info.fmt == TVIN_SIG_FMT_HDMI_3840_2160_00HZ || |
| devp->parm.info.fmt == TVIN_SIG_FMT_HDMI_4096_2160_00HZ) && |
| devp->prop.colordepth == VDIN_COLOR_DEEPS_10BIT) { |
| set_width = devp->output_color_depth; |
| pr_info("set output color depth %d bit from dts\n", set_width); |
| } |
| |
| switch (devp->color_depth_config & 0xff) { |
| case COLOR_DEEPS_8BIT: |
| bit_dep = VDIN_COLOR_DEEPS_8BIT; |
| break; |
| case COLOR_DEEPS_10BIT: |
| bit_dep = VDIN_COLOR_DEEPS_10BIT; |
| break; |
| /* |
| * vdin not support 12bit now, when rx submit is 12bit, |
| * vdin config it as 10bit , 12 to 10 |
| */ |
| case COLOR_DEEPS_12BIT: |
| bit_dep = VDIN_COLOR_DEEPS_10BIT; |
| break; |
| case COLOR_DEEPS_AUTO: |
| /* vdin_bit_depth is set to 0 by defaut, in this case, |
| * devp->source_bitdepth is controlled by colordepth |
| * change default to 10bit for 8in8out detail maybe lost |
| */ |
| if (vdin_is_convert_to_444(devp->format_convert) && |
| vdin_is_4k(devp)) { |
| bit_dep = VDIN_COLOR_DEEPS_8BIT; |
| } else if (devp->prop.colordepth == VDIN_COLOR_DEEPS_8BIT) { |
| /* hdmi YUV422, 8 or 10 bit valid is unknown*/ |
| /* so need vdin 10bit to frame buffer*/ |
| port = devp->parm.port; |
| if (port >= TVIN_PORT_HDMI0 && port <= TVIN_PORT_HDMI7) { |
| convert_fmt = devp->format_convert; |
| if ((vdin_is_convert_to_422(convert_fmt) && |
| (devp->color_depth_support & |
| VDIN_WR_COLOR_DEPTH_10BIT)) || |
| devp->prop.vdin_hdr_flag) |
| bit_dep = VDIN_COLOR_DEEPS_10BIT; |
| else |
| bit_dep = VDIN_COLOR_DEEPS_8BIT; |
| |
| if (vdin_is_dolby_tunnel_444_input(devp)) |
| bit_dep = VDIN_COLOR_DEEPS_8BIT; |
| } else { |
| bit_dep = VDIN_COLOR_DEEPS_8BIT; |
| } |
| } else if ((devp->color_depth_support & VDIN_WR_COLOR_DEPTH_10BIT) && |
| ((devp->prop.colordepth == VDIN_COLOR_DEEPS_10BIT) || |
| (devp->prop.colordepth == VDIN_COLOR_DEEPS_12BIT))) { |
| if (set_width == VDIN_COLOR_DEEPS_8BIT) |
| bit_dep = VDIN_COLOR_DEEPS_8BIT; |
| else |
| bit_dep = VDIN_COLOR_DEEPS_10BIT; |
| } else { |
| bit_dep = VDIN_COLOR_DEEPS_8BIT; |
| } |
| |
| break; |
| default: |
| bit_dep = VDIN_COLOR_DEEPS_8BIT; |
| break; |
| } |
| |
| devp->source_bitdepth = bit_dep; |
| #ifdef VDIN_BRINGUP_BYPASS_COLOR_CNVT |
| devp->source_bitdepth = devp->prop.colordepth; |
| #endif |
| if (devp->source_bitdepth == VDIN_COLOR_DEEPS_8BIT) |
| wr_bits(offset, VDIN_WR_CTRL2, 0, |
| VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID); |
| else if (devp->source_bitdepth == VDIN_COLOR_DEEPS_10BIT) |
| wr_bits(offset, VDIN_WR_CTRL2, 1, |
| VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID); |
| |
| /* only support 8bit mode at vpp side when double wr */ |
| if (!vdin_is_support_10bit_for_dw(devp)) |
| wr_bits(offset, VDIN_WR_CTRL2, MIF_8BIT, |
| VDIN_WR_10BIT_MODE_BIT, VDIN_WR_10BIT_MODE_WID); |
| if (vdin_dbg_en) |
| pr_info("%s %d cfg:0x%x\n", __func__, devp->source_bitdepth, |
| devp->color_depth_config); |
| } |
| |
| static void vdin_get_video_format(struct vdin_dev_s *devp) |
| { |
| switch (devp->format_convert) { |
| case VDIN_FORMAT_CONVERT_YUV_YUV444: |
| case VDIN_FORMAT_CONVERT_RGB_YUV444: |
| devp->vdin2vpp_info.cfmt = TVIN_YUV444; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_YUV422: |
| case VDIN_FORMAT_CONVERT_RGB_YUV422: |
| devp->vdin2vpp_info.cfmt = TVIN_YUV422; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_RGB: |
| case VDIN_FORMAT_CONVERT_RGB_RGB: |
| devp->vdin2vpp_info.cfmt = TVIN_RGB444; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_NV21: |
| case VDIN_FORMAT_CONVERT_RGB_NV21: |
| devp->vdin2vpp_info.cfmt = TVIN_NV21; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_NV12: |
| case VDIN_FORMAT_CONVERT_RGB_NV12: |
| devp->vdin2vpp_info.cfmt = TVIN_NV12; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| void vdin_set_to_vpp_parm(struct vdin_dev_s *devp) |
| { |
| if (devp->index) |
| return; |
| |
| devp->vdin2vpp_info.is_dv = devp->dv.dv_flag; |
| devp->vdin2vpp_info.scan_mode = devp->fmt_info_p->scan_mode; |
| devp->vdin2vpp_info.fps = devp->parm.info.fps; |
| devp->vdin2vpp_info.width = devp->h_active; |
| devp->vdin2vpp_info.height = devp->v_active; |
| vdin_get_video_format(devp); |
| |
| vdin_start_notify_vpp(&devp->vdin2vpp_info); |
| } |
| |
| /* do horizontal reverse and veritical reverse |
| * hreverse: |
| * VDIN_WR_H_START_END |
| * Bit29: 1.reverse 0.do not reverse |
| * |
| * vreverse: |
| * VDIN_WR_V_START_END |
| * Bit29: 1.reverse 0.do not reverse |
| */ |
| void vdin_wr_reverse(unsigned int offset, bool hreverse, bool vreverse) |
| { |
| if (hreverse) |
| wr_bits(offset, VDIN_WR_H_START_END, 1, |
| HORIZONTAL_REVERSE_BIT, HORIZONTAL_REVERSE_WID); |
| else |
| wr_bits(offset, VDIN_WR_H_START_END, 0, |
| HORIZONTAL_REVERSE_BIT, HORIZONTAL_REVERSE_WID); |
| if (vreverse) |
| wr_bits(offset, VDIN_WR_V_START_END, 1, |
| VERTICAL_REVERSE_BIT, VERTICAL_REVERSE_WID); |
| else |
| wr_bits(offset, VDIN_WR_V_START_END, 0, |
| VERTICAL_REVERSE_BIT, VERTICAL_REVERSE_WID); |
| } |
| |
| void vdin_bypass_isp(unsigned int offset) |
| { |
| wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 0, CM_TOP_EN_BIT, CM_TOP_EN_WID); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX_EN_BIT, VDIN_MATRIX_EN_WID); |
| wr_bits(offset, VDIN_MATRIX_CTRL, 0, |
| VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID); |
| } |
| |
| void vdin_set_cm2(unsigned int offset, unsigned int w, |
| unsigned int h, unsigned int *cm2) |
| { |
| unsigned int i = 0, j = 0, start_addr = 0x100; |
| |
| if (!cm_enable) |
| return; |
| wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 0, CM_TOP_EN_BIT, CM_TOP_EN_WID); |
| for (i = 0; i < 160; i++) { |
| j = i / 5; |
| wr(offset, VDIN_CHROMA_ADDR_PORT, start_addr + (j << 3) + (i % 5)); |
| wr(offset, VDIN_CHROMA_DATA_PORT, cm2[i]); |
| } |
| for (i = 0; i < 28; i++) { |
| wr(offset, VDIN_CHROMA_ADDR_PORT, 0x200 + i); |
| wr(offset, VDIN_CHROMA_DATA_PORT, cm2[160 + i]); |
| } |
| /*config cm2 frame size*/ |
| wr(offset, VDIN_CHROMA_ADDR_PORT, 0x205); |
| wr(offset, VDIN_CHROMA_DATA_PORT, h << 16 | w); |
| wr_bits(offset, VDIN_CM_BRI_CON_CTRL, 1, CM_TOP_EN_BIT, CM_TOP_EN_WID); |
| } |
| |
| /*vdin0 output ctrl |
| * Bit 26 vcp_nr_en. Only used in VDIN0. NOT used in VDIN1. |
| * Bit 25 vcp_wr_en. Only used in VDIN0. NOT used in VDIN1. |
| * Bit 24 vcp_in_en. Only used in VDIN0. NOT used in VDIN1. |
| */ |
| static void vdin_output_ctl(unsigned int offset, unsigned int output_nr_flag) |
| { |
| wr_bits(offset, VDIN_WR_CTRL, 1, VCP_IN_EN_BIT, VCP_IN_EN_WID); |
| if (output_nr_flag) { |
| wr_bits(offset, VDIN_WR_CTRL, 0, VCP_WR_EN_BIT, VCP_WR_EN_WID); |
| wr_bits(offset, VDIN_WR_CTRL, 1, VCP_NR_EN_BIT, VCP_NR_EN_WID); |
| } else { |
| wr_bits(offset, VDIN_WR_CTRL, 1, VCP_WR_EN_BIT, VCP_WR_EN_WID); |
| wr_bits(offset, VDIN_WR_CTRL, 0, VCP_NR_EN_BIT, VCP_NR_EN_WID); |
| } |
| } |
| |
| /* set mpegin |
| * VDIN_COM_CTRL0 |
| * Bit 31, mpeg_to_vdin_sel, |
| * 0: mpeg source to NR directly, |
| * 1: mpeg source pass through here |
| */ |
| void vdin_set_mpegin(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| /* set VDIN_MEAS_CLK_CNTL, select XTAL clock */ |
| /* if (is_meson_gxbb_cpu()) */ |
| /* ; */ |
| /* else */ |
| /* aml_write_cbus(HHI_VDIN_MEAS_CLK_CNTL, 0x00000100); */ |
| |
| wr(offset, VDIN_COM_CTRL0, 0x80000911); |
| vdin_delay_line(delay_line_num, offset); |
| wr(offset, VDIN_COM_GCLK_CTRL, 0x0); |
| |
| wr(offset, VDIN_INTF_WIDTHM1, devp->h_active - 1); |
| wr(offset, VDIN_WR_CTRL2, 0x0); |
| |
| wr(offset, VDIN_HIST_CTRL, 0x3); |
| wr(offset, VDIN_HIST_H_START_END, devp->h_active - 1); |
| wr(offset, VDIN_HIST_V_START_END, devp->v_active - 1); |
| vdin_output_ctl(offset, 1); |
| } |
| |
| void vdin_force_gofiled(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| wr_bits(offset, VDIN_COM_CTRL0, 1, 28, 1); |
| wr_bits(offset, VDIN_COM_CTRL0, 0, 28, 1); |
| } |
| |
| bool vdin_is_convert_to_444(u32 format_convert) |
| { |
| if (format_convert == VDIN_FORMAT_CONVERT_YUV_YUV444 || |
| format_convert == VDIN_FORMAT_CONVERT_YUV_RGB || |
| format_convert == VDIN_FORMAT_CONVERT_YUV_GBR || |
| format_convert == VDIN_FORMAT_CONVERT_YUV_BRG || |
| format_convert == VDIN_FORMAT_CONVERT_RGB_YUV444 || |
| format_convert == VDIN_FORMAT_CONVERT_RGB_RGB) |
| return true; |
| else |
| return false; |
| } |
| |
| bool vdin_is_convert_to_422(u32 format_convert) |
| { |
| if (format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422 || |
| format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422) |
| return true; |
| else |
| return false; |
| } |
| |
| bool vdin_is_convert_to_nv21(u32 format_convert) |
| { |
| if (format_convert == VDIN_FORMAT_CONVERT_YUV_NV12 || |
| format_convert == VDIN_FORMAT_CONVERT_YUV_NV21 || |
| format_convert == VDIN_FORMAT_CONVERT_RGB_NV12 || |
| format_convert == VDIN_FORMAT_CONVERT_RGB_NV21) |
| return true; |
| else |
| return false; |
| } |
| |
| bool vdin_is_4k(struct vdin_dev_s *devp) |
| { |
| if (devp->h_active >= 3800 && devp->v_active >= 2100) |
| return true; |
| else |
| return false; |
| } |
| |
| bool vdin_is_hdr_signal_in(struct vdin_dev_s *devp) |
| { |
| if (devp->prop.hdr_info.hdr_state == HDR_STATE_GET) |
| return true; |
| else |
| return false; |
| } |
| |
| bool vdin_is_dolby_signal_in(struct vdin_dev_s *devp) |
| { |
| if (K_FORCE_DV_ON) |
| return 1; |
| else |
| return ((devp->dv.dolby_input & (1 << devp->index)) || |
| (devp->dv.dv_flag)); |
| } |
| |
| void vdin_dolby_addr_alloc(struct vdin_dev_s *devp, unsigned int size) |
| { |
| unsigned int index, alloc_size; |
| /*int highmem_flag;*/ |
| unsigned int onebuf_size = dolby_size_byte; |
| |
| dolby_size_byte = onebuf_size; |
| |
| if (devp->dtdata->hw_ver == VDIN_HW_T7) |
| alloc_size = onebuf_size * size + K_DV_META_RAW_BUFF0; |
| else |
| alloc_size = onebuf_size * size; |
| devp->dv.dv_dma_vaddr = dma_alloc_coherent(&devp->this_pdev->dev, |
| alloc_size, |
| &devp->dv.dv_dma_paddr, |
| GFP_KERNEL); |
| if (!devp->dv.dv_dma_vaddr) { |
| pr_info("%s:dmaalloc_coherent fail!!\n", __func__); |
| return; |
| } |
| memset(devp->dv.dv_dma_vaddr, 0, alloc_size); |
| /*if (devp->cma_config_flag & 0x100)*/ |
| /* highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0]));*/ |
| /*else*/ |
| /* highmem_flag = PageHighMem(phys_to_page(devp->mem_start));*/ |
| |
| for (index = 0; index < size; index++) { |
| devp->vfp->dv_buf_mem[index] = devp->dv.dv_dma_paddr + |
| onebuf_size * index; |
| devp->vfp->dv_buf_vmem[index] = devp->dv.dv_dma_vaddr + |
| onebuf_size * index; |
| /* |
| *if (highmem_flag == 0) { |
| * if ((devp->cma_config_flag & 0x100) && |
| * devp->cma_config_en) |
| * devp->vfp->dv_buf_ori[index] = |
| * phys_to_virt(devp->vfmem_start[index] + |
| * devp->vfmem_size - |
| * onebuf_size); |
| * else |
| * devp->vfp->dv_buf_ori[index] = |
| * phys_to_virt(devp->mem_start + |
| * devp->mem_size - |
| * onebuf_size * |
| * (devp->canvas_max_num |
| * - index)); |
| *} else { |
| * if ((devp->cma_config_flag & 0x100) && |
| * devp->cma_config_en) |
| * devp->vfp->dv_buf_ori[index] = |
| * vdin_vmap(devp->vfmem_start[index] + |
| * devp->vfmem_size - |
| * onebuf_size, |
| * onebuf_size); |
| * else |
| * devp->vfp->dv_buf_ori[index] = |
| * vdin_vmap(devp->mem_start + |
| * devp->mem_size - |
| * onebuf_size * |
| * (devp->canvas_max_num - index), |
| * onebuf_size); |
| *} |
| */ |
| /*pr_info("%s:dv_buf[%d]=(0x%x,0x%p)\n", __func__, index,*/ |
| /*devp->vfp->dv_buf_ori[index],*/ |
| /* devp->vfp->dv_buf_mem[index],*/ |
| /* devp->vfp->dv_buf_vmem[index]);*/ |
| } |
| devp->dv.dv_mem_alloced = 1; |
| pr_info("%s:dv_dma_vaddr=0x%p,dv_dma_paddr=0x%lx\n", __func__, |
| devp->dv.dv_dma_vaddr, (ulong)devp->dv.dv_dma_paddr); |
| |
| devp->dv.temp_meta_data = kmalloc(K_DV_META_TEMP_BUFF_SIZE, GFP_KERNEL); |
| if (IS_ERR_OR_NULL(devp->dv.temp_meta_data)) { |
| pr_info("malloc dv temp buffer fail\n"); |
| devp->dv.temp_meta_data = NULL; |
| } else { |
| pr_info("malloc dv temp 2k buffer\n"); |
| } |
| |
| if (devp->dtdata->hw_ver == VDIN_HW_T7) { |
| /*need dma buffer*/ |
| devp->dv.meta_data_raw_pbuff0 = devp->dv.dv_dma_paddr + |
| onebuf_size * size; |
| devp->dv.meta_data_raw_vbuff0 = devp->dv.dv_dma_vaddr + |
| onebuf_size * size; |
| pr_info("dv meta hw buff: paddr:0x%lx vaddr:0x%p\n", |
| (ulong)devp->dv.meta_data_raw_pbuff0, |
| devp->dv.meta_data_raw_vbuff0); |
| |
| devp->dv.meta_data_raw_buff1 = kmalloc(K_DV_META_RAW_BUFF1, |
| GFP_KERNEL); |
| if (IS_ERR_OR_NULL(devp->dv.meta_data_raw_buff1)) { |
| pr_info("malloc dv raw_buff1 fail\n"); |
| devp->dv.meta_data_raw_buff1 = NULL; |
| } else { |
| pr_info("malloc dv raw_buff1\n"); |
| } |
| } |
| } |
| |
| void vdin_dolby_addr_release(struct vdin_dev_s *devp, unsigned int size) |
| { |
| unsigned int alloc_size; |
| /*int highmem_flag;*/ |
| /*int index;*/ |
| |
| if (devp->dv.dv_mem_alloced == 0) |
| return; |
| |
| alloc_size = dolby_size_byte * size; |
| if (devp->dv.dv_dma_vaddr) |
| dma_free_coherent(&devp->this_pdev->dev, alloc_size, |
| devp->dv.dv_dma_vaddr, |
| devp->dv.dv_dma_paddr); |
| devp->dv.dv_dma_vaddr = NULL; |
| /* |
| *if (devp->cma_config_flag & 0x100) |
| * highmem_flag = PageHighMem(phys_to_page(devp->vfmem_start[0])); |
| *else |
| * highmem_flag = PageHighMem(phys_to_page(devp->mem_start)); |
| * |
| *if (highmem_flag) { |
| * for (index = 0; index < size; index++) { |
| * if (devp->vfp->dv_buf_ori[index]) { |
| * vdin_unmap_phyaddr(devp->vfp->dv_buf_ori |
| * [index]); |
| * devp->vfp->dv_buf_ori[index] = NULL; |
| * } |
| * } |
| *} |
| */ |
| devp->dv.dv_mem_alloced = 0; |
| |
| if (!IS_ERR_OR_NULL(devp->dv.temp_meta_data)) { |
| kfree(devp->dv.temp_meta_data); |
| devp->dv.temp_meta_data = NULL; |
| pr_info("release dv temp buffer\n"); |
| } |
| |
| if (!IS_ERR_OR_NULL(devp->dv.meta_data_raw_buff1)) { |
| kfree(devp->dv.meta_data_raw_buff1); |
| devp->dv.meta_data_raw_buff1 = NULL; |
| pr_info("release dv raw_buff1\n"); |
| } |
| } |
| |
| static void vdin_dolby_metadata_swap(struct vdin_dev_s *devp, char *buf) |
| { |
| char ext; |
| unsigned int i, j; |
| |
| for (i = 0; (i * 16) < dolby_size_byte; i++) { |
| for (j = 0; j < 8; j++) { |
| ext = buf[i * 16 + j]; |
| buf[i * 16 + j] = buf[i * 16 + 15 - j]; |
| buf[i * 16 + 15 - j] = ext; |
| } |
| } |
| |
| vdin_dma_flush(devp, buf, dolby_size_byte, DMA_TO_DEVICE); |
| } |
| |
| static u32 crc32_lut[256] = { |
| 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, |
| 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, |
| 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, |
| 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, |
| 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, |
| 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, |
| 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, |
| 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, |
| 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, |
| 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, |
| 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, |
| 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, |
| 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, |
| 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, |
| 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, |
| 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, |
| 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, |
| 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, |
| 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, |
| 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, |
| 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, |
| 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, |
| 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, |
| 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, |
| 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, |
| 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, |
| 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, |
| 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, |
| 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, |
| 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, |
| 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, |
| 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, |
| 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, |
| 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, |
| 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, |
| 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, |
| 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, |
| 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, |
| 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, |
| 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, |
| 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, |
| 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, |
| 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 |
| }; |
| |
| static u32 crc32(u32 crc, const void *buf, size_t size) |
| { |
| const u8 *p = (const uint8_t *)buf; |
| |
| crc = ~crc; |
| while (size) { |
| crc = (crc << 8) ^ crc32_lut[((crc >> 24) ^ *p) & 0xff]; |
| p++; |
| size--; |
| } |
| return crc; |
| } |
| |
| bool vdin_is_dolby_tunnel_444_input(struct vdin_dev_s *devp) |
| { |
| #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION |
| if (vdin_is_dolby_signal_in(devp) && |
| devp->prop.color_format == TVIN_YUV422) |
| return true; |
| #endif |
| return false; |
| } |
| |
| void vdin_dolby_pr_meta_data(void *addr, unsigned int size) |
| { |
| unsigned int i; |
| char *c = addr; |
| |
| for (i = 0; i < size; i += 16) { |
| pr_info("\t%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", |
| c[i], c[i + 1], c[i + 2], c[i + 3], |
| c[i + 4], c[i + 5], c[i + 6], c[i + 7], |
| c[i + 8], c[i + 9], c[i + 10], c[i + 11], |
| c[i + 12], c[i + 13], c[i + 14], c[i + 15]); |
| } |
| } |
| |
| void vdin_dolby_buffer_update(struct vdin_dev_s *devp, unsigned int index) |
| { |
| u32 *p; |
| char *c; |
| char *cp; |
| u32 meta32, meta_size; |
| int i, j; |
| int count; |
| unsigned int offset = devp->addr_offset; |
| u32 crc_r = 0, crc = 1; |
| bool multimeta_flag = 0; |
| bool multimetatail_flag = 0; |
| u32 crc1_r = 0; |
| u32 crc1 = 0; |
| u32 max_pkt = 15; |
| static u32 cnt; |
| u32 rpt_cnt = 0, tail_cnt = 0, rev_cnt = 0, end_flag = 0; |
| u8 pkt_type; |
| struct dv_meta_pkt *pkt_p; |
| u32 cp_size, cp_offset, cp_sum = 0; |
| u32 *src_meta = devp->dv.meta_data_raw_buff1; |
| |
| devp->dv.dv_crc_check = true; |
| max_pkt = 15; |
| if (index >= devp->canvas_max_num) { |
| if (dv_dbg_log & 0x80) |
| pr_info("%s er: %d %d\n", __func__, |
| index, devp->canvas_max_num); |
| devp->dv.dv_crc_check = false; |
| return; |
| } |
| |
| if (devp->dtdata->hw_ver == VDIN_HW_T7 && |
| IS_ERR_OR_NULL(src_meta)) { |
| devp->dv.dv_crc_check = false; |
| pr_info("err: null meta buffer\n"); |
| return; |
| } |
| |
| cp = devp->dv.temp_meta_data; |
| /*c = devp->vfp->dv_buf_ori[index];*/ |
| c = devp->vfp->dv_buf_vmem[index]; |
| p = (u32 *)c; |
| for (count = 0; count < META_RETRY_MAX; count++) { |
| if (dv_dbg_mask & DV_READ_MODE_AXI) { |
| memcpy(p, devp->vfp->dv_buf_vmem[index], 128 * max_pkt); |
| vdin_dma_flush(devp, p, 128 * max_pkt, DMA_TO_DEVICE); |
| vdin_dolby_metadata_swap(devp, c); |
| /*vdin_dma_flush(devp, p, 128*max_pkt, DMA_TO_DEVICE);*/ |
| } else { |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) |
| wr(offset, VDIN_DOLBY_DSC_CTRL2, 0xe800c0d5); |
| else |
| wr(offset, VDIN_DOLBY_DSC_CTRL2, 0xd180c0d5); |
| rpt_cnt = 0; |
| tail_cnt = 0; |
| rev_cnt = 0; |
| for (i = 0; i < (32 * max_pkt); i++) { |
| if (devp->dtdata->hw_ver == VDIN_HW_T7) { |
| p[i] = src_meta[i]; |
| } else { |
| meta32 = rd(offset, VDIN_DOLBY_DSC_STATUS1); |
| p[i] = swap32(meta32); |
| } |
| |
| if (((i % 32) == 0) && !end_flag) { |
| rev_cnt++; |
| pkt_type = c[i * 4] & 0xc0; |
| if (pkt_type == META_PKY_TYPE_START) |
| multimeta_flag = 1; |
| |
| if (pkt_type == META_PKY_TYPE_START) |
| rpt_cnt++; |
| |
| if (pkt_type == META_PKY_TYPE_TAIL) { |
| multimetatail_flag = 1; |
| tail_cnt++; |
| } |
| |
| if (tail_cnt >= rpt_cnt) { |
| end_flag = 1; |
| max_pkt = rev_cnt; |
| } |
| if (((cnt % dv_dbg_log_du) == 0) && |
| (dv_dbg_log & (1 << 0))) |
| pr_info("pkt_type %d:0x%x\n", i, |
| pkt_type); |
| } |
| |
| if (i == 31 && multimeta_flag == 0) |
| break; |
| } |
| } |
| |
| meta_size = (c[3] << 8) | c[4]; |
| if (meta_size > 1024 || rev_cnt > 20 || |
| rpt_cnt != tail_cnt || |
| (meta_size > 128 && rev_cnt == 1)) { |
| if (((cnt % dv_dbg_log_du) == 0) && (dv_dbg_log & (1 << 0))) |
| pr_info("err size:%d rp_cnt:%d, tal_cnt:%d, rv_cnt:%d max_pkt:%d\n", |
| meta_size, rpt_cnt, tail_cnt, rev_cnt, max_pkt); |
| |
| devp->dv.dv_crc_check = false; |
| return; |
| } |
| crc = p[31];/*first pkt chk sum*/ |
| crc_r = crc32(0, p, 124); |
| crc_r = swap32(crc_r); |
| if (meta_size > DV_META_SINGLE_PKT_SIZE || multimeta_flag) { |
| rev_cnt = min(rev_cnt, max_pkt); |
| for (j = 0; j < (128 * rev_cnt); j += (128 * rpt_cnt)) { |
| pkt_type = c[j] & 0xc0; |
| cp_size = DV_META_SINGLE_PKT_SIZE; |
| if (!(pkt_type == META_PKY_TYPE_START)) { |
| cp_size += 2; |
| cp_offset = 3; |
| } else { |
| cp_offset = 5; |
| } |
| for (i = 0; i < rpt_cnt; i++) { |
| pkt_p = (struct dv_meta_pkt *) |
| &c[j + 128 * i]; |
| crc1 = pkt_p->crc; |
| crc1_r = crc32(0, (char *)pkt_p, 124); |
| crc1_r = swap32(crc1_r); |
| if (((cnt % dv_dbg_log_du) == 0) && |
| (dv_dbg_log & (1 << 0))) |
| pr_info("crc:0x%x, 0x%x\n", |
| crc1, crc1_r); |
| if (crc1 == crc1_r) { |
| cp_offset += j + 128 * i; |
| memcpy(cp, |
| &c[cp_offset], cp_size); |
| cp += cp_size; |
| cp_sum += cp_size; |
| break; |
| } |
| } |
| if (((cnt % dv_dbg_log_du) == 0) && |
| (dv_dbg_log & (1 << 0))) |
| pr_info("data idx %d:0x%x\n", |
| j, c[j] & 0xc0); |
| } |
| } else { |
| rev_cnt = 1; |
| rpt_cnt = 0; |
| tail_cnt = 0; |
| } |
| |
| if (((cnt % dv_dbg_log_du) == 0) && (dv_dbg_log & (1 << 0))) { |
| pr_info("mult_flag=%d tail_flag=%d meta_size=%d\n", |
| multimeta_flag, multimetatail_flag, meta_size); |
| pr_info("rpt_cnt:%d tail_cnt:%d rev_cnt:%d cp_sum:%d\n", |
| rpt_cnt, tail_cnt, rev_cnt, cp_sum); |
| } |
| |
| if (crc == crc_r) { |
| if (multimeta_flag == 1 && |
| multimetatail_flag == 1) { |
| if (crc1 == crc1_r) |
| break; |
| } else { |
| break; |
| } |
| } |
| } |
| |
| /*meta data pkt data*/ |
| if (((cnt % dv_dbg_log_du) == 0) && (dv_dbg_log & (1 << 5))) |
| vdin_dolby_pr_meta_data(c, 128 * rev_cnt); |
| |
| if (crc != crc_r || |
| (multimeta_flag == 1 && multimetatail_flag == 1 && |
| crc1 != crc1_r)) { |
| /* set small size to make control path return -1 |
| * to use previous setting |
| */ |
| devp->vfp->dv_buf[index] = &c[5]; |
| devp->vfp->dv_buf_size[index] = 4; |
| if (((cnt % dv_dbg_log_du) == 0) && (dv_dbg_log & (1 << 3))) { |
| pr_err("%s:hdmi dovi meta crc error:%08x!=%08x\n", |
| __func__, crc, crc_r); |
| pr_info("%s:index:%d dma:%x vaddr:%p size:%d\n", |
| __func__, index, |
| devp->vfp->dv_buf_mem[index], |
| devp->vfp->dv_buf_vmem[index], |
| meta_size); |
| vdin_dolby_pr_meta_data(p, 128); |
| } |
| devp->dv.dv_crc_check = false; |
| } else { |
| devp->dv.dv_crc_check = true; |
| devp->vfp->dv_buf[index] = &c[5]; |
| devp->vfp->dv_buf_size[index] = meta_size; |
| if (multimeta_flag == 1 && multimetatail_flag == 1) { |
| devp->vfp->dv_buf[index] = c; |
| cp = devp->dv.temp_meta_data; |
| memcpy(c, cp, meta_size); |
| if (((cnt % dv_dbg_log_du) == 0) && (dv_dbg_log & (1 << 0))) |
| pr_info("cp %d meta to buff\n", meta_size); |
| } else if (meta_size > DV_META_SINGLE_PKT_SIZE) { |
| devp->dv.dv_crc_check = false; |
| } |
| |
| if (((cnt % dv_dbg_log_du) == 0) && (dv_dbg_log & (1 << 0))) |
| pr_info("%s:index:%d dma:%x vaddr:%p size:%d crc:%x crc1:%x\n", |
| __func__, index, |
| devp->vfp->dv_buf_mem[index], |
| devp->vfp->dv_buf_vmem[index], |
| meta_size, crc, crc1); |
| /*meta data raw data*/ |
| if (((cnt % dv_dbg_log_du) == 0) && (dv_dbg_log & (1 << 4))) |
| vdin_dolby_pr_meta_data(c, meta_size); |
| } |
| |
| cnt++; |
| } |
| |
| void vdin_dolby_addr_update(struct vdin_dev_s *devp, unsigned int index) |
| { |
| unsigned int offset = devp->addr_offset; |
| u32 *p; |
| |
| if (index >= devp->canvas_max_num) |
| return; |
| devp->vfp->dv_buf[index] = NULL; |
| devp->vfp->dv_buf_size[index] = 0; |
| p = (u32 *)devp->vfp->dv_buf_vmem[index]; |
| p[0] = 0; |
| p[1] = 0; |
| if (dv_dbg_mask & DV_READ_MODE_AXI) { |
| wr(offset, VDIN_DOLBY_AXI_CTRL1, |
| devp->vfp->dv_buf_mem[index]); |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 4, 1); |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 4, 1); |
| if (dv_dbg_log & (1 << 0)) |
| pr_info("%s:index:%d dma:%x\n", __func__, |
| index, devp->vfp->dv_buf_mem[index]); |
| } else { |
| wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x5180c0d5); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) |
| wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x6800c0d5); |
| else |
| wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x5180c0d5); |
| wr(offset, VDIN_DOLBY_DSC_CTRL3, 0); |
| } |
| } |
| |
| void vdin_dolby_config(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| devp->dv.dv_config = 1; |
| devp->dv.dv_path_idx = devp->index; |
| devp->vfp->low_latency = devp->dv.low_latency; |
| memcpy(&devp->vfp->dv_vsif, |
| &devp->dv.dv_vsif, sizeof(struct tvin_dv_vsif_s)); |
| wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 1, 30, 1); |
| wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 1, 26, 1); |
| wr_bits(offset, VDIN_DOLBY_DSC_CTRL0, 0, 26, 1); |
| if (dv_dbg_mask & DV_READ_MODE_AXI) { |
| wr(offset, VDIN_DOLBY_AXI_CTRL1, devp->vfp->dv_buf_mem[0]); |
| /* hold line = 0 */ |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 8, 8); |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 4, 1); |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 5, 1); |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 5, 1); |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 4, 1); |
| /*enable wr memory*/ |
| vdin_dobly_mdata_write_en(offset, 1); |
| } else { |
| /*disable wr memory*/ |
| vdin_dobly_mdata_write_en(offset, 0); |
| wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x5180c0d5); |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) |
| wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x6800c0d5); |
| else |
| wr(offset, VDIN_DOLBY_DSC_CTRL2, 0x5180c0d5); |
| wr(offset, VDIN_DOLBY_DSC_CTRL3, 0x0); |
| } |
| |
| if (vdin_dbg_en) |
| pr_info("%s\n", __func__); |
| } |
| |
| void vdin_dobly_mdata_write_en(unsigned int offset, unsigned int en) |
| { |
| /*printk("=========>> wr memory %d\n", en);*/ |
| if (en) { |
| /*enable write metadate to memory*/ |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 1, 30, 1); |
| /*vdin0 dolby meta write enable*/ |
| /*W_VCBUS_BIT(0x27af, 1, 2, 1);*/ |
| } else { |
| /*disable write metadate to memory*/ |
| wr_bits(offset, VDIN_DOLBY_AXI_CTRL0, 0, 30, 1); |
| /*vdin0 dolby meta write disable*/ |
| /*W_VCBUS_BIT(0x27af, 0, 2, 1);*/ |
| } |
| } |
| |
| /* |
| * set dv de-scramble scramble, and this function |
| * need call after vdin_set_hvscale if vdin scaling down |
| * enable |
| * parm: devp |
| * on:1 off:0 |
| */ |
| void vdin_dolby_desc_to_4448bit(struct vdin_dev_s *devp, |
| unsigned int onoff) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| /* only support vdin0 |
| * don't support in T5 |
| */ |
| if (devp->index == 1 || |
| (devp->dtdata->hw_ver == VDIN_HW_T5 || |
| devp->dtdata->hw_ver == VDIN_HW_T5D)) |
| return; |
| |
| if (cpu_after_eq(MESON_CPU_MAJOR_ID_TM2)) { |
| if (onoff) { |
| if (!devp->double_wr) { |
| /* enable channel 1 for scramble */ |
| wr_bits(offset, VDIN_LFIFO_CTRL, 0, |
| CH0_OUT_EN_BIT, CH_OUT_EN_WID); |
| wr_bits(offset, VDIN_LFIFO_CTRL, 1, |
| CH1_OUT_EN_BIT, CH_OUT_EN_WID); |
| /* switch vdin 0 wr mif to small */ |
| wr_bits(0, VDIN_TOP_DOUBLE_CTRL, |
| WR_SEL_VDIN0_SML, |
| MIF0_OUT_SEL_BIT, VDIN_REORDER_SEL_WID); |
| } |
| wr(offset, VDIN_DSC_TUNNEL_SEL, 0x3d11);/*re-order*/ |
| |
| /*small path size in*/ |
| wr_bits(offset, VDIN_SCB_CTRL1, devp->v_shrink_out, 0, 13); |
| wr_bits(offset, VDIN_SCB_CTRL1, devp->h_shrink_out, 16, 13); |
| /*de-cramble enable*/ |
| wr_bits(offset, VDIN_VSHRK_CTRL, 0x1, 28, 1); |
| /*small path cramble enable*/ |
| wr_bits(offset, VDIN_VSHRK_CTRL, 0x1, 29, 1); |
| if (vdin_dbg_en) |
| pr_info("vdin SC small in:(%d, %d)\n", |
| devp->h_shrink_out, devp->v_shrink_out); |
| |
| /* normal path size in */ |
| wr_bits(offset, VDIN_DSC2_HSIZE, devp->v_active, 0, 13); |
| wr_bits(offset, VDIN_DSC2_HSIZE, devp->h_active, 16, 13); |
| /* normal patch scramble enable */ |
| wr_bits(offset, VDIN_SCB_CTRL0, 0x1, 28, 1); |
| |
| if (vdin_dbg_en) |
| pr_info("vdin SC normal in:(%d, %d)\n", |
| devp->h_active, devp->v_active); |
| |
| } else { |
| /* disable descramble & scramble */ |
| /*small patch disable*/ |
| /*de-cramble disable*/ |
| wr_bits(offset, VDIN_VSHRK_CTRL, 0x0, 28, 1); |
| /*small path cramble enable*/ |
| wr_bits(offset, VDIN_VSHRK_CTRL, 0x0, 29, 1); |
| /* normal path disable */ |
| wr_bits(offset, VDIN_SCB_CTRL0, 0x0, 28, 1); |
| |
| if (!devp->double_wr) { |
| /* enable channel 0 for normal TV path */ |
| wr_bits(offset, VDIN_LFIFO_CTRL, 1, |
| CH0_OUT_EN_BIT, CH_OUT_EN_WID); |
| wr_bits(offset, VDIN_LFIFO_CTRL, 0, |
| CH1_OUT_EN_BIT, CH_OUT_EN_WID); |
| } |
| } |
| } |
| } |
| |
| /* |
| * yuv format, DV descramble 422 12bit TO 444 10bit |
| */ |
| void vdin_dolby_de_tunnel_to_44410bit(struct vdin_dev_s *devp, |
| unsigned int onoff) |
| { |
| u32 data32; |
| unsigned int offset = devp->addr_offset; |
| |
| data32 = (3 << 18 | |
| 2 << 15 | |
| 0 << 12 | |
| 5 << 9 | |
| 4 << 6 | |
| 1 << 3);/*1 << 2 0:off 1:on*/ |
| |
| if (onoff) |
| wr(offset, VDIN_RO_WRMIF_STATUS, data32 | (1 << 2)); |
| else |
| wr(offset, VDIN_RO_WRMIF_STATUS, data32); |
| |
| wr(offset, VDIN_DSC_DETUNNEL_SEL, 0x2c2d0); |
| /*de-scramble h size in*/ |
| wr_bits(offset, VDIN_CFMT_W, devp->h_active_org / 2, |
| 0, 13); |
| wr_bits(offset, VDIN_CFMT_W, devp->h_active_org, |
| 16, 13); |
| /**/ |
| wr_bits(offset, VDIN_DSC_HSIZE, devp->h_active_org, |
| 0, 13); |
| wr_bits(offset, VDIN_DSC_HSIZE, devp->h_active_org, |
| 16, 13); |
| if (vdin_dbg_en) |
| pr_info("vdin DSC in:(%d, %d)\n", |
| devp->h_active_org, devp->v_active_org); |
| } |
| |
| void vdin_dv_detunel_tunel_set(struct vdin_dev_s *devp) |
| { |
| if (!vdin_is_dolby_signal_in(devp)) |
| return; |
| |
| if (!devp->dtdata->de_tunnel_tunnel) |
| return; |
| |
| if (vdin_dbg_en) { |
| pr_info("vdin dv tunel_set shrink:(%d, %d)\n", |
| devp->h_active, devp->h_shrink_out); |
| } |
| |
| /* h shrink on*/ |
| if (devp->h_shrink_out < devp->h_active) { |
| /*hw verify:de-tunnel 444 to 422 12bit*/ |
| vdin_dolby_de_tunnel_to_44410bit(devp, true); |
| /*vdin de tunnel and tunnel for vdin scaling*/ |
| vdin_dolby_desc_to_4448bit(devp, true); |
| } else { |
| vdin_dolby_de_tunnel_to_44410bit(devp, false); |
| vdin_dolby_desc_to_4448bit(devp, false); |
| } |
| } |
| |
| static int vdin_get_max_buf(struct vdin_dev_s *devp) |
| { |
| if (!devp) { |
| pr_err("devp is NULL\n"); |
| return -1; |
| } |
| |
| return devp->frame_buff_num; |
| } |
| |
| int vdin_event_cb(int type, void *data, void *op_arg) |
| { |
| unsigned long flags; |
| struct vf_pool *p; |
| struct vdin_dev_s *devp = vdin_get_dev(0); |
| |
| if (!op_arg) { |
| if (vdin_ctl_dbg & (1 << 3)) |
| pr_info("%s:op_arg is NULL!\n", __func__); |
| return -1; |
| } |
| if (!data) { |
| if (vdin_ctl_dbg & (1 << 4)) |
| pr_info("%s:data is NULL!\n", __func__); |
| return -1; |
| } |
| p = (struct vf_pool *)op_arg; |
| if (type & VFRAME_EVENT_RECEIVER_GET_AUX_DATA) { |
| struct provider_aux_req_s *req = |
| (struct provider_aux_req_s *)data; |
| unsigned char index; |
| |
| if (!req->vf) { |
| pr_info("%s:req->vf is NULL!\n", __func__); |
| return -1; |
| } |
| spin_lock_irqsave(&p->dv_lock, flags); |
| index = req->vf->index & 0xff; |
| req->aux_buf = NULL; |
| req->aux_size = 0; |
| req->dv_enhance_exist = 0; |
| /* TODO: need change the low latency flag when LL mode */ |
| req->low_latency = p->low_latency; |
| memcpy(&req->dv_vsif, |
| &p->dv_vsif, sizeof(struct tvin_dv_vsif_s)); |
| if (req->bot_flag) |
| index = (req->vf->index >> 8) & 0xff; |
| if (index != 0xff && index < p->size && p->dv_buf[index]) { |
| req->aux_buf = p->dv_buf[index]; |
| req->aux_size = p->dv_buf_size[index]; |
| } |
| spin_unlock_irqrestore(&p->dv_lock, flags); |
| |
| if (dv_dbg_log & BIT(4)) |
| pr_info("%s(type 0x%x vf index 0x%x)=>size 0x%x\n", |
| __func__, type, index, req->aux_size); |
| } else if (type & VFRAME_EVENT_RECEIVER_DISP_MODE) { |
| struct provider_disp_mode_req_s *req = |
| (struct provider_disp_mode_req_s *)data; |
| unsigned int index_disp; |
| |
| if (!req->vf) { |
| pr_info("%s:req->vf is NULL!\n", __func__); |
| return -1; |
| } |
| index_disp = req->vf->index_disp & 0xff; |
| if (index_disp >= VFRAME_DISP_MAX_NUM) { |
| if (vdin_ctl_dbg & (1 << 2)) |
| pr_info("%s:req->vf->index_disp(%d) is overflow!\n", |
| __func__, index_disp); |
| return -1; |
| } |
| if (game_mode || devp->skip_disp_md_check) |
| req->disp_mode = VFRAME_DISP_MODE_NULL; |
| else |
| req->disp_mode = p->disp_mode[index_disp]; |
| if (req->req_mode == 1 && p->skip_vf_num) |
| p->disp_mode[index_disp] = VFRAME_DISP_MODE_UNKNOWN; |
| if (vdin_ctl_dbg & BIT(5)) |
| pr_info("%s(type 0x%x vf index 0x%x)=>disp_mode %d,req_mode:%d\n", |
| __func__, type, index_disp, req->disp_mode, |
| req->req_mode); |
| } else if (type & VFRAME_EVENT_RECEIVER_NEED_NO_COMP) { |
| unsigned int *cnt; |
| |
| /* use for debug */ |
| if (vdin0_afbce_debug_force) |
| return 0; |
| |
| cnt = (unsigned int *)data; |
| if (*cnt) { |
| devp->afbce_mode = 0; |
| } else { |
| if (devp->afbce_valid) |
| devp->afbce_mode = 1; |
| } |
| |
| if (vdin_ctl_dbg & BIT(6)) |
| pr_info("%s(type 0x%x vdin%d) afbce_mode: %d, vpp_cnt: %d\n", |
| __func__, type, devp->index, |
| devp->afbce_mode, *cnt); |
| } else if (type & VFRAME_EVENT_RECEIVER_BUF_COUNT) { |
| *(int *)data = vdin_get_max_buf(devp); |
| } else if (type & VFRAME_EVENT_RECEIVER_REQ_STATE) { |
| struct provider_state_req_s *req = |
| (struct provider_state_req_s *)data; |
| |
| #ifdef CONFIG_AMLOGIC_TEE |
| if (devp->secure_en && devp->mem_protected) |
| req->req_result[0] = 1; |
| else |
| req->req_result[0] = 0; |
| #else |
| req->req_result[0] = 0; |
| #endif |
| } |
| |
| return 0; |
| } |
| |
| void set_invert_top_bot(bool invert_flag) |
| { |
| invert_top_bot = invert_flag; |
| } |
| |
| int vdin_hdr_sei_error_check(struct vdin_dev_s *devp) |
| { |
| int primary_data[3][2]; |
| int i; |
| |
| /*GBR compare with standard 709 primary*/ |
| for (i = 0; i < 3; i++) { |
| primary_data[i][0] = |
| devp->prop.hdr_info.hdr_data.primaries[i].x; |
| primary_data[i][1] = |
| devp->prop.hdr_info.hdr_data.primaries[i].y; |
| } |
| if (((primary_data[0][0] + 250) / 500 == 30) && |
| ((primary_data[0][1] + 250) / 500 == 60) && |
| ((primary_data[1][0] + 250) / 500 == 15) && |
| ((primary_data[1][1] + 250) / 500 == 6) && |
| ((primary_data[2][0] + 250) / 500 == 64) && |
| ((primary_data[2][1] + 250) / 500 == 33)) |
| return 1; |
| |
| /*RGB compare with standard 709 primary*/ |
| for (i = 0; i < 3; i++) { |
| primary_data[(i + 2) % 3][0] = |
| devp->prop.hdr_info.hdr_data.primaries[i].x; |
| primary_data[(i + 2) % 3][1] = |
| devp->prop.hdr_info.hdr_data.primaries[i].y; |
| } |
| |
| if (((primary_data[0][0] + 250) / 500 == 30) && |
| ((primary_data[0][1] + 250) / 500 == 60) && |
| ((primary_data[1][0] + 250) / 500 == 15) && |
| ((primary_data[1][1] + 250) / 500 == 6) && |
| ((primary_data[2][0] + 250) / 500 == 64) && |
| ((primary_data[2][1] + 250) / 500 == 33)) |
| return 1; |
| |
| /*GxBxRxGyByRy compare with standard 709 primary*/ |
| primary_data[0][0] = devp->prop.hdr_info.hdr_data.primaries[0].x; |
| primary_data[0][1] = devp->prop.hdr_info.hdr_data.primaries[1].y; |
| primary_data[1][0] = devp->prop.hdr_info.hdr_data.primaries[0].y; |
| primary_data[1][1] = devp->prop.hdr_info.hdr_data.primaries[2].x; |
| primary_data[2][0] = devp->prop.hdr_info.hdr_data.primaries[1].x; |
| primary_data[2][1] = devp->prop.hdr_info.hdr_data.primaries[2].y; |
| |
| if (((primary_data[0][0] + 250) / 500 == 30) && |
| ((primary_data[0][1] + 250) / 500 == 60) && |
| ((primary_data[1][0] + 250) / 500 == 15) && |
| ((primary_data[1][1] + 250) / 500 == 6) && |
| ((primary_data[2][0] + 250) / 500 == 64) && |
| ((primary_data[2][1] + 250) / 500 == 33)) |
| return 1; |
| else |
| return 0; |
| } |
| |
| void vdin_hdr10plus_check(struct vdin_dev_s *devp, |
| struct vframe_s *vf) |
| { |
| if (devp->prop.hdr10p_info.hdr10p_on) { |
| /*devp->prop.hdr10p_info.hdr10p_on = false;*/ |
| |
| vf->signal_type |= (1 << 29);/*present_flag*/ |
| vf->signal_type |= (0 << 25);/*0:limited*/ |
| /*color_primaries*/ |
| vf->signal_type = ((9 << 16) | |
| (vf->signal_type & (~0xFF0000))); |
| /*transfer_characteristic*/ |
| vf->signal_type = ((0x30 << 8) | |
| (vf->signal_type & (~0xFF00))); |
| /*matrix_coefficient*/ |
| vf->signal_type = ((9 << 0) | |
| (vf->signal_type & (~0xFF))); |
| memcpy(&vf->prop.hdr10p_data, |
| &devp->prop.hdr10p_info.hdr10p_data, |
| sizeof(struct tvin_hdr10p_data_s)); |
| } |
| } |
| |
| void vdin_set_drm_data(struct vdin_dev_s *devp, |
| struct vframe_s *vf) |
| { |
| struct vframe_master_display_colour_s *vf_dp = |
| &vf->prop.master_display_colour; |
| u32 val = 0; |
| |
| if (devp->prop.hdr_info.hdr_state != HDR_STATE_NULL) { |
| if (vdin_hdr_sei_error_check(devp) == 1) { |
| vf_dp->present_flag = false; |
| vf->signal_type &= ~(1 << 29); |
| vf->signal_type &= ~(1 << 25); |
| /*todo;default is bt709,if change need sync*/ |
| vf->signal_type = ((1 << 16) | |
| (vf->signal_type & (~0xFF0000))); |
| vf->signal_type = ((1 << 8) | |
| (vf->signal_type & (~0xFF00))); |
| } else { |
| memcpy(vf_dp->primaries, |
| devp->prop.hdr_info.hdr_data.primaries, |
| sizeof(u32) * 6); |
| memcpy(vf_dp->white_point, |
| &devp->prop.hdr_info.hdr_data.white_points, |
| sizeof(u32) * 2); |
| memcpy(vf_dp->luminance, |
| &devp->prop.hdr_info.hdr_data.master_lum, |
| sizeof(u32) * 2); |
| /* content_light_level */ |
| vf_dp->content_light_level.max_content = |
| devp->prop.hdr_info.hdr_data.mcll; |
| vf_dp->content_light_level.max_pic_average = |
| devp->prop.hdr_info.hdr_data.mfall; |
| |
| vf_dp->present_flag = true; |
| |
| if (devp->prop.hdr_info.hdr_data.mcll != 0 && |
| devp->prop.hdr_info.hdr_data.mfall != 0) |
| vf_dp->content_light_level.present_flag = 1; |
| else |
| vf_dp->content_light_level.present_flag = 0; |
| |
| if (devp->prop.hdr_info.hdr_data.eotf == |
| EOTF_SMPTE_ST_2048 || |
| devp->prop.hdr_info.hdr_data.eotf == |
| EOTF_HDR) { |
| vf->signal_type |= (1 << 29); |
| vf->signal_type |= (0 << 25);/*0:limit*/ |
| vf->signal_type = ((9 << 16) | |
| (vf->signal_type & (~0xFF0000))); |
| vf->signal_type = ((16 << 8) | |
| (vf->signal_type & (~0xFF00))); |
| vf->signal_type = ((9 << 0) | |
| (vf->signal_type & (~0xFF))); |
| } else if (devp->prop.hdr_info.hdr_data.eotf == |
| EOTF_HLG) { |
| vf->signal_type |= (1 << 29); |
| vf->signal_type |= (0 << 25);/*0:limit*/ |
| vf->signal_type = ((9 << 16) | |
| (vf->signal_type & (~0xFF0000))); |
| vf->signal_type = ((14 << 8) | |
| (vf->signal_type & (~0xFF00))); |
| vf->signal_type = ((9 << 0) | |
| (vf->signal_type & (~0xFF))); |
| } else { |
| vf->signal_type &= ~(1 << 29); |
| vf->signal_type &= ~(1 << 25); |
| /*todo;default is bt709,if change need sync*/ |
| vf->signal_type = ((1 << 16) | |
| (vf->signal_type & (~0xFF0000))); |
| vf->signal_type = ((1 << 8) | |
| (vf->signal_type & (~0xFF00))); |
| } |
| } |
| } else if (devp->prop.hdr_info.hdr_state == HDR_STATE_NULL) { |
| vf_dp->present_flag = false; |
| vf->signal_type &= ~(1 << 29); |
| vf->signal_type &= ~(1 << 25); |
| val = vdin_matrix_range_chk(devp); |
| vf->signal_type |= (val << 25); |
| /*todo;default is bt709,if change need sync*/ |
| vf->signal_type = ((1 << 16) | |
| (vf->signal_type & (~0xFF0000))); |
| vf->signal_type = ((1 << 8) | |
| (vf->signal_type & (~0xFF00))); |
| } |
| |
| /* hdr10+ check */ |
| vdin_hdr10plus_check(devp, vf); |
| |
| vf->vsif.addr = &devp->prop.dv_vsif_raw; |
| if (devp->dv.dv_flag) |
| vf->vsif.size = sizeof(struct tvin_dv_vsif_raw_s); |
| else |
| vf->vsif.size = 0; |
| |
| vf->emp.addr = &devp->prop.emp_data.empbuf; |
| vf->emp.size = devp->prop.emp_data.size; |
| } |
| |
| void vdin_vs_proc_monitor(struct vdin_dev_s *devp) |
| { |
| if (IS_HDMI_SRC(devp->parm.port)) { |
| if (devp->prop.dolby_vision != devp->dv.dv_flag) |
| devp->dv.chg_cnt++; |
| else |
| devp->dv.chg_cnt = 0; |
| |
| if (devp->prop.vdin_hdr_flag != devp->pre_prop.vdin_hdr_flag) |
| devp->prop.hdr_info.hdr_check_cnt++; |
| else |
| devp->prop.hdr_info.hdr_check_cnt = 0; |
| |
| if (devp->prop.latency.allm_mode != devp->pre_prop.latency.allm_mode || |
| devp->prop.latency.it_content != devp->pre_prop.latency.it_content || |
| devp->prop.latency.cn_type != devp->pre_prop.latency.cn_type) |
| devp->dv.allm_chg_cnt++; |
| else |
| devp->dv.allm_chg_cnt = 0; |
| |
| /*hdmi source afd check*/ |
| if (devp->pre_prop.aspect_ratio != |
| devp->prop.aspect_ratio) |
| devp->sg_chg_afd_cnt++; |
| else |
| devp->sg_chg_afd_cnt = 0; |
| |
| if (vdin_isr_monitor & BIT(0)) |
| pr_info("dv:%d, hdr st:%d eotf:%d fg:%d allm:%d sty:0x%x\n", |
| devp->prop.dolby_vision, |
| devp->prop.hdr_info.hdr_state, |
| devp->prop.hdr_info.hdr_data.eotf, |
| devp->prop.vdin_hdr_flag, |
| devp->prop.latency.allm_mode, |
| devp->parm.info.signal_type); |
| if (vdin_isr_monitor & BIT(1)) |
| pr_info("emp size:%d, data:0x%x 0x%x 0x%x 0x%x\n", |
| devp->prop.emp_data.size, |
| devp->prop.emp_data.empbuf[0], |
| devp->prop.emp_data.empbuf[1], |
| devp->prop.emp_data.empbuf[2], |
| devp->prop.emp_data.empbuf[3]); |
| if (vdin_isr_monitor & BIT(2)) |
| pr_info("aspect_ratio=0x%x\n", devp->prop.aspect_ratio); |
| } |
| |
| if (color_range_force) |
| devp->prop.color_fmt_range = |
| tvin_get_force_fmt_range(devp->prop.color_format); |
| if (devp->dtdata->hw_ver == VDIN_HW_T7 && |
| (devp->irq_cnt == 1 || devp->irq_cnt == 10)) { |
| vdin_wrmif2_enable(devp, 0); |
| vdin_wrmif2_enable(devp, 1); |
| } |
| } |
| |
| void vdin_check_hdmi_hdr(struct vdin_dev_s *devp) |
| { |
| struct tvin_state_machine_ops_s *sm_ops; |
| enum tvin_port_e port = TVIN_PORT_NULL; |
| struct tvin_sig_property_s *prop; |
| |
| if (!devp) |
| return; |
| |
| port = devp->parm.port; |
| |
| if (port < TVIN_PORT_HDMI0 || port > TVIN_PORT_HDMI7) |
| return; |
| |
| prop = &devp->prop; |
| sm_ops = devp->frontend->sm_ops; |
| if (sm_ops->get_sig_property) { |
| /* don't need get again, already got from start dec */ |
| /* sm_ops->get_sig_property(devp->frontend, prop); */ |
| pr_info("vdin%d hdmi hdr eotf:0x%x, state:%d\n", |
| devp->index, |
| devp->prop.hdr_info.hdr_data.eotf, |
| devp->prop.hdr_info.hdr_state); |
| /*devp->prop.vdin_hdr_flag = vdin_is_hdr_signal_in(devp);*/ |
| } |
| } |
| |
| u32 vdin_get_curr_field_type(struct vdin_dev_s *devp) |
| { |
| u32 field_status; |
| u32 type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_FIELD; |
| |
| /* struct tvin_parm_s *parm = &devp->parm; */ |
| const struct tvin_format_s *fmt_info = devp->fmt_info_p; |
| |
| if (fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) { |
| type |= VIDTYPE_PROGRESSIVE; |
| } else { |
| field_status = vdin_get_field_type(devp->addr_offset); |
| /*tvafe FIELD POLARITY 0 TOP,vdin must invert for correct*/ |
| |
| if (invert_top_bot || IS_TVAFE_SRC(devp->parm.port)) |
| type |= field_status ? |
| VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM; |
| else |
| type |= field_status ? |
| VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP; |
| |
| /*md2 get pre field sts, need invert for cur*/ |
| if ((devp->game_mode & VDIN_GAME_MODE_2) == VDIN_GAME_MODE_2) { |
| if ((type & VIDTYPE_INTERLACE_BOTTOM) == |
| VIDTYPE_INTERLACE_TOP) { |
| type |= VIDTYPE_INTERLACE_BOTTOM; |
| } else if ((type & VIDTYPE_INTERLACE_BOTTOM) == |
| VIDTYPE_INTERLACE_BOTTOM) { |
| type &= ~VIDTYPE_INTERLACE_BOTTOM; |
| type |= VIDTYPE_INTERLACE_TOP; |
| } |
| } |
| } |
| |
| switch (devp->format_convert) { |
| case VDIN_FORMAT_CONVERT_YUV_YUV444: |
| case VDIN_FORMAT_CONVERT_RGB_YUV444: |
| type |= VIDTYPE_VIU_444; |
| /*if (devp->afbce_mode_pre) */ |
| /* type |= VIDTYPE_COMB_MODE; */ |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_YUV422: |
| case VDIN_FORMAT_CONVERT_RGB_YUV422: |
| type |= VIDTYPE_VIU_422; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_RGB: |
| case VDIN_FORMAT_CONVERT_RGB_RGB: |
| type |= VIDTYPE_RGB_444; |
| if (devp->afbce_mode_pre && vdin_chk_is_comb_mode(devp)) |
| type |= VIDTYPE_COMB_MODE; |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_NV21: |
| case VDIN_FORMAT_CONVERT_RGB_NV21: |
| type |= VIDTYPE_VIU_NV21; |
| type &= (~VIDTYPE_VIU_SINGLE_PLANE); |
| break; |
| case VDIN_FORMAT_CONVERT_YUV_NV12: |
| case VDIN_FORMAT_CONVERT_RGB_NV12: |
| /* type |= VIDTYPE_VIU_NV12; */ |
| type &= (~VIDTYPE_VIU_SINGLE_PLANE); |
| break; |
| default: |
| break; |
| } |
| |
| if (devp->afbce_valid) |
| type |= VIDTYPE_SUPPORT_COMPRESS; |
| |
| if (devp->double_wr) { |
| type |= VIDTYPE_COMPRESS; |
| type &= ~VIDTYPE_NO_DW; |
| type |= VIDTYPE_SCATTER; |
| |
| /* add only for TL1 switch mif/afbce dynamically */ |
| type &= ~VIDTYPE_SUPPORT_COMPRESS; |
| |
| if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) |
| type |= VIDTYPE_COMPRESS_LOSS; |
| if (vdin_chk_is_comb_mode(devp)) |
| type |= VIDTYPE_COMB_MODE; |
| } else if (devp->afbce_mode_pre) { |
| type |= VIDTYPE_COMPRESS; |
| type |= VIDTYPE_NO_DW; |
| type |= VIDTYPE_SCATTER; |
| if (devp->afbce_flag & VDIN_AFBCE_EN_LOOSY) |
| type |= VIDTYPE_COMPRESS_LOSS; |
| if (vdin_chk_is_comb_mode(devp)) |
| type |= VIDTYPE_COMB_MODE; |
| } |
| |
| #ifdef CONFIG_AMLOGIC_TEE |
| if (devp->secure_en) |
| type |= VIDTYPE_SEC_MD; |
| else |
| type &= ~VIDTYPE_SEC_MD; |
| #endif |
| |
| return type; |
| } |
| |
| /* function: set vf source type |
| * source type list: |
| * a.VFRAME_SOURCE_TYPE_TUNER (TVIN_PORT CVBS3) |
| * b.VFRAME_SOURCE_TYPE_CVBS (TVIN_PORT CVBS0/CVBS1/ |
| * CVBS2/CVBS4/CVBS5/CVBS6/CVBS7) |
| * c.VFRAME_SOURCE_TYPE_COMP (TVIN_PORT COMP0~COMP7) |
| * d.VFRAME_SOURCE_TYPE_HDMI (TVIN_PORT HDMI0~HDMI7/DVIN0) |
| * e.others |
| */ |
| inline void vdin_set_source_type(struct vdin_dev_s *devp, |
| struct vframe_s *vf) |
| { |
| switch (devp->parm.port) { |
| case TVIN_PORT_CVBS3: |
| vf->source_type = VFRAME_SOURCE_TYPE_TUNER; |
| break; |
| case TVIN_PORT_CVBS0: |
| case TVIN_PORT_CVBS1: |
| case TVIN_PORT_CVBS2: |
| vf->source_type = VFRAME_SOURCE_TYPE_CVBS; |
| break; |
| case TVIN_PORT_HDMI0: |
| case TVIN_PORT_HDMI1: |
| case TVIN_PORT_HDMI2: |
| case TVIN_PORT_HDMI3: |
| case TVIN_PORT_HDMI4: |
| case TVIN_PORT_HDMI5: |
| case TVIN_PORT_HDMI6: |
| case TVIN_PORT_HDMI7: |
| case TVIN_PORT_DVIN0:/* external hdmiin used default */ |
| vf->source_type = VFRAME_SOURCE_TYPE_HDMI; |
| break; |
| default: |
| vf->source_type = VFRAME_SOURCE_TYPE_OTHERS; |
| break; |
| } |
| } |
| |
| /* function:set |
| * main source modes: |
| * a.NTSC b.PAL |
| * c.SECAM d.others |
| */ |
| inline void vdin_set_source_mode(struct vdin_dev_s *devp, |
| struct vframe_s *vf) |
| { |
| switch (devp->parm.info.fmt) { |
| case TVIN_SIG_FMT_CVBS_NTSC_M: |
| case TVIN_SIG_FMT_CVBS_NTSC_443: |
| vf->source_mode = VFRAME_SOURCE_MODE_NTSC; |
| break; |
| case TVIN_SIG_FMT_CVBS_PAL_I: |
| case TVIN_SIG_FMT_CVBS_PAL_M: |
| case TVIN_SIG_FMT_CVBS_PAL_60: |
| case TVIN_SIG_FMT_CVBS_PAL_CN: |
| vf->source_mode = VFRAME_SOURCE_MODE_PAL; |
| break; |
| case TVIN_SIG_FMT_CVBS_SECAM: |
| vf->source_mode = VFRAME_SOURCE_MODE_SECAM; |
| break; |
| default: |
| vf->source_mode = VFRAME_SOURCE_MODE_OTHERS; |
| break; |
| } |
| } |
| |
| /* |
| * 480p/i = 9:8 |
| * 576p/i = 16:15 |
| * 720p and 1080p/i = 1:1 |
| * All VGA format = 1:1 |
| */ |
| void vdin_set_pixel_aspect_ratio(struct vdin_dev_s *devp, |
| struct vframe_s *vf) |
| { |
| switch (devp->parm.info.fmt) { |
| /* 480P */ |
| case TVIN_SIG_FMT_HDMI_640X480P_60HZ: |
| case TVIN_SIG_FMT_HDMI_640X480P_72HZ: |
| case TVIN_SIG_FMT_HDMI_640X480P_75HZ: |
| case TVIN_SIG_FMT_HDMI_720X480P_60HZ: |
| case TVIN_SIG_FMT_HDMI_1440X480P_60HZ: |
| case TVIN_SIG_FMT_HDMI_2880X480P_60HZ: |
| case TVIN_SIG_FMT_HDMI_720X480P_120HZ: |
| case TVIN_SIG_FMT_HDMI_720X480P_240HZ: |
| case TVIN_SIG_FMT_HDMI_720X480P_60HZ_FRAME_PACKING: |
| case TVIN_SIG_FMT_CAMERA_640X480P_30HZ: |
| /* 480I */ |
| case TVIN_SIG_FMT_CVBS_NTSC_M: |
| case TVIN_SIG_FMT_CVBS_NTSC_443: |
| case TVIN_SIG_FMT_CVBS_PAL_M: |
| case TVIN_SIG_FMT_CVBS_PAL_60: |
| case TVIN_SIG_FMT_HDMI_1440X480I_60HZ: |
| case TVIN_SIG_FMT_HDMI_2880X480I_60HZ: |
| case TVIN_SIG_FMT_HDMI_1440X480I_120HZ: |
| case TVIN_SIG_FMT_HDMI_1440X480I_240HZ: |
| case TVIN_SIG_FMT_BT656IN_480I_60HZ: |
| case TVIN_SIG_FMT_BT601IN_480I_60HZ: |
| vf->pixel_ratio = PIXEL_ASPECT_RATIO_8_9; |
| break; |
| /* 576P */ |
| case TVIN_SIG_FMT_HDMI_720X576P_50HZ: |
| case TVIN_SIG_FMT_HDMI_1440X576P_50HZ: |
| case TVIN_SIG_FMT_HDMI_2880X576P_50HZ: |
| case TVIN_SIG_FMT_HDMI_720X576P_100HZ: |
| case TVIN_SIG_FMT_HDMI_720X576P_200HZ: |
| case TVIN_SIG_FMT_HDMI_720X576P_50HZ_FRAME_PACKING: |
| /* 576I */ |
| case TVIN_SIG_FMT_CVBS_PAL_I: |
| case TVIN_SIG_FMT_CVBS_PAL_CN: |
| case TVIN_SIG_FMT_CVBS_SECAM: |
| case TVIN_SIG_FMT_HDMI_1440X576I_50HZ: |
| case TVIN_SIG_FMT_HDMI_2880X576I_50HZ: |
| case TVIN_SIG_FMT_HDMI_1440X576I_100HZ: |
| case TVIN_SIG_FMT_HDMI_1440X576I_200HZ: |
| case TVIN_SIG_FMT_BT656IN_576I_50HZ: |
| case TVIN_SIG_FMT_BT601IN_576I_50HZ: |
| vf->pixel_ratio = PIXEL_ASPECT_RATIO_16_15; |
| break; |
| default: |
| vf->pixel_ratio = PIXEL_ASPECT_RATIO_1_1; |
| break; |
| } |
| } |
| |
| /* |
| * based on the bellow parameters: |
| * 1.h_active |
| * 2.v_active |
| */ |
| void vdin_set_display_ratio(struct vdin_dev_s *devp, |
| struct vframe_s *vf) |
| { |
| unsigned int re = 0; |
| enum tvin_aspect_ratio_e aspect_ratio = devp->prop.aspect_ratio; |
| |
| if (vf->width == 0 || vf->height == 0) |
| return; |
| re = (vf->width * 36) / vf->height; |
| if ((re > 36 && re <= 56) || re == 90 || re == 108) |
| vf->ratio_control = 0xc0 << DISP_RATIO_ASPECT_RATIO_BIT; |
| else if (re > 56) |
| vf->ratio_control = 0x90 << DISP_RATIO_ASPECT_RATIO_BIT; |
| else |
| vf->ratio_control = 0x0 << DISP_RATIO_ASPECT_RATIO_BIT; |
| |
| switch (aspect_ratio) { |
| case TVIN_ASPECT_4x3_FULL: |
| vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM; |
| vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS; |
| vf->pic_mode.hs = 0; |
| vf->pic_mode.he = 0; |
| vf->pic_mode.vs = 0; |
| vf->pic_mode.ve = 0; |
| /* 3*256/4=0xc0 */ |
| vf->pic_mode.custom_ar = 0xc0; |
| vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE; |
| break; |
| case TVIN_ASPECT_14x9_FULL: |
| vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM; |
| vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS; |
| vf->pic_mode.hs = 0; |
| vf->pic_mode.he = 0; |
| vf->pic_mode.vs = 0; |
| vf->pic_mode.ve = 0; |
| /* 9*256/14=0xc0 */ |
| vf->pic_mode.custom_ar = 0xa4; |
| vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE; |
| break; |
| case TVIN_ASPECT_16x9_FULL: |
| vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM; |
| vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS; |
| vf->pic_mode.hs = 0; |
| vf->pic_mode.he = 0; |
| vf->pic_mode.vs = 0; |
| vf->pic_mode.ve = 0; |
| /* 9*256/16=0xc0 */ |
| vf->pic_mode.custom_ar = 0x90; |
| vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE; |
| break; |
| case TVIN_ASPECT_14x9_LB_CENTER: |
| /**720/462=14/9;(576-462)/2=57;57/2=28**/ |
| /**need cut more**/ |
| vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM; |
| vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS; |
| vf->pic_mode.hs = 0; |
| vf->pic_mode.he = 0; |
| vf->pic_mode.vs = 36; |
| vf->pic_mode.ve = 36; |
| vf->pic_mode.custom_ar = 0xa4; |
| vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE; |
| break; |
| case TVIN_ASPECT_14x9_LB_TOP: |
| /**720/462=14/9;(576-462)/2=57**/ |
| vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM; |
| vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS; |
| vf->pic_mode.hs = 0; |
| vf->pic_mode.he = 0; |
| vf->pic_mode.vs = 0; |
| vf->pic_mode.ve = 57; |
| vf->pic_mode.custom_ar = 0xa4; |
| vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE; |
| break; |
| case TVIN_ASPECT_16x9_LB_CENTER: |
| /**720/405=16/9;(576-405)/2=85;85/2=42**/ |
| /**need cut more**/ |
| vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM; |
| vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS; |
| vf->pic_mode.hs = 0; |
| vf->pic_mode.he = 0; |
| vf->pic_mode.vs = 70; |
| vf->pic_mode.ve = 70; |
| vf->pic_mode.custom_ar = 0x90; |
| vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE; |
| break; |
| case TVIN_ASPECT_16x9_LB_TOP: |
| /**720/405=16/9;(576-405)/2=85**/ |
| vf->pic_mode.screen_mode = VIDEO_WIDEOPTION_CUSTOM; |
| vf->pic_mode.provider = PIC_MODE_PROVIDER_WSS; |
| vf->pic_mode.hs = 0; |
| vf->pic_mode.he = 0; |
| vf->pic_mode.vs = 0; |
| vf->pic_mode.ve = 85; |
| vf->pic_mode.custom_ar = 0x90; |
| vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| /*function:set source bitdepth |
| * based on parameter: |
| * devp->source_bitdepth: 8/9/10 |
| */ |
| inline void vdin_set_source_bitdepth(struct vdin_dev_s *devp, |
| struct vframe_s *vf) |
| { |
| switch (devp->source_bitdepth) { |
| case VDIN_COLOR_DEEPS_10BIT: |
| vf->bitdepth = BITDEPTH_Y10 | BITDEPTH_U10 | BITDEPTH_V10; |
| break; |
| case VDIN_COLOR_DEEPS_9BIT: |
| vf->bitdepth = BITDEPTH_Y9 | BITDEPTH_U9 | BITDEPTH_V9; |
| break; |
| case VDIN_COLOR_DEEPS_8BIT: |
| vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; |
| break; |
| default: |
| vf->bitdepth = BITDEPTH_Y8 | BITDEPTH_U8 | BITDEPTH_V8; |
| break; |
| } |
| if (devp->full_pack == VDIN_422_FULL_PK_EN && |
| devp->source_bitdepth > 8 && |
| (devp->format_convert == VDIN_FORMAT_CONVERT_YUV_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_RGB_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_GBR_YUV422 || |
| devp->format_convert == VDIN_FORMAT_CONVERT_BRG_YUV422)) |
| vf->bitdepth |= FULL_PACK_422_MODE; |
| } |
| |
| /*@20170905new add for support dynamic adj dest_format yuv422/yuv444, |
| *not support nv21 dynamic adj!!! |
| */ |
| void vdin_source_bitdepth_reinit(struct vdin_dev_s *devp) |
| { |
| int i = 0; |
| struct vf_entry *master; |
| struct vframe_s *vf; |
| struct vf_pool *p = devp->vfp; |
| |
| for (i = 0; i < p->size; ++i) { |
| master = vf_get_master(p, i); |
| vf = &master->vf; |
| vdin_set_source_bitdepth(devp, vf); |
| } |
| } |
| |
| void vdin_clk_onoff(struct vdin_dev_s *devp, bool onoff) |
| { |
| unsigned int offset = devp->addr_offset; |
| |
| if (onoff) { |
| wr(offset, VDIN_COM_GCLK_CTRL, 0); |
| wr(offset, VDIN_COM_GCLK_CTRL2, 0); |
| } else { |
| wr(offset, VDIN_COM_GCLK_CTRL, 0x55555555); |
| wr(offset, VDIN_COM_GCLK_CTRL2, 0x55555555); |
| } |
| } |
| |
| void vdin_set_matrix_color(struct vdin_dev_s *devp) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int mode = devp->matrix_pattern_mode; |
| |
| /*vdin bist mode RGB:black*/ |
| wr(offset, VDIN_MATRIX_CTRL, 0x4); |
| wr(offset, VDIN_MATRIX_COEF00_01, 0x0); |
| wr(offset, VDIN_MATRIX_COEF02_10, 0x0); |
| wr(offset, VDIN_MATRIX_COEF11_12, 0x0); |
| wr(offset, VDIN_MATRIX_COEF20_21, 0x0); |
| wr(offset, VDIN_MATRIX_COEF22, 0x0); |
| wr(offset, VDIN_MATRIX_PRE_OFFSET0_1, 0x0); |
| wr(offset, VDIN_MATRIX_PRE_OFFSET2, 0x0); |
| if (mode == 1) { |
| wr(offset, VDIN_MATRIX_OFFSET0_1, 0x10f010f); |
| wr(offset, VDIN_MATRIX_OFFSET2, 0x2ff); |
| } else if (mode == 2) { |
| wr(offset, VDIN_MATRIX_OFFSET0_1, 0x10f010f); |
| wr(offset, VDIN_MATRIX_OFFSET2, 0x1ff); |
| } else if (mode == 3) { |
| wr(offset, VDIN_MATRIX_OFFSET0_1, 0x00003ff); |
| wr(offset, VDIN_MATRIX_OFFSET2, 0x0); |
| } else if (mode == 4) { |
| wr(offset, VDIN_MATRIX_OFFSET0_1, 0x1ff01ff); |
| wr(offset, VDIN_MATRIX_OFFSET2, 0x1ff); |
| } else { |
| wr(offset, VDIN_MATRIX_OFFSET0_1, 0x1ff010f); |
| wr(offset, VDIN_MATRIX_OFFSET2, 0x2ff); |
| } |
| |
| if (mode) |
| wr(offset, VDIN_MATRIX_CTRL, 0x6); |
| else |
| wr(offset, VDIN_MATRIX_CTRL, 0x0); |
| pr_info("%s offset:%d, md:%d\n", __func__, offset, mode); |
| } |
| |
| /* only active under vdi6 loopback case */ |
| void vdin_set_bist_pattern(struct vdin_dev_s *devp, unsigned int onoff, unsigned int pat) |
| { |
| unsigned int offset = devp->addr_offset; |
| unsigned int de_start = 0x7; |
| unsigned int v_blank = 0x3f; |
| unsigned int h_blank = 0xff; |
| |
| if (onoff) { |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, de_start, |
| VDI6_BIST_DE_START_BIT, VDI6_BIST_DE_START_WID); |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, v_blank, |
| VDI6_BIST_VBLANK_BIT, VDI6_BIST_VBLANK_WID); |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, h_blank, |
| VDI6_BIST_HBLANK_BIT, VDI6_BIST_HBLANK_WID); |
| |
| /* 0:horizontal gray scale, 1:vertical gray scale, 2,3:random data */ |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, pat, |
| VDI6_BIST_SEL_BIT, VDI6_BIST_SEL_WID); |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, 1, |
| VDI6_BIST_EN_BIT, VDI6_BIST_EN_WID); |
| } else { |
| wr_bits(offset, VDIN_ASFIFO_CTRL0, 0, |
| VDI6_BIST_EN_BIT, VDI6_BIST_EN_WID); |
| } |
| } |
| |
| void vdin_dmc_ctrl(struct vdin_dev_s *devp, bool onoff) |
| { |
| unsigned int reg; |
| |
| if (onoff) { |
| /* for 4k nr, dmc vdin write band width not good |
| * dmc write 1 set to supper urgent |
| */ |
| if (devp->dtdata->hw_ver == VDIN_HW_T5 || |
| devp->dtdata->hw_ver == VDIN_HW_T5W) { |
| reg = READ_DMCREG(0x6c) & (~(1 << 17)); |
| if (!(reg & (1 << 18))) |
| WRITE_DMCREG(0x6c, reg | (1 << 18)); |
| } |
| } else { |
| /* for 4k nr, dmc vdin write band width not good |
| * dmc write 1 set to urgent |
| */ |
| if (devp->dtdata->hw_ver == VDIN_HW_T5 || |
| devp->dtdata->hw_ver == VDIN_HW_T5W) { |
| reg = READ_DMCREG(0x6c) & (~(1 << 18)); |
| WRITE_DMCREG(0x6c, reg | (1 << 17)); |
| } |
| } |
| } |
| |