| /******************************************************************************* |
| * |
| * (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); |
| } |
| |