blob: 70cc2e693612287920cdbd3c5be39fcd95834fdf [file] [log] [blame]
/*******************************************************************************
*
* (C)Copyright 2015 Marvell Hefei Branch. All Rights Reserved.
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
* The copyright notice above does not evidence any actual or intended
* publication of such source code.
* This Module contains Proprietary Information of Marvell and should be
* treated as Confidential.
* The information in this file is provided for the exclusive use of the
* licensees of Marvell.
* Such users have the right to use, modify, and incorporate this code into
* products for purposes authorized by the license agreement provided they
* include this notice and the associated copyright notice with any such
* product.
* The information in this file is provided "AS IS" without warranty.
* *****************************************************************************/
#include "I2C.h"
#include "CIU.h"
// Add by wyq
enum sys_boot_up_reason mbtk_reboot_reason = SYS_BR_POWER_OFF;
// End by wyq
UINT_T PI2C_BASE_ADDR = PI2C_BASE_REGS; // default as PI2C
UINT8_T PMIC_BASE_ADDR = 0x60;
UINT8_T PMIC_POWER_ADDR = 0x62;
UINT8_T PMIC_GPADC_ADDR = 0x64;
UINT8_T PMIC_TEST_ADDR = 0x6E;
static UINT8_T CheckReadTimeout(void)
{
UINT_T value = 0;
UINT_T counter = LOOP_COUNTER_LIMIT;
// check whether the byte transfer has completed or not
do
{
value = I2C_ReadReg(PI2C_BASE_ADDR, I2C_ICR_offset);
counter--;
}
while((value & I2C_ICR_TB) && (counter > 0));
if (counter == 0)
{
obm_printf("RTimeout\n\r");
return 0xff;
}
return 0x0;
}
static void CheckWriteTimeout(void)
{
UINT_T value = 0;
UINT_T counter = LOOP_COUNTER_LIMIT;
// check whether the byte is transmitted or not
do
{
value = I2C_ReadReg(PI2C_BASE_ADDR, I2C_SR_offset);
counter--;
}
while((!(value & I2C_ISR_ITE)) && (counter > 0));
// write back to clear it
I2C_WriteReg(PI2C_BASE_ADDR, I2C_SR_offset, I2C_ISR_ITE);
if (counter == 0)
{
obm_printf("WTimeout\n\r");
return;
}
}
static void PI2C_Init(void)
{
UINT_T value = 0;
PlatformEnableBusReset();
// set the UR/IUE/SCLE bits
value = I2C_ICR_UR | I2C_ICR_IUE | I2C_ICR_SCLE | I2C_ICR_MODE | I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
Delay(10);
// clear the UR bits
value = I2C_ICR_IUE | I2C_ICR_SCLE | I2C_ICR_MODE | I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
Delay(50);
/* toggle clk to release i2c device if SDA is low */
if ((I2C_ReadReg(PI2C_BASE_ADDR, I2C_IMBR_offset) & 0x3) == 0x2) {
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset,
((BIT28) | I2C_ReadReg(PI2C_BASE_ADDR, I2C_ICR_offset)));
obm_printf("i2c-reset\n\r");
Delay(200);
}
// set the load count register to tune the I2C speed performance
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ILCR_offset, 0x082c1da1);
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ISAR_offset, 0xff);
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, 0);
}
static UINT8_T PI2C_Read(UINT8_T slave_addr, UINT8_T reg_addr)
{
UINT_T value = 0;
UINT8_T reg_value = 0xff, retval = 0x0;
// set slave address
I2C_WriteReg(PI2C_BASE_ADDR, I2C_IDBR_offset, slave_addr);
//send 1st bye
value = I2C_ICR_IUE |
I2C_ICR_SCLE |
I2C_ICR_TB |
I2C_ICR_START |
I2C_ICR_MODE |
I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
retval = CheckReadTimeout();
if (retval != 0x0)
return retval;
// check error
value = I2C_ReadReg(PI2C_BASE_ADDR, I2C_SR_offset);
if (value & I2C_ISR_BED)
{
value = I2C_ReadReg(PI2C_BASE_ADDR, I2C_SR_offset);
I2C_WriteReg(PI2C_BASE_ADDR, I2C_SR_offset, value);
PlatformEnableBusReset();
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, 0);
obm_printf("Error detected\n\r");
return 0xff;
}
// send 2nd byte
I2C_WriteReg(PI2C_BASE_ADDR, I2C_IDBR_offset, reg_addr);
value = I2C_ICR_IUE |
I2C_ICR_SCLE |
I2C_ICR_TB |
I2C_ICR_STOP |
I2C_ICR_MODE |
I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
retval = CheckReadTimeout();
if (retval != 0x0)
return retval;
// send 3rd byte
value = slave_addr | 1;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_IDBR_offset, value);
value = I2C_ICR_IUE |
I2C_ICR_SCLE |
I2C_ICR_TB |
I2C_ICR_START |
I2C_ICR_MODE |
I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
retval = CheckReadTimeout();
if (retval != 0x0)
return retval;
// clear SR
I2C_WriteReg(PI2C_BASE_ADDR, I2C_SR_offset, 0);
// send STOP
value = I2C_ICR_IUE |
I2C_ICR_SCLE |
I2C_ICR_TB |
I2C_ICR_STOP |
I2C_ICR_ACKNAK |
I2C_ICR_MODE |
I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
retval = CheckReadTimeout();
if (retval != 0x0)
return retval;
// get data
reg_value = I2C_ReadReg(PI2C_BASE_ADDR, I2C_IDBR_offset);
// clear SR
value = I2C_ReadReg(PI2C_BASE_ADDR, I2C_SR_offset);
I2C_WriteReg(PI2C_BASE_ADDR, I2C_SR_offset, value);
return reg_value;
}
static void PI2C_Write(UINT8_T slave_addr, UINT8_T reg_addr, UINT8_T reg_value)
{
UINT_T value = 0;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ISAR_offset, 0xff);
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, 0);
value = I2C_ICR_IUE |
I2C_ICR_SCLE |
I2C_ICR_MODE |
I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
I2C_WriteReg(PI2C_BASE_ADDR, I2C_IDBR_offset, slave_addr);
// send 1st byte
value |= I2C_ICR_TB | I2C_ICR_START | I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
CheckWriteTimeout();
// send 2nd byte
I2C_WriteReg(PI2C_BASE_ADDR, I2C_IDBR_offset, reg_addr);
value = I2C_ICR_IUE |
I2C_ICR_SCLE |
I2C_ICR_TB |
I2C_ICR_MODE |
I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
CheckWriteTimeout();
// send 3rd byte
I2C_WriteReg(PI2C_BASE_ADDR, I2C_IDBR_offset, reg_value);
value = I2C_ICR_IUE |
I2C_ICR_SCLE |
I2C_ICR_TB |
I2C_ICR_STOP |
I2C_ICR_MODE |
I2C_ICR_GCD;
I2C_WriteReg(PI2C_BASE_ADDR, I2C_ICR_offset, value);
CheckWriteTimeout();
}
void ProcidaBaseWrite(UINT8_T reg_addr, UINT8_T value)
{
if (PMIC_BASE_ADDR != 0x60 && PMIC_BASE_ADDR != 0x00) {
obm_printf("pmic slave addr error\n\r");
return;
}
PI2C_Write(PMIC_BASE_ADDR,reg_addr, value);
}
UINT8_T ProcidaBaseRead(UINT8_T reg_addr)
{
if (PMIC_BASE_ADDR != 0x60 && PMIC_BASE_ADDR != 0x00) {
obm_printf("pmic slave addr error\n\r");
return 0xff;
}
return PI2C_Read(PMIC_BASE_ADDR,reg_addr);
}
void ProcidaPowerWrite(UINT8_T reg_addr, UINT8_T value)
{
if (PMIC_POWER_ADDR != 0x62 && PMIC_POWER_ADDR != 0x02) {
obm_printf("pmic slave addr error\n\r");
return;
}
PI2C_Write(PMIC_POWER_ADDR, reg_addr, value);
}
UINT8_T ProcidaPowerRead(UINT8_T reg_addr)
{
if (PMIC_POWER_ADDR != 0x62 && PMIC_POWER_ADDR != 0x02) {
obm_printf("pmic slave addr error\n\r");
return 0xff;
}
return PI2C_Read(PMIC_POWER_ADDR, reg_addr);
}
void ProcidaGpadcWrite(UINT8_T reg_addr, UINT8_T value)
{
if (PMIC_GPADC_ADDR != 0x64 && PMIC_GPADC_ADDR != 0x04) {
obm_printf("pmic slave addr error\n\r");
return;
}
PI2C_Write(PMIC_GPADC_ADDR, reg_addr, value);
}
UINT8_T ProcidaGpadcRead(UINT8_T reg_addr)
{
if (PMIC_GPADC_ADDR != 0x64 && PMIC_GPADC_ADDR != 0x04) {
obm_printf("pmic slave addr error\n\r");
return 0xff;
}
return PI2C_Read(PMIC_GPADC_ADDR, reg_addr);
}
UINT8_T ProcidaChargerRead(UINT8_T reg_addr)
{
return PI2C_Read(0x66, reg_addr);
}
void ProcidaChargerWrite(UINT8_T reg_addr, UINT8_T value)
{
PI2C_Write(0x66, reg_addr, value);
}
void ProcidaTestWrite(UINT8_T reg_addr, UINT8_T value)
{
if (PMIC_BASE_ADDR != 0x6e && PMIC_BASE_ADDR != 0x0e) {
obm_printf("pmic slave addr error\n\r");
return;
}
PI2C_Write(PMIC_TEST_ADDR, reg_addr, value);
}
UINT8_T ProcidaTestRead(UINT8_T reg_addr)
{
if (PMIC_BASE_ADDR != 0x6e && PMIC_BASE_ADDR != 0x0e) {
obm_printf("pmic slave addr error\n\r");
return 0xff;
}
return PI2C_Read(PMIC_TEST_ADDR, reg_addr);
}
UINT8_T Voltage2Vbuck(UINT16_T mv)
{
UINT8_T value;
/* Max Vbuck voltage of Emei is 3.3v and Min is 0.6V except vbuck1 */
if(mv < 600 || mv > 3300)
return 0x00;
/* from 0x00 to 0x4F VOUT step is 12.5mv, range is from 0 to 1.6v */
if(mv <= 1600){
value = (mv * 10 - 6000) / 125;
}
else
value = ((mv - 1600) / 50) + 0x50;
return value & 0x7F;
}
UINT8_T CheckReset(void)
{
UINT8_T value;
value = ProcidaBaseRead(0x1d);
if ((value & BIT0) == 0)
{
obm_printf("Power up\n\r");
return 0; // power up
}
else
{
obm_printf("Reset\n\r");
return 1; // reset
}
}
/*
* OBM needs to know the DDR size using MRR,
* but the DKB/FF DDR DQ connect is different from each other.
* we don't want to use macro to control swap MRR or not,
*
* current way is reading the voltage of GPADC3 to distinguish them:
* the voltage of GPADC3 on DKB typeA is about 1.2V;
* the voltage of GPADC3 on DKB typeB is about 0.6V;
* the voltage of GPADC3 on FF is about 0.0V;
*/
Board_Type CheckBoardType(void)
{
UINT8_T reg_value[2];
UINT16_T meas_val;
UINT_T vol_gpadc;
Board_Type btype = Board_Unknown;
ProcidaGpadcWrite(0x02, ProcidaGpadcRead(0x02) | BIT5); // GPADC3_MEAS_EN
ProcidaGpadcWrite(0x06, ProcidaGpadcRead(0x06) | BIT0 | BIT1); // GPADC_EN and NON_STOP mode
Delay(5000); // delay for measure data
reg_value[0] = ProcidaGpadcRead(0xA6);
reg_value[1] = ProcidaGpadcRead(0xA7);
meas_val = ((reg_value[0] << 4) | (reg_value[1] & 0x0F));
vol_gpadc = (UINT_T) ((meas_val * 1400) >> 12);
obm_printf("GPADC3 vol_gpadc: 0x%x\n\r", vol_gpadc);
if (vol_gpadc < 150) // 0.15V
{
obm_printf("FF board\n\r");
btype = Board_FF;
}
else if (vol_gpadc < 850) // 0.85V
{
obm_printf("TypeB board\n\r");
btype = Board_TypeB;
}
else if (vol_gpadc < 1350)
{
obm_printf("TypeA board\n\r");
btype = Board_TypeA;
}
else
{
obm_printf("V2R1 board\n\r");
btype = Board_V2R1;
}
return btype;
}
static int pmic_is_pm802s(UINT8_T ID)
{
if (ID == 0x08 || ID == 0x09 || ID == 0x0A)
return 1;
else
return 0;
}
static int pmic_is_pm813s(UINT8_T ID)
{
if (ID == 0x21 || ID == 0x20)
return 1;
else
return 0;
}
static int pmic_is_pm803(UINT8_T ID)
{
if (ID >= 0x18 && ID < 0x1f)
return 1;
else
return 0;
}
static void pmic_save_pdown_log(UINT8_T ID, UINT8_T powerD_l1, UINT8_T powerD_l2)
{
/* save the pdown log */
if (pmic_is_pm803(ID)) {
ProcidaBaseWrite(PM803_BASE_BLANK_REG7, powerD_l1);
ProcidaBaseWrite(PM803_BASE_BLANK_REG8, powerD_l2);
} else if (pmic_is_pm802s(ID)) {
ProcidaBaseWrite(PM802S_BASE_BLANK_REGE, powerD_l1);
ProcidaBaseWrite(PM802S_BASE_BLANK_REGF, powerD_l2);
} else if (pmic_is_pm813s(ID)) {
ProcidaBaseWrite(PM813S_BASE_BLANK_REGE, powerD_l1);
ProcidaBaseWrite(PM813S_BASE_BLANK_REGF, powerD_l2);
}
}
static enum sys_boot_up_reason get_boot_up_reason(UINT8_T ID)
{
UINT8_T powerU_l = 0, powerD_l1 = 0, powerD_l2 = 0, pm803_dummy_reg0 = 0;
UINT32_T pmic_log;
powerU_l = ProcidaBaseRead(POWER_UP_LOG);
powerD_l1 = ProcidaBaseRead(POWER_DOWN_LOG1);
powerD_l2 = ProcidaBaseRead(POWER_DOWN_LOG2);
pm803_dummy_reg0 = ProcidaBaseRead(PM803_DUMMY_REG0);
pmic_save_pdown_log(ID, powerD_l1, powerD_l2);
pmic_log = powerU_l | (powerD_l1 << 8) | (powerD_l2 << 16);
obm_printf("pmic_log: 0x%x\n\r", pmic_log);
/* [power down log2: 0xe6][power down log1: 0xe5][power up log: 0x10] */
if (!(pmic_log & 0x1eff00)) {
/* none pm803 */
if (!pmic_is_pm803(ID))
return SYS_BR_REBOOT;
else if((pm803_dummy_reg0 & 0xf0) == PM803_REBOOT_FLAG)
return SYS_BR_REBOOT;
}
/* get power up log */
pmic_log &= 0xff;
/* pmic is pm803 */
if (pmic_is_pm803(ID)) {
obm_printf("PM803\n\r");
switch (pmic_log) {
case 0x1: return SYS_BR_ONKEY;
case 0x2: return SYS_BR_CHARGE;
case 0x4: return SYS_BR_RTC_ALARM;
case 0x8: return SYS_BR_BAT_WAKEUP;
case 0x10: return SYS_BR_FAULT_WAKEUP;
default: return SYS_BR_POWER_OFF;
}
}
switch (pmic_log) {
case 0x1: return SYS_BR_ONKEY;
case 0x2:
case 0x4: return SYS_BR_CHARGE;
case 0x8:
if (ID == 0x64 || ID == 0x69)
return SYS_BR_REBOOT; //reserved bits for pm801, let it go
else
return SYS_BR_BAT_WAKEUP; //PMIC802 bit3
case 0x10: return SYS_BR_RTC_ALARM;
case 0x20: return SYS_BR_FAULT_WAKEUP;
case 0x40:
if (!(ID == 0x64 || ID == 0x69)) //reserved bits for ASR new pmic
return SYS_BR_REBOOT; //PMIC802 etc bit6
else
return SYS_BR_BAT_WAKEUP; //PMIC801 bit6
default: return SYS_BR_POWER_OFF;
}
}
static void pmic_pm802_powerdown(UINT8_T ID)
{
UINT8_T val;
obm_printf("PM802 power down\n\r");
val = ProcidaBaseRead(0xe2);
val &= ~(0xf << 0);
/* pmic is pm813s or pmic802s */
if (ID == 0x21 || ID == 0x20 || ID == 0x08 || ID == 0x09 || ID == 0x0A) {
obm_printf("dischg 45ms\n\r");
val |= (0x3 << 0);
} else {
obm_printf("!!! pm802 discharge 1S\n\r");
val |= (0x1 << 0);
}
ProcidaBaseWrite(0xe2, val);
val = ProcidaBaseRead(0xe4);
val &= ~(0x1 << 1);
ProcidaBaseWrite(0xe4, val);
//clear old power down log
ProcidaBaseWrite(POWER_DOWN_LOG1, 0xff);
ProcidaBaseWrite(POWER_DOWN_LOG2, 0xff);
val = ProcidaBaseRead(0x0d);
val |= (0x1 << 5);
ProcidaBaseWrite(0x0d, val);
while(1);
}
static void pmic_default_powerdown()
{
//clear old power down log
ProcidaBaseWrite(POWER_DOWN_LOG1, 0xff);
ProcidaBaseWrite(POWER_DOWN_LOG2, 0xff);
obm_printf("default PMIC power down\n\r");
ProcidaBaseWrite(PMIC_WAKE_UP, PMIC_SW_PDOWN);
while(1);
}
static void pmic_powerdown(UINT8_T ID)
{
switch (ID) {
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x08:
case 0x09:
case 0x18:
case 0x19:
case 0x1A:
case 0x1B:
case 0x20:
case 0x21:
case 0x3b:
/* pm802, pm802s, pm803, pm813, pm813s*/
pmic_pm802_powerdown(ID);
break;
default:
pmic_default_powerdown();
break;
}
while(1);
}
// Add by wyq for reboot reason
enum sys_boot_up_reason mbtk_reboot_reason_get(void)
{
return mbtk_reboot_reason;
}
void mbtk_reboot_reason_set(enum sys_boot_up_reason reason)
{
mbtk_reboot_reason = reason;
}
// Add by wyq for reboot reason
void I2CInit(void)
{
UINT8_T value, ID = 0x64, i;
UINT_T RevisionID;
UINT32_T chip_id, volt = 1050;
enum sys_boot_up_reason boot_reason;
#if NZA3
RevisionID = PlatformGetRevisionID();
switch (RevisionID)
{
case 0xF0:
case 0xF2:
PlatformPI2CConfig();
Delay(100);
PI2C_BASE_ADDR = CI2C_BASE_REGS; // Nezha3 Z1/Z2 use CI2C
break;
case 0xF3:
default: // here we suppose next step uses same PI2C as Z3
PlatformPI2CConfig2();
Delay(100);
PI2C_BASE_ADDR = PI2C_BASE_REGS2;
break;
}
#endif
#if NZAS
PlatformPI2CConfig();
Delay(100);
#endif
#if KSTR
PlatformPI2CConfig();
Delay(100);
PI2C_BASE_ADDR = KSTR_PI2C_BASE_REGS;
#endif
PI2C_Init();
Delay(350);
if(PlatformIsFPGA() || PlatformIsEmulator()) //No PMIC on FPGA or Emulator
return;
ID = PI2C_Read(0x60,0x00); // read ID
if (0xFF == ID) //double confirm
ID = PI2C_Read(0x60,0x00);
if (0xFF == ID)
{
obm_printf("RD PMIC ID timeout\n\r");
obm_printf("NO PMIC ON BOARD\n\r");
return;
}
obm_printf("PMIC ID: 0x%x\n\r", ID);
#if PMIC_PWRDN
boot_reason = get_boot_up_reason(ID);
obm_printf("bootup reason = %d\n\r", boot_reason);
// Add by wyq for reboot reason
mbtk_reboot_reason_set(boot_reason);
// Add by wyq for reboot reason
if ((boot_reason == SYS_BR_BAT_WAKEUP) || (boot_reason == SYS_BR_POWER_OFF)) {
value = ProcidaBaseRead(0x01);
/* onkey exton1n exton2 all 0 */
if ((value & 0x7) == 0) {
obm_printf((boot_reason == SYS_BR_BAT_WAKEUP)? "VBAT WKP, power down...\n\r" : "UNKNOWN WKP, power down...\n\r");
pmic_powerdown(ID);
} else {
obm_printf("NOT pdown: reg1: 0x%x\n\r", value);
}
}
#endif
//PM802&PM803&&PM813
if (((0xf0 & ID) == 0x10) || (ID == 0x08 || ID == 0x09 || ID == 0x0A) || (ID == 0x21) || (ID == 0x3B) || (ID == 0x20))
ProcidaBaseWrite(0x0d, BIT7 | BIT3); // set power hold
else
ProcidaBaseWrite(0x0d, BIT7 | BIT6 | BIT3); // reset PMIC register
if (CheckReset() == 0)
{
ProcidaBaseWrite(0x1d, 0x01); // disable PMIC watchdog
value = ProcidaBaseRead(0x1d);
obm_printf("Disable PMIC Watchdog: 0x%x\n\r", value);
}
/*
* Note: we need to double check PMIC ID for buck1 configrations
*/
chip_id = (* (VUINT_T *)CHIP_ID);
/* 1802s */
if (chip_id == 0xc01802)
volt = 1000;
else if ((chip_id & 0xffff) == 0x1903)
volt = 1000;
else if ((chip_id & 0xffff) == 0x1826)
volt = 1150;
else if (((chip_id & 0xff00) == 0x1800)) /* kagu, falcon, falcont */
volt = 1000;
else if ((chip_id & 0xffffff) == 0xc01901) /* kestrel z1*/
volt = 800;
else if ((chip_id & 0xffffff) == 0xc11901) /* kestrel z2 for vdd2*/
volt = 1100;
else if ((chip_id & 0xffffff) == 0xA01901) /* kestrel A0 for vdd2*/
volt = 1100;
else
volt = 1050; /* 1050 should be ok for both 28nm lp and 28nm hp */
/* pm802, pm802s pm803 and pm813 */
if (((0xf0 & ID) == 0x10) || (ID == 0x08 || ID == 0x09 || ID == 0x0A) || (ID == 0x21) || (ID == 0x20) || (ID == 0x3B)) {
//pm802 b0+ pm802s pm813
//intial X0 cap change from 25pf to 10pf for smooth XO boot
if ((ID == 0x13) || (ID == 0x12) || (ID == 0x08 || ID == 0x09 || ID == 0x0A)
|| (ID == 0x21) || (ID == 0x20) || (ID == 0x3B)) {
value = ProcidaBaseRead(0xf0);
value &= ~(0x7 << 5);
value |= (0x1 << 5);
ProcidaBaseWrite(0xf0, value);
}
//PM802
if ((ID >= 0x10 && ID < 0x14)) {
// disable DVCFPWM for all stepping
// OR the RC bit to increase drv capability
ProcidaPowerWrite(0x24, ((ProcidaPowerRead(0x24) & (~BIT7)) | BIT4)); // disable DVCFPWM
ProcidaPowerWrite(0x25, 0x89); // force BUCK1-PWM
for (i = 0; i < 4; i++)
ProcidaPowerWrite((0x29 + i), Voltage2Vbuck(volt));
ProcidaPowerWrite((0x20), Voltage2Vbuck(volt) | (BIT7));
ProcidaPowerWrite((0x30), Voltage2Vbuck(1800) | (BIT7)); // set buck2 to 1.8V
//PM813
} else if ((ID == 0x21) || (ID == 0x3B) || (ID == 0x20)) {
// disable DVCFPWM for all stepping
// OR the RC bit to increase drv capability
ProcidaPowerWrite(0x24, ((ProcidaPowerRead(0x24) & (~BIT7)) | BIT4)); // disable DVCFPWM
ProcidaPowerWrite(0x25, 0x89); // force BUCK1-PWM
for (i = 0; i < 4; i++)
ProcidaPowerWrite((0x2a + i), Voltage2Vbuck(volt));
ProcidaPowerWrite((0x20), Voltage2Vbuck(volt) | (BIT7));
//PM803 & pm802s
} else {
//disable RTP reload
if (ID == 0x08 || ID == 0x09 || ID == 0x0A) {
value = ProcidaBaseRead(0xE1);
value |= (0x1 << 2);
ProcidaBaseWrite(0xE1, value);
}
// disable DVCFPWM for all stepping
// OR the RC bit to increase drv capability
ProcidaPowerWrite(0x24, (ProcidaPowerRead(0x24) & (~BIT7))); // disable DVCFPWM
ProcidaPowerWrite(0x25, 0x89); // force BUCK1-PWM
for (i = 0; i < 4; i++)
ProcidaPowerWrite((0x2b + i), Voltage2Vbuck(volt));
}
} else { /* pm801 and pm812 */
for (i = 0; i < 4; i++)
ProcidaPowerWrite((0x3C + i), Voltage2Vbuck(volt)); // set buck1 to 1.15V
ProcidaPowerWrite((0x40), Voltage2Vbuck(1800)); // set buck2 to 1.8V
ProcidaPowerWrite(0x81, (ProcidaPowerRead(0x81) | BIT6)); // buck4 PWM mode
}
//wait for power to be stable
Delay(40);
return;
}
void PmicClearPowerDownLog(void)
{
UINT8_T val1,val2;
val1 = ProcidaBaseRead(0xe5);
val2 = ProcidaBaseRead(0xe6);
obm_printf("Base-E5/E6: 0x%x 0x%x\n\r", val1, val2);
ProcidaBaseWrite(0xe5, val1);
ProcidaBaseWrite(0xe6, val2);
}