blob: 3ade9f97e8b3e2728e07e633b0e05227abdc2e50 [file] [log] [blame]
/*
* 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, &regData);
delay_1us(2000);
do {
GA_REG_WORD32_READ(0xf74800a0, &regData);
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, &regData);
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, &regData);
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, &regData);
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, &regData);
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, &regData);
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, &regData);
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, &regData);
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, &regData);
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, &regData);
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;
}