blob: 81d6e746fa5696bc83252a2b34792d8714f94548 [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 "lgpl_printf.h"
#include "io.h"
#include "global.h"
#include "util.h"
#include "Galois_memmap.h"
#include "avio_memmap.h"
#include "hdmiRxPipe.h"
#include "hdrx.h"
#include "avioGbl.h"
#include "pcie.h"
#include "apbRegBase.h"
#include "SysMgr.h"
#include "sm_memmap.h"
#include "power_tuning.h"
#include "board_config.h"
#include "pcie.h"
#include "power_ctrl.h"
#define SET_BIT_FIELD(u32_type, u32_var, bitfield, value) \
do { \
volatile u32_type temp_341asd; \
BFM_HOST_Bus_Read32(&(u32_var), &temp_341asd.u32); \
temp_341asd.bitfield = value; \
BFM_HOST_Bus_Write32(&(u32_var), temp_341asd.u32); \
} while(0)
int power_ctrl_emmc(enum POWER_ACT act, enum POWER_SEL sel)
{
SIE_Gbl* ptGlobal = (SIE_Gbl*)MEMMAP_CHIP_CTRL_REG_BASE;
//unsigned int addr,val;
if (act == POWER_ON) {
if (sel & POWER_SEL_CLOCK) {
SET_BIT_FIELD(T32Gbl_clkEnable, ptGlobal->u32Gbl_clkEnable, uclkEnable_emmcSysClkEn, 1);
SET_BIT_FIELD(T32clkD4_ctrl, ptGlobal->ie_emmcClk.u32clkD4_ctrl, uctrl_ClkEn, 1);
}
if (sel & POWER_SEL_PHY) {
}
if (sel & POWER_SEL_SRAM) {
}
} else if (act == POWER_OFF) {
if (sel & POWER_SEL_SRAM) {
}
if (sel & POWER_SEL_PHY) {
}
if (sel & POWER_SEL_CLOCK) {
SET_BIT_FIELD(T32Gbl_clkEnable, ptGlobal->u32Gbl_clkEnable, uclkEnable_emmcSysClkEn, 0);
SET_BIT_FIELD(T32clkD4_ctrl, ptGlobal->ie_emmcClk.u32clkD4_ctrl, uctrl_ClkEn, 0);
}
} else {
lgpl_printf("%s, invalid power control option:%d\n", __func__, act);
return -1;
}
return 0;
}
int powerdown_emmc(int powerdown)
{
if(powerdown) {
power_ctrl_emmc(POWER_OFF, POWER_SEL_ALL);
} else {
power_ctrl_emmc(POWER_ON, POWER_SEL_ALL);
}
return 0;
}
int powerdown_spi(int powerdown, int id)
{
unsigned int temp;
if (powerdown)
{
if (id == 0)
{
// disable
BFM_HOST_Bus_Read32(APB_SSI1_BASE+0x08, &temp);
_BFSET_(temp, 0, 0, 0);
BFM_HOST_Bus_Write32(APB_SSI1_BASE+0x08, temp);
}
}
else
{
if (id == 0)
{
// enable
BFM_HOST_Bus_Read32(APB_SSI1_BASE+0x08, &temp);
_BFSET_(temp, 0, 0, 1);
BFM_HOST_Bus_Write32(APB_SSI1_BASE+0x08, temp);
}
}
return 0;
}
int power_ctrl_nna(enum POWER_ACT act, enum POWER_SEL sel)
{
SIE_Gbl* ptGlobal = (SIE_Gbl*)MEMMAP_CHIP_CTRL_REG_BASE;
unsigned int data;
if (act == POWER_ON) {
if (sel & POWER_SEL_CLOCK) {
SET_BIT_FIELD(T32clkD2_ctrl, ptGlobal->ie_nnaSysClk.u32clkD2_ctrl, uctrl_ClkEn, 1);
SET_BIT_FIELD(T32clkD2_ctrl, ptGlobal->ie_nnaCoreClk.u32clkD2_ctrl, uctrl_ClkEn, 1);
}
if (sel & POWER_SEL_PHY) {
}
if (sel & POWER_SEL_SRAM) {
BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_NNA, &data);
data &= ~3;
BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_NNA, data);
}
} else if (act == POWER_OFF) {
if (sel & POWER_SEL_SRAM) {
BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_NNA, &data);
data &= ~3;
data |= 1;
BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_NNA, data);
}
if (sel & POWER_SEL_PHY) {
}
if (sel & POWER_SEL_CLOCK) {
SET_BIT_FIELD(T32clkD2_ctrl, ptGlobal->ie_nnaSysClk.u32clkD2_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD2_ctrl, ptGlobal->ie_nnaCoreClk.u32clkD2_ctrl, uctrl_ClkEn, 0);
}
} else {
lgpl_printf("%s, invalid power control option:%d\n", __func__, act);
return -1;
}
return 0;
}
int powerdown_nna(int powerdown)
{
if(powerdown)
return power_ctrl_nna(POWER_OFF, POWER_SEL_ALL);
else
return power_ctrl_nna(POWER_ON, POWER_SEL_ALL);
}
void power_on_pcie_phy(unsigned int mac_base, unsigned int phy_base)
{
unsigned int data;
BFM_HOST_Bus_Read32(mac_base + RA_PCIE_REFCLK, &data);
data &= ~MSK32REFCLK_CTRL_PD;
BFM_HOST_Bus_Write32(mac_base + RA_PCIE_REFCLK, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 8, &data);
data &= ~(1 << 0);
data &= ~(1 << 4);
data |= (1 << 12);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 8, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 0x18, &data);
data |= (1 << 8);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 0x18, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 0x1c, &data);
data &= ~(1 << 8);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 0x1c, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 0x28, &data);
data &= ~(1 << 0);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 0x28, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 0x2c, &data);
data &= ~(1 << 5);
data &= ~(1 << 8);
data &= ~(1 << 12);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 0x2c, data);
BFM_HOST_Bus_Read32(phy_base + 0x10000 + 0x0, &data);
data |= (1 << 0);
data &= ~(1 << 3);
data &= ~(1 << 4);
BFM_HOST_Bus_Write32(phy_base + 0x10000 + 0x0, data);
BFM_HOST_Bus_Read32(phy_base + 0x10000 + 0x4, &data);
data &= ~(1 << 15);
BFM_HOST_Bus_Write32(phy_base + 0x10000 + 0x4, data);
BFM_HOST_Bus_Read32(phy_base + 0x10000 + 0x24, &data);
data &= ~(1 << 0);
BFM_HOST_Bus_Write32(phy_base + 0x10000 + 0x24, data);
}
static void power_off_pcie_phy(unsigned int mac_base, unsigned int phy_base)
{
unsigned int data;
BFM_HOST_Bus_Read32(mac_base + RA_PCIE_REFCLK, &data);
data |= MSK32REFCLK_CTRL_PD;
BFM_HOST_Bus_Write32(mac_base + RA_PCIE_REFCLK, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 8, &data);
data |= (1 << 0);
data |= (1 << 4);
data &= ~(1 << 12);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 8, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 0x18, &data);
data &= ~(1 << 8);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 0x18, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 0x1c, &data);
data |= (1 << 8);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 0x1c, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 0x28, &data);
data |= (1 << 0);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 0x28, data);
BFM_HOST_Bus_Read32(phy_base + 0x10800 + 0x2c, &data);
data |= (1 << 5);
data |= (1 << 8);
data |= (1 << 12);
BFM_HOST_Bus_Write32(phy_base + 0x10800 + 0x2c, data);
BFM_HOST_Bus_Read32(phy_base + 0x10000 + 0x0, &data);
data &= ~(1 << 0);
data |= (1 << 3);
data |= (1 << 4);
BFM_HOST_Bus_Write32(phy_base + 0x10000 + 0x0, data);
BFM_HOST_Bus_Read32(phy_base + 0x10000 + 0x4, &data);
data |= (1 << 15);
BFM_HOST_Bus_Write32(phy_base + 0x10000 + 0x4, data);
BFM_HOST_Bus_Read32(phy_base + 0x10000 + 0x24, &data);
data |= (1 << 0);
BFM_HOST_Bus_Write32(phy_base + 0x10000 + 0x24, data);
}
int power_ctrl_pcie0(enum POWER_ACT act, enum POWER_SEL sel)
{
SIE_Gbl* ptGlobal = (SIE_Gbl*)MEMMAP_CHIP_CTRL_REG_BASE;
unsigned int data;
unsigned int mac_base = MEMMAP_PCIE_REG_BASE;
unsigned int phy_base = MEMMAP_PCIE_PHY_REG_BASE;
BFM_HOST_Bus_Read32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN), &data);
data |= MSK32Gbl_perifStickyResetN_pcie0Rstn;
BFM_HOST_Bus_Write32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN), data);
if (act == POWER_ON) {
if (sel & POWER_SEL_CLOCK) {
// clock enable
SET_BIT_FIELD(T32Gbl_clkEnable, ptGlobal->u32Gbl_clkEnable, uclkEnable_pcie0SysClkEn, 1);
}
if (sel & POWER_SEL_PHY) {
power_on_pcie_phy(mac_base, phy_base);
}
if (sel & POWER_SEL_SRAM) {
BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_PCIE0, &data);
data &= ~3;
BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_PCIE0, data);
}
} else if (act == POWER_OFF) {
if (sel & POWER_SEL_SRAM) {
BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_PCIE0, &data);
data &= ~3;
data |= 1;
BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_PCIE0, data);
}
if (sel & POWER_SEL_PHY) {
power_off_pcie_phy(mac_base, phy_base);
}
if (sel & POWER_SEL_CLOCK) {
SET_BIT_FIELD(T32Gbl_clkEnable, ptGlobal->u32Gbl_clkEnable, uclkEnable_pcie0SysClkEn, 0);
SET_BIT_FIELD(T32clkD4_ctrl, ptGlobal->ie_pcie_500M_TxTestClk.u32clkD4_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD4_ctrl, ptGlobal->ie_pcie_500M_RxTestClk.u32clkD4_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD8_ctrl, ptGlobal->ie_pcie_250M_pipeTestClk1.u32clkD8_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD8_ctrl, ptGlobal->ie_pcie_250M_pipeTestClk2.u32clkD8_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD8_ctrl, ptGlobal->ie_pcie_serdesTestClk.u32clkD8_ctrl, uctrl_ClkEn, 0);
}
} else {
lgpl_printf("%s, invalid power control option:%d\n", __func__, act);
return -1;
}
return 0;
}
int power_ctrl_pcie1(enum POWER_ACT act, enum POWER_SEL sel)
{
SIE_Gbl* ptGlobal = (SIE_Gbl*)MEMMAP_CHIP_CTRL_REG_BASE;
unsigned int data;
unsigned int mac_base = MEMMAP_PCIE1_REG_BASE;
unsigned int phy_base = MEMMAP_PCIE1_PHY_REG_BASE;
BFM_HOST_Bus_Read32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN), &data);
data |= MSK32Gbl_perifStickyResetN_pcie1Rstn;
BFM_HOST_Bus_Write32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_perifStickyResetN), data);
if (act == POWER_ON) {
if (sel & POWER_SEL_CLOCK) {
// clock enable
SET_BIT_FIELD(T32Gbl_clkEnable, ptGlobal->u32Gbl_clkEnable, uclkEnable_pcie1SysClkEn, 1);
}
if (sel & POWER_SEL_PHY) {
power_on_pcie_phy(mac_base, phy_base);
}
if (sel & POWER_SEL_SRAM) {
BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_PCIE1, &data);
data &= ~3;
BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_PCIE1, data);
}
} else if (act == POWER_OFF) {
if (sel & POWER_SEL_SRAM) {
BFM_HOST_Bus_Read32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_PCIE1, &data);
data &= ~3;
data |= 1;
BFM_HOST_Bus_Write32(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_SRAM_PWR_CTRL_PCIE1, data);
}
if (sel & POWER_SEL_PHY) {
power_off_pcie_phy(mac_base, phy_base);
}
if (sel & POWER_SEL_CLOCK) {
SET_BIT_FIELD(T32Gbl_clkEnable, ptGlobal->u32Gbl_clkEnable, uclkEnable_pcie1SysClkEn, 0);
SET_BIT_FIELD(T32clkD4_ctrl, ptGlobal->ie_pcie_500M_TxTestClk.u32clkD4_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD4_ctrl, ptGlobal->ie_pcie_500M_RxTestClk.u32clkD4_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD8_ctrl, ptGlobal->ie_pcie_250M_pipeTestClk1.u32clkD8_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD8_ctrl, ptGlobal->ie_pcie_250M_pipeTestClk2.u32clkD8_ctrl, uctrl_ClkEn, 0);
SET_BIT_FIELD(T32clkD8_ctrl, ptGlobal->ie_pcie_serdesTestClk.u32clkD8_ctrl, uctrl_ClkEn, 0);
}
} else {
lgpl_printf("%s, invalid power control option:%d\n", __func__, act);
return -1;
}
return 0;
}
int powerdown_pcie(int powerdown)
{
if(powerdown) {
power_ctrl_pcie0(POWER_OFF, POWER_SEL_ALL);
power_ctrl_pcie1(POWER_OFF, POWER_SEL_ALL);
} else {
power_ctrl_pcie0(POWER_ON, POWER_SEL_ALL);
power_ctrl_pcie1(POWER_ON, POWER_SEL_ALL);
}
return 0;
}
int power_ctrl_sdio(enum POWER_ACT act, enum POWER_SEL sel)
{
SIE_Gbl* ptGlobal = (SIE_Gbl*)MEMMAP_CHIP_CTRL_REG_BASE;
//unsigned int addr,val;
if (act == POWER_ON) {
if (sel & POWER_SEL_CLOCK) {
SET_BIT_FIELD(T32Gbl_clkEnable, ptGlobal->u32Gbl_clkEnable, uclkEnable_sdioSysClkEn, 1);
SET_BIT_FIELD(T32clkD4_ctrl, ptGlobal->ie_sd0Clk.u32clkD4_ctrl, uctrl_ClkEn, 1);
}
if (sel & POWER_SEL_PHY) {
}
if (sel & POWER_SEL_SRAM) {
}
} else if (act == POWER_OFF) {
if (sel & POWER_SEL_SRAM) {
}
if (sel & POWER_SEL_PHY) {
}
if (sel & POWER_SEL_CLOCK) {
SET_BIT_FIELD(T32Gbl_clkEnable, ptGlobal->u32Gbl_clkEnable, uclkEnable_sdioSysClkEn, 0);
SET_BIT_FIELD(T32clkD4_ctrl, ptGlobal->ie_sd0Clk.u32clkD4_ctrl, uctrl_ClkEn, 0);
}
} else {
lgpl_printf("%s, invalid power control option:%d\n", __func__, act);
return -1;
}
return 0;
}
int powerdown_sdio(int powerdown)
{
if(powerdown) {
power_ctrl_sdio(POWER_OFF, POWER_SEL_ALL);
} else {
power_ctrl_sdio(POWER_ON, POWER_SEL_ALL);
}
return 0;
}