/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * 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 https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/


//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------

#include "x_pdwnc.h"
#include "x_bim.h"
#include "x_ckgen.h"
#include "x_os.h"
#include "drvcust_if.h"
#include "x_lint.h"
#include "pdwnc_config.h"
#include "pdwnc_debug.h"
#include "pdwnc_entry.h"
#include "pdwnc_gpio.h"
#include "pdwnc_t8032.h"
#include "pdwnc_srvad.h"
#include "pdwnc_hw.h"
#include "pdwnc_if.h"

//#undef PDWNC_WRITE32
//#undef PDWNC_READ32
//EXTERN UINT8 _au1CecData[];

//-----------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------
#define DEFAULT_RESET_COUNTER       (DRVCUST_InitGet(eSysResetTimer))


//-----------------------------------------------------------------------------
// Imported functions
//-----------------------------------------------------------------------------
//EXTERN void HAL_Delay_us(UINT32 u4Micros);


//-----------------------------------------------------------------------------
// Public functions
//-----------------------------------------------------------------------------
UINT32 PDWNC_IsBootByWakeup(void)
{
	if((PDWNC_ReadWakeupReason() == PDWNC_WAKE_UP_REASON_AC_POWER))
	{
		return 0;
	}
	else
	{
		return 1;
	}
	//return (IO32ReadFldAlign(PDWNC_WKRSC, FLD_WKRSC) == DEFAULT_RESET_COUNTER);
}

void PDWNC_SetupPowerDown(void)
{
    UINT32 u4Val;

    // Disable watchdog timer.
    vIO32Write4B(PDWNC_WDTCTL, 0);

    // Set reset count from 16/27 seconds to 5/27 seconds
    vIO32WriteFldAlign(PDWNC_WKRSC, DEFAULT_RESET_COUNTER, FLD_WKRSC);

	// Turn off all Interrupt.
    BIM_WRITE32(REG_IRQCL, 0xffffffff);
    BIM_WRITE32(REG_IRQEN, 0x8801);
    BIM_WRITE32(REG_FIQCL, 0xffffffff);
    BIM_WRITE32(REG_FIQEN, 0);

    _PDWNC_SetupStrapping();
    /* wait more than 1.5 IR clock cycle for IR busy bit clear */
    for (u4Val=0; u4Val<512; u4Val++) { }
    /* Do BIM clear IR busy bit. */
    vIO32WriteFldAlign(PDWNC_IRCLR, 0x1, FLD_IRCLR);
    //david: Notify VideoSlt to change string parser mode from mt53xx to mt822x
    // HAL_Delay_us(150 * 1000);
    LOG(0, "SWITCH_T8032\n");
    //  HAL_Delay_us(150 * 1000);

    // Enter Power Down mode by T8032 if uP is enabled.
    if( (DRVCUST_InitGetUptr(eT8032uPOffset) == 0)  || !_PDWNC_SetT8032(PDWNC_T8032_SET_STANDBY))
    {

		#if defined(CC_SUPPORT_STR_CORE_OFF)
		if(PDWNC_IsSuspend())
		{
			//PDWNC_SetSuspendMode(FALSE);
			BIM_WRITE32(REG_IRQEN, 0x8800);
			return;
		}
		#endif

        LOG(0, "Error!! ARM enter standby state by itself!!\n");
        // Enter Power Down mode by ARM if uP is disabled.
        vIO32WriteFldAlign(PDWNC_PDCODE, PWRDWN_CODE1, FLD_PDCODE);
        vIO32WriteFldAlign(PDWNC_PDCODE, PWRDWN_CODE2, FLD_PDCODE);
    }
    PDWNC_Reboot();
    while (1) { }

}

