blob: db940bc13af5f2769a03ef3c633caefc90541c1a [file] [log] [blame]
/******************************************************************************
*
* (C)Copyright 2022 ASR. All Rights Reserved.
*
******************************************************************************/
#include "PlatformConfig.h"
#include "platform_interrupts.h"
#include "predefines.h"
#include "USB_controller.h"
#include "USB_PHY.h"
#include "PMUA.h"
#include "Flash.h"
#include "timer.h"
#include "uart_regs.h"
#include "geu_interface.h"
#include "APBC.h"
#include "obm2osl.h"
#include "misc.h"
#include "sdhc2.h"
#include "Provisioning.h"
#include "Typedef.h"
#include "serial.h"
#include "downloader.h"
#include "BootLoader.h"
#include "sdram_config.h"
#include "I2C.h"
#include "CIU.h"
#include "spi.h"
#include "tinyalloc.h"
#include "PlatformCommon.h"
static UINT8_T rdp_buf_idx = 0;
/*
* Table definitions for multi function pin registers
*/
#if UPDATE_USE_GPIO
CS_REGISTER_PAIR_S gpio_key_pins[] =
{
(int *) (APPS_PAD_BASE | 0x02f0), 0xB081, 0x0, //GPIO55 -> Key_uAP
(int *) (APPS_PAD_BASE | 0x02f4), 0xB081, 0x0, //GPIO56 -> Key_TD
(int *) (APPS_PAD_BASE | 0x0300), 0xB081, 0x0, //GPIO59 -> Key_WiFi
0x0,0x0,0x0 // termination
};
#endif
#if MMC_CODE
// MMC2 controller compatible pinout
CS_REGISTER_PAIR_S mmc2_pins[]=
{
(INT *) (APPS_PAD_BASE | 0x02FC), 0x1040, 0x0, //MMC2_CMD
(INT *) (APPS_PAD_BASE | 0x0300), 0x1040, 0x0, //MMC2_CLK
(INT *) (APPS_PAD_BASE | 0x02F8), 0x1040, 0x0, //MMC2_DAT0
(INT *) (APPS_PAD_BASE | 0x02F4), 0x1040, 0x0, //MMC2_DAT1
(INT *) (APPS_PAD_BASE | 0x02F0), 0x1040, 0x0, //MMC2_DAT2
(INT *) (APPS_PAD_BASE | 0x02EC), 0x1040, 0x0, //MMC2_DAT3
(INT *) (APPS_PAD_BASE | 0x02D0), 0xd042, 0x0, //MMC2_DAT4
(INT *) (APPS_PAD_BASE | 0x02CC), 0xd042, 0x0, //MMC2_DAT5
(INT *) (APPS_PAD_BASE | 0x02C8), 0xd042, 0x0, //MMC2_DAT6
(INT *) (APPS_PAD_BASE | 0x02C4), 0xd042, 0x0, //MMC2_DAT7
0x0,0x0,0x0 //termination
};
#endif
CS_REGISTER_PAIR_S uart_pins[]=
{
#if CPUART
(int *) (APPS_PAD_BASE | 0x01A8), 0x5081, 0x0, //TX
(int *) (APPS_PAD_BASE | 0x01AC), 0x5081, 0x0, //RX
#else
(int *) (APPS_PAD_BASE | 0x0150), 0x5081, 0x0, //TX
(int *) (APPS_PAD_BASE | 0x0154), 0x5081, 0x0, //RX
#endif
0x0,0x0,0x0 //termination
};
#if SPINOR_CODE
CS_REGISTER_PAIR_S spi_nor_pins[]=
{
(int *) (APPS_PAD_BASE | 0x2C4), 0x1081, 0x0, //nHold
(int *) (APPS_PAD_BASE | 0x2C8), 0x1081, 0x0, //nWP
(int *) (APPS_PAD_BASE | 0x2CC), 0x1082, 0x0, //RX
(int *) (APPS_PAD_BASE | 0x2D0), 0x1082, 0x0, //TX
(int *) (APPS_PAD_BASE | 0x2D4), 0x1082, 0x0, //CLK
#ifdef SSP_CS_USE_GPIO
(int *) (APPS_PAD_BASE | 0x2D8), 0x1081, 0x0, //FRM (CS): GPIO_76
#else
(int *) (APPS_PAD_BASE | 0x2D8), 0x1082, 0x0, //FRM (CS)
#endif
0x0,0x0,0x0 //termination
};
CS_REGISTER_PAIR_S spi_nor_pins_falcon_z1[]=
{
/* Falcon Z1: GPIO12-15 is used for SSP2, QSPI use dedicatd pins
* TODO: Falcon A0 will use the same pins with QSPI
*/
(int *) (APPS_PAD_BASE | 0x114), 0x1087, 0x0, //RX
(int *) (APPS_PAD_BASE | 0x118), 0x1087, 0x0, //TX
(int *) (APPS_PAD_BASE | 0x10C), 0x1087, 0x0, //CLK
#ifdef SSP_CS_USE_GPIO
(int *) (APPS_PAD_BASE | 0x110), 0x1080, 0x0, //FRM (CS) GPIO_13
#else
(int *) (APPS_PAD_BASE | 0x110), 0x1087, 0x0, //FRM (CS)
#endif
0x0,0x0,0x0 //termination
};
CS_REGISTER_PAIR_S spi_nor_pins_falcon_a0[]=
{
(int *) (APPS_PAD_BASE | 0x2C4), 0x1081, 0x0, //nHold
(int *) (APPS_PAD_BASE | 0x2C8), 0x1081, 0x0, //nWP
(int *) (APPS_PAD_BASE | 0x2CC), 0x1084, 0x0, //RX
(int *) (APPS_PAD_BASE | 0x2D0), 0x1084, 0x0, //TX
(int *) (APPS_PAD_BASE | 0x2D4), 0x1084, 0x0, //CLK
#ifdef SSP_CS_USE_GPIO
(int *) (APPS_PAD_BASE | 0x2D8), 0x1081, 0x0, //FRM (CS): GPIO_76
#else
(int *) (APPS_PAD_BASE | 0x2D8), 0x1084, 0x0, //FRM (CS)
#endif
0x0,0x0,0x0 //termination
};
#endif
#if SPINAND_CODE
CS_REGISTER_PAIR_S spi_nand_pins[]=
{
(int *) (APPS_PAD_BASE | 0x2C4), 0x1081, 0x0, //nHold
(int *) (APPS_PAD_BASE | 0x2C8), 0x1081, 0x0, //nWP
(int *) (APPS_PAD_BASE | 0x2CC), 0x1082, 0x0, //RX
(int *) (APPS_PAD_BASE | 0x2D0), 0x1082, 0x0, //TX
(int *) (APPS_PAD_BASE | 0x2D4), 0x1082, 0x0, //CLK
#ifdef SSP_CS_USE_GPIO
(int *) (APPS_PAD_BASE | 0x2D8), 0x1081, 0x0, //FRM (CS): GPIO_76
#else
(int *) (APPS_PAD_BASE | 0x2D8), 0x1082, 0x0, //FRM (CS)
#endif
0x0,0x0,0x0 //termination
};
CS_REGISTER_PAIR_S spi_nand_pins_falcon_z1[]=
{
/* Falcon Z1: GPIO12-15 is used for SSP2, QSPI use dedicatd pins
* TODO: Falcon A0 will use the same pins with QSPI
*/
(int *) (APPS_PAD_BASE | 0x114), 0x1087, 0x0, //RX
(int *) (APPS_PAD_BASE | 0x118), 0x1087, 0x0, //TX
(int *) (APPS_PAD_BASE | 0x10C), 0x1087, 0x0, //CLK
#ifdef SSP_CS_USE_GPIO
(int *) (APPS_PAD_BASE | 0x110), 0x1080, 0x0, //FRM (CS) GPIO_13
#else
(int *) (APPS_PAD_BASE | 0x110), 0x1087, 0x0, //FRM (CS)
#endif
0x0,0x0,0x0 //termination
};
CS_REGISTER_PAIR_S spi_nand_pins_falcon_a0[]=
{
(int *) (APPS_PAD_BASE | 0x2C4), 0x1081, 0x0, //nHold
(int *) (APPS_PAD_BASE | 0x2C8), 0x1081, 0x0, //nWP
(int *) (APPS_PAD_BASE | 0x2CC), 0x1084, 0x0, //RX
(int *) (APPS_PAD_BASE | 0x2D0), 0x1084, 0x0, //TX
(int *) (APPS_PAD_BASE | 0x2D4), 0x1084, 0x0, //CLK
#ifdef SSP_CS_USE_GPIO
(int *) (APPS_PAD_BASE | 0x2D8), 0x1081, 0x0, //FRM (CS): GPIO_76
#else
(int *) (APPS_PAD_BASE | 0x2D8), 0x1084, 0x0, //FRM (CS)
#endif
0x0,0x0,0x0 //termination
};
#endif
const CS_REGISTER_PAIR_S pi2c_pins[]=
{
(int *) (APPS_PAD_BASE | 0x01B0), 0xd0c2, 0x0, //CI2C_SCL
(int *) (APPS_PAD_BASE | 0x01B4), 0xd0c2, 0x0, //CI2C_SDA
0x0,0x0,0x0 //termination
};
#if QSPINAND_CODE || QSPINOR_CODE
const CS_REGISTER_PAIR_S qspi_pins[]=
{
(int *) (APPS_PAD_BASE | 0x2c4), 0xd000, 0x0, //QSPI_DAT3
(int *) (APPS_PAD_BASE | 0x2c8), 0xd000, 0x0, //QSPI_DAT2
(int *) (APPS_PAD_BASE | 0x2cc), 0x1000, 0x0, //QSPI_DAT1
(int *) (APPS_PAD_BASE | 0x2d0), 0x1000, 0x0, //QSPI_DAT0
(int *) (APPS_PAD_BASE | 0x2d4), 0x1000, 0x0, //QSPI_CLK
(int *) (APPS_PAD_BASE | 0x2d8), 0x1000, 0x0, //QSPI_CS1
0x0,0x0,0x0 //termination
};
#endif
#if SPINOR_CODE
void ChipSelectSPINOR( void )
{
obm_printf("ManuCS 26MHz\n\r");
reg_write(APBC_SSP2_CLK_RST, BIT0 | BIT1 | BIT2);
reg_write(APBC_SSP2_CLK_RST, BIT0 | BIT1 | (2 << 4)); // 26MHZ
if(PlatformIsNezhac()){
ConfigRegWrite(spi_nor_pins);
//GPIO 71/72 output high
reg_bit_set((GPIO2_BASE + GPIO_SDR), 0x180);
reg_bit_set((GPIO2_BASE + GPIO_PSR), 0x180);
//GPIO 76 output high
reg_bit_set((GPIO2_BASE + GPIO_SDR), (1 << 12)); // high
reg_bit_set((GPIO2_BASE + GPIO_PSR), (1 << 12)); // output
} else if (PlatformIsFalconA0() || PlatformIsFalconT()) {
obm_printf("Falcon A0 spi pinmux for NOR\n\r");
ConfigRegWrite(spi_nor_pins_falcon_a0);
//GPIO 71/72 output high
reg_bit_set((GPIO2_BASE + GPIO_SDR), 0x180);
reg_bit_set((GPIO2_BASE + GPIO_PSR), 0x180);
//GPIO 76 output high
reg_bit_set((GPIO2_BASE + GPIO_SDR), (1 << 12)); // high
reg_bit_set((GPIO2_BASE + GPIO_PSR), (1 << 12)); // output
}else{
ConfigRegWrite(spi_nor_pins_falcon_z1);
}
return;
}
#endif
#if SPINAND_CODE
void ChipSelectSPINAND( void )
{
//enabled SSP2 clock, then take out of reset
obm_printf("ManuCS 26MHz\n\r");
reg_write(APBC_SSP2_CLK_RST, BIT0 | BIT1 | BIT2);
reg_write(APBC_SSP2_CLK_RST, BIT0 | BIT1 | (2 << 4)); // 26MHZ
if(PlatformIsNezhac()){
ConfigRegWrite(spi_nand_pins);
//GPIO 71/72 output high
reg_bit_set((GPIO2_BASE + GPIO_SDR), 0x180);
reg_bit_set((GPIO2_BASE + GPIO_PSR), 0x180);
//GPIO 76 output high
reg_bit_set((GPIO2_BASE + GPIO_SDR), (1 << 12)); // high
reg_bit_set((GPIO2_BASE + GPIO_PSR), (1 << 12)); // output
} else if (PlatformIsFalconA0() || PlatformIsFalconT()) {
obm_printf("Falcon A0 spi pinmux\n\r");
ConfigRegWrite(spi_nand_pins_falcon_a0);
//GPIO 71/72 output high
reg_bit_set((GPIO2_BASE + GPIO_SDR), 0x180);
reg_bit_set((GPIO2_BASE + GPIO_PSR), 0x180);
//GPIO 76 output high
reg_bit_set((GPIO2_BASE + GPIO_SDR), (1 << 12)); // high
reg_bit_set((GPIO2_BASE + GPIO_PSR), (1 << 12)); // output
}else{
ConfigRegWrite(spi_nand_pins_falcon_z1);
}
return;
}
#endif
#if QSPINAND_CODE || QSPINOR_CODE
void ChipSelectQSPI( void )
{
ConfigRegWrite(qspi_pins);
return;
}
#endif
UINT_T getPlatformPortSelection(unsigned int *default_usb_port)
{
UINT_T port;
*default_usb_port = CI2_USB_D;
port = 7; // send default configuration USB only
return port;
}
#if UPDATE_USE_GPIO
UINT_T PlatformGPIOKeyConfig(void)
{
UINT_T Temp;
ConfigRegWrite(gpio_key_pins);
*(VUINT_T *)(GPIO1_BASE + GPIO_CDR) |= BIT23 | BIT24 | BIT27; // GPIO 55, 56, 59
Delay(1000);
Temp = *(VUINT_T *)(GPIO1_BASE + GPIO_CDR);
Temp = *(VUINT_T *)(GPIO1_BASE + GPIO_PLR);
return (NoError);
}
UINT_T PlatformCheckGPIOKey(void)
{
UINT_T RegisterValue, i;
UINT_T key_detected = 0;
RegisterValue = *(VUINT_T *)(GPIO1_BASE + GPIO_PLR);
if (((RegisterValue >> 23) & 1) == 1) // GPIO55/Key_uAP
key_detected = KEYID_PRODUCT_USB_MODE_REQUEST;
return key_detected;
}
#endif
UINT_T PlatformUARTConfig(void)
{
UINT_T temp;
ConfigRegWrite(uart_pins);
#if LAPW
*(VUINT_T *)APBC_UART3_CLK_RST = (BIT4 | BIT1 | BIT0);
temp = *(VUINT_T *)APBC_UART3_CLK_RST;
#else
#if CPUART
*(VUINT_T *)APBC_UART1_CLK_RST = (BIT4 | BIT1 | BIT0);
temp = *(VUINT_T *)APBC_UART1_CLK_RST;
#else
*(VUINT_T *)APBC_UART0_CLK_RST = (BIT4 | BIT1 | BIT0);
temp = *(VUINT_T *)APBC_UART0_CLK_RST;
#endif
#endif
return (NoError);
}
/*
* Set NAND and UART clocks in the PMUM Clock Gating Register
*/
void CheckDefaultClocks(void)
{
volatile UINT_T Temp; //-JML- declared volatile since it's not used and to resolve compiler warning #550
*(VUINT_T *)PMUM_ACGR = 0xFFFFFFFF;
*(VUINT_T *)PMUM_CCGR = 0xFFFFFFFF;
// AIB unit must be out of reset for MFPR set up
*(VUINT_T *)APBC_AIB_CLK_RST = 0x7;
Temp = *(VUINT_T *)APBC_AIB_CLK_RST;
*(VUINT_T *)APBC_AIB_CLK_RST = 0x3;
Temp = *(VUINT_T *)APBC_AIB_CLK_RST;
// Get the GPIO unit out of reset, too.
*(VUINT_T *)APBC_GPIO_CLK_RST = 0x7;
Temp = *(VUINT_T *)APBC_GPIO_CLK_RST;
*(VUINT_T *)APBC_GPIO_CLK_RST = 0x3;
Temp = *(VUINT_T *)APBC_GPIO_CLK_RST;
return;
}
#if MMC_CODE
// MMC
CONTROLLER_TYPE ConfigureMMC(UINT8_T FlashNum, UINT_T *pBaseAddress, UINT_T *pInterruptMask, UINT_T *pFusePartitionNumber)
{
UINT_T sdh_clk;
// Tavor TD only supports MMC3 boot
ConfigRegSave(mmc2_pins);
ConfigRegWrite(mmc2_pins);
*pBaseAddress = SDHC0_2_BASE;
*pInterruptMask = INT_MMC;
//Enable PMUA clock for this interface
// Notes:
// Documentation should state that:
// PMUA_SDH0_CLK_RES_CTRL -> offset 0x054
// PMUA_SDH1_CLK_RES_CTRL -> offset 0x058
// PMUA_SDH2_CLK_RES_CTRL -> offset 0x0E0
//
// However, out header file PMUA.H states:
// PMUA_SDH0_CLK_RES_CTRL -> offset 0x054
// PMUA_SDH1_CLK_RES_CTRL -> offset 0x0E0
#if BASE_CLOCK_208MHZ
sdh_clk = SDH_CLK_FC_REQ | SDH_CLK_SEL_416MHZ | SDH_CLK_DIV(1); // 208MHZ
#else
sdh_clk = SDH_CLK_FC_REQ | SDH_CLK_SEL_416MHZ | SDH_CLK_DIV(3); // 104MHZ
#endif
reg_write(PMUA_SDH0_CLK_RES_CTRL, sdh_clk | APMU_PERIPH_CLK_EN | APMU_AXI_CLK_EN | APMU_PERIPH_RESET | APMU_AXI_RESET);
reg_write(PMUA_SDH1_CLK_RES_CTRL, sdh_clk | APMU_PERIPH_CLK_EN | APMU_AXI_CLK_EN | APMU_PERIPH_RESET | APMU_AXI_RESET);
while ((*(VUINT_T *) PMUA_SDH0_CLK_RES_CTRL) & SDH_CLK_FC_REQ);
while ((*(VUINT_T *) PMUA_SDH1_CLK_RES_CTRL) & SDH_CLK_FC_REQ);
// Now pick the partition we are supposed to boot from.
*pFusePartitionNumber = MMC_SD_USER_PARTITION;
return MMCSDHC1_1; // MMC2
}
void DisableMMCSlots()
{
DisablePeripheralIRQInterrupt(INT_MMC);
// Disable PMUA clocks for the SD controllers
*(UINT_T *) PMUA_SDH1_CLK_RES_CTRL = 0x0; //Disable PMUA clock for this interface
// Restores the MMC GPIO's back to their default values
ConfigRegRestore(mmc2_pins);
}
UINT_T MMCHighSpeedTimingEnabled()
{
return 1;
}
#endif
void Platform_PortEnable(pFUSE_SET pFuses)
{
pTIM pTIM_h = GetTimPointer();
SetUpUSBDescriptors (pTIM_h, 1);
InitPort(30);
return;
}
void Platform_USB2_Shutdown()
{
// Power down PHY and PLL
// only turn off only those that BR
// had to turn on
//------------------------------------
//*ACCR1 &= (~ci2ACCR1TurnOns); //DCB TTC-bringup
// Use D0CKEN_C reg to turn off 26Mhz
// clock, for PHY PLL input
// only turn-off only those that BR
// had to turn on
//------------------------------------
//*D0CKEN_C &= (~ci2D0TurnOns); //DCB TTC-bringup
//*OSCC &= ~0x800; // turn off CLK_POUT
#if KAGU
BU_REG_WRITE((PMUA_BASE+0x170), 0x00000); //turn off USB AXI clock
#else
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL = 0x0; //turn off USB AXI clock
#endif
}
//----------------------------------------------
// OTG PHY setup TTD2
//
//----------------------------------------------
void Platform_KAGU_USB2_ON_USB2_PHY_Init(void)
{
UINT32 usb_reset_timeout = 3000;
UINT32 pll_wait_us = 400;
UINT32 val;
//wait for 200 us
BU_REG_WRITE((PMUA_BASE+0x170), 0x00000);
//need to wait 10us
Delay(10);
BU_REG_WRITE((PMUA_BASE+0x170), 0x1E000);
Delay(5);
//USB PHY config
//step.1
//config phphy, sw init done, ref clk cfg=2
//open allclk en bits
BU_REG_WRITE(PUPHY0_REG02, 0x97C);
//step.2 wait for PUPHY PLL READY
while((BU_REG_READ(PUPHY0_REG02) & 0x1) != 0x1)
{
Delay(1);
pll_wait_us--;
if (pll_wait_us == 0)
break;
}
//step.3 override pipe_phystatus to 0 if puphy pll not ready
if (pll_wait_us == 0)
BU_REG_WRITE(PUPHY0_REG10, (BU_REG_READ(PUPHY0_REG10) | (0x1 << 10)));
//step.4 wait for USB2 PHY PLL READY
pll_wait_us = 400;
while (((BU_REG_READ(USB2_PHY0_REG01) & USB2_PLL_BIT_RDY) != USB2_PLL_BIT_RDY)
&& (pll_wait_us--))
{
Delay(1);
}
BU_REG_WRITE(USB2_PHY0_REG29, BU_REG_READ(USB2_PHY0_REG29) & (~BIT14));
//Step 5&6
//Release usb2 phy internal reset and enable clock gating
BU_REG_WRITE(USB2_PHY0_REG01, 0x60ef);
BU_REG_WRITE(USB2_PHY0_REG0D, 0x1C);
//STEP.7
/*0x1: serial mode, 0x0: parallel mode
* USB2_PHY0_REG06 (USB2_BASE+0x18)
*/
/* set to serial mode for stability */
BU_REG_WRITE(USB2_PHY0_REG06, BU_REG_READ(USB2_PHY0_REG06) | (BIT0));
/* TX DAC increase 10% */
BU_REG_WRITE(USB2_PHY0_REG29,
(BU_REG_READ(USB2_PHY0_REG29) & (~0x1F)) | (BIT4 | 0xB));
}
void Platform_LPWG_USB2_ON_USB2_PHY_Init(void)
{
UINT32 pll_wait_us = 200;
/* reset usb phy/controller to default state */
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL = 0;
//wait for 50 us
Delay(50);
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL |= PMUA_USB_CLK_RES_CTRL_USB_AXICLK_EN;
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL |= PMUA_USB_CLK_RES_CTRL_USB_SPH_AXI_RST;
/* Release usb controller and axi */
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL |= (PMUA_USB_CLK_RES_CTRL_USB_AXI_RST | PMUA_USB_CTRL_RLS_RST);
//step.1 wait for USB2 PHY PLL READY
pll_wait_us = 400;
while (((BU_REG_READ(USB2_PHY0_REG01) & USB2_PLL_BIT_RDY) != USB2_PLL_BIT_RDY)
&& (pll_wait_us--))
{
Delay(1);
}
//Step 2&3
//Release usb2 phy internal reset and enable clock gating
BU_REG_WRITE(USB2_PHY0_REG01, 0x60ef);
BU_REG_WRITE(USB2_PHY0_REG0D, 0x1C);
//STEP.4
/*0x1: serial mode, 0x0: parallel mode
* USB2_PHY0_REG06 (USB2_BASE+0x18)
*/
/* set to serial mode for stability */
BU_REG_WRITE(USB2_PHY0_REG06, BU_REG_READ(USB2_PHY0_REG06) | (BIT0));
}
void Platform_USB2_ON_USB2_PHY_Init(void)
{
UINT32 usb_reset_timeout = 3000;
UINT32 pll_wait_us = 200;
volatile int j = 0, k = 0;
#if KAGU
Platform_KAGU_USB2_ON_USB2_PHY_Init();
return;
#elif LAPW
Platform_LPWG_USB2_ON_USB2_PHY_Init();
return;
#else
/* reset usb phy/controller to default state */
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL = PMUA_USB_CLK_RES_CTRL_USB_SPH_AXI_RST;
//wait for 50 us
Delay(50);
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL |= PMUA_USB_CLK_RES_CTRL_USB_AXICLK_EN;
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL |= PMUA_USB_CLK_RES_CTRL_USB_AXI_RST;
//wait for 50 us
Delay(50);
//WAIT FOR PHY PLL RDY
while (((BU_REG_READ(USB2_PHY_REG01) & USB2_PLL_BIT_RDY) != USB2_PLL_BIT_RDY)
&& (pll_wait_us--))
{
Delay(1);
}
#if NZAC
//Workaround for usb fs phy issue
BU_REG_WRITE(USB2_PHY_REG28, BU_REG_READ(USB2_PHY_REG28) & (~BIT14));
BU_REG_WRITE(USB_CMD, BU_REG_READ(USB_CMD) & (~BIT0));
BU_REG_WRITE(USB2_PHY_REG08, BU_REG_READ(USB2_PHY_REG08) & (~BIT6));
BU_REG_WRITE(USB2_PHY_REG0A, BU_REG_READ(USB2_PHY_REG0A) | (BIT4));
/* Make some delay */
Delay(40);
BU_REG_WRITE(USB2_PHY_REG0A, BU_REG_READ(USB2_PHY_REG0A) & (~BIT4));
#endif
#if FLCN || FACT
BU_REG_WRITE(USB2_PHY_REG29, BU_REG_READ(USB2_PHY_REG29) & (~BIT14));
/* set to serial mode for stability */
BU_REG_WRITE(USB2_PHY_REG06, BU_REG_READ(USB2_PHY_REG06) | (BIT0));
/* TX DAC increase 10%, will add back for some speciall cases */
/* BU_REG_WRITE(USB2_PHY_REG29,
(BU_REG_READ(USB2_PHY_REG29) & (~0x1F)) | (BIT4 | 0xB)); */
#endif
//Release usb2 phy internal reset and enable clock gating
BU_REG_WRITE(USB2_PHY_REG01, 0x60ef);
BU_REG_WRITE(USB2_PHY_REG0D, 0x1C);
//enable parallel mode, default is serial mode
//BU_REG_WRITE(USB2_PHY_REG06, BU_REG_READ(USB2_PHY_REG06) & ~(USB2_CFG_HS_SRCS_SEL));
/* Release usb controller */
#if FACT
*(VUINT_T *)PMUA_USB_CLK_RES_CTRL |= PMUA_USB_CTRL_RLS_RST;
#endif
#endif
}
VOID DisplaySecurityInfo(VOID)
{
UINT_T AP_Config[3];
UINT_T op_mode;
GEU_ReadApConfigFuseBits(AP_Config, 10);
op_mode = ((AP_Config[2] & 0xC00) >> 10);
obm_printf("BootROM OP Mode: %d\n\r", op_mode);
if(op_mode == 2)
obm_printf("Trusted Boot enabled\n\r");
else
obm_printf("Trusted Boot not enabled\n\r");
#if ATRB_ENABLE
if(GEU_MajorAntiRollBackEnabled()){
obm_printf("Anti-rollback fuse enabled\n\r")
obm_printf("ATRB Major Version: 0x%x\n\r", GEU_ReadMajorVersion());
}
#endif
}
void ShutdownPort(void)
{
DisablePeripheralIRQInterrupt(USB0_OTG_INT);
Platform_USB2_Shutdown();
}
#if 0
INT_T PlatformIsNezhac(void)
{
UINT ChipID_value = PlatformGetChipID();
return (ChipID_value == 0x1802);
}
INT_T PlatformIsFalcon(void)
{
UINT ChipID_value = PlatformGetChipID();
return (ChipID_value == 0x1803);
}
INT_T PlatformIsFalconT(void)
{
UINT ChipID_value = PlatformGetChipID();
return (ChipID_value == 0x1806);
}
INT_T PlatformIsFalconA0(void)
{
UINT ChipID_value = PlatformGetChipID();
UINT StepID_value = PlatformGetRevisionID();
return (ChipID_value == 0x1803 && StepID_value == 0xA0);
}
INT_T PlatformIsKagu(void)
{
UINT ChipID_value = PlatformGetChipID();
return (ChipID_value == 0x1829);
}
INT_T PlatformIsLapwing(void)
{
UINT ChipID_value = PlatformGetChipID();
return (ChipID_value == 0x1903);
}
#endif
#if LAPW
INT_T PlatformIsLapwA0(void)
{
UINT ChipID_value = PlatformGetChipID();
UINT StepID = PlatformGetRevisionID();
return ((ChipID_value == 0x1903) && (StepID == 0xA0));
}
INT_T PlatformIsLapwB0(void)
{
UINT ChipID_value = PlatformGetChipID();
UINT StepID = PlatformGetRevisionID();
return ((ChipID_value == 0x1903) && (StepID == 0xB0));
}
INT_T PlatformIsLapwZ1(void)
{
UINT ChipID_value = PlatformGetChipID();
UINT StepID = PlatformGetRevisionID();
return ((ChipID_value == 0x1903) && (StepID == 0xF0));
}
#endif
UINT_T PlatformPI2CConfig(void)
{
// Get the TWSI unit out of reset, too.
reg_write(APBCP_ICER, 0x0);
reg_write(APBCP_ICER, 0x7);
reg_write(APBCP_ICER, 0x3);
return NoError;
}
UINT_T PlatformPI2CConfig2(void)
{
// Get the TWSI unit out of reset, too.
reg_write(APBC_TWSI1_CLK_RST, 0x7);
reg_write(APBC_TWSI1_CLK_RST, 0x3);
return NoError;
}
UINT_T PlatformCheckEMMDStatus(void)
{
UINT_T emmd_status0 = 0;
UINT_T emmd_status1 = 0;
UINT_T emmd_status2 = 0;
emmd_status0 = *(VUINT_T *)DDR_RDCA_LOAD_ADDR0;
emmd_status1 = *(VUINT_T *)DDR_RDCA_LOAD_ADDR1;
emmd_status2 = *(VUINT_T *)DDR_RDCA_LOAD_ADDR2;
PlatformReleaseEMMDStatus();
/* firstly check the rdp flag is set at DDR_RDCA_LOAD_ADDR0, and secondly
* check it at DDR_RDCA_LOAD_ADDR1, DDR_RDCA_LOAD_ADDR2
*/
if (RDCAIDENTIFIER == emmd_status0) {
rdp_buf_idx = 0;
return 1;
} else if (RDCAIDENTIFIER == emmd_status1) {
rdp_buf_idx = 1;
return 1;
} else if (RDCAIDENTIFIER == emmd_status2) {
rdp_buf_idx = 2;
return 1;
} else {
return 0;
}
}
void PlatformSetEMMDStatus(void)
{
if (0 == rdp_buf_idx)
*(VUINT_T *)DDR_RDCA_LOAD_ADDR0 = RDCAIDENTIFIER;
else if (1 == rdp_buf_idx)
*(VUINT_T *)DDR_RDCA_LOAD_ADDR1 = RDCAIDENTIFIER;
else
*(VUINT_T *)DDR_RDCA_LOAD_ADDR2 = RDCAIDENTIFIER;
}
void PlatformReleaseEMMDStatus(void)
{
if (!is_heap_init())
return;
free(RAMDUMP_MEM_START);
}
void PlatformEnableBusReset(void)
{
UINT_T value = 0;
value = BU_REG_READ(PI2C_BASE_REGS + I2C_ICYC_offset);
BU_REG_WRITE((PI2C_BASE_REGS + I2C_ICYC_offset), value | 0x9); // 9 cycles
value = BU_REG_READ(PI2C_BASE_REGS + I2C_ICR_offset);
BU_REG_WRITE((PI2C_BASE_REGS + I2C_ICR_offset), value | BIT28); // enable bus reset
Delay(5000); // wait until the control bit is self-cleared
value = BU_REG_READ(PI2C_BASE_REGS + I2C_ICR_offset);
if (value & BIT28) // still not cleared
obm_printf("Bus Reset is not self-cleared\n\r");
}
//TODO: better to skip ddr freq change if don't do ddr test to keep the same flow as old code
//TODO: MCK5_Check_LPDDR2_Info should be called before this function to keep ddr work @266mhz
UINT_T PlatformFrequencyChange(INT_T CorePP, INT_T DdrPP, INT_T AxiPP)
{
UINT_T cfg, div, idx;
UINT_T time_out = 1000;
UINT_T clk_sel = 0, clk_div = 1;
if (CorePP == -1)
goto skip_cpu_fc;
#if !CP_BOOT
switch(CorePP){
#if 0 /* not used and reduce code size ? */
case 0:
obm_printf("Core@624 ");
//PLL_624 pclk_div=0x1 mem_clk_div=2 bus_clk_div=3
cfg = (0x2<<9) | (0x1<<6) | (0x0<<3) | (0x0<<0);
break;
#endif
case 1:
#if !NZAC
//PLL1 SW control, enable PLL1_832 which default is off on Falcon
BU_REG_WRITE(APB_SPARE2_REG, BU_REG_READ(APB_SPARE2_REG) | 0x1);
#endif
obm_printf("Core@832 ");
//PLL_832 pclk_div=0x1 mem_clk_div=2 bus_clk_div=2
cfg = (0x1<<9) | (0x1<<6) | (0x0<<3) | (0x4<<0);
break;
#if 0 /* voltage is not enought for this pp and reduce code size ? */
case 2:
obm_printf("Core@1248 ");
//Enable PLL1_1248
#if NZAC
BU_REG_WRITE(APB_SPARE2_REG, BU_REG_READ(APB_SPARE2_REG) | (1 << 3));
#else
BU_REG_WRITE(APB_SPARE2_REG, BU_REG_READ(APB_SPARE2_REG) | (1 << 8)); //Falcon
#endif
//PLL_1248 pclk_div=0x1 mem_clk_div=2 bus_clk_div=2
cfg = (0x1<<9) | (0x1<<6) | (0x0<<3) | (0x5<<0);
break;
#endif
default:
break;
}
cfg |= (1 << 12);
BU_REG_WRITE(PMUA_AP_CLK_CTRL, cfg);
do{
cfg = BU_REG_READ(PMUA_AP_CLK_CTRL);
if((cfg & 0x1000) == 0)
break;
Delay(1);
time_out --;
}while(time_out);
if(time_out == 0)
{
obm_printf("CA7 frequency change failed\n\r");
}
#endif
skip_cpu_fc:
#if 1
if (DdrPP == -1)
goto skip_ddr_fc;
//ddr frequency change
switch(DdrPP)
{
case 0:
obm_printf("DDR@266 ");
//266
div = 0x4;
idx = 0;
#if LAPW
clk_sel = (0 << 18);
clk_div = (1 << 16);
#endif
break;
case 1:
//533 1:1
obm_printf("DDR@533 ");
div = 0x0;
idx = 1;
#if LAPW
clk_sel = (0 << 18);
clk_div = (0 << 16);
#endif
break;
}
#if !LAPW
cfg = BU_REG_READ(PMUA_CKPHY_FC_CTRL);
cfg &= 0xfffffff0;
cfg |= div;
BU_REG_WRITE(PMUA_CKPHY_FC_CTRL, cfg);
cfg = BU_REG_READ(PMUA_MC_HW_SLP_TYPE);
cfg &= ~(3 << 5);
cfg |= (idx << 5); //select table
BU_REG_WRITE(PMUA_MC_HW_SLP_TYPE, cfg);
cfg |= 0x01000000;
BU_REG_WRITE(PMUA_MC_HW_SLP_TYPE, cfg);
#else
if (PlatformIsLapwZ1()) {
cfg = BU_REG_READ(PMUA_CKPHY_FC_CTRL);
cfg &= 0xfffffff0;
cfg |= div;
BU_REG_WRITE(PMUA_CKPHY_FC_CTRL, cfg);
cfg = BU_REG_READ(PMUA_MC_HW_SLP_TYPE);
cfg &= ~(3 << 5);
cfg |= (idx << 5); //select table
BU_REG_WRITE(PMUA_MC_HW_SLP_TYPE, cfg);
cfg |= 0x01000000;
BU_REG_WRITE(PMUA_MC_HW_SLP_TYPE, cfg);
} else {
obm_printf("19003a0p\n\r");
cfg = BU_REG_READ(PMUA_MC_HW_SLP_TYPE);
cfg &= ~(MC_HW_SLP_TYPE_MASK | MC_HW_SLP_DCLK_SRC_MASK);
cfg |= ((idx << 5) | clk_sel | clk_div); //select table
BU_REG_WRITE(PMUA_MC_HW_SLP_TYPE, cfg);
cfg |= 0x01000000;
BU_REG_WRITE(PMUA_MC_HW_SLP_TYPE, cfg);
}
#endif
time_out = 1000;
do{
cfg = BU_REG_READ(PMUA_MC_HW_SLP_TYPE);
if((cfg & 0x01000000) == 0)
break;
Delay(1);
time_out --;
}while(time_out);
if(time_out == 0)
{
obm_printf("DDR frequency change failed\n\r");
}
#endif
skip_ddr_fc:
if (AxiPP == -1)
goto skip_axi_fc;
//axi frequency change
switch(AxiPP)
{
#if 0 /* not used and reduce code size ? */
case 0:
obm_printf("AXI@156\n\r");
#if FACT
cfg = 0x4;
#elif KAGU
cfg = 0x5;
#else
cfg = 0x0 << 0; //156
#endif
break;
#endif
case 0:
case 1:
obm_printf("AXI@208\n\r");
#if KAGU
cfg = 0x0;
#else
cfg = 0x1 << 0; //208
#endif
break;
default:
break;
}
cfg |= (1 << 4);
BU_REG_WRITE(PMUA_ACLK_CTRL, cfg);
time_out = 1000;
do{
cfg = BU_REG_READ(PMUA_ACLK_CTRL);
if((cfg & 0x10) == 0)
break;
Delay(1);
time_out --;
}while(time_out);
if(time_out == 0)
{
obm_printf("AXI frequency change failed\n\r");
}
skip_axi_fc:
return NoError;
}
void PlatformHoldStateEnable(void)
{
//After reset, this bit should be cleared to 0
//If not, something may be wrong
if((BU_REG_READ(STATE_HOLD_CTRL) & 1) != 0){
obm_printf("State hold controlling error\n\r");
return;
}
obm_printf("DVC_STATUS_HD: 0x%x\n\r", BU_REG_READ(DVC_STATUS_HD));
obm_printf("CP_PMU_STATUS_HD: 0x%x\n\r", BU_REG_READ(CP_PMU_STATUS_HD));
obm_printf("AP_PMU_STATUS_HD: 0x%x\n\r", BU_REG_READ(AP_PMU_STATUS_HD));
#if LAPW
obm_printf("CR5 HD registers:\n\r");
obm_printf("PC: 0x%08x --> 0x%08x\n\r", BU_REG_READ(LAPW_CR5_PC_LST), BU_REG_READ(LAPW_CR5_PC_HD));
obm_printf("SP: 0x%08x CPSR: 0x%08x\n\r", BU_REG_READ(LAPW_CR5_SP_HD), BU_REG_READ(LAPW_CR5_CPSR_HD));
obm_printf("LR: 0x%08x SPSR: 0x%08x\n\r", BU_REG_READ(LAPW_CR5_LR_HD), BU_REG_READ(LAPW_CR5_SPSR_HD));
obm_printf("CA7 HD registers:\n\r");
obm_printf("PC: 0x%08x --> 0x%08x\n\r", BU_REG_READ(LAPW_CA7_PC_LST), BU_REG_READ(LAPW_CA7_PC_HD));
obm_printf("SP: 0x%08x CPSR: 0x%08x\n\r", BU_REG_READ(LAPW_CA7_SP_HD), BU_REG_READ(LAPW_CA7_CPSR_HD));
obm_printf("LR: 0x%08x SPSR: 0x%08x\n\r", BU_REG_READ(LAPW_CA7_LR_HD), BU_REG_READ(LAPW_CA7_SPSR_HD));
#else
obm_printf("CR5_PC_HD: 0x%x\n\r", BU_REG_READ(CR5_PC_HD));
obm_printf("CR5_CPSR_HD: 0x%x\n\r", BU_REG_READ(CR5_CPSR_HD));
obm_printf("CR5_SPSR_HD: 0x%x\n\r", BU_REG_READ(CR5_SPSR_HD));
obm_printf("CA7_PC_HD: 0x%x\n\r", BU_REG_READ(CA7_PC_HD));
obm_printf("CA7_CPSR_HD: 0x%x\n\r", BU_REG_READ(CA7_CPSR_HD));
obm_printf("CA7_SPSR_HD: 0x%x\n\r", BU_REG_READ(CA7_SPSR_HD));
#endif
BU_REG_WRITE(STATE_HOLD_CTRL, 0x1);
}
VOID PlatformInitFM(UINT_T *max_tim_size_byte)
{
#if NZAC
*max_tim_size_byte = 0x1000;
#elif FACT || LAPW
*max_tim_size_byte = 0x4000;
#else
*max_tim_size_byte = 0x2000; //Falcon, Kagu
#endif
}
INT_T PlatformUSBPluggedIn(void)
{
if ((*(VUINT_T *)PMUA_SD_ROT_WAKE_CLR) & PMUA_SD_ROT_WAKE_CLR_USB_VBUS_STS)
return 1;
return 0;
}
CHAR *PlatformName(void)
{
#if NZAC
return "ASR1802SL";
#endif
#if FLCN
return "ASR1803";
#endif
#if KAGU
return "ASR1828";
#endif
#if FACT
return "ASR1806";
#endif
#if LAPW
return "ASR1903";
#endif
return "Unknow Chip";
}
VOID PlatformLateInit(VOID)
{
//Enable State hold feature and dump HD registers
PlatformHoldStateEnable();
//CA7@832 DDR@533 AXI@208
PlatformFrequencyChange(1, -1, 1);
}
#if LAPW
BR_ESTATE lBR_Estate;
VOID ParseBR_ExtraState(UINT_T EstateValue)
{
if(!PlatformIsLapwB0()) {
lBR_Estate.value = 0;
return;
}
lBR_Estate.value = EstateValue;
obm_printf("EBRState: 0x%x\n\r", EstateValue);
#if 0
if(lBR_Estate.bits.HwHash) {
obm_printf("HW hash enabled\n\r");
}
if(lBR_Estate.bits.HwRSAV) {
obm_printf("HW RSAV enabled\n\r");
}
if(lBR_Estate.bits.BkupTIM) {
obm_printf("Boot from Backup TIM\n\r");
}
if(lBR_Estate.bits.BkupOBM) {
obm_printf("Boot from Backup OBM\n\r");
}
if(lBR_Estate.bits.A7Fdis) {
obm_printf("A7 Fuse disabled\n\r");
}
#endif
}
INT_T HwHashIsUsed(void)
{
return lBR_Estate.bits.HwHash;
}
INT_T HwRASVIsUsed(void)
{
return lBR_Estate.bits.HwRSAV;
}
#endif