/*
 * 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.
 */

#define _VPP_ISR_C_
#include "vpp_module.h"
#include "vpp_cfg.h"
#include "vpp_bcmbuf.h"
#include "api_avio_dhub.h"
#include "vpp_api.h"
#include "io.h"
#include "show_logoframe.h"
#include "vpp_bcm_cmds_isr.h"
#include <common.h>

#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 VPP_BCMBUF_WRITE(a, d) VPP_BCMBUF_Write(vpp_obj->pVbiBcmBuf, a, d)
#define VPP_BCMBUF_WRITE_CLEARBUF(a, d) \
                VPP_BCMBUF_Write(vpp_obj->pVbiClearBcmBuf, a, d)

static VOID VPP_CPCB_ISR_service(VPP_OBJ *vpp_obj);
static VOID disp_callback_dummy(VOID *param);

voidfunc_t disp_isr_service = disp_callback_dummy;
voidfunc_t disp_after_isr_service = disp_callback_dummy;
voidfunc_t disp_dsr_service = disp_callback_dummy;

static VOID disp_callback_dummy(VOID *param)
{
    (void)param;
}

VOID VPP_RegisterInterruptService(voidfunc_t f1, voidfunc_t f2, voidfunc_t f3)
{
    if (NULL != f1)
        disp_isr_service = f1;
    if (NULL != f2)
        disp_after_isr_service = f2;
    if (NULL != f3)
        disp_dsr_service = f3;
    return;
}

void VPP_Enable_ISR_Interrupt(VPP_OBJ *vpp_obj, int cpcbID)
{
    vpp_obj->pSemHandle = dhub_semaphore(&VPP_dhubHandle.dhub);
    if (cpcbID == CPCB_1) {
        /* configure and enable CPCB0 interrupt */
        semaphore_cfg(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppCPCB0_intr,
                1, 0);
        semaphore_clr_full(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppCPCB0_intr);
        semaphore_intr_enable(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppCPCB0_intr, 0,
                1, 0, 0, 0);
        semaphore_cfg(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppOUT4_intr,
                1, 0);
        semaphore_clr_full(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppOUT4_intr);
        semaphore_intr_enable(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppOUT4_intr, 0,
                1, 0, 0, 0);
    }
}

void VPP_Disable_ISR_Interrupt(VPP_OBJ *vpp_obj, int cpcbID)
{
    vpp_obj->pSemHandle = dhub_semaphore(&VPP_dhubHandle.dhub);
    if (cpcbID == CPCB_1) {
        semaphore_clr_full(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppCPCB0_intr);
        semaphore_intr_enable(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppCPCB0_intr, 0,
                0, 0, 0, 0);
        semaphore_clr_full(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppOUT4_intr);
        semaphore_intr_enable(vpp_obj->pSemHandle,
                avioDhubSemMap_vpp_vppOUT4_intr, 0,
                0, 0, 0, 0);
    }
    return;
}

static void updateFEChannelCurrentFrame(VPP_OBJ *vpp_obj)
{
    VBUF_INFO *pinfo;

    if (vpp_obj->dvstatus == STATUS_DISP_VIDEO) {
        /* recycle only when new frame is popped */
        if (vpp_obj->prev_curr_frame != vpp_obj->curr_frame &&
                vpp_obj->prev_curr_frame)
            frmq_push(&vpp_obj->outputq, vpp_obj->prev_curr_frame);

        vpp_obj->prev_curr_frame = vpp_obj->curr_frame;
        vpp_obj->curr_frame = NULL;
        /* try to get a new frame descriptor from frame queue */
        while (frmq_pop(&vpp_obj->inputq, (void **)&pinfo)) {
            frmq_pop_commit(&vpp_obj->inputq);
            /* recycle current frame descriptor */
            if (vpp_obj->curr_frame) {
                frmq_push(&vpp_obj->outputq,
                    vpp_obj->curr_frame);
            }
            vpp_obj->curr_frame = pinfo;
        }
        /*repeat the old frame if no one is not popped*/
        if (!vpp_obj->curr_frame)
            vpp_obj->curr_frame = vpp_obj->prev_curr_frame;
        vpp_obj->frm_count++;
    }
}

static int startChannelDataLoader(VPP_OBJ *vpp_obj)
{
    VBUF_INFO *pinfo;
    UINT32 *cfgQ, *cfgQ_shadow;
    UINT32 *cfgQ_len;

    cfgQ_shadow = vpp_obj->curr_cpcb_vbi_dma_cfgQ->addr;
    cfgQ_len = &(vpp_obj->curr_cpcb_vbi_dma_cfgQ->len);

    if (vpp_obj->dvstatus == STATUS_DISP_VIDEO)
        pinfo = vpp_obj->curr_frame;
    else
        return MV_VPP_OK;
    if (pinfo == NULL)
        return MV_VPP_OK;
    cfgQ = cfgQ_shadow + *cfgQ_len * 2;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
    *cfgQ_len += START_2NDDMA(&VPP_dhubHandle, vpp_obj->dmaRID,
            (UINT32)pinfo->m_pbuf_start,
            pinfo->m_buf_stride, pinfo->m_buf_stride, 1,
            pinfo->m_buf_stride, pinfo->m_active_height, (T64b *) cfgQ);
#pragma GCC diagnostic pop
    return MV_VPP_OK;
}

int VPP_ISR_Handler(UINT32 msg_id, UINT32 msg_para, VPP_OBJ *vpp_obj)
{
    int instat;
    HRESULT rc;
    unsigned int EmptySts;

    if (vpp_obj->status != STATUS_ACTIVE)
        return 0;

    if (VPP_CC_MSG_TYPE_VPP == msg_id) {
        instat = msg_para;
        /* CPCB-0 VBI interrupt */
        if (bTST(instat, avioDhubSemMap_vpp_vppCPCB0_intr)) {
            BCM_SCHED_GetEmptySts(0, &EmptySts);

            if (EmptySts == 0) {
                vpp_obj->skip_vde_int = 1;
                return 0;
            } else {
                vpp_obj->skip_vde_int = 0;
            }

            disp_dsr_service((void *)vpp_obj);

            /* current VBI BCM cfgQ */
            vpp_obj->curr_vbi_bcm_cfgQ =
                vpp_obj->curr_cpcb_vbi_bcm_cfgQ;

            /* reset vbi bcm & dma cfgQ length */
            vpp_obj->curr_cpcb_vbi_bcm_cfgQ->len = 0;
            vpp_obj->curr_cpcb_vbi_dma_cfgQ->len = 0;
            /* select BCM buffer for the CPCB */
            vpp_obj->pVbiBcmBuf =
                vpp_obj->pVbiBcmBufCpcb[CPCB_1];

            /* select BCM sub-buffer to dump register settings */
            VPP_BCMBUF_Select(vpp_obj->pVbiBcmBuf, CPCB_1);

            /* select CLEAR BCM buffer for the CPCB */
            vpp_obj->pVbiClearBcmBuf =
                vpp_obj->pVbiClearBcmBufCpcb[CPCB_1];

            VPP_BCMBUF_Select(vpp_obj->pVbiClearBcmBuf, CPCB_1);

            disp_isr_service(vpp_obj);

            VPP_CPCB_ISR_service(vpp_obj);
            /* generate CPCB-0 CLEAR BCM DHUB cmdQ and,*/
            rc = VPP_BCMBUF_To_CFGQ(vpp_obj->pVbiClearBcmBuf,
                    vpp_obj->curr_vbi_bcm_cfgQ);

            if (rc == MV_VPP_OK) {
                if (vpp_obj->pVbiClearBcmBufCpcb[CPCB_1] ==
                        &vpp_obj->vbi_clear_bcm_buf[0])
                    vpp_obj->pVbiClearBcmBufCpcb[CPCB_1] =
                        &vpp_obj->vbi_clear_bcm_buf[1];
                else
                    vpp_obj->pVbiClearBcmBufCpcb[CPCB_1] =
                        &vpp_obj->vbi_clear_bcm_buf[0];
            }

            /* generate CPCB-0 BCM DHUB cmdQ and,*/
            rc = VPP_BCMBUF_To_CFGQ(vpp_obj->pVbiBcmBuf,
                    vpp_obj->curr_vbi_bcm_cfgQ);
            VPP_CFGQ_To_CFGQ(vpp_obj->curr_cpcb_vbi_dma_cfgQ,
                    vpp_obj->curr_vbi_bcm_cfgQ);

            if (rc == MV_VPP_OK) {
                /* switch BCM buffer for the CPCB */
                if (vpp_obj->pVbiBcmBufCpcb[CPCB_1] ==
                        &vpp_obj->vbi_bcm_buf[0])
                    vpp_obj->pVbiBcmBufCpcb[CPCB_1] =
                        &vpp_obj->vbi_bcm_buf[1];
                else
                    vpp_obj->pVbiBcmBufCpcb[CPCB_1] =
                        &vpp_obj->vbi_bcm_buf[0];
            }

            rc = VPP_BCMDHUB_CFGQ_Commit(vpp_obj->curr_vbi_bcm_cfgQ,
                    CPCB_1, 0);

            if (vpp_obj->curr_cpcb_vbi_dma_cfgQ ==
                        &vpp_obj->vbi_dma_cfgQ[0])
                vpp_obj->curr_cpcb_vbi_dma_cfgQ =
                        &(vpp_obj->vbi_dma_cfgQ[1]);
            else
                vpp_obj->curr_cpcb_vbi_dma_cfgQ =
                        &(vpp_obj->vbi_dma_cfgQ[0]);

            if (vpp_obj->curr_cpcb_vbi_bcm_cfgQ ==
                        &vpp_obj->vbi_bcm_cfgQ[0])
                vpp_obj->curr_cpcb_vbi_bcm_cfgQ =
                        &(vpp_obj->vbi_bcm_cfgQ[1]);
            else
                vpp_obj->curr_cpcb_vbi_bcm_cfgQ =
                        &(vpp_obj->vbi_bcm_cfgQ[0]);
        }

    }
    return MV_VPP_OK;
}

void VPP_CPCB_ISR_service(VPP_OBJ *vpp_obj)
{
    static unsigned int x = 0;
    static unsigned int y = 0;
    static unsigned int w = 0;
    static unsigned int h = 0;

    unsigned int main_TG_PL_X, main_TG_PL_Y;
    unsigned int crop_TG_PL_X, crop_TG_PL_Y, total_pixels;
    unsigned int dlr_plane_size, dlr_client_size;

    static int first_time_init = 1;
    static VBUF_INFO *pinfo;
#ifdef BOOTLOGO_ANIM
    static int ix = 0, iy = 0;
#endif

    vpp_obj->vbi_num++;
    if ((vpp_obj->dvstatus == STATUS_INACTIVE) ||
                (vpp_obj->vbi_num <= 2))
        return;

    if (vpp_obj->dvstatus != STATUS_INACTIVE) {

    if(frmq_pop(&vpp_obj->inputq, (void **)&pinfo))
    {
        x = pinfo->m_active_left;
        y = pinfo->m_active_top;
        w = pinfo->m_active_width;
        h = pinfo->m_active_height;
    }
#ifdef BOOTLOGO_ANIM
        ix += 2;
        iy += 2;
        if((ix + pinfo->m_active_width) > MV_SYSTEM_XRES ||
            (iy + pinfo->m_active_height) > MV_SYSTEM_YRES)
        {
            ix = 0;
            iy = 0;
        }
        x = ix;
        y = iy;
#endif

        main_TG_PL_X = ((x & 0x1fff) | (((x+w) << 13) & 0x3ffe000));
        main_TG_PL_Y = ((y & 0xfff) | (((y+h) << 12) & 0xfff000));
        crop_TG_PL_X = ((x & 0x1fff) | (((x+w) << 13) & 0x3ffe000));
        crop_TG_PL_Y = ((y & 0xfff) | (((y+h) << 12) & 0xfff000));
        total_pixels = w * h;
        dlr_plane_size = w * h;
        dlr_client_size = ((((w+(w%8)) * 16 + 127) / 128) * h);

        if(first_time_init == 1)
        {
            cmd_ISR_PRE_DL_1[82] = dlr_plane_size;
            cmd_ISR_PRE_DL_1[94] = dlr_client_size;
            cmd_ISR_PRE_DL_1[692] = main_TG_PL_X;
            cmd_ISR_PRE_DL_1[694] = main_TG_PL_Y;
            cmd_ISR_PRE_DL_1[696] = crop_TG_PL_X;
            cmd_ISR_PRE_DL_1[698] = crop_TG_PL_Y;
            cmd_ISR_PRE_DL_1[700] = total_pixels;
            cmd_ISR_PRE_DL_1[702] = main_TG_PL_X;
            cmd_ISR_PRE_DL_1[704] = main_TG_PL_Y;

            VPP_BCMBUF_WriteBlock(vpp_obj->pVbiBcmBuf, cmd_ISR_PRE_DL_1, sizeof(cmd_ISR_PRE_DL_1));
        }
        else
        {
            cmd_ISR_PRE_DL_2[0] = dlr_plane_size;
            cmd_ISR_PRE_DL_2[2] = dlr_client_size;
            cmd_ISR_PRE_DL_2[4] = main_TG_PL_X;
            cmd_ISR_PRE_DL_2[6] = main_TG_PL_Y;
            cmd_ISR_PRE_DL_2[8] = crop_TG_PL_X;
            cmd_ISR_PRE_DL_2[10] = crop_TG_PL_Y;
            cmd_ISR_PRE_DL_2[12] = total_pixels;
            cmd_ISR_PRE_DL_2[14] = main_TG_PL_X;
            cmd_ISR_PRE_DL_2[16] = main_TG_PL_Y;

            VPP_BCMBUF_WriteBlock(vpp_obj->pVbiBcmBuf, cmd_ISR_PRE_DL_2, sizeof(cmd_ISR_PRE_DL_2));
        }
        updateFEChannelCurrentFrame(vpp_obj);
        startChannelDataLoader(vpp_obj);
        if(first_time_init == 1)
        {
            VPP_BCMBUF_WriteBlock(vpp_obj->pVbiBcmBuf, cmd_ISR_PRE_DL_3, sizeof(cmd_ISR_PRE_DL_3));
        }
        else
        {
            VPP_BCMBUF_WriteBlock(vpp_obj->pVbiBcmBuf, cmd_ISR_PRE_DL_4, sizeof(cmd_ISR_PRE_DL_4));
        }
    }
    first_time_init = 0;
    return;
}

VOID MV_VPP_EnableISR(VPP_OBJ *pVpp_obj)
{
    VPP_Enable_ISR_Interrupt(pVpp_obj, CPCB_1);
}

VOID MV_VPP_DisableISR(VPP_OBJ *pVpp_obj)
{
    VPP_Disable_ISR_Interrupt(pVpp_obj, CPCB_1);
}
