| /* |
| * Copyright (C) 2018 Synaptics Incorporated. 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 version 2 as |
| * published by the Free Software Foundation. |
| * |
| * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND |
| * SYNAPTICS EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, |
| * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE, AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY |
| * INTELLECTUAL PROPERTY RIGHTS. IN NO EVENT SHALL SYNAPTICS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, OR |
| * CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE |
| * OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED AND |
| * BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS |
| * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF |
| * COMPETENT JURISDICTION DOES NOT PERMIT THE DISCLAIMER OF DIRECT |
| * DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' TOTAL CUMULATIVE LIABILITY |
| * TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. DOLLARS. |
| */ |
| |
| #include <common.h> |
| #include "util.h" |
| #include "io.h" |
| #include "soc.h" |
| #include "vpp_module.h" |
| #include "vpp_cfg.h" |
| #include "vpp_api.h" |
| #include "vpp_mem.h" |
| #include "api_dhub.h" |
| #include "avio.h" |
| #include "Galois_memmap.h" |
| #include "apbRegBase.h" |
| #include "vpp_bcm_cmds_api.h" |
| #include "show_logoframe.h" |
| #include "avpll_api.h" |
| |
| #define HDMITX_ENABLE_TIMEOUT |
| #define HDMITX_TIMEOUT_COUNT 500 |
| |
| #define avioDhubSemMap_vpp_vppCPCB0_intr avioDhubSemMap_vpp128b_vpp_inr0 |
| #define avioDhubSemMap_vpp_vppOUT4_intr avioDhubSemMap_vpp128b_vpp_inr6 |
| #define bTST(x, b) (((x) >> (b)) & 1) |
| |
| #define MEMMAP_AVIO_REG_BASE 0xF7400000 |
| |
| static VPP_OBJ *pVppobj; |
| volatile unsigned logo_isr_count; |
| |
| extern int VPP_ISR_Handler(UINT32 msg_id, UINT32 msg_para, VPP_OBJ *vpp_obj); |
| void show_logoframe_isr(void); |
| extern int register_isr(void (*isr)(void), int irq_id); |
| extern void set_irq_enable(int irq_id); |
| |
| static void enable_irq() |
| { |
| if(register_isr(show_logoframe_isr, IRQ_dHubIntrAvio0)) |
| printf("vpp isr can't be registered\n"); |
| |
| set_irq_enable(IRQ_dHubIntrAvio0); |
| } |
| |
| void show_logoframe_isr() |
| { |
| ++logo_isr_count; |
| VPP_ISR_Handler_irq(); |
| } |
| |
| static VOID delay_1us(INT32 DelayTime) |
| { |
| (void)DelayTime; |
| volatile unsigned int counter = 200000; |
| while(--counter > 0); |
| } |
| |
| |
| VOID MV_VPPOBJ_Reset(VOID) |
| { |
| unsigned int counter = 0; |
| unsigned int regData = 0; |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_Reset_1, sizeof(cmd_VPPOBJ_Reset_1), 1); |
| |
| delay_1us(10000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_Reset_2, sizeof(cmd_VPPOBJ_Reset_2), 1); |
| |
| delay_1us(10000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_Reset_3, sizeof(cmd_VPPOBJ_Reset_3), 1); |
| |
| delay_1us(10000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_Reset_4, sizeof(cmd_VPPOBJ_Reset_4), 1); |
| |
| delay_1us(10000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1ce); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x003c1b89); |
| delay_1us(550); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00341b89); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f619064); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1cf); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1ce); |
| delay_1us(35000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f639064); |
| counter = 0; |
| regData = 0; |
| GA_REG_WORD32_READ(0xf7480008, ®Data); |
| delay_1us(2000); |
| do { |
| GA_REG_WORD32_READ(0xf74800a0, ®Data); |
| if (regData & 0x10000) |
| break; |
| counter++; |
| if (counter >= 2000) { |
| printf("MV_VPPOBJ_Reset: calibration 1 failed : %x\n", |
| regData); |
| break; |
| } |
| } while (1); |
| delay_1us(20000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_Reset_5, sizeof(cmd_VPPOBJ_Reset_5), 1); |
| |
| delay_1us(10000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1ce); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00388312); |
| delay_1us(550); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00308312); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e19064); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1cf); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1ce); |
| delay_1us(35000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e39064); |
| counter = 0; |
| regData = 0; |
| delay_1us(2000); |
| do { |
| GA_REG_WORD32_READ(0xf74800a0, ®Data); |
| if (regData & 0x10000) |
| break; |
| counter++; |
| if (counter >= 2000) { |
| printf("MV_VPPOBJ_Reset : calibration 2 failed : %x\n", |
| regData); |
| break; |
| } |
| } while (1); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e19064); |
| GA_REG_WORD32_WRITE(0xf7480030, 0x00308312); |
| GA_REG_WORD32_WRITE(0xf7480030, 0x00388312); |
| delay_1us(200); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_Reset_6, sizeof(cmd_VPPOBJ_Reset_6), 1); |
| |
| delay_1us(200); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_Reset_7, sizeof(cmd_VPPOBJ_Reset_7), 1); |
| } |
| |
| VOID MV_VPPOBJ_Config() |
| { |
| VPP_REG_Block_Write(cmd_VPPOBJ_Config, sizeof(cmd_VPPOBJ_Config), 1); |
| } |
| |
| VOID MV_VPPOBJ_SetCPCBOutputResolution() |
| { |
| #if defined(USE_RES_1080P) |
| unsigned int counter = 0; |
| unsigned int regData = 0; |
| GA_REG_WORD32_WRITE(0xf74800c8, 0x00000000); |
| GA_REG_WORD32_WRITE(0xf74800cc, 0x86666000); |
| GA_REG_WORD32_WRITE(0xf74b0090, 0x00000001); |
| delay_1us(20000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_1, sizeof(cmd_VPPOBJ_CPCB_1), 0); |
| |
| delay_1us(10000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1ce); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x003c1b89); |
| delay_1us(550); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00341b89); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f619064); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1cf); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1ce); |
| delay_1us(35000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f639064); |
| counter = 0; |
| regData = 0; |
| delay_1us(2000); |
| do { |
| GA_REG_WORD32_READ(0xf74800a0, ®Data); |
| if (regData & 0x10000) |
| break; |
| counter++; |
| if (counter >= 2000) { |
| printf("MV_VPPOBJ_SetCPCBOutputResolution: calibration 1 failed : %x\n", |
| regData); |
| break; |
| } |
| } while (1); |
| delay_1us(20000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_2, sizeof(cmd_VPPOBJ_CPCB_2), 0); |
| |
| delay_1us(10000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1ce); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00388312); |
| delay_1us(550); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00308312); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e19064); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1cf); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1ce); |
| delay_1us(35000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e39064); |
| counter = 0; |
| regData = 0; |
| delay_1us(2000); |
| do { |
| GA_REG_WORD32_READ(0xf74800a0, ®Data); |
| if (regData & 0x10000) |
| break; |
| counter++; |
| if (counter >= 2000) { |
| printf("MV_VPPOBJ_SetCPCBOutputResolution: calibration 2 failed : %x\n", |
| regData); |
| break; |
| } |
| } while (1); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e19064); |
| GA_REG_WORD32_WRITE(0xf7480030, 0x00308312); |
| GA_REG_WORD32_WRITE(0xf7480030, 0x00388312); |
| delay_1us(200); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_3, sizeof(cmd_VPPOBJ_CPCB_3), 0); |
| |
| delay_1us(200); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_4, sizeof(cmd_VPPOBJ_CPCB_4), 0); |
| |
| delay_1us(10000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1ce); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x003c1b89); |
| delay_1us(550); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00341b89); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f619064); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1cf); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1ce); |
| delay_1us(35000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f639064); |
| counter = 0; |
| regData = 0; |
| delay_1us(2000); |
| do { |
| GA_REG_WORD32_READ(0xf74800a0, ®Data); |
| if (regData & 0x10000) |
| break; |
| counter++; |
| if (counter >= 2000) { |
| printf("MV_VPPOBJ_SetCPCBOutputResolution: calibration 2 failed : %x\n", |
| regData); |
| break; |
| } |
| } while (1); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f619064); |
| GA_REG_WORD32_WRITE(0xf7480030, 0x0034a3d7); |
| GA_REG_WORD32_WRITE(0xf7480030, 0x003ca3d7); |
| delay_1us(200); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_5, sizeof(cmd_VPPOBJ_CPCB_5), 0); |
| |
| delay_1us(10000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_6, sizeof(cmd_VPPOBJ_CPCB_6), 0); |
| #elif defined(USE_RES_720P) |
| unsigned int counter = 0; |
| unsigned int regData = 0; |
| GA_REG_WORD32_WRITE(0xf74800c8, 0x00000000); |
| GA_REG_WORD32_WRITE(0xf74800cc, 0x86666000); |
| GA_REG_WORD32_WRITE(0xf74b0090, 0x00000001); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480060, 0x00300000); |
| GA_REG_WORD32_WRITE(0xf7480060, 0x00380000); |
| delay_1us(200); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_1, sizeof(cmd_VPPOBJ_CPCB_1), 0); |
| |
| delay_1us(10000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1ce); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x003c1b89); |
| delay_1us(550); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00341b89); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f619064); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1cf); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x24efe1ce); |
| delay_1us(35000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f639064); |
| counter = 0; |
| regData = 0; |
| delay_1us(2000); |
| do { |
| GA_REG_WORD32_READ(0xf74800a0, ®Data); |
| if (regData & 0x10000) |
| break; |
| counter++; |
| if (counter >= 2000) { |
| printf("MV_VPPOBJ_SetCPCBOutputResolution: calibration failed : %x\n", |
| regData); |
| break; |
| } |
| } while (1); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x2f619064); |
| GA_REG_WORD32_WRITE(0xf7480020, 0x00300000); |
| GA_REG_WORD32_WRITE(0xf7480020, 0x00380000); |
| delay_1us(200); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_2, sizeof(cmd_VPPOBJ_CPCB_2), 0); |
| |
| delay_1us(10000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_3, sizeof(cmd_VPPOBJ_CPCB_3), 0); |
| #elif defined(USE_RES_480P) |
| unsigned int counter = 0; |
| unsigned int regData = 0; |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_1, sizeof(cmd_VPPOBJ_CPCB_1), 0); |
| |
| delay_1us(10000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1ce); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00388312); |
| delay_1us(550); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00308312); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e19064); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1cf); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1ce); |
| delay_1us(35000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e39064); |
| counter = 0; |
| regData = 0; |
| delay_1us(2000); |
| do { |
| GA_REG_WORD32_READ(0xf74800a0, ®Data); |
| if (regData & 0x10000) |
| break; |
| counter++; |
| if (counter >= 2000) { |
| printf("MV_VPPOBJ_SetCPCBOutputResolution: calibration 1 failed : %x\n", |
| regData); |
| break; |
| } |
| } while (1); |
| delay_1us(20000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_2, sizeof(cmd_VPPOBJ_CPCB_2), 0); |
| |
| delay_1us(10000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1ce); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00388312); |
| delay_1us(550); |
| GA_REG_WORD32_WRITE(0xf7480090, 0x00308312); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e19064); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1cf); |
| delay_1us(20000); |
| GA_REG_WORD32_WRITE(0xf7480000, 0x2479e1ce); |
| delay_1us(35000); |
| GA_REG_WORD32_WRITE(0xf7480008, 0x27e39064); |
| counter = 0; |
| regData = 0; |
| delay_1us(2000); |
| do { |
| GA_REG_WORD32_READ(0xf74800a0, ®Data); |
| if (regData & 0x10000) |
| break; |
| counter++; |
| if (counter >= 2000) { |
| printf("MV_VPPOBJ_SetCPCBOutputResolution: calibration 2 failed : %x\n", |
| regData); |
| break; |
| } |
| } while (1); |
| delay_1us(20000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_3, sizeof(cmd_VPPOBJ_CPCB_3), 0); |
| |
| delay_1us(10000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_CPCB_4, sizeof(cmd_VPPOBJ_CPCB_4), 0); |
| #endif |
| } |
| |
| VOID MV_VPPOBJ_OpenDispWindow() |
| { |
| VPP_REG_Block_Write(cmd_VPPOBJ_OpenDispWindow, sizeof(cmd_VPPOBJ_OpenDispWindow), 0); |
| } |
| |
| VOID MV_VPPOBJ_CloseDispWindow() |
| { |
| GA_REG_WORD32_WRITE(0xf74b004c, 0x00000003); |
| } |
| |
| |
| INT32 MV_DisplayFrame(VPP_OBJ *pVpp_obj, VBUF_INFO *vbufinfo) |
| { |
| if (frmq_push(&(pVpp_obj->inputq), vbufinfo) == 0) |
| return MV_VPP_EFRAMEQFULL; |
| return 0; |
| } |
| |
| VOID MV_VPP_RecycleFrames(VOID *param) |
| { |
| VOID *frame = NULL; |
| VPP_OBJ *pVpp_obj = (VPP_OBJ *)param; |
| if (frmq_pop(&(pVpp_obj->outputq), (VOID **)&frame)) |
| frmq_pop_commit(&(pVpp_obj->outputq)); |
| } |
| |
| INT32 MV_VPP_SetHdmiVideoFmt(unsigned int hdmi_mode) |
| { |
| unsigned int counter = 0; |
| unsigned int regData = 0; |
| GA_REG_WORD32_WRITE(0xf74800c8, 0x00000000); |
| GA_REG_WORD32_WRITE(0xf74800cc, 0x86666000); |
| GA_REG_WORD32_WRITE(0xf74b0090, 0x00000001); |
| delay_1us(20000); |
| |
| #if (defined(USE_RES_1080P) || defined(USE_RES_720P)) |
| cmd_VPPOBJ_HDMI_1[42] = (((!!hdmi_mode) << 5) & 0x00000020); |
| #elif defined(USE_RES_480P) |
| cmd_VPPOBJ_HDMI_1[54] = (((!!hdmi_mode) << 5) & 0x00000020); |
| #endif |
| VPP_REG_Block_Write(cmd_VPPOBJ_HDMI_1, sizeof(cmd_VPPOBJ_HDMI_1), 0); |
| |
| delay_1us(200); |
| VPP_REG_Block_Write(cmd_VPPOBJ_HDMI_2, sizeof(cmd_VPPOBJ_HDMI_2), 0); |
| delay_1us(1000); |
| GA_REG_WORD32_WRITE(0xf74800e0, 0x00000008); |
| GA_REG_WORD32_WRITE(0xf74800dc, 0x1e54a760); |
| counter = 0; |
| regData = 0; |
| do |
| { |
| delay_1us(100); |
| GA_REG_WORD32_READ(0xf74800e4, ®Data); |
| counter++; |
| if(counter>=2000) { |
| printf("MV_VPP_SetHdmiVideoFmt: failed : %x & 0x200 \n",regData); |
| break; |
| } |
| }while(((regData & 0x200) == 0x200)); |
| |
| if((regData & 0x4000) == 0x4000) |
| { |
| printf("MV_VPP_SetHdmiVideoFmt: Calibration failed\n"); |
| } |
| VPP_REG_Block_Write(cmd_VPPOBJ_HDMI_3, sizeof(cmd_VPPOBJ_HDMI_3), 0); |
| counter = 0; |
| regData = 0; |
| do |
| { |
| delay_1us(100); |
| GA_REG_WORD32_READ(0xf74800e4, ®Data); |
| counter++; |
| if(counter>=2000) { |
| printf("MV_VPP_SetHdmiVideoFmt: failed : %x & 0x100 \n",regData); |
| break; |
| } |
| }while(((regData & 0x100) == 0)); |
| |
| delay_1us(1000); |
| GA_REG_WORD32_WRITE(0xf74800c8, 0x0049203f); |
| delay_1us(1000); |
| |
| VPP_REG_Block_Write(cmd_VPPOBJ_HDMI_4, sizeof(cmd_VPPOBJ_HDMI_4), 0); |
| return 0; |
| } |
| |
| INT32 MV_VPP_CONFIG(INT32 cpcbID, VPP_OBJ **pVpp) |
| { |
| VPP_OBJ *vpp_obj; |
| INT32 result = MV_VPP_OK; |
| |
| vpp_obj = UtilMemAllocZ(sizeof(VPP_OBJ)); |
| |
| if (vpp_obj == NULL) { |
| printf("Failed to allocate mem for vpp object\n"); |
| *pVpp = NULL; |
| return MV_VPP_ENOMEM; |
| } |
| |
| *pVpp = vpp_obj; |
| /* create VBI BCM buffer */ |
| if (VPP_BCMBUF_Create(&(vpp_obj->vbi_bcm_buf[0]), |
| BCM_BUFFER_SIZE) != MV_VPP_OK) { |
| result = MV_VPP_ENOMEM; |
| goto cleanup; |
| } |
| |
| if (VPP_BCMBUF_Create(&(vpp_obj->vbi_bcm_buf[1]), |
| BCM_BUFFER_SIZE) != MV_VPP_OK) { |
| result = MV_VPP_ENOMEM; |
| goto cleanup; |
| } |
| if (VPP_BCMBUF_Create(&(vpp_obj->vbi_clear_bcm_buf[0]), |
| BCM_BUFFER_SIZE) != MV_VPP_OK) { |
| result = MV_VPP_ENOMEM; |
| goto cleanup; |
| } |
| if (VPP_BCMBUF_Create(&(vpp_obj->vbi_clear_bcm_buf[0]), |
| BCM_BUFFER_SIZE) != MV_VPP_OK) { |
| result = MV_VPP_ENOMEM; |
| goto cleanup; |
| } |
| if (VPP_BCMBUF_Create(&(vpp_obj->vbi_clear_bcm_buf[1]), |
| BCM_BUFFER_SIZE) != MV_VPP_OK){ |
| result = MV_VPP_ENOMEM; |
| goto cleanup; |
| } |
| (vpp_obj->vbi_dma_cfgQ[0]).handle = UtilMemAllocZ(DMA_CMD_BUFFER_SIZE); |
| if((vpp_obj->vbi_dma_cfgQ[0]).handle == NULL) { |
| goto cleanup; |
| } |
| vpp_obj->vbi_dma_cfgQ[0].addr = (vpp_obj->vbi_dma_cfgQ[0]).handle; |
| vpp_obj->vbi_dma_cfgQ[0].phy_addr = (vpp_obj->vbi_dma_cfgQ[0]).handle; |
| (&vpp_obj->vbi_dma_cfgQ[0])->len = 0; |
| |
| (vpp_obj->vbi_dma_cfgQ[1]).handle = UtilMemAllocZ(DMA_CMD_BUFFER_SIZE); |
| if((vpp_obj->vbi_dma_cfgQ[1]).handle == NULL){ |
| goto cleanup; |
| } |
| vpp_obj->vbi_dma_cfgQ[1].addr = (vpp_obj->vbi_dma_cfgQ[1]).handle; |
| vpp_obj->vbi_dma_cfgQ[1].phy_addr = (vpp_obj->vbi_dma_cfgQ[1]).handle; |
| (&vpp_obj->vbi_dma_cfgQ[1])->len = 0; |
| |
| vpp_obj->curr_cpcb_vbi_dma_cfgQ = &(vpp_obj->vbi_dma_cfgQ[0]); |
| |
| (vpp_obj->vbi_bcm_cfgQ[0]).handle = UtilMemAllocZ(DMA_CMD_BUFFER_SIZE); |
| if((vpp_obj->vbi_bcm_cfgQ[0]).handle == NULL){ |
| goto cleanup; |
| } |
| vpp_obj->vbi_bcm_cfgQ[0].addr = vpp_obj->vbi_bcm_cfgQ[0].handle; |
| vpp_obj->vbi_bcm_cfgQ[0].phy_addr = vpp_obj->vbi_bcm_cfgQ[0].handle; |
| (&vpp_obj->vbi_bcm_cfgQ[0])->len = 0; |
| |
| (vpp_obj->vbi_bcm_cfgQ[1]).handle = UtilMemAllocZ(DMA_CMD_BUFFER_SIZE); |
| if((vpp_obj->vbi_bcm_cfgQ[1]).handle == NULL){ |
| goto cleanup; |
| } |
| vpp_obj->vbi_bcm_cfgQ[1].addr = vpp_obj->vbi_bcm_cfgQ[1].handle; |
| vpp_obj->vbi_bcm_cfgQ[1].phy_addr = vpp_obj->vbi_bcm_cfgQ[1].handle; |
| (&vpp_obj->vbi_bcm_cfgQ[1])->len = 0; |
| |
| vpp_obj->curr_cpcb_vbi_bcm_cfgQ = &(vpp_obj->vbi_bcm_cfgQ[0]); |
| |
| /* reset VBI BCM buffer */ |
| VPP_BCMBUF_Reset(&vpp_obj->vbi_bcm_buf[0]); |
| vpp_obj->pVbiBcmBuf = &vpp_obj->vbi_bcm_buf[0]; |
| VPP_BCMBUF_Reset(&vpp_obj->vbi_bcm_buf[1]); |
| vpp_obj->pVbiBcmBufCpcb[0] = &vpp_obj->vbi_bcm_buf[0]; |
| vpp_obj->pVbiBcmBufCpcb[1] = &vpp_obj->vbi_bcm_buf[0]; |
| vpp_obj->pVbiBcmBufCpcb[2] = &vpp_obj->vbi_bcm_buf[0]; |
| /* reset VBI CLEAR BCM buffer */ |
| VPP_BCMBUF_Reset(&vpp_obj->vbi_clear_bcm_buf[0]); |
| vpp_obj->pVbiClearBcmBuf = &vpp_obj->vbi_clear_bcm_buf[0]; |
| VPP_BCMBUF_Reset(&vpp_obj->vbi_clear_bcm_buf[1]); |
| vpp_obj->pVbiClearBcmBufCpcb[0] = &vpp_obj->vbi_clear_bcm_buf[0]; |
| vpp_obj->pVbiClearBcmBufCpcb[1] = &vpp_obj->vbi_clear_bcm_buf[0]; |
| vpp_obj->pVbiClearBcmBufCpcb[2] = &vpp_obj->vbi_clear_bcm_buf[0]; |
| |
| MV_VPPOBJ_Reset(); |
| |
| vpp_obj->pSemHandle = dhub_semaphore(&VPP_dhubHandle.dhub); |
| |
| MV_VPPOBJ_Config(); |
| |
| VPP_RegisterInterruptService(MV_VPP_RecycleFrames, NULL, NULL); |
| BCM_SCHED_SetMux(BCM_SCHED_Q0, 0); |
| BCM_SCHED_SetMux(BCM_SCHED_Q1, 11); |
| vpp_obj->status = STATUS_ACTIVE; |
| |
| MV_VPPOBJ_SetCPCBOutputResolution(); |
| |
| MV_VPP_SetHdmiVideoFmt(HDMI_MODE); |
| MV_VPPOBJ_OpenDispWindow(); |
| |
| VPP_BCMBUF_Select(vpp_obj->pVbiBcmBuf, cpcbID); |
| vpp_obj->vbi_num = 0; |
| vpp_obj->dvstatus = STATUS_DISP_VIDEO; |
| vpp_obj->curr_frame = NULL; |
| vpp_obj->prev_curr_frame = NULL; |
| vpp_obj->curr_still_picture = NULL; |
| vpp_obj->still_picture = NULL; |
| vpp_obj->frm_count = 0; |
| vpp_obj->skip_vde_int = 0; |
| /* reset frame descriptor queues */ |
| frmq_reset(&(vpp_obj->inputq)); |
| frmq_reset(&(vpp_obj->outputq)); |
| |
| vpp_obj->dmaRID = avioDhubChMap_vpp128b_MV_R0; |
| |
| return MV_VPP_OK; |
| cleanup: |
| printf("Failed to allocate memory for VPP buffers\n"); |
| /*No need to check validity of pointer here*/ |
| VPP_BCMBUF_Destroy(&(vpp_obj->vbi_bcm_buf[0])); |
| VPP_BCMBUF_Destroy(&(vpp_obj->vbi_bcm_buf[1])); |
| VPP_BCMBUF_Destroy(&(vpp_obj->vbi_clear_bcm_buf[0])); |
| VPP_BCMBUF_Destroy(&(vpp_obj->vbi_clear_bcm_buf[1])); |
| return result; |
| } |
| |
| VOID MV_VPP_DisplayPatternFrame(INT32 x, INT32 y, INT32 logo_width, |
| INT32 logo_height, INT32 logo_stride, VOID *yuv_logo) |
| { |
| VBUF_INFO *pVbufInfo = NULL; |
| unsigned size; |
| int i =0; |
| char *dest = NULL; |
| char *src = NULL; |
| int align_x = logo_width % 8; |
| int align_w = logo_width + align_x; |
| int align_stride = align_w*2; |
| |
| if((logo_width <= 0 || logo_height <= 0) || |
| ((x + align_w) > MV_SYSTEM_XRES) || |
| ((y + logo_height) > MV_SYSTEM_YRES) || |
| (x < 0 || y < 0)) |
| { |
| printf("Error: Invalid width=%d and height=%d\n", |
| logo_width, logo_height); |
| return; |
| } |
| |
| pVbufInfo = MV_VPP_GetFrame(x, y, align_w, logo_height, align_stride); |
| if(pVbufInfo == NULL) |
| { |
| printf("Error: Memory not available for frame\n"); |
| } |
| printf("MV_VPP_DisplayPatternFrame pVbufInfo->m_pbuf_start=0x%x " |
| "pVbufInfo->m_buf_stride=%d pVbufInfo->m_active_height=%d\n", |
| pVbufInfo->m_pbuf_start, pVbufInfo->m_buf_stride, |
| pVbufInfo->m_active_height); |
| |
| dest = (char*)pVbufInfo->m_pbuf_start; |
| src = (char*)yuv_logo; |
| if(src == NULL || dest == NULL) |
| { |
| printf("Error: Invalid logo params\n"); |
| return; |
| } |
| for(i = 0; i < logo_height; i++) |
| { |
| memcpy(dest + (i * pVbufInfo->m_buf_stride), |
| src + (i * logo_stride), |
| logo_stride); |
| } |
| |
| size = pVbufInfo->m_buf_stride * pVbufInfo->m_active_height; |
| flush_dcache_range(pVbufInfo->m_pbuf_start, |
| (void *)(((char *)pVbufInfo->m_pbuf_start) + size)); |
| if (pVbufInfo) |
| { |
| MV_DisplayFrame(pVppobj, pVbufInfo); |
| } |
| } |
| |
| VOID MV_VPP_DisplayFrame(void **pBuf,int width,int height) |
| { |
| unsigned size; |
| VBUF_INFO *vbuf; |
| void *tptr = NULL, *buf = *pBuf; |
| |
| printf("buf=%x width=%d height=%d\n", buf, width, height); |
| vbuf = MV_VPP_GetFrame(0, 0, width, height, width*4); |
| |
| //Swap instead of MemCpy |
| tptr = vbuf->m_pbuf_start; |
| vbuf->m_pbuf_start = *pBuf; |
| *pBuf = tptr; |
| |
| size = vbuf->m_buf_stride * vbuf->m_active_height; |
| flush_dcache_range(vbuf->m_pbuf_start, |
| (void *)(((char *)vbuf->m_pbuf_start) + size)); |
| MV_VPP_RecycleFrames(pVppobj); |
| MV_DisplayFrame(pVppobj, vbuf); |
| } |
| |
| VOID VPP_ISR_Handler_irq() |
| { |
| VPP_OBJ* vpp_obj = pVppobj; |
| int instat = 0; |
| |
| vpp_obj->pSemHandle = dhub_semaphore(&VPP_dhubHandle.dhub); |
| instat = semaphore_chk_full(vpp_obj->pSemHandle, -1); |
| if(!!(bTST(instat, avioDhubSemMap_vpp_vppCPCB0_intr))) |
| { |
| semaphore_pop(vpp_obj->pSemHandle, |
| avioDhubSemMap_vpp_vppCPCB0_intr, 1); |
| semaphore_clr_full(vpp_obj->pSemHandle, |
| avioDhubSemMap_vpp_vppCPCB0_intr); |
| |
| VPP_ISR_Handler(0, instat, vpp_obj); |
| } |
| if(!!(bTST(instat, avioDhubSemMap_vpp_vppOUT4_intr))) |
| { |
| semaphore_pop(vpp_obj->pSemHandle, |
| avioDhubSemMap_vpp_vppOUT4_intr, 1); |
| semaphore_clr_full(vpp_obj->pSemHandle, |
| avioDhubSemMap_vpp_vppOUT4_intr); |
| } |
| } |
| |
| static int dhub_init(void) |
| { |
| GA_REG_WORD32_WRITE(MEMMAP_AVIO_REG_BASE + |
| AVIO_MEMMAP_AVIO_BCM_REG_BASE + RA_AVIO_BCM_AUTOPUSH, 0x0); |
| DhubInitialization(0, VPP_DHUB_BASE, VPP_HBO_SRAM_BASE, &VPP_dhubHandle, |
| VPP_config, VPP_NUM_OF_CHANNELS, DHUB_TYPE_128BIT); |
| DhubInitialization(0, AG_DHUB_BASE, AG_HBO_SRAM_BASE, &AG_dhubHandle, |
| AG_config, AG_NUM_OF_CHANNELS, DHUB_TYPE_64BIT); |
| return 0; |
| } |
| |
| INT32 MV_VPP_Init(VOID) |
| { |
| int res = 0; |
| |
| MV_VPP_InitMemory(); |
| dhub_init(); |
| |
| MV_AVPLL_Enable(); |
| |
| res = MV_VPP_CONFIG(CPCB_1, &pVppobj); |
| if (pVppobj == NULL) |
| return res; |
| |
| res = create_global_desc_array(); |
| if (res != MV_VPP_OK) |
| return res; |
| |
| printf("MV_VPP_Init\n"); |
| return 0; |
| } |
| |
| void MV_VPP_Enable_IRQ() |
| { |
| logo_isr_count = 0; |
| enable_irq(); |
| |
| MV_VPP_EnableISR(pVppobj); |
| } |
| |
| VOID MV_VPP_Deinit(VOID) |
| { |
| while (logo_isr_count < MAX_ISR_COUNT); |
| |
| MV_VPPOBJ_CloseDispWindow(); |
| MV_VPP_DisableISR(pVppobj); |
| destroy_global_desc_array(); |
| VPP_BCMBUF_Destroy(&(pVppobj->vbi_bcm_buf[0])); |
| VPP_BCMBUF_Destroy(&(pVppobj->vbi_bcm_buf[1])); |
| VPP_BCMBUF_Destroy(&(pVppobj->vbi_clear_bcm_buf[0])); |
| VPP_BCMBUF_Destroy(&(pVppobj->vbi_clear_bcm_buf[1])); |
| } |
| |
| int getFrmCount() |
| { |
| return pVppobj->frm_count; |
| } |